Upgrade to SpiderMonkey 1.8.5 (fixes #734)

This was SVN commit r9852.
This commit is contained in:
Ykkrosh 2011-07-16 23:24:14 +00:00
parent c7ba150c40
commit 2f0bd8d8b0
28 changed files with 267 additions and 93 deletions

View file

@ -190,13 +190,13 @@ extern_lib_defs = {
else
include_dir = "include-unix"
end
tinsert(package.config["Debug" ].includepaths, libraries_dir.."spidermonkey-tip/"..include_dir.."/debug")
tinsert(package.config["Testing"].includepaths, libraries_dir.."spidermonkey-tip/"..include_dir.."/debug")
tinsert(package.config["Release"].includepaths, libraries_dir.."spidermonkey-tip/"..include_dir.."/release")
tinsert(package.libpaths, libraries_dir.."spidermonkey-tip/lib")
tinsert(package.config["Debug" ].links, "mozjs-ps-debug")
tinsert(package.config["Testing"].links, "mozjs-ps-release")
tinsert(package.config["Release"].links, "mozjs-ps-release")
tinsert(package.config["Debug" ].includepaths, libraries_dir.."spidermonkey/"..include_dir)
tinsert(package.config["Testing"].includepaths, libraries_dir.."spidermonkey/"..include_dir)
tinsert(package.config["Release"].includepaths, libraries_dir.."spidermonkey/"..include_dir)
tinsert(package.libpaths, libraries_dir.."spidermonkey/lib")
tinsert(package.config["Debug" ].links, "mozjs185-ps-debug")
tinsert(package.config["Testing"].links, "mozjs185-ps-release")
tinsert(package.config["Release"].links, "mozjs185-ps-release")
end,
},
valgrind = {

View file

@ -485,22 +485,22 @@ extern_lib_defs = {
include_dir = "include-unix"
end
configuration "Debug"
includedirs { libraries_dir.."spidermonkey-tip/"..include_dir.."/debug" }
includedirs { libraries_dir.."spidermonkey/"..include_dir }
configuration "Testing"
includedirs { libraries_dir.."spidermonkey-tip/"..include_dir.."/debug" }
includedirs { libraries_dir.."spidermonkey/"..include_dir }
configuration "Release"
includedirs { libraries_dir.."spidermonkey-tip/"..include_dir.."/release" }
includedirs { libraries_dir.."spidermonkey/"..include_dir }
configuration { }
end,
link_settings = function()
configuration "Debug"
links { "mozjs-ps-debug" }
links { "mozjs185-ps-debug" }
configuration "Testing"
links { "mozjs-ps-debug" }
links { "mozjs185-ps-debug" }
configuration "Release"
links { "mozjs-ps-release" }
links { "mozjs185-ps-release" }
configuration { }
add_default_lib_paths("spidermonkey-tip")
add_default_lib_paths("spidermonkey")
end,
},
valgrind = {

View file

@ -50,7 +50,7 @@ echo
# Build/update bundled external libraries
(cd ../../libraries/fcollada/src && make ${JOBS}) || die "FCollada build failed"
echo
(cd ../../libraries/spidermonkey-tip && JOBS=${JOBS} ./build.sh) || die "SpiderMonkey build failed"
(cd ../../libraries/spidermonkey && JOBS=${JOBS} ./build.sh) || die "SpiderMonkey build failed"
echo
if [ "$with_system_nvtt" = "false" ]; then
(cd ../../libraries/nvtt && JOBS=${JOBS} ./build.sh) || die "NVTT build failed"

View file

@ -49,7 +49,7 @@ echo
# Build/update bundled external libraries
(cd ../../libraries/fcollada/src && make ${JOBS}) || die "FCollada build failed"
echo
(cd ../../libraries/spidermonkey-tip && JOBS=${JOBS} ./build.sh) || die "SpiderMonkey build failed"
(cd ../../libraries/spidermonkey && JOBS=${JOBS} ./build.sh) || die "SpiderMonkey build failed"
echo
if [ "$with_system_nvtt" = "false" ]; then
(cd ../../libraries/nvtt && JOBS=${JOBS} ./build.sh) || die "NVTT build failed"

View file

@ -325,7 +325,7 @@ static JSBool GetGlobalProperty(JSContext* cx, JSObject* UNUSED(obj), jsid id, j
return JS_GetPropertyById(cx, g_ScriptingHost.GetGlobalObject(), id, vp);
}
static JSBool SetGlobalProperty(JSContext* cx, JSObject* UNUSED(obj), jsid id, jsval* vp)
static JSBool SetGlobalProperty(JSContext* cx, JSObject* UNUSED(obj), jsid id, JSBool UNUSED(strict), jsval* vp)
{
return JS_SetPropertyById(cx, g_ScriptingHost.GetGlobalObject(), id, vp);
}
@ -376,7 +376,7 @@ static JSBool ResolveGlobalProperty(JSContext* cx, JSObject* obj, jsid id, uintN
static JSClass page_global_class = {
"page_global", JSCLASS_GLOBAL_FLAGS | JSCLASS_NEW_RESOLVE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, (JSResolveOp)ResolveGlobalProperty, JS_ConvertStub, JS_FinalizeStub,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL

View file

@ -146,7 +146,7 @@ class IGUIObject
// Allow getProperty to access things like GetParent()
friend JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
friend JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
friend JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool strict, jsval* vp);
public:
IGUIObject();

View file

@ -24,7 +24,7 @@
JSClass JSI_GUISize::JSI_class = {
"GUISize", 0,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub,
JS_ConvertStub, JS_FinalizeStub,
NULL, NULL, NULL, JSI_GUISize::construct
@ -137,7 +137,7 @@ JSBool JSI_GUISize::toString(JSContext* cx, uintN argc, jsval* vp)
JSClass JSI_GUIColor::JSI_class = {
"GUIColor", 0,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub,
JS_ConvertStub, JS_FinalizeStub,
NULL, NULL, NULL, JSI_GUIColor::construct
@ -214,7 +214,7 @@ JSBool JSI_GUIColor::toString(JSContext* cx, uintN argc, jsval* vp)
JSClass JSI_GUIMouse::JSI_class = {
"GUIMouse", 0,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub,
JS_ConvertStub, JS_FinalizeStub,
NULL, NULL, NULL, JSI_GUIMouse::construct

View file

@ -290,7 +290,7 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval*
}
}
JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool UNUSED(strict), jsval* vp)
{
IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, obj, &JSI_IGUIObject::JSI_class, NULL);
if (!e)

View file

@ -26,7 +26,7 @@ namespace JSI_IGUIObject
extern JSPropertySpec JSI_props[];
extern JSFunctionSpec JSI_methods[];
JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool strict, jsval* vp);
JSBool construct(JSContext* cx, uintN argc, jsval* vp);
JSBool toString(JSContext* cx, uintN argc, jsval* vp);
JSBool focus(JSContext* cx, uintN argc, jsval* vp);

View file

@ -125,7 +125,7 @@ JSBool JSI_Vector3D::getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* v
return JS_FALSE;
}
JSBool JSI_Vector3D::setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
JSBool JSI_Vector3D::setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool UNUSED(strict), jsval* vp)
{
if (!JSID_IS_INT(id))
return JS_TRUE;

View file

@ -57,7 +57,7 @@ namespace JSI_Vector3D
extern JSFunctionSpec JSI_methods[];
JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool strict, jsval* vp);
void finalize(JSContext* cx, JSObject* obj);
JSBool construct(JSContext* cx, uintN argc, jsval* vp);
void init();

View file

@ -60,7 +60,7 @@ namespace ConfigNamespace_JS
return JS_TRUE;
}
JSBool SetProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp)
JSBool SetProperty(JSContext* cx, JSObject* obj, jsid id, JSBool UNUSED(strict), jsval* vp)
{
EConfigNamespace cfgNs = GET_NS_PRIVATE(cx, obj);
if (cfgNs < 0 || cfgNs >= CFG_LAST)
@ -169,7 +169,7 @@ namespace ConfigDB_JS
JSClass Class = {
"ConfigDB", 0,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub,
JS_ConvertStub, JS_FinalizeStub
};

View file

@ -62,7 +62,7 @@ JSBool JSI_Console::getProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), js
}
}
JSBool JSI_Console::setProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid id, jsval* vp)
JSBool JSI_Console::setProperty(JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsid id, JSBool UNUSED(strict), jsval* vp)
{
if (!JSID_IS_INT(id))
return JS_TRUE;

View file

@ -35,7 +35,7 @@ namespace JSI_Console
extern JSFunctionSpec JSI_methods[];
JSBool getProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, jsval* vp);
JSBool setProperty(JSContext* cx, JSObject* obj, jsid id, JSBool strict, jsval* vp);
JSBool getConsole(JSContext* context, JSObject* obj, jsid id, jsval* vp);

View file

@ -407,7 +407,7 @@ private:
return( JS_TRUE );
}
static JSBool JSSetProperty( JSContext* cx, JSObject* obj, jsid id, jsval* vp )
static JSBool JSSetProperty( JSContext* cx, JSObject* obj, jsid id, JSBool UNUSED(strict), jsval* vp )
{
T* Instance = ToNative<T>( cx, obj );
if( !Instance )

View file

@ -208,7 +208,10 @@ CStrW ScriptingHost::ValueToUCString( const jsval value )
if (string == NULL)
throw PSERROR_Scripting_ConversionFailed();
jschar *strptr=JS_GetStringChars(string);
size_t length=JS_GetStringLength(string);
size_t length;
const jschar *strptr = JS_GetStringCharsAndLength(m_Context, string, &length);
if (!strptr)
throw PSERROR_Scripting_ConversionFailed();
return std::wstring(strptr, strptr+length);
}

View file

@ -72,11 +72,18 @@ struct ScriptInterface_NativeMethodWrapper<void, TC> {
};
// Fast natives don't trigger the hook we use for profiling, so explicitly
// notify the profiler when these functions are being called
// notify the profiler when these functions are being called.
// ScriptInterface_impl::Register stores the name in a reserved slot.
// (TODO: this doesn't work for functions registered via InterfaceScripted.h.
// Maybe we should do some interned JS_GetFunctionId thing.)
#if ENABLE_SCRIPT_PROFILING
#define SCRIPT_PROFILE \
ENSURE(JSVAL_IS_OBJECT(JS_CALLEE(cx, vp)) && JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)))); \
const char* name = JS_GetFunctionName(JS_ValueToFunction(cx, JS_CALLEE(cx, vp))); /* native function so ValueToFunction is safe; this makes unsafe lifetime assumptions */ \
const char* name = "(unknown)"; \
jsval nameval; \
if (JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0, &nameval) \
&& !JSVAL_IS_VOID(nameval)) \
name = static_cast<const char*>(JSVAL_TO_PRIVATE(nameval)); \
CProfileSampleScript profile(name);
#else
#define SCRIPT_PROFILE

View file

@ -23,12 +23,7 @@
#include "ps/utf16string.h"
#include "ps/CLogger.h"
#include "ps/CStr.h"
#include "js/jsapi.h"
#define signbit std::signbit
#include "js/jstypedarray.h"
#undef signbit
#include "scriptinterface/ScriptExtraHeaders.h" // for typed arrays
#define FAIL(msg) STMT(JS_ReportError(cx, msg); return false)
@ -114,8 +109,11 @@ template<> bool ScriptInterface::FromJSVal<std::wstring>(JSContext* cx, jsval v,
JSString* ret = JS_ValueToString(cx, v);
if (!ret)
FAIL("Argument must be convertible to a string");
jschar* ch = JS_GetStringChars(ret);
out = std::wstring(ch, ch + JS_GetStringLength(ret));
size_t length;
const jschar* ch = JS_GetStringCharsAndLength(cx, ret, &length);
if (!ch)
FAIL("JS_GetStringsCharsAndLength failed"); // out of memory
out = std::wstring(ch, ch + length);
return true;
}

View file

@ -0,0 +1,53 @@
/* Copyright (C) 2011 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_SCRIPTEXTRAHEADERS
#define INCLUDED_SCRIPTEXTRAHEADERS
// Includes occasionally-used SpiderMonkey headers for typed arrays and debug API,
// with appropriate tweaks to fix warnings and build errors. (Most code should
// just include ScriptTypes.h directly to get the standard jsapi.h.)
#include "scriptinterface/ScriptTypes.h"
// Ignore some harmless warnings
#if GCC_VERSION >= 402 // (older GCCs don't support this pragma)
# pragma GCC diagnostic ignored "-Wunused-parameter"
# pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
#if MSC_VERSION
# pragma warning(push)
# pragma warning(disable:4800) // "forcing value to bool 'true' or 'false' (performance warning)"
#endif
// Redefine signbit to fix build error in GCC
#define signbit std::signbit
#include "js/jstypedarray.h"
#include "js/jsdbgapi.h"
#undef signbit
#if MSC_VERSION
# pragma warning(pop)
#endif
#if GCC_VERSION >= 402
# pragma GCC diagnostic ignored "-Wunused-parameter"
# pragma GCC diagnostic warning "-Wredundant-decls"
#endif
#endif // INCLUDED_SCRIPTEXTRAHEADERS

View file

@ -45,11 +45,7 @@
#define STACK_CHUNK_SIZE 8192
#if ENABLE_SCRIPT_PROFILING
# define signbit std::signbit
# include "js/jsdbgapi.h"
# undef signbit
#endif
#include "scriptinterface/ScriptExtraHeaders.h"
////////////////////////////////////////////////////////////////
@ -57,7 +53,7 @@ class ScriptRuntime
{
public:
ScriptRuntime(int runtimeSize) :
m_rooter(NULL)
m_rooter(NULL), m_compartmentGlobal(NULL)
{
m_rt = JS_NewRuntime(runtimeSize);
ENSURE(m_rt); // TODO: error handling
@ -85,6 +81,8 @@ public:
JSRuntime* m_rt;
AutoGCRooter* m_rooter;
JSObject* m_compartmentGlobal;
private:
#if ENABLE_SCRIPT_PROFILING
@ -227,6 +225,7 @@ struct ScriptInterface_impl
JSContext* m_cx;
JSObject* m_glob; // global scope object
JSObject* m_nativeScope; // native function scope object
JSCrossCompartmentCall* m_call;
};
namespace
@ -234,7 +233,7 @@ namespace
JSClass global_class = {
"global", JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL
@ -265,6 +264,10 @@ void ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report)
{
// TODO: this violates the docs ("The error reporter callback must not reenter the JSAPI.")
// Hide the exception from EvaluateScript
JSExceptionState* excnState = JS_SaveExceptionState(cx);
JS_ClearPendingException(cx);
jsval rval;
const char dumpStack[] = "this.stack.trimRight().replace(/^/mg, ' ')"; // indent each line
if (JS_EvaluateScript(cx, JSVAL_TO_OBJECT(excn), dumpStack, ARRAY_SIZE(dumpStack)-1, "(eval)", 1, &rval))
@ -272,6 +275,13 @@ void ErrorReporter(JSContext* cx, const char* message, JSErrorReport* report)
std::string stackTrace;
if (ScriptInterface::FromJSVal(cx, rval, stackTrace))
msg << "\n" << stackTrace;
JS_RestoreExceptionState(cx, excnState);
}
else
{
// Error got replaced by new exception from EvaluateScript
JS_DropExceptionState(cx, excnState);
}
}
@ -357,7 +367,15 @@ JSBool deepcopy(JSContext* cx, uintN argc, jsval* vp)
}
jsval ret;
if (!JS_StructuredClone(cx, JS_ARGV(cx, vp)[0], &ret))
// We'd usually do:
// if (!JS_StructuredClone(cx, JS_ARGV(cx, vp)[0], &ret, NULL, NULL))
// return JS_FALSE;
// but that function is broken in the 1.8.5 release
// (https://bugzilla.mozilla.org/show_bug.cgi?id=651510)
// so do an equivalent operation with a different API:
JSAutoStructuredCloneBuffer buf;
if (!buf.write(cx, JS_ARGV(cx, vp)[0]) || !buf.read(&ret, cx))
return JS_FALSE;
JS_SET_RVAL(cx, vp, ret);
@ -463,7 +481,19 @@ ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const sh
// Threadsafe SpiderMonkey requires that we have a request before doing anything much
JS_BeginRequest(m_cx);
m_glob = JS_NewGlobalObject(m_cx, &global_class);
// We only want a single compartment per runtime
if (m_runtime->m_compartmentGlobal)
{
m_call = JS_EnterCrossCompartmentCall(m_cx, m_runtime->m_compartmentGlobal);
m_glob = JS_NewGlobalObject(m_cx, &global_class);
}
else
{
m_call = NULL;
m_glob = JS_NewCompartmentAndGlobalObject(m_cx, &global_class, NULL);
m_runtime->m_compartmentGlobal = m_glob;
}
ok = JS_InitStandardClasses(m_cx, m_glob);
ENSURE(ok);
@ -485,13 +515,33 @@ ScriptInterface_impl::ScriptInterface_impl(const char* nativeScopeName, const sh
ScriptInterface_impl::~ScriptInterface_impl()
{
if (m_call)
JS_LeaveCrossCompartmentCall(m_call);
JS_EndRequest(m_cx);
JS_DestroyContext(m_cx);
}
void ScriptInterface_impl::Register(const char* name, JSNative fptr, uintN nargs)
{
JS_DefineFunction(m_cx, m_nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
JSFunction* func = JS_DefineFunction(m_cx, m_nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
if (!func)
return;
#if ENABLE_SCRIPT_PROFILING
// Store the function name in a slot, so we can pass it to the profiler.
// Use a flyweight std::string because we can't assume the caller has
// a correctly-aligned string and that its lifetime is long enough
typedef boost::flyweight<
std::string,
boost::flyweights::no_tracking
// can't use no_locking; Register might be called in threads
> LockedStringFlyweight;
LockedStringFlyweight fw(name);
JS_SetReservedSlot(m_cx, JS_GetFunctionObject(func), 0, PRIVATE_TO_JSVAL((void*)fw.get().c_str()));
#endif
}
ScriptInterface::ScriptInterface(const char* nativeScopeName, const char* debugName, const shared_ptr<ScriptRuntime>& runtime) :
@ -762,9 +812,9 @@ bool ScriptInterface::EnumeratePropertyNamesWithPrefix(jsval obj, const char* pr
continue; // ignore integer properties
JSString* name = JSVAL_TO_STRING(val);
size_t len = JS_GetStringLength(name);
jschar* chars = JS_GetStringChars(name);
if (len >= prefix16.size() && memcmp(chars, prefix16.c_str(), prefix16.size()*2) == 0)
size_t len;
const jschar* chars = JS_GetStringCharsAndLength(m->m_cx, name, &len);
if (chars && len >= prefix16.size() && memcmp(chars, prefix16.c_str(), prefix16.size()*2) == 0)
out.push_back(std::string(chars, chars+len)); // handles Unicode poorly
}
@ -1102,7 +1152,10 @@ private:
if (JSVAL_IS_STRING(val))
{
JSString* str = JS_NewUCStringCopyN(cxTo, JS_GetStringChars(JSVAL_TO_STRING(val)), JS_GetStringLength(JSVAL_TO_STRING(val)));
size_t len;
const jschar* chars = JS_GetStringCharsAndLength(cxFrom, JSVAL_TO_STRING(val), &len);
CLONE_REQUIRE(chars, L"JS_GetStringCharsAndLength");
JSString* str = JS_NewUCStringCopyN(cxTo, chars, len);
CLONE_REQUIRE(str, L"JS_NewUCStringCopyN");
jsval rval = STRING_TO_JSVAL(str);
m_Mapping[JSVAL_TO_GCTHING(val)] = rval;
@ -1153,7 +1206,10 @@ private:
// string jsids are runtime-specific, so we need to copy the string content
JSString* idstr = JS_ValueToString(cxFrom, idval);
CLONE_REQUIRE(idstr, L"JS_ValueToString (id)");
CLONE_REQUIRE(JS_SetUCProperty(cxTo, newObj, JS_GetStringChars(idstr), JS_GetStringLength(idstr), &newPropval), L"JS_SetUCProperty");
size_t len;
const jschar* chars = JS_GetStringCharsAndLength(cxFrom, idstr, &len);
CLONE_REQUIRE(idstr, L"JS_GetStringCharsAndLength (id)");
CLONE_REQUIRE(JS_SetUCProperty(cxTo, newObj, chars, len, &newPropval), L"JS_SetUCProperty");
}
else
{
@ -1195,7 +1251,7 @@ shared_ptr<ScriptInterface::StructuredClone> ScriptInterface::WriteStructuredClo
{
uint64* data = NULL;
size_t nbytes = 0;
if (!JS_WriteStructuredClone(m->m_cx, v, &data, &nbytes))
if (!JS_WriteStructuredClone(m->m_cx, v, &data, &nbytes, NULL, NULL))
return shared_ptr<StructuredClone>();
// TODO: should we have better error handling?
// Currently we'll probably continue and then crash in ReadStructuredClone
@ -1210,6 +1266,6 @@ shared_ptr<ScriptInterface::StructuredClone> ScriptInterface::WriteStructuredClo
jsval ScriptInterface::ReadStructuredClone(const shared_ptr<ScriptInterface::StructuredClone>& ptr)
{
jsval ret = JSVAL_VOID;
JS_ReadStructuredClone(m->m_cx, ptr->m_Data, ptr->m_Size, &ret);
JS_ReadStructuredClone(m->m_cx, ptr->m_Data, ptr->m_Size, JS_STRUCTURED_CLONE_VERSION, &ret, NULL, NULL);
return ret;
}

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2010 Wildfire Games.
/* Copyright (C) 2011 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -47,8 +47,27 @@
# endif
#endif
// Ignore some harmless warnings triggered by jsapi.h
#if GCC_VERSION >= 402 // (older GCCs don't support this pragma)
# pragma GCC diagnostic ignored "-Wunused-parameter"
# pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
#if MSC_VERSION
# pragma warning(push)
# pragma warning(disable:4480) // "nonstandard extension used: specifying underlying type for enum"
# pragma warning(disable:4100) // "unreferenced formal parameter"
#endif
#include "js/jsapi.h"
#if MSC_VERSION
# pragma warning(pop)
#endif
#if GCC_VERSION >= 402
# pragma GCC diagnostic warning "-Wunused-parameter"
# pragma GCC diagnostic warning "-Wredundant-decls"
#endif
#if JS_VERSION != 185
#error Your compiler is trying to use an incorrect version of the SpiderMonkey library.
#error The only version that works is the one in the libraries/spidermonkey-tip/ directory,

View file

@ -90,6 +90,7 @@ private:
{
// Clean up rooted objects before destroying their script context
m_Obj = CScriptValRooted();
m_Commands.clear();
}
static void IncludeModule(void* cbdata, std::wstring name)
@ -270,6 +271,8 @@ public:
m_EntityTemplates = CScriptValRooted();
m_PlayerMetadata.clear();
m_Players.clear();
m_GameState.reset();
m_GameStateMapVal = CScriptValRooted();
}
bool AddPlayer(const std::wstring& aiName, player_id_t player, bool callConstructor)

View file

@ -18,6 +18,7 @@
#include "precompiled.h"
#include "scriptinterface/ScriptInterface.h"
#include "scriptinterface/ScriptExtraHeaders.h" // for typed arrays
#include "maths/Fixed.h"
#include "maths/FixedVector2D.h"
@ -29,12 +30,6 @@
#include "simulation2/system/IComponent.h"
#include "simulation2/system/ParamNode.h"
#include "js/jsapi.h"
#define signbit std::signbit
#include "js/jstypedarray.h"
#undef signbit
#define FAIL(msg) STMT(JS_ReportError(cx, msg); return false)
template<> jsval ScriptInterface::ToJSVal<IComponent*>(JSContext* cx, IComponent* const& val)

View file

@ -25,10 +25,7 @@
#include "ps/CLogger.h"
#include "scriptinterface/ScriptInterface.h"
#define signbit std::signbit
#include "js/jsvalue.h" // for JSDOUBLE_IS_INT32
#undef signbit
#include "scriptinterface/ScriptExtraHeaders.h" // for JSDOUBLE_IS_INT32
CBinarySerializerScriptImpl::CBinarySerializerScriptImpl(ScriptInterface& scriptInterface, ISerializer& serializer) :
m_ScriptInterface(scriptInterface), m_Serializer(serializer), m_Rooter(m_ScriptInterface),
@ -188,8 +185,12 @@ void CBinarySerializerScriptImpl::HandleScriptVal(jsval val)
void CBinarySerializerScriptImpl::ScriptString(const char* name, JSString* string)
{
jschar* chars = JS_GetStringChars(string);
size_t length = JS_GetStringLength(string);
JSContext* cx = m_ScriptInterface.GetContext();
size_t length;
const jschar* chars = JS_GetStringCharsAndLength(cx, string, &length);
if (!chars)
throw PSERROR_Serialize_ScriptError("JS_GetStringCharsAndLength failed");
#if BYTE_ORDER != LITTLE_ENDIAN
#error TODO: probably need to convert JS strings to little-endian

View file

@ -24,7 +24,7 @@
#define BEGIN_INTERFACE_WRAPPER(iname) \
JSClass class_ICmp##iname = { \
"ICmp" #iname, JSCLASS_HAS_PRIVATE, \
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, \
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, \
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, \
JSCLASS_NO_OPTIONAL_MEMBERS \
}; \

View file

@ -71,7 +71,7 @@ static AtSmartPtr<AtNode> ConvertNode(JSContext* cx, jsval node)
if (!str)
return obj; // error
size_t valueLen;
const jschar* valueChars = JS_GetStringCharsAndLength(str, &valueLen);
const jschar* valueChars = JS_GetStringCharsAndLength(cx, str, &valueLen);
if (!valueChars)
return obj; // error
wxString valueWx(reinterpret_cast<const char*>(valueChars), wxMBConvUTF16(), valueLen*2);
@ -111,9 +111,9 @@ static AtSmartPtr<AtNode> ConvertNode(JSContext* cx, jsval node)
continue; // ignore integer properties
JSString* name = JSVAL_TO_STRING(val);
size_t len = JS_GetStringLength(name);
jschar* chars = JS_GetStringChars(name);
wxString nameWx(reinterpret_cast<char*>(chars), wxMBConvUTF16(), len*2);
size_t len;
const jschar* chars = JS_GetStringCharsAndLength(cx, name, &len);
wxString nameWx(reinterpret_cast<const char*>(chars), wxMBConvUTF16(), len*2);
std::string nameStr(nameWx.ToUTF8().data());
jsval vp;

View file

@ -23,12 +23,6 @@
# include <cxxabi.h>
#endif
#include "js/jsapi.h"
#ifdef _WIN32
# pragma warning(disable: 4996) // avoid complaints about deprecated localtime
#endif
#include "wx/wx.h"
#include "GameInterface/Shareable.h"
@ -143,8 +137,11 @@ namespace
JSString* ret = JS_ValueToString(cx, v);
if (! ret)
FAIL("Argument must be convertible to a string");
jschar* ch = JS_GetStringChars(ret);
out = std::wstring(ch, ch+JS_GetStringLength(ret));
size_t len;
const jschar* ch = JS_GetStringCharsAndLength(cx, ret, &len);
if (! ch)
FAIL("JS_GetStringsCharsAndLength failed"); // probably out of memory
out = std::wstring(ch, ch + len);
return true;
}
};
@ -156,10 +153,13 @@ namespace
JSString* ret = JS_ValueToString(cx, v);
if (! ret)
FAIL("Argument must be convertible to a string");
size_t len = JS_GetStringEncodingLength(cx, ret);
if (len == (size_t)-1)
FAIL("JS_GetStringEncodingLength failed");
char* ch = JS_EncodeString(cx, ret); // chops off high byte of each jschar
if (! ch)
FAIL("JS_EncodeString failed"); // out of memory
out = std::string(ch, ch + JS_GetStringLength(ret));
FAIL("JS_EncodeString failed"); // probably out of memory
out = std::string(ch, ch + len);
JS_free(cx, ch);
return true;
}
@ -170,10 +170,13 @@ namespace
static bool Convert(JSContext* cx, jsval v, wxString& out)
{
JSString* ret = JS_ValueToString(cx, v);
size_t len;
if (! ret)
FAIL("Argument must be convertible to a string");
jschar* ch = JS_GetStringChars(ret);
out = wxString((const char*)ch, wxMBConvUTF16(), (size_t)(JS_GetStringLength(ret)*2));
const jschar* ch = JS_GetStringCharsAndLength(cx, ret, &len);
if (! ch)
FAIL("JS_GetStringsCharsAndLength failed"); // probably out of memory
out = wxString((const char*)ch, wxMBConvUTF16(), len*2);
return true;
}
};
@ -371,7 +374,7 @@ namespace
{
JSClass global_class = {
"global", JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL
@ -416,9 +419,14 @@ namespace
JSString* code = JSVAL_TO_STRING(JS_ARGV(cx, vp)[1]);
size_t len;
const jschar* ch = JS_GetStringCharsAndLength(cx, code, &len);
if (!ch)
return JS_FALSE;
jsval rval = JSVAL_VOID;
if (!AtlasScriptInterface_impl::LoadScript(cx,
JS_GetStringChars(code), (uintN)JS_GetStringLength(code),
ch, (uintN)len,
name.c_str(), &rval))
return JS_FALSE;
@ -465,7 +473,7 @@ AtlasScriptInterface_impl::AtlasScriptInterface_impl()
JS_SetVersion(m_cx, JSVERSION_LATEST);
m_glob = JS_NewGlobalObject(m_cx, &global_class);
m_glob = JS_NewCompartmentAndGlobalObject(m_cx, &global_class, NULL);
JS_InitStandardClasses(m_cx, m_glob);
JS_DefineProperty(m_cx, m_glob, "global", OBJECT_TO_JSVAL(m_glob), NULL, NULL, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT);

View file

@ -31,8 +31,39 @@
# define XP_UNIX
#endif // (we don't support XP_OS2 or XP_BEOS)
#ifdef __GNUC__
# define GCC_VERSION (__GNUC__*100 + __GNUC_MINOR__)
#else
# define GCC_VERSION 0
#endif
#ifdef _MSC_VER
# define MSC_VERSION _MSC_VER
#else
# define MSC_VERSION 0
#endif
// Ignore some harmless warnings triggered by jsapi.h
#if GCC_VERSION >= 402 // (older GCCs don't support this pragma)
# pragma GCC diagnostic ignored "-Wunused-parameter"
# pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
#if MSC_VERSION
# pragma warning(push)
# pragma warning(disable:4480) // "nonstandard extension used: specifying underlying type for enum"
# pragma warning(disable:4100) // "unreferenced formal parameter"
#endif
#include "js/jsapi.h"
#if MSC_VERSION
# pragma warning(pop)
#endif
#if GCC_VERSION >= 402
# pragma GCC diagnostic warning "-Wunused-parameter"
# pragma GCC diagnostic warning "-Wredundant-decls"
#endif
class wxString;
namespace AtlasMessage { struct mWorldCommand; }