summaryrefslogtreecommitdiffstats
path: root/js/src/frontend/BytecodeCompiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/frontend/BytecodeCompiler.cpp')
-rw-r--r--js/src/frontend/BytecodeCompiler.cpp152
1 files changed, 65 insertions, 87 deletions
diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp
index d4c758b6c..76afe80b1 100644
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -7,6 +7,7 @@
#include "frontend/BytecodeCompiler.h"
#include "mozilla/IntegerPrintfMacros.h"
+#include "mozilla/Maybe.h"
#include "jscntxt.h"
#include "jsscript.h"
@@ -28,6 +29,7 @@
using namespace js;
using namespace js::frontend;
using mozilla::Maybe;
+using mozilla::Nothing;
class MOZ_STACK_CLASS AutoCompilationTraceLogger
{
@@ -57,24 +59,24 @@ class MOZ_STACK_CLASS BytecodeCompiler
// Call setters for optional arguments.
void maybeSetSourceCompressor(SourceCompressionTask* sourceCompressor);
- void setSourceArgumentsNotIncluded();
JSScript* compileGlobalScript(ScopeKind scopeKind);
JSScript* compileEvalScript(HandleObject environment, HandleScope enclosingScope);
ModuleObject* compileModule();
- bool compileFunctionBody(MutableHandleFunction fun, Handle<PropertyNameVector> formals,
- GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
+ bool compileStandaloneFunction(MutableHandleFunction fun, GeneratorKind generatorKind,
+ FunctionAsyncKind asyncKind,
+ Maybe<uint32_t> parameterListEnd);
ScriptSourceObject* sourceObjectPtr() const;
private:
JSScript* compileScript(HandleObject environment, SharedContext* sc);
bool checkLength();
- bool createScriptSource();
+ bool createScriptSource(Maybe<uint32_t> parameterListEnd);
bool maybeCompressSource();
bool canLazilyParse();
bool createParser();
- bool createSourceAndParser();
+ bool createSourceAndParser(Maybe<uint32_t> parameterListEnd = Nothing());
bool createScript();
bool emplaceEmitter(Maybe<BytecodeEmitter>& emitter, SharedContext* sharedContext);
bool handleParseFailure(const Directives& newDirectives);
@@ -90,7 +92,6 @@ class MOZ_STACK_CLASS BytecodeCompiler
SourceBufferHolder& sourceBuffer;
RootedScope enclosingScope;
- bool sourceArgumentsNotIncluded;
RootedScriptSource sourceObject;
ScriptSource* scriptSource;
@@ -130,7 +131,6 @@ BytecodeCompiler::BytecodeCompiler(ExclusiveContext* cx,
options(options),
sourceBuffer(sourceBuffer),
enclosingScope(cx, enclosingScope),
- sourceArgumentsNotIncluded(false),
sourceObject(cx),
scriptSource(nullptr),
sourceCompressor(nullptr),
@@ -147,12 +147,6 @@ BytecodeCompiler::maybeSetSourceCompressor(SourceCompressionTask* sourceCompress
this->sourceCompressor = sourceCompressor;
}
-void
-BytecodeCompiler::setSourceArgumentsNotIncluded()
-{
- sourceArgumentsNotIncluded = true;
-}
-
bool
BytecodeCompiler::checkLength()
{
@@ -169,12 +163,12 @@ BytecodeCompiler::checkLength()
}
bool
-BytecodeCompiler::createScriptSource()
+BytecodeCompiler::createScriptSource(Maybe<uint32_t> parameterListEnd)
{
if (!checkLength())
return false;
- sourceObject = CreateScriptSourceObject(cx, options);
+ sourceObject = CreateScriptSourceObject(cx, options, parameterListEnd);
if (!sourceObject)
return false;
@@ -193,9 +187,7 @@ BytecodeCompiler::maybeCompressSource()
if (!cx->compartment()->behaviors().discardSource()) {
if (options.sourceIsLazy) {
scriptSource->setSourceRetrievable();
- } else if (!scriptSource->setSourceCopy(cx, sourceBuffer, sourceArgumentsNotIncluded,
- sourceCompressor))
- {
+ } else if (!scriptSource->setSourceCopy(cx, sourceBuffer, sourceCompressor)) {
return false;
}
}
@@ -242,9 +234,9 @@ BytecodeCompiler::createParser()
}
bool
-BytecodeCompiler::createSourceAndParser()
+BytecodeCompiler::createSourceAndParser(Maybe<uint32_t> parameterListEnd /* = Nothing() */)
{
- return createScriptSource() &&
+ return createScriptSource(parameterListEnd) &&
maybeCompressSource() &&
createParser();
}
@@ -344,10 +336,10 @@ BytecodeCompiler::compileScript(HandleObject environment, SharedContext* sc)
if (!deoptimizeArgumentsInEnclosingScripts(cx->asJSContext(), environment))
return nullptr;
}
- if (!NameFunctions(cx, pn))
- return nullptr;
if (!emitter->emitScript(pn))
return nullptr;
+ if (!NameFunctions(cx, pn))
+ return nullptr;
parser->handler.freeTree(pn);
break;
@@ -405,15 +397,15 @@ BytecodeCompiler::compileModule()
if (!pn)
return nullptr;
- if (!NameFunctions(cx, pn))
- return nullptr;
-
Maybe<BytecodeEmitter> emitter;
if (!emplaceEmitter(emitter, &modulesc))
return nullptr;
if (!emitter->emitScript(pn->pn_body))
return nullptr;
+ if (!NameFunctions(cx, pn))
+ return nullptr;
+
parser->handler.freeTree(pn);
if (!builder.initModule())
@@ -432,18 +424,19 @@ BytecodeCompiler::compileModule()
return module;
}
+// Compile a standalone JS function, which might appear as the value of an
+// event handler attribute in an HTML <INPUT> tag, or in a Function()
+// constructor.
bool
-BytecodeCompiler::compileFunctionBody(MutableHandleFunction fun,
- Handle<PropertyNameVector> formals,
- GeneratorKind generatorKind,
- FunctionAsyncKind asyncKind)
+BytecodeCompiler::compileStandaloneFunction(MutableHandleFunction fun,
+ GeneratorKind generatorKind,
+ FunctionAsyncKind asyncKind,
+ Maybe<uint32_t> parameterListEnd)
{
MOZ_ASSERT(fun);
MOZ_ASSERT(fun->isTenured());
- fun->setArgCount(formals.length());
-
- if (!createSourceAndParser())
+ if (!createSourceAndParser(parameterListEnd))
return false;
// Speculatively parse using the default directives implied by the context.
@@ -454,15 +447,12 @@ BytecodeCompiler::compileFunctionBody(MutableHandleFunction fun,
ParseNode* fn;
do {
Directives newDirectives = directives;
- fn = parser->standaloneFunctionBody(fun, enclosingScope, formals, generatorKind, asyncKind,
- directives, &newDirectives);
+ fn = parser->standaloneFunction(fun, enclosingScope, parameterListEnd, generatorKind,
+ asyncKind, directives, &newDirectives);
if (!fn && !handleParseFailure(newDirectives))
return false;
} while (!fn);
- if (!NameFunctions(cx, fn))
- return false;
-
if (fn->pn_funbox->function()->isInterpreted()) {
MOZ_ASSERT(fun == fn->pn_funbox->function());
@@ -479,6 +469,9 @@ BytecodeCompiler::compileFunctionBody(MutableHandleFunction fun,
MOZ_ASSERT(IsAsmJSModule(fun));
}
+ if (!NameFunctions(cx, fn))
+ return false;
+
if (!maybeCompleteCompressSource())
return false;
@@ -492,14 +485,15 @@ BytecodeCompiler::sourceObjectPtr() const
}
ScriptSourceObject*
-frontend::CreateScriptSourceObject(ExclusiveContext* cx, const ReadOnlyCompileOptions& options)
+frontend::CreateScriptSourceObject(ExclusiveContext* cx, const ReadOnlyCompileOptions& options,
+ Maybe<uint32_t> parameterListEnd /* = Nothing() */)
{
ScriptSource* ss = cx->new_<ScriptSource>();
if (!ss)
return nullptr;
ScriptSourceHolder ssHolder(ss);
- if (!ss->initFromOptions(cx, options))
+ if (!ss->initFromOptions(cx, options, parameterListEnd))
return nullptr;
RootedScriptSource sso(cx, ScriptSourceObject::create(cx, ss));
@@ -652,9 +646,6 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
if (!pn)
return false;
- if (!NameFunctions(cx, pn))
- return false;
-
RootedScriptSource sourceObject(cx, lazy->sourceObject());
MOZ_ASSERT(sourceObject);
@@ -673,66 +664,53 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
if (!bce.init())
return false;
- return bce.emitFunctionScript(pn->pn_body);
-}
-
-// Compile a JS function body, which might appear as the value of an event
-// handler attribute in an HTML <INPUT> tag, or in a Function() constructor.
-static bool
-CompileFunctionBody(JSContext* cx, MutableHandleFunction fun, const ReadOnlyCompileOptions& options,
- Handle<PropertyNameVector> formals, SourceBufferHolder& srcBuf,
- HandleScope enclosingScope, GeneratorKind generatorKind,
- FunctionAsyncKind asyncKind)
-{
- MOZ_ASSERT(!options.isRunOnce);
+ if (!bce.emitFunctionScript(pn->pn_body))
+ return false;
- // FIXME: make Function pass in two strings and parse them as arguments and
- // ProgramElements respectively.
+ if (!NameFunctions(cx, pn))
+ return false;
- BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, enclosingScope,
- TraceLogger_ParserCompileFunction);
- compiler.setSourceArgumentsNotIncluded();
- return compiler.compileFunctionBody(fun, formals, generatorKind, asyncKind);
+ return true;
}
bool
-frontend::CompileFunctionBody(JSContext* cx, MutableHandleFunction fun,
- const ReadOnlyCompileOptions& options,
- Handle<PropertyNameVector> formals, JS::SourceBufferHolder& srcBuf,
- HandleScope enclosingScope)
+frontend::CompileStandaloneFunction(JSContext* cx, MutableHandleFunction fun,
+ const ReadOnlyCompileOptions& options,
+ JS::SourceBufferHolder& srcBuf,
+ Maybe<uint32_t> parameterListEnd,
+ HandleScope enclosingScope /* = nullptr */)
{
- return CompileFunctionBody(cx, fun, options, formals, srcBuf, enclosingScope, NotGenerator,
- SyncFunction);
-}
+ RootedScope scope(cx, enclosingScope);
+ if (!scope)
+ scope = &cx->global()->emptyGlobalScope();
-bool
-frontend::CompileFunctionBody(JSContext* cx, MutableHandleFunction fun,
- const ReadOnlyCompileOptions& options,
- Handle<PropertyNameVector> formals, JS::SourceBufferHolder& srcBuf)
-{
- RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
- return CompileFunctionBody(cx, fun, options, formals, srcBuf, emptyGlobalScope,
- NotGenerator, SyncFunction);
+ BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, scope,
+ TraceLogger_ParserCompileFunction);
+ return compiler.compileStandaloneFunction(fun, NotGenerator, SyncFunction, parameterListEnd);
}
bool
-frontend::CompileStarGeneratorBody(JSContext* cx, MutableHandleFunction fun,
- const ReadOnlyCompileOptions& options,
- Handle<PropertyNameVector> formals,
- JS::SourceBufferHolder& srcBuf)
+frontend::CompileStandaloneGenerator(JSContext* cx, MutableHandleFunction fun,
+ const ReadOnlyCompileOptions& options,
+ JS::SourceBufferHolder& srcBuf,
+ Maybe<uint32_t> parameterListEnd)
{
RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
- return CompileFunctionBody(cx, fun, options, formals, srcBuf, emptyGlobalScope,
- StarGenerator, SyncFunction);
+
+ BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope,
+ TraceLogger_ParserCompileFunction);
+ return compiler.compileStandaloneFunction(fun, StarGenerator, SyncFunction, parameterListEnd);
}
bool
-frontend::CompileAsyncFunctionBody(JSContext* cx, MutableHandleFunction fun,
- const ReadOnlyCompileOptions& options,
- Handle<PropertyNameVector> formals,
- JS::SourceBufferHolder& srcBuf)
+frontend::CompileStandaloneAsyncFunction(JSContext* cx, MutableHandleFunction fun,
+ const ReadOnlyCompileOptions& options,
+ JS::SourceBufferHolder& srcBuf,
+ Maybe<uint32_t> parameterListEnd)
{
RootedScope emptyGlobalScope(cx, &cx->global()->emptyGlobalScope());
- return CompileFunctionBody(cx, fun, options, formals, srcBuf, emptyGlobalScope,
- StarGenerator, AsyncFunction);
+
+ BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope,
+ TraceLogger_ParserCompileFunction);
+ return compiler.compileStandaloneFunction(fun, StarGenerator, AsyncFunction, parameterListEnd);
}