mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-12-04 09:13:37 +00:00
!3978 Lazy initialization for some builtins interface in workervm
Merge pull request !3978 from lukai/lazyBuiltins
This commit is contained in:
commit
110322f3a3
1
BUILD.gn
1
BUILD.gn
@ -546,6 +546,7 @@ ecma_source = [
|
||||
"ecmascript/builtins/builtins_iterator.cpp",
|
||||
"ecmascript/builtins/builtins_async_iterator.cpp",
|
||||
"ecmascript/builtins/builtins_json.cpp",
|
||||
"ecmascript/builtins/builtins_lazy_callback.cpp",
|
||||
"ecmascript/builtins/builtins_map.cpp",
|
||||
"ecmascript/builtins/builtins_math.cpp",
|
||||
"ecmascript/builtins/builtins_number.cpp",
|
||||
|
@ -123,6 +123,7 @@ using Object = builtins::BuiltinsObject;
|
||||
using Date = builtins::BuiltinsDate;
|
||||
using Symbol = builtins::BuiltinsSymbol;
|
||||
using Boolean = builtins::BuiltinsBoolean;
|
||||
using BuiltinsLazyCallback = builtins::BuiltinsLazyCallback;
|
||||
using BuiltinsMap = builtins::BuiltinsMap;
|
||||
using BuiltinsSet = builtins::BuiltinsSet;
|
||||
using BuiltinsWeakMap = builtins::BuiltinsWeakMap;
|
||||
@ -184,7 +185,7 @@ using SharedArrayBuffer = builtins::BuiltinsSharedArrayBuffer;
|
||||
using BuiltinsAsyncIterator = builtins::BuiltinsAsyncIterator;
|
||||
using AsyncGeneratorObject = builtins::BuiltinsAsyncGenerator;
|
||||
|
||||
void Builtins::Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread)
|
||||
void Builtins::Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread, bool lazyInit)
|
||||
{
|
||||
thread_ = thread;
|
||||
vm_ = thread->GetEcmaVM();
|
||||
@ -202,6 +203,7 @@ void Builtins::Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread)
|
||||
// Object.prototype_or_hclass
|
||||
JSHandle<JSHClass> objFuncClass =
|
||||
factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, objFuncPrototypeVal);
|
||||
env->SetObjectFunctionClass(thread_, objFuncClass);
|
||||
|
||||
// GLobalObject.prototype_or_hclass
|
||||
JSHandle<JSHClass> globalObjFuncClass =
|
||||
@ -274,25 +276,37 @@ void Builtins::Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread)
|
||||
InitializeSymbolWithRealm(env, primRefObjHClass);
|
||||
InitializeBigIntWithRealm(env);
|
||||
}
|
||||
|
||||
InitializeArray(env, objFuncPrototypeVal);
|
||||
if (lazyInit) {
|
||||
LazyInitializeDate(env);
|
||||
LazyInitializeSet(env);
|
||||
LazyInitializeMap(env);
|
||||
LazyInitializeWeakMap(env);
|
||||
LazyInitializeWeakSet(env);
|
||||
LazyInitializeWeakRef(env);
|
||||
LazyInitializeFinalizationRegistry(env);
|
||||
LazyInitializeTypedArray(env);
|
||||
LazyInitializeArrayBuffer(env);
|
||||
LazyInitializeDataView(env);
|
||||
LazyInitializeSharedArrayBuffer(env);
|
||||
} else {
|
||||
InitializeDate(env, objFuncClass);
|
||||
InitializeSet(env, objFuncClass);
|
||||
InitializeMap(env, objFuncClass);
|
||||
InitializeWeakMap(env, objFuncClass);
|
||||
InitializeWeakSet(env, objFuncClass);
|
||||
InitializeWeakRef(env, objFuncClass);
|
||||
InitializeFinalizationRegistry(env, objFuncClass);
|
||||
InitializeTypedArray(env, objFuncClass);
|
||||
InitializeArrayBuffer(env, objFuncClass);
|
||||
InitializeDataView(env, objFuncClass);
|
||||
InitializeSharedArrayBuffer(env, objFuncClass);
|
||||
}
|
||||
InitializeNumber(env, globalObject, primRefObjHClass);
|
||||
InitializeDate(env, objFuncClass);
|
||||
InitializeObject(env, objFuncPrototype, objectFunction);
|
||||
InitializeBoolean(env, primRefObjHClass);
|
||||
|
||||
InitializeRegExp(env);
|
||||
InitializeSet(env, objFuncClass);
|
||||
InitializeMap(env, objFuncClass);
|
||||
InitializeWeakMap(env, objFuncClass);
|
||||
InitializeWeakSet(env, objFuncClass);
|
||||
InitializeWeakRef(env, objFuncClass);
|
||||
InitializeFinalizationRegistry(env, objFuncClass);
|
||||
InitializeArray(env, objFuncPrototypeVal);
|
||||
InitializeTypedArray(env, objFuncClass);
|
||||
InitializeString(env, primRefObjHClass);
|
||||
InitializeArrayBuffer(env, objFuncClass);
|
||||
InitializeDataView(env, objFuncClass);
|
||||
InitializeSharedArrayBuffer(env, objFuncClass);
|
||||
|
||||
JSHandle<JSHClass> argumentsClass = factory_->CreateJSArguments();
|
||||
env->SetArgumentsClass(thread_, argumentsClass);
|
||||
@ -316,14 +330,25 @@ void Builtins::Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread)
|
||||
InitializePromiseJob(env);
|
||||
#ifdef ARK_SUPPORT_INTL
|
||||
InitializeIntl(env, objFuncPrototypeVal);
|
||||
InitializeLocale(env);
|
||||
InitializeDateTimeFormat(env);
|
||||
InitializeNumberFormat(env);
|
||||
InitializeRelativeTimeFormat(env);
|
||||
InitializeCollator(env);
|
||||
InitializePluralRules(env);
|
||||
InitializeDisplayNames(env);
|
||||
InitializeListFormat(env);
|
||||
if (lazyInit) {
|
||||
LazyInitializeLocale(env);
|
||||
LazyInitializeDateTimeFormat(env);
|
||||
LazyInitializeNumberFormat(env);
|
||||
LazyInitializeRelativeTimeFormat(env);
|
||||
LazyInitializeCollator(env);
|
||||
LazyInitializePluralRules(env);
|
||||
LazyInitializeDisplayNames(env);
|
||||
LazyInitializeListFormat(env);
|
||||
} else {
|
||||
InitializeLocale(env);
|
||||
InitializeDateTimeFormat(env);
|
||||
InitializeNumberFormat(env);
|
||||
InitializeRelativeTimeFormat(env);
|
||||
InitializeCollator(env);
|
||||
InitializePluralRules(env);
|
||||
InitializeDisplayNames(env);
|
||||
InitializeListFormat(env);
|
||||
}
|
||||
#endif
|
||||
InitializeModuleNamespace(env, objFuncClass);
|
||||
InitializeCjsModule(env);
|
||||
@ -346,6 +371,14 @@ void Builtins::Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread)
|
||||
env->SetAsyncFunctionClass(thread_, asyncFuncClass);
|
||||
thread_->ResetGuardians();
|
||||
}
|
||||
|
||||
void Builtins::SetLazyAccessor(const JSHandle<JSObject> &object, const JSHandle<JSTaggedValue> &key,
|
||||
const JSHandle<AccessorData> &accessor) const
|
||||
{
|
||||
PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(accessor), true, false, true);
|
||||
JSObject::DefineOwnProperty(thread_, object, key, descriptor);
|
||||
}
|
||||
|
||||
void Builtins::InitializeForSnapshot(JSThread *thread)
|
||||
{
|
||||
thread_ = thread;
|
||||
@ -903,6 +936,16 @@ void Builtins::InitializeDate(const JSHandle<GlobalEnv> &env, const JSHandle<JSH
|
||||
env->SetDateFunction(thread_, dateFunction);
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeDate(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("Date"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::Date));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetDateFunction(thread_, accessor);
|
||||
}
|
||||
|
||||
void Builtins::InitializeBoolean(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &primRefObjHClass) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
@ -1281,6 +1324,16 @@ void Builtins::InitializeSet(const JSHandle<GlobalEnv> &env, const JSHandle<JSHC
|
||||
env->SetBuiltinsSetFunction(thread_, setFunction);
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeSet(const JSHandle<GlobalEnv> &env)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("Set"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::Set));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetBuiltinsSetFunction(thread_, accessor);
|
||||
}
|
||||
|
||||
void Builtins::InitializeMap(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
@ -1346,6 +1399,17 @@ void Builtins::InitializeMap(const JSHandle<GlobalEnv> &env, const JSHandle<JSHC
|
||||
env->SetMapPrototype(thread_, mapFuncPrototype);
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeMap(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("Map"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::Map));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetBuiltinsMapFunction(thread_, accessor);
|
||||
env->SetMapPrototype(thread_, accessor);
|
||||
}
|
||||
|
||||
void Builtins::InitializeWeakMap(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
@ -1382,6 +1446,16 @@ void Builtins::InitializeWeakMap(const JSHandle<GlobalEnv> &env, const JSHandle<
|
||||
env->SetBuiltinsWeakMapFunction(thread_, weakMapFunction);
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeWeakMap(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("WeakMap"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::WeakMap));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetBuiltinsWeakMapFunction(thread_, accessor);
|
||||
}
|
||||
|
||||
void Builtins::InitializeWeakSet(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
@ -1413,6 +1487,16 @@ void Builtins::InitializeWeakSet(const JSHandle<GlobalEnv> &env, const JSHandle<
|
||||
env->SetBuiltinsWeakSetFunction(thread_, weakSetFunction);
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeWeakSet(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("WeakSet"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::WeakSet));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetBuiltinsWeakSetFunction(thread_, accessor);
|
||||
}
|
||||
|
||||
void Builtins::InitializeAtomics(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSTaggedValue> &objFuncPrototypeVal) const
|
||||
{
|
||||
@ -1468,6 +1552,16 @@ void Builtins::InitializeWeakRef(const JSHandle<GlobalEnv> &env, const JSHandle<
|
||||
env->SetBuiltinsWeakRefFunction(thread_, weakRefFunction);
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeWeakRef(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("WeakRef"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::WeakRef));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetBuiltinsWeakRefFunction(thread_, accessor);
|
||||
}
|
||||
|
||||
void Builtins::InitializeFinalizationRegistry(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSHClass> &objFuncClass) const
|
||||
{
|
||||
@ -1502,6 +1596,17 @@ void Builtins::InitializeFinalizationRegistry(const JSHandle<GlobalEnv> &env,
|
||||
env->SetBuiltinsFinalizationRegistryFunction(thread_, finalizationRegistryFunction);
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeFinalizationRegistry(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("FinalizationRegistry"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr,
|
||||
reinterpret_cast<void *>(BuiltinsLazyCallback::FinalizationRegistry));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetBuiltinsFinalizationRegistryFunction(thread_, accessor);
|
||||
}
|
||||
|
||||
void Builtins::InitializeMath(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &objFuncPrototypeVal) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
@ -2134,6 +2239,30 @@ void Builtins::InitializeTypedArray(const JSHandle<GlobalEnv> &env, const JSHand
|
||||
InitializeBigUint64Array(env, typedArrFuncInstanceHClass);
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeTypedArray(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("TypedArray"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr,
|
||||
reinterpret_cast<void *>(BuiltinsLazyCallback::TypedArray));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetTypedArrayFunction(thread_, accessor);
|
||||
env->SetTypedArrayPrototype(thread_, accessor);
|
||||
env->SetSpecificTypedArrayFunctionClass(thread_, accessor);
|
||||
LazyInitializeInt8Array(env);
|
||||
LazyInitializeUint8Array(env);
|
||||
LazyInitializeUint8ClampedArray(env);
|
||||
LazyInitializeInt16Array(env);
|
||||
LazyInitializeUint16Array(env);
|
||||
LazyInitializeInt32Array(env);
|
||||
LazyInitializeUint32Array(env);
|
||||
LazyInitializeFloat32Array(env);
|
||||
LazyInitializeFloat64Array(env);
|
||||
LazyInitializeBigInt64Array(env);
|
||||
LazyInitializeBigUint64Array(env);
|
||||
}
|
||||
|
||||
void Builtins::InitializeInt8Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
@ -2182,6 +2311,20 @@ void Builtins::InitializeUint8Array(const JSHandle<GlobalEnv> &env, const JSHand
|
||||
env->SetUint8ArrayFunction(thread_, uint8ArrayFunction);
|
||||
}
|
||||
|
||||
#define TYPED_ARRAY_LAZY_INITIALIZE(type) \
|
||||
void Builtins::LazyInitialize##type(const JSHandle<GlobalEnv> &env) const \
|
||||
{ \
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_); \
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject()); \
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8(#type)); \
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::type)); \
|
||||
SetLazyAccessor(globalObject, key, accessor); \
|
||||
env->Set##type##Function(thread_, accessor); \
|
||||
}
|
||||
|
||||
ITERATE_TYPED_ARRAY(TYPED_ARRAY_LAZY_INITIALIZE)
|
||||
#undef TYPED_ARRAY_LAZY_INITIALIZE
|
||||
|
||||
void Builtins::InitializeUint8ClampedArray(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSHClass> &objFuncClass) const
|
||||
{
|
||||
@ -2443,6 +2586,17 @@ void Builtins::InitializeArrayBuffer(const JSHandle<GlobalEnv> &env, const JSHan
|
||||
env->SetArrayBufferFunction(thread_, arrayBufferFunction.GetTaggedValue());
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeArrayBuffer(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("ArrayBuffer"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr,
|
||||
reinterpret_cast<void *>(BuiltinsLazyCallback::ArrayBuffer));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetArrayBufferFunction(thread_, accessor);
|
||||
}
|
||||
|
||||
void Builtins::InitializeReflect(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSTaggedValue> &objFuncPrototypeVal) const
|
||||
{
|
||||
@ -2522,6 +2676,16 @@ void Builtins::InitializeSharedArrayBuffer(const JSHandle<GlobalEnv> &env,
|
||||
env->SetSharedArrayBufferFunction(thread_, SharedArrayBufferFunction.GetTaggedValue());
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeSharedArrayBuffer(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("SharedArrayBuffer"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::SharedArrayBuffer));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetSharedArrayBufferFunction(thread_, accessor);
|
||||
}
|
||||
|
||||
void Builtins::InitializePromise(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &promiseFuncClass)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
@ -2686,6 +2850,16 @@ void Builtins::InitializeDataView(const JSHandle<GlobalEnv> &env, const JSHandle
|
||||
env->SetDataViewFunction(thread_, dataViewFunction.GetTaggedValue());
|
||||
}
|
||||
|
||||
void Builtins::LazyInitializeDataView(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8("DataView"));
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr, reinterpret_cast<void *>(BuiltinsLazyCallback::DataView));
|
||||
SetLazyAccessor(globalObject, key, accessor);
|
||||
env->SetDataViewFunction(thread_, accessor);
|
||||
}
|
||||
|
||||
JSHandle<JSFunction> Builtins::NewBuiltinConstructor(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSObject> &prototype, EcmaEntrypoint ctorFunc,
|
||||
const char *name, int length,
|
||||
@ -3085,6 +3259,21 @@ JSHandle<JSFunction> Builtins::NewIntlConstructor(const JSHandle<GlobalEnv> &env
|
||||
return ctor;
|
||||
}
|
||||
|
||||
#define INTL_LAZY_INITIALIZE(type) \
|
||||
void Builtins::LazyInitialize##type(const JSHandle<GlobalEnv> &env) const \
|
||||
{ \
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_); \
|
||||
JSHandle<JSObject> intlObject(env->GetIntlFunction()); \
|
||||
JSHandle<JSTaggedValue> key(factory_->NewFromUtf8(#type)); \
|
||||
auto accessor = factory_->NewInternalAccessor(nullptr, \
|
||||
reinterpret_cast<void *>(BuiltinsLazyCallback::type)); \
|
||||
SetLazyAccessor(intlObject, key, accessor); \
|
||||
env->Set##type##Function(thread_, accessor); \
|
||||
}
|
||||
|
||||
ITERATE_INTL(INTL_LAZY_INITIALIZE)
|
||||
#undef INTL_LAZY_INITIALIZE
|
||||
|
||||
void Builtins::InitializeIntlCtor(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &prototype,
|
||||
const JSHandle<JSFunction> &ctor, const char *name, int length)
|
||||
{
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef ECMASCRIPT_BUILTINS_H
|
||||
#define ECMASCRIPT_BUILTINS_H
|
||||
|
||||
#include "ecmascript/builtins/builtins_lazy_callback.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_handle.h"
|
||||
@ -36,11 +37,13 @@ enum FunctionLength : uint8_t { ZERO = 0, ONE, TWO, THREE, FOUR };
|
||||
class Builtins {
|
||||
public:
|
||||
Builtins() = default;
|
||||
Builtins(JSThread *thread, ObjectFactory *factory, EcmaVM *vm)
|
||||
: thread_(thread), factory_(factory), vm_(vm) {}
|
||||
~Builtins() = default;
|
||||
NO_COPY_SEMANTIC(Builtins);
|
||||
NO_MOVE_SEMANTIC(Builtins);
|
||||
|
||||
void Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread);
|
||||
void Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread, bool lazyInit = false);
|
||||
void InitializeForSnapshot(JSThread *thread);
|
||||
|
||||
private:
|
||||
@ -62,6 +65,9 @@ private:
|
||||
kungfu::BuiltinsStubCSigns::ID builtinId =
|
||||
kungfu::BuiltinsStubCSigns::INVALID) const;
|
||||
|
||||
void SetLazyAccessor(const JSHandle<JSObject> &object, const JSHandle<JSTaggedValue> &key,
|
||||
const JSHandle<AccessorData> &accessor) const;
|
||||
|
||||
void InitializeCtor(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &prototype,
|
||||
const JSHandle<JSFunction> &ctor, const char *name, int length) const;
|
||||
|
||||
@ -80,6 +86,7 @@ private:
|
||||
void InitializeBigIntWithRealm(const JSHandle<GlobalEnv> &realm) const;
|
||||
|
||||
void InitializeDate(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeDate(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeBoolean(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &primRefObjClass) const;
|
||||
|
||||
@ -90,28 +97,40 @@ private:
|
||||
void InitializeArray(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &objFuncPrototypeVal) const;
|
||||
|
||||
void InitializeTypedArray(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeTypedArray(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeInt8Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeInt8Array(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeUint8Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeUint8Array(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeUint8ClampedArray(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeUint8ClampedArray(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeInt16Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeInt16Array(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeUint16Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeUint16Array(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeInt32Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeInt32Array(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeUint32Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeUint32Array(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeFloat32Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeFloat32Array(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeFloat64Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeFloat64Array(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeBigInt64Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeBigInt64Array(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeBigUint64Array(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeBigUint64Array(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeAllTypeError(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
|
||||
@ -139,21 +158,36 @@ private:
|
||||
void InitializeDisplayNames(const JSHandle<GlobalEnv> &env);
|
||||
void InitializeListFormat(const JSHandle<GlobalEnv> &env);
|
||||
|
||||
void LazyInitializeLocale(const JSHandle<GlobalEnv> &env) const;
|
||||
void LazyInitializeDateTimeFormat(const JSHandle<GlobalEnv> &env) const;
|
||||
void LazyInitializeNumberFormat(const JSHandle<GlobalEnv> &env) const;
|
||||
void LazyInitializeRelativeTimeFormat(const JSHandle<GlobalEnv> &env) const;
|
||||
void LazyInitializeCollator(const JSHandle<GlobalEnv> &env) const;
|
||||
void LazyInitializePluralRules(const JSHandle<GlobalEnv> &env) const;
|
||||
void LazyInitializeDisplayNames(const JSHandle<GlobalEnv> &env) const;
|
||||
void LazyInitializeListFormat(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void GeneralUpdateError(ErrorParameter *error, EcmaEntrypoint constructor, EcmaEntrypoint method, const char *name,
|
||||
JSType type) const;
|
||||
|
||||
void InitializeSet(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeSet(const JSHandle<GlobalEnv> &env);
|
||||
|
||||
void InitializeMap(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeMap(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeWeakMap(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeWeakMap(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeWeakSet(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeWeakSet(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeWeakRef(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeWeakRef(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeFinalizationRegistry(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeFinalizationRegistry(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeMath(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &objFuncPrototypeVal) const;
|
||||
|
||||
@ -181,10 +215,13 @@ private:
|
||||
void InitializeArrayIterator(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &iteratorFuncClass) const;
|
||||
|
||||
void InitializeArrayBuffer(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeArrayBuffer(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeSharedArrayBuffer(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeSharedArrayBuffer(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeDataView(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &objFuncClass) const;
|
||||
void LazyInitializeDataView(const JSHandle<GlobalEnv> &env) const;
|
||||
|
||||
void InitializeForPromiseFuncClass(const JSHandle<GlobalEnv> &env);
|
||||
|
||||
@ -269,6 +306,8 @@ private:
|
||||
void SetFrozenFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, const char *key,
|
||||
EcmaEntrypoint func, int length) const;
|
||||
void SetNonConstantObject(const JSHandle<JSObject> &obj, const char *key, JSHandle<JSTaggedValue> &value) const;
|
||||
|
||||
friend class builtins::BuiltinsLazyCallback;
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_BUILTINS_H
|
||||
|
244
ecmascript/builtins/builtins_lazy_callback.cpp
Normal file
244
ecmascript/builtins/builtins_lazy_callback.cpp
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecmascript/builtins/builtins_lazy_callback.h"
|
||||
|
||||
#include "ecmascript/builtins/builtins.h"
|
||||
#include "ecmascript/global_dictionary-inl.h"
|
||||
#include "ecmascript/tagged_dictionary.h"
|
||||
#include "ecmascript/ecma_macros.h"
|
||||
|
||||
namespace panda::ecmascript::builtins {
|
||||
JSTaggedValue BuiltinsLazyCallback::Date(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "Date");
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
Builtins builtin(thread, factory, vm);
|
||||
builtin.InitializeDate(env, objFuncClass);
|
||||
return env->GetDateFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsLazyCallback::Set(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "Set");
|
||||
Builtins builtin(thread, factory, vm);
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
builtin.InitializeSet(env, objFuncClass);
|
||||
return env->GetBuiltinsSetFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsLazyCallback::Map(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "Map");
|
||||
Builtins builtin(thread, factory, vm);
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
builtin.InitializeMap(env, objFuncClass);
|
||||
return env->GetBuiltinsMapFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsLazyCallback::WeakMap(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "WeakMap");
|
||||
Builtins builtin(thread, factory, vm);
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
builtin.InitializeWeakMap(env, objFuncClass);
|
||||
return env->GetBuiltinsWeakMapFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsLazyCallback::WeakSet(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "WeakSet");
|
||||
Builtins builtin(thread, factory, vm);
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
builtin.InitializeWeakSet(env, objFuncClass);
|
||||
return env->GetBuiltinsWeakSetFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsLazyCallback::WeakRef(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "WeakRef");
|
||||
Builtins builtin(thread, factory, vm);
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
builtin.InitializeWeakRef(env, objFuncClass);
|
||||
return env->GetBuiltinsWeakRefFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsLazyCallback::FinalizationRegistry(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "FinalizationRegistry");
|
||||
Builtins builtin(thread, factory, vm);
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
builtin.InitializeFinalizationRegistry(env, objFuncClass);
|
||||
return env->GetBuiltinsFinalizationRegistryFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsLazyCallback::TypedArray(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "TypedArray");
|
||||
|
||||
#define RESET_TYPED_ARRAY_INTERNAL_ATTR(type) \
|
||||
ResetLazyInternalAttr(thread, obj, #type);
|
||||
|
||||
ITERATE_TYPED_ARRAY(RESET_TYPED_ARRAY_INTERNAL_ATTR)
|
||||
#undef RESET_TYPED_ARRAY_INTERNAL_ATTR
|
||||
Builtins builtin(thread, factory, vm);
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
builtin.InitializeTypedArray(env, objFuncClass);
|
||||
return env->GetTypedArrayFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
#define TYPED_ARRAY_CALLBACK(type) \
|
||||
JSTaggedValue BuiltinsLazyCallback::type(JSThread *thread, const JSHandle<JSObject> &obj) \
|
||||
{ \
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread); \
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__; \
|
||||
EcmaVM *vm = thread->GetEcmaVM(); \
|
||||
auto env = vm->GetGlobalEnv(); \
|
||||
TypedArray(thread, obj); \
|
||||
return env->Get##type##Function().GetTaggedValue(); \
|
||||
}
|
||||
|
||||
ITERATE_TYPED_ARRAY(TYPED_ARRAY_CALLBACK)
|
||||
#undef TYPED_ARRAY_CALLBACK
|
||||
|
||||
JSTaggedValue BuiltinsLazyCallback::ArrayBuffer(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "ArrayBuffer");
|
||||
Builtins builtin(thread, factory, vm);
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
builtin.InitializeArrayBuffer(env, objFuncClass);
|
||||
return env->GetArrayBufferFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsLazyCallback::DataView(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "DataView");
|
||||
Builtins builtin(thread, factory, vm);
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
builtin.InitializeDataView(env, objFuncClass);
|
||||
return env->GetDataViewFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsLazyCallback::SharedArrayBuffer(JSThread *thread, const JSHandle<JSObject> &obj)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread);
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__;
|
||||
EcmaVM *vm = thread->GetEcmaVM();
|
||||
ObjectFactory *factory = vm->GetFactory();
|
||||
auto env = vm->GetGlobalEnv();
|
||||
ResetLazyInternalAttr(thread, obj, "SharedArrayBuffer");
|
||||
Builtins builtin(thread, factory, vm);
|
||||
JSHandle<JSHClass> objFuncClass(env->GetObjectFunctionClass());
|
||||
builtin.InitializeSharedArrayBuffer(env, objFuncClass);
|
||||
return env->GetSharedArrayBufferFunction().GetTaggedValue();
|
||||
}
|
||||
|
||||
#ifdef ARK_SUPPORT_INTL
|
||||
#define INTL_CALLBACK(type) \
|
||||
JSTaggedValue BuiltinsLazyCallback::type(JSThread *thread, const JSHandle<JSObject> &obj) \
|
||||
{ \
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread); \
|
||||
LOG_ECMA(DEBUG) << "BuiltinsLazyCallback::" << __func__; \
|
||||
EcmaVM *vm = thread->GetEcmaVM(); \
|
||||
auto env = vm->GetGlobalEnv(); \
|
||||
ObjectFactory *factory = vm->GetFactory(); \
|
||||
ResetLazyInternalAttr(thread, obj, #type); \
|
||||
Builtins builtin(thread, factory, vm); \
|
||||
builtin.Initialize##type(env); \
|
||||
return env->Get##type##Function().GetTaggedValue(); \
|
||||
}
|
||||
|
||||
ITERATE_INTL(INTL_CALLBACK)
|
||||
#undef INTL_CALLBACK
|
||||
#endif
|
||||
|
||||
void BuiltinsLazyCallback::ResetLazyInternalAttr(JSThread *thread, const JSHandle<JSObject> &object,
|
||||
const char *name)
|
||||
{
|
||||
JSHClass *hclass = object->GetClass();
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8(name));
|
||||
if (LIKELY(!hclass->IsDictionaryMode())) {
|
||||
LayoutInfo *layoutInfo = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
|
||||
uint32_t propsNumber = hclass->NumberOfProps();
|
||||
int entry = layoutInfo->FindElementWithCache(thread, hclass, key.GetTaggedValue(), propsNumber);
|
||||
if (entry != -1) {
|
||||
PropertyAttributes attr(layoutInfo->GetAttr(entry));
|
||||
attr.SetIsAccessor(false);
|
||||
layoutInfo->SetNormalAttr(thread, entry, attr);
|
||||
}
|
||||
} else {
|
||||
TaggedArray *array = TaggedArray::Cast(object->GetProperties().GetTaggedObject());
|
||||
ASSERT(array->IsDictionaryMode());
|
||||
NameDictionary *dict = NameDictionary::Cast(array);
|
||||
int entry = dict->FindEntry(key.GetTaggedValue());
|
||||
if (entry != -1) {
|
||||
auto attr = dict->GetAttributes(entry);
|
||||
attr.SetIsAccessor(false);
|
||||
dict->SetAttributes(thread, entry, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript::builtins
|
90
ecmascript/builtins/builtins_lazy_callback.h
Normal file
90
ecmascript/builtins/builtins_lazy_callback.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_BUILTINS_BUILTINS_LAZY_CALLBACK_H
|
||||
#define ECMASCRIPT_BUILTINS_BUILTINS_LAZY_CALLBACK_H
|
||||
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_handle.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define ITERATE_TYPED_ARRAY(V) \
|
||||
V(Int8Array) \
|
||||
V(Uint8Array) \
|
||||
V(Uint8ClampedArray) \
|
||||
V(Int16Array) \
|
||||
V(Uint16Array) \
|
||||
V(Int32Array) \
|
||||
V(Uint32Array) \
|
||||
V(Float32Array) \
|
||||
V(Float64Array) \
|
||||
V(BigInt64Array) \
|
||||
V(BigUint64Array)
|
||||
|
||||
#define ITERATE_INTL(V) \
|
||||
V(Locale) \
|
||||
V(DateTimeFormat) \
|
||||
V(NumberFormat) \
|
||||
V(RelativeTimeFormat) \
|
||||
V(Collator) \
|
||||
V(PluralRules) \
|
||||
V(DisplayNames) \
|
||||
V(ListFormat) \
|
||||
|
||||
namespace panda::ecmascript::builtins {
|
||||
class BuiltinsLazyCallback {
|
||||
public:
|
||||
static JSTaggedValue Date(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Set(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Map(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue WeakMap(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue WeakSet(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue WeakRef(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue FinalizationRegistry(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue TypedArray(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Int8Array(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Uint8Array(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Uint8ClampedArray(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Int16Array(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Uint16Array(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Int32Array(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Uint32Array(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Float32Array(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Float64Array(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue BigInt64Array(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue BigUint64Array(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue ArrayBuffer(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue DataView(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue SharedArrayBuffer(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
#ifdef ARK_SUPPORT_INTL
|
||||
static JSTaggedValue Locale(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue DateTimeFormat(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue NumberFormat(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue RelativeTimeFormat(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue Collator(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue PluralRules(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue DisplayNames(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
static JSTaggedValue ListFormat(JSThread *thread, const JSHandle<JSObject> &obj);
|
||||
#endif
|
||||
|
||||
private:
|
||||
static void ResetLazyInternalAttr(JSThread *thread, const JSHandle<JSObject> &object, const char *key);
|
||||
};
|
||||
} // namespace panda::ecmascript::builtins
|
||||
#endif // ECMASCRIPT_BUILTINS_BUILTINS_LAZY_CALLBACK_H
|
@ -25,6 +25,7 @@ host_unittest_action("BuiltinsInternational_001_Test") {
|
||||
"builtins_collator_test.cpp",
|
||||
"builtins_date_time_format_test.cpp",
|
||||
"builtins_displaynames_test.cpp",
|
||||
"builtins_lazy_test.cpp",
|
||||
]
|
||||
|
||||
configs = [
|
||||
|
374
ecmascript/builtins/tests/builtins_lazy_test.cpp
Normal file
374
ecmascript/builtins/tests/builtins_lazy_test.cpp
Normal file
@ -0,0 +1,374 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecmascript/base/string_helper.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/interpreter/fast_runtime_stub-inl.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/platform/time.h"
|
||||
#include "ecmascript/tests/test_helper.h"
|
||||
|
||||
using namespace panda::ecmascript;
|
||||
|
||||
namespace panda::test {
|
||||
class BuiltinsLazyTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
GTEST_LOG_(INFO) << "SetUpTestCase";
|
||||
}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
GTEST_LOG_(INFO) << "TearDownCase";
|
||||
}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
JSRuntimeOptions options;
|
||||
#if PANDA_TARGET_LINUX
|
||||
// for consistency requirement, use ohos_icu4j/data as icu-data-path
|
||||
options.SetIcuDataPath(ICU_PATH);
|
||||
#endif
|
||||
options.SetIsWorker(true);
|
||||
options.SetEnableBuiltinsLazy(true);
|
||||
options.SetEnableForceGC(true);
|
||||
instance = JSNApi::CreateEcmaVM(options);
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
TestHelper::DestroyEcmaVMWithScope(instance, scope);
|
||||
}
|
||||
|
||||
EcmaVM *instance {nullptr};
|
||||
EcmaHandleScope *scope {nullptr};
|
||||
JSThread *thread {nullptr};
|
||||
};
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, SlowGetOwnProperty)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("Date"));
|
||||
auto globalObj = JSHandle<JSObject>(thread, globalEnv->GetGlobalObject());
|
||||
PropertyDescriptor desc(thread);
|
||||
bool success = JSObject::GetOwnProperty(thread, globalObj, key, desc);
|
||||
ASSERT_TRUE(success);
|
||||
ASSERT_TRUE(desc.GetValue()->IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, SlowSetProperty)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("Date"));
|
||||
auto globalObj = JSHandle<JSTaggedValue>(thread, globalEnv->GetGlobalObject());
|
||||
JSHandle<JSTaggedValue> value(factory->NewFromUtf8("Value"));
|
||||
bool success = JSObject::SetProperty(thread, globalObj, key, value);
|
||||
ASSERT_TRUE(success);
|
||||
PropertyDescriptor desc(thread);
|
||||
JSObject::GetOwnProperty(thread, JSHandle<JSObject>::Cast(globalObj), key, desc);
|
||||
ASSERT_FALSE(desc.IsAccessorDescriptor());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetDateConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> dateFunction = globalEnv->GetDateFunction();
|
||||
ASSERT_TRUE(dateFunction->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("now"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, dateFunction, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetDateConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
auto key = factory->NewFromUtf8("Date");
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto dateFunction = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key.GetTaggedValue());
|
||||
ASSERT_TRUE(dateFunction.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetSetConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> setFunction = globalEnv->GetBuiltinsSetFunction();
|
||||
ASSERT_TRUE(setFunction->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> setObject(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(setFunction),
|
||||
setFunction));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("add"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, setObject, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetSetConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("Set").GetTaggedValue();
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto setFunction = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
|
||||
ASSERT_TRUE(setFunction.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetMapConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> mapFunction = globalEnv->GetBuiltinsMapFunction();
|
||||
ASSERT_TRUE(mapFunction->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> mapObject(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(mapFunction),
|
||||
mapFunction));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("clear"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, mapObject, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetMapConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("Map").GetTaggedValue();
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto mapFunction = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
|
||||
ASSERT_TRUE(mapFunction.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetWeakMapConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> weakMapFunction = globalEnv->GetBuiltinsWeakMapFunction();
|
||||
ASSERT_TRUE(weakMapFunction->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> weakMapObject(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(weakMapFunction),
|
||||
weakMapFunction));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("delete"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, weakMapObject, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetWeakMapConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("WeakMap").GetTaggedValue();
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto weakMapFunction = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
|
||||
ASSERT_TRUE(weakMapFunction.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetWeakSetConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> weakSetFunction = globalEnv->GetBuiltinsWeakSetFunction();
|
||||
ASSERT_TRUE(weakSetFunction->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> weakSetObject(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(weakSetFunction),
|
||||
weakSetFunction));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("delete"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, weakSetObject, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetWeakSetConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("WeakSet").GetTaggedValue();
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto weakSetFunction = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
|
||||
ASSERT_TRUE(weakSetFunction.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetWeakRefConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> weakRefFunction = globalEnv->GetBuiltinsWeakRefFunction();
|
||||
ASSERT_TRUE(weakRefFunction->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> weakRefObject(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(weakRefFunction),
|
||||
weakRefFunction));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("deref"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, weakRefObject, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetWeakRefConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("WeakRef").GetTaggedValue();
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto weakRefFunction = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
|
||||
ASSERT_TRUE(weakRefFunction.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetFinalizationRegistryConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> function = globalEnv->GetBuiltinsFinalizationRegistryFunction();
|
||||
ASSERT_TRUE(function->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("register"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, object, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetFinalizationRegistryConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("FinalizationRegistry").GetTaggedValue();
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto function = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
|
||||
ASSERT_TRUE(function.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetInt8ArrayConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> function = globalEnv->GetInt8ArrayFunction();
|
||||
ASSERT_TRUE(function->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("BYTES_PER_ELEMENT"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, object, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetInt8ArrayConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("Int8Array").GetTaggedValue();
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto function = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
|
||||
ASSERT_TRUE(function.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetArrayBufferConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> function = globalEnv->GetArrayBufferFunction();
|
||||
ASSERT_TRUE(function->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("slice"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, object, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetArrayBufferConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("ArrayBuffer").GetTaggedValue();
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto function = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
|
||||
ASSERT_TRUE(function.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetDataViewConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> function = globalEnv->GetDataViewFunction();
|
||||
ASSERT_TRUE(function->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("getFloat32"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, object, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetDataViewConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("DataView").GetTaggedValue();
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto function = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
|
||||
ASSERT_TRUE(function.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetSharedArrayBufferConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> function = globalEnv->GetSharedArrayBufferFunction();
|
||||
ASSERT_TRUE(function->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("slice"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, object, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, GlobalGetSharedArrayBufferConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("SharedArrayBuffer").GetTaggedValue();
|
||||
auto globalObj = globalEnv->GetGlobalObject();
|
||||
auto function = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
|
||||
ASSERT_TRUE(function.IsJSFunction());
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, EnvGetLocaleConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
JSHandle<JSTaggedValue> function = globalEnv->GetLocaleFunction();
|
||||
ASSERT_TRUE(function->IsJSFunction());
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function));
|
||||
JSHandle<JSTaggedValue> key(factory->NewFromUtf8("maximize"));
|
||||
ASSERT_TRUE(JSTaggedValue::HasProperty(thread, object, key));
|
||||
}
|
||||
|
||||
HWTEST_F_L0(BuiltinsLazyTest, IntlGetLocaleFunctionConstructorTest)
|
||||
{
|
||||
EcmaVM *ecmaVM = thread->GetEcmaVM();
|
||||
JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
|
||||
ObjectFactory *factory = ecmaVM->GetFactory();
|
||||
JSTaggedValue key = factory->NewFromUtf8("Locale").GetTaggedValue();
|
||||
auto intlObj = globalEnv->GetIntlFunction().GetTaggedValue();
|
||||
auto function = FastRuntimeStub::GetPropertyByName(thread, intlObj, key);
|
||||
ASSERT_TRUE(function.IsJSFunction());
|
||||
}
|
||||
} // namespace panda::test
|
@ -220,7 +220,8 @@ bool EcmaVM::Initialize()
|
||||
globalEnv_ = globalEnv.GetTaggedValue();
|
||||
thread_->SetGlueGlobalEnv(reinterpret_cast<GlobalEnv *>(globalEnv.GetTaggedType()));
|
||||
Builtins builtins;
|
||||
builtins.Initialize(globalEnv, thread_);
|
||||
bool builtinsLazyEnabled = options_.IsWorker() && options_.GetEnableBuiltinsLazy();
|
||||
builtins.Initialize(globalEnv, thread_, builtinsLazyEnabled);
|
||||
if (!WIN_OR_MAC_OR_IOS_PLATFORM && options_.EnableSnapshotSerialize()) {
|
||||
const CString fileName = "builtins.snapshot";
|
||||
Snapshot snapshot(this);
|
||||
|
@ -29,6 +29,7 @@ class JSThread;
|
||||
#define GLOBAL_ENV_FIELDS(V) \
|
||||
/* Function */ \
|
||||
V(JSTaggedValue, ObjectFunction, OBJECT_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, ObjectFunctionClass, OBJECT_FUNCTION_CLASS_INDEX) \
|
||||
V(JSTaggedValue, ObjectFunctionPrototype, OBJECT_FUNCTION_PROTOTYPE_INDEX) \
|
||||
V(JSTaggedValue, ObjectFunctionPrototypeClass, OBJECT_FUNCTION_PROTOTYPE_CLASS_INDEX) \
|
||||
V(JSTaggedValue, FunctionFunction, FUNCTION_FUNCTION_INDEX) \
|
||||
@ -231,12 +232,23 @@ public:
|
||||
const uintptr_t address = \
|
||||
reinterpret_cast<uintptr_t>(this) + HEADER_SIZE + index * JSTaggedValue::TaggedTypeSize(); \
|
||||
JSHandle<type> result(address); \
|
||||
if (result.GetTaggedValue().IsInternalAccessor()) { \
|
||||
JSThread *thread = GetJSThread(); \
|
||||
AccessorData *accessor = AccessorData::Cast(result.GetTaggedValue().GetTaggedObject()); \
|
||||
accessor->CallInternalGet(thread, JSHandle<JSObject>::Cast(GetJSGlobalObject())); \
|
||||
} \
|
||||
return result; \
|
||||
} \
|
||||
inline JSTaggedValue GetTagged##name() const \
|
||||
{ \
|
||||
uint32_t offset = HEADER_SIZE + index * JSTaggedValue::TaggedTypeSize(); \
|
||||
return JSTaggedValue(Barriers::GetValue<JSTaggedType>(this, offset)); \
|
||||
JSTaggedValue result(Barriers::GetValue<JSTaggedType>(this, offset)); \
|
||||
if (result.IsInternalAccessor()) { \
|
||||
JSThread *thread = GetJSThread(); \
|
||||
AccessorData *accessor = AccessorData::Cast(result.GetTaggedObject()); \
|
||||
accessor->CallInternalGet(thread, JSHandle<JSObject>::Cast(GetJSGlobalObject())); \
|
||||
} \
|
||||
return result; \
|
||||
} \
|
||||
template<typename T> \
|
||||
inline void Set##name(const JSThread *thread, JSHandle<T> value, BarrierMode mode = WRITE_BARRIER) \
|
||||
|
@ -167,6 +167,9 @@ JSTaggedValue LoadICRuntime::LoadMiss(JSHandle<JSTaggedValue> receiver, JSHandle
|
||||
|
||||
ObjectOperator op(GetThread(), receiver, key);
|
||||
auto result = JSHandle<JSTaggedValue>(thread_, JSObject::GetProperty(GetThread(), &op));
|
||||
if (op.GetValue().IsInternalAccessor()) {
|
||||
op = ObjectOperator(GetThread(), receiver, key);
|
||||
}
|
||||
if (!op.IsFound() && kind == ICKind::NamedGlobalTryLoadIC) {
|
||||
return SlowRuntimeStub::ThrowReferenceError(GetThread(), key.GetTaggedValue(), " is not defined");
|
||||
}
|
||||
|
@ -2638,13 +2638,16 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t
|
||||
RESTORE_ACC();
|
||||
} else {
|
||||
// 2. find from global object
|
||||
SAVE_ACC();
|
||||
auto globalResult = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, propKey);
|
||||
if (globalResult.IsHole()) {
|
||||
auto result = SlowRuntimeStub::ThrowReferenceError(thread, propKey, " is not defined");
|
||||
INTERPRETER_RETURN_IF_ABRUPT(result);
|
||||
}
|
||||
constpool = GetConstantPool(sp); // Maybe moved by GC
|
||||
propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
|
||||
RESTORE_ACC();
|
||||
JSTaggedValue value = GET_ACC();
|
||||
SAVE_ACC();
|
||||
JSTaggedValue res = SlowRuntimeStub::StGlobalVar(thread, propKey, value);
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
RESTORE_ACC();
|
||||
@ -6384,13 +6387,16 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t
|
||||
RESTORE_ACC();
|
||||
} else {
|
||||
// 2. find from global object
|
||||
SAVE_ACC();
|
||||
auto globalResult = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, propKey);
|
||||
if (globalResult.IsHole()) {
|
||||
auto result = SlowRuntimeStub::ThrowReferenceError(thread, propKey, " is not defined");
|
||||
INTERPRETER_RETURN_IF_ABRUPT(result);
|
||||
}
|
||||
constpool = GetConstantPool(sp); // Maybe moved by GC
|
||||
propKey = GET_STR_FROM_CACHE(stringId); // Maybe moved by GC
|
||||
RESTORE_ACC();
|
||||
JSTaggedValue value = GET_ACC();
|
||||
SAVE_ACC();
|
||||
JSTaggedValue res = SlowRuntimeStub::StGlobalVar(thread, propKey, value);
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
RESTORE_ACC();
|
||||
|
@ -46,6 +46,7 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
|
||||
"--asm-opcode-disable-range: Opcode range when asm interpreter is enabled.\n"
|
||||
"--compiler-assert-types: Enable type assertion for type inference tests. Default: 'false'\n"
|
||||
"--builtins-dts: Builtins.d.abc file path for AOT.\n"
|
||||
"--builtins-lazy: Load some builtins function later.This option is only valid in workervm.\n"
|
||||
"--compiler-log: Log Option For aot compiler and stub compiler,\n"
|
||||
" 'none': no log,\n"
|
||||
" 'allllircirasm' or 'all012': print all log for all methods,\n"
|
||||
@ -143,6 +144,7 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
{"asm-opcode-disable-range", required_argument, nullptr, OPTION_ASM_OPCODE_DISABLE_RANGE},
|
||||
{"compiler-assert-types", required_argument, nullptr, OPTION_COMPILER_ASSERT_TYPES},
|
||||
{"builtins-dts", required_argument, nullptr, OPTION_BUILTINS_DTS},
|
||||
{"builtins-lazy", required_argument, nullptr, OPTION_ENABLE_BUILTINS_LAZY},
|
||||
{"compiler-log", required_argument, nullptr, OPTION_COMPILER_LOG_OPT},
|
||||
{"compiler-log-methods", required_argument, nullptr, OPTION_COMPILER_LOG_METHODS},
|
||||
{"compiler-log-snapshot", required_argument, nullptr, OPTION_COMPILER_LOG_SNAPSHOT},
|
||||
@ -276,6 +278,14 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
case OPTION_BUILTINS_DTS:
|
||||
SetBuiltinsDTS(optarg);
|
||||
break;
|
||||
case OPTION_ENABLE_BUILTINS_LAZY:
|
||||
ret = ParseBoolParam(&argBool);
|
||||
if (ret) {
|
||||
SetEnableBuiltinsLazy(argBool);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case OPTION_COMPILER_LOG_OPT:
|
||||
SetCompilerLogOption(optarg);
|
||||
break;
|
||||
|
@ -75,6 +75,7 @@ enum CommandValues {
|
||||
OPTION_RELOCATION_MODE,
|
||||
OPTION_MAX_UNMOVABLE_SPACE,
|
||||
OPTION_ENABLE_ASM_INTERPRETER,
|
||||
OPTION_ENABLE_BUILTINS_LAZY,
|
||||
OPTION_ASM_OPCODE_DISABLE_RANGE,
|
||||
OPTION_SERIALIZER_BUFFER_SIZE_LIMIT,
|
||||
OPTION_HEAP_SIZE_LIMIT,
|
||||
@ -434,6 +435,16 @@ public:
|
||||
return enableAsmInterpreter_;
|
||||
}
|
||||
|
||||
void SetEnableBuiltinsLazy(bool value)
|
||||
{
|
||||
enableBuiltinsLazy_ = value;
|
||||
}
|
||||
|
||||
bool GetEnableBuiltinsLazy() const
|
||||
{
|
||||
return enableBuiltinsLazy_;
|
||||
}
|
||||
|
||||
void SetAsmOpcodeDisableRange(std::string value)
|
||||
{
|
||||
asmOpcodeDisableRange_ = std::move(value);
|
||||
@ -1038,6 +1049,7 @@ private:
|
||||
uint32_t relocationMode_ {2}; // 2: default relocation mode
|
||||
uint32_t maxNonmovableSpaceCapacity_ {4_MB};
|
||||
bool enableAsmInterpreter_ {true};
|
||||
bool enableBuiltinsLazy_ {true};
|
||||
std::string asmOpcodeDisableRange_ {""};
|
||||
AsmInterParsedOption asmInterParsedOption_;
|
||||
uint64_t serializerBufferSizeLimit_ {2_GB};
|
||||
|
@ -1007,6 +1007,11 @@ public:
|
||||
enableAsmInterpreter_ = value;
|
||||
}
|
||||
|
||||
void SetEnableBuiltinsLazy(bool value)
|
||||
{
|
||||
enableBuiltinsLazy_ = value;
|
||||
}
|
||||
|
||||
void SetAsmOpcodeDisableRange(const std::string &value)
|
||||
{
|
||||
asmOpcodeDisableRange_ = value;
|
||||
@ -1123,6 +1128,11 @@ private:
|
||||
return enableAsmInterpreter_;
|
||||
}
|
||||
|
||||
bool GetEnableBuiltinsLazy() const
|
||||
{
|
||||
return enableBuiltinsLazy_;
|
||||
}
|
||||
|
||||
std::string GetAsmOpcodeDisableRange() const
|
||||
{
|
||||
return asmOpcodeDisableRange_;
|
||||
@ -1165,6 +1175,7 @@ private:
|
||||
size_t gcThreadNum_ {DEFAULT_GC_THREAD_NUM};
|
||||
size_t longPauseTime_ {DEFAULT_LONG_PAUSE_TIME};
|
||||
bool enableAsmInterpreter_ {true};
|
||||
bool enableBuiltinsLazy_ {true};
|
||||
bool isWorker_ {false};
|
||||
std::string asmOpcodeDisableRange_ {""};
|
||||
std::string bundleName_ {};
|
||||
|
@ -199,6 +199,7 @@ EcmaVM *JSNApi::CreateJSVM(const RuntimeOption &option)
|
||||
#else
|
||||
runtimeOptions.SetEnableAsmInterpreter(false);
|
||||
#endif
|
||||
runtimeOptions.SetEnableBuiltinsLazy(option.GetEnableBuiltinsLazy());
|
||||
runtimeOptions.SetAsmOpcodeDisableRange(option.GetAsmOpcodeDisableRange());
|
||||
// aot
|
||||
runtimeOptions.SetEnableAOT(option.GetEnableAOT());
|
||||
|
@ -225,7 +225,8 @@ void ObjectOperator::ToPropertyDescriptor(PropertyDescriptor &desc) const
|
||||
desc.SetValue(JSHandle<JSTaggedValue>(thread_, val));
|
||||
} else {
|
||||
auto result = GetValue();
|
||||
if (result.IsPropertyBox()) {
|
||||
bool isPropertyBox = result.IsPropertyBox();
|
||||
if (isPropertyBox) {
|
||||
result = PropertyBox::Cast(result.GetTaggedObject())->GetValue();
|
||||
}
|
||||
AccessorData *accessor = AccessorData::Cast(result.GetTaggedObject());
|
||||
@ -233,7 +234,13 @@ void ObjectOperator::ToPropertyDescriptor(PropertyDescriptor &desc) const
|
||||
if (UNLIKELY(accessor->IsInternal())) {
|
||||
desc.SetWritable(IsWritable());
|
||||
auto val = accessor->CallInternalGet(thread_, JSHandle<JSObject>::Cast(GetHolder()));
|
||||
desc.SetValue(JSHandle<JSTaggedValue>(thread_, val));
|
||||
JSMutableHandle<JSTaggedValue> value(thread_, val);
|
||||
if (isPropertyBox) {
|
||||
JSHandle<PropertyBox> cell(value_);
|
||||
cell->SetValue(thread_, val);
|
||||
value.Update(cell);
|
||||
}
|
||||
desc.SetValue(value);
|
||||
} else {
|
||||
desc.SetGetter(JSHandle<JSTaggedValue>(thread_, accessor->GetGetter()));
|
||||
desc.SetSetter(JSHandle<JSTaggedValue>(thread_, accessor->GetSetter()));
|
||||
@ -443,6 +450,11 @@ bool ObjectOperator::UpdateDataValue(const JSHandle<JSObject> &receiver, const J
|
||||
if (receiver->IsJSGlobalObject()) {
|
||||
// need update cell type ?
|
||||
auto *dict = GlobalDictionary::Cast(receiver->GetProperties().GetTaggedObject());
|
||||
if (isInternalAccessor && !value->IsAccessor()) {
|
||||
PropertyAttributes attr = dict->GetAttributes(GetIndex());
|
||||
attr.SetIsAccessor(false);
|
||||
dict->SetAttributes(thread_, GetIndex(), attr);
|
||||
}
|
||||
PropertyBox *cell = dict->GetBox(GetIndex());
|
||||
cell->SetValue(thread_, value.GetTaggedValue());
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user