5 #include "src/builtins/builtins-utils-inl.h" 6 #include "src/counters.h" 7 #include "src/objects/js-weak-refs-inl.h" 12 BUILTIN(WeakFactoryConstructor) {
13 HandleScope scope(isolate);
14 Handle<JSFunction> target = args.target();
15 if (args.new_target()->IsUndefined(isolate)) {
16 THROW_NEW_ERROR_RETURN_FAILURE(
17 isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
18 handle(target->shared()->Name(), isolate)));
21 Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
22 Handle<Object> cleanup = args.atOrUndefined(isolate, 1);
24 if (!cleanup->IsCallable()) {
25 THROW_NEW_ERROR_RETURN_FAILURE(
26 isolate, NewTypeError(MessageTemplate::kWeakRefsCleanupMustBeCallable));
29 Handle<JSObject> result;
30 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
32 JSObject::New(target, new_target, Handle<AllocationSite>::null()));
34 Handle<JSWeakFactory> weak_factory = Handle<JSWeakFactory>::cast(result);
35 weak_factory->set_native_context(*isolate->native_context());
36 weak_factory->set_cleanup(*cleanup);
37 weak_factory->set_flags(
38 JSWeakFactory::ScheduledForCleanupField::encode(
false));
42 BUILTIN(WeakFactoryMakeCell) {
43 HandleScope scope(isolate);
44 const char* method_name =
"WeakFactory.prototype.makeCell";
46 CHECK_RECEIVER(JSWeakFactory, weak_factory, method_name);
48 Handle<Object> target = args.atOrUndefined(isolate, 1);
49 if (!target->IsJSReceiver()) {
50 THROW_NEW_ERROR_RETURN_FAILURE(
52 NewTypeError(MessageTemplate::kWeakRefsMakeCellTargetMustBeObject));
54 Handle<JSReceiver> target_receiver = Handle<JSReceiver>::cast(target);
55 Handle<Object> holdings = args.atOrUndefined(isolate, 2);
56 if (target->SameValue(*holdings)) {
57 THROW_NEW_ERROR_RETURN_FAILURE(
60 MessageTemplate::kWeakRefsMakeCellTargetAndHoldingsMustNotBeSame));
65 Handle<Map> weak_cell_map(isolate->native_context()->js_weak_cell_map(),
71 Handle<JSWeakCell> weak_cell =
72 Handle<JSWeakCell>::cast(isolate->factory()->NewJSObjectFromMap(
73 weak_cell_map, TENURED, Handle<AllocationSite>::null()));
74 weak_cell->set_target(*target_receiver);
75 weak_cell->set_holdings(*holdings);
76 weak_factory->AddWeakCell(*weak_cell);
80 BUILTIN(WeakFactoryMakeRef) {
81 HandleScope scope(isolate);
82 const char* method_name =
"WeakFactory.prototype.makeRef";
84 CHECK_RECEIVER(JSWeakFactory, weak_factory, method_name);
86 Handle<Object> target = args.atOrUndefined(isolate, 1);
87 if (!target->IsJSReceiver()) {
88 THROW_NEW_ERROR_RETURN_FAILURE(
90 NewTypeError(MessageTemplate::kWeakRefsMakeRefTargetMustBeObject));
92 Handle<JSReceiver> target_receiver = Handle<JSReceiver>::cast(target);
93 Handle<Object> holdings = args.atOrUndefined(isolate, 2);
94 if (target->SameValue(*holdings)) {
95 THROW_NEW_ERROR_RETURN_FAILURE(
98 MessageTemplate::kWeakRefsMakeRefTargetAndHoldingsMustNotBeSame));
103 Handle<Map> weak_ref_map(isolate->native_context()->js_weak_ref_map(),
106 Handle<JSWeakRef> weak_ref =
107 Handle<JSWeakRef>::cast(isolate->factory()->NewJSObjectFromMap(
108 weak_ref_map, TENURED, Handle<AllocationSite>::null()));
109 weak_ref->set_target(*target_receiver);
110 weak_ref->set_holdings(*holdings);
111 weak_factory->AddWeakCell(*weak_ref);
113 isolate->heap()->AddKeepDuringJobTarget(target_receiver);
118 BUILTIN(WeakFactoryCleanupSome) {
119 HandleScope scope(isolate);
120 const char* method_name =
"WeakFactory.prototype.cleanupSome";
122 CHECK_RECEIVER(JSWeakFactory, weak_factory, method_name);
127 JSWeakFactory::Cleanup(weak_factory, isolate);
128 return ReadOnlyRoots(isolate).undefined_value();
131 BUILTIN(WeakFactoryCleanupIteratorNext) {
132 HandleScope scope(isolate);
133 CHECK_RECEIVER(JSWeakFactoryCleanupIterator, iterator,
"next");
135 Handle<JSWeakFactory> weak_factory(iterator->factory(), isolate);
136 if (!weak_factory->NeedsCleanup()) {
137 return *isolate->factory()->NewJSIteratorResult(
138 handle(ReadOnlyRoots(isolate).undefined_value(), isolate),
true);
140 Handle<JSWeakCell> weak_cell_object =
141 handle(weak_factory->PopClearedCell(isolate), isolate);
143 return *isolate->factory()->NewJSIteratorResult(weak_cell_object,
false);
146 BUILTIN(WeakCellHoldingsGetter) {
147 HandleScope scope(isolate);
148 CHECK_RECEIVER(JSWeakCell, weak_cell,
"get WeakCell.holdings");
149 return weak_cell->holdings();
152 BUILTIN(WeakCellClear) {
153 HandleScope scope(isolate);
154 CHECK_RECEIVER(JSWeakCell, weak_cell,
"WeakCell.prototype.clear");
155 weak_cell->Clear(isolate);
156 return ReadOnlyRoots(isolate).undefined_value();
159 BUILTIN(WeakRefDeref) {
160 HandleScope scope(isolate);
161 CHECK_RECEIVER(JSWeakRef, weak_ref,
"WeakRef.prototype.deref");
162 if (weak_ref->target()->IsJSReceiver()) {
163 Handle<JSReceiver> target =
164 handle(JSReceiver::cast(weak_ref->target()), isolate);
167 isolate->heap()->AddKeepDuringJobTarget(target);
169 DCHECK(weak_ref->target()->IsUndefined(isolate));
171 return weak_ref->target();