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