• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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