bug 630209 - (Compile|Execute)Script that are GC-safe. r=jorendorff

This commit is contained in:
Igor Bukanov
2011-02-03 14:06:21 +01:00
parent 19e73839b6
commit bb7edb5173
31 changed files with 422 additions and 558 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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));

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
/************************************************************************/
/*

View File

@@ -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"

View File

@@ -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 */

View File

@@ -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___ */

View File

@@ -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"

View File

@@ -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"

View File

@@ -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;

View File

@@ -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"

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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___ */

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}
};

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;