1 diff --git a/js/jsd/jsd_xpc.cpp b/js/jsd/jsd_xpc.cpp
2 --- a/js/jsd/jsd_xpc.cpp
3 +++ b/js/jsd/jsd_xpc.cpp
4 @@ -1037,17 +1037,17 @@ PCMapEntry *
5 jsdScript::CreatePPLineMap()
7 JSContext *cx = JSD_GetDefaultJSContext (mCx);
9 JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
10 JSFunction *fun = JSD_GetJSFunction (mCx, mScript);
11 JSScript *script; /* In JSD compartment */
13 - PRBool scriptOwner = PR_FALSE;
14 + JSObject *scriptObj = NULL;
23 @@ -1075,36 +1075,40 @@ jsdScript::CreatePPLineMap()
24 if (!fun || !(script = JS_GetFunctionScript(cx, fun)))
28 script = JSD_GetJSScript(mCx, mScript);
32 - JSAutoEnterCompartment ac;
33 + JS::AutoEnterScriptCompartment ac;
34 if (!ac.enter(cx, script))
37 - jsstr = JS_DecompileScript (cx, JSD_GetJSScript(mCx, mScript), "ppscript", 4);
38 + jsstr = JS_DecompileScript (cx, script, "ppscript", 4);
42 if (!(chars = JS_GetStringCharsAndLength(cx, jsstr, &length)))
46 JS::Anchor<JSString *> kungFuDeathGrip(jsstr);
47 - script = JS_CompileUCScript (cx, obj, chars, length, "x-jsd:ppbuffer?type=script", 1);
49 + scriptObj = JS_CompileUCScript (cx, obj, chars, length, "x-jsd:ppbuffer?type=script", 1);
52 - scriptOwner = PR_TRUE;
53 + script = JS_GetScriptFromObject(scriptObj);
57 + /* Make sure that a non-function script is rooted via scriptObj until the
58 + * end of script usage. */
59 + JS::Anchor<JSObject *> scriptAnchor(scriptObj);
61 PRUint32 scriptExtent = JS_GetScriptLineExtent (cx, script);
62 jsbytecode* firstPC = JS_LineNumberToPC (cx, script, 0);
63 /* allocate worst case size of map (number of lines in script + 1
64 * for our 0 record), we'll shrink it with a realloc later. */
66 static_cast<PCMapEntry *>
67 (PR_Malloc((scriptExtent + 1) * sizeof (PCMapEntry)));
68 PRUint32 lineMapSize = 0;
69 @@ -1125,19 +1129,16 @@ jsdScript::CreatePPLineMap()
70 lineMapSize * sizeof(PCMapEntry)));
79 - JS_DestroyScript (cx, script);
81 mPCMapSize = lineMapSize;
82 return mPPLineMap = lineMap;
86 jsdScript::PPPcToLine (PRUint32 aPC)
88 if (!mPPLineMap && !CreatePPLineMap())
89 @@ -1182,17 +1183,17 @@ jsdScript::GetJSDScript(JSDScript **_rva
93 jsdScript::GetVersion (PRInt32 *_rval)
95 ASSERT_VALID_EPHEMERAL;
96 JSContext *cx = JSD_GetDefaultJSContext (mCx);
97 JSScript *script = JSD_GetJSScript(mCx, mScript);
98 - JSAutoEnterCompartment ac;
99 + JS::AutoEnterScriptCompartment ac;
100 if (!ac.enter(cx, script))
101 return NS_ERROR_FAILURE;
102 *_rval = static_cast<PRInt32>(JS_GetScriptVersion(cx, script));
107 jsdScript::GetTag(PRUint32 *_rval)
108 @@ -1378,23 +1379,24 @@ jsdScript::GetFunctionSource(nsAString &
109 return NS_ERROR_FAILURE;
111 JSFunction *fun = JSD_GetJSFunction (mCx, mScript);
113 JSAutoRequest ar(cx);
116 JSAutoEnterCompartment ac;
117 + JS::AutoEnterScriptCompartment asc;
119 if (!ac.enter(cx, JS_GetFunctionObject(fun)))
120 return NS_ERROR_FAILURE;
121 jsstr = JS_DecompileFunction (cx, fun, 4);
123 JSScript *script = JSD_GetJSScript (mCx, mScript);
124 - if (!ac.enter(cx, script))
125 + if (!asc.enter(cx, script))
126 return NS_ERROR_FAILURE;
127 jsstr = JS_DecompileScript (cx, script, "ppscript", 4);
130 return NS_ERROR_FAILURE;
133 const jschar *chars = JS_GetStringCharsZAndLength(cx, jsstr, &length);
134 diff --git a/js/src/jsapi-tests/testScriptObject.cpp b/js/src/jsapi-tests/testScriptObject.cpp
135 --- a/js/src/jsapi-tests/testScriptObject.cpp
136 +++ b/js/src/jsapi-tests/testScriptObject.cpp
137 @@ -10,41 +10,25 @@ struct ScriptObjectFixture : public JSAP
138 static jschar uc_code[];
140 ScriptObjectFixture()
142 for (int i = 0; i < code_size; i++)
143 uc_code[i] = code[i];
146 - bool tryScript(JSScript *script)
147 + bool tryScript(JSObject *scriptObj)
151 - /* We should have allocated a script object for the script already. */
152 - jsvalRoot script_object(cx, OBJECT_TO_JSVAL(JS_GetScriptObject(script)));
153 - CHECK(JSVAL_TO_OBJECT(script_object.value()));
156 - * JS_NewScriptObject just returns the object already created for the
157 - * script. It was always a bug to call this more than once.
159 - jsvalRoot second_script_object
160 - (cx, OBJECT_TO_JSVAL(JS_NewScriptObject(cx, script)));
161 - CHECK_SAME(second_script_object.value(), script_object.value());
166 /* After a garbage collection, the script should still work. */
168 - CHECK(JS_ExecuteScript(cx, global, script, &result));
170 - /* JS_DestroyScript must still be safe to call, whether or not it
171 - actually has any effect. */
172 - JS_DestroyScript(cx, script);
173 + CHECK(JS_ExecuteScript(cx, global, scriptObj, &result));
179 const char ScriptObjectFixture::code[] =
180 "(function(a, b){return a+' '+b;}('hello', 'world'))";
181 const int ScriptObjectFixture::code_size = sizeof(ScriptObjectFixture::code) - 1;
182 @@ -98,31 +82,31 @@ END_FIXTURE_TEST(ScriptObjectFixture, bu
184 BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile)
187 static const char script_filename[] = "temp-bug438633_JS_CompileFile";
188 FILE *script_stream = tempScript.open(script_filename);
189 CHECK(fputs(code, script_stream) != EOF);
191 - JSScript *script = JS_CompileFile(cx, global, script_filename);
192 + JSObject *scriptObj = JS_CompileFile(cx, global, script_filename);
194 - return tryScript(script);
195 + return tryScript(scriptObj);
197 END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile)
199 BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile_empty)
202 static const char script_filename[] = "temp-bug438633_JS_CompileFile_empty";
203 tempScript.open(script_filename);
205 - JSScript *script = JS_CompileFile(cx, global, script_filename);
206 + JSObject *scriptObj = JS_CompileFile(cx, global, script_filename);
208 - return tryScript(script);
209 + return tryScript(scriptObj);
211 END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile_empty)
213 BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandle)
216 FILE *script_stream = tempScript.open("temp-bug438633_JS_CompileFileHandle");
217 CHECK(fputs(code, script_stream) != EOF);
218 @@ -147,24 +131,8 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture,
219 FILE *script_stream = tempScript.open("temp-bug438633_JS_CompileFileHandleForPrincipals");
220 CHECK(fputs(code, script_stream) != EOF);
221 CHECK(fseek(script_stream, 0, SEEK_SET) != EOF);
222 return tryScript(JS_CompileFileHandleForPrincipals(cx, global,
224 script_stream, NULL));
226 END_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFileHandleForPrincipals)
228 -BEGIN_TEST(testScriptObject_ScriptlessScriptObjects)
230 - /* JS_NewScriptObject(cx, NULL) should return a fresh object each time. */
231 - jsvalRoot script_object1(cx, OBJECT_TO_JSVAL(JS_NewScriptObject(cx, NULL)));
232 - CHECK(!JSVAL_IS_PRIMITIVE(script_object1.value()));
234 - jsvalRoot script_object2(cx, OBJECT_TO_JSVAL(JS_NewScriptObject(cx, NULL)));
235 - CHECK(!JSVAL_IS_PRIMITIVE(script_object2.value()));
237 - if (script_object1.value() == script_object2.value())
242 -END_TEST(testScriptObject_ScriptlessScriptObjects)
243 diff --git a/js/src/jsapi-tests/testTrap.cpp b/js/src/jsapi-tests/testTrap.cpp
244 --- a/js/src/jsapi-tests/testTrap.cpp
245 +++ b/js/src/jsapi-tests/testTrap.cpp
246 @@ -25,52 +25,56 @@ BEGIN_TEST(testTrap_gc)
251 "({ result: sum });\n"
255 - JSScript *script = JS_CompileScript(cx, global, source, strlen(source), __FILE__, 1);
257 - JSObject *scrobj = JS_NewScriptObject(cx, script);
259 - jsvalRoot v(cx, OBJECT_TO_JSVAL(scrobj));
260 + JSObject *scriptObj = JS_CompileScript(cx, global, source, strlen(source), __FILE__, 1);
265 - CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
266 + CHECK(JS_ExecuteScript(cx, global, scriptObj, v2.addr()));
267 CHECK(JSVAL_IS_OBJECT(v2));
268 CHECK(emptyTrapCallCount == 0);
270 // Disable JIT for debugging
271 JS_SetOptions(cx, JS_GetOptions(cx) & ~JSOPTION_JIT);
274 CHECK(JS_SetDebugMode(cx, JS_TRUE));
276 - jsbytecode *line2 = JS_LineNumberToPC(cx, script, 1);
278 + static const char trapClosureText[] = "some trap closure";
280 - jsbytecode *line6 = JS_LineNumberToPC(cx, script, 5);
283 - static const char trapClosureText[] = "some trap closure";
284 - JSString *trapClosure = JS_NewStringCopyZ(cx, trapClosureText);
285 - CHECK(trapClosure);
286 - JS_SetTrap(cx, script, line2, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
287 - JS_SetTrap(cx, script, line6, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
291 - CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
292 + // scope JSScript usage to make sure that it is not used after
293 + // JS_ExecuteScript. This way we avoid using Anchor.
294 + JSString *trapClosure;
296 + JSScript *script = JS_GetScriptFromObject(scriptObj);
297 + jsbytecode *line2 = JS_LineNumberToPC(cx, script, 1);
300 + jsbytecode *line6 = JS_LineNumberToPC(cx, script, 5);
303 + trapClosure = JS_NewStringCopyZ(cx, trapClosureText);
304 + CHECK(trapClosure);
305 + JS_SetTrap(cx, script, line2, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
306 + JS_SetTrap(cx, script, line6, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
310 + CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
314 - CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
315 + CHECK(JS_ExecuteScript(cx, global, scriptObj, v2.addr()));
316 CHECK(emptyTrapCallCount == 11);
320 CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
324 diff --git a/js/src/jsapi-tests/testVersion.cpp b/js/src/jsapi-tests/testVersion.cpp
325 --- a/js/src/jsapi-tests/testVersion.cpp
326 +++ b/js/src/jsapi-tests/testVersion.cpp
327 @@ -36,17 +36,17 @@ struct VersionFixture : public JSAPITest
328 JS_DefineFunction(cx, global, "checkNewScriptNoXML", CheckNewScriptNoXML, 0, 0) &&
329 JS_DefineFunction(cx, global, "overrideVersion15", OverrideVersion15, 0, 0) &&
330 JS_DefineFunction(cx, global, "captureVersion", CaptureVersion, 0, 0) &&
331 JS_DefineFunction(cx, global, "checkOverride", CheckOverride, 1, 0) &&
332 JS_DefineFunction(cx, global, "evalScriptVersion16",
333 EvalScriptVersion16, 0, 0);
336 - JSScript *fakeScript(const char *contents, size_t length) {
337 + JSObject *fakeScript(const char *contents, size_t length) {
338 return JS_CompileScript(cx, global, contents, length, "<test>", 1);
341 bool hasXML(uintN version) {
342 return VersionHasXML(JSVersion(version));
345 bool hasXML(JSScript *script) {
346 @@ -69,19 +69,19 @@ struct VersionFixture : public JSAPITest
348 bool checkVersionIsOverridden() {
349 CHECK(cx->isVersionOverridden());
353 /* Check that script compilation results in a version without XML. */
354 bool checkNewScriptNoXML() {
355 - JSScript *script = fakeScript("", 0);
357 - CHECK(!hasXML(script->getVersion()));
358 + JSObject *scriptObj = fakeScript("", 0);
360 + CHECK(!hasXML(JS_GetScriptFromObject(scriptObj)->getVersion()));
364 bool checkVersionHasXML() {
365 CHECK(VersionHasXML(cx->findVersion()));
369 @@ -190,25 +190,22 @@ BEGIN_FIXTURE_TEST(VersionFixture, testO
371 /* Enable XML and compile a script to activate. */
373 const char toActivateChars[] =
374 "checkVersionHasXML();"
375 "disableXMLOption();"
376 "callSetVersion17();"
377 "checkNewScriptNoXML();";
378 - JSScript *toActivate = fakeScript(toActivateChars, sizeof(toActivateChars) - 1);
379 + JSObject *toActivate = fakeScript(toActivateChars, sizeof(toActivateChars) - 1);
381 - JSObject *scriptObject = JS_GetScriptObject(toActivate);
382 - CHECK(hasXML(toActivate));
383 + CHECK(hasXML(JS_GetScriptFromObject(toActivate)));
387 - CHECK(scriptObject);
389 /* Activate the script. */
391 CHECK(JS_ExecuteScript(cx, global, toActivate, &dummy));
394 END_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags)
397 diff --git a/js/src/jsapi-tests/testXDR.cpp b/js/src/jsapi-tests/testXDR.cpp
398 --- a/js/src/jsapi-tests/testXDR.cpp
399 +++ b/js/src/jsapi-tests/testXDR.cpp
400 @@ -11,87 +11,75 @@ BEGIN_TEST(testXDR_bug506491)
402 "function makeClosure(s, name, value) {\n"
404 " return let (n = name, v = value) function () { return String(v); };\n"
406 "var f = makeClosure('0;', 'status', 'ok');\n";
409 - JSScript *script = JS_CompileScript(cx, global, s, strlen(s), __FILE__, __LINE__);
411 - JSObject *scrobj = JS_NewScriptObject(cx, script);
413 - jsvalRoot v(cx, OBJECT_TO_JSVAL(scrobj));
414 + JSObject *scriptObj = JS_CompileScript(cx, global, s, strlen(s), __FILE__, __LINE__);
418 JSXDRState *w = JS_XDRNewMem(cx, JSXDR_ENCODE);
420 - CHECK(JS_XDRScript(w, &script));
421 + CHECK(JS_XDRScriptObject(w, &scriptObj));
423 void *p = JS_XDRMemGetData(w, &nbytes);
425 void *frozen = JS_malloc(cx, nbytes);
427 memcpy(frozen, p, nbytes);
433 JSXDRState *r = JS_XDRNewMem(cx, JSXDR_DECODE);
434 JS_XDRMemSetData(r, frozen, nbytes);
435 - CHECK(JS_XDRScript(r, &script));
436 + CHECK(JS_XDRScriptObject(r, &scriptObj));
437 JS_XDRDestroy(r); // this frees `frozen`
438 - scrobj = JS_NewScriptObject(cx, script);
440 - v = OBJECT_TO_JSVAL(scrobj);
444 - CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
445 + CHECK(JS_ExecuteScript(cx, global, scriptObj, v2.addr()));
447 // try to break the Block object that is the parent of f
451 EVAL("f() === 'ok';\n", v2.addr());
452 jsvalRoot trueval(cx, JSVAL_TRUE);
453 CHECK_SAME(v2, trueval);
456 END_TEST(testXDR_bug506491)
458 BEGIN_TEST(testXDR_bug516827)
460 // compile an empty script
461 - JSScript *script = JS_CompileScript(cx, global, "", 0, __FILE__, __LINE__);
463 - JSObject *scrobj = JS_NewScriptObject(cx, script);
465 - jsvalRoot v(cx, OBJECT_TO_JSVAL(scrobj));
466 + JSObject *scriptObj = JS_CompileScript(cx, global, "", 0, __FILE__, __LINE__);
470 JSXDRState *w = JS_XDRNewMem(cx, JSXDR_ENCODE);
472 - CHECK(JS_XDRScript(w, &script));
473 + CHECK(JS_XDRScriptObject(w, &scriptObj));
475 void *p = JS_XDRMemGetData(w, &nbytes);
477 void *frozen = JS_malloc(cx, nbytes);
479 memcpy(frozen, p, nbytes);
485 JSXDRState *r = JS_XDRNewMem(cx, JSXDR_DECODE);
486 JS_XDRMemSetData(r, frozen, nbytes);
487 - CHECK(JS_XDRScript(r, &script));
488 + CHECK(JS_XDRScriptObject(r, &scriptObj));
489 JS_XDRDestroy(r); // this frees `frozen`
490 - scrobj = JS_NewScriptObject(cx, script);
492 - v = OBJECT_TO_JSVAL(scrobj);
494 // execute with null result meaning no result wanted
495 - CHECK(JS_ExecuteScript(cx, global, script, NULL));
496 + CHECK(JS_ExecuteScript(cx, global, scriptObj, NULL));
499 END_TEST(testXDR_bug516827)
500 diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
501 --- a/js/src/jsapi.cpp
502 +++ b/js/src/jsapi.cpp
506 #include "jsregexp.h"
509 #include "jsscript.h"
511 #include "jstracer.h"
512 -#include "jsdbgapi.h"
513 #include "prmjtime.h"
514 #include "jsstaticcheck.h"
515 #include "jsvector.h"
516 #include "jswrapper.h"
517 #include "jstypedarray.h"
519 #include "jsatominlines.h"
520 #include "jscntxtinlines.h"
521 @@ -107,26 +106,16 @@
523 #if JS_HAS_XML_SUPPORT
528 using namespace js::gc;
530 -static JSClass dummy_class = {
532 - JSCLASS_GLOBAL_FLAGS,
533 - JS_PropertyStub, JS_PropertyStub,
534 - JS_PropertyStub, JS_StrictPropertyStub,
535 - JS_EnumerateStub, JS_ResolveStub,
536 - JS_ConvertStub, NULL,
537 - JSCLASS_NO_OPTIONAL_MEMBERS
541 * This class is a version-establising barrier at the head of a VM entry or
542 * re-entry. It ensures that:
544 * - |newVersion| is the starting (default) version used for the context.
545 * - The starting version state is not an override.
546 * - Overrides in the VM session are not propagated to the caller.
548 @@ -1187,16 +1176,26 @@ JS_EnterCrossCompartmentCall(JSContext *
551 return reinterpret_cast<JSCrossCompartmentCall *>(call);
554 JS_PUBLIC_API(JSCrossCompartmentCall *)
555 JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target)
557 + static JSClass dummy_class = {
559 + JSCLASS_GLOBAL_FLAGS,
560 + JS_PropertyStub, JS_PropertyStub,
561 + JS_PropertyStub, JS_StrictPropertyStub,
562 + JS_EnumerateStub, JS_ResolveStub,
563 + JS_ConvertStub, NULL,
564 + JSCLASS_NO_OPTIONAL_MEMBERS
570 JSObject *scriptObject = target->u.object;
572 SwitchToCompartment sc(cx, target->compartment);
573 scriptObject = JS_NewGlobalObject(cx, &dummy_class);
575 @@ -1221,33 +1220,37 @@ JSAutoEnterCompartment::enter(JSContext
576 if (cx->compartment == target->getCompartment()) {
577 call = reinterpret_cast<JSCrossCompartmentCall*>(1);
580 call = JS_EnterCrossCompartmentCall(cx, target);
585 +JSAutoEnterCompartment::enterAndIgnoreErrors(JSContext *cx, JSObject *target)
587 + (void) enter(cx, target);
593 -JSAutoEnterCompartment::enter(JSContext *cx, JSScript *target)
594 +AutoEnterScriptCompartment::enter(JSContext *cx, JSScript *target)
597 if (cx->compartment == target->compartment) {
598 call = reinterpret_cast<JSCrossCompartmentCall*>(1);
601 call = JS_EnterCrossCompartmentCallScript(cx, target);
606 -JSAutoEnterCompartment::enterAndIgnoreErrors(JSContext *cx, JSObject *target)
608 - (void) enter(cx, target);
610 +} /* namespace JS */
612 JS_PUBLIC_API(void *)
613 JS_SetCompartmentPrivate(JSContext *cx, JSCompartment *compartment, void *data)
616 void *old = compartment->data;
617 compartment->data = data;
619 @@ -2181,16 +2184,21 @@ JS_RemoveObjectRoot(JSContext *cx, JSObj
621 JS_PUBLIC_API(JSBool)
622 JS_RemoveGCThingRoot(JSContext *cx, void **rp)
625 return js_RemoveRoot(cx->runtime, (void *)rp);
628 +JS_NEVER_INLINE JS_PUBLIC_API(void)
629 +JS_AnchorPtr(void *p)
636 JS_DumpNamedRoots(JSRuntime *rt,
637 void (*dump)(const char *name, void *rp, JSGCRootType type, void *data),
640 js_DumpNamedRoots(rt, dump, data);
641 @@ -4510,94 +4518,97 @@ LAST_FRAME_CHECKS(JSContext *cx, bool re
644 JS_OPTIONS_TO_TCFLAGS(JSContext *cx)
646 return (cx->hasRunOption(JSOPTION_COMPILE_N_GO) ? TCF_COMPILE_N_GO : 0) |
647 (cx->hasRunOption(JSOPTION_NO_SCRIPT_RVAL) ? TCF_NO_SCRIPT_RVAL : 0);
652 CompileUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj, JSPrincipals *principals,
653 const jschar *chars, size_t length,
654 const char *filename, uintN lineno, JSVersion version)
656 JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
658 assertSameCompartment(cx, obj, principals);
660 uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT;
661 JSScript *script = Compiler::compileScript(cx, obj, NULL, principals, tcflags,
662 chars, length, filename, lineno, version);
663 - if (script && !js_NewScriptObject(cx, script)) {
664 - js_DestroyScript(cx, script);
666 + JSObject *scriptObj = NULL;
668 + scriptObj = js_NewScriptObject(cx, script);
670 + js_DestroyScript(cx, script);
672 - LAST_FRAME_CHECKS(cx, script);
676 -extern JS_PUBLIC_API(JSScript *)
677 + LAST_FRAME_CHECKS(cx, scriptObj);
681 +extern JS_PUBLIC_API(JSObject *)
682 JS_CompileUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
683 JSPrincipals *principals,
684 const jschar *chars, size_t length,
685 const char *filename, uintN lineno,
688 AutoVersionAPI avi(cx, version);
689 return CompileUCScriptForPrincipalsCommon(cx, obj, principals, chars, length, filename, lineno,
693 -JS_PUBLIC_API(JSScript *)
694 +JS_PUBLIC_API(JSObject *)
695 JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj, JSPrincipals *principals,
696 const jschar *chars, size_t length,
697 const char *filename, uintN lineno)
699 return CompileUCScriptForPrincipalsCommon(cx, obj, principals, chars, length, filename, lineno,
703 -JS_PUBLIC_API(JSScript *)
704 +JS_PUBLIC_API(JSObject *)
705 JS_CompileUCScript(JSContext *cx, JSObject *obj, const jschar *chars, size_t length,
706 const char *filename, uintN lineno)
708 JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
709 return JS_CompileUCScriptForPrincipals(cx, obj, NULL, chars, length, filename, lineno);
712 -JS_PUBLIC_API(JSScript *)
713 +JS_PUBLIC_API(JSObject *)
714 JS_CompileScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
715 JSPrincipals *principals,
716 const char *bytes, size_t length,
717 const char *filename, uintN lineno,
720 AutoVersionAPI ava(cx, version);
721 return JS_CompileScriptForPrincipals(cx, obj, principals, bytes, length, filename, lineno);
724 -JS_PUBLIC_API(JSScript *)
725 +JS_PUBLIC_API(JSObject *)
726 JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
727 JSPrincipals *principals,
728 const char *bytes, size_t length,
729 const char *filename, uintN lineno)
731 JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
734 jschar *chars = js_InflateString(cx, bytes, &length);
737 - JSScript *script = JS_CompileUCScriptForPrincipals(cx, obj, principals, chars, length, filename, lineno);
738 + JSObject *scriptObj =
739 + JS_CompileUCScriptForPrincipals(cx, obj, principals, chars, length, filename, lineno);
744 -JS_PUBLIC_API(JSScript *)
748 +JS_PUBLIC_API(JSObject *)
749 JS_CompileScript(JSContext *cx, JSObject *obj, const char *bytes, size_t length,
750 const char *filename, uintN lineno)
752 JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
753 return JS_CompileScriptForPrincipals(cx, obj, NULL, bytes, length, filename, lineno);
756 JS_PUBLIC_API(JSBool)
757 @@ -4645,18 +4656,18 @@ JS_BufferIsCompilableUnit(JSContext *cx,
758 #if defined(HAVE_GETC_UNLOCKED)
759 # define fast_getc getc_unlocked
760 #elif defined(HAVE__GETC_NOLOCK)
761 # define fast_getc _getc_nolock
763 # define fast_getc getc
767 -CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals, uint32 tcflags,
769 +CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals,
770 const char* filename, FILE *fp)
773 int ok = fstat(fileno(fp), &st);
778 @@ -4667,165 +4678,122 @@ CompileFileHelper(JSContext *cx, JSObjec
779 /* Read in the whole file, then compile it. */
782 len = 8; /* start with a small buffer, expand as necessary */
787 - jschar* tmpbuf = (jschar *) cx->realloc(buf, len * sizeof(jschar));
788 + jschar* tmpbuf = (jschar *) js_realloc(buf, len * sizeof(jschar));
801 buf[i++] = (jschar) (unsigned char) c;
805 - buf = (jschar *) cx->malloc(len * sizeof(jschar));
806 + buf = (jschar *) js_malloc(len * sizeof(jschar));
811 while ((c = fast_getc(fp)) != EOF)
812 buf[i++] = (jschar) (unsigned char) c;
817 + uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT;
818 script = Compiler::compileScript(cx, obj, NULL, principals, tcflags, buf, len, filename, 1,
824 -JS_PUBLIC_API(JSScript *)
829 + JSObject *scriptObj = js_NewScriptObject(cx, script);
831 + js_DestroyScript(cx, script);
836 +JS_PUBLIC_API(JSObject *)
837 JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename)
839 JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
845 assertSameCompartment(cx, obj);
846 - if (!filename || strcmp(filename, "-") == 0) {
849 - fp = fopen(filename, "r");
851 - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN,
852 - filename, "No such file or directory");
854 + JSObject *scriptObj = NULL;
857 + if (!filename || strcmp(filename, "-") == 0) {
860 + fp = fopen(filename, "r");
862 + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN,
863 + filename, "No such file or directory");
869 - tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT;
870 - script = CompileFileHelper(cx, obj, NULL, tcflags, filename, fp);
874 - if (script && !js_NewScriptObject(cx, script)) {
875 - js_DestroyScript(cx, script);
878 - LAST_FRAME_CHECKS(cx, script);
882 -JS_PUBLIC_API(JSScript *)
883 -JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj, const char *filename, FILE *file,
884 - JSPrincipals *principals)
886 + scriptObj = CompileFileHelper(cx, obj, NULL, filename, fp);
891 + LAST_FRAME_CHECKS(cx, scriptObj);
895 +JS_PUBLIC_API(JSObject *)
896 +JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj, const char *filename,
897 + FILE *file, JSPrincipals *principals)
899 JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
904 assertSameCompartment(cx, obj, principals);
905 - tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT;
906 - script = CompileFileHelper(cx, obj, principals, tcflags, filename, file);
908 - if (script && !js_NewScriptObject(cx, script)) {
909 - js_DestroyScript(cx, script);
912 - LAST_FRAME_CHECKS(cx, script);
916 -JS_PUBLIC_API(JSScript *)
917 + JSObject *scriptObj = CompileFileHelper(cx, obj, principals, filename, file);
918 + LAST_FRAME_CHECKS(cx, scriptObj);
922 +JS_PUBLIC_API(JSObject *)
923 JS_CompileFileHandleForPrincipalsVersion(JSContext *cx, JSObject *obj, const char *filename,
924 FILE *file, JSPrincipals *principals, JSVersion version)
926 AutoVersionAPI ava(cx, version);
927 return JS_CompileFileHandleForPrincipals(cx, obj, filename, file, principals);
930 -JS_PUBLIC_API(JSScript *)
931 +JS_PUBLIC_API(JSObject *)
932 JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename, FILE *file)
934 JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
935 return JS_CompileFileHandleForPrincipals(cx, obj, filename, file, NULL);
938 -JS_PUBLIC_API(JSObject *)
939 -JS_NewScriptObject(JSContext *cx, JSScript *script)
941 - JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
943 - assertSameCompartment(cx, script);
945 - return NewNonFunction<WithProto::Class>(cx, &js_ScriptClass, NULL, NULL);
948 - * This function should only ever be applied to JSScripts that had
949 - * script objects allocated for them when they were created, as
950 - * described in the comment for JSScript::u.object.
952 - JS_ASSERT(script->u.object);
953 - return script->u.object;
956 -JS_PUBLIC_API(JSObject *)
957 -JS_GetScriptObject(JSScript *script)
960 - * This function should only ever be applied to JSScripts that had
961 - * script objects allocated for them when they were created, as
962 - * described in the comment for JSScript::u.object.
964 - JS_ASSERT(script->u.object);
965 - return script->u.object;
969 -JS_DestroyScript(JSContext *cx, JSScript *script)
974 - * Originally, JSScript lifetimes were managed explicitly, and this function
975 - * was used to free a JSScript. Now, this function does nothing, and the
976 - * garbage collector manages JSScripts; you must root the JSScript's script
977 - * object (obtained via JS_GetScriptObject) to keep it alive.
979 - * However, since the script objects have taken over this responsibility, it
980 - * follows that every script passed here must have a script object.
982 - JS_ASSERT(script->u.object);
983 +JS_PUBLIC_API(JSScript *)
984 +JS_GetScriptFromObject(JSObject *scriptObj)
986 + JS_ASSERT(scriptObj->isScript());
988 + return (JSScript *) scriptObj->getPrivate();
992 CompileUCFunctionForPrincipalsCommon(JSContext *cx, JSObject *obj,
993 JSPrincipals *principals, const char *name,
994 uintN nargs, const char **argnames,
995 const jschar *chars, size_t length,
996 const char *filename, uintN lineno, JSVersion version)
997 @@ -4985,16 +4953,22 @@ JS_DecompileScript(JSContext *cx, JSScri
998 str = js_GetPrinterOutput(jp);
1001 js_DestroyPrinter(jp);
1005 JS_PUBLIC_API(JSString *)
1006 +JS_DecompileScriptObject(JSContext *cx, JSObject *scriptObj, const char *name, uintN indent)
1008 + return JS_DecompileScript(cx, scriptObj->getScript(), name, indent);
1011 +JS_PUBLIC_API(JSString *)
1012 JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent)
1014 JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
1016 assertSameCompartment(cx, fun);
1017 return js_DecompileToString(cx, "JS_DecompileFunction", fun,
1018 indent & ~JS_DONT_PRETTY_PRINT,
1019 !(indent & JS_DONT_PRETTY_PRINT),
1020 @@ -5009,36 +4983,34 @@ JS_DecompileFunctionBody(JSContext *cx,
1021 assertSameCompartment(cx, fun);
1022 return js_DecompileToString(cx, "JS_DecompileFunctionBody", fun,
1023 indent & ~JS_DONT_PRETTY_PRINT,
1024 !(indent & JS_DONT_PRETTY_PRINT),
1025 false, false, js_DecompileFunctionBody);
1028 JS_PUBLIC_API(JSBool)
1029 -JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval)
1030 +JS_ExecuteScript(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval)
1032 JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
1036 - assertSameCompartment(cx, obj, script);
1037 - /* This should receive only scripts handed out via the JSAPI. */
1038 - JS_ASSERT(script->u.object);
1039 - ok = Execute(cx, obj, script, NULL, 0, Valueify(rval));
1040 + assertSameCompartment(cx, obj, scriptObj);
1042 + JSBool ok = Execute(cx, obj, scriptObj->getScript(), NULL, 0, Valueify(rval));
1043 LAST_FRAME_CHECKS(cx, ok);
1047 JS_PUBLIC_API(JSBool)
1048 -JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval,
1049 +JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval,
1052 AutoVersionAPI ava(cx, version);
1053 - return JS_ExecuteScript(cx, obj, script, rval);
1054 + return JS_ExecuteScript(cx, obj, scriptObj, rval);
1058 EvaluateUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj,
1059 JSPrincipals *principals,
1060 const jschar *chars, uintN length,
1061 const char *filename, uintN lineno,
1062 jsval *rval, JSVersion compileVersion)
1063 @@ -6184,30 +6156,16 @@ JS_ClearContextThread(JSContext *cx)
1064 * with the GC that may delete t.
1066 return reinterpret_cast<jsword>(t->id);
1072 -#ifdef MOZ_TRACE_JSCALLS
1073 -JS_PUBLIC_API(void)
1074 -JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb)
1076 - cx->functionCallback = fcb;
1079 -JS_PUBLIC_API(JSFunctionCallback)
1080 -JS_GetFunctionCallback(JSContext *cx)
1082 - return cx->functionCallback;
1088 JS_SetGCZeal(JSContext *cx, uint8 zeal)
1090 cx->runtime->gcZeal = zeal;
1094 diff --git a/js/src/jsapi.h b/js/src/jsapi.h
1095 --- a/js/src/jsapi.h
1096 +++ b/js/src/jsapi.h
1097 @@ -983,19 +983,16 @@ JS_SetCompartmentCallback(JSRuntime *rt,
1098 extern JS_PUBLIC_API(JSWrapObjectCallback)
1099 JS_SetWrapObjectCallbacks(JSRuntime *rt,
1100 JSWrapObjectCallback callback,
1101 JSPreWrapCallback precallback);
1103 extern JS_PUBLIC_API(JSCrossCompartmentCall *)
1104 JS_EnterCrossCompartmentCall(JSContext *cx, JSObject *target);
1106 -extern JS_PUBLIC_API(JSCrossCompartmentCall *)
1107 -JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target);
1109 extern JS_PUBLIC_API(void)
1110 JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call);
1112 extern JS_PUBLIC_API(void *)
1113 JS_SetCompartmentPrivate(JSContext *cx, JSCompartment *compartment, void *data);
1115 extern JS_PUBLIC_API(void *)
1116 JS_GetCompartmentPrivate(JSContext *cx, JSCompartment *compartment);
1117 @@ -1030,18 +1027,16 @@ class JS_PUBLIC_API(JSAutoEnterCompartme
1119 JSCrossCompartmentCall *call;
1122 JSAutoEnterCompartment() : call(NULL) {}
1124 bool enter(JSContext *cx, JSObject *target);
1126 - bool enter(JSContext *cx, JSScript *target);
1128 void enterAndIgnoreErrors(JSContext *cx, JSObject *target);
1130 bool entered() const { return call != NULL; }
1132 ~JSAutoEnterCompartment() {
1133 if (call && call != reinterpret_cast<JSCrossCompartmentCall*>(1))
1134 JS_LeaveCrossCompartmentCall(call);
1136 @@ -1468,16 +1463,23 @@ inline Anchor<jsval>::~Anchor() {
1139 } /* namespace JS */
1145 + * C-compatible version of the Anchor class. It should be called after the last
1146 + * use of the variable it protects.
1148 +extern JS_NEVER_INLINE JS_PUBLIC_API(void)
1149 +JS_AnchorPtr(void *p);
1152 * This symbol may be used by embedders to detect the change from the old
1153 * JS_AddRoot(JSContext *, void *) APIs to the new ones above.
1155 #define JS_TYPED_ROOTING_API
1157 /* Obsolete rooting APIs. */
1158 #define JS_ClearNewbornRoots(cx) ((void) 0)
1159 #define JS_EnterLocalRootScope(cx) (JS_TRUE)
1160 @@ -2653,106 +2655,70 @@ JS_CloneFunctionObject(JSContext *cx, JS
1161 * JS_TRUE. The intent is to support interactive compilation - accumulate
1162 * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
1165 extern JS_PUBLIC_API(JSBool)
1166 JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj,
1167 const char *bytes, size_t length);
1170 - * The JSScript objects returned by the following functions refer to string and
1171 - * other kinds of literals, including doubles and RegExp objects. These
1172 - * literals are vulnerable to garbage collection; to root script objects and
1173 - * prevent literals from being collected, create a rootable object using
1174 - * JS_NewScriptObject, and root the resulting object using JS_Add[Named]Root.
1176 -extern JS_PUBLIC_API(JSScript *)
1177 +extern JS_PUBLIC_API(JSObject *)
1178 JS_CompileScript(JSContext *cx, JSObject *obj,
1179 const char *bytes, size_t length,
1180 const char *filename, uintN lineno);
1182 -extern JS_PUBLIC_API(JSScript *)
1183 +extern JS_PUBLIC_API(JSObject *)
1184 JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
1185 JSPrincipals *principals,
1186 const char *bytes, size_t length,
1187 const char *filename, uintN lineno);
1189 -extern JS_PUBLIC_API(JSScript *)
1190 +extern JS_PUBLIC_API(JSObject *)
1191 JS_CompileScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
1192 JSPrincipals *principals,
1193 const char *bytes, size_t length,
1194 const char *filename, uintN lineno,
1197 -extern JS_PUBLIC_API(JSScript *)
1198 +extern JS_PUBLIC_API(JSObject *)
1199 JS_CompileUCScript(JSContext *cx, JSObject *obj,
1200 const jschar *chars, size_t length,
1201 const char *filename, uintN lineno);
1203 -extern JS_PUBLIC_API(JSScript *)
1204 +extern JS_PUBLIC_API(JSObject *)
1205 JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
1206 JSPrincipals *principals,
1207 const jschar *chars, size_t length,
1208 const char *filename, uintN lineno);
1210 -extern JS_PUBLIC_API(JSScript *)
1211 +extern JS_PUBLIC_API(JSObject *)
1212 JS_CompileUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
1213 JSPrincipals *principals,
1214 const jschar *chars, size_t length,
1215 const char *filename, uintN lineno,
1218 -extern JS_PUBLIC_API(JSScript *)
1219 +extern JS_PUBLIC_API(JSObject *)
1220 JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename);
1222 -extern JS_PUBLIC_API(JSScript *)
1223 +extern JS_PUBLIC_API(JSObject *)
1224 JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename,
1227 -extern JS_PUBLIC_API(JSScript *)
1228 +extern JS_PUBLIC_API(JSObject *)
1229 JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj,
1230 const char *filename, FILE *fh,
1231 JSPrincipals *principals);
1233 -extern JS_PUBLIC_API(JSScript *)
1234 +extern JS_PUBLIC_API(JSObject *)
1235 JS_CompileFileHandleForPrincipalsVersion(JSContext *cx, JSObject *obj,
1236 const char *filename, FILE *fh,
1237 JSPrincipals *principals,
1241 - * NB: you must use JS_NewScriptObject and root a pointer to its return value
1242 - * in order to keep a JSScript and its atoms safe from garbage collection after
1243 - * creating the script via JS_Compile* and before a JS_ExecuteScript* call.
1244 - * E.g., and without error checks:
1246 - * JSScript *script = JS_CompileFile(cx, global, filename);
1247 - * JSObject *scrobj = JS_NewScriptObject(cx, script);
1248 - * JS_AddNamedObjectRoot(cx, &scrobj, "scrobj");
1251 - * JS_ExecuteScript(cx, global, script, &result);
1253 - * } while (!JSVAL_IS_BOOLEAN(result) || JSVAL_TO_BOOLEAN(result));
1254 - * JS_RemoveObjectRoot(cx, &scrobj);
1256 -extern JS_PUBLIC_API(JSObject *)
1257 -JS_NewScriptObject(JSContext *cx, JSScript *script);
1260 - * Infallible getter for a script's object. If JS_NewScriptObject has not been
1261 - * called on script yet, the return value will be null.
1263 -extern JS_PUBLIC_API(JSObject *)
1264 -JS_GetScriptObject(JSScript *script);
1266 -extern JS_PUBLIC_API(void)
1267 -JS_DestroyScript(JSContext *cx, JSScript *script);
1269 extern JS_PUBLIC_API(JSFunction *)
1270 JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
1271 uintN nargs, const char **argnames,
1272 const char *bytes, size_t length,
1273 const char *filename, uintN lineno);
1275 extern JS_PUBLIC_API(JSFunction *)
1276 JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj,
1277 @@ -2778,18 +2744,17 @@ extern JS_PUBLIC_API(JSFunction *)
1278 JS_CompileUCFunctionForPrincipalsVersion(JSContext *cx, JSObject *obj,
1279 JSPrincipals *principals, const char *name,
1280 uintN nargs, const char **argnames,
1281 const jschar *chars, size_t length,
1282 const char *filename, uintN lineno,
1285 extern JS_PUBLIC_API(JSString *)
1286 -JS_DecompileScript(JSContext *cx, JSScript *script, const char *name,
1288 +JS_DecompileScriptObject(JSContext *cx, JSObject *scriptObj, const char *name, uintN indent);
1291 * API extension: OR this into indent to avoid pretty-printing the decompiled
1292 * source resulting from JS_DecompileFunction{,Body}.
1294 #define JS_DONT_PRETTY_PRINT ((uintN)0x8000)
1296 extern JS_PUBLIC_API(JSString *)
1297 @@ -2829,20 +2794,20 @@ JS_DecompileFunctionBody(JSContext *cx,
1298 * points with signatures matching the following six, and that doesn't seem
1299 * worth the code bloat cost. Such new entry points would probably have less
1300 * obvious names, too, so would not tend to be used. The JS_SetOption call,
1301 * OTOH, can be more easily hacked into existing code that does not depend on
1302 * the bug; such code can continue to use the familiar JS_EvaluateScript,
1303 * etc., entry points.
1305 extern JS_PUBLIC_API(JSBool)
1306 -JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval);
1307 +JS_ExecuteScript(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval);
1309 extern JS_PUBLIC_API(JSBool)
1310 -JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval,
1311 +JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSObject *scriptObj, jsval *rval,
1315 * Execute either the function-defining prolog of a script, or the script's
1316 * main body, but not both.
1318 typedef enum JSExecPart { JSEXEC_PROLOG, JSEXEC_MAIN } JSExecPart;
1320 @@ -3775,38 +3740,16 @@ extern JS_PUBLIC_API(jsword)
1321 JS_GetContextThread(JSContext *cx);
1323 extern JS_PUBLIC_API(jsword)
1324 JS_SetContextThread(JSContext *cx);
1326 extern JS_PUBLIC_API(jsword)
1327 JS_ClearContextThread(JSContext *cx);
1329 -#ifdef MOZ_TRACE_JSCALLS
1330 -typedef void (*JSFunctionCallback)(const JSFunction *fun,
1331 - const JSScript *scr,
1332 - const JSContext *cx,
1336 - * The callback is expected to be quick and noninvasive. It should not
1337 - * trigger interrupts, turn on debugging, or produce uncaught JS
1338 - * exceptions. The state of the stack and registers in the context
1339 - * cannot be relied upon, since this callback may be invoked directly
1340 - * from either JIT. The 'entering' field means we are entering a
1341 - * function if it is positive, leaving a function if it is zero or
1344 -extern JS_PUBLIC_API(void)
1345 -JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb);
1347 -extern JS_PUBLIC_API(JSFunctionCallback)
1348 -JS_GetFunctionCallback(JSContext *cx);
1351 /************************************************************************/
1354 * JS_IsConstructing must be called from within a native given the
1355 * native's original cx and vp arguments. If JS_IsConstructing is true,
1356 * JS_THIS must not be used; the constructor should construct and return a
1357 * new object. Otherwise, the native is called as an ordinary function and
1358 * JS_THIS may be used.
1359 diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp
1360 --- a/js/src/jsarray.cpp
1361 +++ b/js/src/jsarray.cpp
1363 #include "jsarray.h"
1367 #include "jstracer.h"
1368 #include "jsbuiltins.h"
1369 #include "jscntxt.h"
1370 #include "jsversion.h"
1371 -#include "jsdbgapi.h" /* for js_TraceWatchPoints */
1374 #include "jsinterp.h"
1379 #include "jsscope.h"
1380 diff --git a/js/src/jsdbgapi.cpp b/js/src/jsdbgapi.cpp
1381 --- a/js/src/jsdbgapi.cpp
1382 +++ b/js/src/jsdbgapi.cpp
1383 @@ -155,17 +155,17 @@ JS_SetDebugModeForCompartment(JSContext
1385 // All scripts compiled from this point on should be in the requested debugMode.
1386 comp->debugMode = !!debug;
1388 // Discard JIT code for any scripts that change debugMode. This function
1389 // assumes that 'comp' is in the same thread as 'cx'.
1392 - JSAutoEnterCompartment ac;
1393 + JS::AutoEnterScriptCompartment ac;
1395 for (JSScript *script = (JSScript *)comp->scripts.next;
1396 &script->links != &comp->scripts;
1397 script = (JSScript *)script->links.next)
1399 if (!script->debugMode == !debug)
1402 @@ -2666,8 +2666,25 @@ js_ShutdownEthogram(JSContext *cx, uintN
1403 if (traceVisScriptTable)
1404 JS_HashTableDestroy(traceVisScriptTable);
1406 JS_SET_RVAL(cx, vp, JSVAL_VOID);
1410 #endif /* MOZ_TRACEVIS */
1412 +#ifdef MOZ_TRACE_JSCALLS
1414 +JS_PUBLIC_API(void)
1415 +JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb)
1417 + cx->functionCallback = fcb;
1420 +JS_PUBLIC_API(JSFunctionCallback)
1421 +JS_GetFunctionCallback(JSContext *cx)
1423 + return cx->functionCallback;
1426 +#endif /* MOZ_TRACE_JSCALLS */
1428 diff --git a/js/src/jsdbgapi.h b/js/src/jsdbgapi.h
1429 --- a/js/src/jsdbgapi.h
1430 +++ b/js/src/jsdbgapi.h
1432 -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
1433 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
1434 * vim: set ts=8 sw=4 et tw=99:
1436 * ***** BEGIN LICENSE BLOCK *****
1437 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
1439 * The contents of this file are subject to the Mozilla Public License Version
1440 * 1.1 (the "License"); you may not use this file except in compliance with
1441 * the License. You may obtain a copy of the License at
1446 #include "jsopcode.h"
1447 #include "jsprvtd.h"
1451 +extern JS_PUBLIC_API(JSCrossCompartmentCall *)
1452 +JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target);
1459 +class JS_PUBLIC_API(AutoEnterScriptCompartment)
1461 + JSCrossCompartmentCall *call;
1464 + AutoEnterScriptCompartment() : call(NULL) {}
1466 + bool enter(JSContext *cx, JSScript *target);
1468 + bool entered() const { return call != NULL; }
1470 + ~AutoEnterScriptCompartment() {
1471 + if (call && call != reinterpret_cast<JSCrossCompartmentCall*>(1))
1472 + JS_LeaveCrossCompartmentCall(call);
1476 +} /* namespace JS */
1481 +extern JS_PUBLIC_API(JSScript *)
1482 +JS_GetScriptFromObject(JSObject *scriptObject);
1484 +extern JS_PUBLIC_API(JSString *)
1485 +JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, uintN indent);
1488 * Currently, we only support runtime-wide debugging. In the future, we should
1489 * be able to support compartment-wide debugging.
1491 extern JS_PUBLIC_API(void)
1492 JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug);
1495 @@ -558,11 +594,33 @@ js_ResumeVtune(JSContext *cx, uintN argc
1498 extern JS_FRIEND_API(JSBool)
1499 js_InitEthogram(JSContext *cx, uintN argc, jsval *vp);
1500 extern JS_FRIEND_API(JSBool)
1501 js_ShutdownEthogram(JSContext *cx, uintN argc, jsval *vp);
1502 #endif /* MOZ_TRACEVIS */
1504 +#ifdef MOZ_TRACE_JSCALLS
1505 +typedef void (*JSFunctionCallback)(const JSFunction *fun,
1506 + const JSScript *scr,
1507 + const JSContext *cx,
1511 + * The callback is expected to be quick and noninvasive. It should not
1512 + * trigger interrupts, turn on debugging, or produce uncaught JS
1513 + * exceptions. The state of the stack and registers in the context
1514 + * cannot be relied upon, since this callback may be invoked directly
1515 + * from either JIT. The 'entering' field means we are entering a
1516 + * function if it is positive, leaving a function if it is zero or
1519 +extern JS_PUBLIC_API(void)
1520 +JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb);
1522 +extern JS_PUBLIC_API(JSFunctionCallback)
1523 +JS_GetFunctionCallback(JSContext *cx);
1524 +#endif /* MOZ_TRACE_JSCALLS */
1528 #endif /* jsdbgapi_h___ */
1529 diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp
1530 --- a/js/src/jsexn.cpp
1531 +++ b/js/src/jsexn.cpp
1533 #include "jstypes.h"
1534 #include "jsstdint.h"
1539 #include "jscntxt.h"
1540 #include "jsversion.h"
1541 -#include "jsdbgapi.h"
1544 #include "jsinterp.h"
1547 #include "jsopcode.h"
1548 #include "jsscope.h"
1549 #include "jsscript.h"
1550 diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp
1551 --- a/js/src/jsfun.cpp
1552 +++ b/js/src/jsfun.cpp
1556 #include "jsarray.h"
1559 #include "jsbuiltins.h"
1560 #include "jscntxt.h"
1561 #include "jsversion.h"
1562 -#include "jsdbgapi.h"
1566 #include "jsinterp.h"
1570 #include "jsopcode.h"
1571 diff --git a/js/src/jsobj.h b/js/src/jsobj.h
1572 --- a/js/src/jsobj.h
1573 +++ b/js/src/jsobj.h
1574 @@ -1049,16 +1049,22 @@ struct JSObject : js::gc::Cell {
1576 * Iterator-specific getters and setters.
1579 inline js::NativeIterator *getNativeIterator() const;
1580 inline void setNativeIterator(js::NativeIterator *);
1583 + * Script-related getters.
1586 + inline JSScript *getScript() const;
1589 * XML-related getters and setters.
1593 * Slots for XML-related classes are as follows:
1594 * - js_NamespaceClass.base reserves the *_NAME_* and *_NAMESPACE_* slots.
1595 * - js_QNameClass.base, js_AttributeNameClass, js_AnyNameClass reserve
1596 * the *_NAME_* and *_QNAME_* slots.
1597 @@ -1291,16 +1297,17 @@ struct JSObject : js::gc::Cell {
1598 inline bool isFunction() const;
1599 inline bool isObject() const;
1600 inline bool isWith() const;
1601 inline bool isBlock() const;
1602 inline bool isStaticBlock() const;
1603 inline bool isClonedBlock() const;
1604 inline bool isCall() const;
1605 inline bool isRegExp() const;
1606 + inline bool isScript() const;
1607 inline bool isXML() const;
1608 inline bool isXMLId() const;
1609 inline bool isNamespace() const;
1610 inline bool isQName() const;
1612 inline bool isProxy() const;
1613 inline bool isObjectProxy() const;
1614 inline bool isFunctionProxy() const;
1615 diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp
1616 --- a/js/src/jsopcode.cpp
1617 +++ b/js/src/jsopcode.cpp
1619 #include "jsarena.h"
1623 #include "jsarray.h"
1625 #include "jscntxt.h"
1626 #include "jsversion.h"
1627 -#include "jsdbgapi.h"
1633 #include "jsopcode.h"
1634 #include "jsregexp.h"
1636 diff --git a/js/src/jsprvtd.h b/js/src/jsprvtd.h
1637 --- a/js/src/jsprvtd.h
1638 +++ b/js/src/jsprvtd.h
1639 @@ -80,16 +80,17 @@ typedef struct JSArgumentFormatMap JSAr
1640 typedef struct JSCodeGenerator JSCodeGenerator;
1641 typedef struct JSGCThing JSGCThing;
1642 typedef struct JSGenerator JSGenerator;
1643 typedef struct JSNativeEnumerator JSNativeEnumerator;
1644 typedef struct JSFunctionBox JSFunctionBox;
1645 typedef struct JSObjectBox JSObjectBox;
1646 typedef struct JSParseNode JSParseNode;
1647 typedef struct JSProperty JSProperty;
1648 +typedef struct JSScript JSScript;
1649 typedef struct JSSharpObjectMap JSSharpObjectMap;
1650 typedef struct JSThread JSThread;
1651 typedef struct JSThreadData JSThreadData;
1652 typedef struct JSTreeContext JSTreeContext;
1653 typedef struct JSTryNote JSTryNote;
1655 /* Friend "Advanced API" typedefs. */
1656 typedef struct JSLinearString JSLinearString;
1657 diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h
1658 --- a/js/src/jspubtd.h
1659 +++ b/js/src/jspubtd.h
1660 @@ -151,17 +151,16 @@ typedef struct JSErrorReport JSError
1661 typedef struct JSFunction JSFunction;
1662 typedef struct JSFunctionSpec JSFunctionSpec;
1663 typedef struct JSTracer JSTracer;
1664 typedef struct JSIdArray JSIdArray;
1665 typedef struct JSPropertyDescriptor JSPropertyDescriptor;
1666 typedef struct JSPropertySpec JSPropertySpec;
1667 typedef struct JSObjectMap JSObjectMap;
1668 typedef struct JSRuntime JSRuntime;
1669 -typedef struct JSScript JSScript;
1670 typedef struct JSStackFrame JSStackFrame;
1671 typedef struct JSXDRState JSXDRState;
1672 typedef struct JSExceptionState JSExceptionState;
1673 typedef struct JSLocaleCallbacks JSLocaleCallbacks;
1674 typedef struct JSSecurityCallbacks JSSecurityCallbacks;
1675 typedef struct JSONParser JSONParser;
1676 typedef struct JSCompartment JSCompartment;
1677 typedef struct JSCrossCompartmentCall JSCrossCompartmentCall;
1678 @@ -462,22 +461,16 @@ typedef JSBool
1682 (* JSTraceDataOp)(JSTracer *trc, void *data);
1685 (* JSOperationCallback)(JSContext *cx);
1688 - * Deprecated form of JSOperationCallback.
1691 -(* JSBranchCallback)(JSContext *cx, JSScript *script);
1694 (* JSErrorReporter)(JSContext *cx, const char *message, JSErrorReport *report);
1697 * Possible exception types. These types are part of a JSErrorFormatString
1698 * structure. They define which error to throw in case of a runtime error.
1699 * JSEXN_NONE marks an unthrowable error.
1701 diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp
1702 --- a/js/src/jsscript.cpp
1703 +++ b/js/src/jsscript.cpp
1704 @@ -289,17 +289,17 @@ Bindings::makeImmutable()
1707 Bindings::trace(JSTracer *trc)
1709 for (const Shape *shape = lastBinding; shape; shape = shape->previous())
1714 +} /* namespace js */
1723 @@ -1700,40 +1700,40 @@ js_TraceScript(JSTracer *trc, JSScript *
1726 if (IS_GC_MARKING_TRACER(trc) && script->filename)
1727 js_MarkScriptFilename(script->filename);
1729 script->bindings.trace(trc);
1734 js_NewScriptObject(JSContext *cx, JSScript *script)
1736 AutoScriptRooter root(cx, script);
1738 JS_ASSERT(!script->u.object);
1740 JSObject *obj = NewNonFunction<WithProto::Class>(cx, &js_ScriptClass, NULL, NULL);
1744 obj->setPrivate(script);
1745 script->u.object = obj;
1748 * Clear the object's proto, to avoid entraining stuff. Once we no longer use the parent
1749 * for security checks, then we can clear the parent, too.
1753 #ifdef CHECK_SCRIPT_OWNER
1754 script->owner = NULL;
1761 typedef struct GSNCacheEntry {
1762 JSDHashEntryHdr hdr;
1767 @@ -1968,17 +1968,17 @@ js_CloneScript(JSContext *cx, JSScript *
1769 JSXDRState *w = JS_XDRNewMem(cx, JSXDR_ENCODE);
1773 // we don't want gecko to transcribe our principals for us
1774 DisablePrincipalsTranscoding disable(cx);
1776 - if (!JS_XDRScript(w, &script)) {
1777 + if (!js_XDRScript(w, &script, NULL)) {
1783 void *p = JS_XDRMemGetData(w, &nbytes);
1786 @@ -1992,17 +1992,16 @@ js_CloneScript(JSContext *cx, JSScript *
1790 // Hand p off from w to r. Don't want them to share the data
1791 // mem, lest they both try to free it in JS_XDRDestroy
1792 JS_XDRMemSetData(r, p, nbytes);
1793 JS_XDRMemSetData(w, NULL, 0);
1795 - // We can't use the public API because it makes a script object.
1796 if (!js_XDRScript(r, &script, NULL))
1802 // set the proper principals for the script
1803 script->principals = script->compartment->principals;
1804 diff --git a/js/src/jsscript.h b/js/src/jsscript.h
1805 --- a/js/src/jsscript.h
1806 +++ b/js/src/jsscript.h
1807 @@ -674,17 +674,17 @@ js_DestroyScriptFromGC(JSContext *cx, JS
1811 js_DestroyCachedScript(JSContext *cx, JSScript *script);
1814 js_TraceScript(JSTracer *trc, JSScript *script);
1818 js_NewScriptObject(JSContext *cx, JSScript *script);
1821 * To perturb as little code as possible, we introduce a js_GetSrcNote lookup
1822 * cache without adding an explicit cx parameter. Thus js_GetSrcNote becomes
1823 * a macro that uses cx from its calls' lexical environments.
1825 #define js_GetSrcNote(script,pc) js_GetSrcNoteCached(cx, script, pc)
1826 @@ -729,9 +729,22 @@ js_CloneScript(JSContext *cx, JSScript *
1828 * NB: after a successful JSXDR_DECODE, js_XDRScript callers must do any
1829 * required subsequent set-up of owning function or script object and then call
1830 * js_CallNewScriptHook.
1833 js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic);
1836 +JSObject::isScript() const
1838 + return getClass() == &js_ScriptClass;
1842 +JSObject::getScript() const
1844 + JS_ASSERT(isScript());
1845 + return static_cast<JSScript *>(getPrivate());
1848 #endif /* jsscript_h___ */
1849 diff --git a/js/src/jsxdrapi.cpp b/js/src/jsxdrapi.cpp
1850 --- a/js/src/jsxdrapi.cpp
1851 +++ b/js/src/jsxdrapi.cpp
1852 @@ -661,31 +661,39 @@ js_XDRAtom(JSXDRState *xdr, JSAtom **ato
1860 JS_PUBLIC_API(JSBool)
1861 -JS_XDRScript(JSXDRState *xdr, JSScript **scriptp)
1862 +JS_XDRScriptObject(JSXDRState *xdr, JSObject **scriptObjp)
1864 - if (!js_XDRScript(xdr, scriptp, NULL))
1867 + if (xdr->mode == JSXDR_DECODE) {
1869 + *scriptObjp = NULL;
1871 + script = (*scriptObjp)->getScript();
1874 + if (!js_XDRScript(xdr, &script, NULL))
1877 if (xdr->mode == JSXDR_DECODE) {
1878 - js_CallNewScriptHook(xdr->cx, *scriptp, NULL);
1879 - if (!js_NewScriptObject(xdr->cx, *scriptp)) {
1880 - js_DestroyScript(xdr->cx, *scriptp);
1883 + js_CallNewScriptHook(xdr->cx, script, NULL);
1884 + *scriptObjp = js_NewScriptObject(xdr->cx, script);
1885 + if (!*scriptObjp) {
1886 + js_DestroyScript(xdr->cx, script);
1895 #define CLASS_REGISTRY_MIN 8
1896 #define CLASS_INDEX_TO_ID(i) ((i)+1)
1897 #define CLASS_ID_TO_INDEX(id) ((id)-1)
1899 typedef struct JSRegHashEntry {
1900 JSDHashEntryHdr hdr;
1901 diff --git a/js/src/jsxdrapi.h b/js/src/jsxdrapi.h
1902 --- a/js/src/jsxdrapi.h
1903 +++ b/js/src/jsxdrapi.h
1904 @@ -165,17 +165,17 @@ JS_XDRStringOrNull(JSXDRState *xdr, JSSt
1906 extern JS_PUBLIC_API(JSBool)
1907 JS_XDRDouble(JSXDRState *xdr, jsdouble *dp);
1909 extern JS_PUBLIC_API(JSBool)
1910 JS_XDRValue(JSXDRState *xdr, jsval *vp);
1912 extern JS_PUBLIC_API(JSBool)
1913 -JS_XDRScript(JSXDRState *xdr, JSScript **scriptp);
1914 +JS_XDRScriptObject(JSXDRState *xdr, JSObject **scriptObjp);
1916 extern JS_PUBLIC_API(JSBool)
1917 JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp);
1919 extern JS_PUBLIC_API(uint32)
1920 JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name);
1922 extern JS_PUBLIC_API(JSClass *)
1923 diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp
1924 --- a/js/src/shell/js.cpp
1925 +++ b/js/src/shell/js.cpp
1926 @@ -392,17 +392,17 @@ SetContextOptions(JSContext *cx)
1932 Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
1936 + JSObject *scriptObj;
1945 @@ -441,20 +441,20 @@ Process(JSContext *cx, JSObject *obj, ch
1951 int64 t1 = PRMJ_Now();
1952 oldopts = JS_GetOptions(cx);
1953 JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
1954 - script = JS_CompileFileHandle(cx, obj, filename, file);
1955 + scriptObj = JS_CompileFileHandle(cx, obj, filename, file);
1956 JS_SetOptions(cx, oldopts);
1957 - if (script && !compileOnly) {
1958 - (void)JS_ExecuteScript(cx, obj, script, NULL);
1959 + if (scriptObj && !compileOnly) {
1960 + (void) JS_ExecuteScript(cx, obj, scriptObj, NULL);
1961 int64 t2 = PRMJ_Now() - t1;
1963 printf("runtime = %.3f ms\n", double(t2) / PRMJ_USEC_PER_MSEC);
1969 @@ -530,23 +530,23 @@ Process(JSContext *cx, JSObject *obj, ch
1971 /* Clear any pending exception from previous failed compiles. */
1972 JS_ClearPendingException(cx);
1974 /* Even though we're interactive, we have a compile-n-go opportunity. */
1975 oldopts = JS_GetOptions(cx);
1977 JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
1978 - script = JS_CompileScript(cx, obj, buffer, len, "typein",
1980 + scriptObj = JS_CompileScript(cx, obj, buffer, len, "typein",
1983 JS_SetOptions(cx, oldopts);
1985 - if (script && !compileOnly) {
1986 - ok = JS_ExecuteScript(cx, obj, script, &result);
1987 + if (scriptObj && !compileOnly) {
1988 + ok = JS_ExecuteScript(cx, obj, scriptObj, &result);
1989 if (ok && !JSVAL_IS_VOID(result)) {
1990 str = JS_ValueToSource(cx, result);
1993 JSAutoByteString bytes(cx, str);
1996 fprintf(gOutFile, "%s\n", bytes.ptr());
1997 @@ -1013,46 +1013,42 @@ Options(JSContext *cx, uintN argc, jsval
1999 *vp = STRING_TO_JSVAL(str);
2004 Load(JSContext *cx, uintN argc, jsval *vp)
2011 JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
2015 jsval *argv = JS_ARGV(cx, vp);
2016 - for (i = 0; i < argc; i++) {
2017 - str = JS_ValueToString(cx, argv[i]);
2018 + for (uintN i = 0; i < argc; i++) {
2019 + JSString *str = JS_ValueToString(cx, argv[i]);
2023 argv[i] = STRING_TO_JSVAL(str);
2024 JSAutoByteString filename(cx, str);
2028 - oldopts = JS_GetOptions(cx);
2029 + uint32 oldopts = JS_GetOptions(cx);
2030 JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
2031 - script = JS_CompileFile(cx, thisobj, filename.ptr());
2034 + JSObject *scriptObj = JS_CompileFile(cx, thisobj, filename.ptr());
2035 JS_SetOptions(cx, oldopts);
2036 - if (!compileOnly && !JS_ExecuteScript(cx, thisobj, script, NULL))
2044 + if (!compileOnly && !JS_ExecuteScript(cx, thisobj, scriptObj, NULL))
2052 Evaluate(JSContext *cx, uintN argc, jsval *vp)
2054 if (argc != 1 || !JSVAL_IS_STRING(JS_ARGV(cx, vp)[0])) {
2055 JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
2056 (argc != 1) ? JSSMSG_NOT_ENOUGH_ARGS : JSSMSG_INVALID_ARGS,
2057 @@ -1155,27 +1151,22 @@ Run(JSContext *cx, uintN argc, jsval *vp
2061 JS::Anchor<JSString *> a_str(str);
2062 uint32 oldopts = JS_GetOptions(cx);
2063 JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
2065 int64 startClock = PRMJ_Now();
2066 - JSScript *script = JS_CompileUCScript(cx, thisobj, ucbuf, buflen, filename.ptr(), 1);
2067 + JSObject *scriptObj = JS_CompileUCScript(cx, thisobj, ucbuf, buflen, filename.ptr(), 1);
2068 JS_SetOptions(cx, oldopts);
2070 + if (!scriptObj || !JS_ExecuteScript(cx, thisobj, scriptObj, NULL))
2073 - JSBool ok = JS_ExecuteScript(cx, thisobj, script, NULL);
2074 int64 endClock = PRMJ_Now();
2075 - JS_DestroyScript(cx, script);
2079 JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL((endClock - startClock) / double(PRMJ_USEC_PER_MSEC)));
2084 * function readline()
2085 * Provides a hook for scripts to read a line from stdin.
2087 @@ -2252,40 +2243,35 @@ DisassFile(JSContext *cx, uintN argc, js
2091 /* Support extra options at the start, just like Dissassemble. */
2097 JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
2101 JSString *str = JS_ValueToString(cx, argv[0]);
2104 JSAutoByteString filename(cx, str);
2108 uint32 oldopts = JS_GetOptions(cx);
2109 JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
2110 - JSScript *script = JS_CompileFile(cx, thisobj, filename.ptr());
2111 + JSObject *scriptObj = JS_CompileFile(cx, thisobj, filename.ptr());
2112 JS_SetOptions(cx, oldopts);
2116 - JSObject *obj = JS_NewScriptObject(cx, script);
2120 - argv[0] = OBJECT_TO_JSVAL(obj); /* I like to root it, root it. */
2124 + argv[0] = OBJECT_TO_JSVAL(scriptObj);
2125 JSBool ok = Disassemble(cx, _argc, vp); /* gross, but works! */
2126 JS_SET_RVAL(cx, vp, JSVAL_VOID);
2131 DisassWithSrc(JSContext *cx, uintN argc, jsval *vp)
2133 @@ -4313,20 +4299,20 @@ Compile(JSContext *cx, uintN argc, jsval
2134 jsval arg0 = JS_ARGV(cx, vp)[0];
2135 if (!JSVAL_IS_STRING(arg0)) {
2136 const char *typeName = JS_GetTypeName(cx, JS_TypeOfValue(cx, arg0));
2137 JS_ReportError(cx, "expected string to compile, got %s", typeName);
2141 JSString *scriptContents = JSVAL_TO_STRING(arg0);
2142 - JSScript *result = JS_CompileUCScript(cx, NULL, JS_GetStringCharsZ(cx, scriptContents),
2143 - JS_GetStringLength(scriptContents), "<string>", 0);
2146 + if (!JS_CompileUCScript(cx, NULL, JS_GetStringCharsZ(cx, scriptContents),
2147 + JS_GetStringLength(scriptContents), "<string>", 0)) {
2151 JS_SET_RVAL(cx, vp, JSVAL_VOID);
2156 Parse(JSContext *cx, uintN argc, jsval *vp)
2158 diff --git a/js/src/shell/jsworkers.cpp b/js/src/shell/jsworkers.cpp
2159 --- a/js/src/shell/jsworkers.cpp
2160 +++ b/js/src/shell/jsworkers.cpp
2161 @@ -890,23 +890,22 @@ class InitEvent : public Event
2163 if (!deserializeData(cx, &s))
2165 JS_ASSERT(JSVAL_IS_STRING(s));
2166 JSAutoByteString filename(cx, JSVAL_TO_STRING(s));
2170 - JSScript *script = JS_CompileFile(cx, child->getGlobal(), filename.ptr());
2172 + JSObject *scriptObj = JS_CompileFile(cx, child->getGlobal(), filename.ptr());
2176 AutoValueRooter rval(cx);
2177 - JSBool ok = JS_ExecuteScript(cx, child->getGlobal(), script, Jsvalify(rval.addr()));
2178 - JS_DestroyScript(cx, script);
2179 + JSBool ok = JS_ExecuteScript(cx, child->getGlobal(), scriptObj, Jsvalify(rval.addr()));
2184 class DownMessageEvent : public Event
2187 static DownMessageEvent *create(JSContext *cx, Worker *child, jsval data) {
2188 diff --git a/js/src/xpconnect/loader/mozJSComponentLoader.cpp b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
2189 --- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp
2190 +++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
2191 @@ -341,35 +341,35 @@ ReportOnCaller(JSCLContextHelper &helper
2194 return OutputError(cx, format, ap);
2197 #ifdef MOZ_ENABLE_LIBXUL
2199 ReadScriptFromStream(JSContext *cx, nsIObjectInputStream *stream,
2200 - JSScript **script)
2201 + JSObject **scriptObj)
2204 + *scriptObj = nsnull;
2207 nsresult rv = stream->Read32(&size);
2208 NS_ENSURE_SUCCESS(rv, rv);
2211 rv = stream->ReadBytes(size, &data);
2212 NS_ENSURE_SUCCESS(rv, rv);
2214 JSXDRState *xdr = JS_XDRNewMem(cx, JSXDR_DECODE);
2215 NS_ENSURE_TRUE(xdr, NS_ERROR_OUT_OF_MEMORY);
2217 xdr->userdata = stream;
2218 JS_XDRMemSetData(xdr, data, size);
2220 - if (!JS_XDRScript(xdr, script)) {
2221 + if (!JS_XDRScriptObject(xdr, scriptObj)) {
2222 rv = NS_ERROR_FAILURE;
2225 // Update data in case ::JS_XDRScript called back into C++ code to
2226 // read an XPCOM object.
2228 // In that case, the serialization process must have flushed a run
2229 // of counted bytes containing JS data at the point where the XPCOM
2230 @@ -400,26 +400,26 @@ ReadScriptFromStream(JSContext *cx, nsIO
2232 nsMemory::Free(data);
2239 -WriteScriptToStream(JSContext *cx, JSScript *script,
2240 +WriteScriptToStream(JSContext *cx, JSObject *scriptObj,
2241 nsIObjectOutputStream *stream)
2243 JSXDRState *xdr = JS_XDRNewMem(cx, JSXDR_ENCODE);
2244 NS_ENSURE_TRUE(xdr, NS_ERROR_OUT_OF_MEMORY);
2246 xdr->userdata = stream;
2247 nsresult rv = NS_OK;
2249 - if (JS_XDRScript(xdr, &script)) {
2250 + if (JS_XDRScriptObject(xdr, &scriptObj)) {
2251 // Get the encoded JSXDRState data and write it. The JSXDRState owns
2252 // this buffer memory and will free it beneath ::JS_XDRDestroy.
2254 // If an XPCOM object needs to be written in the midst of the JS XDR
2255 // encoding process, the C++ code called back from the JS engine (e.g.,
2256 // nsEncodeJSPrincipals in caps/src/nsJSPrincipals.cpp) will flush data
2257 // from the JSXDRState to aStream, then write the object, then return
2258 // to JS XDR code with xdr reset so new JS data is encoded at the front
2259 @@ -822,27 +822,16 @@ class JSPrincipalsHolder
2260 JSPrincipalsHolder(JSContext *cx, JSPrincipals *principals)
2261 : mCx(cx), mPrincipals(principals) {}
2262 ~JSPrincipalsHolder() { JSPRINCIPALS_DROP(mCx, mPrincipals); }
2265 JSPrincipals *mPrincipals;
2268 -class JSScriptHolder
2271 - JSScriptHolder(JSContext *cx, JSScript *script)
2272 - : mCx(cx), mScript(script) {}
2273 - ~JSScriptHolder() { ::JS_DestroyScript(mCx, mScript); }
2276 - JSScript *mScript;
2280 * PathifyURI transforms mozilla .js uris into useful zip paths
2281 * to make it makes it easier to manipulate startup cache entries
2282 * using standard zip tools.
2283 * Transformations applied:
2284 * * jsloader/<scheme> prefix is used to group mozJSComponentLoader cache entries in
2285 * a top-level zip directory.
2286 * * In MOZ_OMNIJAR case resource:/// and resource://gre/ URIs refer to the same path
2287 @@ -880,17 +869,17 @@ PathifyURI(nsIURI *in, nsACString &out)
2293 #ifdef MOZ_ENABLE_LIBXUL
2295 mozJSComponentLoader::ReadScript(StartupCache* cache, nsIURI *uri,
2296 - JSContext *cx, JSScript **script)
2297 + JSContext *cx, JSObject **scriptObj)
2302 rv = PathifyURI(uri, spec);
2303 NS_ENSURE_SUCCESS(rv, rv);
2305 nsAutoArrayPtr<char> buf;
2306 @@ -902,37 +891,37 @@ mozJSComponentLoader::ReadScript(Startup
2309 LOG(("Found %s in startupcache\n", spec.get()));
2310 nsCOMPtr<nsIObjectInputStream> ois;
2311 rv = NS_NewObjectInputStreamFromBuffer(buf, len, getter_AddRefs(ois));
2312 NS_ENSURE_SUCCESS(rv, rv);
2315 - return ReadScriptFromStream(cx, ois, script);
2316 + return ReadScriptFromStream(cx, ois, scriptObj);
2320 -mozJSComponentLoader::WriteScript(StartupCache* cache, JSScript *script,
2321 +mozJSComponentLoader::WriteScript(StartupCache* cache, JSObject *scriptObj,
2322 nsIFile *component, nsIURI *uri, JSContext *cx)
2327 rv = PathifyURI(uri, spec);
2328 NS_ENSURE_SUCCESS(rv, rv);
2330 LOG(("Writing %s to startupcache\n", spec.get()));
2331 nsCOMPtr<nsIObjectOutputStream> oos;
2332 nsCOMPtr<nsIStorageStream> storageStream;
2333 rv = NS_NewObjectOutputWrappedStorageStream(getter_AddRefs(oos),
2334 getter_AddRefs(storageStream));
2335 NS_ENSURE_SUCCESS(rv, rv);
2337 - rv = WriteScriptToStream(cx, script, oos);
2338 + rv = WriteScriptToStream(cx, scriptObj, oos);
2340 NS_ENSURE_SUCCESS(rv, rv);
2342 nsAutoArrayPtr<char> buf;
2344 rv = NS_NewBufferFromStorageStream(storageStream, getter_Transfers(buf),
2346 NS_ENSURE_SUCCESS(rv, rv);
2347 @@ -1036,40 +1025,40 @@ mozJSComponentLoader::GlobalForLocation(
2348 // See: http://bugzilla.mozilla.org/show_bug.cgi?id=121438
2349 #ifdef XPCONNECT_STANDALONE
2350 localFile->GetNativePath(nativePath);
2352 rv = aURI->GetSpec(nativePath);
2353 NS_ENSURE_SUCCESS(rv, rv);
2356 - JSScript *script = nsnull;
2357 + JSObject *scriptObj = nsnull;
2359 #ifdef MOZ_ENABLE_LIBXUL
2360 // Before compiling the script, first check to see if we have it in
2361 // the startupcache. Note: as a rule, startupcache errors are not fatal
2362 // to loading the script, since we can always slow-load.
2364 PRBool writeToCache = PR_FALSE;
2365 StartupCache* cache = StartupCache::GetSingleton();
2368 - rv = ReadScript(cache, aURI, cx, &script);
2369 + rv = ReadScript(cache, aURI, cx, &scriptObj);
2370 if (NS_SUCCEEDED(rv)) {
2371 LOG(("Successfully loaded %s from startupcache\n", nativePath.get()));
2373 // This is ok, it just means the script is not yet in the
2374 // cache. Could mean that the cache was corrupted and got removed,
2375 // but either way we're going to write this out.
2376 writeToCache = PR_TRUE;
2383 // The script wasn't in the cache , so compile it now.
2384 LOG(("Slow loading %s\n", nativePath.get()));
2386 // If |exception| is non-null, then our caller wants us to propagate
2387 // any exceptions out to our caller. Ensure that the engine doesn't
2388 // eagerly report the exception.
2391 @@ -1120,17 +1109,17 @@ mozJSComponentLoader::GlobalForLocation(
2393 char *buf = static_cast<char*>(PR_MemMap(map, 0, fileSize32));
2395 NS_WARNING("Failed to map file");
2396 JS_SetOptions(cx, oldopts);
2397 return NS_ERROR_FAILURE;
2400 - script = JS_CompileScriptForPrincipalsVersion(
2401 + scriptObj = JS_CompileScriptForPrincipalsVersion(
2402 cx, global, jsPrincipals, buf, fileSize32, nativePath.get(), 1,
2405 PR_MemUnmap(buf, fileSize32);
2407 #else /* HAVE_PR_MEMMAP */
2410 @@ -1176,78 +1165,73 @@ mozJSComponentLoader::GlobalForLocation(
2412 /* read the file in one swoop */
2413 rv = scriptStream->Read(buf, len, &bytesRead);
2414 if (bytesRead != len)
2415 return NS_BASE_STREAM_OSERROR;
2419 - script = JS_CompileScriptForPrincipalsVersion(
2420 + scriptObj = JS_CompileScriptForPrincipalsVersion(
2421 cx, global, jsPrincipals, buf, bytesRead, nativePath.get(), 1,
2424 // Propagate the exception, if one exists. Also, don't leave the stale
2425 // exception on this context.
2426 - // NB: The caller must stick exception into a rooted slot (probably on
2427 - // its context) as soon as possible to avoid GC hazards.
2429 JS_SetOptions(cx, oldopts);
2432 JS_GetPendingException(cx, exception);
2433 JS_ClearPendingException(cx);
2440 #ifdef DEBUG_shaver_off
2441 fprintf(stderr, "mJCL: script compilation of %s FAILED\n",
2444 return NS_ERROR_FAILURE;
2447 - // Ensure that we clean up the script on return.
2448 - JSScriptHolder scriptHolder(cx, script);
2450 // Flag this script as a system script
2451 // FIXME: BUG 346139: We actually want to flag this exact filename, not
2452 // anything that starts with this filename... Maybe we need a way to do
2453 // that? On the other hand, the fact that this is in our components dir
2454 // means that if someone snuck a malicious file into this dir we're screwed
2455 // anyway... So maybe flagging as a prefix is fine.
2456 xpc->FlagSystemFilenamePrefix(nativePath.get(), PR_TRUE);
2458 #ifdef DEBUG_shaver_off
2459 fprintf(stderr, "mJCL: compiled JS component %s\n",
2463 #ifdef MOZ_ENABLE_LIBXUL
2465 // We successfully compiled the script, so cache it.
2466 - rv = WriteScript(cache, script, aComponentFile, aURI, cx);
2467 + rv = WriteScript(cache, scriptObj, aComponentFile, aURI, cx);
2469 // Don't treat failure to write as fatal, since we might be working
2470 // with a read-only cache.
2471 if (NS_SUCCEEDED(rv)) {
2472 LOG(("Successfully wrote to cache\n"));
2474 LOG(("Failed to write to cache\n"));
2479 // Assign aGlobal here so that it's available to recursive imports.
2484 - if (!JS_ExecuteScriptVersion(cx, global, script, &retval, JSVERSION_LATEST)) {
2485 + if (!JS_ExecuteScriptVersion(cx, global, scriptObj, &retval, JSVERSION_LATEST)) {
2486 #ifdef DEBUG_shaver_off
2487 fprintf(stderr, "mJCL: failed to execute %s\n", nativePath.get());
2490 return NS_ERROR_FAILURE;
2493 /* Freed when we remove from the table. */
2494 diff --git a/js/src/xpconnect/loader/mozJSComponentLoader.h b/js/src/xpconnect/loader/mozJSComponentLoader.h
2495 --- a/js/src/xpconnect/loader/mozJSComponentLoader.h
2496 +++ b/js/src/xpconnect/loader/mozJSComponentLoader.h
2497 @@ -130,18 +130,18 @@ class mozJSComponentLoader : public mozi
2498 nsresult GlobalForLocation(nsILocalFile* aComponentFile,
2504 #ifdef MOZ_ENABLE_LIBXUL
2505 nsresult ReadScript(StartupCache *cache, nsIURI *uri,
2506 - JSContext *cx, JSScript **script);
2507 - nsresult WriteScript(StartupCache *cache, JSScript *script,
2508 + JSContext *cx, JSObject **scriptObj);
2509 + nsresult WriteScript(StartupCache *cache, JSObject *scriptObj,
2510 nsIFile *component, nsIURI *uri, JSContext *cx);
2513 nsCOMPtr<nsIComponentManager> mCompMgr;
2514 nsCOMPtr<nsIJSRuntimeService> mRuntimeService;
2515 nsCOMPtr<nsIThreadJSContextStack> mContextStack;
2516 #ifndef XPCONNECT_STANDALONE
2517 nsCOMPtr<nsIPrincipal> mSystemPrincipal;
2518 diff --git a/js/src/xpconnect/shell/xpcshell.cpp b/js/src/xpconnect/shell/xpcshell.cpp
2519 --- a/js/src/xpconnect/shell/xpcshell.cpp
2520 +++ b/js/src/xpconnect/shell/xpcshell.cpp
2521 @@ -457,57 +457,47 @@ Dump(JSContext *cx, uintN argc, jsval *v
2522 fputs(bytes.ptr(), gOutFile);
2528 Load(JSContext *cx, uintN argc, jsval *vp)
2537 JSObject *obj = JS_THIS_OBJECT(cx, vp);
2542 jsval *argv = JS_ARGV(cx, vp);
2543 - for (i = 0; i < argc; i++) {
2544 - str = JS_ValueToString(cx, argv[i]);
2545 + for (uintN i = 0; i < argc; i++) {
2546 + JSString *str = JS_ValueToString(cx, argv[i]);
2550 argv[i] = STRING_TO_JSVAL(str);
2551 JSAutoByteString filename(cx, str);
2554 - file = fopen(filename.ptr(), "r");
2556 + FILE *file = fopen(filename.ptr(), "r");
2558 JS_ReportError(cx, "cannot open file '%s' for reading",
2563 - script = JS_CompileFileHandleForPrincipals(cx, obj, filename.ptr(),
2564 - file, gJSPrincipals);
2565 + JSObject *scriptObj = JS_CompileFileHandleForPrincipals(cx, obj, filename.ptr(),
2566 + file, gJSPrincipals);
2574 - ? JS_ExecuteScript(cx, obj, script, &result)
2576 - JS_DestroyScript(cx, script);
2580 + if (!compileOnly && !JS_ExecuteScript(cx, obj, scriptObj, &result))
2583 JS_SET_RVAL(cx, vp, JSVAL_VOID);
2589 Version(JSContext *cx, uintN argc, jsval *vp)
2591 if (argc > 0 && JSVAL_IS_INT(JS_ARGV(cx, vp)[0]))
2592 JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_SetVersion(cx, JSVersion(JSVAL_TO_INT(JS_ARGV(cx, vp)[0])))));
2594 @@ -1041,17 +1031,17 @@ my_GetErrorMessage(void *userRef, const
2600 ProcessFile(JSContext *cx, JSObject *obj, const char *filename, FILE *file,
2604 + JSObject *scriptObj;
2606 int lineno, startline;
2608 char *bufp, buffer[4096];
2613 @@ -1074,24 +1064,21 @@ ProcessFile(JSContext *cx, JSObject *obj
2614 while((ch = fgetc(file)) != EOF) {
2615 if(ch == '\n' || ch == '\r')
2622 - script = JS_CompileFileHandleForPrincipals(cx, obj, filename, file,
2624 + scriptObj = JS_CompileFileHandleForPrincipals(cx, obj, filename, file,
2629 - (void)JS_ExecuteScript(cx, obj, script, &result);
2630 - JS_DestroyScript(cx, script);
2632 + if (scriptObj && !compileOnly)
2633 + (void)JS_ExecuteScript(cx, obj, scriptObj, &result);
2639 /* It's an interactive filehandle; drop into read-eval-print loop. */
2642 @@ -1113,36 +1100,35 @@ ProcessFile(JSContext *cx, JSObject *obj
2644 bufp += strlen(bufp);
2646 } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer)));
2649 /* Clear any pending exception from previous failed compiles. */
2650 JS_ClearPendingException(cx);
2651 - script = JS_CompileScriptForPrincipals(cx, obj, gJSPrincipals, buffer,
2652 - strlen(buffer), "typein", startline);
2654 + scriptObj = JS_CompileScriptForPrincipals(cx, obj, gJSPrincipals, buffer,
2655 + strlen(buffer), "typein", startline);
2657 JSErrorReporter older;
2660 - ok = JS_ExecuteScript(cx, obj, script, &result);
2661 + ok = JS_ExecuteScript(cx, obj, scriptObj, &result);
2662 if (ok && result != JSVAL_VOID) {
2663 /* Suppress error reports from JS_ValueToString(). */
2664 older = JS_SetErrorReporter(cx, NULL);
2665 str = JS_ValueToString(cx, result);
2666 JS_SetErrorReporter(cx, older);
2667 JSAutoByteString bytes;
2668 if (str && bytes.encode(cx, str))
2669 fprintf(gOutFile, "%s\n", bytes.ptr());
2674 - JS_DestroyScript(cx, script);
2677 } while (!hitEOF && !gQuitting);
2679 fprintf(gOutFile, "\n");
2683 diff --git a/js/src/xpconnect/src/xpcstack.cpp b/js/src/xpconnect/src/xpcstack.cpp
2684 --- a/js/src/xpconnect/src/xpcstack.cpp
2685 +++ b/js/src/xpconnect/src/xpcstack.cpp
2686 @@ -155,21 +155,21 @@ XPCJSStackFrame::CreateStack(JSContext*
2688 self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT;
2689 if(self->IsJSFrame())
2691 JSScript* script = JS_GetFrameScript(cx, fp);
2692 jsbytecode* pc = JS_GetFramePC(cx, fp);
2695 - JSAutoEnterCompartment ac;
2696 + JS::AutoEnterScriptCompartment ac;
2697 if(ac.enter(cx, script))
2699 - const char* filename = JS_GetScriptFilename(cx, script);
2702 + const char* filename = JS_GetScriptFilename(cx, script);
2705 self->mFilename = (char*)
2706 nsMemory::Clone(filename,
2707 sizeof(char)*(strlen(filename)+1));
2710 self->mLineno = (PRInt32) JS_PCToLineNumber(cx, script, pc);
2712 diff --git a/js/src/xpconnect/tests/TestXPC.cpp b/js/src/xpconnect/tests/TestXPC.cpp
2713 --- a/js/src/xpconnect/tests/TestXPC.cpp
2714 +++ b/js/src/xpconnect/tests/TestXPC.cpp
2715 @@ -94,42 +94,34 @@ Print(JSContext *cx, uintN argc, jsval *
2720 Load(JSContext *cx, uintN argc, jsval *vp)
2728 JSObject *obj = JS_THIS_OBJECT(cx, vp);
2732 jsval *argv = JS_ARGV(cx, vp);
2733 for (i = 0; i < argc; i++) {
2734 str = JS_ValueToString(cx, argv[i]);
2737 argv[i] = STRING_TO_JSVAL(str);
2738 JSAutoByteString filename(cx, str);
2741 - script = JS_CompileFile(cx, obj, filename.ptr());
2745 - ok = JS_ExecuteScript(cx, obj, script, &result);
2746 - JS_DestroyScript(cx, script);
2750 + JSObject *scriptObj = JS_CompileFile(cx, obj, filename.ptr());
2751 + if (!scriptObj || !JS_ExecuteScript(cx, obj, scriptObj, &result))
2754 JS_SET_RVAL(cx, vp, JSVAL_VOID);
2758 static JSFunctionSpec glob_functions[] = {
2759 {"print", Print, 0,0},
2760 {"load", Load, 1,0},