From 7d03d26f267a70160d626e4dfb99d9a427613d9b Mon Sep 17 00:00:00 2001 From: vagin ivan Date: Wed, 13 Jul 2022 16:56:25 +0300 Subject: [PATCH] [runtime] Fix ecmascript bugs Change-Id: I7e3905a21afb436dfd059386cffb8cca339eb03e Signed-off-by: vagin ivan --- runtime/base/typed_array_helper.cpp | 12 +++--- runtime/base/typed_array_helper.h | 2 +- runtime/builtins/builtins_array.cpp | 12 +++++- runtime/ic/ic_runtime.cpp | 16 +++++++- runtime/interpreter/slow_runtime_stub.cpp | 8 +++- runtime/js_array_iterator.cpp | 6 ++- runtime/js_tagged_value.cpp | 4 +- runtime/tagged_array-inl.h | 4 +- tests/runtime/common/CMakeLists.txt | 4 ++ tests/runtime/common/js_arrays/CMakeLists.txt | 22 +++++++++++ tests/runtime/common/js_arrays/js_arrays.js | 22 +++++++++++ tests/runtime/common/js_arrays/verify.sh | 24 ++++++++++++ .../common/js_typed_arrays/CMakeLists.txt | 22 +++++++++++ .../common/js_typed_arrays/js_typed_arrays.js | 28 ++++++++++++++ .../runtime/common/js_typed_arrays/verify.sh | 23 ++++++++++++ .../common/recursive_array/CMakeLists.txt | 22 +++++++++++ .../common/recursive_array/recursive_array.js | 12 ++++++ .../runtime/common/recursive_array/verify.sh | 19 ++++++++++ .../common/spread_primitives/CMakeLists.txt | 22 +++++++++++ .../spread_primitives/spread_primitives.js | 22 +++++++++++ .../common/spread_primitives/verify.sh | 37 +++++++++++++++++++ 21 files changed, 328 insertions(+), 15 deletions(-) create mode 100644 tests/runtime/common/js_arrays/CMakeLists.txt create mode 100644 tests/runtime/common/js_arrays/js_arrays.js create mode 100644 tests/runtime/common/js_arrays/verify.sh create mode 100644 tests/runtime/common/js_typed_arrays/CMakeLists.txt create mode 100644 tests/runtime/common/js_typed_arrays/js_typed_arrays.js create mode 100644 tests/runtime/common/js_typed_arrays/verify.sh create mode 100644 tests/runtime/common/recursive_array/CMakeLists.txt create mode 100644 tests/runtime/common/recursive_array/recursive_array.js create mode 100644 tests/runtime/common/recursive_array/verify.sh create mode 100644 tests/runtime/common/spread_primitives/CMakeLists.txt create mode 100644 tests/runtime/common/spread_primitives/spread_primitives.js create mode 100644 tests/runtime/common/spread_primitives/verify.sh diff --git a/runtime/base/typed_array_helper.cpp b/runtime/base/typed_array_helper.cpp index 776da6e7d..979ec7601 100644 --- a/runtime/base/typed_array_helper.cpp +++ b/runtime/base/typed_array_helper.cpp @@ -55,12 +55,12 @@ JSTaggedValue TypedArrayHelper::TypedArrayConstructor(EcmaRuntimeCallInfo *argv, JSHandle firstArg = BuiltinsBase::GetCallArg(argv, 0); if (!firstArg->IsECMAObject()) { // es11 22.2.4.1 TypedArray ( ) - int32_t elementLength = 0; + double elementLength = 0; // es11 22.2.4.2 TypedArray ( length ) if (!firstArg->IsUndefined()) { JSTaggedNumber index = JSTaggedValue::ToIndex(thread, firstArg); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - elementLength = static_cast(index.GetNumber()); + elementLength = index.GetNumber(); } JSHandle obj = TypedArrayHelper::AllocateTypedArray(factory, ecmaVm, constructorName, newTarget, elementLength); @@ -198,9 +198,9 @@ JSTaggedValue TypedArrayHelper::CreateFromTypedArray(EcmaRuntimeCallInfo *argv, // 13. Let srcByteOffset be srcArray.[[ByteOffset]]. // 14. Let elementSize be the Element Size value specified in Table 61 for constructorName. // 15. Let byteLength be elementSize × elementLength. - int32_t srcByteOffset = TypedArrayHelper::GetByteOffset(thread, srcObj); - int32_t elementSize = TypedArrayHelper::GetSizeFromName(thread, constructorName); - int32_t byteLength = elementSize * elementLength; + double srcByteOffset = TypedArrayHelper::GetByteOffset(thread, srcObj); + double elementSize = TypedArrayHelper::GetSizeFromName(thread, constructorName); + double byteLength = elementSize * elementLength; // 16. If IsSharedArrayBuffer(srcData) is false, then // a. Let bufferConstructor be ? SpeciesConstructor(srcData, %ArrayBuffer%). @@ -358,7 +358,7 @@ JSHandle TypedArrayHelper::AllocateTypedArray(ObjectFactory *factory, // es11 22.2.4.2.1 Runtime Semantics: AllocateTypedArray ( constructorName, newTarget, defaultProto, length ) JSHandle TypedArrayHelper::AllocateTypedArray(ObjectFactory *factory, EcmaVM *ecmaVm, const JSHandle &constructorName, - const JSHandle &newTarget, int32_t length) + const JSHandle &newTarget, double length) { JSThread *thread = ecmaVm->GetJSThread(); // 1. Let proto be ? GetPrototypeFromConstructor(newTarget, defaultProto). diff --git a/runtime/base/typed_array_helper.h b/runtime/base/typed_array_helper.h index 3bc635611..accbb6e37 100644 --- a/runtime/base/typed_array_helper.h +++ b/runtime/base/typed_array_helper.h @@ -33,7 +33,7 @@ public: const JSHandle &newTarget); static JSHandle AllocateTypedArray(ObjectFactory *factory, EcmaVM *ecmaVm, const JSHandle &constructorName, - const JSHandle &newTarget, int32_t length); + const JSHandle &newTarget, double length); static JSHandle TypedArraySpeciesCreate(JSThread *thread, const JSHandle &obj, uint32_t argc, const JSTaggedType argv[] // NOLINT(modernize-avoid-c-arrays) ); diff --git a/runtime/builtins/builtins_array.cpp b/runtime/builtins/builtins_array.cpp index 77e598e0a..90b069819 100644 --- a/runtime/builtins/builtins_array.cpp +++ b/runtime/builtins/builtins_array.cpp @@ -1081,8 +1081,8 @@ JSTaggedValue BuiltinsArray::Find(EcmaRuntimeCallInfo *argv) arguments->MakeArgv(kValue, key, thisObjVal); JSTaggedValue callResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, 3, arguments->GetArgv()); // 3: three args - bool boolResult = callResult.ToBoolean(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + bool boolResult = callResult.ToBoolean(); if (boolResult) { return kValue.GetTaggedValue(); } @@ -1377,6 +1377,16 @@ JSTaggedValue BuiltinsArray::Join(EcmaRuntimeCallInfo *argv) JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle thisHandle = GetThis(argv); + + // Prevent inifinity joining of recursive arrays + static std::vector visited_stack = {}; + if (std::find(visited_stack.begin(), visited_stack.end(), thisHandle->GetRawData()) != visited_stack.end()) { + return GetTaggedString(thread, ""); + } + visited_stack.push_back(thisHandle->GetRawData()); + auto unvisit = std::unique_ptr>( + reinterpret_cast(1), [&](void * /* unused */) { visited_stack.pop_back(); }); + if (thisHandle->IsStableJSArray(thread)) { return JSStableArray::Join(JSHandle::Cast(thisHandle), argv); } diff --git a/runtime/ic/ic_runtime.cpp b/runtime/ic/ic_runtime.cpp index d7b719f7c..3c72fc28d 100644 --- a/runtime/ic/ic_runtime.cpp +++ b/runtime/ic/ic_runtime.cpp @@ -172,8 +172,12 @@ JSTaggedValue StoreICRuntime::StoreMiss(JSHandle receiver, JSHand JSHandle value) { if (receiver->IsTypedArray() || !receiver->IsJSObject()) { - bool success = JSTaggedValue::SetProperty(GetThread(), receiver, key, value, true); - return success ? JSTaggedValue::Undefined() : JSTaggedValue::Exception(); + if (UNLIKELY(!JSTaggedValue::IsPropertyKey(key))) { + key = JSHandle(JSTaggedValue::ToString(thread_, key)); + } + JSTaggedValue::SetProperty(GetThread(), receiver, key, value, true); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(GetThread()); + return JSTaggedValue::Undefined(); } // global variable find from global record firstly @@ -200,8 +204,16 @@ JSTaggedValue StoreICRuntime::StoreMiss(JSHandle receiver, JSHand UpdateReceiverHClass(JSHandle(GetThread(), JSHandle::Cast(receiver)->GetClass())); ObjectOperator op(GetThread(), receiver, key); + JSHandle old_hc(thread_, JSObject::Cast(receiver.GetTaggedValue())->GetJSHClass()); bool success = JSObject::SetProperty(&op, value, true); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); + + auto new_hc = JSObject::Cast(receiver.GetTaggedValue())->GetJSHClass(); + // Update object operator if there was transition to dictionary mode + if (UNLIKELY(!old_hc->IsDictionaryMode() && new_hc->IsDictionaryMode())) { + op = ObjectOperator(GetThread(), receiver, key); + } + if (!success && (GetICKind() == ICKind::NAMED_GLOBAL_STORE_IC || GetICKind() == ICKind::TRY_NAMED_GLOBAL_STORE_IC)) { return SlowRuntimeStub::ThrowReferenceError(GetThread(), key.GetTaggedValue(), " is not defined"); diff --git a/runtime/interpreter/slow_runtime_stub.cpp b/runtime/interpreter/slow_runtime_stub.cpp index 17baf84df..db5561809 100644 --- a/runtime/interpreter/slow_runtime_stub.cpp +++ b/runtime/interpreter/slow_runtime_stub.cpp @@ -1591,7 +1591,13 @@ JSTaggedValue SlowRuntimeStub::StArraySpread(JSThread *thread, JSTaggedValue dst JSHandle dstHandle(thread, dst); JSHandle srcHandle(thread, src); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - ASSERT(dstHandle->IsJSArray() && !srcHandle->IsNull() && !srcHandle->IsUndefined()); + if (srcHandle->IsUndefined()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "undefined is not iterable", JSTaggedValue::Exception()); + } + if (srcHandle->IsNull()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "null is not iterable", JSTaggedValue::Exception()); + } + ASSERT(dstHandle->IsJSArray()); if (srcHandle->IsString()) { JSHandle srcString = JSTaggedValue::ToString(thread, srcHandle); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); diff --git a/runtime/js_array_iterator.cpp b/runtime/js_array_iterator.cpp index 605401a92..7c45ad932 100644 --- a/runtime/js_array_iterator.cpp +++ b/runtime/js_array_iterator.cpp @@ -59,7 +59,11 @@ JSTaggedValue JSArrayIterator::Next(EcmaRuntimeCallInfo *argv) } else { // 9.Else JSHandle lengthKey = thread->GlobalConstants()->GetHandledLengthString(); - length = JSTaggedValue::GetProperty(thread, array, lengthKey).GetValue()->GetArrayLength(); + JSHandle taggedLen = JSTaggedValue::GetProperty(thread, array, lengthKey).GetValue(); + if (UNLIKELY(!taggedLen->IsNumber())) { + return JSIterator::CreateIterResultObject(thread, undefinedHandle, true).GetTaggedValue(); + } + length = taggedLen->GetArrayLength(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } diff --git a/runtime/js_tagged_value.cpp b/runtime/js_tagged_value.cpp index 879dfedd3..00944e294 100644 --- a/runtime/js_tagged_value.cpp +++ b/runtime/js_tagged_value.cpp @@ -633,7 +633,7 @@ bool JSTaggedValue::GetOwnProperty(JSThread *thread, const JSHandleIsSpecialContainer()) { return GetContainerProperty(thread, obj, key, desc); } - return JSObject::GetOwnProperty(thread, JSHandle(obj), key, desc); + return JSObject::GetOwnProperty(thread, JSTaggedValue::ToObject(thread, obj), key, desc); } bool JSTaggedValue::SetPrototype(JSThread *thread, const JSHandle &obj, @@ -668,7 +668,7 @@ JSHandle JSTaggedValue::GetOwnPropertyKeys(JSThread *thread, const if (obj->IsSpecialContainer()) { return GetOwnContainerPropertyKeys(thread, obj); } - return JSObject::GetOwnPropertyKeys(thread, JSHandle(obj)); + return JSObject::GetOwnPropertyKeys(thread, JSTaggedValue::ToObject(thread, obj)); } // 7.3.10 HasProperty (O, P) diff --git a/runtime/tagged_array-inl.h b/runtime/tagged_array-inl.h index 44a123dfb..78087d84f 100644 --- a/runtime/tagged_array-inl.h +++ b/runtime/tagged_array-inl.h @@ -23,7 +23,9 @@ namespace panda::ecmascript { inline JSTaggedValue TaggedArray::Get(uint32_t idx) const { - ASSERT(idx < GetLength()); + if (UNLIKELY(idx >= GetLength())) { + return JSTaggedValue::Hole(); + } // Note: Here we can't statically decide the element type is a primitive or heap object, especially for // dynamically-typed languages like JavaScript. So we simply skip the read-barrier. size_t offset = JSTaggedValue::TaggedTypeSize() * idx; diff --git a/tests/runtime/common/CMakeLists.txt b/tests/runtime/common/CMakeLists.txt index 213d66288..d6221d3ac 100644 --- a/tests/runtime/common/CMakeLists.txt +++ b/tests/runtime/common/CMakeLists.txt @@ -5,6 +5,8 @@ add_subdirectory(helloworld) add_subdirectory(newobjdynrange) add_subdirectory(bitwiseop) add_subdirectory(big_file) +add_subdirectory(js_arrays) +add_subdirectory(js_typed_arrays) add_subdirectory(dyninstruction) add_subdirectory(throwdyn) add_subdirectory(getunmappedargs) @@ -18,8 +20,10 @@ add_subdirectory(yieldstar) add_subdirectory(class) add_subdirectory(multiargs) add_subdirectory(fortest) +add_subdirectory(recursive_array) add_subdirectory(returnundefined) add_subdirectory(sieve) +add_subdirectory(spread_primitives) add_subdirectory(strictequal) add_subdirectory(restargs) add_subdirectory(native_methods_api_no_crash) diff --git a/tests/runtime/common/js_arrays/CMakeLists.txt b/tests/runtime/common/js_arrays/CMakeLists.txt new file mode 100644 index 000000000..51168dc4d --- /dev/null +++ b/tests/runtime/common/js_arrays/CMakeLists.txt @@ -0,0 +1,22 @@ +# Huawei Technologies Co.,Ltd. + +set(JS_ARRAYS_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/js_arrays.txt) +set(JS_ARRAYS_BIN ${CMAKE_CURRENT_BINARY_DIR}/js_arrays.abc) +set(JS_ARRAYS_JS ${CMAKE_CURRENT_SOURCE_DIR}/js_arrays.js) +set(JS_ARRAYS_VERIFY ${CMAKE_CURRENT_SOURCE_DIR}/verify.sh) + +set(RUNTIME_ARGUMENTS --boot-panda-files=${CMAKE_BINARY_DIR}/pandastdlib/arkstdlib.abc --boot-class-spaces=\"ecmascript\" --compiler-enable-jit=false --gc-type=stw --run-gc-in-place --runtime-type \"ecmascript\" ${JS_ARRAYS_BIN} _GLOBAL::func_main_0) + +add_custom_command( + OUTPUT ${JS_ARRAYS_OUTPUT} + COMMENT "running javascript js_arrays testcase" + COMMAND ${PANDA_RUN_PREFIX} $ ${JS_ARRAYS_JS} --output ${JS_ARRAYS_BIN} + COMMAND rm -f ${JS_ARRAYS_OUTPUT} + COMMAND ${PANDA_RUN_PREFIX} $ ${RUNTIME_ARGUMENTS} 2>&1 > ${JS_ARRAYS_OUTPUT} + COMMAND bash ${JS_ARRAYS_VERIFY} ${JS_ARRAYS_OUTPUT} +) +add_custom_target(js_arrays + DEPENDS ${JS_ARRAYS_OUTPUT} ${JS_ARRAYS_VERIFY} +) +add_dependencies(js_arrays es2panda ark) +add_dependencies(ecmascript_common_tests js_arrays) diff --git a/tests/runtime/common/js_arrays/js_arrays.js b/tests/runtime/common/js_arrays/js_arrays.js new file mode 100644 index 000000000..7e8972d26 --- /dev/null +++ b/tests/runtime/common/js_arrays/js_arrays.js @@ -0,0 +1,22 @@ +let a = Array(8); +print(a.slice()); +print(a.join()); + +let b = []; +b.length = 1025; +print(b.length); + +let c = {"__proto__": [], "length": "InvalidLength"}; +print([...c]); +print(c.join()); +print(c.length); +c.push(322); +print(c.join()); +print(c.length); + +let d = new Float64Array(9); +try { + d.find(Float64Array); +} catch (e) { + print(e); +} diff --git a/tests/runtime/common/js_arrays/verify.sh b/tests/runtime/common/js_arrays/verify.sh new file mode 100644 index 000000000..2d5d968f3 --- /dev/null +++ b/tests/runtime/common/js_arrays/verify.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. + +set -eo pipefail + +expected=",,,,,,, +,,,,,,, +1025 + + +InvalidLength +322 +1 +TypeError: The NewTarget is undefined." + +actual=$(cat "$1") +if [[ "$actual" == "$expected" ]];then + exit 0; +else + echo -e "expected:"$expected + echo -e "actual:"$actual + echo -e "\033[31mrestargstest failed\033[0m" + exit 1; +fi diff --git a/tests/runtime/common/js_typed_arrays/CMakeLists.txt b/tests/runtime/common/js_typed_arrays/CMakeLists.txt new file mode 100644 index 000000000..fec452855 --- /dev/null +++ b/tests/runtime/common/js_typed_arrays/CMakeLists.txt @@ -0,0 +1,22 @@ +# Huawei Technologies Co.,Ltd. + +set(JS_TYPED_ARRAYS_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/js_typed_arrays.txt) +set(JS_TYPED_ARRAYS_BIN ${CMAKE_CURRENT_BINARY_DIR}/js_typed_arrays.abc) +set(JS_TYPED_ARRAYS_JS ${CMAKE_CURRENT_SOURCE_DIR}/js_typed_arrays.js) +set(JS_TYPED_ARRAYS_VERIFY ${CMAKE_CURRENT_SOURCE_DIR}/verify.sh) + +set(RUNTIME_ARGUMENTS --boot-panda-files=${CMAKE_BINARY_DIR}/pandastdlib/arkstdlib.abc --boot-class-spaces=\"ecmascript\" --compiler-enable-jit=false --gc-type=stw --run-gc-in-place --runtime-type \"ecmascript\" ${JS_TYPED_ARRAYS_BIN} _GLOBAL::func_main_0) + +add_custom_command( + OUTPUT ${JS_TYPED_ARRAYS_OUTPUT} + COMMENT "running javascript js_typed_arrays testcase" + COMMAND ${PANDA_RUN_PREFIX} $ ${JS_TYPED_ARRAYS_JS} --output ${JS_TYPED_ARRAYS_BIN} + COMMAND rm -f ${JS_TYPED_ARRAYS_OUTPUT} + COMMAND ${PANDA_RUN_PREFIX} $ ${RUNTIME_ARGUMENTS} 2>&1 > ${JS_TYPED_ARRAYS_OUTPUT} + COMMAND bash ${JS_TYPED_ARRAYS_VERIFY} ${JS_TYPED_ARRAYS_OUTPUT} +) +add_custom_target(js_typed_arrays + DEPENDS ${JS_TYPED_ARRAYS_OUTPUT} ${JS_TYPED_ARRAYS_VERIFY} +) +add_dependencies(js_typed_arrays es2panda ark) +add_dependencies(ecmascript_common_tests js_typed_arrays) diff --git a/tests/runtime/common/js_typed_arrays/js_typed_arrays.js b/tests/runtime/common/js_typed_arrays/js_typed_arrays.js new file mode 100644 index 000000000..9a001ac77 --- /dev/null +++ b/tests/runtime/common/js_typed_arrays/js_typed_arrays.js @@ -0,0 +1,28 @@ +let a = new Uint8Array(10); +a['aa'] = 1; +a[0] = 2; +a[20] = 3; +a[-1] = 4; +print(a['aa']); +print(a[-1]); +print(a[0]); +print(a[20]); + +try { + new Uint8ClampedArray(3122127621); +} catch (e) { + print(e); +} + +let b = new Float32Array(); +b[Float32Array] = Float32Array; +for (let k of Object.keys(b)) { + print(k); + print(b[k]); +} + +try { + new Uint32Array(new Uint16Array(1000000000.0)); +} catch (e) { + print(e); +} diff --git a/tests/runtime/common/js_typed_arrays/verify.sh b/tests/runtime/common/js_typed_arrays/verify.sh new file mode 100644 index 000000000..d6121e7aa --- /dev/null +++ b/tests/runtime/common/js_typed_arrays/verify.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. + +set -eo pipefail + +expected="1 +undefined +2 +undefined +RangeError: Out of range +Not support function.toString() due to Runtime can not obtain Source Code yet. +Not support function.toString() due to Runtime can not obtain Source Code yet. +RangeError: Out of range" + +actual=$(cat "$1") +if [[ "$actual" == "$expected" ]];then + exit 0; +else + echo -e "expected:"$expected + echo -e "actual:"$actual + echo -e "\033[31mrestargstest failed\033[0m" + exit 1; +fi diff --git a/tests/runtime/common/recursive_array/CMakeLists.txt b/tests/runtime/common/recursive_array/CMakeLists.txt new file mode 100644 index 000000000..c99e4cc99 --- /dev/null +++ b/tests/runtime/common/recursive_array/CMakeLists.txt @@ -0,0 +1,22 @@ +# Huawei Technologies Co.,Ltd. + +set(RECURSIVE_ARRAY_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/recursive_array.txt) +set(RECURSIVE_ARRAY_BIN ${CMAKE_CURRENT_BINARY_DIR}/recursive_array.abc) +set(RECURSIVE_ARRAY_JS ${CMAKE_CURRENT_SOURCE_DIR}/recursive_array.js) +set(RECURSIVE_ARRAY_VERIFY ${CMAKE_CURRENT_SOURCE_DIR}/verify.sh) + +set(RUNTIME_ARGUMENTS --boot-panda-files=${CMAKE_BINARY_DIR}/pandastdlib/arkstdlib.abc --boot-class-spaces=\"ecmascript\" --compiler-enable-jit=false --gc-type=stw --run-gc-in-place --runtime-type \"ecmascript\" ${RECURSIVE_ARRAY_BIN} _GLOBAL::func_main_0) + +add_custom_command( + OUTPUT ${RECURSIVE_ARRAY_OUTPUT} + COMMENT "running javascript recursive_array testcase" + COMMAND ${PANDA_RUN_PREFIX} $ ${RECURSIVE_ARRAY_JS} --output ${RECURSIVE_ARRAY_BIN} + COMMAND rm -f ${RECURSIVE_ARRAY_OUTPUT} + COMMAND ${PANDA_RUN_PREFIX} $ ${RUNTIME_ARGUMENTS} 2>&1 > ${RECURSIVE_ARRAY_OUTPUT} + COMMAND bash ${RECURSIVE_ARRAY_VERIFY} ${RECURSIVE_ARRAY_OUTPUT} +) +add_custom_target(recursive_array + DEPENDS ${RECURSIVE_ARRAY_OUTPUT} ${RECURSIVE_ARRAY_VERIFY} +) +add_dependencies(recursive_array es2panda ark) +add_dependencies(ecmascript_common_tests recursive_array) diff --git a/tests/runtime/common/recursive_array/recursive_array.js b/tests/runtime/common/recursive_array/recursive_array.js new file mode 100644 index 000000000..9416e2a0c --- /dev/null +++ b/tests/runtime/common/recursive_array/recursive_array.js @@ -0,0 +1,12 @@ +let a = [] +a.push(a) +print(a.join()) + +a = [1] +let b = [a,0,a] +let c = [2,b,3] +let d = [4,c,5] +b[1] = d +print(b.join()) +print(c.join()) +print(d.join()) diff --git a/tests/runtime/common/recursive_array/verify.sh b/tests/runtime/common/recursive_array/verify.sh new file mode 100644 index 000000000..51a7771b1 --- /dev/null +++ b/tests/runtime/common/recursive_array/verify.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + +set -eo pipefail + +expected=" +1,4,2,,3,5,1 +2,1,4,,5,1,3 +4,2,1,,1,3,5" + +actual=`cat $1` +if [[ "$actual" == "$expected" ]];then + exit 0; +else + echo -e "expected:"$expected + echo -e "actual:"$actual + echo -e "\033[31mrestargstest failed\033[0m" + exit 1; +fi diff --git a/tests/runtime/common/spread_primitives/CMakeLists.txt b/tests/runtime/common/spread_primitives/CMakeLists.txt new file mode 100644 index 000000000..73b1441cc --- /dev/null +++ b/tests/runtime/common/spread_primitives/CMakeLists.txt @@ -0,0 +1,22 @@ +# Huawei Technologies Co.,Ltd. + +set(SPREAD_PRIMITIVES_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/spread_primitives.txt) +set(SPREAD_PRIMITIVES_BIN ${CMAKE_CURRENT_BINARY_DIR}/spread_primitives.abc) +set(SPREAD_PRIMITIVES_JS ${CMAKE_CURRENT_SOURCE_DIR}/spread_primitives.js) +set(SPREAD_PRIMITIVES_VERIFY ${CMAKE_CURRENT_SOURCE_DIR}/verify.sh) + +set(RUNTIME_ARGUMENTS --boot-panda-files=${CMAKE_BINARY_DIR}/pandastdlib/arkstdlib.abc --boot-class-spaces=\"ecmascript\" --compiler-enable-jit=false --gc-type=stw --run-gc-in-place --runtime-type \"ecmascript\" ${SPREAD_PRIMITIVES_BIN} _GLOBAL::func_main_0) + +add_custom_command( + OUTPUT ${SPREAD_PRIMITIVES_OUTPUT} + COMMENT "running javascript spread_primitives testcase" + COMMAND ${PANDA_RUN_PREFIX} $ ${SPREAD_PRIMITIVES_JS} --output ${SPREAD_PRIMITIVES_BIN} + COMMAND rm -f ${SPREAD_PRIMITIVES_OUTPUT} + COMMAND ${PANDA_RUN_PREFIX} $ ${RUNTIME_ARGUMENTS} 2>&1 > ${SPREAD_PRIMITIVES_OUTPUT} + COMMAND bash ${SPREAD_PRIMITIVES_VERIFY} ${SPREAD_PRIMITIVES_OUTPUT} +) +add_custom_target(spread_primitives + DEPENDS ${SPREAD_PRIMITIVES_OUTPUT} ${SPREAD_PRIMITIVES_VERIFY} +) +add_dependencies(spread_primitives es2panda ark) +add_dependencies(ecmascript_common_tests spread_primitives) diff --git a/tests/runtime/common/spread_primitives/spread_primitives.js b/tests/runtime/common/spread_primitives/spread_primitives.js new file mode 100644 index 000000000..9427f8ccd --- /dev/null +++ b/tests/runtime/common/spread_primitives/spread_primitives.js @@ -0,0 +1,22 @@ +let a = 'spread_primitives' +let b = {...a}; +print(b) +for (let i = 0; i < a.length; ++i) { + print(b[i.toString()]) +} + +let c = {...322} +print(c) +print(Object.keys(c).length) + +try { + [...null] +} catch (e) { + print(e) +} + +try { + [...undefined] +} catch(e) { + print(e) +} diff --git a/tests/runtime/common/spread_primitives/verify.sh b/tests/runtime/common/spread_primitives/verify.sh new file mode 100644 index 000000000..bf81e70f4 --- /dev/null +++ b/tests/runtime/common/spread_primitives/verify.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. + +set -eo pipefail + +expected="[object Object] +s +p +r +e +a +d +_ +p +r +i +m +i +t +i +v +e +s +[object Object] +0 +TypeError: null is not iterable +TypeError: undefined is not iterable" + +actual=`cat $1` +if [[ "$actual" == "$expected" ]];then + exit 0; +else + echo -e "expected:"$expected + echo -e "actual:"$actual + echo -e "\033[31mrestargstest failed\033[0m" + exit 1; +fi -- Gitee