18 #include "precompiled.h"
35 #define BOOST_MULTI_INDEX_DISABLE_SERIALIZATION
36 #include <boost/preprocessor/punctuation/comma_if.hpp>
37 #include <boost/preprocessor/repetition/repeat.hpp>
38 #include <boost/random/linear_congruential.hpp>
39 #include <boost/flyweight.hpp>
40 #include <boost/flyweight/key_value.hpp>
41 #include <boost/flyweight/no_locking.hpp>
42 #include <boost/flyweight/no_tracking.hpp>
46 #define STACK_CHUNK_SIZE 8192
74 m_rt = JS_NewRuntime(runtimeSize);
95 JS_DestroyRuntime(
m_rt);
137 std::size_t seed = 0;
138 boost::hash_combine(seed, loc.
cx);
139 boost::hash_combine(seed, loc.
script);
140 boost::hash_combine(seed, loc.
pc);
150 JSContext* cx = loc.
cx;
151 JSScript* script = loc.
script;
152 jsbytecode* pc = loc.
pc;
154 std::string filename = JS_GetScriptFilename(cx, script);
155 size_t slash = filename.rfind(
'/');
156 if (slash != filename.npos)
157 filename = filename.substr(slash+1);
159 uintN line = JS_PCToLineNumber(cx, script, pc);
161 std::stringstream ss;
162 ss <<
"(" << filename <<
":" << line <<
")";
172 typedef boost::flyweight<
174 boost::flyweights::no_tracking,
175 boost::flyweights::no_locking
177 typedef boost::flyweight<
178 boost::flyweights::key_value<ScriptLocation, ScriptLocationName>,
179 boost::flyweights::no_tracking,
180 boost::flyweights::no_locking
191 JSFunction* fn = JS_GetFrameFunction(cx, fp);
199 JSString* name = JS_GetFunctionId(fn);
202 char* chars = JS_EncodeString(cx, name);
212 ScriptLocation loc = { cx, JS_GetFrameScript(cx, fp), JS_GetFramePC(cx, fp) };
229 return shared_ptr<ScriptRuntime>(
new ScriptRuntime(runtimeSize));
238 void Register(
const char* name, JSNative fptr, uintN nargs);
251 "global", JSCLASS_GLOBAL_FLAGS,
252 JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
253 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
254 NULL, NULL, NULL, NULL,
255 NULL, NULL, NULL, NULL
258 void ErrorReporter(JSContext* cx,
const char* message, JSErrorReport* report)
263 if (report->flags == 5 && report->lineno == 0 && report->errorNumber == 163)
266 std::stringstream msg;
267 bool isWarning = JSREPORT_IS_WARNING(report->flags);
268 msg << (isWarning ?
"JavaScript warning: " :
"JavaScript error: ");
269 if (report->filename)
271 msg << report->filename;
272 msg <<
" line " << report->lineno <<
"\n";
279 if (JS_GetPendingException(cx, &excn) && JSVAL_IS_OBJECT(excn))
284 JSExceptionState* excnState = JS_SaveExceptionState(cx);
285 JS_ClearPendingException(cx);
288 const char dumpStack[] =
"this.stack.trimRight().replace(/^/mg, ' ')";
289 if (JS_EvaluateScript(cx, JSVAL_TO_OBJECT(excn), dumpStack,
ARRAY_SIZE(dumpStack)-1,
"(eval)", 1, &rval))
291 std::string stackTrace;
293 msg <<
"\n" << stackTrace;
295 JS_RestoreExceptionState(cx, excnState);
300 JS_DropExceptionState(cx, excnState);
307 LOGERROR(L
"%hs", msg.str().c_str());
315 JSBool
print(JSContext* cx, uintN argc, jsval* vp)
317 for (uintN i = 0; i < argc; ++i)
325 JS_SET_RVAL(cx, vp, JSVAL_VOID);
329 JSBool
logmsg(JSContext* cx, uintN argc, jsval* vp)
333 JS_SET_RVAL(cx, vp, JSVAL_VOID);
341 JS_SET_RVAL(cx, vp, JSVAL_VOID);
345 JSBool
warn(JSContext* cx, uintN argc, jsval* vp)
349 JS_SET_RVAL(cx, vp, JSVAL_VOID);
357 JS_SET_RVAL(cx, vp, JSVAL_VOID);
361 JSBool
error(JSContext* cx, uintN argc, jsval* vp)
365 JS_SET_RVAL(cx, vp, JSVAL_VOID);
373 JS_SET_RVAL(cx, vp, JSVAL_VOID);
377 JSBool
deepcopy(JSContext* cx, uintN argc, jsval* vp)
381 JS_SET_RVAL(cx, vp, JSVAL_VOID);
393 JSAutoStructuredCloneBuffer buf;
394 if (!buf.write(cx, JS_ARGV(cx, vp)[0]) || !buf.read(&ret, cx))
397 JS_SET_RVAL(cx, vp, ret);
403 const char* name =
"(ProfileStart)";
411 typedef boost::flyweight<
413 boost::flyweights::no_tracking,
414 boost::flyweights::no_locking
417 name = StringFlyweight(str).get().c_str();
425 JS_SET_RVAL(cx, vp, JSVAL_VOID);
436 JS_SET_RVAL(cx, vp, JSVAL_VOID);
449 double n = (double)(
rng() - rng.min());
450 double d = (double)(rng.max() - rng.min()) + 1.0;
451 ENSURE(d > 0 && n >= 0 && n <= d);
452 double r = n / d * (max - min) + min;
462 if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0, &rngp))
464 boost::rand48*
rng =
static_cast<boost::rand48*
>(JSVAL_TO_PRIVATE(rngp));
469 if (!JS_NewNumberValue(cx, r, &rv))
471 JS_SET_RVAL(cx, vp, rv);
488 JS_SetContextPrivate(
m_cx, NULL);
493 options |= JSOPTION_STRICT;
494 options |= JSOPTION_XML;
495 options |= JSOPTION_VAROBJFIX;
502 options |= JSOPTION_METHODJIT;
505 options |= JSOPTION_JIT;
506 options |= JSOPTION_PROFILING;
509 JS_SetOptions(
m_cx, options);
511 JS_SetVersion(
m_cx, JSVERSION_LATEST);
514 JS_BeginRequest(
m_cx);
520 m_glob = JS_NewGlobalObject(
m_cx, &global_class);
525 m_glob = JS_NewCompartmentAndGlobalObject(
m_cx, &global_class, NULL);
532 JS_DefineProperty(
m_cx,
m_glob,
"global", OBJECT_TO_JSVAL(
m_glob), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY
538 JS_DefineFunction(
m_cx,
m_glob,
"print", ::
print, 0, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
539 JS_DefineFunction(
m_cx,
m_glob,
"log", ::
logmsg, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
540 JS_DefineFunction(
m_cx,
m_glob,
"warn", ::
warn, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
541 JS_DefineFunction(
m_cx,
m_glob,
"error", ::
error, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
542 JS_DefineFunction(
m_cx,
m_glob,
"deepcopy", ::
deepcopy, 1, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
551 JS_LeaveCrossCompartmentCall(
m_call);
553 JS_DestroyContext(
m_cx);
558 JSFunction* func = JS_DefineFunction(
m_cx,
m_nativeScope, name, fptr, nargs, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
569 typedef boost::flyweight<
571 boost::flyweights::no_tracking
573 > LockedStringFlyweight;
575 LockedStringFlyweight fw(name);
576 JS_SetReservedSlot(
m_cx, JS_GetFunctionObject(func), 0, PRIVATE_TO_JSVAL((
void*)fw.get().c_str()));
593 LOGERROR(L
"Failed to set Spidermonkey to debug mode!");
619 JS_SetContextPrivate(
m->m_cx, cbdata);
624 return JS_GetContextPrivate(cx);
636 for (VfsPaths::iterator it = pathnames.begin(); it != pathnames.end(); ++it)
640 LOGERROR(L
"LoadGlobalScripts: Failed to load script %ls", it->string().c_str());
651 if (JS_GetProperty(
m->m_cx,
m->m_glob,
"Math", &math) && JSVAL_IS_OBJECT(math))
653 JSFunction* random = JS_DefineFunction(
m->m_cx, JSVAL_TO_OBJECT(math),
"random",
Math_random, 0,
654 JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
658 if (JS_SetReservedSlot(
m->m_cx, JS_GetFunctionObject(random), 0, PRIVATE_TO_JSVAL(&rng)))
663 LOGERROR(L
"ReplaceNondeterministicRNG: failed to replace Math.random");
669 m->Register(name, fptr, (uintN)nargs);
679 return m->m_runtime->m_rt;
685 m->m_runtime->m_rooter = rooter;
692 if (!JSVAL_IS_OBJECT(ctor))
694 LOGERROR(L
"CallConstructor: ctor is not an object");
698 return OBJECT_TO_JSVAL(JS_New(
m->m_cx, JSVAL_TO_OBJECT(ctor), 1, &arg));
706 if (!JS_GetProperty(
m->m_cx, JSVAL_TO_OBJECT(ctor),
"prototype", &protoVal))
708 LOGERROR(L
"NewObjectFromConstructor: can't get prototype");
712 if (!JSVAL_IS_OBJECT(protoVal))
714 LOGERROR(L
"NewObjectFromConstructor: prototype is not an object");
718 JSObject* proto = JSVAL_TO_OBJECT(protoVal);
719 JSObject* parent = JS_GetParent(
m->m_cx, JSVAL_TO_OBJECT(ctor));
721 if (!proto || !parent)
723 LOGERROR(L
"NewObjectFromConstructor: null proto/parent");
727 JSObject* obj = JS_NewObject(
m->m_cx, NULL, proto, parent);
730 LOGERROR(L
"NewObjectFromConstructor: object creation failed");
734 return OBJECT_TO_JSVAL(obj);
746 if (!JS_ValueToObject(
m->m_cx, val, &obj) || obj == NULL)
752 if (!JS_HasProperty(
m->m_cx, obj, name, &found) || !found)
755 JSBool ok = JS_CallFunctionName(
m->m_cx, obj, name, (uintN)argc, argv, &ret);
757 return ok ?
true :
false;
762 return OBJECT_TO_JSVAL(JS_GetGlobalObject(
m->m_cx));
775 if (!JS_HasProperty(
m->m_cx,
m->m_glob, name, &found))
779 JS_ReportError(
m->m_cx,
"SetGlobal \"%s\" called multiple times", name);
784 JSBool ok = JS_DefineProperty(
m->m_cx,
m->m_glob, name, value, NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY
786 return ok ?
true :
false;
793 attrs |= JSPROP_READONLY | JSPROP_PERMANENT;
795 attrs |= JSPROP_ENUMERATE;
797 if (! JSVAL_IS_OBJECT(obj))
799 JSObject*
object = JSVAL_TO_OBJECT(obj);
801 if (! JS_DefineProperty(
m->m_cx,
object, name, value, NULL, NULL, attrs))
810 attrs |= JSPROP_READONLY | JSPROP_PERMANENT;
812 attrs |= JSPROP_ENUMERATE;
814 if (! JSVAL_IS_OBJECT(obj))
816 JSObject*
object = JSVAL_TO_OBJECT(obj);
818 if (! JS_DefinePropertyById(
m->m_cx,
object, INT_TO_JSID(name), value, NULL, NULL, attrs))
825 if (! JSVAL_IS_OBJECT(obj))
827 JSObject*
object = JSVAL_TO_OBJECT(obj);
829 if (!JS_GetProperty(
m->m_cx,
object, name, &out))
836 if (! JSVAL_IS_OBJECT(obj))
838 JSObject*
object = JSVAL_TO_OBJECT(obj);
840 if (!JS_GetPropertyById(
m->m_cx,
object, INT_TO_JSID(name), &out))
847 if (! JSVAL_IS_OBJECT(obj))
849 JSObject*
object = JSVAL_TO_OBJECT(obj);
852 if (!JS_HasProperty(
m->m_cx,
object, name, &found))
854 return (found != JS_FALSE);
859 utf16string prefix16 (prefix, prefix+strlen(prefix));
861 if (! JSVAL_IS_OBJECT(obj))
864 JSObject* it = JS_NewPropertyIterator(
m->m_cx, JSVAL_TO_OBJECT(obj));
872 if (! JS_NextProperty(
m->m_cx, it, &idp) || ! JS_IdToValue(
m->m_cx, idp, &val))
874 if (val == JSVAL_VOID)
876 if (! JSVAL_IS_STRING(val))
879 JSString* name = JSVAL_TO_STRING(val);
881 const jschar* chars = JS_GetStringCharsAndLength(
m->m_cx, name, &len);
882 if (chars && len >= prefix16.size() && memcmp(chars, prefix16.c_str(), prefix16.size()*2) == 0)
883 out.push_back(std::string(chars, chars+len));
887 JSObject* prototype = JS_GetPrototype(
m->m_cx, JSVAL_TO_OBJECT(obj));
899 if (!JSVAL_IS_OBJECT(obj) || !JSVAL_IS_OBJECT(proto))
901 return JS_SetPrototype(
m->m_cx, JSVAL_TO_OBJECT(obj), JSVAL_TO_OBJECT(proto)) ?
true :
false;
906 if (!JSVAL_IS_OBJECT(obj))
910 return JS_DeepFreezeObject(
m->m_cx, JSVAL_TO_OBJECT(obj)) ?
true :
false;
912 return JS_FreezeObject(
m->m_cx, JSVAL_TO_OBJECT(obj)) ?
true :
false;
920 utf16string codeUtf16(codeStrict.begin(), codeStrict.end());
923 JSFunction* func = JS_CompileUCFunction(
m->m_cx, NULL, NULL, 0, NULL,
924 reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uintN)(codeUtf16.length()),
931 JSBool ok = JS_CallFunction(
m->m_cx, NULL, func, 0, NULL, &scriptRval);
933 return ok ?
true :
false;
941 utf16string codeUtf16(codeStrict.begin(), codeStrict.end());
945 JSBool ok = JS_EvaluateUCScript(
m->m_cx,
m->m_glob,
946 reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uintN)(codeUtf16.length()),
949 return ok ?
true :
false;
974 std::wstring codeStrict = L
"\"use strict\";\n" + code;
975 utf16string codeUtf16(codeStrict.begin(), codeStrict.end());
979 JSBool ok = JS_EvaluateUCScript(
m->m_cx,
m->m_glob,
980 reinterpret_cast<const jschar*> (codeUtf16.c_str()), (uintN)(codeUtf16.length()),
983 return ok ?
true :
false;
990 return Eval_(code, rval);
997 JSBool ok = JS_EvaluateUCScript(
m->m_cx,
m->m_glob, (
const jschar*)codeUtf16.c_str(), (uintN)codeUtf16.length(),
"(eval)", 1, &rval);
998 return ok ?
true :
false;
1005 JSBool ok = JS_EvaluateUCScript(
m->m_cx,
m->m_glob, (
const jschar*)codeUtf16.c_str(), (uintN)codeUtf16.length(),
"(eval)", 1, &rval);
1006 return ok ?
true :
false;
1015 JSONParser* parser = JS_BeginJSONParse(
m->m_cx, &vp);
1018 LOGERROR(L
"ParseJSON failed to begin");
1022 if (!JS_ConsumeJSONText(
m->m_cx, parser, reinterpret_cast<const jschar*>(
string.c_str()), (uint32)
string.size()))
1024 LOGERROR(L
"ParseJSON failed to consume");
1028 if (!JS_FinishJSONParse(
m->m_cx, parser, JSVAL_NULL))
1030 LOGERROR(L
"ParseJSON failed to finish");
1062 static JSBool
callback(
const jschar* buf, uint32 len,
void* data)
1065 std::wstring strw(str.begin(), str.end());
1077 static JSBool
callback(
const jschar* buf, uint32 len,
void* data)
1090 if (!JS_Stringify(
m->m_cx, &obj, NULL, indent ? INT_TO_JSVAL(2) : JSVAL_VOID, &
Stringifier::callback, &str))
1092 JS_ClearPendingException(
m->m_cx);
1094 JS_ClearPendingException(
m->m_cx);
1095 return std::string();
1104 if (JSVAL_IS_VOID(obj))
1114 JSErrorReporter er = JS_SetErrorReporter(
m->m_cx, NULL);
1119 JS_SetErrorReporter(
m->m_cx, er);
1125 JS_ClearPendingException(
m->m_cx);
1131 std::wstring source = L
"(error)";
1142 JS_SetPendingException(
m->m_cx, JSVAL_VOID);
1144 JS_ReportError(
m->m_cx,
"%s", msg);
1151 return JS_IsExceptionPending(cx) ?
true :
false;
1158 return JS_GET_CLASS(cx, obj);
1164 return JS_GetPrivate(cx, obj);
1170 JS_DumpHeap(
m->m_cx, stderr, NULL, 0, NULL, (
size_t)-1, NULL);
1172 fprintf(stderr,
"# Bytes allocated: %u\n", JS_GetGCParameter(
GetRuntime(), JSGC_BYTES));
1174 fprintf(stderr,
"# Bytes allocated after GC: %u\n", JS_GetGCParameter(
GetRuntime(), JSGC_BYTES));
1179 JS_MaybeGC(
m->m_cx);
1193 if (!JSVAL_IS_GCTHING(val) || JSVAL_IS_NULL(val))
1196 std::map<void*, jsval>::iterator it =
m_Mapping.find(JSVAL_TO_GCTHING(val));
1207 #define CLONE_REQUIRE(expr, msg) if (!(expr)) { debug_warn(L"Internal error in CloneValueFromOtherContext: " msg); return JSVAL_VOID; }
1212 if (JSVAL_IS_DOUBLE(val))
1215 CLONE_REQUIRE(JS_NewNumberValue(
cxTo, JSVAL_TO_DOUBLE(val), &rval), L
"JS_NewNumberValue");
1220 if (JSVAL_IS_STRING(val))
1223 const jschar* chars = JS_GetStringCharsAndLength(
cxFrom, JSVAL_TO_STRING(val), &len);
1225 JSString* str = JS_NewUCStringCopyN(
cxTo, chars, len);
1227 jsval rval = STRING_TO_JSVAL(str);
1228 m_Mapping[JSVAL_TO_GCTHING(val)] = rval;
1233 ENSURE(JSVAL_IS_OBJECT(val));
1236 if (JS_IsArrayObject(
cxFrom, JSVAL_TO_OBJECT(val)))
1239 CLONE_REQUIRE(JS_GetArrayLength(
cxFrom, JSVAL_TO_OBJECT(val), &length), L
"JS_GetArrayLength");
1240 newObj = JS_NewArrayObject(
cxTo, length, NULL);
1245 newObj = JS_NewObject(
cxTo, NULL, NULL, NULL);
1249 m_Mapping[JSVAL_TO_GCTHING(val)] = OBJECT_TO_JSVAL(newObj);
1256 idaRooter.Push(ida.
get());
1258 for (
size_t i = 0; i < ida.
length(); ++i)
1261 jsval idval, propval;
1263 CLONE_REQUIRE(JS_GetPropertyById(
cxFrom, JSVAL_TO_OBJECT(val),
id, &propval), L
"JS_GetPropertyById");
1266 if (JSVAL_IS_INT(idval))
1269 CLONE_REQUIRE(JS_SetPropertyById(
cxTo, newObj,
id, &newPropval), L
"JS_SetPropertyById");
1271 else if (JSVAL_IS_STRING(idval))
1274 JSString* idstr = JS_ValueToString(
cxFrom, idval);
1277 const jschar* chars = JS_GetStringCharsAndLength(
cxFrom, idstr, &len);
1279 CLONE_REQUIRE(JS_SetUCProperty(
cxTo, newObj, chars, len, &newPropval), L
"JS_SetUCProperty");
1287 return OBJECT_TO_JSVAL(newObj);
1300 PROFILE(
"CloneValueFromOtherContext");
1307 m_Context(NULL), m_Data(NULL), m_Size(0)
1314 JS_free(m_Context, m_Data);
1319 uint64* data = NULL;
1321 if (!JS_WriteStructuredClone(
m->m_cx, v, &data, &nbytes, NULL, NULL))
1322 return shared_ptr<StructuredClone>();
1327 ret->m_Context =
m->m_cx;
1329 ret->m_Size = nbytes;
1335 jsval ret = JSVAL_VOID;
1336 JS_ReadStructuredClone(
m->m_cx, ptr->m_Data, ptr->m_Size, JS_STRUCTURED_CLONE_VERSION, &ret, NULL, NULL);
CDebuggingServer * g_DebuggingServer
bool SetPrototype(jsval obj, jsval proto)
jsval GetOrClone(jsval val)
CStr DecodeUTF8() const
Returns contents of a UTF-8 encoded file as a string with optional BOM removed.
bool ReplaceNondeterministicRNG(boost::rand48 &rng)
Replace the default JS random number geenrator with a seeded, network-sync'd one. ...
bool CallFunction_(jsval val, const char *name, size_t argc, jsval *argv, jsval &ret)
CScriptStatsTable * g_ScriptStatsTable
static JSBool callback(const jschar *buf, uint32 len, void *data)
void Add(const ScriptInterface *scriptInterface, const std::string &title)
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
static void jshook_trace(JSTracer *trc, void *data)
bool LoadGlobalScript(const VfsPath &filename, const std::string &code)
Load and execute the given script in the global scope.
boost::flyweight< boost::flyweights::key_value< ScriptLocation, ScriptLocationName >, boost::flyweights::no_tracking, boost::flyweights::no_locking > LocFlyweight
bool SetGlobal_(const char *name, jsval value, bool replace)
bool HasProperty(jsval obj, const char *name)
Check the named property has been defined on the given object.
void SetCallbackData(void *cbdata)
const PSRETURN PSRETURN_OK
Reads a file, then gives read-only access to the contents.
std::string utf8_from_wstring(const std::wstring &src, Status *err)
opposite of wstring_from_utf8
void Register(const char *name, JSNative fptr, uintN nargs)
AutoGCRooter m_RooterFrom
void RegisterScriptinterface(std::string name, ScriptInterface *pScriptInterface)
Register a new ScriptInerface for debugging the scripts it executes.
JSBool logmsg(JSContext *cx, uintN argc, jsval *vp)
static void out(const wchar_t *fmt,...)
bool CallFunctionVoid(jsval val, const char *name)
Call the named property on the given object, with void return type and 0 arguments.
void Register(const char *name, JSNative fptr, size_t nargs)
JSRuntime * GetRuntime() const
static void ShutDown()
Shut down the JS system to clean up memory.
bool GetProperty_(jsval obj, const char *name, jsval &value)
bool FreezeObject(jsval obj, bool deep)
bool LoadScript(const VfsPath &filename, const std::string &code)
Load and execute the given script in a new function scope.
bool LoadGlobalScripts()
Load global scripts that most script contexts need, located in the /globalscripts directory...
std::string StringifyJSON(jsval obj, bool indent=true)
Stringify to a JSON string, UTF-8 encoded.
CScriptValRooted ParseJSON(const std::string &string_utf8)
Parse a UTF-8-encoded JSON string.
bool SetPropertyInt_(jsval obj, int name, jsval value, bool readonly, bool enumerate)
std::map< void *, jsval > m_Mapping
static double generate_uniform_real(boost::rand48 &rng, double min, double max)
bool g_ScriptProfilingEnabled
Structured clones are a way to serialize 'simple' JS values into a buffer that can safely be passed b...
AutoGCRooter * ReplaceAutoGCRooter(AutoGCRooter *rooter)
void DumpHeap()
Dump some memory heap debugging information to stderr.
static bool IsExceptionPending(JSContext *cx)
jsval NewObjectFromConstructor(jsval ctor)
Create an object as with CallConstructor except don't actually execute the constructor function...
ScriptInterface(const char *nativeScopeName, const char *debugName, const shared_ptr< ScriptRuntime > &runtime)
Constructor.
shared_ptr< ScriptRuntime > m_runtime
friend std::size_t hash_value(const ScriptLocation &loc)
static bool FromJSVal(JSContext *cx, jsval val, T &ret)
Convert a jsval to a C++ type.
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
#define UNUSED2(param)
mark a function local variable or parameter as unused and avoid the corresponding compiler warning...
JSBool ProfileStart(JSContext *cx, uintN argc, jsval *vp)
ScriptLocationName(const ScriptLocation &loc)
JSObject * m_compartmentGlobal
JSBool Math_random(JSContext *cx, uintN argc, jsval *vp)
JSCrossCompartmentCall * m_call
static void * GetCallbackData(JSContext *cx)
ValueCloner(ScriptInterface &from, ScriptInterface &to)
boost::mt19937 rng
Random number generator (Boost Mersenne Twister)
CScriptValRooted ReadJSONFile(const VfsPath &path)
Read a JSON file.
const String & string() const
static JSBool callback(const jschar *buf, uint32 len, void *data)
bool LoadGlobalScriptFile(const VfsPath &path)
Load and execute the given script in the global scope.
static JSClass * GetClass(JSContext *cx, JSObject *obj)
void Remove(const ScriptInterface *scriptInterface)
bool Eval(const char *code)
JSBool print(JSContext *cx, uintN argc, jsval *vp)
i64 Status
Error handling system.
static bool IsInitialised()
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::no_locking > StringFlyweight
static void * jshook_function(JSContext *cx, JSStackFrame *fp, JSBool before, JSBool *ok, void *closure)
jsval CloneValueFromOtherContext(ScriptInterface &otherContext, jsval val)
Construct a new value (usable in this ScriptInterface's context) by cloning a value from a different ...
const char * GetErrorString(PSRETURN code)
std::wstring wstring_from_utf8(const std::string &src, Status *err)
convert UTF-8 to a wide string (UTF-16 or UCS-4, depending on the platform's wchar_t).
bool CallFunction(jsval val, const char *name, R &ret)
Call the named property on the given object, with return type R and 0 arguments.
void RecordRegionEnter(const char *id)
std::basic_string< utf16_t, utf16_traits > utf16string
bool SetProperty_(jsval obj, const char *name, jsval value, bool readonly, bool enumerate)
ScriptInterface_impl(const char *nativeScopeName, const shared_ptr< ScriptRuntime > &runtime)
PSRETURN Load(const PIVFS &vfs, const VfsPath &filename)
Returns either PSRETURN_OK or PSRETURN_CVFSFile_LoadFailed.
jsval CallConstructor(jsval ctor, jsval arg)
Call a constructor function, equivalent to JS "new ctor(arg)".
JSClass * GetGlobalClass()
bool VfsFileExists(const VfsPath &pathname)
static void * jshook_script(JSContext *cx, JSStackFrame *fp, JSBool before, JSBool *ok, void *closure)
bool IsMainThread()
Returns whether the current thread is the 'main' thread (i.e.
std::vector< VfsPath > VfsPaths
JSBool error(JSContext *cx, uintN argc, jsval *vp)
static void * GetPrivate(JSContext *cx, JSObject *obj)
void ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
#define CLONE_REQUIRE(expr, msg)
Abstraction around a SpiderMonkey JSContext.
void RecordRegionLeave(const char *id)
std::wstring ToString(jsval obj, bool pretty=false)
bool GetPropertyInt_(jsval obj, int name, jsval &value)
void Trace(JSTracer *trc)
bool Eval_(const char *code, jsval &ret)
std::wstringstream stream
Abstraction around a SpiderMonkey JSRuntime.
jsval ReadStructuredClone(const shared_ptr< StructuredClone > &ptr)
JSBool ProfileStop(JSContext *cx, uintN argc, jsval *vp)
bool operator==(const ScriptLocation &b) const
bool EnumeratePropertyNamesWithPrefix(jsval obj, const char *prefix, std::vector< std::string > &out)
ScriptRuntime(int runtimeSize)
static shared_ptr< ScriptRuntime > CreateRuntime(int runtimeSize=DEFAULT_RUNTIME_SIZE)
Returns a runtime, which can used to initialise any number of ScriptInterfaces contexts.
Status GetPathnames(const PIVFS &fs, const VfsPath &path, const wchar_t *filter, VfsPaths &pathnames)
JSBool warn(JSContext *cx, uintN argc, jsval *vp)
JSBool deepcopy(JSContext *cx, uintN argc, jsval *vp)
JSContext * GetContext() const
void MaybeGC()
MaybeGC tries to determine whether garbage collection in cx's runtime would free up enough memory to ...
Helper for rooting large groups of script values.
void UnRegisterScriptinterface(ScriptInterface *pScriptInterface)
Unregister a ScriptInerface that was previously registered using RegisterScriptinterface.
void ReportError(const char *msg)
Report the given error message through the JS error reporting mechanism, and throw a JS exception...
RAII wrapper for JSIdArray*.
std::auto_ptr< ScriptInterface_impl > m
ScriptInterface & scriptInterfaceFrom
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
shared_ptr< StructuredClone > WriteStructuredClone(jsval v)