mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
Supprt define instance hclass
Support non-static&public field of sendable class Signed-off-by: lukai <lukai25@huawei.com> Change-Id: I66ca75e4fe031c5b39f184268509cad8160113b8
This commit is contained in:
parent
5b838d0963
commit
f5457927f9
@ -551,6 +551,8 @@ static void DumpAttr(const PropertyAttributes &attr, bool fastMode, std::ostream
|
||||
if (attr.IsConfigurable()) {
|
||||
os << "C";
|
||||
}
|
||||
|
||||
os << (int)(attr.GetTrackType());
|
||||
os << ")";
|
||||
|
||||
os << " InlinedProps: " << attr.IsInlinedProps();
|
||||
@ -720,6 +722,7 @@ static void DumpObject(TaggedObject *obj, std::ostream &os)
|
||||
break;
|
||||
case JSType::ACCESSOR_DATA:
|
||||
break;
|
||||
case JSType::JS_SHARED_FUNCTION:
|
||||
case JSType::JS_FUNCTION:
|
||||
needDumpHClass = true;
|
||||
JSFunction::Cast(obj)->Dump(os);
|
||||
|
@ -494,9 +494,9 @@ JSHandle<JSFunction> ClassHelper::DefineSendableClassFromExtractor(JSThread *thr
|
||||
// JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(prototype),
|
||||
// globalConst->GetHandledConstructorString(), ctorDesc);
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
auto value = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>(prototype), globalConst->GetHandledConstructorString()).GetValue();
|
||||
[[maybe_unused]]auto value = JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>(prototype), globalConst->GetHandledConstructorString()).GetValue();
|
||||
ASSERT(JSTaggedValue::Equal(thread, value, JSHandle<JSTaggedValue>(constructor)));
|
||||
|
||||
ECMAObject::InitializeExtRefAndOwner(thread->GetEcmaVM(), JSHandle<JSObject>(constructor));
|
||||
constructor->SetHomeObject(thread, prototype);
|
||||
constructor->SetProtoOrHClass(thread, prototype);
|
||||
constructor->SetLexicalEnv(thread, lexenv);
|
||||
@ -757,87 +757,127 @@ void ClassHelper::HandleElementsProperties(JSThread *thread, const JSHandle<JSOb
|
||||
}
|
||||
}
|
||||
|
||||
// todo , need ihc information from abc
|
||||
void ClassHelper::DefineSendableInstanceHClass(JSThread *thread, const JSHandle<JSFunction> &ctor, bool isbaseCase)
|
||||
void ClassHelper::AddFieldTypeToHClass(JSThread *thread, const JSHandle<TaggedArray> &fieldTypeArray,
|
||||
const JSHandle<LayoutInfo> &layout, const JSHandle<JSHClass> &hclass)
|
||||
{
|
||||
uint32_t length = fieldTypeArray->GetLength();
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
uint32_t index = layout->NumberOfElements();
|
||||
PropertyAttributes attributes = PropertyAttributes::Default(true, true, true);
|
||||
attributes.SetIsInlinedProps(true);
|
||||
attributes.SetRepresentation(Representation::TAGGED);
|
||||
for (uint32_t i = 0; i < length; i += 2) { // 2: key-value pair;
|
||||
key.Update(fieldTypeArray->Get(i));
|
||||
TrackType type = FromFieldType(FieldType(fieldTypeArray->Get(i + 1).GetInt()));
|
||||
int entry = layout->FindElementWithCache(thread, *hclass, key.GetTaggedValue(), index);
|
||||
if (entry != -1) {
|
||||
std::stringstream ss;
|
||||
key->Dump(ss);
|
||||
LOG_FULL(ERROR) << "defineSendableClass with same filed " << ss.str(); // TODO DELETE THIS LOG WHEN PUBLISH THIS PR.
|
||||
attributes = layout->GetAttr(entry);
|
||||
attributes.SetTrackType(type);
|
||||
layout->SetNormalAttr(thread, entry, attributes);
|
||||
} else {
|
||||
attributes.SetTrackType(type);
|
||||
attributes.SetOffset(index);
|
||||
layout->AddKey<true>(thread, index++, key.GetTaggedValue(), attributes); // todo check duplicated only for test
|
||||
}
|
||||
}
|
||||
hclass->SetLayout(thread, layout);
|
||||
hclass->SetNumberOfProps(index);
|
||||
auto inlinedProps = hclass->GetInlinedProperties();
|
||||
if (inlinedProps > index) {
|
||||
// resize hclass due to duplicated key.
|
||||
uint32_t duplicatedSize = (inlinedProps - index) * JSTaggedValue::TaggedTypeSize();
|
||||
hclass->SetObjectSize(hclass->GetObjectSize() - duplicatedSize);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassHelper::AddFieldTypeToHClass(JSThread *thread, const JSHandle<TaggedArray> &fieldTypeArray,
|
||||
const JSHandle<NameDictionary> &nameDict, const JSHandle<JSHClass> &hclass)
|
||||
{
|
||||
uint32_t length = fieldTypeArray->GetLength();
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<NameDictionary> dict(thread, nameDict);
|
||||
PropertyAttributes attributes = PropertyAttributes::Default(true, true, true);
|
||||
auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
|
||||
JSHandle<JSTaggedValue> value = globalConst->GetHandledUndefined();
|
||||
for (uint32_t i = 0; i < length; i += 2) { // 2: key-value pair;
|
||||
key.Update(fieldTypeArray->Get(i));
|
||||
TrackType type = FromFieldType(FieldType(fieldTypeArray->Get(i + 1).GetInt()));
|
||||
attributes.SetTrackType(type);
|
||||
attributes.SetBoxType(PropertyBoxType::UNDEFINED);
|
||||
JSHandle<NameDictionary> newDict = NameDictionary::Put(thread, dict, key, value, attributes);
|
||||
dict.Update(newDict);
|
||||
}
|
||||
ASSERT(hclass->GetInlinedProperties() == 0);
|
||||
// HClass's layout field is reused as a NameDictionary
|
||||
hclass->SetLayout(thread, dict);
|
||||
hclass->SetNumberOfProps(0);
|
||||
hclass->SetIsDictionaryMode(true);
|
||||
}
|
||||
|
||||
void ClassHelper::DefineSendableInstanceHClass(JSThread *thread, const JSHandle<TaggedArray> &fieldTypeArray,
|
||||
const JSHandle<JSFunction> &ctor, const JSHandle<JSTaggedValue> &base)
|
||||
{
|
||||
ASSERT(ctor->GetClass()->IsJSSharedFunction());
|
||||
JSHandle<JSObject> clsPrototype(thread, JSHandle<JSFunction>(ctor)->GetFunctionPrototype());
|
||||
ASSERT(clsPrototype->GetClass()->IsJSSharedObject());
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
// todo define ihc
|
||||
// for test , i create ihc with such fields. Should match your .js with such fields.
|
||||
// -------- base case ---------
|
||||
// x : string
|
||||
// y : number
|
||||
// z : boolean
|
||||
// -------- derived case --------
|
||||
// a : sobj
|
||||
// b : boolean
|
||||
JSHandle<JSHClass> hclass;
|
||||
if (isbaseCase) {
|
||||
int length = 3;
|
||||
std::string keys[] = {"x", "y", "z"};
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(length, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
|
||||
for (int i = 0; i < length; i++) {
|
||||
key.Update(factory->NewFromUtf8(keys[i]));
|
||||
PropertyAttributes attributes = PropertyAttributes::Default(true, true, true);
|
||||
attributes.SetIsInlinedProps(true);
|
||||
attributes.SetRepresentation(Representation::TAGGED);
|
||||
switch (i) {
|
||||
case 0: {
|
||||
attributes.SetTrackType(TrackType::STRING);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
attributes.SetTrackType(TrackType::NUMBER);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
attributes.SetTrackType(TrackType::BOOLEAN);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
attributes.SetOffset(i);
|
||||
layout->AddKey(thread, i, key.GetTaggedValue(), attributes);
|
||||
uint32_t length = fieldTypeArray->GetLength();
|
||||
uint32_t fieldNum = length / 2; // 2: key-value pair;
|
||||
JSHandle<JSHClass> iHClass;
|
||||
if (base->IsHole() || base->IsNull()) {
|
||||
if (LIKELY(fieldNum <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
|
||||
iHClass = factory->NewEcmaHClass(JSSharedObject::SIZE, JSType::JS_SHARED_OBJECT, fieldNum);
|
||||
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(fieldNum, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
|
||||
AddFieldTypeToHClass(thread, fieldTypeArray, layout, iHClass);
|
||||
} else {
|
||||
iHClass = factory->NewEcmaHClass(JSSharedObject::SIZE, JSType::JS_SHARED_OBJECT, 0);
|
||||
JSHandle<NameDictionary> dict =
|
||||
NameDictionary::Create(thread, NameDictionary::ComputeHashTableSize(fieldNum));
|
||||
AddFieldTypeToHClass(thread, fieldTypeArray, dict, iHClass);
|
||||
}
|
||||
hclass = factory->NewEcmaHClass(JSSharedObject::SIZE, JSType::JS_SHARED_OBJECT, length);
|
||||
hclass->SetLayout(thread, layout);
|
||||
hclass->SetNumberOfProps(length);
|
||||
} else {
|
||||
int length = 2;
|
||||
std::string keys[] = {"a", "b"};
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(length, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
|
||||
for (int i = 0; i < length; i++) {
|
||||
key.Update(factory->NewFromUtf8(keys[i]));
|
||||
PropertyAttributes attributes = PropertyAttributes::Default(true, true, true);
|
||||
attributes.SetIsInlinedProps(true);
|
||||
attributes.SetRepresentation(Representation::TAGGED);
|
||||
switch (i) {
|
||||
case 0: {
|
||||
attributes.SetTrackType(TrackType::SENDABLE);
|
||||
break;
|
||||
ASSERT(base->IsJSSharedFunction());
|
||||
JSHandle<JSFunction> baseCtor = JSHandle<JSFunction>::Cast(base);
|
||||
JSHandle<JSHClass> baseIHClass(thread, baseCtor->GetProtoOrHClass());
|
||||
ASSERT(baseIHClass->IsJSSharedObject());
|
||||
if (LIKELY(!baseIHClass->IsDictionaryMode())) {
|
||||
auto baseLength = baseIHClass->NumberOfProps();
|
||||
JSHandle<LayoutInfo> baseLayout(thread, baseIHClass->GetLayout());
|
||||
auto newLength = baseLength + fieldNum;
|
||||
if (newLength <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY) {
|
||||
iHClass = factory->NewEcmaHClass(JSSharedObject::SIZE, JSType::JS_SHARED_OBJECT, newLength);
|
||||
JSHandle<LayoutInfo> layout = factory->ExtendLayoutInfo(baseLayout, newLength);
|
||||
AddFieldTypeToHClass(thread, fieldTypeArray, layout, iHClass);
|
||||
} else {
|
||||
iHClass = factory->NewEcmaHClass(JSSharedObject::SIZE, JSType::JS_SHARED_OBJECT, 0);
|
||||
JSHandle<NameDictionary> dict =
|
||||
NameDictionary::Create(thread, NameDictionary::ComputeHashTableSize(newLength));
|
||||
auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
|
||||
JSHandle<JSTaggedValue> value = globalConst->GetHandledUndefined();
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
for (uint32_t i = 0; i < baseLength; i++) {
|
||||
key.Update(baseLayout->GetKey(i));
|
||||
PropertyAttributes attr = baseLayout->GetAttr(i);
|
||||
attr.SetBoxType(PropertyBoxType::UNDEFINED);
|
||||
dict = NameDictionary::Put(thread, dict, key, value, attr);
|
||||
}
|
||||
case 1: {
|
||||
attributes.SetTrackType(TrackType::BOOLEAN);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
AddFieldTypeToHClass(thread, fieldTypeArray, dict, iHClass);
|
||||
}
|
||||
attributes.SetOffset(i);
|
||||
layout->AddKey(thread, i, key.GetTaggedValue(), attributes);
|
||||
} else {
|
||||
JSHandle<NameDictionary> baseDict(thread, baseIHClass->GetLayout());
|
||||
auto baseLength = baseDict->EntriesCount();
|
||||
JSHandle<NameDictionary> dict =
|
||||
NameDictionary::Create(thread, NameDictionary::ComputeHashTableSize(fieldNum + baseLength));
|
||||
baseDict->Rehash(thread, *dict);
|
||||
iHClass = factory->NewEcmaHClass(JSSharedObject::SIZE, JSType::JS_SHARED_OBJECT, 0);
|
||||
AddFieldTypeToHClass(thread, fieldTypeArray, dict, iHClass);
|
||||
}
|
||||
hclass = factory->NewEcmaHClass(JSSharedObject::SIZE, JSType::JS_SHARED_OBJECT, length);
|
||||
hclass->SetLayout(thread, layout);
|
||||
hclass->SetNumberOfProps(length);
|
||||
}
|
||||
hclass->SetPrototype(thread, JSHandle<JSTaggedValue>(clsPrototype));
|
||||
ctor->SetProtoOrHClass(thread, hclass);
|
||||
// todo support dictionary mode?
|
||||
iHClass->SetPrototype(thread, JSHandle<JSTaggedValue>(clsPrototype));
|
||||
ctor->SetProtoOrHClass(thread, iHClass);
|
||||
}
|
||||
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -25,6 +25,14 @@ namespace panda::ecmascript {
|
||||
// Attention: keys accessor stores the property key and properties accessor stores the property value, but elements
|
||||
// accessor stores the key-value pair abuttally.
|
||||
using EntityId = panda_file::File::EntityId;
|
||||
enum class FieldType
|
||||
{
|
||||
NONE = 0,
|
||||
NUMBER = (1 << 0),
|
||||
STRING = (1 << 1),
|
||||
BOOLEAN = (1 << 2),
|
||||
TS_TYPE_REF = (1 << 3),
|
||||
};
|
||||
class ClassInfoExtractor : public TaggedObject {
|
||||
public:
|
||||
static constexpr uint8_t NON_STATIC_RESERVED_LENGTH = 1;
|
||||
@ -106,7 +114,24 @@ public:
|
||||
const JSHandle<JSTaggedValue> &lexenv,
|
||||
const JSHandle<JSTaggedValue> &ihclass,
|
||||
const JSHandle<JSHClass> &constructorHClass);
|
||||
static void DefineSendableInstanceHClass(JSThread *thread, const JSHandle<JSFunction> &ctor, bool isbaseCase);
|
||||
static void DefineSendableInstanceHClass(JSThread *thread, const JSHandle<TaggedArray> &fieldTypeArray,
|
||||
const JSHandle<JSFunction> &ctor, const JSHandle<JSTaggedValue> &base);
|
||||
static TrackType FromFieldType(FieldType type) {
|
||||
switch (type) {
|
||||
case FieldType::NONE:
|
||||
return TrackType::NONE;
|
||||
case FieldType::NUMBER:
|
||||
return TrackType::NUMBER;
|
||||
case FieldType::STRING:
|
||||
return TrackType::STRING;
|
||||
case FieldType::BOOLEAN:
|
||||
return TrackType::BOOLEAN;
|
||||
case FieldType::TS_TYPE_REF:
|
||||
return TrackType::SENDABLE;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static JSHandle<NameDictionary> BuildDictionaryProperties(JSThread *thread, const JSHandle<JSObject> &object,
|
||||
@ -122,6 +147,12 @@ private:
|
||||
|
||||
static void HandleElementsProperties(JSThread *thread, const JSHandle<JSObject> &object,
|
||||
JSHandle<TaggedArray> &elements);
|
||||
|
||||
static void AddFieldTypeToHClass(JSThread *thread, const JSHandle<TaggedArray> &fieldTypeArray,
|
||||
const JSHandle<LayoutInfo> &layout, const JSHandle<JSHClass> &hclass);
|
||||
|
||||
static void AddFieldTypeToHClass(JSThread *thread, const JSHandle<TaggedArray> &fieldTypeArray,
|
||||
const JSHandle<NameDictionary> &nameDict, const JSHandle<JSHClass> &hclass);
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_JSPANDAFILE_CLASS_INFO_EXTRACTOR_H
|
||||
|
@ -504,6 +504,10 @@ JSHandle<TaggedArray> LiteralDataExtractor::GetDatasIgnoreType(JSThread *thread,
|
||||
jt = accessor.GetTaggedValue();
|
||||
break;
|
||||
}
|
||||
case LiteralTag::LITERALARRAY: {
|
||||
jt = JSTaggedValue(std::get<uint32_t>(value));
|
||||
break;
|
||||
}
|
||||
case LiteralTag::NULLVALUE: {
|
||||
break;
|
||||
}
|
||||
|
@ -287,6 +287,37 @@ public:
|
||||
return val;
|
||||
}
|
||||
|
||||
static JSHandle<TaggedArray> GetFieldLiteral(JSThread *thread, JSHandle<ConstantPool> constpool,
|
||||
uint32_t literal, CString entry)
|
||||
{
|
||||
// auto val = constpool->GetObjectFromCache(literal);
|
||||
JSPandaFile *jsPandaFile = constpool->GetJSPandaFile();
|
||||
|
||||
// // For AOT
|
||||
// bool isLoadedAOT = jsPandaFile->IsLoadedAOT();
|
||||
JSHandle<AOTLiteralInfo> entryIndexes(thread, JSTaggedValue::Undefined());
|
||||
// if (isLoadedAOT && val.IsAOTLiteralInfo()) {
|
||||
// entryIndexes = JSHandle<AOTLiteralInfo>(thread, val);
|
||||
// val = JSTaggedValue::Hole();
|
||||
// }
|
||||
|
||||
// if (val.IsHole()) {
|
||||
// EcmaVM *vm = thread->GetEcmaVM();
|
||||
// ObjectFactory *factory = vm->GetFactory();
|
||||
ASSERT(jsPandaFile->IsNewVersion());
|
||||
panda_file::File::EntityId literalId(literal);
|
||||
// bool needSetAotFlag = isLoadedAOT && !entryIndexes.GetTaggedValue().IsUndefined();
|
||||
JSHandle<TaggedArray> literalArray = LiteralDataExtractor::GetDatasIgnoreType(
|
||||
thread, jsPandaFile, literalId, constpool, entry, false, entryIndexes);
|
||||
// JSHandle<ClassLiteral> classLiteral = factory->NewClassLiteral();
|
||||
// classLiteral->SetArray(thread, literalArray);
|
||||
// val = classLiteral.GetTaggedValue();
|
||||
// constpool->SetObjectToCache(thread, literal, val);
|
||||
// }
|
||||
|
||||
return literalArray;
|
||||
}
|
||||
|
||||
template <ConstPoolType type>
|
||||
static JSTaggedValue GetLiteralFromCache(JSThread *thread, JSTaggedValue constpool, uint32_t index, CString entry)
|
||||
{
|
||||
|
@ -212,6 +212,7 @@ void LayoutInfo::AddKey(const JSThread *thread, [[maybe_unused]] int index, cons
|
||||
return;
|
||||
}
|
||||
if (prevKey == key) {
|
||||
std::abort();
|
||||
THROW_TYPE_ERROR(const_cast<JSThread *>(thread), "property keys can not duplicate");
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ enum class PropertyBoxType {
|
||||
* -----------------------------
|
||||
* Slow | PropertyBoxTypeField(bit 8...9)
|
||||
* | DictionaryOrderField(bit 10...29)
|
||||
* | TrackTypeField(bit 30...32)
|
||||
*/
|
||||
class PropertyAttributes {
|
||||
public:
|
||||
@ -128,7 +129,8 @@ public:
|
||||
static_assert(DictModeStartField::SIZE == CommonLastBitField::SIZE);
|
||||
using PropertyBoxTypeField = DictModeStartField::NextField<PropertyBoxType, 2>; // 2: 2 bits, 8-9
|
||||
using DictionaryOrderField = PropertyBoxTypeField::NextField<uint32_t, DICTIONARY_ORDER_NUM>; // 29
|
||||
using DictModeLastField = DictionaryOrderField;
|
||||
using DictTrackTypeField = DictionaryOrderField::NextField<TrackType, TRACK_TYPE_NUM>;
|
||||
using DictModeLastField = DictTrackTypeField;
|
||||
static_assert(
|
||||
DictModeLastField::START_BIT + DictModeLastField::SIZE <= sizeof(uint32_t) * BITS_PER_BYTE, "Invalid");
|
||||
|
||||
@ -307,6 +309,16 @@ public:
|
||||
TrackTypeField::Set(type, &value_);
|
||||
}
|
||||
|
||||
inline void SetDictTrackType(TrackType type)
|
||||
{
|
||||
DictTrackTypeField::Set(type, &value_);
|
||||
}
|
||||
|
||||
inline TrackType GetDictTrackType() const
|
||||
{
|
||||
return DictTrackTypeField::Get(value_);
|
||||
}
|
||||
|
||||
inline void SetDictionaryOrder(uint32_t order)
|
||||
{
|
||||
DictionaryOrderField::Set<uint32_t>(order, &value_);
|
||||
|
@ -900,35 +900,26 @@ JSTaggedValue RuntimeStubs::RuntimeCreateSendableClass(JSThread *thread,
|
||||
thread, constpool.GetTaggedValue(), module.GetTaggedValue(), methodId);
|
||||
JSHandle<JSTaggedValue> method(thread, methodObj);
|
||||
JSHandle<ConstantPool> constpoolHandle = JSHandle<ConstantPool>::Cast(constpool);
|
||||
// JSHandle<JSFunction> cls;
|
||||
// JSMutableHandle<JSTaggedValue> ihc(thread, JSTaggedValue::Undefined());
|
||||
// JSMutableHandle<JSTaggedValue> chc(thread, JSTaggedValue::Undefined());
|
||||
|
||||
// JSTaggedValue val = constpoolHandle->GetObjectFromCache(literalId);
|
||||
// if (val.IsAOTLiteralInfo()) {
|
||||
// JSHandle<AOTLiteralInfo> aotLiteralInfo(thread, val);
|
||||
// ihc.Update(aotLiteralInfo->GetIhc());
|
||||
// chc.Update(aotLiteralInfo->GetChc());
|
||||
// }
|
||||
auto literalObj = ConstantPool::GetClassLiteralFromCache(thread, constpoolHandle, literalId, entry);
|
||||
JSHandle<ClassLiteral> classLiteral(thread, literalObj);
|
||||
JSHandle<TaggedArray> arrayHandle(thread, classLiteral->GetArray());
|
||||
auto literalLength = arrayHandle->GetLength();
|
||||
// fieldTypeId is the last element in literal buffer
|
||||
auto fieldTypeId = static_cast<uint32_t>(arrayHandle->Get(literalLength - 1).GetInt());
|
||||
arrayHandle->Trim(thread, literalLength - 1);
|
||||
JSHandle<ClassInfoExtractor> extractor = factory->NewClassInfoExtractor(method);
|
||||
ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(thread, extractor, arrayHandle);
|
||||
// if (ShouldUseAOTHClass(ihc, chc, classLiteral)) {
|
||||
// classLiteral->SetIsAOTUsed(true);
|
||||
// JSHandle<JSHClass> chclass(chc);
|
||||
// cls = ClassHelper::DefineClassWithIHClass(thread, extractor,
|
||||
// lexenv, ihc, chclass);
|
||||
// } else {
|
||||
|
||||
JSHandle<JSFunction> cls = ClassHelper::DefineSendableClassFromExtractor(thread, base, extractor, lexenv);
|
||||
// }
|
||||
|
||||
RuntimeSetClassConstructorLength(thread, cls.GetTaggedValue(), JSTaggedValue(length));
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
RuntimeSetClassInheritanceRelationship(thread, JSHandle<JSTaggedValue>(cls), base, true);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
bool isbaseClass = base->IsHole(); // todo for test
|
||||
ClassHelper::DefineSendableInstanceHClass(thread, cls, isbaseClass); // todo need ihc information from abc
|
||||
|
||||
JSHandle<TaggedArray> fieldTypeArray = ConstantPool::GetFieldLiteral(thread, constpoolHandle, fieldTypeId, entry);
|
||||
ClassHelper::DefineSendableInstanceHClass(thread, fieldTypeArray, cls, base);
|
||||
return cls.GetTaggedValue();
|
||||
}
|
||||
|
||||
|
@ -295,6 +295,33 @@ public:
|
||||
Set(thread, index, value);
|
||||
}
|
||||
|
||||
// Rehash element to new_table
|
||||
void Rehash(const JSThread *thread, Derived *newTable)
|
||||
{
|
||||
if ((newTable == nullptr) || (newTable->Size() < EntriesCount())) {
|
||||
return;
|
||||
}
|
||||
int currentSize = this->Size();
|
||||
// Rehash elements to new table
|
||||
for (int i = 0; i < currentSize; i++) {
|
||||
int fromIndex = Derived::GetKeyIndex(i);
|
||||
JSTaggedValue k = this->GetKey(i);
|
||||
if (!IsKey(k)) {
|
||||
continue;
|
||||
}
|
||||
int32_t hash = static_cast<int32_t>(Derived::Hash(k));
|
||||
int insertionIndex = Derived::GetKeyIndex(newTable->FindInsertIndex(hash));
|
||||
JSTaggedValue tv = Get(fromIndex);
|
||||
newTable->Set(thread, insertionIndex, tv);
|
||||
for (int j = 1; j < Derived::GetEntrySize(); j++) {
|
||||
tv = Get(fromIndex + j);
|
||||
newTable->Set(thread, insertionIndex + j, tv);
|
||||
}
|
||||
}
|
||||
newTable->SetEntriesCount(thread, EntriesCount());
|
||||
newTable->SetHoleEntriesCount(thread, 0);
|
||||
}
|
||||
|
||||
static constexpr int MIN_SHRINK_SIZE = 16;
|
||||
static constexpr int MIN_SIZE = 4;
|
||||
static constexpr int NUMBER_OF_ENTRIES_INDEX = 0;
|
||||
@ -354,33 +381,6 @@ protected:
|
||||
this->SetValue(thread, entry, defaultValue);
|
||||
this->IncreaseHoleEntriesCount(thread);
|
||||
}
|
||||
|
||||
// Rehash element to new_table
|
||||
void Rehash(const JSThread *thread, Derived *newTable)
|
||||
{
|
||||
if ((newTable == nullptr) || (newTable->Size() < EntriesCount())) {
|
||||
return;
|
||||
}
|
||||
int currentSize = this->Size();
|
||||
// Rehash elements to new table
|
||||
for (int i = 0; i < currentSize; i++) {
|
||||
int fromIndex = Derived::GetKeyIndex(i);
|
||||
JSTaggedValue k = this->GetKey(i);
|
||||
if (!IsKey(k)) {
|
||||
continue;
|
||||
}
|
||||
int32_t hash = static_cast<int32_t>(Derived::Hash(k));
|
||||
int insertionIndex = Derived::GetKeyIndex(newTable->FindInsertIndex(hash));
|
||||
JSTaggedValue tv = Get(fromIndex);
|
||||
newTable->Set(thread, insertionIndex, tv);
|
||||
for (int j = 1; j < Derived::GetEntrySize(); j++) {
|
||||
tv = Get(fromIndex + j);
|
||||
newTable->Set(thread, insertionIndex + j, tv);
|
||||
}
|
||||
}
|
||||
newTable->SetEntriesCount(thread, EntriesCount());
|
||||
newTable->SetHoleEntriesCount(thread, 0);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
@ -443,6 +443,7 @@ public:
|
||||
PropertyAttributes attr(metaData);
|
||||
attr.SetDictionaryOrder(enumIndex);
|
||||
attr.SetRepresentation(Representation::TAGGED);
|
||||
attr.SetDictTrackType(metaData.GetTrackType());
|
||||
int entry = table->FindEntry(key.GetTaggedValue());
|
||||
if (entry != -1) {
|
||||
table->SetEntry(thread, entry, key.GetTaggedValue(), value.GetTaggedValue(), attr);
|
||||
|
Loading…
Reference in New Issue
Block a user