Fix napi_define_sendable_class

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I9AUU2?from=project-issue
Signed-off-by: liu-zelin <liuzelin8@huawei.com>
Change-Id: Id3bdb9f5dd975dc0243f8a12f82c94f86043fe46
This commit is contained in:
liu-zelin 2024-03-22 20:02:22 +08:00
parent becdd90295
commit 89c0b1061f
17 changed files with 455 additions and 251 deletions

View File

@ -745,6 +745,7 @@ ecma_source = [
"ecmascript/js_iterator.cpp",
"ecmascript/js_map.cpp",
"ecmascript/js_map_iterator.cpp",
"ecmascript/jsnapi_sendable.cpp",
"ecmascript/method.cpp",
"ecmascript/js_object.cpp",
"ecmascript/js_primitive_ref.cpp",

View File

@ -491,6 +491,22 @@ void EcmaVM::ProcessNativeDelete(const WeakRootVisitor &visitor)
}
}
void EcmaVM::ProcessSharedNativeDelete(const WeakRootVisitor &visitor)
{
auto sharedIter = sharedNativePointerList_.begin();
while (sharedIter != sharedNativePointerList_.end()) {
JSNativePointer *object = *sharedIter;
auto fwd = visitor(reinterpret_cast<TaggedObject *>(object));
if (fwd == nullptr) {
sharedNativePointerCallbacks_.emplace_back(
std::make_pair(object->GetDeleter(), std::make_pair(object->GetExternalPointer(), object->GetData())));
sharedIter = sharedNativePointerList_.erase(sharedIter);
} else {
++sharedIter;
}
}
}
void EcmaVM::ProcessReferences(const WeakRootVisitor &visitor)
{
if (thread_->GetCurrentEcmaContext()->GetRegExpParserCache() != nullptr) {
@ -549,6 +565,12 @@ void EcmaVM::PushToNativePointerList(JSNativePointer *pointer, Concurrent isConc
}
}
void EcmaVM::PushToSharedNativePointerList(JSNativePointer *pointer)
{
ASSERT(JSTaggedValue(pointer).IsInSharedHeap());
sharedNativePointerList_.emplace_back(pointer);
}
void EcmaVM::RemoveFromNativePointerList(JSNativePointer *pointer)
{
auto iter = std::find(nativePointerList_.begin(), nativePointerList_.end(), pointer);

View File

@ -246,6 +246,9 @@ public:
void ProcessNativeDelete(const WeakRootVisitor &visitor);
void ProcessReferences(const WeakRootVisitor &visitor);
void PushToSharedNativePointerList(JSNativePointer *pointer);
void ProcessSharedNativeDelete(const WeakRootVisitor &visitor);
SnapshotEnv *GetSnapshotEnv() const
{
return snapshotEnv_;
@ -335,7 +338,7 @@ public:
{
return resolveBufferCallback_;
}
void SetSearchHapPathCallBack(SearchHapPathCallBack cb)
{
SearchHapPathCallBack_ = cb;
@ -623,6 +626,11 @@ public:
}
static void InitializeIcuData(const JSRuntimeOptions &options);
std::vector<std::pair<DeleteEntryPoint, std::pair<void *, void *>>> &GetSharedNativePointerCallbacks()
{
return sharedNativePointerCallbacks_;
}
protected:
void PrintJSErrorInfo(const JSHandle<JSTaggedValue> &exceptionInfo) const;
@ -653,6 +661,8 @@ private:
CList<JSNativePointer *> nativePointerList_;
CList<JSNativePointer *> concurrentNativePointerList_;
std::vector<std::pair<DeleteEntryPoint, std::pair<void *, void *>>> nativePointerCallbacks_ {};
CList<JSNativePointer *> sharedNativePointerList_;
std::vector<std::pair<DeleteEntryPoint, std::pair<void *, void *>>> sharedNativePointerCallbacks_ {};
// VM execution states.
JSThread *thread_ {nullptr};

View File

@ -1326,4 +1326,97 @@ PropertyLookupResult JSHClass::LookupPropertyInBuiltinHClass(const JSThread *thr
result.SetIsFound(false);
return result;
}
JSHandle<JSHClass> JSHClass::CreateSHClass(JSThread *thread,
const std::vector<PropertyDescriptor> &descs,
bool isFunction)
{
EcmaVM *vm = thread->GetEcmaVM();
ObjectFactory *factory = vm->GetFactory();
uint32_t length = descs.size();
uint32_t maxInline = isFunction ? JSSharedFunction::MAX_INLINE : JSSharedObject::MAX_INLINE;
JSHandle<JSHClass> hclass =
isFunction ? factory->NewSEcmaHClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION, length)
: factory->NewSEcmaHClass(JSSharedObject::SIZE, JSType::JS_SHARED_OBJECT, length);
if (LIKELY(length <= maxInline)) {
auto layout = CreateSInlinedLayout(thread, descs);
hclass->SetLayout(thread, layout);
hclass->SetNumberOfProps(length);
} else {
auto layout = CreateSDictLayout(thread, descs);
hclass->SetLayout(thread, layout);
hclass->SetNumberOfProps(0);
hclass->SetIsDictionaryMode(true);
}
return hclass;
}
JSHandle<JSHClass> JSHClass::CreateSConstructorHClass(JSThread *thread, const std::vector<PropertyDescriptor> &descs)
{
auto hclass = CreateSHClass(thread, descs, true);
hclass->SetClassConstructor(true);
hclass->SetConstructor(true);
return hclass;
}
JSHandle<JSHClass> JSHClass::CreateSPrototypeHClass(JSThread *thread, const std::vector<PropertyDescriptor> &descs)
{
auto hclass = CreateSHClass(thread, descs);
hclass->SetClassPrototype(true);
hclass->SetIsPrototype(true);
return hclass;
}
JSHandle<LayoutInfo> JSHClass::CreateSInlinedLayout(JSThread *thread, const std::vector<PropertyDescriptor> &descs)
{
EcmaVM *vm = thread->GetEcmaVM();
ObjectFactory *factory = vm->GetFactory();
auto length = descs.size();
auto layout = factory->CreateSLayoutInfo(length);
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
for (uint32_t i = 0; i < length; ++i) {
key.Update(descs[i].GetKey());
PropertyAttributes attr =
PropertyAttributes::Default(descs[i].IsWritable(), descs[i].IsEnumerable(), descs[i].IsConfigurable());
if (UNLIKELY(descs[i].GetValue()->IsAccessor())) {
attr.SetIsAccessor(true);
}
attr.SetIsInlinedProps(true);
attr.SetRepresentation(Representation::TAGGED);
attr.SetSharedFieldType(descs[i].GetSharedFieldType());
attr.SetOffset(i);
layout->AddKey(thread, i, key.GetTaggedValue(), attr);
}
return layout;
}
JSHandle<NameDictionary> JSHClass::CreateSDictLayout(JSThread *thread, const std::vector<PropertyDescriptor> &descs)
{
auto length = descs.size();
JSMutableHandle<NameDictionary> dict(
thread, NameDictionary::CreateInSharedHeap(thread, NameDictionary::ComputeHashTableSize(length)));
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
JSHandle<JSTaggedValue> value = globalConst->GetHandledUndefined();
for (uint32_t i = 0; i < length; ++i) {
key.Update(descs[i].GetKey());
PropertyAttributes attr =
PropertyAttributes::Default(descs[i].IsWritable(), descs[i].IsEnumerable(), descs[i].IsConfigurable());
attr.SetSharedFieldType(descs[i].GetSharedFieldType());
attr.SetBoxType(PropertyBoxType::UNDEFINED);
JSHandle<NameDictionary> newDict = NameDictionary::Put(thread, dict, key, value, attr);
dict.Update(newDict);
}
return dict;
}
} // namespace panda::ecmascript

View File

@ -64,6 +64,8 @@ class ProtoChangeDetails;
class PropertyLookupResult;
class SharedHeap;
class JSSharedArray;
class LayoutInfo;
class NameDictionary;
namespace pgo {
class HClassLayoutDesc;
class PGOHClassTreeDesc;
@ -1919,7 +1921,15 @@ public:
DECL_VISIT_OBJECT(PROTOTYPE_OFFSET, BIT_FIELD_OFFSET);
inline JSHClass *FindProtoTransitions(const JSTaggedValue &key, const JSTaggedValue &proto);
static JSHandle<JSHClass> CreateSHClass(JSThread *thread,
const std::vector<PropertyDescriptor> &descs,
bool isFunction = false);
static JSHandle<JSHClass> CreateSConstructorHClass(JSThread *thread, const std::vector<PropertyDescriptor> &descs);
static JSHandle<JSHClass> CreateSPrototypeHClass(JSThread *thread, const std::vector<PropertyDescriptor> &descs);
private:
static JSHandle<LayoutInfo> CreateSInlinedLayout(JSThread *thread, const std::vector<PropertyDescriptor> &descs);
static JSHandle<NameDictionary> CreateSDictLayout(JSThread *thread, const std::vector<PropertyDescriptor> &descs);
static inline void AddTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key,
PropertyAttributes attr);

View File

@ -333,6 +333,41 @@ void JSObject::OptimizeAsFastProperties(const JSThread *thread, JSHandle<JSObjec
obj->SetProperties(thread, array);
}
void JSObject::SetSProperties(JSThread *thread,
JSHandle<JSObject> obj,
JSHandle<JSHClass> hclass,
const std::vector<PropertyDescriptor> &descs)
{
uint32_t length = descs.size();
JSMutableHandle<JSTaggedValue> propKey(thread, JSTaggedValue::Undefined());
JSMutableHandle<JSTaggedValue> propValue(thread, JSTaggedValue::Undefined());
if (LIKELY(!hclass->IsDictionaryMode())) {
for (uint32_t i = 0; i < length; ++i) {
propValue.Update(descs[i].GetValue());
// note(lzl): IsSAccessor?
if (!propValue->IsSharedType() && !propValue->IsAccessor()) {
THROW_TYPE_ERROR(thread, "The properties of sendable class must be sendable too.");
}
obj->SetPropertyInlinedProps(thread, i, propValue.GetTaggedValue());
}
} else {
JSMutableHandle<ecmascript::NameDictionary> dict(
thread, ecmascript::NameDictionary::CreateInSharedHeap(
thread, ecmascript::NameDictionary::ComputeHashTableSize(length)));
for (uint32_t i = 0; i < length; i++) {
propKey.Update(descs[i].GetKey());
propValue.Update(descs[i].GetValue());
PropertyAttributes attr =
PropertyAttributes::Default(descs[i].IsWritable(), descs[i].IsEnumerable(), descs[i].IsConfigurable());
JSHandle<ecmascript::NameDictionary> newDict =
ecmascript::NameDictionary::PutIfAbsent(thread, dict, propKey, propValue, attr);
dict.Update(newDict);
}
obj->SetProperties(thread, dict);
}
}
bool JSObject::IsArrayLengthWritable(JSThread *thread, const JSHandle<JSObject> &receiver)
{
auto *hclass = receiver->GetJSHClass();
@ -2809,10 +2844,15 @@ void ECMAObject::SetNativePointerField(const JSThread *thread, int32_t index, vo
if (static_cast<int32_t>(array->GetExtraLength()) > index) {
EcmaVM *vm = thread->GetEcmaVM();
JSHandle<JSTaggedValue> current = JSHandle<JSTaggedValue>(thread, array->Get(thread, index));
JSHandle<JSTaggedValue> obj(thread, this);
if (!current->IsHole() && nativePointer == nullptr) {
// Try to remove native pointer if exists.
vm->RemoveFromNativePointerList(*JSHandle<JSNativePointer>(current));
array->Set(thread, index, JSTaggedValue::Hole());
} else if (obj->IsJSShared()) {
JSHandle<JSNativePointer> pointer =
vm->GetFactory()->NewSJSNativePointer(nativePointer, callBack, data, false, nativeBindingsize);
array->Set(thread, index, pointer.GetTaggedValue());
} else {
JSHandle<JSNativePointer> pointer = vm->GetFactory()->NewJSNativePointer(
nativePointer, callBack, data, false, nativeBindingsize, isConcurrent);
@ -2848,7 +2888,8 @@ void ECMAObject::SetNativePointerFieldCount(const JSThread *thread, int32_t coun
// Native Pointer field count is fixed.
if (array->GetExtraLength() == 0) {
JSHandle<TaggedArray> newArray =
thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + RESOLVED_MAX_SIZE);
value->IsJSShared() ? thread->GetEcmaVM()->GetFactory()->NewSTaggedArray(count + RESOLVED_MAX_SIZE)
: thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + RESOLVED_MAX_SIZE);
newArray->SetExtraLength(count);
newArray->Set(thread, count + HASH_INDEX, array->Get(HASH_INDEX));
newArray->Set(thread, count + FUNCTION_EXTRA_INDEX, array->Get(FUNCTION_EXTRA_INDEX));
@ -2856,7 +2897,8 @@ void ECMAObject::SetNativePointerFieldCount(const JSThread *thread, int32_t coun
}
} else if (value->IsJSNativePointer()) {
JSHandle<TaggedArray> newArray =
thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + RESOLVED_MAX_SIZE);
value->IsJSShared() ? thread->GetEcmaVM()->GetFactory()->NewSTaggedArray(count + RESOLVED_MAX_SIZE)
: thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + RESOLVED_MAX_SIZE);
newArray->SetExtraLength(count);
newArray->Set(thread, count + HASH_INDEX, JSTaggedValue(0));
newArray->Set(thread, count + FUNCTION_EXTRA_INDEX, value);
@ -2866,7 +2908,9 @@ void ECMAObject::SetNativePointerFieldCount(const JSThread *thread, int32_t coun
UNREACHABLE();
}
} else {
JSHandle<TaggedArray> newArray = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + 1);
JSHandle<TaggedArray> newArray = value->IsJSShared()
? thread->GetEcmaVM()->GetFactory()->NewSTaggedArray(count + 1)
: thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + 1);
newArray->SetExtraLength(count);
newArray->Set(thread, count + HASH_INDEX, value);
Barriers::SetObject<true>(thread, *obj, HASH_OFFSET, newArray.GetTaggedValue().GetRawData());

View File

@ -743,6 +743,11 @@ public:
static void TryOptimizeAsFastElements(const JSThread *thread, JSHandle<JSObject> obj);
static void OptimizeAsFastProperties(const JSThread *thread, JSHandle<JSObject> obj);
static void SetSProperties(JSThread *thread,
JSHandle<JSObject> obj,
JSHandle<JSHClass> hclass,
const std::vector<PropertyDescriptor> &descs);
protected:
static void ElementsToDictionary(const JSThread *thread, JSHandle<JSObject> obj);

View File

@ -215,6 +215,19 @@ void JSThread::InvokeWeakNodeFreeGlobalCallBack()
}
}
void JSThread::InvokeSharedNativePointerCallbacks()
{
auto callbacks = vm_->GetSharedNativePointerCallbacks();
while (!callbacks.empty()) {
auto callbackPair = callbacks.back();
callbacks.pop_back();
ASSERT(callbackPair.first != nullptr && callbackPair.second.first != nullptr &&
callbackPair.second.second != nullptr);
auto callback = callbackPair.first;
(*callback)(callbackPair.second.first, callbackPair.second.second);
}
}
void JSThread::InvokeWeakNodeNativeFinalizeCallback()
{
// the second callback may lead to another GC, if this, return directly;
@ -1043,6 +1056,9 @@ void JSThread::TransferToRunning()
if (!weakNodeFreeGlobalCallbacks_.empty()) {
InvokeWeakNodeFreeGlobalCallBack();
}
if (!vm_->GetSharedNativePointerCallbacks().empty()) {
InvokeSharedNativePointerCallbacks();
}
}
void JSThread::StoreState(ThreadState newState, bool lockMutatorLock)

View File

@ -794,6 +794,7 @@ public:
}
void InvokeWeakNodeFreeGlobalCallBack();
void InvokeSharedNativePointerCallbacks();
void InvokeWeakNodeNativeFinalizeCallback();
bool IsStartGlobalLeakCheck() const;
bool EnableGlobalObjectLeakCheck() const;

View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2024 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/jsnapi_sendable.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/global_env.h"
#include "ecmascript/napi/jsnapi_helper.h"
#include "ecmascript/object_factory.h"
#include "ecmascript/tagged_dictionary.h"
#include "js_function.h"
namespace panda::ecmascript {
JSNapiSendable::JSNapiSendable(JSThread *thread, FunctionRef::SendablePropertiesInfos &infos, Local<StringRef> &name)
{
InitSPropertiesInfos(thread, infos, name);
Init(thread, infos.staticPropertiesInfo, staticDescs_);
Init(thread, infos.nonStaticPropertiesInfo, nonStaticDescs_);
Init(thread, infos.instancePropertiesInfo, instanceDescs_);
}
void JSNapiSendable::InitSPropertiesInfos(JSThread *thread,
FunctionRef::SendablePropertiesInfos &infos,
Local<StringRef> &name)
{
EcmaVM *vm = thread->GetEcmaVM();
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
JSHandle<JSTaggedValue> napiWrapperKey = globalConst->GetHandledNapiWrapperString();
infos.instancePropertiesInfo.keys.insert(infos.instancePropertiesInfo.keys.begin(),
JSNApiHelper::ToLocal<StringRef>(napiWrapperKey));
infos.instancePropertiesInfo.types.insert(infos.instancePropertiesInfo.types.begin(),
FunctionRef::SendableType::OBJECT);
infos.instancePropertiesInfo.attributes.insert(infos.instancePropertiesInfo.attributes.begin(),
PropertyAttribute(JSValueRef::Null(vm), true, false, true));
JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
infos.staticPropertiesInfo.keys.insert(infos.staticPropertiesInfo.keys.begin(),
JSNApiHelper::ToLocal<StringRef>(nameKey));
infos.staticPropertiesInfo.types.insert(infos.staticPropertiesInfo.types.begin(), FunctionRef::SendableType::NONE);
infos.staticPropertiesInfo.attributes.insert(infos.staticPropertiesInfo.attributes.begin(),
PropertyAttribute(name, false, false, false));
JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
infos.nonStaticPropertiesInfo.keys.insert(infos.nonStaticPropertiesInfo.keys.begin(),
JSNApiHelper::ToLocal<StringRef>(constructorKey));
infos.nonStaticPropertiesInfo.types.insert(infos.nonStaticPropertiesInfo.types.begin(),
FunctionRef::SendableType::OBJECT);
infos.nonStaticPropertiesInfo.attributes.insert(infos.nonStaticPropertiesInfo.attributes.begin(),
PropertyAttribute(JSValueRef::Null(vm), false, false, false));
}
void JSNapiSendable::Init(JSThread *thread,
FunctionRef::SendablePropertiesInfo &info,
std::vector<PropertyDescriptor> &descs)
{
EcmaVM *vm = thread->GetEcmaVM();
auto length = info.keys.size();
for (size_t i = 0; i < length; ++i) {
PropertyDescriptor desc(thread, info.attributes[i].IsWritable(), info.attributes[i].IsEnumerable(),
info.attributes[i].IsConfigurable());
desc.SetKey(JSNApiHelper::ToJSHandle(info.keys[i]));
auto type = GetSharedFieldType(thread, info.types[i], info.attributes[i].GetValue(vm));
desc.SetSharedFieldType(type);
desc.SetValue(JSNApiHelper::ToJSHandle(info.attributes[i].GetValue(vm)));
descs.push_back(desc);
}
}
SharedFieldType JSNapiSendable::GetSharedFieldType(JSThread *thread,
FunctionRef::SendableType type,
Local<JSValueRef> value)
{
switch (type) {
case FunctionRef::SendableType::OBJECT:
return SharedFieldType::SENDABLE;
case FunctionRef::SendableType::NONE: {
auto valueHandle = JSNApiHelper::ToJSHandle(value);
if (valueHandle->IsUndefined()) {
return SharedFieldType::NONE;
}
if (valueHandle->IsNull()) {
// fixme: SharedFieldType::NULL ?
return SharedFieldType::SENDABLE;
}
if (valueHandle->IsNumber()) {
return SharedFieldType::NUMBER;
}
if (valueHandle->IsString()) {
return SharedFieldType::STRING;
}
if (valueHandle->IsBoolean()) {
return SharedFieldType::BOOLEAN;
}
if (valueHandle->IsJSShared()) {
return SharedFieldType::SENDABLE;
}
if (valueHandle->IsBigInt()) {
return SharedFieldType::BIG_INT;
}
THROW_TYPE_ERROR_AND_RETURN(thread, "Unknown SharedFieldType", SharedFieldType::NONE);
}
default:
THROW_TYPE_ERROR_AND_RETURN(thread, "Unknown SharedFieldType", SharedFieldType::NONE);
}
}
} // namespace panda::ecmascript

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2024 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_JS_NAPI_SENDABLE_H
#define ECMASCRIPT_JS_NAPI_SENDABLE_H
#include "ecmascript/layout_info.h"
#include "ecmascript/property_attributes.h"
namespace panda::ecmascript {
class JSNapiSendable {
public:
JSNapiSendable(JSThread *thread, FunctionRef::SendablePropertiesInfos &infos, Local<StringRef> &name);
const std::vector<PropertyDescriptor> GetStaticDescs() const
{
return staticDescs_;
}
const std::vector<PropertyDescriptor> GetNonStaticDescs() const
{
return nonStaticDescs_;
}
const std::vector<PropertyDescriptor> GetInstanceDescs() const
{
return instanceDescs_;
}
private:
std::vector<PropertyDescriptor> staticDescs_;
std::vector<PropertyDescriptor> nonStaticDescs_;
std::vector<PropertyDescriptor> instanceDescs_;
static void InitSPropertiesInfos(JSThread *thread,
FunctionRef::SendablePropertiesInfos &infos,
Local<StringRef> &name);
static void Init(JSThread *thread,
FunctionRef::SendablePropertiesInfo &info,
std::vector<PropertyDescriptor> &descs);
static SharedFieldType GetSharedFieldType(JSThread *thread,
FunctionRef::SendableType type,
Local<JSValueRef> value);
};
} // namespace panda::ecmascript
#endif

View File

@ -86,6 +86,7 @@ void SharedGC::Sweep()
ASSERT(!thread->IsInRunningState());
thread->GetCurrentEcmaContext()->ProcessNativeDeleteInSharedGC(gcUpdateWeak);
thread->IterateWeakEcmaGlobalStorage(gcUpdateWeak, true);
thread->GetEcmaVM()->ProcessSharedNativeDelete(gcUpdateWeak);
});
sHeap_->GetSweeper()->Sweep();

View File

@ -627,6 +627,11 @@ public:
static Local<NativePointerRef> NewConcurrent(const EcmaVM *vm, void *nativePointer,
NativePointerCallback callBack,
void *data, size_t nativeBindingsize = 0);
static Local<NativePointerRef> NewSendable(const EcmaVM *vm,
void *nativePointer,
NativePointerCallback callBack,
void *data,
size_t nativeBindingsize = 0);
void *Value();
};
@ -691,10 +696,14 @@ using FunctionCallback = Local<JSValueRef>(*)(JsiRuntimeCallInfo*);
using InternalFunctionCallback = JSValueRef(*)(JsiRuntimeCallInfo*);
class ECMA_PUBLIC_API FunctionRef : public ObjectRef {
public:
enum class SendableType {
NONE,
OBJECT,
};
struct SendablePropertiesInfo {
Local<panda::ArrayRef> keys;
Local<panda::ArrayRef> values;
PropertyAttribute *attributes;
std::vector<Local<JSValueRef>> keys;
std::vector<SendableType> types;
std::vector<PropertyAttribute> attributes;
};
struct SendablePropertiesInfos {
SendablePropertiesInfo instancePropertiesInfo;
@ -724,7 +733,7 @@ public:
Deleter deleter,
void *data,
Local<StringRef> name,
SendablePropertiesInfos infos,
SendablePropertiesInfos &infos,
Local<FunctionRef> parent,
bool callNapi = false,
size_t nativeBindingsize = 0);

View File

@ -70,6 +70,7 @@
#include "ecmascript/js_tagged_number.h"
#include "ecmascript/js_thread.h"
#include "ecmascript/js_typed_array.h"
#include "ecmascript/jsnapi_sendable.h"
#include "ecmascript/jspandafile/debug_info_extractor.h"
#include "ecmascript/jspandafile/js_pandafile_executor.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
@ -132,6 +133,7 @@ using ecmascript::JSHClass;
using ecmascript::JSIterator;
using ecmascript::JSMap;
using ecmascript::JSMapIterator;
using ecmascript::JSNapiSendable;
using ecmascript::JSNativePointer;
using ecmascript::JSObject;
using ecmascript::JSPandaFile;
@ -2051,8 +2053,19 @@ Local<NativePointerRef> NativePointerRef::NewConcurrent(
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSNativePointer> obj = factory->NewJSNativePointer(nativePointer, callBack, data,
false, nativeBindingsize, Concurrent::YES);
JSHandle<JSNativePointer> obj =
factory->NewJSNativePointer(nativePointer, callBack, data, false, nativeBindingsize, Concurrent::YES);
return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
}
Local<NativePointerRef> NativePointerRef::NewSendable(
const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data, size_t nativeBindingsize)
{
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSNativePointer> obj =
factory->NewSJSNativePointer(nativePointer, callBack, data, false, nativeBindingsize);
return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
}
@ -2317,165 +2330,12 @@ Local<FunctionRef> FunctionRef::NewClassFunction(EcmaVM *vm, InternalFunctionCal
return scope.Escape(result);
}
ecmascript::SharedFieldType GetSharedFieldType(Local<JSValueRef> value)
{
auto valueHandle = JSNApiHelper::ToJSHandle(value);
if (valueHandle->IsUndefined()) {
return ecmascript::SharedFieldType::NONE;
}
if (valueHandle->IsNumber()) {
return ecmascript::SharedFieldType::NUMBER;
}
if (valueHandle->IsString()) {
return ecmascript::SharedFieldType::STRING;
}
if (valueHandle->IsBoolean()) {
return ecmascript::SharedFieldType::BOOLEAN;
}
if (valueHandle->IsObject()) {
return ecmascript::SharedFieldType::SENDABLE;
}
if (valueHandle->IsBigInt()) {
return ecmascript::SharedFieldType::BIG_INT;
}
LOG_ECMA(ERROR) << "SharedFieldType";
return ecmascript::SharedFieldType::NONE;
}
JSHandle<JSHClass> CreateInlinedSendableHClass(JSThread *thread,
FunctionRef::SendablePropertiesInfo info,
bool isProtoClass)
{
EcmaVM *vm = thread->GetEcmaVM();
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSHClass> hclass;
uint32_t length = info.keys->Length(vm);
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
JSHandle<ecmascript::LayoutInfo> layout = factory->CreateSLayoutInfo(length);
for (uint32_t i = 0; i < length; ++i) {
key.Update(JSNApiHelper::ToJSHandle(info.keys->Get(vm, i)));
ASSERT(key->IsString());
ecmascript::SharedFieldType type = GetSharedFieldType(info.values->Get(vm, i));
ecmascript::PropertyAttributes attr = ecmascript::PropertyAttributes::Default(
info.attributes[i].IsWritable(), info.attributes[i].IsEnumerable(), info.attributes[i].IsConfigurable());
if (UNLIKELY(JSNApiHelper::ToJSHandle(info.attributes[i].GetValue(vm))->IsAccessor())) {
attr.SetIsAccessor(true);
}
attr.SetIsInlinedProps(true);
attr.SetRepresentation(ecmascript::Representation::TAGGED);
attr.SetSharedFieldType(type);
attr.SetOffset(i);
layout->AddKey(thread, i, key.GetTaggedValue(), attr);
}
hclass = isProtoClass ? factory->NewSEcmaHClass(ecmascript::JSSharedObject::SIZE,
ecmascript::JSType::JS_SHARED_OBJECT, length)
: factory->NewSEcmaHClass(ecmascript::JSSharedFunction::SIZE,
ecmascript::JSType::JS_SHARED_FUNCTION, length);
hclass->SetLayout(thread, layout);
hclass->SetNumberOfProps(length);
return hclass;
}
JSHandle<JSHClass> CreateDictSendableHClass(JSThread *thread,
FunctionRef::SendablePropertiesInfo info,
bool isProtoClass)
{
EcmaVM *vm = thread->GetEcmaVM();
ObjectFactory *factory = vm->GetFactory();
JSHandle<JSHClass> hclass;
uint32_t length = info.keys->Length(vm);
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
JSMutableHandle<ecmascript::NameDictionary> dict(thread,
ecmascript::NameDictionary::CreateInSharedHeap(thread,
ecmascript::NameDictionary::ComputeHashTableSize(length)));
auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
JSHandle<JSTaggedValue> value = globalConst->GetHandledUndefined();
for (uint32_t i = 0; i < length; ++i) {
key.Update(JSNApiHelper::ToJSHandle(info.keys->Get(vm, i)));
ASSERT(key->IsString());
ecmascript::SharedFieldType type = GetSharedFieldType(info.values->Get(vm, i));
ecmascript::PropertyAttributes attr = ecmascript::PropertyAttributes::Default(
info.attributes[i].IsWritable(), info.attributes[i].IsEnumerable(), info.attributes[i].IsConfigurable());
attr.SetSharedFieldType(type);
attr.SetBoxType(ecmascript::PropertyBoxType::UNDEFINED);
JSHandle<ecmascript::NameDictionary> newDict = ecmascript::NameDictionary::Put(thread, dict, key, value, attr);
dict.Update(newDict);
}
hclass =
isProtoClass
? factory->NewSEcmaHClass(ecmascript::JSSharedObject::SIZE, ecmascript::JSType::JS_SHARED_OBJECT, 0)
: factory->NewSEcmaHClass(ecmascript::JSSharedFunction::SIZE, ecmascript::JSType::JS_SHARED_FUNCTION, 0);
hclass->SetLayout(thread, dict);
hclass->SetNumberOfProps(0);
hclass->SetIsDictionaryMode(true);
return hclass;
}
JSHandle<JSHClass> CreateSendableHClass(JSThread *thread, FunctionRef::SendablePropertiesInfo info, bool isProtoClass)
{
EcmaVM *vm = thread->GetEcmaVM();
uint32_t length = info.keys->Length(vm);
uint32_t maxInline =
isProtoClass ? ecmascript::JSSharedObject::MAX_INLINE : ecmascript::JSSharedFunction::MAX_INLINE;
JSHandle<JSHClass> hclass;
if (LIKELY(length <= maxInline)) {
hclass = CreateInlinedSendableHClass(thread, info, isProtoClass);
} else {
hclass = CreateDictSendableHClass(thread, info, isProtoClass);
}
if (isProtoClass) {
hclass->SetClassPrototype(true);
hclass->SetIsPrototype(true);
} else {
hclass->SetClassConstructor(true);
hclass->SetConstructor(true);
}
return hclass;
}
void SetInlinedAndDictProps(JSThread *thread,
FunctionRef::SendablePropertiesInfo info,
JSHandle<JSHClass> hclass,
JSHandle<JSObject> obj)
{
EcmaVM *vm = thread->GetEcmaVM();
JSMutableHandle<JSTaggedValue> propKey(thread, JSTaggedValue::Undefined());
JSMutableHandle<JSTaggedValue> propValue(thread, JSTaggedValue::Undefined());
uint32_t length = info.keys->Length(vm);
if (LIKELY(!hclass->IsDictionaryMode())) {
for (uint32_t i = 0; i < length; ++i) {
propValue.Update(JSNApiHelper::ToJSHandle(info.attributes[i].GetValue(vm)));
obj->SetPropertyInlinedProps(thread, i, propValue.GetTaggedValue());
}
} else {
JSMutableHandle<ecmascript::NameDictionary> dict(thread,
ecmascript::NameDictionary::CreateInSharedHeap(thread,
ecmascript::NameDictionary::ComputeHashTableSize(length)));
for (uint32_t i = 0; i < length; i++) {
ecmascript::PropertyAttributes attr = ecmascript::PropertyAttributes::Default(
info.attributes[i].IsWritable(), info.attributes[i].IsEnumerable(),
info.attributes[i].IsConfigurable());
propKey.Update(JSNApiHelper::ToJSHandle(info.keys->Get(vm, i)));
propValue.Update(JSNApiHelper::ToJSHandle(info.attributes[i].GetValue(vm)));
JSHandle<ecmascript::NameDictionary> newDict =
ecmascript::NameDictionary::PutIfAbsent(thread, dict, propKey, propValue, attr);
dict.Update(newDict);
}
obj->SetProperties(thread, dict);
}
}
Local<FunctionRef> FunctionRef::NewSendableClassFunction(const EcmaVM *vm,
InternalFunctionCallback nativeFunc,
Deleter deleter,
void *data,
Local<StringRef> name,
SendablePropertiesInfos propertiesInfos,
SendablePropertiesInfos &infos,
Local<FunctionRef> parent,
bool callNapi,
size_t nativeBindingSize)
@ -2484,27 +2344,19 @@ Local<FunctionRef> FunctionRef::NewSendableClassFunction(const EcmaVM *vm,
ecmascript::ThreadManagedScope managedScope(thread);
EscapeLocalScope scope(vm);
ObjectFactory *factory = vm->GetFactory();
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
auto [instancePropertiesInfo, staticPropertiesInfo, nonStaticPropertiesInfo] = propertiesInfos;
JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
staticPropertiesInfo.keys->Set(vm, 0, JSNApiHelper::ToLocal<StringRef>(nameKey));
staticPropertiesInfo.values->Set(vm, 0, name);
JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
nonStaticPropertiesInfo.keys->Set(vm, 0, JSNApiHelper::ToLocal<StringRef>(constructorKey));
nonStaticPropertiesInfo.values->Set(vm, 0, JSValueRef::Null(vm));
JSHandle<JSHClass> prototypeHClass = CreateSendableHClass(thread, nonStaticPropertiesInfo, true);
JSNapiSendable sendable(thread, infos, name);
JSHandle<JSHClass> prototypeHClass = JSHClass::CreateSPrototypeHClass(thread, sendable.GetNonStaticDescs());
JSHandle<JSObject> prototype = factory->NewSharedOldSpaceJSObject(prototypeHClass);
JSHandle<JSHClass> constructorHClass = CreateSendableHClass(thread, staticPropertiesInfo, false);
JSHandle<JSHClass> constructorHClass = JSHClass::CreateSConstructorHClass(thread, sendable.GetStaticDescs());
JSHandle<JSFunction> constructor = factory->NewSFunctionByHClass(
reinterpret_cast<void *>(nativeFunc), constructorHClass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
staticPropertiesInfo.attributes[0] = PropertyAttribute(name, false, false, false);
nonStaticPropertiesInfo.attributes[0] = PropertyAttribute(
infos.nonStaticPropertiesInfo.attributes.front() = PropertyAttribute(
JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>::Cast(constructor)), false, false, false);
SetInlinedAndDictProps(thread, nonStaticPropertiesInfo, prototypeHClass, prototype);
SetInlinedAndDictProps(thread, staticPropertiesInfo, constructorHClass, JSHandle<JSObject>::Cast(constructor));
JSObject::SetSProperties(thread, prototype, prototypeHClass, sendable.GetNonStaticDescs());
JSObject::SetSProperties(thread, JSHandle<JSObject>::Cast(constructor), constructorHClass,
sendable.GetStaticDescs());
if (!parent->IsNull()) {
auto parentPrototype = parent->GetFunctionPrototype(vm);
@ -2518,7 +2370,7 @@ Local<FunctionRef> FunctionRef::NewSendableClassFunction(const EcmaVM *vm,
constructor->SetCallNapi(callNapi);
constructor->SetSFunctionExtraInfo(thread, nullptr, deleter, data, nativeBindingSize);
JSHandle<JSHClass> iHClass = CreateSendableHClass(thread, instancePropertiesInfo, true);
JSHandle<JSHClass> iHClass = JSHClass::CreateSHClass(thread, sendable.GetInstanceDescs());
iHClass->SetPrototype(thread, JSHandle<JSTaggedValue>(prototype));
iHClass->SetExtensible(false);
constructor->SetProtoOrHClass(thread, iHClass);

View File

@ -17,9 +17,6 @@
#include "ecmascript/tests/test_helper.h"
#include "gtest/gtest.h"
// index 0 is name/constructor, index 1 is property to test.
static constexpr int INITIAL_PROPERTY_LENGTH = 2;
using namespace panda::ecmascript;
namespace panda::test {
@ -107,40 +104,26 @@ panda::JSValueRef FunctionCallback(JsiRuntimeCallInfo *info)
Local<FunctionRef> GetNewSendableClassFunction(
EcmaVM *vm, const char *instanceKey, const char *staticKey, const char *nonStaticKey, Local<FunctionRef> parent)
{
Local<panda::ArrayRef> instanceKeys = panda::ArrayRef::New(vm, 1);
Local<panda::ArrayRef> instanceValues = panda::ArrayRef::New(vm, 1);
PropertyAttribute *instanceAttributes = new PropertyAttribute[1];
// index 0 is name
Local<panda::ArrayRef> staticKeys = panda::ArrayRef::New(vm, INITIAL_PROPERTY_LENGTH);
Local<panda::ArrayRef> staticValues = panda::ArrayRef::New(vm, INITIAL_PROPERTY_LENGTH);
PropertyAttribute *staticAttributes = new PropertyAttribute[INITIAL_PROPERTY_LENGTH];
// index 0 is constructor
Local<panda::ArrayRef> nonStaticKeys = panda::ArrayRef::New(vm, INITIAL_PROPERTY_LENGTH);
Local<panda::ArrayRef> nonStaticValues = panda::ArrayRef::New(vm, INITIAL_PROPERTY_LENGTH);
PropertyAttribute *nonStaticAttributes = new PropertyAttribute[INITIAL_PROPERTY_LENGTH];
FunctionRef::SendablePropertiesInfos infos;
Local<StringRef> instanceStr = StringRef::NewFromUtf8(vm, instanceKey);
instanceKeys->Set(vm, 0, instanceStr);
instanceValues->Set(vm, 0, instanceStr);
instanceAttributes[0] = PropertyAttribute(instanceStr, true, true, true);
infos.instancePropertiesInfo.keys.push_back(instanceStr);
infos.instancePropertiesInfo.types.push_back(FunctionRef::SendableType::NONE);
infos.instancePropertiesInfo.attributes.push_back(PropertyAttribute(instanceStr, true, true, true));
Local<StringRef> staticStr = StringRef::NewFromUtf8(vm, staticKey);
staticKeys->Set(vm, 1, staticStr);
staticValues->Set(vm, 1, staticStr);
staticAttributes[1] = PropertyAttribute(staticStr, true, true, true);
infos.staticPropertiesInfo.keys.push_back(staticStr);
infos.staticPropertiesInfo.types.push_back(FunctionRef::SendableType::NONE);
infos.staticPropertiesInfo.attributes.push_back(PropertyAttribute(staticStr, true, true, true));
Local<StringRef> nonStaticStr = StringRef::NewFromUtf8(vm, nonStaticKey);
nonStaticKeys->Set(vm, 1, nonStaticStr);
nonStaticValues->Set(vm, 1, nonStaticStr);
nonStaticAttributes[1] = PropertyAttribute(nonStaticStr, true, true, true);
infos.nonStaticPropertiesInfo.keys.push_back(nonStaticStr);
infos.nonStaticPropertiesInfo.types.push_back(FunctionRef::SendableType::NONE);
infos.nonStaticPropertiesInfo.attributes.push_back(PropertyAttribute(nonStaticStr, true, true, true));
Local<StringRef> nameStr = StringRef::NewFromUtf8(vm, "name");
Local<FunctionRef> constructor =
FunctionRef::NewSendableClassFunction(vm, FunctionCallback, nullptr, nullptr, nameStr,
{{instanceKeys, instanceValues, instanceAttributes},
{staticKeys, staticValues, staticAttributes},
{nonStaticKeys, nonStaticValues, nonStaticAttributes}},
parent);
FunctionRef::NewSendableClassFunction(vm, FunctionCallback, nullptr, nullptr, nameStr, infos, parent);
return constructor;
}
@ -291,17 +274,7 @@ HWTEST_F_L0(JSNApiTests, NewSendableClassFunctionFunction)
{
LocalScope scope(vm_);
Local<panda::ArrayRef> instanceKeys = panda::ArrayRef::New(vm_, 0);
Local<panda::ArrayRef> instanceValues = panda::ArrayRef::New(vm_, 0);
PropertyAttribute *instanceAttributes = new PropertyAttribute[0];
// index 0 is name
Local<panda::ArrayRef> staticKeys = panda::ArrayRef::New(vm_, INITIAL_PROPERTY_LENGTH);
Local<panda::ArrayRef> staticValues = panda::ArrayRef::New(vm_, INITIAL_PROPERTY_LENGTH);
PropertyAttribute *staticAttributes = new PropertyAttribute[INITIAL_PROPERTY_LENGTH];
// index 0 is constructor
Local<panda::ArrayRef> nonStaticKeys = panda::ArrayRef::New(vm_, 1);
Local<panda::ArrayRef> nonStaticValues = panda::ArrayRef::New(vm_, 1);
PropertyAttribute *nonStaticAttributes = new PropertyAttribute[1];
FunctionRef::SendablePropertiesInfos infos;
Local<FunctionRef> func = FunctionRef::NewSendable(
vm_,
@ -311,16 +284,12 @@ HWTEST_F_L0(JSNApiTests, NewSendableClassFunctionFunction)
return **StringRef::NewFromUtf8(vm, "funcResult");
},
nullptr);
staticKeys->Set(vm_, 1, staticKey);
staticValues->Set(vm_, 1, func);
staticAttributes[1] = PropertyAttribute(func, true, true, true);
infos.staticPropertiesInfo.keys.push_back(staticKey);
infos.staticPropertiesInfo.types.push_back(FunctionRef::SendableType::OBJECT);
infos.staticPropertiesInfo.attributes.push_back(PropertyAttribute(func, true, true, true));
Local<FunctionRef> constructor = FunctionRef::NewSendableClassFunction(
vm_, FunctionCallback, nullptr, nullptr, StringRef::NewFromUtf8(vm_, "name"),
{{instanceKeys, instanceValues, instanceAttributes},
{staticKeys, staticValues, staticAttributes},
{nonStaticKeys, nonStaticValues, nonStaticAttributes}},
FunctionRef::Null(vm_));
vm_, FunctionCallback, nullptr, nullptr, StringRef::NewFromUtf8(vm_, "name"), infos, FunctionRef::Null(vm_));
Local<FunctionRef> staticValue = constructor->Get(vm_, staticKey);
ASSERT_TRUE(staticValue->IsFunction());
@ -332,22 +301,12 @@ HWTEST_F_L0(JSNApiTests, NewSendableClassFunctionGetterSetter)
{
LocalScope scope(vm_);
Local<panda::ArrayRef> instanceKeys = panda::ArrayRef::New(vm_, 0);
Local<panda::ArrayRef> instanceValues = panda::ArrayRef::New(vm_, 0);
PropertyAttribute *instanceAttributes = new PropertyAttribute[0];
// index 0 is name
Local<panda::ArrayRef> staticKeys = panda::ArrayRef::New(vm_, 3);
Local<panda::ArrayRef> staticValues = panda::ArrayRef::New(vm_, 3);
PropertyAttribute *staticAttributes = new PropertyAttribute[3];
// index 0 is constructor
Local<panda::ArrayRef> nonStaticKeys = panda::ArrayRef::New(vm_, 1);
Local<panda::ArrayRef> nonStaticValues = panda::ArrayRef::New(vm_, 1);
PropertyAttribute *nonStaticAttributes = new PropertyAttribute[1];
FunctionRef::SendablePropertiesInfos infos;
Local<StringRef> getterSetter = StringRef::NewFromUtf8(vm_, "getterSetter");
staticKeys->Set(vm_, 1, getterSetter);
staticValues->Set(vm_, 1, getterSetter);
staticAttributes[1] = PropertyAttribute(getterSetter, true, true, true);
infos.staticPropertiesInfo.keys.push_back(getterSetter);
infos.staticPropertiesInfo.types.push_back(FunctionRef::SendableType::NONE);
infos.staticPropertiesInfo.attributes.push_back(PropertyAttribute(getterSetter, true, true, true));
Local<FunctionRef> staticGetter = FunctionRef::NewSendable(
vm_,
[](JsiRuntimeCallInfo *info) -> JSValueRef {
@ -368,19 +327,17 @@ HWTEST_F_L0(JSNApiTests, NewSendableClassFunctionGetterSetter)
},
nullptr);
Local<JSValueRef> staticValue = panda::ObjectRef::CreateSendableAccessorData(vm_, staticGetter, staticSetter);
staticKeys->Set(vm_, 2, staticKey);
staticValues->Set(vm_, 2, staticValue);
staticAttributes[2] = PropertyAttribute(staticValue, true, true, true);
infos.staticPropertiesInfo.keys.push_back(staticKey);
infos.staticPropertiesInfo.types.push_back(FunctionRef::SendableType::OBJECT);
infos.staticPropertiesInfo.attributes.push_back(PropertyAttribute(staticValue, true, true, true));
Local<FunctionRef> constructor = FunctionRef::NewSendableClassFunction(
vm_, FunctionCallback, nullptr, nullptr, StringRef::NewFromUtf8(vm_, "name"),
{{instanceKeys, instanceValues, instanceAttributes},
{staticKeys, staticValues, staticAttributes},
{nonStaticKeys, nonStaticValues, nonStaticAttributes}},
FunctionRef::Null(vm_));
vm_, FunctionCallback, nullptr, nullptr, StringRef::NewFromUtf8(vm_, "name"), infos, FunctionRef::Null(vm_));
ASSERT_EQ("getterSetter", constructor->Get(vm_, getterSetter)->ToString(vm_)->ToString());
ASSERT_EQ("getterSetter", constructor->Get(vm_, staticKey)->ToString(vm_)->ToString());
constructor->Set(vm_, staticKey, StringRef::NewFromUtf8(vm_, "getterSetter0"));
ASSERT_EQ("getterSetter0", constructor->Get(vm_, getterSetter)->ToString(vm_)->ToString());
ASSERT_EQ("getterSetter0", constructor->Get(vm_, staticKey)->ToString(vm_)->ToString());
}

View File

@ -766,7 +766,9 @@ public:
JSHandle<TaggedArray> NewSOldSpaceTaggedArray(uint32_t length, JSTaggedValue initVal = JSTaggedValue::Hole());
JSHandle<TaggedArray> NewSTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType);
JSHandle<TaggedArray> NewSTaggedArray(uint32_t length,
JSTaggedValue initVal = JSTaggedValue::Hole(),
MemSpaceType spaceType = SHARED_OLD_SPACE);
JSHandle<AccessorData> NewSAccessorData();
@ -816,6 +818,7 @@ public:
JSHandle<JSSymbol> NewSWellKnownSymbolWithChar(std::string_view description);
JSHandle<JSSymbol> NewSPublicSymbolWithChar(std::string_view description);
JSHandle<JSSymbol> NewSPublicSymbol(const JSHandle<JSTaggedValue> &name);
private:
friend class GlobalEnv;
friend class GlobalEnvConstants;

View File

@ -362,7 +362,7 @@ JSHandle<JSNativePointer> ObjectFactory::NewSJSNativePointer(void *externalPoint
obj->SetNativeFlag(flag);
if (callBack != nullptr) {
vm_->PushToNativePointerList(static_cast<JSNativePointer *>(header));
vm_->PushToSharedNativePointerList(static_cast<JSNativePointer *>(header));
// In some cases, the size of JS/TS object is too small and the native binding size is too large.
// Check and try trigger concurrent mark here.
}