Skip to content

Commit

Permalink
Implement FinalizationRegistry of Symbol type
Browse files Browse the repository at this point in the history
Signed-off-by: HyukWoo Park <hyukwoo.park@samsung.com>
  • Loading branch information
clover2123 committed Jan 12, 2024
1 parent 062c5a5 commit a29896f
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 23 deletions.
5 changes: 3 additions & 2 deletions src/api/EscargotPublic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4265,12 +4265,13 @@ WeakSetObjectRef* WeakSetObjectRef::create(ExecutionStateRef* state)
return toRef(new WeakSetObject(*toImpl(state)));
}

void WeakSetObjectRef::add(ExecutionStateRef* state, ValueRef* key)
bool WeakSetObjectRef::add(ExecutionStateRef* state, ValueRef* key)
{
if (!toImpl(key).canBeHeldWeakly(toImpl(state)->context()->vmInstance())) {
return;
return false;
}
toImpl(this)->add(*toImpl(state), toImpl(key).asPointerValue());
return true;
}

bool WeakSetObjectRef::deleteOperation(ExecutionStateRef* state, ValueRef* key)
Expand Down
2 changes: 1 addition & 1 deletion src/api/EscargotPublic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1910,7 +1910,7 @@ class ESCARGOT_EXPORT SetObjectRef : public ObjectRef {
class ESCARGOT_EXPORT WeakSetObjectRef : public ObjectRef {
public:
static WeakSetObjectRef* create(ExecutionStateRef* state);
void add(ExecutionStateRef* state, ValueRef* key);
bool add(ExecutionStateRef* state, ValueRef* key);
bool deleteOperation(ExecutionStateRef* state, ValueRef* key);
bool has(ExecutionStateRef* state, ValueRef* key);
};
Expand Down
24 changes: 12 additions & 12 deletions src/builtins/BuiltinFinalizationRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static Value builtinFinalizationRegistryConstructor(ExecutionState& state, Value
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::GlobalObject_ConstructorRequiresNew);
return Value();
}
if (argc == 0 || !argv[0].isCallable()) {
if (!argv[0].isCallable()) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "cleanup Callback is not callable");
}

Expand All @@ -54,32 +54,32 @@ static Value builtinfinalizationRegistryRegister(ExecutionState& state, Value th
{
RESOLVE_THIS_BINDING_TO_FINALIZATIONREGISTRY(finalRegistry, stringRegister);

if (argc == 0 || !argv[0].isObject()) {
if (!argv[0].canBeHeldWeakly(state.context()->vmInstance())) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "target is not object");
}
if (argv[0] == argv[1]) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "target and heldValue is the same");
}

Optional<Object*> unregisterToken;
if (argc >= 3) {
if (argv[2].isObject()) {
unregisterToken = argv[2].asObject();
} else if (!argv[2].isUndefined()) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "unregisterToken is not undefined");
}
Optional<PointerValue*> unregisterToken;
Value tokenValue = argc >= 3 ? argv[2] : Value();
if (tokenValue.canBeHeldWeakly(state.context()->vmInstance())) {
unregisterToken = argv[2].asPointerValue();
} else if (!tokenValue.isUndefined()) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "unregisterToken is not undefined");
}
finalRegistry->setCell(argv[0].asObject(), argv[1], unregisterToken);

finalRegistry->setCell(argv[0].asPointerValue(), argv[1], unregisterToken);
return Value();
}

static Value builtinfinalizationRegistryUnregister(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_FINALIZATIONREGISTRY(finalRegistry, unregister);
if (argc == 0 || !argv[0].isObject()) {
if (!argv[0].canBeHeldWeakly(state.context()->vmInstance())) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "unregisterToken is not object");
}
return Value(finalRegistry->deleteCell(argv[0].asObject()));
return Value(finalRegistry->deleteCell(argv[0].asPointerValue()));
}

static Value builtinfinalizationRegistryCleanupSome(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
Expand Down
6 changes: 4 additions & 2 deletions src/runtime/FinalizationRegistryObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ void* FinalizationRegistryObject::operator new(size_t size)
return GC_MALLOC_EXPLICITLY_TYPED(size, descr);
}

void FinalizationRegistryObject::setCell(Object* weakRefTarget, const Value& heldValue, Optional<Object*> unregisterToken)
void FinalizationRegistryObject::setCell(PointerValue* weakRefTarget, const Value& heldValue, Optional<PointerValue*> unregisterToken)
{
ASSERT(!!weakRefTarget);
ASSERT(weakRefTarget->isObject() || weakRefTarget->isSymbol());
FinalizationRegistryObjectItem* newCell = nullptr;

if (m_deletedCellCount) {
Expand All @@ -99,9 +100,10 @@ void FinalizationRegistryObject::setCell(Object* weakRefTarget, const Value& hel
weakRefTarget->addFinalizer(finalizer, newCell);
}

bool FinalizationRegistryObject::deleteCell(Object* unregisterToken)
bool FinalizationRegistryObject::deleteCell(PointerValue* unregisterToken)
{
ASSERT(!!unregisterToken);
ASSERT(unregisterToken->isObject() || unregisterToken->isSymbol());
bool removed = false;
for (size_t i = 0; i < m_cells.size(); i++) {
if (m_cells[i]->unregisterToken.hasValue() && m_cells[i]->unregisterToken.value() == unregisterToken) {
Expand Down
8 changes: 4 additions & 4 deletions src/runtime/FinalizationRegistryObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ class FinalizationRegistryObject : public DerivedObject {
#if !defined(NDEBUG)
friend int getValidValueInFinalizationRegistryObjectItem(void* ptr, GC_mark_custom_result* arr);
#endif
Object* weakRefTarget;
PointerValue* weakRefTarget;
EncodedValue heldValue;
FinalizationRegistryObject* source;
Optional<Object*> unregisterToken;
Optional<PointerValue*> unregisterToken;

void reset()
{
Expand All @@ -59,8 +59,8 @@ class FinalizationRegistryObject : public DerivedObject {
return true;
}

void setCell(Object* weakRefTarget, const Value& heldValue, Optional<Object*> unregisterToken);
bool deleteCell(Object* unregisterToken);
void setCell(PointerValue* weakRefTarget, const Value& heldValue, Optional<PointerValue*> unregisterToken);
bool deleteCell(PointerValue* unregisterToken);
bool deleteCellOnly(FinalizationRegistryObjectItem* item);
void cleanupSome(ExecutionState& state, Optional<Object*> callback);

Expand Down
1 change: 1 addition & 0 deletions tools/test/spidermonkey/excludelist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ non262/regress/regress-591846.js
non262/Reflect/surfaces.js
non262/Reflect/target.js
non262/Promise/iterator-close.js
non262/WeakMap/symbols.js

# Passed in 64bit but, Failed in 32bit binary due to value expression bug in 32bit mode
non262/TypedArray/sort-negative-nan.js
Expand Down
2 changes: 0 additions & 2 deletions tools/test/test262/excludelist.orig.xml
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,6 @@
<test id="built-ins/Date/UTC/fp-evaluation-order"><reason>TODO</reason></test>
<test id="built-ins/Date/parse/year-zero"><reason>TODO</reason></test>
<test id="built-ins/Date/year-zero"><reason>TODO</reason></test>
<test id="built-ins/FinalizationRegistry/prototype/register/return-undefined-register-symbol"><reason>TODO</reason></test>
<test id="built-ins/FinalizationRegistry/prototype/unregister/unregister-symbol-token"><reason>TODO</reason></test>
<test id="built-ins/Function/internals/Construct/derived-this-uninitialized-realm"><reason>TODO</reason></test>
<test id="built-ins/Function/prototype/toString/line-terminator-normalisation-CR"><reason>TODO</reason></test>
<test id="built-ins/GeneratorFunction/prototype/not-callable"><reason>TODO</reason></test>
Expand Down

0 comments on commit a29896f

Please sign in to comment.