diff --git a/ecmascript/object_operator.cpp b/ecmascript/object_operator.cpp index e83e772ef427927010bf17e7d70275d1c7edbd1e..325ee997ac50f9e9704e72e897bf3dd6df14e7ba 100644 --- a/ecmascript/object_operator.cpp +++ b/ecmascript/object_operator.cpp @@ -552,7 +552,7 @@ void ObjectOperator::LookupPropertyInlinedProps(const JSHandle &obj) JSTaggedValue value(dict->GetBox(entry)); auto attr = dict->GetAttributes(entry).GetValue(); - SetFound(entry, value, attr, true); + SetFound(entry, value, attr, !IsFoundDict()); return; } @@ -581,10 +581,10 @@ void ObjectOperator::LookupPropertyInlinedProps(const JSHandle &obj) value = array->Get(entry); } - SetFound(entry, value, attr.GetValue(), true); + SetFound(entry, value, attr.GetValue(), !IsFoundDict()); return; } - + SetFoundDict(true); NameDictionary *dict = NameDictionary::Cast(array); int entry = dict->FindEntry(key_.GetTaggedValue()); if (entry == -1) { @@ -985,7 +985,7 @@ void ObjectOperator::LookupElementInlinedProps(const JSHandle &obj) bool status = JSPrimitiveRef::StringGetIndexProperty(thread_, obj, elementIndex_, &desc); if (status) { PropertyAttributes attr(desc); - SetFound(elementIndex_, desc.GetValue().GetTaggedValue(), attr.GetValue(), true); + SetFound(elementIndex_, desc.GetValue().GetTaggedValue(), attr.GetValue(), !IsFoundDict()); return; } } @@ -996,7 +996,7 @@ void ObjectOperator::LookupElementInlinedProps(const JSHandle &obj) JSHandle::Cast(obj), elementIndex_).GetValue().GetTaggedValue(); RETURN_IF_ABRUPT_COMPLETION(thread_); if (!val.IsHole()) { - SetFound(elementIndex_, val, PropertyAttributes::GetDefaultAttributes(), true); + SetFound(elementIndex_, val, PropertyAttributes::GetDefaultAttributes(), !IsFoundDict()); } return; } @@ -1014,8 +1014,9 @@ void ObjectOperator::LookupElementInlinedProps(const JSHandle &obj) if (value.IsHole()) { return; } - SetFound(elementIndex_, value, PropertyAttributes::GetDefaultAttributes(), true); + SetFound(elementIndex_, value, PropertyAttributes::GetDefaultAttributes(), !IsFoundDict()); } else { + SetFoundDict(true); NumberDictionary *dictionary = NumberDictionary::Cast(obj->GetElements().GetTaggedObject()); JSTaggedValue key(static_cast(elementIndex_)); int entry = dictionary->FindEntry(key); diff --git a/ecmascript/object_operator.h b/ecmascript/object_operator.h index fc3ad4b14baa4f768bf6b245a2a6f6eca5df047c..38f507f1e956252f1581f4b4043875bd6036c804 100644 --- a/ecmascript/object_operator.h +++ b/ecmascript/object_operator.h @@ -94,6 +94,16 @@ public: IsFastModeField::Set(flag, &metaData_); } + inline void SetFoundDict(bool flag) + { + IsFoundDictField::Set(flag, &metaData_); + } + + inline bool IsFoundDict() + { + return IsFoundDictField::Get(metaData_); + } + inline bool IsElement() const { return key_.IsEmpty(); @@ -330,6 +340,8 @@ private: using HasReceiverField = IsOnPrototypeField::NextFlag; using IsTransitionField = HasReceiverField::NextFlag; using IsTSHClassField = IsTransitionField::NextFlag; + // found dictionary obj between receriver and holder + using IsFoundDictField = IsTSHClassField::NextFlag; void UpdateHolder(); void UpdateIsTSHClass(); diff --git a/test/moduletest/loadicbyname/expect_output.txt b/test/moduletest/loadicbyname/expect_output.txt index 0343d2d5ae7a3464a4dad0ef646c93be3314c090..41a40ab49652518b9752afeb8f4e19a6c5428a1c 100644 --- a/test/moduletest/loadicbyname/expect_output.txt +++ b/test/moduletest/loadicbyname/expect_output.txt @@ -29,3 +29,13 @@ SendableUint8ClampedArray set proto with sendable object failed. err: TypeError: 1 1 load global ic with accessor success! +1 +change +2 +1 +change +function Number() { [native code] } +function Number() { [native code] } +change +2 +2 diff --git a/test/moduletest/loadicbyname/loadicbyname.js b/test/moduletest/loadicbyname/loadicbyname.js index 0feed78f2d7f466d57a58105f6530e3b35e67d5f..0d60a3bd0c1fcba8c9752fca2cb21a1c75cded66 100644 --- a/test/moduletest/loadicbyname/loadicbyname.js +++ b/test/moduletest/loadicbyname/loadicbyname.js @@ -139,3 +139,77 @@ for(let i=0;i<2;i++){ print(g) } print("load global ic with accessor success!"); + +function func1(o, v) { + let res; + for (let i = 0; i < 100; i++) { + res=o.x; + if (res != v) { + print("Error"); + } + } + return res; +} +{ + let pro = { + get x() { + return 1; + } + } + let o = { + __proto__: pro + }; + o[102500] = 1; + o["test"] = "test"; + print(func1(o, 1)); + Object.defineProperty(o, "x", { value: 2 }); + print("change") + print(func1(o, 2)); +} + +{ + let pro = { + get x() { + return 1; + } + } + let pro2 = { + __proto__: pro + }; + let o = { + __proto__: pro2 + }; + pro2[102500] = 1; + pro2["test"] = "test"; + print(func1(o, 1)); + Object.defineProperty(pro2, "x", { value: 2 }); + print("change") + func1(o, 2); +} + +{ + function getNumber(o) { + let res; + for (let i = 0; i < 100; i++) { + res=o.Number; + } + return res; + } + let pro = globalThis + let pro2 = { + __proto__: pro + }; + let o = { + __proto__: pro2 + }; + pro2[102500] = 1; + pro2["test"] = "test"; + for (let i = 0; i < 2; i++) { + print(getNumber(o)) + } + Object.defineProperty(o, "Number", { value: 2 }); + print("change") + for (let i = 0; i < 2; i++) { + print(getNumber(o)) + } +} diff --git a/test/moduletest/loadicbyvalue/expect_output.txt b/test/moduletest/loadicbyvalue/expect_output.txt index bf3e662fd2cc42ee73b1a519e74da69bd4c80a2e..6a890b0018b1cb5028cf462886ff50ac2f2268b7 100644 --- a/test/moduletest/loadicbyvalue/expect_output.txt +++ b/test/moduletest/loadicbyvalue/expect_output.txt @@ -19,4 +19,10 @@ test successful !!! 4294967295 3 4294967296 4 load ic by COWArray Success +1 +change +2 +1 +change +2 ic load success diff --git a/test/moduletest/loadicbyvalue/loadicbyvalue.js b/test/moduletest/loadicbyvalue/loadicbyvalue.js index 409521ddeaffce701cbca48d652edc8c4395ce7c..7e618040201ef5374edb694a543f7fc647fd4c96 100644 --- a/test/moduletest/loadicbyvalue/loadicbyvalue.js +++ b/test/moduletest/loadicbyvalue/loadicbyvalue.js @@ -85,4 +85,37 @@ for (let i = 0; i < 100; i++) { } print("load ic by COWArray Success") +function g(o, v) { + let res; + for (let i = 0; i < 100; i++) { + res = o[1]; + if (res != v) { + print("Error ",res); + } + } + return res; +} +{ + let pro = [1,1,1,1]; + let o = { + __proto__: pro }; + o[102500] = 1; + o["test"] = "test"; + print(g(o, 1)); + Object.defineProperty(o, "1", { value: 2 }); + print("change") + print(g(o, 2)); +} +{ + let pro = new Uint8Array(10); + pro[1]=1; + let o = { + __proto__: pro }; + o[102500] = 1; + o["test"] = "test"; + print(g(o, 1)); + Object.defineProperty(o, "1", { value: 2 }); + print("change") + print(g(o, 2)); +} print("ic load success");