diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-03-18 17:54:38 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-03-18 17:56:16 +0100 |
commit | 122938a4398ae8db07060dca3561ff46f93b5925 (patch) | |
tree | 965b4bcf2ea8133c172170cf66e5c87cf1e17df3 /js/src/frontend/BytecodeCompiler.cpp | |
parent | dda392cd4edb3258889188af5a5644eb8d36aeb7 (diff) | |
parent | af300f36f11293c12f2ee01580fc749a7e114376 (diff) | |
download | UXP-122938a4398ae8db07060dca3561ff46f93b5925.tar UXP-122938a4398ae8db07060dca3561ff46f93b5925.tar.gz UXP-122938a4398ae8db07060dca3561ff46f93b5925.tar.lz UXP-122938a4398ae8db07060dca3561ff46f93b5925.tar.xz UXP-122938a4398ae8db07060dca3561ff46f93b5925.zip |
Support ES6's "new function" construct
This resolves #75.
Merged remote-tracking branch 'janek/js_function_new_1'
Diffstat (limited to 'js/src/frontend/BytecodeCompiler.cpp')
-rw-r--r-- | js/src/frontend/BytecodeCompiler.cpp | 127 |
1 files changed, 51 insertions, 76 deletions
diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index d4c758b6c..3fbfdaa1a 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(); } @@ -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,8 +447,8 @@ 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); @@ -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)); @@ -676,63 +670,44 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha 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) +bool +frontend::CompileStandaloneFunction(JSContext* cx, MutableHandleFunction fun, + const ReadOnlyCompileOptions& options, + JS::SourceBufferHolder& srcBuf, + Maybe<uint32_t> parameterListEnd, + HandleScope enclosingScope /* = nullptr */) { - MOZ_ASSERT(!options.isRunOnce); - - // FIXME: make Function pass in two strings and parse them as arguments and - // ProgramElements respectively. + RootedScope scope(cx, enclosingScope); + if (!scope) + scope = &cx->global()->emptyGlobalScope(); - BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, enclosingScope, + BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, scope, TraceLogger_ParserCompileFunction); - compiler.setSourceArgumentsNotIncluded(); - return compiler.compileFunctionBody(fun, formals, generatorKind, asyncKind); + return compiler.compileStandaloneFunction(fun, NotGenerator, SyncFunction, parameterListEnd); } bool -frontend::CompileFunctionBody(JSContext* cx, MutableHandleFunction fun, - const ReadOnlyCompileOptions& options, - Handle<PropertyNameVector> formals, JS::SourceBufferHolder& srcBuf, - HandleScope enclosingScope) -{ - return CompileFunctionBody(cx, fun, options, formals, srcBuf, enclosingScope, NotGenerator, - SyncFunction); -} - -bool -frontend::CompileFunctionBody(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, - NotGenerator, SyncFunction); -} -bool -frontend::CompileStarGeneratorBody(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, - 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); } |