Ticket #1886: patch_26_v0.7.diff

File patch_26_v0.7.diff, 152.2 KB (added by Yves, 10 years ago)

Current patch with SpiderMonkey version 145669:aa9ec17cf912 (http://hg.mozilla.org/mozilla-central) and 0 A.D. version r14528 . This is still heavily WIP. There's a description how to apply it here: http://www.wildfiregames.com/forum/index.php?showtopic=17289&st=80#entry271330

  • libraries/source/spidermonkey/build.sh

     
    1414    exit
    1515fi
    1616
     17echo "Building NSPR (required for Spidermonkey THREADSAFE build)"
     18echo
     19cd mozjs24/nsprpub
     20mkdir -p build-64
     21cd build-64
     22../configure --disable-debug --enable-optimize --enable-64bit
     23make
     24cd ../../../
     25
     26
    1727echo "Building SpiderMonkey..."
    1828echo
    1929
    20 JOBS=${JOBS:="-j2"}
     30
     31JOBS=${JOBS:="-j5"}
    2132MAKE=${MAKE:="make"}
    2233
    2334MAKE_OPTS="${JOBS}"
     35#--with-nspr-cflags='\
     36NSPR_INCLUDES="-I/home/yves/Projekte/0ad_spidermonkey4/libraries/source/spidermonkey/mozjs24/nsprpub/build-64/dist/include/nspr"
     37NSPR_LIBS="/home/yves/Projekte/0ad_spidermonkey4/libraries/source/spidermonkey/mozjs24/nsprpub/build-64/dist/lib/libnspr4.a "\
     38"/home/yves/Projekte/0ad_spidermonkey4/libraries/source/spidermonkey/mozjs24/nsprpub/build-64/dist/lib/libplc4.a "\
     39"/home/yves/Projekte/0ad_spidermonkey4/libraries/source/spidermonkey/mozjs24/nsprpub/build-64/dist/lib/libplds4.a"
     40CONF_OPTS="--disable-e4x --enable-threadsafe --enable-shared-js" # --enable-trace-logging" # --disable-tests
    2441
    25 CONF_OPTS="--disable-tests"
    2642# (We don't use --enable-threadsafe because we don't use a single runtime in
    2743# multiple threads, so it is unnecessary complexity and performance overhead)
    2844
     
    4359  ${CTARGET:+--target=${CTARGET}}"
    4460
    4561echo "SpiderMonkey build options: ${CONF_OPTS}"
     62echo ${CONF_OPTS}
    4663
    4764# Extract the tarball
    48 tar xzf js185-1.0.0.tar.gz
     65#tar xzf mozjs18.0.0.tar.gz
    4966
    5067# Apply patches
    51 patch -p0 < openbsd-spidermonkey-650742.diff
    52 patch -p0 < openbsd-spidermonkey-634609.diff
     68#patch -p0 < openbsd-spidermonkey-650742.diff
     69#patch -p0 < openbsd-spidermonkey-634609.diff
    5370
    54 cd js-1.8.5/js/src
     71cd mozjs24/js/src
    5572
    5673# We want separate debug/release versions of the library, so we have to change
    5774# the LIBRARY_NAME for each build.
    5875# (We use perl instead of sed so that it works with MozillaBuild on Windows,
    5976# which has an ancient sed.)
    60 perl -i.bak -pe 's/^(LIBRARY_NAME\s+= mozjs185)(-ps-debug|-ps-release)?/$1-ps-debug/' Makefile.in
     77perl -i.bak -pe 's/(LIBRARY_NAME\s+=).*/$1 '\''mozjs24-ps-debug'\''/' moz.build
    6178mkdir -p build-debug
    6279cd build-debug
    63 ../configure ${CONF_OPTS} --enable-debug --disable-optimize
     80##../configure --disable-tests --disable-e4x --enable-threadsafe --with-nspr-cflags="-I./mozjs24/nsprpub/build-64/dist/include/nspr" --with-nspr-libs="./mozjs24/nsprpub/build-64/dist/lib/libnspr4.a ./mozjs24/nsprpub/build-64/dist/lib/libplc4.a ./mozjs24/nsprpub/build-64/dist/lib/libplds4.a" --enable-valgrind
     81../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
    6482${MAKE} ${MAKE_OPTS}
    6583cd ..
    6684
    67 perl -i.bak -pe 's/^(LIBRARY_NAME\s+= mozjs185)(-ps-debug|-ps-release)?/$1-ps-release/' Makefile.in
     85perl -i.bak -pe 's/(LIBRARY_NAME\s+=).*/$1 '\''mozjs24-ps-release'\''/' moz.build
    6886mkdir -p build-release
    6987cd build-release
    70 ../configure ${CONF_OPTS} # --enable-gczeal --enable-debug-symbols
     88../configure ${CONF_OPTS} --with-nspr-libs="$NSPR_LIBS" --with-nspr-cflags="$NSPR_INCLUDES" --enable-optimize  # --enable-gczeal --enable-debug-symbols
    7189${MAKE} ${MAKE_OPTS}
    7290cd ..
    7391
    7492# 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
     93#perl -i.bak -pe 's/^(LIBRARY_NAME\s+= mozjs24)(-ps-debug|-ps-release)?/$1/' Makefile.in
    7694
    7795cd ../../..
    7896
     
    93111  LIB_SRC_SUFFIX=.dylib
    94112  LIB_DST_SUFFIX=.dylib
    95113  # 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}
     114  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}
     115  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}
    98116else
    99117  INCLUDE_DIR=include-unix
    100118  DLL_SRC_SUFFIX=.so
    101   DLL_DST_SUFFIX=.so.1.0
     119  DLL_DST_SUFFIX=.so
    102120  LIB_PREFIX=lib
    103121  LIB_SRC_SUFFIX=.so
    104122  LIB_DST_SUFFIX=.so
     
    114132# Copy files into the necessary locations for building and running the game
    115133
    116134# 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/
     135mkdir -p ${INCLUDE_DIR}
     136cp -R -L mozjs24/js/src/build-debug/dist/include/* ${INCLUDE_DIR}/
    119137
    120138mkdir -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}
     139cp -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}
     140cp -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}
     141cp -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}
     142cp -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}
    125143
    126144# Flag that it's already been built successfully so we can skip it next time
    127145touch .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)
     8http://people.mozilla.org/~sstangl/mozjs17.0.0.rc1.tar.gz
    109
    1110The game must be compiled with precisely this version, and must not use a
    1211standard system-provided version of the library, since SpiderMonkey does not
  • build/premake/extern_libs4.lua

     
    577577                end
    578578                configuration "Debug"
    579579                    includedirs { libraries_source_dir.."spidermonkey/"..include_dir }
     580                    defines { "DEBUG" }
    580581                configuration "Release"
    581582                    includedirs { libraries_source_dir.."spidermonkey/"..include_dir }
    582583                configuration { }
     
    591592                end
    592593            else
    593594                configuration "Debug"
    594                     links { "mozjs185-ps-debug" }
     595                    links { "mozjs24-ps-debug" }
    595596                configuration "Release"
    596                     links { "mozjs185-ps-release" }
     597                    links { "mozjs24-ps-release" }
    597598                configuration { }
    598599                add_source_lib_paths("spidermonkey")
    599600            end
  • 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/Replay.cpp

     
    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/ps/scripting/JSInterface_VFS.cpp

     
    6868{
    6969    BuildDirEntListState* s = (BuildDirEntListState*)cbData;
    7070
    71     jsval val = ScriptInterface::ToJSVal(s->cx, CStrW(pathname.string()));
     71    JS::RootedValue val(s->cx, ScriptInterface::ToJSVal( s->cx, CStrW(pathname.string()) ));
    7272    JS_SetElement(s->cx, s->filename_array, s->cur_idx++, &val);
    7373    return INFO::OK;
    7474}
     
    191191    while (std::getline(ss, line))
    192192    {
    193193        // Decode each line as UTF-8
    194         jsval val = ScriptInterface::ToJSVal(cx, CStr(line).FromUTF8());
     194        JS::RootedValue val(cx, ScriptInterface::ToJSVal(cx, CStr(line).FromUTF8()));
    195195        JS_SetElement(cx, line_array, cur_line++, &val);
    196196    }
    197197
  • 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/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        bool construct(JSContext* cx, uint argc, jsval* vp);    \
     30        bool 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"
     72#include "jsapi.h"
    7373/*
    7474 * This file defines a set of functions that are available to GUI scripts, to allow
    7575 * interaction with the rest of the engine.
     
    552552void ForceGC(ScriptInterface::CxPrivate* pCxPrivate)
    553553{
    554554    double time = timer_Time();
    555     JS_GC(pCxPrivate->pScriptInterface->GetContext());
     555    JS_GC(pCxPrivate->pScriptInterface->GetJSRuntime());
    556556    time = timer_Time() - time;
    557557    g_Console->InsertMessage(L"Garbage collection completed in: %f", time);
    558558}
  • 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 },
     49    { "toString", JSOP_WRAPPER(JSI_IGUIObject::toString), 0, 0 },
     50    { "focus", JSOP_WRAPPER(JSI_IGUIObject::focus), 0, 0 },
     51    { "blur", JSOP_WRAPPER(JSI_IGUIObject::blur), 0, 0 },
     52    { "getComputedSize", JSOP_WRAPPER(JSI_IGUIObject::getComputedSize), 0, 0 },
    5353    { 0 }
    5454};
    5555
    56 JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
     56bool 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)
    60         return JS_FALSE;
     60        return false;
    6161
    6262    jsval idval;
    6363    if (!JS_IdToValue(cx, id, &idval))
    64         return JS_FALSE;
     64        return false;
    6565
    6666    std::string propName;
    6767    if (!ScriptInterface::FromJSVal(cx, idval, propName))
    68         return JS_FALSE;
     68        return false;
    6969
    7070    // Skip some things which are known to be functions rather than properties.
    7171    // ("constructor" *must* be here, else it'll try to GetSettingType before
     
    8080        propName == "blur"        ||
    8181        propName == "getComputedSize"
    8282       )
    83         return JS_TRUE;
     83        return true;
    8484
    8585    // Use onWhatever to access event handlers
    8686    if (propName.substr(0, 2) == "on")
     
    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();
    94         return JS_TRUE;
     93            vp.set((*it).second.get());
     94        return true;
    9595    }
    9696
    9797
     
    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        }
    112         return JS_TRUE;
     112        return 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()));
    118         return JS_TRUE;
     117        vp.set(STRING_TO_JSVAL(JS_NewStringCopyZ(cx, e->GetName().c_str())));
     118        return true;
    119119    }
    120120    // Handle all other properties
    121121    else
     
    125125        if (e->GetSettingType(propName, Type) != PSRETURN_OK)
    126126        {
    127127            JS_ReportError(cx, "Invalid GUIObject property '%s'", propName.c_str());
    128             return JS_FALSE;
     128            return false;
    129129        }
    130130
    131131        // (All the cases are in {...} to avoid scoping problems)
     
    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)
    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);
    282285                }
    283286
    284287                break;
     
    287290        default:
    288291            JS_ReportError(cx, "Setting '%s' uses an unimplemented type", propName.c_str());
    289292            DEBUG_WARN_ERR(ERR::LOGIC);
    290             return JS_FALSE;
     293            return false;
    291294        }
    292295
    293         return JS_TRUE;
     296        return true;
    294297    }
    295298}
    296299
    297 JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool UNUSED(strict), jsval* vp)
     300bool JSI_IGUIObject::setProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool UNUSED(strict), JS::MutableHandle<jsval> vp)
    298301{
    299302    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, obj, &JSI_IGUIObject::JSI_class, NULL);
    300303    if (!e)
    301         return JS_FALSE;
     304        return false;
    302305
    303306    jsval idval;
    304307    if (!JS_IdToValue(cx, id, &idval))
    305         return JS_FALSE;
     308        return false;
    306309
    307310    std::string propName;
    308311    if (!ScriptInterface::FromJSVal(cx, idval, propName))
    309         return JS_FALSE;
     312        return false;
    310313
    311314    if (propName == "name")
    312315    {
    313316        std::string value;
    314         if (!ScriptInterface::FromJSVal(cx, *vp, value))
    315             return JS_FALSE;
     317        if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
     318            return false;
    316319        e->SetName(value);
    317         return JS_TRUE;
     320        return true;
    318321    }
    319322
    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");
    326             return JS_FALSE;
     329            return 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
    332         return JS_TRUE;
     335        return true;
    333336    }
    334337
    335338    // Retrieve the setting's type (and make sure it actually exists)
     
    337340    if (e->GetSettingType(propName, Type) != PSRETURN_OK)
    338341    {
    339342        JS_ReportError(cx, "Invalid setting '%s'", propName.c_str());
    340         return JS_TRUE;
     343        return true;
    341344    }
    342345
    343346    switch (Type)
     
    346349    case GUIST_CStr:
    347350        {
    348351            std::string value;
    349             if (!ScriptInterface::FromJSVal(cx, *vp, value))
    350                 return JS_FALSE;
     352            if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
     353                return false;
    351354
    352355            GUI<CStr>::SetSetting(e, propName, value);
    353356            break;
     
    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))
    380                 return JS_FALSE;
     382            if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
     383                return false;
    381384
    382385            CGUIString str;
    383386            str.SetValue(value);
     
    388391    case GUIST_EAlign:
    389392        {
    390393            std::string value;
    391             if (!ScriptInterface::FromJSVal(cx, *vp, value))
    392                 return JS_FALSE;
     394            if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
     395                return false;
    393396
    394397            EAlign a;
    395398            if (value == "left") a = EAlign_Left;
     
    398401            else
    399402            {
    400403                JS_ReportError(cx, "Invalid alignment (should be 'left', 'right' or 'center')");
    401                 return JS_FALSE;
     404                return false;
    402405            }
    403406            GUI<EAlign>::SetSetting(e, propName, a);
    404407            break;
     
    407410    case GUIST_EVAlign:
    408411        {
    409412            std::string value;
    410             if (!ScriptInterface::FromJSVal(cx, *vp, value))
    411                 return JS_FALSE;
     413            if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
     414                return false;
    412415
    413416            EVAlign a;
    414417            if (value == "top") a = EVAlign_Top;
     
    417420            else
    418421            {
    419422                JS_ReportError(cx, "Invalid alignment (should be 'top', 'bottom' or 'center')");
    420                 return JS_FALSE;
     423                return false;
    421424            }
    422425            GUI<EVAlign>::SetSetting(e, propName, a);
    423426            break;
     
    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            {
    433436                JS_ReportError(cx, "Cannot convert value to int");
    434                 return JS_FALSE;
     437                return false;
    435438            }
    436439            break;
    437440        }
    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            {
    446449                JS_ReportError(cx, "Cannot convert value to float");
    447                 return JS_FALSE;
     450                return false;
    448451            }
    449452            break;
    450453        }
    451454
    452455    case GUIST_bool:
    453456        {
    454             JSBool value;
    455             if (JS_ValueToBoolean(cx, *vp, &value) == JS_TRUE)
    456                 GUI<bool>::SetSetting(e, propName, value == JS_TRUE);
     457            bool value;
     458            if (JS_ValueToBoolean(cx, vp.get(), &value) == true)
     459                GUI<bool>::SetSetting(e, propName, value == true);
    457460            else
    458461            {
    459462                JS_ReportError(cx, "Cannot convert value to bool");
    460                 return JS_FALSE;
     463                return false;
    461464            }
    462465            break;
    463466        }
    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))
    471                     return JS_FALSE;
     473                if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
     474                    return false;
    472475
    473476                if (e->SetSetting(propName, value) != PSRETURN_OK)
    474477                {
    475478                    JS_ReportError(cx, "Invalid value for setting '%s'", propName.c_str());
    476                     return JS_FALSE;
     479                    return 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);
     
    499502            else
    500503            {
    501504                JS_ReportError(cx, "Size only accepts strings or GUISize objects");
    502                 return JS_FALSE;
     505                return false;
    503506            }
    504507            break;
    505508        }
    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))
    513                     return JS_FALSE;
     515                if (!ScriptInterface::FromJSVal(cx, vp.get(), value))
     516                    return false;
    514517
    515518                if (e->SetSetting(propName, value) != PSRETURN_OK)
    516519                {
    517520                    JS_ReportError(cx, "Invalid value for setting '%s'", propName.c_str());
    518                     return JS_FALSE;
     521                    return 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;
     527                JSObject* obj = JSVAL_TO_OBJECT(vp.get());
     528                JS::RootedValue t(cx);
     529                double s;
    526530                #define PROP(x) JS_GetProperty(cx, obj, #x, &t); \
    527531                                JS_ValueToNumber(cx, t, &s); \
    528532                                colour.x = (float)s
     
    534538            else
    535539            {
    536540                JS_ReportError(cx, "Color only accepts strings or GUIColor objects");
    537                 return JS_FALSE;
     541                return false;
    538542            }
    539543            break;
    540544        }
    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;
     556                    JS::RootedValue element(cx);
    553557                    if (! JS_GetElement(cx, obj, i, &element))
    554558                    {
    555559                        JS_ReportError(cx, "Failed to get list element");
    556                         return JS_FALSE;
     560                        return false;
    557561                    }
    558562
    559563                    std::wstring value;
    560564                    if (!ScriptInterface::FromJSVal(cx, element, value))
    561                         return JS_FALSE;
     565                        return false;
    562566
    563567                    CGUIString str;
    564568                    str.SetValue(value);
    565                    
     569
    566570                    list.m_Items.push_back(str);
    567571                }
    568572
     
    571575            else
    572576            {
    573577                JS_ReportError(cx, "List only accepts a GUIList object");
    574                 return JS_FALSE;
     578                return false;
    575579            }
    576580            break;
    577581        }
     
    587591}
    588592
    589593
    590 JSBool JSI_IGUIObject::construct(JSContext* cx, uintN argc, jsval* vp)
     594bool JSI_IGUIObject::construct(JSContext* cx, uint argc, jsval* vp)
    591595{
    592596    if (argc == 0)
    593597    {
    594598        JS_ReportError(cx, "GUIObject has no default constructor");
    595         return JS_FALSE;
     599        return false;
    596600    }
    597601
    598602    JSObject* obj = JS_NewObject(cx, &JSI_IGUIObject::JSI_class, NULL, NULL);
    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));
    605     return JS_TRUE;
     609    return true;
    606610}
    607611
    608612void JSI_IGUIObject::init(ScriptInterface& scriptInterface)
     
    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)
     617bool JSI_IGUIObject::toString(JSContext* cx, uint argc, jsval* vp)
    614618{
    615619    UNUSED2(argc);
    616620
    617621    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL);
    618622    if (!e)
    619         return JS_FALSE;
     623        return false;
    620624
    621625    char buffer[256];
    622626    snprintf(buffer, 256, "[GUIObject: %s]", e->GetName().c_str());
    623627    buffer[255] = 0;
    624628    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer)));
    625     return JS_TRUE;
     629    return true;
    626630}
    627631
    628 JSBool JSI_IGUIObject::focus(JSContext* cx, uintN argc, jsval* vp)
     632bool JSI_IGUIObject::focus(JSContext* cx, uint argc, jsval* vp)
    629633{
    630634    UNUSED2(argc);
    631635
    632636    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL);
    633637    if (!e)
    634         return JS_FALSE;
     638        return false;
    635639
    636640    e->GetGUI()->SetFocusedObject(e);
    637641
    638642    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    639     return JS_TRUE;
     643    return true;
    640644}
    641645
    642 JSBool JSI_IGUIObject::blur(JSContext* cx, uintN argc, jsval* vp)
     646bool JSI_IGUIObject::blur(JSContext* cx, uint argc, jsval* vp)
    643647{
    644648    UNUSED2(argc);
    645649
    646650    IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL);
    647651    if (!e)
    648         return JS_FALSE;
     652        return false;
    649653
    650654    e->GetGUI()->SetFocusedObject(NULL);
    651655
    652656    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    653     return JS_TRUE;
     657    return true;
    654658}
    655659
    656 JSBool JSI_IGUIObject::getComputedSize(JSContext* cx, uintN argc, jsval* vp)
     660bool 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);
    660664    if (!e)
    661         return JS_FALSE;
     665        return false;
    662666
    663667    e->UpdateCachedSize();
    664668    CRect size = e->m_CachedActualSize;
     
    675679    catch (PSERROR_Scripting_ConversionFailed&)
    676680    {
    677681        debug_warn(L"Error creating size object!");
    678         return JS_FALSE;
     682        return false;
    679683    }
    680684
    681685    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    682     return JS_TRUE;
     686    return true;
    683687}
  • source/gui/scripting/GuiScriptConversions.cpp

     
    2323#include "lib/external_libraries/libsdl.h"
    2424#include "ps/Hotkey.h"
    2525
    26 #include "js/jsapi.h"
     26#include "jsapi.h"
    2727
    28 #define SET(obj, name, value) STMT(jsval v_ = ToJSVal(cx, (value)); JS_SetProperty(cx, (obj), (name), &v_))
     28#define SET(obj, name, value) STMT(JS::RootedValue v_(cx, ToJSVal(cx, (value))); JS_SetProperty(cx, (obj), (name), v_))
    2929    // ignore JS_SetProperty return value, because errors should be impossible
    3030    // and we can't do anything useful in the case of errors anyway
    3131
    3232template<> jsval ScriptInterface::ToJSVal<SDL_Event_>(JSContext* cx, SDL_Event_ const& val)
    3333{
     34    JSAutoRequest rq(cx);
    3435    const char* typeName;
    3536
    3637    switch (val.ev.type)
     
    7879        JSObject* keysym = JS_NewObject(cx, NULL, NULL, NULL);
    7980        if (! keysym)
    8081            return JSVAL_VOID;
    81         jsval keysymVal = OBJECT_TO_JSVAL(keysym);
    82         JS_SetProperty(cx, obj, "keysym", &keysymVal);
     82        JS::RootedValue keysymVal(cx, OBJECT_TO_JSVAL(keysym));
     83        JS_SetProperty(cx, obj, "keysym", keysymVal);
    8384
    8485        // SET(keysym, "scancode", (int)val.ev.key.keysym.scancode); // (not in wsdl.h)
    8586        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    bool getProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<jsval> vp);
     29    bool setProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool UNUSED(strict), JS::MutableHandle<jsval> vp);
     30    bool construct(JSContext* cx, uint argc, jsval* vp);
     31    bool toString(JSContext* cx, uint argc, jsval* vp);
     32    bool focus(JSContext* cx, uint argc, jsval* vp);
     33    bool blur(JSContext* cx, uint argc, jsval* vp);
     34    bool getComputedSize(JSContext* cx, uint argc, jsval* vp);
    3535    void init(ScriptInterface& scriptInterface);
    3636}
    3737
  • 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 },
     48    { "toString", JSOP_WRAPPER(JSI_GUISize::toString), 0, 0 },
    4949    { 0 }
    5050};
    5151
    52 JSBool JSI_GUISize::construct(JSContext* cx, uintN argc, jsval* vp)
     52bool 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);
     68        JS_SetProperty(cx, obj, "top",      v1);
     69        JS_SetProperty(cx, obj, "right",    v2);
     70        JS_SetProperty(cx, obj, "bottom",   v3);
     71        JS_SetProperty(cx, obj, "rleft",    v4);
     72        JS_SetProperty(cx, obj, "rtop",     v5);
     73        JS_SetProperty(cx, obj, "rright",   v6);
     74        JS_SetProperty(cx, obj, "rbottom",  v7);
    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);
     84        JS_SetProperty(cx, obj, "top",      v1);
     85        JS_SetProperty(cx, obj, "right",    v2);
     86        JS_SetProperty(cx, obj, "bottom",   v3);
     87        JS_SetProperty(cx, obj, "rleft",    zero);
     88        JS_SetProperty(cx, obj, "rtop",     zero);
     89        JS_SetProperty(cx, obj, "rright",   zero);
     90        JS_SetProperty(cx, obj, "rbottom",  zero);
    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);
     96        JS_SetProperty(cx, obj, "top",      zero);
     97        JS_SetProperty(cx, obj, "right",    zero);
     98        JS_SetProperty(cx, obj, "bottom",   zero);
     99        JS_SetProperty(cx, obj, "rleft",    zero);
     100        JS_SetProperty(cx, obj, "rtop",     zero);
     101        JS_SetProperty(cx, obj, "rright",   zero);
     102        JS_SetProperty(cx, obj, "rbottom",  zero);
    90103    }
    91104
    92105    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    93     return JS_TRUE;
     106    return true;
    94107}
    95108
    96109// Produces "10", "-10", "50%", "50%-10", "50%+10", etc
     
    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)
     118bool JSI_GUISize::toString(JSContext* cx, uint argc, jsval* vp)
    106119{
    107120    UNUSED2(argc);
    108121
     
    128141    catch (PSERROR_Scripting_ConversionFailed&)
    129142    {
    130143        JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "<Error converting value to numbers>")));
    131         return JS_TRUE;
     144        return true;
    132145    }
    133146
    134147    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer.c_str())));
    135     return JS_TRUE;
     148    return true;
    136149}
    137150
    138151
     
    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
     
    163176    { 0 }
    164177};
    165178
    166 JSBool JSI_GUIColor::construct(JSContext* cx, uintN argc, jsval* vp)
     179bool JSI_GUIColor::construct(JSContext* cx, uint argc, jsval* vp)
    167180{
    168181    JSObject* obj = JS_NewObject(cx, &JSI_GUIColor::JSI_class, NULL, NULL);
    169182
    170183    if (argc == 4)
    171184    {
    172         JS_SetProperty(cx, obj, "r", &JS_ARGV(cx, vp)[0]);
    173         JS_SetProperty(cx, obj, "g", &JS_ARGV(cx, vp)[1]);
    174         JS_SetProperty(cx, obj, "b", &JS_ARGV(cx, vp)[2]);
    175         JS_SetProperty(cx, obj, "a", &JS_ARGV(cx, vp)[3]);
     185        JS_SetProperty(cx, obj, "r", JS::RootedValue(cx, JS_ARGV(cx, vp)[0]));
     186        JS_SetProperty(cx, obj, "g", JS::RootedValue(cx, JS_ARGV(cx, vp)[1]));
     187        JS_SetProperty(cx, obj, "b", JS::RootedValue(cx, JS_ARGV(cx, vp)[2]));
     188        JS_SetProperty(cx, obj, "a", JS::RootedValue(cx, JS_ARGV(cx, vp)[3]));
    176189    }
    177190    else
    178191    {
    179192        // Nice magenta:
    180         jsval c;
    181         if (!JS_NewNumberValue(cx, 1.0, &c))
    182             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))
    187             return JS_FALSE;
    188         JS_SetProperty(cx, obj, "g", &c);
     193        JS::RootedValue c(cx, JS_NumberValue(1.0));
     194        if (JSVAL_IS_NULL(c))
     195            return false;
     196        JS_SetProperty(cx, obj, "r", c);
     197        JS_SetProperty(cx, obj, "b", c);
     198        JS_SetProperty(cx, obj, "a", c);
     199        c = JS_NumberValue(0.0);
     200        if (JSVAL_IS_NULL(c))
     201            return false;
     202        JS_SetProperty(cx, obj, "g", c);
    189203    }
    190204
    191205    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    192     return JS_TRUE;
     206    return true;
    193207}
    194208
    195 JSBool JSI_GUIColor::toString(JSContext* cx, uintN argc, jsval* vp)
     209bool JSI_GUIColor::toString(JSContext* cx, uint argc, jsval* vp)
    196210{
    197211    UNUSED2(argc);
    198212
     
    210224        (int)(255.0 * b),
    211225        (int)(255.0 * a));
    212226    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer)));
    213     return JS_TRUE;
     227    return true;
    214228}
    215229
    216230/**** GUIMouse ****/
     
    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
     
    239253    { 0 }
    240254};
    241255
    242 JSBool JSI_GUIMouse::construct(JSContext* cx, uintN argc, jsval* vp)
     256bool 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);
     266        JS_SetProperty(cx, obj, "y", v1);
     267        JS_SetProperty(cx, obj, "buttons", v2);
    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);
     273        JS_SetProperty(cx, obj, "y", zero);
     274        JS_SetProperty(cx, obj, "buttons", zero);
    258275    }
    259276
    260277    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
    261     return JS_TRUE;
     278    return true;
    262279}
    263280
    264 JSBool JSI_GUIMouse::toString(JSContext* cx, uintN argc, jsval* vp)
     281bool 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);
     
    274291    char buffer[256];
    275292    snprintf(buffer, 256, "%d %d %d", x, y, buttons);
    276293    JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buffer)));
    277     return JS_TRUE;
     294    return true;
    278295}
    279296
    280297
  • 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/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 bool JSI_IGUIObject::getProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<jsval> vp);
     146    friend bool JSI_IGUIObject::setProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool UNUSED(strict), JS::MutableHandle<jsval> vp);
     147    friend bool JSI_IGUIObject::getComputedSize(JSContext* cx, uint argc, jsval* vp);
    148148
    149149public:
    150150    IGUIObject();
  • 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/system/InterfaceScripted.h

     
    1919#define INCLUDED_INTERFACE_SCRIPTED
    2020
    2121#include "scriptinterface/ScriptInterface.h"
    22 #include "js/jsapi.h"
     22#include "jsapi.h"
    2323
    2424#define BEGIN_INTERFACE_WRAPPER(iname) \
    2525    JSClass class_ICmp##iname = { \
    2626        "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 \
     27        JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, \
     28        JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub \
    3029    }; \
    3130    static JSFunctionSpec methods_ICmp##iname[] = {
    3231
     
    3534    }; \
    3635    void ICmp##iname::InterfaceInit(ScriptInterface& scriptInterface) { \
    3736        JSContext* cx = scriptInterface.GetContext(); \
    38         JSObject* global = JS_GetGlobalObject(cx); \
     37        JSAutoRequest rq(cx); \
     38        JSObject* global = JS::CurrentGlobalOrNull(cx); \
    3939        JS_InitClass(cx, global, NULL, &class_ICmp##iname, NULL, 0, NULL, methods_ICmp##iname, NULL, NULL); \
    4040    } \
    4141    JSClass* ICmp##iname::GetJSClass() const { return &class_ICmp##iname; } \
     
    4545
    4646#define DEFINE_INTERFACE_METHOD_0(scriptname, rettype, classname, methodname) \
    4747    { scriptname, \
    48         ScriptInterface::callMethod<rettype, &class_##classname, classname, &classname::methodname>, \
     48        { ScriptInterface::callMethod<rettype, &class_##classname, classname, &classname::methodname>, NULL }, \
    4949        0, \
    5050        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    5151
    5252#define DEFINE_INTERFACE_METHOD_1(scriptname, rettype, classname, methodname, arg1) \
    5353    { scriptname, \
    54         ScriptInterface::callMethod<rettype, arg1, &class_##classname, classname, &classname::methodname>, \
     54        { ScriptInterface::callMethod<rettype, arg1, &class_##classname, classname, &classname::methodname>, NULL}, \
    5555        1, \
    5656        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    5757
    5858#define DEFINE_INTERFACE_METHOD_2(scriptname, rettype, classname, methodname, arg1, arg2) \
    5959    { scriptname, \
    60         ScriptInterface::callMethod<rettype, arg1, arg2, &class_##classname, classname, &classname::methodname>, \
     60        { ScriptInterface::callMethod<rettype, arg1, arg2, &class_##classname, classname, &classname::methodname>, NULL }, \
    6161        2, \
    6262        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    6363
    6464#define DEFINE_INTERFACE_METHOD_3(scriptname, rettype, classname, methodname, arg1, arg2, arg3) \
    6565    { scriptname, \
    66         ScriptInterface::callMethod<rettype, arg1, arg2, arg3, &class_##classname, classname, &classname::methodname>, \
     66        { ScriptInterface::callMethod<rettype, arg1, arg2, arg3, &class_##classname, classname, &classname::methodname>, NULL }, \
    6767        3, \
    6868        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    6969
    7070#define DEFINE_INTERFACE_METHOD_4(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4) \
    7171    { scriptname, \
    72         ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, &class_##classname, classname, &classname::methodname>, \
     72        { ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, &class_##classname, classname, &classname::methodname>, NULL }, \
    7373        4, \
    7474        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    7575
    7676#define DEFINE_INTERFACE_METHOD_5(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5) \
    7777    { scriptname, \
    78         ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, &class_##classname, classname, &classname::methodname>, \
     78        { ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, &class_##classname, classname, &classname::methodname>, NULL }, \
    7979        5, \
    8080        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    8181
    8282#define DEFINE_INTERFACE_METHOD_6(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5, arg6) \
    8383    { scriptname, \
    84         ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, arg6, &class_##classname, classname, &classname::methodname>, \
     84        { ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, arg6, &class_##classname, classname, &classname::methodname>, NULL }, \
    8585        6, \
    8686        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    8787
    8888#define DEFINE_INTERFACE_METHOD_7(scriptname, rettype, classname, methodname, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
    8989    { scriptname, \
    90         ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, arg6, arg7, &class_##classname, classname, &classname::methodname>, \
     90        { ScriptInterface::callMethod<rettype, arg1, arg2, arg3, arg4, arg5, arg6, arg7, &class_##classname, classname, &classname::methodname>, NULL }, \
    9191        7, \
    9292        JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT },
    9393
  • source/simulation2/system/ParamNode.cpp

     
    2525#include "ps/Filesystem.h"
    2626#include "ps/XML/Xeromyces.h"
    2727
    28 #include "js/jsapi.h"
     28#include "jsapi.h"
    2929
    3030#include <sstream>
    3131
     
    328328
    329329jsval CParamNode::ConstructJSVal(JSContext* cx) const
    330330{
     331    JSAutoRequest rq(cx);
    331332    if (m_Childs.empty())
    332333    {
    333334        // Empty node - map to undefined
     
    351352
    352353    for (std::map<std::string, CParamNode>::const_iterator it = m_Childs.begin(); it != m_Childs.end(); ++it)
    353354    {
    354         jsval childVal = it->second.ConstructJSVal(cx);
    355         if (!JS_SetProperty(cx, obj, it->first.c_str(), &childVal))
     355        JS::RootedValue childVal(cx, it->second.ConstructJSVal(cx));
     356        if (!JS_SetProperty(cx, obj, it->first.c_str(), childVal))
    356357            return JSVAL_VOID; // TODO: report error
    357358    }
    358359
     
    363364        JSString* str = JS_InternUCStringN(cx, reinterpret_cast<const jschar*>(text.data()), text.length());
    364365        if (!str)
    365366            return JSVAL_VOID; // TODO: report error
    366         jsval childVal = STRING_TO_JSVAL(str);
    367         if (!JS_SetProperty(cx, obj, "_string", &childVal))
     367        JS::RootedValue childVal(cx, STRING_TO_JSVAL(str));
     368        if (!JS_SetProperty(cx, obj, "_string", childVal))
    368369            return JSVAL_VOID; // TODO: report error
    369370    }
    370371
  • 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/components/ICmpCommandQueue.cpp

     
    1616 */
    1717
    1818#include "precompiled.h"
     19#include "jsapi.h"
    1920
    2021#include "ICmpCommandQueue.h"
    2122
  • 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            {
     
    213215        // to prevent frequent AI out-of-memory crashes. The argument should be
    214216        // removed as soon whenever the new pathfinder is committed
    215217        // 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)),
     218        m_ScriptInterface(new ScriptInterface("Engine", "AI", g_ScriptRuntime)),
    218219        m_TurnNum(0),
    219220        m_CommandsComputed(true),
    220221        m_HasLoadedEntityTemplates(false),
     
    305306    static void ForceGC(ScriptInterface::CxPrivate* pCxPrivate)
    306307    {
    307308        PROFILE3("AI compute GC");
    308         JS_GC(pCxPrivate->pScriptInterface->GetContext());
     309        JS_GC(pCxPrivate->pScriptInterface->GetJSRuntime());
    309310    }
    310311   
    311312    /**
     
    408409            m_ScriptInterface->Eval("({})", fakeTech);
    409410            m_ScriptInterface->SetProperty(settings.get(), "techTemplates", fakeTech, false);
    410411        }
    411         m_SharedAIObj = CScriptValRooted(m_ScriptInterface->GetContext(),m_ScriptInterface->CallConstructor(ctor.get(), settings.get()));
     412       
     413        JS::AutoValueVector argv(m_ScriptInterface->GetContext());
     414        argv.append(settings.get());
     415        m_SharedAIObj = CScriptValRooted(m_ScriptInterface->GetContext(),m_ScriptInterface->CallConstructor(ctor.get(), argv.length(), argv.handleAt(0)));
    412416   
    413417       
    414418        if (m_SharedAIObj.undefined())
     
    754758                m_Players[i]->Run(state, m_Players[i]->m_Player);
    755759        }
    756760
     761/*
    757762        // Run GC if we are about to overflow
    758763        if (JS_GetGCParameter(m_ScriptInterface->GetJSRuntime(), JSGC_BYTES) > 33000000)
    759764        {
    760765            PROFILE3("AI compute GC");
    761766
    762             JS_GC(m_ScriptInterface->GetContext());
     767            JS_GC(m_ScriptInterface->GetJSRuntime());
    763768        }
    764        
     769    */ 
    765770        // Run the GC every so often.
    766771        // (This isn't particularly necessary, but it makes profiling clearer
    767772        // 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);
     45        JS_SetProperty(cx, obj, "radius", pradius);
     46        JS_SetProperty(cx, obj, "height", pheight);
    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);
     55        JS_SetProperty(cx, obj, "width", pwidth);
     56        JS_SetProperty(cx, obj, "depth", pdepth);
     57        JS_SetProperty(cx, obj, "height", pheight);
    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"
     24#include "jsapi.h"
    2525
    2626#define TOJSVAL_SETUP() \
    27     JSObject* obj = JS_NewObject(scriptInterface.GetContext(), NULL, NULL, NULL); \
    28     if (! obj) \
    29         return JSVAL_VOID;
     27    JSObject* obj; \
     28    {\
     29    JSAutoRequest rq(scriptInterface.GetContext()); \
     30    obj = JS_NewObject(scriptInterface.GetContext(), NULL, NULL, NULL); \
     31    if (!obj) \
     32        return JSVAL_VOID; \
     33    }
    3034
    3135#define SET_MSG_PROPERTY(name) \
    3236    do { \
    33         jsval prop = ScriptInterface::ToJSVal(scriptInterface.GetContext(), this->name); \
    34         if (! JS_SetProperty(scriptInterface.GetContext(), obj, #name, &prop)) \
     37        JSAutoRequest rq(scriptInterface.GetContext()); \
     38        JSContext* cx = scriptInterface.GetContext(); \
     39        JS::RootedValue prop(cx, ScriptInterface::ToJSVal(cx, this->name)); \
     40        if (! JS_SetProperty(cx, obj, #name, prop)) \
    3541            return JSVAL_VOID; \
    3642    } while (0);
    3743
    3844#define FROMJSVAL_SETUP() \
    39     if (! JSVAL_IS_OBJECT(val)) \
     45    if ( JSVAL_IS_PRIMITIVE(val)) \
    4046        return NULL; \
    4147    JSObject* obj = JSVAL_TO_OBJECT(val); \
    42     jsval prop;
     48    JS::RootedValue prop(scriptInterface.GetContext());
    4349
    4450#define GET_MSG_PROPERTY(type, name) \
     51    type name; \
     52    { \
     53    JSAutoRequest rq(scriptInterface.GetContext()); \
    4554    if (! JS_GetProperty(scriptInterface.GetContext(), obj, #name, &prop)) \
    4655        return NULL; \
    47     type name; \
    4856    if (! ScriptInterface::FromJSVal(scriptInterface.GetContext(), prop, name)) \
    49         return NULL;
     57        return NULL; \
     58    }
    5059
    5160jsval CMessage::ToJSValCached(ScriptInterface& scriptInterface) const
    5261{
  • 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;
     96    JS::RootedValue r(cx);
     97    JS::RootedValue g(cx);
     98    JS::RootedValue b(cx);
     99    JS::RootedValue a(cx);
    94100    if (!JS_GetProperty(cx, obj, "r", &r) || !FromJSVal(cx, r, out.r))
    95101        FAIL("Failed to get property CColor.r");
    96102    if (!JS_GetProperty(cx, obj, "g", &g) || !FromJSVal(cx, g, out.g))
     
    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);
     126    JS_SetProperty(cx, obj, "g", g);
     127    JS_SetProperty(cx, obj, "b", b);
     128    JS_SetProperty(cx, obj, "a", a);
    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);
     
    136144
    137145template<> jsval ScriptInterface::ToJSVal<fixed>(JSContext* 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
    152161    if (!JS_GetProperty(cx, obj, "x", &p)) return false; // TODO: report type errors
    153162    if (!FromJSVal(cx, p, out.X)) return false;
     
    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);
     185    JS_SetProperty(cx, obj, "y", y);
     186    JS_SetProperty(cx, obj, "z", z);
    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
    189200    if (!JS_GetProperty(cx, obj, "x", &p)) return false; // TODO: report type errors
    190201    if (!FromJSVal(cx, p, out.X)) return false;
     
    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);
     220    JS_SetProperty(cx, obj, "y", y);
    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);
     240    JS_SetProperty(cx, obj, "height", h);
     241    JS_SetProperty(cx, obj, "data", data);
    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);
     260    JS_SetProperty(cx, obj, "height", h);
     261    JS_SetProperty(cx, obj, "data", data);
    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/simulation2/serialization/StdDeserializer.cpp

     
    2525#include "scriptinterface/ScriptInterface.h"
    2626#include "scriptinterface/ScriptExtraHeaders.h" // for typed arrays
    2727
    28 #include "js/jsapi.h"
     28#include "jsapi.h"
    2929
    3030#include "lib/byte_order.h"
    3131
    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 
    5932CStdDeserializer::CStdDeserializer(ScriptInterface& scriptInterface, std::istream& stream) :
    6033    m_ScriptInterface(scriptInterface), m_Stream(stream)
    6134{
     
    141114    std::map<u32, JSObject*>::iterator it = m_ScriptBackrefs.begin();
    142115    for (; it != m_ScriptBackrefs.end(); ++it)
    143116    {
    144         if (!JS_RemoveObjectRoot(m_ScriptInterface.GetContext(), &it->second))
    145             throw PSERROR_Deserialize_ScriptError("JS_RemoveRoot failed");
     117        JS_RemoveObjectRoot(m_ScriptInterface.GetContext(), &it->second);
    146118    }
    147119    m_ScriptBackrefs.clear();
    148120}
     
    192164            if (!proto)
    193165                throw PSERROR_Deserialize_ScriptError("Failed to find serializable prototype for object");
    194166
    195             JSObject* parent = JS_GetParent(cx, proto);
     167            JSObject* parent = JS_GetParent(proto);
    196168            if (!proto || !parent)
    197169                throw PSERROR_Deserialize_ScriptError();
    198170
     
    203175
    204176            // Does it have custom Deserialize function?
    205177            // if so, we let it handle the deserialized data, rather than adding properties directly
    206             JSBool hasCustomDeserialize, hasCustomSerialize;
     178            bool hasCustomDeserialize, hasCustomSerialize;
    207179            if (!JS_HasProperty(cx, obj, "Serialize", &hasCustomSerialize) || !JS_HasProperty(cx, obj, "Deserialize", &hasCustomDeserialize))
    208180                throw PSERROR_Serialize_ScriptError("JS_HasProperty failed");
    209            
     181
    210182            if (hasCustomDeserialize)
    211183            {
    212                 jsval serialize;
     184                JS::RootedValue serialize(cx);
    213185                if (!JS_LookupProperty(cx, obj, "Serialize", &serialize))
    214186                    throw PSERROR_Serialize_ScriptError("JS_LookupProperty failed");
    215187                bool hasNullSerialize = hasCustomSerialize && JSVAL_IS_NULL(serialize);
     
    241213            utf16string propname;
    242214            ReadStringUTF16("prop name", propname);
    243215
    244             jsval propval = ReadScriptVal("prop value", NULL);
     216            JS::RootedValue propval(cx, ReadScriptVal("prop value", NULL));
    245217            CScriptValRooted propvalRoot(cx, propval);
    246218
    247             if (!JS_SetUCProperty(cx, obj, (const jschar*)propname.data(), propname.length(), &propval))
     219            if (!JS_SetUCProperty(cx, obj, (const jschar*)propname.data(), propname.length(), propval))
    248220                throw PSERROR_Deserialize_ScriptError();
    249221        }
    250222
     
    266238    {
    267239        double value;
    268240        NumberDouble_Unbounded("value", value);
    269         jsval rval;
    270         if (!JS_NewNumberValue(cx, value, &rval))
     241        jsval rval = JS_NumberValue(value);
     242        if (JSVAL_IS_NULL(rval))
    271243            throw PSERROR_Deserialize_ScriptError("JS_NewNumberValue failed");
    272244        return rval;
    273245    }
     
    275247    {
    276248        uint8_t value;
    277249        NumberU8("value", value, 0, 1);
    278         return BOOLEAN_TO_JSVAL(value ? JS_TRUE : JS_FALSE);
     250        return BOOLEAN_TO_JSVAL(value ? true : false);
    279251    }
    280252    case SCRIPT_TYPE_BACKREF:
    281253    {
     
    290262    {
    291263        double value;
    292264        NumberDouble_Unbounded("value", value);
    293         jsval val;
    294         if (!JS_NewNumberValue(cx, value, &val))
    295             throw PSERROR_Deserialize_ScriptError();
     265        JS::RootedValue val(cx, JS_NumberValue(value));
    296266        CScriptValRooted objRoot(cx, val);
    297267
    298268        JSObject* ctorobj;
    299         if (!JS_GetClassObject(cx, JS_GetGlobalObject(cx), JSProto_Number, &ctorobj))
     269        if (!JS_GetClassObject(cx, JS::CurrentGlobalOrNull(cx), JSProto_Number, &ctorobj))
    300270            throw PSERROR_Deserialize_ScriptError("JS_GetClassObject failed");
    301271
    302         JSObject* obj = JS_New(cx, ctorobj, 1, &val);
     272        JSObject* obj = JS_New(cx, ctorobj, 1, val.address());
    303273        if (!obj)
    304274            throw PSERROR_Deserialize_ScriptError("JS_New failed");
    305275        AddScriptBackref(obj);
     
    311281        ScriptString("value", str);
    312282        if (!str)
    313283            throw PSERROR_Deserialize_ScriptError();
    314         jsval val = STRING_TO_JSVAL(str);
     284        JS::RootedValue val(cx, STRING_TO_JSVAL(str));
    315285        CScriptValRooted valRoot(cx, val);
    316286
    317287        JSObject* ctorobj;
    318         if (!JS_GetClassObject(cx, JS_GetGlobalObject(cx), JSProto_String, &ctorobj))
     288        if (!JS_GetClassObject(cx, JS::CurrentGlobalOrNull(cx), JSProto_String, &ctorobj))
    319289            throw PSERROR_Deserialize_ScriptError("JS_GetClassObject failed");
    320290
    321         JSObject* obj = JS_New(cx, ctorobj, 1, &val);
     291        JSObject* obj = JS_New(cx, ctorobj, 1, val.address());
    322292        if (!obj)
    323293            throw PSERROR_Deserialize_ScriptError("JS_New failed");
    324294        AddScriptBackref(obj);
     
    328298    {
    329299        bool value;
    330300        Bool("value", value);
    331         jsval val = BOOLEAN_TO_JSVAL(value ? JS_TRUE : JS_FALSE);
    332         CScriptValRooted objRoot(cx, val);
     301        JS::RootedValue val(cx, BOOLEAN_TO_JSVAL(value));
    333302
    334303        JSObject* ctorobj;
    335         if (!JS_GetClassObject(cx, JS_GetGlobalObject(cx), JSProto_Boolean, &ctorobj))
     304        if (!JS_GetClassObject(cx, JS::CurrentGlobalOrNull(cx), JSProto_Boolean, &ctorobj))
    336305            throw PSERROR_Deserialize_ScriptError("JS_GetClassObject failed");
    337306
    338         JSObject* obj = JS_New(cx, ctorobj, 1, &val);
     307        JSObject* obj = JS_New(cx, ctorobj, 1, val.address());
    339308        if (!obj)
    340309            throw PSERROR_Deserialize_ScriptError("JS_New failed");
    341310        AddScriptBackref(obj);
     
    354323
    355324        // Get buffer object
    356325        jsval bufferVal = ReadScriptVal("buffer", NULL);
    357         CScriptValRooted bufferValRoot(cx, bufferVal);
    358326
    359         if (!JSVAL_IS_OBJECT(bufferVal))
     327        if (JSVAL_IS_PRIMITIVE(bufferVal))
    360328            throw PSERROR_Deserialize_ScriptError();
    361329
    362330        JSObject* bufferObj = JSVAL_TO_OBJECT(bufferVal);
    363         if (!js_IsArrayBuffer(bufferObj))
     331        if (!JS_IsArrayBufferObject(bufferObj))
    364332            throw PSERROR_Deserialize_ScriptError("js_IsArrayBuffer failed");
    365333
    366         JSObject* arrayObj = js_CreateTypedArrayWithBuffer(cx, GetJSArrayType(arrayType), bufferObj, byteOffset, length);
     334        JSObject* arrayObj;
     335        switch(arrayType)
     336        {
     337        case SCRIPT_TYPED_ARRAY_INT8:
     338            arrayObj = JS_NewInt8ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     339            break;
     340        case SCRIPT_TYPED_ARRAY_UINT8:
     341            arrayObj = JS_NewUint8ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     342            break;
     343        case SCRIPT_TYPED_ARRAY_INT16:
     344            arrayObj = JS_NewInt16ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     345            break;
     346        case SCRIPT_TYPED_ARRAY_UINT16:
     347            arrayObj = JS_NewUint16ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     348            break;
     349        case SCRIPT_TYPED_ARRAY_INT32:
     350            arrayObj = JS_NewInt32ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     351            break;
     352        case SCRIPT_TYPED_ARRAY_UINT32:
     353            arrayObj = JS_NewUint32ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     354            break;
     355        case SCRIPT_TYPED_ARRAY_FLOAT32:
     356            arrayObj = JS_NewFloat32ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     357            break;
     358        case SCRIPT_TYPED_ARRAY_FLOAT64:
     359            arrayObj = JS_NewFloat64ArrayWithBuffer(cx, bufferObj, byteOffset, length);
     360            break;
     361        case SCRIPT_TYPED_ARRAY_UINT8_CLAMPED:
     362            arrayObj = JS_NewUint8ClampedArrayWithBuffer(cx, bufferObj, byteOffset, length);
     363            break;
     364        default:
     365            throw PSERROR_Deserialize_ScriptError("Failed to deserialize unrecognized typed array view");
     366        }
    367367        if (!arrayObj)
    368368            throw PSERROR_Deserialize_ScriptError("js_CreateTypedArrayWithBuffer failed");
    369369
     
    383383#error TODO: need to convert JS ArrayBuffer data from little-endian
    384384#endif
    385385
    386         JSObject* bufferObj = js_CreateArrayBuffer(cx, length);
    387         if (!bufferObj)
    388             throw PSERROR_Deserialize_ScriptError("js_CreateArrayBuffer failed");
    389 
     386        JSObject* bufferObj = JS_NewArrayBufferWithContents(cx, (void*)bufferData);
    390387        AddScriptBackref(bufferObj);
    391388
    392         js::ArrayBuffer* buffer = js::ArrayBuffer::fromJSObject(bufferObj);
    393         memcpy(buffer->data, bufferData, length);
    394         delete[] bufferData;
    395 
    396389        return OBJECT_TO_JSVAL(bufferObj);
    397390    }
    398391    default:
     
    440433
    441434void CStdDeserializer::ScriptObjectAppend(const char* name, jsval& obj)
    442435{
    443     if (!JSVAL_IS_OBJECT(obj))
     436    if (JSVAL_IS_PRIMITIVE(obj))
    444437        throw PSERROR_Deserialize_ScriptError();
    445438
    446439    ReadScriptVal(name, JSVAL_TO_OBJECT(obj));
  • source/simulation2/serialization/BinarySerializer.cpp

     
    2727#include "scriptinterface/ScriptInterface.h"
    2828#include "scriptinterface/ScriptExtraHeaders.h" // for JSDOUBLE_IS_INT32, typed arrays
    2929
    30 static u8 GetArrayType(uint32 arrayType)
     30static u8 GetArrayType(JSArrayBufferViewType arrayType)
    3131{
    3232    switch(arrayType)
    3333    {
    34     case js::TypedArray::TYPE_INT8:
     34    case JSArrayBufferViewType::TYPE_INT8:
    3535        return SCRIPT_TYPED_ARRAY_INT8;
    36     case js::TypedArray::TYPE_UINT8:
     36    case JSArrayBufferViewType::TYPE_UINT8:
    3737        return SCRIPT_TYPED_ARRAY_UINT8;
    38     case js::TypedArray::TYPE_INT16:
     38    case JSArrayBufferViewType::TYPE_INT16:
    3939        return SCRIPT_TYPED_ARRAY_INT16;
    40     case js::TypedArray::TYPE_UINT16:
     40    case JSArrayBufferViewType::TYPE_UINT16:
    4141        return SCRIPT_TYPED_ARRAY_UINT16;
    42     case js::TypedArray::TYPE_INT32:
     42    case JSArrayBufferViewType::TYPE_INT32:
    4343        return SCRIPT_TYPED_ARRAY_INT32;
    44     case js::TypedArray::TYPE_UINT32:
     44    case JSArrayBufferViewType::TYPE_UINT32:
    4545        return SCRIPT_TYPED_ARRAY_UINT32;
    46     case js::TypedArray::TYPE_FLOAT32:
     46    case JSArrayBufferViewType::TYPE_FLOAT32:
    4747        return SCRIPT_TYPED_ARRAY_FLOAT32;
    48     case js::TypedArray::TYPE_FLOAT64:
     48    case JSArrayBufferViewType::TYPE_FLOAT64:
    4949        return SCRIPT_TYPED_ARRAY_FLOAT64;
    50     case js::TypedArray::TYPE_UINT8_CLAMPED:
     50    case JSArrayBufferViewType::TYPE_UINT8_CLAMPED:
    5151        return SCRIPT_TYPED_ARRAY_UINT8_CLAMPED;
    5252    default:
    5353        LOGERROR(L"Cannot serialize unrecognized typed array view: %d", arrayType);
     
    6060    m_ScriptBackrefsArena(1 * MiB), m_ScriptBackrefs(backrefs_t::key_compare(), ScriptBackrefsAlloc(m_ScriptBackrefsArena)), m_ScriptBackrefsNext(1)
    6161{
    6262}
    63 
     63// TODO YGW: Test serialization...
    6464void CBinarySerializerScriptImpl::HandleScriptVal(jsval val)
    6565{
    6666    JSContext* cx = m_ScriptInterface.GetContext();
     67    JSAutoRequest rq(cx);
    6768
    6869    switch (JS_TypeOfValue(cx, val))
    6970    {
     
    8586            break;
    8687        }
    8788
    88         JSObject* obj = JSVAL_TO_OBJECT(val);
     89        //JSObject* obj = JSVAL_TO_OBJECT(val);
     90        JS::RootedObject obj(cx, JSVAL_TO_OBJECT(val));
    8991
    9092        // If we've already serialized this object, just output a reference to it
    9193        u32 tag = GetScriptBackrefTag(obj);
     
    104106
    105107            // Arrays like [1, 2, ] have an 'undefined' at the end which is part of the
    106108            // length but seemingly isn't enumerated, so store the length explicitly
    107             jsuint length = 0;
     109            uint length = 0;
    108110            if (!JS_GetArrayLength(cx, obj, &length))
    109111                throw PSERROR_Serialize_ScriptError("JS_GetArrayLength failed");
    110112            m_Serializer.NumberU32_Unbounded("array length", length);
    111113        }
    112         else if (js_IsTypedArray(obj))
     114        //JS_IsArrayBufferViewObject()
     115        //JS_IsTypedArrayObject()
     116        else if (JS_IsTypedArrayObject(obj))
    113117        {
    114118            m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_TYPED_ARRAY);
    115119
    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);
     120            m_Serializer.NumberU8_Unbounded("array type", GetArrayType(JS_GetArrayBufferViewType(obj)));
     121            m_Serializer.NumberU32_Unbounded("byte offset", JS_GetTypedArrayByteOffset(obj));
     122            m_Serializer.NumberU32_Unbounded("length", JS_GetTypedArrayLength(obj));
    121123
    122124            // Now handle its array buffer
    123125            // this may be a backref, since ArrayBuffers can be shared by multiple views
    124             HandleScriptVal(OBJECT_TO_JSVAL(typedArray->bufferJS));
     126            HandleScriptVal(OBJECT_TO_JSVAL(JS_GetArrayBufferViewBuffer(obj)));
    125127            break;
    126128        }
    127         else if (js_IsArrayBuffer(obj))
     129        else if (JS_IsArrayBufferObject(obj))
    128130        {
    129131            m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_ARRAY_BUFFER);
    130132
    131             js::ArrayBuffer* arrayBuffer = js::ArrayBuffer::fromJSObject(obj);
    132 
    133133#if BYTE_ORDER != LITTLE_ENDIAN
    134134#error TODO: need to convert JS ArrayBuffer data to little-endian
    135135#endif
    136136
    137             u32 length = arrayBuffer->byteLength;
     137            u32 length = JS_GetArrayBufferByteLength(obj);
    138138            m_Serializer.NumberU32_Unbounded("buffer length", length);
    139             m_Serializer.RawBytes("buffer data", (const u8*)arrayBuffer->data, length);
     139            m_Serializer.RawBytes("buffer data", (const u8*)JS_GetArrayBufferData(obj), length);
    140140            break;
    141141        }
    142142        else
    143143        {
    144144            // Find type of object
    145             JSClass* jsclass = JS_GET_CLASS(cx, obj);
     145            JSClass* jsclass = JS_GetClass(obj);
    146146            if (!jsclass)
    147                 throw PSERROR_Serialize_ScriptError("JS_GET_CLASS failed");
     147                throw PSERROR_Serialize_ScriptError("JS_GetClass failed");
    148148            JSProtoKey protokey = JSCLASS_CACHED_PROTO_KEY(jsclass);
    149149
    150150            if (protokey == JSProto_Object)
    151151            {
    152152                // Object class - check for user-defined prototype
    153                 JSObject* proto = JS_GetPrototype(cx, obj);
     153                JS::RootedObject proto(cx);
     154                JS_GetPrototype(cx, obj, &proto);
    154155                if (!proto)
    155156                    throw PSERROR_Serialize_ScriptError("JS_GetPrototype failed");
    156157
     
    172173
    173174                    // Does it have custom Serialize function?
    174175                    // if so, we serialize the data it returns, rather than the object's properties directly
    175                     JSBool hasCustomSerialize;
     176                    bool hasCustomSerialize;
    176177                    if (!JS_HasProperty(cx, obj, "Serialize", &hasCustomSerialize))
    177178                        throw PSERROR_Serialize_ScriptError("JS_HasProperty failed");
    178                    
     179
    179180                    if (hasCustomSerialize)
    180181                    {
    181                         jsval serialize;
     182                        JS::RootedValue serialize(cx);
    182183                        if (!JS_LookupProperty(cx, obj, "Serialize", &serialize))
    183184                            throw PSERROR_Serialize_ScriptError("JS_LookupProperty failed");
    184185
     
    199200                // Standard Number object
    200201                m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_OBJECT_NUMBER);
    201202                // Get primitive value
    202                 jsdouble d;
     203                double d;
    203204                if (!JS_ValueToNumber(cx, val, &d))
    204205                    throw PSERROR_Serialize_ScriptError("JS_ValueToNumber failed");
    205206                m_Serializer.NumberDouble_Unbounded("value", d);
     
    221222                // Standard Boolean object
    222223                m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_OBJECT_BOOLEAN);
    223224                // Get primitive value
    224                 JSBool b;
     225                bool b;
    225226                if (!JS_ValueToBoolean(cx, val, &b))
    226227                    throw PSERROR_Serialize_ScriptError("JS_ValueToBoolean failed");
    227                 m_Serializer.Bool("value", b == JS_TRUE);
     228                m_Serializer.Bool("value", b);
    228229                break;
    229230            }
    230231            else
     
    240241        // (Note that we don't do any rooting, because we assume nothing is going to trigger GC.
    241242        // I'm not absolute certain that's necessarily a valid assumption.)
    242243
    243         AutoJSIdArray ida (cx, JS_Enumerate(cx, obj));
    244         if (!ida.get())
     244        JS::AutoIdArray ida (cx, JS_Enumerate(cx, obj));
     245        if (!ida)
    245246            throw PSERROR_Serialize_ScriptError("JS_Enumerate failed");
    246247
    247248        m_Serializer.NumberU32_Unbounded("num props", (uint32_t)ida.length());
     
    250251        {
    251252            jsid id = ida[i];
    252253
    253             jsval idval, propval;
     254            JS::Value idval;
     255            JS::RootedValue propval(cx);
    254256
    255257            // Get the property name as a string
    256258            if (!JS_IdToValue(cx, id, &idval))
     
    308310        else
    309311        {
    310312            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             }
     313            m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_DOUBLE);
     314            m_Serializer.NumberDouble_Unbounded("value", JSVAL_TO_DOUBLE(val));
    326315        }
    327316        break;
    328317    }
    329318    case JSTYPE_BOOLEAN:
    330319    {
    331320        m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_BOOLEAN);
    332         JSBool b = JSVAL_TO_BOOLEAN(val);
     321        bool b = JSVAL_TO_BOOLEAN(val);
    333322        m_Serializer.NumberU8_Unbounded("value", b ? 1 : 0);
    334323        break;
    335324    }
    336     case JSTYPE_XML:
    337     {
    338         LOGERROR(L"Cannot serialise JS objects of type 'xml'");
    339         throw PSERROR_Serialize_InvalidScriptValue();
    340     }
    341325    default:
    342326    {
    343327        debug_warn(L"Invalid TypeOfValue");
     
    349333void CBinarySerializerScriptImpl::ScriptString(const char* name, JSString* string)
    350334{
    351335    JSContext* cx = m_ScriptInterface.GetContext();
     336    JSAutoRequest rq(cx);
     337
    352338    size_t length;
    353339    const jschar* chars = JS_GetStringCharsAndLength(cx, string, &length);
    354340
     
    382368
    383369    // If it was newly inserted, we need to make sure it gets rooted
    384370    // for the duration that it's in m_ScriptBackrefs
     371    // Note: Spidermonkey has a moving GC. JSObject pointers in this mapping table can change,
     372    // but we have registered a custom trace call for the time m_ScriptBackrefs is alive which
     373    // takes care of updating the pointers in our mapping table.
     374    // TODO: Could this be bad for GC-Performance if we serialize large objects and keep the Serializer
     375    // (including m_ScriptBackrefs) alive? Do we keep it alive somewhere?
    385376    m_Rooter.Push(it.first->first);
    386377    m_ScriptBackrefsNext++;
    387378    // Return a non-tag number so callers know they need to serialize the object
  • 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    scriptInterface.EnumeratePropertyNamesWithPrefix(JS::RootedObject(scriptInterface.GetContext(), JSVAL_TO_OBJECT(dataval)), "", properties);
    333333    for (std::vector<int>::size_type i = 0; i != properties.size(); i++)
    334334    {
    335335        std::wstring value;
  • source/scriptinterface/ScriptConversions.cpp

     
    3232
    3333template<> bool ScriptInterface::FromJSVal<bool>(JSContext* cx, jsval v, bool& out)
    3434{
    35     JSBool ret;
     35    JSAutoRequest rq(cx);
     36    bool ret;
    3637    WARN_IF_NOT(JSVAL_IS_BOOLEAN(v), v);
    3738    if (!JS_ValueToBoolean(cx, v, &ret))
    3839        return false;
     
    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
    215245    if(!JS_GetProperty(cx, obj, "player", &player) || !FromJSVal(cx, player, out.playerID))
     
    236266
    237267template<> jsval ScriptInterface::ToJSVal<float>(JSContext* 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
    244273template<> jsval ScriptInterface::ToJSVal<double>(JSContext* 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
     
    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);
    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;
     420        JS::RootedValue el(cx);
    389421        if (!JS_GetElement(cx, obj, i, &el))
    390422            FAIL("Failed to read array element");
    391423        T el2;
  • 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 bool 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 bool callMethod(JSContext* cx, uint32_t argc, jsval* vp);
    6262BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
    6363#undef OVERLOADS
    6464
  • 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    bool 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    bool 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/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

     
    4040
    4141    for (size_t i = 0; i < m_Objects.size(); ++i)
    4242    {
    43         JS_CALL_OBJECT_TRACER(trc, m_Objects[i], "AutoGCRooter object");
     43        JS_CallObjectTracer(trc, &m_Objects[i], "AutoGCRooter object");
    4444    }
    4545
    4646    for (size_t i = 0; i < m_Vals.size(); ++i)
    4747    {
    48         JS_CALL_VALUE_TRACER(trc, m_Vals[i], "AutoGCRooter val");
     48        JS_CallValueTracer(trc, &m_Vals[i], "AutoGCRooter val");
    4949    }
    5050
     51    JSContext* cx = m_ScriptInterface.GetContext();
    5152    for (size_t i = 0; i < m_IdArrays.size(); ++i)
    5253    {
    53         for (jsint j = 0; j < m_IdArrays[i]->length; ++j)
     54        for (size_t j = 0; j < JS_IdArrayLength(cx, m_IdArrays[i]); ++j)
    5455        {
    5556            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");
     57            JS_IdToValue(cx, JS_IdArrayGet(cx, m_IdArrays[i], j), &val);
     58            JS_CallValueTracer(trc, &val, "AutoGCRooter id array");
    5859        }
    5960    }
    6061
  • source/scriptinterface/ScriptInterface.h

     
    2525#include "ScriptTypes.h"
    2626#include "ScriptVal.h"
    2727
    28 #include "js/jsapi.h"
     28#include "jsapi.h"
    2929
    3030#include "ps/Errors.h"
    3131ERROR_GROUP(Scripting);
     
    114114        void* pCBData; // meant to be used as the "this" object for callback functions
    115115    } m_CxPrivate;
    116116
     117    void Tick();
    117118    void SetCallbackData(void* pCBData);
    118119    static CxPrivate* GetScriptInterfaceAndCBData(JSContext* cx);
    119120
     
    136137     * Call a constructor function, equivalent to JS "new ctor(arg)".
    137138     * @return The new object; or JSVAL_VOID on failure, and logs an error message
    138139     */
    139     jsval CallConstructor(jsval ctor, jsval arg);
     140    jsval CallConstructor(jsval ctor, int argc, jsval argv);
    140141
    141142    /**
    142143     * Create an object as with CallConstructor except don't actually execute the
     
    251252     */
    252253    bool HasProperty(jsval obj, const char* name);
    253254
    254     bool EnumeratePropertyNamesWithPrefix(jsval obj, const char* prefix, std::vector<std::string>& out);
     255    bool EnumeratePropertyNamesWithPrefix(JS::HandleObject obj, const char* prefix, std::vector<std::string>& out);
    255256
    256     bool SetPrototype(jsval obj, jsval proto);
     257    bool SetPrototype(JS::HandleObject obj, JS::HandleObject proto);
    257258
    258259    bool FreezeObject(jsval obj, bool deep);
    259260
     
    338339     */
    339340    void MaybeGC();
    340341
     342    bool MathRandom(double& nbr);
     343
    341344    /**
    342345     * Structured clones are a way to serialize 'simple' JS values into a buffer
    343346     * that can safely be passed between contexts and runtimes and threads.
     
    351354    public:
    352355        StructuredClone();
    353356        ~StructuredClone();
    354         JSContext* m_Context;
    355         uint64* m_Data;
     357        uint64_t* m_Data;
    356358        size_t m_Size;
    357359    };
    358360
     
    367369    bool SetProperty_(jsval obj, const char* name, jsval value, bool readonly, bool enumerate);
    368370    bool SetProperty_(jsval obj, const wchar_t* name, jsval value, bool readonly, bool enumerate);
    369371    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);
     372    bool GetProperty_(jsval obj, const char* name, JS::MutableHandleValue out);
     373    bool GetPropertyInt_(jsval obj, int name, JS::MutableHandleValue value);
    372374    static bool IsExceptionPending(JSContext* cx);
    373     static JSClass* GetClass(JSContext* cx, JSObject* obj);
    374     static void* GetPrivate(JSContext* cx, JSObject* obj);
     375    static JSClass* GetClass(JSObject* obj);
     376    static void* GetPrivate(JSObject* obj);
    375377
    376378    class CustomType
    377379    {
     
    383385    void Register(const char* name, JSNative fptr, size_t nargs);
    384386    std::auto_ptr<ScriptInterface_impl> m;
    385387   
     388    boost::rand48* m_rng;
    386389    std::map<std::string, CustomType> m_CustomObjectTypes;
    387390
    388391// The nasty macro/template bits are split into a separate file so you don't have to look at them
     
    527530template<typename T>
    528531bool ScriptInterface::GetProperty(jsval obj, const char* name, T& out)
    529532{
    530     jsval val;
    531     if (! GetProperty_(obj, name, val))
     533    JSContext* cx = GetContext();
     534    JSAutoRequest rq(cx);
     535    JS::RootedValue val(cx);
     536    if (! GetProperty_(obj, name, &val))
    532537        return false;
    533     return FromJSVal(GetContext(), val, out);
     538    return FromJSVal(cx, val, out);
    534539}
    535540
    536541template<typename T>
    537542bool ScriptInterface::GetPropertyInt(jsval obj, int name, T& out)
    538543{
    539     jsval val;
    540     if (! GetPropertyInt_(obj, name, val))
     544    JS::RootedValue val(GetContext());
     545    if (! GetPropertyInt_(obj, name, &val))
    541546        return false;
    542547    return FromJSVal(GetContext(), val, out);
    543548}
  • source/scriptinterface/ScriptTypes.h

     
    7878# pragma warning(disable:4100) // "unreferenced formal parameter"
    7979#endif
    8080
    81 #include "js/jsapi.h"
     81#include "jsapi.h"
     82#include "jspubtd.h"
    8283
    8384#if MSC_VERSION
    8485# pragma warning(pop)
     
    8889# pragma GCC diagnostic warning "-Wredundant-decls"
    8990#endif
    9091
    91 #if JS_VERSION != 185
    92 #error Your compiler is trying to use an incorrect version of the SpiderMonkey library.
    93 #error The only version that works is the one in the libraries/spidermonkey/ directory,
    94 #error and it will not work with a typical system-installed version.
    95 #error Make sure you have got all the right files and include paths.
    96 #endif
     92//#if MOZJS_MAJOR_VERSION != 24 || MOZJS_MINOR_VERSION != 0
     93//#error Your compiler is trying to use an incorrect version of the SpiderMonkey library.
     94//#error The only version that works is the one in the libraries/spidermonkey/ directory,
     95//#error and it will not work with a typical system-installed version.
     96//#error Make sure you have got all the right files and include paths.
     97//#endif
    9798
    9899class ScriptInterface;
    99100class CScriptVal;
  • source/scriptinterface/ScriptVal.cpp

     
    1717
    1818#include "precompiled.h"
    1919
     20#include "ScriptInterface.h"
    2021#include "ScriptVal.h"
    2122
    22 #include "js/jsapi.h"
     23#include "jsapi.h"
     24#include "jspubtd.h"
     25//#include "jsatom.h"
    2326
     27
    2428struct Unrooter
    2529{
    2630    Unrooter(JSContext* cx) : cx(cx) { }
    27     void operator()(jsval* p) { JS_RemoveValueRoot(cx, p); delete p; }
     31    void operator()(jsval* p)
     32    {
     33        JSAutoRequest rq(cx);
     34        JS_RemoveValueRoot(cx, p); delete p;
     35    }
    2836    JSContext* cx;
    2937};
    3038
    3139CScriptValRooted::CScriptValRooted(JSContext* cx, jsval val)
    3240{
     41    JSAutoRequest rq(cx);
    3342    jsval* p = new jsval(val);
    3443    JS_AddNamedValueRoot(cx, p, "CScriptValRooted");
    3544    m_Val = boost::shared_ptr<jsval>(p, Unrooter(cx));
     
    3746
    3847CScriptValRooted::CScriptValRooted(JSContext* cx, CScriptVal val)
    3948{
     49    JSAutoRequest rq(cx);
    4050    jsval* p = new jsval(val.get());
    4151    JS_AddNamedValueRoot(cx, p, "CScriptValRooted");
    4252    m_Val = boost::shared_ptr<jsval>(p, Unrooter(cx));
     
    4959    return *m_Val;
    5060}
    5161
     62void CScriptValRooted::getPtr(JS::Value** val)
     63{
     64    *val = &*m_Val;
     65}
     66
    5267jsval& CScriptValRooted::getRef() const
    5368{
    5469    ENSURE(m_Val);
     
    6580    return !m_Val;
    6681}
    6782
     83/*
    6884AutoJSIdArray::AutoJSIdArray(JSContext* cx, JSIdArray* ida) :
    6985    m_Context(cx), m_IdArray(ida)
    7086{
     
    85101{
    86102    if (!m_IdArray)
    87103        return 0;
    88     return m_IdArray->length;
     104    return JS_IdArrayLength(m_Context, m_IdArray);
    89105}
    90106
    91107jsid AutoJSIdArray::operator[](size_t i) const
     
    93109    if (!(m_IdArray && i < (size_t)m_IdArray->length))
    94110        return JSID_VOID;
    95111    return m_IdArray->vector[i];
    96 }
     112}*/
     113
     114
     115//CRootedWrapper::CRootedWrapper(JSContext* cx, JS::Value val)
     116//{
     117//  JSAutoRequest rq(cx);
     118//  JS::Value* wrap = &val;
     119//  JS_WrapValue(cx, val);
     120//  m_Val = boost::shared_ptr<JS::Value>(wrap, Unrooter(cx));
     121//}
  • source/scriptinterface/ScriptExtraHeaders.h

     
    4646# define signbit std::signbit
    4747#endif
    4848
    49 #include "js/jstypedarray.h"
    50 #include "js/jsdbgapi.h"
     49//#include "js/jstypedarray.h"
     50//#include "jspubtd.h"
     51//#include "jsatom.h"
     52#include "jsfriendapi.h"
     53#include "js/OldDebugAPI.h"
     54#include "js/StructuredClone.h"
    5155
    5256#undef signbit
    5357
  • source/scriptinterface/ScriptStats.cpp

     
    2121
    2222#include "scriptinterface/ScriptInterface.h"
    2323
    24 #include "js/jsapi.h"
     24#include "jsapi.h"
    2525
    2626CScriptStatsTable* g_ScriptStatsTable;
    2727
  • source/scriptinterface/ScriptInterface.cpp

     
    7171    ScriptRuntime(int runtimeSize) :
    7272        m_rooter(NULL)
    7373    {
    74         m_rt = JS_NewRuntime(runtimeSize);
     74        // TODO: check what JS_Init() actually does and what the constraints are
     75        // What I know: It must be called before calling JS_NewRuntime
     76        JS_Init();
     77        m_rt = JS_NewRuntime(runtimeSize, JS_USE_HELPER_THREADS);
     78
    7579        ENSURE(m_rt); // TODO: error handling
    7680
     81        JS_SetNativeStackQuota(m_rt, 128 * sizeof(size_t) * 1024);
    7782        if (g_ScriptProfilingEnabled)
    7883        {
    7984            // Profiler isn't thread-safe, so only enable this on the main thread
     
    8792            }
    8893        }
    8994
    90         JS_SetExtraGCRoots(m_rt, jshook_trace, this);
     95        JS_AddExtraGCRootsTracer(m_rt, jshook_trace, this);
     96        m_dummyContext = JS_NewContext(m_rt, STACK_CHUNK_SIZE);
     97        ENSURE(m_dummyContext);
    9198    }
    9299
    93100    ~ScriptRuntime()
    94101    {
     102        JS_DestroyContext(m_dummyContext);
    95103        JS_DestroyRuntime(m_rt);
    96104    }
    97105
     106    JSContext* m_dummyContext;
    98107    JSRuntime* m_rt;
    99108    AutoGCRooter* m_rooter;
    100109
    101110private:
    102111
    103112
    104     static void* jshook_script(JSContext* UNUSED(cx), JSStackFrame* UNUSED(fp), JSBool before, JSBool* UNUSED(ok), void* closure)
     113    static void* jshook_script(JSContext* UNUSED(cx), JSAbstractFramePtr UNUSED(fp), bool isConstructing, bool before, bool* UNUSED(ok), void* closure)
    105114    {
    106115        if (before)
    107116            g_Profiler.StartScript("script invocation");
     
    154163            if (slash != filename.npos)
    155164                filename = filename.substr(slash+1);
    156165
    157             uintN line = JS_PCToLineNumber(cx, script, pc);
     166            uint line = JS_PCToLineNumber(cx, script, pc);
    158167
    159168            std::stringstream ss;
    160169            ss << "(" << filename << ":" << line << ")";
     
    178187        boost::flyweights::no_locking
    179188    > LocFlyweight;
    180189
    181     static void* jshook_function(JSContext* cx, JSStackFrame* fp, JSBool before, JSBool* UNUSED(ok), void* closure)
     190    static void* jshook_function(JSContext* cx, JSAbstractFramePtr fp, bool isConstructing, bool before, bool* UNUSED(ok), void* closure)
    182191    {
    183192        if (!before)
    184193        {
     
    186195            return closure;
    187196        }
    188197
    189         JSFunction* fn = JS_GetFrameFunction(cx, fp);
     198        JSFunction* fn = fp.maybeFun();
    190199        if (!fn)
    191200        {
    192201            g_Profiler.StartScript("(function)");
     
    207216        }
    208217
    209218        // No name - compute from the location instead
    210         ScriptLocation loc = { cx, JS_GetFrameScript(cx, fp), JS_GetFramePC(cx, fp) };
     219        JSScript* script;
     220        unsigned lineno;
     221        JS_DescribeScriptedCaller(cx, &script, &lineno);
     222        ENSURE(script == fp.script());
     223        ScriptLocation loc = { cx, fp.script(), JS_LineNumberToPC(cx, script, lineno) };
    211224        g_Profiler.StartScript(LocFlyweight(loc).get().name.c_str());
    212225
    213226        return closure;
     
    233246{
    234247    ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime);
    235248    ~ScriptInterface_impl();
    236     void Register(const char* name, JSNative fptr, uintN nargs);
     249    void Register(const char* name, JSNative fptr, uint nargs);
    237250
    238251    shared_ptr<ScriptRuntime> m_runtime;
    239252    JSContext* m_cx;
    240253    JSObject* m_glob; // global scope object
     254    JSCompartment* m_comp;
     255    boost::rand48* m_rng;
    241256    JSObject* m_nativeScope; // native function scope object
    242257};
    243258
     
    246261
    247262JSClass global_class = {
    248263    "global", JSCLASS_GLOBAL_FLAGS,
    249     JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
    250     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
     264    JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     265    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
    251266    NULL, NULL, NULL, NULL,
    252267    NULL, NULL, NULL, NULL
    253268};
    254269
    255270void ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report)
    256271{
    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;
    262272
    263273    std::stringstream msg;
    264274    bool isWarning = JSREPORT_IS_WARNING(report->flags);
     
    273283
    274284    // If there is an exception, then print its stack trace
    275285    jsval excn;
    276     if (JS_GetPendingException(cx, &excn) && JSVAL_IS_OBJECT(excn))
     286    if (JS_GetPendingException(cx, &excn) && !JSVAL_IS_PRIMITIVE(excn))
    277287    {
    278288        // TODO: this violates the docs ("The error reporter callback must not reenter the JSAPI.")
    279289
     
    309319
    310320// Functions in the global namespace:
    311321
    312 JSBool print(JSContext* cx, uintN argc, jsval* vp)
     322bool print(JSContext* cx, uint argc, jsval* vp)
    313323{
    314     for (uintN i = 0; i < argc; ++i)
     324    for (uint i = 0; i < argc; ++i)
    315325    {
    316326        std::wstring str;
    317327        if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[i], str))
    318             return JS_FALSE;
     328            return false;
    319329        debug_printf(L"%ls", str.c_str());
    320330    }
    321331    fflush(stdout);
    322332    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    323     return JS_TRUE;
     333    return true;
    324334}
    325335
    326 JSBool logmsg(JSContext* cx, uintN argc, jsval* vp)
     336bool logmsg(JSContext* cx, uint argc, jsval* vp)
    327337{
    328338    if (argc < 1)
    329339    {
    330340        JS_SET_RVAL(cx, vp, JSVAL_VOID);
    331         return JS_TRUE;
     341        return true;
    332342    }
    333343
    334344    std::wstring str;
    335345    if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
    336         return JS_FALSE;
    337     LOGMESSAGE(L"%ls", str.c_str());
     346        return false;
     347    LOGMESSAGE(L"%ls%f", str.c_str(), timer_Time());
    338348    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    339     return JS_TRUE;
     349    return true;
    340350}
    341351
    342 JSBool warn(JSContext* cx, uintN argc, jsval* vp)
     352bool warn(JSContext* cx, uint argc, jsval* vp)
    343353{
    344354    if (argc < 1)
    345355    {
    346356        JS_SET_RVAL(cx, vp, JSVAL_VOID);
    347         return JS_TRUE;
     357        return true;
    348358    }
    349359
    350360    std::wstring str;
    351361    if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
    352         return JS_FALSE;
     362        return false;
    353363    LOGWARNING(L"%ls", str.c_str());
    354364    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    355     return JS_TRUE;
     365    return true;
    356366}
    357367
    358 JSBool error(JSContext* cx, uintN argc, jsval* vp)
     368bool error(JSContext* cx, uint argc, jsval* vp)
    359369{
    360370    if (argc < 1)
    361371    {
    362372        JS_SET_RVAL(cx, vp, JSVAL_VOID);
    363         return JS_TRUE;
     373        return true;
    364374    }
    365375
    366376    std::wstring str;
    367377    if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
    368         return JS_FALSE;
     378        return false;
    369379    LOGERROR(L"%ls", str.c_str());
    370380    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    371     return JS_TRUE;
     381    return true;
    372382}
    373383
    374 JSBool deepcopy(JSContext* cx, uintN argc, jsval* vp)
     384bool deepcopy(JSContext* cx, uint argc, jsval* vp)
    375385{
    376386    if (argc < 1)
    377387    {
    378388        JS_SET_RVAL(cx, vp, JSVAL_VOID);
    379         return JS_TRUE;
     389        return true;
    380390    }
    381391
    382392    jsval ret;
    383393
    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))
    392         return JS_FALSE;
     394    if (!JS_StructuredClone(cx, JS_ARGV(cx, vp)[0], &ret, NULL, NULL))
     395        return false;
    393396
    394397    JS_SET_RVAL(cx, vp, ret);
    395     return JS_TRUE;
     398    return true;
    396399}
    397400
    398 JSBool ProfileStart(JSContext* cx, uintN argc, jsval* vp)
     401bool ProfileStart(JSContext* cx, uint argc, jsval* vp)
    399402{
    400403    const char* name = "(ProfileStart)";
    401404
     
    403406    {
    404407        std::string str;
    405408        if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
    406             return JS_FALSE;
     409            return false;
    407410
    408411        typedef boost::flyweight<
    409412            std::string,
     
    420423    g_Profiler2.RecordRegionEnter(name);
    421424
    422425    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    423     return JS_TRUE;
     426    return true;
    424427}
    425428
    426 JSBool ProfileStop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* vp)
     429bool ProfileStop(JSContext* UNUSED(cx), uint UNUSED(argc), jsval* vp)
    427430{
    428431    if (CProfileManager::IsInitialised() && ThreadUtil::IsMainThread())
    429432        g_Profiler.Stop();
     
    431434    g_Profiler2.RecordRegionLeave("(ProfileStop)");
    432435
    433436    JS_SET_RVAL(cx, vp, JSVAL_VOID);
    434     return JS_TRUE;
     437    return true;
    435438}
    436439
    437440// Math override functions:
     
    452455    }
    453456}
    454457
    455 JSBool Math_random(JSContext* cx, uintN UNUSED(argc), jsval* vp)
     458bool Math_random(JSContext* cx, uint UNUSED(argc), jsval* vp)
    456459{
    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))
    460         return JS_FALSE;
    461     boost::rand48* rng = static_cast<boost::rand48*>(JSVAL_TO_PRIVATE(rngp));
     460    double r;
     461    if(!ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface->MathRandom(r))
     462    {
     463        return false;
     464    }
     465    else
     466    {
     467        jsval rv = JS_NumberValue(r);
     468        JS_SET_RVAL(cx, vp, rv);
     469        return true;
     470    }
     471}
    462472
    463     double r = generate_uniform_real(*rng, 0.0, 1.0);
     473} // anonymous namespace
    464474
    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;
     475bool ScriptInterface::MathRandom(double& nbr)
     476{
     477    if (m->m_rng == NULL)
     478        return false;
     479    nbr = generate_uniform_real(*(m->m_rng), 0.0, 1.0);
     480    return true;
    470481}
    471482
    472 } // anonymous namespace
    473 
    474483ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const shared_ptr<ScriptRuntime>& runtime) :
    475484    m_runtime(runtime)
    476485{
    477     JSBool ok;
     486    bool ok;
    478487
    479488    m_cx = JS_NewContext(m_runtime->m_rt, STACK_CHUNK_SIZE);
    480489    ENSURE(m_cx);
    481490
     491    JS_SetParallelIonCompilationEnabled(m_cx, true);
     492
    482493    // For GC debugging:
    483494    // JS_SetGCZeal(m_cx, 2);
    484495
     
    486497
    487498    JS_SetErrorReporter(m_cx, ErrorReporter);
    488499
    489     uint32 options = 0;
    490     options |= JSOPTION_STRICT; // "warn on dubious practice"
    491     options |= JSOPTION_XML; // "ECMAScript for XML support: parse <!-- --> as a token"
     500    uint32_t options = 0;
     501    options |= JSOPTION_EXTRA_WARNINGS; // "warn on dubious practice"
     502    // We use strict mode to encourage better coding practices and
     503    //to get code that can be optimized better by Spidermonkey's JIT compiler.
     504    options |= JSOPTION_STRICT_MODE;
     505    //options |= JSOPTION_ALLOW_XML; // "ECMAScript for XML support: parse <!-- --> as a token"
    492506    options |= JSOPTION_VAROBJFIX; // "recommended" (fixes variable scoping)
    493507
    494508    // Enable method JIT, unless script profiling/debugging is enabled (since profiling/debugging
     
    496510    // TODO: Verify what exactly is incompatible
    497511    if (!g_ScriptProfilingEnabled && !g_JSDebuggerEnabled)
    498512    {
    499         options |= JSOPTION_METHODJIT;
     513        options |= JSOPTION_BASELINE;
     514        options |= JSOPTION_ION;
     515        options |= JSOPTION_TYPE_INFERENCE;
     516        options |= JSOPTION_COMPILE_N_GO;
    500517
    501518        // Some other JIT flags to experiment with:
    502         options |= JSOPTION_JIT;
    503         options |= JSOPTION_PROFILING;
     519        //options |= JSOPTION_METHODJIT_ALWAYS;
    504520    }
    505521
    506522    JS_SetOptions(m_cx, options);
    507     JS_SetVersion(m_cx, JSVERSION_LATEST);
     523    JSAutoRequest rq(m_cx);
    508524
    509     m_glob = JS_NewCompartmentAndGlobalObject(m_cx, &global_class, NULL);
     525    JS::CompartmentOptions opt;
     526    opt.setVersion(JSVERSION_LATEST);
     527    JS::RootedObject tmpglob(m_cx, JS_NewGlobalObject(m_cx, &global_class, NULL, JS::OnNewGlobalHookOption::DontFireOnNewGlobalHook, opt));
     528    // TODO: check again if we're doing everything correctly https://bugzilla.mozilla.org/show_bug.cgi?id=897322
     529    JS_FireOnNewGlobalObject(m_cx, tmpglob);
     530    m_glob = tmpglob.get();
     531    m_comp = JS_EnterCompartment(m_cx, m_glob);
    510532
    511533    ok = JS_InitStandardClasses(m_cx, m_glob);
    512534    ENSURE(ok);
     
    529551
    530552ScriptInterface_impl::~ScriptInterface_impl()
    531553{
     554    {
     555        JSAutoRequest rq(m_cx);
     556        JS_LeaveCompartment(m_cx, m_comp);
     557    }
    532558    JS_DestroyContext(m_cx);
    533559}
    534560
    535 void ScriptInterface_impl::Register(const char* name, JSNative fptr, uintN nargs)
     561void ScriptInterface_impl::Register(const char* name, JSNative fptr, uint nargs)
    536562{
     563    JSAutoRequest rq(m_cx);
    537564    JSFunction* func = JS_DefineFunction(m_cx, m_nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
    538565
    539566    if (!func)
     
    552579        > LockedStringFlyweight;
    553580
    554581        LockedStringFlyweight fw(name);
    555         JS_SetReservedSlot(m_cx, JS_GetFunctionObject(func), 0, PRIVATE_TO_JSVAL((void*)fw.get().c_str()));
     582        JS_SetReservedSlot(JS_GetFunctionObject(func), 0, PRIVATE_TO_JSVAL((void*)fw.get().c_str()));
    556583    }
    557584}
    558585
     
    599626    JS_ShutDown();
    600627}
    601628
     629void ScriptInterface::Tick()
     630{
     631    js::NotifyAnimationActivity(m->m_glob);
     632}
     633
    602634void ScriptInterface::SetCallbackData(void* pCBData)
    603635{
    604636    m_CxPrivate.pCBData = pCBData;
     
    633665
    634666bool ScriptInterface::ReplaceNondeterministicRNG(boost::rand48& rng)
    635667{
    636     jsval math;
    637     if (JS_GetProperty(m->m_cx, m->m_glob, "Math", &math) && JSVAL_IS_OBJECT(math))
     668    JSAutoRequest rq(m->m_cx);
     669    JS::RootedValue math(m->m_cx);
     670    if (JS_GetProperty(m->m_cx, m->m_glob, "Math", &math) && !JSVAL_IS_PRIMITIVE(math))
    638671    {
    639672        JSFunction* random = JS_DefineFunction(m->m_cx, JSVAL_TO_OBJECT(math), "random", Math_random, 0,
    640673            JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
    641674        if (random)
    642675        {
    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;
     676            m->m_rng = &rng;
     677            return true;
    646678        }
    647679    }
    648680
     
    652684
    653685void ScriptInterface::Register(const char* name, JSNative fptr, size_t nargs)
    654686{
    655     m->Register(name, fptr, (uintN)nargs);
     687    m->Register(name, fptr, (uint)nargs);
    656688}
    657689
    658690JSContext* ScriptInterface::GetContext() const
     
    678710}
    679711
    680712
    681 jsval ScriptInterface::CallConstructor(jsval ctor, jsval arg)
     713jsval ScriptInterface::CallConstructor(jsval ctor, int argc, jsval argv)
    682714{
    683     if (!JSVAL_IS_OBJECT(ctor))
     715    JSAutoRequest rq(m->m_cx);
     716    if (JSVAL_IS_PRIMITIVE(ctor))
    684717    {
    685718        LOGERROR(L"CallConstructor: ctor is not an object");
    686719        return JSVAL_VOID;
    687720    }
    688721
    689     return OBJECT_TO_JSVAL(JS_New(m->m_cx, JSVAL_TO_OBJECT(ctor), 1, &arg));
     722    // Passing argc 0 and argv JSVAL_VOID causes a crash in mozjs24
     723    if (argc == 0)
     724    {
     725        return OBJECT_TO_JSVAL(JS_New(m->m_cx, JSVAL_TO_OBJECT(ctor), 0, NULL));
     726    }
     727    else
     728        return OBJECT_TO_JSVAL(JS_New(m->m_cx, JSVAL_TO_OBJECT(ctor), argc, &argv));
    690729}
    691730
    692731jsval ScriptInterface::NewObjectFromConstructor(jsval ctor)
    693732{
     733    JSAutoRequest rq(m->m_cx);
    694734    // Get the constructor's prototype
    695735    // (Can't use JS_GetPrototype, since we want .prototype not .__proto__)
    696     jsval protoVal;
     736    JS::RootedValue protoVal(m->m_cx);
    697737    if (!JS_GetProperty(m->m_cx, JSVAL_TO_OBJECT(ctor), "prototype", &protoVal))
    698738    {
    699739        LOGERROR(L"NewObjectFromConstructor: can't get prototype");
    700740        return JSVAL_VOID;
    701741    }
    702742
    703     if (!JSVAL_IS_OBJECT(protoVal))
     743    if (JSVAL_IS_PRIMITIVE(protoVal))
    704744    {
    705745        LOGERROR(L"NewObjectFromConstructor: prototype is not an object");
    706746        return JSVAL_VOID;
    707747    }
    708748
    709749    JSObject* proto = JSVAL_TO_OBJECT(protoVal);
    710     JSObject* parent = JS_GetParent(m->m_cx, JSVAL_TO_OBJECT(ctor));
     750    JSObject* parent = JS_GetParent(JSVAL_TO_OBJECT(ctor));
    711751    // TODO: rooting?
    712752    if (!proto || !parent)
    713753    {
     
    727767
    728768void ScriptInterface::DefineCustomObjectType(JSClass *clasp, JSNative constructor, uint minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
    729769{
     770    JSAutoRequest rq(m->m_cx);
    730771    std::string typeName = clasp->name;
    731772
    732773    if (m_CustomObjectTypes.find(typeName) != m_CustomObjectTypes.end())
     
    774815
    775816bool ScriptInterface::CallFunction_(jsval val, const char* name, size_t argc, jsval* argv, jsval& ret)
    776817{
     818    JSAutoRequest rq(m->m_cx);
    777819    JSObject* obj;
    778820    if (!JS_ValueToObject(m->m_cx, val, &obj) || obj == NULL)
    779821        return false;
    780822
    781823    // Check that the named function actually exists, to avoid ugly JS error reports
    782824    // when calling an undefined value
    783     JSBool found;
     825    bool found;
    784826    if (!JS_HasProperty(m->m_cx, obj, name, &found) || !found)
    785827        return false;
    786828
    787     JSBool ok = JS_CallFunctionName(m->m_cx, obj, name, (uintN)argc, argv, &ret);
     829    bool ok = JS_CallFunctionName(m->m_cx, obj, name, (uint)argc, argv, &ret);
    788830
    789     return ok ? true : false;
     831    return ok;
    790832}
    791833
    792834jsval ScriptInterface::GetGlobalObject()
    793835{
    794     return OBJECT_TO_JSVAL(JS_GetGlobalObject(m->m_cx));
     836    JSAutoRequest rq(m->m_cx);
     837    return OBJECT_TO_JSVAL(JS::CurrentGlobalOrNull(m->m_cx));
    795838}
    796839
    797840JSClass* ScriptInterface::GetGlobalClass()
     
    801844
    802845bool ScriptInterface::SetGlobal_(const char* name, jsval value, bool replace)
    803846{
     847    JSAutoRequest rq(m->m_cx);
    804848    if (!replace)
    805849    {
    806         JSBool found;
     850        bool found;
    807851        if (!JS_HasProperty(m->m_cx, m->m_glob, name, &found))
    808852            return false;
    809853        if (found)
     
    813857        }
    814858    }
    815859
    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;
     860    bool ok = JS_DefineProperty(m->m_cx, m->m_glob, name, value, NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY
     861            | JSPROP_PERMANENT);
     862    return ok;
    819863}
    820864
    821865bool ScriptInterface::SetProperty_(jsval obj, const char* name, jsval value, bool constant, bool enumerate)
    822866{
    823     uintN attrs = 0;
     867    JSAutoRequest rq(m->m_cx);
     868    uint attrs = 0;
    824869    if (constant)
    825870        attrs |= JSPROP_READONLY | JSPROP_PERMANENT;
    826871    if (enumerate)
    827872        attrs |= JSPROP_ENUMERATE;
    828873
    829     if (! JSVAL_IS_OBJECT(obj))
     874    if (JSVAL_IS_PRIMITIVE(obj))
    830875        return false;
    831876    JSObject* object = JSVAL_TO_OBJECT(obj);
    832877
     
    837882
    838883bool ScriptInterface::SetProperty_(jsval obj, const wchar_t* name, jsval value, bool constant, bool enumerate)
    839884{
    840     uintN attrs = 0;
     885    JSAutoRequest rq(m->m_cx);
     886    uint attrs = 0;
    841887    if (constant)
    842888        attrs |= JSPROP_READONLY | JSPROP_PERMANENT;
    843889    if (enumerate)
    844890        attrs |= JSPROP_ENUMERATE;
    845891
    846     if (! JSVAL_IS_OBJECT(obj))
     892    if ( JSVAL_IS_PRIMITIVE(obj))
    847893        return false;
    848894    JSObject* object = JSVAL_TO_OBJECT(obj);
    849895
     
    855901
    856902bool ScriptInterface::SetPropertyInt_(jsval obj, int name, jsval value, bool constant, bool enumerate)
    857903{
    858     uintN attrs = 0;
     904    JSAutoRequest rq(m->m_cx);
     905    uint attrs = 0;
    859906    if (constant)
    860907        attrs |= JSPROP_READONLY | JSPROP_PERMANENT;
    861908    if (enumerate)
    862909        attrs |= JSPROP_ENUMERATE;
    863910
    864     if (! JSVAL_IS_OBJECT(obj))
     911    if ( JSVAL_IS_PRIMITIVE(obj))
    865912        return false;
    866913    JSObject* object = JSVAL_TO_OBJECT(obj);
    867914
     
    870917    return true;
    871918}
    872919
    873 bool ScriptInterface::GetProperty_(jsval obj, const char* name, jsval& out)
     920bool ScriptInterface::GetProperty_(jsval obj, const char* name, JS::MutableHandleValue out)
    874921{
    875     if (! JSVAL_IS_OBJECT(obj))
     922    JSAutoRequest rq(m->m_cx);
     923    if ( JSVAL_IS_PRIMITIVE(obj))
    876924        return false;
    877925    JSObject* object = JSVAL_TO_OBJECT(obj);
    878926
    879     if (!JS_GetProperty(m->m_cx, object, name, &out))
     927    if (!JS_GetProperty(m->m_cx, object, name, out))
    880928        return false;
    881929    return true;
    882930}
    883931
    884 bool ScriptInterface::GetPropertyInt_(jsval obj, int name, jsval& out)
     932bool ScriptInterface::GetPropertyInt_(jsval obj, int name, JS::MutableHandleValue out)
    885933{
    886     if (! JSVAL_IS_OBJECT(obj))
     934    JSAutoRequest rq(m->m_cx);
     935    if ( JSVAL_IS_PRIMITIVE(obj))
    887936        return false;
    888937    JSObject* object = JSVAL_TO_OBJECT(obj);
    889938
    890     if (!JS_GetPropertyById(m->m_cx, object, INT_TO_JSID(name), &out))
     939    if (!JS_GetPropertyById(m->m_cx, object, INT_TO_JSID(name), out))
    891940        return false;
    892941    return true;
    893942}
    894943
    895944bool ScriptInterface::HasProperty(jsval obj, const char* name)
    896945{
    897     if (! JSVAL_IS_OBJECT(obj))
     946    // TODO: proper errorhandling
     947    JSAutoRequest rq(m->m_cx);
     948    if ( JSVAL_IS_PRIMITIVE(obj))
    898949        return false;
    899950    JSObject* object = JSVAL_TO_OBJECT(obj);
    900951
    901     JSBool found;
     952    bool found;
    902953    if (!JS_HasProperty(m->m_cx, object, name, &found))
    903954        return false;
    904     return (found != JS_FALSE);
     955    return found;
    905956}
    906957
    907 bool ScriptInterface::EnumeratePropertyNamesWithPrefix(jsval obj, const char* prefix, std::vector<std::string>& out)
     958bool ScriptInterface::EnumeratePropertyNamesWithPrefix(JS::HandleObject obj, const char* prefix, std::vector<std::string>& out)
    908959{
    909     utf16string prefix16 (prefix, prefix+strlen(prefix));
     960    JSAutoRequest rq(m->m_cx);
     961    if (obj.get() == 0x0)
     962        return true;
    910963
    911     if (! JSVAL_IS_OBJECT(obj))
    912         return false; // TODO: log error messages
     964//  if ( obj.get().isPrimitive() )
     965//      return false; // TODO: log error messages
    913966
    914     JSObject* it = JS_NewPropertyIterator(m->m_cx, JSVAL_TO_OBJECT(obj));
     967    JSObject* it = JS_NewPropertyIterator(m->m_cx, obj.get());
    915968    if (!it)
    916969        return false;
    917970
     
    927980            continue; // ignore integer properties
    928981
    929982        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
     983        size_t len = strlen(prefix)+1;
     984        char buf[len];
     985        size_t prefixLen = strlen(prefix) * sizeof(char);
     986        JS_EncodeStringToBuffer(m->m_cx, name, buf, prefixLen);
     987        buf[len-1]= '\0';
     988        if(0 == strcmp(buf, prefix))
     989        {
     990            size_t len;
     991            const jschar* chars = JS_GetStringCharsAndLength(m->m_cx, name, &len);
     992            out.push_back(std::string(chars, chars+len));
     993        }
     994//      if (chars && len >= prefix16.size() && memcmp(chars, prefix16.c_str(), prefix16.size()*2) == 0)
     995//          out.push_back(std::string(chars, chars+len)); // handles Unicode poorly
     996
    934997    }
    935998
    936999    // Recurse up the prototype chain
    937     JSObject* prototype = JS_GetPrototype(m->m_cx, JSVAL_TO_OBJECT(obj));
    938     if (prototype)
     1000    JS::RootedObject prototype(m->m_cx);
     1001    if (JS_GetPrototype(m->m_cx, obj, &prototype))
    9391002    {
    940         if (! EnumeratePropertyNamesWithPrefix(OBJECT_TO_JSVAL(prototype), prefix, out))
     1003        if (! EnumeratePropertyNamesWithPrefix(prototype, prefix, out))
    9411004            return false;
    9421005    }
    9431006
    9441007    return true;
    9451008}
    9461009
    947 bool ScriptInterface::SetPrototype(jsval obj, jsval proto)
     1010bool ScriptInterface::SetPrototype(JS::HandleObject obj, JS::HandleObject proto)
    9481011{
    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;
     1012    JSAutoRequest rq(m->m_cx);
     1013    //if (JSVAL_IS_PRIMITIVE(obj) || JSVAL_IS_PRIMITIVE(proto))
     1014    //  return false;
     1015    return JS_SetPrototype(m->m_cx, obj, proto);
    9521016}
    9531017
    9541018bool ScriptInterface::FreezeObject(jsval obj, bool deep)
    9551019{
    956     if (!JSVAL_IS_OBJECT(obj))
     1020    JSAutoRequest rq(m->m_cx);
     1021    if (JSVAL_IS_PRIMITIVE(obj))
    9571022        return false;
    9581023
    9591024    if (deep)
     
    9641029
    9651030bool ScriptInterface::LoadScript(const VfsPath& filename, const std::string& code)
    9661031{
    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
     1032    JSAutoRequest rq(m->m_cx);
     1033    utf16string codeUtf16(code.begin(), code.end());
     1034    uint lineNo = 1;
    9721035
    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 
     1036    JS::Rooted<JSFunction*> func(m->m_cx,
     1037        JS_CompileUCFunction(m->m_cx, m->m_glob, utf8_from_wstring(filename.string()).c_str(), 0, NULL,
     1038            reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uint)(codeUtf16.length()),
     1039            utf8_from_wstring(filename.string()).c_str(), lineNo)
     1040    );
    9771041    if (!func)
    9781042        return false;
    9791043
    980     jsval scriptRval;
    981     JSBool ok = JS_CallFunction(m->m_cx, NULL, func, 0, NULL, &scriptRval);
     1044    JS::RootedValue val(m->m_cx);
     1045    bool ok = JS_CallFunction(m->m_cx, NULL, func, 0, NULL, val.address());
    9821046
    9831047    return ok ? true : false;
    9841048}
    9851049
    9861050bool ScriptInterface::LoadGlobalScript(const VfsPath& filename, const std::wstring& code)
    9871051{
    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
     1052    JSAutoRequest rq(m->m_cx);
     1053    utf16string codeUtf16(code.begin(), code.end());
     1054    uint lineNo = 1;
    9931055
    9941056    jsval rval;
    995     JSBool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob,
    996             reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uintN)(codeUtf16.length()),
     1057    bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob,
     1058            reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uint)(codeUtf16.length()),
    9971059            utf8_from_wstring(filename.string()).c_str(), lineNo, &rval);
    9981060
    999     return ok ? true : false;
     1061    return ok;
    10001062}
    10011063
    10021064bool ScriptInterface::LoadGlobalScriptFile(const VfsPath& path)
    10031065{
     1066    JSAutoRequest rq(m->m_cx);
    10041067    if (!VfsFileExists(path))
    10051068    {
    10061069        LOGERROR(L"File '%ls' does not exist", path.string().c_str());
     
    10191082
    10201083    std::wstring code = wstring_from_utf8(file.DecodeUTF8()); // assume it's UTF-8
    10211084
    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
     1085    utf16string codeUtf16(code.begin(), code.end());
     1086    uint lineNo = 1;
    10271087
    10281088    jsval rval;
    1029     JSBool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob,
    1030             reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uintN)(codeUtf16.length()),
     1089    bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob,
     1090            reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uint)(codeUtf16.length()),
    10311091            utf8_from_wstring(path.string()).c_str(), lineNo, &rval);
    10321092
    1033     return ok ? true : false;
     1093    return ok;
    10341094}
    10351095
    10361096
     
    10421102
    10431103bool ScriptInterface::Eval_(const char* code, jsval& rval)
    10441104{
     1105    JSAutoRequest rq(m->m_cx);
    10451106    utf16string codeUtf16(code, code+strlen(code));
    10461107
    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;
     1108    bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uint)codeUtf16.length(), "(eval)", 1, &rval);
     1109    return ok;
    10491110}
    10501111
    10511112bool ScriptInterface::Eval_(const wchar_t* code, jsval& rval)
    10521113{
     1114    JSAutoRequest rq(m->m_cx);
    10531115    utf16string codeUtf16(code, code+wcslen(code));
    10541116
    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;
     1117    bool ok = JS_EvaluateUCScript(m->m_cx, m->m_glob, (const jschar*)codeUtf16.c_str(), (uint)codeUtf16.length(), "(eval)", 1, &rval);
     1118    return ok;
    10571119}
    10581120
    10591121CScriptValRooted ScriptInterface::ParseJSON(const std::string& string_utf8)
    10601122{
     1123    JSAutoRequest rq(m->m_cx);
    10611124    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 
     1125    utf16string string(attrsW.begin(), attrsW.end());
     1126    JS::Rooted<jsval> vp(m->m_cx);
     1127    JS_ParseJSON(m->m_cx, reinterpret_cast<const jschar*>(string.c_str()), (uint32_t)string.size(), &vp);
    10841128    return CScriptValRooted(m->m_cx, vp);
    10851129}
    10861130
     
    11091153
    11101154struct Stringifier
    11111155{
    1112     static JSBool callback(const jschar* buf, uint32 len, void* data)
     1156    static bool callback(const jschar* buf, uint32_t len, void* data)
    11131157    {
    11141158        utf16string str(buf, buf+len);
    11151159        std::wstring strw(str.begin(), str.end());
    11161160
    11171161        Status err; // ignore Unicode errors
    11181162        static_cast<Stringifier*>(data)->stream << utf8_from_wstring(strw, &err);
    1119         return JS_TRUE;
     1163        return true;
    11201164    }
    11211165
    11221166    std::stringstream stream;
     
    11241168
    11251169struct StringifierW
    11261170{
    1127     static JSBool callback(const jschar* buf, uint32 len, void* data)
     1171    static bool callback(const jschar* buf, uint32_t len, void* data)
    11281172    {
    11291173        utf16string str(buf, buf+len);
    11301174        static_cast<StringifierW*>(data)->stream << std::wstring(str.begin(), str.end());
    1131         return JS_TRUE;
     1175        return true;
    11321176    }
    11331177
    11341178    std::wstringstream stream;
     
    11361180
    11371181std::string ScriptInterface::StringifyJSON(jsval obj, bool indent)
    11381182{
     1183    JSAutoRequest rq(m->m_cx);
    11391184    Stringifier str;
    11401185    if (!JS_Stringify(m->m_cx, &obj, NULL, indent ? INT_TO_JSVAL(2) : JSVAL_VOID, &Stringifier::callback, &str))
    11411186    {
     
    11511196
    11521197std::wstring ScriptInterface::ToString(jsval obj, bool pretty)
    11531198{
     1199    JSAutoRequest rq(m->m_cx);
    11541200    if (JSVAL_IS_VOID(obj))
    11551201        return L"(void 0)";
    11561202
     
    11631209        // Temporary disable the error reporter, so we don't print complaints about cyclic values
    11641210        JSErrorReporter er = JS_SetErrorReporter(m->m_cx, NULL);
    11651211
    1166         bool ok = JS_Stringify(m->m_cx, &obj, NULL, INT_TO_JSVAL(2), &StringifierW::callback, &str) == JS_TRUE;
     1212        bool ok = JS_Stringify(m->m_cx, &obj, NULL, INT_TO_JSVAL(2), &StringifierW::callback, &str) == true;
    11671213
    11681214        // Restore error reporter
    11691215        JS_SetErrorReporter(m->m_cx, er);
     
    11851231
    11861232void ScriptInterface::ReportError(const char* msg)
    11871233{
     1234    JSAutoRequest rq(m->m_cx);
    11881235    // JS_ReportError by itself doesn't seem to set a JS-style exception, and so
    11891236    // script callers will be unable to catch anything. So use JS_SetPendingException
    11901237    // to make sure there really is a script-level exception. But just set it to undefined
     
    11981245
    11991246bool ScriptInterface::IsExceptionPending(JSContext* cx)
    12001247{
     1248    JSAutoRequest rq(cx);
    12011249    return JS_IsExceptionPending(cx) ? true : false;
    12021250}
    12031251
    1204 JSClass* ScriptInterface::GetClass(JSContext* cx, JSObject* obj)
     1252JSClass* ScriptInterface::GetClass(JSObject* obj)
    12051253{
    1206     UNUSED2(cx); // unused if not JS_THREADSAFE
    1207 
    1208     return JS_GET_CLASS(cx, obj);
     1254    return JS_GetClass(obj);
    12091255}
    12101256
    1211 void* ScriptInterface::GetPrivate(JSContext* cx, JSObject* obj)
     1257void* ScriptInterface::GetPrivate(JSObject* obj)
    12121258{
    12131259    // TODO: use JS_GetInstancePrivate
    1214     return JS_GetPrivate(cx, obj);
     1260    return JS_GetPrivate(obj);
    12151261}
    12161262
    12171263void ScriptInterface::DumpHeap()
    12181264{
    12191265#if MOZJS_DEBUG_ABI
    1220     JS_DumpHeap(m->m_cx, stderr, NULL, 0, NULL, (size_t)-1, NULL);
     1266    JS_DumpHeap(GetJSRuntime(), stderr, NULL, JSTRACE_OBJECT, NULL, (size_t)-1, NULL);
    12211267#endif
    12221268    fprintf(stderr, "# Bytes allocated: %u\n", JS_GetGCParameter(GetJSRuntime(), JSGC_BYTES));
    1223     JS_GC(m->m_cx);
     1269    JS_GC(GetJSRuntime());
    12241270    fprintf(stderr, "# Bytes allocated after GC: %u\n", JS_GetGCParameter(GetJSRuntime(), JSGC_BYTES));
    12251271}
    12261272
     
    12591305    // Clone a new value (and root it and add it to the mapping)
    12601306    jsval Clone(jsval val)
    12611307    {
     1308        JSAutoRequest rq(cxFrom);
    12621309        if (JSVAL_IS_DOUBLE(val))
    12631310        {
    1264             jsval rval;
    1265             CLONE_REQUIRE(JS_NewNumberValue(cxTo, JSVAL_TO_DOUBLE(val), &rval), L"JS_NewNumberValue");
     1311            jsval rval = JS_NumberValue(JSVAL_TO_DOUBLE(val));
     1312            CLONE_REQUIRE(!JSVAL_IS_VOID(rval), L"JS_NumberValue");
    12661313            m_RooterTo.Push(rval);
    12671314            return rval;
    12681315        }
     
    12721319            size_t len;
    12731320            const jschar* chars = JS_GetStringCharsAndLength(cxFrom, JSVAL_TO_STRING(val), &len);
    12741321            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;
     1322            {
     1323                JSAutoRequest rq(cxTo);
     1324                JSString* str = JS_NewUCStringCopyN(cxTo, chars, len);
     1325                CLONE_REQUIRE(str, L"JS_NewUCStringCopyN");
     1326                jsval rval = STRING_TO_JSVAL(str);
     1327                m_Mapping[JSVAL_TO_GCTHING(val)] = rval;
     1328                m_RooterTo.Push(rval);
     1329                return rval;
     1330            }
    12811331        }
    12821332
    1283         ENSURE(JSVAL_IS_OBJECT(val));
     1333        ENSURE(!JSVAL_IS_PRIMITIVE(val));
    12841334
    12851335        JSObject* newObj;
    12861336        if (JS_IsArrayObject(cxFrom, JSVAL_TO_OBJECT(val)))
    12871337        {
    1288             jsuint length;
     1338            uint length;
    12891339            CLONE_REQUIRE(JS_GetArrayLength(cxFrom, JSVAL_TO_OBJECT(val), &length), L"JS_GetArrayLength");
    1290             newObj = JS_NewArrayObject(cxTo, length, NULL);
     1340            {
     1341                JSAutoRequest rq(cxTo);
     1342                newObj = JS_NewArrayObject(cxTo, length, NULL);
     1343            }   
    12911344            CLONE_REQUIRE(newObj, L"JS_NewArrayObject");
    12921345        }
    12931346        else
    12941347        {
    1295             newObj = JS_NewObject(cxTo, NULL, NULL, NULL);
     1348            {
     1349                JSAutoRequest rq(cxTo);
     1350                newObj = JS_NewObject(cxTo, NULL, NULL, NULL);
     1351            }
    12961352            CLONE_REQUIRE(newObj, L"JS_NewObject");
    12971353        }
    12981354
    12991355        m_Mapping[JSVAL_TO_GCTHING(val)] = OBJECT_TO_JSVAL(newObj);
    13001356        m_RooterTo.Push(newObj);
    13011357
    1302         AutoJSIdArray ida (cxFrom, JS_Enumerate(cxFrom, JSVAL_TO_OBJECT(val)));
    1303         CLONE_REQUIRE(ida.get(), L"JS_Enumerate");
     1358        JS::AutoIdArray ida (cxFrom, JS_Enumerate(cxFrom, JSVAL_TO_OBJECT(val)));
     1359        CLONE_REQUIRE(ida, L"JS_Enumerate");
     1360       
     1361//      AutoGCRooter idaRooter(scriptInterfaceFrom);
     1362//      idaRooter.Push(&ida);
    13041363
    1305         AutoGCRooter idaRooter(scriptInterfaceFrom);
    1306         idaRooter.Push(ida.get());
    1307 
    13081364        for (size_t i = 0; i < ida.length(); ++i)
    13091365        {
    13101366            jsid id = ida[i];
    1311             jsval idval, propval;
    1312             CLONE_REQUIRE(JS_IdToValue(cxFrom, id, &idval), L"JS_IdToValue");
     1367            JS::RootedValue idval(cxTo);
     1368            JS::RootedValue propval(cxTo);
     1369            CLONE_REQUIRE(JS_IdToValue(cxFrom, id, idval.address()), L"JS_IdToValue");
    13131370            CLONE_REQUIRE(JS_GetPropertyById(cxFrom, JSVAL_TO_OBJECT(val), id, &propval), L"JS_GetPropertyById");
    1314             jsval newPropval = GetOrClone(propval);
     1371            JS::RootedValue newPropval(cxTo, GetOrClone(propval));
    13151372
    13161373            if (JSVAL_IS_INT(idval))
    13171374            {
    13181375                // int jsids are portable across runtimes
    1319                 CLONE_REQUIRE(JS_SetPropertyById(cxTo, newObj, id, &newPropval), L"JS_SetPropertyById");
    1320             }
     1376                JSAutoRequest rq(cxTo);
     1377                CLONE_REQUIRE(JS_SetPropertyById(cxTo, newObj, id, newPropval), L"JS_SetPropertyById");
     1378                        }
    13211379            else if (JSVAL_IS_STRING(idval))
    13221380            {
    13231381                // string jsids are runtime-specific, so we need to copy the string content
     
    13261384                size_t len;
    13271385                const jschar* chars = JS_GetStringCharsAndLength(cxFrom, idstr, &len);
    13281386                CLONE_REQUIRE(idstr, L"JS_GetStringCharsAndLength (id)");
    1329                 CLONE_REQUIRE(JS_SetUCProperty(cxTo, newObj, chars, len, &newPropval), L"JS_SetUCProperty");
     1387                {
     1388                    JSAutoRequest rq(cxTo);
     1389                            CLONE_REQUIRE(JS_SetUCProperty(cxTo, newObj, chars, len, newPropval), L"JS_SetUCProperty");
     1390                }
    13301391            }
    13311392            else
    13321393            {
     
    13541415}
    13551416
    13561417ScriptInterface::StructuredClone::StructuredClone() :
    1357     m_Context(NULL), m_Data(NULL), m_Size(0)
     1418    m_Data(NULL), m_Size(0)
    13581419{
    13591420}
    13601421
    13611422ScriptInterface::StructuredClone::~StructuredClone()
    13621423{
    13631424    if (m_Data)
    1364         JS_free(m_Context, m_Data);
     1425        JS_ClearStructuredClone(m_Data, m_Size);
    13651426}
    13661427
    13671428shared_ptr<ScriptInterface::StructuredClone> ScriptInterface::WriteStructuredClone(jsval v)
    13681429{
    1369     uint64* data = NULL;
     1430    JSAutoRequest rq(m->m_cx);
     1431    uint64_t* data = NULL;
    13701432    size_t nbytes = 0;
    1371     if (!JS_WriteStructuredClone(m->m_cx, v, &data, &nbytes, NULL, NULL))
     1433    if (!JS_WriteStructuredClone(m->m_cx, v, &data, &nbytes, NULL, NULL, JSVAL_VOID))
    13721434    {
    13731435        debug_warn(L"Writing a structured clone with JS_WriteStructuredClone failed!");
    13741436        return shared_ptr<StructuredClone>();
    13751437    }
    13761438
    13771439    shared_ptr<StructuredClone> ret (new StructuredClone);
    1378     ret->m_Context = m->m_cx;
    13791440    ret->m_Data = data;
    13801441    ret->m_Size = nbytes;
    13811442    return ret;
     
    13831444
    13841445jsval ScriptInterface::ReadStructuredClone(const shared_ptr<ScriptInterface::StructuredClone>& ptr)
    13851446{
     1447    JSAutoRequest rq(m->m_cx);
    13861448    jsval ret = JSVAL_VOID;
    13871449    JS_ReadStructuredClone(m->m_cx, ptr->m_Data, ptr->m_Size, JS_STRUCTURED_CLONE_VERSION, &ret, NULL, NULL);
    13881450    return ret;
  • source/scriptinterface/AutoRooters.h

     
    2020
    2121#include "scriptinterface/ScriptTypes.h"
    2222
    23 #include "js/jsapi.h"
     23#include "jsapi.h"
    2424
    2525/**
    2626 * Helper for rooting large groups of script values.
  • 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