实现接口:BuiltinsObject::GetOwnPropertyDescriptors

Signed-off-by: 杨云飞 <yangyunfei19@h-partners.com>
This commit is contained in:
杨云飞 2024-02-01 14:25:26 +08:00
parent 0cbcaa60e0
commit 9d510ac7d0
6 changed files with 74 additions and 2 deletions

View File

@ -392,6 +392,55 @@ JSTaggedValue BuiltinsObject::GetOwnPropertyDescriptor(EcmaRuntimeCallInfo *argv
return res.GetTaggedValue();
}
JSTaggedValue BuiltinsObject::GetOwnPropertyDescriptors(EcmaRuntimeCallInfo *argv)
{
ASSERT(argv);
JSThread *thread = argv->GetThread();
BUILTINS_API_TRACE(thread, Object, GetOwnPropertyDescriptors);
[[maybe_unused]] EcmaHandleScope handleScope(thread);
// 1.Let obj be ToObject(O).
JSHandle<JSTaggedValue> func = GetCallArg(argv, 0);
JSHandle<JSObject> handle = JSTaggedValue::ToObject(thread, func);
// 2.ReturnIfAbrupt(obj).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
// 3. Let ownKeys be ? obj.[[OwnPropertyKeys]]().
JSHandle<TaggedArray> ownKeys =
JSTaggedValue::GetOwnPropertyKeys(thread, JSHandle<JSTaggedValue>(handle));
// 4.ReturnIfAbrupt(ownKeys).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
// 5.Let descriptors be OrdinaryObjectCreate(%Object.prototype%).
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
JSHandle<JSFunction> constructor(env->GetObjectFunction());
JSHandle<JSObject> descriptors = factory->NewJSObjectByConstructor(constructor);
// 6.For each element key of ownKeys, do
// a. Let desc be ? obj.[[GetOwnProperty]](key).
// b. Let descriptor be FromPropertyDescriptor(desc).
// c. If descriptor is not undefined, perform ! CreateDataPropertyOrThrow(descriptors, key, descriptor).
uint32_t length = ownKeys->GetLength();
JSMutableHandle<JSTaggedValue> handleKey(thread, JSTaggedValue::Undefined());
for (uint32_t i = 0; i < length; ++i) {
handleKey.Update(ownKeys->Get(i));
PropertyDescriptor desc(thread);
JSTaggedValue::GetOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(handle), handleKey, desc);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSTaggedValue> descriptor = JSObject::FromPropertyDescriptor(thread, desc);
if (!descriptor->IsUndefined()) {
JSObject::CreateDataPropertyOrThrow(thread, descriptors, handleKey, descriptor);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
}
}
// 7.Return descriptors.
return descriptors.GetTaggedValue();
}
// Runtime Semantics
JSTaggedValue BuiltinsObject::GetOwnPropertyKeys(JSThread *thread, const JSHandle<JSTaggedValue> &object,
const KeyType &type)

View File

@ -25,8 +25,7 @@
// V(name, func, length, stubIndex)
// where BuiltinsObject::func refers to the native implementation of Object[name].
// kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available.
// The following functions are not implemented yet:
// - Object.getOwnPropertyDescriptors ( O )
#define BUILTIN_OBJECT_FUNCTIONS(V) \
/* Object.assign ( target, ...sources ) */ \
V("assign", Assign, 2, ObjectAssign) \
@ -44,6 +43,8 @@
V("fromEntries", FromEntries, 1, INVALID) \
/* Object.getOwnPropertyDescriptor ( O, P ) */ \
V("getOwnPropertyDescriptor", GetOwnPropertyDescriptor, 2, INVALID) \
/* Object.getOwnPropertyDescriptors ( O ) */ \
V("getOwnPropertyDescriptors", GetOwnPropertyDescriptors, 1, INVALID) \
/* Object.getOwnPropertyNames ( O ) */ \
V("getOwnPropertyNames", GetOwnPropertyNames, 1, INVALID) \
/* Object.getOwnPropertySymbols ( O ) */ \
@ -136,6 +137,8 @@ public:
static JSTaggedValue Seal(EcmaRuntimeCallInfo *argv);
// 19.1.2.18 Object.setPrototypeOf(O, proto)
static JSTaggedValue SetPrototypeOf(EcmaRuntimeCallInfo *argv);
static JSTaggedValue GetOwnPropertyDescriptors(EcmaRuntimeCallInfo *argv);
// 19.1.3.2 Object.prototype.hasOwnProperty(V)
static JSTaggedValue HasOwnProperty(EcmaRuntimeCallInfo *argv);

View File

@ -586,6 +586,7 @@ namespace panda::ecmascript {
V(Object, Freeze) \
V(Object, FromEntries) \
V(Object, GetOwnPropertyDescriptor) \
V(Object, GetOwnPropertyDescriptors) \
V(Object, GetOwnPropertyKeys) \
V(Object, GetOwnPropertyNames) \
V(Object, GetOwnPropertySymbols) \

View File

@ -307,6 +307,7 @@ static uintptr_t g_nativeTable[] = {
reinterpret_cast<uintptr_t>(Object::DefineProperty),
reinterpret_cast<uintptr_t>(Object::Freeze),
reinterpret_cast<uintptr_t>(Object::GetOwnPropertyDescriptor),
reinterpret_cast<uintptr_t>(Object::GetOwnPropertyDescriptors),
reinterpret_cast<uintptr_t>(Object::GetOwnPropertyNames),
reinterpret_cast<uintptr_t>(Object::GetOwnPropertySymbols),
reinterpret_cast<uintptr_t>(Object::GetPrototypeOf),

View File

@ -15,3 +15,7 @@ true
true
true
true
true
true
true
[object Object]

View File

@ -23,3 +23,17 @@ print(g.__proto__.constructor == FakeGeneratorFunctionConstructor);
function FakeGeneratorObjectConstructor() {}
Object.defineProperty(g.prototype.__proto__, "constructor", {value: FakeGeneratorObjectConstructor});
print(g.prototype.__proto__.constructor == FakeGeneratorObjectConstructor);
const obj = {
name: '小明',
age: 20,
get fullName() {
return this.name;
}
};
const descriptors = Object.getOwnPropertyDescriptors(obj);
print(descriptors.name.value === '小明');
print(descriptors.age.value === 20);
print(typeof descriptors.fullName.get === 'function');
print(descriptors);