From c7ee2ad411a5e05f6140ffb9a68ff7951d57806e Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Mon, 11 May 2020 14:41:52 +0000 Subject: [PATCH] Bug 1636796 - Add ScriptStencil::intoScript. r=mgaudet This performs JSScript allocation by consuming the Stencil. For now we leave handling of delazification compiles alone. Differential Revision: https://phabricator.services.mozilla.com/D74572 --- js/src/frontend/BytecodeEmitter.cpp | 23 ++++--------------- js/src/frontend/Frontend2.cpp | 21 ++--------------- js/src/frontend/FunctionEmitter.cpp | 35 ++++++++++++++++------------- js/src/frontend/Stencil.cpp | 27 ++++++++++++++++++++++ js/src/frontend/Stencil.h | 5 +++++ 5 files changed, 58 insertions(+), 53 deletions(-) diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index fccddc23cbfd..fa617d6c3858 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -2433,27 +2433,12 @@ bool BytecodeEmitter::emitScript(ParseNode* body) { return false; } + // Create a Stencil and convert it into a JSScript. + SourceExtent extent = sc->getScriptExtent(); BCEScriptStencil stencil(*this, std::move(immutableScriptData)); + outputScript = stencil.intoScript(cx, compilationInfo, extent); - RootedObject functionOrGlobal(cx); - if (sc->isFunctionBox()) { - functionOrGlobal = sc->asFunctionBox()->function(); - } else { - functionOrGlobal = cx->global(); - } - - RootedScript script( - cx, JSScript::Create(cx, functionOrGlobal, compilationInfo.sourceObject, - sc->getScriptExtent(), stencil.immutableFlags)); - if (!script) { - return false; - } - if (!JSScript::fullyInitFromStencil(cx, compilationInfo, script, stencil)) { - return false; - } - // Script is allocated now. - outputScript = script; - return true; + return !!outputScript; } js::UniquePtr BytecodeEmitter::createImmutableScriptData( diff --git a/js/src/frontend/Frontend2.cpp b/js/src/frontend/Frontend2.cpp index a38b16303e19..ae3055e88d5f 100644 --- a/js/src/frontend/Frontend2.cpp +++ b/js/src/frontend/Frontend2.cpp @@ -414,20 +414,6 @@ JSScript* Smoosh::compileGlobalScript(CompilationInfo& compilationInfo, *unimplemented = false; - RootedScriptSourceObject sso(cx, - frontend::CreateScriptSourceObject(cx, options)); - if (!sso) { - return nullptr; - } - - RootedObject proto(cx); - if (!GetFunctionPrototype(cx, GeneratorKind::NotGenerator, - FunctionAsyncKind::SyncFunction, &proto)) { - return nullptr; - } - - SourceExtent extent = SourceExtent::makeGlobalExtent(length); - Vector scopeNotes; if (!scopeNotes.resize(smoosh.scope_notes.len)) { return nullptr; @@ -461,19 +447,16 @@ JSScript* Smoosh::compileGlobalScript(CompilationInfo& compilationInfo, return nullptr; } + SourceExtent extent = SourceExtent::makeGlobalExtent(length); SmooshScriptStencil stencil(smoosh, compilationInfo); if (!stencil.init(cx, std::move(immutableScriptData))) { return nullptr; } - RootedScript script(cx, JSScript::Create(cx, cx->global(), sso, extent, - stencil.immutableFlags)); + RootedScript script(cx, stencil.intoScript(cx, compilationInfo, extent)); if (!script) { return nullptr; } - if (!JSScript::fullyInitFromStencil(cx, compilationInfo, script, stencil)) { - return nullptr; - } #if defined(DEBUG) || defined(JS_JITSPEW) Sprinter sprinter(cx); diff --git a/js/src/frontend/FunctionEmitter.cpp b/js/src/frontend/FunctionEmitter.cpp index a2162e737e44..e20d9145721d 100644 --- a/js/src/frontend/FunctionEmitter.cpp +++ b/js/src/frontend/FunctionEmitter.cpp @@ -702,34 +702,39 @@ bool FunctionScriptEmitter::emitEndBody() { bool FunctionScriptEmitter::initScript() { MOZ_ASSERT(state_ == State::EndBody); + MOZ_ASSERT(!bce_->outputScript); + + JSContext* cx = bce_->cx; js::UniquePtr immutableScriptData = - bce_->createImmutableScriptData(bce_->cx); + bce_->createImmutableScriptData(cx); if (!immutableScriptData) { return false; } - BCEScriptStencil stencil(*bce_, std::move(immutableScriptData)); - - RootedFunction function(bce_->cx, funbox_->function()); - RootedScript script(bce_->cx); if (bce_->emitterMode == BytecodeEmitter::LazyFunction) { - script = JSScript::CastFromLazy(funbox_->function()->baseScript()); + BCEScriptStencil stencil(*bce_, std::move(immutableScriptData)); + RootedScript script( + cx, JSScript::CastFromLazy(funbox_->function()->baseScript())); + + if (!JSScript::fullyInitFromStencil(cx, bce_->compilationInfo, script, + stencil)) { + return false; + } + + bce_->outputScript = script; } else { - script = - JSScript::Create(bce_->cx, function, bce_->compilationInfo.sourceObject, - funbox_->getScriptExtent(), stencil.immutableFlags); + SourceExtent extent = funbox_->getScriptExtent(); + BCEScriptStencil stencil(*bce_, std::move(immutableScriptData)); + + RootedScript script(cx, + stencil.intoScript(cx, bce_->compilationInfo, extent)); if (!script) { return false; } - } - if (!JSScript::fullyInitFromStencil(bce_->cx, bce_->compilationInfo, script, - stencil)) { - return false; + bce_->outputScript = script; } - MOZ_ASSERT(!bce_->outputScript); - bce_->outputScript = script; #ifdef DEBUG state_ = State::End; diff --git a/js/src/frontend/Stencil.cpp b/js/src/frontend/Stencil.cpp index 4a709c1855cd..233d8319772a 100644 --- a/js/src/frontend/Stencil.cpp +++ b/js/src/frontend/Stencil.cpp @@ -6,6 +6,7 @@ #include "frontend/Stencil.h" +#include "frontend/CompilationInfo.h" #include "frontend/SharedContext.h" #include "js/TracingAPI.h" #include "vm/EnvironmentObject.h" @@ -214,3 +215,29 @@ void ScriptStencilBase::trace(JSTracer* trc) { } } } + +JSScript* ScriptStencil::intoScript(JSContext* cx, + CompilationInfo& compilationInfo, + SourceExtent extent) { + MOZ_ASSERT(immutableScriptData, + "Need generated bytecode to use ScriptStencil::intoScript"); + + RootedObject functionOrGlobal(cx, cx->global()); + if (functionIndex) { + functionOrGlobal = + compilationInfo.funcData[*functionIndex].as(); + } + + RootedScript script( + cx, JSScript::Create(cx, functionOrGlobal, compilationInfo.sourceObject, + extent, immutableFlags)); + if (!script) { + return nullptr; + } + + if (!JSScript::fullyInitFromStencil(cx, compilationInfo, script, *this)) { + return nullptr; + } + + return script; +} diff --git a/js/src/frontend/Stencil.h b/js/src/frontend/Stencil.h index f27e869fbe40..3e8388c404a9 100644 --- a/js/src/frontend/Stencil.h +++ b/js/src/frontend/Stencil.h @@ -376,6 +376,11 @@ class ScriptStencil : public ScriptStencilBase { return immutableFlags.hasFlag(ImmutableFlags::IsFunction); } + // Allocate a JSScript and initialize it with bytecode. This consumes + // allocations within this stencil. + JSScript* intoScript(JSContext* cx, CompilationInfo& compilationInfo, + SourceExtent extent); + // Store all atoms into `atoms` // `atoms` is the pointer to `this.natoms`-length array of `GCPtrAtom`. virtual void initAtomMap(GCPtrAtom* atoms) const = 0;