mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-08-15 14:43:32 -07:00
parent
c7ba150c40
commit
2f0bd8d8b0
28 changed files with 267 additions and 93 deletions
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
53
source/scriptinterface/ScriptExtraHeaders.h
Normal file
53
source/scriptinterface/ScriptExtraHeaders.h
Normal 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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
}; \
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue