зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1688794 - Remove code for the (now unused) self-hosting zone. r=jandem,jonco
The dedicated zone for self-hosting can now be removed entirely. Also remove the object cloning code that was only used for the old self-hosting mechanism. Differential Revision: https://phabricator.services.mozilla.com/D120547
This commit is contained in:
Родитель
1f57d353aa
Коммит
f3326c91ec
|
@ -548,7 +548,7 @@ namespace JS {
|
|||
D(FULL_CELL_PTR_STR_BUFFER, 28) \
|
||||
D(TOO_MUCH_JIT_CODE, 29) \
|
||||
D(FULL_CELL_PTR_BIGINT_BUFFER, 30) \
|
||||
D(INIT_SELF_HOSTING, 31) \
|
||||
D(UNUSED5, 31) \
|
||||
D(NURSERY_MALLOC_BUFFERS, 32) \
|
||||
\
|
||||
/* \
|
||||
|
|
|
@ -48,9 +48,6 @@ enum class CompartmentSpecifier {
|
|||
|
||||
// Create a new realm in an existing compartment.
|
||||
ExistingCompartment,
|
||||
|
||||
// Internal use only. Create the self-hosting compartment.
|
||||
NewCompartmentInSelfHostingZone,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -98,7 +95,6 @@ class JS_PUBLIC_API RealmCreationOptions {
|
|||
RealmCreationOptions& setNewCompartmentAndZone();
|
||||
RealmCreationOptions& setExistingCompartment(JSObject* obj);
|
||||
RealmCreationOptions& setExistingCompartment(Compartment* compartment);
|
||||
RealmCreationOptions& setNewCompartmentInSelfHostingZone();
|
||||
|
||||
// Certain compartments are implementation details of the embedding, and
|
||||
// references to them should never leak out to script. This flag causes this
|
||||
|
|
|
@ -33,7 +33,7 @@ struct Zone {
|
|||
Compact
|
||||
};
|
||||
|
||||
enum Kind : uint8_t { NormalZone, AtomsZone, SelfHostingZone, SystemZone };
|
||||
enum Kind : uint8_t { NormalZone, AtomsZone, SystemZone };
|
||||
|
||||
protected:
|
||||
JSRuntime* const runtime_;
|
||||
|
@ -82,7 +82,6 @@ struct Zone {
|
|||
}
|
||||
|
||||
bool isAtomsZone() const { return kind_ == AtomsZone; }
|
||||
bool isSelfHostingZone() const { return kind_ == SelfHostingZone; }
|
||||
bool isSystemZone() const { return kind_ == SystemZone; }
|
||||
|
||||
static shadow::Zone* from(JS::Zone* zone) {
|
||||
|
|
|
@ -63,10 +63,6 @@
|
|||
#define PROP_DESC_GETTER_INDEX 1
|
||||
#define PROP_DESC_SETTER_INDEX 2
|
||||
|
||||
// The extended slot of uncloned self-hosted function, in which the canonical
|
||||
// name for self-hosted builtins is stored by `_SetCanonicalName`.
|
||||
#define CANONICAL_FUNCTION_NAME_SLOT 0
|
||||
|
||||
// The extended slot of cloned self-hosted function, in which the self-hosted
|
||||
// name for self-hosted builtins is stored.
|
||||
#define LAZY_FUNCTION_NAME_SLOT 0
|
||||
|
|
|
@ -5938,10 +5938,6 @@ bool Debugger::CallData::findAllGlobals() {
|
|||
|
||||
GlobalObject* global = r->maybeGlobal();
|
||||
|
||||
if (cx->runtime()->isSelfHostingGlobal(global)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We pulled |global| out of nowhere, so it's possible that it was
|
||||
// marked gray by XPConnect. Since we're now exposing it to JS code,
|
||||
// we need to mark it black.
|
||||
|
|
|
@ -432,8 +432,6 @@ bool GCRuntime::checkAllocatorState(JSContext* cx, AllocKind kind) {
|
|||
kind == AllocKind::SCOPE);
|
||||
MOZ_ASSERT_IF(!cx->zone()->isAtomsZone(),
|
||||
kind != AllocKind::ATOM && kind != AllocKind::FAT_INLINE_ATOM);
|
||||
MOZ_ASSERT_IF(cx->zone()->isSelfHostingZone(),
|
||||
!rt->parentRuntime && !selfHostingZoneFrozen);
|
||||
MOZ_ASSERT(!JS::RuntimeHeapIsBusy());
|
||||
#endif
|
||||
|
||||
|
|
|
@ -227,7 +227,6 @@ template <typename T>
|
|||
// into another runtime. The zone's uid lock will protect against multiple
|
||||
// workers doing this simultaneously.
|
||||
MOZ_ASSERT(CurrentThreadCanAccessZone(l->zoneFromAnyThread()) ||
|
||||
l->zoneFromAnyThread()->isSelfHostingZone() ||
|
||||
CurrentThreadIsPerformingGC());
|
||||
|
||||
return l->zoneFromAnyThread()->getHashCodeInfallible(l);
|
||||
|
@ -245,8 +244,7 @@ template <typename T>
|
|||
|
||||
MOZ_ASSERT(k);
|
||||
MOZ_ASSERT(l);
|
||||
MOZ_ASSERT(CurrentThreadCanAccessZone(l->zoneFromAnyThread()) ||
|
||||
l->zoneFromAnyThread()->isSelfHostingZone());
|
||||
MOZ_ASSERT(CurrentThreadCanAccessZone(l->zoneFromAnyThread()));
|
||||
|
||||
Zone* zone = k->zoneFromAnyThread();
|
||||
if (zone != l->zoneFromAnyThread()) {
|
||||
|
|
|
@ -520,9 +520,6 @@ MOZ_ALWAYS_INLINE void PreWriteBarrierImpl(TenuredCell* thing) {
|
|||
// - while we are verifying pre-barriers for a worker runtime
|
||||
// The barrier is not required in either case.
|
||||
bool checkThread = zone->isAtomsZone();
|
||||
#ifdef JS_GC_ZEAL
|
||||
checkThread = checkThread || zone->isSelfHostingZone();
|
||||
#endif
|
||||
JSRuntime* runtime = thing->runtimeFromAnyThread();
|
||||
if (checkThread && !CurrentThreadCanAccessRuntime(runtime)) {
|
||||
MOZ_ASSERT(CurrentThreadIsGCFinalizing() ||
|
||||
|
|
|
@ -1597,21 +1597,6 @@ bool GCRuntime::init(uint32_t maxbytes) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void GCRuntime::freezeSelfHostingZone() {
|
||||
MOZ_ASSERT(!selfHostingZoneFrozen);
|
||||
MOZ_ASSERT(!isIncrementalGCInProgress());
|
||||
|
||||
for (ZonesIter zone(this, WithAtoms); !zone.done(); zone.next()) {
|
||||
MOZ_ASSERT(!zone->isGCScheduled());
|
||||
if (zone->isSelfHostingZone()) {
|
||||
zone->scheduleGC();
|
||||
}
|
||||
}
|
||||
|
||||
gc(JS::GCOptions::Shrink, JS::GCReason::INIT_SELF_HOSTING);
|
||||
selfHostingZoneFrozen = true;
|
||||
}
|
||||
|
||||
void GCRuntime::finish() {
|
||||
MOZ_ASSERT(inPageLoadCount == 0);
|
||||
|
||||
|
@ -2154,15 +2139,7 @@ AutoDisableCompactingGC::~AutoDisableCompactingGC() {
|
|||
}
|
||||
|
||||
bool GCRuntime::canRelocateZone(Zone* zone) const {
|
||||
if (zone->isAtomsZone()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (zone->isSelfHostingZone() && selfHostingZoneFrozen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !zone->isAtomsZone();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -4370,9 +4347,6 @@ void GCRuntime::discardJITCodeForGC() {
|
|||
void GCRuntime::relazifyFunctionsForShrinkingGC() {
|
||||
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::RELAZIFY_FUNCTIONS);
|
||||
for (GCZonesIter zone(this); !zone.done(); zone.next()) {
|
||||
if (zone->isSelfHostingZone()) {
|
||||
continue;
|
||||
}
|
||||
RelazifyFunctions(zone, AllocKind::FUNCTION);
|
||||
RelazifyFunctions(zone, AllocKind::FUNCTION_EXTENDED);
|
||||
}
|
||||
|
@ -8298,19 +8272,14 @@ Realm* js::NewRealm(JSContext* cx, JSPrincipals* principals,
|
|||
zone = comp->zone();
|
||||
break;
|
||||
case JS::CompartmentSpecifier::NewCompartmentAndZone:
|
||||
case JS::CompartmentSpecifier::NewCompartmentInSelfHostingZone:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!zone) {
|
||||
Zone::Kind kind = Zone::NormalZone;
|
||||
const JSPrincipals* trusted = rt->trustedPrincipals();
|
||||
if (compSpec == JS::CompartmentSpecifier::NewCompartmentInSelfHostingZone) {
|
||||
MOZ_ASSERT(!rt->hasInitializedSelfHosting());
|
||||
kind = Zone::SelfHostingZone;
|
||||
} else if (compSpec ==
|
||||
JS::CompartmentSpecifier::NewCompartmentInSystemZone ||
|
||||
(principals && principals == trusted)) {
|
||||
if (compSpec == JS::CompartmentSpecifier::NewCompartmentInSystemZone ||
|
||||
(principals && principals == trusted)) {
|
||||
kind = Zone::SystemZone;
|
||||
}
|
||||
|
||||
|
|
|
@ -135,8 +135,6 @@ void WaitForBackgroundTasks(JSContext* cx);
|
|||
*/
|
||||
void MergeRealms(JS::Realm* source, JS::Realm* target);
|
||||
|
||||
void CollectSelfHostingZone(JSContext* cx);
|
||||
|
||||
enum VerifierType { PreBarrierVerifier };
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
|
|
|
@ -290,9 +290,6 @@ class GCRuntime {
|
|||
|
||||
JS::HeapState heapState() const { return heapState_; }
|
||||
|
||||
void freezeSelfHostingZone();
|
||||
bool isSelfHostingZoneFrozen() const { return selfHostingZoneFrozen; }
|
||||
|
||||
inline bool hasZealMode(ZealMode mode);
|
||||
inline void clearZealMode(ZealMode mode);
|
||||
inline bool upcomingZealousGC();
|
||||
|
@ -960,12 +957,6 @@ class GCRuntime {
|
|||
|
||||
mozilla::Atomic<size_t, mozilla::ReleaseAcquire> numActiveZoneIters;
|
||||
|
||||
/*
|
||||
* The self hosting zone is collected once after initialization. We don't
|
||||
* allow allocation after this point and we don't collect it again.
|
||||
*/
|
||||
WriteOnceData<bool> selfHostingZoneFrozen;
|
||||
|
||||
/* During shutdown, the GC needs to clean up every possible object. */
|
||||
MainThreadData<bool> cleanUpEverything;
|
||||
|
||||
|
|
|
@ -169,8 +169,7 @@ static inline bool IsThingPoisoned(T* thing) {
|
|||
template <typename T>
|
||||
static inline bool IsOwnedByOtherRuntime(JSRuntime* rt, T thing) {
|
||||
bool other = thing->runtimeFromAnyThread() != rt;
|
||||
MOZ_ASSERT_IF(other, thing->isPermanentAndMayBeShared() ||
|
||||
thing->zoneFromAnyThread()->isSelfHostingZone());
|
||||
MOZ_ASSERT_IF(other, thing->isPermanentAndMayBeShared());
|
||||
return other;
|
||||
}
|
||||
|
||||
|
|
|
@ -343,8 +343,7 @@ void js::gc::GCRuntime::traceRuntimeCommon(JSTracer* trc,
|
|||
// Trace runtime global roots.
|
||||
TracePersistentRooted(rt, trc);
|
||||
|
||||
// Trace the self-hosting global compartment.
|
||||
rt->traceSelfHostingGlobal(trc);
|
||||
// Trace the self-hosting stencil.
|
||||
rt->traceSelfHostingStencil(trc);
|
||||
|
||||
#ifdef JS_HAS_INTL_API
|
||||
|
@ -445,7 +444,6 @@ void js::gc::GCRuntime::finishRoots() {
|
|||
rt->finishPersistentRoots();
|
||||
|
||||
rt->finishSelfHosting();
|
||||
selfHostingZoneFrozen = false;
|
||||
|
||||
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
|
||||
zone->finishRoots();
|
||||
|
|
|
@ -50,8 +50,7 @@ void JS::TracingContext::getEdgeName(char* buffer, size_t bufferSize) {
|
|||
JS_PUBLIC_API void JS::TraceChildren(JSTracer* trc, GCCellPtr thing) {
|
||||
ApplyGCThingTyped(thing.asCell(), thing.kind(), [trc](auto t) {
|
||||
MOZ_ASSERT_IF(t->runtimeFromAnyThread() != trc->runtime(),
|
||||
t->isPermanentAndMayBeShared() ||
|
||||
t->zoneFromAnyThread()->isSelfHostingZone());
|
||||
t->isPermanentAndMayBeShared());
|
||||
t->traceChildren(trc);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -190,7 +190,6 @@ JS::Zone::Zone(JSRuntime* rt, Kind kind)
|
|||
MOZ_ASSERT(reinterpret_cast<JS::shadow::Zone*>(this) ==
|
||||
static_cast<JS::shadow::Zone*>(this));
|
||||
MOZ_ASSERT_IF(isAtomsZone(), !rt->unsafeAtomsZone());
|
||||
MOZ_ASSERT_IF(isSelfHostingZone(), !rt->hasInitializedSelfHosting());
|
||||
|
||||
// We can't call updateGCStartThresholds until the Zone has been constructed.
|
||||
AutoLockGC lock(rt);
|
||||
|
@ -585,11 +584,6 @@ bool Zone::canCollect() {
|
|||
return !runtimeFromAnyThread()->hasHelperThreadZones();
|
||||
}
|
||||
|
||||
// We don't collect the self hosting zone after it has been initialized.
|
||||
if (isSelfHostingZone()) {
|
||||
return !runtimeFromAnyThread()->gc.isSelfHostingZoneFrozen();
|
||||
}
|
||||
|
||||
// Zones that will be or are currently used by other threads cannot be
|
||||
// collected.
|
||||
return !createdForHelperThread();
|
||||
|
|
|
@ -1739,13 +1739,6 @@ JS::RealmCreationOptions& JS::RealmCreationOptions::setNewCompartmentAndZone() {
|
|||
return *this;
|
||||
}
|
||||
|
||||
JS::RealmCreationOptions&
|
||||
JS::RealmCreationOptions::setNewCompartmentInSelfHostingZone() {
|
||||
compSpec_ = CompartmentSpecifier::NewCompartmentInSelfHostingZone;
|
||||
comp_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const JS::RealmCreationOptions& JS::RealmCreationOptionsRef(Realm* realm) {
|
||||
return realm->creationOptions();
|
||||
}
|
||||
|
|
|
@ -291,14 +291,6 @@ void js::ErrorToException(JSContext* cx, JSErrorReport* reportp,
|
|||
JSErrorCallback callback, void* userRef) {
|
||||
MOZ_ASSERT(!reportp->isWarning());
|
||||
|
||||
// We cannot throw a proper object inside the self-hosting realm, as we
|
||||
// cannot construct the Error constructor without self-hosted code. Just
|
||||
// print the error to stderr to help debugging.
|
||||
if (cx->realm()->isSelfHostingRealm()) {
|
||||
JS::PrintError(stderr, reportp, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the exception index associated with this error.
|
||||
JSErrNum errorNumber = static_cast<JSErrNum>(reportp->errorNumber);
|
||||
if (!callback) {
|
||||
|
|
|
@ -209,13 +209,6 @@ bool Compartment::getNonWrapperObjectForCurrentCompartment(
|
|||
// Ensure that we have entered a realm.
|
||||
MOZ_ASSERT(cx->global());
|
||||
|
||||
// If we have a cross-compartment wrapper, make sure that the cx isn't
|
||||
// associated with the self-hosting zone. We don't want to create
|
||||
// wrappers for objects in other runtimes, which may be the case for the
|
||||
// self-hosting zone.
|
||||
MOZ_ASSERT(!cx->zone()->isSelfHostingZone());
|
||||
MOZ_ASSERT(!obj->zone()->isSelfHostingZone());
|
||||
|
||||
// The object is already in the right compartment. Normally same-
|
||||
// compartment returns the object itself, however, windows are always
|
||||
// wrapped by a proxy, so we have to check for that case here manually.
|
||||
|
|
|
@ -833,8 +833,7 @@ bool FrameIter::matchCallee(JSContext* cx, JS::Handle<JSFunction*> fun) const {
|
|||
// the script clones do not use the same script, they also have a different
|
||||
// group and Ion will not inline them interchangeably.
|
||||
//
|
||||
// See: js::jit::InlineFrameIterator::findNextFrame(),
|
||||
// js::CloneFunctionAndScript()
|
||||
// See: js::jit::InlineFrameIterator::findNextFrame()
|
||||
if (currentCallee->hasBaseScript()) {
|
||||
if (currentCallee->baseScript() != fun->baseScript()) {
|
||||
return false;
|
||||
|
|
|
@ -338,28 +338,24 @@ bool GlobalObject::resolveConstructor(JSContext* cx,
|
|||
global->setConstructor(key, ObjectValue(*ctor));
|
||||
}
|
||||
|
||||
// If we're operating on the self-hosting global, we don't want any
|
||||
// functions and properties on the builtins and their prototypes.
|
||||
if (!cx->runtime()->isSelfHostingGlobal(global)) {
|
||||
if (const JSFunctionSpec* funs = clasp->specPrototypeFunctions()) {
|
||||
if (!JS_DefineFunctions(cx, proto, funs)) {
|
||||
return false;
|
||||
}
|
||||
if (const JSFunctionSpec* funs = clasp->specPrototypeFunctions()) {
|
||||
if (!JS_DefineFunctions(cx, proto, funs)) {
|
||||
return false;
|
||||
}
|
||||
if (const JSPropertySpec* props = clasp->specPrototypeProperties()) {
|
||||
if (!JS_DefineProperties(cx, proto, props)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (const JSPropertySpec* props = clasp->specPrototypeProperties()) {
|
||||
if (!JS_DefineProperties(cx, proto, props)) {
|
||||
return false;
|
||||
}
|
||||
if (const JSFunctionSpec* funs = clasp->specConstructorFunctions()) {
|
||||
if (!JS_DefineFunctions(cx, ctor, funs)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (const JSFunctionSpec* funs = clasp->specConstructorFunctions()) {
|
||||
if (!JS_DefineFunctions(cx, ctor, funs)) {
|
||||
return false;
|
||||
}
|
||||
if (const JSPropertySpec* props = clasp->specConstructorProperties()) {
|
||||
if (!JS_DefineProperties(cx, ctor, props)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (const JSPropertySpec* props = clasp->specConstructorProperties()) {
|
||||
if (!JS_DefineProperties(cx, ctor, props)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -937,15 +933,10 @@ NativeObject* GlobalObject::getIntrinsicsHolder(JSContext* cx,
|
|||
return &slot.toObject().as<NativeObject>();
|
||||
}
|
||||
|
||||
Rooted<NativeObject*> intrinsicsHolder(cx);
|
||||
bool isSelfHostingGlobal = cx->runtime()->isSelfHostingGlobal(global);
|
||||
if (isSelfHostingGlobal) {
|
||||
intrinsicsHolder = global;
|
||||
} else {
|
||||
intrinsicsHolder = NewTenuredObjectWithGivenProto<PlainObject>(cx, nullptr);
|
||||
if (!intrinsicsHolder) {
|
||||
return nullptr;
|
||||
}
|
||||
Rooted<NativeObject*> intrinsicsHolder(
|
||||
cx, NewTenuredObjectWithGivenProto<PlainObject>(cx, nullptr));
|
||||
if (!intrinsicsHolder) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Define a top-level property 'undefined' with the undefined value.
|
||||
|
|
|
@ -1571,10 +1571,6 @@ void JSFunction::maybeRelazify(JSRuntime* rt) {
|
|||
MOZ_ASSERT(!realm->hasBeenEnteredIgnoringJit());
|
||||
}
|
||||
|
||||
// The caller should have checked we're not in the self-hosting zone (it's
|
||||
// shared with worker runtimes so relazifying functions in it will race).
|
||||
MOZ_ASSERT(!realm->isSelfHostingRealm());
|
||||
|
||||
// Don't relazify if the realm is being debugged. The debugger side-tables
|
||||
// such as the set of active breakpoints require bytecode to exist.
|
||||
if (realm->isDebuggee()) {
|
||||
|
@ -1963,15 +1959,6 @@ JSFunction* js::NewFunctionWithProto(
|
|||
bool js::GetFunctionPrototype(JSContext* cx, js::GeneratorKind generatorKind,
|
||||
js::FunctionAsyncKind asyncKind,
|
||||
js::MutableHandleObject proto) {
|
||||
// Self-hosted functions have null [[Prototype]]. This allows self-hosting to
|
||||
// support generators, despite this loop in the builtin object graph:
|
||||
// - %Generator%.prototype.[[Prototype]] is Iterator.prototype;
|
||||
// - Iterator.prototype has self-hosted methods (iterator helpers).
|
||||
if (cx->realm()->isSelfHostingRealm()) {
|
||||
proto.set(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (generatorKind == js::GeneratorKind::NotGenerator) {
|
||||
if (asyncKind == js::FunctionAsyncKind::SyncFunction) {
|
||||
proto.set(nullptr);
|
||||
|
@ -2103,45 +2090,6 @@ JSFunction* js::CloneFunctionReuseScript(JSContext* cx, HandleFunction fun,
|
|||
return clone;
|
||||
}
|
||||
|
||||
JSFunction* js::CloneFunctionAndScript(JSContext* cx, HandleFunction fun,
|
||||
HandleObject enclosingEnv,
|
||||
HandleScope newScope,
|
||||
Handle<ScriptSourceObject*> sourceObject,
|
||||
gc::AllocKind allocKind,
|
||||
HandleObject proto /* = nullptr */) {
|
||||
MOZ_ASSERT(NewFunctionEnvironmentIsWellFormed(cx, enclosingEnv));
|
||||
MOZ_ASSERT(fun->isInterpreted());
|
||||
MOZ_ASSERT(!fun->isBoundFunction());
|
||||
|
||||
JSScript::AutoDelazify funScript(cx, fun);
|
||||
if (!funScript) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RootedFunction clone(
|
||||
cx, NewFunctionClone(cx, fun, TenuredObject, allocKind, proto));
|
||||
if (!clone) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
clone->initScript(nullptr);
|
||||
clone->initEnvironment(enclosingEnv);
|
||||
|
||||
RootedScript script(cx, fun->nonLazyScript());
|
||||
MOZ_ASSERT(script->realm() == fun->realm());
|
||||
MOZ_ASSERT(cx->compartment() == clone->compartment(),
|
||||
"Otherwise we could relazify clone below!");
|
||||
|
||||
RootedScript clonedScript(
|
||||
cx, CloneScriptIntoFunction(cx, newScope, clone, script, sourceObject));
|
||||
if (!clonedScript) {
|
||||
return nullptr;
|
||||
}
|
||||
DebugAPI::onNewScript(cx, clonedScript);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
JSFunction* js::CloneAsmJSModuleFunction(JSContext* cx, HandleFunction fun) {
|
||||
MOZ_ASSERT(fun->isNativeFun());
|
||||
MOZ_ASSERT(IsAsmJSModule(fun));
|
||||
|
@ -2162,24 +2110,6 @@ JSFunction* js::CloneAsmJSModuleFunction(JSContext* cx, HandleFunction fun) {
|
|||
return clone;
|
||||
}
|
||||
|
||||
JSFunction* js::CloneSelfHostingIntrinsic(JSContext* cx, HandleFunction fun) {
|
||||
MOZ_ASSERT(fun->isNativeFun());
|
||||
MOZ_ASSERT(fun->realm()->isSelfHostingRealm());
|
||||
MOZ_ASSERT(!fun->isExtended());
|
||||
MOZ_ASSERT(cx->compartment() != fun->compartment());
|
||||
|
||||
JSFunction* clone =
|
||||
NewFunctionClone(cx, fun, TenuredObject, gc::AllocKind::FUNCTION,
|
||||
/* proto = */ nullptr);
|
||||
if (!clone) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
clone->initNative(fun->native(),
|
||||
fun->hasJitInfo() ? fun->jitInfo() : nullptr);
|
||||
return clone;
|
||||
}
|
||||
|
||||
static JSAtom* SymbolToFunctionName(JSContext* cx, JS::Symbol* symbol,
|
||||
FunctionPrefixKind prefixKind) {
|
||||
// Step 4.a.
|
||||
|
|
|
@ -817,15 +817,8 @@ extern JSFunction* CloneFunctionReuseScript(JSContext* cx, HandleFunction fun,
|
|||
gc::AllocKind kind,
|
||||
HandleObject proto);
|
||||
|
||||
extern JSFunction* CloneFunctionAndScript(
|
||||
JSContext* cx, HandleFunction fun, HandleObject enclosingEnv,
|
||||
HandleScope newScope, Handle<ScriptSourceObject*> sourceObject,
|
||||
gc::AllocKind kind, HandleObject proto = nullptr);
|
||||
|
||||
extern JSFunction* CloneAsmJSModuleFunction(JSContext* cx, HandleFunction fun);
|
||||
|
||||
extern JSFunction* CloneSelfHostingIntrinsic(JSContext* cx, HandleFunction fun);
|
||||
|
||||
} // namespace js
|
||||
|
||||
inline js::FunctionExtended* JSFunction::toExtended() {
|
||||
|
|
|
@ -4840,27 +4840,17 @@ gc::AllocSite* JSScript::createAllocSite() {
|
|||
|
||||
void JSScript::AutoDelazify::holdScript(JS::HandleFunction fun) {
|
||||
if (fun) {
|
||||
if (fun->realm()->isSelfHostingRealm()) {
|
||||
// The self-hosting realm is shared across runtimes, so we can't use
|
||||
// JSAutoRealm: it could cause races. Functions in the self-hosting
|
||||
// realm will never be lazy, so we can safely assume we don't have
|
||||
// to delazify.
|
||||
script_ = fun->nonLazyScript();
|
||||
} else {
|
||||
JSAutoRealm ar(cx_, fun);
|
||||
script_ = JSFunction::getOrCreateScript(cx_, fun);
|
||||
if (script_) {
|
||||
oldAllowRelazify_ = script_->allowRelazify();
|
||||
script_->clearAllowRelazify();
|
||||
}
|
||||
JSAutoRealm ar(cx_, fun);
|
||||
script_ = JSFunction::getOrCreateScript(cx_, fun);
|
||||
if (script_) {
|
||||
oldAllowRelazify_ = script_->allowRelazify();
|
||||
script_->clearAllowRelazify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JSScript::AutoDelazify::dropScript() {
|
||||
// Don't touch script_ if it's in the self-hosting realm, see the comment
|
||||
// in holdScript.
|
||||
if (script_ && !script_->realm()->isSelfHostingRealm()) {
|
||||
if (script_) {
|
||||
script_->setAllowRelazify(oldAllowRelazify_);
|
||||
}
|
||||
script_ = nullptr;
|
||||
|
|
|
@ -118,13 +118,6 @@ bool Realm::init(JSContext* cx, JSPrincipals* principals) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void Realm::setIsSelfHostingRealm() {
|
||||
MOZ_ASSERT(!isSelfHostingRealm_);
|
||||
MOZ_ASSERT(zone()->isSelfHostingZone());
|
||||
isSelfHostingRealm_ = true;
|
||||
isSystem_ = true;
|
||||
}
|
||||
|
||||
bool JSRuntime::createJitRuntime(JSContext* cx) {
|
||||
using namespace js::jit;
|
||||
|
||||
|
|
|
@ -409,7 +409,6 @@ class JS::Realm : public JS::shadow::Realm {
|
|||
unsigned debugModeBits_ = 0;
|
||||
friend class js::AutoRestoreRealmDebugMode;
|
||||
|
||||
bool isSelfHostingRealm_ = false;
|
||||
bool isSystem_ = false;
|
||||
|
||||
js::UniquePtr<js::coverage::LCovRealm> lcovRealm_ = nullptr;
|
||||
|
@ -500,9 +499,6 @@ class JS::Realm : public JS::shadow::Realm {
|
|||
/* Whether to preserve JIT code on non-shrinking GCs. */
|
||||
bool preserveJitCode() { return creationOptions_.preserveJitCode(); }
|
||||
|
||||
bool isSelfHostingRealm() const { return isSelfHostingRealm_; }
|
||||
void setIsSelfHostingRealm();
|
||||
|
||||
/* The global object for this realm.
|
||||
*
|
||||
* Note: the global_ field is null briefly during GC, after the global
|
||||
|
|
|
@ -131,7 +131,6 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
|
|||
scriptAndCountsVector(nullptr),
|
||||
lcovOutput_(),
|
||||
jitRuntime_(nullptr),
|
||||
selfHostingGlobal_(nullptr),
|
||||
gc(thisFromCtor()),
|
||||
gcInitialized(false),
|
||||
emptyString(nullptr),
|
||||
|
|
|
@ -658,18 +658,7 @@ struct JSRuntime {
|
|||
private:
|
||||
js::UnprotectedData<js::jit::JitRuntime*> jitRuntime_;
|
||||
|
||||
/*
|
||||
* Self-hosting state cloned on demand into other compartments. Shared with
|
||||
* the parent runtime if there is one.
|
||||
*/
|
||||
js::WriteOnceData<js::NativeObject*> selfHostingGlobal_;
|
||||
|
||||
static js::GlobalObject* createSelfHostingGlobal(JSContext* cx);
|
||||
|
||||
public:
|
||||
void getUnclonedSelfHostedValue(js::PropertyName* name, JS::Value* vp);
|
||||
JSFunction* getUnclonedSelfHostedFunction(js::PropertyName* name);
|
||||
|
||||
mozilla::Maybe<js::frontend::ScriptIndexRange> getSelfHostedScriptIndexRange(
|
||||
js::PropertyName* name);
|
||||
|
||||
|
@ -701,11 +690,7 @@ struct JSRuntime {
|
|||
bool initSelfHosting(JSContext* cx, JS::SelfHostedCache xdrCache = nullptr,
|
||||
JS::SelfHostedWriter xdrWriter = nullptr);
|
||||
void finishSelfHosting();
|
||||
void traceSelfHostingGlobal(JSTracer* trc);
|
||||
void traceSelfHostingStencil(JSTracer* trc);
|
||||
bool isSelfHostingGlobal(JSObject* global) {
|
||||
return global == selfHostingGlobal_;
|
||||
}
|
||||
js::GeneratorKind getSelfHostedFunctionGeneratorKind(js::PropertyName* name);
|
||||
bool delazifySelfHostedFunction(JSContext* cx,
|
||||
js::Handle<js::PropertyName*> name,
|
||||
|
@ -713,11 +698,6 @@ struct JSRuntime {
|
|||
bool getSelfHostedValue(JSContext* cx, js::Handle<js::PropertyName*> name,
|
||||
js::MutableHandleValue vp);
|
||||
void assertSelfHostedFunctionHasCanonicalName(js::HandlePropertyName name);
|
||||
#if DEBUG
|
||||
bool isSelfHostingZone(const JS::Zone* zone) const {
|
||||
return selfHostingGlobal_ && selfHostingGlobal_->zone() == zone;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Locale information
|
||||
|
|
|
@ -894,17 +894,6 @@ bool js::intrinsic_NewRegExpStringIterator(JSContext* cx, unsigned argc,
|
|||
return true;
|
||||
}
|
||||
|
||||
static js::PropertyName* GetUnclonedSelfHostedCanonicalName(JSFunction* fun) {
|
||||
if (!fun->isExtended()) {
|
||||
return nullptr;
|
||||
}
|
||||
Value name = fun->getExtendedSlot(CANONICAL_FUNCTION_NAME_SLOT);
|
||||
if (!name.isString()) {
|
||||
return nullptr;
|
||||
}
|
||||
return name.toString()->asAtom().asPropertyName();
|
||||
}
|
||||
|
||||
js::PropertyName* js::GetClonedSelfHostedFunctionName(const JSFunction* fun) {
|
||||
if (!fun->isExtended()) {
|
||||
return nullptr;
|
||||
|
@ -933,10 +922,6 @@ bool js::IsExtendedUnclonedSelfHostedFunctionName(JSAtom* name) {
|
|||
ExtendedUnclonedSelfHostedFunctionNamePrefix;
|
||||
}
|
||||
|
||||
void js::SetUnclonedSelfHostedCanonicalName(JSFunction* fun, JSAtom* name) {
|
||||
fun->setExtendedSlot(CANONICAL_FUNCTION_NAME_SLOT, StringValue(name));
|
||||
}
|
||||
|
||||
void js::SetClonedSelfHostedFunctionName(JSFunction* fun,
|
||||
js::PropertyName* name) {
|
||||
fun->setExtendedSlot(LAZY_FUNCTION_NAME_SLOT, StringValue(name));
|
||||
|
@ -2597,53 +2582,6 @@ void js::FillSelfHostingCompileOptions(CompileOptions& options) {
|
|||
options.setNoScriptRval(true);
|
||||
}
|
||||
|
||||
GlobalObject* JSRuntime::createSelfHostingGlobal(JSContext* cx) {
|
||||
MOZ_ASSERT(!cx->isExceptionPending());
|
||||
MOZ_ASSERT(!cx->realm());
|
||||
|
||||
JS::RealmOptions options;
|
||||
options.creationOptions().setNewCompartmentInSelfHostingZone();
|
||||
// Debugging the selfHosted zone is not supported because CCWs are not
|
||||
// allowed in that zone.
|
||||
options.creationOptions().setInvisibleToDebugger(true);
|
||||
|
||||
Realm* realm = NewRealm(cx, nullptr, options);
|
||||
if (!realm) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static const JSClassOps shgClassOps = {
|
||||
nullptr, // addProperty
|
||||
nullptr, // delProperty
|
||||
nullptr, // enumerate
|
||||
nullptr, // newEnumerate
|
||||
nullptr, // resolve
|
||||
nullptr, // mayResolve
|
||||
nullptr, // finalize
|
||||
nullptr, // call
|
||||
nullptr, // hasInstance
|
||||
nullptr, // construct
|
||||
JS_GlobalObjectTraceHook, // trace
|
||||
};
|
||||
|
||||
static const JSClass shgClass = {"self-hosting-global", JSCLASS_GLOBAL_FLAGS,
|
||||
&shgClassOps};
|
||||
|
||||
AutoRealmUnchecked ar(cx, realm);
|
||||
Rooted<GlobalObject*> shg(cx, GlobalObject::createInternal(cx, &shgClass));
|
||||
if (!shg) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cx->runtime()->selfHostingGlobal_ = shg;
|
||||
MOZ_ASSERT(realm->zone()->isSelfHostingZone());
|
||||
realm->setIsSelfHostingRealm();
|
||||
|
||||
JS_FireOnNewGlobalObject(cx, shg);
|
||||
|
||||
return shg;
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS AutoSelfHostingErrorReporter {
|
||||
JSContext* cx_;
|
||||
JS::WarningReporter oldReporter_;
|
||||
|
@ -2864,15 +2802,6 @@ void JSRuntime::finishSelfHosting() {
|
|||
selfHostStencil_ = nullptr;
|
||||
|
||||
selfHostScriptMap.ref().clear();
|
||||
|
||||
selfHostingGlobal_ = nullptr;
|
||||
}
|
||||
|
||||
void JSRuntime::traceSelfHostingGlobal(JSTracer* trc) {
|
||||
if (selfHostingGlobal_ && !parentRuntime) {
|
||||
TraceRoot(trc, const_cast<NativeObject**>(&selfHostingGlobal_.ref()),
|
||||
"self-hosting global");
|
||||
}
|
||||
}
|
||||
|
||||
void JSRuntime::traceSelfHostingStencil(JSTracer* trc) {
|
||||
|
@ -2891,124 +2820,6 @@ GeneratorKind JSRuntime::getSelfHostedFunctionGeneratorKind(
|
|||
: GeneratorKind::NotGenerator;
|
||||
}
|
||||
|
||||
static bool CloneValue(JSContext* cx, HandleValue selfHostedValue,
|
||||
MutableHandleValue vp);
|
||||
|
||||
static void GetUnclonedValue(NativeObject* selfHostedObject,
|
||||
const PropertyKey& id, Value* vp) {
|
||||
if (JSID_IS_INT(id)) {
|
||||
size_t index = JSID_TO_INT(id);
|
||||
if (index < selfHostedObject->getDenseInitializedLength() &&
|
||||
!selfHostedObject->getDenseElement(index).isMagic(JS_ELEMENTS_HOLE)) {
|
||||
*vp = selfHostedObject->getDenseElement(JSID_TO_INT(id));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Since all atoms used by self-hosting are marked as permanent, the only
|
||||
// reason we'd see a non-permanent atom here is code looking for
|
||||
// properties on the self hosted global which aren't present.
|
||||
// Since we ensure that that can't happen during startup, encountering
|
||||
// non-permanent atoms here should be impossible.
|
||||
MOZ_ASSERT_IF(JSID_IS_STRING(id), JSID_TO_STRING(id)->isPermanentAtom());
|
||||
|
||||
mozilla::Maybe<PropertyInfo> prop = selfHostedObject->lookupPure(id);
|
||||
MOZ_ASSERT(prop.isSome());
|
||||
MOZ_ASSERT(prop->isDataProperty());
|
||||
*vp = selfHostedObject->getSlot(prop->slot());
|
||||
}
|
||||
|
||||
static bool CloneProperties(JSContext* cx, HandleNativeObject selfHostedObject,
|
||||
HandleObject clone) {
|
||||
RootedIdVector ids(cx);
|
||||
Vector<uint8_t, 16> attrs(cx);
|
||||
|
||||
for (size_t i = 0; i < selfHostedObject->getDenseInitializedLength(); i++) {
|
||||
if (!selfHostedObject->getDenseElement(i).isMagic(JS_ELEMENTS_HOLE)) {
|
||||
if (!ids.append(INT_TO_JSID(i))) {
|
||||
return false;
|
||||
}
|
||||
if (!attrs.append(JSPROP_ENUMERATE)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rooted<PropertyInfoWithKeyVector> props(cx, PropertyInfoWithKeyVector(cx));
|
||||
for (ShapePropertyIter<NoGC> iter(selfHostedObject->shape()); !iter.done();
|
||||
iter++) {
|
||||
if (iter->enumerable() && !props.append(*iter)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now our properties are in last-to-first order, so....
|
||||
std::reverse(props.begin(), props.end());
|
||||
for (size_t i = 0; i < props.length(); ++i) {
|
||||
MOZ_ASSERT(props[i].isDataProperty(),
|
||||
"Can't handle cloning accessors here yet.");
|
||||
if (!ids.append(props[i].key())) {
|
||||
return false;
|
||||
}
|
||||
PropertyInfo prop = props[i];
|
||||
uint8_t propAttrs = 0;
|
||||
if (prop.enumerable()) {
|
||||
propAttrs |= JSPROP_ENUMERATE;
|
||||
}
|
||||
if (!prop.configurable()) {
|
||||
propAttrs |= JSPROP_PERMANENT;
|
||||
}
|
||||
if (!prop.writable()) {
|
||||
propAttrs |= JSPROP_READONLY;
|
||||
}
|
||||
if (!attrs.append(propAttrs)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RootedId id(cx);
|
||||
RootedValue val(cx);
|
||||
RootedValue selfHostedValue(cx);
|
||||
for (uint32_t i = 0; i < ids.length(); i++) {
|
||||
id = ids[i];
|
||||
GetUnclonedValue(selfHostedObject, id, selfHostedValue.address());
|
||||
if (!CloneValue(cx, selfHostedValue, &val) ||
|
||||
!JS_DefinePropertyById(cx, clone, id, val, attrs[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSString* CloneString(JSContext* cx, JSLinearString* selfHostedString) {
|
||||
size_t len = selfHostedString->length();
|
||||
{
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
JSString* clone;
|
||||
if (selfHostedString->hasLatin1Chars()) {
|
||||
clone =
|
||||
NewStringCopyN<NoGC>(cx, selfHostedString->latin1Chars(nogc), len);
|
||||
} else {
|
||||
clone = NewStringCopyNDontDeflate<NoGC>(
|
||||
cx, selfHostedString->twoByteChars(nogc), len);
|
||||
}
|
||||
if (clone) {
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
AutoStableStringChars chars(cx);
|
||||
if (!chars.init(cx, selfHostedString)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return chars.isLatin1()
|
||||
? NewStringCopyN<CanGC>(cx, chars.latin1Range().begin().get(), len)
|
||||
: NewStringCopyNDontDeflate<CanGC>(
|
||||
cx, chars.twoByteRange().begin().get(), len);
|
||||
}
|
||||
|
||||
// Returns the ScriptSourceObject to use for cloned self-hosted scripts in the
|
||||
// current realm.
|
||||
ScriptSourceObject* js::SelfHostingScriptSourceObject(JSContext* cx) {
|
||||
|
@ -3042,146 +2853,6 @@ ScriptSourceObject* js::SelfHostingScriptSourceObject(JSContext* cx) {
|
|||
return sourceObject;
|
||||
}
|
||||
|
||||
static JSObject* CloneObject(JSContext* cx,
|
||||
HandleNativeObject selfHostedObject) {
|
||||
#ifdef DEBUG
|
||||
// Object hash identities are owned by the hashed object, which may be on a
|
||||
// different thread than the clone target. In theory, these objects are all
|
||||
// tenured and will not be compacted; however, we simply avoid the issue
|
||||
// altogether by skipping the cycle-detection when off thread.
|
||||
mozilla::Maybe<AutoCycleDetector> detect;
|
||||
if (js::CurrentThreadCanAccessZone(selfHostedObject->zoneFromAnyThread())) {
|
||||
detect.emplace(cx, selfHostedObject);
|
||||
if (!detect->init()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (detect->foundCycle()) {
|
||||
MOZ_CRASH("SelfHosted cloning cannot handle cyclic object graphs.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
RootedObject clone(cx);
|
||||
if (selfHostedObject->is<JSFunction>()) {
|
||||
RootedFunction selfHostedFunction(cx, &selfHostedObject->as<JSFunction>());
|
||||
if (selfHostedFunction->isInterpreted()) {
|
||||
// Arrow functions use the first extended slot for their lexical |this|
|
||||
// value. And methods use the first extended slot for their home-object.
|
||||
// We only expect to see normal functions here.
|
||||
MOZ_ASSERT(selfHostedFunction->kind() == FunctionFlags::NormalFunction);
|
||||
MOZ_ASSERT(selfHostedFunction->isLambda() == false);
|
||||
|
||||
Handle<GlobalObject*> global = cx->global();
|
||||
Rooted<GlobalLexicalEnvironmentObject*> globalLexical(
|
||||
cx, &global->lexicalEnvironment());
|
||||
RootedScope emptyGlobalScope(cx, &global->emptyGlobalScope());
|
||||
Rooted<ScriptSourceObject*> sourceObject(
|
||||
cx, SelfHostingScriptSourceObject(cx));
|
||||
if (!sourceObject) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(
|
||||
!CanReuseScriptForClone(cx->realm(), selfHostedFunction, global));
|
||||
clone = CloneFunctionAndScript(cx, selfHostedFunction, globalLexical,
|
||||
emptyGlobalScope, sourceObject,
|
||||
gc::AllocKind::FUNCTION_EXTENDED);
|
||||
if (!clone) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Save the original function name that we are cloning from. This allows
|
||||
// the function to potentially be relazified in the future.
|
||||
SetClonedSelfHostedFunctionName(
|
||||
&clone->as<JSFunction>(),
|
||||
selfHostedFunction->explicitName()->asPropertyName());
|
||||
|
||||
// If |_SetCanonicalName| was called on the function, the function name to
|
||||
// use is stored in the extended slot.
|
||||
if (JSAtom* name =
|
||||
GetUnclonedSelfHostedCanonicalName(selfHostedFunction)) {
|
||||
clone->as<JSFunction>().setAtom(name);
|
||||
}
|
||||
} else {
|
||||
clone = CloneSelfHostingIntrinsic(cx, selfHostedFunction);
|
||||
}
|
||||
} else if (selfHostedObject->is<RegExpObject>()) {
|
||||
RegExpObject& reobj = selfHostedObject->as<RegExpObject>();
|
||||
RootedAtom source(cx, reobj.getSource());
|
||||
MOZ_ASSERT(source->isPermanentAtom());
|
||||
clone = RegExpObject::create(cx, source, reobj.getFlags(), TenuredObject);
|
||||
} else if (selfHostedObject->is<DateObject>()) {
|
||||
clone =
|
||||
JS::NewDateObject(cx, selfHostedObject->as<DateObject>().clippedTime());
|
||||
} else if (selfHostedObject->is<BooleanObject>()) {
|
||||
clone = BooleanObject::create(
|
||||
cx, selfHostedObject->as<BooleanObject>().unbox());
|
||||
} else if (selfHostedObject->is<NumberObject>()) {
|
||||
clone =
|
||||
NumberObject::create(cx, selfHostedObject->as<NumberObject>().unbox());
|
||||
} else if (selfHostedObject->is<StringObject>()) {
|
||||
JSString* selfHostedString = selfHostedObject->as<StringObject>().unbox();
|
||||
if (!selfHostedString->isLinear()) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
RootedString str(cx, CloneString(cx, &selfHostedString->asLinear()));
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
clone = StringObject::create(cx, str);
|
||||
} else if (selfHostedObject->is<ArrayObject>()) {
|
||||
clone = NewTenuredDenseEmptyArray(cx, nullptr);
|
||||
} else {
|
||||
MOZ_ASSERT(selfHostedObject->is<NativeObject>());
|
||||
clone = NewObjectWithGivenProto(
|
||||
cx, selfHostedObject->getClass(), nullptr,
|
||||
selfHostedObject->asTenured().getAllocKind(), TenuredObject);
|
||||
}
|
||||
if (!clone) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!CloneProperties(cx, selfHostedObject, clone)) {
|
||||
return nullptr;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
static bool CloneValue(JSContext* cx, HandleValue selfHostedValue,
|
||||
MutableHandleValue vp) {
|
||||
if (selfHostedValue.isObject()) {
|
||||
RootedNativeObject selfHostedObject(
|
||||
cx, &selfHostedValue.toObject().as<NativeObject>());
|
||||
JSObject* clone = CloneObject(cx, selfHostedObject);
|
||||
if (!clone) {
|
||||
return false;
|
||||
}
|
||||
vp.setObject(*clone);
|
||||
} else if (selfHostedValue.isBoolean() || selfHostedValue.isNumber() ||
|
||||
selfHostedValue.isNullOrUndefined()) {
|
||||
// Nothing to do here: these are represented inline in the value.
|
||||
vp.set(selfHostedValue);
|
||||
} else if (selfHostedValue.isString()) {
|
||||
if (!selfHostedValue.toString()->isLinear()) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
JSLinearString* selfHostedString = &selfHostedValue.toString()->asLinear();
|
||||
JSString* clone = CloneString(cx, selfHostedString);
|
||||
if (!clone) {
|
||||
return false;
|
||||
}
|
||||
vp.setString(clone);
|
||||
} else if (selfHostedValue.isSymbol()) {
|
||||
// Well-known symbols are shared.
|
||||
mozilla::DebugOnly<JS::Symbol*> sym = selfHostedValue.toSymbol();
|
||||
MOZ_ASSERT(sym->isWellKnownSymbol());
|
||||
MOZ_ASSERT(cx->wellKnownSymbols().get(sym->code()) == sym);
|
||||
vp.set(selfHostedValue);
|
||||
} else {
|
||||
MOZ_CRASH("Self-hosting CloneValue can't clone given value.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JSRuntime::delazifySelfHostedFunction(JSContext* cx,
|
||||
HandlePropertyName name,
|
||||
HandleFunction targetFun) {
|
||||
|
@ -3209,17 +2880,6 @@ bool JSRuntime::delazifySelfHostedFunction(JSContext* cx,
|
|||
return true;
|
||||
}
|
||||
|
||||
void JSRuntime::getUnclonedSelfHostedValue(PropertyName* name, Value* vp) {
|
||||
PropertyKey id = NameToId(name);
|
||||
GetUnclonedValue(selfHostingGlobal_, id, vp);
|
||||
}
|
||||
|
||||
JSFunction* JSRuntime::getUnclonedSelfHostedFunction(PropertyName* name) {
|
||||
Value selfHostedValue;
|
||||
getUnclonedSelfHostedValue(name, &selfHostedValue);
|
||||
return &selfHostedValue.toObject().as<JSFunction>();
|
||||
}
|
||||
|
||||
mozilla::Maybe<frontend::ScriptIndexRange>
|
||||
JSRuntime::getSelfHostedScriptIndexRange(js::PropertyName* name) {
|
||||
if (parentRuntime) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче