blob: ee2194d9ec11401c69c13029d42068bbd8620072 [file] [log] [blame]
// 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.
#include 'src/builtins/builtins-collections-gen.h'
namespace runtime {
extern runtime JSWeakRefAddToKeptObjects(
implicit context: Context)(JSReceiver|Symbol): void;
} // namespace runtime
namespace weakref {
// https://tc39.es/ecma262/#sec-weak-ref-target
@incrementUseCounter('v8::Isolate::kWeakReferences')
transitioning javascript builtin WeakRefConstructor(
js-implicit context: NativeContext, receiver: JSAny, newTarget: JSAny,
target: JSFunction)(...arguments): JSWeakRef {
// 1. If NewTarget is undefined, throw a TypeError exception.
if (newTarget == Undefined) {
ThrowTypeError(MessageTemplate::kConstructorNotFunction, 'WeakRef');
}
if (arguments.actual_count == 0) {
ThrowTypeError(MessageTemplate::kInvalidWeakRefsWeakRefConstructorTarget);
}
// 2. If CanBeHeldWeakly(weakTarget) is false, throw a TypeError exception.
GotoIfCannotBeHeldWeakly(arguments[0]) otherwise ThrowTypeError(
MessageTemplate::kInvalidWeakRefsWeakRefConstructorTarget);
const weakTarget = UnsafeCast<(JSReceiver | Symbol)>(arguments[0]);
// 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget,
// "%WeakRefPrototype%", « [[WeakRefTarget]] »).
const map = GetDerivedMap(target, UnsafeCast<JSReceiver>(newTarget));
const weakRef = UnsafeCast<JSWeakRef>(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<JSWeakRef>(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<(JSReceiver | Symbol)>(target));
}
return target;
}
} // namespace weakrefs