mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-27 04:00:37 +00:00
!5322 Instanceof Stub FastPath && AOT Instanceof bugfix
Merge pull request !5322 from yaoyuan/instanceof
This commit is contained in:
commit
2aec2809c2
@ -4454,6 +4454,35 @@ void StubBuilder::FastSetPropertyByIndex(GateRef glue, GateRef obj, GateRef inde
|
||||
env->SubCfgExit();
|
||||
}
|
||||
|
||||
GateRef StubBuilder::GetCtorPrototype(GateRef ctor)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
env->SubCfgEntry(&entry);
|
||||
DEFVARIABLE(constructorPrototype, VariableType::JS_ANY(), Undefined());
|
||||
Label exit(env);
|
||||
Label isHClass(env);
|
||||
Label isPrototype(env);
|
||||
|
||||
GateRef ctorProtoOrHC = Load(VariableType::JS_POINTER(), ctor, IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
|
||||
Branch(IsJSHClass(ctorProtoOrHC), &isHClass, &isPrototype);
|
||||
Bind(&isHClass);
|
||||
{
|
||||
constructorPrototype = Load(VariableType::JS_POINTER(), ctorProtoOrHC, IntPtr(JSHClass::PROTOTYPE_OFFSET));
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&isPrototype);
|
||||
{
|
||||
constructorPrototype = ctorProtoOrHC;
|
||||
Jump(&exit);
|
||||
}
|
||||
|
||||
Bind(&exit);
|
||||
auto ret = *constructorPrototype;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef StubBuilder::OrdinaryHasInstance(GateRef glue, GateRef target, GateRef obj)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
@ -4503,10 +4532,32 @@ GateRef StubBuilder::OrdinaryHasInstance(GateRef glue, GateRef target, GateRef o
|
||||
Bind(&objIsEcmaObject);
|
||||
{
|
||||
// 4. Let P be Get(C, "prototype").
|
||||
auto prototypeString = GetGlobalConstantValue(
|
||||
VariableType::JS_POINTER(), glue, ConstantIndex::PROTOTYPE_STRING_INDEX);
|
||||
Label getCtorProtoSlowPath(env);
|
||||
Label ctorIsJSFunction(env);
|
||||
Label gotCtorPrototype(env);
|
||||
DEFVARIABLE(constructorPrototype, VariableType::JS_ANY(), Undefined());
|
||||
Branch(IsJSFunction(target), &ctorIsJSFunction, &getCtorProtoSlowPath);
|
||||
Bind(&ctorIsJSFunction);
|
||||
{
|
||||
Label getCtorProtoFastPath(env);
|
||||
GateRef ctorProtoOrHC = Load(VariableType::JS_POINTER(), target,
|
||||
IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
|
||||
|
||||
GateRef constructorPrototype = FastGetPropertyByName(glue, target, prototypeString, ProfileOperation());
|
||||
Branch(TaggedIsHole(ctorProtoOrHC), &getCtorProtoSlowPath, &getCtorProtoFastPath);
|
||||
Bind(&getCtorProtoFastPath);
|
||||
{
|
||||
constructorPrototype = GetCtorPrototype(target);
|
||||
Jump(&gotCtorPrototype);
|
||||
}
|
||||
}
|
||||
Bind(&getCtorProtoSlowPath);
|
||||
{
|
||||
auto prototypeString = GetGlobalConstantValue(VariableType::JS_POINTER(), glue,
|
||||
ConstantIndex::PROTOTYPE_STRING_INDEX);
|
||||
constructorPrototype = FastGetPropertyByName(glue, target, prototypeString, ProfileOperation());
|
||||
Jump(&gotCtorPrototype);
|
||||
}
|
||||
Bind(&gotCtorPrototype);
|
||||
|
||||
// 5. ReturnIfAbrupt(P).
|
||||
// no throw exception, so needn't return
|
||||
@ -4524,10 +4575,10 @@ GateRef StubBuilder::OrdinaryHasInstance(GateRef glue, GateRef target, GateRef o
|
||||
Label constructorPrototypeIsHeapObject(env);
|
||||
Label constructorPrototypeIsEcmaObject(env);
|
||||
Label constructorPrototypeNotEcmaObject(env);
|
||||
Branch(TaggedIsHeapObject(constructorPrototype), &constructorPrototypeIsHeapObject,
|
||||
Branch(TaggedIsHeapObject(*constructorPrototype), &constructorPrototypeIsHeapObject,
|
||||
&constructorPrototypeNotEcmaObject);
|
||||
Bind(&constructorPrototypeIsHeapObject);
|
||||
Branch(TaggedObjectIsEcmaObject(constructorPrototype), &constructorPrototypeIsEcmaObject,
|
||||
Branch(TaggedObjectIsEcmaObject(*constructorPrototype), &constructorPrototypeIsEcmaObject,
|
||||
&constructorPrototypeNotEcmaObject);
|
||||
Bind(&constructorPrototypeNotEcmaObject);
|
||||
{
|
||||
@ -4554,7 +4605,7 @@ GateRef StubBuilder::OrdinaryHasInstance(GateRef glue, GateRef target, GateRef o
|
||||
Branch(TaggedIsNull(*object), &afterLoop, &loopHead);
|
||||
LoopBegin(&loopHead);
|
||||
{
|
||||
GateRef isEqual = SameValue(glue, *object, constructorPrototype);
|
||||
GateRef isEqual = SameValue(glue, *object, *constructorPrototype);
|
||||
|
||||
Branch(isEqual, &strictEqual1, ¬StrictEqual1);
|
||||
Bind(&strictEqual1);
|
||||
|
@ -388,6 +388,7 @@ public:
|
||||
GateRef HclassIsTransitionHandler(GateRef hClass);
|
||||
GateRef HclassIsPropertyBox(GateRef hClass);
|
||||
GateRef PropAttrGetOffset(GateRef attr);
|
||||
GateRef GetCtorPrototype(GateRef ctor);
|
||||
GateRef InstanceOf(GateRef glue, GateRef object, GateRef target, GateRef profileTypeInfo, GateRef slotId,
|
||||
ProfileOperation callback);
|
||||
GateRef OrdinaryHasInstance(GateRef glue, GateRef target, GateRef obj);
|
||||
|
@ -2182,11 +2182,44 @@ void TypeHCRLowering::LowerOrdinaryHasInstance(GateRef gate, GateRef glue)
|
||||
builder_.Bind(&objIsEcmaObject);
|
||||
{
|
||||
// 4. Let P be Get(C, "prototype").
|
||||
// target must be a builtin function
|
||||
GateRef ctorHClass = builder_.LoadConstOffset(VariableType::JS_POINTER(), target,
|
||||
JSFunction::PROTO_OR_DYNCLASS_OFFSET);
|
||||
GateRef constructorPrototype = builder_.LoadPrototype(ctorHClass);
|
||||
Label getCtorProtoSlowPath(&builder_);
|
||||
Label ctorIsJSFunction(&builder_);
|
||||
Label gotCtorPrototype(&builder_);
|
||||
DEFVALUE(constructorPrototype, (&builder_), VariableType::JS_ANY(), builder_.Undefined());
|
||||
builder_.Branch(builder_.IsJSFunction(target), &ctorIsJSFunction, &getCtorProtoSlowPath);
|
||||
builder_.Bind(&ctorIsJSFunction);
|
||||
{
|
||||
Label getCtorProtoFastPath(&builder_);
|
||||
GateRef ctorProtoOrHC = builder_.LoadConstOffset(VariableType::JS_POINTER(), target,
|
||||
JSFunction::PROTO_OR_DYNCLASS_OFFSET);
|
||||
|
||||
builder_.Branch(builder_.TaggedIsHole(ctorProtoOrHC), &getCtorProtoSlowPath, &getCtorProtoFastPath);
|
||||
builder_.Bind(&getCtorProtoFastPath);
|
||||
{
|
||||
Label isHClass(&builder_);
|
||||
Label isPrototype(&builder_);
|
||||
builder_.Branch(builder_.IsJSHClass(ctorProtoOrHC), &isHClass, &isPrototype);
|
||||
builder_.Bind(&isHClass);
|
||||
{
|
||||
constructorPrototype = builder_.LoadConstOffset(VariableType::JS_POINTER(), ctorProtoOrHC,
|
||||
JSHClass::PROTOTYPE_OFFSET);
|
||||
builder_.Jump(&gotCtorPrototype);
|
||||
}
|
||||
builder_.Bind(&isPrototype);
|
||||
{
|
||||
constructorPrototype = ctorProtoOrHC;
|
||||
builder_.Jump(&gotCtorPrototype);
|
||||
}
|
||||
}
|
||||
}
|
||||
builder_.Bind(&getCtorProtoSlowPath);
|
||||
{
|
||||
auto prototypeString = builder_.GetGlobalConstantValue(ConstantIndex::PROTOTYPE_STRING_INDEX);
|
||||
constructorPrototype = builder_.CallRuntime(glue, RTSTUB_ID(GetPropertyByName), Gate::InvalidGateRef,
|
||||
{ target, prototypeString }, gate);
|
||||
builder_.Jump(&gotCtorPrototype);
|
||||
}
|
||||
builder_.Bind(&gotCtorPrototype);
|
||||
// 7. Repeat
|
||||
// a.Let O be O.[[GetPrototypeOf]]().
|
||||
// b.ReturnIfAbrupt(O).
|
||||
@ -2203,7 +2236,7 @@ void TypeHCRLowering::LowerOrdinaryHasInstance(GateRef gate, GateRef glue)
|
||||
builder_.Branch(builder_.TaggedIsNull(*object), &afterLoop, &loopHead);
|
||||
builder_.LoopBegin(&loopHead);
|
||||
{
|
||||
GateRef isEqual = builder_.Equal(*object, constructorPrototype);
|
||||
GateRef isEqual = builder_.Equal(*object, *constructorPrototype);
|
||||
|
||||
builder_.Branch(isEqual, &strictEqual1, ¬StrictEqual1);
|
||||
builder_.Bind(&strictEqual1);
|
||||
|
@ -2251,6 +2251,14 @@ DEF_RUNTIME_STUBS(FastCopyElementToArray)
|
||||
return JSTaggedValue(JSTypedArray::FastCopyElementToArray(thread, typedArray, array)).GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(GetPropertyByName)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(GetPropertyByName);
|
||||
JSHandle<JSTaggedValue> target = GetHArg<JSTaggedValue>(argv, argc, 0); // 0: means the zeroth parameter
|
||||
JSHandle<JSTaggedValue> key = GetHArg<JSTaggedValue>(argv, argc, 1); // 1: means the first parameter
|
||||
return JSTaggedValue::GetProperty(thread, target, key).GetValue()->GetRawData();
|
||||
}
|
||||
|
||||
DEF_RUNTIME_STUBS(DebugAOTPrint)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(DebugAOTPrint);
|
||||
|
@ -316,6 +316,7 @@ using FastCallAotEntryType = JSTaggedValue (*)(uintptr_t glue, uint32_t argc, co
|
||||
V(GetTypeArrayPropertyByIndex) \
|
||||
V(SetTypeArrayPropertyByIndex) \
|
||||
V(FastCopyElementToArray) \
|
||||
V(GetPropertyByName) \
|
||||
V(JSObjectGetMethod) \
|
||||
V(DebugAOTPrint) \
|
||||
V(ProfileOptimizedCode) \
|
||||
|
@ -22,6 +22,9 @@ true
|
||||
false
|
||||
true
|
||||
true
|
||||
false
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
|
@ -67,6 +67,16 @@ function test5() {
|
||||
}
|
||||
test5();
|
||||
|
||||
function foo() {};
|
||||
function bar() {};
|
||||
const proxy = new Proxy(foo, {});
|
||||
|
||||
let f = new foo();
|
||||
|
||||
print(f instanceof foo); // true
|
||||
print(f instanceof proxy); // true
|
||||
print(f instanceof bar); // false
|
||||
|
||||
print(ArkTools.isAOTCompiled(test1));
|
||||
print(ArkTools.isAOTCompiled(test2));
|
||||
print(ArkTools.isAOTCompiled(test3));
|
||||
|
Loading…
Reference in New Issue
Block a user