1// Copyright 2020 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5namespace runtime { 6 7extern runtime JSWeakRefAddToKeptObjects(implicit context: Context)(JSReceiver): 8 void; 9 10} // namespace runtime 11 12namespace weakref { 13 14transitioning javascript builtin 15WeakRefConstructor( 16 js-implicit context: NativeContext, receiver: JSAny, newTarget: JSAny, 17 target: JSFunction)(weakTarget: JSAny): JSWeakRef { 18 // 1. If NewTarget is undefined, throw a TypeError exception. 19 if (newTarget == Undefined) { 20 ThrowTypeError(MessageTemplate::kConstructorNotFunction, 'WeakRef'); 21 } 22 // 2. If Type(target) is not Object, throw a TypeError exception. 23 const weakTarget = Cast<JSReceiver>(weakTarget) otherwise 24 ThrowTypeError( 25 MessageTemplate::kWeakRefsWeakRefConstructorTargetMustBeObject); 26 // 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, 27 // "%WeakRefPrototype%", « [[WeakRefTarget]] »). 28 const map = GetDerivedMap(target, UnsafeCast<JSReceiver>(newTarget)); 29 const weakRef = UnsafeCast<JSWeakRef>(AllocateFastOrSlowJSObjectFromMap(map)); 30 // 4. Perfom ! AddToKeptObjects(target). 31 runtime::JSWeakRefAddToKeptObjects(weakTarget); 32 // 5. Set weakRef.[[WeakRefTarget]] to target. 33 weakRef.target = weakTarget; 34 // 6. Return weakRef. 35 return weakRef; 36} 37 38transitioning javascript builtin 39WeakRefDeref(js-implicit context: NativeContext, receiver: JSAny)(): JSAny { 40 // 1. Let weakRef be the this value. 41 // 2. Perform ? RequireInternalSlot(weakRef, [[WeakRefTarget]]). 42 const weakRef = Cast<JSWeakRef>(receiver) otherwise 43 ThrowTypeError( 44 MessageTemplate::kIncompatibleMethodReceiver, 'WeakRef.prototype.deref', 45 receiver); 46 // 3. Let target be the value of weakRef.[[WeakRefTarget]]. 47 const target = weakRef.target; 48 // 4. If target is not empty, 49 // a. Perform ! AddToKeptObjects(target). 50 // b. Return target. 51 // 5. Return undefined. 52 if (target != Undefined) { 53 // JSWeakRefAddToKeptObjects might allocate and cause a GC, but it 54 // won't clear `target` since we hold it here on the stack. 55 runtime::JSWeakRefAddToKeptObjects(UnsafeCast<JSReceiver>(target)); 56 } 57 return target; 58} 59 60} // namespace weakrefs 61