diff --git a/ecmascript/js_async_function.cpp b/ecmascript/js_async_function.cpp index a943ce835f..12edd5aa6d 100644 --- a/ecmascript/js_async_function.cpp +++ b/ecmascript/js_async_function.cpp @@ -106,22 +106,12 @@ void JSAsyncFunction::AsyncFunctionAwait(JSThread *thread, const JSHandle(thread, asyncFun->GetGeneratorContext()); } - // 2.Let promiseCapability be ! NewPromiseCapability(%Promise%). + // 2.Let promise be ? PromiseResolve(%Promise%, value). JSHandle env = vm->GetGlobalEnv(); - const GlobalEnvConstants *globalConst = thread->GlobalConstants(); - JSHandle pcap = - JSPromise::NewPromiseCapability(thread, JSHandle::Cast(env->GetPromiseFunction())); - - // 3.Let resolveResult be ! Call(promiseCapability.[[Resolve]], undefined, « value »). - JSHandle resolve(thread, pcap->GetResolve()); - JSHandle thisArg = globalConst->GetHandledUndefined(); - - JSHandle undefined = globalConst->GetHandledUndefined(); - EcmaRuntimeCallInfo *info = - EcmaInterpreter::NewRuntimeCallInfo(thread, resolve, thisArg, undefined, 1); - RETURN_IF_ABRUPT_COMPLETION(thread); - info->SetCallArg(value.GetTaggedValue()); - JSFunction::Call(info); + JSHandle promiseValue = + builtins::BuiltinsPromiseHandler::PromiseResolve(thread, + JSHandle::Cast(env->GetPromiseFunction()), + value); RETURN_IF_ABRUPT_COMPLETION(thread); // 4.Let onFulfilled be a new built-in function object as defined in AsyncFunction Awaited Fulfilled. JSHandle fulFunc = factory->NewJSAsyncAwaitStatusFunction( @@ -143,8 +133,9 @@ void JSAsyncFunction::AsyncFunctionAwait(JSThread *thread, const JSHandle(thread, tcap->GetPromise())->SetPromiseIsHandled(true); // 10.Perform ! PerformPromiseThen(promiseCapability.[[Promise]], onFulfilled, onRejected, throwawayCapability). - JSHandle promise(thread, pcap->GetPromise()); - BuiltinsPromise::PerformPromiseThen(thread, promise, JSHandle::Cast(fulFunc), + JSHandle promise = JSHandle::Cast(promiseValue); + BuiltinsPromise::PerformPromiseThen(thread, JSHandle::Cast(promise), + JSHandle::Cast(fulFunc), JSHandle::Cast(rejFunc), tcap); // 11.Remove asyncContext from the execution context stack and restore the execution context that diff --git a/ecmascript/stubs/runtime_stubs-inl.h b/ecmascript/stubs/runtime_stubs-inl.h index 95deaa4ea7..ca070d91d2 100644 --- a/ecmascript/stubs/runtime_stubs-inl.h +++ b/ecmascript/stubs/runtime_stubs-inl.h @@ -1289,7 +1289,7 @@ JSTaggedValue RuntimeStubs::RuntimeTryUpdateGlobalRecord(JSThread *thread, JSTag ASSERT(entry != -1); if (dict->GetAttributes(entry).IsConstProps()) { - return RuntimeThrowSyntaxError(thread, "const variable can not be modified"); + return RuntimeThrowTypeError(thread, "const variable can not be modified"); } PropertyBox *box = dict->GetBox(entry); @@ -1929,9 +1929,12 @@ JSTaggedValue RuntimeStubs::RuntimeCreateObjectWithExcludedKeys(JSThread *thread uint16_t firstArgRegIdx) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle restObj = factory->NewEmptyJSObject(); + if (objVal->IsNull() || objVal->IsUndefined()) { + return restObj.GetTaggedValue(); + } + JSHandle obj(JSTaggedValue::ToObject(thread, objVal)); - ASSERT(objVal->IsJSObject()); - JSHandle obj(objVal); uint32_t numExcludedKeys = 0; JSHandle excludedKeys = factory->NewTaggedArray(numKeys + 1); FrameHandler frameHandler(thread); @@ -1945,11 +1948,8 @@ JSTaggedValue RuntimeStubs::RuntimeCreateObjectWithExcludedKeys(JSThread *thread } } - uint32_t numAllKeys = obj->GetNumberOfKeys(); - JSHandle allKeys = factory->NewTaggedArray(numAllKeys); - JSObject::GetAllKeys(thread, obj, 0, allKeys); - - JSHandle restObj = factory->NewEmptyJSObject(); + JSHandle allKeys = JSObject::GetOwnPropertyKeys(thread, obj); + uint32_t numAllKeys = allKeys->GetLength(); JSMutableHandle key(thread, JSTaggedValue::Undefined()); for (uint32_t i = 0; i < numAllKeys; i++) { key.Update(allKeys->Get(i)); diff --git a/test/moduletest/BUILD.gn b/test/moduletest/BUILD.gn index 30a8a46ceb..52a11e8fc4 100644 --- a/test/moduletest/BUILD.gn +++ b/test/moduletest/BUILD.gn @@ -37,6 +37,7 @@ group("ark_js_moduletest") { "dynamicimport", "dyninstruction", "ecmastringtable", + "forawaitof", "forin", "fortest", "generator", diff --git a/test/moduletest/forawaitof/BUILD.gn b/test/moduletest/forawaitof/BUILD.gn new file mode 100644 index 0000000000..496f70b15e --- /dev/null +++ b/test/moduletest/forawaitof/BUILD.gn @@ -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("forawaitof") { + deps = [] +} diff --git a/test/moduletest/forawaitof/expect_output.txt b/test/moduletest/forawaitof/expect_output.txt new file mode 100644 index 0000000000..7128dc90ac --- /dev/null +++ b/test/moduletest/forawaitof/expect_output.txt @@ -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. + +true +true +true +true +1 diff --git a/test/moduletest/forawaitof/forawaitof.js b/test/moduletest/forawaitof/forawaitof.js new file mode 100644 index 0000000000..e62e695728 --- /dev/null +++ b/test/moduletest/forawaitof/forawaitof.js @@ -0,0 +1,37 @@ +/* + * 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. + */ + +/* + * @tc.name:forawaitof + * @tc.desc:test forawaitof + * @tc.type: FUNC + * @tc.require: issueI5NO8G + */ +let rest; + +let iterCount = 0; +async function fn() { + for await ({...rest} of ["foo"]) { + print(rest["0"] == "f"); + print(rest["1"] == "o"); + print(rest["2"] == "o"); + print(rest instanceof Object); + iterCount += 1; + } +} + +let promise = fn(); + +promise.then(() => print(iterCount));