mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 14:25:49 +00:00
Bug 1773319 - Use wrapper around CompilationInput instead of UniquePtr r=arai
Embedders would not be able to use UniquePtr<CompilationInput> since CompilationInput is opaque to them. This also resolves a rooting hazard with the UniquePtr because the JS script might have a 'uses asm' directive, which the hazard analysis reports could be a problem if CompilationInput has GC pointers. We know the CompilationInput has no GC pointers, however because we are only compiling to Stencil. Differential Revision: https://phabricator.services.mozilla.com/D172336
This commit is contained in:
parent
1ed143bc2a
commit
454b80333b
@ -12,6 +12,7 @@
|
||||
|
||||
#include "jspubtd.h"
|
||||
#include "js/experimental/JSStencil.h"
|
||||
#include "js/GCAnnotations.h"
|
||||
#include "js/Modules.h"
|
||||
#include "js/Stack.h"
|
||||
#include "js/UniquePtr.h"
|
||||
@ -19,8 +20,6 @@
|
||||
namespace js {
|
||||
class FrontendContext;
|
||||
namespace frontend {
|
||||
// TODO Create wrapper type around CompilationInput because it is opaque, which
|
||||
// means UniquePtr can't perform deletion on it
|
||||
struct CompilationInput;
|
||||
} // namespace frontend
|
||||
} // namespace js
|
||||
@ -43,28 +42,96 @@ JS_PUBLIC_API bool SetSupportedImportAssertions(
|
||||
JS::FrontendContext* fc,
|
||||
const JS::ImportAssertionVector& supportedImportAssertions);
|
||||
|
||||
// Temporary storage used during compiling and preparing to instantiate a
|
||||
// Stencil.
|
||||
//
|
||||
// Off-thread consumers can allocate this instance off main thread, and pass it
|
||||
// back to the main thread, in order to reduce the main thread allocation.
|
||||
struct CompilationStorage {
|
||||
private:
|
||||
// Owned CompilationInput.
|
||||
//
|
||||
// This uses raw pointer instead of UniquePtr because CompilationInput
|
||||
// is opaque.
|
||||
JS_HAZ_NON_GC_POINTER js::frontend::CompilationInput* input_ = nullptr;
|
||||
|
||||
friend JS_PUBLIC_API already_AddRefed<JS::Stencil>
|
||||
CompileGlobalScriptToStencil(JS::FrontendContext* fc,
|
||||
const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit,
|
||||
JS::SourceText<mozilla::Utf8Unit>& srcBuf,
|
||||
JS::CompilationStorage& compileStorage);
|
||||
|
||||
friend JS_PUBLIC_API already_AddRefed<JS::Stencil>
|
||||
CompileGlobalScriptToStencil(JS::FrontendContext* fc,
|
||||
const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit,
|
||||
JS::SourceText<char16_t>& srcBuf,
|
||||
JS::CompilationStorage& compileStorage);
|
||||
|
||||
friend JS_PUBLIC_API already_AddRefed<JS::Stencil>
|
||||
CompileModuleScriptToStencil(JS::FrontendContext* fc,
|
||||
const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit,
|
||||
JS::SourceText<mozilla::Utf8Unit>& srcBuf,
|
||||
JS::CompilationStorage& compileStorage);
|
||||
|
||||
friend JS_PUBLIC_API already_AddRefed<JS::Stencil>
|
||||
CompileModuleScriptToStencil(JS::FrontendContext* fc,
|
||||
const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit,
|
||||
JS::SourceText<char16_t>& srcBuf,
|
||||
JS::CompilationStorage& compileStorage);
|
||||
|
||||
friend JS_PUBLIC_API bool PrepareForInstantiate(
|
||||
JS::FrontendContext* fc, JS::CompilationStorage& compileStorage,
|
||||
JS::Stencil& stencil, JS::InstantiationStorage& storage);
|
||||
|
||||
public:
|
||||
CompilationStorage() = default;
|
||||
CompilationStorage(CompilationStorage&& other) : input_(other.input_) {
|
||||
other.input_ = nullptr;
|
||||
}
|
||||
|
||||
~CompilationStorage();
|
||||
|
||||
private:
|
||||
CompilationStorage(const CompilationStorage& other) = delete;
|
||||
void operator=(const CompilationStorage& aOther) = delete;
|
||||
|
||||
public:
|
||||
bool hasInput() { return !!input_; }
|
||||
|
||||
js::frontend::CompilationInput& getInput() {
|
||||
MOZ_ASSERT(hasInput());
|
||||
return *input_;
|
||||
}
|
||||
|
||||
void trace(JSTracer* trc);
|
||||
};
|
||||
|
||||
extern JS_PUBLIC_API already_AddRefed<JS::Stencil> CompileGlobalScriptToStencil(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit, JS::SourceText<mozilla::Utf8Unit>& srcBuf,
|
||||
js::UniquePtr<js::frontend::CompilationInput>& stencilInput);
|
||||
JS::CompilationStorage& compileStorage);
|
||||
|
||||
extern JS_PUBLIC_API already_AddRefed<JS::Stencil> CompileGlobalScriptToStencil(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit, JS::SourceText<char16_t>& srcBuf,
|
||||
js::UniquePtr<js::frontend::CompilationInput>& stencilInput);
|
||||
JS::CompilationStorage& compileStorage);
|
||||
|
||||
extern JS_PUBLIC_API already_AddRefed<JS::Stencil> CompileModuleScriptToStencil(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit, JS::SourceText<mozilla::Utf8Unit>& srcBuf,
|
||||
js::UniquePtr<js::frontend::CompilationInput>& stencilInput);
|
||||
JS::CompilationStorage& compileStorage);
|
||||
|
||||
extern JS_PUBLIC_API already_AddRefed<JS::Stencil> CompileModuleScriptToStencil(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit, JS::SourceText<char16_t>& srcBuf,
|
||||
js::UniquePtr<js::frontend::CompilationInput>& stencilInput);
|
||||
JS::CompilationStorage& compileStorage);
|
||||
|
||||
extern JS_PUBLIC_API bool PrepareForInstantiate(
|
||||
JS::FrontendContext* fc, js::frontend::CompilationInput& input,
|
||||
JS::FrontendContext* fc, JS::CompilationStorage& compileStorage,
|
||||
JS::Stencil& stencil, JS::InstantiationStorage& storage);
|
||||
|
||||
} // namespace JS
|
||||
|
@ -48,6 +48,8 @@ struct CompilationInput;
|
||||
|
||||
namespace JS {
|
||||
|
||||
struct CompilationStorage;
|
||||
|
||||
using Stencil = js::frontend::CompilationStencil;
|
||||
using FrontendContext = js::FrontendContext;
|
||||
|
||||
@ -71,8 +73,8 @@ struct InstantiationStorage {
|
||||
JSContext* cx, const InstantiateOptions& options, Stencil* stencil,
|
||||
InstantiationStorage* storage);
|
||||
|
||||
friend JS_PUBLIC_API JS_PUBLIC_API bool PrepareForInstantiate(
|
||||
JS::FrontendContext* fc, js::frontend::CompilationInput& input,
|
||||
friend JS_PUBLIC_API bool PrepareForInstantiate(
|
||||
JS::FrontendContext* fc, JS::CompilationStorage& compileStorage,
|
||||
JS::Stencil& stencil, JS::InstantiationStorage& storage);
|
||||
|
||||
friend struct js::ParseTask;
|
||||
|
@ -6502,15 +6502,15 @@ static bool CompileToStencil(JSContext* cx, uint32_t argc, Value* vp) {
|
||||
|
||||
AutoReportFrontendContext fc(cx);
|
||||
RefPtr<JS::Stencil> stencil;
|
||||
JS::Rooted<UniquePtr<js::frontend::CompilationInput>> stencilInput(cx);
|
||||
JS::CompilationStorage compileStorage;
|
||||
if (isModule) {
|
||||
stencil = JS::CompileModuleScriptToStencil(
|
||||
&fc, options, cx->stackLimitForCurrentPrincipal(), srcBuf,
|
||||
stencilInput.get());
|
||||
compileStorage);
|
||||
} else {
|
||||
stencil = JS::CompileGlobalScriptToStencil(
|
||||
&fc, options, cx->stackLimitForCurrentPrincipal(), srcBuf,
|
||||
stencilInput.get());
|
||||
compileStorage);
|
||||
}
|
||||
if (!stencil) {
|
||||
return false;
|
||||
@ -6522,8 +6522,7 @@ static bool CompileToStencil(JSContext* cx, uint32_t argc, Value* vp) {
|
||||
|
||||
JS::InstantiationStorage storage;
|
||||
if (prepareForInstantiate) {
|
||||
if (!JS::PrepareForInstantiate(&fc, *stencilInput.get(), *stencil,
|
||||
storage)) {
|
||||
if (!JS::PrepareForInstantiate(&fc, compileStorage, *stencil, storage)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -35,18 +35,31 @@ JS_PUBLIC_API bool JS::SetSupportedImportAssertions(
|
||||
return fc->setSupportedImportAssertions(supportedImportAssertions);
|
||||
}
|
||||
|
||||
JS::CompilationStorage::~CompilationStorage() {
|
||||
if (input_) {
|
||||
js_delete(input_);
|
||||
input_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void JS::CompilationStorage::trace(JSTracer* trc) {
|
||||
if (input_) {
|
||||
input_->trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
static already_AddRefed<JS::Stencil> CompileGlobalScriptToStencilImpl(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit, JS::SourceText<CharT>& srcBuf,
|
||||
js::UniquePtr<js::frontend::CompilationInput>& stencilInput) {
|
||||
js::frontend::CompilationInput*& stencilInput) {
|
||||
ScopeKind scopeKind =
|
||||
options.nonSyntacticScope ? ScopeKind::NonSyntactic : ScopeKind::Global;
|
||||
|
||||
JS::SourceText<CharT> data(std::move(srcBuf));
|
||||
|
||||
stencilInput =
|
||||
fc->getAllocator()->make_unique<frontend::CompilationInput>(options);
|
||||
MOZ_ASSERT(!stencilInput);
|
||||
stencilInput = fc->getAllocator()->new_<frontend::CompilationInput>(options);
|
||||
if (!stencilInput) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -64,12 +77,12 @@ template <typename CharT>
|
||||
static already_AddRefed<JS::Stencil> CompileModuleScriptToStencilImpl(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& optionsInput,
|
||||
JS::NativeStackLimit stackLimit, JS::SourceText<CharT>& srcBuf,
|
||||
js::UniquePtr<js::frontend::CompilationInput>& stencilInput) {
|
||||
js::frontend::CompilationInput*& stencilInput) {
|
||||
JS::CompileOptions options(nullptr, optionsInput);
|
||||
options.setModule();
|
||||
|
||||
stencilInput =
|
||||
fc->getAllocator()->make_unique<frontend::CompilationInput>(options);
|
||||
MOZ_ASSERT(!stencilInput);
|
||||
stencilInput = fc->getAllocator()->new_<frontend::CompilationInput>(options);
|
||||
if (!stencilInput) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -90,38 +103,58 @@ static already_AddRefed<JS::Stencil> CompileModuleScriptToStencilImpl(
|
||||
already_AddRefed<JS::Stencil> JS::CompileGlobalScriptToStencil(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit, JS::SourceText<mozilla::Utf8Unit>& srcBuf,
|
||||
js::UniquePtr<js::frontend::CompilationInput>& stencilInput) {
|
||||
JS::CompilationStorage& compileStorage) {
|
||||
return CompileGlobalScriptToStencilImpl(fc, options, stackLimit, srcBuf,
|
||||
stencilInput);
|
||||
compileStorage.input_);
|
||||
}
|
||||
|
||||
already_AddRefed<JS::Stencil> JS::CompileGlobalScriptToStencil(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& options,
|
||||
JS::NativeStackLimit stackLimit, JS::SourceText<char16_t>& srcBuf,
|
||||
js::UniquePtr<js::frontend::CompilationInput>& stencilInput) {
|
||||
JS::CompilationStorage& compileStorage) {
|
||||
return CompileGlobalScriptToStencilImpl(fc, options, stackLimit, srcBuf,
|
||||
stencilInput);
|
||||
compileStorage.input_);
|
||||
}
|
||||
|
||||
already_AddRefed<JS::Stencil> JS::CompileModuleScriptToStencil(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& optionsInput,
|
||||
JS::NativeStackLimit stackLimit, JS::SourceText<mozilla::Utf8Unit>& srcBuf,
|
||||
js::UniquePtr<js::frontend::CompilationInput>& stencilInput) {
|
||||
JS::CompilationStorage& compileStorage) {
|
||||
return CompileModuleScriptToStencilImpl(fc, optionsInput, stackLimit, srcBuf,
|
||||
stencilInput);
|
||||
compileStorage.input_);
|
||||
}
|
||||
|
||||
already_AddRefed<JS::Stencil> JS::CompileModuleScriptToStencil(
|
||||
JS::FrontendContext* fc, const JS::ReadOnlyCompileOptions& optionsInput,
|
||||
JS::NativeStackLimit stackLimit, JS::SourceText<char16_t>& srcBuf,
|
||||
js::UniquePtr<js::frontend::CompilationInput>& stencilInput) {
|
||||
JS::CompilationStorage& compileStorage) {
|
||||
return CompileModuleScriptToStencilImpl(fc, optionsInput, stackLimit, srcBuf,
|
||||
stencilInput);
|
||||
compileStorage.input_);
|
||||
}
|
||||
|
||||
bool JS::PrepareForInstantiate(JS::FrontendContext* fc, CompilationInput& input,
|
||||
// We don't need to worry about GC if the CompilationInput has no GC pointers
|
||||
static bool isGCSafe(js::frontend::CompilationInput* input_) {
|
||||
if (!input_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isGlobalOrModule =
|
||||
input_->target == CompilationInput::CompilationTarget::Global ||
|
||||
input_->target == CompilationInput::CompilationTarget::Module;
|
||||
bool scopeHasNoGC =
|
||||
input_->enclosingScope.isStencil() || input_->enclosingScope.isNull();
|
||||
bool scriptHasNoGC = input_->lazyOuterScript().isStencil() ||
|
||||
input_->lazyOuterScript().isNull();
|
||||
bool cacheHasNoGC = input_->atomCache.empty();
|
||||
|
||||
return isGlobalOrModule && scopeHasNoGC && scriptHasNoGC && cacheHasNoGC;
|
||||
}
|
||||
|
||||
bool JS::PrepareForInstantiate(JS::FrontendContext* fc,
|
||||
JS::CompilationStorage& compileStorage,
|
||||
JS::Stencil& stencil,
|
||||
JS::InstantiationStorage& storage) {
|
||||
MOZ_ASSERT(isGCSafe(compileStorage.input_));
|
||||
if (!storage.gcOutput_) {
|
||||
storage.gcOutput_ =
|
||||
fc->getAllocator()->new_<js::frontend::CompilationGCOutput>();
|
||||
@ -129,6 +162,6 @@ bool JS::PrepareForInstantiate(JS::FrontendContext* fc, CompilationInput& input,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return CompilationStencil::prepareForInstantiate(fc, input.atomCache, stencil,
|
||||
*storage.gcOutput_);
|
||||
return CompilationStencil::prepareForInstantiate(
|
||||
fc, compileStorage.input_->atomCache, stencil, *storage.gcOutput_);
|
||||
}
|
||||
|
@ -52,9 +52,10 @@ bool testCompile() {
|
||||
CHECK(buf16.init(cx, src_16.data(), src_16.length(),
|
||||
JS::SourceOwnership::Borrowed));
|
||||
|
||||
js::UniquePtr<js::frontend::CompilationInput> stencilInput;
|
||||
JS::CompilationStorage compileStorage;
|
||||
RefPtr<JS::Stencil> stencil = CompileGlobalScriptToStencil(
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), buf16, stencilInput);
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), buf16,
|
||||
compileStorage);
|
||||
CHECK(stencil);
|
||||
CHECK(stencil->scriptExtra.size() == 1);
|
||||
CHECK(stencil->scriptExtra[0].extent.sourceStart == 0);
|
||||
@ -62,7 +63,7 @@ bool testCompile() {
|
||||
CHECK(stencil->scriptData.size() == 1);
|
||||
CHECK(stencil->scriptData[0].hasSharedData()); // has generated bytecode
|
||||
CHECK(stencil->scriptData[0].gcThingsLength == 1);
|
||||
CHECK(stencilInput);
|
||||
CHECK(compileStorage.hasInput());
|
||||
}
|
||||
|
||||
{ // 8-bit characters
|
||||
@ -70,9 +71,9 @@ bool testCompile() {
|
||||
CHECK(
|
||||
buf8.init(cx, src.data(), src.length(), JS::SourceOwnership::Borrowed));
|
||||
|
||||
js::UniquePtr<js::frontend::CompilationInput> stencilInput;
|
||||
JS::CompilationStorage compileStorage;
|
||||
RefPtr<JS::Stencil> stencil = CompileGlobalScriptToStencil(
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), buf8, stencilInput);
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), buf8, compileStorage);
|
||||
CHECK(stencil);
|
||||
CHECK(stencil->scriptExtra.size() == 1);
|
||||
CHECK(stencil->scriptExtra[0].extent.sourceStart == 0);
|
||||
@ -80,7 +81,7 @@ bool testCompile() {
|
||||
CHECK(stencil->scriptData.size() == 1);
|
||||
CHECK(stencil->scriptData[0].hasSharedData()); // has generated bytecode
|
||||
CHECK(stencil->scriptData[0].gcThingsLength == 1);
|
||||
CHECK(stencilInput);
|
||||
CHECK(compileStorage.hasInput());
|
||||
}
|
||||
|
||||
{ // propagates failures
|
||||
@ -89,9 +90,10 @@ bool testCompile() {
|
||||
CHECK(srcBuf.init(cx, badSrc.data(), badSrc.length(),
|
||||
JS::SourceOwnership::Borrowed));
|
||||
|
||||
js::UniquePtr<js::frontend::CompilationInput> stencilInput;
|
||||
JS::CompilationStorage compileStorage;
|
||||
RefPtr<JS::Stencil> stencil = CompileGlobalScriptToStencil(
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), srcBuf, stencilInput);
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), srcBuf,
|
||||
compileStorage);
|
||||
CHECK(!stencil);
|
||||
CHECK(fc->maybeError().isSome());
|
||||
const js::CompileError& error = fc->maybeError().ref();
|
||||
@ -119,10 +121,9 @@ bool testNonsyntacticCompile() {
|
||||
auto destroyFc =
|
||||
mozilla::MakeScopeExit([fc] { JS::DestroyFrontendContext(fc); });
|
||||
|
||||
JS::Rooted<js::UniquePtr<js::frontend::CompilationInput>> stencilInput(cx);
|
||||
JS::CompilationStorage compileStorage;
|
||||
RefPtr<JS::Stencil> stencil = CompileGlobalScriptToStencil(
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), srcBuf,
|
||||
stencilInput.get());
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), srcBuf, compileStorage);
|
||||
CHECK(stencil);
|
||||
|
||||
JS::InstantiateOptions instantiateOptions(options);
|
||||
@ -153,9 +154,10 @@ bool testCompileModule() {
|
||||
CHECK(buf16.init(cx, src_16.data(), src_16.length(),
|
||||
JS::SourceOwnership::Borrowed));
|
||||
|
||||
js::UniquePtr<js::frontend::CompilationInput> stencilInput;
|
||||
JS::CompilationStorage compileStorage;
|
||||
RefPtr<JS::Stencil> stencil = CompileModuleScriptToStencil(
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), buf16, stencilInput);
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), buf16,
|
||||
compileStorage);
|
||||
CHECK(stencil);
|
||||
CHECK(stencil->isModule());
|
||||
CHECK(stencil->scriptExtra.size() == 1);
|
||||
@ -164,7 +166,7 @@ bool testCompileModule() {
|
||||
CHECK(stencil->scriptData.size() == 1);
|
||||
CHECK(stencil->scriptData[0].hasSharedData()); // has generated bytecode
|
||||
CHECK(stencil->scriptData[0].gcThingsLength == 1);
|
||||
CHECK(stencilInput);
|
||||
CHECK(compileStorage.hasInput());
|
||||
}
|
||||
|
||||
{ // 8-bit characters
|
||||
@ -172,9 +174,9 @@ bool testCompileModule() {
|
||||
CHECK(
|
||||
buf8.init(cx, src.data(), src.length(), JS::SourceOwnership::Borrowed));
|
||||
|
||||
js::UniquePtr<js::frontend::CompilationInput> stencilInput;
|
||||
JS::CompilationStorage compileStorage;
|
||||
RefPtr<JS::Stencil> stencil = CompileModuleScriptToStencil(
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), buf8, stencilInput);
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), buf8, compileStorage);
|
||||
CHECK(stencil);
|
||||
CHECK(stencil->scriptExtra.size() == 1);
|
||||
CHECK(stencil->scriptExtra[0].extent.sourceStart == 0);
|
||||
@ -182,7 +184,7 @@ bool testCompileModule() {
|
||||
CHECK(stencil->scriptData.size() == 1);
|
||||
CHECK(stencil->scriptData[0].hasSharedData()); // has generated bytecode
|
||||
CHECK(stencil->scriptData[0].gcThingsLength == 1);
|
||||
CHECK(stencilInput);
|
||||
CHECK(compileStorage.hasInput());
|
||||
}
|
||||
|
||||
{ // propagates failures
|
||||
@ -191,9 +193,10 @@ bool testCompileModule() {
|
||||
CHECK(srcBuf.init(cx, badSrc.data(), badSrc.length(),
|
||||
JS::SourceOwnership::Borrowed));
|
||||
|
||||
js::UniquePtr<js::frontend::CompilationInput> stencilInput;
|
||||
JS::CompilationStorage compileStorage;
|
||||
RefPtr<JS::Stencil> stencil = CompileModuleScriptToStencil(
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), srcBuf, stencilInput);
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), srcBuf,
|
||||
compileStorage);
|
||||
CHECK(!stencil);
|
||||
CHECK(fc->maybeError().isSome());
|
||||
const js::CompileError& error = fc->maybeError().ref();
|
||||
@ -220,22 +223,22 @@ bool testPrepareForInstantiate() {
|
||||
auto destroyFc =
|
||||
mozilla::MakeScopeExit([fc] { JS::DestroyFrontendContext(fc); });
|
||||
|
||||
js::UniquePtr<js::frontend::CompilationInput> stencilInput;
|
||||
JS::CompilationStorage compileStorage;
|
||||
RefPtr<JS::Stencil> stencil = CompileGlobalScriptToStencil(
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), buf16, stencilInput);
|
||||
fc, options, cx->stackLimitForCurrentPrincipal(), buf16, compileStorage);
|
||||
CHECK(stencil);
|
||||
CHECK(stencil->scriptData.size() == 2);
|
||||
CHECK(stencil->scopeData.size() == 1); // function f
|
||||
CHECK(stencil->parserAtomData.size() == 1); // 'field'
|
||||
CHECK(stencilInput);
|
||||
CHECK(stencilInput->atomCache.empty());
|
||||
CHECK(compileStorage.hasInput());
|
||||
CHECK(compileStorage.getInput().atomCache.empty());
|
||||
|
||||
JS::InstantiationStorage storage;
|
||||
CHECK(JS::PrepareForInstantiate(fc, *stencilInput, *stencil, storage));
|
||||
CHECK(stencilInput->atomCache.size() == 1); // 'field'
|
||||
CHECK(JS::PrepareForInstantiate(fc, compileStorage, *stencil, storage));
|
||||
CHECK(compileStorage.getInput().atomCache.size() == 1); // 'field'
|
||||
CHECK(storage.isValid());
|
||||
// TODO storage.gcOutput_ is private, so there isn't a good way to check the
|
||||
// scripData and scopeData capacities
|
||||
// scriptData and scopeData capacities
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user