mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 944121: Add options argument to the JS shell's offThreadCompileScript function. For off-thread compilation, put off initializing some slots of ScriptSourceObject until after the compartment merge. r=bhackett
--HG-- rename : js/src/jit-test/tests/basic/offThreadCompileScript.js => js/src/jit-test/tests/basic/offThreadCompileScript-01.js
This commit is contained in:
parent
34f1d33ff0
commit
84f1ffacbe
17
js/src/jit-test/tests/basic/offThreadCompileScript-02.js
Normal file
17
js/src/jit-test/tests/basic/offThreadCompileScript-02.js
Normal file
@ -0,0 +1,17 @@
|
||||
// Test offThreadCompileScript option handling.
|
||||
|
||||
offThreadCompileScript('Error()');
|
||||
assertEq(!!runOffThreadScript().stack.match(/^@<string>:1\n/), true);
|
||||
|
||||
offThreadCompileScript('Error()',
|
||||
{ fileName: "candelabra", lineNumber: 6502 });
|
||||
assertEq(!!runOffThreadScript().stack.match(/^@candelabra:6502\n/), true);
|
||||
|
||||
var element = {};
|
||||
offThreadCompileScript('Error()', { element: element }); // shouldn't crash
|
||||
runOffThreadScript();
|
||||
|
||||
var elementAttribute = "molybdenum";
|
||||
elementAttribute += elementAttribute + elementAttribute + elementAttribute;
|
||||
offThreadCompileScript('Error()', { elementProperty: elementAttribute }); // shouldn't crash
|
||||
runOffThreadScript();
|
@ -990,6 +990,13 @@ ScriptSourceObject::element() const
|
||||
return getReservedSlot(ELEMENT_SLOT).toObjectOrNull();
|
||||
}
|
||||
|
||||
void
|
||||
ScriptSourceObject::initElement(HandleObject element)
|
||||
{
|
||||
JS_ASSERT(getReservedSlot(ELEMENT_SLOT).isNull());
|
||||
setReservedSlot(ELEMENT_SLOT, ObjectOrNullValue(element));
|
||||
}
|
||||
|
||||
const Value &
|
||||
ScriptSourceObject::elementProperty() const
|
||||
{
|
||||
|
@ -497,6 +497,8 @@ class ScriptSourceObject : public JSObject
|
||||
void setSource(ScriptSource *source);
|
||||
|
||||
JSObject *element() const;
|
||||
void initElement(HandleObject element);
|
||||
|
||||
const Value &elementProperty() const;
|
||||
|
||||
private:
|
||||
|
@ -191,7 +191,7 @@ ParseTask::ParseTask(ExclusiveContext *cx, JSObject *exclusiveContextGlobal, JSC
|
||||
JS::OffThreadCompileCallback callback, void *callbackData)
|
||||
: cx(cx), options(initCx), chars(chars), length(length),
|
||||
alloc(JSRuntime::TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), scopeChain(initCx, scopeChain),
|
||||
exclusiveContextGlobal(initCx, exclusiveContextGlobal), callback(callback),
|
||||
exclusiveContextGlobal(initCx, exclusiveContextGlobal), optionsElement(initCx), callback(callback),
|
||||
callbackData(callbackData), script(nullptr), errors(cx), overRecursed(false)
|
||||
{
|
||||
}
|
||||
@ -199,7 +199,15 @@ ParseTask::ParseTask(ExclusiveContext *cx, JSObject *exclusiveContextGlobal, JSC
|
||||
bool
|
||||
ParseTask::init(JSContext *cx, const ReadOnlyCompileOptions &options)
|
||||
{
|
||||
return this->options.copy(cx, options);
|
||||
if (!this->options.copy(cx, options))
|
||||
return false;
|
||||
|
||||
// Save those compilation options that the ScriptSourceObject can't
|
||||
// point at while it's in the compilation's temporary compartment.
|
||||
optionsElement = this->options.element();
|
||||
this->options.setElement(nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -209,6 +217,17 @@ ParseTask::activate(JSRuntime *rt)
|
||||
cx->enterCompartment(exclusiveContextGlobal->compartment());
|
||||
}
|
||||
|
||||
void
|
||||
ParseTask::finish()
|
||||
{
|
||||
if (script) {
|
||||
// Initialize the ScriptSourceObject slots that we couldn't while the SSO
|
||||
// was in the temporary compartment.
|
||||
ScriptSourceObject &sso = script->sourceObject()->as<ScriptSourceObject>();
|
||||
sso.initElement(optionsElement);
|
||||
}
|
||||
}
|
||||
|
||||
ParseTask::~ParseTask()
|
||||
{
|
||||
// ParseTask takes over ownership of its input exclusive context.
|
||||
@ -640,6 +659,7 @@ WorkerThreadState::finishParseTask(JSContext *maybecx, JSRuntime *rt, void *toke
|
||||
|
||||
// Move the parsed script and all its contents into the desired compartment.
|
||||
gc::MergeCompartments(parseTask->cx->compartment(), parseTask->scopeChain->compartment());
|
||||
parseTask->finish();
|
||||
|
||||
RootedScript script(rt, parseTask->script);
|
||||
|
||||
|
@ -347,6 +347,13 @@ struct ParseTask
|
||||
// Rooted pointer to the global object used by 'cx'.
|
||||
PersistentRootedObject exclusiveContextGlobal;
|
||||
|
||||
// Saved GC-managed CompileOptions fields that will populate slots in
|
||||
// the ScriptSourceObject. We create the ScriptSourceObject in the
|
||||
// compilation's temporary compartment, so storing these values there
|
||||
// at that point would create cross-compartment references. Instead we
|
||||
// hold them here, and install them after merging the compartments.
|
||||
PersistentRootedObject optionsElement;
|
||||
|
||||
// Callback invoked off the main thread when the parse finishes.
|
||||
JS::OffThreadCompileCallback callback;
|
||||
void *callbackData;
|
||||
@ -367,6 +374,7 @@ struct ParseTask
|
||||
bool init(JSContext *cx, const ReadOnlyCompileOptions &options);
|
||||
|
||||
void activate(JSRuntime *rt);
|
||||
void finish();
|
||||
|
||||
~ParseTask();
|
||||
};
|
||||
|
@ -3307,16 +3307,30 @@ OffThreadCompileScript(JSContext *cx, unsigned argc, jsval *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
JSString *scriptContents = args[0].toString();
|
||||
JSAutoByteString fileNameBytes;
|
||||
CompileOptions options(cx);
|
||||
options.setFileAndLine("<string>", 1)
|
||||
.setCompileAndGo(true)
|
||||
options.setFileAndLine("<string>", 1);
|
||||
|
||||
if (args.length() >= 2) {
|
||||
if (args[1].isPrimitive()) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "evaluate");
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedObject opts(cx, &args[1].toObject());
|
||||
if (!ParseCompileOptions(cx, options, opts, fileNameBytes))
|
||||
return false;
|
||||
}
|
||||
|
||||
// These option settings must override whatever the caller requested.
|
||||
options.setCompileAndGo(true)
|
||||
.setSourcePolicy(CompileOptions::SAVE_SOURCE);
|
||||
|
||||
// We assume the caller wants caching if at all possible, ignoring
|
||||
// heuristics that make sense for a real browser.
|
||||
options.forceAsync = true;
|
||||
|
||||
JSString *scriptContents = args[0].toString();
|
||||
const jschar *chars = JS_GetStringCharsZ(cx, scriptContents);
|
||||
if (!chars)
|
||||
return false;
|
||||
@ -4050,8 +4064,8 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
||||
" catchTermination: if true, catch termination (failure without\n"
|
||||
" an exception value, as for slow scripts or out-of-memory)\n"
|
||||
" and return 'terminated'\n"
|
||||
" element: if present with value |v|, convert |v| to an object |o| mark\n"
|
||||
" the source as being attached to the DOM element |o|. If the\n"
|
||||
" element: if present with value |v|, convert |v| to an object |o| and\n"
|
||||
" mark the source as being attached to the DOM element |o|. If the\n"
|
||||
" property is omitted or |v| is null, don't attribute the source to\n"
|
||||
" any DOM element.\n"
|
||||
" elementProperty: if present and not undefined, the name of property\n"
|
||||
@ -4245,14 +4259,26 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_FN_HELP("offThreadCompileScript", OffThreadCompileScript, 1, 0,
|
||||
"offThreadCompileScript(code)",
|
||||
" Trigger an off thread parse/emit for the input string"),
|
||||
"offThreadCompileScript(code[, options])",
|
||||
" Compile |code| on a helper thread. To wait for the compilation to finish\n"
|
||||
" and run the code, call |runOffThreadScript|. If present, |options| may\n"
|
||||
" have properties saying how the code should be compiled:\n"
|
||||
" noScriptRval: use the no-script-rval compiler option (default: false)\n"
|
||||
" fileName: filename for error messages and debug info\n"
|
||||
" lineNumber: starting line number for error messages and debug info\n"
|
||||
" element: if present with value |v|, convert |v| to an object |o| and\n"
|
||||
" mark the source as being attached to the DOM element |o|. If the\n"
|
||||
" property is omitted or |v| is null, don't attribute the source to\n"
|
||||
" any DOM element.\n"
|
||||
" elementProperty: if present and not undefined, the name of property\n"
|
||||
" of 'element' that holds this code. This is what Debugger.Source\n"
|
||||
" .prototype.elementProperty returns.\n"),
|
||||
|
||||
JS_FN_HELP("runOffThreadScript", runOffThreadScript, 0, 0,
|
||||
"runOffThreadScript()",
|
||||
" Wait for off-thread compilation to complete. If an error occurred,\n"
|
||||
" throw the appropriate exception; otherwise, run the script and return\n"
|
||||
" its value."),
|
||||
" its value."),
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user