Ticket #1886: SpiderMonkeyESR24_v0.8.diff

File SpiderMonkeyESR24_v0.8.diff, 165.4 KB (added by Yves, 10 years ago)

The current WIP patch for ESR24 (download it here and copy it to libraries/source/spidermonkey: https://ftp.mozilla.org/pub/mozilla.org/js/mozjs-24.2.0.tar.bz2)

  • build/premake/extern_libs4.lua

    Kann nicht anzeigen: Dateityp ist als binär angegeben.
    svn:mime-type = application/octet-stream
    Kann nicht anzeigen: Dateityp ist als binär angegeben.
    svn:mime-type = application/octet-stream
     
    562562    },
    563563    spidermonkey = {
    564564        compile_settings = function()
    565             if _OPTIONS["with-system-mozjs185"] then
    566                 if not _OPTIONS["android"] then
    567                     pkgconfig_cflags("mozjs185")
    568                 end
    569                 defines { "WITH_SYSTEM_MOZJS185" }
     565            if _OPTIONS["with-system-mozjs24"] then
     566                -- to be implemented when such system packages exist
     567                --if not _OPTIONS["android"] then
     568                --  pkgconfig_cflags("mozjs24")
     569                --end
     570                --defines { "WITH_SYSTEM_MOZJS24" }
    570571            else
    571572                if os.is("windows") then
    572573                    include_dir = "include-win32"
    573574                elseif os.is("macosx") then
    574                     include_dir = "include"
     575                    include_dir = "include-unix"
    575576                else
    576577                    include_dir = "include-unix"
    577578                end
    578579                configuration "Debug"
    579                     includedirs { libraries_source_dir.."spidermonkey/"..include_dir }
     580                    includedirs { libraries_source_dir.."spidermonkey/"..include_dir.."-debug" }
     581                    defines { "DEBUG" }
    580582                configuration "Release"
    581                     includedirs { libraries_source_dir.."spidermonkey/"..include_dir }
     583                    includedirs { libraries_source_dir.."spidermonkey/"..include_dir.."-release" }
    582584                configuration { }
    583585            end
    584586        end,
    585587        link_settings = function()
    586             if _OPTIONS["with-system-mozjs185"] then
    587                 if _OPTIONS["android"] then
    588                     links { "mozjs185-1.0" }
    589                 else
    590                     pkgconfig_libs("mozjs185")
    591                 end
     588            if _OPTIONS["with-system-mozjs24"] then
     589                -- to be implemented when such system packages exist
     590                --if _OPTIONS["android"] then
     591                --  links { "mozjs185-1.0" }
     592                --else
     593                --  pkgconfig_libs("mozjs185")
     594                --end
    592595            else
    593596                configuration "Debug"
    594                     links { "mozjs185-ps-debug" }
     597                    links { "mozjs24-ps-debug" }
    595598                configuration "Release"
    596                     links { "mozjs185-ps-release" }
     599                    links { "mozjs24-ps-release" }
    597600                configuration { }
    598601                add_source_lib_paths("spidermonkey")
    599602            end
  • build/premake/premake4.lua

     
    1515newoption { trigger = "with-system-nvtt", description = "Search standard paths for nvidia-texture-tools library, instead of using bundled copy" }
    1616newoption { trigger = "with-system-enet", description = "Search standard paths for libenet, instead of using bundled copy" }
    1717newoption { trigger = "with-system-miniupnpc", description = "Search standard paths for libminiupnpc, instead of using bundled copy" }
    18 newoption { trigger = "with-system-mozjs185", description = "Search standard paths for libmozjs185, instead of using bundled copy" }
     18newoption { trigger = "with-system-mozjs24", description = "Search standard paths for libmozjs24, instead of using bundled copy" }
    1919newoption { trigger = "with-c++11", description = "Enable C++11 on GCC" }
    2020newoption { trigger = "sysroot", description = "Set compiler system root path, used for building against a non-system SDK. For example /usr/local becomes SYSROOT/user/local" }
    2121newoption { trigger = "macosx-version-min", description = "Set minimum required version of the OS X API, the build will possibly fail if an older SDK is used, while newer API functions will be weakly linked (i.e. resolved at runtime)" }
  • source/simulation2/serialization/BinarySerializer.h

     
    2020
    2121#include "ISerializer.h"
    2222
    23 #include "scriptinterface/AutoRooters.h"
    24 
    2523#include "lib/byte_order.h"
    2624#include "lib/allocators/arena.h"
    2725
     
    7371    u32 m_ScriptBackrefsNext;
    7472    u32 GetScriptBackrefTag(JSObject* obj);
    7573
    76     AutoGCRooter m_Rooter;
     74    JS::AutoObjectVector m_Rooter;
    7775
    7876    std::map<JSObject*, std::wstring> m_SerializablePrototypes;
    7977
  • source/simulation2/serialization/StdDeserializer.cpp

     
    2525#include "scriptinterface/ScriptInterface.h"
    2626#include "scriptinterface/ScriptExtraHeaders.h" // for typed arrays
    2727
    28 #include "js/jsapi.h"
    29 
    3028#include "lib/byte_order.h"
    3129
    32 static uint32 GetJSArrayType(u8 arrayType)
    33 {
    34     switch(arrayType)
    35     {
    36     case SCRIPT_TYPED_ARRAY_INT8:
    37         return js::TypedArray::TYPE_INT8;
    38     case SCRIPT_TYPED_ARRAY_UINT8:
    39         return js::TypedArray::TYPE_UINT8;
    40     case SCRIPT_TYPED_ARRAY_INT16:
    41         return js::TypedArray::TYPE_INT16;
    42     case SCRIPT_TYPED_ARRAY_UINT16:
    43         return js::TypedArray::TYPE_UINT16;
    44     case SCRIPT_TYPED_ARRAY_INT32:
    45         return js::TypedArray::TYPE_INT32;
    46     case SCRIPT_TYPED_ARRAY_UINT32:
    47         return js::TypedArray::TYPE_UINT32;
    48     case SCRIPT_TYPED_ARRAY_FLOAT32:
    49         return js::TypedArray::TYPE_FLOAT32;
    50     case SCRIPT_TYPED_ARRAY_FLOAT64:
    51         return js::TypedArray::TYPE_FLOAT64;
    52     case SCRIPT_TYPED_ARRAY_UINT8_CLAMPED:
    53         return js::TypedArray::TYPE_UINT8_CLAMPED;
    54     default:
    55         throw PSERROR_Deserialize_ScriptError("Failed to deserialize unrecognized typed array view");
    56     }
    57 }
    58 
    5930CStdDeserializer::CStdDeserializer(ScriptInterface& scriptInterface, std::istream& stream) :
    6031    m_ScriptInterface(scriptInterface), m_Stream(stream)
    6132{
     
    138109
    139110void CStdDeserializer::FreeScriptBackrefs()
    140111{
     112    JSContext* cx = m_ScriptInterface.GetContext();
     113    JSAutoRequest rq(cx);
     114   
    141115    std::map<u32, JSObject*>::iterator it = m_ScriptBackrefs.begin();
    142116    for (; it != m_ScriptBackrefs.end(); ++it)
    143117    {
    144         if (!JS_RemoveObjectRoot(m_ScriptInterface.GetContext(), &it->second))
    145             throw PSERROR_Deserialize_ScriptError("JS_RemoveRoot failed");
     118        JS_RemoveObjectRoot(m_ScriptInterface.GetContext(), &it->second);
    146119    }
    147120    m_ScriptBackrefs.clear();
    148121}
     
    152125jsval CStdDeserializer::ReadScriptVal(const char* UNUSED(name), JSObject* appendParent)
    153126{
    154127    JSContext* cx = m_ScriptInterface.GetContext();
     128   
     129    JSAutoRequest rq(cx);
    155130
    156131    uint8_t type;
    157132    NumberU8_Unbounded("type", type);
     
    192167            if (!proto)
    193168                throw PSERROR_Deserialize_ScriptError("Failed to find serializable prototype for object");
    194169
    195             JSObject* parent = JS_GetParent(cx, proto);
     170            JSObject* parent = JS_GetParent(proto);
    196171            if (!proto || !parent)
    197172                throw PSERROR_Deserialize_ScriptError();
    198173
     
    206181            JSBool hasCustomDeserialize, hasCustomSerialize;
    207182            if (!JS_HasProperty(cx, obj, "Serialize", &hasCustomSerialize) || !JS_HasProperty(cx, obj, "Deserialize", &hasCustomDeserialize))
    208183                throw PSERROR_Serialize_ScriptError("JS_HasProperty failed");
    209            
     184
    210185            if (hasCustomDeserialize)
    211186            {
    212                 jsval serialize;
    213                 if (!JS_LookupProperty(cx, obj, "Serialize", &serialize))
     187                JS::RootedValue serialize(cx);
     188                if (!JS_LookupProperty(cx, obj, "Serialize", serialize.address()))
    214189                    throw PSERROR_Serialize_ScriptError("JS_LookupProperty failed");
    215190                bool hasNullSerialize = hasCustomSerialize && JSVAL_IS_NULL(serialize);
    216191
     
    241216            utf16string propname;
    242217            ReadStringUTF16("prop name", propname);
    243218
    244             jsval propval = ReadScriptVal("prop value", NULL);
     219            JS::RootedValue propval(cx, ReadScriptVal("prop value", NULL));
    245220            CScriptValRooted propvalRoot(cx, propval);
    246221
    247             if (!JS_SetUCProperty(cx, obj, (const jschar*)propname.data(), propname.length(), &propval))
     222            if (!JS_SetUCProperty(cx, obj, (const jschar*)propname.data(), propname.length(), propval.address()))
    248223                throw PSERROR_Deserialize_ScriptError();
    249224        }
    250225
     
    266241    {
    267242        double value;
    268243        NumberDouble_Unbounded("value", value);
    269         jsval rval;
    270         if (!JS_NewNumberValue(cx, value, &rval))
     244        jsval rval = JS_NumberValue(value);
     245        if (JSVAL_IS_NULL(rval))
    271246            throw PSERROR_Deserialize_ScriptError("JS_NewNumberValue failed");
    272247        return rval;
    273248    }
     
    275250    {
    276251        uint8_t value;
    277252        NumberU8("value", value, 0, 1);
    278         return BOOLEAN_TO_JSVAL(value ? JS_TRUE : JS_FALSE);
     253        return BOOLEAN_TO_JSVAL(value ? true : false);
    279254    }
    280255    case SCRIPT_TYPE_BACKREF:
    281256    {
     
    290265    {
    291266        double value;
    292267        NumberDouble_Unbounded("value", value);
    293         jsval val;
    294         if (!JS_NewNumberValue(cx, value, &val))
    295             throw PSERROR_Deserialize_ScriptError();
     268        JS::RootedValue val(cx, JS_NumberValue(value));
    296269        CScriptValRooted objRoot(cx, val);
    297270
    298271        JSObject* ctorobj;
    299         if (!JS_GetClassObject(cx, JS_GetGlobalObject(cx), JSProto_Number, &ctorobj))
     272        if (!JS_GetClassObject(cx, JS_GetGlobalForScopeChain(cx), JSProto_Number, &ctorobj))
    300273            throw PSERROR_Deserialize_ScriptError("JS_GetClassObject failed");
    301274
    302         JSObject* obj = JS_New(cx, ctorobj, 1, &val);
     275        JSObject* obj = JS_New(cx, ctorobj, 1, val.address());
    303276        if (!obj)
    304277            throw PSERROR_Deserialize_ScriptError("JS_New failed");
    305278        AddScriptBackref(obj);
     
    311284        ScriptString("value", str);
    312285        if (!str)
    313286            throw PSERROR_Deserialize_ScriptError();
    314         jsval val = STRING_TO_JSVAL(str);
     287        JS::RootedValue val(cx, STRING_TO_JSVAL(str));
    315288        CScriptValRooted valRoot(cx, val);
    316289
    317290        JSObject* ctorobj;
    318         if (!JS_GetClassObject(cx, JS_GetGlobalObject(cx), JSProto_String, &ctorobj))
     291        if (!JS_GetClassObject(cx, JS_GetGlobalForScopeChain(cx), JSProto_String, &ctorobj))
    319292            throw PSERROR_Deserialize_ScriptError("JS_GetClassObject failed");
    320293
    321         JSObject* obj = JS_New(cx, ctorobj, 1, &val);
     294        JSObject* obj = JS_New(cx, ctorobj, 1, val.address());
    322295        if (!obj)
    323296            throw PSERROR_Deserialize_ScriptError("JS_New failed");
    324297        AddScriptBackref(obj);
     
    328301    {
    329302        bool value;
    330303        Bool("value", value);
    331         jsval val = BOOLEAN_TO_JSVAL(value ? JS_TRUE : JS_FALSE);
    332         CScriptValRooted objRoot(cx, val);
     304        JS::RootedValue val(cx, BOOLEAN_TO_JSVAL(value));
    333305
    334306        JSObject* ctorobj;
    335         if (!JS_GetClassObject(cx, JS_GetGlobalObject(cx), JSProto_Boolean, &ctorobj))
     307        if (!JS_GetClassObject(cx, JS_GetGlobalForScopeChain(cx), JSProto_Boolean, &ctorobj))
    336308            throw PSERROR_Deserialize_ScriptError("JS_GetClassObject failed");
    337309
    338         JSObject* obj = JS_New(cx, ctorobj, 1, &val);
     310        JSObject* obj = JS_New(cx, ctorobj, 1, val.address());
    339311        if (!obj)
    340312            throw PSERROR_Deserialize_ScriptError("JS_New failed");
    341313        AddScriptBackref(obj);
     
    354326
    355327        // Get buffer object
    356328        jsval bufferVal = ReadScriptVal("buffer", NULL);
    357         CScriptValRooted bufferValRoot(cx, bufferVal);
    358329
    359         if (!JSVAL_IS_OBJECT(bufferVal))
     330        if (JSVAL_IS_PRIMITIVE(bufferVal))
    360331            throw PSERROR_Deserialize_ScriptError();
    361332
    362333        JSObject* bufferObj = JSVAL_TO_OBJECT(bufferVal);
    363         if (!js_IsArrayBuffer(bufferObj))
     334        if (!JS_IsArrayBufferObject(bufferObj))
    364335            throw PSERROR_Deserialize_ScriptError("js_IsArrayBuffer failed");
    365336
    366         JSObject* arrayObj = js_CreateTypedArrayWithBuffer(cx, GetJSArrayType(arrayType), bufferObj, byteOffset, length);
     337        JSObject* arrayObj;
     338        switch(arrayType)
     339        {
     340        case SCRIPT_TYPED_ARRAY_INT8:
     341            arrayObj = JS_NewInt8ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     342            break;
     343        case SCRIPT_TYPED_ARRAY_UINT8:
     344            arrayObj = JS_NewUint8ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     345            break;
     346        case SCRIPT_TYPED_ARRAY_INT16:
     347            arrayObj = JS_NewInt16ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     348            break;
     349        case SCRIPT_TYPED_ARRAY_UINT16:
     350            arrayObj = JS_NewUint16ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     351            break;
     352        case SCRIPT_TYPED_ARRAY_INT32:
     353            arrayObj = JS_NewInt32ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     354            break;
     355        case SCRIPT_TYPED_ARRAY_UINT32:
     356            arrayObj = JS_NewUint32ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     357            break;
     358        case SCRIPT_TYPED_ARRAY_FLOAT32:
     359            arrayObj = JS_NewFloat32ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     360            break;
     361        case SCRIPT_TYPED_ARRAY_FLOAT64:
     362            arrayObj = JS_NewFloat64ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     363            break;
     364        case SCRIPT_TYPED_ARRAY_UINT8_CLAMPED:
     365            arrayObj = JS_NewUint8ClampedArrayWithBuffer(cx, bufferObj, byteOffset, length);
     366            break;
     367        default:
     368            throw PSERROR_Deserialize_ScriptError("Failed to deserialize unrecognized typed array view");
     369        }
    367370        if (!arrayObj)
    368371            throw PSERROR_Deserialize_ScriptError("js_CreateTypedArrayWithBuffer failed");
    369372
     
    383386#error TODO: need to convert JS ArrayBuffer data from little-endian
    384387#endif
    385388
    386         JSObject* bufferObj = js_CreateArrayBuffer(cx, length);
    387         if (!bufferObj)
    388             throw PSERROR_Deserialize_ScriptError("js_CreateArrayBuffer failed");
    389 
     389        JSObject* bufferObj = JS_NewArrayBufferWithContents(cx, (void*)bufferData);
    390390        AddScriptBackref(bufferObj);
    391391
    392         js::ArrayBuffer* buffer = js::ArrayBuffer::fromJSObject(bufferObj);
    393         memcpy(buffer->data, bufferData, length);
    394         delete[] bufferData;
    395 
    396392        return OBJECT_TO_JSVAL(bufferObj);
    397393    }
    398394    default:
     
    440436
    441437void CStdDeserializer::ScriptObjectAppend(const char* name, jsval& obj)
    442438{
    443     if (!JSVAL_IS_OBJECT(obj))
     439    if (JSVAL_IS_PRIMITIVE(obj))
    444440        throw PSERROR_Deserialize_ScriptError();
    445441
    446442    ReadScriptVal(name, JSVAL_TO_OBJECT(obj));
  • source/simulation2/serialization/BinarySerializer.cpp

     
    1919
    2020#include "BinarySerializer.h"
    2121
    22 #include "SerializedScriptTypes.h"
    23 
    2422#include "lib/alignment.h"
    2523#include "ps/CLogger.h"
    2624
    2725#include "scriptinterface/ScriptInterface.h"
    2826#include "scriptinterface/ScriptExtraHeaders.h" // for JSDOUBLE_IS_INT32, typed arrays
     27#include "SerializedScriptTypes.h"
    2928
    30 static u8 GetArrayType(uint32 arrayType)
     29static u8 GetArrayType(JSArrayBufferViewType arrayType)
    3130{
    3231    switch(arrayType)
    3332    {
    34     case js::TypedArray::TYPE_INT8:
     33    case JSArrayBufferViewType::TYPE_INT8:
    3534        return SCRIPT_TYPED_ARRAY_INT8;
    36     case js::TypedArray::TYPE_UINT8:
     35    case JSArrayBufferViewType::TYPE_UINT8:
    3736        return SCRIPT_TYPED_ARRAY_UINT8;
    38     case js::TypedArray::TYPE_INT16:
     37    case JSArrayBufferViewType::TYPE_INT16:
    3938        return SCRIPT_TYPED_ARRAY_INT16;
    40     case js::TypedArray::TYPE_UINT16:
     39    case JSArrayBufferViewType::TYPE_UINT16:
    4140        return SCRIPT_TYPED_ARRAY_UINT16;
    42     case js::TypedArray::TYPE_INT32:
     41    case JSArrayBufferViewType::TYPE_INT32:
    4342        return SCRIPT_TYPED_ARRAY_INT32;
    44     case js::TypedArray::TYPE_UINT32:
     43    case JSArrayBufferViewType::TYPE_UINT32:
    4544        return SCRIPT_TYPED_ARRAY_UINT32;
    46     case js::TypedArray::TYPE_FLOAT32:
     45    case JSArrayBufferViewType::TYPE_FLOAT32:
    4746        return SCRIPT_TYPED_ARRAY_FLOAT32;
    48     case js::TypedArray::TYPE_FLOAT64:
     47    case JSArrayBufferViewType::TYPE_FLOAT64:
    4948        return SCRIPT_TYPED_ARRAY_FLOAT64;
    50     case js::TypedArray::TYPE_UINT8_CLAMPED:
     49    case JSArrayBufferViewType::TYPE_UINT8_CLAMPED:
    5150        return SCRIPT_TYPED_ARRAY_UINT8_CLAMPED;
    5251    default:
    5352        LOGERROR(L"Cannot serialize unrecognized typed array view: %d", arrayType);
     
    5655}
    5756
    5857CBinarySerializerScriptImpl::CBinarySerializerScriptImpl(ScriptInterface& scriptInterface, ISerializer& serializer) :
    59     m_ScriptInterface(scriptInterface), m_Serializer(serializer), m_Rooter(m_ScriptInterface),
     58    m_ScriptInterface(scriptInterface), m_Serializer(serializer), m_Rooter(m_ScriptInterface.GetContext()),
    6059    m_ScriptBackrefsArena(1 * MiB), m_ScriptBackrefs(backrefs_t::key_compare(), ScriptBackrefsAlloc(m_ScriptBackrefsArena)), m_ScriptBackrefsNext(1)
    6160{
    6261}
    63 
     62// TODO YGW: Test serialization...
    6463void CBinarySerializerScriptImpl::HandleScriptVal(jsval val)
    6564{
    6665    JSContext* cx = m_ScriptInterface.GetContext();
     66    JSAutoRequest rq(cx);
    6767
    6868    switch (JS_TypeOfValue(cx, val))
    6969    {
     
    8585            break;
    8686        }
    8787
    88         JSObject* obj = JSVAL_TO_OBJECT(val);
     88        //JSObject* obj = JSVAL_TO_OBJECT(val);
     89        JS::RootedObject obj(cx, JSVAL_TO_OBJECT(val));
    8990
    9091        // If we've already serialized this object, just output a reference to it
    9192        u32 tag = GetScriptBackrefTag(obj);
     
    104105
    105106            // Arrays like [1, 2, ] have an 'undefined' at the end which is part of the
    106107            // length but seemingly isn't enumerated, so store the length explicitly
    107             jsuint length = 0;
     108            uint length = 0;
    108109            if (!JS_GetArrayLength(cx, obj, &length))
    109110                throw PSERROR_Serialize_ScriptError("JS_GetArrayLength failed");
    110111            m_Serializer.NumberU32_Unbounded("array length", length);
    111112        }
    112         else if (js_IsTypedArray(obj))
     113        //JS_IsArrayBufferViewObject()
     114        //JS_IsTypedArrayObject()
     115        else if (JS_IsTypedArrayObject(obj))
    113116        {
    114117            m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_TYPED_ARRAY);
    115118
    116             js::TypedArray* typedArray = js::TypedArray::fromJSObject(obj);
    117            
    118             m_Serializer.NumberU8_Unbounded("array type", GetArrayType(typedArray->type));
    119             m_Serializer.NumberU32_Unbounded("byte offset", typedArray->byteOffset);
    120             m_Serializer.NumberU32_Unbounded("length", typedArray->length);
     119            m_Serializer.NumberU8_Unbounded("array type", GetArrayType(JS_GetArrayBufferViewType(obj)));
     120            m_Serializer.NumberU32_Unbounded("byte offset", JS_GetTypedArrayByteOffset(obj));
     121            m_Serializer.NumberU32_Unbounded("length", JS_GetTypedArrayLength(obj));
    121122
    122123            // Now handle its array buffer
    123124            // this may be a backref, since ArrayBuffers can be shared by multiple views
    124             HandleScriptVal(OBJECT_TO_JSVAL(typedArray->bufferJS));
     125            HandleScriptVal(OBJECT_TO_JSVAL(JS_GetArrayBufferViewBuffer(obj)));
    125126            break;
    126127        }
    127         else if (js_IsArrayBuffer(obj))
     128        else if (JS_IsArrayBufferObject(obj))
    128129        {
    129130            m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_ARRAY_BUFFER);
    130131
    131             js::ArrayBuffer* arrayBuffer = js::ArrayBuffer::fromJSObject(obj);
    132 
    133132#if BYTE_ORDER != LITTLE_ENDIAN
    134133#error TODO: need to convert JS ArrayBuffer data to little-endian
    135134#endif
    136135
    137             u32 length = arrayBuffer->byteLength;
     136            u32 length = JS_GetArrayBufferByteLength(obj);
    138137            m_Serializer.NumberU32_Unbounded("buffer length", length);
    139             m_Serializer.RawBytes("buffer data", (const u8*)arrayBuffer->data, length);
     138            m_Serializer.RawBytes("buffer data", (const u8*)JS_GetArrayBufferData(obj), length);
    140139            break;
    141140        }
    142141        else
    143142        {
    144143            // Find type of object
    145             JSClass* jsclass = JS_GET_CLASS(cx, obj);
     144            JSClass* jsclass = JS_GetClass(obj);
    146145            if (!jsclass)
    147                 throw PSERROR_Serialize_ScriptError("JS_GET_CLASS failed");
     146                throw PSERROR_Serialize_ScriptError("JS_GetClass failed");
    148147            JSProtoKey protokey = JSCLASS_CACHED_PROTO_KEY(jsclass);
    149148
    150149            if (protokey == JSProto_Object)
    151150            {
    152151                // Object class - check for user-defined prototype
    153                 JSObject* proto = JS_GetPrototype(cx, obj);
     152                JS::RootedObject proto(cx);
     153                JS_GetPrototype(cx, obj, proto.address());
    154154                if (!proto)
    155155                    throw PSERROR_Serialize_ScriptError("JS_GetPrototype failed");
    156156
     
    175175                    JSBool hasCustomSerialize;
    176176                    if (!JS_HasProperty(cx, obj, "Serialize", &hasCustomSerialize))
    177177                        throw PSERROR_Serialize_ScriptError("JS_HasProperty failed");
    178                    
     178
    179179                    if (hasCustomSerialize)
    180180                    {
    181                         jsval serialize;
    182                         if (!JS_LookupProperty(cx, obj, "Serialize", &serialize))
     181                        JS::RootedValue serialize(cx);
     182                        if (!JS_LookupProperty(cx, obj, "Serialize", serialize.address()))
    183183                            throw PSERROR_Serialize_ScriptError("JS_LookupProperty failed");
    184184
    185185                        // If serialize is null, so don't serialize anything more
     
    199199                // Standard Number object
    200200                m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_OBJECT_NUMBER);
    201201                // Get primitive value
    202                 jsdouble d;
     202                double d;
    203203                if (!JS_ValueToNumber(cx, val, &d))
    204204                    throw PSERROR_Serialize_ScriptError("JS_ValueToNumber failed");
    205205                m_Serializer.NumberDouble_Unbounded("value", d);
     
    224224                JSBool b;
    225225                if (!JS_ValueToBoolean(cx, val, &b))
    226226                    throw PSERROR_Serialize_ScriptError("JS_ValueToBoolean failed");
    227                 m_Serializer.Bool("value", b == JS_TRUE);
     227                m_Serializer.Bool("value", b);
    228228                break;
    229229            }
    230230            else
     
    240240        // (Note that we don't do any rooting, because we assume nothing is going to trigger GC.
    241241        // I'm not absolute certain that's necessarily a valid assumption.)
    242242
    243         AutoJSIdArray ida (cx, JS_Enumerate(cx, obj));
    244         if (!ida.get())
     243        JS::AutoIdArray ida (cx, JS_Enumerate(cx, obj));
     244        if (!ida)
    245245            throw PSERROR_Serialize_ScriptError("JS_Enumerate failed");
    246246
    247247        m_Serializer.NumberU32_Unbounded("num props", (uint32_t)ida.length());
     
    250250        {
    251251            jsid id = ida[i];
    252252
    253             jsval idval, propval;
    254 
     253            JS::RootedValue idval(cx);
     254            JS::RootedValue propval(cx);
     255           
    255256            // Get the property name as a string
    256             if (!JS_IdToValue(cx, id, &idval))
     257            if (!JS_IdToValue(cx, id, idval.address()))
    257258                throw PSERROR_Serialize_ScriptError("JS_IdToValue failed");
    258             JSString* idstr = JS_ValueToString(cx, idval);
     259            JSString* idstr = JS_ValueToString(cx, idval.get());
    259260            if (!idstr)
    260261                throw PSERROR_Serialize_ScriptError("JS_ValueToString failed");
    261262
     
    263264
    264265            // Use LookupProperty instead of GetProperty to avoid the danger of getters
    265266            // (they might delete values and trigger GC)
    266             if (!JS_LookupPropertyById(cx, obj, id, &propval))
     267            if (!JS_LookupPropertyById(cx, obj, id, propval.address()))
    267268                throw PSERROR_Serialize_ScriptError("JS_LookupPropertyById failed");
    268269
    269270            HandleScriptVal(propval);
     
    308309        else
    309310        {
    310311            ENSURE(JSVAL_IS_DOUBLE(val));
    311 
    312             // If the value fits in an int, serialise as an int
    313             jsdouble d = JSVAL_TO_DOUBLE(val);
    314             int32_t i;
    315             if (JSDOUBLE_IS_INT32(d, &i))
    316             {
    317                 m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_INT);
    318                 m_Serializer.NumberI32_Unbounded("value", i);
    319             }
    320             // Otherwise serialise as a double
    321             else
    322             {
    323                 m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_DOUBLE);
    324                 m_Serializer.NumberDouble_Unbounded("value", d);
    325             }
     312            m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_DOUBLE);
     313            m_Serializer.NumberDouble_Unbounded("value", JSVAL_TO_DOUBLE(val));
    326314        }
    327315        break;
    328316    }
    329317    case JSTYPE_BOOLEAN:
    330318    {
    331319        m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_BOOLEAN);
    332         JSBool b = JSVAL_TO_BOOLEAN(val);
     320        bool b = JSVAL_TO_BOOLEAN(val);
    333321        m_Serializer.NumberU8_Unbounded("value", b ? 1 : 0);
    334322        break;
    335323    }
    336     case JSTYPE_XML:
    337     {
    338         LOGERROR(L"Cannot serialise JS objects of type 'xml'");
    339         throw PSERROR_Serialize_InvalidScriptValue();
    340     }
    341324    default:
    342325    {
    343326        debug_warn(L"Invalid TypeOfValue");
     
    349332void CBinarySerializerScriptImpl::ScriptString(const char* name, JSString* string)
    350333{
    351334    JSContext* cx = m_ScriptInterface.GetContext();
     335    JSAutoRequest rq(cx);
     336
    352337    size_t length;
    353338    const jschar* chars = JS_GetStringCharsAndLength(cx, string, &length);
    354339
     
    382367
    383368    // If it was newly inserted, we need to make sure it gets rooted
    384369    // for the duration that it's in m_ScriptBackrefs
    385     m_Rooter.Push(it.first->first);
     370    // Note: Spidermonkey has a moving GC. JSObject pointers in this mapping table can change,
     371    // but we have registered a custom trace call for the time m_ScriptBackrefs is alive which
     372    // takes care of updating the pointers in our mapping table.
     373    // TODO: Could this be bad for GC-Performance if we serialize large objects and keep the Serializer
     374    // (including m_ScriptBackrefs) alive? Do we keep it alive somewhere?
     375    m_Rooter.append(it.first->first);
    386376    m_ScriptBackrefsNext++;
    387377    // Return a non-tag number so callers know they need to serialize the object
    388378    return 0;
  • source/simulation2/system/ComponentManager.cpp

     
    243243
    244244    // Find all the ctor prototype's On* methods, and subscribe to the appropriate messages:
    245245
    246     CScriptVal proto;
     246    JS::RootedObject proto(componentManager->m_ScriptInterface.GetContext());
    247247    if (!componentManager->m_ScriptInterface.GetProperty(ctor.get(), "prototype", proto))
    248248        return; // error
    249249
    250250    std::vector<std::string> methods;
    251     if (!componentManager->m_ScriptInterface.EnumeratePropertyNamesWithPrefix(proto.get(), "On", methods))
     251    if (!componentManager->m_ScriptInterface.EnumeratePropertyNamesWithPrefix(proto, "On", methods))
    252252        return; // error
    253253
    254254    for (std::vector<std::string>::const_iterator it = methods.begin(); it != methods.end(); ++it)
     
    289289        {
    290290            jsval instance = eit->second->GetJSInstance();
    291291            if (!JSVAL_IS_NULL(instance))
    292                 componentManager->m_ScriptInterface.SetPrototype(instance, proto.get());
     292            {
     293                JS::RootedObject instanceObj(componentManager->m_ScriptInterface.GetContext(),&instance.toObject());
     294                componentManager->m_ScriptInterface.SetPrototype(instanceObj, proto);
     295            }
    293296        }
    294297    }
    295298}
     
    616619    jsval obj = JSVAL_NULL;
    617620    if (ct.type == CT_Script)
    618621    {
    619         obj = m_ScriptInterface.CallConstructor(ct.ctor.get(), JSVAL_VOID);
     622        obj = m_ScriptInterface.CallConstructor(ct.ctor.get(), 0, JSVAL_VOID);
    620623        if (JSVAL_IS_VOID(obj))
    621624        {
    622625            LOGERROR(L"Script component constructor failed");
  • source/simulation2/system/InterfaceScripted.h

     
    1919#define INCLUDED_INTERFACE_SCRIPTED
    2020
    2121#include "scriptinterface/ScriptInterface.h"
    22 #include "js/jsapi.h"
    2322
    2423#define BEGIN_INTERFACE_WRAPPER(iname) \
    2524    JSClass class_ICmp##iname = { \
    2625        "ICmp" #iname, JSCLASS_HAS_PRIVATE, \
    27         JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, \
    28         JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, \
    29         JSCLASS_NO_OPTIONAL_MEMBERS \
     26        JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, \
     27        JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub \
    3028    }; \
    3129    static JSFunctionSpec methods_ICmp##iname[] = {
    3230
     
    3533    }; \
    3634    void ICmp##iname::InterfaceInit(ScriptInterface& scriptInterface) { \
    3735        JSContext* cx = scriptInterface.GetContext(); \
    38         JSObject* global = JS_GetGlobalObject(cx); \
     36        JSAutoRequest rq(cx); \
     37        JSObject* global = JS_GetGlobalForScopeChain(cx); \
    3938        JS_InitClass(cx, global, NULL, &class_ICmp##iname, NULL, 0, NULL, methods_ICmp##iname, NULL, NULL); \
    4039    } \
    4140    JSClass* ICmp##iname::GetJSClass() const { return &class_ICmp##iname; } \
     
    4544
    4645#define DEFINE_INTERFACE_METHOD_0(scriptname, rettype, classname, methodname) \
    4746    { scriptname, \
    48         ScriptInterface::callMethod<rettype, &class_##classname, classname, &classname::methodname>, \
     47        { ScriptInterface::callMethod<rettype, &class_##classname, classname, &classname::methodname>, NULL }, \
    4948        0, \
    5049        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    5150
    5251#define DEFINE_INTERFACE_METHOD_1(scriptname, rettype, classname, methodname, arg1) \
    5352    { scriptname, \
    54         ScriptInterface::callMethod<rettype, arg1, &class_##classname, classname, &classname::methodname>, \
     53        { ScriptInterface::callMethod<rettype, arg1, &class_##classname, classname, &classname::methodname>, NULL}, \
    5554        1, \
    5655        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    5756
    5857#define DEFINE_INTERFACE_METHOD_2(scriptname, rettype, classname, methodname, arg1, arg2) \
    5958    { scriptname, \
    60         ScriptInterface::callMethod<rettype, arg1, arg2, &class_##classname, classname, &classname::methodname>, \
     59        { ScriptInterface::callMethod<rettype, arg1, arg2, &class_##classname, classname, &classname::methodname>, NULL }, \
    6160        2, \
    6261        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    6362
    6463#define DEFINE_INTERFACE_METHOD_3(scriptname, rettype, classname, methodname, arg1, arg2, arg3) \
    6564    { scriptname, \
    66         ScriptInterface::callMethod<rettype, arg1, arg2, arg3, &class_##classname, classname, &classname::methodname>, \
     65        { ScriptInterface::callMethod<rettype, arg1, arg2, arg3, &class_##classname, classname, &classname::methodname>, NULL }, \
    6766        3, \
    6867        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    6968
    7069#define DEFINE_INTERFACE_METHOD_4(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4) \
    7170    { scriptname, \
    72         ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, &class_##classname, classname, &classname::methodname>, \
     71        { ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, &class_##classname, classname, &classname::methodname>, NULL }, \
    7372        4, \
    7473        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    7574
    7675#define DEFINE_INTERFACE_METHOD_5(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5) \
    7776    { scriptname, \
    78         ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, &class_##classname, classname, &classname::methodname>, \
     77        { ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, &class_##classname, classname, &classname::methodname>, NULL }, \
    7978        5, \
    8079        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    8180
    8281#define DEFINE_INTERFACE_METHOD_6(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5, arg6) \
    8382    { scriptname, \
    84         ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, arg6, &class_##classname, classname, &classname::methodname>, \
     83        { ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, arg6, &class_##classname, classname, &classname::methodname>, NULL }, \
    8584        6, \
    8685        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    8786
    8887#define DEFINE_INTERFACE_METHOD_7(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
    8988    { scriptname, \
    90         ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, arg6, arg7, &class_##classname, classname, &classname::methodname>, \
     89        { ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, arg6, arg7, &class_##classname, classname, &classname::methodname>, NULL }, \
    9190        7, \
    9291        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    9392
  • source/simulation2/system/ParamNode.cpp

     
    2525#include "ps/Filesystem.h"
    2626#include "ps/XML/Xeromyces.h"
    2727
    28 #include "js/jsapi.h"
    29 
    3028#include <sstream>
    3129
    3230// Disable "'boost::algorithm::detail::is_classifiedF' : assignment operator could not be generated"
     
    328326
    329327jsval CParamNode::ConstructJSVal(JSContext* cx) const
    330328{
     329    JSAutoRequest rq(cx);
    331330    if (m_Childs.empty())
    332331    {
    333332        // Empty node - map to undefined
     
    351350
    352351    for (std::map<std::string, CParamNode>::const_iterator it = m_Childs.begin(); it != m_Childs.end(); ++it)
    353352    {
    354         jsval childVal = it->second.ConstructJSVal(cx);
    355         if (!JS_SetProperty(cx, obj, it->first.c_str(), &childVal))
     353        JS::RootedValue childVal(cx, it->second.ConstructJSVal(cx));
     354        if (!JS_SetProperty(cx, obj, it->first.c_str(), childVal.address()))
    356355            return JSVAL_VOID; // TODO: report error
    357356    }
    358357
     
    363362        JSString* str = JS_InternUCStringN(cx, reinterpret_cast<const jschar*>(text.data()), text.length());
    364363        if (!str)
    365364            return JSVAL_VOID; // TODO: report error
    366         jsval childVal = STRING_TO_JSVAL(str);
    367         if (!JS_SetProperty(cx, obj, "_string", &childVal))
     365        JS::RootedValue childVal(cx, STRING_TO_JSVAL(str));
     366        if (!JS_SetProperty(cx, obj, "_string", childVal.address()))
    368367            return JSVAL_VOID; // TODO: report error
    369368    }
    370369
  • source/simulation2/system/ComponentManager.h

     
    9696    void RegisterComponentType(InterfaceId, ComponentTypeId, AllocFunc, DeallocFunc, const char*, const std::string& schema);
    9797    void RegisterComponentTypeScriptWrapper(InterfaceId, ComponentTypeId, AllocFunc, DeallocFunc, const char*, const std::string& schema);
    9898
     99
     100    void Tick() { m_ScriptInterface.Tick(); };
    99101    /**
    100102     * Subscribe the current component type to the given message type.
    101103     * Each component's HandleMessage will be called on any BroadcastMessage of this message type,
  • source/simulation2/components/CCmpAIManager.cpp

     
    152152                ENSURE(m_Worker.m_HasLoadedEntityTemplates);
    153153                m_ScriptInterface->SetProperty(settings.get(), "templates", m_Worker.m_EntityTemplates, false);
    154154
    155                 obj = m_ScriptInterface->CallConstructor(ctor.get(), settings.get());
     155                JS::AutoValueVector argv(m_ScriptInterface->GetContext());
     156                argv.append(settings.get());
     157                obj = m_ScriptInterface->CallConstructor(ctor.get(), argv.length(), argv.handleAt(0));
    156158            }
    157159            else
    158160            {
     
    209211    };
    210212
    211213    CAIWorker() :
    212         // TODO: Passing a 32 MB argument to CreateRuntime() is a temporary fix
    213         // to prevent frequent AI out-of-memory crashes. The argument should be
    214         // removed as soon whenever the new pathfinder is committed
    215         // And the AIs can stop relying on their own little hands.
    216         m_ScriptRuntime(ScriptInterface::CreateRuntime(33554432)),
    217         m_ScriptInterface(new ScriptInterface("Engine", "AI", m_ScriptRuntime)),
     214        m_ScriptInterface(new ScriptInterface("Engine", "AI", g_ScriptRuntime)),
    218215        m_TurnNum(0),
    219216        m_CommandsComputed(true),
    220217        m_HasLoadedEntityTemplates(false),
     
    305302    static void ForceGC(ScriptInterface::CxPrivate* pCxPrivate)
    306303    {
    307304        PROFILE3("AI compute GC");
    308         JS_GC(pCxPrivate->pScriptInterface->GetContext());
     305        JS_GC(pCxPrivate->pScriptInterface->GetJSRuntime());
    309306    }
    310307   
    311308    /**
     
    408405            m_ScriptInterface->Eval("({})", fakeTech);
    409406            m_ScriptInterface->SetProperty(settings.get(), "techTemplates", fakeTech, false);
    410407        }
    411         m_SharedAIObj = CScriptValRooted(m_ScriptInterface->GetContext(),m_ScriptInterface->CallConstructor(ctor.get(), settings.get()));
     408       
     409        JS::AutoValueVector argv(m_ScriptInterface->GetContext());
     410        argv.append(settings.get());
     411        m_SharedAIObj = CScriptValRooted(m_ScriptInterface->GetContext(),m_ScriptInterface->CallConstructor(ctor.get(), argv.length(), argv.handleAt(0)));
    412412   
    413413       
    414414        if (m_SharedAIObj.undefined())
     
    754754                m_Players[i]->Run(state, m_Players[i]->m_Player);
    755755        }
    756756
     757/*
    757758        // Run GC if we are about to overflow
    758759        if (JS_GetGCParameter(m_ScriptInterface->GetJSRuntime(), JSGC_BYTES) > 33000000)
    759760        {
    760761            PROFILE3("AI compute GC");
    761762
    762             JS_GC(m_ScriptInterface->GetContext());
     763            JS_GC(m_ScriptInterface->GetJSRuntime());
    763764        }
    764        
     765    */ 
    765766        // Run the GC every so often.
    766767        // (This isn't particularly necessary, but it makes profiling clearer
    767768        // since it avoids random GC delays while running other scripts)
  • source/simulation2/components/ICmpFootprint.cpp

     
    3838
    3939    if (shape == CIRCLE)
    4040    {
    41         jsval ptype = ScriptInterface::ToJSVal<std::string>(cx, "circle");
    42         jsval pradius = ScriptInterface::ToJSVal(cx, size0);
    43         jsval pheight = ScriptInterface::ToJSVal(cx, height);
    44         JS_SetProperty(cx, obj, "type", &ptype);
    45         JS_SetProperty(cx, obj, "radius", &pradius);
    46         JS_SetProperty(cx, obj, "height", &pheight);
     41        JS::RootedValue ptype(cx, ScriptInterface::ToJSVal<std::string>(cx, "circle"));
     42        JS::RootedValue pradius(cx, ScriptInterface::ToJSVal(cx, size0));
     43        JS::RootedValue pheight(cx, ScriptInterface::ToJSVal(cx, height));
     44        JS_SetProperty(cx, obj, "type", ptype.address());
     45        JS_SetProperty(cx, obj, "radius", pradius.address());
     46        JS_SetProperty(cx, obj, "height", pheight.address());
    4747    }
    4848    else
    4949    {
    50         jsval ptype = ScriptInterface::ToJSVal<std::string>(cx, "square");
    51         jsval pwidth = ScriptInterface::ToJSVal(cx, size0);
    52         jsval pdepth = ScriptInterface::ToJSVal(cx, size1);
    53         jsval pheight = ScriptInterface::ToJSVal(cx, height);
    54         JS_SetProperty(cx, obj, "type", &ptype);
    55         JS_SetProperty(cx, obj, "width", &pwidth);
    56         JS_SetProperty(cx, obj, "depth", &pdepth);
    57         JS_SetProperty(cx, obj, "height", &pheight);
     50        JS::RootedValue ptype(cx, ScriptInterface::ToJSVal<std::string>(cx, "square"));
     51        JS::RootedValue pwidth(cx, ScriptInterface::ToJSVal(cx, size0));
     52        JS::RootedValue pdepth(cx, ScriptInterface::ToJSVal(cx, size1));
     53        JS::RootedValue pheight(cx, ScriptInterface::ToJSVal(cx, height));
     54        JS_SetProperty(cx, obj, "type", ptype.address());
     55        JS_SetProperty(cx, obj, "width", pwidth.address());
     56        JS_SetProperty(cx, obj, "depth", pdepth.address());
     57        JS_SetProperty(cx, obj, "height", pheight.address());
    5858    }
    5959
    6060    return OBJECT_TO_JSVAL(obj);
  • source/simulation2/Simulation2.cpp

     
    155155    }
    156156
    157157    int ProgressiveLoad();
     158
     159    void Tick();
    158160    void Update(int turnLength, const std::vector<SimulationCommand>& commands);
    159161    static void UpdateComponents(CSimContext& simContext, fixed turnLengthFixed, const std::vector<SimulationCommand>& commands);
    160162    void Interpolate(float simFrameLength, float frameOffset, float realFrameLength);
     
    336338    debug_warn(L"Serialization test failure");
    337339}
    338340
     341void CSimulation2Impl::Tick()
     342{
     343    m_ComponentManager.Tick();
     344}
     345
    339346void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationCommand>& commands)
    340347{
    341348    PROFILE3("sim update");
     
    637644    return m->m_ComponentManager.GetEntitiesWithInterfaceUnordered(iid);
    638645}
    639646
     647void CSimulation2::Tick()
     648{
     649    m->Tick();
     650}
     651
    640652const CSimContext& CSimulation2::GetSimContext() const
    641653{
    642654    return m->m_SimContext;
  • source/simulation2/Simulation2.h

     
    5353    ~CSimulation2();
    5454
    5555    void EnableOOSLog();
     56    void Tick();
    5657    void EnableSerializationTest();
    5758
    5859    /**
  • source/simulation2/scripting/MessageTypeConversions.cpp

     
    2121#include "scriptinterface/ScriptInterface.h"
    2222#include "simulation2/MessageTypes.h"
    2323
    24 #include "js/jsapi.h"
    25 
    2624#define TOJSVAL_SETUP() \
    27     JSObject* obj = JS_NewObject(scriptInterface.GetContext(), NULL, NULL, NULL); \
    28     if (! obj) \
    29         return JSVAL_VOID;
     25    JSObject* obj; \
     26    {\
     27    JSAutoRequest rq(scriptInterface.GetContext()); \
     28    obj = JS_NewObject(scriptInterface.GetContext(), NULL, NULL, NULL); \
     29    if (!obj) \
     30        return JSVAL_VOID; \
     31    }
    3032
    3133#define SET_MSG_PROPERTY(name) \
    3234    do { \
    33         jsval prop = ScriptInterface::ToJSVal(scriptInterface.GetContext(), this->name); \
    34         if (! JS_SetProperty(scriptInterface.GetContext(), obj, #name, &prop)) \
     35        JSAutoRequest rq(scriptInterface.GetContext()); \
     36        JSContext* cx = scriptInterface.GetContext(); \
     37        JS::RootedValue prop(cx, ScriptInterface::ToJSVal(cx, this->name)); \
     38        if (! JS_SetProperty(cx, obj, #name, prop.address())) \
    3539            return JSVAL_VOID; \
    3640    } while (0);
    3741
    3842#define FROMJSVAL_SETUP() \
    39     if (! JSVAL_IS_OBJECT(val)) \
     43    if ( JSVAL_IS_PRIMITIVE(val)) \
    4044        return NULL; \
    4145    JSObject* obj = JSVAL_TO_OBJECT(val); \
    42     jsval prop;
     46    JS::RootedValue prop(scriptInterface.GetContext());
    4347
    4448#define GET_MSG_PROPERTY(type, name) \
    45     if (! JS_GetProperty(scriptInterface.GetContext(), obj, #name, &prop)) \
     49    type name; \
     50    { \
     51    JSAutoRequest rq(scriptInterface.GetContext()); \
     52    if (! JS_GetProperty(scriptInterface.GetContext(), obj, #name, prop.address())) \
    4653        return NULL; \
    47     type name; \
    48     if (! ScriptInterface::FromJSVal(scriptInterface.GetContext(), prop, name)) \
    49         return NULL;
     54    if (! ScriptInterface::FromJSVal(scriptInterface.GetContext(), prop.get(), name)) \
     55        return NULL; \
     56    }
    5057
    5158jsval CMessage::ToJSValCached(ScriptInterface& scriptInterface) const
    5259{
  • source/simulation2/scripting/EngineScriptConversions.cpp

     
    3434
    3535template<> jsval ScriptInterface::ToJSVal<IComponent*>(JSContext* cx, IComponent* const& val)
    3636{
     37    JSAutoRequest rq(cx);
    3738    if (val == NULL)
    3839        return JSVAL_NULL;
    3940
     
    5859        LOGERROR(L"Failed to construct IComponent script object");
    5960        return JSVAL_VOID;
    6061    }
    61     JS_SetPrivate(cx, obj, static_cast<void*>(val));
     62    JS_SetPrivate(obj, static_cast<void*>(val));
    6263
    6364    return OBJECT_TO_JSVAL(obj);
    6465}
    6566
    6667template<> jsval ScriptInterface::ToJSVal<CParamNode>(JSContext* cx, CParamNode const& val)
    6768{
     69    JSAutoRequest rq(cx);
    6870    jsval rval = val.ToJSVal(cx, true);
    6971
    7072    // Prevent modifications to the object, so that it's safe to share between
    7173    // components and to reconstruct on deserialization
    72     if (JSVAL_IS_OBJECT(rval))
     74    if (!JSVAL_IS_PRIMITIVE(rval))
    7375        JS_DeepFreezeObject(cx, JSVAL_TO_OBJECT(rval));
    7476
    7577    return rval;
     
    8587
    8688template<> bool ScriptInterface::FromJSVal<CColor>(JSContext* cx, jsval v, CColor& out)
    8789{
    88     if (!JSVAL_IS_OBJECT(v))
     90    if (JSVAL_IS_PRIMITIVE(v))
    8991        FAIL("jsval not an object");
    9092
     93    JSAutoRequest rq(cx);
    9194    JSObject* obj = JSVAL_TO_OBJECT(v);
    9295
    93     jsval r, g, b, a;
    94     if (!JS_GetProperty(cx, obj, "r", &r) || !FromJSVal(cx, r, out.r))
     96    JS::RootedValue r(cx);
     97    JS::RootedValue g(cx);
     98    JS::RootedValue b(cx);
     99    JS::RootedValue a(cx);
     100    if (!JS_GetProperty(cx, obj, "r", r.address()) || !FromJSVal(cx, r, out.r))
    95101        FAIL("Failed to get property CColor.r");
    96     if (!JS_GetProperty(cx, obj, "g", &g) || !FromJSVal(cx, g, out.g))
     102    if (!JS_GetProperty(cx, obj, "g", g.address()) || !FromJSVal(cx, g, out.g))
    97103        FAIL("Failed to get property CColor.g");
    98     if (!JS_GetProperty(cx, obj, "b", &b) || !FromJSVal(cx, b, out.b))
     104    if (!JS_GetProperty(cx, obj, "b", b.address()) || !FromJSVal(cx, b, out.b))
    99105        FAIL("Failed to get property CColor.b");
    100     if (!JS_GetProperty(cx, obj, "a", &a) || !FromJSVal(cx, a, out.a))
     106    if (!JS_GetProperty(cx, obj, "a", a.address()) || !FromJSVal(cx, a, out.a))
    101107        FAIL("Failed to get property CColor.a");
    102108    // TODO: this probably has GC bugs if a getter returns an unrooted value
    103109
     
    106112
    107113template<> jsval ScriptInterface::ToJSVal<CColor>(JSContext* cx, CColor const& val)
    108114{
     115    JSAutoRequest rq(cx);
    109116    JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
    110117    if (!obj)
    111118        return JSVAL_VOID;
    112119
    113     jsval r = ToJSVal(cx, val.r);
    114     jsval g = ToJSVal(cx, val.g);
    115     jsval b = ToJSVal(cx, val.b);
    116     jsval a = ToJSVal(cx, val.a);
     120    JS::RootedValue r(cx, ToJSVal(cx, val.r));
     121    JS::RootedValue g(cx, ToJSVal(cx, val.g));
     122    JS::RootedValue b(cx, ToJSVal(cx, val.b));
     123    JS::RootedValue a(cx, ToJSVal(cx, val.a));
    117124
    118     JS_SetProperty(cx, obj, "r", &r);
    119     JS_SetProperty(cx, obj, "g", &g);
    120     JS_SetProperty(cx, obj, "b", &b);
    121     JS_SetProperty(cx, obj, "a", &a);
     125    JS_SetProperty(cx, obj, "r", r.address());
     126    JS_SetProperty(cx, obj, "g", g.address());
     127    JS_SetProperty(cx, obj, "b", b.address());
     128    JS_SetProperty(cx, obj, "a", a.address());
    122129
    123130    return OBJECT_TO_JSVAL(obj);
    124131}
    125132
    126133template<> bool ScriptInterface::FromJSVal<fixed>(JSContext* cx, jsval v, fixed& out)
    127134{
    128     jsdouble ret;
     135    JSAutoRequest rq(cx);
     136    double ret;
    129137    if (!JS_ValueToNumber(cx, v, &ret))
    130138        return false;
    131139    out = fixed::FromDouble(ret);
     
    134142    return true;
    135143}
    136144
    137 template<> jsval ScriptInterface::ToJSVal<fixed>(JSContext* cx, const fixed& val)
     145template<> jsval ScriptInterface::ToJSVal<fixed>(JSContext* UNUSED(cx), const fixed& val)
    138146{
    139     jsval rval = JSVAL_VOID;
    140     JS_NewNumberValue(cx, val.ToDouble(), &rval); // ignore return value
     147    jsval rval = JS_NumberValue(val.ToDouble());
    141148    return rval;
    142149}
    143150
    144151template<> bool ScriptInterface::FromJSVal<CFixedVector3D>(JSContext* cx, jsval v, CFixedVector3D& out)
    145152{
    146     if (!JSVAL_IS_OBJECT(v))
     153    if (JSVAL_IS_PRIMITIVE(v))
    147154        return false; // TODO: report type error
     155
     156    JSAutoRequest rq(cx);
    148157    JSObject* obj = JSVAL_TO_OBJECT(v);
    149158
    150     jsval p;
     159    JS::RootedValue p(cx);
    151160
    152     if (!JS_GetProperty(cx, obj, "x", &p)) return false; // TODO: report type errors
     161    if (!JS_GetProperty(cx, obj, "x", p.address())) return false; // TODO: report type errors
    153162    if (!FromJSVal(cx, p, out.X)) return false;
    154163
    155     if (!JS_GetProperty(cx, obj, "y", &p)) return false;
     164    if (!JS_GetProperty(cx, obj, "y", p.address())) return false;
    156165    if (!FromJSVal(cx, p, out.Y)) return false;
    157166
    158     if (!JS_GetProperty(cx, obj, "z", &p)) return false;
     167    if (!JS_GetProperty(cx, obj, "z", p.address())) return false;
    159168    if (!FromJSVal(cx, p, out.Z)) return false;
    160169
    161170    return true;
     
    163172
    164173template<> jsval ScriptInterface::ToJSVal<CFixedVector3D>(JSContext* cx, const CFixedVector3D& val)
    165174{
     175    JSAutoRequest rq(cx);
    166176    JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
    167177    if (!obj)
    168178        return JSVAL_VOID;
    169179
    170     jsval x = ToJSVal(cx, val.X);
    171     jsval y = ToJSVal(cx, val.Y);
    172     jsval z = ToJSVal(cx, val.Z);
     180    JS::RootedValue x(cx, ToJSVal(cx, val.X));
     181    JS::RootedValue y(cx, ToJSVal(cx, val.Y));
     182    JS::RootedValue z(cx, ToJSVal(cx, val.Z));
    173183
    174     JS_SetProperty(cx, obj, "x", &x);
    175     JS_SetProperty(cx, obj, "y", &y);
    176     JS_SetProperty(cx, obj, "z", &z);
     184    JS_SetProperty(cx, obj, "x", x.address());
     185    JS_SetProperty(cx, obj, "y", y.address());
     186    JS_SetProperty(cx, obj, "z", z.address());
    177187
    178188    return OBJECT_TO_JSVAL(obj);
    179189}
    180190
    181191template<> bool ScriptInterface::FromJSVal<CFixedVector2D>(JSContext* cx, jsval v, CFixedVector2D& out)
    182192{
    183     if (!JSVAL_IS_OBJECT(v))
     193    JSAutoRequest rq(cx);
     194    if (JSVAL_IS_PRIMITIVE(v))
    184195        return false; // TODO: report type error
    185196    JSObject* obj = JSVAL_TO_OBJECT(v);
    186197
    187     jsval p;
     198    JS::RootedValue p(cx);
    188199
    189     if (!JS_GetProperty(cx, obj, "x", &p)) return false; // TODO: report type errors
     200    if (!JS_GetProperty(cx, obj, "x", p.address())) return false; // TODO: report type errors
    190201    if (!FromJSVal(cx, p, out.X)) return false;
    191202
    192     if (!JS_GetProperty(cx, obj, "y", &p)) return false;
     203    if (!JS_GetProperty(cx, obj, "y", p.address())) return false;
    193204    if (!FromJSVal(cx, p, out.Y)) return false;
    194205
    195206    return true;
     
    197208
    198209template<> jsval ScriptInterface::ToJSVal<CFixedVector2D>(JSContext* cx, const CFixedVector2D& val)
    199210{
     211    JSAutoRequest rq(cx);
    200212    JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
    201213    if (!obj)
    202214        return JSVAL_VOID;
    203215
    204     jsval x = ToJSVal(cx, val.X);
    205     jsval y = ToJSVal(cx, val.Y);
     216    JS::RootedValue x(cx, ToJSVal(cx, val.X));
     217    JS::RootedValue y(cx, ToJSVal(cx, val.Y));
    206218
    207     JS_SetProperty(cx, obj, "x", &x);
    208     JS_SetProperty(cx, obj, "y", &y);
     219    JS_SetProperty(cx, obj, "x", x.address());
     220    JS_SetProperty(cx, obj, "y", y.address());
    209221
    210222    return OBJECT_TO_JSVAL(obj);
    211223}
    212224
    213 template<jsint atype, typename T> jsval ToJSVal_Grid(JSContext* cx, const Grid<T>& val)
     225template<> jsval ScriptInterface::ToJSVal<Grid<u8> >(JSContext* cx, const Grid<u8>& val)
    214226{
    215     JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
    216     if (!obj)
    217         return JSVAL_VOID;
     227    JSAutoRequest rq(cx);
     228    uint32_t length = (uint32_t)(val.m_W * val.m_H);
     229    uint32_t nbytes = (uint32_t)(length * sizeof(uint8_t));
     230    JSObject* objArr = JS_NewUint8Array(cx, length);
     231    memcpy((void*)JS_GetUint8ArrayData(objArr), val.m_Data, nbytes);
    218232
    219     jsuint len = val.m_W * val.m_H;
    220     JSObject *darray = js_CreateTypedArray(cx, atype, len);
    221     if (!darray)
    222         return JSVAL_VOID;
     233    JS::RootedValue data(cx, OBJECT_TO_JSVAL(objArr));
     234    JS::RootedValue w(cx, ScriptInterface::ToJSVal(cx, val.m_W));
     235    JS::RootedValue h(cx, ScriptInterface::ToJSVal(cx, val.m_H));
    223236
    224     js::TypedArray *tdest = js::TypedArray::fromJSObject(darray);
    225     ENSURE(tdest->byteLength == len*sizeof(T));
    226237
    227     memcpy(tdest->data, val.m_Data, tdest->byteLength);
     238    JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
     239    JS_SetProperty(cx, obj, "width", w.address());
     240    JS_SetProperty(cx, obj, "height", h.address());
     241    JS_SetProperty(cx, obj, "data", data.address());
    228242
    229     jsval w = ScriptInterface::ToJSVal(cx, val.m_W);
    230     jsval h = ScriptInterface::ToJSVal(cx, val.m_H);
    231     jsval data = OBJECT_TO_JSVAL(darray);
    232 
    233     JS_SetProperty(cx, obj, "width", &w);
    234     JS_SetProperty(cx, obj, "height", &h);
    235     JS_SetProperty(cx, obj, "data", &data);
    236 
    237243    return OBJECT_TO_JSVAL(obj);
    238244}
     245 
     246template<> jsval ScriptInterface::ToJSVal<Grid<u16> >(JSContext* cx, const Grid<u16>& val)
     247 {
     248    JSAutoRequest rq(cx);
     249    uint32_t length = (uint32_t)(val.m_W * val.m_H);
     250    uint32_t nbytes = (uint32_t)(length * sizeof(uint16_t));
     251    JSObject* objArr = JS_NewUint16Array(cx, length);
     252    memcpy((void*)JS_GetUint16ArrayData(objArr), val.m_Data, nbytes);
     253 
     254    JS::RootedValue data(cx, OBJECT_TO_JSVAL(objArr));
     255    JS::RootedValue w(cx, ScriptInterface::ToJSVal(cx, val.m_W));
     256    JS::RootedValue h(cx, ScriptInterface::ToJSVal(cx, val.m_H));
    239257
    240 template<> jsval ScriptInterface::ToJSVal<Grid<u8> >(JSContext* cx, const Grid<u8>& val)
    241 {
    242     return ToJSVal_Grid<js::TypedArray::TYPE_UINT8>(cx, val);
    243 }
     258    JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
     259    JS_SetProperty(cx, obj, "width", w.address());
     260    JS_SetProperty(cx, obj, "height", h.address());
     261    JS_SetProperty(cx, obj, "data", data.address());
    244262
    245 template<> jsval ScriptInterface::ToJSVal<Grid<u16> >(JSContext* cx, const Grid<u16>& val)
    246 {
    247     return ToJSVal_Grid<js::TypedArray::TYPE_UINT16>(cx, val);
     263    return OBJECT_TO_JSVAL(obj);
    248264}
  • source/lobby/XmppClient.cpp

     
    284284void XmppClient::SendIqGameReport(ScriptInterface& scriptInterface, CScriptVal data)
    285285{
    286286    glooxwrapper::JID xpartamuppJid(m_xpartamuppId);
    287     jsval dataval = data.get();
     287    JS::RootedValue dataval(scriptInterface.GetContext(), data.get());
    288288
    289289    // Setup some base stanza attributes
    290290    GameReport* game = new GameReport();
     
    292292
    293293    // Iterate through all the properties reported and add them to the stanza.
    294294    std::vector<std::string> properties;
    295     scriptInterface.EnumeratePropertyNamesWithPrefix(dataval, "", properties);
     295    scriptInterface.EnumeratePropertyNamesWithPrefix(JS::RootedObject(scriptInterface.GetContext(), JSVAL_TO_OBJECT(dataval)), "", properties);
    296296    for (std::vector<int>::size_type i = 0; i != properties.size(); i++)
    297297    {
    298298        std::wstring value;
     
    318318void XmppClient::SendIqRegisterGame(ScriptInterface& scriptInterface, CScriptVal data)
    319319{
    320320    glooxwrapper::JID xpartamuppJid(m_xpartamuppId);
    321     jsval dataval = data.get();
     321    JS::RootedValue dataval(scriptInterface.GetContext(), data.get());
    322322
    323323    // Setup some base stanza attributes
    324324    GameListQuery* g = new GameListQuery();
     
    329329
    330330    // Iterate through all the properties reported and add them to the stanza.
    331331    std::vector<std::string> properties;
    332     scriptInterface.EnumeratePropertyNamesWithPrefix(dataval, "", properties);
     332    JS::RootedObject dataobj(scriptInterface.GetContext(), JSVAL_TO_OBJECT(dataval.get()));
     333    scriptInterface.EnumeratePropertyNamesWithPrefix(dataobj, "", properties);
    333334    for (std::vector<int>::size_type i = 0; i != properties.size(); i++)
    334335    {
    335336        std::wstring value;
  • source/ps/scripting/JSInterface_VFS.cpp

     
    6868{
    6969    BuildDirEntListState* s = (BuildDirEntListState*)cbData;
    7070
    71     jsval val = ScriptInterface::ToJSVal(s->cx, CStrW(pathname.string()));
    72     JS_SetElement(s->cx, s->filename_array, s->cur_idx++, &val);
     71    JS::RootedValue val(s->cx, ScriptInterface::ToJSVal( s->cx, CStrW(pathname.string()) ));
     72    JS_SetElement(s->cx, s->filename_array, s->cur_idx++, val.address());
    7373    return INFO::OK;
    7474}
    7575
     
    191191    while (std::getline(ss, line))
    192192    {
    193193        // Decode each line as UTF-8
    194         jsval val = ScriptInterface::ToJSVal(cx, CStr(line).FromUTF8());
    195         JS_SetElement(cx, line_array, cur_line++, &val);
     194        JS::RootedValue val(cx, ScriptInterface::ToJSVal(cx, CStr(line).FromUTF8()));
     195        JS_SetElement(cx, line_array, cur_line++, val.address());
    196196    }
    197197
    198198    return OBJECT_TO_JSVAL( line_array );
  • source/ps/Profile.cpp

     
    2929# define USE_CRT_SET_ALLOC_HOOK
    3030#endif
    3131
    32 #if defined(__GLIBC__) && !defined(NDEBUG)
    33 //# define USE_GLIBC_MALLOC_HOOK
    34 # define USE_GLIBC_MALLOC_OVERRIDE
    35 # include <dlfcn.h>
    36 # include <malloc.h>
    37 # include "lib/sysdep/cpu.h"
    38 #endif
     32//#if defined(__GLIBC__) && !defined(NDEBUG)
     33////# define USE_GLIBC_MALLOC_HOOK
     34//# define USE_GLIBC_MALLOC_OVERRIDE
     35//# include <dlfcn.h>
     36//# include <malloc.h>
     37//# include "lib/sysdep/cpu.h"
     38//#endif
    3939
    4040#include <numeric>
    4141
  • source/ps/GameSetup/GameSetup.cpp

     
    10991099        CStr seedArg = args.Get("autostart-random");
    11001100
    11011101        // Default seed is 0
    1102         uint32 seed = 0;
     1102        uint32_t seed = 0;
    11031103        if (!seedArg.empty())
    11041104        {
    11051105            if (seedArg.compare("-1") == 0)
  • source/ps/Errors.h

     
    7272
    7373#include <exception>
    7474
    75 typedef u32 PSRETURN;
     75//typedef u32 PSRETURN;
     76typedef uint32_t PSRETURN;
    7677
    7778class PSERROR : public std::exception
    7879{
  • source/ps/Replay.cpp

     
    127127    new CProfileManager;
    128128    g_ScriptStatsTable = new CScriptStatsTable;
    129129    g_ProfileViewer.AddRootTable(g_ScriptStatsTable);
    130     g_ScriptRuntime = ScriptInterface::CreateRuntime(128 * 1024 * 1024);
     130    g_ScriptRuntime = ScriptInterface::CreateRuntime(256 * 1024 * 1024);
    131131
    132132    CGame game(true);
    133133    g_Game = &game;
     
    210210                g_Profiler2.IncrementFrameNumber();
    211211                PROFILE2_ATTR("%d", g_Profiler2.GetFrameNumber());
    212212
     213                game.GetSimulation2()->Tick();
    213214                game.GetSimulation2()->Update(turnLength, commands);
    214215                commands.clear();
    215216            }
  • source/scriptinterface/ScriptExtraHeaders.h

     
    3131# endif
    3232# pragma GCC diagnostic ignored "-Wunused-parameter"
    3333# pragma GCC diagnostic ignored "-Wredundant-decls"
     34# pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
    3435# if GCC_VERSION >= 408
    3536#  pragma GCC diagnostic ignored "-Wunused-local-typedefs" // caused by js/debug.h
    3637# endif
     
    4647# define signbit std::signbit
    4748#endif
    4849
    49 #include "js/jstypedarray.h"
    50 #include "js/jsdbgapi.h"
     50//#include "js/jstypedarray.h"
     51//#include "jspubtd.h"
     52//#include "jsatom.h"
     53#include "jsfriendapi.h"
     54#include "jsdbgapi.h"
    5155
    5256#undef signbit
    5357
     
    5761#if GCC_VERSION >= 402
    5862# pragma GCC diagnostic warning "-Wunused-parameter"
    5963# pragma GCC diagnostic warning "-Wredundant-decls"
     64# pragma GCC diagnostic warning "-Wnon-virtual-dtor"
    6065# if GCC_VERSION >= 406
    6166#  pragma GCC diagnostic pop // restore user flags
    6267# endif
  • source/scriptinterface/ScriptVal.h

     
    5858     */
    5959    jsval get() const;
    6060
     61    void Wrap(JSContext* cx);
     62
    6163    /**
    6264     * Returns reference to the current value.
    6365     * Fails if the value is not yet initialised.
    6466     */
    6567    jsval& getRef() const;
    6668
     69    void getPtr(JS::Value** val);
     70
    6771    /**
    6872     * Returns whether the value is uninitialised or is JSVAL_VOID.
    6973     */
  • source/scriptinterface/tests/test_ScriptConversions.h

     
    2323#include "maths/MathUtil.h"
    2424#include "ps/CLogger.h"
    2525
    26 #include "js/jsapi.h"
     26#include "jsapi.h"
    2727
    2828class TestScriptConversions : public CxxTest::TestSuite
    2929{
     
    3838        // We want to convert values to strings, but can't just call toSource() on them
    3939        // since they might not be objects. So just use uneval.
    4040        std::string source;
    41         TS_ASSERT(script.CallFunction(OBJECT_TO_JSVAL(JS_GetGlobalObject(cx)), "uneval", CScriptVal(v1), source));
     41        TS_ASSERT(script.CallFunction(OBJECT_TO_JSVAL(JS_GetGlobalForScopeChain(cx)), "uneval", CScriptVal(v1), source));
    4242
    4343        TS_ASSERT_STR_EQUALS(source, expected);
    4444    }
     
    5252        jsval v1 = ScriptInterface::ToJSVal(cx, value);
    5353
    5454        std::string source;
    55         TS_ASSERT(script.CallFunction(OBJECT_TO_JSVAL(JS_GetGlobalObject(cx)), "uneval", CScriptVal(v1), source));
     55        TS_ASSERT(script.CallFunction(OBJECT_TO_JSVAL(JS_GetGlobalForScopeChain(cx)), "uneval", CScriptVal(v1), source));
    5656
    5757        if (expected)
    5858            TS_ASSERT_STR_EQUALS(source, expected);
  • source/scriptinterface/tests/test_ScriptVal.h

     
    2020#include "scriptinterface/ScriptInterface.h"
    2121#include "scriptinterface/ScriptVal.h"
    2222
    23 #include "js/jsapi.h"
     23#include "jsapi.h"
    2424
    2525class TestScriptVal : public CxxTest::TestSuite
    2626{
     
    3535
    3636        CScriptValRooted root(cx, OBJECT_TO_JSVAL(obj));
    3737
    38         JS_GC(cx);
     38        JS_GC(script.GetRuntime());
    3939
    4040        jsval val = INT_TO_JSVAL(123);
    4141        TS_ASSERT(JS_SetProperty(cx, obj, "test", &val));
    4242
    43         JS_GC(cx);
     43        JS_GC(script.GetRuntime());
    4444
    4545        jsval rval;
    4646        TS_ASSERT(JS_GetProperty(cx, obj, "test", &rval));
  • source/scriptinterface/AutoRooters.cpp

     
    1 /* Copyright (C) 2010 Wildfire Games.
    2  * This file is part of 0 A.D.
    3  *
    4  * 0 A.D. is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * 0 A.D. is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 
    18 #include "precompiled.h"
    19 
    20 #include "AutoRooters.h"
    21 
    22 #include "scriptinterface/ScriptInterface.h"
    23 
    24 AutoGCRooter::AutoGCRooter(ScriptInterface& scriptInterface)
    25     : m_ScriptInterface(scriptInterface)
    26 {
    27     m_Previous = m_ScriptInterface.ReplaceAutoGCRooter(this);
    28 }
    29 
    30 AutoGCRooter::~AutoGCRooter()
    31 {
    32     AutoGCRooter* r = m_ScriptInterface.ReplaceAutoGCRooter(m_Previous);
    33     ENSURE(r == this); // must be correctly nested
    34 }
    35 
    36 void AutoGCRooter::Trace(JSTracer* trc)
    37 {
    38     if (m_Previous)
    39         m_Previous->Trace(trc);
    40 
    41     for (size_t i = 0; i < m_Objects.size(); ++i)
    42     {
    43         JS_CALL_OBJECT_TRACER(trc, m_Objects[i], "AutoGCRooter object");
    44     }
    45 
    46     for (size_t i = 0; i < m_Vals.size(); ++i)
    47     {
    48         JS_CALL_VALUE_TRACER(trc, m_Vals[i], "AutoGCRooter val");
    49     }
    50 
    51     for (size_t i = 0; i < m_IdArrays.size(); ++i)
    52     {
    53         for (jsint j = 0; j < m_IdArrays[i]->length; ++j)
    54         {
    55             jsval val = JSVAL_VOID;
    56             JS_IdToValue(m_ScriptInterface.GetContext(), m_IdArrays[i]->vector[j], &val);
    57             JS_CALL_VALUE_TRACER(trc, val, "AutoGCRooter id array");
    58         }
    59     }
    60 
    61 }
  • source/scriptinterface/ScriptInterface.h

     
    2525#include "ScriptTypes.h"
    2626#include "ScriptVal.h"
    2727
    28 #include "js/jsapi.h"
    29 
    3028#include "ps/Errors.h"
    3129ERROR_GROUP(Scripting);
    3230ERROR_TYPE(Scripting, SetupFailed);
     
    5250
    5351#include <boost/random/linear_congruential.hpp>
    5452
    55 class AutoGCRooter;
    56 
    5753// Set the maximum number of function arguments that can be handled
    5854// (This should be as small as possible (for compiler efficiency),
    5955// but as large as necessary for all wrapped functions)
     
    114110        void* pCBData; // meant to be used as the "this" object for callback functions
    115111    } m_CxPrivate;
    116112
     113    void Tick();
    117114    void SetCallbackData(void* pCBData);
    118115    static CxPrivate* GetScriptInterfaceAndCBData(JSContext* cx);
    119116
     
    136133     * Call a constructor function, equivalent to JS "new ctor(arg)".
    137134     * @return The new object; or JSVAL_VOID on failure, and logs an error message
    138135     */
    139     jsval CallConstructor(jsval ctor, jsval arg);
     136    jsval CallConstructor(jsval ctor, int argc, jsval argv);
    140137
    141138    /**
    142139     * Create an object as with CallConstructor except don't actually execute the
     
    251248     */
    252249    bool HasProperty(jsval obj, const char* name);
    253250
    254     bool EnumeratePropertyNamesWithPrefix(jsval obj, const char* prefix, std::vector<std::string>& out);
     251    bool EnumeratePropertyNamesWithPrefix(JS::HandleObject obj, const char* prefix, std::vector<std::string>& out);
    255252
    256     bool SetPrototype(jsval obj, jsval proto);
     253    bool SetPrototype(JS::HandleObject obj, JS::HandleObject proto);
    257254
    258255    bool FreezeObject(jsval obj, bool deep);
    259256
     
    326323     */
    327324    template<typename T> static jsval ToJSVal(JSContext* cx, T const& val);
    328325
    329     AutoGCRooter* ReplaceAutoGCRooter(AutoGCRooter* rooter);
    330 
    331326    /**
    332327     * Dump some memory heap debugging information to stderr.
    333328     */
     
    338333     */
    339334    void MaybeGC();
    340335
     336    bool MathRandom(double& nbr);
     337
    341338    /**
    342339     * Structured clones are a way to serialize 'simple' JS values into a buffer
    343340     * that can safely be passed between contexts and runtimes and threads.
     
    351348    public:
    352349        StructuredClone();
    353350        ~StructuredClone();
    354         JSContext* m_Context;
    355         uint64* m_Data;
     351        uint64_t* m_Data;
    356352        size_t m_Size;
    357353    };
    358354
     
    367363    bool SetProperty_(jsval obj, const char* name, jsval value, bool readonly, bool enumerate);
    368364    bool SetProperty_(jsval obj, const wchar_t* name, jsval value, bool readonly, bool enumerate);
    369365    bool SetPropertyInt_(jsval obj, int name, jsval value, bool readonly, bool enumerate);
    370     bool GetProperty_(jsval obj, const char* name, jsval& value);
    371     bool GetPropertyInt_(jsval obj, int name, jsval& value);
     366    bool GetProperty_(jsval obj, const char* name, JS::MutableHandleValue out);
     367    bool GetPropertyInt_(jsval obj, int name, JS::MutableHandleValue value);
    372368    static bool IsExceptionPending(JSContext* cx);
    373     static JSClass* GetClass(JSContext* cx, JSObject* obj);
    374     static void* GetPrivate(JSContext* cx, JSObject* obj);
     369    static JSClass* GetClass(JSObject* obj);
     370    static void* GetPrivate(JSObject* obj);
    375371
    376372    class CustomType
    377373    {
     
    383379    void Register(const char* name, JSNative fptr, size_t nargs);
    384380    std::auto_ptr<ScriptInterface_impl> m;
    385381   
     382    boost::rand48* m_rng;
    386383    std::map<std::string, CustomType> m_CustomObjectTypes;
    387384
    388385// The nasty macro/template bits are split into a separate file so you don't have to look at them
     
    527524template<typename T>
    528525bool ScriptInterface::GetProperty(jsval obj, const char* name, T& out)
    529526{
    530     jsval val;
    531     if (! GetProperty_(obj, name, val))
     527    JSContext* cx = GetContext();
     528    JSAutoRequest rq(cx);
     529    JS::RootedValue val(cx);
     530    if (! GetProperty_(obj, name, &val))
    532531        return false;
    533     return FromJSVal(GetContext(), val, out);
     532    return FromJSVal(cx, val, out);
    534533}
    535534
    536535template<typename T>
    537536bool ScriptInterface::GetPropertyInt(jsval obj, int name, T& out)
    538537{
    539     jsval val;
    540     if (! GetPropertyInt_(obj, name, val))
     538    JS::RootedValue val(GetContext());
     539    if (! GetPropertyInt_(obj, name, &val))
    541540        return false;
    542541    return FromJSVal(GetContext(), val, out);
    543542}
  • source/scriptinterface/ScriptTypes.h

     
    3333// the ones that are needed and this avoids conflicting definitions
    3434# define JS_SYS_TYPES_H_DEFINES_EXACT_SIZE_TYPES
    3535
     36
    3637#else // If not Windows, then Unix:
    3738
    3839# define XP_UNIX
    3940
    40 // In DEBUG mode, jsval defaults to struct types. Normally we build separate
    41 // debug/release mode versions of the library, but when using --with-system-mozjs185
    42 // it's always a release mode library, so we have to disable struct types for
    43 // ABI compatibility
    44 # if defined(DEBUG) && defined(WITH_SYSTEM_MOZJS185)
    45 #  define JS_NO_JSVAL_JSID_STRUCT_TYPES
    46 # endif
    47 
    4841#endif
    4942// (we don't support XP_OS2 or XP_BEOS)
    5043
    5144
    5245// Guess whether the library was compiled with the release-mode or debug-mode ABI
    5346// (for JS_DumpHeap etc)
    54 #if defined(DEBUG) && !defined(WITH_SYSTEM_MOZJS185)
     47#if defined(DEBUG) && !defined(WITH_SYSTEM_MOZJS24)
    5548# define MOZJS_DEBUG_ABI 1
    5649#else
    5750# define MOZJS_DEBUG_ABI 0
    5851#endif
    5952
    60 
    61 // SpiderMonkey wants the DEBUG flag
    62 #ifndef NDEBUG
    63 # ifndef DEBUG
    64 #  define DEBUG
    65 # endif
    66 #endif
    67 
    6853// Ignore some harmless warnings triggered by jsapi.h
    69 #if GCC_VERSION >= 402 // (older GCCs don't support this pragma)
     54// TODO: Optimize this for different GCC versions if we find a list which pragma is supported in which version of GCC)
     55// Also some versions of GCC will still print warnings (see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431).
     56#if GCC_VERSION >= 402
    7057# pragma GCC diagnostic ignored "-Wunused-parameter"
    7158# pragma GCC diagnostic ignored "-Wredundant-decls"
     59# pragma GCC diagnostic ignored "-Wundef"
     60# pragma GCC diagnostic ignored "-Wignored-qualifiers"
     61# pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
    7262#endif
    7363#if MSC_VERSION
    7464# pragma warning(push)
     
    7666# pragma warning(disable:4100) // "unreferenced formal parameter"
    7767#endif
    7868
    79 #include "js/jsapi.h"
     69#include "jspubtd.h"
     70#include "jsapi.h"
    8071
     72
    8173#if MSC_VERSION
    8274# pragma warning(pop)
    8375#endif
    8476#if GCC_VERSION >= 402
    8577# pragma GCC diagnostic warning "-Wunused-parameter"
    8678# pragma GCC diagnostic warning "-Wredundant-decls"
     79# pragma GCC diagnostic warning "-Wundef"
     80# pragma GCC diagnostic warning "-Wignored-qualifiers"
     81# pragma GCC diagnostic warning "-Wnon-virtual-dtor"
    8782#endif
    8883
    89 #if JS_VERSION != 185
    90 #error Your compiler is trying to use an incorrect version of the SpiderMonkey library.
    91 #error The only version that works is the one in the libraries/spidermonkey/ directory,
    92 #error and it will not work with a typical system-installed version.
    93 #error Make sure you have got all the right files and include paths.
    94 #endif
     84//#if MOZJS_MAJOR_VERSION != 24 || MOZJS_MINOR_VERSION != 0
     85//#error Your compiler is trying to use an incorrect version of the SpiderMonkey library.
     86//#error The only version that works is the one in the libraries/spidermonkey/ directory,
     87//#error and it will not work with a typical system-installed version.
     88//#error Make sure you have got all the right files and include paths.
     89//#endif
    9590
    9691class ScriptInterface;
    9792class CScriptVal;
  • source/scriptinterface/NativeWrapperDecls.h

     
    2626#define NUMBERED_LIST_BALANCED(z, i, data) BOOST_PP_COMMA_IF(i) data##i
    2727// Some other things
    2828#define TYPED_ARGS(z, i, data) , T##i a##i
    29 #define CONVERT_ARG(z, i, data) T##i a##i; if (! ScriptInterface::FromJSVal<T##i>(cx, i < argc ? JS_ARGV(cx, vp)[i] : JSVAL_VOID, a##i)) return JS_FALSE;
     29#define CONVERT_ARG(z, i, data) T##i a##i; if (! ScriptInterface::FromJSVal<T##i>(cx, i < argc ? JS_ARGV(cx, vp)[i] : JSVAL_VOID, a##i)) return false;
    3030
    3131// List-generating macros, named roughly after their first list item
    3232#define TYPENAME_T0_HEAD(z, i) BOOST_PP_REPEAT_##z (i, NUMBERED_LIST_HEAD, typename T) // "typename T0, typename T1, "
     
    5151// (Definition comes later, since it depends on some things we haven't defined yet)
    5252#define OVERLOADS(z, i, data) \
    5353    template <typename R, TYPENAME_T0_HEAD(z,i)  R (*fptr) ( ScriptInterface::CxPrivate* T0_TAIL(z,i) )> \
    54     static JSBool call(JSContext* cx, uintN argc, jsval* vp);
     54    static JSBool call(JSContext* cx, uint32_t argc, jsval* vp);
    5555BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
    5656#undef OVERLOADS
    5757
    5858// Similar, for class methods
    5959#define OVERLOADS(z, i, data) \
    6060    template <typename R, TYPENAME_T0_HEAD(z,i)  JSClass* CLS, typename TC, R (TC::*fptr) ( T0(z,i) )> \
    61     static JSBool callMethod(JSContext* cx, uintN argc, jsval* vp);
     61    static JSBool callMethod(JSContext* cx, uint32_t argc, jsval* vp);
    6262BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
    6363#undef OVERLOADS
    6464
  • source/scriptinterface/ScriptVal.cpp

     
    1717
    1818#include "precompiled.h"
    1919
     20#include "ScriptInterface.h"
    2021#include "ScriptVal.h"
    2122
    22 #include "js/jsapi.h"
    2323
    2424struct Unrooter
    2525{
    2626    Unrooter(JSContext* cx) : cx(cx) { }
    27     void operator()(jsval* p) { JS_RemoveValueRoot(cx, p); delete p; }
     27    void operator()(jsval* p)
     28    {
     29        JSAutoRequest rq(cx);
     30        JS_RemoveValueRoot(cx, p); delete p;
     31    }
    2832    JSContext* cx;
    2933};
    3034
    3135CScriptValRooted::CScriptValRooted(JSContext* cx, jsval val)
    3236{
     37    JSAutoRequest rq(cx);
    3338    jsval* p = new jsval(val);
    3439    JS_AddNamedValueRoot(cx, p, "CScriptValRooted");
    3540    m_Val = boost::shared_ptr<jsval>(p, Unrooter(cx));
     
    3742
    3843CScriptValRooted::CScriptValRooted(JSContext* cx, CScriptVal val)
    3944{
     45    JSAutoRequest rq(cx);
    4046    jsval* p = new jsval(val.get());
    4147    JS_AddNamedValueRoot(cx, p, "CScriptValRooted");
    4248    m_Val = boost::shared_ptr<jsval>(p, Unrooter(cx));
     
    4955    return *m_Val;
    5056}
    5157
     58void CScriptValRooted::getPtr(JS::Value** val)
     59{
     60    *val = &*m_Val;
     61}
     62
    5263jsval& CScriptValRooted::getRef() const
    5364{
    5465    ENSURE(m_Val);
     
    6576    return !m_Val;
    6677}
    6778
     79/*
    6880AutoJSIdArray::AutoJSIdArray(JSContext* cx, JSIdArray* ida) :
    6981    m_Context(cx), m_IdArray(ida)
    7082{
     
    8597{
    8698    if (!m_IdArray)
    8799        return 0;
    88     return m_IdArray->length;
     100    return JS_IdArrayLength(m_Context, m_IdArray);
    89101}
    90102
    91103jsid AutoJSIdArray::operator[](size_t i) const
     
    93105    if (!(m_IdArray && i < (size_t)m_IdArray->length))
    94106        return JSID_VOID;
    95107    return m_IdArray->vector[i];
    96 }
     108}*/
     109
     110
     111//CRootedWrapper::CRootedWrapper(JSContext* cx, JS::Value val)
     112//{
     113//  JSAutoRequest rq(cx);
     114//  JS::Value* wrap = &val;
     115//  JS_WrapValue(cx, val);
     116//  m_Val = boost::shared_ptr<JS::Value>(wrap, Unrooter(cx));
     117//}
  • source/scriptinterface/NativeWrapperDefns.h

     
    7979#define SCRIPT_PROFILE \
    8080    if (g_ScriptProfilingEnabled) \
    8181    { \
    82         ENSURE(JSVAL_IS_OBJECT(JS_CALLEE(cx, vp)) && JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)))); \
     82        ENSURE(!JSVAL_IS_PRIMITIVE(JS_CALLEE(cx, vp)) && JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)))); \
    8383        const char* name = "(unknown)"; \
    8484        jsval nameval; \
    85         if (JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0, &nameval) \
    86             && !JSVAL_IS_VOID(nameval)) \
     85        nameval = JS_GetReservedSlot(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0); \
     86        if (!JSVAL_IS_VOID(nameval)) \
    8787            name = static_cast<const char*>(JSVAL_TO_PRIVATE(nameval)); \
    8888        CProfileSampleScript profile(name); \
    8989    }
     
    9191// JSFastNative-compatible function that wraps the function identified in the template argument list
    9292#define OVERLOADS(z, i, data) \
    9393    template <typename R, TYPENAME_T0_HEAD(z,i)  R (*fptr) ( ScriptInterface::CxPrivate* T0_TAIL(z,i) )> \
    94     JSBool ScriptInterface::call(JSContext* cx, uintN argc, jsval* vp) { \
     94    JSBool ScriptInterface::call(JSContext* cx, uint32_t argc, jsval* vp) { \
    9595        UNUSED2(argc); \
    9696        SCRIPT_PROFILE \
    9797        BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \
    9898        jsval rval = JSVAL_VOID; \
    9999        ScriptInterface_NativeWrapper<R>::call(cx, rval, fptr  A0_TAIL(z,i)); \
    100100        JS_SET_RVAL(cx, vp, rval); \
    101         return (ScriptInterface::IsExceptionPending(cx) ? JS_FALSE : JS_TRUE); \
     101        return !ScriptInterface::IsExceptionPending(cx); \
    102102    }
    103103BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
    104104#undef OVERLOADS
     
    106106// Same idea but for methods
    107107#define OVERLOADS(z, i, data) \
    108108    template <typename R, TYPENAME_T0_HEAD(z,i)  JSClass* CLS, typename TC, R (TC::*fptr) ( T0(z,i) )> \
    109     JSBool ScriptInterface::callMethod(JSContext* cx, uintN argc, jsval* vp) { \
     109    JSBool ScriptInterface::callMethod(JSContext* cx, uint32_t argc, jsval* vp) { \
    110110        UNUSED2(argc); \
    111111        SCRIPT_PROFILE \
    112         if (ScriptInterface::GetClass(cx, JS_THIS_OBJECT(cx, vp)) != CLS) return JS_FALSE; \
    113         TC* c = static_cast<TC*>(ScriptInterface::GetPrivate(cx, JS_THIS_OBJECT(cx, vp))); \
    114         if (! c) return JS_FALSE; \
     112        if (ScriptInterface::GetClass(JS_THIS_OBJECT(cx, vp)) != CLS) return false; \
     113        TC* c = static_cast<TC*>(ScriptInterface::GetPrivate(JS_THIS_OBJECT(cx, vp))); \
     114        if (! c) return false; \
    115115        BOOST_PP_REPEAT_##z (i, CONVERT_ARG, ~) \
    116116        jsval rval = JSVAL_VOID; \
    117117        ScriptInterface_NativeMethodWrapper<R, TC>::call(cx, rval, c, fptr  A0_TAIL(z,i)); \
    118118        JS_SET_RVAL(cx, vp, rval); \
    119         return (ScriptInterface::IsExceptionPending(cx) ? JS_FALSE : JS_TRUE); \
     119        return !ScriptInterface::IsExceptionPending(cx); \
    120120    }
    121121BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
    122122#undef OVERLOADS
  • source/scriptinterface/ScriptStats.cpp

     
    2121
    2222#include "scriptinterface/ScriptInterface.h"
    2323
    24 #include "js/jsapi.h"
    25 
    2624CScriptStatsTable* g_ScriptStatsTable;
    2725
    2826enum
  • source/scriptinterface/ScriptInterface.cpp

     
    2020#include "ScriptInterface.h"
    2121// #include "DebuggingServer.h" // JS debugger temporarily disabled during the SpiderMonkey upgrade (check trac ticket #2348 for details)
    2222#include "ScriptStats.h"
    23 #include "AutoRooters.h"
    2423
    2524#include "lib/debug.h"
    2625#include "lib/utf8.h"
     
    6867class ScriptRuntime
    6968{
    7069public:
    71     ScriptRuntime(int runtimeSize) :
    72         m_rooter(NULL)
     70    ScriptRuntime(int runtimeSize)
    7371    {
    74         m_rt = JS_NewRuntime(runtimeSize);
     72        // TODO: check what JS_Init() actually does and what the constraints are
     73        // What I know: It must be called before calling JS_NewRuntime
     74        m_rt = JS_NewRuntime(runtimeSize, JS_USE_HELPER_THREADS);
     75
    7576        ENSURE(m_rt); // TODO: error handling
    7677
     78        JS_SetNativeStackQuota(m_rt, 128 * sizeof(size_t) * 1024);
    7779        if (g_ScriptProfilingEnabled)
    7880        {
    7981            // Profiler isn't thread-safe, so only enable this on the main thread
     
    8688                }
    8789            }
    8890        }
     91        JS_SetGCParameter(m_rt, JSGC_MAX_MALLOC_BYTES, 256 * 1024 * 1024);
     92        JS_SetGCParameter(m_rt, JSGC_MAX_BYTES, 256 * 1024 * 1024);
    8993
    90         JS_SetExtraGCRoots(m_rt, jshook_trace, this);
     94        m_dummyContext = JS_NewContext(m_rt, STACK_CHUNK_SIZE);
     95        ENSURE(m_dummyContext);
    9196    }
    9297
    9398    ~ScriptRuntime()
    9499    {
     100        JS_DestroyContext(m_dummyContext);
    95101        JS_DestroyRuntime(m_rt);
    96102    }
    97103
     104    JSContext* m_dummyContext;
    98105    JSRuntime* m_rt;
    99     AutoGCRooter* m_rooter;
    100106
    101107private:
    102108
    103109
    104     static void* jshook_script(JSContext* UNUSED(cx), JSStackFrame* UNUSED(fp), JSBool before, JSBool* UNUSED(ok), void* closure)
     110    static void* jshook_script(JSContext* UNUSED(cx), JSAbstractFramePtr UNUSED(fp), bool UNUSED(isConstructing), JSBool before, JSBool* UNUSED(ok), void* closure)
    105111    {
    106112        if (before)
    107113            g_Profiler.StartScript("script invocation");
     
    154160            if (slash != filename.npos)
    155161                filename = filename.substr(slash+1);
    156162
    157             uintN line = JS_PCToLineNumber(cx, script, pc);
     163            uint line = JS_PCToLineNumber(cx, script, pc);
    158164
    159165            std::stringstream ss;
    160166            ss << "(" << filename << ":" << line << ")";
     
    178184        boost::flyweights::no_locking
    179185    > LocFlyweight;
    180186
    181     static void* jshook_function(JSContext* cx, JSStackFrame* fp, JSBool before, JSBool* UNUSED(ok), void* closure)
     187    static void* jshook_function(JSContext* cx, JSAbstractFramePtr fp, bool UNUSED(isConstructing), JSBool before, JSBool* UNUSED(ok), void* closure)
    182188    {
    183189        if (!before)
    184190        {
     
    186192            return closure;
    187193        }
    188194
    189         JSFunction* fn = JS_GetFrameFunction(cx, fp);
     195        JSFunction* fn = fp.maybeFun();
    190196        if (!fn)
    191197        {
    192198            g_Profiler.StartScript("(function)");
     
    207213        }
    208214
    209215        // No name - compute from the location instead
    210         ScriptLocation loc = { cx, JS_GetFrameScript(cx, fp), JS_GetFramePC(cx, fp) };
     216        JSScript* script;
     217        unsigned lineno;
     218        JS_DescribeScriptedCaller(cx, &script, &lineno);
     219        ENSURE(script == fp.script());
     220        ScriptLocation loc = { cx, fp.script(), JS_LineNumberToPC(cx, script, lineno) };
    211221        g_Profiler.StartScript(LocFlyweight(loc).get().name.c_str());
    212222
    213223        return closure;
    214224    }
    215 
    216     static void jshook_trace(JSTracer* trc, void* data)
    217     {
    218         ScriptRuntime* m = static_cast<ScriptRuntime*>(data);
    219 
    220         if (m->m_rooter)
    221             m->m_rooter->Trace(trc);
    222     }
    223225};
    224226
    225227shared_ptr<ScriptRuntime> ScriptInterface::CreateRuntime(int runtimeSize)
     
    233235{
    234236    ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime);
    235237    ~ScriptInterface_impl();
    236     void Register(const char* name, JSNative fptr, uintN nargs);
     238    void Register(const char* name, JSNative fptr, uint nargs);
    237239
    238240    shared_ptr<ScriptRuntime> m_runtime;
    239241    JSContext* m_cx;
    240242    JSObject* m_glob; // global scope object
     243    JSCompartment* m_comp;
     244    boost::rand48* m_rng;
    241245    JSObject* m_nativeScope; // native function scope object
    242246};
    243247
     
    246250
    247251JSClass global_class = {
    248252    "global", JSCLASS_GLOBAL_FLAGS,
    249     JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
    250     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
    251     NULL, NULL, NULL, NULL,
     253    JS_PropertyStub, JS_DeletePropertyStub,
     254    JS_PropertyStub, JS_StrictPropertyStub,
     255    JS_EnumerateStub, JS_ResolveStub,
     256    JS_ConvertStub, NULL,
    252257    NULL, NULL, NULL, NULL
    253258};
    254259
    255260void ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report)
    256261{
    257     // XXX Ugly hack: we want to compile code with 'use strict' and with JSOPTION_STRICT,
    258     // but the latter causes the former to be reported as a useless expression, so
    259     // ignore that specific warning here
    260     if (report->flags == 5 && report->lineno == 0 && report->errorNumber == 163)
    261         return;
    262262
    263263    std::stringstream msg;
    264264    bool isWarning = JSREPORT_IS_WARNING(report->flags);
     
    273273
    274274    // If there is an exception, then print its stack trace
    275275    jsval excn;
    276     if (JS_GetPendingException(cx, &excn) && JSVAL_IS_OBJECT(excn))
     276    if (JS_GetPendingException(cx, &excn) && !JSVAL_IS_PRIMITIVE(excn))
    277277    {
    278278        // TODO: this violates the docs ("The error reporter callback must not reenter the JSAPI.")
    279279
     
    309309
    310310// Functions in the global namespace:
    311311
    312 JSBool print(JSContext* cx, uintN argc, jsval* vp)
     312JSBool print(JSContext* cx, uint argc, jsval* vp)
    313313{
    314     for (uintN i = 0; i < argc; ++i)
     314    for (uint i = 0; i < argc; ++i)
    315315    {
    316316        std::wstring str;
    317317        if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[i], str))
     
    323323    return JS_TRUE;
    324324}
    325325
    326 JSBool logmsg(JSContext* cx, uintN argc, jsval* vp)
     326JSBool logmsg(JSContext* cx, uint argc, jsval* vp)
    327327{
    328328    if (argc < 1)
    329329    {
     
    334334    std::wstring str;
    335335    if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
    336336        return JS_FALSE;
    337     LOGMESSAGE(L"%ls", str.c_str());
     337    LOGMESSAGE(L"%ls%f", str.c_str(), timer_Time());
    338338    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    339339    return JS_TRUE;
    340340}
    341341
    342 JSBool warn(JSContext* cx, uintN argc, jsval* vp)
     342JSBool warn(JSContext* cx, uint argc, jsval* vp)
    343343{
    344344    if (argc < 1)
    345345    {
     
    355355    return JS_TRUE;
    356356}
    357357
    358 JSBool error(JSContext* cx, uintN argc, jsval* vp)
     358JSBool error(JSContext* cx, uint argc, jsval* vp)
    359359{
    360360    if (argc < 1)
    361361    {
     
    371371    return JS_TRUE;
    372372}
    373373
    374 JSBool deepcopy(JSContext* cx, uintN argc, jsval* vp)
     374JSBool deepcopy(JSContext* cx, uint argc, jsval* vp)
    375375{
    376376    if (argc < 1)
    377377    {
     
    381381
    382382    jsval ret;
    383383
    384     // We'd usually do:
    385     //  if (!JS_StructuredClone(cx, JS_ARGV(cx, vp)[0], &ret, NULL, NULL))
    386     //      return JS_FALSE;
    387     // but that function is broken in the 1.8.5 release
    388     // (https://bugzilla.mozilla.org/show_bug.cgi?id=651510)
    389     // so do an equivalent operation with a different API:
    390     JSAutoStructuredCloneBuffer buf;
    391     if (!buf.write(cx, JS_ARGV(cx, vp)[0]) || !buf.read(&ret, cx))
     384    if (!JS_StructuredClone(cx, JS_ARGV(cx, vp)[0], &ret, NULL, NULL))
    392385        return JS_FALSE;
    393386
    394387    JS_SET_RVAL(cx, vp, ret);
    395388    return JS_TRUE;
    396389}
    397390
    398 JSBool ProfileStart(JSContext* cx, uintN argc, jsval* vp)
     391JSBool ProfileStart(JSContext* cx, uint argc, jsval* vp)
    399392{
    400393    const char* name = "(ProfileStart)";
    401394
     
    423416    return JS_TRUE;
    424417}
    425418
    426 JSBool ProfileStop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* vp)
     419JSBool ProfileStop(JSContext* UNUSED(cx), uint UNUSED(argc), jsval* vp)
    427420{
    428421    if (CProfileManager::IsInitialised() && ThreadUtil::IsMainThread())
    429422        g_Profiler.Stop();
     
    452445    }
    453446}
    454447
    455 JSBool Math_random(JSContext* cx, uintN UNUSED(argc), jsval* vp)
     448JSBool Math_random(JSContext* cx, uint UNUSED(argc), jsval* vp)
    456449{
    457     // Grab the RNG that was hidden in our slot
    458     jsval rngp;
    459     if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0, &rngp))
     450    double r;
     451    if(!ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface->MathRandom(r))
     452    {
    460453        return JS_FALSE;
    461     boost::rand48* rng = static_cast<boost::rand48*>(JSVAL_TO_PRIVATE(rngp));
     454    }
     455    else
     456    {
     457        jsval rv = JS_NumberValue(r);
     458        JS_SET_RVAL(cx, vp, rv);
     459        return JS_TRUE;
     460    }
     461}
    462462
    463     double r = generate_uniform_real(*rng, 0.0, 1.0);
     463} // anonymous namespace
    464464
    465     jsval rv;
    466     if (!JS_NewNumberValue(cx, r, &rv))
    467         return JS_FALSE;
    468     JS_SET_RVAL(cx, vp, rv);
    469     return JS_TRUE;
     465bool ScriptInterface::MathRandom(double& nbr)
     466{
     467    if (m->m_rng == NULL)
     468        return false;
     469    nbr = generate_uniform_real(*(m->m_rng), 0.0, 1.0);
     470    return true;
    470471}
    471472
    472 } // anonymous namespace
    473 
    474473ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime) :
    475474    m_runtime(runtime)
    476475{
    477     JSBool ok;
     476    bool ok;
    478477
    479478    m_cx = JS_NewContext(m_runtime->m_rt, STACK_CHUNK_SIZE);
    480479    ENSURE(m_cx);
    481480
     481    JS_SetParallelCompilationEnabled(m_cx, true);
     482
    482483    // For GC debugging:
    483484    // JS_SetGCZeal(m_cx, 2);
    484485
     
    486487
    487488    JS_SetErrorReporter(m_cx, ErrorReporter);
    488489
    489     uint32 options = 0;
    490     options |= JSOPTION_STRICT; // "warn on dubious practice"
    491     options |= JSOPTION_XML; // "ECMAScript for XML support: parse <!-- --> as a token"
     490    uint32_t options = 0;
     491    options |= JSOPTION_EXTRA_WARNINGS; // "warn on dubious practice"
     492    // We use strict mode to encourage better coding practices and
     493    //to get code that can be optimized better by Spidermonkey's JIT compiler.
     494    options |= JSOPTION_STRICT_MODE;
     495    //options |= JSOPTION_ALLOW_XML; // "ECMAScript for XML support: parse <!-- --> as a token"
    492496    options |= JSOPTION_VAROBJFIX; // "recommended" (fixes variable scoping)
    493497
    494498    // Enable method JIT, unless script profiling/debugging is enabled (since profiling/debugging
     
    496500    // TODO: Verify what exactly is incompatible
    497501    if (!g_ScriptProfilingEnabled && !g_JSDebuggerEnabled)
    498502    {
    499         options |= JSOPTION_METHODJIT;
     503        options |= JSOPTION_BASELINE;
     504        options |= JSOPTION_ION;
     505        options |= JSOPTION_TYPE_INFERENCE;
     506        options |= JSOPTION_COMPILE_N_GO;
    500507
    501508        // Some other JIT flags to experiment with:
    502         options |= JSOPTION_JIT;
    503         options |= JSOPTION_PROFILING;
     509        //options |= JSOPTION_METHODJIT_ALWAYS;
    504510    }
    505511
    506512    JS_SetOptions(m_cx, options);
    507     JS_SetVersion(m_cx, JSVERSION_LATEST);
     513   
     514    JSAutoRequest rq(m_cx);
     515   
     516    JS::CompartmentOptions opt;
     517    opt.setVersion(JSVERSION_LATEST);
     518    m_glob = JS_NewGlobalObject(m_cx, &global_class, NULL, opt);
     519    m_comp = JS_EnterCompartment(m_cx, m_glob);
     520    JS_SetGlobalObject(m_cx, m_glob);
    508521
    509     m_glob = JS_NewCompartmentAndGlobalObject(m_cx, &global_class, NULL);
    510 
    511522    ok = JS_InitStandardClasses(m_cx, m_glob);
    512523    ENSURE(ok);
     524   
     525    //JS_SetVersionForCompartment(m_comp, JSVERSION_LATEST);
    513526
     527
    514528    JS_DefineProperty(m_cx, m_glob, "global", OBJECT_TO_JSVAL(m_glob), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY
    515529            | JSPROP_PERMANENT);
    516530
     
    529543
    530544ScriptInterface_impl::~ScriptInterface_impl()
    531545{
     546    {
     547        JSAutoRequest rq(m_cx);
     548        JS_LeaveCompartment(m_cx, m_comp);
     549    }
    532550    JS_DestroyContext(m_cx);
    533551}
    534552
    535 void ScriptInterface_impl::Register(const char* name, JSNative fptr, uintN nargs)
     553void ScriptInterface_impl::Register(const char* name, JSNative fptr, uint nargs)
    536554{
     555    JSAutoRequest rq(m_cx);
    537556    JSFunction* func = JS_DefineFunction(m_cx, m_nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
    538557
    539558    if (!func)
     
    552571        > LockedStringFlyweight;
    553572
    554573        LockedStringFlyweight fw(name);
    555         JS_SetReservedSlot(m_cx, JS_GetFunctionObject(func), 0, PRIVATE_TO_JSVAL((void*)fw.get().c_str()));
     574        JS_SetReservedSlot(JS_GetFunctionObject(func), 0, PRIVATE_TO_JSVAL((void*)fw.get().c_str()));
    556575    }
    557576}
    558577
     
    599618    JS_ShutDown();
    600619}
    601620
     621void ScriptInterface::Tick()
     622{
     623    js::NotifyAnimationActivity(m->m_glob);
     624}
     625
    602626void ScriptInterface::SetCallbackData(void* pCBData)
    603627{
    604628    m_CxPrivate.pCBData = pCBData;
     
    633657
    634658bool ScriptInterface::ReplaceNondeterministicRNG(boost::rand48& rng)
    635659{
    636     jsval math;
    637     if (JS_GetProperty(m->m_cx, m->m_glob, "Math", &math) && JSVAL_IS_OBJECT(math))
     660    JSAutoRequest rq(m->m_cx);
     661    JS::RootedValue math(m->m_cx);
     662    if (JS_GetProperty(m->m_cx, m->m_glob, "Math", math.address()) && !JSVAL_IS_PRIMITIVE(math.get()))
    638663    {
    639664        JSFunction* random = JS_DefineFunction(m->m_cx, JSVAL_TO_OBJECT(math), "random", Math_random, 0,
    640665            JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
    641666        if (random)
    642667        {
    643             // Store the RNG in a slot which is sort-of-guaranteed to be unused by the JS engine
    644             if (JS_SetReservedSlot(m->m_cx, JS_GetFunctionObject(random), 0, PRIVATE_TO_JSVAL(&rng)))
    645                 return true;
     668            m->m_rng = &rng;
     669            return true;
    646670        }
    647671    }
    648672
     
    652676
    653677void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs)
    654678{
    655     m->Register(name, fptr, (uintN)nargs);
     679    m->Register(name, fptr, (uint)nargs);
    656680}
    657681
    658682JSContext* ScriptInterface::GetContext() const
     
    670694    return m->m_runtime;
    671695}
    672696
    673 AutoGCRooter* ScriptInterface::ReplaceAutoGCRooter(AutoGCRooter* rooter)
    674 {
    675     AutoGCRooter* ret = m->m_runtime->m_rooter;
    676     m->m_runtime->m_rooter = rooter;
    677     return ret;
    678 }
    679697
    680 
    681 jsval ScriptInterface::CallConstructor(jsval ctor, jsval arg)
     698jsval ScriptInterface::CallConstructor(jsval ctor, int argc, jsval argv)
    682699{
    683     if (!JSVAL_IS_OBJECT(ctor))
     700    JSAutoRequest rq(m->m_cx);
     701    if (JSVAL_IS_PRIMITIVE(ctor))
    684702    {
    685703        LOGERROR(L"CallConstructor: ctor is not an object");
    686704        return JSVAL_VOID;
    687705    }
    688706
    689     return OBJECT_TO_JSVAL(JS_New(m->m_cx, JSVAL_TO_OBJECT(ctor), 1, &arg));
     707    // Passing argc 0 and argv JSVAL_VOID causes a crash in mozjs24
     708    if (argc == 0)
     709    {
     710        return OBJECT_TO_JSVAL(JS_New(m->m_cx, JSVAL_TO_OBJECT(ctor), 0, NULL));
     711    }
     712    else
     713        return OBJECT_TO_JSVAL(JS_New(m->m_cx, JSVAL_TO_OBJECT(ctor), argc, &argv));
    690714}
    691715
    692716jsval ScriptInterface::NewObjectFromConstructor(jsval ctor)
    693717{
     718    JSAutoRequest rq(m->m_cx);
    694719    // Get the constructor's prototype
    695720    // (Can't use JS_GetPrototype, since we want .prototype not .__proto__)
    696     jsval protoVal;
    697     if (!JS_GetProperty(m->m_cx, JSVAL_TO_OBJECT(ctor), "prototype", &protoVal))
     721    JS::RootedValue protoVal(m->m_cx);
     722    if (!JS_GetProperty(m->m_cx, JSVAL_TO_OBJECT(ctor), "prototype", protoVal.address()))
    698723    {
    699724        LOGERROR(L"NewObjectFromConstructor: can't get prototype");
    700725        return JSVAL_VOID;
    701726    }
    702727
    703     if (!JSVAL_IS_OBJECT(protoVal))
     728    if (JSVAL_IS_PRIMITIVE(protoVal.get()))
    704729    {
    705730        LOGERROR(L"NewObjectFromConstructor: prototype is not an object");
    706731        return JSVAL_VOID;
    707732    }
    708733
    709     JSObject* proto = JSVAL_TO_OBJECT(protoVal);
    710     JSObject* parent = JS_GetParent(m->m_cx, JSVAL_TO_OBJECT(ctor));
     734    JSObject* proto = JSVAL_TO_OBJECT(protoVal.get());
     735    JSObject* parent = JS_GetParent(JSVAL_TO_OBJECT(ctor));
    711736    // TODO: rooting?
    712737    if (!proto || !parent)
    713738    {
     
    727752
    728753void ScriptInterface::DefineCustomObjectType(JSClass *clasp, JSNative constructor, uint minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
    729754{
     755    JSAutoRequest rq(m->m_cx);
    730756    std::string typeName = clasp->name;
    731757
    732758    if (m_CustomObjectTypes.find(typeName) != m_CustomObjectTypes.end())
     
    774800
    775801bool ScriptInterface::CallFunction_(jsval val, const char* name, size_t argc, jsval* argv, jsval& ret)
    776802{
     803    JSAutoRequest rq(m->m_cx);
    777804    JSObject* obj;
    778805    if (!JS_ValueToObject(m->m_cx, val, &obj) || obj == NULL)
    779806        return false;
     
    782809    // when calling an undefined value
    783810    JSBool found;
    784811    if (!JS_HasProperty(m->m_cx, obj, name, &found) || !found)
    785         return false;
     812        return JS_FALSE;
    786813
    787     JSBool ok = JS_CallFunctionName(m->m_cx, obj, name, (uintN)argc, argv, &ret);
     814    bool ok = JS_CallFunctionName(m->m_cx, obj, name, (uint)argc, argv, &ret);
    788815
    789     return ok ? true : false;
     816    return ok ? JS_TRUE : JS_FALSE;
    790817}
    791818
    792819jsval ScriptInterface::GetGlobalObject()
    793820{
    794     return OBJECT_TO_JSVAL(JS_GetGlobalObject(m->m_cx));
     821    JSAutoRequest rq(m->m_cx);
     822    return OBJECT_TO_JSVAL(JS_GetGlobalForScopeChain(m->m_cx));
    795823}
    796824
    797825JSClass* ScriptInterface::GetGlobalClass()
     
    801829
    802830bool ScriptInterface::SetGlobal_(const char* name, jsval value, bool replace)
    803831{
     832    JSAutoRequest rq(m->m_cx);
    804833    if (!replace)
    805834    {
    806835        JSBool found;
    807836        if (!JS_HasProperty(m->m_cx, m->m_glob, name, &found))
    808             return false;
     837            return JS_FALSE;
    809838        if (found)
    810839        {
    811840            JS_ReportError(m->m_cx, "SetGlobal \"%s\" called multiple times", name);
    812             return false;
     841            return JS_FALSE;
    813842        }
    814843    }
    815844
    816     JSBool ok = JS_DefineProperty(m->m_cx, m->m_glob, name, value, NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY
    817             | JSPROP_PERMANENT);
    818     return ok ? true : false;
     845    bool ok = JS_DefineProperty(m->m_cx, m->m_glob, name, value, NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY
     846            | JSPROP_PERMANENT);
     847    return ok ? JS_TRUE : JS_FALSE;
    819848}
    820849
    821850bool ScriptInterface::SetProperty_(jsval obj, const char* name, jsval value, bool constant, bool enumerate)
    822851{
    823     uintN attrs = 0;
     852    JSAutoRequest rq(m->m_cx);
     853    uint attrs = 0;
    824854    if (constant)
    825855        attrs |= JSPROP_READONLY | JSPROP_PERMANENT;
    826856    if (enumerate)
    827857        attrs |= JSPROP_ENUMERATE;
    828858
    829     if (! JSVAL_IS_OBJECT(obj))
     859    if (JSVAL_IS_PRIMITIVE(obj))
    830860        return false;
    831861    JSObject* object = JSVAL_TO_OBJECT(obj);
    832862
     
    837867
    838868bool ScriptInterface::SetProperty_(jsval obj, const wchar_t* name, jsval value, bool constant, bool enumerate)
    839869{
    840     uintN attrs = 0;
     870    JSAutoRequest rq(m->m_cx);
     871    uint attrs = 0;
    841872    if (constant)
    842873        attrs |= JSPROP_READONLY | JSPROP_PERMANENT;
    843874    if (enumerate)
    844875        attrs |= JSPROP_ENUMERATE;
    845876
    846     if (! JSVAL_IS_OBJECT(obj))
     877    if ( JSVAL_IS_PRIMITIVE(obj))
    847878        return false;
    848879    JSObject* object = JSVAL_TO_OBJECT(obj);
    849880
     
    855886
    856887bool ScriptInterface::SetPropertyInt_(jsval obj, int name, jsval value, bool constant, bool enumerate)
    857888{
    858     uintN attrs = 0;
     889    JSAutoRequest rq(m->m_cx);
     890    uint attrs = 0;
    859891    if (constant)
    860892        attrs |= JSPROP_READONLY | JSPROP_PERMANENT;
    861893    if (enumerate)
    862894        attrs |= JSPROP_ENUMERATE;
    863895
    864     if (! JSVAL_IS_OBJECT(obj))
     896    if ( JSVAL_IS_PRIMITIVE(obj))
    865897        return false;
    866898    JSObject* object = JSVAL_TO_OBJECT(obj);
    867899
     
    870902    return true;
    871903}
    872904
    873 bool ScriptInterface::GetProperty_(jsval obj, const char* name, jsval& out)
     905bool ScriptInterface::GetProperty_(jsval obj, const char* name, JS::MutableHandleValue out)
    874906{
    875     if (! JSVAL_IS_OBJECT(obj))
     907    JSAutoRequest rq(m->m_cx);
     908    if ( JSVAL_IS_PRIMITIVE(obj))
    876909        return false;
    877910    JSObject* object = JSVAL_TO_OBJECT(obj);
    878911
    879     if (!JS_GetProperty(m->m_cx, object, name, &out))
     912    if (!JS_GetProperty(m->m_cx, object, name, out.address()))
    880913        return false;
    881914    return true;
    882915}
    883916
    884 bool ScriptInterface::GetPropertyInt_(jsval obj, int name, jsval& out)
     917bool ScriptInterface::GetPropertyInt_(jsval obj, int name, JS::MutableHandleValue out)
    885918{
    886     if (! JSVAL_IS_OBJECT(obj))
     919    JSAutoRequest rq(m->m_cx);
     920    if ( JSVAL_IS_PRIMITIVE(obj))
    887921        return false;
    888922    JSObject* object = JSVAL_TO_OBJECT(obj);
    889923
    890     if (!JS_GetPropertyById(m->m_cx, object, INT_TO_JSID(name), &out))
     924    if (!JS_GetPropertyById(m->m_cx, object, INT_TO_JSID(name), out.address()))
    891925        return false;
    892926    return true;
    893927}
    894928
    895929bool ScriptInterface::HasProperty(jsval obj, const char* name)
    896930{
    897     if (! JSVAL_IS_OBJECT(obj))
    898         return false;
     931    // TODO: proper errorhandling
     932    JSAutoRequest rq(m->m_cx);
     933    if ( JSVAL_IS_PRIMITIVE(obj))
     934        return JS_FALSE;
    899935    JSObject* object = JSVAL_TO_OBJECT(obj);
    900936
    901937    JSBool found;
    902938    if (!JS_HasProperty(m->m_cx, object, name, &found))
    903         return false;
    904     return (found != JS_FALSE);
     939        return JS_FALSE;
     940    return found;
    905941}
    906942
    907 bool ScriptInterface::EnumeratePropertyNamesWithPrefix(jsval obj, const char* prefix, std::vector<std::string>& out)
     943bool ScriptInterface::EnumeratePropertyNamesWithPrefix(JS::HandleObject obj, const char* prefix, std::vector<std::string>& out)
    908944{
    909     utf16string prefix16 (prefix, prefix+strlen(prefix));
     945    JSAutoRequest rq(m->m_cx);
     946    if (obj.get() == 0x0)
     947        return true;
    910948
    911     if (! JSVAL_IS_OBJECT(obj))
    912         return false; // TODO: log error messages
     949//  if ( obj.get().isPrimitive() )
     950//      return false; // TODO: log error messages
    913951
    914     JSObject* it = JS_NewPropertyIterator(m->m_cx, JSVAL_TO_OBJECT(obj));
     952    JSObject* it = JS_NewPropertyIterator(m->m_cx, obj.get());
    915953    if (!it)
    916954        return false;
    917955
     
    927965            continue; // ignore integer properties
    928966
    929967        JSString* name = JSVAL_TO_STRING(val);
    930         size_t len;
    931         const jschar* chars = JS_GetStringCharsAndLength(m->m_cx, name, &len);
    932         if (chars && len >= prefix16.size() && memcmp(chars, prefix16.c_str(), prefix16.size()*2) == 0)
    933             out.push_back(std::string(chars, chars+len)); // handles Unicode poorly
     968        size_t len = strlen(prefix)+1;
     969        char buf[len];
     970        size_t prefixLen = strlen(prefix) * sizeof(char);
     971        JS_EncodeStringToBuffer(m->m_cx, name, buf, prefixLen);
     972        buf[len-1]= '\0';
     973        if(0 == strcmp(buf, prefix))
     974        {
     975            size_t len;
     976            const jschar* chars = JS_GetStringCharsAndLength(m->m_cx, name, &len);
     977            out.push_back(std::string(chars, chars+len));
     978        }
     979//      if (chars && len >= prefix16.size() && memcmp(chars, prefix16.c_str(), prefix16.size()*2) == 0)
     980//          out.push_back(std::string(chars, chars+len)); // handles Unicode poorly
     981
    934982    }
    935983
    936984    // Recurse up the prototype chain
    937     JSObject* prototype = JS_GetPrototype(m->m_cx, JSVAL_TO_OBJECT(obj));
    938     if (prototype)
     985    JS::RootedObject prototype(m->m_cx);
     986    if (JS_GetPrototype(m->m_cx, obj, prototype.address()))
    939987    {
    940         if (! EnumeratePropertyNamesWithPrefix(OBJECT_TO_JSVAL(prototype), prefix, out))
     988        if (! EnumeratePropertyNamesWithPrefix(prototype, prefix, out))
    941989            return false;
    942990    }
    943991
    944992    return true;
    945993}
    946994
    947 bool ScriptInterface::SetPrototype(jsval obj, jsval proto)
     995bool ScriptInterface::SetPrototype(JS::HandleObject obj, JS::HandleObject proto)
    948996{
    949     if (!JSVAL_IS_OBJECT(obj) || !JSVAL_IS_OBJECT(proto))
    950         return false;
    951     return JS_SetPrototype(m->m_cx, JSVAL_TO_OBJECT(obj), JSVAL_TO_OBJECT(proto)) ? true : false;
     997    JSAutoRequest rq(m->m_cx);
     998    //if (JSVAL_IS_PRIMITIVE(obj) || JSVAL_IS_PRIMITIVE(proto))
     999    //  return false;
     1000    return JS_SetPrototype(m->m_cx, obj, proto);
    9521001}
    9531002
    9541003bool ScriptInterface::FreezeObject(jsval obj, bool deep)
    9551004{
    956     if (!JSVAL_IS_OBJECT(obj))
     1005    JSAutoRequest rq(m->m_cx);
     1006    if (JSVAL_IS_PRIMITIVE(obj))
    9571007        return false;
    9581008
    9591009    if (deep)
     
    9641014
    9651015bool ScriptInterface::LoadScript(const VfsPath& filename, const std::string& code)
    9661016{
    967     // Compile the code in strict mode, to encourage better coding practices and
    968     // to possibly help SpiderMonkey with optimisations
    969     std::wstring codeStrict = L"\"use strict\";\n" + wstring_from_utf8(code);
    970     utf16string codeUtf16(codeStrict.begin(), codeStrict.end());
    971     uintN lineNo = 0; // put the automatic 'use strict' on line 0, so the real code starts at line 1
     1017    JSAutoRequest rq(m->m_cx);
     1018    utf16string codeUtf16(code.begin(), code.end());
     1019    uint lineNo = 1;
    9721020
    973     JSFunction* func = JS_CompileUCFunction(m->m_cx, NULL, NULL, 0, NULL,
    974             reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uintN)(codeUtf16.length()),
    975             utf8_from_wstring(filename.string()).c_str(), lineNo);
    976 
     1021    JS::Rooted<JSFunction*> func(m->m_cx,
     1022        JS_CompileUCFunction(m->m_cx, m->m_glob, utf8_from_wstring(filename.string()).c_str(), 0, NULL,
     1023            reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uint)(codeUtf16.length()),
     1024            utf8_from_wstring(filename.string()).c_str(), lineNo)
     1025    );
    9771026    if (!func)
    9781027        return false;
    9791028
    980     jsval scriptRval;
    981     JSBool ok = JS_CallFunction(m->m_cx, NULL, func, 0, NULL, &scriptRval);
     1029    JS::RootedValue val(m->m_cx);
     1030    bool ok = JS_CallFunction(m->m_cx, NULL, func, 0, NULL, val.address());
    9821031
    9831032    return ok ? true : false;
    9841033}
    9851034
    9861035bool ScriptInterface::LoadGlobalScript(const VfsPath& filename, const std::wstring& code)
    9871036{
    988     // Compile the code in strict mode, to encourage better coding practices and
    989     // to possibly help SpiderMonkey with optimisations
    990     std::wstring codeStrict = L"\"use strict\";\n" + code;
    991     utf16string codeUtf16(codeStrict.begin(), codeStrict.end());
    992     uintN lineNo = 0; // put the automatic 'use strict' on line 0, so the real code starts at line 1
     1037    JSAutoRequest rq(m->m_cx);
     1038    utf16string codeUtf16(code.begin(), code.end());
     1039    uint lineNo = 1;
    9931040
    9941041    jsval rval;
    995     JSBool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob,
    996             reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uintN)(codeUtf16.length()),
     1042    bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob,
     1043            reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uint)(codeUtf16.length()),
    9971044            utf8_from_wstring(filename.string()).c_str(), lineNo, &rval);
    9981045
    999     return ok ? true : false;
     1046    return ok;
    10001047}
    10011048
    10021049bool ScriptInterface::LoadGlobalScriptFile(const VfsPath& path)
    10031050{
     1051    JSAutoRequest rq(m->m_cx);
    10041052    if (!VfsFileExists(path))
    10051053    {
    10061054        LOGERROR(L"File '%ls' does not exist", path.string().c_str());
     
    10191067
    10201068    std::wstring code = wstring_from_utf8(file.DecodeUTF8()); // assume it's UTF-8
    10211069
    1022     // Compile the code in strict mode, to encourage better coding practices and
    1023     // to possibly help SpiderMonkey with optimisations
    1024     std::wstring codeStrict = L"\"use strict\";\n" + code;
    1025     utf16string codeUtf16(codeStrict.begin(), codeStrict.end());
    1026     uintN lineNo = 0; // put the automatic 'use strict' on line 0, so the real code starts at line 1
     1070    utf16string codeUtf16(code.begin(), code.end());
     1071    uint lineNo = 1;
    10271072
    10281073    jsval rval;
    1029     JSBool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob,
    1030             reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uintN)(codeUtf16.length()),
     1074    bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob,
     1075            reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uint)(codeUtf16.length()),
    10311076            utf8_from_wstring(path.string()).c_str(), lineNo, &rval);
    10321077
    1033     return ok ? true : false;
     1078    return ok;
    10341079}
    10351080
    10361081
     
    10421087
    10431088bool ScriptInterface::Eval_(const char* code, jsval& rval)
    10441089{
     1090    JSAutoRequest rq(m->m_cx);
    10451091    utf16string codeUtf16(code, code+strlen(code));
    10461092
    1047     JSBool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uintN)codeUtf16.length(), "(eval)", 1, &rval);
    1048     return ok ? true : false;
     1093    bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uint)codeUtf16.length(), "(eval)", 1, &rval);
     1094    return ok;
    10491095}
    10501096
    10511097bool ScriptInterface::Eval_(const wchar_t* code, jsval& rval)
    10521098{
     1099    JSAutoRequest rq(m->m_cx);
    10531100    utf16string codeUtf16(code, code+wcslen(code));
    10541101
    1055     JSBool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uintN)codeUtf16.length(), "(eval)", 1, &rval);
    1056     return ok ? true : false;
     1102    bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uint)codeUtf16.length(), "(eval)", 1, &rval);
     1103    return ok;
    10571104}
    10581105
    10591106CScriptValRooted ScriptInterface::ParseJSON(const std::string& string_utf8)
    10601107{
     1108    JSAutoRequest rq(m->m_cx);
    10611109    std::wstring attrsW = wstring_from_utf8(string_utf8);
    1062     utf16string string(attrsW.begin(), attrsW.end());
    1063 
    1064     jsval vp;
    1065     JSONParser* parser = JS_BeginJSONParse(m->m_cx, &vp);
    1066     if (!parser)
    1067     {
    1068         LOGERROR(L"ParseJSON failed to begin");
    1069         return CScriptValRooted();
    1070     }
    1071 
    1072     if (!JS_ConsumeJSONText(m->m_cx, parser, reinterpret_cast<const jschar*>(string.c_str()), (uint32)string.size()))
    1073     {
    1074         LOGERROR(L"ParseJSON failed to consume");
    1075         return CScriptValRooted();
    1076     }
    1077 
    1078     if (!JS_FinishJSONParse(m->m_cx, parser, JSVAL_NULL))
    1079     {
    1080         LOGERROR(L"ParseJSON failed to finish");
    1081         return CScriptValRooted();
    1082     }
    1083 
     1110    utf16string string(attrsW.begin(), attrsW.end());
     1111    JS::Rooted<jsval> vp(m->m_cx);
     1112    JS_ParseJSON(m->m_cx, reinterpret_cast<const jschar*>(string.c_str()), (uint32_t)string.size(), &vp);
    10841113    return CScriptValRooted(m->m_cx, vp);
    10851114}
    10861115
     
    11091138
    11101139struct Stringifier
    11111140{
    1112     static JSBool callback(const jschar* buf, uint32 len, void* data)
     1141    static JSBool callback(const jschar* buf, uint32_t len, void* data)
    11131142    {
    11141143        utf16string str(buf, buf+len);
    11151144        std::wstring strw(str.begin(), str.end());
     
    11241153
    11251154struct StringifierW
    11261155{
    1127     static JSBool callback(const jschar* buf, uint32 len, void* data)
     1156    static JSBool callback(const jschar* buf, uint32_t len, void* data)
    11281157    {
    11291158        utf16string str(buf, buf+len);
    11301159        static_cast<StringifierW*>(data)->stream << std::wstring(str.begin(), str.end());
     
    11361165
    11371166std::string ScriptInterface::StringifyJSON(jsval obj, bool indent)
    11381167{
     1168    JSAutoRequest rq(m->m_cx);
    11391169    Stringifier str;
    11401170    if (!JS_Stringify(m->m_cx, &obj, NULL, indent ? INT_TO_JSVAL(2) : JSVAL_VOID, &Stringifier::callback, &str))
    11411171    {
     
    11511181
    11521182std::wstring ScriptInterface::ToString(jsval obj, bool pretty)
    11531183{
     1184    JSAutoRequest rq(m->m_cx);
    11541185    if (JSVAL_IS_VOID(obj))
    11551186        return L"(void 0)";
    11561187
     
    11631194        // Temporary disable the error reporter, so we don't print complaints about cyclic values
    11641195        JSErrorReporter er = JS_SetErrorReporter(m->m_cx, NULL);
    11651196
    1166         bool ok = JS_Stringify(m->m_cx, &obj, NULL, INT_TO_JSVAL(2), &StringifierW::callback, &str) == JS_TRUE;
     1197        JSBool ok = JS_Stringify(m->m_cx, &obj, NULL, INT_TO_JSVAL(2), &StringifierW::callback, &str);
    11671198
    11681199        // Restore error reporter
    11691200        JS_SetErrorReporter(m->m_cx, er);
     
    11851216
    11861217void ScriptInterface::ReportError(const char* msg)
    11871218{
     1219    JSAutoRequest rq(m->m_cx);
    11881220    // JS_ReportError by itself doesn't seem to set a JS-style exception, and so
    11891221    // script callers will be unable to catch anything. So use JS_SetPendingException
    11901222    // to make sure there really is a script-level exception. But just set it to undefined
     
    11981230
    11991231bool ScriptInterface::IsExceptionPending(JSContext* cx)
    12001232{
     1233    JSAutoRequest rq(cx);
    12011234    return JS_IsExceptionPending(cx) ? true : false;
    12021235}
    12031236
    1204 JSClass* ScriptInterface::GetClass(JSContext* cx, JSObject* obj)
     1237JSClass* ScriptInterface::GetClass(JSObject* obj)
    12051238{
    1206     UNUSED2(cx); // unused if not JS_THREADSAFE
    1207 
    1208     return JS_GET_CLASS(cx, obj);
     1239    return JS_GetClass(obj);
    12091240}
    12101241
    1211 void* ScriptInterface::GetPrivate(JSContext* cx, JSObject* obj)
     1242void* ScriptInterface::GetPrivate(JSObject* obj)
    12121243{
    12131244    // TODO: use JS_GetInstancePrivate
    1214     return JS_GetPrivate(cx, obj);
     1245    return JS_GetPrivate(obj);
    12151246}
    12161247
    12171248void ScriptInterface::DumpHeap()
    12181249{
    12191250#if MOZJS_DEBUG_ABI
    1220     JS_DumpHeap(m->m_cx, stderr, NULL, 0, NULL, (size_t)-1, NULL);
     1251    JS_DumpHeap(GetJSRuntime(), stderr, NULL, JSTRACE_OBJECT, NULL, (size_t)-1, NULL);
    12211252#endif
    12221253    fprintf(stderr, "# Bytes allocated: %u\n", JS_GetGCParameter(GetJSRuntime(), JSGC_BYTES));
    1223     JS_GC(m->m_cx);
     1254    JS_GC(GetJSRuntime());
    12241255    fprintf(stderr, "# Bytes allocated after GC: %u\n", JS_GetGCParameter(GetJSRuntime(), JSGC_BYTES));
    12251256}
    12261257
     
    12331264{
    12341265public:
    12351266    ValueCloner(ScriptInterface& from, ScriptInterface& to) :
    1236         scriptInterfaceFrom(from), cxFrom(from.GetContext()), cxTo(to.GetContext()), m_RooterFrom(from), m_RooterTo(to)
     1267        scriptInterfaceFrom(from), cxFrom(from.GetContext()), cxTo(to.GetContext()), m_RooterFrom(from.GetContext()), m_RooterTo(to.GetContext())
    12371268    {
    12381269    }
    12391270
     
    12471278        if (it != m_Mapping.end())
    12481279            return it->second;
    12491280
    1250         m_RooterFrom.Push(val); // root it so our mapping doesn't get invalidated
     1281        m_RooterFrom.append(val); // root it so our mapping doesn't get invalidated
    12511282
    12521283        return Clone(val);
    12531284    }
     
    12591290    // Clone a new value (and root it and add it to the mapping)
    12601291    jsval Clone(jsval val)
    12611292    {
     1293        JSAutoRequest rq(cxFrom);
    12621294        if (JSVAL_IS_DOUBLE(val))
    12631295        {
    1264             jsval rval;
    1265             CLONE_REQUIRE(JS_NewNumberValue(cxTo, JSVAL_TO_DOUBLE(val), &rval), L"JS_NewNumberValue");
    1266             m_RooterTo.Push(rval);
     1296            jsval rval = JS_NumberValue(JSVAL_TO_DOUBLE(val));
     1297            CLONE_REQUIRE(!JSVAL_IS_VOID(rval), L"JS_NumberValue");
     1298            m_RooterTo.append(rval);
    12671299            return rval;
    12681300        }
    12691301
     
    12721304            size_t len;
    12731305            const jschar* chars = JS_GetStringCharsAndLength(cxFrom, JSVAL_TO_STRING(val), &len);
    12741306            CLONE_REQUIRE(chars, L"JS_GetStringCharsAndLength");
    1275             JSString* str = JS_NewUCStringCopyN(cxTo, chars, len);
    1276             CLONE_REQUIRE(str, L"JS_NewUCStringCopyN");
    1277             jsval rval = STRING_TO_JSVAL(str);
    1278             m_Mapping[JSVAL_TO_GCTHING(val)] = rval;
    1279             m_RooterTo.Push(rval);
    1280             return rval;
     1307            {
     1308                JSAutoRequest rq(cxTo);
     1309                JSString* str = JS_NewUCStringCopyN(cxTo, chars, len);
     1310                CLONE_REQUIRE(str, L"JS_NewUCStringCopyN");
     1311                jsval rval = STRING_TO_JSVAL(str);
     1312                m_Mapping[JSVAL_TO_GCTHING(val)] = rval;
     1313                m_RooterTo.append(rval);
     1314                return rval;
     1315            }
    12811316        }
    12821317
    1283         ENSURE(JSVAL_IS_OBJECT(val));
     1318        ENSURE(!JSVAL_IS_PRIMITIVE(val));
    12841319
    12851320        JSObject* newObj;
    12861321        if (JS_IsArrayObject(cxFrom, JSVAL_TO_OBJECT(val)))
    12871322        {
    1288             jsuint length;
     1323            uint length;
    12891324            CLONE_REQUIRE(JS_GetArrayLength(cxFrom, JSVAL_TO_OBJECT(val), &length), L"JS_GetArrayLength");
    1290             newObj = JS_NewArrayObject(cxTo, length, NULL);
     1325            {
     1326                JSAutoRequest rq(cxTo);
     1327                newObj = JS_NewArrayObject(cxTo, length, NULL);
     1328            }   
    12911329            CLONE_REQUIRE(newObj, L"JS_NewArrayObject");
    12921330        }
    12931331        else
    12941332        {
    1295             newObj = JS_NewObject(cxTo, NULL, NULL, NULL);
     1333            {
     1334                JSAutoRequest rq(cxTo);
     1335                newObj = JS_NewObject(cxTo, NULL, NULL, NULL);
     1336            }
    12961337            CLONE_REQUIRE(newObj, L"JS_NewObject");
    12971338        }
    12981339
    12991340        m_Mapping[JSVAL_TO_GCTHING(val)] = OBJECT_TO_JSVAL(newObj);
    1300         m_RooterTo.Push(newObj);
     1341        m_RooterTo.append(OBJECT_TO_JSVAL(newObj));
    13011342
    1302         AutoJSIdArray ida (cxFrom, JS_Enumerate(cxFrom, JSVAL_TO_OBJECT(val)));
    1303         CLONE_REQUIRE(ida.get(), L"JS_Enumerate");
     1343        JS::AutoIdArray ida (cxFrom, JS_Enumerate(cxFrom, JSVAL_TO_OBJECT(val)));
     1344        CLONE_REQUIRE(ida, L"JS_Enumerate");
     1345       
     1346//      AutoGCRooter idaRooter(scriptInterfaceFrom);
     1347//      idaRooter.Push(&ida);
    13041348
    1305         AutoGCRooter idaRooter(scriptInterfaceFrom);
    1306         idaRooter.Push(ida.get());
    1307 
    13081349        for (size_t i = 0; i < ida.length(); ++i)
    13091350        {
    13101351            jsid id = ida[i];
    1311             jsval idval, propval;
    1312             CLONE_REQUIRE(JS_IdToValue(cxFrom, id, &idval), L"JS_IdToValue");
    1313             CLONE_REQUIRE(JS_GetPropertyById(cxFrom, JSVAL_TO_OBJECT(val), id, &propval), L"JS_GetPropertyById");
    1314             jsval newPropval = GetOrClone(propval);
     1352            JS::RootedValue idval(cxTo);
     1353            JS::RootedValue propval(cxTo);
     1354            CLONE_REQUIRE(JS_IdToValue(cxFrom, id, idval.address()), L"JS_IdToValue");
     1355            CLONE_REQUIRE(JS_GetPropertyById(cxFrom, JSVAL_TO_OBJECT(val), id, propval.address()), L"JS_GetPropertyById");
     1356            JS::RootedValue newPropval(cxTo, GetOrClone(propval));
    13151357
    13161358            if (JSVAL_IS_INT(idval))
    13171359            {
    13181360                // int jsids are portable across runtimes
    1319                 CLONE_REQUIRE(JS_SetPropertyById(cxTo, newObj, id, &newPropval), L"JS_SetPropertyById");
    1320             }
     1361                JSAutoRequest rq(cxTo);
     1362                CLONE_REQUIRE(JS_SetPropertyById(cxTo, newObj, id, newPropval.address()), L"JS_SetPropertyById");
     1363                        }
    13211364            else if (JSVAL_IS_STRING(idval))
    13221365            {
    13231366                // string jsids are runtime-specific, so we need to copy the string content
     
    13261369                size_t len;
    13271370                const jschar* chars = JS_GetStringCharsAndLength(cxFrom, idstr, &len);
    13281371                CLONE_REQUIRE(idstr, L"JS_GetStringCharsAndLength (id)");
    1329                 CLONE_REQUIRE(JS_SetUCProperty(cxTo, newObj, chars, len, &newPropval), L"JS_SetUCProperty");
     1372                {
     1373                    JSAutoRequest rq(cxTo);
     1374                            CLONE_REQUIRE(JS_SetUCProperty(cxTo, newObj, chars, len, newPropval.address()), L"JS_SetUCProperty");
     1375                }
    13301376            }
    13311377            else
    13321378            {
     
    13411387    JSContext* cxFrom;
    13421388    JSContext* cxTo;
    13431389    std::map<void*, jsval> m_Mapping;
    1344     AutoGCRooter m_RooterFrom;
    1345     AutoGCRooter m_RooterTo;
     1390    JS::AutoValueVector m_RooterFrom;
     1391    JS::AutoValueVector m_RooterTo;
    13461392};
    13471393
    13481394jsval ScriptInterface::CloneValueFromOtherContext(ScriptInterface& otherContext, jsval val)
     
    13541400}
    13551401
    13561402ScriptInterface::StructuredClone::StructuredClone() :
    1357     m_Context(NULL), m_Data(NULL), m_Size(0)
     1403    m_Data(NULL), m_Size(0)
    13581404{
    13591405}
    13601406
    13611407ScriptInterface::StructuredClone::~StructuredClone()
    13621408{
    13631409    if (m_Data)
    1364         JS_free(m_Context, m_Data);
     1410        JS_ClearStructuredClone(m_Data, m_Size);
    13651411}
    13661412
    13671413shared_ptr<ScriptInterface::StructuredClone> ScriptInterface::WriteStructuredClone(jsval v)
    13681414{
    1369     uint64* data = NULL;
     1415    JSAutoRequest rq(m->m_cx);
     1416    uint64_t* data = NULL;
    13701417    size_t nbytes = 0;
    1371     if (!JS_WriteStructuredClone(m->m_cx, v, &data, &nbytes, NULL, NULL))
     1418    if (!JS_WriteStructuredClone(m->m_cx, v, &data, &nbytes, NULL, NULL, JSVAL_VOID))
    13721419    {
    13731420        debug_warn(L"Writing a structured clone with JS_WriteStructuredClone failed!");
    13741421        return shared_ptr<StructuredClone>();
    13751422    }
    13761423
    13771424    shared_ptr<StructuredClone> ret (new StructuredClone);
    1378     ret->m_Context = m->m_cx;
    13791425    ret->m_Data = data;
    13801426    ret->m_Size = nbytes;
    13811427    return ret;
     
    13831429
    13841430jsval ScriptInterface::ReadStructuredClone(const shared_ptr<ScriptInterface::StructuredClone>& ptr)
    13851431{
     1432    JSAutoRequest rq(m->m_cx);
    13861433    jsval ret = JSVAL_VOID;
    13871434    JS_ReadStructuredClone(m->m_cx, ptr->m_Data, ptr->m_Size, JS_STRUCTURED_CLONE_VERSION, &ret, NULL, NULL);
    13881435    return ret;
  • source/scriptinterface/AutoRooters.h

     
    1 /* Copyright (C) 2010 Wildfire Games.
    2  * This file is part of 0 A.D.
    3  *
    4  * 0 A.D. is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * 0 A.D. is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 
    18 #ifndef INCLUDED_AUTOROOTERS
    19 #define INCLUDED_AUTOROOTERS
    20 
    21 #include "scriptinterface/ScriptTypes.h"
    22 
    23 #include "js/jsapi.h"
    24 
    25 /**
    26  * Helper for rooting large groups of script values.
    27  * Construct this object, push values into it, and they will all be rooted until this
    28  * object is destroyed.
    29  * Many of these objects can be used at once, but their lifetimes must be correctly nested.
    30  */
    31 class AutoGCRooter
    32 {
    33     NONCOPYABLE(AutoGCRooter);
    34 public:
    35     AutoGCRooter(ScriptInterface& scriptInterface);
    36     ~AutoGCRooter();
    37 
    38     void Push(JSObject* obj) { m_Objects.push_back(obj); }
    39     void Push(jsval val) { m_Vals.push_back(val); }
    40     void Push(JSIdArray* ida) { m_IdArrays.push_back(ida); }
    41 
    42     void Trace(JSTracer* trc);
    43 private:
    44     ScriptInterface& m_ScriptInterface;
    45     AutoGCRooter* m_Previous;
    46 
    47     std::vector<JSObject*> m_Objects;
    48     std::vector<jsval> m_Vals;
    49     std::vector<JSIdArray*> m_IdArrays;
    50     // TODO: add vectors of other value types
    51 };
    52 
    53 #endif // INCLUDED_AUTOROOTERS
  • source/scriptinterface/ScriptConversions.cpp

     
    3232
    3333template<> bool ScriptInterface::FromJSVal<bool>(JSContext* cx, jsval v, bool& out)
    3434{
     35    JSAutoRequest rq(cx);
    3536    JSBool ret;
    3637    WARN_IF_NOT(JSVAL_IS_BOOLEAN(v), v);
    3738    if (!JS_ValueToBoolean(cx, v, &ret))
     
    4243
    4344template<> bool ScriptInterface::FromJSVal<float>(JSContext* cx, jsval v, float& out)
    4445{
    45     jsdouble ret;
     46    JSAutoRequest rq(cx);
     47    double ret;
    4648    WARN_IF_NOT(JSVAL_IS_NUMBER(v), v);
    4749    if (!JS_ValueToNumber(cx, v, &ret))
    4850        return false;
     
    5254
    5355template<> bool ScriptInterface::FromJSVal<double>(JSContext* cx, jsval v, double& out)
    5456{
    55     jsdouble ret;
     57    JSAutoRequest rq(cx);
     58    double ret;
    5659    WARN_IF_NOT(JSVAL_IS_NUMBER(v), v);
    5760    if (!JS_ValueToNumber(cx, v, &ret))
    5861        return false;
     
    6265
    6366template<> bool ScriptInterface::FromJSVal<i32>(JSContext* cx, jsval v, i32& out)
    6467{
    65     int32 ret;
     68    JSAutoRequest rq(cx);
     69    // TODO: Change FromJSVal to use JS::RootedValue and remove this temporary workaround here
     70    JS::RootedValue v1(cx, v);
     71    int32_t ret;
    6672    WARN_IF_NOT(JSVAL_IS_NUMBER(v), v);
    67     if (!JS_ValueToECMAInt32(cx, v, &ret))
     73    if (!JS::ToInt32(cx, v1, &ret))
    6874        return false;
    6975    out = ret;
    7076    return true;
     
    7278
    7379template<> bool ScriptInterface::FromJSVal<u32>(JSContext* cx, jsval v, u32& out)
    7480{
    75     uint32 ret;
     81    JSAutoRequest rq(cx);
     82    uint32_t ret;
    7683    WARN_IF_NOT(JSVAL_IS_NUMBER(v), v);
    7784    if (!JS_ValueToECMAUint32(cx, v, &ret))
    7885        return false;
     
    8289
    8390template<> bool ScriptInterface::FromJSVal<u16>(JSContext* cx, jsval v, u16& out)
    8491{
    85     uint16 ret;
     92    JSAutoRequest rq(cx);
     93    uint16_t ret;
    8694    WARN_IF_NOT(JSVAL_IS_NUMBER(v), v);
    8795    if (!JS_ValueToUint16(cx, v, &ret))
    8896        return false;
     
    92100
    93101template<> bool ScriptInterface::FromJSVal<u8>(JSContext* cx, jsval v, u8& out)
    94102{
    95     uint16 ret;
     103    JSAutoRequest rq(cx);
     104    uint16_t ret;
    96105    WARN_IF_NOT(JSVAL_IS_NUMBER(v), v);
    97106    if (!JS_ValueToUint16(cx, v, &ret))
    98107        return false;
     
    102111
    103112template<> bool ScriptInterface::FromJSVal<long>(JSContext* cx, jsval v, long& out)
    104113{
    105     int32 tmp;
    106     JSBool ok = JS_ValueToInt32(cx, v, &tmp);
     114    int32_t tmp;
     115    bool ok = JS_ValueToInt32(cx, v, &tmp);
    107116    out = (long)tmp;
    108     return ok == JS_TRUE;
     117    return ok;
    109118}
    110119
    111120template<> bool ScriptInterface::FromJSVal<unsigned long>(JSContext* cx, jsval v, unsigned long& out)
    112121{
    113     int32 tmp;
    114     JSBool ok = JS_ValueToInt32(cx, v, &tmp);
     122    int32_t tmp;
     123    bool ok = JS_ValueToInt32(cx, v, &tmp);
    115124    out = (unsigned long)tmp;
    116     return ok == JS_TRUE;
     125    return ok;
    117126}
    118127
    119128// see comment below (where the same preprocessor condition is used)
     
    143152
    144153#endif
    145154
    146 // NOTE: we can't define a jsval specialisation, because that conflicts with integer types
     155template<> jsval ScriptInterface::ToJSVal<JS::Value>(JSContext* UNUSED(cx), const JS::Value& val)
     156{
     157    return val;
     158}
     159
    147160template<> bool ScriptInterface::FromJSVal<CScriptVal>(JSContext* UNUSED(cx), jsval v, CScriptVal& out)
    148161{
    149162    out = v;
    150163    return true;
    151164}
    152165
     166template<> bool ScriptInterface::FromJSVal<JS::RootedObject>(JSContext* UNUSED(cx), jsval v, JS::RootedObject& out)
     167{
     168    if (v.isObjectOrNull())
     169    {
     170        out.set(JSVAL_TO_OBJECT(v));
     171        return true;
     172    }
     173    return false;
     174}
     175
    153176template<> bool ScriptInterface::FromJSVal<CScriptValRooted>(JSContext* cx, jsval v, CScriptValRooted& out)
    154177{
    155178    out = CScriptValRooted(cx, v);
     
    158181
    159182template<> bool ScriptInterface::FromJSVal<std::wstring>(JSContext* cx, jsval v, std::wstring& out)
    160183{
     184    JSAutoRequest rq(cx);
    161185    WARN_IF_NOT(JSVAL_IS_STRING(v) || JSVAL_IS_NUMBER(v), v); // allow implicit number conversions
    162186    JSString* ret = JS_ValueToString(cx, v);
    163187    if (!ret)
     
    181205
    182206template<> bool ScriptInterface::FromJSVal<std::string>(JSContext* cx, jsval v, std::string& out)
    183207{
     208    JSAutoRequest rq(cx);
    184209    WARN_IF_NOT(JSVAL_IS_STRING(v) || JSVAL_IS_NUMBER(v), v); // allow implicit number conversions
    185210    JSString* ret = JS_ValueToString(cx, v);
    186211    if (!ret)
     
    205230
    206231template<> bool ScriptInterface::FromJSVal<Entity>(JSContext* cx, jsval v, Entity& out)
    207232{
     233    JSAutoRequest rq(cx);
    208234    JSObject* obj;
    209235    if (!JS_ValueToObject(cx, v, &obj) || obj == NULL)
    210236        FAIL("Argument must be an object");
    211237
    212     jsval templateName, id, player, position, rotation;
     238    JS::RootedValue templateName(cx);
     239    JS::RootedValue id(cx);
     240    JS::RootedValue player(cx);
     241    JS::RootedValue position(cx);
     242    JS::RootedValue rotation(cx);
    213243
    214244    // TODO: Report type errors
    215     if(!JS_GetProperty(cx, obj, "player", &player) || !FromJSVal(cx, player, out.playerID))
     245    if(!JS_GetProperty(cx, obj, "player", player.address()) || !FromJSVal(cx, player, out.playerID))
    216246        FAIL("Failed to read Entity.player property");
    217     if (!JS_GetProperty(cx, obj, "templateName", &templateName) || !FromJSVal(cx, templateName, out.templateName))
     247    if (!JS_GetProperty(cx, obj, "templateName", templateName.address()) || !FromJSVal(cx, templateName, out.templateName))
    218248        FAIL("Failed to read Entity.templateName property");
    219     if (!JS_GetProperty(cx, obj, "id", &id) || !FromJSVal(cx, id, out.entityID))
     249    if (!JS_GetProperty(cx, obj, "id", id.address()) || !FromJSVal(cx, id, out.entityID))
    220250        FAIL("Failed to read Entity.id property");
    221     if (!JS_GetProperty(cx, obj, "position", &position) || !FromJSVal(cx, position, out.position))
     251    if (!JS_GetProperty(cx, obj, "position", position.address()) || !FromJSVal(cx, position, out.position))
    222252        FAIL("Failed to read Entity.position property");
    223     if (!JS_GetProperty(cx, obj, "rotation", &rotation) || !FromJSVal(cx, rotation, out.rotation))
     253    if (!JS_GetProperty(cx, obj, "rotation", rotation.address()) || !FromJSVal(cx, rotation, out.rotation))
    224254        FAIL("Failed to read Entity.rotation property");
    225255
    226256    return true;
     
    234264    return val ? JSVAL_TRUE : JSVAL_FALSE;
    235265}
    236266
    237 template<> jsval ScriptInterface::ToJSVal<float>(JSContext* cx, const float& val)
     267template<> jsval ScriptInterface::ToJSVal<float>(JSContext* UNUSED(cx), const float& val)
    238268{
    239     jsval rval = JSVAL_VOID;
    240     JS_NewNumberValue(cx, val, &rval); // ignore return value
     269    jsval rval = JS_NumberValue(val);
    241270    return rval;
    242271}
    243272
    244 template<> jsval ScriptInterface::ToJSVal<double>(JSContext* cx, const double& val)
     273template<> jsval ScriptInterface::ToJSVal<double>(JSContext* UNUSED(cx), const double& val)
    245274{
    246     jsval rval = JSVAL_VOID;
    247     JS_NewNumberValue(cx, val, &rval); // ignore return value
     275    jsval rval = JS_NumberValue(val);
    248276    return rval;
    249277}
    250278
     
    264292    return INT_TO_JSVAL(val);
    265293}
    266294
    267 template<> jsval ScriptInterface::ToJSVal<u32>(JSContext* cx, const u32& val)
     295template<> jsval ScriptInterface::ToJSVal<u32>(JSContext* UNUSED(cx), const u32& val)
    268296{
    269297    if (val <= JSVAL_INT_MAX)
    270298        return INT_TO_JSVAL(val);
    271     jsval rval = JSVAL_VOID;
    272     JS_NewNumberValue(cx, val, &rval); // ignore return value
     299    jsval rval = JS_NumberValue(val);
    273300    return rval;
    274301}
    275302
     
    315342
    316343template<> jsval ScriptInterface::ToJSVal<std::wstring>(JSContext* cx, const std::wstring& val)
    317344{
     345    JSAutoRequest rq(cx);
    318346    utf16string utf16(val.begin(), val.end());
    319347    JSString* str = JS_NewUCStringCopyN(cx, reinterpret_cast<const jschar*> (utf16.c_str()), utf16.length());
    320348    if (str)
     
    329357
    330358template<> jsval ScriptInterface::ToJSVal<std::string>(JSContext* cx, const std::string& val)
    331359{
     360    JSAutoRequest rq(cx);
    332361    JSString* str = JS_NewStringCopyN(cx, val.c_str(), val.length());
    333362    if (str)
    334363        return STRING_TO_JSVAL(str);
     
    342371
    343372template<> jsval ScriptInterface::ToJSVal<const char*>(JSContext* cx, const char* const& val)
    344373{
     374    JSAutoRequest rq(cx);
    345375    JSString* str = JS_NewStringCopyZ(cx, val);
    346376    if (str)
    347377        return STRING_TO_JSVAL(str);
     
    363393
    364394template<typename T> static jsval ToJSVal_vector(JSContext* cx, const std::vector<T>& val)
    365395{
    366     JSObject* obj = JS_NewArrayObject(cx, (jsint)val.size(), NULL);
     396    JSAutoRequest rq(cx);
     397    JSObject* obj = JS_NewArrayObject(cx, val.size(), NULL);
    367398    if (!obj)
    368399        return JSVAL_VOID;
    369     for (size_t i = 0; i < val.size(); ++i)
     400    for (uint32_t i = 0; i < val.size(); ++i)
    370401    {
    371         jsval el = ScriptInterface::ToJSVal<T>(cx, val[i]);
    372         JS_SetElement(cx, obj, (jsint)i, &el);
     402        JS::RootedValue el(cx, ScriptInterface::ToJSVal<T>(cx, val[i]));
     403        JS_SetElement(cx, obj, i, el.address());
    373404    }
    374405    return OBJECT_TO_JSVAL(obj);
    375406}
    376407
    377408template<typename T> static bool FromJSVal_vector(JSContext* cx, jsval v, std::vector<T>& out)
    378409{
     410    JSAutoRequest rq(cx);
    379411    JSObject* obj;
    380     if (!JS_ValueToObject(cx, v, &obj) || obj == NULL || !(JS_IsArrayObject(cx, obj) || js_IsTypedArray(obj)))
     412    if (!JS_ValueToObject(cx, v, &obj) || obj == NULL || !(JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj)))
    381413        FAIL("Argument must be an array");
    382     jsuint length;
     414    uint32_t length;
    383415    if (!JS_GetArrayLength(cx, obj, &length))
    384416        FAIL("Failed to get array length");
    385417    out.reserve(length);
    386     for (jsuint i = 0; i < length; ++i)
     418    for (uint32_t i = 0; i < length; ++i)
    387419    {
    388         jsval el;
    389         if (!JS_GetElement(cx, obj, i, &el))
     420        JS::RootedValue el(cx);
     421        if (!JS_GetElement(cx, obj, i, el.address()))
    390422            FAIL("Failed to read array element");
    391423        T el2;
    392424        if (!ScriptInterface::FromJSVal<T>(cx, el, el2))
  • source/scripting/JSUtil.cpp

     
    1 /* Copyright (C) 2009 Wildfire Games.
    2  * This file is part of 0 A.D.
    3  *
    4  * 0 A.D. is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * 0 A.D. is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 
    18 #include "precompiled.h"
    19 
    20 #include "SpiderMonkey.h"
    21 
    22 JSBool jsu_report_param_error(JSContext* cx, jsval* vp)
    23 {
    24     JS_ReportError(cx, "Invalid parameter(s) or count");
    25 
    26     if (vp)
    27         JS_SET_RVAL(cx, vp, JSVAL_NULL);
    28 
    29     // yes, we had an error, but returning JS_FALSE would cause SpiderMonkey
    30     // to abort. that would be hard to debug.
    31     return JS_TRUE;
    32 }
  • source/scripting/SpiderMonkey.h

     
    3535
    3636#include "scriptinterface/ScriptTypes.h"
    3737
    38 #include "JSUtil.h"
    39 
    4038// Make JS debugging a little easier by automatically naming GC roots
    4139// Don't simply #define NAME_ALL_GC_ROOTS, because jsapi.h is horridly broken
    4240#ifndef NDEBUG
  • source/scripting/JSUtil.h

     
    1 /* Copyright (C) 2009 Wildfire Games.
    2  * This file is part of 0 A.D.
    3  *
    4  * 0 A.D. is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * 0 A.D. is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 
    18 // included from SpiderMonkey.h
    19 
    20 extern JSBool jsu_report_param_error(JSContext* cx, jsval* vp);
    21 
    22 
    23 // consistent argc checking for normal function wrappers: reports an
    24 // error via JS and returns if number of parameters is incorrect.
    25 // .. require exact number (most common case)
    26 #define JSU_REQUIRE_PARAMS(exact_number)\
    27     if(argc != exact_number)\
    28         return jsu_report_param_error(cx, vp);
    29 // .. require 0 params (avoids L4 warning "unused argv param")
    30 #define JSU_REQUIRE_NO_PARAMS()\
    31     if(argc != 0)\
    32         return jsu_report_param_error(cx, vp);
    33 // .. require a certain range (e.g. due to optional params)
    34 #define JSU_REQUIRE_PARAM_RANGE(min_number, max_number)\
    35     if(!(min_number <= argc && argc <= max_number))\
    36         return jsu_report_param_error(cx, vp);
    37 // .. require at most a certain count
    38 #define JSU_REQUIRE_MAX_PARAMS(max_number)\
    39     if(argc > max_number)\
    40         return jsu_report_param_error(cx, vp);
    41 // .. require at least a certain count (rarely needed)
    42 #define JSU_REQUIRE_MIN_PARAMS(min_number)\
    43     if(argc < min_number)\
    44         return jsu_report_param_error(cx, vp);
    45 
    46 // same as JSU_REQUIRE_PARAMS, but used from C++ functions that are
    47 // a bit further removed from SpiderMonkey, i.e. return a
    48 // C++ bool indicating success, and not taking an rval param.
    49 #define JSU_REQUIRE_PARAMS_CPP(exact_number)\
    50     if(argc != exact_number)\
    51     {\
    52         jsu_report_param_error(cx, 0);\
    53         return false;\
    54     }
    55 
    56 
    57 #define JSU_ASSERT(expr, msg)\
    58 STMT(\
    59     if(!(expr))\
    60     {\
    61         JS_ReportError(cx, msg);\
    62         return JS_FALSE;\
    63     }\
    64 )
  • source/lib/types.h

     
    3333
    3434#define i8 int8_t
    3535#define i16 int16_t
    36 #define i32 int32_t
     36//#define i32 int32_t
     37typedef int32_t i32;
    3738#define i64 int64_t
    3839
    3940#define u8  uint8_t
    40 #define u16 uint16_t
    41 #define u32 uint32_t
     41//#define u16 uint16_t
     42typedef uint16_t u16;
     43//#define u32 uint32_t
     44typedef uint32_t u32;
    4245#define u64 uint64_t
    4346
    4447#endif // #ifndef INCLUDED_TYPES
  • source/gui/IGUIObject.cpp

     
    420420        throw PSERROR_GUI_OperationNeedsGUIObject();
    421421       
    422422    JSContext* cx = pGUI->GetScriptInterface()->GetContext();
     423    JSAutoRequest rq(cx);
    423424   
    424425    const int paramCount = 1;
    425426    const char* paramNames[paramCount] = { "mouse" };
     
    467468        return;
    468469
    469470    JSContext* cx = m_pGUI->GetScriptInterface()->GetContext();
    470 
     471    JSAutoRequest rq(cx);
     472   
    471473    // Set up the 'mouse' parameter
    472474    CScriptVal mouse;
    473475    m_pGUI->GetScriptInterface()->Eval("({})", mouse);
     
    478480    jsval paramData[] = { mouse.get() };
    479481
    480482    jsval result;
    481     JSBool ok = JS_CallFunctionValue(cx, GetJSObject(), (*it).second.get(), ARRAY_SIZE(paramData), paramData, &result);
     483    bool ok = JS_CallFunctionValue(cx, GetJSObject(), (*it).second.get(), ARRAY_SIZE(paramData), paramData, &result);
    482484    if (!ok)
    483485    {
    484486        // We have no way to propagate the script exception, so just ignore it
     
    498500    jsval arg = Argument.get();
    499501
    500502    jsval result;
    501     JSBool ok = JS_CallFunctionValue(cx, object, (*it).second.get(), 1, &arg, &result);
     503    bool ok = JS_CallFunctionValue(cx, object, (*it).second.get(), 1, &arg, &result);
    502504    if (!ok)
    503505    {
    504506        JS_ReportError(cx, "Errors executing script action \"%s\"", Action.c_str());
     
    508510JSObject* IGUIObject::GetJSObject()
    509511{
    510512    JSContext* cx = m_pGUI->GetScriptInterface()->GetContext();
     513    JSAutoRequest rq(cx);
    511514    // Cache the object when somebody first asks for it, because otherwise
    512515    // we end up doing far too much object allocation. TODO: Would be nice to
    513516    // not have these objects hang around forever using up memory, though.
     
    515518    {
    516519        JSObject* obj = JS_NewObject(cx, &JSI_IGUIObject::JSI_class, NULL, NULL);
    517520        m_JSObject = CScriptValRooted(cx, OBJECT_TO_JSVAL(obj));
    518         JS_SetPrivate(cx, JSVAL_TO_OBJECT(m_JSObject.get()), this);
     521        JS_SetPrivate(JSVAL_TO_OBJECT(m_JSObject.get()), this);
    519522    }
    520523    return JSVAL_TO_OBJECT(m_JSObject.get());;
    521524}
  • source/gui/scripting/JSInterface_GUITypes.cpp

     
    2323/**** GUISize ****/
    2424JSClass JSI_GUISize::JSI_class = {
    2525    "GUISize", 0,
    26         JS_PropertyStub, JS_PropertyStub,
     26        JS_PropertyStub, JS_DeletePropertyStub,
    2727        JS_PropertyStub, JS_StrictPropertyStub,
    2828        JS_EnumerateStub, JS_ResolveStub,
    29         JS_ConvertStub, JS_FinalizeStub,
     29        JS_ConvertStub, NULL,
    3030        NULL, NULL, NULL, JSI_GUISize::construct
    3131};
    3232
     
    4545
    4646JSFunctionSpec JSI_GUISize::JSI_methods[] =
    4747{
    48     { "toString", JSI_GUISize::toString, 0, 0 },
    49     { 0 }
     48    JS_FS("toString", JSI_GUISize::toString, 0, 0),
     49    JS_FS_END
    5050};
    5151
    52 JSBool JSI_GUISize::construct(JSContext* cx, uintN argc, jsval* vp)
     52JSBool JSI_GUISize::construct(JSContext* cx, uint argc, jsval* vp)
    5353{
    5454    JSObject* obj = JS_NewObject(cx, &JSI_GUISize::JSI_class, NULL, NULL);
    5555
     56    // TODO: ugly with so much repetition...?
    5657    if (argc == 8)
    5758    {
    58         JS_SetProperty(cx, obj, "left",     &JS_ARGV(cx, vp)[0]);
    59         JS_SetProperty(cx, obj, "top",      &JS_ARGV(cx, vp)[1]);
    60         JS_SetProperty(cx, obj, "right",    &JS_ARGV(cx, vp)[2]);
    61         JS_SetProperty(cx, obj, "bottom",   &JS_ARGV(cx, vp)[3]);
    62         JS_SetProperty(cx, obj, "rleft",    &JS_ARGV(cx, vp)[4]);
    63         JS_SetProperty(cx, obj, "rtop",     &JS_ARGV(cx, vp)[5]);
    64         JS_SetProperty(cx, obj, "rright",   &JS_ARGV(cx, vp)[6]);
    65         JS_SetProperty(cx, obj, "rbottom",  &JS_ARGV(cx, vp)[7]);
     59        JS::RootedValue v0(cx, JS_ARGV(cx, vp)[0]);
     60        JS::RootedValue v1(cx, JS_ARGV(cx, vp)[1]);
     61        JS::RootedValue v2(cx, JS_ARGV(cx, vp)[2]);
     62        JS::RootedValue v3(cx, JS_ARGV(cx, vp)[3]);
     63        JS::RootedValue v4(cx, JS_ARGV(cx, vp)[4]);
     64        JS::RootedValue v5(cx, JS_ARGV(cx, vp)[5]);
     65        JS::RootedValue v6(cx, JS_ARGV(cx, vp)[6]);
     66        JS::RootedValue v7(cx, JS_ARGV(cx, vp)[7]);
     67        JS_SetProperty(cx, obj, "left",     v0.address());
     68        JS_SetProperty(cx, obj, "top",      v1.address());
     69        JS_SetProperty(cx, obj, "right",    v2.address());
     70        JS_SetProperty(cx, obj, "bottom",   v3.address());
     71        JS_SetProperty(cx, obj, "rleft",    v4.address());
     72        JS_SetProperty(cx, obj, "rtop",     v5.address());
     73        JS_SetProperty(cx, obj, "rright",   v6.address());
     74        JS_SetProperty(cx, obj, "rbottom",  v7.address());
    6675    }
    6776    else if (argc == 4)
    6877    {
    69         jsval zero = JSVAL_ZERO;
    70         JS_SetProperty(cx, obj, "left",     &JS_ARGV(cx, vp)[0]);
    71         JS_SetProperty(cx, obj, "top",      &JS_ARGV(cx, vp)[1]);
    72         JS_SetProperty(cx, obj, "right",    &JS_ARGV(cx, vp)[2]);
    73         JS_SetProperty(cx, obj, "bottom",   &JS_ARGV(cx, vp)[3]);
    74         JS_SetProperty(cx, obj, "rleft",    &zero);
    75         JS_SetProperty(cx, obj, "rtop",     &zero);
    76         JS_SetProperty(cx, obj, "rright",   &zero);
    77         JS_SetProperty(cx, obj, "rbottom",  &zero);
     78        JS::RootedValue zero(cx, JSVAL_ZERO);
     79        JS::RootedValue v0(cx, JS_ARGV(cx, vp)[0]);
     80        JS::RootedValue v1(cx, JS_ARGV(cx, vp)[1]);
     81        JS::RootedValue v2(cx, JS_ARGV(cx, vp)[2]);
     82        JS::RootedValue v3(cx, JS_ARGV(cx, vp)[3]);
     83        JS_SetProperty(cx, obj, "left",     v0.address());
     84        JS_SetProperty(cx, obj, "top",      v1.address());
     85        JS_SetProperty(cx, obj, "right",    v2.address());
     86        JS_SetProperty(cx, obj, "bottom",   v3.address());
     87        JS_SetProperty(cx, obj, "rleft",    zero.address());
     88        JS_SetProperty(cx, obj, "rtop",     zero.address());
     89        JS_SetProperty(cx, obj, "rright",   zero.address());
     90        JS_SetProperty(cx, obj, "rbottom",  zero.address());
    7891    }
    7992    else
    8093    {
    81         jsval zero = JSVAL_ZERO;
    82         JS_SetProperty(cx, obj, "left",     &zero);
    83         JS_SetProperty(cx, obj, "top",      &zero);
    84         JS_SetProperty(cx, obj, "right",    &zero);
    85         JS_SetProperty(cx, obj, "bottom",   &zero);
    86         JS_SetProperty(cx, obj, "rleft",    &zero);
    87         JS_SetProperty(cx, obj, "rtop",     &zero);
    88         JS_SetProperty(cx, obj, "rright",   &zero);
    89         JS_SetProperty(cx, obj, "rbottom",  &zero);
     94        JS::RootedValue zero(cx, JSVAL_ZERO);
     95        JS_SetProperty(cx, obj, "left",     zero.address());
     96        JS_SetProperty(cx, obj, "top",      zero.address());
     97        JS_SetProperty(cx, obj, "right",    zero.address());
     98        JS_SetProperty(cx, obj, "bottom",   zero.address());
     99        JS_SetProperty(cx, obj, "rleft",    zero.address());
     100        JS_SetProperty(cx, obj, "rtop",     zero.address());
     101        JS_SetProperty(cx, obj, "rright",   zero.address());
     102        JS_SetProperty(cx, obj, "rbottom",  zero.address());
    90103    }
    91104
    92105    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
     
    102115        return CStr::FromDouble(per)+"%"+( pix == 0.0 ? CStr() : pix > 0.0 ? CStr("+")+CStr::FromDouble(pix) : CStr::FromDouble(pix) );
    103116}
    104117
    105 JSBool JSI_GUISize::toString(JSContext* cx, uintN argc, jsval* vp)
     118JSBool JSI_GUISize::toString(JSContext* cx, uint argc, jsval* vp)
    106119{
    107120    UNUSED2(argc);
    108121
     
    141154
    142155JSClass JSI_GUIColor::JSI_class = {
    143156    "GUIColor", 0,
    144         JS_PropertyStub, JS_PropertyStub,
     157        JS_PropertyStub, JS_DeletePropertyStub,
    145158        JS_PropertyStub, JS_StrictPropertyStub,
    146159        JS_EnumerateStub, JS_ResolveStub,
    147         JS_ConvertStub, JS_FinalizeStub,
     160        JS_ConvertStub, NULL,
    148161        NULL, NULL, NULL, JSI_GUIColor::construct
    149162};
    150163
     
    159172
    160173JSFunctionSpec JSI_GUIColor::JSI_methods[] =
    161174{
    162     { "toString", JSI_GUIColor::toString, 0, 0 },
    163     { 0 }
     175    JS_FS("toString", JSI_GUIColor::toString, 0, 0),
     176    JS_FS_END
    164177};
    165178
    166 JSBool JSI_GUIColor::construct(JSContext* cx, uintN argc, jsval* vp)
     179JSBool JSI_GUIColor::construct(JSContext* cx, uint argc, jsval* vp)
    167180{
    168181    JSObject* obj = JS_NewObject(cx, &JSI_GUIColor::JSI_class, NULL, NULL);
    169182
     
    177190    else
    178191    {
    179192        // Nice magenta:
    180         jsval c;
    181         if (!JS_NewNumberValue(cx, 1.0, &c))
     193        JS::RootedValue c(cx, JS_NumberValue(1.0));
     194        if (JSVAL_IS_NULL(c))
    182195            return JS_FALSE;
    183         JS_SetProperty(cx, obj, "r", &c);
    184         JS_SetProperty(cx, obj, "b", &c);
    185         JS_SetProperty(cx, obj, "a", &c);
    186         if (!JS_NewNumberValue(cx, 0.0, &c))
     196        JS_SetProperty(cx, obj, "r", c.address());
     197        JS_SetProperty(cx, obj, "b", c.address());
     198        JS_SetProperty(cx, obj, "a", c.address());
     199        c = JS_NumberValue(0.0);
     200        if (JSVAL_IS_NULL(c))
    187201            return JS_FALSE;
    188         JS_SetProperty(cx, obj, "g", &c);
     202        JS_SetProperty(cx, obj, "g", c.address());
    189203    }
    190204
    191205    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    192206    return JS_TRUE;
    193207}
    194208
    195 JSBool JSI_GUIColor::toString(JSContext* cx, uintN argc, jsval* vp)
     209JSBool JSI_GUIColor::toString(JSContext* cx, uint argc, jsval* vp)
    196210{
    197211    UNUSED2(argc);
    198212
     
    218232
    219233JSClass JSI_GUIMouse::JSI_class = {
    220234    "GUIMouse", 0,
    221         JS_PropertyStub, JS_PropertyStub,
     235        JS_PropertyStub, JS_DeletePropertyStub,
    222236        JS_PropertyStub, JS_StrictPropertyStub,
    223237        JS_EnumerateStub, JS_ResolveStub,
    224         JS_ConvertStub, JS_FinalizeStub,
     238        JS_ConvertStub, NULL,
    225239        NULL, NULL, NULL, JSI_GUIMouse::construct
    226240};
    227241
     
    235249
    236250JSFunctionSpec JSI_GUIMouse::JSI_methods[] =
    237251{
    238     { "toString", JSI_GUIMouse::toString, 0, 0 },
    239     { 0 }
     252    JS_FS("toString", JSI_GUIMouse::toString, 0, 0),
     253    JS_FS_END
    240254};
    241255
    242 JSBool JSI_GUIMouse::construct(JSContext* cx, uintN argc, jsval* vp)
     256JSBool JSI_GUIMouse::construct(JSContext* cx, uint argc, jsval* vp)
    243257{
    244258    JSObject* obj = JS_NewObject(cx, &JSI_GUIMouse::JSI_class, NULL, NULL);
    245259
    246260    if (argc == 3)
    247261    {
    248         JS_SetProperty(cx, obj, "x", &JS_ARGV(cx, vp)[0]);
    249         JS_SetProperty(cx, obj, "y", &JS_ARGV(cx, vp)[1]);
    250         JS_SetProperty(cx, obj, "buttons", &JS_ARGV(cx, vp)[2]);
     262        JS::RootedValue v0(cx, JS_ARGV(cx, vp)[0]);
     263        JS::RootedValue v1(cx, JS_ARGV(cx, vp)[1]);
     264        JS::RootedValue v2(cx, JS_ARGV(cx, vp)[2]);
     265        JS_SetProperty(cx, obj, "x", v0.address());
     266        JS_SetProperty(cx, obj, "y", v1.address());
     267        JS_SetProperty(cx, obj, "buttons", v2.address());
    251268    }
    252269    else
    253270    {
    254         jsval zero = JSVAL_ZERO;
    255         JS_SetProperty(cx, obj, "x", &zero);
    256         JS_SetProperty(cx, obj, "y", &zero);
    257         JS_SetProperty(cx, obj, "buttons", &zero);
     271        JS::RootedValue zero (cx, JSVAL_ZERO);
     272        JS_SetProperty(cx, obj, "x", zero.address());
     273        JS_SetProperty(cx, obj, "y", zero.address());
     274        JS_SetProperty(cx, obj, "buttons", zero.address());
    258275    }
    259276
    260277    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    261278    return JS_TRUE;
    262279}
    263280
    264 JSBool JSI_GUIMouse::toString(JSContext* cx, uintN argc, jsval* vp)
     281JSBool JSI_GUIMouse::toString(JSContext* cx, uint argc, jsval* vp)
    265282{
    266283    UNUSED2(argc);
    267284
    268     int32 x, y, buttons;
     285    int32_t x, y, buttons;
    269286    ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface;
    270287    pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), "x", x);
    271288    pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), "y", y);
  • source/gui/scripting/JSInterface_GUITypes.h

     
    2626        extern JSClass JSI_class;               \
    2727        extern JSPropertySpec JSI_props[];      \
    2828        extern JSFunctionSpec JSI_methods[];    \
    29         JSBool construct(JSContext* cx, uintN argc, jsval* vp); \
    30         JSBool toString(JSContext* cx, uintN argc, jsval* vp);  \
     29        JSBool construct(JSContext* cx, uint argc, jsval* vp);  \
     30        JSBool toString(JSContext* cx, uint argc, jsval* vp);   \
    3131    }
    3232
    3333GUISTDTYPE(Size)
  • source/gui/scripting/ScriptFunctions.cpp

     
    6969#include "soundmanager/SoundManager.h"
    7070#include "soundmanager/scripting/JSInterface_Sound.h"
    7171
    72 #include "js/jsapi.h"
    7372/*
    7473 * This file defines a set of functions that are available to GUI scripts, to allow
    7574 * interaction with the rest of the engine.
     
    552551void ForceGC(ScriptInterface::CxPrivate* pCxPrivate)
    553552{
    554553    double time = timer_Time();
    555     JS_GC(pCxPrivate->pScriptInterface->GetContext());
     554    JS_GC(pCxPrivate->pScriptInterface->GetJSRuntime());
    556555    time = timer_Time() - time;
    557556    g_Console->InsertMessage(L"Garbage collection completed in: %f", time);
    558557}
  • source/gui/scripting/JSInterface_IGUIObject.cpp

     
    3232
    3333JSClass JSI_IGUIObject::JSI_class = {
    3434    "GUIObject", JSCLASS_HAS_PRIVATE,
    35     JS_PropertyStub, JS_PropertyStub,
     35    JS_PropertyStub, JS_DeletePropertyStub,
    3636    JSI_IGUIObject::getProperty, JSI_IGUIObject::setProperty,
    3737    JS_EnumerateStub, JS_ResolveStub,
    38     JS_ConvertStub, JS_FinalizeStub,
     38    JS_ConvertStub, NULL,
    3939    NULL, NULL, NULL, JSI_IGUIObject::construct
    4040};
    4141
    42 JSPropertySpec JSI_IGUIObject::JSI_props[] = 
     42JSPropertySpec JSI_IGUIObject::JSI_props[] =
    4343{
    4444    { 0 }
    4545};
    4646
    47 JSFunctionSpec JSI_IGUIObject::JSI_methods[] = 
     47JSFunctionSpec JSI_IGUIObject::JSI_methods[] =
    4848{
    49     { "toString", JSI_IGUIObject::toString, 0, 0 },
    50     { "focus", JSI_IGUIObject::focus, 0, 0 },
    51     { "blur", JSI_IGUIObject::blur, 0, 0 },
    52     { "getComputedSize", JSI_IGUIObject::getComputedSize, 0, 0 },
    53     { 0 }
     49    JS_FS("toString", JSI_IGUIObject::toString, 0, 0),
     50    JS_FS("focus", JSI_IGUIObject::focus, 0, 0),
     51    JS_FS("blur", JSI_IGUIObject::blur, 0, 0),
     52    JS_FS("getComputedSize", JSI_IGUIObject::getComputedSize, 0, 0),
     53    JS_FS_END
    5454};
    5555
    56 JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
     56JSBool JSI_IGUIObject::getProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<jsval> vp)
    5757{
    5858    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, obj, &JSI_IGUIObject::JSI_class, NULL);
    5959    if (!e)
     
    8888        CStr eventName (CStr(propName.substr(2)).LowerCase());
    8989        std::map<CStr, CScriptValRooted>::iterator it = e->m_ScriptHandlers.find(eventName);
    9090        if (it == e->m_ScriptHandlers.end())
    91             *vp = JSVAL_NULL;
     91            vp.set(JSVAL_NULL);
    9292        else
    93             *vp = it->second.get();
     93            vp.set((*it).second.get());
    9494        return JS_TRUE;
    9595    }
    9696
     
    102102        if (parent)
    103103        {
    104104            // If the object isn't parentless, return a new object
    105             *vp = OBJECT_TO_JSVAL(parent->GetJSObject());
     105            vp.set(OBJECT_TO_JSVAL(parent->GetJSObject()));
    106106        }
    107107        else
    108108        {
    109109            // Return null if there's no parent
    110             *vp = JSVAL_NULL;
     110            vp.set(JSVAL_NULL);
    111111        }
    112112        return JS_TRUE;
    113113    }
    114114    // Also handle "name" specially
    115115    else if (propName == "name")
    116116    {
    117         *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, e->GetName().c_str()));
     117        vp.set(STRING_TO_JSVAL(JS_NewStringCopyZ(cx, e->GetName().c_str())));
    118118        return JS_TRUE;
    119119    }
    120120    // Handle all other properties
     
    135135            {
    136136                bool value;
    137137                GUI<bool>::GetSetting(e, propName, value);
    138                 *vp = value ? JSVAL_TRUE : JSVAL_FALSE;
     138                vp.set(BOOLEAN_TO_JSVAL(value));
     139                //value ? JSVAL_TRUE : JSVAL_FALSE;
    139140                break;
    140141            }
    141142
     
    143144            {
    144145                int value;
    145146                GUI<int>::GetSetting(e, propName, value);
    146                 *vp = INT_TO_JSVAL(value);
     147                vp.set(INT_TO_JSVAL(value));
    147148                break;
    148149            }
    149150
     
    152153                float value;
    153154                GUI<float>::GetSetting(e, propName, value);
    154155                // Create a garbage-collectable double
    155                 return JS_NewNumberValue(cx, value, vp);
     156                vp.set(JS_NumberValue(value));
     157                return !JSVAL_IS_NULL(vp.get());
    156158            }
    157159
    158160        case GUIST_CColor:
     
    160162                CColor colour;
    161163                GUI<CColor>::GetSetting(e, propName, colour);
    162164                JSObject* obj = JS_NewObject(cx, &JSI_GUIColor::JSI_class, NULL, NULL);
    163                 *vp = OBJECT_TO_JSVAL(obj); // root it
     165                vp.set(OBJECT_TO_JSVAL(obj)); // root it
    164166
    165                 jsval c;
     167                JS::RootedValue c(cx);
    166168                // Attempt to minimise ugliness through macrosity
    167                 #define P(x) if (!JS_NewNumberValue(cx, colour.x, &c)) return JS_FALSE; JS_SetProperty(cx, obj, #x, &c)
     169                #define P(x) c = JS_NumberValue(colour.x); \
     170                if (JSVAL_IS_NULL(c)) return false; JS_SetProperty(cx, obj, #x, c.address())
    168171                    P(r);
    169172                    P(g);
    170173                    P(b);
     
    179182                CClientArea area;
    180183                GUI<CClientArea>::GetSetting(e, propName, area);
    181184                JSObject* obj = JS_NewObject(cx, &JSI_GUISize::JSI_class, NULL, NULL);
    182                 *vp = OBJECT_TO_JSVAL(obj); // root it
     185                vp.set(OBJECT_TO_JSVAL(obj)); // root it
    183186                try
    184187                {
    185188                    ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface;
     
    207210            {
    208211                CGUIString value;
    209212                GUI<CGUIString>::GetSetting(e, propName, value);
    210                 *vp = ScriptInterface::ToJSVal(cx, value.GetOriginalString());
     213                vp.set(ScriptInterface::ToJSVal(cx, value.GetOriginalString()));
    211214                break;
    212215            }
    213216
     
    215218            {
    216219                CStr value;
    217220                GUI<CStr>::GetSetting(e, propName, value);
    218                 *vp = ScriptInterface::ToJSVal(cx, value);
     221                vp.set(ScriptInterface::ToJSVal(cx, value));
    219222                break;
    220223            }
    221224
     
    223226            {
    224227                CStrW value;
    225228                GUI<CStrW>::GetSetting(e, propName, value);
    226                 *vp = ScriptInterface::ToJSVal(cx, value);
     229                vp.set(ScriptInterface::ToJSVal(cx, value));
    227230                break;
    228231            }
    229232
     
    231234            {
    232235                CGUISpriteInstance *value;
    233236                GUI<CGUISpriteInstance>::GetSettingPointer(e, propName, value);
    234                 *vp = ScriptInterface::ToJSVal(cx, value->GetName());
     237                vp.set(ScriptInterface::ToJSVal(cx, value->GetName()));
    235238                break;
    236239            }
    237240
     
    247250                case EAlign_Center: word = "center"; break;
    248251                default: debug_warn(L"Invalid EAlign!"); word = "error"; break;
    249252                }
    250                 *vp = ScriptInterface::ToJSVal(cx, word);
     253                vp.set(ScriptInterface::ToJSVal(cx, word));
    251254                break;
    252255            }
    253256
     
    263266                case EVAlign_Center: word = "center"; break;
    264267                default: debug_warn(L"Invalid EVAlign!"); word = "error"; break;
    265268                }
    266                 *vp = ScriptInterface::ToJSVal(cx, word);
     269                vp.set(ScriptInterface::ToJSVal(cx, word));
    267270                break;
    268271            }
    269272
     
    273276                GUI<CGUIList>::GetSetting(e, propName, value);
    274277
    275278                JSObject *obj = JS_NewArrayObject(cx, 0, NULL);
    276                 *vp = OBJECT_TO_JSVAL(obj); // root it
    277                
     279                vp.set(OBJECT_TO_JSVAL(obj)); // root it
     280
    278281                for (size_t i = 0; i < value.m_Items.size(); ++i)
    279282                {
    280                     jsval val = ScriptInterface::ToJSVal(cx, value.m_Items[i].GetOriginalString());
    281                     JS_SetElement(cx, obj, (jsint)i, &val);
     283                    JS::RootedValue val(cx, ScriptInterface::ToJSVal(cx, value.m_Items[i].GetOriginalString()));
     284                    JS_SetElement(cx, obj, (uint32_t)i, val.address());
    282285                }
    283286
    284287                break;
     
    294297    }
    295298}
    296299
    297 JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool UNUSED(strict), jsval* vp)
     300JSBool JSI_IGUIObject::setProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSBool UNUSED(strict), JS::MutableHandle<jsval> vp)
    298301{
    299302    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, obj, &JSI_IGUIObject::JSI_class, NULL);
    300303    if (!e)
     
    311314    if (propName == "name")
    312315    {
    313316        std::string value;
    314         if (!ScriptInterface::FromJSVal(cx, *vp, value))
     317        if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
    315318            return JS_FALSE;
    316319        e->SetName(value);
    317320        return JS_TRUE;
     
    320323    // Use onWhatever to set event handlers
    321324    if (propName.substr(0, 2) == "on")
    322325    {
    323         if (!JSVAL_IS_OBJECT(*vp) || !JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(*vp)))
     326        if (JSVAL_IS_PRIMITIVE(vp.get()) || !JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(vp.get())))
    324327        {
    325328            JS_ReportError(cx, "on- event-handlers must be functions");
    326329            return JS_FALSE;
    327330        }
    328331
    329332        CStr eventName (CStr(propName.substr(2)).LowerCase());
    330         e->SetScriptHandler(eventName, JSVAL_TO_OBJECT(*vp));
     333        e->SetScriptHandler(eventName, JSVAL_TO_OBJECT(vp.get()));
    331334
    332335        return JS_TRUE;
    333336    }
     
    346349    case GUIST_CStr:
    347350        {
    348351            std::string value;
    349             if (!ScriptInterface::FromJSVal(cx, *vp, value))
     352            if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
    350353                return JS_FALSE;
    351354
    352355            GUI<CStr>::SetSetting(e, propName, value);
     
    356359    case GUIST_CStrW:
    357360        {
    358361            std::wstring value;
    359             if (!ScriptInterface::FromJSVal(cx, *vp, value))
    360                 return JS_FALSE;
     362            if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
     363                return false;
    361364
    362365            GUI<CStrW>::SetSetting(e, propName, value);
    363366            break;
     
    366369    case GUIST_CGUISpriteInstance:
    367370        {
    368371            std::string value;
    369             if (!ScriptInterface::FromJSVal(cx, *vp, value))
    370                 return JS_FALSE;
     372            if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
     373                return false;
    371374
    372375            GUI<CGUISpriteInstance>::SetSetting(e, propName, CGUISpriteInstance(value));
    373376            break;
     
    376379    case GUIST_CGUIString:
    377380        {
    378381            std::wstring value;
    379             if (!ScriptInterface::FromJSVal(cx, *vp, value))
     382            if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
    380383                return JS_FALSE;
    381384
    382385            CGUIString str;
     
    388391    case GUIST_EAlign:
    389392        {
    390393            std::string value;
    391             if (!ScriptInterface::FromJSVal(cx, *vp, value))
     394            if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
    392395                return JS_FALSE;
    393396
    394397            EAlign a;
     
    407410    case GUIST_EVAlign:
    408411        {
    409412            std::string value;
    410             if (!ScriptInterface::FromJSVal(cx, *vp, value))
     413            if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
    411414                return JS_FALSE;
    412415
    413416            EVAlign a;
     
    425428
    426429    case GUIST_int:
    427430        {
    428             int32 value;
    429             if (JS_ValueToInt32(cx, *vp, &value) == JS_TRUE)
     431            int32_t value;
     432            if (JS_ValueToInt32(cx, vp.get(), &value) == true)
    430433                GUI<int>::SetSetting(e, propName, value);
    431434            else
    432435            {
     
    438441
    439442    case GUIST_float:
    440443        {
    441             jsdouble value;
    442             if (JS_ValueToNumber(cx, *vp, &value) == JS_TRUE)
     444            double value;
     445            if (JS_ValueToNumber(cx, vp.get(), &value) == true)
    443446                GUI<float>::SetSetting(e, propName, (float)value);
    444447            else
    445448            {
     
    452455    case GUIST_bool:
    453456        {
    454457            JSBool value;
    455             if (JS_ValueToBoolean(cx, *vp, &value) == JS_TRUE)
    456                 GUI<bool>::SetSetting(e, propName, value == JS_TRUE);
     458            if (JS_ValueToBoolean(cx, vp.get(), &value))
     459                GUI<bool>::SetSetting(e, propName, value);
    457460            else
    458461            {
    459462                JS_ReportError(cx, "Cannot convert value to bool");
     
    464467
    465468    case GUIST_CClientArea:
    466469        {
    467             if (JSVAL_IS_STRING(*vp))
     470            if (JSVAL_IS_STRING(vp.get()))
    468471            {
    469472                std::wstring value;
    470                 if (!ScriptInterface::FromJSVal(cx, *vp, value))
     473                if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
    471474                    return JS_FALSE;
    472475
    473476                if (e->SetSetting(propName, value) != PSRETURN_OK)
     
    476479                    return JS_FALSE;
    477480                }
    478481            }
    479             else if (JSVAL_IS_OBJECT(*vp) && JS_InstanceOf(cx, JSVAL_TO_OBJECT(*vp), &JSI_GUISize::JSI_class, NULL))
     482            else if (!JSVAL_IS_PRIMITIVE(vp.get()) && JS_InstanceOf(cx, JSVAL_TO_OBJECT(vp.get()), &JSI_GUISize::JSI_class, NULL))
    480483            {
    481484                CClientArea area;
    482485                GUI<CClientArea>::GetSetting(e, propName, area);
    483486
    484                 JSObject* obj = JSVAL_TO_OBJECT(*vp);
     487                JSObject* obj = JSVAL_TO_OBJECT(vp.get());
    485488                ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface;
    486489                #define P(x, y, z) pScriptInterface->GetProperty(OBJECT_TO_JSVAL(obj), #z, area.x.y)
    487490                    P(pixel,    left,   left);
     
    506509
    507510    case GUIST_CColor:
    508511        {
    509             if (JSVAL_IS_STRING(*vp))
     512            if (JSVAL_IS_STRING(vp.get()))
    510513            {
    511514                std::wstring value;
    512                 if (!ScriptInterface::FromJSVal(cx, *vp, value))
     515                if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
    513516                    return JS_FALSE;
    514517
    515518                if (e->SetSetting(propName, value) != PSRETURN_OK)
     
    518521                    return JS_FALSE;
    519522                }
    520523            }
    521             else if (JSVAL_IS_OBJECT(*vp) && JS_InstanceOf(cx, JSVAL_TO_OBJECT(*vp), &JSI_GUIColor::JSI_class, NULL))
     524            else if (!JSVAL_IS_PRIMITIVE(vp.get()) && JS_InstanceOf(cx, JSVAL_TO_OBJECT(vp.get()), &JSI_GUIColor::JSI_class, NULL))
    522525            {
    523526                CColor colour;
    524                 JSObject* obj = JSVAL_TO_OBJECT(*vp);
    525                 jsval t; double s;
    526                 #define PROP(x) JS_GetProperty(cx, obj, #x, &t); \
     527                JSObject* obj = JSVAL_TO_OBJECT(vp.get());
     528                JS::RootedValue t(cx);
     529                double s;
     530                #define PROP(x) JS_GetProperty(cx, obj, #x, t.address()); \
    527531                                JS_ValueToNumber(cx, t, &s); \
    528532                                colour.x = (float)s
    529533                PROP(r); PROP(g); PROP(b); PROP(a);
     
    541545
    542546    case GUIST_CGUIList:
    543547        {
    544             JSObject* obj = JSVAL_TO_OBJECT(*vp);
    545             jsuint length;
    546             if (JSVAL_IS_OBJECT(*vp) && JS_GetArrayLength(cx, obj, &length) == JS_TRUE)
     548            JSObject* obj = JSVAL_TO_OBJECT(vp.get());
     549            uint length;
     550            if (!JSVAL_IS_PRIMITIVE(vp.get()) && JS_GetArrayLength(cx, obj, &length) == true)
    547551            {
    548552                CGUIList list;
    549553
    550554                for (int i=0; i<(int)length; ++i)
    551555                {
    552                     jsval element;
    553                     if (! JS_GetElement(cx, obj, i, &element))
     556                    JS::RootedValue element(cx);
     557                    if (! JS_GetElement(cx, obj, i, element.address()))
    554558                    {
    555559                        JS_ReportError(cx, "Failed to get list element");
    556560                        return JS_FALSE;
     
    562566
    563567                    CGUIString str;
    564568                    str.SetValue(value);
    565                    
     569
    566570                    list.m_Items.push_back(str);
    567571                }
    568572
     
    587591}
    588592
    589593
    590 JSBool JSI_IGUIObject::construct(JSContext* cx, uintN argc, jsval* vp)
     594JSBool JSI_IGUIObject::construct(JSContext* cx, uint argc, jsval* vp)
    591595{
    592596    if (argc == 0)
    593597    {
     
    599603
    600604    // Store the IGUIObject in the JS object's 'private' area
    601605    IGUIObject* guiObject = (IGUIObject*)JSVAL_TO_PRIVATE(JS_ARGV(cx, vp)[0]);
    602     JS_SetPrivate(cx, obj, guiObject);
     606    JS_SetPrivate(obj, guiObject);
    603607
    604608    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    605609    return JS_TRUE;
     
    610614    scriptInterface.DefineCustomObjectType(&JSI_class, construct, 1, JSI_props, JSI_methods, NULL, NULL);
    611615}
    612616
    613 JSBool JSI_IGUIObject::toString(JSContext* cx, uintN argc, jsval* vp)
     617JSBool JSI_IGUIObject::toString(JSContext* cx, uint argc, jsval* vp)
    614618{
    615619    UNUSED2(argc);
    616620
     
    625629    return JS_TRUE;
    626630}
    627631
    628 JSBool JSI_IGUIObject::focus(JSContext* cx, uintN argc, jsval* vp)
     632JSBool JSI_IGUIObject::focus(JSContext* cx, uint argc, jsval* vp)
    629633{
    630634    UNUSED2(argc);
    631635
     
    639643    return JS_TRUE;
    640644}
    641645
    642 JSBool JSI_IGUIObject::blur(JSContext* cx, uintN argc, jsval* vp)
     646JSBool JSI_IGUIObject::blur(JSContext* cx, uint argc, jsval* vp)
    643647{
    644648    UNUSED2(argc);
    645649
     
    653657    return JS_TRUE;
    654658}
    655659
    656 JSBool JSI_IGUIObject::getComputedSize(JSContext* cx, uintN argc, jsval* vp)
     660JSBool JSI_IGUIObject::getComputedSize(JSContext* cx, uint argc, jsval* vp)
    657661{
    658662    UNUSED2(argc);
    659663    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL);
  • source/gui/scripting/GuiScriptConversions.cpp

     
    2323#include "lib/external_libraries/libsdl.h"
    2424#include "ps/Hotkey.h"
    2525
    26 #include "js/jsapi.h"
    27 
    28 #define SET(obj, name, value) STMT(jsval v_ = ToJSVal(cx, (value)); JS_SetProperty(cx, (obj), (name), &v_))
     26#define SET(obj, name, value) STMT(JS::RootedValue v_(cx, ToJSVal(cx, (value))); JS_SetProperty(cx, (obj), (name), v_.address()))
    2927    // ignore JS_SetProperty return value, because errors should be impossible
    3028    // and we can't do anything useful in the case of errors anyway
    3129
    3230template<> jsval ScriptInterface::ToJSVal<SDL_Event_>(JSContext* cx, SDL_Event_ const& val)
    3331{
     32    JSAutoRequest rq(cx);
    3433    const char* typeName;
    3534
    3635    switch (val.ev.type)
     
    7877        JSObject* keysym = JS_NewObject(cx, NULL, NULL, NULL);
    7978        if (! keysym)
    8079            return JSVAL_VOID;
    81         jsval keysymVal = OBJECT_TO_JSVAL(keysym);
    82         JS_SetProperty(cx, obj, "keysym", &keysymVal);
     80        JS::RootedValue keysymVal(cx, OBJECT_TO_JSVAL(keysym));
     81        JS_SetProperty(cx, obj, "keysym", keysymVal.address());
    8382
    8483        // SET(keysym, "scancode", (int)val.ev.key.keysym.scancode); // (not in wsdl.h)
    8584        SET(keysym, "sym", (int)val.ev.key.keysym.sym);
  • source/gui/scripting/JSInterface_IGUIObject.h

     
    2525    extern JSClass JSI_class;
    2626    extern JSPropertySpec JSI_props[];
    2727    extern JSFunctionSpec JSI_methods[];
    28     JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
    29     JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool strict, jsval* vp);
    30     JSBool construct(JSContext* cx, uintN argc, jsval* vp);
    31     JSBool toString(JSContext* cx, uintN argc, jsval* vp);
    32     JSBool focus(JSContext* cx, uintN argc, jsval* vp);
    33     JSBool blur(JSContext* cx, uintN argc, jsval* vp);
    34     JSBool getComputedSize(JSContext* cx, uintN argc, jsval* vp);
     28    JSBool getProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<jsval> vp);
     29    JSBool setProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSBool UNUSED(strict), JS::MutableHandle<jsval> vp);
     30    JSBool construct(JSContext* cx, uint argc, jsval* vp);
     31    JSBool toString(JSContext* cx, uint argc, jsval* vp);
     32    JSBool focus(JSContext* cx, uint argc, jsval* vp);
     33    JSBool blur(JSContext* cx, uint argc, jsval* vp);
     34    JSBool getComputedSize(JSContext* cx, uint argc, jsval* vp);
    3535    void init(ScriptInterface& scriptInterface);
    3636}
    3737
  • source/gui/IGUIObject.h

     
    142142    friend class GUITooltip;
    143143
    144144    // Allow getProperty to access things like GetParent()
    145     friend JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
    146     friend JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool strict, jsval* vp);
    147     friend JSBool JSI_IGUIObject::getComputedSize(JSContext* cx, uintN argc, jsval* vp);
     145    friend JSBool JSI_IGUIObject::getProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<jsval> vp);
     146    friend JSBool JSI_IGUIObject::setProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSBool UNUSED(strict), JS::MutableHandle<jsval> vp);
     147    friend JSBool JSI_IGUIObject::getComputedSize(JSContext* cx, uint argc, jsval* vp);
    148148
    149149public:
    150150    IGUIObject();
  • libraries/source/spidermonkey/build.sh

    Kann nicht anzeigen: Dateityp ist als binär angegeben.
    svn:mime-type = application/octet-stream
    Kann nicht anzeigen: Dateityp ist als binär angegeben.
    svn:mime-type = application/octet-stream
    Kann nicht anzeigen: Dateityp ist als binär angegeben.
    svn:mime-type = application/octet-stream
     
    1717echo "Building SpiderMonkey..."
    1818echo
    1919
    20 JOBS=${JOBS:="-j2"}
     20
     21JOBS=${JOBS:="-j5"}
    2122MAKE=${MAKE:="make"}
    2223
    2324MAKE_OPTS="${JOBS}"
     25NSPR_INCLUDES="`pkg-config nspr --cflags`"
     26NSPR_LIBS="`pkg-config nspr --libs`"
    2427
    25 CONF_OPTS="--disable-tests"
    26 # (We don't use --enable-threadsafe because we don't use a single runtime in
    27 # multiple threads, so it is unnecessary complexity and performance overhead)
     28CONF_OPTS="--disable-e4x --enable-threadsafe --enable-shared-js --disable-tests" # --enable-trace-logging"
    2829
    2930# If Valgrind looks like it's installed, then set up SM to support it
    3031# (else the JITs will interact poorly with it)
     
    3334  CONF_OPTS="${CONF_OPTS} --enable-valgrind"
    3435fi
    3536
    36 #CONF_OPTS="${CONF_OPTS} --enable-threadsafe --with-system-nspr"
    37 #CONF_OPTS="${CONF_OPTS} --enable-trace-jscalls"
    38 
    3937# We need to be able to override CHOST in case it is 32bit userland on 64bit kernel
    4038CONF_OPTS="${CONF_OPTS} \
    4139  ${CBUILD:+--build=${CBUILD}} \
     
    4341  ${CTARGET:+--target=${CTARGET}}"
    4442
    4543echo "SpiderMonkey build options: ${CONF_OPTS}"
     44echo ${CONF_OPTS}
    4645
    47 # Extract the tarball
    48 tar xzf js185-1.0.0.tar.gz
     46# Delete the existing directory to avoid conflicts and extract the tarball
     47rm -rf mozjs24
     48tar xjf mozjs-24.2.0.tar.bz2
    4949
    50 # Apply patches
    51 patch -p0 < openbsd-spidermonkey-650742.diff
    52 patch -p0 < openbsd-spidermonkey-634609.diff
     50# Apply patches if needed
     51#patch -p0 < name_of_thepatch.diff
    5352
    54 cd js-1.8.5/js/src
     53# rename the extracted directory to something shorter
     54mv mozjs-24.2.0 mozjs24
    5555
     56cd mozjs24/js/src
     57
    5658# We want separate debug/release versions of the library, so we have to change
    5759# the LIBRARY_NAME for each build.
    5860# (We use perl instead of sed so that it works with MozillaBuild on Windows,
    5961# which has an ancient sed.)
    60 perl -i.bak -pe 's/^(LIBRARY_NAME\s+= mozjs185)(-ps-debug|-ps-release)?/$1-ps-debug/' Makefile.in
     62perl -i.bak -pe 's/(^LIBRARY_NAME\s+=).*/$1mozjs24-ps-debug/' Makefile.in
    6163mkdir -p build-debug
    6264cd build-debug
    63 ../configure ${CONF_OPTS} --enable-debug --disable-optimize
     65../configure ${CONF_OPTS} --with-nspr-libs="$NSPR_LIBS" --with-nspr-cflags="$NSPR_INCLUDES" --enable-debug --disable-optimize --enable-js-diagnostics --enable-gczeal # --enable-root-analysis
    6466${MAKE} ${MAKE_OPTS}
    6567cd ..
    6668
    67 perl -i.bak -pe 's/^(LIBRARY_NAME\s+= mozjs185)(-ps-debug|-ps-release)?/$1-ps-release/' Makefile.in
     69perl -i.bak -pe 's/(^LIBRARY_NAME\s+=).*/$1mozjs24-ps-release/' Makefile.in
    6870mkdir -p build-release
    6971cd build-release
    70 ../configure ${CONF_OPTS} # --enable-gczeal --enable-debug-symbols
     72../configure ${CONF_OPTS} --with-nspr-libs="$NSPR_LIBS" --with-nspr-cflags="$NSPR_INCLUDES" --enable-optimize  # --enable-gczeal --enable-debug-symbols
    7173${MAKE} ${MAKE_OPTS}
    7274cd ..
    7375
    74 # Remove the library suffixes to avoid spurious SVN diffs
    75 perl -i.bak -pe 's/^(LIBRARY_NAME\s+= mozjs185)(-ps-debug|-ps-release)?/$1/' Makefile.in
    76 
    7776cd ../../..
    7877
    7978if [ "${OS}" = "Windows_NT" ]
    8079then
    81   INCLUDE_DIR=include-win32
     80  INCLUDE_DIR_DEBUG=include-win32-debug
     81  INCLUDE_DIR_RELEASE=include-win32-release
    8282  DLL_SRC_SUFFIX=-1.0.dll
    8383  DLL_DST_SUFFIX=-1.0.dll
    8484  LIB_PREFIX=
     
    8686  LIB_DST_SUFFIX=.lib
    8787elif [ "`uname -s`" = "Darwin" ]
    8888then
    89   INCLUDE_DIR=include-unix
     89  INCLUDE_DIR_DEBUG=include-unix-debug
     90  INCLUDE_DIR_RELEASE=include-unix-release
    9091  DLL_SRC_SUFFIX=.dylib
    9192  DLL_DST_SUFFIX=.1.0.dylib
    9293  LIB_PREFIX=lib
    9394  LIB_SRC_SUFFIX=.dylib
    9495  LIB_DST_SUFFIX=.dylib
    9596  # Fix libtool's use of an absolute path
    96   install_name_tool -id @executable_path/${LIB_PREFIX}mozjs185-ps-debug${DLL_DST_SUFFIX} js-1.8.5/js/src/build-debug/dist/bin/${LIB_PREFIX}mozjs185-ps-debug${DLL_SRC_SUFFIX}
    97   install_name_tool -id @executable_path/${LIB_PREFIX}mozjs185-ps-release${DLL_DST_SUFFIX} js-1.8.5/js/src/build-release/dist/bin/${LIB_PREFIX}mozjs185-ps-release${DLL_SRC_SUFFIX}
     97  install_name_tool -id @executable_path/${LIB_PREFIX}mozjs24-ps-debug${DLL_DST_SUFFIX} mozjs24/js/src/build-debug/dist/bin/${LIB_PREFIX}mozjs24-ps-debug${DLL_SRC_SUFFIX}
     98  install_name_tool -id @executable_path/${LIB_PREFIX}mozjs24-ps-release${DLL_DST_SUFFIX} mozjs24/js/src/build-release/dist/bin/${LIB_PREFIX}mozjs24-ps-release${DLL_SRC_SUFFIX}
    9899else
    99   INCLUDE_DIR=include-unix
     100  INCLUDE_DIR_DEBUG=include-unix-debug
     101  INCLUDE_DIR_RELEASE=include-unix-release
    100102  DLL_SRC_SUFFIX=.so
    101   DLL_DST_SUFFIX=.so.1.0
     103  DLL_DST_SUFFIX=.so
    102104  LIB_PREFIX=lib
    103105  LIB_SRC_SUFFIX=.so
    104106  LIB_DST_SUFFIX=.so
     
    113115
    114116# Copy files into the necessary locations for building and running the game
    115117
    116 # js-config.h is the same for both debug and release builds, so we only need to copy one
    117 mkdir -p ${INCLUDE_DIR}/js
    118 cp -L js-1.8.5/js/src/build-release/dist/include/* ${INCLUDE_DIR}/js/
     118# js-config.h is different for debug and release builds, so we need different include directories for both
     119mkdir -p ${INCLUDE_DIR_DEBUG}
     120mkdir -p ${INCLUDE_DIR_RELEASE}
     121cp -R -L mozjs24/js/src/build-release/dist/include/* ${INCLUDE_DIR_RELEASE}/
     122cp -R -L mozjs24/js/src/build-debug/dist/include/* ${INCLUDE_DIR_DEBUG}/
    119123
    120124mkdir -p lib/
    121 cp -L js-1.8.5/js/src/build-debug/dist/lib/${LIB_PREFIX}mozjs185-ps-debug${LIB_SRC_SUFFIX} lib/${LIB_PREFIX}mozjs185-ps-debug${LIB_DST_SUFFIX}
    122 cp -L js-1.8.5/js/src/build-release/dist/lib/${LIB_PREFIX}mozjs185-ps-release${LIB_SRC_SUFFIX} lib/${LIB_PREFIX}mozjs185-ps-release${LIB_DST_SUFFIX}
    123 cp -L js-1.8.5/js/src/build-debug/dist/bin/${LIB_PREFIX}mozjs185-ps-debug${DLL_SRC_SUFFIX} ../../../binaries/system/${LIB_PREFIX}mozjs185-ps-debug${DLL_DST_SUFFIX}
    124 cp -L js-1.8.5/js/src/build-release/dist/bin/${LIB_PREFIX}mozjs185-ps-release${DLL_SRC_SUFFIX} ../../../binaries/system/${LIB_PREFIX}mozjs185-ps-release${DLL_DST_SUFFIX}
     125cp -L mozjs24/js/src/build-debug/dist/lib/${LIB_PREFIX}mozjs24-ps-debug${LIB_SRC_SUFFIX} lib/${LIB_PREFIX}mozjs24-ps-debug${LIB_DST_SUFFIX}
     126cp -L mozjs24/js/src/build-release/dist/lib/${LIB_PREFIX}mozjs24-ps-release${LIB_SRC_SUFFIX} lib/${LIB_PREFIX}mozjs24-ps-release${LIB_DST_SUFFIX}
     127cp -L mozjs24/js/src/build-debug/dist/bin/${LIB_PREFIX}mozjs24-ps-debug${DLL_SRC_SUFFIX} ../../../binaries/system/${LIB_PREFIX}mozjs24-ps-debug${DLL_DST_SUFFIX}
     128cp -L mozjs24/js/src/build-release/dist/bin/${LIB_PREFIX}mozjs24-ps-release${DLL_SRC_SUFFIX} ../../../binaries/system/${LIB_PREFIX}mozjs24-ps-release${DLL_DST_SUFFIX}
    125129
    126130# Flag that it's already been built successfully so we can skip it next time
    127131touch .already-built
  • libraries/source/spidermonkey/README.txt

     
    55then run start-msvc8.bat and run ./build.sh here.
    66
    77This version of SpiderMonkey comes from
    8 http://ftp.mozilla.org/pub/mozilla.org/js/js185-1.0.0.tar.gz
    9 (see also https://developer.mozilla.org/en/SpiderMonkey/1.8.5)
     8https://ftp.mozilla.org/pub/mozilla.org/js/mozjs-24.2.0.tar.bz2
    109
    11 The game must be compiled with precisely this version, and must not use a
    12 standard system-provided version of the library, since SpiderMonkey does not
    13 guarantee API stability and may have behavioural changes that cause subtle
    14 bugs or network out-of-sync errors.
     10The game must be compiled with precisely this version since SpiderMonkey
     11does not guarantee API stability and may have behavioural changes that
     12cause subtle bugs or network out-of-sync errors.
     13A standard system-provided version of the library may only be used if it's
     14exactly the same version or if it's another minor release that does not
     15change the behaviour of the scripts executed by SpiderMonkey.
  • libraries/source/spidermonkey/openbsd-spidermonkey-650742.diff

     
    1 --- js-1.8.5/js/src/configure.in
    2 +++ js-1.8.5/js/src/configure.in
    3 @@ -3041,6 +3041,9 @@
    4  *-freebsd*|*-kfreebsd*)
    5      AC_DEFINE(AVMPLUS_UNIX)
    6      ;;
    7 +*-openbsd*)
    8 +    AC_DEFINE(AVMPLUS_UNIX)
    9 +    ;;
    10  *-gnu*)
    11      AC_DEFINE(AVMPLUS_UNIX)
    12      ;;
    13 --- js-1.8.5/js/src/configure
    14 +++ js-1.8.5/js/src/configure
    15 @@ -8093,6 +8093,12 @@
    16  EOF
    17  
    18      ;;
    19 +*-openbsd*)
    20 +    cat >> confdefs.h <<\EOF
    21 +#define AVMPLUS_UNIX 1
    22 +EOF
    23 +
    24 +    ;;
    25  *-gnu*)
    26      cat >> confdefs.h <<\EOF
    27  #define AVMPLUS_UNIX 1
  • libraries/source/spidermonkey/openbsd-spidermonkey-634609.diff

     
    1 --- js-1.8.5/js/src/jsnativestack.cpp
    2 +++ js-1.8.5/js/src/jsnativestack.cpp
    3 @@ -50,7 +50,7 @@
    4  #elif defined(XP_MACOSX) || defined(DARWIN) || defined(XP_UNIX)
    5  # include <pthread.h>
    6  
    7 -# if defined(__FreeBSD__)
    8 +# if defined(__FreeBSD__) || defined(__OpenBSD__)
    9  #  include <pthread_np.h>
    10  # endif
    11  
    12 @@ -196,7 +196,9 @@
    13  # else
    14      pthread_attr_t sattr;
    15      pthread_attr_init(&sattr);
    16 -#  if defined(PTHREAD_NP_H) || defined(_PTHREAD_NP_H_) || defined(NETBSD)
    17 +#  if defined(__OpenBSD__)
    18 +    stack_t ss;
    19 +#  elif defined(PTHREAD_NP_H) || defined(_PTHREAD_NP_H_) || defined(NETBSD)
    20      /* e.g. on FreeBSD 4.8 or newer, neundorf@kde.org */
    21      pthread_attr_get_np(thread, &sattr);
    22  #  else
    23 @@ -212,7 +214,13 @@
    24  #  ifdef DEBUG
    25      int rc =
    26  #  endif
    27 +# if defined(__OpenBSD__)
    28 +        pthread_stackseg_np(pthread_self(), &ss);
    29 +    stackBase = (void*)((size_t) ss.ss_sp - ss.ss_size);
    30 +    stackSize = ss.ss_size;
    31 +# else
    32          pthread_attr_getstack(&sattr, &stackBase, &stackSize);
    33 +# endif
    34      JS_ASSERT(!rc);
    35      JS_ASSERT(stackBase);
    36      pthread_attr_destroy(&sattr);