Reason:optmize delete property

Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I8NI8E?from=project-issue

Signed-off-by: wupengyong <wupengyong@huawei.com>
Change-Id: I30585bf08d358f419b2d52d6bdcc5d8f9ad0a5af
This commit is contained in:
wupengyong 2023-12-12 16:58:41 +08:00
parent 6fd33864e4
commit 3998151f3b
7 changed files with 149 additions and 91 deletions

View File

@ -6210,30 +6210,34 @@ GateRef StubBuilder::DeletePropertyOrThrow(GateRef glue, GateRef obj, GateRef va
Label entry(env);
env->SubCfgEntry(&entry);
Label exit(env);
DEFVARIABLE(result, VariableType::JS_ANY(), Hole());
DEFVARIABLE(result, VariableType::JS_ANY(), Exception());
DEFVARIABLE(key, VariableType::JS_ANY(), value);
Label toObject(env);
Label isException(env);
Label isNotExceptiont(env);
Label objectIsEcmaObject(env);
Label objectIsHeapObject(env);
GateRef object = ToObject(glue, obj);
Branch(HasPendingException(glue), &isException, &isNotExceptiont);
Branch(TaggedIsException(object), &exit, &isNotExceptiont);
Bind(&isNotExceptiont);
Branch(TaggedIsHeapObject(object), &objectIsHeapObject, &isException);
Bind(&objectIsHeapObject);
Branch(TaggedObjectIsEcmaObject(object), &objectIsEcmaObject, &isException);
Bind(&objectIsEcmaObject);
{
GateRef keyValue = CallRuntime(glue, RTSTUB_ID(ToPropertyKey), {value});
result = DeleteProperty(glue, obj, keyValue);
Jump(&exit);
}
Bind(&isException);
{
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(CanNotConvertNotValidObject));
CallRuntime(glue, RTSTUB_ID(ThrowTypeError), { IntToTaggedInt(taggedId) });
result = Exception();
Jump(&exit);
Label deleteProper(env);
Label notStringOrSymbol(env);
Label notPrimitive(env);
Branch(TaggedIsStringOrSymbol(value), &deleteProper, &notStringOrSymbol);
Bind(&notStringOrSymbol);
{
Branch(TaggedIsNumber(value), &deleteProper, &notPrimitive);
Bind(&notPrimitive);
{
key = CallRuntime(glue, RTSTUB_ID(ToPropertyKey), {value});
Branch(TaggedIsException(*key), &exit, &deleteProper);
}
}
Bind(&deleteProper);
{
result = DeleteProperty(glue, object, *key);
Jump(&exit);
}
}
Bind(&exit);
auto ret = *result;
@ -6248,48 +6252,20 @@ GateRef StubBuilder::DeleteProperty(GateRef glue, GateRef obj, GateRef value)
env->SubCfgEntry(&entry);
DEFVARIABLE(result, VariableType::JS_ANY(), Hole());
Label exit(env);
Label objectIsJsProxy(env);
Label objectIsNotJsProxy(env);
Label objectIsModuleNamespace(env);
Label objectIsNotModuleNamespace(env);
Label objectIsTypedArray(env);
Label objectIsNotTypedArray(env);
Label objectIsSpecialContainer(env);
Label objectIsNotSpecialContainer(env);
Branch(IsJsProxy(obj), &objectIsJsProxy, &objectIsNotJsProxy);
Bind(&objectIsJsProxy);
Label notRegularJSObject(env);
Label regularJSObjDeletePrototype(env);
Branch(TaggedIsRegularObject(obj), &regularJSObjDeletePrototype, &notRegularJSObject);
Bind(&regularJSObjDeletePrototype);
{
result = CallRuntime(glue, RTSTUB_ID(CallJSDeleteProxyPrototype), { obj, value});
result = CallRuntime(glue, RTSTUB_ID(RegularJSObjDeletePrototype), { obj, value});
Jump(&exit);
}
Bind(&objectIsNotJsProxy);
Branch(IsModuleNamespace(obj), &objectIsModuleNamespace, &objectIsNotModuleNamespace);
Bind(&objectIsModuleNamespace);
{
result = CallRuntime(glue, RTSTUB_ID(CallModuleNamespaceDeletePrototype), { obj, value});
Jump(&exit);
}
Bind(&objectIsNotModuleNamespace);
Branch(IsTypedArray(obj), &objectIsTypedArray, &objectIsNotTypedArray);
Bind(&objectIsTypedArray);
{
result = CallRuntime(glue, RTSTUB_ID(CallTypedArrayDeletePrototype), { obj, value});
Jump(&exit);
}
Bind(&objectIsNotTypedArray);
Branch(ObjIsSpecialContainer(obj), &objectIsSpecialContainer, &objectIsNotSpecialContainer);
Bind(&objectIsSpecialContainer);
{
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(CanNotConvertContainerObject));
CallRuntime(glue, RTSTUB_ID(ThrowTypeError), { IntToTaggedInt(taggedId) });
result = Exception();
Jump(&exit);
}
Bind(&objectIsNotSpecialContainer);
Bind(&notRegularJSObject);
{
result = CallRuntime(glue, RTSTUB_ID(CallJSObjDeletePrototype), { obj, value});
Jump(&exit);
}
Bind(&exit);
auto ret = *result;
env->SubCfgExit();

View File

@ -652,42 +652,27 @@ DEF_RUNTIME_STUBS(CallGetPrototype)
return JSProxy::GetPrototype(thread, proxy).GetRawData();
}
DEF_RUNTIME_STUBS(CallJSDeleteProxyPrototype)
DEF_RUNTIME_STUBS(RegularJSObjDeletePrototype)
{
RUNTIME_STUBS_HEADER(CallJSDeleteProxyPrototype);
JSHandle<JSProxy> proxy = GetHArg<JSProxy>(argv, argc, 0); // 0: means the zeroth parameter
JSHandle<JSTaggedValue> value = GetHArg<JSTaggedValue>(argv, argc, 1);
auto result = JSProxy::DeleteProperty(thread, proxy, value);
if (!result) {
auto factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSObject> error = factory->GetJSError(ErrorType::TYPE_ERROR, "Cannot delete property");
thread->SetException(error.GetTaggedValue());
return JSTaggedValue::Exception().GetRawData();
RUNTIME_STUBS_HEADER(CallJSObjDeletePrototype);
JSHandle<JSObject> tagged = GetHArg<JSObject>(argv, argc, 0); // 0: means the zeroth parameter
JSTaggedValue value = GetArg(argv, argc, 1);
uint32_t index = 0;
if (value.IsString()) {
auto string = reinterpret_cast<EcmaString *>(value.GetTaggedObject());
if (EcmaStringAccessor(string).ToElementIndex(&index)) {
value = JSTaggedValue(index);
} else if (!EcmaStringAccessor(string).IsInternString()) {
JSTaggedValue key(RuntimeTryGetInternString(argGlue, string));
if (key.IsHole()) {
return JSTaggedValue::True().GetRawData();
} else {
value = key;
}
}
}
return JSTaggedValue::True().GetRawData();
}
DEF_RUNTIME_STUBS(CallModuleNamespaceDeletePrototype)
{
RUNTIME_STUBS_HEADER(CallModuleNamespaceDeletePrototype);
JSHandle<JSTaggedValue> obj = GetHArg<JSTaggedValue>(argv, argc, 0); // 0: means the zeroth parameter
JSHandle<JSTaggedValue> value = GetHArg<JSTaggedValue>(argv, argc, 1);
auto result = ModuleNamespace::DeleteProperty(thread, obj, value);
if (!result) {
auto factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSObject> error = factory->GetJSError(ErrorType::TYPE_ERROR, "Cannot delete property");
thread->SetException(error.GetTaggedValue());
return JSTaggedValue::Exception().GetRawData();
}
return JSTaggedValue::True().GetRawData();
}
DEF_RUNTIME_STUBS(CallTypedArrayDeletePrototype)
{
RUNTIME_STUBS_HEADER(CallTypedArrayDeletePrototype);
JSHandle<JSTaggedValue> tagged = GetHArg<JSTaggedValue>(argv, argc, 0); // 0: means the zeroth parameter
JSHandle<JSTaggedValue> value = GetHArg<JSTaggedValue>(argv, argc, 1);
auto result = JSTypedArray::DeleteProperty(thread, tagged, value);
auto result = JSObject::DeleteProperty(thread, tagged, JSHandle<JSTaggedValue>(thread, value));
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception().GetRawData());
if (!result) {
auto factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSObject> error = factory->GetJSError(ErrorType::TYPE_ERROR, "Cannot delete property");
@ -700,9 +685,10 @@ DEF_RUNTIME_STUBS(CallTypedArrayDeletePrototype)
DEF_RUNTIME_STUBS(CallJSObjDeletePrototype)
{
RUNTIME_STUBS_HEADER(CallJSObjDeletePrototype);
JSHandle<JSObject> tagged = GetHArg<JSObject>(argv, argc, 0); // 0: means the zeroth parameter
JSHandle<JSTaggedValue> tagged = GetHArg<JSTaggedValue>(argv, argc, 0); // 0: means the zeroth parameter
JSHandle<JSTaggedValue> value = GetHArg<JSTaggedValue>(argv, argc, 1);
auto result = JSObject::DeleteProperty(thread, tagged, value);
auto result = JSTaggedValue::DeleteProperty(thread, tagged, value);
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception().GetRawData());
if (!result) {
auto factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSObject> error = factory->GetJSError(ErrorType::TYPE_ERROR, "Cannot delete property");

View File

@ -147,9 +147,7 @@ using FastCallAotEntryType = JSTaggedValue (*)(uintptr_t glue, uint32_t argc, co
V(CallInternalGetter) \
V(CallInternalSetter) \
V(CallGetPrototype) \
V(CallJSDeleteProxyPrototype) \
V(CallModuleNamespaceDeletePrototype) \
V(CallTypedArrayDeletePrototype) \
V(RegularJSObjDeletePrototype) \
V(CallJSObjDeletePrototype) \
V(ToPropertyKey) \
V(NewJSPrimitiveRef) \

View File

@ -55,6 +55,7 @@ group("ark_js_moduletest") {
"dateparse",
"decodeuricomponent",
"definefunc",
"deleteobjproperty",
"div",
"dynamicimport",
"dyninstruction",
@ -208,6 +209,7 @@ group("ark_asm_test") {
"dateparse",
"decodeuricomponent",
"definefunc",
"deleteobjproperty",
"div",
"dynamicimport",
"dyninstruction",

View File

@ -0,0 +1,18 @@
# 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.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_moduletest_action("deleteobjproperty") {
deps = []
}

View File

@ -0,0 +1,58 @@
/*
* 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.
*/
let a = {jj:"kaifa", wo:"tian"};
Object.defineProperty(a, 'myname', {
configurable:false,
value:222
});
var str = 'j' + 'j';
var b = undefined;
var l = new ArrayBuffer(400);
var v1 = new Int32Array(l);
var Stack = ArkPrivate.Load(ArkPrivate.Stack);
var stack = new Stack();
delete a[str];
try {
print(delete a.hhh);
} catch (e){
print(e);
}
try {
print(delete b.kk);
} catch (e){
print(e);
}
try {
var str1 = 'my' + 'name';
print(delete a[str1]);
} catch (e){
print(e);
}
try {
print(delete v1[1000]);
} catch (e){
print(e);
}
try {
print(delete stack[1000]);
} catch (e){
print(e);
}
print(a.myname);
print(a.jj);

View File

@ -0,0 +1,20 @@
# 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.
true
TypeError: Cannot convert a UNDEFINED value to a JSObject
TypeError: Cannot delete property
true
TypeError: Can not delete property in Container Object
222
undefined