bug 630209 - (Compile|Execute)Script that are GC-safe. r=jorendorff
This commit is contained in:
@@ -628,9 +628,7 @@ nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
|
||||
mGlobal->GetJSObject(&global);
|
||||
if (global) {
|
||||
jsval val;
|
||||
JS_ExecuteScript(mCx, global,
|
||||
(JSScript*)JS_GetPrivate(mCx, holder->mObject),
|
||||
&val);
|
||||
JS_ExecuteScript(mCx, global, holder->mObject, &val);
|
||||
}
|
||||
}
|
||||
JSContext* unused;
|
||||
@@ -682,15 +680,13 @@ nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
|
||||
JSPrincipals* jsprin = nsnull;
|
||||
mPrincipal->GetJSPrincipals(mCx, &jsprin);
|
||||
nsContentUtils::XPConnect()->FlagSystemFilenamePrefix(url.get(), PR_TRUE);
|
||||
JSScript* script =
|
||||
JSObject* scriptObj =
|
||||
JS_CompileUCScriptForPrincipals(mCx, nsnull, jsprin,
|
||||
(jschar*)dataString.get(),
|
||||
dataString.Length(),
|
||||
url.get(), 1);
|
||||
|
||||
if (script) {
|
||||
JSObject* scriptObj = JS_NewScriptObject(mCx, script);
|
||||
JS_AddObjectRoot(mCx, &scriptObj);
|
||||
if (scriptObj) {
|
||||
nsCAutoString scheme;
|
||||
uri->GetScheme(scheme);
|
||||
// We don't cache data: scripts!
|
||||
@@ -703,9 +699,7 @@ nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
|
||||
sCachedScripts->Put(aURL, holder);
|
||||
}
|
||||
jsval val;
|
||||
JS_ExecuteScript(mCx, global,
|
||||
(JSScript*)JS_GetPrivate(mCx, scriptObj), &val);
|
||||
JS_RemoveObjectRoot(mCx, &scriptObj);
|
||||
JS_ExecuteScript(mCx, global, scriptObj, &val);
|
||||
}
|
||||
//XXX Argh, JSPrincipals are manually refcounted!
|
||||
JSPRINCIPALS_DROP(mCx, jsprin);
|
||||
|
||||
@@ -1542,7 +1542,7 @@ nsJSContext::CompileScript(const PRUnichar* aText,
|
||||
if (ok && ((JSVersion)aVersion) != JSVERSION_UNKNOWN) {
|
||||
JSAutoRequest ar(mContext);
|
||||
|
||||
JSScript* script =
|
||||
JSObject* scriptObj =
|
||||
::JS_CompileUCScriptForPrincipalsVersion(mContext,
|
||||
(JSObject *)aScopeObject,
|
||||
jsprin,
|
||||
@@ -1551,16 +1551,10 @@ nsJSContext::CompileScript(const PRUnichar* aText,
|
||||
aURL,
|
||||
aLineNo,
|
||||
JSVersion(aVersion));
|
||||
if (script) {
|
||||
JSObject *scriptObject = ::JS_NewScriptObject(mContext, script);
|
||||
if (scriptObject) {
|
||||
if (scriptObj) {
|
||||
NS_ASSERTION(aScriptObject.getScriptTypeID()==JAVASCRIPT,
|
||||
"Expecting JS script object holder");
|
||||
rv = aScriptObject.set(scriptObject);
|
||||
} else {
|
||||
::JS_DestroyScript(mContext, script);
|
||||
script = nsnull;
|
||||
}
|
||||
rv = aScriptObject.set(scriptObj);
|
||||
} else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -1622,10 +1616,7 @@ nsJSContext::ExecuteScript(void *aScriptObject,
|
||||
nsJSContext::TerminationFuncHolder holder(this);
|
||||
JSAutoRequest ar(mContext);
|
||||
++mExecuteDepth;
|
||||
ok = ::JS_ExecuteScript(mContext,
|
||||
(JSObject *)aScopeObject,
|
||||
(JSScript*)::JS_GetPrivate(mContext, scriptObj),
|
||||
&val);
|
||||
ok = ::JS_ExecuteScript(mContext, (JSObject *)aScopeObject, scriptObj, &val);
|
||||
|
||||
if (ok) {
|
||||
// If all went well, convert val to a string (XXXbe unless undefined?).
|
||||
@@ -2068,9 +2059,7 @@ nsJSContext::Serialize(nsIObjectOutputStream* aStream, void *aScriptObject)
|
||||
xdr->userdata = (void*) aStream;
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
JSScript *script = reinterpret_cast<JSScript*>
|
||||
(::JS_GetPrivate(cx, mJSObject));
|
||||
if (! ::JS_XDRScript(xdr, &script)) {
|
||||
if (! ::JS_XDRScriptObject(xdr, &mJSObject)) {
|
||||
rv = NS_ERROR_FAILURE; // likely to be a principals serialization error
|
||||
} else {
|
||||
// Get the encoded JSXDRState data and write it. The JSXDRState owns
|
||||
@@ -2132,15 +2121,8 @@ nsJSContext::Deserialize(nsIObjectInputStream* aStream,
|
||||
JSAutoRequest ar(cx);
|
||||
::JS_XDRMemSetData(xdr, data, size);
|
||||
|
||||
JSScript *script = nsnull;
|
||||
if (! ::JS_XDRScript(xdr, &script)) {
|
||||
if (! ::JS_XDRScriptObject(xdr, &result)) {
|
||||
rv = NS_ERROR_FAILURE; // principals deserialization error?
|
||||
} else {
|
||||
result = ::JS_NewScriptObject(cx, script);
|
||||
if (! result) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY; // certain error
|
||||
::JS_DestroyScript(cx, script);
|
||||
}
|
||||
}
|
||||
|
||||
// Update data in case ::JS_XDRScript called back into C++ code to
|
||||
|
||||
@@ -255,9 +255,8 @@ nsDOMWorkerScriptLoader::ExecuteScripts(JSContext* aCx)
|
||||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
JSScript* script =
|
||||
static_cast<JSScript*>(JS_GetPrivate(aCx, loadInfo.scriptObj.ToJSObject()));
|
||||
NS_ASSERTION(script, "This shouldn't ever be null!");
|
||||
JSObject* scriptObj = loadInfo.scriptObj.ToJSObject();
|
||||
NS_ASSERTION(scriptObj, "This shouldn't ever be null!");
|
||||
|
||||
JSObject* global = mWorker->mGlobal ?
|
||||
mWorker->mGlobal :
|
||||
@@ -270,7 +269,7 @@ nsDOMWorkerScriptLoader::ExecuteScripts(JSContext* aCx)
|
||||
JS_SetOptions(aCx, JS_GetOptions(aCx) | JSOPTION_DONT_REPORT_UNCAUGHT);
|
||||
|
||||
jsval val;
|
||||
PRBool success = JS_ExecuteScript(aCx, global, script, &val);
|
||||
PRBool success = JS_ExecuteScript(aCx, global, scriptObj, &val);
|
||||
|
||||
JS_SetOptions(aCx, oldOpts);
|
||||
|
||||
@@ -827,7 +826,7 @@ nsDOMWorkerScriptLoader::ScriptCompiler::Run()
|
||||
|
||||
JSPrincipals* principal = nsDOMWorkerSecurityManager::WorkerPrincipal();
|
||||
|
||||
JSScript* script =
|
||||
JSObject* scriptObj =
|
||||
JS_CompileUCScriptForPrincipals(cx, global, principal,
|
||||
reinterpret_cast<const jschar*>
|
||||
(mScriptText.BeginReading()),
|
||||
@@ -835,12 +834,11 @@ nsDOMWorkerScriptLoader::ScriptCompiler::Run()
|
||||
|
||||
JS_SetOptions(cx, oldOpts);
|
||||
|
||||
if (!script) {
|
||||
if (!scriptObj) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mScriptObj = JS_NewScriptObject(cx, script);
|
||||
NS_ENSURE_STATE(mScriptObj.ToJSObject());
|
||||
mScriptObj = scriptObj;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -309,8 +309,7 @@ Load(JSContext *cx,
|
||||
{
|
||||
uintN i;
|
||||
JSString *str;
|
||||
JSScript *script;
|
||||
JSBool ok;
|
||||
JSObject *scriptObj;
|
||||
jsval result;
|
||||
FILE *file;
|
||||
|
||||
@@ -332,19 +331,17 @@ Load(JSContext *cx,
|
||||
JS_ReportError(cx, "cannot open file '%s' for reading", filename.ptr());
|
||||
return JS_FALSE;
|
||||
}
|
||||
script = JS_CompileFileHandleForPrincipals(cx, obj, filename.ptr(), file,
|
||||
scriptObj = JS_CompileFileHandleForPrincipals(cx, obj, filename.ptr(), file,
|
||||
Environment(cx)->GetPrincipal());
|
||||
fclose(file);
|
||||
if (!script)
|
||||
if (!scriptObj)
|
||||
return JS_FALSE;
|
||||
|
||||
ok = !Environment(cx)->ShouldCompileOnly()
|
||||
? JS_ExecuteScript(cx, obj, script, &result)
|
||||
: JS_TRUE;
|
||||
JS_DestroyScript(cx, script);
|
||||
if (!ok)
|
||||
if (!Environment(cx)->ShouldCompileOnly() &&
|
||||
!JS_ExecuteScript(cx, obj, scriptObj, &result)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
}
|
||||
@@ -575,7 +572,7 @@ ProcessFile(JSContext *cx,
|
||||
XPCShellEnvironment* env = Environment(cx);
|
||||
XPCShellEnvironment::AutoContextPusher pusher(env);
|
||||
|
||||
JSScript *script;
|
||||
JSObject *scriptObj;
|
||||
jsval result;
|
||||
int lineno, startline;
|
||||
JSBool ok, hitEOF;
|
||||
@@ -615,14 +612,11 @@ ProcessFile(JSContext *cx,
|
||||
return;
|
||||
}
|
||||
|
||||
JSScript* script =
|
||||
JSObject* scriptObj =
|
||||
JS_CompileFileHandleForPrincipals(cx, obj, filename, file,
|
||||
env->GetPrincipal());
|
||||
if (script) {
|
||||
if (!env->ShouldCompileOnly())
|
||||
(void)JS_ExecuteScript(cx, obj, script, &result);
|
||||
JS_DestroyScript(cx, script);
|
||||
}
|
||||
if (scriptObj && !env->ShouldCompileOnly())
|
||||
(void)JS_ExecuteScript(cx, obj, scriptObj, &result);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -660,14 +654,14 @@ ProcessFile(JSContext *cx,
|
||||
|
||||
/* Clear any pending exception from previous failed compiles. */
|
||||
JS_ClearPendingException(cx);
|
||||
script =
|
||||
scriptObj =
|
||||
JS_CompileScriptForPrincipals(cx, obj, env->GetPrincipal(), buffer,
|
||||
strlen(buffer), "typein", startline);
|
||||
if (script) {
|
||||
if (scriptObj) {
|
||||
JSErrorReporter older;
|
||||
|
||||
if (!env->ShouldCompileOnly()) {
|
||||
ok = JS_ExecuteScript(cx, obj, script, &result);
|
||||
ok = JS_ExecuteScript(cx, obj, scriptObj, &result);
|
||||
if (ok && result != JSVAL_VOID) {
|
||||
/* Suppress error reports from JS_ValueToString(). */
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
@@ -683,7 +677,6 @@ ProcessFile(JSContext *cx,
|
||||
ok = JS_FALSE;
|
||||
}
|
||||
}
|
||||
JS_DestroyScript(cx, script);
|
||||
}
|
||||
} while (!hitEOF && !env->IsQuitting());
|
||||
|
||||
@@ -1234,11 +1227,11 @@ XPCShellEnvironment::EvaluateString(const nsString& aString,
|
||||
return false;
|
||||
}
|
||||
|
||||
JSScript* script =
|
||||
JSObject* scriptObj =
|
||||
JS_CompileUCScriptForPrincipals(mCx, global, GetPrincipal(),
|
||||
aString.get(), aString.Length(),
|
||||
"typein", 0);
|
||||
if (!script) {
|
||||
if (!scriptObj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1248,7 +1241,7 @@ XPCShellEnvironment::EvaluateString(const nsString& aString,
|
||||
}
|
||||
|
||||
jsval result;
|
||||
JSBool ok = JS_ExecuteScript(mCx, global, script, &result);
|
||||
JSBool ok = JS_ExecuteScript(mCx, global, scriptObj, &result);
|
||||
if (ok && result != JSVAL_VOID) {
|
||||
JSErrorReporter old = JS_SetErrorReporter(mCx, NULL);
|
||||
JSString* str = JS_ValueToString(mCx, result);
|
||||
@@ -1263,7 +1256,5 @@ XPCShellEnvironment::EvaluateString(const nsString& aString,
|
||||
}
|
||||
}
|
||||
|
||||
JS_DestroyScript(mCx, script);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1042,7 +1042,7 @@ jsdScript::CreatePPLineMap()
|
||||
JSFunction *fun = JSD_GetJSFunction (mCx, mScript);
|
||||
JSScript *script; /* In JSD compartment */
|
||||
PRUint32 baseLine;
|
||||
PRBool scriptOwner = PR_FALSE;
|
||||
JSObject *scriptObj = NULL;
|
||||
JSString *jsstr;
|
||||
size_t length;
|
||||
const jschar *chars;
|
||||
@@ -1080,11 +1080,11 @@ jsdScript::CreatePPLineMap()
|
||||
JSString *jsstr;
|
||||
|
||||
{
|
||||
JSAutoEnterCompartment ac;
|
||||
JS::AutoEnterScriptCompartment ac;
|
||||
if (!ac.enter(cx, script))
|
||||
return nsnull;
|
||||
|
||||
jsstr = JS_DecompileScript (cx, JSD_GetJSScript(mCx, mScript), "ppscript", 4);
|
||||
jsstr = JS_DecompileScript (cx, script, "ppscript", 4);
|
||||
if (!jsstr)
|
||||
return nsnull;
|
||||
|
||||
@@ -1093,13 +1093,17 @@ jsdScript::CreatePPLineMap()
|
||||
}
|
||||
|
||||
JS::Anchor<JSString *> kungFuDeathGrip(jsstr);
|
||||
script = JS_CompileUCScript (cx, obj, chars, length, "x-jsd:ppbuffer?type=script", 1);
|
||||
if (!script)
|
||||
scriptObj = JS_CompileUCScript (cx, obj, chars, length, "x-jsd:ppbuffer?type=script", 1);
|
||||
if (!scriptObj)
|
||||
return nsnull;
|
||||
scriptOwner = PR_TRUE;
|
||||
script = JS_GetScriptFromObject(scriptObj);
|
||||
baseLine = 1;
|
||||
}
|
||||
|
||||
/* Make sure that a non-function script is rooted via scriptObj until the
|
||||
* end of script usage. */
|
||||
JS::Anchor<JSObject *> scriptAnchor(scriptObj);
|
||||
|
||||
PRUint32 scriptExtent = JS_GetScriptLineExtent (cx, script);
|
||||
jsbytecode* firstPC = JS_LineNumberToPC (cx, script, 0);
|
||||
/* allocate worst case size of map (number of lines in script + 1
|
||||
@@ -1130,9 +1134,6 @@ jsdScript::CreatePPLineMap()
|
||||
}
|
||||
}
|
||||
|
||||
if (scriptOwner)
|
||||
JS_DestroyScript (cx, script);
|
||||
|
||||
mPCMapSize = lineMapSize;
|
||||
return mPPLineMap = lineMap;
|
||||
}
|
||||
@@ -1187,7 +1188,7 @@ jsdScript::GetVersion (PRInt32 *_rval)
|
||||
ASSERT_VALID_EPHEMERAL;
|
||||
JSContext *cx = JSD_GetDefaultJSContext (mCx);
|
||||
JSScript *script = JSD_GetJSScript(mCx, mScript);
|
||||
JSAutoEnterCompartment ac;
|
||||
JS::AutoEnterScriptCompartment ac;
|
||||
if (!ac.enter(cx, script))
|
||||
return NS_ERROR_FAILURE;
|
||||
*_rval = static_cast<PRInt32>(JS_GetScriptVersion(cx, script));
|
||||
@@ -1383,13 +1384,14 @@ jsdScript::GetFunctionSource(nsAString & aFunctionSource)
|
||||
|
||||
JSString *jsstr;
|
||||
JSAutoEnterCompartment ac;
|
||||
JS::AutoEnterScriptCompartment asc;
|
||||
if (fun) {
|
||||
if (!ac.enter(cx, JS_GetFunctionObject(fun)))
|
||||
return NS_ERROR_FAILURE;
|
||||
jsstr = JS_DecompileFunction (cx, fun, 4);
|
||||
} else {
|
||||
JSScript *script = JSD_GetJSScript (mCx, mScript);
|
||||
if (!ac.enter(cx, script))
|
||||
if (!asc.enter(cx, script))
|
||||
return NS_ERROR_FAILURE;
|
||||
jsstr = JS_DecompileScript (cx, script, "ppscript", 4);
|
||||
}
|
||||
|
||||
@@ -15,31 +15,15 @@ struct ScriptObjectFixture : public JSAPITest {
|
||||
uc_code[i] = code[i];
|
||||
}
|
||||
|
||||
bool tryScript(JSScript *script)
|
||||
bool tryScript(JSObject *scriptObj)
|
||||
{
|
||||
CHECK(script);
|
||||
|
||||
/* We should have allocated a script object for the script already. */
|
||||
jsvalRoot script_object(cx, OBJECT_TO_JSVAL(JS_GetScriptObject(script)));
|
||||
CHECK(JSVAL_TO_OBJECT(script_object.value()));
|
||||
|
||||
/*
|
||||
* JS_NewScriptObject just returns the object already created for the
|
||||
* script. It was always a bug to call this more than once.
|
||||
*/
|
||||
jsvalRoot second_script_object
|
||||
(cx, OBJECT_TO_JSVAL(JS_NewScriptObject(cx, script)));
|
||||
CHECK_SAME(second_script_object.value(), script_object.value());
|
||||
CHECK(scriptObj);
|
||||
|
||||
JS_GC(cx);
|
||||
|
||||
/* After a garbage collection, the script should still work. */
|
||||
jsval result;
|
||||
CHECK(JS_ExecuteScript(cx, global, script, &result));
|
||||
|
||||
/* JS_DestroyScript must still be safe to call, whether or not it
|
||||
actually has any effect. */
|
||||
JS_DestroyScript(cx, script);
|
||||
CHECK(JS_ExecuteScript(cx, global, scriptObj, &result));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -103,9 +87,9 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile)
|
||||
FILE *script_stream = tempScript.open(script_filename);
|
||||
CHECK(fputs(code, script_stream) != EOF);
|
||||
tempScript.close();
|
||||
JSScript *script = JS_CompileFile(cx, global, script_filename);
|
||||
JSObject *scriptObj = JS_CompileFile(cx, global, script_filename);
|
||||
tempScript.remove();
|
||||
return tryScript(script);
|
||||
return tryScript(scriptObj);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile)
|
||||
|
||||
@@ -115,9 +99,9 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile_empty)
|
||||
static const char script_filename[] = "temp-bug438633_JS_CompileFile_empty";
|
||||
tempScript.open(script_filename);
|
||||
tempScript.close();
|
||||
JSScript *script = JS_CompileFile(cx, global, script_filename);
|
||||
JSObject *scriptObj = JS_CompileFile(cx, global, script_filename);
|
||||
tempScript.remove();
|
||||
return tryScript(script);
|
||||
return tryScript(scriptObj);
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile_empty)
|
||||
|
||||
@@ -152,19 +136,3 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandleForPrincip
|
||||
script_stream, NULL));
|
||||
}
|
||||
END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandleForPrincipals)
|
||||
|
||||
BEGIN_TEST(testScriptObject_ScriptlessScriptObjects)
|
||||
{
|
||||
/* JS_NewScriptObject(cx, NULL) should return a fresh object each time. */
|
||||
jsvalRoot script_object1(cx, OBJECT_TO_JSVAL(JS_NewScriptObject(cx, NULL)));
|
||||
CHECK(!JSVAL_IS_PRIMITIVE(script_object1.value()));
|
||||
|
||||
jsvalRoot script_object2(cx, OBJECT_TO_JSVAL(JS_NewScriptObject(cx, NULL)));
|
||||
CHECK(!JSVAL_IS_PRIMITIVE(script_object2.value()));
|
||||
|
||||
if (script_object1.value() == script_object2.value())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testScriptObject_ScriptlessScriptObjects)
|
||||
|
||||
@@ -30,15 +30,12 @@ BEGIN_TEST(testTrap_gc)
|
||||
;
|
||||
|
||||
// compile
|
||||
JSScript *script = JS_CompileScript(cx, global, source, strlen(source), __FILE__, 1);
|
||||
CHECK(script);
|
||||
JSObject *scrobj = JS_NewScriptObject(cx, script);
|
||||
CHECK(scrobj);
|
||||
jsvalRoot v(cx, OBJECT_TO_JSVAL(scrobj));
|
||||
JSObject *scriptObj = JS_CompileScript(cx, global, source, strlen(source), __FILE__, 1);
|
||||
CHECK(scriptObj);
|
||||
|
||||
// execute
|
||||
jsvalRoot v2(cx);
|
||||
CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
|
||||
CHECK(JS_ExecuteScript(cx, global, scriptObj, v2.addr()));
|
||||
CHECK(JSVAL_IS_OBJECT(v2));
|
||||
CHECK(emptyTrapCallCount == 0);
|
||||
|
||||
@@ -48,14 +45,20 @@ BEGIN_TEST(testTrap_gc)
|
||||
// Enable debug mode
|
||||
CHECK(JS_SetDebugMode(cx, JS_TRUE));
|
||||
|
||||
static const char trapClosureText[] = "some trap closure";
|
||||
|
||||
// scope JSScript usage to make sure that it is not used after
|
||||
// JS_ExecuteScript. This way we avoid using Anchor.
|
||||
JSString *trapClosure;
|
||||
{
|
||||
JSScript *script = JS_GetScriptFromObject(scriptObj);
|
||||
jsbytecode *line2 = JS_LineNumberToPC(cx, script, 1);
|
||||
CHECK(line2);
|
||||
|
||||
jsbytecode *line6 = JS_LineNumberToPC(cx, script, 5);
|
||||
CHECK(line2);
|
||||
|
||||
static const char trapClosureText[] = "some trap closure";
|
||||
JSString *trapClosure = JS_NewStringCopyZ(cx, trapClosureText);
|
||||
trapClosure = JS_NewStringCopyZ(cx, trapClosureText);
|
||||
CHECK(trapClosure);
|
||||
JS_SetTrap(cx, script, line2, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
|
||||
JS_SetTrap(cx, script, line6, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
|
||||
@@ -63,9 +66,10 @@ BEGIN_TEST(testTrap_gc)
|
||||
JS_GC(cx);
|
||||
|
||||
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
|
||||
}
|
||||
|
||||
// execute
|
||||
CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
|
||||
CHECK(JS_ExecuteScript(cx, global, scriptObj, v2.addr()));
|
||||
CHECK(emptyTrapCallCount == 11);
|
||||
|
||||
JS_GC(cx);
|
||||
|
||||
@@ -41,7 +41,7 @@ struct VersionFixture : public JSAPITest
|
||||
EvalScriptVersion16, 0, 0);
|
||||
}
|
||||
|
||||
JSScript *fakeScript(const char *contents, size_t length) {
|
||||
JSObject *fakeScript(const char *contents, size_t length) {
|
||||
return JS_CompileScript(cx, global, contents, length, "<test>", 1);
|
||||
}
|
||||
|
||||
@@ -74,9 +74,9 @@ struct VersionFixture : public JSAPITest
|
||||
|
||||
/* Check that script compilation results in a version without XML. */
|
||||
bool checkNewScriptNoXML() {
|
||||
JSScript *script = fakeScript("", 0);
|
||||
CHECK(script);
|
||||
CHECK(!hasXML(script->getVersion()));
|
||||
JSObject *scriptObj = fakeScript("", 0);
|
||||
CHECK(scriptObj);
|
||||
CHECK(!hasXML(JS_GetScriptFromObject(scriptObj)->getVersion()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -195,15 +195,12 @@ BEGIN_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags)
|
||||
"disableXMLOption();"
|
||||
"callSetVersion17();"
|
||||
"checkNewScriptNoXML();";
|
||||
JSScript *toActivate = fakeScript(toActivateChars, sizeof(toActivateChars) - 1);
|
||||
JSObject *toActivate = fakeScript(toActivateChars, sizeof(toActivateChars) - 1);
|
||||
CHECK(toActivate);
|
||||
JSObject *scriptObject = JS_GetScriptObject(toActivate);
|
||||
CHECK(hasXML(toActivate));
|
||||
CHECK(hasXML(JS_GetScriptFromObject(toActivate)));
|
||||
|
||||
disableXML();
|
||||
|
||||
CHECK(scriptObject);
|
||||
|
||||
/* Activate the script. */
|
||||
jsval dummy;
|
||||
CHECK(JS_ExecuteScript(cx, global, toActivate, &dummy));
|
||||
|
||||
@@ -16,16 +16,13 @@ BEGIN_TEST(testXDR_bug506491)
|
||||
"var f = makeClosure('0;', 'status', 'ok');\n";
|
||||
|
||||
// compile
|
||||
JSScript *script = JS_CompileScript(cx, global, s, strlen(s), __FILE__, __LINE__);
|
||||
CHECK(script);
|
||||
JSObject *scrobj = JS_NewScriptObject(cx, script);
|
||||
CHECK(scrobj);
|
||||
jsvalRoot v(cx, OBJECT_TO_JSVAL(scrobj));
|
||||
JSObject *scriptObj = JS_CompileScript(cx, global, s, strlen(s), __FILE__, __LINE__);
|
||||
CHECK(scriptObj);
|
||||
|
||||
// freeze
|
||||
JSXDRState *w = JS_XDRNewMem(cx, JSXDR_ENCODE);
|
||||
CHECK(w);
|
||||
CHECK(JS_XDRScript(w, &script));
|
||||
CHECK(JS_XDRScriptObject(w, &scriptObj));
|
||||
uint32 nbytes;
|
||||
void *p = JS_XDRMemGetData(w, &nbytes);
|
||||
CHECK(p);
|
||||
@@ -35,18 +32,15 @@ BEGIN_TEST(testXDR_bug506491)
|
||||
JS_XDRDestroy(w);
|
||||
|
||||
// thaw
|
||||
script = NULL;
|
||||
scriptObj = NULL;
|
||||
JSXDRState *r = JS_XDRNewMem(cx, JSXDR_DECODE);
|
||||
JS_XDRMemSetData(r, frozen, nbytes);
|
||||
CHECK(JS_XDRScript(r, &script));
|
||||
CHECK(JS_XDRScriptObject(r, &scriptObj));
|
||||
JS_XDRDestroy(r); // this frees `frozen`
|
||||
scrobj = JS_NewScriptObject(cx, script);
|
||||
CHECK(scrobj);
|
||||
v = OBJECT_TO_JSVAL(scrobj);
|
||||
|
||||
// execute
|
||||
jsvalRoot v2(cx);
|
||||
CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
|
||||
CHECK(JS_ExecuteScript(cx, global, scriptObj, v2.addr()));
|
||||
|
||||
// try to break the Block object that is the parent of f
|
||||
JS_GC(cx);
|
||||
@@ -62,16 +56,13 @@ END_TEST(testXDR_bug506491)
|
||||
BEGIN_TEST(testXDR_bug516827)
|
||||
{
|
||||
// compile an empty script
|
||||
JSScript *script = JS_CompileScript(cx, global, "", 0, __FILE__, __LINE__);
|
||||
CHECK(script);
|
||||
JSObject *scrobj = JS_NewScriptObject(cx, script);
|
||||
CHECK(scrobj);
|
||||
jsvalRoot v(cx, OBJECT_TO_JSVAL(scrobj));
|
||||
JSObject *scriptObj = JS_CompileScript(cx, global, "", 0, __FILE__, __LINE__);
|
||||
CHECK(scriptObj);
|
||||
|
||||
// freeze
|
||||
JSXDRState *w = JS_XDRNewMem(cx, JSXDR_ENCODE);
|
||||
CHECK(w);
|
||||
CHECK(JS_XDRScript(w, &script));
|
||||
CHECK(JS_XDRScriptObject(w, &scriptObj));
|
||||
uint32 nbytes;
|
||||
void *p = JS_XDRMemGetData(w, &nbytes);
|
||||
CHECK(p);
|
||||
@@ -81,17 +72,14 @@ BEGIN_TEST(testXDR_bug516827)
|
||||
JS_XDRDestroy(w);
|
||||
|
||||
// thaw
|
||||
script = NULL;
|
||||
scriptObj = NULL;
|
||||
JSXDRState *r = JS_XDRNewMem(cx, JSXDR_DECODE);
|
||||
JS_XDRMemSetData(r, frozen, nbytes);
|
||||
CHECK(JS_XDRScript(r, &script));
|
||||
CHECK(JS_XDRScriptObject(r, &scriptObj));
|
||||
JS_XDRDestroy(r); // this frees `frozen`
|
||||
scrobj = JS_NewScriptObject(cx, script);
|
||||
CHECK(scrobj);
|
||||
v = OBJECT_TO_JSVAL(scrobj);
|
||||
|
||||
// execute with null result meaning no result wanted
|
||||
CHECK(JS_ExecuteScript(cx, global, script, NULL));
|
||||
CHECK(JS_ExecuteScript(cx, global, scriptObj, NULL));
|
||||
return true;
|
||||
}
|
||||
END_TEST(testXDR_bug516827)
|
||||
|
||||
220
js/src/jsapi.cpp
220
js/src/jsapi.cpp
@@ -82,7 +82,6 @@
|
||||
#include "jsscript.h"
|
||||
#include "jsstr.h"
|
||||
#include "jstracer.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "prmjtime.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jsvector.h"
|
||||
@@ -112,16 +111,6 @@
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
static JSClass dummy_class = {
|
||||
"jdummy",
|
||||
JSCLASS_GLOBAL_FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
/*
|
||||
* This class is a version-establising barrier at the head of a VM entry or
|
||||
* re-entry. It ensures that:
|
||||
@@ -1192,6 +1181,16 @@ JS_EnterCrossCompartmentCall(JSContext *cx, JSObject *target)
|
||||
JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target)
|
||||
{
|
||||
static JSClass dummy_class = {
|
||||
"jdummy",
|
||||
JSCLASS_GLOBAL_FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, NULL,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
JS_ASSERT(target);
|
||||
@@ -1226,8 +1225,16 @@ JSAutoEnterCompartment::enter(JSContext *cx, JSObject *target)
|
||||
return call != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
JSAutoEnterCompartment::enterAndIgnoreErrors(JSContext *cx, JSObject *target)
|
||||
{
|
||||
(void) enter(cx, target);
|
||||
}
|
||||
|
||||
namespace JS {
|
||||
|
||||
bool
|
||||
JSAutoEnterCompartment::enter(JSContext *cx, JSScript *target)
|
||||
AutoEnterScriptCompartment::enter(JSContext *cx, JSScript *target)
|
||||
{
|
||||
JS_ASSERT(!call);
|
||||
if (cx->compartment == target->compartment) {
|
||||
@@ -1238,11 +1245,7 @@ JSAutoEnterCompartment::enter(JSContext *cx, JSScript *target)
|
||||
return call != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
JSAutoEnterCompartment::enterAndIgnoreErrors(JSContext *cx, JSObject *target)
|
||||
{
|
||||
(void) enter(cx, target);
|
||||
}
|
||||
} /* namespace JS */
|
||||
|
||||
JS_PUBLIC_API(void *)
|
||||
JS_SetCompartmentPrivate(JSContext *cx, JSCompartment *compartment, void *data)
|
||||
@@ -2186,6 +2189,11 @@ JS_RemoveGCThingRoot(JSContext *cx, void **rp)
|
||||
return js_RemoveRoot(cx->runtime, (void *)rp);
|
||||
}
|
||||
|
||||
JS_NEVER_INLINE JS_PUBLIC_API(void)
|
||||
JS_AnchorPtr(void *p)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
@@ -4515,7 +4523,7 @@ JS_OPTIONS_TO_TCFLAGS(JSContext *cx)
|
||||
(cx->hasRunOption(JSOPTION_NO_SCRIPT_RVAL) ? TCF_NO_SCRIPT_RVAL : 0);
|
||||
}
|
||||
|
||||
static JSScript *
|
||||
static JSObject *
|
||||
CompileUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, uintN lineno, JSVersion version)
|
||||
@@ -4527,15 +4535,17 @@ CompileUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj, JSPrincipals *p
|
||||
uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT;
|
||||
JSScript *script = Compiler::compileScript(cx, obj, NULL, principals, tcflags,
|
||||
chars, length, filename, lineno, version);
|
||||
if (script && !js_NewScriptObject(cx, script)) {
|
||||
JSObject *scriptObj = NULL;
|
||||
if (script) {
|
||||
scriptObj = js_NewScriptObject(cx, script);
|
||||
if (!scriptObj)
|
||||
js_DestroyScript(cx, script);
|
||||
script = NULL;
|
||||
}
|
||||
LAST_FRAME_CHECKS(cx, script);
|
||||
return script;
|
||||
LAST_FRAME_CHECKS(cx, scriptObj);
|
||||
return scriptObj;
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
const jschar *chars, size_t length,
|
||||
@@ -4547,7 +4557,7 @@ JS_CompileUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
avi.version());
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, uintN lineno)
|
||||
@@ -4556,7 +4566,7 @@ JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj, JSPrincipals *prin
|
||||
cx->findVersion());
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileUCScript(JSContext *cx, JSObject *obj, const jschar *chars, size_t length,
|
||||
const char *filename, uintN lineno)
|
||||
{
|
||||
@@ -4564,7 +4574,7 @@ JS_CompileUCScript(JSContext *cx, JSObject *obj, const jschar *chars, size_t len
|
||||
return JS_CompileUCScriptForPrincipals(cx, obj, NULL, chars, length, filename, lineno);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
const char *bytes, size_t length,
|
||||
@@ -4575,7 +4585,7 @@ JS_CompileScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
return JS_CompileScriptForPrincipals(cx, obj, principals, bytes, length, filename, lineno);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
const char *bytes, size_t length,
|
||||
@@ -4587,12 +4597,13 @@ JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
|
||||
jschar *chars = js_InflateString(cx, bytes, &length);
|
||||
if (!chars)
|
||||
return NULL;
|
||||
JSScript *script = JS_CompileUCScriptForPrincipals(cx, obj, principals, chars, length, filename, lineno);
|
||||
JSObject *scriptObj =
|
||||
JS_CompileUCScriptForPrincipals(cx, obj, principals, chars, length, filename, lineno);
|
||||
cx->free(chars);
|
||||
return script;
|
||||
return scriptObj;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileScript(JSContext *cx, JSObject *obj, const char *bytes, size_t length,
|
||||
const char *filename, uintN lineno)
|
||||
{
|
||||
@@ -4650,8 +4661,8 @@ JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj, const char *bytes, size_
|
||||
# define fast_getc getc
|
||||
#endif
|
||||
|
||||
static JSScript *
|
||||
CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals, uint32 tcflags,
|
||||
static JSObject *
|
||||
CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
const char* filename, FILE *fp)
|
||||
{
|
||||
struct stat st;
|
||||
@@ -4672,7 +4683,7 @@ CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals, uint32
|
||||
bool hitEOF = false;
|
||||
while (!hitEOF) {
|
||||
len *= 2;
|
||||
jschar* tmpbuf = (jschar *) cx->realloc(buf, len * sizeof(jschar));
|
||||
jschar* tmpbuf = (jschar *) js_realloc(buf, len * sizeof(jschar));
|
||||
if (!tmpbuf) {
|
||||
cx->free(buf);
|
||||
return NULL;
|
||||
@@ -4689,7 +4700,7 @@ CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals, uint32
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buf = (jschar *) cx->malloc(len * sizeof(jschar));
|
||||
buf = (jschar *) js_malloc(len * sizeof(jschar));
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
@@ -4700,22 +4711,30 @@ CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals, uint32
|
||||
|
||||
JS_ASSERT(i <= len);
|
||||
len = i;
|
||||
uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT;
|
||||
script = Compiler::compileScript(cx, obj, NULL, principals, tcflags, buf, len, filename, 1,
|
||||
cx->findVersion());
|
||||
cx->free(buf);
|
||||
return script;
|
||||
js_free(buf);
|
||||
if (!script)
|
||||
return NULL;
|
||||
|
||||
JSObject *scriptObj = js_NewScriptObject(cx, script);
|
||||
if (!scriptObj)
|
||||
js_DestroyScript(cx, script);
|
||||
|
||||
return scriptObj;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename)
|
||||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
FILE *fp;
|
||||
uint32 tcflags;
|
||||
JSScript *script;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
JSObject *scriptObj = NULL;
|
||||
do {
|
||||
FILE *fp;
|
||||
if (!filename || strcmp(filename, "-") == 0) {
|
||||
fp = stdin;
|
||||
} else {
|
||||
@@ -4723,45 +4742,33 @@ JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename)
|
||||
if (!fp) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN,
|
||||
filename, "No such file or directory");
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT;
|
||||
script = CompileFileHelper(cx, obj, NULL, tcflags, filename, fp);
|
||||
|
||||
scriptObj = CompileFileHelper(cx, obj, NULL, filename, fp);
|
||||
if (fp != stdin)
|
||||
fclose(fp);
|
||||
if (script && !js_NewScriptObject(cx, script)) {
|
||||
js_DestroyScript(cx, script);
|
||||
script = NULL;
|
||||
}
|
||||
LAST_FRAME_CHECKS(cx, script);
|
||||
return script;
|
||||
} while (false);
|
||||
|
||||
LAST_FRAME_CHECKS(cx, scriptObj);
|
||||
return scriptObj;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj, const char *filename, FILE *file,
|
||||
JSPrincipals *principals)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj, const char *filename,
|
||||
FILE *file, JSPrincipals *principals)
|
||||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
uint32 tcflags;
|
||||
JSScript *script;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, principals);
|
||||
tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT;
|
||||
script = CompileFileHelper(cx, obj, principals, tcflags, filename, file);
|
||||
|
||||
if (script && !js_NewScriptObject(cx, script)) {
|
||||
js_DestroyScript(cx, script);
|
||||
script = NULL;
|
||||
}
|
||||
LAST_FRAME_CHECKS(cx, script);
|
||||
return script;
|
||||
JSObject *scriptObj = CompileFileHelper(cx, obj, principals, filename, file);
|
||||
LAST_FRAME_CHECKS(cx, scriptObj);
|
||||
return scriptObj;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileFileHandleForPrincipalsVersion(JSContext *cx, JSObject *obj, const char *filename,
|
||||
FILE *file, JSPrincipals *principals, JSVersion version)
|
||||
{
|
||||
@@ -4769,58 +4776,19 @@ JS_CompileFileHandleForPrincipalsVersion(JSContext *cx, JSObject *obj, const cha
|
||||
return JS_CompileFileHandleForPrincipals(cx, obj, filename, file, principals);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename, FILE *file)
|
||||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
return JS_CompileFileHandleForPrincipals(cx, obj, filename, file, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_NewScriptObject(JSContext *cx, JSScript *script)
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
JS_GetScriptFromObject(JSObject *scriptObj)
|
||||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, script);
|
||||
if (!script)
|
||||
return NewNonFunction<WithProto::Class>(cx, &js_ScriptClass, NULL, NULL);
|
||||
JS_ASSERT(scriptObj->isScript());
|
||||
|
||||
/*
|
||||
* This function should only ever be applied to JSScripts that had
|
||||
* script objects allocated for them when they were created, as
|
||||
* described in the comment for JSScript::u.object.
|
||||
*/
|
||||
JS_ASSERT(script->u.object);
|
||||
return script->u.object;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetScriptObject(JSScript *script)
|
||||
{
|
||||
/*
|
||||
* This function should only ever be applied to JSScripts that had
|
||||
* script objects allocated for them when they were created, as
|
||||
* described in the comment for JSScript::u.object.
|
||||
*/
|
||||
JS_ASSERT(script->u.object);
|
||||
return script->u.object;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_DestroyScript(JSContext *cx, JSScript *script)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
/*
|
||||
* Originally, JSScript lifetimes were managed explicitly, and this function
|
||||
* was used to free a JSScript. Now, this function does nothing, and the
|
||||
* garbage collector manages JSScripts; you must root the JSScript's script
|
||||
* object (obtained via JS_GetScriptObject) to keep it alive.
|
||||
*
|
||||
* However, since the script objects have taken over this responsibility, it
|
||||
* follows that every script passed here must have a script object.
|
||||
*/
|
||||
JS_ASSERT(script->u.object);
|
||||
return (JSScript *) scriptObj->getPrivate();
|
||||
}
|
||||
|
||||
static JSFunction *
|
||||
@@ -4989,6 +4957,12 @@ JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, uintN inde
|
||||
return str;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
JS_DecompileScriptObject(JSContext *cx, JSObject *scriptObj, const char *name, uintN indent)
|
||||
{
|
||||
return JS_DecompileScript(cx, scriptObj->getScript(), name, indent);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent)
|
||||
{
|
||||
@@ -5014,26 +4988,24 @@ JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval)
|
||||
JS_ExecuteScript(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval)
|
||||
{
|
||||
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
|
||||
JSBool ok;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, script);
|
||||
/* This should receive only scripts handed out via the JSAPI. */
|
||||
JS_ASSERT(script->u.object);
|
||||
ok = Execute(cx, obj, script, NULL, 0, Valueify(rval));
|
||||
assertSameCompartment(cx, obj, scriptObj);
|
||||
|
||||
JSBool ok = Execute(cx, obj, scriptObj->getScript(), NULL, 0, Valueify(rval));
|
||||
LAST_FRAME_CHECKS(cx, ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval,
|
||||
JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval,
|
||||
JSVersion version)
|
||||
{
|
||||
AutoVersionAPI ava(cx, version);
|
||||
return JS_ExecuteScript(cx, obj, script, rval);
|
||||
return JS_ExecuteScript(cx, obj, scriptObj, rval);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -6189,20 +6161,6 @@ JS_ClearContextThread(JSContext *cx)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_TRACE_JSCALLS
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb)
|
||||
{
|
||||
cx->functionCallback = fcb;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunctionCallback)
|
||||
JS_GetFunctionCallback(JSContext *cx)
|
||||
{
|
||||
return cx->functionCallback;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetGCZeal(JSContext *cx, uint8 zeal)
|
||||
|
||||
@@ -988,9 +988,6 @@ JS_SetWrapObjectCallbacks(JSRuntime *rt,
|
||||
extern JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
JS_EnterCrossCompartmentCall(JSContext *cx, JSObject *target);
|
||||
|
||||
extern JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call);
|
||||
|
||||
@@ -1035,8 +1032,6 @@ class JS_PUBLIC_API(JSAutoEnterCompartment)
|
||||
|
||||
bool enter(JSContext *cx, JSObject *target);
|
||||
|
||||
bool enter(JSContext *cx, JSScript *target);
|
||||
|
||||
void enterAndIgnoreErrors(JSContext *cx, JSObject *target);
|
||||
|
||||
bool entered() const { return call != NULL; }
|
||||
@@ -1472,6 +1467,13 @@ inline Anchor<jsval>::~Anchor() {
|
||||
JS_BEGIN_EXTERN_C
|
||||
#endif
|
||||
|
||||
/*
|
||||
* C-compatible version of the Anchor class. It should be called after the last
|
||||
* use of the variable it protects.
|
||||
*/
|
||||
extern JS_NEVER_INLINE JS_PUBLIC_API(void)
|
||||
JS_AnchorPtr(void *p);
|
||||
|
||||
/*
|
||||
* This symbol may be used by embedders to detect the change from the old
|
||||
* JS_AddRoot(JSContext *, void *) APIs to the new ones above.
|
||||
@@ -2658,96 +2660,60 @@ extern JS_PUBLIC_API(JSBool)
|
||||
JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj,
|
||||
const char *bytes, size_t length);
|
||||
|
||||
/*
|
||||
* The JSScript objects returned by the following functions refer to string and
|
||||
* other kinds of literals, including doubles and RegExp objects. These
|
||||
* literals are vulnerable to garbage collection; to root script objects and
|
||||
* prevent literals from being collected, create a rootable object using
|
||||
* JS_NewScriptObject, and root the resulting object using JS_Add[Named]Root.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileScript(JSContext *cx, JSObject *obj,
|
||||
const char *bytes, size_t length,
|
||||
const char *filename, uintN lineno);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
const char *bytes, size_t length,
|
||||
const char *filename, uintN lineno);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
const char *bytes, size_t length,
|
||||
const char *filename, uintN lineno,
|
||||
JSVersion version);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileUCScript(JSContext *cx, JSObject *obj,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, uintN lineno);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, uintN lineno);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, uintN lineno,
|
||||
JSVersion version);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename,
|
||||
FILE *fh);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj,
|
||||
const char *filename, FILE *fh,
|
||||
JSPrincipals *principals);
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_CompileFileHandleForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
const char *filename, FILE *fh,
|
||||
JSPrincipals *principals,
|
||||
JSVersion version);
|
||||
|
||||
/*
|
||||
* NB: you must use JS_NewScriptObject and root a pointer to its return value
|
||||
* in order to keep a JSScript and its atoms safe from garbage collection after
|
||||
* creating the script via JS_Compile* and before a JS_ExecuteScript* call.
|
||||
* E.g., and without error checks:
|
||||
*
|
||||
* JSScript *script = JS_CompileFile(cx, global, filename);
|
||||
* JSObject *scrobj = JS_NewScriptObject(cx, script);
|
||||
* JS_AddNamedObjectRoot(cx, &scrobj, "scrobj");
|
||||
* do {
|
||||
* jsval result;
|
||||
* JS_ExecuteScript(cx, global, script, &result);
|
||||
* JS_GC();
|
||||
* } while (!JSVAL_IS_BOOLEAN(result) || JSVAL_TO_BOOLEAN(result));
|
||||
* JS_RemoveObjectRoot(cx, &scrobj);
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_NewScriptObject(JSContext *cx, JSScript *script);
|
||||
|
||||
/*
|
||||
* Infallible getter for a script's object. If JS_NewScriptObject has not been
|
||||
* called on script yet, the return value will be null.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_GetScriptObject(JSScript *script);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_DestroyScript(JSContext *cx, JSScript *script);
|
||||
|
||||
extern JS_PUBLIC_API(JSFunction *)
|
||||
JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
|
||||
uintN nargs, const char **argnames,
|
||||
@@ -2783,8 +2749,7 @@ JS_CompileUCFunctionForPrincipalsVersion(JSContext *cx, JSObject *obj,
|
||||
JSVersion version);
|
||||
|
||||
extern JS_PUBLIC_API(JSString *)
|
||||
JS_DecompileScript(JSContext *cx, JSScript *script, const char *name,
|
||||
uintN indent);
|
||||
JS_DecompileScriptObject(JSContext *cx, JSObject *scriptObj, const char *name, uintN indent);
|
||||
|
||||
/*
|
||||
* API extension: OR this into indent to avoid pretty-printing the decompiled
|
||||
@@ -2834,10 +2799,10 @@ JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent);
|
||||
* etc., entry points.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval);
|
||||
JS_ExecuteScript(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval,
|
||||
JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval,
|
||||
JSVersion version);
|
||||
|
||||
/*
|
||||
@@ -3780,28 +3745,6 @@ JS_SetContextThread(JSContext *cx);
|
||||
extern JS_PUBLIC_API(jsword)
|
||||
JS_ClearContextThread(JSContext *cx);
|
||||
|
||||
#ifdef MOZ_TRACE_JSCALLS
|
||||
typedef void (*JSFunctionCallback)(const JSFunction *fun,
|
||||
const JSScript *scr,
|
||||
const JSContext *cx,
|
||||
int entering);
|
||||
|
||||
/*
|
||||
* The callback is expected to be quick and noninvasive. It should not
|
||||
* trigger interrupts, turn on debugging, or produce uncaught JS
|
||||
* exceptions. The state of the stack and registers in the context
|
||||
* cannot be relied upon, since this callback may be invoked directly
|
||||
* from either JIT. The 'entering' field means we are entering a
|
||||
* function if it is positive, leaving a function if it is zero or
|
||||
* negative.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb);
|
||||
|
||||
extern JS_PUBLIC_API(JSFunctionCallback)
|
||||
JS_GetFunctionCallback(JSContext *cx);
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
@@ -91,7 +91,6 @@
|
||||
#include "jsbuiltins.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsversion.h"
|
||||
#include "jsdbgapi.h" /* for js_TraceWatchPoints */
|
||||
#include "jsfun.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsinterp.h"
|
||||
|
||||
@@ -158,7 +158,7 @@ JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, JSBool debug)
|
||||
// assumes that 'comp' is in the same thread as 'cx'.
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
JSAutoEnterCompartment ac;
|
||||
JS::AutoEnterScriptCompartment ac;
|
||||
|
||||
for (JSScript *script = (JSScript *)comp->scripts.next;
|
||||
&script->links != &comp->scripts;
|
||||
@@ -2669,3 +2669,20 @@ js_ShutdownEthogram(JSContext *cx, uintN argc, jsval *vp)
|
||||
}
|
||||
|
||||
#endif /* MOZ_TRACEVIS */
|
||||
|
||||
#ifdef MOZ_TRACE_JSCALLS
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb)
|
||||
{
|
||||
cx->functionCallback = fcb;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunctionCallback)
|
||||
JS_GetFunctionCallback(JSContext *cx)
|
||||
{
|
||||
return cx->functionCallback;
|
||||
}
|
||||
|
||||
#endif /* MOZ_TRACE_JSCALLS */
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
@@ -49,6 +49,42 @@
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
extern JS_PUBLIC_API(JSCrossCompartmentCall *)
|
||||
JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target);
|
||||
|
||||
#ifdef __cplusplus
|
||||
JS_END_EXTERN_C
|
||||
|
||||
namespace JS {
|
||||
|
||||
class JS_PUBLIC_API(AutoEnterScriptCompartment)
|
||||
{
|
||||
JSCrossCompartmentCall *call;
|
||||
|
||||
public:
|
||||
AutoEnterScriptCompartment() : call(NULL) {}
|
||||
|
||||
bool enter(JSContext *cx, JSScript *target);
|
||||
|
||||
bool entered() const { return call != NULL; }
|
||||
|
||||
~AutoEnterScriptCompartment() {
|
||||
if (call && call != reinterpret_cast<JSCrossCompartmentCall*>(1))
|
||||
JS_LeaveCrossCompartmentCall(call);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
#endif
|
||||
|
||||
extern JS_PUBLIC_API(JSScript *)
|
||||
JS_GetScriptFromObject(JSObject *scriptObject);
|
||||
|
||||
extern JS_PUBLIC_API(JSString *)
|
||||
JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, uintN indent);
|
||||
|
||||
/*
|
||||
* Currently, we only support runtime-wide debugging. In the future, we should
|
||||
* be able to support compartment-wide debugging.
|
||||
@@ -563,6 +599,28 @@ extern JS_FRIEND_API(JSBool)
|
||||
js_ShutdownEthogram(JSContext *cx, uintN argc, jsval *vp);
|
||||
#endif /* MOZ_TRACEVIS */
|
||||
|
||||
#ifdef MOZ_TRACE_JSCALLS
|
||||
typedef void (*JSFunctionCallback)(const JSFunction *fun,
|
||||
const JSScript *scr,
|
||||
const JSContext *cx,
|
||||
int entering);
|
||||
|
||||
/*
|
||||
* The callback is expected to be quick and noninvasive. It should not
|
||||
* trigger interrupts, turn on debugging, or produce uncaught JS
|
||||
* exceptions. The state of the stack and registers in the context
|
||||
* cannot be relied upon, since this callback may be invoked directly
|
||||
* from either JIT. The 'entering' field means we are entering a
|
||||
* function if it is positive, leaving a function if it is zero or
|
||||
* negative.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb);
|
||||
|
||||
extern JS_PUBLIC_API(JSFunctionCallback)
|
||||
JS_GetFunctionCallback(JSContext *cx);
|
||||
#endif /* MOZ_TRACE_JSCALLS */
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#endif /* jsdbgapi_h___ */
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsversion.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsexn.h"
|
||||
#include "jsfun.h"
|
||||
#include "jsinterp.h"
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
#include "jsbuiltins.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsversion.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsemit.h"
|
||||
#include "jsfun.h"
|
||||
#include "jsgc.h"
|
||||
|
||||
@@ -1053,6 +1053,12 @@ struct JSObject : js::gc::Cell {
|
||||
inline js::NativeIterator *getNativeIterator() const;
|
||||
inline void setNativeIterator(js::NativeIterator *);
|
||||
|
||||
/*
|
||||
* Script-related getters.
|
||||
*/
|
||||
|
||||
inline JSScript *getScript() const;
|
||||
|
||||
/*
|
||||
* XML-related getters and setters.
|
||||
*/
|
||||
@@ -1296,6 +1302,7 @@ struct JSObject : js::gc::Cell {
|
||||
inline bool isClonedBlock() const;
|
||||
inline bool isCall() const;
|
||||
inline bool isRegExp() const;
|
||||
inline bool isScript() const;
|
||||
inline bool isXML() const;
|
||||
inline bool isXMLId() const;
|
||||
inline bool isNamespace() const;
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsversion.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsemit.h"
|
||||
#include "jsfun.h"
|
||||
#include "jsiter.h"
|
||||
|
||||
@@ -85,6 +85,7 @@ typedef struct JSFunctionBox JSFunctionBox;
|
||||
typedef struct JSObjectBox JSObjectBox;
|
||||
typedef struct JSParseNode JSParseNode;
|
||||
typedef struct JSProperty JSProperty;
|
||||
typedef struct JSScript JSScript;
|
||||
typedef struct JSSharpObjectMap JSSharpObjectMap;
|
||||
typedef struct JSThread JSThread;
|
||||
typedef struct JSThreadData JSThreadData;
|
||||
|
||||
@@ -156,7 +156,6 @@ typedef struct JSPropertyDescriptor JSPropertyDescriptor;
|
||||
typedef struct JSPropertySpec JSPropertySpec;
|
||||
typedef struct JSObjectMap JSObjectMap;
|
||||
typedef struct JSRuntime JSRuntime;
|
||||
typedef struct JSScript JSScript;
|
||||
typedef struct JSStackFrame JSStackFrame;
|
||||
typedef struct JSXDRState JSXDRState;
|
||||
typedef struct JSExceptionState JSExceptionState;
|
||||
@@ -467,12 +466,6 @@ typedef void
|
||||
typedef JSBool
|
||||
(* JSOperationCallback)(JSContext *cx);
|
||||
|
||||
/*
|
||||
* Deprecated form of JSOperationCallback.
|
||||
*/
|
||||
typedef JSBool
|
||||
(* JSBranchCallback)(JSContext *cx, JSScript *script);
|
||||
|
||||
typedef void
|
||||
(* JSErrorReporter)(JSContext *cx, const char *message, JSErrorReport *report);
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ Bindings::trace(JSTracer *trc)
|
||||
shape->trace(trc);
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
} /* namespace js */
|
||||
|
||||
#if JS_HAS_XDR
|
||||
|
||||
@@ -1705,7 +1705,7 @@ js_TraceScript(JSTracer *trc, JSScript *script)
|
||||
script->bindings.trace(trc);
|
||||
}
|
||||
|
||||
JSBool
|
||||
JSObject *
|
||||
js_NewScriptObject(JSContext *cx, JSScript *script)
|
||||
{
|
||||
AutoScriptRooter root(cx, script);
|
||||
@@ -1714,7 +1714,7 @@ js_NewScriptObject(JSContext *cx, JSScript *script)
|
||||
|
||||
JSObject *obj = NewNonFunction<WithProto::Class>(cx, &js_ScriptClass, NULL, NULL);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
return NULL;
|
||||
obj->setPrivate(script);
|
||||
script->u.object = obj;
|
||||
|
||||
@@ -1728,7 +1728,7 @@ js_NewScriptObject(JSContext *cx, JSScript *script)
|
||||
script->owner = NULL;
|
||||
#endif
|
||||
|
||||
return JS_TRUE;
|
||||
return obj;
|
||||
}
|
||||
|
||||
typedef struct GSNCacheEntry {
|
||||
@@ -1973,7 +1973,7 @@ js_CloneScript(JSContext *cx, JSScript *script)
|
||||
// we don't want gecko to transcribe our principals for us
|
||||
DisablePrincipalsTranscoding disable(cx);
|
||||
|
||||
if (!JS_XDRScript(w, &script)) {
|
||||
if (!js_XDRScript(w, &script, NULL)) {
|
||||
JS_XDRDestroy(w);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1997,7 +1997,6 @@ js_CloneScript(JSContext *cx, JSScript *script)
|
||||
JS_XDRMemSetData(r, p, nbytes);
|
||||
JS_XDRMemSetData(w, NULL, 0);
|
||||
|
||||
// We can't use the public API because it makes a script object.
|
||||
if (!js_XDRScript(r, &script, NULL))
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -679,7 +679,7 @@ js_DestroyCachedScript(JSContext *cx, JSScript *script);
|
||||
extern void
|
||||
js_TraceScript(JSTracer *trc, JSScript *script);
|
||||
|
||||
extern JSBool
|
||||
extern JSObject *
|
||||
js_NewScriptObject(JSContext *cx, JSScript *script);
|
||||
|
||||
/*
|
||||
@@ -734,4 +734,17 @@ js_CloneScript(JSContext *cx, JSScript *script);
|
||||
extern JSBool
|
||||
js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic);
|
||||
|
||||
inline bool
|
||||
JSObject::isScript() const
|
||||
{
|
||||
return getClass() == &js_ScriptClass;
|
||||
}
|
||||
|
||||
inline JSScript *
|
||||
JSObject::getScript() const
|
||||
{
|
||||
JS_ASSERT(isScript());
|
||||
return static_cast<JSScript *>(getPrivate());
|
||||
}
|
||||
|
||||
#endif /* jsscript_h___ */
|
||||
|
||||
@@ -666,21 +666,29 @@ js_XDRAtom(JSXDRState *xdr, JSAtom **atomp)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_XDRScript(JSXDRState *xdr, JSScript **scriptp)
|
||||
JS_XDRScriptObject(JSXDRState *xdr, JSObject **scriptObjp)
|
||||
{
|
||||
if (!js_XDRScript(xdr, scriptp, NULL))
|
||||
return JS_FALSE;
|
||||
JSScript *script;
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
script = NULL;
|
||||
*scriptObjp = NULL;
|
||||
} else {
|
||||
script = (*scriptObjp)->getScript();
|
||||
}
|
||||
|
||||
if (!js_XDRScript(xdr, &script, NULL))
|
||||
return false;
|
||||
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
js_CallNewScriptHook(xdr->cx, *scriptp, NULL);
|
||||
if (!js_NewScriptObject(xdr->cx, *scriptp)) {
|
||||
js_DestroyScript(xdr->cx, *scriptp);
|
||||
*scriptp = NULL;
|
||||
return JS_FALSE;
|
||||
js_CallNewScriptHook(xdr->cx, script, NULL);
|
||||
*scriptObjp = js_NewScriptObject(xdr->cx, script);
|
||||
if (!*scriptObjp) {
|
||||
js_DestroyScript(xdr->cx, script);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define CLASS_REGISTRY_MIN 8
|
||||
|
||||
@@ -170,7 +170,7 @@ extern JS_PUBLIC_API(JSBool)
|
||||
JS_XDRValue(JSXDRState *xdr, jsval *vp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_XDRScript(JSXDRState *xdr, JSScript **scriptp);
|
||||
JS_XDRScriptObject(JSXDRState *xdr, JSObject **scriptObjp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp);
|
||||
|
||||
@@ -397,7 +397,7 @@ static void
|
||||
Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
|
||||
{
|
||||
JSBool ok, hitEOF;
|
||||
JSScript *script;
|
||||
JSObject *scriptObj;
|
||||
jsval result;
|
||||
JSString *str;
|
||||
char *buffer;
|
||||
@@ -446,10 +446,10 @@ Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
|
||||
int64 t1 = PRMJ_Now();
|
||||
oldopts = JS_GetOptions(cx);
|
||||
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
|
||||
script = JS_CompileFileHandle(cx, obj, filename, file);
|
||||
scriptObj = JS_CompileFileHandle(cx, obj, filename, file);
|
||||
JS_SetOptions(cx, oldopts);
|
||||
if (script && !compileOnly) {
|
||||
(void)JS_ExecuteScript(cx, obj, script, NULL);
|
||||
if (scriptObj && !compileOnly) {
|
||||
(void) JS_ExecuteScript(cx, obj, scriptObj, NULL);
|
||||
int64 t2 = PRMJ_Now() - t1;
|
||||
if (printTiming)
|
||||
printf("runtime = %.3f ms\n", double(t2) / PRMJ_USEC_PER_MSEC);
|
||||
@@ -535,13 +535,13 @@ Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
|
||||
oldopts = JS_GetOptions(cx);
|
||||
if (!compileOnly)
|
||||
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
|
||||
script = JS_CompileScript(cx, obj, buffer, len, "typein",
|
||||
scriptObj = JS_CompileScript(cx, obj, buffer, len, "typein",
|
||||
startline);
|
||||
if (!compileOnly)
|
||||
JS_SetOptions(cx, oldopts);
|
||||
|
||||
if (script && !compileOnly) {
|
||||
ok = JS_ExecuteScript(cx, obj, script, &result);
|
||||
if (scriptObj && !compileOnly) {
|
||||
ok = JS_ExecuteScript(cx, obj, scriptObj, &result);
|
||||
if (ok && !JSVAL_IS_VOID(result)) {
|
||||
str = JS_ValueToSource(cx, result);
|
||||
ok = !!str;
|
||||
@@ -1018,36 +1018,32 @@ Options(JSContext *cx, uintN argc, jsval *vp)
|
||||
static JSBool
|
||||
Load(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
uintN i;
|
||||
JSString *str;
|
||||
JSScript *script;
|
||||
uint32 oldopts;
|
||||
|
||||
JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
|
||||
if (!thisobj)
|
||||
return JS_FALSE;
|
||||
|
||||
jsval *argv = JS_ARGV(cx, vp);
|
||||
for (i = 0; i < argc; i++) {
|
||||
str = JS_ValueToString(cx, argv[i]);
|
||||
for (uintN i = 0; i < argc; i++) {
|
||||
JSString *str = JS_ValueToString(cx, argv[i]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
argv[i] = STRING_TO_JSVAL(str);
|
||||
JSAutoByteString filename(cx, str);
|
||||
if (!filename)
|
||||
return JS_FALSE;
|
||||
errno = 0;
|
||||
oldopts = JS_GetOptions(cx);
|
||||
uint32 oldopts = JS_GetOptions(cx);
|
||||
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
|
||||
script = JS_CompileFile(cx, thisobj, filename.ptr());
|
||||
if (!script)
|
||||
return JS_FALSE;
|
||||
JSObject *scriptObj = JS_CompileFile(cx, thisobj, filename.ptr());
|
||||
JS_SetOptions(cx, oldopts);
|
||||
if (!compileOnly && !JS_ExecuteScript(cx, thisobj, script, NULL))
|
||||
return JS_FALSE;
|
||||
if (!scriptObj)
|
||||
return false;
|
||||
|
||||
if (!compileOnly && !JS_ExecuteScript(cx, thisobj, scriptObj, NULL))
|
||||
return false;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@@ -1160,17 +1156,12 @@ Run(JSContext *cx, uintN argc, jsval *vp)
|
||||
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
|
||||
|
||||
int64 startClock = PRMJ_Now();
|
||||
JSScript *script = JS_CompileUCScript(cx, thisobj, ucbuf, buflen, filename.ptr(), 1);
|
||||
JSObject *scriptObj = JS_CompileUCScript(cx, thisobj, ucbuf, buflen, filename.ptr(), 1);
|
||||
JS_SetOptions(cx, oldopts);
|
||||
if (!script)
|
||||
if (!scriptObj || !JS_ExecuteScript(cx, thisobj, scriptObj, NULL))
|
||||
return false;
|
||||
|
||||
JSBool ok = JS_ExecuteScript(cx, thisobj, script, NULL);
|
||||
int64 endClock = PRMJ_Now();
|
||||
JS_DestroyScript(cx, script);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL((endClock - startClock) / double(PRMJ_USEC_PER_MSEC)));
|
||||
return true;
|
||||
}
|
||||
@@ -2257,7 +2248,6 @@ DisassFile(JSContext *cx, uintN argc, jsval *vp)
|
||||
argv += argc-1;
|
||||
argc = 1;
|
||||
|
||||
|
||||
JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
|
||||
if (!thisobj)
|
||||
return JS_FALSE;
|
||||
@@ -2271,16 +2261,12 @@ DisassFile(JSContext *cx, uintN argc, jsval *vp)
|
||||
|
||||
uint32 oldopts = JS_GetOptions(cx);
|
||||
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
|
||||
JSScript *script = JS_CompileFile(cx, thisobj, filename.ptr());
|
||||
JSObject *scriptObj = JS_CompileFile(cx, thisobj, filename.ptr());
|
||||
JS_SetOptions(cx, oldopts);
|
||||
if (!script)
|
||||
return JS_FALSE;
|
||||
if (!scriptObj)
|
||||
return false;
|
||||
|
||||
JSObject *obj = JS_NewScriptObject(cx, script);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
|
||||
argv[0] = OBJECT_TO_JSVAL(obj); /* I like to root it, root it. */
|
||||
argv[0] = OBJECT_TO_JSVAL(scriptObj);
|
||||
JSBool ok = Disassemble(cx, _argc, vp); /* gross, but works! */
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return ok;
|
||||
@@ -4318,10 +4304,10 @@ Compile(JSContext *cx, uintN argc, jsval *vp)
|
||||
}
|
||||
|
||||
JSString *scriptContents = JSVAL_TO_STRING(arg0);
|
||||
JSScript *result = JS_CompileUCScript(cx, NULL, JS_GetStringCharsZ(cx, scriptContents),
|
||||
JS_GetStringLength(scriptContents), "<string>", 0);
|
||||
if (!result)
|
||||
return JS_FALSE;
|
||||
if (!JS_CompileUCScript(cx, NULL, JS_GetStringCharsZ(cx, scriptContents),
|
||||
JS_GetStringLength(scriptContents), "<string>", 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
|
||||
@@ -895,13 +895,12 @@ class InitEvent : public Event
|
||||
if (!filename)
|
||||
return fail;
|
||||
|
||||
JSScript *script = JS_CompileFile(cx, child->getGlobal(), filename.ptr());
|
||||
if (!script)
|
||||
JSObject *scriptObj = JS_CompileFile(cx, child->getGlobal(), filename.ptr());
|
||||
if (!scriptObj)
|
||||
return fail;
|
||||
|
||||
AutoValueRooter rval(cx);
|
||||
JSBool ok = JS_ExecuteScript(cx, child->getGlobal(), script, Jsvalify(rval.addr()));
|
||||
JS_DestroyScript(cx, script);
|
||||
JSBool ok = JS_ExecuteScript(cx, child->getGlobal(), scriptObj, Jsvalify(rval.addr()));
|
||||
return Result(ok);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -346,9 +346,9 @@ ReportOnCaller(JSCLContextHelper &helper,
|
||||
#ifdef MOZ_ENABLE_LIBXUL
|
||||
static nsresult
|
||||
ReadScriptFromStream(JSContext *cx, nsIObjectInputStream *stream,
|
||||
JSScript **script)
|
||||
JSObject **scriptObj)
|
||||
{
|
||||
*script = nsnull;
|
||||
*scriptObj = nsnull;
|
||||
|
||||
PRUint32 size;
|
||||
nsresult rv = stream->Read32(&size);
|
||||
@@ -364,7 +364,7 @@ ReadScriptFromStream(JSContext *cx, nsIObjectInputStream *stream,
|
||||
xdr->userdata = stream;
|
||||
JS_XDRMemSetData(xdr, data, size);
|
||||
|
||||
if (!JS_XDRScript(xdr, script)) {
|
||||
if (!JS_XDRScriptObject(xdr, scriptObj)) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ ReadScriptFromStream(JSContext *cx, nsIObjectInputStream *stream,
|
||||
}
|
||||
|
||||
static nsresult
|
||||
WriteScriptToStream(JSContext *cx, JSScript *script,
|
||||
WriteScriptToStream(JSContext *cx, JSObject *scriptObj,
|
||||
nsIObjectOutputStream *stream)
|
||||
{
|
||||
JSXDRState *xdr = JS_XDRNewMem(cx, JSXDR_ENCODE);
|
||||
@@ -414,7 +414,7 @@ WriteScriptToStream(JSContext *cx, JSScript *script,
|
||||
xdr->userdata = stream;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (JS_XDRScript(xdr, &script)) {
|
||||
if (JS_XDRScriptObject(xdr, &scriptObj)) {
|
||||
// Get the encoded JSXDRState data and write it. The JSXDRState owns
|
||||
// this buffer memory and will free it beneath ::JS_XDRDestroy.
|
||||
//
|
||||
@@ -827,17 +827,6 @@ class JSPrincipalsHolder
|
||||
JSPrincipals *mPrincipals;
|
||||
};
|
||||
|
||||
class JSScriptHolder
|
||||
{
|
||||
public:
|
||||
JSScriptHolder(JSContext *cx, JSScript *script)
|
||||
: mCx(cx), mScript(script) {}
|
||||
~JSScriptHolder() { ::JS_DestroyScript(mCx, mScript); }
|
||||
private:
|
||||
JSContext *mCx;
|
||||
JSScript *mScript;
|
||||
};
|
||||
|
||||
/**
|
||||
* PathifyURI transforms mozilla .js uris into useful zip paths
|
||||
* to make it makes it easier to manipulate startup cache entries
|
||||
@@ -885,7 +874,7 @@ PathifyURI(nsIURI *in, nsACString &out)
|
||||
#ifdef MOZ_ENABLE_LIBXUL
|
||||
nsresult
|
||||
mozJSComponentLoader::ReadScript(StartupCache* cache, nsIURI *uri,
|
||||
JSContext *cx, JSScript **script)
|
||||
JSContext *cx, JSObject **scriptObj)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@@ -907,11 +896,11 @@ mozJSComponentLoader::ReadScript(StartupCache* cache, nsIURI *uri,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
buf.forget();
|
||||
|
||||
return ReadScriptFromStream(cx, ois, script);
|
||||
return ReadScriptFromStream(cx, ois, scriptObj);
|
||||
}
|
||||
|
||||
nsresult
|
||||
mozJSComponentLoader::WriteScript(StartupCache* cache, JSScript *script,
|
||||
mozJSComponentLoader::WriteScript(StartupCache* cache, JSObject *scriptObj,
|
||||
nsIFile *component, nsIURI *uri, JSContext *cx)
|
||||
{
|
||||
nsresult rv;
|
||||
@@ -927,7 +916,7 @@ mozJSComponentLoader::WriteScript(StartupCache* cache, JSScript *script,
|
||||
getter_AddRefs(storageStream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = WriteScriptToStream(cx, script, oos);
|
||||
rv = WriteScriptToStream(cx, scriptObj, oos);
|
||||
oos->Close();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@@ -1041,7 +1030,7 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
#endif
|
||||
|
||||
JSScript *script = nsnull;
|
||||
JSObject *scriptObj = nsnull;
|
||||
|
||||
#ifdef MOZ_ENABLE_LIBXUL
|
||||
// Before compiling the script, first check to see if we have it in
|
||||
@@ -1052,7 +1041,7 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
StartupCache* cache = StartupCache::GetSingleton();
|
||||
|
||||
if (cache) {
|
||||
rv = ReadScript(cache, aURI, cx, &script);
|
||||
rv = ReadScript(cache, aURI, cx, &scriptObj);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
LOG(("Successfully loaded %s from startupcache\n", nativePath.get()));
|
||||
} else {
|
||||
@@ -1064,7 +1053,7 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!script) {
|
||||
if (!scriptObj) {
|
||||
// The script wasn't in the cache , so compile it now.
|
||||
LOG(("Slow loading %s\n", nativePath.get()));
|
||||
|
||||
@@ -1125,7 +1114,7 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
script = JS_CompileScriptForPrincipalsVersion(
|
||||
scriptObj = JS_CompileScriptForPrincipalsVersion(
|
||||
cx, global, jsPrincipals, buf, fileSize32, nativePath.get(), 1,
|
||||
JSVERSION_LATEST);
|
||||
|
||||
@@ -1181,24 +1170,22 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
|
||||
buf[len] = '\0';
|
||||
|
||||
script = JS_CompileScriptForPrincipalsVersion(
|
||||
scriptObj = JS_CompileScriptForPrincipalsVersion(
|
||||
cx, global, jsPrincipals, buf, bytesRead, nativePath.get(), 1,
|
||||
JSVERSION_LATEST);
|
||||
}
|
||||
// Propagate the exception, if one exists. Also, don't leave the stale
|
||||
// exception on this context.
|
||||
// NB: The caller must stick exception into a rooted slot (probably on
|
||||
// its context) as soon as possible to avoid GC hazards.
|
||||
if (exception) {
|
||||
JS_SetOptions(cx, oldopts);
|
||||
if (!script) {
|
||||
if (!scriptObj) {
|
||||
JS_GetPendingException(cx, exception);
|
||||
JS_ClearPendingException(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!script) {
|
||||
if (!scriptObj) {
|
||||
#ifdef DEBUG_shaver_off
|
||||
fprintf(stderr, "mJCL: script compilation of %s FAILED\n",
|
||||
nativePath.get());
|
||||
@@ -1206,9 +1193,6 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Ensure that we clean up the script on return.
|
||||
JSScriptHolder scriptHolder(cx, script);
|
||||
|
||||
// Flag this script as a system script
|
||||
// FIXME: BUG 346139: We actually want to flag this exact filename, not
|
||||
// anything that starts with this filename... Maybe we need a way to do
|
||||
@@ -1225,7 +1209,7 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
#ifdef MOZ_ENABLE_LIBXUL
|
||||
if (writeToCache) {
|
||||
// We successfully compiled the script, so cache it.
|
||||
rv = WriteScript(cache, script, aComponentFile, aURI, cx);
|
||||
rv = WriteScript(cache, scriptObj, aComponentFile, aURI, cx);
|
||||
|
||||
// Don't treat failure to write as fatal, since we might be working
|
||||
// with a read-only cache.
|
||||
@@ -1242,7 +1226,7 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponentFile,
|
||||
*aGlobal = global;
|
||||
|
||||
jsval retval;
|
||||
if (!JS_ExecuteScriptVersion(cx, global, script, &retval, JSVERSION_LATEST)) {
|
||||
if (!JS_ExecuteScriptVersion(cx, global, scriptObj, &retval, JSVERSION_LATEST)) {
|
||||
#ifdef DEBUG_shaver_off
|
||||
fprintf(stderr, "mJCL: failed to execute %s\n", nativePath.get());
|
||||
#endif
|
||||
|
||||
@@ -135,8 +135,8 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
||||
|
||||
#ifdef MOZ_ENABLE_LIBXUL
|
||||
nsresult ReadScript(StartupCache *cache, nsIURI *uri,
|
||||
JSContext *cx, JSScript **script);
|
||||
nsresult WriteScript(StartupCache *cache, JSScript *script,
|
||||
JSContext *cx, JSObject **scriptObj);
|
||||
nsresult WriteScript(StartupCache *cache, JSObject *scriptObj,
|
||||
nsIFile *component, nsIURI *uri, JSContext *cx);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -462,47 +462,37 @@ Dump(JSContext *cx, uintN argc, jsval *vp)
|
||||
static JSBool
|
||||
Load(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
uintN i;
|
||||
JSString *str;
|
||||
JSScript *script;
|
||||
JSBool ok;
|
||||
jsval result;
|
||||
FILE *file;
|
||||
|
||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
|
||||
jsval *argv = JS_ARGV(cx, vp);
|
||||
for (i = 0; i < argc; i++) {
|
||||
str = JS_ValueToString(cx, argv[i]);
|
||||
for (uintN i = 0; i < argc; i++) {
|
||||
JSString *str = JS_ValueToString(cx, argv[i]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
argv[i] = STRING_TO_JSVAL(str);
|
||||
JSAutoByteString filename(cx, str);
|
||||
if (!filename)
|
||||
return JS_FALSE;
|
||||
file = fopen(filename.ptr(), "r");
|
||||
return false;
|
||||
FILE *file = fopen(filename.ptr(), "r");
|
||||
if (!file) {
|
||||
JS_ReportError(cx, "cannot open file '%s' for reading",
|
||||
filename.ptr());
|
||||
return JS_FALSE;
|
||||
return false;
|
||||
}
|
||||
script = JS_CompileFileHandleForPrincipals(cx, obj, filename.ptr(),
|
||||
JSObject *scriptObj = JS_CompileFileHandleForPrincipals(cx, obj, filename.ptr(),
|
||||
file, gJSPrincipals);
|
||||
fclose(file);
|
||||
if (!script)
|
||||
return JS_FALSE;
|
||||
if (!scriptObj)
|
||||
return false;
|
||||
|
||||
ok = !compileOnly
|
||||
? JS_ExecuteScript(cx, obj, script, &result)
|
||||
: JS_TRUE;
|
||||
JS_DestroyScript(cx, script);
|
||||
if (!ok)
|
||||
return JS_FALSE;
|
||||
jsval result;
|
||||
if (!compileOnly && !JS_ExecuteScript(cx, obj, scriptObj, &result))
|
||||
return false;
|
||||
}
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@@ -1046,7 +1036,7 @@ static void
|
||||
ProcessFile(JSContext *cx, JSObject *obj, const char *filename, FILE *file,
|
||||
JSBool forceTTY)
|
||||
{
|
||||
JSScript *script;
|
||||
JSObject *scriptObj;
|
||||
jsval result;
|
||||
int lineno, startline;
|
||||
JSBool ok, hitEOF;
|
||||
@@ -1079,14 +1069,11 @@ ProcessFile(JSContext *cx, JSObject *obj, const char *filename, FILE *file,
|
||||
ungetc(ch, file);
|
||||
DoBeginRequest(cx);
|
||||
|
||||
script = JS_CompileFileHandleForPrincipals(cx, obj, filename, file,
|
||||
scriptObj = JS_CompileFileHandleForPrincipals(cx, obj, filename, file,
|
||||
gJSPrincipals);
|
||||
|
||||
if (script) {
|
||||
if (!compileOnly)
|
||||
(void)JS_ExecuteScript(cx, obj, script, &result);
|
||||
JS_DestroyScript(cx, script);
|
||||
}
|
||||
if (scriptObj && !compileOnly)
|
||||
(void)JS_ExecuteScript(cx, obj, scriptObj, &result);
|
||||
DoEndRequest(cx);
|
||||
|
||||
return;
|
||||
@@ -1118,13 +1105,13 @@ ProcessFile(JSContext *cx, JSObject *obj, const char *filename, FILE *file,
|
||||
DoBeginRequest(cx);
|
||||
/* Clear any pending exception from previous failed compiles. */
|
||||
JS_ClearPendingException(cx);
|
||||
script = JS_CompileScriptForPrincipals(cx, obj, gJSPrincipals, buffer,
|
||||
scriptObj = JS_CompileScriptForPrincipals(cx, obj, gJSPrincipals, buffer,
|
||||
strlen(buffer), "typein", startline);
|
||||
if (script) {
|
||||
if (scriptObj) {
|
||||
JSErrorReporter older;
|
||||
|
||||
if (!compileOnly) {
|
||||
ok = JS_ExecuteScript(cx, obj, script, &result);
|
||||
ok = JS_ExecuteScript(cx, obj, scriptObj, &result);
|
||||
if (ok && result != JSVAL_VOID) {
|
||||
/* Suppress error reports from JS_ValueToString(). */
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
@@ -1137,7 +1124,6 @@ ProcessFile(JSContext *cx, JSObject *obj, const char *filename, FILE *file,
|
||||
ok = JS_FALSE;
|
||||
}
|
||||
}
|
||||
JS_DestroyScript(cx, script);
|
||||
}
|
||||
DoEndRequest(cx);
|
||||
} while (!hitEOF && !gQuitting);
|
||||
|
||||
@@ -160,7 +160,7 @@ XPCJSStackFrame::CreateStack(JSContext* cx, JSStackFrame* fp,
|
||||
jsbytecode* pc = JS_GetFramePC(cx, fp);
|
||||
if(script && pc)
|
||||
{
|
||||
JSAutoEnterCompartment ac;
|
||||
JS::AutoEnterScriptCompartment ac;
|
||||
if(ac.enter(cx, script))
|
||||
{
|
||||
const char* filename = JS_GetScriptFilename(cx, script);
|
||||
|
||||
@@ -99,8 +99,6 @@ Load(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
uintN i;
|
||||
JSString *str;
|
||||
JSScript *script;
|
||||
JSBool ok;
|
||||
jsval result;
|
||||
|
||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||
@@ -116,15 +114,9 @@ Load(JSContext *cx, uintN argc, jsval *vp)
|
||||
JSAutoByteString filename(cx, str);
|
||||
if (!filename)
|
||||
return false;
|
||||
script = JS_CompileFile(cx, obj, filename.ptr());
|
||||
if (!script)
|
||||
ok = JS_FALSE;
|
||||
else {
|
||||
ok = JS_ExecuteScript(cx, obj, script, &result);
|
||||
JS_DestroyScript(cx, script);
|
||||
}
|
||||
if (!ok)
|
||||
return JS_FALSE;
|
||||
JSObject *scriptObj = JS_CompileFile(cx, obj, filename.ptr());
|
||||
if (!scriptObj || !JS_ExecuteScript(cx, obj, scriptObj, &result))
|
||||
return false;
|
||||
}
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
|
||||
Reference in New Issue
Block a user