// Copyright 2020 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. namespace runtime { extern runtime JSWeakRefAddToKeptObjects(implicit context: Context)(JSReceiver); } // namespace runtime namespace weakref { transitioning javascript builtin WeakRefConstructor( js-implicit context: NativeContext, receiver: JSAny, newTarget: JSAny, target: JSFunction)(weakTarget: JSAny): JSWeakRef { // 1. If NewTarget is undefined, throw a TypeError exception. if (newTarget == Undefined) { ThrowTypeError(MessageTemplate::kConstructorNotFunction, 'WeakRef'); } // 2. If Type(target) is not Object, throw a TypeError exception. const weakTarget = Cast(weakTarget) otherwise ThrowTypeError( MessageTemplate::kWeakRefsWeakRefConstructorTargetMustBeObject); // 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, // "%WeakRefPrototype%", « [[WeakRefTarget]] »). const map = GetDerivedMap(target, UnsafeCast(newTarget)); const weakRef = UnsafeCast(AllocateFastOrSlowJSObjectFromMap(map)); // 4. Perfom ! AddToKeptObjects(target). runtime::JSWeakRefAddToKeptObjects(weakTarget); // 5. Set weakRef.[[WeakRefTarget]] to target. weakRef.target = weakTarget; // 6. Return weakRef. return weakRef; } transitioning javascript builtin WeakRefDeref(js-implicit context: NativeContext, receiver: JSAny)(): JSAny { // 1. Let weakRef be the this value. // 2. Perform ? RequireInternalSlot(weakRef, [[WeakRefTarget]]). const weakRef = Cast(receiver) otherwise ThrowTypeError( MessageTemplate::kIncompatibleMethodReceiver, 'WeakRef.prototype.deref', receiver); // 3. Let target be the value of weakRef.[[WeakRefTarget]]. const target = weakRef.target; // 4. If target is not empty, // a. Perform ! AddToKeptObjects(target). // b. Return target. // 5. Return undefined. if (target != Undefined) { // JSWeakRefAddToKeptObjects might allocate and cause a GC, but it // won't clear `target` since we hold it here on the stack. runtime::JSWeakRefAddToKeptObjects(UnsafeCast(target)); } return target; } } // namespace weakrefs