Backed out changeset b88172246b66 due to Win32 debug failures.

This commit is contained in:
Chris Leary 2011-01-25 04:11:47 -08:00
Родитель 39fad63856
Коммит 8a9852db5d
28 изменённых файлов: 343 добавлений и 545 удалений

Просмотреть файл

@ -1072,8 +1072,7 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
newDefaultJSOptions &= ~JSOPTION_PROFILING; newDefaultJSOptions &= ~JSOPTION_PROFILING;
#ifdef DEBUG #ifdef DEBUG
// In debug builds, warnings are enabled in chrome context if // In debug builds, warnings are enabled in chrome context if javascript.options.strict.debug is true
// javascript.options.strict.debug is true
PRBool strictDebug = nsContentUtils::GetBoolPref(js_strict_debug_option_str); PRBool strictDebug = nsContentUtils::GetBoolPref(js_strict_debug_option_str);
// Note this callback is also called from context's InitClasses thus we don't // Note this callback is also called from context's InitClasses thus we don't
// need to enable this directly from InitContext // need to enable this directly from InitContext
@ -1095,10 +1094,15 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
else else
newDefaultJSOptions &= ~JSOPTION_RELIMIT; newDefaultJSOptions &= ~JSOPTION_RELIMIT;
::JS_SetOptions(context->mContext, newDefaultJSOptions); if (newDefaultJSOptions != oldDefaultJSOptions) {
// Set options only if we used the old defaults; otherwise the page has
// customized some via the options object and we defer to its wisdom.
if (::JS_GetOptions(context->mContext) == oldDefaultJSOptions)
::JS_SetOptions(context->mContext, newDefaultJSOptions);
// Save the new defaults for the next page load (InitContext). // Save the new defaults for the next page load (InitContext).
context->mDefaultJSOptions = newDefaultJSOptions; context->mDefaultJSOptions = newDefaultJSOptions;
}
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
PRInt32 zeal = nsContentUtils::GetIntPref(js_zeal_option_str, -1); PRInt32 zeal = nsContentUtils::GetIntPref(js_zeal_option_str, -1);
@ -2839,6 +2843,57 @@ nsJSContext::AddSupportsPrimitiveTojsvals(nsISupports *aArg, jsval *aArgv)
return NS_OK; return NS_OK;
} }
static JSPropertySpec OptionsProperties[] = {
{"strict", (int8)JSOPTION_STRICT, JSPROP_ENUMERATE | JSPROP_PERMANENT},
{"werror", (int8)JSOPTION_WERROR, JSPROP_ENUMERATE | JSPROP_PERMANENT},
{"relimit", (int8)JSOPTION_RELIMIT, JSPROP_ENUMERATE | JSPROP_PERMANENT},
{0}
};
static JSBool
GetOptionsProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
if (JSID_IS_INT(id)) {
uint32 optbit = (uint32) JSID_TO_INT(id);
if (((optbit & (optbit - 1)) == 0 && optbit <= JSOPTION_WERROR) ||
optbit == JSOPTION_RELIMIT)
*vp = (JS_GetOptions(cx) & optbit) ? JSVAL_TRUE : JSVAL_FALSE;
}
return JS_TRUE;
}
static JSBool
SetOptionsProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
if (JSID_IS_INT(id)) {
uint32 optbit = (uint32) JSID_TO_INT(id);
// Don't let options other than strict, werror, or relimit be set -- it
// would be bad if web page script could clear
// JSOPTION_PRIVATE_IS_NSISUPPORTS!
if (((optbit & (optbit - 1)) == 0 && optbit <= JSOPTION_WERROR) ||
optbit == JSOPTION_RELIMIT) {
JSBool optval;
JS_ValueToBoolean(cx, *vp, &optval);
uint32 optset = ::JS_GetOptions(cx);
if (optval)
optset |= optbit;
else
optset &= ~optbit;
::JS_SetOptions(cx, optset);
}
}
return JS_TRUE;
}
static JSClass OptionsClass = {
"JSOptions",
0,
JS_PropertyStub, JS_PropertyStub, GetOptionsProperty, SetOptionsProperty,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nsnull
};
#ifdef NS_TRACE_MALLOC #ifdef NS_TRACE_MALLOC
#include <errno.h> // XXX assume Linux if NS_TRACE_MALLOC #include <errno.h> // XXX assume Linux if NS_TRACE_MALLOC
@ -3116,7 +3171,15 @@ nsJSContext::InitClasses(void *aGlobalObj)
JSAutoRequest ar(mContext); JSAutoRequest ar(mContext);
::JS_SetOptions(mContext, mDefaultJSOptions); // Initialize the options object and set default options in mContext
JSObject *optionsObj = ::JS_DefineObject(mContext, globalObj, "_options",
&OptionsClass, nsnull, 0);
if (optionsObj &&
::JS_DefineProperties(mContext, optionsObj, OptionsProperties)) {
::JS_SetOptions(mContext, mDefaultJSOptions);
} else {
rv = NS_ERROR_FAILURE;
}
// Attempt to initialize profiling functions // Attempt to initialize profiling functions
::JS_DefineProfilingFunctions(mContext, globalObj); ::JS_DefineProfilingFunctions(mContext, globalObj);

Просмотреть файл

@ -13,8 +13,7 @@ version(150);
assertEq(syntaxErrorFromXML(), true); assertEq(syntaxErrorFromXML(), true);
revertVersion(); revertVersion();
for (vno in {160: null, 170: null, 180: null}) { for (vno in {150: null, 160: null, 170: null, 180: null}) {
print('Setting version to: ' + vno);
version(vno); version(vno);
assertEq(syntaxErrorFromXML(), false); assertEq(syntaxErrorFromXML(), false);
revertVersion(); revertVersion();

Просмотреть файл

@ -6,41 +6,10 @@ using namespace js;
struct VersionFixture; struct VersionFixture;
/*
* Fast-native callbacks for use from JS.
* They set their results on the current fixture instance.
*/
static VersionFixture *callbackData = NULL; static VersionFixture *callbackData = NULL;
JSBool CheckVersionHasXML(JSContext *cx, uintN argc, jsval *vp);
JSBool DisableXMLOption(JSContext *cx, uintN argc, jsval *vp);
JSBool CallSetVersion17(JSContext *cx, uintN argc, jsval *vp);
JSBool CheckNewScriptNoXML(JSContext *cx, uintN argc, jsval *vp);
JSBool OverrideVersion15(JSContext *cx, uintN argc, jsval *vp);
JSBool CaptureVersion(JSContext *cx, uintN argc, jsval *vp);
JSBool CheckOverride(JSContext *cx, uintN argc, jsval *vp);
JSBool EvalScriptVersion16(JSContext *cx, uintN argc, jsval *vp);
struct VersionFixture : public JSAPITest struct VersionFixture : public JSAPITest
{ {
JSVersion captured;
virtual bool init() {
JSAPITest::init();
callbackData = this;
captured = JSVERSION_UNKNOWN;
return JS_DefineFunction(cx, global, "checkVersionHasXML", CheckVersionHasXML, 0, 0) &&
JS_DefineFunction(cx, global, "disableXMLOption", DisableXMLOption, 0, 0) &&
JS_DefineFunction(cx, global, "callSetVersion17", CallSetVersion17, 0, 0) &&
JS_DefineFunction(cx, global, "checkNewScriptNoXML", CheckNewScriptNoXML, 0, 0) &&
JS_DefineFunction(cx, global, "overrideVersion15", OverrideVersion15, 0, 0) &&
JS_DefineFunction(cx, global, "captureVersion", CaptureVersion, 0, 0) &&
JS_DefineFunction(cx, global, "checkOverride", CheckOverride, 1, 0) &&
JS_DefineFunction(cx, global, "evalScriptVersion16",
EvalScriptVersion16, 0, 0);
}
JSScript *fakeScript(const char *contents, size_t length) { JSScript *fakeScript(const char *contents, size_t length) {
return JS_CompileScript(cx, global, contents, length, "<test>", 1); return JS_CompileScript(cx, global, contents, length, "<test>", 1);
} }
@ -50,25 +19,20 @@ struct VersionFixture : public JSAPITest
} }
bool hasXML(JSScript *script) { bool hasXML(JSScript *script) {
return hasXML(script->getVersion()); return hasXML(script->version);
} }
bool hasXML() { bool hasXML() {
return OptionsHasXML(JS_GetOptions(cx)); return OptionsHasXML(JS_GetOptions(cx));
} }
bool checkVersionHasXML() {
CHECK(hasXML(cx->findVersion()));
return true;
}
bool checkOptionsHasNoXML() { bool checkOptionsHasNoXML() {
CHECK(!OptionsHasXML(JS_GetOptions(cx))); CHECK(!OptionsHasXML(cx->options));
return true;
}
bool disableXMLOption() {
JS_SetOptions(cx, JS_GetOptions(cx) & ~JSOPTION_XML);
return true;
}
bool checkVersionIsOverridden() {
CHECK(cx->isVersionOverridden());
return true; return true;
} }
@ -76,12 +40,7 @@ struct VersionFixture : public JSAPITest
bool checkNewScriptNoXML() { bool checkNewScriptNoXML() {
JSScript *script = fakeScript("", 0); JSScript *script = fakeScript("", 0);
CHECK(script); CHECK(script);
CHECK(!hasXML(script->getVersion())); CHECK(!hasXML(script->version));
return true;
}
bool checkVersionHasXML() {
CHECK(VersionHasXML(cx->findVersion()));
return true; return true;
} }
@ -91,14 +50,6 @@ struct VersionFixture : public JSAPITest
return true; return true;
} }
bool evalVersion(const jschar *chars, size_t len, JSVersion version) {
CHECK(JS_GetVersion(cx) != version);
jsval rval;
CHECK(JS_EvaluateUCScriptForPrincipalsVersion(
cx, global, NULL, chars, len, "<test>", 0, &rval, version));
return true;
}
bool toggleXML(bool shouldEnable) { bool toggleXML(bool shouldEnable) {
CHECK(hasXML() == !shouldEnable); CHECK(hasXML() == !shouldEnable);
JS_ToggleOptions(cx, JSOPTION_XML); JS_ToggleOptions(cx, JSOPTION_XML);
@ -118,7 +69,7 @@ struct VersionFixture : public JSAPITest
/* Callbacks to throw into JS-land. */ /* Callbacks to throw into JS-land. */
JSBool JSBool
CallSetVersion17(JSContext *cx, uintN argc, jsval *vp) CallSetVersion(JSContext *cx, uintN argc, jsval *vp)
{ {
return callbackData->setVersion(JSVERSION_1_7); return callbackData->setVersion(JSVERSION_1_7);
} }
@ -130,9 +81,9 @@ CheckVersionHasXML(JSContext *cx, uintN argc, jsval *vp)
} }
JSBool JSBool
DisableXMLOption(JSContext *cx, uintN argc, jsval *vp) CheckOptionsHasNoXML(JSContext *cx, uintN argc, jsval *vp)
{ {
return callbackData->disableXMLOption(); return callbackData->checkOptionsHasNoXML();
} }
JSBool JSBool
@ -141,59 +92,21 @@ CheckNewScriptNoXML(JSContext *cx, uintN argc, jsval *vp)
return callbackData->checkNewScriptNoXML(); return callbackData->checkNewScriptNoXML();
} }
JSBool
OverrideVersion15(JSContext *cx, uintN argc, jsval *vp)
{
if (!callbackData->setVersion(JSVERSION_1_5))
return false;
return callbackData->checkVersionIsOverridden();
}
JSBool
EvalScriptVersion16(JSContext *cx, uintN argc, jsval *vp)
{
JS_ASSERT(argc == 1);
jsval *argv = JS_ARGV(cx, vp);
JS_ASSERT(JSVAL_IS_STRING(argv[0]));
JSString *str = JSVAL_TO_STRING(argv[0]);
const jschar *chars = str->getChars(cx);
JS_ASSERT(chars);
size_t len = str->length();
return callbackData->evalVersion(chars, len, JSVERSION_1_6);
}
JSBool
CaptureVersion(JSContext *cx, uintN argc, jsval *vp)
{
callbackData->captured = JS_GetVersion(cx);
return true;
}
JSBool
CheckOverride(JSContext *cx, uintN argc, jsval *vp)
{
JS_ASSERT(argc == 1);
jsval *argv = JS_ARGV(cx, vp);
JS_ASSERT(JSVAL_IS_BOOLEAN(argv[0]));
bool shouldHaveOverride = !!JSVAL_TO_BOOLEAN(argv[0]);
return shouldHaveOverride == cx->isVersionOverridden();
}
/*
* See bug 611462. We are checking that the XML option setting from a JSAPI
* call is propagated to newly compiled scripts, instead of inheriting the XML
* setting from a script on the stack.
*/
BEGIN_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags) BEGIN_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags)
{ {
/*
* See bug 611462. We are checking that the XML option setting from a JSAPI
* call is propagated to newly compiled scripts, instead of inheriting the
* XML setting from a script on the stack.
*/
callbackData = this; callbackData = this;
/* Enable XML and compile a script to activate. */ /* Enable XML and compile a script to activate. */
enableXML(); enableXML();
const char toActivateChars[] = const char toActivateChars[] =
"checkVersionHasXML();" "checkVersionHasXML();"
"disableXMLOption();" "checkOptionsHasNoXML();"
"callSetVersion17();" "callSetVersion();"
"checkNewScriptNoXML();"; "checkNewScriptNoXML();";
JSScript *toActivate = fakeScript(toActivateChars, sizeof(toActivateChars) - 1); JSScript *toActivate = fakeScript(toActivateChars, sizeof(toActivateChars) - 1);
CHECK(toActivate); CHECK(toActivate);
@ -202,6 +115,16 @@ BEGIN_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags)
disableXML(); disableXML();
JSFunction *f1 = JS_DefineFunction(cx, global, "checkVersionHasXML", CheckVersionHasXML, 0, 0);
CHECK(f1);
JSFunction *f2 = JS_DefineFunction(cx, global, "checkOptionsHasNoXML", CheckOptionsHasNoXML,
0, 0);
CHECK(f2);
JSFunction *f3 = JS_DefineFunction(cx, global, "callSetVersion", CallSetVersion, 0, 0);
CHECK(f3);
JSFunction *f4 = JS_DefineFunction(cx, global, "checkNewScriptNoXML", CheckNewScriptNoXML,
0, 0);
CHECK(f4);
CHECK(scriptObject); CHECK(scriptObject);
/* Activate the script. */ /* Activate the script. */
@ -210,58 +133,3 @@ BEGIN_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags)
return true; return true;
} }
END_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags) END_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags)
/*
* When re-entering the virtual machine through a *Version API the version
* is no longer forced -- it continues with its natural push/pop oriented
* version progression. This is maintained by the |AutoVersionAPI| class in
* jsapi.cpp.
*/
BEGIN_FIXTURE_TEST(VersionFixture, testEntryLosesOverride)
{
EXEC("overrideVersion15(); evalScriptVersion16('checkOverride(false); captureVersion()');");
CHECK(captured == JSVERSION_1_6);
/*
* Override gets propagated to default version as non-override when you leave the VM's execute
* call.
*/
CHECK(JS_GetVersion(cx) == JSVERSION_1_5);
CHECK(!cx->isVersionOverridden());
return true;
}
END_FIXTURE_TEST(VersionFixture, testEntryLosesOverride)
/*
* EvalScriptVersion does not propagate overrides to its caller, it
* restores things exactly as they were before the call. This is as opposed to
* the normal (no Version suffix) API which propagates overrides
* to the caller.
*/
BEGIN_FIXTURE_TEST(VersionFixture, testReturnLosesOverride)
{
CHECK(JS_GetVersion(cx) == JSVERSION_ECMA_5);
EXEC(
"checkOverride(false);"
"evalScriptVersion16('overrideVersion15();');"
"checkOverride(false);"
"captureVersion();"
);
CHECK(captured == JSVERSION_ECMA_5);
return true;
}
END_FIXTURE_TEST(VersionFixture, testReturnLosesOverride)
BEGIN_FIXTURE_TEST(VersionFixture, testEvalPropagatesOverride)
{
CHECK(JS_GetVersion(cx) == JSVERSION_ECMA_5);
EXEC(
"checkOverride(false);"
"eval('overrideVersion15();');"
"checkOverride(true);"
"captureVersion();"
);
CHECK(captured == JSVERSION_1_5);
return true;
}
END_FIXTURE_TEST(VersionFixture, testEvalPropagatesOverride)

Просмотреть файл

@ -122,57 +122,41 @@ static JSClass dummy_class = {
JSCLASS_NO_OPTIONAL_MEMBERS JSCLASS_NO_OPTIONAL_MEMBERS
}; };
/*
* This class is a version-establising barrier at the head of a VM entry or
* re-entry. It ensures that:
*
* - |newVersion| is the starting (default) version used for the context.
* - The starting version state is not an override.
* - Overrides in the VM session are not propagated to the caller.
*/
class AutoVersionAPI class AutoVersionAPI
{ {
JSContext * const cx; JSContext * const cx;
JSVersion oldDefaultVersion; JSVersion oldVersion;
bool oldHasVersionOverride; bool oldVersionWasOverride;
JSVersion oldVersionOverride; uint32 oldOptions;
#ifdef DEBUG
uintN oldCompileOptions;
#endif
JSVersion newVersion;
public: public:
explicit AutoVersionAPI(JSContext *cx, JSVersion newVersion) explicit AutoVersionAPI(JSContext *cx, JSVersion newVersion)
: cx(cx), : cx(cx), oldVersion(cx->findVersion()), oldVersionWasOverride(cx->isVersionOverridden()),
oldDefaultVersion(cx->getDefaultVersion()), oldOptions(cx->options) {
oldHasVersionOverride(cx->isVersionOverridden()),
oldVersionOverride(oldHasVersionOverride ? cx->findVersion() : JSVERSION_UNKNOWN)
#ifdef DEBUG
, oldCompileOptions(cx->getCompileOptions())
#endif
{
/* /*
* Note: ANONFUNFIX in newVersion is ignored for backwards * Note: ANONFUNFIX in newVersion is ignored for backwards
* compatibility, must be set via JS_SetOptions. (Because of this, we * compatibility, must be set via JS_SetOptions. (Because of this, we
* inherit the current ANONFUNFIX setting from the options. * inherit the current ANONFUNFIX setting from the options.
*/ */
VersionSetAnonFunFix(&newVersion, OptionsHasAnonFunFix(cx->getCompileOptions())); cx->options = VersionHasXML(newVersion)
this->newVersion = newVersion; ? (cx->options | JSOPTION_XML)
cx->clearVersionOverride(); : (cx->options & ~JSOPTION_XML);
cx->setDefaultVersion(newVersion);
VersionSetAnonFunFix(&newVersion, OptionsHasAnonFunFix(cx->options));
cx->maybeOverrideVersion(newVersion);
cx->checkOptionVersionSync();
} }
~AutoVersionAPI() { ~AutoVersionAPI() {
cx->setDefaultVersion(oldDefaultVersion); cx->options = oldOptions;
if (oldHasVersionOverride) if (oldVersionWasOverride) {
cx->overrideVersion(oldVersionOverride); JS_ALWAYS_TRUE(cx->maybeOverrideVersion(oldVersion));
else } else {
cx->clearVersionOverride(); cx->clearVersionOverride();
JS_ASSERT(oldCompileOptions == cx->getCompileOptions()); cx->setDefaultVersion(oldVersion);
}
JS_ASSERT(cx->findVersion() == oldVersion);
} }
/* The version that this scoped-entity establishes. */
JSVersion version() const { return newVersion; }
}; };
#ifdef HAVE_VA_LIST_AS_ARRAY #ifdef HAVE_VA_LIST_AS_ARRAY
@ -1054,9 +1038,6 @@ JS_SetVersion(JSContext *cx, JSVersion newVersion)
JS_ASSERT(!VersionHasFlags(newVersion)); JS_ASSERT(!VersionHasFlags(newVersion));
JSVersion newVersionNumber = newVersion; JSVersion newVersionNumber = newVersion;
#ifdef DEBUG
uintN coptsBefore = cx->getCompileOptions();
#endif
JSVersion oldVersion = cx->findVersion(); JSVersion oldVersion = cx->findVersion();
JSVersion oldVersionNumber = VersionNumber(oldVersion); JSVersion oldVersionNumber = VersionNumber(oldVersion);
if (oldVersionNumber == newVersionNumber) if (oldVersionNumber == newVersionNumber)
@ -1066,9 +1047,9 @@ JS_SetVersion(JSContext *cx, JSVersion newVersion)
if (newVersionNumber != JSVERSION_DEFAULT && newVersionNumber <= JSVERSION_1_4) if (newVersionNumber != JSVERSION_DEFAULT && newVersionNumber <= JSVERSION_1_4)
return oldVersionNumber; return oldVersionNumber;
VersionCopyFlags(&newVersion, oldVersion); cx->optionFlagsToVersion(&newVersion);
cx->maybeOverrideVersion(newVersion); cx->maybeOverrideVersion(newVersion);
JS_ASSERT(cx->getCompileOptions() == coptsBefore); cx->checkOptionVersionSync();
return oldVersionNumber; return oldVersionNumber;
} }
@ -1121,36 +1102,32 @@ JS_GetOptions(JSContext *cx)
* We may have been synchronized with a script version that was formerly on * We may have been synchronized with a script version that was formerly on
* the stack, but has now been popped. * the stack, but has now been popped.
*/ */
return cx->allOptions(); return cx->options;
}
static uintN
SetOptionsCommon(JSContext *cx, uintN options)
{
JS_ASSERT((options & JSALLOPTION_MASK) == options);
uintN oldopts = cx->allOptions();
uintN newropts = options & JSRUNOPTION_MASK;
uintN newcopts = options & JSCOMPILEOPTION_MASK;
cx->setRunOptions(newropts);
cx->setCompileOptions(newcopts);
cx->updateJITEnabled();
return oldopts;
} }
JS_PUBLIC_API(uint32) JS_PUBLIC_API(uint32)
JS_SetOptions(JSContext *cx, uint32 options) JS_SetOptions(JSContext *cx, uint32 options)
{ {
AutoLockGC lock(cx->runtime); AutoLockGC lock(cx->runtime);
return SetOptionsCommon(cx, options); uint32 oldopts = cx->options;
cx->options = options;
cx->syncOptionsToVersion();
cx->updateJITEnabled();
cx->checkOptionVersionSync();
return oldopts;
} }
JS_PUBLIC_API(uint32) JS_PUBLIC_API(uint32)
JS_ToggleOptions(JSContext *cx, uint32 options) JS_ToggleOptions(JSContext *cx, uint32 options)
{ {
AutoLockGC lock(cx->runtime); AutoLockGC lock(cx->runtime);
uintN oldopts = cx->allOptions(); cx->checkOptionVersionSync();
uintN newopts = oldopts ^ options; uint32 oldopts = cx->options;
return SetOptionsCommon(cx, newopts); cx->options ^= options;
cx->syncOptionsToVersion();
cx->updateJITEnabled();
cx->checkOptionVersionSync();
return oldopts;
} }
JS_PUBLIC_API(const char *) JS_PUBLIC_API(const char *)
@ -4400,7 +4377,7 @@ JS_DefineFunctionById(JSContext *cx, JSObject *obj, jsid id, JSNative call,
inline static void inline static void
LAST_FRAME_EXCEPTION_CHECK(JSContext *cx, bool result) LAST_FRAME_EXCEPTION_CHECK(JSContext *cx, bool result)
{ {
if (!result && !cx->hasRunOption(JSOPTION_DONT_REPORT_UNCAUGHT)) if (!result && !(cx->options & JSOPTION_DONT_REPORT_UNCAUGHT))
js_ReportUncaughtException(cx); js_ReportUncaughtException(cx);
} }
@ -4415,8 +4392,8 @@ LAST_FRAME_CHECKS(JSContext *cx, bool result)
inline static uint32 inline static uint32
JS_OPTIONS_TO_TCFLAGS(JSContext *cx) JS_OPTIONS_TO_TCFLAGS(JSContext *cx)
{ {
return (cx->hasRunOption(JSOPTION_COMPILE_N_GO) ? TCF_COMPILE_N_GO : 0) | return ((cx->options & JSOPTION_COMPILE_N_GO) ? TCF_COMPILE_N_GO : 0) |
(cx->hasRunOption(JSOPTION_NO_SCRIPT_RVAL) ? TCF_NO_SCRIPT_RVAL : 0); ((cx->options & JSOPTION_NO_SCRIPT_RVAL) ? TCF_NO_SCRIPT_RVAL : 0);
} }
extern JS_PUBLIC_API(JSScript *) extern JS_PUBLIC_API(JSScript *)
@ -4441,7 +4418,7 @@ JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj, JSPrincipals *prin
uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT; uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT;
JSScript *script = Compiler::compileScript(cx, obj, NULL, principals, tcflags, JSScript *script = Compiler::compileScript(cx, obj, NULL, principals, tcflags,
chars, length, filename, lineno, cx->findVersion()); chars, length, filename, lineno);
if (script && !js_NewScriptObject(cx, script)) { if (script && !js_NewScriptObject(cx, script)) {
js_DestroyScript(cx, script); js_DestroyScript(cx, script);
script = NULL; script = NULL;
@ -4516,7 +4493,7 @@ JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj, const char *bytes, size_
exnState = JS_SaveExceptionState(cx); exnState = JS_SaveExceptionState(cx);
{ {
Parser parser(cx); Parser parser(cx);
if (parser.init(chars, length, NULL, 1, cx->findVersion())) { if (parser.init(chars, length, NULL, 1)) {
older = JS_SetErrorReporter(cx, NULL); older = JS_SetErrorReporter(cx, NULL);
if (!parser.parse(obj) && if (!parser.parse(obj) &&
parser.tokenStream.isUnexpectedEOF()) { parser.tokenStream.isUnexpectedEOF()) {
@ -4594,8 +4571,7 @@ CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals, uint32
JS_ASSERT(i <= len); JS_ASSERT(i <= len);
len = i; len = i;
script = Compiler::compileScript(cx, obj, NULL, principals, tcflags, buf, len, filename, 1, script = Compiler::compileScript(cx, obj, NULL, principals, tcflags, buf, len, filename, 1);
cx->findVersion());
cx->free(buf); cx->free(buf);
return script; return script;
} }
@ -4779,7 +4755,7 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
} }
if (!Compiler::compileFunctionBody(cx, fun, principals, &bindings, if (!Compiler::compileFunctionBody(cx, fun, principals, &bindings,
chars, length, filename, lineno, cx->findVersion())) { chars, length, filename, lineno)) {
fun = NULL; fun = NULL;
goto out2; goto out2;
} }
@ -4920,32 +4896,6 @@ JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSScript *script, jsval *r
return JS_ExecuteScript(cx, obj, script, rval); return JS_ExecuteScript(cx, obj, script, rval);
} }
bool
EvaluateUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj,
JSPrincipals *principals,
const jschar *chars, uintN length,
const char *filename, uintN lineno,
jsval *rval, JSVersion compileVersion)
{
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
CHECK_REQUEST(cx);
JSScript *script = Compiler::compileScript(cx, obj, NULL, principals,
!rval
? TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL
: TCF_COMPILE_N_GO,
chars, length, filename, lineno, compileVersion);
if (!script) {
LAST_FRAME_CHECKS(cx, script);
return false;
}
JS_ASSERT(script->getVersion() == compileVersion);
bool ok = Execute(cx, obj, script, NULL, 0, Valueify(rval));
LAST_FRAME_CHECKS(cx, ok);
js_DestroyScript(cx, script);
return ok;
}
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_EvaluateUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj, JS_EvaluateUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
@ -4955,8 +4905,8 @@ JS_EvaluateUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj,
jsval *rval, JSVersion version) jsval *rval, JSVersion version)
{ {
AutoVersionAPI avi(cx, version); AutoVersionAPI avi(cx, version);
return EvaluateUCScriptForPrincipalsCommon(cx, obj, principals, chars, length, return JS_EvaluateUCScriptForPrincipals(cx, obj, principals, chars, length, filename, lineno,
filename, lineno, rval, avi.version()); rval);
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
@ -4966,8 +4916,24 @@ JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj,
const char *filename, uintN lineno, const char *filename, uintN lineno,
jsval *rval) jsval *rval)
{ {
return EvaluateUCScriptForPrincipalsCommon(cx, obj, principals, chars, length, JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
filename, lineno, rval, cx->findVersion()); JSScript *script;
JSBool ok;
CHECK_REQUEST(cx);
script = Compiler::compileScript(cx, obj, NULL, principals,
!rval
? TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL
: TCF_COMPILE_N_GO,
chars, length, filename, lineno);
if (!script) {
LAST_FRAME_CHECKS(cx, script);
return JS_FALSE;
}
ok = Execute(cx, obj, script, NULL, 0, Valueify(rval));
LAST_FRAME_CHECKS(cx, ok);
js_DestroyScript(cx, script);
return ok;
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)

Просмотреть файл

@ -956,12 +956,6 @@ JS_StringToVersion(const char *string);
#define JSOPTION_METHODJIT JS_BIT(14) /* Whole-method JIT. */ #define JSOPTION_METHODJIT JS_BIT(14) /* Whole-method JIT. */
#define JSOPTION_PROFILING JS_BIT(15) /* Profiler to make tracer/methodjit choices. */ #define JSOPTION_PROFILING JS_BIT(15) /* Profiler to make tracer/methodjit choices. */
/* Options which reflect compile-time properties of scripts. */
#define JSCOMPILEOPTION_MASK (JSOPTION_XML | JSOPTION_ANONFUNFIX)
#define JSRUNOPTION_MASK (JS_BITMASK(16) & ~JSCOMPILEOPTION_MASK)
#define JSALLOPTION_MASK (JSCOMPILEOPTION_MASK | JSRUNOPTION_MASK)
extern JS_PUBLIC_API(uint32) extern JS_PUBLIC_API(uint32)
JS_GetOptions(JSContext *cx); JS_GetOptions(JSContext *cx);

Просмотреть файл

@ -1406,18 +1406,18 @@ checkReportFlags(JSContext *cx, uintN *flags)
JSStackFrame *fp = js_GetScriptedCaller(cx, NULL); JSStackFrame *fp = js_GetScriptedCaller(cx, NULL);
if (fp && fp->script()->strictModeCode) if (fp && fp->script()->strictModeCode)
*flags &= ~JSREPORT_WARNING; *flags &= ~JSREPORT_WARNING;
else if (cx->hasStrictOption()) else if (JS_HAS_STRICT_OPTION(cx))
*flags |= JSREPORT_WARNING; *flags |= JSREPORT_WARNING;
else else
return true; return true;
} else if (JSREPORT_IS_STRICT(*flags)) { } else if (JSREPORT_IS_STRICT(*flags)) {
/* Warning/error only when JSOPTION_STRICT is set. */ /* Warning/error only when JSOPTION_STRICT is set. */
if (!cx->hasStrictOption()) if (!JS_HAS_STRICT_OPTION(cx))
return true; return true;
} }
/* Warnings become errors when JSOPTION_WERROR is set. */ /* Warnings become errors when JSOPTION_WERROR is set. */
if (JSREPORT_IS_WARNING(*flags) && cx->hasWErrorOption()) if (JSREPORT_IS_WARNING(*flags) && JS_HAS_WERROR_OPTION(cx))
*flags &= ~JSREPORT_WARNING; *flags &= ~JSREPORT_WARNING;
return false; return false;
@ -1990,8 +1990,7 @@ DSTOffsetCache::DSTOffsetCache()
} }
JSContext::JSContext(JSRuntime *rt) JSContext::JSContext(JSRuntime *rt)
: hasVersionOverride(false), : runtime(rt),
runtime(rt),
compartment(NULL), compartment(NULL),
regs(NULL), regs(NULL),
busyArrays() busyArrays()
@ -2077,7 +2076,6 @@ JSContext::popSegmentAndFrame()
JS_ASSERT(regs->fp->prev() == NULL); JS_ASSERT(regs->fp->prev() == NULL);
setCurrentRegs(NULL); setCurrentRegs(NULL);
} }
maybeMigrateVersionOverride();
} }
void void
@ -2278,14 +2276,14 @@ void
JSContext::updateJITEnabled() JSContext::updateJITEnabled()
{ {
#ifdef JS_TRACER #ifdef JS_TRACER
traceJitEnabled = ((runOptions & JSOPTION_JIT) && traceJitEnabled = ((options & JSOPTION_JIT) &&
!IsJITBrokenHere() && !IsJITBrokenHere() &&
(debugHooks == &js_NullDebugHooks || (debugHooks == &js_NullDebugHooks ||
(debugHooks == &runtime->globalDebugHooks && (debugHooks == &runtime->globalDebugHooks &&
!runtime->debuggerInhibitsJIT()))); !runtime->debuggerInhibitsJIT())));
#endif #endif
#ifdef JS_METHODJIT #ifdef JS_METHODJIT
methodJitEnabled = (runOptions & JSOPTION_METHODJIT) && methodJitEnabled = (options & JSOPTION_METHODJIT) &&
!IsJITBrokenHere() !IsJITBrokenHere()
# if defined JS_CPU_X86 || defined JS_CPU_X64 # if defined JS_CPU_X86 || defined JS_CPU_X64
&& JSC::MacroAssemblerX86Common::getSSEState() >= && JSC::MacroAssemblerX86Common::getSSEState() >=
@ -2293,7 +2291,7 @@ JSContext::updateJITEnabled()
# endif # endif
; ;
#ifdef JS_TRACER #ifdef JS_TRACER
profilingEnabled = (runOptions & JSOPTION_PROFILING) && traceJitEnabled && methodJitEnabled; profilingEnabled = (options & JSOPTION_PROFILING) && traceJitEnabled && methodJitEnabled;
#endif #endif
#endif #endif
} }

Просмотреть файл

@ -1533,6 +1533,12 @@ namespace js {
class AutoGCRooter; class AutoGCRooter;
#define JS_HAS_OPTION(cx,option) (((cx)->options & (option)) != 0)
#define JS_HAS_STRICT_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_STRICT)
#define JS_HAS_WERROR_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_WERROR)
#define JS_HAS_COMPILE_N_GO_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_COMPILE_N_GO)
#define JS_HAS_ATLINE_OPTION(cx) JS_HAS_OPTION(cx, JSOPTION_ATLINE)
static inline bool static inline bool
OptionsHasXML(uint32 options) OptionsHasXML(uint32 options)
{ {
@ -1561,10 +1567,9 @@ OptionsSameVersionFlags(uint32 self, uint32 other)
* become invalid. * become invalid.
*/ */
namespace VersionFlags { namespace VersionFlags {
static const uintN MASK = 0x0FFF; /* see JSVersion in jspubtd.h */ static const uint32 MASK = 0x0FFF; /* see JSVersion in jspubtd.h */
static const uintN HAS_XML = 0x1000; /* flag induced by XML option */ static const uint32 HAS_XML = 0x1000; /* flag induced by XML option */
static const uintN ANONFUNFIX = 0x2000; /* see jsapi.h comment on JSOPTION_ANONFUNFIX */ static const uint32 ANONFUNFIX = 0x2000; /* see jsapi.h comment on JSOPTION_ANONFUNFIX */
static const uintN FULL_MASK = 0x3FFF;
} }
static inline JSVersion static inline JSVersion
@ -1616,35 +1621,12 @@ VersionExtractFlags(JSVersion version)
return JSVersion(uint32(version) & ~VersionFlags::MASK); return JSVersion(uint32(version) & ~VersionFlags::MASK);
} }
static inline void
VersionCopyFlags(JSVersion *version, JSVersion from)
{
*version = JSVersion(VersionNumber(*version) | VersionExtractFlags(from));
}
static inline bool static inline bool
VersionHasFlags(JSVersion version) VersionHasFlags(JSVersion version)
{ {
return !!VersionExtractFlags(version); return !!VersionExtractFlags(version);
} }
static inline uintN
VersionFlagsToOptions(JSVersion version)
{
uintN copts = (VersionHasXML(version) ? JSOPTION_XML : 0) |
(VersionHasAnonFunFix(version) ? JSOPTION_ANONFUNFIX : 0);
JS_ASSERT((copts & JSCOMPILEOPTION_MASK) == copts);
return copts;
}
static inline JSVersion
OptionFlagsToVersion(uintN options, JSVersion version)
{
VersionSetXML(&version, OptionsHasXML(options));
VersionSetAnonFunFix(&version, OptionsHasAnonFunFix(options));
return version;
}
static inline bool static inline bool
VersionIsKnown(JSVersion version) VersionIsKnown(JSVersion version)
{ {
@ -1674,10 +1656,10 @@ struct JSContext
JSBool throwing; /* is there a pending exception? */ JSBool throwing; /* is there a pending exception? */
js::Value exception; /* most-recently-thrown exception */ js::Value exception; /* most-recently-thrown exception */
/* Per-context run options. */
uintN runOptions; /* see jsapi.h for JSOPTION_* */
public: public:
/* Per-context options. */
uint32 options; /* see jsapi.h for JSOPTION_* */
/* Locale specific callbacks for string conversion. */ /* Locale specific callbacks for string conversion. */
JSLocaleCallbacks *localeCallbacks; JSLocaleCallbacks *localeCallbacks;
@ -1849,7 +1831,7 @@ struct JSContext
return fp; return fp;
} }
public: private:
/* /*
* The default script compilation version can be set iff there is no code running. * The default script compilation version can be set iff there is no code running.
* This typically occurs via the JSAPI right after a context is constructed. * This typically occurs via the JSAPI right after a context is constructed.
@ -1865,20 +1847,20 @@ struct JSContext
hasVersionOverride = true; hasVersionOverride = true;
} }
public:
void clearVersionOverride() {
hasVersionOverride = false;
}
bool isVersionOverridden() const {
return hasVersionOverride;
}
/* Set the default script compilation version. */ /* Set the default script compilation version. */
void setDefaultVersion(JSVersion version) { void setDefaultVersion(JSVersion version) {
defaultVersion = version; defaultVersion = version;
} }
void clearVersionOverride() { hasVersionOverride = false; }
JSVersion getDefaultVersion() const { return defaultVersion; }
bool isVersionOverridden() const { return hasVersionOverride; }
JSVersion getVersionOverride() const {
JS_ASSERT(isVersionOverridden());
return versionOverride;
}
/* /*
* Set the default version if possible; otherwise, force the version. * Set the default version if possible; otherwise, force the version.
* Return whether an override occurred. * Return whether an override occurred.
@ -1892,23 +1874,6 @@ struct JSContext
return true; return true;
} }
private:
/*
* If there is no code currently executing, turn the override version into
* the default version.
*
* NB: the only time the version is potentially capable of migrating is
* on return from the Execute or ExternalInvoke paths as they call through
* JSContext::popSegmentAndFrame.
*/
void maybeMigrateVersionOverride() {
if (JS_LIKELY(!isVersionOverridden() || currentSegment))
return;
defaultVersion = versionOverride;
clearVersionOverride();
}
public:
/* /*
* Return: * Return:
* - The override version, if there is an override version. * - The override version, if there is an override version.
@ -1933,34 +1898,30 @@ struct JSContext
return defaultVersion; return defaultVersion;
} }
void setRunOptions(uintN ropts) { void optionFlagsToVersion(JSVersion *version) const {
JS_ASSERT((ropts & JSRUNOPTION_MASK) == ropts); js::VersionSetXML(version, js::OptionsHasXML(options));
runOptions = ropts; js::VersionSetAnonFunFix(version, js::OptionsHasAnonFunFix(options));
}
void checkOptionVersionSync() const {
#ifdef DEBUG
JSVersion version = findVersion();
JS_ASSERT(js::VersionHasXML(version) == js::OptionsHasXML(options));
JS_ASSERT(js::VersionHasAnonFunFix(version) == js::OptionsHasAnonFunFix(options));
#endif
} }
/* Note: may override the version. */ /* Note: may override the version. */
void setCompileOptions(uintN newcopts) { void syncOptionsToVersion() {
JS_ASSERT((newcopts & JSCOMPILEOPTION_MASK) == newcopts);
if (JS_LIKELY(getCompileOptions() == newcopts))
return;
JSVersion version = findVersion(); JSVersion version = findVersion();
JSVersion newVersion = js::OptionFlagsToVersion(newcopts, version); if (js::OptionsHasXML(options) == js::VersionHasXML(version) &&
maybeOverrideVersion(newVersion); js::OptionsHasAnonFunFix(options) == js::VersionHasAnonFunFix(version))
return;
js::VersionSetXML(&version, js::OptionsHasXML(options));
js::VersionSetAnonFunFix(&version, js::OptionsHasAnonFunFix(options));
maybeOverrideVersion(version);
} }
uintN getRunOptions() const { return runOptions; }
uintN getCompileOptions() const { return js::VersionFlagsToOptions(findVersion()); }
uintN allOptions() const { return getRunOptions() | getCompileOptions(); }
bool hasRunOption(uintN ropt) const {
JS_ASSERT((ropt & JSRUNOPTION_MASK) == ropt);
return !!(runOptions & ropt);
}
bool hasStrictOption() const { return hasRunOption(JSOPTION_STRICT); }
bool hasWErrorOption() const { return hasRunOption(JSOPTION_WERROR); }
bool hasAtLineOption() const { return hasRunOption(JSOPTION_ATLINE); }
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
JSThread *thread; JSThread *thread;
unsigned outstandingRequests;/* number of JS_BeginRequest calls unsigned outstandingRequests;/* number of JS_BeginRequest calls

Просмотреть файл

@ -1483,8 +1483,8 @@ JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
*/ */
JSScript *script = Compiler::compileScript(cx, scobj, fp, js_StackFramePrincipals(cx, fp), JSScript *script = Compiler::compileScript(cx, scobj, fp, js_StackFramePrincipals(cx, fp),
TCF_COMPILE_N_GO, chars, length, TCF_COMPILE_N_GO, chars, length,
filename, lineno, cx->findVersion(), filename, lineno, NULL,
NULL, UpvarCookie::UPVAR_LEVEL_LIMIT); UpvarCookie::UPVAR_LEVEL_LIMIT);
if (!script) if (!script)
return false; return false;

Просмотреть файл

@ -464,7 +464,7 @@ struct JSTreeContext { /* tree context for semantic checks */
* JSOPTION_STRICT warnings or strict mode errors. * JSOPTION_STRICT warnings or strict mode errors.
*/ */
inline bool JSTreeContext::needStrictChecks() { inline bool JSTreeContext::needStrictChecks() {
return parser->context->hasStrictOption() || inStrictMode(); return JS_HAS_STRICT_OPTION(parser->context) || inStrictMode();
} }
/* /*
@ -653,18 +653,17 @@ struct JSCodeGenerator : public JSTreeContext
*/ */
bool addGlobalUse(JSAtom *atom, uint32 slot, js::UpvarCookie *cookie); bool addGlobalUse(JSAtom *atom, uint32 slot, js::UpvarCookie *cookie);
bool hasSharps() const { bool hasSharps() {
bool rv = !!(flags & TCF_HAS_SHARPS); bool rv = !!(flags & TCF_HAS_SHARPS);
JS_ASSERT((sharpSlotBase >= 0) == rv); JS_ASSERT((sharpSlotBase >= 0) == rv);
return rv; return rv;
} }
uintN sharpSlots() const { uintN sharpSlots() {
return hasSharps() ? SHARP_NSLOTS : 0; return hasSharps() ? SHARP_NSLOTS : 0;
} }
bool compilingForEval() const { return !!(flags & TCF_COMPILE_FOR_EVAL); } bool compilingForEval() { return !!(flags & TCF_COMPILE_FOR_EVAL); }
JSVersion version() const { return parser->versionWithFlags(); }
bool shouldNoteClosedName(JSParseNode *pn); bool shouldNoteClosedName(JSParseNode *pn);

Просмотреть файл

@ -404,8 +404,7 @@ WrapEscapingClosure(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
? script->globals()->length ? script->globals()->length
: 0, : 0,
script->nClosedArgs, script->nClosedArgs,
script->nClosedVars, script->nClosedVars);
script->getVersion());
if (!wscript) if (!wscript)
return NULL; return NULL;
@ -470,7 +469,7 @@ WrapEscapingClosure(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
* Fill in the rest of wscript. This means if you add members to JSScript * Fill in the rest of wscript. This means if you add members to JSScript
* you must update this code. FIXME: factor into JSScript::clone method. * you must update this code. FIXME: factor into JSScript::clone method.
*/ */
JS_ASSERT(wscript->getVersion() == script->getVersion()); wscript->setVersion(script->getVersion());
wscript->nfixed = script->nfixed; wscript->nfixed = script->nfixed;
wscript->filename = script->filename; wscript->filename = script->filename;
wscript->lineno = script->lineno; wscript->lineno = script->lineno;
@ -2513,7 +2512,7 @@ Function(JSContext *cx, uintN argc, Value *vp)
/* Initialize a tokenstream that reads from the given string. */ /* Initialize a tokenstream that reads from the given string. */
TokenStream ts(cx); TokenStream ts(cx);
if (!ts.init(collected_args, args_length, filename, lineno, cx->findVersion())) { if (!ts.init(cx->findVersion(), collected_args, args_length, filename, lineno)) {
JS_ARENA_RELEASE(&cx->tempPool, mark); JS_ARENA_RELEASE(&cx->tempPool, mark);
return JS_FALSE; return JS_FALSE;
} }
@ -2602,7 +2601,7 @@ Function(JSContext *cx, uintN argc, Value *vp)
return JS_FALSE; return JS_FALSE;
return Compiler::compileFunctionBody(cx, fun, principals, &bindings, return Compiler::compileFunctionBody(cx, fun, principals, &bindings,
chars, length, filename, lineno, cx->findVersion()); chars, length, filename, lineno);
} }
static JSBool static JSBool
@ -2626,9 +2625,10 @@ js_InitFunctionClass(JSContext *cx, JSObject *obj)
return NULL; return NULL;
fun->flags |= JSFUN_PROTOTYPE; fun->flags |= JSFUN_PROTOTYPE;
JSScript *script = JSScript::NewScript(cx, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, JSVERSION_DEFAULT); JSScript *script = JSScript::NewScript(cx, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
if (!script) if (!script)
return NULL; return NULL;
script->setVersion(JSVERSION_DEFAULT);
script->noScriptRval = true; script->noScriptRval = true;
script->code[0] = JSOP_STOP; script->code[0] = JSOP_STOP;
script->code[1] = SRC_NULL; script->code[1] = SRC_NULL;

Просмотреть файл

@ -1620,7 +1620,7 @@ MarkContext(JSTracer *trc, JSContext *acx)
/* Stack frames and slots are traced by StackSpace::mark. */ /* Stack frames and slots are traced by StackSpace::mark. */
/* Mark other roots-by-definition in acx. */ /* Mark other roots-by-definition in acx. */
if (acx->globalObject && !acx->hasRunOption(JSOPTION_UNROOTED_GLOBAL)) if (acx->globalObject && !JS_HAS_OPTION(acx, JSOPTION_UNROOTED_GLOBAL))
MarkObject(trc, *acx->globalObject, "global object"); MarkObject(trc, *acx->globalObject, "global object");
if (acx->isExceptionPending()) if (acx->isExceptionPending())
MarkValue(trc, acx->getPendingException(), "exception"); MarkValue(trc, acx->getPendingException(), "exception");

Просмотреть файл

@ -963,7 +963,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
return false; return false;
frame.fp()->globalThis().setObject(*thisp); frame.fp()->globalThis().setObject(*thisp);
initialVarObj = cx->hasRunOption(JSOPTION_VAROBJFIX) ? chain->getGlobal() : chain; initialVarObj = (cx->options & JSOPTION_VAROBJFIX) ? chain->getGlobal() : chain;
} }
/* /*

Просмотреть файл

@ -1051,7 +1051,7 @@ EvalCacheLookup(JSContext *cx, JSLinearString *str, JSStackFrame *caller, uintN
while ((script = *scriptp) != NULL) { while ((script = *scriptp) != NULL) {
if (script->savedCallerFun && if (script->savedCallerFun &&
script->staticLevel == staticLevel && script->staticLevel == staticLevel &&
script->getVersion() == version && script->version == version &&
!script->hasSingletons && !script->hasSingletons &&
(script->principals == principals || (script->principals == principals ||
(principals->subsume(principals, script->principals) && (principals->subsume(principals, script->principals) &&
@ -1258,8 +1258,7 @@ EvalKernel(JSContext *cx, uintN argc, Value *vp, EvalType evalType, JSStackFrame
uint32 tcflags = TCF_COMPILE_N_GO | TCF_NEED_MUTABLE_SCRIPT | TCF_COMPILE_FOR_EVAL; uint32 tcflags = TCF_COMPILE_N_GO | TCF_NEED_MUTABLE_SCRIPT | TCF_COMPILE_FOR_EVAL;
script = Compiler::compileScript(cx, scopeobj, callerFrame, script = Compiler::compileScript(cx, scopeobj, callerFrame,
principals, tcflags, chars, length, principals, tcflags, chars, length,
filename, lineno, cx->findVersion(), filename, lineno, linearStr, staticLevel);
linearStr, staticLevel);
if (!script) if (!script)
return false; return false;
} }
@ -5275,7 +5274,7 @@ js_GetPropertyHelperWithShapeInline(JSContext *cx, JSObject *obj, JSObject *rece
if (op == JSOP_GETXPROP) { if (op == JSOP_GETXPROP) {
flags = JSREPORT_ERROR; flags = JSREPORT_ERROR;
} else { } else {
if (!cx->hasStrictOption() || if (!JS_HAS_STRICT_OPTION(cx) ||
(op != JSOP_GETPROP && op != JSOP_GETELEM) || (op != JSOP_GETPROP && op != JSOP_GETELEM) ||
js_CurrentPCIsInImacro(cx)) { js_CurrentPCIsInImacro(cx)) {
return JS_TRUE; return JS_TRUE;
@ -5408,7 +5407,7 @@ js_CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname)
/* If neither cx nor the code is strict, then no check is needed. */ /* If neither cx nor the code is strict, then no check is needed. */
if (!(fp->isScriptFrame() && fp->script()->strictModeCode) && if (!(fp->isScriptFrame() && fp->script()->strictModeCode) &&
!cx->hasStrictOption()) { !JS_HAS_STRICT_OPTION(cx)) {
return true; return true;
} }
@ -5484,7 +5483,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
if (pd.attrs & JSPROP_READONLY) { if (pd.attrs & JSPROP_READONLY) {
if (strict) if (strict)
return obj->reportReadOnly(cx, id); return obj->reportReadOnly(cx, id);
if (cx->hasStrictOption()) if (JS_HAS_STRICT_OPTION(cx))
return obj->reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING); return obj->reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
return true; return true;
} }
@ -5529,7 +5528,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
/* Error in strict mode code, warn with strict option, otherwise do nothing. */ /* Error in strict mode code, warn with strict option, otherwise do nothing. */
if (strict) if (strict)
return obj->reportReadOnly(cx, id); return obj->reportReadOnly(cx, id);
if (cx->hasStrictOption()) if (JS_HAS_STRICT_OPTION(cx))
return obj->reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING); return obj->reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
return JS_TRUE; return JS_TRUE;
} }
@ -5622,7 +5621,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
/* Error in strict mode code, warn with strict option, otherwise do nothing. */ /* Error in strict mode code, warn with strict option, otherwise do nothing. */
if (strict) if (strict)
return obj->reportNotExtensible(cx); return obj->reportNotExtensible(cx);
if (cx->hasStrictOption()) if (JS_HAS_STRICT_OPTION(cx))
return obj->reportNotExtensible(cx, JSREPORT_STRICT | JSREPORT_WARNING); return obj->reportNotExtensible(cx, JSREPORT_STRICT | JSREPORT_WARNING);
return JS_TRUE; return JS_TRUE;
} }

Просмотреть файл

@ -203,12 +203,13 @@ Parser::Parser(JSContext *cx, JSPrincipals *prin, JSStackFrame *cfp)
} }
bool bool
Parser::init(const jschar *base, size_t length, const char *filename, uintN lineno, Parser::init(const jschar *base, size_t length, const char *filename, uintN lineno)
JSVersion version)
{ {
JSContext *cx = context; JSContext *cx = context;
version = cx->findVersion();
tempPoolMark = JS_ARENA_MARK(&cx->tempPool); tempPoolMark = JS_ARENA_MARK(&cx->tempPool);
if (!tokenStream.init(base, length, filename, lineno, version)) { if (!tokenStream.init(version, base, length, filename, lineno)) {
JS_ARENA_RELEASE(&cx->tempPool, tempPoolMark); JS_ARENA_RELEASE(&cx->tempPool, tempPoolMark);
return false; return false;
} }
@ -886,7 +887,7 @@ JSScript *
Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *callerFrame, Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *callerFrame,
JSPrincipals *principals, uint32 tcflags, JSPrincipals *principals, uint32 tcflags,
const jschar *chars, size_t length, const jschar *chars, size_t length,
const char *filename, uintN lineno, JSVersion version, const char *filename, uintN lineno,
JSString *source /* = NULL */, JSString *source /* = NULL */,
uintN staticLevel /* = 0 */) uintN staticLevel /* = 0 */)
{ {
@ -910,7 +911,7 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *calle
JS_ASSERT_IF(staticLevel != 0, callerFrame); JS_ASSERT_IF(staticLevel != 0, callerFrame);
Compiler compiler(cx, principals, callerFrame); Compiler compiler(cx, principals, callerFrame);
if (!compiler.init(chars, length, filename, lineno, version)) if (!compiler.init(chars, length, filename, lineno))
return NULL; return NULL;
JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode), JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode),
@ -1031,7 +1032,6 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *calle
if (!js_EmitTree(cx, &cg, pn)) if (!js_EmitTree(cx, &cg, pn))
goto out; goto out;
#if JS_HAS_XML_SUPPORT #if JS_HAS_XML_SUPPORT
if (PN_TYPE(pn) != TOK_SEMI || if (PN_TYPE(pn) != TOK_SEMI ||
!pn->pn_kid || !pn->pn_kid ||
@ -1109,18 +1109,13 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *calle
*/ */
if (js_Emit1(cx, &cg, JSOP_STOP) < 0) if (js_Emit1(cx, &cg, JSOP_STOP) < 0)
goto out; goto out;
#ifdef METER_PARSENODES #ifdef METER_PARSENODES
printf("Code-gen growth: %d (%u bytecodes, %u srcnotes)\n", printf("Code-gen growth: %d (%u bytecodes, %u srcnotes)\n",
(char *)sbrk(0) - (char *)before, CG_OFFSET(&cg), cg.noteCount); (char *)sbrk(0) - (char *)before, CG_OFFSET(&cg), cg.noteCount);
#endif #endif
#ifdef JS_ARENAMETER #ifdef JS_ARENAMETER
JS_DumpArenaStats(stdout); JS_DumpArenaStats(stdout);
#endif #endif
JS_ASSERT(cg.version() == version);
script = JSScript::NewScriptFromCG(cx, &cg); script = JSScript::NewScriptFromCG(cx, &cg);
if (script && funbox) if (script && funbox)
script->savedCallerFun = true; script->savedCallerFun = true;
@ -1549,7 +1544,7 @@ Parser::functionBody()
pn->pn_pos.begin.lineno = firstLine; pn->pn_pos.begin.lineno = firstLine;
/* Check for falling off the end of a function that returns a value. */ /* Check for falling off the end of a function that returns a value. */
if (context->hasStrictOption() && (tc->flags & TCF_RETURN_EXPR) && if (JS_HAS_STRICT_OPTION(context) && (tc->flags & TCF_RETURN_EXPR) &&
!CheckFinalReturn(context, tc, pn)) { !CheckFinalReturn(context, tc, pn)) {
pn = NULL; pn = NULL;
} }
@ -1787,11 +1782,11 @@ DefineArg(JSParseNode *pn, JSAtom *atom, uintN i, JSTreeContext *tc)
bool bool
Compiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals, Compiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals,
Bindings *bindings, const jschar *chars, size_t length, Bindings *bindings, const jschar *chars, size_t length,
const char *filename, uintN lineno, JSVersion version) const char *filename, uintN lineno)
{ {
Compiler compiler(cx, principals); Compiler compiler(cx, principals);
if (!compiler.init(chars, length, filename, lineno, version)) if (!compiler.init(chars, length, filename, lineno))
return false; return false;
/* No early return from after here until the js_FinishArenaPool calls. */ /* No early return from after here until the js_FinishArenaPool calls. */
@ -3041,7 +3036,7 @@ Parser::functionDef(JSAtom *funAtom, FunctionType type, uintN lambda)
JS_ASSERT(!dn->pn_used); JS_ASSERT(!dn->pn_used);
JS_ASSERT(dn->pn_defn); JS_ASSERT(dn->pn_defn);
if (context->hasStrictOption() || dn_kind == JSDefinition::CONST) { if (JS_HAS_STRICT_OPTION(context) || dn_kind == JSDefinition::CONST) {
JSAutoByteString name; JSAutoByteString name;
if (!js_AtomToPrintableString(context, funAtom, &name) || if (!js_AtomToPrintableString(context, funAtom, &name) ||
!reportErrorNumber(NULL, !reportErrorNumber(NULL,
@ -3354,7 +3349,7 @@ Parser::functionStmt()
if (tokenStream.getToken(TSF_KEYWORD_IS_NAME) == TOK_NAME) { if (tokenStream.getToken(TSF_KEYWORD_IS_NAME) == TOK_NAME) {
name = tokenStream.currentToken().t_atom; name = tokenStream.currentToken().t_atom;
} else { } else {
if (hasAnonFunFix()) { if (context->options & JSOPTION_ANONFUNFIX) {
/* Extension: accept unnamed function expressions as statements. */ /* Extension: accept unnamed function expressions as statements. */
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_SYNTAX_ERROR); reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_SYNTAX_ERROR);
return NULL; return NULL;
@ -3915,7 +3910,7 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
(dn_kind == JSDefinition::LET && (dn_kind == JSDefinition::LET &&
(stmt->type != STMT_CATCH || OuterLet(tc, stmt, atom)))); (stmt->type != STMT_CATCH || OuterLet(tc, stmt, atom))));
if (cx->hasStrictOption() if (JS_HAS_STRICT_OPTION(cx)
? op != JSOP_DEFVAR || dn_kind != JSDefinition::VAR ? op != JSOP_DEFVAR || dn_kind != JSDefinition::VAR
: error) { : error) {
JSAutoByteString name; JSAutoByteString name;
@ -4806,7 +4801,7 @@ Parser::returnOrYield(bool useAssignExpr)
return NULL; return NULL;
} }
if (context->hasStrictOption() && if (JS_HAS_STRICT_OPTION(context) &&
(~tc->flags & (TCF_RETURN_EXPR | TCF_RETURN_VOID)) == 0 && (~tc->flags & (TCF_RETURN_EXPR | TCF_RETURN_VOID)) == 0 &&
!ReportBadReturn(context, tc, JSREPORT_WARNING | JSREPORT_STRICT, !ReportBadReturn(context, tc, JSREPORT_WARNING | JSREPORT_STRICT,
JSMSG_NO_RETURN_VALUE, JSMSG_NO_RETURN_VALUE,
@ -5264,7 +5259,7 @@ Parser::forStatement()
if (TokenKindIsDecl(tt) if (TokenKindIsDecl(tt)
? (pn1->pn_count > 1 || pn1->pn_op == JSOP_DEFCONST ? (pn1->pn_count > 1 || pn1->pn_op == JSOP_DEFCONST
#if JS_HAS_DESTRUCTURING #if JS_HAS_DESTRUCTURING
|| (versionNumber() == JSVERSION_1_7 && || (VersionNumber(version) == JSVERSION_1_7 &&
pn->pn_op == JSOP_ITER && pn->pn_op == JSOP_ITER &&
!(pn->pn_iflags & JSITER_FOREACH) && !(pn->pn_iflags & JSITER_FOREACH) &&
(pn1->pn_head->pn_type == TOK_RC || (pn1->pn_head->pn_type == TOK_RC ||
@ -5278,7 +5273,7 @@ Parser::forStatement()
: (pn1->pn_type != TOK_NAME && : (pn1->pn_type != TOK_NAME &&
pn1->pn_type != TOK_DOT && pn1->pn_type != TOK_DOT &&
#if JS_HAS_DESTRUCTURING #if JS_HAS_DESTRUCTURING
((versionNumber() == JSVERSION_1_7 && ((VersionNumber(version) == JSVERSION_1_7 &&
pn->pn_op == JSOP_ITER && pn->pn_op == JSOP_ITER &&
!(pn->pn_iflags & JSITER_FOREACH)) !(pn->pn_iflags & JSITER_FOREACH))
? (pn1->pn_type != TOK_RB || pn1->pn_count != 2) ? (pn1->pn_type != TOK_RB || pn1->pn_count != 2)
@ -5391,7 +5386,7 @@ Parser::forStatement()
if (pn1 == pn2 && !CheckDestructuring(context, NULL, pn2, NULL, tc)) if (pn1 == pn2 && !CheckDestructuring(context, NULL, pn2, NULL, tc))
return NULL; return NULL;
if (versionNumber() == JSVERSION_1_7) { if (VersionNumber(version) == JSVERSION_1_7) {
/* /*
* Destructuring for-in requires [key, value] enumeration * Destructuring for-in requires [key, value] enumeration
* in JS1.7. * in JS1.7.
@ -6023,7 +6018,7 @@ Parser::statement()
PopStatement(tc); PopStatement(tc);
pn->pn_pos.end = pn3->pn_pos.end; pn->pn_pos.end = pn3->pn_pos.end;
pn->pn_right = pn3; pn->pn_right = pn3;
if (versionNumber() != JSVERSION_ECMA_3) { if (VersionNumber(version) != JSVERSION_ECMA_3) {
/* /*
* All legacy and extended versions must do automatic semicolon * All legacy and extended versions must do automatic semicolon
* insertion after do-while. See the testcase and discussion in * insertion after do-while. See the testcase and discussion in
@ -7258,7 +7253,7 @@ Parser::comprehensionTail(JSParseNode *kid, uintN blockid,
if (!CheckDestructuring(context, &data, pn3, NULL, tc)) if (!CheckDestructuring(context, &data, pn3, NULL, tc))
return NULL; return NULL;
if (versionNumber() == JSVERSION_1_7) { if (VersionNumber(version) == JSVERSION_1_7) {
/* Destructuring requires [key, value] enumeration in JS1.7. */ /* Destructuring requires [key, value] enumeration in JS1.7. */
if (pn3->pn_type != TOK_RB || pn3->pn_count != 2) { if (pn3->pn_type != TOK_RB || pn3->pn_count != 2) {
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_BAD_FOR_LEFTSIDE); reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_BAD_FOR_LEFTSIDE);
@ -8263,16 +8258,26 @@ Parser::xmlElementOrList(JSBool allowList)
JSParseNode * JSParseNode *
Parser::xmlElementOrListRoot(JSBool allowList) Parser::xmlElementOrListRoot(JSBool allowList)
{ {
uint32 oldopts;
JSParseNode *pn;
/* /*
* Force XML support to be enabled so that comments and CDATA literals * Force XML support to be enabled so that comments and CDATA literals
* are recognized, instead of <! followed by -- starting an HTML comment * are recognized, instead of <! followed by -- starting an HTML comment
* to end of line (used in script tags to hide content from old browsers * to end of line (used in script tags to hide content from old browsers
* that don't recognize <script>). * that don't recognize <script>).
*/ */
bool hadXML = tokenStream.hasXML(); oldopts = JS_SetOptions(context, context->options | JSOPTION_XML);
tokenStream.setXML(true); version = context->findVersion();
JSParseNode *pn = xmlElementOrList(allowList); tokenStream.setVersion(version);
tokenStream.setXML(hadXML); JS_ASSERT(VersionHasXML(version));
pn = xmlElementOrList(allowList);
JS_SetOptions(context, oldopts);
version = context->findVersion();
tokenStream.setVersion(version);
JS_ASSERT(!!(oldopts & JSOPTION_XML) == VersionHasXML(version));
return pn; return pn;
} }

Просмотреть файл

@ -1043,7 +1043,7 @@ struct Parser : private js::AutoGCRooter
JSContext * const context; /* FIXME Bug 551291: use AutoGCRooter::context? */ JSContext * const context; /* FIXME Bug 551291: use AutoGCRooter::context? */
JSAtomListElement *aleFreeList; JSAtomListElement *aleFreeList;
void *tempFreeList[NUM_TEMP_FREELISTS]; void *tempFreeList[NUM_TEMP_FREELISTS];
TokenStream tokenStream; js::TokenStream tokenStream;
void *tempPoolMark; /* initial JSContext.tempPool mark */ void *tempPoolMark; /* initial JSContext.tempPool mark */
JSPrincipals *principals; /* principals associated with source */ JSPrincipals *principals; /* principals associated with source */
JSStackFrame *const callerFrame; /* scripted caller frame for eval and dbgapi */ JSStackFrame *const callerFrame; /* scripted caller frame for eval and dbgapi */
@ -1052,6 +1052,7 @@ struct Parser : private js::AutoGCRooter
uint32 functionCount; /* number of functions in current unit */ uint32 functionCount; /* number of functions in current unit */
JSObjectBox *traceListHead; /* list of parsed object for GC tracing */ JSObjectBox *traceListHead; /* list of parsed object for GC tracing */
JSTreeContext *tc; /* innermost tree context (stack-allocated) */ JSTreeContext *tc; /* innermost tree context (stack-allocated) */
JSVersion version; /* cached version to avoid repeated lookups */
/* Root atoms and objects allocated for the parsed tree. */ /* Root atoms and objects allocated for the parsed tree. */
js::AutoKeepAtoms keepAtoms; js::AutoKeepAtoms keepAtoms;
@ -1069,16 +1070,15 @@ struct Parser : private js::AutoGCRooter
* JSContext.tempPool mark. This means you cannot allocate from tempPool * JSContext.tempPool mark. This means you cannot allocate from tempPool
* and save the pointer beyond the next Parser destructor invocation. * and save the pointer beyond the next Parser destructor invocation.
*/ */
bool init(const jschar *base, size_t length, const char *filename, uintN lineno, bool init(const jschar *base, size_t length,
JSVersion version); const char *filename, uintN lineno);
void setPrincipals(JSPrincipals *prin); void setPrincipals(JSPrincipals *prin);
const char *getFilename() const { return tokenStream.getFilename(); } const char *getFilename()
JSVersion versionWithFlags() const { return tokenStream.versionWithFlags(); } {
JSVersion versionNumber() const { return tokenStream.versionNumber(); } return tokenStream.getFilename();
bool hasXML() const { return tokenStream.hasXML(); } }
bool hasAnonFunFix() const { return tokenStream.hasAnonFunFix(); }
/* /*
* Parse a top-level JS script. * Parse a top-level JS script.
@ -1217,25 +1217,28 @@ struct Compiler
* Initialize a compiler. Parameters are passed on to init parser. * Initialize a compiler. Parameters are passed on to init parser.
*/ */
inline bool inline bool
init(const jschar *base, size_t length, const char *filename, uintN lineno, JSVersion version) init(const jschar *base, size_t length,
const char *filename, uintN lineno)
{ {
return parser.init(base, length, filename, lineno, version); return parser.init(base, length, filename, lineno);
} }
static bool static bool
compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals, compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals,
js::Bindings *bindings, const jschar *chars, size_t length, js::Bindings *bindings, const jschar *chars, size_t length,
const char *filename, uintN lineno, JSVersion version); const char *filename, uintN lineno);
static JSScript * static JSScript *
compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *callerFrame, compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *callerFrame,
JSPrincipals *principals, uint32 tcflags, JSPrincipals *principals, uint32 tcflags,
const jschar *chars, size_t length, const jschar *chars, size_t length,
const char *filename, uintN lineno, JSVersion version, const char *filename, uintN lineno,
JSString *source = NULL, uintN staticLevel = 0); JSString *source = NULL,
uintN staticLevel = 0);
private: private:
static bool defineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript *script); static bool
defineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript *script);
}; };
} /* namespace js */ } /* namespace js */

Просмотреть файл

@ -3279,7 +3279,7 @@ reflect_parse(JSContext *cx, uint32 argc, jsval *vp)
Parser parser(cx); Parser parser(cx);
if (!parser.init(chars, length, filename, lineno, cx->findVersion())) if (!parser.init(chars, length, filename, lineno))
return JS_FALSE; return JS_FALSE;
JSParseNode *pn = parser.parse(NULL); JSParseNode *pn = parser.parse(NULL);

Просмотреть файл

@ -183,12 +183,12 @@ TokenStream::TokenStream(JSContext *cx)
#endif #endif
bool bool
TokenStream::init(const jschar *base, size_t length, const char *fn, uintN ln, JSVersion v) TokenStream::init(JSVersion version, const jschar *base, size_t length, const char *fn, uintN ln)
{ {
this->version = version;
filename = fn; filename = fn;
lineno = ln; lineno = ln;
version = v;
xml = VersionHasXML(v);
userbuf.base = (jschar *)base; userbuf.base = (jschar *)base;
userbuf.limit = (jschar *)base + length; userbuf.limit = (jschar *)base + length;
@ -428,11 +428,11 @@ TokenStream::reportCompileErrorNumberVA(JSParseNode *pn, uintN flags, uintN erro
uintN index, i; uintN index, i;
JSErrorReporter onError; JSErrorReporter onError;
if (JSREPORT_IS_STRICT(flags) && !cx->hasStrictOption()) if (JSREPORT_IS_STRICT(flags) && !JS_HAS_STRICT_OPTION(cx))
return JS_TRUE; return JS_TRUE;
warning = JSREPORT_IS_WARNING(flags); warning = JSREPORT_IS_WARNING(flags);
if (warning && cx->hasWErrorOption()) { if (warning && JS_HAS_WERROR_OPTION(cx)) {
flags &= ~JSREPORT_WARNING; flags &= ~JSREPORT_WARNING;
warning = false; warning = false;
} }
@ -583,7 +583,7 @@ js::ReportStrictModeError(JSContext *cx, TokenStream *ts, JSTreeContext *tc, JSP
if ((ts && ts->isStrictMode()) || (tc && (tc->flags & TCF_STRICT_MODE_CODE))) { if ((ts && ts->isStrictMode()) || (tc && (tc->flags & TCF_STRICT_MODE_CODE))) {
flags = JSREPORT_ERROR; flags = JSREPORT_ERROR;
} else { } else {
if (!cx->hasStrictOption()) if (!JS_HAS_STRICT_OPTION(cx))
return true; return true;
flags = JSREPORT_WARNING; flags = JSREPORT_WARNING;
} }
@ -1056,7 +1056,7 @@ TokenStream::getTokenInternal()
goto error; goto error;
} }
} else { } else {
if (kw->version <= versionNumber()) { if (kw->version <= VersionNumber(version)) {
tt = kw->tokentype; tt = kw->tokentype;
tp->t_op = (JSOp) kw->op; tp->t_op = (JSOp) kw->op;
goto out; goto out;
@ -1420,7 +1420,8 @@ TokenStream::getTokenInternal()
* *
* The check for this is in jsparse.cpp, Compiler::compileScript. * The check for this is in jsparse.cpp, Compiler::compileScript.
*/ */
if ((flags & TSF_OPERAND) && (hasXML() || peekChar() != '!')) { if ((flags & TSF_OPERAND) &&
(VersionShouldParseXML(version) || peekChar() != '!')) {
/* Check for XML comment or CDATA section. */ /* Check for XML comment or CDATA section. */
if (matchChar('!')) { if (matchChar('!')) {
tokenbuf.clear(); tokenbuf.clear();
@ -1576,7 +1577,7 @@ TokenStream::getTokenInternal()
* "//@line 123\n" sets the number of the *next* line after the * "//@line 123\n" sets the number of the *next* line after the
* comment to 123. * comment to 123.
*/ */
if (cx->hasAtLineOption()) { if (JS_HAS_ATLINE_OPTION(cx)) {
jschar cp[5]; jschar cp[5];
uintN i, line, temp; uintN i, line, temp;
char filenameBuf[1024]; char filenameBuf[1024];
@ -1794,7 +1795,7 @@ TokenStream::getTokenInternal()
} }
} }
tp->t_dval = (jsdouble) n; tp->t_dval = (jsdouble) n;
if (cx->hasStrictOption() && if (JS_HAS_STRICT_OPTION(cx) &&
(c == '=' || c == '#')) { (c == '=' || c == '#')) {
char buf[20]; char buf[20];
JS_snprintf(buf, sizeof buf, "#%u%c", n, c); JS_snprintf(buf, sizeof buf, "#%u%c", n, c);

Просмотреть файл

@ -319,8 +319,8 @@ class TokenStream
* Create a new token stream from an input buffer. * Create a new token stream from an input buffer.
* Return false on memory-allocation failure. * Return false on memory-allocation failure.
*/ */
bool init(const jschar *base, size_t length, const char *filename, uintN lineno, bool init(JSVersion version, const jschar *base, size_t length,
JSVersion version); const char *filename, uintN lineno);
void close(); void close();
~TokenStream() {} ~TokenStream() {}
@ -331,12 +331,6 @@ class TokenStream
const CharBuffer &getTokenbuf() const { return tokenbuf; } const CharBuffer &getTokenbuf() const { return tokenbuf; }
const char *getFilename() const { return filename; } const char *getFilename() const { return filename; }
uintN getLineno() const { return lineno; } uintN getLineno() const { return lineno; }
/* Note that the version and hasXML can get out of sync via setXML. */
JSVersion versionNumber() const { return VersionNumber(version); }
JSVersion versionWithFlags() const { return version; }
bool hasAnonFunFix() const { return VersionHasAnonFunFix(version); }
bool hasXML() const { return xml || VersionShouldParseXML(versionNumber()); }
void setXML(bool enabled) { xml = enabled; }
/* Flag methods. */ /* Flag methods. */
void setStrictMode(bool enabled = true) { setFlag(enabled, TSF_STRICT_MODE_CODE); } void setStrictMode(bool enabled = true) { setFlag(enabled, TSF_STRICT_MODE_CODE); }
@ -457,6 +451,8 @@ class TokenStream
return JS_FALSE; return JS_FALSE;
} }
void setVersion(JSVersion newVersion) { version = newVersion; }
private: private:
typedef struct TokenBuf { typedef struct TokenBuf {
jschar *base; /* base of line or stream buffer */ jschar *base; /* base of line or stream buffer */
@ -513,8 +509,7 @@ class TokenStream
CharBuffer tokenbuf; /* current token string buffer */ CharBuffer tokenbuf; /* current token string buffer */
bool maybeEOL[256]; /* probabilistic EOL lookup table */ bool maybeEOL[256]; /* probabilistic EOL lookup table */
bool maybeStrSpecial[256];/* speeds up string scanning */ bool maybeStrSpecial[256];/* speeds up string scanning */
JSVersion version; /* (i.e. to identify keywords) */ JSVersion version; /* cached version number for scan */
bool xml; /* see JSOPTION_XML */
}; };
} /* namespace js */ } /* namespace js */

Просмотреть файл

@ -576,18 +576,16 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic)
nClosedArgs = encodedClosedCount >> 16; nClosedArgs = encodedClosedCount >> 16;
nClosedVars = encodedClosedCount & 0xFFFF; nClosedVars = encodedClosedCount & 0xFFFF;
/* Note: version is packed into the 32b space with another 16b value. */
JSVersion version_ = JSVersion(version & JS_BITMASK(16));
JS_ASSERT((version_ & VersionFlags::FULL_MASK) == uintN(version_));
script = JSScript::NewScript(cx, length, nsrcnotes, natoms, nobjects, nupvars, script = JSScript::NewScript(cx, length, nsrcnotes, natoms, nobjects, nupvars,
nregexps, ntrynotes, nconsts, 0, nClosedArgs, nregexps, ntrynotes, nconsts, 0, nClosedArgs,
nClosedVars, version_); nClosedVars);
if (!script) if (!script)
return JS_FALSE; return JS_FALSE;
script->bindings.transfer(cx, &bindings); script->bindings.transfer(cx, &bindings);
script->main += prologLength; script->main += prologLength;
script->setVersion(JSVersion(version & 0xffff));
script->nfixed = uint16(version >> 16); script->nfixed = uint16(version >> 16);
/* If we know nsrcnotes, we allocated space for notes in script. */ /* If we know nsrcnotes, we allocated space for notes in script. */
@ -1215,7 +1213,7 @@ JSScript *
JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms,
uint32 nobjects, uint32 nupvars, uint32 nregexps, uint32 nobjects, uint32 nupvars, uint32 nregexps,
uint32 ntrynotes, uint32 nconsts, uint32 nglobals, uint32 ntrynotes, uint32 nconsts, uint32 nglobals,
uint16 nClosedArgs, uint16 nClosedVars, JSVersion version) uint16 nClosedArgs, uint16 nClosedVars)
{ {
size_t size, vectorSize; size_t size, vectorSize;
JSScript *script; JSScript *script;
@ -1259,7 +1257,7 @@ JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natom
PodZero(script); PodZero(script);
script->length = length; script->length = length;
script->version = version; script->setVersion(cx->findVersion());
new (&script->bindings) Bindings(cx); new (&script->bindings) Bindings(cx);
uint8 *scriptEnd = reinterpret_cast<uint8 *>(script + 1); uint8 *scriptEnd = reinterpret_cast<uint8 *>(script + 1);
@ -1397,7 +1395,6 @@ JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natom
#endif #endif
JS_APPEND_LINK(&script->links, &cx->compartment->scripts); JS_APPEND_LINK(&script->links, &cx->compartment->scripts);
JS_ASSERT(script->getVersion() == version);
return script; return script;
} }
@ -1426,7 +1423,7 @@ JSScript::NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg)
cg->atomList.count, cg->objectList.length, cg->atomList.count, cg->objectList.length,
cg->upvarList.count, cg->regexpList.length, cg->upvarList.count, cg->regexpList.length,
cg->ntrynotes, cg->constList.length(), cg->ntrynotes, cg->constList.length(),
cg->globalUses.length(), nClosedArgs, nClosedVars, cg->version()); cg->globalUses.length(), nClosedArgs, nClosedVars);
if (!script) if (!script)
return NULL; return NULL;

Просмотреть файл

@ -367,7 +367,7 @@ struct JSScript {
static JSScript *NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, static JSScript *NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms,
uint32 nobjects, uint32 nupvars, uint32 nregexps, uint32 nobjects, uint32 nupvars, uint32 nregexps,
uint32 ntrynotes, uint32 nconsts, uint32 nglobals, uint32 ntrynotes, uint32 nconsts, uint32 nglobals,
uint16 nClosedArgs, uint16 nClosedVars, JSVersion version); uint16 nClosedArgs, uint16 nClosedVars);
static JSScript *NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg); static JSScript *NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg);
@ -375,11 +375,7 @@ struct JSScript {
JSCList links; /* Links for compartment script list */ JSCList links; /* Links for compartment script list */
jsbytecode *code; /* bytecodes and their immediate operands */ jsbytecode *code; /* bytecodes and their immediate operands */
uint32 length; /* length of code vector */ uint32 length; /* length of code vector */
private:
uint16 version; /* JS version under which script was compiled */ uint16 version; /* JS version under which script was compiled */
public:
uint16 nfixed; /* number of slots besides stack operands in uint16 nfixed; /* number of slots besides stack operands in
slot array */ slot array */
@ -552,6 +548,11 @@ struct JSScript {
return JSVersion(version); return JSVersion(version);
} }
void setVersion(JSVersion newVersion) {
JS_ASSERT((newVersion & JS_BITMASK(16)) == uint32(newVersion));
version = newVersion;
}
inline JSFunction *getFunction(size_t index); inline JSFunction *getFunction(size_t index);
inline JSObject *getRegExp(size_t index); inline JSObject *getRegExp(size_t index);

Просмотреть файл

@ -1752,7 +1752,7 @@ ParseXMLSource(JSContext *cx, JSString *src)
{ {
Parser parser(cx); Parser parser(cx);
if (parser.init(chars, length, filename, lineno, cx->findVersion())) { if (parser.init(chars, length, filename, lineno)) {
JSObject *scopeChain = GetScopeChain(cx); JSObject *scopeChain = GetScopeChain(cx);
if (!scopeChain) { if (!scopeChain) {
cx->free(chars); cx->free(chars);

Просмотреть файл

@ -4128,7 +4128,7 @@ Parse(JSContext *cx, uintN argc, jsval *vp)
JSString *scriptContents = JSVAL_TO_STRING(arg0); JSString *scriptContents = JSVAL_TO_STRING(arg0);
js::Parser parser(cx); js::Parser parser(cx);
parser.init(JS_GetStringCharsZ(cx, scriptContents), JS_GetStringLength(scriptContents), parser.init(JS_GetStringCharsZ(cx, scriptContents), JS_GetStringLength(scriptContents),
"<string>", 0, cx->findVersion()); "<string>", 0);
if (!parser.parse(NULL)) if (!parser.parse(NULL))
return JS_FALSE; return JS_FALSE;
JS_SET_RVAL(cx, vp, JSVAL_VOID); JS_SET_RVAL(cx, vp, JSVAL_VOID);

Просмотреть файл

@ -523,7 +523,7 @@ function options(aOptionName)
if (aOptionName) if (aOptionName)
{ {
if (options.currvalues.hasOwnProperty(aOptionName)) if (options.currvalues[aOptionName])
{ {
// option is set, toggle it to unset // option is set, toggle it to unset
delete options.currvalues[aOptionName]; delete options.currvalues[aOptionName];
@ -543,18 +543,17 @@ function options(aOptionName)
function optionsInit() { function optionsInit() {
// hash containing the set options // hash containing the set options
options.currvalues = { options.currvalues = {strict: '',
strict: true, werror: '',
werror: true, atline: '',
atline: true, xml: '',
xml: true, relimit: '',
relimit: true, anonfunfux: ''
anonfunfix: true, }
};
// record initial values to support resetting // record initial values to support resetting
// options to their initial values // options to their initial values
options.initvalues = {}; options.initvalues = {};
// record values in a stack to support pushing // record values in a stack to support pushing
// and popping options // and popping options
@ -570,7 +569,7 @@ function optionsInit() {
} }
else else
{ {
options.initvalues[optionName] = true; options.initvalues[optionName] = '';
} }
} }
} }

Просмотреть файл

@ -647,10 +647,7 @@ function optionsClear() {
for (var i = 0; i < optionNames.length; i++) for (var i = 0; i < optionNames.length; i++)
{ {
var optionName = optionNames[i]; var optionName = optionNames[i];
if (optionName && if (optionName && optionName != "methodjit" && optionName != "tracejit" && optionName != "jitprofiling")
optionName != "methodjit" &&
optionName != "tracejit" &&
optionName != "jitprofiling")
{ {
options(optionName); options(optionName);
} }
@ -697,10 +694,8 @@ function optionsReset() {
optionsClear(); optionsClear();
// turn on initial settings // turn on initial settings
for (var optionName in options.initvalues) for (optionName in options.initvalues)
{ {
if (!options.hasOwnProperty(optionName))
continue;
options(optionName); options(optionName);
} }
} }

Просмотреть файл

@ -376,26 +376,32 @@ mozJSSubScriptLoader::LoadSubScript (const PRUnichar * aURL
* exceptions, including the source/line number */ * exceptions, including the source/line number */
er = JS_SetErrorReporter (cx, mozJSLoaderErrorReporter); er = JS_SetErrorReporter (cx, mozJSLoaderErrorReporter);
if (charset)
{ {
nsString script; JSVersion version = cx->findVersion();
rv = nsScriptLoader::ConvertToUTF16(
nsnull, reinterpret_cast<PRUint8*>(buf.get()), len,
nsDependentString(reinterpret_cast<PRUnichar*>(charset)), nsnull, script);
if (NS_FAILED(rv)) if (charset)
{ {
errmsg = JS_NewStringCopyZ(cx, LOAD_ERROR_BADCHARSET); nsString script;
goto return_exception; rv = nsScriptLoader::ConvertToUTF16(
nsnull, reinterpret_cast<PRUint8*>(buf.get()), len,
nsDependentString(reinterpret_cast<PRUnichar*>(charset)), nsnull, script);
if (NS_FAILED(rv))
{
errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_BADCHARSET);
goto return_exception;
}
ok = JS_EvaluateUCScriptForPrincipalsVersion(cx, target_obj, jsPrincipals,
reinterpret_cast<const jschar*>(script.get()),
script.Length(), uriStr.get(), 1, rval,
version);
}
else
{
ok = JS_EvaluateScriptForPrincipalsVersion(cx, target_obj, jsPrincipals,
buf, len, uriStr.get(), 1, rval,
version);
} }
ok = JS_EvaluateUCScriptForPrincipals(cx, target_obj, jsPrincipals,
reinterpret_cast<const jschar*>(script.get()),
script.Length(), uriStr.get(), 1, rval);
}
else
{
ok = JS_EvaluateScriptForPrincipals(cx, target_obj, jsPrincipals,
buf, len, uriStr.get(), 1, rval);
} }
if (ok) if (ok)

Просмотреть файл

@ -426,7 +426,7 @@ void XPCJSRuntime::TraceXPConnectRoots(JSTracer *trc)
{ {
JSContext *iter = nsnull, *acx; JSContext *iter = nsnull, *acx;
while ((acx = JS_ContextIterator(GetJSRuntime(), &iter))) { while ((acx = JS_ContextIterator(GetJSRuntime(), &iter))) {
JS_ASSERT(acx->hasRunOption(JSOPTION_UNROOTED_GLOBAL)); JS_ASSERT(JS_HAS_OPTION(acx, JSOPTION_UNROOTED_GLOBAL));
if (acx->globalObject) if (acx->globalObject)
JS_CALL_OBJECT_TRACER(trc, acx->globalObject, "global object"); JS_CALL_OBJECT_TRACER(trc, acx->globalObject, "global object");
} }
@ -628,7 +628,7 @@ JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status)
JSContext *iter = nsnull, *acx; JSContext *iter = nsnull, *acx;
while((acx = JS_ContextIterator(cx->runtime, &iter))) { while((acx = JS_ContextIterator(cx->runtime, &iter))) {
if (!acx->hasRunOption(JSOPTION_UNROOTED_GLOBAL)) if (!JS_HAS_OPTION(acx, JSOPTION_UNROOTED_GLOBAL))
JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL); JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL);
} }
break; break;

Просмотреть файл

@ -61,7 +61,6 @@ _CHROME_FILES = \
test_bug610390.xul \ test_bug610390.xul \
test_bug614757.xul \ test_bug614757.xul \
test_bug616992.xul \ test_bug616992.xul \
test_bug596580.xul \
$(NULL) $(NULL)
# Disabled until this test gets updated to test the new proxy based # Disabled until this test gets updated to test the new proxy based

Просмотреть файл

@ -1,50 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="Mozilla Bug 596580"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=596580"
target="_blank">Mozilla Bug 596580</a>
</body>
<!-- test code goes here -->
<script type="application/x-javascript;version=1.8"><![CDATA[
function init() {
var f = new Function("let test = 'let is ok'; return test;");
is(f(), 'let is ok', 'let should be ok');
SimpleTest.finish();
}
Test = {
include: function(p) {
var sawError = false;
try {
Components.classes["@mozilla.org/moz/jssubscript-loader;1"].
getService(Components.interfaces["mozIJSSubScriptLoader"]).
loadSubScript(p);
} catch (e) {
sawError = true;
}
ok(sawError, 'should receive an error loading a not-found file');
}
};
// If the include method is defined as a global function, it works.
// try to load a non existing file to produce the error
Test.include("notfound.js");
// If init is called directly, it works.
setTimeout('init();', 10);
SimpleTest.waitForExplicitFinish();
]]></script>
</window>