Implement WeakRef Object

related test262 test-cases has been removed from the skip list

Except two test since it needs FinalizationRegistry feature

Signed-off-by: bence gabor kis <kisbg@inf.u-szeged.hu>
This commit is contained in:
bence gabor kis 2021-01-11 09:02:10 +01:00 committed by Patrick Kim
commit ccd0ec704c
11 changed files with 234 additions and 24 deletions

View file

@ -49,6 +49,7 @@
#include "runtime/WeakSetObject.h"
#include "runtime/MapObject.h"
#include "runtime/WeakMapObject.h"
#include "runtime/WeakRefObject.h"
#include "runtime/GlobalObjectProxyObject.h"
#include "runtime/CompressibleString.h"
#include "runtime/ReloadableString.h"
@ -759,6 +760,7 @@ DEFINE_IS_AS_POINTERVALUE_XXX(SetObject)
DEFINE_IS_AS_POINTERVALUE_XXX(WeakSetObject)
DEFINE_IS_AS_POINTERVALUE_XXX(MapObject)
DEFINE_IS_AS_POINTERVALUE_XXX(WeakMapObject)
DEFINE_IS_AS_POINTERVALUE_XXX(WeakRefObject)
DEFINE_IS_AS_POINTERVALUE_XXX(GlobalObjectProxyObject)
bool ValueRef::isSetIteratorObject()
@ -2973,6 +2975,16 @@ bool WeakMapObjectRef::has(ExecutionStateRef* state, ObjectRef* key)
return toImpl(this)->has(*toImpl(state), toImpl(key));
}
WeakRefObjectRef* WeakRefObjectRef::create(ExecutionStateRef* state, ObjectRef* target)
{
return toRef(new WeakRefObject(*toImpl(state), toImpl(target)));
}
bool WeakRefObjectRef::deleteOperation(ExecutionStateRef* state)
{
return toImpl(this)->deleteOperation(*toImpl(state));
}
void TemplateRef::set(const TemplatePropertyNameRef& name, ValueRef* data, bool isWritable, bool isEnumerable, bool isConfigurable)
{
toImpl(this)->set(TemplatePropertyName(toImpl(name.value())), toImpl(data), isWritable, isEnumerable, isConfigurable);

View file

@ -73,6 +73,7 @@ class SetObjectRef;
class WeakSetObjectRef;
class MapObjectRef;
class WeakMapObjectRef;
class WeakRefObjectRef;
class ErrorObjectRef;
class DateObjectRef;
class StringObjectRef;
@ -714,6 +715,7 @@ public:
bool isSetIteratorObject();
bool isMapObject();
bool isWeakMapObject();
bool isWeakRefObject();
bool isMapIteratorObject();
bool isGlobalObjectProxyObject();
@ -774,6 +776,7 @@ public:
WeakSetObjectRef* asWeakSetObject();
MapObjectRef* asMapObject();
WeakMapObjectRef* asWeakMapObject();
WeakRefObjectRef* asWeakRefObject();
GlobalObjectProxyObjectRef* asGlobalObjectProxyObject();
bool abstractEqualsTo(ExecutionStateRef* state, const ValueRef* other) const; // ==
@ -1573,6 +1576,12 @@ public:
void set(ExecutionStateRef* state, ObjectRef* key, ValueRef* value);
};
class ESCARGOT_EXPORT WeakRefObjectRef : public ObjectRef {
public:
static WeakRefObjectRef* create(ExecutionStateRef* state, ObjectRef* target);
bool deleteOperation(ExecutionStateRef* state);
};
class ESCARGOT_EXPORT TemplatePropertyNameRef {
public:
TemplatePropertyNameRef(StringRef* name = StringRef::emptyString())

View file

@ -103,6 +103,7 @@ DEFINE_CAST(SetObject);
DEFINE_CAST(WeakSetObject);
DEFINE_CAST(MapObject);
DEFINE_CAST(WeakMapObject);
DEFINE_CAST(WeakRefObject);
DEFINE_CAST(Template);
DEFINE_CAST(ObjectTemplate);
DEFINE_CAST(FunctionTemplate);

View file

@ -90,6 +90,7 @@ void GlobalObject::installBuiltins(ExecutionState& state)
installMap(state);
installSet(state);
installWeakMap(state);
installWeakRef(state);
installWeakSet(state);
installGenerator(state);
installAsyncFunction(state);

View file

@ -201,6 +201,9 @@ class FunctionObject;
#define GLOBALOBJECT_BUILTIN_WEAKSET(F, NAME) \
F(weakSet, FunctionObject, NAME) \
F(weakSetPrototype, Object, NAME)
#define GLOBALOBJECT_BUILTIN_WEAKREF(F, NAME) \
F(weakRef, FunctionObject, NAME) \
F(weakRefPrototype, Object, NAME)
//WebAssembly
#if defined(ENABLE_WASM)
#define GLOBALOBJECT_BUILTIN_WASM(F, NAME) \
@ -250,6 +253,7 @@ class FunctionObject;
GLOBALOBJECT_BUILTIN_TYPEDARRAY(F, TypedArray) \
GLOBALOBJECT_BUILTIN_WEAKMAP(F, WeakMap) \
GLOBALOBJECT_BUILTIN_WEAKSET(F, WeakSet) \
GLOBALOBJECT_BUILTIN_WEAKREF(F, WeakRef) \
GLOBALOBJECT_BUILTIN_WASM(F, WebAssembly)
@ -334,6 +338,7 @@ private:
void installMap(ExecutionState& state);
void installSet(ExecutionState& state);
void installWeakMap(ExecutionState& state);
void installWeakRef(ExecutionState& state);
void installWeakSet(ExecutionState& state);
void installGenerator(ExecutionState& state);
void installAsyncFunction(ExecutionState& state);

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2021-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "Escargot.h"
#include "GlobalObject.h"
#include "Context.h"
#include "VMInstance.h"
#include "WeakRefObject.h"
#include "NativeFunctionObject.h"
namespace Escargot {
Value builtinWeakRefConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
if (!newTarget.hasValue()) {
ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, ErrorObject::Messages::GlobalObject_ConstructorRequiresNew);
}
if (argc == 0 || !argv[0].isObject()) {
ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, "target is not object");
}
// Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRefPrototype%", « [[WeakRefTarget]] »).
Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* {
return constructorRealm->globalObject()->weakRefPrototype();
});
WeakRefObject* weakRef = new WeakRefObject(state, proto, argv[0].asObject());
return weakRef;
}
Value builtinWeakRefDeRef(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
if (!thisValue.isObject() || !thisValue.asObject()->isWeakRefObject()) {
ErrorObject::throwBuiltinError(state, ErrorObject::TypeError, ErrorObject::Messages::GlobalObject_CalledOnIncompatibleReceiver);
}
// Let weakRef be the this value.
WeakRefObject* weakRef = thisValue.asObject()->asWeakRefObject();
return weakRef->getTarget();
}
void GlobalObject::installWeakRef(ExecutionState& state)
{
m_weakRef = new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().WeakRef, builtinWeakRefConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__);
m_weakRef->setGlobalIntrinsicObject(state);
m_weakRefPrototype = new Object(state, m_objectPrototype);
m_weakRefPrototype->setGlobalIntrinsicObject(state, true);
m_weakRefPrototype->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().constructor), ObjectPropertyDescriptor(m_weakRef, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
m_weakRefPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().deref),
ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(state.context()->staticStrings().deref, builtinWeakRefDeRef, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
// WeakRef.prototype.deref
m_weakRefPrototype->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, Value(state.context()->vmInstance()->globalSymbols().toStringTag)),
ObjectPropertyDescriptor(Value(state.context()->staticStrings().WeakRef.string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent)));
m_weakRef->setFunctionPrototype(state, m_weakRefPrototype);
defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().WeakRef),
ObjectPropertyDescriptor(m_weakRef, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
}
} // namespace Escargot

View file

@ -58,6 +58,7 @@ class IteratorObject;
class MapObject;
class SetObject;
class WeakMapObject;
class WeakRefObject;
class WeakSetObject;
class GeneratorObject;
class AsyncGeneratorObject;
@ -312,6 +313,11 @@ public:
return false;
}
virtual bool isWeakRefObject() const
{
return false;
}
virtual bool isWeakSetObject() const
{
return false;
@ -658,6 +664,12 @@ public:
return (WeakMapObject*)this;
}
WeakRefObject* asWeakRefObject()
{
ASSERT(isWeakRefObject());
return (WeakRefObject*)this;
}
WeakSetObject* asWeakSetObject()
{
ASSERT(isWeakSetObject());

View file

@ -114,6 +114,7 @@ namespace Escargot {
F(Uint8Array) \
F(Uint8ClampedArray) \
F(WeakMap) \
F(WeakRef) \
F(WeakSet) \
F(__defineGetter__) \
F(__defineSetter__) \
@ -182,6 +183,7 @@ namespace Escargot {
F(defineProperties) \
F(defineProperty) \
F(deleteProperty) \
F(deref) \
F(description) \
F(done) \
F(dotAll) \

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2021-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "Escargot.h"
#include "WeakRefObject.h"
#include "ArrayObject.h"
#include "Context.h"
namespace Escargot {
WeakRefObject::WeakRefObject(ExecutionState& state, Object* target)
: WeakRefObject(state, state.context()->globalObject()->weakRefPrototype(), target)
{
}
WeakRefObject::WeakRefObject(ExecutionState& state, Object* proto, Object* target)
: Object(state, proto)
, m_target(target)
{
}
void* WeakRefObject::operator new(size_t size)
{
static bool typeInited = false;
static GC_descr descr;
if (!typeInited) {
GC_word obj_bitmap[GC_BITMAP_SIZE(WeakRefObject)] = { 0 };
Object::fillGCDescriptor(obj_bitmap);
GC_set_bit(obj_bitmap, GC_WORD_OFFSET(WeakRefObject, m_target));
descr = GC_make_descriptor(obj_bitmap, GC_WORD_LEN(WeakRefObject));
typeInited = true;
}
return GC_MALLOC_EXPLICITLY_TYPED(size, descr);
}
bool WeakRefObject::deleteOperation(ExecutionState& state)
{
m_target = nullptr;
return true;
}
} // namespace Escargot

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2021-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef __EscargotWeakRefObject__
#define __EscargotWeakRefObject__
#include "runtime/Object.h"
namespace Escargot {
class WeakRefObject : public Object {
public:
explicit WeakRefObject(ExecutionState& state, Object* target);
explicit WeakRefObject(ExecutionState& state, Object* proto, Object* target);
virtual bool isWeakRefObject() const
{
return true;
}
Value getTarget()
{
if (m_target.hasValue()) {
return m_target.value();
}
return Value();
}
bool deleteOperation(ExecutionState& state);
void* operator new(size_t size);
void* operator new[](size_t size) = delete;
private:
Optional<Object*> m_target;
};
} // namespace Escargot
#endif

View file

@ -851,32 +851,8 @@
<test id="built-ins/TypedArrayConstructors/ctors/buffer-arg/use-default-proto-if-custom-proto-is-not-object-sab"><reason>TODO</reason></test>
<test id="built-ins/TypedArrayConstructors/internals/Get/BigInt/indexed-value-sab"><reason>TODO</reason></test>
<test id="built-ins/TypedArrayConstructors/internals/Get/indexed-value-sab"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/constructor"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/instance-extensible"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/length"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/name"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/newtarget-prototype-is-not-object"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/proto"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/proto-from-ctor-realm"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype-from-newtarget"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype-from-newtarget-abrupt"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype-from-newtarget-custom"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/Symbol.toStringTag"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/constructor"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/deref/custom-this"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/deref/gc-cleanup-not-prevented-with-wr-deref"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/deref/length"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/deref/name"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/deref/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/deref/return-target"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/deref/this-does-not-have-internal-target-throws"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/deref/this-not-object-throws"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/prototype/proto"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/returns-new-object-from-constructor"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/target-not-object-throws"><reason>TODO</reason></test>
<test id="built-ins/WeakRef/undefined-newtarget-throws"><reason>TODO</reason></test>
<test id="intl402/DateTimeFormat/constructor-options-dateStyle-invalid"><reason>TODO</reason></test>
<test id="intl402/DateTimeFormat/constructor-options-dateStyle-valid"><reason>TODO</reason></test>
<test id="intl402/DateTimeFormat/constructor-options-dayPeriod-invalid"><reason>TODO</reason></test>