diff --git a/BUILD.gn b/BUILD.gn index 86e03b4b58b5bc442bf47422f1fc5070e2c9c4df..0f8e7fe84d7bd8d9216411a4bd284f2846d65196 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -92,9 +92,49 @@ config("ark_jsruntime_public_config") { ] } -config("ark_jsruntime_config") { +ohos_static_library("libark_js_intl_static") { + sources = [ + "ecmascript/builtins/builtins_collator.cpp", + "ecmascript/builtins/builtins_date_time_format.cpp", + "ecmascript/builtins/builtins_intl.cpp", + "ecmascript/builtins/builtins_locale.cpp", + "ecmascript/builtins/builtins_number_format.cpp", + "ecmascript/builtins/builtins_plural_rules.cpp", + "ecmascript/builtins/builtins_relative_time_format.cpp", + "ecmascript/js_collator.cpp", + "ecmascript/js_date_time_format.cpp", + "ecmascript/js_locale.cpp", + "ecmascript/js_number_format.cpp", + "ecmascript/js_plural_rules.cpp", + "ecmascript/js_relative_time_format.cpp", + ] + + configs = [ + ":ark_jsruntime_public_config", + ":ark_jsruntime_common_config", + "$ark_root/runtime:arkruntime_public_config", + ] + + deps = [ + ":libark_jsruntime_static", + "$ark_root/libpandabase:libarkbase", + "$ark_root/libpandafile:libarkfile", + "//third_party/icu/icu4c:shared_icui18n", + "//third_party/icu/icu4c:shared_icuuc", + sdk_libc_secshared_dep, + ] + + output_extension = "a" + subsystem_name = "ark" +} + +config("ark_jsruntime_common_config") { defines = [ "PANDA_ENABLE_LTO" ] + if (is_standard_system) { + defines += [ "IS_STANDARD_SYSTEM" ] + } + if (is_linux) { defines += [ "PANDA_TARGET_UNIX", @@ -118,6 +158,9 @@ config("ark_jsruntime_config") { "PANDA_TARGET_UNIX", "PANDA_USE_FUTEX", ] + if (!is_standard_system && (current_cpu != "arm" || is_wearable_product)) { + defines += [ "PANDA_TARGET_MOBILE" ] + } } cflags_cc = [ @@ -127,10 +170,11 @@ config("ark_jsruntime_config") { "-pipe", "-Wdate-time", "-Wformat=2", - - #"-Wshadow", + "-flto", ] + ldflags = [ "-flto" ] + if (is_debug) { cflags_cc += [ "-Og", @@ -165,6 +209,11 @@ config("ark_jsruntime_config") { } } +config("ark_jsruntime_config") { + configs = [ ":ark_jsruntime_common_config" ] + cflags_cc = [ "-Wshadow" ] +} + # ecmascript unit testcase config config("ecma_test_config") { visibility = [ ":*" ] @@ -236,6 +285,7 @@ ecma_source = [ "ecmascript/ic/ic_runtime.cpp", "ecmascript/ic/property_box.cpp", "ecmascript/ic/proto_change_details.cpp", + "ecmascript/internal_call_params.cpp", "ecmascript/interpreter/frame_handler.cpp", "ecmascript/interpreter/slow_runtime_helper.cpp", "ecmascript/interpreter/slow_runtime_stub.cpp", @@ -255,6 +305,7 @@ ecma_source = [ "ecmascript/js_iterator.cpp", "ecmascript/js_map.cpp", "ecmascript/js_map_iterator.cpp", + "ecmascript/js_method.cpp", "ecmascript/js_object.cpp", "ecmascript/js_primitive_ref.cpp", "ecmascript/js_promise.cpp", @@ -270,6 +321,7 @@ ecma_source = [ "ecmascript/js_weak_container.cpp", "ecmascript/linked_hash_table.cpp", "ecmascript/literal_data_extractor.cpp", + "ecmascript/message_string.cpp", "ecmascript/mem/c_string.cpp", "ecmascript/mem/chunk.cpp", "ecmascript/mem/compress_collector.cpp", @@ -296,6 +348,7 @@ ecma_source = [ "ecmascript/regexp/regexp_opcode.cpp", "ecmascript/regexp/regexp_parser.cpp", "ecmascript/regexp/regexp_parser_cache.cpp", + "ecmascript/runtime_trampolines.cpp", "ecmascript/snapshot/mem/slot_bit.cpp", "ecmascript/snapshot/mem/snapshot.cpp", "ecmascript/snapshot/mem/snapshot_serialize.cpp", @@ -323,8 +376,6 @@ ohos_static_library("libark_jsruntime_static") { deps = [ "$ark_root/libpandabase:libarkbase", "$ark_root/libpandafile:libarkfile", - "//third_party/icu/icu4c:shared_icui18n", - "//third_party/icu/icu4c:shared_icuuc", sdk_libc_secshared_dep, ] @@ -340,7 +391,12 @@ ohos_static_library("libark_jsruntime_static") { } ohos_shared_library("libark_jsruntime") { - deps = [ ":libark_jsruntime_static" ] + deps = [ + ":libark_js_intl_static", + ":libark_jsruntime_static", + "//third_party/icu/icu4c:shared_icui18n", + "//third_party/icu/icu4c:shared_icuuc", + ] install_enable = true part_name = "ark_js_runtime" diff --git a/ecmascript/accessor_data.h b/ecmascript/accessor_data.h index 35633dd9b62b6e14bcbaa5753363b7e88e598b15..8732191c94ee3c074772fd95be347b9fff80eb45 100644 --- a/ecmascript/accessor_data.h +++ b/ecmascript/accessor_data.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMA_ACCESSOR_DATA_H -#define PANDA_RUNTIME_ECMA_ACCESSOR_DATA_H +#ifndef ECMASCRIPT_ACCESSOR_DATA_H +#define ECMASCRIPT_ACCESSOR_DATA_H #include "ecmascript/ecma_macros.h" #include "ecmascript/js_hclass.h" @@ -83,7 +83,7 @@ public: return JSTaggedValue::SameValue(this->GetType(), JSTaggedValue(static_cast(THROW))); } - static constexpr size_t TYPE_OFFSET = ObjectHeaderSize(); + static constexpr size_t TYPE_OFFSET = Record::SIZE; ACCESSORS(Type, TYPE_OFFSET, VALUE_OFFSET); ACCESSORS(Value, VALUE_OFFSET, SIZE); @@ -92,4 +92,4 @@ public: DECL_VISIT_OBJECT(TYPE_OFFSET, SIZE) }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMA_ACCESSOR_DATA_H +#endif // ECMASCRIPT_ACCESSOR_DATA_H diff --git a/ecmascript/base/array_helper.cpp b/ecmascript/base/array_helper.cpp index e01a821c7141a82d2c1c9e72370c095dfeb65ae0..12b4e80d967ca6d26bc7a5549eefbb2aaed27034 100644 --- a/ecmascript/base/array_helper.cpp +++ b/ecmascript/base/array_helper.cpp @@ -19,6 +19,7 @@ #include "ecmascript/ecma_macros.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_array.h" #include "ecmascript/js_hclass.h" #include "ecmascript/js_tagged_number.h" @@ -50,8 +51,7 @@ bool ArrayHelper::IsConcatSpreadable(JSThread *thread, const JSHandle &callbackfnHandle, - const JSHandle &valueX, const JSHandle &valueY, - const JSHandle &argv) + const JSHandle &valueX, const JSHandle &valueY) { // 1. If x and y are both undefined, return +0. if (valueX->IsHole()) { @@ -81,9 +81,10 @@ int32_t ArrayHelper::SortCompare(JSThread *thread, const JSHandle // d. Return v. if (!callbackfnHandle->IsUndefined()) { JSHandle thisArgHandle(thread, JSTaggedValue::Undefined()); - argv->Set(thread, 0, valueX); - argv->Set(thread, 1, valueY); - JSTaggedValue callResult = JSFunction::Call(thread, callbackfnHandle, thisArgHandle, argv); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(valueX, valueY); + JSTaggedValue callResult = + JSFunction::Call(thread, callbackfnHandle, thisArgHandle, 2, arguments->GetArgv()); // 2: two args if (callResult.IsInt()) { return callResult.GetInt(); } diff --git a/ecmascript/base/array_helper.h b/ecmascript/base/array_helper.h index 9dfa9cc2fe09395b985f64924ca5c87578bc89ed..0f0524daf78eb099682b92559b2a2c3ab74feb94 100644 --- a/ecmascript/base/array_helper.h +++ b/ecmascript/base/array_helper.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BASE_ARRAY_HELPER_H -#define PANDA_RUNTIME_ECMASCRIPT_BASE_ARRAY_HELPER_H +#ifndef ECMASCRIPT_BASE_ARRAY_HELPER_H +#define ECMASCRIPT_BASE_ARRAY_HELPER_H #include #include @@ -26,11 +26,10 @@ class ArrayHelper { public: static bool IsConcatSpreadable(JSThread *thread, const JSHandle &obj); static int32_t SortCompare(JSThread *thread, const JSHandle &callbackfnHandle, - const JSHandle &valueX, const JSHandle &valueY, - const JSHandle &arg); + const JSHandle &valueX, const JSHandle &valueY); static double GetLength(JSThread *thread, const JSHandle &thisHandle); static double GetArrayLength(JSThread *thread, const JSHandle &thisHandle); }; } // namespace panda::ecmascript::base -#endif // PANDA_RUNTIME_ECMASCRIPT_BASE_ARRAY_HELPER_H +#endif // ECMASCRIPT_BASE_ARRAY_HELPER_H diff --git a/ecmascript/base/builtins_base.h b/ecmascript/base/builtins_base.h index 3630c29e599f018eebee0495ffa6f90d83ded01a..bf218da0924a380b7fb5e1bc02f3058c04481074 100644 --- a/ecmascript/base/builtins_base.h +++ b/ecmascript/base/builtins_base.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BASE_BUILTINS_BASE_H -#define PANDA_RUNTIME_ECMASCRIPT_BASE_BUILTINS_BASE_H +#ifndef ECMASCRIPT_BASE_BUILTINS_BASE_H +#define ECMASCRIPT_BASE_BUILTINS_BASE_H #include "ecmascript/base/string_helper.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -76,10 +76,10 @@ public: static inline JSTaggedValue GetTaggedString(JSThread *thread, const char *str) { - return thread->GetEcmaVM()->GetFactory()->NewFromString(str).GetTaggedValue(); + return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } }; } // namespace base } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_H +#endif // ECMASCRIPT_BASE_BUILTINS_BASE_H diff --git a/ecmascript/js_uint8_array.h b/ecmascript/base/config.h similarity index 38% rename from ecmascript/js_uint8_array.h rename to ecmascript/base/config.h index a55c6a8a3454cb9cf919b6b3a35c6cafbeb573d5..c8d03a02be511fc80c8ed3205f0a7e6c6e297a14 100644 --- a/ecmascript/js_uint8_array.h +++ b/ecmascript/base/config.h @@ -13,32 +13,15 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_UINT8_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_UINT8_ARRAY_H - -#include -#include "ecmascript/js_object.h" -#include "ecmascript/js_tagged_value-inl.h" -#include "ecmascript/js_tagged_value.h" +#ifndef ECMASCRIPT_BASE_CONFIG_H +#define ECMASCRIPT_BASE_CONFIG_H namespace panda::ecmascript { -class JSUint8Array : public JSObject { -public: - static JSUint8Array *Cast(ObjectHeader *object) - { - ASSERT(JSTaggedValue(object).IsJSUint8Array()); - return static_cast(object); - } - - static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE; - ACCESSORS(ViewedArrayBuffer, VIEWED_ARRAY_BUFFER_OFFSET, TYPED_ARRAY_NAME_OFFSET) - ACCESSORS(TypedArrayName, TYPED_ARRAY_NAME_OFFSET, BYTE_LENGTH_OFFSET) - ACCESSORS(ByteLength, BYTE_LENGTH_OFFSET, BYTE_OFFSET_OFFSET) - ACCESSORS(ByteOffset, BYTE_OFFSET_OFFSET, ARRAY_LENGTH_OFFSET) - ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, SIZE) - DECL_DUMP() +#define ARK_INLINE __attribute__((always_inline)) +#define ARK_NOINLINE __attribute__((noinline)) - DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE) -}; // namespace panda::ecmascript +#define ECMASCRIPT_ENABLE_RUNTIME_STAT 0 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define ECMASCRIPT_ENABLE_IC 1 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_UINT8_ARRAY_H \ No newline at end of file + +#endif // ECMASCRIPT_BASE_CONFIG_H diff --git a/ecmascript/base/error_helper.cpp b/ecmascript/base/error_helper.cpp index d5c8a1b9570186027c665c45ccfceacf7bd9fe5e..fb4311f0ae4333ab31aac89298e0e1d609a88c72 100644 --- a/ecmascript/base/error_helper.cpp +++ b/ecmascript/base/error_helper.cpp @@ -79,7 +79,7 @@ JSTaggedValue ErrorHelper::ErrorCommonToString(EcmaRuntimeCallInfo *argv, const } // 13. Return the result of concatenating name, the code unit 0x003A (COLON), the code unit 0x0020 (SPACE), and msg. - JSHandle space = factory->NewFromString(": "); + JSHandle space = factory->NewFromCanBeCompressString(": "); JSHandle jsHandleName = JSHandle::Cast(name); JSHandle jsHandleMsg = JSHandle::Cast(msg); JSHandle handleNameSpace = factory->ConcatFromString(jsHandleName, space); @@ -172,9 +172,8 @@ JSTaggedValue ErrorHelper::ErrorCommonConstructor(EcmaRuntimeCallInfo *argv, return nativeInstanceObj.GetTaggedValue(); } -CString ErrorHelper::DecodeFunctionName(const char *methodName) +CString ErrorHelper::DecodeFunctionName(const CString &name) { - CString name(methodName); if (name.empty()) { return "anonymous"; } @@ -200,8 +199,7 @@ CString ErrorHelper::BuildNativeEcmaStackTrace(JSThread *thread) data += INTRINSIC_METHOD_NAME; } else { data.append(" at "); - data += DecodeFunctionName( - utf::Mutf8AsCString(method->GetStringDataAnnotation(Method::AnnotationField::FUNCTION_NAME).data)); + data += DecodeFunctionName(method->ParseFunctionName()); data.append(" ("); // source file PtJSExtractor *debugExtractor = ecmaVm->GetDebugInfoExtractor(method->GetPandaFile()); diff --git a/ecmascript/base/error_helper.h b/ecmascript/base/error_helper.h index d35eec8b092775cdad4676e91c2920bcbd95b99b..4c680db5d72a840478a5aaadca018cbe86c3099e 100644 --- a/ecmascript/base/error_helper.h +++ b/ecmascript/base/error_helper.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BASE_ERROR_HELPER_H -#define PANDA_RUNTIME_ECMASCRIPT_BASE_ERROR_HELPER_H +#ifndef ECMASCRIPT_BASE_ERROR_HELPER_H +#define ECMASCRIPT_BASE_ERROR_HELPER_H #include "ecmascript/base/error_type.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -34,7 +34,7 @@ public: static CString BuildNativeEcmaStackTrace(JSThread *thread); private: - static CString DecodeFunctionName(const char *methodName); + static CString DecodeFunctionName(const CString &name); static JSHandle BuildEcmaStackTrace(JSThread *thread); static JSHandle GetErrorName(JSThread *thread, const JSHandle &name, @@ -42,4 +42,4 @@ private: }; } // namespace panda::ecmascript::base -#endif // PANDA_RUNTIME_ECMASCRIPT_BASE_ERROR_HELPER_H +#endif // ECMASCRIPT_BASE_ERROR_HELPER_H diff --git a/ecmascript/base/error_type.h b/ecmascript/base/error_type.h index 998856740f82d3094aa354fa7a2397a4f884812f..42a5dcd1528cf486a363d0a1c557d3ab05d46c65 100644 --- a/ecmascript/base/error_type.h +++ b/ecmascript/base/error_type.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BASE_ERROR_TYPE_H -#define PANDA_RUNTIME_ECMASCRIPT_BASE_ERROR_TYPE_H +#ifndef ECMASCRIPT_BASE_ERROR_TYPE_H +#define ECMASCRIPT_BASE_ERROR_TYPE_H #include @@ -30,4 +30,4 @@ enum class ErrorType : uint8_t { }; } // namespace panda::ecmascript::base -#endif // PANDA_RUNTIME_ECMASCRIPT_BASE_ERROR_TYPE_H +#endif // ECMASCRIPT_BASE_ERROR_TYPE_H diff --git a/ecmascript/base/json_parser.cpp b/ecmascript/base/json_parser.cpp index a4acd07a5b199e7f7ead8ce762fc6f5a1249ba47..1702080a9abad30457a675f695d6deb367b4c0ac 100644 --- a/ecmascript/base/json_parser.cpp +++ b/ecmascript/base/json_parser.cpp @@ -20,6 +20,7 @@ #include "ecmascript/base/utf_helper.h" #include "ecmascript/ecma_string-inl.h" #include "ecmascript/ecma_string.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/fast_runtime_stub-inl.h" #include "ecmascript/js_array.h" #include "ecmascript/js_function.h" @@ -33,6 +34,7 @@ constexpr unsigned int NUMBER_TEN = 10; constexpr unsigned int NUMBER_SIXTEEN = 16; constexpr unsigned char CODE_SPACE = 0x20; +constexpr unsigned char ASCII_END = 0X7F; JSHandle JsonParser::Parse(Text begin, Text end) { end_ = end - 1; @@ -52,20 +54,21 @@ JSHandle JsonParser::Parse(EcmaString *str) { ASSERT(str != nullptr); if (UNLIKELY(str->IsUtf16())) { - size_t len = base::utf_helper::Utf16ToUtf8Size(str->GetDataUtf16(), str->GetLength()) - 1; - CVector buf(len); - len = base::utf_helper::ConvertRegionUtf16ToUtf8(str->GetDataUtf16(), buf.data(), str->GetLength(), len, 0); - Text begin = buf.data(); - return Parse(begin, begin + len); + uint32_t len = str->GetLength(); + std::u16string u16str = StringHelper::Utf16ToU16String(str->GetDataUtf16(), len); + std::string u8str = StringHelper::U16stringToString(u16str); + Text begin = reinterpret_cast(u8str.c_str()); + return Parse(begin, begin + u8str.length()); } + isAsciiString_ = true; CVector buf(str->GetUtf8Length()); str->CopyDataUtf8(buf.data(), str->GetUtf8Length()); Text begin = buf.data(); return Parse(begin, begin + str->GetLength()); } -template +template JSTaggedValue JsonParser::ParseJSONText() { SkipStartWhiteSpace(); @@ -122,7 +125,6 @@ JsonParser::Tokens JsonParser::ParseToken() } } - void JsonParser::SkipEndWhiteSpace() { while (current_ != end_) { @@ -145,10 +147,17 @@ void JsonParser::SkipStartWhiteSpace() } } +void JsonParser::GetNextNonSpaceChar() +{ + current_++; + SkipStartWhiteSpace(); +} + JSTaggedValue JsonParser::ParseLiteral(CString str, Tokens literalToken) { uint32_t strLen = str.size() - 1; - if (UNLIKELY(range_ - current_ < strLen)) { + uint32_t remainingLength = range_ - current_; + if (UNLIKELY(remainingLength < strLen)) { THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception()); } @@ -182,14 +191,20 @@ bool JsonParser::MatchText(CString str, uint32_t matchLen) return true; } -template +template JSTaggedValue JsonParser::ParseNumber() { if (inObjOrArr) { - bool isNumber = ReadNumberRange(); + bool isFast = true; + bool isNumber = ReadNumberRange(isFast); if (!isNumber) { THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); } + if (isFast) { + double result = NumberHelper::StringToDouble(current_, end_ + 1, 0, 0); + current_ = end_; + return JSTaggedValue(result); + } } Text current = current_; @@ -200,35 +215,12 @@ JSTaggedValue JsonParser::ParseNumber() } } if (*current_ == '0') { - if (current_++ != end_) { - if (*current_ == '.') { - if (!IsDecimalsLegal(hasExponent)) { - THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); - } - } else if (*current_ == 'e' || *current_ == 'E') { - if (!IsExponentLegal(hasExponent)) { - THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); - } - } else { - THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); - } + if (!CheckZeroBeginNumber(hasExponent)) { + THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); } } else if (*current_ >= '1' && *current_ <= '9') { - while (current_ != end_) { - current_++; - if (IsNumberCharacter(*current_)) { - continue; - } else if (*current_ == '.') { - if (!IsDecimalsLegal(hasExponent)) { - THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); - } - } else if (*current_ == 'e' || *current_ == 'E') { - if (!IsExponentLegal(hasExponent)) { - THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); - } - } else { - THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); - } + if (!CheckNonZeroBeginNumber(hasExponent)) { + THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); } } else { THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Number in JSON", JSTaggedValue::Exception()); @@ -239,11 +231,68 @@ JSTaggedValue JsonParser::ParseNumber() return JSTaggedValue(result); } -bool JsonParser::ReadNumberRange() +bool JsonParser::CheckZeroBeginNumber(bool &hasExponent) +{ + if (current_++ != end_) { + if (*current_ == '.') { + if (!IsDecimalsLegal(hasExponent)) { + return false; + } + } else if (*current_ == 'e' || *current_ == 'E') { + if (!IsExponentLegal(hasExponent)) { + return false; + } + } else { + return false; + } + } + return true; +} + +bool JsonParser::CheckNonZeroBeginNumber(bool &hasExponent) +{ + while (current_ != end_) { + current_++; + if (IsNumberCharacter(*current_)) { + continue; + } else if (*current_ == '.') { + if (!IsDecimalsLegal(hasExponent)) { + return false; + } + } else if (*current_ == 'e' || *current_ == 'E') { + if (!IsExponentLegal(hasExponent)) { + return false; + } + } else { + return false; + } + } + return true; +} + +bool JsonParser::ReadNumberRange(bool &isFast) { Text current = current_; + if (*current == '0') { + isFast = false; + current++; + } else if (*current == '-') { + current++; + if (*current == '0') { + isFast = false; + current++; + } + } + while (current != range_) { - if (!(IsNumberCharacter(*current)) && !IsNumberSignalCharacter(*current)) { + if (IsNumberCharacter(*current)) { + current++; + continue; + } else if (IsNumberSignalCharacter(*current)) { + isFast = false; + current++; + continue; + } else { Text end = current; while (current != range_) { if (*current == ' ' || *current == '\r' || *current == '\n' || *current == '\t') { @@ -257,9 +306,8 @@ bool JsonParser::ReadNumberRange() } return false; } - end_ = range_ - 1; - current++; } + end_ = range_ - 1; return true; } @@ -336,66 +384,112 @@ bool JsonParser::IsExponentLegal(bool &hasExponent) return true; } -bool JsonParser::ReadStringRange(bool &isFast) +bool JsonParser::ReadStringRange(bool &isFast, bool &isAscii) { uint8_t c = 0; Text current = current_; - if (current == range_) { - return false; - } + while (current != range_) { c = *current; if (c == '"') { end_ = current; return true; - } else if (UNLIKELY(c < CODE_SPACE)) { - return false; - } else if (UNLIKELY(c == base::utf_helper::UTF8_2B_FIRST)) { - uint8_t next = *(current + 1); - if (next == base::utf_helper::UTF8_2B_SECOND) { // special case for U+0000 => C0 80 - return false; + } else if (UNLIKELY(c == '\\')) { + if (*(current + 1) == '"') { + current++; } - } else if (c == '\\') { isFast = false; } + if (!IsLegalAsciiCharacter(c, isAscii)) { + return false; + } + current++; + } + return false; +} +bool JsonParser::ReadAsciiStringRange(bool &isFast) +{ + uint8_t c = 0; + Text current = current_; + + while (current != range_) { + c = *current; + if (c == '"') { + end_ = current; + return true; + } else if (UNLIKELY(c == '\\')) { + if (*(current + 1) == '"') { + current++; + } + isFast = false; + } else if (UNLIKELY(c < CODE_SPACE)) { + return false; + } current++; } return false; } -template +inline bool JsonParser::IsLegalAsciiCharacter(uint8_t c, bool &isAscii) +{ + if (c <= ASCII_END) { + if (c >= CODE_SPACE) { + return true; + } + return false; + } + isAscii = false; + return true; +} + +template JSTaggedValue JsonParser::ParseString() { bool isFast = true; + bool isAscii = true; + bool isLegal = true; if (inObjorArr) { current_++; - bool isString = ReadStringRange(isFast); - if (!isString) { + if (isAsciiString_) { + isLegal = ReadAsciiStringRange(isFast); + } else { + isLegal = ReadStringRange(isFast, isAscii); + } + if (!isLegal) { THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected end Text in JSON", JSTaggedValue::Exception()); } if (isFast) { CString value(current_, end_); current_ = end_; - - return factory_->NewFromString(value).GetTaggedValue(); + if (isAscii) { + return factory_->NewFromUtf8LiteralUnCheck(reinterpret_cast(value.c_str()), value.length(), true) + .GetTaggedValue(); + } + return factory_->NewFromUtf8LiteralUnCheck(reinterpret_cast(value.c_str()), value.length(), false) + .GetTaggedValue(); } } else { if (*end_ != '"' || current_ == end_) { THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected end Text in JSON", JSTaggedValue::Exception()); } current_++; - Text current = current_; - while (current != end_) { - if (UNLIKELY(*current < CODE_SPACE)) { - THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Text in JSON", JSTaggedValue::Exception()); - } - current++; + if (isAsciiString_) { + isLegal = IsFastParseString(isFast, isAscii); + } else { + isLegal = IsFastParseAsciiString(isFast); + } + if (!isLegal) { + THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected end Text in JSON", JSTaggedValue::Exception()); } - CString value(current_, end_); - isFast = IsFastParseString(value); if (LIKELY(isFast)) { - return factory_->NewFromString(value).GetTaggedValue(); + CString value(current_, end_); + if (isAscii) { + return factory_->NewFromUtf8LiteralUnCheck(reinterpret_cast(value.c_str()), value.length(), true) + .GetTaggedValue(); + } + return factory_->NewFromUtf8LiteralUnCheck(reinterpret_cast(value.c_str()), value.length(), false) + .GetTaggedValue(); } } end_--; @@ -449,20 +543,42 @@ JSTaggedValue JsonParser::ParseString() } current_++; } - return factory_->NewFromString(res).GetTaggedValue(); + return factory_->NewFromUtf8Literal(reinterpret_cast(res.c_str()), res.length()).GetTaggedValue(); } -bool JsonParser::IsFastParseString(CString &value) +bool JsonParser::IsFastParseString(bool &isFast, bool &isAscii) { - if (strpbrk(value.c_str(), "\"\\/\b\f\n\r\t") != nullptr) { - return false; + Text current = current_; + while (current != end_) { + if (!IsLegalAsciiCharacter(*current, isAscii)) { + return false; + } + if (*current == '\\') { + isFast = false; + } + current++; + } + return true; +} + +bool JsonParser::IsFastParseAsciiString(bool &isFast) +{ + Text current = current_; + while (current != end_) { + if (*current < CODE_SPACE) { + return false; + } else if (*current == '\\') { + isFast = false; + } + current++; } return true; } bool JsonParser::ConvertStringUnicode(CVector &vec) { - if (end_ - current_ < UNICODE_DIGIT_LENGTH) { + uint32_t remainingLength = end_ - current_; + if (remainingLength < UNICODE_DIGIT_LENGTH) { return false; } uint16_t res = 0; @@ -483,17 +599,17 @@ bool JsonParser::ConvertStringUnicode(CVector &vec) if (res < CODE_SPACE) { return false; } - current_++; + vec.emplace_back(res); - if (*(current_ + 1) == '\\' && *(current_ + 2) == 'u') { // 2: next two chars - current_ += 2; // 2: point moves backwards by two digits + if (*(current_ + 1) == '\\' && *(current_ + 2) == 'u') { // 2: next two chars + current_ += 2; // 2: point moves backwards by two digits return ConvertStringUnicode(vec); } return true; } -template +template JSTaggedValue JsonParser::ParseArray() { if (UNLIKELY(*range_ != ']' && !inObjorArr)) { @@ -506,14 +622,13 @@ JSTaggedValue JsonParser::ParseArray() return arr.GetTaggedValue(); } - JSMutableHandle valueHandle(thread_, JSTaggedValue::Undefined()); + JSTaggedValue value; uint32_t index = 0; while (current_ <= range_) { - valueHandle.Update(ParseJSONText()); + value = ParseJSONText(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); - FastRuntimeStub::SetPropertyByIndex(thread_, arr.GetTaggedValue(), index++, valueHandle.GetTaggedValue()); - current_++; - SkipStartWhiteSpace(); + FastRuntimeStub::SetPropertyByIndex(thread_, arr.GetTaggedValue(), index++, value); + GetNextNonSpaceChar(); if (*current_ == ',') { current_++; } else if (*current_ == ']') { @@ -527,7 +642,7 @@ JSTaggedValue JsonParser::ParseArray() THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Array in JSON", JSTaggedValue::Exception()); } -template +template JSTaggedValue JsonParser::ParseObject() { if (UNLIKELY(*range_ != '}' && !inObjorArr)) { @@ -542,7 +657,7 @@ JSTaggedValue JsonParser::ParseObject() } JSMutableHandle keyHandle(thread_, JSTaggedValue::Undefined()); - JSMutableHandle valueHandle(thread_, JSTaggedValue::Undefined()); + JSTaggedValue value; while (current_ <= range_) { SkipStartWhiteSpace(); if (*current_ == '"') { @@ -553,18 +668,15 @@ JSTaggedValue JsonParser::ParseObject() } THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception()); } - current_++; - SkipStartWhiteSpace(); + GetNextNonSpaceChar(); if (*current_ == ':') { current_++; } else { THROW_SYNTAX_ERROR_AND_RETURN(thread_, "Unexpected Object in JSON", JSTaggedValue::Exception()); } - valueHandle.Update(ParseJSONText()); - FastRuntimeStub::SetPropertyByValue(thread_, result.GetTaggedValue(), keyHandle.GetTaggedValue(), - valueHandle.GetTaggedValue()); - current_++; - SkipStartWhiteSpace(); + value = ParseJSONText(); + FastRuntimeStub::SetPropertyByValue(thread_, result.GetTaggedValue(), keyHandle.GetTaggedValue(), value); + GetNextNonSpaceChar(); if (*current_ == ',') { current_++; } else if (*current_ == '}') { @@ -610,19 +722,16 @@ JSHandle JsonParser::InternalizeJsonProperty(const JSHandle keyName(thread_, JSTaggedValue::Undefined()); for (array_size_t i = 0; i < namesLength; i++) { keyName.Update(JSTaggedValue::GetProperty(thread_, JSHandle(ownerNames), i) - .GetValue() - .GetTaggedValue()); + .GetValue().GetTaggedValue()); RecurseAndApply(obj, keyName, receiver); } } } // Return ? Call(receiver, holder, « name, val »). - array_size_t length = 2; - JSHandle msg = factory_->NewTaggedArray(length); - msg->Set(thread_, 0, name); - msg->Set(thread_, 1, val); - JSTaggedValue result = JSFunction::Call(thread_, receiver, objHandle, msg); + InternalCallParams *arguments = thread_->GetInternalCallParams(); + arguments->MakeArgv(name, val); + JSTaggedValue result = JSFunction::Call(thread_, receiver, objHandle, 2, arguments->GetArgv()); // 2: two args return JSHandle(thread_, result); } diff --git a/ecmascript/base/json_parser.h b/ecmascript/base/json_parser.h index ba8042533566a6644f324a43f12145fd34923ad2..c94e5f27d30e4219f06a6a3af7e2b1c3cc14429d 100644 --- a/ecmascript/base/json_parser.h +++ b/ecmascript/base/json_parser.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BASE_JSON_PARSE_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_BASE_JSON_PARSE_INL_H +#ifndef ECMASCRIPT_BASE_JSON_PARSE_INL_H +#define ECMASCRIPT_BASE_JSON_PARSE_INL_H #include "ecmascript/js_tagged_value.h" #include "ecmascript/js_handle.h" @@ -48,39 +48,47 @@ private: TOKEN_ILLEGAL, }; - template + template JSTaggedValue ParseJSONText(); - template + template JSTaggedValue ParseNumber(); - template + template JSTaggedValue ParseString(); - template + template JSTaggedValue ParseArray(); - template + template JSTaggedValue ParseObject(); void SkipEndWhiteSpace(); void SkipStartWhiteSpace(); + void GetNextNonSpaceChar(); JsonParser::Tokens ParseToken(); JSTaggedValue ParseLiteral(CString str, Tokens literalToken); bool MatchText(CString str, uint32_t matchLen); - bool ReadNumberRange(); + bool ReadNumberRange(bool &isFast); bool IsNumberCharacter(uint8_t ch); bool IsNumberSignalCharacter(uint8_t ch); bool IsExponentNumber(); bool IsDecimalsLegal(bool &hasExponent); bool IsExponentLegal(bool &hasExponent); - bool ReadStringRange(bool &isFast); - bool IsFastParseString(CString &value); + bool ReadStringRange(bool &isFast, bool &isAscii); + bool ReadAsciiStringRange(bool &isFast); + bool IsFastParseString(bool &isFast, bool &isAscii); + bool IsFastParseAsciiString(bool &isFast); bool ConvertStringUnicode(CVector &vec); + bool CheckZeroBeginNumber(bool &hasExponent); + bool CheckNonZeroBeginNumber(bool &hasExponent); bool RecurseAndApply(const JSHandle &holder, const JSHandle &name, const JSHandle &receiver); + inline bool IsLegalAsciiCharacter(uint8_t c, bool &isAscii); + + bool isAsciiString_{false}; Text end_{nullptr}; Text current_{nullptr}; Text range_{nullptr}; @@ -90,4 +98,4 @@ private: }; } // namespace panda::ecmascript::base -#endif // PANDA_RUNTIME_ECMASCRIPT_BASE_JSON_PARSE_INL_H +#endif // ECMASCRIPT_BASE_JSON_PARSE_INL_H diff --git a/ecmascript/base/json_stringifier.cpp b/ecmascript/base/json_stringifier.cpp index 8d07257637304f60f62cb1d6438c574501da3685..352de5ed2fe19a6426b6cd3ffcb109b6060f7634 100644 --- a/ecmascript/base/json_stringifier.cpp +++ b/ecmascript/base/json_stringifier.cpp @@ -23,6 +23,7 @@ #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/ecma_string-inl.h" #include "ecmascript/ecma_vm.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/fast_runtime_stub-inl.h" #include "ecmascript/js_array.h" #include "ecmascript/js_function.h" @@ -292,24 +293,21 @@ JSTaggedValue JsonStringifier::GetSerializeValue(const JSHandle & // c. If IsCallable(toJSON) is true if (UNLIKELY(toJsonFun->IsCallable())) { - array_size_t length = 1; - JSHandle msg = factory_->NewTaggedArray(length); - msg->Set(thread_, 0, key.GetTaggedValue()); // Let value be Call(toJSON, value, «key»). - tagValue = JSFunction::Call(thread_, toJsonFun, value, msg); + InternalCallParams *arguments = thread_->GetInternalCallParams(); + arguments->MakeArgv(key); + tagValue = JSFunction::Call(thread_, toJsonFun, value, 1, arguments->GetArgv()); // ii. ReturnIfAbrupt(value). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); } } if (UNLIKELY(replacer->IsCallable())) { - array_size_t length = 2; handleValue_.Update(tagValue); - JSHandle msg = factory_->NewTaggedArray(length); - msg->Set(thread_, 0, key); - msg->Set(thread_, 1, handleValue_); // a. Let value be Call(ReplacerFunction, holder, «key, value»). - tagValue = JSFunction::Call(thread_, replacer, object, msg); + InternalCallParams *arguments = thread_->GetInternalCallParams(); + arguments->MakeArgv(key, handleValue_); + tagValue = JSFunction::Call(thread_, replacer, object, 2, arguments->GetArgv()); // 2: two args // b. ReturnIfAbrupt(value). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_); } @@ -468,7 +466,7 @@ bool JsonStringifier::SerializeJSONObject(const JSHandle &value, JSTaggedValue serializeValue = GetSerializeValue(value, propList_[i], handleValue_, replacer); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false); if (UNLIKELY(serializeValue.IsUndefined() || serializeValue.IsSymbol() || - (serializeValue.IsECMAObject() && serializeValue.IsCallable()))) { + (serializeValue.IsECMAObject() && serializeValue.IsCallable()))) { continue; } handleValue_.Update(serializeValue); @@ -757,7 +755,7 @@ bool JsonStringifier::AppendJsonString(const JSHandle &obj, const JSHa JSTaggedValue serializeValue = GetSerializeValue(JSHandle(obj), handleKey_, handleValue_, replacer); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, false); if (UNLIKELY(serializeValue.IsUndefined() || serializeValue.IsSymbol() || - (serializeValue.IsECMAObject() && serializeValue.IsCallable()))) { + (serializeValue.IsECMAObject() && serializeValue.IsCallable()))) { return hasContent; } handleValue_.Update(serializeValue); diff --git a/ecmascript/base/json_stringifier.h b/ecmascript/base/json_stringifier.h index 8aa0ba14c64cbf24ee47006b707e3b74eff9bc8a..6979f0e3d40f448522363c86aac17fd9e3ac46f3 100644 --- a/ecmascript/base/json_stringifier.h +++ b/ecmascript/base/json_stringifier.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BASE_JSON_STRINGIFY_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_BASE_JSON_STRINGIFY_INL_H +#ifndef ECMASCRIPT_BASE_JSON_STRINGIFY_INL_H +#define ECMASCRIPT_BASE_JSON_STRINGIFY_INL_H #include "ecmascript/js_tagged_value.h" #include "ecmascript/js_handle.h" @@ -79,4 +79,4 @@ private: JSMutableHandle handleValue_{}; }; } // namespace panda::ecmascript::base -#endif // PANDA_RUNTIME_ECMASCRIPT_BASE_JSON_STRINGIFY_INL_H +#endif // ECMASCRIPT_BASE_JSON_STRINGIFY_INL_H diff --git a/ecmascript/base/number_helper.cpp b/ecmascript/base/number_helper.cpp index 793024c4026c38cd121b75a3737286c2e05965fa..a6c3410babc5fbb3f8ae8a33f4cd0e984ee2453d 100644 --- a/ecmascript/base/number_helper.cpp +++ b/ecmascript/base/number_helper.cpp @@ -331,18 +331,18 @@ JSHandle NumberHelper::NumberToString(const JSThread *thread, JSTagg ASSERT(number.IsNumber()); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); if (number.IsInt()) { - return factory->NewFromString(IntToString(number.GetInt())); + return factory->NewFromCanBeCompressString(IntToString(number.GetInt())); } double d = number.GetDouble(); if (std::isnan(d)) { - return factory->NewFromString("NaN"); + return factory->NewFromCanBeCompressString("NaN"); } if (d == 0.0) { - return factory->NewFromString("0"); + return factory->NewFromCanBeCompressString("0"); } if (d >= INT32_MIN + 1 && d <= INT32_MAX && d == static_cast(static_cast(d))) { - return factory->NewFromString(IntToString(static_cast(d))); + return factory->NewFromCanBeCompressString(IntToString(static_cast(d))); } std::string result; @@ -353,7 +353,7 @@ JSHandle NumberHelper::NumberToString(const JSThread *thread, JSTagg if (std::isinf(d)) { result += "Infinity"; - return factory->NewFromStdString(result); + return factory->NewFromStdStringUnCheck(result, true); } ASSERT(d > 0); @@ -408,7 +408,7 @@ JSHandle NumberHelper::NumberToString(const JSThread *thread, JSTagg base += "e" + (n >= 1 ? std::string("+") : "") + std::to_string(n - 1); } result += base; - return factory->NewFromStdString(result); + return factory->NewFromStdStringUnCheck(result, true); } double NumberHelper::TruncateDouble(double d) @@ -614,6 +614,7 @@ double NumberHelper::StringToDouble(const uint8_t *start, const uint8_t *end, ui double NumberHelper::Strtod(const char *str, int exponent, uint8_t radix) { ASSERT(str != nullptr); + ASSERT(radix >= base::MIN_RADIX && radix <= base::MAX_RADIX); auto p = const_cast(str); Sign sign = Sign::NONE; uint64_t number = 0; diff --git a/ecmascript/base/number_helper.h b/ecmascript/base/number_helper.h index b4c96cb2b81029ce72c7a2edfe39f6937a71bab2..ebf3012556a2c17eb3e3dce1fa078f2001221cfc 100644 --- a/ecmascript/base/number_helper.h +++ b/ecmascript/base/number_helper.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BASE_NUMBER_HELPER_H -#define PANDA_RUNTIME_ECMASCRIPT_BASE_NUMBER_HELPER_H +#ifndef ECMASCRIPT_BASE_NUMBER_HELPER_H +#define ECMASCRIPT_BASE_NUMBER_HELPER_H #include #include "ecmascript/ecma_string.h" @@ -99,4 +99,4 @@ private: static bool GotoNonspace(uint8_t **ptr, const uint8_t *end); }; } // namespace panda::ecmascript::base -#endif // PANDA_RUNTIME_ECMASCRIPT_BASE_NUMBER_HELPER_H +#endif // ECMASCRIPT_BASE_NUMBER_HELPER_H diff --git a/ecmascript/base/string_helper.cpp b/ecmascript/base/string_helper.cpp index 8b82916fa6935d0d3d5b3c075bbf01f302355b7c..b10e82692541d25defd9becf1d5b1dadb85cad81 100644 --- a/ecmascript/base/string_helper.cpp +++ b/ecmascript/base/string_helper.cpp @@ -42,7 +42,7 @@ bool StringHelper::CheckDuplicate(EcmaString *string) return false; } -EcmaString *StringHelper::Repeat(JSThread *thread, const std::u16string &thisStr, int32_t repeatLen) +EcmaString *StringHelper::Repeat(JSThread *thread, const std::u16string &thisStr, int32_t repeatLen, bool canBeCompress) { ecmascript::ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); if (repeatLen == 0) { @@ -56,7 +56,7 @@ EcmaString *StringHelper::Repeat(JSThread *thread, const std::u16string &thisStr auto *char16tData = const_cast(constChar16tData); auto *uint16tData = reinterpret_cast(char16tData); int32_t length = tmpStr.size(); - return *factory->NewFromUtf16(uint16tData, length); + return *factory->NewFromUtf16UnCheck(uint16tData, length, canBeCompress); } EcmaString *StringHelper::Trim(JSThread *thread, const std::u16string &thisStr) diff --git a/ecmascript/base/string_helper.h b/ecmascript/base/string_helper.h index b435555e81b2b93d318413c9cbedd838335dc321..38f6f6942f948d343493a668569c5dc83604e82b 100644 --- a/ecmascript/base/string_helper.h +++ b/ecmascript/base/string_helper.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BASE_STRING_HELP_H -#define PANDA_RUNTIME_ECMASCRIPT_BASE_STRING_HELP_H +#ifndef ECMASCRIPT_BASE_STRING_HELP_H +#define ECMASCRIPT_BASE_STRING_HELP_H #include #include @@ -153,7 +153,7 @@ public: return idx; } - static EcmaString *Repeat(JSThread *thread, const std::u16string &thisStr, int32_t repeatLen); + static EcmaString *Repeat(JSThread *thread, const std::u16string &thisStr, int32_t repeatLen, bool canBeCompress); static EcmaString *Trim(JSThread *thread, const std::u16string &thisStr); @@ -181,4 +181,4 @@ public: } }; } // namespace panda::ecmascript::base -#endif // PANDA_RUNTIME_ECMASCRIPT_BASE_STRING_HELP_H +#endif // ECMASCRIPT_BASE_STRING_HELP_H diff --git a/ecmascript/base/typed_array_helper-inl.h b/ecmascript/base/typed_array_helper-inl.h index b7d483149027d906b9a4a3deae511f2364cc0bed..117becf590d6bfd891acfbaf37c2205e642e4e07 100644 --- a/ecmascript/base/typed_array_helper-inl.h +++ b/ecmascript/base/typed_array_helper-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_INL_H +#ifndef ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_INL_H +#define ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_INL_H #include "ecmascript/builtins/builtins_arraybuffer.h" #include "ecmascript/base/builtins_base.h" @@ -27,18 +27,10 @@ #include "ecmascript/global_env.h" #include "ecmascript/js_object.h" #include "ecmascript/js_array_iterator.h" -#include "ecmascript/js_int8_array.h" -#include "ecmascript/js_uint8_array.h" -#include "ecmascript/js_uint8_clamped_array.h" -#include "ecmascript/js_int16_array.h" -#include "ecmascript/js_uint16_array.h" -#include "ecmascript/js_int32_array.h" -#include "ecmascript/js_uint32_array.h" -#include "ecmascript/js_float32_array.h" -#include "ecmascript/js_float64_array.h" #include "ecmascript/js_arraybuffer.h" #include "ecmascript/base/error_helper.h" #include "ecmascript/js_tagged_value-inl.h" +#include "ecmascript/js_typed_array.h" #include "ecmascript/base/error_type.h" namespace panda::ecmascript::base { @@ -195,380 +187,17 @@ int32_t TypedArrayHelper::GetSizeFromName(JSThread *thread, const JSHandle &obj, - JSTaggedValue viewedArrayBuffer) -{ - JSType type = obj->GetJSHClass()->GetObjectType(); - switch (type) { - case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetViewedArrayBuffer(thread, viewedArrayBuffer); - break; - case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetViewedArrayBuffer(thread, viewedArrayBuffer); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetViewedArrayBuffer(thread, viewedArrayBuffer); - break; - case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetViewedArrayBuffer(thread, viewedArrayBuffer); - break; - case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetViewedArrayBuffer(thread, viewedArrayBuffer); - break; - case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetViewedArrayBuffer(thread, viewedArrayBuffer); - break; - case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetViewedArrayBuffer(thread, viewedArrayBuffer); - break; - case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetViewedArrayBuffer(thread, viewedArrayBuffer); - break; - case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetViewedArrayBuffer(thread, viewedArrayBuffer); - break; - default: - break; - } -} - -void TypedArrayHelper::SetTypedArrayName(JSThread *thread, const JSHandle &obj, - const JSHandle &typedArrayName) -{ - JSType type = obj->GetJSHClass()->GetObjectType(); - switch (type) { - case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetTypedArrayName(thread, typedArrayName); - break; - case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetTypedArrayName(thread, typedArrayName); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetTypedArrayName(thread, typedArrayName); - break; - case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetTypedArrayName(thread, typedArrayName); - break; - case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetTypedArrayName(thread, typedArrayName); - break; - case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetTypedArrayName(thread, typedArrayName); - break; - case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetTypedArrayName(thread, typedArrayName); - break; - case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetTypedArrayName(thread, typedArrayName); - break; - case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetTypedArrayName(thread, typedArrayName); - break; - default: - break; - } -} - -void TypedArrayHelper::SetByteLength(JSThread *thread, const JSHandle &obj, int32_t byteLength) -{ - auto byteLengthValue = JSTaggedValue(byteLength); - JSType type = obj->GetJSHClass()->GetObjectType(); - switch (type) { - case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetByteLength(thread, byteLengthValue); - break; - case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetByteLength(thread, byteLengthValue); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetByteLength(thread, byteLengthValue); - break; - case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetByteLength(thread, byteLengthValue); - break; - case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetByteLength(thread, byteLengthValue); - break; - case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetByteLength(thread, byteLengthValue); - break; - case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetByteLength(thread, byteLengthValue); - break; - case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetByteLength(thread, byteLengthValue); - break; - case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetByteLength(thread, byteLengthValue); - break; - default: - break; - } -} - -void TypedArrayHelper::SetByteOffset(JSThread *thread, const JSHandle &obj, int32_t byteOffset) -{ - auto byteOffsetValue = JSTaggedValue(byteOffset); - JSType type = obj->GetJSHClass()->GetObjectType(); - switch (type) { - case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetByteOffset(thread, byteOffsetValue); - break; - case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetByteOffset(thread, byteOffsetValue); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetByteOffset(thread, byteOffsetValue); - break; - case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetByteOffset(thread, byteOffsetValue); - break; - case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetByteOffset(thread, byteOffsetValue); - break; - case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetByteOffset(thread, byteOffsetValue); - break; - case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetByteOffset(thread, byteOffsetValue); - break; - case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetByteOffset(thread, byteOffsetValue); - break; - case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetByteOffset(thread, byteOffsetValue); - break; - default: - break; - } -} - -void TypedArrayHelper::SetArrayLength(JSThread *thread, const JSHandle &obj, int32_t arrayLength) -{ - auto arrayLengthValue = JSTaggedValue(arrayLength); - JSType type = obj->GetJSHClass()->GetObjectType(); - switch (type) { - case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetArrayLength(thread, arrayLengthValue); - break; - case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetArrayLength(thread, arrayLengthValue); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetArrayLength(thread, arrayLengthValue); - break; - case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetArrayLength(thread, arrayLengthValue); - break; - case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetArrayLength(thread, arrayLengthValue); - break; - case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetArrayLength(thread, arrayLengthValue); - break; - case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetArrayLength(thread, arrayLengthValue); - break; - case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetArrayLength(thread, arrayLengthValue); - break; - case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetArrayLength(thread, arrayLengthValue); - break; - default: - break; - } -} - -JSTaggedValue TypedArrayHelper::GetViewedArrayBuffer(const JSHandle &obj) -{ - JSType type = obj->GetJSHClass()->GetObjectType(); - JSTaggedValue buffer; - switch (type) { - case JSType::JS_INT8_ARRAY: - buffer = JSInt8Array::Cast(*obj)->GetViewedArrayBuffer(); - break; - case JSType::JS_UINT8_ARRAY: - buffer = JSUint8Array::Cast(*obj)->GetViewedArrayBuffer(); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - buffer = JSUint8ClampedArray::Cast(*obj)->GetViewedArrayBuffer(); - break; - case JSType::JS_INT16_ARRAY: - buffer = JSInt16Array::Cast(*obj)->GetViewedArrayBuffer(); - break; - case JSType::JS_UINT16_ARRAY: - buffer = JSUint16Array::Cast(*obj)->GetViewedArrayBuffer(); - break; - case JSType::JS_INT32_ARRAY: - buffer = JSInt32Array::Cast(*obj)->GetViewedArrayBuffer(); - break; - case JSType::JS_UINT32_ARRAY: - buffer = JSUint32Array::Cast(*obj)->GetViewedArrayBuffer(); - break; - case JSType::JS_FLOAT32_ARRAY: - buffer = JSFloat32Array::Cast(*obj)->GetViewedArrayBuffer(); - break; - case JSType::JS_FLOAT64_ARRAY: - buffer = JSFloat64Array::Cast(*obj)->GetViewedArrayBuffer(); - break; - default: - break; - } - return buffer; -} - -JSHandle TypedArrayHelper::GetTypedArrayName(JSThread *thread, const JSHandle &obj) -{ - JSType type = obj->GetJSHClass()->GetObjectType(); - JSTaggedValue name; - switch (type) { - case JSType::JS_INT8_ARRAY: - name = JSInt8Array::Cast(*obj)->GetTypedArrayName(); - break; - case JSType::JS_UINT8_ARRAY: - name = JSUint8Array::Cast(*obj)->GetTypedArrayName(); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - name = JSUint8ClampedArray::Cast(*obj)->GetTypedArrayName(); - break; - case JSType::JS_INT16_ARRAY: - name = JSInt16Array::Cast(*obj)->GetTypedArrayName(); - break; - case JSType::JS_UINT16_ARRAY: - name = JSUint16Array::Cast(*obj)->GetTypedArrayName(); - break; - case JSType::JS_INT32_ARRAY: - name = JSInt32Array::Cast(*obj)->GetTypedArrayName(); - break; - case JSType::JS_UINT32_ARRAY: - name = JSUint32Array::Cast(*obj)->GetTypedArrayName(); - break; - case JSType::JS_FLOAT32_ARRAY: - name = JSFloat32Array::Cast(*obj)->GetTypedArrayName(); - break; - case JSType::JS_FLOAT64_ARRAY: - name = JSFloat64Array::Cast(*obj)->GetTypedArrayName(); - break; - default: - break; - } - return JSHandle(thread, name); -} - -int32_t TypedArrayHelper::GetByteLength(JSThread *thread, const JSHandle &obj) -{ - JSType type = obj->GetJSHClass()->GetObjectType(); - JSTaggedValue length; - switch (type) { - case JSType::JS_INT8_ARRAY: - length = JSInt8Array::Cast(*obj)->GetByteLength(); - break; - case JSType::JS_UINT8_ARRAY: - length = JSUint8Array::Cast(*obj)->GetByteLength(); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - length = JSUint8ClampedArray::Cast(*obj)->GetByteLength(); - break; - case JSType::JS_INT16_ARRAY: - length = JSInt16Array::Cast(*obj)->GetByteLength(); - break; - case JSType::JS_UINT16_ARRAY: - length = JSUint16Array::Cast(*obj)->GetByteLength(); - break; - case JSType::JS_INT32_ARRAY: - length = JSInt32Array::Cast(*obj)->GetByteLength(); - break; - case JSType::JS_UINT32_ARRAY: - length = JSUint32Array::Cast(*obj)->GetByteLength(); - break; - case JSType::JS_FLOAT32_ARRAY: - length = JSFloat32Array::Cast(*obj)->GetByteLength(); - break; - case JSType::JS_FLOAT64_ARRAY: - length = JSFloat64Array::Cast(*obj)->GetByteLength(); - break; - default: - break; - } - return JSTaggedValue::ToLength(thread, JSHandle(thread, length)).ToInt32(); -} - int32_t TypedArrayHelper::GetByteOffset(JSThread *thread, const JSHandle &obj) { - JSType type = obj->GetJSHClass()->GetObjectType(); - JSTaggedValue length; - switch (type) { - case JSType::JS_INT8_ARRAY: - length = JSInt8Array::Cast(*obj)->GetByteOffset(); - break; - case JSType::JS_UINT8_ARRAY: - length = JSUint8Array::Cast(*obj)->GetByteOffset(); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - length = JSUint8ClampedArray::Cast(*obj)->GetByteOffset(); - break; - case JSType::JS_INT16_ARRAY: - length = JSInt16Array::Cast(*obj)->GetByteOffset(); - break; - case JSType::JS_UINT16_ARRAY: - length = JSUint16Array::Cast(*obj)->GetByteOffset(); - break; - case JSType::JS_INT32_ARRAY: - length = JSInt32Array::Cast(*obj)->GetByteOffset(); - break; - case JSType::JS_UINT32_ARRAY: - length = JSUint32Array::Cast(*obj)->GetByteOffset(); - break; - case JSType::JS_FLOAT32_ARRAY: - length = JSFloat32Array::Cast(*obj)->GetByteOffset(); - break; - case JSType::JS_FLOAT64_ARRAY: - length = JSFloat64Array::Cast(*obj)->GetByteOffset(); - break; - default: - break; - } + JSTaggedValue length = JSTypedArray::Cast(*obj)->GetByteOffset(); return JSTaggedValue::ToLength(thread, JSHandle(thread, length)).ToInt32(); } int32_t TypedArrayHelper::GetArrayLength(JSThread *thread, const JSHandle &obj) { - JSType type = obj->GetJSHClass()->GetObjectType(); - JSTaggedValue length; - switch (type) { - case JSType::JS_INT8_ARRAY: - length = JSInt8Array::Cast(*obj)->GetArrayLength(); - break; - case JSType::JS_UINT8_ARRAY: - length = JSUint8Array::Cast(*obj)->GetArrayLength(); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - length = JSUint8ClampedArray::Cast(*obj)->GetArrayLength(); - break; - case JSType::JS_INT16_ARRAY: - length = JSInt16Array::Cast(*obj)->GetArrayLength(); - break; - case JSType::JS_UINT16_ARRAY: - length = JSUint16Array::Cast(*obj)->GetArrayLength(); - break; - case JSType::JS_INT32_ARRAY: - length = JSInt32Array::Cast(*obj)->GetArrayLength(); - break; - case JSType::JS_UINT32_ARRAY: - length = JSUint32Array::Cast(*obj)->GetArrayLength(); - break; - case JSType::JS_FLOAT32_ARRAY: - length = JSFloat32Array::Cast(*obj)->GetArrayLength(); - break; - case JSType::JS_FLOAT64_ARRAY: - length = JSFloat64Array::Cast(*obj)->GetArrayLength(); - break; - default: - break; - } + JSTaggedValue length = JSTypedArray::Cast(*obj)->GetArrayLength(); return JSTaggedValue::ToLength(thread, JSHandle(thread, length)).ToInt32(); } } // namespace panda::ecmascript::base -#endif // PANDA_RUNTIME_ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_INL_H +#endif // ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_INL_H diff --git a/ecmascript/base/typed_array_helper.cpp b/ecmascript/base/typed_array_helper.cpp index 6205a51a179ab648303d32fbc690d96f4e810fd2..dcd4ab8de35fb8796aafa0b9b9ebd5032f81fe65 100644 --- a/ecmascript/base/typed_array_helper.cpp +++ b/ecmascript/base/typed_array_helper.cpp @@ -22,22 +22,14 @@ #include "ecmascript/ecma_macros.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_array_iterator.h" #include "ecmascript/js_arraybuffer.h" -#include "ecmascript/js_float32_array.h" -#include "ecmascript/js_float64_array.h" #include "ecmascript/js_hclass.h" -#include "ecmascript/js_int16_array.h" -#include "ecmascript/js_int32_array.h" -#include "ecmascript/js_int8_array.h" #include "ecmascript/js_object-inl.h" #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/js_tagged_value.h" #include "ecmascript/js_typed_array.h" -#include "ecmascript/js_uint16_array.h" -#include "ecmascript/js_uint32_array.h" -#include "ecmascript/js_uint8_array.h" -#include "ecmascript/js_uint8_clamped_array.h" #include "ecmascript/object_factory.h" namespace panda::ecmascript::base { @@ -188,7 +180,7 @@ JSTaggedValue TypedArrayHelper::CreateFromTypedArray(EcmaRuntimeCallInfo *argv, JSHandle srcArray = BuiltinsBase::GetCallArg(argv, 0); JSHandle srcObj(srcArray); // 6. Let srcData be srcArray.[[ViewedArrayBuffer]]. - JSHandle srcData(thread, TypedArrayHelper::GetViewedArrayBuffer(srcObj)); + JSHandle srcData(thread, JSTypedArray::Cast(*srcObj)->GetViewedArrayBuffer()); // 7. If IsDetachedBuffer(srcData) is true, throw a TypeError exception. if (BuiltinsArrayBuffer::IsDetachedBuffer(srcData.GetTaggedValue())) { THROW_TYPE_ERROR_AND_RETURN(thread, "The srcData is detached buffer.", JSTaggedValue::Exception()); @@ -200,7 +192,7 @@ JSTaggedValue TypedArrayHelper::CreateFromTypedArray(EcmaRuntimeCallInfo *argv, // 11. Let srcType be the Element Type value in Table 61 for srcName. // 12. Let srcElementSize be the Element Size value specified in Table 61 for srcName. int32_t elementLength = TypedArrayHelper::GetArrayLength(thread, srcObj); - JSHandle srcName = TypedArrayHelper::GetTypedArrayName(thread, srcObj); + JSHandle srcName(thread, JSTypedArray::Cast(*srcObj)->GetTypedArrayName()); DataViewType srcType = TypedArrayHelper::GetTypeFromName(thread, srcName); int32_t srcElementSize = TypedArrayHelper::GetSizeFromName(thread, srcName); // 13. Let srcByteOffset be srcArray.[[ByteOffset]]. @@ -257,10 +249,10 @@ JSTaggedValue TypedArrayHelper::CreateFromTypedArray(EcmaRuntimeCallInfo *argv, // 20. Set O’s [[ByteLength]] internal slot to byteLength. // 21. Set O’s [[ByteOffset]] internal slot to 0. // 22. Set O’s [[ArrayLength]] internal slot to elementLength. - TypedArrayHelper::SetViewedArrayBuffer(thread, obj, data); - TypedArrayHelper::SetByteLength(thread, obj, byteLength); - TypedArrayHelper::SetByteOffset(thread, obj, 0); - TypedArrayHelper::SetArrayLength(thread, obj, elementLength); + JSTypedArray::Cast(*obj)->SetViewedArrayBuffer(thread, data); + JSTypedArray::Cast(*obj)->SetByteLength(thread, JSTaggedValue(byteLength)); + JSTypedArray::Cast(*obj)->SetByteOffset(thread, JSTaggedValue(0)); + JSTypedArray::Cast(*obj)->SetArrayLength(thread, JSTaggedValue(elementLength)); // 23. Return O. return obj.GetTaggedValue(); } @@ -329,10 +321,10 @@ JSTaggedValue TypedArrayHelper::CreateFromArrayBuffer(EcmaRuntimeCallInfo *argv, // 14. Set O.[[ByteLength]] to newByteLength. // 15. Set O.[[ByteOffset]] to offset. // 16. Set O.[[ArrayLength]] to newByteLength / elementSize. - TypedArrayHelper::SetViewedArrayBuffer(thread, obj, buffer.GetTaggedValue()); - TypedArrayHelper::SetByteLength(thread, obj, newByteLength); - TypedArrayHelper::SetByteOffset(thread, obj, offset); - TypedArrayHelper::SetArrayLength(thread, obj, newByteLength / elementSize); + JSTypedArray::Cast(*obj)->SetViewedArrayBuffer(thread, buffer); + JSTypedArray::Cast(*obj)->SetByteLength(thread, JSTaggedValue(newByteLength)); + JSTypedArray::Cast(*obj)->SetByteOffset(thread, JSTaggedValue(offset)); + JSTypedArray::Cast(*obj)->SetArrayLength(thread, JSTaggedValue(newByteLength / elementSize)); // 17. Return O. return obj.GetTaggedValue(); } @@ -355,10 +347,10 @@ JSHandle TypedArrayHelper::AllocateTypedArray(ObjectFactory *factory, // a. Set obj.[[ByteLength]] to 0. // b. Set obj.[[ByteOffset]] to 0. // c. Set obj.[[ArrayLength]] to 0. - TypedArrayHelper::SetTypedArrayName(thread, obj, constructorName); - TypedArrayHelper::SetByteLength(thread, obj, 0); - TypedArrayHelper::SetByteOffset(thread, obj, 0); - TypedArrayHelper::SetArrayLength(thread, obj, 0); + JSTypedArray::Cast(*obj)->SetTypedArrayName(thread, constructorName); + JSTypedArray::Cast(*obj)->SetByteLength(thread, JSTaggedValue(0)); + JSTypedArray::Cast(*obj)->SetByteOffset(thread, JSTaggedValue(0)); + JSTypedArray::Cast(*obj)->SetArrayLength(thread, JSTaggedValue(0)); // 9. Return obj. return obj; } // namespace panda::ecmascript::base @@ -377,7 +369,7 @@ JSHandle TypedArrayHelper::AllocateTypedArray(ObjectFactory *factory, RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSHandle(thread, JSTaggedValue::Exception())); // 3. Assert: obj.[[ViewedArrayBuffer]] is undefined. // 4. Set obj.[[TypedArrayName]] to constructorName. - TypedArrayHelper::SetTypedArrayName(thread, obj, constructorName); + JSTypedArray::Cast(*obj)->SetTypedArrayName(thread, constructorName); // 7. If length is not present, then // 8. Else, // a. Perform ? AllocateTypedArrayBuffer(obj, length). @@ -402,7 +394,7 @@ JSHandle TypedArrayHelper::AllocateTypedArrayBuffer(JSThread *thread, THROW_RANGE_ERROR_AND_RETURN(thread, "array length must less than 2^32 - 1", exception); } // 4. Let constructorName be the String value of O.[[TypedArrayName]]. - JSHandle constructorName = TypedArrayHelper::GetTypedArrayName(thread, obj); + JSHandle constructorName(thread, JSTypedArray::Cast(*obj)->GetTypedArrayName()); // 5. Let elementSize be the Element Size value specified in Table 61 for constructorName. int32_t elementSize = TypedArrayHelper::GetSizeFromName(thread, constructorName); // 6. Let byteLength be elementSize × length. @@ -415,17 +407,17 @@ JSHandle TypedArrayHelper::AllocateTypedArrayBuffer(JSThread *thread, // 9. Set O.[[ByteLength]] to byteLength. // 10. Set O.[[ByteOffset]] to 0. // 11. Set O.[[ArrayLength]] to length. - TypedArrayHelper::SetViewedArrayBuffer(thread, obj, data); - TypedArrayHelper::SetByteLength(thread, obj, byteLength); - TypedArrayHelper::SetByteOffset(thread, obj, 0); - TypedArrayHelper::SetArrayLength(thread, obj, length); + JSTypedArray::Cast(*obj)->SetViewedArrayBuffer(thread, data); + JSTypedArray::Cast(*obj)->SetByteLength(thread, JSTaggedValue(byteLength)); + JSTypedArray::Cast(*obj)->SetByteOffset(thread, JSTaggedValue(0)); + JSTypedArray::Cast(*obj)->SetArrayLength(thread, JSTaggedValue(length)); // 12. Return O. return obj; } // es11 22.2.4.7 TypedArraySpeciesCreate ( exemplar, argumentList ) JSHandle TypedArrayHelper::TypedArraySpeciesCreate(JSThread *thread, const JSHandle &obj, - const JSHandle &argumentList) + uint32_t argc, const JSTaggedType argv[]) { // 1. Assert: exemplar is an Object that has [[TypedArrayName]] and [[ContentType]] internal slots. // 2. Let defaultConstructor be the intrinsic object listed in column one of Table 61 for @@ -435,18 +427,17 @@ JSHandle TypedArrayHelper::TypedArraySpeciesCreate(JSThread *thread, c JSHandle thisConstructor = JSObject::SpeciesConstructor(thread, obj, defaultConstructor); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSHandle(thread, JSTaggedValue::Exception())); // 4. Let result be ? TypedArrayCreate(constructor, argumentList). - return TypedArrayHelper::TypedArrayCreate(thread, thisConstructor, argumentList); + return TypedArrayHelper::TypedArrayCreate(thread, thisConstructor, argc, argv); } // es11 22.2.4.6 TypedArrayCreate ( constructor, argumentList ) JSHandle TypedArrayHelper::TypedArrayCreate(JSThread *thread, const JSHandle &constructor, - const JSHandle &argumentList) + uint32_t argc, const JSTaggedType argv[]) { // 1. Let newTypedArray be ? Construct(constructor, argumentList). - JSTaggedValue taggedArray = JSFunction::Construct(thread, constructor, argumentList, + JSTaggedValue taggedArray = JSFunction::Construct(thread, constructor, argc, argv, JSHandle(thread, JSTaggedValue::Undefined())); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSHandle(thread, JSTaggedValue::Exception())); - [[maybe_unused]] JSType type = taggedArray.GetTaggedObject()->GetClass()->GetObjectType(); if (!taggedArray.IsECMAObject()) { THROW_TYPE_ERROR_AND_RETURN(thread, "Failed to construct the Typedarray.", JSHandle(thread, JSTaggedValue::Exception())); @@ -458,9 +449,9 @@ JSHandle TypedArrayHelper::TypedArrayCreate(JSThread *thread, const JS JSHandle newTypedArray(taggedArrayHandle); // 3. If argumentList is a List of a single Number, then // a. If newTypedArray.[[ArrayLength]] < argumentList[0], throw a TypeError exception. - if (argumentList->GetLength() == 1) { + if (argc == 1) { if (TypedArrayHelper::GetArrayLength(thread, newTypedArray) < - JSTaggedValue::ToInt32(thread, JSHandle(thread, argumentList->Get(0)))) { + JSTaggedValue::ToInt32(thread, JSHandle(thread, JSTaggedValue(argv[0])))) { THROW_TYPE_ERROR_AND_RETURN(thread, "the length of newTypedArray is not a correct value.", JSHandle(thread, JSTaggedValue::Exception())); } @@ -479,7 +470,7 @@ JSTaggedValue TypedArrayHelper::ValidateTypedArray(JSThread *thread, const JSHan } // 3. Let buffer be O.[[ViewedArrayBuffer]]. // 4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. - JSTaggedValue buffer = TypedArrayHelper::GetViewedArrayBuffer(JSHandle::Cast(value)); + JSTaggedValue buffer = JSHandle::Cast(value)->GetViewedArrayBuffer(); if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { THROW_TYPE_ERROR_AND_RETURN(thread, "The ViewedArrayBuffer of O is detached buffer.", JSTaggedValue::Exception()); @@ -489,12 +480,12 @@ JSTaggedValue TypedArrayHelper::ValidateTypedArray(JSThread *thread, const JSHan } int32_t TypedArrayHelper::SortCompare(JSThread *thread, const JSHandle &callbackfnHandle, - const JSHandle &buffer, const JSHandle &x, - const JSHandle &y) + const JSHandle &buffer, const JSHandle &firstValue, + const JSHandle &secondValue) { const GlobalEnvConstants *globalConst = thread->GlobalConstants(); // 1. Assert: Both Type(x) and Type(y) is Number. - ASSERT(x->IsNumber() && y->IsNumber()); + ASSERT(firstValue->IsNumber() && secondValue->IsNumber()); // 2. If the argument comparefn is not undefined, then // a. Let v be Call(comparefn, undefined, «x, y»). // b. ReturnIfAbrupt(v). @@ -502,12 +493,11 @@ int32_t TypedArrayHelper::SortCompare(JSThread *thread, const JSHandleIsUndefined()) { - const array_size_t LEN = 2; - JSHandle msg = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(LEN); JSHandle thisArgHandle = globalConst->GetHandledUndefined(); - msg->Set(thread, 0, x); - msg->Set(thread, 1, y); - JSTaggedValue callResult = JSFunction::Call(thread, callbackfnHandle, thisArgHandle, msg); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(firstValue, secondValue); + JSTaggedValue callResult = + JSFunction::Call(thread, callbackfnHandle, thisArgHandle, 2, arguments->GetArgv()); // 2: two args RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, 0); if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer.GetTaggedValue())) { THROW_TYPE_ERROR_AND_RETURN(thread, "The buffer is detached buffer.", 0); @@ -522,18 +512,18 @@ int32_t TypedArrayHelper::SortCompare(JSThread *thread, const JSHandle y, return 1. // 8. If x is -0 and y is +0, return -1. @@ -545,8 +535,8 @@ int32_t TypedArrayHelper::SortCompare(JSThread *thread, const JSHandle &constructorName, const JSHandle &newTarget, int32_t length); static JSHandle TypedArraySpeciesCreate(JSThread *thread, const JSHandle &obj, - const JSHandle &argumentList); + uint32_t argc, const JSTaggedType argv[]); static JSHandle TypedArrayCreate(JSThread *thread, const JSHandle &constructor, - const JSHandle &argumentList); + uint32_t argc, const JSTaggedType argv[]); static JSTaggedValue ValidateTypedArray(JSThread *thread, const JSHandle &value); inline static DataViewType GetType(const JSHandle &obj); inline static int32_t GetElementSize(const JSHandle &obj); @@ -46,14 +46,11 @@ public: inline static JSHandle GetConstructorFromName(JSThread *thread, const JSHandle &typeName); inline static int32_t GetSizeFromName(JSThread *thread, const JSHandle &typeName); - inline static JSTaggedValue GetViewedArrayBuffer(const JSHandle &obj); - inline static JSHandle GetTypedArrayName(JSThread *thread, const JSHandle &obj); - inline static int32_t GetByteLength(JSThread *thread, const JSHandle &obj); inline static int32_t GetByteOffset(JSThread *thread, const JSHandle &obj); inline static int32_t GetArrayLength(JSThread *thread, const JSHandle &obj); static int32_t SortCompare(JSThread *thread, const JSHandle &callbackfnHandle, - const JSHandle &buffer, const JSHandle &x, - const JSHandle &y); + const JSHandle &buffer, const JSHandle &firstValue, + const JSHandle &secondValue); private: static JSTaggedValue CreateFromOrdinaryObject(EcmaRuntimeCallInfo *argv, const JSHandle &obj); @@ -63,14 +60,7 @@ private: const JSHandle &constructorName); static JSHandle AllocateTypedArrayBuffer(JSThread *thread, EcmaVM *ecmaVm, const JSHandle &obj, double length); - inline static void SetViewedArrayBuffer(JSThread *thread, const JSHandle &obj, - JSTaggedValue viewedArrayBuffer); - inline static void SetTypedArrayName(JSThread *thread, const JSHandle &obj, - const JSHandle &typedArrayName); - inline static void SetByteLength(JSThread *thread, const JSHandle &obj, int32_t byteLength); - inline static void SetByteOffset(JSThread *thread, const JSHandle &obj, int32_t byteOffset); - inline static void SetArrayLength(JSThread *thread, const JSHandle &obj, int32_t arrayLength); }; } // namespace panda::ecmascript::base -#endif // PANDA_RUNTIME_ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_H +#endif // ECMASCRIPT_BASE_TYPED_ARRAY_HELPER_H diff --git a/ecmascript/base/utf_helper.h b/ecmascript/base/utf_helper.h index 6d4dce08d40610ede3090e3791e9cfa8c707eab9..29abed490829a3e6d433f3755d681e37f6a3e7ba 100644 --- a/ecmascript/base/utf_helper.h +++ b/ecmascript/base/utf_helper.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BASE_UTF_HELPER_H -#define PANDA_RUNTIME_ECMASCRIPT_BASE_UTF_HELPER_H +#ifndef ECMASCRIPT_BASE_UTF_HELPER_H +#define ECMASCRIPT_BASE_UTF_HELPER_H #include #include @@ -83,4 +83,4 @@ static inline uint32_t CombineTwoU16(uint16_t d0, uint16_t d1) } } // namespace panda::ecmascript::base::utf_helper -#endif // PANDA_RUNTIME_ECMASCRIPT_BASE_UTF_HELPER_H \ No newline at end of file +#endif // ECMASCRIPT_BASE_UTF_HELPER_H \ No newline at end of file diff --git a/ecmascript/builtins.cpp b/ecmascript/builtins.cpp index 18e8ec274be157d69266097fd852fae324263b3d..239543543a0bf7c584273e21edc2885e306bd130 100644 --- a/ecmascript/builtins.cpp +++ b/ecmascript/builtins.cpp @@ -13,31 +13,39 @@ * limitations under the License. */ +#include "ecmascript/builtins.h" + #include "ecmascript/base/error_type.h" #include "ecmascript/base/number_helper.h" -#include "ecmascript/builtins.h" #include "ecmascript/builtins/builtins_array.h" #include "ecmascript/builtins/builtins_arraybuffer.h" #include "ecmascript/builtins/builtins_async_function.h" #include "ecmascript/builtins/builtins_boolean.h" +#include "ecmascript/builtins/builtins_collator.h" #include "ecmascript/builtins/builtins_dataview.h" #include "ecmascript/builtins/builtins_date.h" +#include "ecmascript/builtins/builtins_date_time_format.h" #include "ecmascript/builtins/builtins_errors.h" #include "ecmascript/builtins/builtins_function.h" #include "ecmascript/builtins/builtins_generator.h" #include "ecmascript/builtins/builtins_global.h" +#include "ecmascript/builtins/builtins_intl.h" #include "ecmascript/builtins/builtins_iterator.h" #include "ecmascript/builtins/builtins_json.h" +#include "ecmascript/builtins/builtins_locale.h" #include "ecmascript/builtins/builtins_map.h" #include "ecmascript/builtins/builtins_math.h" #include "ecmascript/builtins/builtins_number.h" +#include "ecmascript/builtins/builtins_number_format.h" #include "ecmascript/builtins/builtins_object.h" +#include "ecmascript/builtins/builtins_plural_rules.h" #include "ecmascript/builtins/builtins_promise.h" #include "ecmascript/builtins/builtins_promise_handler.h" #include "ecmascript/builtins/builtins_promise_job.h" #include "ecmascript/builtins/builtins_proxy.h" #include "ecmascript/builtins/builtins_reflect.h" #include "ecmascript/builtins/builtins_regexp.h" +#include "ecmascript/builtins/builtins_relative_time_format.h" #include "ecmascript/builtins/builtins_set.h" #include "ecmascript/builtins/builtins_string.h" #include "ecmascript/builtins/builtins_string_iterator.h" @@ -46,35 +54,31 @@ #include "ecmascript/builtins/builtins_weak_map.h" #include "ecmascript/builtins/builtins_weak_set.h" #include "ecmascript/ecma_runtime_call_info.h" - #include "ecmascript/js_array.h" -#include "ecmascript/js_array_iterator.h" #include "ecmascript/js_arraybuffer.h" +#include "ecmascript/js_array_iterator.h" #include "ecmascript/js_async_function.h" +#include "ecmascript/js_collator.h" #include "ecmascript/js_dataview.h" -#include "ecmascript/js_float32_array.h" -#include "ecmascript/js_float64_array.h" +#include "ecmascript/js_date_time_format.h" #include "ecmascript/js_for_in_iterator.h" #include "ecmascript/js_function.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_hclass.h" -#include "ecmascript/js_int16_array.h" -#include "ecmascript/js_int32_array.h" -#include "ecmascript/js_int8_array.h" +#include "ecmascript/js_locale.h" #include "ecmascript/js_map.h" #include "ecmascript/js_map_iterator.h" +#include "ecmascript/js_number_format.h" +#include "ecmascript/js_plural_rules.h" #include "ecmascript/js_primitive_ref.h" #include "ecmascript/js_promise.h" #include "ecmascript/js_regexp.h" +#include "ecmascript/js_relative_time_format.h" #include "ecmascript/js_set.h" #include "ecmascript/js_set_iterator.h" #include "ecmascript/js_string_iterator.h" #include "ecmascript/js_tagged_value.h" #include "ecmascript/js_typed_array.h" -#include "ecmascript/js_uint16_array.h" -#include "ecmascript/js_uint32_array.h" -#include "ecmascript/js_uint8_array.h" -#include "ecmascript/js_uint8_clamped_array.h" #include "ecmascript/js_weak_container.h" #include "ecmascript/mem/mem.h" #include "ecmascript/object_factory.h" @@ -119,6 +123,13 @@ using BuiltinsPromiseHandler = builtins::BuiltinsPromiseHandler; using BuiltinsPromiseJob = builtins::BuiltinsPromiseJob; using ErrorType = base::ErrorType; using DataView = builtins::BuiltinsDataView; +using Intl = builtins::BuiltinsIntl; +using Locale = builtins::BuiltinsLocale; +using DateTimeFormat = builtins::BuiltinsDateTimeFormat; +using RelativeTimeFormat = builtins::BuiltinsRelativeTimeFormat; +using NumberFormat = builtins::BuiltinsNumberFormat; +using Collator = builtins::BuiltinsCollator; +using PluralRules = builtins::BuiltinsPluralRules; void Builtins::Initialize(const JSHandle &env, JSThread *thread) { @@ -257,7 +268,20 @@ void Builtins::Initialize(const JSHandle &env, JSThread *thread) InitializePromise(env, objFuncDynclass); InitializePromiseJob(env); - SetHwIcuDirectory(); + RuntimeOptions options = vm_->GetOptions(); + std::string icuPath = options.GetIcuDataPath(); + if (icuPath == "default") { + SetHwIcuDirectory(); + } else { + u_setDataDirectory(icuPath.c_str()); + } + InitializeIntl(env, objFuncPrototypeVal); + InitializeLocale(env); + InitializeDateTimeFormat(env); + InitializeNumberFormat(env); + InitializeRelativeTimeFormat(env); + InitializeCollator(env); + InitializePluralRules(env); JSHandle generatorFuncClass = factory_->CreateFunctionClass(FunctionKind::GENERATOR_FUNCTION, JSFunction::SIZE, JSType::JS_GENERATOR_FUNCTION, @@ -273,7 +297,7 @@ void Builtins::InitializeGlobalObject(const JSHandle &env, const JSHa // Global object test SetFunction(env, globalObject, "print", Global::PrintEntrypoint, 0); -#ifdef PANDA_ECMASCRIPT_ENABLE_RUNTIME_STAT +#if ECMASCRIPT_ENABLE_RUNTIME_STAT SetFunction(env, globalObject, "startRuntimeStat", Global::StartRuntimeStat, 0); SetFunction(env, globalObject, "stopRuntimeStat", Global::StopRuntimeStat, 0); #endif @@ -332,6 +356,11 @@ void Builtins::InitializeFunction(const JSHandle &env, const JSHandle factory_->NewEcmaDynClass(JSFunction::SIZE, JSType::JS_FUNCTION, env->GetFunctionPrototype()); env->SetNormalFunctionClass(thread_, normalFuncClass); + JSHandle jSIntlBoundFunctionClass = + factory_->CreateFunctionClass(FunctionKind::NORMAL_FUNCTION, JSIntlBoundFunction::SIZE, + JSType::JS_INTL_BOUND_FUNCTION, env->GetFunctionPrototype()); + env->SetJSIntlBoundFunctionClass(thread_, jSIntlBoundFunctionClass); + JSHandle constructorFunctionClass = factory_->NewEcmaDynClass(JSFunction::SIZE, JSType::JS_FUNCTION, env->GetFunctionPrototype()); constructorFunctionClass->SetConstructor(true); @@ -415,7 +444,7 @@ void Builtins::InitializeObject(const JSHandle &env, const JSHandle protoKey(factory_->NewFromString("__proto__")); + JSHandle protoKey(factory_->NewFromCanBeCompressString("__proto__")); JSHandle protoGetter = CreateGetter(env, Object::ProtoGetter, "__proto__", FunctionLength::ZERO); JSHandle protoSetter = CreateSetter(env, Object::ProtoSetter, "__proto__", FunctionLength::ONE); SetAccessor(objFuncPrototype, protoKey, protoGetter, protoSetter); @@ -472,7 +501,7 @@ void Builtins::InitializeSymbol(const JSHandle &env, const JSHandle getterKey(factory_->NewFromString("description")); + JSHandle getterKey(factory_->NewFromCanBeCompressString("description")); JSHandle getter(factory_->NewJSFunction(env, reinterpret_cast(Symbol::DescriptionGetter))); SetGetter(symbolFuncPrototype, getterKey, getter); @@ -554,7 +583,7 @@ void Builtins::InitializeSymbolWithRealm(const JSHandle &realm, // symbol.prototype.description PropertyDescriptor descriptionDesc(thread_); - JSHandle getterKey(factory_->NewFromString("description")); + JSHandle getterKey(factory_->NewFromCanBeCompressString("description")); JSHandle getter(factory_->NewJSFunction(realm, reinterpret_cast(Symbol::DescriptionGetter))); SetGetter(symbolFuncPrototype, getterKey, getter); @@ -618,6 +647,7 @@ void Builtins::InitializeNumber(const JSHandle &env, const JSHandleGlobalConstants()->GetHandledToStringString(), Number::ToString, FunctionLength::ONE); @@ -706,6 +736,9 @@ void Builtins::InitializeDate(const JSHandle &env, const JSHandleGlobalConstants()->GetHandledToStringString(), Date::ToString, FunctionLength::ZERO); SetFunction(env, dateFuncPrototype, "toTimeString", Date::ToTimeString, FunctionLength::ZERO); @@ -1049,8 +1082,8 @@ void Builtins::InitializeSet(const JSHandle &env, const JSHandle keys(factory_->NewFromString("keys")); - JSHandle values(factory_->NewFromString("values")); + JSHandle keys(factory_->NewFromCanBeCompressString("keys")); + JSHandle values(factory_->NewFromCanBeCompressString("values")); JSHandle valuesFunc = JSObject::GetMethod(thread_, JSHandle::Cast(setFuncPrototype), values); PropertyDescriptor descriptor(thread_, valuesFunc, true, false, true); @@ -1061,7 +1094,7 @@ void Builtins::InitializeSet(const JSHandle &env, const JSHandle sizeGetter = CreateGetter(env, BuiltinsSet::GetSize, "size", FunctionLength::ZERO); - JSHandle sizeKey(factory_->NewFromString("size")); + JSHandle sizeKey(factory_->NewFromCanBeCompressString("size")); SetGetter(setFuncPrototype, sizeKey, sizeGetter); // 23.1.2.2get Set [ @@species ] @@ -1121,7 +1154,7 @@ void Builtins::InitializeMap(const JSHandle &env, const JSHandle sizeGetter = CreateGetter(env, BuiltinsMap::GetSize, "size", FunctionLength::ZERO); - JSHandle sizeKey(factory_->NewFromString("size")); + JSHandle sizeKey(factory_->NewFromCanBeCompressString("size")); SetGetter(mapFuncPrototype, sizeKey, sizeGetter); // 23.1.2.2get Map [ @@species ] @@ -1132,7 +1165,7 @@ void Builtins::InitializeMap(const JSHandle &env, const JSHandle iteratorSymbol = env->GetIteratorSymbol(); - JSHandle entries(factory_->NewFromString("entries")); + JSHandle entries(factory_->NewFromCanBeCompressString("entries")); JSHandle entriesFunc = JSObject::GetMethod(thread_, JSHandle::Cast(mapFuncPrototype), entries); PropertyDescriptor descriptor(thread_, entriesFunc, true, false, true); @@ -1259,7 +1292,7 @@ void Builtins::InitializeMath(const JSHandle &env, const JSHandle mathString(factory_->NewFromString("Math")); + JSHandle mathString(factory_->NewFromCanBeCompressString("Math")); JSHandle globalObject(thread_, env->GetGlobalObject()); PropertyDescriptor mathDesc(thread_, JSHandle::Cast(mathObject), true, false, true); JSObject::DefineOwnProperty(thread_, globalObject, mathString, mathDesc); @@ -1278,7 +1311,7 @@ void Builtins::InitializeJson(const JSHandle &env, const JSHandle::Cast(jsonObject), true, false, true); - JSHandle jsonString(factory_->NewFromString("JSON")); + JSHandle jsonString(factory_->NewFromCanBeCompressString("JSON")); JSHandle globalObject(thread_, env->GetGlobalObject()); JSObject::DefineOwnProperty(thread_, globalObject, jsonString, jsonDesc); // @@ToStringTag @@ -1316,6 +1349,7 @@ void Builtins::InitializeString(const JSHandle &env, const JSHandle &env, const JSHandleGlobalConstants()->GetHandledToStringString(), BuiltinsString::ToString, FunctionLength::ZERO); @@ -1340,7 +1376,7 @@ void Builtins::InitializeString(const JSHandle &env, const JSHandle lengthGetter = CreateGetter(env, BuiltinsString::GetLength, "length", FunctionLength::ZERO); - JSHandle lengthKey(factory_->NewFromString("length")); + JSHandle lengthKey(factory_->NewFromCanBeCompressString("length")); SetGetter(stringFuncPrototype, lengthKey, lengthGetter); env->SetStringFunction(thread_, stringFunction); @@ -1465,37 +1501,37 @@ void Builtins::InitializeRegExp(const JSHandle &env) FunctionLength::ZERO); JSHandle flagsGetter = CreateGetter(env, RegExp::GetFlags, "flags", FunctionLength::ZERO); - JSHandle flagsKey(factory_->NewFromString("flags")); + JSHandle flagsKey(factory_->NewFromCanBeCompressString("flags")); SetGetter(regPrototype, flagsKey, flagsGetter); JSHandle sourceGetter = CreateGetter(env, RegExp::GetSource, "source", FunctionLength::ZERO); - JSHandle sourceKey(factory_->NewFromString("source")); + JSHandle sourceKey(factory_->NewFromCanBeCompressString("source")); SetGetter(regPrototype, sourceKey, sourceGetter); JSHandle globalGetter = CreateGetter(env, RegExp::GetGlobal, "global", FunctionLength::ZERO); - JSHandle globalKey(factory_->NewFromString("global")); + JSHandle globalKey(factory_->NewFromCanBeCompressString("global")); SetGetter(regPrototype, globalKey, globalGetter); JSHandle ignoreCaseGetter = CreateGetter(env, RegExp::GetIgnoreCase, "ignoreCase", FunctionLength::ZERO); - JSHandle ignoreCaseKey(factory_->NewFromString("ignoreCase")); + JSHandle ignoreCaseKey(factory_->NewFromCanBeCompressString("ignoreCase")); SetGetter(regPrototype, ignoreCaseKey, ignoreCaseGetter); JSHandle multilineGetter = CreateGetter(env, RegExp::GetMultiline, "multiline", FunctionLength::ZERO); - JSHandle multilineKey(factory_->NewFromString("multiline")); + JSHandle multilineKey(factory_->NewFromCanBeCompressString("multiline")); SetGetter(regPrototype, multilineKey, multilineGetter); JSHandle dotAllGetter = CreateGetter(env, RegExp::GetDotAll, "dotAll", FunctionLength::ZERO); - JSHandle dotAllKey(factory_->NewFromString("dotAll")); + JSHandle dotAllKey(factory_->NewFromCanBeCompressString("dotAll")); SetGetter(regPrototype, dotAllKey, dotAllGetter); JSHandle stickyGetter = CreateGetter(env, RegExp::GetSticky, "sticky", FunctionLength::ZERO); - JSHandle stickyKey(factory_->NewFromString("sticky")); + JSHandle stickyKey(factory_->NewFromCanBeCompressString("sticky")); SetGetter(regPrototype, stickyKey, stickyGetter); JSHandle unicodeGetter = CreateGetter(env, RegExp::GetUnicode, "unicode", FunctionLength::ZERO); - JSHandle unicodeKey(factory_->NewFromString("unicode")); + JSHandle unicodeKey(factory_->NewFromCanBeCompressString("unicode")); SetGetter(regPrototype, unicodeKey, unicodeGetter); // Set RegExp [ @@species ] @@ -1581,7 +1617,7 @@ void Builtins::InitializeArray(const JSHandle &env, const JSHandle values(factory_->NewFromString("values")); + JSHandle values(factory_->NewFromCanBeCompressString("values")); JSHandle iteratorSymbol = env->GetIteratorSymbol(); JSHandle valuesFunc = JSObject::GetMethod(thread_, JSHandle::Cast(arrFuncPrototype), values); @@ -1605,7 +1641,7 @@ void Builtins::InitializeArray(const JSHandle &env, const JSHandle valuesKey(factory_->NewFromString("values")); + JSHandle valuesKey(factory_->NewFromCanBeCompressString("values")); PropertyDescriptor desc(thread_); JSObject::GetOwnProperty(thread_, arrFuncPrototype, valuesKey, desc); @@ -1666,22 +1702,22 @@ void Builtins::InitializeTypedArray(const JSHandle &env, const JSHand JSHandle bufferGetter = CreateGetter(env, BuiltinsTypedArray::GetBuffer, "buffer", FunctionLength::ZERO); - JSHandle bufferKey(factory_->NewFromString("buffer")); + JSHandle bufferKey(factory_->NewFromCanBeCompressString("buffer")); SetGetter(typedArrFuncPrototype, bufferKey, bufferGetter); JSHandle byteLengthGetter = CreateGetter(env, BuiltinsTypedArray::GetByteLength, "byteLength", FunctionLength::ZERO); - JSHandle byteLengthKey(factory_->NewFromString("byteLength")); + JSHandle byteLengthKey(factory_->NewFromCanBeCompressString("byteLength")); SetGetter(typedArrFuncPrototype, byteLengthKey, byteLengthGetter); JSHandle byteOffsetGetter = CreateGetter(env, BuiltinsTypedArray::GetByteOffset, "byteOffset", FunctionLength::ZERO); - JSHandle byteOffsetKey(factory_->NewFromString("byteOffset")); + JSHandle byteOffsetKey(factory_->NewFromCanBeCompressString("byteOffset")); SetGetter(typedArrFuncPrototype, byteOffsetKey, byteOffsetGetter); JSHandle lengthGetter = CreateGetter(env, BuiltinsTypedArray::GetLength, "length", FunctionLength::ZERO); - JSHandle lengthKey(factory_->NewFromString("length")); + JSHandle lengthKey(factory_->NewFromCanBeCompressString("length")); SetGetter(typedArrFuncPrototype, lengthKey, lengthGetter); // %TypedArray%.prototype.toString() @@ -1693,7 +1729,7 @@ void Builtins::InitializeTypedArray(const JSHandle &env, const JSHand toStringDesc); // %TypedArray%.prototype [ @@iterator ] ( ) - JSHandle values(factory_->NewFromString("values")); + JSHandle values(factory_->NewFromCanBeCompressString("values")); JSHandle iteratorSymbol = env->GetIteratorSymbol(); JSHandle valuesFunc = JSObject::GetMethod(thread_, JSHandle::Cast(typedArrFuncPrototype), values); @@ -1746,7 +1782,7 @@ void Builtins::InitializeInt8Array(const JSHandle &env, const JSHandl // Int8Array.prototype_or_dynclass JSHandle int8ArrFuncInstanceDynclass = factory_->NewEcmaDynClass( - panda::ecmascript::JSInt8Array::SIZE, JSType::JS_INT8_ARRAY, int8ArrFuncPrototypeValue); + panda::ecmascript::JSTypedArray::SIZE, JSType::JS_INT8_ARRAY, int8ArrFuncPrototypeValue); // Int8Array = new Function() JSHandle int8ArrayFunction = factory_->NewSpecificTypedArrayFunction( @@ -1770,7 +1806,7 @@ void Builtins::InitializeUint8Array(const JSHandle &env, const JSHand // Uint8Array.prototype_or_dynclass JSHandle uint8ArrFuncInstanceDynclass = factory_->NewEcmaDynClass( - panda::ecmascript::JSUint8Array::SIZE, JSType::JS_UINT8_ARRAY, uint8ArrFuncPrototypeValue); + panda::ecmascript::JSTypedArray::SIZE, JSType::JS_UINT8_ARRAY, uint8ArrFuncPrototypeValue); // Uint8Array = new Function() JSHandle uint8ArrayFunction = factory_->NewSpecificTypedArrayFunction( @@ -1795,7 +1831,7 @@ void Builtins::InitializeUint8ClampedArray(const JSHandle &env, // Uint8ClampedArray.prototype_or_dynclass JSHandle uint8ClampedArrFuncInstanceDynclass = - factory_->NewEcmaDynClass(panda::ecmascript::JSUint8ClampedArray::SIZE, JSType::JS_UINT8_CLAMPED_ARRAY, + factory_->NewEcmaDynClass(panda::ecmascript::JSTypedArray::SIZE, JSType::JS_UINT8_CLAMPED_ARRAY, uint8ClampedArrFuncPrototypeValue); // Uint8ClampedArray = new Function() @@ -1821,7 +1857,7 @@ void Builtins::InitializeInt16Array(const JSHandle &env, const JSHand // Int16Array.prototype_or_dynclass JSHandle int16ArrFuncInstanceDynclass = factory_->NewEcmaDynClass( - panda::ecmascript::JSInt16Array::SIZE, JSType::JS_INT16_ARRAY, int16ArrFuncPrototypeValue); + panda::ecmascript::JSTypedArray::SIZE, JSType::JS_INT16_ARRAY, int16ArrFuncPrototypeValue); // Int16Array = new Function() JSHandle int16ArrayFunction = factory_->NewSpecificTypedArrayFunction( @@ -1845,7 +1881,7 @@ void Builtins::InitializeUint16Array(const JSHandle &env, const JSHan // Uint16Array.prototype_or_dynclass JSHandle uint16ArrFuncInstanceDynclass = factory_->NewEcmaDynClass( - panda::ecmascript::JSUint16Array::SIZE, JSType::JS_UINT16_ARRAY, uint16ArrFuncPrototypeValue); + panda::ecmascript::JSTypedArray::SIZE, JSType::JS_UINT16_ARRAY, uint16ArrFuncPrototypeValue); // Uint16Array = new Function() JSHandle uint16ArrayFunction = factory_->NewSpecificTypedArrayFunction( @@ -1869,7 +1905,7 @@ void Builtins::InitializeInt32Array(const JSHandle &env, const JSHand // Int32Array.prototype_or_dynclass JSHandle int32ArrFuncInstanceDynclass = factory_->NewEcmaDynClass( - panda::ecmascript::JSInt32Array::SIZE, JSType::JS_INT32_ARRAY, int32ArrFuncPrototypeValue); + panda::ecmascript::JSTypedArray::SIZE, JSType::JS_INT32_ARRAY, int32ArrFuncPrototypeValue); // Int32Array = new Function() JSHandle int32ArrayFunction = factory_->NewSpecificTypedArrayFunction( @@ -1893,7 +1929,7 @@ void Builtins::InitializeUint32Array(const JSHandle &env, const JSHan // Uint32Array.prototype_or_dynclass JSHandle uint32ArrFuncInstanceDynclass = factory_->NewEcmaDynClass( - panda::ecmascript::JSUint32Array::SIZE, JSType::JS_UINT32_ARRAY, uint32ArrFuncPrototypeValue); + panda::ecmascript::JSTypedArray::SIZE, JSType::JS_UINT32_ARRAY, uint32ArrFuncPrototypeValue); // Uint32Array = new Function() JSHandle uint32ArrayFunction = factory_->NewSpecificTypedArrayFunction( @@ -1917,7 +1953,7 @@ void Builtins::InitializeFloat32Array(const JSHandle &env, const JSHa // Float32Array.prototype_or_dynclass JSHandle float32ArrFuncInstanceDynclass = factory_->NewEcmaDynClass( - panda::ecmascript::JSFloat32Array::SIZE, JSType::JS_FLOAT32_ARRAY, float32ArrFuncPrototypeValue); + panda::ecmascript::JSTypedArray::SIZE, JSType::JS_FLOAT32_ARRAY, float32ArrFuncPrototypeValue); // Float32Array = new Function() JSHandle float32ArrayFunction = factory_->NewSpecificTypedArrayFunction( @@ -1941,7 +1977,7 @@ void Builtins::InitializeFloat64Array(const JSHandle &env, const JSHa // Float64Array.prototype_or_dynclass JSHandle float64ArrFuncInstanceDynclass = factory_->NewEcmaDynClass( - panda::ecmascript::JSFloat64Array::SIZE, JSType::JS_FLOAT64_ARRAY, float64ArrFuncPrototypeValue); + panda::ecmascript::JSTypedArray::SIZE, JSType::JS_FLOAT64_ARRAY, float64ArrFuncPrototypeValue); // Float64Array = new Function() JSHandle float64ArrayFunction = factory_->NewSpecificTypedArrayFunction( @@ -1989,7 +2025,7 @@ void Builtins::InitializeArrayBuffer(const JSHandle &env, const JSHan // 24.1.4.1 get ArrayBuffer.prototype.byteLength JSHandle lengthGetter = CreateGetter(env, ArrayBuffer::GetByteLength, "byteLength", FunctionLength::ZERO); - JSHandle lengthKey(factory_->NewFromString("byteLength")); + JSHandle lengthKey(factory_->NewFromCanBeCompressString("byteLength")); SetGetter(arrayBufferFuncPrototype, lengthKey, lengthGetter); // 24.1.4.4 ArrayBuffer.prototype[@@toStringTag] @@ -2021,7 +2057,7 @@ void Builtins::InitializeReflect(const JSHandle &env, SetFunction(env, reflectObject, "set", Reflect::ReflectSet, FunctionLength::THREE); SetFunction(env, reflectObject, "setPrototypeOf", Reflect::ReflectSetPrototypeOf, FunctionLength::TWO); - JSHandle reflectString(factory_->NewFromString("Reflect")); + JSHandle reflectString(factory_->NewFromCanBeCompressString("Reflect")); JSHandle globalObject(thread_, env->GetGlobalObject()); PropertyDescriptor reflectDesc(thread_, JSHandle::Cast(reflectObject), true, false, true); JSObject::DefineOwnProperty(thread_, globalObject, reflectString, reflectDesc); @@ -2113,18 +2149,18 @@ void Builtins::InitializeDataView(const JSHandle &env, const JSHandle // 24.2.4.1 get DataView.prototype.buffer JSHandle bufferGetter = CreateGetter(env, DataView::GetBuffer, "buffer", FunctionLength::ZERO); - JSHandle bufferKey(factory_->NewFromString("buffer")); + JSHandle bufferKey(factory_->NewFromCanBeCompressString("buffer")); SetGetter(dataViewFuncPrototype, bufferKey, bufferGetter); // 24.2.4.2 get DataView.prototype.byteLength JSHandle lengthGetter = CreateGetter(env, DataView::GetByteLength, "byteLength", FunctionLength::ZERO); - JSHandle lengthKey(factory_->NewFromString("byteLength")); + JSHandle lengthKey(factory_->NewFromCanBeCompressString("byteLength")); SetGetter(dataViewFuncPrototype, lengthKey, lengthGetter); // 24.2.4.3 get DataView.prototype.byteOffset JSHandle offsetGetter = CreateGetter(env, DataView::GetOffset, "byteOffset", FunctionLength::ZERO); - JSHandle offsetKey(factory_->NewFromString("byteOffset")); + JSHandle offsetKey(factory_->NewFromCanBeCompressString("byteOffset")); SetGetter(dataViewFuncPrototype, offsetKey, offsetGetter); // 24.2.4.21 DataView.prototype[ @@toStringTag ] @@ -2168,7 +2204,7 @@ void Builtins::SetFunction(const JSHandle &env, const JSHandle +template void Builtins::SetFunctionAtSymbol(const JSHandle &env, const JSHandle &obj, const JSHandle &symbol, const char *name, EcmaEntrypoint func, int length) const @@ -2273,10 +2309,10 @@ void Builtins::StrictModeForbiddenAccessCallerArguments(const JSHandle function = factory_->NewJSFunction(env, reinterpret_cast(JSFunction::AccessCallerArgumentsThrowTypeError)); - JSHandle caller(factory_->NewFromString("caller")); + JSHandle caller(factory_->NewFromCanBeCompressString("caller")); SetAccessor(prototype, caller, JSHandle::Cast(function), JSHandle::Cast(function)); - JSHandle arguments(factory_->NewFromString("arguments")); + JSHandle arguments(factory_->NewFromCanBeCompressString("arguments")); SetAccessor(prototype, arguments, JSHandle::Cast(function), JSHandle::Cast(function)); } @@ -2390,6 +2426,305 @@ void Builtins::SetGetter(const JSHandle &obj, const JSHandle::Cast(obj), key, accessor, attr); } +JSHandle Builtins::NewIntlConstructor(const JSHandle &env, const JSHandle &prototype, + EcmaEntrypoint ctorFunc, const char *name, int length) +{ + JSHandle ctor = + factory_->NewJSFunction(env, reinterpret_cast(ctorFunc), FunctionKind::BUILTIN_CONSTRUCTOR); + InitializeIntlCtor(env, prototype, ctor, name, length); + return ctor; +} + +void Builtins::InitializeIntlCtor(const JSHandle &env, const JSHandle &prototype, + const JSHandle &ctor, const char *name, int length) +{ + const GlobalEnvConstants *globalConst = thread_->GlobalConstants(); + JSFunction::SetFunctionLength(thread_, ctor, JSTaggedValue(length)); + JSHandle nameString(factory_->NewFromString(name)); + JSFunction::SetFunctionName(thread_, JSHandle(ctor), nameString, + JSHandle(thread_, JSTaggedValue::Undefined())); + JSHandle constructorKey = globalConst->GetHandledConstructorString(); + PropertyDescriptor descriptor1(thread_, JSHandle::Cast(ctor), true, false, true); + JSObject::DefineOwnProperty(thread_, prototype, constructorKey, descriptor1); + + // set "prototype" in constructor. + ctor->SetFunctionPrototype(thread_, prototype.GetTaggedValue()); + + if (!JSTaggedValue::SameValue(nameString, thread_->GlobalConstants()->GetHandledAsyncFunctionString())) { + JSHandle intlObject(thread_, env->GetIntlFunction().GetTaggedValue()); + PropertyDescriptor descriptor2(thread_, JSHandle::Cast(ctor), true, false, true); + JSObject::DefineOwnProperty(thread_, intlObject, nameString, descriptor2); + } +} + +void Builtins::InitializeIntl(const JSHandle &env, const JSHandle &objFuncPrototypeValue) +{ + [[maybe_unused]] EcmaHandleScope scope(thread_); + JSHandle intlDynclass = factory_->NewEcmaDynClass(JSObject::SIZE, JSType::JS_INTL, objFuncPrototypeValue); + JSHandle intlObject = factory_->NewJSObject(intlDynclass); + + JSHandle initIntlSymbol(factory_->NewPublicSymbolWithChar("Symbol.IntlLegacyConstructedSymbol")); + SetNoneAttributeProperty(intlObject, "fallbackSymbol", initIntlSymbol); + + SetFunction(env, intlObject, "getCanonicalLocales", Intl::GetCanonicalLocales, FunctionLength::ONE); + + // initial value of the "Intl" property of the global object. + JSHandle intlString(factory_->NewFromString("Intl")); + JSHandle globalObject(thread_, env->GetGlobalObject()); + PropertyDescriptor intlDesc(thread_, JSHandle::Cast(intlObject), true, false, true); + JSObject::DefineOwnProperty(thread_, globalObject, intlString, intlDesc); + + SetStringTagSymbol(env, intlObject, "Intl"); + + env->SetIntlFunction(thread_, intlObject); +} + +void Builtins::InitializeDateTimeFormat(const JSHandle &env) +{ + [[maybe_unused]] EcmaHandleScope scope(thread_); + // DateTimeFormat.prototype + JSHandle objFun = env->GetObjectFunction(); + JSHandle dtfPrototype = factory_->NewJSObjectByConstructor(JSHandle(objFun), objFun); + JSHandle dtfPrototypeValue(dtfPrototype); + + // DateTimeFormat.prototype_or_dynclass + JSHandle dtfFuncInstanceDynclass = + factory_->NewEcmaDynClass(JSDateTimeFormat::SIZE, JSType::JS_DATE_TIME_FORMAT, dtfPrototypeValue); + + // DateTimeFormat = new Function() + // 13.4.1 Intl.DateTimeFormat.prototype.constructor + JSHandle dtfFunction(NewIntlConstructor(env, dtfPrototype, DateTimeFormat::DateTimeFormatConstructor, + "DateTimeFormat", FunctionLength::ZERO)); + JSHandle(dtfFunction)->SetFunctionPrototype(thread_, JSTaggedValue(*dtfFuncInstanceDynclass)); + + // 13.3.2 Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] ) + SetFunction(env, dtfFunction, "supportedLocalesOf", DateTimeFormat::SupportedLocalesOf, FunctionLength::ONE); + + // DateTimeFormat.prototype method + // 13.4.2 Intl.DateTimeFormat.prototype [ @@toStringTag ] + SetStringTagSymbol(env, dtfPrototype, "Intl.DateTimeFormat"); + env->SetDateTimeFormatFunction(thread_, dtfFunction); + + // 13.4.3 get Intl.DateTimeFormat.prototype.format + JSHandle formatGetter = CreateGetter(env, DateTimeFormat::Format, "format", FunctionLength::ZERO); + JSHandle formatSetter(thread_, JSTaggedValue::Undefined()); + SetAccessor(dtfPrototype, thread_->GlobalConstants()->GetHandledFormatString(), formatGetter, formatSetter); + + // 13.4.4 Intl.DateTimeFormat.prototype.formatToParts ( date ) + SetFunction(env, dtfPrototype, "formatToParts", DateTimeFormat::FormatToParts, FunctionLength::ONE); + + // 13.4.5 Intl.DateTimeFormat.prototype.resolvedOptions () + SetFunction(env, dtfPrototype, "resolvedOptions", DateTimeFormat::ResolvedOptions, FunctionLength::ZERO); + + SetFunction(env, dtfPrototype, "formatRange", DateTimeFormat::FormatRange, FunctionLength::TWO); + + SetFunction(env, dtfPrototype, "formatRangeToParts", DateTimeFormat::FormatRangeToParts, FunctionLength::TWO); +} + +void Builtins::InitializeRelativeTimeFormat(const JSHandle &env) +{ + [[maybe_unused]] EcmaHandleScope scope(thread_); + // RelativeTimeFormat.prototype + JSHandle objFun = env->GetObjectFunction(); + JSHandle rtfPrototype = factory_->NewJSObjectByConstructor(JSHandle(objFun), objFun); + JSHandle rtfPrototypeValue(rtfPrototype); + + // RelativeTimeFormat.prototype_or_dynclass + JSHandle rtfFuncInstanceDynclass = + factory_->NewEcmaDynClass(JSRelativeTimeFormat::SIZE, JSType::JS_RELATIVE_TIME_FORMAT, rtfPrototypeValue); + + // RelativeTimeFormat = new Function() + // 14.2.1 Intl.RelativeTimeFormat.prototype.constructor + JSHandle rtfFunction(NewIntlConstructor(env, rtfPrototype, + RelativeTimeFormat::RelativeTimeFormatConstructor, + "RelativeTimeFormat", FunctionLength::ZERO)); + JSHandle(rtfFunction)->SetFunctionPrototype(thread_, JSTaggedValue(*rtfFuncInstanceDynclass)); + + // 14.3.2 Intl.RelativeTimeFormat.supportedLocalesOf ( locales [ , options ] ) + SetFunction(env, rtfFunction, "supportedLocalesOf", RelativeTimeFormat::SupportedLocalesOf, FunctionLength::ONE); + + // RelativeTimeFormat.prototype method + // 14.4.2 Intl.RelativeTimeFormat.prototype [ @@toStringTag ] + SetStringTagSymbol(env, rtfPrototype, "Intl.RelativeTimeFormat"); + env->SetRelativeTimeFormatFunction(thread_, rtfFunction); + + // 14.4.3 get Intl.RelativeTimeFormat.prototype.format + SetFunction(env, rtfPrototype, "format", RelativeTimeFormat::Format, FunctionLength::TWO); + + // 14.4.4 Intl.RelativeTimeFormat.prototype.formatToParts( value, unit ) + SetFunction(env, rtfPrototype, "formatToParts", RelativeTimeFormat::FormatToParts, FunctionLength::TWO); + + // 14.4.5 Intl.RelativeTimeFormat.prototype.resolvedOptions () + SetFunction(env, rtfPrototype, "resolvedOptions", RelativeTimeFormat::ResolvedOptions, FunctionLength::ZERO); +} + +void Builtins::InitializeNumberFormat(const JSHandle &env) +{ + [[maybe_unused]] EcmaHandleScope scope(thread_); + // NumberFormat.prototype + JSHandle objFun = env->GetObjectFunction(); + JSHandle nfPrototype = factory_->NewJSObjectByConstructor(JSHandle(objFun), objFun); + JSHandle nfPrototypeValue(nfPrototype); + + // NumberFormat.prototype_or_dynclass + JSHandle nfFuncInstanceDynclass = + factory_->NewEcmaDynClass(JSNumberFormat::SIZE, JSType::JS_NUMBER_FORMAT, nfPrototypeValue); + + // NumberFormat = new Function() + // 12.4.1 Intl.NumberFormat.prototype.constructor + JSHandle nfFunction(NewIntlConstructor(env, nfPrototype, NumberFormat::NumberFormatConstructor, + "NumberFormat", FunctionLength::ZERO)); + JSHandle(nfFunction)->SetFunctionPrototype(thread_, JSTaggedValue(*nfFuncInstanceDynclass)); + + // 12.3.2 Intl.NumberFormat.supportedLocalesOf ( locales [ , options ] ) + SetFunction(env, nfFunction, "supportedLocalesOf", NumberFormat::SupportedLocalesOf, FunctionLength::ONE); + + // NumberFormat.prototype method + // 12.4.2 Intl.NumberFormat.prototype [ @@toStringTag ] + SetStringTagSymbol(env, nfPrototype, "Intl.NumberFormat"); + env->SetNumberFormatFunction(thread_, nfFunction); + + // 12.4.3 get Intl.NumberFormat.prototype.format + JSHandle formatGetter = CreateGetter(env, NumberFormat::Format, "format", FunctionLength::ZERO); + JSHandle formatSetter(thread_, JSTaggedValue::Undefined()); + SetAccessor(nfPrototype, thread_->GlobalConstants()->GetHandledFormatString(), formatGetter, formatSetter); + + // 12.4.4 Intl.NumberFormat.prototype.formatToParts ( date ) + SetFunction(env, nfPrototype, "formatToParts", NumberFormat::FormatToParts, FunctionLength::ONE); + + // 12.4.5 Intl.NumberFormat.prototype.resolvedOptions () + SetFunction(env, nfPrototype, "resolvedOptions", NumberFormat::ResolvedOptions, FunctionLength::ZERO); +} + +void Builtins::InitializeLocale(const JSHandle &env) +{ + [[maybe_unused]] EcmaHandleScope scope(thread_); + // Locale.prototype + JSHandle objFun = env->GetObjectFunction(); + JSHandle localePrototype = factory_->NewJSObjectByConstructor(JSHandle(objFun), objFun); + JSHandle localePrototypeValue(localePrototype); + + // Locale.prototype_or_dynclass + JSHandle localeFuncInstanceDynclass = + factory_->NewEcmaDynClass(JSLocale::SIZE, JSType::JS_LOCALE, localePrototypeValue); + + // Locale = new Function() + JSHandle localeFunction( + NewIntlConstructor(env, localePrototype, Locale::LocaleConstructor, "Locale", FunctionLength::ONE)); + JSHandle(localeFunction)->SetFunctionPrototype(thread_, JSTaggedValue(*localeFuncInstanceDynclass)); + + // Locale.prototype method + SetFunction(env, localePrototype, "maximize", Locale::Maximize, FunctionLength::ZERO); + SetFunction(env, localePrototype, "minimize", Locale::Minimize, FunctionLength::ZERO); + SetFunction(env, localePrototype, "toString", Locale::ToString, FunctionLength::ZERO); + + JSHandle baseNameGetter = CreateGetter(env, Locale::GetBaseName, "baseName", FunctionLength::ZERO); + SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledBaseNameString(), baseNameGetter); + + JSHandle calendarGetter = CreateGetter(env, Locale::GetCalendar, "calendar", FunctionLength::ZERO); + SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledCalendarString(), calendarGetter); + + JSHandle caseFirstGetter = + CreateGetter(env, Locale::GetCaseFirst, "caseFirst", FunctionLength::ZERO); + SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledCaseFirstString(), caseFirstGetter); + + JSHandle collationGetter = + CreateGetter(env, Locale::GetCollation, "collation", FunctionLength::ZERO); + SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledCollationString(), collationGetter); + + JSHandle hourCycleGetter = + CreateGetter(env, Locale::GetHourCycle, "hourCycle", FunctionLength::ZERO); + SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledHourCycleString(), hourCycleGetter); + + JSHandle numericGetter = CreateGetter(env, Locale::GetNumeric, "numeric", FunctionLength::ZERO); + SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledNumericString(), numericGetter); + + JSHandle numberingSystemGetter = + CreateGetter(env, Locale::GetNumberingSystem, "numberingSystem", FunctionLength::ZERO); + SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledNumberingSystemString(), numberingSystemGetter); + + JSHandle languageGetter = CreateGetter(env, Locale::GetLanguage, "language", FunctionLength::ZERO); + SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledLanguageString(), languageGetter); + + JSHandle scriptGetter = CreateGetter(env, Locale::GetScript, "script", FunctionLength::ZERO); + SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledScriptString(), scriptGetter); + + JSHandle regionGetter = CreateGetter(env, Locale::GetRegion, "region", FunctionLength::ZERO); + SetGetter(localePrototype, thread_->GlobalConstants()->GetHandledRegionString(), regionGetter); + + // 10.3.2 Intl.Locale.prototype[ @@toStringTag ] + SetStringTagSymbol(env, localePrototype, "Intl.Locale"); + env->SetLocaleFunction(thread_, localeFunction); +} + +void Builtins::InitializeCollator(const JSHandle &env) +{ + [[maybe_unused]] EcmaHandleScope scope(thread_); + // Collator.prototype + JSHandle objFun = env->GetObjectFunction(); + JSHandle collatorPrototype = factory_->NewJSObjectByConstructor(JSHandle(objFun), objFun); + JSHandle collatorPrototypeValue(collatorPrototype); + + // Collator.prototype_or_dynclass + JSHandle collatorFuncInstanceDynclass = + factory_->NewEcmaDynClass(JSCollator::SIZE, JSType::JS_COLLATOR, collatorPrototypeValue); + + // Collator = new Function() + // 11.1.2 Intl.Collator.prototype.constructor + JSHandle collatorFunction( + NewIntlConstructor(env, collatorPrototype, Collator::CollatorConstructor, "Collator", FunctionLength::ZERO)); + JSHandle(collatorFunction)->SetFunctionPrototype(thread_, JSTaggedValue(*collatorFuncInstanceDynclass)); + + // 11.2.2 Intl.Collator.supportedLocalesOf ( locales [ , options ] ) + SetFunction(env, collatorFunction, "supportedLocalesOf", Collator::SupportedLocalesOf, FunctionLength::ONE); + + // Collator.prototype method + // 11.3.2 Intl.Collator.prototype [ @@toStringTag ] + SetStringTagSymbol(env, collatorPrototype, "Intl.Collator"); + env->SetCollatorFunction(thread_, collatorFunction); + + // 11.3.3 get Intl.Collator.prototype.compare + JSHandle compareGetter = CreateGetter(env, Collator::Compare, "compare", FunctionLength::ZERO); + JSHandle compareSetter(thread_, JSTaggedValue::Undefined()); + SetAccessor(collatorPrototype, thread_->GlobalConstants()->GetHandledCompareString(), compareGetter, compareSetter); + + // 11.3.4 Intl.Collator.prototype.resolvedOptions () + SetFunction(env, collatorPrototype, "resolvedOptions", Collator::ResolvedOptions, FunctionLength::ZERO); +} + +void Builtins::InitializePluralRules(const JSHandle &env) +{ + [[maybe_unused]] EcmaHandleScope scope(thread_); + // PluralRules.prototype + JSHandle objFun(env->GetObjectFunction()); + JSHandle prPrototype = factory_->NewJSObjectByConstructor(JSHandle(objFun), objFun); + JSHandle prPrototypeValue(prPrototype); + + // PluralRules.prototype_or_dynclass + JSHandle prFuncInstanceDynclass = + factory_->NewEcmaDynClass(JSPluralRules::SIZE, JSType::JS_PLURAL_RULES, prPrototypeValue); + + // PluralRules = new Function() + // 15.2.1 Intl.PluralRules.prototype.constructor + JSHandle prFunction( + NewIntlConstructor(env, prPrototype, PluralRules::PluralRulesConstructor, "PluralRules", FunctionLength::ZERO)); + JSHandle(prFunction)->SetFunctionPrototype(thread_, JSTaggedValue(*prFuncInstanceDynclass)); + + // 15.3.2 Intl.PluralRules.supportedLocalesOf ( locales [ , options ] ) + SetFunction(env, prFunction, "supportedLocalesOf", PluralRules::SupportedLocalesOf, FunctionLength::ONE); + + // PluralRules.prototype method + // 15.4.2 Intl.PluralRules.prototype [ @@toStringTag ] + SetStringTagSymbol(env, prPrototype, "Intl.PluralRules"); + env->SetPluralRulesFunction(thread_, prFunction); + + // 15.4.3 get Intl.PluralRules.prototype.select + SetFunction(env, prPrototype, "select", PluralRules::Select, FunctionLength::ONE); + + // 15.4.5 Intl.PluralRules.prototype.resolvedOptions () + SetFunction(env, prPrototype, "resolvedOptions", PluralRules::ResolvedOptions, FunctionLength::ZERO); +} + void Builtins::InitializeJSNativeObject(const JSHandle &env) const { [[maybe_unused]] EcmaHandleScope scope(thread_); diff --git a/ecmascript/builtins.h b/ecmascript/builtins.h index 4678867ec542bc79947a1c02c52ed0db8fe57f7e..7a7753ea9633b6ddcde42fc5ab3ad3e546c9c7bc 100644 --- a/ecmascript/builtins.h +++ b/ecmascript/builtins.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMA_INIT_H -#define PANDA_RUNTIME_ECMA_INIT_H +#ifndef ECMASCRIPT_BUILTINS_H +#define ECMASCRIPT_BUILTINS_H #include "ecmascript/global_env.h" #include "ecmascript/js_function.h" @@ -108,6 +108,19 @@ private: void InitializeRegExp(const JSHandle &env); + // for Intl. + JSHandle NewIntlConstructor(const JSHandle &env, const JSHandle &prototype, + EcmaEntrypoint ctorFunc, const char *name, int length); + void InitializeIntlCtor(const JSHandle &env, const JSHandle &prototype, + const JSHandle &ctor, const char *name, int length); + void InitializeIntl(const JSHandle &env, const JSHandle &objFuncPrototypeValue); + void InitializeLocale(const JSHandle &env); + void InitializeDateTimeFormat(const JSHandle &env); + void InitializeRelativeTimeFormat(const JSHandle &env); + void InitializeNumberFormat(const JSHandle &env); + void InitializeCollator(const JSHandle &env); + void InitializePluralRules(const JSHandle &env); + void GeneralUpdateError(ErrorParameter *error, EcmaEntrypoint constructor, EcmaEntrypoint method, const char *name, JSType type) const; @@ -167,7 +180,7 @@ private: void SetFuncToObjAndGlobal(const JSHandle &env, const JSHandle &globalObject, const JSHandle &obj, const char *key, EcmaEntrypoint func, int length); - template + template void SetFunctionAtSymbol(const JSHandle &env, const JSHandle &obj, const JSHandle &symbol, const char *name, EcmaEntrypoint func, int length) const; @@ -198,4 +211,4 @@ private: void InitializeJSNativeObject(const JSHandle &env) const; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMA_INIT_H +#endif // ECMASCRIPT_BUILTINS_H diff --git a/ecmascript/builtins/builtins_array.cpp b/ecmascript/builtins/builtins_array.cpp index 3c89e2526ee89ce67d29804421d6010c8b66aa27..346e2856e2bb6b8c60437bfa164ed09c076f3124 100644 --- a/ecmascript/builtins/builtins_array.cpp +++ b/ecmascript/builtins/builtins_array.cpp @@ -24,6 +24,7 @@ #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/ecma_string.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/fast_runtime_stub-inl.h" #include "ecmascript/js_array.h" #include "ecmascript/js_array_iterator.h" @@ -83,7 +84,7 @@ JSTaggedValue BuiltinsArray::ArrayConstructor(EcmaRuntimeCallInfo *argv) // 9. Let setStatus be Set(array, "length", intLen, true). // 10. Assert: setStatus is not an abrupt completion. if (!len->IsNumber()) { - JSHandle key0(factory->NewFromString("0")); + JSHandle key0(factory->NewFromCanBeCompressString("0")); JSObject::CreateDataProperty(thread, newArrayHandle, key0, len); newLen = 1; } else { @@ -135,7 +136,7 @@ JSTaggedValue BuiltinsArray::From(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), Array, From); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + InternalCallParams *arguments = thread->GetInternalCallParams(); JSHandle lengthKey = thread->GlobalConstants()->GetHandledLengthString(); // 1. Let C be the this value. JSHandle thisHandle = GetThis(argv); @@ -163,8 +164,6 @@ JSTaggedValue BuiltinsArray::From(EcmaRuntimeCallInfo *argv) JSHandle usingIterator = JSObject::GetMethod(thread, items, iteratorSymbol); // 5. ReturnIfAbrupt(usingIterator). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - array_size_t length = 2; - JSHandle msg = factory->NewTaggedArray(length); // 6. If usingIterator is not undefined, then if (!usingIterator->IsUndefined()) { // a. If IsConstructor(C) is true, then @@ -174,7 +173,7 @@ JSTaggedValue BuiltinsArray::From(EcmaRuntimeCallInfo *argv) // c. ReturnIfAbrupt(A). JSTaggedValue newArray; if (thisHandle->IsConstructor()) { - newArray = JSFunction::Construct(thread, thisHandle, factory->EmptyArray(), + newArray = JSFunction::Construct(thread, thisHandle, 0, nullptr, JSHandle(thread, JSTaggedValue::Undefined())); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } else { @@ -193,6 +192,7 @@ JSTaggedValue BuiltinsArray::From(EcmaRuntimeCallInfo *argv) int k = 0; // g. Repeat JSMutableHandle key(thread, JSTaggedValue::Undefined()); + JSMutableHandle mapValue(thread, JSTaggedValue::Undefined()); while (true) { key.Update(JSTaggedValue(k)); // i. Let Pk be ToString(k). @@ -218,16 +218,15 @@ JSTaggedValue BuiltinsArray::From(EcmaRuntimeCallInfo *argv) // 2. If mappedValue is an abrupt completion, return IteratorClose(iterator, mappedValue). // 3. Let mappedValue be mappedValue.[[value]]. // viii. Else, let mappedValue be nextValue. - JSHandle mapValue; if (mapping) { - msg->Set(thread, 0, nextValue); - msg->Set(thread, 1, JSTaggedValue(k)); - JSTaggedValue callResult = JSFunction::Call(thread, mapfn, thisArgHandle, msg); - mapValue = JSHandle(thread, callResult); + arguments->MakeArgv(nextValue, key); + JSTaggedValue callResult = + JSFunction::Call(thread, mapfn, thisArgHandle, 2, arguments->GetArgv()); // 2: two args + mapValue.Update(callResult); JSTaggedValue mapResult = JSIterator::IteratorClose(thread, iterator, mapValue).GetTaggedValue(); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue(mapResult)); } else { - mapValue = nextValue; + mapValue.Update(nextValue.GetTaggedValue()); } // ix. Let defineStatus be CreateDataPropertyOrThrow(A, Pk, mappedValue). // x. If defineStatus is an abrupt completion, return IteratorClose(iterator, defineStatus). @@ -256,10 +255,8 @@ JSTaggedValue BuiltinsArray::From(EcmaRuntimeCallInfo *argv) // 14. ReturnIfAbrupt(A). JSTaggedValue newArray; if (thisHandle->IsConstructor()) { - array_size_t arrayLength = 1; - JSHandle array = factory->NewTaggedArray(arrayLength); - array->Set(thread, 0, JSTaggedValue(len)); - newArray = JSFunction::Construct(thread, thisHandle, array, + arguments->MakeArgv(JSTaggedValue(len)); + newArray = JSFunction::Construct(thread, thisHandle, 1, arguments->GetArgv(), JSHandle(thread, JSTaggedValue::Undefined())); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } else { @@ -278,20 +275,22 @@ JSTaggedValue BuiltinsArray::From(EcmaRuntimeCallInfo *argv) // i. Let mappedValue be Call(mapfn, T, «kValue, k»). // e. Else, let mappedValue be kValue. // f. Let defineStatus be CreateDataPropertyOrThrow(A, Pk, mappedValue). - JSHandle mapValue; + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + JSMutableHandle mapValue(thread, JSTaggedValue::Undefined()); double k = 0; while (k < len) { JSHandle kValue = JSArray::FastGetPropertyByValue(thread, arrayLike, k); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (mapping) { - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - JSTaggedValue callResult = JSFunction::Call(thread, mapfn, thisArgHandle, msg); + key.Update(JSTaggedValue(k)); + arguments->MakeArgv(kValue, key); + JSTaggedValue callResult = + JSFunction::Call(thread, mapfn, thisArgHandle, 2, arguments->GetArgv()); // 2: two args RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - mapValue = JSHandle(thread, callResult); + mapValue.Update(callResult); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } else { - mapValue = kValue; + mapValue.Update(kValue.GetTaggedValue()); } JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, k, mapValue); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -341,10 +340,9 @@ JSTaggedValue BuiltinsArray::Of(EcmaRuntimeCallInfo *argv) JSHandle newArray; if (thisHandle->IsConstructor()) { JSHandle undefined = globalConst->GetHandledUndefined(); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle arguments = factory->NewTaggedArray(1); - arguments->Set(thread, 0, JSTaggedValue(argc)); - JSTaggedValue taggedArray = JSFunction::Construct(thread, thisHandle, arguments, undefined); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(argc)); + JSTaggedValue taggedArray = JSFunction::Construct(thread, thisHandle, 1, arguments->GetArgv(), undefined); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); newArray = JSHandle(thread, taggedArray); } else { @@ -661,7 +659,6 @@ JSTaggedValue BuiltinsArray::Every(EcmaRuntimeCallInfo *argv) ASSERT(argv); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); @@ -696,8 +693,8 @@ JSTaggedValue BuiltinsArray::Every(EcmaRuntimeCallInfo *argv) // iv. ReturnIfAbrupt(testResult). // v. If testResult is false, return false. // e. Increase k by 1. - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); + InternalCallParams *arguments = thread->GetInternalCallParams(); + JSMutableHandle key(thread, JSTaggedValue::Undefined()); uint32_t k = 0; while (k < len) { bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k); @@ -705,10 +702,10 @@ JSTaggedValue BuiltinsArray::Every(EcmaRuntimeCallInfo *argv) if (exists) { JSHandle kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - msg->Set(thread, INDEX_TWO, thisObjVal); - JSTaggedValue callResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + key.Update(JSTaggedValue(k)); + arguments->MakeArgv(kValue, key, thisObjVal); + JSTaggedValue callResult = + JSFunction::Call(thread, callbackFnHandle, thisArgHandle, 3, arguments->GetArgv()); // 3: three args RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); bool boolResult = callResult.ToBoolean(); if (!boolResult) { @@ -805,7 +802,6 @@ JSTaggedValue BuiltinsArray::Filter(EcmaRuntimeCallInfo *argv) ASSERT(argv); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); @@ -852,26 +848,25 @@ JSTaggedValue BuiltinsArray::Filter(EcmaRuntimeCallInfo *argv) // 3. Increase to by 1. // e. Increase k by 1. double toIndex = 0; - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); - + JSMutableHandle key(thread, JSTaggedValue::Undefined()); JSMutableHandle toIndexHandle(thread, JSTaggedValue::Undefined()); + InternalCallParams *arguments = thread->GetInternalCallParams(); uint32_t k = 0; while (k < len) { bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (exists) { - JSHandle kValueHandle = JSArray::FastGetPropertyByValue(thread, thisObjVal, k); + JSHandle kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, kValueHandle); - msg->Set(thread, 1, JSTaggedValue(k)); - msg->Set(thread, INDEX_TWO, thisObjVal); - JSTaggedValue callResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + key.Update(JSTaggedValue(k)); + 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); if (boolResult) { toIndexHandle.Update(JSTaggedValue(toIndex)); - JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toIndexHandle, kValueHandle); + JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toIndexHandle, kValue); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); toIndex++; } @@ -890,7 +885,6 @@ JSTaggedValue BuiltinsArray::Find(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), Array, Find); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); @@ -922,16 +916,16 @@ JSTaggedValue BuiltinsArray::Find(EcmaRuntimeCallInfo *argv) // e. ReturnIfAbrupt(testResult). // f. If testResult is true, return kValue. // g. Increase k by 1. - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + InternalCallParams *arguments = thread->GetInternalCallParams(); uint32_t k = 0; while (k < len) { JSHandle kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - msg->Set(thread, INDEX_TWO, thisObjVal); - JSTaggedValue callResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + key.Update(JSTaggedValue(k)); + 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); if (boolResult) { @@ -951,7 +945,6 @@ JSTaggedValue BuiltinsArray::FindIndex(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), Array, FindIndex); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); @@ -983,16 +976,16 @@ JSTaggedValue BuiltinsArray::FindIndex(EcmaRuntimeCallInfo *argv) // e. ReturnIfAbrupt(testResult). // f. If testResult is true, return k. // g. Increase k by 1. - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + InternalCallParams *arguments = thread->GetInternalCallParams(); uint32_t k = 0; while (k < len) { JSHandle kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - msg->Set(thread, INDEX_TWO, thisObjVal); - JSTaggedValue callResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + key.Update(JSTaggedValue(k)); + 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); if (boolResult) { @@ -1011,7 +1004,6 @@ JSTaggedValue BuiltinsArray::ForEach(EcmaRuntimeCallInfo *argv) ASSERT(argv); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); @@ -1045,8 +1037,8 @@ JSTaggedValue BuiltinsArray::ForEach(EcmaRuntimeCallInfo *argv) // iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»). // iv. ReturnIfAbrupt(funcResult). // e. Increase k by 1. - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + InternalCallParams *arguments = thread->GetInternalCallParams(); uint32_t k = 0; while (k < len) { bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k); @@ -1054,10 +1046,10 @@ JSTaggedValue BuiltinsArray::ForEach(EcmaRuntimeCallInfo *argv) if (exists) { JSHandle kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - msg->Set(thread, INDEX_TWO, thisObjVal); - JSTaggedValue funcResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + key.Update(JSTaggedValue(k)); + arguments->MakeArgv(kValue, key, thisObjVal); + JSTaggedValue funcResult = + JSFunction::Call(thread, callbackFnHandle, thisArgHandle, 3, arguments->GetArgv()); // 3: three args RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult); } k++; @@ -1174,7 +1166,7 @@ JSTaggedValue BuiltinsArray::Join(EcmaRuntimeCallInfo *argv) // 6. Let sep be ToString(separator). JSHandle sepHandle; if ((GetCallArg(argv, 0)->IsUndefined())) { - sepHandle = JSHandle::Cast(factory->NewFromString(",")); + sepHandle = JSHandle::Cast(factory->NewFromCanBeCompressString(",")); } else { sepHandle = GetCallArg(argv, 0); } @@ -1334,7 +1326,6 @@ JSTaggedValue BuiltinsArray::Map(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), Array, Map); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); @@ -1379,8 +1370,9 @@ JSTaggedValue BuiltinsArray::Map(EcmaRuntimeCallInfo *argv) // v. Let status be CreateDataPropertyOrThrow (A, Pk, mappedValue). // vi. ReturnIfAbrupt(status). // e. Increase k by 1. - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + JSMutableHandle mapResultHandle(thread, JSTaggedValue::Undefined()); + InternalCallParams *arguments = thread->GetInternalCallParams(); uint32_t k = 0; while (k < len) { bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k); @@ -1388,13 +1380,13 @@ JSTaggedValue BuiltinsArray::Map(EcmaRuntimeCallInfo *argv) if (exists) { JSHandle kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - msg->Set(thread, INDEX_TWO, thisObjVal); - JSTaggedValue mapResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + key.Update(JSTaggedValue(k)); + arguments->MakeArgv(kValue, key, thisObjVal); + JSTaggedValue mapResult = + JSFunction::Call(thread, callbackFnHandle, thisArgHandle, 3, arguments->GetArgv()); // 3: three args RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSHandle kValueHandle(thread, mapResult); - JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, k, kValueHandle); + mapResultHandle.Update(mapResult); + JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, k, mapResultHandle); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } k++; @@ -1523,7 +1515,6 @@ JSTaggedValue BuiltinsArray::Reduce(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), Array, Reduce); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); array_size_t argc = argv->GetArgsNumber(); @@ -1595,20 +1586,19 @@ JSTaggedValue BuiltinsArray::Reduce(EcmaRuntimeCallInfo *argv) // iv. ReturnIfAbrupt(accumulator). // e. Increase k by 1. JSTaggedValue callResult = JSTaggedValue::Undefined(); - array_size_t length = 4; - JSHandle msg = factory->NewTaggedArray(length); + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + InternalCallParams *arguments = thread->GetInternalCallParams(); while (k < len) { bool exists = (thisHandle->IsTypedArray() || JSTaggedValue::HasProperty(thread, thisObjVal, k)); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (exists) { JSHandle kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, accumulator.GetTaggedValue()); - msg->Set(thread, 1, kValue); - msg->Set(thread, INDEX_TWO, JSTaggedValue(k)); - msg->Set(thread, INDEX_THREE, thisObjVal); + key.Update(JSTaggedValue(k)); + arguments->MakeArgv(accumulator, kValue, key, thisObjVal); JSHandle thisArgHandle = globalConst->GetHandledUndefined(); - callResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + callResult = + JSFunction::Call(thread, callbackFnHandle, thisArgHandle, 4, arguments->GetArgv()); // 4: four args RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); accumulator.Update(callResult); } @@ -1626,7 +1616,6 @@ JSTaggedValue BuiltinsArray::ReduceRight(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), Array, ReduceRight); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); array_size_t argc = argv->GetArgsNumber(); @@ -1656,7 +1645,6 @@ JSTaggedValue BuiltinsArray::ReduceRight(EcmaRuntimeCallInfo *argv) // 7. Let k be len-1. double k = len - 1; - JSMutableHandle key(thread, JSTaggedValue::Undefined()); // 8. If initialValue is present, then // a. Set accumulator to initialValue. // 9. Else initialValue is not present, @@ -1676,11 +1664,10 @@ JSTaggedValue BuiltinsArray::ReduceRight(EcmaRuntimeCallInfo *argv) } else { bool kPresent = false; while (!kPresent && k >= 0) { - key.Update(JSTaggedValue(k)); - kPresent = (thisHandle->IsTypedArray() || JSTaggedValue::HasProperty(thread, thisObjVal, key)); + kPresent = (thisHandle->IsTypedArray() || JSTaggedValue::HasProperty(thread, thisObjVal, k)); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (kPresent) { - accumulator.Update(JSArray::FastGetPropertyByValue(thread, thisObjVal, key).GetTaggedValue()); + accumulator.Update(JSArray::FastGetPropertyByValue(thread, thisObjVal, k).GetTaggedValue()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } k--; @@ -1700,9 +1687,9 @@ JSTaggedValue BuiltinsArray::ReduceRight(EcmaRuntimeCallInfo *argv) // iii. Let accumulator be Call(callbackfn, undefined, «accumulator, kValue, k, O»). // iv. ReturnIfAbrupt(accumulator). // e. Decrease k by 1. + JSMutableHandle key(thread, JSTaggedValue::Undefined()); JSTaggedValue callResult = JSTaggedValue::Undefined(); - array_size_t length = 4; - JSHandle msg = factory->NewTaggedArray(length); + InternalCallParams *arguments = thread->GetInternalCallParams(); while (k >= 0) { key.Update(JSTaggedValue(k)); bool exists = (thisHandle->IsTypedArray() || JSTaggedValue::HasProperty(thread, thisObjVal, key)); @@ -1710,12 +1697,10 @@ JSTaggedValue BuiltinsArray::ReduceRight(EcmaRuntimeCallInfo *argv) if (exists) { JSHandle kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, key); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, accumulator.GetTaggedValue()); - msg->Set(thread, 1, kValue); - msg->Set(thread, INDEX_TWO, JSTaggedValue(k)); - msg->Set(thread, INDEX_THREE, thisObjVal); + arguments->MakeArgv(accumulator, kValue, key, thisObjVal); JSHandle thisArgHandle = globalConst->GetHandledUndefined(); - callResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + callResult = + JSFunction::Call(thread, callbackFnHandle, thisArgHandle, 4, arguments->GetArgv()); // 4: four args RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); accumulator.Update(callResult); } @@ -1838,6 +1823,9 @@ JSTaggedValue BuiltinsArray::Shift(EcmaRuntimeCallInfo *argv) // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); + if (thisHandle->IsStableJSArray(thread)) { + return JSStableArray::Shift(JSHandle::Cast(thisHandle), argv); + } JSHandle thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle); // 2. ReturnIfAbrupt(O). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -1972,8 +1960,23 @@ JSTaggedValue BuiltinsArray::Slice(EcmaRuntimeCallInfo *argv) JSTaggedValue newArray = JSArray::ArraySpeciesCreate(thread, thisObjHandle, JSTaggedNumber(count)); // 13. ReturnIfAbrupt(A). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (count == 0) { + return newArray; + } JSHandle newArrayHandle(thread, newArray); + if (thisHandle->IsStableJSArray(thread) && newArray.IsStableJSArray(thread)) { + TaggedArray *destElements = *JSObject::GrowElementsCapacity(thread, newArrayHandle, count); + TaggedArray *srcElements = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject()); + + for (array_size_t idx = 0; idx < count; idx++) { + destElements->Set(thread, idx, srcElements->Get(k + idx)); + } + + JSHandle::Cast(newArrayHandle)->SetArrayLength(thread, count); + return newArrayHandle.GetTaggedValue(); + } + // 14. Let n be 0. // 15. Repeat, while k < final // a. Let Pk be ToString(k). @@ -2022,7 +2025,6 @@ JSTaggedValue BuiltinsArray::Some(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), Array, Some); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); @@ -2058,8 +2060,7 @@ JSTaggedValue BuiltinsArray::Some(EcmaRuntimeCallInfo *argv) // v. If testResult is true, return true. // e. Increase k by 1. JSMutableHandle key(thread, JSTaggedValue::Undefined()); - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); + InternalCallParams *arguments = thread->GetInternalCallParams(); double k = 0; while (k < len) { bool exists = (thisHandle->IsTypedArray() || JSTaggedValue::HasProperty(thread, thisObjVal, k)); @@ -2068,10 +2069,9 @@ JSTaggedValue BuiltinsArray::Some(EcmaRuntimeCallInfo *argv) key.Update(JSTaggedValue(k)); JSHandle kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, key); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - msg->Set(thread, INDEX_TWO, thisObjVal); - JSTaggedValue callResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + 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); if (boolResult) { @@ -2108,8 +2108,6 @@ JSTaggedValue BuiltinsArray::Sort(EcmaRuntimeCallInfo *argv) // 3. ReturnIfAbrupt(len). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - array_size_t length = 2; - JSHandle msg = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(length); JSMutableHandle presentValue(thread, JSTaggedValue::Undefined()); JSMutableHandle middleValue(thread, JSTaggedValue::Undefined()); JSMutableHandle previousValue(thread, JSTaggedValue::Undefined()); @@ -2123,7 +2121,7 @@ JSTaggedValue BuiltinsArray::Sort(EcmaRuntimeCallInfo *argv) middleValue.Update( FastRuntimeStub::FastGetPropertyByIndex(thread, thisObjHandle.GetTaggedValue(), middleIndex)); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - int32_t compareResult = ArrayHelper::SortCompare(thread, callbackFnHandle, middleValue, presentValue, msg); + int32_t compareResult = ArrayHelper::SortCompare(thread, callbackFnHandle, middleValue, presentValue); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (compareResult > 0) { endIndex = middleIndex; @@ -2204,15 +2202,20 @@ JSTaggedValue BuiltinsArray::Splice(EcmaRuntimeCallInfo *argv) if (argc > 1) { insertCount = argc - 2; // 2:2 means there are two arguments before the insert items. JSHandle msg1 = GetCallArg(argv, 1); - JSTaggedNumber dcTemp = JSTaggedValue::ToInteger(thread, msg1); + JSTaggedNumber argDeleteCount = JSTaggedValue::ToInteger(thread, msg1); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - double dc = dcTemp.GetNumber(); - actualDeleteCount = ((dc > 0 ? dc : 0) < len - start) ? (dc > 0 ? dc : 0) : len - start; + double deleteCount = argDeleteCount.GetNumber(); + deleteCount = deleteCount > 0 ? deleteCount : 0; + actualDeleteCount = deleteCount < (len - start) ? deleteCount : len - start; } // 11. If len+insertCount−actualDeleteCount > 253-1, throw a TypeError exception. if (len + insertCount - actualDeleteCount > base::MAX_SAFE_INTEGER) { THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception()); } + + if (thisHandle->IsStableJSArray(thread)) { + return JSStableArray::Splice(JSHandle::Cast(thisHandle), argv, start, insertCount, actualDeleteCount); + } // 12. Let A be ArraySpeciesCreate(O, actualDeleteCount). JSTaggedValue newArray = JSArray::ArraySpeciesCreate(thread, thisObjHandle, JSTaggedNumber(actualDeleteCount)); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -2247,8 +2250,8 @@ JSTaggedValue BuiltinsArray::Splice(EcmaRuntimeCallInfo *argv) } // 16. Let setStatus be Set(A, "length", actualDeleteCount, true). JSHandle lengthKey = thread->GlobalConstants()->GetHandledLengthString(); - JSHandle actualDelcountHandle(thread, JSTaggedValue(actualDeleteCount)); - JSTaggedValue::SetProperty(thread, JSHandle::Cast(newArrayHandle), lengthKey, actualDelcountHandle, + JSHandle deleteCountHandle(thread, JSTaggedValue(actualDeleteCount)); + JSTaggedValue::SetProperty(thread, JSHandle::Cast(newArrayHandle), lengthKey, deleteCountHandle, true); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 19. Let itemCount be the number of elements in items. @@ -2376,7 +2379,7 @@ JSTaggedValue BuiltinsArray::ToLocaleString(EcmaRuntimeCallInfo *argv) // current locale (this is derived in an implementation-defined way). JSHandle sepHandle; if ((GetCallArg(argv, 0)->IsUndefined())) { - sepHandle = JSHandle::Cast(ecmaVm->GetFactory()->NewFromString(",")); + sepHandle = JSHandle::Cast(ecmaVm->GetFactory()->NewFromCanBeCompressString(",")); } else { sepHandle = GetCallArg(argv, 0); } @@ -2391,9 +2394,6 @@ JSTaggedValue BuiltinsArray::ToLocaleString(EcmaRuntimeCallInfo *argv) // Inject locales and options argument into a taggedArray JSHandle locales = GetCallArg(argv, 0); JSHandle options = GetCallArg(argv, 1); - JSHandle argArray = factory->NewTaggedArray(2); // 2: length - argArray->Set(thread, 0, locales); - argArray->Set(thread, 1, options); CString concatStr; // 7. Let firstElement be Get(array, "0"). @@ -2416,15 +2416,17 @@ JSTaggedValue BuiltinsArray::ToLocaleString(EcmaRuntimeCallInfo *argv) // f. Let R be a String value produced by concatenating S and R. // g. Increase k by 1. auto globalConst = thread->GlobalConstants(); + InternalCallParams *arguments = thread->GetInternalCallParams(); for (int32_t k = 0; k < len; k++) { JSTaggedValue next = globalConst->GetEmptyString(); JSHandle nextElement = JSArray::FastGetPropertyByValue(thread, thisObjVal, k); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (!nextElement->IsUndefined() && !nextElement->IsNull()) { JSHandle nextValueHandle = nextElement; + arguments->MakeArgv(locales, options); JSTaggedValue callResult = - JSFunction::Invoke(thread, nextValueHandle, globalConst->GetHandledToLocaleStringString(), argArray); - + JSFunction::Invoke(thread, nextValueHandle, + globalConst->GetHandledToLocaleStringString(), 2, arguments->GetArgv()); // 2: two args RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); next = callResult; } @@ -2451,7 +2453,8 @@ JSTaggedValue BuiltinsArray::ToString(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), Array, ToString); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + auto ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); // 1. Let array be ToObject(this value). JSHandle thisHandle = GetThis(argv); @@ -2461,25 +2464,24 @@ JSTaggedValue BuiltinsArray::ToString(EcmaRuntimeCallInfo *argv) JSHandle thisObjVal(thisObjHandle); // 3. Let func be Get(array, "join"). - JSHandle key(factory->NewFromString("join")); - JSHandle callbackFnHandle(JSTaggedValue::GetProperty(thread, thisObjVal, key).GetValue()); + JSHandle joinKey(factory->NewFromCanBeCompressString("join")); + JSHandle callbackFnHandle = JSTaggedValue::GetProperty(thread, thisObjVal, joinKey).GetValue(); // 4. ReturnIfAbrupt(func). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 5. If IsCallable(func) is false, let func be the intrinsic function %ObjProto_toString% (19.1.3.6). if (!callbackFnHandle->IsCallable()) { - auto ecmaVm = thread->GetEcmaVM(); JSHandle env = ecmaVm->GetGlobalEnv(); JSHandle objectPrototype = env->GetObjectFunctionPrototype(); - JSHandle tostring = thread->GlobalConstants()->GetHandledToStringString(); - JSHandle callbackfnHandle = - JSHandle::Cast(JSTaggedValue::GetProperty(thread, objectPrototype, tostring).GetValue()); + JSHandle toStringKey = thread->GlobalConstants()->GetHandledToStringString(); + callbackFnHandle = JSTaggedValue::GetProperty(thread, objectPrototype, toStringKey).GetValue(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - return JSFunction::Call(thread, callbackfnHandle, thisObjVal, BuiltinsBase::GetArgsArray(argv)); } - - return JSFunction::Call(thread, callbackFnHandle, thisObjVal, GetArgsArray(argv)); + JSHandle argsList = GetArgsArray(argv); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgList(*argsList); + return JSFunction::Call(thread, callbackFnHandle, thisObjVal, argsList->GetLength(), arguments->GetArgv()); } // 22.1.3.28 Array.prototype.unshift ( ...items ) @@ -2602,34 +2604,34 @@ JSTaggedValue BuiltinsArray::Unscopables(EcmaRuntimeCallInfo *argv) JSHandle unscopableList = factory->OrdinaryNewJSObjectCreate(nullHandle); JSHandle trueVal(thread, JSTaggedValue::True()); - JSHandle copyWithKey(factory->NewFromString("copyWithin")); + JSHandle copyWithKey(factory->NewFromCanBeCompressString("copyWithin")); JSObject::CreateDataProperty(thread, unscopableList, copyWithKey, trueVal); - JSHandle entriesKey(factory->NewFromString("entries")); + JSHandle entriesKey(factory->NewFromCanBeCompressString("entries")); JSObject::CreateDataProperty(thread, unscopableList, entriesKey, trueVal); - JSHandle fillKey(factory->NewFromString("fill")); + JSHandle fillKey(factory->NewFromCanBeCompressString("fill")); JSObject::CreateDataProperty(thread, unscopableList, fillKey, trueVal); - JSHandle findKey(factory->NewFromString("find")); + JSHandle findKey(factory->NewFromCanBeCompressString("find")); JSObject::CreateDataProperty(thread, unscopableList, findKey, trueVal); - JSHandle findIndexKey(factory->NewFromString("findIndex")); + JSHandle findIndexKey(factory->NewFromCanBeCompressString("findIndex")); JSObject::CreateDataProperty(thread, unscopableList, findIndexKey, trueVal); - JSHandle flatKey(factory->NewFromString("flat")); + JSHandle flatKey(factory->NewFromCanBeCompressString("flat")); JSObject::CreateDataProperty(thread, unscopableList, flatKey, trueVal); - JSHandle flatMapKey(factory->NewFromString("flatMap")); + JSHandle flatMapKey(factory->NewFromCanBeCompressString("flatMap")); JSObject::CreateDataProperty(thread, unscopableList, flatMapKey, trueVal); - JSHandle includesKey(factory->NewFromString("includes")); + JSHandle includesKey(factory->NewFromCanBeCompressString("includes")); JSObject::CreateDataProperty(thread, unscopableList, includesKey, trueVal); - JSHandle keysKey(factory->NewFromString("keys")); + JSHandle keysKey(factory->NewFromCanBeCompressString("keys")); JSObject::CreateDataProperty(thread, unscopableList, keysKey, trueVal); - JSHandle valuesKey(factory->NewFromString("values")); + JSHandle valuesKey(factory->NewFromCanBeCompressString("values")); JSObject::CreateDataProperty(thread, unscopableList, valuesKey, trueVal); return unscopableList.GetTaggedValue(); diff --git a/ecmascript/builtins/builtins_array.h b/ecmascript/builtins/builtins_array.h index ee9027712ab38568c9e176282108bde38a6c98d9..7e15e0ffc7d368c292f1ce96793bedd7ce831821 100644 --- a/ecmascript/builtins/builtins_array.h +++ b/ecmascript/builtins/builtins_array.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ARRAY_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_ARRAY_H +#define ECMASCRIPT_BUILTINS_BUILTINS_ARRAY_H #include "ecmascript/base/builtins_base.h" @@ -97,4 +97,4 @@ public: }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ARRAY_H \ No newline at end of file +#endif // ECMASCRIPT_BUILTINS_BUILTINS_ARRAY_H \ No newline at end of file diff --git a/ecmascript/builtins/builtins_arraybuffer.cpp b/ecmascript/builtins/builtins_arraybuffer.cpp index aec84a67099722cd3d9284fe58a22e853aacbec2..8e82578cd0b03f455cf50be8d1547493a0ad84f7 100644 --- a/ecmascript/builtins/builtins_arraybuffer.cpp +++ b/ecmascript/builtins/builtins_arraybuffer.cpp @@ -22,6 +22,7 @@ #include "ecmascript/ecma_macros.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_arraybuffer.h" #include "ecmascript/js_object-inl.h" #include "ecmascript/js_tagged_number.h" @@ -111,7 +112,6 @@ JSTaggedValue BuiltinsArrayBuffer::Slice(EcmaRuntimeCallInfo *argv) [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be the this value. JSHandle thisHandle = GetThis(argv); // 2. If Type(O) is not Object, throw a TypeError exception. @@ -172,9 +172,9 @@ JSTaggedValue BuiltinsArrayBuffer::Slice(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 15. Let new be Construct(ctor, «newLen»). JSHandle undefined = globalConst->GetHandledUndefined(); - JSHandle arguments = factory->NewTaggedArray(1); - arguments->Set(thread, 0, JSTaggedValue(newLen)); - JSTaggedValue taggedNewArrBuf = JSFunction::Construct(thread, constructor, arguments, undefined); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(newLen)); + JSTaggedValue taggedNewArrBuf = JSFunction::Construct(thread, constructor, 1, arguments->GetArgv(), undefined); JSHandle newArrBuf(thread, taggedNewArrBuf); // 16. ReturnIfAbrupt(new). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -400,7 +400,7 @@ JSTaggedValue BuiltinsArrayBuffer::SetValueInBuffer(JSTaggedValue arrBuf, int32_ return JSTaggedValue::Undefined(); } -template +template void BuiltinsArrayBuffer::SetTypeData(uint8_t *block, T value, int32_t index) { int32_t sizeCount = sizeof(T); @@ -411,57 +411,41 @@ void BuiltinsArrayBuffer::SetTypeData(uint8_t *block, T value, int32_t index) } template -T BuiltinsArrayBuffer::TransformIntToBigEndian(T liValue) +T BuiltinsArrayBuffer::LittleEndianToBigEndian(T liValue) { uint8_t sizeCount = sizeof(T); T biValue; - if (sizeCount == 2) { // 2:2 means size of T - biValue = ((liValue & 0x00FF) << BITS_EIGHT) // NOLINT - | ((liValue & 0xFF00) >> BITS_EIGHT); // NOLINT - } else { - biValue = ((liValue & 0x000000FF) << BITS_TWENTY_FOUR) // NOLINT - | ((liValue & 0x0000FF00) << BITS_EIGHT) // NOLINT - | ((liValue & 0x00FF0000) >> BITS_EIGHT) // NOLINT - | ((liValue & 0xFF000000) >> BITS_TWENTY_FOUR); // NOLINT + switch (sizeCount) { + case NumberSize::UINT16: + biValue = ((liValue & 0x00FF) << BITS_EIGHT) // NOLINT + | ((liValue & 0xFF00) >> BITS_EIGHT); // NOLINT + break; + case NumberSize::UINT32: + biValue = ((liValue & 0x000000FF) << BITS_TWENTY_FOUR) // NOLINT + | ((liValue & 0x0000FF00) << BITS_EIGHT) // NOLINT + | ((liValue & 0x00FF0000) >> BITS_EIGHT) // NOLINT + | ((liValue & 0xFF000000) >> BITS_TWENTY_FOUR); // NOLINT + break; + default: + UNREACHABLE(); + break; } return biValue; } -template -T BuiltinsArrayBuffer::TransformFloatToBigEndian(T fValue) -{ - static_assert(std::is_same_v || std::is_same_v, "T must be float type"); - constexpr int32_t size = sizeof(T); - uint8_t s[size]; // NOLINT - uint8_t t[size]; // NOLINT - if (memcpy_s(s, size, &fValue, size) != EOK) { - LOG_ECMA(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - for (int i = 0, j = size - 1; i < size && j >= 0; i++, j--) { - t[i] = s[j]; - } - T res; - if (memcpy_s(&res, size, t, size) != EOK) { - LOG_ECMA(FATAL) << "memset_s failed"; - UNREACHABLE(); - } - return res; -} - -template -T BuiltinsArrayBuffer::TransformByteToNumber(uint8_t *block, int32_t index, uint8_t *tmpArr, int32_t size) +uint64_t BuiltinsArrayBuffer::LittleEndianToBigEndianUint64(uint64_t liValue) { - if (memcpy_s(tmpArr, size, block + index, size) != EOK) { // NOLINT - LOG_ECMA(FATAL) << "memcpy_s failed"; - UNREACHABLE(); - } - auto *arr = reinterpret_cast(tmpArr); - T res = *arr; - return res; + return ((liValue & 0x00000000000000FF) << BITS_FIFTY_SIX) // NOLINT + | ((liValue & 0x000000000000FF00) << BITS_FORTY) // NOLINT + | ((liValue & 0x0000000000FF0000) << BITS_TWENTY_FOUR) // NOLINT + | ((liValue & 0x00000000FF000000) << BITS_EIGHT) // NOLINT + | ((liValue & 0x000000FF00000000) >> BITS_EIGHT) // NOLINT + | ((liValue & 0x0000FF0000000000) >> BITS_TWENTY_FOUR) // NOLINT + | ((liValue & 0x00FF000000000000) >> BITS_FORTY) // NOLINT + | ((liValue & 0xFF00000000000000) >> BITS_FIFTY_SIX); // NOLINT } -template +template JSTaggedValue BuiltinsArrayBuffer::GetValueFromBufferForInteger(uint8_t *block, int32_t byteIndex, bool littleEndian) { static_assert(std::is_integral_v, "T must be integral"); @@ -469,11 +453,9 @@ JSTaggedValue BuiltinsArrayBuffer::GetValueFromBufferForInteger(uint8_t *block, static_assert(sizeof(T) >= sizeof(uint16_t), "T must have a size more than uint8"); ASSERT(size >= NumberSize::UINT16 || size <= NumberSize::FLOAT64); - uint8_t tmpArr[size]; // NOLINT - int32_t capacity = sizeof(T); - auto res = TransformByteToNumber(block, byteIndex, tmpArr, capacity); + T res = *reinterpret_cast(block + byteIndex); if (!littleEndian) { - res = TransformIntToBigEndian(res); + res = LittleEndianToBigEndian(res); } // uint32_t maybe overflow with TaggedInt @@ -487,34 +469,37 @@ JSTaggedValue BuiltinsArrayBuffer::GetValueFromBufferForInteger(uint8_t *block, return GetTaggedInt(res); } -template +template JSTaggedValue BuiltinsArrayBuffer::GetValueFromBufferForFloat(uint8_t *block, int32_t byteIndex, bool littleEndian) { static_assert(std::is_same_v || std::is_same_v, "T must be float type"); static_assert(sizeof(T) == size, "Invalid number size"); - uint8_t tmpArr[size]; // NOLINT - int32_t capacity = sizeof(T); - auto tmp = TransformByteToNumber(block, byteIndex, tmpArr, capacity); + T tmp = *reinterpret_cast(block + byteIndex); // NOLINTNEXTLINE(readability-braces-around-statements) if constexpr (std::is_same_v) { if (std::isnan(tmp)) { return GetTaggedDouble(tmp); } + if (!littleEndian) { + uint32_t res = bit_cast(tmp); + res = LittleEndianToBigEndian(res); + return GetTaggedDouble(bit_cast(res)); + } } else if constexpr (std::is_same_v) { // NOLINTNEXTLINE(readability-braces-around-statements) if (std::isnan(tmp) && !JSTaggedValue::IsImpureNaN(tmp)) { return GetTaggedDouble(tmp); } - } - - if (!littleEndian) { - T res = TransformFloatToBigEndian(tmp); - return GetTaggedDouble(res); + if (!littleEndian) { + uint64_t res = bit_cast(tmp); + res = LittleEndianToBigEndianUint64(res); + return GetTaggedDouble(bit_cast(res)); + } } return GetTaggedDouble(tmp); } -template +template void BuiltinsArrayBuffer::SetValueInBufferForByte(double val, uint8_t *block, int32_t byteIndex) { static_assert(std::is_same_v || std::is_same_v, "T must be int8/uint8"); @@ -545,7 +530,7 @@ void BuiltinsArrayBuffer::SetValueInBufferForUint8Clamped(double val, uint8_t *b SetTypeData(block, res, byteIndex); } -template +template void BuiltinsArrayBuffer::SetValueInBufferForInteger(double val, uint8_t *block, int32_t byteIndex, bool littleEndian) { static_assert(std::is_integral_v, "T must be integral"); @@ -568,12 +553,12 @@ void BuiltinsArrayBuffer::SetValueInBufferForInteger(double val, uint8_t *block, } if (!littleEndian) { - res = TransformIntToBigEndian(res); + res = LittleEndianToBigEndian(res); } SetTypeData(block, res, byteIndex); } -template +template void BuiltinsArrayBuffer::SetValueInBufferForFloat(double val, uint8_t *block, int32_t byteIndex, bool littleEndian) { static_assert(std::is_same_v || std::is_same_v, "T must be float type"); @@ -583,9 +568,13 @@ void BuiltinsArrayBuffer::SetValueInBufferForFloat(double val, uint8_t *block, i return; } if (!littleEndian) { - auto res = TransformFloatToBigEndian(data); - SetTypeData(block, res, byteIndex); - return; + if constexpr (std::is_same_v) { + uint32_t res = bit_cast(data); + data = bit_cast(LittleEndianToBigEndian(res)); + } else if constexpr (std::is_same_v) { + uint64_t res = bit_cast(data); + data = bit_cast(LittleEndianToBigEndianUint64(res)); + } } SetTypeData(block, data, byteIndex); } diff --git a/ecmascript/builtins/builtins_arraybuffer.h b/ecmascript/builtins/builtins_arraybuffer.h index 5563dfe71a82d081a1c8993593a97712c2e4b93f..948657be2823d86d66b47f0da955c7a3f1d11d07 100644 --- a/ecmascript/builtins/builtins_arraybuffer.h +++ b/ecmascript/builtins/builtins_arraybuffer.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ARRAYBUFFER_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ARRAYBUFFER_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_ARRAYBUFFER_H +#define ECMASCRIPT_BUILTINS_BUILTINS_ARRAYBUFFER_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/base/number_helper.h" @@ -24,6 +24,8 @@ namespace panda::ecmascript::builtins { static constexpr double NUMBER_HALF = 0.5; static constexpr uint32_t BITS_EIGHT = 8; static constexpr uint32_t BITS_TWENTY_FOUR = 24; +static constexpr uint32_t BITS_FORTY = 40; +static constexpr uint32_t BITS_FIFTY_SIX = 56; using DataViewType = ecmascript::DataViewType; class BuiltinsArrayBuffer : public base::BuiltinsBase { public: @@ -56,34 +58,30 @@ public: private: template - static T TransformIntToBigEndian(T liValue); + static T LittleEndianToBigEndian(T liValue); - template - static T TransformFloatToBigEndian(T fValue); - - template - static T TransformByteToNumber(uint8_t *block, int32_t index, uint8_t *tmpArr, int32_t size); + static uint64_t LittleEndianToBigEndianUint64(uint64_t liValue); - template + template static void SetTypeData(uint8_t *block, T value, int32_t index); - template + template static JSTaggedValue GetValueFromBufferForInteger(uint8_t *block, int32_t byteIndex, bool littleEndian); - template + template static JSTaggedValue GetValueFromBufferForFloat(uint8_t *block, int32_t byteIndex, bool littleEndian); - template + template static void SetValueInBufferForByte(double val, uint8_t *block, int32_t byteIndex); static void SetValueInBufferForUint8Clamped(double val, uint8_t *block, int32_t byteIndex); - template + template static void SetValueInBufferForInteger(double val, uint8_t *block, int32_t byteIndex, bool littleEndian); - template + template static void SetValueInBufferForFloat(double val, uint8_t *block, int32_t byteIndex, bool littleEndian); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ARRAYBUFFER_H \ No newline at end of file +#endif // ECMASCRIPT_BUILTINS_BUILTINS_ARRAYBUFFER_H diff --git a/ecmascript/builtins/builtins_async_function.h b/ecmascript/builtins/builtins_async_function.h index 23174569f7fc667354dda44550f51c2c4170601b..0b33b5dad5e58f8aec93e0f419a68045583e78c2 100644 --- a/ecmascript/builtins/builtins_async_function.h +++ b/ecmascript/builtins/builtins_async_function.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ASYNC_FUNCTION_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ASYNC_FUNCTION_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_ASYNC_FUNCTION_H +#define ECMASCRIPT_BUILTINS_BUILTINS_ASYNC_FUNCTION_H #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/base/builtins_base.h" @@ -26,4 +26,4 @@ public: static JSTaggedValue AsyncFunctionConstructor(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ASYNC_FUNCTION_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_ASYNC_FUNCTION_H diff --git a/ecmascript/builtins/builtins_boolean.h b/ecmascript/builtins/builtins_boolean.h index 173190e09c0e4f059003cb0eb8e89216e2a91378..df5b91dec488ca5796eb538ccc21812045562278 100644 --- a/ecmascript/builtins/builtins_boolean.h +++ b/ecmascript/builtins/builtins_boolean.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_BOOLEAN_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_BOOLEAN_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_BOOLEAN_H +#define ECMASCRIPT_BUILTINS_BUILTINS_BOOLEAN_H #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/base/builtins_base.h" @@ -35,4 +35,4 @@ public: static JSTaggedValue BooleanPrototypeValueOf(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_BOOLEAN_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_BOOLEAN_H diff --git a/ecmascript/builtins/builtins_collator.cpp b/ecmascript/builtins/builtins_collator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e2665b805af17b1a664ad0bb17461a90181fac1f --- /dev/null +++ b/ecmascript/builtins/builtins_collator.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "builtins_collator.h" + +#include "ecmascript/ecma_vm.h" +#include "ecmascript/global_env.h" +#include "ecmascript/js_collator.h" +#include "ecmascript/js_intl.h" + +namespace panda::ecmascript::builtins { +constexpr uint32_t FUNCTION_LENGTH_TWO = 2; + +// 11.1.2 Intl.Collator ( [ locales [ , options ] ] ) +JSTaggedValue BuiltinsCollator::CollatorConstructor(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. + JSHandle constructor = GetConstructor(argv); + JSHandle newTarget = GetNewTarget(argv); + if (newTarget->IsUndefined()) { + newTarget = constructor; + } + // 2. Let internalSlotsList be « [[InitializedCollator]], [[Locale]], [[Usage]], [[Sensitivity]], + // [[IgnorePunctuation]], [[Collation]], [[BoundCompare]] ». + // 3. If %Collator%.[[RelevantExtensionKeys]] contains "kn", then + // a. Append [[Numeric]] as the last element of internalSlotsList. + // 4. If %Collator%.[[RelevantExtensionKeys]] contains "kf", then + // a. Append [[CaseFirst]] as the last element of internalSlotsList. + + // 5. Let collator be ? OrdinaryCreateFromConstructor(newTarget, "%CollatorPrototype%", internalSlotsList). + JSHandle collator = + JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(constructor), newTarget)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 6. Return ? InitializeCollator(collator, locales, options). + JSHandle locales = GetCallArg(argv, 0); + JSHandle options = GetCallArg(argv, 1); + JSHandle result = JSCollator::InitializeCollator(thread, collator, locales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +// 11.2.2 Intl.Collator.supportedLocalesOf ( locales [ , options ] ) +JSTaggedValue BuiltinsCollator::SupportedLocalesOf(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let availableLocales be %Collator%.[[AvailableLocales]]. + JSHandle availableLocales = JSCollator::GetAvailableLocales(thread); + + // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle locales = GetCallArg(argv, 0); + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). + JSHandle options = GetCallArg(argv, 1); + JSHandle result = JSLocale::SupportedLocales(thread, availableLocales, requestedLocales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +// 11.3.3 get Intl.Collator.prototype.compare +JSTaggedValue BuiltinsCollator::Compare(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let collator be this value. + JSHandle thisValue = GetThis(argv); + + // 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]). + if (!thisValue->IsJSCollator()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not collator", JSTaggedValue::Exception()); + } + // 3. If collator.[[BoundCompare]] is undefined, then + // a. Let F be a new built-in function object as defined in 11.3.3.1. + // b. Set F.[[Collator]] to collator. + // c. Set collator.[[BoundCompare]] to F. + // 4. Return collator.[[BoundCompare]]. + JSHandle collator = JSHandle::Cast(thisValue); + JSHandle boundCompare(thread, collator->GetBoundCompare()); + if (boundCompare->IsUndefined()) { + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle intlBoundFunc = factory->NewJSIntlBoundFunction( + reinterpret_cast(BuiltinsCollator::AnonymousCollator), FUNCTION_LENGTH_TWO); + intlBoundFunc->SetCollator(thread, collator); + collator->SetBoundCompare(thread, intlBoundFunc); + } + return collator->GetBoundCompare(); +} + +// 11.3.3.1 Collator Compare Functions +JSTaggedValue BuiltinsCollator::AnonymousCollator(EcmaRuntimeCallInfo *argv) +{ + // A Collator compare function is an anonymous built-in function that has a [[Collator]] internal slot. + // When a Collator compare function F is called with arguments x and y, the following steps are taken: + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + JSHandle intlBoundFunc = JSHandle::Cast(GetConstructor(argv)); + + // 1. Let collator be F.[[Collator]]. + JSHandle collator(thread, intlBoundFunc->GetCollator()); + + // 2. Assert: Type(collator) is Object and collator has an [[InitializedCollator]] internal slot. + ASSERT_PRINT(collator->IsJSObject() && collator->IsJSCollator(), "collator is not object or JSCollator"); + + // 3. If x is not provided, let x be undefined. + JSHandle x = GetCallArg(argv, 0); + + // 4. If y is not provided, let y be undefined. + JSHandle y = GetCallArg(argv, 1); + + // 5. Let X be ? ToString(x). + JSHandle xValue = JSTaggedValue::ToString(thread, x); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Undefined()); + // 6. Let Y be ? ToString(y). + JSHandle yValue = JSTaggedValue::ToString(thread, y); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Undefined()); + // 7. Return CompareStrings(collator, X, Y). + icu::Collator *icuCollator = (JSHandle::Cast(collator))->GetIcuCollator(); + return JSCollator::CompareStrings(icuCollator, xValue, yValue); +} + +// 11.3.4 Intl.Collator.prototype.resolvedOptions () +JSTaggedValue BuiltinsCollator::ResolvedOptions(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + JSHandle thisValue = GetThis(argv); + if (!thisValue->IsJSCollator()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not Collator object", JSTaggedValue::Exception()); + } + JSHandle options = JSCollator::ResolvedOptions(thread, JSHandle::Cast(thisValue)); + return options.GetTaggedValue(); +} +} // namespace panda::ecmascript::builtins \ No newline at end of file diff --git a/ecmascript/js_int32_array.h b/ecmascript/builtins/builtins_collator.h similarity index 35% rename from ecmascript/js_int32_array.h rename to ecmascript/builtins/builtins_collator.h index 8bc079de03c13094549a5f9b8ad3451052c6f923..4291749406c0309185a5b5a58259090467d3bdbb 100644 --- a/ecmascript/js_int32_array.h +++ b/ecmascript/builtins/builtins_collator.h @@ -1,45 +1,40 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_INT32_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_INT32_ARRAY_H - -#include -#include "ecmascript/js_object.h" -#include "ecmascript/js_tagged_value-inl.h" -#include "ecmascript/js_tagged_value.h" - -namespace panda::ecmascript { -class JSInt32Array : public JSObject { -public: - static JSInt32Array *Cast(ObjectHeader *object) - { - ASSERT(JSTaggedValue(object).IsJSInt32Array()); - return static_cast(object); - } - - static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE; - ACCESSORS(ViewedArrayBuffer, VIEWED_ARRAY_BUFFER_OFFSET, TYPED_ARRAY_NAME_OFFSET) - ACCESSORS(TypedArrayName, TYPED_ARRAY_NAME_OFFSET, BYTE_LENGTH_OFFSET) - ACCESSORS(ByteLength, BYTE_LENGTH_OFFSET, BYTE_OFFSET_OFFSET) - ACCESSORS(ByteOffset, BYTE_OFFSET_OFFSET, ARRAY_LENGTH_OFFSET) - ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, SIZE) - DECL_DUMP() - - DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE) -}; // namespace panda::ecmascript -} // namespace panda::ecmascript - -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_INT32_ARRAY_H +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_COLLATOR_H +#define ECMASCRIPT_BUILTINS_BUILTINS_COLLATOR_H + +#include "ecmascript/base/builtins_base.h" + +namespace panda::ecmascript::builtins { +class BuiltinsCollator : public base::BuiltinsBase { +public: + // 11.1.2 Intl.Collator ( [ locales [ , options ] ] ) + static JSTaggedValue CollatorConstructor(EcmaRuntimeCallInfo *argv); + + // 11.2.2 Intl.Collator.supportedLocalesOf ( locales [ , options ] ) + static JSTaggedValue SupportedLocalesOf(EcmaRuntimeCallInfo *argv); + + // 11.3.3 get Intl.Collator.prototype.compare + static JSTaggedValue Compare(EcmaRuntimeCallInfo *argv); + + // 11.3.4 Intl.Collator.prototype.resolvedOptions () + static JSTaggedValue ResolvedOptions(EcmaRuntimeCallInfo *argv); + +private: + static JSTaggedValue AnonymousCollator(EcmaRuntimeCallInfo *argv); +}; +} // namespace panda::ecmascript::builtins +#endif // ECMASCRIPT_BUILTINS_BUILTINS_COLLATOR_H \ No newline at end of file diff --git a/ecmascript/builtins/builtins_dataview.h b/ecmascript/builtins/builtins_dataview.h index 7ddc0c8d2db21cdfcabe3742752bcad9427f7c0e..57f979f03a6eed79e75e91b50bca4110492fb92d 100644 --- a/ecmascript/builtins/builtins_dataview.h +++ b/ecmascript/builtins/builtins_dataview.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_DATAVIEW_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_DATAVIEW_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_DATAVIEW_H +#define ECMASCRIPT_BUILTINS_BUILTINS_DATAVIEW_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/js_dataview.h" @@ -78,4 +78,4 @@ private: }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_DATAVIEW_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_DATAVIEW_H diff --git a/ecmascript/builtins/builtins_date.cpp b/ecmascript/builtins/builtins_date.cpp index 10790de701b43dba7def2c533c115f3e228c597b..7ae6a6b02c330d5629efd5f579da2ea064fc0ed2 100644 --- a/ecmascript/builtins/builtins_date.cpp +++ b/ecmascript/builtins/builtins_date.cpp @@ -18,6 +18,7 @@ #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" #include "ecmascript/js_date.h" +#include "ecmascript/js_date_time_format.h" #include "ecmascript/js_function.h" #include "ecmascript/js_object-inl.h" #include "ecmascript/js_tagged_value-inl.h" @@ -173,9 +174,8 @@ JSTaggedValue BuiltinsDate::ToJSON(EcmaRuntimeCallInfo *argv) return JSTaggedValue::Null(); } } - JSHandle calleeKey(thread->GetEcmaVM()->GetFactory()->NewFromString("toISOString")); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - return JSFunction::Invoke(thread, objectHandle, calleeKey, factory->EmptyArray()); + JSHandle calleeKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("toISOString")); + return JSFunction::Invoke(thread, objectHandle, calleeKey, 0, nullptr); } // 20.4.4.44 @@ -208,12 +208,12 @@ JSTaggedValue BuiltinsDate::ToPrimitive(EcmaRuntimeCallInfo *argv) JSHandle hint = GetCallArg(argv, 0); PreferredPrimitiveType tryFirst = PREFER_STRING; if (hint->IsString()) { - JSHandle numberStrHandle = factory->NewFromString("number"); + JSHandle numberStrHandle = factory->NewFromCanBeCompressString("number"); if (EcmaString::StringsAreEqual(hint.GetObject(), *numberStrHandle)) { tryFirst = PREFER_NUMBER; } else { - JSHandle stringStrHandle = factory->NewFromString("string"); - JSHandle defaultStrHandle = factory->NewFromString("default"); + JSHandle stringStrHandle = factory->NewFromCanBeCompressString("string"); + JSHandle defaultStrHandle = factory->NewFromCanBeCompressString("default"); if (EcmaString::StringsAreEqual(hint.GetObject(), *stringStrHandle) || EcmaString::StringsAreEqual(hint.GetObject(), *defaultStrHandle)) { tryFirst = PREFER_STRING; @@ -226,4 +226,133 @@ JSTaggedValue BuiltinsDate::ToPrimitive(EcmaRuntimeCallInfo *argv) } return JSTaggedValue::OrdinaryToPrimitive(thread, object, tryFirst); } + +// ecma 402 16.4.1 Date.prototype.toLocaleString ( [ locales [ , options ] ] ) +JSTaggedValue BuiltinsDate::ToLocaleString(EcmaRuntimeCallInfo *argv) +{ + ASSERT(argv); + JSThread *thread = argv->GetThread(); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + JSHandle env = ecmaVm->GetGlobalEnv(); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + // Let x be ? thisTimeValue(this value). + JSHandle msg = GetThis(argv); + if (!msg->IsDate()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "Not a Date Object", JSTaggedValue::Exception()); + } + JSTaggedValue value = JSDate::Cast(msg->GetTaggedObject())->GetTime(); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // If x is NaN, return "Invalid Date". + double x = value.GetNumber(); + if (std::isnan(x)) { + return thread->GlobalConstants()->GetInvalidDateString(); + } + + // Let options be ? ToDateTimeOptions(options, "any", "all"). + JSHandle locales = GetCallArg(argv, 0); + JSHandle options = GetCallArg(argv, 1); + JSHandle dateTimeOptions = + JSDateTimeFormat::ToDateTimeOptions(thread, options, RequiredOption::ANY, DefaultsOption::ALL); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Let dateFormat be ? Construct(%DateTimeFormat%, « locales, options »). + JSHandle ctor = env->GetDateTimeFormatFunction(); + JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(ctor), ctor); + JSHandle dtf = JSDateTimeFormat::InitializeDateTimeFormat( + thread, JSHandle::Cast(obj), locales, JSHandle::Cast(dateTimeOptions)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Return ? FormatDateTime(dateFormat, x). + JSHandle result = JSDateTimeFormat::FormatDateTime(thread, dtf, x); + return result.GetTaggedValue(); +} + +// ecma 402 16.4.1 Date.prototype.toLocaleString ( [ locales [ , options ] ] ) +JSTaggedValue BuiltinsDate::ToLocaleDateString(EcmaRuntimeCallInfo *argv) +{ + ASSERT(argv); + JSThread *thread = argv->GetThread(); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + JSHandle env = ecmaVm->GetGlobalEnv(); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + // Let x be ? thisTimeValue(this value). + JSHandle msg = GetThis(argv); + if (!msg->IsDate()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "Not a Date Object", JSTaggedValue::Exception()); + } + JSTaggedValue value = JSDate::Cast(msg->GetTaggedObject())->GetTime(); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // If x is NaN, return "Invalid Date". + double x = value.GetNumber(); + if (std::isnan(x)) { + return thread->GlobalConstants()->GetInvalidDateString(); + } + + // Let options be ? ToDateTimeOptions(options, "any", "all"). + JSHandle locales = GetCallArg(argv, 0); + JSHandle options = GetCallArg(argv, 1); + JSHandle dateTimeOptions = + JSDateTimeFormat::ToDateTimeOptions(thread, options, RequiredOption::DATE, DefaultsOption::DATE); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Let dateFormat be ? Construct(%DateTimeFormat%, « locales, options »). + JSHandle ctor = env->GetDateTimeFormatFunction(); + JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(ctor), ctor); + JSHandle dtf = JSDateTimeFormat::InitializeDateTimeFormat( + thread, JSHandle::Cast(obj), locales, JSHandle::Cast(dateTimeOptions)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Return ? FormatDateTime(dateFormat, x). + JSHandle result = JSDateTimeFormat::FormatDateTime(thread, dtf, x); + return result.GetTaggedValue(); +} + +// ecma 402 16.4.1 Date.prototype.toLocaleString ( [ locales [ , options ] ] ) +JSTaggedValue BuiltinsDate::ToLocaleTimeString(EcmaRuntimeCallInfo *argv) +{ + ASSERT(argv); + JSThread *thread = argv->GetThread(); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + JSHandle env = ecmaVm->GetGlobalEnv(); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + // Let x be ? thisTimeValue(this value). + JSHandle msg = GetThis(argv); + if (!msg->IsDate()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "Not a Date Object", JSTaggedValue::Exception()); + } + JSTaggedValue value = JSDate::Cast(msg->GetTaggedObject())->GetTime(); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // If x is NaN, return "Invalid Date". + double x = value.GetNumber(); + if (std::isnan(x)) { + return thread->GlobalConstants()->GetInvalidDateString(); + } + + // Let options be ? ToDateTimeOptions(options, "any", "all"). + JSHandle locales = GetCallArg(argv, 0); + JSHandle options = GetCallArg(argv, 1); + JSHandle dateTimeOptions = + JSDateTimeFormat::ToDateTimeOptions(thread, options, RequiredOption::TIME, DefaultsOption::TIME); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Let dateFormat be ? Construct(%DateTimeFormat%, « locales, options »). + JSHandle ctor = env->GetDateTimeFormatFunction(); + JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(ctor), ctor); + JSHandle dtf = JSDateTimeFormat::InitializeDateTimeFormat( + thread, JSHandle::Cast(obj), locales, JSHandle::Cast(dateTimeOptions)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Return ? FormatDateTime(dateFormat, x). + JSHandle result = JSDateTimeFormat::FormatDateTime(thread, dtf, x); + return result.GetTaggedValue(); +} } // namespace panda::ecmascript::builtins diff --git a/ecmascript/builtins/builtins_date.h b/ecmascript/builtins/builtins_date.h index 13f7c54e01e9516b4d80b930763b6b473b64b559..7d83a3a211d6f59270d662923f0aa74cab1284ba 100644 --- a/ecmascript/builtins/builtins_date.h +++ b/ecmascript/builtins/builtins_date.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_DATE_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_DATE_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_DATE_H +#define ECMASCRIPT_BUILTINS_BUILTINS_DATE_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/js_date.h" @@ -177,4 +177,4 @@ private: static constexpr uint8_t CONSTRUCTOR_MAX_LENGTH = 7; }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_NUBMER_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_DATE_H diff --git a/ecmascript/builtins/builtins_date_time_format.cpp b/ecmascript/builtins/builtins_date_time_format.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c7f453f9df30ea56fdb8a5eaf930e23cf3a3bca1 --- /dev/null +++ b/ecmascript/builtins/builtins_date_time_format.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "builtins_date_time_format.h" +#include "ecmascript/ecma_vm.h" +#include "ecmascript/global_env.h" +#include "ecmascript/js_date.h" +#include "ecmascript/js_date_time_format.h" +#include "ecmascript/js_intl.h" + +namespace panda::ecmascript::builtins { +// 13.2.1 Intl.DateTimeFormat ( [ locales [ , options ] ] ) +JSTaggedValue BuiltinsDateTimeFormat::DateTimeFormatConstructor(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + JSHandle env = ecmaVm->GetGlobalEnv(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. + JSHandle constructor = GetConstructor(argv); + JSHandle newTarget = GetNewTarget(argv); + if (newTarget->IsUndefined()) { + newTarget = constructor; + } + + // 2. Let dateTimeFormat be ? OrdinaryCreateFromConstructor(newTarget, "%DateTimeFormatPrototype%", « + // [[InitializedDateTimeFormat]], [[Locale]], [[Calendar]], [[NumberingSystem]], [[TimeZone]], [[Weekday]], + // [[Era]], [[Year]], [[Month]], [[Day]], [[Hour]], [[Minute]], [[Second]], [[TimeZoneName]], [[HourCycle]], + // [[Pattern]], [[BoundFormat]] »). + JSHandle dateTimeFormat = JSHandle::Cast( + factory->NewJSObjectByConstructor(JSHandle(constructor), newTarget)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 3. Perform ? InitializeDateTimeFormat(dateTimeFormat, locales, options). + JSHandle locales = GetCallArg(argv, 0); + JSHandle options = GetCallArg(argv, 1); + JSHandle dtf = + JSDateTimeFormat::InitializeDateTimeFormat(thread, dateTimeFormat, locales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 4. Let this be the this value. + JSHandle thisValue = GetThis(argv); + + // 5. If NewTarget is undefined and Type(this) is Object and ? InstanceofOperator(this, %DateTimeFormat%) is true, + // then + // a. Perform ? DefinePropertyOrThrow(this, %Intl%.[[FallbackSymbol]], PropertyDescriptor{ [[Value]]: + // dateTimeFormat, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }). + // b. Return this. + bool isInstanceOf = JSObject::InstanceOf(thread, thisValue, env->GetDateTimeFormatFunction()); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (newTarget->IsUndefined() && thisValue->IsJSObject() && isInstanceOf) { + PropertyDescriptor descriptor(thread, JSHandle::Cast(dtf), false, false, false); + JSHandle key(thread, JSHandle::Cast(env->GetIntlFunction())->GetFallbackSymbol()); + JSTaggedValue::DefinePropertyOrThrow(thread, thisValue, key, descriptor); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return thisValue.GetTaggedValue(); + } + + // 6. Return dateTimeFormat. + return dtf.GetTaggedValue(); +} + +// 13.3.2 Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] ) +JSTaggedValue BuiltinsDateTimeFormat::SupportedLocalesOf(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let availableLocales be %DateTimeFormat%.[[AvailableLocales]]. + JSHandle availableLocales = JSDateTimeFormat::GainAvailableLocales(thread); + + // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle locales = GetCallArg(argv, 0); + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). + JSHandle options = GetCallArg(argv, 1); + JSHandle result = JSLocale::SupportedLocales(thread, availableLocales, requestedLocales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +// 13.4.3 get Intl.DateTimeFormat.prototype.format +JSTaggedValue BuiltinsDateTimeFormat::Format(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1. Let dtf be this value. + JSHandle thisValue = GetThis(argv); + + // 2. If Type(dtf) is not Object, throw a TypeError exception. + if (!thisValue->IsJSObject()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "dtf is not object", JSTaggedValue::Exception()); + } + + // 3. Let dtf be ? UnwrapDateTimeFormat(dtf). + JSHandle dtfValue = JSDateTimeFormat::UnwrapDateTimeFormat(thread, thisValue); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (dtfValue->IsUndefined()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "dtfValue is not object", JSTaggedValue::Exception()); + } + + // 4. If dtf.[[BoundFormat]] is undefined, then + // a. Let F be a new built-in function object as defined in DateTime Format Functions (13.1.5). + // b. Set F.[[DateTimeFormat]] to dtf. + // c. Set dtf.[[BoundFormat]] to F. + // 5. Return dtf.[[BoundFormat]]. + JSHandle dtf = JSHandle::Cast(dtfValue); + JSHandle boundFormat(thread, dtf->GetBoundFormat()); + if (boundFormat->IsUndefined()) { + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle intlBoundFunc = + factory->NewJSIntlBoundFunction(reinterpret_cast(BuiltinsDateTimeFormat::AnonymousDateTimeFormat)); + intlBoundFunc->SetDateTimeFormat(thread, dtf); + dtf->SetBoundFormat(thread, intlBoundFunc); + } + return dtf->GetBoundFormat(); +} + +// 13.1.5 DateTime Format Functions +JSTaggedValue BuiltinsDateTimeFormat::AnonymousDateTimeFormat(EcmaRuntimeCallInfo *argv) +{ + // A DateTime format function is an anonymous built-in function that has a [[DateTimeFormat]] internal slot. + // When a DateTime format function F is called with optional argument date, the following steps are taken: + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + JSHandle intlBoundFunc = JSHandle::Cast(GetConstructor(argv)); + + // 1. Let dtf be F.[[DateTimeFormat]]. + JSHandle dtf(thread, intlBoundFunc->GetDateTimeFormat()); + + // 2. Assert: Type(dtf) is Object and dtf has an [[InitializedDateTimeFormat]] internal slot. + ASSERT_PRINT(dtf->IsJSObject() && dtf->IsJSDateTimeFormat(), "dtf is not object or JSDateTimeFormat"); + + // 3. If date is not provided or is undefined, then + // a. Let x be Call(%Date_now%, undefined). + // 4. Else, + // a. Let x be ? ToNumber(date). + JSHandle date = GetCallArg(argv, 0); + double x = 0.0; + if (date->IsUndefined()) { + x = JSDate::Now().GetNumber(); + } else { + JSTaggedNumber xNumber = JSTaggedValue::ToNumber(thread, date); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + x = xNumber.GetNumber(); + } + + // 5. Return ? FormatDateTime(dtf, x). + JSHandle result = JSDateTimeFormat::FormatDateTime(thread, JSHandle::Cast(dtf), x); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +// 13.4.4 Intl.DateTimeFormat.prototype.formatToParts ( date ) +JSTaggedValue BuiltinsDateTimeFormat::FormatToParts(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let dtf be this value. + JSHandle dtf = GetThis(argv); + // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). + if (!dtf->IsJSDateTimeFormat()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "is not JSDateTimeFormat", JSTaggedValue::Exception()); + } + + // 3. If date is undefined, then + // a. Let x be Call(%Date_now%, undefined). + // 4. Else, + // a. Let x be ? ToNumber(date). + JSHandle date = GetCallArg(argv, 0); + double x = 0.0; + if (date->IsUndefined()) { + x = JSDate::Now().GetNumber(); + } else { + JSTaggedNumber xNumber = JSTaggedValue::ToNumber(thread, date); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + x = xNumber.GetNumber(); + } + + double xValue = JSDate::TimeClip(x); + if (std::isnan(xValue)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid time value", JSTaggedValue::Exception()); + } + + // 5. Return ? FormatDateTimeToParts(dtf, x). + JSHandle result = + JSDateTimeFormat::FormatDateTimeToParts(thread, JSHandle::Cast(dtf), xValue); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +// 13.4.5 Intl.DateTimeFormat.prototype.resolvedOptions () +JSTaggedValue BuiltinsDateTimeFormat::ResolvedOptions(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let dtf be this value. + JSHandle thisValue = GetThis(argv); + // 2. If Type(dtf) is not Object, throw a TypeError exception. + if (!thisValue->IsJSObject()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not object", JSTaggedValue::Exception()); + } + // 3. Let dtf be ? UnwrapDateTimeFormat(dtf). + thisValue = JSDateTimeFormat::UnwrapDateTimeFormat(thread, thisValue); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + auto ecmaVm = thread->GetEcmaVM(); + JSHandle env = ecmaVm->GetGlobalEnv(); + ObjectFactory *factory = ecmaVm->GetFactory(); + JSHandle ctor = env->GetObjectFunction(); + JSHandle options(factory->NewJSObjectByConstructor(JSHandle(ctor), ctor)); + JSDateTimeFormat::ResolvedOptions(thread, JSHandle::Cast(thisValue), options); + // 6. Return options. + return options.GetTaggedValue(); +} + +// Intl.DateTimeFormat.prototype.formatRange +JSTaggedValue BuiltinsDateTimeFormat::FormatRange(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1. Let dtf be this value. + JSHandle thisValue = GetThis(argv); + // 2. If Type(dtf) is not Object, throw a TypeError exception. + if (!thisValue->IsJSObject()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not object", JSTaggedValue::Exception()); + } + + // 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception. + if (!thisValue->IsJSDateTimeFormat()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not JSDateTimeFormat", JSTaggedValue::Exception()); + } + + // 4. If startDate is undefined or endDate is undefined, throw a TypeError exception. + JSHandle startDate = GetCallArg(argv, 0); + JSHandle endDate = GetCallArg(argv, 1); + if (startDate->IsUndefined() || endDate->IsUndefined()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "startDate or endDate is undefined", JSTaggedValue::Exception()); + } + + // 5. Let x be ? ToNumber(startDate). + JSTaggedNumber valueX = JSTaggedValue::ToNumber(thread, startDate); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + double x = valueX.GetNumber(); + + // 6. Let y be ? ToNumber(endDate). + JSTaggedNumber valueY = JSTaggedValue::ToNumber(thread, endDate); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + double y = valueY.GetNumber(); + // 7. If x is greater than y, throw a RangeError exception. + if (x > y) { + THROW_RANGE_ERROR_AND_RETURN(thread, "x is greater than y", JSTaggedValue::Exception()); + } + + // 8. Return ? FormatDateTimeRange(dtf, x, y) + JSHandle dtf = JSHandle::Cast(thisValue); + JSHandle result = JSDateTimeFormat::NormDateTimeRange(thread, dtf, x, y); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +// Intl.DateTimeFormat.prototype.formatRangeToParts +JSTaggedValue BuiltinsDateTimeFormat::FormatRangeToParts(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let dtf be this value. + JSHandle thisValue = GetThis(argv); + // 2. If Type(dtf) is not Object, throw a TypeError exception. + if (!thisValue->IsJSObject()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not object", JSTaggedValue::Exception()); + } + + // 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, + // throw a TypeError exception. + if (!thisValue->IsJSDateTimeFormat()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not JSDateTimeFormat", JSTaggedValue::Exception()); + } + + // 4. If startDate is undefined or endDate is undefined, throw a TypeError exception. + JSHandle startDate = GetCallArg(argv, 0); + JSHandle endDate = GetCallArg(argv, 1); + if (startDate->IsUndefined() || endDate->IsUndefined()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "startDate or endDate is undefined", JSTaggedValue::Exception()); + } + + // 5. Let x be ? ToNumber(startDate). + JSTaggedNumber valueX = JSTaggedValue::ToNumber(thread, startDate); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + double x = valueX.GetNumber(); + + // 6. Let y be ? ToNumber(endDate). + JSTaggedNumber valueY = JSTaggedValue::ToNumber(thread, endDate); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + double y = valueY.GetNumber(); + // 7. If x is greater than y, throw a RangeError exception. + if (x > y) { + THROW_RANGE_ERROR_AND_RETURN(thread, "x is greater than y", JSTaggedValue::Exception()); + } + + // 8. Return ? FormatDateTimeRangeToParts(dtf, x, y) + JSHandle dtf = JSHandle::Cast(thisValue); + JSHandle result = JSDateTimeFormat::NormDateTimeRangeToParts(thread, dtf, x, y); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} +} // namespace panda::ecmascript::builtins \ No newline at end of file diff --git a/ecmascript/builtins/builtins_date_time_format.h b/ecmascript/builtins/builtins_date_time_format.h new file mode 100644 index 0000000000000000000000000000000000000000..ac6172fae5718998b5c38648edfe7b0967de9fa6 --- /dev/null +++ b/ecmascript/builtins/builtins_date_time_format.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_DATE_TIME_FORMAT_H +#define ECMASCRIPT_BUILTINS_BUILTINS_DATE_TIME_FORMAT_H + +#include "ecmascript/base/builtins_base.h" +#include "ecmascript/ecma_runtime_call_info.h" + +namespace panda::ecmascript::builtins { +class BuiltinsDateTimeFormat : public base::BuiltinsBase { +public: + // 13.2.1 Intl.DateTimeFormat ( [ locales [ , options ] ] ) + static JSTaggedValue DateTimeFormatConstructor(EcmaRuntimeCallInfo *argv); + + // 13.3.2 Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] ) + static JSTaggedValue SupportedLocalesOf(EcmaRuntimeCallInfo *argv); + + // 13.4.3 get Intl.DateTimeFormat.prototype.format + static JSTaggedValue Format(EcmaRuntimeCallInfo *argv); + + // 13.4.4 Intl.DateTimeFormat.prototype.formatToParts ( date ) + static JSTaggedValue FormatToParts(EcmaRuntimeCallInfo *argv); + + // 13.4.5 Intl.DateTimeFormat.prototype.resolvedOptions () + static JSTaggedValue ResolvedOptions(EcmaRuntimeCallInfo *argv); + + // Intl.DateTimeFormat.prototype.formatRange + static JSTaggedValue FormatRange(EcmaRuntimeCallInfo *argv); + + // Intl.DateTimeFormat.prototype.formatRangeToParts + static JSTaggedValue FormatRangeToParts(EcmaRuntimeCallInfo *argv); + +private: + // 13.1.5 DateTime Format Functions + static JSTaggedValue AnonymousDateTimeFormat(EcmaRuntimeCallInfo *argv); +}; +} // namespace panda::ecmascript::builtins +#endif // ECMASCRIPT_BUILTINS_BUILTINS_DATE_TIME_FORMAT_H_ \ No newline at end of file diff --git a/ecmascript/builtins/builtins_errors.h b/ecmascript/builtins/builtins_errors.h index 9e05771d6b9c871b8d4057bff8534bfaf4c7d544..9c842a790a927f0d096364c4048bb1b946e40203 100644 --- a/ecmascript/builtins/builtins_errors.h +++ b/ecmascript/builtins/builtins_errors.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ERRORS_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ERRORS_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_ERRORS_H +#define ECMASCRIPT_BUILTINS_BUILTINS_ERRORS_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -79,4 +79,4 @@ public: }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ERRORS_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_ERRORS_H diff --git a/ecmascript/builtins/builtins_function.cpp b/ecmascript/builtins/builtins_function.cpp index bc4abcda22d84620031f9a59903968b2285fdaf3..50ab74e6b35381f636d8907d1fd29e8c7bf161e9 100644 --- a/ecmascript/builtins/builtins_function.cpp +++ b/ecmascript/builtins/builtins_function.cpp @@ -16,6 +16,9 @@ #include "ecmascript/builtins/builtins_function.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" +#include "ecmascript/js_arguments.h" +#include "ecmascript/js_stable_array.h" #include "ecmascript/tagged_array-inl.h" namespace panda::ecmascript::builtins { @@ -35,6 +38,37 @@ JSTaggedValue BuiltinsFunction::FunctionPrototypeInvokeSelf([[maybe_unused]] Ecm { return JSTaggedValue::Undefined(); } +namespace { +static bool BuildArgumentsListFast(JSThread *thread, const JSHandle &arrayObj) +{ + if (!arrayObj->HasStableElements(thread)) { + return false; + } + InternalCallParams *arguments = thread->GetInternalCallParams(); + if (arrayObj->IsStableJSArguments(thread)) { + JSHandle argList = JSHandle::Cast(arrayObj); + TaggedArray *elements = TaggedArray::Cast(argList->GetElements().GetTaggedObject()); + auto env = thread->GetEcmaVM()->GetGlobalEnv(); + if (argList->GetClass() != env->GetArgumentsClass().GetObject()) { + return false; + } + auto result = argList->GetPropertyInlinedProps(JSArguments::LENGTH_INLINE_PROPERTY_INDEX); + if (!result.IsInt()) { + return false; + } + uint32_t length = static_cast(result.GetInt()); + arguments->MakeArgListWithHole(elements, length); + } else if (arrayObj->IsStableJSArray(thread)) { + JSHandle argList = JSHandle::Cast(arrayObj); + TaggedArray *elements = TaggedArray::Cast(argList->GetElements().GetTaggedObject()); + uint32_t length = argList->GetArrayLength(); + arguments->MakeArgListWithHole(elements, length); + } else { + UNREACHABLE(); + } + return true; +} +} // anonymous namespace // ecma 19.2.3.1 Function.prototype.apply (thisArg, argArray) JSTaggedValue BuiltinsFunction::FunctionPrototypeApply(EcmaRuntimeCallInfo *argv) @@ -48,25 +82,27 @@ JSTaggedValue BuiltinsFunction::FunctionPrototypeApply(EcmaRuntimeCallInfo *argv if (!GetThis(argv)->IsCallable()) { THROW_TYPE_ERROR_AND_RETURN(thread, "apply target is not callable", JSTaggedValue::Exception()); } - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle func = GetThis(argv); JSHandle thisArg = GetCallArg(argv, 0); // 2. If argArray is null or undefined, then - if (GetCallArg(argv, 1)->IsUndefined()) { // null will also be undefined + if (GetCallArg(argv, 1)->IsUndefined()) { // null will also get undefined // a. Return Call(func, thisArg). - JSHandle emptyArray = factory->NewTaggedArray(0); - return JSFunction::Call(thread, func, thisArg, emptyArray); + return JSFunction::Call(thread, func, thisArg, 0, nullptr); } // 3. Let argList be CreateListFromArrayLike(argArray). JSHandle arrayObj = GetCallArg(argv, 1); - JSHandle argList = JSHandle::Cast(JSObject::CreateListFromArrayLike(thread, arrayObj)); - - // 4. ReturnIfAbrupt(argList). - RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + InternalCallParams *arguments = thread->GetInternalCallParams(); + if (!BuildArgumentsListFast(thread, arrayObj)) { + JSHandle argList = JSHandle::Cast( + JSObject::CreateListFromArrayLike(thread, arrayObj)); + // 4. ReturnIfAbrupt(argList). + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + arguments->MakeArgList(*argList); + } // 6. Return Call(func, thisArg, argList). - return JSFunction::Call(thread, func, thisArg, argList); + return JSFunction::Call(thread, func, thisArg, arguments->GetLength(), arguments->GetArgv()); } // ecma 19.2.3.2 Function.prototype.bind (thisArg , ...args) @@ -145,7 +181,7 @@ JSTaggedValue BuiltinsFunction::FunctionPrototypeBind(EcmaRuntimeCallInfo *argv) // 13. ReturnIfAbrupt(targetName). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSHandle boundName(factory->NewFromString("bound")); + JSHandle boundName(factory->NewFromCanBeCompressString("bound")); // 14. If Type(targetName) is not String, let targetName be the empty string. // 15. Perform SetFunctionName(F, targetName, "bound"). if (!targetName->IsString()) { @@ -173,7 +209,6 @@ JSTaggedValue BuiltinsFunction::FunctionPrototypeCall(EcmaRuntimeCallInfo *argv) if (!GetThis(argv)->IsCallable()) { THROW_TYPE_ERROR_AND_RETURN(thread, "call target is not callable", JSTaggedValue::Exception()); } - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle func = GetThis(argv); JSHandle thisArg = GetCallArg(argv, 0); @@ -184,13 +219,11 @@ JSTaggedValue BuiltinsFunction::FunctionPrototypeCall(EcmaRuntimeCallInfo *argv) // 2. Let argList be an empty List. // 3. If this method was called with more than one argument then in left to right order, // starting with the second argument, append each argument as the last element of argList. - JSHandle argsList = factory->NewTaggedArray(argsLength); - for (array_size_t index = 0; index < argsLength; ++index) { - argsList->Set(thread, index, GetCallArg(argv, index + 1)); - } + InternalCallParams *argsList = thread->GetInternalCallParams(); + argsList->MakeArgv(argv, 1); // 5. Return Call(func, thisArg, argList). - return JSFunction::Call(thread, func, thisArg, argsList); + return JSFunction::Call(thread, func, thisArg, argsLength, argsList->GetArgv()); } // ecma 19.2.3.5 Function.prototype.toString () diff --git a/ecmascript/builtins/builtins_function.h b/ecmascript/builtins/builtins_function.h index e18e90da0b526bd6ecb90c0961d4183dfc5950d2..d2027371fefa6d8bf50ced08ee89f010d647ad0c 100644 --- a/ecmascript/builtins/builtins_function.h +++ b/ecmascript/builtins/builtins_function.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_FUNCTION_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_FUNCTION_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_FUNCTION_H +#define ECMASCRIPT_BUILTINS_BUILTINS_FUNCTION_H #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/base/builtins_base.h" @@ -44,4 +44,4 @@ public: static JSTaggedValue FunctionPrototypeHasInstance(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_FUNCTION_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_FUNCTION_H diff --git a/ecmascript/builtins/builtins_generator.h b/ecmascript/builtins/builtins_generator.h index 1c7b468c6f8f85b97a33c284d72f28b068dcc194..e4f4e174e02edf3d818e75246894dcd19a45dcc5 100644 --- a/ecmascript/builtins/builtins_generator.h +++ b/ecmascript/builtins/builtins_generator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_GENERATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_GENERATOR_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_GENERATOR_H +#define ECMASCRIPT_BUILTINS_BUILTINS_GENERATOR_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/js_tagged_value-inl.h" @@ -38,4 +38,4 @@ public: }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_GENERATOR_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_GENERATOR_H diff --git a/ecmascript/builtins/builtins_global.cpp b/ecmascript/builtins/builtins_global.cpp index 8ed7a6d779969732beab86d0665aef4d7ffc1060..694ba3f61072872eb25e31ecf54635bf6c2a4118 100644 --- a/ecmascript/builtins/builtins_global.cpp +++ b/ecmascript/builtins/builtins_global.cpp @@ -21,6 +21,7 @@ #include "ecmascript/base/number_helper.h" #include "ecmascript/base/string_helper.h" #include "ecmascript/ecma_macros.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/slow_runtime_helper.h" #include "ecmascript/js_invoker.h" #include "ecmascript/mem/c_containers.h" @@ -499,17 +500,12 @@ JSTaggedValue BuiltinsGlobal::CallJsBoundFunction(EcmaRuntimeCallInfo *msg) [[maybe_unused]] EcmaHandleScope handleScope(thread); // msg contains jsfunc, this, arg1,... - uint32_t numArgs = msg->GetArgsNumber(); JSHandle boundFunc(GetConstructor(msg)); JSHandle thisObj(thread, boundFunc->GetBoundThis()); - JSHandle newArgs = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(numArgs); - - for (uint32_t i = 0; i < numArgs; i++) { - newArgs->Set(thread, i, GetCallArg(msg, i).GetTaggedValue()); - } - - return SlowRuntimeHelper::CallBoundFunction(thread, boundFunc, thisObj, newArgs); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(msg, 0); + return SlowRuntimeHelper::CallBoundFunction(thread, boundFunc, thisObj); } JSTaggedValue BuiltinsGlobal::CallJsProxy(EcmaRuntimeCallInfo *msg) @@ -518,7 +514,6 @@ JSTaggedValue BuiltinsGlobal::CallJsProxy(EcmaRuntimeCallInfo *msg) BUILTINS_API_TRACE(thread, Global, CallJsProxy); [[maybe_unused]] EcmaHandleScope handleScope(thread); // msg contains js_proxy, this, arg1,... - int32_t numArgs = msg->GetArgsNumber(); JSHandle proxy(GetConstructor(msg)); if (!proxy->IsCallable()) { THROW_TYPE_ERROR_AND_RETURN(thread, "Proxy target is not callable", JSTaggedValue::Undefined()); @@ -527,16 +522,13 @@ JSTaggedValue BuiltinsGlobal::CallJsProxy(EcmaRuntimeCallInfo *msg) // Calling proxy directly should transfer 'undefined' as this JSHandle thisObj(GetThis(msg)); - JSHandle array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(numArgs); - - for (int32_t i = 0; i < numArgs; i++) { - array->Set(thread, i, GetCallArg(msg, i).GetTaggedValue()); - } - - return JSProxy::CallInternal(thread, proxy, thisObj, array); + JSHandle argsList = GetArgsArray(msg); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgList(*argsList); + return JSProxy::CallInternal(thread, proxy, thisObj, argsList->GetLength(), arguments->GetArgv()); } -#ifdef PANDA_ECMASCRIPT_ENABLE_RUNTIME_STAT +#if ECMASCRIPT_ENABLE_RUNTIME_STAT JSTaggedValue BuiltinsGlobal::StartRuntimeStat(EcmaRuntimeCallInfo *msg) { JSThread *thread = msg->GetThread(); diff --git a/ecmascript/builtins/builtins_global.h b/ecmascript/builtins/builtins_global.h index 5523f8590aa108af45515dffccede7f406da39a9..f424a42964d3b337c5854632c9c1537fb7ed11b4 100644 --- a/ecmascript/builtins/builtins_global.h +++ b/ecmascript/builtins/builtins_global.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_GLOBAL_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_GLOBAL_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_GLOBAL_H +#define ECMASCRIPT_BUILTINS_BUILTINS_GLOBAL_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/js_thread.h" @@ -44,7 +44,7 @@ public: static JSTaggedValue PrintEntrypoint(EcmaRuntimeCallInfo *msg); static JSTaggedValue CallJsBoundFunction(EcmaRuntimeCallInfo *msg); static JSTaggedValue CallJsProxy(EcmaRuntimeCallInfo *msg); -#ifdef PANDA_ECMASCRIPT_ENABLE_RUNTIME_STAT +#if ECMASCRIPT_ENABLE_RUNTIME_STAT static JSTaggedValue StartRuntimeStat(EcmaRuntimeCallInfo *msg); static JSTaggedValue StopRuntimeStat(EcmaRuntimeCallInfo *msg); #endif @@ -64,4 +64,4 @@ private: }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ERROR_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_ERROR_H diff --git a/ecmascript/mem/code.h b/ecmascript/builtins/builtins_intl.cpp similarity index 43% rename from ecmascript/mem/code.h rename to ecmascript/builtins/builtins_intl.cpp index d5451a9936261a9c8a8f2c4216ebd1ddfaa9d369..9df44f3b4f83a9080a0f46f8a4e50ccdbb5436b5 100644 --- a/ecmascript/mem/code.h +++ b/ecmascript/builtins/builtins_intl.cpp @@ -1,46 +1,38 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_CODE_H -#define PANDA_RUNTIME_ECMASCRIPT_CODE_H - -#include "ecmascript/js_tagged_value.h" -#include "ecmascript/object_factory.h" -#include "ecmascript/mem/tagged_object.h" - -namespace panda { -namespace ecmascript { -class Code : public TaggedObject { -public: - Code(); - ~Code(); - Code(const Code &) = delete; - Code(Code &&) = delete; - Code &operator=(const Code &) = delete; - Code &operator=(Code &&) = delete; - static Code *Cast(ObjectHeader *object) - { - ASSERT(JSTaggedValue(object).IsCode()); - return static_cast(object); - } - static constexpr size_t LENGTH_OFFSET = TaggedObject::ObjectHeaderSize(); - - ACCESSORS(length, LENGTH_OFFSET, DATA_OFFSET); - ACCESSORS(data, DATA_OFFSET, SIZE); -}; -} // namespace ecmascript -} // namespace panda - -#endif // PANDA_RUNTIME_ECMASCRIPT_CODE_H +/* + * Copyright (c) 2021 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. + */ + +#include "ecmascript/builtins/builtins_intl.h" + +#include "ecmascript/js_array.h" +#include "ecmascript/js_locale.h" +#include "ecmascript/js_tagged_value.h" + +namespace panda::ecmascript::builtins { +// 8.2.1 Intl.getCanonicalLocales ( locales ) +JSTaggedValue BuiltinsIntl::GetCanonicalLocales(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1.Let ll be ? CanonicalizeLocaleList(locales). + JSHandle locales = GetCallArg(argv, 0); + JSHandle elements = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 2.Return CreateArrayFromList(ll). + JSHandle result = JSArray::CreateArrayFromList(thread, elements); + return result.GetTaggedValue(); +} +} // namespace panda::ecmascript::builtins \ No newline at end of file diff --git a/ecmascript/builtins/builtins_intl.h b/ecmascript/builtins/builtins_intl.h new file mode 100644 index 0000000000000000000000000000000000000000..d55580a64decc65b6fe57dbad901247309e139e0 --- /dev/null +++ b/ecmascript/builtins/builtins_intl.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_INTL_H +#define ECMASCRIPT_BUILTINS_BUILTINS_INTL_H + +#include "ecmascript/base/builtins_base.h" + +namespace panda::ecmascript::builtins { +class BuiltinsIntl : public base::BuiltinsBase { +public: + // 8.2.1 Intl.getCanonicalLocales ( locales ) + static JSTaggedValue GetCanonicalLocales(EcmaRuntimeCallInfo *argv); +}; +} // namespace panda::ecmascript::builtins +#endif // ECMASCRIPT_BUILTINS_BUILTINS_INTL_H \ No newline at end of file diff --git a/ecmascript/builtins/builtins_iterator.h b/ecmascript/builtins/builtins_iterator.h index fa4883ec1f5c333b6ff6aab07e802ca0bcfbcc0a..a971d1e250a7b4434219fb374ed43c6083e9bd64 100644 --- a/ecmascript/builtins/builtins_iterator.h +++ b/ecmascript/builtins/builtins_iterator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ITERATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ITERATOR_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_ITERATOR_H +#define ECMASCRIPT_BUILTINS_BUILTINS_ITERATOR_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -33,4 +33,4 @@ public: static JSTaggedValue GetIteratorObj(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_ITERATOR_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_ITERATOR_H diff --git a/ecmascript/builtins/builtins_json.h b/ecmascript/builtins/builtins_json.h index 091bc7378c5c0a9a947731da8d8f7c14a17e1e92..fa01eb6737a658c71f75661edfe6c61634af63ad 100644 --- a/ecmascript/builtins/builtins_json.h +++ b/ecmascript/builtins/builtins_json.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_JSON_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_JSON_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_JSON_H +#define ECMASCRIPT_BUILTINS_BUILTINS_JSON_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -28,4 +28,4 @@ public: static JSTaggedValue Stringify(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_JSON_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_JSON_H diff --git a/ecmascript/builtins/builtins_locale.cpp b/ecmascript/builtins/builtins_locale.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5f5e2517c374229003436db00c2fd0096eb7a542 --- /dev/null +++ b/ecmascript/builtins/builtins_locale.cpp @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "ecmascript/builtins/builtins_locale.h" + +#include "ecmascript/ecma_vm.h" +#include "ecmascript/global_env.h" +#include "ecmascript/js_locale.h" +#include "ecmascript/object_factory.h" + +namespace panda::ecmascript::builtins { +// 10.1.3 Intl.Locale( tag [, options] ) +JSTaggedValue BuiltinsLocale::LocaleConstructor(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + // 1. If NewTarget is undefined, throw a TypeError exception. + JSHandle newTarget = GetNewTarget(argv); + if (newTarget->IsUndefined()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "newTarget is undefined", JSTaggedValue::Exception()); + } + + // 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget, %LocalePrototype%, internalSlotsList). + JSHandle constructor = GetConstructor(argv); + JSHandle locale = + JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(constructor), newTarget)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 7. If Type(tag) is not String or Object, throw a TypeError exception. + JSHandle tag = GetCallArg(argv, 0); + if (!tag->IsString() && !tag->IsJSObject()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "tag is not String or Object", JSTaggedValue::Exception()); + } + + // 8. If Type(tag) is Object and tag has an [[InitializedLocale]] internal slot, then + // a.Let tag be tag.[[Locale]]. + // 9. Else, + // a.Let tag be ? ToString(tag). + JSHandle localeString = factory->GetEmptyString(); + if (!tag->IsJSLocale()) { + localeString = JSTaggedValue::ToString(thread, tag); + } else { + icu::Locale *icuLocale = (JSHandle::Cast(tag))->GetIcuLocale(); + localeString = JSLocale::ToLanguageTag(thread, *icuLocale); + } + // 10. If options is undefined, then + // a.Let options be ! ObjectCreate(null). + // 11. Else + // a.Let options be ? ToObject(options). + JSHandle options = GetCallArg(argv, 1); + JSHandle optionsObj; + if (options->IsUndefined()) { + optionsObj = factory->OrdinaryNewJSObjectCreate(JSHandle(thread, JSTaggedValue::Null())); + } else { + optionsObj = JSTaggedValue::ToObject(thread, options); + } + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + JSHandle result = JSLocale::InitializeLocale(thread, locale, localeString, optionsObj); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::Maximize(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]]. If an error is + // signaled, set maximal to loc.[[Locale]]. + JSHandle locale = JSHandle::Cast(loc); + icu::Locale source(*(locale->GetIcuLocale())); + UErrorCode status = U_ZERO_ERROR; + source.addLikelySubtags(status); + ASSERT(U_SUCCESS(status)); + ASSERT(!source.isBogus()); + + // 4. Return ! Construct(%Locale%, maximal). + EcmaVM *ecmaVm = thread->GetEcmaVM(); + JSHandle env = ecmaVm->GetGlobalEnv(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + JSHandle ctor = env->GetLocaleFunction(); + JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(ctor), ctor); + factory->NewJSIntlIcuData(JSHandle::Cast(obj), source, JSLocale::FreeIcuLocale); + return obj.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::Minimize(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + + // 3. Let minimal be the result of the Remove Likely Subtags algorithm applied to loc.[[Locale]]. + // If an error is signaled, set minimal to loc.[[Locale]]. + JSHandle locale = JSHandle::Cast(loc); + icu::Locale source(*(locale->GetIcuLocale())); + UErrorCode status = U_ZERO_ERROR; + source.minimizeSubtags(status); + ASSERT(U_SUCCESS(status)); + ASSERT(!source.isBogus()); + + [[maybe_unused]] auto res = source.toLanguageTag(status); + + // 4. Return ! Construct(%Locale%, minimal). + EcmaVM *ecmaVm = thread->GetEcmaVM(); + JSHandle env = ecmaVm->GetGlobalEnv(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + JSHandle ctor = env->GetLocaleFunction(); + JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(ctor), ctor); + factory->NewJSIntlIcuData(JSHandle::Cast(obj), source, JSLocale::FreeIcuLocale); + return obj.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::ToString(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Return loc.[[Locale]]. + JSHandle result = JSLocale::ToString(thread, JSHandle::Cast(loc)); + return result.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::GetBaseName(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Let locale be loc.[[Locale]]. + // 4. Return the substring of locale corresponding to the unicode_language_id production. + JSHandle locale = JSHandle::Cast(loc); + icu::Locale icuLocale = icu::Locale::createFromName(locale->GetIcuLocale()->getBaseName()); + JSHandle baseName = JSLocale::ToLanguageTag(thread, icuLocale); + return baseName.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::GetCalendar(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Return loc.[[Calendar]]. + JSHandle locale = JSHandle::Cast(loc); + JSHandle calendar = JSLocale::NormalizeKeywordValue(thread, locale, "ca"); + return calendar.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::GetCaseFirst(EcmaRuntimeCallInfo *argv) +{ + // This property only exists if %Locale%.[[RelevantExtensionKeys]] contains "kf". + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Return loc.[[CaseFirst]]. + JSHandle locale = JSHandle::Cast(loc); + JSHandle caseFirst = JSLocale::NormalizeKeywordValue(thread, locale, "kf"); + return caseFirst.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::GetCollation(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Return loc.[[Collation]]. + JSHandle locale = JSHandle::Cast(loc); + JSHandle collation = JSLocale::NormalizeKeywordValue(thread, locale, "co"); + return collation.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::GetHourCycle(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Return loc.[[HourCycle]]. + JSHandle locale = JSHandle::Cast(loc); + JSHandle hourCycle = JSLocale::NormalizeKeywordValue(thread, locale, "hc"); + return hourCycle.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::GetNumeric(EcmaRuntimeCallInfo *argv) +{ + // This property only exists if %Locale%.[[RelevantExtensionKeys]] contains "kn". + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Return loc.[[Numeric]]. + JSHandle locale = JSHandle::Cast(loc); + icu::Locale *icuLocale = locale->GetIcuLocale(); + UErrorCode status = U_ZERO_ERROR; + auto numeric = icuLocale->getUnicodeKeywordValue("kn", status); + JSTaggedValue result = (numeric == "true") ? JSTaggedValue::True() : JSTaggedValue::False(); + return result; +} + +JSTaggedValue BuiltinsLocale::GetNumberingSystem(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Return loc.[[NumberingSystem]]. + JSHandle locale = JSHandle::Cast(loc); + JSHandle numberingSystem = JSLocale::NormalizeKeywordValue(thread, locale, "nu"); + return numberingSystem.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::GetLanguage(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Let locale be loc.[[Locale]]. + JSHandle locale = JSHandle::Cast(loc); + // 4. Assert: locale matches the unicode_locale_id production. + // 5. Return the substring of locale corresponding to the unicode_language_subtag production of the + // unicode_language_id. + JSHandle result = factory->NewFromString("undefined"); + CString language = locale->GetIcuLocale()->getLanguage(); + if (language.empty()) { + return result.GetTaggedValue(); + } + result = factory->NewFromString(language); + return result.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::GetScript(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Let locale be loc.[[Locale]]. + JSHandle locale = JSHandle::Cast(loc); + + // 4. Assert: locale matches the unicode_locale_id production. + // 5. If the unicode_language_id production of locale does not contain the ["-" unicode_script_subtag] sequence, + // return undefined. + // 6. Return the substring of locale corresponding to the unicode_script_subtag production of the + // unicode_language_id. + JSHandle result(thread, JSTaggedValue::Undefined()); + CString script = locale->GetIcuLocale()->getScript(); + if (script.empty()) { + return result.GetTaggedValue(); + } + result = factory->NewFromString(script); + return result.GetTaggedValue(); +} + +JSTaggedValue BuiltinsLocale::GetRegion(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + const GlobalEnvConstants *globalConst = thread->GlobalConstants(); + ObjectFactory *factory = ecmaVm->GetFactory(); + // 1. Let loc be the this value. + JSHandle loc = GetThis(argv); + // 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]). + if (!loc->IsJSLocale()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "not locale", JSTaggedValue::Exception()); + } + // 3. Let locale be loc.[[Locale]]. + JSHandle locale = JSHandle::Cast(loc); + // 4. Assert: locale matches the unicode_locale_id production. + // 5. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, + // return undefined. + // 6. Return the substring of locale corresponding to the unicode_region_subtag production of the + // unicode_language_id. + CString region = locale->GetIcuLocale()->getCountry(); + if (region.empty()) { + return globalConst->GetUndefined(); + } + return factory->NewFromString(region).GetTaggedValue(); +} +} // namespace panda::ecmascript::builtins \ No newline at end of file diff --git a/ecmascript/builtins/builtins_locale.h b/ecmascript/builtins/builtins_locale.h new file mode 100644 index 0000000000000000000000000000000000000000..d2a378075429398e85f3014b29bd70b7ccc48db6 --- /dev/null +++ b/ecmascript/builtins/builtins_locale.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_LOCALE_H +#define ECMASCRIPT_BUILTINS_BUILTINS_LOCALE_H + +#include "ecmascript/base/builtins_base.h" + +namespace panda::ecmascript::builtins { +class BuiltinsLocale : public base::BuiltinsBase { +public: + // 10.1.3 Intl.Locale( tag [, options] ) + static JSTaggedValue LocaleConstructor(EcmaRuntimeCallInfo *argv); + + // 10.3.3 Intl.Locale.prototype.maximize () + static JSTaggedValue Maximize(EcmaRuntimeCallInfo *argv); + // 10.3.4 Intl.Locale.prototype.minimize () + static JSTaggedValue Minimize(EcmaRuntimeCallInfo *argv); + // 10.3.5 Intl.Locale.prototype.toString () + static JSTaggedValue ToString(EcmaRuntimeCallInfo *argv); + + // 10.3.6 get Intl.Locale.prototype.baseName + static JSTaggedValue GetBaseName(EcmaRuntimeCallInfo *argv); + // 10.3.7 get Intl.Locale.prototype.calendar + static JSTaggedValue GetCalendar(EcmaRuntimeCallInfo *argv); + // 10.3.8 get Intl.Locale.prototype.caseFirst + static JSTaggedValue GetCaseFirst(EcmaRuntimeCallInfo *argv); + // 10.3.9 get Intl.Locale.prototype.collation + static JSTaggedValue GetCollation(EcmaRuntimeCallInfo *argv); + // 10.3.10 get Intl.Locale.prototype.hourCycle + static JSTaggedValue GetHourCycle(EcmaRuntimeCallInfo *argv); + // 10.3.11 get Intl.Locale.prototype.numeric + static JSTaggedValue GetNumeric(EcmaRuntimeCallInfo *argv); + // 10.3.12 get Intl.Locale.prototype.numberingSystem + static JSTaggedValue GetNumberingSystem(EcmaRuntimeCallInfo *argv); + // 10.3.13 get Intl.Locale.prototype.language + static JSTaggedValue GetLanguage(EcmaRuntimeCallInfo *argv); + // 10.3.14 get Intl.Locale.prototype.script + static JSTaggedValue GetScript(EcmaRuntimeCallInfo *argv); + // 10.3.15 get Intl.Locale.prototype.region + static JSTaggedValue GetRegion(EcmaRuntimeCallInfo *argv); +}; +} // namespace panda::ecmascript::builtins +#endif // ECMASCRIPT_BUILTINS_BUILTINS_LOCALE_H \ No newline at end of file diff --git a/ecmascript/builtins/builtins_map.cpp b/ecmascript/builtins/builtins_map.cpp index aa08d508d596dd40847c0ff5da9e63e9a6f135f7..0d7df757b58da5aeba16a18e2e9ce4b0b5d60316 100644 --- a/ecmascript/builtins/builtins_map.cpp +++ b/ecmascript/builtins/builtins_map.cpp @@ -16,6 +16,7 @@ #include "builtins_map.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_invoker.h" #include "ecmascript/js_map.h" #include "ecmascript/js_map_iterator.h" @@ -57,7 +58,7 @@ JSTaggedValue BuiltinsMap::MapConstructor(EcmaRuntimeCallInfo *argv) THROW_TYPE_ERROR_AND_RETURN(thread, "iterable is not object", JSTaggedValue::Exception()); } // Let adder be Get(map, "set"). - JSHandle adderKey(factory->NewFromString("set")); + JSHandle adderKey(factory->NewFromCanBeCompressString("set")); JSHandle adder = JSObject::GetProperty(thread, JSHandle(map), adderKey).GetValue(); // ReturnIfAbrupt(adder). RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, adder.GetTaggedValue()); @@ -99,17 +100,17 @@ JSTaggedValue BuiltinsMap::MapConstructor(EcmaRuntimeCallInfo *argv) if (thread->HasPendingException()) { return JSIterator::IteratorCloseAndReturn(thread, iter, key); } - JSHandle array(factory->NewTaggedArray(2)); // 2: key and value pair - array->Set(thread, 0, key); // Let v be Get(nextItem, "1"). JSHandle value = JSObject::GetProperty(thread, nextValue, valueIndex).GetValue(); // If v is an abrupt completion, return IteratorClose(iter, v). if (thread->HasPendingException()) { return JSIterator::IteratorCloseAndReturn(thread, iter, value); } - array->Set(thread, 1, value); // Let status be Call(adder, map, «nextValue.[[value]]»). - JSTaggedValue ret = JSFunction::Call(thread, adder, JSHandle(map), array); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(key, value); + JSTaggedValue ret = JSFunction::Call(thread, + adder, JSHandle(map), 2, arguments->GetArgv()); // 2: key and value pair status.Update(ret); // If status is an abrupt completion, return IteratorClose(iter, status). @@ -235,22 +236,19 @@ JSTaggedValue BuiltinsMap::ForEach([[maybe_unused]] EcmaRuntimeCallInfo *argv) JSHandle thisArg = GetCallArg(argv, 1); // composed arguments - int arguementsLength = 3; - JSHandle array(factory->NewTaggedArray(arguementsLength)); JSHandle iter(factory->NewJSMapIterator(map, IterationKind::KEY_AND_VALUE)); JSHandle keyIndex(thread, JSTaggedValue(0)); JSHandle valueIndex(thread, JSTaggedValue(1)); JSHandle result = JSIterator::IteratorStep(thread, iter); + InternalCallParams *arguments = thread->GetInternalCallParams(); while (!result->IsFalse()) { RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, result.GetTaggedValue()); JSHandle iterValue(JSIterator::IteratorValue(thread, result)); JSHandle key = JSObject::GetProperty(thread, iterValue, keyIndex).GetValue(); JSHandle value = JSObject::GetProperty(thread, iterValue, valueIndex).GetValue(); - array->Set(thread, 0, value); - array->Set(thread, 1, key); - array->Set(thread, 2, map); // 2: the third arg is map // Let funcResult be Call(callbackfn, T, «e, e, S»). - JSTaggedValue ret = JSFunction::Call(thread, func, thisArg, array); + arguments->MakeArgv(value, key, JSHandle(map)); + JSTaggedValue ret = JSFunction::Call(thread, func, thisArg, 3, arguments->GetArgv()); // 3: three args // returnIfAbrupt RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ret); result = JSIterator::IteratorStep(thread, iter); diff --git a/ecmascript/builtins/builtins_map.h b/ecmascript/builtins/builtins_map.h index 48141f4cee1f1e3b417be5c955cdd7c61226397c..c00b7139575ed1356d6dad9c6a896a60a5bc4ae2 100644 --- a/ecmascript/builtins/builtins_map.h +++ b/ecmascript/builtins/builtins_map.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_MAP_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_MAP_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_MAP_H +#define ECMASCRIPT_BUILTINS_BUILTINS_MAP_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -48,4 +48,4 @@ public: static JSTaggedValue Values(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_MAP_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_MAP_H diff --git a/ecmascript/builtins/builtins_math.h b/ecmascript/builtins/builtins_math.h index 4e780b0ce6a9692b8a65339a5e7e40f75892d1d7..293d6761cfc5d1e3363c4ef83460fda1f2f14b43 100644 --- a/ecmascript/builtins/builtins_math.h +++ b/ecmascript/builtins/builtins_math.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_MATH_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_MATH_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_MATH_H +#define ECMASCRIPT_BUILTINS_BUILTINS_MATH_H #include "ecmascript/base/builtins_base.h" @@ -109,4 +109,4 @@ public: static JSTaggedValue Trunc(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_MATH_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_MATH_H diff --git a/ecmascript/builtins/builtins_number.cpp b/ecmascript/builtins/builtins_number.cpp index 9f8b40bbc4add0e8c595328ee32276b18eade73e..bbce150ed3ad15bc8c8096d4c7ee106a48544f27 100644 --- a/ecmascript/builtins/builtins_number.cpp +++ b/ecmascript/builtins/builtins_number.cpp @@ -13,12 +13,14 @@ * limitations under the License. */ -#include "ecmascript/base/number_helper.h" #include "ecmascript/builtins/builtins_number.h" + +#include "ecmascript/base/number_helper.h" #include "ecmascript/ecma_macros.h" #include "ecmascript/global_env.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_hclass.h" +#include "ecmascript/js_number_format.h" #include "ecmascript/js_primitive_ref.h" #include "ecmascript/js_tagged_number.h" #include "ecmascript/js_tagged_value-inl.h" @@ -292,6 +294,31 @@ JSTaggedValue BuiltinsNumber::ToFixed(EcmaRuntimeCallInfo *argv) return NumberHelper::DoubleToFixed(thread, valueNumber, static_cast(digit)); } +// 20.1.3.4 +JSTaggedValue BuiltinsNumber::ToLocaleString(EcmaRuntimeCallInfo *argv) +{ + ASSERT(argv); + JSThread *thread = argv->GetThread(); + BUILTINS_API_TRACE(thread, Number, ToLocaleString); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + // 1. Let x be thisNumberValue(this value). + JSTaggedNumber x = ThisNumberValue(argv); + // 2. Let numberFormat be ? Construct(%NumberFormat%, « locales, options »). + JSHandle func = thread->GetEcmaVM()->GetGlobalEnv()->GetNumberFormatFunction(); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle numberFormat = + JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(func), func)); + JSHandle locales = GetCallArg(argv, 0); + JSHandle options = GetCallArg(argv, 1); + JSNumberFormat::InitializeNumberFormat(thread, numberFormat, locales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Return ? FormatNumeric(numberFormat, x). + JSHandle result = JSNumberFormat::FormatNumeric(thread, numberFormat, x); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + // 20.1.3.5 JSTaggedValue BuiltinsNumber::ToPrecision(EcmaRuntimeCallInfo *argv) { diff --git a/ecmascript/builtins/builtins_number.h b/ecmascript/builtins/builtins_number.h index 2b24c220abf5a511ffe2fb299975e66aacb0637b..e2ad4d8b496178a9eaadfc69b2854e710b70bef0 100644 --- a/ecmascript/builtins/builtins_number.h +++ b/ecmascript/builtins/builtins_number.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_NUMBER_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_NUMBER_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_NUMBER_H +#define ECMASCRIPT_BUILTINS_BUILTINS_NUMBER_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/js_tagged_value.h" @@ -56,4 +56,4 @@ private: static JSTaggedNumber ThisNumberValue(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_NUBMER_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_NUBMER_H diff --git a/ecmascript/builtins/builtins_number_format.cpp b/ecmascript/builtins/builtins_number_format.cpp new file mode 100644 index 0000000000000000000000000000000000000000..657eb5fa9733382b256503019a5b396f41687dd1 --- /dev/null +++ b/ecmascript/builtins/builtins_number_format.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "builtins_number_format.h" +#include "ecmascript/ecma_vm.h" +#include "ecmascript/global_env.h" +#include "ecmascript/js_array.h" +#include "ecmascript/js_intl.h" +#include "ecmascript/js_locale.h" +#include "ecmascript/js_number_format.h" +#include "ecmascript/js_tagged_value.h" +#include "ecmascript/object_factory.h" + +namespace panda::ecmascript::builtins { +// 13.2.1 Intl.NumberFormat ( [ locales [ , options ] ] ) +JSTaggedValue BuiltinsNumberFormat::NumberFormatConstructor(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + JSHandle env = ecmaVm->GetGlobalEnv(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. + JSHandle constructor = GetConstructor(argv); + JSHandle newTarget = GetNewTarget(argv); + if (newTarget->IsUndefined()) { + newTarget = constructor; + } + + // Let numberFormat be ? OrdinaryCreateFromConstructor(newTarget, "%NumberFormatPrototype%", + // « [[InitializedNumberFormat]], [[Locale]], [[DataLocale]], [[NumberingSystem]], [[Style]], [[Unit]], + // [[UnitDisplay]], [[Currency]], [[CurrencyDisplay]], [[CurrencySign]], [[MinimumIntegerDigits]], + // [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], + // [[RoundingType]], [[Notation]], [[CompactDisplay]], [[UseGrouping]], [[SignDisplay]], [[BoundFormat]] »). + JSHandle numberFormat = + JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(constructor), newTarget)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 3. Perform ? InitializeNumberFormat(numberFormat, locales, options). + JSHandle locales = GetCallArg(argv, 0); + JSHandle options = GetCallArg(argv, 1); + JSNumberFormat::InitializeNumberFormat(thread, numberFormat, locales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 4. Let this be the this value. + JSHandle thisValue = GetThis(argv); + + // 5. If NewTarget is undefined and Type(this) is Object and ? InstanceofOperator(this, %NumberFormat%) is true, + // then + // a. Perform ? DefinePropertyOrThrow(this, %Intl%.[[FallbackSymbol]], PropertyDescriptor{ + // [[Value]]: numberFormat, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }). + // b. Return this. + bool isInstanceOf = JSObject::InstanceOf(thread, thisValue, env->GetNumberFormatFunction()); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (newTarget->IsUndefined() && thisValue->IsJSObject() && isInstanceOf) { + PropertyDescriptor descriptor(thread, JSHandle::Cast(numberFormat), false, false, false); + JSHandle key(thread, JSHandle::Cast(env->GetIntlFunction())->GetFallbackSymbol()); + JSTaggedValue::DefinePropertyOrThrow(thread, thisValue, key, descriptor); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return thisValue.GetTaggedValue(); + } + + // 6. Return numberFormat. + return numberFormat.GetTaggedValue(); +} + +// 13.3.2 Intl.NumberFormat.supportedLocalesOf ( locales [ , options ] ) +JSTaggedValue BuiltinsNumberFormat::SupportedLocalesOf(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let availableLocales be %NumberFormat%.[[AvailableLocales]]. + JSHandle availableLocales = JSNumberFormat::GetAvailableLocales(thread); + + // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle locales = GetCallArg(argv, 0); + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). + JSHandle options = GetCallArg(argv, 1); + JSHandle result = JSLocale::SupportedLocales(thread, availableLocales, requestedLocales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +// 13.4.3 get Intl.NumberFormat.prototype.format +JSTaggedValue BuiltinsNumberFormat::Format(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1. Let nf be this value. + JSHandle thisValue = GetThis(argv); + // 2. If Type(nf) is not Object, throw a TypeError exception. + if (!thisValue->IsJSObject()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "nf is not object", JSTaggedValue::Exception()); + } + // 3. Let nf be ? UnwrapNumberFormat(nf). + JSHandle nf = JSNumberFormat::UnwrapNumberFormat(thread, thisValue); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (nf->IsUndefined()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "nf is not object", JSTaggedValue::Exception()); + } + + JSHandle typpedNf = JSHandle::Cast(nf); + JSHandle boundFunc(thread, typpedNf->GetBoundFormat()); + // 4. If nf.[[BoundFormat]] is undefined, then + // a. Let F be a new built-in function object as defined in Number Format Functions (12.1.4). + // b. Set F.[[NumberFormat]] to nf. + // c. Set nf.[[BoundFormat]] to F. + if (boundFunc->IsUndefined()) { + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle intlBoundFunc = factory->NewJSIntlBoundFunction( + reinterpret_cast(BuiltinsNumberFormat::NumberFormatInternalFormatNumber)); + intlBoundFunc->SetNumberFormat(thread, typpedNf); + typpedNf->SetBoundFormat(thread, intlBoundFunc); + } + return typpedNf->GetBoundFormat(); +} + +// 13.4.4 Intl.NumberFormat.prototype.formatToParts ( date ) +JSTaggedValue BuiltinsNumberFormat::FormatToParts(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let nf be the this value. + JSHandle nf = GetThis(argv); + // 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). + if (!nf->IsJSNumberFormat()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "", JSTaggedValue::Exception()); + } + // 3. Let x be ? ToNumeric(value). + JSHandle value = GetCallArg(argv, 0); + JSTaggedNumber x = JSTaggedValue::ToNumber(thread, value); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + JSHandle result = JSNumberFormat::FormatNumericToParts(thread, JSHandle::Cast(nf), x); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + return result.GetTaggedValue(); +} +// 13.4.5 Intl.NumberFormat.prototype.resolvedOptions () +JSTaggedValue BuiltinsNumberFormat::ResolvedOptions(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + // 1. Let nf be this value. + JSHandle thisValue = GetThis(argv); + // 2. If Type(nf) is not Object, throw a TypeError exception. + if (!thisValue->IsJSObject()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not object", JSTaggedValue::Exception()); + } + // 3. Let nf be ? UnwrapNumberFormat(nf). + JSHandle nf = JSNumberFormat::UnwrapNumberFormat(thread, thisValue); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + // 4. Let options be ! ObjectCreate(%ObjectPrototype%). + auto ecmaVm = thread->GetEcmaVM(); + JSHandle env = ecmaVm->GetGlobalEnv(); + ObjectFactory *factory = ecmaVm->GetFactory(); + JSHandle ctor = env->GetObjectFunction(); + JSHandle options(factory->NewJSObjectByConstructor(JSHandle(ctor), ctor)); + + // 5. For each row of Table 5, except the header row, in table order, do + // Let p be the Property value of the current row. + // Let v be the value of nf's internal slot whose name is the Internal Slot value of the current row. + // If v is not undefined, then + // Perform ! CreateDataPropertyOrThrow(options, p, v). + JSNumberFormat::ResolvedOptions(thread, JSHandle::Cast(nf), options); + return options.GetTaggedValue(); +} + +JSTaggedValue BuiltinsNumberFormat::NumberFormatInternalFormatNumber(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + JSHandle intlBoundFunc = JSHandle::Cast(GetConstructor(argv)); + + // 1. Let nf be F.[[NumberFormat]]. + JSHandle nf(thread, intlBoundFunc->GetNumberFormat()); + // 2. Assert: Type(nf) is Object and nf has an [[InitializedNumberFormat]] internal slot. + ASSERT(nf->IsJSObject() && nf->IsJSNumberFormat()); + // 3. If value is not provided, let value be undefined. + JSHandle value = GetCallArg(argv, 0); + // 4 Let x be ? ToNumeric(value). + JSTaggedNumber x = JSTaggedValue::ToNumber(thread, value); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + // 5 Return ? FormatNumeric(nf, x). + JSHandle result = JSNumberFormat::FormatNumeric(thread, JSHandle::Cast(nf), x); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} +} // namespace panda::ecmascript::builtins \ No newline at end of file diff --git a/ecmascript/js_float32_array.h b/ecmascript/builtins/builtins_number_format.h similarity index 35% rename from ecmascript/js_float32_array.h rename to ecmascript/builtins/builtins_number_format.h index ff44b0b785ec554f8da6c498201ab46ea1cf8da2..f61eaa5e754c3fae9b22fd130aa666c3605d75ec 100644 --- a/ecmascript/js_float32_array.h +++ b/ecmascript/builtins/builtins_number_format.h @@ -1,46 +1,42 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_FLOAT32_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_FLOAT32_ARRAY_H - -#include -#include "ecmascript/js_object.h" -#include "ecmascript/js_tagged_value-inl.h" -#include "ecmascript/js_tagged_value.h" - -namespace panda::ecmascript { -class JSFloat32Array : public JSObject { -public: - static JSFloat32Array *Cast(ObjectHeader *object) - { - ASSERT(JSTaggedValue(object).IsJSFloat32Array()); - return static_cast(object); - } - - static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE; - ACCESSORS(ViewedArrayBuffer, VIEWED_ARRAY_BUFFER_OFFSET, TYPED_ARRAY_NAME_OFFSET) - ACCESSORS(TypedArrayName, TYPED_ARRAY_NAME_OFFSET, BYTE_LENGTH_OFFSET) - ACCESSORS(ByteLength, BYTE_LENGTH_OFFSET, BYTE_OFFSET_OFFSET) - ACCESSORS(ByteOffset, BYTE_OFFSET_OFFSET, ARRAY_LENGTH_OFFSET) - ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, SIZE) - - DECL_DUMP() - - DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE) -}; // namespace panda::ecmascript -} // namespace panda::ecmascript - -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_FLOAT32_ARRAY_H +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_NUMBER_FORMAT_H +#define ECMASCRIPT_BUILTINS_BUILTINS_NUMBER_FORMAT_H + +#include "ecmascript/base/builtins_base.h" + +namespace panda::ecmascript::builtins { +class BuiltinsNumberFormat : public base::BuiltinsBase { +public: + // 13.2.1 Intl.DateTimeFormat ( [ locales [ , options ] ] ) + static JSTaggedValue NumberFormatConstructor(EcmaRuntimeCallInfo *argv); + + // 13.3.2 Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] ) + static JSTaggedValue SupportedLocalesOf(EcmaRuntimeCallInfo *argv); + + // 13.4.3 get Intl.DateTimeFormat.prototype.format + static JSTaggedValue Format(EcmaRuntimeCallInfo *argv); + + // 13.4.4 Intl.DateTimeFormat.prototype.formatToParts ( date ) + static JSTaggedValue FormatToParts(EcmaRuntimeCallInfo *argv); + + // 13.4.5 Intl.DateTimeFormat.prototype.resolvedOptions () + static JSTaggedValue ResolvedOptions(EcmaRuntimeCallInfo *argv); + + static JSTaggedValue NumberFormatInternalFormatNumber(EcmaRuntimeCallInfo *argv); +}; +} // namespace panda::ecmascript::builtins +#endif // ECMASCRIPT_BUILTINS_BUILTINS_NUMBER_FORMAT_H \ No newline at end of file diff --git a/ecmascript/builtins/builtins_object.cpp b/ecmascript/builtins/builtins_object.cpp index c967b68fbd76edc7e3233d847b5d30f6290b22a5..df920725d80c13c3b85c7f1a1b80d0ec43da604a 100644 --- a/ecmascript/builtins/builtins_object.cpp +++ b/ecmascript/builtins/builtins_object.cpp @@ -16,6 +16,7 @@ #include "ecmascript/builtins/builtins_object.h" #include "ecmascript/ecma_macros.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/fast_runtime_stub-inl.h" #include "ecmascript/js_array.h" #include "ecmascript/js_function.h" @@ -25,7 +26,7 @@ #include "ecmascript/object_factory.h" namespace panda::ecmascript::builtins { -// 19.1.1.1Object ( [ value ] ) +// 19.1.1.1 Object ( [ value ] ) JSTaggedValue BuiltinsObject::ObjectConstructor(EcmaRuntimeCallInfo *argv) { ASSERT(argv); @@ -56,7 +57,7 @@ JSTaggedValue BuiltinsObject::ObjectConstructor(EcmaRuntimeCallInfo *argv) return JSTaggedValue::ToObject(thread, value).GetTaggedValue(); } -// 19.1.2.1Object.assign ( target, ...sources ) +// 19.1.2.1 Object.assign ( target, ...sources ) JSTaggedValue BuiltinsObject::Assign(EcmaRuntimeCallInfo *argv) { ASSERT(argv); @@ -98,8 +99,8 @@ JSTaggedValue BuiltinsObject::Assign(EcmaRuntimeCallInfo *argv) // 2.ReturnIfAbrupt(propValue). // 3.Let status be Set(to, nextKey, propValue, true). // 4.ReturnIfAbrupt(status). - array_size_t keys_len = keys->GetLength(); - for (array_size_t j = 0; j < keys_len; j++) { + array_size_t keysLen = keys->GetLength(); + for (array_size_t j = 0; j < keysLen; j++) { PropertyDescriptor desc(thread); key.Update(keys->Get(j)); bool success = JSTaggedValue::GetOwnProperty(thread, JSHandle::Cast(from), key, desc); @@ -164,10 +165,10 @@ JSTaggedValue BuiltinsObject::ObjectDefineProperties(JSThread *thread, const JSH // iii.Let desc be ToPropertyDescriptor(descObj). // iv.ReturnIfAbrupt(desc). // v.Append the pair (a two element List) consisting of nextKey and desc to the end of descriptors. + JSMutableHandle handleKey(thread, JSTaggedValue::Undefined()); for (array_size_t i = 0; i < length; i++) { PropertyDescriptor propDesc(thread); - - JSHandle handleKey(thread, handleKeys->Get(i)); + handleKey.Update(handleKeys->Get(i)); bool success = JSTaggedValue::GetOwnProperty(thread, JSHandle::Cast(props), handleKey, propDesc); // ReturnIfAbrupt(propDesc) @@ -201,7 +202,7 @@ JSTaggedValue BuiltinsObject::ObjectDefineProperties(JSThread *thread, const JSH return obj.GetTaggedValue(); } -// 19.1.2.2Object.create ( O [ , Properties ] ) +// 19.1.2.2 Object.create ( O [ , Properties ] ) JSTaggedValue BuiltinsObject::Create(EcmaRuntimeCallInfo *argv) { ASSERT(argv); @@ -230,7 +231,7 @@ JSTaggedValue BuiltinsObject::Create(EcmaRuntimeCallInfo *argv) return objCreate.GetTaggedValue(); } -// 19.1.2.3Object.defineProperties ( O, Properties ) +// 19.1.2.3 Object.defineProperties ( O, Properties ) JSTaggedValue BuiltinsObject::DefineProperties(EcmaRuntimeCallInfo *argv) { ASSERT(argv); @@ -241,7 +242,7 @@ JSTaggedValue BuiltinsObject::DefineProperties(EcmaRuntimeCallInfo *argv) return ObjectDefineProperties(thread, GetCallArg(argv, 0), GetCallArg(argv, 1)); } -// 19.1.2.4Object.defineProperty ( O, P, Attributes ) +// 19.1.2.4 Object.defineProperty ( O, P, Attributes ) JSTaggedValue BuiltinsObject::DefineProperty(EcmaRuntimeCallInfo *argv) { ASSERT(argv); @@ -278,7 +279,7 @@ JSTaggedValue BuiltinsObject::DefineProperty(EcmaRuntimeCallInfo *argv) return obj.GetTaggedValue(); } -// 19.1.2.5Object.freeze ( O ) +// 19.1.2.5 Object.freeze ( O ) JSTaggedValue BuiltinsObject::Freeze(EcmaRuntimeCallInfo *argv) { ASSERT(argv); @@ -743,7 +744,11 @@ JSTaggedValue BuiltinsObject::ToLocaleString(EcmaRuntimeCallInfo *argv) // 2. Return Invoke(O, "toString"). JSHandle calleeKey = thread->GlobalConstants()->GetHandledToStringString(); - return JSFunction::Invoke(thread, object, calleeKey, BuiltinsBase::GetArgsArray(argv)); + + JSHandle argsList = GetArgsArray(argv); + ecmascript::InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgList(*argsList); + return JSFunction::Invoke(thread, object, calleeKey, argsList->GetLength(), arguments->GetArgv()); } JSTaggedValue BuiltinsObject::GetBuiltinTag(JSThread *thread, const JSHandle &object) @@ -754,32 +759,33 @@ JSTaggedValue BuiltinsObject::GetBuiltinTag(JSThread *thread, const JSHandle builtinTag = thread->GetEcmaVM()->GetFactory()->NewFromString("Object"); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle builtinTag = factory->NewFromCanBeCompressString("Object"); // 6. If isArray is true, let builtinTag be "Array". if (isArray) { - builtinTag = thread->GetEcmaVM()->GetFactory()->NewFromString("Array"); + builtinTag = factory->NewFromCanBeCompressString("Array"); } else if (object->IsJSPrimitiveRef()) { // 7. Else, if O is an exotic String object, let builtinTag be "String". JSPrimitiveRef *primitiveRef = JSPrimitiveRef::Cast(*object); if (primitiveRef->IsString()) { - builtinTag = thread->GetEcmaVM()->GetFactory()->NewFromString("String"); + builtinTag = factory->NewFromCanBeCompressString("String"); } else if (primitiveRef->IsBoolean()) { // 11. Else, if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean". - builtinTag = thread->GetEcmaVM()->GetFactory()->NewFromString("Boolean"); + builtinTag = factory->NewFromCanBeCompressString("Boolean"); } else if (primitiveRef->IsNumber()) { // 12. Else, if O has a [[NumberData]] internal slot, let builtinTag be "Number". - builtinTag = thread->GetEcmaVM()->GetFactory()->NewFromString("Number"); + builtinTag = factory->NewFromCanBeCompressString("Number"); } } else if (object->IsArguments()) { - builtinTag = thread->GetEcmaVM()->GetFactory()->NewFromString("Arguments"); + builtinTag = factory->NewFromCanBeCompressString("Arguments"); } else if (object->IsCallable()) { - builtinTag = thread->GetEcmaVM()->GetFactory()->NewFromString("Function"); + builtinTag = factory->NewFromCanBeCompressString("Function"); } else if (object->IsJSError()) { - builtinTag = thread->GetEcmaVM()->GetFactory()->NewFromString("Error"); + builtinTag = factory->NewFromCanBeCompressString("Error"); } else if (object->IsDate()) { - builtinTag = thread->GetEcmaVM()->GetFactory()->NewFromString("Date"); + builtinTag = factory->NewFromCanBeCompressString("Date"); } else if (object->IsJSRegExp()) { - builtinTag = thread->GetEcmaVM()->GetFactory()->NewFromString("RegExp"); + builtinTag = factory->NewFromCanBeCompressString("RegExp"); } // 15. Else, let builtinTag be "Object". return builtinTag.GetTaggedValue(); @@ -824,8 +830,8 @@ JSTaggedValue BuiltinsObject::ToString(EcmaRuntimeCallInfo *argv) } // 19. Return the String that is the result of concatenating "[object ", tag, and "]". - JSHandle leftString(factory->NewFromString("[object ")); - JSHandle rightString(factory->NewFromString("]")); + JSHandle leftString(factory->NewFromCanBeCompressString("[object ")); + JSHandle rightString(factory->NewFromCanBeCompressString("]")); JSHandle newLeftStringHandle = factory->ConcatFromString(leftString, JSTaggedValue::ToString(thread, tag)); @@ -863,6 +869,7 @@ JSTaggedValue BuiltinsObject::ProtoGetter(EcmaRuntimeCallInfo *argv) // 3.Return obj.[[GetPrototypeOf]](). return obj->GetPrototype(thread); } + JSTaggedValue BuiltinsObject::ProtoSetter(EcmaRuntimeCallInfo *argv) { ASSERT(argv); diff --git a/ecmascript/builtins/builtins_object.h b/ecmascript/builtins/builtins_object.h index 6fa45842a1c6e264da8a223f5e15f10913e934ec..d2ab9a0010f7c8e8140582f91478d05d1eb3f214 100644 --- a/ecmascript/builtins/builtins_object.h +++ b/ecmascript/builtins/builtins_object.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_OBJECT_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_OBJECT_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_OBJECT_H +#define ECMASCRIPT_BUILTINS_BUILTINS_OBJECT_H #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/base/builtins_base.h" @@ -95,4 +95,4 @@ private: static JSTaggedValue GetBuiltinTag(JSThread *thread, const JSHandle &object); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_OBJECT_H diff --git a/ecmascript/builtins/builtins_plural_rules.cpp b/ecmascript/builtins/builtins_plural_rules.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6daa4ea8a8f19708b72540adc4218436e01c21f4 --- /dev/null +++ b/ecmascript/builtins/builtins_plural_rules.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "ecmascript/builtins/builtins_plural_rules.h" + +#include "ecmascript/global_env.h" +#include "ecmascript/js_locale.h" +#include "ecmascript/js_object.h" +#include "ecmascript/js_plural_rules.h" +#include "ecmascript/object_factory.h" + +namespace panda::ecmascript::builtins { +JSTaggedValue BuiltinsPluralRules::PluralRulesConstructor(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + // 1. If NewTarget is undefined, throw a TypeError exception. + JSHandle constructor = GetConstructor(argv); + JSHandle newTarget = GetNewTarget(argv); + if (newTarget->IsUndefined()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "newTarget is undefined", JSTaggedValue::Exception()); + } + + // 2. Let pluralRules be ? OrdinaryCreateFromConstructor(NewTarget, "%PluralRulesPrototype%", + // « [[InitializedPluralRules]], [[Locale]], [[Type]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], + // [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[RoundingType]] »). + JSHandle pluralRules = + JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(constructor), newTarget)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 3. Return ? InitializePluralRules(pluralRules, locales, options). + JSHandle locales = GetCallArg(argv, 0); + JSHandle options = GetCallArg(argv, 1); + JSPluralRules::InitializePluralRules(thread, pluralRules, locales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + return pluralRules.GetTaggedValue(); +} + +JSTaggedValue BuiltinsPluralRules::SupportedLocalesOf(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1. Let availableLocales be %PluralRules%.[[AvailableLocales]]. + JSHandle availableLocales = JSPluralRules::GetAvailableLocales(thread); + + // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle locales = GetCallArg(argv, 0); + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). + JSHandle options = GetCallArg(argv, 1); + JSHandle result = JSLocale::SupportedLocales(thread, availableLocales, requestedLocales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +JSTaggedValue BuiltinsPluralRules::Select(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1. Let pr be the this value. + JSHandle thisValue = GetThis(argv); + + // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]). + if (!thisValue->IsJSPluralRules()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not pr object", JSTaggedValue::Exception()); + } + + // 3. Let n be ? ToNumber(value). + double x = 0.0; + JSHandle value = GetCallArg(argv, 0); + JSTaggedNumber temp = JSTaggedValue::ToNumber(thread, value); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + x = temp.GetNumber(); + + // 4. Return ? ResolvePlural(pr, n). + JSHandle pluralRules = JSHandle::Cast(thisValue); + JSHandle result = JSPluralRules::ResolvePlural(thread, pluralRules, x); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +JSTaggedValue BuiltinsPluralRules::ResolvedOptions(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1. Let thisValue be the this value; + JSHandle thisValue = GetThis(argv); + + // 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]). + if (!thisValue->IsJSPluralRules()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not pr object", JSTaggedValue::Exception()); + } + + // 3. Let options be ! ObjectCreate(%ObjectPrototype%). + auto ecmaVm = thread->GetEcmaVM(); + JSHandle env = ecmaVm->GetGlobalEnv(); + ObjectFactory *factory = ecmaVm->GetFactory(); + JSHandle ctor = env->GetObjectFunction(); + JSHandle options(factory->NewJSObjectByConstructor(JSHandle(ctor), ctor)); + + // 4. Perform resolvedOptions + JSHandle pluralRules = JSHandle::Cast(thisValue); + JSPluralRules::ResolvedOptions(thread, pluralRules, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 5. Return options. + return options.GetTaggedValue(); +} +} // namespace panda::ecmascript::builtins \ No newline at end of file diff --git a/ecmascript/builtins/builtins_plural_rules.h b/ecmascript/builtins/builtins_plural_rules.h new file mode 100644 index 0000000000000000000000000000000000000000..d3481a247cb175ec9025e8a7c661043e71ac1fa8 --- /dev/null +++ b/ecmascript/builtins/builtins_plural_rules.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_PLURAL_RULES_H +#define ECMASCRIPT_BUILTINS_BUILTINS_PLURAL_RULES_H + +#include "ecmascript/base/builtins_base.h" + +namespace panda::ecmascript::builtins { +class BuiltinsPluralRules : public base::BuiltinsBase { +public: + // 15.2.1 Intl.PluralRules ( [ locales [ , options ] ] ) + static JSTaggedValue PluralRulesConstructor(EcmaRuntimeCallInfo *argv); + + // 15.3.2 Intl.PluralRules.supportedLocalesOf ( locales [, options ] ) + static JSTaggedValue SupportedLocalesOf(EcmaRuntimeCallInfo *argv); + + // 15.4.3 Intl.PluralRules.prototype.select( value ) + static JSTaggedValue Select(EcmaRuntimeCallInfo *argv); + + // 15.4.4 Intl.PluralRules.prototype.resolvedOptions () + static JSTaggedValue ResolvedOptions(EcmaRuntimeCallInfo *argv); +}; +} // namespace panda::ecmascript::builtins +#endif // ECMASCRIPT_BUILTINS_BUILTINS_PLURAL_RULES_H \ No newline at end of file diff --git a/ecmascript/builtins/builtins_promise.cpp b/ecmascript/builtins/builtins_promise.cpp index ae2f4dba6c9549a7cb26baff008eb0cd1a95a6f8..a2536c22c5a9f59a59bd40fb96eb0039e385a2ee 100644 --- a/ecmascript/builtins/builtins_promise.cpp +++ b/ecmascript/builtins/builtins_promise.cpp @@ -19,6 +19,7 @@ #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/jobs/micro_job_queue.h" #include "ecmascript/js_array.h" #include "ecmascript/js_function.h" @@ -68,14 +69,12 @@ JSTaggedValue BuiltinsPromise::PromiseConstructor([[maybe_unused]] EcmaRuntimeCa // 8. Let resolvingFunctions be CreateResolvingFunctions(promise). JSHandle resolvingFunction = JSPromise::CreateResolvingFunctions(thread, instancePromise); // 9. Let completion be Call(executor, undefined, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[reject]]) - JSHandle arguments = factory->NewTaggedArray(2); // 2: 2 means two args stored in array - auto result = resolvingFunction->GetResolveFunction(); - arguments->Set(thread, 0, result); - result = resolvingFunction->GetRejectFunction(); - arguments->Set(thread, 1, result); - + auto resolveFunc = resolvingFunction->GetResolveFunction(); + auto rejectFunc = resolvingFunction->GetRejectFunction(); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(resolveFunc, rejectFunc); JSHandle thisValue = globalConst->GetHandledUndefined(); - JSTaggedValue taggedValue = JSFunction::Call(thread, executor, thisValue, arguments); + JSTaggedValue taggedValue = JSFunction::Call(thread, executor, thisValue, 2, arguments->GetArgv()); // 2: two args JSHandle completionValue(thread, taggedValue); // 10. If completion is an abrupt completion, then @@ -84,11 +83,9 @@ JSTaggedValue BuiltinsPromise::PromiseConstructor([[maybe_unused]] EcmaRuntimeCa if (thread->HasPendingException()) { completionValue = JSPromise::IfThrowGetThrowValue(thread); thread->ClearException(); - array_size_t length = 1; - JSHandle arrayCompletion = factory->NewTaggedArray(length); - arrayCompletion->Set(thread, 0, completionValue); JSHandle reject(thread, resolvingFunction->GetRejectFunction()); - JSFunction::Call(thread, reject, thisValue, arrayCompletion); + arguments->MakeArgv(completionValue); + JSFunction::Call(thread, reject, thisValue, 1, arguments->GetArgv()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } @@ -236,9 +233,7 @@ JSTaggedValue BuiltinsPromise::Resolve(EcmaRuntimeCallInfo *argv) JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - auto ecmaVm = thread->GetEcmaVM(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); - ObjectFactory *factory = ecmaVm->GetFactory(); // 1. Let C be the this value. JSHandle thisValue = GetThis(argv); // 2. If Type(C) is not Object, throw a TypeError exception. @@ -266,12 +261,11 @@ JSTaggedValue BuiltinsPromise::Resolve(EcmaRuntimeCallInfo *argv) // 6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined, «x»). // 7. ReturnIfAbrupt(resolveResult). - array_size_t length = 1; - JSHandle arrayCompletion = factory->NewTaggedArray(length); - arrayCompletion->Set(thread, 0, xValue); JSHandle resolve(thread, promiseCapability->GetResolve()); JSHandle undefined = globalConst->GetHandledUndefined(); - JSFunction::Call(thread, resolve, undefined, arrayCompletion); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(xValue); + JSFunction::Call(thread, resolve, undefined, 1, arguments->GetArgv()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 8. Return promiseCapability.[[Promise]]. @@ -286,9 +280,7 @@ JSTaggedValue BuiltinsPromise::Reject(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), Promise, Reject); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - auto ecmaVm = thread->GetEcmaVM(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); - ObjectFactory *factory = ecmaVm->GetFactory(); // 1. Let C be the this value. // 2. If Type(C) is not Object, throw a TypeError exception. @@ -305,12 +297,11 @@ JSTaggedValue BuiltinsPromise::Reject(EcmaRuntimeCallInfo *argv) // 5. Let rejectResult be Call(promiseCapability.[[Reject]], undefined, «r»). // 6. ReturnIfAbrupt(rejectResult). JSHandle reason = GetCallArg(argv, 0); - array_size_t length = 1; - JSHandle arrayCompletion = factory->NewTaggedArray(length); - arrayCompletion->Set(thread, 0, reason); JSHandle reject(thread, promiseCapability->GetReject()); JSHandle undefined = globalConst->GetHandledUndefined(); - JSFunction::Call(thread, reject, undefined, arrayCompletion); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(reason); + JSFunction::Call(thread, reject, undefined, 1, arguments->GetArgv()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 7. Return promiseCapability.[[Promise]]. @@ -334,17 +325,14 @@ JSTaggedValue BuiltinsPromise::Catch(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), Promise, Catch); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - auto ecmaVm = thread->GetEcmaVM(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); - ObjectFactory *factory = ecmaVm->GetFactory(); JSHandle promise = GetThis(argv); JSHandle thenKey = globalConst->GetHandledPromiseThenString(); JSHandle reject = GetCallArg(argv, 0); - array_size_t length = 2; - JSHandle arrayList = factory->NewTaggedArray(length); - arrayList->Set(thread, 0, globalConst->GetHandledUndefined()); - arrayList->Set(thread, 1, reject); - return JSFunction::Invoke(thread, promise, thenKey, arrayList); + + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(globalConst->GetHandledUndefined(), reject); + return JSFunction::Invoke(thread, promise, thenKey, 2, arguments->GetArgv()); // 2: two args } // 25.4.5.3 Promise.prototype.then ( onFulfilled , onRejected ) @@ -485,18 +473,17 @@ JSHandle BuiltinsPromise::PerformPromiseAll(JSThread *thread, JSArray::CreateArrayFromList(thread, JSHandle(thread, values->GetValue())); // 2. Let resolveResult be Call(resultCapability.[[Resolve]], undefined, «valuesArray»). JSHandle resCapaFunc(thread, capa->GetResolve()); - JSHandle argv = factory->NewTaggedArray(1); - argv->Set(thread, 0, jsArrayValues.GetTaggedValue()); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(jsArrayValues.GetTaggedValue()); JSTaggedValue resolveRes = - JSFunction::Call(thread, resCapaFunc, globalConst->GetHandledUndefined(), argv); + JSFunction::Call(thread, resCapaFunc, globalConst->GetHandledUndefined(), 1, arguments->GetArgv()); // 3. ReturnIfAbrupt(resolveResult) JSHandle resolveAbrupt(thread, resolveRes); RETURN_COMPLETION_IF_ABRUPT(thread, resolveAbrupt); } // iv. Return resultCapability.[[Promise]]. JSHandle resRecord = factory->NewCompletionRecord( - CompletionRecord::NORMAL, - JSHandle(thread, capa->GetPromise())); + CompletionRecord::NORMAL, JSHandle(thread, capa->GetPromise())); return resRecord; } // e. Let nextValue be IteratorValue(next). @@ -523,9 +510,9 @@ JSHandle BuiltinsPromise::PerformPromiseAll(JSThread *thread, values->SetValue(thread, valuesArray); // i. Let nextPromise be Invoke(constructor, "resolve", «‍nextValue»). JSHandle resolveKey = globalConst->GetHandledPromiseResolveString(); - JSHandle nextValueArray = factory->NewTaggedArray(1); - nextValueArray->Set(thread, 0, nextVal); - JSTaggedValue taggedNextPromise = JSFunction::Invoke(thread, ctor, resolveKey, nextValueArray); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(nextVal); + JSTaggedValue taggedNextPromise = JSFunction::Invoke(thread, ctor, resolveKey, 1, arguments->GetArgv()); // j. ReturnIfAbrupt(nextPromise). JSHandle nextPromise(thread, taggedNextPromise); RETURN_COMPLETION_IF_ABRUPT(thread, nextPromise); @@ -549,10 +536,10 @@ JSHandle BuiltinsPromise::PerformPromiseAll(JSThread *thread, remainCnt->SetValue(thread, ++JSTaggedNumber(remainCnt->GetValue())); // r. Let result be Invoke(nextPromise, "then", «‍resolveElement, resultCapability.[[Reject]]»). JSHandle thenKey = globalConst->GetHandledPromiseThenString(); - JSHandle arg = factory->NewTaggedArray(2); // 2: 2 means two args stored in array - arg->Set(thread, 0, resoleveElement); - arg->Set(thread, 1, capa->GetReject()); - JSTaggedValue taggedResult = JSFunction::Invoke(thread, nextPromise, thenKey, arg); + arguments->MakeArgv(resoleveElement.GetTaggedValue(), capa->GetReject()); + JSTaggedValue taggedResult = + JSFunction::Invoke(thread, nextPromise, thenKey, 2, arguments->GetArgv()); // 2: two args + JSHandle result(thread, taggedResult); // s. ReturnIfAbrupt(result). RETURN_COMPLETION_IF_ABRUPT(thread, result); @@ -606,10 +593,11 @@ JSHandle BuiltinsPromise::PerformPromiseRace(JSThread *thread, } RETURN_COMPLETION_IF_ABRUPT(thread, nextValue); JSHandle resolveStr = globalConst->GetHandledPromiseResolveString(); - array_size_t length = 1; - JSHandle array = factory->NewTaggedArray(length); - array->Set(thread, 0, nextValue); - JSTaggedValue result = JSFunction::Invoke(thread, constructor, resolveStr, array); + + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(nextValue); + JSTaggedValue result = JSFunction::Invoke(thread, constructor, resolveStr, 1, arguments->GetArgv()); + JSHandle nextPromise(thread, result); if (thread->HasPendingException()) { nextPromise = JSPromise::IfThrowGetThrowValue(thread); @@ -617,11 +605,9 @@ JSHandle BuiltinsPromise::PerformPromiseRace(JSThread *thread, RETURN_COMPLETION_IF_ABRUPT(thread, nextPromise); JSHandle thenStr = globalConst->GetHandledPromiseThenString(); - length = 2; // 2: 2 means two args stored in array - array = factory->NewTaggedArray(length); - array->Set(thread, 0, capability->GetResolve()); - array->Set(thread, 1, capability->GetReject()); - result = JSFunction::Invoke(thread, nextPromise, thenStr, array); + arguments->MakeArgv(capability->GetResolve(), capability->GetReject()); + result = JSFunction::Invoke(thread, nextPromise, thenStr, 2, arguments->GetArgv()); // 2: two args + JSHandle handleResult(thread, result); if (thread->HasPendingException()) { handleResult = JSPromise::IfThrowGetThrowValue(thread); diff --git a/ecmascript/builtins/builtins_promise.h b/ecmascript/builtins/builtins_promise.h index ba68cc8217e7c2d7d6fadc444353486efac3cc84..0fbc9a9cf83be6a4871b546c523b8b8fa07681e7 100644 --- a/ecmascript/builtins/builtins_promise.h +++ b/ecmascript/builtins/builtins_promise.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_PROMISE_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_PROMISE_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_PROMISE_H +#define ECMASCRIPT_BUILTINS_BUILTINS_PROMISE_H #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/base/builtins_base.h" @@ -60,4 +60,4 @@ private: const JSHandle &constructor); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_PROMISE_H \ No newline at end of file +#endif // ECMASCRIPT_BUILTINS_BUILTINS_PROMISE_H \ No newline at end of file diff --git a/ecmascript/builtins/builtins_promise_handler.cpp b/ecmascript/builtins/builtins_promise_handler.cpp index 83728d933ae4c24ea65d7de1f48a962e71c7f275..4dcf9e188b2d3aae1040c91da32b7d535b5e1af9 100644 --- a/ecmascript/builtins/builtins_promise_handler.cpp +++ b/ecmascript/builtins/builtins_promise_handler.cpp @@ -14,7 +14,9 @@ */ #include "ecmascript/builtins/builtins_promise_handler.h" + #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/jobs/micro_job_queue.h" #include "ecmascript/js_array.h" #include "ecmascript/js_async_function.h" @@ -171,7 +173,6 @@ JSTaggedValue BuiltinsPromiseHandler::ResolveElementFunction(EcmaRuntimeCallInfo JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle func = JSHandle::Cast(GetConstructor(argv)); // 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot. @@ -206,9 +207,9 @@ JSTaggedValue BuiltinsPromiseHandler::ResolveElementFunction(EcmaRuntimeCallInfo // b. Return Call(promiseCapability.[[Resolve]], undefined, «valuesArray»). JSHandle capaResolve(thread, capa->GetResolve()); JSHandle undefine = globalConst->GetHandledUndefined(); - JSHandle arg = factory->NewTaggedArray(1); - arg->Set(thread, 0, jsArrayValues); - return JSFunction::Call(thread, capaResolve, undefine, arg); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(jsArrayValues); + return JSFunction::Call(thread, capaResolve, undefine, 1, arguments->GetArgv()); } // 11. Return undefined. return JSTaggedValue::Undefined(); diff --git a/ecmascript/builtins/builtins_promise_handler.h b/ecmascript/builtins/builtins_promise_handler.h index fc17372ac3db1490379d2afb63145d4821c8f307..dabab82f93a3fcd78ada8bcf31a50383b3880284 100644 --- a/ecmascript/builtins/builtins_promise_handler.h +++ b/ecmascript/builtins/builtins_promise_handler.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_PROMISE_HANDLER_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_PROMISE_HANDLER_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_PROMISE_HANDLER_H +#define ECMASCRIPT_BUILTINS_BUILTINS_PROMISE_HANDLER_H #include "ecmascript/base/builtins_base.h" @@ -41,4 +41,4 @@ public: }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_PROMISE_HANDLER_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_PROMISE_HANDLER_H diff --git a/ecmascript/builtins/builtins_promise_job.cpp b/ecmascript/builtins/builtins_promise_job.cpp index 114f41ff42e5ebacbee36e903e2b31167de7d22b..936bf031aa4f0a1622a7cdb2f29da365bfaf96b7 100644 --- a/ecmascript/builtins/builtins_promise_job.cpp +++ b/ecmascript/builtins/builtins_promise_job.cpp @@ -16,6 +16,7 @@ #include "ecmascript/builtins/builtins_promise_job.h" #include "ecmascript/ecma_macros.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_function.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_promise.h" @@ -29,8 +30,6 @@ JSTaggedValue BuiltinsPromiseJob::PromiseReactionJob(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), PromiseJob, Reaction); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - auto ecmaVm = thread->GetEcmaVM(); - ObjectFactory *factory = ecmaVm->GetFactory(); // 1. Assert: reaction is a PromiseReaction Record. JSHandle value = GetCallArg(argv, 0); ASSERT(value->IsPromiseReaction()); @@ -44,34 +43,33 @@ JSTaggedValue BuiltinsPromiseJob::PromiseReactionJob(EcmaRuntimeCallInfo *argv) JSHandle handler(thread, reaction->GetHandler()); JSHandle thisValue = globalConst->GetHandledUndefined(); JSMutableHandle call(thread, capability->GetResolve()); - JSHandle result = factory->NewTaggedArray(1); + InternalCallParams *result = thread->GetInternalCallParams(); + result->MakeArgv(argument); if (handler->IsString()) { // 4. If handler is "Identity", let handlerResult be NormalCompletion(argument). // 5. Else if handler is "Thrower", let handlerResult be Completion{[[type]]: throw, [[value]]: argument, // [[target]]: empty}. - result->Set(thread, 0, argument); + if (EcmaString::StringsAreEqual(handler.GetObject(), globalConst->GetHandledThrowerString().GetObject())) { call.Update(capability->GetReject()); } } else { // 6. Else, let handlerResult be Call(handler, undefined, «argument»). - JSHandle arguments = factory->NewTaggedArray(1); - arguments->Set(thread, 0, argument); - JSTaggedValue taggedValue = JSFunction::Call(thread, handler, thisValue, arguments); - result->Set(thread, 0, taggedValue); + JSTaggedValue taggedValue = JSFunction::Call(thread, handler, thisValue, 1, result->GetArgv()); + result->MakeArgv(taggedValue); // 7. If handlerResult is an abrupt completion, then // a. Let status be Call(promiseCapability.[[Reject]], undefined, «handlerResult.[[value]]»). // b. NextJob Completion(status). if (thread->HasPendingException()) { JSHandle throwValue = JSPromise::IfThrowGetThrowValue(thread); thread->ClearException(); - result->Set(thread, 0, throwValue); + result->MakeArgv(throwValue); call.Update(capability->GetReject()); } } // 8. Let status be Call(promiseCapability.[[Resolve]], undefined, «handlerResult.[[value]]»). - return JSFunction::Call(thread, call, thisValue, result); + return JSFunction::Call(thread, call, thisValue, 1, result->GetArgv()); } JSTaggedValue BuiltinsPromiseJob::PromiseResolveThenableJob(EcmaRuntimeCallInfo *argv) @@ -80,8 +78,6 @@ JSTaggedValue BuiltinsPromiseJob::PromiseResolveThenableJob(EcmaRuntimeCallInfo BUILTINS_API_TRACE(argv->GetThread(), PromiseJob, ResolveThenableJob); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - auto ecmaVm = thread->GetEcmaVM(); - ObjectFactory *factory = ecmaVm->GetFactory(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); JSHandle promise = GetCallArg(argv, 0); ASSERT(promise->IsJSPromise()); @@ -92,10 +88,9 @@ JSTaggedValue BuiltinsPromiseJob::PromiseResolveThenableJob(EcmaRuntimeCallInfo JSHandle then = GetCallArg(argv, BuiltinsBase::ArgsPosition::THIRD); // 2. Let thenCallResult be Call(then, thenable, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»). - JSHandle array = factory->NewTaggedArray(2); - array->Set(thread, 0, resolvingFunctions->GetResolveFunction()); - array->Set(thread, 1, resolvingFunctions->GetRejectFunction()); - JSTaggedValue result = JSFunction::Call(thread, then, thenable, array); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(resolvingFunctions->GetResolveFunction(), resolvingFunctions->GetRejectFunction()); + JSTaggedValue result = JSFunction::Call(thread, then, thenable, 2, arguments->GetArgv()); // 2: two args JSHandle thenResult(thread, result); // 3. If thenCallResult is an abrupt completion, // a. Let status be Call(resolvingFunctions.[[Reject]], undefined, «thenCallResult.[[value]]»). @@ -104,10 +99,9 @@ JSTaggedValue BuiltinsPromiseJob::PromiseResolveThenableJob(EcmaRuntimeCallInfo thenResult = JSPromise::IfThrowGetThrowValue(thread); thread->ClearException(); JSHandle reject(thread, resolvingFunctions->GetRejectFunction()); - JSHandle argument = factory->NewTaggedArray(1); JSHandle undefined = globalConst->GetHandledUndefined(); - argument->Set(thread, 0, thenResult); - return JSFunction::Call(thread, reject, undefined, argument); + arguments->MakeArgv(thenResult); + return JSFunction::Call(thread, reject, undefined, 1, arguments->GetArgv()); } // 4. NextJob Completion(thenCallResult). return result; diff --git a/ecmascript/builtins/builtins_promise_job.h b/ecmascript/builtins/builtins_promise_job.h index 51f035e6ab4f3f483713074071c1663e4b51fb28..d602b510338c18230211699887678a51be543be5 100644 --- a/ecmascript/builtins/builtins_promise_job.h +++ b/ecmascript/builtins/builtins_promise_job.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_PROMISE_JOB_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_PROMISE_JOB_H +#ifndef ECMASCRIPT_JS_PROMISE_JOB_H +#define ECMASCRIPT_JS_PROMISE_JOB_H #include "ecmascript/base/builtins_base.h" @@ -25,4 +25,4 @@ public: static JSTaggedValue PromiseResolveThenableJob(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_PROMISE_JOB_H +#endif // ECMASCRIPT_JS_PROMISE_JOB_H diff --git a/ecmascript/builtins/builtins_proxy.h b/ecmascript/builtins/builtins_proxy.h index 8b07160142c2986b93171e58e1c563eef4b50365..cb059df60c24a0fb753e0af670e9bdbd552ef3cb 100644 --- a/ecmascript/builtins/builtins_proxy.h +++ b/ecmascript/builtins/builtins_proxy.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_PROXY_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_PROXY_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_PROXY_H +#define ECMASCRIPT_BUILTINS_BUILTINS_PROXY_H #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/base/builtins_base.h" @@ -34,4 +34,4 @@ public: static JSTaggedValue InvalidateProxyFunction(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_PROXYH diff --git a/ecmascript/builtins/builtins_reflect.cpp b/ecmascript/builtins/builtins_reflect.cpp index 1b3a981e5f025748c17b9637e298617ecb93fc9b..3e94d5d56dd7bb47cd769a1ed4ce9eb406ae6690 100644 --- a/ecmascript/builtins/builtins_reflect.cpp +++ b/ecmascript/builtins/builtins_reflect.cpp @@ -14,6 +14,7 @@ */ #include "ecmascript/builtins/builtins_reflect.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_tagged_value-inl.h" namespace panda::ecmascript::builtins { @@ -38,7 +39,9 @@ JSTaggedValue BuiltinsReflect::ReflectApply(EcmaRuntimeCallInfo *argv) // 3. Perform PrepareForTailCall(). // 4. Return ? Call(target, thisArgument, args). - return JSFunction::Call(thread, target, thisArgument, args); + ecmascript::InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgList(*args); + return JSFunction::Call(thread, target, thisArgument, args->GetLength(), arguments->GetArgv()); } // ecma 26.1.2 Reflect.construct (target, argumentsList [ , newTarget]) @@ -67,7 +70,9 @@ JSTaggedValue BuiltinsReflect::ReflectConstruct(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); JSHandle args = JSHandle::Cast(argOrAbrupt); // 5. Return ? Construct(target, args, newTarget). - return JSFunction::Construct(thread, target, args, newTarget); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgList(*args); + return JSFunction::Construct(thread, target, args->GetLength(), arguments->GetArgv(), newTarget); } // ecma 26.1.3 Reflect.defineProperty (target, propertyKey, attributes) diff --git a/ecmascript/builtins/builtins_reflect.h b/ecmascript/builtins/builtins_reflect.h index dddcb8d91945142df56abb4c26864e272c9836a0..9c2e926c5883a5bbc06946a3782aa5c3ccd326f6 100644 --- a/ecmascript/builtins/builtins_reflect.h +++ b/ecmascript/builtins/builtins_reflect.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_REFLECT_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_REFLECT_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_REFLECT_H +#define ECMASCRIPT_BUILTINS_BUILTINS_REFLECT_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/js_function.h" @@ -63,4 +63,4 @@ public: static JSTaggedValue ReflectSetPrototypeOf(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_REFLECT_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_REFLECT_H diff --git a/ecmascript/builtins/builtins_regexp.cpp b/ecmascript/builtins/builtins_regexp.cpp index d4b1d4b13f42c858616fe3eb08c297663b32b98c..dc994270fbdbdfe4cbab90b11b961cb51b5629bc 100644 --- a/ecmascript/builtins/builtins_regexp.cpp +++ b/ecmascript/builtins/builtins_regexp.cpp @@ -18,6 +18,7 @@ #include "ecmascript/ecma_string-inl.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_array.h" #include "ecmascript/js_function.h" #include "ecmascript/js_hclass.h" @@ -95,8 +96,8 @@ JSTaggedValue BuiltinsRegExp::RegExpConstructor(EcmaRuntimeCallInfo *argv) } // 6. Else if patternIsRegExp is true } else if (patternIsRegExp) { - JSHandle sourceString(factory->NewFromString("source")); - JSHandle flagsString(factory->NewFromString("flags")); + JSHandle sourceString(factory->NewFromCanBeCompressString("source")); + JSHandle flagsString(factory->NewFromCanBeCompressString("flags")); // disable gc [[maybe_unused]] DisallowGarbageCollection noGc; // 6.a Let P be Get(pattern, "source"). @@ -203,8 +204,8 @@ JSTaggedValue BuiltinsRegExp::ToString(EcmaRuntimeCallInfo *argv) THROW_TYPE_ERROR_AND_RETURN(thread, "this is not Object", JSTaggedValue::Exception()); } ObjectFactory *factory = ecmaVm->GetFactory(); - JSHandle sourceString(factory->NewFromString("source")); - JSHandle flagsString(factory->NewFromString("flags")); + JSHandle sourceString(factory->NewFromCanBeCompressString("source")); + JSHandle flagsString(factory->NewFromCanBeCompressString("flags")); // 3. Let pattern be ToString(Get(R, "source")). JSHandle getSource(JSObject::GetProperty(thread, thisObj, sourceString).GetValue()); JSHandle getFlags(JSObject::GetProperty(thread, thisObj, flagsString).GetValue()); @@ -215,7 +216,7 @@ JSTaggedValue BuiltinsRegExp::ToString(EcmaRuntimeCallInfo *argv) JSHandle flagsStrHandle = JSTaggedValue::ToString(thread, getFlags); // 4. ReturnIfAbrupt(flags). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSHandle slashStr = factory->NewFromString("/"); + JSHandle slashStr = factory->NewFromCanBeCompressString("/"); // 7. Let result be the String value formed by concatenating "/", pattern, and "/", and flags. JSHandle tempStr = factory->ConcatFromString(slashStr, sourceStrHandle); JSHandle resultTemp = factory->ConcatFromString(tempStr, slashStr); @@ -256,7 +257,7 @@ JSTaggedValue BuiltinsRegExp::GetGlobal(EcmaRuntimeCallInfo *argv) [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle thisObj = GetThis(argv); - JSHandle gString = thread->GetEcmaVM()->GetFactory()->NewFromString("g"); + JSHandle gString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("g"); bool result = GetFlagsInternal(thread, thisObj, gString); return GetTaggedBoolean(result); } @@ -268,7 +269,7 @@ JSTaggedValue BuiltinsRegExp::GetIgnoreCase(EcmaRuntimeCallInfo *argv) JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle thisObj = GetThis(argv); - JSHandle iString = thread->GetEcmaVM()->GetFactory()->NewFromString("i"); + JSHandle iString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("i"); bool result = GetFlagsInternal(thread, thisObj, iString); return GetTaggedBoolean(result); } @@ -280,7 +281,7 @@ JSTaggedValue BuiltinsRegExp::GetMultiline(EcmaRuntimeCallInfo *argv) JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle thisObj = GetThis(argv); - JSHandle mString = thread->GetEcmaVM()->GetFactory()->NewFromString("m"); + JSHandle mString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("m"); bool result = GetFlagsInternal(thread, thisObj, mString); return GetTaggedBoolean(result); } @@ -291,7 +292,7 @@ JSTaggedValue BuiltinsRegExp::GetDotAll(EcmaRuntimeCallInfo *argv) JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle thisObj = GetThis(argv); - JSHandle sString = thread->GetEcmaVM()->GetFactory()->NewFromString("s"); + JSHandle sString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("s"); bool result = GetFlagsInternal(thread, thisObj, sString); return GetTaggedBoolean(result); } @@ -331,7 +332,7 @@ JSTaggedValue BuiltinsRegExp::GetSticky(EcmaRuntimeCallInfo *argv) JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle thisObj = GetThis(argv); - JSHandle yString = thread->GetEcmaVM()->GetFactory()->NewFromString("y"); + JSHandle yString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("y"); bool result = GetFlagsInternal(thread, thisObj, yString); return GetTaggedBoolean(result); } @@ -343,7 +344,7 @@ JSTaggedValue BuiltinsRegExp::GetUnicode(EcmaRuntimeCallInfo *argv) JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle thisObj = GetThis(argv); - JSHandle uString = thread->GetEcmaVM()->GetFactory()->NewFromString("u"); + JSHandle uString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("u"); bool result = GetFlagsInternal(thread, thisObj, uString); return GetTaggedBoolean(result); } @@ -376,7 +377,7 @@ JSTaggedValue BuiltinsRegExp::Match(EcmaRuntimeCallInfo *argv) } // 5. Let global be ToBoolean(Get(rx, "global")). ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle global(factory->NewFromString("global")); + JSHandle global(factory->NewFromCanBeCompressString("global")); auto globalValue = JSObject::GetProperty(thread, thisObj, global).GetValue(); // 6. ReturnIfAbrupt(global). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -389,7 +390,7 @@ JSTaggedValue BuiltinsRegExp::Match(EcmaRuntimeCallInfo *argv) } // 8. Else global is true // a. Let fullUnicode be ToBoolean(Get(rx, "unicode")). - JSHandle unicode(factory->NewFromString("unicode")); + JSHandle unicode(factory->NewFromCanBeCompressString("unicode")); JSHandle unicodeHandle = JSObject::GetProperty(thread, thisObj, unicode).GetValue(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); bool fullUnicode = unicodeHandle->ToBoolean(); @@ -423,7 +424,7 @@ JSTaggedValue BuiltinsRegExp::Match(EcmaRuntimeCallInfo *argv) } // iv. Else result is not null, // 1. Let matchStr be ToString(Get(result, "0")). - JSHandle zoreString(factory->NewFromString("0")); + JSHandle zoreString(factory->NewFromCanBeCompressString("0")); JSHandle matchStr(JSObject::GetProperty(thread, result, zoreString).GetValue()); JSHandle matchString = JSTaggedValue::ToString(thread, matchStr); // 2. ReturnIfAbrupt(matchStr). @@ -585,7 +586,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) JSHandle lastIndex(thread->GlobalConstants()->GetHandledLastIndexString()); // 8. Let global be ToBoolean(Get(rx, "global")). ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle global(factory->NewFromString("global")); + JSHandle global(factory->NewFromCanBeCompressString("global")); auto globalValue = JSObject::GetProperty(thread, thisObj, global).GetValue(); // 9. ReturnIfAbrupt(global). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -594,7 +595,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) bool fullUnicode = false; if (isGlobal) { // a. Let fullUnicode be ToBoolean(Get(rx, "unicode")). - JSHandle unicode(factory->NewFromString("unicode")); + JSHandle unicode(factory->NewFromCanBeCompressString("unicode")); JSHandle fullUnicodeHandle = JSObject::GetProperty(thread, thisObj, unicode).GetValue(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); fullUnicode = fullUnicodeHandle->ToBoolean(); @@ -615,7 +616,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) } } - JSHandle matchedStr(factory->NewFromString("0")); + JSHandle matchedStr(factory->NewFromCanBeCompressString("0")); // 11. Let results be a new empty List. JSHandle resultsList(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); int resultsIndex = 0; @@ -684,7 +685,7 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) // f. Let matchLength be the number of code units in matched. uint32_t matchLength = matchString->GetLength(); // g. Let position be ToInteger(Get(result, "index")). - JSHandle resultIndex(factory->NewFromString("index")); + JSHandle resultIndex(factory->NewFromCanBeCompressString("index")); JSHandle positionHandle = JSObject::GetProperty(thread, resultValues, resultIndex).GetValue(); uint32_t position = JSTaggedValue::ToUint32(thread, positionHandle); // h. ReturnIfAbrupt(position). @@ -734,7 +735,10 @@ JSTaggedValue BuiltinsRegExp::Replace(EcmaRuntimeCallInfo *argv) replacerArgs->Set(thread, index + 2, inputStr.GetTaggedValue()); // 2: position of string // iv. Let replValue be Call(replaceValue, undefined, replacerArgs). JSHandle undefined(thread, JSTaggedValue::Undefined()); - JSTaggedValue replaceResult = JSFunction::Call(thread, inputReplaceValue, undefined, replacerArgs); + ecmascript::InternalCallParams *args = thread->GetInternalCallParams(); + args->MakeArgList(*replacerArgs); + JSTaggedValue replaceResult = + JSFunction::Call(thread, inputReplaceValue, undefined, replacerArgs->GetLength(), args->GetArgv()); JSHandle replValue(thread, replaceResult); // v. Let replacement be ToString(replValue). JSHandle replacementString = JSTaggedValue::ToString(thread, replValue); @@ -820,7 +824,7 @@ JSTaggedValue BuiltinsRegExp::Search(EcmaRuntimeCallInfo *argv) } // 10. Return ? Get(result, "index"). ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle index(factory->NewFromString("index")); + JSHandle index(factory->NewFromCanBeCompressString("index")); return JSObject::GetProperty(thread, result, index).GetValue().GetTaggedValue(); } @@ -855,7 +859,7 @@ JSTaggedValue BuiltinsRegExp::Split(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 7. Let flags be ToString(Get(rx, "flags")). ObjectFactory *factory = ecmaVm->GetFactory(); - JSHandle flagsString(factory->NewFromString("flags")); + JSHandle flagsString(factory->NewFromCanBeCompressString("flags")); JSHandle taggedFlags = JSObject::GetProperty(thread, thisObj, flagsString).GetValue(); JSHandle flags; @@ -868,16 +872,16 @@ JSTaggedValue BuiltinsRegExp::Split(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 9. If flags contains "u", let unicodeMatching be true. // 10. Else, let unicodeMatching be false. - JSHandle uStringHandle(factory->NewFromString("u")); + JSHandle uStringHandle(factory->NewFromCanBeCompressString("u")); bool unicodeMatching = base::StringHelper::Contains(*flags, *uStringHandle); // 11. If flags contains "y", let newFlags be flags. JSHandle newFlagsHandle; - JSHandle yStringHandle(factory->NewFromString("y")); + JSHandle yStringHandle(factory->NewFromCanBeCompressString("y")); if (base::StringHelper::Contains(*flags, *yStringHandle)) { newFlagsHandle = flags; } else { // 12. Else, let newFlags be the string that is the concatenation of flags and "y". - JSHandle yStr = factory->NewFromString("y"); + JSHandle yStr = factory->NewFromCanBeCompressString("y"); newFlagsHandle = factory->ConcatFromString(flags, yStr); } @@ -906,10 +910,10 @@ JSTaggedValue BuiltinsRegExp::Split(EcmaRuntimeCallInfo *argv) // 13. Let splitter be Construct(C, «rx, newFlags»). JSHandle globalObject(thread, thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject()); JSHandle undefined(thread, JSTaggedValue::Undefined()); - JSHandle arguments = factory->NewTaggedArray(2); // 2: «rx, newFlags» - arguments->Set(thread, 0, thisObj.GetTaggedValue()); - arguments->Set(thread, 1, newFlagsHandle.GetTaggedValue()); - JSTaggedValue taggedSplitter = JSFunction::Construct(thread, constructor, arguments, undefined); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(thisObj, newFlagsHandle); + JSTaggedValue taggedSplitter = + JSFunction::Construct(thread, constructor, 2, arguments->GetArgv(), undefined); // 2: two args // 14. ReturnIfAbrupt(splitter). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -995,7 +999,7 @@ JSTaggedValue BuiltinsRegExp::Split(EcmaRuntimeCallInfo *argv) // 6. Let p be e. startIndex = lastIndex; // 7. Let numberOfCaptures be ToLength(Get(z, "length")). - JSHandle lengthString(factory->NewFromString("length")); + JSHandle lengthString(factory->NewFromCanBeCompressString("length")); JSHandle capturesHandle = JSObject::GetProperty(thread, execResult, lengthString).GetValue(); JSTaggedNumber numberOfCapturesNumber = JSTaggedValue::ToLength(thread, capturesHandle); @@ -1115,17 +1119,17 @@ JSHandle BuiltinsRegExp::ConcatFlags(JSThread *thread, const JSHa if (exist) { JSHandle temp = factory->GetEmptyString(); if (CString("global") == name) { - temp = factory->NewFromString("g"); + temp = factory->NewFromCanBeCompressString("g"); } else if (CString("ignoreCase") == name) { - temp = factory->NewFromString("i"); + temp = factory->NewFromCanBeCompressString("i"); } else if (CString("multiline") == name) { - temp = factory->NewFromString("m"); + temp = factory->NewFromCanBeCompressString("m"); } else if (CString("dotAll") == name) { - temp = factory->NewFromString("s"); + temp = factory->NewFromCanBeCompressString("s"); } else if (CString("unicode") == name) { - temp = factory->NewFromString("u"); + temp = factory->NewFromCanBeCompressString("u"); } else if (CString("sticky") == name) { - temp = factory->NewFromString("y"); + temp = factory->NewFromCanBeCompressString("y"); } JSHandle thisString(string); return JSHandle(factory->ConcatFromString(thisString, temp)); @@ -1170,10 +1174,10 @@ JSTaggedValue BuiltinsRegExp::RegExpBuiltinExec(JSThread *thread, const JSHandle JSTaggedNumber lastIndexNumber = JSTaggedValue::ToLength(thread, lastIndexResult); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); int32_t lastIndex = lastIndexNumber.GetNumber(); - JSHandle globalHandle(factory->NewFromString("global")); + JSHandle globalHandle(factory->NewFromCanBeCompressString("global")); bool global = JSObject::GetProperty(thread, regexp, globalHandle).GetValue()->ToBoolean(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSHandle stickyHandle(factory->NewFromString("sticky")); + JSHandle stickyHandle(factory->NewFromCanBeCompressString("sticky")); bool sticky = JSObject::GetProperty(thread, regexp, stickyHandle).GetValue()->ToBoolean(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (!global && !sticky) { @@ -1181,7 +1185,7 @@ JSTaggedValue BuiltinsRegExp::RegExpBuiltinExec(JSThread *thread, const JSHandle } JSHandle regexpObj(thread, JSRegExp::Cast(regexp->GetTaggedObject())); auto flagsStr = static_cast(regexpObj->GetOriginalFlags().GetTaggedObject()); - JSHandle uString = factory->NewFromString("u"); + JSHandle uString = factory->NewFromCanBeCompressString("u"); [[maybe_unused]] bool fullUnicode = base::StringHelper::Contains(flagsStr, *uString); if (lastIndex > length) { JSHandle lastIndexValue(thread, JSTaggedValue(0)); @@ -1225,11 +1229,11 @@ JSTaggedValue BuiltinsRegExp::RegExpBuiltinExec(JSThread *thread, const JSHandle JSHandle results(JSArray::ArrayCreate(thread, JSTaggedNumber(capturesSize))); uint32_t matchIndex = matchResult.index_; // 24. Perform CreateDataProperty(A, "index", matchIndex). - JSHandle indexKey(factory->NewFromString("index")); + JSHandle indexKey(factory->NewFromCanBeCompressString("index")); JSHandle indexValue(thread, JSTaggedValue(matchIndex)); JSObject::CreateDataProperty(thread, results, indexKey, indexValue); // 25. Perform CreateDataProperty(A, "input", S). - JSHandle inputKey(factory->NewFromString("input")); + JSHandle inputKey(factory->NewFromCanBeCompressString("input")); JSHandle inputValue(thread, static_cast(inputStr->GetTaggedObject())); JSObject::CreateDataProperty(thread, results, inputKey, inputValue); @@ -1278,9 +1282,9 @@ JSTaggedValue BuiltinsRegExp::RegExpExec(JSThread *thread, const JSHandle obj = JSHandle::Cast(thisObj); - JSHandle arguments = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(1); - arguments->Set(thread, 0, inputStr.GetTaggedValue()); - JSTaggedValue result = JSFunction::Call(thread, exec, obj, arguments); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(inputStr.GetTaggedValue()); + JSTaggedValue result = JSFunction::Call(thread, exec, obj, 1, arguments->GetArgv()); // b. ReturnIfAbrupt(result). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (!result.IsECMAObject() && !result.IsNull()) { diff --git a/ecmascript/builtins/builtins_regexp.h b/ecmascript/builtins/builtins_regexp.h index 50ce7911bb169802561e11c6b75ea661b33c8931..9fd5ba41d2c583fe08d27a00e2db81f6a77d6686 100644 --- a/ecmascript/builtins/builtins_regexp.h +++ b/ecmascript/builtins/builtins_regexp.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_REGEXP_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_REGEXP_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_REGEXP_H +#define ECMASCRIPT_BUILTINS_BUILTINS_REGEXP_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/builtins/builtins_string.h" @@ -160,4 +160,4 @@ private: static constexpr int ENTRY_SIZE = 5; }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_REGEXP_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_REGEXP_H diff --git a/ecmascript/builtins/builtins_relative_time_format.cpp b/ecmascript/builtins/builtins_relative_time_format.cpp new file mode 100644 index 0000000000000000000000000000000000000000..78852abf6577dc75da369c9a4a7eb289f70905f1 --- /dev/null +++ b/ecmascript/builtins/builtins_relative_time_format.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "builtins_relative_time_format.h" + +namespace panda::ecmascript::builtins { +JSTaggedValue BuiltinsRelativeTimeFormat::RelativeTimeFormatConstructor(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + JSHandle env = ecmaVm->GetGlobalEnv(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + // 1. If NewTarget is undefined, throw a TypeError exception. + JSHandle newTarget = GetNewTarget(argv); + if (newTarget->IsUndefined()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "newTarget is undefined", JSTaggedValue::Exception()); + } + + // 2. Let relativeTimeFormat be ? OrdinaryCreateFromConstructor + // (NewTarget, "%RelativeTimeFormatPrototype%", « [[InitializedRelativeTimeFormat]], + // [[Locale]], [[DataLocale]], [[Style]], [[Numeric]], [[NumberFormat]], [[NumberingSystem]], [[PluralRules]] »). + JSHandle constructor = GetConstructor(argv); + JSHandle relativeTimeFormat = JSHandle::Cast( + factory->NewJSObjectByConstructor(JSHandle(constructor), newTarget)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 3. Perform ? InitializeRelativeTimeFormat(relativeTimeFormat, locales, options). + JSHandle locales = GetCallArg(argv, 0); + JSHandle options = GetCallArg(argv, 1); + JSRelativeTimeFormat::InitializeRelativeTimeFormat(thread, relativeTimeFormat, locales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 4. Intl.RelativeTimeFormat.prototype[ @@toStringTag ] + // This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. + JSHandle thisValue = GetThis(argv); + bool isInstanceOf = JSObject::InstanceOf(thread, thisValue, env->GetRelativeTimeFormatFunction()); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (newTarget->IsUndefined() && thisValue->IsJSObject() && isInstanceOf) { + PropertyDescriptor descriptor(thread, JSHandle::Cast(relativeTimeFormat), false, false, true); + JSHandle key(thread, JSHandle::Cast(env->GetIntlFunction())->GetFallbackSymbol()); + JSTaggedValue::DefinePropertyOrThrow(thread, thisValue, key, descriptor); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return thisValue.GetTaggedValue(); + } + + return relativeTimeFormat.GetTaggedValue(); +} + +JSTaggedValue BuiltinsRelativeTimeFormat::SupportedLocalesOf(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1. Let availableLocales be %RelativeTimeFormat%.[[AvailableLocales]]. + JSHandle availableLocales = JSLocale::GetAvailableLocales(thread, "calendar", nullptr); + + // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle locales = GetCallArg(argv, 0); + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). + JSHandle options = GetCallArg(argv, 1); + JSHandle result = JSLocale::SupportedLocales(thread, availableLocales, requestedLocales, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +JSTaggedValue BuiltinsRelativeTimeFormat::Format(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1. Let relativeTimeFormat be the this value. + JSHandle thisValue = GetThis(argv); + + // 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]). + if (!thisValue->IsJSRelativeTimeFormat()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not rtf object", JSTaggedValue::Exception()); + } + + // 3. Let value be ? ToNumber(value). + double x = 0.0; + JSHandle value = GetCallArg(argv, 0); + JSTaggedNumber temp = JSTaggedValue::ToNumber(thread, value); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + x = temp.GetNumber(); + + // 4. Let unit be ? ToString(unit). + JSHandle unitValue = GetCallArg(argv, 1); + JSHandle unit = JSTaggedValue::ToString(thread, unitValue); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 5. Return ? FormatRelativeTime(relativeTimeFormat, value, unit). + JSHandle relativeTimeFormat = JSHandle::Cast(thisValue); + JSHandle result = JSRelativeTimeFormat::Format(thread, x, unit, relativeTimeFormat); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +JSTaggedValue BuiltinsRelativeTimeFormat::FormatToParts(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1. Let relativeTimeFormat be the this value. + JSHandle thisValue = GetThis(argv); + + // 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]). + if (!thisValue->IsJSRelativeTimeFormat()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not rtf object", JSTaggedValue::Exception()); + } + + // 3. Let value be ? ToNumber(value). + double x = 0.0; + JSHandle value = GetCallArg(argv, 0); + JSTaggedNumber temp = JSTaggedValue::ToNumber(thread, value); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + x = temp.GetNumber(); + + // 4. Let unit be ? ToString(unit). + JSHandle unitValue = GetCallArg(argv, 1); + JSHandle unit = JSTaggedValue::ToString(thread, unitValue); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // 5. Return ? FormatRelativeTime(relativeTimeFormat, value, unit). + JSHandle relativeTimeFormat = JSHandle::Cast(thisValue); + JSHandle result = JSRelativeTimeFormat::FormatToParts(thread, x, unit, relativeTimeFormat); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return result.GetTaggedValue(); +} + +JSTaggedValue BuiltinsRelativeTimeFormat::ResolvedOptions(EcmaRuntimeCallInfo *argv) +{ + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope scope(thread); + + // 1. Let relativeTimeFormat be the this value. + JSHandle thisValue = GetThis(argv); + + // 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]). + if (!thisValue->IsJSRelativeTimeFormat()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not rtf object", JSTaggedValue::Exception()); + } + + // 3. Let options be ! ObjectCreate(%ObjectPrototype%). + auto ecmaVm = thread->GetEcmaVM(); + JSHandle env = ecmaVm->GetGlobalEnv(); + ObjectFactory *factory = ecmaVm->GetFactory(); + JSHandle ctor = env->GetObjectFunction(); + JSHandle options(factory->NewJSObjectByConstructor(JSHandle(ctor), ctor)); + + // 4. perform resolvedOptions + JSHandle relativeTimeFormat = JSHandle::Cast(thisValue); + JSRelativeTimeFormat::ResolvedOptions(thread, relativeTimeFormat, options); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + // 5. Return options. + return options.GetTaggedValue(); +} +} // namespace panda::ecmascript::builtins \ No newline at end of file diff --git a/ecmascript/builtins/builtins_relative_time_format.h b/ecmascript/builtins/builtins_relative_time_format.h new file mode 100644 index 0000000000000000000000000000000000000000..9b30b98f35d0a5abafbcd70476c7548ab8877b30 --- /dev/null +++ b/ecmascript/builtins/builtins_relative_time_format.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_RELATIVE_TIME_FORMAT_H +#define ECMASCRIPT_BUILTINS_BUILTINS_RELATIVE_TIME_FORMAT_H + +#include "ecmascript/base/builtins_base.h" +#include "ecmascript/ecma_runtime_call_info.h" +#include "ecmascript/ecma_vm.h" +#include "ecmascript/global_env.h" +#include "ecmascript/js_array.h" +#include "ecmascript/js_date.h" +#include "ecmascript/js_hclass.h" +#include "ecmascript/js_intl.h" +#include "ecmascript/js_locale.h" +#include "ecmascript/js_object.h" +#include "ecmascript/js_relative_time_format.h" +#include "ecmascript/object_factory.h" + +namespace panda::ecmascript::builtins { +class BuiltinsRelativeTimeFormat : public base::BuiltinsBase { +public: + // 14.2.1 Intl.RelativeTimeFormat ([ locales [ , options ]]) + static JSTaggedValue RelativeTimeFormatConstructor(EcmaRuntimeCallInfo *argv); + + // 14.3.1 Intl.RelativeTimeFormat.supportedLocalesOf ( locales [ , options ] ) + static JSTaggedValue SupportedLocalesOf(EcmaRuntimeCallInfo *argv); + + // 14.4.3 Intl.RelativeTimeFormat.prototype.format( value, unit ) + static JSTaggedValue Format(EcmaRuntimeCallInfo *argv); + + // 14.4.4 Intl.RelativeTimeFormat.prototype.formatToParts( value, unit ) + static JSTaggedValue FormatToParts(EcmaRuntimeCallInfo *argv); + + // 14.4.5 Intl.RelativeTimeFormat.prototype.resolvedOptions () + static JSTaggedValue ResolvedOptions(EcmaRuntimeCallInfo *argv); +}; +} // namespace panda::ecmascript::builtins + +#endif // ECMASCRIPT_BUILTINS_BUILTINS_RELATIVE_TIME_FORMAT_H \ No newline at end of file diff --git a/ecmascript/builtins/builtins_set.cpp b/ecmascript/builtins/builtins_set.cpp index 58e0aacc0ce5ecce2106970e575ec4514321809f..a4fb555984d1d4db61740926c36124ef3912e901 100644 --- a/ecmascript/builtins/builtins_set.cpp +++ b/ecmascript/builtins/builtins_set.cpp @@ -16,6 +16,7 @@ #include "builtins_set.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_invoker.h" #include "ecmascript/js_set.h" #include "ecmascript/js_set_iterator.h" @@ -57,7 +58,7 @@ JSTaggedValue BuiltinsSet::SetConstructor(EcmaRuntimeCallInfo *argv) return set.GetTaggedValue(); } // Let adder be Get(set, "add"). - JSHandle adderKey(factory->NewFromString("add")); + JSHandle adderKey(factory->NewFromCanBeCompressString("add")); JSHandle setHandle(set); JSHandle adder = JSObject::GetProperty(thread, setHandle, adderKey).GetValue(); // ReturnIfAbrupt(adder). @@ -74,6 +75,7 @@ JSTaggedValue BuiltinsSet::SetConstructor(EcmaRuntimeCallInfo *argv) // jsarray JSHandle valueIndex(thread, JSTaggedValue(1)); JSHandle next = JSIterator::IteratorStep(thread, iter); + InternalCallParams *arguments = thread->GetInternalCallParams(); while (!next->IsFalse()) { // ReturnIfAbrupt(next). RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, next.GetTaggedValue()); @@ -81,13 +83,12 @@ JSTaggedValue BuiltinsSet::SetConstructor(EcmaRuntimeCallInfo *argv) JSHandle nextValue(JSIterator::IteratorValue(thread, next)); // ReturnIfAbrupt(nextValue). RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, nextValue.GetTaggedValue()); - JSHandle array(factory->NewTaggedArray(1)); - array->Set(thread, 0, nextValue); + arguments->MakeArgv(nextValue); if (nextValue->IsArray(thread)) { auto prop = JSObject::GetProperty(thread, nextValue, valueIndex).GetValue(); - array->Set(thread, 0, prop); + arguments->MakeArgv(prop); } - JSTaggedValue ret = JSFunction::Call(thread, adder, JSHandle(set), array); + JSTaggedValue ret = JSFunction::Call(thread, adder, JSHandle(set), 1, arguments->GetArgv()); // Let status be Call(adder, set, «nextValue.[[value]]»). JSHandle status(thread, ret); @@ -199,18 +200,15 @@ JSTaggedValue BuiltinsSet::ForEach([[maybe_unused]] EcmaRuntimeCallInfo *argv) JSHandle thisArg = GetCallArg(argv, 1); // composed arguments - int argumentsLength = 3; - JSHandle array(factory->NewTaggedArray(argumentsLength)); JSHandle iter(factory->NewJSSetIterator(set, IterationKind::KEY)); JSHandle result = JSIterator::IteratorStep(thread, iter); + InternalCallParams *arguments = thread->GetInternalCallParams(); while (!result->IsFalse()) { RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, result.GetTaggedValue()); JSHandle value = JSIterator::IteratorValue(thread, result); - array->Set(thread, 0, value); - array->Set(thread, 1, value); - array->Set(thread, 2, set); // 2: the third value is set // Let funcResult be Call(callbackfn, T, «e, e, S»). - JSTaggedValue ret = JSFunction::Call(thread, func, thisArg, array); + arguments->MakeArgv(value, value, JSHandle(set)); + JSTaggedValue ret = JSFunction::Call(thread, func, thisArg, 3, arguments->GetArgv()); // 3: three args // returnIfAbrupt RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, ret); result = JSIterator::IteratorStep(thread, iter); diff --git a/ecmascript/builtins/builtins_set.h b/ecmascript/builtins/builtins_set.h index c7fd3da2b56b6835a7b6ae383fcb05d902c3e581..aa00a122ff5c3fd33b8a8538fcb7cc89e09444eb 100644 --- a/ecmascript/builtins/builtins_set.h +++ b/ecmascript/builtins/builtins_set.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_SET_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_SET_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_SET_H +#define ECMASCRIPT_BUILTINS_BUILTINS_SET_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -44,4 +44,4 @@ public: static JSTaggedValue Values(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_SET_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_SET_H diff --git a/ecmascript/builtins/builtins_string.cpp b/ecmascript/builtins/builtins_string.cpp index 3b8d4a4527ccacd611c73ee45839d43f2d5280e7..370803d4a33784d5158c3f3635f7daeed2ec3743 100644 --- a/ecmascript/builtins/builtins_string.cpp +++ b/ecmascript/builtins/builtins_string.cpp @@ -26,9 +26,11 @@ #include "ecmascript/ecma_string-inl.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_array.h" #include "ecmascript/js_hclass.h" #include "ecmascript/js_invoker.h" +#include "ecmascript/js_locale.h" #include "ecmascript/js_object-inl.h" #include "ecmascript/js_primitive_ref.h" #include "ecmascript/js_string_iterator.h" @@ -138,7 +140,7 @@ JSTaggedValue BuiltinsString::FromCodePoint(EcmaRuntimeCallInfo *argv) THROW_RANGE_ERROR_AND_RETURN(thread, "CodePoint < 0 or CodePoint > 0x10FFFF", JSTaggedValue::Exception()); } if (cp == 0) { - CVector data{0x00}; + CVector data {0x00}; return factory->NewFromUtf16Literal(data.data(), 1).GetTaggedValue(); } if (cp > UINT16_MAX) { @@ -174,7 +176,7 @@ JSTaggedValue BuiltinsString::Raw(EcmaRuntimeCallInfo *argv) // ReturnIfAbrupt(cooked). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // Let raw be ToObject(Get(cooked, "raw")). - JSHandle rawKey(factory->NewFromString("raw")); + JSHandle rawKey(factory->NewFromCanBeCompressString("raw")); JSHandle rawTag = JSObject::GetProperty(thread, JSHandle::Cast(cooked), rawKey).GetValue(); JSHandle rawObj = JSTaggedValue::ToObject(thread, rawTag); @@ -194,6 +196,7 @@ JSTaggedValue BuiltinsString::Raw(EcmaRuntimeCallInfo *argv) std::u16string u16str; int argc = static_cast(argv->GetArgsNumber()) - 1; + bool canBeCompress = true; for (int i = 0, argsI = 1; i < length; ++i, ++argsI) { // Let nextSeg be ToString(Get(raw, nextKey)). JSHandle elementString = @@ -203,6 +206,7 @@ JSTaggedValue BuiltinsString::Raw(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (nextSeg->IsUtf16()) { u16str += base::StringHelper::Utf16ToU16String(nextSeg->GetDataUtf16(), nextSeg->GetLength()); + canBeCompress = false; } else { u16str += base::StringHelper::Utf8ToU16String(nextSeg->GetDataUtf8(), nextSeg->GetLength()); } @@ -214,6 +218,7 @@ JSTaggedValue BuiltinsString::Raw(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (nextSub->IsUtf16()) { u16str += base::StringHelper::Utf16ToU16String(nextSub->GetDataUtf16(), nextSub->GetLength()); + canBeCompress = false; } else { u16str += base::StringHelper::Utf8ToU16String(nextSub->GetDataUtf8(), nextSub->GetLength()); } @@ -221,7 +226,7 @@ JSTaggedValue BuiltinsString::Raw(EcmaRuntimeCallInfo *argv) } // return the result string auto *uint16tData = reinterpret_cast(const_cast(u16str.data())); - return factory->NewFromUtf16Literal(uint16tData, u16str.size()).GetTaggedValue(); + return factory->NewFromUtf16LiteralUnCheck(uint16tData, u16str.size(), canBeCompress).GetTaggedValue(); } // 21.1.3.1 @@ -328,8 +333,10 @@ JSTaggedValue BuiltinsString::Concat(EcmaRuntimeCallInfo *argv) } std::u16string u16strThis; std::u16string u16strNext; + bool canBeCompress = true; if (thisHandle->IsUtf16()) { u16strThis = base::StringHelper::Utf16ToU16String(thisHandle->GetDataUtf16(), thisLen); + canBeCompress = false; } else { u16strThis = base::StringHelper::Utf8ToU16String(thisHandle->GetDataUtf8(), thisLen); } @@ -339,6 +346,7 @@ JSTaggedValue BuiltinsString::Concat(EcmaRuntimeCallInfo *argv) int32_t nextLen = nextHandle->GetLength(); if (nextHandle->IsUtf16()) { u16strNext = base::StringHelper::Utf16ToU16String(nextHandle->GetDataUtf16(), nextLen); + canBeCompress = false; } else { u16strNext = base::StringHelper::Utf8ToU16String(nextHandle->GetDataUtf8(), nextLen); } @@ -348,7 +356,7 @@ JSTaggedValue BuiltinsString::Concat(EcmaRuntimeCallInfo *argv) auto *char16tData = const_cast(constChar16tData); auto *uint16tData = reinterpret_cast(char16tData); int32_t u16strSize = u16strThis.size(); - return factory->NewFromUtf16Literal(uint16tData, u16strSize).GetTaggedValue(); + return factory->NewFromUtf16LiteralUnCheck(uint16tData, u16strSize, canBeCompress).GetTaggedValue(); } // 21.1.3.5 String.prototype.constructor @@ -578,7 +586,6 @@ JSTaggedValue BuiltinsString::Match(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), String, Match); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); JSHandle thisTag(JSTaggedValue::RequireObjectCoercible(thread, GetThis(argv))); JSHandle regexp = BuiltinsString::GetCallArg(argv, 0); @@ -589,9 +596,9 @@ JSTaggedValue BuiltinsString::Match(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (!matcher->IsUndefined()) { ASSERT(matcher->IsJSFunction()); - JSHandle arg = factory->NewTaggedArray(1); - arg->Set(thread, 0, thisTag); - return JSFunction::Call(thread, matcher, regexp, arg); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(thisTag); + return JSFunction::Call(thread, matcher, regexp, 1, arguments->GetArgv()); } } } @@ -600,9 +607,70 @@ JSTaggedValue BuiltinsString::Match(EcmaRuntimeCallInfo *argv) JSHandle undifinedHandle = globalConst->GetHandledUndefined(); JSHandle rx(thread, BuiltinsRegExp::RegExpCreate(thread, regexp, undifinedHandle)); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSHandle arguments = factory->NewTaggedArray(1); - arguments->Set(thread, 0, thisVal.GetTaggedValue()); - return JSFunction::Invoke(thread, rx, matchTag, arguments); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(thisVal.GetTaggedValue()); + return JSFunction::Invoke(thread, rx, matchTag, 1, arguments->GetArgv()); +} + +// 21.1.3.12 +JSTaggedValue BuiltinsString::Normalize(EcmaRuntimeCallInfo *argv) +{ + ASSERT(argv); + BUILTINS_API_TRACE(argv->GetThread(), String, Normalize); + JSThread *thread = argv->GetThread(); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle thisTag(JSTaggedValue::RequireObjectCoercible(thread, GetThis(argv))); + JSHandle thisHandle = JSTaggedValue::ToString(thread, thisTag); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); + JSHandle formValue; + if (argv->GetArgsNumber() == 0) { + formValue = factory->NewFromString("NFC"); + } else { + JSHandle formTag = BuiltinsString::GetCallArg(argv, 0); + if (formTag->IsUndefined()) { + formValue = factory->NewFromString("NFC"); + } else { + formValue = JSTaggedValue::ToString(thread, formTag); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); + } + } + JSHandle nfc = factory->NewFromString("NFC"); + JSHandle nfd = factory->NewFromString("NFD"); + JSHandle nfkc = factory->NewFromString("NFKC"); + JSHandle nfkd = factory->NewFromString("NFKD"); + if (formValue->Compare(*nfc) != 0 && formValue->Compare(*nfd) != 0 && formValue->Compare(*nfkc) != 0 && + formValue->Compare(*nfkd) != 0) { + THROW_RANGE_ERROR_AND_RETURN(thread, "compare not equal", JSTaggedValue::Exception()); + } + std::u16string u16strThis; + if (thisHandle->IsUtf16()) { + u16strThis = base::StringHelper::Utf16ToU16String(thisHandle->GetDataUtf16(), thisHandle->GetLength()); + } else { + const uint8_t *uint8This = thisHandle->GetDataUtf8(); + u16strThis = base::StringHelper::Utf8ToU16String(uint8This, thisHandle->GetLength()); + } + const char16_t *constChar16tData = u16strThis.data(); + icu::UnicodeString src(constChar16tData); + icu::UnicodeString res; + UErrorCode errorCode = U_ZERO_ERROR; + UNormalizationMode uForm; + int32_t option = 0; + if (formValue->Compare(*nfc) == 0) { + uForm = UNORM_NFC; + } else if (formValue->Compare(*nfd) == 0) { + uForm = UNORM_NFD; + } else if (formValue->Compare(*nfkc) == 0) { + uForm = UNORM_NFKC; + } else if (formValue->Compare(*nfkd) == 0) { + uForm = UNORM_NFKD; + } else { + UNREACHABLE(); + } + SetHwIcuDirectory(); + icu::Normalizer::normalize(src, uForm, option, res, errorCode); + JSHandle str = JSLocale::IcuToString(thread, res); + return JSTaggedValue(*str); } // 21.1.3.13 @@ -628,8 +696,10 @@ JSTaggedValue BuiltinsString::Repeat(EcmaRuntimeCallInfo *argv) } int32_t count = base::NumberHelper::DoubleInRangeInt32(d); std::u16string u16strThis; + bool canBeCompress = true; if (thisHandle->IsUtf16()) { u16strThis = base::StringHelper::Utf16ToU16String(thisHandle->GetDataUtf16(), thisLen); + canBeCompress = false; } else { const uint8_t *uint8This = thisHandle->GetDataUtf8(); u16strThis = base::StringHelper::Utf8ToU16String(uint8This, thisLen); @@ -638,7 +708,7 @@ JSTaggedValue BuiltinsString::Repeat(EcmaRuntimeCallInfo *argv) return thisHandle.GetTaggedValue(); } - EcmaString *res = base::StringHelper::Repeat(thread, u16strThis, count); + EcmaString *res = base::StringHelper::Repeat(thread, u16strThis, count, canBeCompress); return JSTaggedValue(res); } @@ -670,10 +740,9 @@ JSTaggedValue BuiltinsString::Replace(EcmaRuntimeCallInfo *argv) // If replacer is not undefined, then if (!replaceMethod->IsUndefined()) { // Return Call(replacer, searchValue, «O, replaceValue»). - JSHandle args = factory->NewTaggedArray(2); // 2: 2 means two args stored in array - args->Set(thread, 0, thisTag); - args->Set(thread, 1, replaceTag); - return JSFunction::Call(thread, replaceMethod, searchTag, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(thisTag, replaceTag); + return JSFunction::Call(thread, replaceMethod, searchTag, 2, arguments->GetArgv()); // 2: two args } } @@ -705,13 +774,12 @@ JSTaggedValue BuiltinsString::Replace(EcmaRuntimeCallInfo *argv) // If functionalReplace is true, then if (replaceTag->IsCallable()) { // Let replValue be Call(replaceValue, undefined,«matched, pos, and string»). - JSHandle jsargs = factory->NewTaggedArray(3); // 3: «matched, pos, and string» - jsargs->Set(thread, 0, searchString); - jsargs->Set(thread, 1, JSTaggedValue(pos)); - jsargs->Set(thread, 2, thisString); // 2: Position of string - JSHandle replaceFunc(replaceTag); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSHandle(searchString), + JSHandle(thread, JSTaggedValue(pos)), JSHandle(thisString)); JSTaggedValue replStrDeocodeValue = - JSFunction::Call(thread, replaceTag, globalConst->GetHandledUndefined(), jsargs); + JSFunction::Call(thread, replaceTag, + globalConst->GetHandledUndefined(), 3, arguments->GetArgv()); // 3: «matched, pos, and string» replHandle.Update(replStrDeocodeValue); } else { // Let captures be an empty List. @@ -732,9 +800,11 @@ JSTaggedValue BuiltinsString::Replace(EcmaRuntimeCallInfo *argv) JSHandle suffixString( thread, EcmaString::FastSubString(thisString, tailPos, thisString->GetLength() - tailPos, ecmaVm)); std::u16string stringBuilder; + bool canBeCompress = true; if (prefixString->IsUtf16()) { const uint16_t *data = prefixString->GetDataUtf16(); stringBuilder += base::StringHelper::Utf16ToU16String(data, prefixString->GetLength()); + canBeCompress = false; } else { const uint8_t *data = prefixString->GetDataUtf8(); stringBuilder += base::StringHelper::Utf8ToU16String(data, prefixString->GetLength()); @@ -743,6 +813,7 @@ JSTaggedValue BuiltinsString::Replace(EcmaRuntimeCallInfo *argv) if (realReplaceStr->IsUtf16()) { const uint16_t *data = realReplaceStr->GetDataUtf16(); stringBuilder += base::StringHelper::Utf16ToU16String(data, realReplaceStr->GetLength()); + canBeCompress = false; } else { const uint8_t *data = realReplaceStr->GetDataUtf8(); stringBuilder += base::StringHelper::Utf8ToU16String(data, realReplaceStr->GetLength()); @@ -751,6 +822,7 @@ JSTaggedValue BuiltinsString::Replace(EcmaRuntimeCallInfo *argv) if (suffixString->IsUtf16()) { const uint16_t *data = suffixString->GetDataUtf16(); stringBuilder += base::StringHelper::Utf16ToU16String(data, suffixString->GetLength()); + canBeCompress = false; } else { const uint8_t *data = suffixString->GetDataUtf8(); stringBuilder += base::StringHelper::Utf8ToU16String(data, suffixString->GetLength()); @@ -758,7 +830,7 @@ JSTaggedValue BuiltinsString::Replace(EcmaRuntimeCallInfo *argv) auto *char16tData = const_cast(stringBuilder.c_str()); auto *uint16tData = reinterpret_cast(char16tData); - return factory->NewFromUtf16Literal(uint16tData, stringBuilder.size()).GetTaggedValue(); + return factory->NewFromUtf16LiteralUnCheck(uint16tData, stringBuilder.size(), canBeCompress).GetTaggedValue(); } JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandle &matched, @@ -769,7 +841,7 @@ JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandleGetEcmaVM(); ObjectFactory *factory = ecmaVm->GetFactory(); - JSHandle dollarString = factory->NewFromString("$"); + JSHandle dollarString = factory->NewFromCanBeCompressString("$"); int32_t replaceLength = replacement->GetLength(); int32_t tailPos = position + matched->GetLength(); @@ -779,10 +851,12 @@ JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandle 0) { if (replacement->IsUtf16()) { const uint16_t *data = replacement->GetDataUtf16(); stringBuilder += base::StringHelper::Utf16ToU16String(data, nextDollarIndex); + canBeCompress = false; } else { const uint8_t *data = replacement->GetDataUtf8(); stringBuilder += base::StringHelper::Utf8ToU16String(data, nextDollarIndex); @@ -795,7 +869,8 @@ JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandle(stringBuilder.c_str()); auto *uint16tData = reinterpret_cast(char16tData); - return factory->NewFromUtf16Literal(uint16tData, stringBuilder.length()).GetTaggedValue(); + return factory->NewFromUtf16LiteralUnCheck(uint16tData, stringBuilder.length(), canBeCompress) + .GetTaggedValue(); } int continueFromIndex = -1; uint16_t peek = replacement->At(peekIndex); @@ -808,6 +883,7 @@ JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandleIsUtf16()) { const uint16_t *data = matched->GetDataUtf16(); stringBuilder += base::StringHelper::Utf16ToU16String(data, matched->GetLength()); + canBeCompress = false; } else { const uint8_t *data = matched->GetDataUtf8(); stringBuilder += base::StringHelper::Utf8ToU16String(data, matched->GetLength()); @@ -820,6 +896,7 @@ JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandleIsUtf16()) { const uint16_t *data = prefix->GetDataUtf16(); stringBuilder += base::StringHelper::Utf16ToU16String(data, prefix->GetLength()); + canBeCompress = false; } else { const uint8_t *data = prefix->GetDataUtf8(); stringBuilder += base::StringHelper::Utf8ToU16String(data, prefix->GetLength()); @@ -835,6 +912,7 @@ JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandleIsUtf16()) { const uint16_t *data = sufffix->GetDataUtf16(); stringBuilder += base::StringHelper::Utf16ToU16String(data, sufffix->GetLength()); + canBeCompress = false; } else { const uint8_t *data = sufffix->GetDataUtf8(); stringBuilder += base::StringHelper::Utf8ToU16String(data, sufffix->GetLength()); @@ -881,6 +959,7 @@ JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandleIsUtf16()) { const uint16_t *data = captureString->GetDataUtf16(); stringBuilder += base::StringHelper::Utf16ToU16String(data, captureString->GetLength()); + canBeCompress = false; } else { const uint8_t *data = captureString->GetDataUtf8(); stringBuilder += base::StringHelper::Utf8ToU16String(data, captureString->GetLength()); @@ -903,6 +982,7 @@ JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandleIsUtf16()) { const uint16_t *data = nextAppend->GetDataUtf16(); stringBuilder += base::StringHelper::Utf16ToU16String(data, nextAppend->GetLength()); + canBeCompress = false; } else { const uint8_t *data = nextAppend->GetDataUtf8(); stringBuilder += base::StringHelper::Utf8ToU16String(data, nextAppend->GetLength()); @@ -910,7 +990,8 @@ JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandle(stringBuilder.c_str()); auto *uint16tData = reinterpret_cast(char16tData); - return factory->NewFromUtf16Literal(uint16tData, stringBuilder.length()).GetTaggedValue(); + return factory->NewFromUtf16LiteralUnCheck(uint16tData, stringBuilder.length(), canBeCompress) + .GetTaggedValue(); } // Append substring between the previous and the next $ character. if (nextDollarIndex > continueFromIndex) { @@ -919,6 +1000,7 @@ JSTaggedValue BuiltinsString::GetSubstitution(JSThread *thread, const JSHandleIsUtf16()) { const uint16_t *data = nextAppend->GetDataUtf16(); stringBuilder += base::StringHelper::Utf16ToU16String(data, nextAppend->GetLength()); + canBeCompress = false; } else { const uint8_t *data = nextAppend->GetDataUtf8(); stringBuilder += base::StringHelper::Utf8ToU16String(data, nextAppend->GetLength()); @@ -935,7 +1017,6 @@ JSTaggedValue BuiltinsString::Search(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), String, Search); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); JSHandle thisTag(JSTaggedValue::RequireObjectCoercible(thread, GetThis(argv))); JSHandle regexp = BuiltinsString::GetCallArg(argv, 0); @@ -946,9 +1027,9 @@ JSTaggedValue BuiltinsString::Search(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (!searcher->IsUndefined()) { ASSERT(searcher->IsJSFunction()); - JSHandle arg = factory->NewTaggedArray(1); - arg->Set(thread, 0, thisTag); - return JSFunction::Call(thread, searcher, regexp, arg); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(thisTag); + return JSFunction::Call(thread, searcher, regexp, 1, arguments->GetArgv()); } } } @@ -957,9 +1038,9 @@ JSTaggedValue BuiltinsString::Search(EcmaRuntimeCallInfo *argv) JSHandle undifinedHandle = globalConst->GetHandledUndefined(); JSHandle rx(thread, BuiltinsRegExp::RegExpCreate(thread, regexp, undifinedHandle)); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSHandle arguments = factory->NewTaggedArray(1); - arguments->Set(thread, 0, thisVal.GetTaggedValue()); - return JSFunction::Invoke(thread, rx, searchTag, arguments); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(thisVal.GetTaggedValue()); + return JSFunction::Invoke(thread, rx, searchTag, 1, arguments->GetArgv()); } // 21.1.3.16 @@ -1019,7 +1100,6 @@ JSTaggedValue BuiltinsString::Split(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); JSHandle seperatorTag = BuiltinsString::GetCallArg(argv, 0); JSHandle limitTag = BuiltinsString::GetCallArg(argv, 1); - ObjectFactory *factory = ecmaVm->GetFactory(); // If separator is neither undefined nor null, then if (seperatorTag->IsECMAObject()) { JSHandle splitKey = env->GetSplitSymbol(); @@ -1028,10 +1108,9 @@ JSTaggedValue BuiltinsString::Split(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (!splitter->IsUndefined()) { // Return Call(splitter, separator, «‍O, limit»). - JSHandle jsargs = factory->NewTaggedArray(2); // 2: 2 means two args stored in array - jsargs->Set(thread, 0, thisTag); - jsargs->Set(thread, 1, limitTag); - return JSFunction::Call(thread, splitter, seperatorTag, jsargs); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(thisTag, limitTag); + return JSFunction::Call(thread, splitter, seperatorTag, 2, arguments->GetArgv()); // 2: two args } } // Let S be ToString(O). @@ -1213,6 +1292,142 @@ JSTaggedValue BuiltinsString::Substring(EcmaRuntimeCallInfo *argv) return JSTaggedValue(EcmaString::FastSubString(thisHandle, from, len, thread->GetEcmaVM())); } +// 21.1.3.20 +JSTaggedValue BuiltinsString::ToLocaleLowerCase(EcmaRuntimeCallInfo *argv) +{ + ASSERT(argv); + BUILTINS_API_TRACE(argv->GetThread(), String, ToLocaleLowerCase); + JSThread *thread = argv->GetThread(); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + // Let O be RequireObjectCoercible(this value). + JSHandle obj(JSTaggedValue::RequireObjectCoercible(thread, GetThis(argv))); + + // Let S be ? ToString(O). + JSHandle string = JSTaggedValue::ToString(thread, obj); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle locales = GetCallArg(argv, 0); + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // If requestedLocales is not an empty List, then Let requestedLocale be requestedLocales[0]. + // Else, Let requestedLocale be DefaultLocale(). + JSHandle requestedLocale = JSLocale::DefaultLocale(thread); + if (requestedLocales->GetLength() != 0) { + requestedLocale = JSHandle(thread, requestedLocales->Get(0)); + } + + // Let noExtensionsLocale be the String value that is requestedLocale with all Unicode locale extension sequences + // removed. + JSLocale::ParsedLocale noExtensionsLocale = JSLocale::HandleLocale(requestedLocale); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Let availableLocales be a List with language tags that includes the languages for which the Unicode Character + // Database contains language sensitive case mappings. Implementations may add additional language tags + // if they support case mapping for additional locales. + JSHandle availableLocales = JSLocale::GetAvailableLocales(thread, nullptr, nullptr); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Let locale be BestAvailableLocale(availableLocales, noExtensionsLocale). + std::string locale = JSLocale::BestAvailableLocale(thread, availableLocales, noExtensionsLocale.base); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // If locale is undefined, let locale be "und". + if (locale.empty()) { + locale = "und"; + } + + // Let uString be a List containing in order the code points of S as defined in ES2020, 6.1.4, + // starting at the first element of S. + // Transform those elements in uString to the to the Unicode Default Case Conversion algorithm + icu::Locale icuLocale = icu::Locale::createFromName(locale.c_str()); + std::u16string utf16String; + if (string->IsUtf16()) { + utf16String = base::StringHelper::Utf16ToU16String(string->GetDataUtf16(), string->GetUtf16Length()); + } else { + const uint8_t *uint8This = string->GetDataUtf8(); + utf16String = base::StringHelper::Utf8ToU16String(uint8This, string->GetLength()); + } + icu::UnicodeString uString(utf16String.data()); + icu::UnicodeString res = uString.toLower(icuLocale); + std::string CSLower; + res.toUTF8String(CSLower); + JSHandle result = factory->NewFromStdString(CSLower); + return result.GetTaggedValue(); +} + +// 21.1.3.21 +JSTaggedValue BuiltinsString::ToLocaleUpperCase(EcmaRuntimeCallInfo *argv) +{ + ASSERT(argv); + BUILTINS_API_TRACE(argv->GetThread(), String, ToLocaleLowerCase); + JSThread *thread = argv->GetThread(); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + // Let O be RequireObjectCoercible(this value). + JSHandle obj(JSTaggedValue::RequireObjectCoercible(thread, GetThis(argv))); + + // Let S be ? ToString(O). + JSHandle string = JSTaggedValue::ToString(thread, obj); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle locales = GetCallArg(argv, 0); + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // If requestedLocales is not an empty List, then Let requestedLocale be requestedLocales[0]. + // Else, Let requestedLocale be DefaultLocale(). + JSHandle requestedLocale = JSLocale::DefaultLocale(thread); + if (requestedLocales->GetLength() != 0) { + requestedLocale = JSHandle(thread, requestedLocales->Get(0)); + } + + // Let noExtensionsLocale be the String value that is requestedLocale with all Unicode locale extension sequences + // removed. + JSLocale::ParsedLocale noExtensionsLocale = JSLocale::HandleLocale(requestedLocale); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Let availableLocales be a List with language tags that includes the languages for which the Unicode Character + // Database contains language sensitive case mappings. Implementations may add additional language tags + // if they support case mapping for additional locales. + JSHandle availableLocales = JSLocale::GetAvailableLocales(thread, nullptr, nullptr); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // Let locale be BestAvailableLocale(availableLocales, noExtensionsLocale). + std::string locale = JSLocale::BestAvailableLocale(thread, availableLocales, noExtensionsLocale.base); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + + // If locale is undefined, let locale be "und". + if (locale.empty()) { + locale = "und"; + } + + // Let uString be a List containing in order the code points of S as defined in ES2020, 6.1.4, + // starting at the first element of S. + // Transform those elements in uString to the to the Unicode Default Case Conversion algorithm + icu::Locale icuLocale = icu::Locale::createFromName(locale.c_str()); + std::u16string utf16String; + if (string->IsUtf16()) { + utf16String = base::StringHelper::Utf16ToU16String(string->GetDataUtf16(), string->GetUtf16Length()); + } else { + const uint8_t *uint8This = string->GetDataUtf8(); + utf16String = base::StringHelper::Utf8ToU16String(uint8This, string->GetLength()); + } + icu::UnicodeString uString(utf16String.data()); + icu::UnicodeString res = uString.toUpper(icuLocale); + std::string CSUpper; + res.toUTF8String(CSUpper); + JSHandle result = factory->NewFromStdString(CSUpper); + return result.GetTaggedValue(); +} + // 21.1.3.22 JSTaggedValue BuiltinsString::ToLowerCase(EcmaRuntimeCallInfo *argv) { diff --git a/ecmascript/builtins/builtins_string.h b/ecmascript/builtins/builtins_string.h index 2371fb720fbe3e043f6bc28421c03ac14b5ee25c..b08ad344f18232db6c0ce7af83c6d8ab25fa6171 100644 --- a/ecmascript/builtins/builtins_string.h +++ b/ecmascript/builtins/builtins_string.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_STRING_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_STRING_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_STRING_H +#define ECMASCRIPT_BUILTINS_BUILTINS_STRING_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -116,4 +116,4 @@ private: static int32_t SplitMatch(const JSHandle &str, int32_t q, const JSHandle ®); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_STRING_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_STRING_H diff --git a/ecmascript/builtins/builtins_string_iterator.cpp b/ecmascript/builtins/builtins_string_iterator.cpp index abfa2b643cce57bafe603299a6a23fbac913f4db..cc38dc157f7c7e16a8855451ca4e7a3bbbc24949 100644 --- a/ecmascript/builtins/builtins_string_iterator.cpp +++ b/ecmascript/builtins/builtins_string_iterator.cpp @@ -66,8 +66,8 @@ JSTaggedValue BuiltinsStringIterator::Next(EcmaRuntimeCallInfo *argv) ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); if (position + 1 == len || first < base::utf_helper::DECODE_LEAD_LOW || first > base::utf_helper::DECODE_LEAD_HIGH) { - std::vector resultString{first, 0x0}; - result.Update(factory->NewFromUtf16(resultString.data(), 1).GetTaggedValue()); + std::vector resultString {first, 0x0}; + result.Update(factory->NewFromUtf16UnCheck(resultString.data(), 1, true).GetTaggedValue()); } else { // 11. Else, // a. Let second be the code unit value at index position+1 in the String S. @@ -76,11 +76,12 @@ JSTaggedValue BuiltinsStringIterator::Next(EcmaRuntimeCallInfo *argv) // c. Else, let resultString be the string consisting of the code unit first followed by the code unit second. uint16_t second = string.GetObject()->At(position + 1); if (second < base::utf_helper::DECODE_TRAIL_LOW || second > base::utf_helper::DECODE_TRAIL_HIGH) { - std::vector resultString{first, 0x0}; - result.Update(factory->NewFromUtf16(resultString.data(), 1).GetTaggedValue()); + std::vector resultString {first, 0x0}; + result.Update(factory->NewFromUtf16UnCheck(resultString.data(), 1, false).GetTaggedValue()); } else { - std::vector resultString{first, second, 0x0}; - result.Update(factory->NewFromUtf16(resultString.data(), 2).GetTaggedValue()); // 2: two bytes + std::vector resultString {first, second, 0x0}; + result.Update( + factory->NewFromUtf16UnCheck(resultString.data(), 2, false).GetTaggedValue()); // 2: two bytes resultSize = 2; // 2: 2 means that two bytes represent a character string } } diff --git a/ecmascript/builtins/builtins_string_iterator.h b/ecmascript/builtins/builtins_string_iterator.h index 98a6c86d596a49132b1b9b6a5707500b004f9a48..32d2d59d7d7e42084db009a2267edb4342070b9d 100644 --- a/ecmascript/builtins/builtins_string_iterator.h +++ b/ecmascript/builtins/builtins_string_iterator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_STRING_ITERATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_STRING_ITERATOR_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_STRING_ITERATOR_H +#define ECMASCRIPT_BUILTINS_BUILTINS_STRING_ITERATOR_H #include "ecmascript/base/builtins_base.h" @@ -25,4 +25,4 @@ public: static JSTaggedValue Next(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_STRING_ITERATOR_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_STRING_ITERATOR_H diff --git a/ecmascript/builtins/builtins_symbol.cpp b/ecmascript/builtins/builtins_symbol.cpp index ba54f1536f9ca137fa8622ae1c436c891132b6ff..bd49902e9a1b63220b737120c366b75467e0c5d7 100644 --- a/ecmascript/builtins/builtins_symbol.cpp +++ b/ecmascript/builtins/builtins_symbol.cpp @@ -101,16 +101,16 @@ JSTaggedValue BuiltinsSymbol::SymbolDescriptiveString(JSThread *thread, JSTagged // If desc is undefined, let desc be the empty string. if (descHandle->IsUndefined()) { - JSHandle leftHandle(factory->NewFromString("Symbol(")); - JSHandle rightHandle(factory->NewFromString(")")); + JSHandle leftHandle(factory->NewFromCanBeCompressString("Symbol(")); + JSHandle rightHandle(factory->NewFromCanBeCompressString(")")); JSHandle str = factory->ConcatFromString(leftHandle, rightHandle); return str.GetTaggedValue(); } // Assert: Type(desc) is String. ASSERT(descHandle->IsString()); // Return the result of concatenating the strings "Symbol(", desc, and ")". - JSHandle leftHandle(factory->NewFromString("Symbol(")); - JSHandle rightHandle(factory->NewFromString(")")); + JSHandle leftHandle(factory->NewFromCanBeCompressString("Symbol(")); + JSHandle rightHandle(factory->NewFromCanBeCompressString(")")); JSHandle stringLeft = factory->ConcatFromString(leftHandle, JSTaggedValue::ToString(thread, descHandle)); JSHandle str = factory->ConcatFromString(stringLeft, rightHandle); diff --git a/ecmascript/builtins/builtins_symbol.h b/ecmascript/builtins/builtins_symbol.h index 8f22b62b2744be9d9c68c0ec76df129de341ae65..cc5be06ed7822881abe1ecf97b8ee121e71cea18 100644 --- a/ecmascript/builtins/builtins_symbol.h +++ b/ecmascript/builtins/builtins_symbol.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_SYMBOL_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_SYMBOL_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_SYMBOL_H +#define ECMASCRIPT_BUILTINS_BUILTINS_SYMBOL_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -47,4 +47,4 @@ public: static JSTaggedValue SymbolDescriptiveString(JSThread *thread, JSTaggedValue sym); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_SYMBOL_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_SYMBOL_H diff --git a/ecmascript/builtins/builtins_typedarray.cpp b/ecmascript/builtins/builtins_typedarray.cpp index 24718e3e48bb83510cce28f3f4b451e094c1ba8d..9aaa5e38c347bea7bc5e682ae65d4e357d0e4369 100644 --- a/ecmascript/builtins/builtins_typedarray.cpp +++ b/ecmascript/builtins/builtins_typedarray.cpp @@ -22,6 +22,7 @@ #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/ecma_string.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_array.h" #include "ecmascript/js_array_iterator.h" #include "ecmascript/js_function.h" @@ -29,6 +30,7 @@ #include "ecmascript/js_iterator.h" #include "ecmascript/js_tagged_number.h" #include "ecmascript/js_tagged_value-inl.h" +#include "ecmascript/js_typed_array.h" #include "ecmascript/object_factory.h" namespace panda::ecmascript::builtins { @@ -116,7 +118,6 @@ JSTaggedValue BuiltinsTypedArray::From(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), TypedArray, From); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); // 1. Let C be the this value. // 2. If IsConstructor(C) is false, throw a TypeError exception. @@ -153,8 +154,6 @@ JSTaggedValue BuiltinsTypedArray::From(EcmaRuntimeCallInfo *argv) // a. Let values be ? IterableToList(source, usingIterator). // b. Let len be the number of elements in values. // c. Let targetObj be ? TypedArrayCreate(C, « len »). - array_size_t length = 2; - JSHandle msg = factory->NewTaggedArray(length); if (!usingIterator->IsUndefined()) { CVector> vec; JSHandle iterator = JSIterator::GetIterator(thread, source, usingIterator); @@ -170,10 +169,9 @@ JSTaggedValue BuiltinsTypedArray::From(EcmaRuntimeCallInfo *argv) } } int32_t len = vec.size(); - array_size_t arrayLength = 1; - JSHandle array = factory->NewTaggedArray(arrayLength); - array->Set(thread, 0, JSTaggedValue(len)); - JSHandle targetObj = TypedArrayHelper::TypedArrayCreate(thread, thisHandle, array); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(len)); + JSHandle targetObj = TypedArrayHelper::TypedArrayCreate(thread, thisHandle, 1, arguments->GetArgv()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // d. Let k be 0. // e. Repeat, while k < len @@ -188,17 +186,17 @@ JSTaggedValue BuiltinsTypedArray::From(EcmaRuntimeCallInfo *argv) JSMutableHandle mapValue(thread, JSTaggedValue::Undefined()); double k = 0; while (k < len) { + tKey.Update(JSTaggedValue(k)); JSHandle kValue = vec[k]; if (mapping) { - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - JSTaggedValue callResult = JSFunction::Call(thread, mapfn, thisArgHandle, msg); + arguments->MakeArgv(kValue, tKey); + JSTaggedValue callResult = + JSFunction::Call(thread, mapfn, thisArgHandle, 2, arguments->GetArgv()); // 2: two args RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); mapValue.Update(callResult); } else { mapValue.Update(kValue.GetTaggedValue()); } - tKey.Update(JSTaggedValue(k)); JSHandle kKey(JSTaggedValue::ToString(thread, tKey)); JSTaggedValue::SetProperty(thread, JSHandle::Cast(targetObj), kKey, mapValue, true); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -223,11 +221,10 @@ JSTaggedValue BuiltinsTypedArray::From(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); double len = tLen.GetNumber(); - array_size_t arrayLen = 1; // 10. Let targetObj be ? TypedArrayCreate(C, « len »). - JSHandle array = factory->NewTaggedArray(arrayLen); - array->Set(thread, 0, JSTaggedValue(len)); - JSHandle targetObj = TypedArrayHelper::TypedArrayCreate(thread, thisHandle, array); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(len)); + JSHandle targetObj = TypedArrayHelper::TypedArrayCreate(thread, thisHandle, 1, arguments->GetArgv()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 11. Let k be 0. // 12. Repeat, while k < len @@ -247,9 +244,9 @@ JSTaggedValue BuiltinsTypedArray::From(EcmaRuntimeCallInfo *argv) RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); JSHandle mapValue; if (mapping) { - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - JSTaggedValue callResult = JSFunction::Call(thread, mapfn, thisArgHandle, msg); + arguments->MakeArgv(kValue, tKey); + JSTaggedValue callResult = + JSFunction::Call(thread, mapfn, thisArgHandle, 2, arguments->GetArgv()); // 2: two args RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); mapValue = JSHandle(thread, callResult); } else { @@ -270,7 +267,6 @@ JSTaggedValue BuiltinsTypedArray::Of(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), TypedArray, Of); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let len be the actual number of arguments passed to this function. array_size_t len = argv->GetArgsNumber(); // 2. Let items be the List of arguments passed to this function. @@ -281,10 +277,9 @@ JSTaggedValue BuiltinsTypedArray::Of(EcmaRuntimeCallInfo *argv) THROW_TYPE_ERROR_AND_RETURN(thread, "the this value is not a Constructor.", JSTaggedValue::Exception()); } // 5. Let newObj be TypedArrayCreate(C, « len »). - array_size_t length = 1; - JSHandle array = factory->NewTaggedArray(length); - array->Set(thread, 0, JSTaggedValue(len)); - JSHandle newObj = TypedArrayHelper::TypedArrayCreate(thread, thisHandle, array); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(len)); + JSHandle newObj = TypedArrayHelper::TypedArrayCreate(thread, thisHandle, 1, arguments->GetArgv()); // 6. ReturnIfAbrupt(newObj). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 7. Let k be 0. @@ -336,7 +331,7 @@ JSTaggedValue BuiltinsTypedArray::GetBuffer(EcmaRuntimeCallInfo *argv) JSTaggedValue::Exception()); } // 4. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. - JSTaggedValue buffer = TypedArrayHelper::GetViewedArrayBuffer(JSHandle(thisHandle)); + JSTaggedValue buffer = JSHandle::Cast(thisHandle)->GetViewedArrayBuffer(); // 5. Return buffer. return buffer; } @@ -360,15 +355,14 @@ JSTaggedValue BuiltinsTypedArray::GetByteLength(EcmaRuntimeCallInfo *argv) JSTaggedValue::Exception()); } // 4. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. - JSTaggedValue buffer = TypedArrayHelper::GetViewedArrayBuffer(JSHandle(thisHandle)); + JSTaggedValue buffer = JSHandle::Cast(thisHandle)->GetViewedArrayBuffer(); // 5. If IsDetachedBuffer(buffer) is true, return 0. if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { return JSTaggedValue(0); } // 6. Let size be the value of O’s [[ByteLength]] internal slot. - int32_t size = TypedArrayHelper::GetByteLength(thread, JSHandle(thisHandle)); // 7. Return size. - return JSTaggedValue(size); + return JSHandle(thisHandle)->GetByteLength(); } // 22.2.3.3 @@ -390,7 +384,7 @@ JSTaggedValue BuiltinsTypedArray::GetByteOffset(EcmaRuntimeCallInfo *argv) JSTaggedValue::Exception()); } // 4. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. - JSTaggedValue buffer = TypedArrayHelper::GetViewedArrayBuffer(JSHandle(thisHandle)); + JSTaggedValue buffer = JSHandle::Cast(thisHandle)->GetViewedArrayBuffer(); // 5. If IsDetachedBuffer(buffer) is true, return 0. if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { return JSTaggedValue(0); @@ -439,7 +433,6 @@ JSTaggedValue BuiltinsTypedArray::Every(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), TypedArray, Every); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); @@ -477,17 +470,17 @@ JSTaggedValue BuiltinsTypedArray::Every(EcmaRuntimeCallInfo *argv) // iv. ReturnIfAbrupt(testResult). // v. If testResult is false, return false. // e. Increase k by 1. - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + InternalCallParams *arguments = thread->GetInternalCallParams(); int32_t k = 0; while (k < len) { RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); JSHandle kValue = JSTaggedValue::GetProperty(thread, thisObjVal, k).GetValue(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - msg->Set(thread, INDEX_TWO, thisObjVal); - JSTaggedValue callResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + key.Update(JSTaggedValue(k)); + arguments->MakeArgv(kValue, key, thisObjVal); + JSTaggedValue callResult = + JSFunction::Call(thread, callbackFnHandle, thisArgHandle, 3, arguments->GetArgv()); // 3: three args RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); bool boolResult = callResult.ToBoolean(); if (!boolResult) { @@ -529,8 +522,8 @@ JSTaggedValue BuiltinsTypedArray::Filter(EcmaRuntimeCallInfo *argv) // 4. Let len be the value of O’s [[ArrayLength]] internal slot. int32_t len = TypedArrayHelper::GetArrayLength(thread, thisObj); // 5. If IsCallable(callbackfn) is false, throw a TypeError exception. - JSHandle callbackfnHandle = GetCallArg(argv, 0); - if (!callbackfnHandle->IsCallable()) { + JSHandle callbackFnHandle = GetCallArg(argv, 0); + if (!callbackFnHandle->IsCallable()) { THROW_TYPE_ERROR_AND_RETURN(thread, "the callbackfun is not callable.", JSTaggedValue::Exception()); } // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. @@ -551,30 +544,27 @@ JSTaggedValue BuiltinsTypedArray::Filter(EcmaRuntimeCallInfo *argv) // i. Append kValue to the end of kept. // ii. Increase captured by 1. // g. Increase k by 1. - int32_t capt = 0; - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); + int32_t captured = 0; JSMutableHandle tKey(thread, JSTaggedValue::Undefined()); + InternalCallParams *arguments = thread->GetInternalCallParams(); for (int32_t k = 0; k < len; k++) { tKey.Update(JSTaggedValue(k)); JSHandle kKey(JSTaggedValue::ToString(thread, tKey)); JSHandle kValue = JSTaggedValue::GetProperty(thread, thisHandle, kKey).GetValue(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - msg->Set(thread, 2, thisHandle); // 2: the third arg is this - JSTaggedValue callResult = JSFunction::Call(thread, callbackfnHandle, thisArgHandle, msg); + arguments->MakeArgv(kValue, tKey, thisHandle); + JSTaggedValue callResult = + JSFunction::Call(thread, callbackFnHandle, thisArgHandle, 3, arguments->GetArgv()); // 3: three args bool testResult = callResult.ToBoolean(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (testResult) { - kept->Set(thread, capt, kValue); - capt++; + kept->Set(thread, captured, kValue); + captured++; } } // es11 9. Let A be ? TypedArraySpeciesCreate(O, « captured »). - JSHandle argumentsList = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(1); - argumentsList->Set(thread, 0, JSTaggedValue(capt)); - JSHandle newArrObj = TypedArrayHelper::TypedArraySpeciesCreate(thread, thisObj, argumentsList); + arguments->MakeArgv(JSTaggedValue(captured)); + JSHandle newArrObj = TypedArrayHelper::TypedArraySpeciesCreate(thread, thisObj, 1, arguments->GetArgv()); // 15. ReturnIfAbrupt(A). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 16. Let n be 0. @@ -584,7 +574,7 @@ JSTaggedValue BuiltinsTypedArray::Filter(EcmaRuntimeCallInfo *argv) // c. Increment n by 1. JSMutableHandle valueHandle(thread, JSTaggedValue::Undefined()); JSMutableHandle ntKey(thread, JSTaggedValue::Undefined()); - for (int32_t n = 0; n < capt; n++) { + for (int32_t n = 0; n < captured; n++) { valueHandle.Update(kept->Get(n)); ntKey.Update(JSTaggedValue(n)); JSHandle nKey(JSTaggedValue::ToString(thread, ntKey)); @@ -622,7 +612,6 @@ JSTaggedValue BuiltinsTypedArray::ForEach(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), TypedArray, ForEach); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be ToObject(this value). JSHandle thisHandle = GetThis(argv); @@ -659,16 +648,16 @@ JSTaggedValue BuiltinsTypedArray::ForEach(EcmaRuntimeCallInfo *argv) // iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»). // iv. ReturnIfAbrupt(funcResult). // e. Increase k by 1. - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + InternalCallParams *arguments = thread->GetInternalCallParams(); int32_t k = 0; while (k < len) { JSHandle kValue = JSTaggedValue::GetProperty(thread, thisObjVal, k).GetValue(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, 0, kValue); - msg->Set(thread, 1, JSTaggedValue(k)); - msg->Set(thread, INDEX_TWO, thisObjVal); - JSTaggedValue funcResult = JSFunction::Call(thread, callbackFnHandle, thisArgHandle, msg); + key.Update(JSTaggedValue(k)); + arguments->MakeArgv(kValue, key, thisObjVal); + JSTaggedValue funcResult = + JSFunction::Call(thread, callbackFnHandle, thisArgHandle, 3, arguments->GetArgv()); // 3: three args RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult); k++; } @@ -747,7 +736,7 @@ JSTaggedValue BuiltinsTypedArray::GetLength(EcmaRuntimeCallInfo *argv) } // 4. Assert: O has [[ViewedArrayBuffer]] and [[ArrayLength]] internal slots. // 5. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. - JSTaggedValue buffer = TypedArrayHelper::GetViewedArrayBuffer(JSHandle(thisHandle)); + JSTaggedValue buffer = JSHandle::Cast(thisHandle)->GetViewedArrayBuffer(); // 6. If IsDetachedBuffer(buffer) is true, return 0. if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { return JSTaggedValue(0); @@ -765,7 +754,6 @@ JSTaggedValue BuiltinsTypedArray::Map(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), TypedArray, Map); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be the this value. JSHandle thisHandle = GetThis(argv); // 2. Let valid be ValidateTypedArray(O). @@ -784,9 +772,9 @@ JSTaggedValue BuiltinsTypedArray::Map(EcmaRuntimeCallInfo *argv) // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. JSHandle thisArgHandle = GetCallArg(argv, 1); // es11 5. Let A be ? TypedArraySpeciesCreate(O, « len »). - JSHandle argumentsList = factory->NewTaggedArray(1); - argumentsList->Set(thread, 0, JSTaggedValue(len)); - JSHandle newArrObj = TypedArrayHelper::TypedArraySpeciesCreate(thread, thisObj, argumentsList); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(len)); + JSHandle newArrObj = TypedArrayHelper::TypedArraySpeciesCreate(thread, thisObj, 1, arguments->GetArgv()); // 11. ReturnIfAbrupt(A). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -800,23 +788,18 @@ JSTaggedValue BuiltinsTypedArray::Map(EcmaRuntimeCallInfo *argv) // f. Let status be Set(A, Pk, mappedValue, true ). // g. ReturnIfAbrupt(status). // h. Increase k by 1. - array_size_t length = 3; - JSHandle msg = factory->NewTaggedArray(length); - JSMutableHandle tKey(thread, JSTaggedValue::Undefined()); - JSMutableHandle kValue(thread, JSTaggedValue::Undefined()); + JSMutableHandle key(thread, JSTaggedValue::Undefined()); JSMutableHandle mapValue(thread, JSTaggedValue::Undefined()); for (int32_t k = 0; k < len; k++) { - tKey.Update(JSTaggedValue(k)); - JSHandle kKey(JSTaggedValue::ToString(thread, tKey)); - kValue.Update(JSTaggedValue::GetProperty(thread, thisHandle, kKey).GetValue().GetTaggedValue()); + key.Update(JSTaggedValue(k)); + JSHandle kValue = JSTaggedValue::GetProperty(thread, thisHandle, key).GetValue(); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - msg->Set(thread, ArgsPosition::FIRST, kValue); - msg->Set(thread, ArgsPosition::SECOND, JSTaggedValue(k)); - msg->Set(thread, ArgsPosition::THIRD, thisHandle); - JSTaggedValue callResult = JSFunction::Call(thread, callbackfnHandle, thisArgHandle, msg); + arguments->MakeArgv(kValue, key, thisHandle); + JSTaggedValue callResult = + JSFunction::Call(thread, callbackfnHandle, thisArgHandle, 3, arguments->GetArgv()); // 3: three args mapValue.Update(callResult); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); - JSTaggedValue::SetProperty(thread, JSHandle(newArrObj), kKey, mapValue, true); + JSTaggedValue::SetProperty(thread, JSHandle(newArrObj), key, mapValue, true); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } @@ -889,7 +872,7 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) JSTaggedValue::Exception()); } // 9. Let targetBuffer be the value of target’s [[ViewedArrayBuffer]] internal slot. - JSHandle targetBuffer(thread, TypedArrayHelper::GetViewedArrayBuffer(targetObj)); + JSHandle targetBuffer(thread, JSTypedArray::Cast(*targetObj)->GetViewedArrayBuffer()); // 10. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError exception. if (BuiltinsArrayBuffer::IsDetachedBuffer(targetBuffer.GetTaggedValue())) { THROW_TYPE_ERROR_AND_RETURN(thread, "The targetBuffer of This value is detached buffer.", @@ -901,7 +884,7 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) // 14. Let targetType be the String value of the Element Type value in Table 49 for targetName. // 15. Let targetByteOffset be the value of target’s [[ByteOffset]] internal slot. int32_t targetLength = TypedArrayHelper::GetArrayLength(thread, targetObj); - JSHandle targetName = TypedArrayHelper::GetTypedArrayName(thread, targetObj); + JSHandle targetName(thread, JSTypedArray::Cast(*targetObj)->GetTypedArrayName()); int32_t targetElementSize = TypedArrayHelper::GetSizeFromName(thread, targetName); DataViewType targetType = TypedArrayHelper::GetTypeFromName(thread, targetName); int32_t targetByteOffset = TypedArrayHelper::GetByteOffset(thread, targetObj); @@ -967,7 +950,7 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) JSHandle typedArray(argArray); // 12. Let srcBuffer be the value of typedArray’s [[ViewedArrayBuffer]] internal slot. // 13. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception. - JSTaggedValue srcBuffer = TypedArrayHelper::GetViewedArrayBuffer(typedArray); + JSTaggedValue srcBuffer = JSTypedArray::Cast(*typedArray)->GetViewedArrayBuffer(); if (BuiltinsArrayBuffer::IsDetachedBuffer(srcBuffer)) { THROW_TYPE_ERROR_AND_RETURN(thread, "The ArrayBuffer of typedArray is detached buffer.", JSTaggedValue::Exception()); @@ -977,7 +960,7 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv) // 20. Let srcElementSize be the Number value of the Element Size value specified in Table 49 for srcName. // 21. Let srcLength be the value of typedArray’s [[ArrayLength]] internal slot. // 22. Let srcByteOffset be the value of typedArray’s [[ByteOffset]] internal slot. - JSHandle srcName = TypedArrayHelper::GetTypedArrayName(thread, typedArray); + JSHandle srcName(thread, JSTypedArray::Cast(*typedArray)->GetTypedArrayName()); DataViewType srcType = TypedArrayHelper::GetTypeFromName(thread, srcName); int32_t srcElementSize = TypedArrayHelper::GetSizeFromName(thread, srcName); int32_t srcLength = TypedArrayHelper::GetArrayLength(thread, typedArray); @@ -1055,7 +1038,6 @@ JSTaggedValue BuiltinsTypedArray::Slice(EcmaRuntimeCallInfo *argv) BUILTINS_API_TRACE(argv->GetThread(), TypedArray, Slice); JSThread *thread = argv->GetThread(); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1. Let O be the this value. JSHandle thisHandle = GetThis(argv); // 2. Let valid be ValidateTypedArray(O). @@ -1099,17 +1081,17 @@ JSTaggedValue BuiltinsTypedArray::Slice(EcmaRuntimeCallInfo *argv) // 11. Let count be max(final – k, 0). double count = (final - k) > 0 ? (final - k) : 0; // es11 9. Let A be ? TypedArraySpeciesCreate(O, « count »). - JSHandle argumentsList = factory->NewTaggedArray(1); - argumentsList->Set(thread, 0, JSTaggedValue(count)); - JSHandle newArrObj = TypedArrayHelper::TypedArraySpeciesCreate(thread, thisObj, argumentsList); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(count)); + JSHandle newArrObj = TypedArrayHelper::TypedArraySpeciesCreate(thread, thisObj, 1, arguments->GetArgv()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 17. Let srcName be the String value of O’s [[TypedArrayName]] internal slot. // 18. Let srcType be the String value of the Element Type value in Table 49 for srcName. - JSHandle srcName = TypedArrayHelper::GetTypedArrayName(thread, thisObj); + JSHandle srcName(thread, JSTypedArray::Cast(*thisObj)->GetTypedArrayName()); DataViewType srcType = TypedArrayHelper::GetTypeFromName(thread, srcName); // 19. Let targetName be the String value of A’s [[TypedArrayName]] internal slot. // 20. Let targetType be the String value of the Element Type value in Table 49 for targetName. - JSHandle targetName = TypedArrayHelper::GetTypedArrayName(thread, newArrObj); + JSHandle targetName(thread, JSTypedArray::Cast(*newArrObj)->GetTypedArrayName()); DataViewType targetType = TypedArrayHelper::GetTypeFromName(thread, targetName); // 21. If SameValue(srcType, targetType) is false, then // a. Let n be 0. @@ -1142,13 +1124,13 @@ JSTaggedValue BuiltinsTypedArray::Slice(EcmaRuntimeCallInfo *argv) // 22. Else if count > 0, // a. Let srcBuffer be the value of O’s [[ViewedArrayBuffer]] internal slot. // b. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception. - JSHandle srcBuffer(thread, TypedArrayHelper::GetViewedArrayBuffer(thisObj)); + JSHandle srcBuffer(thread, JSTypedArray::Cast(*thisObj)->GetViewedArrayBuffer()); if (BuiltinsArrayBuffer::IsDetachedBuffer(srcBuffer.GetTaggedValue())) { THROW_TYPE_ERROR_AND_RETURN(thread, "The ArrayBuffer of this value is detached buffer.", JSTaggedValue::Exception()); } // c. Let targetBuffer be the value of A’s [[ViewedArrayBuffer]] internal slot. - JSHandle targetBuffer(thread, TypedArrayHelper::GetViewedArrayBuffer(newArrObj)); + JSHandle targetBuffer(thread, JSTypedArray::Cast(*newArrObj)->GetViewedArrayBuffer()); // d. Let elementSize be the Number value of the Element Size value specified in Table 49 for srcType. int32_t elementSize = TypedArrayHelper::GetSizeFromName(thread, srcName); // e. NOTE: If srcType and targetType are the same the transfer must be performed in a manner that @@ -1297,20 +1279,18 @@ JSTaggedValue BuiltinsTypedArray::Subarray(EcmaRuntimeCallInfo *argv) // 15. Let elementSize be the Number value of the Element Size value specified in Table 49 for constructorName. // 16. Let srcByteOffset be the value of O’s [[ByteOffset]] internal slot. // 17. Let beginByteOffset be srcByteOffset + beginIndex × elementSize. - JSHandle constructorName = TypedArrayHelper::GetTypedArrayName(thread, thisObj); + JSHandle constructorName(thread, JSTypedArray::Cast(*thisObj)->GetTypedArrayName()); int32_t elementSize = TypedArrayHelper::GetSizeFromName(thread, constructorName); int32_t srcByteOffset = TypedArrayHelper::GetByteOffset(thread, thisObj); int32_t beginByteOffset = srcByteOffset + beginIndex * elementSize; // 21. Let argumentsList be «buffer, beginByteOffset, newLength». - JSHandle argumentsList = - thread->GetEcmaVM()->GetFactory()->NewTaggedArray(3); // 3: «buffer, beginByteOffset, newLength» // 5. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. - JSTaggedValue buffer = TypedArrayHelper::GetViewedArrayBuffer(thisObj); - argumentsList->Set(thread, 0, buffer); - argumentsList->Set(thread, 1, JSTaggedValue(beginByteOffset)); - argumentsList->Set(thread, 2, JSTaggedValue(newLength)); // 2: the third arg is newLength + JSTaggedValue buffer = JSTypedArray::Cast(*thisObj)->GetViewedArrayBuffer(); // 22. Return Construct(constructor, argumentsList). - JSHandle newArr = TypedArrayHelper::TypedArraySpeciesCreate(thread, thisObj, argumentsList); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(buffer, JSTaggedValue(beginByteOffset), JSTaggedValue(newLength)); + JSHandle newArr = + TypedArrayHelper::TypedArraySpeciesCreate(thread, thisObj, 3, arguments->GetArgv()); // 3: three args RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return newArr.GetTaggedValue(); } @@ -1373,10 +1353,10 @@ JSTaggedValue BuiltinsTypedArray::ToStringTag(EcmaRuntimeCallInfo *argv) return JSTaggedValue::Undefined(); } // 4. Let name be the value of O’s [[TypedArrayName]] internal slot. - JSHandle name = TypedArrayHelper::GetTypedArrayName(thread, JSHandle(thisHandle)); + JSTaggedValue name = JSHandle::Cast(thisHandle)->GetTypedArrayName(); // 5. Assert: name is a String value. - ASSERT(name->IsString()); + ASSERT(name.IsString()); // 6. Return name. - return name.GetTaggedValue(); + return name; } } // namespace panda::ecmascript::builtins diff --git a/ecmascript/builtins/builtins_typedarray.h b/ecmascript/builtins/builtins_typedarray.h index 1f3126199325b3fdc3154377ac2edd6f9b30ddfd..7b561298494862b7163001199e096da5a4a0b660 100644 --- a/ecmascript/builtins/builtins_typedarray.h +++ b/ecmascript/builtins/builtins_typedarray.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_TYPEDARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_TYPEDARRAY_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_TYPEDARRAY_H +#define ECMASCRIPT_BUILTINS_BUILTINS_TYPEDARRAY_H #include "ecmascript/base/builtins_base.h" @@ -105,4 +105,4 @@ public: }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_TYPEDARRAY_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_TYPEDARRAY_H diff --git a/ecmascript/builtins/builtins_weak_map.cpp b/ecmascript/builtins/builtins_weak_map.cpp index f7c7e46ea31d860207fb915706fd47a2c11fa13d..6541f8c20f0960f33597d36d91282effdb3094ba 100644 --- a/ecmascript/builtins/builtins_weak_map.cpp +++ b/ecmascript/builtins/builtins_weak_map.cpp @@ -16,6 +16,7 @@ #include "ecmascript/builtins/builtins_weak_map.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_invoker.h" #include "ecmascript/js_map_iterator.h" #include "ecmascript/js_weak_container.h" @@ -58,7 +59,7 @@ JSTaggedValue BuiltinsWeakMap::WeakMapConstructor(EcmaRuntimeCallInfo *argv) THROW_TYPE_ERROR_AND_RETURN(thread, "iterable is not object", JSTaggedValue::Exception()); } // Let adder be Get(weakMap, "set"). - JSHandle adderKey(factory->NewFromString("set")); + JSHandle adderKey(factory->NewFromCanBeCompressString("set")); JSHandle adder = JSObject::GetProperty(thread, JSHandle(weakMap), adderKey).GetValue(); // ReturnIfAbrupt(adder). @@ -83,7 +84,6 @@ JSTaggedValue BuiltinsWeakMap::WeakMapConstructor(EcmaRuntimeCallInfo *argv) JSHandle nextValue(JSIterator::IteratorValue(thread, next)); // ReturnIfAbrupt(nextValue). RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, next.GetTaggedValue()); - JSHandle array(factory->NewTaggedArray(2)); // 2: key and value pair // If Type(nextItem) is not Object if (!nextValue->IsECMAObject()) { JSHandle typeError = factory->GetJSError(ErrorType::TYPE_ERROR, "nextItem is not Object"); @@ -101,7 +101,7 @@ JSTaggedValue BuiltinsWeakMap::WeakMapConstructor(EcmaRuntimeCallInfo *argv) if (thread->HasPendingException()) { return JSIterator::IteratorCloseAndReturn(thread, iter, key); } - array->Set(thread, 0, key); + // Let v be Get(nextItem, "1"). JSHandle value = JSObject::GetProperty(thread, nextValue, valueIndex).GetValue(); // If v is an abrupt completion, return IteratorClose(iter, v). @@ -109,9 +109,11 @@ JSTaggedValue BuiltinsWeakMap::WeakMapConstructor(EcmaRuntimeCallInfo *argv) return JSIterator::IteratorCloseAndReturn(thread, iter, value); } - array->Set(thread, 1, value); // Let status be Call(adder, weakMap, «nextValue.[[value]]»). - JSTaggedValue ret = JSFunction::Call(thread, adder, JSHandle(weakMap), array); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(key, value); + JSTaggedValue ret = JSFunction::Call(thread, + adder, JSHandle(weakMap), 2, arguments->GetArgv()); // 2: key and value pair status.Update(ret); // If status is an abrupt completion, return IteratorClose(iter, status). diff --git a/ecmascript/builtins/builtins_weak_map.h b/ecmascript/builtins/builtins_weak_map.h index 89e9031d84ba4819ed7574a5387c7bb2ab14219c..24363cf767ec03a365b331a70898cc94b0f09010 100644 --- a/ecmascript/builtins/builtins_weak_map.h +++ b/ecmascript/builtins/builtins_weak_map.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_WEAK_MAP_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_WEAK_MAP_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_WEAK_MAP_H +#define ECMASCRIPT_BUILTINS_BUILTINS_WEAK_MAP_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -35,4 +35,4 @@ public: // 23.1.3.6 @@toStringTag }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_MAP_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_MAP_H diff --git a/ecmascript/builtins/builtins_weak_set.cpp b/ecmascript/builtins/builtins_weak_set.cpp index 90fb697b2abe52f49182adff6a95307a63ca481c..814e746aeaf1847775d60526b530c24b946740be 100644 --- a/ecmascript/builtins/builtins_weak_set.cpp +++ b/ecmascript/builtins/builtins_weak_set.cpp @@ -16,6 +16,7 @@ #include "builtins_weak_set.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_invoker.h" #include "ecmascript/js_set_iterator.h" #include "ecmascript/js_weak_container.h" @@ -56,7 +57,7 @@ JSTaggedValue BuiltinsWeakSet::WeakSetConstructor(EcmaRuntimeCallInfo *argv) return weakSet.GetTaggedValue(); } // Let adder be Get(weakset, "add"). - JSHandle adderKey(factory->NewFromString("add")); + JSHandle adderKey(factory->NewFromCanBeCompressString("add")); JSHandle weakSetHandle(weakSet); JSHandle adder = JSObject::GetProperty(thread, weakSetHandle, adderKey).GetValue(); // ReturnIfAbrupt(adder). @@ -82,13 +83,14 @@ JSTaggedValue BuiltinsWeakSet::WeakSetConstructor(EcmaRuntimeCallInfo *argv) JSHandle nextValue(JSIterator::IteratorValue(thread, next)); // ReturnIfAbrupt(nextValue). RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, nextValue.GetTaggedValue()); - JSHandle array(factory->NewTaggedArray(1)); - array->Set(thread, 0, nextValue); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(nextValue); if (nextValue->IsArray(thread)) { auto prop = JSObject::GetProperty(thread, nextValue, valueIndex).GetValue(); - array->Set(thread, 0, prop); + arguments->MakeArgv(prop); } - JSTaggedValue ret = JSFunction::Call(thread, adder, JSHandle(weakSet), array); + JSTaggedValue ret = JSFunction::Call(thread, adder, JSHandle(weakSet), 1, arguments->GetArgv()); + // Let status be Call(adder, weakset, «nextValue.[[value]]»). status.Update(ret); // If status is an abrupt completion, return IteratorClose(iter, status). diff --git a/ecmascript/builtins/builtins_weak_set.h b/ecmascript/builtins/builtins_weak_set.h index bc8a8166ecfd0d67ec4d4299b42199ac403e2c78..767a992102772d1c665c12ec7176bc2fe5211b08 100644 --- a/ecmascript/builtins/builtins_weak_set.h +++ b/ecmascript/builtins/builtins_weak_set.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_BUILTINS_WEAK_SET_H -#define PANDA_RUNTIME_ECMASCRIPT_BUILTINS_WEAK_SET_H +#ifndef ECMASCRIPT_BUILTINS_BUILTINS_WEAK_SET_H +#define ECMASCRIPT_BUILTINS_BUILTINS_WEAK_SET_H #include "ecmascript/base/builtins_base.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -32,4 +32,4 @@ public: static JSTaggedValue Has(EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript::builtins -#endif // PANDA_RUNTIME_ECMASCRIPT_BUILTINS_SET_H +#endif // ECMASCRIPT_BUILTINS_BUILTINS_SET_H diff --git a/ecmascript/builtins/tests/builtins_array_test.cpp b/ecmascript/builtins/tests/builtins_array_test.cpp index 64967fe0a8a16e0234eba5dc22b556d4687792d0..0e9a9c1e359d1cfab1088d8e2422b87f7fbc05a0 100644 --- a/ecmascript/builtins/tests/builtins_array_test.cpp +++ b/ecmascript/builtins/tests/builtins_array_test.cpp @@ -157,7 +157,7 @@ JSTaggedValue CreateBuiltinsJSObject(JSThread *thread, const CString keyCStr) ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle obj(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); - JSHandle key(factory->NewFromString(&keyCStr[0])); + JSHandle key(factory->NewFromCanBeCompressString(&keyCStr[0])); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, obj, key, value); return obj.GetTaggedValue(); @@ -1255,7 +1255,7 @@ HWTEST_F_L0(BuiltinsArrayTest, Join) PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(4))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key2, desc2); - JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromString("2,3,4"); + JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2,3,4"); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); @@ -1287,7 +1287,7 @@ HWTEST_F_L0(BuiltinsArrayTest, ToString) PropertyDescriptor desc2(thread, JSHandle(thread, JSTaggedValue(4))); JSArray::DefineOwnProperty(thread, JSHandle(obj), key2, desc2); - JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromString("2,3,4"); + JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2,3,4"); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue()); diff --git a/ecmascript/builtins/tests/builtins_boolean_test.cpp b/ecmascript/builtins/tests/builtins_boolean_test.cpp index 5163a403fd6d97166752e3e46faf1ac580ab8d52..c080884c4f2549507205db400b49ffbbdb0fbe5e 100644 --- a/ecmascript/builtins/tests/builtins_boolean_test.cpp +++ b/ecmascript/builtins/tests/builtins_boolean_test.cpp @@ -59,7 +59,6 @@ public: // new Boolean(123) HWTEST_F_L0(BuiltinsBooleanTest, BooleanConstructor) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle boolean(env->GetBooleanFunction()); @@ -80,7 +79,6 @@ HWTEST_F_L0(BuiltinsBooleanTest, BooleanConstructor) // new Boolean(undefined) HWTEST_F_L0(BuiltinsBooleanTest, BooleanConstructor1) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle boolean(env->GetBooleanFunction()); @@ -101,12 +99,11 @@ HWTEST_F_L0(BuiltinsBooleanTest, BooleanConstructor1) // Boolean("helloworld") HWTEST_F_L0(BuiltinsBooleanTest, BooleanConstructor2) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle boolean(env->GetBooleanFunction()); JSHandle globalObject(thread, env->GetGlobalObject()); - JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromString("helloworld"); + JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("helloworld"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(boolean.GetTaggedValue()); @@ -123,8 +120,6 @@ HWTEST_F_L0(BuiltinsBooleanTest, BooleanConstructor2) // false.toString() HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeToString) { - ASSERT_NE(thread, nullptr); - auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::False()); @@ -133,14 +128,13 @@ HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeToString) JSTaggedValue result = BuiltinsBoolean::BooleanPrototypeToString(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); - auto ruler = thread->GetEcmaVM()->GetFactory()->NewFromString("false"); + auto ruler = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("false"); ASSERT_EQ(res->Compare(*ruler), 0); } // (new Boolean(true)).toString() HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeToString1) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -156,15 +150,13 @@ HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeToString1) JSTaggedValue result = BuiltinsBoolean::BooleanPrototypeToString(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); - auto ruler = thread->GetEcmaVM()->GetFactory()->NewFromString("true"); + auto ruler = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("true"); ASSERT_EQ(res->Compare(*ruler), 0); } // true.valueOf() HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeValueOf) { - ASSERT_NE(thread, nullptr); - auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::True()); @@ -179,7 +171,6 @@ HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeValueOf) // (new Boolean(false)).valueOf() HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeValueOf1) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); diff --git a/ecmascript/builtins/tests/builtins_date_test.cpp b/ecmascript/builtins/tests/builtins_date_test.cpp index eff692581f85002de8adff766c846dac19ed9235..dc1a2517d21af30ee8b4a20a474aa9d522026988 100644 --- a/ecmascript/builtins/tests/builtins_date_test.cpp +++ b/ecmascript/builtins/tests/builtins_date_test.cpp @@ -649,9 +649,9 @@ void SetAll2(JSThread *thread, const JSHandle &jsDate) auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(jsDate.GetTaggedValue()); - ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast(1901))); // 1901 : test case + ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast(1901))); // 1901 : test case ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast(0))); - ecmaRuntimeCallInfo->SetCallArg(2, JSTaggedValue(static_cast(1))); // 2 : test case + ecmaRuntimeCallInfo->SetCallArg(2, JSTaggedValue(static_cast(1))); // 2 : test case [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get()); BuiltinsDate::SetFullYear(ecmaRuntimeCallInfo.get()); @@ -662,9 +662,9 @@ void SetAll2(JSThread *thread, const JSHandle &jsDate) ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(jsDate.GetTaggedValue()); ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast(0))); - ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(3))); // 3 : test case - ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast(21))); // 2, 21 : test case - ecmaRuntimeCallInfo1->SetCallArg(3, JSTaggedValue(static_cast(129))); // 3, 129 : test case + ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast(3))); // 3 : test case + ecmaRuntimeCallInfo1->SetCallArg(2, JSTaggedValue(static_cast(21))); // 2, 21 : test case + ecmaRuntimeCallInfo1->SetCallArg(3, JSTaggedValue(static_cast(129))); // 3, 129 : test case prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1.get()); BuiltinsDate::SetHours(ecmaRuntimeCallInfo1.get()); @@ -673,7 +673,8 @@ void SetAll2(JSThread *thread, const JSHandle &jsDate) HWTEST_F_L0(BuiltinsDateTest, parse) { - JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromString("2020-11-19T12:18:18.132Z"); + JSHandle str = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2020-11-19T12:18:18.132Z"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -683,7 +684,7 @@ HWTEST_F_L0(BuiltinsDateTest, parse) JSTaggedValue result1 = BuiltinsDate::Parse(ecmaRuntimeCallInfo.get()); ASSERT_EQ(result1.GetRawData(), JSTaggedValue(static_cast(1605788298132)).GetRawData()); - JSHandle str1 = thread->GetEcmaVM()->GetFactory()->NewFromString("2020-11-19Z"); + JSHandle str1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2020-11-19Z"); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined()); @@ -694,7 +695,8 @@ HWTEST_F_L0(BuiltinsDateTest, parse) TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result1.GetRawData(), JSTaggedValue(static_cast(1605744000000)).GetRawData()); - JSHandle str2 = thread->GetEcmaVM()->GetFactory()->NewFromString("2020-11T12:18:17.231+08:00"); + JSHandle str2 = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2020-11T12:18:17.231+08:00"); auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo2->SetThis(JSTaggedValue::Undefined()); @@ -705,7 +707,8 @@ HWTEST_F_L0(BuiltinsDateTest, parse) TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result1.GetRawData(), JSTaggedValue(static_cast(1604204297231)).GetRawData()); - JSHandle str3 = thread->GetEcmaVM()->GetFactory()->NewFromString("Thu Nov 19 2020 20:18:18 GMT+0800"); + JSHandle str3 = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Thu Nov 19 2020 20:18:18 GMT+0800"); auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo3->SetThis(JSTaggedValue::Undefined()); @@ -716,7 +719,8 @@ HWTEST_F_L0(BuiltinsDateTest, parse) TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result1.GetRawData(), JSTaggedValue(static_cast(1605788298000)).GetRawData()); - JSHandle str4 = thread->GetEcmaVM()->GetFactory()->NewFromString("Thu 03 Jun 2093 04:18 GMT"); + JSHandle str4 = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Thu 03 Jun 2093 04:18 GMT"); auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo4->SetThis(JSTaggedValue::Undefined()); @@ -740,7 +744,8 @@ HWTEST_F_L0(BuiltinsDateTest, parse) HWTEST_F_L0(BuiltinsDateTest, ToDateString) { - JSHandle expect_value = thread->GetEcmaVM()->GetFactory()->NewFromString("Tue Nov 06 2018"); + JSHandle expect_value = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Tue Nov 06 2018"); JSHandle jsDate = JSDateCreateTest(thread); SetAllYearAndHours(thread, jsDate); @@ -758,7 +763,8 @@ HWTEST_F_L0(BuiltinsDateTest, ToDateString) HWTEST_F_L0(BuiltinsDateTest, ToISOString) { - JSHandle expect_value = thread->GetEcmaVM()->GetFactory()->NewFromString("2020-11-19T12:18:18.132Z"); + JSHandle expect_value = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2020-11-19T12:18:18.132Z"); JSHandle jsDate = JSDateCreateTest(thread); JSDate::Cast(jsDate.GetTaggedValue().GetTaggedObject())->SetTimeValue(thread, JSTaggedValue(1605788298132.0)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); @@ -774,7 +780,8 @@ HWTEST_F_L0(BuiltinsDateTest, ToISOString) HWTEST_F_L0(BuiltinsDateTest, ToISOStringMinus) { - JSHandle expect_value = thread->GetEcmaVM()->GetFactory()->NewFromString("1831-12-02T21:47:18.382Z"); + JSHandle expect_value = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1831-12-02T21:47:18.382Z"); JSHandle jsDate = JSDateCreateTest(thread); JSDate::Cast(jsDate.GetTaggedValue().GetTaggedObject())->SetTimeValue(thread, JSTaggedValue(-4357419161618.0)); @@ -792,7 +799,8 @@ HWTEST_F_L0(BuiltinsDateTest, ToISOStringMinus) // test toJSON and toPrimitive HWTEST_F_L0(BuiltinsDateTest, ToJSON) { - JSHandle expect_value = thread->GetEcmaVM()->GetFactory()->NewFromString("2020-11-19T12:18:18.132Z"); + JSHandle expect_value = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2020-11-19T12:18:18.132Z"); JSHandle jsDate = JSDateCreateTest(thread); jsDate->SetTimeValue(thread, JSTaggedValue(1605788298132.0)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); @@ -808,7 +816,8 @@ HWTEST_F_L0(BuiltinsDateTest, ToJSON) HWTEST_F_L0(BuiltinsDateTest, ToJSONMinus) { - JSHandle expect_value = thread->GetEcmaVM()->GetFactory()->NewFromString("1831-12-02T21:47:18.382Z"); + JSHandle expect_value = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1831-12-02T21:47:18.382Z"); JSHandle jsDate = JSDateCreateTest(thread); jsDate->SetTimeValue(thread, JSTaggedValue(-4357419161618.0)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); @@ -853,7 +862,7 @@ HWTEST_F_L0(BuiltinsDateTest, ToString) TestHelper::TearDownFrame(thread, prev); JSHandle result1_val(thread, reinterpret_cast(result1.GetRawData())); CString str = "Tue Nov 06 2018 18:10:06 GMT" + localTime; - JSHandle str_handle = thread->GetEcmaVM()->GetFactory()->NewFromString(str); + JSHandle str_handle = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str); ASSERT_TRUE(EcmaString::StringsAreEqual(*result1_val, *str_handle)); JSHandle js_date1 = JSDateCreateTest(thread); @@ -883,7 +892,7 @@ HWTEST_F_L0(BuiltinsDateTest, ToString) TestHelper::TearDownFrame(thread, prev); JSHandle result2_val(thread, reinterpret_cast(result2.GetRawData())); str = "Mon Dec 31 1900 23:54:16 GMT" + localTime; - str_handle = thread->GetEcmaVM()->GetFactory()->NewFromString(str); + str_handle = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str); ASSERT_TRUE(EcmaString::StringsAreEqual(*result2_val, *str_handle)); JSHandle js_date2 = JSDateCreateTest(thread); @@ -913,7 +922,7 @@ HWTEST_F_L0(BuiltinsDateTest, ToString) TestHelper::TearDownFrame(thread, prev); JSHandle result3_val(thread, reinterpret_cast(result3.GetRawData())); str = "Tue Jan 01 1901 00:03:21 GMT" + localTime; - str_handle = thread->GetEcmaVM()->GetFactory()->NewFromString(str); + str_handle = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str); ASSERT_TRUE(EcmaString::StringsAreEqual(*result3_val, *str_handle)); } @@ -948,7 +957,7 @@ HWTEST_F_L0(BuiltinsDateTest, ToTimeString) ASSERT_TRUE(result1.IsString()); JSHandle result1_val(thread, reinterpret_cast(result1.GetRawData())); CString str = "18:10:06 GMT" + localTime; - JSHandle str_handle = thread->GetEcmaVM()->GetFactory()->NewFromString(str); + JSHandle str_handle = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str); ASSERT_TRUE(EcmaString::StringsAreEqual(*result1_val, *str_handle)); JSHandle js_date1 = JSDateCreateTest(thread); @@ -976,7 +985,7 @@ HWTEST_F_L0(BuiltinsDateTest, ToTimeString) ASSERT_TRUE(result2.IsString()); JSHandle result2_val(thread, reinterpret_cast(result2.GetRawData())); str = "23:54:16 GMT" + localTime; - str_handle = thread->GetEcmaVM()->GetFactory()->NewFromString(str); + str_handle = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str); ASSERT_TRUE(EcmaString::StringsAreEqual(*result2_val, *str_handle)); JSHandle js_date2 = JSDateCreateTest(thread); auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); @@ -1003,14 +1012,14 @@ HWTEST_F_L0(BuiltinsDateTest, ToTimeString) ASSERT_TRUE(result3.IsString()); JSHandle result3_val(thread, reinterpret_cast(result3.GetRawData())); str = "00:03:21 GMT" + localTime; - str_handle = thread->GetEcmaVM()->GetFactory()->NewFromString(str); + str_handle = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str); ASSERT_TRUE(EcmaString::StringsAreEqual(*result3_val, *str_handle)); } HWTEST_F_L0(BuiltinsDateTest, ToUTCString) { JSHandle expect_value = - thread->GetEcmaVM()->GetFactory()->NewFromString("Thu, 19 Nov 2020 12:18:18 GMT"); + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Thu, 19 Nov 2020 12:18:18 GMT"); JSHandle jsDate = JSDateCreateTest(thread); JSDate::Cast(jsDate.GetTaggedValue().GetTaggedObject())->SetTimeValue(thread, JSTaggedValue(1605788298132.0)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); @@ -1026,7 +1035,7 @@ HWTEST_F_L0(BuiltinsDateTest, ToUTCString) HWTEST_F_L0(BuiltinsDateTest, ToUTCStringMinus) { JSHandle expect_value = - thread->GetEcmaVM()->GetFactory()->NewFromString("Fri, 02 Dec 1831 21:47:18 GMT"); + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Fri, 02 Dec 1831 21:47:18 GMT"); JSHandle jsDate = JSDateCreateTest(thread); JSDate::Cast(jsDate.GetTaggedValue().GetTaggedObject())->SetTimeValue(thread, JSTaggedValue(-4357419161618.0)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); diff --git a/ecmascript/builtins/tests/builtins_errors_test.cpp b/ecmascript/builtins/tests/builtins_errors_test.cpp index 0c2d58cd400c58302aead4416a817378048fcb68..3fb168ec2dde2c84dfa0ad8a789608195a251c3b 100644 --- a/ecmascript/builtins/tests/builtins_errors_test.cpp +++ b/ecmascript/builtins/tests/builtins_errors_test.cpp @@ -83,7 +83,7 @@ HWTEST_F_L0(BuiltinsErrorsTest, GetJSErrorObject) ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle handleObj = factory->GetJSError(ErrorType::TYPE_ERROR); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); /** @@ -93,14 +93,14 @@ HWTEST_F_L0(BuiltinsErrorsTest, GetJSErrorObject) JSObject::GetProperty(thread, JSHandle(handleObj), msgKey).GetValue()); EXPECT_EQ(reinterpret_cast(msgValue->GetRawData()) ->Compare(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("")).GetRawData())), + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("")).GetRawData())), 0); JSHandle nameValue( JSObject::GetProperty(thread, JSHandle(handleObj), nameKey).GetValue()); - ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("TypeError")).GetRawData()) - ->Compare(reinterpret_cast(nameValue->GetRawData())), - 0); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("TypeError")).GetRawData()) + ->Compare(reinterpret_cast(nameValue->GetRawData())), + 0); } /* @@ -113,20 +113,20 @@ HWTEST_F_L0(BuiltinsErrorsTest, GetJSErrorWithMessage) ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle handleObj = factory->GetJSError(ErrorType::TYPE_ERROR, "I am type error"); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue( JSObject::GetProperty(thread, JSHandle(handleObj), msgKey).GetValue()); ASSERT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("I am type error")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("I am type error")).GetRawData()) ->Compare(reinterpret_cast(msgValue->GetRawData())), 0); JSHandle nameValue( JSObject::GetProperty(thread, JSHandle(handleObj), nameKey).GetValue()); - ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("TypeError")).GetRawData()) - ->Compare(reinterpret_cast(nameValue->GetRawData())), - 0); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("TypeError")).GetRawData()) + ->Compare(reinterpret_cast(nameValue->GetRawData())), + 0); } /* @@ -136,8 +136,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, GetJSErrorWithMessage) */ HWTEST_F_L0(BuiltinsErrorsTest, ErrorNoParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -153,16 +151,18 @@ HWTEST_F_L0(BuiltinsErrorsTest, ErrorNoParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); - ASSERT_EQ(reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("")).GetRawData()) - ->Compare(reinterpret_cast(msgValue->GetRawData())), - 0); + ASSERT_EQ( + reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("")).GetRawData()) + ->Compare(reinterpret_cast(msgValue->GetRawData())), + 0); JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); - ASSERT_EQ(reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("Error")).GetRawData()) + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Error")).GetRawData()) ->Compare(reinterpret_cast(nameValue->GetRawData())), 0); } @@ -174,13 +174,11 @@ HWTEST_F_L0(BuiltinsErrorsTest, ErrorNoParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, ErrorParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle error(env->GetErrorFunction()); - JSHandle paramMsg(factory->NewFromString("Hello Error!")); + JSHandle paramMsg(factory->NewFromCanBeCompressString("Hello Error!")); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*error), 6); ecmaRuntimeCallInfo->SetFunction(error.GetTaggedValue()); @@ -193,17 +191,18 @@ HWTEST_F_L0(BuiltinsErrorsTest, ErrorParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); - ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("Hello Error!")).GetRawData()) - ->Compare(reinterpret_cast(msgValue->GetRawData())), - 0); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Hello Error!")).GetRawData()) + ->Compare(reinterpret_cast(msgValue->GetRawData())), + 0); JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); - ASSERT_EQ(reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("Error")).GetRawData()) + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Error")).GetRawData()) ->Compare(reinterpret_cast(nameValue->GetRawData())), 0); } @@ -215,8 +214,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, ErrorParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, ErrorNoParameterToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -232,7 +229,8 @@ HWTEST_F_L0(BuiltinsErrorsTest, ErrorNoParameterToString) JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ(reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("Error")).GetRawData()) + EXPECT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Error")).GetRawData()) ->Compare(reinterpret_cast(*resultHandle)), 0); } @@ -244,17 +242,16 @@ HWTEST_F_L0(BuiltinsErrorsTest, ErrorNoParameterToString) */ HWTEST_F_L0(BuiltinsErrorsTest, ErrorToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle errorObject = env->GetErrorFunction(); JSHandle error = factory->NewJSObjectByConstructor(JSHandle(errorObject), errorObject); - JSHandle handleMsgKey(factory->NewFromString("message")); - JSObject::SetProperty(thread, JSHandle(error), handleMsgKey, - JSHandle(thread, factory->NewFromString("This is Error!").GetTaggedValue())); + JSHandle handleMsgKey(factory->NewFromCanBeCompressString("message")); + JSObject::SetProperty( + thread, JSHandle(error), handleMsgKey, + JSHandle(thread, factory->NewFromCanBeCompressString("This is Error!").GetTaggedValue())); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -266,7 +263,7 @@ HWTEST_F_L0(BuiltinsErrorsTest, ErrorToString) JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); EXPECT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("Error: This is Error!")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Error: This is Error!")).GetRawData()) ->Compare(*resultHandle), 0); } @@ -278,8 +275,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, ErrorToString) */ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorNoParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -295,18 +290,19 @@ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorNoParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); - ASSERT_EQ(reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("")).GetRawData()) - ->Compare(reinterpret_cast(JSTaggedValue(msgValue.GetTaggedValue()).GetRawData())), - 0); - JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("RangeError")).GetRawData()) - ->Compare(reinterpret_cast(JSTaggedValue(nameValue.GetTaggedValue()).GetRawData())), + reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("")).GetRawData()) + ->Compare(reinterpret_cast(JSTaggedValue(msgValue.GetTaggedValue()).GetRawData())), 0); + JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("RangeError")).GetRawData()) + ->Compare(reinterpret_cast(JSTaggedValue(nameValue.GetTaggedValue()).GetRawData())), + 0); } /* @@ -316,13 +312,11 @@ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorNoParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle error(env->GetRangeErrorFunction()); - JSHandle paramMsg(factory->NewFromString("Hello RangeError!")); + JSHandle paramMsg(factory->NewFromCanBeCompressString("Hello RangeError!")); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*error), 6); ecmaRuntimeCallInfo->SetFunction(error.GetTaggedValue()); @@ -335,20 +329,20 @@ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); ASSERT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("Hello RangeError!")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Hello RangeError!")).GetRawData()) ->Compare(reinterpret_cast(msgValue->GetRawData())), 0); JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); - ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("RangeError")).GetRawData()) - ->Compare(reinterpret_cast(nameValue->GetRawData())), - 0); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("RangeError")).GetRawData()) + ->Compare(reinterpret_cast(nameValue->GetRawData())), + 0); } /* @@ -358,8 +352,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorNoParameterToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -376,10 +368,10 @@ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorNoParameterToString) EXPECT_TRUE(result.IsString()); - EXPECT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("RangeError")).GetRawData()) - ->Compare(reinterpret_cast(resultHandle->GetRawData())), - 0); + EXPECT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("RangeError")).GetRawData()) + ->Compare(reinterpret_cast(resultHandle->GetRawData())), + 0); } /* @@ -389,17 +381,15 @@ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorNoParameterToString) */ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle errorObject = env->GetRangeErrorFunction(); JSHandle error = factory->NewJSObjectByConstructor(JSHandle(errorObject), errorObject); - JSHandle handleMsgKey(factory->NewFromString("message")); + JSHandle handleMsgKey(factory->NewFromCanBeCompressString("message")); JSObject::SetProperty(thread, JSHandle(error), handleMsgKey, - JSHandle(factory->NewFromString("This is RangeError!"))); + JSHandle(factory->NewFromCanBeCompressString("This is RangeError!"))); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -410,9 +400,10 @@ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorToString) JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ(factory->NewFromString("RangeError: This is RangeError!")->Compare(*resultHandle), 0); + EXPECT_EQ(factory->NewFromCanBeCompressString("RangeError: This is RangeError!")->Compare(*resultHandle), 0); } +// new ReferenceError() /* * @tc.name: ReferenceErrorNoParameterConstructor * @tc.desc: new ReferenceError() @@ -420,8 +411,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, RangeErrorToString) */ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorNoParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -436,17 +425,18 @@ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorNoParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); - ASSERT_EQ(reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("")).GetRawData()) - ->Compare(reinterpret_cast(msgValue->GetRawData())), - 0); + ASSERT_EQ( + reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("")).GetRawData()) + ->Compare(reinterpret_cast(msgValue->GetRawData())), + 0); JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); ASSERT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("ReferenceError")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("ReferenceError")).GetRawData()) ->Compare(reinterpret_cast(nameValue->GetRawData())), 0); } @@ -458,13 +448,11 @@ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorNoParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle error(env->GetReferenceErrorFunction()); - JSHandle paramMsg(factory->NewFromString("Hello ReferenceError!")); + JSHandle paramMsg(factory->NewFromCanBeCompressString("Hello ReferenceError!")); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*error), 6); ecmaRuntimeCallInfo->SetFunction(error.GetTaggedValue()); @@ -476,17 +464,17 @@ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); ASSERT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("Hello ReferenceError!")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Hello ReferenceError!")).GetRawData()) ->Compare(reinterpret_cast(msgValue->GetRawData())), 0); JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); ASSERT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("ReferenceError")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("ReferenceError")).GetRawData()) ->Compare(reinterpret_cast(nameValue->GetRawData())), 0); } @@ -498,8 +486,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorNoParameterToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -515,7 +501,7 @@ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorNoParameterToString) JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); EXPECT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("ReferenceError")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("ReferenceError")).GetRawData()) ->Compare(*resultHandle), 0); } @@ -527,17 +513,15 @@ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorNoParameterToString) */ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle errorObject = env->GetReferenceErrorFunction(); JSHandle error = factory->NewJSObjectByConstructor(JSHandle(errorObject), errorObject); - JSHandle handleMsgKey(factory->NewFromString("message")); + JSHandle handleMsgKey(factory->NewFromCanBeCompressString("message")); JSObject::SetProperty(thread, JSHandle(error), handleMsgKey, - JSHandle(factory->NewFromString("This is ReferenceError!"))); + JSHandle(factory->NewFromCanBeCompressString("This is ReferenceError!"))); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -547,7 +531,8 @@ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorToString) JSTaggedValue result = ReferenceError::ToString(ecmaRuntimeCallInfo.get()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ(factory->NewFromString("ReferenceError: This is ReferenceError!")->Compare(*resultHandle), 0); + EXPECT_EQ(factory->NewFromCanBeCompressString("ReferenceError: This is ReferenceError!")->Compare(*resultHandle), + 0); } /* @@ -557,8 +542,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, ReferenceErrorToString) */ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorNoParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -573,13 +556,14 @@ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorNoParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); - ASSERT_EQ(reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("")).GetRawData()) - ->Compare(reinterpret_cast(msgValue->GetRawData())), - 0); + ASSERT_EQ( + reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("")).GetRawData()) + ->Compare(reinterpret_cast(msgValue->GetRawData())), + 0); JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); EXPECT_EQ(reinterpret_cast(JSTaggedValue(nameValue.GetTaggedValue()).GetRawData()) @@ -594,13 +578,11 @@ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorNoParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle error(env->GetTypeErrorFunction()); - JSHandle paramMsg(factory->NewFromString("Hello TypeError!")); + JSHandle paramMsg(factory->NewFromCanBeCompressString("Hello TypeError!")); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*error), 6); ecmaRuntimeCallInfo->SetFunction(error.GetTaggedValue()); @@ -612,20 +594,20 @@ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); ASSERT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("Hello TypeError!")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Hello TypeError!")).GetRawData()) ->Compare(reinterpret_cast(msgValue->GetRawData())), 0); JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); - ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("TypeError")).GetRawData()) - ->Compare(reinterpret_cast(nameValue->GetRawData())), - 0); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("TypeError")).GetRawData()) + ->Compare(reinterpret_cast(nameValue->GetRawData())), + 0); } /* @@ -635,8 +617,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorNoParameterToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -651,10 +631,10 @@ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorNoParameterToString) JSTaggedValue result = TypeError::ToString(ecmaRuntimeCallInfo.get()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("TypeError")).GetRawData()) - ->Compare(*resultHandle), - 0); + EXPECT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("TypeError")).GetRawData()) + ->Compare(*resultHandle), + 0); } /* @@ -664,16 +644,14 @@ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorNoParameterToString) */ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle errorObject = env->GetTypeErrorFunction(); JSHandle error = factory->NewJSObjectByConstructor(JSHandle(errorObject), errorObject); - JSHandle value(factory->NewFromString("This is TypeError!")); - JSHandle handleMsgKey(factory->NewFromString("message")); + JSHandle value(factory->NewFromCanBeCompressString("This is TypeError!")); + JSHandle handleMsgKey(factory->NewFromCanBeCompressString("message")); JSObject::SetProperty(thread, JSHandle(error), handleMsgKey, value); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); @@ -684,7 +662,7 @@ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorToString) JSTaggedValue result = TypeError::ToString(ecmaRuntimeCallInfo.get()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ(factory->NewFromString("TypeError: This is TypeError!")->Compare(*resultHandle), 0); + EXPECT_EQ(factory->NewFromCanBeCompressString("TypeError: This is TypeError!")->Compare(*resultHandle), 0); } /* @@ -694,8 +672,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, TypeErrorToString) */ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorNoParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -710,19 +686,20 @@ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorNoParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); - ASSERT_EQ(reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("")).GetRawData()) - ->Compare(reinterpret_cast(msgValue->GetRawData())), - 0); - - JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("URIError")).GetRawData()) - ->Compare(reinterpret_cast(nameValue->GetRawData())), + reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("")).GetRawData()) + ->Compare(reinterpret_cast(msgValue->GetRawData())), 0); + + JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("URIError")).GetRawData()) + ->Compare(reinterpret_cast(nameValue->GetRawData())), + 0); } /* @@ -732,13 +709,11 @@ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorNoParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle error(env->GetURIErrorFunction()); - JSHandle paramMsg(factory->NewFromString("Hello URIError!")); + JSHandle paramMsg(factory->NewFromCanBeCompressString("Hello URIError!")); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*error), 6); ecmaRuntimeCallInfo->SetFunction(error.GetTaggedValue()); @@ -750,20 +725,20 @@ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); ASSERT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("Hello URIError!")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Hello URIError!")).GetRawData()) ->Compare(reinterpret_cast(msgValue->GetRawData())), 0); JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); - ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("URIError")).GetRawData()) - ->Compare(reinterpret_cast(nameValue->GetRawData())), - 0); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("URIError")).GetRawData()) + ->Compare(reinterpret_cast(nameValue->GetRawData())), + 0); } /* @@ -773,8 +748,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorNoParameterToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -790,10 +763,10 @@ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorNoParameterToString) JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("URIError")).GetRawData()) - ->Compare(*resultHandle), - 0); + EXPECT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("URIError")).GetRawData()) + ->Compare(*resultHandle), + 0); } /* @@ -803,18 +776,16 @@ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorNoParameterToString) */ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle errorObject = env->GetURIErrorFunction(); JSHandle error = factory->NewJSObjectByConstructor(JSHandle(errorObject), errorObject); - JSHandle handleMsgKey(factory->NewFromString("message")); + JSHandle handleMsgKey(factory->NewFromCanBeCompressString("message")); JSObject::SetProperty( thread, JSHandle(error), handleMsgKey, - JSHandle(thread, factory->NewFromString("This is URIError!").GetTaggedValue())); + JSHandle(thread, factory->NewFromCanBeCompressString("This is URIError!").GetTaggedValue())); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -825,10 +796,11 @@ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorToString) JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("URIError: This is URIError!")).GetRawData()) - ->Compare(*resultHandle), - 0); + EXPECT_EQ( + reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("URIError: This is URIError!")).GetRawData()) + ->Compare(*resultHandle), + 0); } /* @@ -838,8 +810,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, URIErrorToString) */ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorNoParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -854,19 +824,20 @@ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorNoParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); - ASSERT_EQ(reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("")).GetRawData()) - ->Compare(reinterpret_cast(msgValue->GetRawData())), - 0); - - JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("SyntaxError")).GetRawData()) - ->Compare(reinterpret_cast(nameValue->GetRawData())), + reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("")).GetRawData()) + ->Compare(reinterpret_cast(msgValue->GetRawData())), 0); + + JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("SyntaxError")).GetRawData()) + ->Compare(reinterpret_cast(nameValue->GetRawData())), + 0); } /* @@ -876,13 +847,11 @@ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorNoParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle error(env->GetSyntaxErrorFunction()); - JSHandle paramMsg(factory->NewFromString("Hello SyntaxError!")); + JSHandle paramMsg(factory->NewFromCanBeCompressString("Hello SyntaxError!")); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*error), 6); ecmaRuntimeCallInfo->SetFunction(error.GetTaggedValue()); @@ -894,20 +863,20 @@ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); ASSERT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("Hello SyntaxError!")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Hello SyntaxError!")).GetRawData()) ->Compare(reinterpret_cast(msgValue->GetRawData())), 0); JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); - ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("SyntaxError")).GetRawData()) - ->Compare(reinterpret_cast(nameValue->GetRawData())), - 0); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("SyntaxError")).GetRawData()) + ->Compare(reinterpret_cast(nameValue->GetRawData())), + 0); } /* @@ -917,8 +886,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorNoParameterToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -934,10 +901,10 @@ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorNoParameterToString) JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("SyntaxError")).GetRawData()) - ->Compare(*resultHandle), - 0); + EXPECT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("SyntaxError")).GetRawData()) + ->Compare(*resultHandle), + 0); } /* @@ -947,17 +914,15 @@ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorNoParameterToString) */ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle errorObject = env->GetSyntaxErrorFunction(); JSHandle error = factory->NewJSObjectByConstructor(JSHandle(errorObject), errorObject); - JSHandle handleMsgKey(factory->NewFromString("message")); + JSHandle handleMsgKey(factory->NewFromCanBeCompressString("message")); JSObject::SetProperty(thread, JSHandle(error), handleMsgKey, - JSHandle(factory->NewFromString("This is SyntaxError!"))); + JSHandle(factory->NewFromCanBeCompressString("This is SyntaxError!"))); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -968,7 +933,7 @@ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorToString) JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ(factory->NewFromString("SyntaxError: This is SyntaxError!")->Compare(*resultHandle), 0); + EXPECT_EQ(factory->NewFromCanBeCompressString("SyntaxError: This is SyntaxError!")->Compare(*resultHandle), 0); } /* @@ -978,8 +943,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, SyntaxErrorToString) */ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorNoParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); @@ -994,19 +957,20 @@ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorNoParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); - ASSERT_EQ(reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("")).GetRawData()) - ->Compare(reinterpret_cast(msgValue->GetRawData())), - 0); - - JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("EvalError")).GetRawData()) - ->Compare(reinterpret_cast(nameValue->GetRawData())), + reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("")).GetRawData()) + ->Compare(reinterpret_cast(msgValue->GetRawData())), 0); + + JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("EvalError")).GetRawData()) + ->Compare(reinterpret_cast(nameValue->GetRawData())), + 0); } /* @@ -1016,13 +980,11 @@ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorNoParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorParameterConstructor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle error(env->GetEvalErrorFunction()); - JSHandle paramMsg(factory->NewFromString("Hello EvalError!")); + JSHandle paramMsg(factory->NewFromCanBeCompressString("Hello EvalError!")); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*error), 6); ecmaRuntimeCallInfo->SetFunction(error.GetTaggedValue()); @@ -1034,20 +996,20 @@ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorParameterConstructor) EXPECT_TRUE(result.IsECMAObject()); JSHandle errorObject(thread, reinterpret_cast(result.GetRawData())); - JSHandle msgKey(factory->NewFromString("message")); + JSHandle msgKey(factory->NewFromCanBeCompressString("message")); JSHandle nameKey = thread->GlobalConstants()->GetHandledNameString(); JSHandle msgValue(JSObject::GetProperty(thread, errorObject, msgKey).GetValue()); ASSERT_EQ(reinterpret_cast( - ecmascript::JSTaggedValue(*factory->NewFromString("Hello EvalError!")).GetRawData()) + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("Hello EvalError!")).GetRawData()) ->Compare(reinterpret_cast(msgValue->GetRawData())), 0); JSHandle nameValue(JSObject::GetProperty(thread, errorObject, nameKey).GetValue()); - ASSERT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("EvalError")).GetRawData()) - ->Compare(reinterpret_cast(nameValue->GetRawData())), - 0); + ASSERT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("EvalError")).GetRawData()) + ->Compare(reinterpret_cast(nameValue->GetRawData())), + 0); } /* @@ -1057,8 +1019,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorParameterConstructor) */ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorNoParameterToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle errorObject = env->GetEvalErrorFunction(); @@ -1072,10 +1032,10 @@ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorNoParameterToString) JSTaggedValue result = EvalError::ToString(ecmaRuntimeCallInfo.get()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ( - reinterpret_cast(ecmascript::JSTaggedValue(*factory->NewFromString("EvalError")).GetRawData()) - ->Compare(*resultHandle), - 0); + EXPECT_EQ(reinterpret_cast( + ecmascript::JSTaggedValue(*factory->NewFromCanBeCompressString("EvalError")).GetRawData()) + ->Compare(*resultHandle), + 0); } /* @@ -1085,18 +1045,16 @@ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorNoParameterToString) */ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorToString) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle env = EcmaVM::Cast(instance)->GetGlobalEnv(); JSHandle errorObject = env->GetEvalErrorFunction(); JSHandle error = factory->NewJSObjectByConstructor(JSHandle(errorObject), errorObject); - JSHandle handleMsgKey(factory->NewFromString("message")); + JSHandle handleMsgKey(factory->NewFromCanBeCompressString("message")); JSObject::SetProperty( thread, JSHandle(error), handleMsgKey, - JSHandle(thread, factory->NewFromString("This is EvalError!").GetTaggedValue())); + JSHandle(thread, factory->NewFromCanBeCompressString("This is EvalError!").GetTaggedValue())); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -1106,6 +1064,6 @@ HWTEST_F_L0(BuiltinsErrorsTest, EvalErrorToString) JSTaggedValue result = EvalError::ToString(ecmaRuntimeCallInfo.get()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); EXPECT_TRUE(result.IsString()); - EXPECT_EQ(factory->NewFromString("EvalError: This is EvalError!")->Compare(*resultHandle), 0); + EXPECT_EQ(factory->NewFromCanBeCompressString("EvalError: This is EvalError!")->Compare(*resultHandle), 0); } } // namespace panda::test diff --git a/ecmascript/builtins/tests/builtins_function_test.cpp b/ecmascript/builtins/tests/builtins_function_test.cpp index 95e36eebdf72e44cb76b87aa3d8bc83592e71cbd..d3de7245e9561d273f39304bef25de08bd42cd13 100644 --- a/ecmascript/builtins/tests/builtins_function_test.cpp +++ b/ecmascript/builtins/tests/builtins_function_test.cpp @@ -75,12 +75,12 @@ JSTaggedValue TestFunctionApplyAndCall(EcmaRuntimeCallInfo *argv) JSTaggedValue testA = JSObject::GetProperty(thread, thisValue, - JSHandle(factory->NewFromString("test_builtins_function_a"))) + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_a"))) .GetValue() .GetTaggedValue(); JSTaggedValue testB = JSObject::GetProperty(thread, thisValue, - JSHandle(factory->NewFromString("test_builtins_function_b"))) + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_b"))) .GetValue() .GetTaggedValue(); @@ -91,7 +91,6 @@ JSTaggedValue TestFunctionApplyAndCall(EcmaRuntimeCallInfo *argv) // func.apply(thisArg) HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeApply) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -101,10 +100,10 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeApply) // ecma 19.2.3.1: thisArg JSHandle thisArg(thread, env->GetGlobalObject()); JSObject::SetProperty(thread, JSHandle(thisArg), - JSHandle(factory->NewFromString("test_builtins_function_a")), + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_a")), JSHandle(thread, JSTaggedValue(1))); JSObject::SetProperty(thread, JSHandle(thisArg), - JSHandle(factory->NewFromString("test_builtins_function_b")), + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_b")), JSHandle(thread, JSTaggedValue(2))); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); @@ -118,15 +117,14 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeApply) ASSERT_EQ(result.GetRawData(), JSTaggedValue(3).GetRawData()); JSObject::DeleteProperty(thread, (thisArg), - JSHandle(factory->NewFromString("test_builtins_function_a"))); + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_a"))); JSObject::DeleteProperty(thread, (thisArg), - JSHandle(factory->NewFromString("test_builtins_function_b"))); + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_b"))); } // func.apply(thisArg, argArray) HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeApply1) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -137,10 +135,10 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeApply1) // ecma 19.2.3.1: thisArg JSHandle thisArg(thread, env->GetGlobalObject()); JSObject::SetProperty(thread, JSHandle(thisArg), - JSHandle(factory->NewFromString("test_builtins_function_a")), + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_a")), JSHandle(thread, JSTaggedValue(10))); JSObject::SetProperty(thread, JSHandle(thisArg), - JSHandle(factory->NewFromString("test_builtins_function_b")), + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_b")), JSHandle(thread, JSTaggedValue(20))); // ecma 19.2.3.1: argArray @@ -163,22 +161,21 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeApply1) ASSERT_EQ(result.GetRawData(), JSTaggedValue(100).GetRawData()); JSObject::DeleteProperty(thread, (thisArg), - JSHandle(factory->NewFromString("test_builtins_function_a"))); + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_a"))); JSObject::DeleteProperty(thread, (thisArg), - JSHandle(factory->NewFromString("test_builtins_function_b"))); + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_b"))); } // target.bind(thisArg) HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle target = factory->NewJSFunction(env); JSFunction::SetFunctionName(thread, JSHandle(target), - JSHandle(factory->NewFromString("target")), + JSHandle(factory->NewFromCanBeCompressString("target")), JSHandle(thread, JSTaggedValue::Undefined())); JSFunction::SetFunctionLength(thread, target, JSTaggedValue(2)); @@ -207,7 +204,7 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind) JSHandle nameKey = globalConst->GetHandledNameString(); JSHandle resultFuncHandle(thread, *resultFunc); JSHandle resultName(JSObject::GetProperty(thread, resultFuncHandle, nameKey).GetValue()); - JSHandle boundTarget = factory->NewFromString("bound target"); + JSHandle boundTarget = factory->NewFromCanBeCompressString("bound target"); ASSERT_EQ(resultName->Compare(*boundTarget), 0); // test length property JSHandle lengthKey = globalConst->GetHandledLengthString(); @@ -218,19 +215,18 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind) // target.bind(thisArg, 123, "helloworld") HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind1) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle target = factory->NewJSFunction(env); JSFunction::SetFunctionName(thread, JSHandle(target), - JSHandle(factory->NewFromString("target1")), + JSHandle(factory->NewFromCanBeCompressString("target1")), JSHandle(thread, JSTaggedValue::Undefined())); JSFunction::SetFunctionLength(thread, target, JSTaggedValue(5)); JSHandle thisArg(thread, env->GetGlobalObject()); - JSHandle str = factory->NewFromString("helloworld"); + JSHandle str = factory->NewFromCanBeCompressString("helloworld"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -263,7 +259,7 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind1) JSHandle nameKey = globalConst->GetHandledNameString(); JSHandle resultFuncHandle(thread, *resultFunc); JSHandle resultName(JSObject::GetProperty(thread, resultFuncHandle, nameKey).GetValue()); - JSHandle rulerName = factory->NewFromString("bound target1"); + JSHandle rulerName = factory->NewFromCanBeCompressString("bound target1"); ASSERT_EQ(resultName->Compare(*rulerName), 0); // test length property JSHandle lengthKey = globalConst->GetHandledLengthString(); @@ -275,7 +271,6 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind1) // target.bind(thisArg, 123, "helloworld") set target_name = EmptyString() HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind2) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -287,7 +282,7 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind2) JSFunction::SetFunctionLength(thread, target, JSTaggedValue(5)); JSHandle thisArg(thread, env->GetGlobalObject()); - JSHandle str = factory->NewFromString("helloworld"); + JSHandle str = factory->NewFromCanBeCompressString("helloworld"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -320,7 +315,7 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind2) JSHandle nameKey = globalConst->GetHandledNameString(); JSHandle resultFuncHandle(resultFunc); JSHandle resultName(JSObject::GetProperty(thread, resultFuncHandle, nameKey).GetValue()); - JSHandle rulerName = factory->NewFromString("bound "); + JSHandle rulerName = factory->NewFromCanBeCompressString("bound "); ASSERT_EQ(resultName->Compare(*rulerName), 0); // test length property JSHandle lengthKey = globalConst->GetHandledLengthString(); @@ -332,7 +327,6 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind2) // func.call(thisArg) HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeCall) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -343,10 +337,10 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeCall) // ecma 19.2.3.3: thisArg JSHandle thisArg(thread, env->GetGlobalObject()); JSObject::SetProperty(thread, JSHandle(thisArg), - JSHandle(factory->NewFromString("test_builtins_function_a")), + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_a")), JSHandle(thread, JSTaggedValue(1))); JSObject::SetProperty(thread, JSHandle(thisArg), - JSHandle(factory->NewFromString("test_builtins_function_b")), + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_b")), JSHandle(thread, JSTaggedValue(2))); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); @@ -360,15 +354,14 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeCall) ASSERT_EQ(result.GetRawData(), JSTaggedValue(3).GetRawData()); JSObject::DeleteProperty(thread, (thisArg), - JSHandle(factory->NewFromString("test_builtins_function_a"))); + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_a"))); JSObject::DeleteProperty(thread, (thisArg), - JSHandle(factory->NewFromString("test_builtins_function_b"))); + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_b"))); } // func.call(thisArg, 123, 456, 789) HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeCall1) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -379,10 +372,10 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeCall1) // ecma 19.2.3.3: thisArg JSHandle thisArg(thread, env->GetGlobalObject()); JSObject::SetProperty(thread, JSHandle(thisArg), - JSHandle(factory->NewFromString("test_builtins_function_a")), + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_a")), JSHandle(thread, JSTaggedValue(1))); JSObject::SetProperty(thread, JSHandle(thisArg), - JSHandle(factory->NewFromString("test_builtins_function_b")), + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_b")), JSHandle(thread, JSTaggedValue(2))); // func thisArg ...args @@ -400,14 +393,13 @@ HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeCall1) ASSERT_EQ(result.GetRawData(), JSTaggedValue(1371).GetRawData()); JSObject::DeleteProperty(thread, (thisArg), - JSHandle(factory->NewFromString("test_builtins_function_a"))); + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_a"))); JSObject::DeleteProperty(thread, (thisArg), - JSHandle(factory->NewFromString("test_builtins_function_b"))); + JSHandle(factory->NewFromCanBeCompressString("test_builtins_function_b"))); } HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeHasInstance) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle booleanCtor(env->GetBooleanFunction()); diff --git a/ecmascript/builtins/tests/builtins_json_test.cpp b/ecmascript/builtins/tests/builtins_json_test.cpp index 1bc972607635becb58a48f9e9e7cdedf0ade71fc..8714bb243b23d3a4b962117978f0462b51b4a174 100644 --- a/ecmascript/builtins/tests/builtins_json_test.cpp +++ b/ecmascript/builtins/tests/builtins_json_test.cpp @@ -123,18 +123,18 @@ JSTaggedValue CreateBuiltinJSObject1(JSThread *thread, const CString keyCStr) JSHandle jsobject(factory->NewJSObjectByConstructor(JSHandle(objectFunc), objectFunc)); EXPECT_TRUE(*jsobject != nullptr); - JSHandle key(factory->NewFromString(&keyCStr[0])); + JSHandle key(factory->NewFromCanBeCompressString(&keyCStr[0])); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(jsobject), key, value); CString str2 = "y"; - JSHandle key2(factory->NewFromString(str2)); + JSHandle key2(factory->NewFromCanBeCompressString(str2)); JSHandle value2(thread, JSTaggedValue(2.5)); // 2.5 : test case JSObject::SetProperty(thread, JSHandle(jsobject), key2, value2); CString str3 = "z"; - JSHandle key3(factory->NewFromString(str3)); - JSHandle value3(factory->NewFromString("abc")); + JSHandle key3(factory->NewFromCanBeCompressString(str3)); + JSHandle value3(factory->NewFromCanBeCompressString("abc")); JSObject::SetProperty(thread, JSHandle(jsobject), key3, value3); return jsobject.GetTaggedValue(); @@ -143,10 +143,9 @@ JSTaggedValue CreateBuiltinJSObject1(JSThread *thread, const CString keyCStr) HWTEST_F_L0(BuiltinsJsonTest, Parse10) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle msg(factory->NewFromString( + JSHandle msg(factory->NewFromCanBeCompressString( "\t\r \n{\t\r \n \"property\"\t\r \n:\t\r \n{\t\r \n}\t\r \n,\t\r \n \"prop2\"\t\r \n:\t\r \n [\t\r \ntrue\t\r " "\n,\t\r \nnull\t\r \n,123.456\t\r \n] \t\r \n}\t\r \n")); JSHandle str(JSTaggedValue::ToString(thread, msg)); @@ -163,11 +162,10 @@ HWTEST_F_L0(BuiltinsJsonTest, Parse10) HWTEST_F_L0(BuiltinsJsonTest, Parse21) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); - JSHandle msg(factory->NewFromString("[100,2.5,\"abc\"]")); + JSHandle msg(factory->NewFromCanBeCompressString("[100,2.5,\"abc\"]")); JSHandle handleFunc = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestForParse)); JSHandle str(JSTaggedValue::ToString(thread, msg)); @@ -185,11 +183,10 @@ HWTEST_F_L0(BuiltinsJsonTest, Parse21) HWTEST_F_L0(BuiltinsJsonTest, Parse) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString(); - JSHandle msg(factory->NewFromString("[100,2.5,\"abc\"]")); + JSHandle msg(factory->NewFromCanBeCompressString("[100,2.5,\"abc\"]")); JSHandle str(JSTaggedValue::ToString(thread, msg)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); @@ -211,7 +208,7 @@ HWTEST_F_L0(BuiltinsJsonTest, Parse) HWTEST_F_L0(BuiltinsJsonTest, Parse2) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle msg(factory->NewFromString("{\"epf\":100,\"key1\":200}")); + JSHandle msg(factory->NewFromCanBeCompressString("{\"epf\":100,\"key1\":200}")); JSHandle str(JSTaggedValue::ToString(thread, msg)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); @@ -229,7 +226,7 @@ HWTEST_F_L0(BuiltinsJsonTest, Parse2) JSHandle nameResult = JSArray::CreateArrayFromList(thread, nameList); JSHandle handleKey(nameResult); - JSHandle lengthKey(factory->NewFromString("length")); + JSHandle lengthKey(factory->NewFromCanBeCompressString("length")); JSHandle lenResult = JSObject::GetProperty(thread, handleKey, lengthKey).GetValue(); uint32_t length = JSTaggedValue::ToLength(thread, lenResult).ToUint32(); ASSERT_EQ(length, 2); @@ -281,7 +278,7 @@ HWTEST_F_L0(BuiltinsJsonTest, Stringify13) JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle handleFunc = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestForStringfy)); - JSHandle msg(factory->NewFromString("tttt")); + JSHandle msg(factory->NewFromCanBeCompressString("tttt")); JSHandle str(JSTaggedValue::ToString(thread, msg)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); @@ -304,13 +301,13 @@ HWTEST_F_L0(BuiltinsJsonTest, Stringify14) JSHandle obj1(thread, arr); JSHandle key0(thread, JSTaggedValue(0)); - JSHandle value0(factory->NewFromString("x")); + JSHandle value0(factory->NewFromCanBeCompressString("x")); JSObject::SetProperty(thread, JSHandle(obj), key0, value0); JSHandle key1(thread, JSTaggedValue(1)); - JSHandle value1(factory->NewFromString("z")); + JSHandle value1(factory->NewFromCanBeCompressString("z")); JSObject::SetProperty(thread, JSHandle(obj), key1, value1); - JSHandle msg(factory->NewFromString("tttt")); + JSHandle msg(factory->NewFromCanBeCompressString("tttt")); JSHandle str(JSTaggedValue::ToString(thread, msg)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); @@ -340,7 +337,6 @@ HWTEST_F_L0(BuiltinsJsonTest, Stringify) HWTEST_F_L0(BuiltinsJsonTest, Stringify1) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -351,7 +347,7 @@ HWTEST_F_L0(BuiltinsJsonTest, Stringify1) JSHandle obj(thread, arr); JSHandle key0(thread, JSTaggedValue(0)); - JSHandle value(factory->NewFromString("def")); + JSHandle value(factory->NewFromCanBeCompressString("def")); JSObject::SetProperty(thread, JSHandle(obj), key0, value); JSHandle key1(thread, JSTaggedValue(1)); @@ -359,12 +355,12 @@ HWTEST_F_L0(BuiltinsJsonTest, Stringify1) JSArray::DefineOwnProperty(thread, obj, key1, desc1); JSHandle key2(thread, JSTaggedValue(2)); - JSHandle value2(factory->NewFromString("abc")); + JSHandle value2(factory->NewFromCanBeCompressString("abc")); JSObject::SetProperty(thread, JSHandle(obj), key2, value2); JSHandle handleFunc = factory->NewJSFunction(env, reinterpret_cast(TestClass::TestForStringfy)); - JSHandle msg(factory->NewFromString("tttt")); + JSHandle msg(factory->NewFromCanBeCompressString("tttt")); JSHandle str(JSTaggedValue::ToString(thread, msg)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); @@ -381,7 +377,6 @@ HWTEST_F_L0(BuiltinsJsonTest, Stringify1) HWTEST_F_L0(BuiltinsJsonTest, Stringify2) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); ObjectFactory *factory = ecmaVM->GetFactory(); @@ -398,7 +393,7 @@ HWTEST_F_L0(BuiltinsJsonTest, Stringify2) JSArray::DefineOwnProperty(thread, obj, key1, desc1); // 2 : test case JSHandle key2(thread, JSTaggedValue(2)); - JSHandle value2(factory->NewFromString("abc")); + JSHandle value2(factory->NewFromCanBeCompressString("abc")); JSObject::SetProperty(thread, JSHandle(obj), key2, value2); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); diff --git a/ecmascript/builtins/tests/builtins_map_test.cpp b/ecmascript/builtins/tests/builtins_map_test.cpp index 6ea43bf535f597cc0b2c9c62e2100cf405717875..dac0e77209930e17646de810b40089a7891e9e51 100644 --- a/ecmascript/builtins/tests/builtins_map_test.cpp +++ b/ecmascript/builtins/tests/builtins_map_test.cpp @@ -140,7 +140,7 @@ HWTEST_F_L0(BuiltinsMapTest, SetAndHas) ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // create jsMap JSHandle map(thread, CreateBuiltinsMap(thread)); - JSHandle key(factory->NewFromString("key")); + JSHandle key(factory->NewFromCanBeCompressString("key")); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -186,7 +186,7 @@ HWTEST_F_L0(BuiltinsMapTest, ForEach) char keyArray[] = "key0"; for (int i = 0; i < 5; i++) { keyArray[3] = '1' + i; - JSHandle key(factory->NewFromString(keyArray)); + JSHandle key(factory->NewFromCanBeCompressString(keyArray)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(map.GetTaggedValue()); @@ -226,7 +226,7 @@ HWTEST_F_L0(BuiltinsMapTest, DeleteAndRemove) char keyArray[] = "key0"; for (int i = 0; i < 40; i++) { keyArray[3] = '1' + i; - JSHandle key(thread, factory->NewFromString(keyArray).GetTaggedValue()); + JSHandle key(thread, factory->NewFromCanBeCompressString(keyArray).GetTaggedValue()); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(map.GetTaggedValue()); @@ -242,7 +242,7 @@ HWTEST_F_L0(BuiltinsMapTest, DeleteAndRemove) } // whether jsMap has delete key keyArray[3] = '1' + 8; - JSHandle deleteKey(factory->NewFromString(keyArray)); + JSHandle deleteKey(factory->NewFromCanBeCompressString(keyArray)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); @@ -293,38 +293,38 @@ HWTEST_F_L0(BuiltinsMapTest, Species) // to string tag JSHandle toStringTagSymbol = env->GetToStringTagSymbol(); JSHandle stringTag(JSObject::GetProperty(thread, map, toStringTagSymbol).GetValue()); - JSHandle str = factory->NewFromString("Map"); + JSHandle str = factory->NewFromCanBeCompressString("Map"); EXPECT_TRUE(!stringTag.GetTaggedValue().IsUndefined()); EXPECT_TRUE(EcmaString::StringsAreEqual(*str, *stringTag)); JSHandle constructor = JSHandle::Cast(JSTaggedValue::ToObject(thread, valueHandle)); EXPECT_EQ(JSHandle(map)->GetPrototype(thread), constructor->GetFunctionPrototype()); - JSHandle key1(factory->NewFromString("set")); + JSHandle key1(factory->NewFromCanBeCompressString("set")); JSTaggedValue value1 = JSObject::GetProperty(thread, map, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value1.IsUndefined()); - JSHandle key2(factory->NewFromString("has")); + JSHandle key2(factory->NewFromCanBeCompressString("has")); JSTaggedValue value2 = JSObject::GetProperty(thread, map, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value2.IsUndefined()); - JSHandle key3(factory->NewFromString("clear")); + JSHandle key3(factory->NewFromCanBeCompressString("clear")); JSTaggedValue value3 = JSObject::GetProperty(thread, map, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value3.IsUndefined()); - JSHandle key4(factory->NewFromString("size")); + JSHandle key4(factory->NewFromCanBeCompressString("size")); JSTaggedValue value4 = JSObject::GetProperty(thread, map, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value4.IsUndefined()); - JSHandle key5(factory->NewFromString("delete")); + JSHandle key5(factory->NewFromCanBeCompressString("delete")); JSTaggedValue value5 = JSObject::GetProperty(thread, map, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value5.IsUndefined()); - JSHandle key6(factory->NewFromString("forEach")); + JSHandle key6(factory->NewFromCanBeCompressString("forEach")); JSTaggedValue value6 = JSObject::GetProperty(thread, map, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value6.IsUndefined()); - JSHandle key7(factory->NewFromString("get")); + JSHandle key7(factory->NewFromCanBeCompressString("get")); JSTaggedValue value7 = JSObject::GetProperty(thread, map, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value7.IsUndefined()); } diff --git a/ecmascript/builtins/tests/builtins_math_test.cpp b/ecmascript/builtins/tests/builtins_math_test.cpp index f475155473700a6f69725c20f0eb3f718e9e9a86..3865d93976e82a6d683699c377640d3cfdcedeb0 100644 --- a/ecmascript/builtins/tests/builtins_math_test.cpp +++ b/ecmascript/builtins/tests/builtins_math_test.cpp @@ -112,7 +112,7 @@ HWTEST_F_L0(BuiltinsMathTest, Abs_3) // Math.abs("hello") HWTEST_F_L0(BuiltinsMathTest, Abs_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("helloworld"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("helloworld"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -269,7 +269,7 @@ HWTEST_F_L0(BuiltinsMathTest, Abs_13) // Math.abs("100.12") HWTEST_F_L0(BuiltinsMathTest, Abs_14) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("100.12"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("100.12"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -390,7 +390,7 @@ HWTEST_F_L0(BuiltinsMathTest, Acos_6) // Math.acos("0.1") HWTEST_F_L0(BuiltinsMathTest, Acos_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("0.1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0.1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -406,7 +406,7 @@ HWTEST_F_L0(BuiltinsMathTest, Acos_7) // Math.acos("") HWTEST_F_L0(BuiltinsMathTest, Acos_8) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(""); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -557,7 +557,7 @@ HWTEST_F_L0(BuiltinsMathTest, Acosh_7) // Math.acosh("1") HWTEST_F_L0(BuiltinsMathTest, Acosh_8) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -573,7 +573,7 @@ HWTEST_F_L0(BuiltinsMathTest, Acosh_8) // Math.acosh("") HWTEST_F_L0(BuiltinsMathTest, Acosh_9) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(""); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -709,7 +709,7 @@ HWTEST_F_L0(BuiltinsMathTest, Asin_6) // Math.asin(""") HWTEST_F_L0(BuiltinsMathTest, Asin_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(""); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -725,7 +725,7 @@ HWTEST_F_L0(BuiltinsMathTest, Asin_7) // Math.asin("1") HWTEST_F_L0(BuiltinsMathTest, Asin_8) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -848,7 +848,7 @@ HWTEST_F_L0(BuiltinsMathTest, Asinh_6) // Math.asinh("") HWTEST_F_L0(BuiltinsMathTest, Asinh_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(""); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -864,7 +864,7 @@ HWTEST_F_L0(BuiltinsMathTest, Asinh_7) // Math.asinh("-5.7") HWTEST_F_L0(BuiltinsMathTest, Asinh_8) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-5.7"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-5.7"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -985,7 +985,7 @@ HWTEST_F_L0(BuiltinsMathTest, Atan_6) // Math.atan("") HWTEST_F_L0(BuiltinsMathTest, Atan_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(" "); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" "); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1001,7 +1001,7 @@ HWTEST_F_L0(BuiltinsMathTest, Atan_7) // Math.atan("-1") HWTEST_F_L0(BuiltinsMathTest, Atan_8) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1122,7 +1122,7 @@ HWTEST_F_L0(BuiltinsMathTest, Atanh_6) // Math.atanh("") HWTEST_F_L0(BuiltinsMathTest, Atanh_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(" "); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" "); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1138,7 +1138,7 @@ HWTEST_F_L0(BuiltinsMathTest, Atanh_7) // Math.atanh("-1") HWTEST_F_L0(BuiltinsMathTest, Atanh_8) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1298,8 +1298,8 @@ HWTEST_F_L0(BuiltinsMathTest, Atan2_8) // Math.atan2("-1","") HWTEST_F_L0(BuiltinsMathTest, Atan2_9) { - JSHandle test_1 = thread_->GetEcmaVM()->GetFactory()->NewFromString("-1"); - JSHandle test_2 = thread_->GetEcmaVM()->GetFactory()->NewFromString(""); + JSHandle test_1 = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-1"); + JSHandle test_2 = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1316,8 +1316,8 @@ HWTEST_F_L0(BuiltinsMathTest, Atan2_9) // Math.atan2("0.23","0.72") HWTEST_F_L0(BuiltinsMathTest, Atan2_10) { - JSHandle test_1 = thread_->GetEcmaVM()->GetFactory()->NewFromString("0.23"); - JSHandle test_2 = thread_->GetEcmaVM()->GetFactory()->NewFromString("0.72"); + JSHandle test_1 = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0.23"); + JSHandle test_2 = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0.72"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1455,7 +1455,7 @@ HWTEST_F_L0(BuiltinsMathTest, Cbrt_6) // Math.cbrt("") HWTEST_F_L0(BuiltinsMathTest, Cbrt_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(" "); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" "); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1471,7 +1471,7 @@ HWTEST_F_L0(BuiltinsMathTest, Cbrt_7) // Math.cbrt("1.23") HWTEST_F_L0(BuiltinsMathTest, Cbrt_8) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("1.23"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1.23"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1607,7 +1607,7 @@ HWTEST_F_L0(BuiltinsMathTest, Ceil_6) // Math.ceil("") HWTEST_F_L0(BuiltinsMathTest, Ceil_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(""); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1623,7 +1623,7 @@ HWTEST_F_L0(BuiltinsMathTest, Ceil_7) // Math.ceil("3.23") HWTEST_F_L0(BuiltinsMathTest, Ceil_8) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("3.23"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("3.23"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1744,7 +1744,7 @@ HWTEST_F_L0(BuiltinsMathTest, Cos_5) // Math.cos("") HWTEST_F_L0(BuiltinsMathTest, Cos_6) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(""); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1760,7 +1760,7 @@ HWTEST_F_L0(BuiltinsMathTest, Cos_6) // Math.cos("3.23") HWTEST_F_L0(BuiltinsMathTest, Cos_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("3.23"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("3.23"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1866,7 +1866,7 @@ HWTEST_F_L0(BuiltinsMathTest, Cosh_5) // Math.cosh("") HWTEST_F_L0(BuiltinsMathTest, Cosh_6) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(" "); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" "); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1882,7 +1882,7 @@ HWTEST_F_L0(BuiltinsMathTest, Cosh_6) // Math.cosh("3.23") HWTEST_F_L0(BuiltinsMathTest, Cosh_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("3.23"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("3.23"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -1988,7 +1988,7 @@ HWTEST_F_L0(BuiltinsMathTest, Exp_5) // Math.exp("") HWTEST_F_L0(BuiltinsMathTest, Exp_6) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(""); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2004,7 +2004,7 @@ HWTEST_F_L0(BuiltinsMathTest, Exp_6) // Math.exp("-3.23") HWTEST_F_L0(BuiltinsMathTest, Exp_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-3.23"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-3.23"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2126,7 +2126,7 @@ HWTEST_F_L0(BuiltinsMathTest, Expm1_6) // Math.expm1("") HWTEST_F_L0(BuiltinsMathTest, Expm1_7) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString(" "); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" "); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2142,7 +2142,7 @@ HWTEST_F_L0(BuiltinsMathTest, Expm1_7) // Math.expm1("-3.23") HWTEST_F_L0(BuiltinsMathTest, Expm1_8) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-3.23"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-3.23"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2158,7 +2158,7 @@ HWTEST_F_L0(BuiltinsMathTest, Expm1_8) // Math.expm1("0x12") HWTEST_F_L0(BuiltinsMathTest, Expm1_9) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("0x12"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0x12"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2234,7 +2234,7 @@ HWTEST_F_L0(BuiltinsMathTest, Floor_3) // Math.floor("-3.23") HWTEST_F_L0(BuiltinsMathTest, Floor_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-3.23"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-3.23"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2310,7 +2310,7 @@ HWTEST_F_L0(BuiltinsMathTest, Log_3) // Math.log("-3.23") HWTEST_F_L0(BuiltinsMathTest, Log_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-3.23"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-3.23"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2401,7 +2401,7 @@ HWTEST_F_L0(BuiltinsMathTest, Log1p_3) // Math.log1p("-3.23") HWTEST_F_L0(BuiltinsMathTest, Log1p_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-3.23"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-3.23"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2492,7 +2492,7 @@ HWTEST_F_L0(BuiltinsMathTest, Log10_3) // Math.Log10("2") HWTEST_F_L0(BuiltinsMathTest, Log10_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("2"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2583,7 +2583,7 @@ HWTEST_F_L0(BuiltinsMathTest, Log2_3) // Math.log2("2") HWTEST_F_L0(BuiltinsMathTest, Log2_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("2"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2645,7 +2645,7 @@ HWTEST_F_L0(BuiltinsMathTest, Max_1) // Math.Max("3",100,2.5) HWTEST_F_L0(BuiltinsMathTest, Max_2) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("3"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("3"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2663,7 +2663,7 @@ HWTEST_F_L0(BuiltinsMathTest, Max_2) // Math.Max(3,"100",-101.5) HWTEST_F_L0(BuiltinsMathTest, Max_3) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("100"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("100"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2681,7 +2681,7 @@ HWTEST_F_L0(BuiltinsMathTest, Max_3) // Math.Max(-3,"-100",true) HWTEST_F_L0(BuiltinsMathTest, Max_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-100"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-100"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2730,7 +2730,7 @@ HWTEST_F_L0(BuiltinsMathTest, Min_1) // Math.min("3",100,2.5) HWTEST_F_L0(BuiltinsMathTest, Min_2) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("3"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("3"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2748,7 +2748,7 @@ HWTEST_F_L0(BuiltinsMathTest, Min_2) // Math.min(3,"100",-101.5) HWTEST_F_L0(BuiltinsMathTest, Min_3) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("100"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("100"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -2783,7 +2783,7 @@ HWTEST_F_L0(BuiltinsMathTest, Min_4) // Math.pow(2,"-2") HWTEST_F_L0(BuiltinsMathTest, Pow) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-2"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-2"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -3212,7 +3212,7 @@ HWTEST_F_L0(BuiltinsMathTest, Imul) // Math.Imul("-2",9.256) HWTEST_F_L0(BuiltinsMathTest, Imul_1) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-2"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-2"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -3336,7 +3336,7 @@ HWTEST_F_L0(BuiltinsMathTest, Sin_5) // Math.sin("0.1") HWTEST_F_L0(BuiltinsMathTest, Sin_6) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("0.1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0.1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -3457,7 +3457,7 @@ HWTEST_F_L0(BuiltinsMathTest, Sinh_4) // Math.sinh("0.1") HWTEST_F_L0(BuiltinsMathTest, Sinh_5) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("0.1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0.1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -3563,7 +3563,7 @@ HWTEST_F_L0(BuiltinsMathTest, Sqrt_3) // Math.sqrt("0.1") HWTEST_F_L0(BuiltinsMathTest, Sqrt_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("0.1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0.1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -3669,7 +3669,7 @@ HWTEST_F_L0(BuiltinsMathTest, Tan_3) // Math.tan("0.1") HWTEST_F_L0(BuiltinsMathTest, Tan_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("0.1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0.1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -3775,7 +3775,7 @@ HWTEST_F_L0(BuiltinsMathTest, Tanh_3) // Math.tanh("0.1") HWTEST_F_L0(BuiltinsMathTest, Tanh_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("0.1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0.1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -3881,7 +3881,7 @@ HWTEST_F_L0(BuiltinsMathTest, Trunc_3) // Math.trunc("-0.1") HWTEST_F_L0(BuiltinsMathTest, Trunc_4) { - JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromString("-0.1"); + JSHandle test = thread_->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-0.1"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread_, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); diff --git a/ecmascript/builtins/tests/builtins_number_test.cpp b/ecmascript/builtins/tests/builtins_number_test.cpp index 80cd7dfac8952ce143d220a62b6bdc0715bdb9df..3d0cb10eaec22aad364ab1af0b78f4b871e65b82 100644 --- a/ecmascript/builtins/tests/builtins_number_test.cpp +++ b/ecmascript/builtins/tests/builtins_number_test.cpp @@ -66,7 +66,6 @@ public: // new Number(10) HWTEST_F_L0(BuiltinsNumberTest, NumberConstructor) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle number(env->GetNumberFunction()); @@ -115,7 +114,7 @@ HWTEST_F_L0(BuiltinsNumberTest, IsFinite1) // Number.isFinite("helloworld") HWTEST_F_L0(BuiltinsNumberTest, IsFinite2) { - JSHandle test = thread->GetEcmaVM()->GetFactory()->NewFromString("helloworld"); + JSHandle test = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("helloworld"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -207,7 +206,6 @@ HWTEST_F_L0(BuiltinsNumberTest, IsNaN) // new Number(123.456).toString(7) HWTEST_F_L0(BuiltinsNumberTest, ToString) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -225,7 +223,7 @@ HWTEST_F_L0(BuiltinsNumberTest, ToString) JSTaggedValue result = BuiltinsNumber::ToString(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); - JSHandle correctResult = factory->NewFromString("234.312256641535441"); + JSHandle correctResult = factory->NewFromCanBeCompressString("234.312256641535441"); CVector test(res->GetLength() + 1); res->CopyDataUtf8(test.data(), res->GetLength()); ASSERT_TRUE(EcmaString::StringsAreEqual(*res, *correctResult)); @@ -234,7 +232,6 @@ HWTEST_F_L0(BuiltinsNumberTest, ToString) // new Number(123.456).toExponential(5) HWTEST_F_L0(BuiltinsNumberTest, IsExponential) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -252,7 +249,7 @@ HWTEST_F_L0(BuiltinsNumberTest, IsExponential) JSTaggedValue result = BuiltinsNumber::ToExponential(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); - JSHandle correctResult = factory->NewFromString("1.23456e+2"); + JSHandle correctResult = factory->NewFromCanBeCompressString("1.23456e+2"); CVector test(res->GetLength() + 1); res->CopyDataUtf8(test.data(), res->GetLength()); ASSERT_TRUE(EcmaString::StringsAreEqual(*res, *correctResult)); @@ -261,7 +258,6 @@ HWTEST_F_L0(BuiltinsNumberTest, IsExponential) // new Number(123.456).toFixed(10) HWTEST_F_L0(BuiltinsNumberTest, ToFixed) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -279,14 +275,13 @@ HWTEST_F_L0(BuiltinsNumberTest, ToFixed) JSTaggedValue result = BuiltinsNumber::ToFixed(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); - JSHandle correctResult = factory->NewFromString("123.4560000000"); + JSHandle correctResult = factory->NewFromCanBeCompressString("123.4560000000"); ASSERT_TRUE(EcmaString::StringsAreEqual(*res, *correctResult)); } // new Number(123.456).toFixed(30) HWTEST_F_L0(BuiltinsNumberTest, ToFixed1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -304,14 +299,12 @@ HWTEST_F_L0(BuiltinsNumberTest, ToFixed1) JSTaggedValue result = BuiltinsNumber::ToFixed(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); - JSHandle correctResult = factory->NewFromString("123.456000000000003069544618483633"); + JSHandle correctResult = factory->NewFromCanBeCompressString("123.456000000000003069544618483633"); ASSERT_TRUE(EcmaString::StringsAreEqual(*res, *correctResult)); } // new Number(1e21).toFixed(20) -HWTEST_F_L0(BuiltinsNumberTest, ToFixed2) -{ - ASSERT_NE(thread, nullptr); +HWTEST_F_L0(BuiltinsNumberTest, ToFixed2) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -330,7 +323,7 @@ HWTEST_F_L0(BuiltinsNumberTest, ToFixed2) JSTaggedValue result = BuiltinsNumber::ToFixed(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); - JSHandle correctResult = factory->NewFromString("1e+21"); + JSHandle correctResult = factory->NewFromCanBeCompressString("1e+21"); CVector test(res->GetLength() + 1); res->CopyDataUtf8(test.data(), res->GetLength()); std::cout << test.data(); @@ -340,7 +333,6 @@ HWTEST_F_L0(BuiltinsNumberTest, ToFixed2) // new Number(123.456).toPrecision(8) HWTEST_F_L0(BuiltinsNumberTest, ToPrecision) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -358,14 +350,14 @@ HWTEST_F_L0(BuiltinsNumberTest, ToPrecision) JSTaggedValue result = BuiltinsNumber::ToPrecision(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle res(thread, reinterpret_cast(result.GetRawData())); - JSHandle correctResult = factory->NewFromString("123.45600"); + JSHandle correctResult = factory->NewFromCanBeCompressString("123.45600"); ASSERT_TRUE(EcmaString::StringsAreEqual(*res, *correctResult)); } // Number.parseFloat(0x123) HWTEST_F_L0(BuiltinsNumberTest, parseFloat) { - JSHandle param = thread->GetEcmaVM()->GetFactory()->NewFromString("0x123"); + JSHandle param = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0x123"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -379,7 +371,7 @@ HWTEST_F_L0(BuiltinsNumberTest, parseFloat) // Number.parseFloat(0x123xx) HWTEST_F_L0(BuiltinsNumberTest, parseFloat1) { - JSHandle param = thread->GetEcmaVM()->GetFactory()->NewFromString("0x123xx"); + JSHandle param = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0x123xx"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -395,7 +387,7 @@ HWTEST_F_L0(BuiltinsNumberTest, parseInt) { const char *number = "0x123"; - JSHandle param = thread->GetEcmaVM()->GetFactory()->NewFromString(number); + JSHandle param = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(number); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined()); @@ -415,74 +407,74 @@ HWTEST_F_L0(BuiltinsNumberTest, StringToDoubleFlags) // flags of IGNORE_TRAILING - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0a"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0a"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 0); - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0b"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0b"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 0); - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0o"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0o"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 0); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 00x"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 00x"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 0); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 000.4_"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 000.4_"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 0.4); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 0010.s "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0010.s "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 10); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 0010e2"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0010e2"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 1000); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 0010e+3_0"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0010e+3_0"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 10000); // flags of ALLOW_HEX - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0x"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0x"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_TRUE(std::isnan(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_HEX))); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 0x10 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0x10 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_HEX), 16); - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0x1g"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0x1g"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_HEX + base::IGNORE_TRAILING), 1); - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0xh"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0xh"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_TRUE(std::isnan( base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_HEX + base::IGNORE_TRAILING))); // flags of ALLOW_OCTAL - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0O"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0O"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_TRUE(std::isnan(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_OCTAL))); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 0o10 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0o10 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_OCTAL), 8); - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0o1d"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0o1d"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_OCTAL | base::IGNORE_TRAILING), 1); - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0o8"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0o8"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_TRUE(std::isnan( base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_OCTAL | base::IGNORE_TRAILING))); // flags of ALLOW_BINARY - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0b"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0b"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_TRUE(std::isnan(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_BINARY))); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 0b10 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0b10 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_BINARY), 2); - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0b1d"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0b1d"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_BINARY | base::IGNORE_TRAILING), 1); - str = thread->GetEcmaVM()->GetFactory()->NewFromString("0b2"); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0b2"); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_TRUE(std::isnan( base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_BINARY | base::IGNORE_TRAILING))); @@ -496,80 +488,80 @@ HWTEST_F_L0(BuiltinsNumberTest, StringToDoubleRadix) int radix; radix = 0; // default 10 - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 100); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100.3e2 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100.3e2 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 10030); radix = 1; - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 0000 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0000 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 0); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 0001 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0001 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_TRUE(std::isnan(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS))); radix = 2; - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 4); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 11 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 11 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 3); radix = 3; - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 9); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 21 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 21 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 7); radix = 4; - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 16); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 31 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 31 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 13); radix = 8; - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 64); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 71 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 71 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 57); radix = 10; - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 100); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 0020 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0020 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 20); radix = 16; - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 256); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 1e "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 1e "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 30); radix = 18; - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 324); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 1g "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 1g "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 34); radix = 25; - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 625); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 1g "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 1g "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 41); radix = 36; - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 100 "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 100 "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 1296); - str = thread->GetEcmaVM()->GetFactory()->NewFromString(" 1z "); + str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 1z "); sp = Span(str->GetDataUtf8(), str->GetUtf8Length() - 1); ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 71); } @@ -577,31 +569,31 @@ HWTEST_F_L0(BuiltinsNumberTest, StringToDoubleRadix) HWTEST_F_L0(BuiltinsNumberTest, NumberToString) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle res = factory->NewFromString("100"); + JSHandle res = factory->NewFromCanBeCompressString("100"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(100))->Compare(*res), 0); - res = factory->NewFromString("11223344"); + res = factory->NewFromCanBeCompressString("11223344"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(11223344))->Compare(*res), 0); - res = factory->NewFromString("1234567890"); + res = factory->NewFromCanBeCompressString("1234567890"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(1234567890))->Compare(*res), 0); - res = factory->NewFromString("100"); + res = factory->NewFromCanBeCompressString("100"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(double(100.0)))->Compare(*res), 0); - res = factory->NewFromString("100.5"); + res = factory->NewFromCanBeCompressString("100.5"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(double(100.5)))->Compare(*res), 0); - res = factory->NewFromString("100.25"); + res = factory->NewFromCanBeCompressString("100.25"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(double(100.25)))->Compare(*res), 0); - res = factory->NewFromString("100.125"); + res = factory->NewFromCanBeCompressString("100.125"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(double(100.125)))->Compare(*res), 0); - res = factory->NewFromString("100.6125"); + res = factory->NewFromCanBeCompressString("100.6125"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(double(100.6125)))->Compare(*res), 0); - res = factory->NewFromString("0.0006125"); + res = factory->NewFromCanBeCompressString("0.0006125"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(double(0.0006125)))->Compare(*res), 0); - res = factory->NewFromString("-0.0006125"); + res = factory->NewFromCanBeCompressString("-0.0006125"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(double(-0.0006125)))->Compare(*res), 0); - res = factory->NewFromString("-1234567890.0006125"); + res = factory->NewFromCanBeCompressString("-1234567890.0006125"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(double(-1234567890.0006125)))->Compare(*res), 0); - res = factory->NewFromString("1234567890.0006125"); + res = factory->NewFromCanBeCompressString("1234567890.0006125"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(double(1234567890.0006125)))->Compare(*res), 0); - res = factory->NewFromString("11234567890.000612"); + res = factory->NewFromCanBeCompressString("11234567890.000612"); ASSERT_EQ(base::NumberHelper::NumberToString(thread, JSTaggedValue(double(11234567890.0006125)))->Compare(*res), 0); } } // namespace panda::test diff --git a/ecmascript/builtins/tests/builtins_object_test.cpp b/ecmascript/builtins/tests/builtins_object_test.cpp index 85c985799ce6881e91259d033337af253d7a95c9..aebf11a964d2011cbefdce2b7fddfd38f5ef6793 100644 --- a/ecmascript/builtins/tests/builtins_object_test.cpp +++ b/ecmascript/builtins/tests/builtins_object_test.cpp @@ -68,7 +68,7 @@ JSTaggedValue CreateBuiltinJSObject(JSThread *thread, const CString keyCStr) ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle obj(factory->NewJSObjectByConstructor(JSHandle(objFun), objFun)); - JSHandle key(factory->NewFromString(&keyCStr[0])); + JSHandle key(factory->NewFromCanBeCompressString(&keyCStr[0])); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, obj, key, value); return obj.GetTaggedValue(); @@ -90,7 +90,7 @@ JSObject *TestNewJSObject(JSThread *thread, const JSHandle &dynClass) return obj; } -// 19.1.1.1 Object ( [ value ] ) +// 19.1.1.1Object ( [ value ] ) HWTEST_F_L0(BuiltinsObjectTest, ObjectConstructor) { JSHandle function(thread, BuiltinsObjectTestCreate(thread)); @@ -154,7 +154,7 @@ HWTEST_F_L0(BuiltinsObjectTest, ObjectConstructor) ASSERT_TRUE(jtHandleVn->IsExtensible()); } -// 19.1.2.1 Object.assign ( target, ...sources ) +// 19.1.2.1Object.assign ( target, ...sources ) HWTEST_F_L0(BuiltinsObjectTest, Assign) { JSHandle function(thread, BuiltinsObjectTestCreate(thread)); @@ -163,12 +163,12 @@ HWTEST_F_L0(BuiltinsObjectTest, Assign) JSHandle objHandle2 = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(function), function); - JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString("x")); + JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("x")); JSHandle value1(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(objHandle1), key1, value1); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(objHandle1), key1).GetValue()->GetInt(), 1); - JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromString("y")); + JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("y")); JSHandle value2(thread, JSTaggedValue(2)); JSObject::SetProperty(thread, JSHandle(objHandle2), key2, value2); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(objHandle2), key2).GetValue()->GetInt(), 2); @@ -189,7 +189,7 @@ HWTEST_F_L0(BuiltinsObjectTest, Assign) EXPECT_EQ(JSObject::GetProperty(thread, jtHandle, key2).GetValue()->GetInt(), 2); } -// 19.1.2.2 Object.create ( O [ , Properties ] ) +// 19.1.2.2Object.create ( O [ , Properties ] ) HWTEST_F_L0(BuiltinsObjectTest, Create) { JSHandle function(thread, BuiltinsObjectTestCreate(thread)); @@ -212,7 +212,7 @@ HWTEST_F_L0(BuiltinsObjectTest, Create) ASSERT_EQ(resultProto, funcProto.GetTaggedValue()); // has prop - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("prop")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("prop")); JSHandle objHandle = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle::Cast(function), function); EXPECT_TRUE(*objHandle != nullptr); @@ -252,7 +252,7 @@ HWTEST_F_L0(BuiltinsObjectTest, Create) ASSERT_EQ(resultUn.GetRawData(), JSTaggedValue::VALUE_EXCEPTION); } -// 19.1.2.3 Object.defineProperties ( O, Properties ) +// 19.1.2.3Object.defineProperties ( O, Properties ) HWTEST_F_L0(BuiltinsObjectTest, DefineProperties) { JSHandle function(thread, BuiltinsObjectTestCreate(thread)); @@ -260,7 +260,7 @@ HWTEST_F_L0(BuiltinsObjectTest, DefineProperties) JSHandle objFunc(env->GetObjectFunction()); JSHandle objHandle = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(function), function); - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("prop")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("prop")); JSHandle jsobjHandle = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(function), function); @@ -288,7 +288,7 @@ HWTEST_F_L0(BuiltinsObjectTest, DefineProperties) EXPECT_TRUE(!descRes.IsWritable()); } -// 19.1.2.4 Object.defineProperty ( O, P, Attributes ) +// 19.1.2.4Object.defineProperty ( O, P, Attributes ) HWTEST_F_L0(BuiltinsObjectTest, DefineProperty) { JSHandle function(thread, BuiltinsObjectTestCreate(thread)); @@ -306,7 +306,7 @@ HWTEST_F_L0(BuiltinsObjectTest, DefineProperty) JSHandle writable(thread, JSTaggedValue(desc.IsWritable())); JSObject::CreateDataProperty(thread, attHandle, writableStr, writable); - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("x")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("x")); PropertyDescriptor descNw(thread); JSObject::GetOwnProperty(thread, objHandle, key, descNw); @@ -330,7 +330,7 @@ HWTEST_F_L0(BuiltinsObjectTest, DefineProperty) EXPECT_TRUE(descRes.HasWritable()); } -// 19.1.2.5 Object.freeze ( O ) +// 19.1.2.5Object.freeze ( O ) HWTEST_F_L0(BuiltinsObjectTest, Freeze) { JSHandle function(thread, BuiltinsObjectTestCreate(thread)); @@ -361,7 +361,7 @@ HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertyDesciptor) JSHandle objHandle = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(function), function); - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("x")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("x")); PropertyDescriptor descEnum(thread); descEnum.SetWritable(true); @@ -393,7 +393,7 @@ HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertyNames) JSHandle objHandle = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(function), function); - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("x")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("x")); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(objHandle), key, value); @@ -461,8 +461,8 @@ HWTEST_F_L0(BuiltinsObjectTest, Is) ASSERT_EQ(objResult2.GetRawData(), JSTaggedValue::True().GetRawData()); // string compare - JSHandle testStrValue1 = thread->GetEcmaVM()->GetFactory()->NewFromString("helloworld"); - JSHandle testStrValue2 = thread->GetEcmaVM()->GetFactory()->NewFromString("helloworld"); + JSHandle testStrValue1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("helloworld"); + JSHandle testStrValue2 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("helloworld"); auto strCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); strCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -557,7 +557,7 @@ HWTEST_F_L0(BuiltinsObjectTest, IsExtensible) HWTEST_F_L0(BuiltinsObjectTest, IsFrozen) { JSHandle function(thread, BuiltinsObjectTestCreate(thread)); - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("x")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("x")); JSHandle value(thread, JSTaggedValue(1)); // An object is extensible by default, so it is also non-frozen. @@ -712,7 +712,7 @@ HWTEST_F_L0(BuiltinsObjectTest, SetPrototypeOf) ASSERT_EQ(result.GetRawData(), obj.GetTaggedValue().GetRawData()); // test obj has property "y". - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("y")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("y")); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(obj), key).GetValue()->GetInt(), 1); } @@ -721,7 +721,7 @@ HWTEST_F_L0(BuiltinsObjectTest, HasOwnProperty) { JSHandle obj(thread, CreateBuiltinJSObject(thread, "x")); CString keyCStr = "x"; - JSHandle keyString = thread->GetEcmaVM()->GetFactory()->NewFromString(&keyCStr[0]); + JSHandle keyString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(&keyCStr[0]); JSHandle key(keyString); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); @@ -788,7 +788,7 @@ HWTEST_F_L0(BuiltinsObjectTest, IsPrototypeOfTrue) HWTEST_F_L0(BuiltinsObjectTest, PropertyIsEnumerable) { JSHandle obj(thread, CreateBuiltinJSObject(thread, "x")); - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("x")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("x")); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -810,10 +810,10 @@ HWTEST_F_L0(BuiltinsObjectTest, ToLocaleString) thread->GetEcmaVM()->GetGlobalEnv(), reinterpret_cast(BuiltinsObject::ToString)); calleeFunc->GetClass()->SetCallable(true); JSHandle calleeValue(calleeFunc); - JSHandle calleeKey(thread->GetEcmaVM()->GetFactory()->NewFromString("toString")); + JSHandle calleeKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("toString")); JSObject::SetProperty(thread, obj, calleeKey, calleeValue); - JSHandle resultValue = thread->GetEcmaVM()->GetFactory()->NewFromString("[object Object]"); + JSHandle resultValue = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("[object Object]"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -834,7 +834,7 @@ HWTEST_F_L0(BuiltinsObjectTest, ToString) JSHandle obj = JSHandle(thread, CreateBuiltinJSObject(thread, "x")); // object - JSHandle resultValue = thread->GetEcmaVM()->GetFactory()->NewFromString("[object Object]"); + JSHandle resultValue = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("[object Object]"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue()); @@ -848,7 +848,8 @@ HWTEST_F_L0(BuiltinsObjectTest, ToString) // array JSHandle arr = thread->GetEcmaVM()->GetFactory()->NewJSArray(); - JSHandle resultArrValue = thread->GetEcmaVM()->GetFactory()->NewFromString("[object Array]"); + JSHandle resultArrValue = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("[object Array]"); auto arrEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); arrEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); arrEcmaRuntimeCallInfo->SetThis(arr.GetTaggedValue()); @@ -861,8 +862,9 @@ HWTEST_F_L0(BuiltinsObjectTest, ToString) ASSERT_EQ(resultArrValue->Compare(reinterpret_cast(resultArr.GetRawData())), 0); // string - JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromString("hello"); - JSHandle resultStrValue = thread->GetEcmaVM()->GetFactory()->NewFromString("[object String]"); + JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("hello"); + JSHandle resultStrValue = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("[object String]"); auto strEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); strEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); strEcmaRuntimeCallInfo->SetThis(str.GetTaggedValue()); @@ -876,7 +878,8 @@ HWTEST_F_L0(BuiltinsObjectTest, ToString) // function JSHandle func = thread->GetEcmaVM()->GetFactory()->NewJSFunction(thread->GetEcmaVM()->GetGlobalEnv()); - JSHandle resultFuncValue = thread->GetEcmaVM()->GetFactory()->NewFromString("[object Function]"); + JSHandle resultFuncValue = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("[object Function]"); auto funcEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); funcEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); funcEcmaRuntimeCallInfo->SetThis(func.GetTaggedValue()); @@ -894,7 +897,7 @@ HWTEST_F_L0(BuiltinsObjectTest, ToString) JSHandle errorObject = env->GetErrorFunction(); JSHandle error = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(errorObject), errorObject); - JSHandle errorValue = thread->GetEcmaVM()->GetFactory()->NewFromString("[object Error]"); + JSHandle errorValue = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("[object Error]"); auto errorEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); errorEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); errorEcmaRuntimeCallInfo->SetThis(error.GetTaggedValue()); @@ -910,7 +913,8 @@ HWTEST_F_L0(BuiltinsObjectTest, ToString) JSHandle value(thread, JSTaggedValue::False()); JSHandle booleanObject(env->GetBooleanFunction()); JSHandle boolean = thread->GetEcmaVM()->GetFactory()->NewJSPrimitiveRef(booleanObject, value); - JSHandle resultBoolValue = thread->GetEcmaVM()->GetFactory()->NewFromString("[object Boolean]"); + JSHandle resultBoolValue = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("[object Boolean]"); auto boolEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); boolEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); boolEcmaRuntimeCallInfo->SetThis(boolean.GetTaggedValue()); @@ -923,7 +927,8 @@ HWTEST_F_L0(BuiltinsObjectTest, ToString) ASSERT_EQ(resultBoolValue->Compare(reinterpret_cast(resultBool.GetRawData())), 0); // number - JSHandle resultNumValue = thread->GetEcmaVM()->GetFactory()->NewFromString("[object Number]"); + JSHandle resultNumValue = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("[object Number]"); auto numEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); numEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); numEcmaRuntimeCallInfo->SetThis(JSTaggedValue(static_cast(0))); diff --git a/ecmascript/builtins/tests/builtins_promise_test.cpp b/ecmascript/builtins/tests/builtins_promise_test.cpp index cf31f16c11cadbcc25251904afd0708d483b105d..cba9fba226c33b3ff291a6e47d94eb437101cff7 100644 --- a/ecmascript/builtins/tests/builtins_promise_test.cpp +++ b/ecmascript/builtins/tests/builtins_promise_test.cpp @@ -106,7 +106,7 @@ JSTaggedValue TestPromiseThenOnResolved(EcmaRuntimeCallInfo *argv) { auto factory = argv->GetThread()->GetEcmaVM()->GetFactory(); JSHandle result = BuiltinsBase::GetCallArg(argv, 0); - auto expect = factory->NewFromString("resolve"); + auto expect = factory->NewFromCanBeCompressString("resolve"); EXPECT_EQ(JSTaggedValue::SameValue(result.GetTaggedValue(), expect.GetTaggedValue()), true); return JSTaggedValue::Undefined(); } @@ -116,7 +116,7 @@ JSTaggedValue TestPromiseThenOnRejected(EcmaRuntimeCallInfo *argv) { auto factory = argv->GetThread()->GetEcmaVM()->GetFactory(); JSHandle result = BuiltinsBase::GetCallArg(argv, 0); - auto expect = factory->NewFromString("reject"); + auto expect = factory->NewFromCanBeCompressString("reject"); EXPECT_EQ(JSTaggedValue::SameValue(result.GetTaggedValue(), expect.GetTaggedValue()), true); return JSTaggedValue::Undefined(); } @@ -162,7 +162,8 @@ HWTEST_F_L0(BuiltinsPromiseTest, Reject2) // constructor promise1 JSHandle promise = JSHandle::Cast(env->GetPromiseFunction()); - JSHandle paramMsg1 = JSHandle::Cast(factory->NewFromString("Promise reject")); + JSHandle paramMsg1 = + JSHandle::Cast(factory->NewFromCanBeCompressString("Promise reject")); /** * @tc.steps: step1. var p1 = Promise.reject("Promise reject") @@ -241,7 +242,8 @@ HWTEST_F_L0(BuiltinsPromiseTest, Resolve2) // constructor promise1 JSHandle promise = JSHandle::Cast(env->GetPromiseFunction()); - JSHandle paramMsg1 = JSHandle::Cast(factory->NewFromString("Promise reject")); + JSHandle paramMsg1 = + JSHandle::Cast(factory->NewFromCanBeCompressString("Promise reject")); /** * @tc.steps: step1. var p1 = Promise.reject("Promise reject") @@ -350,7 +352,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, Race1) EXPECT_EQ(racePromise->GetPromiseResult().IsUndefined(), true); } -/** +/* * @tc.name: Race2 * @tc.desc: The Race method receives an array, uses the Then method to save the task in the task queue, and outputs * the execution result of the queue. @@ -619,7 +621,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, ThenResolve) auto factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle promise = JSHandle::Cast(env->GetPromiseFunction()); - JSHandle paramMsg = JSHandle::Cast(factory->NewFromString("resolve")); + JSHandle paramMsg = JSHandle::Cast(factory->NewFromCanBeCompressString("resolve")); /** * @tc.steps: step1. var p1 = Promise.resolve("resolve") @@ -677,7 +679,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, ThenReject) auto factory = EcmaVM::Cast(instance)->GetFactory(); JSHandle promise = JSHandle::Cast(env->GetPromiseFunction()); - JSHandle paramMsg = JSHandle::Cast(factory->NewFromString("reject")); + JSHandle paramMsg = JSHandle::Cast(factory->NewFromCanBeCompressString("reject")); /** * @tc.steps: step1. var p1 = Promise.Reject(5) diff --git a/ecmascript/builtins/tests/builtins_proxy_test.cpp b/ecmascript/builtins/tests/builtins_proxy_test.cpp index 2ae6072e5ae181b8e2238f153a084b59626ee9bd..20e200f067a543f5397dd95ad872fc047aca4383 100644 --- a/ecmascript/builtins/tests/builtins_proxy_test.cpp +++ b/ecmascript/builtins/tests/builtins_proxy_test.cpp @@ -96,7 +96,7 @@ HWTEST_F_L0(BuiltinsProxyTest, Revocable) JSHandle globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle proxyFun(globalEnv->GetProxyFunction()); - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("prop")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("prop")); PropertyDescriptor desc(thread); desc.SetWritable(false); JSObject::DefineOwnProperty(thread, handler, key, desc); diff --git a/ecmascript/builtins/tests/builtins_reflect_test.cpp b/ecmascript/builtins/tests/builtins_reflect_test.cpp index d8466f677ecc0807fad158193ffde93258e7f1c2..d630efc9cbbb0323c9e33e4864c27ef69e0eb2c5 100644 --- a/ecmascript/builtins/tests/builtins_reflect_test.cpp +++ b/ecmascript/builtins/tests/builtins_reflect_test.cpp @@ -81,12 +81,12 @@ JSTaggedValue TestReflectApply(EcmaRuntimeCallInfo *argv) JSTaggedValue testA = JSObject::GetProperty(thread, thisValue, - JSHandle(factory->NewFromString("test_reflect_apply_a"))) + JSHandle(factory->NewFromCanBeCompressString("test_reflect_apply_a"))) .GetValue() .GetTaggedValue(); JSTaggedValue testB = JSObject::GetProperty(thread, thisValue, - JSHandle(factory->NewFromString("test_reflect_apply_b"))) + JSHandle(factory->NewFromCanBeCompressString("test_reflect_apply_b"))) .GetValue() .GetTaggedValue(); @@ -97,7 +97,6 @@ JSTaggedValue TestReflectApply(EcmaRuntimeCallInfo *argv) // Reflect.apply (target, thisArgument, argumentsList) HWTEST_F_L0(BuiltinsReflectTest, ReflectApply) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -108,10 +107,10 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectApply) JSHandle thisArgument = factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle(TestObjectCreate(thread))); JSObject::SetProperty(thread, JSHandle(thisArgument), - JSHandle(factory->NewFromString("test_reflect_apply_a")), + JSHandle(factory->NewFromCanBeCompressString("test_reflect_apply_a")), JSHandle(thread, JSTaggedValue(11))); JSObject::SetProperty(thread, JSHandle(thisArgument), - JSHandle(factory->NewFromString("test_reflect_apply_b")), + JSHandle(factory->NewFromCanBeCompressString("test_reflect_apply_b")), JSHandle(thread, JSTaggedValue(22))); // argumentsList JSHandle argumentsList(JSArray::ArrayCreate(thread, JSTaggedNumber(2))); @@ -133,15 +132,14 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectApply) ASSERT_EQ(result.GetRawData(), JSTaggedValue(110).GetRawData()); JSObject::DeleteProperty(thread, (thisArgument), - JSHandle(factory->NewFromString("test_reflect_apply_a"))); + JSHandle(factory->NewFromCanBeCompressString("test_reflect_apply_a"))); JSObject::DeleteProperty(thread, (thisArgument), - JSHandle(factory->NewFromString("test_reflect_apply_b"))); + JSHandle(factory->NewFromCanBeCompressString("test_reflect_apply_b"))); } // Reflect.construct (target, argumentsList [ , newTarget]) HWTEST_F_L0(BuiltinsReflectTest, ReflectConstruct) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -150,7 +148,8 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectConstruct) JSHandle target = JSHandle::Cast(env->GetStringFunction()); // argumentsList JSHandle argumentsList(JSArray::ArrayCreate(thread, JSTaggedNumber(1))); - PropertyDescriptor desc(thread, JSHandle::Cast(factory->NewFromString("ReflectConstruct"))); + PropertyDescriptor desc(thread, + JSHandle::Cast(factory->NewFromCanBeCompressString("ReflectConstruct"))); JSArray::DefineOwnProperty(thread, argumentsList, JSHandle(thread, JSTaggedValue(0)), desc); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); @@ -165,22 +164,20 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectConstruct) ASSERT_TRUE(result.IsECMAObject()); JSHandle taggedResult(thread, result); JSHandle refResult = JSHandle::Cast(taggedResult); - JSHandle ruler = factory->NewFromString("ReflectConstruct"); + JSHandle ruler = factory->NewFromCanBeCompressString("ReflectConstruct"); ASSERT_EQ(EcmaString::Cast(refResult->GetValue().GetTaggedObject())->Compare(*ruler), 0); } // Reflect.defineProperty (target, propertyKey, attributes) HWTEST_F_L0(BuiltinsReflectTest, ReflectDefineProperty) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // target JSHandle target = factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle(TestObjectCreate(thread))); // propertyKey - JSHandle key(factory->NewFromString("test_reflect_define_property")); + JSHandle key(factory->NewFromCanBeCompressString("test_reflect_define_property")); // attributes JSHandle attributes = factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle(TestObjectCreate(thread))); @@ -224,15 +221,13 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectDefineProperty) // Reflect.deleteProperty (target, propertyKey) HWTEST_F_L0(BuiltinsReflectTest, ReflectDeleteProperty) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // target JSHandle target = factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle(TestObjectCreate(thread))); // propertyKey - JSHandle key(factory->NewFromString("test_reflect_delete_property")); + JSHandle key(factory->NewFromCanBeCompressString("test_reflect_delete_property")); JSHandle value(thread, JSTaggedValue(101)); JSObject::SetProperty(thread, JSHandle(target), key, value); @@ -254,15 +249,13 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectDeleteProperty) // Reflect.get (target, propertyKey [ , receiver]) HWTEST_F_L0(BuiltinsReflectTest, ReflectGet) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // target JSHandle target = factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle(TestObjectCreate(thread))); // propertyKey - JSHandle key(factory->NewFromString("test_reflect_get")); + JSHandle key(factory->NewFromCanBeCompressString("test_reflect_get")); // set property JSHandle value(thread, JSTaggedValue(101.5)); JSObject::SetProperty(thread, JSHandle(target), key, value); @@ -283,15 +276,13 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectGet) // Reflect.getOwnPropertyDescriptor ( target, propertyKey ) HWTEST_F_L0(BuiltinsReflectTest, ReflectGetOwnPropertyDescriptor) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // target JSHandle target = factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle(TestObjectCreate(thread))); // propertyKey - JSHandle key(factory->NewFromString("test_reflect_get_property_descriptor")); + JSHandle key(factory->NewFromCanBeCompressString("test_reflect_get_property_descriptor")); PropertyDescriptor desc(thread, JSHandle(thread, JSTaggedValue(102)), true, false, true); ASSERT_EQ(JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle(target), key, desc), true); @@ -329,8 +320,6 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectGetOwnPropertyDescriptor) // Reflect.getPrototypeOf (target) HWTEST_F_L0(BuiltinsReflectTest, ReflectGetPrototypeOf) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle target = @@ -355,15 +344,13 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectGetPrototypeOf) // Reflect.has (target, propertyKey) HWTEST_F_L0(BuiltinsReflectTest, ReflectHas) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // target JSHandle target = factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle(TestObjectCreate(thread))); // propertyKey - JSHandle key(factory->NewFromString("test_reflect_has")); + JSHandle key(factory->NewFromCanBeCompressString("test_reflect_has")); JSHandle value(thread, JSTaggedValue(103)); ASSERT_EQ(JSObject::SetProperty(thread, JSHandle(target), key, value), true); @@ -382,8 +369,6 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectHas) // Reflect.isExtensible (target) HWTEST_F_L0(BuiltinsReflectTest, ReflectIsExtensible) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // target @@ -405,17 +390,15 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectIsExtensible) // Reflect.ownKeys (target) HWTEST_F_L0(BuiltinsReflectTest, ReflectOwnKeys) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // target JSHandle target = factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle(TestObjectCreate(thread))); - JSHandle key0(factory->NewFromString("test_reflect_own_keys1")); + JSHandle key0(factory->NewFromCanBeCompressString("test_reflect_own_keys1")); JSHandle value0(thread, JSTaggedValue(104)); ASSERT_EQ(JSObject::SetProperty(thread, JSHandle(target), key0, value0), true); - JSHandle key1(factory->NewFromString("test_reflect_own_keys2")); + JSHandle key1(factory->NewFromCanBeCompressString("test_reflect_own_keys2")); JSHandle value1(thread, JSTaggedValue(105)); ASSERT_EQ(JSObject::SetProperty(thread, JSHandle(target), key1, value1), true); @@ -454,8 +437,6 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectOwnKeys) // Reflect.preventExtensions (target) HWTEST_F_L0(BuiltinsReflectTest, ReflectPreventExtensions) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // target @@ -478,15 +459,13 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectPreventExtensions) // Reflect.set (target, propertyKey, V [ , receiver]) HWTEST_F_L0(BuiltinsReflectTest, ReflectSet) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // target JSHandle target = factory->NewJSObjectByConstructor(TestObjectCreate(thread), JSHandle(TestObjectCreate(thread))); // propertyKey - JSHandle key(factory->NewFromString("test_reflect_set")); + JSHandle key(factory->NewFromCanBeCompressString("test_reflect_set")); // value JSHandle value(thread, JSTaggedValue(106)); @@ -509,8 +488,6 @@ HWTEST_F_L0(BuiltinsReflectTest, ReflectSet) // Reflect.setPrototypeOf (target, proto) HWTEST_F_L0(BuiltinsReflectTest, ReflectSetPrototypeOf) { - ASSERT_NE(thread, nullptr); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle target = diff --git a/ecmascript/builtins/tests/builtins_regexp_test.cpp b/ecmascript/builtins/tests/builtins_regexp_test.cpp index ea39a66fa11ccbef6715dcf58a4140eccf40225b..ad9990e3a4de5ce0fa9c60998a37f8d79732cee2 100644 --- a/ecmascript/builtins/tests/builtins_regexp_test.cpp +++ b/ecmascript/builtins/tests/builtins_regexp_test.cpp @@ -60,33 +60,33 @@ public: PandaVM *instance {nullptr}; EcmaHandleScope *scope {nullptr}; JSThread *thread {nullptr}; - - JSTaggedValue CreateRegExpObjByPatternAndFlags(JSThread *thread, const JSHandle &pattern, - const JSHandle &flags) - { - JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); - JSHandle regexp(env->GetRegExpFunction()); - JSHandle globalObject(thread, env->GetGlobalObject()); - // make dyn_runtime_call_info - // 8 : test case - auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*regexp), 8); - ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue()); - ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue()); - ecmaRuntimeCallInfo->SetCallArg(0, pattern.GetTaggedValue()); - ecmaRuntimeCallInfo->SetCallArg(1, flags.GetTaggedValue()); - - [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get()); - // invoke RegExpConstructor method - JSTaggedValue result = BuiltinsRegExp::RegExpConstructor(ecmaRuntimeCallInfo.get()); - return result; - } }; +JSTaggedValue CreateRegExpObjByPatternAndFlags(JSThread *thread, const JSHandle &pattern, + const JSHandle &flags) +{ + JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); + JSHandle regexp(env->GetRegExpFunction()); + JSHandle globalObject(thread, env->GetGlobalObject()); + // make dyn_runtime_call_info + // 8 : test case + auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*regexp), 8); + ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue()); + ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue()); + ecmaRuntimeCallInfo->SetCallArg(0, pattern.GetTaggedValue()); + ecmaRuntimeCallInfo->SetCallArg(1, flags.GetTaggedValue()); + + [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get()); + // invoke RegExpConstructor method + JSTaggedValue result = BuiltinsRegExp::RegExpConstructor(ecmaRuntimeCallInfo.get()); + return result; +} + HWTEST_F_L0(BuiltinsRegExpTest, RegExpConstructor1) { // invoke RegExpConstructor method - JSHandle pattern = thread->GetEcmaVM()->GetFactory()->NewFromString("\\w+"); - JSHandle flags = thread->GetEcmaVM()->GetFactory()->NewFromString("i"); + JSHandle pattern = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("\\w+"); + JSHandle flags = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("i"); JSTaggedValue result = CreateRegExpObjByPatternAndFlags(thread, pattern, flags); // ASSERT IsRegExp() @@ -103,8 +103,8 @@ HWTEST_F_L0(BuiltinsRegExpTest, RegExpConstructor1) HWTEST_F_L0(BuiltinsRegExpTest, RegExpConstructor2) { // invoke RegExpConstructor method - JSHandle pattern = thread->GetEcmaVM()->GetFactory()->NewFromString("\\w+"); - JSHandle flags = thread->GetEcmaVM()->GetFactory()->NewFromString("i"); + JSHandle pattern = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("\\w+"); + JSHandle flags = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("i"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern, flags); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); @@ -136,15 +136,15 @@ HWTEST_F_L0(BuiltinsRegExpTest, RegExpConstructor2) HWTEST_F_L0(BuiltinsRegExpTest, RegExpConstructor3) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("\\w+"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("i"); + JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("\\w+"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("i"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle regexp(env->GetRegExpFunction()); JSHandle globalObject(thread, env->GetGlobalObject()); - JSHandle flags2 = thread->GetEcmaVM()->GetFactory()->NewFromString("gi"); + JSHandle flags2 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("gi"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*regexp), 8); ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue()); @@ -170,64 +170,65 @@ HWTEST_F_L0(BuiltinsRegExpTest, RegExpConstructor3) HWTEST_F_L0(BuiltinsRegExpTest, GetSource1) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString(""); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("i"); + JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(""); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("i"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle result1Handle(thread, result1); // invoke GetSource method - JSHandle source(thread, thread->GetEcmaVM()->GetFactory()->NewFromString("source").GetTaggedValue()); + JSHandle source( + thread, thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("source").GetTaggedValue()); JSHandle sourceResult(JSObject::GetProperty(thread, result1Handle, source).GetValue()); - JSHandle expect = thread->GetEcmaVM()->GetFactory()->NewFromString("(?:)"); + JSHandle expect = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("(?:)"); ASSERT_EQ(static_cast(sourceResult->GetTaggedObject())->Compare(*expect), 0); } HWTEST_F_L0(BuiltinsRegExpTest, GetSource2) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("/w+"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("i"); + JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("/w+"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("i"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle result1Handle(thread, result1); // invoke GetSource method - JSHandle source(thread->GetEcmaVM()->GetFactory()->NewFromString("source")); + JSHandle source(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("source")); JSHandle sourceResult(JSObject::GetProperty(thread, result1Handle, source).GetValue()); - JSHandle expect = thread->GetEcmaVM()->GetFactory()->NewFromString("\\/w+"); + JSHandle expect = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("\\/w+"); ASSERT_EQ(static_cast(sourceResult->GetTaggedObject())->Compare(*expect), 0); } HWTEST_F_L0(BuiltinsRegExpTest, Get) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("\\w+"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("gimuy"); + JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("\\w+"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("gimuy"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle result1Handle(thread, result1); - JSHandle global(thread->GetEcmaVM()->GetFactory()->NewFromString("global")); + JSHandle global(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("global")); JSTaggedValue taggedGlobalResult = JSTaggedValue(JSObject::GetProperty(thread, result1Handle, global).GetValue().GetTaggedValue()); ASSERT_EQ(taggedGlobalResult.GetRawData(), JSTaggedValue::True().GetRawData()); - JSHandle ignoreCase(thread->GetEcmaVM()->GetFactory()->NewFromString("ignoreCase")); + JSHandle ignoreCase(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("ignoreCase")); JSTaggedValue taggedIgnoreCaseResult = JSTaggedValue(JSObject::GetProperty(thread, result1Handle, ignoreCase).GetValue().GetTaggedValue()); ASSERT_EQ(taggedIgnoreCaseResult.GetRawData(), JSTaggedValue::True().GetRawData()); - JSHandle multiline(thread->GetEcmaVM()->GetFactory()->NewFromString("multiline")); + JSHandle multiline(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("multiline")); JSTaggedValue taggedMultilineResult = JSTaggedValue(JSObject::GetProperty(thread, result1Handle, multiline).GetValue().GetTaggedValue()); ASSERT_EQ(taggedMultilineResult.GetRawData(), JSTaggedValue::True().GetRawData()); - JSHandle sticky(thread->GetEcmaVM()->GetFactory()->NewFromString("sticky")); + JSHandle sticky(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("sticky")); JSTaggedValue taggedStickyResult = JSTaggedValue(JSObject::GetProperty(thread, result1Handle, sticky).GetValue().GetTaggedValue()); ASSERT_EQ(taggedStickyResult.GetRawData(), JSTaggedValue::True().GetRawData()); - JSHandle unicode(thread->GetEcmaVM()->GetFactory()->NewFromString("unicode")); + JSHandle unicode(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("unicode")); JSTaggedValue taggedUnicodeResult = JSTaggedValue(JSObject::GetProperty(thread, result1Handle, unicode).GetValue().GetTaggedValue()); ASSERT_EQ(taggedUnicodeResult.GetRawData(), JSTaggedValue::True().GetRawData()); @@ -236,24 +237,24 @@ HWTEST_F_L0(BuiltinsRegExpTest, Get) HWTEST_F_L0(BuiltinsRegExpTest, GetFlags) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("\\w+"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("imuyg"); + JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("\\w+"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("imuyg"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle result1Handle(thread, result1); // invoke GetFlags method - JSHandle flags(thread->GetEcmaVM()->GetFactory()->NewFromString("flags")); + JSHandle flags(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("flags")); JSHandle flagsResult(JSObject::GetProperty(thread, result1Handle, flags).GetValue()); - JSHandle expectResult = thread->GetEcmaVM()->GetFactory()->NewFromString("gimuy"); + JSHandle expectResult = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("gimuy"); ASSERT_EQ(static_cast(flagsResult->GetTaggedObject())->Compare(*expectResult), 0); } HWTEST_F_L0(BuiltinsRegExpTest, toString) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("\\w+"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("imuyg"); + JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("\\w+"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("imuyg"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); @@ -266,20 +267,21 @@ HWTEST_F_L0(BuiltinsRegExpTest, toString) JSTaggedValue toStringResult = BuiltinsRegExp::ToString(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(toStringResult.IsString()); JSHandle toStringResultHandle(thread, toStringResult); - JSHandle expectResult = thread->GetEcmaVM()->GetFactory()->NewFromString("/\\w+/gimuy"); + JSHandle expectResult = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("/\\w+/gimuy"); ASSERT_EQ(static_cast(toStringResultHandle->GetTaggedObject())->Compare(*expectResult), 0); } HWTEST_F_L0(BuiltinsRegExpTest, Exec1) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("quick\\s(brown).+?(jumps)"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("ig"); + JSHandle pattern1 = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("quick\\s(brown).+?(jumps)"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("ig"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); JSHandle inputString = - thread->GetEcmaVM()->GetFactory()->NewFromString("The Quick Brown Fox Jumps Over The Lazy Dog"); + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("The Quick Brown Fox Jumps Over The Lazy Dog"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); @@ -290,38 +292,39 @@ HWTEST_F_L0(BuiltinsRegExpTest, Exec1) JSTaggedValue results = BuiltinsRegExp::Exec(ecmaRuntimeCallInfo.get()); JSHandle execResult(thread, results); - JSHandle resultZero = thread->GetEcmaVM()->GetFactory()->NewFromString("Quick Brown Fox Jumps"); - JSHandle resultOne = thread->GetEcmaVM()->GetFactory()->NewFromString("Brown"); - JSHandle resultTwo = thread->GetEcmaVM()->GetFactory()->NewFromString("Jumps"); + JSHandle resultZero = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Quick Brown Fox Jumps"); + JSHandle resultOne = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Brown"); + JSHandle resultTwo = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Jumps"); - JSHandle index(thread->GetEcmaVM()->GetFactory()->NewFromString("index")); + JSHandle index(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("index")); JSHandle indexHandle(JSObject::GetProperty(thread, execResult, index).GetValue()); uint32_t resultIndex = JSTaggedValue::ToUint32(thread, indexHandle); ASSERT_TRUE(resultIndex == 4); - JSHandle input(thread->GetEcmaVM()->GetFactory()->NewFromString("input")); + JSHandle input(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("input")); JSHandle inputHandle(JSObject::GetProperty(thread, execResult, input).GetValue()); JSHandle outputInput = JSTaggedValue::ToString(thread, inputHandle); ASSERT_EQ(outputInput->Compare(*inputString), 0); - JSHandle zero(thread->GetEcmaVM()->GetFactory()->NewFromString("0")); + JSHandle zero(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0")); JSHandle zeroHandle(JSObject::GetProperty(thread, execResult, zero).GetValue()); JSHandle outputZero = JSTaggedValue::ToString(thread, zeroHandle); ASSERT_EQ(outputZero->Compare(*resultZero), 0); - JSHandle first(thread->GetEcmaVM()->GetFactory()->NewFromString("1")); + JSHandle first(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1")); JSHandle oneHandle(JSObject::GetProperty(thread, execResult, first).GetValue()); JSHandle outputOne = JSTaggedValue::ToString(thread, oneHandle); ASSERT_EQ(outputOne->Compare(*resultOne), 0); - JSHandle second(thread->GetEcmaVM()->GetFactory()->NewFromString("2")); + JSHandle second(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2")); JSHandle twoHandle(JSObject::GetProperty(thread, execResult, second).GetValue()); JSHandle outputTwo = JSTaggedValue::ToString(thread, twoHandle); ASSERT_EQ(outputTwo->Compare(*resultTwo), 0); JSHandle regexp = JSHandle::Cast(value); - JSHandle lastIndexHandle(thread->GetEcmaVM()->GetFactory()->NewFromString("lastIndex")); + JSHandle lastIndexHandle(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("lastIndex")); JSHandle lastIndexObj(JSObject::GetProperty(thread, regexp, lastIndexHandle).GetValue()); int lastIndex = lastIndexObj->GetInt(); ASSERT_TRUE(lastIndex == 25); @@ -330,12 +333,13 @@ HWTEST_F_L0(BuiltinsRegExpTest, Exec1) HWTEST_F_L0(BuiltinsRegExpTest, Exec2) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("((1)|(12))((3)|(23))"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("ig"); + JSHandle pattern1 = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("((1)|(12))((3)|(23))"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("ig"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); - JSHandle inputString = thread->GetEcmaVM()->GetFactory()->NewFromString("123"); + JSHandle inputString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("123"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); @@ -346,57 +350,57 @@ HWTEST_F_L0(BuiltinsRegExpTest, Exec2) JSTaggedValue results = BuiltinsRegExp::Exec(ecmaRuntimeCallInfo.get()); JSHandle execResult(thread, results); - JSHandle resultZero = thread->GetEcmaVM()->GetFactory()->NewFromString("123"); - JSHandle resultOne = thread->GetEcmaVM()->GetFactory()->NewFromString("1"); - JSHandle resultTwo = thread->GetEcmaVM()->GetFactory()->NewFromString("1"); - JSHandle resultFour = thread->GetEcmaVM()->GetFactory()->NewFromString("23"); - JSHandle resultSix = thread->GetEcmaVM()->GetFactory()->NewFromString("23"); + JSHandle resultZero = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("123"); + JSHandle resultOne = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1"); + JSHandle resultTwo = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1"); + JSHandle resultFour = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("23"); + JSHandle resultSix = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("23"); - JSHandle index(thread->GetEcmaVM()->GetFactory()->NewFromString("index")); + JSHandle index(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("index")); JSHandle indexHandle(JSObject::GetProperty(thread, execResult, index).GetValue()); uint32_t resultIndex = JSTaggedValue::ToUint32(thread, indexHandle); ASSERT_TRUE(resultIndex == 0); - JSHandle input(thread->GetEcmaVM()->GetFactory()->NewFromString("input")); + JSHandle input(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("input")); JSHandle inputHandle(JSObject::GetProperty(thread, execResult, input).GetValue()); JSHandle outputInput = JSTaggedValue::ToString(thread, inputHandle); ASSERT_EQ(outputInput->Compare(*inputString), 0); - JSHandle zero(thread->GetEcmaVM()->GetFactory()->NewFromString("0")); + JSHandle zero(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0")); JSHandle zeroHandle(JSObject::GetProperty(thread, execResult, zero).GetValue()); JSHandle outputZero = JSTaggedValue::ToString(thread, zeroHandle); ASSERT_EQ(outputZero->Compare(*resultZero), 0); - JSHandle first(thread->GetEcmaVM()->GetFactory()->NewFromString("1")); + JSHandle first(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1")); JSHandle oneHandle(JSObject::GetProperty(thread, execResult, first).GetValue()); JSHandle outputOne = JSTaggedValue::ToString(thread, oneHandle); ASSERT_EQ(outputOne->Compare(*resultOne), 0); - JSHandle second(thread->GetEcmaVM()->GetFactory()->NewFromString("2")); + JSHandle second(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2")); JSHandle twoHandle(JSObject::GetProperty(thread, execResult, second).GetValue()); JSHandle outputTwo = JSTaggedValue::ToString(thread, twoHandle); ASSERT_EQ(outputTwo->Compare(*resultTwo), 0); JSHandle regexp = JSHandle::Cast(value); - JSHandle lastIndexHandle(thread->GetEcmaVM()->GetFactory()->NewFromString("lastIndex")); + JSHandle lastIndexHandle(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("lastIndex")); JSHandle lastIndexObj(JSObject::GetProperty(thread, regexp, lastIndexHandle).GetValue()); int lastIndex = lastIndexObj->GetInt(); ASSERT_TRUE(lastIndex == 3); - JSHandle third(thread->GetEcmaVM()->GetFactory()->NewFromString("3")); + JSHandle third(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("3")); JSHandle thirdHandle(JSObject::GetProperty(thread, execResult, third).GetValue()); ASSERT_TRUE(thirdHandle->IsUndefined()); - JSHandle four(thread->GetEcmaVM()->GetFactory()->NewFromString("4")); + JSHandle four(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("4")); JSHandle fourHandle(JSObject::GetProperty(thread, execResult, four).GetValue()); JSHandle outputFour = JSTaggedValue::ToString(thread, fourHandle); ASSERT_EQ(outputFour->Compare(*resultFour), 0); - JSHandle five(thread->GetEcmaVM()->GetFactory()->NewFromString("5")); + JSHandle five(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("5")); JSHandle fiveHandle(JSObject::GetProperty(thread, execResult, five).GetValue()); ASSERT_TRUE(fiveHandle->IsUndefined()); - JSHandle six(thread->GetEcmaVM()->GetFactory()->NewFromString("6")); + JSHandle six(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("6")); JSHandle sixHandle(JSObject::GetProperty(thread, execResult, six).GetValue()); JSHandle outputSix = JSTaggedValue::ToString(thread, sixHandle); ASSERT_EQ(outputSix->Compare(*resultSix), 0); @@ -405,13 +409,14 @@ HWTEST_F_L0(BuiltinsRegExpTest, Exec2) HWTEST_F_L0(BuiltinsRegExpTest, Match1) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("quick\\s(brown).+?(jumps)"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("iug"); + JSHandle pattern1 = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("quick\\s(brown).+?(jumps)"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("iug"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); JSHandle inputString = - thread->GetEcmaVM()->GetFactory()->NewFromString("The Quick Brown Fox Jumps Over The Lazy Dog"); + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("The Quick Brown Fox Jumps Over The Lazy Dog"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); @@ -422,8 +427,9 @@ HWTEST_F_L0(BuiltinsRegExpTest, Match1) JSTaggedValue matchResults = BuiltinsRegExp::Match(ecmaRuntimeCallInfo.get()); JSHandle matchResult(thread, matchResults); - JSHandle zero(thread->GetEcmaVM()->GetFactory()->NewFromString("0")); - JSHandle resultZero = thread->GetEcmaVM()->GetFactory()->NewFromString("Quick Brown Fox Jumps"); + JSHandle zero(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0")); + JSHandle resultZero = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Quick Brown Fox Jumps"); JSHandle zeroHandle(JSObject::GetProperty(thread, matchResult, zero).GetValue()); JSHandle outputZero = JSTaggedValue::ToString(thread, zeroHandle); ASSERT_EQ(outputZero->Compare(*resultZero), 0); @@ -432,13 +438,14 @@ HWTEST_F_L0(BuiltinsRegExpTest, Match1) HWTEST_F_L0(BuiltinsRegExpTest, Test1) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("quick\\s(brown).+?(jumps)"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("iug"); + JSHandle pattern1 = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("quick\\s(brown).+?(jumps)"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("iug"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); JSHandle inputString = - thread->GetEcmaVM()->GetFactory()->NewFromString("The Quick Brown Fox Jumps Over The Lazy Dog"); + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("The Quick Brown Fox Jumps Over The Lazy Dog"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); @@ -453,13 +460,14 @@ HWTEST_F_L0(BuiltinsRegExpTest, Test1) HWTEST_F_L0(BuiltinsRegExpTest, Search1) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("quick\\s(brown).+?(jumps)"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("iug"); + JSHandle pattern1 = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("quick\\s(brown).+?(jumps)"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("iug"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); JSHandle inputString = - thread->GetEcmaVM()->GetFactory()->NewFromString("The Quick Brown Fox Jumps Over The Lazy Dog"); + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("The Quick Brown Fox Jumps Over The Lazy Dog"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); @@ -474,12 +482,12 @@ HWTEST_F_L0(BuiltinsRegExpTest, Search1) HWTEST_F_L0(BuiltinsRegExpTest, Split1) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("-"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("iug"); + JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("iug"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); - JSHandle inputString = thread->GetEcmaVM()->GetFactory()->NewFromString(""); + JSHandle inputString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -492,21 +500,22 @@ HWTEST_F_L0(BuiltinsRegExpTest, Split1) JSTaggedValue splitResults = BuiltinsRegExp::Split(ecmaRuntimeCallInfo.get()); JSHandle splitResult(thread, splitResults); - JSHandle zero(thread->GetEcmaVM()->GetFactory()->NewFromString("0")); + JSHandle zero(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0")); JSHandle zeroHandle(JSObject::GetProperty(thread, splitResult, zero).GetValue()); JSHandle outputZero = JSTaggedValue::ToString(thread, zeroHandle); + ASSERT_EQ(outputZero->Compare(*inputString), 0); } HWTEST_F_L0(BuiltinsRegExpTest, Split2) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("-"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("iug"); + JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("iug"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); - JSHandle inputString = thread->GetEcmaVM()->GetFactory()->NewFromString("a-b-c"); + JSHandle inputString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("a-b-c"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -518,21 +527,21 @@ HWTEST_F_L0(BuiltinsRegExpTest, Split2) // invoke Split method JSTaggedValue splitResults = BuiltinsRegExp::Split(ecmaRuntimeCallInfo.get()); JSHandle splitResult(thread, splitResults); - JSHandle resultZero = thread->GetEcmaVM()->GetFactory()->NewFromString("a"); - JSHandle resultOne = thread->GetEcmaVM()->GetFactory()->NewFromString("b"); - JSHandle resultTwo = thread->GetEcmaVM()->GetFactory()->NewFromString("c"); + JSHandle resultZero = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("a"); + JSHandle resultOne = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("b"); + JSHandle resultTwo = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("c"); - JSHandle zero(thread->GetEcmaVM()->GetFactory()->NewFromString("0")); + JSHandle zero(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0")); JSHandle zeroHandle(JSObject::GetProperty(thread, splitResult, zero).GetValue()); JSHandle outputZero = JSTaggedValue::ToString(thread, zeroHandle); ASSERT_EQ(outputZero->Compare(*resultZero), 0); - JSHandle first(thread->GetEcmaVM()->GetFactory()->NewFromString("1")); + JSHandle first(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1")); JSHandle oneHandle(JSObject::GetProperty(thread, splitResult, first).GetValue()); JSHandle outputOne = JSTaggedValue::ToString(thread, oneHandle); ASSERT_EQ(outputOne->Compare(*resultOne), 0); - JSHandle second(thread->GetEcmaVM()->GetFactory()->NewFromString("2")); + JSHandle second(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2")); JSHandle twoHandle(JSObject::GetProperty(thread, splitResult, second).GetValue()); JSHandle outputTwo = JSTaggedValue::ToString(thread, twoHandle); ASSERT_EQ(outputTwo->Compare(*resultTwo), 0); @@ -555,15 +564,16 @@ HWTEST_F_L0(BuiltinsRegExpTest, GetSpecies) HWTEST_F_L0(BuiltinsRegExpTest, Replace1) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("quick\\s(brown).+?(jumps)"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("iug"); + JSHandle pattern1 = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("quick\\s(brown).+?(jumps)"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("iug"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); JSHandle inputString = - thread->GetEcmaVM()->GetFactory()->NewFromString("The Quick Brown Fox Jumps Over The Lazy Dog"); + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("The Quick Brown Fox Jumps Over The Lazy Dog"); JSHandle replaceString = - thread->GetEcmaVM()->GetFactory()->NewFromString("$&a $` $\' $2 $01 $$1 $21 $32 a"); + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("$&a $` $\' $2 $01 $$1 $21 $32 a"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); @@ -574,7 +584,7 @@ HWTEST_F_L0(BuiltinsRegExpTest, Replace1) // invoke replace method JSTaggedValue results = BuiltinsRegExp::Replace(ecmaRuntimeCallInfo.get()); JSHandle replaceResult(thread, results); - JSHandle resultZero = thread->GetEcmaVM()->GetFactory()->NewFromString( + JSHandle resultZero = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString( "The Quick Brown Fox Jumpsa The Over The Lazy Dog Jumps Brown $1 Jumps1 $32 a Over The Lazy Dog"); ASSERT_EQ(static_cast(replaceResult->GetTaggedObject())->Compare(*resultZero), 0); } @@ -583,13 +593,13 @@ HWTEST_F_L0(BuiltinsRegExpTest, Replace2) { // invoke RegExpConstructor method ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle pattern1 = factory->NewFromString("b(c)(z)?(.)"); - JSHandle flags1 = factory->NewFromString(""); + JSHandle pattern1 = factory->NewFromCanBeCompressString("b(c)(z)?(.)"); + JSHandle flags1 = factory->NewFromCanBeCompressString(""); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); - JSHandle inputString = factory->NewFromString("abcde"); - JSHandle replaceString = factory->NewFromString("[$01$02$03$04$00]"); + JSHandle inputString = factory->NewFromCanBeCompressString("abcde"); + JSHandle replaceString = factory->NewFromCanBeCompressString("[$01$02$03$04$00]"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); @@ -600,7 +610,7 @@ HWTEST_F_L0(BuiltinsRegExpTest, Replace2) // invoke replace method JSTaggedValue results = BuiltinsRegExp::Replace(ecmaRuntimeCallInfo.get()); JSHandle replaceResult(thread, results); - JSHandle resultZero = factory->NewFromString("a[cd$04$00]e"); + JSHandle resultZero = factory->NewFromCanBeCompressString("a[cd$04$00]e"); ASSERT_EQ(static_cast(replaceResult->GetTaggedObject())->Compare(*resultZero), 0); } @@ -608,13 +618,13 @@ HWTEST_F_L0(BuiltinsRegExpTest, Replace3) { // invoke RegExpConstructor method ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle pattern1 = factory->NewFromString("abc"); - JSHandle flags1 = factory->NewFromString("g"); + JSHandle pattern1 = factory->NewFromCanBeCompressString("abc"); + JSHandle flags1 = factory->NewFromCanBeCompressString("g"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle value(thread, reinterpret_cast(result1.GetRawData())); - JSHandle inputString = factory->NewFromString("abcde"); - JSHandle replaceString = factory->NewFromString(""); + JSHandle inputString = factory->NewFromCanBeCompressString("abcde"); + JSHandle replaceString = factory->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue()); @@ -625,7 +635,7 @@ HWTEST_F_L0(BuiltinsRegExpTest, Replace3) // invoke replace method JSTaggedValue results = BuiltinsRegExp::Replace(ecmaRuntimeCallInfo.get()); JSHandle replaceResult(thread, results); - JSHandle resultZero = factory->NewFromString("de"); + JSHandle resultZero = factory->NewFromCanBeCompressString("de"); ASSERT_EQ(static_cast(replaceResult->GetTaggedObject())->Compare(*resultZero), 0); } @@ -633,8 +643,8 @@ HWTEST_F_L0(BuiltinsRegExpTest, RegExpParseCache) { RegExpParserCache *regExpParserCache = thread->GetEcmaVM()->GetRegExpParserCache(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle string1 = factory->NewFromString("abc"); - JSHandle string2 = factory->NewFromString("abcd"); + JSHandle string1 = factory->NewFromCanBeCompressString("abc"); + JSHandle string2 = factory->NewFromCanBeCompressString("abcd"); regExpParserCache->SetCache(*string1, 0, JSTaggedValue::True(), 2); ASSERT_TRUE(regExpParserCache->GetCache(*string1, 0).first == JSTaggedValue::True()); ASSERT_TRUE(regExpParserCache->GetCache(*string1, 0).second == 2); diff --git a/ecmascript/builtins/tests/builtins_set_test.cpp b/ecmascript/builtins/tests/builtins_set_test.cpp index f1adc2fec35d676b8a8edc4a13497e76d4034cff..ccea63173c481bdcf7a2428b7bc58164c3c227e2 100644 --- a/ecmascript/builtins/tests/builtins_set_test.cpp +++ b/ecmascript/builtins/tests/builtins_set_test.cpp @@ -137,7 +137,7 @@ HWTEST_F_L0(BuiltinsSetTest, AddAndHas) ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // create jsSet JSHandle set(thread, CreateBuiltinsSet(thread)); - JSHandle key(thread, factory->NewFromString("key").GetTaggedValue()); + JSHandle key(thread, factory->NewFromCanBeCompressString("key").GetTaggedValue()); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -161,7 +161,7 @@ HWTEST_F_L0(BuiltinsSetTest, AddAndHas) ecmaRuntimeCallInfo1->SetThis(JSTaggedValue(jsSet)); ecmaRuntimeCallInfo1->SetCallArg(0, key.GetTaggedValue()); { - [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1.get()); + [[maybe_unused]] auto prevLocal = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1.get()); JSTaggedValue result3 = BuiltinsSet::Has(ecmaRuntimeCallInfo1.get()); EXPECT_EQ(result3.GetRawData(), JSTaggedValue::True().GetRawData()); @@ -175,7 +175,7 @@ HWTEST_F_L0(BuiltinsSetTest, AddAndHas) ecmaRuntimeCallInfo2->SetThis(JSTaggedValue(jsSet)); ecmaRuntimeCallInfo2->SetCallArg(0, negativeZero.GetTaggedValue()); { - [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2.get()); + [[maybe_unused]] auto prevLocal = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2.get()); BuiltinsSet::Add(ecmaRuntimeCallInfo.get()); } @@ -184,7 +184,7 @@ HWTEST_F_L0(BuiltinsSetTest, AddAndHas) ecmaRuntimeCallInfo3->SetThis(JSTaggedValue(jsSet)); ecmaRuntimeCallInfo3->SetCallArg(0, positiveZero.GetTaggedValue()); { - [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3.get()); + [[maybe_unused]] auto prevLocal = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3.get()); JSTaggedValue result4 = BuiltinsSet::Has(ecmaRuntimeCallInfo3.get()); EXPECT_EQ(result4.GetRawData(), JSTaggedValue::False().GetRawData()); @@ -199,7 +199,7 @@ HWTEST_F_L0(BuiltinsSetTest, ForEach) char keyArray[] = "key0"; for (int i = 0; i < 5; i++) { keyArray[3] = '1' + i; - JSHandle key(factory->NewFromString(keyArray)); + JSHandle key(factory->NewFromCanBeCompressString(keyArray)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); ecmaRuntimeCallInfo->SetThis(set.GetTaggedValue()); @@ -240,7 +240,7 @@ HWTEST_F_L0(BuiltinsSetTest, DeleteAndRemove) char keyArray[] = "key0"; for (int i = 0; i < 40; i++) { keyArray[3] = '1' + i; - JSHandle key(factory->NewFromString(keyArray)); + JSHandle key(factory->NewFromCanBeCompressString(keyArray)); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -256,7 +256,7 @@ HWTEST_F_L0(BuiltinsSetTest, DeleteAndRemove) } // whether jsSet has delete key keyArray[3] = '1' + 8; - JSHandle deleteKey(factory->NewFromString(keyArray)); + JSHandle deleteKey(factory->NewFromCanBeCompressString(keyArray)); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); @@ -306,34 +306,34 @@ HWTEST_F_L0(BuiltinsSetTest, Species) // to string tag JSHandle toStringTagSymbol = env->GetToStringTagSymbol(); JSHandle stringTag(JSObject::GetProperty(thread, set, toStringTagSymbol).GetValue()); - JSHandle str = factory->NewFromString("Set"); + JSHandle str = factory->NewFromCanBeCompressString("Set"); EXPECT_TRUE(!stringTag.GetTaggedValue().IsUndefined()); EXPECT_TRUE(EcmaString::StringsAreEqual(*str, *stringTag)); JSHandle constructor = JSHandle::Cast(JSTaggedValue::ToObject(thread, valueHandle)); EXPECT_EQ(JSHandle(set)->GetPrototype(thread), constructor->GetFunctionPrototype()); - JSHandle key1(factory->NewFromString("add")); + JSHandle key1(factory->NewFromCanBeCompressString("add")); JSTaggedValue value1 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value1.IsUndefined()); - JSHandle key2(factory->NewFromString("has")); + JSHandle key2(factory->NewFromCanBeCompressString("has")); JSTaggedValue value2 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value2.IsUndefined()); - JSHandle key3(factory->NewFromString("clear")); + JSHandle key3(factory->NewFromCanBeCompressString("clear")); JSTaggedValue value3 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value3.IsUndefined()); - JSHandle key4(factory->NewFromString("size")); + JSHandle key4(factory->NewFromCanBeCompressString("size")); JSTaggedValue value4 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value4.IsUndefined()); - JSHandle key5(factory->NewFromString("delete")); + JSHandle key5(factory->NewFromCanBeCompressString("delete")); JSTaggedValue value5 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value5.IsUndefined()); - JSHandle key6(factory->NewFromString("forEach")); + JSHandle key6(factory->NewFromCanBeCompressString("forEach")); JSTaggedValue value6 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue(); EXPECT_FALSE(value6.IsUndefined()); } diff --git a/ecmascript/builtins/tests/builtins_string_test.cpp b/ecmascript/builtins/tests/builtins_string_test.cpp index e33586e28f5f0e1e9252429dd66cc4e7e52db89a..21c0f7041aba3fcd3a61a431a20b2559149a957d 100644 --- a/ecmascript/builtins/tests/builtins_string_test.cpp +++ b/ecmascript/builtins/tests/builtins_string_test.cpp @@ -57,36 +57,35 @@ public: PandaVM *instance {nullptr}; EcmaHandleScope *scope {nullptr}; JSThread *thread {nullptr}; - - JSTaggedValue CreateRegExpObjByPatternAndFlags(JSThread *thread, const JSHandle &pattern, - const JSHandle &flags) - { - JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); - JSHandle regexp(env->GetRegExpFunction()); - JSHandle globalObject(thread, env->GetGlobalObject()); - - // 8 : test case - auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, regexp.GetTaggedValue(), 8); - ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue()); - ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue()); - ecmaRuntimeCallInfo->SetCallArg(0, pattern.GetTaggedValue()); - ecmaRuntimeCallInfo->SetCallArg(1, flags.GetTaggedValue()); - - [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get()); - JSTaggedValue result = BuiltinsRegExp::RegExpConstructor(ecmaRuntimeCallInfo.get()); - return result; - } }; +JSTaggedValue CreateRegExpObjByPatternAndFlags(JSThread *thread, const JSHandle &pattern, + const JSHandle &flags) +{ + JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); + JSHandle regexp(env->GetRegExpFunction()); + JSHandle globalObject(thread, env->GetGlobalObject()); + + // 8 : test case + auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, regexp.GetTaggedValue(), 8); + ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue()); + ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue()); + ecmaRuntimeCallInfo->SetCallArg(0, pattern.GetTaggedValue()); + ecmaRuntimeCallInfo->SetCallArg(1, flags.GetTaggedValue()); + + [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get()); + JSTaggedValue result = BuiltinsRegExp::RegExpConstructor(ecmaRuntimeCallInfo.get()); + return result; +} + HWTEST_F_L0(BuiltinsStringTest, StringConstructor1) { - ASSERT_NE(thread, nullptr); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle string(env->GetStringFunction()); JSHandle globalObject(thread, env->GetGlobalObject()); - JSHandle string2 = factory->NewFromString("ABC"); + JSHandle string2 = factory->NewFromCanBeCompressString("ABC"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, string.GetTaggedValue(), 6); ecmaRuntimeCallInfo->SetFunction(string.GetTaggedValue()); @@ -98,7 +97,7 @@ HWTEST_F_L0(BuiltinsStringTest, StringConstructor1) JSTaggedValue value(static_cast(result.GetRawData())); ASSERT_TRUE(value.IsECMAObject()); JSHandle ref(thread, JSPrimitiveRef::Cast(value.GetTaggedObject())); - JSTaggedValue test = factory->NewFromString("ABC").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("ABC").GetTaggedValue(); ASSERT_EQ( EcmaString::Cast(ref->GetValue().GetTaggedObject())->Compare(reinterpret_cast(test.GetRawData())), 0); @@ -107,7 +106,6 @@ HWTEST_F_L0(BuiltinsStringTest, StringConstructor1) // String.fromCharCode(65, 66, 67) HWTEST_F_L0(BuiltinsStringTest, fromCharCode1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); const double arg1 = 65; const double arg2 = 66; @@ -125,7 +123,7 @@ HWTEST_F_L0(BuiltinsStringTest, fromCharCode1) ASSERT_TRUE(result.IsString()); JSTaggedValue value(static_cast(result.GetRawData())); JSHandle valueHandle(thread, JSTaggedValue(value.GetTaggedObject())); - JSTaggedValue test = factory->NewFromString("ABC").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("ABC").GetTaggedValue(); ASSERT_EQ( EcmaString::Cast(valueHandle->GetTaggedObject())->Compare(reinterpret_cast(test.GetRawData())), 0); @@ -134,7 +132,6 @@ HWTEST_F_L0(BuiltinsStringTest, fromCharCode1) // String.fromCodePoint(65, 66, 67) HWTEST_F_L0(BuiltinsStringTest, fromCodePoint1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); const double arg1 = 65; const double arg2 = 66; @@ -151,16 +148,15 @@ HWTEST_F_L0(BuiltinsStringTest, fromCodePoint1) JSTaggedValue result = BuiltinsString::FromCodePoint(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("ABC").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("ABC").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } // "abcabcabc".charAt(5) HWTEST_F_L0(BuiltinsStringTest, charAt1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisVal = factory->NewFromString("abcabcabc"); + JSHandle thisVal = factory->NewFromCanBeCompressString("abcabcabc"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -171,14 +167,13 @@ HWTEST_F_L0(BuiltinsStringTest, charAt1) JSTaggedValue result = BuiltinsString::CharAt(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("c").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("c").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } // "一二三四".charAt(2) HWTEST_F_L0(BuiltinsStringTest, charAt2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle thisVal = factory->NewFromString("一二三四"); @@ -198,9 +193,8 @@ HWTEST_F_L0(BuiltinsStringTest, charAt2) // "abcabcabc".charAt(-1) HWTEST_F_L0(BuiltinsStringTest, charAt3) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisVal = factory->NewFromString("abcabcabc"); + JSHandle thisVal = factory->NewFromCanBeCompressString("abcabcabc"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -218,9 +212,8 @@ HWTEST_F_L0(BuiltinsStringTest, charAt3) // "ABC".charCodeAt(0) HWTEST_F_L0(BuiltinsStringTest, charCodeAt1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisVal = factory->NewFromString("ABC"); + JSHandle thisVal = factory->NewFromCanBeCompressString("ABC"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -236,9 +229,8 @@ HWTEST_F_L0(BuiltinsStringTest, charCodeAt1) // "ABC".charCodeAt(-1) HWTEST_F_L0(BuiltinsStringTest, charCodeAt2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisVal = factory->NewFromString("ABC"); + JSHandle thisVal = factory->NewFromCanBeCompressString("ABC"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -255,9 +247,8 @@ HWTEST_F_L0(BuiltinsStringTest, charCodeAt2) // "ABC".codePointAt(1) HWTEST_F_L0(BuiltinsStringTest, codePointAt1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisVal = factory->NewFromString("ABC"); + JSHandle thisVal = factory->NewFromCanBeCompressString("ABC"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -273,12 +264,11 @@ HWTEST_F_L0(BuiltinsStringTest, codePointAt1) // 'a'.concat('b', 'c', 'd') HWTEST_F_L0(BuiltinsStringTest, concat1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("a"); - JSHandle val1 = factory->NewFromString("b"); - JSHandle val2 = factory->NewFromString("c"); - JSHandle val3 = factory->NewFromString("d"); + JSHandle thisStr = factory->NewFromCanBeCompressString("a"); + JSHandle val1 = factory->NewFromCanBeCompressString("b"); + JSHandle val2 = factory->NewFromCanBeCompressString("c"); + JSHandle val3 = factory->NewFromCanBeCompressString("d"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -291,17 +281,16 @@ HWTEST_F_L0(BuiltinsStringTest, concat1) JSTaggedValue result = BuiltinsString::Concat(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("abcd").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("abcd").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } // "abcabcabc".indexof('b') HWTEST_F_L0(BuiltinsStringTest, indexof1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abcabcabc"); - JSHandle val = factory->NewFromString("b"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abcabcabc"); + JSHandle val = factory->NewFromCanBeCompressString("b"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -317,10 +306,9 @@ HWTEST_F_L0(BuiltinsStringTest, indexof1) // "abcabcabc".indexof('b', 2) HWTEST_F_L0(BuiltinsStringTest, indexof2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abcabcabc"); - JSHandle val = factory->NewFromString("b"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abcabcabc"); + JSHandle val = factory->NewFromCanBeCompressString("b"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -337,10 +325,9 @@ HWTEST_F_L0(BuiltinsStringTest, indexof2) // "abcabcabc".indexof('d') HWTEST_F_L0(BuiltinsStringTest, indexof3) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abcabcabc"); - JSHandle val = factory->NewFromString("d"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abcabcabc"); + JSHandle val = factory->NewFromCanBeCompressString("d"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -356,10 +343,9 @@ HWTEST_F_L0(BuiltinsStringTest, indexof3) // "abcabcabc".lastIndexOf('b') HWTEST_F_L0(BuiltinsStringTest, lastIndexOf1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abcabcabc"); - JSHandle val = factory->NewFromString("b"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abcabcabc"); + JSHandle val = factory->NewFromCanBeCompressString("b"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -374,10 +360,9 @@ HWTEST_F_L0(BuiltinsStringTest, lastIndexOf1) // "abcabcabc".lastIndexOf('b', 2) HWTEST_F_L0(BuiltinsStringTest, lastIndexOf2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abcabcabc"); - JSHandle val = factory->NewFromString("b"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abcabcabc"); + JSHandle val = factory->NewFromCanBeCompressString("b"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -394,10 +379,9 @@ HWTEST_F_L0(BuiltinsStringTest, lastIndexOf2) // "abcabcabc".lastIndexOf('d') HWTEST_F_L0(BuiltinsStringTest, lastIndexOf3) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abcabcabc"); - JSHandle val = factory->NewFromString("d"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abcabcabc"); + JSHandle val = factory->NewFromCanBeCompressString("d"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -413,10 +397,9 @@ HWTEST_F_L0(BuiltinsStringTest, lastIndexOf3) // "abcabcabc".includes('b') HWTEST_F_L0(BuiltinsStringTest, Includes2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abcabcabc"); - JSHandle val = factory->NewFromString("b"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abcabcabc"); + JSHandle val = factory->NewFromCanBeCompressString("b"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -432,10 +415,9 @@ HWTEST_F_L0(BuiltinsStringTest, Includes2) // "abccccccc".includes('b',2) HWTEST_F_L0(BuiltinsStringTest, Includes3) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abccccccc"); - JSHandle val = factory->NewFromString("b"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abccccccc"); + JSHandle val = factory->NewFromCanBeCompressString("b"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -452,7 +434,6 @@ HWTEST_F_L0(BuiltinsStringTest, Includes3) // "一二三四".includes('二') HWTEST_F_L0(BuiltinsStringTest, Includes4) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle thisStr = factory->NewFromString("一二三四"); JSHandle val = factory->NewFromString("二"); @@ -471,10 +452,9 @@ HWTEST_F_L0(BuiltinsStringTest, Includes4) // "To be, or not to be, that is the question.".startsWith('To be') HWTEST_F_L0(BuiltinsStringTest, startsWith1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("To be, or not to be, that is the question."); - JSHandle val = factory->NewFromString("To be"); + JSHandle thisStr = factory->NewFromCanBeCompressString("To be, or not to be, that is the question."); + JSHandle val = factory->NewFromCanBeCompressString("To be"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -490,10 +470,9 @@ HWTEST_F_L0(BuiltinsStringTest, startsWith1) // "To be, or not to be, that is the question.".startsWith('not to be') HWTEST_F_L0(BuiltinsStringTest, startsWith2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("To be, or not to be, that is the question."); - JSHandle val = factory->NewFromString("not to be"); + JSHandle thisStr = factory->NewFromCanBeCompressString("To be, or not to be, that is the question."); + JSHandle val = factory->NewFromCanBeCompressString("not to be"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -509,10 +488,9 @@ HWTEST_F_L0(BuiltinsStringTest, startsWith2) // "To be, or not to be, that is the question.".startsWith('not to be', 10) HWTEST_F_L0(BuiltinsStringTest, startsWith3) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("To be, or not to be, that is the question."); - JSHandle val = factory->NewFromString("not to be"); + JSHandle thisStr = factory->NewFromCanBeCompressString("To be, or not to be, that is the question."); + JSHandle val = factory->NewFromCanBeCompressString("not to be"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -529,10 +507,9 @@ HWTEST_F_L0(BuiltinsStringTest, startsWith3) // "To be, or not to be, that is the question.".endsWith('question.') HWTEST_F_L0(BuiltinsStringTest, endsWith1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("To be, or not to be, that is the question."); - JSHandle val = factory->NewFromString("question."); + JSHandle thisStr = factory->NewFromCanBeCompressString("To be, or not to be, that is the question."); + JSHandle val = factory->NewFromCanBeCompressString("question."); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -548,10 +525,9 @@ HWTEST_F_L0(BuiltinsStringTest, endsWith1) // "To be, or not to be, that is the question.".endsWith('to be') HWTEST_F_L0(BuiltinsStringTest, endsWith2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("To be, or not to be, that is the question."); - JSHandle val = factory->NewFromString("to be"); + JSHandle thisStr = factory->NewFromCanBeCompressString("To be, or not to be, that is the question."); + JSHandle val = factory->NewFromCanBeCompressString("to be"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -567,10 +543,9 @@ HWTEST_F_L0(BuiltinsStringTest, endsWith2) // "To be, or not to be, that is the question.".endsWith('to be', 19) HWTEST_F_L0(BuiltinsStringTest, endsWith3) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("To be, or not to be, that is the question."); - JSHandle val = factory->NewFromString("to be"); + JSHandle thisStr = factory->NewFromCanBeCompressString("To be, or not to be, that is the question."); + JSHandle val = factory->NewFromCanBeCompressString("to be"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -584,12 +559,30 @@ HWTEST_F_L0(BuiltinsStringTest, endsWith3) ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData()); } +// "有ABC".toLocaleLowerCase() +HWTEST_F_L0(BuiltinsStringTest, toLocaleLowerCase2) +{ + ASSERT_NE(thread, nullptr); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle this_str = factory->NewFromString("有ABC"); + + auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); + ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetThis(this_str.GetTaggedValue()); + + [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get()); + JSTaggedValue result = BuiltinsString::ToLocaleLowerCase(ecmaRuntimeCallInfo.get()); + ASSERT_TRUE(result.IsString()); + JSHandle result_handle(thread, reinterpret_cast(result.GetRawData())); + JSTaggedValue test = factory->NewFromString("有abc").GetTaggedValue(); + ASSERT_EQ(result_handle->Compare(reinterpret_cast(test.GetRawData())), 0); +} + // "ABC".toLowerCase() HWTEST_F_L0(BuiltinsStringTest, toLowerCase1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("ABC"); + JSHandle thisStr = factory->NewFromCanBeCompressString("ABC"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -599,16 +592,15 @@ HWTEST_F_L0(BuiltinsStringTest, toLowerCase1) JSTaggedValue result = BuiltinsString::ToLowerCase(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSHandle test = factory->NewFromString("abc"); + JSHandle test = factory->NewFromCanBeCompressString("abc"); ASSERT_TRUE(JSTaggedValue::SameValue(resultHandle.GetTaggedValue(), test.GetTaggedValue())); } // "abc".toUpperCase() HWTEST_F_L0(BuiltinsStringTest, toUpperCase1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abc"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abc"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -618,17 +610,16 @@ HWTEST_F_L0(BuiltinsStringTest, toUpperCase1) JSTaggedValue result = BuiltinsString::ToUpperCase(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("ABC").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("ABC").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } // "abc".localecompare('b') HWTEST_F_L0(BuiltinsStringTest, localecompare1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abc"); - JSHandle val = factory->NewFromString("b"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abc"); + JSHandle val = factory->NewFromCanBeCompressString("b"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -644,10 +635,9 @@ HWTEST_F_L0(BuiltinsStringTest, localecompare1) // "abc".localecompare('abc') HWTEST_F_L0(BuiltinsStringTest, localecompare2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abc"); - JSHandle val = factory->NewFromString("abc"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abc"); + JSHandle val = factory->NewFromCanBeCompressString("abc"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -663,10 +653,9 @@ HWTEST_F_L0(BuiltinsStringTest, localecompare2) // "abc".localecompare('aa') HWTEST_F_L0(BuiltinsStringTest, localecompare3) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abc"); - JSHandle val = factory->NewFromString("aa"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abc"); + JSHandle val = factory->NewFromCanBeCompressString("aa"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -679,12 +668,32 @@ HWTEST_F_L0(BuiltinsStringTest, localecompare3) ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData()); } +// "abc".normalize('NFC') +HWTEST_F_L0(BuiltinsStringTest, normalize1) +{ + ASSERT_NE(thread, nullptr); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle this_str = factory->NewFromString("abc"); + JSHandle val = factory->NewFromString("NFC"); + + auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); + ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetThis(this_str.GetTaggedValue()); + ecmaRuntimeCallInfo->SetCallArg(0, val.GetTaggedValue()); + + [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get()); + JSTaggedValue result = BuiltinsString::Normalize(ecmaRuntimeCallInfo.get()); + ASSERT_TRUE(result.IsString()); + JSHandle result_handle(thread, reinterpret_cast(result.GetRawData())); + JSTaggedValue test = factory->NewFromString("abc").GetTaggedValue(); + ASSERT_EQ(result_handle->Compare(reinterpret_cast(test.GetRawData())), 0); +} + // "abc".repeat(5) HWTEST_F_L0(BuiltinsStringTest, repeat1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abc"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abc"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -695,16 +704,15 @@ HWTEST_F_L0(BuiltinsStringTest, repeat1) JSTaggedValue result = BuiltinsString::Repeat(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("abcabcabcabcabc").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("abcabcabcabcabc").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } // 'The morning is upon us.'.slice(4, -2) HWTEST_F_L0(BuiltinsStringTest, slice1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("The morning is upon us."); + JSHandle thisStr = factory->NewFromCanBeCompressString("The morning is upon us."); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -716,16 +724,15 @@ HWTEST_F_L0(BuiltinsStringTest, slice1) JSTaggedValue result = BuiltinsString::Slice(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("morning is upon u").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("morning is upon u").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } // 'The morning is upon us.'.slice(12) HWTEST_F_L0(BuiltinsStringTest, slice2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("The morning is upon us."); + JSHandle thisStr = factory->NewFromCanBeCompressString("The morning is upon us."); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -736,16 +743,15 @@ HWTEST_F_L0(BuiltinsStringTest, slice2) JSTaggedValue result = BuiltinsString::Slice(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("is upon us.").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("is upon us.").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } // 'Mozilla'.substring(3, -3) HWTEST_F_L0(BuiltinsStringTest, substring1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("Mozilla"); + JSHandle thisStr = factory->NewFromCanBeCompressString("Mozilla"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -757,16 +763,15 @@ HWTEST_F_L0(BuiltinsStringTest, substring1) JSTaggedValue result = BuiltinsString::Substring(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("Moz").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("Moz").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } // 'Mozilla'.substring(7, 4) HWTEST_F_L0(BuiltinsStringTest, substring2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("Mozilla"); + JSHandle thisStr = factory->NewFromCanBeCompressString("Mozilla"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -778,16 +783,15 @@ HWTEST_F_L0(BuiltinsStringTest, substring2) JSTaggedValue result = BuiltinsString::Substring(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("lla").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("lla").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } // " Hello world! ".trim() HWTEST_F_L0(BuiltinsStringTest, trim1) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString(" Hello world! "); + JSHandle thisStr = factory->NewFromCanBeCompressString(" Hello world! "); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -797,18 +801,17 @@ HWTEST_F_L0(BuiltinsStringTest, trim1) JSTaggedValue result = BuiltinsString::Trim(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("Hello world!").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("Hello world!").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } HWTEST_F_L0(BuiltinsStringTest, trim2) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString(" Hello world! "); + JSHandle thisStr = factory->NewFromCanBeCompressString(" Hello world! "); JSHandle stringObject(env->GetStringFunction()); JSHandle value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject())); JSHandle str = factory->NewJSPrimitiveRef(stringObject, value); @@ -821,18 +824,17 @@ HWTEST_F_L0(BuiltinsStringTest, trim2) JSTaggedValue result = BuiltinsString::Trim(ecmaRuntimeCallInfo.get()); ASSERT_TRUE(result.IsString()); JSHandle resultHandle(thread, reinterpret_cast(result.GetRawData())); - JSTaggedValue test = factory->NewFromString("Hello world!").GetTaggedValue(); + JSTaggedValue test = factory->NewFromCanBeCompressString("Hello world!").GetTaggedValue(); ASSERT_EQ(resultHandle->Compare(reinterpret_cast(test.GetRawData())), 0); } HWTEST_F_L0(BuiltinsStringTest, ToString) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abcabcabc"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abcabcabc"); JSHandle stringObject(env->GetStringFunction()); JSHandle value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject())); JSHandle str = factory->NewJSPrimitiveRef(stringObject, value); @@ -851,12 +853,11 @@ HWTEST_F_L0(BuiltinsStringTest, ToString) HWTEST_F_L0(BuiltinsStringTest, ValueOf) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("abcabcabc"); + JSHandle thisStr = factory->NewFromCanBeCompressString("abcabcabc"); JSHandle stringObject(env->GetStringFunction()); JSHandle value(thread, JSTaggedValue(thisStr.GetTaggedValue().GetTaggedObject())); JSHandle str = factory->NewJSPrimitiveRef(stringObject, value); @@ -882,11 +883,10 @@ static inline JSFunction *BuiltinsStringTestCreate(JSThread *thread) HWTEST_F_L0(BuiltinsStringTest, Raw) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle foo(factory->NewFromString("foo")); - JSHandle bar(factory->NewFromString("bar")); - JSHandle baz(factory->NewFromString("baz")); + JSHandle foo(factory->NewFromCanBeCompressString("foo")); + JSHandle bar(factory->NewFromCanBeCompressString("bar")); + JSHandle baz(factory->NewFromCanBeCompressString("baz")); JSHandle rawArray = JSHandle::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); JSHandle obj(rawArray); JSHandle key0(thread, JSTaggedValue(0)); @@ -902,11 +902,11 @@ HWTEST_F_L0(BuiltinsStringTest, Raw) JSHandle constructor(thread, BuiltinsStringTestCreate(thread)); JSHandle templateString( factory->NewJSObjectByConstructor(JSHandle(constructor), constructor)); - JSHandle rawKey(factory->NewFromString("raw")); + JSHandle rawKey(factory->NewFromCanBeCompressString("raw")); JSObject::SetProperty(thread, templateString, rawKey, rawArray); - JSHandle test = factory->NewFromString("foo5barJavaScriptbaz"); + JSHandle test = factory->NewFromCanBeCompressString("foo5barJavaScriptbaz"); - JSHandle javascript = factory->NewFromString("JavaScript"); + JSHandle javascript = factory->NewFromCanBeCompressString("JavaScript"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -923,12 +923,11 @@ HWTEST_F_L0(BuiltinsStringTest, Raw) HWTEST_F_L0(BuiltinsStringTest, Replace) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("Twas the night before Xmas..."); - JSHandle searchStr = factory->NewFromString("Xmas"); - JSHandle replaceStr = factory->NewFromString("Christmas"); - JSHandle expected = factory->NewFromString("Twas the night before Christmas..."); + JSHandle thisStr = factory->NewFromCanBeCompressString("Twas the night before Xmas..."); + JSHandle searchStr = factory->NewFromCanBeCompressString("Xmas"); + JSHandle replaceStr = factory->NewFromCanBeCompressString("Christmas"); + JSHandle expected = factory->NewFromCanBeCompressString("Twas the night before Christmas..."); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -943,8 +942,8 @@ HWTEST_F_L0(BuiltinsStringTest, Replace) ASSERT_TRUE(result.IsString()); ASSERT_TRUE(EcmaString::StringsAreEqual(reinterpret_cast(result.GetRawData()), *expected)); - JSHandle replaceStr1 = factory->NewFromString("abc$$"); - JSHandle expected1 = factory->NewFromString("Twas the night before abc$..."); + JSHandle replaceStr1 = factory->NewFromCanBeCompressString("abc$$"); + JSHandle expected1 = factory->NewFromCanBeCompressString("Twas the night before abc$..."); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined()); @@ -960,8 +959,8 @@ HWTEST_F_L0(BuiltinsStringTest, Replace) ASSERT_TRUE(result1.IsString()); ASSERT_TRUE(EcmaString::StringsAreEqual(*resultString1, *expected1)); - JSHandle replaceStr2 = factory->NewFromString("abc$$dd"); - JSHandle expected2 = factory->NewFromString("Twas the night before abc$dd..."); + JSHandle replaceStr2 = factory->NewFromCanBeCompressString("abc$$dd"); + JSHandle expected2 = factory->NewFromCanBeCompressString("Twas the night before abc$dd..."); auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined()); @@ -977,8 +976,8 @@ HWTEST_F_L0(BuiltinsStringTest, Replace) ASSERT_TRUE(result2.IsString()); ASSERT_TRUE(EcmaString::StringsAreEqual(*resultString2, *expected2)); - JSHandle replaceStr3 = factory->NewFromString("abc$&dd"); - JSHandle expected3 = factory->NewFromString("Twas the night before abcXmasdd..."); + JSHandle replaceStr3 = factory->NewFromCanBeCompressString("abc$&dd"); + JSHandle expected3 = factory->NewFromCanBeCompressString("Twas the night before abcXmasdd..."); auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined()); @@ -994,8 +993,9 @@ HWTEST_F_L0(BuiltinsStringTest, Replace) ASSERT_TRUE(result3.IsString()); ASSERT_TRUE(EcmaString::StringsAreEqual(*resultString3, *expected3)); - JSHandle replaceStr4 = factory->NewFromString("abc$`dd"); - JSHandle expected4 = factory->NewFromString("Twas the night before abcTwas the night before dd..."); + JSHandle replaceStr4 = factory->NewFromCanBeCompressString("abc$`dd"); + JSHandle expected4 = + factory->NewFromCanBeCompressString("Twas the night before abcTwas the night before dd..."); auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined()); @@ -1014,12 +1014,11 @@ HWTEST_F_L0(BuiltinsStringTest, Replace) HWTEST_F_L0(BuiltinsStringTest, Replace2) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("Twas the night before Xmas..."); - JSHandle searchStr = factory->NewFromString("Xmas"); - JSHandle replaceStr = factory->NewFromString("abc$\'dd"); - JSHandle expected = factory->NewFromString("Twas the night before abc...dd..."); + JSHandle thisStr = factory->NewFromCanBeCompressString("Twas the night before Xmas..."); + JSHandle searchStr = factory->NewFromCanBeCompressString("Xmas"); + JSHandle replaceStr = factory->NewFromCanBeCompressString("abc$\'dd"); + JSHandle expected = factory->NewFromCanBeCompressString("Twas the night before abc...dd..."); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -1034,9 +1033,9 @@ HWTEST_F_L0(BuiltinsStringTest, Replace2) ASSERT_TRUE(result.IsString()); ASSERT_TRUE(EcmaString::StringsAreEqual(reinterpret_cast(result.GetRawData()), *expected)); - JSHandle replaceStr2 = factory->NewFromString("abc$`dd$\'$ff"); + JSHandle replaceStr2 = factory->NewFromCanBeCompressString("abc$`dd$\'$ff"); JSHandle expected2 = - factory->NewFromString("Twas the night before abcTwas the night before dd...$ff..."); + factory->NewFromCanBeCompressString("Twas the night before abcTwas the night before dd...$ff..."); auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined()); @@ -1052,8 +1051,9 @@ HWTEST_F_L0(BuiltinsStringTest, Replace2) ASSERT_TRUE(result2.IsString()); ASSERT_TRUE(EcmaString::StringsAreEqual(*resultString2, *expected2)); - JSHandle replaceStr3 = factory->NewFromString("abc$`dd$\'$"); - JSHandle expected3 = factory->NewFromString("Twas the night before abcTwas the night before dd...$..."); + JSHandle replaceStr3 = factory->NewFromCanBeCompressString("abc$`dd$\'$"); + JSHandle expected3 = + factory->NewFromCanBeCompressString("Twas the night before abcTwas the night before dd...$..."); auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined()); @@ -1069,8 +1069,9 @@ HWTEST_F_L0(BuiltinsStringTest, Replace2) ASSERT_TRUE(result3.IsString()); ASSERT_TRUE(EcmaString::StringsAreEqual(*resultString3, *expected3)); - JSHandle replaceStr4 = factory->NewFromString("abc$`dd$$"); - JSHandle expected4 = factory->NewFromString("Twas the night before abcTwas the night before dd$..."); + JSHandle replaceStr4 = factory->NewFromCanBeCompressString("abc$`dd$$"); + JSHandle expected4 = + factory->NewFromCanBeCompressString("Twas the night before abcTwas the night before dd$..."); auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined()); @@ -1089,13 +1090,12 @@ HWTEST_F_L0(BuiltinsStringTest, Replace2) HWTEST_F_L0(BuiltinsStringTest, Replace3) { - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("Twas the night before Xmas..."); - JSHandle searchStr = factory->NewFromString("Xmas"); - JSHandle replaceStr = factory->NewFromString("$&a $` $\' $2 $01 $$1 $21 $32 a"); - JSHandle expected = - factory->NewFromString("Twas the night before Xmasa Twas the night before ... $2 $01 $1 $21 $32 a..."); + JSHandle thisStr = factory->NewFromCanBeCompressString("Twas the night before Xmas..."); + JSHandle searchStr = factory->NewFromCanBeCompressString("Xmas"); + JSHandle replaceStr = factory->NewFromCanBeCompressString("$&a $` $\' $2 $01 $$1 $21 $32 a"); + JSHandle expected = factory->NewFromCanBeCompressString( + "Twas the night before Xmasa Twas the night before ... $2 $01 $1 $21 $32 a..."); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -1113,18 +1113,19 @@ HWTEST_F_L0(BuiltinsStringTest, Replace3) HWTEST_F_L0(BuiltinsStringTest, Replace4) { // invoke RegExpConstructor method - JSHandle pattern1 = thread->GetEcmaVM()->GetFactory()->NewFromString("quick\\s(brown).+?(jumps)"); - JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromString("iug"); + JSHandle pattern1 = + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("quick\\s(brown).+?(jumps)"); + JSHandle flags1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("iug"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle searchStr(thread, reinterpret_cast(result1.GetRawData())); - JSHandle expected = thread->GetEcmaVM()->GetFactory()->NewFromString( + JSHandle expected = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString( "The Quick Brown Fox Jumpsa The Over The Lazy Dog Jumps Brown $1 Jumps1 $32 a Over The Lazy Dog"); // make dyn_runtime_call_info2 JSHandle thisStr = - thread->GetEcmaVM()->GetFactory()->NewFromString("The Quick Brown Fox Jumps Over The Lazy Dog"); + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("The Quick Brown Fox Jumps Over The Lazy Dog"); JSHandle replaceStr = - thread->GetEcmaVM()->GetFactory()->NewFromString("$&a $` $\' $2 $01 $$1 $21 $32 a"); + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("$&a $` $\' $2 $01 $$1 $21 $32 a"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -1142,14 +1143,13 @@ HWTEST_F_L0(BuiltinsStringTest, Replace4) HWTEST_F_L0(BuiltinsStringTest, Split) { // invoke RegExpConstructor method - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("Hello World. How are you doing?"); - JSHandle separatorStr = factory->NewFromString(" "); + JSHandle thisStr = factory->NewFromCanBeCompressString("Hello World. How are you doing?"); + JSHandle separatorStr = factory->NewFromCanBeCompressString(" "); JSHandle limit(thread, JSTaggedValue(3)); - JSHandle expected1 = factory->NewFromString("Hello"); - JSHandle expected2 = factory->NewFromString("World."); - JSHandle expected3 = factory->NewFromString("How"); + JSHandle expected1 = factory->NewFromCanBeCompressString("Hello"); + JSHandle expected2 = factory->NewFromCanBeCompressString("World."); + JSHandle expected3 = factory->NewFromCanBeCompressString("How"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -1178,18 +1178,17 @@ HWTEST_F_L0(BuiltinsStringTest, Split) HWTEST_F_L0(BuiltinsStringTest, Split2) { // invoke RegExpConstructor method - ASSERT_NE(thread, nullptr); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle thisStr = factory->NewFromString("a-b-c"); - JSHandle pattern1 = factory->NewFromString("-"); - JSHandle flags1 = factory->NewFromString("iug"); + JSHandle thisStr = factory->NewFromCanBeCompressString("a-b-c"); + JSHandle pattern1 = factory->NewFromCanBeCompressString("-"); + JSHandle flags1 = factory->NewFromCanBeCompressString("iug"); JSTaggedValue result1 = CreateRegExpObjByPatternAndFlags(thread, pattern1, flags1); JSHandle separatorObj(thread, result1); JSHandle limit(thread, JSTaggedValue(3)); - JSHandle expected1 = factory->NewFromString("a"); - JSHandle expected2 = factory->NewFromString("b"); - JSHandle expected3 = factory->NewFromString("c"); + JSHandle expected1 = factory->NewFromCanBeCompressString("a"); + JSHandle expected2 = factory->NewFromCanBeCompressString("b"); + JSHandle expected3 = factory->NewFromCanBeCompressString("c"); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); diff --git a/ecmascript/builtins/tests/builtins_symbol_test.cpp b/ecmascript/builtins/tests/builtins_symbol_test.cpp index 344eb43bf9d03d7ae91504d6db47dcf5b8ab2047..0d4975fbd8557625abf604324ec5f6ce498a279b 100644 --- a/ecmascript/builtins/tests/builtins_symbol_test.cpp +++ b/ecmascript/builtins/tests/builtins_symbol_test.cpp @@ -67,7 +67,6 @@ public: // new Symbol.toString() HWTEST_F_L0(BuiltinsSymbolTest, SymbolNoParameterToString) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle symbol = ecmaVM->GetFactory()->NewJSSymbol(); @@ -88,7 +87,6 @@ HWTEST_F_L0(BuiltinsSymbolTest, SymbolNoParameterToString) // new Symbol("aaa").toString() HWTEST_F_L0(BuiltinsSymbolTest, SymbolWithParameterToString) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle symbol = ecmaVM->GetFactory()->NewPublicSymbolWithChar("aaa"); @@ -109,7 +107,6 @@ HWTEST_F_L0(BuiltinsSymbolTest, SymbolWithParameterToString) // new Symbol().valueOf() HWTEST_F_L0(BuiltinsSymbolTest, SymbolNoParameterValueOf) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -143,7 +140,6 @@ HWTEST_F_L0(BuiltinsSymbolTest, SymbolNoParameterValueOf) // new Symbol("bbb").valueOf() HWTEST_F_L0(BuiltinsSymbolTest, SymbolWithParameterValueOf) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -177,13 +173,12 @@ HWTEST_F_L0(BuiltinsSymbolTest, SymbolWithParameterValueOf) // new Symbol().for HWTEST_F_L0(BuiltinsSymbolTest, SymbolWithParameterFor) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); JSHandle tableHandle(env->GetRegisterSymbols()); - JSHandle string = ecmaVM->GetFactory()->NewFromString("ccc"); + JSHandle string = ecmaVM->GetFactory()->NewFromCanBeCompressString("ccc"); ASSERT_EQ(string->GetLength(), 3); JSHandle string_handle(string); ASSERT_EQ(tableHandle->ContainsKey(thread, string_handle.GetTaggedValue()), false); @@ -207,7 +202,6 @@ HWTEST_F_L0(BuiltinsSymbolTest, SymbolWithParameterFor) // Symbol.keyFor (sym) HWTEST_F_L0(BuiltinsSymbolTest, SymbolKeyFor) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -223,7 +217,7 @@ HWTEST_F_L0(BuiltinsSymbolTest, SymbolKeyFor) TestHelper::TearDownFrame(thread, prev); ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED); - JSHandle string = ecmaVM->GetFactory()->NewFromString("ccc"); + JSHandle string = ecmaVM->GetFactory()->NewFromCanBeCompressString("ccc"); ASSERT_EQ(string->GetLength(), 3); auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); @@ -253,7 +247,6 @@ HWTEST_F_L0(BuiltinsSymbolTest, SymbolKeyFor) // Symbol.ToPrimitive() HWTEST_F_L0(BuiltinsSymbolTest, SymbolToPrimitive) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -287,7 +280,6 @@ HWTEST_F_L0(BuiltinsSymbolTest, SymbolToPrimitive) // constructor HWTEST_F_L0(BuiltinsSymbolTest, SymbolConstructor) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); @@ -302,7 +294,7 @@ HWTEST_F_L0(BuiltinsSymbolTest, SymbolConstructor) JSSymbol *sym = reinterpret_cast(result.GetRawData()); ASSERT_EQ(sym->GetDescription().IsUndefined(), true); - JSHandle string = ecmaVM->GetFactory()->NewFromString("ddd"); + JSHandle string = ecmaVM->GetFactory()->NewFromCanBeCompressString("ddd"); auto otherEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); otherEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); @@ -319,11 +311,10 @@ HWTEST_F_L0(BuiltinsSymbolTest, SymbolConstructor) HWTEST_F_L0(BuiltinsSymbolTest, SymbolGetter) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle symbol = ecmaVM->GetFactory()->NewPublicSymbolWithChar(""); - JSHandle string = ecmaVM->GetFactory()->NewFromString(""); + JSHandle string = ecmaVM->GetFactory()->NewFromCanBeCompressString(""); auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); diff --git a/ecmascript/builtins/tests/builtins_typedarray_test.cpp b/ecmascript/builtins/tests/builtins_typedarray_test.cpp index 4b13b2c4358a6aa0ca5852f8cd9b27a30715f242..7cab6934fb567ad738fef0fecb97d498350697ca 100644 --- a/ecmascript/builtins/tests/builtins_typedarray_test.cpp +++ b/ecmascript/builtins/tests/builtins_typedarray_test.cpp @@ -27,11 +27,11 @@ #include "ecmascript/js_array_iterator.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_hclass.h" -#include "ecmascript/js_int8_array.h" #include "ecmascript/js_object-inl.h" #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/js_tagged_value.h" #include "ecmascript/js_thread.h" +#include "ecmascript/js_typed_array.h" #include "ecmascript/object_factory.h" #include "ecmascript/object_operator.h" @@ -181,13 +181,13 @@ JSTaggedValue CreateBuiltinsJSObject(JSThread *thread, const CString keyCStr) ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle obj(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); - JSHandle key(factory->NewFromString(&keyCStr[0])); + JSHandle key(factory->NewFromCanBeCompressString(&keyCStr[0])); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, obj, key, value); return obj.GetTaggedValue(); } -JSInt8Array *CreateTypedArrayFromList(JSThread *thread, const JSHandle &array) +JSTypedArray *CreateTypedArrayFromList(JSThread *thread, const JSHandle &array) { auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -205,7 +205,7 @@ JSInt8Array *CreateTypedArrayFromList(JSThread *thread, const JSHandle(result.GetRawData())); + JSTypedArray *int8arr = JSTypedArray::Cast(reinterpret_cast(result.GetRawData())); return int8arr; } diff --git a/ecmascript/builtins/tests/builtins_weak_map_test.cpp b/ecmascript/builtins/tests/builtins_weak_map_test.cpp index d745d0fabf65aac8178c4b87af388c605221f0d9..382bdd5930f4b6f0fe5e50e9724518639ed9310d 100644 --- a/ecmascript/builtins/tests/builtins_weak_map_test.cpp +++ b/ecmascript/builtins/tests/builtins_weak_map_test.cpp @@ -101,12 +101,12 @@ HWTEST_F_L0(BuiltinsWeakMapTest, CreateAndGetSize) JSHandle map(thread, CreateBuiltinsWeakMap(thread)); JSHandle array(factory->NewTaggedArray(1)); - JSHandle internal_array(factory->NewTaggedArray(2)); - JSTaggedValue value(JSObjectTestCreate(thread)); - internal_array->Set(thread, 0, value); - internal_array->Set(thread, 1, JSTaggedValue(0)); - auto result = JSArray::CreateArrayFromList(thread, internal_array); - array->Set(thread, 0, result); + JSHandle internal_array(factory->NewTaggedArray(2)); + JSTaggedValue value(JSObjectTestCreate(thread)); + internal_array->Set(thread, 0, value); + internal_array->Set(thread, 1, JSTaggedValue(0)); + auto result = JSArray::CreateArrayFromList(thread, internal_array); + array->Set(thread, 0, result); JSHandle values = JSArray::CreateArrayFromList(thread, array); diff --git a/ecmascript/class_linker/panda_file_translator.cpp b/ecmascript/class_linker/panda_file_translator.cpp index 1e44b3f1e4d97a5fab604d2a67285ba8f70e48f7..1bed3ea3f5db40312262e0db9849e01a56358c79 100644 --- a/ecmascript/class_linker/panda_file_translator.cpp +++ b/ecmascript/class_linker/panda_file_translator.cpp @@ -49,7 +49,7 @@ JSHandle PandaFileTranslator::TranslatePandaFile(EcmaVM *vm, const pand return JSHandle(translator.thread_, result); } -template +template static T *InitializeMemory(T *mem, Args... args) { return new (mem) T(std::forward(args)...); @@ -125,7 +125,7 @@ Program *PandaFileTranslator::GenerateProgram(const panda_file::File &pf) EcmaHandleScope handleScope(thread_); JSHandle program = factory_->NewProgram(); - JSHandle location = factory_->NewFromStdString(pf.GetFilename()); + JSHandle location = factory_->NewFromStdStringUnCheck(pf.GetFilename(), true); // +1 for program JSHandle constpool = factory_->NewConstantPool(constpoolIndex_ + 1); @@ -275,14 +275,6 @@ void PandaFileTranslator::FixOpcode(uint8_t *pc) const { auto opcode = static_cast(*pc); - constexpr size_t numBuiltinsFormat = 20; - std::array skipTable = { - // NOLINTNEXTLINE(readability-magic-numbers) - 0U, 32U, 83U, 101U, 105U, 107U, 113U, 122U, 122U, 124U, - // NOLINTNEXTLINE(readability-magic-numbers) - 129U, 133U, 139U, 139U, 140U, 141U, 147U, 148U, 150U, 152U - }; - switch (opcode) { case BytecodeInstruction::Opcode::MOV_V4_V4: *pc = static_cast(EcmaOpcode::MOV_V4_V4); @@ -332,38 +324,55 @@ void PandaFileTranslator::FixOpcode(uint8_t *pc) const case BytecodeInstruction::Opcode::RETURN_DYN: *pc = static_cast(EcmaOpcode::RETURN_DYN); break; - case BytecodeInstruction::Opcode::BUILTIN_ACC_IMM8: - case BytecodeInstruction::Opcode::BUILTIN_BIN2_IMM8_V8: - case BytecodeInstruction::Opcode::BUILTIN_TERN3_IMM8_V8_V8: - case BytecodeInstruction::Opcode::BUILTIN_QUATERN4_IMM8_V8_V8_V8: - case BytecodeInstruction::Opcode::BUILTIN_QUIN5_IMM8_V8_V8_V8_V8: - case BytecodeInstruction::Opcode::BUILTIN_R2I_IMM8_IMM16_V8: - case BytecodeInstruction::Opcode::BUILTIN_R3I_IMM8_IMM16_V8_V8: - case BytecodeInstruction::Opcode::BUILTIN_R4I_IMM8_IMM16_V8_V8_V8: - case BytecodeInstruction::Opcode::BUILTIN_ID_IMM8_ID32: - case BytecodeInstruction::Opcode::BUILTIN_MIDR_IMM8_ID16_V8: - case BytecodeInstruction::Opcode::BUILTIN_IDI_IMM8_ID32_IMM16: - case BytecodeInstruction::Opcode::BUILTIN_IDR3I_IMM8_ID32_IMM16_V8: - case BytecodeInstruction::Opcode::BUILTIN_IDR4I_IMM8_ID32_IMM16_V8_V8: - case BytecodeInstruction::Opcode::BUILTIN_I2R3_IMM8_IMM16_IMM16_V8: - case BytecodeInstruction::Opcode::BUILTIN_I2R2_IMM8_IMM16_IMM16: - case BytecodeInstruction::Opcode::BUILTIN_IMM_IMM8_IMM16: - case BytecodeInstruction::Opcode::BUILTIN_IMR2_IMM8_ID16_IMM16_V8_V8: { - const int index = - static_cast(opcode) - static_cast(BytecodeInstruction::Opcode::BUILTIN_ACC_IMM8); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - auto builtinId = *(pc + 1); - builtinId += skipTable[index]; - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - *pc = builtinId; - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic, readability-magic-numbers) + default: + if (*pc != static_cast(BytecodeInstruction::Opcode::ECMA_LDNAN_PREF_NONE)) { + LOG_ECMA(FATAL) << "Is not an Ecma Opcode opcode: " << static_cast(opcode); + UNREACHABLE(); + } + *pc = *(pc + 1); *(pc + 1) = 0xFF; break; - } + } +} + +// reuse prefix 8bits to store slotid +void PandaFileTranslator::UpdateICOffset(JSMethod *method, uint8_t *pc) const +{ + uint8_t offset = method->GetSlotSize(); + if (UNLIKELY(offset == JSMethod::MAX_SLOT_SIZE)) { + return; + } + + auto opcode = static_cast(*pc); + switch (opcode) { + case EcmaOpcode::TRYLDGLOBALBYNAME_PREF_ID32: + case EcmaOpcode::TRYSTGLOBALBYNAME_PREF_ID32: + case EcmaOpcode::LDGLOBALVAR_PREF_ID32: + case EcmaOpcode::STGLOBALVAR_PREF_ID32: + method->UpdateSlotSize(1); + break; + case EcmaOpcode::LDOBJBYVALUE_PREF_V8_V8: + case EcmaOpcode::STOBJBYVALUE_PREF_V8_V8: + case EcmaOpcode::STOWNBYVALUE_PREF_V8_V8: + case EcmaOpcode::LDOBJBYNAME_PREF_ID32_V8: + case EcmaOpcode::STOBJBYNAME_PREF_ID32_V8: + case EcmaOpcode::STOWNBYNAME_PREF_ID32_V8: + case EcmaOpcode::LDOBJBYINDEX_PREF_V8_IMM32: + case EcmaOpcode::STOBJBYINDEX_PREF_V8_IMM32: + case EcmaOpcode::STOWNBYINDEX_PREF_V8_IMM32: + case EcmaOpcode::LDSUPERBYVALUE_PREF_V8_V8: + case EcmaOpcode::STSUPERBYVALUE_PREF_V8_V8: + case EcmaOpcode::LDSUPERBYNAME_PREF_ID32_V8: + case EcmaOpcode::STSUPERBYNAME_PREF_ID32_V8: + case EcmaOpcode::LDMODVARBYNAME_PREF_ID32_V8: + case EcmaOpcode::STMODULEVAR_PREF_ID32: + method->UpdateSlotSize(2); + break; default: - LOG_ECMA(FATAL) << "Unsupported opcode: " << static_cast(opcode); - UNREACHABLE(); + return; } + + *(pc + 1) = offset; } void PandaFileTranslator::FixInstructionId32(const BytecodeInstruction &inst, [[maybe_unused]] uint32_t index, @@ -381,7 +390,7 @@ void PandaFileTranslator::FixInstructionId32(const BytecodeInstruction &inst, [[ } break; } - case BytecodeInstruction::Format::IMM8_ID16_V8: { + case BytecodeInstruction::Format::PREF_ID16_IMM16_V8: { uint16_t u16Index = index; uint8_t size = sizeof(uint16_t); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -391,10 +400,9 @@ void PandaFileTranslator::FixInstructionId32(const BytecodeInstruction &inst, [[ } break; } - case BytecodeInstruction::Format::IMM8_ID32: - case BytecodeInstruction::Format::IMM8_ID32_IMM16: - case BytecodeInstruction::Format::IMM8_ID32_IMM16_V8: - case BytecodeInstruction::Format::IMM8_ID32_IMM16_V8_V8: { + case BytecodeInstruction::Format::PREF_ID32: + case BytecodeInstruction::Format::PREF_ID32_V8: + case BytecodeInstruction::Format::PREF_ID32_IMM8: { uint8_t size = sizeof(uint32_t); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) if (memcpy_s(pc + FixInstructionIndex::FIX_TWO, size, &index, size) != EOK) { @@ -403,7 +411,7 @@ void PandaFileTranslator::FixInstructionId32(const BytecodeInstruction &inst, [[ } break; } - case BytecodeInstruction::Format::IMM8_IMM16: { + case BytecodeInstruction::Format::PREF_IMM16: { ASSERT(static_cast(index) == index); uint16_t u16Index = index; uint8_t size = sizeof(uint16_t); @@ -414,7 +422,7 @@ void PandaFileTranslator::FixInstructionId32(const BytecodeInstruction &inst, [[ } break; } - case BytecodeInstruction::Format::IMM8_ID16_IMM16_V8_V8: { + case BytecodeInstruction::Format::PREF_ID16_IMM16_IMM16_V8_V8: { // Usually, we fix one part of instruction one time. But as for instruction DefineClassWithBuffer, // which use both method id and literal buffer id.Using fixOrder indicates fix Location. if (fixOrder == 0) { @@ -452,86 +460,69 @@ void PandaFileTranslator::TranslateBytecode(uint32_t insSz, const uint8_t *insAr auto bcInsLast = bcIns.JumpTo(insSz); while (bcIns.GetAddress() != bcInsLast.GetAddress()) { - { - if (bcIns.HasFlag(BytecodeInstruction::Flags::STRING_ID) && - BytecodeInstruction::HasId(bcIns.GetFormat(), 0)) { - auto index = GetOrInsertConstantPool(ConstPoolType::STRING, bcIns.GetId().AsFileId().GetOffset()); - FixInstructionId32(bcIns, index); - } else if (static_cast(bcIns.GetOpcode()) == - BytecodeInstruction::Opcode::BUILTIN_MIDR_IMM8_ID16_V8) { - auto methodId = pf.ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset(); - switch (bcIns.template GetImm()) { - uint32_t index; - case SecondInstructionOfMidr::DEFINE_FUNC_DYN: - index = GetOrInsertConstantPool(ConstPoolType::BASE_FUNCTION, methodId); - FixInstructionId32(bcIns, index); - break; - case SecondInstructionOfMidr::DEFINE_NC_FUNC_DYN: - index = GetOrInsertConstantPool(ConstPoolType::NC_FUNCTION, methodId); - FixInstructionId32(bcIns, index); - break; - case SecondInstructionOfMidr::DEFINE_GENERATOR_FUNC_DYN: - index = GetOrInsertConstantPool(ConstPoolType::GENERATOR_FUNCTION, methodId); - FixInstructionId32(bcIns, index); - break; - case SecondInstructionOfMidr::DEFINE_ASYNC_FUNC_DYN: - index = GetOrInsertConstantPool(ConstPoolType::ASYNC_FUNCTION, methodId); - FixInstructionId32(bcIns, index); - break; - case SecondInstructionOfMidr::DEFINE_METHOD: - index = GetOrInsertConstantPool(ConstPoolType::METHOD, methodId); - FixInstructionId32(bcIns, index); - break; - default: - UNREACHABLE(); - } - } else if (static_cast(bcIns.GetOpcode()) == - BytecodeInstruction::Opcode::BUILTIN_IMM_IMM8_IMM16) { - switch (bcIns.template GetImm()) { - uint32_t index; - case 0: - case 1: - break; - case SecondInstructionOfImm::CREATE_OBJECT_WITH_BUFFER: - // createobjectwithbuffer - index = GetOrInsertConstantPool(ConstPoolType::OBJECT_LITERAL, - bcIns.GetImm()); - FixInstructionId32(bcIns, index); - break; - case SecondInstructionOfImm::CREATE_ARRAY_WITH_BUFFER: - // createarraywithbuffer - index = GetOrInsertConstantPool(ConstPoolType::ARRAY_LITERAL, - bcIns.GetImm()); - FixInstructionId32(bcIns, index); - break; - case SecondInstructionOfImm::CREATE_OBJECT_HAVING_METHOD: - // createobjecthavingmethod - index = GetOrInsertConstantPool(ConstPoolType::OBJECT_LITERAL, - bcIns.GetImm()); - FixInstructionId32(bcIns, index); - break; - default: - break; - } - } else if (static_cast(bcIns.GetOpcode()) == - BytecodeInstruction::Opcode::BUILTIN_IMR2_IMM8_ID16_IMM16_V8_V8) { - if (bcIns.template GetImm() == 0) { - // defineclasswithbuffer - auto methodId = pf.ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset(); - uint32_t index1 = GetOrInsertConstantPool(ConstPoolType::CLASS_FUNCTION, methodId); - FixInstructionId32(bcIns, index1); - - uint32_t index2 = - GetOrInsertConstantPool(ConstPoolType::CLASS_LITERAL, - bcIns.GetImm()); - FixInstructionId32(bcIns, index2, 1); - } + if (bcIns.HasFlag(BytecodeInstruction::Flags::STRING_ID) && + BytecodeInstruction::HasId(bcIns.GetFormat(), 0)) { + auto index = GetOrInsertConstantPool(ConstPoolType::STRING, bcIns.GetId().AsFileId().GetOffset()); + FixInstructionId32(bcIns, index); + } else { + BytecodeInstruction::Opcode opcode = static_cast(bcIns.GetOpcode()); + switch (opcode) { + uint32_t index; + uint32_t methodId; + case BytecodeInstruction::Opcode::ECMA_DEFINEFUNCDYN_PREF_ID16_IMM16_V8: + methodId = pf.ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset(); + index = GetOrInsertConstantPool(ConstPoolType::BASE_FUNCTION, methodId); + FixInstructionId32(bcIns, index); + break; + case BytecodeInstruction::Opcode::ECMA_DEFINENCFUNCDYN_PREF_ID16_IMM16_V8: + methodId = pf.ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset(); + index = GetOrInsertConstantPool(ConstPoolType::NC_FUNCTION, methodId); + FixInstructionId32(bcIns, index); + break; + case BytecodeInstruction::Opcode::ECMA_DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8: + methodId = pf.ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset(); + index = GetOrInsertConstantPool(ConstPoolType::GENERATOR_FUNCTION, methodId); + FixInstructionId32(bcIns, index); + break; + case BytecodeInstruction::Opcode::ECMA_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8: + methodId = pf.ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset(); + index = GetOrInsertConstantPool(ConstPoolType::ASYNC_FUNCTION, methodId); + FixInstructionId32(bcIns, index); + break; + case BytecodeInstruction::Opcode::ECMA_DEFINEMETHOD_PREF_ID16_IMM16_V8: + methodId = pf.ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset(); + index = GetOrInsertConstantPool(ConstPoolType::METHOD, methodId); + FixInstructionId32(bcIns, index); + break; + case BytecodeInstruction::Opcode::ECMA_CREATEOBJECTWITHBUFFER_PREF_IMM16: + case BytecodeInstruction::Opcode::ECMA_CREATEOBJECTHAVINGMETHOD_PREF_IMM16: + index = GetOrInsertConstantPool(ConstPoolType::OBJECT_LITERAL, + bcIns.GetImm()); + FixInstructionId32(bcIns, index); + break; + case BytecodeInstruction::Opcode::ECMA_CREATEARRAYWITHBUFFER_PREF_IMM16: + index = GetOrInsertConstantPool(ConstPoolType::ARRAY_LITERAL, + bcIns.GetImm()); + FixInstructionId32(bcIns, index); + break; + case BytecodeInstruction::Opcode::ECMA_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8: + methodId = pf.ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset(); + index = GetOrInsertConstantPool(ConstPoolType::CLASS_FUNCTION, methodId); + FixInstructionId32(bcIns, index); + index = GetOrInsertConstantPool(ConstPoolType::CLASS_LITERAL, + bcIns.GetImm()); + FixInstructionId32(bcIns, index, 1); + break; + default: + break; } } // NOLINTNEXTLINE(hicpp-use-auto) auto pc = const_cast(bcIns.GetAddress()); bcIns = bcIns.GetNext(); FixOpcode(pc); + UpdateICOffset(const_cast(method), pc); } } @@ -549,7 +540,8 @@ uint32_t PandaFileTranslator::GetOrInsertConstantPool(ConstPoolType type, uint32 return index; } -JSHandle PandaFileTranslator::DefineMethodById(uint32_t methodId, FunctionKind kind) const +JSHandle PandaFileTranslator::DefineMethodInLiteral(JSThread *thread, uint32_t methodId, FunctionKind kind, + uint16_t length) const { auto method = const_cast(FindMethods(methodId)); ASSERT(method != nullptr); @@ -570,6 +562,7 @@ JSHandle PandaFileTranslator::DefineMethodById(uint32_t methodId, Fu JSObject::SetPrototype(thread_, initialGeneratorFuncPrototype, env->GetGeneratorPrototype()); jsFunc->SetProtoOrDynClass(thread_, initialGeneratorFuncPrototype); } + jsFunc->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length)); return jsFunc; } } // namespace panda::ecmascript diff --git a/ecmascript/class_linker/panda_file_translator.h b/ecmascript/class_linker/panda_file_translator.h index 5547543a0bbe795fec4292fcda84b7c0ecd57c5f..bd6427fd0018bfdc3897e1c24513b3fedd025ec9 100644 --- a/ecmascript/class_linker/panda_file_translator.h +++ b/ecmascript/class_linker/panda_file_translator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_PANDA_FILE_TRANSLATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_PANDA_FILE_TRANSLATOR_H +#ifndef ECMASCRIPT_CLASS_LINKER_PANDA_FILE_TRANSLATOR_H +#define ECMASCRIPT_CLASS_LINKER_PANDA_FILE_TRANSLATOR_H #include "ecmascript/ecma_vm.h" #include "ecmascript/js_function.h" @@ -51,7 +51,8 @@ public: NO_MOVE_SEMANTIC(PandaFileTranslator); static JSHandle TranslatePandaFile(EcmaVM *vm, const panda_file::File &pf, const CString &methodName); - JSHandle DefineMethodById(uint32_t methodId, FunctionKind kind) const; + JSHandle DefineMethodInLiteral(JSThread *thread, uint32_t methodId, FunctionKind kind, + uint16_t length) const; private: enum class ConstPoolType : uint8_t { @@ -109,6 +110,7 @@ private: void TranslateBytecode(uint32_t insSz, const uint8_t *insArr, const panda_file::File &pf, const JSMethod *method); void FixInstructionId32(const BytecodeInstruction &inst, uint32_t index, uint32_t fixOrder = 0) const; void FixOpcode(uint8_t *pc) const; + void UpdateICOffset(JSMethod *method, uint8_t *pc) const; void SetMethods(Span methods, const uint32_t numMethods) { @@ -133,4 +135,4 @@ private: std::set translated_code_; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_PANDA_FILE_TRANSLATOR_H +#endif // ECMASCRIPT_CLASS_LINKER_PANDA_FILE_TRANSLATOR_H diff --git a/ecmascript/class_linker/program_object-inl.h b/ecmascript/class_linker/program_object-inl.h index ee1263311e764c8171bfa630aecef1dd2d29ea30..1c235eb625e2fc666e61313d60ef4a8ff65fce75 100644 --- a/ecmascript/class_linker/program_object-inl.h +++ b/ecmascript/class_linker/program_object-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_PROGRAM_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_PROGRAM_INL_H +#ifndef ECMASCRIPT_CLASS_LINKER_PROGRAM_INL_H +#define ECMASCRIPT_CLASS_LINKER_PROGRAM_INL_H #include "program_object.h" #include "ecmascript/mem/region_factory.h" @@ -39,4 +39,4 @@ void Program::FreeMethodData(RegionFactory *factory) } } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_PROGRAM_INL_H \ No newline at end of file +#endif // ECMASCRIPT_CLASS_LINKER_PROGRAM_INL_H \ No newline at end of file diff --git a/ecmascript/class_linker/program_object.h b/ecmascript/class_linker/program_object.h index b1fc7cfe3e4f07320a41bee95da75c01ae890be3..6f27229019979cdef004dfa3ee8e465c8ce070c6 100644 --- a/ecmascript/class_linker/program_object.h +++ b/ecmascript/class_linker/program_object.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_PROGRAM_H -#define PANDA_RUNTIME_ECMASCRIPT_PROGRAM_H +#ifndef ECMASCRIPT_CLASS_LINKER_PROGRAM_H +#define ECMASCRIPT_CLASS_LINKER_PROGRAM_H #include "ecmascript/ecma_macros.h" #include "ecmascript/js_tagged_value-inl.h" @@ -28,7 +28,7 @@ class Program : public ECMAObject { public: DECL_CAST(Program) - static constexpr size_t LOCATION_OFFSET = sizeof(ECMAObject); + static constexpr size_t LOCATION_OFFSET = ECMAObject::SIZE; ACCESSORS(Location, LOCATION_OFFSET, CONSTANT_POOL_OFFSET) ACCESSORS(ConstantPool, CONSTANT_POOL_OFFSET, MAIN_FUNCTION_OFFSET) ACCESSORS(MainFunction, MAIN_FUNCTION_OFFSET, METHODS_DATA_OFFSET) @@ -57,7 +57,7 @@ public: inline const uint8_t *GetInstructions() const; - static constexpr size_t NAME_OFFSET = sizeof(ECMAObject); + static constexpr size_t NAME_OFFSET = ECMAObject::SIZE; ACCESSORS(Name, NAME_OFFSET, NUMBER_VREGS_OFFSET) ACCESSORS(NumberVRegs, NUMBER_VREGS_OFFSET, NUMBER_IC_SLOTS_OFFSET) ACCESSORS(NumberICSlots, NUMBER_IC_SLOTS_OFFSET, BYTECODE_OFFSET) @@ -80,4 +80,4 @@ public: }; } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_PROGRAM_H +#endif // ECMASCRIPT_CLASS_LINKER_PROGRAM_H diff --git a/ecmascript/common.h b/ecmascript/common.h index 23fd9380242541333129472b95198a00ea29f3da..55cf2cb0ce4d5c1ab7ffeebcebc0eae4ae5d912f 100644 --- a/ecmascript/common.h +++ b/ecmascript/common.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMMON_H -#define PANDA_RUNTIME_ECMASCRIPT_COMMON_H +#ifndef ECMASCRIPT_COMMON_H +#define ECMASCRIPT_COMMON_H #include "libpandabase/macros.h" @@ -27,11 +27,11 @@ constexpr size_t NUM_MANDATORY_JSFUNC_ARGS = 3; #define PUBLIC_API PANDA_PUBLIC_API #ifdef NDEBUG -#define DUMP_API_ATTR +#define DUMP_API_ATTR __attribute__((unused)) #else #define DUMP_API_ATTR __attribute__((visibility ("default"), used)) #endif } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_COMMON_H +#endif // ECMASCRIPT_COMMON_H diff --git a/ecmascript/compiler/BUILD.gn b/ecmascript/compiler/BUILD.gn index d627f9fea2fd9434962b2dc6d0446279f8f5b1e1..162ecd49752c6318d9b4b2138b0308f8cb666448 100644 --- a/ecmascript/compiler/BUILD.gn +++ b/ecmascript/compiler/BUILD.gn @@ -28,6 +28,10 @@ config("include_llvm") { ] } +config("ark_jsruntime_compiler_config") { + configs = [ "//ark/js_runtime:ark_jsruntime_common_config" ] +} + ohos_shared_library("libark_jsoptimizer") { sources = [ "circuit.cpp", @@ -37,6 +41,7 @@ ohos_shared_library("libark_jsoptimizer") { "gate.cpp", "llvm_ir_builder.cpp", "llvm_mcjit_compiler.cpp", + "llvm_stackmap_parse.cpp", "scheduler.cpp", "stub_interface.cpp", "stub_optimizer.cpp", @@ -46,7 +51,7 @@ ohos_shared_library("libark_jsoptimizer") { configs = [ ":include_llvm", - "//ark/js_runtime:ark_jsruntime_config", + ":ark_jsruntime_compiler_config", "//ark/js_runtime:ark_jsruntime_public_config", "$ark_root/runtime:arkruntime_public_config", ] @@ -177,8 +182,6 @@ ohos_shared_library("libark_jsoptimizer") { ] output_extension = "so" - if (!is_standard_system) { - relative_install_dir = "ark" - } + relative_install_dir = "ark" subsystem_name = "ark" } diff --git a/ecmascript/compiler/circuit.cpp b/ecmascript/compiler/circuit.cpp index 4995c188e8b746dd9c37fb2ab096f1d93fd99c80..f1a0c3c7357777cb281f74bed1b5ead7e5cf4aa6 100644 --- a/ecmascript/compiler/circuit.cpp +++ b/ecmascript/compiler/circuit.cpp @@ -352,4 +352,14 @@ void Circuit::SetSpaceDataSize(size_t sz) { return this->space.resize(sz); } + +panda::ecmascript::FrameType Circuit::GetFrameType() const +{ + return this->frameType; +} + +void Circuit::SetFrameType(panda::ecmascript::FrameType type) +{ + this->frameType = type; +} } // namespace kungfu diff --git a/ecmascript/compiler/circuit.h b/ecmascript/compiler/circuit.h index 36056bbd7d4cf89abb3e8377ed0203a6a02b4c9a..d8306d5f1d39c31bdbd964317ceb627c793084d5 100644 --- a/ecmascript/compiler/circuit.h +++ b/ecmascript/compiler/circuit.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_CIRCUIT_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_CIRCUIT_H +#ifndef ECMASCRIPT_COMPILER_CIRCUIT_H +#define ECMASCRIPT_COMPILER_CIRCUIT_H #include #include @@ -25,6 +25,8 @@ #include "ecmascript/compiler/gate.h" #include "libpandabase/macros.h" #include "securec.h" +#include "ecmascript/frames.h" + namespace kungfu { const size_t INITIAL_SPACE = 1U << 0U; // this should be tuned @@ -83,6 +85,8 @@ public: [[nodiscard]] uint8_t *GetDataPtr(size_t offset); [[nodiscard]] size_t GetSpaceDataSize() const; void SetSpaceDataSize(size_t sz); + panda::ecmascript::FrameType GetFrameType() const; + void SetFrameType(panda::ecmascript::FrameType type); private: uint8_t *AllocateSpace(size_t gateSize); @@ -94,7 +98,8 @@ private: size_t gateCounter; TimeStamp time; std::vector dataSection; + panda::ecmascript::FrameType frameType {panda::ecmascript::FrameType::OPTIMIZED_FRAME}; }; } // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_CIRCUIT_H +#endif // ECMASCRIPT_COMPILER_CIRCUIT_H diff --git a/ecmascript/compiler/circuit_builder.cpp b/ecmascript/compiler/circuit_builder.cpp index 119fc6f7aacbc651120571098ccd235f2ae7f071..307edc8b58f54d21d4812127c83b2083c8cccafe 100644 --- a/ecmascript/compiler/circuit_builder.cpp +++ b/ecmascript/compiler/circuit_builder.cpp @@ -61,15 +61,15 @@ AddrShift CircuitBuilder::NewBooleanConstant(bool val) AddrShift CircuitBuilder::NewDoubleConstant(double val) { auto constantList = Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST)); - return circuit_->NewGate(OpCode(OpCode::FLOAT64_CONSTANT), bit_cast(val), - {constantList}, TypeCode::NOTYPE); + return circuit_->NewGate(OpCode(OpCode::FLOAT64_CONSTANT), bit_cast(val), {constantList}, + TypeCode::NOTYPE); } AddrShift CircuitBuilder::UndefineConstant() { auto constantList = Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST)); return circuit_->NewGate(OpCode(OpCode::INT64_CONSTANT), panda::coretypes::TaggedValue::VALUE_UNDEFINED, - {constantList}, TypeCode::NOTYPE); + {constantList}, TypeCode::NOTYPE); } AddrShift CircuitBuilder::HoleConstant() @@ -316,7 +316,7 @@ AddrShift CircuitBuilder::NewCallGate(StubInterfaceDescriptor *descriptor, AddrS return circuit_->NewGate(opcode, args.size() + 1, inputs, TypeCode::JS_ANY); } -AddrShift CircuitBuilder::NewCallGate(StubInterfaceDescriptor *descriptor, AddrShift target, AddrShift depend, +AddrShift CircuitBuilder::NewCallGate(StubInterfaceDescriptor *descriptor, AddrShift target, AddrShift depend, std::initializer_list args) { std::vector inputs; @@ -328,6 +328,40 @@ AddrShift CircuitBuilder::NewCallGate(StubInterfaceDescriptor *descriptor, Addr OpCode opcode = GetCallOpCodeFromMachineType(descriptor->GetReturnType()); return circuit_->NewGate(opcode, args.size() + 1, inputs, TypeCode::JS_ANY); } + +AddrShift CircuitBuilder::NewCallRuntimeGate(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, + std::initializer_list args) +{ + ASSERT(descriptor->GetStubKind() == StubInterfaceDescriptor::RUNTIME_STUB); + std::vector inputs; + auto dependEntry = Circuit::GetCircuitRoot(OpCode(OpCode::DEPEND_ENTRY)); + inputs.push_back(dependEntry); + inputs.push_back(target); + inputs.push_back(thread); + for (auto arg : args) { + inputs.push_back(arg); + } + OpCode opcode = GetCallOpCodeFromMachineType(descriptor->GetReturnType()); + // 2 : 2 means extra two input gates (target thread ) + return circuit_->NewGate(opcode, args.size() + 2, inputs, TypeCode::JS_ANY); +} + +AddrShift CircuitBuilder::NewCallRuntimeGate(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, + AddrShift depend, std::initializer_list args) +{ + ASSERT(descriptor->GetStubKind() == StubInterfaceDescriptor::RUNTIME_STUB); + std::vector inputs; + inputs.push_back(depend); + inputs.push_back(target); + inputs.push_back(thread); + for (auto arg : args) { + inputs.push_back(arg); + } + OpCode opcode = GetCallOpCodeFromMachineType(descriptor->GetReturnType()); + // 2 : 2 means extra two input gates (target thread ) + return circuit_->NewGate(opcode, args.size() + 2, inputs, TypeCode::JS_ANY); +} + AddrShift CircuitBuilder::Alloca(int size) { auto allocaList = Circuit::GetCircuitRoot(OpCode(OpCode::ALLOCA_LIST)); diff --git a/ecmascript/compiler/circuit_builder.h b/ecmascript/compiler/circuit_builder.h index 3289590eb62c8d61d4a7cfdef01e27edc036cce6..35e3c473934d9b6c1d9f66f4067e8137c03d7900 100644 --- a/ecmascript/compiler/circuit_builder.h +++ b/ecmascript/compiler/circuit_builder.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H +#ifndef ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H +#define ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H #include "ecmascript/compiler/circuit.h" #include "ecmascript/compiler/gate.h" @@ -55,10 +55,13 @@ public: AddrShift NewArithMeticGate(OpCode opcode, AddrShift value); AddrShift NewLogicGate(OpCode opcode, AddrShift left, AddrShift right); AddrShift NewLogicGate(OpCode opcode, AddrShift value); - AddrShift NewCallGate(StubInterfaceDescriptor *descriptor, AddrShift target, - std::initializer_list args); - AddrShift NewCallGate(StubInterfaceDescriptor *descriptor, AddrShift target, AddrShift depend, - std::initializer_list args); + AddrShift NewCallGate(StubInterfaceDescriptor *descriptor, AddrShift target, std::initializer_list args); + AddrShift NewCallGate(StubInterfaceDescriptor *descriptor, AddrShift target, AddrShift depend, + std::initializer_list args); + AddrShift NewCallRuntimeGate(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, + std::initializer_list args); + AddrShift NewCallRuntimeGate(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, + AddrShift depend, std::initializer_list args); static OpCode GetLoadOpCodeFromMachineType(MachineType type); static OpCode GetStoreOpCodeFromMachineType(MachineType type); static OpCode GetSelectOpCodeFromMachineType(MachineType type); @@ -69,4 +72,4 @@ private: }; } // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H \ No newline at end of file +#endif // ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H \ No newline at end of file diff --git a/ecmascript/compiler/circuit_visualizer.cpp b/ecmascript/compiler/circuit_visualizer.cpp index 7d65858818a7a1a1be5d5ac7c8a8fe95711ad758..b533cc01cc96126dd1e2e75dcf8a6e86cc91a05b 100644 --- a/ecmascript/compiler/circuit_visualizer.cpp +++ b/ecmascript/compiler/circuit_visualizer.cpp @@ -20,7 +20,7 @@ namespace kungfu { #ifndef NDEBUG void CircuitVisualizer::DumpDFG() {} -void CircuitVisualizer::PrintGateVisit(const Gate *node, std::ostream &os, int depth, int indentation) +void CircuitVisualizer::PrintGateVisit(Gate *node, std::ostream &os, int depth, int indentation) { for (int i = 0; i < indentation; ++i) { os << "---"; @@ -46,13 +46,13 @@ void CircuitVisualizer::PrintGateVisit(const Gate *node, std::ostream &os, int d } } -void CircuitVisualizer::PrintGate(const Gate *node, int depth) +void CircuitVisualizer::PrintGate(Gate *node, int depth) { PrintGateVisit(node, std::cout, depth, 0); std::flush(std::cout); } -void CircuitVisualizer::PrintSingleGate(const Gate *node, std::ostream &os) +void CircuitVisualizer::PrintSingleGate(Gate *node, std::ostream &os) { ASSERT(node != nullptr); (void)os; diff --git a/ecmascript/compiler/circuit_visualizer.h b/ecmascript/compiler/circuit_visualizer.h index 97cf12f27b32ee03fb60c2a9e8338d435af10cb5..b968082360213bff6fc2dc0c17bcaae7ac6b3632 100644 --- a/ecmascript/compiler/circuit_visualizer.h +++ b/ecmascript/compiler/circuit_visualizer.h @@ -13,12 +13,15 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_CIRCUIT_VISUALIZER_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_CIRCUIT_VISUALIZER_H +#ifndef ECMASCRIPT_COMPILER_CIRCUIT_VISUALIZER_H +#define ECMASCRIPT_COMPILER_CIRCUIT_VISUALIZER_H #include #include #include +#include +#include "circuit.h" +#include "gate.h" namespace kungfu { #ifndef NDEBUG diff --git a/ecmascript/compiler/fast_stub_define.h b/ecmascript/compiler/fast_stub_define.h index e6e909ef1d3ee88959f5e8eca20df117de62ed65..9dbc8ab846fc7c2d1f2eace4e65f4a4c2df5287f 100644 --- a/ecmascript/compiler/fast_stub_define.h +++ b/ecmascript/compiler/fast_stub_define.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_FASTSTUB_DEFINE_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_FASTSTUB_DEFINE_H +#ifndef ECMASCRIPT_COMPILER_FASTSTUB_DEFINE_H +#define ECMASCRIPT_COMPILER_FASTSTUB_DEFINE_H namespace kungfu { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -22,12 +22,8 @@ namespace kungfu { V(AddElementInternal, 5) \ V(CallSetter, 2) \ V(ThrowTypeError, 2) \ - V(JSProxySetProperty, 6) - -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define EXTERNAL_REFRENCE_STUB_LIST(V) \ - V(GetHash32, 2) \ - V(PhiTest, 1) + V(JSProxySetProperty, 6) \ + V(GetHash32, 2) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define FAST_RUNTIME_STUB_LIST(V) \ @@ -54,13 +50,21 @@ namespace kungfu { V(FindOwnProperty, 6) \ V(FindOwnElement, 2) \ V(NewLexicalEnvDyn, 4) \ - V(FindOwnProperty2, 3) \ - V(FindOwnElement2, 5) + V(FindOwnProperty2, 6) \ + V(FindOwnElement2, 6) -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define CALL_STUB_LIST(V) \ - FAST_RUNTIME_STUB_LIST(V) \ - EXTERNAL_REFRENCE_STUB_LIST(V) \ +#define CALL_STUB_LIST(V) \ + FAST_RUNTIME_STUB_LIST(V) \ EXTERNAL_RUNTIMESTUB_LIST(V) + +enum CallStubId { +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define DEF_FAST_STUB(name, counter) NAME_##name, + FAST_RUNTIME_STUB_LIST(DEF_FAST_STUB) FAST_STUB_MAXCOUNT, + EXTERNAL_RUNTIME_STUB_BEGIN = FAST_STUB_MAXCOUNT - 1, + EXTERNAL_RUNTIMESTUB_LIST(DEF_FAST_STUB) EXTERN_RUNTIME_STUB_MAXCOUNT, +#undef DEF_FAST_STUB + CALL_STUB_MAXCOUNT = EXTERN_RUNTIME_STUB_MAXCOUNT, +}; } // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_FASTSTUB_DEFINE_H \ No newline at end of file +#endif // ECMASCRIPT_COMPILER_FASTSTUB_DEFINE_H \ No newline at end of file diff --git a/ecmascript/compiler/fastpath_optimizer.h b/ecmascript/compiler/fastpath_optimizer.h index a59cff4d0b8b60e131a88ce082c01855955a1440..bf61207024cb64dc120da1095be43aea0d771772 100644 --- a/ecmascript/compiler/fastpath_optimizer.h +++ b/ecmascript/compiler/fastpath_optimizer.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_FASTPATH_OPTIMIZER_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_FASTPATH_OPTIMIZER_H +#ifndef ECMASCRIPT_COMPILER_FASTPATH_OPTIMIZER_H +#define ECMASCRIPT_COMPILER_FASTPATH_OPTIMIZER_H #include "ecmascript/compiler/fast_stub_define.h" #include "ecmascript/compiler/stub_optimizer.h" @@ -69,4 +69,4 @@ private: std::array fastRuntimeOptimizers_; }; } // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_FASTPATH_OPTIMIZER_H \ No newline at end of file +#endif // ECMASCRIPT_COMPILER_FASTPATH_OPTIMIZER_H \ No newline at end of file diff --git a/ecmascript/compiler/gate.h b/ecmascript/compiler/gate.h index 9b1b1255c80d691b354932e1d6adaa17aec4be36..6c76373deffb8f7af752d621bb2b43d60543d2c5 100644 --- a/ecmascript/compiler/gate.h +++ b/ecmascript/compiler/gate.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_GATE_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_GATE_H +#ifndef ECMASCRIPT_COMPILER_GATE_H +#define ECMASCRIPT_COMPILER_GATE_H #include #include @@ -386,4 +386,4 @@ private: }; } // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_GATE_H +#endif // ECMASCRIPT_COMPILER_GATE_H diff --git a/ecmascript/compiler/llvm_ir_builder.cpp b/ecmascript/compiler/llvm_ir_builder.cpp index 9092e87b0fefd328f5d59b32acf10c4ee9331a32..22fa5a9adb66fb4d6652e2aeaae98271d045fca6 100644 --- a/ecmascript/compiler/llvm_ir_builder.cpp +++ b/ecmascript/compiler/llvm_ir_builder.cpp @@ -22,43 +22,45 @@ #include "ecmascript/compiler/gate.h" #include "ecmascript/compiler/stub_interface.h" #include "ecmascript/js_array.h" +#include "ecmascript/js_thread.h" #include "llvm/IR/Instructions.h" #include "llvm/Support/Host.h" #include "llvm_mcjit_compiler.h" #include "securec.h" +#include "utils/logger.h" namespace kungfu { std::unordered_map g_values = {}; LLVMIRBuilder::LLVMIRBuilder(const std::vector> *schedule, const Circuit *circuit) - : m_schedule(schedule), m_circuit(circuit) + : schedule_(schedule), circuit_(circuit) { - m_module = LLVMModuleCreateWithName("simple_module"); - LLVMSetTarget(m_module, "x86_64-unknown-linux-gnu"); - m_builder = LLVMCreateBuilder(); - m_context = LLVMGetGlobalContext(); + module_ = LLVMModuleCreateWithName("simple_module"); + LLVMSetTarget(module_, "x86_64-unknown-linux-gnu"); + builder_ = LLVMCreateBuilder(); + context_ = LLVMGetGlobalContext(); LLVMTypeRef paramTys[] = { LLVMInt32Type(), }; - m_function = LLVMAddFunction(m_module, "foo", LLVMFunctionType(LLVMInt32Type(), paramTys, 1, 0)); - m_bbIdMapBb.clear(); + function_ = LLVMAddFunction(module_, "foo", LLVMFunctionType(LLVMInt32Type(), paramTys, 1, 0)); + bbIdMapBb_.clear(); } LLVMIRBuilder::LLVMIRBuilder(const std::vector> *schedule, const Circuit *circuit, LLVMModuleRef module, LLVMValueRef function) - : m_schedule(schedule), m_circuit(circuit), m_module(module), m_function(function) + : schedule_(schedule), circuit_(circuit), module_(module), function_(function) { - LLVMSetTarget(m_module, "x86_64-unknown-linux-gnu"); - m_builder = LLVMCreateBuilder(); - m_context = LLVMGetGlobalContext(); - m_bbIdMapBb.clear(); + LLVMSetTarget(module_, "x86_64-unknown-linux-gnu"); + builder_ = LLVMCreateBuilder(); + context_ = LLVMGetGlobalContext(); + bbIdMapBb_.clear(); } int LLVMIRBuilder::FindBasicBlock(AddrShift gate) const { - for (size_t bbIdx = 0; bbIdx < m_schedule->size(); bbIdx++) { - for (size_t instIdx = (*m_schedule)[bbIdx].size(); instIdx > 0; instIdx--) { - AddrShift tmp = (*m_schedule)[bbIdx][instIdx - 1]; + for (size_t bbIdx = 0; bbIdx < schedule_->size(); bbIdx++) { + for (size_t instIdx = (*schedule_)[bbIdx].size(); instIdx > 0; instIdx--) { + AddrShift tmp = (*schedule_)[bbIdx][instIdx - 1]; if (tmp == gate) { return bbIdx; } @@ -69,37 +71,37 @@ int LLVMIRBuilder::FindBasicBlock(AddrShift gate) const void LLVMIRBuilder::Build() { - std::cout << "LLVM IR Builder Create Id Map of Blocks..." << std::endl; - for (size_t bbIdx = 0; bbIdx < m_schedule->size(); bbIdx++) { - for (size_t instIdx = (*m_schedule)[bbIdx].size(); instIdx > 0; instIdx--) { - GateId gateId = m_circuit->GetId((*m_schedule)[bbIdx][instIdx - 1]); - m_instIdMapBbId[gateId] = bbIdx; + LOG_ECMA(INFO) << "LLVM IR Builder Create Id Map of Blocks..."; + for (size_t bbIdx = 0; bbIdx < schedule_->size(); bbIdx++) { + for (size_t instIdx = (*schedule_)[bbIdx].size(); instIdx > 0; instIdx--) { + GateId gateId = circuit_->GetId((*schedule_)[bbIdx][instIdx - 1]); + instIdMapBbId_[gateId] = bbIdx; } } - std::cout << "LLVM IR Builder Visit Gate..." << std::endl; - for (size_t bbIdx = 0; bbIdx < (*m_schedule).size(); bbIdx++) { + LOG_ECMA(INFO) << "LLVM IR Builder Visit Gate..."; + for (size_t bbIdx = 0; bbIdx < (*schedule_).size(); bbIdx++) { OperandsVector predecessors; - for (auto in : m_circuit->GetInVector((*m_schedule)[bbIdx][0])) { - if (!m_circuit->GetOpCode(in).IsState()) { + for (auto in : circuit_->GetInVector((*schedule_)[bbIdx][0])) { + if (!circuit_->GetOpCode(in).IsState()) { continue; } - predecessors.insert(m_instIdMapBbId[m_circuit->GetId(in)]); + predecessors.insert(instIdMapBbId_[circuit_->GetId(in)]); } VisitBlock(bbIdx, predecessors); - for (size_t instIdx = (*m_schedule)[bbIdx].size(); instIdx > 0; instIdx--) { - AddrShift gate = (*m_schedule)[bbIdx][instIdx - 1]; - std::vector ins = m_circuit->GetInVector(gate); - std::vector outs = m_circuit->GetOutVector(gate); - switch (m_circuit->GetOpCode(gate)) { + for (size_t instIdx = (*schedule_)[bbIdx].size(); instIdx > 0; instIdx--) { + AddrShift gate = (*schedule_)[bbIdx][instIdx - 1]; + std::vector ins = circuit_->GetInVector(gate); + std::vector outs = circuit_->GetOutVector(gate); + switch (circuit_->GetOpCode(gate)) { case OpCode::NOP: break; case OpCode::CIRCUIT_ROOT: break; case OpCode::STATE_ENTRY: { - int block = m_instIdMapBbId[m_circuit->GetId(gate)]; - int bbOut = m_instIdMapBbId[m_circuit->GetId(outs[0])]; + int block = instIdMapBbId_[circuit_->GetId(gate)]; + int bbOut = instIdMapBbId_[circuit_->GetId(outs[0])]; VisitGoto(block, bbOut); break; } @@ -123,10 +125,10 @@ void LLVMIRBuilder::Build() case OpCode::THROW: break; case OpCode::IF_BRANCH: { - AddrShift bTrue = (m_circuit->GetOpCode(outs[0]) == OpCode::IF_TRUE) ? outs[0] : outs[1]; - AddrShift bFalse = (m_circuit->GetOpCode(outs[0]) == OpCode::IF_FALSE) ? outs[0] : outs[1]; - int bbTrue = m_instIdMapBbId[m_circuit->GetId(bTrue)]; - int bbFalse = m_instIdMapBbId[m_circuit->GetId(bFalse)]; + AddrShift bTrue = (circuit_->GetOpCode(outs[0]) == OpCode::IF_TRUE) ? outs[0] : outs[1]; + AddrShift bFalse = (circuit_->GetOpCode(outs[0]) == OpCode::IF_FALSE) ? outs[0] : outs[1]; + int bbTrue = instIdMapBbId_[circuit_->GetId(bTrue)]; + int bbFalse = instIdMapBbId_[circuit_->GetId(bFalse)]; VisitBranch(gate, ins[1], bbTrue, bbFalse); break; } @@ -139,32 +141,32 @@ void LLVMIRBuilder::Build() case OpCode::IF_FALSE: case OpCode::SWITCH_CASE: case OpCode::DEFAULT_CASE: { - int block = m_instIdMapBbId[m_circuit->GetId(gate)]; - int bbOut = m_instIdMapBbId[m_circuit->GetId(outs[0])]; + int block = instIdMapBbId_[circuit_->GetId(gate)]; + int bbOut = instIdMapBbId_[circuit_->GetId(outs[0])]; VisitGoto(block, bbOut); break; } case OpCode::MERGE: { - int block = m_instIdMapBbId[m_circuit->GetId(gate)]; + int block = instIdMapBbId_[circuit_->GetId(gate)]; int bbOut; for (int i = 0; i < static_cast(outs.size()); i++) { - bbOut = m_instIdMapBbId[m_circuit->GetId(outs[i])]; + bbOut = instIdMapBbId_[circuit_->GetId(outs[i])]; VisitGoto(block, bbOut); } break; } case OpCode::LOOP_BEGIN: { - int block = m_instIdMapBbId[m_circuit->GetId(gate)]; + int block = instIdMapBbId_[circuit_->GetId(gate)]; int bbOut; for (int i = 0; i < static_cast(outs.size()); i++) { - bbOut = m_instIdMapBbId[m_circuit->GetId(outs[i])]; + bbOut = instIdMapBbId_[circuit_->GetId(outs[i])]; VisitGoto(block, bbOut); } break; } case OpCode::LOOP_BACK: { - int block = m_instIdMapBbId[m_circuit->GetId(gate)]; - int bbOut = m_instIdMapBbId[m_circuit->GetId(outs[0])]; + int block = instIdMapBbId_[circuit_->GetId(gate)]; + int bbOut = instIdMapBbId_[circuit_->GetId(outs[0])]; VisitGoto(block, bbOut); break; } @@ -199,25 +201,25 @@ void LLVMIRBuilder::Build() VisitAlloca(gate); break; } - case OpCode::INT1_ARG: // no break, fall through + case OpCode::INT1_ARG: // no break, fall through case OpCode::INT32_ARG: // no break, fall through case OpCode::INT64_ARG: { VisitParameter(gate); break; } case OpCode::INT32_CONSTANT: { - int32_t value = m_circuit->GetBitField(gate); + int32_t value = circuit_->GetBitField(gate); VisitInt32Constant(gate, value); break; } - case OpCode::JS_CONSTANT: // no break, fall through + case OpCode::JS_CONSTANT: // no break, fall through case OpCode::INT64_CONSTANT: { - int64_t value = m_circuit->GetBitField(gate); + int64_t value = circuit_->GetBitField(gate); VisitInt64Constant(gate, value); break; } case OpCode::FLOAT64_CONSTANT: { - int64_t value = m_circuit->GetBitField(gate); + int64_t value = circuit_->GetBitField(gate); VisitFloat64Constant(gate, value); break; } @@ -297,7 +299,11 @@ void LLVMIRBuilder::Build() VisitIntOr(gate, ins[0], ins[1]); break; } - case OpCode::INT32_LSR: // no break, fall through + case OpCode::INT64_XOR: { + VisitIntXor(gate, ins[0], ins[1]); + break; + } + case OpCode::INT32_LSR: // no break, fall through case OpCode::INT64_LSR: { VisitIntLsr(gate, ins[0], ins[1]); break; @@ -328,7 +334,7 @@ void LLVMIRBuilder::Build() break; } case OpCode::FLOAT64_EQ: { - VisitFloatOrDoubleCmp(gate, ins[0], ins[1], LLVMRealUEQ); + VisitFloatOrDoubleCmp(gate, ins[0], ins[1], LLVMRealOEQ); break; } case OpCode::INT32_NE: // no break, fall through @@ -347,14 +353,14 @@ void LLVMIRBuilder::Build() break; } case OpCode::INT32_STORE: { - VisitStore(gate, MachineRep::K_WORD32, ins[2], ins[1]); // 2:baseAddr gate, 1:data gate + VisitStore(gate, MachineRep::K_WORD32, ins[2], ins[1]); // 2:baseAddr gate, 1:data gate break; } case OpCode::INT64_STORE: { - VisitStore(gate, MachineRep::K_WORD64, ins[2], ins[1]); // 2:baseAddr gate, 1:data gate + VisitStore(gate, MachineRep::K_WORD64, ins[2], ins[1]); // 2:baseAddr gate, 1:data gate break; } - case OpCode::INT32_TO_FLOAT64: // no break, fall through + case OpCode::INT32_TO_FLOAT64: // no break, fall through case OpCode::INT64_TO_FLOAT64: { VisitCastIntToDouble(gate, ins[0]); break; @@ -364,8 +370,8 @@ void LLVMIRBuilder::Build() break; } default: { - std::cout << "The gate below need to be translated " << std::endl; - m_circuit->Print(gate); + LOG_ECMA(ERROR) << "The gate below need to be translated "; + circuit_->Print(gate); UNREACHABLE(); } } @@ -377,12 +383,12 @@ void LLVMIRBuilder::Build() BasicBlock *LLVMIRBuilder::EnsurBasicBlock(int id) { BasicBlock *bb = nullptr; - if (m_bbIdMapBb.count(id) == 0) { + if (bbIdMapBb_.count(id) == 0) { auto newBB = std::make_unique(id); bb = newBB.get(); - m_bbIdMapBb[id] = std::move(newBB); + bbIdMapBb_[id] = std::move(newBB); } else { - bb = m_bbIdMapBb[id].get(); + bb = bbIdMapBb_[id].get(); } return bb; } @@ -392,50 +398,49 @@ void LLVMIRBuilder::StartLLVMBuilder(BasicBlock *bb) const EnsureLLVMBB(bb); LLVMTFBuilderBasicBlockImpl *impl = bb->GetImpl(); if ((impl == nullptr) || (impl->llvm_bb_ == nullptr)) { - std::cerr << "StartLLVMBuilder failed " << std::endl; + LOG_ECMA(ERROR) << "StartLLVMBuilder failed "; return; } impl->started = true; bb->SetImpl(impl); - std::cout << "Basicblock id :" << bb->GetId() << - "impl:" << bb->GetImpl() << std::endl; - LLVMPositionBuilderAtEnd(m_builder, impl->llvm_bb_); + LOG_ECMA(DEBUG) << "Basicblock id :" << bb->GetId() << "impl:" << bb->GetImpl(); + LLVMPositionBuilderAtEnd(builder_, impl->llvm_bb_); } void LLVMIRBuilder::ProcessPhiWorkList() { - for (BasicBlock *bb : m_phiRebuildWorklist) { + for (BasicBlock *bb : phiRebuildWorklist_) { auto impl = bb->GetImpl(); for (auto &e : impl->not_merged_phis) { BasicBlock *pred = e.pred; if (impl->started == 0) { - std::cerr << " ProcessPhiWorkList error hav't start " << std::endl; + LOG_ECMA(ERROR) << " ProcessPhiWorkList error hav't start "; return; } LLVMValueRef value = g_values[e.operand]; if (LLVMTypeOf(value) != LLVMTypeOf(e.phi)) { - std::cerr << " ProcessPhiWorkList LLVMTypeOf don't match error " << std::endl; + LOG_ECMA(ERROR) << " ProcessPhiWorkList LLVMTypeOf don't match error "; } LLVMBasicBlockRef llvmBB = EnsureLLVMBB(pred); LLVMAddIncoming(e.phi, &value, &llvmBB, 1); } impl->not_merged_phis.clear(); } - m_phiRebuildWorklist.clear(); + phiRebuildWorklist_.clear(); } void LLVMIRBuilder::EndCurrentBlock() const { - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); + LLVMTFBuilderBasicBlockImpl *impl = currentBb_->GetImpl(); impl->ended = true; } void LLVMIRBuilder::End() { - ASSERT(!!m_currentBb); + ASSERT(!!currentBb_); EndCurrentBlock(); ProcessPhiWorkList(); - for (auto &it: m_bbIdMapBb) { + for (auto &it : bbIdMapBb_) { it.second->ResetImpl(); } } @@ -450,6 +455,63 @@ LLVMTFBuilderBasicBlockImpl *LLVMIRBuilder::EnsureLLVMBBImpl(BasicBlock *bb) con return bb->GetImpl(); } +void LLVMIRBuilder::PrologueHandle(LLVMModuleRef &module, LLVMBuilderRef &builder) +{ + auto frameType = circuit_->GetFrameType(); + LLVMAddTargetDependentFunctionAttr(function_, "frame-pointer", "all"); + + if (frameType == panda::ecmascript::FrameType::OPTIMIZED_FRAME) { + LLVMAddTargetDependentFunctionAttr(function_, "js-stub-call", "0"); + } else if (frameType == panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME) { + LLVMAddTargetDependentFunctionAttr(function_, "js-stub-call", "1"); + } else { + LOG_ECMA(DEBUG) << "frameType interpret type error !"; + } + + if (frameType != panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME) { + return; + } + + LLVMValueRef baseAddr = LLVMCallingFp(module_, builder_); + /* current frame + 0 pre rbp <-- rbp + -8 type + -16 pre frame thread fp + */ + LLVMValueRef thread = LLVMGetParam(function_, 0); + LLVMValueRef rtoffset = LLVMConstInt(LLVMInt64Type(), + panda::ecmascript::JSThread::GetCurrentFrameOffset(), + 0); + LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, thread, rtoffset, ""); + + LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, rtbaseoffset, LLVMPointerType(LLVMInt64Type(), 0), ""); + LLVMValueRef threadFpValue = LLVMBuildLoad(builder_, rtbaseAddr, ""); + LLVMValueRef value = LLVMBuildStore(builder_, threadFpValue, baseAddr); + LOG_ECMA(INFO) << "store value:" << value << " " + << "value type" << LLVMTypeOf(value); +} + +LLVMValueRef LLVMIRBuilder::LLVMCallingFp(LLVMModuleRef &module, LLVMBuilderRef &builder) +{ + /* 0:calling 1:its caller */ + std::vector args = {LLVMConstInt(LLVMInt32Type(), 0, false)}; + auto fn = LLVMGetNamedFunction(module, "llvm.frameaddress.p0i8"); + if (!fn) { + /* init instrinsic function declare */ + LLVMTypeRef paramTys1[] = { + LLVMInt32Type(), + }; + auto fnTy = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), paramTys1, 1, 0); + fn = LLVMAddFunction(module, "llvm.frameaddress.p0i8", fnTy); + } + LLVMValueRef fAddrRet = LLVMBuildCall(builder, fn, args.data(), 1, ""); + LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder, fAddrRet, LLVMInt64Type(), "cast_int64_t"); + LLVMValueRef addr = LLVMBuildSub(builder, frameAddr, LLVMConstInt(LLVMInt64Type(), + 16, false), ""); // 16:thread fp offset + LLVMValueRef preFpAddr = LLVMBuildIntToPtr(builder, addr, LLVMPointerType(LLVMInt64Type(), 0), "thread.fp.Addr"); + return preFpAddr; +} + LLVMBasicBlockRef LLVMIRBuilder::EnsureLLVMBB(BasicBlock *bb) const { LLVMTFBuilderBasicBlockImpl *impl = EnsureLLVMBBImpl(bb); @@ -457,12 +519,11 @@ LLVMBasicBlockRef LLVMIRBuilder::EnsureLLVMBB(BasicBlock *bb) const return impl->llvm_bb_; } std::string buf = "B" + std::to_string(bb->GetId()); - LLVMBasicBlockRef llvmBB = LLVMAppendBasicBlock(m_function, buf.c_str()); + LLVMBasicBlockRef llvmBB = LLVMAppendBasicBlock(function_, buf.c_str()); impl->llvm_bb_ = llvmBB; impl->continuation = llvmBB; bb->SetImpl(impl); - std::cout << std::endl - << "create LLVMBB = " << buf << " impl:" << bb->GetImpl() << std::endl; + LOG_ECMA(DEBUG) << "create LLVMBB = " << buf << " impl:" << bb->GetImpl(); return llvmBB; } @@ -471,19 +532,19 @@ LLVMTypeRef LLVMIRBuilder::GetMachineRepType(MachineRep rep) const LLVMTypeRef dstType; switch (rep) { case MachineRep::K_BIT: - dstType = LLVMInt1TypeInContext(m_context); + dstType = LLVMInt1TypeInContext(context_); break; case MachineRep::K_WORD8: - dstType = LLVMInt8TypeInContext(m_context); + dstType = LLVMInt8TypeInContext(context_); break; case MachineRep::K_WORD32: - dstType = LLVMInt32TypeInContext(m_context); + dstType = LLVMInt32TypeInContext(context_); break; case MachineRep::K_FLOAT64: - dstType = LLVMDoubleTypeInContext(m_context); + dstType = LLVMDoubleTypeInContext(context_); break; - default: // 64bit int goes to default scenario - dstType = LLVMInt64TypeInContext(m_context); + default: // 64bit int goes to default scenario + dstType = LLVMInt64TypeInContext(context_); break; } return dstType; @@ -491,61 +552,79 @@ LLVMTypeRef LLVMIRBuilder::GetMachineRepType(MachineRep rep) const void LLVMIRBuilder::VisitCall(AddrShift gate, const std::vector &inList) { - constexpr int paraStartIndex = 2; - int index = m_circuit->GetBitField(inList[1]); + int paraStartIndex = 2; + int index = circuit_->GetBitField(inList[1]); LLVMValueRef callee = reinterpret_cast(FastStubs::GetInstance().GetFastStub(index)); - LLVMValueRef params[16]; // 16: number of param + StubInterfaceDescriptor *callee_descriptor = FastStubs::GetInstance().GetStubDescriptor(index); + // runtime case + if (callee_descriptor->GetStubKind() == StubInterfaceDescriptor::RUNTIME_STUB) { + LLVMTypeRef rtfuncType = reinterpret_cast(FastStubs::GetInstance().GetRunTimeLLVMType(index)); + LLVMTypeRef rtfuncTypePtr = LLVMPointerType(rtfuncType, 0); + LLVMValueRef thread = g_values[inList[2]]; // 2 : 2 means skip two input gates (target thread ) + LLVMValueRef rtoffset = LLVMConstInt(LLVMInt64Type(), + panda::ecmascript::JSThread::GetRuntimeFunctionsOffset() + + (index - FAST_STUB_MAXCOUNT) * sizeof(uintptr_t), + 0); + LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, thread, rtoffset, ""); + LLVMDumpValue(thread); + LLVMDumpValue(rtoffset); + LLVMDumpValue(rtbaseoffset); + LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, rtbaseoffset, LLVMPointerType(LLVMInt64Type(), 0), ""); + LLVMValueRef llvmAddr = LLVMBuildLoad(builder_, rtbaseAddr, ""); + callee = LLVMBuildIntToPtr(builder_, llvmAddr, rtfuncTypePtr, "cast"); + std::cout << std::endl; + LLVMDumpValue(callee); + paraStartIndex += 1; + } + // 16 : params limit + LLVMValueRef params[16]; for (size_t paraIdx = paraStartIndex; paraIdx < inList.size(); ++paraIdx) { AddrShift gateTmp = inList[paraIdx]; params[paraIdx - paraStartIndex] = g_values[gateTmp]; - m_circuit->Print(gateTmp); - std::cout << "arg" << paraIdx - paraStartIndex << " th " << std::endl; - LLVMDumpValue(params[paraIdx - paraStartIndex]); - std::cout << std::endl; + circuit_->Print(gateTmp); + LOG_ECMA(INFO) << "arg" << paraIdx - paraStartIndex << ": " + << LLVMPrintValueToString(params[paraIdx - paraStartIndex]); } if (callee == nullptr) { - std::cout << "callee nullptr" << std::endl; + LOG_ECMA(ERROR) << "callee nullptr"; return; } - g_values[gate] = LLVMBuildCall(m_builder, callee, params, inList.size() - paraStartIndex, ""); + g_values[gate] = LLVMBuildCall(builder_, callee, params, inList.size() - paraStartIndex, ""); return; } void LLVMIRBuilder::VisitAlloca(AddrShift gate) { - std::cout << " VisitAlloca " << std::endl; - uint64_t sizeEnum = m_circuit->GetBitField(gate); + uint64_t sizeEnum = circuit_->GetBitField(gate); LLVMTypeRef sizeType = GetMachineRepType(static_cast(sizeEnum)); - std::cout << LLVMGetTypeKind(sizeType) << std::endl; - g_values[gate] = LLVMBuildPtrToInt(m_builder, LLVMBuildAlloca(m_builder, sizeType, ""), - LLVMInt64Type(), ""); // NOTE: pointer val is currently viewed as 64bits + LOG_ECMA(INFO) << LLVMGetTypeKind(sizeType); + g_values[gate] = LLVMBuildPtrToInt(builder_, LLVMBuildAlloca(builder_, sizeType, ""), LLVMInt64Type(), + ""); // NOTE: pointer val is currently viewed as 64bits return; } void LLVMIRBuilder::VisitPhi(AddrShift gate, const std::vector &srcGates, MachineRep rep) { - std::cout << "--------------- VisitPhi ------------------------" << std::endl; LLVMTypeRef type = GetMachineRepType(rep); - LLVMValueRef phi = LLVMBuildPhi(m_builder, type, ""); - std::vector relMergeIns = m_circuit->GetInVector(srcGates[0]); + LLVMValueRef phi = LLVMBuildPhi(builder_, type, ""); + std::vector relMergeIns = circuit_->GetInVector(srcGates[0]); bool addToPhiRebuildList = false; for (int i = 1; i < static_cast(srcGates.size()); i++) { - GateId gateId = m_circuit->GetId(relMergeIns[i - 1]); - int bbIdx = m_instIdMapBbId[gateId]; - std::cout << "srcGate: " << srcGates[i] << " dominated gateId:" << gateId << "dominated bbIdx: " << bbIdx - << std::endl; - int cnt = m_bbIdMapBb.count(bbIdx); + GateId gateId = circuit_->GetId(relMergeIns[i - 1]); + int bbIdx = instIdMapBbId_[gateId]; + LOG_ECMA(INFO) << "srcGate: " << srcGates[i] << " dominated gateId:" << gateId << "dominated bbIdx: " << bbIdx; + int cnt = bbIdMapBb_.count(bbIdx); // if cnt = 0 means bb with current bbIdx hasn't been created if (cnt > 0) { - BasicBlock *bb = m_bbIdMapBb[bbIdx].get(); - std::cout << "bb : " << bb << std::endl; + BasicBlock *bb = bbIdMapBb_[bbIdx].get(); + LOG_ECMA(INFO) << "bb : " << bb; if (bb == nullptr) { - std::cerr << "VisitPhi failed BasicBlock nullptr" << std::endl; + LOG_ECMA(ERROR) << "VisitPhi failed BasicBlock nullptr"; return; } LLVMTFBuilderBasicBlockImpl *impl = bb->GetImpl(); if (impl == nullptr) { - std::cerr << "VisitPhi failed impl nullptr" << std::endl; + LOG_ECMA(ERROR) << "VisitPhi failed impl nullptr"; return; } LLVMBasicBlockRef llvmBB = EnsureLLVMBB(bb); // The llvm bb @@ -554,7 +633,7 @@ void LLVMIRBuilder::VisitPhi(AddrShift gate, const std::vector &srcGa LLVMAddIncoming(phi, &value, &llvmBB, 1); } else { addToPhiRebuildList = true; - impl = m_currentBb->GetImpl(); + impl = currentBb_->GetImpl(); impl->not_merged_phis.emplace_back(); auto ¬_merged_phi = impl->not_merged_phis.back(); not_merged_phi.phi = phi; @@ -565,50 +644,48 @@ void LLVMIRBuilder::VisitPhi(AddrShift gate, const std::vector &srcGa addToPhiRebuildList = true; } if (addToPhiRebuildList == true) { - m_phiRebuildWorklist.push_back(m_currentBb); + phiRebuildWorklist_.push_back(currentBb_); } g_values[gate] = phi; } - std::cout << "+++++++++++++++ VisitPhi ++++++++++++++++++++++++" << std::endl; } void LLVMIRBuilder::VisitReturn(AddrShift gate, AddrShift popCount, const std::vector &operands) const { // [STATE] [DEPEND] [VALUE] [RETURN_LIST] - std::cout << "VisitReturn -" << std::endl; - AddrShift operand = operands[2]; // 2: skip 2 in gate that are not data gate - std::cout << "VisitReturn gate: " << gate << " popCount: " << popCount << std::endl; - std::cout << "VisitReturn return: " << operand << " gateId: " << m_circuit->GetId(operand) << std::endl; + AddrShift operand = operands[2]; // 2: skip 2 in gate that are not data gate + LOG_ECMA(INFO) << " gate: " << gate << " popCount: " << popCount; + LOG_ECMA(INFO) << " return: " << operand << " gateId: " << circuit_->GetId(operand); LLVMValueRef returnValue = g_values[operand]; - LLVMDumpValue(returnValue); - std::cout << std::endl; - LLVMBuildRet(m_builder, returnValue); - std::cout << "VisitReturn +" << std::endl; + LOG_ECMA(INFO) << LLVMPrintValueToString(returnValue); + LLVMBuildRet(builder_, returnValue); } void LLVMIRBuilder::VisitBlock(int gate, const OperandsVector &predecessors) // NOLINTNEXTLINE(misc-unused-parameters) { - std::cout << "VisitBlock BBIdx:" << gate << " -" << std::endl; + LOG_ECMA(INFO) << " BBIdx:" << gate; BasicBlock *bb = EnsurBasicBlock(gate); if (bb == nullptr) { - std::cerr << "StartLLVMBuilder failed " << std::endl; + LOG_ECMA(ERROR) << " block create failed "; return; } - m_currentBb = bb; + currentBb_ = bb; LLVMBasicBlockRef llvmbb = EnsureLLVMBB(bb); StartLLVMBuilder(bb); - std::cout << "predecessors :"; + LOG_ECMA(INFO) << "predecessors :"; for (int predecessor : predecessors) { BasicBlock *pre = EnsurBasicBlock(predecessor); if (pre == nullptr) { - std::cerr << "StartLLVMBuilder failed predecessor:%d nullptr" << predecessor << std::endl; + LOG_ECMA(ERROR) << " block setup failed, predecessor:%d nullptr" << predecessor; return; } LLVMBasicBlockRef llvmpre = EnsureLLVMBB(pre); - std::cout << " " << predecessor; + LOG_ECMA(INFO) << " " << predecessor; LLVMMoveBasicBlockBefore(llvmpre, llvmbb); } - std::cout << "VisitBlock BBIdx:" << gate << " +" << std::endl; + if (gate == 0) { // insert prologue + PrologueHandle(module_, builder_); + } } void LLVMIRBuilder::VisitGoto(int block, int bbOut) @@ -618,11 +695,11 @@ void LLVMIRBuilder::VisitGoto(int block, int bbOut) } BasicBlock *bb = EnsurBasicBlock(bbOut); if (bb == nullptr) { - std::cerr << "StartLLVMBuilder failed " << std::endl; + LOG_ECMA(ERROR) << " block is nullptr "; return; } - llvm::BasicBlock *self = llvm::unwrap(EnsureLLVMBB(m_bbIdMapBb[block].get())); - llvm::BasicBlock *out = llvm::unwrap(EnsureLLVMBB(m_bbIdMapBb[bbOut].get())); + llvm::BasicBlock *self = llvm::unwrap(EnsureLLVMBB(bbIdMapBb_[block].get())); + llvm::BasicBlock *out = llvm::unwrap(EnsureLLVMBB(bbIdMapBb_[bbOut].get())); llvm::BranchInst::Create(out, self); EndCurrentBlock(); } @@ -630,65 +707,60 @@ void LLVMIRBuilder::VisitGoto(int block, int bbOut) void LLVMIRBuilder::VisitInt32Constant(AddrShift gate, int32_t value) const { LLVMValueRef llvmValue = LLVMConstInt(LLVMInt32Type(), value, 0); - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); + LLVMTFBuilderBasicBlockImpl *impl = currentBb_->GetImpl(); impl->values_[gate] = llvmValue; g_values[gate] = llvmValue; char *str = LLVMPrintValueToString(llvmValue); - std::cout << "VisitInt32Constant set gate:" << gate << " value:" << value << " impl:" << impl << std::endl; - std::cout << "VisitInt32Constant " << str << std::endl; + LOG_ECMA(INFO) << "VisitInt32Constant set gate:" << gate << " value:" << value; + LOG_ECMA(INFO) << "VisitInt32Constant " << str; } void LLVMIRBuilder::VisitInt64Constant(AddrShift gate, int64_t value) const { LLVMValueRef llvmValue = LLVMConstInt(LLVMInt64Type(), value, 0); - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); + LLVMTFBuilderBasicBlockImpl *impl = currentBb_->GetImpl(); impl->values_[gate] = llvmValue; g_values[gate] = llvmValue; char *str = LLVMPrintValueToString(llvmValue); - std::cout << "VisitInt64Constant set gate:" << gate << " value:" << value << " impl:" << impl << std::endl; - std::cout << "VisitInt64Constant " << str << std::endl; + LOG_ECMA(INFO) << "VisitInt64Constant set gate:" << gate << " value:" << value; + LOG_ECMA(INFO) << "VisitInt64Constant " << str; } void LLVMIRBuilder::VisitFloat64Constant(AddrShift gate, int64_t value) const { LLVMValueRef llvmValue = LLVMConstReal(LLVMDoubleType(), value); - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); + LLVMTFBuilderBasicBlockImpl *impl = currentBb_->GetImpl(); impl->values_[gate] = llvmValue; g_values[gate] = llvmValue; char *str = LLVMPrintValueToString(llvmValue); - std::cout << "VisitFloat64Constant set gate:" << gate << " value:" << value << " impl:" << impl << std::endl; - std::cout << "VisitFloat64Constant " << str << std::endl; + LOG_ECMA(INFO) << "VisitFloat64Constant set gate:" << gate << " value:" << value; + LOG_ECMA(INFO) << "VisitFloat64Constant " << str; } void LLVMIRBuilder::VisitParameter(AddrShift gate) const { - int argth = m_circuit->LoadGatePtrConst(gate)->GetBitField(); - std::cout << "VisitParameter " << argth << "th parameter -" << std::endl; - LLVMValueRef value = LLVMGetParam(m_function, argth); - LLVMDumpValue(value); - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); + int argth = circuit_->LoadGatePtrConst(gate)->GetBitField(); + LOG_ECMA(INFO) << " Parameter value" << argth; + LLVMValueRef value = LLVMGetParam(function_, argth); + LLVMTFBuilderBasicBlockImpl *impl = currentBb_->GetImpl(); impl->values_[gate] = value; g_values[gate] = value; - std::cout << "VisitParameter set gate:" << gate << " value:" << value << " impl:" << impl << std::endl; + LOG_ECMA(INFO) << "VisitParameter set gate:" << gate << " value:" << value; // NOTE: caller put args, otherwise crash if (value == nullptr) { - std::cerr << "VisitParameter arg" << argth << "th nullptr" << std::endl; + LOG_ECMA(ERROR) << "generate LLVM IR for para: " << argth << "fail"; return; } - LLVMDumpValue(value); char *str = LLVMPrintValueToString(value); - if (str != nullptr) { - std::cout << "VisitParameter arg" << argth << "th value = " << str << std::endl; - } - std::cout << "VisitParameter " << argth << "th parameter +" << std::endl; + LOG_ECMA(INFO) << "para arg:" << argth << "value IR:" << str; } void LLVMIRBuilder::VisitBranch(AddrShift gate, AddrShift cmp, int btrue, int bfalse) { - std::cout << "VisitBranch - cmp:" << cmp << std::endl; - LLVMTFBuilderBasicBlockImpl *impl = EnsureLLVMBBImpl(m_currentBb); + LOG_ECMA(INFO) << "cmp gate:" << cmp; + LLVMTFBuilderBasicBlockImpl *impl = EnsureLLVMBBImpl(currentBb_); if ((impl->values_.count(cmp) == 0) && (g_values.count(cmp) == 0)) { - std::cerr << "VisitBranch cmp empty !" << std::endl; + LOG_ECMA(ERROR) << "Branch condition gate is nullptr!"; return; } LLVMValueRef cond = g_values[cmp]; @@ -700,364 +772,282 @@ void LLVMIRBuilder::VisitBranch(AddrShift gate, AddrShift cmp, int btrue, int bf LLVMBasicBlockRef llvmTrueBB = trueBB->GetImpl()->llvm_bb_; LLVMBasicBlockRef llvmFalseBB = falseBB->GetImpl()->llvm_bb_; - LLVMValueRef result = LLVMBuildCondBr(m_builder, cond, llvmTrueBB, llvmFalseBB); + LLVMValueRef result = LLVMBuildCondBr(builder_, cond, llvmTrueBB, llvmFalseBB); EndCurrentBlock(); g_values[gate] = result; - std::cout << "VisitBranch + " << std::endl; } void LLVMIRBuilder::VisitSwitch(AddrShift gate, AddrShift input, const std::vector &outList) { - std::cout << "VisitSwitch - " << std::endl; LLVMValueRef cond = g_values[input]; unsigned caseNum = outList.size(); BasicBlock *curOutBB = nullptr; LLVMBasicBlockRef llvmDefaultOutBB = nullptr; for (int i = 0; i < static_cast(caseNum); i++) { - curOutBB = EnsurBasicBlock(m_instIdMapBbId[m_circuit->GetId(outList[i])]); + curOutBB = EnsurBasicBlock(instIdMapBbId_[circuit_->GetId(outList[i])]); EnsureLLVMBB(curOutBB); - if (m_circuit->GetOpCode(outList[i]) == OpCode::DEFAULT_CASE) { + if (circuit_->GetOpCode(outList[i]) == OpCode::DEFAULT_CASE) { llvmDefaultOutBB = curOutBB->GetImpl()->llvm_bb_; } } - LLVMValueRef result = LLVMBuildSwitch(m_builder, cond, llvmDefaultOutBB, caseNum - 1); + LLVMValueRef result = LLVMBuildSwitch(builder_, cond, llvmDefaultOutBB, caseNum - 1); LLVMBasicBlockRef llvmCurOutBB = nullptr; for (int i = 0; i < static_cast(caseNum - 1); i++) { - if (m_circuit->GetOpCode(outList[i]) == OpCode::DEFAULT_CASE) { + if (circuit_->GetOpCode(outList[i]) == OpCode::DEFAULT_CASE) { continue; } - curOutBB = EnsurBasicBlock(m_instIdMapBbId[m_circuit->GetId(outList[i])]); + curOutBB = EnsurBasicBlock(instIdMapBbId_[circuit_->GetId(outList[i])]); llvmCurOutBB = curOutBB->GetImpl()->llvm_bb_; - LLVMAddCase(result, LLVMConstInt(LLVMInt64Type(), m_circuit->GetBitField(outList[i]), 0), llvmCurOutBB); + LLVMAddCase(result, LLVMConstInt(LLVMInt64Type(), circuit_->GetBitField(outList[i]), 0), llvmCurOutBB); } EndCurrentBlock(); g_values[gate] = result; - std::cout << "VisitSwitch + " << std::endl; } void LLVMIRBuilder::VisitLoad(AddrShift gate, MachineRep rep, AddrShift base) const { - std::cout << "VisitLoad base:" << base << std::endl; - + LOG_ECMA(INFO) << "Load base gate:" << base; LLVMValueRef baseAddr = g_values[base]; if (LLVMGetTypeKind(LLVMTypeOf(baseAddr)) == LLVMIntegerTypeKind) { - baseAddr = LLVMBuildIntToPtr(m_builder, baseAddr, LLVMPointerType(GetMachineRepType(rep), 0), ""); + baseAddr = LLVMBuildIntToPtr(builder_, baseAddr, LLVMPointerType(GetMachineRepType(rep), 0), ""); } - baseAddr = LLVMBuildPointerCast(m_builder, baseAddr, LLVMPointerType(GetMachineRepType(rep), 0), ""); - LLVMValueRef value = LLVMBuildLoad(m_builder, baseAddr, ""); + baseAddr = LLVMBuildPointerCast(builder_, baseAddr, LLVMPointerType(GetMachineRepType(rep), 0), ""); + LLVMValueRef value = LLVMBuildLoad(builder_, baseAddr, ""); g_values[gate] = value; - std::cout << "VisitLoad value:" << value << " " - << "value type" << LLVMTypeOf(value) << std::endl; + LOG_ECMA(INFO) << "Load value:" << value << " " + << "value type" << LLVMTypeOf(value); } void LLVMIRBuilder::VisitStore(AddrShift gate, MachineRep rep, AddrShift base, AddrShift dataToStore) const { - std::cout << "VisitStore base:" << base << std::endl; + LOG_ECMA(INFO) << "store base gate:" << base; LLVMValueRef baseAddr = g_values[base]; if (LLVMGetTypeKind(LLVMTypeOf(baseAddr)) == LLVMIntegerTypeKind) { - baseAddr = LLVMBuildIntToPtr(m_builder, baseAddr, LLVMPointerType(GetMachineRepType(rep), 0), ""); + baseAddr = LLVMBuildIntToPtr(builder_, baseAddr, LLVMPointerType(GetMachineRepType(rep), 0), ""); } - baseAddr = LLVMBuildPointerCast(m_builder, baseAddr, LLVMPointerType(GetMachineRepType(rep), 0), ""); - LLVMValueRef value = LLVMBuildStore(m_builder, g_values[dataToStore], baseAddr); + baseAddr = LLVMBuildPointerCast(builder_, baseAddr, LLVMPointerType(GetMachineRepType(rep), 0), ""); + LLVMValueRef value = LLVMBuildStore(builder_, g_values[dataToStore], baseAddr); g_values[gate] = value; - std::cout << "VisitStore value:" << value << " " - << "value type" << LLVMTypeOf(value) << std::endl; + LOG_ECMA(INFO) << "store value:" << value << " " + << "value type" << LLVMTypeOf(value); } + void LLVMIRBuilder::VisitIntOrUintCmp(AddrShift gate, AddrShift e1, AddrShift e2, LLVMIntPredicate opcode) const { - std::cout << "VisitIntOrUintCmp -" << std::endl; - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); - std::cout << "VisitIntOrUintCmp get gate:" << e1 << " value:" << g_values[e1] << " impl:" << impl << std::endl; - + LOG_ECMA(INFO) << "cmp gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; - + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildICmp(m_builder, opcode, e1Value, e2Value, ""); - + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildICmp(builder_, opcode, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitIntOrUintCmp set gate:" << gate << " value:" << result << " impl:" << impl << std::endl; - std::cout << "VisitIntOrUintCmp +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitFloatOrDoubleCmp(AddrShift gate, AddrShift e1, AddrShift e2, LLVMRealPredicate opcode) const { - std::cout << "VisitFloatOrDoubleCmp -" << std::endl; - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); - std::cout << "VisitFloatOrDouble get gate:" << e1 << " value:" << g_values[e1] << " impl:" << impl << std::endl; + LOG_ECMA(INFO) << "cmp gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildFCmp(m_builder, opcode, e1Value, e2Value, ""); + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildFCmp(builder_, opcode, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitFloatOrDoubleCmp set gate:" << gate << " value:" << result << " impl:" << impl << std::endl; - std::cout << "VisitFloatOrDoubleCmp +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitIntRev(AddrShift gate, AddrShift e1) const { - std::cout << "VisitIntRev -" << std::endl; - std::cout << "VisitIntRev get gate:" << e1 << " value:" << std::endl; + LOG_ECMA(INFO) << "int sign invert gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << std::endl; - LLVMValueRef result = LLVMBuildNeg(m_builder, e1Value, ""); + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); + LLVMValueRef result = LLVMBuildNeg(builder_, e1Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << std::endl; - std::cout << "VisitIntRev set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitIntRev +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitIntAdd(AddrShift gate, AddrShift e1, AddrShift e2, MachineRep rep) const { - std::cout << "VisitIntAdd -" << std::endl; - std::cout << "VisitIntAdd get gate:" << e1 << std::endl; + LOG_ECMA(INFO) << "int add gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); if (LLVMGetTypeKind(LLVMTypeOf(e1Value)) == LLVMPointerTypeKind) { // for scenario: pointer + offset - e1Value = LLVMBuildPtrToInt(m_builder, e1Value, GetMachineRepType(rep), ""); + e1Value = LLVMBuildPtrToInt(builder_, e1Value, GetMachineRepType(rep), ""); } - LLVMValueRef result = LLVMBuildAdd(m_builder, e1Value, e2Value, ""); + LLVMValueRef result = LLVMBuildAdd(builder_, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitIntAdd set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitIntAdd +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitFloatAdd(AddrShift gate, AddrShift e1, AddrShift e2) const { - std::cout << "VisitFloatAdd -" << std::endl; - std::cout << "VisitFloatAdd get gate:" << e1 << std::endl; + LOG_ECMA(INFO) << "float add gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildFAdd(m_builder, e1Value, e2Value, ""); + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildFAdd(builder_, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitFloatAdd set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitFloatAdd +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitFloatSub(AddrShift gate, AddrShift e1, AddrShift e2) const { - std::cout << "VisitFloatSub -" << std::endl; - std::cout << "VisitFloatSub get gate:" << gate << std::endl; - std::cout << " LLVMDumpValue e1 " << std::endl; + LOG_ECMA(INFO) << "float sub gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildFSub(m_builder, e1Value, e2Value, ""); + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildFSub(builder_, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitFloatSub set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitFloatSub +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitFloatMul(AddrShift gate, AddrShift e1, AddrShift e2) const { - std::cout << "VisitFloatMul -" << std::endl; - std::cout << "VisitFloatMul get gate:" << gate << std::endl; - std::cout << " LLVMDumpValue e1 " << std::endl; + LOG_ECMA(INFO) << "float mul gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildFMul(m_builder, e1Value, e2Value, ""); + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildFMul(builder_, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitFloatMul set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitFloatMul +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitFloatDiv(AddrShift gate, AddrShift e1, AddrShift e2) const { - std::cout << "VisitFloatDiv -" << std::endl; - std::cout << "VisitFloatDiv get gate:" << gate << std::endl; - std::cout << " LLVMDumpValue e1 " << std::endl; + LOG_ECMA(INFO) << "float div gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildFDiv(m_builder, e1Value, e2Value, ""); + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildFDiv(builder_, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitFloatDiv set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitFloatDiv +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitIntSub(AddrShift gate, AddrShift e1, AddrShift e2) const { - std::cout << "VisitIntSub -" << std::endl; - std::cout << "VisitIntSub get gate:" << e1 << std::endl; + LOG_ECMA(INFO) << "int sub gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildSub(m_builder, e1Value, e2Value, ""); + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildSub(builder_, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitIntSub set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitIntSub +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitIntMul(AddrShift gate, AddrShift e1, AddrShift e2) const { - std::cout << "VisitIntMul -" << std::endl; - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); - std::cout << "VisitIntMul get gate:" << e1 << " value:" << (impl->values_[e1]) << " impl:" << impl << std::endl; - + LOG_ECMA(INFO) << "int mul gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; - + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildMul(m_builder, e1Value, e2Value, ""); - + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildMul(builder_, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitIntMul set gate:" << gate << " value:" << result << " impl:" << impl << std::endl; - std::cout << "VisitIntMul +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitIntOr(AddrShift gate, AddrShift e1, AddrShift e2) const { - std::cout << "VisitIntOr -" << std::endl; - std::cout << "VisitIntOr get gate:" << e1 << std::endl; - std::cout << " LLVMDumpValue e1 " << std::endl; + LOG_ECMA(INFO) << "int or gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildOr(m_builder, e1Value, e2Value, ""); + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildOr(builder_, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitIntOr set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitIntOr +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitIntAnd(AddrShift gate, AddrShift e1, AddrShift e2) const { - std::cout << "VisitIntAnd -" << std::endl; - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); - std::cout << "VisitIntAnd get gate:" << e1 << " value:" << (impl->values_[e1]) << " impl:" << impl << std::endl; - + LOG_ECMA(INFO) << "int and gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; - + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildAnd(m_builder, e1Value, e2Value, ""); + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildAnd(builder_, e1Value, e2Value, ""); + g_values[gate] = result; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); +} +void LLVMIRBuilder::VisitIntXor(AddrShift gate, AddrShift e1, AddrShift e2) const +{ + LOG_ECMA(INFO) << "int xor gate:" << gate; + LLVMValueRef e1Value = g_values[e1]; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); + LLVMValueRef e2Value = g_values[e2]; + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildXor(builder_, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitIntAnd set gate:" << gate << " value:" << result << " impl:" << impl << std::endl; - std::cout << "VisitIntAnd +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitIntLsr(AddrShift gate, AddrShift e1, AddrShift e2) const { - std::cout << "VisitIntLsr -" << std::endl; - std::cout << "VisitIntLsr get gate:" << e1 << std::endl; - std::cout << " LLVMDumpValue e1 " << std::endl; + LOG_ECMA(INFO) << "int lsr gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - std::cout << " LLVMDumpValue e2 " << std::endl; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); LLVMValueRef e2Value = g_values[e2]; - LLVMDumpValue(e2Value); - LLVMValueRef result = LLVMBuildLShr(m_builder, e1Value, e2Value, ""); + LOG_ECMA(INFO) << "operand 1: " << LLVMPrintValueToString(e2Value); + LLVMValueRef result = LLVMBuildLShr(builder_, e1Value, e2Value, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitIntLsr set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitIntLsr +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } + void LLVMIRBuilder::VisitZExtInt(AddrShift gate, AddrShift e1, MachineRep rep) const { - std::cout << "VisitZExtInt -" << std::endl; - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); - std::cout << "VisitZExtInt get gate:" << e1 << "value:" << (impl->values_[e1]) << std::endl; - + LOG_ECMA(INFO) << "int zero extension gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - LLVMValueRef result = LLVMBuildZExt(m_builder, e1Value, GetMachineRepType(rep), ""); + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); + LLVMValueRef result = LLVMBuildZExt(builder_, e1Value, GetMachineRepType(rep), ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitZExtInt set gate:" << gate << " value:" << result << " impl:" << impl << std::endl; - std::cout << "VisitZExtInt +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitSExtInt(AddrShift gate, AddrShift e1, MachineRep rep) const { - std::cout << "VisitSExtInt -" << std::endl; - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); - std::cout << "VisitSExtInt get gate:" << e1 << "value:" << (impl->values_[e1]) << std::endl; - + LOG_ECMA(INFO) << "int sign extension gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - LLVMValueRef result = LLVMBuildSExt(m_builder, e1Value, GetMachineRepType(rep), ""); - + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); + LLVMValueRef result = LLVMBuildSExt(builder_, e1Value, GetMachineRepType(rep), ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitSExtInt set gate:" << gate << " value:" << result << " impl:" << impl << std::endl; - std::cout << "VisitSExtInt +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitCastIntXToIntY(AddrShift gate, AddrShift e1, MachineRep rep) const { - std::cout << "VisitCastIntXToIntY -" << std::endl; - LLVMTFBuilderBasicBlockImpl *impl = m_currentBb->GetImpl(); - std::cout << "VisitCastIntXToIntY get gate:" << e1 << "value:" << (impl->values_[e1]) << std::endl; - + LOG_ECMA(INFO) << "int cast2 int gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - LLVMValueRef result = LLVMBuildIntCast2(m_builder, e1Value, GetMachineRepType(rep), 1, ""); - + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); + LLVMValueRef result = LLVMBuildIntCast2(builder_, e1Value, GetMachineRepType(rep), 1, ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitCastIntXToIntY set gate:" << gate << " value:" << result << " impl:" << impl << std::endl; - std::cout << "VisitCastIntXToIntY +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitCastIntToDouble(AddrShift gate, AddrShift e1) const { - std::cout << "VisitCastIntToDouble -" << std::endl; + LOG_ECMA(INFO) << "int cast2 double gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - LLVMValueRef result = LLVMBuildSIToFP(m_builder, e1Value, LLVMDoubleType(), ""); + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); + LLVMValueRef result = LLVMBuildSIToFP(builder_, e1Value, LLVMDoubleType(), ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitCastIntToDouble set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitCastIntToDouble +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } void LLVMIRBuilder::VisitCastDoubleToInt(AddrShift gate, AddrShift e1) const { - std::cout << "VisitCastDoubleToInt -" << std::endl; + LOG_ECMA(INFO) << "double cast2 int gate:" << gate; LLVMValueRef e1Value = g_values[e1]; - LLVMDumpValue(e1Value); - LLVMValueRef result = LLVMBuildFPToSI(m_builder, e1Value, LLVMInt64Type(), ""); + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); + LLVMValueRef result = LLVMBuildFPToSI(builder_, e1Value, LLVMInt64Type(), ""); g_values[gate] = result; - LLVMDumpValue(result); - std::cout << "VisitCastDoubleToInt set gate:" << gate << " value:" << result << std::endl; - std::cout << "VisitCastDoubleToInt +" << std::endl; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } } // namespace kungfu diff --git a/ecmascript/compiler/llvm_ir_builder.h b/ecmascript/compiler/llvm_ir_builder.h index 34ba3bdc963bc612b08fb95d0c997dcf8a7d99e9..ca6f1dd0850a2d3d987952b4526fe0dc7edb4ff9 100644 --- a/ecmascript/compiler/llvm_ir_builder.h +++ b/ecmascript/compiler/llvm_ir_builder.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_LLVM_IR_BUILDER_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_LLVM_IR_BUILDER_H +#ifndef ECMASCRIPT_COMPILER_LLVM_IR_BUILDER_H +#define ECMASCRIPT_COMPILER_LLVM_IR_BUILDER_H #include #include @@ -58,7 +58,7 @@ public: return id_; } - template + template inline T *GetImpl() const { return static_cast(impl_); @@ -69,7 +69,7 @@ public: impl_ = impl; } - template + template inline void ResetImpl() { if (impl_) { @@ -94,7 +94,6 @@ struct NotMergedPhiDesc { struct LLVMTFBuilderBasicBlockImpl { LLVMBasicBlockRef llvm_bb_ = nullptr; LLVMBasicBlockRef continuation = nullptr; - LLVMBuilderRef llvm_builder_ = nullptr; std::unordered_map values_ = {}; bool started = false; bool ended = false; @@ -132,6 +131,7 @@ private: void VisitIntMul(AddrShift gate, AddrShift e1, AddrShift e2) const; void VisitIntOr(AddrShift gate, AddrShift e1, AddrShift e2) const; void VisitIntAnd(AddrShift gate, AddrShift e1, AddrShift e2) const; + void VisitIntXor(AddrShift gate, AddrShift e1, AddrShift e2) const; void VisitIntLsr(AddrShift gate, AddrShift e1, AddrShift e2) const; void VisitInt32LessThanOrEqual(AddrShift gate, AddrShift e1, AddrShift e2) const; void VisitIntOrUintCmp(AddrShift gate, AddrShift e1, AddrShift e2, LLVMIntPredicate opcode) const; @@ -147,6 +147,8 @@ private: void VisitCastInt64ToPointer(AddrShift gate, AddrShift e1) const; BasicBlock *EnsurBasicBlock(int id); + LLVMValueRef LLVMCallingFp(LLVMModuleRef &module, LLVMBuilderRef &builder); + void PrologueHandle(LLVMModuleRef &module, LLVMBuilderRef &builder); LLVMBasicBlockRef EnsureLLVMBB(BasicBlock *bb) const; LLVMTFBuilderBasicBlockImpl *EnsureLLVMBBImpl(BasicBlock *bb) const; void StartLLVMBuilder(BasicBlock *bb) const; @@ -159,19 +161,19 @@ private: void ProcessPhiWorkList(); private: - const std::vector> *m_schedule {nullptr}; - const Circuit *m_circuit {nullptr}; - BasicBlock *m_currentBb {nullptr}; - int m_lineNumber {0}; - - LLVMModuleRef m_module {nullptr}; - LLVMContextRef m_context; - LLVMValueRef m_function {nullptr}; - LLVMBuilderRef m_builder {nullptr}; - std::map m_instIdMapBbId; - BasicBlockMap m_bbIdMapBb; - - std::vector m_phiRebuildWorklist; + const std::vector> *schedule_ {nullptr}; + const Circuit *circuit_ {nullptr}; + BasicBlock *currentBb_ {nullptr}; + int lineNumber_ {0}; + + LLVMModuleRef module_ {nullptr}; + LLVMContextRef context_; + LLVMValueRef function_ {nullptr}; + LLVMBuilderRef builder_ {nullptr}; + std::map instIdMapBbId_; + BasicBlockMap bbIdMapBb_; + + std::vector phiRebuildWorklist_; }; #endif } // namespace kungfu \ No newline at end of file diff --git a/ecmascript/compiler/llvm_mcjit_compiler.cpp b/ecmascript/compiler/llvm_mcjit_compiler.cpp index 07a9a0c2195a47f77d9525924c35a8ac90d5234b..2ad0a094d0fb508643688113086b3e8bbf4b705b 100644 --- a/ecmascript/compiler/llvm_mcjit_compiler.cpp +++ b/ecmascript/compiler/llvm_mcjit_compiler.cpp @@ -13,18 +13,12 @@ * limitations under the License. */ -#include "llvm_mcjit_compiler.h" +#include "ecmascript/compiler/llvm_mcjit_compiler.h" #include - -#include "llvm-c/Analysis.h" -#include "llvm-c/Core.h" -#include "llvm-c/Disassembler.h" -#include "llvm-c/DisassemblerTypes.h" -#include "llvm-c/Target.h" -#include "llvm-c/Transforms/PassManagerBuilder.h" -#include "llvm-c/Transforms/Scalar.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/ADT/APInt.h" +#include "llvm/IR/Verifier.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/IR/Argument.h" @@ -37,13 +31,23 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" -#include "llvm/IR/Verifier.h" +#include "llvm/CodeGen/BuiltinGCs.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm-c/Analysis.h" +#include "llvm-c/Core.h" +#include "llvm-c/Target.h" +#include "llvm-c/Transforms/PassManagerBuilder.h" +#include "llvm-c/Transforms/Scalar.h" +#include "llvm/CodeGen/BuiltinGCs.h" + +#include "llvm/Transforms/Scalar.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Host.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/TargetSelect.h" +#include "llvm-c/Disassembler.h" +#include "llvm-c/DisassemblerTypes.h" +#include "llvm/IRReader/IRReader.h" + namespace kungfu { static uint8_t *RoundTripAllocateCodeSection(void *object, uintptr_t size, unsigned alignment, unsigned sectionID, @@ -79,18 +83,18 @@ static void RoundTripDestroy(void *object) void LLVMMCJITCompiler::UseRoundTripSectionMemoryManager() { auto sectionMemoryManager = std::make_unique(); - m_options.MCJMM = - LLVMCreateSimpleMCJITMemoryManager(&compilerState, RoundTripAllocateCodeSection, + options_.MCJMM = + LLVMCreateSimpleMCJITMemoryManager(&compilerState_, RoundTripAllocateCodeSection, RoundTripAllocateDataSection, RoundTripFinalizeMemory, RoundTripDestroy); } bool LLVMMCJITCompiler::BuildMCJITEngine() { std::cout << " BuildMCJITEngine - " << std::endl; - LLVMBool ret = LLVMCreateMCJITCompilerForModule(&m_engine, m_module, &m_options, sizeof(m_options), &m_error); - std::cout << " m_engine " << m_engine << std::endl; + LLVMBool ret = LLVMCreateMCJITCompilerForModule(&engine_, module_, &options_, sizeof(options_), &error_); + std::cout << " engine_ " << engine_ << std::endl; if (ret) { - std::cout << "m_error : " << m_error << std::endl; + std::cout << "error_ : " << error_ << std::endl; return false; } std::cout << " BuildMCJITEngine ++++++++++++ " << std::endl; @@ -103,13 +107,15 @@ void LLVMMCJITCompiler::BuildAndRunPasses() const LLVMPassManagerRef pass = LLVMCreatePassManager(); LLVMAddConstantPropagationPass(pass); LLVMAddInstructionCombiningPass(pass); - LLVMRunPassManager(pass, m_module); + llvm::unwrap(pass)->add(llvm::createRewriteStatepointsForGCLegacyPass()); + LLVMDumpModule(module_); + LLVMRunPassManager(pass, module_); LLVMDisposePassManager(pass); std::cout << "BuildAndRunPasses + " << std::endl; } -LLVMMCJITCompiler::LLVMMCJITCompiler(LLVMModuleRef module): m_module(module), m_engine(nullptr), - m_hostTriple(""), m_error(nullptr) +LLVMMCJITCompiler::LLVMMCJITCompiler(LLVMModuleRef module): module_(module), engine_(nullptr), + hostTriple_(""), error_(nullptr) { Initialize(); InitMember(); @@ -117,10 +123,10 @@ LLVMMCJITCompiler::LLVMMCJITCompiler(LLVMModuleRef module): m_module(module), m_ LLVMMCJITCompiler::~LLVMMCJITCompiler() { - m_module = nullptr; - m_engine = nullptr; - m_hostTriple = ""; - m_error = nullptr; + module_ = nullptr; + engine_ = nullptr; + hostTriple_ = ""; + error_ = nullptr; } void LLVMMCJITCompiler::Run() @@ -141,10 +147,11 @@ void LLVMMCJITCompiler::Initialize() LLVMInitializeNativeAsmPrinter(); LLVMInitializeNativeAsmParser(); LLVMInitializeAllTargets(); - LLVMInitializeMCJITCompilerOptions(&m_options, sizeof(m_options)); - m_options.OptLevel = 2; // opt level 2 + llvm::linkAllBuiltinGCs(); + LLVMInitializeMCJITCompilerOptions(&options_, sizeof(options_)); + options_.OptLevel = 2; // opt level 2 // Just ensure that this field still exists. - m_options.NoFramePointerElim = false; + options_.NoFramePointerElim = true; } static const char *SymbolLookupCallback(void *disInfo, uint64_t referenceValue, uint64_t *referenceType, @@ -154,11 +161,11 @@ static const char *SymbolLookupCallback(void *disInfo, uint64_t referenceValue, return nullptr; } -void LLVMMCJITCompiler::Disassemble() const +void LLVMMCJITCompiler::Disassemble(std::map addr2name) const { LLVMDisasmContextRef dcr = LLVMCreateDisasm("x86_64-unknown-linux-gnu", nullptr, 0, nullptr, SymbolLookupCallback); std::cout << "========================================================================" << std::endl; - for (auto it : compilerState.codeInfo) { + for (auto it : compilerState_.GetCodeInfo()) { uint8_t *byteSp; uintptr_t numBytes; byteSp = it.first; @@ -177,7 +184,10 @@ void LLVMMCJITCompiler::Disassemble() const byteSp += 4; // 4 sp offset numBytes -= 4; // 4 num bytes } - + uint64_t addr = reinterpret_cast(byteSp); + if (addr2name.find(addr) != addr2name.end()) { + std::cout << addr2name[addr].c_str() << ":" << std::endl; + } fprintf(stderr, "%08x: %08x %s\n", pc, *reinterpret_cast(byteSp), outString); pc += InstSize; byteSp += InstSize; @@ -189,9 +199,9 @@ void LLVMMCJITCompiler::Disassemble() const void LLVMMCJITCompiler::InitMember() { - if (m_module == nullptr) { - m_module = LLVMModuleCreateWithName("simple_module"); - LLVMSetTarget(m_module, "x86_64-unknown-linux-gnu"); + if (module_ == nullptr) { + module_ = LLVMModuleCreateWithName("simple_module"); + LLVMSetTarget(module_, "x86_64-unknown-linux-gnu"); } } } // namespace kungfu diff --git a/ecmascript/compiler/llvm_mcjit_compiler.h b/ecmascript/compiler/llvm_mcjit_compiler.h index 1da6ecfbad24a46ac1d5e7c9e3a582dcd85dfebd..b8c38782c634e951735b0c40827b4c5e89e74bf7 100644 --- a/ecmascript/compiler/llvm_mcjit_compiler.h +++ b/ecmascript/compiler/llvm_mcjit_compiler.h @@ -13,11 +13,12 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_LLVM_MCJINT_COMPILER_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_LLVM_MCJINT_COMPILER_H +#ifndef ECMASCRIPT_COMPILER_LLVM_MCJINT_COMPILER_H +#define ECMASCRIPT_COMPILER_LLVM_MCJINT_COMPILER_H #include #include +#include #include #include @@ -37,7 +38,7 @@ using ByteBuffer = std::vector; using BufferList = std::list; using StringList = std::list; struct CompilerState { - CompilerState(): machineCode(nullptr), codeBufferPos(0) + CompilerState(): machineCode(nullptr), codeBufferPos(0), stackMapsSection_(nullptr) { Reset(); static constexpr int prot = PROT_READ | PROT_WRITE | PROT_EXEC; // NOLINT(hicpp-signed-bitwise) @@ -64,7 +65,7 @@ struct CompilerState { codeSectionNames_.push_back(sectionName); addr = machineCode + codeBufferPos; std::cout << "AllocaCodeSection addr:" << std::hex << reinterpret_cast(addr) << std::endl; - codeInfo.push_back({addr, size}); + codeInfo_.push_back({addr, size}); return addr; } @@ -75,20 +76,30 @@ struct CompilerState { dataSectionList_.back().resize(size); dataSectionNames_.push_back(sectionName); addr = static_cast(dataSectionList_.back().data()); + if (!strcmp(sectionName, ".llvm_stackmaps")) { + std::cout << "llvm_stackmaps : " << addr << std::endl; + stackMapsSection_ = addr; + } return addr; } void Reset() { - codeInfo.clear(); + stackMapsSection_ = nullptr; + codeInfo_.clear(); dataSectionList_.clear(); dataSectionNames_.clear(); codeSectionNames_.clear(); codeBufferPos = 0; } -public: - /* for asssembler */ - std::vector> codeInfo {}; + uint8_t* GetStackMapsSection() const + { + return stackMapsSection_; + } + std::vector> GetCodeInfo() const + { + return codeInfo_; + } private: BufferList dataSectionList_ {}; StringList dataSectionNames_ {}; @@ -96,6 +107,10 @@ private: uint8_t *machineCode; const size_t MAX_MACHINE_CODE_SIZE = (1 << 20); // 1M int codeBufferPos = 0; + /* for asssembler */ + std::vector> codeInfo_ {}; + /* stack map */ + uint8_t* stackMapsSection_ {nullptr}; }; class LLVMMCJITCompiler { public: @@ -104,9 +119,13 @@ public: void Run(); const LLVMExecutionEngineRef &GetEngine() { - return m_engine; + return engine_; + } + void Disassemble(std::map addr2name = std::map()) const; + uint8_t *GetStackMapsSection() const + { + return compilerState_.GetStackMapsSection(); } - void Disassemble() const; private: void UseRoundTripSectionMemoryManager(); @@ -116,12 +135,12 @@ private: void Initialize(); void InitMember(); - LLVMMCJITCompilerOptions m_options; - LLVMModuleRef m_module; - LLVMExecutionEngineRef m_engine; - std::string m_hostTriple; - char *m_error; - struct CompilerState compilerState; + LLVMMCJITCompilerOptions options_; + LLVMModuleRef module_; + LLVMExecutionEngineRef engine_; + std::string hostTriple_; + char *error_; + struct CompilerState compilerState_; }; #endif diff --git a/ecmascript/compiler/llvm_stackmap_parse.cpp b/ecmascript/compiler/llvm_stackmap_parse.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e49ed47e66b5370bfebfda2ef42d32b6d604c164 --- /dev/null +++ b/ecmascript/compiler/llvm_stackmap_parse.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "ecmascript/compiler/llvm_stackmap_parse.h" +#include +#include +#include + +namespace kungfu { +std::string LocationTy::TypeToString(Kind location) const +{ + switch (location) { + case Kind::REGISTER: + return "Register Reg Value in a register"; + case Kind::DIRECT: + return "Direct Reg + Offset Frame index value"; + case Kind::INDIRECT: + return "Indirect [Reg + Offset] Spilled value"; + case Kind::CONSTANT: + return "Constant Offset Small constant"; + case Kind::CONSTANTNDEX: + return "ConstIndex constants[Offset] Large constant"; + default: + return "no know location"; + } +} + +bool LLVMStackMapParse::StackMapByAddr(uintptr_t funcAddr, DwarfRegAndOffsetType &info) +{ + for (auto it: callSiteInfos_) { + if (it.first == funcAddr) { + info = it.second; + return true; + } + } + return false; +} + +void LLVMStackMapParse::CalcCallSite() +{ + uint64_t recordNum = 0; + for (size_t i = 0; i < llvmStackMap_.StkSizeRecords.size(); i++) { + uintptr_t address = llvmStackMap_.StkSizeRecords[i].functionAddress; + std::cout << std::hex << "address " << address << std::endl; + uint64_t recordCount = llvmStackMap_.StkSizeRecords[i].recordCount; + std::cout << std::hex << "recordCount " << recordCount << std::endl; + recordNum += recordCount; + std::cout << std::hex << "recordNum " << recordNum << std::endl; + struct StkMapRecordHeadTy recordHead = llvmStackMap_.StkMapRecord[recordNum - 1].head; + uint32_t instructionOffset = recordHead.InstructionOffset; + std::cout << std::hex << "instructionOffset " << instructionOffset << std::endl; + uintptr_t callsite = address + instructionOffset; + + for (int j = 0; j < recordHead.NumLocations; j++) { + struct LocationTy loc = llvmStackMap_.StkMapRecord[recordNum - 1].Locations[j]; + if (loc.location == LocationTy::Kind::INDIRECT) { + DwarfRegAndOffsetType info(loc.DwarfRegNum, loc.OffsetOrSmallConstant); + Fun2InfoType callSiteInfo {callsite, info}; + callSiteInfos_.push_back(callSiteInfo); + } + } + } +} + +bool LLVMStackMapParse::CalculateStackMap(const uint8_t *stackMapAddr) +{ + stackMapAddr_ = stackMapAddr; + if (!stackMapAddr_) { + std::cerr << "stackMapAddr_ nullptr error ! " << std::endl; + return false; + } + dataInfo_ = std::make_unique(stackMapAddr_); + llvmStackMap_.head = dataInfo_->Read(); + uint32_t numFunctions, numConstants, numRecords; + numFunctions = dataInfo_->Read(); + numConstants = dataInfo_->Read(); + numRecords = dataInfo_->Read(); + for (uint32_t i = 0; i < numFunctions; i++) { + auto stkRecord = dataInfo_->Read(); + llvmStackMap_.StkSizeRecords.push_back(stkRecord); + } + for (uint32_t i = 0; i < numConstants; i++) { + auto val = dataInfo_->Read(); + llvmStackMap_.Constants.push_back(val); + } + for (uint32_t i = 0; i < numRecords; i++) { + struct StkMapRecordTy stkSizeRecord; + auto head = dataInfo_->Read(); + stkSizeRecord.head = head; + for (uint16_t j = 0; j < head.NumLocations; j++) { + auto location = dataInfo_->Read(); + stkSizeRecord.Locations.push_back(location); + } + uint16_t padding; + while (dataInfo_->GetOffset() & 7) { // 7: 8 byte align + padding = dataInfo_->Read(); + } + uint32_t numLiveOuts = dataInfo_->Read(); + if (numLiveOuts > 0) { + for (uint32_t j = 0; j < numLiveOuts; j++) { + auto liveOut = dataInfo_->Read(); + stkSizeRecord.LiveOuts.push_back(liveOut); + } + } + while (dataInfo_->GetOffset() & 7) { // 7: 8 byte align + padding = dataInfo_->Read(); + } + llvmStackMap_.StkMapRecord.push_back(stkSizeRecord); + } + CalcCallSite(); + return true; +} +} // namespace kungfu \ No newline at end of file diff --git a/ecmascript/compiler/llvm_stackmap_parse.h b/ecmascript/compiler/llvm_stackmap_parse.h new file mode 100644 index 0000000000000000000000000000000000000000..17204129db3881cacc565a950921b9b7ab5b632f --- /dev/null +++ b/ecmascript/compiler/llvm_stackmap_parse.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_COMPILER_LLVM_LLVMSTACKPARSE_H +#define ECMASCRIPT_COMPILER_LLVM_LLVMSTACKPARSE_H +#include +#include +#include + +namespace kungfu { +using OffsetType = int32_t; +using DwarfRegType = uint16_t; +using DwarfRegAndOffsetType = std::pair; +using Fun2InfoType = std::pair; + +struct Header { + uint8_t stackmapversion; // Stack Map Version (current version is 3) + uint8_t Reserved0; // Reserved (expected to be 0) + uint16_t Reserved1; // Reserved (expected to be 0) + void Print() const + { + std::cout << "----- head ----" << std::endl; + std::cout << " version:" << stackmapversion << std::endl; + std::cout << "+++++ head ++++" << std::endl; + } +}; + +struct StkSizeRecordTy { + uint64_t functionAddress; + uint64_t stackSize; + uint64_t recordCount; + void Print() const + { + std::cout << " functionAddress:0x" << std::hex << functionAddress << std::endl; + std::cout << " stackSize:" << std::dec << stackSize << std::endl; + std::cout << " recordCount:" << std::dec << recordCount << std::endl; + } +}; + +struct ConstantsTy { + uint64_t LargeConstant; + void Print() const + { + std::cout << " LargeConstant:" << LargeConstant << std::endl; + } +}; + +struct StkMapRecordHeadTy { + uint64_t PatchPointID; + uint32_t InstructionOffset; + uint16_t Reserved; + uint16_t NumLocations; + void Print() const + { + std::cout << " PatchPointID:" << std::hex << PatchPointID << std::endl; + std::cout << " instructionOffset:" << std::hex << InstructionOffset << std::endl; + std::cout << " Reserved:" << Reserved << std::endl; + std::cout << " NumLocations:" << NumLocations << std::endl; + } +}; + +struct LocationTy { + enum class Kind: uint8_t { + REGISTER = 1, + DIRECT = 2, + INDIRECT = 3, + CONSTANT = 4, + CONSTANTNDEX = 5, + }; + Kind location; + uint8_t Reserved_0; + uint16_t LocationSize; + uint16_t DwarfRegNum; + uint16_t Reserved_1; + OffsetType OffsetOrSmallConstant; + + std::string TypeToString(Kind location) const; + + void Print() const + { + std::cout << TypeToString(location); + std::cout << ", size:" << std::dec << LocationSize; + std::cout << "\tDwarfRegNum:" << DwarfRegNum; + std::cout << "\t OffsetOrSmallConstant:" << OffsetOrSmallConstant << std::endl; + } +}; + +struct LiveOutsTy { + DwarfRegType DwarfRegNum; + uint8_t Reserved; + uint8_t SizeinBytes; + void Print() const + { + std::cout << " Dwarf RegNum:" << DwarfRegNum << std::endl; + std::cout << " Reserved:" << Reserved << std::endl; + std::cout << " SizeinBytes:" << SizeinBytes << std::endl; + } +}; + +struct StkMapRecordTy { + struct StkMapRecordHeadTy head; + std::vector Locations; + std::vector LiveOuts; + void Print() const + { + head.Print(); + auto size = Locations.size(); + for (size_t i = 0; i < size; i++) { + std::cout << " #" << std::dec << i << ":"; + Locations[i].Print(); + } + size = LiveOuts.size(); + for (size_t i = 0; i < size; i++) { + std::cout << " liveOuts[" << i << "] info:" << std::endl; + } + } +}; + +class DataInfo { +public: + explicit DataInfo(const uint8_t* data): data_(data), offset(0) {} + ~DataInfo() + { + data_ = nullptr; + offset = 0; + } + template + T Read() + { + T t = *reinterpret_cast(data_ + offset); + offset += sizeof(T); + return t; + } + unsigned int GetOffset() const + { + return offset; + } +private: + const uint8_t* data_; + unsigned int offset; +}; + +struct LLVMStackMap { + struct Header head; + std::vector StkSizeRecords; + std::vector Constants; + std::vector StkMapRecord; + void Print() const + { + head.Print(); + for (size_t i = 0; i < StkSizeRecords.size(); i++) { + std::cout << "stkSizeRecord[" << i << "] info:" << std::endl; + StkSizeRecords[i].Print(); + } + for (size_t i = 0; i < Constants.size(); i++) { + std::cout << "constants[" << i << "] info:" << std::endl; + Constants[i].Print(); + } + for (size_t i = 0; i < StkMapRecord.size(); i++) { + std::cout << "StkMapRecord[" << i << "] info:" << std::endl; + StkMapRecord[i].Print(); + } + } +}; + +class LLVMStackMapParse { +public: + static LLVMStackMapParse& GetInstance() + { + static LLVMStackMapParse instance; + return instance; + } + bool CalculateStackMap(const uint8_t *stackMapAddr); + void Print() const + { + llvmStackMap_.Print(); + } + bool StackMapByAddr(uintptr_t funcAddr, DwarfRegAndOffsetType &info); +private: + LLVMStackMapParse() + { + stackMapAddr_ = nullptr; + callSiteInfos_.clear(); + dataInfo_ = nullptr; + } + ~LLVMStackMapParse() + { + stackMapAddr_ = nullptr; + callSiteInfos_.clear(); + dataInfo_ = nullptr; + } + void CalcCallSite(); + const uint8_t *stackMapAddr_; + struct LLVMStackMap llvmStackMap_; + std::vector callSiteInfos_; + std::unique_ptr dataInfo_; +}; +} // namespace kungfu +#endif // ECMASCRIPT_COMPILER_LLVM_LLVMSTACKPARSE_H \ No newline at end of file diff --git a/ecmascript/compiler/machine_type.h b/ecmascript/compiler/machine_type.h index 01b45da8bfa08ff93d840cbb9b1c6f58f1354d1e..3530cd14dd56c19fae70e3e1ef5147d28c7bd7da 100644 --- a/ecmascript/compiler/machine_type.h +++ b/ecmascript/compiler/machine_type.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_MACHINE_TYPE_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_MACHINE_TYPE_H +#ifndef ECMASCRIPT_COMPILER_MACHINE_TYPE_H +#define ECMASCRIPT_COMPILER_MACHINE_TYPE_H namespace kungfu { enum MachineType { @@ -35,4 +35,4 @@ enum MachineType { FLOAT64_TYPE, }; } // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_MACHINE_TYPE_H \ No newline at end of file +#endif // ECMASCRIPT_COMPILER_MACHINE_TYPE_H \ No newline at end of file diff --git a/ecmascript/compiler/scheduler.cpp b/ecmascript/compiler/scheduler.cpp index bc678364c829e44a1ba9576356d3e07bf5ef28fb..a89fbc574b09a9365be1a824f6a4d946e5529ca3 100644 --- a/ecmascript/compiler/scheduler.cpp +++ b/ecmascript/compiler/scheduler.cpp @@ -15,6 +15,8 @@ #include "ecmascript/compiler/scheduler.h" +#include + #include "ecmascript/compiler/verifier.h" namespace kungfu { @@ -119,7 +121,7 @@ std::vector> Scheduler::Run(const Circuit *circuit) for (size_t idx = 1; idx < immDom.size(); idx++) { sonList[immDom[idx]].push_back(idx); } - const size_t sizeLog = ceil(log2(static_cast(result.size())) + 1); + const size_t sizeLog = std::ceil(std::log2(static_cast(result.size())) + 1); std::vector timeIn(result.size()); std::vector timeOut(result.size()); std::vector> jumpUp; diff --git a/ecmascript/compiler/scheduler.h b/ecmascript/compiler/scheduler.h index cf5e2d4bb2b7ee970b55880a853c819f13231d00..edfa7be124fa35e539534324cd50d73a57ed9d01 100644 --- a/ecmascript/compiler/scheduler.h +++ b/ecmascript/compiler/scheduler.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_SCHEDULER_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_SCHEDULER_H +#ifndef ECMASCRIPT_COMPILER_SCHEDULER_H +#define ECMASCRIPT_COMPILER_SCHEDULER_H #include #include @@ -40,4 +40,4 @@ public: }; }; // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_SCHEDULER_H +#endif // ECMASCRIPT_COMPILER_SCHEDULER_H diff --git a/ecmascript/compiler/stub_interface.cpp b/ecmascript/compiler/stub_interface.cpp index 8fe7e2594c9538718e0e18613247dfa4f836b5d4..66908736a106b284558f0f0e87c8a3e8df598a7e 100644 --- a/ecmascript/compiler/stub_interface.cpp +++ b/ecmascript/compiler/stub_interface.cpp @@ -28,6 +28,14 @@ namespace kungfu { }; \ LLVMValueRef LLVM##name##Stub::InitializeFunction(LLVMModuleRef module) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define LLVM_STUB_GETFUCTION_TYPE(name) \ + class LLVM##name##Stub##Type final { \ + public: \ + static LLVMTypeRef InitializeFunctionType(); \ + }; \ + LLVMTypeRef LLVM##name##Stub##Type::InitializeFunctionType() + LLVM_STUB_GETFUCTION(FastAdd) { (void)module; @@ -191,68 +199,204 @@ LLVM_STUB_GETFUCTION(FindOwnProperty2) } LLVM_STUB_GETFUCTION(FindOwnElement2) +{ + // 6 : 6 input parameters + std::array paramTys = { + LLVMInt64Type(), LLVMInt64Type(), LLVMInt32Type(), LLVMInt1Type(), LLVMInt64Type(), LLVMInt64Type(), + }; + // 6 : 6 input parameters + return LLVMAddFunction(module, "FindOwnElement2", LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 6, 0)); +} + +LLVM_STUB_GETFUCTION_TYPE(FastAdd) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FastSub) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FastMul) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FastDiv) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FastMod) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FastEqual) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FastTypeOf) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FastStrictEqual) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(IsSpecialIndexedObjForSet) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(IsSpecialIndexedObjForGet) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(GetElement) +{ + // 2 : 2 input parameters + std::array paramTys = { + LLVMInt64Type(), + LLVMInt32Type(), + }; + return LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 2, 0); // 2 : 2 parameters number +} + +LLVM_STUB_GETFUCTION_TYPE(SetElement) { // 5 : 5 input parameters + std::array paramTys = { + LLVMInt64Type(), LLVMInt64Type(), LLVMInt32Type(), LLVMInt64Type(), LLVMInt32Type(), + }; + return LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 5, 0); // 5 : 5 parameters number +} + +LLVM_STUB_GETFUCTION_TYPE(SetPropertyByName) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(GetPropertyByName) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(SetGlobalOwnProperty) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(GetGlobalOwnProperty) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(SetOwnPropertyByName) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(SetOwnElement) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FastSetProperty) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FastGetProperty) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FindOwnProperty) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FindOwnElement) +{ + // 2 : 2 parameters number + std::array paramTys = { + LLVMInt64Type(), + LLVMInt32Type(), + }; + return LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 2, 0); // 2 : 2 parameters number +} + +LLVM_STUB_GETFUCTION_TYPE(NewLexicalEnvDyn) +{ + return nullptr; +} + +LLVM_STUB_GETFUCTION_TYPE(FindOwnProperty2) +{ + // 5 : 5 parameters number std::array paramTys = { LLVMInt64Type(), LLVMInt32Type(), LLVMInt1Type(), LLVMInt64Type(), LLVMInt64Type(), }; - // 5 : 5 input parameters - return LLVMAddFunction(module, "FindOwnElement2", LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 5, 0)); + return LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 5, 0); // 5 : 5 parameters number } -LLVM_STUB_GETFUCTION(AddElementInternal) +LLVM_STUB_GETFUCTION_TYPE(FindOwnElement2) { - // 5 : 5 input parameters + // 5 : 5 parameters number + std::array paramTys = { + LLVMInt64Type(), LLVMInt32Type(), LLVMInt1Type(), LLVMInt64Type(), LLVMInt64Type(), + }; + return LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 5, 0); // 5 : 5 parameters number +} + +LLVM_STUB_GETFUCTION_TYPE(AddElementInternal) +{ + // 5 : 5 parameters number std::array paramTys = { LLVMInt64Type(), LLVMInt64Type(), LLVMInt32Type(), LLVMInt64Type(), LLVMInt32Type(), }; - return LLVMAddFunction(module, "_ZN5panda10ecmascript11RuntimeStub18AddElementInternalEmmjmj", - LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 5, 0)); // 5 : 5 input parameters + return LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 5, 0); // 5 : 5 parameters number } -LLVM_STUB_GETFUCTION(CallSetter) +LLVM_STUB_GETFUCTION_TYPE(CallSetter) { - // 5 : 5 input parameters + // 5 : 5 parameters number std::array paramTys = { LLVMInt64Type(), LLVMInt64Type(), LLVMInt64Type(), LLVMInt64Type(), LLVMInt1Type(), }; - return LLVMAddFunction(module, "_ZN5panda10ecmascript11RuntimeStub10CallSetterEmmmmb", - LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 5, 0)); // 5 : 5 input parameters + return LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 5, 0); // 5 : 5 parameters number } -LLVM_STUB_GETFUCTION(ThrowTypeError) +LLVM_STUB_GETFUCTION_TYPE(ThrowTypeError) { - // 2 : 2 input parameter + // 2 : 2 parameters number std::array paramTys = { LLVMInt64Type(), LLVMInt32Type(), }; - return LLVMAddFunction(module, " _ZN5panda10ecmascript11RuntimeStub14ThrowTypeErrorEmi", - LLVMFunctionType(LLVMVoidType(), paramTys.data(), 2, 0)); // 2 : 2 input parameters + return LLVMFunctionType(LLVMVoidType(), paramTys.data(), 2, 0); // 2 : 2 parameters number } -LLVM_STUB_GETFUCTION(JSProxySetProperty) +LLVM_STUB_GETFUCTION_TYPE(JSProxySetProperty) { - // 6 : 6 input parameters + // 6 : 6 parameters number std::array paramTys = { LLVMInt64Type(), LLVMInt64Type(), LLVMInt64Type(), LLVMInt64Type(), LLVMInt64Type(), LLVMInt1Type(), }; - return LLVMAddFunction(module, "_ZN5panda10ecmascript11RuntimeStub18JSProxySetPropertyEmmmmmb", - LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 6, 0)); // 6 : 6 input parameters + return LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 6, 0); // 6 : 6 parameters number } -LLVM_STUB_GETFUCTION(GetHash32) +LLVM_STUB_GETFUCTION_TYPE(GetHash32) { - std::array paramTys = { // 2 : 2 input parameters - LLVMInt64Type(), LLVMInt32Type()}; - return LLVMAddFunction(module, "_ZN5panda9GetHash32EPKhm", - LLVMFunctionType(LLVMInt32Type(), paramTys.data(), 2, 0)); // 2 : 2 input parameters -} - -LLVM_STUB_GETFUCTION(PhiTest) -{ - std::array paramTys = {LLVMInt32Type()}; - return LLVMAddFunction(module, "PhiTest", LLVMFunctionType(LLVMInt32Type(), paramTys.data(), 1, 0)); + // 2 : 2 parameters number + std::array paramTys = {LLVMInt64Type(), LLVMInt32Type()}; + return LLVMFunctionType(LLVMInt32Type(), paramTys.data(), 2, 0); // 2 : 2 parameters number } LLVMStubsImplement::LLVMStubsImplement() @@ -269,6 +413,16 @@ void LLVMStubsImplement::Initialize() // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define INITIALIZE_CALL_STUB(name, argcounts) \ llvmCallStubs_[DEF_CALL_STUB(name)] = LLVM##name##Stub::InitializeFunction(stubsModule_); + FAST_RUNTIME_STUB_LIST(INITIALIZE_CALL_STUB) +#undef INITIALIZE_CALL_STUB +#undef DEF_CALL_STUB + +// Intialize Stubs Function +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define DEF_CALL_STUB(name) NAME_##name +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define INITIALIZE_CALL_STUB(name, argcounts) \ + llvm_fuction_type_[DEF_CALL_STUB(name)] = LLVM##name##Stub##Type::InitializeFunctionType(); CALL_STUB_LIST(INITIALIZE_CALL_STUB) #undef INITIALIZE_CALL_STUB #undef DEF_CALL_STUB @@ -286,6 +440,12 @@ void LLVMStubsImplement::SetFastStub(int index, void *code) llvmCallStubs_[index] = reinterpret_cast(code); } +void *LLVMStubsImplement::GetRunTimeLLVMType(int index) +{ + ASSERT(index < CALL_STUB_MAXCOUNT && index >= 0); + return reinterpret_cast(llvm_fuction_type_[index]); +} + // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define CALL_STUB_INIT_DESCRIPTOR(name) \ class Stub##name##InterfaceDescriptor final { \ @@ -347,13 +507,14 @@ CALL_STUB_INIT_DESCRIPTOR(FindOwnElement2) // 5 : 5 input parameters static StubInterfaceDescriptor findOwnElement2(0, 5, DEFAULT_ORDER, UINT64_TYPE); *descriptor = findOwnElement2; - auto params = new std::array(); // 5 : 5 input parameters - (*params)[0] = MachineType::UINT64_TYPE; - (*params)[1] = MachineType::UINT32_TYPE; - (*params)[2] = MachineType::BOOL_TYPE; // 2 : 3rd para - (*params)[3] = MachineType::UINT64_TYPE; // 3 : 4th para - (*params)[4] = MachineType::UINT64_TYPE; // 4 : 5th para - descriptor->SetParameters(params->data()); + std::array params = { // 5 : 5 input parameters + MachineType::UINT64_TYPE, + MachineType::UINT32_TYPE, + MachineType::BOOL_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); } CALL_STUB_INIT_DESCRIPTOR(AddElementInternal) @@ -361,13 +522,15 @@ CALL_STUB_INIT_DESCRIPTOR(AddElementInternal) // 5 : 5 input parameters static StubInterfaceDescriptor addElementInternal(0, 5, DEFAULT_ORDER, BOOL_TYPE); *descriptor = addElementInternal; - auto params = new std::array(); // 5 : 5 input parameters - (*params)[0] = MachineType::UINT64_TYPE; - (*params)[1] = MachineType::UINT64_TYPE; - (*params)[2] = MachineType::UINT32_TYPE; // 2 : 3rd para - (*params)[3] = MachineType::UINT64_TYPE; // 3 : 4th para - (*params)[4] = MachineType::UINT32_TYPE; // 4 : 5th para - descriptor->SetParameters(params->data()); + std::array params = { // 5 : 5 input parameters + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT32_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT32_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubInterfaceDescriptor::RUNTIME_STUB); } CALL_STUB_INIT_DESCRIPTOR(CallSetter) @@ -375,13 +538,15 @@ CALL_STUB_INIT_DESCRIPTOR(CallSetter) // 5 : 5 input parameters static StubInterfaceDescriptor callSetter(0, 5, DEFAULT_ORDER, NONE_TYPE); *descriptor = callSetter; - auto params = new std::array(); // 5 : 5 input parameters - (*params)[0] = MachineType::UINT64_TYPE; - (*params)[1] = MachineType::UINT64_TYPE; - (*params)[2] = MachineType::UINT64_TYPE; // 2 : 3rd para - (*params)[3] = MachineType::UINT64_TYPE; // 3 : 4th para - (*params)[4] = MachineType::BOOL_TYPE; // 4 : 5th para - descriptor->SetParameters(params->data()); + std::array params = { // 5 : 5 input parameters + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::BOOL_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubInterfaceDescriptor::RUNTIME_STUB); } CALL_STUB_INIT_DESCRIPTOR(ThrowTypeError) @@ -389,10 +554,12 @@ CALL_STUB_INIT_DESCRIPTOR(ThrowTypeError) // 2 : 2 input parameters static StubInterfaceDescriptor throwTypeError(0, 2, DEFAULT_ORDER, NONE_TYPE); *descriptor = throwTypeError; - auto params = new std::array(); // 2 : 2 input parameters - (*params)[0] = MachineType::UINT64_TYPE; - (*params)[1] = MachineType::UINT32_TYPE; - descriptor->SetParameters(params->data()); + std::array params = { // 2 : 2 input parameters + MachineType::UINT64_TYPE, + MachineType::UINT32_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubInterfaceDescriptor::RUNTIME_STUB); } CALL_STUB_INIT_DESCRIPTOR(JSProxySetProperty) @@ -400,14 +567,16 @@ CALL_STUB_INIT_DESCRIPTOR(JSProxySetProperty) // 6 : 6 input parameters static StubInterfaceDescriptor jsproxySetproperty(0, 6, DEFAULT_ORDER, BOOL_TYPE); *descriptor = jsproxySetproperty; - auto params = new std::array(); // 6 : 6 input parameters - (*params)[0] = MachineType::UINT64_TYPE; - (*params)[1] = MachineType::UINT64_TYPE; - (*params)[2] = MachineType::UINT64_TYPE; // 2 : 3rd para - (*params)[3] = MachineType::UINT64_TYPE; // 3 : 4th para - (*params)[4] = MachineType::UINT64_TYPE; // 4 : 5th para - (*params)[5] = MachineType::BOOL_TYPE; // 5 : 6th para - descriptor->SetParameters(params->data()); + std::array params = { // 6 : 6 input parameters + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::BOOL_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubInterfaceDescriptor::RUNTIME_STUB); } CALL_STUB_INIT_DESCRIPTOR(GetHash32) @@ -415,18 +584,18 @@ CALL_STUB_INIT_DESCRIPTOR(GetHash32) // 2 : 2 input parameters static StubInterfaceDescriptor getHash32(0, 2, DEFAULT_ORDER, UINT32_TYPE); *descriptor = getHash32; - auto params = new std::array(); // 2 : 2 input parameters - (*params)[0] = MachineType::POINTER_TYPE; - (*params)[1] = MachineType::UINT32_TYPE; - descriptor->SetParameters(params->data()); + std::array params = { // 2 : 2 input parameters + MachineType::POINTER_TYPE, + MachineType::UINT32_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubInterfaceDescriptor::RUNTIME_STUB); } -CALL_STUB_INIT_DESCRIPTOR(PhiTest) {} - void FastStubs::InitializeStubDescriptors() { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DEF_CALL_STUB(name) CallStubsImplement::NAME_##name +#define DEF_CALL_STUB(name) NAME_##name // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define INITIALIZE_CALL_STUB_DESCRIPTOR(name, argcounts) \ Stub##name##InterfaceDescriptor::Initialize(&callStubsDescriptor_[DEF_CALL_STUB(name)]); diff --git a/ecmascript/compiler/stub_interface.h b/ecmascript/compiler/stub_interface.h index 35910a59dca9e9766a252ba393161a93a81f7549..758fb6f1faa9f6c1473d9965c35556e20fe86350 100644 --- a/ecmascript/compiler/stub_interface.h +++ b/ecmascript/compiler/stub_interface.h @@ -12,13 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_STUB_INTERFACE_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_STUB_INTERFACE_H +#ifndef ECMASCRIPT_COMPILER_STUB_INTERFACE_H +#define ECMASCRIPT_COMPILER_STUB_INTERFACE_H + +#include +#include #include "ecmascript/compiler/fast_stub_define.h" #include "ecmascript/compiler/machine_type.h" -#include "ecmascript/js_handle.h" -#include "ecmascript/mem/code.h" +#include "libpandabase/macros.h" #include "llvm-c/Types.h" namespace kungfu { @@ -28,32 +30,64 @@ enum ArgumentsOrder { class StubInterfaceDescriptor { public: + enum CallStubKind { + CODE_STUB, + RUNTIME_STUB, + }; explicit StubInterfaceDescriptor(int flags, int paramCounter, ArgumentsOrder order, MachineType returnType) : flags_(flags), paramCounter_(paramCounter), order_(order), returnType_(returnType) { } - explicit StubInterfaceDescriptor(int flags, int paramCounter, ArgumentsOrder order, MachineType returnType, - MachineType *paramsType) - : flags_(flags), paramCounter_(paramCounter), order_(order), returnType_(returnType) - { - paramsType_ = paramsType; - } StubInterfaceDescriptor() = default; - ~StubInterfaceDescriptor() + ~StubInterfaceDescriptor() = default; + StubInterfaceDescriptor(StubInterfaceDescriptor const &other) + { + flags_ = other.flags_; + paramCounter_ = other.paramCounter_; + order_ = other.order_; + kind_ = other.kind_; + returnType_ = other.returnType_; + if (paramCounter_ > 0 && other.paramsType_ != nullptr) { + paramsType_ = std::make_unique>(paramCounter_); + for (int i = 0; i < paramCounter_; i++) { + (*paramsType_)[i] = other.GetParametersType()[i]; + } + } + } + + StubInterfaceDescriptor &operator=(StubInterfaceDescriptor const &other) { - if (paramsType_ != nullptr) { - delete paramsType_; + flags_ = other.flags_; + paramCounter_ = other.paramCounter_; + order_ = other.order_; + kind_ = other.kind_; + returnType_ = other.returnType_; + if (paramCounter_ > 0 && other.paramsType_ != nullptr) { + paramsType_ = std::make_unique>(paramCounter_); + for (int i = 0; i < paramCounter_; i++) { + (*paramsType_)[i] = other.GetParametersType()[i]; + } } + return *this; } void SetParameters(MachineType *paramsType) { - paramsType_ = paramsType; + if (paramCounter_ > 0 && paramsType_ == nullptr) { + paramsType_ = std::make_unique>(paramCounter_); + for (int i = 0; i < paramCounter_; i++) { + (*paramsType_)[i] = paramsType[i]; + } + } } MachineType *GetParametersType() const { - return paramsType_; + if (paramsType_ != nullptr) { + return paramsType_->data(); + } else { + return nullptr; + } } int GetParametersCount() const @@ -76,39 +110,24 @@ public: return flags_; } -private: - int flags_{0}; - int paramCounter_{0}; - ArgumentsOrder order_{DEFAULT_ORDER}; - - MachineType returnType_{MachineType::NONE_TYPE}; - MachineType *paramsType_{nullptr}; -}; - -class StubInterface final { -public: - explicit StubInterface(panda::ecmascript::JSHandle code, - StubInterfaceDescriptor *descriptor) - : code_(code), descriptor_(descriptor) - { - } - virtual ~StubInterface() = default; - DEFAULT_COPY_SEMANTIC(StubInterface); - DEFAULT_MOVE_SEMANTIC(StubInterface); - - panda::ecmascript::JSHandle GetCode() const + CallStubKind GetStubKind() const { - return code_; + return kind_; } - StubInterfaceDescriptor *GetDescriptor() const + void SetStubKind(CallStubKind kind) { - return descriptor_; + kind_ = kind; } private: - panda::ecmascript::JSHandle code_; - StubInterfaceDescriptor *descriptor_; + CallStubKind kind_{CODE_STUB}; + int flags_{0}; + int paramCounter_{0}; + ArgumentsOrder order_{DEFAULT_ORDER}; + + MachineType returnType_{MachineType::NONE_TYPE}; + std::unique_ptr> paramsType_{nullptr}; }; class CallStubsImplement { @@ -117,17 +136,10 @@ public: virtual ~CallStubsImplement() = default; NO_MOVE_SEMANTIC(CallStubsImplement); NO_COPY_SEMANTIC(CallStubsImplement); - enum CallStubName { -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DEF_FAST_STUB(name, counter) NAME_##name, - CALL_STUB_LIST(DEF_FAST_STUB) -#undef DEF_FAST_STUB - CALL_STUB_MAXCOUNT, - }; - virtual void Initialize() = 0; virtual void *GetFastStub(int index) = 0; virtual void SetFastStub(int index, void *code) = 0; + virtual void *GetRunTimeLLVMType(int index) = 0; virtual void *GetModule() = 0; }; @@ -140,6 +152,8 @@ public: void Initialize() override; void *GetFastStub(int index) override; void SetFastStub(int index, void *code) override; + + void *GetRunTimeLLVMType(int index) override; void *GetModule() override { return reinterpret_cast(stubsModule_); @@ -147,10 +161,11 @@ public: private: std::array llvmCallStubs_{nullptr}; + std::array llvm_fuction_type_{nullptr}; LLVMModuleRef stubsModule_{nullptr}; }; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define FAST_STUB_ID(name) CallStubsImplement::NAME_##name +#define FAST_STUB_ID(name) NAME_##name // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define GET_STUBDESCRIPTOR(name) FastStubs::GetInstance().GetStubDescriptor(FAST_STUB_ID(name)) @@ -170,6 +185,11 @@ public: stubsImpl_->Initialize(); } + void *GetRunTimeLLVMType(int index) + { + return stubsImpl_->GetRunTimeLLVMType(index); + } + void *GetFastStub(int index) const { return stubsImpl_->GetFastStub(index); @@ -200,7 +220,7 @@ private: NO_MOVE_SEMANTIC(FastStubs); NO_COPY_SEMANTIC(FastStubs); std::unique_ptr stubsImpl_{nullptr}; - std::array callStubsDescriptor_{}; + std::array callStubsDescriptor_{}; }; } // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_STUB_INTERFACE_H \ No newline at end of file +#endif // ECMASCRIPT_COMPILER_STUB_INTERFACE_H \ No newline at end of file diff --git a/ecmascript/compiler/stub_optimizer.cpp b/ecmascript/compiler/stub_optimizer.cpp index 8033befdf94b8822747ba8ceb962c1a78cd6fedc..25e344e793695be399d82c8ccfeb843461163276 100644 --- a/ecmascript/compiler/stub_optimizer.cpp +++ b/ecmascript/compiler/stub_optimizer.cpp @@ -349,12 +349,14 @@ AddrShift StubOptimizer::LoadFromObject(MachineType type, AddrShift object, Addr return Load(type, ChangeInt64ToPointer(elements), dataOffset); } -AddrShift StubOptimizer::FindElementFromNumberDictionary(AddrShift elements, AddrShift key, Label *next) +AddrShift StubOptimizer::FindElementFromNumberDictionary(AddrShift thread, AddrShift elements, AddrShift key, + Label *next) { auto env = GetEnvironment(); DEFVARIABLE(result, INT32_TYPE, GetInteger32Constant(-1)); - AddrShift capcityoffset = PtrMul(GetPtrConstant(panda::ecmascript::JSTaggedValue::TaggedTypeSize()), - GetPtrConstant(panda::ecmascript::TaggedHashTable::SIZE_INDEX)); + AddrShift capcityoffset = + PtrMul(GetPtrConstant(panda::ecmascript::JSTaggedValue::TaggedTypeSize()), + GetPtrConstant(panda::ecmascript::TaggedHashTable::SIZE_INDEX)); AddrShift dataoffset = GetPtrConstant(panda::coretypes::Array::GetDataOffset()); AddrShift capacity = TaggedCastToInt32(Load(TAGGED_TYPE, elements, PtrAdd(dataoffset, capcityoffset))); DEFVARIABLE(count, INT32_TYPE, GetInteger32Constant(1)); @@ -363,7 +365,8 @@ AddrShift StubOptimizer::FindElementFromNumberDictionary(AddrShift elements, Add AddrShift keyStore = Store(INT32_TYPE, pKey, GetPtrConstant(0), TaggedCastToInt32(key)); StubInterfaceDescriptor *getHash32Descriptor = GET_STUBDESCRIPTOR(GetHash32); AddrShift len = GetInteger32Constant(sizeof(int) / sizeof(uint8_t)); - AddrShift hash = CallStub(getHash32Descriptor, GetWord64Constant(FAST_STUB_ID(GetHash32)), keyStore, {pKey, len}); + AddrShift hash = + CallRuntime(getHash32Descriptor, thread, GetWord64Constant(FAST_STUB_ID(GetHash32)), keyStore, {pKey, len}); DEFVARIABLE(entry, INT32_TYPE, Word32And(hash, Int32Sub(capacity, GetInteger32Constant(1)))); Label loopHead(env); Label loopEnd(env); @@ -445,9 +448,9 @@ AddrShift StubOptimizer::GetKeyFromNumberDictionary(AddrShift elements, AddrShif Label gtLength(env); Label notGtLength(env); AddrShift dictionaryLength = Load(INT32_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetLengthOffset())); - AddrShift arrayIndex = Int32Add( - GetInteger32Constant(panda::ecmascript::NumberDictionary::TABLE_HEADER_SIZE), - Int32Mul(entry, GetInteger32Constant(panda::ecmascript::NumberDictionary::ENTRY_SIZE))); + AddrShift arrayIndex = + Int32Add(GetInteger32Constant(panda::ecmascript::NumberDictionary::TABLE_HEADER_SIZE), + Int32Mul(entry, GetInteger32Constant(panda::ecmascript::NumberDictionary::ENTRY_SIZE))); Branch(Int32LessThan(arrayIndex, GetInteger32Constant(0)), <Zero, ¬LtZero); Bind(<Zero); Jump(next); @@ -569,7 +572,7 @@ AddrShift StubOptimizer::UpdateRepresention(AddrShift oldRep, AddrShift value, L Label isObjectNewRep(env); Label notObjectNewRep(env); Branch(Word64NotEqual(newRep, GetWord64Constant( - static_cast(panda::ecmascript::Representation::OBJECT))), + static_cast(panda::ecmascript::Representation::OBJECT))), ¬ObjectNewRep, &isObjectNewRep); Bind(¬ObjectNewRep); { @@ -596,11 +599,9 @@ AddrShift StubOptimizer::UpdateRepresention(AddrShift oldRep, AddrShift value, L return *resultRep; } -void StubOptimizer::UpdateRepresention(AddrShift hclass, AddrShift value) +void StubOptimizer::UpdateAndStoreRepresention(AddrShift hclass, AddrShift value, Label *next) { - auto env = GetEnvironment(); - Label updateRepLabel(env); - AddrShift newRep = UpdateRepresention(GetElementRepresentation(hclass), value, &updateRepLabel); + AddrShift newRep = UpdateRepresention(GetElementRepresentation(hclass), value, next); SetElementRepresentation(hclass, newRep); } } // namespace kungfu \ No newline at end of file diff --git a/ecmascript/compiler/stub_optimizer.h b/ecmascript/compiler/stub_optimizer.h index 2b1a48aced0f64218b7c41da81af6054e6e4835a..cedc09c784a7c3843610fcee56d315260158b4a4 100644 --- a/ecmascript/compiler/stub_optimizer.h +++ b/ecmascript/compiler/stub_optimizer.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_STUBOPTIMIZER_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_STUBOPTIMIZER_H +#ifndef ECMASCRIPT_COMPILER_STUBOPTIMIZER_H +#define ECMASCRIPT_COMPILER_STUBOPTIMIZER_H #include "ecmascript/accessor_data.h" #include "ecmascript/compiler/circuit.h" @@ -478,11 +478,23 @@ public: return env_->GetCircuitBuilder().NewCallGate(descriptor, target, args); } AddrShift CallStub(StubInterfaceDescriptor *descriptor, AddrShift target, AddrShift depend, - std::initializer_list args) + std::initializer_list args) { return env_->GetCircuitBuilder().NewCallGate(descriptor, target, depend, args); } + AddrShift CallRuntime(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, + std::initializer_list args) + { + return env_->GetCircuitBuilder().NewCallRuntimeGate(descriptor, thread, target, args); + } + + AddrShift CallRuntime(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, AddrShift depend, + std::initializer_list args) + { + return env_->GetCircuitBuilder().NewCallRuntimeGate(descriptor, thread, target, depend, args); + } + // memory AddrShift Load(MachineType type, AddrShift base, AddrShift offset) { @@ -605,7 +617,12 @@ public: { return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_AND), x, y); } - AddrShift Word64Xor(AddrShift x, AddrShift y); + + AddrShift Word64Xor(AddrShift x, AddrShift y) + { + return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_XOR), x, y); + } + AddrShift Word32Not(AddrShift x); AddrShift Word64Not(AddrShift x) { @@ -688,10 +705,10 @@ public: return TruncInt32ToInt1(WordLogicAnd( SExtInt1ToInt32( Word64Equal(Word64And(x, GetWord64Constant(~panda::ecmascript::JSTaggedValue::TAG_SPECIAL_MASK)), - GetWord64Constant(0))), + GetWord64Constant(0))), WordLogicOr(SExtInt1ToInt32(Word64NotEqual( - Word64And(x, GetWord64Constant(panda::ecmascript::JSTaggedValue::TAG_SPECIAL_MASK)), - GetWord64Constant(0))), + Word64And(x, GetWord64Constant(panda::ecmascript::JSTaggedValue::TAG_SPECIAL_MASK)), + GetWord64Constant(0))), SExtInt1ToInt32(TaggedIsHole(x))))); } @@ -706,11 +723,13 @@ public: AddrShift diff = DoubleEqual(x, x); return Word32NotEqual(SExtInt1ToInt32(diff), GetInteger32Constant(0)); } + AddrShift IntBuildTagged(AddrShift x) { AddrShift val = ZExtInt32ToInt64(x); return Word64Or(val, GetWord64Constant(panda::ecmascript::JSTaggedValue::TAG_INT)); } + AddrShift DoubleBuildTagged(AddrShift x) { AddrShift val = CastDoubleToInt64(x); @@ -742,6 +761,7 @@ public: { return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::FLOAT64_EQ), x, y); } + AddrShift Word64NotEqual(AddrShift x, AddrShift y) { return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_NE), x, y); @@ -871,7 +891,7 @@ public: // object operation AddrShift LoadHClass(AddrShift object) { - return ChangeInt32ToPointer(Load(UINT32_TYPE, object, GetPtrConstant(panda::ObjectHeader::GetClassOffset()))); + return ChangeInt32ToPointer(Load(UINT32_TYPE, object)); } AddrShift GetObjectType(AddrShift object) @@ -924,9 +944,10 @@ public: AddrShift IsAcesscor(AddrShift attr) { return Word32NotEqual( - Word32And(Word32LSR(attr, GetInteger32Constant( - panda::ecmascript::PropertyAttributes::IsAccessorField::START_BIT)), - GetInteger32Constant((1LLU << panda::ecmascript::PropertyAttributes::IsAccessorField::SIZE) - 1)), + Word32And( + Word32LSR(attr, + GetInteger32Constant(panda::ecmascript::PropertyAttributes::IsAccessorField::START_BIT)), + GetInteger32Constant((1LLU << panda::ecmascript::PropertyAttributes::IsAccessorField::SIZE) - 1)), GetInteger32Constant(0)); } @@ -973,42 +994,43 @@ public: Word64Or(Word64And(oldValue, GetWord64Constant(~panda::ecmascript::JSHClass::ElementRepresentationBits::Mask())), Word64LSR(value, GetWord64Constant( - panda::ecmascript::JSHClass::ElementRepresentationBits::START_BIT)))); + panda::ecmascript::JSHClass::ElementRepresentationBits::START_BIT)))); } void UpdateValueAndDetails(AddrShift elements, AddrShift index, AddrShift value, AddrShift attr) { - AddrShift arrayIndex = Int32Add(GetInteger32Constant(panda::ecmascript::NameDictionary::TABLE_HEADER_SIZE), - Int32Mul(index, GetInteger32Constant(panda::ecmascript::NameDictionary::ENTRY_SIZE))); - AddrShift valueIndex = Int32Add(arrayIndex, - GetInteger32Constant(panda::ecmascript::NameDictionary::ENTRY_VALUE_INDEX)); - AddrShift attributesIndex = Int32Add(arrayIndex, - GetInteger32Constant(panda::ecmascript::NameDictionary::ENTRY_DETAILS_INDEX)); + AddrShift arrayIndex = + Int32Add(GetInteger32Constant(panda::ecmascript::NameDictionary::TABLE_HEADER_SIZE), + Int32Mul(index, GetInteger32Constant(panda::ecmascript::NameDictionary::ENTRY_SIZE))); + AddrShift valueIndex = + Int32Add(arrayIndex, GetInteger32Constant(panda::ecmascript::NameDictionary::ENTRY_VALUE_INDEX)); + AddrShift attributesIndex = + Int32Add(arrayIndex, GetInteger32Constant(panda::ecmascript::NameDictionary::ENTRY_DETAILS_INDEX)); StoreElement(elements, valueIndex, value); StoreElement(elements, attributesIndex, IntBuildTagged(attr)); } - void UpdateRepresention(AddrShift hclass, AddrShift value); + void UpdateAndStoreRepresention(AddrShift hclass, AddrShift value, Label *next); AddrShift UpdateRepresention(AddrShift oldRep, AddrShift value, Label *next); AddrShift GetDetailsFromDictionary(AddrShift elements, AddrShift entry) { - AddrShift arrayIndex = Int32Add( - GetInteger32Constant(panda::ecmascript::NumberDictionary::TABLE_HEADER_SIZE), - Int32Mul(entry, GetInteger32Constant(panda::ecmascript::NumberDictionary::ENTRY_SIZE))); - AddrShift attributesIndex = Int32Add(arrayIndex, - GetInteger32Constant(panda::ecmascript::NameDictionary::ENTRY_DETAILS_INDEX)); + AddrShift arrayIndex = + Int32Add(GetInteger32Constant(panda::ecmascript::NumberDictionary::TABLE_HEADER_SIZE), + Int32Mul(entry, GetInteger32Constant(panda::ecmascript::NumberDictionary::ENTRY_SIZE))); + AddrShift attributesIndex = + Int32Add(arrayIndex, GetInteger32Constant(panda::ecmascript::NameDictionary::ENTRY_DETAILS_INDEX)); return GetValueFromTaggedArray(elements, attributesIndex); } AddrShift GetValueFromDictionary(AddrShift elements, AddrShift entry) { - AddrShift arrayIndex = Int32Add( - GetInteger32Constant(panda::ecmascript::NumberDictionary::TABLE_HEADER_SIZE), - Int32Mul(entry, GetInteger32Constant(panda::ecmascript::NumberDictionary::ENTRY_SIZE))); - AddrShift valueIndex = Int32Add(arrayIndex, - GetInteger32Constant(panda::ecmascript::NameDictionary::ENTRY_VALUE_INDEX)); + AddrShift arrayIndex = + Int32Add(GetInteger32Constant(panda::ecmascript::NumberDictionary::TABLE_HEADER_SIZE), + Int32Mul(entry, GetInteger32Constant(panda::ecmascript::NumberDictionary::ENTRY_SIZE))); + AddrShift valueIndex = + Int32Add(arrayIndex, GetInteger32Constant(panda::ecmascript::NameDictionary::ENTRY_VALUE_INDEX)); return GetValueFromTaggedArray(elements, valueIndex); } @@ -1016,7 +1038,7 @@ public: AddrShift IsMatchInNumberDictionary(AddrShift key, AddrShift other, Label *next); - AddrShift FindElementFromNumberDictionary(AddrShift elements, AddrShift key, Label *next); + AddrShift FindElementFromNumberDictionary(AddrShift thread, AddrShift elements, AddrShift key, Label *next); AddrShift TaggedCastToInt32(AddrShift x) { @@ -1027,7 +1049,7 @@ public: AddrShift TaggedCastToDouble(AddrShift x) { AddrShift val = Int64Sub(x, GetWord64Constant(panda::ecmascript::JSTaggedValue::DOUBLE_ENCODE_OFFSET)); - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_TO_FLOAT64), val); + return CastInt64ToFloat64(val); } AddrShift CastInt32ToFloat64(AddrShift x) @@ -1035,6 +1057,11 @@ public: return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_TO_FLOAT64), x); } + AddrShift CastInt64ToFloat64(AddrShift x) + { + return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_TO_FLOAT64), x); + } + AddrShift SExtInt32ToInt64(AddrShift x) { return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::SEXT_INT32_TO_INT64), x); @@ -1090,4 +1117,4 @@ private: uint32_t varibial_id_{0}; }; } // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_STUBOPTIMIZER_H +#endif // ECMASCRIPT_COMPILER_STUBOPTIMIZER_H diff --git a/ecmascript/compiler/tests/BUILD.gn b/ecmascript/compiler/tests/BUILD.gn index 2fa8e0a953f9f651f8f7fc28ec2f8f962fe41adc..4c5845aa3025328a6219ff332c785aca740ed35e 100644 --- a/ecmascript/compiler/tests/BUILD.gn +++ b/ecmascript/compiler/tests/BUILD.gn @@ -15,7 +15,7 @@ import("//ark/js_runtime/js_runtime_config.gni") import("//ark/js_runtime/test/test_helper.gni") import("//build/test.gni") -config("include_llvmC") { +config("include_llvm_config") { include_dirs = [ "//third_party/llvm-project/llvm/include/", "//third_party/llvm-project/build/include", @@ -33,15 +33,137 @@ host_unittest_action("StubOptimizerTest") { "stub_optimizer_tests.cpp", ] configs = [ - ":include_llvm", + ":include_llvm_config", "//ark/js_runtime:ecma_test_config", - "//ark/js_runtime:ark_jsruntime_config", + "//ark/js_runtime/ecmascript/compiler:ark_jsruntime_compiler_config", "//ark/js_runtime:ark_jsruntime_public_config", "$ark_root/runtime:arkruntime_public_config", ] + lib_dirs = [ "//third_party/llvm-project/build/lib" ] + + libs = [ + "stdc++", + "z", + "tinfo", + "LTO", + "LLVMTarget", + "LLVMObject", + "LLVMMC", + "LLVMSupport", + "LLVMCore", + "LLVMExecutionEngine", + "LLVMInterpreter", + "LLVMMCJIT", + "LLVMExegesis", + "LLVMRuntimeDyld", + "LLVMInstCombine", + "LLVMAnalysis", + "LLVMScalarOpts", + "LLVMBinaryFormat", + "LLVMDebugInfoDWARF", + "LLVMRemarks", + "LLVMTextAPI", + "LLVMScalarOpts", + "LLVMTransformUtils", + "LLVMBitReader", + "LLVMSystemZInfo", + "LLVMAsmPrinter", + "LLVMProfileData", + "LLVMBitstreamReader", + "LLVMSelectionDAG", + "LLVMGlobalISel", + "LLVMLTO", + "LLVMCFGuard", + "LLVMVectorize", + "LLVMDemangle", + "LLVMipo", + "LLVMInstrumentation", + "LLVMDebugInfoCodeView", + "LLVMAggressiveInstCombine", + "LLVMAsmParser", + "LLVMMipsAsmParser", + "LLVMMCParser", + "LLVMMIRParser", + "LLVMMSP430AsmParser", + "LLVMX86Info", + "LLVMAArch64Info", + "LLVMLanaiInfo", + "LLVMAMDGPUInfo", + "LLVMARMInfo", + "LLVMHexagonInfo", + "LLVMNVPTXInfo", + "LLVMRISCVInfo", + "LLVMSparcInfo", + "LLVMMipsInfo", + "LLVMWebAssemblyInfo", + "LLVMBPFInfo", + "LLVMMSP430Info", + "LLVMPowerPCInfo", + "LLVMXCoreInfo", + "LLVMARMDesc", + "LLVMAArch64Desc", + "LLVMSparcDesc", + "LLVMAMDGPUDesc", + "LLVMXCoreDesc", + "LLVMWebAssemblyDesc", + "LLVMNVPTXDesc", + "LLVMMSP430Desc", + "LLVMPowerPCDesc", + "LLVMMipsDesc", + "LLVMRISCVDesc", + "LLVMLanaiDesc", + "LLVMSystemZDesc", + "LLVMHexagonDesc", + "LLVMX86Desc", + "LLVMBPFDesc", + "LLVMSparcDisassembler", + "LLVMRISCVDisassembler", + "LLVMMipsDisassembler", + "LLVMXCoreDisassembler", + "LLVMPowerPCDisassembler", + "LLVMX86Disassembler", + "LLVMMSP430Disassembler", + "LLVMARMDisassembler", + "LLVMLanaiDisassembler", + "LLVMAArch64Disassembler", + "LLVMBPFDisassembler", + "LLVMSystemZDisassembler", + "LLVMMCDisassembler", + "LLVMWebAssemblyDisassembler", + "LLVMHexagonDisassembler", + "LLVMAMDGPUDisassembler", + "LLVMXCoreCodeGen", + "LLVMPowerPCCodeGen", + "LLVMNVPTXCodeGen", + "LLVMAArch64CodeGen", + "LLVMMSP430CodeGen", + "LLVMARMCodeGen", + "LLVMMipsCodeGen", + "LLVMSparcCodeGen", + "LLVMBPFCodeGen", + "LLVMHexagonCodeGen", + "LLVMAMDGPUCodeGen", + "LLVMRISCVCodeGen", + "LLVMWebAssemblyCodeGen", + "LLVMSystemZCodeGen", + "LLVMCodeGen", + "LLVMX86CodeGen", + "LLVMLanaiCodeGen", + "LLVMX86AsmParser", + "LLVMAMDGPUUtils", + "LLVMRISCVUtils", + "LLVMTransformUtils", + "LLVMAArch64Utils", + "LLVMARMUtils", + "LLVMX86Utils", + "LLVMIRReader", + ] + deps = [ "$ark_root/libpandabase:libarkbase", + "$ark_root/runtime:libarkruntime", + "//ark/js_runtime:libark_jsruntime_test", "//ark/js_runtime/ecmascript/compiler:libark_jsoptimizer(${host_toolchain})", sdk_libc_secshared_dep, ] diff --git a/ecmascript/compiler/tests/satepoint_GC_0.ll b/ecmascript/compiler/tests/satepoint_GC_0.ll new file mode 100644 index 0000000000000000000000000000000000000000..71ce1169944139c23d0c662d9a2214f0d49a4435 --- /dev/null +++ b/ecmascript/compiler/tests/satepoint_GC_0.ll @@ -0,0 +1,99 @@ +; Copyright (c) 2021 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. + +define i32 @main() #0 gc "statepoint-example" { +entry: + %tmp1 = call i8 addrspace(0)* @malloc(i64 8) + %tmp2 = call i8 addrspace(0)* @malloc(i64 8) + %tmp3 = call i8 addrspace(0)* @malloc(i64 8) + %tmp4 = call i8 addrspace(0)* @malloc(i64 8) + %tmp5 = call i8 addrspace(0)* @malloc(i64 8) + %tmp6 = call i8 addrspace(0)* @malloc(i64 8) + %tmp7 = call i8 addrspace(0)* @malloc(i64 8) + %tmp8 = call i8 addrspace(0)* @malloc(i64 8) + %tmp9 = call i8 addrspace(1)* @_Znam(i64 8) + + %value1 = bitcast i8 addrspace(0)* %tmp1 to i64 addrspace(0)* + %value2 = bitcast i8 addrspace(0)* %tmp2 to i64 addrspace(0)* + %value3 = bitcast i8 addrspace(0)* %tmp3 to i64 addrspace(0)* + %value4 = bitcast i8 addrspace(0)* %tmp4 to i64 addrspace(0)* + %value5 = bitcast i8 addrspace(0)* %tmp5 to i64 addrspace(0)* + %value6 = bitcast i8 addrspace(0)* %tmp6 to i64 addrspace(0)* + %value7 = bitcast i8 addrspace(0)* %tmp7 to i64 addrspace(0)* + %value8 = bitcast i8 addrspace(0)* %tmp8 to i64 addrspace(0)* + %value9 = bitcast i8 addrspace(1)* %tmp9 to i64 addrspace(1)* + + ;; 0x11223344 --> 287454020 + store i64 287454020, i64 addrspace(0)* %value1 + ;; 0x55667788 --> 1432778632‬ + store i64 1432778632, i64 addrspace(0)* %value2 + ;; 0x12345678 --> 305419896‬ + store i64 305419896, i64 addrspace(0)* %value3 + + ;; 0x11223344 --> 287454020 + store i64 287454020, i64 addrspace(0)* %value4 + ;; 0x55667788 --> 1432778632‬ + store i64 1432778632, i64 addrspace(0)* %value5 + ;; 0x12345678 --> 305419896‬ + store i64 305419896, i64 addrspace(0)* %value6 + ;; 0x11223344 --> 287454020 + store i64 287454020, i64 addrspace(0)* %value7 + + ;; 0x11223344 --> 287454020 + store i64 287454020, i64 addrspace(0)* %value8 + ;; 0x55667788 --> 1432778632‬ + store i64 1432778632, i64 addrspace(1)* %value9 + + call void @bar(i64 addrspace(0)* %value1, i64 addrspace(0)* %value2, i64 addrspace(0)* %value3, i64 addrspace(0)* %value4, i64 addrspace(0)* %value5, i64 addrspace(0)* %value6, i64 addrspace(0)* %value7, i64 addrspace(0)* %value8, i64 addrspace(1)* %value9) + + ret i32 0 +} + +define void @bar(i64 addrspace(0)* %value, i64 addrspace(0)* %value2, i64 addrspace(0)* %value3, i64 addrspace(0)* %value4, i64 addrspace(0)* %value5, i64 addrspace(0)* %value6, i64 addrspace(0)* %value7, i64 addrspace(0)* %value8, i64 addrspace(1)* %value9) #0 gc "coreclr" { +entry: + %ret = call i64 @test3(i64 addrspace(0)* %value, i64 addrspace(0)* %value2, i64 addrspace(0)* %value3, i64 addrspace(0)* %value4, i64 addrspace(0)* %value5, i64 addrspace(0)* %value6, i64 addrspace(0)* %value7, i64 addrspace(0)* %value8, i64 addrspace(1)* %value9) + ret void +} + +define i64 @test3(i64 addrspace(0)* %obj1, i64 addrspace(0)* %obj2, i64 addrspace(0)* %obj3, i64 addrspace(0)* %obj4, i64 addrspace(0)* %obj5, i64 addrspace(0)* %obj6, i64 addrspace(0)* %obj7, i64 addrspace(0)* %obj8, i64 addrspace(1)* %obj9) #0 gc "coreclr" { +entry: + ;call void @DoSafepoint() [ "deopt"() ] + call void @DoSafepoint() + %obj_1 = load i64, i64 addrspace(0)* %obj1 + %obj_2 = load i64, i64 addrspace(0)* %obj2 + %obj_3 = load i64, i64 addrspace(0)* %obj3 + %obj_4 = load i64, i64 addrspace(0)* %obj4 + %obj_5 = load i64, i64 addrspace(0)* %obj5 + %obj_6 = load i64, i64 addrspace(0)* %obj6 + %obj_7 = load i64, i64 addrspace(0)* %obj7 + %obj_8 = load i64, i64 addrspace(0)* %obj8 + %obj_9 = load i64, i64 addrspace(1)* %obj9 + %result_1 = add i64 %obj_1, %obj_2 + %result_2 = add i64 %result_1, %obj_3 + %result_3 = add i64 %result_2, %obj_4 + %result_4 = add i64 %result_3, %obj_5 + %result_5 = add i64 %result_4, %obj_6 + %result_6 = add i64 %result_5, %obj_7 + %result_7 = add i64 %result_5, %obj_8 + %result_8 = add i64 %result_5, %obj_9 + ret i64 %result_8 +} + +declare void @DoSafepoint() +declare noalias i8 addrspace(1)* @_Znam(i64) +declare noalias i8* @malloc(i64) + +attributes #0 = { "frame-pointer"="all"} + + + diff --git a/ecmascript/compiler/tests/stub_optimizer_tests.cpp b/ecmascript/compiler/tests/stub_optimizer_tests.cpp index 18d6db4cd51a03ee5a78c820169e1eb24311b7cf..165e90c9a1b77a86d70770f786f1da9590f776e5 100644 --- a/ecmascript/compiler/tests/stub_optimizer_tests.cpp +++ b/ecmascript/compiler/tests/stub_optimizer_tests.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include #include #include @@ -48,9 +49,9 @@ public: TestHelper::DestroyEcmaVMWithScope(instance, scope); } - PandaVM *instance {nullptr}; - EcmaHandleScope *scope {nullptr}; - JSThread *thread {nullptr}; + PandaVM *instance{nullptr}; + EcmaHandleScope *scope{nullptr}; + JSThread *thread{nullptr}; }; HWTEST_F_L0(StubOptimizerTest, FastLoadElement) @@ -66,7 +67,7 @@ HWTEST_F_L0(StubOptimizerTest, FastLoadElement) // 2 : parameter number LLVMAddFunction(module, "FastLoadElement", LLVMFunctionType(LLVMInt64Type(), paramTys, 2, 0)); LLVMDumpModule(module); - Environment fastEnv("FastLoadElement", 2); // 2 : parameter count + Environment fastEnv("FastLoadElement", 2); // 2 : parameter count FastArrayLoadElementOptimizer optimizer(&fastEnv); optimizer.GenerateCircuit(); auto netOfGates = fastEnv.GetCircuit(); @@ -118,12 +119,12 @@ public: StubOptimizerLabel ifFalse(env); StubOptimizerLabel next(env); - Branch(Word32Equal(*x, GetInteger32Constant(10)), &ifTrue, &ifFalse); // 10 : size of entry + Branch(Word32Equal(*x, GetInteger32Constant(10)), &ifTrue, &ifFalse); // 10 : size of entry Bind(&ifTrue); - z = Int32Add(*x, GetInteger32Constant(10)); // 10 : size of entry + z = Int32Add(*x, GetInteger32Constant(10)); // 10 : size of entry Jump(&next); - Bind(&ifFalse); // else - z = Int32Add(*x, GetInteger32Constant(100)); // 100 : size of entry + Bind(&ifFalse); // else + z = Int32Add(*x, GetInteger32Constant(100)); // 100 : size of entry Jump(&next); Bind(&next); Return(*z); @@ -138,8 +139,7 @@ HWTEST_F_L0(StubOptimizerTest, PhiGateTest) LLVMTypeRef paramTys[] = { LLVMInt32Type(), }; - LLVMValueRef function = - LLVMAddFunction(module, "PhiGateTest", LLVMFunctionType(LLVMInt32Type(), paramTys, 1, 0)); + LLVMValueRef function = LLVMAddFunction(module, "PhiGateTest", LLVMFunctionType(LLVMInt32Type(), paramTys, 1, 0)); Environment env("PhiGateTest", 1); StubPhiOptimizer optimizer(&env); optimizer.GenerateCircuit(); @@ -160,7 +160,7 @@ HWTEST_F_L0(StubOptimizerTest, PhiGateTest) auto engine = compiler.GetEngine(); /* exec function */ auto fn = reinterpret_cast(LLVMGetPointerToGlobal(engine, function)); - auto val = fn(3); // 3 : size of array + auto val = fn(3); // 3 : size of array auto val2 = fn(0); std::cout << "val = " << std::dec << val << std::endl; std::cout << "val2 = " << std::dec << val2 << std::endl; @@ -183,7 +183,7 @@ public: { DEFVARIABLE(x, MachineType::INT32_TYPE, Int32Argument(0)); x = Int32Add(*x, GetInteger32Constant(1)); - AddrShift callFoo = CallStub(&phi_descriptor_, GetWord64Constant(FAST_STUB_ID(PhiTest)), {*x}); + AddrShift callFoo = CallStub(&phi_descriptor_, GetWord64Constant(0), {*x}); Return(Int32Add(callFoo, GetInteger32Constant(1))); } @@ -194,12 +194,16 @@ private: HWTEST_F_L0(StubOptimizerTest, CallPhiGateTest) { LLVMModuleRef module = static_cast(FastStubs::GetInstance().GetModule()); - LLVMValueRef function = LLVMGetNamedFunction(module, "PhiTest"); + LLVMTypeRef fooParamTys[] = { + LLVMInt32Type(), + }; + LLVMValueRef function = LLVMAddFunction(module, "PhiTest", LLVMFunctionType(LLVMInt32Type(), fooParamTys, 1, 0)); LLVMTypeRef barParamTys[] = { LLVMInt32Type(), }; - LLVMValueRef barfunction = LLVMAddFunction(module, "CallPhiGateTest_bar", - LLVMFunctionType(LLVMInt32Type(), barParamTys, 1, 0)); + FastStubs::GetInstance().SetFastStub(0, reinterpret_cast(function)); + LLVMValueRef barfunction = + LLVMAddFunction(module, "CallPhiGateTest_bar", LLVMFunctionType(LLVMInt32Type(), barParamTys, 1, 0)); Environment env("PhiTest", 1); StubPhiOptimizer optimizer(&env); optimizer.GenerateCircuit(); @@ -226,13 +230,13 @@ HWTEST_F_L0(StubOptimizerTest, CallPhiGateTest) LLVMMCJITCompiler compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); - auto *phiTestPointer = reinterpret_cast( - reinterpret_cast(LLVMGetPointerToGlobal(engine, function))); + auto *phiTestPointer = + reinterpret_cast(reinterpret_cast(LLVMGetPointerToGlobal(engine, function))); LLVMAddGlobalMapping(engine, function, reinterpret_cast(phiTestPointer)); - auto *barPointerbar = reinterpret_cast( - reinterpret_cast(LLVMGetPointerToGlobal(engine, barfunction))); - std::cout << std::hex << "phiTestPointer:" << reinterpret_cast(phiTestPointer) << - " barPointerbar:" << reinterpret_cast(barPointerbar) << std::endl; + auto *barPointerbar = + reinterpret_cast(reinterpret_cast(LLVMGetPointerToGlobal(engine, barfunction))); + std::cout << std::hex << "phiTestPointer:" << reinterpret_cast(phiTestPointer) + << " barPointerbar:" << reinterpret_cast(barPointerbar) << std::endl; compiler.Disassemble(); int result = barPointerbar(9); EXPECT_EQ(result, 21); @@ -254,18 +258,18 @@ public: Label loopHead(env); Label loopEnd(env); Label afterLoop(env); - Branch(Int32LessThan(*y, GetInteger32Constant(10)), &loopHead, &afterLoop); // 10 : size of entry + Branch(Int32LessThan(*y, GetInteger32Constant(10)), &loopHead, &afterLoop); // 10 : size of entry LoopBegin(&loopHead); Label ifTrue(env); Label ifFalse(env); Label next(env); - Branch(Word32Equal(Int32Argument(0), GetInteger32Constant(9)), &ifTrue, &ifFalse); // 9 : size of entry + Branch(Word32Equal(Int32Argument(0), GetInteger32Constant(9)), &ifTrue, &ifFalse); // 9 : size of entry Bind(&ifTrue); - z = Int32Add(*y, GetInteger32Constant(10)); // 10 : size of entry + z = Int32Add(*y, GetInteger32Constant(10)); // 10 : size of entry y = Int32Add(*z, GetInteger32Constant(1)); Jump(&next); Bind(&ifFalse); - z = Int32Add(*y, GetInteger32Constant(100)); // 100 : size of entry + z = Int32Add(*y, GetInteger32Constant(100)); // 100 : size of entry Jump(&next); Bind(&next); y = Int32Add(*y, GetInteger32Constant(1)); @@ -307,8 +311,8 @@ HWTEST_F_L0(StubOptimizerTest, LoopTest) /* exec function */ auto fn = reinterpret_cast(LLVMGetPointerToGlobal(engine, function)); auto resValid = fn(1); - auto resValid2 = fn(9); // 9 : size of array - auto resInvalid = fn(11); // 11 : size of array + auto resValid2 = fn(9); // 9 : size of array + auto resInvalid = fn(11); // 11 : size of array std::cout << "res for loop(1) = " << std::dec << resValid << std::endl; std::cout << "res for loop(9) = " << std::dec << resValid2 << std::endl; std::cout << "res for loop(11) = " << std::dec << resInvalid << std::endl; @@ -329,18 +333,18 @@ public: Label loopHead(env); Label loopEnd(env); Label afterLoop(env); - Branch(Int32LessThan(*y, GetInteger32Constant(10)), &loopHead, &afterLoop); // 10 : size of entry + Branch(Int32LessThan(*y, GetInteger32Constant(10)), &loopHead, &afterLoop); // 10 : size of entry LoopBegin(&loopHead); - x = Int32Add(*z, GetInteger32Constant(3)); // 3 : size of entry + x = Int32Add(*z, GetInteger32Constant(3)); // 3 : size of entry Label ifTrue(env); Label next(env); - Branch(Word32Equal(*x, GetInteger32Constant(9)), &ifTrue, &next); // 9 : size of entry + Branch(Word32Equal(*x, GetInteger32Constant(9)), &ifTrue, &next); // 9 : size of entry Bind(&ifTrue); y = Int32Add(*z, *x); Jump(&next); Bind(&next); y = Int32Add(*y, GetInteger32Constant(1)); - Branch(Int32LessThan(*y, GetInteger32Constant(10)), &loopEnd, &afterLoop); // 10 : size of entry + Branch(Int32LessThan(*y, GetInteger32Constant(10)), &loopEnd, &afterLoop); // 10 : size of entry Bind(&loopEnd); LoopEnd(&loopHead); Bind(&afterLoop); @@ -377,8 +381,8 @@ HWTEST_F_L0(StubOptimizerTest, LoopTest1) /* exec function */ auto fn = reinterpret_cast(LLVMGetPointerToGlobal(engine, function)); auto resValid = fn(1); - auto resValid2 = fn(9); // 9 : size of array - auto resInvalid = fn(11); // 11 : size of array + auto resValid2 = fn(9); // 9 : size of array + auto resInvalid = fn(11); // 11 : size of array std::cout << "res for loop1(1) = " << std::dec << resValid << std::endl; std::cout << "res for loop1(9) = " << std::dec << resValid2 << std::endl; std::cout << "res for loop1(11) = " << std::dec << resInvalid << std::endl; @@ -395,6 +399,8 @@ public: auto env = GetEnvironment(); AddrShift x = Int64Argument(0); AddrShift y = Int64Argument(1); + DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); + DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); StubOptimizerLabel ifTrue1(env); StubOptimizerLabel ifTrue2(env); StubOptimizerLabel ifFalse1(env); @@ -423,8 +429,8 @@ public: intX = Int32Add(intX, intY); Jump(&next3); Bind(&ifFalse4); - AddrShift doubleY = TaggedCastToDouble(y); - AddrShift doubleX = CastInt32ToFloat64(intX); + doubleY = TaggedCastToDouble(y); + doubleX = CastInt32ToFloat64(intX); Jump(&next2); Bind(&ifFalse3); doubleX = TaggedCastToDouble(x); @@ -443,8 +449,8 @@ public: Bind(&next1); Return(GetHoleConstant()); Bind(&next2); - doubleX = DoubleAdd(doubleX, doubleY); - Return(DoubleBuildTagged(doubleX)); + doubleX = DoubleAdd(*doubleX, *doubleY); + Return(DoubleBuildTagged(*doubleX)); Bind(&next3); Return(IntBuildTagged(intX)); } @@ -481,8 +487,8 @@ HWTEST_F_L0(StubOptimizerTest, FastAddTest) /* exec function */ auto fn = reinterpret_cast(LLVMGetPointerToGlobal(engine, function)); auto resValid = fn(JSTaggedValue(1).GetRawData(), JSTaggedValue(1).GetRawData()); - auto resValid2 = fn(JSTaggedValue(2).GetRawData(), JSTaggedValue(2).GetRawData()); // 2 : test case - auto resInvalid = fn(JSTaggedValue(11).GetRawData(), JSTaggedValue(11).GetRawData()); // 11 : test case + auto resValid2 = fn(JSTaggedValue(2).GetRawData(), JSTaggedValue(2).GetRawData()); // 2 : test case + auto resInvalid = fn(JSTaggedValue(11).GetRawData(), JSTaggedValue(11).GetRawData()); // 11 : test case std::cout << "res for FastAdd(1, 1) = " << std::dec << resValid.GetNumber() << std::endl; std::cout << "res for FastAdd(2, 2) = " << std::dec << resValid2.GetNumber() << std::endl; std::cout << "res for FastAdd(11, 11) = " << std::dec << resInvalid.GetNumber() << std::endl; @@ -499,6 +505,8 @@ public: auto env = GetEnvironment(); AddrShift x = Int64Argument(0); AddrShift y = Int64Argument(1); + DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); + DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); StubOptimizerLabel ifTrue1(env); StubOptimizerLabel ifTrue2(env); StubOptimizerLabel ifFalse1(env); @@ -527,8 +535,8 @@ public: intX = Int32Sub(intX, intY); Jump(&next3); Bind(&ifFalse4); - AddrShift doubleY = TaggedCastToDouble(y); - AddrShift doubleX = CastInt32ToFloat64(intX); + doubleY = TaggedCastToDouble(y); + doubleX = CastInt32ToFloat64(intX); Jump(&next2); Bind(&ifFalse3); doubleX = TaggedCastToDouble(x); @@ -547,8 +555,8 @@ public: Bind(&next1); Return(GetHoleConstant()); Bind(&next2); - doubleX = DoubleSub(doubleX, doubleY); - Return(DoubleBuildTagged(doubleX)); + doubleX = DoubleSub(*doubleX, *doubleY); + Return(DoubleBuildTagged(*doubleX)); Bind(&next3); Return(IntBuildTagged(intX)); } @@ -564,7 +572,7 @@ HWTEST_F_L0(StubOptimizerTest, FastSubTest) }; LLVMValueRef function = LLVMAddFunction(module, "FastSubTest", LLVMFunctionType(LLVMInt64Type(), paramTys, 2, 0)); LLVMDumpModule(module); - Environment env("FastSub", 2); // 2 : parameter + Environment env("FastSub", 2); // 2 : parameter FastSubOptimizer optimizer(&env); optimizer.GenerateCircuit(); auto netOfGates = env.GetCircuit(); @@ -584,9 +592,9 @@ HWTEST_F_L0(StubOptimizerTest, FastSubTest) auto engine = compiler.GetEngine(); /* exec function */ auto fn = reinterpret_cast(LLVMGetPointerToGlobal(engine, function)); - auto resA = fn(JSTaggedValue(2).GetRawData(), JSTaggedValue(1).GetRawData()); // 2 : test case - auto resB = fn(JSTaggedValue(7).GetRawData(), JSTaggedValue(2).GetRawData()); // 7, 2 : test cases - auto resC = fn(JSTaggedValue(11).GetRawData(), JSTaggedValue(11).GetRawData()); // 11 : test case + auto resA = fn(JSTaggedValue(2).GetRawData(), JSTaggedValue(1).GetRawData()); // 2 : test case + auto resB = fn(JSTaggedValue(7).GetRawData(), JSTaggedValue(2).GetRawData()); // 7, 2 : test cases + auto resC = fn(JSTaggedValue(11).GetRawData(), JSTaggedValue(11).GetRawData()); // 11 : test case std::cout << "res for FastSub(2, 1) = " << std::dec << resA.GetNumber() << std::endl; std::cout << "res for FastSub(7, 2) = " << std::dec << resB.GetNumber() << std::endl; std::cout << "res for FastSub(11, 11) = " << std::dec << resC.GetNumber() << std::endl; @@ -603,6 +611,8 @@ public: auto env = GetEnvironment(); AddrShift x = Int64Argument(0); AddrShift y = Int64Argument(1); + DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); + DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); StubOptimizerLabel ifTrue1(env); StubOptimizerLabel ifTrue2(env); StubOptimizerLabel ifFalse1(env); @@ -631,8 +641,8 @@ public: intX = Int32Mul(intX, intY); Jump(&next3); Bind(&ifFalse4); - AddrShift doubleY = TaggedCastToDouble(y); - AddrShift doubleX = CastInt32ToFloat64(intX); + doubleY = TaggedCastToDouble(y); + doubleX = CastInt32ToFloat64(intX); Jump(&next2); Bind(&ifFalse3); doubleX = TaggedCastToDouble(x); @@ -651,8 +661,8 @@ public: Bind(&next1); Return(GetHoleConstant()); Bind(&next2); - doubleX = DoubleMul(doubleX, doubleY); - Return(DoubleBuildTagged(doubleX)); + doubleX = DoubleMul(*doubleX, *doubleY); + Return(DoubleBuildTagged(*doubleX)); Bind(&next3); Return(IntBuildTagged(intX)); } @@ -668,7 +678,7 @@ HWTEST_F_L0(StubOptimizerTest, FastMulTest) }; LLVMValueRef function = LLVMAddFunction(module, "FastMulTest", LLVMFunctionType(LLVMInt64Type(), paramTys, 2, 0)); LLVMDumpModule(module); - Environment env("FastMul", 2); // 2 : parameter count + Environment env("FastMul", 2); // 2 : parameter count FastMulOptimizer optimizer(&env); optimizer.GenerateCircuit(); auto netOfGates = env.GetCircuit(); @@ -689,8 +699,8 @@ HWTEST_F_L0(StubOptimizerTest, FastMulTest) /* exec function */ auto fn = reinterpret_cast(LLVMGetPointerToGlobal(engine, function)); - auto resA = fn(JSTaggedValue(-2).GetRawData(), JSTaggedValue(1).GetRawData()); // -2 : test case - auto resB = fn(JSTaggedValue(-7).GetRawData(), JSTaggedValue(-2).GetRawData()); // -7, -2 : test case + auto resA = fn(JSTaggedValue(-2).GetRawData(), JSTaggedValue(1).GetRawData()); // -2 : test case + auto resB = fn(JSTaggedValue(-7).GetRawData(), JSTaggedValue(-2).GetRawData()); // -7, -2 : test case auto resC = fn(JSTaggedValue(11).GetRawData(), JSTaggedValue(11).GetRawData()); // 11 : test case std::cout << "res for FastMul(-2, 1) = " << std::dec << resA.GetNumber() << std::endl; std::cout << "res for FastMul(-7, -2) = " << std::dec << resB.GetNumber() << std::endl; @@ -708,6 +718,8 @@ public: auto env = GetEnvironment(); AddrShift x = Int64Argument(0); AddrShift y = Int64Argument(1); + DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); + DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); StubOptimizerLabel ifTrue1(env); StubOptimizerLabel ifTrue2(env); StubOptimizerLabel ifFalse1(env); @@ -732,7 +744,7 @@ public: Branch(TaggedIsInt(x), &ifTrue3, &ifFalse3); Bind(&ifTrue3); AddrShift intX = TaggedCastToInt32(x); - AddrShift doubleX = CastInt32ToFloat64(intX); + doubleX = CastInt32ToFloat64(intX); Jump(&next2); Bind(&ifFalse3); doubleX = TaggedCastToDouble(x); @@ -747,31 +759,32 @@ public: Branch(TaggedIsInt(y), &ifTrue4, &ifFalse4); Bind(&ifTrue4); AddrShift intY = TaggedCastToInt32(y); - AddrShift doubleY = CastInt32ToFloat64(intY); + doubleY = CastInt32ToFloat64(intY); Jump(&next3); Bind(&ifFalse4); doubleY = TaggedCastToDouble(y); Jump(&next3); Bind(&next3); - Branch(DoubleEqual(doubleY, GetDoubleConstant(0.0)), &ifTrue5, &ifFalse5); + Branch(DoubleEqual(*doubleY, GetDoubleConstant(0.0)), &ifTrue5, &ifFalse5); Bind(&ifTrue5); // dLeft == 0.0 || std::isnan(dLeft) - Branch(TruncInt64ToInt1(Word64Or(SExtInt1ToInt64(DoubleEqual(doubleX, GetDoubleConstant(0.0))), - SExtInt32ToInt64(DoubleIsNAN(doubleX)))), &ifTrue6, &ifFalse6); + Branch(TruncInt64ToInt1(Word64Or(SExtInt1ToInt64(DoubleEqual(*doubleX, GetDoubleConstant(0.0))), + SExtInt32ToInt64(DoubleIsNAN(*doubleX)))), + &ifTrue6, &ifFalse6); Bind(&ifTrue6); Return(DoubleBuildTagged(GetDoubleConstant(base::NAN_VALUE))); Bind(&ifFalse6); Jump(&next4); Bind(&next4); - AddrShift taggedX = CastDoubleToInt64(doubleX); - AddrShift taggedY = CastDoubleToInt64(doubleY); - taggedX = Word64And(Word64Or(taggedX, taggedY), GetWord64Constant(base::DOUBLE_SIGN_MASK)); - taggedX = Word64Or(taggedX, CastDoubleToInt64(GetDoubleConstant(base::POSITIVE_INFINITY))); - doubleX = TaggedCastToDouble(taggedX); - Return(DoubleBuildTagged(doubleX)); + AddrShift intXTmp = CastDoubleToInt64(*doubleX); + AddrShift intYtmp = CastDoubleToInt64(*doubleY); + intXTmp = Word64And(Word64Xor(intXTmp, intYtmp), GetWord64Constant(base::DOUBLE_SIGN_MASK)); + intXTmp = Word64Xor(intXTmp, CastDoubleToInt64(GetDoubleConstant(base::POSITIVE_INFINITY))); + doubleX = CastInt64ToFloat64(intXTmp); + Return(DoubleBuildTagged(*doubleX)); Bind(&ifFalse5); - doubleX = DoubleDiv(doubleX, doubleY); - Return(DoubleBuildTagged(doubleX)); + doubleX = DoubleDiv(*doubleX, *doubleY); + Return(DoubleBuildTagged(*doubleX)); } }; @@ -1014,8 +1027,8 @@ public: Jump(&loopHead); LoopBegin(&loopHead); AddrShift objPtr = ChangeInt64ToPointer(receiver); - AddrShift callFindOwnElementVal = CallStub(&findOwnElementDescriptor, - GetWord64Constant(FAST_STUB_ID(FindOwnElement)), {objPtr, index}); + AddrShift callFindOwnElementVal = + CallStub(&findOwnElementDescriptor, GetWord64Constant(FAST_STUB_ID(FindOwnElement)), {objPtr, index}); Branch(TaggedIsHole(callFindOwnElementVal), &isHole, ¬Hole); Bind(¬Hole); Return(callFindOwnElementVal); @@ -1076,11 +1089,12 @@ public: void GenerateCircuit() override { auto env = GetEnvironment(); - AddrShift elements = PtrArgument(0); - AddrShift index = Int32Argument(1); - AddrShift isDict = Int32Argument(2); // 2 : 3rd argument - AddrShift attr = PtrArgument(3); // 3 : 4th argument - AddrShift indexOrEntry = PtrArgument(4); // 4 : 5th argument + AddrShift thread = PtrArgument(0); + AddrShift elements = PtrArgument(1); + AddrShift index = Int32Argument(2); + AddrShift isDict = Int32Argument(3); + AddrShift attr = PtrArgument(4); + AddrShift indexOrEntry = PtrArgument(5); isDict = ZExtInt1ToInt32(isDict); Label notDictionary(env); Label isDictionary(env); @@ -1088,8 +1102,8 @@ public: Branch(Word32Equal(isDict, GetInteger32Constant(0)), ¬Dictionary, &isDictionary); Bind(¬Dictionary); { - AddrShift elementsLength = Load(UINT32_TYPE, elements, - GetPtrConstant(panda::coretypes::Array::GetLengthOffset())); + AddrShift elementsLength = + Load(UINT32_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetLengthOffset())); Label outOfElements(env); Label notOutOfElements(env); Branch(Int32LessThanOrEqual(elementsLength, index), &outOfElements, ¬OutOfElements); @@ -1108,7 +1122,7 @@ public: Bind(¬Hole); { Store(UINT32_TYPE, attr, GetPtrConstant(0), - GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())); + GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())); Store(UINT32_TYPE, indexOrEntry, GetPtrConstant(0), index); Return(value); } @@ -1117,7 +1131,8 @@ public: Bind(&isDictionary); { Label afterFindElement(env); - AddrShift entry = FindElementFromNumberDictionary(elements, IntBuildTagged(index), &afterFindElement); + AddrShift entry = + FindElementFromNumberDictionary(thread, elements, IntBuildTagged(index), &afterFindElement); Label notNegtiveOne(env); Label negtiveOne(env); Branch(Word32NotEqual(entry, GetInteger32Constant(-1)), ¬NegtiveOne, &negtiveOne); @@ -1147,9 +1162,9 @@ public: AddrShift thread = PtrArgument(0); AddrShift receiver = PtrArgument(1); DEFVARIABLE(holder, MachineType::TAGGED_POINTER_TYPE, receiver); - AddrShift index = Int32Argument(2); // 2 : 3rd argument - AddrShift value = Int64Argument(3); // 3 : 4th argument - AddrShift mayThrow = Int32Argument(4); // 4 : 5th argument + AddrShift index = Int32Argument(2); // 2 : 3rd argument + AddrShift value = Int64Argument(3); // 3 : 4th argument + AddrShift mayThrow = Int32Argument(4); // 4 : 5th argument DEFVARIABLE(onPrototype, MachineType::BOOL_TYPE, FalseConstant()); AddrShift pattr = Alloca(static_cast(MachineRep::K_WORD32)); @@ -1162,7 +1177,7 @@ public: AddrShift isDictionary = IsDictionaryMode(elements); StubInterfaceDescriptor *findOwnElemnt2 = GET_STUBDESCRIPTOR(FindOwnElement2); AddrShift val = CallStub(findOwnElemnt2, GetWord64Constant(FAST_STUB_ID(FindOwnElement2)), - {elements, index, isDictionary, pattr, pindexOrEntry}); + {thread, elements, index, isDictionary, pattr, pindexOrEntry}); Label notHole(env); Label isHole(env); Branch(TaggedIsNotHole(val), ¬Hole, &isHole); @@ -1172,9 +1187,9 @@ public: Label notOnProtoType(env); Label afterOnProtoType(env); Branch(*onPrototype, &isOnProtoType, ¬OnProtoType); - Bind(&isOnProtoType); - Jump(&afterOnProtoType); Bind(¬OnProtoType); + Jump(&afterOnProtoType); + Bind(&isOnProtoType); { Label isExtensible(env); Label notExtensible(env); @@ -1195,9 +1210,9 @@ public: } Bind(&nextExtensible); StubInterfaceDescriptor *addElementInternal = GET_STUBDESCRIPTOR(AddElementInternal); - Return(CallStub(addElementInternal, GetWord64Constant(FAST_STUB_ID(AddElementInternal)), - {thread, receiver, index, value, - GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())})); + Return(CallRuntime(addElementInternal, thread, GetWord64Constant(FAST_STUB_ID(AddElementInternal)), + {thread, receiver, index, value, + GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())})); } Bind(&afterOnProtoType); { @@ -1220,7 +1235,8 @@ public: Bind(¬Dict); { StoreElement(elements, indexOrEntry, value); - UpdateRepresention(LoadHClass(receiver), value); + Label updateRepLabel(env); + UpdateRepresention(LoadHClass(receiver), value, &updateRepLabel); Return(TrueConstant()); } Bind(&isDict); @@ -1244,8 +1260,8 @@ public: { StubInterfaceDescriptor *callsetter = GET_STUBDESCRIPTOR(CallSetter); AddrShift setter = GetSetterFromAccessor(val); - Return(CallStub(callsetter, GetWord64Constant(FAST_STUB_ID(CallSetter)), - { thread, setter, receiver, value, TruncInt32ToInt1(mayThrow) })); + Return(CallRuntime(callsetter, thread, GetWord64Constant(FAST_STUB_ID(CallSetter)), + {thread, setter, receiver, value, TruncInt32ToInt1(mayThrow)})); } } } @@ -1278,9 +1294,10 @@ public: Bind(&nextExtensible); { StubInterfaceDescriptor *addElementInternal = GET_STUBDESCRIPTOR(AddElementInternal); - Return(CallStub(addElementInternal, GetWord64Constant(FAST_STUB_ID(AddElementInternal)), - {thread, receiver, index, value, - GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())})); + Return(CallRuntime(addElementInternal, thread, + GetWord64Constant(FAST_STUB_ID(AddElementInternal)), + {thread, receiver, index, value, + GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())})); } } Bind(&isHeapObj); @@ -1291,8 +1308,9 @@ public: Bind(&isJsProxy); { StubInterfaceDescriptor *setProperty = GET_STUBDESCRIPTOR(JSProxySetProperty); - Return(CallStub(setProperty, GetWord64Constant(FAST_STUB_ID(JSProxySetProperty)), - { thread, *holder, IntBuildTagged(index), value, receiver, TruncInt32ToInt1(mayThrow) })); + Return(CallRuntime( + setProperty, thread, GetWord64Constant(FAST_STUB_ID(JSProxySetProperty)), + {thread, *holder, IntBuildTagged(index), value, receiver, TruncInt32ToInt1(mayThrow)})); } Bind(¬JsProxy); onPrototype = TrueConstant(); @@ -1308,7 +1326,7 @@ HWTEST_F_L0(StubOptimizerTest, FastFindOwnElement2Stub) std::cout << " ------------------------FastFindOwnElement2Stub ---------------------" << std::endl; LLVMModuleRef module = static_cast(FastStubs::GetInstance().GetModule()); LLVMValueRef function = LLVMGetNamedFunction(module, "FindOwnElement2"); - Environment env("FindOwnElement2", 5); + Environment env("FindOwnElement2", 6); FastFindOwnElement2Stub optimizer(&env); optimizer.GenerateCircuit(); auto netOfGates = env.GetCircuit(); @@ -1325,6 +1343,548 @@ HWTEST_F_L0(StubOptimizerTest, FastFindOwnElement2Stub) llvmBuilder.Build(); LLVMMCJITCompiler compiler(module); compiler.Run(); + auto engine = compiler.GetEngine(); + auto *findOwnElement2Ptr = reinterpret_cast( + reinterpret_cast(LLVMGetPointerToGlobal(engine, function))); + auto *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory(); + JSHandle obj = factory->NewEmptyJSObject(); + int x = 213; + int y = 10; + FastRuntimeStub::SetOwnElement(thread, obj.GetTaggedValue(), 1, JSTaggedValue(x)); + FastRuntimeStub::SetOwnElement(thread, obj.GetTaggedValue(), 10250, JSTaggedValue(y)); + TaggedArray *elements = TaggedArray::Cast(obj->GetElements().GetHeapObject()); + PropertyAttributes attr; + uint32_t indexOrEntry; + bool isDict = elements->IsDictionaryMode(); + compiler.Disassemble(); + JSTaggedValue resVal = findOwnElement2Ptr(thread, elements, 1, isDict, &attr, &indexOrEntry); + EXPECT_EQ(resVal.GetNumber(), x); + resVal = findOwnElement2Ptr(thread, elements, 10250, isDict, &attr, &indexOrEntry); + EXPECT_EQ(resVal.GetNumber(), y); std::cout << " ++++++++++++++++++++FastFindOwnElement2Stub ++++++++++++++++++" << std::endl; } + +HWTEST_F_L0(StubOptimizerTest, SetElementStub) +{ + LLVMModuleRef module = static_cast(FastStubs::GetInstance().GetModule()); + LLVMValueRef function = LLVMGetNamedFunction(module, "SetElement"); + Environment env("SetElementStub", 5); + SetElementStub optimizer(&env); + optimizer.GenerateCircuit(); + auto netOfGates = env.GetCircuit(); + netOfGates.PrintAllGates(); + auto cfg = Scheduler::Run(&netOfGates); + for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { + std::cout << (netOfGates.GetOpCode(cfg[bbIdx].front()).IsCFGMerge() ? "MERGE_" : "BB_") << bbIdx << ":" + << std::endl; + for (size_t instIdx = cfg[bbIdx].size(); instIdx > 0; instIdx--) { + netOfGates.Print(cfg[bbIdx][instIdx - 1]); + } + } + LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); + llvmBuilder.Build(); + LLVMMCJITCompiler compiler(module); + compiler.Run(); +} + +struct ThreadTy { + intptr_t magic; // 0x11223344 + intptr_t fp; +}; +class StubCallRunTimeThreadFpLock { +public: + StubCallRunTimeThreadFpLock(struct ThreadTy *thread, intptr_t newFp): oldRbp_(thread->fp), + thread_(thread) + { + thread_->fp = *(reinterpret_cast(newFp)); + std::cout << "StubCallRunTimeThreadFpLock newFp: " << newFp << " oldRbp_ : " << oldRbp_ + << " thread_->fp:" << thread_->fp <fp:" << thread_->fp << std::endl; + thread_->fp = oldRbp_; + } +private: + intptr_t oldRbp_; + struct ThreadTy *thread_; +}; + +extern "C" { +int64_t RuntimeFunc(struct ThreadTy *fpInfo) +{ + int64_t *rbp; + asm("mov %%rbp, %0" : "=rm"(rbp)); + if (fpInfo->fp == *rbp) { + return 1; + } + return 0; +} + +int64_t (*g_stub2Func)(struct ThreadTy *) = nullptr; + +int RuntimeFunc1(struct ThreadTy *fpInfo) +{ + std::cout << "RuntimeFunc1 -" << std::endl; + int64_t newRbp; + asm("mov %%rbp, %0" : "=rm"(newRbp)); + StubCallRunTimeThreadFpLock lock(fpInfo, newRbp); + + std::cout << std::hex << "g_stub2Func " << reinterpret_cast(g_stub2Func) << std::endl; + if (g_stub2Func != nullptr) { + g_stub2Func(fpInfo); + } + std::cout << "RuntimeFunc1 +" << std::endl; + return 0; +} + +int RuntimeFunc2(struct ThreadTy *fpInfo) +{ + std::cout << "RuntimeFunc2 -" << std::endl; + // update thread.fp + int64_t newRbp; + asm("mov %%rbp, %0" : "=rm"(newRbp)); + StubCallRunTimeThreadFpLock lock(fpInfo, newRbp); + auto rbp = reinterpret_cast(fpInfo->fp); + + std::cout << " RuntimeFunc2 rbp:" << rbp <(*gcFp); + std::cout << std::hex << "frameType :" << *frameType << " gcFp:" << *gcFp << std::endl; + } while (*gcFp != 0); + std::cout << "+++++++++++++++++walkback++++++++++++++++" << std::endl; + std::cout << "call RuntimeFunc2 func ThreadTy fp: " << fpInfo->fp << " magic:" << fpInfo->magic << std::endl; + std::cout << "RuntimeFunc2 +" << std::endl; + return 0; +} +} + +/* +c++:main + --> js (stub1(struct ThreadTy *)) + stack frame: 0 pre rbp <-- rbp + -8 type + -16 pre frame thread fp + --> c++(int RuntimeFunc1(struct ThreadTy *fpInfo)) + --> js (int stub2(struct ThreadTy *)) + stack frame: 0 pre rbp <-- rbp + -8 type + -16 pre frame thread fp + --> js (int stub3(struct ThreadTy *)) + stack frame: 0 pre rbp <-- rbp + -8 type + --> c++(int RuntimeFunc2(struct ThreadTy *fpInfo)) + +result: +-----------------walkback---------------- +frameType :0 gcFp:7fffffffd780 +frameType :1 gcFp:7fffffffd820 +frameType :1 gcFp:0 ++++++++++++++++++walkback++++++++++++++++ +#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:40 +#1 0x00007ffff03778b1 in __GI_abort () at abort.c:79 +#2 0x0000555555610f1c in RuntimeFunc2 () +#3 0x00007fffebf7b1fb in stub3 () +#4 0x00007fffebf7b1ab in stub2 () +#5 0x0000555555610afe in RuntimeFunc1 () +#6 0x00007fffebf7b14e in stub1 () +#7 0x000055555561197c in panda::test::StubOptimizerTest_JSEntryTest_Test::TestBody() () +*/ + +LLVMValueRef LLVMCallingFp(LLVMModuleRef &module, LLVMBuilderRef &builder) +{ + /* 0:calling 1:its caller */ + std::vector args = {LLVMConstInt(LLVMInt32Type(), 0, false)}; + auto fn = LLVMGetNamedFunction(module, "llvm.frameaddress.p0i8"); + if (!fn) { + std::cout << "Could not find function " << std::endl; + return LLVMConstInt(LLVMInt64Type(), 0, false); + } + LLVMValueRef fAddrRet = LLVMBuildCall(builder, fn, args.data(), 1, ""); + LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder, fAddrRet, LLVMInt64Type(), "cast_int64_t"); + return frameAddr; +} + +HWTEST_F_L0(StubOptimizerTest, JSEntryTest) +{ + std::cout << " ---------- JSEntryTest ------------- " << std::endl; + LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); + LLVMSetTarget(module, "x86_64-unknown-linux-gnu"); + LLVMBuilderRef builder = LLVMCreateBuilder(); + LLVMContextRef context = LLVMGetGlobalContext(); + + /* init instrinsic function declare */ + LLVMTypeRef paramTys1[] = { + LLVMInt32Type(), + }; + auto llvmFnType = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), paramTys1, 1, 0); + LLVMValueRef llvmFn = LLVMAddFunction(module, "llvm.frameaddress.p0i8", llvmFnType); + (void)llvmFn; + + // struct ThreadTy + LLVMTypeRef llvmI32 = LLVMInt32TypeInContext(context); + LLVMTypeRef llvmI64 = LLVMInt64TypeInContext(context); + std::vector elements_t {llvmI64, llvmI64}; + LLVMTypeRef threadTy = LLVMStructTypeInContext(context, elements_t.data(), elements_t.size(), 0); + LLVMTypeRef threadTyPtr = LLVMPointerType(threadTy, 0); + LLVMTypeRef paramTys0[] = { + threadTyPtr + }; + /* implement stub1 */ + LLVMValueRef stub1 = LLVMAddFunction(module, "stub1", LLVMFunctionType(LLVMInt64Type(), paramTys0, 1, 0)); + LLVMAddTargetDependentFunctionAttr(stub1, "frame-pointer", "all"); + LLVMAddTargetDependentFunctionAttr(stub1, "js-stub-call", "1"); + + LLVMBasicBlockRef entryBb = LLVMAppendBasicBlock(stub1, "entry"); + LLVMPositionBuilderAtEnd(builder, entryBb); + /* struct ThreadTy fpInfo; + fpInfo.magic = 0x11223344; + fpInfo.fp = calling frame address + */ + LLVMValueRef value = LLVMGetParam(stub1, 0); + LLVMValueRef c0 = LLVMConstInt(LLVMInt32Type(), 0, false); + LLVMValueRef c1 = LLVMConstInt(LLVMInt32Type(), 1, false); + std::vector indexes1 = {c0, c0}; + std::vector indexes2 = {c0, c1}; + LLVMValueRef gep1 = LLVMBuildGEP2(builder, threadTy, value, indexes1.data(), indexes1.size(), ""); + + LLVMValueRef gep2 = LLVMBuildGEP2(builder, threadTy, value, indexes2.data(), indexes2.size(), "fpAddr"); + LLVMBuildStore(builder, LLVMConstInt(LLVMInt64Type(), 0x11223344, false), gep1); + LLVMValueRef frameAddr = LLVMCallingFp(module, builder); + /* current frame + 0 pre rbp <-- rbp + -8 type + -16 pre frame thread fp + */ + LLVMValueRef preFp = LLVMBuildLoad2(builder, LLVMInt64Type(), gep2, "thread.fp"); + LLVMValueRef addr = LLVMBuildSub(builder, frameAddr, LLVMConstInt(LLVMInt64Type(), 16, false), ""); + LLVMValueRef preFpAddr = LLVMBuildIntToPtr(builder, addr, LLVMPointerType(LLVMInt64Type(), 0), "thread.fp.Addr"); + LLVMBuildStore(builder, preFp, preFpAddr); + + /* stub1 call RuntimeFunc1 */ + std::vector argsTy(1, threadTyPtr); + LLVMTypeRef funcType = LLVMFunctionType(llvmI32, argsTy.data(), argsTy.size(), 1); + LLVMValueRef runtimeFunc1 = LLVMAddFunction(module, "RuntimeFunc1", funcType); + + std::vector argValue = {value}; + LLVMBuildCall(builder, runtimeFunc1, argValue.data(), 1, ""); + LLVMValueRef retVal = LLVMConstInt(LLVMInt64Type(), 1, false); + LLVMBuildRet(builder, retVal); + + /* implement stub2 call stub3 */ + LLVMValueRef stub2 = LLVMAddFunction(module, "stub2", LLVMFunctionType(LLVMInt64Type(), paramTys0, 1, 0)); + LLVMAddTargetDependentFunctionAttr(stub2, "frame-pointer", "all"); + LLVMAddTargetDependentFunctionAttr(stub2, "js-stub-call", "1"); + + entryBb = LLVMAppendBasicBlock(stub2, "entry"); + LLVMPositionBuilderAtEnd(builder, entryBb); + LLVMValueRef value2 = LLVMGetParam(stub2, 0); + /* struct ThreadTy fpInfo; + fpInfo.fp = calling frame address + */ + gep2 = LLVMBuildGEP2(builder, threadTy, value2, indexes2.data(), indexes2.size(), "fpAddr"); + frameAddr = LLVMCallingFp(module, builder); + /* current frame + 0 pre rbp <-- rbp + -8 type + -16 pre frame thread fp + */ + preFp = LLVMBuildLoad2(builder, LLVMInt64Type(), gep2, "thread.fp"); + addr = LLVMBuildSub(builder, frameAddr, LLVMConstInt(LLVMInt64Type(), 16, false), ""); + preFpAddr = LLVMBuildIntToPtr(builder, addr, LLVMPointerType(LLVMInt64Type(), 0), "thread.fp.Addr"); + LLVMBuildStore(builder, preFp, preFpAddr); + + LLVMValueRef stub3 = LLVMAddFunction(module, "stub3", LLVMFunctionType(LLVMInt64Type(), paramTys0, 1, 0)); + /* stub2 call stub3 */ + argValue = {value2}; + + LLVMBuildCall(builder, stub3, argValue.data(), 1, ""); + retVal = LLVMConstInt(LLVMInt64Type(), 2, false); + LLVMBuildRet(builder, retVal); + + /* implement stub3 call RuntimeFunc2 */ + LLVMAddTargetDependentFunctionAttr(stub3, "frame-pointer", "all"); + LLVMAddTargetDependentFunctionAttr(stub3, "js-stub-call", "0"); + + entryBb = LLVMAppendBasicBlock(stub3, "entry"); + LLVMPositionBuilderAtEnd(builder, entryBb); + LLVMValueRef value3 = LLVMGetParam(stub3, 0); + /* struct ThreadTy fpInfo; + fpInfo.fp = calling frame address + */ + gep2 = LLVMBuildGEP2(builder, threadTy, value3, indexes2.data(), indexes2.size(), "fpAddr"); + /* current frame + 0 pre rbp <-- rbp + -8 type + */ + /* stub2 call RuntimeFunc2 */ + LLVMValueRef runtimeFunc2 = LLVMAddFunction(module, "RuntimeFunc2", funcType); + argValue = {value3}; + LLVMBuildCall(builder, runtimeFunc2, argValue.data(), 1, ""); + retVal = LLVMConstInt(LLVMInt64Type(), 3, false); + LLVMBuildRet(builder, retVal); + LLVMDumpModule(module); + char* error = nullptr; + LLVMVerifyModule(module, LLVMAbortProcessAction, &error); + + LLVMMCJITCompiler compiler(module); + compiler.Run(); + auto engine = compiler.GetEngine(); + uint64_t stub1Code = LLVMGetFunctionAddress(engine, "stub1"); + uint64_t stub2Code = LLVMGetFunctionAddress(engine, "stub2"); + uint64_t stub3Code = LLVMGetFunctionAddress(engine, "stub3"); + std::map addr2name = { + {stub1Code, "stub1"}, {stub2Code, "stub2"}, {stub3Code, "stub3"} + }; + std::cout << std::endl << " stub1Code : " << stub1Code << std::endl; + std::cout << std::endl << " stub2Code : " << stub2Code << std::endl; + std::cout << std::endl << " stub3Code : " << stub3Code << std::endl; + compiler.Disassemble(addr2name); + struct ThreadTy parameters = {0x0, 0x0}; + auto stub1Func = reinterpret_cast(stub1Code); + g_stub2Func = reinterpret_cast(stub2Code); + int64_t result = stub1Func(¶meters); + std::cout << std::endl << "parameters magic:" << parameters.magic + << " parameters.fp " << parameters.fp << std::endl; + EXPECT_EQ(parameters.fp, 0x0); + EXPECT_EQ(result, 1); + std::cout << " ++++++++++ JSEntryTest +++++++++++++ " << std::endl; +} + +/* +verify modify llvm prologue : call main ok means don't destory c abi +test: +main push rbp + push type + push thread.fp // reserved for modification + call bar + push rbp + push type +*/ +HWTEST_F_L0(StubOptimizerTest, Prologue) +{ + std::cout << " ---------- Prologue ------------- " << std::endl; + LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); + LLVMSetTarget(module, "x86_64-unknown-linux-gnu"); + LLVMBuilderRef builder = LLVMCreateBuilder(); + // struct ThreadTy + LLVMTypeRef paramTys0[] = { + LLVMInt64Type(), + LLVMInt64Type(), + }; + + /* implement main implement */ + LLVMValueRef func = LLVMAddFunction(module, "main", LLVMFunctionType(LLVMInt64Type(), nullptr, 0, 0)); + LLVMAddTargetDependentFunctionAttr(func, "frame-pointer", "all"); + LLVMAddTargetDependentFunctionAttr(func, "js-stub-call", "1"); + + LLVMBasicBlockRef entryBb = LLVMAppendBasicBlock(func, "entry"); + LLVMPositionBuilderAtEnd(builder, entryBb); + + /* implement main call RuntimeFunc */ + LLVMBuilderRef builderBar = LLVMCreateBuilder(); + LLVMValueRef bar = LLVMAddFunction(module, "bar", LLVMFunctionType(LLVMInt64Type(), paramTys0, 2, 0)); + LLVMAddTargetDependentFunctionAttr(bar, "frame-pointer", "all"); + LLVMAddTargetDependentFunctionAttr(bar, "js-stub-call", "0"); + LLVMBasicBlockRef entryBbBar = LLVMAppendBasicBlock(bar, "entry"); + LLVMPositionBuilderAtEnd(builderBar, entryBbBar); + LLVMValueRef value0Bar = LLVMGetParam(bar, 0); + LLVMValueRef value1Bar = LLVMGetParam(bar, 1); + LLVMValueRef retValBar = LLVMBuildAdd(builderBar, value0Bar, value1Bar, ""); + LLVMBuildRet(builderBar, retValBar); + + LLVMValueRef value0 = LLVMConstInt(LLVMInt64Type(), 1, false); + LLVMValueRef value1 = LLVMConstInt(LLVMInt64Type(), 2, false); + std::vector args = {value0, value1}; + auto retVal = LLVMBuildCall(builder, bar, args.data(), 2, ""); + LLVMBuildRet(builder, retVal); + + LLVMDumpModule(module); + char* error = nullptr; + LLVMVerifyModule(module, LLVMAbortProcessAction, &error); + + LLVMMCJITCompiler compiler(module); + compiler.Run(); + auto engine = compiler.GetEngine(); + uint64_t mainCode = LLVMGetFunctionAddress(engine, "main"); + compiler.Disassemble(); + auto mainFunc = reinterpret_cast(mainCode); + int64_t result = mainFunc(1, 2); + EXPECT_EQ(result, 3); + std::cout << " ++++++++++ Prologue +++++++++++++ " << std::endl; +} + +/* +verify llvm.frameaddress.p0i8 ok +test: + js(stub):main + call RuntimeFunc +*/ +HWTEST_F_L0(StubOptimizerTest, CEntryFp) +{ + std::cout << " ---------- CEntryFp ------------- " << std::endl; + LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); + LLVMSetTarget(module, "x86_64-unknown-linux-gnu"); + LLVMBuilderRef builder = LLVMCreateBuilder(); + LLVMContextRef context = LLVMGetGlobalContext(); + + // struct ThreadTy + LLVMTypeRef llvmI64 = LLVMInt64TypeInContext(context); + std::vector elements_t {llvmI64, llvmI64}; + LLVMTypeRef threadTy = LLVMStructTypeInContext(context, elements_t.data(), elements_t.size(), 0); + LLVMTypeRef threadTyPtr = LLVMPointerType(threadTy, 0); + LLVMTypeRef paramTys0[] = { + threadTyPtr + }; + /* implement main call RuntimeFunc */ + LLVMValueRef func = LLVMAddFunction(module, "main", LLVMFunctionType(LLVMInt64Type(), paramTys0, 1, 0)); + LLVMAddTargetDependentFunctionAttr(func, "frame-pointer", "all"); + LLVMAddTargetDependentFunctionAttr(func, "js-stub-call", "1"); + LLVMBasicBlockRef entryBb = LLVMAppendBasicBlock(func, "entry"); + LLVMPositionBuilderAtEnd(builder, entryBb); + /* struct ThreadTy fpInfo; + fpInfo.magic = 0x11223344; + fpInfo.fp = calling frame address + */ + LLVMValueRef value = LLVMGetParam(func, 0); + + LLVMValueRef c0 = LLVMConstInt(LLVMInt32Type(), 0, false); + LLVMValueRef c1 = LLVMConstInt(LLVMInt32Type(), 1, false); + std::vector indexes1 = {c0, c0}; + std::vector indexes2 = {c0, c1}; + LLVMValueRef gep1 = LLVMBuildGEP2(builder, threadTy, value, indexes1.data(), indexes1.size(), ""); + LLVMDumpValue(gep1); + std::cout << std::endl; + LLVMValueRef gep2 = LLVMBuildGEP2(builder, threadTy, value, indexes2.data(), indexes2.size(), "fpAddr"); + LLVMBuildStore(builder, LLVMConstInt(LLVMInt64Type(), 0x11223344, false), gep1); + + LLVMTypeRef paramTys1[] = { + LLVMInt32Type(), + }; + auto fnType = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), paramTys1, 1, 0); + /* 0:calling 1:its caller */ + std::vector args = {LLVMConstInt(LLVMInt32Type(), 0, false)}; + LLVMValueRef fn = LLVMAddFunction(module, "llvm.frameaddress.p0i8", fnType); + LLVMValueRef fAddrRet = LLVMBuildCall(builder, fn, args.data(), 1, ""); + LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder, fAddrRet, LLVMInt64Type(), "cast_int64_t"); + + LLVMBuildStore(builder, frameAddr, gep2); + + /* main call RuntimeFunc */ + std::vector argsTy(1, threadTyPtr); + LLVMTypeRef funcType = LLVMFunctionType(llvmI64, argsTy.data(), argsTy.size(), 1); + LLVMValueRef runTimeFunc = LLVMAddFunction(module, "RuntimeFunc", funcType); + + std::vector argValue = {value}; + std::cout << std::endl; + LLVMValueRef retVal = LLVMBuildCall(builder, runTimeFunc, argValue.data(), 1, ""); + LLVMBuildRet(builder, retVal); + + LLVMDumpModule(module); + char* error = nullptr; + LLVMVerifyModule(module, LLVMAbortProcessAction, &error); + + LLVMMCJITCompiler compiler(module); + compiler.Run(); + auto engine = compiler.GetEngine(); + uint64_t nativeCode = LLVMGetFunctionAddress(engine, "main"); + std::cout << std::endl << " nativeCode : " << nativeCode << std::endl; + compiler.Disassemble(); + struct ThreadTy parameters = {0x0, 0x0}; + + auto mainFunc = reinterpret_cast(nativeCode); + int64_t result = mainFunc(¶meters); + EXPECT_EQ(result, 1); + std::cout << " ++++++++++ CEntryFp +++++++++++++ " << std::endl; +} + +HWTEST_F_L0(StubOptimizerTest, LoadGCIRTest) +{ + std::cout << "--------------LoadGCIRTest--------------------" << std::endl; + char *path = get_current_dir_name(); + std::string filePath = std::string(path) + "/../../ark/js_runtime/ecmascript/compiler/tests/satepoint_GC_0.ll"; + + char resolvedPath[PATH_MAX]; + char *res = realpath(filePath.c_str(), resolvedPath); + if (res == nullptr) { + std::cerr << "filePath :" << filePath.c_str() << " is not exist !" << std::endl; + return; + } + + llvm::SMDiagnostic err; + llvm::LLVMContext context; + llvm::StringRef inputFilename(resolvedPath); + // Load the input module... + std::unique_ptr rawModule = + parseIRFile(inputFilename, err, context); + if (!rawModule) { + std::cout << "parseIRFile :" << inputFilename.data() << " failed !" << std::endl; + return; + } + LLVMModuleRef module = LLVMCloneModule(wrap(rawModule.get())); + LLVMMCJITCompiler compiler(module); + compiler.Run(); + auto engine = compiler.GetEngine(); + LLVMValueRef function = + LLVMGetNamedFunction(module, "main"); + LLVMDumpValue(function); + + auto *mainPtr = reinterpret_cast(LLVMGetPointerToGlobal(engine, function)); + uint8_t *ptr = compiler.GetStackMapsSection(); + LLVMStackMapParse::GetInstance().CalculateStackMap(ptr); + LLVMStackMapParse::GetInstance().Print(); + + compiler.Disassemble(); + LLVMDumpModule(module); + int value = reinterpret_cast(mainPtr)(); + std::cout << " value:" << value << std::endl; +} +extern "C" { +void DoSafepoint() +{ + uintptr_t *rbp; + asm("mov %%rbp, %0" : "=rm" (rbp)); + for (int i = 0; i < 3; i++) { + uintptr_t returnAddr = *(rbp + 1); + uintptr_t *rsp = rbp + 2; + rbp = reinterpret_cast(*rbp); + DwarfRegAndOffsetType info; + bool found = LLVMStackMapParse::GetInstance().StackMapByAddr(returnAddr, info); + if (found) { + uintptr_t **address = nullptr; + if (info.first == 7) { + address = reinterpret_cast(reinterpret_cast(rsp) + info.second); + // rbp + } else if (info.first == 6) { + address = reinterpret_cast(reinterpret_cast(rbp) + info.second); + } + std::cout << std::hex << "ref addr:" << address; + std::cout << " value:" << *address; + std::cout << " *value :" << **address << std::endl; + } + std::cout << std::endl << std::endl; + std::cout << std::hex << "+++++++++++++++++++ returnAddr : 0x" << returnAddr << " rbp:" << rbp + << " rsp: " << rsp << std::endl; + } + std::cout << "do_safepoint +++ " << std::endl; +} +} } // namespace panda::test diff --git a/ecmascript/compiler/type.h b/ecmascript/compiler/type.h index 6218a3c617ed9c32098f7cf780b1ad75dcb0a6d3..399d6cfa755bd939c2ab48b6d786997cbcf5449a 100644 --- a/ecmascript/compiler/type.h +++ b/ecmascript/compiler/type.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_TYPE_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_TYPE_H +#ifndef ECMASCRIPT_COMPILER_TYPE_H +#define ECMASCRIPT_COMPILER_TYPE_H #include @@ -58,4 +58,4 @@ private: }; } // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_TYPE_H +#endif // ECMASCRIPT_COMPILER_TYPE_H diff --git a/ecmascript/compiler/verifier.cpp b/ecmascript/compiler/verifier.cpp index 526ce9bffbe2fe3a32a63d3d8e2ac2f0b4233cf8..ef13d9f3fefb45d2c9fcb846ec393c6d4c4b5c8c 100644 --- a/ecmascript/compiler/verifier.cpp +++ b/ecmascript/compiler/verifier.cpp @@ -84,7 +84,7 @@ bool Verifier::RunDataIntegrityCheck(const Circuit *circuit) while (!curOut->IsNextOutNull()) { curOut = curOut->GetNextOutConst(); if (!(circuit->GetSpaceDataStartPtrConst() < curOut && - curOut < circuit->GetSpaceDataEndPtrConst())) { + curOut < circuit->GetSpaceDataEndPtrConst())) { std::cerr << "[Verifier][Error] Circuit data is corrupted (corrupted out list)" << std::endl; std::cerr << "id: " << std::dec << circuit->GetId(gate) << std::endl; return false; @@ -421,7 +421,7 @@ bool Verifier::Run(const Circuit *circuit) for (size_t idx = 1; idx < immDom.size(); idx++) { sonList[immDom[idx]].push_back(idx); } - const size_t sizeLog = ceil(log2(static_cast(bbGatesList.size())) + 1); + const size_t sizeLog = std::ceil(std::log2(static_cast(bbGatesList.size())) + 1); std::vector timeIn(bbGatesList.size()); std::vector timeOut(bbGatesList.size()); std::vector> jumpUp; diff --git a/ecmascript/compiler/verifier.h b/ecmascript/compiler/verifier.h index c3729164157c6377622e9c0a128275d156a3c53b..2c23be63cf3915ad5b2d7a380b4090a6ef49f9e2 100644 --- a/ecmascript/compiler/verifier.h +++ b/ecmascript/compiler/verifier.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_COMPILER_VERIFIER_H -#define PANDA_RUNTIME_ECMASCRIPT_COMPILER_VERIFIER_H +#ifndef ECMASCRIPT_COMPILER_VERIFIER_H +#define ECMASCRIPT_COMPILER_VERIFIER_H #include #include @@ -52,4 +52,4 @@ public: }; } // namespace kungfu -#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_VERIFIER_H +#endif // ECMASCRIPT_COMPILER_VERIFIER_H diff --git a/ecmascript/dump.cpp b/ecmascript/dump.cpp index ef93394ac5a22bc71be131e8b84ee5324421c439..92f46420e8fd8f5b2b11a8e2479dbbe7c2363004 100644 --- a/ecmascript/dump.cpp +++ b/ecmascript/dump.cpp @@ -31,13 +31,8 @@ #include "ecmascript/js_async_function.h" #include "ecmascript/js_dataview.h" #include "ecmascript/js_date.h" -#include "ecmascript/js_float32_array.h" -#include "ecmascript/js_float64_array.h" #include "ecmascript/js_function.h" #include "ecmascript/js_handle.h" -#include "ecmascript/js_int16_array.h" -#include "ecmascript/js_int32_array.h" -#include "ecmascript/js_int8_array.h" #include "ecmascript/js_map.h" #include "ecmascript/js_map_iterator.h" #include "ecmascript/js_object-inl.h" @@ -50,10 +45,6 @@ #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/js_thread.h" #include "ecmascript/js_typed_array.h" -#include "ecmascript/js_uint16_array.h" -#include "ecmascript/js_uint32_array.h" -#include "ecmascript/js_uint8_array.h" -#include "ecmascript/js_uint8_clamped_array.h" #include "ecmascript/js_weak_container.h" #include "ecmascript/layout_info-inl.h" #include "ecmascript/lexical_env.h" @@ -384,34 +375,16 @@ static void DumpObject(JSThread *thread, TaggedObject *obj, std::ostream &os) JSArray::Cast(obj)->Dump(thread, os); break; case JSType::JS_TYPED_ARRAY: - JSTypedArray::Cast(obj)->Dump(thread, os); - break; case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(obj)->Dump(thread, os); - break; case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(obj)->Dump(thread, os); - break; case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(obj)->Dump(thread, os); - break; case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(obj)->Dump(thread, os); - break; case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(obj)->Dump(thread, os); - break; case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(obj)->Dump(thread, os); - break; case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(obj)->Dump(thread, os); - break; case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(obj)->Dump(thread, os); - break; case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(obj)->Dump(thread, os); + JSTypedArray::Cast(obj)->Dump(thread, os); break; case JSType::JS_PROXY: JSProxy::Cast(obj)->Dump(thread, os); @@ -959,140 +932,6 @@ void JSTypedArray::Dump(JSThread *thread, std::ostream &os) const JSObject::Dump(thread, os); } -void JSInt8Array::Dump(JSThread *thread, std::ostream &os) const -{ - os << " - viewed-array-buffer: "; - GetViewedArrayBuffer().Dump(thread); - os << " - typed-array-name: "; - GetTypedArrayName().Dump(thread); - os << " - byte-length: "; - GetByteLength().Dump(thread); - os << " - byte-offset: "; - GetByteOffset().Dump(thread); - os << " - array-length: "; - GetArrayLength().Dump(thread); - JSObject::Dump(thread, os); -} - -void JSUint8Array::Dump(JSThread *thread, std::ostream &os) const -{ - os << " - viewed-array-buffer: "; - GetViewedArrayBuffer().Dump(thread); - os << " - typed-array-name: "; - GetTypedArrayName().Dump(thread); - os << " - byte-length: "; - GetByteLength().Dump(thread); - os << " - byte-offset: "; - GetByteOffset().Dump(thread); - os << " - array-length: "; - GetArrayLength().Dump(thread); - JSObject::Dump(thread, os); -} - -void JSUint8ClampedArray::Dump(JSThread *thread, std::ostream &os) const -{ - os << " - viewed-array-buffer: "; - GetViewedArrayBuffer().Dump(thread); - os << " - typed-array-name: "; - GetTypedArrayName().Dump(thread); - os << " - byte-length: "; - GetByteLength().Dump(thread); - os << " - byte-offset: "; - GetByteOffset().Dump(thread); - os << " - array-length: "; - GetArrayLength().Dump(thread); - JSObject::Dump(thread, os); -} - -void JSInt16Array::Dump(JSThread *thread, std::ostream &os) const -{ - os << " - viewed-array-buffer: "; - GetViewedArrayBuffer().Dump(thread); - os << " - typed-array-name: "; - GetTypedArrayName().Dump(thread); - os << " - byte-length: "; - GetByteLength().Dump(thread); - os << " - byte-offset: "; - GetByteOffset().Dump(thread); - os << " - array-length: "; - GetArrayLength().Dump(thread); - JSObject::Dump(thread, os); -} - -void JSUint16Array::Dump(JSThread *thread, std::ostream &os) const -{ - os << " - viewed-array-buffer: "; - GetViewedArrayBuffer().Dump(thread); - os << " - typed-array-name: "; - GetTypedArrayName().Dump(thread); - os << " - byte-length: "; - GetByteLength().Dump(thread); - os << " - byte-offset: "; - GetByteOffset().Dump(thread); - os << " - array-length: "; - GetArrayLength().Dump(thread); - JSObject::Dump(thread, os); -} - -void JSInt32Array::Dump(JSThread *thread, std::ostream &os) const -{ - os << " - viewed-array-buffer: "; - GetViewedArrayBuffer().Dump(thread); - os << " - typed-array-name: "; - GetTypedArrayName().Dump(thread); - os << " - byte-length: "; - GetByteLength().Dump(thread); - os << " - byte-offset: "; - GetByteOffset().Dump(thread); - os << " - array-length: "; - GetArrayLength().Dump(thread); - JSObject::Dump(thread, os); -} - -void JSUint32Array::Dump(JSThread *thread, std::ostream &os) const -{ - os << " - viewed-array-buffer: "; - GetViewedArrayBuffer().Dump(thread); - os << " - typed-array-name: "; - GetTypedArrayName().Dump(thread); - os << " - byte-length: "; - GetByteLength().Dump(thread); - os << " - byte-offset: "; - GetByteOffset().Dump(thread); - os << " - array-length: "; - GetArrayLength().Dump(thread); - JSObject::Dump(thread, os); -} - -void JSFloat32Array::Dump(JSThread *thread, std::ostream &os) const -{ - os << " - viewed-array-buffer: "; - GetViewedArrayBuffer().Dump(thread); - os << " - typed-array-name: "; - GetTypedArrayName().Dump(thread); - os << " - byte-length: "; - GetByteLength().Dump(thread); - os << " - byte-offset: "; - GetByteOffset().Dump(thread); - os << " - array-length: "; - GetArrayLength().Dump(thread); - JSObject::Dump(thread, os); -} - -void JSFloat64Array::Dump(JSThread *thread, std::ostream &os) const -{ - os << " - viewed-array-buffer: "; - GetViewedArrayBuffer().Dump(thread); - os << " - typed-array-name: "; - GetTypedArrayName().Dump(thread); - os << " - byte-length: "; - GetByteLength().Dump(thread); - os << " - byte-offset: "; - GetByteOffset().Dump(thread); - os << " - array-length: "; - GetArrayLength().Dump(thread); -} - void JSRegExp::Dump(JSThread *thread, std::ostream &os) const { os << " - source: "; @@ -1582,34 +1421,16 @@ static void DumpObject(JSThread *thread, TaggedObject *obj, std::vectorDumpForSnapshot(thread, vec); break; case JSType::JS_TYPED_ARRAY: - JSTypedArray::Cast(obj)->DumpForSnapshot(thread, vec); - break; case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(obj)->DumpForSnapshot(thread, vec); - break; case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(obj)->DumpForSnapshot(thread, vec); - break; case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(obj)->DumpForSnapshot(thread, vec); - break; case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(obj)->DumpForSnapshot(thread, vec); - break; case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(obj)->DumpForSnapshot(thread, vec); - break; case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(obj)->DumpForSnapshot(thread, vec); - break; case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(obj)->DumpForSnapshot(thread, vec); - break; case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(obj)->DumpForSnapshot(thread, vec); - break; case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(obj)->DumpForSnapshot(thread, vec); + JSTypedArray::Cast(obj)->DumpForSnapshot(thread, vec); break; case JSType::JS_PROXY: JSProxy::Cast(obj)->DumpForSnapshot(thread, vec); @@ -1994,96 +1815,6 @@ void JSTypedArray::DumpForSnapshot([[maybe_unused]] JSThread *thread, vec.push_back(std::make_pair(CString("array-length"), GetArrayLength())); } -void JSInt8Array::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.push_back(std::make_pair(CString("viewed-array-buffer"), GetViewedArrayBuffer())); - vec.push_back(std::make_pair(CString("typed-array-name"), GetTypedArrayName())); - vec.push_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.push_back(std::make_pair(CString("byte-offset"), GetByteOffset())); - vec.push_back(std::make_pair(CString("array-length"), GetArrayLength())); -} - -void JSUint8Array::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.push_back(std::make_pair(CString("viewed-array-buffer"), GetViewedArrayBuffer())); - vec.push_back(std::make_pair(CString("typed-array-name"), GetTypedArrayName())); - vec.push_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.push_back(std::make_pair(CString("byte-offset"), GetByteOffset())); - vec.push_back(std::make_pair(CString("array-length"), GetArrayLength())); -} - -void JSUint8ClampedArray::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.push_back(std::make_pair(CString("viewed-array-buffer"), GetViewedArrayBuffer())); - vec.push_back(std::make_pair(CString("typed-array-name"), GetTypedArrayName())); - vec.push_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.push_back(std::make_pair(CString("byte-offset"), GetByteOffset())); - vec.push_back(std::make_pair(CString("array-length"), GetArrayLength())); -} - -void JSInt16Array::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.push_back(std::make_pair(CString("viewed-array-buffer"), GetViewedArrayBuffer())); - vec.push_back(std::make_pair(CString("typed-array-name"), GetTypedArrayName())); - vec.push_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.push_back(std::make_pair(CString("byte-offset"), GetByteOffset())); - vec.push_back(std::make_pair(CString("array-length"), GetArrayLength())); -} - -void JSUint16Array::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.push_back(std::make_pair(CString("viewed-array-buffer"), GetViewedArrayBuffer())); - vec.push_back(std::make_pair(CString("typed-array-name"), GetTypedArrayName())); - vec.push_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.push_back(std::make_pair(CString("byte-offset"), GetByteOffset())); - vec.push_back(std::make_pair(CString("array-length"), GetArrayLength())); -} - -void JSInt32Array::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.push_back(std::make_pair(CString("viewed-array-buffer"), GetViewedArrayBuffer())); - vec.push_back(std::make_pair(CString("typed-array-name"), GetTypedArrayName())); - vec.push_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.push_back(std::make_pair(CString("byte-offset"), GetByteOffset())); - vec.push_back(std::make_pair(CString("array-length"), GetArrayLength())); -} - -void JSUint32Array::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.push_back(std::make_pair(CString("viewed-array-buffer"), GetViewedArrayBuffer())); - vec.push_back(std::make_pair(CString("typed-array-name"), GetTypedArrayName())); - vec.push_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.push_back(std::make_pair(CString("byte-offset"), GetByteOffset())); - vec.push_back(std::make_pair(CString("array-length"), GetArrayLength())); -} - -void JSFloat32Array::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.push_back(std::make_pair(CString("viewed-array-buffer"), GetViewedArrayBuffer())); - vec.push_back(std::make_pair(CString("typed-array-name"), GetTypedArrayName())); - vec.push_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.push_back(std::make_pair(CString("byte-offset"), GetByteOffset())); - vec.push_back(std::make_pair(CString("array-length"), GetArrayLength())); -} - -void JSFloat64Array::DumpForSnapshot([[maybe_unused]] JSThread *thread, - std::vector> &vec) const -{ - vec.push_back(std::make_pair(CString("viewed-array-buffer"), GetViewedArrayBuffer())); - vec.push_back(std::make_pair(CString("typed-array-name"), GetTypedArrayName())); - vec.push_back(std::make_pair(CString("byte-length"), GetByteLength())); - vec.push_back(std::make_pair(CString("byte-offset"), GetByteOffset())); - vec.push_back(std::make_pair(CString("array-length"), GetArrayLength())); -} - void JSRegExp::DumpForSnapshot([[maybe_unused]] JSThread *thread, std::vector> &vec) const { diff --git a/ecmascript/ecma_builtins.rb b/ecmascript/ecma_builtins.rb deleted file mode 100755 index c870e57512c646f36eeacb42e2fd6225f53cfaa2..0000000000000000000000000000000000000000 --- a/ecmascript/ecma_builtins.rb +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) 2021 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. - -def ExtBuiltins.load_ecma_builtins(data) - ecma_fname = File.expand_path(File.join(File.dirname(__FILE__), 'ecma_runtime.yaml')) - builtins = YAML.load_file(ecma_fname) - builtins = JSON.parse(builtins.to_json, object_class: OpenStruct) - builtins.intrinsics.each do |intr| - new_intr = intr.signature.clone - - if !intr.signature['sig'] - new_intr['sig'] = intr.method_name - v_idx = 1 - imm_idx =2 # first imm is subcode, so other begin at 2 - new_intr.args.each_index do |i| - case new_intr.args[i] - when "any" - new_intr['sig'] << " v" + v_idx.to_s + ":in:any" - v_idx += 1 - when "acc" - next - when "u8", "i8", "u16", "i16", "u32", "i32" - new_intr['sig'] << " imm" + imm_idx.to_s + ":i32" - imm_idx += 1 - when "u64", "i64" - new_intr['sig'] << " imm" + imm_idx.to_s + ":i64" - imm_idx += 1 - when "string_id" - new_intr['sig'] << " string_id" - when "method_id" - new_intr['sig'] << " method_id" - else - raise "unknown the type in " + intr.method_name - end - end - end - - if new_intr['sig'].include?('v1:') && !new_intr['sig'].include?('v2:') - new_intr['sig'].sub!(/v1+?/, 'v') - end - - if !intr.signature['acc'] - if new_intr.ret == "any" then - new_intr['acc'] = "out:any" - elsif new_intr.ret == "void" then - new_intr['acc'] = "none" - else - raise "unknown the ret in " + intr.method_name - end - end - - if intr['exception'] == true - new_intr['exception'] = true - end - - new_intr['space'] = intr.space - - new_intr['name'] = intr.name - - data["builtins"] << new_intr - end -end \ No newline at end of file diff --git a/ecmascript/ecma_class_linker_extension.cpp b/ecmascript/ecma_class_linker_extension.cpp index ac1c552f91dcc45d6b9ea7a633c1d627058a203b..24711c50cb7b588bbc17cb2a2ef0fcd09f90930f 100644 --- a/ecmascript/ecma_class_linker_extension.cpp +++ b/ecmascript/ecma_class_linker_extension.cpp @@ -23,7 +23,6 @@ using SourceLang = panda_file::SourceLang; bool EcmaClassLinkerExtension::InitializeImpl(bool cmpStrEnabled) { - EcmaString::SetCompressedStringsEnabled(cmpStrEnabled); return true; } @@ -44,7 +43,7 @@ void EcmaClassLinkerExtension::InitClasses(EcmaVM *vm) if (objClass == nullptr) { return; } - objClass->SetObjectSize(TaggedObject::ObjectHeaderSize()); + objClass->SetObjectSize(TaggedObject::TaggedObjectSize()); objClass->SetSourceLang(SourceLang::ECMASCRIPT); objClass->SetState(Class::State::LOADED); Runtime::GetCurrent()->GetClassLinker()->AddClassRoot(ClassRoot::OBJECT, objClass); diff --git a/ecmascript/ecma_class_linker_extension.h b/ecmascript/ecma_class_linker_extension.h index 75c51ec0bc73e774503df012141d1a585f5eecb5..d9b6a68dd2fb37d4bd4a8d258b4ff82ce94bb4f1 100644 --- a/ecmascript/ecma_class_linker_extension.h +++ b/ecmascript/ecma_class_linker_extension.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMA_CLASS_LINKER_EXTENSION_H -#define PANDA_RUNTIME_ECMA_CLASS_LINKER_EXTENSION_H +#ifndef ECMASCRIPT_ECMA_CLASS_LINKER_EXTENSION_H +#define ECMASCRIPT_ECMA_CLASS_LINKER_EXTENSION_H #include "libpandafile/file_items.h" #include "include/class_linker.h" @@ -106,4 +106,4 @@ private: } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMA_CLASS_LINKER_EXTENSION_H +#endif // ECMASCRIPT_ECMA_CLASS_LINKER_EXTENSION_H diff --git a/ecmascript/ecma_exceptions.h b/ecmascript/ecma_exceptions.h index 626b45209ceba9d05c870630d07dc4e9c06f57e4..9590f7275b8e8c1346e031b5c95f4f273dd18e03 100644 --- a/ecmascript/ecma_exceptions.h +++ b/ecmascript/ecma_exceptions.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMA_EXCEPTIONS_H -#define PANDA_RUNTIME_ECMA_EXCEPTIONS_H +#ifndef ECMASCRIPT_ECMA_EXCEPTIONS_H +#define ECMASCRIPT_ECMA_EXCEPTIONS_H /* Do not add ecma special header's here */ #include "ecmascript/js_thread.h" @@ -26,4 +26,4 @@ static constexpr const char *REFERENCE_ERROR_STRING = "Lecma/ReferenceError;"; void ThrowException(JSThread *thread, const char *name, const char *msg); } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMA_EXCEPTIONS_H \ No newline at end of file +#endif // ECMASCRIPT_ECMA_EXCEPTIONS_H \ No newline at end of file diff --git a/ecmascript/ecma_global_storage-inl.h b/ecmascript/ecma_global_storage-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..7309541690c1bb02db4324c2db57b85b53a3b3e5 --- /dev/null +++ b/ecmascript/ecma_global_storage-inl.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021 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. + */ +#ifndef ECMASCRIPT_ECMA_GLOABL_STORAGE_INL_H +#define ECMASCRIPT_ECMA_GLOABL_STORAGE_INL_H + +#include "ecmascript/ecma_global_storage.h" +#include "ecmascript/mem/chunk.h" + +namespace panda::ecmascript { +inline uintptr_t EcmaGlobalStorage::NewGlobalHandleImplement(CVector *> *storage, + Node *freeList, int32_t &count, JSTaggedType value) +{ + if (count == GLOBAL_BLOCK_SIZE && freeList == nullptr) { + // alloc new block + auto block = chunk_->New>(); + storage->push_back(block); + count = count - GLOBAL_BLOCK_SIZE; + } + + // use node in block first + if (count != GLOBAL_BLOCK_SIZE) { + storage->back()->at(count).SetNext(nullptr); + storage->back()->at(count).SetObject(value); + return storage->back()->at(count++).GetObjectAddress(); + } + + // use free_list node + Node *node = freeList; + freeList = freeList->GetNext(); + node->SetNext(nullptr); + node->SetObject(value); + return node->GetObjectAddress(); +} + +inline uintptr_t EcmaGlobalStorage::NewGlobalHandle(JSTaggedType value) +{ + return NewGlobalHandleImplement(globalNodes_, freeList_, count_, value); +} + +inline void EcmaGlobalStorage::DisposeGlobalHandle(uintptr_t nodeAddr) +{ + Node *node = reinterpret_cast(nodeAddr); + node->SetObject(JSTaggedValue::Undefined().GetRawData()); + auto freeList = freeList_; + if (IsWeak(nodeAddr)) { + freeList = weakFreeList_; + } + if (freeList != nullptr) { + node->SetNext(freeList->GetNext()); + freeList->SetNext(node); + } else { + freeList = node; + } +} + +inline uintptr_t EcmaGlobalStorage::SetWeak(uintptr_t nodeAddr) +{ + auto value = reinterpret_cast(nodeAddr)->GetObject(); + DisposeGlobalHandle(nodeAddr); + return NewGlobalHandleImplement(weakGlobalNodes_, weakFreeList_, weakCount_, value); +} + +inline bool EcmaGlobalStorage::IsWeak(uintptr_t nodeAddr) const +{ + if (weakGlobalNodes_->empty()) { + return false; + } + size_t pageSize = sizeof(Node) * GLOBAL_BLOCK_SIZE; + for (size_t i = 0; i < weakGlobalNodes_->size(); i++) { + auto block = weakGlobalNodes_->at(i); + if (nodeAddr >= ToUintPtr(block) && nodeAddr < ToUintPtr(block) + pageSize) { + return true; + } + } + return false; +} +} // namespace panda::ecmascript +#endif // ECMASCRIPT_ECMA_GLOABL_STORAGE_INL_H diff --git a/ecmascript/ecma_global_storage.h b/ecmascript/ecma_global_storage.h new file mode 100644 index 0000000000000000000000000000000000000000..6250124e84aab0b00a64b93caaf77f7b31eb8b8d --- /dev/null +++ b/ecmascript/ecma_global_storage.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_ECMA_GLOABL_STORAGE_H +#define ECMASCRIPT_ECMA_GLOABL_STORAGE_H + +#include "ecmascript/js_tagged_value.h" + +#include "ecmascript/mem/c_containers.h" +#include "ecmascript/mem/chunk.h" + +namespace panda::ecmascript { +class EcmaGlobalStorage { +public: + static const int32_t GLOBAL_BLOCK_SIZE = 256; + + explicit EcmaGlobalStorage(Chunk *chunk) : chunk_(chunk) + { + ASSERT(chunk != nullptr); + globalNodes_ = chunk->New *>>(); + weakGlobalNodes_ = chunk->New *>>(); + }; + + ~EcmaGlobalStorage() + { + for (auto block : *globalNodes_) { + chunk_->Delete(block); + } + chunk_->Delete(globalNodes_); + + for (auto block : *weakGlobalNodes_) { + chunk_->Delete(block); + } + chunk_->Delete(weakGlobalNodes_); + } + + class Node { + public: + JSTaggedType GetObject() const + { + return obj_; + } + + void SetObject(JSTaggedType obj) + { + obj_ = obj; + } + + Node *GetNext() const + { + return next_; + } + + void SetNext(Node *node) + { + next_ = node; + } + + uintptr_t GetObjectAddress() const + { + return reinterpret_cast(&obj_); + } + + private: + JSTaggedType obj_; + Node *next_; + }; + + inline uintptr_t NewGlobalHandle(JSTaggedType value); + inline void DisposeGlobalHandle(uintptr_t addr); + inline uintptr_t SetWeak(uintptr_t addr); + inline bool IsWeak(uintptr_t addr) const; + + inline CVector *> *GetNodes() const + { + return globalNodes_; + } + + inline CVector *> *GetWeakNodes() const + { + return weakGlobalNodes_; + } + + inline int32_t GetCount() const + { + return count_; + } + + inline int32_t GetWeakCount() const + { + return weakCount_; + } + +private: + NO_COPY_SEMANTIC(EcmaGlobalStorage); + NO_MOVE_SEMANTIC(EcmaGlobalStorage); + + inline uintptr_t NewGlobalHandleImplement(CVector *> *storage, Node *freeList, + int32_t &count, JSTaggedType value); + + Chunk *chunk_ {nullptr}; + CVector *> *globalNodes_ {nullptr}; + int32_t count_ {GLOBAL_BLOCK_SIZE}; + Node *freeList_ {nullptr}; + CVector *> *weakGlobalNodes_ {nullptr}; + int32_t weakCount_ {GLOBAL_BLOCK_SIZE}; + Node *weakFreeList_ {nullptr}; +}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_ECMA_GLOABL_STORAGE_H diff --git a/ecmascript/ecma_handle_scope-inl.h b/ecmascript/ecma_handle_scope-inl.h index 10bc552a8aa43fda33204bfc7d2cb512ec78be28..53bbceb2cd958ece6e8cb20012929b4d0df4b0dc 100644 --- a/ecmascript/ecma_handle_scope-inl.h +++ b/ecmascript/ecma_handle_scope-inl.h @@ -13,15 +13,16 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_HANDLE_SCOPE_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_HANDLE_SCOPE_INL_H +#ifndef ECMASCRIPT_HANDLE_SCOPE_INL_H +#define ECMASCRIPT_HANDLE_SCOPE_INL_H #include "ecmascript/ecma_handle_scope.h" #include "ecmascript/js_thread.h" namespace panda::ecmascript { inline EcmaHandleScope::EcmaHandleScope(JSThread *thread) - : thread_(thread), prevNext_(thread->handleScopeStorageNext_), prevEnd_(thread->handleScopeStorageEnd_) + : thread_(thread), prevNext_(thread->handleScopeStorageNext_), prevEnd_(thread->handleScopeStorageEnd_), + prevHandleStorageIndex_(thread->currentHandleStorageIndex_) { } @@ -30,7 +31,7 @@ inline EcmaHandleScope::~EcmaHandleScope() thread_->handleScopeStorageNext_ = prevNext_; if (thread_->handleScopeStorageEnd_ != prevEnd_) { thread_->handleScopeStorageEnd_ = prevEnd_; - thread_->ShrunkHandleStorage(prevEnd_); + thread_->ShrinkHandleStorage(prevHandleStorageIndex_); } } @@ -46,4 +47,4 @@ uintptr_t EcmaHandleScope::NewHandle(JSThread *thread, JSTaggedType value) return reinterpret_cast(result); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_HANDLE_SCOPE_INL_H +#endif // ECMASCRIPT_HANDLE_SCOPE_INL_H diff --git a/ecmascript/ecma_handle_scope.h b/ecmascript/ecma_handle_scope.h index 552da05ee10e325a0db72bf94f3f7ae37001bdcc..13604c45550f81960b1767c9f9a1e16c5a3e6a59 100644 --- a/ecmascript/ecma_handle_scope.h +++ b/ecmascript/ecma_handle_scope.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_HANDLE_SCOPE_H -#define PANDA_RUNTIME_ECMASCRIPT_HANDLE_SCOPE_H +#ifndef ECMASCRIPT_HANDLE_SCOPE_H +#define ECMASCRIPT_HANDLE_SCOPE_H #include "ecmascript/js_tagged_value.h" @@ -42,9 +42,10 @@ private: JSThread *thread_; JSTaggedType *prevNext_; JSTaggedType *prevEnd_; + int prevHandleStorageIndex_{-1}; NO_COPY_SEMANTIC(EcmaHandleScope); NO_MOVE_SEMANTIC(EcmaHandleScope); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_HANDLE_SCOPE_H +#endif // ECMASCRIPT_HANDLE_SCOPE_H diff --git a/ecmascript/ecma_heap_manager_helper.h b/ecmascript/ecma_heap_manager_helper.h index 228be789457515f6c82230669c2d371bc6370fcd..bb3710fcc75900387f0e382474aa02e6ca631691 100644 --- a/ecmascript/ecma_heap_manager_helper.h +++ b/ecmascript/ecma_heap_manager_helper.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_HEAPMANAGER_HELPER_H -#define PANDA_RUNTIME_ECMASCRIPT_HEAPMANAGER_HELPER_H +#ifndef ECMASCRIPT_HEAPMANAGER_HELPER_H +#define ECMASCRIPT_HEAPMANAGER_HELPER_H namespace panda::ecmascript { class EcmaHeapManagerHelper { @@ -62,4 +62,4 @@ private: JSThread *thread_; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_HEAPMANAGER_HELPER_H +#endif // ECMASCRIPT_HEAPMANAGER_HELPER_H diff --git a/ecmascript/ecma_isa.yaml b/ecmascript/ecma_isa.yaml new file mode 100644 index 0000000000000000000000000000000000000000..56ca07bf8660434a931daac952ce84949a656420 --- /dev/null +++ b/ecmascript/ecma_isa.yaml @@ -0,0 +1,564 @@ +# Copyright (c) 2021 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. + +prefixes: + - name: ecma + description: Extension for ecma support. + +groups: + - title: Ecma extension intrunctions + description: Ecma extension intrunctions with prefix ecam + verification: + - none + exceptions: + - x_none + properties: + - acc_read + - acc_write + namespace: ecmascript + pseudo: | + acc = ecma_op(acc, operand_0, ..., operands_n) + semantics: | + skip + instructions: + - sig: ecma.ldnan + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldinfinity + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldglobalthis + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldundefined + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldnull + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldsymbol + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldglobal + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldtrue + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldfalse + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.throwdyn + acc: in:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.typeofdyn + acc: inout:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldlexenvdyn + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.poplexenvdyn + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.getunmappedargs + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.getpropiterator + acc: inout:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.asyncfunctionenter + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldhole + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.returnundefined + acc: none + prefix: ecma + format: [pref_op_none] + - sig: ecma.createemptyobject + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.createemptyarray + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.getiterator + acc: inout:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.throwthrownotexists + acc: none + prefix: ecma + format: [pref_op_none] + - sig: ecma.throwpatternnoncoercible + acc: none + prefix: ecma + format: [pref_op_none] + - sig: ecma.ldhomeobject + acc: out:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.throwdeletesuperproperty + acc: none + prefix: ecma + format: [pref_op_none] + - sig: ecma.debugger + acc: none + prefix: ecma + format: [pref_op_none] + - sig: ecma.add2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.sub2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.mul2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.div2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.mod2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.eqdyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.noteqdyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.lessdyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.lesseqdyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.greaterdyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.greatereqdyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.shl2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.shr2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.ashr2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.and2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.or2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.xor2dyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.tonumber v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.negdyn v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.notdyn v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.incdyn v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.decdyn v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.expdyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.isindyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.instanceofdyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.strictnoteqdyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.stricteqdyn v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.resumegenerator v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.getresumemode v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.creategeneratorobj v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.throwconstassignment v:in:top + acc: none + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.gettemplateobject v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.getnextpropname v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.callarg0dyn v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.throwifnotobject v:in:top + acc: none + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.iternext v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.closeiterator v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.copymodule v:in:top + acc: out:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.supercallspread v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v_8] + - sig: ecma.delobjprop v1:in:top, v2:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.newobjspreaddyn v1:in:top, v2:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.createiterresultobj v1:in:top, v2:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.suspendgenerator v1:in:top, v2:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.asyncfunctionawaituncaught v1:in:top, v2:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.throwundefinedifhole v1:in:top, v2:in:top + acc: none + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.callarg1dyn v1:in:top, v2:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.copydataproperties v1:in:top, v2:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.starrayspread v1:in:top, v2:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.getiteratornext v1:in:top, v2:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.setobjectwithproto v1:in:top, v2:in:top + acc: none + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.ldobjbyvalue v1:in:top, v2:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.stobjbyvalue v1:in:top, v2:in:top + acc: in:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.stownbyvalue v1:in:top, v2:in:top + acc: in:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.ldsuperbyvalue v1:in:top, v2:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.stsuperbyvalue v1:in:top, v2:in:top + acc: in:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.ldobjbyindex v:in:top, imm + acc: out:top + prefix: ecma + format: [pref_op_v_8_imm_32] + - sig: ecma.stobjbyindex v:in:top, imm + acc: in:top + prefix: ecma + format: [pref_op_v_8_imm_32] + - sig: ecma.stownbyindex v:in:top, imm + acc: in:top + prefix: ecma + format: [pref_op_v_8_imm_32] + - sig: ecma.callspreaddyn v1:in:top, v2:in:top, v3:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8_v3_8] + - sig: ecma.asyncfunctionresolve v1:in:top, v2:in:top, v3:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8_v3_8] + - sig: ecma.asyncfunctionreject v1:in:top, v2:in:top, v3:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8_v3_8] + - sig: ecma.callargs2dyn v1:in:top, v2:in:top, v3:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8_v3_8] + - sig: ecma.callargs3dyn v1:in:top, v2:in:top, v3:in:top, v4:in:top + acc: out:top + prefix: ecma + format: [pref_op_v1_8_v2_8_v3_8_v4_8] + - sig: ecma.definegettersetterbyvalue v1:in:top, v2:in:top, v3:in:top, v4:in:top + acc: inout:top + prefix: ecma + format: [pref_op_v1_8_v2_8_v3_8_v4_8] + - sig: ecma.newobjdynrange imm, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_imm_16_v_8] + - sig: ecma.callirangedyn imm, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_imm_16_v_8] + - sig: ecma.callithisrangedyn imm, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_imm_16_v_8] + - sig: ecma.supercall imm, v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_imm_16_v_8] + - sig: ecma.createobjectwithexcludedkeys imm, v1:in:top, v2:in:top + acc: out:top + prefix: ecma + format: [pref_op_imm_16_v1_8_v2_8] + - sig: ecma.definefuncdyn method_id, imm, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_id_16_imm_16_v_8] + properties: [method_id] + - sig: ecma.definencfuncdyn method_id, imm, v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_id_16_imm_16_v_8] + properties: [method_id] + - sig: ecma.definegeneratorfunc method_id, imm, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_id_16_imm_16_v_8] + properties: [method_id] + - sig: ecma.defineasyncfunc method_id, imm, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_id_16_imm_16_v_8] + properties: [method_id] + - sig: ecma.definemethod method_id, imm, v:in:top + acc: inout:top + prefix: ecma + format: [pref_op_id_16_imm_16_v_8] + properties: [method_id] + - sig: ecma.newlexenvdyn imm + acc: out:top + prefix: ecma + format: [pref_op_imm_16] + - sig: ecma.copyrestargs imm + acc: out:top + prefix: ecma + format: [pref_op_imm_16] + - sig: ecma.createarraywithbuffer imm + acc: out:top + prefix: ecma + format: [pref_op_imm_16] + - sig: ecma.createobjecthavingmethod imm + acc: inout:top + prefix: ecma + format: [pref_op_imm_16] + - sig: ecma.throwifsupernotcorrectcall imm + acc: in:top + prefix: ecma + format: [pref_op_imm_16] + - sig: ecma.createobjectwithbuffer imm + acc: out:top + prefix: ecma + format: [pref_op_imm_16] + - sig: ecma.ldlexvardyn imm1, imm2 + acc: out:top + prefix: ecma + format: [pref_op_imm1_4_imm2_4] + - sig: ecma.ldlexvardyn imm1, imm2 + acc: out:top + prefix: ecma + format: [pref_op_imm1_8_imm2_8] + - sig: ecma.ldlexvardyn imm1, imm2 + acc: out:top + prefix: ecma + format: [pref_op_imm1_16_imm2_16] + - sig: ecma.stlexvardyn imm1, imm2, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_imm1_4_imm2_4_v_8] + - sig: ecma.stlexvardyn imm1, imm2, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_imm1_8_imm2_8_v_8] + - sig: ecma.stlexvardyn imm1, imm2, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_imm1_16_imm2_16_v_8] + - sig: ecma.defineclasswithbuffer method_id, imm1, imm2, v1:in:top, v2:in:top + acc: out:top + prefix: ecma + format: [pref_op_id_16_imm1_16_imm2_16_v1_8_v2_8] + properties: [method_id] + - sig: ecma.importmodule string_id + acc: out:top + prefix: ecma + format: [pref_op_id_32] + properties: [string_id] + - sig: ecma.stmodulevar string_id + acc: in:top + prefix: ecma + format: [pref_op_id_32] + properties: [string_id] + - sig: ecma.tryldglobalbyname string_id + acc: out:top + prefix: ecma + format: [pref_op_id_32] + properties: [string_id] + - sig: ecma.trystglobalbyname string_id + acc: in:top + prefix: ecma + format: [pref_op_id_32] + properties: [string_id] + - sig: ecma.ldglobalvar string_id + acc: out:top + prefix: ecma + format: [pref_op_id_32] + properties: [string_id] + - sig: ecma.stglobalvar string_id + acc: in:top + prefix: ecma + format: [pref_op_id_32] + properties: [string_id] + - sig: ecma.ldobjbyname string_id, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_id_32_v_8] + properties: [string_id] + - sig: ecma.stobjbyname string_id, v:in:top + acc: in:top + prefix: ecma + format: [pref_op_id_32_v_8] + properties: [string_id] + - sig: ecma.stownbyname string_id, v:in:top + acc: in:top + prefix: ecma + format: [pref_op_id_32_v_8] + properties: [string_id] + - sig: ecma.ldsuperbyname string_id, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_id_32_v_8] + properties: [string_id] + - sig: ecma.stsuperbyname string_id, v:in:top + acc: in:top + prefix: ecma + format: [pref_op_id_32_v_8] + properties: [string_id] + - sig: ecma.ldmodvarbyname string_id, v:in:top + acc: out:top + prefix: ecma + format: [pref_op_id_32_v_8] + properties: [string_id] + - sig: ecma.createregexpwithliteral string_id, imm + acc: out:top + prefix: ecma + format: [pref_op_id_32_imm_8] + properties: [string_id] + - sig: ecma.istrue + acc: inout:top + prefix: ecma + format: [pref_op_none] + - sig: ecma.isfalse + acc: inout:top + prefix: ecma + format: [pref_op_none] diff --git a/ecmascript/ecma_language_context.h b/ecmascript/ecma_language_context.h index ed49410f49ba4e5f0be5140a64c54dad7796e853..52c5eb7388c778c0e506430cf396b6ed93f17ef6 100644 --- a/ecmascript/ecma_language_context.h +++ b/ecmascript/ecma_language_context.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_LANGUAGE_CONTEXT_H -#define PANDA_RUNTIME_ECMASCRIPT_LANGUAGE_CONTEXT_H +#ifndef ECMASCRIPT_LANGUAGE_CONTEXT_H +#define ECMASCRIPT_LANGUAGE_CONTEXT_H #include "ecmascript/common.h" #include "include/language_context.h" @@ -264,4 +264,4 @@ public: }; } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_LANGUAGE_CONTEXT_H +#endif // ECMASCRIPT_LANGUAGE_CONTEXT_H diff --git a/ecmascript/ecma_macros.h b/ecmascript/ecma_macros.h index 8de569ae14afef381de65592ffcd6cde1ded84fb..7c4d37a34debab2ee806d415856696e5073ea9a9 100644 --- a/ecmascript/ecma_macros.h +++ b/ecmascript/ecma_macros.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_ECMA_MACROS_H -#define PANDA_RUNTIME_ECMASCRIPT_ECMA_MACROS_H +#ifndef ECMASCRIPT_ECMA_MACROS_H +#define ECMASCRIPT_ECMA_MACROS_H #include "ecmascript/common.h" #include "ecmascript/ecma_vm.h" @@ -55,7 +55,7 @@ /* dynamically-typed languages like JavaScript. So we simply skip the read-barrier. */ \ return JSTaggedValue(Barriers::GetDynValue(this, offset)); \ } \ - template \ + template \ void Set##name(const JSThread *thread, JSHandle value, BarrierMode mode = WRITE_BARRIER) \ { \ if (mode == WRITE_BARRIER) { \ @@ -236,7 +236,7 @@ THROW_TYPE_ERROR_AND_RETURN(thread, "Not a Date Object", JSTaggedValue::Exception()); \ } \ if (std::isnan(JSDate::Cast(msg->GetTaggedObject())->GetTimeValue().GetDouble())) { \ - return thread->GetEcmaVM()->GetFactory()->NewFromString("Invalid Date").GetTaggedValue(); \ + return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Invalid Date").GetTaggedValue(); \ } \ return JSDate::Cast(msg->GetTaggedObject())->name(thread); \ } @@ -313,34 +313,31 @@ } while (false) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define RETURN_REJECT_PROMISE_IF_ABRUPT(thread, value, capability) \ - do { \ - ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory(); \ - const GlobalEnvConstants *globalConst = thread->GlobalConstants(); \ - if (value.GetTaggedValue().IsCompletionRecord()) { \ - JSHandle record = JSHandle::Cast(value); \ - if (record->IsThrow()) { \ - JSHandle reject(thread, capability->GetReject()); \ - array_size_t length = 1; \ - JSHandle array = objectFactory->NewTaggedArray(length); \ - array->Set(thread, 0, record->GetValue()); \ - JSHandle undefine = globalConst->GetHandledUndefined(); \ - JSTaggedValue taggedValue = JSFunction::Call(thread, reject, undefine, array); \ - RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, taggedValue); \ - return capability->GetPromise(); \ - } \ - } \ - if (thread->HasPendingException()) { \ - thread->ClearException(); \ - JSHandle reject(thread, capability->GetReject()); \ - array_size_t length = 1; \ - JSHandle array = objectFactory->NewTaggedArray(length); \ - array->Set(thread, 0, value); \ - JSHandle undefined = globalConst->GetHandledUndefined(); \ - JSTaggedValue taggedValue = JSFunction::Call(thread, reject, undefined, array); \ - RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, taggedValue); \ - return capability->GetPromise(); \ - } \ +#define RETURN_REJECT_PROMISE_IF_ABRUPT(thread, value, capability) \ + do { \ + const GlobalEnvConstants *globalConst = thread->GlobalConstants(); \ + if (value.GetTaggedValue().IsCompletionRecord()) { \ + JSHandle record = JSHandle::Cast(value); \ + if (record->IsThrow()) { \ + JSHandle reject(thread, capability->GetReject()); \ + JSHandle undefine = globalConst->GetHandledUndefined(); \ + InternalCallParams *arg = thread->GetInternalCallParams(); \ + arg->MakeArgv(record->GetValue()); \ + JSTaggedValue res = JSFunction::Call(thread, reject, undefine, 1, arg->GetArgv()); \ + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, res); \ + return capability->GetPromise(); \ + } \ + } \ + if (thread->HasPendingException()) { \ + thread->ClearException(); \ + JSHandle reject(thread, capability->GetReject()); \ + JSHandle undefined = globalConst->GetHandledUndefined(); \ + InternalCallParams *arg = thread->GetInternalCallParams(); \ + arg->MakeArgv(value); \ + JSTaggedValue res = JSFunction::Call(thread, reject, undefined, 1, arg->GetArgv()); \ + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, res); \ + return capability->GetPromise(); \ + } \ } while (false) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -399,4 +396,4 @@ visitor(this, ObjectSlot(ToUintPtr(this) + BEGIN_OFFSET), ObjectSlot(ToUintPtr(this) + SIZE)); \ } -#endif // PANDA_RUNTIME_ECMASCRIPT_ECMA_MACROS_H +#endif // ECMASCRIPT_ECMA_MACROS_H diff --git a/ecmascript/ecma_module.h b/ecmascript/ecma_module.h index aa3aa2562cb43d80020efb89b62b36d24353ceb7..707724d782f69a70a61e4c9b24ee026ad3e66bd0 100644 --- a/ecmascript/ecma_module.h +++ b/ecmascript/ecma_module.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_ECMA_MODULE_H -#define PANDA_RUNTIME_ECMASCRIPT_ECMA_MODULE_H +#ifndef ECMASCRIPT_ECMA_MODULE_H +#define ECMASCRIPT_ECMA_MODULE_H #include "ecmascript/js_object.h" #include "ecmascript/js_tagged_value-inl.h" diff --git a/ecmascript/ecma_runtime.yaml b/ecmascript/ecma_runtime.yaml deleted file mode 100644 index 07b39ccec251905563b9fbeb85394a26db537883..0000000000000000000000000000000000000000 --- a/ecmascript/ecma_runtime.yaml +++ /dev/null @@ -1,1480 +0,0 @@ -# Copyright (c) 2021 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. - -intrinsics_namespace: panda::ecmascript::intrinsics - -intrinsics: -- name: Ldnan - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldnan - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::Ldnan - -- name: Ldinfinity - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldinfinity - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::Ldinfinity - -- name: Ldglobalthis - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldglobalthis - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::Ldglobalthis - -- name: Ldundefined - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldundefined - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::Ldundefined - -- name: Ldboolean - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldboolean - static: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::Ldboolean - -- name: Ldnumber - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldnumber - static: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::Ldnumber - -- name: Ldstring - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldstring - static: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::Ldstring - -- name: Ldbigint - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldbigint - static: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::Ldbigint - -- name: Ldnull - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldnull - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::Ldnull - -- name: Ldsymbol - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldsymbol - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::Ldsymbol - -- name: Ldobject - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldobject - static: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::Ldobject - -- name: Ldfunction - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldfunction - static: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::Ldfunction - -- name: Ldglobal - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldglobal - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::Ldglobal - -- name: Ldtrue - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldtrue - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::Ldtrue - -- name: Ldfalse - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldfalse - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::Ldfalse - -- name: Add2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: add2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::Add2Dyn - -- name: Sub2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: sub2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::Sub2Dyn - -- name: Mul2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: mul2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::Mul2Dyn - -- name: Div2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: div2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::Div2Dyn - -- name: Mod2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: mod2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::Mod2Dyn - -- name: EqDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: eqDyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::EqDyn - -- name: NotEqDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: noteqDyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::NotEqDyn - -- name: LessDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: lessDyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::LessDyn - -- name: LessEqDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: lesseqDyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::LessEqDyn - -- name: GreaterDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: greaterDyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::GreaterDyn - -- name: GreaterEqDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: greatereqDyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::GreaterEqDyn - -- name: LdObjByValue - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldObjByValue - static: true - exception: true - signature: - ret: any - args: [u16, any, any] - impl: panda::ecmascript::intrinsics::LdObjByValue - -- name: TryLdGlobalByValue - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: tryLdGlobalByValue - static: true - exception: true - signature: - ret: any - args: [u16, any] - impl: panda::ecmascript::intrinsics::TryLdGlobalByValue - -- name: StObjByValue - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: stObjByValue - static: true - exception: true - signature: - ret: void - args: [u16, any, any, acc] - impl: panda::ecmascript::intrinsics::StObjByValue - -- name: Shl2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: shl2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::Shl2Dyn - -- name: Shr2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: shr2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::Shr2Dyn - -- name: Ashr2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ashr2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::Ashr2Dyn - -- name: And2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: and2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::And2Dyn - -- name: Or2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: or2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::Or2Dyn - -- name: Xor2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: xor2Dyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::Xor2Dyn - -- name: Tonumber - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: tonumber - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::Tonumber - -- name: NegDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: negDyn - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::NegDyn - -- name: NotDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: notDyn - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::NotDyn - -- name: IncDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: incDyn - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::IncDyn - -- name: DecDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: decDyn - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::DecDyn - -- name: ThrowDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: throwDyn - static: true - exception: true - signature: - ret: void - args: [acc] - impl: panda::ecmascript::intrinsics::ThrowDyn - -- name: Delobjprop - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: delobjprop - static: true - exception: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::Delobjprop - -- name: Defineglobalvar - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: defineglobalvar - static: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::Defineglobalvar - -- name: Definelocalvar - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: definelocalvar - static: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::Definelocalvar - -- name: Definefuncexpr - class_name: Ecmascript.Intrinsics - space: ecmascript - method_name: definefuncexpr - static: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::Definefuncexpr - -- name: DefinefuncDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: definefuncDyn - static: true - exception: true - signature: - ret: any - args: [method_id, any] - impl: panda::ecmascript::intrinsics::DefinefuncDyn - -- name: DefineNCFuncDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: defineNCFuncDyn - static: true - exception: true - signature: - ret: any - args: [method_id, any, acc] - impl: panda::ecmascript::intrinsics::DefineNCFuncDyn - -- name: NewobjDynrange - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: newobjDynrange - static: true - exception: true - signature: - ret: any - args: [u16, any] - impl: panda::ecmascript::intrinsics::NewobjDynrange - -- name: RefeqDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: refeqDyn - static: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::RefeqDyn - -- name: ExpDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: expDyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::ExpDyn - -- name: TypeofDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: typeofDyn - static: true - signature: - ret: any - args: [acc] - impl: panda::ecmascript::intrinsics::TypeofDyn - -- name: Callruntimerange - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: callruntimerange - static: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::Callruntimerange - -- name: IsinDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: isinDyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::IsinDyn - -- name: InstanceofDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: instanceofDyn - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::InstanceofDyn - -- name: StrictNotEqDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: strictNotEqDyn - static: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::StrictNotEqDyn - -- name: StrictEqDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: strictEqDyn - static: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::StrictEqDyn - -- name: NewobjspreadDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: newobjspreadDyn - static: true - exception: true - signature: - ret: any - args: [any, any, acc] - impl: panda::ecmascript::intrinsics::NewobjspreadDyn - -- name: CallspreadDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: callspreadDyn - static: true - exception: true - signature: - ret: any - args: [any, any, any] - impl: panda::ecmascript::intrinsics::CallspreadDyn - -- name: NewlexenvDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: newlexenvDyn - static: true - exception: true - signature: - ret: any - args: [u16] - impl: panda::ecmascript::intrinsics::NewlexenvDyn - -- name: StLexVarDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: StLexVarDyn - static: true - exception: true - signature: - ret: void - args: [u16, u16, any] - impl: panda::ecmascript::intrinsics::StLexVarDyn - -- name: LdLexVarDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: LdLexVarDyn - static: true - exception: true - signature: - ret: any - args: [u16, u16] - impl: panda::ecmascript::intrinsics::LdLexVarDyn - -- name: LdlexenvDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldlexenvDyn - static: true - exception: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::LdlexenvDyn - -- name: PopLexenvDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: popLexenvDyn - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::PopLexenvDyn - -- name: GetUnmappedArgs - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: getUnmappedArgs - static: true - exception: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::GetUnmappedArgs - -- name: Toboolean - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: toboolean - static: true - signature: - ret: any - args: [acc] - impl: panda::ecmascript::intrinsics::Toboolean - -- name: GetPropIterator - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: getPropIterator - static: true - exception: true - signature: - ret: any - args: [acc] - impl: panda::ecmascript::intrinsics::GetPropIterator - -- name: DefineGeneratorFunc - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: defineGeneratorFunc - static: true - exception: true - signature: - ret: any - args: [method_id, any] - impl: panda::ecmascript::intrinsics::DefineGeneratorFunc - -- name: CreateIterResultObj - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: createIterResultObj - static: true - exception: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::CreateIterResultObj - -- name: SuspendGenerator - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: suspendGenerator - static: true - exception: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::SuspendGenerator - -- name: ResumeGenerator - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: resumeGenerator - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::ResumeGenerator - -- name: GetResumeMode - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: getResumeMode - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::GetResumeMode - -- name: CreateGeneratorObj - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: createGeneratorObj - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::CreateGeneratorObj - -- name: DefineAsyncFunc - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: defineAsyncFunc - static: true - exception: true - signature: - ret: any - args: [method_id, any] - impl: panda::ecmascript::intrinsics::DefineAsyncFunc - -- name: AsyncFunctionEnter - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: asyncFunctionEnter - static: true - exception: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::AsyncFunctionEnter - -- name: AsyncFunctionAwaitUncaught - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: asyncFunctionAwaitUncaught - static: true - exception: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::AsyncFunctionAwaitUncaught - -- name: AsyncFunctionResolve - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: asyncFunctionResolve - static: true - exception: true - signature: - ret: any - args: [any, any, any] - impl: panda::ecmascript::intrinsics::AsyncFunctionResolve - -- name: AsyncFunctionReject - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: asyncFunctionReject - exception: true - static: true - signature: - ret: any - args: [any, any, any] - impl: panda::ecmascript::intrinsics::AsyncFunctionReject - -- name: ThrowUndefined - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: throwUndefined - static: true - exception: true - signature: - ret: void - args: [any] - impl: panda::ecmascript::intrinsics::ThrowUndefined - -- name: ThrowConstAssignment - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: throwConstAssignment - static: true - exception: true - signature: - ret: void - args: [any] - impl: panda::ecmascript::intrinsics::ThrowConstAssignment - -- name: ThrowUndefinedIfHole - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: throwUndefinedIfHole - static: true - exception: true - signature: - ret: void - args: [any, any] - impl: panda::ecmascript::intrinsics::ThrowUndefinedIfHole - -- name: Copyrestargs - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: copyrestargs - static: true - exception: true - signature: - ret: any - args: [u16] - impl: panda::ecmascript::intrinsics::Copyrestargs - -- name: LdHole - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ldHole - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::LdHole - -- name: TryStGlobalByValue - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: tryStGlobalByValue - exception: true - static: true - signature: - ret: void - args: [u16, any, acc] - impl: panda::ecmascript::intrinsics::TryStGlobalByValue - -- name: GetTemplateObject - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: getTemplateObject - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::GetTemplateObject - -- name: TryLdGlobalByName - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: TryLdGlobalByName - static: true - exception: true - signature: - ret: any - args: [string_id, u16] - impl: panda::ecmascript::intrinsics::TryLdGlobalByName - -- name: TryStGlobalByName - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: TryStGlobalByName - static: true - exception: true - signature: - ret: void - args: [string_id, u16, acc] - impl: panda::ecmascript::intrinsics::TryStGlobalByName - -- name: LdGlobalVar - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: LdGlobalVar - static: true - exception: true - signature: - ret: any - args: [string_id, u16] - impl: panda::ecmascript::intrinsics::LdGlobalVar - -- name: StGlobalVar - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: StGlobalVar - static: true - exception: true - signature: - ret: void - args: [string_id, u16, acc] - impl: panda::ecmascript::intrinsics::StGlobalVar - -- name: LdObjByName - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: LdObjByName - static: true - exception: true - signature: - ret: any - args: [string_id, u16, any] - impl: panda::ecmascript::intrinsics::LdObjByName - -- name: StObjByName - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: StObjByName - static: true - exception: true - signature: - ret: void - args: [string_id, u16, any, acc] - impl: panda::ecmascript::intrinsics::StObjByName - -- name: LdObjByIndex - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: LdObjByIndex - static: true - exception: true - signature: - ret: any - args: [u16, any, any] - impl: panda::ecmascript::intrinsics::LdObjByIndex - -- name: StObjByIndex - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: StObjByIndex - static: true - exception: true - signature: - ret: void - args: [u16, any, any, acc] - impl: panda::ecmascript::intrinsics::StObjByIndex - -- name: GetNextPropName - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: getnextpropname - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::GetNextPropName - -- name: ReturnUndefined - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ReturnUndefined - static: true - signature: - ret: void - args: [] - impl: panda::ecmascript::intrinsics::ReturnUndefined - -- name: Call0Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: Call0Dyn - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::CallArg0Dyn - -- name: Call1Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: Call1Dyn - static: true - exception: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::CallArg1Dyn - -- name: Call2Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: Call2Dyn - static: true - exception: true - signature: - ret: any - args: [any, any, any] - impl: panda::ecmascript::intrinsics::CallArgs2Dyn - -- name: Call3Dyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: Call3Dyn - static: true - exception: true - signature: - ret: any - args: [any, any, any, any] - impl: panda::ecmascript::intrinsics::CallArgs3Dyn - -- name: CalliRangeDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: CalliRangeDyn - static: true - exception: true - signature: - ret: any - args: [u16, any] - impl: panda::ecmascript::intrinsics::CalliRangeDyn - -- name: CalliThisRangeDyn - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: CalliThisRangeDyn - static: true - exception: true - signature: - ret: any - args: [u16, any] - impl: panda::ecmascript::intrinsics::CalliThisRangeDyn - -- name: CreateEmptyObject - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: createemptyobject - static: true - exception: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::CreateEmptyObject - -- name: CreateObjectWithBuffer - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: createobjectwithbuffer - static: true - exception: true - signature: - ret: any - args: [u16] - impl: panda::ecmascript::intrinsics::CreateObjectWithBuffer - -- name: CopyDataProperties - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: copydataproperties - static: true - exception: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::CopyDataProperties - -- name: DefineGetterSetterByValue - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: definegettersetterbyvalue - static: true - exception: true - signature: - ret: any - args: [any, any, any, any, acc] - impl: panda::ecmascript::intrinsics::DefineGetterSetterByValue - -- name: CreateEmptyArray - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: createemptyarray - static: true - exception: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::CreateEmptyArray - -- name: CreateArrayWithBuffer - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: createarraywithbuffer - static: true - exception: true - signature: - ret: any - args: [u16] - impl: panda::ecmascript::intrinsics::CreateArrayWithBuffer - -- name: StOwnByName - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: StOwnByName - static: true - exception: true - signature: - ret: void - args: [string_id, u16, any, acc] - impl: panda::ecmascript::intrinsics::StOwnByName - -- name: StOwnByIndex - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: StOwnByIndex - static: true - exception: true - signature: - ret: void - args: [u16, any, any, acc] - impl: panda::ecmascript::intrinsics::StOwnByIndex - -- name: StOwnByValue - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: StOwnByValue - static: true - exception: true - signature: - ret: void - args: [u16, any, any, acc] - impl: panda::ecmascript::intrinsics::StOwnByValue - -- name: StArraySpread - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: starrayspread - static: true - exception: true - signature: - ret: any - args: [any, any, acc] - impl: panda::ecmascript::intrinsics::StArraySpread - -- name: GetIterator - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: GetIterator - static: true - exception: true - signature: - ret: any - args: [acc] - impl: panda::ecmascript::intrinsics::GetIterator - -- name: ThrowIfNotObject - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ThrowIfNotObject - static: true - exception: true - signature: - ret: void - args: [any] - impl: panda::ecmascript::intrinsics::ThrowIfNotObject - -- name: ThrowThrowNotExists - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ThrowThrowNotExists - static: true - exception: true - signature: - ret: void - args: [] - impl: panda::ecmascript::intrinsics::ThrowThrowNotExists - -- name: CreateObjectWithExcludedKeys - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: CreateObjectWithExcludedKeys - static: true - signature: - ret: any - args: [u16, any, any] - impl: panda::ecmascript::intrinsics::CreateObjectWithExcludedKeys - -- name: ThrowPatternNonCoercible - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ThrowPatternNonCoercible - static: true - exception: true - signature: - ret: void - args: [] - impl: panda::ecmascript::intrinsics::ThrowPatternNonCoercible - -- name: IterNext - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: IterNext - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::IterNext - -- name: GetIteratorNext - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: GetIteratorNext - static: true - exception: true - signature: - ret: any - args: [any, any] - impl: panda::ecmascript::intrinsics::GetIteratorNext - -- name: CloseIterator - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: CloseIterator - static: true - exception: true - signature: - ret: any - args: [any] - impl: panda::ecmascript::intrinsics::CloseIterator - -- name: ImportModule - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ImportModule - static: true - exception: true - signature: - ret: any - args: [string_id] - impl: panda::ecmascript::intrinsics::ImportModule - -- name: StModuleVar - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: StModuleVar - static: true - exception: true - signature: - ret: void - args: [string_id, acc] - impl: panda::ecmascript::intrinsics::StModuleVar - -- name: CopyModule - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: CopyModule - static: true - exception: true - signature: - ret: void - args: [any] - impl: panda::ecmascript::intrinsics::CopyModule - -- name: LdModvarByName - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: LdModvarByName - static: true - exception: true - signature: - ret: any - args: [string_id, u16, any] - impl: panda::ecmascript::intrinsics::LdModvarByName - -- name: DefineClassWithBuffer - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: DefineClassWithBuffer - static: true - exception: true - signature: - ret: any - args: [method_id, u16, any, any] - impl: panda::ecmascript::intrinsics::DefineClassWithBuffer - -- name: SuperCall - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: SuperCall - static: true - exception: true - signature: - ret: any - args: [u16, any, acc] - impl: panda::ecmascript::intrinsics::SuperCall - -- name: SuperCallSpread - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: SuperCallSpread - static: true - exception: true - signature: - ret: any - args: [any, acc] - impl: panda::ecmascript::intrinsics::SuperCallSpread - -- name: DefineMethod - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: defineMethod - static: true - exception: true - signature: - ret: any - args: [method_id, any, acc] - impl: panda::ecmascript::intrinsics::DefineMethod - -- name: LdSuperByName - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: LdSuperByName - static: true - exception: true - signature: - ret: any - args: [string_id, u16, any] - impl: panda::ecmascript::intrinsics::LdSuperByName - -- name: StSuperByName - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: StSuperByName - static: true - exception: true - signature: - ret: void - args: [string_id, u16, any, acc] - impl: panda::ecmascript::intrinsics::StSuperByName - -- name: StSuperByValue - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: StSuperByValue - static: true - exception: true - signature: - ret: void - args: [u16, any, any, acc] - impl: panda::ecmascript::intrinsics::StSuperByValue - -- name: LdSuperByValue - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: LdSuperByValue - static: true - exception: true - signature: - ret: any - args: [u16, any, any] - impl: panda::ecmascript::intrinsics::LdSuperByValue - -- name: CreateObjectHavingMethod - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: createobjecthavingmethod - static: true - exception: true - signature: - ret: any - args: [u16, acc] - impl: panda::ecmascript::intrinsics::CreateObjectHavingMethod - -- name: ThrowIfSuperNotCorrectCall - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ThrowIfSuperNotCorrectCall - static: true - signature: - ret: void - args: [u16, acc] - impl: panda::ecmascript::intrinsics::ThrowIfSuperNotCorrectCall - -- name: LdHomeObject - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: LdHomeObject - static: true - signature: - ret: any - args: [] - impl: panda::ecmascript::intrinsics::LdHomeObject - -- name: SetObjectWithProto - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: setobjectwithproto - static: true - exception: true - signature: - ret: void - args: [any, any] - impl: panda::ecmascript::intrinsics::SetObjectWithProto - -- name: ThrowDeleteSuperProperty - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: ThrowDeleteSuperProperty - static: true - exception: true - signature: - ret: void - args: [] - impl: panda::ecmascript::intrinsics::ThrowDeleteSuperProperty - -- name: Debugger - space: ecmascript - class_name: Ecmascript.Intrinsics - method_name: debugger - static: true - signature: - ret: void - args: [] - impl: panda::ecmascript::intrinsics::Debugger diff --git a/ecmascript/ecma_runtime_call_info.h b/ecmascript/ecma_runtime_call_info.h index ff24b99ddf09fa80760d6d1993eb568570ccd667..c7c557efb4c2f7185feeb8fdf21ae9b01c54da7f 100644 --- a/ecmascript/ecma_runtime_call_info.h +++ b/ecmascript/ecma_runtime_call_info.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_ECMASCRIPT_ECMA_RUNTIM_CALL_INFO_H -#define PANDA_ECMASCRIPT_ECMA_RUNTIM_CALL_INFO_H +#ifndef ECMASCRIPT_ECMA_RUNTIM_CALL_INFO_H +#define ECMASCRIPT_ECMA_RUNTIM_CALL_INFO_H #include @@ -125,4 +125,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_ECMASCRIPT_ECMA_RUNTIM_CALL_INFO_H \ No newline at end of file +#endif // ECMASCRIPT_ECMA_RUNTIM_CALL_INFO_H \ No newline at end of file diff --git a/ecmascript/ecma_string-inl.h b/ecmascript/ecma_string-inl.h index 19afd4cf02d1600762aa1c09addc2e9c5ba9f651..5cffa1c1b1eaabc26f13cfeb27c8d6fb80082cbb 100644 --- a/ecmascript/ecma_string-inl.h +++ b/ecmascript/ecma_string-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_STRING_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_STRING_INL_H +#ifndef ECMASCRIPT_STRING_INL_H +#define ECMASCRIPT_STRING_INL_H #include "ecmascript/ecma_string.h" #include "ecmascript/ecma_vm.h" @@ -47,14 +47,14 @@ inline EcmaString *EcmaString::CreateEmptyString(const EcmaVM *vm) } /* static */ -inline EcmaString *EcmaString::CreateFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len, const EcmaVM *vm) +inline EcmaString *EcmaString::CreateFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len, const EcmaVM *vm, + bool canBeCompress) { if (utf8Len == 0) { return vm->GetFactory()->GetEmptyString().GetObject(); } - bool canBeCompressed = CanBeCompressed(utf8Data); EcmaString *string = nullptr; - if (canBeCompressed) { + if (canBeCompress) { string = AllocStringObject(utf8Len, true, vm); ASSERT(string != nullptr); @@ -75,16 +75,16 @@ inline EcmaString *EcmaString::CreateFromUtf8(const uint8_t *utf8Data, uint32_t return string; } -inline EcmaString *EcmaString::CreateFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len, const EcmaVM *vm) +inline EcmaString *EcmaString::CreateFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len, const EcmaVM *vm, + bool canBeCompress) { if (utf16Len == 0) { return vm->GetFactory()->GetEmptyString().GetObject(); } - bool canBeCompressed = CanBeCompressed(utf16Data, utf16Len); - auto string = AllocStringObject(utf16Len, canBeCompressed, vm); + auto string = AllocStringObject(utf16Len, canBeCompress, vm); ASSERT(string != nullptr); - if (canBeCompressed) { + if (canBeCompress) { CopyUtf16AsUtf8(utf16Data, string->GetDataUtf8Writable(), utf16Len); } else { uint32_t len = utf16Len * (sizeof(uint16_t) / sizeof(uint8_t)); @@ -97,7 +97,7 @@ inline EcmaString *EcmaString::CreateFromUtf16(const uint16_t *utf16Data, uint32 return string; } -template +template inline uint16_t EcmaString::At(int32_t index) const { int32_t length = GetLength(); diff --git a/ecmascript/ecma_string.cpp b/ecmascript/ecma_string.cpp index 7d7cf38ba79bf4e887a207712f5851f5fbc24868..51e300d39fb69724db2b3b805fc4a873eb1984b3 100644 --- a/ecmascript/ecma_string.cpp +++ b/ecmascript/ecma_string.cpp @@ -83,7 +83,7 @@ EcmaString *EcmaString::FastSubString(const JSHandle &src, uint32_t return vm->GetFactory()->GetEmptyString().GetObject(); } // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - bool canBeCompressed = !src->IsUtf16() || CanBeCompressed(src->GetDataUtf16() + start, utf16Len); + bool canBeCompressed = !src->IsUtf16(); // allocator may trig gc and move src, need to hold it auto string = AllocStringObject(utf16Len, canBeCompressed, vm); @@ -108,7 +108,7 @@ EcmaString *EcmaString::FastSubString(const JSHandle &src, uint32_t return string; } -template +template int32_t CompareStringSpan(Span &lhsSp, Span &rhsSp, int32_t count) { for (int32_t i = 0; i < count; ++i) { @@ -164,7 +164,7 @@ int32_t EcmaString::Compare(const EcmaString *rhs) const } /* static */ -template +template int32_t EcmaString::IndexOf(Span &lhsSp, Span &rhsSp, int32_t pos, int32_t max) { ASSERT(rhsSp.size() > 0); @@ -172,7 +172,9 @@ int32_t EcmaString::IndexOf(Span &lhsSp, Span &rhsSp, int32_ int32_t i; for (i = pos; i <= max; i++) { if (static_cast(lhsSp[i]) != first) { - while (++i <= max && static_cast(lhsSp[i]) != first) { + i++; + while (i <= max && static_cast(lhsSp[i]) != first) { + i++; } } /* Found first character, now look at the rest of rhsSp */ @@ -212,6 +214,9 @@ int32_t EcmaString::IndexOf(const EcmaString *rhs, int32_t pos) const } int32_t max = lhsCount - rhsCount; + if (max < 0) { + return -1; + } if (rhs->IsUtf8() && lhs->IsUtf8()) { Span lhsSp(lhs->GetDataUtf8(), lhsCount); Span rhsSp(rhs->GetDataUtf8(), rhsCount); @@ -300,24 +305,22 @@ bool EcmaString::StringsAreEqual(EcmaString *str1, EcmaString *str2) } /* static */ -bool EcmaString::StringsAreEqualUtf8(const EcmaString *str1, const uint8_t *utf8Data, uint32_t utf8Len) +bool EcmaString::StringsAreEqualUtf8(const EcmaString *str1, const uint8_t *utf8Data, uint32_t utf8Len, + bool canBeCompress) { - bool str1CanBeCompressed = str1->IsUtf8(); - if (str1CanBeCompressed && str1->GetLength() != utf8Len) { + if (canBeCompress != str1->IsUtf8()) { return false; } - bool str2CanBeCompressed = EcmaString::CanBeCompressed(utf8Data); - if (str1CanBeCompressed != str2CanBeCompressed) { + if (canBeCompress && str1->GetLength() != utf8Len) { return false; } - if (str1CanBeCompressed) { - Span data1(str1->GetDataUtf8(), str1->GetLength()); + if (canBeCompress) { + Span data1(str1->GetDataUtf8(), utf8Len); Span data2(utf8Data, utf8Len); return EcmaString::StringsAreEquals(data1, data2); } - return IsUtf8EqualsUtf16(utf8Data, str1->GetDataUtf16(), str1->GetLength()); } @@ -338,7 +341,7 @@ bool EcmaString::StringsAreEqualUtf16(const EcmaString *str1, const uint16_t *ut } /* static */ -template +template bool EcmaString::StringsAreEquals(Span &str1, Span &str2) { ASSERT(str1.Size() <= str2.Size()); @@ -354,7 +357,7 @@ bool EcmaString::StringsAreEquals(Span &str1, Span &str2) return !memcmp(str1.data(), str2.data(), size); } -template +template bool EcmaString::StringCopy(Span &dst, size_t dstMax, Span &src, size_t count) { ASSERT(dstMax >= count); @@ -372,7 +375,7 @@ bool EcmaString::StringCopy(Span &dst, size_t dstMax, Span &src, siz return true; } -template +template static int32_t ComputeHashForData(const T *data, size_t size) { uint32_t hash = 0; @@ -419,11 +422,10 @@ uint32_t EcmaString::ComputeHashcode() const } /* static */ -uint32_t EcmaString::ComputeHashcodeUtf8(const uint8_t *utf8Data) +uint32_t EcmaString::ComputeHashcodeUtf8(const uint8_t *utf8Data, bool canBeCompress) { - bool canBeCompressed = EcmaString::CanBeCompressed(utf8Data); uint32_t hash; - if (canBeCompressed) { + if (canBeCompress) { hash = ComputeHashForUtf8(utf8Data); } else { auto utf16Len = base::utf_helper::Utf8ToUtf16Size(utf8Data); diff --git a/ecmascript/ecma_string.h b/ecmascript/ecma_string.h index d8c22d3c2aae24796fc813c21ac10a5da7c57a68..499295787b1dc9e21cf603ddf98a1ca1da7f96d4 100644 --- a/ecmascript/ecma_string.h +++ b/ecmascript/ecma_string.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_STRING_H -#define PANDA_RUNTIME_ECMASCRIPT_STRING_H +#ifndef ECMASCRIPT_STRING_H +#define ECMASCRIPT_STRING_H #include #include @@ -27,7 +27,7 @@ namespace panda { namespace ecmascript { -template +template class JSHandle; class EcmaVM; @@ -37,14 +37,15 @@ public: static const EcmaString *ConstCast(const TaggedObject *object); static EcmaString *CreateEmptyString(const EcmaVM *vm); - static EcmaString *CreateFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len, const EcmaVM *vm); - static EcmaString *CreateFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len, const EcmaVM *vm); + static EcmaString *CreateFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len, const EcmaVM *vm, bool canBeCompress); + static EcmaString *CreateFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len, const EcmaVM *vm, + bool canBeCompress); static EcmaString *Concat(const JSHandle &str1Handle, const JSHandle &str2Handle, const EcmaVM *vm); static EcmaString *FastSubString(const JSHandle &src, uint32_t start, uint32_t utf16Len, const EcmaVM *vm); - template + template uint16_t At(int32_t index) const; int32_t Compare(const EcmaString *rhs) const; @@ -170,8 +171,8 @@ public: inline std::unique_ptr GetCString() { auto length = GetUtf8Length(); - char* buf = new char[length]; - CopyDataUtf8(reinterpret_cast(buf), length); + char *buf = new char[length](); + CopyDataUtf8(reinterpret_cast(buf), length); // NOLINTNEXTLINE(modernize-avoid-c-arrays) return std::unique_ptr(buf); } @@ -231,12 +232,13 @@ public: /** * Compares strings by bytes, It doesn't check canonical unicode equivalence. */ - static bool StringsAreEqualUtf8(const EcmaString *str1, const uint8_t *utf8Data, uint32_t utf8Len); + static bool StringsAreEqualUtf8(const EcmaString *str1, const uint8_t *utf8Data, uint32_t utf8Len, + bool canBeCompress); /** * Compares strings by bytes, It doesn't check canonical unicode equivalence. */ static bool StringsAreEqualUtf16(const EcmaString *str1, const uint16_t *utf16Data, uint32_t utf16Len); - static uint32_t ComputeHashcodeUtf8(const uint8_t *utf8Data); + static uint32_t ComputeHashcodeUtf8(const uint8_t *utf8Data, bool canBeCompress); static uint32_t ComputeHashcodeUtf16(const uint16_t *utf16Data, uint32_t length); static void SetCompressedStringsEnabled(bool val) @@ -251,6 +253,9 @@ public: static EcmaString *AllocStringObject(size_t length, bool compressed, const EcmaVM *vm); + static bool CanBeCompressed(const uint8_t *utf8Data); + static bool CanBeCompressed(const uint16_t *utf16Data, uint32_t utf16Len); + private: void SetLength(uint32_t length, bool compressed = false) { @@ -277,8 +282,6 @@ private: } uint32_t ComputeHashcode() const; - static bool CanBeCompressed(const uint8_t *utf8Data); - static bool CanBeCompressed(const uint16_t *utf16Data, uint32_t utf16Len); static void CopyUtf16AsUtf8(const uint16_t *utf16From, uint8_t *utf8To, uint32_t utf16Len); static bool compressedStringsEnabled; @@ -301,19 +304,19 @@ private: */ static bool IsUtf8EqualsUtf16(const uint8_t *utf8Data, const uint16_t *utf16Data, uint32_t utf16Len); - template + template /** * Check that two spans are equal. Should have the same length. */ static bool StringsAreEquals(Span &str1, Span &str2); - template + template /** * Copy String from src to dst * */ static bool StringCopy(Span &dst, size_t dstMax, Span &src, size_t count); - template + template static int32_t IndexOf(Span &lhsSp, Span &rhsSp, int32_t pos, int32_t max); // In last bit of length_ we store if this string is compressed or not. @@ -325,4 +328,4 @@ private: }; } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_STRING_H +#endif // ECMASCRIPT_STRING_H diff --git a/ecmascript/ecma_string_table.cpp b/ecmascript/ecma_string_table.cpp index f4524653c44fcd441371c474ed2cb6d586509478..88426a7a22ed58ca41911955b7ee0943bf816bab 100644 --- a/ecmascript/ecma_string_table.cpp +++ b/ecmascript/ecma_string_table.cpp @@ -25,12 +25,12 @@ namespace panda::ecmascript { EcmaStringTable::EcmaStringTable(const EcmaVM *vm) : vm_(vm) {} -EcmaString *EcmaStringTable::GetString(const uint8_t *utf8Data, uint32_t utf8Len) const +EcmaString *EcmaStringTable::GetString(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress) const { - uint32_t hashCode = EcmaString::ComputeHashcodeUtf8(utf8Data); + uint32_t hashCode = EcmaString::ComputeHashcodeUtf8(utf8Data, canBeCompress); for (auto it = table_.find(hashCode); it != table_.end(); it++) { auto foundedString = it->second; - if (EcmaString::StringsAreEqualUtf8(foundedString, utf8Data, utf8Len)) { + if (EcmaString::StringsAreEqualUtf8(foundedString, utf8Data, utf8Len, canBeCompress)) { return foundedString; } } @@ -75,31 +75,27 @@ void EcmaStringTable::InternEmptyString(EcmaString *emptyStr) InternString(emptyStr); } -EcmaString *EcmaStringTable::GetOrInternString(const uint8_t *utf8Data, uint32_t utf8Len) +EcmaString *EcmaStringTable::GetOrInternString(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress) { - EcmaString *result = GetString(utf8Data, utf8Len); + EcmaString *result = GetString(utf8Data, utf8Len, canBeCompress); if (result != nullptr) { return result; } - result = EcmaString::CreateFromUtf8(utf8Data, utf8Len, vm_); - + result = EcmaString::CreateFromUtf8(utf8Data, utf8Len, vm_, canBeCompress); InternString(result); - return result; } -EcmaString *EcmaStringTable::GetOrInternString(const uint16_t *utf16Data, uint32_t utf16Len) +EcmaString *EcmaStringTable::GetOrInternString(const uint16_t *utf16Data, uint32_t utf16Len, bool canBeCompress) { EcmaString *result = GetString(utf16Data, utf16Len); if (result != nullptr) { return result; } - result = EcmaString::CreateFromUtf16(utf16Data, utf16Len, vm_); - + result = EcmaString::CreateFromUtf16(utf16Data, utf16Len, vm_, canBeCompress); InternString(result); - return result; } diff --git a/ecmascript/ecma_string_table.h b/ecmascript/ecma_string_table.h index 1e2061bf825b0b35953f86c936011fa3668491ef..11992f3757f0dae1dfb862ef88419b5487b8f1a7 100644 --- a/ecmascript/ecma_string_table.h +++ b/ecmascript/ecma_string_table.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_STRING_TABLE_H -#define PANDA_RUNTIME_ECMASCRIPT_STRING_TABLE_H +#ifndef ECMASCRIPT_STRING_TABLE_H +#define ECMASCRIPT_STRING_TABLE_H #include "ecmascript/mem/c_containers.h" #include "ecmascript/mem/heap_roots.h" @@ -32,8 +32,8 @@ public: } void InternEmptyString(EcmaString *emptyStr); - EcmaString *GetOrInternString(const uint8_t *utf8Data, uint32_t utf8Len); - EcmaString *GetOrInternString(const uint16_t *utf16Data, uint32_t utf16Len); + EcmaString *GetOrInternString(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress); + EcmaString *GetOrInternString(const uint16_t *utf16Data, uint32_t utf16Len, bool canBeCompress); EcmaString *GetOrInternString(EcmaString *string); void SweepWeakReference(const WeakRootVisitor &visitor); @@ -42,7 +42,7 @@ private: NO_COPY_SEMANTIC(EcmaStringTable); NO_MOVE_SEMANTIC(EcmaStringTable); - EcmaString *GetString(const uint8_t *utf8Data, uint32_t utf8Len) const; + EcmaString *GetString(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress) const; EcmaString *GetString(const uint16_t *utf16Data, uint32_t utf16Len) const; EcmaString *GetString(EcmaString *string) const; @@ -62,4 +62,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_STRING_TABLE_H +#endif // ECMASCRIPT_STRING_TABLE_H diff --git a/ecmascript/ecma_vm.cpp b/ecmascript/ecma_vm.cpp index 4962c89386b6eec4224c2055dc202716323f4cbc..2fde7aa0d33f4f38aeceda2ac2ef9680edcafe8c 100644 --- a/ecmascript/ecma_vm.cpp +++ b/ecmascript/ecma_vm.cpp @@ -25,8 +25,8 @@ #include "ecmascript/global_env.h" #include "ecmascript/global_env_constants-inl.h" #include "ecmascript/global_env_constants.h" -#include "ecmascript/global_handle_collection.h" #include "ecmascript/ic/properties_cache-inl.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/jobs/micro_job_queue.h" #include "ecmascript/js_arraybuffer.h" #include "ecmascript/js_for_in_iterator.h" @@ -36,6 +36,7 @@ #include "ecmascript/object_factory.h" #include "ecmascript/regexp/regexp_parser_cache.h" #include "ecmascript/runtime_call_id.h" +#include "ecmascript/runtime_trampolines.h" #include "ecmascript/snapshot/mem/slot_bit.h" #include "ecmascript/snapshot/mem/snapshot.h" #include "ecmascript/snapshot/mem/snapshot_serialize.h" @@ -99,11 +100,9 @@ EcmaVM::EcmaVM(RuntimeOptions options) stringTable_(new EcmaStringTable(this)), regionFactory_(std::make_unique()), chunk_(regionFactory_.get()), - allocator_(new CAddressAllocator()), nativeMethods_(&chunk_) { icEnable_ = options_.IsIcEnable(); - gcStats_ = chunk_.New(); rendezvous_ = chunk_.New(); snapshotSerializeEnable_ = options_.IsSnapshotSerializeEnabled(); if (!snapshotSerializeEnable_) { @@ -115,15 +114,17 @@ EcmaVM::EcmaVM(RuntimeOptions options) bool EcmaVM::Initialize() { - ASSERT(thread_ != nullptr); trace::ScopedTrace scoped_trace("EcmaVM::Initialize"); + RuntimeTrampolines::InitializeRuntimeTrampolines(thread_); + auto globalConst = const_cast(thread_->GlobalConstants()); propertiesCache_ = new PropertiesCache(); regExpParserCache_ = new RegExpParserCache(); heap_ = new Heap(this); - heap_->SetUp(); + heap_->Initialize(); + gcStats_ = chunk_.New(heap_); factory_ = chunk_.New(thread_, heap_); if (UNLIKELY(factory_ == nullptr)) { LOG_ECMA(FATAL) << "alloc factory_ failed"; @@ -196,7 +197,7 @@ void EcmaVM::InitializeEcmaScriptRunStat() BUITINS_API_LIST(BUILTINS_API_NAME) #undef BUILTINS_API_NAME #define ABSTRACT_OPERATION_NAME(class, name) "AbstractOperation::" #class "_" #name, - ABSTRACT_OPERATION_LIST(ABSTRACT_OPERATION_NAME) + ABSTRACT_OPERATION_LIST(ABSTRACT_OPERATION_NAME) #undef ABSTRACT_OPERATION_NAME }; runtimeStat_ = chunk_.New(runtimeCallerNames, ecmascript::RUNTIME_CALLER_NUMBER); @@ -238,8 +239,14 @@ EcmaVM::~EcmaVM() // clear c_address: c++ pointer delete ClearBufferData(); + if (gcStats_ != nullptr) { + gcStats_->PrintStatisticResult(); + chunk_.Delete(gcStats_); + gcStats_ = nullptr; + } + if (heap_ != nullptr) { - heap_->TearDown(); + heap_->Destroy(); delete heap_; heap_ = nullptr; } @@ -255,12 +262,6 @@ EcmaVM::~EcmaVM() factory_ = nullptr; } - if (gcStats_ != nullptr) { - gcStats_->PrintStatisticResult(); - chunk_.Delete(gcStats_); - gcStats_ = nullptr; - } - if (stringTable_ != nullptr) { delete stringTable_; stringTable_ = nullptr; @@ -281,11 +282,6 @@ EcmaVM::~EcmaVM() thread_ = nullptr; } - if (allocator_ != nullptr) { - delete allocator_; - allocator_ = nullptr; - } - extractorCache_.clear(); frameworkProgramMethods_.clear(); } @@ -316,7 +312,7 @@ bool EcmaVM::ExecuteFromBuffer(const void *buffer, size_t size, std::string_view return false; } const panda_file::File *pf_ptr = pf.get(); - AddPandaFile(pf.release(), false); // Store here from being automatically cleared + AddPandaFile(pf.release(), false); // Store here prevent from being automatically cleared return Execute(*pf_ptr, entryPoint, args); } @@ -410,7 +406,7 @@ Expected EcmaVM::InvokeEcmaEntrypoint(const panda_file::Fil if (&pf != frameworkPandaFile_) { program = PandaFileTranslator::TranslatePandaFile(this, pf, methodName); } else { - JSHandle string = factory_->NewFromStdString(pf.GetFilename()); + JSHandle string = factory_->NewFromStdStringUnCheck(pf.GetFilename(), true); program = JSHandle(thread_, frameworkProgram_); program->SetLocation(thread_, string); RedirectMethod(pf); @@ -433,7 +429,9 @@ Expected EcmaVM::InvokeEcmaEntrypoint(const panda_file::Fil jsargs->Set(thread_, i++, strobj); } - panda::ecmascript::InvokeJsFunction(thread_, func, global, newTarget, jsargs); + InternalCallParams *params = thread_->GetInternalCallParams(); + params->MakeArgList(*jsargs); + panda::ecmascript::InvokeJsFunction(thread_, func, global, newTarget, params); if (!thread_->HasPendingException()) { job::MicroJobQueue::Cast(microJobQueue_.GetTaggedObject())->ExecutePendingJob(thread_); } @@ -735,5 +733,4 @@ void EcmaVM::SetupRegExpResultCache() { regexpCache_ = builtins::RegExpExecResultCache::CreateCacheTable(thread_); } - } // namespace panda::ecmascript diff --git a/ecmascript/ecma_vm.h b/ecmascript/ecma_vm.h index d77a3bc56581c4d734c05fb7d837107c761ae96d..afa964b5a12c8f40210ae22c70243ff2951218ef 100644 --- a/ecmascript/ecma_vm.h +++ b/ecmascript/ecma_vm.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMA_VM_H -#define PANDA_RUNTIME_ECMA_VM_H +#ifndef ECMASCRIPT_ECMA_VM_H +#define ECMASCRIPT_ECMA_VM_H #include @@ -55,7 +55,7 @@ namespace job { class MicroJobQueue; } // namespace job -template +template class JSHandle; class JSArrayBuffer; class JSFunction; @@ -253,7 +253,7 @@ public: JSHandle GetEcmaUncaughtException() const; void EnableUserUncaughtErrorHandler(); - template + template void EnumeratePandaFiles(Callback cb) const { for (const auto &iter : pandaFileWithProgram_) { @@ -263,7 +263,7 @@ public: } } - template + template void EnumerateProgram(Callback cb, std::string pandaFile) const { for (const auto &iter : pandaFileWithProgram_) { @@ -320,11 +320,6 @@ public: return moduleManager_; } - CAddressAllocator *GetCountAllocator() const - { - return allocator_; - } - static constexpr uint32_t GetGlobalEnvOffset() { return MEMBER_OFFSET(EcmaVM, globalEnv_); @@ -388,7 +383,6 @@ private: EcmaStringTable *stringTable_; std::unique_ptr regionFactory_; Chunk chunk_; - CAddressAllocator *allocator_{nullptr}; ChunkVector nativeMethods_; bool icEnable_{true}; GCStats *gcStats_ = nullptr; diff --git a/ecmascript/js_int8_array.h b/ecmascript/frames.h similarity index 39% rename from ecmascript/js_int8_array.h rename to ecmascript/frames.h index af3a64718a36bead370cd3eb44cf777d1f342853..dc5c0022865afcd0c0ac708b802e7959a959027a 100644 --- a/ecmascript/js_int8_array.h +++ b/ecmascript/frames.h @@ -1,45 +1,54 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_INT8_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_INT8_ARRAY_H - -#include -#include "ecmascript/js_object.h" -#include "ecmascript/js_tagged_value-inl.h" -#include "ecmascript/js_tagged_value.h" - -namespace panda::ecmascript { -class JSInt8Array : public JSObject { -public: - static JSInt8Array *Cast(ObjectHeader *object) - { - ASSERT(JSTaggedValue(object).IsJSInt8Array()); - return static_cast(object); - } - - static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE; - ACCESSORS(ViewedArrayBuffer, VIEWED_ARRAY_BUFFER_OFFSET, TYPED_ARRAY_NAME_OFFSET) - ACCESSORS(TypedArrayName, TYPED_ARRAY_NAME_OFFSET, BYTE_LENGTH_OFFSET) - ACCESSORS(ByteLength, BYTE_LENGTH_OFFSET, BYTE_OFFSET_OFFSET) - ACCESSORS(ByteOffset, BYTE_OFFSET_OFFSET, ARRAY_LENGTH_OFFSET) - ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, SIZE) - DECL_DUMP() - - DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE) -}; // namespace panda::ecmascript -} // namespace panda::ecmascript - -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_INT8_ARRAY_H +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_FRAMES_H +#define ECMASCRIPT_FRAMES_H + +namespace panda::ecmascript { +enum class FrameType: unsigned int { + OPTIMIZED_FRAME = 0, + OPTIMIZED_ENTRY_FRAME = 1, + INTERPRETER_FRAME = 2, +}; + +template +auto as_integer(Enumeration const value) +-> typename std::underlying_type::type +{ + return static_cast::type>(value); +} + +class FrameStateBase { +public: + FrameType frameType; + uint64_t *prev; // for llvm :c-fp ; for interrupt: thread-fp for gc +}; + +class LLVMBoundaryFrameState { +public: + uint64_t *threadFp; // for gc + FrameStateBase base; +}; + +constexpr int kSystemPointerSize = sizeof(void*); +class FrameConst { +public: + uint64_t *prev; + FrameType frameType; + static constexpr int kPreOffset = -kSystemPointerSize; + static constexpr int kFrameType = -2 * kSystemPointerSize; +}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_FRAMES_H \ No newline at end of file diff --git a/ecmascript/free_object.h b/ecmascript/free_object.h index 1ff055838ddd5de52244d38685865afba89b9b34..9c695d76211d48d19205b33e912e5ba4f7bc1579 100644 --- a/ecmascript/free_object.h +++ b/ecmascript/free_object.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_FREE_OBJECT_H -#define PANDA_RUNTIME_ECMASCRIPT_FREE_OBJECT_H +#ifndef ECMASCRIPT_FREE_OBJECT_H +#define ECMASCRIPT_FREE_OBJECT_H #include "ecmascript/js_hclass.h" #include "ecmascript/mem/barriers.h" @@ -67,9 +67,9 @@ public: hclass->IsFreeObjectWithNoneField()); } - static constexpr size_t NEXT_OFFSET = TaggedObject::ObjectHeaderSize(); + static constexpr size_t NEXT_OFFSET = TaggedObjectSize(); SET_GET_NATIVE_FIELD(Next, FreeObject, NEXT_OFFSET, SIZE_OFFSET); SET_GET_PRIMITIVE_FIELD(Size, size_t, SIZE_OFFSET, SIZE); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_FREE_OBJECT_H +#endif // ECMASCRIPT_MEM_FREE_OBJECT_H diff --git a/ecmascript/generator_helper.h b/ecmascript/generator_helper.h index c5dedb209e2bd758b6107f6b09ae94f62bef6614..f6ad6616ce1d6e5f85aec5a551360a970bceb2bc 100644 --- a/ecmascript/generator_helper.h +++ b/ecmascript/generator_helper.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_GENERATOR_HELPER_H -#define PANDA_RUNTIME_ECMASCRIPT_GENERATOR_HELPER_H +#ifndef ECMASCRIPT_GENERATOR_HELPER_H +#define ECMASCRIPT_GENERATOR_HELPER_H #include @@ -44,4 +44,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_GENERATOR_HELPER_H +#endif // ECMASCRIPT_GENERATOR_HELPER_H diff --git a/ecmascript/global_dictionary-inl.h b/ecmascript/global_dictionary-inl.h index 52a2ecbf2e94574460569e6ced7b86172b87a5ac..f53ceed58f58f45cb227d9e88ab460303ee4ccdb 100644 --- a/ecmascript/global_dictionary-inl.h +++ b/ecmascript/global_dictionary-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_GLOBAL_DICTIONARY_INL_H -#define PANDA_RUNTIME_GLOBAL_DICTIONARY_INL_H +#ifndef ECMASCRIPT_GLOBAL_DICTIONARY_INL_H +#define ECMASCRIPT_GLOBAL_DICTIONARY_INL_H #include "ecmascript/global_dictionary.h" #include "ecmascript/ic/property_box.h" diff --git a/ecmascript/global_dictionary.h b/ecmascript/global_dictionary.h index 9e36dc6409be076ced1df7b6a97ddfd068b053eb..bbbda1709ed8942cc6a7e89ebeb3333eed7ce438 100644 --- a/ecmascript/global_dictionary.h +++ b/ecmascript/global_dictionary.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_GLOBAL_DICTIONARY_H -#define PANDA_RUNTIME_GLOBAL_DICTIONARY_H +#ifndef ECMASCRIPT_GLOBAL_DICTIONARY_H +#define ECMASCRIPT_GLOBAL_DICTIONARY_H #include "ecmascript/ecma_string.h" #include "ecmascript/ic/property_box.h" diff --git a/ecmascript/global_env.h b/ecmascript/global_env.h index 6ea196415bca3bc5c052409a65d7dce24afffa25..3d9c225b67c975bf0da9c87a9feb14a19a9d1d8e 100644 --- a/ecmascript/global_env.h +++ b/ecmascript/global_env.h @@ -13,14 +13,14 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_GLOBAL_ENV_H -#define PANDA_RUNTIME_ECMASCRIPT_GLOBAL_ENV_H +#ifndef ECMASCRIPT_GLOBAL_ENV_H +#define ECMASCRIPT_GLOBAL_ENV_H -#include "ecmascript/global_env_constants-inl.h" -#include "ecmascript/js_function.h" #include "ecmascript/js_global_object.h" -#include "ecmascript/js_handle.h" +#include "ecmascript/js_function.h" #include "ecmascript/lexical_env.h" +#include "ecmascript/js_handle.h" +#include "ecmascript/global_env_constants-inl.h" namespace panda::ecmascript { class JSThread; @@ -175,7 +175,7 @@ public: JSHandle result(address); \ return result; \ } \ - template \ + template \ inline void Set##name(const JSThread *thread, JSHandle value, BarrierMode mode = WRITE_BARRIER) \ { \ int offset = HEADER_SIZE + index * JSTaggedValue::TaggedTypeSize(); \ @@ -197,7 +197,7 @@ public: GLOBAL_ENV_FIELDS(GLOBAL_ENV_FIELD_ACCESSORS) #undef GLOBAL_ENV_FIELD_ACCESSORS - static constexpr size_t HEADER_SIZE = sizeof(TaggedObject); + static constexpr size_t HEADER_SIZE = TaggedObjectSize(); static constexpr size_t SIZE = HEADER_SIZE + FINAL_INDEX * JSTaggedValue::TaggedTypeSize(); DECL_DUMP() @@ -209,4 +209,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_GLOBAL_ENV_H +#endif // ECMASCRIPT_GLOBAL_ENV_H diff --git a/ecmascript/global_env_constants-inl.h b/ecmascript/global_env_constants-inl.h index c937cffb59d9b086a33f8587d7f8ecb3bbe6df09..e06448234f4aa8bb4907daca327a2ede437cf370 100644 --- a/ecmascript/global_env_constants-inl.h +++ b/ecmascript/global_env_constants-inl.h @@ -37,6 +37,11 @@ inline void GlobalEnvConstants::SetConstant(ConstantIndex index, JSTaggedValue v constants_[static_cast(index)] = value; } +inline uintptr_t GlobalEnvConstants::GetGlobalConstantAddr(ConstantIndex index) const +{ + return ToUintPtr(this) + sizeof(JSTaggedValue) * static_cast(index); +} + // clang-format off // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define DECL_GET_IMPL(Type, Name, Index, Desc) \ diff --git a/ecmascript/global_env_constants.cpp b/ecmascript/global_env_constants.cpp index 88266834fa66a89162d5c922001184ec3d4bdfca..03a32f56a7d9c5d4c40a3612cf93c0cb1793b5ec 100644 --- a/ecmascript/global_env_constants.cpp +++ b/ecmascript/global_env_constants.cpp @@ -15,13 +15,12 @@ #include "ecmascript/global_env_constants.h" -#include "ecma_vm.h" #include "ecmascript/accessor_data.h" -#include "ecmascript/ecma_macros.h" -#include "ecmascript/ecma_module.h" #include "ecmascript/builtins.h" #include "ecmascript/builtins/builtins_global.h" #include "ecmascript/class_linker/program_object.h" +#include "ecmascript/ecma_module.h" +#include "ecmascript/ecma_vm.h" #include "ecmascript/free_object.h" #include "ecmascript/global_env.h" #include "ecmascript/global_env_constants-inl.h" @@ -52,7 +51,6 @@ #include "ecmascript/js_thread.h" #include "ecmascript/object_factory.h" - namespace panda::ecmascript { void GlobalEnvConstants::InitRootsClass([[maybe_unused]] JSThread *thread, JSHClass *dynClassClass) { @@ -152,6 +150,8 @@ void GlobalEnvConstants::InitRootsClass([[maybe_unused]] JSThread *thread, JSHCl SetConstant(ConstantIndex::JS_REALM_CLASS_INDEX, factory->NewEcmaDynClass(dynClassClass, JSRealm::SIZE, JSType::JS_REALM).GetTaggedValue()); + SetConstant(ConstantIndex::MACHINE_CODE_CLASS_INDEX, + factory->NewEcmaDynClass(dynClassClass, 0, JSType::MACHINE_CODE_OBJECT).GetTaggedValue()); } // NOLINTNEXTLINE(readability-function-size) @@ -164,219 +164,298 @@ void GlobalEnvConstants::InitGlobalConstant(JSThread *thread) auto vm = thread->GetEcmaVM(); SetConstant(ConstantIndex::EMPTY_STRING_OBJECT_INDEX, JSTaggedValue(EcmaString::CreateEmptyString(vm))); [[maybe_unused]] auto test = EcmaString::Cast(GetHandledEmptyString().GetObject()); - SetConstant(ConstantIndex::CONSTRUCTOR_STRING_INDEX, factory->NewFromString("constructor").GetTaggedValue()); - SetConstant(ConstantIndex::PROTOTYPE_STRING_INDEX, factory->NewFromString("prototype").GetTaggedValue()); - SetConstant(ConstantIndex::LENGTH_STRING_INDEX, factory->NewFromString("length").GetTaggedValue()); - SetConstant(ConstantIndex::VALUE_STRING_INDEX, factory->NewFromString("value").GetTaggedValue()); - SetConstant(ConstantIndex::SET_STRING_INDEX, factory->NewFromString("set").GetTaggedValue()); - SetConstant(ConstantIndex::GET_STRING_INDEX, factory->NewFromString("get").GetTaggedValue()); - SetConstant(ConstantIndex::WRITABLE_STRING_INDEX, factory->NewFromString("writable").GetTaggedValue()); - SetConstant(ConstantIndex::ENUMERABLE_STRING_INDEX, factory->NewFromString("enumerable").GetTaggedValue()); - SetConstant(ConstantIndex::CONFIGURABLE_STRING_INDEX, factory->NewFromString("configurable").GetTaggedValue()); + SetConstant(ConstantIndex::CONSTRUCTOR_STRING_INDEX, + factory->NewFromCanBeCompressString("constructor").GetTaggedValue()); + SetConstant(ConstantIndex::PROTOTYPE_STRING_INDEX, + factory->NewFromCanBeCompressString("prototype").GetTaggedValue()); + SetConstant(ConstantIndex::LENGTH_STRING_INDEX, factory->NewFromCanBeCompressString("length").GetTaggedValue()); + SetConstant(ConstantIndex::VALUE_STRING_INDEX, factory->NewFromCanBeCompressString("value").GetTaggedValue()); + SetConstant(ConstantIndex::SET_STRING_INDEX, factory->NewFromCanBeCompressString("set").GetTaggedValue()); + SetConstant(ConstantIndex::GET_STRING_INDEX, factory->NewFromCanBeCompressString("get").GetTaggedValue()); + SetConstant(ConstantIndex::WRITABLE_STRING_INDEX, factory->NewFromCanBeCompressString("writable").GetTaggedValue()); + SetConstant(ConstantIndex::ENUMERABLE_STRING_INDEX, + factory->NewFromCanBeCompressString("enumerable").GetTaggedValue()); + SetConstant(ConstantIndex::CONFIGURABLE_STRING_INDEX, + factory->NewFromCanBeCompressString("configurable").GetTaggedValue()); /* SymbolTable *RegisterSymbols */ - SetConstant(ConstantIndex::NAME_STRING_INDEX, factory->NewFromString("name").GetTaggedValue()); - SetConstant(ConstantIndex::GETPROTOTYPEOF_STRING_INDEX, factory->NewFromString("getPrototypeOf").GetTaggedValue()); - SetConstant(ConstantIndex::SETPROTOTYPEOF_STRING_INDEX, factory->NewFromString("setPrototypeOf").GetTaggedValue()); - SetConstant(ConstantIndex::ISEXTENSIBLE_STRING_INDEX, factory->NewFromString("isExtensible").GetTaggedValue()); + SetConstant(ConstantIndex::NAME_STRING_INDEX, factory->NewFromCanBeCompressString("name").GetTaggedValue()); + SetConstant(ConstantIndex::GETPROTOTYPEOF_STRING_INDEX, + factory->NewFromCanBeCompressString("getPrototypeOf").GetTaggedValue()); + SetConstant(ConstantIndex::SETPROTOTYPEOF_STRING_INDEX, + factory->NewFromCanBeCompressString("setPrototypeOf").GetTaggedValue()); + SetConstant(ConstantIndex::ISEXTENSIBLE_STRING_INDEX, + factory->NewFromCanBeCompressString("isExtensible").GetTaggedValue()); SetConstant(ConstantIndex::PREVENTEXTENSIONS_STRING_INDEX, - factory->NewFromString("preventExtensions").GetTaggedValue()); + factory->NewFromCanBeCompressString("preventExtensions").GetTaggedValue()); SetConstant(ConstantIndex::GETOWNPROPERTYDESCRIPTOR_STRING_INDEX, - factory->NewFromString("getOwnPropertyDescriptor").GetTaggedValue()); - SetConstant(ConstantIndex::DEFINEPROPERTY_STRING_INDEX, factory->NewFromString("defineProperty").GetTaggedValue()); - SetConstant(ConstantIndex::HAS_STRING_INDEX, factory->NewFromString("has").GetTaggedValue()); - SetConstant(ConstantIndex::DELETEPROPERTY_STRING_INDEX, factory->NewFromString("deleteProperty").GetTaggedValue()); - SetConstant(ConstantIndex::ENUMERATE_STRING_INDEX, factory->NewFromString("enumerate").GetTaggedValue()); - SetConstant(ConstantIndex::OWNKEYS_STRING_INDEX, factory->NewFromString("ownKeys").GetTaggedValue()); - SetConstant(ConstantIndex::APPLY_STRING_INDEX, factory->NewFromString("apply").GetTaggedValue()); - SetConstant(ConstantIndex::NEGATIVE_ZERO_STRING_INDEX, factory->NewFromString("-0").GetTaggedValue()); - SetConstant(ConstantIndex::DONE_STRING_INDEX, factory->NewFromString("done").GetTaggedValue()); - SetConstant(ConstantIndex::PROXY_STRING_INDEX, factory->NewFromString("proxy").GetTaggedValue()); - SetConstant(ConstantIndex::REVOKE_STRING_INDEX, factory->NewFromString("revoke").GetTaggedValue()); - SetConstant(ConstantIndex::NEXT_STRING_INDEX, factory->NewFromString("next").GetTaggedValue()); - SetConstant(ConstantIndex::TO_STRING_STRING_INDEX, factory->NewFromString("toString").GetTaggedValue()); + factory->NewFromCanBeCompressString("getOwnPropertyDescriptor").GetTaggedValue()); + SetConstant(ConstantIndex::DEFINEPROPERTY_STRING_INDEX, + factory->NewFromCanBeCompressString("defineProperty").GetTaggedValue()); + SetConstant(ConstantIndex::HAS_STRING_INDEX, factory->NewFromCanBeCompressString("has").GetTaggedValue()); + SetConstant(ConstantIndex::DELETEPROPERTY_STRING_INDEX, + factory->NewFromCanBeCompressString("deleteProperty").GetTaggedValue()); + SetConstant(ConstantIndex::ENUMERATE_STRING_INDEX, + factory->NewFromCanBeCompressString("enumerate").GetTaggedValue()); + SetConstant(ConstantIndex::OWNKEYS_STRING_INDEX, factory->NewFromCanBeCompressString("ownKeys").GetTaggedValue()); + SetConstant(ConstantIndex::APPLY_STRING_INDEX, factory->NewFromCanBeCompressString("apply").GetTaggedValue()); + SetConstant(ConstantIndex::NEGATIVE_ZERO_STRING_INDEX, factory->NewFromCanBeCompressString("-0").GetTaggedValue()); + SetConstant(ConstantIndex::DONE_STRING_INDEX, factory->NewFromCanBeCompressString("done").GetTaggedValue()); + SetConstant(ConstantIndex::PROXY_STRING_INDEX, factory->NewFromCanBeCompressString("proxy").GetTaggedValue()); + SetConstant(ConstantIndex::REVOKE_STRING_INDEX, factory->NewFromCanBeCompressString("revoke").GetTaggedValue()); + SetConstant(ConstantIndex::NEXT_STRING_INDEX, factory->NewFromCanBeCompressString("next").GetTaggedValue()); + SetConstant(ConstantIndex::TO_STRING_STRING_INDEX, + factory->NewFromCanBeCompressString("toString").GetTaggedValue()); SetConstant(ConstantIndex::TO_LOCALE_STRING_STRING_INDEX, - factory->NewFromString("toLocaleString").GetTaggedValue()); - SetConstant(ConstantIndex::VALUE_OF_STRING_INDEX, factory->NewFromString("valueOf").GetTaggedValue()); - SetConstant(ConstantIndex::UNDEFINED_STRING_INDEX, factory->NewFromString("undefined").GetTaggedValue()); - SetConstant(ConstantIndex::NULL_STRING_INDEX, factory->NewFromString("null").GetTaggedValue()); - SetConstant(ConstantIndex::BOOLEAN_STRING_INDEX, factory->NewFromString("boolean").GetTaggedValue()); - SetConstant(ConstantIndex::NUMBER_STRING_INDEX, factory->NewFromString("number").GetTaggedValue()); - SetConstant(ConstantIndex::FUNCTION_STRING_INDEX, factory->NewFromString("function").GetTaggedValue()); - SetConstant(ConstantIndex::STRING_STRING_INDEX, factory->NewFromString("string").GetTaggedValue()); - SetConstant(ConstantIndex::SYMBOL_STRING_INDEX, factory->NewFromString("symbol").GetTaggedValue()); - SetConstant(ConstantIndex::OBJECT_STRING_INDEX, factory->NewFromString("object").GetTaggedValue()); - SetConstant(ConstantIndex::TRUE_STRING_INDEX, factory->NewFromString("true").GetTaggedValue()); - SetConstant(ConstantIndex::FALSE_STRING_INDEX, factory->NewFromString("false").GetTaggedValue()); - SetConstant(ConstantIndex::RETURN_STRING_INDEX, factory->NewFromString("return").GetTaggedValue()); - SetConstant(ConstantIndex::PROXY_CONSTRUCT_STRING_INDEX, factory->NewFromString("construct").GetTaggedValue()); - SetConstant(ConstantIndex::PROXY_CALL_STRING_INDEX, factory->NewFromString("call").GetTaggedValue()); - SetConstant(ConstantIndex::PROMISE_THEN_STRING_INDEX, factory->NewFromString("then").GetTaggedValue()); - SetConstant(ConstantIndex::PROMISE_CATCH_STRING_INDEX, factory->NewFromString("catch").GetTaggedValue()); - SetConstant(ConstantIndex::SCRIPT_JOB_STRING_INDEX, factory->NewFromString("ScriptJobs").GetTaggedValue()); - SetConstant(ConstantIndex::PROMISE_STRING_INDEX, factory->NewFromString("PrimiseJobs").GetTaggedValue()); - SetConstant(ConstantIndex::THROWER_STRING_INDEX, factory->NewFromString("Thrower").GetTaggedValue()); - SetConstant(ConstantIndex::IDENTITY_STRING_INDEX, factory->NewFromString("Identity").GetTaggedValue()); - SetConstant(ConstantIndex::CALLER_STRING_INDEX, factory->NewFromString("caller").GetTaggedValue()); - SetConstant(ConstantIndex::CALLEE_STRING_INDEX, factory->NewFromString("callee").GetTaggedValue()); - SetConstant(ConstantIndex::INT8_ARRAY_STRING_INDEX, factory->NewFromString("Int8Array").GetTaggedValue()); - SetConstant(ConstantIndex::UINT8_ARRAY_STRING_INDEX, factory->NewFromString("Uint8Array").GetTaggedValue()); + factory->NewFromCanBeCompressString("toLocaleString").GetTaggedValue()); + SetConstant(ConstantIndex::VALUE_OF_STRING_INDEX, factory->NewFromCanBeCompressString("valueOf").GetTaggedValue()); + SetConstant(ConstantIndex::UNDEFINED_STRING_INDEX, + factory->NewFromCanBeCompressString("undefined").GetTaggedValue()); + SetConstant(ConstantIndex::NULL_STRING_INDEX, factory->NewFromCanBeCompressString("null").GetTaggedValue()); + SetConstant(ConstantIndex::BOOLEAN_STRING_INDEX, factory->NewFromCanBeCompressString("boolean").GetTaggedValue()); + SetConstant(ConstantIndex::NUMBER_STRING_INDEX, factory->NewFromCanBeCompressString("number").GetTaggedValue()); + SetConstant(ConstantIndex::FUNCTION_STRING_INDEX, factory->NewFromCanBeCompressString("function").GetTaggedValue()); + SetConstant(ConstantIndex::STRING_STRING_INDEX, factory->NewFromCanBeCompressString("string").GetTaggedValue()); + SetConstant(ConstantIndex::SYMBOL_STRING_INDEX, factory->NewFromCanBeCompressString("symbol").GetTaggedValue()); + SetConstant(ConstantIndex::OBJECT_STRING_INDEX, factory->NewFromCanBeCompressString("object").GetTaggedValue()); + SetConstant(ConstantIndex::TRUE_STRING_INDEX, factory->NewFromCanBeCompressString("true").GetTaggedValue()); + SetConstant(ConstantIndex::FALSE_STRING_INDEX, factory->NewFromCanBeCompressString("false").GetTaggedValue()); + SetConstant(ConstantIndex::RETURN_STRING_INDEX, factory->NewFromCanBeCompressString("return").GetTaggedValue()); + SetConstant(ConstantIndex::PROXY_CONSTRUCT_STRING_INDEX, + factory->NewFromCanBeCompressString("construct").GetTaggedValue()); + SetConstant(ConstantIndex::PROXY_CALL_STRING_INDEX, factory->NewFromCanBeCompressString("call").GetTaggedValue()); + SetConstant(ConstantIndex::PROMISE_THEN_STRING_INDEX, factory->NewFromCanBeCompressString("then").GetTaggedValue()); + SetConstant(ConstantIndex::PROMISE_CATCH_STRING_INDEX, + factory->NewFromCanBeCompressString("catch").GetTaggedValue()); + SetConstant(ConstantIndex::SCRIPT_JOB_STRING_INDEX, + factory->NewFromCanBeCompressString("ScriptJobs").GetTaggedValue()); + SetConstant(ConstantIndex::PROMISE_STRING_INDEX, + factory->NewFromCanBeCompressString("PrimiseJobs").GetTaggedValue()); + SetConstant(ConstantIndex::THROWER_STRING_INDEX, factory->NewFromCanBeCompressString("Thrower").GetTaggedValue()); + SetConstant(ConstantIndex::IDENTITY_STRING_INDEX, factory->NewFromCanBeCompressString("Identity").GetTaggedValue()); + SetConstant(ConstantIndex::CALLER_STRING_INDEX, factory->NewFromCanBeCompressString("caller").GetTaggedValue()); + SetConstant(ConstantIndex::CALLEE_STRING_INDEX, factory->NewFromCanBeCompressString("callee").GetTaggedValue()); + SetConstant(ConstantIndex::INT8_ARRAY_STRING_INDEX, + factory->NewFromCanBeCompressString("Int8Array").GetTaggedValue()); + SetConstant(ConstantIndex::UINT8_ARRAY_STRING_INDEX, + factory->NewFromCanBeCompressString("Uint8Array").GetTaggedValue()); SetConstant(ConstantIndex::UINT8_CLAMPED_ARRAY_STRING_INDEX, - factory->NewFromString("Uint8ClampedArray").GetTaggedValue()); - SetConstant(ConstantIndex::INT16_ARRAY_STRING_INDEX, factory->NewFromString("Int16Array").GetTaggedValue()); - SetConstant(ConstantIndex::UINT16_ARRAY_STRING_INDEX, factory->NewFromString("Uint16Array").GetTaggedValue()); - SetConstant(ConstantIndex::INT32_ARRAY_STRING_INDEX, factory->NewFromString("Int32Array").GetTaggedValue()); - SetConstant(ConstantIndex::UINT32_ARRAY_STRING_INDEX, factory->NewFromString("Uint32Array").GetTaggedValue()); - SetConstant(ConstantIndex::FLOAT32_ARRAY_STRING_INDEX, factory->NewFromString("Float32Array").GetTaggedValue()); - SetConstant(ConstantIndex::FLOAT64_ARRAY_STRING_INDEX, factory->NewFromString("Float64Array").GetTaggedValue()); - SetConstant(ConstantIndex::ASYNC_FUNCTION_STRING_INDEX, factory->NewFromString("AsyncFunction").GetTaggedValue()); - SetConstant(ConstantIndex::PROMISE_RESOLVE_STRING_INDEX, factory->NewFromString("resolve").GetTaggedValue()); - SetConstant(ConstantIndex::ID_STRING_INDEX, factory->NewFromString("id").GetTaggedValue()); - SetConstant(ConstantIndex::METHOD_STRING_INDEX, factory->NewFromString("method").GetTaggedValue()); - SetConstant(ConstantIndex::PARAMS_STRING_INDEX, factory->NewFromString("params").GetTaggedValue()); - SetConstant(ConstantIndex::RESULT_STRING_INDEX, factory->NewFromString("result").GetTaggedValue()); - SetConstant(ConstantIndex::TO_JSON_STRING_INDEX, factory->NewFromString("toJSON").GetTaggedValue()); - SetConstant(ConstantIndex::GLOBAL_STRING_INDEX, factory->NewFromString("global").GetTaggedValue()); - SetConstant(ConstantIndex::MESSAGE_STRING_INDEX, factory->NewFromString("message").GetTaggedValue()); - SetConstant(ConstantIndex::ERROR_STRING_INDEX, factory->NewFromString("Error").GetTaggedValue()); - SetConstant(ConstantIndex::RANGE_ERROR_STRING_INDEX, factory->NewFromString("RangeError").GetTaggedValue()); - SetConstant(ConstantIndex::REFERENCE_ERROR_STRING_INDEX, factory->NewFromString("ReferenceError").GetTaggedValue()); - SetConstant(ConstantIndex::TYPE_ERROR_STRING_INDEX, factory->NewFromString("TypeError").GetTaggedValue()); - SetConstant(ConstantIndex::URI_ERROR_STRING_INDEX, factory->NewFromString("URIError").GetTaggedValue()); - SetConstant(ConstantIndex::SYNTAX_ERROR_STRING_INDEX, factory->NewFromString("SyntaxError").GetTaggedValue()); - SetConstant(ConstantIndex::EVAL_ERROR_STRING_INDEX, factory->NewFromString("EvalError").GetTaggedValue()); - SetConstant(ConstantIndex::STACK_STRING_INDEX, factory->NewFromString("stack").GetTaggedValue()); - SetConstant(ConstantIndex::STACK_EMPTY_STRING_INDEX, factory->NewFromString("stackisempty").GetTaggedValue()); + factory->NewFromCanBeCompressString("Uint8ClampedArray").GetTaggedValue()); + SetConstant(ConstantIndex::INT16_ARRAY_STRING_INDEX, + factory->NewFromCanBeCompressString("Int16Array").GetTaggedValue()); + SetConstant(ConstantIndex::UINT16_ARRAY_STRING_INDEX, + factory->NewFromCanBeCompressString("Uint16Array").GetTaggedValue()); + SetConstant(ConstantIndex::INT32_ARRAY_STRING_INDEX, + factory->NewFromCanBeCompressString("Int32Array").GetTaggedValue()); + SetConstant(ConstantIndex::UINT32_ARRAY_STRING_INDEX, + factory->NewFromCanBeCompressString("Uint32Array").GetTaggedValue()); + SetConstant(ConstantIndex::FLOAT32_ARRAY_STRING_INDEX, + factory->NewFromCanBeCompressString("Float32Array").GetTaggedValue()); + SetConstant(ConstantIndex::FLOAT64_ARRAY_STRING_INDEX, + factory->NewFromCanBeCompressString("Float64Array").GetTaggedValue()); + SetConstant(ConstantIndex::ASYNC_FUNCTION_STRING_INDEX, + factory->NewFromCanBeCompressString("AsyncFunction").GetTaggedValue()); + SetConstant(ConstantIndex::PROMISE_RESOLVE_STRING_INDEX, + factory->NewFromCanBeCompressString("resolve").GetTaggedValue()); + SetConstant(ConstantIndex::ID_STRING_INDEX, factory->NewFromCanBeCompressString("id").GetTaggedValue()); + SetConstant(ConstantIndex::METHOD_STRING_INDEX, factory->NewFromCanBeCompressString("method").GetTaggedValue()); + SetConstant(ConstantIndex::PARAMS_STRING_INDEX, factory->NewFromCanBeCompressString("params").GetTaggedValue()); + SetConstant(ConstantIndex::RESULT_STRING_INDEX, factory->NewFromCanBeCompressString("result").GetTaggedValue()); + SetConstant(ConstantIndex::TO_JSON_STRING_INDEX, factory->NewFromCanBeCompressString("toJSON").GetTaggedValue()); + SetConstant(ConstantIndex::GLOBAL_STRING_INDEX, factory->NewFromCanBeCompressString("global").GetTaggedValue()); + SetConstant(ConstantIndex::MESSAGE_STRING_INDEX, factory->NewFromCanBeCompressString("message").GetTaggedValue()); + SetConstant(ConstantIndex::ERROR_STRING_INDEX, factory->NewFromCanBeCompressString("Error").GetTaggedValue()); + SetConstant(ConstantIndex::RANGE_ERROR_STRING_INDEX, + factory->NewFromCanBeCompressString("RangeError").GetTaggedValue()); + SetConstant(ConstantIndex::REFERENCE_ERROR_STRING_INDEX, + factory->NewFromCanBeCompressString("ReferenceError").GetTaggedValue()); + SetConstant(ConstantIndex::TYPE_ERROR_STRING_INDEX, + factory->NewFromCanBeCompressString("TypeError").GetTaggedValue()); + SetConstant(ConstantIndex::URI_ERROR_STRING_INDEX, + factory->NewFromCanBeCompressString("URIError").GetTaggedValue()); + SetConstant(ConstantIndex::SYNTAX_ERROR_STRING_INDEX, + factory->NewFromCanBeCompressString("SyntaxError").GetTaggedValue()); + SetConstant(ConstantIndex::EVAL_ERROR_STRING_INDEX, + factory->NewFromCanBeCompressString("EvalError").GetTaggedValue()); + SetConstant(ConstantIndex::STACK_STRING_INDEX, factory->NewFromCanBeCompressString("stack").GetTaggedValue()); + SetConstant(ConstantIndex::STACK_EMPTY_STRING_INDEX, + factory->NewFromCanBeCompressString("stackisempty").GetTaggedValue()); SetConstant(ConstantIndex::OBJ_NOT_COERCIBLE_STRING_INDEX, - factory->NewFromString("objectnotcoercible").GetTaggedValue()); + factory->NewFromCanBeCompressString("objectnotcoercible").GetTaggedValue()); /* for Intl. */ - SetConstant(ConstantIndex::LANGUAGE_STRING_CLASS_INDEX, factory->NewFromString("language").GetTaggedValue()); - SetConstant(ConstantIndex::SCRIPT_STRING_CLASS_INDEX, factory->NewFromString("script").GetTaggedValue()); - SetConstant(ConstantIndex::REGION_STRING_CLASS_INDEX, factory->NewFromString("region").GetTaggedValue()); - SetConstant(ConstantIndex::BASE_NAME_STRING_CLASS_INDEX, factory->NewFromString("baseName").GetTaggedValue()); - SetConstant(ConstantIndex::CALENDAR_STRING_CLASS_INDEX, factory->NewFromString("calendar").GetTaggedValue()); - SetConstant(ConstantIndex::COLLATION_STRING_CLASS_INDEX, factory->NewFromString("collation").GetTaggedValue()); - SetConstant(ConstantIndex::HOUR_CYCLE_STRING_CLASS_INDEX, factory->NewFromString("hourCycle").GetTaggedValue()); - SetConstant(ConstantIndex::CASE_FIRST_STRING_CLASS_INDEX, factory->NewFromString("caseFirst").GetTaggedValue()); - SetConstant(ConstantIndex::NUMERIC_STRING_CLASS_INDEX, factory->NewFromString("numeric").GetTaggedValue()); + SetConstant(ConstantIndex::LANGUAGE_STRING_CLASS_INDEX, + factory->NewFromCanBeCompressString("language").GetTaggedValue()); + SetConstant(ConstantIndex::SCRIPT_STRING_CLASS_INDEX, + factory->NewFromCanBeCompressString("script").GetTaggedValue()); + SetConstant(ConstantIndex::REGION_STRING_CLASS_INDEX, + factory->NewFromCanBeCompressString("region").GetTaggedValue()); + SetConstant(ConstantIndex::BASE_NAME_STRING_CLASS_INDEX, + factory->NewFromCanBeCompressString("baseName").GetTaggedValue()); + SetConstant(ConstantIndex::CALENDAR_STRING_CLASS_INDEX, + factory->NewFromCanBeCompressString("calendar").GetTaggedValue()); + SetConstant(ConstantIndex::COLLATION_STRING_CLASS_INDEX, + factory->NewFromCanBeCompressString("collation").GetTaggedValue()); + SetConstant(ConstantIndex::HOUR_CYCLE_STRING_CLASS_INDEX, + factory->NewFromCanBeCompressString("hourCycle").GetTaggedValue()); + SetConstant(ConstantIndex::CASE_FIRST_STRING_CLASS_INDEX, + factory->NewFromCanBeCompressString("caseFirst").GetTaggedValue()); + SetConstant(ConstantIndex::NUMERIC_STRING_CLASS_INDEX, + factory->NewFromCanBeCompressString("numeric").GetTaggedValue()); SetConstant(ConstantIndex::NUMBERING_SYSTEM_STRING_CLASS_INDEX, - factory->NewFromString("numberingSystem").GetTaggedValue()); - SetConstant(ConstantIndex::TYPE_STRING_INDEX, factory->NewFromString("type").GetTaggedValue()); - SetConstant(ConstantIndex::LOCALE_MATCHER_STRING_INDEX, factory->NewFromString("localeMatcher").GetTaggedValue()); - SetConstant(ConstantIndex::FORMAT_MATCHER_STRING_INDEX, factory->NewFromString("formatMatcher").GetTaggedValue()); - SetConstant(ConstantIndex::HOUR12_STRING_INDEX, factory->NewFromString("hour12").GetTaggedValue()); - SetConstant(ConstantIndex::H11_STRING_INDEX, factory->NewFromString("h11").GetTaggedValue()); - SetConstant(ConstantIndex::H12_STRING_INDEX, factory->NewFromString("h12").GetTaggedValue()); - SetConstant(ConstantIndex::H23_STRING_INDEX, factory->NewFromString("h23").GetTaggedValue()); - SetConstant(ConstantIndex::H24_STRING_INDEX, factory->NewFromString("h24").GetTaggedValue()); - SetConstant(ConstantIndex::WEEK_DAY_STRING_INDEX, factory->NewFromString("weekday").GetTaggedValue()); - SetConstant(ConstantIndex::ERA_STRING_INDEX, factory->NewFromString("era").GetTaggedValue()); - SetConstant(ConstantIndex::YEAR_STRING_INDEX, factory->NewFromString("year").GetTaggedValue()); - SetConstant(ConstantIndex::QUARTER_STRING_INDEX, factory->NewFromString("quarter").GetTaggedValue()); - SetConstant(ConstantIndex::MONTH_STRING_INDEX, factory->NewFromString("month").GetTaggedValue()); - SetConstant(ConstantIndex::DAY_STRING_INDEX, factory->NewFromString("day").GetTaggedValue()); - SetConstant(ConstantIndex::HOUR_STRING_INDEX, factory->NewFromString("hour").GetTaggedValue()); - SetConstant(ConstantIndex::MINUTE_STRING_INDEX, factory->NewFromString("minute").GetTaggedValue()); - SetConstant(ConstantIndex::SECOND_STRING_INDEX, factory->NewFromString("second").GetTaggedValue()); - SetConstant(ConstantIndex::YEARS_STRING_INDEX, factory->NewFromString("years").GetTaggedValue()); - SetConstant(ConstantIndex::QUARTERS_STRING_INDEX, factory->NewFromString("quarters").GetTaggedValue()); - SetConstant(ConstantIndex::MONTHS_STRING_INDEX, factory->NewFromString("months").GetTaggedValue()); - SetConstant(ConstantIndex::DAYS_STRING_INDEX, factory->NewFromString("days").GetTaggedValue()); - SetConstant(ConstantIndex::HOURS_STRING_INDEX, factory->NewFromString("hours").GetTaggedValue()); - SetConstant(ConstantIndex::MINUTES_STRING_INDEX, factory->NewFromString("minutes").GetTaggedValue()); - SetConstant(ConstantIndex::SECONDS_STRING_INDEX, factory->NewFromString("seconds").GetTaggedValue()); - SetConstant(ConstantIndex::TIME_ZONE_NAME_STRING_INDEX, factory->NewFromString("timeZoneName").GetTaggedValue()); - SetConstant(ConstantIndex::LOCALE_STRING_INDEX, factory->NewFromString("locale").GetTaggedValue()); - SetConstant(ConstantIndex::TIME_ZONE_STRING_INDEX, factory->NewFromString("timeZone").GetTaggedValue()); - SetConstant(ConstantIndex::LITERAL_STRING_INDEX, factory->NewFromString("literal").GetTaggedValue()); - SetConstant(ConstantIndex::YEAR_NAME_STRING_INDEX, factory->NewFromString("yearName").GetTaggedValue()); - SetConstant(ConstantIndex::DAY_PERIOD_STRING_INDEX, factory->NewFromString("dayPeriod").GetTaggedValue()); + factory->NewFromCanBeCompressString("numberingSystem").GetTaggedValue()); + SetConstant(ConstantIndex::TYPE_STRING_INDEX, factory->NewFromCanBeCompressString("type").GetTaggedValue()); + SetConstant(ConstantIndex::LOCALE_MATCHER_STRING_INDEX, + factory->NewFromCanBeCompressString("localeMatcher").GetTaggedValue()); + SetConstant(ConstantIndex::FORMAT_MATCHER_STRING_INDEX, + factory->NewFromCanBeCompressString("formatMatcher").GetTaggedValue()); + SetConstant(ConstantIndex::HOUR12_STRING_INDEX, factory->NewFromCanBeCompressString("hour12").GetTaggedValue()); + SetConstant(ConstantIndex::H11_STRING_INDEX, factory->NewFromCanBeCompressString("h11").GetTaggedValue()); + SetConstant(ConstantIndex::H12_STRING_INDEX, factory->NewFromCanBeCompressString("h12").GetTaggedValue()); + SetConstant(ConstantIndex::H23_STRING_INDEX, factory->NewFromCanBeCompressString("h23").GetTaggedValue()); + SetConstant(ConstantIndex::H24_STRING_INDEX, factory->NewFromCanBeCompressString("h24").GetTaggedValue()); + SetConstant(ConstantIndex::WEEK_DAY_STRING_INDEX, factory->NewFromCanBeCompressString("weekday").GetTaggedValue()); + SetConstant(ConstantIndex::ERA_STRING_INDEX, factory->NewFromCanBeCompressString("era").GetTaggedValue()); + SetConstant(ConstantIndex::YEAR_STRING_INDEX, factory->NewFromCanBeCompressString("year").GetTaggedValue()); + SetConstant(ConstantIndex::QUARTER_STRING_INDEX, factory->NewFromCanBeCompressString("quarter").GetTaggedValue()); + SetConstant(ConstantIndex::MONTH_STRING_INDEX, factory->NewFromCanBeCompressString("month").GetTaggedValue()); + SetConstant(ConstantIndex::DAY_STRING_INDEX, factory->NewFromCanBeCompressString("day").GetTaggedValue()); + SetConstant(ConstantIndex::HOUR_STRING_INDEX, factory->NewFromCanBeCompressString("hour").GetTaggedValue()); + SetConstant(ConstantIndex::MINUTE_STRING_INDEX, factory->NewFromCanBeCompressString("minute").GetTaggedValue()); + SetConstant(ConstantIndex::SECOND_STRING_INDEX, factory->NewFromCanBeCompressString("second").GetTaggedValue()); + SetConstant(ConstantIndex::YEARS_STRING_INDEX, factory->NewFromCanBeCompressString("years").GetTaggedValue()); + SetConstant(ConstantIndex::QUARTERS_STRING_INDEX, factory->NewFromCanBeCompressString("quarters").GetTaggedValue()); + SetConstant(ConstantIndex::MONTHS_STRING_INDEX, factory->NewFromCanBeCompressString("months").GetTaggedValue()); + SetConstant(ConstantIndex::DAYS_STRING_INDEX, factory->NewFromCanBeCompressString("days").GetTaggedValue()); + SetConstant(ConstantIndex::HOURS_STRING_INDEX, factory->NewFromCanBeCompressString("hours").GetTaggedValue()); + SetConstant(ConstantIndex::MINUTES_STRING_INDEX, factory->NewFromCanBeCompressString("minutes").GetTaggedValue()); + SetConstant(ConstantIndex::SECONDS_STRING_INDEX, factory->NewFromCanBeCompressString("seconds").GetTaggedValue()); + SetConstant(ConstantIndex::TIME_ZONE_NAME_STRING_INDEX, + factory->NewFromCanBeCompressString("timeZoneName").GetTaggedValue()); + SetConstant(ConstantIndex::LOCALE_STRING_INDEX, factory->NewFromCanBeCompressString("locale").GetTaggedValue()); + SetConstant(ConstantIndex::TIME_ZONE_STRING_INDEX, + factory->NewFromCanBeCompressString("timeZone").GetTaggedValue()); + SetConstant(ConstantIndex::LITERAL_STRING_INDEX, factory->NewFromCanBeCompressString("literal").GetTaggedValue()); + SetConstant(ConstantIndex::YEAR_NAME_STRING_INDEX, + factory->NewFromCanBeCompressString("yearName").GetTaggedValue()); + SetConstant(ConstantIndex::DAY_PERIOD_STRING_INDEX, + factory->NewFromCanBeCompressString("dayPeriod").GetTaggedValue()); SetConstant(ConstantIndex::FRACTIONAL_SECOND_DIGITS_STRING_INDEX, - factory->NewFromString("fractionalSecondDigits").GetTaggedValue()); + factory->NewFromCanBeCompressString("fractionalSecondDigits").GetTaggedValue()); SetConstant(ConstantIndex::FRACTIONAL_SECOND_STRING_INDEX, - factory->NewFromString("fractionalSecond").GetTaggedValue()); - SetConstant(ConstantIndex::RELATED_YEAR_STRING_INDEX, factory->NewFromString("relatedYear").GetTaggedValue()); - SetConstant(ConstantIndex::LOOK_UP_STRING_INDEX, factory->NewFromString("lookup").GetTaggedValue()); - SetConstant(ConstantIndex::BEST_FIT_STRING_INDEX, factory->NewFromString("bestfit").GetTaggedValue()); - SetConstant(ConstantIndex::DATE_STYLE_STRING_INDEX, factory->NewFromString("dateStyle").GetTaggedValue()); - SetConstant(ConstantIndex::TIME_STYLE_STRING_INDEX, factory->NewFromString("timeStyle").GetTaggedValue()); - SetConstant(ConstantIndex::UTC_STRING_INDEX, factory->NewFromString("UTC").GetTaggedValue()); - SetConstant(ConstantIndex::INITIALIZED_RELATIVE_INDEX, factory->NewFromString("true").GetTaggedValue()); - SetConstant(ConstantIndex::WEEK_STRING_INDEX, factory->NewFromString("week").GetTaggedValue()); - SetConstant(ConstantIndex::WEEKS_STRING_INDEX, factory->NewFromString("weeks").GetTaggedValue()); - SetConstant(ConstantIndex::SOURCE_STRING_INDEX, factory->NewFromString("source").GetTaggedValue()); - SetConstant(ConstantIndex::FORMAT_STRING_INDEX, factory->NewFromString("format").GetTaggedValue()); - SetConstant(ConstantIndex::EN_US_STRING_INDEX, factory->NewFromString("en-US").GetTaggedValue()); - SetConstant(ConstantIndex::UND_STRING_INDEX, factory->NewFromString("und").GetTaggedValue()); - SetConstant(ConstantIndex::LATN_STRING_INDEX, factory->NewFromString("latn").GetTaggedValue()); - SetConstant(ConstantIndex::STYLE_STRING_INDEX, factory->NewFromString("style").GetTaggedValue()); - SetConstant(ConstantIndex::UNIT_STRING_INDEX, factory->NewFromString("unit").GetTaggedValue()); - SetConstant(ConstantIndex::INTEGER_STRING_INDEX, factory->NewFromString("integer").GetTaggedValue()); - SetConstant(ConstantIndex::NAN_STRING_INDEX, factory->NewFromString("nan").GetTaggedValue()); - SetConstant(ConstantIndex::INFINITY_STRING_INDEX, factory->NewFromString("infinity").GetTaggedValue()); - SetConstant(ConstantIndex::FRACTION_STRING_INDEX, factory->NewFromString("fraction").GetTaggedValue()); - SetConstant(ConstantIndex::DECIMAL_STRING_INDEX, factory->NewFromString("decimal").GetTaggedValue()); - SetConstant(ConstantIndex::GROUP_STRING_INDEX, factory->NewFromString("group").GetTaggedValue()); - SetConstant(ConstantIndex::CURRENCY_STRING_INDEX, factory->NewFromString("currency").GetTaggedValue()); - SetConstant(ConstantIndex::CURRENCY_SIGN_STRING_INDEX, factory->NewFromString("currencySign").GetTaggedValue()); + factory->NewFromCanBeCompressString("fractionalSecond").GetTaggedValue()); + SetConstant(ConstantIndex::RELATED_YEAR_STRING_INDEX, + factory->NewFromCanBeCompressString("relatedYear").GetTaggedValue()); + SetConstant(ConstantIndex::LOOK_UP_STRING_INDEX, factory->NewFromCanBeCompressString("lookup").GetTaggedValue()); + SetConstant(ConstantIndex::BEST_FIT_STRING_INDEX, factory->NewFromCanBeCompressString("bestfit").GetTaggedValue()); + SetConstant(ConstantIndex::DATE_STYLE_STRING_INDEX, + factory->NewFromCanBeCompressString("dateStyle").GetTaggedValue()); + SetConstant(ConstantIndex::TIME_STYLE_STRING_INDEX, + factory->NewFromCanBeCompressString("timeStyle").GetTaggedValue()); + SetConstant(ConstantIndex::UTC_STRING_INDEX, factory->NewFromCanBeCompressString("UTC").GetTaggedValue()); + SetConstant(ConstantIndex::INITIALIZED_RELATIVE_INDEX, + factory->NewFromCanBeCompressString("true").GetTaggedValue()); + SetConstant(ConstantIndex::WEEK_STRING_INDEX, factory->NewFromCanBeCompressString("week").GetTaggedValue()); + SetConstant(ConstantIndex::WEEKS_STRING_INDEX, factory->NewFromCanBeCompressString("weeks").GetTaggedValue()); + SetConstant(ConstantIndex::SOURCE_STRING_INDEX, factory->NewFromCanBeCompressString("source").GetTaggedValue()); + SetConstant(ConstantIndex::FORMAT_STRING_INDEX, factory->NewFromCanBeCompressString("format").GetTaggedValue()); + SetConstant(ConstantIndex::EN_US_STRING_INDEX, factory->NewFromCanBeCompressString("en-US").GetTaggedValue()); + SetConstant(ConstantIndex::UND_STRING_INDEX, factory->NewFromCanBeCompressString("und").GetTaggedValue()); + SetConstant(ConstantIndex::LATN_STRING_INDEX, factory->NewFromCanBeCompressString("latn").GetTaggedValue()); + SetConstant(ConstantIndex::STYLE_STRING_INDEX, factory->NewFromCanBeCompressString("style").GetTaggedValue()); + SetConstant(ConstantIndex::UNIT_STRING_INDEX, factory->NewFromCanBeCompressString("unit").GetTaggedValue()); + SetConstant(ConstantIndex::INTEGER_STRING_INDEX, factory->NewFromCanBeCompressString("integer").GetTaggedValue()); + SetConstant(ConstantIndex::NAN_STRING_INDEX, factory->NewFromCanBeCompressString("nan").GetTaggedValue()); + SetConstant(ConstantIndex::INFINITY_STRING_INDEX, factory->NewFromCanBeCompressString("infinity").GetTaggedValue()); + SetConstant(ConstantIndex::FRACTION_STRING_INDEX, factory->NewFromCanBeCompressString("fraction").GetTaggedValue()); + SetConstant(ConstantIndex::DECIMAL_STRING_INDEX, factory->NewFromCanBeCompressString("decimal").GetTaggedValue()); + SetConstant(ConstantIndex::GROUP_STRING_INDEX, factory->NewFromCanBeCompressString("group").GetTaggedValue()); + SetConstant(ConstantIndex::CURRENCY_STRING_INDEX, factory->NewFromCanBeCompressString("currency").GetTaggedValue()); + SetConstant(ConstantIndex::CURRENCY_SIGN_STRING_INDEX, + factory->NewFromCanBeCompressString("currencySign").GetTaggedValue()); SetConstant(ConstantIndex::CURRENCY_DISPLAY_STRING_INDEX, - factory->NewFromString("currencyDisplay").GetTaggedValue()); - SetConstant(ConstantIndex::PERCENT_SIGN_STRING_INDEX, factory->NewFromString("percentSign").GetTaggedValue()); - SetConstant(ConstantIndex::PERCENT_STRING_INDEX, factory->NewFromString("percent").GetTaggedValue()); - SetConstant(ConstantIndex::MINUS_SIGN_STRING_INDEX, factory->NewFromString("minusSign").GetTaggedValue()); - SetConstant(ConstantIndex::PLUS_SIGN_STRING_INDEX, factory->NewFromString("plusSign").GetTaggedValue()); + factory->NewFromCanBeCompressString("currencyDisplay").GetTaggedValue()); + SetConstant(ConstantIndex::PERCENT_SIGN_STRING_INDEX, + factory->NewFromCanBeCompressString("percentSign").GetTaggedValue()); + SetConstant(ConstantIndex::PERCENT_STRING_INDEX, factory->NewFromCanBeCompressString("percent").GetTaggedValue()); + SetConstant(ConstantIndex::MINUS_SIGN_STRING_INDEX, + factory->NewFromCanBeCompressString("minusSign").GetTaggedValue()); + SetConstant(ConstantIndex::PLUS_SIGN_STRING_INDEX, + factory->NewFromCanBeCompressString("plusSign").GetTaggedValue()); SetConstant(ConstantIndex::EXPONENT_SEPARATOR_STRING_INDEX, - factory->NewFromString("exponentSeparator").GetTaggedValue()); - SetConstant(ConstantIndex::EXPONENT_MINUS_SIGN_INDEX, factory->NewFromString("exponentMinusSign").GetTaggedValue()); + factory->NewFromCanBeCompressString("exponentSeparator").GetTaggedValue()); + SetConstant(ConstantIndex::EXPONENT_MINUS_SIGN_INDEX, + factory->NewFromCanBeCompressString("exponentMinusSign").GetTaggedValue()); SetConstant(ConstantIndex::EXPONENT_INTEGER_STRING_INDEX, - factory->NewFromString("exponentInteger").GetTaggedValue()); - SetConstant(ConstantIndex::LONG_STRING_INDEX, factory->NewFromString("long").GetTaggedValue()); - SetConstant(ConstantIndex::SHORT_STRING_INDEX, factory->NewFromString("short").GetTaggedValue()); - SetConstant(ConstantIndex::FULL_STRING_INDEX, factory->NewFromString("full").GetTaggedValue()); - SetConstant(ConstantIndex::MEDIUM_STRING_INDEX, factory->NewFromString("medium").GetTaggedValue()); - SetConstant(ConstantIndex::NARROW_STRING_INDEX, factory->NewFromString("narrow").GetTaggedValue()); - SetConstant(ConstantIndex::ALWAYS_STRING_INDEX, factory->NewFromString("always").GetTaggedValue()); - SetConstant(ConstantIndex::AUTO_STRING_INDEX, factory->NewFromString("auto").GetTaggedValue()); - SetConstant(ConstantIndex::UNIT_DISPLAY_INDEX, factory->NewFromString("unitDisplay").GetTaggedValue()); - SetConstant(ConstantIndex::NOTATION_INDEX, factory->NewFromString("notation").GetTaggedValue()); - SetConstant(ConstantIndex::COMPACT_DISPALY_INDEX, factory->NewFromString("compactDisplay").GetTaggedValue()); - SetConstant(ConstantIndex::USER_GROUPING_INDEX, factory->NewFromString("useGrouping").GetTaggedValue()); - SetConstant(ConstantIndex::SIGN_DISPLAY_INDEX, factory->NewFromString("signDisplay").GetTaggedValue()); - SetConstant(ConstantIndex::CODE_INDEX, factory->NewFromString("code").GetTaggedValue()); - SetConstant(ConstantIndex::NARROW_SYMBOL_INDEX, factory->NewFromString("narrowSymbol").GetTaggedValue()); - SetConstant(ConstantIndex::STANDARD_INDEX, factory->NewFromString("standard").GetTaggedValue()); - SetConstant(ConstantIndex::ACCOUNTING_INDEX, factory->NewFromString("accounting").GetTaggedValue()); - SetConstant(ConstantIndex::SCIENTIFIC_INDEX, factory->NewFromString("scientific").GetTaggedValue()); - SetConstant(ConstantIndex::ENGINEERING_INDEX, factory->NewFromString("engineering").GetTaggedValue()); - SetConstant(ConstantIndex::COMPACT_STRING_INDEX, factory->NewFromString("compact").GetTaggedValue()); - SetConstant(ConstantIndex::NEVER_INDEX, factory->NewFromString("never").GetTaggedValue()); - SetConstant(ConstantIndex::EXPECT_ZERO_INDEX, factory->NewFromString("exceptZero").GetTaggedValue()); + factory->NewFromCanBeCompressString("exponentInteger").GetTaggedValue()); + SetConstant(ConstantIndex::LONG_STRING_INDEX, factory->NewFromCanBeCompressString("long").GetTaggedValue()); + SetConstant(ConstantIndex::SHORT_STRING_INDEX, factory->NewFromCanBeCompressString("short").GetTaggedValue()); + SetConstant(ConstantIndex::FULL_STRING_INDEX, factory->NewFromCanBeCompressString("full").GetTaggedValue()); + SetConstant(ConstantIndex::MEDIUM_STRING_INDEX, factory->NewFromCanBeCompressString("medium").GetTaggedValue()); + SetConstant(ConstantIndex::NARROW_STRING_INDEX, factory->NewFromCanBeCompressString("narrow").GetTaggedValue()); + SetConstant(ConstantIndex::ALWAYS_STRING_INDEX, factory->NewFromCanBeCompressString("always").GetTaggedValue()); + SetConstant(ConstantIndex::AUTO_STRING_INDEX, factory->NewFromCanBeCompressString("auto").GetTaggedValue()); + SetConstant(ConstantIndex::UNIT_DISPLAY_INDEX, factory->NewFromCanBeCompressString("unitDisplay").GetTaggedValue()); + SetConstant(ConstantIndex::NOTATION_INDEX, factory->NewFromCanBeCompressString("notation").GetTaggedValue()); + SetConstant(ConstantIndex::COMPACT_DISPALY_INDEX, + factory->NewFromCanBeCompressString("compactDisplay").GetTaggedValue()); + SetConstant(ConstantIndex::USER_GROUPING_INDEX, + factory->NewFromCanBeCompressString("useGrouping").GetTaggedValue()); + SetConstant(ConstantIndex::SIGN_DISPLAY_INDEX, factory->NewFromCanBeCompressString("signDisplay").GetTaggedValue()); + SetConstant(ConstantIndex::CODE_INDEX, factory->NewFromCanBeCompressString("code").GetTaggedValue()); + SetConstant(ConstantIndex::NARROW_SYMBOL_INDEX, + factory->NewFromCanBeCompressString("narrowSymbol").GetTaggedValue()); + SetConstant(ConstantIndex::STANDARD_INDEX, factory->NewFromCanBeCompressString("standard").GetTaggedValue()); + SetConstant(ConstantIndex::ACCOUNTING_INDEX, factory->NewFromCanBeCompressString("accounting").GetTaggedValue()); + SetConstant(ConstantIndex::SCIENTIFIC_INDEX, factory->NewFromCanBeCompressString("scientific").GetTaggedValue()); + SetConstant(ConstantIndex::ENGINEERING_INDEX, factory->NewFromCanBeCompressString("engineering").GetTaggedValue()); + SetConstant(ConstantIndex::COMPACT_STRING_INDEX, factory->NewFromCanBeCompressString("compact").GetTaggedValue()); + SetConstant(ConstantIndex::NEVER_INDEX, factory->NewFromCanBeCompressString("never").GetTaggedValue()); + SetConstant(ConstantIndex::EXPECT_ZERO_INDEX, factory->NewFromCanBeCompressString("exceptZero").GetTaggedValue()); SetConstant(ConstantIndex::MINIMUM_INTEGER_DIGITS_INDEX, - factory->NewFromString("minimumIntegerDigits").GetTaggedValue()); + factory->NewFromCanBeCompressString("minimumIntegerDigits").GetTaggedValue()); SetConstant(ConstantIndex::MINIMUM_FRACTIONDIGITS_INDEX, - factory->NewFromString("minimumFractionDigits").GetTaggedValue()); + factory->NewFromCanBeCompressString("minimumFractionDigits").GetTaggedValue()); SetConstant(ConstantIndex::MAXIMUM_FRACTIONDIGITS_INDEX, - factory->NewFromString("maximumFractionDigits").GetTaggedValue()); + factory->NewFromCanBeCompressString("maximumFractionDigits").GetTaggedValue()); SetConstant(ConstantIndex::MINIMUM_SIGNIFICANTDIGITS_INDEX, - factory->NewFromString("minimumSignificantDigits").GetTaggedValue()); + factory->NewFromCanBeCompressString("minimumSignificantDigits").GetTaggedValue()); SetConstant(ConstantIndex::MAXIMUM_SIGNIFICANTDIGITS_INDEX, - factory->NewFromString("maximumSignificantDigits").GetTaggedValue()); - SetConstant(ConstantIndex::INVALID_DATE_INDEX, factory->NewFromString("InvalidDate").GetTaggedValue()); - SetConstant(ConstantIndex::USAGE_INDEX, factory->NewFromString("usage").GetTaggedValue()); - SetConstant(ConstantIndex::COMPARE_INDEX, factory->NewFromString("compare").GetTaggedValue()); - SetConstant(ConstantIndex::SENSITIVITY_INDEX, factory->NewFromString("sensitivity").GetTaggedValue()); - SetConstant(ConstantIndex::IGNORE_PUNCTUATION_INDEX, factory->NewFromString("ignorePunctuation").GetTaggedValue()); - SetConstant(ConstantIndex::CARDINAL_INDEX, factory->NewFromString("cardinal").GetTaggedValue()); - SetConstant(ConstantIndex::ORDINAL_INDEX, factory->NewFromString("ordinal").GetTaggedValue()); - SetConstant(ConstantIndex::EXEC_INDEX, factory->NewFromString("exec").GetTaggedValue()); - SetConstant(ConstantIndex::LAST_INDEX_INDEX, factory->NewFromString("lastIndex").GetTaggedValue()); + factory->NewFromCanBeCompressString("maximumSignificantDigits").GetTaggedValue()); + SetConstant(ConstantIndex::INVALID_DATE_INDEX, + factory->NewFromCanBeCompressString("Invalid Date").GetTaggedValue()); + SetConstant(ConstantIndex::USAGE_INDEX, factory->NewFromCanBeCompressString("usage").GetTaggedValue()); + SetConstant(ConstantIndex::COMPARE_INDEX, factory->NewFromCanBeCompressString("compare").GetTaggedValue()); + SetConstant(ConstantIndex::SENSITIVITY_INDEX, factory->NewFromCanBeCompressString("sensitivity").GetTaggedValue()); + SetConstant(ConstantIndex::IGNORE_PUNCTUATION_INDEX, + factory->NewFromCanBeCompressString("ignorePunctuation").GetTaggedValue()); + SetConstant(ConstantIndex::CARDINAL_INDEX, factory->NewFromCanBeCompressString("cardinal").GetTaggedValue()); + SetConstant(ConstantIndex::ORDINAL_INDEX, factory->NewFromCanBeCompressString("ordinal").GetTaggedValue()); + SetConstant(ConstantIndex::EXEC_INDEX, factory->NewFromCanBeCompressString("exec").GetTaggedValue()); + SetConstant(ConstantIndex::LAST_INDEX_INDEX, factory->NewFromCanBeCompressString("lastIndex").GetTaggedValue()); + SetConstant(ConstantIndex::PLURAL_CATEGORIES_INDEX, + factory->NewFromCanBeCompressString("pluralCategories").GetTaggedValue()); + SetConstant(ConstantIndex::SORT_INDEX, factory->NewFromCanBeCompressString("sort").GetTaggedValue()); + SetConstant(ConstantIndex::SEARCH_INDEX, factory->NewFromCanBeCompressString("search").GetTaggedValue()); + SetConstant(ConstantIndex::BASE_INDEX, factory->NewFromCanBeCompressString("base").GetTaggedValue()); + SetConstant(ConstantIndex::ACCENT_INDEX, factory->NewFromCanBeCompressString("accent").GetTaggedValue()); + SetConstant(ConstantIndex::CASE_INDEX, factory->NewFromCanBeCompressString("case").GetTaggedValue()); + SetConstant(ConstantIndex::VARIANT_INDEX, factory->NewFromCanBeCompressString("variant").GetTaggedValue()); + SetConstant(ConstantIndex::EN_US_POSIX_STRING_INDEX, + factory->NewFromCanBeCompressString("en-US-POSIX").GetTaggedValue()); + SetConstant(ConstantIndex::UPPER_INDEX, factory->NewFromCanBeCompressString("upper").GetTaggedValue()); + SetConstant(ConstantIndex::LOWER_INDEX, factory->NewFromCanBeCompressString("lower").GetTaggedValue()); + SetConstant(ConstantIndex::DEFAULT_INDEX, factory->NewFromCanBeCompressString("default").GetTaggedValue()); + SetConstant(ConstantIndex::SHARED_INDEX, factory->NewFromCanBeCompressString("shared").GetTaggedValue()); + SetConstant(ConstantIndex::START_RANGE_INDEX, factory->NewFromCanBeCompressString("startRange").GetTaggedValue()); + SetConstant(ConstantIndex::END_RANGE_INDEX, factory->NewFromCanBeCompressString("endRange").GetTaggedValue()); + SetConstant(ConstantIndex::ISO8601_INDEX, factory->NewFromCanBeCompressString("iso8601").GetTaggedValue()); + SetConstant(ConstantIndex::GREGORY_INDEX, factory->NewFromCanBeCompressString("gregory").GetTaggedValue()); + SetConstant(ConstantIndex::ETHIOAA_INDEX, factory->NewFromCanBeCompressString("ethioaa").GetTaggedValue()); auto accessor = factory->NewInternalAccessor(reinterpret_cast(JSFunction::PrototypeSetter), reinterpret_cast(JSFunction::PrototypeGetter)); SetConstant(ConstantIndex::FUNCTION_PROTOTYPE_ACCESSOR, accessor.GetTaggedValue()); accessor = factory->NewInternalAccessor(nullptr, reinterpret_cast(JSFunction::NameGetter)); SetConstant(ConstantIndex::FUNCTION_NAME_ACCESSOR, accessor.GetTaggedValue()); - accessor = factory->NewInternalAccessor(nullptr, reinterpret_cast(JSFunction::LengthGetter)); - SetConstant(ConstantIndex::FUNCTION_LENGTH_ACCESSOR, accessor.GetTaggedValue()); accessor = factory->NewInternalAccessor(reinterpret_cast(JSArray::LengthSetter), reinterpret_cast(JSArray::LengthGetter)); SetConstant(ConstantIndex::ARRAY_LENGTH_ACCESSOR, accessor.GetTaggedValue()); diff --git a/ecmascript/global_env_constants.h b/ecmascript/global_env_constants.h index 7ca719d4fc170471a1216d63f1dcbd96ff7a268f..7c90e113baff0c7e336a43f051a36d3801d2a69f 100644 --- a/ecmascript/global_env_constants.h +++ b/ecmascript/global_env_constants.h @@ -24,7 +24,7 @@ namespace panda::ecmascript { // Forward Declaration class ObjectFactory; -template +template class JSHandle; class JSHClass; class JSThread; @@ -66,7 +66,8 @@ class JSThread; V(JSTaggedValue, JSProxyCallableClass, JS_PROXY_CALLABLE_CLASS_INDEX, ecma_roots_class) \ V(JSTaggedValue, JSProxyConstructClass, JS_PROXY_CONSTRUCT_CLASS_INDEX, ecma_roots_class) \ V(JSTaggedValue, JSRealmClass, JS_REALM_CLASS_INDEX, ecma_roots_class) \ - V(JSTaggedValue, JSRegExpClass, JS_REGEXP_CLASS_INDEX, ecma_roots_class) + V(JSTaggedValue, JSRegExpClass, JS_REGEXP_CLASS_INDEX, ecma_roots_class) \ + V(JSTaggedValue, MachineCodeClass, MACHINE_CODE_CLASS_INDEX, ecma_roots_class) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define GLOBAL_ENV_CONSTANT_SPECIAL(V) \ @@ -263,6 +264,23 @@ class JSThread; V(JSTaggedValue, IgnorePunctuationString, IGNORE_PUNCTUATION_INDEX, ignorePunctuation) \ V(JSTaggedValue, CardinalString, CARDINAL_INDEX, cardinal) \ V(JSTaggedValue, OrdinalString, ORDINAL_INDEX, ordinal) \ + V(JSTaggedValue, PluralCategoriesString, PLURAL_CATEGORIES_INDEX, pluralCategories) \ + V(JSTaggedValue, SortString, SORT_INDEX, sort) \ + V(JSTaggedValue, SearchString, SEARCH_INDEX, search) \ + V(JSTaggedValue, BaseString, BASE_INDEX, base) \ + V(JSTaggedValue, AccentString, ACCENT_INDEX, accent) \ + V(JSTaggedValue, CaseString, CASE_INDEX, Case) \ + V(JSTaggedValue, VariantString, VARIANT_INDEX, variant) \ + V(JSTaggedValue, EnUsPosixString, EN_US_POSIX_STRING_INDEX, en - US - POSIX) \ + V(JSTaggedValue, UpperString, UPPER_INDEX, upper) \ + V(JSTaggedValue, LowerString, LOWER_INDEX, lower) \ + V(JSTaggedValue, DefaultString, DEFAULT_INDEX, Default) \ + V(JSTaggedValue, SharedString, SHARED_INDEX, shared) \ + V(JSTaggedValue, StartRangeString, START_RANGE_INDEX, startRange) \ + V(JSTaggedValue, EndRangeString, END_RANGE_INDEX, endRange) \ + V(JSTaggedValue, Iso8601String, ISO8601_INDEX, iso8601) \ + V(JSTaggedValue, GregoryString, GREGORY_INDEX, gregory) \ + V(JSTaggedValue, EthioaaString, ETHIOAA_INDEX, ethioaa) \ /* for regexp. */ \ V(JSTaggedValue, ExecString, EXEC_INDEX, exec) \ V(JSTaggedValue, LastIndexString, LAST_INDEX_INDEX, lastIndex) @@ -271,7 +289,6 @@ class JSThread; #define GLOBAL_ENV_CONSTANT_ACCESSOR(V) \ V(JSTaggedValue, FunctionPrototypeAccessor, FUNCTION_PROTOTYPE_ACCESSOR, ecma_roots_accessor) \ V(JSTaggedValue, FunctionNameAccessor, FUNCTION_NAME_ACCESSOR, ecma_roots_accessor) \ - V(JSTaggedValue, FunctionLengthAccessor, FUNCTION_LENGTH_ACCESSOR, ecma_roots_accessor) \ V(JSTaggedValue, ArrayLengthAccessor, ARRAY_LENGTH_ACCESSOR, ecma_roots_accessor) /* RealmConstant */ @@ -315,6 +332,8 @@ public: void SetConstant(ConstantIndex index, JSTaggedValue value); + uintptr_t GetGlobalConstantAddr(ConstantIndex index) const; + // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define DECL_GET(Type, Name, Index, Desc) \ const Type Get##Name() const; \ diff --git a/ecmascript/global_handle_collection.h b/ecmascript/global_handle_collection.h index fd02adc16f1a6287572b1bd413004153c18e0192..8e99ceec4141f47f96e82a97421d6a9c2707f227 100644 --- a/ecmascript/global_handle_collection.h +++ b/ecmascript/global_handle_collection.h @@ -13,13 +13,13 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_GLOBAL_HANDLE_COLLECTION_H -#define PANDA_RUNTIME_ECMASCRIPT_GLOBAL_HANDLE_COLLECTION_H +#ifndef ECMASCRIPT_GLOBAL_HANDLE_COLLECTION_H +#define ECMASCRIPT_GLOBAL_HANDLE_COLLECTION_H #include "ecmascript/js_thread.h" namespace panda::ecmascript { -template +template class JSHandle; class GlobalHandleCollection { public: @@ -30,16 +30,17 @@ public: DEFAULT_MOVE_SEMANTIC(GlobalHandleCollection); DEFAULT_COPY_SEMANTIC(GlobalHandleCollection); - template + template JSHandle NewHandle(JSTaggedType value) { - uintptr_t addr = thread_->GetGlobalHandleStorage()->NewGlobalHandle(value); + uintptr_t addr = thread_->GetEcmaGlobalStorage()->NewGlobalHandle(value); return JSHandle(addr); } - void Dispose(HandleBase handle) + template + void Dispose(JSHandle handle) { - thread_->GetGlobalHandleStorage()->DisposeGlobalHandle(handle.GetAddress()); + thread_->GetEcmaGlobalStorage()->DisposeGlobalHandle(handle.GetAddress()); } private: @@ -47,4 +48,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_GLOBAL_HANDLE_COLLECTION_H +#endif // ECMASCRIPT_GLOBAL_HANDLE_COLLECTION_H diff --git a/ecmascript/hprof/heap_profiler.cpp b/ecmascript/hprof/heap_profiler.cpp index 759c71a45edab5dc80d4d5d9309a16ee7f385721..6a2d640af63acfd297553abf9a7a21393cf67a2b 100644 --- a/ecmascript/hprof/heap_profiler.cpp +++ b/ecmascript/hprof/heap_profiler.cpp @@ -29,7 +29,7 @@ namespace panda::ecmascript { HeapProfiler::~HeapProfiler() { ClearSnapShot(); - allocator_->Finalize(jsonSerializer_); + const_cast(heap_->GetRegionFactory())->Delete(jsonSerializer_); jsonSerializer_ = nullptr; } @@ -144,7 +144,6 @@ CString HeapProfiler::GetTimeStamp() bool HeapProfiler::ForceFullGC(JSThread *thread) { - ASSERT(thread != nullptr); auto vm = thread->GetEcmaVM(); if (vm->IsInitialized()) { const_cast(vm->GetHeap())->CollectGarbage(TriggerGCType::SEMI_GC); @@ -160,7 +159,7 @@ HeapSnapShot *HeapProfiler::MakeHeapSnapShot(JSThread *thread, SampleType sample DISALLOW_GARBAGE_COLLECTION; switch (sampleType) { case SampleType::ONE_SHOT: { - auto *snapShot = allocator_->New(thread, allocator_); + auto *snapShot = const_cast(heap_->GetRegionFactory())->New(thread, heap_); if (snapShot == nullptr) { LOG_ECMA(FATAL) << "alloc snapshot failed"; UNREACHABLE(); @@ -170,7 +169,7 @@ HeapSnapShot *HeapProfiler::MakeHeapSnapShot(JSThread *thread, SampleType sample return snapShot; } case SampleType::REAL_TIME: { - auto *snapShot = allocator_->New(thread, allocator_); + auto *snapShot = const_cast(heap_->GetRegionFactory())->New(thread, heap_); if (snapShot == nullptr) { LOG_ECMA(FATAL) << "alloc snapshot failed"; UNREACHABLE(); @@ -196,7 +195,7 @@ void HeapProfiler::AddSnapShot(HeapSnapShot *snapshot) void HeapProfiler::ClearSnapShot() { for (auto *snapshot : hprofs_) { - allocator_->Finalize(snapshot); + const_cast(heap_->GetRegionFactory())->Delete(snapshot); } hprofs_.clear(); } diff --git a/ecmascript/hprof/heap_profiler.h b/ecmascript/hprof/heap_profiler.h index 15ebb50e446ff52d6ab0906820d19f6dff43b9dc..a516645df78e51fd5ad0247c38c5b7914091fa3c 100644 --- a/ecmascript/hprof/heap_profiler.h +++ b/ecmascript/hprof/heap_profiler.h @@ -13,14 +13,15 @@ * limitations under the License. */ -#ifndef RUNTIME_ECMASCRIPT_HPROF_HEAP_PROFILER_H -#define RUNTIME_ECMASCRIPT_HPROF_HEAP_PROFILER_H +#ifndef ECMASCRIPT_HPROF_HEAP_PROFILER_H +#define ECMASCRIPT_HPROF_HEAP_PROFILER_H #include "ecmascript/ecma_macros.h" #include "ecmascript/hprof/heap_profiler_interface.h" #include "ecmascript/hprof/heap_snapshot_json_serializer.h" #include "ecmascript/hprof/heap_tracker.h" #include "ecmascript/mem/c_containers.h" +#include "ecmascript/mem/heap.h" #include "os/mem.h" namespace panda::ecmascript { @@ -29,10 +30,9 @@ class HeapProfiler : public HeapProfilerInterface { public: NO_MOVE_SEMANTIC(HeapProfiler); NO_COPY_SEMANTIC(HeapProfiler); - explicit HeapProfiler(CAddressAllocator *allocator) : allocator_(allocator) + explicit HeapProfiler(const Heap *heap) : heap_(heap) { - ASSERT(allocator != nullptr); - jsonSerializer_ = allocator->New(); + jsonSerializer_ = const_cast(heap->GetRegionFactory())->New(); if (UNLIKELY(jsonSerializer_ == nullptr)) { LOG_ECMA(FATAL) << "alloc snapshot json serializer failed"; UNREACHABLE(); @@ -66,10 +66,10 @@ private: void ClearSnapShot(); const size_t MAX_NUM_HPROF = 5; // ~10MB - CAddressAllocator *allocator_{nullptr}; CVector hprofs_; HeapSnapShotJSONSerializer *jsonSerializer_{nullptr}; std::unique_ptr heapTracker_; + const Heap *heap_; }; } // namespace panda::ecmascript -#endif // RUNTIME_ECMASCRIPT_HPROF_HEAP_PROFILER_H +#endif // ECMASCRIPT_HPROF_HEAP_PROFILER_H diff --git a/ecmascript/hprof/heap_profiler_interface.cpp b/ecmascript/hprof/heap_profiler_interface.cpp index 7e2ba64055115576ee348ffcf9d75db7402e0314..93ae61bbe70ea75d72c8ac6c875006927466a7df 100644 --- a/ecmascript/hprof/heap_profiler_interface.cpp +++ b/ecmascript/hprof/heap_profiler_interface.cpp @@ -15,31 +15,32 @@ #include "ecmascript/hprof/heap_profiler.h" #include "ecmascript/js_thread.h" +#include "ecmascript/mem/heap.h" namespace panda::ecmascript { void HeapProfilerInterface::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath) { - auto allocator = thread->GetEcmaVM()->GetCountAllocator(); - auto *hprof = allocator->New(allocator); + const Heap *heap = thread->GetEcmaVM()->GetHeap(); + auto *hprof = const_cast(heap->GetRegionFactory())->New(heap); if (UNLIKELY(hprof == nullptr)) { LOG_ECMA(FATAL) << "alloc hprof failed"; UNREACHABLE(); } hprof->DumpHeapSnapShot(thread, dumpFormat, filePath); - allocator->Finalize(hprof); + const_cast(heap->GetRegionFactory())->Delete(hprof); } HeapProfilerInterface *HeapProfilerInterface::CreateHeapProfiler(JSThread *thread) { - auto allocator = thread->GetEcmaVM()->GetCountAllocator(); - auto *hprof = allocator->New(allocator); + const Heap *heap = thread->GetEcmaVM()->GetHeap(); + auto *hprof = const_cast(heap->GetRegionFactory())->New(heap); ASSERT(hprof != nullptr); return hprof; } void HeapProfilerInterface::Destory(JSThread *thread, HeapProfilerInterface *heapProfiler) { - auto allocator = thread->GetEcmaVM()->GetCountAllocator(); - allocator->Finalize(heapProfiler); + const Heap *heap = thread->GetEcmaVM()->GetHeap(); + const_cast(heap->GetRegionFactory())->Delete(heapProfiler); } } // namespace panda::ecmascript diff --git a/ecmascript/hprof/heap_profiler_interface.h b/ecmascript/hprof/heap_profiler_interface.h index e27142ff5d775e452ebd06b74534c6525af515a7..736f8167479484e0a28dbfb5185e1cd26edb67a3 100644 --- a/ecmascript/hprof/heap_profiler_interface.h +++ b/ecmascript/hprof/heap_profiler_interface.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef RUNTIME_ECMASCRIPT_HPROF_HEAP_PROFILER_INTERFACE_H -#define RUNTIME_ECMASCRIPT_HPROF_HEAP_PROFILER_INTERFACE_H +#ifndef ECMASCRIPT_HPROF_HEAP_PROFILER_INTERFACE_H +#define ECMASCRIPT_HPROF_HEAP_PROFILER_INTERFACE_H #include "ecmascript/mem/c_string.h" #include "ecmascript/js_thread.h" @@ -39,4 +39,4 @@ public: NO_COPY_SEMANTIC(HeapProfilerInterface); }; } // namespace panda::ecmascript -#endif // RUNTIME_ECMASCRIPT_HPROF_HEAP_PROFILER_INTERFACE_H +#endif // ECMASCRIPT_HPROF_HEAP_PROFILER_INTERFACE_H diff --git a/ecmascript/hprof/heap_root_visitor.h b/ecmascript/hprof/heap_root_visitor.h index 0b317e4fcc288bab5092ebaf3a53f5b7e41948a9..a7e509146ed7f832dc6e01839633cf4e76dd3066 100644 --- a/ecmascript/hprof/heap_root_visitor.h +++ b/ecmascript/hprof/heap_root_visitor.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef RUNTIME_ECMASCRIPT_HPROF_HEAP_ROOT_VISITOR_H -#define RUNTIME_ECMASCRIPT_HPROF_HEAP_ROOT_VISITOR_H +#ifndef ECMASCRIPT_HPROF_HEAP_ROOT_VISITOR_H +#define ECMASCRIPT_HPROF_HEAP_ROOT_VISITOR_H #include "ecmascript/mem/heap_roots.h" @@ -33,4 +33,4 @@ private: EcmaVM *GetVMInstance(JSThread *thread) const; }; } // namespace panda::ecmascript -#endif // RUNTIME_ECMASCRIPT_HPROF_HEAP_ROOT_VISITOR_H +#endif // ECMASCRIPT_HPROF_HEAP_ROOT_VISITOR_H diff --git a/ecmascript/hprof/heap_snapshot.cpp b/ecmascript/hprof/heap_snapshot.cpp index e6b373cefd1808c203ff02a5710f65d2c33daeea..32512f9f6b8c1e55df4ff1edcc07edae77c4e0f3 100644 --- a/ecmascript/hprof/heap_snapshot.cpp +++ b/ecmascript/hprof/heap_snapshot.cpp @@ -34,25 +34,16 @@ #include "ecmascript/tagged_dictionary.h" namespace panda::ecmascript { -// NOLINTNEXTLINE(fuchsia-statically-constructed-objects) -CAddressAllocator *HeapSnapShot::allocator_ = nullptr; - -CAddressAllocator *HeapSnapShot::GetAllocator() -{ - ASSERT(allocator_ != nullptr); - return allocator_; -} - CString *HeapSnapShot::GetString(const CString &as) { return stringTable_.GetString(as); } -Node *Node::NewNode(size_t id, size_t index, CString *name, NodeType type, size_t size, TaggedObject *entry, - bool isLive) +Node *Node::NewNode(const Heap *heap, size_t id, size_t index, CString *name, NodeType type, size_t size, + TaggedObject *entry, bool isLive) { - auto node = HeapSnapShot::GetAllocator()->New(id, index, name, type, size, 0, NewAddress(entry), - isLive); + auto node = const_cast( + heap->GetRegionFactory())->New(id, index, name, type, size, 0, NewAddress(entry), isLive); if (UNLIKELY(node == nullptr)) { LOG_ECMA(FATAL) << "internal allocator failed"; UNREACHABLE(); @@ -60,9 +51,9 @@ Node *Node::NewNode(size_t id, size_t index, CString *name, NodeType type, size_ return node; } -Edge *Edge::NewEdge(uint64_t id, EdgeType type, Node *from, Node *to, CString *name) +Edge *Edge::NewEdge(const Heap *heap, uint64_t id, EdgeType type, Node *from, Node *to, CString *name) { - auto edge = HeapSnapShot::GetAllocator()->New(id, type, from, to, name); + auto edge = const_cast(heap->GetRegionFactory())->New(id, type, from, to, name); if (UNLIKELY(edge == nullptr)) { LOG_ECMA(FATAL) << "internal allocator failed"; UNREACHABLE(); @@ -72,11 +63,12 @@ Edge *Edge::NewEdge(uint64_t id, EdgeType type, Node *from, Node *to, CString *n HeapSnapShot::~HeapSnapShot() { + const Heap *heap = thread_->GetEcmaVM()->GetHeap(); for (Node *node : nodes_) { - HeapSnapShot::GetAllocator()->Finalize(node); + const_cast(heap->GetRegionFactory())->Delete(node); } for (Edge *edge : edges_) { - HeapSnapShot::GetAllocator()->Finalize(edge); + const_cast(heap->GetRegionFactory())->Delete(edge); } nodes_.clear(); edges_.clear(); @@ -198,6 +190,8 @@ CString *HeapSnapShot::GenerateNodeName(JSThread *thread, TaggedObject *entry) name = GetString("JSFunctionBase"); } else if (hCls->IsJsBoundFunction()) { name = GetString("JsBoundFunction"); + } else if (hCls->IsJSIntlBoundFunction()) { + name = GetString("JSIntlBoundFunction"); } else if (hCls->IsJSProxyRevocFunction()) { name = GetString("JSProxyRevocFunction"); } else if (hCls->IsJSAsyncFunction()) { @@ -238,6 +232,16 @@ CString *HeapSnapShot::GenerateNodeName(JSThread *thread, TaggedObject *entry) name = GetString("JSRegExp"); } else if (hCls->IsJSProxy()) { name = GetString("JSProxy"); + } else if (hCls->IsJSLocale()) { + name = GetString("JSLocale"); + } else if (hCls->IsJSIntl()) { + name = GetString("JSIntl"); + } else if (hCls->IsJSDateTimeFormat()) { + name = GetString("JSDateTimeFormat"); + } else if (hCls->IsJSRelativeTimeFormat()) { + name = GetString("JSRelativeTimeFormat"); + } else if (hCls->IsJSNumberFormat()) { + name = GetString("JSNumberFormat"); } else if (hCls->IsAccessorData()) { name = GetString("AccessorData"); } else if (hCls->IsInternalAccessor()) { @@ -383,7 +387,7 @@ Node *HeapSnapShot::GenerateNode(JSThread *thread, JSTaggedValue entry, int sequ TaggedObject *obj = entry.GetTaggedObject(); auto *baseClass = obj->GetClass(); if (baseClass != nullptr) { - node = Node::NewNode(sequenceId, nodeCount_, GenerateNodeName(thread, obj), GenerateNodeType(obj), + node = Node::NewNode(heap_, sequenceId, nodeCount_, GenerateNodeName(thread, obj), GenerateNodeType(obj), obj->GetObjectSize(), obj); Node *existNode = entryMap_.FindOrInsertNode(node); // Fast Index if (existNode == node) { @@ -395,7 +399,7 @@ Node *HeapSnapShot::GenerateNode(JSThread *thread, JSTaggedValue entry, int sequ } else { existNode->SetLive(true); ASSERT(entryMap_.FindEntry(node->GetAddress())->GetAddress() == node->GetAddress()); - HeapSnapShot::GetAllocator()->Finalize(node); + const_cast(heap_->GetRegionFactory())->Delete(node); return nullptr; } } @@ -425,7 +429,8 @@ Node *HeapSnapShot::GenerateNode(JSThread *thread, JSTaggedValue entry, int sequ primitiveName.append("Illegal_Primitive"); } - node = Node::NewNode(sequenceId, nodeCount_, GetString(primitiveName), NodeType::JS_PRIMITIVE_REF, 0, obj); + node = Node::NewNode(heap_, sequenceId, nodeCount_, GetString(primitiveName), NodeType::JS_PRIMITIVE_REF, 0, + obj); Node *existNode = entryMap_.FindOrInsertNode(node); // Fast Index if (existNode == node) { if (sequenceId == sequenceId_ + SEQ_STEP) { @@ -433,7 +438,7 @@ Node *HeapSnapShot::GenerateNode(JSThread *thread, JSTaggedValue entry, int sequ } InsertNodeUnique(node); } else { - allocator_->Finalize(node); + const_cast(heap_->GetRegionFactory())->Delete(node); node = nullptr; existNode->SetLive(true); } @@ -448,7 +453,7 @@ Node *HeapSnapShot::GenerateStringNode(JSTaggedValue entry, int sequenceId) size_t selfsize = originStr->ObjectSize(); CString strContent; strContent.append(EntryVisitor::ConvertKey(entry)); - node = Node::NewNode(sequenceId, nodeCount_, GetString(strContent), NodeType::PRIM_STRING, selfsize, + node = Node::NewNode(heap_, sequenceId, nodeCount_, GetString(strContent), NodeType::PRIM_STRING, selfsize, entry.GetTaggedObject()); Node *existNode = entryMap_.FindOrInsertNode(node); // Fast Index if (existNode == node) { @@ -461,7 +466,7 @@ Node *HeapSnapShot::GenerateStringNode(JSTaggedValue entry, int sequenceId) } ASSERT(entryMap_.FindEntry(node->GetAddress())->GetAddress() == node->GetAddress()); if (existNode != node) { - HeapSnapShot::GetAllocator()->Finalize(node); + const_cast(heap_->GetRegionFactory())->Delete(node); return nullptr; } return node; @@ -484,7 +489,7 @@ void HeapSnapShot::FillEdges(JSThread *thread) entryTo = GenerateNode(thread, it.second); } if (entryTo != nullptr) { - Edge *edge = Edge::NewEdge(edgeCount_, EdgeType::DEFAULT, *iter, entryTo, GetString(it.first)); + Edge *edge = Edge::NewEdge(heap_, edgeCount_, EdgeType::DEFAULT, *iter, entryTo, GetString(it.first)); InsertEdgeUnique(edge); (*iter)->IncEdgeCount(); // Update Node's edgeCount_ here } @@ -505,7 +510,7 @@ void HeapSnapShot::FillEdges(JSThread *thread) } else { valueName.append("NaN"); } - Edge *edge = Edge::NewEdge(edgeCount_, EdgeType::DEFAULT, (*iter), (*iter), GetString(valueName)); + Edge *edge = Edge::NewEdge(heap_, edgeCount_, EdgeType::DEFAULT, (*iter), (*iter), GetString(valueName)); InsertEdgeUnique(edge); (*iter)->IncEdgeCount(); // Update Node's edgeCount_ here } @@ -560,7 +565,8 @@ Edge *HeapSnapShot::InsertEdgeUnique(Edge *edge) void HeapSnapShot::AddSyntheticRoot(JSThread *thread) { - Node *syntheticRoot = Node::NewNode(1, nodeCount_, GetString("SyntheticRoot"), NodeType::SYNTHETIC, 0, nullptr); + Node *syntheticRoot = Node::NewNode(heap_, 1, nodeCount_, GetString("SyntheticRoot"), NodeType::SYNTHETIC, 0, + nullptr); InsertNodeAt(0, syntheticRoot); int edgeOffset = 0; @@ -572,7 +578,7 @@ void HeapSnapShot::AddSyntheticRoot(JSThread *thread) Node *rootNode = entryMap_.FindEntry(Node::NewAddress(root)); \ if (rootNode != nullptr) { \ Edge *edge = \ - Edge::NewEdge(edgeCount_, EdgeType::SHORTCUT, syntheticRoot, rootNode, GetString("-subroot-")); \ + Edge::NewEdge(heap_, edgeCount_, EdgeType::SHORTCUT, syntheticRoot, rootNode, GetString("-subroot-")); \ InsertEdgeAt(edgeOffset, edge); \ edgeOffset++; \ syntheticRoot->IncEdgeCount(); \ diff --git a/ecmascript/hprof/heap_snapshot.h b/ecmascript/hprof/heap_snapshot.h index 85486af28517c3ee611f5672e2af68cd292d6a10..be10d01f51b8ddaa092ad154a92742628d6ef18a 100644 --- a/ecmascript/hprof/heap_snapshot.h +++ b/ecmascript/hprof/heap_snapshot.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef RUNTIME_ECMASCRIPT_HPROF_HEAP_SNAPSHOT_H -#define RUNTIME_ECMASCRIPT_HPROF_HEAP_SNAPSHOT_H +#ifndef ECMASCRIPT_HPROF_HEAP_SNAPSHOT_H +#define ECMASCRIPT_HPROF_HEAP_SNAPSHOT_H #include #include @@ -57,7 +57,7 @@ public: isLive_(isLive) { } - uint64_t GetId() + uint64_t GetId() const { return id_; } @@ -65,23 +65,24 @@ public: { index_ = index; } - uint64_t GetIndex() + uint64_t GetIndex() const { return index_; } - CString *GetName() + + const CString *GetName() const { return name_; } - NodeType GetType() + NodeType GetType() const { return type_; } - size_t GetSelfSize() + size_t GetSelfSize() const { return size_; } - size_t GetEdgeCount() + size_t GetEdgeCount() const { return edgeCount_; } @@ -89,15 +90,15 @@ public: { edgeCount_++; } - uint64_t GetStackTraceId() + uint64_t GetStackTraceId() const { return traceId_; } - Address GetAddress() + Address GetAddress() const { return address_; } - bool IsLive() + bool IsLive() const { return isLive_; } @@ -105,9 +106,9 @@ public: { isLive_ = isLive; } - static Node *NewNode(size_t id, size_t index, CString *name, NodeType type, size_t size, TaggedObject *entry, - bool isLive = true); - template + static Node *NewNode(const Heap *heap, size_t id, size_t index, CString *name, NodeType type, size_t size, + TaggedObject *entry, bool isLive = true); + template static Address NewAddress(T *addr) { return reinterpret_cast
(addr); @@ -140,15 +141,15 @@ public: { return edgeType_; } - Node *GetFrom() const + const Node *GetFrom() const { return from_; } - Node *GetTo() const + const Node *GetTo() const { return to_; } - CString *GetName() const + const CString *GetName() const { return name_; } @@ -164,7 +165,7 @@ public: { to_ = node; } - static Edge *NewEdge(uint64_t id, EdgeType type, Node *from, Node *to, CString *name); + static Edge *NewEdge(const Heap *heap, uint64_t id, EdgeType type, Node *from, Node *to, CString *name); static constexpr int EDGE_FIELD_COUNT = 3; ~Edge() = default; private: @@ -183,12 +184,12 @@ public: DEFAULT_MOVE_SEMANTIC(TimeStamp); DEFAULT_COPY_SEMANTIC(TimeStamp); - int GetLastSequenceId() + int GetLastSequenceId() const { return lastSequenceId_; } - int64_t GetTimeStamp() + int64_t GetTimeStamp() const { return timeStampUs_; } @@ -215,11 +216,11 @@ public: Node *FindOrInsertNode(Node *node); Node *FindAndEraseNode(Address addr); Node *FindEntry(Address addr); - size_t GetCapcity() + size_t GetCapcity() const { return nodesMap_.size(); } - size_t GetEntryCount() + size_t GetEntryCount() const { return nodeEntryCount_; } @@ -235,11 +236,9 @@ public: static constexpr int SEQ_STEP = 2; NO_MOVE_SEMANTIC(HeapSnapShot); NO_COPY_SEMANTIC(HeapSnapShot); - explicit HeapSnapShot(JSThread *thread, CAddressAllocator *allocator) - : stringTable_(allocator), thread_(thread) + explicit HeapSnapShot(JSThread *thread, const Heap *heap) + : stringTable_(heap), thread_(thread), heap_(heap) { - allocator_ = allocator; - ASSERT(allocator_ != nullptr); } ~HeapSnapShot(); bool BuildUp(JSThread *thread); @@ -252,20 +251,20 @@ public: void RecordSampleTime(); bool FinishSnapShot(); - CVector &GetTimeStamps() + const CVector &GetTimeStamps() const { return timeStamps_; } - size_t GetNodeCount() + size_t GetNodeCount() const { return nodeCount_; } - size_t GetEdgeCount() + size_t GetEdgeCount() const { return edgeCount_; } - size_t GetTotalNodeSize() + size_t GetTotalNodeSize() const { return totalNodesSize_; } @@ -279,20 +278,19 @@ public: } CString *GenerateNodeName(JSThread *thread, TaggedObject *entry); NodeType GenerateNodeType(TaggedObject *entry); - CList *GetNodes() + const CList *GetNodes() const { return &nodes_; } - CVector *GetEdges() + const CVector *GetEdges() const { return &edges_; } - StringHashMap *GetEcmaStringTable() + const StringHashMap *GetEcmaStringTable() const { return &stringTable_; } - static CAddressAllocator *GetAllocator(); CString *GetString(const CString &as); private: @@ -310,7 +308,6 @@ private: Node *InsertNodeAt(size_t pos, Node *node); Edge *InsertEdgeAt(size_t pos, Edge *edge); - static CAddressAllocator *allocator_; StringHashMap stringTable_; CList nodes_{}; CVector edges_{}; @@ -322,6 +319,7 @@ private: HeapEntryMap entryMap_; panda::ecmascript::HeapRootVisitor rootVisitor_; JSThread *thread_; + const Heap *heap_; }; class EntryVisitor { @@ -363,4 +361,4 @@ public: static FrontType Convert(NodeType type); }; } // namespace panda::ecmascript -#endif // RUNTIME_ECMASCRIPT_HPROF_HEAP_SNAPSHOT_H +#endif // ECMASCRIPT_HPROF_HEAP_SNAPSHOT_H diff --git a/ecmascript/hprof/heap_snapshot_json_serializer.cpp b/ecmascript/hprof/heap_snapshot_json_serializer.cpp index f302785e1dfe128af1560ba91514c30cf05403d0..1946fdb7dd94a734c698e33c885b69bfb46f719d 100644 --- a/ecmascript/hprof/heap_snapshot_json_serializer.cpp +++ b/ecmascript/hprof/heap_snapshot_json_serializer.cpp @@ -79,8 +79,8 @@ void HeapSnapShotJSONSerializer::SerializeSnapShotHeader() void HeapSnapShotJSONSerializer::SerializeNodes() { - CList *nodes = snapShot_->GetNodes(); - StringHashMap *stringTable = snapShot_->GetEcmaStringTable(); + const CList *nodes = snapShot_->GetNodes(); + const StringHashMap *stringTable = snapShot_->GetEcmaStringTable(); ASSERT(nodes != nullptr); stringBuffer_ << "\"nodes\":["; // Section Header size_t i = 0; @@ -106,8 +106,8 @@ void HeapSnapShotJSONSerializer::SerializeNodes() void HeapSnapShotJSONSerializer::SerializeEdges() { - CVector *edges = snapShot_->GetEdges(); - StringHashMap *stringTable = snapShot_->GetEcmaStringTable(); + const CVector *edges = snapShot_->GetEdges(); + const StringHashMap *stringTable = snapShot_->GetEcmaStringTable(); ASSERT(edges != nullptr); stringBuffer_ << "\"edges\":["; size_t i = 0; @@ -121,7 +121,7 @@ void HeapSnapShotJSONSerializer::SerializeEdges() if (i == edges->size() - 1) { // add comma at last the line stringBuffer_ << edge->GetTo()->GetIndex() * Node::NODE_FIELD_COUNT << "],\n"; // 3. } else { - stringBuffer_ << edge->GetTo()->GetIndex() * Node::NODE_FIELD_COUNT << "\n"; // 3. + stringBuffer_ << edge->GetTo()->GetIndex() * Node::NODE_FIELD_COUNT << "\n"; // 3. } i++; } @@ -140,7 +140,7 @@ void HeapSnapShotJSONSerializer::SerializeTraceTree() void HeapSnapShotJSONSerializer::SerializeSamples() { stringBuffer_ << "\"samples\":["; - CVector &timeStamps = snapShot_->GetTimeStamps(); + const CVector &timeStamps = snapShot_->GetTimeStamps(); if (!timeStamps.empty()) { auto firstTimeStamp = timeStamps[0]; bool isFirst = true; @@ -164,7 +164,7 @@ void HeapSnapShotJSONSerializer::SerializeLocations() void HeapSnapShotJSONSerializer::SerializeStringTable() { - StringHashMap *stringTable = snapShot_->GetEcmaStringTable(); + const StringHashMap *stringTable = snapShot_->GetEcmaStringTable(); ASSERT(stringTable != nullptr); stringBuffer_ << "\"strings\":[\"\",\n"; stringBuffer_ << "\"\",\n"; @@ -172,7 +172,7 @@ void HeapSnapShotJSONSerializer::SerializeStringTable() // StringId Range from 3 size_t capcity = stringTable->GetCapcity(); size_t i = 0; - for (auto key : *(stringTable->GetOrderedKeyStorage())) { + for (auto key : stringTable->GetOrderedKeyStorage()) { if (i == capcity - 1) { stringBuffer_ << "\"" << *(stringTable->GetStringByKey(key)) << "\"\n"; // No Comma for the last line } else { diff --git a/ecmascript/hprof/heap_snapshot_json_serializer.h b/ecmascript/hprof/heap_snapshot_json_serializer.h index 91d8b6abcb338966cb90df6f38a9fa1afca9013e..0f1c769b69ca993f8c5e04dcd42fea34720b3c7d 100644 --- a/ecmascript/hprof/heap_snapshot_json_serializer.h +++ b/ecmascript/hprof/heap_snapshot_json_serializer.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef RUNTIME_ECMASCRIPT_HPROF_HEAP_SNAPSHOT_SERIALIZER_H -#define RUNTIME_ECMASCRIPT_HPROF_HEAP_SNAPSHOT_SERIALIZER_H +#ifndef ECMASCRIPT_HPROF_HEAP_SNAPSHOT_SERIALIZER_H +#define ECMASCRIPT_HPROF_HEAP_SNAPSHOT_SERIALIZER_H #include #include @@ -53,4 +53,4 @@ private: stringstream stringBuffer_; }; } // namespace panda::ecmascript -#endif // RUNTIME_ECMASCRIPT_HPROF_HEAP_SNAPSHOT_SERIALIZER_H +#endif // ECMASCRIPT_HPROF_HEAP_SNAPSHOT_SERIALIZER_H diff --git a/ecmascript/hprof/heap_tracker.h b/ecmascript/hprof/heap_tracker.h index 199ab8bb68b69d6250186e5e1f11f89fcf7c3266..cb36415a39580e7047f74daad650336a5bb874d7 100644 --- a/ecmascript/hprof/heap_tracker.h +++ b/ecmascript/hprof/heap_tracker.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_HPROF_HEAP_TRACKER_H -#define PANDA_RUNTIME_ECMASCRIPT_HPROF_HEAP_TRACKER_H +#ifndef ECMASCRIPT_HPROF_HEAP_TRACKER_H +#define ECMASCRIPT_HPROF_HEAP_TRACKER_H #include #include @@ -89,4 +89,4 @@ private: HeapTrackerSample sample_; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_HPROF_HEAP_TRACKER_H +#endif // ECMASCRIPT_HPROF_HEAP_TRACKER_H diff --git a/ecmascript/hprof/string_hashmap.cpp b/ecmascript/hprof/string_hashmap.cpp index 8c713b336834896ac901b637d149bc1d071e81d8..114541729d2437d96f889e19c2ff2f4690613804 100644 --- a/ecmascript/hprof/string_hashmap.cpp +++ b/ecmascript/hprof/string_hashmap.cpp @@ -31,13 +31,13 @@ CString *StringHashMap::FindOrInsertString(CString *string) } } -StringId StringHashMap::GetStringId(CString *string) +StringId StringHashMap::GetStringId(const CString *string) const { auto it = indexMap_.find(GenerateStringKey(string)); return it != indexMap_.end() ? it->second : 1; // "" } -CString *StringHashMap::GetStringByKey(StringKey key) +CString *StringHashMap::GetStringByKey(StringKey key) const { auto it = hashmap_.find(key); if (it != hashmap_.end()) { @@ -46,7 +46,7 @@ CString *StringHashMap::GetStringByKey(StringKey key) return nullptr; } -CString *StringHashMap::FormatString(CString *string) +CString *StringHashMap::FormatString(CString *string) const { // remove "\"" | "\r\n" | "\\" | "\t" | "\f" int length = string->length(); @@ -73,17 +73,17 @@ CString *StringHashMap::FormatString(CString *string) return string; } -StringKey StringHashMap::GenerateStringKey(CString *string) +StringKey StringHashMap::GenerateStringKey(const CString *string) const { return std::hash{}(std::string(*string)); } CString *StringHashMap::GetString(CString as) { - auto *tempString = allocator_->New(std::move(as)); + auto *tempString = const_cast(heap_->GetRegionFactory())->New(std::move(as)); CString *oldString = FindOrInsertString(tempString); if (tempString != oldString) { - allocator_->Finalize(tempString); + const_cast(heap_->GetRegionFactory())->Delete(tempString); return oldString; } return tempString; @@ -93,7 +93,7 @@ void StringHashMap::Clear() { for (auto it : hashmap_) { if (it.second != nullptr) { - allocator_->Finalize(it.second); + const_cast(heap_->GetRegionFactory())->Delete(it.second); } } } diff --git a/ecmascript/hprof/string_hashmap.h b/ecmascript/hprof/string_hashmap.h index c5a9349021960a5046eb1787b4b9de63aadef71b..b1bf7accab037df5028c10e48022192a3ba8668c 100644 --- a/ecmascript/hprof/string_hashmap.h +++ b/ecmascript/hprof/string_hashmap.h @@ -13,12 +13,13 @@ * limitations under the License. */ -#ifndef RUNTIME_ECMASCRIPT_HPROF_STRING_HASHMAP_H -#define RUNTIME_ECMASCRIPT_HPROF_STRING_HASHMAP_H +#ifndef ECMASCRIPT_HPROF_STRING_HASHMAP_H +#define ECMASCRIPT_HPROF_STRING_HASHMAP_H #include "ecmascript/js_thread.h" #include "ecmascript/mem/c_containers.h" #include "ecmascript/mem/c_string.h" +#include "ecmascript/mem/heap.h" #include "os/mem.h" namespace panda::ecmascript { @@ -29,9 +30,9 @@ using StringId = uint64_t; // To make sure when using String, it still stays where it was. class StringHashMap { public: - explicit StringHashMap(CAddressAllocator *allocator) : allocator_(allocator) + explicit StringHashMap(const Heap *heap) : heap_(heap) { - ASSERT(allocator_ != nullptr); + ASSERT(heap_ != nullptr); } ~StringHashMap() { @@ -42,19 +43,19 @@ public: /* * The ID is the seat number in JSON file Range from 0~string_table_.size() */ - StringId GetStringId(CString *string); + StringId GetStringId(const CString *string) const; /* * Get all keys sorted by insert order */ - CVector *GetOrderedKeyStorage() + const CVector &GetOrderedKeyStorage() const { - return &orderedKey_; + return orderedKey_; } /* * Get string by its hash key */ - CString *GetStringByKey(StringKey key); - size_t GetCapcity() + CString *GetStringByKey(StringKey key) const; + size_t GetCapcity() const { ASSERT(orderedKey_.size() == hashmap_.size()); return orderedKey_.size(); @@ -65,18 +66,18 @@ public: CString *GetString(CString as); private: - StringKey GenerateStringKey(CString *string); + StringKey GenerateStringKey(const CString *string) const; CString *FindOrInsertString(CString *string); - CString *FormatString(CString *string); + CString *FormatString(CString *string) const; /* * Free all memory */ void Clear(); - CAddressAllocator *allocator_{nullptr}; + const Heap *heap_; CVector orderedKey_; // Used for Serialize Order size_t index_{2}; // 2: Offset the String-Table Header CUnorderedMap indexMap_; CUnorderedMap hashmap_; }; } // namespace panda::ecmascript -#endif // RUNTIME_ECMASCRIPT_HPROF_STRING_HASHMAP_H +#endif // ECMASCRIPT_HPROF_STRING_HASHMAP_H diff --git a/ecmascript/hprof/tests/heap_tracker_test.cpp b/ecmascript/hprof/tests/heap_tracker_test.cpp index 09ce8a6e829237e80c4120518b40cd9ad9372325..1c6bc1748f53a141677fc50cfa81ffed30350280 100644 --- a/ecmascript/hprof/tests/heap_tracker_test.cpp +++ b/ecmascript/hprof/tests/heap_tracker_test.cpp @@ -74,7 +74,7 @@ HWTEST_F_L0(HeapTrackerTest, HeapTracker) sleep(1); count = 100; while (count-- > 0) { - JSHandle string = thread->GetEcmaVM()->GetFactory()->NewFromString("Hello World"); + JSHandle string = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("Hello World"); thread->GetEcmaVM()->GetFactory()->NewJSString(JSHandle(string)); } diff --git a/ecmascript/ic/function_cache.h b/ecmascript/ic/function_cache.h index b9b10c2de36285ac832845e605f9b5dce109abe0..edf42f06f5390e2410cc2fc8127ca53a0949d3dd 100644 --- a/ecmascript/ic/function_cache.h +++ b/ecmascript/ic/function_cache.h @@ -13,11 +13,12 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_FUNCTION_CACHE_H -#define PANDA_RUNTIME_FUNCTION_CACHE_H +#ifndef ECMASCRIPT_IC_FUNCTION_CACHE_H +#define ECMASCRIPT_IC_FUNCTION_CACHE_H #include "ecmascript/js_function.h" #include "ecmascript/tagged_array.h" + namespace panda { namespace ecmascript { class FunctionCache : public TaggedArray { @@ -93,4 +94,4 @@ public: } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_FUNCTION_CACHE_H +#endif // ECMASCRIPT_IC_FUNCTION_CACHE_H diff --git a/ecmascript/ic/ic_accessor-inl.h b/ecmascript/ic/ic_accessor-inl.h deleted file mode 100644 index 2a52fc214c9369094f1683c975261afbd9f8b5f3..0000000000000000000000000000000000000000 --- a/ecmascript/ic/ic_accessor-inl.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_IC_ACCESSOR_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_IC_ACCESSOR_INL_H - -#include "ecmascript/accessor_data.h" -#include "ecmascript/interpreter/fast_runtime_stub-inl.h" -#include "ecmascript/js_hclass-inl.h" -#include "ecmascript/js_object-inl.h" -#include "ecmascript/js_proxy.h" -#include "ecmascript/object_factory.h" -#include "function_cache.h" -#include "ic_accessor.h" -#include "ic_handler-inl.h" - -namespace panda::ecmascript { -inline JSTaggedValue ICAccessor::LoadGlobalWithHandler(JSThread *thread, JSTaggedValue receiver, JSTaggedValue handler) -{ - if (handler.IsPrototypeHandler()) { - return LoadGlobalPrototype(thread, receiver, handler); - } - if (handler.IsGlobalHandler()) { - return LoadGlobal(thread, receiver, handler); - } - ASSERT(handler.IsNonExistentHandler()); - return LoadNonExistent(handler); -} - -inline JSTaggedValue ICAccessor::LoadGlobalPrototype(JSThread *thread, JSTaggedValue obj, JSTaggedValue handler) -{ - ASSERT(handler.IsPrototypeHandler()); - PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject()); - if (JSHClass::HasProtoChainChanged(prototypeHandler->GetProtoCell())) { - return JSTaggedValue::Hole(); - } - JSTaggedValue handlerInfo = prototypeHandler->GetHandlerInfo(); - ASSERT(handlerInfo.IsGlobalHandler()); - return LoadGlobal(thread, obj, handlerInfo); -} - -inline JSTaggedValue ICAccessor::LoadNonExistent(JSTaggedValue handler) -{ - NonExistentHandler *nonExistentHandler = NonExistentHandler::Cast(handler.GetTaggedObject()); - if (JSHClass::HasProtoChainChanged(nonExistentHandler->GetProtoCell())) { - return JSTaggedValue::Hole(); - } - return JSTaggedValue::Undefined(); -} - -inline bool ICAccessor::StoreGlobalICByName(JSThread *thread, uint32_t stringId, JSTaggedValue value, uint16_t slotId) -{ - FunctionCache *cache = FunctionCache::GetCurrent(thread); - JSTaggedValue handler = cache->GetGlobalHandlerByIndex(slotId); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - bool success = false; - if (!handler.IsNull()) { - JSTaggedValue globalValue = thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject(); - success = StoreGlobalWithHandlerByName(thread, globalValue, stringId, value, handler, slotId); - } else { - JSTaggedValue key(factory->ResolveString(stringId)); - success = StoreGlobalMissByName(thread, JSHandle(thread, key), - JSHandle(thread, value), slotId); - } - return success; -} - -inline bool ICAccessor::StoreGlobalWithHandlerByName(JSThread *thread, JSTaggedValue obj, uint32_t stringId, - JSTaggedValue value, JSTaggedValue handler, uint16_t slotId) -{ - if (handler.IsPrototypeHandler()) { - return StoreGlobalPrototypeByName(thread, obj, stringId, value, handler, slotId); - } - if (handler.IsGlobalHandler()) { - return StoreGlobalByName(thread, JSObject::Cast(obj.GetTaggedObject()), stringId, value, handler, slotId); - } - ASSERT(handler.IsTransitionHandler()); - StoreWithTransition(thread, JSObject::Cast(obj.GetTaggedObject()), value, handler); - return true; -} - -inline bool ICAccessor::StoreGlobalWithHandlerByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, - JSTaggedValue value, JSTaggedValue handler, uint16_t slotId) -{ - if (handler.IsPrototypeHandler()) { - return StoreGlobalPrototypeByValue(thread, obj, key, value, handler, slotId); - } - if (handler.IsGlobalHandler()) { - return StoreGlobalByValue(thread, JSObject::Cast(obj.GetTaggedObject()), key, value, handler, slotId); - } - ASSERT(handler.IsTransitionHandler()); - StoreWithTransition(thread, JSObject::Cast(obj.GetTaggedObject()), value, handler); - return true; -} - -inline bool ICAccessor::StoreGlobalPrototypeByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, - JSTaggedValue value, JSTaggedValue handler, uint16_t slotId) -{ - ASSERT(handler.IsPrototypeHandler()); - PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject()); - if (JSHClass::HasProtoChainChanged(prototypeHandler->GetProtoCell())) { - JSTaggedValue handlerInfo = prototypeHandler->GetHandlerInfo(); - ASSERT(handlerInfo.IsGlobalHandler()); - GlobalHandler *globalHandler = GlobalHandler::Cast(handlerInfo.GetTaggedObject()); - PropertyBox *cell = PropertyBox::Cast(globalHandler->GetPropertyBox().GetTaggedObject()); - auto *setter = AccessorData::Cast(cell->GetValue().GetTaggedObject()); - JSObject::CallSetter(thread, *setter, JSHandle(thread, obj), - JSHandle(thread, value)); - return true; - } - JSHandle value_handle(thread, value); - return StoreGlobalMissByValue(thread, JSHandle(thread, key), JSHandle(thread, value), - slotId); -} -inline void ICAccessor::StoreWithTransition(const JSThread *thread, JSObject *obj, JSTaggedValue value, - JSTaggedValue handler) -{ - TransitionHandler *transitionHandler = TransitionHandler::Cast(handler.GetTaggedObject()); - JSHClass *newDynclass = JSHClass::Cast(transitionHandler->GetTransitionHClass().GetTaggedObject()); - obj->SetClass(newDynclass); - uint32_t handlerInfo = transitionHandler->GetHandlerInfo().GetInt(); - ASSERT(HandlerBase::IsField(handlerInfo)); - StoreField(thread, obj, value, handlerInfo); -} -} // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_IC_ACCESSOR_INL_H diff --git a/ecmascript/ic/ic_accessor.cpp b/ecmascript/ic/ic_accessor.cpp deleted file mode 100644 index 593929b7c0a8e16dd8f4d70cfc673d8460a228e2..0000000000000000000000000000000000000000 --- a/ecmascript/ic/ic_accessor.cpp +++ /dev/null @@ -1,790 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#include "ic_accessor.h" -#include "ecmascript/js_object-inl.h" -#include "ecmascript/mem/assert_scope-inl.h" -#include "ic_accessor-inl.h" - -namespace panda::ecmascript { -JSTaggedValue ICAccessor::LoadMiss(JSThread *thread, const JSHandle &obj, const JSHandle &key, - uint16_t slotId) -{ - if (obj->IsTypedArray()) { - return JSTaggedValue::GetProperty(thread, JSHandle(obj), key).GetValue().GetTaggedValue(); - } - ObjectOperator op(thread, obj, key); - // ic-switch - if (!thread->GetEcmaVM()->ICEnable()) { - return JSObject::GetProperty(thread, &op); - } - // do not cache element - if (!op.IsFastMode() || op.IsElement()) { - return JSObject::GetProperty(thread, &op); - } - JSTaggedValue handler; - JSHandle dynclass(thread, obj->GetJSHClass()); - if (!op.IsFound()) { - handler = NonExistentHandler::LoadNonExistent(thread, dynclass); - } else if (!op.IsOnPrototype()) { - handler = LoadHandler::LoadProperty(thread, op); - } else { - handler = PrototypeHandler::LoadPrototype(thread, op, dynclass); - } - // add handler to ic slot - FunctionCache::AddLoadHandler(thread, key, dynclass, JSHandle(thread, handler), slotId); - return JSObject::GetProperty(thread, &op); -} - -JSTaggedValue ICAccessor::LoadMissByName(JSThread *thread, const JSHandle &obj, - const JSHandle &key, uint16_t slotId) -{ - if (obj->IsTypedArray()) { - return JSTaggedValue::GetProperty(thread, JSHandle(obj), key).GetValue().GetTaggedValue(); - } - ObjectOperator op(thread, obj, key); - // ic-switch - if (!thread->GetEcmaVM()->ICEnable()) { - return JSObject::GetProperty(thread, &op); - } - // do not cache element - if (!op.IsFastMode() || op.IsElement()) { - return JSObject::GetProperty(thread, &op); - } - JSTaggedValue handler; - JSHandle dynclass(thread, obj->GetJSHClass()); - if (!op.IsFound()) { - handler = NonExistentHandler::LoadNonExistent(thread, dynclass); - } else if (!op.IsOnPrototype()) { - handler = LoadHandler::LoadProperty(thread, op); - } else { - handler = PrototypeHandler::LoadPrototype(thread, op, dynclass); - } - // add handler to ic slot - FunctionCache::AddLoadHandler(thread, JSHandle(thread, JSTaggedValue::Null()), dynclass, - JSHandle(thread, handler), slotId); - return JSObject::GetProperty(thread, &op); -} - -bool ICAccessor::StoreMiss(JSThread *thread, const JSHandle &obj, const JSHandle &key, - const JSHandle &value, uint16_t slotId) -{ - if (obj->IsTypedArray()) { - return JSTaggedValue::SetProperty(thread, JSHandle(obj), key, value); - } - ObjectOperator op(thread, obj, key); - bool success = JSObject::SetProperty(&op, value, false); - if (!thread->GetEcmaVM()->ICEnable()) { - return success; - } - - if (!success) { - return false; - } - // do not cache element and proxy - if (!op.IsFastMode() || op.IsElement() || op.GetHolder()->IsJSProxy()) { - return true; - } - // if !op.IsElement && !op.IsFound, target will be added in function AddPropertyInternal(), at the same time op will - // be set found() - ASSERT(op.IsFound()); - JSHandle dynclass(thread, obj->GetJSHClass()); - JSTaggedValue handler; - if (op.IsOnPrototype()) { - // if SetProperty successfully, op.IsOnPrototype will be reset if op.IsAccessorDescriptor is false; - ASSERT(op.IsAccessorDescriptor()); - handler = PrototypeHandler::StorePrototype(thread, op, dynclass); - } else if (*dynclass == obj->GetJSHClass()) { - handler = StoreHandler::StoreProperty(thread, op); - } else { - handler = TransitionHandler::StoreTransition(thread, op); - } - // add handler to ic slot - FunctionCache::AddStoreHandler(thread, key, dynclass, JSHandle(thread, handler), slotId); - return true; -} - -bool ICAccessor::StoreMissByName(JSThread *thread, const JSHandle &obj, const JSHandle &key, - const JSHandle &value, uint16_t slotId) -{ - if (obj->IsTypedArray()) { - return JSTaggedValue::SetProperty(thread, JSHandle(obj), key, value); - } - ObjectOperator op(thread, obj, key); - bool success = JSObject::SetProperty(&op, value, false); - if (!thread->GetEcmaVM()->ICEnable()) { - return success; - } - - if (!success) { - return false; - } - // do not cache element and proxy - if (!op.IsFastMode() || op.IsElement() || op.GetHolder()->IsJSProxy()) { - return true; - } - // if !op.IsElement && !op.IsFound, target will be added in function AddPropertyInternal(), at the same time op will - // be set found() - ASSERT(op.IsFound()); - JSHandle dynclass(thread, obj->GetJSHClass()); - JSTaggedValue handler; - if (op.IsOnPrototype()) { - // if SetProperty successfully, op.IsOnPrototype will be reset if op.IsAccessorDescriptor is false; - ASSERT(op.IsAccessorDescriptor()); - handler = PrototypeHandler::StorePrototype(thread, op, dynclass); - } else if (*dynclass == obj->GetJSHClass()) { - handler = StoreHandler::StoreProperty(thread, op); - } else { - handler = TransitionHandler::StoreTransition(thread, op); - } - // add handler to ic slot - FunctionCache::AddStoreHandler(thread, JSHandle(thread, JSTaggedValue::Null()), dynclass, - JSHandle(thread, handler), slotId); - return true; -} - -JSTaggedValue ICAccessor::LoadGlobalMiss(JSThread *thread, const JSHandle &key, uint16_t slotId) -{ - ObjectOperator op(thread, key); - // ic-switch - if (!thread->GetEcmaVM()->ICEnable()) { - return JSObject::GetProperty(thread, &op); - } - // do not cache element - if (op.IsElement()) { - return JSObject::GetProperty(thread, &op); - } - JSTaggedValue handler; - if (!op.IsFound()) { - handler = NonExistentHandler::LoadGlobalNonExistent(thread); - } else if (!op.IsOnPrototype()) { - handler = LoadHandler::LoadGlobalProperty(thread, op); - } else { - handler = PrototypeHandler::LoadGlobalPrototype(thread, op); - } - // add handler to ic slot - FunctionCache::AddGlobalHandler(thread, key, JSHandle(thread, handler), slotId); - return JSObject::GetProperty(thread, &op); -} - -JSTaggedValue ICAccessor::LoadGlobalMissByName(JSThread *thread, const JSHandle &key, uint16_t slotId) -{ - ObjectOperator op(thread, key); - // ic-switch - if (!thread->GetEcmaVM()->ICEnable()) { - return JSObject::GetProperty(thread, &op); - } - // do not cache element - if (op.IsElement()) { - return JSObject::GetProperty(thread, &op); - } - JSTaggedValue handler; - if (!op.IsFound()) { - handler = NonExistentHandler::LoadGlobalNonExistent(thread); - } else if (!op.IsOnPrototype()) { - handler = LoadHandler::LoadGlobalProperty(thread, op); - } else { - handler = PrototypeHandler::LoadGlobalPrototype(thread, op); - } - // add handler to ic slot - FunctionCache::AddGlobalHandler(thread, JSHandle(thread, JSTaggedValue::Null()), - JSHandle(thread, handler), slotId); - return JSObject::GetProperty(thread, &op); -} - -bool ICAccessor::StoreGlobalMissByName(JSThread *thread, const JSHandle &key, - const JSHandle &value, uint16_t slotId) -{ - ObjectOperator op(thread, key); - bool success = JSObject::SetProperty(&op, value, false); - if (!thread->GetEcmaVM()->ICEnable()) { - return success; - } - - if (!success) { - return false; - } - // do not cache element and proxy - if (op.IsElement() || op.GetHolder()->IsJSProxy()) { - return true; - } - ASSERT(op.IsFound()); - JSTaggedValue handler; - if (op.IsOnPrototype()) { - // if SetProperty successfully, op.IsOnPrototype will be reset if op.IsAccessorDescriptor is false; - ASSERT(op.IsAccessorDescriptor()); - handler = PrototypeHandler::StoreGlobalPrototype(thread, op); - FunctionCache::AddGlobalHandler(thread, JSHandle(thread, JSTaggedValue::Null()), - JSHandle(thread, handler), slotId); - return true; - } - JSHandle obj(thread, thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject()); - JSHandle dynclass(thread, obj->GetJSHClass()); - if (*dynclass == obj->GetJSHClass()) { - handler = StoreHandler::StoreGlobalProperty(thread, op); - } else { - handler = TransitionHandler::StoreTransition(thread, op); - } - // add handler to ic slot - FunctionCache::AddGlobalHandler(thread, JSHandle(thread, JSTaggedValue::Null()), - JSHandle(thread, handler), slotId); - return true; -} - -bool ICAccessor::StoreGlobalMissByValue(JSThread *thread, const JSHandle &key, - const JSHandle &value, uint16_t slotId) -{ - ObjectOperator op(thread, key); - bool success = JSObject::SetProperty(&op, value, false); - if (!thread->GetEcmaVM()->ICEnable()) { - return success; - } - - if (!success) { - return false; - } - // do not cache element and proxy - if (op.IsElement() || op.GetHolder()->IsJSProxy()) { - return true; - } - ASSERT(op.IsFound()); - JSTaggedValue handler; - if (op.IsOnPrototype()) { - // if SetProperty successfully, op.IsOnPrototype will be reset if op.IsAccessorDescriptor is false; - ASSERT(op.IsAccessorDescriptor()); - handler = PrototypeHandler::StoreGlobalPrototype(thread, op); - FunctionCache::AddGlobalHandler(thread, key, JSHandle(thread, handler), slotId); - return true; - } - JSHandle obj(thread, thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject()); - JSHandle dynclass(thread, obj->GetJSHClass()); - if (*dynclass == obj->GetJSHClass()) { - handler = StoreHandler::StoreGlobalProperty(thread, op); - } else { - handler = TransitionHandler::StoreTransition(thread, op); - } - // add handler to ic slot - FunctionCache::AddGlobalHandler(thread, key, JSHandle(thread, handler), slotId); - return true; -} - -JSTaggedValue ICAccessor::LoadIC(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, uint16_t slotId) -{ - if (receiver.IsUndefined() || receiver.IsNull() || receiver.IsHole()) { - THROW_TYPE_ERROR_AND_RETURN(thread, "LoadIC--receiver is not valid", JSTaggedValue::Exception()); - } - ASSERT_PRINT(JSTaggedValue::IsPropertyKey(JSHandle(thread, key)), "Key is not a property key"); - if (!receiver.IsECMAObject()) { - return JSTaggedValue::GetProperty(thread, JSHandle(thread, receiver), - JSHandle(thread, key)) - .GetValue() - .GetTaggedValue(); - } - if (key.IsNumber()) { - if (!receiver.IsJSPrimitiveRef() && !receiver.IsTypedArray()) { - JSTaggedValue val = FastRuntimeStub::FastGetPropertyByIndex(thread, receiver, key.GetArrayLength()); - if (UNLIKELY(val.IsAccessorData())) { - return JSObject::CallGetter(thread, AccessorData::Cast(val.GetTaggedObject()), - JSHandle(thread, receiver)); - } - return val; - } - return JSTaggedValue::GetProperty(thread, JSHandle(thread, receiver), - JSHandle(thread, key)) - .GetValue() - .GetTaggedValue(); - } - JSObject *obj = JSObject::Cast(receiver.GetTaggedObject()); - JSTaggedValue dynclass(obj->GetJSHClass()); - FunctionCache *cache = FunctionCache::GetCurrent(thread); - JSTaggedValue handler = cache->GetLoadHandler(thread, key, dynclass, slotId); - if (!handler.IsNull()) { - JSTaggedValue ret = LoadWithHandler(thread, obj, receiver, handler); - if (!ret.IsHole()) { - return ret; - } - } - return LoadMiss(thread, JSHandle(thread, obj), JSHandle(thread, key), slotId); -} - -JSTaggedValue ICAccessor::LoadICByName(JSThread *thread, JSTaggedValue receiver, uint32_t stringId, uint16_t slotId) -{ - if (receiver.IsUndefined() || receiver.IsNull() || receiver.IsHole()) { - THROW_TYPE_ERROR_AND_RETURN(thread, "LoadIC--receiver is not valid", JSTaggedValue::Exception()); - } - if (UNLIKELY(!receiver.IsECMAObject())) { - JSHandle receiverHandle(thread, receiver); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSTaggedValue key(factory->ResolveString(stringId)); - return JSTaggedValue::GetProperty(thread, receiverHandle, JSHandle(thread, key)) - .GetValue() - .GetTaggedValue(); - } - JSObject *obj = JSObject::Cast(receiver.GetTaggedObject()); - JSTaggedValue dynclass(obj->GetJSHClass()); - FunctionCache *cache = FunctionCache::GetCurrent(thread); - JSTaggedValue handler = cache->GetHandlerByIndex(dynclass, slotId); - if (!handler.IsNull()) { - JSTaggedValue ret = LoadWithHandler(thread, obj, receiver, handler); - if (!ret.IsHole()) { - return ret; - } - } - JSHandle objHandle(thread, obj); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSTaggedValue key(factory->ResolveString(stringId)); - return LoadMissByName(thread, objHandle, JSHandle(thread, key), slotId); -} - -// dispatch -JSTaggedValue ICAccessor::LoadWithHandler(JSThread *thread, JSObject *obj, JSTaggedValue receiver, - JSTaggedValue handler) -{ - if (handler.IsInt()) { - return LoadProperty(thread, obj, receiver, handler); - } - if (handler.IsPrototypeHandler()) { - return LoadPrototype(thread, obj, handler); - } - if (handler.IsGlobalHandler()) { - return LoadGlobal(thread, receiver, handler); - } - ASSERT(handler.IsNonExistentHandler()); - return LoadNonExistent(handler); -} - -JSTaggedValue ICAccessor::LoadProperty(JSThread *thread, JSObject *obj, JSTaggedValue receiver, JSTaggedValue handler) -{ - ASSERT(handler.IsInt()); - int32_t handlerInfo = handler.GetInt(); - JSTaggedValue ret; - - if (HandlerBase::IsInlinedProps(handlerInfo)) { - int index = HandlerBase::GetOffset(handlerInfo); - ret = obj->GetPropertyInlinedProps(index); - } else if (HandlerBase::IsNonInlinedProps(handlerInfo)) { - int index = HandlerBase::GetOffset(handlerInfo); - ret = TaggedArray::Cast(obj->GetProperties().GetTaggedObject())->Get(index); - } else { - UNREACHABLE(); - } - if (HandlerBase::IsField(handlerInfo)) { - return ret; - } - - if (HandlerBase::IsAccessor(handlerInfo)) { - return JSObject::CallGetter(thread, AccessorData::Cast(ret.GetTaggedObject()), - JSHandle(thread, receiver)); - } - ASSERT(HandlerBase::IsInternalAccessor(handlerInfo)); - return AccessorData::Cast(ret.GetTaggedObject())->CallInternalGet(thread, JSHandle(thread, receiver)); -} - -JSTaggedValue ICAccessor::LoadGlobal(JSThread *thread, JSTaggedValue receiver, JSTaggedValue handler) -{ - ASSERT(handler.IsGlobalHandler()); - GlobalHandler *globalHandler = GlobalHandler::Cast(handler.GetTaggedObject()); - PropertyBox *cell = PropertyBox::Cast(globalHandler->GetPropertyBox().GetTaggedObject()); - if (cell->IsInvalid()) { - return JSTaggedValue::Hole(); - } - JSTaggedValue ret = cell->GetValue(); - if (ret.IsAccessorData()) { - return JSObject::CallGetter(thread, AccessorData::Cast(ret.GetTaggedObject()), - JSHandle(thread, receiver)); - } - return ret; -} - -JSTaggedValue ICAccessor::LoadPrototype(JSThread *thread, JSObject *obj, JSTaggedValue handler) -{ - ASSERT(handler.IsPrototypeHandler()); - PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject()); - if (JSHClass::HasProtoChainChanged(prototypeHandler->GetProtoCell())) { - return JSTaggedValue::Hole(); - } - JSObject *holder = JSObject::Cast(prototypeHandler->GetHolder().GetTaggedObject()); - JSTaggedValue handlerInfo = prototypeHandler->GetHandlerInfo(); - ASSERT(handlerInfo.IsInt() || handlerInfo.IsGlobalHandler()); - if (handlerInfo.IsInt()) { - return LoadProperty(thread, holder, JSTaggedValue(obj), handlerInfo); - } - if (handlerInfo.IsGlobalHandler()) { - return LoadGlobal(thread, JSTaggedValue(obj), handlerInfo); - } - UNREACHABLE(); -} - -bool ICAccessor::StoreIC(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, - uint16_t slotId) -{ - if (receiver.IsUndefined() || receiver.IsNull() || receiver.IsHole()) { - THROW_TYPE_ERROR_AND_RETURN(thread, "StoreIC--receiver is not valid", false); - } - if (!receiver.IsECMAObject()) { - return JSTaggedValue::SetProperty(thread, JSHandle(thread, receiver), - JSHandle(thread, key), JSHandle(thread, value)); - } - - if (key.IsNumber()) { - if (!receiver.IsArray(thread) && !receiver.IsTypedArray()) { - return FastRuntimeStub::FastSetPropertyByIndex(thread, receiver, key.GetArrayLength(), value); - } - return JSTaggedValue::SetProperty(thread, JSHandle(thread, receiver), - JSHandle(thread, key), JSHandle(thread, value)); - } - JSObject *obj = JSObject::Cast(receiver.GetTaggedObject()); - JSTaggedValue dynclass(obj->GetJSHClass()); - FunctionCache *cache = FunctionCache::GetCurrent(thread); - JSTaggedValue handler = cache->GetStoreHandler(thread, key, dynclass, slotId); - bool success = false; - if (!handler.IsNull()) { - success = StoreWithHandler(thread, obj, key, value, handler, slotId); - } else { - JSHandle prop = JSTaggedValue::ToPropertyKey(thread, JSHandle(thread, key)); - success = - StoreMiss(thread, JSHandle(thread, obj), prop, JSHandle(thread, value), slotId); - } - return success; -} - -bool ICAccessor::StoreICByName(JSThread *thread, JSTaggedValue receiver, uint32_t stringId, JSTaggedValue value, - uint16_t slotId) -{ - if (receiver.IsUndefined() || receiver.IsNull() || receiver.IsHole()) { - THROW_TYPE_ERROR_AND_RETURN(thread, "StoreIC--receiver is not valid", false); - } - if (!receiver.IsECMAObject()) { - JSHandle receiverHandle(thread, receiver); - JSHandle valueHandle(thread, value); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSTaggedValue key(factory->ResolveString(stringId)); - return JSTaggedValue::SetProperty(thread, receiverHandle, JSHandle(thread, key), valueHandle); - } - JSObject *obj = JSObject::Cast(receiver.GetTaggedObject()); - JSTaggedValue dynclass(obj->GetJSHClass()); - FunctionCache *cache = FunctionCache::GetCurrent(thread); - JSTaggedValue handler = cache->GetHandlerByIndex(dynclass, slotId); - bool success = false; - if (!handler.IsNull()) { - success = StoreWithHandlerByName(thread, obj, stringId, value, handler, slotId); - } else { - JSHandle objHandle(thread, obj); - JSHandle valueHandle(thread, value); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSTaggedValue key(factory->ResolveString(stringId)); - success = StoreMissByName(thread, objHandle, JSHandle(thread, key), valueHandle, slotId); - } - return success; -} - -bool ICAccessor::StoreWithHandler(JSThread *thread, JSObject *obj, JSTaggedValue key, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId) -{ - if (handler.IsInt()) { - StoreProperty(thread, obj, value, handler.GetInt()); - return true; - } - if (handler.IsGlobalHandler()) { - return StoreGlobal(thread, obj, key, value, handler, slotId); - } - if (handler.IsTransitionHandler()) { - StoreWithTransition(thread, obj, value, handler); - return true; - } - if (handler.IsPrototypeHandler()) { - return StorePrototype(thread, obj, key, value, handler, slotId); - } - UNREACHABLE(); -} - -bool ICAccessor::StoreWithHandlerByName(JSThread *thread, JSObject *obj, uint32_t stringId, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId) -{ - if (handler.IsInt()) { - StoreProperty(thread, obj, value, handler.GetInt()); - return true; - } - if (handler.IsGlobalHandler()) { - return StoreGlobalByName(thread, obj, stringId, value, handler, slotId); - } - if (handler.IsTransitionHandler()) { - StoreWithTransition(thread, obj, value, handler); - return true; - } - if (handler.IsPrototypeHandler()) { - return StorePrototypeByName(thread, obj, stringId, value, handler, slotId); - } - UNREACHABLE(); -} - -void ICAccessor::StoreProperty(JSThread *thread, JSObject *obj, JSTaggedValue value, uint32_t handler) -{ - if (StoreHandler::IsField(handler)) { - StoreField(thread, obj, value, handler); - } else if (StoreHandler::IsAccessor(handler)) { - auto *setter = GetAccessor(thread, obj, handler); - JSObject::CallSetter(thread, *setter, JSHandle(thread, obj), - JSHandle(thread, value)); - } else { - ASSERT(HandlerBase::IsInternalAccessor(handler)); - AccessorData *accessor = GetAccessor(thread, obj, handler); - accessor->CallInternalSet(thread, JSHandle(thread, obj), JSHandle(thread, value)); - } -} - -void ICAccessor::StoreField(const JSThread *thread, JSObject *obj, JSTaggedValue value, uint32_t handler) -{ - int index = HandlerBase::GetOffset(handler); - if (HandlerBase::IsInlinedProps(handler)) { - obj->SetPropertyInlinedProps(thread, index, value); - return; - } - ASSERT(HandlerBase::IsNonInlinedProps(handler)); - TaggedArray *array = TaggedArray::Cast(obj->GetProperties().GetTaggedObject()); - int capacity = array->GetLength(); - // grow capacity - if (UNLIKELY(index >= capacity)) { - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle properties; - JSHandle objHandle(thread, obj); - if (capacity == 0) { - capacity = JSObject::MIN_PROPERTIES_LENGTH; - properties = factory->NewTaggedArray(capacity); - } else { - properties = factory->CopyArray(JSHandle(thread, array), capacity, - JSObject::ComputePropertyCapacity(capacity)); - } - properties->Set(thread, index, value); - objHandle->SetProperties(thread, properties); - return; - } - - array->Set(thread, index, value); -} - -bool ICAccessor::StoreGlobal(JSThread *thread, JSObject *obj, JSTaggedValue key, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId) -{ - ASSERT(handler.IsGlobalHandler()); - GlobalHandler *globalHandler = GlobalHandler::Cast(handler.GetTaggedObject()); - PropertyBox *cell = PropertyBox::Cast(globalHandler->GetPropertyBox().GetTaggedObject()); - JSTaggedValue val = cell->GetValue(); - if (cell->IsInvalid()) { - return StoreMiss(thread, JSHandle(thread, obj), JSHandle(thread, key), - JSHandle(thread, value), slotId); - } - if (UNLIKELY(val.IsAccessorData())) { - auto *setter = AccessorData::Cast(val.GetTaggedObject()); - JSObject::CallSetter(thread, *setter, JSHandle(thread, obj), - JSHandle(thread, value)); - return true; - } - cell->SetValue(thread, value); - return true; -} - -bool ICAccessor::StoreGlobalByName(JSThread *thread, JSObject *obj, uint32_t stringId, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId) -{ - ASSERT(handler.IsGlobalHandler()); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - GlobalHandler *globalHandler = GlobalHandler::Cast(handler.GetTaggedObject()); - PropertyBox *cell = PropertyBox::Cast(globalHandler->GetPropertyBox().GetTaggedObject()); - JSTaggedValue val = cell->GetValue(); - if (cell->IsInvalid()) { - JSHandle valueHandle(thread, value); - JSTaggedValue key(factory->ResolveString(stringId)); - return StoreGlobalMissByName(thread, JSHandle(thread, key), valueHandle, slotId); - } - if (UNLIKELY(val.IsAccessorData())) { - auto *setter = AccessorData::Cast(val.GetTaggedObject()); - JSObject::CallSetter(thread, *setter, JSHandle(thread, obj), - JSHandle(thread, value)); - return true; - } - cell->SetValue(thread, value); - return true; -} - -bool ICAccessor::StoreGlobalByValue(JSThread *thread, JSObject *obj, JSTaggedValue key, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId) -{ - ASSERT(handler.IsGlobalHandler()); - GlobalHandler *globalHandler = GlobalHandler::Cast(handler.GetTaggedObject()); - PropertyBox *cell = PropertyBox::Cast(globalHandler->GetPropertyBox().GetTaggedObject()); - JSTaggedValue val = cell->GetValue(); - if (cell->IsInvalid()) { - JSHandle valueHandle(thread, value); - JSHandle keyHandle(thread, key); - return StoreGlobalMissByValue(thread, keyHandle, valueHandle, slotId); - } - if (UNLIKELY(val.IsAccessorData())) { - auto *setter = AccessorData::Cast(val.GetTaggedObject()); - JSObject::CallSetter(thread, *setter, JSHandle(thread, obj), - JSHandle(thread, value)); - return true; - } - cell->SetValue(thread, value); - return true; -} - -bool ICAccessor::StorePrototype(JSThread *thread, JSObject *obj, JSTaggedValue key, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId) -{ - ASSERT(handler.IsPrototypeHandler()); - PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject()); - if (JSHClass::HasProtoChainChanged(prototypeHandler->GetProtoCell())) { - JSObject *holder = JSObject::Cast(prototypeHandler->GetHolder().GetTaggedObject()); - JSTaggedValue handlerInfo = prototypeHandler->GetHandlerInfo(); - AccessorData *setter = nullptr; - if (handlerInfo.IsInt()) { - setter = GetAccessor(thread, holder, handlerInfo.GetInt()); - } else { - ASSERT(handlerInfo.IsGlobalHandler()); - GlobalHandler *globalHandler = GlobalHandler::Cast(handlerInfo.GetTaggedObject()); - PropertyBox *cell = PropertyBox::Cast(globalHandler->GetPropertyBox().GetTaggedObject()); - setter = AccessorData::Cast(cell->GetValue().GetTaggedObject()); - } - JSObject::CallSetter(thread, *setter, JSHandle(thread, obj), - JSHandle(thread, value)); - return true; - } - return StoreMiss(thread, JSHandle(thread, obj), JSHandle(thread, key), - JSHandle(thread, value), slotId); -} - -bool ICAccessor::StorePrototypeByName(JSThread *thread, JSObject *obj, uint32_t stringId, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId) -{ - ASSERT(handler.IsPrototypeHandler()); - PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject()); - if (JSHClass::HasProtoChainChanged(prototypeHandler->GetProtoCell())) { - JSObject *holder = JSObject::Cast(prototypeHandler->GetHolder().GetTaggedObject()); - JSTaggedValue handlerInfo = prototypeHandler->GetHandlerInfo(); - AccessorData *setter; - if (handlerInfo.IsInt()) { - setter = GetAccessor(thread, holder, handlerInfo.GetInt()); - } else { - ASSERT(handlerInfo.IsGlobalHandler()); - GlobalHandler *globalHandler = GlobalHandler::Cast(handlerInfo.GetTaggedObject()); - PropertyBox *cell = PropertyBox::Cast(globalHandler->GetPropertyBox().GetTaggedObject()); - setter = AccessorData::Cast(cell->GetValue().GetTaggedObject()); - } - JSObject::CallSetter(thread, *setter, JSHandle(thread, obj), - JSHandle(thread, value)); - return true; - } - JSHandle objHandle(thread, obj); - JSHandle valueHandle(thread, value); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSTaggedValue key(factory->ResolveString(stringId)); - return StoreMissByName(thread, JSHandle(thread, obj), JSHandle(thread, key), - JSHandle(thread, value), slotId); -} - -bool ICAccessor::StoreGlobalPrototypeByName(JSThread *thread, JSTaggedValue obj, uint32_t stringId, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId) -{ - ASSERT(handler.IsPrototypeHandler()); - PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject()); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - if (JSHClass::HasProtoChainChanged(prototypeHandler->GetProtoCell())) { - JSTaggedValue handlerInfo = prototypeHandler->GetHandlerInfo(); - ASSERT(handlerInfo.IsGlobalHandler()); - GlobalHandler *globalHandler = GlobalHandler::Cast(handlerInfo.GetTaggedObject()); - PropertyBox *cell = PropertyBox::Cast(globalHandler->GetPropertyBox().GetTaggedObject()); - auto *setter = AccessorData::Cast(cell->GetValue().GetTaggedObject()); - JSObject::CallSetter(thread, *setter, JSHandle(thread, obj), - JSHandle(thread, value)); - return true; - } - JSHandle valueHandle(thread, value); - JSTaggedValue key(factory->ResolveString(stringId)); - return StoreGlobalMissByName(thread, JSHandle(thread, key), JSHandle(thread, value), - slotId); -} - -AccessorData *ICAccessor::GetAccessor([[maybe_unused]] JSThread *thread, JSObject *obj, uint32_t handler) -{ - DISALLOW_GARBAGE_COLLECTION; - JSTaggedValue accessor = JSTaggedValue::Undefined(); - int index = HandlerBase::GetOffset(handler); - if (HandlerBase::IsInlinedProps(handler)) { - accessor = obj->GetPropertyInlinedProps(index); - } else if (HandlerBase::IsNonInlinedProps(handler)) { - TaggedArray *array = TaggedArray::Cast(obj->GetProperties().GetTaggedObject()); - accessor = array->Get(index); - } - ASSERT(!accessor.IsUndefined()); - return AccessorData::Cast(accessor.GetTaggedObject()); -} - -bool ICAccessor::StoreGlobalICByValue(JSThread *thread, JSTaggedValue key, JSTaggedValue value, uint16_t slotId) -{ - ASSERT_PRINT(JSTaggedValue::IsPropertyKey(JSHandle(thread, key)), "Key is not a property key"); - - if (key.IsNumber()) { - JSTaggedValue globalValue = thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject(); - return JSTaggedValue::SetProperty(thread, JSHandle(thread, globalValue), - JSHandle(thread, key), JSHandle(thread, value)); - } - FunctionCache *cache = FunctionCache::GetCurrent(thread); - JSTaggedValue handler = cache->GetGlobalHandlerByValue(key, slotId); - bool success = false; - if (!handler.IsNull()) { - JSTaggedValue globalValue = thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject(); - success = StoreGlobalWithHandlerByValue(thread, globalValue, key, value, handler, slotId); - } else { - success = StoreGlobalMissByValue(thread, JSHandle(thread, key), - JSHandle(thread, value), slotId); - } - return success; -} - -JSTaggedValue ICAccessor::LoadGlobalIC(JSThread *thread, JSTaggedValue key, uint16_t slotId) -{ - ASSERT_PRINT(JSTaggedValue::IsPropertyKey(JSHandle(thread, key)), "Key is not a property key"); - JSTaggedValue globalValue = thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject(); - if (key.IsNumber()) { - return FastRuntimeStub::FastGetPropertyByIndex(thread, globalValue, key.GetArrayLength()); - } - FunctionCache *cache = FunctionCache::GetCurrent(thread); - JSTaggedValue handler = cache->GetGlobalHandlerByValue(key, slotId); - if (!handler.IsNull()) { - JSTaggedValue ret = LoadGlobalWithHandler(thread, globalValue, handler); - if (!ret.IsHole()) { - return ret; - } - } - return LoadGlobalMiss(thread, JSHandle(thread, key), slotId); -} - -JSTaggedValue ICAccessor::LoadGlobalICByName(JSThread *thread, uint32_t stringId, uint16_t slotId) -{ - FunctionCache *cache = FunctionCache::GetCurrent(thread); - JSTaggedValue handler = cache->GetGlobalHandlerByIndex(slotId); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - if (!handler.IsNull()) { - JSTaggedValue globalValue = thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject(); - JSTaggedValue ret = LoadGlobalWithHandler(thread, globalValue, handler); - if (!ret.IsHole()) { - return ret; - } - } - JSTaggedValue key(factory->ResolveString(stringId)); - return LoadGlobalMissByName(thread, JSHandle(thread, key), slotId); -} -} // namespace panda::ecmascript diff --git a/ecmascript/ic/ic_accessor.h b/ecmascript/ic/ic_accessor.h deleted file mode 100644 index 57cab7b4307155fc340cea45d56a7543999c2fa7..0000000000000000000000000000000000000000 --- a/ecmascript/ic/ic_accessor.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_IC_ACCESSOR_H -#define PANDA_RUNTIME_ECMASCRIPT_IC_ACCESSOR_H - -#include "ecmascript/accessor_data.h" -#include "ecmascript/ecma_macros.h" -#include "ecmascript/ecma_vm.h" -#include "ecmascript/js_handle.h" -#include "ecmascript/js_tagged_value.h" - -namespace panda::ecmascript { -class ICAccessor { -public: - static JSTaggedValue LoadIC(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, uint16_t slotId); - - static JSTaggedValue LoadGlobalIC(JSThread *thread, JSTaggedValue key, uint16_t slotId); - - static JSTaggedValue LoadGlobalICByName(JSThread *thread, uint32_t stringId, uint16_t slotId); - - static JSTaggedValue LoadICByName(JSThread *thread, JSTaggedValue receiver, uint32_t stringId, uint16_t slotId); - // dispatch - static JSTaggedValue LoadWithHandler(JSThread *thread, JSObject *obj, JSTaggedValue receiver, - JSTaggedValue handler); - - static JSTaggedValue LoadGlobalWithHandler(JSThread *thread, JSTaggedValue receiver, JSTaggedValue handler); - - static JSTaggedValue LoadProperty(JSThread *thread, JSObject *obj, JSTaggedValue receiver, JSTaggedValue handler); - - static JSTaggedValue LoadGlobal(JSThread *thread, JSTaggedValue receiver, JSTaggedValue handler); - - static JSTaggedValue LoadPrototype(JSThread *thread, JSObject *obj, JSTaggedValue handler); - - static JSTaggedValue LoadGlobalPrototype(JSThread *thread, JSTaggedValue obj, JSTaggedValue handler); - - static JSTaggedValue LoadNonExistent(JSTaggedValue handler); - - static bool StoreIC(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, - uint16_t slotId); - - static bool StoreGlobalICByName(JSThread *thread, uint32_t stringId, JSTaggedValue value, uint16_t slotId); - - static bool StoreGlobalICByValue(JSThread *thread, JSTaggedValue key, JSTaggedValue value, uint16_t slotId); - - static bool StoreICByName(JSThread *thread, JSTaggedValue receiver, uint32_t stringId, JSTaggedValue value, - uint16_t slotId); - - static bool StoreWithHandler(JSThread *thread, JSObject *obj, JSTaggedValue key, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId); - - static bool StoreWithHandlerByName(JSThread *thread, JSObject *obj, uint32_t stringId, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId); - - static bool StoreGlobalWithHandlerByName(JSThread *thread, JSTaggedValue obj, uint32_t stringId, - JSTaggedValue value, JSTaggedValue handler, uint16_t slotId); - - static bool StoreGlobalWithHandlerByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, - JSTaggedValue value, JSTaggedValue handler, uint16_t slotId); - - static void StoreProperty(JSThread *thread, JSObject *obj, JSTaggedValue value, uint32_t handler); - - static void StoreField(const JSThread *thread, JSObject *obj, JSTaggedValue value, uint32_t handler); - - static bool StoreGlobal(JSThread *thread, JSObject *obj, JSTaggedValue key, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId); - - static bool StoreGlobalByName(JSThread *thread, JSObject *obj, uint32_t stringId, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId); - - static bool StoreGlobalByValue(JSThread *thread, JSObject *obj, JSTaggedValue key, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId); - - static void StoreWithTransition(const JSThread *thread, JSObject *obj, JSTaggedValue value, JSTaggedValue handler); - - static bool StorePrototype(JSThread *thread, JSObject *obj, JSTaggedValue key, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId); - - static bool StorePrototypeByName(JSThread *thread, JSObject *obj, uint32_t stringId, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId); - - static bool StoreGlobalPrototypeByName(JSThread *thread, JSTaggedValue obj, uint32_t stringId, JSTaggedValue value, - JSTaggedValue handler, uint16_t slotId); - - static inline bool StoreGlobalPrototypeByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, - JSTaggedValue value, JSTaggedValue handler, uint16_t slotId); - - static AccessorData *GetAccessor(JSThread *thread, JSObject *obj, uint32_t handler); - - static AccessorData *GetInternelAccessor(JSObject *obj, uint32_t handler); - - static JSTaggedValue LoadMiss(JSThread *thread, const JSHandle &obj, const JSHandle &key, - uint16_t slotId); - - static JSTaggedValue LoadGlobalMiss(JSThread *thread, const JSHandle &key, uint16_t slotId); - - static JSTaggedValue LoadGlobalMissByName(JSThread *thread, const JSHandle &key, uint16_t slotId); - - static bool StoreMiss(JSThread *thread, const JSHandle &obj, const JSHandle &key, - const JSHandle &value, uint16_t slotId); - - static JSTaggedValue LoadMissByName(JSThread *thread, const JSHandle &obj, - const JSHandle &key, uint16_t slotId); - - static bool StoreMissByName(JSThread *thread, const JSHandle &obj, const JSHandle &key, - const JSHandle &value, uint16_t slotId); - static bool StoreGlobalMissByName(JSThread *thread, const JSHandle &key, - const JSHandle &value, uint16_t slotId); - - static bool StoreGlobalMissByValue(JSThread *thread, const JSHandle &key, - const JSHandle &value, uint16_t slotId); -}; -} // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_IC_ACCESSOR_H diff --git a/ecmascript/ic/ic_handler-inl.h b/ecmascript/ic/ic_handler-inl.h index effd3ada1496be2521fd547c7d24575c284d4ee8..99c901649b3730fe850a0f90cf9fac72055460dd 100644 --- a/ecmascript/ic/ic_handler-inl.h +++ b/ecmascript/ic/ic_handler-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_IC_HANDLER_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_IC_HANDLER_INL_H +#ifndef ECMASCRIPT_IC_IC_HANDLER_INL_H +#define ECMASCRIPT_IC_IC_HANDLER_INL_H #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" @@ -22,26 +22,26 @@ #include "ic_handler.h" namespace panda::ecmascript { -JSTaggedValue LoadHandler::LoadElement() +JSHandle LoadHandler::LoadElement(const JSThread *thread) { uint32_t handler = 0; KindBit::Set(HandlerKind::ELEMENT, &handler); - return JSTaggedValue(handler); + return JSHandle(thread, JSTaggedValue(handler)); } -JSTaggedValue LoadHandler::LoadProperty(const ObjectOperator &op) +JSHandle LoadHandler::LoadProperty(const JSThread *thread, const ObjectOperator &op) { uint32_t handler = 0; ASSERT(!op.IsElement()); if (!op.IsFound()) { KindBit::Set(HandlerKind::NON_EXIST, &handler); - return JSTaggedValue(handler); + return JSHandle(thread, JSTaggedValue(handler)); } ASSERT(op.IsFastMode()); JSTaggedValue val = op.GetValue(); if (val.IsPropertyBox()) { - return val; + return JSHandle(thread, val); } bool hasAccessor = op.IsAccessorDescriptor(); AccessorBit::Set(hasAccessor, &handler); @@ -54,44 +54,46 @@ JSTaggedValue LoadHandler::LoadProperty(const ObjectOperator &op) JSHandle holder = JSHandle::Cast(op.GetHolder()); auto index = holder->GetPropertyInObjectIndex(op.GetIndex()); OffsetBit::Set(index, &handler); - return JSTaggedValue(handler); + return JSHandle(thread, JSTaggedValue(handler)); } if (op.IsFastMode()) { OffsetBit::Set(op.GetIndex(), &handler); - return JSTaggedValue(handler); + return JSHandle(thread, JSTaggedValue(handler)); } UNREACHABLE(); } -inline JSTaggedValue PrototypeHandler::LoadPrototype(const JSThread *thread, const ObjectOperator &op, - const JSHandle &hclass) +JSHandle PrototypeHandler::LoadPrototype(const JSThread *thread, + const ObjectOperator &op, + const JSHandle &hclass) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSTaggedValue handlerInfo = LoadHandler::LoadProperty(op); - PrototypeHandler *handler = factory->NewPrototypeHandler(); + JSHandle handlerInfo = LoadHandler::LoadProperty(thread, op); + JSHandle handler = factory->NewPrototypeHandler(); handler->SetHandlerInfo(thread, handlerInfo); if (op.IsFound()) { handler->SetHolder(thread, op.GetHolder()); } auto result = JSHClass::EnableProtoChangeMarker(thread, hclass); handler->SetProtoCell(thread, result); - return JSTaggedValue(handler); + return JSHandle::Cast(handler); } -inline JSTaggedValue PrototypeHandler::StorePrototype(const JSThread *thread, const ObjectOperator &op, - const JSHandle &hclass) +JSHandle PrototypeHandler::StorePrototype(const JSThread *thread, + const ObjectOperator &op, + const JSHandle &hclass) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - PrototypeHandler *handler = factory->NewPrototypeHandler(); - JSTaggedValue handlerInfo = StoreHandler::StoreProperty(op); + JSHandle handler = factory->NewPrototypeHandler(); + JSHandle handlerInfo = StoreHandler::StoreProperty(thread, op); handler->SetHandlerInfo(thread, handlerInfo); handler->SetHolder(thread, op.GetHolder()); auto result = JSHClass::EnableProtoChangeMarker(thread, hclass); handler->SetProtoCell(thread, result); - return JSTaggedValue(handler); + return JSHandle::Cast(handler); } -JSTaggedValue StoreHandler::StoreElement(JSHandle receiver) +JSHandle StoreHandler::StoreElement(const JSThread *thread, JSHandle receiver) { uint32_t handler = 0; KindBit::Set(HandlerKind::ELEMENT, &handler); @@ -99,16 +101,16 @@ JSTaggedValue StoreHandler::StoreElement(JSHandle receiver) if (receiver->IsJSArray()) { IsJSArrayBit::Set(true, &handler); } - return JSTaggedValue(handler); + return JSHandle(thread, JSTaggedValue(handler)); } -JSTaggedValue StoreHandler::StoreProperty(const ObjectOperator &op) +JSHandle StoreHandler::StoreProperty(const JSThread *thread, const ObjectOperator &op) { ASSERT(!op.IsElement()); uint32_t handler = 0; JSTaggedValue val = op.GetValue(); if (val.IsPropertyBox()) { - return val; + return JSHandle(thread, val); } bool hasSetter = op.IsAccessorDescriptor(); AccessorBit::Set(hasSetter, &handler); @@ -120,23 +122,23 @@ JSTaggedValue StoreHandler::StoreProperty(const ObjectOperator &op) JSHandle receiver = JSHandle::Cast(op.GetReceiver()); auto index = receiver->GetPropertyInObjectIndex(op.GetIndex()); OffsetBit::Set(index, &handler); - return JSTaggedValue(handler); + return JSHandle(thread, JSTaggedValue(handler)); } ASSERT(op.IsFastMode()); OffsetBit::Set(op.GetIndex(), &handler); - return JSTaggedValue(handler); + return JSHandle(thread, JSTaggedValue(handler)); } -inline JSTaggedValue TransitionHandler::StoreTransition(const JSThread *thread, const ObjectOperator &op) +JSHandle TransitionHandler::StoreTransition(const JSThread *thread, const ObjectOperator &op) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - TransitionHandler *handler = factory->NewTransitionHandler(); - JSTaggedValue handlerInfo = StoreHandler::StoreProperty(op); + JSHandle handler = factory->NewTransitionHandler(); + JSHandle handlerInfo = StoreHandler::StoreProperty(thread, op); handler->SetHandlerInfo(thread, handlerInfo); auto hclass = JSObject::Cast(op.GetReceiver()->GetHeapObject())->GetJSHClass(); handler->SetTransitionHClass(thread, JSTaggedValue(hclass)); - return JSTaggedValue(handler); + return JSHandle::Cast(handler); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_IC_HANDLER_INL_H +#endif // ECMASCRIPT_IC_IC_HANDLER_INL_H diff --git a/ecmascript/ic/ic_handler.h b/ecmascript/ic/ic_handler.h index 91f193f085a01562f6f6bcc9b2efb1c29dc8b0e0..e87af94ab09b8e3c26293a790222d270e38b6dcc 100644 --- a/ecmascript/ic/ic_handler.h +++ b/ecmascript/ic/ic_handler.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_IC_HANDLER_H -#define PANDA_RUNTIME_ECMASCRIPT_IC_HANDLER_H +#ifndef ECMASCRIPT_IC_IC_HANDLER_H +#define ECMASCRIPT_IC_IC_HANDLER_H #include "ecmascript/ecma_macros.h" #include "ecmascript/js_tagged_value-inl.h" @@ -95,14 +95,15 @@ public: class LoadHandler final : public HandlerBase { public: - static inline JSTaggedValue LoadProperty(const ObjectOperator &op); - static inline JSTaggedValue LoadElement(); + static inline JSHandle LoadProperty(const JSThread *thread, const ObjectOperator &op); + static inline JSHandle LoadElement(const JSThread *thread); }; class StoreHandler final : public HandlerBase { public: - static inline JSTaggedValue StoreProperty(const ObjectOperator &op); - static inline JSTaggedValue StoreElement(JSHandle receiver); + static inline JSHandle StoreProperty(const JSThread *thread, const ObjectOperator &op); + static inline JSHandle StoreElement(const JSThread *thread, + JSHandle receiver); }; class TransitionHandler : public TaggedObject { @@ -113,9 +114,9 @@ public: return static_cast(object); } - static inline JSTaggedValue StoreTransition(const JSThread *thread, const ObjectOperator &op); + static inline JSHandle StoreTransition(const JSThread *thread, const ObjectOperator &op); - static constexpr size_t HANDLER_INFO_OFFSET = sizeof(TaggedObject); + static constexpr size_t HANDLER_INFO_OFFSET = TaggedObjectSize(); ACCESSORS(HandlerInfo, HANDLER_INFO_OFFSET, TRANSITION_HCLASS_OFFSET) ACCESSORS(TransitionHClass, TRANSITION_HCLASS_OFFSET, SIZE) @@ -131,12 +132,12 @@ public: return static_cast(object); } - static inline JSTaggedValue LoadPrototype(const JSThread *thread, const ObjectOperator &op, - const JSHandle &hclass); - static inline JSTaggedValue StorePrototype(const JSThread *thread, const ObjectOperator &op, - const JSHandle &hclass); + static inline JSHandle LoadPrototype(const JSThread *thread, const ObjectOperator &op, + const JSHandle &hclass); + static inline JSHandle StorePrototype(const JSThread *thread, const ObjectOperator &op, + const JSHandle &hclass); - static constexpr size_t HANDLER_INFO_OFFSET = sizeof(TaggedObject); + static constexpr size_t HANDLER_INFO_OFFSET = TaggedObjectSize(); ACCESSORS(HandlerInfo, HANDLER_INFO_OFFSET, PROTO_CELL_OFFSET) @@ -147,4 +148,4 @@ public: DECL_VISIT_OBJECT(HANDLER_INFO_OFFSET, SIZE) }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_IC_HANDLER_H +#endif // ECMASCRIPT_IC_IC_HANDLER_H diff --git a/ecmascript/ic/ic_runtime.cpp b/ecmascript/ic/ic_runtime.cpp index ee47519aac9ba5c91a17eba46fded1ec7d33691e..2c3b96859aab4f68461ef63c777059e17223b148 100644 --- a/ecmascript/ic/ic_runtime.cpp +++ b/ecmascript/ic/ic_runtime.cpp @@ -38,15 +38,18 @@ void ICRuntime::UpdateLoadHandler(const ObjectOperator &op, JSHandle(); } - JSTaggedValue handlerValue; + JSHandle handlerValue; JSHandle hclass(GetThread(), JSHandle::Cast(receiver)->GetClass()); if (op.IsElement()) { - handlerValue = LoadHandler::LoadElement(); + if (!op.IsFound() && hclass->IsDictionaryElement()) { + return; + } + handlerValue = LoadHandler::LoadElement(thread_); } else { if (!op.IsFound()) { handlerValue = PrototypeHandler::LoadPrototype(thread_, op, hclass); } else if (!op.IsOnPrototype()) { - handlerValue = LoadHandler::LoadProperty(op); + handlerValue = LoadHandler::LoadProperty(thread_, op); } else { // do not support global prototype ic if (IsGlobalLoadIC(GetICKind())) { @@ -56,17 +59,16 @@ void ICRuntime::UpdateLoadHandler(const ObjectOperator &op, JSHandle(thread_, handlerValue); if (key.IsEmpty()) { - icAccessor_.AddHandlerWithoutKey(JSHandle::Cast(hclass), handler); + icAccessor_.AddHandlerWithoutKey(JSHandle::Cast(hclass), handlerValue); } else if (op.IsElement()) { // do not support global element ic if (IsGlobalLoadIC(GetICKind())) { return; } - icAccessor_.AddElementHandler(JSHandle::Cast(hclass), handler); + icAccessor_.AddElementHandler(JSHandle::Cast(hclass), handlerValue); } else { - icAccessor_.AddHandlerWithKey(key, JSHandle::Cast(hclass), handler); + icAccessor_.AddHandlerWithKey(key, JSHandle::Cast(hclass), handlerValue); } } @@ -79,9 +81,9 @@ void ICRuntime::UpdateStoreHandler(const ObjectOperator &op, JSHandle(); } - JSTaggedValue handlerValue; + JSHandle handlerValue; if (op.IsElement()) { - handlerValue = StoreHandler::StoreElement(receiver); + handlerValue = StoreHandler::StoreElement(thread_, receiver); } else { ASSERT(op.IsFound()); if (op.IsOnPrototype()) { @@ -89,26 +91,25 @@ void ICRuntime::UpdateStoreHandler(const ObjectOperator &op, JSHandle hclass(GetThread(), JSHandle::Cast(receiver)->GetClass()); + JSHandle hclass(thread_, JSHandle::Cast(receiver)->GetClass()); handlerValue = PrototypeHandler::StorePrototype(thread_, op, hclass); } else if (op.IsTransition()) { handlerValue = TransitionHandler::StoreTransition(thread_, op); } else { - handlerValue = StoreHandler::StoreProperty(op); + handlerValue = StoreHandler::StoreProperty(thread_, op); } } - auto handler = JSHandle(thread_, handlerValue); if (key.IsEmpty()) { - icAccessor_.AddHandlerWithoutKey(receiverHClass_, handler); + icAccessor_.AddHandlerWithoutKey(receiverHClass_, handlerValue); } else if (op.IsElement()) { // do not support global element ic if (IsGlobalStoreIC(GetICKind())) { return; } - icAccessor_.AddElementHandler(receiverHClass_, handler); + icAccessor_.AddElementHandler(receiverHClass_, handlerValue); } else { - icAccessor_.AddHandlerWithKey(key, receiverHClass_, handler); + icAccessor_.AddHandlerWithKey(key, receiverHClass_, handlerValue); } } @@ -132,11 +133,11 @@ void ICRuntime::TraceIC([[maybe_unused]] JSHandle receiver, JSTaggedValue LoadICRuntime::LoadMiss(JSHandle receiver, JSHandle key) { - if (!receiver->IsJSObject()) { + if (receiver->IsTypedArray() || !receiver->IsJSObject()) { return JSTaggedValue::GetProperty(GetThread(), receiver, key).GetValue().GetTaggedValue(); } ObjectOperator op(GetThread(), receiver, key); - auto result = JSObject::GetProperty(GetThread(), &op); + auto result = JSHandle(thread_, JSObject::GetProperty(GetThread(), &op)); if (!op.IsFound() && GetICKind() == ICKind::NamedGlobalLoadIC) { return SlowRuntimeStub::ThrowReferenceError(GetThread(), key.GetTaggedValue(), " is not defined"); } @@ -144,7 +145,7 @@ JSTaggedValue LoadICRuntime::LoadMiss(JSHandle receiver, JSHandle // ic-switch if (!GetThread()->GetEcmaVM()->ICEnable()) { icAccessor_.SetAsMega(); - return result; + return result.GetTaggedValue(); } #ifndef NDEBUG TraceIC(receiver, key); @@ -152,17 +153,17 @@ JSTaggedValue LoadICRuntime::LoadMiss(JSHandle receiver, JSHandle // do not cache element if (!op.IsFastMode() && op.IsFound()) { icAccessor_.SetAsMega(); - return result; + return result.GetTaggedValue(); } UpdateLoadHandler(op, key, receiver); - return result; + return result.GetTaggedValue(); } JSTaggedValue StoreICRuntime::StoreMiss(JSHandle receiver, JSHandle key, JSHandle value) { - if (!receiver->IsJSObject()) { + if (receiver->IsTypedArray() || !receiver->IsJSObject()) { bool success = JSTaggedValue::SetProperty(GetThread(), receiver, key, value, true); return success ? JSTaggedValue::Undefined() : JSTaggedValue::Exception(); } @@ -185,7 +186,10 @@ JSTaggedValue StoreICRuntime::StoreMiss(JSHandle receiver, JSHand icAccessor_.SetAsMega(); return success ? JSTaggedValue::Undefined() : JSTaggedValue::Exception(); } - UpdateStoreHandler(op, key, receiver); - return success ? JSTaggedValue::Undefined() : JSTaggedValue::Exception(); + if (success) { + UpdateStoreHandler(op, key, receiver); + return JSTaggedValue::Undefined(); + } + return JSTaggedValue::Exception(); } } // namespace panda::ecmascript diff --git a/ecmascript/ic/ic_runtime.h b/ecmascript/ic/ic_runtime.h index 3fe5320e8c6253998fa41360fce986863897937e..350fa71bdf10bd8adfd555a5a5171bc1e9a6eb9c 100644 --- a/ecmascript/ic/ic_runtime.h +++ b/ecmascript/ic/ic_runtime.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_IC_IC_RUNTIME_H -#define PANDA_RUNTIME_ECMASCRIPT_IC_IC_RUNTIME_H +#ifndef ECMASCRIPT_IC_IC_RUNTIME_H +#define ECMASCRIPT_IC_IC_RUNTIME_H #include "ecmascript/ic/profile_type_info.h" #include "ecmascript/accessor_data.h" @@ -88,4 +88,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_IC_IC_RUNTIME_H +#endif // ECMASCRIPT_IC_IC_RUNTIME_H diff --git a/ecmascript/ic/fast_ic_runtime_stub-inl.h b/ecmascript/ic/ic_runtime_stub-inl.h similarity index 66% rename from ecmascript/ic/fast_ic_runtime_stub-inl.h rename to ecmascript/ic/ic_runtime_stub-inl.h index d58c3d73ad9527734e71cdcc803a5fdea0a60f0e..ea51670b40064d3d9b5b1e0bb4315343d622bcc2 100644 --- a/ecmascript/ic/fast_ic_runtime_stub-inl.h +++ b/ecmascript/ic/ic_runtime_stub-inl.h @@ -13,10 +13,11 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_FAST_IC_RUNTIME_STUB_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_FAST_IC_RUNTIME_STUB_INL_H +#ifndef ECMASCRIPT_IC_IC_RUNTIME_STUB_INL_H_ +#define ECMASCRIPT_IC_IC_RUNTIME_STUB_INL_H_ -#include "fast_ic_runtime_stub.h" +#include "ecmascript/base/config.h" +#include "ic_runtime_stub.h" #include "ic_handler.h" #include "ic_runtime.h" #include "profile_type_info.h" @@ -32,6 +33,9 @@ #include "ecmascript/interpreter/fast_runtime_stub-inl.h" #include "ecmascript/ic/proto_change_details.h" +#include "ecmascript/vmstat/runtime_stat.h" +#include "ecmascript/runtime_call_id.h" + namespace panda::ecmascript { JSTaggedValue ICRuntimeStub::LoadGlobalICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue globalValue, JSTaggedValue key, uint32_t slotId) @@ -90,75 +94,60 @@ JSTaggedValue ICRuntimeStub::CheckPolyHClass(JSTaggedValue cachedValue, JSHClass return JSTaggedValue::Hole(); } -JSTaggedValue ICRuntimeStub::LoadICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId) +ARK_INLINE JSTaggedValue ICRuntimeStub::TryLoadICByName(JSThread *thread, JSTaggedValue receiver, + JSTaggedValue firstValue, JSTaggedValue secondValue) { - if (receiver.IsHeapObject()) { - JSTaggedValue cachedValue = profileTypeInfo->Get(slotId); - if (cachedValue.IsHeapObject()) { - auto hclass = receiver.GetTaggedObject()->GetClass(); - if (cachedValue.GetWeakReferentUnChecked() == hclass) { - auto cachedHandler = profileTypeInfo->Get(slotId + 1); - auto result = LoadICWithHandler(thread, receiver, receiver, cachedHandler); - if (!result.IsHole()) { - return result; - } - } - JSTaggedValue cachedHandler = CheckPolyHClass(cachedValue, hclass); - if (!cachedHandler.IsHole()) { - auto result = LoadICWithHandler(thread, receiver, receiver, cachedHandler); - if (!result.IsHole()) { - return result; - } - } - } else if (cachedValue.IsHole()) { - JSTaggedValue result = FastRuntimeStub::GetPropertyByName(thread, receiver, key); - if (!result.IsHole()) { - return result; - } + INTERPRETER_TRACE(thread, TryLoadICByName); + if (LIKELY(receiver.IsHeapObject())) { + auto hclass = receiver.GetTaggedObject()->GetClass(); + if (LIKELY(firstValue.GetWeakReferentUnChecked() == hclass)) { + return LoadICWithHandler(thread, receiver, receiver, secondValue); + } + JSTaggedValue cachedHandler = CheckPolyHClass(firstValue, hclass); + if (!cachedHandler.IsHole()) { + return LoadICWithHandler(thread, receiver, receiver, cachedHandler); } } + return JSTaggedValue::Hole(); +} +ARK_NOINLINE JSTaggedValue ICRuntimeStub::LoadICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId) +{ + INTERPRETER_TRACE(thread, LoadICByName); [[maybe_unused]] EcmaHandleScope handleScope(thread); auto keyHandle = JSHandle(thread, key); auto receiverHandle = JSHandle(thread, receiver); - auto profileInfoHandle = JSHandle(thread, profileTypeInfo); - LoadICRuntime icRuntime(thread, JSHandle::Cast(profileInfoHandle), slotId, ICKind::NamedLoadIC); + auto profileInfoHandle = JSHandle(thread, profileTypeInfo); + LoadICRuntime icRuntime(thread, profileInfoHandle, slotId, ICKind::NamedLoadIC); return icRuntime.LoadMiss(receiverHandle, keyHandle); } -JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, - JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId) +ARK_INLINE JSTaggedValue ICRuntimeStub::TryLoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue firstValue, JSTaggedValue secondValue) { + INTERPRETER_TRACE(thread, TryLoadICByValue); if (receiver.IsHeapObject()) { - JSTaggedValue cachedValue = profileTypeInfo->Get(slotId); - if (cachedValue.IsHeapObject()) { - auto hclass = receiver.GetTaggedObject()->GetClass(); - if (cachedValue.GetWeakReferentUnChecked() == hclass) { - ASSERT(HandlerBase::IsElement(profileTypeInfo->Get(slotId + 1).GetInt())); - auto result = LoadElement(JSObject::Cast(receiver.GetHeapObject()), key); - if (!result.IsHole()) { - return result; - } - } - // Check key - if (cachedValue == key) { - cachedValue = profileTypeInfo->Get(slotId + 1); - JSTaggedValue cachedHandler = CheckPolyHClass(cachedValue, hclass); - if (!cachedHandler.IsHole()) { - auto result = LoadICWithHandler(thread, receiver, receiver, cachedHandler); - if (!result.IsHole()) { - return result; - } - } - } - } else if (cachedValue.IsHole()) { - JSTaggedValue result = FastRuntimeStub::GetPropertyByValue(thread, receiver, key); - if (!result.IsHole()) { - return result; + auto hclass = receiver.GetTaggedObject()->GetClass(); + if (firstValue.GetWeakReferentUnChecked() == hclass) { + ASSERT(HandlerBase::IsElement(secondValue.GetInt())); + return LoadElement(JSObject::Cast(receiver.GetHeapObject()), key); + } + // Check key + if (firstValue == key) { + JSTaggedValue cachedHandler = CheckPolyHClass(secondValue, hclass); + if (!cachedHandler.IsHole()) { + return LoadICWithHandler(thread, receiver, receiver, cachedHandler); } } } + return JSTaggedValue::Hole(); +} + +ARK_NOINLINE JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId) +{ + INTERPRETER_TRACE(thread, LoadICByValue); [[maybe_unused]] EcmaHandleScope handleScope(thread); auto keyHandle = JSHandle(thread, key); @@ -168,39 +157,35 @@ JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, ProfileTypeInfo *pr return icRuntime.LoadMiss(receiverHandle, keyHandle); } -JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver, - JSTaggedValue key, JSTaggedValue value, uint32_t slotId) +ARK_INLINE JSTaggedValue ICRuntimeStub::TryStoreICByValue(JSThread *thread, JSTaggedValue receiver, + JSTaggedValue key, JSTaggedValue firstValue, + JSTaggedValue secondValue, JSTaggedValue value) { + INTERPRETER_TRACE(thread, TryStoreICByValue); if (receiver.IsHeapObject()) { - JSTaggedValue cachedValue = profileTypeInfo->Get(slotId); - if (cachedValue.IsHeapObject()) { - auto hclass = receiver.GetTaggedObject()->GetClass(); - if (cachedValue.GetWeakReferentUnChecked() == hclass) { - auto handlerInfo = static_cast(profileTypeInfo->Get(slotId + 1).GetInt()); - auto result = StoreElement(thread, JSObject::Cast(receiver.GetHeapObject()), key, value, handlerInfo); - if (!result.IsHole()) { - return result; - } - } - // Check key - if (cachedValue == key) { - cachedValue = profileTypeInfo->Get(slotId + 1); - JSTaggedValue cachedHandler = CheckPolyHClass(cachedValue, hclass); - if (!cachedHandler.IsHole()) { - auto result = StoreICWithHandler(thread, receiver, receiver, value, cachedHandler); - if (!result.IsHole()) { - return result; - } - } - } - } else if (cachedValue.IsHole()) { - JSTaggedValue result = FastRuntimeStub::SetPropertyByValue(thread, receiver, key, value); - if (!result.IsHole()) { - return result; + auto hclass = receiver.GetTaggedObject()->GetClass(); + if (firstValue.GetWeakReferentUnChecked() == hclass) { + auto handlerInfo = static_cast(secondValue.GetInt()); + return StoreElement(thread, JSObject::Cast(receiver.GetHeapObject()), key, value, handlerInfo); + } + // Check key + if (firstValue == key) { + JSTaggedValue cachedHandler = CheckPolyHClass(secondValue, hclass); + if (!cachedHandler.IsHole()) { + return StoreICWithHandler(thread, receiver, receiver, value, cachedHandler); } } } + return JSTaggedValue::Hole(); +} + +ARK_NOINLINE JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue value, uint32_t slotId) +{ + INTERPRETER_TRACE(thread, StoreICByValue); + [[maybe_unused]] EcmaHandleScope handleScope(thread); auto keyHandle = JSHandle(thread, key); auto receiverHandle = JSHandle(thread, receiver); @@ -210,34 +195,29 @@ JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, ProfileTypeInfo *p return icRuntime.StoreMiss(receiverHandle, keyHandle, valueHandle); } -JSTaggedValue ICRuntimeStub::StoreICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver, - JSTaggedValue key, JSTaggedValue value, uint32_t slotId) +ARK_INLINE JSTaggedValue ICRuntimeStub::TryStoreICByName(JSThread *thread, JSTaggedValue receiver, + JSTaggedValue firstValue, JSTaggedValue secondValue, + JSTaggedValue value) { + INTERPRETER_TRACE(thread, TryStoreICByName); if (receiver.IsHeapObject()) { - JSTaggedValue cachedValue = profileTypeInfo->Get(slotId); - if (cachedValue.IsHeapObject()) { - auto hclass = receiver.GetTaggedObject()->GetClass(); - if (cachedValue.GetWeakReferentUnChecked() == hclass) { - auto cachedHandler = profileTypeInfo->Get(slotId + 1); - auto result = StoreICWithHandler(thread, receiver, receiver, value, cachedHandler); - if (!result.IsHole()) { - return result; - } - } - JSTaggedValue cachedHandler = CheckPolyHClass(cachedValue, hclass); - if (!cachedHandler.IsHole()) { - auto result = StoreICWithHandler(thread, receiver, receiver, value, cachedHandler); - if (!result.IsHole()) { - return result; - } - } - } else if (cachedValue.IsHole()) { - JSTaggedValue result = FastRuntimeStub::SetPropertyByName(thread, receiver, key, value); - if (!result.IsHole()) { - return result; - } + auto hclass = receiver.GetTaggedObject()->GetClass(); + if (firstValue.GetWeakReferentUnChecked() == hclass) { + return StoreICWithHandler(thread, receiver, receiver, value, secondValue); + } + JSTaggedValue cachedHandler = CheckPolyHClass(firstValue, hclass); + if (!cachedHandler.IsHole()) { + return StoreICWithHandler(thread, receiver, receiver, value, cachedHandler); } } + return JSTaggedValue::Hole(); +} + +ARK_NOINLINE JSTaggedValue ICRuntimeStub::StoreICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, + JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue value, uint32_t slotId) +{ + INTERPRETER_TRACE(thread, StoreICByName); [[maybe_unused]] EcmaHandleScope handleScope(thread); auto keyHandle = JSHandle(thread, key); @@ -248,8 +228,9 @@ JSTaggedValue ICRuntimeStub::StoreICByName(JSThread *thread, ProfileTypeInfo *pr return icRuntime.StoreMiss(receiverHandle, keyHandle, valueHandle); } -JSTaggedValue ICRuntimeStub::StoreICWithHandler(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder, - JSTaggedValue value, JSTaggedValue handler) +ARK_INLINE JSTaggedValue ICRuntimeStub::StoreICWithHandler(JSThread *thread, JSTaggedValue receiver, + JSTaggedValue holder, + JSTaggedValue value, JSTaggedValue handler) { if (handler.IsInt()) { auto handlerInfo = static_cast(handler.GetInt()); @@ -307,14 +288,16 @@ void ICRuntimeStub::StoreWithTransition(JSThread *thread, JSObject *receiver, JS ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle properties; JSHandle objHandle(thread, receiver); + JSHandle valueHandle(thread, value); if (capacity == 0) { capacity = JSObject::MIN_PROPERTIES_LENGTH; properties = factory->NewTaggedArray(capacity); } else { - properties = factory->CopyArray(JSHandle(thread, array), capacity, + auto arrayHandle = JSHandle(thread, array); + properties = factory->CopyArray(arrayHandle, capacity, JSObject::ComputePropertyCapacity(capacity)); } - properties->Set(thread, index, value); + properties->Set(thread, index, valueHandle); objHandle->SetProperties(thread, properties); return; } @@ -324,7 +307,7 @@ void ICRuntimeStub::StoreWithTransition(JSThread *thread, JSObject *receiver, JS StoreField(thread, receiver, value, handlerInfo); } -void ICRuntimeStub::StoreField(JSThread *thread, JSObject *receiver, JSTaggedValue value, uint32_t handler) +ARK_INLINE void ICRuntimeStub::StoreField(JSThread *thread, JSObject *receiver, JSTaggedValue value, uint32_t handler) { int index = HandlerBase::GetOffset(handler); if (HandlerBase::IsInlinedProps(handler)) { @@ -336,7 +319,7 @@ void ICRuntimeStub::StoreField(JSThread *thread, JSObject *receiver, JSTaggedVal array->Set(thread, index, value); } -JSTaggedValue ICRuntimeStub::LoadFromField(JSObject *receiver, uint32_t handlerInfo) +ARK_INLINE JSTaggedValue ICRuntimeStub::LoadFromField(JSObject *receiver, uint32_t handlerInfo) { int index = HandlerBase::GetOffset(handlerInfo); if (HandlerBase::IsInlinedProps(handlerInfo)) { @@ -345,7 +328,7 @@ JSTaggedValue ICRuntimeStub::LoadFromField(JSObject *receiver, uint32_t handlerI return TaggedArray::Cast(receiver->GetProperties().GetHeapObject())->Get(index); } -JSTaggedValue ICRuntimeStub::LoadGlobal(JSTaggedValue handler) +ARK_INLINE JSTaggedValue ICRuntimeStub::LoadGlobal(JSTaggedValue handler) { ASSERT(handler.IsPropertyBox()); PropertyBox *cell = PropertyBox::Cast(handler.GetHeapObject()); @@ -357,7 +340,7 @@ JSTaggedValue ICRuntimeStub::LoadGlobal(JSTaggedValue handler) return ret; } -JSTaggedValue ICRuntimeStub::StoreGlobal(JSThread *thread, JSTaggedValue value, JSTaggedValue handler) +ARK_INLINE JSTaggedValue ICRuntimeStub::StoreGlobal(JSThread *thread, JSTaggedValue value, JSTaggedValue handler) { ASSERT(handler.IsPropertyBox()); PropertyBox *cell = PropertyBox::Cast(handler.GetHeapObject()); @@ -384,8 +367,8 @@ JSTaggedValue ICRuntimeStub::LoadPrototype(JSThread *thread, JSTaggedValue recei return LoadICWithHandler(thread, receiver, holder, handlerInfo); } -JSTaggedValue ICRuntimeStub::LoadICWithHandler(JSThread *thread, JSTaggedValue receiver, JSTaggedValue holder, - JSTaggedValue handler) +ARK_INLINE JSTaggedValue ICRuntimeStub::LoadICWithHandler(JSThread *thread, JSTaggedValue receiver, + JSTaggedValue holder, JSTaggedValue handler) { if (LIKELY(handler.IsInt())) { auto handlerInfo = static_cast(handler.GetInt()); @@ -407,7 +390,7 @@ JSTaggedValue ICRuntimeStub::LoadICWithHandler(JSThread *thread, JSTaggedValue r return LoadGlobal(handler); } -JSTaggedValue ICRuntimeStub::LoadElement(JSObject *receiver, JSTaggedValue key) +ARK_INLINE JSTaggedValue ICRuntimeStub::LoadElement(JSObject *receiver, JSTaggedValue key) { auto index = TryToElementsIndex(key); if (index < 0) { @@ -420,7 +403,7 @@ JSTaggedValue ICRuntimeStub::LoadElement(JSObject *receiver, JSTaggedValue key) } JSTaggedValue value = elements->Get(elementIndex); - // TaggedArray + // TaggedArray elements return value; } @@ -448,16 +431,18 @@ JSTaggedValue ICRuntimeStub::StoreElement(JSThread *thread, JSObject *receiver, } [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle receiverHandle(thread, receiver); + JSHandle valueHandle(thread, value); elements = *JSObject::GrowElementsCapacity(thread, receiverHandle, JSObject::ComputeElementCapacity(elementIndex + 1)); - receiver->SetElements(thread, JSTaggedValue(elements)); + receiverHandle->SetElements(thread, JSTaggedValue(elements)); + elements->Set(thread, elementIndex, valueHandle); + return JSTaggedValue::Undefined(); } elements->Set(thread, elementIndex, value); - receiver->GetJSHClass()->UpdateRepresentation(value); return JSTaggedValue::Undefined(); } -int32_t ICRuntimeStub::TryToElementsIndex(JSTaggedValue key) +ARK_INLINE int32_t ICRuntimeStub::TryToElementsIndex(JSTaggedValue key) { if (LIKELY(key.IsInt())) { return key.GetInt(); @@ -482,4 +467,4 @@ int32_t ICRuntimeStub::TryToElementsIndex(JSTaggedValue key) } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_FAST_IC_RUNTIME_STUB_INL_H +#endif // ECMASCRIPT_IC_IC_RUNTIME_STUB_INL_H_ diff --git a/ecmascript/ic/fast_ic_runtime_stub.h b/ecmascript/ic/ic_runtime_stub.h similarity index 78% rename from ecmascript/ic/fast_ic_runtime_stub.h rename to ecmascript/ic/ic_runtime_stub.h index f61b84395c8ffdd0aaaf6fbbff631ab10ee1fa31..491cea8041ae86bf0b6a88487aa0f8d5184f76e1 100644 --- a/ecmascript/ic/fast_ic_runtime_stub.h +++ b/ecmascript/ic/ic_runtime_stub.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_FAST_IC_RUNTIME_STUB_H -#define PANDA_RUNTIME_ECMASCRIPT_FAST_IC_RUNTIME_STUB_H +#ifndef ECMASCRIPT_IC_IC_RUNTIME_STUB_H_ +#define ECMASCRIPT_IC_IC_RUNTIME_STUB_H_ #include "ecmascript/js_tagged_value.h" #include "ecmascript/property_attributes.h" @@ -29,6 +29,11 @@ public: JSTaggedValue value, uint32_t slotId); static inline JSTaggedValue LoadICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId); + static inline JSTaggedValue TryLoadICByName(JSThread *thread, JSTaggedValue receiver, + JSTaggedValue firstValue, JSTaggedValue secondValue); + static inline JSTaggedValue TryStoreICByName(JSThread *thread, JSTaggedValue receiver, + JSTaggedValue firstValue, JSTaggedValue secondValue, + JSTaggedValue value); static inline JSTaggedValue StoreICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, uint32_t slotId); @@ -47,8 +52,13 @@ public: static inline JSTaggedValue StoreGlobal(JSThread *thread, JSTaggedValue value, JSTaggedValue handler); static inline JSTaggedValue LoadPrototype(JSThread *thread, JSTaggedValue receiver, JSTaggedValue handler); + static inline JSTaggedValue TryLoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue firstValue, JSTaggedValue secondValue); static inline JSTaggedValue LoadICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId); + static inline JSTaggedValue TryStoreICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, + JSTaggedValue firstValue, JSTaggedValue secondValue, + JSTaggedValue value); static inline JSTaggedValue StoreICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value, uint32_t slotId); @@ -59,4 +69,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_FAST_IC_RUNTIME_STUB_H +#endif // ECMASCRIPT_IC_IC_RUNTIME_STUB_H_ diff --git a/ecmascript/ic/profile_type_info.h b/ecmascript/ic/profile_type_info.h index 3d98d0a2abfbb3dc0287161bb98f7f35caf802ef..3546a856b9ae971f8d7cbcc328c9535b0d3c6333 100644 --- a/ecmascript/ic/profile_type_info.h +++ b/ecmascript/ic/profile_type_info.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_PROFILE_TYPE_INFO_H -#define PANDA_RUNTIME_PROFILE_TYPE_INFO_H +#ifndef ECMASCRIPT_IC_PROFILE_TYPE_INFO_H +#define ECMASCRIPT_IC_PROFILE_TYPE_INFO_H #include "ecmascript/js_function.h" #include "ecmascript/tagged_array.h" @@ -141,4 +141,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_PROFILE_TYPE_INFO_H +#endif // ECMASCRIPT_IC_PROFILE_TYPE_INFO_H diff --git a/ecmascript/ic/properties_cache-inl.h b/ecmascript/ic/properties_cache-inl.h index d69a5355d71e2409b34b9ba2319619b17c4adc9d..9f8b62befac13f2bbbb59703b23ef726991ed369 100644 --- a/ecmascript/ic/properties_cache-inl.h +++ b/ecmascript/ic/properties_cache-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_PROPERTIES_CACHE_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_PROPERTIES_CACHE_INL_H +#ifndef ECMASCRIPT_IC_PROPERTIES_CACHE_INL_H +#define ECMASCRIPT_IC_PROPERTIES_CACHE_INL_H #include "ecmascript/ic/properties_cache.h" #include "ecmascript/js_tagged_value-inl.h" @@ -53,4 +53,4 @@ int PropertiesCache::Hash(JSHClass *cls, JSTaggedValue key) return static_cast((clsHash ^ keyHash) & CACHE_LENGTH_MASK); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_PROPERTIES_CACHE_INL_H +#endif // ECMASCRIPT_IC_PROPERTIES_CACHE_INL_H diff --git a/ecmascript/ic/properties_cache.h b/ecmascript/ic/properties_cache.h index e6ed518643cd83038b0067b57d304783afeedf7c..f99b06a1d1276823c22edbb19f590eb9a00516e2 100644 --- a/ecmascript/ic/properties_cache.h +++ b/ecmascript/ic/properties_cache.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_PROPERTIES_CACHE_H -#define PANDA_RUNTIME_ECMASCRIPT_PROPERTIES_CACHE_H +#ifndef ECMASCRIPT_IC_PROPERTIES_CACHE_H +#define ECMASCRIPT_IC_PROPERTIES_CACHE_H #include @@ -60,4 +60,4 @@ private: friend class EcmaVM; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_PROPERTIES_CACHE_H +#endif // ECMASCRIPT_IC_PROPERTIES_CACHE_H diff --git a/ecmascript/ic/property_box.h b/ecmascript/ic/property_box.h index 23e17f20148145b1740873a8e739d77ac99c3632..180834c1d8466a636eed5136f3555558bcdb44f7 100644 --- a/ecmascript/ic/property_box.h +++ b/ecmascript/ic/property_box.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_PROPERTY_BOX_H -#define PANDA_RUNTIME_PROPERTY_BOX_H +#ifndef ECMASCRIPT_IC_PROPERTY_BOX_H +#define ECMASCRIPT_IC_PROPERTY_BOX_H #include "ecmascript/ecma_macros.h" #include "ecmascript/js_hclass.h" @@ -38,7 +38,7 @@ public: return GetValue().IsHole(); } - static constexpr size_t VALUE_OFFSET = sizeof(TaggedObject); + static constexpr size_t VALUE_OFFSET = TaggedObjectSize(); ACCESSORS(Value, VALUE_OFFSET, SIZE); DECL_VISIT_OBJECT(VALUE_OFFSET, SIZE) diff --git a/ecmascript/ic/proto_change_details.h b/ecmascript/ic/proto_change_details.h index f4a60775275ab5d377cb9398580e8a742297a364..c212fd2ad530810ca4a8a0638e516c2afe2a08aa 100644 --- a/ecmascript/ic/proto_change_details.h +++ b/ecmascript/ic/proto_change_details.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_PROTOTYPE_CHANGE_DETAILS_H -#define PANDA_RUNTIME_PROTOTYPE_CHANGE_DETAILS_H +#ifndef ECMASCRIPT_IC_PROTOTYPE_CHANGE_DETAILS_H +#define ECMASCRIPT_IC_PROTOTYPE_CHANGE_DETAILS_H #include "ecmascript/ecma_macros.h" #include "ecmascript/js_handle.h" @@ -33,7 +33,7 @@ public: return static_cast(object); } - static constexpr size_t HAS_CHANGED_OFFSET = sizeof(TaggedObject); + static constexpr size_t HAS_CHANGED_OFFSET = TaggedObjectSize(); SET_GET_PRIMITIVE_FIELD(HasChanged, bool, HAS_CHANGED_OFFSET, SIZE); }; @@ -46,7 +46,7 @@ public: return static_cast(object); } - static constexpr size_t CHANGE_LISTENER_OFFSET = sizeof(TaggedObject); + static constexpr size_t CHANGE_LISTENER_OFFSET = TaggedObjectSize(); ACCESSORS(ChangeListener, CHANGE_LISTENER_OFFSET, REGISTER_INDEX_OFFSET); ACCESSORS(RegisterIndex, REGISTER_INDEX_OFFSET, SIZE); @@ -70,4 +70,4 @@ public: } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_PROTOTYPE_CHANGE_DETAILS_H +#endif // ECMASCRIPT_IC_PROTOTYPE_CHANGE_DETAILS_H diff --git a/ecmascript/internal_call_params.cpp b/ecmascript/internal_call_params.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0b1463f2296e105af95ccffed1a2b146fb30ccb2 --- /dev/null +++ b/ecmascript/internal_call_params.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "ecmascript/internal_call_params.h" + +namespace panda::ecmascript { +void InternalCallParams::MakeArgv(const EcmaRuntimeCallInfo *info, uint32_t position) +{ + int32_t mayLenth = info->GetArgsNumber() - position; + uint32_t length = mayLenth > 0 ? mayLenth : 0; + if (LIKELY(length <= InternalCallParams::RESERVE_INTERNAL_CALL_PARAMS_FIXED_LENGTH)) { + EnableFixedModeAndSetLength(length); + for (array_size_t index = 0; index < length; ++index) { + SetFixedBuffer(index, info->GetCallArg(index + position)); + } + return; + } + + EnableVariableModeAndSetLength(length); + for (array_size_t index = 0; index < length; ++index) { + SetVariableBuffer(index, info->GetCallArg(index + position)); + } +} + +void InternalCallParams::MakeArgListWithHole(const TaggedArray *argv, uint32_t length) +{ + ASSERT(length <= argv->GetLength()); + if (LIKELY(length <= InternalCallParams::RESERVE_INTERNAL_CALL_PARAMS_FIXED_LENGTH)) { + EnableFixedModeAndSetLength(length); + for (array_size_t index = 0; index < length; ++index) { + auto value = argv->Get(index); + SetFixedBuffer(index, value.IsHole() ? JSTaggedValue::Undefined() : value); + } + return; + } + + EnableVariableModeAndSetLength(length); + for (array_size_t index = 0; index < length; ++index) { + auto value = argv->Get(index); + SetVariableBuffer(index, value.IsHole() ? JSTaggedValue::Undefined() : value); + } +} + +void InternalCallParams::MakeArgList(const TaggedArray *argv) +{ + uint32_t length = argv->GetLength(); + if (LIKELY(length <= InternalCallParams::RESERVE_INTERNAL_CALL_PARAMS_FIXED_LENGTH)) { + EnableFixedModeAndSetLength(length); + for (array_size_t index = 0; index < length; ++index) { + SetFixedBuffer(index, argv->Get(index)); + } + return; + } + + EnableVariableModeAndSetLength(length); + for (array_size_t index = 0; index < length; ++index) { + SetVariableBuffer(index, argv->Get(index)); + } +} + +void InternalCallParams::MakeBoundArgv(const JSThread *thread, const JSHandle &boundFunc) +{ + JSHandle boundArgs(thread, boundFunc->GetBoundArguments()); + uint32_t boundLength = boundArgs->GetLength(); + uint32_t length = IsFixedMode() ? boundLength + GetFixedLength() + : boundLength + GetVariableLength(); + if (LIKELY(length <= InternalCallParams::RESERVE_INTERNAL_CALL_PARAMS_FIXED_LENGTH)) { + EnableFixedModeAndSetLength(length); + + // Prevent override, reverse write order + for (array_ssize_t index = length - 1; index >= static_cast(boundLength); --index) { + SetFixedBuffer(index, GetFixedBuffer(index - boundLength)); + } + + for (array_size_t index = 0; index < boundLength; ++index) { + SetFixedBuffer(index, boundArgs->Get(index)); + } + return; + } + + // need cross mode: fixed -> variable + if (IsFixedMode()) { + // enable variable mode not clear fixed buffer + EnableVariableModeAndSetLength(length); + for (array_size_t index = 0; index < boundLength; ++index) { + SetVariableBuffer(index, boundArgs->Get(index)); + } + + for (array_size_t index = boundLength; index < length; ++index) { + SetVariableBuffer(index, GetFixedBuffer(index - boundLength)); + } + return; + } + + EnableVariableModeAndSetLength(length); + for (array_ssize_t index = boundLength - 1; index >= 0; --index) { + InsertVariableBuffer(boundArgs->Get(index)); + } +} + +void InternalCallParams::Iterate(const RootRangeVisitor &v) const +{ + if (GetLength() == 0) { + return; + } + uintptr_t start = 0U; + uintptr_t end = 0U; + if (LIKELY(IsFixedMode())) { + JSTaggedType first = GetFixedBuffer(0); + start = ToUintPtr(&first); + JSTaggedType last = GetFixedBuffer(fixed_length_ - 1); + end = ToUintPtr(&last); + } else { + JSTaggedType first = GetVariableBuffer(0); + start = ToUintPtr(&first); + JSTaggedType last = GetVariableBuffer(variable_length_ - 1); + end = ToUintPtr(&last); + } + v(Root::ROOT_INTERNAL_CALL_PARAMS, ObjectSlot(start), ObjectSlot(end)); +} +} // namespace panda::ecmascript diff --git a/ecmascript/internal_call_params.h b/ecmascript/internal_call_params.h new file mode 100644 index 0000000000000000000000000000000000000000..2d979140379d99ad842f2f62e30d174fb754a342 --- /dev/null +++ b/ecmascript/internal_call_params.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_INTERNAL_CALL_PARAMS_H +#define ECMASCRIPT_INTERNAL_CALL_PARAMS_H + +#include "ecmascript/ecma_runtime_call_info.h" +#include "ecmascript/js_tagged_value.h" +#include "ecmascript/js_handle.h" +#include "ecmascript/js_function.h" +#include "ecmascript/mem/c_containers.h" + +namespace panda::ecmascript { +class InternalCallParams { +public: + static constexpr uint8_t RESERVE_INTERNAL_CALL_PARAMS_FIXED_LENGTH = 128; + + InternalCallParams() + { + } + + ~InternalCallParams() = default; + + inline const JSTaggedType *GetArgv() const + { + if (IsFixedMode()) { + return &fixed_data_.front(); + } + + ASSERT_PRINT(variable_length_ > RESERVE_INTERNAL_CALL_PARAMS_FIXED_LENGTH, "internal call params mode error"); + return variable_data_.data(); + } + + inline uint32_t GetLength() const + { + if (IsFixedMode()) { + return fixed_length_; + } + + ASSERT_PRINT(variable_length_ > RESERVE_INTERNAL_CALL_PARAMS_FIXED_LENGTH, "internal call params mode error"); + return variable_length_; + } + + template + inline void MakeArgv(const JSHandle &arg) + { + EnableFixedModeAndSetLength(1); + fixed_data_[0] = arg.GetTaggedType(); + } + + template + inline void MakeArgv(const JSHandle &arg0, const JSHandle &arg1) + { + EnableFixedModeAndSetLength(2); + fixed_data_[0] = arg0.GetTaggedType(); + fixed_data_[1] = arg1.GetTaggedType(); + } + + template + inline void MakeArgv(const JSHandle &arg0, const JSHandle &arg1, const JSHandle &arg2) + { + EnableFixedModeAndSetLength(3); + fixed_data_[0] = arg0.GetTaggedType(); + fixed_data_[1] = arg1.GetTaggedType(); + fixed_data_[2] = arg2.GetTaggedType(); + } + + template + inline void MakeArgv(const JSHandle &arg0, const JSHandle &arg1, const JSHandle &arg2, + const JSHandle &arg3) + { + EnableFixedModeAndSetLength(4); + fixed_data_[0] = arg0.GetTaggedType(); + fixed_data_[1] = arg1.GetTaggedType(); + fixed_data_[2] = arg2.GetTaggedType(); + fixed_data_[3] = arg3.GetTaggedType(); + } + + inline void MakeEmptyArgv() + { + EnableFixedModeAndSetLength(0); + } + + inline void MakeArgv(const JSTaggedValue arg) + { + EnableFixedModeAndSetLength(1); + fixed_data_[0] = arg.GetRawData(); + } + + inline void MakeArgv(const JSTaggedValue arg0, const JSTaggedValue arg1) + { + EnableFixedModeAndSetLength(2); + fixed_data_[0] = arg0.GetRawData(); + fixed_data_[1] = arg1.GetRawData(); + } + + inline void MakeArgv(const JSTaggedValue arg0, const JSTaggedValue arg1, const JSTaggedValue arg2) + { + EnableFixedModeAndSetLength(3); + fixed_data_[0] = arg0.GetRawData(); + fixed_data_[1] = arg1.GetRawData(); + fixed_data_[2] = arg2.GetRawData(); + } + + inline void MakeArgv(const JSTaggedValue arg0, const JSTaggedValue arg1, const JSTaggedValue arg2, + const JSTaggedValue arg3) + { + EnableFixedModeAndSetLength(4); + fixed_data_[0] = arg0.GetRawData(); + fixed_data_[1] = arg1.GetRawData(); + fixed_data_[2] = arg2.GetRawData(); + fixed_data_[3] = arg3.GetRawData(); + } + + void MakeArgv(const EcmaRuntimeCallInfo *info, uint32_t position); + + void MakeArgList(const TaggedArray *argv); + void MakeArgListWithHole(const TaggedArray *argv, uint32_t length); + + void MakeBoundArgv(const JSThread *thread, const JSHandle &boundFunc); + + void Iterate(const RootRangeVisitor &v) const; + +private: + DEFAULT_COPY_SEMANTIC(InternalCallParams); + DEFAULT_MOVE_SEMANTIC(InternalCallParams); + + inline bool IsFixedMode() const + { + return !variable_mode_; + } + + inline void EnableFixedModeAndSetLength(uint32_t length) + { + variable_mode_ = false; + variable_data_.clear(); + variable_length_ = 0; + fixed_length_ = length; + } + + inline uint32_t GetFixedLength() const + { + return fixed_length_; + } + + inline JSTaggedType GetFixedBuffer(uint32_t idx) const + { + return fixed_data_[idx]; + } + + inline void SetFixedBuffer(uint32_t idx, JSHandle val) + { + fixed_data_[idx] = val.GetTaggedType(); + } + + inline void SetFixedBuffer(uint32_t idx, JSTaggedValue val) + { + fixed_data_[idx] = val.GetRawData(); + } + + inline void SetFixedBuffer(uint32_t idx, JSTaggedType val) + { + fixed_data_[idx] = val; + } + + inline void EnableVariableModeAndSetLength(uint32_t length) + { + variable_mode_ = true; + fixed_length_ = 0; + variable_length_ = length; + variable_data_.resize(variable_length_); + } + + inline uint32_t GetVariableLength() const + { + return variable_length_; + } + + inline JSTaggedType GetVariableBuffer(uint32_t idx) const + { + return variable_data_[idx]; + } + + inline void SetVariableBuffer(uint32_t idx, JSHandle val) + { + variable_data_[idx] = val.GetTaggedType(); + } + + inline void SetVariableBuffer(uint32_t idx, JSTaggedValue val) + { + variable_data_[idx] = val.GetRawData(); + } + + inline void SetVariableBuffer(uint32_t idx, JSTaggedType val) + { + variable_data_[idx] = val; + } + + inline void InsertVariableBuffer(JSTaggedValue val) + { + variable_data_.insert(variable_data_.begin(), val.GetRawData()); + } + + std::array fixed_data_{}; + CVector variable_data_{}; + uint32_t fixed_length_{0}; + uint32_t variable_length_{0}; + bool variable_mode_{false}; +}; +} // namespace panda::ecmascript + +#endif // ECMASCRIPT_INTERNAL_CALL_PARAMS_H diff --git a/ecmascript/interpreter/fast_runtime_stub-inl.h b/ecmascript/interpreter/fast_runtime_stub-inl.h index 7b52ff74e4f7b4f2d136dc7bd809b98f259077ca..4e5cdfd5da24f9c29a10bea4059f88ab6f53655b 100644 --- a/ecmascript/interpreter/fast_runtime_stub-inl.h +++ b/ecmascript/interpreter/fast_runtime_stub-inl.h @@ -13,20 +13,23 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_FAST_RUNTIME_STUB_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_FAST_RUNTIME_STUB_INL_H +#ifndef ECMASCRIPT_INTERPRETER_FAST_RUNTIME_STUB_INL_H +#define ECMASCRIPT_INTERPRETER_FAST_RUNTIME_STUB_INL_H #include "ecmascript/interpreter/fast_runtime_stub.h" #include "ecmascript/global_dictionary-inl.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_function.h" #include "ecmascript/js_hclass-inl.h" #include "ecmascript/js_proxy.h" #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/js_typed_array.h" #include "ecmascript/object_factory-inl.h" +#include "ecmascript/runtime_call_id.h" #include "ecmascript/tagged_dictionary.h" +#include "ecmascript/vmstat/runtime_stat.h" namespace panda::ecmascript { JSTaggedValue FastRuntimeStub::FastAdd(JSTaggedValue left, JSTaggedValue right) @@ -106,7 +109,6 @@ JSTaggedValue FastRuntimeStub::FastEqual(JSTaggedValue left, JSTaggedValue right } if (left.IsNumber()) { if (left.IsInt() && right.IsInt()) { - // left != right return JSTaggedValue::False(); } } @@ -300,7 +302,7 @@ JSTaggedValue FastRuntimeStub::AddPropertyByIndex(JSThread *thread, JSTaggedValu return success ? JSTaggedValue::Undefined() : JSTaggedValue::Exception(); } -template +template JSTaggedValue FastRuntimeStub::GetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index) { [[maybe_unused]] EcmaHandleScope handleScope(thread); @@ -346,7 +348,7 @@ JSTaggedValue FastRuntimeStub::GetPropertyByIndex(JSThread *thread, JSTaggedValu return JSTaggedValue::Undefined(); } -template +template JSTaggedValue FastRuntimeStub::GetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key) { if (UNLIKELY(!key.IsNumber() && !key.IsStringOrSymbol())) { @@ -371,9 +373,10 @@ JSTaggedValue FastRuntimeStub::GetPropertyByValue(JSThread *thread, JSTaggedValu return JSTaggedValue::Hole(); } -template +template JSTaggedValue FastRuntimeStub::GetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key) { + INTERPRETER_TRACE(thread, GetPropertyByName); // no gc when return hole ASSERT(key.IsStringOrSymbol()); JSTaggedValue holder = receiver; @@ -425,7 +428,7 @@ JSTaggedValue FastRuntimeStub::GetPropertyByName(JSThread *thread, JSTaggedValue return JSTaggedValue::Undefined(); } -template +template JSTaggedValue FastRuntimeStub::SetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value) { @@ -497,7 +500,7 @@ JSTaggedValue FastRuntimeStub::SetPropertyByName(JSThread *thread, JSTaggedValue return AddPropertyByName(thread, receiver, key, value); } -template +template JSTaggedValue FastRuntimeStub::SetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index, JSTaggedValue value) { @@ -532,7 +535,7 @@ JSTaggedValue FastRuntimeStub::SetPropertyByIndex(JSThread *thread, JSTaggedValu return AddPropertyByIndex(thread, receiver, index, value); } -template +template JSTaggedValue FastRuntimeStub::SetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value) { @@ -660,7 +663,7 @@ JSTaggedValue FastRuntimeStub::FastGetPropertyByValue(JSThread *thread, JSTagged return result; } -template // UseHole is only for Array::Sort() which requires Hole order +template // UseHole is only for Array::Sort() which requires Hole order JSTaggedValue FastRuntimeStub::FastGetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index) { JSTaggedValue result = GetPropertyByIndex(thread, receiver, index); @@ -977,11 +980,10 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei } JSHandle objHandle(thread, receiver); - JSHandle valueHandle(thread, value); JSHandle setFunc(thread, setter); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(1); - args->Set(thread, 0, valueHandle); - JSFunction::Call(thread, setFunc, objHandle, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(value); + JSFunction::Call(thread, setFunc, objHandle, 1, arguments->GetArgv()); // 10. ReturnIfAbrupt(setterResult). RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); return true; @@ -1261,4 +1263,4 @@ JSTaggedValue FastRuntimeStub::HasOwnProperty(JSThread *thread, JSObject *obj, J return FastRuntimeStub::FindOwnProperty(thread, obj, key); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_FAST_RUNTIME_STUB_INL_H +#endif // ECMASCRIPT_INTERPRETER_FAST_RUNTIME_STUB_INL_H diff --git a/ecmascript/interpreter/fast_runtime_stub.h b/ecmascript/interpreter/fast_runtime_stub.h index e18362b9aa3b17d7652a0117a6512fbaedccd826..271ac0f0f9faeee58ad752d7f5c8bc7ce8feabfd 100644 --- a/ecmascript/interpreter/fast_runtime_stub.h +++ b/ecmascript/interpreter/fast_runtime_stub.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_FAST_RUNTIME_STUB_H -#define PANDA_RUNTIME_ECMASCRIPT_FAST_RUNTIME_STUB_H +#ifndef ECMASCRIPT_INTERPRETER_FAST_RUNTIME_STUB_H +#define ECMASCRIPT_INTERPRETER_FAST_RUNTIME_STUB_H #include "ecmascript/js_tagged_value.h" @@ -67,19 +67,19 @@ public: /* -------------- Special API For Multi-Language VM End ----------------- */ /* -------------- Common API End, Don't change those interface!!! ----------------- */ - template + template static inline JSTaggedValue GetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key); - template + template static inline JSTaggedValue GetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key); - template + template static inline JSTaggedValue GetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index); - template + template static inline JSTaggedValue SetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value); - template + template static inline JSTaggedValue SetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key, JSTaggedValue value); - template + template static inline JSTaggedValue SetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index, JSTaggedValue value); @@ -89,7 +89,7 @@ public: JSTaggedValue value); static inline JSTaggedValue FastGetPropertyByName(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key); static inline JSTaggedValue FastGetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key); - template + template static inline JSTaggedValue FastGetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index); private: @@ -110,4 +110,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_OBJECT_OPERATOR_INL_H +#endif // ECMASCRIPT_INTERPRETER_OBJECT_OPERATOR_INL_H diff --git a/ecmascript/interpreter/frame_handler.cpp b/ecmascript/interpreter/frame_handler.cpp index 9c2e68d55e3094c9fe9427db513a9c07dcb22690..e321181c29b25910e4fcaec2e4a55f7475ca0b53 100644 --- a/ecmascript/interpreter/frame_handler.cpp +++ b/ecmascript/interpreter/frame_handler.cpp @@ -13,7 +13,8 @@ * limitations under the License. */ -#include "frame_handler.h" +#include "ecmascript/interpreter/frame_handler.h" + #include "ecmascript/interpreter/interpreter.h" #include "ecmascript/js_thread.h" #include "libpandafile/bytecode_instruction-inl.h" @@ -21,7 +22,7 @@ namespace panda::ecmascript { EcmaFrameHandler::EcmaFrameHandler(const JSThread *thread) { - sp_ = thread->GetCurrentSPFrame(); + sp_ = const_cast(thread->GetCurrentSPFrame()); } bool EcmaFrameHandler::HasFrame() const @@ -183,7 +184,7 @@ void EcmaFrameHandler::DumpStack(std::ostream &os) const EcmaFrameHandler frameHandler(sp_); for (; frameHandler.HasFrame(); frameHandler.PrevFrame()) { os << "[" << i++ - << "]:" << frameHandler.GetMethod()->GetStringDataAnnotation(Method::AnnotationField::FUNCTION_NAME).data + << "]:" << frameHandler.GetMethod()->ParseFunctionName() << "\n"; } } diff --git a/ecmascript/interpreter/frame_handler.h b/ecmascript/interpreter/frame_handler.h index bea45197e3ba9fe6d4e71c1eba608d56346577f2..ad82f3723649049c2155188d8baf6354f9aeff11 100644 --- a/ecmascript/interpreter/frame_handler.h +++ b/ecmascript/interpreter/frame_handler.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_FRAME_HANDLER_H -#define PANDA_RUNTIME_ECMASCRIPT_FRAME_HANDLER_H +#ifndef ECMASCRIPT_INTERPRETER_FRAME_HANDLER_H +#define ECMASCRIPT_INTERPRETER_FRAME_HANDLER_H #include "ecmascript/js_method.h" #include "ecmascript/js_tagged_value.h" @@ -70,4 +70,4 @@ private: }; } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_FRAME_HANDLER_H +#endif // ECMASCRIPT_INTERPRETER_FRAME_HANDLER_H diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index aec2acf5d2cd51be1408b73960b7292390de83b9..e0200af99896c07bd0241fa827e58966764f943e 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -13,14 +13,14 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_INTERPRETER_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_INTERPRETER_INL_H +#ifndef ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H +#define ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H #include "ecmascript/class_linker/program_object-inl.h" #include "ecmascript/ecma_string.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" -#include "ecmascript/ic/fast_ic_runtime_stub-inl.h" +#include "ecmascript/ic/ic_runtime_stub-inl.h" #include "ecmascript/interpreter/fast_runtime_stub-inl.h" #include "ecmascript/interpreter/interpreter.h" #include "ecmascript/interpreter/slow_runtime_stub.h" @@ -125,61 +125,73 @@ namespace panda::ecmascript { RESTORE_ACC(); \ } while (false) -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define UPDATE_HOTNESS_COUNTER(thread, sp, offset) (UpdateHotnessCounter(thread, sp, offset)) +#define UPDATE_HOTNESS_COUNTER_NON_ACC(offset) (UpdateHotnessCounter(thread, sp, acc, offset)) + +#define UPDATE_HOTNESS_COUNTER(offset) \ + do { \ + if (UpdateHotnessCounter(thread, sp, acc, offset)) { \ + RESTORE_ACC(); \ + } \ + } while (false) #else // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define UPDATE_HOTNESS_COUNTER(thread, sp, offset) static_cast(0) +#define UPDATE_HOTNESS_COUNTER(offset) static_cast(0) +#define UPDATE_HOTNESS_COUNTER_NON_ACC(offset) static_cast(0) #endif -#define READ_INST_OP() READ_INST_8(0); -#define READ_INST_4_0(inst_) (READ_INST_8(1) & 0xf) -#define READ_INST_4_1(inst_) ((READ_INST_8(1) >> 4) & 0xf) -#define READ_INST_8_0(inst_) (READ_INST_8(1) & 0xff) -#define READ_INST_8_1(inst_) (READ_INST_8(2) & 0xff) -#define READ_INST_8_2(inst_) (READ_INST_8(3) & 0xff) -#define READ_INST_8_3(inst_) (READ_INST_8(4) & 0xff) -#define READ_INST_8_4(inst_) (READ_INST_8(5) & 0xff) -#define READ_INST_8_5(inst_) (READ_INST_8(6) & 0xff) -#define READ_INST_8_6(inst_) (READ_INST_8(7) & 0xff) -#define READ_INST_8(offset) (*(pc + (offset))) +#define READ_INST_OP() READ_INST_8(0) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_4_0() (READ_INST_8(1) & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_4_1() (READ_INST_8(1) >> 4 & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_4_2() (READ_INST_8(2) & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_4_3() (READ_INST_8(2) >> 4 & 0xf) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_8_0() READ_INST_8(1) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_8_1() READ_INST_8(2) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_8_2() READ_INST_8(3) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_8_3() READ_INST_8(4) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_8_4() READ_INST_8(5) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_8_5() READ_INST_8(6) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_8_6() READ_INST_8(7) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_8_7() READ_INST_8(8) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_8_8() READ_INST_8(9) // NOLINT(hicpp-signed-bitwise, cppcoreguidelines-macro-usage) +#define READ_INST_8(offset) (*(pc + offset)) #define MOVE_AND_READ_INST_8(currentInst, offset) \ - (currentInst) <<= 8; \ - (currentInst) += READ_INST_8(offset); + currentInst <<= 8; \ + currentInst += READ_INST_8(offset); \ #define READ_INST_16_0() READ_INST_16(2) #define READ_INST_16_1() READ_INST_16(3) #define READ_INST_16_2() READ_INST_16(4) #define READ_INST_16_3() READ_INST_16(5) -#define READ_INST_16_4() READ_INST_16(6) #define READ_INST_16_5() READ_INST_16(7) -#define READ_INST_16(offset) \ - ({ \ - uint16_t currentInst = READ_INST_8(offset); \ - MOVE_AND_READ_INST_8(currentInst, offset - 1); \ +#define READ_INST_16(offset) \ + ({ \ + uint16_t currentInst = READ_INST_8(offset); \ + MOVE_AND_READ_INST_8(currentInst, offset - 1) \ }) #define READ_INST_32_0() READ_INST_32(4) #define READ_INST_32_1() READ_INST_32(5) -#define READ_INST_32(offset) \ - ({ \ - uint32_t currentInst = READ_INST_8(offset); \ - MOVE_AND_READ_INST_8(currentInst, offset - 1); \ - MOVE_AND_READ_INST_8(currentInst, offset - 2); \ - MOVE_AND_READ_INST_8(currentInst, offset - 3); \ +#define READ_INST_32_2() READ_INST_32(6) +#define READ_INST_32(offset) \ + ({ \ + uint32_t currentInst = READ_INST_8(offset); \ + MOVE_AND_READ_INST_8(currentInst, offset - 1) \ + MOVE_AND_READ_INST_8(currentInst, offset - 2) \ + MOVE_AND_READ_INST_8(currentInst, offset - 3) \ }) #define READ_INST_64_0() \ ({ \ uint64_t currentInst = READ_INST_8(8); \ - MOVE_AND_READ_INST_8(currentInst, 7); \ - MOVE_AND_READ_INST_8(currentInst, 6); \ - MOVE_AND_READ_INST_8(currentInst, 5); \ - MOVE_AND_READ_INST_8(currentInst, 4); \ - MOVE_AND_READ_INST_8(currentInst, 3); \ - MOVE_AND_READ_INST_8(currentInst, 2); \ - MOVE_AND_READ_INST_8(currentInst, 1); \ + MOVE_AND_READ_INST_8(currentInst, 7) \ + MOVE_AND_READ_INST_8(currentInst, 6) \ + MOVE_AND_READ_INST_8(currentInst, 5) \ + MOVE_AND_READ_INST_8(currentInst, 4) \ + MOVE_AND_READ_INST_8(currentInst, 3) \ + MOVE_AND_READ_INST_8(currentInst, 2) \ + MOVE_AND_READ_INST_8(currentInst, 1) \ }) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -193,7 +205,7 @@ namespace panda::ecmascript { JSTaggedValue EcmaInterpreter::ExecuteNative(JSThread *thread, const CallParams& params) { - JSTaggedType *sp = thread->GetCurrentSPFrame(); + JSTaggedType *sp = const_cast(thread->GetCurrentSPFrame()); JSMethod *methodToCall = params.callTarget->GetCallTarget(); ASSERT(methodToCall->GetNumVregs() == 0); uint32_t numActualArgs = params.argc + RESERVED_CALL_ARGCOUNT; @@ -236,7 +248,7 @@ JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& param return EcmaInterpreter::ExecuteNative(thread, params); } - JSTaggedType *originalPrevSp = thread->GetCurrentSPFrame(); + JSTaggedType *originalPrevSp = const_cast(thread->GetCurrentSPFrame()); // push break state // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -313,7 +325,7 @@ JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSH JSHandle func = JSHandle::Cast(JSHandle(thread, context->GetMethod())); JSMethod *method = func->GetCallTarget(); - JSTaggedType *currentSp = thread->GetCurrentSPFrame(); + JSTaggedType *currentSp = const_cast(thread->GetCurrentSPFrame()); // push break frame // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -344,7 +356,7 @@ JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSH // pc = first_inst + offset + size(Opcode::SUSPENDGENERATOR_IMM8_V8_V8) // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) const uint8_t *resumePc = JSMethod::Cast(method)->GetBytecodeArray() + static_cast(pcOffset.GetInt()) + - BytecodeInstruction::Size(BytecodeInstruction::Format::IMM8_V8_V8); + BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8); FrameState *state = GET_FRAME(newSp); state->pc = resumePc; @@ -374,7 +386,7 @@ void EcmaInterpreter::ChangeGenContext(JSThread *thread, JSHandle func = JSHandle::Cast(JSHandle(thread, context->GetMethod())); JSMethod *method = func->GetCallTarget(); - JSTaggedType *currentSp = thread->GetCurrentSPFrame(); + JSTaggedType *currentSp = const_cast(thread->GetCurrentSPFrame()); // push break frame // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -422,7 +434,7 @@ void EcmaInterpreter::ChangeGenContext(JSThread *thread, JSHandleGetCurrentSPFrame(); + JSTaggedType *sp = const_cast(thread->GetCurrentSPFrame()); FrameState *state = GET_FRAME(sp); thread->SetCurrentSPFrame(state->prev); } @@ -501,41 +513,41 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } HANDLE_OPCODE(HANDLE_JMP_IMM8) { int8_t offset = READ_INST_8_0(); - UPDATE_HOTNESS_COUNTER(thread, sp, offset); + UPDATE_HOTNESS_COUNTER(offset); LOG_INST() << "jmp " << std::hex << static_cast(offset); DISPATCH_OFFSET(offset); } HANDLE_OPCODE(HANDLE_JMP_IMM16) { int16_t offset = READ_INST_16_0(); - UPDATE_HOTNESS_COUNTER(thread, sp, offset); + UPDATE_HOTNESS_COUNTER(offset); LOG_INST() << "jmp " << std::hex << static_cast(offset); DISPATCH_OFFSET(offset); } HANDLE_OPCODE(HANDLE_JMP_IMM32) { int32_t offset = READ_INST_32_0(); - UPDATE_HOTNESS_COUNTER(thread, sp, offset); + UPDATE_HOTNESS_COUNTER(offset); LOG_INST() << "jmp " << std::hex << offset; DISPATCH_OFFSET(offset); } HANDLE_OPCODE(HANDLE_JEQZ_IMM8) { int8_t offset = READ_INST_8_0(); - UPDATE_HOTNESS_COUNTER(thread, sp, offset); LOG_INST() << "jeqz ->\t" << "cond jmpz " << std::hex << static_cast(offset); if (GET_ACC() == JSTaggedValue::False() || (GET_ACC().IsInt() && GET_ACC().GetInt() == 0) || (GET_ACC().IsDouble() && GET_ACC().GetDouble() == 0)) { + UPDATE_HOTNESS_COUNTER(offset); DISPATCH_OFFSET(offset); } else { - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } } HANDLE_OPCODE(HANDLE_JEQZ_IMM16) { int16_t offset = READ_INST_16_0(); - UPDATE_HOTNESS_COUNTER(thread, sp, offset); LOG_INST() << "jeqz ->\t" << "cond jmpz " << std::hex << static_cast(offset); if (GET_ACC() == JSTaggedValue::False() || (GET_ACC().IsInt() && GET_ACC().GetInt() == 0) || (GET_ACC().IsDouble() && GET_ACC().GetDouble() == 0)) { + UPDATE_HOTNESS_COUNTER(offset); DISPATCH_OFFSET(offset); } else { DISPATCH(BytecodeInstruction::Format::IMM16); @@ -547,9 +559,10 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool << "cond jmpz " << std::hex << static_cast(offset); if (GET_ACC() == JSTaggedValue::True() || (GET_ACC().IsInt() && GET_ACC().GetInt() != 0) || (GET_ACC().IsDouble() && GET_ACC().GetDouble() != 0)) { + UPDATE_HOTNESS_COUNTER(offset); DISPATCH_OFFSET(offset); } else { - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } } HANDLE_OPCODE(HANDLE_JNEZ_IMM16) { @@ -558,6 +571,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool << "cond jmpz " << std::hex << static_cast(offset); if (GET_ACC() == JSTaggedValue::True() || (GET_ACC().IsInt() && GET_ACC().GetInt() != 0) || (GET_ACC().IsDouble() && GET_ACC().GetDouble() != 0)) { + UPDATE_HOTNESS_COUNTER(offset); DISPATCH_OFFSET(offset); } else { DISPATCH(BytecodeInstruction::Format::IMM16); @@ -595,7 +609,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool bool callThis; bool callRange; - HANDLE_OPCODE(HANDLE_BUILTIN_CALLARG0DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_CALLARG0DYN_PREF_V8) { funcReg = READ_INST_8_1(); actualNumArgs = ActualNumArgsOfCall::CALLARG0; @@ -606,7 +620,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto, hicpp-avoid-goto) goto handlerCall; } - HANDLE_OPCODE(HANDLE_BUILTIN_CALLARG1DYN_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_CALLARG1DYN_PREF_V8_V8) { funcReg = READ_INST_8_1(); actualNumArgs = ActualNumArgsOfCall::CALLARG1; @@ -617,7 +631,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto, hicpp-avoid-goto) goto handlerCall; } - HANDLE_OPCODE(HANDLE_BUILTIN_CALLARGS2DYN_IMM8_V8_V8_V8) { + HANDLE_OPCODE(HANDLE_CALLARGS2DYN_PREF_V8_V8_V8) { funcReg = READ_INST_8_1(); actualNumArgs = ActualNumArgsOfCall::CALLARGS2; @@ -628,7 +642,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto, hicpp-avoid-goto) goto handlerCall; } - HANDLE_OPCODE(HANDLE_BUILTIN_CALLARGS3DYN_IMM8_V8_V8_V8_V8) { + HANDLE_OPCODE(HANDLE_CALLARGS3DYN_PREF_V8_V8_V8_V8) { funcReg = READ_INST_8_1(); actualNumArgs = ActualNumArgsOfCall::CALLARGS3; @@ -640,7 +654,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto, hicpp-avoid-goto) goto handlerCall; } - HANDLE_OPCODE(HANDLE_BUILTIN_CALLITHISRANGEDYN_IMM8_IMM16_V8) { + HANDLE_OPCODE(HANDLE_CALLITHISRANGEDYN_PREF_IMM16_V8) { actualNumArgs = READ_INST_16_1() + 2; // 2: func and newTarget funcReg = READ_INST_8_3(); @@ -650,7 +664,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto, hicpp-avoid-goto) goto handlerCall; } - HANDLE_OPCODE(HANDLE_BUILTIN_CALLSPREADDYN_IMM8_V8_V8_V8) { + HANDLE_OPCODE(HANDLE_CALLSPREADDYN_PREF_V8_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); uint16_t v2 = READ_INST_8_3(); @@ -664,9 +678,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_CALLIRANGEDYN_IMM8_IMM16_V8) { + HANDLE_OPCODE(HANDLE_CALLIRANGEDYN_PREF_IMM16_V8) { actualNumArgs = READ_INST_16_1() + NUM_MANDATORY_JSFUNC_ARGS; funcReg = READ_INST_8_3(); callRange = true; @@ -856,7 +870,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast(state->sp) << " " << std::hex << reinterpret_cast(state->pc); [[maybe_unused]] auto fistPC = state->method->GetInstructions(); - UPDATE_HOTNESS_COUNTER(thread, sp, -(pc - fistPC)); + UPDATE_HOTNESS_COUNTER(-(pc - fistPC)); sp = state->prev; ASSERT(sp != nullptr); FrameState *prevState = GET_FRAME(sp); @@ -874,13 +888,13 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool size_t jumpSize = GetJumpSizeAfterCall(pc); DISPATCH_OFFSET(jumpSize); } - HANDLE_OPCODE(HANDLE_BUILTIN_RETURNUNDEFINED_IMM8) { + HANDLE_OPCODE(HANDLE_RETURNUNDEFINED_PREF) { LOG_INST() << "return.undefined"; FrameState *state = GET_FRAME(sp); LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast(sp) << " " << std::hex << reinterpret_cast(state->pc); [[maybe_unused]] auto fistPC = state->method->GetInstructions(); - UPDATE_HOTNESS_COUNTER(thread, sp, -(pc - fistPC)); + UPDATE_HOTNESS_COUNTER_NON_ACC(-(pc - fistPC)); sp = state->prev; ASSERT(sp != nullptr); FrameState *prevState = GET_FRAME(sp); @@ -899,59 +913,59 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool size_t jumpSize = GetJumpSizeAfterCall(pc); DISPATCH_OFFSET(jumpSize); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDNAN_IMM8) { + HANDLE_OPCODE(HANDLE_LDNAN_PREF) { LOG_INST() << "intrinsics::ldnan"; SET_ACC(JSTaggedValue(base::NAN_VALUE)); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDINFINITY_IMM8) { + HANDLE_OPCODE(HANDLE_LDINFINITY_PREF) { LOG_INST() << "intrinsics::ldinfinity"; SET_ACC(JSTaggedValue(base::POSITIVE_INFINITY)); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDGLOBALTHIS_IMM8) { + HANDLE_OPCODE(HANDLE_LDGLOBALTHIS_PREF) { LOG_INST() << "intrinsics::ldglobalthis"; SET_ACC(globalObj) - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDUNDEFINED_IMM8) { + HANDLE_OPCODE(HANDLE_LDUNDEFINED_PREF) { LOG_INST() << "intrinsics::ldundefined"; SET_ACC(JSTaggedValue::Undefined()) - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDNULL_IMM8) { + HANDLE_OPCODE(HANDLE_LDNULL_PREF) { LOG_INST() << "intrinsics::ldnull"; SET_ACC(JSTaggedValue::Null()) - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDSYMBOL_IMM8) { + HANDLE_OPCODE(HANDLE_LDSYMBOL_PREF) { LOG_INST() << "intrinsics::ldsymbol"; SET_ACC(globalEnv->GetSymbolFunction().GetTaggedValue()); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDGLOBAL_IMM8) { + HANDLE_OPCODE(HANDLE_LDGLOBAL_PREF) { LOG_INST() << "intrinsics::ldglobal"; SET_ACC(globalObj) - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDTRUE_IMM8) { + HANDLE_OPCODE(HANDLE_LDTRUE_PREF) { LOG_INST() << "intrinsics::ldtrue"; SET_ACC(JSTaggedValue::True()) - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDFALSE_IMM8) { + HANDLE_OPCODE(HANDLE_LDFALSE_PREF) { LOG_INST() << "intrinsics::ldfalse"; SET_ACC(JSTaggedValue::False()) - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDLEXENVDYN_IMM8) { + HANDLE_OPCODE(HANDLE_LDLEXENVDYN_PREF) { LOG_INST() << "intrinsics::ldlexenvDyn "; FrameState *state = GET_FRAME(sp); JSTaggedValue currentLexenv = state->env; SET_ACC(currentLexenv); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_GETUNMAPPEDARGS_IMM8) { + HANDLE_OPCODE(HANDLE_GETUNMAPPEDARGS_PREF) { LOG_INST() << "intrinsics::getunmappedargs"; FrameState *state = GET_FRAME(sp); @@ -963,36 +977,16 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::GetUnmapedArgs(thread, sp, actualNumArgs, startIdx); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_ASYNCFUNCTIONENTER_IMM8) { + HANDLE_OPCODE(HANDLE_ASYNCFUNCTIONENTER_PREF) { LOG_INST() << "intrinsics::asyncfunctionenter"; JSTaggedValue res = SlowRuntimeStub::AsyncFunctionEnter(thread); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_LDBOOLEAN_IMM8_V8) { - // it38 Unimplement - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_LDNUMBER_IMM8_V8) { - // it38 Unimplement - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_LDSTRING_IMM8_V8) { - // it38 Unimplement - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_LDBIGINT_IMM8_V8) { - // it38 Unimplement - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_TONUMBER_IMM8_V8) { + HANDLE_OPCODE(HANDLE_TONUMBER_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::tonumber" @@ -1007,9 +1001,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_NEGDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_NEGDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::negdyn" << " v" << v0; @@ -1028,9 +1022,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_NOTDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_NOTDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::notdyn" @@ -1050,9 +1044,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_INCDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_INCDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::incdyn" @@ -1076,9 +1070,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_DECDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_DECDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::decdyn" << " v" << v0; @@ -1101,47 +1095,41 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_THROWDYN_IMM8) { + HANDLE_OPCODE(HANDLE_THROWDYN_PREF) { LOG_INST() << "intrinsics::throwdyn"; SlowRuntimeStub::ThrowDyn(thread, GET_ACC()); INTERPRETER_GOTO_EXCEPTION_HANDLER(); } - HANDLE_OPCODE(HANDLE_BUILTIN_TYPEOFDYN_IMM8) { + HANDLE_OPCODE(HANDLE_TYPEOFDYN_PREF) { LOG_INST() << "intrinsics::typeofdyn"; JSTaggedValue res = FastRuntimeStub::FastTypeOf(thread, GET_ACC()); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_TOBOOLEAN_IMM8) { - LOG_INST() << "intrinsics::toboolean"; - JSTaggedValue left = acc; - SET_ACC(left.ToBoolean() ? JSTaggedValue::True() : JSTaggedValue::False()) - DISPATCH(BytecodeInstruction::Format::IMM8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_GETPROPITERATOR_IMM8) { + HANDLE_OPCODE(HANDLE_GETPROPITERATOR_PREF) { LOG_INST() << "intrinsics::getpropiterator"; JSTaggedValue res = SlowRuntimeStub::GetPropIterator(thread, GET_ACC()); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_RESUMEGENERATOR_IMM8_V8) { + HANDLE_OPCODE(HANDLE_RESUMEGENERATOR_PREF_V8) { LOG_INST() << "intrinsics::resumegenerator"; uint16_t vs = READ_INST_8_1(); JSGeneratorObject *obj = JSGeneratorObject::Cast(GET_VREG_VALUE(vs).GetTaggedObject()); SET_ACC(obj->GetResumeResult()); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_GETRESUMEMODE_IMM8_V8) { + HANDLE_OPCODE(HANDLE_GETRESUMEMODE_PREF_V8) { LOG_INST() << "intrinsics::getresumemode"; uint16_t vs = READ_INST_8_1(); JSGeneratorObject *obj = JSGeneratorObject::Cast(GET_VREG_VALUE(vs).GetTaggedObject()); SET_ACC(obj->GetResumeMode()); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_GETITERATOR_IMM8) { + HANDLE_OPCODE(HANDLE_GETITERATOR_PREF) { LOG_INST() << "intrinsics::getiterator"; JSTaggedValue obj = GET_ACC(); @@ -1152,48 +1140,42 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_THROWUNDEFINED_IMM8_V8) { - // the instrunction has beed retired - LOG_INST() << "-------------"; - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_THROWCONSTASSIGNMENT_IMM8_V8) { + HANDLE_OPCODE(HANDLE_THROWCONSTASSIGNMENT_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "throwconstassignment" << " v" << v0; SlowRuntimeStub::ThrowConstAssignment(thread, GET_VREG_VALUE(v0)); INTERPRETER_GOTO_EXCEPTION_HANDLER(); } - HANDLE_OPCODE(HANDLE_BUILTIN_THROWTHROWNOTEXISTS_IMM8) { + HANDLE_OPCODE(HANDLE_THROWTHROWNOTEXISTS_PREF) { LOG_INST() << "throwthrownotexists"; SlowRuntimeStub::ThrowThrowNotExists(thread); INTERPRETER_GOTO_EXCEPTION_HANDLER(); } - HANDLE_OPCODE(HANDLE_BUILTIN_THROWPATTERNNONCOERCIBLE_IMM8) { + HANDLE_OPCODE(HANDLE_THROWPATTERNNONCOERCIBLE_PREF) { LOG_INST() << "throwpatternnoncoercible"; SlowRuntimeStub::ThrowPatternNonCoercible(thread); INTERPRETER_GOTO_EXCEPTION_HANDLER(); } - HANDLE_OPCODE(HANDLE_BUILTIN_THROWIFNOTOBJECT_IMM8_V8) { + HANDLE_OPCODE(HANDLE_THROWIFNOTOBJECT_PREF_V8) { LOG_INST() << "throwifnotobject"; uint16_t v0 = READ_INST_8_1(); JSTaggedValue value = GET_VREG_VALUE(v0); // fast path if (value.IsECMAObject()) { - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } // slow path SlowRuntimeStub::ThrowIfNotObject(thread); INTERPRETER_GOTO_EXCEPTION_HANDLER(); } - HANDLE_OPCODE(HANDLE_BUILTIN_ITERNEXT_IMM8_V8) { + HANDLE_OPCODE(HANDLE_ITERNEXT_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::iternext" << " v" << v0; @@ -1201,9 +1183,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::IterNext(thread, iter); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_CLOSEITERATOR_IMM8_V8) { + HANDLE_OPCODE(HANDLE_CLOSEITERATOR_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::closeiterator" << " v" << v0; @@ -1211,21 +1193,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::CloseIterator(thread, iter); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_LDOBJECT_IMM8_V8_V8) { - // it38 Unimplement - LOG_INST() << "-------------"; - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDFUNCTION_IMM8_V8_V8) { - // it38 Unimplement - LOG_INST() << "-------------"; - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_ADD2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_ADD2DYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::add2dyn" << " v" << v0; @@ -1254,9 +1224,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_SUB2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_SUB2DYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::sub2dyn" << " v" << v0; @@ -1284,9 +1254,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_MUL2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_MUL2DYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::mul2dyn" << " v" << v0; @@ -1301,9 +1271,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_DIV2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_DIV2DYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::div2dyn" << " v" << v0; @@ -1319,9 +1289,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(slowRes); SET_ACC(slowRes); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_MOD2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_MOD2DYN_PREF_V8) { uint16_t vs = READ_INST_8_1(); LOG_INST() << "intrinsics::mod2dyn" << " v" << vs; @@ -1337,9 +1307,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(slowRes); SET_ACC(slowRes); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_EQDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_EQDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::eqdyn" @@ -1356,9 +1326,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_NOTEQDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_NOTEQDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::noteqdyn" @@ -1376,9 +1346,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_LESSDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_LESSDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::lessdyn" @@ -1397,9 +1367,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_LESSEQDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_LESSEQDYN_PREF_V8) { uint16_t vs = READ_INST_8_1(); LOG_INST() << "intrinsics::lesseqdyn " << " v" << vs; @@ -1417,9 +1387,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_GREATERDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_GREATERDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::greaterdyn" @@ -1438,9 +1408,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_GREATEREQDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_GREATEREQDYN_PREF_V8) { uint16_t vs = READ_INST_8_1(); LOG_INST() << "intrinsics::greateqdyn " << " v" << vs; @@ -1459,9 +1429,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_SHL2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_SHL2DYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::shl2dyn" @@ -1498,9 +1468,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool auto ret = static_cast(static_cast(opNumber0) << shift); // NOLINT(hicpp-signed-bitwise) SET_ACC(JSTaggedValue(ret)) - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_SHR2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_SHR2DYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::shr2dyn" @@ -1535,9 +1505,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool static_cast(opNumber1) & 0x1f; // NOLINT(hicpp-signed-bitwise, readability-magic-numbers) auto ret = static_cast(opNumber0 >> shift); // NOLINT(hicpp-signed-bitwise) SET_ACC(JSTaggedValue(ret)) - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_ASHR2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_ASHR2DYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::ashr2dyn" @@ -1574,9 +1544,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool static_cast(static_cast(opNumber0) >> shift); // NOLINT(hicpp-signed-bitwise) SET_ACC(JSTaggedValue(ret)) - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_AND2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_AND2DYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::and2dyn" @@ -1609,9 +1579,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool // NOLINT(hicpp-signed-bitwise) auto ret = static_cast(opNumber0) & static_cast(opNumber1); SET_ACC(JSTaggedValue(static_cast(ret))) - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_OR2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_OR2DYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::or2dyn" @@ -1644,9 +1614,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool // NOLINT(hicpp-signed-bitwise) auto ret = static_cast(opNumber0) | static_cast(opNumber1); SET_ACC(JSTaggedValue(static_cast(ret))) - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_XOR2DYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_XOR2DYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::xor2dyn" @@ -1679,9 +1649,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool // NOLINT(hicpp-signed-bitwise) auto ret = static_cast(opNumber0) ^ static_cast(opNumber1); SET_ACC(JSTaggedValue(static_cast(ret))) - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_DELOBJPROP_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_DELOBJPROP_PREF_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsics::delobjprop" @@ -1693,30 +1663,13 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_DEFINEGLOBALVAR_IMM8_V8_V8) { - // it38 Unimplement - LOG_INST() << "-------------"; - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_DEFINELOCALVAR_IMM8_V8_V8) { - // it38 Unimplement - LOG_INST() << "-------------"; - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_DEFINEFUNCEXPR_IMM8_V8_V8) { - // it38 Unimplement - LOG_INST() << "-------------"; - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_DEFINEFUNCDYN_IMM8_ID16_V8) { + HANDLE_OPCODE(HANDLE_DEFINEFUNCDYN_PREF_ID16_IMM16_V8) { uint16_t methodId = READ_INST_16_1(); - uint16_t v0 = READ_INST_8_3(); - LOG_INST() << "intrinsics::definefuncDyn" + uint16_t length = READ_INST_16_3(); + uint16_t v0 = READ_INST_8_5(); + LOG_INST() << "intrinsics::definefuncDyn length: " << length << " v" << v0; JSFunction *result = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject()); ASSERT(result != nullptr); @@ -1729,17 +1682,19 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool result->SetResolved(thread); } + result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length)); JSTaggedValue envHandle = GET_VREG_VALUE(v0); result->SetLexicalEnv(thread, envHandle); SET_ACC(JSTaggedValue(result)) - DISPATCH(BytecodeInstruction::Format::IMM8_ID16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_DEFINENCFUNCDYN_IMM8_ID16_V8) { + HANDLE_OPCODE(HANDLE_DEFINENCFUNCDYN_PREF_ID16_IMM16_V8) { uint16_t methodId = READ_INST_16_1(); - uint16_t v0 = READ_INST_8_3(); + uint16_t length = READ_INST_16_3(); + uint16_t v0 = READ_INST_8_5(); JSTaggedValue homeObject = GET_ACC(); - LOG_INST() << "intrinsics::definencfuncDyn" + LOG_INST() << "intrinsics::definencfuncDyn length: " << length << " v" << v0; JSFunction *result = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject()); ASSERT(result != nullptr); @@ -1751,18 +1706,21 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } else { result->SetResolved(thread); } + + result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length)); JSTaggedValue env = GET_VREG_VALUE(v0); result->SetLexicalEnv(thread, env); result->SetHomeObject(thread, homeObject); SET_ACC(JSTaggedValue(result)); - DISPATCH(BytecodeInstruction::Format::IMM8_ID16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_DEFINEMETHOD_IMM8_ID16_V8) { + HANDLE_OPCODE(HANDLE_DEFINEMETHOD_PREF_ID16_IMM16_V8) { uint16_t methodId = READ_INST_16_1(); - uint16_t v0 = READ_INST_8_3(); + uint16_t length = READ_INST_16_3(); + uint16_t v0 = READ_INST_8_5(); JSTaggedValue homeObject = GET_ACC(); - LOG_INST() << "intrinsics::definemethod" + LOG_INST() << "intrinsics::definemethod length: " << length << " v" << v0; JSFunction *result = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject()); ASSERT(result != nullptr); @@ -1776,13 +1734,14 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool result->SetResolved(thread); } + result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length)); JSTaggedValue taggedCurEnv = GET_VREG_VALUE(v0); result->SetLexicalEnv(thread, taggedCurEnv); SET_ACC(JSTaggedValue(result)); - DISPATCH(BytecodeInstruction::Format::IMM8_ID16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_NEWOBJDYNRANGE_IMM8_IMM16_V8) { + HANDLE_OPCODE(HANDLE_NEWOBJDYNRANGE_PREF_IMM16_V8) { uint16_t numArgs = READ_INST_16_1(); uint16_t firstArgRegIdx = READ_INST_8_3(); LOG_INST() << "intrinsics::newobjDynrange " << numArgs << " v" << firstArgRegIdx; @@ -1797,15 +1756,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::NewObjDynRange(thread, func, newTarget, firstArgIdx, length); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_REFEQDYN_IMM8_V8_V8) { - // it38 Unimplement - LOG_INST() << "-------------"; - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_EXPDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_EXPDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::expdyn" << " v" << v0; @@ -1837,15 +1790,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_CALLRUNTIMERANGE_IMM8_V8_V8) { - // it38 Unimplement - LOG_INST() << "-------------"; - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_ISINDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_ISINDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::isindyn" << " v" << v0; @@ -1854,9 +1801,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::IsInDyn(thread, prop, obj); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_INSTANCEOFDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_INSTANCEOFDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::instanceofdyn" << " v" << v0; @@ -1865,9 +1812,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::InstanceofDyn(thread, obj, target); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_STRICTNOTEQDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_STRICTNOTEQDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::strictnoteq" << " v" << v0; @@ -1875,9 +1822,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue right = GET_ACC(); bool res = FastRuntimeStub::FastStrictEqual(left, right); SET_ACC(JSTaggedValue(!res)); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_STRICTEQDYN_IMM8_V8) { + HANDLE_OPCODE(HANDLE_STRICTEQDYN_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::stricteq" << " v" << v0; @@ -1885,9 +1832,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue right = GET_ACC(); bool res = FastRuntimeStub::FastStrictEqual(left, right); SET_ACC(JSTaggedValue(res)); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDLEXVARDYN_IMM8_IMM16_IMM16) { + HANDLE_OPCODE(HANDLE_LDLEXVARDYN_PREF_IMM16_IMM16) { uint16_t level = READ_INST_16_1(); uint16_t slot = READ_INST_16_3(); @@ -1902,9 +1849,43 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool env = taggedParentEnv; } SET_ACC(LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot)); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16_IMM16); + } + HANDLE_OPCODE(HANDLE_LDLEXVARDYN_PREF_IMM8_IMM8) { + uint16_t level = READ_INST_8_1(); + uint16_t slot = READ_INST_8_2(); + + LOG_INST() << "intrinsics::ldlexvardyn" + << " level:" << level << " slot:" << slot; + FrameState *state = GET_FRAME(sp); + JSTaggedValue currentLexenv = state->env; + JSTaggedValue env(currentLexenv); + for (int i = 0; i < level; i++) { + JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv(); + ASSERT(!taggedParentEnv.IsUndefined()); + env = taggedParentEnv; + } + SET_ACC(LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot)); + DISPATCH(BytecodeInstruction::Format::PREF_IMM8_IMM8); + } + HANDLE_OPCODE(HANDLE_LDLEXVARDYN_PREF_IMM4_IMM4) { + uint16_t level = READ_INST_4_2(); + uint16_t slot = READ_INST_4_3(); + + LOG_INST() << "intrinsics::ldlexvardyn" + << " level:" << level << " slot:" << slot; + FrameState *state = GET_FRAME(sp); + JSTaggedValue currentLexenv = state->env; + JSTaggedValue env(currentLexenv); + for (int i = 0; i < level; i++) { + JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv(); + ASSERT(!taggedParentEnv.IsUndefined()); + env = taggedParentEnv; + } + SET_ACC(LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot)); + DISPATCH(BytecodeInstruction::Format::PREF_IMM4_IMM4); } - HANDLE_OPCODE(HANDLE_BUILTIN_STLEXVARDYN_IMM8_IMM16_IMM16_V8) { + HANDLE_OPCODE(HANDLE_STLEXVARDYN_PREF_IMM16_IMM16_V8) { uint16_t level = READ_INST_16_1(); uint16_t slot = READ_INST_16_3(); uint16_t v0 = READ_INST_8_5(); @@ -1921,9 +1902,47 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16_IMM16_V8); + } + HANDLE_OPCODE(HANDLE_STLEXVARDYN_PREF_IMM8_IMM8_V8) { + uint16_t level = READ_INST_8_1(); + uint16_t slot = READ_INST_8_2(); + uint16_t v0 = READ_INST_8_3(); + LOG_INST() << "intrinsics::stlexvardyn" + << " level:" << level << " slot:" << slot << " v" << v0; + + JSTaggedValue value = GET_VREG_VALUE(v0); + FrameState *state = GET_FRAME(sp); + JSTaggedValue env = state->env; + for (int i = 0; i < level; i++) { + JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv(); + ASSERT(!taggedParentEnv.IsUndefined()); + env = taggedParentEnv; + } + LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value); + + DISPATCH(BytecodeInstruction::Format::PREF_IMM8_IMM8_V8); + } + HANDLE_OPCODE(HANDLE_STLEXVARDYN_PREF_IMM4_IMM4_V8) { + uint16_t level = READ_INST_4_2(); + uint16_t slot = READ_INST_4_3(); + uint16_t v0 = READ_INST_8_2(); + LOG_INST() << "intrinsics::stlexvardyn" + << " level:" << level << " slot:" << slot << " v" << v0; + + JSTaggedValue value = GET_VREG_VALUE(v0); + FrameState *state = GET_FRAME(sp); + JSTaggedValue env = state->env; + for (int i = 0; i < level; i++) { + JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv(); + ASSERT(!taggedParentEnv.IsUndefined()); + env = taggedParentEnv; + } + LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(thread, slot, value); + + DISPATCH(BytecodeInstruction::Format::PREF_IMM4_IMM4_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_NEWLEXENVDYN_IMM8_IMM16) { + HANDLE_OPCODE(HANDLE_NEWLEXENVDYN_PREF_IMM16) { uint16_t numVars = READ_INST_16_1(); LOG_INST() << "intrinsics::newlexenvdyn" << " imm " << numVars; @@ -1935,16 +1954,16 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } SET_ACC(res); GET_FRAME(sp)->env = res; - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16); } - HANDLE_OPCODE(HANDLE_BUILTIN_POPLEXENVDYN_IMM8) { + HANDLE_OPCODE(HANDLE_POPLEXENVDYN_PREF) { FrameState *state = GET_FRAME(sp); JSTaggedValue currentLexenv = state->env; JSTaggedValue parentLexenv = LexicalEnv::Cast(currentLexenv.GetTaggedObject())->GetParentEnv(); GET_FRAME(sp)->env = parentLexenv; - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_CREATEITERRESULTOBJ_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_CREATEITERRESULTOBJ_PREF_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsics::createiterresultobj" @@ -1954,9 +1973,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::CreateIterResultObj(thread, value, flag); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_SUSPENDGENERATOR_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_SUSPENDGENERATOR_PREF_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsics::suspendgenerator" @@ -1972,7 +1991,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool FrameState *state = GET_FRAME(sp); [[maybe_unused]] auto fistPC = state->method->GetInstructions(); - UPDATE_HOTNESS_COUNTER(thread, sp, -(pc - fistPC)); + UPDATE_HOTNESS_COUNTER(-(pc - fistPC)); LOG(DEBUG, INTERPRETER) << "Exit: SuspendGenerator " << std::hex << reinterpret_cast(sp) << " " << std::hex << reinterpret_cast(state->pc); sp = state->prev; @@ -1991,7 +2010,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool size_t jumpSize = GetJumpSizeAfterCall(pc); DISPATCH_OFFSET(jumpSize); } - HANDLE_OPCODE(HANDLE_BUILTIN_ASYNCFUNCTIONAWAITUNCAUGHT_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsics::asyncfunctionawaituncaught" @@ -2001,9 +2020,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::AsyncFunctionAwaitUncaught(thread, asyncFuncObj, value); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_ASYNCFUNCTIONRESOLVE_IMM8_V8_V8_V8) { + HANDLE_OPCODE(HANDLE_ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8) { uint16_t v0 = READ_INST_8_1(); [[maybe_unused]] uint16_t v1 = READ_INST_8_2(); uint16_t v2 = READ_INST_8_3(); @@ -2015,9 +2034,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::AsyncFunctionResolveOrReject(thread, asyncFuncObj, value, true); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_ASYNCFUNCTIONREJECT_IMM8_V8_V8_V8) { + HANDLE_OPCODE(HANDLE_ASYNCFUNCTIONREJECT_PREF_V8_V8_V8) { uint16_t v0 = READ_INST_8_1(); [[maybe_unused]] uint16_t v1 = READ_INST_8_2(); uint16_t v2 = READ_INST_8_3(); @@ -2030,9 +2049,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::AsyncFunctionResolveOrReject(thread, asyncFuncObj, value, false); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_NEWOBJSPREADDYN_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_NEWOBJSPREADDYN_PREF_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsic::newobjspearddyn" @@ -2043,25 +2062,25 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::NewObjSpreadDyn(thread, func, newTarget, array); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_THROWUNDEFINEDIFHOLE_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_THROWUNDEFINEDIFHOLE_PREF_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsic::throwundefinedifhole" << " v" << v0 << " v" << v1; JSTaggedValue hole = GET_VREG_VALUE(v0); if (!hole.IsHole()) { - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } JSTaggedValue obj = GET_VREG_VALUE(v1); ASSERT(obj.IsString()); SlowRuntimeStub::ThrowUndefinedIfHole(thread, obj); INTERPRETER_GOTO_EXCEPTION_HANDLER(); } - HANDLE_OPCODE(HANDLE_BUILTIN_STOWNBYNAME_IMM8_ID32_IMM16_V8) { + HANDLE_OPCODE(HANDLE_STOWNBYNAME_PREF_ID32_V8) { uint32_t stringId = READ_INST_32_1(); - uint32_t v0 = ReadU8(pc, 1); + uint32_t v0 = READ_INST_8_5(); LOG_INST() << "intrinsics::stownbyname " << "v" << v0 << " stringId:" << stringId; @@ -2075,7 +2094,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool if (!res.IsHole()) { INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); } RESTORE_ACC(); } @@ -2087,21 +2106,21 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::StOwnByName(thread, receiver, propKey, value); RESTORE_ACC(); INTERPRETER_RETURN_IF_ABRUPT(res); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_CREATEEMPTYARRAY_IMM8) { + HANDLE_OPCODE(HANDLE_CREATEEMPTYARRAY_PREF) { LOG_INST() << "intrinsics::createemptyarray"; JSTaggedValue res = SlowRuntimeStub::CreateEmptyArray(thread, factory, globalEnv); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_CREATEEMPTYOBJECT_IMM8) { + HANDLE_OPCODE(HANDLE_CREATEEMPTYOBJECT_PREF) { LOG_INST() << "intrinsics::createemptyobject"; JSTaggedValue res = SlowRuntimeStub::CreateEmptyObject(thread, factory, globalEnv); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_CREATEOBJECTWITHBUFFER_IMM8_IMM16) { + HANDLE_OPCODE(HANDLE_CREATEOBJECTWITHBUFFER_PREF_IMM16) { uint16_t imm = READ_INST_16_1(); LOG_INST() << "intrinsics::createobjectwithbuffer" << " imm:" << imm; @@ -2110,9 +2129,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::CreateObjectWithBuffer(thread, factory, result); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16); } - HANDLE_OPCODE(HANDLE_BUILTIN_SETOBJECTWITHPROTO_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_SETOBJECTWITHPROTO_PREF_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsics::setobjectwithproto" @@ -2123,9 +2142,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::SetObjectWithProto(thread, proto, obj); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_CREATEARRAYWITHBUFFER_IMM8_IMM16) { + HANDLE_OPCODE(HANDLE_CREATEARRAYWITHBUFFER_PREF_IMM16) { uint16_t imm = READ_INST_16_1(); LOG_INST() << "intrinsics::createarraywithbuffer" << " imm:" << imm; @@ -2133,9 +2152,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::CreateArrayWithBuffer(thread, factory, result); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16); } - HANDLE_OPCODE(HANDLE_BUILTIN_IMPORTMODULE_IMM8_ID32) { + HANDLE_OPCODE(HANDLE_IMPORTMODULE_PREF_ID32) { uint32_t stringId = READ_INST_32_1(); auto prop = constpool->GetObjectFromCache(stringId); @@ -2144,9 +2163,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue moduleRef = SlowRuntimeStub::ImportModule(thread, prop); SET_ACC(moduleRef); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); } - HANDLE_OPCODE(HANDLE_BUILTIN_STMODULEVAR_IMM8_ID32) { + HANDLE_OPCODE(HANDLE_STMODULEVAR_PREF_ID32) { uint32_t stringId = READ_INST_32_1(); auto prop = constpool->GetObjectFromCache(stringId); @@ -2157,9 +2176,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool SAVE_ACC(); SlowRuntimeStub::StModuleVar(thread, prop, value); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); } - HANDLE_OPCODE(HANDLE_BUILTIN_COPYMODULE_IMM8_V8) { + HANDLE_OPCODE(HANDLE_COPYMODULE_PREF_V8) { uint16_t v0 = READ_INST_8_1(); JSTaggedValue srcModule = GET_VREG_VALUE(v0); @@ -2168,11 +2187,11 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool SAVE_ACC(); SlowRuntimeStub::CopyModule(thread, srcModule); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDMODVARBYNAME_IMM8_ID32_IMM16_V8) { + HANDLE_OPCODE(HANDLE_LDMODVARBYNAME_PREF_ID32_V8) { uint32_t stringId = READ_INST_32_1(); - uint32_t v0 = ReadU8(pc, 1); + uint32_t v0 = READ_INST_8_5(); JSTaggedValue itemName = constpool->GetObjectFromCache(stringId); JSTaggedValue moduleObj = GET_VREG_VALUE(v0); @@ -2182,9 +2201,21 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue moduleVar = SlowRuntimeStub::LdModvarByName(thread, moduleObj, itemName); SET_ACC(moduleVar); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_GETTEMPLATEOBJECT_IMM8_V8) { + HANDLE_OPCODE(HANDLE_CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8) { + uint32_t stringId = READ_INST_32_1(); + JSTaggedValue pattern = constpool->GetObjectFromCache(stringId); + uint8_t flags = READ_INST_8_5(); + LOG_INST() << "intrinsics::createregexpwithliteral " + << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(pattern.GetTaggedObject())) + << ", flags:" << flags; + JSTaggedValue res = SlowRuntimeStub::CreateRegExpWithLiteral(thread, pattern, flags); + INTERPRETER_RETURN_IF_ABRUPT(res); + SET_ACC(res); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_IMM8); + } + HANDLE_OPCODE(HANDLE_GETTEMPLATEOBJECT_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsic::gettemplateobject" << " v" << v0; @@ -2193,9 +2224,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::GetTemplateObject(thread, literal); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_GETNEXTPROPNAME_IMM8_V8) { + HANDLE_OPCODE(HANDLE_GETNEXTPROPNAME_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsic::getnextpropname" << " v" << v0; @@ -2203,9 +2234,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::GetNextPropName(thread, iter); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_COPYDATAPROPERTIES_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_COPYDATAPROPERTIES_PREF_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsic::copydataproperties" @@ -2215,26 +2246,25 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::CopyDataProperties(thread, dst, src); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_STOWNBYINDEX_IMM8_IMM16_V8_V8) { - uint32_t v0 = READ_INST_8_3(); - uint32_t v1 = READ_INST_8_4(); + HANDLE_OPCODE(HANDLE_STOWNBYINDEX_PREF_V8_IMM32) { + uint32_t v0 = READ_INST_8_1(); + uint32_t index = READ_INST_32_2(); LOG_INST() << "intrinsics::stownbyindex" - << " v" << v0 << " v" << v1; + << " v" << v0 << " imm" << index; JSTaggedValue receiver = GET_VREG_VALUE(v0); - JSTaggedValue index = GET_VREG_VALUE(v1); // fast path if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) { SAVE_ACC(); JSTaggedValue value = GET_ACC(); // fast path JSTaggedValue res = - FastRuntimeStub::SetPropertyByIndex(thread, receiver, index.GetArrayLength(), value); + FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value); if (!res.IsHole()) { INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32); } RESTORE_ACC(); } @@ -2244,11 +2274,11 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::StOwnByIndex(thread, receiver, index, value); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32); } - HANDLE_OPCODE(HANDLE_BUILTIN_STOWNBYVALUE_IMM8_IMM16_V8_V8) { - uint32_t v0 = READ_INST_8_3(); - uint32_t v1 = READ_INST_8_4(); + HANDLE_OPCODE(HANDLE_STOWNBYVALUE_PREF_V8_V8) { + uint32_t v0 = READ_INST_8_1(); + uint32_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsics::stownbyvalue" << " v" << v0 << " v" << v1; @@ -2270,7 +2300,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey); } RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } } @@ -2282,9 +2312,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::StOwnByValue(thread, receiver, propKey, value); RESTORE_ACC(); INTERPRETER_RETURN_IF_ABRUPT(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_CREATEOBJECTWITHEXCLUDEDKEYS_IMM8_IMM16_V8_V8) { + HANDLE_OPCODE(HANDLE_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8) { uint16_t numKeys = READ_INST_16_1(); uint16_t v0 = READ_INST_8_3(); uint16_t firstArgRegIdx = READ_INST_8_4(); @@ -2295,12 +2325,13 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::CreateObjectWithExcludedKeys(thread, numKeys, obj, firstArgRegIdx); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_DEFINEGENERATORFUNC_IMM8_ID16_V8) { + HANDLE_OPCODE(HANDLE_DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8) { uint16_t methodId = READ_INST_16_1(); - uint16_t v0 = READ_INST_8_3(); - LOG_INST() << "define gengerator function" + uint16_t length = READ_INST_16_3(); + uint16_t v0 = READ_INST_8_5(); + LOG_INST() << "define gengerator function length: " << length << " v" << v0; JSFunction *result = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject()); ASSERT(result != nullptr); @@ -2312,15 +2343,18 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } else { result->SetResolved(thread); } + + result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length)); JSTaggedValue env = GET_VREG_VALUE(v0); result->SetLexicalEnv(thread, env); SET_ACC(JSTaggedValue(result)) - DISPATCH(BytecodeInstruction::Format::IMM8_ID16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_DEFINEASYNCFUNC_IMM8_ID16_V8) { + HANDLE_OPCODE(HANDLE_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8) { uint16_t methodId = READ_INST_16_1(); - uint16_t v0 = READ_INST_8_3(); - LOG_INST() << "define async function" + uint16_t length = READ_INST_16_3(); + uint16_t v0 = READ_INST_8_5(); + LOG_INST() << "define async function length: " << length << " v" << v0; JSFunction *result = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject()); ASSERT(result != nullptr); @@ -2332,17 +2366,19 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } else { result->SetResolved(thread); } + + result->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length)); JSTaggedValue env = GET_VREG_VALUE(v0); result->SetLexicalEnv(thread, env); SET_ACC(JSTaggedValue(result)) - DISPATCH(BytecodeInstruction::Format::IMM8_ID16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDHOLE_IMM8) { + HANDLE_OPCODE(HANDLE_LDHOLE_PREF) { LOG_INST() << "intrinsic::ldhole"; SET_ACC(JSTaggedValue::Hole()); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_COPYRESTARGS_IMM8_IMM16) { + HANDLE_OPCODE(HANDLE_COPYRESTARGS_PREF_IMM16) { uint16_t restIdx = READ_INST_16_1(); LOG_INST() << "intrinsics::copyrestargs" << " index: " << restIdx; @@ -2358,15 +2394,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::CopyRestArgs(thread, sp, restNumArgs, startIdx); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16); - } - HANDLE_OPCODE(HANDLE_BUILTIN_TRYLDGLOBALBYVALUE_IMM8_IMM16_V8) { - // replaced by ldobjbyindex, not need - LOG_INST() << "-------------"; - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16); } - HANDLE_OPCODE(HANDLE_BUILTIN_DEFINEGETTERSETTERBYVALUE_IMM8_V8_V8_V8_V8) { + HANDLE_OPCODE(HANDLE_DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); uint16_t v2 = READ_INST_8_3(); @@ -2383,30 +2413,22 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool SlowRuntimeStub::DefineGetterSetterByValue(thread, obj, prop, getter, setter, flag.ToBoolean()); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8_V8_V8); - } - HANDLE_OPCODE(HANDLE_BUILTIN_TRYSTGLOBALBYVALUE_IMM8_IMM16_V8) { - // replaced by stobjbyindex, not need - LOG_INST() << "-------------"; - UNREACHABLE(); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDOBJBYINDEX_IMM8_IMM16_V8_V8) { - uint16_t v0 = READ_INST_8_3(); - uint16_t v1 = READ_INST_8_4(); + HANDLE_OPCODE(HANDLE_LDOBJBYINDEX_PREF_V8_IMM32) { + uint16_t v0 = READ_INST_8_1(); + uint32_t idx = READ_INST_32_2(); LOG_INST() << "intrinsics::ldobjbyindex" - << " v" << v0 << " v" << v1; + << " v" << v0 << " imm" << idx; JSTaggedValue receiver = GET_VREG_VALUE(v0); - JSTaggedValue idx = GET_VREG_VALUE(v1); - ASSERT(!(idx.IsDouble() && idx.GetDouble() >= JSObject::MAX_ELEMENT_INDEX)); // fast path if (LIKELY(receiver.IsHeapObject())) { - JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, receiver, idx.GetArrayLength()); + JSTaggedValue res = FastRuntimeStub::GetPropertyByIndex(thread, receiver, idx); if (!res.IsHole()) { INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32); } } // not meet fast condition or fast path return hole, walk slow path @@ -2414,25 +2436,24 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::LdObjByIndex(thread, receiver, idx, false, JSTaggedValue::Undefined()); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32); } - HANDLE_OPCODE(HANDLE_BUILTIN_STOBJBYINDEX_IMM8_IMM16_V8_V8) { - uint16_t v0 = READ_INST_8_3(); - uint16_t v1 = READ_INST_8_4(); + HANDLE_OPCODE(HANDLE_STOBJBYINDEX_PREF_V8_IMM32) { + uint16_t v0 = READ_INST_8_1(); + uint32_t index = READ_INST_32_2(); LOG_INST() << "intrinsics::stobjbyindex" - << " v" << v0 << " v" << v1; + << " v" << v0 << " imm" << index; JSTaggedValue receiver = GET_VREG_VALUE(v0); - JSTaggedValue index = GET_VREG_VALUE(v1); if (receiver.IsHeapObject()) { SAVE_ACC(); JSTaggedValue value = GET_ACC(); // fast path - JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index.GetArrayLength(), value); + JSTaggedValue res = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value); if (!res.IsHole()) { INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32); } RESTORE_ACC(); } @@ -2443,27 +2464,39 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::StObjByIndex(thread, receiver, index, value); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_IMM32); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDOBJBYVALUE_IMM8_IMM16_V8_V8) { - uint32_t v0 = READ_INST_8_3(); - uint32_t v1 = READ_INST_8_4(); + HANDLE_OPCODE(HANDLE_LDOBJBYVALUE_PREF_V8_V8) { + uint32_t v0 = READ_INST_8_1(); + uint32_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsics::Ldobjbyvalue" << " v" << v0 << " v" << v1; JSTaggedValue receiver = GET_VREG_VALUE(v0); JSTaggedValue propKey = GET_VREG_VALUE(v1); -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp); if (!profileTypeInfo.IsUndefined()) { - uint16_t slotId = READ_INST_16_1(); - JSTaggedValue res = ICRuntimeStub::LoadICByValue(thread, - ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()), - receiver, propKey, slotId); - INTERPRETER_RETURN_IF_ABRUPT(res); - SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + uint16_t slotId = READ_INST_8_0(); + auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()); + JSTaggedValue firstValue = profileTypeArray->Get(slotId); + JSTaggedValue res = JSTaggedValue::Hole(); + + if (LIKELY(firstValue.IsHeapObject())) { + JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1); + res = ICRuntimeStub::TryLoadICByValue(thread, receiver, propKey, firstValue, secondValue); + } else if (firstValue.IsUndefined()) { + res = ICRuntimeStub::LoadICByValue(thread, + profileTypeArray, + receiver, propKey, slotId); + } + + if (LIKELY(!res.IsHole())) { + INTERPRETER_RETURN_IF_ABRUPT(res); + SET_ACC(res); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); + } } #endif // fast path @@ -2473,36 +2506,48 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool ASSERT(!res.IsAccessor()); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } } // slow path JSTaggedValue res = SlowRuntimeStub::LdObjByValue(thread, receiver, propKey, false, JSTaggedValue::Undefined()); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_STOBJBYVALUE_IMM8_IMM16_V8_V8) { - uint32_t v0 = READ_INST_8_3(); - uint32_t v1 = READ_INST_8_4(); + HANDLE_OPCODE(HANDLE_STOBJBYVALUE_PREF_V8_V8) { + uint32_t v0 = READ_INST_8_1(); + uint32_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsics::stobjbyvalue" << " v" << v0 << " v" << v1; JSTaggedValue receiver = GET_VREG_VALUE(v0); -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp); if (!profileTypeInfo.IsUndefined()) { - uint16_t slotId = READ_INST_16_1(); - SAVE_ACC(); + uint16_t slotId = READ_INST_8_0(); + auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()); + JSTaggedValue firstValue = profileTypeArray->Get(slotId); JSTaggedValue propKey = GET_VREG_VALUE(v1); JSTaggedValue value = GET_ACC(); - JSTaggedValue res = ICRuntimeStub::StoreICByValue(thread, - ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()), - receiver, propKey, value, slotId); - INTERPRETER_RETURN_IF_ABRUPT(res); - RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + JSTaggedValue res = JSTaggedValue::Hole(); + SAVE_ACC(); + + if (LIKELY(firstValue.IsHeapObject())) { + JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1); + res = ICRuntimeStub::TryStoreICByValue(thread, receiver, propKey, firstValue, secondValue, value); + } else if (firstValue.IsUndefined()) { + res = ICRuntimeStub::StoreICByValue(thread, + profileTypeArray, + receiver, propKey, value, slotId); + } + + if (LIKELY(!res.IsHole())) { + INTERPRETER_RETURN_IF_ABRUPT(res); + RESTORE_ACC(); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); + } } #endif if (receiver.IsHeapObject()) { @@ -2514,7 +2559,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool if (!res.IsHole()) { INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } RESTORE_ACC(); } @@ -2528,11 +2573,11 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); } - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDSUPERBYVALUE_IMM8_IMM16_V8_V8) { - uint32_t v0 = READ_INST_8_3(); - uint32_t v1 = READ_INST_8_4(); + HANDLE_OPCODE(HANDLE_LDSUPERBYVALUE_PREF_V8_V8) { + uint32_t v0 = READ_INST_8_1(); + uint32_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsics::Ldsuperbyvalue" << " v" << v0 << " v" << v1; @@ -2544,11 +2589,11 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::LdSuperByValue(thread, receiver, propKey, thisFunc); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_STSUPERBYVALUE_IMM8_IMM16_V8_V8) { - uint32_t v0 = READ_INST_8_3(); - uint32_t v1 = READ_INST_8_4(); + HANDLE_OPCODE(HANDLE_STSUPERBYVALUE_PREF_V8_V8) { + uint32_t v0 = READ_INST_8_1(); + uint32_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsics::stsuperbyvalue" << " v" << v0 << " v" << v1; @@ -2562,26 +2607,26 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::StSuperByValue(thread, receiver, propKey, value, thisFunc); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_TRYLDGLOBALBYNAME_IMM8_ID32_IMM16) { + HANDLE_OPCODE(HANDLE_TRYLDGLOBALBYNAME_PREF_ID32) { uint32_t stringId = READ_INST_32_1(); auto prop = constpool->GetObjectFromCache(stringId); LOG_INST() << "intrinsics::tryldglobalbyname " << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(prop.GetTaggedObject())); -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp); if (!profileTypeInfo.IsUndefined()) { - uint16_t slotId = READ_INST_16_5(); + uint16_t slotId = READ_INST_8_0(); JSTaggedValue res = ICRuntimeStub::LoadGlobalICByName(thread, ProfileTypeInfo::Cast( profileTypeInfo.GetTaggedObject()), globalObj, prop, slotId); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); } #endif @@ -2596,18 +2641,18 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); } - HANDLE_OPCODE(HANDLE_BUILTIN_TRYSTGLOBALBYNAME_IMM8_ID32_IMM16) { + HANDLE_OPCODE(HANDLE_TRYSTGLOBALBYNAME_PREF_ID32) { uint32_t stringId = READ_INST_32_1(); JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); LOG_INST() << "intrinsics::trystglobalbyname" << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())); -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp); if (!profileTypeInfo.IsUndefined()) { - uint16_t slotId = READ_INST_16_5(); + uint16_t slotId = READ_INST_8_0(); JSTaggedValue value = GET_ACC(); SAVE_ACC(); JSTaggedValue res = ICRuntimeStub::StoreGlobalICByName(thread, @@ -2616,7 +2661,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool globalObj, propKey, value, slotId); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); } #endif @@ -2633,23 +2678,23 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); } - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDGLOBALVAR_IMM8_ID32_IMM16) { + HANDLE_OPCODE(HANDLE_LDGLOBALVAR_PREF_ID32) { uint32_t stringId = READ_INST_32_1(); JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp); if (!profileTypeInfo.IsUndefined()) { - uint16_t slotId = READ_INST_16_5(); + uint16_t slotId = READ_INST_8_0(); JSTaggedValue res = ICRuntimeStub::LoadGlobalICByName(thread, ProfileTypeInfo::Cast( profileTypeInfo.GetTaggedObject()), globalObj, propKey, slotId); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); } #endif bool found = false; @@ -2662,30 +2707,44 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); } - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDOBJBYNAME_IMM8_ID32_IMM16_V8) { - uint32_t stringId = READ_INST_32_1(); - uint32_t v0 = ReadU8(pc, 1); + HANDLE_OPCODE(HANDLE_LDOBJBYNAME_PREF_ID32_V8) { + uint32_t v0 = READ_INST_8_5(); JSTaggedValue receiver = GET_VREG_VALUE(v0); - JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); - - LOG_INST() << "intrinsics::ldobjbyname " - << "v" << v0 << " stringId:" << stringId << ", " - << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << receiver.GetRawData(); -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp); if (!profileTypeInfo.IsUndefined()) { - uint16_t slotId = READ_INST_16_5(); - JSTaggedValue res = ICRuntimeStub::LoadICByName(thread, - ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()), - receiver, propKey, slotId); - INTERPRETER_RETURN_IF_ABRUPT(res); - SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + uint16_t slotId = READ_INST_8_0(); + auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()); + JSTaggedValue firstValue = profileTypeArray->Get(slotId); + JSTaggedValue res = JSTaggedValue::Hole(); + + if (LIKELY(firstValue.IsHeapObject())) { + JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1); + res = ICRuntimeStub::TryLoadICByName(thread, receiver, firstValue, secondValue); + } else if (firstValue.IsUndefined()) { + uint32_t stringId = READ_INST_32_1(); + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + res = ICRuntimeStub::LoadICByName(thread, + profileTypeArray, + receiver, propKey, slotId); + } + + if (LIKELY(!res.IsHole())) { + INTERPRETER_RETURN_IF_ABRUPT(res); + SET_ACC(res); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); + } } #endif + uint32_t stringId = READ_INST_32_1(); + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + LOG_INST() << "intrinsics::ldobjbyname " + << "v" << v0 << " stringId:" << stringId << ", " + << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())) << ", obj:" << receiver.GetRawData(); + if (LIKELY(receiver.IsHeapObject())) { // fast path JSTaggedValue res = FastRuntimeStub::GetPropertyByName(thread, receiver, propKey); @@ -2693,7 +2752,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool ASSERT(!res.IsAccessor()); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); } } // not meet fast condition or fast path return hole, walk slow path @@ -2701,40 +2760,52 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::LdObjByName(thread, receiver, propKey, false, JSTaggedValue::Undefined()); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_STOBJBYNAME_IMM8_ID32_IMM16_V8) { - uint32_t stringId = READ_INST_32_1(); - uint32_t v0 = ReadU8(pc, 1); - LOG_INST() << "intrinsics::stobjbyname " - << "v" << v0 << " stringId:" << stringId; - + HANDLE_OPCODE(HANDLE_STOBJBYNAME_PREF_ID32_V8) { + uint32_t v0 = READ_INST_8_5(); JSTaggedValue receiver = GET_VREG_VALUE(v0); -#if ENABLE_IC + JSTaggedValue value = GET_ACC(); +#if ECMASCRIPT_ENABLE_IC auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp); if (!profileTypeInfo.IsUndefined()) { - uint16_t slotId = READ_INST_16_5(); + uint16_t slotId = READ_INST_8_0(); + auto profileTypeArray = ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()); + JSTaggedValue firstValue = profileTypeArray->Get(slotId); + JSTaggedValue res = JSTaggedValue::Hole(); SAVE_ACC(); - JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); - JSTaggedValue value = GET_ACC(); - JSTaggedValue res = ICRuntimeStub::StoreICByName(thread, - ProfileTypeInfo::Cast(profileTypeInfo.GetTaggedObject()), - receiver, propKey, value, slotId); - INTERPRETER_RETURN_IF_ABRUPT(res); - RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + + if (LIKELY(firstValue.IsHeapObject())) { + JSTaggedValue secondValue = profileTypeArray->Get(slotId + 1); + res = ICRuntimeStub::TryStoreICByName(thread, receiver, firstValue, secondValue, value); + } else if (firstValue.IsUndefined()) { + uint32_t stringId = READ_INST_32_1(); + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + res = ICRuntimeStub::StoreICByName(thread, + profileTypeArray, + receiver, propKey, value, slotId); + } + + if (LIKELY(!res.IsHole())) { + INTERPRETER_RETURN_IF_ABRUPT(res); + RESTORE_ACC(); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); + } } #endif + uint32_t stringId = READ_INST_32_1(); + LOG_INST() << "intrinsics::stobjbyname " + << "v" << v0 << " stringId:" << stringId; if (receiver.IsHeapObject()) { JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); - JSTaggedValue value = GET_ACC(); + value = GET_ACC(); // fast path SAVE_ACC(); JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value); if (!res.IsHole()) { INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); } RESTORE_ACC(); } @@ -2742,15 +2813,15 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool SAVE_ACC(); receiver = GET_VREG_VALUE(v0); // Maybe moved by GC auto propKey = constpool->GetObjectFromCache(stringId); // Maybe moved by GC - auto value = GET_ACC(); // Maybe moved by GC + value = GET_ACC(); // Maybe moved by GC JSTaggedValue res = SlowRuntimeStub::StObjByName(thread, receiver, propKey, value); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDSUPERBYNAME_IMM8_ID32_IMM16_V8) { + HANDLE_OPCODE(HANDLE_LDSUPERBYNAME_PREF_ID32_V8) { uint32_t stringId = READ_INST_32_1(); - uint32_t v0 = ReadU8(pc, 1); + uint32_t v0 = READ_INST_8_5(); JSTaggedValue obj = GET_VREG_VALUE(v0); JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); @@ -2763,11 +2834,11 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_STSUPERBYNAME_IMM8_ID32_IMM16_V8) { + HANDLE_OPCODE(HANDLE_STSUPERBYNAME_PREF_ID32_V8) { uint32_t stringId = READ_INST_32_1(); - uint32_t v0 = ReadU8(pc, 1); + uint32_t v0 = READ_INST_8_5(); JSTaggedValue obj = GET_VREG_VALUE(v0); JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); @@ -2784,9 +2855,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::StSuperByValue(thread, obj, propKey, value, thisFunc); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_STGLOBALVAR_IMM8_ID32_IMM16) { + HANDLE_OPCODE(HANDLE_STGLOBALVAR_PREF_ID32) { uint32_t stringId = READ_INST_32_1(); JSTaggedValue prop = constpool->GetObjectFromCache(stringId); JSTaggedValue value = GET_ACC(); @@ -2794,10 +2865,10 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool LOG_INST() << "intrinsics::stglobalvar " << "stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(prop.GetTaggedObject())) << ", value:" << value.GetRawData(); -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC auto profileTypeInfo = GetRuntimeProfileTypeInfo(sp); if (!profileTypeInfo.IsUndefined()) { - uint16_t slotId = READ_INST_16_5(); + uint16_t slotId = READ_INST_8_0(); SAVE_ACC(); JSTaggedValue res = ICRuntimeStub::StoreGlobalICByName(thread, ProfileTypeInfo::Cast( @@ -2805,16 +2876,16 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool globalObj, prop, value, slotId); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); } #endif SAVE_ACC(); JSTaggedValue res = SlowRuntimeStub::StGlobalVar(thread, prop, value); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - DISPATCH(BytecodeInstruction::Format::IMM8_ID32_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); } - HANDLE_OPCODE(HANDLE_BUILTIN_CREATEGENERATOROBJ_IMM8_V8) { + HANDLE_OPCODE(HANDLE_CREATEGENERATOROBJ_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsics::creategeneratorobj" << " v" << v0; @@ -2822,9 +2893,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::CreateGeneratorObj(thread, genFunc); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_STARRAYSPREAD_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_STARRAYSPREAD_PREF_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); LOG_INST() << "ecmascript::intrinsics::starrayspread" @@ -2835,9 +2906,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::StArraySpread(thread, dst, index, src); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_GETITERATORNEXT_IMM8_V8_V8) { + HANDLE_OPCODE(HANDLE_GETITERATORNEXT_PREF_V8_V8) { uint16_t v0 = READ_INST_8_1(); uint16_t v1 = READ_INST_8_2(); LOG_INST() << "intrinsic::getiteratornext" @@ -2847,13 +2918,14 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::GetIteratorNext(thread, obj, method); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_DEFINECLASSWITHBUFFER_IMM8_ID16_IMM16_V8_V8) { + HANDLE_OPCODE(HANDLE_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8) { uint16_t methodId = READ_INST_16_1(); uint16_t imm = READ_INST_16_3(); - uint16_t v0 = READ_INST_8_5(); - uint16_t v1 = READ_INST_8_6(); + uint16_t length = READ_INST_16_5(); + uint16_t v0 = READ_INST_8_7(); + uint16_t v1 = READ_INST_8_8(); LOG_INST() << "intrinsics::defineclasswithbuffer" << " method id:" << methodId << " literal id:" << imm << " lexenv: v" << v0 << " parent: v" << v1; JSFunction *cls = JSFunction::Cast(constpool->GetObjectFromCache(methodId).GetTaggedObject()); @@ -2866,6 +2938,8 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } else { cls->SetResolved(thread); } + + cls->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, JSTaggedValue(length)); JSTaggedValue lexenv = GET_VREG_VALUE(v0); cls->SetLexicalEnv(thread, lexenv); @@ -2874,9 +2948,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::DefineClass(thread, cls, literalBuffer, proto, lexenv, constpool); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_ID16_IMM16_V8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_IMM16_V8_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_SUPERCALL_IMM8_IMM16_V8) { + HANDLE_OPCODE(HANDLE_SUPERCALL_PREF_IMM16_V8) { uint16_t range = READ_INST_16_1(); uint16_t v0 = READ_INST_8_3(); LOG_INST() << "intrinsics::supercall" @@ -2890,9 +2964,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::SuperCall(thread, thisFunc, newTarget, v0, range); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16_V8); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_SUPERCALLSPREAD_IMM8_V8) { + HANDLE_OPCODE(HANDLE_SUPERCALLSPREAD_PREF_V8) { uint16_t v0 = READ_INST_8_1(); LOG_INST() << "intrinsic::supercallspread" << " array: v" << v0; @@ -2906,9 +2980,9 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::SuperCallSpread(thread, thisFunc, newTarget, array); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_V8); + DISPATCH(BytecodeInstruction::Format::PREF_V8); } - HANDLE_OPCODE(HANDLE_BUILTIN_CREATEOBJECTHAVINGMETHOD_IMM8_IMM16) { + HANDLE_OPCODE(HANDLE_CREATEOBJECTHAVINGMETHOD_PREF_IMM16) { uint16_t imm = READ_INST_16_1(); LOG_INST() << "intrinsics::createobjecthavingmethod" << " imm:" << imm; @@ -2918,35 +2992,53 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::CreateObjectHavingMethod(thread, factory, result, env, constpool); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16); } - HANDLE_OPCODE(HANDLE_BUILTIN_THROWIFSUPERNOTCORRECTCALL_IMM8_IMM16) { + HANDLE_OPCODE(HANDLE_THROWIFSUPERNOTCORRECTCALL_PREF_IMM16) { uint16_t imm = READ_INST_16_1(); JSTaggedValue thisValue = GET_ACC(); LOG_INST() << "intrinsic::throwifsupernotcorrectcall" << " imm:" << imm; JSTaggedValue res = SlowRuntimeStub::ThrowIfSuperNotCorrectCall(thread, imm, thisValue); INTERPRETER_RETURN_IF_ABRUPT(res); - DISPATCH(BytecodeInstruction::Format::IMM8_IMM16); + DISPATCH(BytecodeInstruction::Format::PREF_IMM16); } - HANDLE_OPCODE(HANDLE_BUILTIN_LDHOMEOBJECT_IMM8) { + HANDLE_OPCODE(HANDLE_LDHOMEOBJECT_PREF) { LOG_INST() << "intrinsics::ldhomeobject"; JSTaggedValue thisFunc = GetThisFunction(sp); JSTaggedValue homeObject = JSFunction::Cast(thisFunc.GetTaggedObject())->GetHomeObject(); SET_ACC(homeObject); - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } - HANDLE_OPCODE(HANDLE_BUILTIN_THROWDELETESUPERPROPERTY_IMM8) { + HANDLE_OPCODE(HANDLE_THROWDELETESUPERPROPERTY_PREF) { LOG_INST() << "throwdeletesuperproperty"; SlowRuntimeStub::ThrowDeleteSuperProperty(thread); INTERPRETER_GOTO_EXCEPTION_HANDLER(); } - HANDLE_OPCODE(HANDLE_BUILTIN_DEBUGGER_IMM8) { + HANDLE_OPCODE(HANDLE_DEBUGGER_PREF) { LOG_INST() << "intrinsics::debugger"; - DISPATCH(BytecodeInstruction::Format::IMM8); + DISPATCH(BytecodeInstruction::Format::PREF_NONE); + } + HANDLE_OPCODE(HANDLE_ISTRUE_PREF) { + LOG_INST() << "intrinsics::istrue"; + if (GET_ACC().ToBoolean()) { + SET_ACC(JSTaggedValue::True()); + } else { + SET_ACC(JSTaggedValue::False()); + } + DISPATCH(BytecodeInstruction::Format::PREF_NONE); + } + HANDLE_OPCODE(HANDLE_ISFALSE_PREF) { + LOG_INST() << "intrinsics::isfalse"; + if (!GET_ACC().ToBoolean()) { + SET_ACC(JSTaggedValue::True()); + } else { + SET_ACC(JSTaggedValue::False()); + } + DISPATCH(BytecodeInstruction::Format::PREF_NONE); } HANDLE_OPCODE(EXCEPTION_HANDLER) { auto exception = thread->GetException(); @@ -2978,22 +3070,15 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool thread->SetCurrentSPFrame(sp); DISPATCH_OFFSET(0); } - HANDLE_OPCODE(OVERFLOW_HANDLER) { + HANDLE_OPCODE(HANDLE_OVERFLOW) { LOG(FATAL, INTERPRETER) << "opcode overflow"; } #include "templates/debugger_instruction_handler.inl" } -uint8_t EcmaInterpreter::ReadU8(const uint8_t *pc, uint32_t offset) -{ - constexpr uint8_t BIT_8 = 8; - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - return *reinterpret_cast(pc + offset * BIT_8); -} - void EcmaInterpreter::InitStackFrame(JSThread *thread) { - uint64_t *prevSp = thread->GetCurrentSPFrame(); + uint64_t *prevSp = const_cast(thread->GetCurrentSPFrame()); FrameState *state = GET_FRAME(prevSp); state->pc = nullptr; state->sp = nullptr; @@ -3050,23 +3135,23 @@ size_t EcmaInterpreter::GetJumpSizeAfterCall(const uint8_t *prevPc) uint8_t op = *prevPc; size_t jumpSize; switch (op) { - case (EcmaOpcode::CALLARG0DYN_IMM8_V8): - jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::IMM8_V8); + case (EcmaOpcode::CALLARG0DYN_PREF_V8): + jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8); break; - case (EcmaOpcode::CALLARG1DYN_IMM8_V8_V8): - jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::IMM8_V8_V8); + case (EcmaOpcode::CALLARG1DYN_PREF_V8_V8): + jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8); break; - case (EcmaOpcode::CALLARGS2DYN_IMM8_V8_V8_V8): - jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::IMM8_V8_V8_V8); + case (EcmaOpcode::CALLARGS2DYN_PREF_V8_V8_V8): + jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8_V8); break; - case (EcmaOpcode::CALLARGS3DYN_IMM8_V8_V8_V8_V8): - jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::IMM8_V8_V8_V8_V8); + case (EcmaOpcode::CALLARGS3DYN_PREF_V8_V8_V8_V8): + jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8_V8_V8); break; - case (EcmaOpcode::CALLIRANGEDYN_IMM8_IMM16_V8): - jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::IMM16_V16); + case (EcmaOpcode::CALLIRANGEDYN_PREF_IMM16_V8): + jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_IMM16_V8); break; - case (EcmaOpcode::CALLITHISRANGEDYN_IMM8_IMM16_V8): - jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::IMM8_IMM16_V8); + case (EcmaOpcode::CALLITHISRANGEDYN_PREF_IMM16_V8): + jumpSize = BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_IMM16_V8); break; default: UNREACHABLE(); @@ -3082,31 +3167,30 @@ JSTaggedValue EcmaInterpreter::GetRuntimeProfileTypeInfo(TaggedType *sp) return state->profileTypeInfo; } -void EcmaInterpreter::UpdateHotnessCounter(JSThread* thread, TaggedType *sp, int32_t offset) +bool EcmaInterpreter::UpdateHotnessCounter(JSThread* thread, TaggedType *sp, JSTaggedValue acc, int32_t offset) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - FrameState *state = reinterpret_cast(sp) - 1; + FrameState *state = GET_FRAME(sp); auto method = state->method; auto hotnessCounter = static_cast(method->GetHotnessCounter()); - if (offset < 0) { - hotnessCounter += offset; - if (UNLIKELY(hotnessCounter <= 0)) { - if (state->profileTypeInfo == JSTaggedValue::Undefined()) { - auto numVregs = method->GetNumVregs(); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - auto thisFunc = JSTaggedValue(sp[numVregs]); - auto res = SlowRuntimeStub::NotifyInlineCache( - thread, JSFunction::Cast(thisFunc.GetHeapObject()), method); - state->profileTypeInfo = res; - } else { - hotnessCounter = EcmaInterpreter::METHOD_HOTNESS_THRESHOLD; - } + hotnessCounter += offset; + if (UNLIKELY(hotnessCounter <= 0)) { + if (state->profileTypeInfo == JSTaggedValue::Undefined()) { + state->acc = acc; + auto numVregs = method->GetNumVregs(); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + auto thisFunc = JSTaggedValue(sp[numVregs]); + auto res = SlowRuntimeStub::NotifyInlineCache( + thread, JSFunction::Cast(thisFunc.GetHeapObject()), method); + state->profileTypeInfo = res; + method->SetHotnessCounter(std::numeric_limits::max()); + return true; + } else { + hotnessCounter = std::numeric_limits::max(); } - } else { - hotnessCounter += offset; } method->SetHotnessCounter(static_cast(hotnessCounter)); + return false; } #if defined(__clang__) #pragma clang diagnostic pop @@ -3114,4 +3198,4 @@ void EcmaInterpreter::UpdateHotnessCounter(JSThread* thread, TaggedType *sp, int #pragma GCC diagnostic pop #endif } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_INTERPRETER_INL_H +#endif // ECMASCRIPT_INTERPRETER_INTERPRETER_INL_H diff --git a/ecmascript/interpreter/interpreter.h b/ecmascript/interpreter/interpreter.h index d3ba2aa5d1c18b543d723d558efb41896b9ba115..ab6ecb8f6d96ec9dacd035d1a4a9e8e8af1aeb46 100644 --- a/ecmascript/interpreter/interpreter.h +++ b/ecmascript/interpreter/interpreter.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_INTERPRETER_H -#define PANDA_RUNTIME_ECMASCRIPT_INTERPRETER_H +#ifndef ECMASCRIPT_INTERPRETER_INTERPRETER_H +#define ECMASCRIPT_INTERPRETER_INTERPRETER_H #include "ecmascript/js_method.h" #include "ecmascript/js_tagged_value.h" @@ -25,6 +25,7 @@ namespace panda::ecmascript { class ConstantPool; class ECMAObject; class GeneratorContext; +using TaggedType = coretypes::TaggedType; // align with 8 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) @@ -59,7 +60,7 @@ struct CallParams { class EcmaInterpreter { public: - static const uint32_t METHOD_HOTNESS_THRESHOLD = 100 * 1024; + static const uint32_t METHOD_HOTNESS_THRESHOLD = 512; enum ActualNumArgsOfCall : uint8_t { CALLARG0 = 3, CALLARG1, CALLARGS2, CALLARGS3 }; static inline JSTaggedValue Execute(JSThread *thread, const CallParams& params); @@ -74,7 +75,7 @@ public: static inline size_t GetJumpSizeAfterCall(const uint8_t *prevPc); static inline JSTaggedValue GetRuntimeProfileTypeInfo(TaggedType *sp); - static inline void UpdateHotnessCounter(JSThread* thread, TaggedType *sp, int32_t offset); + static inline bool UpdateHotnessCounter(JSThread* thread, TaggedType *sp, JSTaggedValue acc, int32_t offset); static inline void InterpreterFrameCopyArgs(JSTaggedType *newSp, uint32_t numVregs, uint32_t numActualArgs, uint32_t numDeclaredArgs); static inline void NotifyBytecodePcChanged(JSThread *thread); @@ -82,38 +83,139 @@ public: }; enum EcmaOpcode { + LDNAN_PREF, + LDINFINITY_PREF, + LDGLOBALTHIS_PREF, + LDUNDEFINED_PREF, + LDNULL_PREF, + LDSYMBOL_PREF, + LDGLOBAL_PREF, + LDTRUE_PREF, + LDFALSE_PREF, + THROWDYN_PREF, + TYPEOFDYN_PREF, + LDLEXENVDYN_PREF, + POPLEXENVDYN_PREF, + GETUNMAPPEDARGS_PREF, + GETPROPITERATOR_PREF, + ASYNCFUNCTIONENTER_PREF, + LDHOLE_PREF, + RETURNUNDEFINED_PREF, + CREATEEMPTYOBJECT_PREF, + CREATEEMPTYARRAY_PREF, + GETITERATOR_PREF, + THROWTHROWNOTEXISTS_PREF, + THROWPATTERNNONCOERCIBLE_PREF, + LDHOMEOBJECT_PREF, + THROWDELETESUPERPROPERTY_PREF, + DEBUGGER_PREF, + ADD2DYN_PREF_V8, + SUB2DYN_PREF_V8, + MUL2DYN_PREF_V8, + DIV2DYN_PREF_V8, + MOD2DYN_PREF_V8, + EQDYN_PREF_V8, + NOTEQDYN_PREF_V8, + LESSDYN_PREF_V8, + LESSEQDYN_PREF_V8, + GREATERDYN_PREF_V8, + GREATEREQDYN_PREF_V8, + SHL2DYN_PREF_V8, + SHR2DYN_PREF_V8, + ASHR2DYN_PREF_V8, + AND2DYN_PREF_V8, + OR2DYN_PREF_V8, + XOR2DYN_PREF_V8, + TONUMBER_PREF_V8, + NEGDYN_PREF_V8, + NOTDYN_PREF_V8, + INCDYN_PREF_V8, + DECDYN_PREF_V8, + EXPDYN_PREF_V8, + ISINDYN_PREF_V8, + INSTANCEOFDYN_PREF_V8, + STRICTNOTEQDYN_PREF_V8, + STRICTEQDYN_PREF_V8, + RESUMEGENERATOR_PREF_V8, + GETRESUMEMODE_PREF_V8, + CREATEGENERATOROBJ_PREF_V8, + THROWCONSTASSIGNMENT_PREF_V8, + GETTEMPLATEOBJECT_PREF_V8, + GETNEXTPROPNAME_PREF_V8, + CALLARG0DYN_PREF_V8, + THROWIFNOTOBJECT_PREF_V8, + ITERNEXT_PREF_V8, + CLOSEITERATOR_PREF_V8, + COPYMODULE_PREF_V8, + SUPERCALLSPREAD_PREF_V8, + DELOBJPROP_PREF_V8_V8, + NEWOBJSPREADDYN_PREF_V8_V8, + CREATEITERRESULTOBJ_PREF_V8_V8, + SUSPENDGENERATOR_PREF_V8_V8, + ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8, + THROWUNDEFINEDIFHOLE_PREF_V8_V8, + CALLARG1DYN_PREF_V8_V8, + COPYDATAPROPERTIES_PREF_V8_V8, + STARRAYSPREAD_PREF_V8_V8, + GETITERATORNEXT_PREF_V8_V8, + SETOBJECTWITHPROTO_PREF_V8_V8, + LDOBJBYVALUE_PREF_V8_V8, + STOBJBYVALUE_PREF_V8_V8, + STOWNBYVALUE_PREF_V8_V8, + LDSUPERBYVALUE_PREF_V8_V8, + STSUPERBYVALUE_PREF_V8_V8, + LDOBJBYINDEX_PREF_V8_IMM32, + STOBJBYINDEX_PREF_V8_IMM32, + STOWNBYINDEX_PREF_V8_IMM32, + CALLSPREADDYN_PREF_V8_V8_V8, + ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8, + ASYNCFUNCTIONREJECT_PREF_V8_V8_V8, + CALLARGS2DYN_PREF_V8_V8_V8, + CALLARGS3DYN_PREF_V8_V8_V8_V8, + DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8, + NEWOBJDYNRANGE_PREF_IMM16_V8, + CALLIRANGEDYN_PREF_IMM16_V8, + CALLITHISRANGEDYN_PREF_IMM16_V8, + SUPERCALL_PREF_IMM16_V8, + CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8, + DEFINEFUNCDYN_PREF_ID16_IMM16_V8, + DEFINENCFUNCDYN_PREF_ID16_IMM16_V8, + DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8, + DEFINEASYNCFUNC_PREF_ID16_IMM16_V8, + DEFINEMETHOD_PREF_ID16_IMM16_V8, + NEWLEXENVDYN_PREF_IMM16, + COPYRESTARGS_PREF_IMM16, + CREATEARRAYWITHBUFFER_PREF_IMM16, + CREATEOBJECTHAVINGMETHOD_PREF_IMM16, + THROWIFSUPERNOTCORRECTCALL_PREF_IMM16, + CREATEOBJECTWITHBUFFER_PREF_IMM16, + LDLEXVARDYN_PREF_IMM4_IMM4, + LDLEXVARDYN_PREF_IMM8_IMM8, + LDLEXVARDYN_PREF_IMM16_IMM16, + STLEXVARDYN_PREF_IMM4_IMM4_V8, + STLEXVARDYN_PREF_IMM8_IMM8_V8, + STLEXVARDYN_PREF_IMM16_IMM16_V8, + DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8, + IMPORTMODULE_PREF_ID32, + STMODULEVAR_PREF_ID32, + TRYLDGLOBALBYNAME_PREF_ID32, + TRYSTGLOBALBYNAME_PREF_ID32, + LDGLOBALVAR_PREF_ID32, + STGLOBALVAR_PREF_ID32, + LDOBJBYNAME_PREF_ID32_V8, + STOBJBYNAME_PREF_ID32_V8, + STOWNBYNAME_PREF_ID32_V8, + LDSUPERBYNAME_PREF_ID32_V8, + STSUPERBYNAME_PREF_ID32_V8, + LDMODVARBYNAME_PREF_ID32_V8, + CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8, + ISTRUE_PREF, + ISFALSE_PREF, MOV_DYN_V8_V8, MOV_DYN_V16_V16, LDA_STR_ID32, LDAI_DYN_IMM32, FLDAI_DYN_IMM64, - LDNAN_IMM8, - LDINFINITY_IMM8, - LDGLOBALTHIS_IMM8, - LDUNDEFINED_IMM8, - LDNULL_IMM8, - LDSYMBOL_IMM8, - LDGLOBAL_IMM8, - LDTRUE_IMM8, - LDFALSE_IMM8, - THROWDYN_IMM8, - TYPEOFDYN_IMM8, - LDLEXENVDYN_IMM8, - POPLEXENVDYN_IMM8, - GETUNMAPPEDARGS_IMM8, - TOBOOLEAN_IMM8, - GETPROPITERATOR_IMM8, - ASYNCFUNCTIONENTER_IMM8, - LDHOLE_IMM8, - RETURNUNDEFINED_IMM8, - CREATEEMPTYOBJECT_IMM8, - CREATEEMPTYARRAY_IMM8, - GETITERATOR_IMM8, - THROWTHROWNOTEXISTS_IMM8, - THROWPATTERNNONCOERCIBLE_IMM8, - LDHOMEOBJECT_IMM8, - THROWDELETESUPERPROPERTY_IMM8, - DEBUGGER_IMM8, JMP_IMM8, JMP_IMM16, JMP_IMM32, @@ -121,115 +223,6 @@ enum EcmaOpcode { JEQZ_IMM16, LDA_DYN_V8, STA_DYN_V8, - LDBOOLEAN_IMM8_V8, - LDNUMBER_IMM8_V8, - LDSTRING_IMM8_V8, - LDBIGINT_IMM8_V8, - ADD2DYN_IMM8_V8, - SUB2DYN_IMM8_V8, - MUL2DYN_IMM8_V8, - DIV2DYN_IMM8_V8, - MOD2DYN_IMM8_V8, - EQDYN_IMM8_V8, - NOTEQDYN_IMM8_V8, - LESSDYN_IMM8_V8, - LESSEQDYN_IMM8_V8, - GREATERDYN_IMM8_V8, - GREATEREQDYN_IMM8_V8, - SHL2DYN_IMM8_V8, - SHR2DYN_IMM8_V8, - ASHR2DYN_IMM8_V8, - AND2DYN_IMM8_V8, - OR2DYN_IMM8_V8, - XOR2DYN_IMM8_V8, - TONUMBER_IMM8_V8, - NEGDYN_IMM8_V8, - NOTDYN_IMM8_V8, - INCDYN_IMM8_V8, - DECDYN_IMM8_V8, - EXPDYN_IMM8_V8, - ISINDYN_IMM8_V8, - INSTANCEOFDYN_IMM8_V8, - STRICTNOTEQDYN_IMM8_V8, - STRICTEQDYN_IMM8_V8, - RESUMEGENERATOR_IMM8_V8, - GETRESUMEMODE_IMM8_V8, - CREATEGENERATOROBJ_IMM8_V8, - THROWUNDEFINED_IMM8_V8, - THROWCONSTASSIGNMENT_IMM8_V8, - GETTEMPLATEOBJECT_IMM8_V8, - GETNEXTPROPNAME_IMM8_V8, - CALLARG0DYN_IMM8_V8, - THROWIFNOTOBJECT_IMM8_V8, - ITERNEXT_IMM8_V8, - CLOSEITERATOR_IMM8_V8, - COPYMODULE_IMM8_V8, - SUPERCALLSPREAD_IMM8_V8, - LDOBJECT_IMM8_V8_V8, - LDFUNCTION_IMM8_V8_V8, - DELOBJPROP_IMM8_V8_V8, - DEFINEGLOBALVAR_IMM8_V8_V8, - DEFINELOCALVAR_IMM8_V8_V8, - DEFINEFUNCEXPR_IMM8_V8_V8, - REFEQDYN_IMM8_V8_V8, - CALLRUNTIMERANGE_IMM8_V8_V8, - NEWOBJSPREADDYN_IMM8_V8_V8, - CREATEITERRESULTOBJ_IMM8_V8_V8, - SUSPENDGENERATOR_IMM8_V8_V8, - ASYNCFUNCTIONAWAITUNCAUGHT_IMM8_V8_V8, - THROWUNDEFINEDIFHOLE_IMM8_V8_V8, - CALLARG1DYN_IMM8_V8_V8, - COPYDATAPROPERTIES_IMM8_V8_V8, - STARRAYSPREAD_IMM8_V8_V8, - GETITERATORNEXT_IMM8_V8_V8, - SETOBJECTWITHPROTO_IMM8_V8_V8, - CALLSPREADDYN_IMM8_V8_V8_V8, - ASYNCFUNCTIONRESOLVE_IMM8_V8_V8_V8, - ASYNCFUNCTIONREJECT_IMM8_V8_V8_V8, - CALLARGS2DYN_IMM8_V8_V8_V8, - CALLARGS3DYN_IMM8_V8_V8_V8_V8, - DEFINEGETTERSETTERBYVALUE_IMM8_V8_V8_V8_V8, - TRYLDGLOBALBYVALUE_IMM8_IMM16_V8, - NEWOBJDYNRANGE_IMM8_IMM16_V8, - TRYSTGLOBALBYVALUE_IMM8_IMM16_V8, - CALLIRANGEDYN_IMM8_IMM16_V8, - CALLITHISRANGEDYN_IMM8_IMM16_V8, - SUPERCALL_IMM8_IMM16_V8, - LDOBJBYVALUE_IMM8_IMM16_V8_V8, - STOBJBYVALUE_IMM8_IMM16_V8_V8, - LDOBJBYINDEX_IMM8_IMM16_V8_V8, - STOBJBYINDEX_IMM8_IMM16_V8_V8, - STOWNBYINDEX_IMM8_IMM16_V8_V8, - STOWNBYVALUE_IMM8_IMM16_V8_V8, - CREATEOBJECTWITHEXCLUDEDKEYS_IMM8_IMM16_V8_V8, - STSUPERBYVALUE_IMM8_IMM16_V8_V8, - LDSUPERBYVALUE_IMM8_IMM16_V8_V8, - IMPORTMODULE_IMM8_ID32, - STMODULEVAR_IMM8_ID32, - DEFINEFUNCDYN_IMM8_ID16_V8, - DEFINENCFUNCDYN_IMM8_ID16_V8, - DEFINEGENERATORFUNC_IMM8_ID16_V8, - DEFINEASYNCFUNC_IMM8_ID16_V8, - DEFINEMETHOD_IMM8_ID16_V8, - TRYLDGLOBALBYNAME_IMM8_ID32_IMM16, - TRYSTGLOBALBYNAME_IMM8_ID32_IMM16, - LDGLOBALVAR_IMM8_ID32_IMM16, - STGLOBALVAR_IMM8_ID32_IMM16, - LDOBJBYNAME_IMM8_ID32_IMM16_V8, - STOBJBYNAME_IMM8_ID32_IMM16_V8, - STOWNBYNAME_IMM8_ID32_IMM16_V8, - LDMODVARBYNAME_IMM8_ID32_IMM16_V8, - LDSUPERBYNAME_IMM8_ID32_IMM16_V8, - STSUPERBYNAME_IMM8_ID32_IMM16_V8, - STLEXVARDYN_IMM8_IMM16_IMM16_V8, - LDLEXVARDYN_IMM8_IMM16_IMM16, - NEWLEXENVDYN_IMM8_IMM16, - COPYRESTARGS_IMM8_IMM16, - CREATEOBJECTWITHBUFFER_IMM8_IMM16, - CREATEARRAYWITHBUFFER_IMM8_IMM16, - CREATEOBJECTHAVINGMETHOD_IMM8_IMM16, - THROWIFSUPERNOTCORRECTCALL_IMM8_IMM16, - DEFINECLASSWITHBUFFER_IMM8_ID16_IMM16_V8_V8, RETURN_DYN, MOV_V4_V4, JNEZ_IMM8, @@ -237,4 +230,4 @@ enum EcmaOpcode { LAST_OPCODE, }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_INTERPRETER_H +#endif // ECMASCRIPT_INTERPRETER_INTERPRETER_H diff --git a/ecmascript/interpreter/slow_runtime_helper.cpp b/ecmascript/interpreter/slow_runtime_helper.cpp index c70d6b694ca67d15a62264b17904c09276ad7319..4d89e3df16226072199b2fa40905a00a2d0c8212 100644 --- a/ecmascript/interpreter/slow_runtime_helper.cpp +++ b/ecmascript/interpreter/slow_runtime_helper.cpp @@ -15,6 +15,7 @@ #include "slow_runtime_helper.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/frame_handler.h" #include "ecmascript/interpreter/interpreter-inl.h" #include "ecmascript/js_generator_object.h" @@ -24,37 +25,23 @@ #include "ecmascript/tagged_array-inl.h" namespace panda::ecmascript { -JSTaggedValue SlowRuntimeHelper::CallBoundFunction(JSThread *thread, JSHandle boundFunc, - JSHandle obj, JSHandle args) +JSTaggedValue SlowRuntimeHelper::CallBoundFunction(JSThread *thread, + JSHandle boundFunc, JSHandle obj) { - uint32_t numArgsReal = args->GetLength(); - - JSHandle argsBound(thread, boundFunc->GetBoundArguments()); - uint32_t numArgsBound = argsBound->GetLength(); - JSHandle targetFunc(thread, boundFunc->GetBoundTarget()); if (targetFunc->IsClassConstructor()) { THROW_TYPE_ERROR_AND_RETURN(thread, "class constructor cannot called without 'new'", JSTaggedValue::Exception()); } - uint32_t arraySize = numArgsBound + numArgsReal; - JSHandle argsNew = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(arraySize); - - uint32_t idx = 0; - for (uint32_t i = 0; i < numArgsBound; i++) { - argsNew->Set(thread, idx++, argsBound->Get(i)); - } - for (uint32_t i = 0; i < numArgsReal; i++) { - argsNew->Set(thread, idx++, args->Get(i)); - } - + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeBoundArgv(thread, boundFunc); JSHandle newTarget(thread, JSTaggedValue::Undefined()); - return InvokeJsFunction(thread, targetFunc, obj, newTarget, argsNew); + return InvokeJsFunction(thread, targetFunc, obj, newTarget, arguments); } JSTaggedValue SlowRuntimeHelper::NewObject(JSThread *thread, JSHandle func, - JSHandle newTarget, JSHandle args) + JSHandle newTarget, uint32_t argc, const JSTaggedType argv[]) { if (!func->IsHeapObject()) { THROW_TYPE_ERROR_AND_RETURN(thread, "function is nullptr", JSTaggedValue::Exception()); @@ -63,13 +50,13 @@ JSTaggedValue SlowRuntimeHelper::NewObject(JSThread *thread, JSHandleIsJSFunction()) { if (func->IsBoundFunction()) { JSTaggedValue result = - JSBoundFunction::ConstructInternal(thread, JSHandle::Cast(func), args, newTarget); + JSBoundFunction::ConstructInternal(thread, JSHandle::Cast(func), newTarget); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return result; } if (func->IsJSProxy()) { - JSTaggedValue jsObj = JSProxy::ConstructInternal(thread, JSHandle(func), args, newTarget); + JSTaggedValue jsObj = JSProxy::ConstructInternal(thread, JSHandle(func), argc, argv, newTarget); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return jsObj; } @@ -83,12 +70,12 @@ JSTaggedValue SlowRuntimeHelper::NewObject(JSThread *thread, JSHandleGetCallTarget()->IsNative()) { if (jsFunc->IsBuiltinsConstructor()) { return InvokeJsFunction(thread, jsFunc, JSHandle(thread, JSTaggedValue::Undefined()), - newTarget, args); + newTarget, thread->GetInternalCallParams()); } THROW_TYPE_ERROR_AND_RETURN(thread, "Constructed NonConstructable", JSTaggedValue::Exception()); } - JSTaggedValue result = JSFunction::ConstructInternal(thread, jsFunc, args, newTarget); + JSTaggedValue result = JSFunction::ConstructInternal(thread, jsFunc, argc, argv, newTarget); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return result; } @@ -241,12 +228,10 @@ JSTaggedValue ConstructProxy(JSThread *thread, JSHandle ctor, JSHandle< } // step 8 ~ 9 Call(trap, handler, «target, argArray, newTarget »). - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle nextArgv(factory->NewTaggedArray(3)); // 3: «target, argArray, newTarget » - nextArgv->Set(thread, 0, target.GetTaggedValue()); - nextArgv->Set(thread, 1, args.GetTaggedValue()); - nextArgv->Set(thread, 2, newTgt.GetTaggedValue()); // 2: the third arg is new target - JSTaggedValue newObjValue = JSFunction::Call(thread, method, handler, nextArgv); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(target, JSHandle(args), newTgt); + JSTaggedValue newObjValue = + JSFunction::Call(thread, method, handler, 3, arguments->GetArgv()); // 3: «target, argArray, newTarget » // 10.ReturnIfAbrupt(newObj). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 11.If Type(newObj) is not Object, throw a TypeError exception. diff --git a/ecmascript/interpreter/slow_runtime_helper.h b/ecmascript/interpreter/slow_runtime_helper.h index c82a6da8d90c12982c1b3a22d6f3a31809552fe7..effdd504eebc0faf612ef6916ea025a52a686470 100644 --- a/ecmascript/interpreter/slow_runtime_helper.h +++ b/ecmascript/interpreter/slow_runtime_helper.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_SLOW_RUNTIME_HELPER_H -#define PANDA_RUNTIME_ECMASCRIPT_SLOW_RUNTIME_HELPER_H +#ifndef ECMASCRIPT_INTERPRETER_SLOW_RUNTIME_HELPER_H +#define ECMASCRIPT_INTERPRETER_SLOW_RUNTIME_HELPER_H #include "ecmascript/js_function.h" #include "ecmascript/js_thread.h" @@ -24,10 +24,10 @@ namespace panda::ecmascript { class SlowRuntimeHelper { public: static JSTaggedValue NewObject(JSThread *thread, JSHandle func, JSHandle newTarget, - JSHandle args); + uint32_t argc, const JSTaggedType argv[]); static JSTaggedValue CallBoundFunction(JSThread *thread, JSHandle boundFunc, - JSHandle obj, JSHandle args); + JSHandle obj); static void SaveFrameToContext(JSThread *thread, JSHandle context); @@ -36,4 +36,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_SLOW_RUNTIME_HELPER_H +#endif // ECMASCRIPT_INTERPRETER_SLOW_RUNTIME_HELPER_H diff --git a/ecmascript/interpreter/slow_runtime_stub.cpp b/ecmascript/interpreter/slow_runtime_stub.cpp index 8e5c86d631c12beda922fb63408732cd1f3e85ab..405dd0c092cd46fd71e43bcc1e2c67e6add5fba3 100644 --- a/ecmascript/interpreter/slow_runtime_stub.cpp +++ b/ecmascript/interpreter/slow_runtime_stub.cpp @@ -16,11 +16,12 @@ #include "ecmascript/interpreter/slow_runtime_stub.h" #include "ecmascript/base/number_helper.h" - +#include "ecmascript/builtins/builtins_regexp.h" #include "ecmascript/class_linker/program_object-inl.h" #include "ecmascript/ecma_module.h" #include "ecmascript/global_dictionary-inl.h" #include "ecmascript/ic/profile_type_info.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/fast_runtime_stub-inl.h" #include "ecmascript/interpreter/slow_runtime_helper.h" #include "ecmascript/js_arguments.h" @@ -55,9 +56,10 @@ JSTaggedValue SlowRuntimeStub::CallSpreadDyn(JSThread *thread, JSTaggedValue fun JSHandle taggedObj(thread, obj); JSHandle coretypesArray(thread, GetCallSpreadArgs(thread, jsArray.GetTaggedValue())); - + InternalCallParams *params = thread->GetInternalCallParams(); + params->MakeArgList(*coretypesArray); JSHandle newTarget(thread, JSTaggedValue::Undefined()); - JSTaggedValue res = InvokeJsFunction(thread, jsFunc, taggedObj, newTarget, coretypesArray); + JSTaggedValue res = InvokeJsFunction(thread, jsFunc, taggedObj, newTarget, params); return res; } @@ -177,7 +179,7 @@ void SlowRuntimeStub::ThrowConstAssignment(JSThread *thread, JSTaggedValue value ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle name(thread, value.GetTaggedObject()); - JSHandle info = factory->NewFromString("Assignment to const variable "); + JSHandle info = factory->NewFromCanBeCompressString("Assignment to const variable "); JSHandle msg = factory->ConcatFromString(info, name); THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::TYPE_ERROR, msg).GetTaggedValue()); @@ -619,7 +621,6 @@ JSTaggedValue SlowRuntimeStub::AsyncFunctionResolveOrReject(JSThread *thread, JS INTERPRETER_TRACE(thread, AsyncFunctionResolveOrReject); [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle asyncFuncObjHandle(thread, asyncFuncObj); JSHandle promise(thread, asyncFuncObjHandle->GetPromise()); JSHandle valueHandle(thread, value); @@ -628,15 +629,15 @@ JSTaggedValue SlowRuntimeStub::AsyncFunctionResolveOrReject(JSThread *thread, JS JSHandle reactions = JSPromise::CreateResolvingFunctions(thread, promise); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); JSHandle thisArg = globalConst->GetHandledUndefined(); - JSHandle args = factory->NewTaggedArray(1); - args->Set(thread, 0, value); JSHandle activeFunc; if (is_resolve) { activeFunc = JSHandle(thread, reactions->GetResolveFunction()); } else { activeFunc = JSHandle(thread, reactions->GetRejectFunction()); } - [[maybe_unused]] JSTaggedValue res = JSFunction::Call(thread, activeFunc, thisArg, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(valueHandle); + [[maybe_unused]] JSTaggedValue res = JSFunction::Call(thread, activeFunc, thisArg, 1, arguments->GetArgv()); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return promise.GetTaggedValue(); @@ -663,7 +664,9 @@ JSTaggedValue SlowRuntimeStub::NewObjSpreadDyn(JSThread *thread, JSTaggedValue f argsArray->Set(thread, i, prop); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); } - auto tagged = SlowRuntimeHelper::NewObject(thread, funcHandle, newTargetHandle, argsArray); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgList(*argsArray); + auto tagged = SlowRuntimeHelper::NewObject(thread, funcHandle, newTargetHandle, length, arguments->GetArgv()); return tagged; } @@ -673,7 +676,7 @@ void SlowRuntimeStub::ThrowUndefinedIfHole(JSThread *thread, JSTaggedValue obj) ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle name(thread, obj); - JSHandle info = factory->NewFromString(" is not initialized"); + JSHandle info = factory->NewFromCanBeCompressString(" is not initialized"); JSHandle msg = factory->ConcatFromString(info, name); THROW_NEW_ERROR_AND_RETURN(thread, factory->NewJSError(base::ErrorType::REFERENCE_ERROR, msg).GetTaggedValue()); @@ -736,13 +739,13 @@ JSTaggedValue SlowRuntimeStub::StOwnByName(JSThread *thread, JSTaggedValue obj, return JSTaggedValue::True(); } -JSTaggedValue SlowRuntimeStub::StOwnByIndex(JSThread *thread, JSTaggedValue obj, JSTaggedValue idx, JSTaggedValue value) +JSTaggedValue SlowRuntimeStub::StOwnByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, JSTaggedValue value) { INTERPRETER_TRACE(thread, StOwnByIdDyn); [[maybe_unused]] EcmaHandleScope handleScope(thread); JSHandle objHandle(thread, obj); - JSHandle idxHandle(thread, idx); + JSHandle idxHandle(thread, JSTaggedValue(idx)); JSHandle valueHandle(thread, value); // property in class is non-enumerable @@ -917,6 +920,45 @@ JSTaggedValue SlowRuntimeStub::LdModvarByName([[maybe_unused]] JSThread *thread, return moduleVar.GetTaggedValue(); } +JSTaggedValue SlowRuntimeStub::CreateRegExpWithLiteral(JSThread *thread, JSTaggedValue pattern, uint8_t flags) +{ + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle patternHandle(thread, pattern); + uint8_t *flagsStr = new uint8_t[7]; // 7: maximum 6 flags + '\0' + size_t flagsLen = 0; + if (flags & RegExpParser::FLAG_GLOBAL) { + flagsStr[flagsLen] = 'g'; + flagsLen++; + } + if (flags & RegExpParser::FLAG_IGNORECASE) { + flagsStr[flagsLen] = 'i'; + flagsLen++; + } + if (flags & RegExpParser::FLAG_MULTILINE) { + flagsStr[flagsLen] = 'm'; + flagsLen++; + } + if (flags & RegExpParser::FLAG_DOTALL) { + flagsStr[flagsLen] = 's'; + flagsLen++; + } + if (flags & RegExpParser::FLAG_UTF16) { + flagsStr[flagsLen] = 'u'; + flagsLen++; + } + if (flags & RegExpParser::FLAG_STICKY) { + flagsStr[flagsLen] = 'y'; + flagsLen++; + } + flagsStr[flagsLen] = '\0'; + JSHandle flagsHandle(factory->NewFromUtf8(flagsStr, flagsLen)); + delete[] flagsStr; + + return builtins::BuiltinsRegExp::RegExpCreate(thread, patternHandle, flagsHandle); +} + JSTaggedValue SlowRuntimeStub::CreateArrayWithBuffer(JSThread *thread, ObjectFactory *factory, JSArray *literal) { [[maybe_unused]] EcmaHandleScope handleScope(thread); @@ -981,14 +1023,11 @@ JSTaggedValue SlowRuntimeStub::GetIteratorNext(JSThread *thread, JSTaggedValue o { [[maybe_unused]] EcmaHandleScope handleScope(thread); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle iter(thread, obj); JSHandle next(thread, method); - JSHandle argv(factory->EmptyArray()); ASSERT(next->IsCallable()); - JSTaggedValue ret = JSFunction::Call(thread, next, iter, argv); + JSTaggedValue ret = JSFunction::Call(thread, next, iter, 0, nullptr); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); if (!ret.IsECMAObject()) { return ThrowTypeError(thread, "the Iterator is not an ecmaobject."); @@ -1077,8 +1116,9 @@ JSTaggedValue SlowRuntimeStub::GetIterator(JSThread *thread, JSTaggedValue obj) return valuesFunc.GetTaggedValue(); } JSHandle newTarget(thread, JSTaggedValue::Undefined()); - JSHandle args = vm->GetFactory()->EmptyArray(); - JSTaggedValue res = InvokeJsFunction(thread, JSHandle(valuesFunc), objHandle, newTarget, args); + InternalCallParams *params = thread->GetInternalCallParams(); + params->MakeEmptyArgv(); + JSTaggedValue res = InvokeJsFunction(thread, JSHandle(valuesFunc), objHandle, newTarget, params); return res; } @@ -1140,7 +1180,7 @@ JSTaggedValue SlowRuntimeStub::DefineGetterSetterByValue(JSThread *thread, JSTag return objHandle.GetTaggedValue(); } -JSTaggedValue SlowRuntimeStub::LdObjByIndex(JSThread *thread, JSTaggedValue obj, JSTaggedValue idx, bool callGetter, +JSTaggedValue SlowRuntimeStub::LdObjByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, bool callGetter, JSTaggedValue receiver) { INTERPRETER_TRACE(thread, LdObjByIndexDyn); @@ -1151,18 +1191,18 @@ JSTaggedValue SlowRuntimeStub::LdObjByIndex(JSThread *thread, JSTaggedValue obj, if (callGetter) { res = JSObject::CallGetter(thread, AccessorData::Cast(receiver.GetTaggedObject()), objHandle); } else { - res = JSTaggedValue::GetProperty(thread, objHandle, idx.GetArrayLength()).GetValue().GetTaggedValue(); + res = JSTaggedValue::GetProperty(thread, objHandle, idx).GetValue().GetTaggedValue(); } RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return res; } -JSTaggedValue SlowRuntimeStub::StObjByIndex(JSThread *thread, JSTaggedValue obj, JSTaggedValue idx, JSTaggedValue value) +JSTaggedValue SlowRuntimeStub::StObjByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, JSTaggedValue value) { INTERPRETER_TRACE(thread, StObjByIndexDyn); [[maybe_unused]] EcmaHandleScope handleScope(thread); - JSTaggedValue::SetProperty(thread, JSHandle(thread, obj), idx.GetArrayLength(), + JSTaggedValue::SetProperty(thread, JSHandle(thread, obj), idx, JSHandle(thread, value), true); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return JSTaggedValue::True(); @@ -1531,8 +1571,7 @@ JSTaggedValue SlowRuntimeStub::DefineClass(JSThread *thread, JSFunction *func, T if (!JSTaggedValue::HasOwnProperty(thread, cls, globalConst->GetHandledNameString())) { JSMethod *clsTarget = JSHandle::Cast(cls)->GetCallTarget(); ASSERT(clsTarget != nullptr); - CString clsName( - utf::Mutf8AsCString(clsTarget->GetStringDataAnnotation(Method::AnnotationField::FUNCTION_NAME).data)); + CString clsName = clsTarget->ParseFunctionName(); if (!clsName.empty()) { success = success && JSFunction::SetFunctionName(thread, JSHandle(cls), @@ -1566,7 +1605,9 @@ JSTaggedValue SlowRuntimeStub::SuperCall(JSThread *thread, JSTaggedValue func, J for (size_t i = 0; i < length; ++i) { argv->Set(thread, i, frameHandler.GetVRegValue(firstVRegIdx + i)); } - JSTaggedValue result = JSFunction::Construct(thread, superFunc, argv, newTargetHandle); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgList(*argv); + JSTaggedValue result = JSFunction::Construct(thread, superFunc, length, arguments->GetArgv(), newTargetHandle); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return result; @@ -1586,7 +1627,10 @@ JSTaggedValue SlowRuntimeStub::SuperCallSpread(JSThread *thread, JSTaggedValue f ASSERT(superFunc->IsJSFunction()); JSHandle argv(thread, GetCallSpreadArgs(thread, jsArray.GetTaggedValue())); - JSTaggedValue result = JSFunction::Construct(thread, superFunc, argv, newTargetHandle); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgList(*argv); + JSTaggedValue result = + JSFunction::Construct(thread, superFunc, argv->GetLength(), arguments->GetArgv(), newTargetHandle); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return result; @@ -1692,15 +1736,14 @@ void SlowRuntimeStub::ThrowDeleteSuperProperty(JSThread *thread) [[maybe_unused]] EcmaHandleScope handleScope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle info = factory->NewFromString("Can not delete super property"); + JSHandle info = factory->NewFromCanBeCompressString("Can not delete super property"); JSHandle errorObj = factory->NewJSError(base::ErrorType::REFERENCE_ERROR, info); THROW_NEW_ERROR_AND_RETURN(thread, errorObj.GetTaggedValue()); } JSTaggedValue SlowRuntimeStub::NotifyInlineCache(JSThread *thread, JSFunction *func, JSMethod *method) { - // use vtable index as ic Size - uint32_t icSlotSize = method->GetNumericalAnnotation(JSMethod::AnnotationField::IC_SIZE); + uint32_t icSlotSize = method->GetSlotSize(); if (icSlotSize > 0 && icSlotSize < ProfileTypeInfo::INVALID_SLOT_INDEX) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); [[maybe_unused]] EcmaHandleScope handleScope(thread); diff --git a/ecmascript/interpreter/slow_runtime_stub.h b/ecmascript/interpreter/slow_runtime_stub.h index b67e7d3fc39684b432e6fc591e47f971962fad7f..32b5704db30e65f0924de6fbebb3ad2772e930f5 100644 --- a/ecmascript/interpreter/slow_runtime_stub.h +++ b/ecmascript/interpreter/slow_runtime_stub.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_SLOW_RUNTIME_STUB_H -#define PANDA_RUNTIME_ECMASCRIPT_SLOW_RUNTIME_STUB_H +#ifndef ECMASCRIPT_INTERPRETER_SLOW_RUNTIME_STUB_H +#define ECMASCRIPT_INTERPRETER_SLOW_RUNTIME_STUB_H #include "ecmascript/js_tagged_value.h" #include "ecmascript/js_thread.h" @@ -79,7 +79,7 @@ public: static void ThrowDeleteSuperProperty(JSThread *thread); static JSTaggedValue StOwnByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, JSTaggedValue value); - static JSTaggedValue StOwnByIndex(JSThread *thread, JSTaggedValue obj, JSTaggedValue idx, JSTaggedValue value); + static JSTaggedValue StOwnByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, JSTaggedValue value); static JSTaggedValue StOwnByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, JSTaggedValue value); static JSTaggedValue CreateEmptyArray(JSThread *thread, ObjectFactory *factory, JSHandle globalEnv); static JSTaggedValue CreateEmptyObject(JSThread *thread, ObjectFactory *factory, JSHandle globalEnv); @@ -102,14 +102,15 @@ public: static void StModuleVar(JSThread *thread, JSTaggedValue exportName, JSTaggedValue exportObj); static void CopyModule(JSThread *thread, JSTaggedValue srcModule); static JSTaggedValue LdModvarByName(JSThread *thread, JSTaggedValue moduleObj, JSTaggedValue itemName); + static JSTaggedValue CreateRegExpWithLiteral(JSThread *thread, JSTaggedValue pattern, uint8_t flags); static JSTaggedValue GetIteratorNext(JSThread *thread, JSTaggedValue obj, JSTaggedValue method); static JSTaggedValue DefineGetterSetterByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, JSTaggedValue getter, JSTaggedValue setter, bool flag); - static JSTaggedValue LdObjByIndex(JSThread *thread, JSTaggedValue obj, JSTaggedValue idx, bool callGetter, + static JSTaggedValue LdObjByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, bool callGetter, JSTaggedValue receiver); - static JSTaggedValue StObjByIndex(JSThread *thread, JSTaggedValue obj, JSTaggedValue idx, JSTaggedValue value); + static JSTaggedValue StObjByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, JSTaggedValue value); static JSTaggedValue LdObjByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, bool callGetter, JSTaggedValue receiver); static JSTaggedValue StObjByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, JSTaggedValue value); @@ -147,4 +148,4 @@ private: static JSTaggedValue GetCallSpreadArgs(JSThread *thread, JSTaggedValue array); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_SLOW_RUNTIME_STUB_H +#endif // ECMASCRIPT_INTERPRETER_SLOW_RUNTIME_STUB_H diff --git a/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl b/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl index e27787db30dbd5b9711df033c485e265372bf957..c9111ef78f4e001d8dd53f23988de2b2ca7affbd 100644 --- a/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl @@ -13,38 +13,139 @@ * limitations under the License. */ + &&DEBUG_HANDLE_LDNAN_PREF, + &&DEBUG_HANDLE_LDINFINITY_PREF, + &&DEBUG_HANDLE_LDGLOBALTHIS_PREF, + &&DEBUG_HANDLE_LDUNDEFINED_PREF, + &&DEBUG_HANDLE_LDNULL_PREF, + &&DEBUG_HANDLE_LDSYMBOL_PREF, + &&DEBUG_HANDLE_LDGLOBAL_PREF, + &&DEBUG_HANDLE_LDTRUE_PREF, + &&DEBUG_HANDLE_LDFALSE_PREF, + &&DEBUG_HANDLE_THROWDYN_PREF, + &&DEBUG_HANDLE_TYPEOFDYN_PREF, + &&DEBUG_HANDLE_LDLEXENVDYN_PREF, + &&DEBUG_HANDLE_POPLEXENVDYN_PREF, + &&DEBUG_HANDLE_GETUNMAPPEDARGS_PREF, + &&DEBUG_HANDLE_GETPROPITERATOR_PREF, + &&DEBUG_HANDLE_ASYNCFUNCTIONENTER_PREF, + &&DEBUG_HANDLE_LDHOLE_PREF, + &&DEBUG_HANDLE_RETURNUNDEFINED_PREF, + &&DEBUG_HANDLE_CREATEEMPTYOBJECT_PREF, + &&DEBUG_HANDLE_CREATEEMPTYARRAY_PREF, + &&DEBUG_HANDLE_GETITERATOR_PREF, + &&DEBUG_HANDLE_THROWTHROWNOTEXISTS_PREF, + &&DEBUG_HANDLE_THROWPATTERNNONCOERCIBLE_PREF, + &&DEBUG_HANDLE_LDHOMEOBJECT_PREF, + &&DEBUG_HANDLE_THROWDELETESUPERPROPERTY_PREF, + &&DEBUG_HANDLE_DEBUGGER_PREF, + &&DEBUG_HANDLE_ADD2DYN_PREF_V8, + &&DEBUG_HANDLE_SUB2DYN_PREF_V8, + &&DEBUG_HANDLE_MUL2DYN_PREF_V8, + &&DEBUG_HANDLE_DIV2DYN_PREF_V8, + &&DEBUG_HANDLE_MOD2DYN_PREF_V8, + &&DEBUG_HANDLE_EQDYN_PREF_V8, + &&DEBUG_HANDLE_NOTEQDYN_PREF_V8, + &&DEBUG_HANDLE_LESSDYN_PREF_V8, + &&DEBUG_HANDLE_LESSEQDYN_PREF_V8, + &&DEBUG_HANDLE_GREATERDYN_PREF_V8, + &&DEBUG_HANDLE_GREATEREQDYN_PREF_V8, + &&DEBUG_HANDLE_SHL2DYN_PREF_V8, + &&DEBUG_HANDLE_SHR2DYN_PREF_V8, + &&DEBUG_HANDLE_ASHR2DYN_PREF_V8, + &&DEBUG_HANDLE_AND2DYN_PREF_V8, + &&DEBUG_HANDLE_OR2DYN_PREF_V8, + &&DEBUG_HANDLE_XOR2DYN_PREF_V8, + &&DEBUG_HANDLE_TONUMBER_PREF_V8, + &&DEBUG_HANDLE_NEGDYN_PREF_V8, + &&DEBUG_HANDLE_NOTDYN_PREF_V8, + &&DEBUG_HANDLE_INCDYN_PREF_V8, + &&DEBUG_HANDLE_DECDYN_PREF_V8, + &&DEBUG_HANDLE_EXPDYN_PREF_V8, + &&DEBUG_HANDLE_ISINDYN_PREF_V8, + &&DEBUG_HANDLE_INSTANCEOFDYN_PREF_V8, + &&DEBUG_HANDLE_STRICTNOTEQDYN_PREF_V8, + &&DEBUG_HANDLE_STRICTEQDYN_PREF_V8, + &&DEBUG_HANDLE_RESUMEGENERATOR_PREF_V8, + &&DEBUG_HANDLE_GETRESUMEMODE_PREF_V8, + &&DEBUG_HANDLE_CREATEGENERATOROBJ_PREF_V8, + &&DEBUG_HANDLE_THROWCONSTASSIGNMENT_PREF_V8, + &&DEBUG_HANDLE_GETTEMPLATEOBJECT_PREF_V8, + &&DEBUG_HANDLE_GETNEXTPROPNAME_PREF_V8, + &&DEBUG_HANDLE_CALLARG0DYN_PREF_V8, + &&DEBUG_HANDLE_THROWIFNOTOBJECT_PREF_V8, + &&DEBUG_HANDLE_ITERNEXT_PREF_V8, + &&DEBUG_HANDLE_CLOSEITERATOR_PREF_V8, + &&DEBUG_HANDLE_COPYMODULE_PREF_V8, + &&DEBUG_HANDLE_SUPERCALLSPREAD_PREF_V8, + &&DEBUG_HANDLE_DELOBJPROP_PREF_V8_V8, + &&DEBUG_HANDLE_NEWOBJSPREADDYN_PREF_V8_V8, + &&DEBUG_HANDLE_CREATEITERRESULTOBJ_PREF_V8_V8, + &&DEBUG_HANDLE_SUSPENDGENERATOR_PREF_V8_V8, + &&DEBUG_HANDLE_ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8, + &&DEBUG_HANDLE_THROWUNDEFINEDIFHOLE_PREF_V8_V8, + &&DEBUG_HANDLE_CALLARG1DYN_PREF_V8_V8, + &&DEBUG_HANDLE_COPYDATAPROPERTIES_PREF_V8_V8, + &&DEBUG_HANDLE_STARRAYSPREAD_PREF_V8_V8, + &&DEBUG_HANDLE_GETITERATORNEXT_PREF_V8_V8, + &&DEBUG_HANDLE_SETOBJECTWITHPROTO_PREF_V8_V8, + &&DEBUG_HANDLE_LDOBJBYVALUE_PREF_V8_V8, + &&DEBUG_HANDLE_STOBJBYVALUE_PREF_V8_V8, + &&DEBUG_HANDLE_STOWNBYVALUE_PREF_V8_V8, + &&DEBUG_HANDLE_LDSUPERBYVALUE_PREF_V8_V8, + &&DEBUG_HANDLE_STSUPERBYVALUE_PREF_V8_V8, + &&DEBUG_HANDLE_LDOBJBYINDEX_PREF_V8_IMM32, + &&DEBUG_HANDLE_STOBJBYINDEX_PREF_V8_IMM32, + &&DEBUG_HANDLE_STOWNBYINDEX_PREF_V8_IMM32, + &&DEBUG_HANDLE_CALLSPREADDYN_PREF_V8_V8_V8, + &&DEBUG_HANDLE_ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8, + &&DEBUG_HANDLE_ASYNCFUNCTIONREJECT_PREF_V8_V8_V8, + &&DEBUG_HANDLE_CALLARGS2DYN_PREF_V8_V8_V8, + &&DEBUG_HANDLE_CALLARGS3DYN_PREF_V8_V8_V8_V8, + &&DEBUG_HANDLE_DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8, + &&DEBUG_HANDLE_NEWOBJDYNRANGE_PREF_IMM16_V8, + &&DEBUG_HANDLE_CALLIRANGEDYN_PREF_IMM16_V8, + &&DEBUG_HANDLE_CALLITHISRANGEDYN_PREF_IMM16_V8, + &&DEBUG_HANDLE_SUPERCALL_PREF_IMM16_V8, + &&DEBUG_HANDLE_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8, + &&DEBUG_HANDLE_DEFINEFUNCDYN_PREF_ID16_IMM16_V8, + &&DEBUG_HANDLE_DEFINENCFUNCDYN_PREF_ID16_IMM16_V8, + &&DEBUG_HANDLE_DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8, + &&DEBUG_HANDLE_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8, + &&DEBUG_HANDLE_DEFINEMETHOD_PREF_ID16_IMM16_V8, + &&DEBUG_HANDLE_NEWLEXENVDYN_PREF_IMM16, + &&DEBUG_HANDLE_COPYRESTARGS_PREF_IMM16, + &&DEBUG_HANDLE_CREATEARRAYWITHBUFFER_PREF_IMM16, + &&DEBUG_HANDLE_CREATEOBJECTHAVINGMETHOD_PREF_IMM16, + &&DEBUG_HANDLE_THROWIFSUPERNOTCORRECTCALL_PREF_IMM16, + &&DEBUG_HANDLE_CREATEOBJECTWITHBUFFER_PREF_IMM16, + &&DEBUG_HANDLE_LDLEXVARDYN_PREF_IMM4_IMM4, + &&DEBUG_HANDLE_LDLEXVARDYN_PREF_IMM8_IMM8, + &&DEBUG_HANDLE_LDLEXVARDYN_PREF_IMM16_IMM16, + &&DEBUG_HANDLE_STLEXVARDYN_PREF_IMM4_IMM4_V8, + &&DEBUG_HANDLE_STLEXVARDYN_PREF_IMM8_IMM8_V8, + &&DEBUG_HANDLE_STLEXVARDYN_PREF_IMM16_IMM16_V8, + &&DEBUG_HANDLE_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8, + &&DEBUG_HANDLE_IMPORTMODULE_PREF_ID32, + &&DEBUG_HANDLE_STMODULEVAR_PREF_ID32, + &&DEBUG_HANDLE_TRYLDGLOBALBYNAME_PREF_ID32, + &&DEBUG_HANDLE_TRYSTGLOBALBYNAME_PREF_ID32, + &&DEBUG_HANDLE_LDGLOBALVAR_PREF_ID32, + &&DEBUG_HANDLE_STGLOBALVAR_PREF_ID32, + &&DEBUG_HANDLE_LDOBJBYNAME_PREF_ID32_V8, + &&DEBUG_HANDLE_STOBJBYNAME_PREF_ID32_V8, + &&DEBUG_HANDLE_STOWNBYNAME_PREF_ID32_V8, + &&DEBUG_HANDLE_LDSUPERBYNAME_PREF_ID32_V8, + &&DEBUG_HANDLE_STSUPERBYNAME_PREF_ID32_V8, + &&DEBUG_HANDLE_LDMODVARBYNAME_PREF_ID32_V8, + &&DEBUG_HANDLE_CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8, + &&DEBUG_HANDLE_ISTRUE_PREF, + &&DEBUG_HANDLE_ISFALSE_PREF, &&DEBUG_HANDLE_MOV_DYN_V8_V8, &&DEBUG_HANDLE_MOV_DYN_V16_V16, &&DEBUG_HANDLE_LDA_STR_ID32, &&DEBUG_HANDLE_LDAI_DYN_IMM32, &&DEBUG_HANDLE_FLDAI_DYN_IMM64, - &&DEBUG_HANDLE_BUILTIN_LDNAN_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDINFINITY_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDGLOBALTHIS_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDUNDEFINED_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDNULL_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDSYMBOL_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDGLOBAL_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDTRUE_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDFALSE_IMM8, - &&DEBUG_HANDLE_BUILTIN_THROWDYN_IMM8, - &&DEBUG_HANDLE_BUILTIN_TYPEOFDYN_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDLEXENVDYN_IMM8, - &&DEBUG_HANDLE_BUILTIN_POPLEXENVDYN_IMM8, - &&DEBUG_HANDLE_BUILTIN_GETUNMAPPEDARGS_IMM8, - &&DEBUG_HANDLE_BUILTIN_TOBOOLEAN_IMM8, - &&DEBUG_HANDLE_BUILTIN_GETPROPITERATOR_IMM8, - &&DEBUG_HANDLE_BUILTIN_ASYNCFUNCTIONENTER_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDHOLE_IMM8, - &&DEBUG_HANDLE_BUILTIN_RETURNUNDEFINED_IMM8, - &&DEBUG_HANDLE_BUILTIN_CREATEEMPTYOBJECT_IMM8, - &&DEBUG_HANDLE_BUILTIN_CREATEEMPTYARRAY_IMM8, - &&DEBUG_HANDLE_BUILTIN_GETITERATOR_IMM8, - &&DEBUG_HANDLE_BUILTIN_THROWTHROWNOTEXISTS_IMM8, - &&DEBUG_HANDLE_BUILTIN_THROWPATTERNNONCOERCIBLE_IMM8, - &&DEBUG_HANDLE_BUILTIN_LDHOMEOBJECT_IMM8, - &&DEBUG_HANDLE_BUILTIN_THROWDELETESUPERPROPERTY_IMM8, - &&DEBUG_HANDLE_BUILTIN_DEBUGGER_IMM8, &&DEBUG_HANDLE_JMP_IMM8, &&DEBUG_HANDLE_JMP_IMM16, &&DEBUG_HANDLE_JMP_IMM32, @@ -52,220 +153,119 @@ &&DEBUG_HANDLE_JEQZ_IMM16, &&DEBUG_HANDLE_LDA_DYN_V8, &&DEBUG_HANDLE_STA_DYN_V8, - &&DEBUG_HANDLE_BUILTIN_LDBOOLEAN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_LDNUMBER_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_LDSTRING_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_LDBIGINT_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_ADD2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_SUB2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_MUL2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_DIV2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_MOD2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_EQDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_NOTEQDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_LESSDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_LESSEQDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_GREATERDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_GREATEREQDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_SHL2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_SHR2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_ASHR2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_AND2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_OR2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_XOR2DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_TONUMBER_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_NEGDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_NOTDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_INCDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_DECDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_EXPDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_ISINDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_INSTANCEOFDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_STRICTNOTEQDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_STRICTEQDYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_RESUMEGENERATOR_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_GETRESUMEMODE_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_CREATEGENERATOROBJ_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_THROWUNDEFINED_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_THROWCONSTASSIGNMENT_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_GETTEMPLATEOBJECT_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_GETNEXTPROPNAME_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_CALLARG0DYN_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_THROWIFNOTOBJECT_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_ITERNEXT_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_CLOSEITERATOR_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_COPYMODULE_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_SUPERCALLSPREAD_IMM8_V8, - &&DEBUG_HANDLE_BUILTIN_LDOBJECT_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_LDFUNCTION_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_DELOBJPROP_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_DEFINEGLOBALVAR_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_DEFINELOCALVAR_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_DEFINEFUNCEXPR_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_REFEQDYN_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_CALLRUNTIMERANGE_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_NEWOBJSPREADDYN_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_CREATEITERRESULTOBJ_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_SUSPENDGENERATOR_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_ASYNCFUNCTIONAWAITUNCAUGHT_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_THROWUNDEFINEDIFHOLE_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_CALLARG1DYN_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_COPYDATAPROPERTIES_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_STARRAYSPREAD_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_GETITERATORNEXT_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_SETOBJECTWITHPROTO_IMM8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_CALLSPREADDYN_IMM8_V8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_ASYNCFUNCTIONRESOLVE_IMM8_V8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_ASYNCFUNCTIONREJECT_IMM8_V8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_CALLARGS2DYN_IMM8_V8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_CALLARGS3DYN_IMM8_V8_V8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_DEFINEGETTERSETTERBYVALUE_IMM8_V8_V8_V8_V8, - &&DEBUG_HANDLE_BUILTIN_TRYLDGLOBALBYVALUE_IMM8_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_NEWOBJDYNRANGE_IMM8_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_TRYSTGLOBALBYVALUE_IMM8_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_CALLIRANGEDYN_IMM8_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_CALLITHISRANGEDYN_IMM8_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_SUPERCALL_IMM8_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_LDOBJBYVALUE_IMM8_IMM16_V8_V8, - &&DEBUG_HANDLE_BUILTIN_STOBJBYVALUE_IMM8_IMM16_V8_V8, - &&DEBUG_HANDLE_BUILTIN_LDOBJBYINDEX_IMM8_IMM16_V8_V8, - &&DEBUG_HANDLE_BUILTIN_STOBJBYINDEX_IMM8_IMM16_V8_V8, - &&DEBUG_HANDLE_BUILTIN_STOWNBYINDEX_IMM8_IMM16_V8_V8, - &&DEBUG_HANDLE_BUILTIN_STOWNBYVALUE_IMM8_IMM16_V8_V8, - &&DEBUG_HANDLE_BUILTIN_CREATEOBJECTWITHEXCLUDEDKEYS_IMM8_IMM16_V8_V8, - &&DEBUG_HANDLE_BUILTIN_LDSUPERBYVALUE_IMM8_IMM16_V8_V8, - &&DEBUG_HANDLE_BUILTIN_STSUPERBYVALUE_IMM8_IMM16_V8_V8, - &&DEBUG_HANDLE_BUILTIN_IMPORTMODULE_IMM8_ID32, - &&DEBUG_HANDLE_BUILTIN_STMODULEVAR_IMM8_ID32, - &&DEBUG_HANDLE_BUILTIN_DEFINEFUNCDYN_IMM8_ID16_V8, - &&DEBUG_HANDLE_BUILTIN_DEFINENCFUNCDYN_IMM8_ID16_V8, - &&DEBUG_HANDLE_BUILTIN_DEFINEGENERATORFUNC_IMM8_ID16_V8, - &&DEBUG_HANDLE_BUILTIN_DEFINEASYNCFUNC_IMM8_ID16_V8, - &&DEBUG_HANDLE_BUILTIN_DEFINEMETHOD_IMM8_ID16_V8, - &&DEBUG_HANDLE_BUILTIN_TRYLDGLOBALBYNAME_IMM8_ID32_IMM16, - &&DEBUG_HANDLE_BUILTIN_TRYSTGLOBALBYNAME_IMM8_ID32_IMM16, - &&DEBUG_HANDLE_BUILTIN_LDGLOBALVAR_IMM8_ID32_IMM16, - &&DEBUG_HANDLE_BUILTIN_STGLOBALVAR_IMM8_ID32_IMM16, - &&DEBUG_HANDLE_BUILTIN_LDOBJBYNAME_IMM8_ID32_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_STOBJBYNAME_IMM8_ID32_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_STOWNBYNAME_IMM8_ID32_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_LDMODVARBYNAME_IMM8_ID32_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_LDSUPERBYNAME_IMM8_ID32_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_STSUPERBYNAME_IMM8_ID32_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_STLEXVARDYN_IMM8_IMM16_IMM16_V8, - &&DEBUG_HANDLE_BUILTIN_LDLEXVARDYN_IMM8_IMM16_IMM16, - &&DEBUG_HANDLE_BUILTIN_NEWLEXENVDYN_IMM8_IMM16, - &&DEBUG_HANDLE_BUILTIN_COPYRESTARGS_IMM8_IMM16, - &&DEBUG_HANDLE_BUILTIN_CREATEOBJECTWITHBUFFER_IMM8_IMM16, - &&DEBUG_HANDLE_BUILTIN_CREATEARRAYWITHBUFFER_IMM8_IMM16, - &&DEBUG_HANDLE_BUILTIN_CREATEOBJECTHAVINGMETHOD_IMM8_IMM16, - &&DEBUG_HANDLE_BUILTIN_THROWIFSUPERNOTCORRECTCALL_IMM8_IMM16, - &&DEBUG_HANDLE_BUILTIN_DEFINECLASSWITHBUFFER_IMM8_ID16_IMM16_V8_V8, &&DEBUG_HANDLE_RETURN_DYN, &&DEBUG_HANDLE_MOV_V4_V4, &&DEBUG_HANDLE_JNEZ_IMM8, &&DEBUG_HANDLE_JNEZ_IMM16, &&DEBUG_EXCEPTION_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, - &&DEBUG_OVERFLOW_HANDLER, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, diff --git a/ecmascript/interpreter/templates/debugger_instruction_handler.inl b/ecmascript/interpreter/templates/debugger_instruction_handler.inl index 1517b2e869a4c9f536ce7af831cb289d5c1691c4..1c03309f214d8eaae3b79cf0fa4cd00f3c637b89 100644 --- a/ecmascript/interpreter/templates/debugger_instruction_handler.inl +++ b/ecmascript/interpreter/templates/debugger_instruction_handler.inl @@ -13,772 +13,732 @@ * limitations under the License. */ - HANDLE_OPCODE(DEBUG_HANDLE_MOV_DYN_V8_V8) - { - NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::MOV_DYN_V8_V8); - } - HANDLE_OPCODE(DEBUG_HANDLE_MOV_DYN_V16_V16) - { - NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::MOV_DYN_V16_V16); - } - HANDLE_OPCODE(DEBUG_HANDLE_LDA_STR_ID32) - { - NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDA_STR_ID32); - } - HANDLE_OPCODE(DEBUG_HANDLE_LDAI_DYN_IMM32) - { - NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDAI_DYN_IMM32); - } - HANDLE_OPCODE(DEBUG_HANDLE_FLDAI_DYN_IMM64) - { - NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::FLDAI_DYN_IMM64); - } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDNAN_IMM8) - { - NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDNAN_IMM8); - } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDINFINITY_IMM8) - { - NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDINFINITY_IMM8); - } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDGLOBALTHIS_IMM8) - { - NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDGLOBALTHIS_IMM8); - } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDUNDEFINED_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDNAN_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDUNDEFINED_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDNAN_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDNULL_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDINFINITY_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDNULL_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDINFINITY_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDSYMBOL_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDGLOBALTHIS_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDSYMBOL_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDGLOBALTHIS_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDGLOBAL_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDUNDEFINED_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDGLOBAL_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDUNDEFINED_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDTRUE_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDNULL_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDTRUE_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDNULL_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDFALSE_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDSYMBOL_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDFALSE_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDSYMBOL_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_THROWDYN_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDGLOBAL_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWDYN_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDGLOBAL_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_TYPEOFDYN_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDTRUE_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TYPEOFDYN_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDTRUE_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_GETUNMAPPEDARGS_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDFALSE_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETUNMAPPEDARGS_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDFALSE_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_TOBOOLEAN_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_THROWDYN_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TOBOOLEAN_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWDYN_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_GETPROPITERATOR_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_TYPEOFDYN_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETPROPITERATOR_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TYPEOFDYN_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_ASYNCFUNCTIONENTER_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDLEXENVDYN_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASYNCFUNCTIONENTER_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDLEXENVDYN_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDHOLE_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_POPLEXENVDYN_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDHOLE_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::POPLEXENVDYN_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_RETURNUNDEFINED_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_GETUNMAPPEDARGS_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::RETURNUNDEFINED_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETUNMAPPEDARGS_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CREATEEMPTYOBJECT_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_GETPROPITERATOR_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEEMPTYOBJECT_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETPROPITERATOR_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CREATEEMPTYARRAY_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_ASYNCFUNCTIONENTER_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEEMPTYARRAY_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASYNCFUNCTIONENTER_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_GETITERATOR_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_LDHOLE_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETITERATOR_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDHOLE_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_THROWTHROWNOTEXISTS_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_RETURNUNDEFINED_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWTHROWNOTEXISTS_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::RETURNUNDEFINED_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_THROWPATTERNNONCOERCIBLE_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_CREATEEMPTYOBJECT_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWPATTERNNONCOERCIBLE_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEEMPTYOBJECT_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDHOMEOBJECT_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_CREATEEMPTYARRAY_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDHOMEOBJECT_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEEMPTYARRAY_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_THROWDELETESUPERPROPERTY_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_GETITERATOR_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWDELETESUPERPROPERTY_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETITERATOR_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEBUGGER_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_THROWTHROWNOTEXISTS_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEBUGGER_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWTHROWNOTEXISTS_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_JMP_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_THROWPATTERNNONCOERCIBLE_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JMP_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWPATTERNNONCOERCIBLE_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_JMP_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_LDHOMEOBJECT_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JMP_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDHOMEOBJECT_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_JMP_IMM32) + HANDLE_OPCODE(DEBUG_HANDLE_THROWDELETESUPERPROPERTY_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JMP_IMM32); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWDELETESUPERPROPERTY_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_JEQZ_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_DEBUGGER_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JEQZ_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEBUGGER_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_JEQZ_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_ADD2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JEQZ_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ADD2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_JNEZ_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_SUB2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JNEZ_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SUB2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_JNEZ_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_MUL2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JNEZ_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::MUL2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_LDA_DYN_V8) + HANDLE_OPCODE(DEBUG_HANDLE_DIV2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDA_DYN_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DIV2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_STA_DYN_V8) + HANDLE_OPCODE(DEBUG_HANDLE_MOD2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STA_DYN_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::MOD2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDBOOLEAN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_EQDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDBOOLEAN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::EQDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDNUMBER_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_NOTEQDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDNUMBER_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NOTEQDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDSTRING_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LESSDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDSTRING_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LESSDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDBIGINT_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LESSEQDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDBIGINT_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LESSEQDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_ADD2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_GREATERDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ADD2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GREATERDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_SUB2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_GREATEREQDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SUB2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GREATEREQDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_MUL2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_SHL2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::MUL2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SHL2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DIV2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_SHR2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DIV2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SHR2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_MOD2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_ASHR2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::MOD2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASHR2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_EQDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_AND2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::EQDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::AND2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_NOTEQDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_OR2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NOTEQDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::OR2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LESSDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_XOR2DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LESSDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::XOR2DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LESSEQDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_TONUMBER_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LESSEQDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TONUMBER_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_GREATERDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_NEGDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GREATERDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NEGDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_GREATEREQDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_NOTDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GREATEREQDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NOTDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_SHL2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_INCDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SHL2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::INCDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_SHR2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_DECDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SHR2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DECDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_ASHR2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_EXPDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASHR2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::EXPDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_AND2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_ISINDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::AND2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ISINDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_OR2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_INSTANCEOFDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::OR2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::INSTANCEOFDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_XOR2DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STRICTNOTEQDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::XOR2DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STRICTNOTEQDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_TONUMBER_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STRICTEQDYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TONUMBER_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STRICTEQDYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_NEGDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_RESUMEGENERATOR_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NEGDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::RESUMEGENERATOR_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_NOTDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_GETRESUMEMODE_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NOTDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETRESUMEMODE_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_INCDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CREATEGENERATOROBJ_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::INCDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEGENERATOROBJ_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DECDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_THROWCONSTASSIGNMENT_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DECDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWCONSTASSIGNMENT_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_EXPDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_GETTEMPLATEOBJECT_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::EXPDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETTEMPLATEOBJECT_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_ISINDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_GETNEXTPROPNAME_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ISINDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETNEXTPROPNAME_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_INSTANCEOFDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CALLARG0DYN_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::INSTANCEOFDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLARG0DYN_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STRICTNOTEQDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_THROWIFNOTOBJECT_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STRICTNOTEQDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWIFNOTOBJECT_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STRICTEQDYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_ITERNEXT_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STRICTEQDYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ITERNEXT_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDLEXENVDYN_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_CLOSEITERATOR_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDLEXENVDYN_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CLOSEITERATOR_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_POPLEXENVDYN_IMM8) + HANDLE_OPCODE(DEBUG_HANDLE_COPYMODULE_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::POPLEXENVDYN_IMM8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::COPYMODULE_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_RESUMEGENERATOR_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_SUPERCALLSPREAD_PREF_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::RESUMEGENERATOR_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SUPERCALLSPREAD_PREF_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_GETRESUMEMODE_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_DELOBJPROP_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETRESUMEMODE_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DELOBJPROP_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CREATEGENERATOROBJ_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_NEWOBJSPREADDYN_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEGENERATOROBJ_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NEWOBJSPREADDYN_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_THROWUNDEFINED_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CREATEITERRESULTOBJ_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWUNDEFINED_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEITERRESULTOBJ_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_THROWCONSTASSIGNMENT_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_SUSPENDGENERATOR_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWCONSTASSIGNMENT_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SUSPENDGENERATOR_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_GETTEMPLATEOBJECT_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETTEMPLATEOBJECT_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_GETNEXTPROPNAME_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_THROWUNDEFINEDIFHOLE_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETNEXTPROPNAME_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWUNDEFINEDIFHOLE_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CALLARG0DYN_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CALLARG1DYN_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLARG0DYN_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLARG1DYN_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_SETOBJECTWITHPROTO_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_COPYDATAPROPERTIES_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SETOBJECTWITHPROTO_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::COPYDATAPROPERTIES_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_THROWIFNOTOBJECT_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STARRAYSPREAD_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWIFNOTOBJECT_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STARRAYSPREAD_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_ITERNEXT_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_GETITERATORNEXT_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ITERNEXT_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETITERATORNEXT_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CLOSEITERATOR_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_SETOBJECTWITHPROTO_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CLOSEITERATOR_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SETOBJECTWITHPROTO_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_COPYMODULE_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LDOBJBYVALUE_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::COPYMODULE_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDOBJBYVALUE_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_SUPERCALLSPREAD_IMM8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STOBJBYVALUE_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SUPERCALLSPREAD_IMM8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOBJBYVALUE_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDOBJECT_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STOWNBYVALUE_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDOBJECT_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOWNBYVALUE_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDFUNCTION_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LDSUPERBYVALUE_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDFUNCTION_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDSUPERBYVALUE_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DELOBJPROP_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STSUPERBYVALUE_PREF_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DELOBJPROP_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STSUPERBYVALUE_PREF_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEFINEGLOBALVAR_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LDOBJBYINDEX_PREF_V8_IMM32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEGLOBALVAR_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDOBJBYINDEX_PREF_V8_IMM32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEFINELOCALVAR_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STOBJBYINDEX_PREF_V8_IMM32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINELOCALVAR_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOBJBYINDEX_PREF_V8_IMM32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEFINEFUNCEXPR_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STOWNBYINDEX_PREF_V8_IMM32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEFUNCEXPR_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOWNBYINDEX_PREF_V8_IMM32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_REFEQDYN_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CALLSPREADDYN_PREF_V8_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::REFEQDYN_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLSPREADDYN_PREF_V8_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CALLRUNTIMERANGE_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLRUNTIMERANGE_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_NEWOBJSPREADDYN_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_ASYNCFUNCTIONREJECT_PREF_V8_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NEWOBJSPREADDYN_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASYNCFUNCTIONREJECT_PREF_V8_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_NEWLEXENVDYN_IMM8_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_CALLARGS2DYN_PREF_V8_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NEWLEXENVDYN_IMM8_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLARGS2DYN_PREF_V8_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CREATEITERRESULTOBJ_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CALLARGS3DYN_PREF_V8_V8_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEITERRESULTOBJ_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLARGS3DYN_PREF_V8_V8_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_SUSPENDGENERATOR_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SUSPENDGENERATOR_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_ASYNCFUNCTIONAWAITUNCAUGHT_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_NEWOBJDYNRANGE_PREF_IMM16_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASYNCFUNCTIONAWAITUNCAUGHT_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NEWOBJDYNRANGE_PREF_IMM16_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_THROWUNDEFINEDIFHOLE_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CALLIRANGEDYN_PREF_IMM16_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWUNDEFINEDIFHOLE_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLIRANGEDYN_PREF_IMM16_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CALLARG1DYN_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CALLITHISRANGEDYN_PREF_IMM16_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLARG1DYN_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLITHISRANGEDYN_PREF_IMM16_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_COPYDATAPROPERTIES_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_SUPERCALL_PREF_IMM16_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::COPYDATAPROPERTIES_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SUPERCALL_PREF_IMM16_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STARRAYSPREAD_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STARRAYSPREAD_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_GETITERATORNEXT_IMM8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_DEFINEFUNCDYN_PREF_ID16_IMM16_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::GETITERATORNEXT_IMM8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEFUNCDYN_PREF_ID16_IMM16_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CALLSPREADDYN_IMM8_V8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_DEFINENCFUNCDYN_PREF_ID16_IMM16_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLSPREADDYN_IMM8_V8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINENCFUNCDYN_PREF_ID16_IMM16_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_ASYNCFUNCTIONRESOLVE_IMM8_V8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASYNCFUNCTIONRESOLVE_IMM8_V8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_ASYNCFUNCTIONREJECT_IMM8_V8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ASYNCFUNCTIONREJECT_IMM8_V8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEASYNCFUNC_PREF_ID16_IMM16_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CALLARGS2DYN_IMM8_V8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_DEFINEMETHOD_PREF_ID16_IMM16_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLARGS2DYN_IMM8_V8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEMETHOD_PREF_ID16_IMM16_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CALLARGS3DYN_IMM8_V8_V8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_NEWLEXENVDYN_PREF_IMM16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLARGS3DYN_IMM8_V8_V8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NEWLEXENVDYN_PREF_IMM16); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEFINEGETTERSETTERBYVALUE_IMM8_V8_V8_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_COPYRESTARGS_PREF_IMM16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEGETTERSETTERBYVALUE_IMM8_V8_V8_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::COPYRESTARGS_PREF_IMM16); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_TRYLDGLOBALBYVALUE_IMM8_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CREATEARRAYWITHBUFFER_PREF_IMM16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TRYLDGLOBALBYVALUE_IMM8_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEARRAYWITHBUFFER_PREF_IMM16); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_NEWOBJDYNRANGE_IMM8_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CREATEOBJECTHAVINGMETHOD_PREF_IMM16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::NEWOBJDYNRANGE_IMM8_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEOBJECTHAVINGMETHOD_PREF_IMM16); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_TRYSTGLOBALBYVALUE_IMM8_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_THROWIFSUPERNOTCORRECTCALL_PREF_IMM16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TRYSTGLOBALBYVALUE_IMM8_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWIFSUPERNOTCORRECTCALL_PREF_IMM16); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CALLIRANGEDYN_IMM8_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_CREATEOBJECTWITHBUFFER_PREF_IMM16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLIRANGEDYN_IMM8_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEOBJECTWITHBUFFER_PREF_IMM16); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CALLITHISRANGEDYN_IMM8_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LDLEXVARDYN_PREF_IMM4_IMM4) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CALLITHISRANGEDYN_IMM8_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDLEXVARDYN_PREF_IMM4_IMM4); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_SUPERCALL_IMM8_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LDLEXVARDYN_PREF_IMM8_IMM8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::SUPERCALL_IMM8_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDLEXVARDYN_PREF_IMM8_IMM8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDOBJBYVALUE_IMM8_IMM16_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LDLEXVARDYN_PREF_IMM16_IMM16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDOBJBYVALUE_IMM8_IMM16_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDLEXVARDYN_PREF_IMM16_IMM16); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STOBJBYVALUE_IMM8_IMM16_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STLEXVARDYN_PREF_IMM4_IMM4_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOBJBYVALUE_IMM8_IMM16_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STLEXVARDYN_PREF_IMM4_IMM4_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDOBJBYINDEX_IMM8_IMM16_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STLEXVARDYN_PREF_IMM8_IMM8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDOBJBYINDEX_IMM8_IMM16_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STLEXVARDYN_PREF_IMM8_IMM8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STOBJBYINDEX_IMM8_IMM16_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STLEXVARDYN_PREF_IMM16_IMM16_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOBJBYINDEX_IMM8_IMM16_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STLEXVARDYN_PREF_IMM16_IMM16_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STOWNBYINDEX_IMM8_IMM16_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOWNBYINDEX_IMM8_IMM16_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STOWNBYVALUE_IMM8_IMM16_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_IMPORTMODULE_PREF_ID32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOWNBYVALUE_IMM8_IMM16_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::IMPORTMODULE_PREF_ID32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CREATEOBJECTWITHEXCLUDEDKEYS_IMM8_IMM16_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STMODULEVAR_PREF_ID32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEOBJECTWITHEXCLUDEDKEYS_IMM8_IMM16_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STMODULEVAR_PREF_ID32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDSUPERBYVALUE_IMM8_IMM16_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_TRYLDGLOBALBYNAME_PREF_ID32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDSUPERBYVALUE_IMM8_IMM16_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TRYLDGLOBALBYNAME_PREF_ID32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STSUPERBYVALUE_IMM8_IMM16_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_TRYSTGLOBALBYNAME_PREF_ID32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STSUPERBYVALUE_IMM8_IMM16_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TRYSTGLOBALBYNAME_PREF_ID32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_IMPORTMODULE_IMM8_ID32) + HANDLE_OPCODE(DEBUG_HANDLE_LDGLOBALVAR_PREF_ID32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::IMPORTMODULE_IMM8_ID32); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDGLOBALVAR_PREF_ID32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STMODULEVAR_IMM8_ID32) + HANDLE_OPCODE(DEBUG_HANDLE_STGLOBALVAR_PREF_ID32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STMODULEVAR_IMM8_ID32); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STGLOBALVAR_PREF_ID32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEFINEFUNCDYN_IMM8_ID16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LDOBJBYNAME_PREF_ID32_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEFUNCDYN_IMM8_ID16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDOBJBYNAME_PREF_ID32_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEFINENCFUNCDYN_IMM8_ID16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STOBJBYNAME_PREF_ID32_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINENCFUNCDYN_IMM8_ID16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOBJBYNAME_PREF_ID32_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEFINEGENERATORFUNC_IMM8_ID16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STOWNBYNAME_PREF_ID32_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEGENERATORFUNC_IMM8_ID16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOWNBYNAME_PREF_ID32_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEFINEASYNCFUNC_IMM8_ID16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LDSUPERBYNAME_PREF_ID32_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEASYNCFUNC_IMM8_ID16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDSUPERBYNAME_PREF_ID32_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEFINEMETHOD_IMM8_ID16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_STSUPERBYNAME_PREF_ID32_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINEMETHOD_IMM8_ID16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STSUPERBYNAME_PREF_ID32_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_TRYLDGLOBALBYNAME_IMM8_ID32_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_LDMODVARBYNAME_PREF_ID32_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TRYLDGLOBALBYNAME_IMM8_ID32_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDMODVARBYNAME_PREF_ID32_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_TRYSTGLOBALBYNAME_IMM8_ID32_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::TRYSTGLOBALBYNAME_IMM8_ID32_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDGLOBALVAR_IMM8_ID32_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_ISTRUE_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDGLOBALVAR_IMM8_ID32_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ISTRUE_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STGLOBALVAR_IMM8_ID32_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_ISFALSE_PREF) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STGLOBALVAR_IMM8_ID32_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ISFALSE_PREF); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDOBJBYNAME_IMM8_ID32_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_MOV_DYN_V8_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDOBJBYNAME_IMM8_ID32_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::MOV_DYN_V8_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STOBJBYNAME_IMM8_ID32_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_MOV_DYN_V16_V16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOBJBYNAME_IMM8_ID32_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::MOV_DYN_V16_V16); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STOWNBYNAME_IMM8_ID32_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LDA_STR_ID32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOWNBYNAME_IMM8_ID32_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDA_STR_ID32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDMODVARBYNAME_IMM8_ID32_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_LDAI_DYN_IMM32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDMODVARBYNAME_IMM8_ID32_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDAI_DYN_IMM32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDSUPERBYNAME_IMM8_ID32_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_FLDAI_DYN_IMM64) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDSUPERBYNAME_IMM8_ID32_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::FLDAI_DYN_IMM64); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STSUPERBYNAME_IMM8_ID32_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_JMP_IMM8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STSUPERBYNAME_IMM8_ID32_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JMP_IMM8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_LDLEXVARDYN_IMM8_IMM16_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_JMP_IMM16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDLEXVARDYN_IMM8_IMM16_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JMP_IMM16); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_STLEXVARDYN_IMM8_IMM16_IMM16_V8) + HANDLE_OPCODE(DEBUG_HANDLE_JMP_IMM32) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STLEXVARDYN_IMM8_IMM16_IMM16_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JMP_IMM32); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_COPYRESTARGS_IMM8_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_JEQZ_IMM8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::COPYRESTARGS_IMM8_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JEQZ_IMM8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CREATEOBJECTWITHBUFFER_IMM8_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_JEQZ_IMM16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM8_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JEQZ_IMM16); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CREATEARRAYWITHBUFFER_IMM8_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_LDA_DYN_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LDA_DYN_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_CREATEOBJECTHAVINGMETHOD_IMM8_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_STA_DYN_V8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::CREATEOBJECTHAVINGMETHOD_IMM8_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STA_DYN_V8); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_THROWIFSUPERNOTCORRECTCALL_IMM8_IMM16) + HANDLE_OPCODE(DEBUG_HANDLE_RETURN_DYN) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::THROWIFSUPERNOTCORRECTCALL_IMM8_IMM16); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::RETURN_DYN); } - HANDLE_OPCODE(DEBUG_HANDLE_BUILTIN_DEFINECLASSWITHBUFFER_IMM8_ID16_IMM16_V8_V8) + HANDLE_OPCODE(DEBUG_HANDLE_MOV_V4_V4) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::DEFINECLASSWITHBUFFER_IMM8_ID16_IMM16_V8_V8); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::MOV_V4_V4); } - HANDLE_OPCODE(DEBUG_HANDLE_RETURN_DYN) + HANDLE_OPCODE(DEBUG_HANDLE_JNEZ_IMM8) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::RETURN_DYN); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JNEZ_IMM8); } - HANDLE_OPCODE(DEBUG_HANDLE_MOV_V4_V4) + HANDLE_OPCODE(DEBUG_HANDLE_JNEZ_IMM16) { NOTIFY_DEBUGGER_EVENT(); - REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::MOV_V4_V4); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::JNEZ_IMM16); } HANDLE_OPCODE(DEBUG_EXCEPTION_HANDLER) { NOTIFY_DEBUGGER_EVENT(); REAL_GOTO_EXCEPTION_HANDLER(); } - HANDLE_OPCODE(DEBUG_OVERFLOW_HANDLER) + HANDLE_OPCODE(DEBUG_HANDLE_OVERFLOW) { NOTIFY_DEBUGGER_EVENT(); REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::LAST_OPCODE + 1); diff --git a/ecmascript/interpreter/templates/instruction_dispatch.inl b/ecmascript/interpreter/templates/instruction_dispatch.inl index 6bc2f361b561002609d281b8dd9e2eec66493086..dfdfb40baec760ded6f711c4810f6ae520fc5397 100644 --- a/ecmascript/interpreter/templates/instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/instruction_dispatch.inl @@ -13,38 +13,139 @@ * limitations under the License. */ + &&HANDLE_LDNAN_PREF, + &&HANDLE_LDINFINITY_PREF, + &&HANDLE_LDGLOBALTHIS_PREF, + &&HANDLE_LDUNDEFINED_PREF, + &&HANDLE_LDNULL_PREF, + &&HANDLE_LDSYMBOL_PREF, + &&HANDLE_LDGLOBAL_PREF, + &&HANDLE_LDTRUE_PREF, + &&HANDLE_LDFALSE_PREF, + &&HANDLE_THROWDYN_PREF, + &&HANDLE_TYPEOFDYN_PREF, + &&HANDLE_LDLEXENVDYN_PREF, + &&HANDLE_POPLEXENVDYN_PREF, + &&HANDLE_GETUNMAPPEDARGS_PREF, + &&HANDLE_GETPROPITERATOR_PREF, + &&HANDLE_ASYNCFUNCTIONENTER_PREF, + &&HANDLE_LDHOLE_PREF, + &&HANDLE_RETURNUNDEFINED_PREF, + &&HANDLE_CREATEEMPTYOBJECT_PREF, + &&HANDLE_CREATEEMPTYARRAY_PREF, + &&HANDLE_GETITERATOR_PREF, + &&HANDLE_THROWTHROWNOTEXISTS_PREF, + &&HANDLE_THROWPATTERNNONCOERCIBLE_PREF, + &&HANDLE_LDHOMEOBJECT_PREF, + &&HANDLE_THROWDELETESUPERPROPERTY_PREF, + &&HANDLE_DEBUGGER_PREF, + &&HANDLE_ADD2DYN_PREF_V8, + &&HANDLE_SUB2DYN_PREF_V8, + &&HANDLE_MUL2DYN_PREF_V8, + &&HANDLE_DIV2DYN_PREF_V8, + &&HANDLE_MOD2DYN_PREF_V8, + &&HANDLE_EQDYN_PREF_V8, + &&HANDLE_NOTEQDYN_PREF_V8, + &&HANDLE_LESSDYN_PREF_V8, + &&HANDLE_LESSEQDYN_PREF_V8, + &&HANDLE_GREATERDYN_PREF_V8, + &&HANDLE_GREATEREQDYN_PREF_V8, + &&HANDLE_SHL2DYN_PREF_V8, + &&HANDLE_SHR2DYN_PREF_V8, + &&HANDLE_ASHR2DYN_PREF_V8, + &&HANDLE_AND2DYN_PREF_V8, + &&HANDLE_OR2DYN_PREF_V8, + &&HANDLE_XOR2DYN_PREF_V8, + &&HANDLE_TONUMBER_PREF_V8, + &&HANDLE_NEGDYN_PREF_V8, + &&HANDLE_NOTDYN_PREF_V8, + &&HANDLE_INCDYN_PREF_V8, + &&HANDLE_DECDYN_PREF_V8, + &&HANDLE_EXPDYN_PREF_V8, + &&HANDLE_ISINDYN_PREF_V8, + &&HANDLE_INSTANCEOFDYN_PREF_V8, + &&HANDLE_STRICTNOTEQDYN_PREF_V8, + &&HANDLE_STRICTEQDYN_PREF_V8, + &&HANDLE_RESUMEGENERATOR_PREF_V8, + &&HANDLE_GETRESUMEMODE_PREF_V8, + &&HANDLE_CREATEGENERATOROBJ_PREF_V8, + &&HANDLE_THROWCONSTASSIGNMENT_PREF_V8, + &&HANDLE_GETTEMPLATEOBJECT_PREF_V8, + &&HANDLE_GETNEXTPROPNAME_PREF_V8, + &&HANDLE_CALLARG0DYN_PREF_V8, + &&HANDLE_THROWIFNOTOBJECT_PREF_V8, + &&HANDLE_ITERNEXT_PREF_V8, + &&HANDLE_CLOSEITERATOR_PREF_V8, + &&HANDLE_COPYMODULE_PREF_V8, + &&HANDLE_SUPERCALLSPREAD_PREF_V8, + &&HANDLE_DELOBJPROP_PREF_V8_V8, + &&HANDLE_NEWOBJSPREADDYN_PREF_V8_V8, + &&HANDLE_CREATEITERRESULTOBJ_PREF_V8_V8, + &&HANDLE_SUSPENDGENERATOR_PREF_V8_V8, + &&HANDLE_ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8, + &&HANDLE_THROWUNDEFINEDIFHOLE_PREF_V8_V8, + &&HANDLE_CALLARG1DYN_PREF_V8_V8, + &&HANDLE_COPYDATAPROPERTIES_PREF_V8_V8, + &&HANDLE_STARRAYSPREAD_PREF_V8_V8, + &&HANDLE_GETITERATORNEXT_PREF_V8_V8, + &&HANDLE_SETOBJECTWITHPROTO_PREF_V8_V8, + &&HANDLE_LDOBJBYVALUE_PREF_V8_V8, + &&HANDLE_STOBJBYVALUE_PREF_V8_V8, + &&HANDLE_STOWNBYVALUE_PREF_V8_V8, + &&HANDLE_LDSUPERBYVALUE_PREF_V8_V8, + &&HANDLE_STSUPERBYVALUE_PREF_V8_V8, + &&HANDLE_LDOBJBYINDEX_PREF_V8_IMM32, + &&HANDLE_STOBJBYINDEX_PREF_V8_IMM32, + &&HANDLE_STOWNBYINDEX_PREF_V8_IMM32, + &&HANDLE_CALLSPREADDYN_PREF_V8_V8_V8, + &&HANDLE_ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8, + &&HANDLE_ASYNCFUNCTIONREJECT_PREF_V8_V8_V8, + &&HANDLE_CALLARGS2DYN_PREF_V8_V8_V8, + &&HANDLE_CALLARGS3DYN_PREF_V8_V8_V8_V8, + &&HANDLE_DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8, + &&HANDLE_NEWOBJDYNRANGE_PREF_IMM16_V8, + &&HANDLE_CALLIRANGEDYN_PREF_IMM16_V8, + &&HANDLE_CALLITHISRANGEDYN_PREF_IMM16_V8, + &&HANDLE_SUPERCALL_PREF_IMM16_V8, + &&HANDLE_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8, + &&HANDLE_DEFINEFUNCDYN_PREF_ID16_IMM16_V8, + &&HANDLE_DEFINENCFUNCDYN_PREF_ID16_IMM16_V8, + &&HANDLE_DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8, + &&HANDLE_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8, + &&HANDLE_DEFINEMETHOD_PREF_ID16_IMM16_V8, + &&HANDLE_NEWLEXENVDYN_PREF_IMM16, + &&HANDLE_COPYRESTARGS_PREF_IMM16, + &&HANDLE_CREATEARRAYWITHBUFFER_PREF_IMM16, + &&HANDLE_CREATEOBJECTHAVINGMETHOD_PREF_IMM16, + &&HANDLE_THROWIFSUPERNOTCORRECTCALL_PREF_IMM16, + &&HANDLE_CREATEOBJECTWITHBUFFER_PREF_IMM16, + &&HANDLE_LDLEXVARDYN_PREF_IMM4_IMM4, + &&HANDLE_LDLEXVARDYN_PREF_IMM8_IMM8, + &&HANDLE_LDLEXVARDYN_PREF_IMM16_IMM16, + &&HANDLE_STLEXVARDYN_PREF_IMM4_IMM4_V8, + &&HANDLE_STLEXVARDYN_PREF_IMM8_IMM8_V8, + &&HANDLE_STLEXVARDYN_PREF_IMM16_IMM16_V8, + &&HANDLE_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8, + &&HANDLE_IMPORTMODULE_PREF_ID32, + &&HANDLE_STMODULEVAR_PREF_ID32, + &&HANDLE_TRYLDGLOBALBYNAME_PREF_ID32, + &&HANDLE_TRYSTGLOBALBYNAME_PREF_ID32, + &&HANDLE_LDGLOBALVAR_PREF_ID32, + &&HANDLE_STGLOBALVAR_PREF_ID32, + &&HANDLE_LDOBJBYNAME_PREF_ID32_V8, + &&HANDLE_STOBJBYNAME_PREF_ID32_V8, + &&HANDLE_STOWNBYNAME_PREF_ID32_V8, + &&HANDLE_LDSUPERBYNAME_PREF_ID32_V8, + &&HANDLE_STSUPERBYNAME_PREF_ID32_V8, + &&HANDLE_LDMODVARBYNAME_PREF_ID32_V8, + &&HANDLE_CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8, + &&HANDLE_ISTRUE_PREF, + &&HANDLE_ISFALSE_PREF, &&HANDLE_MOV_DYN_V8_V8, &&HANDLE_MOV_DYN_V16_V16, &&HANDLE_LDA_STR_ID32, &&HANDLE_LDAI_DYN_IMM32, &&HANDLE_FLDAI_DYN_IMM64, - &&HANDLE_BUILTIN_LDNAN_IMM8, - &&HANDLE_BUILTIN_LDINFINITY_IMM8, - &&HANDLE_BUILTIN_LDGLOBALTHIS_IMM8, - &&HANDLE_BUILTIN_LDUNDEFINED_IMM8, - &&HANDLE_BUILTIN_LDNULL_IMM8, - &&HANDLE_BUILTIN_LDSYMBOL_IMM8, - &&HANDLE_BUILTIN_LDGLOBAL_IMM8, - &&HANDLE_BUILTIN_LDTRUE_IMM8, - &&HANDLE_BUILTIN_LDFALSE_IMM8, - &&HANDLE_BUILTIN_THROWDYN_IMM8, - &&HANDLE_BUILTIN_TYPEOFDYN_IMM8, - &&HANDLE_BUILTIN_LDLEXENVDYN_IMM8, - &&HANDLE_BUILTIN_POPLEXENVDYN_IMM8, - &&HANDLE_BUILTIN_GETUNMAPPEDARGS_IMM8, - &&HANDLE_BUILTIN_TOBOOLEAN_IMM8, - &&HANDLE_BUILTIN_GETPROPITERATOR_IMM8, - &&HANDLE_BUILTIN_ASYNCFUNCTIONENTER_IMM8, - &&HANDLE_BUILTIN_LDHOLE_IMM8, - &&HANDLE_BUILTIN_RETURNUNDEFINED_IMM8, - &&HANDLE_BUILTIN_CREATEEMPTYOBJECT_IMM8, - &&HANDLE_BUILTIN_CREATEEMPTYARRAY_IMM8, - &&HANDLE_BUILTIN_GETITERATOR_IMM8, - &&HANDLE_BUILTIN_THROWTHROWNOTEXISTS_IMM8, - &&HANDLE_BUILTIN_THROWPATTERNNONCOERCIBLE_IMM8, - &&HANDLE_BUILTIN_LDHOMEOBJECT_IMM8, - &&HANDLE_BUILTIN_THROWDELETESUPERPROPERTY_IMM8, - &&HANDLE_BUILTIN_DEBUGGER_IMM8, &&HANDLE_JMP_IMM8, &&HANDLE_JMP_IMM16, &&HANDLE_JMP_IMM32, @@ -52,220 +153,119 @@ &&HANDLE_JEQZ_IMM16, &&HANDLE_LDA_DYN_V8, &&HANDLE_STA_DYN_V8, - &&HANDLE_BUILTIN_LDBOOLEAN_IMM8_V8, - &&HANDLE_BUILTIN_LDNUMBER_IMM8_V8, - &&HANDLE_BUILTIN_LDSTRING_IMM8_V8, - &&HANDLE_BUILTIN_LDBIGINT_IMM8_V8, - &&HANDLE_BUILTIN_ADD2DYN_IMM8_V8, - &&HANDLE_BUILTIN_SUB2DYN_IMM8_V8, - &&HANDLE_BUILTIN_MUL2DYN_IMM8_V8, - &&HANDLE_BUILTIN_DIV2DYN_IMM8_V8, - &&HANDLE_BUILTIN_MOD2DYN_IMM8_V8, - &&HANDLE_BUILTIN_EQDYN_IMM8_V8, - &&HANDLE_BUILTIN_NOTEQDYN_IMM8_V8, - &&HANDLE_BUILTIN_LESSDYN_IMM8_V8, - &&HANDLE_BUILTIN_LESSEQDYN_IMM8_V8, - &&HANDLE_BUILTIN_GREATERDYN_IMM8_V8, - &&HANDLE_BUILTIN_GREATEREQDYN_IMM8_V8, - &&HANDLE_BUILTIN_SHL2DYN_IMM8_V8, - &&HANDLE_BUILTIN_SHR2DYN_IMM8_V8, - &&HANDLE_BUILTIN_ASHR2DYN_IMM8_V8, - &&HANDLE_BUILTIN_AND2DYN_IMM8_V8, - &&HANDLE_BUILTIN_OR2DYN_IMM8_V8, - &&HANDLE_BUILTIN_XOR2DYN_IMM8_V8, - &&HANDLE_BUILTIN_TONUMBER_IMM8_V8, - &&HANDLE_BUILTIN_NEGDYN_IMM8_V8, - &&HANDLE_BUILTIN_NOTDYN_IMM8_V8, - &&HANDLE_BUILTIN_INCDYN_IMM8_V8, - &&HANDLE_BUILTIN_DECDYN_IMM8_V8, - &&HANDLE_BUILTIN_EXPDYN_IMM8_V8, - &&HANDLE_BUILTIN_ISINDYN_IMM8_V8, - &&HANDLE_BUILTIN_INSTANCEOFDYN_IMM8_V8, - &&HANDLE_BUILTIN_STRICTNOTEQDYN_IMM8_V8, - &&HANDLE_BUILTIN_STRICTEQDYN_IMM8_V8, - &&HANDLE_BUILTIN_RESUMEGENERATOR_IMM8_V8, - &&HANDLE_BUILTIN_GETRESUMEMODE_IMM8_V8, - &&HANDLE_BUILTIN_CREATEGENERATOROBJ_IMM8_V8, - &&HANDLE_BUILTIN_THROWUNDEFINED_IMM8_V8, - &&HANDLE_BUILTIN_THROWCONSTASSIGNMENT_IMM8_V8, - &&HANDLE_BUILTIN_GETTEMPLATEOBJECT_IMM8_V8, - &&HANDLE_BUILTIN_GETNEXTPROPNAME_IMM8_V8, - &&HANDLE_BUILTIN_CALLARG0DYN_IMM8_V8, - &&HANDLE_BUILTIN_THROWIFNOTOBJECT_IMM8_V8, - &&HANDLE_BUILTIN_ITERNEXT_IMM8_V8, - &&HANDLE_BUILTIN_CLOSEITERATOR_IMM8_V8, - &&HANDLE_BUILTIN_COPYMODULE_IMM8_V8, - &&HANDLE_BUILTIN_SUPERCALLSPREAD_IMM8_V8, - &&HANDLE_BUILTIN_LDOBJECT_IMM8_V8_V8, - &&HANDLE_BUILTIN_LDFUNCTION_IMM8_V8_V8, - &&HANDLE_BUILTIN_DELOBJPROP_IMM8_V8_V8, - &&HANDLE_BUILTIN_DEFINEGLOBALVAR_IMM8_V8_V8, - &&HANDLE_BUILTIN_DEFINELOCALVAR_IMM8_V8_V8, - &&HANDLE_BUILTIN_DEFINEFUNCEXPR_IMM8_V8_V8, - &&HANDLE_BUILTIN_REFEQDYN_IMM8_V8_V8, - &&HANDLE_BUILTIN_CALLRUNTIMERANGE_IMM8_V8_V8, - &&HANDLE_BUILTIN_NEWOBJSPREADDYN_IMM8_V8_V8, - &&HANDLE_BUILTIN_CREATEITERRESULTOBJ_IMM8_V8_V8, - &&HANDLE_BUILTIN_SUSPENDGENERATOR_IMM8_V8_V8, - &&HANDLE_BUILTIN_ASYNCFUNCTIONAWAITUNCAUGHT_IMM8_V8_V8, - &&HANDLE_BUILTIN_THROWUNDEFINEDIFHOLE_IMM8_V8_V8, - &&HANDLE_BUILTIN_CALLARG1DYN_IMM8_V8_V8, - &&HANDLE_BUILTIN_COPYDATAPROPERTIES_IMM8_V8_V8, - &&HANDLE_BUILTIN_STARRAYSPREAD_IMM8_V8_V8, - &&HANDLE_BUILTIN_GETITERATORNEXT_IMM8_V8_V8, - &&HANDLE_BUILTIN_SETOBJECTWITHPROTO_IMM8_V8_V8, - &&HANDLE_BUILTIN_CALLSPREADDYN_IMM8_V8_V8_V8, - &&HANDLE_BUILTIN_ASYNCFUNCTIONRESOLVE_IMM8_V8_V8_V8, - &&HANDLE_BUILTIN_ASYNCFUNCTIONREJECT_IMM8_V8_V8_V8, - &&HANDLE_BUILTIN_CALLARGS2DYN_IMM8_V8_V8_V8, - &&HANDLE_BUILTIN_CALLARGS3DYN_IMM8_V8_V8_V8_V8, - &&HANDLE_BUILTIN_DEFINEGETTERSETTERBYVALUE_IMM8_V8_V8_V8_V8, - &&HANDLE_BUILTIN_TRYLDGLOBALBYVALUE_IMM8_IMM16_V8, - &&HANDLE_BUILTIN_NEWOBJDYNRANGE_IMM8_IMM16_V8, - &&HANDLE_BUILTIN_TRYSTGLOBALBYVALUE_IMM8_IMM16_V8, - &&HANDLE_BUILTIN_CALLIRANGEDYN_IMM8_IMM16_V8, - &&HANDLE_BUILTIN_CALLITHISRANGEDYN_IMM8_IMM16_V8, - &&HANDLE_BUILTIN_SUPERCALL_IMM8_IMM16_V8, - &&HANDLE_BUILTIN_LDOBJBYVALUE_IMM8_IMM16_V8_V8, - &&HANDLE_BUILTIN_STOBJBYVALUE_IMM8_IMM16_V8_V8, - &&HANDLE_BUILTIN_LDOBJBYINDEX_IMM8_IMM16_V8_V8, - &&HANDLE_BUILTIN_STOBJBYINDEX_IMM8_IMM16_V8_V8, - &&HANDLE_BUILTIN_STOWNBYINDEX_IMM8_IMM16_V8_V8, - &&HANDLE_BUILTIN_STOWNBYVALUE_IMM8_IMM16_V8_V8, - &&HANDLE_BUILTIN_CREATEOBJECTWITHEXCLUDEDKEYS_IMM8_IMM16_V8_V8, - &&HANDLE_BUILTIN_STSUPERBYVALUE_IMM8_IMM16_V8_V8, - &&HANDLE_BUILTIN_LDSUPERBYVALUE_IMM8_IMM16_V8_V8, - &&HANDLE_BUILTIN_IMPORTMODULE_IMM8_ID32, - &&HANDLE_BUILTIN_STMODULEVAR_IMM8_ID32, - &&HANDLE_BUILTIN_DEFINEFUNCDYN_IMM8_ID16_V8, - &&HANDLE_BUILTIN_DEFINENCFUNCDYN_IMM8_ID16_V8, - &&HANDLE_BUILTIN_DEFINEGENERATORFUNC_IMM8_ID16_V8, - &&HANDLE_BUILTIN_DEFINEASYNCFUNC_IMM8_ID16_V8, - &&HANDLE_BUILTIN_DEFINEMETHOD_IMM8_ID16_V8, - &&HANDLE_BUILTIN_TRYLDGLOBALBYNAME_IMM8_ID32_IMM16, - &&HANDLE_BUILTIN_TRYSTGLOBALBYNAME_IMM8_ID32_IMM16, - &&HANDLE_BUILTIN_LDGLOBALVAR_IMM8_ID32_IMM16, - &&HANDLE_BUILTIN_STGLOBALVAR_IMM8_ID32_IMM16, - &&HANDLE_BUILTIN_LDOBJBYNAME_IMM8_ID32_IMM16_V8, - &&HANDLE_BUILTIN_STOBJBYNAME_IMM8_ID32_IMM16_V8, - &&HANDLE_BUILTIN_STOWNBYNAME_IMM8_ID32_IMM16_V8, - &&HANDLE_BUILTIN_LDMODVARBYNAME_IMM8_ID32_IMM16_V8, - &&HANDLE_BUILTIN_LDSUPERBYNAME_IMM8_ID32_IMM16_V8, - &&HANDLE_BUILTIN_STSUPERBYNAME_IMM8_ID32_IMM16_V8, - &&HANDLE_BUILTIN_STLEXVARDYN_IMM8_IMM16_IMM16_V8, - &&HANDLE_BUILTIN_LDLEXVARDYN_IMM8_IMM16_IMM16, - &&HANDLE_BUILTIN_NEWLEXENVDYN_IMM8_IMM16, - &&HANDLE_BUILTIN_COPYRESTARGS_IMM8_IMM16, - &&HANDLE_BUILTIN_CREATEOBJECTWITHBUFFER_IMM8_IMM16, - &&HANDLE_BUILTIN_CREATEARRAYWITHBUFFER_IMM8_IMM16, - &&HANDLE_BUILTIN_CREATEOBJECTHAVINGMETHOD_IMM8_IMM16, - &&HANDLE_BUILTIN_THROWIFSUPERNOTCORRECTCALL_IMM8_IMM16, - &&HANDLE_BUILTIN_DEFINECLASSWITHBUFFER_IMM8_ID16_IMM16_V8_V8, &&HANDLE_RETURN_DYN, &&HANDLE_MOV_V4_V4, &&HANDLE_JNEZ_IMM8, &&HANDLE_JNEZ_IMM16, &&EXCEPTION_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, - &&OVERFLOW_HANDLER, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, + &&HANDLE_OVERFLOW, diff --git a/ecmascript/intrinsics.cpp b/ecmascript/intrinsics.cpp deleted file mode 100644 index 30d943cd615c27f9b3b784a643fd4d9fbec8b464..0000000000000000000000000000000000000000 --- a/ecmascript/intrinsics.cpp +++ /dev/null @@ -1,810 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#include "intrinsics.h" - -namespace panda::ecmascript::intrinsics { -DecodedTaggedValue Ldnan() -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldinfinity() -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldglobalthis() -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldundefined() -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldboolean([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldnumber([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldstring([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldbigint([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldnull() -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldsymbol() -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldobject([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldfunction([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldglobal() -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldtrue() -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ldfalse() -{ - UNREACHABLE(); -} - -DecodedTaggedValue Add2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Sub2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -// 12.6.3 Runtime Semantics: Evaluation -DecodedTaggedValue Mul2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -// 12.6.3 Runtime Semantics: Evaluation -DecodedTaggedValue Div2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -// 12.6.3 Runtime Semantics: Evaluation -DecodedTaggedValue Mod2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue ExpDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue EqDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue NotEqDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue StrictEqDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue StrictNotEqDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LessDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LessEqDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue GreaterDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue GreaterEqDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdObjByValue([[maybe_unused]] uint16_t slotId, [[maybe_unused]] int64_t objValue, - [[maybe_unused]] int64_t objTag, [[maybe_unused]] int64_t propValue, - [[maybe_unused]] int64_t propTag) -{ - UNREACHABLE(); -} - -void StObjByValue([[maybe_unused]] uint16_t slotId, [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t propValue, [[maybe_unused]] int64_t propTag, - [[maybe_unused]] int64_t valValue, [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue TryLdGlobalByValue([[maybe_unused]] uint16_t slotId, [[maybe_unused]] int64_t propValue, - [[maybe_unused]] int64_t propTag) -{ - UNREACHABLE(); -} - -void TryStGlobalByValue([[maybe_unused]] uint16_t slotId, [[maybe_unused]] int64_t propValue, - [[maybe_unused]] int64_t propTag, [[maybe_unused]] int64_t valValue, - [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue TryLdGlobalByName([[maybe_unused]] uint32_t stringId, [[maybe_unused]] uint16_t slotId) -{ - UNREACHABLE(); -} - -void TryStGlobalByName([[maybe_unused]] uint32_t stringId, [[maybe_unused]] uint16_t slotId, - [[maybe_unused]] int64_t valValue, [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdGlobalVar([[maybe_unused]] uint32_t stringId, [[maybe_unused]] uint16_t slotId) -{ - UNREACHABLE(); -} - -void StGlobalVar([[maybe_unused]] uint32_t stringId, [[maybe_unused]] uint16_t slotId, - [[maybe_unused]] int64_t valValue, [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdObjByName([[maybe_unused]] uint32_t stringId, [[maybe_unused]] uint16_t slotId, - [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -void StObjByName([[maybe_unused]] uint32_t stringId, [[maybe_unused]] uint16_t slotId, - [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, [[maybe_unused]] int64_t valValue, - [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdObjByIndex([[maybe_unused]] uint16_t slotId, [[maybe_unused]] int64_t objValue, - [[maybe_unused]] int64_t objTag, [[maybe_unused]] int64_t idxValue, - [[maybe_unused]] int64_t idxTag) -{ - UNREACHABLE(); -} - -void StObjByIndex([[maybe_unused]] uint16_t slotId, [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t idxValue, [[maybe_unused]] int64_t idxTag, [[maybe_unused]] int64_t valValue, - [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue And2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Or2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Xor2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Shl2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Shr2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Ashr2Dyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Tonumber([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue NegDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue NotDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue IncDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue DecDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -void ThrowDyn([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Delobjprop([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t propValue, [[maybe_unused]] int64_t propTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Defineglobalvar([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, - [[maybe_unused]] int64_t a1, [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Definelocalvar([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Definefuncexpr([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - return DecodedTaggedValue(0, 0); -} - -DecodedTaggedValue DefinefuncDyn([[maybe_unused]] uint32_t methodId, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -// define not constructor function -DecodedTaggedValue DefineNCFuncDyn([[maybe_unused]] uint32_t methodId, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1, [[maybe_unused]] int64_t a2, - [[maybe_unused]] int64_t t2) -{ - UNREACHABLE(); -} - -// a0 is args' length which include ctor and new_target, and a1 is the start index of args -DecodedTaggedValue NewobjDynrange([[maybe_unused]] uint16_t numArgs, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue RefeqDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue TypeofDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Callruntimerange([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, - [[maybe_unused]] int64_t a1, [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdLexVarDyn([[maybe_unused]] uint16_t level, [[maybe_unused]] uint16_t slot) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdlexenvDyn() -{ - UNREACHABLE(); -} - -DecodedTaggedValue PopLexenvDyn() -{ - UNREACHABLE(); -} - -DecodedTaggedValue IsinDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue InstanceofDyn([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue NewobjspreadDyn([[maybe_unused]] int64_t funcValue, [[maybe_unused]] int64_t funcTag, - [[maybe_unused]] int64_t targetValue, [[maybe_unused]] int64_t targetTag, - [[maybe_unused]] int64_t arrValue, [[maybe_unused]] int64_t arrTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CallspreadDyn([[maybe_unused]] int64_t funcValue, [[maybe_unused]] int64_t funcTag, - [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t arrValue, [[maybe_unused]] int64_t arrTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue NewlexenvDyn([[maybe_unused]] uint16_t numSlot) -{ - UNREACHABLE(); -} - -void StLexVarDyn([[maybe_unused]] uint16_t level, [[maybe_unused]] uint16_t slot, [[maybe_unused]] int64_t valueValue, - [[maybe_unused]] int64_t valueTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue GetUnmappedArgs() -{ - UNREACHABLE(); -} - -DecodedTaggedValue Toboolean([[maybe_unused]] int64_t value, [[maybe_unused]] int64_t tag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue GetPropIterator([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue DefineGeneratorFunc([[maybe_unused]] uint32_t methodId, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CreateIterResultObj([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, - [[maybe_unused]] int64_t a1, [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue SuspendGenerator([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, - [[maybe_unused]] int64_t a1, [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue ResumeGenerator([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue GetResumeMode([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CreateGeneratorObj([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -DecodedTaggedValue DefineAsyncFunc([[maybe_unused]] uint32_t methodId, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue AsyncFunctionEnter() -{ - UNREACHABLE(); -} - -DecodedTaggedValue AsyncFunctionAwaitUncaught([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, - [[maybe_unused]] int64_t a1, [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue AsyncFunctionResolve([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, - [[maybe_unused]] int64_t a1, [[maybe_unused]] int64_t t1, - [[maybe_unused]] int64_t a2, [[maybe_unused]] int64_t t2) -{ - UNREACHABLE(); -} - -DecodedTaggedValue AsyncFunctionReject([[maybe_unused]] int64_t a0, [[maybe_unused]] int64_t t0, - [[maybe_unused]] int64_t a1, [[maybe_unused]] int64_t t1, - [[maybe_unused]] int64_t a2, [[maybe_unused]] int64_t t2) -{ - UNREACHABLE(); -} - -void ThrowUndefined([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -void ThrowConstAssignment([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -void ThrowUndefinedIfHole([[maybe_unused]] int64_t accValue, [[maybe_unused]] int64_t accTag, - [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue Copyrestargs([[maybe_unused]] uint16_t index) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdHole() -{ - UNREACHABLE(); -} - -DecodedTaggedValue GetTemplateObject([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue GetNextPropName([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -void ReturnUndefined() -{ - UNREACHABLE(); -} - -DecodedTaggedValue CallArg0Dyn([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CallArg1Dyn([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t arg0Value, [[maybe_unused]] int64_t arg0Tag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CallArgs2Dyn([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t arg0Value, [[maybe_unused]] int64_t arg0Tag, - [[maybe_unused]] int64_t arg1Value, [[maybe_unused]] int64_t arg1Tag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CallArgs3Dyn([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t arg0Value, [[maybe_unused]] int64_t arg0Tag, - [[maybe_unused]] int64_t arg1Value, [[maybe_unused]] int64_t arg1Tag, - [[maybe_unused]] int64_t arg2Value, [[maybe_unused]] int64_t arg2Vag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CalliRangeDyn([[maybe_unused]] uint16_t num, [[maybe_unused]] int64_t objValue, - [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CalliThisRangeDyn([[maybe_unused]] uint16_t num, [[maybe_unused]] int64_t objValue, - [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CreateEmptyObject() -{ - UNREACHABLE(); -} - -DecodedTaggedValue CreateObjectWithBuffer([[maybe_unused]] uint16_t index) -{ - UNREACHABLE(); -} - -void SetObjectWithProto([[maybe_unused]] int64_t protoValue, [[maybe_unused]] int64_t protoTag, - [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CopyDataProperties([[maybe_unused]] int64_t dstValue, [[maybe_unused]] int64_t dstTag, - [[maybe_unused]] int64_t srcValue, [[maybe_unused]] int64_t srcTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue DefineGetterSetterByValue([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t propValue, [[maybe_unused]] int64_t propTag, - [[maybe_unused]] int64_t getterValue, [[maybe_unused]] int64_t getterTag, - [[maybe_unused]] int64_t setterValue, [[maybe_unused]] int64_t setterTag, - [[maybe_unused]] int64_t flagValue, [[maybe_unused]] int64_t flagTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CreateEmptyArray() -{ - UNREACHABLE(); -} - -DecodedTaggedValue CreateArrayWithBuffer([[maybe_unused]] uint16_t index) -{ - UNREACHABLE(); -} - -void StOwnByIndex([[maybe_unused]] uint16_t slotId, [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t idxValue, [[maybe_unused]] int64_t idxTag, [[maybe_unused]] int64_t valValue, - [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -void StOwnByName([[maybe_unused]] uint32_t stringId, [[maybe_unused]] uint16_t slotId, - [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, [[maybe_unused]] int64_t valValue, - [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -void StOwnByValue([[maybe_unused]] uint16_t slotId, [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t propValue, [[maybe_unused]] int64_t propTag, - [[maybe_unused]] int64_t valValue, [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue StArraySpread([[maybe_unused]] int64_t dstValue, [[maybe_unused]] int64_t dstTag, - [[maybe_unused]] int64_t indexValue, [[maybe_unused]] int64_t indexTag, - [[maybe_unused]] int64_t srcValue, [[maybe_unused]] int64_t srcTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue GetIterator([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -void ThrowIfNotObject([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -void ThrowThrowNotExists() -{ - UNREACHABLE(); -} - -DecodedTaggedValue CreateObjectWithExcludedKeys([[maybe_unused]] uint16_t numKeys, [[maybe_unused]] int64_t objValue, - [[maybe_unused]] int64_t objTag, [[maybe_unused]] int64_t a0, - [[maybe_unused]] int64_t t0) -{ - UNREACHABLE(); -} - -void ThrowPatternNonCoercible() -{ - UNREACHABLE(); -} - -DecodedTaggedValue IterNext([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue GetIteratorNext([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t methodValue, [[maybe_unused]] int64_t methodTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CloseIterator([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue ImportModule([[maybe_unused]] uint32_t stringId) -{ - UNREACHABLE(); -} - -void StModuleVar([[maybe_unused]] uint32_t stringId, [[maybe_unused]] int64_t valValue, [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -void CopyModule([[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdModvarByName([[maybe_unused]] uint32_t stringId, [[maybe_unused]] uint16_t slotId, - [[maybe_unused]] int64_t objTag, [[maybe_unused]] int64_t objValue) -{ - return DecodedTaggedValue(0, 0); -} - -DecodedTaggedValue DefineClassWithBuffer([[maybe_unused]] uint32_t methodId, [[maybe_unused]] uint16_t literalIndex, - [[maybe_unused]] int64_t lexenvValue, [[maybe_unused]] int64_t lexenvTag, - [[maybe_unused]] int64_t parentValue, [[maybe_unused]] int64_t parentTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue SuperCall([[maybe_unused]] uint16_t range, [[maybe_unused]] int64_t firstVRegValue, - [[maybe_unused]] int64_t firstVRegTag, [[maybe_unused]] int64_t objValue, - [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue SuperCallSpread([[maybe_unused]] int64_t arrayValue, [[maybe_unused]] int64_t arrayTag, - [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue DefineMethod([[maybe_unused]] uint32_t methodId, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1, [[maybe_unused]] int64_t a2, [[maybe_unused]] int64_t t2) -{ - UNREACHABLE(); -} - -void StSuperByName([[maybe_unused]] uint32_t stringId, [[maybe_unused]] uint16_t slotId, - [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag, - [[maybe_unused]] int64_t valValue, [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdSuperByName([[maybe_unused]] uint32_t stringId, [[maybe_unused]] uint16_t slotId, - [[maybe_unused]] int64_t objValue, [[maybe_unused]] int64_t objTag) -{ - UNREACHABLE(); -} - -void StSuperByValue([[maybe_unused]] uint16_t slotId, [[maybe_unused]] int64_t objValue, - [[maybe_unused]] int64_t objTag, [[maybe_unused]] int64_t propValue, - [[maybe_unused]] int64_t propTag, [[maybe_unused]] int64_t valValue, - [[maybe_unused]] int64_t valTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdSuperByValue([[maybe_unused]] uint16_t slotId, [[maybe_unused]] int64_t objValue, - [[maybe_unused]] int64_t objTag, [[maybe_unused]] int64_t propValue, - [[maybe_unused]] int64_t propTag) -{ - UNREACHABLE(); -} - -DecodedTaggedValue CreateObjectHavingMethod([[maybe_unused]] uint16_t index, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -void ThrowIfSuperNotCorrectCall([[maybe_unused]] uint16_t index, [[maybe_unused]] int64_t a1, - [[maybe_unused]] int64_t t1) -{ - UNREACHABLE(); -} - -DecodedTaggedValue LdHomeObject() -{ - UNREACHABLE(); -} - -void ThrowDeleteSuperProperty() -{ - UNREACHABLE(); -} - -void Debugger() -{ - UNREACHABLE(); -} -} // namespace panda::ecmascript::intrinsics diff --git a/ecmascript/jobs/micro_job_queue.h b/ecmascript/jobs/micro_job_queue.h index 8aa424acf0e65a813106c0a9cbfcb18a36d4436b..c2b4d128a4efdbd52ce331e9416b0f25d95162cb 100644 --- a/ecmascript/jobs/micro_job_queue.h +++ b/ecmascript/jobs/micro_job_queue.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MICRO_JOB_QUEUE_H -#define PANDA_RUNTIME_ECMASCRIPT_MICRO_JOB_QUEUE_H +#ifndef ECMASCRIPT_JOBS_MICRO_JOB_QUEUE_H +#define ECMASCRIPT_JOBS_MICRO_JOB_QUEUE_H #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/ecma_string.h" @@ -53,4 +53,4 @@ public: DECL_VISIT_OBJECT(PROMISE_JOB_QUEUE_OFFSET, SIZE) }; } // namespace panda::ecmascript::job -#endif // PANDA_RUNTIME_ECMASCRIPT_MICRO_JOB_QUEUE_H +#endif // ECMASCRIPT_JOBS_MICRO_JOB_QUEUE_H diff --git a/ecmascript/jobs/pending_job.h b/ecmascript/jobs/pending_job.h index 22ca20656ec9434b9f41b3d2cda6771aa287cdbe..ff3b14229ab88a12241f7fe589e64aede378ce96 100644 --- a/ecmascript/jobs/pending_job.h +++ b/ecmascript/jobs/pending_job.h @@ -13,10 +13,11 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_PENDING_JOB_H -#define PANDA_RUNTIME_ECMASCRIPT_PENDING_JOB_H +#ifndef ECMASCRIPT_JOBS_PENDING_JOB_H +#define ECMASCRIPT_JOBS_PENDING_JOB_H #include "ecmascript/ecma_macros.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_function.h" #include "ecmascript/record.h" #include "ecmascript/js_handle.h" @@ -39,7 +40,9 @@ public: ASSERT(job->IsCallable()); JSHandle thisValue(thread, JSTaggedValue::Undefined()); JSHandle argv(thread, pendingJob->GetArguments()); - return JSFunction::Call(thread, job, thisValue, argv); + InternalCallParams *args = thread->GetInternalCallParams(); + args->MakeArgList(*argv); + return JSFunction::Call(thread, job, thisValue, argv->GetLength(), args->GetArgv()); } static constexpr size_t JOB_OFFSET = Record::SIZE; @@ -51,4 +54,4 @@ public: DECL_VISIT_OBJECT(JOB_OFFSET, SIZE) }; } // namespace panda::ecmascript::job -#endif // PANDA_RUNTIME_ECMASCRIPT_PENDING_JOB_H +#endif // ECMASCRIPT_JOBS_PENDING_JOB_H diff --git a/ecmascript/js_arguments.cpp b/ecmascript/js_arguments.cpp index 6c8177d8f96ea13ea1e6906944f9ea13b2d25ff7..307423b9015a02924dae4a61c4c3157f35e146f5 100644 --- a/ecmascript/js_arguments.cpp +++ b/ecmascript/js_arguments.cpp @@ -48,7 +48,7 @@ bool JSArguments::GetOwnProperty(JSThread *thread, const JSHandle & // 8.If IsDataDescriptor(desc) is true and P is "caller" and desc.[[Value]] is a strict mode Function object, // throw a TypeError exception. - JSHandle caller = thread->GetEcmaVM()->GetFactory()->NewFromString("caller"); + JSHandle caller = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("caller"); if (desc.IsDataDescriptor() && JSTaggedValue::SameValue(key.GetTaggedValue(), caller.GetTaggedValue()) && desc.GetValue()->IsJSFunction()) { THROW_TYPE_ERROR_AND_RETURN(thread, "Arguments GetOwnProperty: type error", false); diff --git a/ecmascript/js_arguments.h b/ecmascript/js_arguments.h index e4af84254fc0574f2edbaf57c4aa01ab36a8433e..ba69c599d5450d3169f77fa0bae8ed6cf0ae6be2 100644 --- a/ecmascript/js_arguments.h +++ b/ecmascript/js_arguments.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSARGUMENTS_H -#define PANDA_RUNTIME_ECMASCRIPT_JSARGUMENTS_H +#ifndef ECMASCRIPT_JSARGUMENTS_H +#define ECMASCRIPT_JSARGUMENTS_H #include "ecmascript/js_object.h" #include "ecmascript/tagged_array.h" @@ -70,4 +70,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSARGUMENTS_H +#endif // ECMASCRIPT_JSARGUMENTS_H diff --git a/ecmascript/js_array.cpp b/ecmascript/js_array.cpp index d23828bb8901f7f23eaaabb07e9c87b812adbb0b..c48c280693a07e308aa9ac460be31b7e37687455 100644 --- a/ecmascript/js_array.cpp +++ b/ecmascript/js_array.cpp @@ -17,6 +17,7 @@ #include "ecmascript/accessor_data.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_invoker.h" #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/object_factory.h" @@ -155,10 +156,10 @@ JSTaggedValue JSArray::ArraySpeciesCreate(JSThread *thread, const JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(1); - args->Set(thread, 0, JSTaggedValue(arrayLength)); JSHandle newTarget(thread, JSTaggedValue::Undefined()); - JSTaggedValue result = JSFunction::Construct(thread, constructor, args, newTarget); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(arrayLength)); + JSTaggedValue result = JSFunction::Construct(thread, constructor, 1, arguments->GetArgv(), newTarget); // NOTEIf originalArray was created using the standard built-in Array constructor for // a Realm that is not the Realm of the running execution context, then a new Array is diff --git a/ecmascript/js_array.h b/ecmascript/js_array.h index d311ae6498ea5fc9ac4ee20a610423f9185976ce..9a15eb47a41d81f1373c54cf1195bbce84afc9e8 100644 --- a/ecmascript/js_array.h +++ b/ecmascript/js_array.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JSARRAY_H +#ifndef ECMASCRIPT_JSARRAY_H +#define ECMASCRIPT_JSARRAY_H #include #include "ecmascript/js_object.h" @@ -96,4 +96,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSARRAY_H +#endif // ECMASCRIPT_JSARRAY_H diff --git a/ecmascript/js_array_iterator.h b/ecmascript/js_array_iterator.h index c604aff2fb0a0bd9308a76220dfbbca6a1fc53da..7c8427869b7718caebe0ad605afadcb8eeea8241 100644 --- a/ecmascript/js_array_iterator.h +++ b/ecmascript/js_array_iterator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_ARRAY_ITERATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_ARRAY_ITERATOR_H +#ifndef ECMASCRIPT_JS_ARRAY_ITERATOR_H +#define ECMASCRIPT_JS_ARRAY_ITERATOR_H #include "js_iterator.h" #include "js_object.h" @@ -40,4 +40,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_ARRAY_ITERATOR_H +#endif // ECMASCRIPT_JS_ARRAY_ITERATOR_H diff --git a/ecmascript/js_arraybuffer.h b/ecmascript/js_arraybuffer.h index 0be53df9ef3270712cfa2b0beecd105833f2709d..18afaf06c33f50bb85b774e0d0308738d715fcba 100644 --- a/ecmascript/js_arraybuffer.h +++ b/ecmascript/js_arraybuffer.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSARRAYBUFFER_H -#define PANDA_RUNTIME_ECMASCRIPT_JSARRAYBUFFER_H +#ifndef ECMASCRIPT_JSARRAYBUFFER_H +#define ECMASCRIPT_JSARRAYBUFFER_H #include "ecmascript/js_object.h" @@ -47,4 +47,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSARRAYBUFFER_H \ No newline at end of file +#endif // ECMASCRIPT_JSARRAYBUFFER_H \ No newline at end of file diff --git a/ecmascript/js_async_function.cpp b/ecmascript/js_async_function.cpp index 94a734def059c4aae74766e5e9a4ce8f22aaf9c1..7a36ed2e18f339e2f8d26e262b7dd37a72092b49 100644 --- a/ecmascript/js_async_function.cpp +++ b/ecmascript/js_async_function.cpp @@ -20,6 +20,7 @@ #include "ecmascript/ecma_vm.h" #include "ecmascript/generator_helper.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_promise.h" #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/object_factory.h" @@ -45,9 +46,9 @@ void JSAsyncFunction::AsyncFunctionAwait(JSThread *thread, const JSHandle resolve(thread, pcap->GetResolve()); JSHandle thisArg = globalConst->GetHandledUndefined(); - JSHandle args = factory->NewTaggedArray(1); - args->Set(thread, 0, value); - [[maybe_unused]] JSTaggedValue res = JSFunction::Call(thread, resolve, thisArg, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(value); + [[maybe_unused]] JSTaggedValue res = JSFunction::Call(thread, resolve, thisArg, 1, arguments->GetArgv()); // 4.Let onFulfilled be a new built-in function object as defined in AsyncFunction Awaited Fulfilled. JSHandle fulFunc = diff --git a/ecmascript/js_async_function.h b/ecmascript/js_async_function.h index 92c59568b9b30353bd1a4bd5f1e0073da62b9627..a79b7bf136bd26c59f16c31b8dd04168e4c20492 100644 --- a/ecmascript/js_async_function.h +++ b/ecmascript/js_async_function.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_ASYNC_FUNCTION_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_ASYNC_FUNCTION_H +#ifndef ECMASCRIPT_JS_ASYNC_FUNCTION_H +#define ECMASCRIPT_JS_ASYNC_FUNCTION_H #include "ecmascript/ecma_macros.h" #include "ecmascript/js_tagged_value.h" @@ -63,4 +63,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_ASYNC_FUNCTION_H +#endif // ECMASCRIPT_JS_ASYNC_FUNCTION_H diff --git a/ecmascript/js_collator.cpp b/ecmascript/js_collator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54b2b9c20bf319ce81f5e66258a8afc6f3ba8172 --- /dev/null +++ b/ecmascript/js_collator.cpp @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "ecmascript/js_collator.h" + +#include "unicode/udata.h" + +#include "ecmascript/global_env.h" +#include "ecmascript/mem/c_string.h" + +namespace panda::ecmascript { +// NOLINTNEXTLINE (readability-identifier-naming, fuchsia-statically-constructed-objects) +const CString JSCollator::uIcuDataColl = U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "coll"; +const std::map JSCollator::caseFirstMap = { + {"upper", CaseFirstOption::UPPER}, + {"lower", CaseFirstOption::LOWER}, + {"false", CaseFirstOption::FALSE_OPTION} +}; +const std::map JSCollator::uColAttributeValueMap = { + {CaseFirstOption::UPPER, UCOL_UPPER_FIRST}, + {CaseFirstOption::LOWER, UCOL_LOWER_FIRST}, + {CaseFirstOption::FALSE_OPTION, UCOL_OFF}, + {CaseFirstOption::UNDEFINED, UCOL_OFF} +}; + +JSHandle JSCollator::GetAvailableLocales(JSThread *thread) +{ + const char *key = nullptr; + const char *path = JSCollator::uIcuDataColl.c_str(); + JSHandle availableLocales = JSLocale::GetAvailableLocales(thread, key, path); + return availableLocales; +} + +void JSCollator::SetIcuCollator(JSThread *thread, icu::Collator *icuCollator, const DeleteEntryPoint &callback) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + ASSERT(icuCollator != nullptr); + JSTaggedValue data = GetIcuField(); + if (data.IsJSNativePointer()) { + JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject()); + native->ResetExternalPointer(icuCollator); + return; + } + JSHandle pointer = factory->NewJSNativePointer(icuCollator); + pointer->SetDeleter(callback); + SetIcuField(thread, pointer.GetTaggedValue()); + ecmaVm->PushToArrayDataList(*pointer); +} + +JSHandle JSCollator::InitializeCollator(JSThread *thread, const JSHandle &collator, + const JSHandle &locales, + const JSHandle &options) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + const GlobalEnvConstants *globalConst = thread->GlobalConstants(); + // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread); + + // 2. If options is undefined, then + // a. Let options be ObjectCreate(null). + // 3. Else, + // a. Let options be ? ToObject(options). + JSHandle optionsObject; + if (options->IsUndefined()) { + JSHandle nullValue = globalConst->GetHandledNull(); + optionsObject = factory->OrdinaryNewJSObjectCreate(nullValue); + } else { + optionsObject = JSTaggedValue::ToObject(thread, options); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread); + } + // 4. Let usage be ? GetOption(options, "usage", "string", « "sort", "search" », "sort"). + auto usage = JSLocale::GetOptionOfString(thread, optionsObject, globalConst->GetHandledUsageString(), + {UsageOption::SORT, UsageOption::SEARCH}, {"sort", "search"}, + UsageOption::SORT); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread); + JSHandle usageValue(thread, JSTaggedValue(static_cast(usage))); + collator->SetUsage(thread, usageValue); + + // 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + auto matcher = JSLocale::GetOptionOfString( + thread, optionsObject, globalConst->GetHandledLocaleMatcherString(), + {LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT}, {"lookup", "best fit"}, + LocaleMatcherOption::BEST_FIT); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread); + + // 6. Let collation be ? GetOption(options, "collation", "string", undefined, undefined). + // 7. If collation is not undefined, then + // a. If collation does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception. + JSHandle collation = + JSLocale::GetOption(thread, optionsObject, globalConst->GetHandledCollationString(), OptionType::STRING, + globalConst->GetHandledUndefined(), globalConst->GetHandledUndefined()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread); + collator->SetCollation(thread, collation); + std::string collationStr; + if (!collation->IsUndefined()) { + JSHandle collationEcmaStr = JSHandle::Cast(collation); + collationStr = JSLocale::ConvertToStdString(collationEcmaStr); + if (!JSLocale::IsWellAlphaNumList(collationStr)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid collation", collator); + } + } + + // 8. Let numeric be ? GetOption(options, "numeric", "boolean", undefined, undefined). + bool numeric = false; + bool foundNumeric = + JSLocale::GetOptionOfBool(thread, optionsObject, globalConst->GetHandledNumericString(), false, &numeric); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread); + JSHandle numericValue(thread, JSTaggedValue(numeric)); + collator->SetNumeric(thread, numericValue); + + // 14. Let caseFirst be ? GetOption(options, "caseFirst", "string", « "upper", "lower", "false" », undefined). + auto caseFirst = JSLocale::GetOptionOfString( + thread, optionsObject, globalConst->GetHandledCaseFirstString(), + {CaseFirstOption::UPPER, CaseFirstOption::LOWER, CaseFirstOption::FALSE_OPTION}, {"upper", "lower", "false"}, + CaseFirstOption::UNDEFINED); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread); + JSHandle caseFirstValue(thread, JSTaggedValue(static_cast(caseFirst))); + collator->SetCaseFirst(thread, caseFirstValue); + + // 16. Let relevantExtensionKeys be %Collator%.[[RelevantExtensionKeys]]. + std::set relevantExtensionKeys = {"co", "kn", "kf"}; + + // 17. Let r be ResolveLocale(%Collator%.[[AvailableLocales]], requestedLocales, opt, + // %Collator%.[[RelevantExtensionKeys]], localeData). + JSHandle availableLocales; + if (requestedLocales->GetLength() == 0) { + availableLocales = factory->EmptyArray(); + } else { + availableLocales = GetAvailableLocales(thread); + } + ResolvedLocale r = + JSLocale::ResolveLocale(thread, availableLocales, requestedLocales, matcher, relevantExtensionKeys); + icu::Locale icuLocale = r.localeData; + JSHandle localeStr = JSLocale::ToLanguageTag(thread, icuLocale); + collator->SetLocale(thread, localeStr.GetTaggedValue()); + ASSERT_PRINT(!icuLocale.isBogus(), "icuLocale is bogus"); + + // If collation is undefined iterate RelevantExtensionKeys to find "co" + // if found, set ICU collator UnicodeKeyword to iterator->second + UErrorCode status = U_ZERO_ERROR; + if (!collation->IsUndefined()) { + auto extensionIter = r.extensions.find("co"); + if (extensionIter != r.extensions.end() && extensionIter->second != collationStr) { + icuLocale.setUnicodeKeywordValue("co", nullptr, status); + ASSERT_PRINT(U_SUCCESS(status), "icuLocale set co failed"); + } + } + + // If usage is serach set co-serach to icu locale key word value + // Eles set collation string to icu locale key word value + if (usage == UsageOption::SEARCH) { + icuLocale.setUnicodeKeywordValue("co", "search", status); + ASSERT(U_SUCCESS(status)); + } else { + if (!collationStr.empty() && JSLocale::IsWellCollation(icuLocale, collationStr)) { + icuLocale.setUnicodeKeywordValue("co", collationStr, status); + ASSERT(U_SUCCESS(status)); + } + } + + std::unique_ptr icuCollator(icu::Collator::createInstance(icuLocale, status)); + if (U_FAILURE(status) || icuCollator == nullptr) { // NOLINT(readability-implicit-bool-conversion) + status = U_ZERO_ERROR; + icu::Locale localeName(icuLocale.getBaseName()); + icuCollator.reset(icu::Collator::createInstance(localeName, status)); + if (U_FAILURE(status) || icuCollator == nullptr) { // NOLINT(readability-implicit-bool-conversion) + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid collation", collator); + } + } + ASSERT(U_SUCCESS(status)); + icu::Locale collatorLocale(icuCollator->getLocale(ULOC_VALID_LOCALE, status)); + + icuCollator->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); + ASSERT(U_SUCCESS(status)); + + // If numeric is found set ICU collator UCOL_NUMERIC_COLLATION to numeric + // Else iterate RelevantExtensionKeys to find "kn" + // if found, set ICU collator UCOL_NUMERIC_COLLATION to iterator->second + status = U_ZERO_ERROR; + if (foundNumeric) { + ASSERT(icuCollator.get() != nullptr); + icuCollator.get()->setAttribute(UCOL_NUMERIC_COLLATION, numeric ? UCOL_ON : UCOL_OFF, status); + ASSERT(U_SUCCESS(status)); + } else { + auto extensionIter = r.extensions.find("kn"); + if (extensionIter != r.extensions.end()) { + ASSERT(icuCollator.get() != nullptr); + bool found = (extensionIter->second == "true"); + JSHandle isNumeric(thread, JSTaggedValue(found)); + collator->SetNumeric(thread, isNumeric); + icuCollator.get()->setAttribute(UCOL_NUMERIC_COLLATION, found ? UCOL_ON : UCOL_OFF, status); + ASSERT(U_SUCCESS(status)); + } + } + + // If caseFirst is not undefined set ICU collator UColAttributeValue to caseFirst + // Else iterate RelevantExtensionKeys to find "kf" + // if found, set ICU collator UColAttributeValue to iterator->second + status = U_ZERO_ERROR; + if (caseFirst != CaseFirstOption::UNDEFINED) { + ASSERT(icuCollator.get() != nullptr); + icuCollator.get()->setAttribute(UCOL_CASE_FIRST, OptionToUColAttribute(caseFirst), status); + ASSERT(U_SUCCESS(status)); + } else { + auto extensionIter = r.extensions.find("kf"); + if (extensionIter != r.extensions.end()) { + ASSERT(icuCollator.get() != nullptr); + auto mapIter = caseFirstMap.find(extensionIter->second); + if (mapIter != caseFirstMap.end()) { + icuCollator.get()->setAttribute(UCOL_CASE_FIRST, OptionToUColAttribute(mapIter->second), status); + JSHandle caseFirstValue(thread, JSTaggedValue(static_cast(mapIter->second))); + collator->SetCaseFirst(thread, caseFirstValue); + } else { + icuCollator.get()->setAttribute(UCOL_CASE_FIRST, OptionToUColAttribute(CaseFirstOption::UNDEFINED), + status); + } + ASSERT(U_SUCCESS(status)); + } + } + + // 24. Let sensitivity be ? GetOption(options, "sensitivity", "string", « "base", "accent", "case", "variant" », + // undefined). + auto sensitivity = JSLocale::GetOptionOfString( + thread, optionsObject, globalConst->GetHandledSensitivityString(), + {SensitivityOption::BASE, SensitivityOption::ACCENT, SensitivityOption::CASE, SensitivityOption::VARIANT}, + {"base", "accent", "case", "variant"}, SensitivityOption::UNDEFINED); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSCollator, thread); + // 25. If sensitivity is undefined, then + // a. If usage is "sort", then + // i. Let sensitivity be "variant". + if (sensitivity == SensitivityOption::UNDEFINED) { + if (usage == UsageOption::SORT) { + sensitivity = SensitivityOption::VARIANT; + } + } + JSHandle sensitivityValue(thread, JSTaggedValue(static_cast(sensitivity))); + collator->SetSensitivity(thread, sensitivityValue); + + // Trans SensitivityOption to Icu strength option + switch (sensitivity) { + case SensitivityOption::BASE: + icuCollator->setStrength(icu::Collator::PRIMARY); + break; + case SensitivityOption::ACCENT: + icuCollator->setStrength(icu::Collator::SECONDARY); + break; + case SensitivityOption::CASE: + icuCollator->setStrength(icu::Collator::PRIMARY); + icuCollator->setAttribute(UCOL_CASE_LEVEL, UCOL_ON, status); + break; + case SensitivityOption::VARIANT: + icuCollator->setStrength(icu::Collator::TERTIARY); + break; + case SensitivityOption::UNDEFINED: + break; + case SensitivityOption::EXCEPTION: + UNREACHABLE(); + } + + // 27. Let ignorePunctuation be ? GetOption(options, "ignorePunctuation", "boolean", undefined, false). + // 28. Set collator.[[IgnorePunctuation]] to ignorePunctuation. + bool ignorePunctuation = false; + JSLocale::GetOptionOfBool(thread, optionsObject, globalConst->GetHandledIgnorePunctuationString(), false, + &ignorePunctuation); + JSHandle ignorePunctuationValue(thread, JSTaggedValue(ignorePunctuation)); + collator->SetIgnorePunctuation(thread, ignorePunctuationValue); + if (ignorePunctuation) { + status = U_ZERO_ERROR; + icuCollator->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, status); + ASSERT(U_SUCCESS(status)); + } + + collator->SetIcuCollator(thread, icuCollator.release(), JSCollator::FreeIcuCollator); + collator->SetBoundCompare(thread, JSTaggedValue::Undefined()); + // 29. Return collator. + return collator; +} + +UColAttributeValue JSCollator::OptionToUColAttribute(CaseFirstOption caseFirstOption) +{ + auto iter = uColAttributeValueMap.find(caseFirstOption); + if (iter != uColAttributeValueMap.end()) { + return iter->second; + } + UNREACHABLE(); +} + +JSHandle OptionsToEcmaString(JSThread *thread, UsageOption usage) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (usage) { + case UsageOption::SORT: + result.Update(globalConst->GetSortString()); + break; + case UsageOption::SEARCH: + result.Update(globalConst->GetSearchString()); + break; + default: + UNREACHABLE(); + } + return result; +} + +JSHandle OptionsToEcmaString(JSThread *thread, SensitivityOption sensitivity) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (sensitivity) { + case SensitivityOption::BASE: + result.Update(globalConst->GetBaseString()); + break; + case SensitivityOption::ACCENT: + result.Update(globalConst->GetAccentString()); + break; + case SensitivityOption::CASE: + result.Update(globalConst->GetCaseString()); + break; + case SensitivityOption::VARIANT: + result.Update(globalConst->GetVariantString()); + break; + case SensitivityOption::UNDEFINED: + break; + default: + UNREACHABLE(); + } + return result; +} + +JSHandle OptionsToEcmaString(JSThread *thread, CaseFirstOption caseFirst) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (caseFirst) { + case CaseFirstOption::UPPER: + result.Update(globalConst->GetUpperString()); + break; + case CaseFirstOption::LOWER: + result.Update(globalConst->GetLowerString()); + break; + case CaseFirstOption::FALSE_OPTION: + result.Update(globalConst->GetFalseString()); + break; + case CaseFirstOption::UNDEFINED: + result.Update(globalConst->GetUpperString()); + break; + default: + UNREACHABLE(); + } + return result; +} + +// 11.3.4 Intl.Collator.prototype.resolvedOptions () +JSHandle JSCollator::ResolvedOptions(JSThread *thread, const JSHandle &collator) +{ + auto ecmaVm = thread->GetEcmaVM(); + auto globalConst = thread->GlobalConstants(); + ObjectFactory *factory = ecmaVm->GetFactory(); + JSHandle env = ecmaVm->GetGlobalEnv(); + JSHandle ctor = env->GetObjectFunction(); + JSHandle funCtor = JSHandle::Cast(env->GetObjectFunction()); + JSHandle options(factory->NewJSObjectByConstructor(funCtor, ctor)); + + // [[Locale]] + JSHandle property = globalConst->GetHandledLocaleString(); + JSHandle locale(thread, collator->GetLocale()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, locale); + + // [[Usage]] + UsageOption usageOption = static_cast(collator->GetUsage().GetNumber()); + JSHandle usageValue = OptionsToEcmaString(thread, usageOption); + JSObject::CreateDataProperty(thread, options, globalConst->GetHandledUsageString(), usageValue); + + // [[Sensitivity]] + auto sentivityOption = static_cast(collator->GetSensitivity().GetNumber()); + JSHandle sensitivityValue = OptionsToEcmaString(thread, sentivityOption); + JSObject::CreateDataProperty(thread, options, globalConst->GetHandledSensitivityString(), sensitivityValue); + + // [[IgnorePunctuation]] + JSHandle ignorePunctuationValue(thread, collator->GetIgnorePunctuation()); + JSObject::CreateDataProperty(thread, options, globalConst->GetHandledIgnorePunctuationString(), + ignorePunctuationValue); + + // [[Collation]] + JSMutableHandle collationValue(thread, collator->GetCollation()); + if (collationValue->IsUndefined()) { + collationValue.Update(globalConst->GetDefaultString()); + } + JSObject::CreateDataProperty(thread, options, globalConst->GetHandledCollationString(), collationValue); + + // [[Numeric]] + JSHandle numericValue(thread, collator->GetNumeric()); + JSObject::CreateDataProperty(thread, options, globalConst->GetHandledNumericString(), numericValue); + + // [[CaseFirst]] + CaseFirstOption caseFirstOption = static_cast(collator->GetCaseFirst().GetNumber()); + // In Ecma402 spec, caseFirst is an optional property so we set it to Upper when input is undefined + // the requirement maybe change in the future + JSHandle caseFirstValue = OptionsToEcmaString(thread, caseFirstOption); + JSObject::CreateDataProperty(thread, options, globalConst->GetHandledCaseFirstString(), caseFirstValue); + return options; +} + +icu::UnicodeString EcmaStringToUString(const JSHandle &string) +{ + std::string stdString(ConvertToString(*string, StringConvertedUsage::LOGICOPERATION)); + icu::StringPiece sp(stdString); + icu::UnicodeString uString = icu::UnicodeString::fromUTF8(sp); + return uString; +} + +JSTaggedValue JSCollator::CompareStrings(const icu::Collator *icuCollator, const JSHandle &string1, + const JSHandle &string2) +{ + icu::UnicodeString uString1 = EcmaStringToUString(string1); + icu::UnicodeString uString2 = EcmaStringToUString(string2); + + UCollationResult result; + UErrorCode status = U_ZERO_ERROR; + result = icuCollator->compare(uString1, uString2, status); + ASSERT(U_SUCCESS(status)); + + return JSTaggedValue(result); +} +} // namespace panda::ecmascript diff --git a/ecmascript/js_collator.h b/ecmascript/js_collator.h new file mode 100644 index 0000000000000000000000000000000000000000..77b21885bf3eb8111eab861d78b7d5be3e2d174f --- /dev/null +++ b/ecmascript/js_collator.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_JS_COLLATOR_H +#define ECMASCRIPT_JS_COLLATOR_H + +#include "js_locale.h" + +#include "unicode/udata.h" + +namespace panda::ecmascript { +enum class UsageOption : uint8_t { SORT = 0x01, SEARCH, EXCEPTION }; +enum class CaseFirstOption : uint8_t { UPPER = 0x01, LOWER, FALSE_OPTION, UNDEFINED, EXCEPTION }; +enum class SensitivityOption : uint8_t { BASE = 0x01, ACCENT, CASE, VARIANT, UNDEFINED, EXCEPTION }; + +class JSCollator : public JSObject { +public: + // NOLINTNEXTLINE (readability-identifier-naming, fuchsia-statically-constructed-objects) + static const CString uIcuDataColl; + + static const std::map caseFirstMap; + + static const std::map uColAttributeValueMap; + + static JSCollator *Cast(ObjectHeader *object) + { + ASSERT(JSTaggedValue(object).IsJSCollator()); + return reinterpret_cast(object); + } + + static constexpr size_t ICU_FIELD_OFFSET = JSObject::SIZE; + + // icu field. + ACCESSORS(IcuField, ICU_FIELD_OFFSET, LOCALE_OFFSET) + ACCESSORS(Locale, LOCALE_OFFSET, USAGE_OFFSET) + ACCESSORS(Usage, USAGE_OFFSET, SENSITIVITY_OFFSET) + ACCESSORS(Sensitivity, SENSITIVITY_OFFSET, IGNORE_PUNCTUATION_OFFSET) + ACCESSORS(IgnorePunctuation, IGNORE_PUNCTUATION_OFFSET, COLLATION_OFFSET) + ACCESSORS(Collation, COLLATION_OFFSET, NUMERIC_OFFSET) + ACCESSORS(Numeric, NUMERIC_OFFSET, CASE_FIRST_OFFSET) + ACCESSORS(CaseFirst, CASE_FIRST_OFFSET, BOUND_COMPARE_OFFSET) + ACCESSORS(BoundCompare, BOUND_COMPARE_OFFSET, SIZE) + + DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, ICU_FIELD_OFFSET, SIZE) + + icu::Collator *GetIcuCollator() const + { + ASSERT(GetIcuField().IsJSNativePointer()); + auto result = JSNativePointer::Cast(GetIcuField().GetTaggedObject())->GetExternalPointer(); + return reinterpret_cast(result); + } + + static void FreeIcuCollator(void *pointer, [[maybe_unused]] void *hint = nullptr) + { + if (pointer == nullptr) { + return; + } + auto icuCollator = reinterpret_cast(pointer); + icuCollator->~Collator(); + } + + void SetIcuCollator(JSThread *thread, icu::Collator *icuCollator, const DeleteEntryPoint &callback); + + // 11.1.1 InitializeCollator ( collator, locales, options ) + static JSHandle InitializeCollator(JSThread *thread, const JSHandle &collator, + const JSHandle &locales, + const JSHandle &options); + + // 11.3.4 Intl.Collator.prototype.resolvedOptions () + static JSHandle ResolvedOptions(JSThread *thread, const JSHandle &collator); + + static JSHandle GetAvailableLocales(JSThread *thread); + + static JSTaggedValue CompareStrings(const icu::Collator *icuCollator, const JSHandle &string1, + const JSHandle &string2); + +private: + static CaseFirstOption StringToCaseForstOption(const std::string &str); + + static UColAttributeValue OptionToUColAttribute(CaseFirstOption caseFirstOption); + + static std::set BuildLocaleSet(const std::vector &availableLocales, const char *path, + const char *key); + + static void SetNumericOption(icu::Collator *icuCollator, bool numeric); + + static void SetCaseFirstOption(icu::Collator *icuCollator, CaseFirstOption caseFirstOption); +}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_JS_COLLATOR_H \ No newline at end of file diff --git a/ecmascript/js_dataview.h b/ecmascript/js_dataview.h index 3d563f63985887e18942bd6ee46c824fda2f8517..4afef0b855e2a9a9f20412e99a69c3f571cabbf0 100644 --- a/ecmascript/js_dataview.h +++ b/ecmascript/js_dataview.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSDATAVIEW_H -#define PANDA_RUNTIME_ECMASCRIPT_JSDATAVIEW_H +#ifndef ECMASCRIPT_JSDATAVIEW_H +#define ECMASCRIPT_JSDATAVIEW_H #include "ecmascript/js_object.h" @@ -40,4 +40,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSDATAVIEW_H +#endif // ECMASCRIPT_JSDATAVIEW_H diff --git a/ecmascript/js_date.cpp b/ecmascript/js_date.cpp index ececd323c3537ec3a2733006a051286fd3b9a30f..84d2d36d62ef9c2a52ec55ad1ff2f7111e8c17e6 100644 --- a/ecmascript/js_date.cpp +++ b/ecmascript/js_date.cpp @@ -646,7 +646,7 @@ JSTaggedValue JSDate::ToDateString(JSThread *thread) const CString year = StrToTargetLength(ToCString(fields[YEAR]), STR_LENGTH_YEAR); CString day = StrToTargetLength(ToCString(fields[DAYS]), STR_LENGTH_OTHERS); CString str = weekdayName[fields[WEEKDAY]] + SPACE + monthName[fields[MONTH]] + SPACE + day + SPACE + year; - JSHandle result = thread->GetEcmaVM()->GetFactory()->NewFromString(str); + JSHandle result = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str); return result.GetTaggedValue(); } @@ -712,7 +712,7 @@ JSTaggedValue JSDate::ToISOString(JSThread *thread) const CString ms = StrToTargetLength(ToCString(fields[MS]), STR_LENGTH_OTHERS + 1); CString str = year + NEG + month + NEG + day + FLAG_TIME + hour + COLON + minute + COLON + second + POINT + ms + FLAG_UTC; - return thread->GetEcmaVM()->GetFactory()->NewFromString(str).GetTaggedValue(); + return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } CString JSDate::GetLocaleTimeStr(const std::array &fields) const @@ -756,7 +756,7 @@ JSTaggedValue JSDate::ToLocaleDateString(JSThread *thread) const return JSTaggedValue(base::NAN_VALUE); } CString str = GetLocaleDateStr(fields); - return thread->GetEcmaVM()->GetFactory()->NewFromString(str).GetTaggedValue(); + return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } // 20.4.4.39 @@ -768,7 +768,7 @@ JSTaggedValue JSDate::ToLocaleString(JSThread *thread) const } CString strDate = GetLocaleDateStr(fields); CString strTime = GetLocaleTimeStr(fields); - return thread->GetEcmaVM()->GetFactory()->NewFromString(strDate + SPACE + strTime).GetTaggedValue(); + return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(strDate + SPACE + strTime).GetTaggedValue(); } // 20.4.4.40 @@ -779,7 +779,7 @@ JSTaggedValue JSDate::ToLocaleTimeString(JSThread *thread) const return JSTaggedValue(base::NAN_VALUE); } CString str = GetLocaleTimeStr(fields); - return thread->GetEcmaVM()->GetFactory()->NewFromString(str).GetTaggedValue(); + return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } // 20.4.4.41 @@ -819,7 +819,7 @@ JSTaggedValue JSDate::ToString(JSThread *thread) const CString second = StrToTargetLength(ToCString(fields[SEC]), STR_LENGTH_OTHERS); CString str = weekday + SPACE + month + SPACE + day + SPACE + year + SPACE + hour + COLON + minute + COLON + second + SPACE + "GMT" + localTime; - return thread->GetEcmaVM()->GetFactory()->NewFromString(str).GetTaggedValue(); + return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } // 20.4.4.42 @@ -848,7 +848,7 @@ JSTaggedValue JSDate::ToTimeString(JSThread *thread) const CString minute = StrToTargetLength(ToCString(fields[MIN]), STR_LENGTH_OTHERS); CString second = StrToTargetLength(ToCString(fields[SEC]), STR_LENGTH_OTHERS); CString str = hour + COLON + minute + COLON + second + SPACE + "GMT" + localTime; - return thread->GetEcmaVM()->GetFactory()->NewFromString(str).GetTaggedValue(); + return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } // 20.4.4.43 @@ -874,7 +874,7 @@ JSTaggedValue JSDate::ToUTCString(JSThread *thread) const CString ms = StrToTargetLength(ToCString(fields[MS]), STR_LENGTH_OTHERS); CString str = weekday + COMMA + SPACE + day + SPACE + month + SPACE + year + SPACE + hour + COLON + minute + COLON + second + SPACE + "GMT"; - return thread->GetEcmaVM()->GetFactory()->NewFromString(str).GetTaggedValue(); + return thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(str).GetTaggedValue(); } // 20.4.4.44 diff --git a/ecmascript/js_date.h b/ecmascript/js_date.h index ccaf4a8127db0220dfdaf057df540e0fc21d95f4..c0040e6cdf5af1a8fd148e047f8f29f98f535613 100644 --- a/ecmascript/js_date.h +++ b/ecmascript/js_date.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSDATE_H -#define PANDA_RUNTIME_ECMASCRIPT_JSDATE_H +#ifndef ECMASCRIPT_JSDATE_H +#define ECMASCRIPT_JSDATE_H #include @@ -193,4 +193,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSDATE_H +#endif // ECMASCRIPT_JSDATE_H diff --git a/ecmascript/js_date_time_format.cpp b/ecmascript/js_date_time_format.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69db27cbb06e1d8d6976a391394aea67abe5aaf1 --- /dev/null +++ b/ecmascript/js_date_time_format.cpp @@ -0,0 +1,1461 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "js_date_time_format.h" + +#include "ecma_macros.h" +#include "global_env.h" +#include "js_array.h" +#include "js_date.h" +#include "js_intl.h" +#include "js_locale.h" +#include "js_object-inl.h" +#include "object_factory.h" + +namespace panda::ecmascript { +struct CommonDateFormatPart { + int32_t fField = 0; + int32_t fBeginIndex = 0; // NOLINT(misc-non-private-member-variables-in-classes) + int32_t fEndIndex = 0; // NOLINT(misc-non-private-member-variables-in-classes) + int32_t index = 0; // NOLINT(misc-non-private-member-variables-in-classes) + bool isPreExist = false; + + CommonDateFormatPart() = default; + CommonDateFormatPart(int32_t fField, int32_t fBeginIndex, int32_t fEndIndex, int32_t index, bool isPreExist) + : fField(fField), fBeginIndex(fBeginIndex), fEndIndex(fEndIndex), index(index), isPreExist(isPreExist) + { + } + + ~CommonDateFormatPart() = default; + + DEFAULT_COPY_SEMANTIC(CommonDateFormatPart); + DEFAULT_MOVE_SEMANTIC(CommonDateFormatPart); +}; + +namespace { +const std::vector ICU_LONG_SHORT = {"long", "short"}; +const std::vector ICU_NARROW_LONG_SHORT = {"narrow", "long", "short"}; +const std::vector ICU2_DIGIT_NUMERIC = {"2-digit", "numeric"}; +const std::vector ICU_NARROW_LONG_SHORT2_DIGIT_NUMERIC = {"narrow", "long", "short", "2-digit", "numeric"}; +const std::vector ICU_WEEKDAY_PE = { + {"EEEEE", "narrow"}, {"EEEE", "long"}, {"EEE", "short"}, + {"ccccc", "narrow"}, {"cccc", "long"}, {"ccc", "short"} +}; +const std::vector ICU_ERA_PE = {{"GGGGG", "narrow"}, {"GGGG", "long"}, {"GGG", "short"}}; +const std::vector ICU_YEAR_PE = {{"yy", "2-digit"}, {"y", "numeric"}}; +const std::vector ICU_MONTH_PE = { + {"MMMMM", "narrow"}, {"MMMM", "long"}, {"MMM", "short"}, {"MM", "2-digit"}, {"M", "numeric"}, + {"LLLLL", "narrow"}, {"LLLL", "long"}, {"LLL", "short"}, {"LL", "2-digit"}, {"L", "numeric"} +}; +const std::vector ICU_DAY_PE = {{"dd", "2-digit"}, {"d", "numeric"}}; +const std::vector ICU_DAY_PERIOD_PE = { + {"BBBBB", "narrow"}, {"bbbbb", "narrow"}, {"BBBB", "long"}, + {"bbbb", "long"}, {"B", "short"}, {"b", "short"} +}; +const std::vector ICU_HOUR_PE = { + {"HH", "2-digit"}, {"H", "numeric"}, {"hh", "2-digit"}, {"h", "numeric"}, + {"kk", "2-digit"}, {"k", "numeric"}, {"KK", "2-digit"}, {"K", "numeric"} +}; +const std::vector ICU_MINUTE_PE = {{"mm", "2-digit"}, {"m", "numeric"}}; +const std::vector ICU_SECOND_PE = {{"ss", "2-digit"}, {"s", "numeric"}}; +const std::vector ICU_YIME_ZONE_NAME_PE = {{"zzzz", "long"}, {"z", "short"}}; + +const std::map HOUR_CYCLE_MAP = { + {'K', HourCycleOption::H11}, + {'h', HourCycleOption::H12}, + {'H', HourCycleOption::H23}, + {'k', HourCycleOption::H24} +}; +const std::map TO_HOUR_CYCLE_MAP = { + {"h11", HourCycleOption::H11}, + {"h12", HourCycleOption::H12}, + {"h23", HourCycleOption::H23}, + {"h24", HourCycleOption::H24} +}; + +// The value of the [[RelevantExtensionKeys]] internal slot is « "ca", "nu", "hc" ». +const std::set RELEVANT_EXTENSION_KEYS = {"nu", "ca", "hc"}; +} + +icu::Locale *JSDateTimeFormat::GetIcuLocale() const +{ + ASSERT(GetLocaleIcu().IsJSNativePointer()); + auto result = JSNativePointer::Cast(GetLocaleIcu().GetTaggedObject())->GetExternalPointer(); + return reinterpret_cast(result); +} + +void JSDateTimeFormat::SetIcuLocale(JSThread *thread, const icu::Locale &icuLocale, const DeleteEntryPoint &callback) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + icu::Locale *icuPointer = ecmaVm->GetRegionFactory()->New(icuLocale); + ASSERT(icuPointer != nullptr); + JSTaggedValue data = GetLocaleIcu(); + if (data.IsHeapObject() && data.IsJSNativePointer()) { + JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject()); + native->ResetExternalPointer(icuPointer); + return; + } + JSHandle pointer = factory->NewJSNativePointer(icuPointer); + pointer->SetDeleter(callback); + pointer->SetData(ecmaVm); + SetLocaleIcu(thread, pointer.GetTaggedValue()); + ecmaVm->PushToArrayDataList(*pointer); +} + +void JSDateTimeFormat::FreeIcuLocale(void *pointer, void *data) +{ + if (pointer == nullptr) { + return; + } + auto icuLocale = reinterpret_cast(pointer); + icuLocale->~Locale(); + if (data != nullptr) { + reinterpret_cast(data)->GetRegionFactory()->FreeBuffer(pointer); + } +} + +icu::SimpleDateFormat *JSDateTimeFormat::GetIcuSimpleDateFormat() const +{ + ASSERT(GetSimpleDateTimeFormatIcu().IsJSNativePointer()); + auto result = JSNativePointer::Cast(GetSimpleDateTimeFormatIcu().GetTaggedObject())->GetExternalPointer(); + return reinterpret_cast(result); +} + +void JSDateTimeFormat::SetIcuSimpleDateFormat(JSThread *thread, const icu::SimpleDateFormat &icuSimpleDateTimeFormat, + const DeleteEntryPoint &callback) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + icu::SimpleDateFormat *icuPointer = ecmaVm->GetRegionFactory()->New(icuSimpleDateTimeFormat); + ASSERT(icuPointer != nullptr); + JSTaggedValue data = GetSimpleDateTimeFormatIcu(); + if (data.IsHeapObject() && data.IsJSNativePointer()) { + JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject()); + native->ResetExternalPointer(icuPointer); + return; + } + JSHandle pointer = factory->NewJSNativePointer(icuPointer); + pointer->SetDeleter(callback); + pointer->SetData(ecmaVm); + SetSimpleDateTimeFormatIcu(thread, pointer.GetTaggedValue()); + ecmaVm->PushToArrayDataList(*pointer); +} + +void JSDateTimeFormat::FreeSimpleDateFormat(void *pointer, void *data) +{ + if (pointer == nullptr) { + return; + } + auto icuSimpleDateFormat = reinterpret_cast(pointer); + icuSimpleDateFormat->~SimpleDateFormat(); + if (data != nullptr) { + reinterpret_cast(data)->GetRegionFactory()->FreeBuffer(pointer); + } +} + +JSHandle JSDateTimeFormat::ToValueString(JSThread *thread, const Value value) +{ + auto globalConst = thread->GlobalConstants(); + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + switch (value) { + case Value::SHARED: + result.Update(globalConst->GetHandledSharedString().GetTaggedValue()); + break; + case Value::START_RANGE: + result.Update(globalConst->GetHandledStartRangeString().GetTaggedValue()); + break; + case Value::END_RANGE: + result.Update(globalConst->GetHandledEndRangeString().GetTaggedValue()); + break; + default: + UNREACHABLE(); + } + return result; +} + +// 13.1.1 InitializeDateTimeFormat (dateTimeFormat, locales, options) +// NOLINTNEXTLINE(readability-function-size) +JSHandle JSDateTimeFormat::InitializeDateTimeFormat(JSThread *thread, + const JSHandle &dateTimeFormat, + const JSHandle &locales, + const JSHandle &options) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + const GlobalEnvConstants *globalConst = thread->GlobalConstants(); + + // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + + // 2. Let options be ? ToDateTimeOptions(options, "any", "date"). + JSHandle dateTimeOptions = ToDateTimeOptions(thread, options, RequiredOption::ANY, DefaultsOption::DATE); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + + // 4. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + auto matcher = JSLocale::GetOptionOfString( + thread, dateTimeOptions, globalConst->GetHandledLocaleMatcherString(), + {LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT}, {"lookup", "best fit"}, + LocaleMatcherOption::BEST_FIT); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + + // 6. Let calendar be ? GetOption(options, "calendar", "string", undefined, undefined). + JSHandle calendar = + JSLocale::GetOption(thread, dateTimeOptions, globalConst->GetHandledCalendarString(), OptionType::STRING, + globalConst->GetHandledUndefined(), globalConst->GetHandledUndefined()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + dateTimeFormat->SetCalendar(thread, calendar); + + // 7. If calendar is not undefined, then + // a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception. + std::string calendarStr; + if (!calendar->IsUndefined()) { + JSHandle calendarEcmaStr = JSHandle::Cast(calendar); + calendarStr = JSLocale::ConvertToStdString(calendarEcmaStr); + if (!JSLocale::IsNormativeCalendar(calendarStr)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid calendar", dateTimeFormat); + } + } + + // 9. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined). + JSHandle numberingSystem = + JSLocale::GetOption(thread, dateTimeOptions, globalConst->GetHandledNumberingSystemString(), OptionType::STRING, + globalConst->GetHandledUndefined(), globalConst->GetHandledUndefined()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + dateTimeFormat->SetNumberingSystem(thread, numberingSystem); + + // 10. If numberingSystem is not undefined, then + // a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError + // exception. + std::string nsStr; + if (!numberingSystem->IsUndefined()) { + JSHandle nsEcmaStr = JSHandle::Cast(numberingSystem); + nsStr = JSLocale::ConvertToStdString(nsEcmaStr); + if (!JSLocale::IsWellNumberingSystem(nsStr)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid numberingSystem", dateTimeFormat); + } + } + + // 12. Let hour12 be ? GetOption(options, "hour12", "boolean", undefined, undefined). + JSHandle hour12 = + JSLocale::GetOption(thread, dateTimeOptions, globalConst->GetHandledHour12String(), OptionType::BOOLEAN, + globalConst->GetHandledUndefined(), globalConst->GetHandledUndefined()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + + // 13. Let hourCycle be ? GetOption(options, "hourCycle", "string", « "h11", "h12", "h23", "h24" », undefined). + auto hourCycle = JSLocale::GetOptionOfString( + thread, dateTimeOptions, globalConst->GetHandledHourCycleString(), + {HourCycleOption::H11, HourCycleOption::H12, HourCycleOption::H23, HourCycleOption::H24}, + {"h11", "h12", "h23", "h24"}, HourCycleOption::UNDEFINED); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + + // 14. If hour12 is not undefined, then + // a. Let hourCycle be null. + if (!hour12->IsUndefined()) { + hourCycle = HourCycleOption::UNDEFINED; + } + + // 16. Let localeData be %DateTimeFormat%.[[LocaleData]]. + JSHandle availableLocales = (requestedLocales->GetLength() == 0) ? factory->EmptyArray() : + GainAvailableLocales(thread); + + // 17. Let r be ResolveLocale(%DateTimeFormat%.[[AvailableLocales]], requestedLocales, opt, %DateTimeFormat% + // .[[RelevantExtensionKeys]], localeData). + ResolvedLocale resolvedLocale = + JSLocale::ResolveLocale(thread, availableLocales, requestedLocales, matcher, RELEVANT_EXTENSION_KEYS); + + // 18. Set icuLocale to r.[[locale]]. + icu::Locale icuLocale = resolvedLocale.localeData; + ASSERT_PRINT(!icuLocale.isBogus(), "icuLocale is bogus"); + UErrorCode status = U_ZERO_ERROR; + + // Set resolvedIcuLocaleCopy to a copy of icuLocale. + // Set icuLocale.[[ca]] to calendar. + // Set icuLocale.[[nu]] to numberingSystem. + icu::Locale resolvedIcuLocaleCopy(icuLocale); + if (!calendar->IsUndefined() && JSLocale::IsWellCalendar(icuLocale, calendarStr)) { + icuLocale.setUnicodeKeywordValue("ca", calendarStr, status); + } + if (!numberingSystem->IsUndefined() && JSLocale::IsWellNumberingSystem(nsStr)) { + icuLocale.setUnicodeKeywordValue("nu", nsStr, status); + } + + // 24. Let timeZone be ? Get(options, "timeZone"). + OperationResult operationResult = + JSObject::GetProperty(thread, dateTimeOptions, globalConst->GetHandledTimeZoneString()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + dateTimeFormat->SetTimeZone(thread, operationResult.GetValue()); + + // 25. If timeZone is not undefined, then + // a. Let timeZone be ? ToString(timeZone). + // b. If the result of IsValidTimeZoneName(timeZone) is false, then + // i. Throw a RangeError exception. + std::unique_ptr icuTimeZone; + if (!operationResult.GetValue()->IsUndefined()) { + JSHandle timezone = JSTaggedValue::ToString(thread, operationResult.GetValue()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + icuTimeZone = ConstructTimeZone(JSLocale::ConvertToStdString(timezone)); + if (icuTimeZone == nullptr) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid timeZone", dateTimeFormat); + } + } else { + // 26. Else, + // a. Let timeZone be DefaultTimeZone(). + icuTimeZone = std::unique_ptr(icu::TimeZone::createDefault()); + } + + // 36.a. Let hcDefault be dataLocaleData.[[hourCycle]]. + std::unique_ptr generator( + icu::DateTimePatternGenerator::createInstance(icuLocale, status)); + ASSERT_PRINT(U_SUCCESS(status), "constructGenerator failed"); + HourCycleOption hcDefault = OptionToHourCycle(generator->getDefaultHourCycle(status)); + // b. Let hc be dateTimeFormat.[[HourCycle]]. + HourCycleOption hc = HourCycleOption::UNDEFINED; + hc = (hourCycle == HourCycleOption::UNDEFINED) ? OptionToHourCycle(resolvedLocale.extensions.find("hc")->second) : + hourCycle; + // c. If hc is null, then + // i. Set hc to hcDefault. + if (hc == HourCycleOption::UNDEFINED) { + hc = hcDefault; + } + // d. If hour12 is not undefined, then + if (!hour12->IsUndefined()) { + // i. If hour12 is true, then + if (JSTaggedValue::SameValue(hour12.GetTaggedValue(), JSTaggedValue::True())) { + // 1. If hcDefault is "h11" or "h23", then + if (hcDefault == HourCycleOption::H11 || hcDefault == HourCycleOption::H23) { + // a. Set hc to "h11". + hc = HourCycleOption::H11; + } else { + // 2. Else, + // a. Set hc to "h12". + hc = HourCycleOption::H12; + } + } else { + // ii. Else, + // 2. If hcDefault is "h11" or "h23", then + if (hcDefault == HourCycleOption::H11 || hcDefault == HourCycleOption::H23) { + // a. Set hc to "h23". + hc = HourCycleOption::H23; + } else { + // 3. Else, + // a. Set hc to "h24". + hc = HourCycleOption::H24; + } + } + } + + // Set isHourDefined be false when dateTimeFormat.[[Hour]] is not undefined. + bool isHourDefined = false; + + // 29. For each row of Table 6, except the header row, in table order, do + // a. Let prop be the name given in the Property column of the row. + // b. Let value be ? GetOption(options, prop, "string", « the strings given in the Values column of the + // row », undefined). + // c. Set opt.[[]] to value. + std::string skeleton; + std::vector data = GetIcuPatternDesc(hc); + for (const IcuPatternDesc &item : data) { + // prop be [[TimeZoneName]] + if (item.property == "timeZoneName") { + int secondDigitsString = JSLocale::GetNumberOption(thread, dateTimeOptions, + globalConst->GetHandledFractionalSecondDigitsString(), + 1, 3, 0); + skeleton.append(secondDigitsString, 'S'); + } + JSHandle property(thread, factory->NewFromStdString(item.property).GetTaggedValue()); + std::string value; + bool isFind = JSLocale::GetOptionOfString(thread, dateTimeOptions, property, item.allowedValues, &value); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + if (isFind) { + skeleton += item.map.find(value)->second; + // [[Hour]] is defined. + isHourDefined = (item.property == "hour") ? true : isHourDefined; + } + } + + // 13.1.3 BasicFormatMatcher (options, formats) + [[maybe_unused]] auto formatMatcher = JSLocale::GetOptionOfString( + thread, dateTimeOptions, globalConst->GetHandledFormatMatcherString(), + {FormatMatcherOption::BASIC, FormatMatcherOption::BEST_FIT}, {"basic", "best fit"}, + FormatMatcherOption::BEST_FIT); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + + // Let dateStyle be ? GetOption(options, "string", «"full", "long", "medium", "short"», undefined). + // Set dateTimeFormat.[[dateStyle]] + auto dateStyle = JSLocale::GetOptionOfString( + thread, dateTimeOptions, globalConst->GetHandledDateStyleString(), + {DateTimeStyleOption::FULL, DateTimeStyleOption::LONG, DateTimeStyleOption::MEDIUM, DateTimeStyleOption::SHORT}, + {"full", "long", "medium", "short"}, DateTimeStyleOption::UNDEFINED); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + dateTimeFormat->SetDateStyle(thread, JSTaggedValue(static_cast(dateStyle))); + + // Let timeStyle be ? GetOption(options, "string", «"full", "long", "medium", "short"», undefined). + // Set dateTimeFormat.[[timeStyle]] + auto timeStyle = JSLocale::GetOptionOfString( + thread, dateTimeOptions, globalConst->GetHandledTimeStyleString(), + {DateTimeStyleOption::FULL, DateTimeStyleOption::LONG, DateTimeStyleOption::MEDIUM, DateTimeStyleOption::SHORT}, + {"full", "long", "medium", "short"}, DateTimeStyleOption::UNDEFINED); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSDateTimeFormat, thread); + dateTimeFormat->SetTimeStyle(thread, JSTaggedValue(static_cast(timeStyle))); + + HourCycleOption dtfHourCycle = HourCycleOption::UNDEFINED; + + // If dateTimeFormat.[[Hour]] is defined, then + if (isHourDefined) { + // e. Set dateTimeFormat.[[HourCycle]] to hc. + dtfHourCycle = hc; + } else { + // 37. Else, + // a. Set dateTimeFormat.[[HourCycle]] to undefined. + dtfHourCycle = HourCycleOption::UNDEFINED; + } + + // Set dateTimeFormat.[[hourCycle]]. + dateTimeFormat->SetHourCycle(thread, JSTaggedValue(static_cast(dtfHourCycle))); + + // Set dateTimeFormat.[[icuLocale]]. + dateTimeFormat->SetIcuLocale(thread, icuLocale, JSDateTimeFormat::FreeIcuLocale); + + // Creates a Calendar using the given timezone and given locale. + // Set dateTimeFormat.[[icuSimpleDateFormat]]. + icu::UnicodeString dtfSkeleton(skeleton.c_str()); + status = U_ZERO_ERROR; + icu::UnicodeString pattern = ChangeHourCyclePattern( + generator.get()->getBestPattern(dtfSkeleton, UDATPG_MATCH_HOUR_FIELD_LENGTH, status), dtfHourCycle); + ASSERT_PRINT((U_SUCCESS(status) != 0), "get best pattern failed"); + auto simpleDateFormatIcu(std::make_unique(pattern, icuLocale, status)); + if (U_FAILURE(status) != 0) { + simpleDateFormatIcu = std::unique_ptr(); + } + ASSERT_PRINT(simpleDateFormatIcu != nullptr, "invalid icuSimpleDateFormat"); + std::unique_ptr calendarPtr = BuildCalendar(icuLocale, *icuTimeZone); + ASSERT_PRINT(calendarPtr != nullptr, "invalid calendar"); + simpleDateFormatIcu->adoptCalendar(calendarPtr.release()); + dateTimeFormat->SetIcuSimpleDateFormat(thread, *simpleDateFormatIcu, JSDateTimeFormat::FreeSimpleDateFormat); + + // Set dateTimeFormat.[[iso8601]]. + bool iso8601 = strstr(icuLocale.getName(), "calendar=iso8601") != nullptr; + dateTimeFormat->SetIso8601(thread, JSTaggedValue(iso8601)); + + // Set dateTimeFormat.[[locale]]. + if (!hour12->IsUndefined() || hourCycle != HourCycleOption::UNDEFINED) { + if ((resolvedLocale.extensions.find("hc") != resolvedLocale.extensions.end()) + && (dtfHourCycle != OptionToHourCycle((resolvedLocale.extensions.find("hc")->second)))) { + resolvedIcuLocaleCopy.setUnicodeKeywordValue("hc", nullptr, status); + ASSERT_PRINT(U_SUCCESS(status), "resolvedIcuLocaleCopy set hc failed"); + } + } + JSHandle localeStr = JSLocale::ToLanguageTag(thread, resolvedIcuLocaleCopy); + dateTimeFormat->SetLocale(thread, localeStr.GetTaggedValue()); + + // Set dateTimeFormat.[[boundFormat]]. + dateTimeFormat->SetBoundFormat(thread, JSTaggedValue::Undefined()); + + // 39. Return dateTimeFormat. + return dateTimeFormat; +} + +// 13.1.2 ToDateTimeOptions (options, required, defaults) +JSHandle JSDateTimeFormat::ToDateTimeOptions(JSThread *thread, const JSHandle &options, + const RequiredOption &required, const DefaultsOption &defaults) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + // 1. If options is undefined, let options be null; otherwise let options be ? ToObject(options). + JSHandle optionsResult(thread, JSTaggedValue::Null()); + if (!options->IsUndefined()) { + optionsResult = JSTaggedValue::ToObject(thread, options); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread); + } + + // 2. Let options be ObjectCreate(options). + optionsResult = JSObject::ObjectCreate(thread, optionsResult); + + // 3. Let needDefaults be true. + bool needDefaults = true; + + // 4. If required is "date" or "any", then + // a. For each of the property names "weekday", "year", "month", "day", do + // i. Let prop be the property name. + // ii. Let value be ? Get(options, prop). + // iii. If value is not undefined, let needDefaults be false. + auto globalConst = thread->GlobalConstants(); + if (required == RequiredOption::DATE || required == RequiredOption::ANY) { + JSHandle array = factory->NewTaggedArray(CAPACITY_4); + array->Set(thread, 0, globalConst->GetHandledWeekdayString()); + array->Set(thread, 1, globalConst->GetHandledYearString()); + array->Set(thread, 2, globalConst->GetHandledMonthString()); // 2 means the third slot + array->Set(thread, 3, globalConst->GetHandledDayString()); // 3 means the fourth slot + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + array_size_t len = array->GetLength(); + for (array_size_t i = 0; i < len; i++) { + key.Update(array->Get(thread, i)); + OperationResult operationResult = JSObject::GetProperty(thread, optionsResult, key); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread); + if (!operationResult.GetValue()->IsUndefined()) { + needDefaults = false; + } + } + } + + // 5. If required is "time" or "any", then + // a. For each of the property names "dayPeriod", "hour", "minute", "second", "fractionalSecondDigits", do + // i. Let prop be the property name. + // ii. Let value be ? Get(options, prop). + // iii. If value is not undefined, let needDefaults be false. + if (required == RequiredOption::TIME || required == RequiredOption::ANY) { + JSHandle array = factory->NewTaggedArray(CAPACITY_5); + array->Set(thread, 0, globalConst->GetHandledDayPeriodString()); + array->Set(thread, 1, globalConst->GetHandledHourString()); + array->Set(thread, 2, globalConst->GetHandledMinuteString()); // 2 means the second slot + array->Set(thread, 3, globalConst->GetHandledSecondString()); // 3 means the third slot + array->Set(thread, 4, globalConst->GetHandledFractionalSecondDigitsString()); // 4 means the fourth slot + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + array_size_t len = array->GetLength(); + for (array_size_t i = 0; i < len; i++) { + key.Update(array->Get(thread, i)); + OperationResult operationResult = JSObject::GetProperty(thread, optionsResult, key); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread); + if (!operationResult.GetValue()->IsUndefined()) { + needDefaults = false; + } + } + } + + // Let dateStyle/timeStyle be ? Get(options, "dateStyle"/"timeStyle"). + OperationResult dateStyleResult = + JSObject::GetProperty(thread, optionsResult, globalConst->GetHandledDateStyleString()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread); + JSHandle dateStyle = dateStyleResult.GetValue(); + OperationResult timeStyleResult = + JSObject::GetProperty(thread, optionsResult, globalConst->GetHandledTimeStyleString()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread); + JSHandle timeStyle = timeStyleResult.GetValue(); + + // If dateStyle is not undefined or timeStyle is not undefined, let needDefaults be false. + if (!dateStyle->IsUndefined() || !timeStyle->IsUndefined()) { + needDefaults = false; + } + + // If required is "date"/"time" and timeStyle is not undefined, throw a TypeError exception. + if (required == RequiredOption::DATE && !timeStyle->IsUndefined()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "timeStyle is not undefined", optionsResult); + } + if (required == RequiredOption::TIME && !dateStyle->IsUndefined()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "dateStyle is not undefined", optionsResult); + } + + // 6. If needDefaults is true and defaults is either "date" or "all", then + // a. For each of the property names "year", "month", "day", do + // i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric"). + if (needDefaults && (defaults == DefaultsOption::DATE || defaults == DefaultsOption::ALL)) { + JSHandle array = factory->NewTaggedArray(CAPACITY_3); + array->Set(thread, 0, globalConst->GetHandledYearString()); + array->Set(thread, 1, globalConst->GetHandledMonthString()); + array->Set(thread, 2, globalConst->GetHandledDayString()); // 2 means the third slot + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + array_size_t len = array->GetLength(); + for (array_size_t i = 0; i < len; i++) { + key.Update(array->Get(thread, i)); + JSObject::CreateDataPropertyOrThrow(thread, optionsResult, key, globalConst->GetHandledNumericString()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread); + } + } + + // 7. If needDefaults is true and defaults is either "time" or "all", then + // a. For each of the property names "hour", "minute", "second", do + // i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric"). + if (needDefaults && (defaults == DefaultsOption::TIME || defaults == DefaultsOption::ALL)) { + JSHandle array = factory->NewTaggedArray(CAPACITY_3); + array->Set(thread, 0, globalConst->GetHandledHourString()); + array->Set(thread, 1, globalConst->GetHandledMinuteString()); + array->Set(thread, 2, globalConst->GetHandledSecondString()); // 2 means the third slot + JSMutableHandle key(thread, JSTaggedValue::Undefined()); + array_size_t len = array->GetLength(); + for (array_size_t i = 0; i < len; i++) { + key.Update(array->Get(thread, i)); + JSObject::CreateDataPropertyOrThrow(thread, optionsResult, key, globalConst->GetHandledNumericString()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread); + } + } + + // 8. Return options. + return optionsResult; +} + +// 13.1.7 FormatDateTime(dateTimeFormat, x) +JSHandle JSDateTimeFormat::FormatDateTime(JSThread *thread, + const JSHandle &dateTimeFormat, double x) +{ + icu::SimpleDateFormat *simpleDateFormat = dateTimeFormat->GetIcuSimpleDateFormat(); + // 1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x). + double xValue = JSDate::TimeClip(x); + if (std::isnan(xValue)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid time value", thread->GetEcmaVM()->GetFactory()->GetEmptyString()); + } + + // 2. Let result be the empty String. + icu::UnicodeString result; + + // 3. Set result to the string-concatenation of result and part.[[Value]]. + simpleDateFormat->format(xValue, result); + + // 4. Return result. + return JSLocale::IcuToString(thread, result); +} + +// 13.1.8 FormatDateTimeToParts (dateTimeFormat, x) +JSHandle JSDateTimeFormat::FormatDateTimeToParts(JSThread *thread, + const JSHandle &dateTimeFormat, double x) +{ + icu::SimpleDateFormat *simpleDateFormat = dateTimeFormat->GetIcuSimpleDateFormat(); + ASSERT(simpleDateFormat != nullptr); + UErrorCode status = U_ZERO_ERROR; + icu::FieldPositionIterator fieldPositionIter; + icu::UnicodeString formattedParts; + simpleDateFormat->format(x, formattedParts, &fieldPositionIter, status); + if (U_FAILURE(status) != 0) { + THROW_TYPE_ERROR_AND_RETURN(thread, "format failed", thread->GetEcmaVM()->GetFactory()->NewJSArray()); + } + + // 2. Let result be ArrayCreate(0). + JSHandle result(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); + if (formattedParts.isBogus()) { + return result; + } + + // 3. Let n be 0. + int32_t index = 0; + int32_t preEdgePos = 0; + std::vector parts; + icu::FieldPosition fieldPosition; + while (fieldPositionIter.next(fieldPosition)) { + int32_t fField = fieldPosition.getField(); + int32_t fBeginIndex = fieldPosition.getBeginIndex(); + int32_t fEndIndex = fieldPosition.getEndIndex(); + if (preEdgePos < fBeginIndex) { + parts.emplace_back(CommonDateFormatPart(fField, preEdgePos, fBeginIndex, index, true)); + ++index; + } + parts.emplace_back(CommonDateFormatPart(fField, fBeginIndex, fEndIndex, index, false)); + preEdgePos = fEndIndex; + ++index; + } + int32_t length = formattedParts.length(); + if (preEdgePos < length) { + parts.emplace_back(CommonDateFormatPart(-1, preEdgePos, length, index, true)); + } + JSMutableHandle substring(thread, JSTaggedValue::Undefined()); + + // 4. For each part in parts, do + for (auto part : parts) { + substring.Update(JSLocale::IcuToString(thread, formattedParts, part.fBeginIndex, + part.fEndIndex).GetTaggedValue()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSArray, thread); + // Let O be ObjectCreate(%ObjectPrototype%). + // Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]). + // Perform ! CreateDataPropertyOrThrow(O, "value", part.[[Value]]). + // Perform ! CreateDataProperty(result, ! ToString(n), O). + if (part.isPreExist) { + JSLocale::PutElement(thread, part.index, result, ConvertFieldIdToDateType(thread, -1), + JSHandle::Cast(substring)); + } else { + JSLocale::PutElement(thread, part.index, result, ConvertFieldIdToDateType(thread, part.fField), + JSHandle::Cast(substring)); + } + } + + // 5. Return result. + return result; +} + +// 13.1.10 UnwrapDateTimeFormat(dtf) +JSHandle JSDateTimeFormat::UnwrapDateTimeFormat(JSThread *thread, + const JSHandle &dateTimeFormat) +{ + // 1. Assert: Type(dtf) is Object. + ASSERT_PRINT(dateTimeFormat->IsJSObject(), "dateTimeFormat is not object"); + + // 2. If dateTimeFormat does not have an [[InitializedDateTimeFormat]] internal slot + // and ? InstanceofOperator(dateTimeFormat, %DateTimeFormat%) is true, then + // a. Let dateTimeFormat be ? Get(dateTimeFormat, %Intl%.[[FallbackSymbol]]). + JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); + bool isInstanceOf = JSFunction::InstanceOf(thread, dateTimeFormat, env->GetDateTimeFormatFunction()); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, dateTimeFormat); + if (!dateTimeFormat->IsJSDateTimeFormat() && isInstanceOf) { + JSHandle key(thread, JSHandle::Cast(env->GetIntlFunction())->GetFallbackSymbol()); + OperationResult operationResult = JSTaggedValue::GetProperty(thread, dateTimeFormat, key); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, dateTimeFormat); + return operationResult.GetValue(); + } + + // 3. Perform ? RequireInternalSlot(dateTimeFormat, [[InitializedDateTimeFormat]]). + if (!dateTimeFormat->IsJSDateTimeFormat()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "is not JSDateTimeFormat", + JSHandle(thread, JSTaggedValue::Exception())); + } + + // 4. Return dateTimeFormat. + return dateTimeFormat; +} + +JSHandle ToHourCycleEcmaString(JSThread *thread, int32_t hc) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (hc) { + case static_cast(HourCycleOption::H11): + result.Update(globalConst->GetHandledH11String().GetTaggedValue()); + break; + case static_cast(HourCycleOption::H12): + result.Update(globalConst->GetHandledH12String().GetTaggedValue()); + break; + case static_cast(HourCycleOption::H23): + result.Update(globalConst->GetHandledH23String().GetTaggedValue()); + break; + case static_cast(HourCycleOption::H24): + result.Update(globalConst->GetHandledH24String().GetTaggedValue()); + break; + default: + UNREACHABLE(); + } + return result; +} + +JSHandle ToDateTimeStyleEcmaString(JSThread *thread, int32_t style) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (style) { + case static_cast(DateTimeStyleOption::FULL): + result.Update(globalConst->GetHandledFullString().GetTaggedValue()); + break; + case static_cast(DateTimeStyleOption::LONG): + result.Update(globalConst->GetHandledLongString().GetTaggedValue()); + break; + case static_cast(DateTimeStyleOption::MEDIUM): + result.Update(globalConst->GetHandledMediumString().GetTaggedValue()); + break; + case static_cast(DateTimeStyleOption::SHORT): + result.Update(globalConst->GetHandledShortString().GetTaggedValue()); + break; + default: + UNREACHABLE(); + } + return result; +} + +// 13.4.5 Intl.DateTimeFormat.prototype.resolvedOptions () +void JSDateTimeFormat::ResolvedOptions(JSThread *thread, const JSHandle &dateTimeFormat, + const JSHandle &options) +{ // Table 8: Resolved Options of DateTimeFormat Instances + // Internal Slot Property + // [[Locale]] "locale" + // [[Calendar]] "calendar" + // [[NumberingSystem]] "numberingSystem" + // [[TimeZone]] "timeZone" + // [[HourCycle]] "hourCycle" + // "hour12" + // [[Weekday]] "weekday" + // [[Era]] "era" + // [[Year]] "year" + // [[Month]] "month" + // [[Day]] "day" + // [[Hour]] "hour" + // [[Minute]] "minute" + // [[Second]] "second" + // [[TimeZoneName]] "timeZoneName" + auto globalConst = thread->GlobalConstants(); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + + // 5. For each row of Table 8, except the header row, in table order, do + // Let p be the Property value of the current row. + // [[Locale]] + JSHandle locale(thread, dateTimeFormat->GetLocale()); + JSHandle property = globalConst->GetHandledLocaleString(); + JSObject::CreateDataPropertyOrThrow(thread, options, property, locale); + // [[Calendar]] + JSMutableHandle calendarValue(thread, dateTimeFormat->GetCalendar()); + icu::SimpleDateFormat *icuSimpleDateFormat = dateTimeFormat->GetIcuSimpleDateFormat(); + const icu::Calendar *calendar = icuSimpleDateFormat->getCalendar(); + std::string icuCalendar = calendar->getType(); + if (icuCalendar == "gregorian") { + if (dateTimeFormat->GetIso8601() == JSTaggedValue::True()) { + calendarValue.Update(globalConst->GetHandledIso8601String().GetTaggedValue()); + } else { + calendarValue.Update(globalConst->GetHandledGregoryString().GetTaggedValue()); + } + } else if (icuCalendar == "ethiopic-amete-alem") { + calendarValue.Update(globalConst->GetHandledEthioaaString().GetTaggedValue()); + } + property = globalConst->GetHandledCalendarString(); + JSObject::CreateDataPropertyOrThrow(thread, options, property, calendarValue); + // [[NumberingSystem]] + JSHandle numberingSystem(thread, dateTimeFormat->GetNumberingSystem()); + if (numberingSystem->IsUndefined()) { + numberingSystem = globalConst->GetHandledLatnString(); + } + property = globalConst->GetHandledNumberingSystemString(); + JSObject::CreateDataPropertyOrThrow(thread, options, property, numberingSystem); + // [[TimeZone]] + JSMutableHandle timezoneValue(thread, dateTimeFormat->GetTimeZone()); + const icu::TimeZone &icuTZ = calendar->getTimeZone(); + icu::UnicodeString timezone; + icuTZ.getID(timezone); + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString canonicalTimezone; + icu::TimeZone::getCanonicalID(timezone, canonicalTimezone, status); + if (U_SUCCESS(status) != 0) { + if ((canonicalTimezone == UNICODE_STRING_SIMPLE("Etc/UTC")) != 0 || + (canonicalTimezone == UNICODE_STRING_SIMPLE("Etc/GMT")) != 0) { + timezoneValue.Update(globalConst->GetUTCString()); + } else { + timezoneValue.Update(JSLocale::IcuToString(thread, canonicalTimezone).GetTaggedValue()); + } + } + property = globalConst->GetHandledTimeZoneString(); + JSObject::CreateDataPropertyOrThrow(thread, options, property, timezoneValue); + // [[HourCycle]] + // For web compatibility reasons, if the property "hourCycle" is set, the "hour12" property should be set to true + // when "hourCycle" is "h11" or "h12", or to false when "hourCycle" is "h23" or "h24". + // i. Let hc be dtf.[[HourCycle]]. + JSHandle hcValue; + HourCycleOption hc = static_cast(dateTimeFormat->GetHourCycle().GetInt()); + if (hc != HourCycleOption::UNDEFINED) { + property = globalConst->GetHandledHourCycleString(); + hcValue = ToHourCycleEcmaString(thread, dateTimeFormat->GetHourCycle().GetInt()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, hcValue); + if (hc == HourCycleOption::H11 || hc == HourCycleOption::H12) { + JSHandle trueValue(thread, JSTaggedValue::True()); + hcValue = trueValue; + } else if (hc == HourCycleOption::H23 || hc == HourCycleOption::H24) { + JSHandle falseValue(thread, JSTaggedValue::False()); + hcValue = falseValue; + } + property = globalConst->GetHandledHour12String(); + JSObject::CreateDataPropertyOrThrow(thread, options, property, hcValue); + } + // [[DateStyle]], [[TimeStyle]]. + icu::UnicodeString patternUnicode; + icuSimpleDateFormat->toPattern(patternUnicode); + std::string pattern; + patternUnicode.toUTF8String(pattern); + if (dateTimeFormat->GetDateStyle() == JSTaggedValue(static_cast(DateTimeStyleOption::UNDEFINED)) && + dateTimeFormat->GetTimeStyle() == JSTaggedValue(static_cast(DateTimeStyleOption::UNDEFINED))) { + for (const auto &item : BuildIcuPatternDescs()) { + // fractionalSecondsDigits need to be added before timeZoneName. + if (item.property == "timeZoneName") { + int tmpResult = count(pattern.begin(), pattern.end(), 'S'); + int fsd = (tmpResult >= STRING_LENGTH_3) ? STRING_LENGTH_3 : tmpResult; + if (fsd > 0) { + JSHandle fsdValue(thread, JSTaggedValue(fsd)); + property = globalConst->GetHandledFractionalSecondDigitsString(); + JSObject::CreateDataPropertyOrThrow(thread, options, property, fsdValue); + } + } + property = JSHandle::Cast(factory->NewFromStdString(item.property)); + for (const auto &pair : item.pairs) { + if (pattern.find(pair.first) != std::string::npos) { + hcValue = JSHandle::Cast(factory->NewFromStdString(pair.second)); + JSObject::CreateDataPropertyOrThrow(thread, options, property, hcValue); + break; + } + } + } + } + if (dateTimeFormat->GetDateStyle() != JSTaggedValue(static_cast(DateTimeStyleOption::UNDEFINED))) { + property = globalConst->GetHandledDateStyleString(); + hcValue = ToDateTimeStyleEcmaString(thread, dateTimeFormat->GetDateStyle().GetInt()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, hcValue); + } + if (dateTimeFormat->GetTimeStyle() != JSTaggedValue(static_cast(DateTimeStyleOption::UNDEFINED))) { + property = globalConst->GetHandledTimeStyleString(); + hcValue = ToDateTimeStyleEcmaString(thread, dateTimeFormat->GetTimeStyle().GetInt()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, hcValue); + } +} + +// Use dateInterval(x, y) construct datetimeformatrange +icu::FormattedDateInterval JSDateTimeFormat::ConstructDTFRange(JSThread *thread, const JSHandle &dtf, + double x, double y) +{ + std::unique_ptr dateIntervalFormat(ConstructDateIntervalFormat(dtf)); + if (dateIntervalFormat == nullptr) { + icu::FormattedDateInterval emptyValue; + THROW_TYPE_ERROR_AND_RETURN(thread, "create dateIntervalFormat failed", emptyValue); + } + UErrorCode status = U_ZERO_ERROR; + icu::DateInterval dateInterval(x, y); + icu::FormattedDateInterval formatted = dateIntervalFormat->formatToValue(dateInterval, status); + return formatted; +} + +JSHandle JSDateTimeFormat::NormDateTimeRange(JSThread *thread, const JSHandle &dtf, + double x, double y) +{ + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle result = factory->GetEmptyString(); + // 1. Let x be TimeClip(x). + x = JSDate::TimeClip(x); + // 2. If x is NaN, throw a RangeError exception. + if (std::isnan(x)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "x is NaN", result); + } + // 3. Let y be TimeClip(y). + y = JSDate::TimeClip(y); + // 4. If y is NaN, throw a RangeError exception. + if (std::isnan(y)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "y is NaN", result); + } + + icu::FormattedDateInterval formatted = ConstructDTFRange(thread, dtf, x, y); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread); + + // Formatted to string. + bool outputRange = false; + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString formatResult = formatted.toString(status); + if (U_FAILURE(status) != 0) { + THROW_TYPE_ERROR_AND_RETURN(thread, "format to string failed", + thread->GetEcmaVM()->GetFactory()->GetEmptyString()); + } + icu::ConstrainedFieldPosition cfpos; + while (formatted.nextPosition(cfpos, status) != 0) { + if (cfpos.getCategory() == UFIELD_CATEGORY_DATE_INTERVAL_SPAN) { + outputRange = true; + break; + } + } + result = JSLocale::IcuToString(thread, formatResult); + if (!outputRange) { + return FormatDateTime(thread, dtf, x); + } + return result; +} + +JSHandle JSDateTimeFormat::NormDateTimeRangeToParts(JSThread *thread, const JSHandle &dtf, + double x, double y) +{ + JSHandle result(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); + // 1. Let x be TimeClip(x). + x = JSDate::TimeClip(x); + // 2. If x is NaN, throw a RangeError exception. + if (std::isnan(x)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "x is invalid time value", result); + } + // 3. Let y be TimeClip(y). + y = JSDate::TimeClip(y); + // 4. If y is NaN, throw a RangeError exception. + if (std::isnan(y)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "y is invalid time value", result); + } + + icu::FormattedDateInterval formatted = ConstructDTFRange(thread, dtf, x, y); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSArray, thread); + return ConstructFDateIntervalToJSArray(thread, formatted); +} + +JSHandle JSDateTimeFormat::GainAvailableLocales(JSThread *thread) +{ + JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); + JSHandle dateTimeFormatLocales = env->GetDateTimeFormatLocales(); + const char *key = "calendar"; + const char *path = nullptr; + if (dateTimeFormatLocales->IsUndefined()) { + JSHandle availableLocales = JSLocale::GetAvailableLocales(thread, key, path); + env->SetDateTimeFormatLocales(thread, availableLocales); + return availableLocales; + } + return JSHandle::Cast(dateTimeFormatLocales); +} + +JSHandle JSDateTimeFormat::ConstructFDateIntervalToJSArray(JSThread *thread, + const icu::FormattedDateInterval &formatted) +{ + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString formattedValue = formatted.toTempString(status); + // Let result be ArrayCreate(0). + JSHandle array(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); + // Let index be 0. + int index = 0; + int32_t preEndPos = 0; + std::array begin {}; + std::array end {}; + begin[0] = begin[1] = end[0] = end[1] = 0; + std::vector parts; + + /** + * From ICU header file document @unumberformatter.h + * Sets a constraint on the field category. + * + * When this instance of ConstrainedFieldPosition is passed to FormattedValue#nextPosition, + * positions are skipped unless they have the given category. + * + * Any previously set constraints are cleared. + * + * For example, to loop over only the number-related fields: + * + * ConstrainedFieldPosition cfpo; + * cfpo.constrainCategory(UFIELDCATEGORY_NUMBER_FORMAT); + * while (fmtval.nextPosition(cfpo, status)) { + * // handle the number-related field position + * } + */ + JSMutableHandle substring(thread, JSTaggedValue::Undefined()); + icu::ConstrainedFieldPosition cfpos; + while (formatted.nextPosition(cfpos, status)) { + int32_t fCategory = cfpos.getCategory(); + int32_t fField = cfpos.getField(); + int32_t fStart = cfpos.getStart(); + int32_t fLimit = cfpos.getLimit(); + + // 2 means the number of elements in category + if (fCategory == UFIELD_CATEGORY_DATE_INTERVAL_SPAN && (fField == 0 || fField == 1)) { + begin[fField] = fStart; + end[fField] = fLimit; + } + if (fCategory == UFIELD_CATEGORY_DATE) { + if (preEndPos < fStart) { + parts.emplace_back(CommonDateFormatPart(fField, preEndPos, fStart, index, true)); + preEndPos = fStart; // NOLINT(clang-analyzer-deadcode.DeadStores) + index++; + } + parts.emplace_back(CommonDateFormatPart(fField, fStart, fLimit, index, false)); + preEndPos = fLimit; + ++index; + } + } + if (U_FAILURE(status) != 0) { + THROW_TYPE_ERROR_AND_RETURN(thread, "format date interval error", array); + } + int32_t length = formattedValue.length(); + if (length > preEndPos) { + parts.emplace_back(CommonDateFormatPart(-1, preEndPos, length, index, true)); + } + for (auto part : parts) { + substring.Update(JSLocale::IcuToString(thread, formattedValue, part.fBeginIndex, + part.fEndIndex).GetTaggedValue()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSArray, thread); + JSHandle element; + if (part.isPreExist) { + element = JSLocale::PutElement(thread, part.index, array, ConvertFieldIdToDateType(thread, -1), + JSHandle::Cast(substring)); + } else { + element = JSLocale::PutElement(thread, part.index, array, ConvertFieldIdToDateType(thread, part.fField), + JSHandle::Cast(substring)); + } + JSHandle value = JSHandle::Cast( + ToValueString(thread, TrackValue(part.fBeginIndex, part.fEndIndex, begin, end))); + JSObject::SetProperty(thread, element, thread->GlobalConstants()->GetHandledSourceString(), value, true); + } + return array; +} + +Value JSDateTimeFormat::TrackValue(int32_t beginning, int32_t ending, + std::array begin, std::array end) +{ + Value value = Value::SHARED; + if ((begin[0] <= beginning) && (beginning <= end[0]) && (begin[0] <= ending) && (ending <= end[0])) { + value = Value::START_RANGE; + } else if ((begin[1] <= beginning) && (beginning <= end[1]) && (begin[1] <= ending) && (ending <= end[1])) { + value = Value::END_RANGE; + } + return value; +} + +std::vector BuildIcuPatternDescs() +{ + std::vector items = { + IcuPatternDesc("weekday", ICU_WEEKDAY_PE, ICU_NARROW_LONG_SHORT), + IcuPatternDesc("era", ICU_ERA_PE, ICU_NARROW_LONG_SHORT), + IcuPatternDesc("year", ICU_YEAR_PE, ICU2_DIGIT_NUMERIC), + IcuPatternDesc("month", ICU_MONTH_PE, ICU_NARROW_LONG_SHORT2_DIGIT_NUMERIC), + IcuPatternDesc("day", ICU_DAY_PE, ICU2_DIGIT_NUMERIC), + IcuPatternDesc("dayPeriod", ICU_DAY_PERIOD_PE, ICU_NARROW_LONG_SHORT), + IcuPatternDesc("hour", ICU_HOUR_PE, ICU2_DIGIT_NUMERIC), + IcuPatternDesc("minute", ICU_MINUTE_PE, ICU2_DIGIT_NUMERIC), + IcuPatternDesc("second", ICU_SECOND_PE, ICU2_DIGIT_NUMERIC), + IcuPatternDesc("timeZoneName", ICU_YIME_ZONE_NAME_PE, ICU_LONG_SHORT) + }; + return items; +} + +std::vector InitializePattern(const IcuPatternDesc &hourData) +{ + std::vector result; + std::vector items = BuildIcuPatternDescs(); + std::vector::iterator item = items.begin(); + while (item != items.end()) { + if (item->property != "hour") { + result.emplace_back(IcuPatternDesc(item->property, item->pairs, item->allowedValues)); + } else { + result.emplace_back(hourData); + } + item++; + } + return result; +} + +std::vector JSDateTimeFormat::GetIcuPatternDesc(const HourCycleOption &hourCycle) +{ + if (hourCycle == HourCycleOption::H11) { + Pattern h11("KK", "K"); + return h11.Get(); + } else if (hourCycle == HourCycleOption::H12) { + Pattern h12("hh", "h"); + return h12.Get(); + } else if (hourCycle == HourCycleOption::H23) { + Pattern h23("HH", "H"); + return h23.Get(); + } else if (hourCycle == HourCycleOption::H24) { + Pattern h24("kk", "k"); + return h24.Get(); + } else if (hourCycle == HourCycleOption::UNDEFINED) { + Pattern pattern("jj", "j"); + return pattern.Get(); + } + UNREACHABLE(); +} + +icu::UnicodeString JSDateTimeFormat::ChangeHourCyclePattern(const icu::UnicodeString &pattern, HourCycleOption hc) +{ + if (hc == HourCycleOption::UNDEFINED || hc == HourCycleOption::EXCEPTION) { + return pattern; + } + icu::UnicodeString result; + char16_t key = u'\0'; + auto mapIter = std::find_if(HOUR_CYCLE_MAP.begin(), HOUR_CYCLE_MAP.end(), + [hc](const std::map::value_type item) { + return item.second == hc; + }); + if (mapIter != HOUR_CYCLE_MAP.end()) { + key = mapIter->first; + } + bool needChange = true; + char16_t last = u'\0'; + for (int32_t i = 0; i < pattern.length(); i++) { + char16_t ch = pattern.charAt(i); + if (ch == '\'') { + needChange = !needChange; + result.append(ch); + } else if (HOUR_CYCLE_MAP.find(ch) != HOUR_CYCLE_MAP.end()) { + result = (needChange && last == u'd') ? result.append(' ') : result; + result.append(needChange ? key : ch); + } else { + result.append(ch); + } + last = ch; + } + return result; +} + +std::unique_ptr JSDateTimeFormat::CreateICUSimpleDateFormat(const icu::Locale &icuLocale, + const icu::UnicodeString &skeleton, + icu::DateTimePatternGenerator *gn, + HourCycleOption hc) +{ + // See https://github.com/tc39/ecma402/issues/225 + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString pattern = ChangeHourCyclePattern( + gn->getBestPattern(skeleton, UDATPG_MATCH_HOUR_FIELD_LENGTH, status), hc); + ASSERT_PRINT((U_SUCCESS(status) != 0), "get best pattern failed"); + + status = U_ZERO_ERROR; + auto dateFormat(std::make_unique(pattern, icuLocale, status)); + if (U_FAILURE(status) != 0) { + return std::unique_ptr(); + } + ASSERT_PRINT(dateFormat != nullptr, "dateFormat failed"); + return dateFormat; +} + +std::unique_ptr JSDateTimeFormat::BuildCalendar(const icu::Locale &locale, const icu::TimeZone &timeZone) +{ + UErrorCode status = U_ZERO_ERROR; + std::unique_ptr calendar(icu::Calendar::createInstance(timeZone, locale, status)); + ASSERT_PRINT(U_SUCCESS(status), "buildCalendar failed"); + ASSERT_PRINT(calendar.get() != nullptr, "calender is nullptr"); + + /** + * Return the class ID for this class. + * + * This is useful only for comparing to a return value from getDynamicClassID(). For example: + * + * Base* polymorphic_pointer = createPolymorphicObject(); + * if (polymorphic_pointer->getDynamicClassID() == + * Derived::getStaticClassID()) ... + */ + if (calendar->getDynamicClassID() == icu::GregorianCalendar::getStaticClassID()) { + auto gregorianCalendar = static_cast(calendar.get()); + // ECMAScript start time, value = -(2**53) + const double beginTime = -9007199254740992; + gregorianCalendar->setGregorianChange(beginTime, status); + ASSERT(U_SUCCESS(status)); + } + return calendar; +} + +std::unique_ptr JSDateTimeFormat::ConstructTimeZone(const std::string &timezone) +{ + if (timezone.empty()) { + return std::unique_ptr(); + } + std::string canonicalized = ConstructFormattedTimeZoneID(timezone); + + std::unique_ptr tz(icu::TimeZone::createTimeZone(canonicalized.c_str())); + if (!JSLocale::IsValidTimeZoneName(*tz)) { + return std::unique_ptr(); + } + return tz; +} + +std::map JSDateTimeFormat::GetSpecialTimeZoneMap() +{ + std::vector specicalTimeZones = { + "America/Argentina/ComodRivadavia" + "America/Knox_IN" + "Antarctica/McMurdo" + "Australia/ACT" + "Australia/LHI" + "Australia/NSW" + "Antarctica/DumontDUrville" + "Brazil/DeNoronha" + "CET" + "CST6CDT" + "Chile/EasterIsland" + "EET" + "EST" + "EST5EDT" + "GB" + "GB-Eire" + "HST" + "MET" + "MST" + "MST7MDT" + "Mexico/BajaNorte" + "Mexico/BajaSur" + "NZ" + "NZ-CHAT" + "PRC" + "PST8PDT" + "ROC" + "ROK" + "UCT" + "W-SU" + "WET"}; + std::map map; + for (const auto &item : specicalTimeZones) { + std::string upper(item); + transform(upper.begin(), upper.end(), upper.begin(), toupper); + map.insert({upper, item}); + } + return map; +} + +std::string JSDateTimeFormat::ConstructFormattedTimeZoneID(const std::string &input) +{ + std::string result = input; + transform(result.begin(), result.end(), result.begin(), toupper); + static const std::vector tzStyleEntry = { + "GMT", "ETC/UTC", "ETC/UCT", "GMT0", "ETC/GMT", "GMT+0", "GMT-0" + }; + if (result.find("SYSTEMV/") == 0) { + result.replace(0, STRING_LENGTH_8, "SystemV/"); + } else if (result.find("US/") == 0) { + result = (result.length() == STRING_LENGTH_3) ? result : "US/" + ToTitleCaseTimezonePosition(input.substr(3)); + } else if (result.find("ETC/GMT") == 0 && result.length() > STRING_LENGTH_7) { + result = ConstructGMTTimeZoneID(input); + } else if (count(tzStyleEntry.begin(), tzStyleEntry.end(), result)) { + result = "UTC"; + } + return result; +} + +std::string JSDateTimeFormat::ToTitleCaseFunction(const std::string &input) +{ + std::string result(input); + transform(result.begin(), result.end(), result.begin(), tolower); + result[0] = toupper(result[0]); + return result; +} + +bool JSDateTimeFormat::IsValidTimeZoneInput(const std::string &input) +{ + std::regex r("[a-zA-Z_-/]*"); + bool isValid = regex_match(input, r); + return isValid; +} + +std::string JSDateTimeFormat::ToTitleCaseTimezonePosition(const std::string &input) +{ + if (!IsValidTimeZoneInput(input)) { + return std::string(); + } + std::vector titleEntry; + std::vector charEntry; + int32_t leftPosition = 0; + int32_t titleLength = 0; + for (size_t i = 0; i < input.length(); i++) { + if (input[i] == '_' || input[i] == '-' || input[i] == '/') { + std::string s(1, input[i]); + charEntry.emplace_back(s); + titleLength = i - leftPosition; + titleEntry.emplace_back(input.substr(leftPosition, titleLength)); + leftPosition = i + 1; + } else { + continue; + } + } + std::string result; + for (size_t i = 0; i < titleEntry.size()-1; i++) { + std::string titleValue = ToTitleCaseFunction(titleEntry[i]); + if (titleValue == "Of" || titleValue == "Es" || titleValue == "Au") { + titleValue[0] = tolower(titleValue[0]); + } + result = result + titleValue + charEntry[i]; + } + result = result + ToTitleCaseFunction(titleEntry[titleEntry.size()-1]); + return result; +} + +std::string JSDateTimeFormat::ConstructGMTTimeZoneID(const std::string &input) +{ + if (input.length() < STRING_LENGTH_8 || input.length() > STRING_LENGTH_10) { + return ""; + } + std::string ret = "Etc/GMT"; + if (regex_match(input.substr(7), std::regex("[+-][1][0-4]")) || (regex_match(input.substr(7), + std::regex("[+-][0-9]")) || input.substr(7) == "0")) { + return ret + input.substr(7); + } + return ""; +} + +std::string JSDateTimeFormat::ToHourCycleString(int32_t hc) +{ + auto mapIter = std::find_if(TO_HOUR_CYCLE_MAP.begin(), TO_HOUR_CYCLE_MAP.end(), + [hc](const std::map::value_type item) { + return static_cast(item.second) == hc; + }); + if (mapIter != TO_HOUR_CYCLE_MAP.end()) { + return mapIter->first; + } + return ""; +} + +HourCycleOption JSDateTimeFormat::OptionToHourCycle(const std::string &hc) +{ + auto iter = TO_HOUR_CYCLE_MAP.find(hc); + if (iter != TO_HOUR_CYCLE_MAP.end()) { + return iter->second; + } + return HourCycleOption::UNDEFINED; +} + +HourCycleOption JSDateTimeFormat::OptionToHourCycle(UDateFormatHourCycle hc) +{ + HourCycleOption hcOption = HourCycleOption::UNDEFINED; + switch (hc) { + case UDAT_HOUR_CYCLE_11: + hcOption = HourCycleOption::H11; + break; + case UDAT_HOUR_CYCLE_12: + hcOption = HourCycleOption::H12; + break; + case UDAT_HOUR_CYCLE_23: + hcOption = HourCycleOption::H23; + break; + case UDAT_HOUR_CYCLE_24: + hcOption = HourCycleOption::H24; + break; + default: + UNREACHABLE(); + } + return hcOption; +} + +JSHandle JSDateTimeFormat::ConvertFieldIdToDateType(JSThread *thread, int32_t fieldId) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + if (fieldId == -1) { + result.Update(globalConst->GetHandledLiteralString().GetTaggedValue()); + } else if (fieldId == UDAT_YEAR_FIELD || fieldId == UDAT_EXTENDED_YEAR_FIELD) { + result.Update(globalConst->GetHandledYearString().GetTaggedValue()); + } else if (fieldId == UDAT_YEAR_NAME_FIELD) { + result.Update(globalConst->GetHandledYearNameString().GetTaggedValue()); + } else if (fieldId == UDAT_MONTH_FIELD || fieldId == UDAT_STANDALONE_MONTH_FIELD) { + result.Update(globalConst->GetHandledMonthString().GetTaggedValue()); + } else if (fieldId == UDAT_DATE_FIELD) { + result.Update(globalConst->GetHandledDayString().GetTaggedValue()); + } else if (fieldId == UDAT_HOUR_OF_DAY1_FIELD || + fieldId == UDAT_HOUR_OF_DAY0_FIELD || fieldId == UDAT_HOUR1_FIELD || fieldId == UDAT_HOUR0_FIELD) { + result.Update(globalConst->GetHandledHourString().GetTaggedValue()); + } else if (fieldId == UDAT_MINUTE_FIELD) { + result.Update(globalConst->GetHandledMinuteString().GetTaggedValue()); + } else if (fieldId == UDAT_SECOND_FIELD) { + result.Update(globalConst->GetHandledSecondString().GetTaggedValue()); + } else if (fieldId == UDAT_DAY_OF_WEEK_FIELD || fieldId == UDAT_DOW_LOCAL_FIELD || + fieldId == UDAT_STANDALONE_DAY_FIELD) { + result.Update(globalConst->GetHandledWeekdayString().GetTaggedValue()); + } else if (fieldId == UDAT_AM_PM_FIELD || fieldId == UDAT_AM_PM_MIDNIGHT_NOON_FIELD || + fieldId == UDAT_FLEXIBLE_DAY_PERIOD_FIELD) { + result.Update(globalConst->GetHandledDayPeriodString().GetTaggedValue()); + } else if (fieldId == UDAT_TIMEZONE_FIELD || fieldId == UDAT_TIMEZONE_RFC_FIELD || + fieldId == UDAT_TIMEZONE_GENERIC_FIELD || fieldId == UDAT_TIMEZONE_SPECIAL_FIELD || + fieldId == UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD || fieldId == UDAT_TIMEZONE_ISO_FIELD || + fieldId == UDAT_TIMEZONE_ISO_LOCAL_FIELD) { + result.Update(globalConst->GetHandledTimeZoneNameString().GetTaggedValue()); + } else if (fieldId == UDAT_ERA_FIELD) { + result.Update(globalConst->GetHandledEraString().GetTaggedValue()); + } else if (fieldId == UDAT_FRACTIONAL_SECOND_FIELD) { + result.Update(globalConst->GetHandledFractionalSecondString().GetTaggedValue()); + } else if (fieldId == UDAT_RELATED_YEAR_FIELD) { + result.Update(globalConst->GetHandledRelatedYearString().GetTaggedValue()); + } else if (fieldId == UDAT_QUARTER_FIELD || fieldId == UDAT_STANDALONE_QUARTER_FIELD) { + UNREACHABLE(); + } + return result; +} + +std::unique_ptr JSDateTimeFormat::ConstructDateIntervalFormat( + const JSHandle &dtf) +{ + icu::SimpleDateFormat *icuSimpleDateFormat = dtf->GetIcuSimpleDateFormat(); + icu::Locale locale = *(dtf->GetIcuLocale()); + std::string hcString = ToHourCycleString(dtf->GetHourCycle().GetInt()); + UErrorCode status = U_ZERO_ERROR; + // Sets the Unicode value for a Unicode keyword. + if (!hcString.empty()) { + locale.setUnicodeKeywordValue("hc", hcString, status); + } + icu::UnicodeString pattern; + // Return a pattern string describing this date format. + pattern = icuSimpleDateFormat->toPattern(pattern); + // Utility to return a unique skeleton from a given pattern. + icu::UnicodeString skeleton = icu::DateTimePatternGenerator::staticGetSkeleton(pattern, status); + // Construct a DateIntervalFormat from skeleton and a given locale. + std::unique_ptr dateIntervalFormat( + icu::DateIntervalFormat::createInstance(skeleton, locale, status)); + if (U_FAILURE(status)) { + return nullptr; + } + dateIntervalFormat->setTimeZone(icuSimpleDateFormat->getTimeZone()); + return dateIntervalFormat; +} +} // namespace panda::ecmascript diff --git a/ecmascript/js_date_time_format.h b/ecmascript/js_date_time_format.h new file mode 100644 index 0000000000000000000000000000000000000000..eaedd7f34c8734bfaedf19a239695627f4e725b1 --- /dev/null +++ b/ecmascript/js_date_time_format.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_JS_DATE_TIME_FORMAT_H +#define ECMASCRIPT_JS_DATE_TIME_FORMAT_H + +#include "js_locale.h" + +namespace panda::ecmascript { +enum class CalendarOption : uint8_t { UNDEFINED = 0x01 }; +enum class DateTimeStyleOption : uint8_t { FULL = 0x01, LONG, MEDIUM, SHORT, UNDEFINED, EXCEPTION }; +enum class DefaultsOption : uint8_t { DATE = 0x01, TIME, ALL }; +enum class HourCycleOption : uint8_t { H11 = 0x01, H12, H23, H24, UNDEFINED, EXCEPTION }; +enum class RequiredOption : uint8_t { DATE = 0x01, TIME, ANY }; +enum class Value : uint8_t { SHARED, START_RANGE, END_RANGE }; + +constexpr int CAPACITY_3 = 3; +constexpr int CAPACITY_4 = 4; +constexpr int CAPACITY_5 = 5; +constexpr int CAPACITY_8 = 8; +constexpr int STRING_LENGTH_2 = 2; +constexpr int STRING_LENGTH_3 = 3; +constexpr int STRING_LENGTH_7 = 7; +constexpr int STRING_LENGTH_8 = 8; +constexpr int STRING_LENGTH_9 = 9; +constexpr int STRING_LENGTH_10 = 10; + +class IcuPatternDesc; + +std::vector BuildIcuPatternDescs(); +std::vector InitializePattern(const IcuPatternDesc &hourData); + +using IcuPatternDescVect = std::vector; +using IcuPatternEntry = std::pair; + +class IcuPatternDesc { +public: + IcuPatternDesc(std::string property, const std::vector &pairs, + std::vector allowedValues) : property(std::move(property)), pairs(std::move(pairs)), + allowedValues(std::move(allowedValues)) + { + for (const auto &pair : pairs) { + map.insert(std::make_pair(pair.second, pair.first)); + } + } + + virtual ~IcuPatternDesc() = default; + + std::string property; // NOLINT(misc-non-private-member-variables-in-classes) + std::vector pairs; // NOLINT(misc-non-private-member-variables-in-classes) + std::map map; // NOLINT(misc-non-private-member-variables-in-classes) + std::vector allowedValues; // NOLINT(misc-non-private-member-variables-in-classes) + + DEFAULT_COPY_SEMANTIC(IcuPatternDesc); + // NOLINT(performance-noexcept-move-constructor, hicpp-noexcept-move) + DEFAULT_NOEXCEPT_MOVE_SEMANTIC(IcuPatternDesc); +}; + +class Pattern { +public: + Pattern(const std::string &data1, const std::string &data2) : data(InitializePattern( + IcuPatternDesc("hour", {{data1, "2-digit"}, {data2, "numeric"}}, {"2-digit", "numeric"}))) {} + virtual ~Pattern() = default; + std::vector Get() const + { + return data; + } + +private: + std::vector data{}; + NO_COPY_SEMANTIC(Pattern); + NO_MOVE_SEMANTIC(Pattern); +}; + +class JSDateTimeFormat : public JSObject { +public: + static JSDateTimeFormat *Cast(ObjectHeader *object) + { + ASSERT(JSTaggedValue(object).IsJSDateTimeFormat()); + return reinterpret_cast(object); + } + + static constexpr size_t LOCALE_OFFSET = JSObject::SIZE; + + ACCESSORS(Locale, LOCALE_OFFSET, CALENDAR_OFFSET) + ACCESSORS(Calendar, CALENDAR_OFFSET, NUMBER_STRING_SYSTEM_OFFSET) + ACCESSORS(NumberingSystem, NUMBER_STRING_SYSTEM_OFFSET, TIME_ZONE_OFFSET) + ACCESSORS(TimeZone, TIME_ZONE_OFFSET, HOUR_CYCLE_OFFSET) + ACCESSORS(HourCycle, HOUR_CYCLE_OFFSET, LOCALE_ICU_OFFSET) + ACCESSORS(LocaleIcu, LOCALE_ICU_OFFSET, SIMPLE_DATE_TIME_FORMAT_ICU_OFFSET) + ACCESSORS(SimpleDateTimeFormatIcu, SIMPLE_DATE_TIME_FORMAT_ICU_OFFSET, ISO8601_OFFSET) + ACCESSORS(Iso8601, ISO8601_OFFSET, DATE_STYLE_OFFSET) + ACCESSORS(DateStyle, DATE_STYLE_OFFSET, TIME_STYLE_OFFSET) + ACCESSORS(TimeStyle, TIME_STYLE_OFFSET, BOUND_FORMAT_OFFSET) + ACCESSORS(BoundFormat, BOUND_FORMAT_OFFSET, SIZE) + + DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE) + + icu::Locale *GetIcuLocale() const; + void SetIcuLocale(JSThread *thread, const icu::Locale &icuLocale, const DeleteEntryPoint &callback); + static void FreeIcuLocale(void *pointer, void *data); + + icu::SimpleDateFormat *GetIcuSimpleDateFormat() const; + void SetIcuSimpleDateFormat(JSThread *thread, const icu::SimpleDateFormat &icuSimpleDateTimeFormat, + const DeleteEntryPoint &callback); + static void FreeSimpleDateFormat(void *pointer, void *data); + + // 13.1.1 InitializeDateTimeFormat (dateTimeFormat, locales, options) + static JSHandle InitializeDateTimeFormat(JSThread *thread, + const JSHandle &dateTimeFormat, + const JSHandle &locales, + const JSHandle &options); + + // 13.1.2 ToDateTimeOptions (options, required, defaults) + static JSHandle ToDateTimeOptions(JSThread *thread, const JSHandle &options, + const RequiredOption &required, const DefaultsOption &defaults); + + // 13.1.7 FormatDateTime(dateTimeFormat, x) + static JSHandle FormatDateTime(JSThread *thread, const JSHandle &dateTimeFormat, + double x); + + // 13.1.8 FormatDateTimeToParts (dateTimeFormat, x) + static JSHandle FormatDateTimeToParts(JSThread *thread, const JSHandle &dateTimeFormat, + double x); + + // 13.1.10 UnwrapDateTimeFormat(dtf) + static JSHandle UnwrapDateTimeFormat(JSThread *thread, + const JSHandle &dateTimeFormat); + + static JSHandle GainAvailableLocales(JSThread *thread); + + static void ResolvedOptions(JSThread *thread, const JSHandle &dateTimeFormat, + const JSHandle &options); + + static JSHandle NormDateTimeRange(JSThread *thread, const JSHandle &dtf, double x, + double y); + + static JSHandle NormDateTimeRangeToParts(JSThread *thread, const JSHandle &dtf, + double x, double y); + +private: + static HourCycleOption OptionToHourCycle(const std::string &hc); + + static Value TrackValue(int32_t beginning, int32_t ending, std::array begin, + std::array end); + + static HourCycleOption OptionToHourCycle(UDateFormatHourCycle hc); + + static std::string ToHourCycleString(int32_t hc); + + static std::unique_ptr ConstructTimeZone(const std::string &timezone); + + static std::string ConstructFormattedTimeZoneID(const std::string &input); + + static std::string ToTitleCaseTimezonePosition(const std::string &input); + + static std::unique_ptr ConstructDateIntervalFormat(const JSHandle &dtf); + + static std::string ConstructGMTTimeZoneID(const std::string &input); + + static std::unique_ptr BuildCalendar(const icu::Locale &locale, const icu::TimeZone &timeZone); + + static std::map GetSpecialTimeZoneMap(); + + static JSHandle ConstructFDateIntervalToJSArray(JSThread *thread, + const icu::FormattedDateInterval &formatted); + + static std::vector GetIcuPatternDesc(const HourCycleOption &hourCycle); + + static std::unique_ptr CreateICUSimpleDateFormat(const icu::Locale &icuLocale, + const icu::UnicodeString &skeleton, + icu::DateTimePatternGenerator *generator, + HourCycleOption hc); + + static JSHandle ConvertFieldIdToDateType(JSThread *thread, int32_t fieldId); + + static icu::UnicodeString ChangeHourCyclePattern(const icu::UnicodeString &pattern, HourCycleOption hc); + + static std::string ToTitleCaseFunction(const std::string &input); + + static bool IsValidTimeZoneInput(const std::string &input); + + static JSHandle ToValueString(JSThread *thread, Value value); + + static icu::FormattedDateInterval ConstructDTFRange(JSThread *thread, const JSHandle &dtf, + double x, double y); +}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_JS_DATE_TIME_FORMAT_H diff --git a/ecmascript/js_float64_array.h b/ecmascript/js_float64_array.h deleted file mode 100644 index 1e248e6bf0f68d8df02eda0cc79daa5ed0e4fa5f..0000000000000000000000000000000000000000 --- a/ecmascript/js_float64_array.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_FLOAT64_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_FLOAT64_ARRAY_H - -#include -#include "ecmascript/js_object.h" -#include "ecmascript/js_tagged_value-inl.h" -#include "ecmascript/js_tagged_value.h" - -namespace panda::ecmascript { -class JSFloat64Array : public JSObject { -public: - static JSFloat64Array *Cast(ObjectHeader *object) - { - ASSERT(JSTaggedValue(object).IsJSFloat64Array()); - return static_cast(object); - } - - static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE; - ACCESSORS(ViewedArrayBuffer, VIEWED_ARRAY_BUFFER_OFFSET, TYPED_ARRAY_NAME_OFFSET) - ACCESSORS(TypedArrayName, TYPED_ARRAY_NAME_OFFSET, BYTE_LENGTH_OFFSET) - ACCESSORS(ByteLength, BYTE_LENGTH_OFFSET, BYTE_OFFSET_OFFSET) - ACCESSORS(ByteOffset, BYTE_OFFSET_OFFSET, ARRAY_LENGTH_OFFSET) - ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, SIZE) - DECL_DUMP() - - DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE) -}; // namespace panda::ecmascript -} // namespace panda::ecmascript - -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_FLOAT64_ARRAY_H diff --git a/ecmascript/js_for_in_iterator.cpp b/ecmascript/js_for_in_iterator.cpp index 1876c2e6beae8c6fefcb0a239de41b833ceb8ce3..7568ade4b813daff0e471fac27addbc03d0ede5a 100644 --- a/ecmascript/js_for_in_iterator.cpp +++ b/ecmascript/js_for_in_iterator.cpp @@ -63,7 +63,7 @@ void JSForInIterator::FastGetAllEnumKeys(const JSThread *thread, const JSHandle< if (obj->IsJSPrimitiveRef() && JSPrimitiveRef::Cast(*obj)->IsString()) { elementIndex = JSPrimitiveRef::Cast(*obj)->GetStringLength(); for (uint32_t i = 0; i < elementIndex; i++) { - value.Update(factory->NewFromString(ToCString(i)).GetTaggedValue()); + value.Update(factory->NewFromCanBeCompressString(ToCString(i)).GetTaggedValue()); TaggedQueue::PushFixedQueue(thread, remaining, value); } } else { @@ -72,7 +72,7 @@ void JSForInIterator::FastGetAllEnumKeys(const JSThread *thread, const JSHandle< uint32_t elementsLen = elements->GetLength(); for (uint32_t i = 0; i < elementsLen; ++i) { if (!elements->Get(i).IsHole()) { - value.Update(factory->NewFromString(ToCString(i)).GetTaggedValue()); + value.Update(factory->NewFromCanBeCompressString(ToCString(i)).GetTaggedValue()); TaggedQueue::PushFixedQueue(thread, remaining, value); } } @@ -91,7 +91,7 @@ void JSForInIterator::FastGetAllEnumKeys(const JSThread *thread, const JSHandle< } std::sort(sortArr.begin(), sortArr.end(), NumberDictionary::CompKey); for (const auto &entry : sortArr) { - value.Update(factory->NewFromString(ToCString(entry.GetInt())).GetTaggedValue()); + value.Update(factory->NewFromCanBeCompressString(ToCString(entry.GetInt())).GetTaggedValue()); TaggedQueue::PushFixedQueue(thread, remaining, value); } } diff --git a/ecmascript/js_for_in_iterator.h b/ecmascript/js_for_in_iterator.h index d8b45fc67727ee2f32df4083e7819493dcc7d188..a33690a249383cf9287a4668696053df8b2e2130 100644 --- a/ecmascript/js_for_in_iterator.h +++ b/ecmascript/js_for_in_iterator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_FORIN_ITERATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_FORIN_ITERATOR_H +#ifndef ECMASCRIPT_JS_FORIN_ITERATOR_H +#define ECMASCRIPT_JS_FORIN_ITERATOR_H #include #include "ecmascript/js_tagged_value-inl.h" @@ -55,4 +55,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_FORIN_ITERATOR_H +#endif // ECMASCRIPT_JS_FORIN_ITERATOR_H diff --git a/ecmascript/js_function.cpp b/ecmascript/js_function.cpp index 0e650c46aa4c7fadbb7082bc18b4ec9596b5eca8..f631a61ef99367877d56968914ac141033143813 100644 --- a/ecmascript/js_function.cpp +++ b/ecmascript/js_function.cpp @@ -19,6 +19,7 @@ #include "ecmascript/ecma_macros.h" #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/interpreter-inl.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_promise.h" @@ -58,12 +59,8 @@ void JSFunction::InitializeJSFunction(JSThread *thread, const JSHandleSetPropertyInlinedProps(thread, PROTOTYPE_INLINE_PROPERTY_INDEX, accessor.GetTaggedValue()); accessor = globalConst->GetHandledFunctionNameAccessor(); func->SetPropertyInlinedProps(thread, NAME_INLINE_PROPERTY_INDEX, accessor.GetTaggedValue()); - accessor = globalConst->GetHandledFunctionLengthAccessor(); - func->SetPropertyInlinedProps(thread, LENGTH_INLINE_PROPERTY_INDEX, accessor.GetTaggedValue()); } else if (JSFunction::IsClassConstructor(kind)) { func->SetPropertyInlinedProps(thread, CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX, accessor.GetTaggedValue()); - accessor = globalConst->GetHandledFunctionLengthAccessor(); - func->SetPropertyInlinedProps(thread, LENGTH_INLINE_PROPERTY_INDEX, accessor.GetTaggedValue()); } else { PropertyDescriptor desc(thread, accessor, kind != FunctionKind::BUILTIN_CONSTRUCTOR, false, false); [[maybe_unused]] bool success = JSObject::DefineOwnProperty(thread, JSHandle(func), @@ -73,8 +70,6 @@ void JSFunction::InitializeJSFunction(JSThread *thread, const JSHandle accessor = globalConst->GetHandledFunctionNameAccessor(); func->SetPropertyInlinedProps(thread, NAME_INLINE_PROPERTY_INDEX, accessor.GetTaggedValue()); - accessor = globalConst->GetHandledFunctionLengthAccessor(); - func->SetPropertyInlinedProps(thread, LENGTH_INLINE_PROPERTY_INDEX, accessor.GetTaggedValue()); } } @@ -150,8 +145,7 @@ JSTaggedValue JSFunction::NameGetter(JSThread *thread, const JSHandle if (target->GetPandaFile() == nullptr) { return JSTaggedValue::Undefined(); } - CString funcName( - utf::Mutf8AsCString(target->GetStringDataAnnotation(JSMethod::AnnotationField::FUNCTION_NAME).data)); + CString funcName = target->ParseFunctionName(); if (funcName.empty()) { return thread->GlobalConstants()->GetEmptyString(); } @@ -166,15 +160,6 @@ JSTaggedValue JSFunction::NameGetter(JSThread *thread, const JSHandle return factory->NewFromString(funcName).GetTaggedValue(); } -JSTaggedValue JSFunction::LengthGetter([[maybe_unused]] JSThread *thread, const JSHandle &self) -{ - JSMethod *target = JSHandle::Cast(self)->GetCallTarget(); - if (target->GetPandaFile() == nullptr) { - return JSTaggedValue::Undefined(); - } - return JSTaggedValue(target->GetNumericalAnnotation(Method::AnnotationField::FUNCTION_LENGTH)); -} - bool JSFunction::OrdinaryHasInstance(JSThread *thread, const JSHandle &constructor, const JSHandle &obj) { @@ -278,7 +263,7 @@ bool JSFunction::MakeClassConstructor(JSThread *thread, const JSHandle &func, - const JSHandle &thisArg, const JSHandle &argv) + const JSHandle &thisArg, uint32_t argc, const JSTaggedType argv[]) { // 1. ReturnIfAbrupt(F). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -287,22 +272,24 @@ JSTaggedValue JSFunction::Call(JSThread *thread, const JSHandle & if (!func->IsCallable()) { THROW_TYPE_ERROR_AND_RETURN(thread, "Callable is false", JSTaggedValue::Exception()); } + if (func->IsJSFunction()) { - return JSFunction::CallInternal(thread, JSHandle(func), thisArg, argv); + return JSFunction::CallInternal(thread, JSHandle(func), thisArg, argc, argv); } - // 4. Return F.[[Call]](V, argumentsList). + if (func->IsBoundFunction()) { - return JSBoundFunction::CallInternal(thread, JSHandle(func), thisArg, argv); + return JSBoundFunction::CallInternal(thread, JSHandle(func)); } + if (func->IsJSProxy()) { - return JSProxy::CallInternal(thread, JSHandle(func), thisArg, argv); + return JSProxy::CallInternal(thread, JSHandle(func), thisArg, argc, argv); } THROW_TYPE_ERROR_AND_RETURN(thread, "Call NonCallable", JSTaggedValue::Exception()); } -JSTaggedValue JSFunction::Construct(JSThread *thread, const JSHandle &func, - const JSHandle &argv, const JSHandle &newTarget) +JSTaggedValue JSFunction::Construct(JSThread *thread, const JSHandle &func, uint32_t argc, + const JSTaggedType argv[], const JSHandle &newTarget) { JSMutableHandle target(thread, newTarget.GetTaggedValue()); if (target->IsUndefined()) { @@ -312,28 +299,28 @@ JSTaggedValue JSFunction::Construct(JSThread *thread, const JSHandleIsJSFunction()) { - return JSFunction::ConstructInternal(thread, JSHandle(func), argv, target); + return JSFunction::ConstructInternal(thread, JSHandle(func), argc, argv, target); } if (func->IsBoundFunction()) { - return JSBoundFunction::ConstructInternal(thread, JSHandle(func), argv, target); + return JSBoundFunction::ConstructInternal(thread, JSHandle(func), target); } if (func->IsJSProxy()) { - return JSProxy::ConstructInternal(thread, JSHandle(func), argv, target); + return JSProxy::ConstructInternal(thread, JSHandle(func), argc, argv, target); } THROW_TYPE_ERROR_AND_RETURN(thread, "Constructor NonConstructor", JSTaggedValue::Exception()); } JSTaggedValue JSFunction::Invoke(JSThread *thread, const JSHandle &thisArg, - const JSHandle &key, const JSHandle &argv) + const JSHandle &key, uint32_t argc, const JSTaggedType argv[]) { ASSERT(JSTaggedValue::IsPropertyKey(key)); JSHandle func(JSTaggedValue::GetProperty(thread, thisArg, key).GetValue()); - return JSFunction::Call(thread, func, thisArg, argv); + return JSFunction::Call(thread, func, thisArg, argc, argv); } // [[Call]] JSTaggedValue JSFunction::CallInternal(JSThread *thread, const JSHandle &func, - const JSHandle &thisArg, const JSHandle &argv) + const JSHandle &thisArg, uint32_t argc, const JSTaggedType argv[]) { if (!func->IsBuiltinsConstructor() && func->IsClassConstructor()) { THROW_TYPE_ERROR_AND_RETURN(thread, "class constructor cannot call", JSTaggedValue::Exception()); @@ -342,21 +329,14 @@ JSTaggedValue JSFunction::CallInternal(JSThread *thread, const JSHandleGetLength(); - CVector values; - values.reserve(params.argc); - - for (array_size_t i = 0; i < params.argc; ++i) { - JSTaggedValue arg = argv->Get(i); - values.emplace_back(arg.GetRawData()); - } - params.argv = values.data(); + params.argc = argc; + params.argv = argv; return EcmaInterpreter::Execute(thread, params); } // [[Construct]] -JSTaggedValue JSFunction::ConstructInternal(JSThread *thread, const JSHandle &func, - const JSHandle &argv, const JSHandle &newTarget) +JSTaggedValue JSFunction::ConstructInternal(JSThread *thread, const JSHandle &func, uint32_t argc, + const JSTaggedType argv[], const JSHandle &newTarget) { ASSERT(newTarget->IsECMAObject()); if (!func->IsConstructor()) { @@ -373,15 +353,8 @@ JSTaggedValue JSFunction::ConstructInternal(JSThread *thread, const JSHandleGetLength(); - CVector values; - values.reserve(params.argc); - - for (uint32_t i = 0; i < params.argc; ++i) { - JSTaggedValue arg = argv->Get(i); - values.emplace_back(arg.GetRawData()); - } - params.argv = values.data(); + params.argc = argc; + params.argv = argv; JSTaggedValue resultValue = EcmaInterpreter::Execute(thread, params); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -440,8 +413,8 @@ bool JSFunctionBase::SetFunctionName(JSThread *thread, const JSHandleGetEmptyString(); } else { - JSHandle leftBrackets = factory->NewFromString("["); - JSHandle rightBrackets = factory->NewFromString("]"); + JSHandle leftBrackets = factory->NewFromCanBeCompressString("["); + JSHandle rightBrackets = factory->NewFromCanBeCompressString("]"); functionName = factory->ConcatFromString(leftBrackets, descriptionHandle); functionName = factory->ConcatFromString(functionName, rightBrackets); } @@ -451,7 +424,7 @@ bool JSFunctionBase::SetFunctionName(JSThread *thread, const JSHandle handlePrefixString = JSTaggedValue::ToString(thread, prefix); - JSHandle spaceString(factory->NewFromString(" ")); + JSHandle spaceString(factory->NewFromCanBeCompressString(" ")); JSHandle concatString = factory->ConcatFromString(handlePrefixString, spaceString); newString = *factory->ConcatFromString(concatString, functionName); } else { @@ -477,32 +450,29 @@ bool JSFunction::SetFunctionLength(JSThread *thread, const JSHandle return JSTaggedValue::DefinePropertyOrThrow(thread, funcHandle, lengthKeyHandle, lengthDesc); } -// 9.4.1.1[[Call]](thisArgument, argumentsList) -JSTaggedValue JSBoundFunction::CallInternal(JSThread *thread, const JSHandle &func, - [[maybe_unused]] const JSHandle &thisArg, - const JSHandle &argv) +JSTaggedValue JSBoundFunction::CallInternal(JSThread *thread, const JSHandle &func) { JSHandle target(thread, func->GetBoundTarget()); JSHandle boundThis(thread, func->GetBoundThis()); - JSHandle boundArgs(thread, func->GetBoundArguments()); - JSHandle arguments = TaggedArray::Append(thread, boundArgs, argv); - return JSFunction::Call(thread, target, boundThis, arguments); + + InternalCallParams *params = thread->GetInternalCallParams(); + params->MakeBoundArgv(thread, func); + return JSFunction::Call(thread, target, boundThis, params->GetLength(), params->GetArgv()); } // 9.4.1.2[[Construct]](argumentsList, newTarget) JSTaggedValue JSBoundFunction::ConstructInternal(JSThread *thread, const JSHandle &func, - const JSHandle &argv, const JSHandle &newTarget) { JSHandle target(thread, func->GetBoundTarget()); ASSERT(target->IsConstructor()); - JSHandle boundArgs(thread, func->GetBoundArguments()); - JSHandle arguments = TaggedArray::Append(thread, boundArgs, argv); JSMutableHandle newTargetMutable(thread, newTarget.GetTaggedValue()); if (JSTaggedValue::SameValue(func.GetTaggedValue(), newTarget.GetTaggedValue())) { newTargetMutable.Update(target.GetTaggedValue()); } - return JSFunction::Construct(thread, target, arguments, newTargetMutable); + InternalCallParams *params = thread->GetInternalCallParams(); + params->MakeBoundArgv(thread, func); + return JSFunction::Construct(thread, target, params->GetLength(), params->GetArgv(), newTargetMutable); } void JSProxyRevocFunction::ProxyRevocFunctions(const JSThread *thread, const JSHandle &revoker) @@ -533,6 +503,11 @@ JSTaggedValue JSFunction::AccessCallerArgumentsThrowTypeError([[maybe_unused]] E JSTaggedValue::Exception()); } +JSTaggedValue JSIntlBoundFunction::IntlNameGetter(JSThread *thread, [[maybe_unused]] const JSHandle &self) +{ + return thread->GlobalConstants()->GetEmptyString(); +} + void JSFunction::SetFunctionNameNoPrefix(JSThread *thread, JSFunction *func, JSTaggedValue name) { ASSERT_PRINT(func->IsExtensible(), "Function must be extensible"); @@ -550,8 +525,8 @@ void JSFunction::SetFunctionNameNoPrefix(JSThread *thread, JSFunction *func, JST nameHandle.Update(thread->GlobalConstants()->GetEmptyString()); } else { JSHandle concatName; - JSHandle leftBrackets = factory->NewFromString("["); - JSHandle rightBrackets = factory->NewFromString("]"); + JSHandle leftBrackets = factory->NewFromCanBeCompressString("["); + JSHandle rightBrackets = factory->NewFromCanBeCompressString("]"); concatName = factory->ConcatFromString( leftBrackets, JSHandle(thread, JSSymbol::Cast(nameBegin->GetHeapObject())->GetDescription())); @@ -666,16 +641,4 @@ bool JSFunction::NameSetter(JSThread *thread, const JSHandle &self, co self->SetPropertyInlinedProps(thread, NAME_INLINE_PROPERTY_INDEX, value.GetTaggedValue()); return true; } - -bool JSFunction::LengthSetter(JSThread *thread, const JSHandle &self, const JSHandle &value, - [[maybe_unused]] bool mayThrow) -{ - if (self->IsPropertiesDict()) { - // replace setter with value - JSHandle lengthString = thread->GlobalConstants()->GetHandledLengthString(); - return self->UpdatePropertyInDictionary(thread, lengthString.GetTaggedValue(), value.GetTaggedValue()); - } - self->SetPropertyInlinedProps(thread, LENGTH_INLINE_PROPERTY_INDEX, value.GetTaggedValue()); - return true; -} } // namespace panda::ecmascript diff --git a/ecmascript/js_function.h b/ecmascript/js_function.h index f13b07ca9f66f408e2f971c793345371b9ffc6f5..316399e1aaeb4c8b2894f4406506734c3750dba0 100644 --- a/ecmascript/js_function.h +++ b/ecmascript/js_function.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSFUCNTION_H -#define PANDA_RUNTIME_ECMASCRIPT_JSFUCNTION_H +#ifndef ECMASCRIPT_JSFUCNTION_H +#define ECMASCRIPT_JSFUCNTION_H #include "ecmascript/accessor_data.h" #include "ecmascript/ecma_macros.h" @@ -88,20 +88,22 @@ public: // ecma6 9.2 // 7.3.12 Call(F, V, argumentsList) + static JSTaggedValue Call(JSThread *thread, const JSHandle &func, - const JSHandle &thisArg, const JSHandle &argv); - static JSTaggedValue Construct(JSThread *thread, const JSHandle &func, - const JSHandle &argv, const JSHandle &newTarget); + const JSHandle &thisArg, uint32_t argc, const JSTaggedType argv[]); + + static JSTaggedValue Construct(JSThread *thread, const JSHandle &func, uint32_t argc, + const JSTaggedType argv[], const JSHandle &newTarget); static JSTaggedValue Invoke(JSThread *thread, const JSHandle &thisArg, - const JSHandle &key, const JSHandle &argv); + const JSHandle &key, uint32_t argc, const JSTaggedType argv[]); // 9.2.1[[Call]](thisArgument, argumentsList) // 9.3.1[[Call]](thisArgument, argumentsList) static JSTaggedValue CallInternal(JSThread *thread, const JSHandle &func, - const JSHandle &thisArg, const JSHandle &argv); + const JSHandle &thisArg, uint32_t argc, const JSTaggedType argv[]); // 9.2.2[[Construct]](argumentsList, newTarget) // 9.3.2[[Construct]](argumentsList, newTarget) - static JSTaggedValue ConstructInternal(JSThread *thread, const JSHandle &func, - const JSHandle &argv, const JSHandle &newTarget); + static JSTaggedValue ConstructInternal(JSThread *thread, const JSHandle &func, uint32_t argc, + const JSTaggedType argv[], const JSHandle &newTarget); static bool AddRestrictedFunctionProperties(const JSHandle &func, const JSHandle &realm); static bool MakeConstructor(JSThread *thread, const JSHandle &func, @@ -123,9 +125,6 @@ public: static JSTaggedValue NameGetter(JSThread *thread, const JSHandle &self); static bool NameSetter(JSThread *thread, const JSHandle &self, const JSHandle &value, bool mayThrow); - static JSTaggedValue LengthGetter(JSThread *thread, const JSHandle &self); - static bool LengthSetter(JSThread *thread, const JSHandle &self, const JSHandle &value, - bool mayThrow); static void SetFunctionNameNoPrefix(JSThread *thread, JSFunction *func, JSTaggedValue name); static JSHandle GetInstanceDynClass(JSThread *thread, JSHandle constructor, JSHandle newTarget); @@ -326,11 +325,11 @@ public: } // 9.4.1.1[[Call]](thisArgument, argumentsList) - static JSTaggedValue CallInternal(JSThread *thread, const JSHandle &func, - const JSHandle &thisArg, const JSHandle &argv); + static JSTaggedValue CallInternal(JSThread *thread, const JSHandle &func); + // 9.4.1.2[[Construct]](argumentsList, newTarget) static JSTaggedValue ConstructInternal(JSThread *thread, const JSHandle &func, - const JSHandle &argv, const JSHandle &newTarget); + const JSHandle &newTarget); static constexpr size_t BOUND_TARGET_OFFSET = JSFunctionBase::SIZE; ACCESSORS(BoundTarget, BOUND_TARGET_OFFSET, BOUND_THIS_OFFSET); @@ -414,6 +413,25 @@ public: DECL_DUMP() }; + +class JSIntlBoundFunction : public JSFunction { +public: + static JSIntlBoundFunction *Cast(ObjectHeader *object) + { + ASSERT(JSTaggedValue(object).IsJSIntlBoundFunction()); + return static_cast(object); + } + + static JSTaggedValue IntlNameGetter(JSThread *thread, const JSHandle &self); + + static constexpr size_t NUMBER_FORMAT_OFFSET = JSFunction::SIZE; + + ACCESSORS(NumberFormat, NUMBER_FORMAT_OFFSET, DATETIME_FORMAT_OFFSET); + ACCESSORS(DateTimeFormat, DATETIME_FORMAT_OFFSET, COLLATOR_OFFSET); + ACCESSORS(Collator, COLLATOR_OFFSET, SIZE); + + DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, NUMBER_FORMAT_OFFSET, SIZE) +}; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSFUCNTION_H +#endif // ECMASCRIPT_JSFUCNTION_H diff --git a/ecmascript/js_function_extra_info.h b/ecmascript/js_function_extra_info.h index 1258e4450dd5f1c879899c5ec4f02e047836eac0..5c789e86a979daeb36bd0430c9eb30834f489153 100644 --- a/ecmascript/js_function_extra_info.h +++ b/ecmascript/js_function_extra_info.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_FUNCTION_INFO_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_FUNCTION_INFO_H +#ifndef ECMASCRIPT_JS_FUNCTION_INFO_H +#define ECMASCRIPT_JS_FUNCTION_INFO_H #include "utils/bit_field.h" #include "ecmascript/ecma_macros.h" @@ -31,7 +31,7 @@ public: return static_cast(object); } - static constexpr size_t CALL_BACK_OFFSET = sizeof(TaggedObject); + static constexpr size_t CALL_BACK_OFFSET = TaggedObjectSize(); ACCESSORS(Callback, CALL_BACK_OFFSET, DATA_OFFSET); ACCESSORS(Data, DATA_OFFSET, SIZE); diff --git a/ecmascript/js_function_kind.h b/ecmascript/js_function_kind.h index d035caf509f12200f61d174274060fe244201334..50e95fff7d668ac3bdb124e94361de442981694e 100644 --- a/ecmascript/js_function_kind.h +++ b/ecmascript/js_function_kind.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_FUNCTION_KIND_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_FUNCTION_KIND_H +#ifndef ECMASCRIPT_JS_FUNCTION_KIND_H +#define ECMASCRIPT_JS_FUNCTION_KIND_H #include @@ -73,4 +73,4 @@ enum FunctionMode : uint8_t { }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_FUNCTION_KIND_H +#endif // ECMASCRIPT_JS_FUNCTION_KIND_H diff --git a/ecmascript/js_generator_object.h b/ecmascript/js_generator_object.h index 97b4a943f49f97fc632e74e7a33bbbafa5392d29..faf1796618f7251ff848ef378747d3250f8813c7 100644 --- a/ecmascript/js_generator_object.h +++ b/ecmascript/js_generator_object.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_GENERATOR_OBJECT_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_GENERATOR_OBJECT_H +#ifndef ECMASCRIPT_JS_GENERATOR_OBJECT_H +#define ECMASCRIPT_JS_GENERATOR_OBJECT_H #include "ecmascript/js_function.h" @@ -36,7 +36,7 @@ public: return static_cast(object); } - static constexpr size_t GENERATOR_REGS_ARRAY_OFFSET = sizeof(TaggedObject); + static constexpr size_t GENERATOR_REGS_ARRAY_OFFSET = TaggedObjectSize(); ACCESSORS(RegsArray, GENERATOR_REGS_ARRAY_OFFSET, GENERATOR_METHOD_OFFSET) ACCESSORS(Method, GENERATOR_METHOD_OFFSET, GENERATOR_ACC_OFFSET) ACCESSORS(Acc, GENERATOR_ACC_OFFSET, GENERATOR_NREGS_OFFSET) @@ -102,4 +102,4 @@ public: } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_GENERATOR_OBJECT_H +#endif // ECMASCRIPT_JS_GENERATOR_OBJECT_H diff --git a/ecmascript/js_global_object.h b/ecmascript/js_global_object.h index 3f60b5e18de06844aed8a03c26bf43228a4dc46a..7fdbb07a1dafca5424149ddf8d08828a35ead044 100644 --- a/ecmascript/js_global_object.h +++ b/ecmascript/js_global_object.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSGLOBALOBJECT_H -#define PANDA_RUNTIME_ECMASCRIPT_JSGLOBALOBJECT_H +#ifndef ECMASCRIPT_JSGLOBALOBJECT_H +#define ECMASCRIPT_JSGLOBALOBJECT_H #include "ecmascript/js_object.h" #include "ecmascript/js_tagged_value.h" @@ -34,4 +34,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSGLOBALOBJECT_H +#endif // ECMASCRIPT_JSGLOBALOBJECT_H diff --git a/ecmascript/js_handle.h b/ecmascript/js_handle.h index 925817dbc126518eb2e0cb623aa8952959c41162..dffb90285e0d8eb57fa9117474f500d98e050bbe 100644 --- a/ecmascript/js_handle.h +++ b/ecmascript/js_handle.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSHANDLE_H -#define PANDA_RUNTIME_ECMASCRIPT_JSHANDLE_H +#ifndef ECMASCRIPT_JSHANDLE_H +#define ECMASCRIPT_JSHANDLE_H #include @@ -32,7 +32,7 @@ class LinkedHashMap; class LinkedHashSet; class NameDictionary; -template +template class JSHandle : public HandleBase { public: inline explicit JSHandle() : HandleBase(reinterpret_cast(nullptr)) {} @@ -55,12 +55,12 @@ public: address_ = EcmaHandleScope::NewHandle(const_cast(thread), JSTaggedValue(value).GetRawData()); } - template + template explicit JSHandle(const JSHandle &handle) : HandleBase(handle.GetAddress()) { } - template + template inline static JSHandle Cast(const JSHandle &handle) { T::Cast(handle.GetTaggedValue().GetTaggedObject()); @@ -104,7 +104,7 @@ public: return GetAddress() == 0U; } - template + template R *GetObject() const { return reinterpret_cast(GetTaggedValue().GetTaggedObject()); @@ -132,31 +132,31 @@ private: friend class GlobalHandleCollection; }; -template <> +template<> inline JSTaggedValue *JSHandle::operator->() const { return reinterpret_cast(GetAddress()); } -template <> +template<> inline JSTaggedValue *JSHandle::operator*() const { return reinterpret_cast(GetAddress()); } -template <> +template<> inline JSTaggedNumber *JSHandle::operator->() const { return reinterpret_cast(GetAddress()); } -template <> +template<> inline JSTaggedNumber *JSHandle::operator*() const { return reinterpret_cast(GetAddress()); } -template +template class JSMutableHandle : public JSHandle { public: JSMutableHandle() = default; @@ -167,7 +167,7 @@ public: explicit JSMutableHandle(const JSThread *thread, JSTaggedValue value) : JSHandle(thread, value) {} explicit JSMutableHandle(const JSThread *thread, const TaggedArray *value) : JSHandle(thread, value) {} - template + template explicit JSMutableHandle(const JSHandle &handle) : JSHandle(handle) { } @@ -180,4 +180,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSHANDLE_H +#endif // ECMASCRIPT_JSHANDLE_H diff --git a/ecmascript/js_hclass-inl.h b/ecmascript/js_hclass-inl.h index a199cb54c733e38d425326b6ba1f84a960ec9510..2eeccd944ccb4c876ce040b134c19d046ce15d6a 100644 --- a/ecmascript/js_hclass-inl.h +++ b/ecmascript/js_hclass-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_HCLASS_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_HCLASS_INL_H +#ifndef ECMASCRIPT_JS_HCLASS_INL_H +#define ECMASCRIPT_JS_HCLASS_INL_H #include "ecmascript/js_hclass.h" @@ -160,6 +160,9 @@ inline size_t JSHClass::SizeFromJSHClass(JSType type, TaggedObject *header) if (type == JSType::STRING) { return reinterpret_cast(header)->ObjectSize(); } + if (type == JSType::MACHINE_CODE_OBJECT) { + return reinterpret_cast(header)->GetMachineCodeObjectSize(); + } ASSERT(GetObjectSize() != 0); return GetObjectSize(); } @@ -174,4 +177,4 @@ inline void JSHClass::Copy(const JSThread *thread, const JSHClass *jshcalss) } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_HCLASS_INL_H +#endif // ECMASCRIPT_JS_HCLASS_INL_H diff --git a/ecmascript/js_hclass.cpp b/ecmascript/js_hclass.cpp index a0b6dbe33e3603029b795c48e98e8736ffcbe785..be304ec9ca11002f3b4d9693343466ec6f5c5009 100644 --- a/ecmascript/js_hclass.cpp +++ b/ecmascript/js_hclass.cpp @@ -17,6 +17,7 @@ #include +#include "ecmascript/base/config.h" #include "ecmascript/global_env.h" #include "ecmascript/ic/proto_change_details.h" #include "ecmascript/js_object-inl.h" @@ -26,8 +27,6 @@ #include "ecmascript/weak_vector-inl.h" namespace panda::ecmascript { -#define ENABLE_IC 0 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) - // class TransitionsDictionary TransitionsDictionary *TransitionsDictionary::PutIfAbsent(const JSThread *thread, const JSHandle &dictionary, @@ -56,8 +55,8 @@ TransitionsDictionary *TransitionsDictionary::PutIfAbsent(const JSThread *thread int TransitionsDictionary::FindEntry(const JSTaggedValue &key, const JSTaggedValue &metaData) { size_t size = Size(); - int count = 1; - int hash = TransitionsDictionary::Hash(key, metaData); + uint32_t count = 1; + uint32_t hash = TransitionsDictionary::Hash(key, metaData); // GrowHashTable will guarantee the hash table is never full. for (int entry = GetFirstPosition(hash, size);; entry = GetNextPosition(entry, count++, size)) { JSTaggedValue element = GetKey(entry); @@ -174,7 +173,7 @@ void JSHClass::TransitionElementsToDictionary(const JSThread *thread, const JSHa JSObject::TransitionToDictionary(thread, obj); } obj->GetJSHClass()->SetIsDictionaryElement(true); - obj->GetJSHClass()->SetIsStableJSArray(false); + obj->GetJSHClass()->SetIsStableElements(false); } void JSHClass::AddProperty(const JSThread *thread, const JSHandle &obj, const JSHandle &key, @@ -184,7 +183,7 @@ void JSHClass::AddProperty(const JSThread *thread, const JSHandle &obj JSHandle jshclass(thread, obj->GetJSHClass()); JSHClass *newDyn = jshclass->FindTransitions(key.GetTaggedValue(), JSTaggedValue(attr.GetPropertyMetaData())); if (newDyn != nullptr) { -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC JSHClass::NotifyHclassChanged(thread, jshclass, JSHandle(thread, newDyn)); #endif obj->SetClass(newDyn); @@ -226,7 +225,7 @@ void JSHClass::AddProperty(const JSThread *thread, const JSHandle &obj AddTransitions(thread, jshclass, newJshclass, key, attr); // 6. update hclass in object. -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC JSHClass::NotifyHclassChanged(thread, jshclass, newJshclass); #endif obj->SetClass(*newJshclass); @@ -333,7 +332,7 @@ void JSHClass::TransitionToDictionary(const JSThread *thread, const JSHandleSetIsDictionaryMode(true); // 3. Add newJshclass to ? -#if ENABLE_IC +#if ECMASCRIPT_ENABLE_IC JSHClass::NotifyHclassChanged(thread, JSHandle(thread, obj->GetJSHClass()), newJshclass); #endif obj->SetClass(newJshclass); diff --git a/ecmascript/js_hclass.h b/ecmascript/js_hclass.h index 46e097218406abbb017aa436983239edbe2d7fdc..0b6b7115f460ee6b067bbacac16151079097fe85 100644 --- a/ecmascript/js_hclass.h +++ b/ecmascript/js_hclass.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_HCLASS_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_HCLASS_H +#ifndef ECMASCRIPT_JS_HCLASS_H +#define ECMASCRIPT_JS_HCLASS_H #include "ecmascript/ecma_macros.h" #include "ecmascript/js_tagged_value.h" @@ -127,6 +127,7 @@ class ProtoChangeDetails; PENDING_JOB, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ FUNCTION_EXTRA_INFO, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ COMPLETION_RECORD, /* JS_RECORD_END /////////////////////////////////////////////////////////////////////// */ \ + MACHINE_CODE_OBJECT, \ ECMA_MODULE, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ JS_TYPE_LAST = ECMA_MODULE, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ \ @@ -166,16 +167,17 @@ public: using IsPrototypeBit = ExtensibleBit::NextFlag; using ElementRepresentationBits = IsPrototypeBit::NextField; // 3 means next 3 bit using DictionaryElementBits = ElementRepresentationBits::NextFlag; // 16 - using NumberOfUnusedInlinedPropsBits = DictionaryElementBits::NextField; // 3 means next 3 bit + using IsDictionaryBit = DictionaryElementBits::NextFlag; + using IsStableElementsBit = IsDictionaryBit::NextFlag; + using NumberOfUnusedInlinedPropsBits = IsStableElementsBit::NextField; // 3 means next 3 bit // the max value is 1024, need 11 bits using NumberOfUnusedNonInlinedPropsBits = - NumberOfUnusedInlinedPropsBits::NextField; // 29 - using IsLiteralBit = NumberOfUnusedNonInlinedPropsBits::NextFlag; + NumberOfUnusedInlinedPropsBits::NextField; // 31 + + using HasConstructorBits = NumberOfUnusedNonInlinedPropsBits::NextFlag; + using IsLiteralBit = HasConstructorBits::NextFlag; using ClassConstructorBit = IsLiteralBit::NextFlag; using ClassPrototypeBit = ClassConstructorBit::NextFlag; - using IsDictionaryBit = ClassPrototypeBit::NextFlag; - using IsStableJSArrayBit = IsDictionaryBit::NextFlag; - using HasConstructorBits = IsStableJSArrayBit::NextFlag; static constexpr int DEFAULT_CAPACITY_OF_IN_OBJECTS = 4; static constexpr int DEFAULT_CAPACITY_OF_OUT_OBJECTS = @@ -421,6 +423,11 @@ public: return GetObjectType() == JSType::JS_BOUND_FUNCTION; } + inline bool IsJSIntlBoundFunction() const + { + return GetObjectType() == JSType::JS_INTL_BOUND_FUNCTION; + } + inline bool IsJSProxyRevocFunction() const { return GetObjectType() == JSType::JS_PROXY_REVOC_FUNCTION; @@ -522,6 +529,41 @@ public: return GetObjectType() == JSType::JS_PROXY; } + inline bool IsJSLocale() const + { + return GetObjectType() == JSType::JS_LOCALE; + } + + inline bool IsJSIntl() const + { + return GetObjectType() == JSType::JS_INTL; + } + + inline bool IsJSDateTimeFormat() const + { + return GetObjectType() == JSType::JS_DATE_TIME_FORMAT; + } + + inline bool IsJSRelativeTimeFormat() const + { + return GetObjectType() == JSType::JS_RELATIVE_TIME_FORMAT; + } + + inline bool IsJSNumberFormat() const + { + return GetObjectType() == JSType::JS_NUMBER_FORMAT; + } + + inline bool IsJSCollator() const + { + return GetObjectType() == JSType::JS_COLLATOR; + } + + inline bool IsJSPluralRules() const + { + return GetObjectType() == JSType::JS_PLURAL_RULES; + } + inline bool IsAccessorData() const { return GetObjectType() == JSType::ACCESSOR_DATA; @@ -752,6 +794,11 @@ public: return GetObjectType() == JSType::FREE_OBJECT_WITH_TWO_FIELD; } + inline bool IsMachineCodeObject() const + { + return GetObjectType() == JSType::MACHINE_CODE_OBJECT; + } + inline void SetElementRepresentation(Representation representation) { uint64_t bits = GetBitField(); @@ -780,16 +827,26 @@ public: { return DictionaryElementBits::Decode(GetBitField()); } - inline void SetIsStableJSArray(bool value) + inline void SetIsStableElements(bool value) { - ASSERT(!value || (IsJSArray() && !IsDictionaryElement())); - JSTaggedType newVal = IsStableJSArrayBit::Update(GetBitField(), value); + JSTaggedType newVal = IsStableElementsBit::Update(GetBitField(), value); SetBitField(newVal); } + inline bool IsStableElements() const + { + return IsStableElementsBit::Decode(GetBitField()); + } + inline bool IsStableJSArguments() const + { + uint64_t bits = GetBitField(); + auto type = ObjectTypeBits::Decode(bits); + return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARGUMENTS); + } inline bool IsStableJSArray() const { - ASSERT(!IsStableJSArrayBit::Decode(GetBitField()) || (IsJSArray() && !IsDictionaryElement())); - return IsStableJSArrayBit::Decode(GetBitField()); + uint64_t bits = GetBitField(); + auto type = ObjectTypeBits::Decode(bits); + return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARRAY); } inline void SetHasConstructor(bool value) { @@ -850,7 +907,7 @@ public: JSTaggedValue GetAccessor(const JSTaggedValue &key); - static constexpr size_t BIT_FIELD_OFFSET = sizeof(TaggedObject) + sizeof(HClass); + static constexpr size_t BIT_FIELD_OFFSET = TaggedObjectSize(); SET_GET_PRIMITIVE_FIELD(BitField, uint64_t, BIT_FIELD_OFFSET, OBJECT_SIZE_OFFSET); SET_GET_PRIMITIVE_FIELD(ObjectSize, uint64_t, OBJECT_SIZE_OFFSET, PROTOTYPE_OFFSET); ACCESSORS(Proto, PROTOTYPE_OFFSET, ATTRIBUTES_OFFSET); @@ -897,4 +954,4 @@ private: static_assert(JSHClass::BIT_FIELD_OFFSET % static_cast(MemAlignment::MEM_ALIGN_OBJECT) == 0); } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_HCLASS_H +#endif // ECMASCRIPT_JS_HCLASS_H diff --git a/ecmascript/js_uint16_array.h b/ecmascript/js_intl.h similarity index 40% rename from ecmascript/js_uint16_array.h rename to ecmascript/js_intl.h index f4fd907f8cdb61ef6bb2f3afb390aeb2cddb5329..d4c91a60f4c240e4935d7af8672f35e595b82e09 100644 --- a/ecmascript/js_uint16_array.h +++ b/ecmascript/js_intl.h @@ -1,45 +1,38 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_UINT16_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_UINT16_ARRAY_H - -#include -#include "ecmascript/js_object.h" -#include "ecmascript/js_tagged_value-inl.h" -#include "ecmascript/js_tagged_value.h" - -namespace panda::ecmascript { -class JSUint16Array : public JSObject { -public: - static JSUint16Array *Cast(ObjectHeader *object) - { - ASSERT(JSTaggedValue(object).IsJSUint16Array()); - return static_cast(object); - } - - static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE; - ACCESSORS(ViewedArrayBuffer, VIEWED_ARRAY_BUFFER_OFFSET, TYPED_ARRAY_NAME_OFFSET) - ACCESSORS(TypedArrayName, TYPED_ARRAY_NAME_OFFSET, BYTE_LENGTH_OFFSET) - ACCESSORS(ByteLength, BYTE_LENGTH_OFFSET, BYTE_OFFSET_OFFSET) - ACCESSORS(ByteOffset, BYTE_OFFSET_OFFSET, ARRAY_LENGTH_OFFSET) - ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, SIZE) - DECL_DUMP() - - DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE) -}; -} // namespace panda::ecmascript - -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_UINT16_ARRAY_H \ No newline at end of file +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_JSINTL_H +#define ECMASCRIPT_JSINTL_H + +#include "js_object.h" + +namespace panda::ecmascript { +class JSIntl : public JSObject { +public: + static JSIntl *Cast(ObjectHeader *object) + { + ASSERT(JSTaggedValue(object).IsJSIntl()); + return static_cast(object); + } + + static constexpr size_t FALLBACK_SYMBOL = JSObject::SIZE; + + ACCESSORS(FallbackSymbol, FALLBACK_SYMBOL, SIZE) + + DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, FALLBACK_SYMBOL, SIZE) +}; +} // namespace panda::ecmascript + +#endif // ECMASCRIPT_JSINTL_H \ No newline at end of file diff --git a/ecmascript/js_invoker.cpp b/ecmascript/js_invoker.cpp index 65d82b939cb43809a1e90f7dd5eeeccb10b8e832..d5d45eb2b882a1ff268f9f8535a61fcb2ba1a7f9 100644 --- a/ecmascript/js_invoker.cpp +++ b/ecmascript/js_invoker.cpp @@ -30,7 +30,7 @@ JSTaggedValue JsInvoker::Invoke(JSThread *thread) } JSTaggedValue InvokeJsFunction(JSThread *thread, const JSHandle &func, const JSHandle &obj, - const JSHandle &newTgt, const JSHandle &args) + const JSHandle &newTgt, InternalCallParams *arguments) { ASSERT(func->GetCallTarget() != nullptr); @@ -38,16 +38,8 @@ JSTaggedValue InvokeJsFunction(JSThread *thread, const JSHandle &fun params.callTarget = ECMAObject::Cast(*func); params.newTarget = newTgt.GetTaggedType(); params.thisArg = obj.GetTaggedType(); - params.argc = args->GetLength(); - CVector values; - values.reserve(params.argc); - - for (uint32_t i = 0; i < params.argc; ++i) { - JSTaggedValue arg = args->Get(thread, i); - values.emplace_back(arg.GetRawData()); - } - - params.argv = values.data(); + params.argc = arguments->GetLength(); + params.argv = arguments->GetArgv(); return EcmaInterpreter::Execute(thread, params); } } // namespace panda::ecmascript diff --git a/ecmascript/js_invoker.h b/ecmascript/js_invoker.h index e31546279394977cb05758a5b8ed53ae5291c4e6..92a0464e6412690cf37d96c99756840e6117e251 100644 --- a/ecmascript/js_invoker.h +++ b/ecmascript/js_invoker.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_INVOKE_H -#define PANDA_RUNTIME_ECMASCRIPT_INVOKE_H +#ifndef ECMASCRIPT_INVOKE_H +#define ECMASCRIPT_INVOKE_H #include "ecmascript/js_function.h" #include "ecmascript/js_handle.h" @@ -41,13 +41,13 @@ public: NO_COPY_SEMANTIC(JsInvoker); NO_MOVE_SEMANTIC(JsInvoker); - template + template void AddArgument(const JSHandle &arg) { args_.emplace_back(JSHandle(arg)); } - template + template void AddArgument(JSHandle &&arg) { args_.emplace_back(std::move(arg)); @@ -60,7 +60,7 @@ private: }; JSTaggedValue InvokeJsFunction(JSThread *thread, const JSHandle &func, const JSHandle &obj, - const JSHandle &newTgt, const JSHandle &args); + const JSHandle &newTgt, InternalCallParams *arguments); } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_INVOKE_H +#endif // ECMASCRIPT_INVOKE_H diff --git a/ecmascript/js_iterator.cpp b/ecmascript/js_iterator.cpp index 191a3bb6743cbf629d0e2ce56753b1119bf6be01..41eb2b414f9838ce8da43675a47ecf9138b26e82 100644 --- a/ecmascript/js_iterator.cpp +++ b/ecmascript/js_iterator.cpp @@ -17,6 +17,7 @@ #include "ecma_macros.h" #include "ecma_vm.h" #include "ecmascript/accessor_data.h" +#include "ecmascript/internal_call_params.h" #include "global_env.h" #include "js_invoker.h" #include "js_symbol.h" @@ -60,12 +61,10 @@ JSHandle JSIterator::GetIterator(JSThread *thread, const JSHandle JSHandle JSIterator::GetIterator(JSThread *thread, const JSHandle &obj, const JSHandle &method) { - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 1.ReturnIfAbrupt(obj). RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, obj); // 3.Let iterator be Call(method,obj). - JSHandle array(factory->EmptyArray()); - JSTaggedValue ret = JSFunction::Call(thread, method, obj, array); + JSTaggedValue ret = JSFunction::Call(thread, method, obj, 0, nullptr); JSHandle iter(thread, ret); // 4.ReturnIfAbrupt(iterator). RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, iter); @@ -80,13 +79,10 @@ JSHandle JSIterator::GetIterator(JSThread *thread, const JSHandle JSHandle JSIterator::IteratorNext(JSThread *thread, const JSHandle &iter) { // 1.If value was not passed, then Let result be Invoke(iterator, "next", «‍ »). - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - - JSHandle argv(factory->EmptyArray()); JSHandle key(thread->GlobalConstants()->GetHandledNextString()); JSHandle next(JSObject::GetMethod(thread, iter, key)); ASSERT(next->IsCallable()); - JSTaggedValue ret = JSFunction::Call(thread, next, iter, argv); + JSTaggedValue ret = JSFunction::Call(thread, next, iter, 0, nullptr); JSHandle result(thread, ret); // 3.ReturnIfAbrupt(result) RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, result); @@ -100,14 +96,14 @@ JSHandle JSIterator::IteratorNext(JSThread *thread, const JSHandle JSIterator::IteratorNext(JSThread *thread, const JSHandle &iter, const JSHandle &value) { - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // 2.Let result be Invoke(iterator, "next", «‍value»). - JSHandle argv(factory->NewTaggedArray(1)); - argv->Set(thread, 0, value); JSHandle key(thread->GlobalConstants()->GetHandledNextString()); JSHandle next(JSObject::GetMethod(thread, iter, key)); ASSERT(next->IsCallable()); - JSTaggedValue ret = JSFunction::Call(thread, next, iter, argv); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(value); + JSTaggedValue ret = JSFunction::Call(thread, next, iter, 1, arguments->GetArgv()); + JSHandle result(thread, ret); // 3.ReturnIfAbrupt(result) RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, result); @@ -160,8 +156,6 @@ JSHandle JSIterator::IteratorClose(JSThread *thread, const JSHand { // 1.Assert: Type(iterator) is Object. ASSERT_PRINT(iter->IsECMAObject(), "iter must be JSObject"); - auto ecmaVm = thread->GetEcmaVM(); - ObjectFactory *factory = ecmaVm->GetFactory(); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); JSHandle exceptionOnThread; if (thread->HasPendingException()) { @@ -181,7 +175,7 @@ JSHandle JSIterator::IteratorClose(JSThread *thread, const JSHand return completion; } // 6.Let innerResult be Call(return, iterator, «‍ »). - JSTaggedValue ret = JSFunction::Call(thread, returnFunc, iter, factory->EmptyArray()); + JSTaggedValue ret = JSFunction::Call(thread, returnFunc, iter, 0, nullptr); if (!exceptionOnThread.IsEmpty()) { thread->SetException(exceptionOnThread.GetTaggedValue()); } diff --git a/ecmascript/js_iterator.h b/ecmascript/js_iterator.h index 5c3c733753d0eefe3cd6227c15cc87fde2072dde..5c44fd0f23b1b32557b4ca5426b415e7f6182a29 100644 --- a/ecmascript/js_iterator.h +++ b/ecmascript/js_iterator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_ITERATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_ITERATOR_H +#ifndef ECMASCRIPT_JS_ITERATOR_H +#define ECMASCRIPT_JS_ITERATOR_H #include "ecmascript/js_tagged_value.h" #include "tagged_array-inl.h" @@ -48,4 +48,4 @@ public: static JSHandle CreateIterResultObject(JSThread *thread, const JSHandle &value, bool done); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_ITERATOR_H +#endif // ECMASCRIPT_JS_ITERATOR_H diff --git a/ecmascript/js_locale.cpp b/ecmascript/js_locale.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f87f3830ec4f7f4e3dafec5a1b88d918ad90d1c1 --- /dev/null +++ b/ecmascript/js_locale.cpp @@ -0,0 +1,1391 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "base/string_helper.h" +#include "ecma_macros.h" +#include "ecma_vm.h" +#include "global_env.h" +#include "js_locale.h" +#include "object_factory.h" + +#include "unicode/localebuilder.h" +#include "unicode/localematcher.h" + +namespace panda::ecmascript { +// 6.2.2 IsStructurallyValidLanguageTag( locale ) +bool JSLocale::IsStructurallyValidLanguageTag(const JSHandle &tag) +{ + std::string tagCollection = ConvertToStdString(tag); + std::vector containers; + std::string substring; + std::set uniqueSubtags; + size_t address = 1; + for (auto it = tagCollection.begin(); it != tagCollection.end(); it++) { + if (*it != '-' && it != tagCollection.end() - 1) { + substring += *it; + } else { + if (it == tagCollection.end() - 1) { + substring += *it; + } + containers.push_back(substring); + if (IsVariantSubtag(substring)) { + std::transform(substring.begin(), substring.end(), substring.begin(), AsciiAlphaToLower); + if (!uniqueSubtags.insert(substring).second) { + return false; + } + } + substring.clear(); + } + } + bool result = DealwithLanguageTag(containers, address); + return result; +} + +std::string JSLocale::ConvertToStdString(const JSHandle &ecmaStr) +{ + return std::string(ConvertToString(*ecmaStr, StringConvertedUsage::LOGICOPERATION)); +} + +// 6.2.3 CanonicalizeUnicodeLocaleId( locale ) +JSHandle JSLocale::CanonicalizeUnicodeLocaleId(JSThread *thread, const JSHandle &locale) +{ + [[maybe_unused]] ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + if (!IsStructurallyValidLanguageTag(locale)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid locale", factory->GetEmptyString()); + } + + if (locale->GetLength() == 0 || locale->IsUtf16()) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid locale", factory->GetEmptyString()); + } + + std::string localeCStr = ConvertToStdString(locale); + std::transform(localeCStr.begin(), localeCStr.end(), localeCStr.begin(), AsciiAlphaToLower); + UErrorCode status = U_ZERO_ERROR; + icu::Locale formalLocale = icu::Locale::forLanguageTag(localeCStr.c_str(), status); + if ((U_FAILURE(status) != 0) || (formalLocale.isBogus() != 0)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid locale", factory->GetEmptyString()); + } + + // Resets the LocaleBuilder to match the locale. + // Returns an instance of Locale created from the fields set on this builder. + formalLocale = icu::LocaleBuilder().setLocale(formalLocale).build(status); + // Canonicalize the locale ID of this object according to CLDR. + formalLocale.canonicalize(status); + if ((U_FAILURE(status) != 0) || (formalLocale.isBogus() != 0)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid locale", factory->GetEmptyString()); + } + JSHandle languageTag = ToLanguageTag(thread, formalLocale); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread); + return languageTag; +} + +// 6.2.4 DefaultLocale () +JSHandle JSLocale::DefaultLocale(JSThread *thread) +{ + icu::Locale defaultLocale; + auto globalConst = thread->GlobalConstants(); + if (strcmp(defaultLocale.getName(), "en_US_POSIX") == 0 || strcmp(defaultLocale.getName(), "c") == 0) { + return JSHandle::Cast(globalConst->GetHandledEnUsString()); + } + if (defaultLocale.isBogus() != 0) { + return JSHandle::Cast(globalConst->GetHandledUndString()); + } + return ToLanguageTag(thread, defaultLocale); +} + +// 6.4.1 IsValidTimeZoneName ( timeZone ) +bool JSLocale::IsValidTimeZoneName(const icu::TimeZone &tz) +{ + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString id; + tz.getID(id); + icu::UnicodeString canonical; + icu::TimeZone::getCanonicalID(id, canonical, status); + UBool canonicalFlag = (canonical != icu::UnicodeString("Etc/Unknown", -1, US_INV)); + return (U_SUCCESS(status) != 0) && (canonicalFlag != 0); +} + +void JSLocale::HandleLocaleExtension(size_t &start, size_t &extensionEnd, + const std::string result, const size_t len) +{ + bool flag = false; + while (start < len - INTL_INDEX_TWO) { + if (result[start] != '-') { + start++; + continue; + } + if (result[start + INTL_INDEX_TWO] == '-') { + extensionEnd = start; + flag = true; + break; + } + if (!flag) { + start++; + } + start += INTL_INDEX_TWO; + } +} + +JSLocale::ParsedLocale JSLocale::HandleLocale(const JSHandle &localeString) +{ + std::string result = ConvertToStdString(localeString); + size_t len = result.size(); + ParsedLocale parsedResult; + + // a. The single-character subtag ’x’ as the primary subtag indicates + // that the language tag consists solely of subtags whose meaning is + // defined by private agreement. + // b. Extensions cannot be used in tags that are entirely private use. + if (IsPrivateSubTag(result, len)) { + parsedResult.base = result; + return parsedResult; + } + // If cannot find "-u-", return the whole string as base. + size_t foundExtension = result.find("-u-"); + if (foundExtension == std::string::npos) { + parsedResult.base = result; + return parsedResult; + } + // Let privateIndex be Call(%StringProto_indexOf%, foundLocale, « "-x-" »). + size_t praviteIndex = result.find("-x-"); + if (praviteIndex != std::string::npos && praviteIndex < foundExtension) { + parsedResult.base = result; + return parsedResult; + } + const std::string basis = result.substr(INTL_INDEX_ZERO, foundExtension); + size_t extensionEnd = len; + ASSERT(len > INTL_INDEX_TWO); + size_t start = foundExtension + INTL_INDEX_ONE; + HandleLocaleExtension(start, extensionEnd, result, len); + const std::string end = result.substr(extensionEnd); + parsedResult.base = basis + end; + parsedResult.extension = result.substr(foundExtension, extensionEnd - foundExtension); + return parsedResult; +} + +// 9.2.1 CanonicalizeLocaleList ( locales ) +JSHandle JSLocale::CanonicalizeLocaleList(JSThread *thread, const JSHandle &locales) +{ + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + // 1. If locales is undefined, then + // a. Return a new empty List. + if (locales->IsUndefined()) { + return factory->EmptyArray(); + } + // 2. Let seen be a new empty List. + JSHandle localeSeen = factory->NewTaggedArray(1); + // 3. If Type(locales) is String or Type(locales) is Object and locales has an [[InitializedLocale]] internal slot, + // then + // a. Let O be CreateArrayFromList(« locales »). + // 4. Else, + // a.Let O be ? ToObject(locales). + if (locales->IsString()) { + JSHandle tag = JSHandle::Cast(locales); + JSHandle temp = factory->NewTaggedArray(1); + temp->Set(thread, 0, tag.GetTaggedValue()); + JSHandle obj = JSArray::CreateArrayFromList(thread, temp); + JSHandle finalSeen = CanonicalizeHelper(thread, locales, obj, localeSeen); + return finalSeen; + } else if (locales->IsJSLocale()) { + JSHandle tag = JSLocale::ToString(thread, JSHandle::Cast(locales)); + JSHandle temp = factory->NewTaggedArray(1); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); + temp->Set(thread, 0, tag.GetTaggedValue()); + JSHandle obj = JSArray::CreateArrayFromList(thread, temp); + JSHandle finalSeen = CanonicalizeHelper(thread, locales, obj, localeSeen); + return finalSeen; + } else { + JSHandle obj = JSTaggedValue::ToObject(thread, locales); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); + JSHandle finalSeen = CanonicalizeHelper(thread, locales, obj, localeSeen); + return finalSeen; + } + return localeSeen; +} + +template +JSHandle JSLocale::CanonicalizeHelper(JSThread *thread, const JSHandle &locales, + JSHandle &obj, JSHandle &seen) +{ + OperationResult operationResult = JSTaggedValue::GetProperty(thread, JSHandle::Cast(obj), + thread->GlobalConstants()->GetHandledLengthString()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); + JSTaggedNumber len = JSTaggedValue::ToLength(thread, operationResult.GetValue()); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + // 2. Let seen be a new empty List. + uint32_t requestedLocalesLen = len.ToUint32(); + seen = factory->NewTaggedArray(requestedLocalesLen); + // 6. Let k be 0. + // 7. Repeat, while k < len + JSMutableHandle pk(thread, JSTaggedValue::Undefined()); + JSMutableHandle tag(thread, JSTaggedValue::Undefined()); + array_size_t index = 0; + JSHandle objTagged = JSHandle::Cast(obj); + for (uint32_t k = 0; k < requestedLocalesLen; k++) { + // a. Let Pk be ToString(k). + JSHandle kHandle(thread, JSTaggedValue(k)); + JSHandle str = JSTaggedValue::ToString(thread, kHandle); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); + pk.Update(str.GetTaggedValue()); + // b. Let kPresent be ? HasProperty(O, Pk). + bool kPresent = JSTaggedValue::HasProperty(thread, objTagged, pk); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); + + // c. If kPresent is true, then + if (kPresent) { + // i. Let kValue be ? Get(O, Pk). + OperationResult result = JSTaggedValue::GetProperty(thread, objTagged, pk); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); + JSHandle kValue = result.GetValue(); + // ii. If Type(kValue) is not String or Object, throw a TypeError exception. + if (!kValue->IsString() && !kValue->IsJSObject()) { + THROW_TYPE_ERROR_AND_RETURN(thread, "kValue is not String or Object.", factory->EmptyArray()); + } + // iii. If Type(kValue) is Object and kValue has an [[InitializedLocale]] internal slot, then + // 1. Let tag be kValue.[[Locale]]. + // iv. Else, + // 1. Let tag be ? ToString(kValue). + if (kValue->IsJSLocale()) { + JSHandle kValueStr = JSLocale::ToString(thread, JSHandle::Cast(kValue)); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); + tag.Update(kValueStr.GetTaggedValue()); + } else { + JSHandle kValueString = JSTaggedValue::ToString(thread, kValue); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); + JSHandle str = CanonicalizeUnicodeLocaleId(thread, kValueString); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); + tag.Update(str.GetTaggedValue()); + } + // vii. If canonicalizedTag is not an element of seen, append canonicalizedTag as the last element of seen. + bool isExist = false; + array_size_t len = seen->GetLength(); + for (array_size_t i = 0; i < len; i++) { + if (JSTaggedValue::SameValue(seen->Get(thread, i), tag.GetTaggedValue())) { + isExist = true; + } + } + if (!isExist) { + seen->Set(thread, index++, JSHandle::Cast(tag)); + } + } + // d. Increase k by 1. + } + // set capacity + seen = TaggedArray::SetCapacity(thread, seen, index); + // 8. Return seen. + return seen; +} + +// 9.2.2 BestAvailableLocale ( availableLocales, locale ) +std::string JSLocale::BestAvailableLocale(JSThread *thread, const JSHandle &availableLocales, + const std::string &locale) +{ + // 1. Let candidate be locale. + std::string localeCandidate = locale; + std::string undefined = std::string(); + // 2. Repeat, + array_size_t length = availableLocales->GetLength(); + JSMutableHandle item(thread, JSTaggedValue::Undefined()); + while (true) { + // a. If availableLocales contains an element equal to candidate, return candidate. + for (array_size_t i = 0; i < length; ++i) { + item.Update(availableLocales->Get(thread, i)); + std::string itemStr = ConvertToStdString(item); + if (itemStr == localeCandidate) { + return localeCandidate; + } + } + // b. Let pos be the character index of the last occurrence of "-" (U+002D) within candidate. + // If that character does not occur, return undefined. + size_t pos = localeCandidate.rfind('-'); + if (pos == std::string::npos) { + return undefined; + } + // c. If pos ≥ 2 and the character "-" occurs at index pos-2 of candidate, decrease pos by 2. + if (pos >= INTL_INDEX_TWO && localeCandidate[pos - INTL_INDEX_TWO] == '-') { + pos -= INTL_INDEX_TWO; + } + // d. Let candidate be the substring of candidate from position 0, inclusive, to position pos, exclusive. + localeCandidate = localeCandidate.substr(0, pos); + } +} + +// 9.2.3 LookupMatcher ( availableLocales, requestedLocales ) +JSHandle JSLocale::LookupMatcher(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales) +{ + MatcherResult result = {std::string(), std::string()}; + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + // 1. Let result be a new Record. + // 2. For each element locale of requestedLocales in List order, do + array_size_t length = requestedLocales->GetLength(); + JSMutableHandle locale(thread, JSTaggedValue::Undefined()); + for (array_size_t i = 0; i < length; ++i) { + locale.Update(requestedLocales->Get(thread, i)); + // 2. a. Let noExtensionsLocale be the String value that is locale + // with all Unicode locale extension sequences removed. + ParsedLocale parsedResult = HandleLocale(locale); + // 2. b. Let availableLocale be BestAvailableLocale(availableLocales, noExtensionsLocale). + std::string availableLocale = BestAvailableLocale(thread, availableLocales, parsedResult.base); + // 2. c. If availableLocale is not undefined, append locale to the end of subset. + if (!availableLocale.empty()) { + result = {std::string(), std::string()}; + // 2. c. i. Set result.[[locale]] to availableLocale. + result.locale = availableLocale; + // 2. c. ii. If locale and noExtensionsLocale are not the same String value, then + // 2. c. ii. 1. Let extension be the String value consisting of the first substring of locale that is a + // Unicode locale extension sequence. + if (!parsedResult.extension.empty()) { + result.extension = parsedResult.extension; + } + // 2. c. ii. 2. Set result.[[extension]] to extension. + std::string res = result.locale + result.extension; + // 2. c. iii. Return result. + return factory->NewFromStdString(res); + } + } + + // 3. Let defLocale be DefaultLocale(); + // 4. Set result.[[locale]] to defLocale. + // 5. Return result. + std::string defLocale = ConvertToStdString(DefaultLocale(thread)); + result.locale = defLocale; + return factory->NewFromStdString(result.locale); +} + +icu::LocaleMatcher BuildLocaleMatcher(JSThread *thread, array_size_t *availableLength, UErrorCode *status, + const JSHandle &availableLocales) +{ + std::string locale = JSLocale::ConvertToStdString(JSLocale::DefaultLocale(thread)); + icu::Locale defaultLocale = icu::Locale::forLanguageTag(locale, *status); + ASSERT_PRINT(U_SUCCESS(*status), "icu::Locale::forLanguageTag failed"); + icu::LocaleMatcher::Builder builder; + builder.setDefaultLocale(&defaultLocale); + array_size_t length = availableLocales->GetLength(); + + JSMutableHandle item(thread, JSTaggedValue::Undefined()); + for (*availableLength = 0; *availableLength < length; ++(*availableLength)) { + item.Update(availableLocales->Get(thread, *availableLength)); + std::string itemStr = JSLocale::ConvertToStdString(item); + icu::Locale localeForLanguageTag = icu::Locale::forLanguageTag(itemStr, *status); + if (U_SUCCESS(*status) != 0) { + builder.addSupportedLocale(localeForLanguageTag); + } else { + break; + } + } + *status = U_ZERO_ERROR; + return builder.build(*status); +} + +// 9.2.4 BestFitMatcher ( availableLocales, requestedLocales ) +JSHandle JSLocale::BestFitMatcher(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales) +{ + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + UErrorCode status = U_ZERO_ERROR; + array_size_t availableLength = availableLocales->GetLength(); + icu::LocaleMatcher matcher = BuildLocaleMatcher(thread, &availableLength, &status, availableLocales); + ASSERT(U_SUCCESS(status)); + + array_size_t requestedLocalesLength = requestedLocales->GetLength(); + JSIntlIterator iter(requestedLocales, requestedLocalesLength); + auto bestFit = matcher.getBestMatch(iter, status)->toLanguageTag(status); + + if (U_FAILURE(status) != 0) { + return DefaultLocale(thread); + } + + for (array_size_t i = 0; i < requestedLocalesLength; ++i) { + if (iter[i] == bestFit) { + return JSHandle(thread, requestedLocales->Get(thread, i)); + } + } + return factory->NewFromStdString(bestFit); +} + +// 9.2.8 LookupSupportedLocales ( availableLocales, requestedLocales ) +JSHandle JSLocale::LookupSupportedLocales(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales) +{ + uint32_t index = 0; + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + array_size_t length = requestedLocales->GetLength(); + // 1. Let subset be a new empty List. + JSHandle subset = factory->NewTaggedArray(length); + JSMutableHandle item(thread, JSTaggedValue::Undefined()); + // 2. For each element locale of requestedLocales in List order, do + // a. Let noExtensionsLocale be the String value that is locale with all Unicode locale extension sequences + // removed. + // b. Let availableLocale be BestAvailableLocale(availableLocales, noExtensionsLocale). + // c. If availableLocale is not undefined, append locale to the end of subset. + for (array_size_t i = 0; i < length; ++i) { + item.Update(requestedLocales->Get(thread, i)); + ParsedLocale foundationResult = HandleLocale(item); + std::string availableLocale = BestAvailableLocale(thread, availableLocales, foundationResult.base); + if (!availableLocale.empty()) { + subset->Set(thread, index++, item.GetTaggedValue()); + } + } + // 3. Return subset. + return TaggedArray::SetCapacity(thread, subset, index); +} + +// 9.2.9 BestFitSupportedLocales ( availableLocales, requestedLocales ) +JSHandle JSLocale::BestFitSupportedLocales(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales) +{ + UErrorCode status = U_ZERO_ERROR; + array_size_t requestLength = requestedLocales->GetLength(); + array_size_t availableLength = availableLocales->GetLength(); + icu::LocaleMatcher matcher = BuildLocaleMatcher(thread, &availableLength, &status, availableLocales); + ASSERT(U_SUCCESS(status)); + + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle defaultLocale = DefaultLocale(thread); + JSHandle result = factory->NewTaggedArray(requestLength); + + uint32_t index = 0; + JSMutableHandle locale(thread, JSTaggedValue::Undefined()); + for (array_size_t i = 0; i < requestLength; ++i) { + locale.Update(requestedLocales->Get(thread, i)); + if (EcmaString::StringsAreEqual(*locale, *defaultLocale)) { + result->Set(thread, index++, locale.GetTaggedValue()); + } else { + status = U_ZERO_ERROR; + std::string localeStr = ConvertToStdString(locale); + icu::Locale desired = icu::Locale::forLanguageTag(localeStr, status); + auto bestFit = matcher.getBestMatch(desired, status)->toLanguageTag(status); + if ((U_SUCCESS(status) != 0) && + EcmaString::StringsAreEqual(*locale, *(factory->NewFromStdString(bestFit)))) { + result->Set(thread, index++, locale.GetTaggedValue()); + } + } + } + result = TaggedArray::SetCapacity(thread, result, index); + return result; +} + +JSHandle JSLocale::ToLanguageTag(JSThread *thread, const icu::Locale &locale) +{ + UErrorCode status = U_ZERO_ERROR; + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + auto result = locale.toLanguageTag(status); + bool flag = (U_FAILURE(status) == 0) ? true : false; + if (!flag) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid locale", factory->GetEmptyString()); + } + size_t findBeginning = result.find("-u-"); + std::string finalRes; + std::string tempRes; + if (findBeginning == std::string::npos) { + return factory->NewFromStdString(result); + } + size_t specialBeginning = findBeginning + INTL_INDEX_THREE; + size_t specialCount = 0; + while (result[specialBeginning] != '-') { + specialCount++; + specialBeginning++; + } + if (findBeginning != std::string::npos) { + // It begin with "-u-xx" or with more elements. + tempRes = result.substr(0, findBeginning + INTL_INDEX_THREE + specialCount); + if (result.size() <= findBeginning + INTL_INDEX_THREE + specialCount) { + return factory->NewFromStdString(result); + } + std::string leftStr = result.substr(findBeginning + INTL_INDEX_THREE + specialCount + INTL_INDEX_ONE); + std::istringstream temp(leftStr); + std::string buffer; + std::vector resContainer; + while (getline(temp, buffer, '-')) { + if (buffer != "true" && buffer != "yes") { + resContainer.push_back(buffer); + } + } + for (auto it = resContainer.begin(); it != resContainer.end(); it++) { + std::string tag = "-"; + tag += *it; + finalRes += tag; + } + } + if (!finalRes.empty()) { + tempRes += finalRes; + } + result = tempRes; + return factory->NewFromStdString(result); +} + +// 9.2.10 SupportedLocales ( availableLocales, requestedLocales, options ) +JSHandle JSLocale::SupportedLocales(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales, + const JSHandle &options) +{ + const GlobalEnvConstants *globalConst = thread->GlobalConstants(); + // 1. If options is not undefined, then + // a. Let options be ? ToObject(options). + // b. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + // 2. Else, let matcher be "best fit". + LocaleMatcherOption matcher = LocaleMatcherOption::BEST_FIT; + if (!options->IsUndefined()) { + JSHandle obj = JSTaggedValue::ToObject(thread, options); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSArray, thread); + + matcher = GetOptionOfString(thread, obj, globalConst->GetHandledLocaleMatcherString(), + {LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT}, + {"lookup", "best fit"}, LocaleMatcherOption::BEST_FIT); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSArray, thread); + } + + // 3. If matcher is "best fit", then + // a. Let supportedLocales be BestFitSupportedLocales(availableLocales, requestedLocales). + // 4. Else, + // a. Let supportedLocales be LookupSupportedLocales(availableLocales, requestedLocales). + JSMutableHandle supportedLocales(thread, JSTaggedValue::Undefined()); + bool isBestfitSupport = false; + if (matcher == LocaleMatcherOption::BEST_FIT && isBestfitSupport) { + supportedLocales.Update(BestFitSupportedLocales(thread, availableLocales, requestedLocales).GetTaggedValue()); + } else { + supportedLocales.Update(LookupSupportedLocales(thread, availableLocales, requestedLocales).GetTaggedValue()); + } + + JSHandle subset = JSArray::CreateArrayFromList(thread, supportedLocales); + // 5. Return CreateArrayFromList(supportedLocales). + return subset; +} + +// 9.2.11 GetOption ( options, property, type, values, fallback ) +JSHandle JSLocale::GetOption(JSThread *thread, const JSHandle &options, + const JSHandle &property, OptionType type, + const JSHandle &values, + const JSHandle &fallback) +{ + // 1. Let value be ? Get(options, property). + JSHandle value = JSObject::GetProperty(thread, options, property).GetValue(); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread); + + // 2. If value is not undefined, then + if (!value->IsUndefined()) { + // a. Assert: type is "boolean" or "string". + ASSERT_PRINT(type == OptionType::BOOLEAN || type == OptionType::STRING, "type is not boolean or string"); + + // b. If type is "boolean", then + // i. Let value be ToBoolean(value). + if (type == OptionType::BOOLEAN) { + value = JSHandle(thread, JSTaggedValue(value->ToBoolean())); + } + // c. If type is "string", then + // i. Let value be ? ToString(value). + if (type == OptionType::STRING) { + JSHandle str = JSTaggedValue::ToString(thread, value); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread); + value = JSHandle(thread, str.GetTaggedValue()); + } + + // d. If values is not undefined, then + // i. If values does not contain an element equal to value, throw a RangeError exception. + if (!values->IsUndefined()) { + bool isExist = false; + JSHandle valuesArray = JSHandle::Cast(values); + uint32_t length = valuesArray->GetLength(); + for (uint32_t i = 0; i < length; i++) { + if (JSTaggedValue::SameValue(valuesArray->Get(thread, i), value.GetTaggedValue())) { + isExist = true; + } + } + if (!isExist) { + JSHandle exception(thread, JSTaggedValue::Exception()); + THROW_RANGE_ERROR_AND_RETURN(thread, "values does not contain an element equal to value", exception); + } + } + // e. Return value. + return value; + } + // 3. Else, return fallback. + return fallback; +} + +bool JSLocale::GetOptionOfString(JSThread *thread, const JSHandle &options, + const JSHandle &property, const std::vector &values, + std::string *optionValue) +{ + // 1. Let value be ? Get(options, property). + OperationResult operationResult = JSObject::GetProperty(thread, options, property); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + JSHandle value = operationResult.GetValue(); + // 2. If value is not undefined, then + if (value->IsUndefined()) { + return false; + } + // c. If type is "string" "string", then + // i. Let value be ? ToString(value). + JSHandle valueEStr = JSTaggedValue::ToString(thread, value); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + if (valueEStr->IsUtf16()) { + THROW_RANGE_ERROR_AND_RETURN(thread, "Value out of range for locale options property", false); + } + *optionValue = JSLocale::ConvertToStdString(valueEStr); + if (values.empty()) { + return true; + } + // d. If values is not undefined, then + // i. If values does not contain an element equal to value, throw a RangeError exception. + for (const auto &item : values) { + if (item == *optionValue) { + return true; + } + } + THROW_RANGE_ERROR_AND_RETURN(thread, "Value out of range for locale options property", false); +} + +// 9.2.12 DefaultNumberOption ( value, minimum, maximum, fallback ) +int JSLocale::DefaultNumberOption(JSThread *thread, const JSHandle &value, int minimum, int maximum, + int fallback) +{ + // 1. If value is not undefined, then + if (!value->IsUndefined()) { + // a. Let value be ? ToNumber(value). + JSTaggedNumber number = JSTaggedValue::ToNumber(thread, value); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fallback); + // b. If value is NaN or less than minimum or greater than maximum, throw a RangeError exception. + double num = JSTaggedValue(number).GetNumber(); + if (std::isnan(num) || num < minimum || num > maximum) { + THROW_RANGE_ERROR_AND_RETURN(thread, "", fallback); + } + // c. Return floor(value). + return std::floor(num); + } + // 2. Else, return fallback. + return fallback; +} + +// 9.2.13 GetNumberOption ( options, property, minimum, maximum, fallback ) +int JSLocale::GetNumberOption(JSThread *thread, const JSHandle &options, + const JSHandle &property, int min, int max, int fallback) +{ + // 1. Let value be ? Get(options, property). + JSHandle value = JSObject::GetProperty(thread, options, property).GetValue(); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fallback); + + // 2. Return ? DefaultNumberOption(value, minimum, maximum, fallback). + int result = DefaultNumberOption(thread, value, min, max, fallback); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fallback); + return result; +} + +// 9.2.5 UnicodeExtensionValue ( extension, key ) +std::string JSLocale::UnicodeExtensionValue(const std::string extension, const std::string key) +{ + // 1. Assert: The number of elements in key is 2. + // 2. Let size be the number of elements in extension. + ASSERT(key.size() == INTL_INDEX_TWO); + size_t size = extension.size(); + // 3. Let searchValue be the concatenation of "-" , key, and "-". + std::string searchValue = "-" + key + "-"; + // 4. Let pos be Call(%StringProto_indexOf%, extension, « searchValue »). + size_t pos = extension.find(searchValue); + // 5. If pos ≠ -1, then + if (pos != std::string::npos) { + // a. Let start be pos + 4. + size_t start = pos + INTL_INDEX_FOUR; + // b. Let end be start. + size_t end = start; + // c. Let k be start. + size_t k = start; + // d. Let done be false. + bool done = false; + // e. Repeat, while done is false + while (!done) { + // i. Let e be Call(%StringProto_indexOf%, extension, « "-", k »). + size_t e = extension.find("-", k); + size_t len; + // ii. If e = -1, let len be size - k; else let len be e - k. + if (e == std::string::npos) { + len = size - k; + } else { + len = e - k; + } + // iii. If len = 2, then + // 1. Let done be true. + if (len == INTL_INDEX_TWO) { + done = true; + // iv. Else if e = -1, then + // 1. Let end be size. + // 2. Let done be true. + } else if (e == std::string::npos) { + end = size; + done = true; + // v. Else, + // 1. Let end be e. + // 2. Let k be e + 1. + } else { + end = e; + k = e + INTL_INDEX_ONE; + } + } + // f. Return the String value equal to the substring of extension consisting of the code units at indices. + // start (inclusive) through end (exclusive). + std::string result = extension.substr(start, end - start); + return result; + } + // 6. Let searchValue be the concatenation of "-" and key. + searchValue = "-" + key; + // 7. Let pos be Call(%StringProto_indexOf%, extension, « searchValue »). + pos = extension.find(searchValue); + // 8. If pos ≠ -1 and pos + 3 = size, then + // a. Return the empty String. + if (pos != std::string::npos && pos + INTL_INDEX_THREE == size) { + return ""; + } + // 9. Return undefined. + return "undefined"; +} + +ResolvedLocale JSLocale::ResolveLocale(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales, LocaleMatcherOption matcher, + const std::set &relevantExtensionKeys) +{ + bool isBestfitSupport = false; + std::map> localeMap = { + {"hc", {"h11", "h12", "h23", "h24"}}, + {"lb", {"strict", "normal", "loose"}}, + {"kn", {"true", "false"}}, + {"kf", {"upper", "lower", "false"}} + }; + + // 1. Let matcher be options.[[localeMatcher]]. + // 2. If matcher is "lookup" "lookup", then + // a. Let r be LookupMatcher(availableLocales, requestedLocales). + // 3. Else, + // a. Let r be BestFitMatcher(availableLocales, requestedLocales). + JSMutableHandle locale(thread, JSTaggedValue::Undefined()); + if (availableLocales->GetLength() == 0 && requestedLocales->GetLength() == 0) { + locale.Update(DefaultLocale(thread).GetTaggedValue()); + } else { + if (matcher == LocaleMatcherOption::BEST_FIT && isBestfitSupport) { + locale.Update(BestFitMatcher(thread, availableLocales, requestedLocales).GetTaggedValue()); + } else { + locale.Update(LookupMatcher(thread, availableLocales, requestedLocales).GetTaggedValue()); + } + } + + // 4. Let foundLocale be r.[[locale]]. + // 5. Let result be a new Record. + // 6. Set result.[[dataLocale]] to foundLocale. + // 7. Let supportedExtension be "-u". + std::string foundLocale = ConvertToStdString(locale); + icu::Locale foundLocaleData = BuildICULocale(foundLocale); + ResolvedLocale result; + result.localeData = foundLocaleData; + JSHandle tag = ToLanguageTag(thread, foundLocaleData); + result.locale = ConvertToStdString(tag); + std::string supportedExtension = "-u"; + icu::LocaleBuilder localeBuilder; + localeBuilder.setLocale(foundLocaleData).clearExtensions(); + // 8. For each element key of relevantExtensionKeys in List order, do + for (auto &key : relevantExtensionKeys) { + auto doubleMatch = foundLocale.find(key); + if (doubleMatch == std::string::npos) { + continue; + } + UErrorCode status = U_ZERO_ERROR; + std::set keyLocaleData; + std::unique_ptr wellFormKey(foundLocaleData.createKeywords(status)); + if (U_FAILURE(status) != 0) { + return result; + } + if (!wellFormKey) { + return result; + } + std::string value; + + // c. Let keyLocaleData be foundLocaleData.[[]]. + // e. Let value be keyLocaleData[0]. + if ((key != "ca") && (key != "co") && (key != "nu")) { + keyLocaleData = localeMap[key]; + value = *keyLocaleData.begin(); + } + + // g. Let supportedExtensionAddition be "". + // h. If r has an [[extension]] field, then + std::string supportedExtensionAddition; + size_t found = foundLocale.find("-u-"); + if (found != std::string::npos) { + std::string extension = foundLocale.substr(found + INTL_INDEX_ONE); + + // i. Let requestedValue be UnicodeExtensionValue(r.[[extension]], key). + std::string requestedValue = UnicodeExtensionValue(extension, key); + if (key == "kn" && requestedValue.empty()) { + requestedValue = "true"; + } + + // ii. If requestedValue is not undefined, then + if (requestedValue != "undefined") { + // 1. If requestedValue is not the empty String, then + if (!requestedValue.empty()) { + // a. If keyLocaleData contains requestedValue, then + // i. Let value be requestedValue. + // ii. Let supportedExtensionAddition be the concatenation of "-", key, "-", and value. + if (key == "ca" || key == "co") { + if (key == "co") { + bool isValidValue = IsWellCollation(foundLocaleData, requestedValue); + if (!isValidValue) { + continue; + } + value = requestedValue; + supportedExtensionAddition = "-" + key + "-" + value; + localeBuilder.setUnicodeLocaleKeyword(key, requestedValue); + } else { + bool isValidValue = IsWellCalendar(foundLocaleData, requestedValue); + if (!isValidValue) { + continue; + } + value = requestedValue; + supportedExtensionAddition = "-" + key + "-" + value; + localeBuilder.setUnicodeLocaleKeyword(key, requestedValue); + } + } else if (key == "nu") { + bool isValidValue = IsWellNumberingSystem(requestedValue); + if (!isValidValue) { + continue; + } + value = requestedValue; + supportedExtensionAddition = "-" + key + "-" + value; + localeBuilder.setUnicodeLocaleKeyword(key, requestedValue); + } else if (keyLocaleData.find(requestedValue) != keyLocaleData.end()) { + value = requestedValue; + supportedExtensionAddition = "-" + key + "-" + value; + localeBuilder.setUnicodeLocaleKeyword(key, requestedValue); + } + } + } + } + result.extensions.insert(std::pair(key, value)); + supportedExtension += supportedExtensionAddition; + } + size_t found = foundLocale.find("-u-"); + if (found != std::string::npos) { + foundLocale = foundLocale.substr(0, found); + } + + // 9. If the number of elements in supportedExtension is greater than 2, then + if (supportedExtension.size() > 2) { + // a. Let privateIndex be Call(%StringProto_indexOf%, foundLocale, « "-x-" »). + size_t privateIndex = foundLocale.find("-x-"); + // b. If privateIndex = -1, then + // i. Let foundLocale be the concatenation of foundLocale and supportedExtension. + if (privateIndex == std::string::npos) { + foundLocale = foundLocale + supportedExtension; + } else { + std::string preExtension = foundLocale.substr(0, privateIndex); + std::string postExtension = foundLocale.substr(privateIndex); + foundLocale = preExtension + supportedExtension + postExtension; + } + + tag = ToLanguageTag(thread, foundLocaleData); + if (!IsStructurallyValidLanguageTag(tag)) { + result.extensions.erase(result.extensions.begin(), result.extensions.end()); + result.locale = foundLocale; + } + tag = CanonicalizeUnicodeLocaleId(thread, tag); + foundLocale = ConvertToStdString(tag); + } + + // 10. Set result.[[locale]] to foundLocale. + result.locale = foundLocale; + UErrorCode status = U_ZERO_ERROR; + foundLocaleData = localeBuilder.build(status); + result.localeData = foundLocaleData; + + // 11. Return result. + return result; +} + +icu::Locale JSLocale::BuildICULocale(const std::string &bcp47Locale) +{ + UErrorCode status = U_ZERO_ERROR; + icu::Locale icuLocale = icu::Locale::forLanguageTag(bcp47Locale, status); + ASSERT_PRINT(U_SUCCESS(status), "forLanguageTag failed"); + ASSERT_PRINT(!icuLocale.isBogus(), "icuLocale is bogus"); + return icuLocale; +} + +JSHandle JSLocale::ConstructLocaleList(JSThread *thread, + const std::vector &icuAvailableLocales) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + JSHandle locales = factory->NewTaggedArray(icuAvailableLocales.size()); + int32_t index = 0; + for (const std::string &locale : icuAvailableLocales) { + JSHandle localeStr = factory->NewFromStdString(locale); + locales->Set(thread, index++, localeStr); + } + return locales; +} + +JSHandle JSLocale::IcuToString(JSThread *thread, const icu::UnicodeString &string) +{ + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + return factory->NewFromUtf16(reinterpret_cast(string.getBuffer()), string.length()); +} + +JSHandle JSLocale::IcuToString(JSThread *thread, const icu::UnicodeString &string, int32_t begin, + int32_t end) +{ + return IcuToString(thread, string.tempSubStringBetween(begin, end)); +} + +std::string JSLocale::GetNumberingSystem(const icu::Locale &icuLocale) +{ + UErrorCode status = U_ZERO_ERROR; + std::unique_ptr numberingSystem(icu::NumberingSystem::createInstance(icuLocale, status)); + if (U_SUCCESS(status) != 0) { + return numberingSystem->getName(); + } + return "latn"; +} + +bool JSLocale::IsWellFormedCurrencyCode(const std::string ¤cy) +{ + if (currency.length() != INTL_INDEX_THREE) { + return false; + } + return (IsAToZ(currency[INTL_INDEX_ZERO]) && IsAToZ(currency[INTL_INDEX_ONE]) && IsAToZ(currency[INTL_INDEX_TWO])); +} + +JSHandle JSLocale::PutElement(JSThread *thread, int index, const JSHandle &array, + const JSHandle &fieldTypeString, + const JSHandle &value) +{ + auto ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + // Let record be ! ObjectCreate(%ObjectPrototype%). + JSHandle record = factory->NewEmptyJSObject(); + + auto globalConst = thread->GlobalConstants(); + // obj.type = field_type_string + JSObject::CreateDataPropertyOrThrow(thread, record, globalConst->GetHandledTypeString(), fieldTypeString); + // obj.value = value + JSObject::CreateDataPropertyOrThrow(thread, record, globalConst->GetHandledValueString(), value); + + JSTaggedValue::SetProperty(thread, JSHandle::Cast(array), index, + JSHandle::Cast(record), true); + return record; +} + +// 9.2.11 GetOption ( options, property, type, values, fallback ) +bool JSLocale::GetOptionOfBool(JSThread *thread, const JSHandle &options, + const JSHandle &property, bool fallback, bool *res) +{ + // 1. Let value be ? Get(options, property). + OperationResult operationResult = JSObject::GetProperty(thread, options, property); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + JSHandle value = operationResult.GetValue(); + *res = fallback; + // 2. If value is not undefined, then + if (!value->IsUndefined()) { + // b. Let value be ToBoolean(value). + *res = value->ToBoolean(); + return true; + } + // 3. not found + return false; +} + +JSHandle JSLocale::GetNumberFieldType(JSThread *thread, JSTaggedValue x, int32_t fieldId) +{ + ASSERT(x.IsNumber()); + double number = 0; + auto globalConst = thread->GlobalConstants(); + if (static_cast(fieldId) == UNUM_INTEGER_FIELD) { + number = x.GetNumber(); + if (std::isfinite(number)) { + return globalConst->GetHandledIntegerString(); + } + if (std::isnan(number)) { + return globalConst->GetHandledNanString(); + } + return globalConst->GetHandledInfinityString(); + } else if (static_cast(fieldId) == UNUM_FRACTION_FIELD) { + return globalConst->GetHandledFractionString(); + } else if (static_cast(fieldId) == UNUM_DECIMAL_SEPARATOR_FIELD) { + return globalConst->GetHandledDecimalString(); + } else if (static_cast(fieldId) == UNUM_GROUPING_SEPARATOR_FIELD) { + return globalConst->GetHandledGroupString(); + } else if (static_cast(fieldId) == UNUM_CURRENCY_FIELD) { + return globalConst->GetHandledCurrencyString(); + } else if (static_cast(fieldId) == UNUM_PERCENT_FIELD) { + return globalConst->GetHandledPercentSignString(); + } else if (static_cast(fieldId) == UNUM_SIGN_FIELD) { + number = x.GetNumber(); + return std::signbit(number) ? globalConst->GetHandledMinusSignString() + : globalConst->GetHandledPlusSignString(); + } else if (static_cast(fieldId) == UNUM_EXPONENT_SYMBOL_FIELD) { + return globalConst->GetHandledExponentSeparatorString(); + } else if (static_cast(fieldId) == UNUM_EXPONENT_SIGN_FIELD) { + return globalConst->GetHandledExponentMinusSignString(); + } else if (static_cast(fieldId) == UNUM_EXPONENT_FIELD) { + return globalConst->GetHandledExponentIntegerString(); + } else if (static_cast(fieldId) == UNUM_COMPACT_FIELD) { + return globalConst->GetHandledCompactString(); + } else if (static_cast(fieldId) == UNUM_MEASURE_UNIT_FIELD) { + return globalConst->GetHandledUnitString(); + } else { + UNREACHABLE(); + } +} + +// 10.1.1 ApplyOptionsToTag( tag, options ) +bool JSLocale::ApplyOptionsToTag(JSThread *thread, const JSHandle &tag, const JSHandle &options, + TagElements &tagElements) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + const GlobalEnvConstants *globalConst = thread->GlobalConstants(); + ObjectFactory *factory = ecmaVm->GetFactory(); + if (*tag == *(factory->GetEmptyString())) { + return false; + } + // 2. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception. + if (!IsStructurallyValidLanguageTag(tag)) { + return false; + } + + tagElements.language = + GetOption(thread, options, globalConst->GetHandledLanguageString(), OptionType::STRING, + globalConst->GetHandledUndefined(), globalConst->GetHandledUndefined()); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + + // 4. If language is not undefined, then + // a. If language does not match the unicode_language_subtag production, throw a RangeError exception. + if (!tagElements.language->IsUndefined()) { + std::string languageStr = ConvertToStdString(JSHandle::Cast(tagElements.language)); + if (languageStr[INTL_INDEX_ZERO] == '\0' || + IsAlpha(languageStr, INTL_INDEX_FOUR, INTL_INDEX_FOUR)) { + return false; + } + } + + // 5. Let script be ? GetOption(options, "script", "string", undefined, undefined). + tagElements.script = + GetOption(thread, options, globalConst->GetHandledScriptString(), OptionType::STRING, + globalConst->GetHandledUndefined(), globalConst->GetHandledUndefined()); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + + // 6. If script is not undefined, then + // a. If script does not match the unicode_script_subtag production, throw a RangeError exception. + if (!tagElements.script->IsUndefined()) { + std::string scriptStr = JSLocale::ConvertToStdString((JSHandle::Cast(tagElements.script))); + if (scriptStr[INTL_INDEX_ZERO] == '\0') { + return false; + } + } + + // 7. Let region be ? GetOption(options, "region", "string", undefined, undefined). + // 8. If region is not undefined, then + // a. If region does not match the unicode_region_subtag production, throw a RangeError exception. + tagElements.region = + GetOption(thread, options, globalConst->GetHandledRegionString(), OptionType::STRING, + globalConst->GetHandledUndefined(), globalConst->GetHandledUndefined()); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + + if (!tagElements.region->IsUndefined()) { + std::string regionStr = ConvertToStdString(JSHandle::Cast(tagElements.region)); + if (regionStr[INTL_INDEX_ZERO] == '\0') { + return false; + } + } + return true; +} + +bool BuildOptionsTags(const JSHandle &tag, icu::LocaleBuilder *builder, JSHandle language, + JSHandle script, JSHandle region) +{ + std::string tagStr = JSLocale::ConvertToStdString(tag); + int32_t len = static_cast(tagStr.length()); + ASSERT(len > 0); + builder->setLanguageTag({ tagStr.c_str(), len }); + UErrorCode status = U_ZERO_ERROR; + icu::Locale locale = builder->build(status); + locale.canonicalize(status); + if (U_FAILURE(status) != 0) { + return false; + } + builder->setLocale(locale); + + if (!language->IsUndefined()) { + std::string languageStr = JSLocale::ConvertToStdString(JSHandle::Cast(language)); + builder->setLanguage(languageStr); + builder->build(status); + if ((U_FAILURE(status) != 0)) { + return false; + } + } + + if (!script->IsUndefined()) { + std::string scriptStr = JSLocale::ConvertToStdString((JSHandle::Cast(script))); + builder->setScript(scriptStr); + builder->build(status); + if ((U_FAILURE(status) != 0)) { + return false; + } + } + + if (!region->IsUndefined()) { + std::string regionStr = JSLocale::ConvertToStdString(JSHandle::Cast(region)); + builder->setRegion(regionStr); + builder->build(status); + if ((U_FAILURE(status) != 0)) { + return false; + } + } + return true; +} + +bool InsertOptions(JSThread *thread, const JSHandle &options, icu::LocaleBuilder *builder) +{ + const std::vector hourCycleValues = {"h11", "h12", "h23", "h24"}; + const std::vector caseFirstValues = {"upper", "lower", "false"}; + const std::vector emptyValues = {}; + const GlobalEnvConstants *globalConst = thread->GlobalConstants(); + std::string strResult; + bool findca = + JSLocale::GetOptionOfString(thread, options, globalConst->GetHandledCalendarString(), emptyValues, &strResult); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + if (findca) { + if (!uloc_toLegacyType(uloc_toLegacyKey("ca"), strResult.c_str())) { + return false; + } + builder->setUnicodeLocaleKeyword("ca", strResult.c_str()); + } + + bool findco = + JSLocale::GetOptionOfString(thread, options, globalConst->GetHandledCollationString(), emptyValues, &strResult); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + if (findco) { + if (!uloc_toLegacyType(uloc_toLegacyKey("co"), strResult.c_str())) { + return false; + } + builder->setUnicodeLocaleKeyword("co", strResult.c_str()); + } + + bool findhc = JSLocale::GetOptionOfString(thread, options, globalConst->GetHandledHourCycleString(), + hourCycleValues, &strResult); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + if (findhc) { + if (!uloc_toLegacyType(uloc_toLegacyKey("hc"), strResult.c_str())) { + return false; + } + builder->setUnicodeLocaleKeyword("hc", strResult.c_str()); + } + + bool findkf = JSLocale::GetOptionOfString(thread, options, globalConst->GetHandledCaseFirstString(), + caseFirstValues, &strResult); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + if (findkf) { + if (!uloc_toLegacyType(uloc_toLegacyKey("kf"), strResult.c_str())) { + return false; + } + builder->setUnicodeLocaleKeyword("kf", strResult.c_str()); + } + + bool boolResult = false; + bool findkn = + JSLocale::GetOptionOfBool(thread, options, globalConst->GetHandledNumericString(), false, &boolResult); + if (findkn) { + strResult = boolResult ? "true" : "false"; + if (!uloc_toLegacyType(uloc_toLegacyKey("kn"), strResult.c_str())) { + return false; + } + builder->setUnicodeLocaleKeyword("kn", strResult.c_str()); + } + + bool findnu = + JSLocale::GetOptionOfString(thread, options, globalConst->GetHandledNumberingSystemString(), emptyValues, + &strResult); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + if (findnu) { + if (!uloc_toLegacyType(uloc_toLegacyKey("nu"), strResult.c_str())) { + return false; + } + builder->setUnicodeLocaleKeyword("nu", strResult.c_str()); + } + return true; +} + +JSHandle JSLocale::InitializeLocale(JSThread *thread, const JSHandle &locale, + const JSHandle &localeString, + const JSHandle &options) +{ + icu::LocaleBuilder builder; + TagElements tagElements; + if (!ApplyOptionsToTag(thread, localeString, options, tagElements)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "apply option to tag failed", locale); + } + + bool res = BuildOptionsTags(localeString, &builder, tagElements.language, tagElements.script, tagElements.region); + if (!res) { + THROW_RANGE_ERROR_AND_RETURN(thread, "apply option to tag failed", locale); + } + bool insertResult = InsertOptions(thread, options, &builder); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, locale); + UErrorCode status = U_ZERO_ERROR; + icu::Locale icuLocale = builder.build(status); + icuLocale.canonicalize(status); + + if (!insertResult || (U_FAILURE(status) != 0)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "insert or build failed", locale); + } + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + factory->NewJSIntlIcuData(locale, icuLocale, JSLocale::FreeIcuLocale); + return locale; +} + +bool JSLocale::DealwithLanguageTag(const std::vector &containers, size_t &address) +{ + // The abstract operation returns true if locale can be generated from the ABNF grammar in section 2.1 of the RFC, + // starting with Language-Tag, and does not contain duplicate variant or singleton subtags + // If language tag is empty, return false. + if (containers.empty()) { + return false; + } + + // a. if the first tag is not language, return false. + if (!IsLanguageSubtag(containers[0])) { + return false; + } + + // if the tag include language only, like "zh" or "de", return true; + if (containers.size() == 1) { + return true; + } + + // Else, then + // if is unique singleton subtag, script and region tag. + if (IsExtensionSingleton(containers[1])) { + return true; + } + + if (IsScriptSubtag(containers[address])) { + address++; + if (containers.size() == address) { + return true; + } + } + + if (IsRegionSubtag(containers[address])) { + address++; + } + + for (size_t i = address; i < containers.size(); i++) { + if (IsExtensionSingleton(containers[i])) { + return true; + } + if (!IsVariantSubtag(containers[i])) { + return false; + } + } + return true; +} + +int ConvertValue(const UErrorCode &status, std::string &value, const std::string &key) +{ + if (status == U_ILLEGAL_ARGUMENT_ERROR || value.empty()) { + return 1; + } + + if (value == "yes") { + value = "true"; + } + + if (key == "kf" && value == "true") { + return 2; + } + return 0; +} + +JSHandle JSLocale::NormalizeKeywordValue(JSThread *thread, const JSHandle &locale, + const std::string &key) +{ + icu::Locale *icuLocale = locale->GetIcuLocale(); + UErrorCode status = U_ZERO_ERROR; + auto value = icuLocale->getUnicodeKeywordValue(key, status); + + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + int result = ConvertValue(status, value, key); + if (result == 1) { + return JSHandle::Cast(thread->GlobalConstants()->GetHandledUndefinedString()); + } + if (result == 2) { + return factory->GetEmptyString(); + } + return factory->NewFromStdString(value); +} + +JSHandle JSLocale::ToString(JSThread *thread, const JSHandle &locale) +{ + icu::Locale *icuLocale = locale->GetIcuLocale(); + if (icuLocale == nullptr) { + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + return factory->GetEmptyString(); + } + JSHandle result = ToLanguageTag(thread, *icuLocale); + return result; +} + +JSHandle JSLocale::GetAvailableLocales(JSThread *thread, const char *localeKey, const char *localePath) +{ + UErrorCode status = U_ZERO_ERROR; + auto globalConst = thread->GlobalConstants(); + JSHandle specialValue = JSHandle::Cast(globalConst->GetHandledEnUsPosixString()); + std::string specialString = ConvertToStdString(specialValue); + UEnumeration *uenum = uloc_openAvailableByType(ULOC_AVAILABLE_WITH_LEGACY_ALIASES, &status); + std::vector allLocales; + const char *loc = nullptr; + for (loc = uenum_next(uenum, nullptr, &status); loc != nullptr; loc = uenum_next(uenum, nullptr, &status)) { + ASSERT(U_SUCCESS(status)); + std::string locStr(loc); + std::replace(locStr.begin(), locStr.end(), '_', '-'); + if (locStr == specialString) { + locStr = "en-US-u-va-posix"; + } + + if (localePath != nullptr || localeKey != nullptr) { + icu::Locale loc(locStr.c_str()); + bool res = false; + if (!CheckLocales(loc, localeKey, localePath, res)) { + continue; + } + } + bool isScript = false; + allLocales.push_back(locStr); + icu::Locale formalLocale = icu::Locale::createCanonical(locStr.c_str()); + std::string scriptStr = formalLocale.getScript(); + isScript = scriptStr.empty() ? false : true; + if (isScript) { + std::string languageStr = formalLocale.getLanguage(); + std::string countryStr = formalLocale.getCountry(); + std::string shortLocale = icu::Locale(languageStr.c_str(), countryStr.c_str()).getName(); + std::replace(shortLocale.begin(), shortLocale.end(), '_', '-'); + allLocales.push_back(shortLocale); + } + } + uenum_close(uenum); + return ConstructLocaleList(thread, allLocales); +} +} // namespace panda::ecmascript \ No newline at end of file diff --git a/ecmascript/js_locale.h b/ecmascript/js_locale.h new file mode 100644 index 0000000000000000000000000000000000000000..e553afef86fe6b1543abc97ad6e6c941bbde3a0e --- /dev/null +++ b/ecmascript/js_locale.h @@ -0,0 +1,699 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_JSLOCALE_H +#define ECMASCRIPT_JSLOCALE_H + +#include "ecmascript/ecma_macros.h" +#include "ecmascript/js_array.h" +#include "ecmascript/js_object.h" +#include "ecmascript/mem/c_containers.h" +#include "ohos/init_data.h" +#include "unicode/basictz.h" +#include "unicode/brkiter.h" +#include "unicode/calendar.h" +#include "unicode/coll.h" +#include "unicode/datefmt.h" +#include "unicode/decimfmt.h" +#include "unicode/dtitvfmt.h" +#include "unicode/dtptngen.h" +#include "unicode/fieldpos.h" +#include "unicode/formattedvalue.h" +#include "unicode/gregocal.h" +#include "unicode/locid.h" +#include "unicode/normalizer2.h" +#include "unicode/numberformatter.h" +#include "unicode/numfmt.h" +#include "unicode/numsys.h" +#include "unicode/smpdtfmt.h" +#include "unicode/timezone.h" +#include "unicode/udat.h" +#include "unicode/unistr.h" +#include "unicode/ures.h" +#include "unicode/ustring.h" +#include "unicode/uvernum.h" +#include "unicode/uversion.h" + +namespace panda::ecmascript { +enum class OptionType : uint8_t { STRING = 0x01, BOOLEAN }; +enum class LocaleMatcherOption : uint8_t { LOOKUP = 0x01, BEST_FIT, EXCEPTION }; +enum class FormatMatcherOption : uint8_t { BASIC = 0x01, BEST_FIT, EXCEPTION }; +enum class LocaleType : uint8_t { + LITERAL = 0x01, + NUMBER, + PLUS_SIGN, + MINUS_SIGN, + PERCENT_SIGN, + UNIT_PREFIX, + UNIT_SUFFIX, + CURRENCY_CODE, + CURRENCY_PREFIX, + CURRENCY_SUFFIX, +}; +enum class RoundingType : uint8_t { FRACTIONDIGITS = 0x01, SIGNIFICANTDIGITS, COMPACTROUNDING, EXCEPTION }; +enum class NotationOption : uint8_t { STANDARD = 0x01, SCIENTIFIC, ENGINEERING, COMPACT, EXCEPTION }; + +constexpr uint32_t MAX_DIGITS = 21; +constexpr uint32_t MAX_FRACTION_DIGITS = 20; +constexpr uint8_t INTL_INDEX_ZERO = 0; +constexpr uint8_t INTL_INDEX_ONE = 1; +constexpr uint8_t INTL_INDEX_TWO = 2; +constexpr uint8_t INTL_INDEX_THREE = 3; +constexpr uint8_t INTL_INDEX_FOUR = 4; +constexpr uint8_t INTL_INDEX_FIVE = 5; +constexpr uint8_t INTL_INDEX_EIGHT = 8; + +class JSIntlIterator : public icu::Locale::Iterator { +public: + JSIntlIterator(const JSHandle &data, array_size_t length) : length_(length), curIdx_(0) + { + for (array_size_t idx = 0; idx < length; idx++) { + std::string str = base::StringHelper::ToStdString(EcmaString::Cast(data->Get(idx).GetTaggedObject())); + data_.emplace_back(str); + } + } + + ~JSIntlIterator() override = default; + DEFAULT_COPY_SEMANTIC(JSIntlIterator); + DEFAULT_MOVE_SEMANTIC(JSIntlIterator); + + UBool hasNext() const override + { + return static_cast(curIdx_ < length_); + } + + const icu::Locale &next() override + { + ASSERT(curIdx_ < length_); + UErrorCode status = U_ZERO_ERROR; + locale_ = icu::Locale::forLanguageTag(data_[curIdx_].c_str(), status); + ASSERT(U_SUCCESS(status)); + curIdx_++; + return locale_; + } + + inline const std::string &operator[](size_t index) const noexcept + { + ASSERT(index < length_); + return data_[index]; + } + +private: + std::vector data_{}; + array_size_t length_{0}; + array_size_t curIdx_{0}; + icu::Locale locale_{}; +}; + +struct ResolvedLocale { + std::string locale; + icu::Locale localeData; + std::map extensions; +}; + +struct MatcherResult { + std::string locale; + std::string extension; +}; + +struct OptionData { + std::string name; + std::string key; + std::vector possibleValues; + bool isBoolValue = false; +}; + +struct TagElements { + JSHandle language; + JSHandle script; + JSHandle region; +}; + +class JSLocale : public JSObject { +public: + struct ParsedLocale { + std::string base; + std::string extension; + }; + + static JSLocale *Cast(ObjectHeader *object) + { + ASSERT(JSTaggedValue(object).IsJSLocale()); + return static_cast(object); + } + + static constexpr size_t ICU_FIELD_OFFSET = JSObject::SIZE; + // icu::Locale internal slot. + ACCESSORS(IcuField, ICU_FIELD_OFFSET, SIZE) + + DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, ICU_FIELD_OFFSET, SIZE) + + icu::Locale *GetIcuLocale() const + { + ASSERT(GetIcuField().IsJSNativePointer()); + auto result = JSNativePointer::Cast(GetIcuField().GetTaggedObject())->GetExternalPointer(); + return reinterpret_cast(result); + } + + static void FreeIcuLocale(void *pointer, void *data) + { + if (pointer == nullptr) { + return; + } + auto icuLocale = reinterpret_cast(pointer); + icuLocale->~Locale(); + if (data != nullptr) { + reinterpret_cast(data)->GetRegionFactory()->FreeBuffer(pointer); + } + } + + static std::string ConvertToStdString(const JSHandle &ecmaStr); + + // 6.2.2 IsStructurallyValidLanguageTag ( locale ) + static bool IsStructurallyValidLanguageTag(const JSHandle &tag); + + static bool DealwithLanguageTag(const std::vector &containers, size_t &address); + + // 6.2.3 CanonicalizeUnicodeLocaleId ( locale ) + static JSHandle CanonicalizeUnicodeLocaleId(JSThread *thread, const JSHandle &locale); + + // 6.2.4 DefaultLocale () + static JSHandle DefaultLocale(JSThread *thread); + + // 6.4.1 IsValidTimeZoneName ( timeZone ) + static bool IsValidTimeZoneName(const icu::TimeZone &tz); + + // 9.2.1 CanonicalizeLocaleList ( locales ) + static JSHandle CanonicalizeLocaleList(JSThread *thread, const JSHandle &locales); + + template + static JSHandle CanonicalizeHelper(JSThread *thread, const JSHandle &locales, + JSHandle &obj, JSHandle &seen); + + // 9.2.2 BestAvailableLocale ( availableLocales, locale ) + static std::string BestAvailableLocale(JSThread *thread, const JSHandle &availableLocales, + const std::string &locale); + + // 9.2.3 LookupMatcher ( availableLocales, requestedLocales ) + static JSHandle LookupMatcher(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales); + + // 9.2.4 BestFitMatcher ( availableLocales, requestedLocales ) + static JSHandle BestFitMatcher(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales); + + // 9.2.5 UnicodeExtensionValue ( extension, key ) + static std::string UnicodeExtensionValue(const std::string extension, const std::string key); + + // 9.2.7 ResolveLocale ( availableLocales, requestedLocales, options, relevantExtensionKeys, localeData ) + static ResolvedLocale ResolveLocale(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales, LocaleMatcherOption matcher, + const std::set &relevantExtensionKeys); + + // 9.2.8 LookupSupportedLocales ( availableLocales, requestedLocales ) + static JSHandle LookupSupportedLocales(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales); + + // 9.2.9 BestFitSupportedLocales ( availableLocales, requestedLocales ) + static JSHandle BestFitSupportedLocales(JSThread *thread, + const JSHandle &availableLocales, + const JSHandle &requestedLocales); + + // 9.2.10 SupportedLocales ( availableLocales, requestedLocales, options ) + static JSHandle SupportedLocales(JSThread *thread, const JSHandle &availableLocales, + const JSHandle &requestedLocales, + const JSHandle &options); + + // 9.2.11 GetOption ( options, property, type, values, fallback ) + template + static T GetOptionOfString(JSThread *thread, const JSHandle &options, + const JSHandle &property, const std::vector &enumValues, + const std::vector &strValues, T fallback) + { + // 1. Let value be ? Get(options, property). + OperationResult operationResult = JSObject::GetProperty(thread, options, property); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, T::EXCEPTION); + JSHandle value = operationResult.GetValue(); + + if (value->IsUndefined()) { + return fallback; + } + + // 2. If value is not undefined, then + // d. If values is not undefined, then + // i. If values does not contain an element equal to value, throw a RangeError exception. + JSHandle valueEStr = JSTaggedValue::ToString(thread, value); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, T::EXCEPTION); + std::string valueStr = ConvertToStdString(valueEStr); + int existIdx = -1; + if (!enumValues.empty()) { + int strValuesSize = strValues.size(); + for (int i = 0; i < strValuesSize; i++) { + if (strValues[i] == valueStr) { + existIdx = i; + } + } + if (existIdx == -1) { + THROW_RANGE_ERROR_AND_RETURN(thread, "getStringOption failed", T::EXCEPTION); + } + } + if (existIdx == -1) { + UNREACHABLE(); + } + // e.Return value. + return enumValues[existIdx]; + } + + static bool GetOptionOfBool(JSThread *thread, const JSHandle &options, + const JSHandle &property, bool fallback, bool *res); + + static JSHandle GetOption(JSThread *thread, const JSHandle &options, + const JSHandle &property, OptionType type, + const JSHandle &values, + const JSHandle &fallback); + + static bool GetOptionOfString(JSThread *thread, const JSHandle &options, + const JSHandle &property, const std::vector &values, + std::string *optionValue); + + // 9.2.12 DefaultNumberOption ( value, minimum, maximum, fallback ) + static int DefaultNumberOption(JSThread *thread, const JSHandle &value, int minimum, int maximum, + int fallback); + + // 9.2.13 GetNumberOption ( options, property, minimum, maximum, fallback ) + static int GetNumberOption(JSThread *thread, const JSHandle &options, + const JSHandle &property, int minimum, int maximum, int fallback); + + static bool IsLanguageSubtag(const std::string &value) + { + return IsAlpha(value, INTL_INDEX_TWO, INTL_INDEX_THREE) || IsAlpha(value, INTL_INDEX_FIVE, INTL_INDEX_EIGHT); + } + + static bool IsScriptSubtag(const std::string &value) + { + return IsAlpha(value, INTL_INDEX_FOUR, INTL_INDEX_FOUR); + } + + static bool IsRegionSubtag(const std::string &value) + { + return IsAlpha(value, INTL_INDEX_TWO, INTL_INDEX_TWO) || IsDigit(value, INTL_INDEX_THREE, INTL_INDEX_THREE); + } + + static bool IsVariantSubtag(const std::string &value) + { + return IsThirdDigitAlphanum(value) || IsAlphanum(value, INTL_INDEX_FIVE, INTL_INDEX_EIGHT); + } + + static bool IsThirdDigitAlphanum(const std::string &value) + { + return InRange(value[0], '0', '9') && value.length() == 4 && + IsAlphanum(value.substr(INTL_INDEX_ONE), INTL_INDEX_THREE, INTL_INDEX_THREE); + } + + static bool IsExtensionSingleton(const std::string &value) + { + return IsAlphanum(value, INTL_INDEX_ONE, INTL_INDEX_ONE); + } + + static bool IsNormativeCalendar(const std::string &value) + { + return IsWellAlphaNumList(value); + } + + static bool IsNormativeNumberingSystem(const std::string &value) + { + return IsWellAlphaNumList(value); + } + + static bool IsWellNumberingSystem(const std::string &value) + { + std::set irregularList = {"native", "traditio", "finance"}; + if (irregularList.find(value) != irregularList.end()) { + return false; + } + UErrorCode status = U_ZERO_ERROR; + icu::NumberingSystem *numberingSystem = icu::NumberingSystem::createInstanceByName(value.c_str(), status); + bool result = U_SUCCESS(status) != 0 && numberingSystem != nullptr; + delete numberingSystem; + numberingSystem = NULL; + return result; + } + + static bool IsWellCollation(const icu::Locale &locale, const std::string &value) + { + std::set irregularList = {"standard", "search"}; + if (irregularList.find(value) != irregularList.end()) { + return false; + } + return IsWellExtension(locale, "collation", value); + } + + static bool IsWellCalendar(const icu::Locale &locale, const std::string &value) + { + return IsWellExtension(locale, "calendar", value); + } + + template + static bool IsWellExtension(const icu::Locale &locale, const char *key, const std::string &value) + { + UErrorCode status = U_ZERO_ERROR; + const char *outdatedType = uloc_toLegacyType(key, value.c_str()); + if (outdatedType == nullptr) { + return false; + } + icu::StringEnumeration *sequence = T::getKeywordValuesForLocale(key, icu::Locale(locale.getBaseName()), + false, status); + if (U_FAILURE(status)) { + delete sequence; + sequence = NULL; + return false; + } + int32_t size; + const char *element = sequence->next(&size, status); + while (U_SUCCESS(status) && element != nullptr) { + if (strcmp(outdatedType, element) == 0) { + delete sequence; + sequence = NULL; + return true; + } + element = sequence->next(&size, status); + } + delete sequence; + sequence = NULL; + return false; + } + + static inline constexpr int AsciiAlphaToLower(uint32_t c) + { + constexpr uint32_t FLAG = 0x20; + return static_cast(c | FLAG); + } + + static bool IsAsciiAlpha(char ch) + { + return InRange(ch, 'A', 'Z') || InRange(ch, 'a', 'z'); + } + + static char LocaleIndependentAsciiToUpper(char ch) + { + return (InRange(ch, 'a', 'z')) ? static_cast((ch - 'a' + 'A')) : ch; + } + + static char LocaleIndependentAsciiToLower(char ch) + { + return (InRange(ch, 'A', 'Z')) ? static_cast((ch - 'A' + 'a')) : ch; + } + + template + static bool InRange(T value, U start, U end) + { + ASSERT(start <= end); + ASSERT(sizeof(T) >= sizeof(U)); + return (value >= static_cast(start)) && (value <= static_cast(end)); + } + + static bool IsWellAlphaNumList(const std::string &value) + { + if (value.length() < 3) { + return false; + } + char lastChar = value[value.length() - 1]; + if (lastChar == '-') { + return false; + } + std::vector items; + std::istringstream input(value); + std::string temp; + while (getline(input, temp, '-')) { + items.push_back(temp); + } + for (auto &item : items) { + if (!IsAlphanum(item, INTL_INDEX_THREE, INTL_INDEX_EIGHT)) { + return false; + } + } + return true; + } + + static bool ValidateOtherTags(const icu::Locale &locale, const char *packageName, const char *key, bool &res) + { + const char *localeCountry = locale.getCountry(); + const char *localeScript = locale.getScript(); + if (localeCountry[0] != '\0' && localeScript[0] != '\0') { + std::string removeCountry; + removeCountry = locale.getLanguage(); + removeCountry.append("-"); + removeCountry.append(localeScript); + return CheckLocales(removeCountry.c_str(), key, packageName, res); + } + if (localeCountry[0] != '\0' || localeScript[0] != '\0') { + std::string language = locale.getLanguage(); + return CheckLocales(language.c_str(), key, packageName, res); + } + return res; + } + + static bool CheckLocales(const icu::Locale &locale, const char *key, const char *packageName, bool &res) + { + res = false; + UErrorCode status = U_ZERO_ERROR; + const char *formalLocale = locale.getName(); + UResourceBundle *localeRes = ures_open(packageName, formalLocale, &status); + if (localeRes != nullptr && status == U_ZERO_ERROR) { + bool flag = (key == nullptr) ? true : false; + if (flag) { + res = true; + } else { + UResourceBundle *keyRes = ures_getByKey(localeRes, key, nullptr, &status); + if (keyRes != nullptr && status == U_ZERO_ERROR) { + res = true; + } + ures_close(keyRes); + } + } + ures_close(localeRes); + if (res) { + return res; + } else { + ValidateOtherTags(locale, packageName, key, res); + } + return res; + } + + static JSHandle IcuToString(JSThread *thread, const icu::UnicodeString &string); + + static JSHandle IcuToString(JSThread *thread, const icu::UnicodeString &string, int32_t begin, + int32_t end); + + static JSHandle GetAvailableLocales(JSThread *thread, const char *key, const char *path); + + static JSHandle PutElement(JSThread *thread, int index, const JSHandle &array, + const JSHandle &fieldTypeString, + const JSHandle &value); + + static JSHandle ToLanguageTag(JSThread *thread, const icu::Locale &locale); + + static std::string GetNumberingSystem(const icu::Locale &icuLocale); + + static bool IsWellFormedCurrencyCode(const std::string ¤cy); + + static JSHandle GetNumberFieldType(JSThread *thread, JSTaggedValue x, int32_t fieldId); + + static bool ApplyOptionsToTag(JSThread *thread, const JSHandle &tag, const JSHandle &options, + TagElements &tagElements); + + static JSHandle InitializeLocale(JSThread *thread, const JSHandle &locale, + const JSHandle &localeString, + const JSHandle &options); + + static JSHandle NormalizeKeywordValue(JSThread *thread, const JSHandle &locale, + const std::string &key); + + static void HandleLocaleExtension(size_t &start, size_t &extensionEnd, std::string result, size_t len); + + static ParsedLocale HandleLocale(const JSHandle &locale); + + static JSHandle ToString(JSThread *thread, const JSHandle &locale); + + // 12.1.1 SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault, notation ) + template + static void SetNumberFormatDigitOptions(JSThread *thread, const JSHandle &intlObj, + const JSHandle &options, int mnfdDefault, int mxfdDefault, + NotationOption notation) + { + // 1. Assert: Type(intlObj) is Object. + // 2. Assert: Type(options) is Object. + // 3. Assert: Type(mnfdDefault) is Number. + // 4. Assert: Type(mxfdDefault) is Number. + ASSERT(options->IsHeapObject()); + auto globalConst = thread->GlobalConstants(); + // Set intlObj.[[MinimumFractionDigits]] to 0. + intlObj->SetMinimumFractionDigits(thread, JSTaggedValue(0)); + // Set intlObj.[[MaximumFractionDigits]] to 0. + intlObj->SetMaximumFractionDigits(thread, JSTaggedValue(0)); + // Set intlObj.[[MinimumSignificantDigits]] to 0. + intlObj->SetMinimumSignificantDigits(thread, JSTaggedValue(0)); + // Set intlObj.[[MaximumSignificantDigits]] to 0. + intlObj->SetMaximumSignificantDigits(thread, JSTaggedValue(0)); + + // 5. Let mnid be ? GetNumberOption(options, "minimumIntegerDigits,", 1, 21, 1). + JSHandle mnidKey = globalConst->GetHandledMinimumIntegerDigitsString(); + int mnid = GetNumberOption(thread, JSHandle::Cast(options), mnidKey, 1, MAX_DIGITS, 1); + // 6. Let mnfd be ? Get(options, "minimumFractionDigits"). + JSHandle mnfdKey = globalConst->GetHandledMinimumFractionDigitsString(); + JSHandle mnfd = JSTaggedValue::GetProperty(thread, options, mnfdKey).GetValue(); + // 7. Let mxfd be ? Get(options, "maximumFractionDigits"). + JSHandle mxfdKey = globalConst->GetHandledMaximumFractionDigitsString(); + JSHandle mxfd = JSTaggedValue::GetProperty(thread, options, mxfdKey).GetValue(); + // 8. Let mnsd be ? Get(options, "minimumSignificantDigits"). + JSHandle mnsdKey = globalConst->GetHandledMinimumSignificantDigitsString(); + JSHandle mnsd = JSTaggedValue::GetProperty(thread, options, mnsdKey).GetValue(); + // 9. Let mxsd be ? Get(options, "maximumSignificantDigits"). + JSHandle mxsdKey = globalConst->GetHandledMaximumSignificantDigitsString(); + JSHandle mxsd = JSTaggedValue::GetProperty(thread, options, mxsdKey).GetValue(); + + // 10. Set intlObj.[[MinimumIntegerDigits]] to mnid. + intlObj->SetMinimumIntegerDigits(thread, JSTaggedValue(mnid)); + // 11. If mnsd is not undefined or mxsd is not undefined, then + if (!mnsd->IsUndefined() || !mxsd->IsUndefined()) { + // a. Set intlObj.[[RoundingType]] to significantDigits. + intlObj->SetRoundingType(thread, JSTaggedValue(static_cast(RoundingType::SIGNIFICANTDIGITS))); + // b. Let mnsd be ? DefaultNumberOption(mnsd, 1, 21, 1). + mnsd = JSHandle( + thread, JSTaggedValue(JSLocale::DefaultNumberOption(thread, mnsd, 1, MAX_DIGITS, 1))); + // c. Let mxsd be ? DefaultNumberOption(mxsd, mnsd, 21, 21). + mxsd = JSHandle(thread, + JSTaggedValue(JSLocale::DefaultNumberOption(thread, mxsd, mnsd->GetInt(), MAX_DIGITS, MAX_DIGITS))); + // d. Set intlObj.[[MinimumSignificantDigits]] to mnsd. + intlObj->SetMinimumSignificantDigits(thread, mnsd); + // e. Set intlObj.[[MaximumSignificantDigits]] to mxsd. + intlObj->SetMaximumSignificantDigits(thread, mxsd); + } else { + if (!mnfd->IsUndefined() || !mxfd->IsUndefined()) { + // 12. Else if mnfd is not undefined or mxfd is not undefined, then + // a. Set intlObj.[[RoundingType]] to fractionDigits. + intlObj->SetRoundingType(thread, JSTaggedValue(static_cast(RoundingType::FRACTIONDIGITS))); + if (!mxfd->IsUndefined()) { + JSTaggedValue mxfdValue = + JSTaggedValue(JSLocale::DefaultNumberOption(thread, mxfd, 0, MAX_FRACTION_DIGITS, mxfdDefault)); + mxfd = JSHandle(thread, mxfdValue); + mnfdDefault = std::min(mnfdDefault, mxfd->GetInt()); + } + // b. Let mnfd be ? DefaultNumberOption(mnfd, 0, 20, mnfdDefault). + mnfd = JSHandle( + thread, JSTaggedValue(DefaultNumberOption(thread, mnfd, 0, MAX_FRACTION_DIGITS, mnfdDefault))); + // c. Let mxfdActualDefault be max( mnfd, mxfdDefault ). + int mxfdActualDefault = std::max(mnfd->GetInt(), mxfdDefault); + // d. Let mxfd be ? DefaultNumberOption(mxfd, mnfd, 20, mxfdActualDefault). + mxfd = JSHandle( + thread, JSTaggedValue(JSLocale::DefaultNumberOption(thread, mxfd, mnfd->GetInt(), + MAX_FRACTION_DIGITS, mxfdActualDefault))); + // e. Set intlObj.[[MinimumFractionDigits]] to mnfd. + intlObj->SetMinimumFractionDigits(thread, mnfd); + // f. Set intlObj.[[MaximumFractionDigits]] to mxfd. + intlObj->SetMaximumFractionDigits(thread, mxfd); + } else if (notation == NotationOption::COMPACT) { + // 13. Else if notation is "compact", then + // a. Set intlObj.[[RoundingType]] to compactRounding. + intlObj->SetRoundingType(thread, JSTaggedValue(static_cast(RoundingType::COMPACTROUNDING))); + } else { + // 14. else, + // a.Set intlObj.[[RoundingType]] to fractionDigits. + intlObj->SetRoundingType(thread, JSTaggedValue(static_cast(RoundingType::FRACTIONDIGITS))); + // b.Set intlObj.[[MinimumFractionDigits]] to mnfdDefault. + intlObj->SetMinimumFractionDigits(thread, JSTaggedValue(mnfdDefault)); + // c.Set intlObj.[[MaximumFractionDigits]] to mxfdDefault. + intlObj->SetMaximumFractionDigits(thread, JSTaggedValue(mxfdDefault)); + } + } + } + + static JSHandle ConstructLocaleList(JSThread *thread, + const std::vector &icuAvailableLocales); + + static bool CheckLocales(const icu::Locale &locale, const char *path, const char *key); + + static bool IsPrivateSubTag(std::string result, size_t len) + { + if ((len > INTL_INDEX_ONE) && (result[INTL_INDEX_ONE] == '-')) { + ASSERT(result[INTL_INDEX_ZERO] == 'x' || result[INTL_INDEX_ZERO] == 'i'); + return true; + } + return false; + } + +private: + static icu::Locale BuildICULocale(const std::string &bcp47Locale); + + static bool IsCheckRange(const std::string &str, size_t min, size_t max, bool(rangeCheckFunc)(char)) + { + if (!InRange(str.length(), min, max)) { + return false; + } + for (char i : str) { + if (!rangeCheckFunc(i)) { + return false; + } + } + return true; + } + + static bool IsAlpha(const std::string &str, size_t min, size_t max) + { + if (!InRange(str.length(), min, max)) { + return false; + } + for (char c : str) { + if (!IsAsciiAlpha(c)) { + return false; + } + } + return true; + } + + static bool IsDigit(const std::string &str, size_t min, size_t max) + { + if (!InRange(str.length(), min, max)) { + return false; + } + for (char i : str) { + if (!InRange(i, '0', '9')) { + return false; + } + } + return true; + } + + static bool IsAlphanum(const std::string &str, size_t min, size_t max) + { + if (!InRange(str.length(), min, max)) { + return false; + } + for (char i : str) { + if (!IsAsciiAlpha(i) && !InRange(i, '0', '9')) { + return false; + } + } + return true; + } + + static bool IsAToZ(char ch) + { + int lowerCh = JSLocale::AsciiAlphaToLower(ch); + return JSLocale::InRange(lowerCh, 'a', 'z'); + } +}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_JSLOCALE_H diff --git a/ecmascript/js_map.h b/ecmascript/js_map.h index 580c58fdbdb838d8968942512e11d8aca4d63591..7b2a90e3479c023a1904ba3d0bd9df8690d6e383 100644 --- a/ecmascript/js_map.h +++ b/ecmascript/js_map.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSMAP_H -#define PANDA_RUNTIME_ECMASCRIPT_JSMAP_H +#ifndef ECMASCRIPT_JSMAP_H +#define ECMASCRIPT_JSMAP_H #include #include "js_object.h" @@ -52,4 +52,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSMAP_H +#endif // ECMASCRIPT_JSMAP_H diff --git a/ecmascript/js_map_iterator.h b/ecmascript/js_map_iterator.h index d596a0a966d7a74e0cd1f94582d8b3c5ed226d03..8669ed71894116c1234c4fac686da9603dc7d282 100644 --- a/ecmascript/js_map_iterator.h +++ b/ecmascript/js_map_iterator.h @@ -13,11 +13,12 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_MAP_ITERATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_MAP_ITERATOR_H +#ifndef ECMASCRIPT_JS_MAP_ITERATOR_H +#define ECMASCRIPT_JS_MAP_ITERATOR_H #include "js_iterator.h" #include "js_object.h" + namespace panda::ecmascript { class JSMapIterator : public JSObject { public: @@ -43,4 +44,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_MAP_ITERATOR_H +#endif // ECMASCRIPT_JS_MAP_ITERATOR_H diff --git a/ecmascript/js_method.cpp b/ecmascript/js_method.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a704713a717270ce2fb89a5bdb000d059c698092 --- /dev/null +++ b/ecmascript/js_method.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "js_method.h" + +namespace panda::ecmascript { +// It's not allowed '#' token appear in ECMA function(method) name, which discriminates same names in panda methods. +CString JSMethod::ParseFunctionName() const +{ + CString methodName(utf::Mutf8AsCString(GetName().data)); + if (LIKELY(methodName[0] != '#')) { + return methodName; + } + size_t index = methodName.find_last_of('#'); + return CString(methodName.substr(index + 1)); +} +} \ No newline at end of file diff --git a/ecmascript/js_method.h b/ecmascript/js_method.h index 7429cb381f6e61a3b68f35d03285a7ccf3766f48..ea583d495d7ce80cc04b5d5bd9e08d523e7e692d 100644 --- a/ecmascript/js_method.h +++ b/ecmascript/js_method.h @@ -13,9 +13,10 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_METHOD_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_METHOD_H +#ifndef ECMASCRIPT_JS_METHOD_H +#define ECMASCRIPT_JS_METHOD_H +#include "ecmascript/mem/c_string.h" #include "include/method.h" #include "libpandafile/file.h" @@ -26,6 +27,8 @@ class Class; namespace panda::ecmascript { class JSMethod : public Method { public: + static constexpr uint8_t MAX_SLOT_SIZE = 0xFF; + static JSMethod *Cast(Method *method) { return static_cast(method); @@ -40,6 +43,7 @@ public: } JSMethod() = delete; + ~JSMethod() = default; JSMethod(const JSMethod &) = delete; JSMethod(JSMethod &&) = delete; JSMethod &operator=(const JSMethod &) = delete; @@ -65,10 +69,28 @@ public: bytecodeArray_ = bc; } + uint8_t GetSlotSize() const + { + return slotSize_; + } + + void UpdateSlotSize (uint8_t size) + { + uint16_t end = GetSlotSize() + size; + if (end >= MAX_SLOT_SIZE) { + slotSize_ = MAX_SLOT_SIZE; + return; + } + slotSize_ = static_cast(end); + } + + CString ParseFunctionName() const; + private: const uint8_t *bytecodeArray_ {nullptr}; uint32_t bytecodeArraySize_ {0}; + uint8_t slotSize_{0}; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_METHOD_H +#endif // ECMASCRIPT_JS_METHOD_H diff --git a/ecmascript/js_native_object.h b/ecmascript/js_native_object.h index 2c4e48fe4d6f86ad13aef9d71b5ac4a705854192..0b73f52bd233e5cf8b9706b846458d8b3bd9dd94 100644 --- a/ecmascript/js_native_object.h +++ b/ecmascript/js_native_object.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSNATIVEOBJECT_H -#define PANDA_RUNTIME_ECMASCRIPT_JSNATIVEOBJECT_H +#ifndef ECMASCRIPT_JSNATIVEOBJECT_H +#define ECMASCRIPT_JSNATIVEOBJECT_H #include "js_object.h" #include "js_native_pointer.h" @@ -75,4 +75,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSNATIVEOBJECT_H +#endif // ECMASCRIPT_JSNATIVEOBJECT_H diff --git a/ecmascript/js_native_pointer.h b/ecmascript/js_native_pointer.h index f7d511b06328e2722a9fc5d514ce20897b7158bf..81d9989d40bdc5f4ce75076744cc3c6cb284f230 100644 --- a/ecmascript/js_native_pointer.h +++ b/ecmascript/js_native_pointer.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSNATIVEPOINTER_H -#define PANDA_RUNTIME_ECMASCRIPT_JSNATIVEPOINTER_H +#ifndef ECMASCRIPT_JSNATIVEPOINTER_H +#define ECMASCRIPT_JSNATIVEPOINTER_H #include "include/coretypes/native_pointer.h" @@ -29,6 +29,23 @@ public: return reinterpret_cast(object); } + inline void ResetExternalPointer(void *externalPointer) + { + ClearExternalPointer(); + SetExternalPointer(externalPointer); + } + + inline void ClearExternalPointer() + { + if (GetExternalPointer() == nullptr) { + return; + } + if (deleter_ != nullptr) { + deleter_(GetExternalPointer(), data_); + } + SetExternalPointer(nullptr); + } + inline void SetDeleter(DeleteEntryPoint deleter) { deleter_ = deleter; @@ -46,11 +63,9 @@ public: inline void Destroy() { - if (deleter_ == nullptr || GetExternalPointer() == nullptr) { - return; - } - deleter_(GetExternalPointer(), data_); - SetExternalPointer(nullptr); + ClearExternalPointer(); + SetDeleter(nullptr); + SetData(nullptr); } private: @@ -59,4 +74,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSNATIVEPOINTER_H +#endif // ECMASCRIPT_JSNATIVEPOINTER_H diff --git a/ecmascript/js_number_format.cpp b/ecmascript/js_number_format.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d6c52cbc5f1719b8facfff184253e901106c911f --- /dev/null +++ b/ecmascript/js_number_format.cpp @@ -0,0 +1,1007 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "ecmascript/js_number_format.h" + +namespace panda::ecmascript { +constexpr uint32_t DEFAULT_FRACTION_DIGITS = 2; +constexpr uint32_t PERUNIT_STRING = 5; + +JSHandle OptionToEcmaString(JSThread *thread, StyleOption style) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (style) { + case StyleOption::DECIMAL: + result.Update(globalConst->GetHandledDecimalString().GetTaggedValue()); + break; + case StyleOption::CURRENCY: + result.Update(globalConst->GetHandledCurrencyString().GetTaggedValue()); + break; + case StyleOption::PERCENT: + result.Update(globalConst->GetHandledPercentString().GetTaggedValue()); + break; + case StyleOption::UNIT: + result.Update(globalConst->GetHandledUnitString().GetTaggedValue()); + break; + default: + UNREACHABLE(); + } + return result; +} + +JSHandle OptionToEcmaString(JSThread *thread, CurrencyDisplayOption currencyDisplay) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (currencyDisplay) { + case CurrencyDisplayOption::CODE: + result.Update(globalConst->GetHandledCodeString().GetTaggedValue()); + break; + case CurrencyDisplayOption::SYMBOL: + result.Update(globalConst->GetHandledSymbolString().GetTaggedValue()); + break; + case CurrencyDisplayOption::NARROWSYMBOL: + result.Update(globalConst->GetHandledNarrowSymbolString().GetTaggedValue()); + break; + case CurrencyDisplayOption::NAME: + result.Update(globalConst->GetHandledNameString().GetTaggedValue()); + break; + default: + UNREACHABLE(); + } + return result; +} + +JSHandle OptionToEcmaString(JSThread *thread, CurrencySignOption currencySign) +{ + auto globalConst = thread->GlobalConstants(); + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + switch (currencySign) { + case CurrencySignOption::STANDARD: + result.Update(globalConst->GetHandledStandardString().GetTaggedValue()); + break; + case CurrencySignOption::ACCOUNTING: + result.Update(globalConst->GetHandledAccountingString().GetTaggedValue()); + break; + default: + UNREACHABLE(); + } + return result; +} + +JSHandle OptionToEcmaString(JSThread *thread, UnitDisplayOption unitDisplay) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (unitDisplay) { + case UnitDisplayOption::SHORT: + result.Update(globalConst->GetHandledShortString().GetTaggedValue()); + break; + case UnitDisplayOption::NARROW: + result.Update(globalConst->GetHandledNarrowString().GetTaggedValue()); + break; + case UnitDisplayOption::LONG: + result.Update(globalConst->GetHandledLongString().GetTaggedValue()); + break; + default: + UNREACHABLE(); + } + return result; +} + +JSHandle OptionToEcmaString(JSThread *thread, NotationOption notation) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (notation) { + case NotationOption::STANDARD: + result.Update(globalConst->GetHandledStandardString().GetTaggedValue()); + break; + case NotationOption::SCIENTIFIC: + result.Update(globalConst->GetHandledScientificString().GetTaggedValue()); + break; + case NotationOption::ENGINEERING: + result.Update(globalConst->GetHandledEngineeringString().GetTaggedValue()); + break; + case NotationOption::COMPACT: + result.Update(globalConst->GetHandledCompactString().GetTaggedValue()); + break; + default: + UNREACHABLE(); + } + return result; +} + +JSHandle OptionToEcmaString(JSThread *thread, CompactDisplayOption compactDisplay) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (compactDisplay) { + case CompactDisplayOption::SHORT: + result.Update(globalConst->GetHandledShortString().GetTaggedValue()); + break; + case CompactDisplayOption::LONG: + result.Update(globalConst->GetHandledLongString().GetTaggedValue()); + break; + default: + UNREACHABLE(); + } + return result; +} + +JSHandle OptionToEcmaString(JSThread *thread, SignDisplayOption signDisplay) +{ + JSMutableHandle result(thread, JSTaggedValue::Undefined()); + auto globalConst = thread->GlobalConstants(); + switch (signDisplay) { + case SignDisplayOption::AUTO: + result.Update(globalConst->GetHandledAutoString().GetTaggedValue()); + break; + case SignDisplayOption::ALWAYS: + result.Update(globalConst->GetHandledAlwaysString().GetTaggedValue()); + break; + case SignDisplayOption::NEVER: + result.Update(globalConst->GetHandledNeverString().GetTaggedValue()); + break; + case SignDisplayOption::EXCEPTZERO: + result.Update(globalConst->GetHandledExceptZeroString().GetTaggedValue()); + break; + default: + UNREACHABLE(); + } + return result; +} + +icu::MeasureUnit ToMeasureUnit(const std::string &sanctionedUnit) +{ + UErrorCode status = U_ZERO_ERROR; + // Get All ICU measure unit + int32_t total = icu::MeasureUnit::getAvailable(nullptr, 0, status); + status = U_ZERO_ERROR; + std::vector units(total); + icu::MeasureUnit::getAvailable(units.data(), total, status); + ASSERT(U_SUCCESS(status)); + + // Find measure unit according to sanctioned unit + // then return measure unit + for (auto &unit : units) { + if (std::strcmp(sanctionedUnit.c_str(), unit.getSubtype()) == 0) { + return unit; + } + } + return icu::MeasureUnit(); +} + +// ecma402 #sec-issanctionedsimpleunitidentifier +bool IsSanctionedSimpleUnitIdentifier(const std::string &unit) +{ + // 1. If unitIdentifier is listed in sanctioned unit set, return true. + auto it = sanctionedUnit.find(unit); + if (it != sanctionedUnit.end()) { + return true; + } + + // 2. Else, Return false. + return false; +} + +// 6.5.1 IsWellFormedUnitIdentifier ( unitIdentifier ) +bool IsWellFormedUnitIdentifier(const std::string &unit, icu::MeasureUnit &icuUnit, icu::MeasureUnit &icuPerUnit) +{ + // 1. If the result of IsSanctionedSimpleUnitIdentifier(unitIdentifier) is true, then + // a. Return true. + icu::MeasureUnit result = icu::MeasureUnit(); + icu::MeasureUnit emptyUnit = icu::MeasureUnit(); + auto pos = unit.find("-per-"); + if (IsSanctionedSimpleUnitIdentifier(unit) && pos == std::string::npos) { + result = ToMeasureUnit(unit); + icuUnit = result; + icuPerUnit = emptyUnit; + return true; + } + + // 2. If the substring "-per-" does not occur exactly once in unitIdentifier, + // a. then false + size_t afterPos = pos + PERUNIT_STRING; + if (pos == std::string::npos || unit.find("-per-", afterPos) != std::string::npos) { + return false; + } + + // 3. Let numerator be the substring of unitIdentifier from the beginning to just before "-per-". + std::string numerator = unit.substr(0, pos); + // 4. If the result of IsSanctionedUnitIdentifier(numerator) is false, then + // a. return false + if (IsSanctionedSimpleUnitIdentifier(numerator)) { + result = ToMeasureUnit(numerator); + } else { + return false; + } + + // 5. Let denominator be the substring of unitIdentifier from just after "-per-" to the end. + std::string denominator = unit.substr(pos + PERUNIT_STRING); + + // 6. If the result of IsSanctionedUnitIdentifier(denominator) is false, then + // a. Return false + icu::MeasureUnit perResult = icu::MeasureUnit(); + if (IsSanctionedSimpleUnitIdentifier(denominator)) { + perResult = ToMeasureUnit(denominator); + } else { + return false; + } + + // 7. Return true. + icuUnit = result; + icuPerUnit = perResult; + return true; +} + +// 12.1.13 SetNumberFormatUnitOptions ( intlObj, options ) +FractionDigitsOption SetNumberFormatUnitOptions(JSThread *thread, + const JSHandle &numberFormat, + const JSHandle &optionsObject, + icu::number::LocalizedNumberFormatter *icuNumberFormatter) +{ + auto globalConst = thread->GlobalConstants(); + FractionDigitsOption fractionDigitsOption; + // 3. Let style be ? GetOption(options, "style", "string", « "decimal", "percent", "currency", "unit" », "decimal"). + JSHandle property = globalConst->GetHandledStyleString(); + auto style = JSLocale::GetOptionOfString( + thread, optionsObject, property, + {StyleOption::DECIMAL, StyleOption::PERCENT, StyleOption::CURRENCY, StyleOption::UNIT}, + {"decimal", "percent", "currency", "unit"}, StyleOption::DECIMAL); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fractionDigitsOption); + + // 4. Set intlObj.[[Style]] to style. + JSHandle styleValue(thread, JSTaggedValue(static_cast(style))); + numberFormat->SetStyle(thread, styleValue); + + // 5. Let currency be ? GetOption(options, "currency", "string", undefined, undefined). + property = globalConst->GetHandledCurrencyString(); + JSHandle undefinedValue(thread, JSTaggedValue::Undefined()); + JSHandle currency = + JSLocale::GetOption(thread, optionsObject, property, OptionType::STRING, undefinedValue, undefinedValue); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fractionDigitsOption); + + // 6. If currency is not undefined, then + // a. If the result of IsWellFormedCurrencyCode(currency) is false, throw a RangeError exception. + if (!currency->IsUndefined()) { + JSHandle currencyStr = JSHandle::Cast(currency); + if (currencyStr->IsUtf16()) { + THROW_RANGE_ERROR_AND_RETURN(thread, "not a utf-8", fractionDigitsOption); + } + std::string currencyCStr = JSLocale::ConvertToStdString(currencyStr); + if (!JSLocale::IsWellFormedCurrencyCode(currencyCStr)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "not a wellformed code", fractionDigitsOption); + } + } else { + // 7. If style is "currency" and currency is undefined, throw a TypeError exception. + if (style == StyleOption::CURRENCY) { + THROW_TYPE_ERROR_AND_RETURN(thread, "style is currency but currency is undefined", fractionDigitsOption); + } + } + + // 8. Let currencyDisplay be ? GetOption(options, "currencyDisplay", "string", + // « "code", "symbol", "narrowSymbol", "name" », "symbol"). + property = globalConst->GetHandledCurrencyDisplayString(); + auto currencyDisplay = JSLocale::GetOptionOfString( + thread, optionsObject, property, + {CurrencyDisplayOption::CODE, CurrencyDisplayOption::SYMBOL, CurrencyDisplayOption::NARROWSYMBOL, + CurrencyDisplayOption::NAME}, + {"code", "symbol", "narrowSymbol", "name"}, CurrencyDisplayOption::SYMBOL); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fractionDigitsOption); + JSHandle currencyDisplayValue(thread, JSTaggedValue(static_cast(currencyDisplay))); + numberFormat->SetCurrencyDisplay(thread, currencyDisplayValue); + + // 9. Let currencySign be ? GetOption(options, "currencySign", "string", « "standard", "accounting" », "standard"). + property = globalConst->GetHandledCurrencySignString(); + auto currencySign = JSLocale::GetOptionOfString( + thread, optionsObject, property, {CurrencySignOption::STANDARD, CurrencySignOption::ACCOUNTING}, + {"standard", "accounting"}, CurrencySignOption::STANDARD); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fractionDigitsOption); + JSHandle currencySignValue(thread, JSTaggedValue(static_cast(currencySign))); + numberFormat->SetCurrencySign(thread, currencySignValue); + + // 10. Let unit be ? GetOption(options, "unit", "string", undefined, undefined). + property = globalConst->GetHandledUnitString(); + JSHandle unit = + JSLocale::GetOption(thread, optionsObject, property, OptionType::STRING, undefinedValue, undefinedValue); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fractionDigitsOption); + numberFormat->SetUnit(thread, unit); + + // 11. If unit is not undefined, then + // If the result of IsWellFormedUnitIdentifier(unit) is false, throw a RangeError exception. + icu::MeasureUnit icuUnit; + icu::MeasureUnit icuPerUnit; + if (!unit->IsUndefined()) { + JSHandle unitStr = JSHandle::Cast(unit); + if (unitStr->IsUtf16()) { + THROW_RANGE_ERROR_AND_RETURN(thread, "Unit input is illegal", fractionDigitsOption); + } + std::string str = JSLocale::ConvertToStdString(unitStr); + if (!IsWellFormedUnitIdentifier(str, icuUnit, icuPerUnit)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "Unit input is illegal", fractionDigitsOption); + } + } else { + // 15.12. if style is "unit" and unit is undefined, throw a TypeError exception. + if (style == StyleOption::UNIT) { + THROW_TYPE_ERROR_AND_RETURN(thread, "style is unit but unit is undefined", fractionDigitsOption); + } + } + + // 13. Let unitDisplay be ? GetOption(options, "unitDisplay", "string", « "short", "narrow", "long" », "short"). + property = globalConst->GetHandledUnitDisplayString(); + auto unitDisplay = JSLocale::GetOptionOfString( + thread, optionsObject, property, {UnitDisplayOption::SHORT, UnitDisplayOption::NARROW, UnitDisplayOption::LONG}, + {"short", "narrow", "long"}, UnitDisplayOption::SHORT); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, fractionDigitsOption); + JSHandle unitDisplayValue(thread, JSTaggedValue(static_cast(unitDisplay))); + numberFormat->SetUnitDisplay(thread, unitDisplayValue); + + // 14. If style is "currency", then + // a. Let currency be the result of converting currency to upper case as specified in 6.1. + // b. Set intlObj.[[Currency]] to currency. + // c. Set intlObj.[[CurrencyDisplay]] to currencyDisplay. + // d. Set intlObj.[[CurrencySign]] to currencySign. + icu::UnicodeString currencyUStr; + UErrorCode status = U_ZERO_ERROR; + if (style == StyleOption::CURRENCY) { + JSHandle currencyStr = JSHandle::Cast(currency); + std::string currencyCStr = JSLocale::ConvertToStdString(currencyStr); + std::transform(currencyCStr.begin(), currencyCStr.end(), currencyCStr.begin(), toupper); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle currencyValue = JSHandle::Cast(factory->NewFromStdString(currencyCStr)); + numberFormat->SetCurrency(thread, currencyValue); + currencyUStr = currencyCStr.c_str(); + if (!currencyUStr.isEmpty()) { // NOLINT(readability-implicit-bool-conversion) + *icuNumberFormatter = icuNumberFormatter->unit(icu::CurrencyUnit(currencyUStr.getBuffer(), status)); + ASSERT(U_SUCCESS(status)); + UNumberUnitWidth uNumberUnitWidth; + // Trans currencyDisplayOption to ICU format number display option + switch (currencyDisplay) { + case CurrencyDisplayOption::CODE: + uNumberUnitWidth = UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE; + break; + case CurrencyDisplayOption::SYMBOL: + uNumberUnitWidth = UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT; + break; + case CurrencyDisplayOption::NARROWSYMBOL: + uNumberUnitWidth = UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW; + break; + case CurrencyDisplayOption::NAME: + uNumberUnitWidth = UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME; + break; + default: + UNREACHABLE(); + } + *icuNumberFormatter = icuNumberFormatter->unitWidth(uNumberUnitWidth); + } + } + + // 15. If style is "unit", then + // if unit is not undefiend set unit to LocalizedNumberFormatter + // then if perunit is not undefiend set perunit to LocalizedNumberFormatter + if (style == StyleOption::UNIT) { + icu::MeasureUnit emptyUnit = icu::MeasureUnit(); + if (icuUnit != emptyUnit) { // NOLINT(readability-implicit-bool-conversion) + *icuNumberFormatter = icuNumberFormatter->unit(icuUnit); + } + if (icuPerUnit != emptyUnit) { // NOLINT(readability-implicit-bool-conversion) + *icuNumberFormatter = icuNumberFormatter->perUnit(icuPerUnit); + } + } + + // 17. If style is "currency", then + // a. Let cDigits be CurrencyDigits(currency). + // b. Let mnfdDefault be cDigits. + // c. Let mxfdDefault be cDigits. + if (style == StyleOption::CURRENCY) { + int32_t cDigits = JSNumberFormat::CurrencyDigits(currencyUStr); + fractionDigitsOption.mnfdDefault = cDigits; + fractionDigitsOption.mxfdDefault = cDigits; + } else { + // 18. Else, + // a. Let mnfdDefault be 0. + // b. If style is "percent", then + // i. Let mxfdDefault be 0. + // c. else, + // i. Let mxfdDefault be 3. + fractionDigitsOption.mnfdDefault = 0; + if (style == StyleOption::PERCENT) { + fractionDigitsOption.mxfdDefault = 0; + } else { + fractionDigitsOption.mxfdDefault = 3; // Max decimal precision is 3 + } + } + return fractionDigitsOption; +} + +// 12.1.2 InitializeNumberFormat ( numberFormat, locales, options ) +// NOLINTNEXTLINE(readability-function-size) +void JSNumberFormat::InitializeNumberFormat(JSThread *thread, const JSHandle &numberFormat, + const JSHandle &locales, + const JSHandle &options) +{ + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + + // 2. If options is undefined, then + // a. Let options be ObjectCreate(null). + // 3. Else, + // a. Let options be ? ToObject(options). + JSHandle optionsObject; + if (options->IsUndefined()) { + optionsObject = factory->OrdinaryNewJSObjectCreate(JSHandle(thread, JSTaggedValue::Null())); + } else { + optionsObject = JSTaggedValue::ToObject(thread, options); + RETURN_IF_ABRUPT_COMPLETION(thread); + } + + auto globalConst = thread->GlobalConstants(); + // 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + JSHandle property = globalConst->GetHandledLocaleMatcherString(); + auto matcher = JSLocale::GetOptionOfString( + thread, optionsObject, property, {LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT}, + {"lookup", "best fit"}, LocaleMatcherOption::BEST_FIT); + RETURN_IF_ABRUPT_COMPLETION(thread); + + // 7. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined). + property = globalConst->GetHandledNumberingSystemString(); + JSHandle undefinedValue(thread, JSTaggedValue::Undefined()); + JSHandle numberingSystemTaggedValue = + JSLocale::GetOption(thread, optionsObject, property, OptionType::STRING, undefinedValue, undefinedValue); + RETURN_IF_ABRUPT_COMPLETION(thread); + numberFormat->SetNumberingSystem(thread, numberingSystemTaggedValue); + + // 8. If numberingSystem is not undefined, then + // a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, + // throw a RangeError exception. `(3*8alphanum) *("-" (3*8alphanum))` + std::string numberingSystemStr; + if (!numberingSystemTaggedValue->IsUndefined()) { + JSHandle numberingSystemEcmaString = JSHandle::Cast(numberingSystemTaggedValue); + if (numberingSystemEcmaString->IsUtf16()) { + THROW_RANGE_ERROR(thread, "invalid numberingSystem"); + } + numberingSystemStr = JSLocale::ConvertToStdString(numberingSystemEcmaString); + if (!JSLocale::IsNormativeNumberingSystem(numberingSystemStr)) { + THROW_RANGE_ERROR(thread, "invalid numberingSystem"); + } + } + + // 10. Let localeData be %NumberFormat%.[[LocaleData]]. + JSHandle availableLocales; + if (requestedLocales->GetLength() == 0) { + availableLocales = factory->EmptyArray(); + } else { + availableLocales = GetAvailableLocales(thread); + } + + // 11. Let r be ResolveLocale( %NumberFormat%.[[AvailableLocales]], requestedLocales, opt, + // %NumberFormat%.[[RelevantExtensionKeys]], localeData). + std::set relevantExtensionKeys{"nu"}; + ResolvedLocale r = + JSLocale::ResolveLocale(thread, availableLocales, requestedLocales, matcher, relevantExtensionKeys); + + // 12. Set numberFormat.[[Locale]] to r.[[locale]]. + icu::Locale icuLocale = r.localeData; + JSHandle localeStr = JSLocale::ToLanguageTag(thread, icuLocale); + numberFormat->SetLocale(thread, localeStr.GetTaggedValue()); + + // Set numberingSystemStr to UnicodeKeyWord "nu" + UErrorCode status = U_ZERO_ERROR; + if (!numberingSystemStr.empty()) { + if (JSLocale::IsWellNumberingSystem(numberingSystemStr)) { + icuLocale.setUnicodeKeywordValue("nu", numberingSystemStr, status); + ASSERT(U_SUCCESS(status)); + } + } + + icu::number::LocalizedNumberFormatter icuNumberFormatter = + icu::number::NumberFormatter::withLocale(icuLocale).roundingMode(UNUM_ROUND_HALFUP); + + // Get default numbering system associated with the specified locale + std::unique_ptr numberingSystemPtr(icu::NumberingSystem::createInstance(icuLocale, status)); + + int32_t mnfdDefault = 0; + int32_t mxfdDefault = 0; + FractionDigitsOption fractionOptions = + SetNumberFormatUnitOptions(thread, numberFormat, optionsObject, &icuNumberFormatter); + RETURN_IF_ABRUPT_COMPLETION(thread); + mnfdDefault = fractionOptions.mnfdDefault; + mxfdDefault = fractionOptions.mxfdDefault; + JSTaggedValue unitDisplayValue = numberFormat->GetUnitDisplay(); + UnitDisplayOption unitDisplay = static_cast(unitDisplayValue.GetInt()); + + // Trans unitDisplay option to ICU display option + UNumberUnitWidth uNumberUnitWidth; + switch (unitDisplay) { + case UnitDisplayOption::SHORT: + uNumberUnitWidth = UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT; + break; + case UnitDisplayOption::NARROW: + uNumberUnitWidth = UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW; + break; + case UnitDisplayOption::LONG: + // UNUM_UNIT_WIDTH_FULL_NAME Print the full name of the unit, without any abbreviations. + uNumberUnitWidth = UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME; + break; + default: + UNREACHABLE(); + } + icuNumberFormatter = icuNumberFormatter.unitWidth(uNumberUnitWidth); + + // 16. Let style be numberFormat.[[Style]]. + JSTaggedValue styleValue = numberFormat->GetStyle(); + StyleOption style = static_cast(styleValue.GetInt()); + if (style == StyleOption::PERCENT) { + icuNumberFormatter = icuNumberFormatter.unit(icu::MeasureUnit::getPercent()) + .scale(icu::number::Scale::powerOfTen(2)); // means 10^2 + } + + // 19. Let notation be ? GetOption( + // options, "notation", "string", « "standard", "scientific", "engineering", "compact" », "standard"). + property = globalConst->GetHandledNotationString(); + auto notation = JSLocale::GetOptionOfString( + thread, optionsObject, property, + {NotationOption::STANDARD, NotationOption::SCIENTIFIC, NotationOption::ENGINEERING, NotationOption::COMPACT}, + {"standard", "scientific", "engineering", "compact"}, NotationOption::STANDARD); + RETURN_IF_ABRUPT_COMPLETION(thread); + JSHandle notationValue(thread, JSTaggedValue(static_cast(notation))); + numberFormat->SetNotation(thread, notationValue); + + // 21. Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault, mxfdDefault, notation). + JSLocale::SetNumberFormatDigitOptions(thread, numberFormat, JSHandle::Cast(optionsObject), + mnfdDefault, mxfdDefault, notation); + icuNumberFormatter = SetICUFormatterDigitOptions(icuNumberFormatter, numberFormat); + + // 22. Let compactDisplay be ? GetOptionOfString(options, "compactDisplay", "string", « "short", "long" », "short"). + property = globalConst->GetHandledCompactDisplayString(); + auto compactDisplay = JSLocale::GetOptionOfString( + thread, optionsObject, property, {CompactDisplayOption::SHORT, CompactDisplayOption::LONG}, {"short", "long"}, + CompactDisplayOption::SHORT); + JSHandle compactDisplayValue(thread, JSTaggedValue(static_cast(compactDisplay))); + numberFormat->SetCompactDisplay(thread, compactDisplayValue); + + // Trans NotationOption to ICU Noation and set to icuNumberFormatter + if (notation == NotationOption::COMPACT) { + switch (compactDisplay) { + case CompactDisplayOption::SHORT: + icuNumberFormatter = icuNumberFormatter.notation(icu::number::Notation::compactShort()); + break; + case CompactDisplayOption::LONG: + icuNumberFormatter = icuNumberFormatter.notation(icu::number::Notation::compactLong()); + break; + default: + break; + } + } + switch (notation) { + case NotationOption::STANDARD: + icuNumberFormatter = icuNumberFormatter.notation(icu::number::Notation::simple()); + break; + case NotationOption::SCIENTIFIC: + icuNumberFormatter = icuNumberFormatter.notation(icu::number::Notation::scientific()); + break; + case NotationOption::ENGINEERING: + icuNumberFormatter = icuNumberFormatter.notation(icu::number::Notation::engineering()); + break; + default: + break; + } + + // 24. Let useGrouping be ? GetOption(options, "useGrouping", "boolean", undefined, true). + property = globalConst->GetHandledUserGroupingString(); + bool useGrouping = false; + [[maybe_unused]] bool find = JSLocale::GetOptionOfBool(thread, optionsObject, property, true, &useGrouping); + RETURN_IF_ABRUPT_COMPLETION(thread); + JSHandle useGroupingValue(thread, JSTaggedValue(useGrouping)); + numberFormat->SetUseGrouping(thread, useGroupingValue); + + // 25. Set numberFormat.[[UseGrouping]] to useGrouping. + if (!useGrouping) { + icuNumberFormatter = icuNumberFormatter.grouping(UNumberGroupingStrategy::UNUM_GROUPING_OFF); + } + + // 26. Let signDisplay be ? + // GetOption(options, "signDisplay", "string", « "auto", "never", "always", "exceptZero" », "auto"). + property = globalConst->GetHandledSignDisplayString(); + auto signDisplay = JSLocale::GetOptionOfString( + thread, optionsObject, property, + {SignDisplayOption::AUTO, SignDisplayOption::NEVER, SignDisplayOption::ALWAYS, SignDisplayOption::EXCEPTZERO}, + {"auto", "never", "always", "exceptZero"}, SignDisplayOption::AUTO); + RETURN_IF_ABRUPT_COMPLETION(thread); + JSHandle signDisplayValue(thread, JSTaggedValue(static_cast(signDisplay))); + numberFormat->SetSignDisplay(thread, signDisplayValue); + + // 27. Set numberFormat.[[SignDisplay]] to signDisplay. + // The default sign in ICU is UNUM_SIGN_AUTO which is mapped from + // SignDisplay::AUTO and CurrencySign::STANDARD so we can skip setting + // under that values for optimization. + JSTaggedValue currencySignValue = numberFormat->GetCurrencySign(); + CurrencySignOption currencySign = static_cast(currencySignValue.GetInt()); + + // Trans SignDisPlayOption to ICU UNumberSignDisplay and set to icuNumberFormatter + switch (signDisplay) { + case SignDisplayOption::AUTO: + // if CurrencySign is ACCOUNTING, Use the locale-dependent accounting format on negative numbers + if (currencySign == CurrencySignOption::ACCOUNTING) { + icuNumberFormatter = icuNumberFormatter.sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING); + } else { + icuNumberFormatter = icuNumberFormatter.sign(UNumberSignDisplay::UNUM_SIGN_AUTO); + } + break; + case SignDisplayOption::NEVER: + icuNumberFormatter = icuNumberFormatter.sign(UNumberSignDisplay::UNUM_SIGN_NEVER); + break; + case SignDisplayOption::ALWAYS: + // if CurrencySign is ACCOUNTING, Use the locale-dependent accounting format on negative numbers + if (currencySign == CurrencySignOption::ACCOUNTING) { + icuNumberFormatter = icuNumberFormatter.sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_ALWAYS); + } else { + icuNumberFormatter = icuNumberFormatter.sign(UNumberSignDisplay::UNUM_SIGN_ALWAYS); + } + break; + case SignDisplayOption::EXCEPTZERO: + // if CurrencySign is ACCOUNTING, Use the locale-dependent accounting format on negative numbers + if (currencySign == CurrencySignOption::ACCOUNTING) { + icuNumberFormatter = icuNumberFormatter.sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO); + } else { + icuNumberFormatter = icuNumberFormatter.sign(UNumberSignDisplay::UNUM_SIGN_EXCEPT_ZERO); + } + break; + default: + break; + } + + // Set numberFormat.[[IcuNumberForma]] to handleNumberFormatter + factory->NewJSIntlIcuData(numberFormat, icuNumberFormatter, JSNumberFormat::FreeIcuNumberformat); + // Set numberFormat.[[BoundFormat]] to undefinedValue + numberFormat->SetBoundFormat(thread, undefinedValue); +} + +// 12.1.3 CurrencyDigits ( currency ) +int32_t JSNumberFormat::CurrencyDigits(const icu::UnicodeString ¤cy) +{ + UErrorCode status = U_ZERO_ERROR; + // If the ISO 4217 currency and funds code list contains currency as an alphabetic code, + // return the minor unit value corresponding to the currency from the list; otherwise, return 2. + int32_t fractionDigits = + ucurr_getDefaultFractionDigits(reinterpret_cast(currency.getBuffer()), &status); + if (U_SUCCESS(status)) { + return fractionDigits; + } + return DEFAULT_FRACTION_DIGITS; +} + +// 12.1.8 FormatNumeric( numberFormat, x ) +JSHandle JSNumberFormat::FormatNumeric(JSThread *thread, const JSHandle &numberFormat, + JSTaggedValue x) +{ + icu::number::LocalizedNumberFormatter *icuNumberFormat = numberFormat->GetIcuCallTarget(); + ASSERT(icuNumberFormat != nullptr); + + UErrorCode status = U_ZERO_ERROR; + double number = x.GetNumber(); + icu::number::FormattedNumber formattedNumber = icuNumberFormat->formatDouble(number, status); + if (U_FAILURE(status)) { + JSHandle errorResult(thread, JSTaggedValue::Exception()); + THROW_RANGE_ERROR_AND_RETURN(thread, "icu formatter format failed", errorResult); + } + icu::UnicodeString result = formattedNumber.toString(status); + if (U_FAILURE(status)) { + JSHandle errorResult(thread, JSTaggedValue::Exception()); + THROW_RANGE_ERROR_AND_RETURN(thread, "formatted number toString failed", errorResult); + } + JSHandle stringValue = JSLocale::IcuToString(thread, result); + return JSHandle::Cast(stringValue); +} + +void GroupToParts(JSThread *thread, const icu::number::FormattedNumber &formatted, const JSHandle &receiver, + const JSHandle &numberFormat, JSTaggedValue x) +{ + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString formattedText = formatted.toString(status); + if (U_FAILURE(status)) { // NOLINT(readability-implicit-bool-conversion) + THROW_TYPE_ERROR(thread, "formattedNumber toString failed"); + } + ASSERT(x.IsNumber()); + + StyleOption styleOption = static_cast(numberFormat->GetStyle().GetInt()); + + icu::ConstrainedFieldPosition cfpo; + // Set constrainCategory to UFIELD_CATEGORY_NUMBER which is specified for UNumberFormatFields + cfpo.constrainCategory(UFIELD_CATEGORY_NUMBER); + auto globalConst = thread->GlobalConstants(); + JSMutableHandle typeString(thread, JSTaggedValue::Undefined()); + int index = 0; + int previousLimit = 0; + /** + * From ICU header file document @unumberformatter.h + * Sets a constraint on the field category. + * + * When this instance of ConstrainedFieldPosition is passed to FormattedValue#nextPosition, + * positions are skipped unless they have the given category. + * + * Any previously set constraints are cleared. + * + * For example, to loop over only the number-related fields: + * + * ConstrainedFieldPosition cfpo; + * cfpo.constrainCategory(UFIELDCATEGORY_NUMBER_FORMAT); + * while (fmtval.nextPosition(cfpo, status)) { + * // handle the number-related field position + * } + */ + bool lastFieldGroup = false; + int groupLeapLength = 0; + while (formatted.nextPosition(cfpo, status)) { + int32_t fieldId = cfpo.getField(); + int32_t start = cfpo.getStart(); + int32_t limit = cfpo.getLimit(); + typeString.Update(globalConst->GetLiteralString()); + // If start greater than previousLimit, means a literal type exists before number fields + // so add a literal type with value of formattedText.sub(0, start) + // Special case when fieldId is UNUM_GROUPING_SEPARATOR_FIELD + if (static_cast(fieldId) == UNUM_GROUPING_SEPARATOR_FIELD) { + JSHandle substring = JSLocale::IcuToString(thread, formattedText, previousLimit, start); + typeString.Update(globalConst->GetIntegerString()); + JSLocale::PutElement(thread, index, receiver, typeString, JSHandle::Cast(substring)); + RETURN_IF_ABRUPT_COMPLETION(thread); + index++; + { + typeString.Update(JSLocale::GetNumberFieldType(thread, x, fieldId).GetTaggedValue()); + substring = JSLocale::IcuToString(thread, formattedText, start, limit); + JSLocale::PutElement(thread, index, receiver, typeString, JSHandle::Cast(substring)); + RETURN_IF_ABRUPT_COMPLETION(thread); + index++; + } + lastFieldGroup = true; + groupLeapLength = start - previousLimit + 1; + previousLimit = limit; + continue; + } else if (start > previousLimit) { + JSHandle substring = JSLocale::IcuToString(thread, formattedText, previousLimit, start); + JSLocale::PutElement(thread, index, receiver, typeString, JSHandle::Cast(substring)); + RETURN_IF_ABRUPT_COMPLETION(thread); + index++; + } + if (lastFieldGroup) { + start = start + groupLeapLength; + lastFieldGroup = false; + } + // Special case in ICU when style is unit and unit is percent + if (styleOption == StyleOption::UNIT && static_cast(fieldId) == UNUM_PERCENT_FIELD) { + typeString.Update(globalConst->GetUnitString()); + } else { + typeString.Update(JSLocale::GetNumberFieldType(thread, x, fieldId).GetTaggedValue()); + } + JSHandle substring = JSLocale::IcuToString(thread, formattedText, start, limit); + JSLocale::PutElement(thread, index, receiver, typeString, JSHandle::Cast(substring)); + RETURN_IF_ABRUPT_COMPLETION(thread); + index++; + previousLimit = limit; + } + // If iterated length is smaller than formattedText.length, means a literal type exists after number fields + // so add a literal type with value of formattedText.sub(previousLimit, formattedText.length) + if (formattedText.length() > previousLimit) { + typeString.Update(globalConst->GetLiteralString()); + JSHandle substring = + JSLocale::IcuToString(thread, formattedText, previousLimit, formattedText.length()); + JSLocale::PutElement(thread, index, receiver, typeString, JSHandle::Cast(substring)); + } +} + +// 12.1.9 FormatNumericToParts( numberFormat, x ) +JSHandle JSNumberFormat::FormatNumericToParts(JSThread *thread, const JSHandle &numberFormat, + JSTaggedValue x) +{ + ASSERT(x.IsNumber()); + icu::number::LocalizedNumberFormatter *icuNumberFormatter = numberFormat->GetIcuCallTarget(); + ASSERT(icuNumberFormatter != nullptr); + + UErrorCode status = U_ZERO_ERROR; + double number = x.GetNumber(); + icu::number::FormattedNumber formattedNumber = icuNumberFormatter->formatDouble(number, status); + if (U_FAILURE(status)) { + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle emptyArray = factory->NewJSArray(); + THROW_RANGE_ERROR_AND_RETURN(thread, "icu formatter format failed", emptyArray); + } + + JSHandle arr = JSArray::ArrayCreate(thread, JSTaggedNumber(0)); + JSHandle result = JSHandle::Cast(arr); + GroupToParts(thread, formattedNumber, result, numberFormat, x); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSArray, thread); + return result; +} + +// 12.1.12 UnwrapNumberFormat( nf ) +JSHandle JSNumberFormat::UnwrapNumberFormat(JSThread *thread, const JSHandle &nf) +{ + // 1. Assert: Type(nf) is Object. + ASSERT(nf->IsJSObject()); + + // 2. If nf does not have an [[InitializedNumberFormat]] internal slot and ? + // InstanceofOperator(nf, %NumberFormat%) is true, then Let nf be ? Get(nf, %Intl%.[[FallbackSymbol]]). + JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); + bool hasIstance = JSObject::InstanceOf(thread, nf, env->GetNumberFormatFunction()); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSHandle(thread, JSTaggedValue::Undefined())); + + bool isJSNumberFormat = nf->IsJSNumberFormat(); + // If nf does not have an [[InitializedNumberFormat]] internal slot and ? + // InstanceofOperator(nf, %NumberFormat%) is true, then + // a. Let nf be ? Get(nf, %Intl%.[[FallbackSymbol]]). + if (!isJSNumberFormat && hasIstance) { + JSHandle key(thread, JSHandle::Cast(env->GetIntlFunction())->GetFallbackSymbol()); + OperationResult operationResult = JSTaggedValue::GetProperty(thread, nf, key); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSHandle(thread, JSTaggedValue::Undefined())); + return operationResult.GetValue(); + } + // 3. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]). + if (!isJSNumberFormat) { + THROW_TYPE_ERROR_AND_RETURN(thread, "this is not object", + JSHandle(thread, JSTaggedValue::Exception())); + } + return nf; +} + +JSHandle JSNumberFormat::GetAvailableLocales(JSThread *thread) +{ + JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); + JSHandle numberFormatLocales = env->GetNumberFormatLocales(); + if (!numberFormatLocales->IsUndefined()) { + return JSHandle::Cast(numberFormatLocales); + } + const char *key = "NumberElements"; + const char *path = nullptr; + JSHandle availableLocales = JSLocale::GetAvailableLocales(thread, key, path); + env->SetNumberFormatLocales(thread, availableLocales); + return availableLocales; +} + +void JSNumberFormat::ResolvedOptions(JSThread *thread, const JSHandle &numberFormat, + const JSHandle &options) +{ + // Table 5: Resolved Options of NumberFormat Instances + // Internal Slot Property + // [[Locale]] "locale" + // [[NumberingSystem]] "numberingSystem" + // [[Style]] "style" + // [[Currency]] "currency" + // [[CurrencyDisplay]] "currencyDisplay" + // [[CurrencySign]] "currencySign" + // [[Unit]] "unit" + // [[UnitDisplay]] "unitDisplay" + // [[MinimumIntegerDigits]] "minimumIntegerDigits" + // [[MinimumFractionDigits]] "minimumFractionDigits" + // [[MaximumFractionDigits]] "maximumFractionDigits" + // [[MinimumSignificantDigits]] "minimumSignificantDigits" + // [[MaximumSignificantDigits]] "maximumSignificantDigits" + // [[UseGrouping]] "useGrouping" + // [[Notation]] "notation" + // [[CompactDisplay]] "compactDisplay" + // [SignDisplay]] "signDisplay" + // [[Locale]] + auto globalConst = thread->GlobalConstants(); + JSHandle property = globalConst->GetHandledLocaleString(); + JSHandle locale(thread, numberFormat->GetLocale()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, locale); + + // [[NumberingSystem]] + JSHandle numberingSystem(thread, numberFormat->GetNumberingSystem()); + if (numberingSystem->IsUndefined()) { + numberingSystem = globalConst->GetHandledLatnString(); + } + property = globalConst->GetHandledNumberingSystemString(); + JSObject::CreateDataPropertyOrThrow(thread, options, property, numberingSystem); + + // [[Style]] + StyleOption style = static_cast(numberFormat->GetStyle().GetInt()); + property = globalConst->GetHandledStyleString(); + JSHandle styleString = OptionToEcmaString(thread, style); + JSObject::CreateDataPropertyOrThrow(thread, options, property, styleString); + + // [[currency]] + JSHandle currency(thread, JSTaggedValue::Undefined()); + // If style is not currency the currency should be undefined + if (style == StyleOption::CURRENCY) { + currency = JSHandle(thread, numberFormat->GetCurrency()); + } + if (!currency->IsUndefined()) { // NOLINT(readability-implicit-bool-conversion) + property = globalConst->GetHandledCurrencyString(); + JSObject::CreateDataPropertyOrThrow(thread, options, property, currency); + + // [[CurrencyDisplay]] + property = globalConst->GetHandledCurrencyDisplayString(); + CurrencyDisplayOption currencyDisplay = + static_cast(numberFormat->GetCurrencyDisplay().GetInt()); + JSHandle currencyDisplayString = OptionToEcmaString(thread, currencyDisplay); + JSObject::CreateDataPropertyOrThrow(thread, options, property, currencyDisplayString); + + // [[CurrencySign]] + property = globalConst->GetHandledCurrencySignString(); + CurrencySignOption currencySign = static_cast(numberFormat->GetCurrencySign().GetInt()); + JSHandle currencySignString = OptionToEcmaString(thread, currencySign); + JSObject::CreateDataPropertyOrThrow(thread, options, property, currencySignString); + } + + if (style == StyleOption::UNIT) { + JSHandle unit(thread, numberFormat->GetUnit()); + if (!unit->IsUndefined()) { + // [[Unit]] + property = globalConst->GetHandledUnitString(); + JSObject::CreateDataPropertyOrThrow(thread, options, property, unit); + } + // [[UnitDisplay]] + property = globalConst->GetHandledUnitDisplayString(); + UnitDisplayOption unitDisplay = static_cast(numberFormat->GetUnitDisplay().GetInt()); + JSHandle unitDisplayString = OptionToEcmaString(thread, unitDisplay); + JSObject::CreateDataPropertyOrThrow(thread, options, property, unitDisplayString); + } + // [[MinimumIntegerDigits]] + property = globalConst->GetHandledMinimumIntegerDigitsString(); + JSHandle minimumIntegerDigits(thread, numberFormat->GetMinimumIntegerDigits()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, minimumIntegerDigits); + + RoundingType roundingType = static_cast(numberFormat->GetRoundingType().GetInt()); + if (roundingType == RoundingType::SIGNIFICANTDIGITS) { + // [[MinimumSignificantDigits]] + property = globalConst->GetHandledMinimumSignificantDigitsString(); + JSHandle minimumSignificantDigits(thread, numberFormat->GetMinimumSignificantDigits()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, minimumSignificantDigits); + // [[MaximumSignificantDigits]] + property = globalConst->GetHandledMaximumSignificantDigitsString(); + JSHandle maximumSignificantDigits(thread, numberFormat->GetMaximumSignificantDigits()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, maximumSignificantDigits); + } else { + // [[MinimumFractionDigits]] + property = globalConst->GetHandledMinimumFractionDigitsString(); + JSHandle minimumFractionDigits(thread, numberFormat->GetMinimumFractionDigits()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, minimumFractionDigits); + // [[MaximumFractionDigits]] + property = globalConst->GetHandledMaximumFractionDigitsString(); + JSHandle maximumFractionDigits(thread, numberFormat->GetMaximumFractionDigits()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, maximumFractionDigits); + } + + // [[UseGrouping]] + property = globalConst->GetHandledUserGroupingString(); + JSObject::CreateDataPropertyOrThrow(thread, options, property, + JSHandle(thread, numberFormat->GetUseGrouping())); + + // [[Notation]] + property = globalConst->GetHandledNotationString(); + NotationOption notation = static_cast(numberFormat->GetNotation().GetInt()); + JSHandle notationString = OptionToEcmaString(thread, notation); + JSObject::CreateDataPropertyOrThrow(thread, options, property, notationString); + + // Only output compactDisplay when notation is compact. + if (notation == NotationOption::COMPACT) { + // [[CompactDisplay]] + property = globalConst->GetHandledCompactDisplayString(); + CompactDisplayOption compactDisplay = + static_cast(numberFormat->GetCompactDisplay().GetInt()); + JSHandle compactDisplayString = OptionToEcmaString(thread, compactDisplay); + JSObject::CreateDataPropertyOrThrow(thread, options, property, compactDisplayString); + } + + // [[SignDisplay]] + property = globalConst->GetHandledSignDisplayString(); + SignDisplayOption signDisplay = static_cast(numberFormat->GetSignDisplay().GetInt()); + JSHandle signDisplayString = OptionToEcmaString(thread, signDisplay); + JSObject::CreateDataPropertyOrThrow(thread, options, property, signDisplayString); +} +} // namespace panda::ecmascript \ No newline at end of file diff --git a/ecmascript/js_number_format.h b/ecmascript/js_number_format.h new file mode 100644 index 0000000000000000000000000000000000000000..bf0791b9c87366711cdbac0d3c715e19c881580f --- /dev/null +++ b/ecmascript/js_number_format.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_JS_NUMBER_FORMAT_H +#define ECMASCRIPT_JS_NUMBER_FORMAT_H + +#include "global_env.h" +#include "js_array.h" +#include "js_hclass.h" +#include "js_intl.h" +#include "js_locale.h" +#include "js_object.h" + +namespace panda::ecmascript { +enum class StyleOption : uint8_t { DECIMAL = 0x01, CURRENCY, PERCENT, UNIT, EXCEPTION }; + +enum class CompactDisplayOption : uint8_t { SHORT = 0x01, LONG, EXCEPTION }; + +enum class SignDisplayOption : uint8_t { AUTO = 0x01, ALWAYS, NEVER, EXCEPTZERO, EXCEPTION }; + +enum class CurrencyDisplayOption : uint8_t { CODE = 0x01, SYMBOL, NARROWSYMBOL, NAME, EXCEPTION }; + +enum class CurrencySignOption : uint8_t { STANDARD = 0x01, ACCOUNTING, EXCEPTION }; + +enum class UnitDisplayOption : uint8_t { SHORT = 0x01, NARROW, LONG, EXCEPTION }; + +struct FractionDigitsOption { + int32_t mnfdDefault = 0; + int32_t mxfdDefault = 0; +}; + +static const std::set sanctionedUnit({ "acre", "bit", "byte", "celsius", "centimeter", "day", "degree", + "fahrenheit", "fluid-ounce", "foot", "gallon", "gigabit", "gigabyte", + "gram", "hectare", "hour", "inch", "kilobit", "kilobyte", "kilogram", + "kilometer", "liter", "megabit", "megabyte", "meter", "mile", + "mile-scandinavian", "millimeter", "milliliter", "millisecond", + "minute", "month", "ounce", "percent", "petabyte", "pound", "second", + "stone", "terabit", "terabyte", "week", "yard", "year" }); + +class JSNumberFormat : public JSObject { +public: + static JSNumberFormat *Cast(ObjectHeader *object) + { + ASSERT(JSTaggedValue(object).IsJSNumberFormat()); + return reinterpret_cast(object); + } + + static constexpr size_t LOCALE_OFFSET = JSObject::SIZE; + + ACCESSORS(Locale, LOCALE_OFFSET, NUMBER_STRING_SYSTEM_OFFSET) + ACCESSORS(NumberingSystem, NUMBER_STRING_SYSTEM_OFFSET, STYLE_OFFSET) + ACCESSORS(Style, STYLE_OFFSET, CURRENCY_OFFSET) + ACCESSORS(Currency, CURRENCY_OFFSET, CURRENCY_DISPLAY_OFFSET) + ACCESSORS(CurrencyDisplay, CURRENCY_DISPLAY_OFFSET, CURRENCY_SIGN_OFFSET) + ACCESSORS(CurrencySign, CURRENCY_SIGN_OFFSET, UNIT_OFFSET) + ACCESSORS(Unit, UNIT_OFFSET, UNIT_DISPLAY_OFFSET) + ACCESSORS(UnitDisplay, UNIT_DISPLAY_OFFSET, MINIMUM_INTEGER_DIGITS_OFFSET) + ACCESSORS(MinimumIntegerDigits, MINIMUM_INTEGER_DIGITS_OFFSET, MINIMUM_FRACTION_DIGITS_OFFSET) + ACCESSORS(MinimumFractionDigits, MINIMUM_FRACTION_DIGITS_OFFSET, MAXIMUM_FRACTION_DIGITS_OFFSET) + ACCESSORS(MaximumFractionDigits, MAXIMUM_FRACTION_DIGITS_OFFSET, MININUM_SIGNIFICANT_DIGITS_OFFSET) + ACCESSORS(MinimumSignificantDigits, MININUM_SIGNIFICANT_DIGITS_OFFSET, MAXINUM_SIGNIFICANT_DIGITS_OFFSET) + ACCESSORS(MaximumSignificantDigits, MAXINUM_SIGNIFICANT_DIGITS_OFFSET, USER_GROUPING_OFFSET) + ACCESSORS(UseGrouping, USER_GROUPING_OFFSET, ROUNDING_TYPE_OFFSET) + ACCESSORS(RoundingType, ROUNDING_TYPE_OFFSET, NOTATION_OFFSET) + ACCESSORS(Notation, NOTATION_OFFSET, COMPACT_DISPLAY_OFFSET) + ACCESSORS(CompactDisplay, COMPACT_DISPLAY_OFFSET, SIGN_DISPLAY_OFFSET) + ACCESSORS(SignDisplay, SIGN_DISPLAY_OFFSET, ICU_NUMBER_FORMAT_OFFSET) + ACCESSORS(BoundFormat, ICU_NUMBER_FORMAT_OFFSET, BOUND_FORMAT_OFFSET) + + // icu field. + ACCESSORS(IcuField, BOUND_FORMAT_OFFSET, SIZE) + + DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE) + + icu::number::LocalizedNumberFormatter *GetIcuCallTarget() const + { + ASSERT(GetIcuField().IsJSNativePointer()); + auto result = JSNativePointer::Cast(GetIcuField().GetTaggedObject())->GetExternalPointer(); + return reinterpret_cast(result); + } + + static void FreeIcuNumberformat(void *pointer, void *data) + { + if (pointer == nullptr) { + return; + } + auto icuNumberformat = reinterpret_cast(pointer); + icuNumberformat->~LocalizedNumberFormatter(); + if (data != nullptr) { + reinterpret_cast(data)->GetRegionFactory()->FreeBuffer(pointer); + } + } + + // 12.1.2 InitializeNumberFormat ( numberFormat, locales, options ) + static void InitializeNumberFormat(JSThread *thread, const JSHandle &numberFormat, + const JSHandle &locales, const JSHandle &options); + + // 12.1.3 CurrencyDigits ( currency ) + static int32_t CurrencyDigits(const icu::UnicodeString ¤cy); + + // 12.1.8 FormatNumeric( numberFormat, x ) + static JSHandle FormatNumeric(JSThread *thread, const JSHandle &numberFormat, + JSTaggedValue x); + + // 12.1.9 FormatNumericToParts( numberFormat, x ) + static JSHandle FormatNumericToParts(JSThread *thread, const JSHandle &numberFormat, + JSTaggedValue x); + + // 12.1.12 UnwrapNumberFormat( nf ) + static JSHandle UnwrapNumberFormat(JSThread *thread, const JSHandle &nf); + + static JSHandle GetAvailableLocales(JSThread *thread); + static void ResolvedOptions(JSThread *thread, const JSHandle &numberFormat, + const JSHandle &options); + + template + static icu::number::LocalizedNumberFormatter SetICUFormatterDigitOptions( + icu::number::LocalizedNumberFormatter &icuNumberformatter, const JSHandle &formatter) + { + int minimumIntegerDigits = formatter->GetMinimumIntegerDigits().GetInt(); + // Set ICU formatter IntegerWidth to MinimumIntegerDigits + icuNumberformatter = + icuNumberformatter.integerWidth(icu::number::IntegerWidth::zeroFillTo(minimumIntegerDigits)); + + int minimumSignificantDigits = formatter->GetMinimumSignificantDigits().GetInt(); + int maximumSignificantDigits = formatter->GetMaximumSignificantDigits().GetInt(); + int minimumFractionDigits = formatter->GetMinimumFractionDigits().GetInt(); + int maximumFractionDigits = formatter->GetMaximumFractionDigits().GetInt(); + + // If roundingtype is "compact-rounding" return ICU formatter + auto roundingType = static_cast(formatter->GetRoundingType().GetInt()); + if (roundingType == RoundingType::COMPACTROUNDING) { + return icuNumberformatter; + } + // Else, Set ICU formatter FractionDigits and SignificantDigits + // a. Set ICU formatter minFraction, maxFraction to MinimumFractionDigits, MaximumFractionDigits + icu::number::Precision precision = + icu::number::Precision::minMaxFraction(minimumFractionDigits, maximumFractionDigits); + // b. if MinimumSignificantDigits is not 0, + // Set ICU formatter minSignificantDigits, maxSignificantDigits to MinimumSignificantDigits, + // MaximumSignificantDigits + if (minimumSignificantDigits != 0) { + precision = + icu::number::Precision::minMaxSignificantDigits(minimumSignificantDigits, maximumSignificantDigits); + } + return icuNumberformatter.precision(precision); + } +}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_JS_NUMBER_FORMAT_H \ No newline at end of file diff --git a/ecmascript/js_object-inl.h b/ecmascript/js_object-inl.h index 56e59071c08bebff6d6a778fca6d10b12c834fa7..fdf6bb49e44e4b6b7084aef083db1cbc51e40662 100644 --- a/ecmascript/js_object-inl.h +++ b/ecmascript/js_object-inl.h @@ -13,12 +13,13 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSOBJECT_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_JSOBJECT_INL_H +#ifndef ECMASCRIPT_JSOBJECT_INL_H +#define ECMASCRIPT_JSOBJECT_INL_H #include "ecmascript/js_hclass-inl.h" #include "ecmascript/js_object.h" #include "ecmascript/js_tagged_value-inl.h" +#include "ecmascript/js_typed_array.h" #include "ecmascript/tagged_array-inl.h" namespace panda::ecmascript { @@ -131,6 +132,11 @@ inline bool JSObject::IsBoundFunction() const return GetJSHClass()->IsJsBoundFunction(); } +inline bool JSObject::IsJSIntlBoundFunction() const +{ + return GetJSHClass()->IsJSIntlBoundFunction(); +} + inline bool JSObject::IsProxyRevocFunction() const { return GetJSHClass()->IsJSProxyRevocFunction(); @@ -272,7 +278,7 @@ inline uint32_t JSObject::ComputePropertyCapacity(uint32_t oldCapacity) } // static -template +template JSHandle JSObject::CreateListFromArrayLike(JSThread *thread, const JSHandle &obj) { // 3. If Type(obj) is not Object, throw a TypeError exception. @@ -296,6 +302,12 @@ JSHandle JSObject::CreateListFromArrayLike(JSThread *thread, cons // 6. Let list be an empty List. JSHandle array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(len); + if (obj->IsTypedArray()) { + JSTypedArray::FastCopyElementToArray(thread, obj, array); + // c. ReturnIfAbrupt(next). + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread); + return JSHandle(array); + } // 8. Repeat while index < len for (uint32_t i = 0; i < len; i++) { JSTaggedValue next = JSTaggedValue::GetProperty(thread, obj, i).GetValue().GetTaggedValue(); @@ -314,4 +326,4 @@ JSHandle JSObject::CreateListFromArrayLike(JSThread *thread, cons return JSHandle(array); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSOBJECT_INL_H +#endif // ECMASCRIPT_JSOBJECT_INL_H diff --git a/ecmascript/js_object.cpp b/ecmascript/js_object.cpp index 2f724cf18e5a8ed8afa4861d4c34ca513b1cae4b..d8fb6ff1427c3d4597de5efe4d95116f8bb26e56 100644 --- a/ecmascript/js_object.cpp +++ b/ecmascript/js_object.cpp @@ -17,6 +17,7 @@ #include "ecmascript/ecma_macros.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/fast_runtime_stub-inl.h" #include "ecmascript/js_primitive_ref.h" #include "ecmascript/js_thread.h" @@ -68,11 +69,11 @@ JSMethod *ECMAObject::GetCallTarget() const JSHandle JSObject::GrowElementsCapacity(const JSThread *thread, const JSHandle &obj, uint32_t capacity) { - capacity = ComputeElementCapacity(capacity); + uint32_t newCapacity = ComputeElementCapacity(capacity); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle oldElements(thread, obj->GetElements()); array_size_t oldLength = oldElements->GetLength(); - JSHandle newElements = factory->CopyArray(oldElements, oldLength, capacity); + JSHandle newElements = factory->CopyArray(oldElements, oldLength, newCapacity); obj->SetElements(thread, newElements); return newElements; @@ -218,7 +219,7 @@ bool JSObject::AddElementInternal(JSThread *thread, const JSHandle &re void JSObject::DeletePropertyInternal(JSThread *thread, const JSHandle &obj, const JSHandle &key, uint32_t index) { - JSMutableHandle array(thread, obj->GetProperties()); + JSHandle array(thread, obj->GetProperties()); if (obj->IsJSGlobalObject()) { JSHandle dictHandle(thread, obj->GetProperties()); @@ -426,6 +427,7 @@ bool JSObject::GlobalSetProperty(JSThread *thread, const JSHandle } return SetProperty(&op, value, mayThrow); } + uint32_t JSObject::GetNumberOfElements() { DISALLOW_GARBAGE_COLLECTION; @@ -620,9 +622,10 @@ bool JSObject::CallSetter(JSThread *thread, const AccessorData &accessor, const } JSHandle func(thread, setter); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(1); - args->Set(thread, 0, value); - JSFunction::Call(thread, func, receiver, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(value); + JSFunction::Call(thread, func, receiver, 1, arguments->GetArgv()); + // 10. ReturnIfAbrupt(setterResult). RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); @@ -639,8 +642,7 @@ JSTaggedValue JSObject::CallGetter(JSThread *thread, const AccessorData *accesso } JSHandle func(thread, getter); - JSHandle args = thread->GetEcmaVM()->GetFactory()->EmptyArray(); - JSTaggedValue res = JSFunction::Call(thread, func, receiver, args); + JSTaggedValue res = JSFunction::Call(thread, func, receiver, 0, nullptr); RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); return res; } @@ -1271,12 +1273,12 @@ JSHandle JSObject::EnumerableOwnNames(JSThread *thread, const JSHan if (tagObj->IsJSObject() && !tagObj->IsTypedArray()) { uint32_t numOfKeys = obj->GetNumberOfKeys(); uint32_t numOfElements = obj->GetNumberOfElements(); - JSHandle keyArray; JSHandle elementArray; if (numOfElements > 0) { elementArray = JSObject::GetEnumElementKeys(thread, obj, 0, numOfElements, ©Length); } + JSHandle keyArray; if (numOfKeys > 0) { keyArray = JSObject::GetAllEnumKeys(thread, obj, 0, numOfKeys, ©Length); } @@ -1293,7 +1295,7 @@ JSHandle JSObject::EnumerableOwnNames(JSThread *thread, const JSHan return keys; } - keys = JSTaggedValue::GetOwnPropertyKeys(thread, JSHandle(obj)); + keys = JSTaggedValue::GetOwnPropertyKeys(thread, tagObj); RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread); array_size_t length = keys->GetLength(); @@ -1312,8 +1314,7 @@ JSHandle JSObject::EnumerableOwnNames(JSThread *thread, const JSHan } } - JSHandle resultList = factory->CopyArray(names, length, copyLength); - return resultList; + return factory->CopyArray(names, length, copyLength); } JSHandle JSObject::EnumerableOwnPropertyNames(JSThread *thread, const JSHandle &obj, @@ -1428,9 +1429,10 @@ bool JSObject::InstanceOf(JSThread *thread, const JSHandle &objec // 4. If instOfHandler is not undefined, then if (!instOfHandler->IsUndefined()) { // a. Return ! ToBoolean(? Call(instOfHandler, target, «object»)). - JSHandle arguments = vm->GetFactory()->NewTaggedArray(1); - arguments->Set(thread, 0, object.GetTaggedValue()); - JSTaggedValue tagged = JSFunction::Call(thread, instOfHandler, target, arguments); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(object); + JSTaggedValue tagged = JSFunction::Call(thread, instOfHandler, target, 1, arguments->GetArgv()); + return tagged.ToBoolean(); } @@ -1901,4 +1903,85 @@ bool JSObject::UpdatePropertyInDictionary(const JSThread *thread, JSTaggedValue dict->UpdateValue(thread, entry, value); return true; } + +void ECMAObject::SetHash(int32_t hash) +{ + JSTaggedType hashField = Barriers::GetDynValue(this, HASH_OFFSET); + JSTaggedValue value(hashField); + if (value.IsHeapObject()) { + JSThread *thread = this->GetJSThread(); + ASSERT(value.IsTaggedArray()); + TaggedArray *array = TaggedArray::Cast(value.GetHeapObject()); + array->Set(thread, 0, JSTaggedValue(hash)); + } else { + Barriers::SetDynPrimitive(this, HASH_OFFSET, JSTaggedValue(hash).GetRawData()); + } +} + +int32_t ECMAObject::GetHash() const +{ + JSTaggedType hashField = Barriers::GetDynValue(this, HASH_OFFSET); + JSTaggedValue value(hashField); + if (value.IsHeapObject()) { + TaggedArray *array = TaggedArray::Cast(value.GetHeapObject()); + return array->Get(0).GetInt(); + } + JSThread *thread = this->GetJSThread(); + JSHandle valueHandle(thread, value); + return JSTaggedValue::ToInt32(thread, valueHandle); +} + +void *ECMAObject::GetNativePointerField(int32_t index) const +{ + JSTaggedType hashField = Barriers::GetDynValue(this, HASH_OFFSET); + JSTaggedValue value(hashField); + if (value.IsHeapObject()) { + JSThread *thread = this->GetJSThread(); + JSHandle array(thread, value); + if (static_cast(array->GetLength()) > index + 1) { + JSHandle pointer(thread, array->Get(index + 1)); + return pointer->GetExternalPointer(); + } + } + return nullptr; +} + +void ECMAObject::SetNativePointerField(int32_t index, void *data) +{ + JSTaggedType hashField = Barriers::GetDynValue(this, HASH_OFFSET); + JSTaggedValue value(hashField); + if (value.IsHeapObject()) { + JSThread *thread = this->GetJSThread(); + JSHandle array(thread, value); + if (static_cast(array->GetLength()) > index + 1) { + JSHandle pointer = thread->GetEcmaVM()->GetFactory()->NewJSNativePointer(data); + array->Set(thread, index + 1, pointer.GetTaggedValue()); + } + } +} + +int32_t ECMAObject::GetNativePointerFieldCount() const +{ + int32_t len = 0; + JSTaggedType hashField = Barriers::GetDynValue(this, HASH_OFFSET); + JSTaggedValue value(hashField); + if (value.IsHeapObject()) { + TaggedArray *array = TaggedArray::Cast(value.GetHeapObject()); + len = array->GetLength() - 1; + } + return len; +} + +void ECMAObject::SetNativePointerFieldCount(int32_t count) +{ + JSTaggedType hashField = Barriers::GetDynValue(this, HASH_OFFSET); + JSTaggedValue value(hashField); + if (!value.IsHeapObject()) { + JSThread *thread = this->GetJSThread(); + JSHandle obj(thread, this); + JSHandle newArray = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(count + 1); + newArray->Set(thread, 0, value); + Barriers::SetDynObject(thread, *obj, HASH_OFFSET, newArray.GetTaggedValue().GetRawData()); + } +} } // namespace panda::ecmascript diff --git a/ecmascript/js_object.h b/ecmascript/js_object.h index 3c71344e2e8fd1deea2b56582071d702b9e380ec..127658b16b22c08e96218626b778c752bbb04b9f 100644 --- a/ecmascript/js_object.h +++ b/ecmascript/js_object.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSOBJECT_H -#define PANDA_RUNTIME_ECMASCRIPT_JSOBJECT_H +#ifndef ECMASCRIPT_JSOBJECT_H +#define ECMASCRIPT_JSOBJECT_H #include @@ -29,6 +29,7 @@ #include "ecmascript/mem/slots.h" #include "ecmascript/object_operator.h" #include "ecmascript/property_attributes.h" +#include "ecmascript/runtime_trampolines.h" #include "ecmascript/tagged_array.h" namespace panda { @@ -333,20 +334,21 @@ public: bool IsCallable() const; JSMethod *GetCallTarget() const; - static constexpr size_t HASH_OFFSET = sizeof(TaggedObject); - static constexpr size_t SIZE = HASH_OFFSET + sizeof(TaggedObject); - void SetHash(int32_t hash) - { - Barriers::SetDynPrimitive(this, HASH_OFFSET, hash); - } - int32_t GetHash() const - { - return Barriers::GetDynValue(this, HASH_OFFSET); - } + static constexpr size_t HASH_OFFSET = TaggedObjectSize(); + static constexpr size_t SIZE = HASH_OFFSET + sizeof(JSTaggedType); - void Visitor([[maybe_unused]] const EcmaObjectRangeVisitor &visitor) const + void SetHash(int32_t hash); + int32_t GetHash() const; + + void* GetNativePointerField(int32_t index) const; + void SetNativePointerField(int32_t index, void *data); + int32_t GetNativePointerFieldCount() const; + void SetNativePointerFieldCount(int32_t count); + + void Visitor(const EcmaObjectRangeVisitor &visitor) const { - // no field in this object + TaggedObject *object = const_cast(reinterpret_cast(this)); + visitor(object, ObjectSlot(ToUintPtr(this) + HASH_OFFSET), ObjectSlot(ToUintPtr(this) + SIZE)); } void VisitObjects([[maybe_unused]] const EcmaObjectRangeVisitor &visitor) const @@ -419,7 +421,7 @@ public: static JSHandle SpeciesConstructor(JSThread *thread, const JSHandle &obj, const JSHandle &defaultConstructort); // 7.3.17 - template + template static JSHandle CreateListFromArrayLike(JSThread *thread, const JSHandle &obj); // emca6 9.1 @@ -535,6 +537,7 @@ public: bool IsJSRegExp() const; bool IsJSFunction() const; bool IsBoundFunction() const; + bool IsJSIntlBoundFunction() const; bool IsProxyRevocFunction() const; bool IsAccessorData() const; bool IsJSGlobalEnv() const; @@ -621,6 +624,7 @@ private: friend class StoreICRuntime; friend class FastRuntimeStub; friend class ICRuntimeStub; + friend class RuntimeTrampolines; static bool AddElementInternal( JSThread *thread, const JSHandle &receiver, uint32_t index, const JSHandle &value, diff --git a/ecmascript/js_plural_rules.cpp b/ecmascript/js_plural_rules.cpp new file mode 100644 index 0000000000000000000000000000000000000000..73d93826a1664185d9454c4f05b96d86a2208bef --- /dev/null +++ b/ecmascript/js_plural_rules.cpp @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "ecmascript/js_plural_rules.h" + +#include "ecmascript/ecma_macros.h" +#include "ecmascript/global_env.h" +#include "ecmascript/global_env_constants.h" +#include "ecmascript/js_number_format.h" + +namespace panda::ecmascript { +enum class TypeOption : uint8_t { CARDINAL = 0x01, ORDINAL, EXCEPTION }; + +constexpr int32_t STRING_SEPARATOR_LENGTH = 4; + +icu::number::LocalizedNumberFormatter *JSPluralRules::GetIcuNumberFormatter() const +{ + ASSERT(GetIcuNF().IsJSNativePointer()); + auto result = JSNativePointer::Cast(GetIcuNF().GetTaggedObject())->GetExternalPointer(); + return reinterpret_cast(result); +} + +void JSPluralRules::FreeIcuNumberFormatter(void *pointer, [[maybe_unused]] void* hint) +{ + if (pointer == nullptr) { + return; + } + auto icuNumberFormatter = reinterpret_cast(pointer); + icuNumberFormatter->~LocalizedNumberFormatter(); +} + +void JSPluralRules::SetIcuNumberFormatter(JSThread *thread, const icu::number::LocalizedNumberFormatter &icuNF, + const DeleteEntryPoint &callback) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + icu::number::LocalizedNumberFormatter *icuPointer = + ecmaVm->GetRegionFactory()->New(icuNF); + ASSERT(icuPointer != nullptr); + JSTaggedValue data = GetIcuNF(); + if (data.IsHeapObject() && data.IsJSNativePointer()) { + JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject()); + native->ResetExternalPointer(icuPointer); + return; + } + JSHandle pointer = factory->NewJSNativePointer(icuPointer); + pointer->SetDeleter(callback); + SetIcuNF(thread, pointer.GetTaggedValue()); + ecmaVm->PushToArrayDataList(*pointer); +} + +icu::PluralRules *JSPluralRules::GetIcuPluralRules() const +{ + ASSERT(GetIcuPR().IsJSNativePointer()); + auto result = JSNativePointer::Cast(GetIcuPR().GetTaggedObject())->GetExternalPointer(); + return reinterpret_cast(result); +} + +void JSPluralRules::FreeIcuPluralRules(void *pointer, [[maybe_unused]] void* hint) +{ + if (pointer == nullptr) { + return; + } + auto icuPluralRules = reinterpret_cast(pointer); + icuPluralRules->~PluralRules(); +} + +void JSPluralRules::SetIcuPluralRules(JSThread *thread, const icu::PluralRules &icuPR, const DeleteEntryPoint &callback) +{ + [[maybe_unused]] EcmaHandleScope scope(thread); + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + icu::PluralRules *icuPointer = ecmaVm->GetRegionFactory()->New(icuPR); + ASSERT(icuPointer != nullptr); + JSTaggedValue data = GetIcuPR(); + if (data.IsHeapObject() && data.IsJSNativePointer()) { + JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject()); + native->ResetExternalPointer(icuPointer); + return; + } + JSHandle pointer = factory->NewJSNativePointer(icuPointer); + pointer->SetDeleter(callback); + SetIcuPR(thread, pointer.GetTaggedValue()); + ecmaVm->PushToArrayDataList(*pointer); +} + +JSHandle JSPluralRules::BuildLocaleSet(JSThread *thread, const std::set &icuAvailableLocales) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + JSHandle locales = factory->NewTaggedArray(icuAvailableLocales.size()); + int32_t index = 0; + + for (const std::string &locale : icuAvailableLocales) { + JSHandle localeStr = factory->NewFromStdString(locale); + locales->Set(thread, index++, localeStr); + } + return locales; +} + +bool GetNextLocale(icu::StringEnumeration *locales, std::string &localeStr, int32_t *len) +{ + UErrorCode status = U_ZERO_ERROR; + const char *locale = nullptr; + locale = locales->next(len, status); + if (!U_SUCCESS(status) || locale == nullptr) { + localeStr = ""; + return false; + } + localeStr = std::string(locale); + return true; +} + +JSHandle JSPluralRules::GetAvailableLocales(JSThread *thread) +{ + UErrorCode status = U_ZERO_ERROR; + std::unique_ptr locales(icu::PluralRules::getAvailableLocales(status)); + ASSERT(U_SUCCESS(status)); + std::set set; + std::string localeStr; + int32_t len = 0; + while (GetNextLocale(locales.get(), localeStr, &len)) { + if (len >= STRING_SEPARATOR_LENGTH) { + std::replace(localeStr.begin(), localeStr.end(), '_', '-'); + } + set.insert(localeStr); + } + return BuildLocaleSet(thread, set); +} + +// InitializePluralRules ( pluralRules, locales, options ) +JSHandle JSPluralRules::InitializePluralRules(JSThread *thread, + const JSHandle &pluralRules, + const JSHandle &locales, + const JSHandle &options) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + auto globalConst = thread->GlobalConstants(); + + // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSPluralRules, thread); + + // 2&3. If options is undefined, then Let options be ObjectCreate(null). else Let options be ? ToObject(options). + JSHandle prOptions; + if (!options->IsUndefined()) { + prOptions = JSTaggedValue::ToObject(thread, options); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSPluralRules, thread); + } else { + prOptions = factory->OrdinaryNewJSObjectCreate(JSHandle(thread, JSTaggedValue::Null())); + } + + // 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + LocaleMatcherOption matcher = + JSLocale::GetOptionOfString(thread, prOptions, globalConst->GetHandledLocaleMatcherString(), + {LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT}, + {"lookup", "best fit"}, LocaleMatcherOption::BEST_FIT); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSPluralRules, thread); + + // 7. Let t be ? GetOption(options, "type", "string", « "cardinal", "ordinal" », "cardinal"). + JSHandle property = JSHandle::Cast(globalConst->GetHandledTypeString()); + TypeOption type = + JSLocale::GetOptionOfString(thread, prOptions, property, { TypeOption::CARDINAL, TypeOption::ORDINAL }, + { "cardinal", "ordinal" }, TypeOption::CARDINAL); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSPluralRules, thread); + + // set pluralRules.[[type]] to type + JSHandle typeValue; + if (type == TypeOption::CARDINAL) { + typeValue = globalConst->GetHandledCardinalString(); + } else { + typeValue = globalConst->GetHandledOrdinalString(); + } + pluralRules->SetType(thread, typeValue.GetTaggedValue()); + + // Let r be ResolveLocale(%PluralRules%.[[AvailableLocales]], requestedLocales, opt, + // %PluralRules%.[[RelevantExtensionKeys]], localeData). + JSHandle availableLocales; + if (requestedLocales->GetLength() == 0) { + availableLocales = factory->EmptyArray(); + } else { + availableLocales = GetAvailableLocales(thread); + } + std::set relevantExtensionKeys{""}; + ResolvedLocale r = + JSLocale::ResolveLocale(thread, availableLocales, requestedLocales, matcher, relevantExtensionKeys); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSPluralRules, thread); + icu::Locale icuLocale = r.localeData; + + // Get ICU numberFormatter with given locale + icu::number::LocalizedNumberFormatter icuNumberFormatter = + icu::number::NumberFormatter::withLocale(icuLocale).roundingMode(UNUM_ROUND_HALFUP); + + bool sucess = true; + UErrorCode status = U_ZERO_ERROR; + UPluralType icuType = UPLURAL_TYPE_CARDINAL; + // Trans typeOption to ICU typeOption + switch (type) { + case TypeOption::ORDINAL: + icuType = UPLURAL_TYPE_ORDINAL; + break; + case TypeOption::CARDINAL: + icuType = UPLURAL_TYPE_CARDINAL; + break; + default: + UNREACHABLE(); + } + std::unique_ptr icuPluralRules(icu::PluralRules::forLocale(icuLocale, icuType, status)); + if (U_FAILURE(status)) { // NOLINT(readability-implicit-bool-conversion) + sucess = false; + } + + // Trans typeOption to ICU typeOption + if (!sucess || icuPluralRules == nullptr) { + icu::Locale noExtensionLocale(icuLocale.getBaseName()); + status = U_ZERO_ERROR; + icuType = UPLURAL_TYPE_CARDINAL; + switch (type) { + case TypeOption::ORDINAL: + icuType = UPLURAL_TYPE_ORDINAL; + break; + case TypeOption::CARDINAL: + icuType = UPLURAL_TYPE_CARDINAL; + break; + default: + UNREACHABLE(); + } + icuPluralRules.reset(icu::PluralRules::forLocale(icuLocale, icuType, status)); + } + if (U_FAILURE(status) || icuPluralRules == nullptr) { // NOLINT(readability-implicit-bool-conversion) + THROW_RANGE_ERROR_AND_RETURN(thread, "cannot create icuPluralRules", pluralRules); + } + + // 9. Perform ? SetNumberFormatDigitOptions(pluralRules, options, 0, 3, "standard"). + JSLocale::SetNumberFormatDigitOptions(thread, pluralRules, JSHandle::Cast(prOptions), MNFD_DEFAULT, + MXFD_DEFAULT, NotationOption::STANDARD); + icuNumberFormatter = JSNumberFormat::SetICUFormatterDigitOptions(icuNumberFormatter, pluralRules); + + // Set pluralRules.[[IcuPluralRules]] to icuPluralRules + pluralRules->SetIcuPluralRules(thread, *icuPluralRules, JSPluralRules::FreeIcuPluralRules); + + // Set pluralRules.[[IcuNumberFormat]] to icuNumberFormatter + pluralRules->SetIcuNumberFormatter(thread, icuNumberFormatter, JSPluralRules::FreeIcuNumberFormatter); + + // 12. Set pluralRules.[[Locale]] to the value of r.[[locale]]. + JSHandle localeStr = JSLocale::ToLanguageTag(thread, icuLocale); + pluralRules->SetLocale(thread, localeStr.GetTaggedValue()); + + // 13. Return pluralRules. + return pluralRules; +} + +JSHandle FormatNumericToString(JSThread *thread, const icu::number::LocalizedNumberFormatter *icuFormatter, + const icu::PluralRules *icuPluralRules, double n) +{ + UErrorCode status = U_ZERO_ERROR; + icu::number::FormattedNumber formatted = icuFormatter->formatDouble(n, status); + if (U_FAILURE(status)) { // NOLINT(readability-implicit-bool-conversion) + JSHandle exception(thread, JSTaggedValue::Exception()); + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid resolve number", JSHandle::Cast(exception)); + } + + icu::UnicodeString uString = icuPluralRules->select(formatted, status); + if (U_FAILURE(status)) { // NOLINT(readability-implicit-bool-conversion) + JSHandle exception(thread, JSTaggedValue::Exception()); + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid resolve number", JSHandle::Cast(exception)); + } + + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle result = + factory->NewFromUtf16(reinterpret_cast(uString.getBuffer()), uString.length()); + return result; +} +JSHandle JSPluralRules::ResolvePlural(JSThread *thread, const JSHandle &pluralRules, + double n) +{ + icu::PluralRules *icuPluralRules = pluralRules->GetIcuPluralRules(); + icu::number::LocalizedNumberFormatter *icuFormatter = pluralRules->GetIcuNumberFormatter(); + if (icuPluralRules == nullptr || icuFormatter == nullptr) { + return JSHandle(thread, JSTaggedValue::Undefined()); + } + + JSHandle result = FormatNumericToString(thread, icuFormatter, icuPluralRules, n); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread); + return result; +} + +void JSPluralRules::ResolvedOptions(JSThread *thread, const JSHandle &pluralRules, + const JSHandle &options) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + auto globalConst = thread->GlobalConstants(); + + // [[Locale]] + JSHandle property = JSHandle::Cast(globalConst->GetHandledLocaleString()); + JSHandle locale(thread, pluralRules->GetLocale()); + PropertyDescriptor localeDesc(thread, JSHandle::Cast(locale), true, true, true); + JSObject::DefineOwnProperty(thread, options, property, localeDesc); + + // [[type]] + property = JSHandle::Cast(globalConst->GetHandledTypeString()); + PropertyDescriptor typeDesc(thread, JSHandle(thread, pluralRules->GetType()), true, true, true); + JSObject::DefineOwnProperty(thread, options, property, typeDesc); + + // [[MinimumIntegerDigits]] + property = JSHandle::Cast(globalConst->GetHandledMinimumIntegerDigitsString()); + JSHandle minimumIntegerDigits(thread, pluralRules->GetMinimumIntegerDigits()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, minimumIntegerDigits); + + RoundingType roundingType = static_cast(pluralRules->GetRoundingType().GetInt()); + if (roundingType == RoundingType::SIGNIFICANTDIGITS) { + // [[MinimumSignificantDigits]] + property = globalConst->GetHandledMinimumSignificantDigitsString(); + JSHandle minimumSignificantDigits(thread, pluralRules->GetMinimumSignificantDigits()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, minimumSignificantDigits); + // [[MaximumSignificantDigits]] + property = globalConst->GetHandledMaximumSignificantDigitsString(); + JSHandle maximumSignificantDigits(thread, pluralRules->GetMaximumSignificantDigits()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, maximumSignificantDigits); + } else { + // [[MinimumFractionDigits]] + property = globalConst->GetHandledMinimumFractionDigitsString(); + JSHandle minimumFractionDigits(thread, pluralRules->GetMinimumFractionDigits()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, minimumFractionDigits); + // [[MaximumFractionDigits]] + property = globalConst->GetHandledMaximumFractionDigitsString(); + JSHandle maximumFractionDigits(thread, pluralRules->GetMaximumFractionDigits()); + JSObject::CreateDataPropertyOrThrow(thread, options, property, maximumFractionDigits); + } + + // 5. Let pluralCategories be a List of Strings representing the possible results of PluralRuleSelect + // for the selected locale pr.[[Locale]]. This List consists of unique String values, + // from the the list "zero", "one", "two", "few", "many" and "other", + // that are relevant for the locale whose localization is specified in LDML Language Plural Rules. + UErrorCode status = U_ZERO_ERROR; + icu::PluralRules *icuPluralRules = pluralRules->GetIcuPluralRules(); + ASSERT(icuPluralRules != nullptr); + std::unique_ptr categories(icuPluralRules->getKeywords(status)); + int32_t count = categories->count(status); + ASSERT(U_SUCCESS(status)); + JSHandle pluralCategories = factory->NewTaggedArray(count); + for (int32_t i = 0; i < count; i++) { + const icu::UnicodeString *category = categories->snext(status); + ASSERT(U_SUCCESS(status)); + JSHandle value = JSLocale::IcuToString(thread, *category); + pluralCategories->Set(thread, i, value); + } + + // 6. Perform ! CreateDataProperty(options, "pluralCategories", CreateArrayFromList(pluralCategories)). + property = globalConst->GetHandledPluralCategoriesString(); + JSHandle jsPluralCategories = JSArray::CreateArrayFromList(thread, pluralCategories); + JSObject::CreateDataPropertyOrThrow(thread, options, property, JSHandle::Cast(jsPluralCategories)); +} +} // namespace panda::ecmascript diff --git a/ecmascript/js_plural_rules.h b/ecmascript/js_plural_rules.h new file mode 100644 index 0000000000000000000000000000000000000000..1e87fa0287fb286b4b24fb7c30923d17f1e595d0 --- /dev/null +++ b/ecmascript/js_plural_rules.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_JS_PLURAL_RULES_H +#define ECMASCRIPT_JS_PLURAL_RULES_H + +#include "js_array.h" +#include "js_hclass.h" +#include "js_intl.h" +#include "js_locale.h" +#include "js_object.h" +#include "js_tagged_value.h" + +namespace panda::ecmascript { +constexpr int MNFD_DEFAULT = 0; +constexpr int MXFD_DEFAULT = 3; + +class JSPluralRules : public JSObject { +public: + static JSPluralRules *Cast(ObjectHeader *object) + { + ASSERT(JSTaggedValue(object).IsJSPluralRules()); + return reinterpret_cast(object); + } + + static constexpr size_t LOCALE_OFFSET = JSObject::SIZE; + + ACCESSORS(Locale, LOCALE_OFFSET, INITIALIZED_PLURAL_RULES) + ACCESSORS(InitializedPluralRules, INITIALIZED_PLURAL_RULES, TYPE_OFFSET) + ACCESSORS(Type, TYPE_OFFSET, MININUM_INTEGER_DIGITS_OFFSET) + ACCESSORS(MinimumIntegerDigits, MININUM_INTEGER_DIGITS_OFFSET, MINIMUM_FRACTION_DIGITS_OFFSET) + ACCESSORS(MinimumFractionDigits, MINIMUM_FRACTION_DIGITS_OFFSET, MAXIMUM_FRACTION_DIGITS_OFFSET) + ACCESSORS(MaximumFractionDigits, MAXIMUM_FRACTION_DIGITS_OFFSET, MININUM_SIGNIFICANT_DIGITS_OFFSET) + ACCESSORS(MinimumSignificantDigits, MININUM_SIGNIFICANT_DIGITS_OFFSET, MAXINUM_SIGNIFICANT_DIGITS_OFFSET) + ACCESSORS(MaximumSignificantDigits, MAXINUM_SIGNIFICANT_DIGITS_OFFSET, ROUDING_TYPE_OFFSET) + ACCESSORS(RoundingType, ROUDING_TYPE_OFFSET, ICU_PLURAL_RULES_OFFSET) + ACCESSORS(IcuPR, ICU_PLURAL_RULES_OFFSET, ICU_NUMBER_FORMAT_OFFSET) + ACCESSORS(IcuNF, ICU_NUMBER_FORMAT_OFFSET, SIZE) + + DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE) + + icu::number::LocalizedNumberFormatter *GetIcuNumberFormatter() const; + + void SetIcuNumberFormatter(JSThread *thread, const icu::number::LocalizedNumberFormatter &icuNF, + const DeleteEntryPoint &callback); + + static void FreeIcuNumberFormatter(void *pointer, [[maybe_unused]] void* hint = nullptr); + + icu::PluralRules *GetIcuPluralRules() const; + + void SetIcuPluralRules(JSThread *thread, const icu::PluralRules &icuPR, const DeleteEntryPoint &callback); + + static void FreeIcuPluralRules(void *pointer, [[maybe_unused]] void* hint = nullptr); + + static JSHandle BuildLocaleSet(JSThread *thread, const std::set &icuAvailableLocales); + + static JSHandle GetAvailableLocales(JSThread *thread); + + // 15.1.1 InitializePluralRules ( pluralRules, locales, options ) + static JSHandle InitializePluralRules(JSThread *thread, const JSHandle &pluralRules, + const JSHandle &locales, + const JSHandle &options); + + // 15.1.4 ResolvePlural ( pluralRules, n ) + static JSHandle ResolvePlural(JSThread *thread, const JSHandle &pluralRules, double n); + + static void ResolvedOptions(JSThread *thread, const JSHandle &pluralRules, + const JSHandle &options); +}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_JS_PLURAL_RULES_H \ No newline at end of file diff --git a/ecmascript/js_primitive_ref.h b/ecmascript/js_primitive_ref.h index 27b727ed56865ed84fc54b1dff04124091e70e30..7564629ec5496f6fc3f4468b610579c8c280588a 100644 --- a/ecmascript/js_primitive_ref.h +++ b/ecmascript/js_primitive_ref.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSPRIMITIVEREF_H -#define PANDA_RUNTIME_ECMASCRIPT_JSPRIMITIVEREF_H +#ifndef ECMASCRIPT_JSPRIMITIVEREF_H +#define ECMASCRIPT_JSPRIMITIVEREF_H #include "ecmascript/js_hclass.h" #include "ecmascript/js_object.h" @@ -44,6 +44,11 @@ public: return GetValue().IsNumber(); } + bool IsInt() const + { + return GetValue().IsInt(); + } + bool IsBoolean() const { return GetValue().IsBoolean(); @@ -80,4 +85,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSPRIMITIVEREF_H +#endif // ECMASCRIPT_JSPRIMITIVEREF_H diff --git a/ecmascript/js_promise.cpp b/ecmascript/js_promise.cpp index 914a6e12b78ae209a89d7cdb80551d1317bd5793..50de98481ff27f6394dd6a9005a7f33618a62dab 100644 --- a/ecmascript/js_promise.cpp +++ b/ecmascript/js_promise.cpp @@ -18,6 +18,7 @@ #include "ecmascript/builtins/builtins_promise_handler.h" #include "ecmascript/ecma_macros.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/jobs/micro_job_queue.h" #include "ecmascript/js_function.h" #include "ecmascript/js_handle.h" @@ -101,11 +102,10 @@ JSHandle JSPromise::NewPromiseCapability(JSThread *thread, co executor->SetCapability(thread, promiseCapability.GetTaggedValue()); // 6. Let promise be Construct(C, «executor»). // 7. ReturnIfAbrupt(promise). - array_size_t length = 1; - JSHandle arrayExecutor = factory->NewTaggedArray(length); - arrayExecutor->Set(thread, 0, executor); JSHandle newTarget(thread, JSTaggedValue::Undefined()); - JSTaggedValue result = JSFunction::Construct(thread, obj, arrayExecutor, newTarget); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(executor); + JSTaggedValue result = JSFunction::Construct(thread, obj, 1, arguments->GetArgv(), newTarget); JSHandle promise(thread, result); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, factory->NewPromiseCapability()); // 8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception. diff --git a/ecmascript/js_promise.h b/ecmascript/js_promise.h index 430b8c1b7c9af4f631a42ab8e1c0445d4ff3a61c..f70561f7cbcef0e5a5b8f7441c6948318337d149 100644 --- a/ecmascript/js_promise.h +++ b/ecmascript/js_promise.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_PROMISE_H -#define PANDA_RUNTIME_ECMASCRIPT_PROMISE_H +#ifndef ECMASCRIPT_PROMISE_H +#define ECMASCRIPT_PROMISE_H #include "js_object.h" #include "ecmascript/js_function.h" @@ -156,4 +156,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_PROMISE_H +#endif // ECMASCRIPT_PROMISE_H diff --git a/ecmascript/js_proxy.cpp b/ecmascript/js_proxy.cpp index 09be113669c866cf90c564a13b0a22e1123eff25..2fb989a09d1cc0a6a20f26d62784c40ea8bc3125 100644 --- a/ecmascript/js_proxy.cpp +++ b/ecmascript/js_proxy.cpp @@ -16,6 +16,7 @@ #include "js_proxy.h" #include "ecmascript/ecma_macros.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_array.h" #include "ecmascript/js_handle.h" #include "ecmascript/object_factory.h" @@ -68,9 +69,9 @@ JSTaggedValue JSProxy::GetPrototype(JSThread *thread, const JSHandle &p return JSHandle(targetHandle)->GetPrototype(thread); } // 8. Let handlerProto be Call(trap, handler, «target»). - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(1); - args->Set(thread, 0, targetHandle); - JSTaggedValue handlerProto = JSFunction::Call(thread, trap, handler, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle); + JSTaggedValue handlerProto = JSFunction::Call(thread, trap, handler, 1, arguments->GetArgv()); // 9. ReturnIfAbrupt(handlerProto). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); @@ -126,11 +127,11 @@ bool JSProxy::SetPrototype(JSThread *thread, const JSHandle &proxy, con return JSTaggedValue::SetPrototype(thread, targetHandle, proto); }; JSHandle handlerTag(thread, proxy->GetHandler()); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(2); // 2: target and proto - args->Set(thread, 0, targetHandle); - args->Set(thread, 1, proto); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle, proto); + JSTaggedValue trapResult = + JSFunction::Call(thread, trap, handlerTag, 2, arguments->GetArgv()); // 2: target and proto - JSTaggedValue trapResult = JSFunction::Call(thread, trap, handlerTag, args); // 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, V»)). // If booleanTrapResult is false, return false bool booleanTrapResult = trapResult.ToBoolean(); @@ -185,9 +186,9 @@ bool JSProxy::IsExtensible(JSThread *thread, const JSHandle &proxy) // 8. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target»)). JSHandle newTgt(thread, JSTaggedValue::Undefined()); JSHandle handlerTag(thread, proxy->GetHandler()); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(1); - args->Set(thread, 0, targetHandle); - JSTaggedValue trapResult = JSFunction::Call(thread, trap, handlerTag, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle); + JSTaggedValue trapResult = JSFunction::Call(thread, trap, handlerTag, 1, arguments->GetArgv()); bool booleanTrapResult = trapResult.ToBoolean(); // 9. ReturnIfAbrupt(booleanTrapResult). @@ -232,9 +233,9 @@ bool JSProxy::PreventExtensions(JSThread *thread, const JSHandle &proxy return JSTaggedValue::PreventExtensions(thread, targetHandle); } JSHandle handlerTag(thread, proxy->GetHandler()); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(1); - args->Set(thread, 0, targetHandle); - JSTaggedValue trapResult = JSFunction::Call(thread, trap, handlerTag, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle); + JSTaggedValue trapResult = JSFunction::Call(thread, trap, handlerTag, 1, arguments->GetArgv()); bool booleanTrapResult = trapResult.ToBoolean(); // 9. ReturnIfAbrupt(booleanTrapResult). @@ -282,10 +283,11 @@ bool JSProxy::GetOwnProperty(JSThread *thread, const JSHandle &proxy, c return JSTaggedValue::GetOwnProperty(thread, targetHandle, key, desc); } JSHandle handlerTag(thread, proxy->GetHandler()); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(2); // 2: target and key - args->Set(thread, 0, targetHandle); - args->Set(thread, 1, key); - JSTaggedValue trapResultObj = JSFunction::Call(thread, trap, handlerTag, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle, key); + JSTaggedValue trapResultObj = + JSFunction::Call(thread, trap, handlerTag, 2, arguments->GetArgv()); // 2: target and key + JSHandle resultHandle(thread, trapResultObj); // 11. If Type(trapResultObj) is neither Object nor Undefined, throw a TypeError exception. @@ -376,11 +378,10 @@ bool JSProxy::DefineOwnProperty(JSThread *thread, const JSHandle &proxy // 9. Let descObj be FromPropertyDescriptor(Desc). JSHandle descObj = JSObject::FromPropertyDescriptor(thread, desc); JSHandle handlerTag(thread, proxy->GetHandler()); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(3); // 3: target, key and desc - args->Set(thread, 0, targetHandle); - args->Set(thread, 1, key); - args->Set(thread, 2, descObj); // 2: the third value is desc - JSTaggedValue trapResult = JSFunction::Call(thread, trap, handlerTag, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle, key, descObj); + JSTaggedValue trapResult = + JSFunction::Call(thread, trap, handlerTag, 3, arguments->GetArgv()); // 3: target, key and desc bool booleanTrapResult = trapResult.ToBoolean(); // 11. ReturnIfAbrupt(booleanTrapResult). @@ -461,10 +462,11 @@ bool JSProxy::HasProperty(JSThread *thread, const JSHandle &proxy, cons // 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)). JSHandle handlerTag(thread, proxy->GetHandler()); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(2); // 2: target and key - args->Set(thread, 0, targetHandle); - args->Set(thread, 1, key); - JSTaggedValue trapResult = JSFunction::Call(thread, trap, handlerTag, args); + + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle, key); + JSTaggedValue trapResult = + JSFunction::Call(thread, trap, handlerTag, 2, arguments->GetArgv()); // 2: target and key bool booleanTrapResult = trapResult.ToBoolean(); // 10. ReturnIfAbrupt(booleanTrapResult). @@ -519,11 +521,10 @@ OperationResult JSProxy::GetProperty(JSThread *thread, const JSHandle & } // 9. Let trapResult be Call(trap, handler, «target, P, Receiver»). JSHandle handlerTag(thread, proxy->GetHandler()); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(3); // 3: «target, P, Receiver» - args->Set(thread, 0, targetHandle); - args->Set(thread, 1, key); - args->Set(thread, 2, receiver); // 2: the third value is receiver - JSTaggedValue trapResult = JSFunction::Call(thread, trap, handlerTag, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle, key, receiver); + JSTaggedValue trapResult = + JSFunction::Call(thread, trap, handlerTag, 3, arguments->GetArgv()); // 3: «target, P, Receiver» JSHandle resultHandle(thread, trapResult); // 10. ReturnIfAbrupt(trapResult). @@ -587,12 +588,10 @@ bool JSProxy::SetProperty(JSThread *thread, const JSHandle &proxy, cons // 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P, V, Receiver»)) JSHandle handlerTag(thread, proxy->GetHandler()); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(4); // 4: «target, P, V, Receiver» - args->Set(thread, 0, targetHandle); - args->Set(thread, 1, key); - args->Set(thread, 2, value); // 2: the third value is value - args->Set(thread, 3, receiver); // 3: the fourth value is receiver - JSTaggedValue trapResult = JSFunction::Call(thread, trap, handlerTag, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle, key, value, receiver); + JSTaggedValue trapResult = + JSFunction::Call(thread, trap, handlerTag, 4, arguments->GetArgv()); // 4: «target, P, V, Receiver» bool booleanTrapResult = trapResult.ToBoolean(); // 11. ReturnIfAbrupt(booleanTrapResult). @@ -645,10 +644,10 @@ bool JSProxy::DeleteProperty(JSThread *thread, const JSHandle &proxy, c // 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)). JSHandle newTgt(thread, JSTaggedValue::Undefined()); JSHandle handlerTag(thread, proxy->GetHandler()); - JSHandle args = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(2); // 2: target and key - args->Set(thread, 0, targetHandle); - args->Set(thread, 1, key); - JSTaggedValue trapResult = JSFunction::Call(thread, trap, handlerTag, args); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle, key); + JSTaggedValue trapResult = + JSFunction::Call(thread, trap, handlerTag, 2, arguments->GetArgv()); // 2: target and key bool booleanTrapResult = trapResult.ToBoolean(); // 11. ReturnIfAbrupt(booleanTrapResult). @@ -706,9 +705,9 @@ JSHandle JSProxy::OwnPropertyKeys(JSThread *thread, const JSHandle< // 8.Let trapResultArray be Call(trap, handler, «target»). JSHandle tagFunc(targetHandle); - JSHandle callArgs = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(1); - callArgs->Set(thread, 0, targetHandle); - JSTaggedValue res = JSFunction::Call(thread, trap, handlerHandle, callArgs); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(targetHandle); + JSTaggedValue res = JSFunction::Call(thread, trap, handlerHandle, 1, arguments->GetArgv()); JSHandle trap_res_arr(thread, res); // 9.Let trapResult be CreateListFromArrayLike(trapResultArray, «String, Symbol»). @@ -822,7 +821,8 @@ JSHandle JSProxy::OwnPropertyKeys(JSThread *thread, const JSHandle< // ES6 9.5.13 [[Call]] (thisArgument, argumentsList) JSTaggedValue JSProxy::CallInternal(JSThread *thread, const JSHandle &proxy, - const JSHandle &thisArg, const JSHandle &argv) + const JSHandle &thisArg, uint32_t argc, + const JSTaggedType argv[]) { // step 1 ~ 4 get ProxyHandler and ProxyTarget JSHandle handler(thread, proxy->GetHandler()); @@ -841,23 +841,25 @@ JSTaggedValue JSProxy::CallInternal(JSThread *thread, const JSHandle &p // 7.If trap is undefined, then // a.Return Call(target, thisArgument, argumentsList). if (method->IsUndefined()) { - return JSFunction::Call(thread, target, thisArg, argv); + return JSFunction::Call(thread, target, thisArg, argc, argv); } // 8.Let argArray be CreateArrayFromList(argumentsList). - JSHandle arrHandle = JSArray::CreateArrayFromList(thread, argv); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle taggedArray = factory->NewTaggedArray(argc); + for (array_size_t index = 0; index < argc; ++index) { + taggedArray->Set(thread, index, JSTaggedValue(argv[index])); + } + JSHandle arrHandle = JSArray::CreateArrayFromList(thread, taggedArray); // 9.Return Call(trap, handler, «target, thisArgument, argArray»). - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle nextArgv(factory->NewTaggedArray(3)); // 3: «target, thisArgument, argArray» - nextArgv->Set(thread, 0, target.GetTaggedValue()); - nextArgv->Set(thread, 1, thisArg.GetTaggedValue()); - nextArgv->Set(thread, 2, arrHandle.GetTaggedValue()); // 2: the third value is an args-array - return JSFunction::Call(thread, method, handler, nextArgv); + InternalCallParams *proxyArgv = thread->GetInternalCallParams(); + proxyArgv->MakeArgv(target, thisArg, arrHandle); + return JSFunction::Call(thread, method, handler, 3, proxyArgv->GetArgv()); // 3: «target, thisArgument, argArray» } // ES6 9.5.14 [[Construct]] ( argumentsList, newTarget) -JSTaggedValue JSProxy::ConstructInternal(JSThread *thread, const JSHandle &proxy, - const JSHandle &argv, const JSHandle &newTarget) +JSTaggedValue JSProxy::ConstructInternal(JSThread *thread, const JSHandle &proxy, uint32_t argc, + const JSTaggedType argv[], const JSHandle &newTarget) { // step 1 ~ 4 get ProxyHandler and ProxyTarget JSHandle handler(thread, proxy->GetHandler()); @@ -878,19 +880,22 @@ JSTaggedValue JSProxy::ConstructInternal(JSThread *thread, const JSHandleIsUndefined()) { ASSERT(target->IsConstructor()); - return JSFunction::Construct(thread, target, argv, newTarget); + return JSFunction::Construct(thread, target, argc, argv, newTarget); } // 8.Let argArray be CreateArrayFromList(argumentsList). - JSHandle arrHandle = JSArray::CreateArrayFromList(thread, argv); + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle taggedArray = factory->NewTaggedArray(argc); + for (array_size_t index = 0; index < argc; ++index) { + taggedArray->Set(thread, index, JSTaggedValue(argv[index])); + } + JSHandle arrHandle = JSArray::CreateArrayFromList(thread, taggedArray); // step 8 ~ 9 Call(trap, handler, «target, argArray, newTarget »). - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle nextArgv(factory->NewTaggedArray(3)); // 3: «target, argArray, newTarget » - nextArgv->Set(thread, 0, target.GetTaggedValue()); - nextArgv->Set(thread, 1, arrHandle.GetTaggedValue()); - nextArgv->Set(thread, 2, newTarget.GetTaggedValue()); // 2: the third value is newTarget - JSTaggedValue newObj = JSFunction::Call(thread, method, handler, nextArgv); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(target, arrHandle, newTarget); + JSTaggedValue newObj = + JSFunction::Call(thread, method, handler, 3, arguments->GetArgv()); // 3: «target, argArray, newTarget » // 10.ReturnIfAbrupt(newObj). RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); // 11.If Type(newObj) is not Object, throw a TypeError exception. diff --git a/ecmascript/js_proxy.h b/ecmascript/js_proxy.h index 9af426977c3ba9ecc6b040ebf047f86e0c6f8f6d..fd6dfb5ec0de8e5f560e72ff3754e7ea7edae395 100644 --- a/ecmascript/js_proxy.h +++ b/ecmascript/js_proxy.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSPROXY_H -#define PANDA_RUNTIME_ECMASCRIPT_JSPROXY_H +#ifndef ECMASCRIPT_JSPROXY_H +#define ECMASCRIPT_JSPROXY_H #include "ecmascript/tagged_array.h" #include "js_object.h" @@ -93,10 +93,11 @@ public: // ES6 9.5.13 [[Call]] (thisArgument, argumentsList) static JSTaggedValue CallInternal(JSThread *thread, const JSHandle &proxy, - const JSHandle &thisArg, const JSHandle &argv); + const JSHandle &thisArg, uint32_t argc, + const JSTaggedType argv[]); // ES6 9.5.14 [[Construct]] ( argumentsList, newTarget) - static JSTaggedValue ConstructInternal(JSThread *thread, const JSHandle &proxy, - const JSHandle &argv, const JSHandle &newTarget); + static JSTaggedValue ConstructInternal(JSThread *thread, const JSHandle &proxy, uint32_t argc, + const JSTaggedType argv[], const JSHandle &newTarget); static constexpr size_t METHOD_OFFSET = ECMAObject::SIZE; SET_GET_NATIVE_FIELD(Method, JSMethod, METHOD_OFFSET, TARGET_OFFSET) @@ -110,4 +111,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSPROXY_H +#endif // ECMASCRIPT_JSPROXY_H diff --git a/ecmascript/js_realm.h b/ecmascript/js_realm.h index 5672be0e7d94cb356176c323c034050789c55415..0372898caa9dcbee4623dbf26398a67cf4fcb030 100644 --- a/ecmascript/js_realm.h +++ b/ecmascript/js_realm.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSREALM_H -#define PANDA_RUNTIME_ECMASCRIPT_JSREALM_H +#ifndef ECMASCRIPT_JSREALM_H +#define ECMASCRIPT_JSREALM_H #include "js_global_object.h" @@ -26,10 +26,10 @@ public: return static_cast(object); } - static constexpr size_t VALUE_OFFSET = ObjectHeaderSize(); + static constexpr size_t VALUE_OFFSET = JSObject::SIZE; ACCESSORS(Value, VALUE_OFFSET, GLOBAL_ENV_OFFSET) ACCESSORS(GlobalEnv, GLOBAL_ENV_OFFSET, SIZE) }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSREALM_H \ No newline at end of file +#endif // ECMASCRIPT_JSREALM_H \ No newline at end of file diff --git a/ecmascript/js_regexp.h b/ecmascript/js_regexp.h index 5bf65408d0807f23f480d0777f7cbc4cd3f79a5c..ef8560df12adc4f4e87c50e44ab2a2034e84a2ea 100644 --- a/ecmascript/js_regexp.h +++ b/ecmascript/js_regexp.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSREGEXP_H -#define PANDA_RUNTIME_ECMASCRIPT_JSREGEXP_H +#ifndef ECMASCRIPT_JSREGEXP_H +#define ECMASCRIPT_JSREGEXP_H #include "ecmascript/js_object.h" #include "ecmascript/js_hclass.h" @@ -43,4 +43,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSPRIMITIVEREF_H +#endif // ECMASCRIPT_JSPRIMITIVEREF_H diff --git a/ecmascript/js_relative_time_format.cpp b/ecmascript/js_relative_time_format.cpp new file mode 100644 index 0000000000000000000000000000000000000000..107ea89fbaace851a1d28033bbb9f48d185740d6 --- /dev/null +++ b/ecmascript/js_relative_time_format.cpp @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "js_relative_time_format.h" + +#include "unicode/decimfmt.h" +#include "unicode/numfmt.h" +#include "unicode/unum.h" + +namespace panda::ecmascript { +enum class StyleOption : uint8_t { LONG = 0x01, SHORT, NARROW, EXCEPTION }; +enum class NumericOption : uint8_t { ALWAYS = 0x01, AUTO, EXCEPTION }; + +// 14.1.1 InitializeRelativeTimeFormat ( relativeTimeFormat, locales, options ) +JSHandle JSRelativeTimeFormat::InitializeRelativeTimeFormat( + JSThread *thread, const JSHandle &relativeTimeFormat, const JSHandle &locales, + const JSHandle &options) +{ + EcmaVM *ecmaVm = thread->GetEcmaVM(); + ObjectFactory *factory = ecmaVm->GetFactory(); + + // 1.Let requestedLocales be ? CanonicalizeLocaleList(locales). + JSHandle requestedLocales = JSLocale::CanonicalizeLocaleList(thread, locales); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSRelativeTimeFormat, thread); + + // 2&3. If options is undefined, then Let options be ObjectCreate(null). else Let options be ? ToObject(options). + JSHandle rtfOptions; + if (!options->IsUndefined()) { + rtfOptions = JSTaggedValue::ToObject(thread, options); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSRelativeTimeFormat, thread); + } else { + rtfOptions = factory->OrdinaryNewJSObjectCreate(JSHandle(thread, JSTaggedValue::Null())); + } + + // 5. Let matcher be ? GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit"). + auto globalConst = thread->GlobalConstants(); + LocaleMatcherOption matcher = + JSLocale::GetOptionOfString(thread, rtfOptions, globalConst->GetHandledLocaleMatcherString(), + {LocaleMatcherOption::LOOKUP, LocaleMatcherOption::BEST_FIT}, + {"lookup", "best fit"}, LocaleMatcherOption::BEST_FIT); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSRelativeTimeFormat, thread); + + // 7. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined). + JSHandle property = JSHandle::Cast(globalConst->GetHandledNumberingSystemString()); + JSHandle undefinedValue(thread, JSTaggedValue::Undefined()); + JSHandle numberingSystemValue = + JSLocale::GetOption(thread, rtfOptions, property, OptionType::STRING, undefinedValue, undefinedValue); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSRelativeTimeFormat, thread); + + // Check whether numberingSystem is well formed and set to %RelativeTimeFormat%.[[numberingSystem]] + std::string numberingSystemStdStr; + if (!numberingSystemValue->IsUndefined()) { + JSHandle numberingSystemString = JSHandle::Cast(numberingSystemValue); + if (numberingSystemString->IsUtf16()) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid numberingSystem", relativeTimeFormat); + } + numberingSystemStdStr = JSLocale::ConvertToStdString(numberingSystemString); + if (!JSLocale::IsNormativeNumberingSystem(numberingSystemStdStr)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "invalid numberingSystem", relativeTimeFormat); + } + } else { + relativeTimeFormat->SetNumberingSystem(thread, globalConst->GetHandledLatnString()); + } + + // 10. Let localeData be %RelativeTimeFormat%.[[LocaleData]]. + // 11. Let r be ResolveLocale(%RelativeTimeFormat%.[[AvailableLocales]], requestedLocales, opt, + // %RelativeTimeFormat%.[[RelevantExtensionKeys]], localeData). + JSHandle availableLocales; + if (requestedLocales->GetLength() == 0) { + availableLocales = factory->EmptyArray(); + } else { + availableLocales = JSLocale::GetAvailableLocales(thread, "calendar", nullptr); + } + std::set relevantExtensionKeys{"nu"}; + ResolvedLocale r = + JSLocale::ResolveLocale(thread, availableLocales, requestedLocales, matcher, relevantExtensionKeys); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSRelativeTimeFormat, thread); + icu::Locale icuLocale = r.localeData; + + // 12. Let locale be r.[[Locale]]. + JSHandle localeStr = JSLocale::ToLanguageTag(thread, icuLocale); + + // 13. Set relativeTimeFormat.[[Locale]] to locale. + relativeTimeFormat->SetLocale(thread, localeStr.GetTaggedValue()); + + // 15. Set relativeTimeFormat.[[NumberingSystem]] to r.[[nu]]. + UErrorCode status = U_ZERO_ERROR; + if (!numberingSystemStdStr.empty()) { + if (JSLocale::IsWellNumberingSystem(numberingSystemStdStr)) { + icuLocale.setUnicodeKeywordValue("nu", numberingSystemStdStr, status); + ASSERT(U_SUCCESS(status)); + } + } + + // 16. Let s be ? GetOption(options, "style", "string", «"long", "short", "narrow"», "long"). + property = JSHandle::Cast(globalConst->GetHandledStyleString()); + StyleOption styleOption = JSLocale::GetOptionOfString(thread, rtfOptions, property, + {StyleOption::LONG, StyleOption::SHORT, StyleOption::NARROW}, + {"long", "short", "narrow"}, StyleOption::LONG); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSRelativeTimeFormat, thread); + + // 17. Set relativeTimeFormat.[[Style]] to s. + JSTaggedValue styleValue(static_cast(styleOption)); + relativeTimeFormat->SetStyle(thread, JSHandle(thread, styleValue)); + + // 18. Let numeric be ? GetOption(options, "numeric", "string", ?"always", "auto"?, "always"). + property = JSHandle::Cast(globalConst->GetHandledNumericString()); + NumericOption numericOption = + JSLocale::GetOptionOfString(thread, rtfOptions, property, {NumericOption::ALWAYS, NumericOption::AUTO}, + {"always", "auto"}, NumericOption::ALWAYS); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSRelativeTimeFormat, thread); + + // 19. Set relativeTimeFormat.[[Numeric]] to numeric. + JSTaggedValue numericValue(static_cast(numericOption)); + relativeTimeFormat->SetNumeric(thread, JSHandle(thread, numericValue)); + + // 20. Let relativeTimeFormat.[[NumberFormat]] be ! Construct(%NumberFormat%, « locale »). + icu::NumberFormat *icuNumberFormat = icu::NumberFormat::createInstance(icuLocale, UNUM_DECIMAL, status); + if (U_FAILURE(status) != 0) { + delete icuNumberFormat; + THROW_RANGE_ERROR_AND_RETURN(thread, "icu Number Format Error", relativeTimeFormat); + } + + // Trans StyleOption to ICU Style + UDateRelativeDateTimeFormatterStyle uStyle; + switch (styleOption) { + case StyleOption::LONG: + uStyle = UDAT_STYLE_LONG; + break; + case StyleOption::SHORT: + uStyle = UDAT_STYLE_SHORT; + break; + case StyleOption::NARROW: + uStyle = UDAT_STYLE_NARROW; + break; + default: + UNREACHABLE(); + } + icu::RelativeDateTimeFormatter rtfFormatter(icuLocale, icuNumberFormat, uStyle, UDISPCTX_CAPITALIZATION_NONE, + status); + if (U_FAILURE(status) != 0) { + THROW_RANGE_ERROR_AND_RETURN(thread, "icu Formatter Error", relativeTimeFormat); + } + + std::string numberingSystem = JSLocale::GetNumberingSystem(icuLocale); + relativeTimeFormat->SetNumberingSystem(thread, factory->NewFromStdString(numberingSystem)); + + // Set RelativeTimeFormat.[[IcuRelativeTimeFormatter]] + factory->NewJSIntlIcuData(relativeTimeFormat, rtfFormatter, JSRelativeTimeFormat::FreeIcuRTFFormatter); + + // 22. Return relativeTimeFormat. + return relativeTimeFormat; +} + +// 14.1.2 SingularRelativeTimeUnit ( unit ) +bool SingularUnitToIcuUnit(JSThread *thread, const JSHandle &unit, URelativeDateTimeUnit *unitEnum) +{ + // 1. Assert: Type(unit) is String. + ASSERT(JSHandle::Cast(unit)->IsString()); + + // 2. If unit is "seconds" or "second", return "second". + // 3. If unit is "minutes" or "minute", return "minute". + // 4. If unit is "hours" or "hour", return "hour". + // 5. If unit is "days" or "day", return "day". + // 6. If unit is "weeks" or "week", return "week". + // 7. If unit is "months" or "month", return "month". + // 8. If unit is "quarters" or "quarter", return "quarter". + // 9. If unit is "years" or "year", return "year". + auto globalConst = thread->GlobalConstants(); + JSHandle second = JSHandle::Cast(globalConst->GetHandledSecondString()); + JSHandle minute = JSHandle::Cast(globalConst->GetHandledMinuteString()); + JSHandle hour = JSHandle::Cast(globalConst->GetHandledHourString()); + JSHandle day = JSHandle::Cast(globalConst->GetHandledDayString()); + JSHandle week = JSHandle::Cast(globalConst->GetHandledWeekString()); + JSHandle month = JSHandle::Cast(globalConst->GetHandledMonthString()); + JSHandle quarter = JSHandle::Cast(globalConst->GetHandledQuarterString()); + JSHandle year = JSHandle::Cast(globalConst->GetHandledYearString()); + + JSHandle seconds = JSHandle::Cast(globalConst->GetHandledSecondsString()); + JSHandle minutes = JSHandle::Cast(globalConst->GetHandledMinutesString()); + JSHandle hours = JSHandle::Cast(globalConst->GetHandledHoursString()); + JSHandle days = JSHandle::Cast(globalConst->GetHandledDaysString()); + JSHandle weeks = JSHandle::Cast(globalConst->GetHandledWeeksString()); + JSHandle months = JSHandle::Cast(globalConst->GetHandledMonthsString()); + JSHandle quarters = JSHandle::Cast(globalConst->GetHandledQuartersString()); + JSHandle years = JSHandle::Cast(globalConst->GetHandledYearsString()); + + if (EcmaString::StringsAreEqual(*second, *unit) || EcmaString::StringsAreEqual(*seconds, *unit)) { + *unitEnum = UDAT_REL_UNIT_SECOND; + } else if (EcmaString::StringsAreEqual(*minute, *unit) || EcmaString::StringsAreEqual(*minutes, *unit)) { + *unitEnum = UDAT_REL_UNIT_MINUTE; + } else if (EcmaString::StringsAreEqual(*hour, *unit) || EcmaString::StringsAreEqual(*hours, *unit)) { + *unitEnum = UDAT_REL_UNIT_HOUR; + } else if (EcmaString::StringsAreEqual(*day, *unit) || EcmaString::StringsAreEqual(*days, *unit)) { + *unitEnum = UDAT_REL_UNIT_DAY; + } else if (EcmaString::StringsAreEqual(*week, *unit) || EcmaString::StringsAreEqual(*weeks, *unit)) { + *unitEnum = UDAT_REL_UNIT_WEEK; + } else if (EcmaString::StringsAreEqual(*month, *unit) || EcmaString::StringsAreEqual(*months, *unit)) { + *unitEnum = UDAT_REL_UNIT_MONTH; + } else if (EcmaString::StringsAreEqual(*quarter, *unit) || EcmaString::StringsAreEqual(*quarters, *unit)) { + *unitEnum = UDAT_REL_UNIT_QUARTER; + } else if (EcmaString::StringsAreEqual(*year, *unit) || EcmaString::StringsAreEqual(*years, *unit)) { + *unitEnum = UDAT_REL_UNIT_YEAR; + } else { + return false; + } + // 11. else return unit. + return true; +} + +// Unwrap RelativeTimeFormat +JSHandle JSRelativeTimeFormat::UnwrapRelativeTimeFormat(JSThread *thread, + const JSHandle &rtf) +{ + ASSERT_PRINT(rtf->IsJSObject(), "rtf is not a JSObject"); + + JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); + bool isInstanceOf = JSFunction::InstanceOf(thread, rtf, env->GetRelativeTimeFormatFunction()); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, rtf); + if (!rtf->IsJSRelativeTimeFormat() && isInstanceOf) { + JSHandle key(thread, JSHandle::Cast(env->GetIntlFunction())->GetFallbackSymbol()); + OperationResult operationResult = JSTaggedValue::GetProperty(thread, rtf, key); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, rtf); + return operationResult.GetValue(); + } + + // Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]). + if (!rtf->IsJSRelativeTimeFormat()) { + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, rtf); + } + return rtf; +} + +// CommonFormat +icu::FormattedRelativeDateTime GetIcuFormatted(JSThread *thread, + const JSHandle &relativeTimeFormat, + double value, const JSHandle &unit) +{ + icu::RelativeDateTimeFormatter *formatter = relativeTimeFormat->GetIcuRTFFormatter(); + ASSERT_PRINT(formatter != nullptr, "rtfFormatter is null"); + + // If isFinite(value) is false, then throw a RangeError exception. + if (!std::isfinite(value)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "", icu::FormattedRelativeDateTime()); + } + + // 10. If unit is not one of "second", "minute", "hour", "day", "week", "month", "quarter", or "year", throw a + // RangeError exception. + URelativeDateTimeUnit unitEnum; + if (!SingularUnitToIcuUnit(thread, unit, &unitEnum)) { + THROW_RANGE_ERROR_AND_RETURN(thread, "", icu::FormattedRelativeDateTime()); + } + UErrorCode status = U_ZERO_ERROR; + NumericOption numeric = static_cast(relativeTimeFormat->GetNumeric().GetNumber()); + + icu::FormattedRelativeDateTime formatted; + switch (numeric) { + case NumericOption::ALWAYS: + formatted = formatter->formatNumericToValue(value, unitEnum, status); + ASSERT_PRINT(U_SUCCESS(status), "icu format to value error"); + break; + case NumericOption::AUTO: + formatted = formatter->formatToValue(value, unitEnum, status); + ASSERT_PRINT(U_SUCCESS(status), "icu format to value error"); + break; + default: + UNREACHABLE(); + } + return formatted; +} + +// 14.1.2 SingularRelativeTimeUnit ( unit ) +JSHandle SingularUnitString(JSThread *thread, const JSHandle &unit) +{ + auto globalConst = thread->GlobalConstants(); + JSHandle second = JSHandle::Cast(globalConst->GetHandledSecondString()); + JSHandle minute = JSHandle::Cast(globalConst->GetHandledMinuteString()); + JSHandle hour = JSHandle::Cast(globalConst->GetHandledHourString()); + JSHandle day = JSHandle::Cast(globalConst->GetHandledDayString()); + JSHandle week = JSHandle::Cast(globalConst->GetHandledWeekString()); + JSHandle month = JSHandle::Cast(globalConst->GetHandledMonthString()); + JSHandle quarter = JSHandle::Cast(globalConst->GetHandledQuarterString()); + JSHandle year = JSHandle::Cast(globalConst->GetHandledYearString()); + JSHandle seconds = JSHandle::Cast(globalConst->GetHandledSecondsString()); + JSHandle minutes = JSHandle::Cast(globalConst->GetHandledMinutesString()); + JSHandle hours = JSHandle::Cast(globalConst->GetHandledHoursString()); + JSHandle days = JSHandle::Cast(globalConst->GetHandledDaysString()); + JSHandle weeks = JSHandle::Cast(globalConst->GetHandledWeeksString()); + JSHandle months = JSHandle::Cast(globalConst->GetHandledMonthsString()); + JSHandle quarters = JSHandle::Cast(globalConst->GetHandledQuartersString()); + JSHandle years = JSHandle::Cast(globalConst->GetHandledYearsString()); + + // 2. If unit is "seconds" or "second", return "second". + if (EcmaString::StringsAreEqual(*second, *unit) || EcmaString::StringsAreEqual(*seconds, *unit)) { + return second; + } + // 3. If unit is "minutes" or "minute", return "minute". + if (EcmaString::StringsAreEqual(*minute, *unit) || EcmaString::StringsAreEqual(*minutes, *unit)) { + return minute; + } + // 4. If unit is "hours" or "hour", return "hour". + if (EcmaString::StringsAreEqual(*hour, *unit) || EcmaString::StringsAreEqual(*hours, *unit)) { + return hour; + } + // 5. If unit is "days" or "day", return "day". + if (EcmaString::StringsAreEqual(*day, *unit) || EcmaString::StringsAreEqual(*days, *unit)) { + return day; + } + // 6. If unit is "weeks" or "week", return "week". + if (EcmaString::StringsAreEqual(*week, *unit) || EcmaString::StringsAreEqual(*weeks, *unit)) { + return week; + } + // 7. If unit is "months" or "month", return "month". + if (EcmaString::StringsAreEqual(*month, *unit) || EcmaString::StringsAreEqual(*months, *unit)) { + return month; + } + // 8. If unit is "quarters" or "quarter", return "quarter". + if (EcmaString::StringsAreEqual(*quarter, *unit) || EcmaString::StringsAreEqual(*quarters, *unit)) { + return quarter; + } + // 9. If unit is "years" or "year", return "year". + if (EcmaString::StringsAreEqual(*year, *unit) || EcmaString::StringsAreEqual(*years, *unit)) { + return year; + } + + JSHandle undefinedValue(thread, JSTaggedValue::Undefined()); + return JSHandle::Cast(undefinedValue); +} + +// 14.1.5 FormatRelativeTime ( relativeTimeFormat, value, unit ) +JSHandle JSRelativeTimeFormat::Format(JSThread *thread, double value, const JSHandle &unit, + const JSHandle &relativeTimeFormat) +{ + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + icu::FormattedRelativeDateTime formatted = GetIcuFormatted(thread, relativeTimeFormat, value, unit); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(EcmaString, thread); + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString uString = formatted.toString(status); + if (U_FAILURE(status) != 0) { + THROW_RANGE_ERROR_AND_RETURN(thread, "icu formatted toString error", factory->GetEmptyString()); + } + JSHandle string = + factory->NewFromUtf16(reinterpret_cast(uString.getBuffer()), uString.length()); + return string; +} + +void FormatToArray(JSThread *thread, const JSHandle &array, + const icu::FormattedRelativeDateTime &formatted, double value, + const JSHandle &unit) +{ + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString formattedText = formatted.toString(status); + if (U_FAILURE(status)) { + THROW_TYPE_ERROR(thread, "formattedRelativeDateTime toString failed"); + } + + icu::ConstrainedFieldPosition cfpo; + // Set constrainCategory to UFIELD_CATEGORY_NUMBER which is specified for UNumberFormatFields + cfpo.constrainCategory(UFIELD_CATEGORY_NUMBER); + int32_t index = 0; + int32_t previousLimit = 0; + auto globalConst = thread->GlobalConstants(); + JSHandle taggedValue(thread, JSTaggedValue(value)); + JSMutableHandle typeString(thread, JSTaggedValue::Undefined()); + JSHandle unitString = globalConst->GetHandledUnitString(); + std::vector> separatorFields; + /** + * From ICU header file document @unumberformatter.h + * Sets a constraint on the field category. + * + * When this instance of ConstrainedFieldPosition is passed to FormattedValue#nextPosition, + * positions are skipped unless they have the given category. + * + * Any previously set constraints are cleared. + * + * For example, to loop over only the number-related fields: + * + * ConstrainedFieldPosition cfpo; + * cfpo.constrainCategory(UFIELDCATEGORY_NUMBER_FORMAT); + * while (fmtval.nextPosition(cfpo, status)) { + * // handle the number-related field position + * } + */ + while ((formatted.nextPosition(cfpo, status) != 0)) { + int32_t fieldId = cfpo.getField(); + int32_t start = cfpo.getStart(); + int32_t limit = cfpo.getLimit(); + // Special case when fieldId is UNUM_GROUPING_SEPARATOR_FIELD + if (static_cast(fieldId) == UNUM_GROUPING_SEPARATOR_FIELD) { + separatorFields.push_back(std::pair(start, limit)); + continue; + } + // If start greater than previousLimit, means a literal type exists before number fields + // so add a literal type with value of formattedText.sub(0, start) + if (start > previousLimit) { + typeString.Update(globalConst->GetLiteralString()); + JSHandle substring = JSLocale::IcuToString(thread, formattedText, previousLimit, start); + JSLocale::PutElement(thread, index++, array, typeString, JSHandle::Cast(substring)); + RETURN_IF_ABRUPT_COMPLETION(thread); + } + // Add part when type is unit + // Iterate former grouping separator vector and add unit element to array + for (auto it = separatorFields.begin(); it != separatorFields.end(); it++) { + if (it->first > start) { + // Add Integer type element + JSHandle resString = JSLocale::IcuToString(thread, formattedText, start, it->first); + typeString.Update( + JSLocale::GetNumberFieldType(thread, taggedValue.GetTaggedValue(), fieldId).GetTaggedValue()); + JSHandle record = + JSLocale::PutElement(thread, index++, array, typeString, JSHandle::Cast(resString)); + RETURN_IF_ABRUPT_COMPLETION(thread); + JSObject::CreateDataPropertyOrThrow(thread, record, unitString, JSHandle::Cast(unit)); + RETURN_IF_ABRUPT_COMPLETION(thread); + // Add Group type element + resString = JSLocale::IcuToString(thread, formattedText, it->first, it->second); + typeString.Update(JSLocale::GetNumberFieldType(thread, taggedValue.GetTaggedValue(), + UNUM_GROUPING_SEPARATOR_FIELD).GetTaggedValue()); + record = + JSLocale::PutElement(thread, index++, array, typeString, JSHandle::Cast(resString)); + RETURN_IF_ABRUPT_COMPLETION(thread); + JSObject::CreateDataPropertyOrThrow(thread, record, unitString, JSHandle::Cast(unit)); + RETURN_IF_ABRUPT_COMPLETION(thread); + start = it->second; + } + } + // Add current field unit + JSHandle subString = JSLocale::IcuToString(thread, formattedText, start, limit); + typeString.Update(JSLocale::GetNumberFieldType(thread, taggedValue.GetTaggedValue(), fieldId).GetTaggedValue()); + JSHandle record = + JSLocale::PutElement(thread, index++, array, typeString, JSHandle::Cast(subString)); + RETURN_IF_ABRUPT_COMPLETION(thread); + JSObject::CreateDataPropertyOrThrow(thread, record, unitString, JSHandle::Cast(unit)); + RETURN_IF_ABRUPT_COMPLETION(thread); + previousLimit = limit; + } + // If iterated length is smaller than formattedText.length, means a literal type exists after number fields + // so add a literal type with value of formattedText.sub(previousLimit, formattedText.length) + if (formattedText.length() > previousLimit) { + typeString.Update(globalConst->GetLiteralString()); + JSHandle substring = + JSLocale::IcuToString(thread, formattedText, previousLimit, formattedText.length()); + JSLocale::PutElement(thread, index, array, typeString, JSHandle::Cast(substring)); + RETURN_IF_ABRUPT_COMPLETION(thread); + } +} + +// 14.1.6 FormatRelativeTimeToParts ( relativeTimeFormat, value, unit ) +JSHandle JSRelativeTimeFormat::FormatToParts(JSThread *thread, double value, const JSHandle &unit, + const JSHandle &relativeTimeFormat) +{ + icu::FormattedRelativeDateTime formatted = GetIcuFormatted(thread, relativeTimeFormat, value, unit); + RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSArray, thread); + JSHandle singularUnit = SingularUnitString(thread, unit); + JSHandle array = JSHandle::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0))); + FormatToArray(thread, array, formatted, value, singularUnit); + return array; +} + +void JSRelativeTimeFormat::ResolvedOptions(JSThread *thread, const JSHandle &relativeTimeFormat, + const JSHandle &options) +{ + if (relativeTimeFormat->GetIcuRTFFormatter() != nullptr) { + [[maybe_unused]] icu::RelativeDateTimeFormatter *formatter = relativeTimeFormat->GetIcuRTFFormatter(); + } else { + THROW_RANGE_ERROR(thread, "rtf is not initialized"); + } + + auto globalConst = thread->GlobalConstants(); + // [[locale]] + JSHandle property = JSHandle::Cast(globalConst->GetHandledLocaleString()); + JSHandle locale(thread, relativeTimeFormat->GetLocale()); + PropertyDescriptor localeDesc(thread, JSHandle::Cast(locale), true, true, true); + JSObject::DefineOwnProperty(thread, options, property, localeDesc); + + // [[Style]] + property = JSHandle::Cast(globalConst->GetHandledStyleString()); + StyleOption style = static_cast(relativeTimeFormat->GetStyle().GetNumber()); + JSHandle styleValue; + if (style == StyleOption::LONG) { + styleValue = globalConst->GetHandledLongString(); + } else if (style == StyleOption::SHORT) { + styleValue = globalConst->GetHandledShortString(); + } else if (style == StyleOption::NARROW) { + styleValue = globalConst->GetHandledNarrowString(); + } + PropertyDescriptor styleDesc(thread, styleValue, true, true, true); + JSObject::DefineOwnProperty(thread, options, property, styleDesc); + + // [[Numeric]] + property = JSHandle::Cast(globalConst->GetHandledNumericString()); + NumericOption numeric = static_cast(relativeTimeFormat->GetNumeric().GetNumber()); + JSHandle numericValue; + if (numeric == NumericOption::ALWAYS) { + numericValue = globalConst->GetHandledAlwaysString(); + } else if (numeric == NumericOption::AUTO) { + numericValue = globalConst->GetHandledAutoString(); + } else { + THROW_RANGE_ERROR(thread, "numeric is exception"); + } + PropertyDescriptor numericDesc(thread, numericValue, true, true, true); + JSObject::DefineOwnProperty(thread, options, property, numericDesc); + + // [[NumberingSystem]] + property = JSHandle::Cast(globalConst->GetHandledNumberingSystemString()); + JSHandle numberingSystem(thread, relativeTimeFormat->GetNumberingSystem()); + PropertyDescriptor numberingSystemDesc(thread, numberingSystem, true, true, true); + JSObject::DefineOwnProperty(thread, options, property, numberingSystemDesc); +} +} // namespace panda::ecmascript \ No newline at end of file diff --git a/ecmascript/js_relative_time_format.h b/ecmascript/js_relative_time_format.h new file mode 100644 index 0000000000000000000000000000000000000000..2c5fdc261906cb362c6e224494ac07d4cc550fe2 --- /dev/null +++ b/ecmascript/js_relative_time_format.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_JS_RELATIVE_TIME_FORMAT_H +#define ECMASCRIPT_JS_RELATIVE_TIME_FORMAT_H + +#include "unicode/reldatefmt.h" + +#include "ecmascript/base/number_helper.h" +#include "ecmascript/common.h" +#include "ecmascript/ecma_macros.h" +#include "ecmascript/ecma_string.h" +#include "ecmascript/ecma_vm.h" +#include "ecmascript/global_env.h" +#include "ecmascript/js_array.h" +#include "ecmascript/js_date.h" +#include "ecmascript/js_intl.h" +#include "ecmascript/js_locale.h" +#include "ecmascript/js_object.h" +#include "ecmascript/js_tagged_number.h" +#include "ecmascript/js_tagged_value.h" +#include "ecmascript/object_factory.h" + +namespace panda::ecmascript { +class JSRelativeTimeFormat : public JSObject { +public: + static JSRelativeTimeFormat *Cast(ObjectHeader *object) + { + ASSERT(JSTaggedValue(object).IsJSRelativeTimeFormat()); + return reinterpret_cast(object); + } + + static constexpr size_t LOCALE_OFFSET = JSObject::SIZE; + + ACCESSORS(Locale, LOCALE_OFFSET, INITIALIZED_RELATIVE_TIME_FORMAT) + ACCESSORS(InitializedRelativeTimeFormat, INITIALIZED_RELATIVE_TIME_FORMAT, NUMBERING_SYSTEM_OFFSET) + ACCESSORS(NumberingSystem, NUMBERING_SYSTEM_OFFSET, STYLE_OFFSET) + ACCESSORS(Style, STYLE_OFFSET, NUMERIC_OFFSET) + ACCESSORS(Numeric, NUMERIC_OFFSET, AVAILABLE_LOCALES_OFFSET) + ACCESSORS(AvailableLocales, AVAILABLE_LOCALES_OFFSET, ICU_FIELD_OFFSET) + + // icu field + ACCESSORS(IcuField, ICU_FIELD_OFFSET, SIZE) + + DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE) + + // 14.1.1 InitializeRelativeTimeFormat ( relativeTimeFormat, locales, options ) + static JSHandle InitializeRelativeTimeFormat( + JSThread *thread, const JSHandle &relativeTimeFormat, + const JSHandle &locales, const JSHandle &options); + + // UnwrapRelativeTimeFormat + static JSHandle UnwrapRelativeTimeFormat(JSThread *thread, const JSHandle &rtf); + + // Get icu formatter from icu field + icu::RelativeDateTimeFormatter *GetIcuRTFFormatter() const + { + ASSERT(GetIcuField().IsJSNativePointer()); + auto result = JSNativePointer::Cast(GetIcuField().GetTaggedObject())->GetExternalPointer(); + return reinterpret_cast(result); + } + + static void FreeIcuRTFFormatter(void *pointer, void *data) + { + if (pointer == nullptr) { + return; + } + auto icuFormatter = reinterpret_cast(pointer); + icuFormatter->~RelativeDateTimeFormatter(); + if (data != nullptr) { + reinterpret_cast(data)->GetRegionFactory()->FreeBuffer(pointer); + } + } + + static void ResolvedOptions(JSThread *thread, const JSHandle &relativeTimeFormat, + const JSHandle &options); + + static JSHandle Format(JSThread *thread, double value, const JSHandle &unit, + const JSHandle &relativeTimeFormat); + + static JSHandle FormatToParts(JSThread *thread, double value, const JSHandle &unit, + const JSHandle &relativeTimeFormat); +}; +} // namespace panda::ecmascript + +#endif // ECMASCRIPT_JS_RELATIVE_TIME_FORMAT_H \ No newline at end of file diff --git a/ecmascript/js_serializer.cpp b/ecmascript/js_serializer.cpp index 1a3e31829e315c844716aa3a16c2dcf1335e0b6d..887efc800a4bf3af8786d435abb93c4aa7cb43b8 100644 --- a/ecmascript/js_serializer.cpp +++ b/ecmascript/js_serializer.cpp @@ -22,18 +22,10 @@ #include "ecmascript/global_env.h" #include "ecmascript/js_array.h" #include "ecmascript/js_arraybuffer.h" -#include "ecmascript/js_float32_array.h" -#include "ecmascript/js_float64_array.h" #include "ecmascript/js_hclass.h" -#include "ecmascript/js_int16_array.h" -#include "ecmascript/js_int32_array.h" -#include "ecmascript/js_int8_array.h" #include "ecmascript/js_regexp.h" #include "ecmascript/js_set.h" -#include "ecmascript/js_uint16_array.h" -#include "ecmascript/js_uint32_array.h" -#include "ecmascript/js_uint8_array.h" -#include "ecmascript/js_uint8_clamped_array.h" +#include "ecmascript/js_typed_array.h" #include "ecmascript/linked_hash_table-inl.h" #include "libpandabase/mem/mem.h" #include "securec.h" @@ -253,17 +245,18 @@ bool JSSerializer::WriteIfSerialized(uintptr_t addr) } // Write HeapObject -bool JSSerializer::WriteTaggedObject(const JSHandle &objValue) +bool JSSerializer::WriteTaggedObject(const JSHandle &value) { - JSHandle obj = JSHandle::Cast(objValue); - uintptr_t addr = reinterpret_cast(*obj); + uintptr_t addr = reinterpret_cast(value.GetTaggedValue().GetTaggedObject()); bool serialized = IsSerialized(addr); if (serialized) { return WriteIfSerialized(addr); } referenceMap_.insert(std::pair(addr, objectId_)); objectId_++; - JSType type = obj->GetJSHClass()->GetObjectType(); + + TaggedObject *taggedObject = value->GetTaggedObject(); + JSType type = taggedObject->GetClass()->GetObjectType(); switch (type) { case JSType::JS_ERROR: case JSType::JS_EVAL_ERROR: @@ -272,58 +265,58 @@ bool JSSerializer::WriteTaggedObject(const JSHandle &objValue) case JSType::JS_TYPE_ERROR: case JSType::JS_URI_ERROR: case JSType::JS_SYNTAX_ERROR: - return WriteJSError(obj); + return WriteJSError(value); case JSType::JS_DATE: - return WriteJSDate(obj); + return WriteJSDate(value); case JSType::JS_ARRAY: - return WriteJSArray(obj); + return WriteJSArray(value); case JSType::JS_MAP: - return WriteJSMap(obj); + return WriteJSMap(value); case JSType::JS_SET: - return WriteJSSet(obj); + return WriteJSSet(value); case JSType::JS_REG_EXP: - return WriteJSRegExp(obj); + return WriteJSRegExp(value); case JSType::JS_INT8_ARRAY: - return WriteJSTypedArray(obj, SerializationUID::JS_INT8_ARRAY); + return WriteJSTypedArray(value, SerializationUID::JS_INT8_ARRAY); case JSType::JS_UINT8_ARRAY: - return WriteJSTypedArray(obj, SerializationUID::JS_UINT8_ARRAY); + return WriteJSTypedArray(value, SerializationUID::JS_UINT8_ARRAY); case JSType::JS_UINT8_CLAMPED_ARRAY: - return WriteJSTypedArray(obj, SerializationUID::JS_UINT8_CLAMPED_ARRAY); + return WriteJSTypedArray(value, SerializationUID::JS_UINT8_CLAMPED_ARRAY); case JSType::JS_INT16_ARRAY: - return WriteJSTypedArray(obj, SerializationUID::JS_INT16_ARRAY); + return WriteJSTypedArray(value, SerializationUID::JS_INT16_ARRAY); case JSType::JS_UINT16_ARRAY: - return WriteJSTypedArray(obj, SerializationUID::JS_UINT16_ARRAY); + return WriteJSTypedArray(value, SerializationUID::JS_UINT16_ARRAY); case JSType::JS_INT32_ARRAY: - return WriteJSTypedArray(obj, SerializationUID::JS_INT32_ARRAY); + return WriteJSTypedArray(value, SerializationUID::JS_INT32_ARRAY); case JSType::JS_UINT32_ARRAY: - return WriteJSTypedArray(obj, SerializationUID::JS_UINT32_ARRAY); + return WriteJSTypedArray(value, SerializationUID::JS_UINT32_ARRAY); case JSType::JS_FLOAT32_ARRAY: - return WriteJSTypedArray(obj, SerializationUID::JS_FLOAT32_ARRAY); + return WriteJSTypedArray(value, SerializationUID::JS_FLOAT32_ARRAY); case JSType::JS_FLOAT64_ARRAY: - return WriteJSTypedArray(obj, SerializationUID::JS_FLOAT64_ARRAY); + return WriteJSTypedArray(value, SerializationUID::JS_FLOAT64_ARRAY); case JSType::JS_ARRAY_BUFFER: - return WriteJSArrayBuffer(objValue); + return WriteJSArrayBuffer(value); case JSType::STRING: - return WriteEcmaString(objValue); + return WriteEcmaString(value); case JSType::JS_OBJECT: - return WritePlainObject(obj); + return WritePlainObject(value); default: break; } return false; } -bool JSSerializer::WriteJSError(const JSHandle &obj) +bool JSSerializer::WriteJSError(const JSHandle &value) { size_t oldSize = bufferSize_; - JSType errorType = obj->GetJSHClass()->GetObjectType(); + TaggedObject *taggedObject = value->GetTaggedObject(); + JSType errorType = taggedObject->GetClass()->GetObjectType(); if (!WriteJSErrorHeader(errorType)) { return false; } auto globalConst = thread_->GlobalConstants(); JSHandle handleMsg = globalConst->GetHandledMessageString(); - JSHandle msg = - JSObject::GetProperty(thread_, JSHandle::Cast(obj), handleMsg).GetValue(); + JSHandle msg = JSObject::GetProperty(thread_, value, handleMsg).GetValue(); // Write error message if (!SerializeJSTaggedValue(msg)) { bufferSize_ = oldSize; @@ -355,14 +348,14 @@ bool JSSerializer::WriteJSErrorHeader(JSType type) return false; } -bool JSSerializer::WriteJSDate(const JSHandle &obj) +bool JSSerializer::WriteJSDate(const JSHandle &value) { - JSHandle date = JSHandle::Cast(obj); + JSHandle date = JSHandle::Cast(value); size_t oldSize = bufferSize_; if (!WriteType(SerializationUID::JS_DATE)) { return false; } - if (!WritePlainObject(JSHandle::Cast(date))) { + if (!WritePlainObject(value)) { bufferSize_ = oldSize; return false; } @@ -379,14 +372,14 @@ bool JSSerializer::WriteJSDate(const JSHandle &obj) return true; } -bool JSSerializer::WriteJSArray(const JSHandle &obj) +bool JSSerializer::WriteJSArray(const JSHandle &value) { - JSHandle array = JSHandle::Cast(obj); + JSHandle array = JSHandle::Cast(value); size_t oldSize = bufferSize_; if (!WriteType(SerializationUID::JS_ARRAY)) { return false; } - if (!WritePlainObject(JSHandle::Cast(array))) { + if (!WritePlainObject(value)) { bufferSize_ = oldSize; return false; } @@ -419,14 +412,14 @@ bool JSSerializer::WriteEcmaString(const JSHandle &value) return true; } -bool JSSerializer::WriteJSMap(const JSHandle &obj) +bool JSSerializer::WriteJSMap(const JSHandle &value) { - JSHandle map = JSHandle::Cast(obj); + JSHandle map = JSHandle::Cast(value); size_t oldSize = bufferSize_; if (!WriteType(SerializationUID::JS_MAP)) { return false; } - if (!WritePlainObject(JSHandle::Cast(map))) { + if (!WritePlainObject(value)) { bufferSize_ = oldSize; return false; } @@ -441,8 +434,8 @@ bool JSSerializer::WriteJSMap(const JSHandle &obj) bufferSize_ = oldSize; return false; } - JSHandle value(thread_, map->GetValue(i)); - if (!SerializeJSTaggedValue(value)) { + JSHandle val(thread_, map->GetValue(i)); + if (!SerializeJSTaggedValue(val)) { bufferSize_ = oldSize; return false; } @@ -450,14 +443,14 @@ bool JSSerializer::WriteJSMap(const JSHandle &obj) return true; } -bool JSSerializer::WriteJSSet(const JSHandle &obj) +bool JSSerializer::WriteJSSet(const JSHandle &value) { - JSHandle set = JSHandle::Cast(obj); + JSHandle set = JSHandle::Cast(value); size_t oldSize = bufferSize_; if (!WriteType(SerializationUID::JS_SET)) { return false; } - if (!WritePlainObject(JSHandle::Cast(set))) { + if (!WritePlainObject(value)) { bufferSize_ = oldSize; return false; } @@ -467,8 +460,8 @@ bool JSSerializer::WriteJSSet(const JSHandle &obj) return false; } for (int i = 0; i < size; i++) { - JSHandle value(thread_, set->GetValue(i)); - if (!SerializeJSTaggedValue(value)) { + JSHandle val(thread_, set->GetValue(i)); + if (!SerializeJSTaggedValue(val)) { bufferSize_ = oldSize; return false; } @@ -476,14 +469,14 @@ bool JSSerializer::WriteJSSet(const JSHandle &obj) return true; } -bool JSSerializer::WriteJSRegExp(const JSHandle &obj) +bool JSSerializer::WriteJSRegExp(const JSHandle &value) { - JSHandle regExp = JSHandle::Cast(obj); + JSHandle regExp = JSHandle::Cast(value); size_t oldSize = bufferSize_; if (!WriteType(SerializationUID::JS_REG_EXP)) { return false; } - if (!WritePlainObject(obj)) { + if (!WritePlainObject(value)) { bufferSize_ = oldSize; return false; } @@ -515,14 +508,14 @@ bool JSSerializer::WriteJSRegExp(const JSHandle &obj) return true; } -bool JSSerializer::WriteJSTypedArray(const JSHandle &obj, SerializationUID uId) +bool JSSerializer::WriteJSTypedArray(const JSHandle &value, SerializationUID uId) { - JSHandle typedArray = JSHandle::Cast(obj); + JSHandle typedArray = JSHandle::Cast(value); size_t oldSize = bufferSize_; if (!WriteType(uId)) { return false; } - if (!WritePlainObject(obj)) { + if (!WritePlainObject(value)) { bufferSize_ = oldSize; return false; } @@ -620,7 +613,7 @@ bool JSSerializer::WriteJSArrayBuffer(const JSHandle &value) } // write obj properties - if (!WritePlainObject(JSHandle::Cast(value))) { + if (!WritePlainObject(value)) { bufferSize_ = oldSize; return false; } @@ -628,8 +621,9 @@ bool JSSerializer::WriteJSArrayBuffer(const JSHandle &value) return true; } -bool JSSerializer::WritePlainObject(const JSHandle &obj) +bool JSSerializer::WritePlainObject(const JSHandle &objValue) { + JSHandle obj = JSHandle::Cast(objValue); size_t oldSize = bufferSize_; if (!WriteType(SerializationUID::JS_PLAIN_OBJECT)) { return false; @@ -1107,81 +1101,47 @@ JSHandle JSDeserializer::ReadJSTypedArray(SerializationUID uid) switch (uid) { case SerializationUID::JS_INT8_ARRAY: { target = env->GetInt8ArrayFunction(); - JSHandle int8Array = - JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); - obj = JSHandle::Cast(int8Array); - objTag = JSHandle::Cast(obj); break; } case SerializationUID::JS_UINT8_ARRAY: { target = env->GetUint8ArrayFunction(); - JSHandle uint8Array = - JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); - obj = JSHandle::Cast(uint8Array); - objTag = JSHandle::Cast(obj); break; } case SerializationUID::JS_UINT8_CLAMPED_ARRAY: { target = env->GetUint8ClampedArrayFunction(); - JSHandle constructor = factory->NewJSObjectByConstructor(JSHandle(target), target); - JSHandle uint8ClampedArray = JSHandle::Cast(constructor); - obj = JSHandle::Cast(uint8ClampedArray); - objTag = JSHandle::Cast(obj); break; } case SerializationUID::JS_INT16_ARRAY: { target = env->GetInt16ArrayFunction(); - JSHandle int16Array = - JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); - obj = JSHandle::Cast(int16Array); - objTag = JSHandle::Cast(obj); break; } case SerializationUID::JS_UINT16_ARRAY: { target = env->GetUint16ArrayFunction(); - JSHandle uint16Array = - JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); - obj = JSHandle::Cast(uint16Array); - objTag = JSHandle::Cast(obj); break; } case SerializationUID::JS_INT32_ARRAY: { target = env->GetInt32ArrayFunction(); - JSHandle int32Array = - JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); - obj = JSHandle::Cast(int32Array); - objTag = JSHandle::Cast(obj); break; } case SerializationUID::JS_UINT32_ARRAY: { target = env->GetUint32ArrayFunction(); - JSHandle uint32Array = - JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); - obj = JSHandle::Cast(uint32Array); - objTag = JSHandle::Cast(obj); break; } case SerializationUID::JS_FLOAT32_ARRAY: { target = env->GetFloat32ArrayFunction(); - JSHandle float32Array = - JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); - obj = JSHandle::Cast(float32Array); - objTag = JSHandle::Cast(obj); - referenceMap_.insert(std::pair(objectId_++, objTag)); break; } case SerializationUID::JS_FLOAT64_ARRAY: { - target = env->GetFloat32ArrayFunction(); - JSHandle float64Array = - JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); - obj = JSHandle::Cast(float64Array); - objTag = JSHandle::Cast(obj); - referenceMap_.insert(std::pair(objectId_++, objTag)); + target = env->GetFloat64ArrayFunction(); break; } default: UNREACHABLE(); } + JSHandle typedArray = + JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); + obj = JSHandle::Cast(typedArray); + objTag = JSHandle::Cast(obj); referenceMap_.insert(std::pair(objectId_++, objTag)); if (!JudgeType(SerializationUID::JS_PLAIN_OBJECT) || !DefinePropertiesAndElements(objTag)) { return JSHandle(); @@ -1191,31 +1151,31 @@ JSHandle JSDeserializer::ReadJSTypedArray(SerializationUID uid) if (viewedArrayBuffer.IsEmpty()) { return JSHandle(); } - SetViewedArrayBuffer(obj, viewedArrayBuffer.GetTaggedValue()); + typedArray->SetViewedArrayBuffer(thread_, viewedArrayBuffer); JSHandle typedArrayName = DeserializeJSTaggedValue(); if (typedArrayName.IsEmpty()) { return JSHandle(); } - SetTypedArrayName(obj, typedArrayName); + typedArray->SetTypedArrayName(thread_, typedArrayName); JSTaggedValue byteLength; if (!ReadJSTaggedValue(&byteLength) || !byteLength.IsNumber()) { return JSHandle(); } - SetByteLength(obj, JSTaggedValue::ToInt32(thread_, JSHandle(thread_, byteLength))); + typedArray->SetByteLength(thread_, byteLength); JSTaggedValue byteOffset; if (!ReadJSTaggedValue(&byteOffset) || !byteOffset.IsNumber()) { return JSHandle(); } - SetByteOffset(obj, JSTaggedValue::ToInt32(thread_, JSHandle(thread_, byteOffset))); + typedArray->SetByteOffset(thread_, byteOffset); JSTaggedValue arrayLength; if (!ReadJSTaggedValue(&arrayLength) || !byteOffset.IsNumber()) { return JSHandle(); } - SetArrayLength(obj, JSTaggedValue::ToInt32(thread_, JSHandle(thread_, arrayLength))); + typedArray->SetArrayLength(thread_, arrayLength); return objTag; } @@ -1420,189 +1380,6 @@ bool JSDeserializer::ReadBoolean(bool *value) return false; } -void JSDeserializer::SetViewedArrayBuffer(const JSHandle &obj, JSTaggedValue viewedArrayBuffer) -{ - JSType type = obj->GetJSHClass()->GetObjectType(); - switch (type) { - case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetViewedArrayBuffer(thread_, viewedArrayBuffer); - break; - case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetViewedArrayBuffer(thread_, viewedArrayBuffer); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetViewedArrayBuffer(thread_, viewedArrayBuffer); - break; - case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetViewedArrayBuffer(thread_, viewedArrayBuffer); - break; - case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetViewedArrayBuffer(thread_, viewedArrayBuffer); - break; - case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetViewedArrayBuffer(thread_, viewedArrayBuffer); - break; - case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetViewedArrayBuffer(thread_, viewedArrayBuffer); - break; - case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetViewedArrayBuffer(thread_, viewedArrayBuffer); - break; - case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetViewedArrayBuffer(thread_, viewedArrayBuffer); - break; - default: - break; - } -} - -void JSDeserializer::SetTypedArrayName(const JSHandle &obj, const JSHandle &typedArrayName) -{ - JSType type = obj->GetJSHClass()->GetObjectType(); - switch (type) { - case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetTypedArrayName(thread_, typedArrayName); - break; - case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetTypedArrayName(thread_, typedArrayName); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetTypedArrayName(thread_, typedArrayName); - break; - case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetTypedArrayName(thread_, typedArrayName); - break; - case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetTypedArrayName(thread_, typedArrayName); - break; - case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetTypedArrayName(thread_, typedArrayName); - break; - case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetTypedArrayName(thread_, typedArrayName); - break; - case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetTypedArrayName(thread_, typedArrayName); - break; - case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetTypedArrayName(thread_, typedArrayName); - break; - default: - break; - } -} - -void JSDeserializer::SetByteLength(const JSHandle &obj, int32_t byteLength) -{ - auto byteLengthValue = JSTaggedValue(byteLength); - JSType type = obj->GetJSHClass()->GetObjectType(); - switch (type) { - case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetByteLength(thread_, byteLengthValue); - break; - case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetByteLength(thread_, byteLengthValue); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetByteLength(thread_, byteLengthValue); - break; - case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetByteLength(thread_, byteLengthValue); - break; - case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetByteLength(thread_, byteLengthValue); - break; - case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetByteLength(thread_, byteLengthValue); - break; - case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetByteLength(thread_, byteLengthValue); - break; - case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetByteLength(thread_, byteLengthValue); - break; - case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetByteLength(thread_, byteLengthValue); - break; - default: - break; - } -} - -void JSDeserializer::SetByteOffset(const JSHandle &obj, int32_t byteOffset) -{ - auto byteOffsetValue = JSTaggedValue(byteOffset); - JSType type = obj->GetJSHClass()->GetObjectType(); - switch (type) { - case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetByteOffset(thread_, byteOffsetValue); - break; - case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetByteOffset(thread_, byteOffsetValue); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetByteOffset(thread_, byteOffsetValue); - break; - case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetByteOffset(thread_, byteOffsetValue); - break; - case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetByteOffset(thread_, byteOffsetValue); - break; - case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetByteOffset(thread_, byteOffsetValue); - break; - case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetByteOffset(thread_, byteOffsetValue); - break; - case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetByteOffset(thread_, byteOffsetValue); - break; - case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetByteOffset(thread_, byteOffsetValue); - break; - default: - break; - } -} - -void JSDeserializer::SetArrayLength(const JSHandle &obj, int32_t arrayLength) -{ - auto arrayLengthValue = JSTaggedValue(arrayLength); - JSType type = obj->GetJSHClass()->GetObjectType(); - switch (type) { - case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetArrayLength(thread_, arrayLengthValue); - break; - case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetArrayLength(thread_, arrayLengthValue); - break; - case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetArrayLength(thread_, arrayLengthValue); - break; - case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetArrayLength(thread_, arrayLengthValue); - break; - case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetArrayLength(thread_, arrayLengthValue); - break; - case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetArrayLength(thread_, arrayLengthValue); - break; - case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetArrayLength(thread_, arrayLengthValue); - break; - case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetArrayLength(thread_, arrayLengthValue); - break; - case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetArrayLength(thread_, arrayLengthValue); - break; - default: - break; - } -} - bool Serializer::WriteValue( JSThread *thread, const JSHandle &value, const JSHandle &transfer) { diff --git a/ecmascript/js_serializer.h b/ecmascript/js_serializer.h index 70a5a792c7813b49e2b4563cd95c7d33d4957e91..edc774a782a7228838959f9bcf7587583e87d092 100644 --- a/ecmascript/js_serializer.h +++ b/ecmascript/js_serializer.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_SERIALIZER_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_SERIALIZER_H +#ifndef ECMASCRIPT_JS_SERIALIZER_H +#define ECMASCRIPT_JS_SERIALIZER_H #include @@ -92,7 +92,7 @@ public: std::pair ReleaseBuffer(); private: - bool WriteTaggedObject(const JSHandle &obj); + bool WriteTaggedObject(const JSHandle &value); bool WritePrimitiveValue(const JSHandle &value); bool WriteInt(int32_t value); bool WriteInt(uint32_t value); @@ -102,16 +102,16 @@ private: bool AllocateBuffer(size_t bytes); bool ExpandBuffer(size_t requestedSize); bool WriteBoolean(bool value); - bool WriteJSError(const JSHandle &obj); + bool WriteJSError(const JSHandle &value); bool WriteJSErrorHeader(JSType type); - bool WriteJSDate(const JSHandle &obj); - bool WriteJSArray(const JSHandle &obj); - bool WriteJSMap(const JSHandle &obj); - bool WriteJSSet(const JSHandle &obj); - bool WriteJSRegExp(const JSHandle &obj); + bool WriteJSDate(const JSHandle &value); + bool WriteJSArray(const JSHandle &value); + bool WriteJSMap(const JSHandle &value); + bool WriteJSSet(const JSHandle &value); + bool WriteJSRegExp(const JSHandle &value); bool WriteEcmaString(const JSHandle &value); - bool WriteJSTypedArray(const JSHandle &obj, SerializationUID uId); - bool WritePlainObject(const JSHandle &obj); + bool WriteJSTypedArray(const JSHandle &value, SerializationUID uId); + bool WritePlainObject(const JSHandle &value); bool WriteLength(uint32_t length); bool WriteNativeFunctionPointer(const JSHandle &value); bool WriteJSArrayBuffer(const JSHandle &value); @@ -166,11 +166,6 @@ private: bool DefinePropertiesAndElements(const JSHandle &obj); bool ReadDesc(PropertyDescriptor *desc); bool ReadBoolean(bool *value); - void SetViewedArrayBuffer(const JSHandle &obj, JSTaggedValue viewedArrayBuffer); - void SetTypedArrayName(const JSHandle &obj, const JSHandle &typedArrayName); - void SetByteLength(const JSHandle &obj, int32_t byteLength); - void SetByteOffset(const JSHandle &obj, int32_t byteOffset); - void SetArrayLength(const JSHandle &obj, int32_t arrayLength); NO_MOVE_SEMANTIC(JSDeserializer); NO_COPY_SEMANTIC(JSDeserializer); @@ -249,4 +244,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_SERIALIZER_H +#endif // ECMASCRIPT_JS_SERIALIZER_H diff --git a/ecmascript/js_set.h b/ecmascript/js_set.h index 81d4a5f028ceea5add9e3d374c94437a836aa0d2..0412ecf9a1535a6aad7f86f1d3982f530992d35c 100644 --- a/ecmascript/js_set.h +++ b/ecmascript/js_set.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSSET_H -#define PANDA_RUNTIME_ECMASCRIPT_JSSET_H +#ifndef ECMASCRIPT_JSSET_H +#define ECMASCRIPT_JSSET_H #include #include "js_object.h" @@ -48,4 +48,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JSSET_H +#endif // ECMASCRIPT_JSSET_H diff --git a/ecmascript/js_set_iterator.h b/ecmascript/js_set_iterator.h index aca57c689dddfc8aa1e9d04495a4e6731307046e..279f5c2021f1afbc3f954ee8428134941de9972b 100644 --- a/ecmascript/js_set_iterator.h +++ b/ecmascript/js_set_iterator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_SET_ITERATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_SET_ITERATOR_H +#ifndef ECMASCRIPT_JS_SET_ITERATOR_H +#define ECMASCRIPT_JS_SET_ITERATOR_H #include "js_object.h" #include "js_iterator.h" @@ -46,4 +46,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_SET_ITERATOR_H +#endif // ECMASCRIPT_JS_SET_ITERATOR_H diff --git a/ecmascript/js_stable_array.cpp b/ecmascript/js_stable_array.cpp index 56999a5d0e517705affda4a729a5a7c08d655428..a3939149c1952840fdefc786eca268cc244b6442 100644 --- a/ecmascript/js_stable_array.cpp +++ b/ecmascript/js_stable_array.cpp @@ -59,8 +59,129 @@ JSTaggedValue JSStableArray::Pop(JSHandle receiver, EcmaRuntimeCallInfo array_size_t capacity = elements->GetLength(); array_size_t index = length - 1; auto result = elements->Get(index); - if (JSObject::ShouldTransToDict(capacity, index)) { - elements->Trim(thread, length); + if (TaggedArray::ShouldTrim(capacity, index)) { + elements->Trim(thread, index); + } else { + elements->Set(thread, index, JSTaggedValue::Hole()); + } + receiver->SetArrayLength(thread, index); + return result; +} + +JSTaggedValue JSStableArray::Splice(JSHandle receiver, EcmaRuntimeCallInfo *argv, + double start, double insertCount, double actualDeleteCount) +{ + JSThread *thread = argv->GetThread(); + uint32_t len = receiver->GetArrayLength(); + array_size_t argc = argv->GetArgsNumber(); + + JSHandle thisObjHandle(receiver); + JSTaggedValue newArray = JSArray::ArraySpeciesCreate(thread, thisObjHandle, JSTaggedNumber(actualDeleteCount)); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + JSHandle newArrayHandle(thread, newArray); + + JSHandle thisObjVal(thisObjHandle); + JSHandle lengthKey = thread->GlobalConstants()->GetHandledLengthString(); + TaggedArray *srcElements = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject()); + JSHandle srcElementsHandle(thread, srcElements); + if (newArray.IsStableJSArray(thread)) { + TaggedArray *destElements = TaggedArray::Cast(newArrayHandle->GetElements().GetTaggedObject()); + if (actualDeleteCount > destElements->GetLength()) { + destElements = *JSObject::GrowElementsCapacity(thread, newArrayHandle, actualDeleteCount); + } + + for (array_size_t idx = 0; idx < actualDeleteCount; idx++) { + destElements->Set(thread, idx, srcElementsHandle->Get(start + idx)); + } + JSHandle::Cast(newArrayHandle)->SetArrayLength(thread, actualDeleteCount); + } else { + JSMutableHandle fromKey(thread, JSTaggedValue::Undefined()); + JSMutableHandle toKey(thread, JSTaggedValue::Undefined()); + double k = 0; + while (k < actualDeleteCount) { + double from = start + k; + fromKey.Update(JSTaggedValue(from)); + bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, fromKey); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + if (exists) { + JSHandle fromValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, fromKey); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + toKey.Update(JSTaggedValue(k)); + if (newArrayHandle->IsJSProxy()) { + toKey.Update(JSTaggedValue::ToString(thread, toKey).GetTaggedValue()); + } + JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toKey, fromValue); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + } + k++; + } + + JSHandle deleteCount(thread, JSTaggedValue(actualDeleteCount)); + JSTaggedValue::SetProperty(thread, JSHandle::Cast(newArrayHandle), lengthKey, deleteCount, + true); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + } + + array_size_t oldCapacity = srcElementsHandle->GetLength(); + array_size_t newCapacity = len - actualDeleteCount + insertCount; + if (insertCount < actualDeleteCount) { + for (array_size_t idx = start; idx < len - actualDeleteCount; idx++) { + auto element = srcElementsHandle->Get(idx + actualDeleteCount); + element = element.IsHole() ? JSTaggedValue::Undefined() : element; + srcElementsHandle->Set(thread, idx + insertCount, element); + } + + if (TaggedArray::ShouldTrim(oldCapacity, newCapacity)) { + srcElementsHandle->Trim(thread, newCapacity); + } else { + for (array_size_t idx = newCapacity; idx < len; idx++) { + srcElementsHandle->Set(thread, idx, JSTaggedValue::Hole()); + } + } + } else { + if (newCapacity > oldCapacity) { + srcElementsHandle = JSObject::GrowElementsCapacity(thread, thisObjHandle, newCapacity); + } + for (array_size_t idx = len - actualDeleteCount; idx > start; idx--) { + auto element = srcElementsHandle->Get(idx + actualDeleteCount - 1); + element = element.IsHole() ? JSTaggedValue::Undefined() : element; + srcElementsHandle->Set(thread, idx + insertCount - 1, element); + } + } + + for (array_size_t i = 2, idx = start; i < argc; i++, idx++) { + srcElementsHandle->Set(thread, idx, argv->GetCallArg(i)); + } + + JSHandle newLenHandle(thread, JSTaggedValue(newCapacity)); + JSTaggedValue::SetProperty(thread, thisObjVal, lengthKey, newLenHandle, true); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return newArrayHandle.GetTaggedValue(); +} + +JSTaggedValue JSStableArray::Shift(JSHandle receiver, EcmaRuntimeCallInfo *argv) +{ + DISALLOW_GARBAGE_COLLECTION; + JSThread *thread = argv->GetThread(); + uint32_t length = receiver->GetArrayLength(); + if (length == 0) { + return JSTaggedValue::Undefined(); + } + + TaggedArray *elements = TaggedArray::Cast(receiver->GetElements().GetTaggedObject()); + auto result = elements->Get(0); + for (array_size_t k = 1; k < length; k++) { + auto kValue = elements->Get(k); + if (kValue.IsHole()) { + elements->Set(thread, k - 1, JSTaggedValue::Undefined()); + } else { + elements->Set(thread, k - 1, kValue); + } + } + array_size_t capacity = elements->GetLength(); + array_size_t index = length - 1; + if (TaggedArray::ShouldTrim(capacity, index)) { + elements->Trim(thread, index); } else { elements->Set(thread, index, JSTaggedValue::Hole()); } diff --git a/ecmascript/js_stable_array.h b/ecmascript/js_stable_array.h index 17e4a35931d883301446553ced7ed4b5e3f8e929..2d039effd502b3cffaea63a75d6e1bd44c1ce353 100644 --- a/ecmascript/js_stable_array.h +++ b/ecmascript/js_stable_array.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_STABLE_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_STABLE_ARRAY_H +#ifndef ECMASCRIPT_JS_STABLE_ARRAY_H +#define ECMASCRIPT_JS_STABLE_ARRAY_H #include #include "ecmascript/js_array.h" @@ -24,10 +24,12 @@ namespace panda::ecmascript { class JSStableArray { public: enum SeparatorFlag : int { MINUS_ONE = -1, MINUS_TWO = -2 }; - static constexpr int FLAG_OF_SEPARATOR = 3; static JSTaggedValue Push(JSHandle receiver, EcmaRuntimeCallInfo *argv); static JSTaggedValue Pop(JSHandle receiver, EcmaRuntimeCallInfo *argv); + static JSTaggedValue Splice(JSHandle receiver, EcmaRuntimeCallInfo *argv, + double start, double insertCount, double actualDeleteCount); + static JSTaggedValue Shift(JSHandle receiver, EcmaRuntimeCallInfo *argv); static JSTaggedValue Join(JSHandle receiver, EcmaRuntimeCallInfo *argv); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_STABLE_ARRAY_H \ No newline at end of file +#endif // ECMASCRIPT_JS_STABLE_ARRAY_H \ No newline at end of file diff --git a/ecmascript/js_string_iterator.h b/ecmascript/js_string_iterator.h index 7a56db52a1f906a5c4149a16421696b1f37eb59d..d13304be5967fc22ca5890d2a33985b2637a2601 100644 --- a/ecmascript/js_string_iterator.h +++ b/ecmascript/js_string_iterator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_STRING_ITERATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_STRING_ITERATOR_H +#ifndef ECMASCRIPT_JS_STRING_ITERATOR_H +#define ECMASCRIPT_JS_STRING_ITERATOR_H #include "ecmascript/ecma_string.h" #include "ecmascript/js_handle.h" @@ -41,4 +41,4 @@ public: }; } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_STRING_ITERATOR_H +#endif // ECMASCRIPT_JS_STRING_ITERATOR_H diff --git a/ecmascript/js_symbol.h b/ecmascript/js_symbol.h index c9370567d1a3ef7f09c15534e8f23b5a4eb1b3a3..b1f4ecb18e5646388faa89632559ffebe6b0c261 100644 --- a/ecmascript/js_symbol.h +++ b/ecmascript/js_symbol.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JSSYMBOL_H -#define PANDA_RUNTIME_ECMASCRIPT_JSSYMBOL_H +#ifndef ECMASCRIPT_JSSYMBOL_H +#define ECMASCRIPT_JSSYMBOL_H #include "ecmascript/ecma_string.h" #include "ecmascript/js_object.h" @@ -152,7 +152,7 @@ public: } public: - static constexpr size_t HASHFIELD_OFFSET = sizeof(TaggedObject); + static constexpr size_t HASHFIELD_OFFSET = TaggedObjectSize(); ACCESSORS(HashField, HASHFIELD_OFFSET, FLAGS_OFFSET) ACCESSORS(Flags, FLAGS_OFFSET, DESCRIPTION_OFFSET) ACCESSORS(Description, DESCRIPTION_OFFSET, SIZE) @@ -163,4 +163,4 @@ public: }; } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_NAME_H +#endif // ECMASCRIPT_NAME_H diff --git a/ecmascript/js_tagged_number.h b/ecmascript/js_tagged_number.h index 26a249c8585c1d47a23bd530357275048549abd3..f3cd90add5e47cf19c9d8152b418d5163dbf2d01 100644 --- a/ecmascript/js_tagged_number.h +++ b/ecmascript/js_tagged_number.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_NUMBER_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_NUMBER_H +#ifndef ECMASCRIPT_JS_NUMBER_H +#define ECMASCRIPT_JS_NUMBER_H #include "ecmascript/base/number_helper.h" @@ -171,4 +171,4 @@ private: }; } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_NUMBER_H +#endif // ECMASCRIPT_JS_NUMBER_H diff --git a/ecmascript/js_tagged_value-inl.h b/ecmascript/js_tagged_value-inl.h index 406677d972b338752dc2ae23d6396da3057cca79..b38d92a8a10d775688b0a277131d69d7e31e502d 100644 --- a/ecmascript/js_tagged_value-inl.h +++ b/ecmascript/js_tagged_value-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_VALUE_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_VALUE_INL_H +#ifndef ECMASCRIPT_TAGGED_VALUE_INL_H +#define ECMASCRIPT_TAGGED_VALUE_INL_H #include "ecmascript/js_tagged_value.h" @@ -472,6 +472,41 @@ inline bool JSTaggedValue::IsPromiseRecord() const return IsHeapObject() && GetTaggedObject()->GetClass()->IsPromiseRecord(); } +inline bool JSTaggedValue::IsJSLocale() const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSLocale(); +} + +inline bool JSTaggedValue::IsJSIntl() const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSIntl(); +} + +inline bool JSTaggedValue::IsJSDateTimeFormat() const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSDateTimeFormat(); +} + +inline bool JSTaggedValue::IsJSRelativeTimeFormat() const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSRelativeTimeFormat(); +} + +inline bool JSTaggedValue::IsJSNumberFormat() const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSNumberFormat(); +} + +inline bool JSTaggedValue::IsJSCollator() const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSCollator(); +} + +inline bool JSTaggedValue::IsJSPluralRules() const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSPluralRules(); +} + inline bool JSTaggedValue::IsPromiseIteratorRecord() const { return IsHeapObject() && GetTaggedObject()->GetClass()->IsPromiseIteratorRecord(); @@ -539,6 +574,18 @@ inline bool JSTaggedValue::IsStableJSArray(JSThread *thread) const !thread->IsStableArrayElementsGuardiansInvalid(); } +inline bool JSTaggedValue::IsStableJSArguments(JSThread *thread) const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsStableJSArguments() && + !thread->IsStableArrayElementsGuardiansInvalid(); +} + +inline bool JSTaggedValue::HasStableElements(JSThread *thread) const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsStableElements() && + !thread->IsStableArrayElementsGuardiansInvalid(); +} + inline bool JSTaggedValue::IsTypedArray() const { return IsHeapObject() && GetTaggedObject()->GetClass()->IsTypedArray(); @@ -634,6 +681,11 @@ inline bool JSTaggedValue::IsBoundFunction() const return IsHeapObject() && GetTaggedObject()->GetClass()->IsJsBoundFunction(); } +inline bool JSTaggedValue::IsJSIntlBoundFunction() const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSIntlBoundFunction(); +} + inline bool JSTaggedValue::IsProxyRevocFunction() const { return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSProxyRevocFunction(); @@ -787,6 +839,11 @@ inline bool JSTaggedValue::IsJSGlobalObject() const return IsHeapObject() && GetTaggedObject()->GetClass()->IsJSGlobalObject(); } +inline bool JSTaggedValue::IsMachineCodeObject() const +{ + return IsHeapObject() && GetTaggedObject()->GetClass()->IsMachineCodeObject(); +} + inline double JSTaggedValue::ExtractNumber() const { ASSERT(IsNumber()); @@ -905,4 +962,4 @@ inline uint32_t JSTaggedValue::GetKeyHashCode() const return static_cast(JSSymbol::Cast(GetTaggedObject())->GetHashField().GetInt()); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TAGGED_VALUE__INL_H +#endif // ECMASCRIPT_TAGGED_VALUE__INL_H diff --git a/ecmascript/js_tagged_value.cpp b/ecmascript/js_tagged_value.cpp index e851beb87825addb7b6837fdc6b8379c88060d6f..b86a3f164ad775970c1e680665035206b5d3f282 100644 --- a/ecmascript/js_tagged_value.cpp +++ b/ecmascript/js_tagged_value.cpp @@ -17,6 +17,7 @@ #include "ecmascript/ecma_macros.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_array.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_primitive_ref.h" @@ -33,12 +34,12 @@ JSHandle GetTypeString(JSThread *thread, PreferredPrimitiveType type { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); if (type == NO_PREFERENCE) { - return factory->NewFromString("default"); + return factory->NewFromCanBeCompressString("default"); } if (type == PREFER_NUMBER) { - return factory->NewFromString("number"); + return factory->NewFromCanBeCompressString("number"); } - return factory->NewFromString("string"); + return factory->NewFromCanBeCompressString("string"); } JSHandle JSTaggedValue::ToPropertyKey(JSThread *thread, const JSHandle &tagged) @@ -267,11 +268,10 @@ JSTaggedValue JSTaggedValue::ToPrimitive(JSThread *thread, const JSHandle exoticToprim = JSObject::GetProperty(thread, object, keyString).GetValue(); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); if (!exoticToprim->IsUndefined()) { - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle argv = factory->NewTaggedArray(1); JSTaggedValue value = GetTypeString(thread, type).GetTaggedValue(); - argv->Set(thread, 0, value); - JSTaggedValue valueResult = JSFunction::Call(thread, exoticToprim, tagged, argv); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(value); + JSTaggedValue valueResult = JSFunction::Call(thread, exoticToprim, tagged, 1, arguments->GetArgv()); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); if (!valueResult.IsECMAObject()) { return valueResult; @@ -300,8 +300,7 @@ JSTaggedValue JSTaggedValue::OrdinaryToPrimitive(JSThread *thread, const JSHandl } JSHandle entryfunc = JSObject::GetProperty(thread, tagged, keyString).GetValue(); if (entryfunc->IsCallable()) { - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSTaggedValue valueResult = JSFunction::Call(thread, entryfunc, tagged, factory->EmptyArray()); + JSTaggedValue valueResult = JSFunction::Call(thread, entryfunc, tagged, 0, nullptr); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); if (!valueResult.IsECMAObject()) { return valueResult; @@ -355,7 +354,7 @@ JSHandle JSTaggedValue::ToString(JSThread *thread, const JSHandle &tagged) { - JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromString("-0"); + JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-0"); if (tagged->IsString()) { if (EcmaString::StringsAreEqual(static_cast(tagged->GetTaggedObject()), *str)) { return JSTaggedValue(-0.0); diff --git a/ecmascript/js_tagged_value.h b/ecmascript/js_tagged_value.h index c904f17da0d2a77ac2ad368a1fd5916bbaaa11de..3616bce3ab37f098665b03f4108cfeb479add5e0 100644 --- a/ecmascript/js_tagged_value.h +++ b/ecmascript/js_tagged_value.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_VALUE_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_VALUE_H +#ifndef ECMASCRIPT_JS_TAGGED_VALUE_H +#define ECMASCRIPT_JS_TAGGED_VALUE_H #include "ecmascript/mem/c_string.h" #include "include/coretypes/tagged_value.h" @@ -22,7 +22,7 @@ namespace panda::ecmascript { class JSObject; class JSTaggedNumber; -template +template class JSHandle; class TaggedArray; class LinkedHashMap; @@ -242,6 +242,8 @@ public: bool IsArray(JSThread *thread) const; bool IsJSArray() const; bool IsStableJSArray(JSThread *thread) const; + bool IsStableJSArguments(JSThread *thread) const; + bool HasStableElements(JSThread *thread) const; bool IsTypedArray() const; bool IsJSTypedArray() const; bool IsJSInt8Array() const; @@ -256,6 +258,7 @@ public: bool IsArguments() const; bool IsDate() const; bool IsBoundFunction() const; + bool IsJSIntlBoundFunction() const; bool IsProxyRevocFunction() const; bool IsJSAsyncFunction() const; bool IsJSAsyncAwaitStatusFunction() const; @@ -303,12 +306,20 @@ public: bool IsJSFunctionExtraInfo() const; bool IsMicroJobQueue() const; bool IsPendingJob() const; + bool IsJSLocale() const; + bool IsJSDateTimeFormat() const; + bool IsJSRelativeTimeFormat() const; + bool IsJSIntl() const; + bool IsJSNumberFormat() const; + bool IsJSCollator() const; + bool IsJSPluralRules() const; bool IsPrototypeHandler() const; bool IsTransitionHandler() const; bool IsPropertyBox() const; bool IsProtoChangeMarker() const; bool IsProtoChangeDetails() const; + bool IsMachineCodeObject() const; static bool IsSameTypeOrHClass(JSTaggedValue x, JSTaggedValue y); static ComparisonResult Compare(JSThread *thread, const JSHandle &x, @@ -333,4 +344,4 @@ private: void DumpHeapObjectType([[maybe_unused]] JSThread *thread, std::ostream &os) const; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TAGGED_VALUE_H +#endif // ECMASCRIPT_JS_TAGGED_VALUE_H diff --git a/ecmascript/js_thread.cpp b/ecmascript/js_thread.cpp index a8ab74bdb1bb993f0299fb77f2dd0e45d809b54a..f2352867b9ef8d99579a91b8946df96b78b13597 100644 --- a/ecmascript/js_thread.cpp +++ b/ecmascript/js_thread.cpp @@ -14,6 +14,7 @@ */ #include "ecmascript/global_env_constants-inl.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/interpreter-inl.h" #include "ecmascript/js_thread.h" #include "include/panda_vm.h" @@ -39,8 +40,9 @@ JSThread::JSThread(Runtime *runtime, PandaVM *vm) Thread::ThreadType::THREAD_TYPE_MANAGED) { SetLanguageContext(runtime->GetLanguageContext(panda_file::SourceLang::ECMASCRIPT)); - globalHandleStorage_ = - EcmaVM::Cast(vm)->GetChunk()->New>(runtime->GetInternalAllocator()); + auto chunk = EcmaVM::Cast(vm)->GetChunk(); + globalStorage_ = chunk->New(chunk); + internalCallParams_ = new InternalCallParams(); } JSThread::~JSThread() @@ -51,11 +53,12 @@ JSThread::~JSThread() handleStorageNodes_.clear(); currentHandleStorageIndex_ = -1; handleScopeStorageNext_ = handleScopeStorageEnd_ = nullptr; - EcmaVM::Cast(GetVM())->GetChunk()->Delete(globalHandleStorage_); + EcmaVM::Cast(GetVM())->GetChunk()->Delete(globalStorage_); GetRegionFactory()->Free(frameBase_, sizeof(JSTaggedType) * MAX_STACK_SIZE); frameBase_ = nullptr; regionFactory_ = nullptr; + delete internalCallParams_; } EcmaVM *JSThread::GetEcmaVM() const @@ -88,6 +91,8 @@ void JSThread::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) globalConst_.Visitor(v1); // visit stack roots EcmaFrameHandler(currentFrame_).Iterate(v0, v1); + // visit internal call params + internalCallParams_->Iterate(v1); // visit tagged handle storage roots if (currentHandleStorageIndex_ != -1) { @@ -100,12 +105,15 @@ void JSThread::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) } } // visit global handle storage roots - if (globalHandleStorage_->GetNodes()->empty()) { + if (globalStorage_->GetNodes()->empty()) { return; } - for (size_t i = 0; i < globalHandleStorage_->GetNodes()->size() - 1; i++) { - auto block = globalHandleStorage_->GetNodes()->at(i); - auto size = GlobalHandleStorage::GLOBAL_BLOCK_SIZE; + for (size_t i = 0; i < globalStorage_->GetNodes()->size(); i++) { + auto block = globalStorage_->GetNodes()->at(i); + auto size = EcmaGlobalStorage::GLOBAL_BLOCK_SIZE; + if (i == globalStorage_->GetNodes()->size() - 1) { + size = globalStorage_->GetCount(); + } for (auto j = 0; j < size; j++) { JSTaggedValue value(block->at(j).GetObject()); @@ -114,13 +122,33 @@ void JSThread::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) } } } +} + +void JSThread::IterateWeakEcmaGlobalStorage(const WeakRootVisitor &visitor) +{ + if (globalStorage_->GetWeakNodes()->empty()) { + return; + } + for (size_t i = 0; i < globalStorage_->GetWeakNodes()->size(); i++) { + auto block = globalStorage_->GetWeakNodes()->at(i); + auto size = EcmaGlobalStorage::GLOBAL_BLOCK_SIZE; + if (i == globalStorage_->GetWeakNodes()->size() - 1) { + size = globalStorage_->GetWeakCount(); + } - auto block = globalHandleStorage_->GetNodes()->back(); - auto size = globalHandleStorage_->GetCount(); - for (auto j = 0; j < size; j++) { - JSTaggedValue value(block->at(j).GetObject()); - if (value.IsHeapObject()) { - v0(ecmascript::Root::ROOT_HANDLE, ecmascript::ObjectSlot(block->at(j).GetObjectAddress())); + for (auto j = 0; j < size; j++) { + JSTaggedValue value(block->at(j).GetObject()); + if (value.IsHeapObject()) { + auto object = value.GetTaggedObject(); + auto fwd = visitor(object); + if (fwd == nullptr) { + // undefind + block->at(j).SetObject(JSTaggedValue::Undefined().GetRawData()); + } else if (fwd != object) { + // update + block->at(j).SetObject(JSTaggedValue(fwd).GetRawData()); + } + } } } } @@ -159,18 +187,9 @@ uintptr_t *JSThread::ExpandHandleStorage() return result; } -void JSThread::ShrunkHandleStorage(const JSTaggedType *end) +void JSThread::ShrinkHandleStorage(int prevIndex) { - for (int32_t i = currentHandleStorageIndex_; i >= 0; i--) { - auto node = handleStorageNodes_[i]; - auto currentEnd = &node->data()[NODE_BLOCK_SIZE]; - if (end == currentEnd) { - currentHandleStorageIndex_ = i; - return; - } - } - ASSERT(end == nullptr); - currentHandleStorageIndex_ = -1; + currentHandleStorageIndex_ = prevIndex; } void JSThread::NotifyStableArrayElementsGuardians(JSHandle receiver) diff --git a/ecmascript/js_thread.h b/ecmascript/js_thread.h index 7b45bb236879cede3a41a558cb6d694965c39918..eef175a525e535a575b3759f799927c91aea043a 100644 --- a/ecmascript/js_thread.h +++ b/ecmascript/js_thread.h @@ -13,21 +13,24 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_THREAD_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_THREAD_H +#ifndef ECMASCRIPT_JS_THREAD_H +#define ECMASCRIPT_JS_THREAD_H +#include "ecmascript/compiler/fast_stub_define.h" +#include "ecmascript/ecma_global_storage.h" #include "ecmascript/global_env_constants.h" #include "ecmascript/interpreter/frame_handler.h" #include "ecmascript/mem/heap_roots.h" -#include "global_handle_storage-inl.h" #include "include/thread.h" namespace panda::ecmascript { class EcmaVM; class RegionFactory; +class InternalCallParams; class JSThread : public ManagedThread { public: + using Address = uintptr_t; static JSThread *Cast(ManagedThread *thread) { ASSERT(thread != nullptr); @@ -62,7 +65,7 @@ public: isSnapshotMode_ = value; } - JSTaggedType *GetCurrentSPFrame() const + const JSTaggedType *GetCurrentSPFrame() const { return currentFrame_; } @@ -92,7 +95,7 @@ public: void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1); uintptr_t *ExpandHandleStorage(); - void ShrunkHandleStorage(const JSTaggedType *end); + void ShrinkHandleStorage(int prevIndex); JSTaggedType *GetHandleScopeStorageNext() const { @@ -114,6 +117,11 @@ public: handleScopeStorageEnd_ = value; } + int GetCurrentHandleStorageIndex() + { + return currentHandleStorageIndex_; + } + void SetException(JSTaggedValue exception); JSTaggedValue GetException() const @@ -128,9 +136,9 @@ public: void ClearException(); - GlobalHandleStorage *GetGlobalHandleStorage() const + EcmaGlobalStorage *GetEcmaGlobalStorage() const { - return globalHandleStorage_; + return globalStorage_; } const GlobalEnvConstants *GlobalConstants() const @@ -149,37 +157,64 @@ public: JSTaggedValue GetCurrentLexenv() const; + void SetRuntimeFunction(uint32_t id, uintptr_t functionAddress) + { + ASSERT(id < MAX_RUNTIME_FUNCTIONS); + runtimeFunctions[id] = functionAddress; + } + + static uint32_t GetRuntimeFunctionsOffset() + { + return MEMBER_OFFSET(JSThread, runtimeFunctions); + } + + static uint64_t GetCurrentFrameOffset() + { + return MEMBER_OFFSET(JSThread, currentFrame_); + } + + InternalCallParams *GetInternalCallParams() const + { + return internalCallParams_; + } + + void IterateWeakEcmaGlobalStorage(const WeakRootVisitor &visitor); + private: NO_COPY_SEMANTIC(JSThread); NO_MOVE_SEMANTIC(JSThread); void DumpStack() DUMP_API_ATTR; - static constexpr uint32_t MAX_STACK_SIZE = 256 * 1024; + static constexpr uint32_t MAX_STACK_SIZE = 128 * 1024; static constexpr uint32_t RESERVE_STACK_SIZE = 128; static const uint32_t NODE_BLOCK_SIZE_LOG2 = 10; static const uint32_t NODE_BLOCK_SIZE = 1U << NODE_BLOCK_SIZE_LOG2; + static constexpr uint32_t MAX_RUNTIME_FUNCTIONS = + kungfu::EXTERN_RUNTIME_STUB_MAXCOUNT - kungfu::EXTERNAL_RUNTIME_STUB_BEGIN - 1; - GlobalHandleStorage *globalHandleStorage_{nullptr}; + EcmaGlobalStorage *globalStorage_ {nullptr}; os::memory::ConditionVariable initializationVar_ GUARDED_BY(initializationLock_); os::memory::Mutex initializationLock_; int nestedLevel_ = 0; - JSTaggedType *currentFrame_{nullptr}; - JSTaggedType *frameBase_{nullptr}; - bool isSnapshotMode_{false}; - bool isEcmaInterpreter_{false}; - RegionFactory *regionFactory_{nullptr}; - JSTaggedType *handleScopeStorageNext_{nullptr}; - JSTaggedType *handleScopeStorageEnd_{nullptr}; - std::vector *> handleStorageNodes_{}; - int32_t currentHandleStorageIndex_{-1}; - JSTaggedValue exception_{JSTaggedValue::Hole()}; - bool stableArrayElementsGuardians_{true}; + JSTaggedType *currentFrame_ {nullptr}; + JSTaggedType *frameBase_ {nullptr}; + bool isSnapshotMode_ {false}; + bool isEcmaInterpreter_ {false}; + RegionFactory *regionFactory_ {nullptr}; + JSTaggedType *handleScopeStorageNext_ {nullptr}; + JSTaggedType *handleScopeStorageEnd_ {nullptr}; + std::vector *> handleStorageNodes_ {}; + int32_t currentHandleStorageIndex_ {-1}; + JSTaggedValue exception_ {JSTaggedValue::Hole()}; + bool stableArrayElementsGuardians_ {true}; GlobalEnvConstants globalConst_; // Place-Holder + Address runtimeFunctions[MAX_RUNTIME_FUNCTIONS]; + InternalCallParams *internalCallParams_ {nullptr}; friend class EcmaHandleScope; friend class GlobalHandleCollection; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_THREAD_H +#endif // ECMASCRIPT_JS_THREAD_H diff --git a/ecmascript/js_typed_array.cpp b/ecmascript/js_typed_array.cpp index fb9c4f9634ee51cd45cae835eb7220ee8717ba75..74482577574532ba8ce183dc2090c1ea378260e9 100644 --- a/ecmascript/js_typed_array.cpp +++ b/ecmascript/js_typed_array.cpp @@ -89,7 +89,7 @@ bool JSTypedArray::HasProperty(JSThread *thread, const JSHandle & JSTaggedValue numericIndex = JSTaggedValue::CanonicalNumericIndexString(thread, key); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); if (!numericIndex.IsUndefined()) { - JSTaggedValue buffer = TypedArrayHelper::GetViewedArrayBuffer(typedarrayObj); + JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer(); if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", false); } @@ -310,7 +310,7 @@ OperationResult JSTypedArray::IntegerIndexedElementGet(JSThread *thread, const J ASSERT(typedarray->IsTypedArray()); // 3. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. JSHandle typedarrayObj(typedarray); - JSTaggedValue buffer = TypedArrayHelper::GetViewedArrayBuffer(typedarrayObj); + JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer(); // 4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", @@ -353,6 +353,44 @@ OperationResult JSTypedArray::IntegerIndexedElementGet(JSThread *thread, const J return OperationResult(thread, result, PropertyMetaData(true)); } +// static +bool JSTypedArray::FastCopyElementToArray(JSThread *thread, const JSHandle &typedArray, + JSHandle &array) +{ + // 2. Assert: O is an Object that has [[ViewedArrayBuffer]], [[ArrayLength]], [[ByteOffset]], and + // [[TypedArrayName]] internal slots. + ASSERT(typedArray->IsTypedArray()); + // 3. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. + JSHandle typedarrayObj(typedArray); + JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer(); + // 4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. + if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { + THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", false); + } + + // 7. Let length be the value of O’s [[ArrayLength]] internal slot. + // 8. If index < 0 or index ≥ length, return undefined. + int32_t arrLen = TypedArrayHelper::GetArrayLength(thread, typedarrayObj); + if (arrLen < 0) { + return false; + } + + // 9. Let offset be the value of O’s [[ByteOffset]] internal slot. + int32_t offset = TypedArrayHelper::GetByteOffset(thread, typedarrayObj); + // 11. Let elementSize be the Number value of the Element Size value specified in Table 49 for arrayTypeName. + int32_t elementSize = TypedArrayHelper::GetElementSize(typedarrayObj); + // 13. Let elementType be the String value of the Element Type value in Table 49 for arrayTypeName. + DataViewType elementType = TypedArrayHelper::GetType(typedarrayObj); + for (int index = 0; index < arrLen; index++) { + // 12. Let indexedPosition = (index × elementSize) + offset. + int32_t byteIndex = index * elementSize + offset; + // 14. Return GetValueFromBuffer(buffer, indexedPosition, elementType). + JSTaggedValue result = BuiltinsArrayBuffer::GetValueFromBuffer(buffer, byteIndex, elementType, true); + array->Set(thread, index, result); + } + return true; +} + // static OperationResult JSTypedArray::FastElementGet(JSThread *thread, const JSHandle &typedarray, uint32_t index) @@ -362,7 +400,7 @@ OperationResult JSTypedArray::FastElementGet(JSThread *thread, const JSHandleIsTypedArray()); // 3. Let buffer be the value of O’s [[ViewedArrayBuffer]] internal slot. JSHandle typedarrayObj(typedarray); - JSTaggedValue buffer = TypedArrayHelper::GetViewedArrayBuffer(typedarrayObj); + JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer(); // 4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", @@ -404,7 +442,7 @@ bool JSTypedArray::IntegerIndexedElementSet(JSThread *thread, const JSHandle typedarrayObj(typedarray); - JSTaggedValue buffer = TypedArrayHelper::GetViewedArrayBuffer(typedarrayObj); + JSTaggedValue buffer = JSTypedArray::Cast(*typedarrayObj)->GetViewedArrayBuffer(); // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. if (BuiltinsArrayBuffer::IsDetachedBuffer(buffer)) { THROW_TYPE_ERROR_AND_RETURN(thread, "Is Detached Buffer", false); diff --git a/ecmascript/js_typed_array.h b/ecmascript/js_typed_array.h index 7ddd78a91d24f8e495db628fe6aecf094011684b..ab8a36cce6db869d731492e2424661cd373956cc 100644 --- a/ecmascript/js_typed_array.h +++ b/ecmascript/js_typed_array.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_TYPED_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_TYPED_ARRAY_H +#ifndef ECMASCRIPT_JS_TYPED_ARRAY_H +#define ECMASCRIPT_JS_TYPED_ARRAY_H #include "ecmascript/tagged_array.h" #include "js_object.h" @@ -24,7 +24,7 @@ class JSTypedArray : public JSObject { public: static JSTypedArray *Cast(ObjectHeader *object) { - ASSERT(JSTaggedValue(object).IsJSTypedArray()); + ASSERT(JSTaggedValue(object).IsTypedArray() || JSTaggedValue(object).IsJSTypedArray()); return static_cast(object); } @@ -70,6 +70,8 @@ public: static OperationResult IntegerIndexedElementGet(JSThread *thread, const JSHandle &typedarray, JSTaggedValue index); static OperationResult FastElementGet(JSThread *thread, const JSHandle &typedarray, uint32_t index); + static bool FastCopyElementToArray(JSThread *thread, const JSHandle &typedArray, + JSHandle &array); // 9.4.5.9 IntegerIndexedElementSet ( O, index, value ) static bool IntegerIndexedElementSet(JSThread *thread, const JSHandle &typedarray, JSTaggedValue index, const JSHandle &value); @@ -87,4 +89,4 @@ public: DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE) }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_TYPED_ARRAY_H \ No newline at end of file +#endif // ECMASCRIPT_JS_TYPED_ARRAY_H diff --git a/ecmascript/js_uint32_array.h b/ecmascript/js_uint32_array.h deleted file mode 100644 index f05e0d5116a57c0d5bcf772cfe47dc1b4803ef8b..0000000000000000000000000000000000000000 --- a/ecmascript/js_uint32_array.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_UINT32_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_UINT32_ARRAY_H - -#include -#include "ecmascript/js_object.h" -#include "ecmascript/js_tagged_value-inl.h" -#include "ecmascript/js_tagged_value.h" - -namespace panda::ecmascript { -class JSUint32Array : public JSObject { -public: - static JSUint32Array *Cast(ObjectHeader *object) - { - ASSERT(JSTaggedValue(object).IsJSUint32Array()); - return static_cast(object); - } - - static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE; - ACCESSORS(ViewedArrayBuffer, VIEWED_ARRAY_BUFFER_OFFSET, TYPED_ARRAY_NAME_OFFSET) - ACCESSORS(TypedArrayName, TYPED_ARRAY_NAME_OFFSET, BYTE_LENGTH_OFFSET) - ACCESSORS(ByteLength, BYTE_LENGTH_OFFSET, BYTE_OFFSET_OFFSET) - ACCESSORS(ByteOffset, BYTE_OFFSET_OFFSET, ARRAY_LENGTH_OFFSET) - ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, SIZE) - DECL_DUMP() - - DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE) -}; // namespace panda::ecmascript -} // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_UINT32_ARRAY_H \ No newline at end of file diff --git a/ecmascript/js_uint8_clamped_array.h b/ecmascript/js_uint8_clamped_array.h deleted file mode 100644 index 1f3aa6ae3c451768acc5da3d3a5d06c7bf29f4a5..0000000000000000000000000000000000000000 --- a/ecmascript/js_uint8_clamped_array.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_UINT8_CLAMPED_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_UINT8_CLAMPED_ARRAY_H - -#include -#include "ecmascript/js_object.h" -#include "ecmascript/js_tagged_value-inl.h" -#include "ecmascript/js_tagged_value.h" - -namespace panda::ecmascript { -class JSUint8ClampedArray : public JSObject { -public: - static JSUint8ClampedArray *Cast(ObjectHeader *object) - { - ASSERT(JSTaggedValue(object).IsJSUint8ClampedArray()); - return static_cast(object); - } - - static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE; - ACCESSORS(ViewedArrayBuffer, VIEWED_ARRAY_BUFFER_OFFSET, TYPED_ARRAY_NAME_OFFSET) - ACCESSORS(TypedArrayName, TYPED_ARRAY_NAME_OFFSET, BYTE_LENGTH_OFFSET) - ACCESSORS(ByteLength, BYTE_LENGTH_OFFSET, BYTE_OFFSET_OFFSET) - ACCESSORS(ByteOffset, BYTE_OFFSET_OFFSET, ARRAY_LENGTH_OFFSET) - ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, SIZE) - DECL_DUMP() - - DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE) -}; // namespace panda::ecmascript -} // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_UINT8_CLAMPED_ARRAY_H \ No newline at end of file diff --git a/ecmascript/js_vm/BUILD.gn b/ecmascript/js_vm/BUILD.gn index aebea98b85a4f49764ae17781568e6b59b50f8ea..0f9aaa5172bd56259eea39128f8099bb087e5895 100644 --- a/ecmascript/js_vm/BUILD.gn +++ b/ecmascript/js_vm/BUILD.gn @@ -25,15 +25,15 @@ ohos_executable("ark_js_vm") { deps = [ "$ark_root/libpandabase:libarkbase", - "//ark/js_runtime:libark_jsruntime_static", + "//ark/js_runtime:libark_jsruntime", ] if (!is_standard_system) { deps += [ "$ark_root/runtime:libarkruntime" ] } - install_enable = false part_name = "ark_js_runtime" + install_enable = false output_name = "ark_js_vm" subsystem_name = "ark" diff --git a/ecmascript/js_vm/main.cpp b/ecmascript/js_vm/main.cpp index abaa6ee2ab97e96ef04e8281588a0d5ded282f60..a3bad4b9ed4861c2b6459d07abec7cc6640c0780 100644 --- a/ecmascript/js_vm/main.cpp +++ b/ecmascript/js_vm/main.cpp @@ -21,6 +21,7 @@ #include #include "ecmascript/ecma_language_context.h" +#include "ecmascript/ecma_string.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/napi/include/jsnapi.h" #include "include/runtime.h" @@ -45,7 +46,7 @@ void BlockSignals() } if (panda::os::native_stack::g_PandaThreadSigmask(SIG_BLOCK, &set, nullptr) != 0) { - LOG(ERROR, RUNTIME) << "PandaThreadSigmask failed"; + LOG(ERROR, RUNTIME) << "g_PandaThreadSigmask failed"; } #endif // PANDA_TARGET_UNIX } diff --git a/ecmascript/js_weak_container.h b/ecmascript/js_weak_container.h index 6217fe7652cf68755cd75e8adb3863e6c24b4206..e7f276c78226d43f1d9263cd18e78627855254d0 100644 --- a/ecmascript/js_weak_container.h +++ b/ecmascript/js_weak_container.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_WEAK_CONTAINER_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_WEAK_CONTAINER_H +#ifndef ECMASCRIPT_JS_WEAK_CONTAINER_H +#define ECMASCRIPT_JS_WEAK_CONTAINER_H #include #include "ecmascript/js_object.h" @@ -69,4 +69,4 @@ public: DECL_DUMP() }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_WEAK_CONTAINER_H \ No newline at end of file +#endif // ECMASCRIPT_JS_WEAK_CONTAINER_H \ No newline at end of file diff --git a/ecmascript/layout_info-inl.h b/ecmascript/layout_info-inl.h index 06b0873dc60032a4bd9c1401472a1fd947948d88..c4a20731556bd6c0986137ff303b329eafea99ee 100644 --- a/ecmascript/layout_info-inl.h +++ b/ecmascript/layout_info-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_LAYOUT_INFO_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_LAYOUT_INFO_INL_H +#ifndef ECMASCRIPT_LAYOUT_INFO_INL_H +#define ECMASCRIPT_LAYOUT_INFO_INL_H #include "ecmascript/layout_info.h" #include "ecmascript/tagged_array-inl.h" @@ -171,4 +171,4 @@ inline int LayoutInfo::BinarySearch(JSTaggedValue key, int propertiesNumber) return -1; } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_LAYOUT_INFO_INL_H +#endif // ECMASCRIPT_LAYOUT_INFO_INL_H diff --git a/ecmascript/layout_info.h b/ecmascript/layout_info.h index 64a3e4af9bf16ff5bb8e53d09595344cffde41b1..9753ff8804487b4e1bcd70f4f8c31f7b1a523510 100644 --- a/ecmascript/layout_info.h +++ b/ecmascript/layout_info.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_LAYOUT_INFO_H -#define PANDA_RUNTIME_ECMASCRIPT_LAYOUT_INFO_H +#ifndef ECMASCRIPT_LAYOUT_INFO_H +#define ECMASCRIPT_LAYOUT_INFO_H #include "ecmascript/tagged_array.h" #include "ecmascript/property_attributes.h" @@ -88,4 +88,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_LAYOUT_INFO_H +#endif // ECMASCRIPT_LAYOUT_INFO_H diff --git a/ecmascript/lexical_env.h b/ecmascript/lexical_env.h index a504fa0cd919e79a10edc2cdd545fd443342b6f2..cedda236d5f29bbf690ef5fb66d11a4db9fc00ae 100644 --- a/ecmascript/lexical_env.h +++ b/ecmascript/lexical_env.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_LEXICALENV_H -#define PANDA_RUNTIME_ECMASCRIPT_LEXICALENV_H +#ifndef ECMASCRIPT_LEXICALENV_H +#define ECMASCRIPT_LEXICALENV_H #include "ecmascript/js_object.h" @@ -58,4 +58,4 @@ public: DECL_DUMP() }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_LEXICALENV_H +#endif // ECMASCRIPT_LEXICALENV_H diff --git a/ecmascript/linked_hash_table-inl.h b/ecmascript/linked_hash_table-inl.h index ee007aa70d90c2ef0b5a0a9c69587287ea66e444..b64e2c57a6e9960e5900e76634c5c0b56206c083 100644 --- a/ecmascript/linked_hash_table-inl.h +++ b/ecmascript/linked_hash_table-inl.h @@ -13,15 +13,15 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_LINKED_HASH_TABLE_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_LINKED_HASH_TABLE_INL_H +#ifndef ECMASCRIPT_LINKED_HASH_TABLE_INL_H +#define ECMASCRIPT_LINKED_HASH_TABLE_INL_H #include "linked_hash_table.h" #include "tagged_array-inl.h" #include "utils/bit_utils.h" namespace panda::ecmascript { -template +template JSTaggedValue LinkedHashTable::GetElement(int index) const { if (UNLIKELY((index < 0 || index > static_cast(GetLength())))) { @@ -30,7 +30,7 @@ JSTaggedValue LinkedHashTable::GetElement(int index) const return Get(index); } -template +template void LinkedHashTable::SetElement(const JSThread *thread, int index, JSTaggedValue element) { if (UNLIKELY((index < 0 || index > static_cast(GetLength())))) { @@ -39,69 +39,69 @@ void LinkedHashTable::SetElement(const JSThread *thread, in Set(thread, index, element); } -template +template int LinkedHashTable::NumberOfElements() const { return Get(NUMBER_OF_ELEMENTS_INDEX).GetInt(); } -template +template int LinkedHashTable::NumberOfDeletedElements() const { return Get(NUMBER_OF_DELETED_ELEMENTS_INDEX).GetInt(); } -template +template int LinkedHashTable::Capacity() const { return JSTaggedValue(Get(CAPACITY_INDEX)).GetInt(); } -template +template void LinkedHashTable::SetNumberOfElements(const JSThread *thread, int nof) { Set(thread, NUMBER_OF_ELEMENTS_INDEX, JSTaggedValue(nof)); } -template +template void LinkedHashTable::SetNumberOfDeletedElements(const JSThread *thread, int nod) { Set(thread, NUMBER_OF_DELETED_ELEMENTS_INDEX, JSTaggedValue(nod)); } -template +template void LinkedHashTable::SetCapacity(const JSThread *thread, int capacity) { Set(thread, CAPACITY_INDEX, JSTaggedValue(capacity)); } -template +template void LinkedHashTable::SetNextTable(const JSThread *thread, JSTaggedValue nextTable) { Set(thread, NEXT_TABLE_INDEX, nextTable); } -template +template JSTaggedValue LinkedHashTable::GetNextTable() const { return JSTaggedValue(Get(NEXT_TABLE_INDEX)); } -template +template int LinkedHashTable::GetDeletedNum(int entry) const { ASSERT_PRINT(!GetNextTable().IsUndefined(), "function only execute after rehash"); return GetNextEntry(entry).GetInt(); } -template +template void LinkedHashTable::SetDeletedNum(const JSThread *thread, int entry, JSTaggedValue num) { ASSERT_PRINT(!GetNextTable().IsUndefined(), "function only execute after rehash"); SetNextEntry(thread, entry, num); } -template +template int LinkedHashTable::GetDeletedElementsAt(int entry) const { ASSERT_PRINT(!GetNextTable().IsUndefined(), "function only execute after rehash"); @@ -115,67 +115,67 @@ int LinkedHashTable::GetDeletedElementsAt(int entry) const return 0; } -template +template uint32_t LinkedHashTable::HashToBucket(uint32_t hash) const { return hash & static_cast(Capacity() - 1); } -template +template uint32_t LinkedHashTable::BucketToIndex(uint32_t bucket) { return bucket + ELEMENTS_START_INDEX; } -template +template uint32_t LinkedHashTable::EntryToIndex(uint32_t entry) const { return ELEMENTS_START_INDEX + Capacity() + entry * (HashObject::ENTRY_SIZE + 1); } -template +template void LinkedHashTable::SetKey(const JSThread *thread, int entry, JSTaggedValue key) { int index = EntryToIndex(entry); SetElement(thread, index, key); } -template +template JSTaggedValue LinkedHashTable::GetKey(int entry) const { int index = EntryToIndex(entry); return GetElement(index); } -template +template JSTaggedValue LinkedHashTable::GetValue(int entry) const { int index = EntryToIndex(entry) + HashObject::ENTRY_VALUE_INDEX; return GetElement(index); } -template +template void LinkedHashTable::SetValue(const JSThread *thread, int entry, JSTaggedValue value) { int index = EntryToIndex(entry) + HashObject::ENTRY_VALUE_INDEX; SetElement(thread, index, value); } -template +template JSTaggedValue LinkedHashTable::GetNextEntry(int entry) const { int index = EntryToIndex(entry) + HashObject::ENTRY_SIZE; return GetElement(index); } -template +template void LinkedHashTable::SetNextEntry(const JSThread *thread, int entry, JSTaggedValue nextEntry) { int index = EntryToIndex(entry) + HashObject::ENTRY_SIZE; SetElement(thread, index, nextEntry); } -template +template void LinkedHashTable::InsertNewEntry(const JSThread *thread, int bucket, int entry) { int bucketIndex = BucketToIndex(bucket); @@ -184,7 +184,7 @@ void LinkedHashTable::InsertNewEntry(const JSThread *thread SetElement(thread, bucketIndex, JSTaggedValue(entry)); } -template +template int LinkedHashTable::FindElement(JSTaggedValue key) const { if (!IsKey(key)) { @@ -208,7 +208,7 @@ int LinkedHashTable::FindElement(JSTaggedValue key) const return -1; } // namespace panda::ecmascript -template +template bool LinkedHashTable::HasSufficientCapacity(int numOfAddElements) const { int numberOfElements = NumberOfElements(); @@ -227,7 +227,7 @@ bool LinkedHashTable::HasSufficientCapacity(int numOfAddEle return false; } -template +template int LinkedHashTable::ComputeCapacity(uint32_t atLeastSpaceFor) { // Add 50% slack to make slot collisions sufficiently unlikely. @@ -237,7 +237,7 @@ int LinkedHashTable::ComputeCapacity(uint32_t atLeastSpaceF return (capacity > MIN_CAPACITY) ? capacity : MIN_CAPACITY; } -template +template void LinkedHashTable::RemoveEntry(const JSThread *thread, int entry) { ASSERT_PRINT(entry >= 0 && entry < Capacity(), "entry must be a non-negative integer less than capacity"); @@ -249,7 +249,7 @@ void LinkedHashTable::RemoveEntry(const JSThread *thread, i SetNumberOfDeletedElements(thread, NumberOfDeletedElements() + 1); } -template +template int LinkedHashTable::ComputeCapacityWithShrink(int currentCapacity, int atLeastSpaceFor) { // Shrink to fit the number of elements if only a quarter of the @@ -272,4 +272,4 @@ bool LinkedHashMapObject::IsMatch(JSTaggedValue key, JSTaggedValue other) return JSTaggedValue::SameValueZero(key, other); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_LINKED_HASH_TABLE_INL_H \ No newline at end of file +#endif // ECMASCRIPT_LINKED_HASH_TABLE_INL_H \ No newline at end of file diff --git a/ecmascript/linked_hash_table.cpp b/ecmascript/linked_hash_table.cpp index 9f79ba560eb05739f64d744fbb30ede0d3c41a8d..da33da77538c00f64c79a77c5ed38cab59fdf9ec 100644 --- a/ecmascript/linked_hash_table.cpp +++ b/ecmascript/linked_hash_table.cpp @@ -20,7 +20,7 @@ #include "object_factory.h" namespace panda::ecmascript { -template +template Derived *LinkedHashTable::Create(const JSThread *thread, int numberOfElements) { ASSERT_PRINT(numberOfElements > 0, "size must be a non-negative integer"); @@ -36,7 +36,7 @@ Derived *LinkedHashTable::Create(const JSThread *thread, in return table; } -template +template Derived *LinkedHashTable::Insert(const JSThread *thread, const JSHandle &table, const JSHandle &key, const JSHandle &value) @@ -61,7 +61,7 @@ Derived *LinkedHashTable::Insert(const JSThread *thread, co return newTable; } -template +template Derived *LinkedHashTable::InsertWeakRef(const JSThread *thread, const JSHandle &table, const JSHandle &key, const JSHandle &value) @@ -90,7 +90,7 @@ Derived *LinkedHashTable::InsertWeakRef(const JSThread *thr return newTable; } -template +template void LinkedHashTable::Rehash(const JSThread *thread, Derived *newTable) { ASSERT_PRINT(newTable != nullptr && newTable->Capacity() > NumberOfElements(), "can not rehash to new table"); @@ -126,7 +126,7 @@ void LinkedHashTable::Rehash(const JSThread *thread, Derive newTable->SetNumberOfDeletedElements(thread, 0); } -template +template Derived *LinkedHashTable::GrowCapacity(const JSThread *thread, const JSHandle &table, int numberOfAddedElements) { @@ -139,7 +139,7 @@ Derived *LinkedHashTable::GrowCapacity(const JSThread *thre return newTable; } -template +template Derived *LinkedHashTable::Remove(const JSThread *thread, const JSHandle &table, const JSHandle &key) { @@ -152,7 +152,7 @@ Derived *LinkedHashTable::Remove(const JSThread *thread, co return Shrink(thread, table); } -template +template Derived *LinkedHashTable::Shrink(const JSThread *thread, const JSHandle &table, int additionalCapacity) { diff --git a/ecmascript/linked_hash_table.h b/ecmascript/linked_hash_table.h index ec5bb124e4e32ea235e88033cad32be4e3a9acbb..b81939372bb811c599e831ed37a6fb3f0ecbac14 100644 --- a/ecmascript/linked_hash_table.h +++ b/ecmascript/linked_hash_table.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_LINKED_HASH_TABLE_H -#define PANDA_RUNTIME_ECMASCRIPT_LINKED_HASH_TABLE_H +#ifndef ECMASCRIPT_LINKED_HASH_TABLE_H +#define ECMASCRIPT_LINKED_HASH_TABLE_H #include "ecmascript/js_tagged_value.h" #include "js_handle.h" @@ -30,7 +30,7 @@ namespace panda::ecmascript { * 3.array[3+capacity+1,3+capacity + capacity*(entry_size+1)] is the entry stored in order, the last element of an entry * is a number which point to next entry. * */ -template +template class LinkedHashTable : public TaggedArray { public: static const int MIN_CAPACITY = 4; @@ -218,4 +218,4 @@ public: DECL_DUMP() }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_LINKED_HASH_TABLE_H +#endif // ECMASCRIPT_LINKED_HASH_TABLE_H diff --git a/ecmascript/literal_data_extractor.cpp b/ecmascript/literal_data_extractor.cpp index 7a847fd6fff29680c45afe882e8dfaa749a94a56..d69fb147fbe737c2f48e9b3116aa03e587045a8c 100644 --- a/ecmascript/literal_data_extractor.cpp +++ b/ecmascript/literal_data_extractor.cpp @@ -42,9 +42,11 @@ void LiteralDataExtractor::ExtractObjectDatas(JSThread *thread, const panda_file array_size_t epos = 0; array_size_t ppos = 0; const uint8_t pairSize = 2; + uint32_t methodId; + FunctionKind kind; lda.EnumerateLiteralVals( - index, [elements, properties, &epos, &ppos, factory, thread, pft](const LiteralValue &value, - const LiteralTag &tag) { + index, [elements, properties, &epos, &ppos, factory, thread, pft, &methodId, &kind](const LiteralValue &value, + const LiteralTag &tag) { JSTaggedValue jt = JSTaggedValue::Null(); bool flag = false; switch (tag) { @@ -72,15 +74,20 @@ void LiteralDataExtractor::ExtractObjectDatas(JSThread *thread, const panda_file } case LiteralTag::METHOD: { ASSERT(pft != nullptr); - uint32_t methodId = std::get(value); - JSHandle jsFunc = pft->DefineMethodById(methodId, FunctionKind::NORMAL_FUNCTION); - jt = jsFunc.GetTaggedValue(); + methodId = std::get(value); + kind = FunctionKind::NORMAL_FUNCTION; break; } case LiteralTag::GENERATORMETHOD: { ASSERT(pft != nullptr); - uint32_t methodId = std::get(value); - JSHandle jsFunc = pft->DefineMethodById(methodId, FunctionKind::GENERATOR_FUNCTION); + methodId = std::get(value); + kind = FunctionKind::GENERATOR_FUNCTION; + break; + } + case LiteralTag::METHODAFFILIATE: { + ASSERT(pft != nullptr); + uint16_t length = std::get(value); + JSHandle jsFunc = pft->DefineMethodInLiteral(thread, methodId, kind, length); jt = jsFunc.GetTaggedValue(); break; } @@ -97,10 +104,12 @@ void LiteralDataExtractor::ExtractObjectDatas(JSThread *thread, const panda_file break; } } - if (epos % pairSize == 0 && !flag) { - properties->Set(thread, ppos++, jt); - } else { - elements->Set(thread, epos++, jt); + if (tag != LiteralTag::METHOD && tag != LiteralTag::GENERATORMETHOD) { + if (epos % pairSize == 0 && !flag) { + properties->Set(thread, ppos++, jt); + } else { + elements->Set(thread, epos++, jt); + } } }); } @@ -117,9 +126,12 @@ JSHandle LiteralDataExtractor::GetDatasIgnoreType(JSThread *thread, uint32_t num = lda.GetLiteralValsNum(index) / 2; // 2: half JSHandle literals = factory->NewTaggedArray(num); array_size_t pos = 0; + uint32_t methodId; + FunctionKind kind; lda.EnumerateLiteralVals( - index, [literals, &pos, factory, thread, pft](const panda_file::LiteralDataAccessor::LiteralValue &value, - const LiteralTag &tag) { + index, [literals, &pos, factory, thread, pft, + &methodId, &kind](const panda_file::LiteralDataAccessor::LiteralValue &value, + const LiteralTag &tag) { JSTaggedValue jt = JSTaggedValue::Null(); switch (tag) { case LiteralTag::INTEGER: { @@ -142,15 +154,20 @@ JSHandle LiteralDataExtractor::GetDatasIgnoreType(JSThread *thread, } case LiteralTag::METHOD: { ASSERT(pft != nullptr); - uint32_t methodId = std::get(value); - JSHandle jsFunc = pft->DefineMethodById(methodId, FunctionKind::NORMAL_FUNCTION); - jt = jsFunc.GetTaggedValue(); + methodId = std::get(value); + kind = FunctionKind::NORMAL_FUNCTION; break; } case LiteralTag::GENERATORMETHOD: { ASSERT(pft != nullptr); - uint32_t methodId = std::get(value); - JSHandle jsFunc = pft->DefineMethodById(methodId, FunctionKind::GENERATOR_FUNCTION); + methodId = std::get(value); + kind = FunctionKind::GENERATOR_FUNCTION; + break; + } + case LiteralTag::METHODAFFILIATE: { + ASSERT(pft != nullptr); + uint16_t length = std::get(value); + JSHandle jsFunc = pft->DefineMethodInLiteral(thread, methodId, kind, length); jt = jsFunc.GetTaggedValue(); break; } @@ -167,7 +184,12 @@ JSHandle LiteralDataExtractor::GetDatasIgnoreType(JSThread *thread, break; } } - literals->Set(thread, pos++, jt); + if (tag != LiteralTag::METHOD && tag != LiteralTag::GENERATORMETHOD) { + literals->Set(thread, pos++, jt); + } else { + array_size_t oldLength = literals->GetLength(); + literals->Trim(thread, oldLength - 1); + } }); return literals; } diff --git a/ecmascript/literal_data_extractor.h b/ecmascript/literal_data_extractor.h index d36fb68184ecec405aa8c9d2e71ce36c907c3129..84b66e14db5f60d780493e848168789b1c86f106 100644 --- a/ecmascript/literal_data_extractor.h +++ b/ecmascript/literal_data_extractor.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_LITERAL_DATA_EXTRACTOR_H -#define PANDA_RUNTIME_ECMASCRIPT_LITERAL_DATA_EXTRACTOR_H +#ifndef ECMASCRIPT_LITERAL_DATA_EXTRACTOR_H +#define ECMASCRIPT_LITERAL_DATA_EXTRACTOR_H #include "ecmascript/class_linker/panda_file_translator.h" #include "ecmascript/js_tagged_value-inl.h" @@ -39,4 +39,4 @@ public: PandaFileTranslator *pft = nullptr); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_LITERAL_DATA_EXTRACTOR_H +#endif // ECMASCRIPT_LITERAL_DATA_EXTRACTOR_H diff --git a/ecmascript/mem/allocator-inl.h b/ecmascript/mem/allocator-inl.h index 8546afdb76c0adfffb9f1a96c7925a14d550ec42..bf0d150fcbc0a28e2fc5243701bd585e0dee33a7 100644 --- a/ecmascript/mem/allocator-inl.h +++ b/ecmascript/mem/allocator-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_ALLOCATOR_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_ALLOCATOR_INL_H +#ifndef ECMASCRIPT_MEM_ALLOCATOR_INL_H +#define ECMASCRIPT_MEM_ALLOCATOR_INL_H #include @@ -86,7 +86,7 @@ void FreeListAllocator::AddFree(Region *region) uintptr_t FreeListAllocator::Allocate(size_t size) { - if (UNLIKELY(size < static_cast(TaggedObject::ObjectHeaderSize()))) { + if (UNLIKELY(size < static_cast(TaggedObject::TaggedObjectSize()))) { return 0; } auto ret = bpAllocator_.Allocate(size); @@ -134,4 +134,4 @@ void FreeListAllocator::RebuildFreeList() freeList_->Rebuild(); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_ALLOCATOR_INL_H +#endif // ECMASCRIPT_MEM_ALLOCATOR_INL_H diff --git a/ecmascript/mem/allocator.h b/ecmascript/mem/allocator.h index 38f40bb53f3a4cfb038114ce926edf1578e90521..25b3d3d4cc8841bdc9475f92e0af6125b9978c59 100644 --- a/ecmascript/mem/allocator.h +++ b/ecmascript/mem/allocator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_ALLOCATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_ALLOCATOR_H +#ifndef ECMASCRIPT_MEM_ALLOCATOR_H +#define ECMASCRIPT_MEM_ALLOCATOR_H #include @@ -116,4 +116,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_ALLOCATOR_H +#endif // ECMASCRIPT_MEM_ALLOCATOR_H diff --git a/ecmascript/mem/area.h b/ecmascript/mem/area.h index a520595cbe34925f1ab0574fcf38451395b001ff..dd76e790f2e794f5bf4018fe7d390b7833f13687 100644 --- a/ecmascript/mem/area.h +++ b/ecmascript/mem/area.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_AREA_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_AREA_H +#ifndef ECMASCRIPT_MEM_AREA_H +#define ECMASCRIPT_MEM_AREA_H namespace panda::ecmascript { class Area { @@ -54,7 +54,7 @@ public: } private: - template + template friend class EcmaList; friend class Worker; Area *GetPrev() const @@ -73,4 +73,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_AREA_H +#endif // ECMASCRIPT_MEM_AREA_H diff --git a/ecmascript/mem/assert_scope-inl.h b/ecmascript/mem/assert_scope-inl.h index 24960c27130ed5a08700a8f364f1c2e14263ae40..f3f3beef7745dba1da28a4f25c1fb5152054dc8a 100644 --- a/ecmascript/mem/assert_scope-inl.h +++ b/ecmascript/mem/assert_scope-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_ASSERT_SCOPE_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_ASSERT_SCOPE_INL_H +#ifndef ECMASCRIPT_MEM_ASSERT_SCOPE_INL_H +#define ECMASCRIPT_MEM_ASSERT_SCOPE_INL_H #include "assert_scope.h" @@ -23,7 +23,7 @@ namespace panda::ecmascript { // NOLINTNEXTLINE(hicpp-signed-bitwise) static thread_local size_t currentAssertData(~0); -template +template AssertScopeT::AssertScopeT() : oldData_(currentAssertData) { switch (type) { @@ -38,7 +38,7 @@ AssertScopeT::AssertScopeT() : oldData_(currentAssertData) } } -template +template AssertScopeT::~AssertScopeT() { if (!oldData_.has_value()) { @@ -50,7 +50,7 @@ AssertScopeT::~AssertScopeT() } // static -template +template bool AssertScopeT::IsAllowed() { switch (type) { @@ -64,4 +64,4 @@ bool AssertScopeT::IsAllowed() } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_ASSERT_SCOPE_INL_H \ No newline at end of file +#endif // ECMASCRIPT_MEM_ASSERT_SCOPE_INL_H \ No newline at end of file diff --git a/ecmascript/mem/assert_scope.h b/ecmascript/mem/assert_scope.h index 32988db7cbb884064dede15b9349b30e5a5dd903..d7758369de8b1d01c69329917da73ce5252fb7d0 100644 --- a/ecmascript/mem/assert_scope.h +++ b/ecmascript/mem/assert_scope.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_ASSERT_SCOPE_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_ASSERT_SCOPE_H +#ifndef ECMASCRIPT_MEM_ASSERT_SCOPE_H +#define ECMASCRIPT_MEM_ASSERT_SCOPE_H #include @@ -33,7 +33,7 @@ constexpr bool IS_ALLOW_CHECK = false; enum class AssertType : uint8_t { GARBAGE_COLLECTION_ASSERT = 0, HEAP_ALLOC_ASSERT, LAST_ASSERT_TYPE }; -template +template class AssertScopeT { public: static bool IsAllowed() @@ -42,7 +42,7 @@ public: } }; -template +template class AssertScopeT { public: AssertScopeT(); @@ -86,4 +86,4 @@ using AllowHeapAlloc = AssertScopeT +// default value for need_write_barrier is true +template inline void Barriers::SetDynObject([[maybe_unused]] const JSThread *thread, void *obj, size_t offset, JSTaggedType value) { @@ -47,4 +48,4 @@ inline void Barriers::SetDynObject([[maybe_unused]] const JSThread *thread, void } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_BARRIERS_INL_H +#endif // ECMASCRIPT_MEM_BARRIERS_INL_H diff --git a/ecmascript/mem/barriers.h b/ecmascript/mem/barriers.h index 6e773b317a12ad6b0b7a07736708f73fd52aa641..4bf80d47dba76e3b38c6d390e898d8966cf42776 100644 --- a/ecmascript/mem/barriers.h +++ b/ecmascript/mem/barriers.h @@ -13,15 +13,15 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_BARRIERS_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_BARRIERS_H +#ifndef ECMASCRIPT_MEM_BARRIERS_H +#define ECMASCRIPT_MEM_BARRIERS_H #include "ecmascript/mem/mark_word.h" namespace panda::ecmascript { class Barriers { public: - template + template static inline void SetDynPrimitive(void *obj, size_t offset, T value) { auto *addr = reinterpret_cast(ToUintPtr(obj) + offset); @@ -29,7 +29,7 @@ public: *addr = value; } - template + template static inline bool AtomicSetDynPrimitive(volatile void *obj, size_t offset, T oldValue, T value) { volatile auto atomicField = reinterpret_cast *>(ToUintPtr(obj) + offset); @@ -37,10 +37,10 @@ public: std::memory_order_relaxed); } - template + template static inline void SetDynObject(const JSThread *thread, void *obj, size_t offset, JSTaggedType value); - template + template static inline T GetDynValue(const void *obj, size_t offset) { auto *addr = reinterpret_cast(ToUintPtr(obj) + offset); @@ -49,4 +49,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_BARRIERS_H +#endif // ECMASCRIPT_MEM_BARRIERS_H diff --git a/ecmascript/mem/c_containers.h b/ecmascript/mem/c_containers.h index d42bed60f0bfb3b392e7cf7298ffed8122ad6a94..15c84556eb1e87c299d2f405562ef44da6aa6486 100644 --- a/ecmascript/mem/c_containers.h +++ b/ecmascript/mem/c_containers.h @@ -31,32 +31,32 @@ #include "ecmascript/mem/caddress_allocator.h" namespace panda::ecmascript { -template +template using CVector = std::vector>; -template +template using CList = std::list>; -template > +template> using CMap = std::map>>; -template > +template> using CMultiMap = std::multimap>>; -template , class KeyEqual = std::equal_to> +template, class KeyEqual = std::equal_to> using CUnorderedMultiMap = std::unordered_multimap>>; -template +template using CDeque = std::deque>; -template > +template> using CQueue = std::queue; -template , class KeyEqual = std::equal_to> +template, class KeyEqual = std::equal_to> using CUnorderedMap = std::unordered_map>>; -template , class KeyEqual = std::equal_to> +template, class KeyEqual = std::equal_to> using CUnorderedSet = std::unordered_set>; } // namespace panda::ecmascript diff --git a/ecmascript/mem/c_string.cpp b/ecmascript/mem/c_string.cpp index 1fe5b6b6902066760513151e1445d89dd4f4fd0f..a5eb91d208dc178ca00d735501dedd31841f6b3e 100644 --- a/ecmascript/mem/c_string.cpp +++ b/ecmascript/mem/c_string.cpp @@ -60,7 +60,7 @@ double CStringToD(const CString &str) return result; } -template +template CString ConvertToString(T sp) { CString res; @@ -96,7 +96,7 @@ CString ConvertToString(const EcmaString *s, StringConvertedUsage usage) return CString(""); } if (s->IsUtf16()) { - // Should convert utf-16 to utf-8, because uint16_t likely greater than maxChar, will convert fail + // Should convert utf-16 to utf-8, because uint16_t likely great than maxChar, will convert fail bool modify = (usage != StringConvertedUsage::PRINT); size_t len = base::utf_helper::Utf16ToUtf8Size(s->GetDataUtf16(), s->GetLength(), modify) - 1; CVector buf(len); diff --git a/ecmascript/mem/c_string.h b/ecmascript/mem/c_string.h index f565ebe48f8c1db7b1d7dc420add0e0c6bae8dd4..194b5ca3d0d80df6828551aec94b0372213d5385 100644 --- a/ecmascript/mem/c_string.h +++ b/ecmascript/mem/c_string.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_C_STRING_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_C_STRING_H +#ifndef ECMASCRIPT_MEM_C_STRING_H +#define ECMASCRIPT_MEM_C_STRING_H #include #include @@ -44,7 +44,7 @@ CString ConvertToString(const std::string &str); CString ConvertToString(const ecmascript::EcmaString *s, StringConvertedUsage usage = StringConvertedUsage::PRINT); CString ConvertToString(ecmascript::JSTaggedValue key); -template +template std::enable_if_t, CString> FloatToCString(T number) { CStringStream strStream; @@ -52,7 +52,7 @@ std::enable_if_t, CString> FloatToCString(T number) return strStream.str(); } -template +template std::enable_if_t, CString> ToCString(T number) { if (number == 0) { @@ -79,4 +79,4 @@ std::enable_if_t, CString> ToCString(T number) } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_C_STRING_H +#endif // ECMASCRIPT_MEM_C_STRING_H diff --git a/ecmascript/mem/caddress_allocator.h b/ecmascript/mem/caddress_allocator.h index 7c522ae48d0cf1af93d41590f6eb159ff27584a5..3a08b03775bdda96a6726370fc6799c964781dd3 100644 --- a/ecmascript/mem/caddress_allocator.h +++ b/ecmascript/mem/caddress_allocator.h @@ -19,7 +19,7 @@ #include "ecmascript/mem/chunk.h" namespace panda::ecmascript { -template +template class CAddressAllocator { public: // using by std allocator @@ -31,17 +31,17 @@ public: using size_type = size_t; using difference_type = ptrdiff_t; - template + template struct Rebind { using other = CAddressAllocator; }; - template + template using rebind = Rebind; CAddressAllocator() = default; - template + template explicit CAddressAllocator(const CAddressAllocator &other [[maybe_unused]]) { } @@ -81,7 +81,7 @@ public: Free(static_cast(p)); } - template + template void construct(U *p, Args &&... args) // NOLINT(readability-identifier-naming) { if (p == nullptr) { @@ -89,7 +89,7 @@ public: } ::new (static_cast(p)) U(std::forward(args)...); } - template + template void destroy(U *p) // NOLINT(readability-identifier-naming) { if (p == nullptr) { @@ -113,7 +113,7 @@ public: return ptr; } - template + template [[nodiscard]] S *New(Args &&... args) { auto p = reinterpret_cast(Allocate(sizeof(S))); @@ -121,7 +121,7 @@ public: return reinterpret_cast(p); } - template + template void Finalize(S *ptr) { ASSERT(ptr != nullptr); diff --git a/ecmascript/mem/chunk.h b/ecmascript/mem/chunk.h index 1af052bf98c219d255379054adb49cc8cb72d82b..3a05d2ee3c1335f0d7cd52b4f9ee71c89302c426 100644 --- a/ecmascript/mem/chunk.h +++ b/ecmascript/mem/chunk.h @@ -52,13 +52,13 @@ public: return reinterpret_cast(result); } - template + template [[nodiscard]] T *NewArray(size_t size) { return static_cast(Allocate(size * sizeof(T))); } - template + template [[nodiscard]] T *New(Args &&... args) { auto p = reinterpret_cast(Allocate(sizeof(T))); @@ -66,7 +66,7 @@ public: return reinterpret_cast(p); } - template + template void Delete(T *ptr) { ASSERT(ptr != nullptr); diff --git a/ecmascript/mem/chunk_allocator.h b/ecmascript/mem/chunk_allocator.h index 886c05f272aad969429d8e69438c58ad7f323b2d..8cd45dd93ee41473970ac42c15667e385f724bf1 100644 --- a/ecmascript/mem/chunk_allocator.h +++ b/ecmascript/mem/chunk_allocator.h @@ -19,7 +19,7 @@ #include "ecmascript/mem/chunk.h" namespace panda::ecmascript { -template +template class ChunkAllocator { public: // used for std allocator @@ -31,21 +31,21 @@ public: using size_type = size_t; using difference_type = ptrdiff_t; - template + template struct Rebind { using other = ChunkAllocator; }; - template + template using rebind = Rebind; explicit ChunkAllocator(Chunk *chunk) : chunk_(chunk) {} - template + template ChunkAllocator(const ChunkAllocator &other) : chunk_(other.chunk_) { } - template + template friend class ChunkAllocator; ChunkAllocator(const ChunkAllocator &) = default; @@ -90,12 +90,12 @@ public: // NOLINTNEXTLINE(readability-identifier-naming) void deallocate([[maybe_unused]] pointer p, [[maybe_unused]] size_type n) {} - template + template void construct(U *p, Args &&... args) // NOLINT(readability-identifier-naming) { ::new (static_cast(p)) U(std::forward(args)...); } - template + template void destroy(U *p) // NOLINT(readability-identifier-naming) { if (p == nullptr) { @@ -136,9 +136,7 @@ public: Free(ptr); } - void Free([[maybe_unused]] void *mem) - { - } + void Free([[maybe_unused]] void *mem) {} Chunk *chunk() { diff --git a/ecmascript/mem/chunk_containers.h b/ecmascript/mem/chunk_containers.h index 2bf7ae4d9f5562caa047992cc859e7c2e1ab7562..c924cd32d001a3049c62ac9fece06c568713d091 100644 --- a/ecmascript/mem/chunk_containers.h +++ b/ecmascript/mem/chunk_containers.h @@ -31,7 +31,7 @@ #include "ecmascript/mem/chunk_allocator.h" namespace panda::ecmascript { -template +template class ChunkVector : public std::vector> { public: explicit ChunkVector(Chunk *chunk) : std::vector>(ChunkAllocator(chunk)) {} @@ -47,7 +47,7 @@ public: NO_MOVE_SEMANTIC(ChunkVector); }; -template > +template> class ChunkMap : public std::map>> { public: // Constructs an empty map. @@ -61,7 +61,7 @@ public: NO_MOVE_SEMANTIC(ChunkMap); }; -template , typename KeyEqual = std::equal_to> +template, typename KeyEqual = std::equal_to> class ChunkUnorderedMap : public std::unordered_map>> { public: // NOLINTNEXTLINE(readability-magic-numbers) @@ -75,7 +75,7 @@ public: NO_MOVE_SEMANTIC(ChunkUnorderedMap); }; -template > +template> class ChunkMultimap : public std::multimap>> { public: // Constructs an empty multimap. diff --git a/ecmascript/mem/clock_scope.h b/ecmascript/mem/clock_scope.h index 0f8233a42540731bdc3b764c173e81b2949cefd4..de76aac3101a61c051b6bc93d46d294f8d02cd5e 100644 --- a/ecmascript/mem/clock_scope.h +++ b/ecmascript/mem/clock_scope.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_CLOCK_SCOPE_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_CLOCK_SCOPE_H +#ifndef ECMASCRIPT_MEM_CLOCK_SCOPE_H +#define ECMASCRIPT_MEM_CLOCK_SCOPE_H #include "time.h" #include "chrono" @@ -55,4 +55,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_CLOCK_SCOPE_H +#endif // ECMASCRIPT_MEM_CLOCK_SCOPE_H diff --git a/ecmascript/mem/compress_collector.cpp b/ecmascript/mem/compress_collector.cpp index 2bf001dfc06265d711e99f45ff128dc8ad35755e..c6dfc6a094887a65244de7adcf032aaff8f2f548 100644 --- a/ecmascript/mem/compress_collector.cpp +++ b/ecmascript/mem/compress_collector.cpp @@ -56,7 +56,7 @@ void CompressCollector::InitializePhase() heap_->GetThreadPool()->WaitTaskFinish(); auto compressSpace = const_cast(heap_->GetCompressSpace()); if (compressSpace->GetCommittedSize() == 0) { - compressSpace->SetUp(); + compressSpace->Initialize(); } auto fromSpace = const_cast(heap_->GetFromSpace()); if (fromSpace->GetCommittedSize() == 0) { @@ -84,7 +84,7 @@ void CompressCollector::InitializePhase() }; heap_->GetNonMovableSpace()->EnumerateRegions(callback); heap_->GetSnapShotSpace()->EnumerateRegions(callback); - heap_->GetLargeObjectSpace()->EnumerateRegions(callback); + heap_->GetHugeObjectSpace()->EnumerateRegions(callback); heap_->FlipCompressSpace(); heap_->FlipNewSpace(); @@ -223,13 +223,14 @@ void CompressCollector::SweepPhases() return reinterpret_cast(ToUintPtr(nullptr)); }; stringTable->SweepWeakReference(gcUpdateWeak); + heap_->GetEcmaVM()->GetJSThread()->IterateWeakEcmaGlobalStorage(gcUpdateWeak); heap_->GetEcmaVM()->ProcessReferences(gcUpdateWeak); SweepSpace(const_cast(heap_->GetNonMovableSpace()), nonMovableAllocator_); - SweepSpace(heap_->GetLargeObjectSpace()); + SweepSpace(const_cast(heap_->GetHugeObjectSpace())); } -void CompressCollector::SweepSpace(LargeObjectSpace *space) +void CompressCollector::SweepSpace(HugeObjectSpace *space) { Region *currentRegion = space->GetRegionList().GetFirst(); while (currentRegion != nullptr) { diff --git a/ecmascript/mem/compress_collector.h b/ecmascript/mem/compress_collector.h index 1f31353f956e3c52af82e207e04c252d2f2affeb..535a3f47a05f1a9942922a8ec2cc5bb6e114a874 100644 --- a/ecmascript/mem/compress_collector.h +++ b/ecmascript/mem/compress_collector.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_COMPRESS_COLLECTOR_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_COMPRESS_COLLECTOR_H +#ifndef ECMASCRIPT_MEM_COMPRESS_COLLECTOR_H +#define ECMASCRIPT_MEM_COMPRESS_COLLECTOR_H #include "ecmascript/mem/compress_gc_marker.h" #include "ecmascript/mem/semi_space_collector.h" @@ -50,7 +50,7 @@ private: uintptr_t AllocateOld(size_t size); void RecordWeakReference(uint32_t threadId, JSTaggedType *ref); void SweepSpace(Space *space, FreeListAllocator &allocator); - void SweepSpace(LargeObjectSpace *space); // Only sweep large space. + void SweepSpace(HugeObjectSpace *space); // Only sweep huge space. void FreeLiveRange(FreeListAllocator &allocator, Region *current, uintptr_t freeStart, uintptr_t freeEnd); Heap *heap_; @@ -76,4 +76,4 @@ private: } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_COMPRESS_COLLECTOR_H +#endif // ECMASCRIPT_MEM_COMPRESS_COLLECTOR_H diff --git a/ecmascript/mem/compress_gc_marker-inl.h b/ecmascript/mem/compress_gc_marker-inl.h index 28372501a8515cd16ecf862ea04ac03d00ea27ac..1f52bfc10f15479744e8fc754bf88695585c1331 100644 --- a/ecmascript/mem/compress_gc_marker-inl.h +++ b/ecmascript/mem/compress_gc_marker-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_COMPRESS_GC_MARKER_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_COMPRESS_GC_MARKER_INL_H +#ifndef ECMASCRIPT_MEM_COMPRESS_GC_MARKER_INL_H +#define ECMASCRIPT_MEM_COMPRESS_GC_MARKER_INL_H #include "ecmascript/mem/compress_collector.h" #include "ecmascript/mem/compress_gc_marker.h" @@ -22,7 +22,7 @@ #include "ecmascript/mem/tlab_allocator-inl.h" namespace panda::ecmascript { -static constexpr int HEAD_SIZE = TaggedObject::ObjectHeaderSize(); +static constexpr int HEAD_SIZE = TaggedObject::TaggedObjectSize(); inline CompressGCMarker::CompressGCMarker(CompressCollector *compressCollector) : collector_(compressCollector) {} @@ -87,4 +87,4 @@ inline void CompressGCMarker::CopyObjectWithoutHeader(TaggedObject *object, uint } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_COMPRESS_GC_MARKER_INL_H +#endif // ECMASCRIPT_MEM_COMPRESS_GC_MARKER_INL_H diff --git a/ecmascript/mem/compress_gc_marker.h b/ecmascript/mem/compress_gc_marker.h index d3f70fc3f72fac1dc297558f8a3df8df33fb74b5..9d138f3e779316d0725a83de6bd9339fe7ff3d4e 100644 --- a/ecmascript/mem/compress_gc_marker.h +++ b/ecmascript/mem/compress_gc_marker.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_COMPRESS_GC_MARKER_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_COMPRESS_GC_MARKER_H +#ifndef ECMASCRIPT_MEM_COMPRESS_GC_MARKER_H +#define ECMASCRIPT_MEM_COMPRESS_GC_MARKER_H #include "ecmascript/mem/slots.h" @@ -41,4 +41,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_COMPRESS_GC_MARKER_H +#endif // ECMASCRIPT_MEM_COMPRESS_GC_MARKER_H diff --git a/ecmascript/mem/ecma_heap_manager-inl.h b/ecmascript/mem/ecma_heap_manager-inl.h index 2ccba6399b793205fa53c50cf007d7f8e2378456..4b65d6c33767a955b2ca0a60e62c019c37e0d961 100644 --- a/ecmascript/mem/ecma_heap_manager-inl.h +++ b/ecmascript/mem/ecma_heap_manager-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_MANAGER_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_MANAGER_INL_H +#ifndef ECMASCRIPT_MEM_HEAP_MANAGER_INL_H +#define ECMASCRIPT_MEM_HEAP_MANAGER_INL_H #include "ecmascript/mem/ecma_heap_manager.h" @@ -27,16 +27,16 @@ #include "ecmascript/js_hclass.h" namespace panda::ecmascript { -TaggedObject *EcmaHeapManager::AllocateYoungGenerationOrLargeObject(JSHClass *hclass) +TaggedObject *EcmaHeapManager::AllocateYoungGenerationOrHugeObject(JSHClass *hclass) { size_t size = hclass->GetObjectSize(); - return AllocateYoungGenerationOrLargeObject(hclass, size); + return AllocateYoungGenerationOrHugeObject(hclass, size); } -TaggedObject *EcmaHeapManager::AllocateYoungGenerationOrLargeObject(JSHClass *hclass, size_t size) +TaggedObject *EcmaHeapManager::AllocateYoungGenerationOrHugeObject(JSHClass *hclass, size_t size) { if (size > MAX_REGULAR_HEAP_OBJECT_SIZE) { - return AllocateLargeObject(hclass, size); + return AllocateHugeObject(hclass, size); } // regular objects auto object = reinterpret_cast(newSpaceAllocator_.Allocate(size)); @@ -78,10 +78,10 @@ TaggedObject *EcmaHeapManager::TryAllocateYoungGeneration(size_t size) return reinterpret_cast(newSpaceAllocator_.Allocate(size)); } -TaggedObject *EcmaHeapManager::AllocateNonMovableOrLargeObject(JSHClass *hclass, size_t size) +TaggedObject *EcmaHeapManager::AllocateNonMovableOrHugeObject(JSHClass *hclass, size_t size) { if (size > MAX_REGULAR_HEAP_OBJECT_SIZE) { - return AllocateLargeObject(hclass, size); + return AllocateHugeObject(hclass, size); } auto object = reinterpret_cast(nonMovableAllocator_.Allocate(size)); if (UNLIKELY(object == nullptr)) { @@ -128,17 +128,17 @@ void EcmaHeapManager::SetClass(TaggedObject *header, JSHClass *hclass) header->SetClass(hclass); } -TaggedObject *EcmaHeapManager::AllocateNonMovableOrLargeObject(JSHClass *hclass) +TaggedObject *EcmaHeapManager::AllocateNonMovableOrHugeObject(JSHClass *hclass) { size_t size = hclass->GetObjectSize(); - return AllocateNonMovableOrLargeObject(hclass, size); + return AllocateNonMovableOrHugeObject(hclass, size); } -TaggedObject *EcmaHeapManager::AllocateOldGenerationOrLargeObject(JSHClass *hclass, size_t size) +TaggedObject *EcmaHeapManager::AllocateOldGenerationOrHugeObject(JSHClass *hclass, size_t size) { ASSERT(size > 0); if (size > MAX_REGULAR_HEAP_OBJECT_SIZE) { - return AllocateLargeObject(hclass, size); + return AllocateHugeObject(hclass, size); } auto object = reinterpret_cast(oldSpaceAllocator_.Allocate(size)); if (UNLIKELY(object == nullptr)) { @@ -163,15 +163,17 @@ TaggedObject *EcmaHeapManager::AllocateOldGenerationOrLargeObject(JSHClass *hcla return object; } -TaggedObject *EcmaHeapManager::AllocateLargeObject(JSHClass *hclass, size_t size) +TaggedObject *EcmaHeapManager::AllocateHugeObject(JSHClass *hclass, size_t size) { ASSERT(size > MAX_REGULAR_HEAP_OBJECT_SIZE); // large objects heap_->CheckAndTriggerOldGC(); - auto *object = reinterpret_cast(heap_->GetLargeObjectSpace()->Allocate(size)); + auto *object = + reinterpret_cast(const_cast(heap_->GetHugeObjectSpace())->Allocate(size)); if (UNLIKELY(object == nullptr)) { - heap_->CollectGarbage(TriggerGCType::LARGE_GC); - object = reinterpret_cast(heap_->GetLargeObjectSpace()->Allocate(size)); + heap_->CollectGarbage(TriggerGCType::HUGE_GC); + object = reinterpret_cast( + const_cast(heap_->GetHugeObjectSpace())->Allocate(size)); if (UNLIKELY(object == nullptr)) { heap_->ThrowOutOfMemoryError(size); UNREACHABLE(); @@ -181,6 +183,24 @@ TaggedObject *EcmaHeapManager::AllocateLargeObject(JSHClass *hclass, size_t size heap_->OnAllocateEvent(reinterpret_cast(object)); return object; } + +TaggedObject *EcmaHeapManager::AllocateMachineCodeSpaceObject(JSHClass *hclass, size_t size) +{ + auto object = reinterpret_cast(machineCodeSpaceAllocator_.Allocate(size)); + if (UNLIKELY(object == nullptr)) { + if (!heap_->FillMachineCodeSpaceAndTryGC(&machineCodeSpaceAllocator_)) { + return nullptr; + } + object = reinterpret_cast(machineCodeSpaceAllocator_.Allocate(size)); + if (UNLIKELY(object == nullptr)) { + heap_->ThrowOutOfMemoryError(size); + return nullptr; + } + } + SetClass(object, hclass); + heap_->OnAllocateEvent(reinterpret_cast(object)); + return object; +} } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_MANAGER_INL_H +#endif // ECMASCRIPT_MEM_HEAP_MANAGER_INL_H diff --git a/ecmascript/mem/ecma_heap_manager.cpp b/ecmascript/mem/ecma_heap_manager.cpp index 618676bbf9639be19848bfd5d8d2ce5740362749..ea3d0b982696759e6cf968acb841bb36268aec9f 100644 --- a/ecmascript/mem/ecma_heap_manager.cpp +++ b/ecmascript/mem/ecma_heap_manager.cpp @@ -21,7 +21,8 @@ EcmaHeapManager::EcmaHeapManager(Heap *heap) : heap_(heap), newSpaceAllocator_(heap->GetNewSpace()), nonMovableAllocator_(heap->GetNonMovableSpace()), - oldSpaceAllocator_(heap->GetOldSpace()) + oldSpaceAllocator_(heap->GetOldSpace()), + machineCodeSpaceAllocator_(heap->GetMachineCodeSpace()) { ASSERT(heap != nullptr); heap->SetHeapManager(this); diff --git a/ecmascript/mem/ecma_heap_manager.h b/ecmascript/mem/ecma_heap_manager.h index c55a07ca73726bd3c2428c6ab7a909992ec3d1d0..6bfd120149acc41d73eeeccef3f94f125b9fcfb2 100644 --- a/ecmascript/mem/ecma_heap_manager.h +++ b/ecmascript/mem/ecma_heap_manager.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_ECMA_HEAP_MANAGER_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_ECMA_HEAP_MANAGER_H +#ifndef ECMASCRIPT_MEM_ECMA_HEAP_MANAGER_H +#define ECMASCRIPT_MEM_ECMA_HEAP_MANAGER_H #include "ecmascript/mem/allocator-inl.h" #include "ecmascript/js_hclass.h" @@ -30,15 +30,15 @@ public: NO_COPY_SEMANTIC(EcmaHeapManager); NO_MOVE_SEMANTIC(EcmaHeapManager); - inline TaggedObject *AllocateYoungGenerationOrLargeObject(JSHClass *hclass); + inline TaggedObject *AllocateYoungGenerationOrHugeObject(JSHClass *hclass); inline TaggedObject *TryAllocateYoungGeneration(size_t size); - inline TaggedObject *AllocateYoungGenerationOrLargeObject(JSHClass *hclass, size_t size); - - inline TaggedObject *AllocateNonMovableOrLargeObject(JSHClass *hclass, size_t size); - inline TaggedObject *AllocateNonMovableOrLargeObject(JSHClass *hclass); - inline TaggedObject *AllocateLargeObject(JSHClass *hclass, size_t size); - inline TaggedObject *AllocateOldGenerationOrLargeObject(JSHClass *hclass, size_t size); + inline TaggedObject *AllocateYoungGenerationOrHugeObject(JSHClass *hclass, size_t size); + inline TaggedObject *AllocateNonMovableOrHugeObject(JSHClass *hclass, size_t size); + inline TaggedObject *AllocateNonMovableOrHugeObject(JSHClass *hclass); + inline TaggedObject *AllocateHugeObject(JSHClass *hclass, size_t size); + inline TaggedObject *AllocateOldGenerationOrHugeObject(JSHClass *hclass, size_t size); + inline TaggedObject *AllocateMachineCodeSpaceObject(JSHClass *hclass, size_t size); inline uintptr_t AllocateSnapShotSpace(size_t size); inline void SetClass(TaggedObject *header, JSHClass *hclass); @@ -68,13 +68,19 @@ public: return snapshotSpaceAllocator_; } + FreeListAllocator &GetMachineCodeSpaceAllocator() + { + return machineCodeSpaceAllocator_; + } + private: Heap *heap_{nullptr}; BumpPointerAllocator newSpaceAllocator_; FreeListAllocator nonMovableAllocator_; FreeListAllocator oldSpaceAllocator_; BumpPointerAllocator snapshotSpaceAllocator_; + FreeListAllocator machineCodeSpaceAllocator_; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_ECMA_HEAP_MANAGER_H +#endif // ECMASCRIPT_MEM_ECMA_HEAP_MANAGER_H diff --git a/ecmascript/mem/ecma_list.h b/ecmascript/mem/ecma_list.h index d22aa473e360006d146c41f8e53c86fa64c1ef4a..e8fbbd45249deadc830c0160c397ce5b00dda097 100644 --- a/ecmascript/mem/ecma_list.h +++ b/ecmascript/mem/ecma_list.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_ECMALIST_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_ECMALIST_H +#ifndef ECMASCRIPT_MEM_ECMALIST_H +#define ECMASCRIPT_MEM_ECMALIST_H #include "ecmascript/mem/mem.h" @@ -22,7 +22,7 @@ namespace panda::ecmascript { // Invoking std::list will cause cross invoking, which is time-consuming. // Therefore, we implement ecma list inside the vm. -template +template class EcmaList { public: EcmaList() : first_(nullptr), last_(nullptr) {} @@ -136,4 +136,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_ECMALIST_H \ No newline at end of file +#endif // ECMASCRIPT_MEM_ECMALIST_H \ No newline at end of file diff --git a/ecmascript/mem/free_object_kind.h b/ecmascript/mem/free_object_kind.h index f8bd144355c32ec866d07403488008fd06be181f..869689c5fb87a2e109e96d34b1f1ce770dadb99d 100644 --- a/ecmascript/mem/free_object_kind.h +++ b/ecmascript/mem/free_object_kind.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_FREE_OBJECT_KIND_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_FREE_OBJECT_KIND_H +#ifndef ECMASCRIPT_MEM_FREE_OBJECT_KIND_H +#define ECMASCRIPT_MEM_FREE_OBJECT_KIND_H #include @@ -65,4 +65,4 @@ private: friend class FreeObjectList; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_FREE_OBJECT_LIST_H +#endif // ECMASCRIPT_MEM_FREE_OBJECT_LIST_H diff --git a/ecmascript/mem/free_object_list-inl.h b/ecmascript/mem/free_object_list-inl.h index cc48091b31c769b2591dc7097c7faeb553884590..b723d6b1de52e7f09e19728619478540e57bfcef 100644 --- a/ecmascript/mem/free_object_list-inl.h +++ b/ecmascript/mem/free_object_list-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_FREE_OBJECT_LIST_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_FREE_OBJECT_LIST_INL_H +#ifndef ECMASCRIPT_MEM_FREE_OBJECT_LIST_INL_H +#define ECMASCRIPT_MEM_FREE_OBJECT_LIST_INL_H #include "ecmascript/mem/free_object_list.h" @@ -54,4 +54,4 @@ inline size_t FreeObjectList::CalcNextNoneEmptyIndex(KindType start) return __builtin_ffsll(noneEmptyKindBitMap_ >> static_cast(start)) + start - 1; } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_FREE_OBJECT_LIST_INL_H +#endif // ECMASCRIPT_MEM_FREE_OBJECT_LIST_INL_H diff --git a/ecmascript/mem/free_object_list.h b/ecmascript/mem/free_object_list.h index 5726cfd0e2b5f24929dba12bc68cb53a1c6fa106..c7db11126e86734ad79e2ac5cedcfa0837b2f150 100644 --- a/ecmascript/mem/free_object_list.h +++ b/ecmascript/mem/free_object_list.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_FREE_OBJECT_LIST_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_FREE_OBJECT_LIST_H +#ifndef ECMASCRIPT_MEM_FREE_OBJECT_LIST_H +#define ECMASCRIPT_MEM_FREE_OBJECT_LIST_H #include @@ -66,4 +66,4 @@ private: Span kinds_ {}; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_FREE_OBJECT_LIST_H +#endif // ECMASCRIPT_MEM_FREE_OBJECT_LIST_H diff --git a/ecmascript/mem/gc_stats.cpp b/ecmascript/mem/gc_stats.cpp index 531d769c24b3a1b7edbe51c452b049481331646b..811707dd6cd1bbfae53eaebcddeb05e9148c2d76 100644 --- a/ecmascript/mem/gc_stats.cpp +++ b/ecmascript/mem/gc_stats.cpp @@ -15,6 +15,7 @@ #include "ecmascript/mem/gc_stats.h" +#include "ecmascript/mem/heap.h" #include "ecmascript/mem/mem.h" namespace panda::ecmascript { @@ -75,6 +76,15 @@ void GCStats::PrintStatisticResult() << " non move total commit size: " << sizeToMB(compressNonMoveTotalCommitSize_) << "MB" << " non move free rate: " << float(compressNonMoveTotalFreeSize_) / compressNonMoveTotalCommitSize_; } + + if (heap_ != nullptr) { + RegionFactory *regionFactory = const_cast(heap_->GetRegionFactory()); + LOG(DEBUG, RUNTIME) << "pool statistic:: " + << "anno memory usage size:" << regionFactory->GetAnnoMemoryUsage() + << "anno memory max usage size:" << regionFactory->GetMaxAnnoMemoryUsage() + << "native memory usage size:" << regionFactory->GetNativeMemoryUsage() + << "native memory max usage size:" << regionFactory->GetMaxNativeMemoryUsage(); + } } void GCStats::StatisticSemiCollector(Duration time, size_t aliveSize, size_t promoteSize, size_t commitSize) @@ -132,4 +142,4 @@ void GCStats::StatisticCompressCollector(Duration time, size_t youngAndOldAliveS compressNonMoveTotalCommitSize_ += nonMoveSpaceCommitSize; compressGCCount_++; } -} // namespace panda::ecmascript \ No newline at end of file +} // namespace panda::ecmascript diff --git a/ecmascript/mem/gc_stats.h b/ecmascript/mem/gc_stats.h index 3cf36b3afceac8eedb81f8e12d657a043f7a3bc4..924d2b2c950f8d3fad384f8db2a4d39885f13e69 100644 --- a/ecmascript/mem/gc_stats.h +++ b/ecmascript/mem/gc_stats.h @@ -13,19 +13,20 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_GC_STATS_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_GC_STATS_H +#ifndef ECMASCRIPT_MEM_GC_STATS_H +#define ECMASCRIPT_MEM_GC_STATS_H #include "time.h" #include "chrono" #include "libpandabase/utils/logger.h" namespace panda::ecmascript { +class Heap; class GCStats { using Duration = std::chrono::duration; public: - GCStats() = default; + GCStats(const Heap *heap) : heap_(heap) {}; ~GCStats() = default; void PrintStatisticResult(); @@ -78,6 +79,8 @@ private: size_t compressNonMoveTotalFreeSize_ = 0; size_t compressNonMoveTotalCommitSize_ = 0; + const Heap *heap_; + static constexpr uint32_t MILLION_TIME = 1000; static constexpr uint32_t MB = 1 * 1024 * 1024; @@ -86,4 +89,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_GC_STATS_H \ No newline at end of file +#endif // ECMASCRIPT_MEM_GC_STATS_H diff --git a/ecmascript/mem/gc_write_barrier.h b/ecmascript/mem/gc_write_barrier.h index 265ec6cf360685d518743af283039e1b86592b1f..e9925d254d986a918967972d982740fec2a6280d 100644 --- a/ecmascript/mem/gc_write_barrier.h +++ b/ecmascript/mem/gc_write_barrier.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_GC_WRITE_BARRIER_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_GC_WRITE_BARRIER_H +#ifndef ECMASCRIPT_MEM_GC_WRITE_BARRIER_H +#define ECMASCRIPT_MEM_GC_WRITE_BARRIER_H #include "ecmascript/mem/mem.h" #include "ecmascript/mem/region.h" @@ -32,4 +32,4 @@ static inline void MarkingBarrier(void *obj, size_t offset, TaggedObject *value) } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_GC_WRITE_BARRIER_H \ No newline at end of file +#endif // ECMASCRIPT_MEM_GC_WRITE_BARRIER_H \ No newline at end of file diff --git a/ecmascript/mem/heap-inl.h b/ecmascript/mem/heap-inl.h index 9455f765d648d9a03efe3499219d6cba9b3e96d6..a459e3e372f66fa70142dabc559fbd60b0ab93ed 100644 --- a/ecmascript/mem/heap-inl.h +++ b/ecmascript/mem/heap-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_INL_H +#ifndef ECMASCRIPT_MEM_HEAP_INL_H +#define ECMASCRIPT_MEM_HEAP_INL_H #include "ecmascript/mem/heap.h" #include "ecmascript/mem/mem_controller.h" @@ -23,42 +23,45 @@ #include "ecmascript/mem/remembered_set.h" namespace panda::ecmascript { -template +template void Heap::EnumerateOldSpaceRegions(const Callback &cb, Region *region) const { oldSpace_->EnumerateRegions(cb, region); nonMovableSpace_->EnumerateRegions(cb); - largeObjectSpace_->EnumerateRegions(cb); + hugeObjectSpace_->EnumerateRegions(cb); + machineCodeSpace_->EnumerateRegions(cb); } -template +template void Heap::EnumerateSnapShotSpaceRegions(const Callback &cb) const { snapshotSpace_->EnumerateRegions(cb); } -template +template void Heap::EnumerateNewSpaceRegions(const Callback &cb) const { toSpace_->EnumerateRegions(cb); } -template +template void Heap::EnumerateRegions(const Callback &cb) const { toSpace_->EnumerateRegions(cb); oldSpace_->EnumerateRegions(cb); snapshotSpace_->EnumerateRegions(cb); nonMovableSpace_->EnumerateRegions(cb); - largeObjectSpace_->EnumerateRegions(cb); + hugeObjectSpace_->EnumerateRegions(cb); + machineCodeSpace_->EnumerateRegions(cb); } -template +template void Heap::IteratorOverObjects(const Callback &cb) const { toSpace_->IterateOverObjects(cb); oldSpace_->IterateOverObjects(cb); nonMovableSpace_->IterateOverObjects(cb); + hugeObjectSpace_->IterateOverObjects(cb); } bool Heap::FillNewSpaceAndTryGC(BumpPointerAllocator *spaceAllocator, bool allowGc) @@ -111,6 +114,20 @@ bool Heap::FillSnapShotSpace(BumpPointerAllocator *spaceAllocator) return result; } +bool Heap::FillMachineCodeSpaceAndTryGC(FreeListAllocator *spaceAllocator, bool allowGc) +{ + if (machineCodeSpace_->Expand()) { + spaceAllocator->AddFree(machineCodeSpace_->GetCurrentRegion()); + return true; + } + if (allowGc) { + CollectGarbage(TriggerGCType::MACHINE_CODE_GC); + return true; + } + return false; +} + + void Heap::OnAllocateEvent(uintptr_t address) { if (tracker_ != nullptr) { @@ -140,7 +157,7 @@ void Heap::SetNewSpaceMaximumCapacity(size_t maximumCapacity) void Heap::InitializeFromSpace() { ASSERT(fromSpace_ != nullptr); - fromSpace_->SetUp(); + fromSpace_->Initialize(); } void Heap::SwapSpace() @@ -186,4 +203,4 @@ void Heap::ClearSlotsRange(Region *current, uintptr_t freeStart, uintptr_t freeE } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_INL_H +#endif // ECMASCRIPT_MEM_HEAP_INL_H diff --git a/ecmascript/mem/heap.cpp b/ecmascript/mem/heap.cpp index 5dc81ba6c59416584ed588e689a0b5a87aa0667b..9294b267354982e618573b87620122b2fe07d67d 100644 --- a/ecmascript/mem/heap.cpp +++ b/ecmascript/mem/heap.cpp @@ -31,25 +31,29 @@ namespace panda::ecmascript { Heap::Heap(EcmaVM *ecmaVm) : ecmaVm_(ecmaVm), regionFactory_(ecmaVm->GetRegionFactory()) {} -void Heap::SetUp() +void Heap::Initialize() { memController_ = CreateMemController("no-gc-for-start-up"); - if (GetMemController()->IsInAppStartup()) { + + if (memController_->IsInAppStartup()) { toSpace_ = new SemiSpace(this, DEFAULT_SEMI_SPACE_SIZE, MAX_SEMI_SPACE_SIZE_STARTUP); fromSpace_ = new SemiSpace(this, DEFAULT_SEMI_SPACE_SIZE, MAX_SEMI_SPACE_SIZE_STARTUP); } else { toSpace_ = new SemiSpace(this); fromSpace_ = new SemiSpace(this); } - toSpace_->SetUp(); + + toSpace_->Initialize(); // not set up from space oldSpace_ = new OldSpace(this); compressSpace_ = new OldSpace(this); - oldSpace_->SetUp(); + oldSpace_->Initialize(); nonMovableSpace_ = new NonMovableSpace(this); - nonMovableSpace_->SetUp(); + nonMovableSpace_->Initialize(); snapshotSpace_ = new SnapShotSpace(this); - largeObjectSpace_ = new LargeObjectSpace(this); + machineCodeSpace_ = new MachineCodeSpace(this); + machineCodeSpace_->Initialize(); + hugeObjectSpace_ = new HugeObjectSpace(this); markStack_ = new MarkStack(this); weakProcessQueue_ = new ProcessQueue(this); bool paralledGc = ecmaVm_->GetOptions().IsEnableParalledYoungGc(); @@ -80,36 +84,39 @@ void Heap::FlipCompressSpace() compressSpace_ = oldSpace_; oldSpace_ = oldSpace; } -void Heap::TearDown() +void Heap::Destroy() { pool_->WaitTaskFinish(); - toSpace_->TearDown(); + toSpace_->Destroy(); delete toSpace_; toSpace_ = nullptr; - fromSpace_->TearDown(); + fromSpace_->Destroy(); delete fromSpace_; fromSpace_ = nullptr; - oldSpace_->TearDown(); + oldSpace_->Destroy(); delete oldSpace_; oldSpace_ = nullptr; - compressSpace_->TearDown(); + compressSpace_->Destroy(); delete compressSpace_; compressSpace_ = nullptr; - nonMovableSpace_->TearDown(); + nonMovableSpace_->Destroy(); delete nonMovableSpace_; nonMovableSpace_ = nullptr; - snapshotSpace_->TearDown(); + snapshotSpace_->Destroy(); delete snapshotSpace_; snapshotSpace_ = nullptr; - markStack_->TearDown(); + machineCodeSpace_->Destroy(); + delete machineCodeSpace_; + machineCodeSpace_ = nullptr; + markStack_->Destroy(); delete markStack_; markStack_ = nullptr; - largeObjectSpace_->TearDown(); - delete largeObjectSpace_; - largeObjectSpace_ = nullptr; + hugeObjectSpace_->Destroy(); + delete hugeObjectSpace_; + hugeObjectSpace_ = nullptr; - weakProcessQueue_->TearDown(); + weakProcessQueue_->Destroy(); delete weakProcessQueue_; weakProcessQueue_ = nullptr; delete semiSpaceCollector_; @@ -141,8 +148,8 @@ void Heap::CollectGarbage(TriggerGCType gcType) case TriggerGCType::SEMI_GC: if (GetMemController()->IsInAppStartup()) { semiSpaceCollector_->RunPhases(); - SetFromSpaceMaximumCapacity(SEMI_SPACE_SIZE_4M); - SetNewSpaceMaximumCapacity(SEMI_SPACE_SIZE_4M); + SetFromSpaceMaximumCapacity(SEMI_SPACE_SIZE_CAPACITY); + SetNewSpaceMaximumCapacity(SEMI_SPACE_SIZE_CAPACITY); ResetAppStartup(); } else { semiSpaceCollector_->RunPhases(); @@ -157,7 +164,8 @@ void Heap::CollectGarbage(TriggerGCType gcType) RecomputeLimits(); break; case TriggerGCType::NON_MOVE_GC: - case TriggerGCType::LARGE_GC: + case TriggerGCType::HUGE_GC: + case TriggerGCType::MACHINE_CODE_GC: oldSpaceCollector_->RunPhases(); RecomputeLimits(); break; @@ -201,7 +209,7 @@ size_t Heap::VerifyHeapObjects() const { VerifyObjectVisitor verifier(this, &failCount); - largeObjectSpace_->IterateOverObjects(verifier); + hugeObjectSpace_->IterateOverObjects(verifier); } return failCount; diff --git a/ecmascript/mem/heap.h b/ecmascript/mem/heap.h index 631e22d5bebdb93420bffac67c736f7228366e1f..bc112f2f877b7714dab00ce70cf545c5d8276cb2 100644 --- a/ecmascript/mem/heap.h +++ b/ecmascript/mem/heap.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_H +#ifndef ECMASCRIPT_MEM_HEAP_H +#define ECMASCRIPT_MEM_HEAP_H #include "ecmascript/thread/thread_pool.h" #include "ecmascript/mem/mark_stack.h" @@ -38,8 +38,8 @@ public: ~Heap() = default; NO_COPY_SEMANTIC(Heap); NO_MOVE_SEMANTIC(Heap); - void SetUp(); - void TearDown(); + void Initialize(); + void Destroy(); const SemiSpace *GetNewSpace() const { @@ -83,9 +83,14 @@ public: return nonMovableSpace_; } - LargeObjectSpace *GetLargeObjectSpace() const + const HugeObjectSpace *GetHugeObjectSpace() const { - return largeObjectSpace_; + return hugeObjectSpace_; + } + + const MachineCodeSpace *GetMachineCodeSpace() const + { + return machineCodeSpace_; } MarkStack *GetMarkStack() const @@ -127,19 +132,19 @@ public: void FlipCompressSpace(); - template + template void EnumerateOldSpaceRegions(const Callback &cb, Region *region = nullptr) const; - template + template void EnumerateNewSpaceRegions(const Callback &cb) const; - template + template void EnumerateSnapShotSpaceRegions(const Callback &cb) const; - template + template void EnumerateRegions(const Callback &cb) const; - template + template void IteratorOverObjects(const Callback &cb) const; void CollectGarbage(TriggerGCType gcType); @@ -148,6 +153,7 @@ public: inline bool FillOldSpaceAndTryGC(FreeListAllocator *spaceAllocator, bool allowGc = true); inline bool FillNonMovableSpaceAndTryGC(FreeListAllocator *spaceAllocator, bool allowGc = true); inline bool FillSnapShotSpace(BumpPointerAllocator *spaceAllocator); + inline bool FillMachineCodeSpaceAndTryGC(FreeListAllocator *spaceAllocator, bool allowGc = true); void ThrowOutOfMemoryError(size_t size); @@ -180,7 +186,7 @@ public: bool CheckAndTriggerNonMovableGC(); - RegionFactory *GetRegionFactory() const + const RegionFactory *GetRegionFactory() const { return regionFactory_; } @@ -208,8 +214,8 @@ public: if (nonMovableSpace_->IsLive(object)) { return true; } - // large object space - if (largeObjectSpace_->IsLive(object)) { + // huge object space + if (hugeObjectSpace_->IsLive(object)) { return true; } return false; @@ -229,8 +235,8 @@ public: if (nonMovableSpace_->ContainObject(object)) { return true; } - // large object space - if (largeObjectSpace_->ContainObject(object)) { + // huge object space + if (hugeObjectSpace_->ContainObject(object)) { return true; } @@ -256,28 +262,29 @@ public: inline void ClearSlotsRange(Region *current, uintptr_t freeStart, uintptr_t freeEnd); private: - EcmaVM *ecmaVm_{nullptr}; - SemiSpace *fromSpace_{nullptr}; - SemiSpace *toSpace_{nullptr}; - OldSpace *oldSpace_{nullptr}; - OldSpace *compressSpace_{nullptr}; - LargeObjectSpace *largeObjectSpace_{nullptr}; - SnapShotSpace *snapshotSpace_{nullptr}; - NonMovableSpace *nonMovableSpace_{nullptr}; - MarkStack *markStack_{nullptr}; - ProcessQueue *weakProcessQueue_{nullptr}; - SemiSpaceCollector *semiSpaceCollector_{nullptr}; - OldSpaceCollector *oldSpaceCollector_{nullptr}; - CompressCollector *compressCollector_{nullptr}; - EcmaHeapManager *heapManager_{nullptr}; - RegionFactory *regionFactory_{nullptr}; - HeapTracker *tracker_{nullptr}; - MemController *memController_{nullptr}; - ThreadPool *pool_{nullptr}; - size_t oldSpaceAllocLimit_{OLD_SPACE_LIMIT_BEGIN}; + EcmaVM *ecmaVm_ {nullptr}; + SemiSpace *fromSpace_ {nullptr}; + SemiSpace *toSpace_ {nullptr}; + OldSpace *oldSpace_ {nullptr}; + OldSpace *compressSpace_ {nullptr}; + HugeObjectSpace *hugeObjectSpace_ {nullptr}; + SnapShotSpace *snapshotSpace_ {nullptr}; + NonMovableSpace *nonMovableSpace_ {nullptr}; + MachineCodeSpace *machineCodeSpace_ {nullptr}; + MarkStack *markStack_ {nullptr}; + ProcessQueue *weakProcessQueue_ {nullptr}; + SemiSpaceCollector *semiSpaceCollector_ {nullptr}; + OldSpaceCollector *oldSpaceCollector_ {nullptr}; + CompressCollector *compressCollector_ {nullptr}; + EcmaHeapManager *heapManager_ {nullptr}; + RegionFactory *regionFactory_ {nullptr}; + HeapTracker *tracker_ {nullptr}; + MemController *memController_ {nullptr}; + ThreadPool *pool_ {nullptr}; + size_t oldSpaceAllocLimit_ {OLD_SPACE_LIMIT_BEGIN}; inline void SetMaximumCapacity(SemiSpace *space, size_t maximumCapacity); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_H +#endif // ECMASCRIPT_MEM_HEAP_H diff --git a/ecmascript/mem/heap_roots-inl.h b/ecmascript/mem/heap_roots-inl.h index 46160cf642bdbccdef1437cb613bf5c025fc7648..deb616d11bc6b25ac5fbe3bba16aa49f26b8be13 100644 --- a/ecmascript/mem/heap_roots-inl.h +++ b/ecmascript/mem/heap_roots-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_ROOTS_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_ROOTS_INL_H +#ifndef ECMASCRIPT_MEM_HEAP_ROOTS_INL_H +#define ECMASCRIPT_MEM_HEAP_ROOTS_INL_H #include #include "ecmascript/class_linker/program_object.h" @@ -32,30 +32,26 @@ #include "ecmascript/js_async_function.h" #include "ecmascript/js_dataview.h" #include "ecmascript/js_date.h" -#include "ecmascript/js_float32_array.h" -#include "ecmascript/js_float64_array.h" +#include "ecmascript/js_date_time_format.h" #include "ecmascript/js_for_in_iterator.h" #include "ecmascript/js_function.h" #include "ecmascript/js_generator_object.h" #include "ecmascript/js_hclass.h" -#include "ecmascript/js_int16_array.h" -#include "ecmascript/js_int32_array.h" -#include "ecmascript/js_int8_array.h" +#include "ecmascript/js_intl.h" +#include "ecmascript/js_locale.h" #include "ecmascript/js_map.h" #include "ecmascript/js_map_iterator.h" #include "ecmascript/js_native_object.h" +#include "ecmascript/js_number_format.h" #include "ecmascript/js_object-inl.h" #include "ecmascript/js_primitive_ref.h" #include "ecmascript/js_promise.h" #include "ecmascript/js_regexp.h" +#include "ecmascript/js_relative_time_format.h" #include "ecmascript/js_set.h" #include "ecmascript/js_set_iterator.h" #include "ecmascript/js_string_iterator.h" #include "ecmascript/js_typed_array.h" -#include "ecmascript/js_uint16_array.h" -#include "ecmascript/js_uint32_array.h" -#include "ecmascript/js_uint8_array.h" -#include "ecmascript/js_uint8_clamped_array.h" #include "ecmascript/js_weak_container.h" #include "ecmascript/mem/heap_roots.h" #include "ecmascript/mem/mem.h" @@ -67,7 +63,7 @@ void HeapRootManager::VisitVMRoots(const RootVisitor &visitor, const RootRangeVi ecmaVm_->GetJSThread()->Iterate(visitor, rangeVisitor); } -template +template // NOLINTNEXTLINE(readability-function-size) void HeapRootManager::MarkObjectBody(TaggedObject *object, JSHClass *klass, const EcmaObjectRangeVisitor &visitor) { @@ -173,34 +169,16 @@ void HeapRootManager::MarkObjectBody(TaggedObject *object, JSHClass *klass, cons JSArray::Cast(object)->Visitor(visitor); break; case JSType::JS_TYPED_ARRAY: - JSTypedArray::Cast(object)->Visitor(visitor); - break; case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(object)->Visitor(visitor); - break; case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(object)->Visitor(visitor); - break; case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(object)->Visitor(visitor); - break; case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(object)->Visitor(visitor); - break; case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(object)->Visitor(visitor); - break; case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(object)->Visitor(visitor); - break; case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(object)->Visitor(visitor); - break; case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(object)->Visitor(visitor); - break; case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(object)->Visitor(visitor); + JSTypedArray::Cast(object)->Visitor(visitor); break; case JSType::JS_PRIMITIVE_REF: JSPrimitiveRef::Cast(object)->Visitor(visitor); @@ -290,6 +268,24 @@ void HeapRootManager::MarkObjectBody(TaggedObject *object, JSHClass *klass, cons case JSType::LEXICAL_FUNCTION: LexicalFunction::Cast(object)->Visitor(visitor); break; + case JSType::JS_INTL: + JSIntl::Cast(object)->Visitor(visitor); + break; + case JSType::JS_NUMBER_FORMAT: + JSNumberFormat::Cast(object)->Visitor(visitor); + break; + case JSType::JS_LOCALE: + JSLocale::Cast(object)->Visitor(visitor); + break; + case JSType::JS_DATE_TIME_FORMAT: + JSDateTimeFormat::Cast(object)->Visitor(visitor); + break; + case JSType::JS_RELATIVE_TIME_FORMAT: + JSRelativeTimeFormat::Cast(object)->Visitor(visitor); + break; + case JSType::JS_INTL_BOUND_FUNCTION: + JSIntlBoundFunction::Cast(object)->Visitor(visitor); + break; case JSType::JS_NATIVE_OBJECT: JSNativeObject::Cast(object)->Visitor(visitor); break; @@ -299,4 +295,4 @@ void HeapRootManager::MarkObjectBody(TaggedObject *object, JSHClass *klass, cons } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_ROOTS_INL_H +#endif // ECMASCRIPT_MEM_HEAP_ROOTS_INL_H diff --git a/ecmascript/mem/heap_roots.h b/ecmascript/mem/heap_roots.h index cc4d233b5029ee6b5d4b92b9f415f7e4eaa5747b..51cd82694bdd13465434e76ea047a867ab625a8c 100644 --- a/ecmascript/mem/heap_roots.h +++ b/ecmascript/mem/heap_roots.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_ROOTS_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_ROOTS_H +#ifndef ECMASCRIPT_MEM_HEAP_ROOTS_H +#define ECMASCRIPT_MEM_HEAP_ROOTS_H #include #include "ecmascript/mem/slots.h" @@ -28,6 +28,7 @@ enum class Root { ROOT_HANDLE, ROOT_VM, ROOT_STRING, + ROOT_INTERNAL_CALL_PARAMS, }; enum class GCType : size_t { SEMI_GC, OLD_GC }; @@ -45,7 +46,7 @@ public: ~HeapRootManager() = default; inline void VisitVMRoots(const RootVisitor &visitor, const RootRangeVisitor &range_visitor) const; - template + template inline void MarkObjectBody(TaggedObject *object, JSHClass *klass, const EcmaObjectRangeVisitor &visitor); private: @@ -53,4 +54,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_ROOTS_H +#endif // ECMASCRIPT_MEM_HEAP_ROOTS_H diff --git a/ecmascript/mem/machine_code.h b/ecmascript/mem/machine_code.h new file mode 100644 index 0000000000000000000000000000000000000000..3345918be79194c2cd104a7ac335468091e0ab5f --- /dev/null +++ b/ecmascript/mem/machine_code.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_MACHINE_CODE_H +#define PANDA_RUNTIME_ECMASCRIPT_MEM_MACHINE_CODE_H + +#include "ecmascript/js_tagged_value.h" +#include "ecmascript/object_factory.h" +#include "ecmascript/mem/tagged_object.h" + +namespace panda { +namespace ecmascript { +class MachineCode : public TaggedObject { +public: + MachineCode(); + ~MachineCode(); + NO_COPY_SEMANTIC(MachineCode); + NO_MOVE_SEMANTIC(MachineCode); + static MachineCode *Cast(ObjectHeader *object) + { + ASSERT(JSTaggedValue(object).IsMachineCodeObject()); + return static_cast(object); + } + + static constexpr size_t INS_SIZE_OFFSET = TaggedObjectSize(); + ACCESSORS(InstructionSizeInBytes, INS_SIZE_OFFSET, DATA_OFFSET); + + uintptr_t GetDataOffsetAddress(void) + { + return reinterpret_cast(this + DATA_OFFSET); + } + + void SetData(const uint8_t *codeData, size_t codeLength) + { + if (codeData == nullptr) { + LOG_ECMA_MEM(ERROR) << "data is null in creating new code object"; + return; + } + if (memcpy_s(reinterpret_cast(this->GetDataOffsetAddress()), + this->GetInstructionSizeInBytes().GetInt(), codeData, codeLength) != EOK) { + LOG_ECMA_MEM(ERROR) << "memcpy fail in creating new code object "; + return; + } + } + + size_t GetMachineCodeObjectSize(void) + { + return sizeof(MachineCode) + this->GetInstructionSizeInBytes().GetInt(); + } +}; +} // namespace ecmascript +} // namespace panda + +#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_MACHINE_CODE_H diff --git a/ecmascript/mem/mark_stack-inl.h b/ecmascript/mem/mark_stack-inl.h index c69166e850876313fafa417158025e93d9cc5b23..ec59f1ba8e6973409a0b081ed806f1dea0aa0a51 100644 --- a/ecmascript/mem/mark_stack-inl.h +++ b/ecmascript/mem/mark_stack-inl.h @@ -13,52 +13,52 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_MARK_STACK_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_MARK_STACK_INL_H +#ifndef ECMASCRIPT_MEM_MARK_STACK_INL_H +#define ECMASCRIPT_MEM_MARK_STACK_INL_H #include "ecmascript/mem/mark_stack.h" #include "ecmascript/mem/heap.h" namespace panda::ecmascript { -template +template void ContinuousStack::BeginMarking(Heap *heap, ContinuousStack *other) { heap_ = heap; currentArea_ = other->currentArea_; if (currentArea_ == nullptr) { - currentArea_ = heap_->GetRegionFactory()->AllocateArea(DEFAULT_MARK_STACK_SIZE); + currentArea_ = const_cast(heap_->GetRegionFactory())->AllocateArea(DEFAULT_MARK_STACK_SIZE); } ResetBegin(currentArea_->GetBegin(), currentArea_->GetEnd()); } -template +template void ContinuousStack::FinishMarking(ContinuousStack *other) { other->currentArea_ = currentArea_; while (!unusedList_.IsEmpty()) { Area *node = unusedList_.PopBack(); - heap_->GetRegionFactory()->FreeArea(node); + const_cast(heap_->GetRegionFactory())->FreeArea(node); } } -template +template void ContinuousStack::Extend() { - auto area = heap_->GetRegionFactory()->AllocateArea(DEFAULT_MARK_STACK_SIZE); + auto area = const_cast(heap_->GetRegionFactory())->AllocateArea(DEFAULT_MARK_STACK_SIZE); areaList_.AddNode(currentArea_); currentArea_ = area; ResetBegin(currentArea_->GetBegin(), currentArea_->GetEnd()); } -template -void ContinuousStack::TearDown() +template +void ContinuousStack::Destroy() { if (currentArea_ != nullptr) { - heap_->GetRegionFactory()->FreeArea(currentArea_); + const_cast(heap_->GetRegionFactory())->FreeArea(currentArea_); currentArea_ = nullptr; } } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_MARK_STACK_INL_H +#endif // ECMASCRIPT_MEM_MARK_STACK_INL_H diff --git a/ecmascript/mem/mark_stack.h b/ecmascript/mem/mark_stack.h index 621ae4d0e6aea6600189e4fe2eb393ec2dfb85ee..8bb2d42e9de5a4a1d23be3c2bb1dd9dcdc9d71ef 100644 --- a/ecmascript/mem/mark_stack.h +++ b/ecmascript/mem/mark_stack.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_MARK_STACK_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_MARK_STACK_H +#ifndef ECMASCRIPT_MEM_MARK_STACK_H +#define ECMASCRIPT_MEM_MARK_STACK_H #include "ecmascript/mem/ecma_list.h" #include "ecmascript/mem/space.h" @@ -85,7 +85,7 @@ public: } private: - template + template friend class ContinuousStack; friend class WorkNode; uintptr_t begin_{0}; @@ -93,7 +93,7 @@ private: uintptr_t *top_{nullptr}; }; -template +template class ContinuousStack : public Stack { public: ContinuousStack() = default; @@ -128,7 +128,7 @@ public: PushBackUnchecked(ToUintPtr(obj)); } - inline void TearDown(); + inline void Destroy(); private: inline void Extend(); @@ -144,4 +144,4 @@ using ProcessQueue = ContinuousStack; } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_MARK_STACK_H +#endif // ECMASCRIPT_MEM_MARK_STACK_H diff --git a/ecmascript/mem/mark_word.h b/ecmascript/mem/mark_word.h index 3857e4e6dd3672100a4ef541b019a4462bc3f20c..e95a0c00cb2a7c11086e69d3d31cd5c13e755a80 100644 --- a/ecmascript/mem/mark_word.h +++ b/ecmascript/mem/mark_word.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_MARK_WORD_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_MARK_WORD_H +#ifndef ECMASCRIPT_MEM_MARK_WORD_H +#define ECMASCRIPT_MEM_MARK_WORD_H #include #include @@ -73,4 +73,4 @@ private: } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_MARK_WORD_H +#endif // ECMASCRIPT_MEM_MARK_WORD_H diff --git a/ecmascript/mem/mem.h b/ecmascript/mem/mem.h index ca29ae88b50e0f4da467d9010f38305f82e9defd..83742742adb1a5261cb6e19dfa9fb471d21e4c34 100644 --- a/ecmascript/mem/mem.h +++ b/ecmascript/mem/mem.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_MEM_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_MEM_H +#ifndef ECMASCRIPT_MEM_MEM_H +#define ECMASCRIPT_MEM_MEM_H #include @@ -34,9 +34,14 @@ enum class MemAlignment : uint8_t { static constexpr size_t DEFAULT_SEMI_SPACE_SIZE = 1024 * 1024; static constexpr size_t MIN_AllOC_LIMIT_GROWING_STEP = 2 * 1024 * 1024; -static constexpr size_t SEMI_SPACE_SIZE_4M = 4 * 1024 * 1024; -static constexpr size_t SEMI_SPACE_SIZE_8M = 8 * 1024 * 1024; + +#if defined(IS_STANDARD_SYSTEM) +static constexpr size_t SEMI_SPACE_SIZE_CAPACITY = 3 * 1024 * 1024; +static constexpr size_t MAX_SEMI_SPACE_SIZE_STARTUP = 3 * 1024 * 1024; +#else +static constexpr size_t SEMI_SPACE_SIZE_CAPACITY = 4 * 1024 * 1024; static constexpr size_t MAX_SEMI_SPACE_SIZE_STARTUP = 16 * 1024 * 1024; +#endif static constexpr size_t OLD_SPACE_LIMIT_BEGIN = 10 * 1024 * 1024; @@ -51,6 +56,9 @@ static constexpr size_t REGION_SIZE_LOG2 = 18U; static constexpr size_t DEFAULT_SNAPSHOT_SPACE_SIZE = 1U << REGION_SIZE_LOG2; static constexpr size_t MAX_SNAPSHOT_SPACE_SIZE = 8 * 1024 * 1024; +static constexpr size_t DEFAULT_MACHINE_CODE_SPACE_SIZE = 1024 * 1024; +static constexpr size_t MAX_MACHINE_CODE_SPACE_SIZE = 8 * 1024 * 1024; + static constexpr size_t MAX_HEAP_SIZE = 256 * 1024 * 1024; static constexpr size_t DEFAULT_REGION_SIZE = 1U << REGION_SIZE_LOG2; @@ -58,14 +66,14 @@ static constexpr size_t DEFAULT_REGION_MASK = DEFAULT_REGION_SIZE - 1; static constexpr size_t DEFAULT_MARK_STACK_SIZE = 4 * 1024; -// Objects which are larger than half of the region size are large objects. +// Objects which are larger than half of the region size are huge objects. // Regular objects will be allocated on regular regions and migrated on spaces. -// They will never be moved to large object space. So we take half of a regular +// They will never be moved to huge object space. So we take half of a regular // region as the border of regular objects. static constexpr size_t MAX_32BIT_OBJECT_SPACE_SIZE = 1 * 1024 * 1024 * 1024; static constexpr size_t MAX_REGULAR_HEAP_OBJECT_SIZE = 1U << (REGION_SIZE_LOG2 - 1); -static constexpr size_t MAX_LARGE_OBJECT_SIZE = 256 * 1024 * 1024; -static constexpr size_t MAX_LARGE_OBJECT_SPACE_SIZE = 256 * 1024 * 1024; +static constexpr size_t MAX_HUGE_OBJECT_SIZE = 256 * 1024 * 1024; +static constexpr size_t MAX_HUGE_OBJECT_SPACE_SIZE = 256 * 1024 * 1024; static constexpr size_t LARGE_BITMAP_MIN_SIZE = static_cast(MemAlignment::MEM_ALIGN_OBJECT) << mem::Bitmap::LOG_BITSPERWORD; @@ -81,13 +89,13 @@ static constexpr uintptr_t PANDA_32BITS_HEAP_START_ADDRESS_256 = 256_KB; static os::memory::Mutex staticResourceLock_; -template +template constexpr inline bool IsAligned(T value, size_t alignment) { return (value & (alignment - 1U)) == 0; } -template +template inline T AlignDown(T x, size_t alignment) { ASSERT(std::is_integral::value); @@ -96,7 +104,7 @@ inline T AlignDown(T x, size_t alignment) return x & ~(alignment - 1U); } -template +template inline T AlignUp(T x, size_t alignment) { ASSERT(std::is_integral::value); @@ -104,4 +112,4 @@ inline T AlignUp(T x, size_t alignment) } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_MEM_H +#endif // ECMASCRIPT_MEM_MEM_H diff --git a/ecmascript/mem/mem_controller.cpp b/ecmascript/mem/mem_controller.cpp index ff803ff2074670a45f6c025448ad99524bf973ff..c04d6077ca35fb3425bbe910324947d94be7588e 100644 --- a/ecmascript/mem/mem_controller.cpp +++ b/ecmascript/mem/mem_controller.cpp @@ -23,7 +23,7 @@ double MemController::CalculateAllocLimit(size_t currentSize, size_t minSize, si { const uint64_t limit = std::max(static_cast(currentSize * factor), static_cast(currentSize) + MIN_AllOC_LIMIT_GROWING_STEP) + - SEMI_SPACE_SIZE_4M; + SEMI_SPACE_SIZE_CAPACITY; const uint64_t limitAboveMinSize = std::max(limit, minSize); const uint64_t halfToMaxSize = (static_cast(currentSize) + maxSize) / 2; diff --git a/ecmascript/mem/mem_controller.h b/ecmascript/mem/mem_controller.h index f32ec351422bf0468092f0df683de806517c80cd..f67ed204d10c0be6704e2a848b2a975653ec9398 100644 --- a/ecmascript/mem/mem_controller.h +++ b/ecmascript/mem/mem_controller.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_MEM_CONTROLLER_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_MEM_CONTROLLER_H +#ifndef ECMASCRIPT_MEM_MEM_CONTROLLER_H +#define ECMASCRIPT_MEM_MEM_CONTROLLER_H #include "ecmascript/mem/mem.h" @@ -61,4 +61,4 @@ private: MemController *CreateMemController(std::string_view gcTriggerType); } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_MEM_CONTROLLER_H +#endif // ECMASCRIPT_MEM_MEM_CONTROLLER_H diff --git a/ecmascript/mem/old_space_collector-inl.h b/ecmascript/mem/old_space_collector-inl.h index d99f59cf778a0963b6f49ebbad114b4d28acb122..a8f88de5598d382c9d9a2786cbff2bc571958915 100644 --- a/ecmascript/mem/old_space_collector-inl.h +++ b/ecmascript/mem/old_space_collector-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H +#ifndef ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H +#define ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H #include "ecmascript/mem/old_space_collector.h" #include "ecmascript/mem/mem.h" @@ -52,4 +52,4 @@ void OldSpaceCollector::FreeLiveRange(FreeListAllocator &allocator, Region *curr } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H +#endif // ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H diff --git a/ecmascript/mem/old_space_collector.cpp b/ecmascript/mem/old_space_collector.cpp index 285aa5576284f4a63cf4edf0cfdbd40b03bb550d..e6145e81cfdf5e268b0220285c9b1fde7f0b0b31 100644 --- a/ecmascript/mem/old_space_collector.cpp +++ b/ecmascript/mem/old_space_collector.cpp @@ -46,6 +46,7 @@ void OldSpaceCollector::InitializePhase() auto heapManager = heap_->GetHeapManager(); oldSpaceAllocator_.Swap(heapManager->GetOldSpaceAllocator()); nonMovableAllocator_.Swap(heapManager->GetNonMovableSpaceAllocator()); + machineCodeSpaceAllocator_.Swap(heapManager->GetMachineCodeSpaceAllocator()); heap_->EnumerateRegions([](Region *current) { // ensure mark bitmap auto bitmap = current->GetMarkBitmap(); @@ -56,7 +57,7 @@ void OldSpaceCollector::InitializePhase() } }); freeSize_ = 0; - largeSpaceFreeSize_ = 0; + hugeSpaceFreeSize_ = 0; oldSpaceCommitSize_ = heap_->GetOldSpace()->GetCommittedSize(); nonMoveSpaceCommitSize_ = heap_->GetNonMovableSpace()->GetCommittedSize(); } @@ -69,6 +70,7 @@ void OldSpaceCollector::FinishPhase() auto heapManager = heap_->GetHeapManager(); heapManager->GetOldSpaceAllocator().Swap(oldSpaceAllocator_); heapManager->GetNonMovableSpaceAllocator().Swap(nonMovableAllocator_); + heapManager->GetMachineCodeSpaceAllocator().Swap(machineCodeSpaceAllocator_); } void OldSpaceCollector::MarkingPhase() @@ -148,7 +150,7 @@ void OldSpaceCollector::SweepSpace(Space *space, FreeListAllocator &allocator) }); } -void OldSpaceCollector::SweepSpace(LargeObjectSpace *space) +void OldSpaceCollector::SweepSpace(HugeObjectSpace *space) { Region *currentRegion = space->GetRegionList().GetFirst(); @@ -159,7 +161,7 @@ void OldSpaceCollector::SweepSpace(LargeObjectSpace *space) markBitmap->IterateOverMarkedChunks([&isMarked]([[maybe_unused]] void *mem) { isMarked = true; }); if (!isMarked) { space->GetRegionList().RemoveNode(currentRegion); - largeSpaceFreeSize_ += currentRegion->GetCapacity(); + hugeSpaceFreeSize_ += currentRegion->GetCapacity(); space->ClearAndFreeRegion(currentRegion); } currentRegion = next; @@ -200,10 +202,12 @@ void OldSpaceCollector::SweepPhases() return reinterpret_cast(ToUintPtr(nullptr)); }; stringTable->SweepWeakReference(gcUpdateWeak); + heap_->GetEcmaVM()->GetJSThread()->IterateWeakEcmaGlobalStorage(gcUpdateWeak); heap_->GetEcmaVM()->ProcessReferences(gcUpdateWeak); SweepSpace(const_cast(heap_->GetOldSpace()), oldSpaceAllocator_); SweepSpace(const_cast(heap_->GetNonMovableSpace()), nonMovableAllocator_); - SweepSpace(heap_->GetLargeObjectSpace()); + SweepSpace(const_cast(heap_->GetHugeObjectSpace())); + SweepSpace(const_cast(heap_->GetMachineCodeSpace()), machineCodeSpaceAllocator_); } } // namespace panda::ecmascript diff --git a/ecmascript/mem/old_space_collector.h b/ecmascript/mem/old_space_collector.h index 53d9b477702d0d3c5d48a384e96521448775310f..64940351b60214b02f4a9a2ac2d0653162e1fc07 100644 --- a/ecmascript/mem/old_space_collector.h +++ b/ecmascript/mem/old_space_collector.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_OLD_SAPACE_COLLECTOR_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_OLD_SAPACE_COLLECTOR_H +#ifndef ECMASCRIPT_MEM_OLD_SAPACE_COLLECTOR_H +#define ECMASCRIPT_MEM_OLD_SAPACE_COLLECTOR_H #include "ecmascript/mem/mem.h" #include "ecmascript/mem/heap.h" @@ -57,20 +57,21 @@ private: inline void FreeLiveRange(FreeListAllocator &allocator, Region *current, uintptr_t freeStart, uintptr_t freeEnd); inline void RecordWeakReference(JSTaggedType *ref); void SweepSpace(Space *space, FreeListAllocator &allocator); - void SweepSpace(LargeObjectSpace *space); // Only sweep large space. + void SweepSpace(HugeObjectSpace *space); // Only sweep huge space. Heap *heap_; HeapRootManager rootManager_; MarkStack markStack_; ProcessQueue weakProcessQueue_; - FreeListAllocator oldSpaceAllocator_{}; - FreeListAllocator nonMovableAllocator_{}; + FreeListAllocator oldSpaceAllocator_ {}; + FreeListAllocator nonMovableAllocator_ {}; + FreeListAllocator machineCodeSpaceAllocator_ {}; size_t freeSize_{0}; - size_t largeSpaceFreeSize_ = 0; + size_t hugeSpaceFreeSize_ = 0; size_t oldSpaceCommitSize_ = 0; size_t nonMoveSpaceCommitSize_ = 0; }; } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_OLD_SAPACE_COLLECTOR_H +#endif // ECMASCRIPT_MEM_OLD_SAPACE_COLLECTOR_H diff --git a/ecmascript/mem/region.h b/ecmascript/mem/region.h index 2c16971de761ff25c672e17c9f30a9e7faad56a8..c80d1a9c0159fba30ba3d60d4a041dfd0a7e2f80 100644 --- a/ecmascript/mem/region.h +++ b/ecmascript/mem/region.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_REGION_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_REGION_H +#ifndef ECMASCRIPT_MEM_REGION_H +#define ECMASCRIPT_MEM_REGION_H #include "ecmascript/mem/mem.h" #include "mem/gc/bitmap.h" @@ -37,7 +37,7 @@ enum RegionFlags { // NOLINTNEXTLINE(hicpp-signed-bitwise) IS_IN_SNAPSHOT_GENERATION = 1 << 4, // NOLINTNEXTLINE(hicpp-signed-bitwise) - IS_LARGE_OBJECT = 1 << 5, + IS_HUGE_OBJECT = 1 << 5, // NOLINTNEXTLINE(hicpp-signed-bitwise) IS_IN_OLD_GENERATION = 1 << 6, // NOLINTNEXTLINE(hicpp-signed-bitwise) @@ -213,6 +213,13 @@ public: highWaterMark_ = mark; } + int SetCodeExecutableAndReadable() + { + // NOLINT(hicpp-signed-bitwise) + int res = mprotect(reinterpret_cast(allocateBase_), GetCapacity(), PROT_EXEC | PROT_READ | PROT_WRITE); + return res; + } + private: Space *space_; uintptr_t flags_; // Memory alignment, only low 32bits are used now @@ -230,4 +237,4 @@ private: } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_REGION_H +#endif // ECMASCRIPT_MEM_REGION_H diff --git a/ecmascript/mem/region_factory.cpp b/ecmascript/mem/region_factory.cpp index d990122b33f38fd9dc240318fd572ac268e234fa..757babbd7f1939c9bed150a7ada3d578b82120cc 100644 --- a/ecmascript/mem/region_factory.cpp +++ b/ecmascript/mem/region_factory.cpp @@ -13,11 +13,13 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MM_REGION_FACTORY_H -#define PANDA_RUNTIME_ECMASCRIPT_MM_REGION_FACTORY_H +#ifndef ECMASCRIPT_MM_REGION_FACTORY_H +#define ECMASCRIPT_MM_REGION_FACTORY_H #include "ecmascript/mem/region_factory.h" +#include + #include "ecmascript/mem/mark_stack.h" #include "ecmascript/mem/region.h" #include "libpandabase/mem/pool_manager.h" @@ -39,7 +41,7 @@ Region *RegionFactory::AllocateAlignedRegion(Space *space, size_t capacity) LOG_ECMA_MEM(FATAL) << "pool is empty"; UNREACHABLE(); } - IncreaseMemoryUsage(capacity); + IncreaseAnnoMemoryUsage(capacity); uintptr_t mem = ToUintPtr(mapMem); // Check that the address is 256K byte aligned @@ -55,7 +57,7 @@ Region *RegionFactory::AllocateAlignedRegion(Space *space, size_t capacity) void RegionFactory::FreeRegion(Region *region) { auto size = region->GetCapacity(); - DecreaseMemoryUsage(size); + DecreaseAnnoMemoryUsage(size); PoolManager::GetMmapMemPool()->FreePool(ToVoidPtr(region->GetAllocateBase()), size); } @@ -77,7 +79,7 @@ Area *RegionFactory::AllocateArea(size_t capacity) LOG_ECMA_MEM(FATAL) << "malloc failed"; UNREACHABLE(); } - IncreaseMemoryUsage(capacity); + IncreaseNativeMemoryUsage(capacity); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) uintptr_t begin = reinterpret_cast(mem) + headerSize; capacity -= headerSize; @@ -94,31 +96,12 @@ void RegionFactory::FreeArea(Area *area) return; } auto size = area->GetSize() + sizeof(Area); - DecreaseMemoryUsage(size); + DecreaseNativeMemoryUsage(size); os::memory::LockHolder lock(staticResourceLock_); // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) free(reinterpret_cast(area)); } -void *RegionFactory::AllocateWithMMap(size_t size) -{ - size = AlignUp(size, CHUNK_ALIGN_SIZE); - void *mem = panda::os::mem::MapRWAnonymousRaw(size); - if (mem == nullptr) { - LOG_ECMA_MEM(FATAL) << "mem is nullptr"; - UNREACHABLE(); - } - ASAN_UNPOISON_MEMORY_REGION(mem, size); - IncreaseMemoryUsage(size); - return mem; -} - -void RegionFactory::FreeWithMMap(void *mem, size_t size) -{ - DecreaseMemoryUsage(size); - os::mem::MmapDeleter(reinterpret_cast(mem), size); -} - void *RegionFactory::Allocate(size_t size) { if (size == 0) { @@ -131,7 +114,7 @@ void *RegionFactory::Allocate(size_t size) LOG_ECMA_MEM(FATAL) << "malloc failed"; UNREACHABLE(); } - IncreaseMemoryUsage(size); + IncreaseNativeMemoryUsage(size); return ptr; } @@ -140,7 +123,7 @@ void RegionFactory::Free(void *mem, size_t size) if (mem == nullptr) { return; } - DecreaseMemoryUsage(size); + DecreaseNativeMemoryUsage(size); os::memory::LockHolder lock(staticResourceLock_); // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) free(mem); @@ -158,6 +141,7 @@ void *RegionFactory::AllocateBuffer(size_t size) LOG_ECMA_MEM(FATAL) << "malloc failed"; UNREACHABLE(); } + IncreaseNativeMemoryUsage(size); return ptr; } @@ -166,6 +150,7 @@ void RegionFactory::FreeBuffer(void *mem) if (mem == nullptr) { return; } + DecreaseNativeMemoryUsage(malloc_usable_size(mem)); os::memory::LockHolder lock(staticResourceLock_); // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) free(mem); @@ -181,4 +166,4 @@ void RegionFactory::FreeBufferFunc(void *buffer, void* data) } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MM_REGION_FACTORY_H +#endif // ECMASCRIPT_MM_REGION_FACTORY_H diff --git a/ecmascript/mem/region_factory.h b/ecmascript/mem/region_factory.h index 927096609978f4b0d3249515e5fd286b2a5d4aae..af2bf0438bfac47d29567c65aff2f83ac3d218a5 100644 --- a/ecmascript/mem/region_factory.h +++ b/ecmascript/mem/region_factory.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_REGION_FACTORY_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_REGION_FACTORY_H +#ifndef ECMASCRIPT_MEM_REGION_FACTORY_H +#define ECMASCRIPT_MEM_REGION_FACTORY_H #include @@ -42,8 +42,6 @@ public: void FreeRegion(Region *region); Area *AllocateArea(size_t capacity); void FreeArea(Area *area); - void *AllocateWithMMap(size_t size); - void FreeWithMMap(void *mem, size_t size); void *Allocate(size_t size); void Free(void *mem, size_t size); void *AllocateBuffer(size_t size); @@ -52,7 +50,7 @@ public: static void FreeBufferFunc(void* buffer, void* data); // implemented by AllocateBuffer - template + template std::enable_if_t, T *> New(Args &&... args) { void *p = AllocateBuffer(sizeof(T)); @@ -63,27 +61,63 @@ public: return reinterpret_cast(p); } - void IncreaseMemoryUsage(size_t bytes) + template + void Delete(T *ptr) { - size_t current = memoryUsage_.fetch_add(bytes, std::memory_order_relaxed) + bytes; - size_t max = maxMemoryUsage_.load(std::memory_order_relaxed); - while (current > max && !maxMemoryUsage_.compare_exchange_weak(max, current, std::memory_order_relaxed)) { + if (ptr == nullptr) { + return; + } + // NOLINTNEXTLINE(readability-braces-around-statements,bugprone-suspicious-semicolon) + if constexpr (std::is_class_v) { + ptr->~T(); + } + FreeBuffer(ptr); + } + + void IncreaseAnnoMemoryUsage(size_t bytes) + { + size_t current = annoMemoryUsage_.fetch_add(bytes, std::memory_order_relaxed) + bytes; + size_t max = maxAnnoMemoryUsage_.load(std::memory_order_relaxed); + while (current > max && !maxAnnoMemoryUsage_.compare_exchange_weak(max, current, std::memory_order_relaxed)) { + } + } + + void DecreaseAnnoMemoryUsage(size_t bytes) + { + annoMemoryUsage_.fetch_sub(bytes, std::memory_order_relaxed); + } + + size_t GetAnnoMemoryUsage() const + { + return annoMemoryUsage_.load(std::memory_order_relaxed); + } + + size_t GetMaxAnnoMemoryUsage() const + { + return maxAnnoMemoryUsage_.load(std::memory_order_relaxed); + } + + void IncreaseNativeMemoryUsage(size_t bytes) + { + size_t current = nativeMemoryUsage_.fetch_add(bytes, std::memory_order_relaxed) + bytes; + size_t max = maxNativeMemoryUsage_.load(std::memory_order_relaxed); + while (current > max && !maxNativeMemoryUsage_.compare_exchange_weak(max, current, std::memory_order_relaxed)) { } } - void DecreaseMemoryUsage(size_t bytes) + void DecreaseNativeMemoryUsage(size_t bytes) { - memoryUsage_.fetch_sub(bytes, std::memory_order_relaxed); + nativeMemoryUsage_.fetch_sub(bytes, std::memory_order_relaxed); } - size_t GetCurrentMemoryUsage() const + size_t GetNativeMemoryUsage() const { - return memoryUsage_.load(std::memory_order_relaxed); + return nativeMemoryUsage_.load(std::memory_order_relaxed); } - size_t GetMaxMemoryUsage() const + size_t GetMaxNativeMemoryUsage() const { - return maxMemoryUsage_.load(std::memory_order_relaxed); + return maxNativeMemoryUsage_.load(std::memory_order_relaxed); } private: @@ -91,9 +125,11 @@ private: NO_MOVE_SEMANTIC(RegionFactory); Area *cachedArea_{nullptr}; - std::atomic memoryUsage_{0}; - std::atomic maxMemoryUsage_{0}; + std::atomic annoMemoryUsage_{0}; + std::atomic maxAnnoMemoryUsage_{0}; + std::atomic nativeMemoryUsage_{0}; + std::atomic maxNativeMemoryUsage_{0}; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_REGION_FACTORY_H +#endif // ECMASCRIPT_MEM_REGION_FACTORY_H diff --git a/ecmascript/mem/remembered_set.h b/ecmascript/mem/remembered_set.h index 88f5ccbf30f5fcd2da2bd25e49973d94c6493068..424a7f825f738fbc538dcbd726bf5a2888f7f114 100644 --- a/ecmascript/mem/remembered_set.h +++ b/ecmascript/mem/remembered_set.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_REMEMBERED_SET_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_REMEMBERED_SET_H +#ifndef ECMASCRIPT_MEM_REMEMBERED_SET_H +#define ECMASCRIPT_MEM_REMEMBERED_SET_H #include "ecmascript/mem/mem.h" #include "mem/gc/bitmap.h" @@ -44,13 +44,13 @@ public: SetBit(AddrToBitOffset(address)); } - template + template void IterateOverSetBits(VisitorType visitor) { IterateOverSetBitsInRange(0, Size(), visitor); } - template + template void IterateOverMarkedChunks(MemVisitor visitor) { IterateOverSetBits( @@ -87,4 +87,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_REMEMBERED_SET_H +#endif // ECMASCRIPT_MEM_REMEMBERED_SET_H diff --git a/ecmascript/mem/semi_space_collector-inl.h b/ecmascript/mem/semi_space_collector-inl.h index 7af7f35ed1c987d8e92ee42e7b857598eb02e5ff..806393c760fa513be0cbe975e20eb8e2dcdca34b 100644 --- a/ecmascript/mem/semi_space_collector-inl.h +++ b/ecmascript/mem/semi_space_collector-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H +#ifndef ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H +#define ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H #include "ecmascript/mem/semi_space_collector.h" #include "ecmascript/mem/mem.h" @@ -84,4 +84,4 @@ bool SemiSpaceCollector::BlowAgeMark(uintptr_t address) } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H +#endif // ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_INL_H diff --git a/ecmascript/mem/semi_space_collector.cpp b/ecmascript/mem/semi_space_collector.cpp index 46d05149d675610b81321643866f2947727fe9d3..44b22063f1444446b0754355d47759b379cf24aa 100644 --- a/ecmascript/mem/semi_space_collector.cpp +++ b/ecmascript/mem/semi_space_collector.cpp @@ -280,6 +280,7 @@ void SemiSpaceCollector::SweepPhases() return reinterpret_cast(ToUintPtr(nullptr)); }; stringTable->SweepWeakReference(gcUpdateWeak); + heap_->GetEcmaVM()->GetJSThread()->IterateWeakEcmaGlobalStorage(gcUpdateWeak); heap_->GetEcmaVM()->ProcessReferences(gcUpdateWeak); } } // namespace panda::ecmascript diff --git a/ecmascript/mem/semi_space_collector.h b/ecmascript/mem/semi_space_collector.h index fa1c854a1ad40aaf5ddae520d23a3d2704d8984b..6e5a31f62468b10c25ffdcd70d77bb02382042f0 100644 --- a/ecmascript/mem/semi_space_collector.h +++ b/ecmascript/mem/semi_space_collector.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_H +#ifndef ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_H +#define ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_H #include "ecmascript/mem/clock_scope.h" #include "ecmascript/mem/mem.h" @@ -100,4 +100,4 @@ private: } // namespace ecmascript } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_H +#endif // ECMASCRIPT_MEM_SEMI_SAPACE_COLLECTOR_H diff --git a/ecmascript/mem/semi_space_marker.cpp b/ecmascript/mem/semi_space_marker.cpp index bdee1ae4a2d06cb7bdd369c0769781c68110d29a..d4ca483813349e67596c0695b56f0d5b2324511c 100644 --- a/ecmascript/mem/semi_space_marker.cpp +++ b/ecmascript/mem/semi_space_marker.cpp @@ -13,16 +13,17 @@ * limitations under the License. */ +#include "ecmascript/mem/semi_space_marker.h" + #include "ecmascript/free_object.h" #include "ecmascript/js_hclass-inl.h" #include "ecmascript/mem/region.h" #include "ecmascript/mem/semi_space_collector-inl.h" -#include "ecmascript/mem/semi_space_marker.h" #include "ecmascript/mem/semi_space_worker.h" #include "ecmascript/mem/tlab_allocator-inl.h" namespace panda::ecmascript { -constexpr int HEAD_SIZE = TaggedObject::ObjectHeaderSize(); +constexpr int HEAD_SIZE = TaggedObject::TaggedObjectSize(); SemiSpaceMarker::SemiSpaceMarker(SemiSpaceCollector *semiSpaceCollector) : collector_(semiSpaceCollector) {} diff --git a/ecmascript/mem/semi_space_marker.h b/ecmascript/mem/semi_space_marker.h index 8aded1fcaf6aeaad1857d50b68344724608c8828..a1c3129dd86387f991ceba580e4d814ce9c325e8 100644 --- a/ecmascript/mem/semi_space_marker.h +++ b/ecmascript/mem/semi_space_marker.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SPACE_MARKER_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SPACE_MARKER_H +#ifndef ECMASCRIPT_MEM_SEMI_SPACE_MARKER_H +#define ECMASCRIPT_MEM_SEMI_SPACE_MARKER_H #include "ecmascript/mem/remembered_set.h" #include "ecmascript/mem/slots.h" @@ -45,4 +45,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SPACE_MARKER_H +#endif // ECMASCRIPT_MEM_SEMI_SPACE_MARKER_H diff --git a/ecmascript/mem/semi_space_worker.cpp b/ecmascript/mem/semi_space_worker.cpp index b49115d2d504ad3410c294e8ad16685c40845395..dbaa62b62335f572f5a05d69ff4b9923a8080017 100644 --- a/ecmascript/mem/semi_space_worker.cpp +++ b/ecmascript/mem/semi_space_worker.cpp @@ -37,7 +37,8 @@ void Worker::Finish(size_t &aliveSize) } while (!unuseSpace_.empty()) { - heap_->GetRegionFactory()->FreeBuffer(reinterpret_cast(unuseSpace_.back())); + const_cast(heap_->GetRegionFactory())->FreeBuffer(reinterpret_cast( + unuseSpace_.back())); unuseSpace_.pop_back(); } } @@ -97,7 +98,8 @@ WorkNode *Worker::AllocalWorkNode() begin = atomicField->load(std::memory_order_acquire); if (begin + totalSize >= markSpaceEnd_) { unuseSpace_.emplace_back(markSpace_); - markSpace_ = ToUintPtr(heap_->GetRegionFactory()->AllocateBuffer(SPACE_SIZE)); + markSpace_ = + ToUintPtr(const_cast(heap_->GetRegionFactory())->AllocateBuffer(SPACE_SIZE)); spaceTop_ = markSpace_; markSpaceEnd_ = markSpace_ + SPACE_SIZE; begin = spaceTop_; @@ -118,17 +120,17 @@ Worker::Worker(Heap *heap, uint32_t threadNum) for (uint32_t i = 0; i < threadNum_; i++) { continuousQueue_[i] = new ProcessQueue(heap); } - markSpace_ = ToUintPtr(heap_->GetRegionFactory()->AllocateBuffer(SPACE_SIZE)); + markSpace_ = ToUintPtr(const_cast(heap_->GetRegionFactory())->AllocateBuffer(SPACE_SIZE)); } Worker::~Worker() { for (uint32_t i = 0; i < threadNum_; i++) { - continuousQueue_[i]->TearDown(); + continuousQueue_[i]->Destroy(); delete continuousQueue_[i]; continuousQueue_[i] = nullptr; } - heap_->GetRegionFactory()->FreeBuffer(reinterpret_cast(markSpace_)); + const_cast(heap_->GetRegionFactory())->FreeBuffer(reinterpret_cast(markSpace_)); } SemiSpaceWorker::~SemiSpaceWorker() = default; diff --git a/ecmascript/mem/semi_space_worker.h b/ecmascript/mem/semi_space_worker.h index e04e0e0d669c622b21d755afb5db2ec96082f666..2572c475e1e2bb830f8aac2ea3e9c2fb668d3efa 100644 --- a/ecmascript/mem/semi_space_worker.h +++ b/ecmascript/mem/semi_space_worker.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SPACE_WORKER_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SPACE_WORKER_H +#ifndef ECMASCRIPT_MEM_SEMI_SPACE_WORKER_H +#define ECMASCRIPT_MEM_SEMI_SPACE_WORKER_H #include "ecmascript/mem/mark_stack.h" #include "ecmascript/mem/slots.h" @@ -235,4 +235,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_SEMI_SPACE_WORKER_H +#endif // ECMASCRIPT_MEM_SEMI_SPACE_WORKER_H diff --git a/ecmascript/mem/slots.h b/ecmascript/mem/slots.h index 607c13c3fb9bcbdf453799dbafd0b16c4a449d16..802a9d2fc1d0ed4af3ee9c45c7280fb549e4c18e 100644 --- a/ecmascript/mem/slots.h +++ b/ecmascript/mem/slots.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_SLOTS_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_SLOTS_H +#ifndef ECMASCRIPT_MEM_SLOTS_H +#define ECMASCRIPT_MEM_SLOTS_H #include "ecmascript/js_tagged_value.h" #include "ecmascript/mem/mem.h" @@ -99,4 +99,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_SLOTS_H +#endif // ECMASCRIPT_MEM_SLOTS_H diff --git a/ecmascript/mem/space-inl.h b/ecmascript/mem/space-inl.h index c9369710d336304912196be3c5770e82cb606df6..c37983e9dc7c739232e284b07959b3aca78ea999 100644 --- a/ecmascript/mem/space-inl.h +++ b/ecmascript/mem/space-inl.h @@ -13,14 +13,14 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_SPACE_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_SPACE_INL_H +#ifndef ECMASCRIPT_MEM_SPACE_INL_H +#define ECMASCRIPT_MEM_SPACE_INL_H #include "ecmascript/mem/space.h" #include "ecmascript/mem/remembered_set.h" namespace panda::ecmascript { -template +template void Space::EnumerateRegions(const Callback &cb, Region *region) const { Region *current = regionList_.GetFirst(); @@ -51,4 +51,4 @@ void Region::InsertOldToNewRememberedSet(uintptr_t addr) } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_SPACE_INL_H +#endif // ECMASCRIPT_MEM_SPACE_INL_H diff --git a/ecmascript/mem/space.cpp b/ecmascript/mem/space.cpp index d499296c2f70d75b49237d05601a8ad8865dd64d..cb83b9416ccd5e0552e14a65bf76a0db9880fe05 100644 --- a/ecmascript/mem/space.cpp +++ b/ecmascript/mem/space.cpp @@ -28,16 +28,22 @@ void Space::AddRegion(Region *region) IncrementCommitted(region->GetCapacity()); } -void Space::SetUp() +void Space::Initialize() { - Region *region = heap_->GetRegionFactory()->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); + Region *region = + const_cast(heap_->GetRegionFactory())->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); if (spaceType_ == MemSpaceType::SEMI_SPACE) { region->SetFlag(RegionFlags::IS_IN_YOUNG_GENERATION); } else if (spaceType_ == MemSpaceType::SNAPSHOT_SPACE) { region->SetFlag(RegionFlags::IS_IN_SNAPSHOT_GENERATION); } else if (spaceType_ == MemSpaceType::OLD_SPACE) { region->SetFlag(RegionFlags::IS_IN_OLD_GENERATION); + } else if (spaceType_ == MemSpaceType::MACHINE_CODE_SPACE) { + region->SetFlag(RegionFlags::IS_IN_OLD_GENERATION); + int res = region->SetCodeExecutableAndReadable(); + LOG_ECMA_MEM(DEBUG) << "Initialize SetCodeExecutableAndReadable" << res; } + AddRegion(region); } @@ -53,23 +59,23 @@ void Space::ClearAndFreeRegion(Region *region) if (region->GetMarkBitmap() != nullptr) { auto bitmap = region->GetMarkBitmap(); auto size = RangeBitmap::GetBitMapSizeInByte(region->GetCapacity()); - heap_->GetRegionFactory()->Free(bitmap->GetBitMap().Data(), size); + const_cast(heap_->GetRegionFactory())->Free(bitmap->GetBitMap().Data(), size); delete bitmap; } if (region->GetCrossRegionRememberedSet() != nullptr) { auto rememberedSet = region->GetCrossRegionRememberedSet(); auto size = RememberedSet::GetSizeInByte(region->GetCapacity()); - heap_->GetRegionFactory()->Free(rememberedSet->GetBitMap().Data(), size); + const_cast(heap_->GetRegionFactory())->Free(rememberedSet->GetBitMap().Data(), size); delete rememberedSet; } if (region->GetOldToNewRememberedSet() != nullptr) { auto rememberedSet = region->GetOldToNewRememberedSet(); auto size = RememberedSet::GetSizeInByte(region->GetCapacity()); - heap_->GetRegionFactory()->Free(rememberedSet->GetBitMap().Data(), size); + const_cast(heap_->GetRegionFactory())->Free(rememberedSet->GetBitMap().Data(), size); delete rememberedSet; } DecrementCommitted(region->GetCapacity()); - heap_->GetRegionFactory()->FreeRegion(region); + const_cast(heap_->GetRegionFactory())->FreeRegion(region); } size_t Space::GetHeapObjectSize() const @@ -99,7 +105,8 @@ bool SemiSpace::Expand(uintptr_t top) return false; } GetCurrentRegion()->SetHighWaterMark(top); - Region *region = heap->GetRegionFactory()->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); + Region *region = + const_cast(heap->GetRegionFactory())->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); region->SetFlag(RegionFlags::IS_IN_YOUNG_GENERATION); AddRegion(region); @@ -167,7 +174,8 @@ bool OldSpace::Expand() LOG_ECMA_MEM(FATAL) << "Committed size " << GetCommittedSize() << " of old space is too big. "; return false; } - Region *region = GetHeap()->GetRegionFactory()->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); + Region *region = + const_cast(GetHeap()->GetRegionFactory())->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); region->SetFlag(RegionFlags::IS_IN_OLD_GENERATION); AddRegion(region); return true; @@ -225,7 +233,7 @@ size_t OldSpace::GetHeapObjectSize() const size_t availableSize = GetHeap()->GetHeapManager()->GetOldSpaceAllocator().GetAvailableSize(); size_t regionSize = GetRegionList().GetLength() * DEFAULT_REGION_SIZE; result = regionSize - availableSize; - result += GetHeap()->GetLargeObjectSpace()->GetHeapObjectSize(); + result += GetHeap()->GetHugeObjectSpace()->GetHeapObjectSize(); return result; } @@ -240,7 +248,8 @@ bool NonMovableSpace::Expand() LOG_ECMA_MEM(FATAL) << "Committed size " << GetCommittedSize() << " of non movable space is too big. "; return false; } - Region *region = GetHeap()->GetRegionFactory()->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); + Region *region = + const_cast(GetHeap()->GetRegionFactory())->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); AddRegion(region); return true; } @@ -268,7 +277,8 @@ bool SnapShotSpace::Expand(uintptr_t top) if (current != nullptr) { current->SetHighWaterMark(top); } - Region *region = GetHeap()->GetRegionFactory()->AllocateAlignedRegion(this, DEFAULT_SNAPSHOT_SPACE_SIZE); + Region *region = const_cast(GetHeap()->GetRegionFactory())-> + AllocateAlignedRegion(this, DEFAULT_SNAPSHOT_SPACE_SIZE); region->SetFlag(RegionFlags::IS_IN_SNAPSHOT_GENERATION); AddRegion(region); return true; @@ -276,11 +286,11 @@ bool SnapShotSpace::Expand(uintptr_t top) RangeBitmap *Region::CreateMarkBitmap() { - size_t heapSize = IsFlagSet(RegionFlags::IS_LARGE_OBJECT) ? LARGE_BITMAP_MIN_SIZE : GetCapacity(); - // Only one large object is stored in a region. The BitmapSize of a large region will always be 8 Bytes. + size_t heapSize = IsFlagSet(RegionFlags::IS_HUGE_OBJECT) ? LARGE_BITMAP_MIN_SIZE : GetCapacity(); + // Only one huge object is stored in a region. The BitmapSize of a huge region will always be 8 Bytes. size_t bitmapSize = RangeBitmap::GetBitMapSizeInByte(heapSize); - auto bitmapData = space_->GetHeap()->GetRegionFactory()->Allocate(bitmapSize); + auto bitmapData = const_cast(space_->GetHeap()->GetRegionFactory())->Allocate(bitmapSize); auto *ret = new RangeBitmap(this, heapSize, bitmapData); ret->ClearAllBits(); @@ -290,14 +300,14 @@ RangeBitmap *Region::CreateMarkBitmap() RememberedSet *Region::CreateRememberedSet() { auto setSize = RememberedSet::GetSizeInByte(GetCapacity()); - auto setAddr = space_->GetHeap()->GetRegionFactory()->Allocate(setSize); + auto setAddr = const_cast(space_->GetHeap()->GetRegionFactory())->Allocate(setSize); uintptr_t setData = ToUintPtr(setAddr); auto ret = new RememberedSet(ToUintPtr(this), GetCapacity(), setData); ret->ClearAllBits(); return ret; } -void Space::TearDown() +void Space::Destroy() { ReclaimRegions(); } @@ -348,30 +358,31 @@ bool NonMovableSpace::IsLive(TaggedObject *object) const return false; } -LargeObjectSpace::LargeObjectSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity) - : Space(heap, MemSpaceType::LARGE_OBJECT_SPACE, initialCapacity, maximumCapacity) +HugeObjectSpace::HugeObjectSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity) + : Space(heap, MemSpaceType::HUGE_OBJECT_SPACE, initialCapacity, maximumCapacity) { } -uintptr_t LargeObjectSpace::Allocate(size_t objectSize) +uintptr_t HugeObjectSpace::Allocate(size_t objectSize) { if (GetCommittedSize() >= GetMaximumCapacity()) { - LOG_ECMA_MEM(FATAL) << "Committed size " << GetCommittedSize() << " of large object space is too big. " + LOG_ECMA_MEM(FATAL) << "Committed size " << GetCommittedSize() << " of huge object space is too big. " << "length: " << GetRegionList().GetLength(); return 0; } size_t alignedSize = AlignUp(objectSize + sizeof(Region), PANDA_POOL_ALIGNMENT_IN_BYTES); - if (UNLIKELY(alignedSize > MAX_LARGE_OBJECT_SIZE)) { + if (UNLIKELY(alignedSize > MAX_HUGE_OBJECT_SIZE)) { LOG_ECMA_MEM(FATAL) << "The size is too big for this allocator. Return nullptr."; return 0; } - Region *region = GetHeap()->GetRegionFactory()->AllocateAlignedRegion(this, alignedSize); - region->SetFlag(RegionFlags::IS_LARGE_OBJECT); + Region *region = + const_cast(GetHeap()->GetRegionFactory())->AllocateAlignedRegion(this, alignedSize); + region->SetFlag(RegionFlags::IS_HUGE_OBJECT); AddRegion(region); return region->GetBegin(); } -bool LargeObjectSpace::ContainObject(TaggedObject *object) const +bool HugeObjectSpace::ContainObject(TaggedObject *object) const { auto region = GetRegionList().GetFirst(); while (region != nullptr) { @@ -383,12 +394,12 @@ bool LargeObjectSpace::ContainObject(TaggedObject *object) const return false; } -bool LargeObjectSpace::IsLive(TaggedObject *object) const +bool HugeObjectSpace::IsLive(TaggedObject *object) const { return ContainObject(object); } -size_t LargeObjectSpace::GetHeapObjectSize() const +size_t HugeObjectSpace::GetHeapObjectSize() const { size_t result = 0; EnumerateRegions([&result](Region *current) { @@ -398,11 +409,30 @@ size_t LargeObjectSpace::GetHeapObjectSize() const return result; } -void LargeObjectSpace::IterateOverObjects(const std::function &objectVisitor) const +void HugeObjectSpace::IterateOverObjects(const std::function &objectVisitor) const { EnumerateRegions([&](Region *region) { uintptr_t curPtr = region->GetBegin(); objectVisitor(reinterpret_cast(curPtr)); }); } + +MachineCodeSpace::MachineCodeSpace(Heap *heap, size_t initialCapacity, size_t maximumCapacity) + : Space(heap, MemSpaceType::MACHINE_CODE_SPACE, initialCapacity, maximumCapacity) +{ +} + +bool MachineCodeSpace::Expand() +{ + if (GetCommittedSize() >= GetMaximumCapacity()) { + LOG_ECMA_MEM(FATAL) << "Committed size " << GetCommittedSize() << " of machine Code space is too big. "; + return false; + } + Region *region = + const_cast(GetHeap()->GetRegionFactory())->AllocateAlignedRegion(this, DEFAULT_REGION_SIZE); + AddRegion(region); + int res = region->SetCodeExecutableAndReadable(); + LOG_ECMA_MEM(DEBUG) << "MachineCodeSpace::Expand() SetCodeExecutableAndReadable" << res; + return true; +} } // namespace panda::ecmascript diff --git a/ecmascript/mem/space.h b/ecmascript/mem/space.h index 16a91acad7edbb14a234b877149d7547bd74e7ce..7e6012f538ac35246ea9bd61b406878eb6703e89 100644 --- a/ecmascript/mem/space.h +++ b/ecmascript/mem/space.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_SPACE_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_SPACE_H +#ifndef ECMASCRIPT_MEM_SPACE_H +#define ECMASCRIPT_MEM_SPACE_H #include "mem/gc/bitmap.h" #include "ecmascript/mem/c_containers.h" @@ -32,8 +32,9 @@ enum MemSpaceType { SEMI_SPACE, OLD_SPACE, NON_MOVABLE, - LARGE_OBJECT_SPACE, + HUGE_OBJECT_SPACE, SNAPSHOT_SPACE, + MACHINE_CODE_SPACE, SPACE_TYPE_LAST // Count of different types }; @@ -41,7 +42,8 @@ enum TriggerGCType { SEMI_GC, OLD_GC, NON_MOVE_GC, - LARGE_GC, + HUGE_GC, + MACHINE_CODE_GC, COMPRESS_FULL_GC, GC_TYPE_LAST // Count of different types }; @@ -139,13 +141,13 @@ public: size_t GetHeapObjectSize() const; - template + template void EnumerateRegions(const Callback &cb, Region *region = nullptr) const; void AddRegion(Region *region); - void SetUp(); - void TearDown(); + void Initialize(); + void Destroy(); void ReclaimRegions(); @@ -163,7 +165,7 @@ private: class SemiSpace : public Space { public: explicit SemiSpace(Heap *heap, size_t initialCapacity = DEFAULT_SEMI_SPACE_SIZE, - size_t maximumCapacity = SEMI_SPACE_SIZE_4M); + size_t maximumCapacity = SEMI_SPACE_SIZE_CAPACITY); ~SemiSpace() override = default; NO_COPY_SEMANTIC(SemiSpace); NO_MOVE_SEMANTIC(SemiSpace); @@ -228,19 +230,29 @@ public: bool Expand(uintptr_t top); }; -class LargeObjectSpace : public Space { +class HugeObjectSpace : public Space { public: - explicit LargeObjectSpace(Heap *heap, size_t initialCapacity = DEFAULT_OLD_SPACE_SIZE, - size_t maximumCapacity = MAX_LARGE_OBJECT_SPACE_SIZE); - ~LargeObjectSpace() override = default; - NO_COPY_SEMANTIC(LargeObjectSpace); - NO_MOVE_SEMANTIC(LargeObjectSpace); + explicit HugeObjectSpace(Heap *heap, size_t initialCapacity = DEFAULT_OLD_SPACE_SIZE, + size_t maximumCapacity = MAX_HUGE_OBJECT_SPACE_SIZE); + ~HugeObjectSpace() override = default; + NO_COPY_SEMANTIC(HugeObjectSpace); + NO_MOVE_SEMANTIC(HugeObjectSpace); uintptr_t Allocate(size_t objectSize); size_t GetHeapObjectSize() const; bool ContainObject(TaggedObject *object) const; bool IsLive(TaggedObject *object) const; void IterateOverObjects(const std::function &objectVisitor) const; }; + +class MachineCodeSpace : public Space { +public: + explicit MachineCodeSpace(Heap *heap, size_t initialCapacity = DEFAULT_MACHINE_CODE_SPACE_SIZE, + size_t maximumCapacity = MAX_MACHINE_CODE_SPACE_SIZE); + ~MachineCodeSpace() override = default; + NO_COPY_SEMANTIC(MachineCodeSpace); + NO_MOVE_SEMANTIC(MachineCodeSpace); + bool Expand(); +}; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_SPACE_H +#endif // ECMASCRIPT_MEM_SPACE_H diff --git a/ecmascript/mem/tagged_object-inl.h b/ecmascript/mem/tagged_object-inl.h index f935a062cd779e2299699c606473eac6379a1401..d993a5aed4cdc31eb92628da620cb6be10f83b50 100644 --- a/ecmascript/mem/tagged_object-inl.h +++ b/ecmascript/mem/tagged_object-inl.h @@ -13,14 +13,15 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_OBJECT_HEADER_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_OBJECT_HEADER_INL_H +#ifndef ECMASCRIPT_TAGGED_OBJECT_HEADER_INL_H +#define ECMASCRIPT_TAGGED_OBJECT_HEADER_INL_H #include "ecmascript/mem/tagged_object.h" #include #include "ecmascript/js_hclass.h" #include "ecmascript/js_handle.h" +#include "heap.h" namespace panda::ecmascript { inline void TaggedObject::SetClass(JSHClass *hclass) @@ -49,6 +50,14 @@ inline JSHClass *TaggedObject::SynchronizedGetClass() const return reinterpret_cast( reinterpret_cast *>(ToUintPtr(this))->load(std::memory_order_acquire)); } + +inline JSThread *TaggedObject::GetJSThread() const +{ + Region *region = Region::ObjectAddressToRange(reinterpret_cast(ToUintPtr(this))); + ASSERT(region != nullptr); + EcmaVM *vm = region->GetSpace()->GetHeap()->GetEcmaVM(); + return vm->GetAssociatedJSThread(); +} } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TAGGED_OBJECT_HEADER_INL_H +#endif // ECMASCRIPT_TAGGED_OBJECT_HEADER_INL_H diff --git a/ecmascript/mem/tagged_object.h b/ecmascript/mem/tagged_object.h index 1f5d37de442fe2f0f434c5bb2fd402b7b3253a7a..5918edf708046c4c9aa4879b3199ac23e16d37fd 100644 --- a/ecmascript/mem/tagged_object.h +++ b/ecmascript/mem/tagged_object.h @@ -13,16 +13,17 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_OBJECT_HEADER_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_OBJECT_HEADER_H +#ifndef ECMASCRIPT_TAGGED_OBJECT_HEADER_H +#define ECMASCRIPT_TAGGED_OBJECT_HEADER_H #include "ecmascript/mem/mark_word.h" #include "include/object_header.h" namespace panda::ecmascript { class JSHClass; -template +template class JSHandle; +class JSThread; class TaggedObject : public ObjectHeader { public: @@ -41,12 +42,14 @@ public: size_t GetObjectSize(); // Size of object header - static constexpr int ObjectHeaderSize() + static constexpr int TaggedObjectSize() { return sizeof(TaggedObject); } + + JSThread* GetJSThread() const; }; -static_assert(TaggedObject::ObjectHeaderSize() == sizeof(MarkWordType)); +static_assert(TaggedObject::TaggedObjectSize() == sizeof(MarkWordType)); } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TAGGED_OBJECT_HEADER_H +#endif // ECMASCRIPT_TAGGED_OBJECT_HEADER_H diff --git a/ecmascript/mem/tlab_allocator-inl.h b/ecmascript/mem/tlab_allocator-inl.h index d92ab43b770e6cd059125582251aa95d49e642c7..3a36d26b60004c612f6447f9d85c872df0feccec 100644 --- a/ecmascript/mem/tlab_allocator-inl.h +++ b/ecmascript/mem/tlab_allocator-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_TLAB_ALLOCATOR_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_TLAB_ALLOCATOR_INL_H +#ifndef ECMASCRIPT_MEM_TLAB_ALLOCATOR_INL_H +#define ECMASCRIPT_MEM_TLAB_ALLOCATOR_INL_H #include @@ -148,4 +148,4 @@ bool TlabAllocator::ExpandOld() return true; } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_TLAB_ALLOCATOR_INL_H +#endif // ECMASCRIPT_MEM_TLAB_ALLOCATOR_INL_H diff --git a/ecmascript/mem/tlab_allocator.h b/ecmascript/mem/tlab_allocator.h index 11064c60263331b50c034fa5ab71b990f3b72cc2..8890965577cce9cad3f9a9adbb6c9c5594dfd9f4 100644 --- a/ecmascript/mem/tlab_allocator.h +++ b/ecmascript/mem/tlab_allocator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_TLAB_ALLOCATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_TLAB_ALLOCATOR_H +#ifndef ECMASCRIPT_MEM_TLAB_ALLOCATOR_H +#define ECMASCRIPT_MEM_TLAB_ALLOCATOR_H namespace panda::ecmascript { enum class SpaceAlloc : bool { @@ -55,4 +55,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_TLAB_ALLOCATOR_H +#endif // ECMASCRIPT_MEM_TLAB_ALLOCATOR_H diff --git a/ecmascript/mem/verification.h b/ecmascript/mem/verification.h index 4fa42f48471052321b7bdfe92be12cac78e4179f..99e6cba7ebbee02173cdc5dcba2b69f3e2a7ee09 100644 --- a/ecmascript/mem/verification.h +++ b/ecmascript/mem/verification.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_VERIFICATION_H -#define PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_VERIFICATION_H +#ifndef ECMASCRIPT_MEM_HEAP_VERIFICATION_H +#define ECMASCRIPT_MEM_HEAP_VERIFICATION_H #include @@ -76,4 +76,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_MEM_HEAP_VERIFICATION_H +#endif // ECMASCRIPT_MEM_HEAP_VERIFICATION_H diff --git a/ecmascript/message_string.cpp b/ecmascript/message_string.cpp new file mode 100644 index 0000000000000000000000000000000000000000..888268908b7e1ba45a56e1b63b9ee7ef0d2a4327 --- /dev/null +++ b/ecmascript/message_string.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "message_string.h" +#include +#include "libpandabase/macros.h" + +namespace panda::ecmascript { +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects) +static std::array g_messageString = { +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define DEF_MESSAGE_ID(name, string) #string, + MESSAGE_STRING_LIST(DEF_MESSAGE_ID) +#undef DEF_MESSAGE_ID +}; + +const std::string& MessageString::GetMessageString(int id) +{ + ASSERT(id < MessageString::MAX_MESSAGE_COUNT); + return g_messageString[id]; +} +} // namespace panda::ecmascript \ No newline at end of file diff --git a/ecmascript/message_string.h b/ecmascript/message_string.h index 4cce99c3ef0771a49f45dcd939bf34ad86d777f6..61a6ba1bfcd501a3dffb9f1db0205012f0bfde38 100644 --- a/ecmascript/message_string.h +++ b/ecmascript/message_string.h @@ -13,30 +13,30 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_MESSAGE_STRING_H -#define PANDA_RUNTIME_ECMASCRIPT_MESSAGE_STRING_H +#ifndef ECMASCRIPT_MESSAGE_STRING_H +#define ECMASCRIPT_MESSAGE_STRING_H #include -namespace kungfu { +namespace panda::ecmascript { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define MESSAGE_STRING_LIST(V) \ - V(SetReadOnlyProperty, "Cannot set readonly property") \ +#define MESSAGE_STRING_LIST(V) \ + V(SetReadOnlyProperty, "Cannot set readonly property") \ V(SetPropertyWhenNotExtensible, "Cannot add property in prevent extensions ") class MessageString { public: enum MessageId { - // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) + // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define DEF_MESSAGE_ID(name, string) Message_##name, MESSAGE_STRING_LIST(DEF_MESSAGE_ID) #undef DEF_MESSAGE_ID - MAX_MESSAGE_COUNT + MAX_MESSAGE_COUNT }; - static std::string GetMessageString(int id); + static const std::string& GetMessageString(int id); }; // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define GET_MESSAGE_STRING_ID(name) static_cast((MessageString::MessageId::Message_##name)) -} // namespace kungfu -#endif +} // namespace panda::ecmascript +#endif // ECMASCRIPT_MESSAGE_STRING_H \ No newline at end of file diff --git a/ecmascript/napi/include/jsnapi.h b/ecmascript/napi/include/jsnapi.h index 2205c2743412fdba3bf804770cd192a245df8600..ce23b0b860c36734030ae82f893299e2097fb3a1 100644 --- a/ecmascript/napi/include/jsnapi.h +++ b/ecmascript/napi/include/jsnapi.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_NAPI_JSNAPI_H -#define PANDA_RUNTIME_ECMASCRIPT_NAPI_JSNAPI_H +#ifndef ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H +#define ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H #include #include @@ -27,7 +27,7 @@ namespace panda { class JSNApiHelper; class EscapeLocalScope; -template +template class Global; class JSNApi; class PrimitiveRef; @@ -37,6 +37,7 @@ class ObjectRef; class FunctionRef; class NumberRef; class BooleanRef; +class NativePointerRef; namespace test { class JSNApiTests; } // namespace test @@ -59,12 +60,15 @@ static constexpr uint32_t DEFAULT_GC_POOL_SIZE = 256 * 1024 * 1024; className(className &&) = delete; \ className &operator=(className &&) = delete -template +template class PUBLIC_API Local { // NOLINT(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) public: inline Local() = default; - template + // Non-empty initial value. + explicit Local(const EcmaVM *vm); + + template inline Local(const Local ¤t) : address_(reinterpret_cast(*current)) { // Check @@ -115,12 +119,15 @@ private: friend EscapeLocalScope; }; -template +template class PUBLIC_API Global { // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions public: inline Global() = default; - template + // Non-empty initial value. + explicit Global(const EcmaVM *vm); + + template Global(const EcmaVM *vm, const Local ¤t); ~Global() = default; @@ -152,6 +159,10 @@ public: return IsEmpty() || GetAddress()->IsException(); } + void SetWeak(); + + bool IsWeak() const; + private: inline T *GetAddress() const { @@ -173,6 +184,7 @@ protected: private: void *prevNext_ = nullptr; void *prevEnd_ = nullptr; + int prevHandleStorageIndex_{-1}; void *thread_ = nullptr; }; @@ -184,7 +196,7 @@ public: DISALLOW_COPY(EscapeLocalScope); DISALLOW_MOVE(EscapeLocalScope); - template + template inline Local Escape(Local current) { ASSERT(!alreadyEscape_); @@ -227,6 +239,7 @@ public: Local ToBoolean(const EcmaVM *vm); Local ToString(const EcmaVM *vm); Local ToObject(const EcmaVM *vm); + Local ToNativePointer(const EcmaVM *vm); bool IsUndefined(); bool IsNull(); @@ -271,6 +284,11 @@ public: bool IsUint32Array(); bool IsFloat32Array(); bool IsFloat64Array(); + bool IsJSPrimitiveRef(); + bool IsJSPrimitiveNumber(); + bool IsJSPrimitiveInt(); + bool IsJSPrimitiveBoolean(); + bool IsJSPrimitiveString(); bool IsStrictEquals(const EcmaVM *vm, Local value); Local Typeof(const EcmaVM *vm); @@ -279,9 +297,9 @@ public: private: JSTaggedType value_; friend JSNApi; - template + template friend class Global; - template + template friend class Local; }; @@ -291,6 +309,7 @@ class PUBLIC_API PrimitiveRef : public JSValueRef { class PUBLIC_API IntegerRef : public PrimitiveRef { public: static Local New(const EcmaVM *vm, int input); + static Local NewFromUnsigned(const EcmaVM *vm, unsigned int input); int Value(); }; @@ -480,7 +499,11 @@ public: bool Delete(const EcmaVM *vm, Local key); bool Delete(const EcmaVM *vm, uint32_t key); - // Private + + void SetNativePointerFieldCount(int32_t count); + int32_t GetNativePointerFieldCount(); + void *GetNativePointerField(int32_t index); + void SetNativePointerField(int32_t index, void *data); }; using FunctionCallback = Local (*)(EcmaVM *, Local, @@ -505,6 +528,8 @@ class PUBLIC_API ArrayRef : public ObjectRef { public: static Local New(const EcmaVM *vm, int32_t length = 0); int32_t Length(const EcmaVM *vm); + static bool SetValueAt(const EcmaVM *vm, Local obj, uint32_t index, Local value); + static Local GetValueAt(const EcmaVM *vm, Local obj, uint32_t index); }; class PUBLIC_API PromiseRef : public ObjectRef { @@ -776,22 +801,32 @@ private: static uintptr_t GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress); static uintptr_t GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress); + static uintptr_t SetWeak(const EcmaVM *vm, uintptr_t localAddress); + static bool IsWeak(const EcmaVM *vm, uintptr_t localAddress); static void DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr); - template + static uintptr_t GetGlobalUndefinedAddr(const EcmaVM *vm); + template friend class Global; - template + template friend class Local; friend class test::JSNApiTests; }; -template -template + +template +Global::Global(const EcmaVM *vm) +{ + address_ = JSNApi::GetGlobalUndefinedAddr(vm); +} + +template +template Global::Global(const EcmaVM *vm, const Local ¤t) : vm_(vm) { address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast(*current)); } -template +template void Global::FreeGlobalHandleAddr() { if (address_ == 0) { @@ -801,11 +836,29 @@ void Global::FreeGlobalHandleAddr() address_ = 0; } +template +void Global::SetWeak() +{ + address_ = JSNApi::SetWeak(vm_, address_); +} + +template +bool Global::IsWeak() const +{ + return JSNApi::IsWeak(vm_, address_); +} + // ---------------------------------- Local -------------------------------------------- -template +template +Local::Local(const EcmaVM *vm) +{ + address_ = JSNApi::GetGlobalUndefinedAddr(vm); +} + +template Local::Local(const EcmaVM *vm, const Global ¤t) { address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast(*current)); } } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_JSNAPI_JSNAPI_H +#endif // ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H diff --git a/ecmascript/napi/jsnapi.cpp b/ecmascript/napi/jsnapi.cpp index e682749fe5118d90857bc8e23d94a95fc3421ec3..1338190fad8415cd0abaeefdb83d7b2f95a178fc 100644 --- a/ecmascript/napi/jsnapi.cpp +++ b/ecmascript/napi/jsnapi.cpp @@ -23,17 +23,20 @@ #include "ecmascript/base/json_stringifier.h" #include "ecmascript/base/string_helper.h" #include "ecmascript/base/typed_array_helper-inl.h" +#include "ecmascript/ecma_global_storage-inl.h" #include "ecmascript/ecma_language_context.h" #include "ecmascript/ecma_module.h" #include "ecmascript/ecma_string.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/fast_runtime_stub-inl.h" #include "ecmascript/js_array.h" #include "ecmascript/js_arraybuffer.h" #include "ecmascript/js_dataview.h" #include "ecmascript/js_function.h" #include "ecmascript/js_map.h" +#include "ecmascript/js_primitive_ref.h" #include "ecmascript/js_promise.h" #include "ecmascript/js_regexp.h" #include "ecmascript/js_serializer.h" @@ -49,11 +52,13 @@ namespace panda { using ecmascript::CString; +using ecmascript::ECMAObject; using ecmascript::EcmaString; using ecmascript::ErrorType; using ecmascript::FastRuntimeStub; using ecmascript::GlobalEnv; using ecmascript::GlobalEnvConstants; +using ecmascript::InternalCallParams; using ecmascript::JSArray; using ecmascript::JSArrayBuffer; using ecmascript::JSDataView; @@ -67,6 +72,7 @@ using ecmascript::JSMethod; using ecmascript::JSNativeObject; using ecmascript::JSNativePointer; using ecmascript::JSObject; +using ecmascript::JSPrimitiveRef; using ecmascript::JSPromise; using ecmascript::JSRegExp; using ecmascript::JSSerializer; @@ -82,18 +88,22 @@ using ecmascript::PropertyDescriptor; using ecmascript::OperationResult; using ecmascript::Region; using ecmascript::TaggedArray; +using ecmascript::JSTypedArray; using ecmascript::base::BuiltinsBase; using ecmascript::base::JsonParser; using ecmascript::base::JsonStringifier; using ecmascript::base::StringHelper; using ecmascript::base::TypedArrayHelper; -template +template using JSHandle = ecmascript::JSHandle; -static const uint32_t INTERNAL_POOL_SIZE = 26214400; -static const uint32_t CODE_POOL_SIZE = 10485760; +namespace { +constexpr uint32_t INTERNAL_POOL_SIZE = 0; +constexpr uint32_t CODE_POOL_SIZE = 0; +constexpr uint32_t COMPILER_POOL_SIZE = 0; // NOLINTNEXTLINE(fuchsia-statically-constructed-objects) -static const std::string_view ENTRY_POINTER = "_GLOBAL::func_main_0"; +constexpr std::string_view ENTRY_POINTER = "_GLOBAL::func_main_0"; +} // ------------------------------------ Panda ----------------------------------------------- bool JSNApi::CreateRuntime(const RuntimeOption &option) @@ -106,9 +116,11 @@ bool JSNApi::CreateRuntime(const RuntimeOption &option) runtimeOptions.SetRunGcInPlace(true); // Mem - runtimeOptions.SetObjectPoolSize(option.GetGcPoolSize()); - runtimeOptions.SetInternalPoolSize(INTERNAL_POOL_SIZE); - runtimeOptions.SetCodePoolSize(CODE_POOL_SIZE); + runtimeOptions.SetHeapSizeLimit(option.GetGcPoolSize()); + runtimeOptions.SetInternalMemorySizeLimit(INTERNAL_POOL_SIZE); + runtimeOptions.SetCodeCacheSizeLimit(CODE_POOL_SIZE); + runtimeOptions.SetCompilerMemorySizeLimit(COMPILER_POOL_SIZE); + runtimeOptions.SetInternalAllocatorType("malloc"); // Boot runtimeOptions.SetShouldLoadBootPandaFiles(false); @@ -275,7 +287,23 @@ uintptr_t JSNApi::GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress) return 0; } JSTaggedType value = *(reinterpret_cast(localAddress)); - return vm->GetJSThread()->GetGlobalHandleStorage()->NewGlobalHandle(value); + return vm->GetJSThread()->GetEcmaGlobalStorage()->NewGlobalHandle(value); +} + +uintptr_t JSNApi::SetWeak(const EcmaVM *vm, uintptr_t localAddress) +{ + if (localAddress == 0) { + return 0; + } + return vm->GetJSThread()->GetEcmaGlobalStorage()->SetWeak(localAddress); +} + +bool JSNApi::IsWeak(const EcmaVM *vm, uintptr_t localAddress) +{ + if (localAddress == 0) { + return false; + } + return vm->GetJSThread()->GetEcmaGlobalStorage()->IsWeak(localAddress); } void JSNApi::DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr) @@ -283,7 +311,12 @@ void JSNApi::DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr) if (addr == 0) { return; } - vm->GetJSThread()->GetGlobalHandleStorage()->DisposeGlobalHandle(addr); + vm->GetJSThread()->GetEcmaGlobalStorage()->DisposeGlobalHandle(addr); +} + +uintptr_t JSNApi::GetGlobalUndefinedAddr(const EcmaVM *vm) +{ + return vm->GetJSThread()->GlobalConstants()->GetGlobalConstantAddr(ecmascript::ConstantIndex::UNDEFINED_INDEX); } void *JSNApi::SerializeValue(const EcmaVM *vm, Local value, Local transfer) @@ -336,7 +369,7 @@ Local JSNApi::GetExportObject(EcmaVM *vm, const std::string &file, co { auto moduleManager = vm->GetModuleManager(); ObjectFactory *factory = vm->GetFactory(); - JSHandle moduleName(factory->NewFromStdString(file)); + JSHandle moduleName(factory->NewFromStdStringUnCheck(file, true)); JSHandle moduleObj = moduleManager->GetModule(vm->GetJSThread(), moduleName); JSHandle itemString(factory->NewFromStdString(itemName)); JSHandle exportObj = moduleManager->GetModuleItem(vm->GetJSThread(), moduleObj, itemString); @@ -348,6 +381,7 @@ LocalScope::LocalScope(const EcmaVM *vm) : thread_(vm->GetJSThread()) auto thread = reinterpret_cast(thread_); prevNext_ = thread->GetHandleScopeStorageNext(); prevEnd_ = thread->GetHandleScopeStorageEnd(); + prevHandleStorageIndex_ = thread->GetCurrentHandleStorageIndex(); } LocalScope::LocalScope(const EcmaVM *vm, JSTaggedType value) : thread_(vm->GetJSThread()) @@ -355,6 +389,7 @@ LocalScope::LocalScope(const EcmaVM *vm, JSTaggedType value) : thread_(vm->GetJS auto thread = reinterpret_cast(thread_); prevNext_ = thread->GetHandleScopeStorageNext(); prevEnd_ = thread->GetHandleScopeStorageEnd(); + prevHandleStorageIndex_ = thread->GetCurrentHandleStorageIndex(); ecmascript::EcmaHandleScope::NewHandle(thread, value); } @@ -364,7 +399,7 @@ LocalScope::~LocalScope() thread->SetHandleScopeStorageNext(static_cast(prevNext_)); if (thread->GetHandleScopeStorageEnd() != prevEnd_) { thread->SetHandleScopeStorageEnd(static_cast(prevEnd_)); - thread->ShrunkHandleStorage(static_cast(prevEnd_)); + thread->ShrinkHandleStorage(prevHandleStorageIndex_); } } @@ -410,6 +445,13 @@ Local IntegerRef::New(const EcmaVM *vm, int input) return JSNApiHelper::ToLocal(integer); } +Local IntegerRef::NewFromUnsigned(const EcmaVM *vm, unsigned int input) +{ + JSThread *thread = vm->GetJSThread(); + JSHandle integer(thread, JSTaggedValue(input)); + return JSNApiHelper::ToLocal(integer); +} + int IntegerRef::Value() { return JSNApiHelper::ToJSTaggedValue(this).GetInt(); @@ -664,6 +706,30 @@ bool ObjectRef::Delete(const EcmaVM *vm, uint32_t key) return result; } +void ObjectRef::SetNativePointerFieldCount(int32_t count) +{ + JSHandle object(JSNApiHelper::ToJSHandle(this)); + object->SetNativePointerFieldCount(count); +} + +int32_t ObjectRef::GetNativePointerFieldCount() +{ + JSHandle object(JSNApiHelper::ToJSHandle(this)); + return object->GetNativePointerFieldCount(); +} + +void *ObjectRef::GetNativePointerField(int32_t index) +{ + JSHandle object(JSNApiHelper::ToJSHandle(this)); + return object->GetNativePointerField(index); +} + +void ObjectRef::SetNativePointerField(int32_t index, void *data) +{ + JSHandle object(JSNApiHelper::ToJSHandle(this)); + object->SetNativePointerField(index, data); +} + // ----------------------------------- FunctionRef -------------------------------------- Local FunctionRef::New(EcmaVM *vm, FunctionCallback nativeFunc, void *data) { @@ -715,7 +781,9 @@ Local FunctionRef::Call(const EcmaVM *vm, Local thisObj, for (int i = 0; i < length; ++i) { arguments->Set(thread, i, JSNApiHelper::ToJSHandle(sp[i])); } - JSTaggedValue result = JSFunction::Call(thread, func, thisValue, arguments); + InternalCallParams *args = thread->GetInternalCallParams(); + args->MakeArgList(*arguments); + JSTaggedValue result = JSFunction::Call(thread, func, thisValue, arguments->GetLength(), args->GetArgv()); RETURN_VALUE_IF_ABRUPT_NOT_CLEAR_EXCEPTION(thread, JSValueRef::Exception(vm)); JSHandle resultValue(thread, result); @@ -741,7 +809,9 @@ Local FunctionRef::Constructor(const EcmaVM *vm, for (int i = 0; i < length; ++i) { arguments->Set(thread, i, JSNApiHelper::ToJSHandle(sp[i])); } - JSTaggedValue result = JSFunction::Construct(thread, func, arguments, newTarget); + ecmascript::InternalCallParams *params = thread->GetInternalCallParams(); + params->MakeArgList(*arguments); + JSTaggedValue result = JSFunction::Construct(thread, func, length, params->GetArgv(), newTarget); RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); JSHandle resultValue(vm->GetJSThread(), result); return JSNApiHelper::ToLocal(resultValue); @@ -795,6 +865,22 @@ int32_t ArrayRef::Length([[maybe_unused]] const EcmaVM *vm) return JSArray::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetArrayLength(); } + +Local ArrayRef::GetValueAt(const EcmaVM *vm, Local obj, uint32_t index) +{ + JSThread *thread = vm->GetAssociatedJSThread(); + JSHandle object = JSNApiHelper::ToJSHandle(obj); + JSHandle result = JSArray::FastGetPropertyByValue(thread, object, index); + return JSNApiHelper::ToLocal(result); +} + +bool ArrayRef::SetValueAt(const EcmaVM *vm, Local obj, uint32_t index, Local value) +{ + JSThread *thread = vm->GetAssociatedJSThread(); + JSHandle objectHandle = JSNApiHelper::ToJSHandle(obj); + JSHandle valueHandle = JSNApiHelper::ToJSHandle(value); + return JSArray::FastSetPropertyByValue(thread, objectHandle, index, valueHandle); +} // ---------------------------------- Promise -------------------------------------- Local PromiseCapabilityRef::New(const EcmaVM *vm) { @@ -815,18 +901,15 @@ Local PromiseCapabilityRef::GetPromise(const EcmaVM *vm) bool PromiseCapabilityRef::Resolve(const EcmaVM *vm, Local value) { JSThread *thread = vm->GetJSThread(); - ObjectFactory *factory = vm->GetFactory(); const GlobalEnvConstants *constants = thread->GlobalConstants(); JSHandle arg = JSNApiHelper::ToJSHandle(value); - array_size_t length = 1; - JSHandle argv = factory->NewTaggedArray(length); - argv->Set(thread, 0, arg); - JSHandle capacity(JSNApiHelper::ToJSHandle(this)); JSHandle resolve(thread, capacity->GetResolve()); JSHandle undefined(thread, constants->GetUndefined()); - JSFunction::Call(thread, resolve, undefined, argv); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(arg); + JSFunction::Call(thread, resolve, undefined, 1, arguments->GetArgv()); RETURN_VALUE_IF_ABRUPT(thread, false); return true; } @@ -834,18 +917,15 @@ bool PromiseCapabilityRef::Resolve(const EcmaVM *vm, Local value) bool PromiseCapabilityRef::Reject(const EcmaVM *vm, Local reason) { JSThread *thread = vm->GetJSThread(); - ObjectFactory *factory = vm->GetFactory(); const GlobalEnvConstants *constants = thread->GlobalConstants(); JSHandle arg = JSNApiHelper::ToJSHandle(reason); - array_size_t length = 1; - JSHandle argv = factory->NewTaggedArray(length); - argv->Set(thread, 0, arg); - JSHandle capacity(JSNApiHelper::ToJSHandle(this)); JSHandle reject(thread, capacity->GetReject()); JSHandle undefined(thread, constants->GetUndefined()); - JSFunction::Call(thread, reject, undefined, argv); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(arg); + JSFunction::Call(thread, reject, undefined, 1, arguments->GetArgv()); RETURN_VALUE_IF_ABRUPT(thread, false); return true; } @@ -853,15 +933,15 @@ bool PromiseCapabilityRef::Reject(const EcmaVM *vm, Local reason) Local PromiseRef::Catch(const EcmaVM *vm, Local handler) { JSThread *thread = vm->GetJSThread(); - ObjectFactory *factory = vm->GetFactory(); const GlobalEnvConstants *constants = thread->GlobalConstants(); JSHandle promise = JSNApiHelper::ToJSHandle(this); JSHandle catchKey(thread, constants->GetPromiseCatchString()); JSHandle reject = JSNApiHelper::ToJSHandle(handler); - JSHandle argv = factory->NewTaggedArray(1); - argv->Set(thread, 0, reject); - JSTaggedValue result = JSFunction::Invoke(thread, promise, catchKey, argv); + ecmascript::InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(reject); + JSTaggedValue result = JSFunction::Invoke(thread, promise, catchKey, 1, arguments->GetArgv()); + RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); return JSNApiHelper::ToLocal(JSHandle(thread, result)); } @@ -869,17 +949,15 @@ Local PromiseRef::Catch(const EcmaVM *vm, Local handler Local PromiseRef::Then(const EcmaVM *vm, Local handler) { JSThread *thread = vm->GetJSThread(); - ObjectFactory *factory = vm->GetFactory(); const GlobalEnvConstants *constants = thread->GlobalConstants(); JSHandle promise = JSNApiHelper::ToJSHandle(this); JSHandle thenKey(thread, constants->GetPromiseThenString()); JSHandle resolver = JSNApiHelper::ToJSHandle(handler); - array_size_t length = 2; - JSHandle argv = factory->NewTaggedArray(length); - argv->Set(thread, 0, resolver); - argv->Set(thread, 1, constants->GetUndefined()); - JSTaggedValue result = JSFunction::Invoke(thread, promise, thenKey, argv); + ecmascript::InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(resolver.GetTaggedValue(), constants->GetUndefined()); + JSTaggedValue result = JSFunction::Invoke(thread, promise, thenKey, 2, arguments->GetArgv()); // 2: two args + RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); return JSNApiHelper::ToLocal(JSHandle(thread, result)); } @@ -887,18 +965,16 @@ Local PromiseRef::Then(const EcmaVM *vm, Local handler) Local PromiseRef::Then(const EcmaVM *vm, Local onFulfilled, Local onRejected) { JSThread *thread = vm->GetJSThread(); - ObjectFactory *factory = vm->GetFactory(); const GlobalEnvConstants *constants = thread->GlobalConstants(); JSHandle promise = JSNApiHelper::ToJSHandle(this); JSHandle thenKey(thread, constants->GetPromiseThenString()); JSHandle resolver = JSNApiHelper::ToJSHandle(onFulfilled); JSHandle reject = JSNApiHelper::ToJSHandle(onRejected); - array_size_t length = 2; - JSHandle argv = factory->NewTaggedArray(length); - argv->Set(thread, 0, resolver); - argv->Set(thread, 1, reject); - JSTaggedValue result = JSFunction::Invoke(thread, promise, thenKey, argv); + ecmascript::InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(resolver, reject); + JSTaggedValue result = JSFunction::Invoke(thread, promise, thenKey, 2, arguments->GetArgv()); // 2: two args + RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); return JSNApiHelper::ToLocal(JSHandle(thread, result)); } @@ -994,53 +1070,59 @@ Local DataViewRef::GetArrayBuffer(const EcmaVM *vm) // ---------------------------------- TypedArray ----------------------------------- int32_t TypedArrayRef::ByteLength(const EcmaVM *vm) { - JSThread *thread = vm->GetJSThread(); - JSHandle typeArray(JSNApiHelper::ToJSHandle(this)); - return TypedArrayHelper::GetByteLength(thread, typeArray); + JSHandle typedArray(JSNApiHelper::ToJSHandle(this)); + JSTaggedValue length = typedArray->GetByteLength(); + if (!length.IsNumber()) { + return 0; + } + return length.GetNumber(); } int32_t TypedArrayRef::ByteOffset(const EcmaVM *vm) { - JSThread *thread = vm->GetJSThread(); - JSHandle typeArray(JSNApiHelper::ToJSHandle(this)); - return TypedArrayHelper::GetByteOffset(thread, typeArray); + JSHandle typedArray(JSNApiHelper::ToJSHandle(this)); + JSTaggedValue length = typedArray->GetByteOffset(); + if (!length.IsNumber()) { + return 0; + } + return length.GetNumber(); } int32_t TypedArrayRef::ArrayLength(const EcmaVM *vm) { - JSThread *thread = vm->GetJSThread(); - JSHandle typeArray(JSNApiHelper::ToJSHandle(this)); - return TypedArrayHelper::GetArrayLength(thread, typeArray); + JSHandle typedArray(JSNApiHelper::ToJSHandle(this)); + JSTaggedValue length = typedArray->GetArrayLength(); + if (!length.IsNumber()) { + return 0; + } + return length.GetNumber(); } Local TypedArrayRef::GetArrayBuffer(const EcmaVM *vm) { JSThread *thread = vm->GetJSThread(); JSHandle typeArray(JSNApiHelper::ToJSHandle(this)); - JSHandle arrayBuffer(thread, TypedArrayHelper::GetViewedArrayBuffer(typeArray)); + JSHandle arrayBuffer(thread, JSTypedArray::Cast(*typeArray)->GetViewedArrayBuffer()); return JSNApiHelper::ToLocal(arrayBuffer); } // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define TYPED_ARRAY_NEW(Type) \ - Local Type##Ref::New( \ - const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length) \ - { \ - JSThread *thread = vm->GetJSThread(); \ - ObjectFactory *factory = vm->GetFactory(); \ - JSHandle env = vm->GetGlobalEnv(); \ - \ - JSHandle func = env->Get##Type##Function(); \ - JSHandle arrayBuffer(JSNApiHelper::ToJSHandle(buffer)); \ - array_size_t arrayLength = 3; \ - JSHandle argv = factory->NewTaggedArray(arrayLength); \ - argv->Set(thread, 0, arrayBuffer); \ - argv->Set(thread, 1, JSTaggedValue(byteOffset)); \ - argv->Set(thread, 2, JSTaggedValue(length)); \ - JSTaggedValue result = JSFunction::Construct(thread, func, argv, func); \ - RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); \ - JSHandle resultHandle(thread, result); \ - return JSNApiHelper::ToLocal(resultHandle); \ +#define TYPED_ARRAY_NEW(Type) \ + Local Type##Ref::New( \ + const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length) \ + { \ + JSThread *thread = vm->GetJSThread(); \ + JSHandle env = vm->GetGlobalEnv(); \ + \ + JSHandle func = env->Get##Type##Function(); \ + JSHandle arrayBuffer(JSNApiHelper::ToJSHandle(buffer)); \ + ecmascript::InternalCallParams *argv = thread->GetInternalCallParams(); \ + argv->MakeArgv(arrayBuffer.GetTaggedValue(), JSTaggedValue(byteOffset), JSTaggedValue(length)); \ + array_size_t argc = 3; \ + JSTaggedValue result = JSFunction::Construct(thread, func, argc, argv->GetArgv(), func); \ + RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); \ + JSHandle resultHandle(thread, result); \ + return JSNApiHelper::ToLocal(resultHandle); \ } TYPED_ARRAY_ALL(TYPED_ARRAY_NEW) @@ -1216,7 +1298,7 @@ JSTaggedValue Callback::RegisterCallbackWithNewTarget(ecmascript::EcmaRuntimeCal (reinterpret_cast(callBackObj->GetExternalPointer())); // newTarget - JSHandle newTarget(BuiltinsBase::GetConstructor(info)); + JSHandle newTarget(BuiltinsBase::GetNewTarget(info)); // this JSHandle thisValue(BuiltinsBase::GetThis(info)); @@ -1297,6 +1379,14 @@ Local JSValueRef::ToString(const EcmaVM *vm) return JSNApiHelper::ToLocal(obj); } +Local JSValueRef::ToNativePointer(const EcmaVM *vm) +{ + JSThread *thread = vm->GetJSThread(); + JSHandle obj = JSNApiHelper::ToJSHandle(this); + RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); + return JSNApiHelper::ToLocal(obj); +} + bool JSValueRef::BooleaValue() { return JSNApiHelper::ToJSTaggedValue(this).ToBoolean(); @@ -1585,4 +1675,33 @@ bool JSValueRef::IsFloat64Array() { return JSNApiHelper::ToJSTaggedValue(this).IsJSFloat64Array(); } + +bool JSValueRef::IsJSPrimitiveRef() +{ + return JSNApiHelper::ToJSTaggedValue(this).IsJSPrimitiveRef(); +} + +bool JSValueRef::IsJSPrimitiveNumber() +{ + JSHandle obj = JSNApiHelper::ToJSHandle(this); + return JSPrimitiveRef::Cast(obj->GetHeapObject())->IsNumber(); +} + +bool JSValueRef::IsJSPrimitiveInt() +{ + JSHandle obj = JSNApiHelper::ToJSHandle(this); + return JSPrimitiveRef::Cast(obj->GetHeapObject())->IsInt(); +} + +bool JSValueRef::IsJSPrimitiveBoolean() +{ + JSHandle obj = JSNApiHelper::ToJSHandle(this); + return JSPrimitiveRef::Cast(obj->GetHeapObject())->IsBoolean(); +} + +bool JSValueRef::IsJSPrimitiveString() +{ + JSHandle obj = JSNApiHelper::ToJSHandle(this); + return JSPrimitiveRef::Cast(obj->GetHeapObject())->IsString(); +} } // namespace panda diff --git a/ecmascript/napi/jsnapi_helper-inl.h b/ecmascript/napi/jsnapi_helper-inl.h index 6c945b26b30c5fb66d1a8485100036e2859a0265..1429ddadcb142472e2c1d15ba8a76caf5b3c7015 100644 --- a/ecmascript/napi/jsnapi_helper-inl.h +++ b/ecmascript/napi/jsnapi_helper-inl.h @@ -13,15 +13,15 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_NAPI_JSNAPI_HELPER_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_NAPI_JSNAPI_HELPER_INL_H +#ifndef ECMASCRIPT_NAPI_JSNAPI_HELPER_INL_H +#define ECMASCRIPT_NAPI_JSNAPI_HELPER_INL_H #include "ecmascript/js_tagged_value.h" #include "jsnapi_helper.h" #include "libpandabase/macros.h" namespace panda { -template +template Local JSNApiHelper::ToLocal(ecmascript::JSHandle from) { return Local(from.GetAddress()); @@ -45,4 +45,4 @@ ecmascript::JSHandle JSNApiHelper::ToJSHandle(JSValue return ecmascript::JSHandle(reinterpret_cast(from)); } } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_NAPI_JSNAPI_HELPER_INL_H \ No newline at end of file +#endif // ECMASCRIPT_NAPI_JSNAPI_HELPER_INL_H \ No newline at end of file diff --git a/ecmascript/napi/jsnapi_helper.h b/ecmascript/napi/jsnapi_helper.h index 1b0c67ec935b2effdfac3aa9fc096928bb3c4e99..bd377a35151ea82092b456b66b61f5467d6f73bc 100644 --- a/ecmascript/napi/jsnapi_helper.h +++ b/ecmascript/napi/jsnapi_helper.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_NAPI_JSNAPI_HELPER_H -#define PANDA_RUNTIME_ECMASCRIPT_NAPI_JSNAPI_HELPER_H +#ifndef ECMASCRIPT_NAPI_JSNAPI_HELPER_H +#define ECMASCRIPT_NAPI_JSNAPI_HELPER_H #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/js_handle.h" @@ -61,7 +61,7 @@ namespace panda { class JSNApiHelper { public: - template + template static inline Local ToLocal(ecmascript::JSHandle from); static inline ecmascript::JSTaggedValue ToJSTaggedValue(JSValueRef *from); @@ -77,4 +77,4 @@ public: static ecmascript::JSTaggedValue RegisterCallbackWithNewTarget(ecmascript::EcmaRuntimeCallInfo *info); }; } // namespace panda -#endif // PANDA_RUNTIME_ECMASCRIPT_JSNAPI_JSNAPI_HELPER_H +#endif // ECMASCRIPT_NAPI_JSNAPI_HELPER_H diff --git a/ecmascript/napi/test/jsnapi_tests.cpp b/ecmascript/napi/test/jsnapi_tests.cpp index 3cb9bcddcd5a3f5896f1c90d74d52cd76d82752e..a8eb17ef376a66b4c471da3308feebabe6df9879 100644 --- a/ecmascript/napi/test/jsnapi_tests.cpp +++ b/ecmascript/napi/test/jsnapi_tests.cpp @@ -375,7 +375,7 @@ HWTEST_F_L0(JSNApiTests, ArrayBufferWithBuffer) }; { LocalScope scope(vm_); - uint8_t *buffer = new uint8_t[length]; + uint8_t *buffer = new uint8_t[length](); Local arrayBuffer = ArrayBufferRef::New(vm_, buffer, length, deleter, data); ASSERT_TRUE(arrayBuffer->IsArrayBuffer()); ASSERT_EQ(arrayBuffer->ByteLength(vm_), length); diff --git a/ecmascript/object_factory-inl.h b/ecmascript/object_factory-inl.h index af7f80482494cc1f4f1c7c0bcd9a97b5ca89f824..bc08129f22deef00509812825549dad0d7fe99e4 100644 --- a/ecmascript/object_factory-inl.h +++ b/ecmascript/object_factory-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_OBJECT_FACTORY_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_OBJECT_FACTORY_INL_H +#ifndef ECMASCRIPT_OBJECT_FACTORY_INL_H +#define ECMASCRIPT_OBJECT_FACTORY_INL_H #include "object_factory.h" #include "ecmascript/mem/ecma_heap_manager-inl.h" @@ -24,21 +24,21 @@ namespace panda::ecmascript { EcmaString *ObjectFactory::AllocNonMovableStringObject(size_t size) { - return reinterpret_cast(heapHelper_.AllocateNonMovableOrLargeObject(stringClass_, size)); + return reinterpret_cast(heapHelper_.AllocateNonMovableOrHugeObject(stringClass_, size)); } EcmaString *ObjectFactory::AllocStringObject(size_t size) { - return reinterpret_cast(heapHelper_.AllocateYoungGenerationOrLargeObject(stringClass_, size)); + return reinterpret_cast(heapHelper_.AllocateYoungGenerationOrHugeObject(stringClass_, size)); } JSHandle ObjectFactory::NewJSNativePointer(void *externalPointer, bool nonMovable) { TaggedObject *header; if (nonMovable) { - header = heapHelper_.AllocateNonMovableOrLargeObject(jsNativePointerClass_); + header = heapHelper_.AllocateNonMovableOrHugeObject(jsNativePointerClass_); } else { - header = heapHelper_.AllocateYoungGenerationOrLargeObject(jsNativePointerClass_); + header = heapHelper_.AllocateYoungGenerationOrHugeObject(jsNativePointerClass_); } JSHandle obj(thread_, header); obj->SetExternalPointer(externalPointer); @@ -48,15 +48,15 @@ JSHandle ObjectFactory::NewJSNativePointer(void *externalPointe } JSHandle ObjectFactory::NewJSNativePointer(void *externalPointer, - DeleteEntryPoint callBack, + const DeleteEntryPoint &callBack, void *data, bool nonMovable) { TaggedObject *header; if (nonMovable) { - header = heapHelper_.AllocateNonMovableOrLargeObject(jsNativePointerClass_); + header = heapHelper_.AllocateNonMovableOrHugeObject(jsNativePointerClass_); } else { - header = heapHelper_.AllocateYoungGenerationOrLargeObject(jsNativePointerClass_); + header = heapHelper_.AllocateYoungGenerationOrHugeObject(jsNativePointerClass_); } JSHandle obj(thread_, header); obj->SetExternalPointer(externalPointer); @@ -78,7 +78,7 @@ LexicalEnv *ObjectFactory::InlineNewLexicalEnv(int numSlots) return array; } -template +template void ObjectFactory::NewJSIntlIcuData(const JSHandle &obj, const S &icu, const DeleteEntryPoint &callback) { S *icuPoint = vm_->GetRegionFactory()->New(icu); @@ -86,20 +86,13 @@ void ObjectFactory::NewJSIntlIcuData(const JSHandle &obj, const S &icu, const JSTaggedValue data = obj->GetIcuField(); if (data.IsHeapObject() && data.IsJSNativePointer()) { JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject()); - void *pointer = native->GetExternalPointer(); - if (pointer != nullptr) { - native->Destroy(); - vm_->GetRegionFactory()->FreeBuffer(native->GetExternalPointer()); - } - native->SetExternalPointer(icuPoint); + native->ResetExternalPointer(icuPoint); return; } - JSHandle pointer(thread_, NewJSNativePointer(icuPoint).GetTaggedValue()); - pointer->SetDeleter(callback); - pointer->SetData(vm_); + JSHandle pointer(thread_, NewJSNativePointer(icuPoint, callback, vm_).GetTaggedValue()); obj->SetIcuField(thread_, pointer.GetTaggedValue()); // push uint8_t* to ecma array_data_list vm_->PushToArrayDataList(*pointer); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_OBJECT_FACTORY_INL_H +#endif // ECMASCRIPT_OBJECT_FACTORY_INL_H diff --git a/ecmascript/object_factory.cpp b/ecmascript/object_factory.cpp index 9bafeca848c89f29b11b989a4dd8cac01f7f957f..7282588009227f3e99881e2fcce43a598c034e9d 100644 --- a/ecmascript/object_factory.cpp +++ b/ecmascript/object_factory.cpp @@ -31,6 +31,7 @@ #include "ecmascript/ic/profile_type_info.h" #include "ecmascript/ic/property_box.h" #include "ecmascript/ic/proto_change_details.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/jobs/micro_job_queue.h" #include "ecmascript/jobs/pending_job.h" #include "ecmascript/js_arguments.h" @@ -40,34 +41,26 @@ #include "ecmascript/js_async_function.h" #include "ecmascript/js_dataview.h" #include "ecmascript/js_date.h" -#include "ecmascript/js_float32_array.h" -#include "ecmascript/js_float64_array.h" #include "ecmascript/js_for_in_iterator.h" #include "ecmascript/js_generator_object.h" #include "ecmascript/js_hclass-inl.h" #include "ecmascript/js_hclass.h" -#include "ecmascript/js_int16_array.h" -#include "ecmascript/js_int32_array.h" -#include "ecmascript/js_int8_array.h" #include "ecmascript/js_iterator.h" -#include "ecmascript/js_map_iterator.h" #include "ecmascript/js_map.h" +#include "ecmascript/js_map_iterator.h" #include "ecmascript/js_object-inl.h" #include "ecmascript/js_primitive_ref.h" #include "ecmascript/js_promise.h" #include "ecmascript/js_proxy.h" #include "ecmascript/js_realm.h" #include "ecmascript/js_regexp.h" -#include "ecmascript/js_set_iterator.h" #include "ecmascript/js_set.h" +#include "ecmascript/js_set_iterator.h" #include "ecmascript/js_string_iterator.h" #include "ecmascript/js_symbol.h" #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/js_thread.h" -#include "ecmascript/js_uint16_array.h" -#include "ecmascript/js_uint32_array.h" -#include "ecmascript/js_uint8_array.h" -#include "ecmascript/js_uint8_clamped_array.h" +#include "ecmascript/js_typed_array.h" #include "ecmascript/js_weak_container.h" #include "ecmascript/layout_info-inl.h" #include "ecmascript/linked_hash_table-inl.h" @@ -98,7 +91,7 @@ JSHandle ObjectFactory::NewEcmaDynClass(JSHClass *hclass, uint32_t siz { NewObjectHook(); uint32_t classSize = JSHClass::SIZE; - auto *newClass = static_cast(heapHelper_.AllocateNonMovableOrLargeObject(hclass, classSize)); + auto *newClass = static_cast(heapHelper_.AllocateNonMovableOrHugeObject(hclass, classSize)); newClass->Initialize(thread_, size, type, JSTaggedValue::Null()); return JSHandle(thread_, newClass); @@ -148,15 +141,16 @@ void ObjectFactory::ObtainRootClass([[maybe_unused]] const JSHandle & prototypeHandlerClass_ = JSHClass::Cast(globalConst->GetPrototypeHandlerClass().GetTaggedObject()); functionExtraInfo_ = JSHClass::Cast(globalConst->GetFunctionExtraInfoClass().GetTaggedObject()); jsRealmClass_ = JSHClass::Cast(globalConst->GetJSRealmClass().GetTaggedObject()); + machineCodeClass_ = JSHClass::Cast(globalConst->GetMachineCodeClass().GetTaggedObject()); } void ObjectFactory::InitObjectFields(const TaggedObject *object) { auto *klass = object->GetClass(); - auto objBodySize = klass->GetObjectSize() - TaggedObject::ObjectHeaderSize(); + auto objBodySize = klass->GetObjectSize() - TaggedObject::TaggedObjectSize(); ASSERT(objBodySize % JSTaggedValue::TaggedTypeSize() == 0); int numOfFields = static_cast(objBodySize / JSTaggedValue::TaggedTypeSize()); - size_t addr = reinterpret_cast(object) + TaggedObject::ObjectHeaderSize(); + size_t addr = reinterpret_cast(object) + TaggedObject::TaggedObjectSize(); for (int i = 0; i < numOfFields; i++) { auto *fieldAddr = reinterpret_cast(addr + i * JSTaggedValue::TaggedTypeSize()); *fieldAddr = JSTaggedValue::Undefined().GetRawData(); @@ -172,16 +166,12 @@ void ObjectFactory::NewJSArrayBufferData(const JSHandle &array, i JSTaggedValue data = array->GetArrayBufferData(); if (data != JSTaggedValue::Undefined()) { auto *pointer = JSNativePointer::Cast(data.GetTaggedObject()); - void *arr = pointer->GetExternalPointer(); - if (arr != nullptr) { - vm_->GetRegionFactory()->FreeBuffer(arr); - } auto newData = vm_->GetRegionFactory()->AllocateBuffer(length * sizeof(uint8_t)); if (memset_s(newData, length, 0, length) != EOK) { LOG_ECMA(FATAL) << "memset_s failed"; UNREACHABLE(); } - pointer->SetExternalPointer(newData); + pointer->ResetExternalPointer(newData); return; } @@ -190,7 +180,8 @@ void ObjectFactory::NewJSArrayBufferData(const JSHandle &array, i LOG_ECMA(FATAL) << "memset_s failed"; UNREACHABLE(); } - JSHandle pointer = NewJSNativePointer(newData); + JSHandle pointer = NewJSNativePointer(newData, RegionFactory::FreeBufferFunc, + vm_->GetRegionFactory()); array->SetArrayBufferData(thread_, pointer.GetTaggedValue()); vm_->PushToArrayDataList(*pointer); } @@ -209,9 +200,8 @@ JSHandle ObjectFactory::NewJSArrayBuffer(int32_t length) LOG_ECMA(FATAL) << "memset_s failed"; UNREACHABLE(); } - JSHandle pointer = NewJSNativePointer(newData); - pointer->SetDeleter(RegionFactory::FreeBufferFunc); - pointer->SetData(vm_->GetRegionFactory()); + JSHandle pointer = NewJSNativePointer(newData, RegionFactory::FreeBufferFunc, + vm_->GetRegionFactory()); arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue()); arrayBuffer->SetShared(thread_, JSTaggedValue::False()); vm_->PushToArrayDataList(*pointer); @@ -230,9 +220,7 @@ JSHandle ObjectFactory::NewJSArrayBuffer(void *buffer, int32_t le length = buffer == nullptr ? 0 : length; arrayBuffer->SetArrayBufferByteLength(thread_, JSTaggedValue(length)); if (length > 0) { - JSHandle pointer = NewJSNativePointer(buffer); - pointer->SetDeleter(deleter); - pointer->SetData(data); + JSHandle pointer = NewJSNativePointer(buffer, deleter, data); arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue()); arrayBuffer->SetShared(thread_, JSTaggedValue(share)); vm_->PushToArrayDataList(*pointer); @@ -277,15 +265,11 @@ void ObjectFactory::NewJSRegExpByteCodeData(const JSHandle ®exp, vo JSTaggedValue data = regexp->GetByteCodeBuffer(); if (data != JSTaggedValue::Undefined()) { JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject()); - native->Destroy(); - void *bufferPointer = native->GetExternalPointer(); - if (bufferPointer != nullptr) { - vm_->GetRegionFactory()->FreeBuffer(bufferPointer); - } - native->SetExternalPointer(newBuffer); + native->ResetExternalPointer(newBuffer); return; } - JSHandle pointer = NewJSNativePointer(newBuffer); + JSHandle pointer = NewJSNativePointer(newBuffer, RegionFactory::FreeBufferFunc, + vm_->GetRegionFactory()); regexp->SetByteCodeBuffer(thread_, pointer.GetTaggedValue()); regexp->SetLength(thread_, JSTaggedValue(static_cast(size))); @@ -305,8 +289,9 @@ JSHandle ObjectFactory::NewJSObject(const JSHandle &jshclass { NewObjectHook(); JSHandle obj(thread_, JSObject::Cast(NewDynObject(jshclass, JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS))); - obj->SetElements(thread_, EmptyArray(), SKIP_BARRIER); - obj->SetProperties(thread_, EmptyArray(), SKIP_BARRIER); + JSHandle emptyArray = EmptyArray(); + obj->SetElements(thread_, emptyArray, SKIP_BARRIER); + obj->SetProperties(thread_, emptyArray, SKIP_BARRIER); return obj; } @@ -319,7 +304,7 @@ JSHandle ObjectFactory::CloneProperties(const JSHandle NewObjectHook(); auto klass = old->GetClass(); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength); - auto header = heapHelper_.AllocateYoungGenerationOrLargeObject(klass, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(klass, size); JSHandle newArray(thread_, header); newArray->SetLength(newLength); @@ -335,7 +320,7 @@ JSHandle ObjectFactory::CloneObjectLiteral(JSHandle object) NewObjectHook(); auto klass = object->GetClass(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(klass); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(klass); JSHandle cloneObject(thread_, JSObject::Cast(header)); JSHandle elements(thread_, object->GetElements()); @@ -357,7 +342,7 @@ JSHandle ObjectFactory::CloneArrayLiteral(JSHandle object) NewObjectHook(); auto klass = object->GetClass(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(klass); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(klass); JSHandle cloneObject(thread_, JSObject::Cast(header)); JSHandle elements(thread_, object->GetElements()); @@ -386,7 +371,7 @@ JSHandle ObjectFactory::CloneProperties(const JSHandle NewObjectHook(); auto klass = old->GetClass(); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength); - auto header = heapHelper_.AllocateYoungGenerationOrLargeObject(klass, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(klass, size); JSHandle newArray(thread_, header); newArray->SetLength(newLength); @@ -412,7 +397,7 @@ JSHandle ObjectFactory::CloneObjectLiteral(JSHandle object, NewObjectHook(); auto klass = object->GetClass(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(klass); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(klass); JSHandle cloneObject(thread_, JSObject::Cast(header)); JSHandle elements(thread_, object->GetElements()); @@ -452,6 +437,9 @@ JSHandle ObjectFactory::CloneJSFuction(JSHandle obj, Fun JSObject::SetPrototype(thread_, initialGeneratorFuncPrototype, env->GetGeneratorPrototype()); cloneFunc->SetProtoOrDynClass(thread_, initialGeneratorFuncPrototype); } + + JSTaggedValue length = obj->GetPropertyInlinedProps(JSFunction::LENGTH_INLINE_PROPERTY_INDEX); + cloneFunc->SetPropertyInlinedProps(thread_, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, length); return cloneFunc; } @@ -543,7 +531,7 @@ JSHandle ObjectFactory::CreateJSArrayInstanceClass(JSHandle= fieldOrder); arrayDynclass->SetUnusedInlinedProps(unusedInlinedProps - fieldOrder); } - arrayDynclass->SetIsStableJSArray(true); + arrayDynclass->SetIsStableElements(true); arrayDynclass->SetHasConstructor(false); return arrayDynclass; @@ -607,6 +595,7 @@ JSHandle ObjectFactory::CreateJSArguments() ASSERT(unusedInlinedProps >= fieldOrder); argumentsDynclass->SetUnusedInlinedProps(unusedInlinedProps - fieldOrder); } + argumentsDynclass->SetIsStableElements(true); return argumentsDynclass; } @@ -668,10 +657,9 @@ JSHandle ObjectFactory::NewJSError(const ErrorType &errorType, const J JSHandle nativePrototype(thread_, nativeFunc->GetFunctionPrototype()); JSHandle ctorKey = globalConst->GetHandledConstructorString(); - array_size_t length = 1; - JSHandle array = NewTaggedArray(length); - array->Set(thread_, 0, message.GetTaggedValue()); - JSTaggedValue obj = JSFunction::Invoke(thread_, nativePrototype, ctorKey, array); + InternalCallParams *arguments = thread_->GetInternalCallParams(); + arguments->MakeArgv(message.GetTaggedValue()); + JSTaggedValue obj = JSFunction::Invoke(thread_, nativePrototype, ctorKey, 1, arguments->GetArgv()); JSHandle handleNativeInstanceObj(thread_, obj); return handleNativeInstanceObj; } @@ -703,6 +691,13 @@ JSHandle ObjectFactory::NewJSObjectByConstructor(const JSHandleSetLength(thread_, JSTaggedValue(0)); @@ -715,67 +710,19 @@ JSHandle ObjectFactory::NewJSObjectByConstructor(const JSHandleSetLocalOffset(thread_, JSTaggedValue(JSDate::MAX_DOUBLE)); break; case JSType::JS_INT8_ARRAY: - JSInt8Array::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined()); - JSInt8Array::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined()); - JSInt8Array::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0)); - JSInt8Array::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0)); - JSInt8Array::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0)); - break; case JSType::JS_UINT8_ARRAY: - JSUint8Array::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined()); - JSUint8Array::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined()); - JSUint8Array::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0)); - JSUint8Array::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0)); - JSUint8Array::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0)); - break; case JSType::JS_UINT8_CLAMPED_ARRAY: - JSUint8ClampedArray::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined()); - JSUint8ClampedArray::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined()); - JSUint8ClampedArray::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0)); - JSUint8ClampedArray::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0)); - JSUint8ClampedArray::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0)); - break; case JSType::JS_INT16_ARRAY: - JSInt16Array::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined()); - JSInt16Array::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined()); - JSInt16Array::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0)); - JSInt16Array::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0)); - JSInt16Array::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0)); - break; case JSType::JS_UINT16_ARRAY: - JSUint16Array::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined()); - JSUint16Array::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined()); - JSUint16Array::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0)); - JSUint16Array::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0)); - JSUint16Array::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0)); - break; case JSType::JS_INT32_ARRAY: - JSInt32Array::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined()); - JSInt32Array::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined()); - JSInt32Array::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0)); - JSInt32Array::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0)); - JSInt32Array::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0)); - break; case JSType::JS_UINT32_ARRAY: - JSUint32Array::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined()); - JSUint32Array::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined()); - JSUint32Array::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0)); - JSUint32Array::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0)); - JSUint32Array::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0)); - break; case JSType::JS_FLOAT32_ARRAY: - JSFloat32Array::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined()); - JSFloat32Array::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined()); - JSFloat32Array::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0)); - JSFloat32Array::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0)); - JSFloat32Array::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0)); - break; case JSType::JS_FLOAT64_ARRAY: - JSFloat64Array::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined()); - JSFloat64Array::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined()); - JSFloat64Array::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0)); - JSFloat64Array::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0)); - JSFloat64Array::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0)); + JSTypedArray::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined()); + JSTypedArray::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined()); + JSTypedArray::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0)); + JSTypedArray::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0)); + JSTypedArray::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0)); break; case JSType::JS_REG_EXP: JSRegExp::Cast(*obj)->SetByteCodeBuffer(thread_, JSTaggedValue::Undefined()); @@ -868,7 +815,7 @@ FreeObject *ObjectFactory::FillFreeObject(uintptr_t address, size_t size, Remove TaggedObject *ObjectFactory::NewDynObject(const JSHandle &dynclass, int inobjPropCount) { - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(*dynclass); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(*dynclass); if (inobjPropCount > 0) { InitializeExtraProperties(dynclass, header, inobjPropCount); } @@ -877,7 +824,7 @@ TaggedObject *ObjectFactory::NewDynObject(const JSHandle &dynclass, in TaggedObject *ObjectFactory::NewNonMovableDynObject(const JSHandle &dynclass, int inobjPropCount) { - TaggedObject *header = heapHelper_.AllocateNonMovableOrLargeObject(*dynclass); + TaggedObject *header = heapHelper_.AllocateNonMovableOrHugeObject(*dynclass); if (inobjPropCount > 0) { InitializeExtraProperties(dynclass, header, inobjPropCount); } @@ -945,7 +892,7 @@ JSHandle ObjectFactory::CreateFunctionClass(FunctionKind kind, uint32_ ASSERT(JSFunction::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder); JSHandle layoutInfoHandle = CreateLayoutInfo(JSFunction::LENGTH_OF_INLINE_PROPERTIES); { - PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, true); + PropertyAttributes attributes = PropertyAttributes::Default(false, false, true); attributes.SetIsInlinedProps(true); attributes.SetRepresentation(Representation::MIXED); attributes.SetOffset(fieldOrder); @@ -1044,6 +991,26 @@ JSHandle ObjectFactory::NewJSBoundFunction(const JSHandle ObjectFactory::NewJSIntlBoundFunction(const void *nativeFunc, int functionLength) +{ + NewObjectHook(); + JSHandle env = vm_->GetGlobalEnv(); + JSHandle dynclass = JSHandle::Cast(env->GetJSIntlBoundFunctionClass()); + + JSHandle intlBoundFunc = JSHandle::Cast(NewJSObject(dynclass)); + JSMethod *method = vm_->GetMethodForNativeFunction(nativeFunc); + intlBoundFunc->SetCallTarget(thread_, method); + JSHandle function = JSHandle::Cast(intlBoundFunc); + JSFunction::InitializeJSFunction(thread_, function, FunctionKind::NORMAL_FUNCTION); + JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(functionLength)); + const GlobalEnvConstants *globalConst = thread_->GlobalConstants(); + JSHandle emptyString = globalConst->GetHandledEmptyString(); + JSHandle nameKey = globalConst->GetHandledNameString(); + PropertyDescriptor nameDesc(thread_, emptyString, false, false, true); + JSTaggedValue::DefinePropertyOrThrow(thread_, JSHandle::Cast(function), nameKey, nameDesc); + return intlBoundFunc; +} + JSHandle ObjectFactory::NewJSProxyRevocFunction(const JSHandle &proxy, const void *nativeFunc) { @@ -1131,7 +1098,7 @@ JSHandle ObjectFactory::NewJSAsyncFuncObject() JSHandle ObjectFactory::NewCompletionRecord(uint8_t type, JSHandle value) { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(completionRecordClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(completionRecordClass_); JSHandle obj(thread_, header); obj->SetType(thread_, JSTaggedValue(static_cast(type))); obj->SetValue(thread_, value); @@ -1141,7 +1108,7 @@ JSHandle ObjectFactory::NewCompletionRecord(uint8_t type, JSHa JSHandle ObjectFactory::NewGeneratorContext() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(generatorContextClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(generatorContextClass_); JSHandle obj(thread_, header); obj->SetRegsArray(thread_, JSTaggedValue::Undefined()); obj->SetMethod(thread_, JSTaggedValue::Undefined()); @@ -1217,7 +1184,7 @@ JSHandle ObjectFactory::NewGlobalEnv(JSHClass *globalEnvClass) NewObjectHook(); // Note: Global env must be allocated in non-movable heap, since its getters will directly return // the offsets of the properties as the address of Handles. - TaggedObject *header = heapHelper_.AllocateNonMovableOrLargeObject(globalEnvClass); + TaggedObject *header = heapHelper_.AllocateNonMovableOrHugeObject(globalEnvClass); InitObjectFields(header); return JSHandle(thread_, GlobalEnv::Cast(header)); } @@ -1226,7 +1193,7 @@ JSHandle ObjectFactory::NewLexicalEnv(int numSlots) { NewObjectHook(); size_t size = LexicalEnv::ComputeSize(numSlots); - auto header = heapHelper_.AllocateYoungGenerationOrLargeObject(envClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(envClass_, size); JSHandle array(thread_, header); array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), numSlots + LexicalEnv::RESERVED_ENV_LENGTH); return array; @@ -1235,11 +1202,11 @@ JSHandle ObjectFactory::NewLexicalEnv(int numSlots) JSHandle ObjectFactory::NewJSSymbol() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(symbolClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(symbolClass_); JSHandle obj(thread_, JSSymbol::Cast(header)); obj->SetDescription(thread_, JSTaggedValue::Undefined()); obj->SetFlags(thread_, JSTaggedValue(0)); - auto result = JSTaggedValue(SymbolTable::Hash(obj.GetTaggedValue())); + auto result = JSTaggedValue(static_cast(SymbolTable::Hash(obj.GetTaggedValue()))); obj->SetHashField(thread_, result); return obj; } @@ -1254,12 +1221,12 @@ JSHandle ObjectFactory::NewPrivateSymbol() JSHandle ObjectFactory::NewPrivateNameSymbol(const JSHandle &name) { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(symbolClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(symbolClass_); JSHandle obj(thread_, JSSymbol::Cast(header)); obj->SetFlags(thread_, JSTaggedValue(0)); obj->SetPrivateNameSymbol(thread_); obj->SetDescription(thread_, name); - auto result = JSTaggedValue(SymbolTable::Hash(name.GetTaggedValue())); + auto result = JSTaggedValue(static_cast(SymbolTable::Hash(name.GetTaggedValue()))); obj->SetHashField(thread_, result); return obj; } @@ -1267,12 +1234,12 @@ JSHandle ObjectFactory::NewPrivateNameSymbol(const JSHandle ObjectFactory::NewWellKnownSymbol(const JSHandle &name) { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(symbolClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(symbolClass_); JSHandle obj(thread_, JSSymbol::Cast(header)); obj->SetFlags(thread_, JSTaggedValue(0)); obj->SetWellKnownSymbol(thread_); obj->SetDescription(thread_, name); - auto result = JSTaggedValue(SymbolTable::Hash(name.GetTaggedValue())); + auto result = JSTaggedValue(static_cast(SymbolTable::Hash(name.GetTaggedValue()))); obj->SetHashField(thread_, result); return obj; } @@ -1280,11 +1247,11 @@ JSHandle ObjectFactory::NewWellKnownSymbol(const JSHandle ObjectFactory::NewPublicSymbol(const JSHandle &name) { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(symbolClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(symbolClass_); JSHandle obj(thread_, JSSymbol::Cast(header)); obj->SetFlags(thread_, JSTaggedValue(0)); obj->SetDescription(thread_, name); - auto result = JSTaggedValue(SymbolTable::Hash(name.GetTaggedValue())); + auto result = JSTaggedValue(static_cast(SymbolTable::Hash(name.GetTaggedValue()))); obj->SetHashField(thread_, result); return obj; } @@ -1338,7 +1305,7 @@ JSHandle ObjectFactory::NewSymbolWithTableWithChar(const char *descrip JSHandle ObjectFactory::NewAccessorData() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(accessorDataClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(accessorDataClass_); JSHandle acc(thread_, AccessorData::Cast(header)); acc->SetGetter(thread_, JSTaggedValue::Undefined()); acc->SetSetter(thread_, JSTaggedValue::Undefined()); @@ -1348,7 +1315,7 @@ JSHandle ObjectFactory::NewAccessorData() JSHandle ObjectFactory::NewInternalAccessor(void *setter, void *getter) { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateNonMovableOrLargeObject(internalAccessorClass_); + TaggedObject *header = heapHelper_.AllocateNonMovableOrHugeObject(internalAccessorClass_); JSHandle obj(thread_, AccessorData::Cast(header)); if (setter != nullptr) { JSHandle setFunc = NewJSNativePointer(setter, true); @@ -1366,7 +1333,7 @@ JSHandle ObjectFactory::NewInternalAccessor(void *setter, void *ge JSHandle ObjectFactory::NewPromiseCapability() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(capabilityRecordClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(capabilityRecordClass_); JSHandle obj(thread_, header); obj->SetPromise(thread_, JSTaggedValue::Undefined()); obj->SetResolve(thread_, JSTaggedValue::Undefined()); @@ -1377,7 +1344,7 @@ JSHandle ObjectFactory::NewPromiseCapability() JSHandle ObjectFactory::NewPromiseReaction() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(reactionsRecordClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(reactionsRecordClass_); JSHandle obj(thread_, header); obj->SetPromiseCapability(thread_, JSTaggedValue::Undefined()); obj->SetHandler(thread_, JSTaggedValue::Undefined()); @@ -1389,7 +1356,7 @@ JSHandle ObjectFactory::NewPromiseIteratorRecord(const JS const JSHandle &done) { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(promiseIteratorRecordClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(promiseIteratorRecordClass_); JSHandle obj(thread_, header); obj->SetIterator(thread_, itor.GetTaggedValue()); obj->SetDone(thread_, done.GetTaggedValue()); @@ -1399,7 +1366,7 @@ JSHandle ObjectFactory::NewPromiseIteratorRecord(const JS JSHandle ObjectFactory::NewMicroJobQueue() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateNonMovableOrLargeObject(microJobQueueClass_); + TaggedObject *header = heapHelper_.AllocateNonMovableOrHugeObject(microJobQueueClass_); JSHandle obj(thread_, header); obj->SetPromiseJobQueue(thread_, GetEmptyTaggedQueue().GetTaggedValue()); obj->SetScriptJobQueue(thread_, GetEmptyTaggedQueue().GetTaggedValue()); @@ -1410,7 +1377,7 @@ JSHandle ObjectFactory::NewPendingJob(const JSHandle &argv) { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(pendingJobClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(pendingJobClass_); JSHandle obj(thread_, header); obj->SetJob(thread_, func.GetTaggedValue()); obj->SetArguments(thread_, argv.GetTaggedValue()); @@ -1421,7 +1388,7 @@ JSHandle ObjectFactory::NewFunctionExtraInfo(const JSHandle const JSHandle &data) { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(functionExtraInfo_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(functionExtraInfo_); JSHandle obj(thread_, header); obj->SetCallback(thread_, callBack.GetTaggedValue()); obj->SetData(thread_, data.GetTaggedValue()); @@ -1434,10 +1401,10 @@ JSHandle ObjectFactory::NewJSProxy(const JSHandle &targe NewObjectHook(); TaggedObject *header = nullptr; if (target->IsCallable()) { - header = target->IsConstructor() ? heapHelper_.AllocateYoungGenerationOrLargeObject(jsProxyConstructClass_) - : heapHelper_.AllocateYoungGenerationOrLargeObject(jsProxyCallableClass_); + header = target->IsConstructor() ? heapHelper_.AllocateYoungGenerationOrHugeObject(jsProxyConstructClass_) + : heapHelper_.AllocateYoungGenerationOrHugeObject(jsProxyCallableClass_); } else { - header = heapHelper_.AllocateYoungGenerationOrLargeObject(jsProxyOrdinaryClass_); + header = heapHelper_.AllocateYoungGenerationOrHugeObject(jsProxyOrdinaryClass_); } JSHandle proxy(thread_, header); @@ -1491,7 +1458,7 @@ JSHandle ObjectFactory::NewEmptyArray() { NewObjectHook(); - auto header = heapHelper_.AllocateNonMovableOrLargeObject(arrayClass_, sizeof(TaggedArray)); + auto header = heapHelper_.AllocateNonMovableOrHugeObject(arrayClass_, sizeof(TaggedArray)); JSHandle array(thread_, header); array->SetLength(0); return array; @@ -1516,13 +1483,13 @@ JSHandle ObjectFactory::NewTaggedArray(array_size_t length, JSTagge TaggedObject *header = nullptr; switch (spaceType) { case MemSpaceType::SEMI_SPACE: - header = heapHelper_.AllocateYoungGenerationOrLargeObject(arrayClass_, size); + header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); break; case MemSpaceType::OLD_SPACE: - header = heapHelper_.AllocateOldGenerationOrLargeObject(arrayClass_, size); + header = heapHelper_.AllocateOldGenerationOrHugeObject(arrayClass_, size); break; case MemSpaceType::NON_MOVABLE: - header = heapHelper_.AllocateNonMovableOrLargeObject(arrayClass_, size); + header = heapHelper_.AllocateNonMovableOrHugeObject(arrayClass_, size); break; default: UNREACHABLE(); @@ -1541,7 +1508,7 @@ JSHandle ObjectFactory::NewTaggedArray(array_size_t length, JSTagge } size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length); - auto header = heapHelper_.AllocateYoungGenerationOrLargeObject(arrayClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); JSHandle array(thread_, header); array->InitializeWithSpecialValue(initVal, length); return array; @@ -1554,7 +1521,7 @@ JSHandle ObjectFactory::NewDictionaryArray(array_size_t length) ASSERT(length > 0); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length); - auto header = heapHelper_.AllocateYoungGenerationOrLargeObject(dictionaryClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(dictionaryClass_, size); JSHandle array(thread_, header); array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length); @@ -1568,7 +1535,7 @@ JSHandle ObjectFactory::ExtendArray(const JSHandle &ol NewObjectHook(); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length); - auto header = heapHelper_.AllocateYoungGenerationOrLargeObject(arrayClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); JSHandle newArray(thread_, header); newArray->SetLength(length); @@ -1598,7 +1565,7 @@ JSHandle ObjectFactory::CopyPartArray(const JSHandle & NewObjectHook(); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength); - auto header = heapHelper_.AllocateYoungGenerationOrLargeObject(arrayClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); JSHandle newArray(thread_, header); newArray->SetLength(newLength); @@ -1625,7 +1592,7 @@ JSHandle ObjectFactory::CopyArray(const JSHandle &old, NewObjectHook(); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength); - auto header = heapHelper_.AllocateYoungGenerationOrLargeObject(arrayClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); JSHandle newArray(thread_, header); newArray->SetLength(newLength); @@ -1682,7 +1649,7 @@ JSHandle ObjectFactory::NewConstantPool(uint32_t capacity) return JSHandle::Cast(EmptyArray()); } size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), capacity); - auto header = heapHelper_.AllocateNonMovableOrLargeObject(arrayClass_, size); + auto header = heapHelper_.AllocateNonMovableOrHugeObject(arrayClass_, size); JSHandle array(thread_, header); array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), capacity); return array; @@ -1691,7 +1658,7 @@ JSHandle ObjectFactory::NewConstantPool(uint32_t capacity) JSHandle ObjectFactory::NewProgram() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(programClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(programClass_); JSHandle p(thread_, header); p->SetLocation(thread_, JSTaggedValue::Undefined()); p->SetConstantPool(thread_, JSTaggedValue::Undefined()); @@ -1703,80 +1670,12 @@ JSHandle ObjectFactory::NewProgram() JSHandle ObjectFactory::NewEmptyEcmaModule() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(ecmaModuleClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(ecmaModuleClass_); JSHandle module(thread_, header); module->SetNameDictionary(thread_, JSTaggedValue::Undefined()); return module; } -JSHandle ObjectFactory::NewFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len) -{ - NewObjectHook(); - return GetStringFromStringTable(utf8Data, utf8Len); -} - -JSHandle ObjectFactory::NewFromString(const CString &data) -{ - NewObjectHook(); - auto utf8Data = reinterpret_cast(data.c_str()); - auto utf8Len = data.length(); - return GetStringFromStringTable(utf8Data, utf8Len); -} - -JSHandle ObjectFactory::NewFromStdString(const std::string &data) -{ - return NewFromUtf8(reinterpret_cast(data.c_str()), data.size()); -} - -JSHandle ObjectFactory::NewFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len) -{ - NewObjectHook(); - return GetStringFromStringTable(utf16Data, utf16Len); -} - -JSHandle ObjectFactory::NewFromString(EcmaString *str) -{ - NewObjectHook(); - return GetStringFromStringTable(str); -} - -JSHandle ObjectFactory::ConcatFromString(const JSHandle &prefix, - const JSHandle &suffix) -{ - NewObjectHook(); - EcmaString *concatString = EcmaString::Concat(prefix, suffix, vm_); - return GetStringFromStringTable(concatString); -} - -JSHandle ObjectFactory::ConcatFromChar(const char *prefix, const char *suffix) -{ - NewObjectHook(); - CString const &concatString = CString(prefix) + CString(suffix); - char const *concatData = concatString.c_str(); - auto utf8Data = reinterpret_cast(concatData); - JSHandle oldString = GetStringFromStringTable(utf8Data, base::utf_helper::Utf8ToUtf16Size(utf8Data)); - return oldString; -} - -JSHandle ObjectFactory::SubString(const JSHandle &src, uint32_t start, uint32_t utf16_length) -{ - NewObjectHook(); - EcmaString *sub_string = EcmaString::FastSubString(src, start, utf16_length, vm_); - return GetStringFromStringTable(sub_string); -} - -JSHandle ObjectFactory::NewFromUtf8Literal(const uint8_t *utf8Data, uint32_t utf8Len) -{ - NewObjectHook(); - return JSHandle(thread_, EcmaString::CreateFromUtf8(utf8Data, utf8Len, vm_)); -} - -JSHandle ObjectFactory::NewFromUtf16Literal(const uint16_t *utf16Data, uint32_t utf16Len) -{ - NewObjectHook(); - return JSHandle(thread_, EcmaString::CreateFromUtf16(utf16Data, utf16Len, vm_)); -} - JSHandle ObjectFactory::GetEmptyString() const { return JSHandle(thread_->GlobalConstants()->GetHandledEmptyString()); @@ -1791,28 +1690,30 @@ JSHandle ObjectFactory::EmptyArray() const JSHandle ObjectFactory::NewObjectWrapper(const JSHandle &value) { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(objectWrapperClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(objectWrapperClass_); ObjectWrapper *obj = ObjectWrapper::Cast(header); obj->SetValue(thread_, value); return JSHandle(thread_, obj); } -JSHandle ObjectFactory::GetStringFromStringTable(const uint8_t *utf8Data, uint32_t utf8Len) const +JSHandle ObjectFactory::GetStringFromStringTable(const uint8_t *utf8Data, uint32_t utf8Len, + bool canBeCompress) const { if (utf8Len == 0) { return GetEmptyString(); } auto stringTable = vm_->GetEcmaStringTable(); - return JSHandle(thread_, stringTable->GetOrInternString(utf8Data, utf8Len)); + return JSHandle(thread_, stringTable->GetOrInternString(utf8Data, utf8Len, canBeCompress)); } -JSHandle ObjectFactory::GetStringFromStringTable(const uint16_t *utf16Data, uint32_t utf16Len) const +JSHandle ObjectFactory::GetStringFromStringTable(const uint16_t *utf16Data, uint32_t utf16Len, + bool canBeCompress) const { if (utf16Len == 0) { return GetEmptyString(); } auto stringTable = vm_->GetEcmaStringTable(); - return JSHandle(thread_, stringTable->GetOrInternString(utf16Data, utf16Len)); + return JSHandle(thread_, stringTable->GetOrInternString(utf16Data, utf16Len, canBeCompress)); } JSHandle ObjectFactory::GetStringFromStringTable(EcmaString *string) const @@ -1833,18 +1734,18 @@ EcmaString *ObjectFactory::GetRawStringFromStringTable(const uint8_t *mutf8Data, } if (utf::IsMUtf8OnlySingleBytes(mutf8Data)) { - return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(mutf8Data, utf16Len)); + return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(mutf8Data, utf16Len, true)); } CVector utf16Data(utf16Len); auto len = utf::ConvertRegionMUtf8ToUtf16(mutf8Data, utf16Data.data(), utf::Mutf8Size(mutf8Data), utf16Len, 0); - return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(utf16Data.data(), len)); + return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(utf16Data.data(), len, false)); } JSHandle ObjectFactory::NewPropertyBox(const JSHandle &value) { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(PropertyBoxClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(PropertyBoxClass_); JSHandle box(thread_, header); box->SetValue(thread_, value); return box; @@ -1853,7 +1754,7 @@ JSHandle ObjectFactory::NewPropertyBox(const JSHandle ObjectFactory::NewProtoChangeMarker() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(protoChangeMarkerClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(protoChangeMarkerClass_); JSHandle marker(thread_, header); marker->SetHasChanged(false); return marker; @@ -1862,7 +1763,7 @@ JSHandle ObjectFactory::NewProtoChangeMarker() JSHandle ObjectFactory::NewProtoChangeDetails() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(protoChangeDetailsClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(protoChangeDetailsClass_); JSHandle protoInfo(thread_, header); protoInfo->SetChangeListener(thread_, JSTaggedValue(0)); protoInfo->SetRegisterIndex(thread_, JSTaggedValue(ProtoChangeDetails::UNREGISTERED)); @@ -1875,7 +1776,7 @@ JSHandle ObjectFactory::NewProfileTypeInfo(uint32_t length) ASSERT(length > 0); size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length); - auto header = heapHelper_.AllocateYoungGenerationOrLargeObject(arrayClass_, size); + auto header = heapHelper_.AllocateYoungGenerationOrHugeObject(arrayClass_, size); JSHandle array(thread_, header); array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length); @@ -1885,7 +1786,7 @@ JSHandle ObjectFactory::NewProfileTypeInfo(uint32_t length) // static void ObjectFactory::NewObjectHook() { -#if !defined(NDEBUG) || defined(FORCE_GC_TEST) +#ifndef NDEBUG if (!isTriggerGc_) { return; } @@ -2027,19 +1928,20 @@ EcmaString *ObjectFactory::InternString(const JSHandle &key) return stringTable->GetOrInternString(str); } -TransitionHandler *ObjectFactory::NewTransitionHandler() +JSHandle ObjectFactory::NewTransitionHandler() { NewObjectHook(); TransitionHandler *handler = - TransitionHandler::Cast(heapHelper_.AllocateYoungGenerationOrLargeObject(transitionHandlerClass_)); - return handler; + TransitionHandler::Cast(heapHelper_.AllocateYoungGenerationOrHugeObject(transitionHandlerClass_)); + return JSHandle(thread_, handler); } -PrototypeHandler *ObjectFactory::NewPrototypeHandler() +JSHandle ObjectFactory::NewPrototypeHandler() { NewObjectHook(); - PrototypeHandler *handler = - PrototypeHandler::Cast(heapHelper_.AllocateYoungGenerationOrLargeObject(prototypeHandlerClass_)); + PrototypeHandler *header = + PrototypeHandler::Cast(heapHelper_.AllocateYoungGenerationOrHugeObject(prototypeHandlerClass_)); + JSHandle handler(thread_, header); handler->SetHandlerInfo(thread_, JSTaggedValue::Undefined()); handler->SetProtoCell(thread_, JSTaggedValue::Undefined()); handler->SetHolder(thread_, JSTaggedValue::Undefined()); @@ -2049,7 +1951,7 @@ PrototypeHandler *ObjectFactory::NewPrototypeHandler() JSHandle ObjectFactory::NewPromiseRecord() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(promiseRecordClass_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(promiseRecordClass_); JSHandle obj(thread_, header); obj->SetValue(thread_, JSTaggedValue::Undefined()); return obj; @@ -2058,7 +1960,7 @@ JSHandle ObjectFactory::NewPromiseRecord() JSHandle ObjectFactory::NewResolvingFunctionsRecord() { NewObjectHook(); - TaggedObject *header = heapHelper_.AllocateYoungGenerationOrLargeObject(promiseResolvingFunctionsRecord_); + TaggedObject *header = heapHelper_.AllocateYoungGenerationOrHugeObject(promiseResolvingFunctionsRecord_); JSHandle obj(thread_, header); obj->SetResolveFunction(thread_, JSTaggedValue::Undefined()); obj->SetRejectFunction(thread_, JSTaggedValue::Undefined()); @@ -2222,4 +2124,118 @@ JSHandle ObjectFactory::NewJSNativeObject(void *externalPointer, vm_->PushToArrayDataList(*pointer); return nativeObject; } + +JSHandle ObjectFactory::NewMachineCodeObject(size_t length, const uint8_t *data) +{ + NewObjectHook(); + TaggedObject *obj = heapHelper_.AllocateMachineCodeSpaceObject(machineCodeClass_, length + sizeof(MachineCode)); + MachineCode *code = MachineCode::Cast(obj); + code->SetInstructionSizeInBytes(thread_, JSTaggedValue(static_cast(length))); + if (data != nullptr) { + code->SetData(data, length); + } + JSHandle codeObj(thread_, code); + return codeObj; +} + +// ----------------------------------- new string ---------------------------------------- +JSHandle ObjectFactory::NewFromString(const CString &data) +{ + NewObjectHook(); + auto utf8Data = reinterpret_cast(data.c_str()); + bool canBeCompress = EcmaString::CanBeCompressed(utf8Data); + return GetStringFromStringTable(utf8Data, data.length(), canBeCompress); +} + +JSHandle ObjectFactory::NewFromCanBeCompressString(const CString &data) +{ + NewObjectHook(); + auto utf8Data = reinterpret_cast(data.c_str()); + ASSERT(EcmaString::CanBeCompressed(utf8Data)); + return GetStringFromStringTable(utf8Data, data.length(), true); +} + +JSHandle ObjectFactory::NewFromStdString(const std::string &data) +{ + NewObjectHook(); + auto utf8Data = reinterpret_cast(data.c_str()); + bool canBeCompress = EcmaString::CanBeCompressed(utf8Data); + return GetStringFromStringTable(utf8Data, data.size(), canBeCompress); +} + +JSHandle ObjectFactory::NewFromStdStringUnCheck(const std::string &data, bool canBeCompress) +{ + NewObjectHook(); + auto utf8Data = reinterpret_cast(data.c_str()); + return GetStringFromStringTable(utf8Data, data.size(), canBeCompress); +} + +JSHandle ObjectFactory::NewFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len) +{ + NewObjectHook(); + bool canBeCompress = EcmaString::CanBeCompressed(utf8Data); + return GetStringFromStringTable(utf8Data, utf8Len, canBeCompress); +} + +JSHandle ObjectFactory::NewFromUtf8UnCheck(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress) +{ + NewObjectHook(); + return GetStringFromStringTable(utf8Data, utf8Len, canBeCompress); +} + +JSHandle ObjectFactory::NewFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len) +{ + NewObjectHook(); + bool canBeCompress = EcmaString::CanBeCompressed(utf16Data, utf16Len); + return GetStringFromStringTable(utf16Data, utf16Len, canBeCompress); +} + +JSHandle ObjectFactory::NewFromUtf16UnCheck(const uint16_t *utf16Data, uint32_t utf16Len, + bool canBeCompress) +{ + NewObjectHook(); + return GetStringFromStringTable(utf16Data, utf16Len, canBeCompress); +} + +JSHandle ObjectFactory::NewFromUtf8Literal(const uint8_t *utf8Data, uint32_t utf8Len) +{ + NewObjectHook(); + bool canBeCompress = EcmaString::CanBeCompressed(utf8Data); + return JSHandle(thread_, EcmaString::CreateFromUtf8(utf8Data, utf8Len, vm_, canBeCompress)); +} + +JSHandle ObjectFactory::NewFromUtf8LiteralUnCheck(const uint8_t *utf8Data, uint32_t utf8Len, + bool canBeCompress) +{ + NewObjectHook(); + return JSHandle(thread_, EcmaString::CreateFromUtf8(utf8Data, utf8Len, vm_, canBeCompress)); +} + +JSHandle ObjectFactory::NewFromUtf16Literal(const uint16_t *utf16Data, uint32_t utf16Len) +{ + NewObjectHook(); + bool canBeCompress = EcmaString::CanBeCompressed(utf16Data, utf16Len); + return JSHandle(thread_, EcmaString::CreateFromUtf16(utf16Data, utf16Len, vm_, canBeCompress)); +} + +JSHandle ObjectFactory::NewFromUtf16LiteralUnCheck(const uint16_t *utf16Data, uint32_t utf16Len, + bool canBeCompress) +{ + NewObjectHook(); + return JSHandle(thread_, EcmaString::CreateFromUtf16(utf16Data, utf16Len, vm_, canBeCompress)); +} + +JSHandle ObjectFactory::NewFromString(EcmaString *str) +{ + NewObjectHook(); + return GetStringFromStringTable(str); +} + +JSHandle ObjectFactory::ConcatFromString(const JSHandle &prefix, + const JSHandle &suffix) +{ + NewObjectHook(); + EcmaString *concatString = EcmaString::Concat(prefix, suffix, vm_); + return GetStringFromStringTable(concatString); +} } // namespace panda::ecmascript diff --git a/ecmascript/object_factory.h b/ecmascript/object_factory.h index 87bef9e1ca926f1583d69b5599a9504415f52812..3c9426247ae017f3f312994e8593b735c62ed278 100644 --- a/ecmascript/object_factory.h +++ b/ecmascript/object_factory.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_OBJECT_FACTORY_H -#define PANDA_RUNTIME_ECMASCRIPT_OBJECT_FACTORY_H +#ifndef ECMASCRIPT_OBJECT_FACTORY_H +#define ECMASCRIPT_OBJECT_FACTORY_H #include "ecmascript/base/error_type.h" #include "ecmascript/ecma_string.h" @@ -24,6 +24,7 @@ #include "ecmascript/js_native_object.h" #include "ecmascript/js_native_pointer.h" #include "ecmascript/js_tagged_value.h" +#include "ecmascript/mem/machine_code.h" #include "ecmascript/mem/ecma_heap_manager.h" #include "ecmascript/mem/region_factory.h" #include "ecmascript/object_wrapper.h" @@ -81,6 +82,7 @@ class ConstantPool; class Program; class EcmaModule; class LayoutInfo; +class JSIntlBoundFunction; class FreeObject; class JSNativePointer; @@ -94,6 +96,7 @@ class PropertyBox; class ProtoChangeMarker; class ProtoChangeDetails; class ProfileTypeInfo; +class MachineCode; enum class PrimitiveType : uint8_t; enum class IterationKind; @@ -117,9 +120,9 @@ public: JSHandle NewJSError(const ErrorType &errorType, const JSHandle &message); - TransitionHandler *NewTransitionHandler(); + JSHandle NewTransitionHandler(); - PrototypeHandler *NewPrototypeHandler(); + JSHandle NewPrototypeHandler(); JSHandle NewEmptyJSObject(); @@ -142,6 +145,8 @@ public: const JSHandle &boundThis, const JSHandle &args); + JSHandle NewJSIntlBoundFunction(const void *nativeFunc = nullptr, int functionLength = 1); + JSHandle NewJSProxyRevocFunction(const JSHandle &proxy, const void *nativeFunc = nullptr); @@ -247,26 +252,6 @@ public: JSHandle CopyAndReSort(const JSHandle &old, int end, int capacity); - JSHandle NewFromString(const CString &data); - - JSHandle NewFromStdString(const std::string &data); - - JSHandle NewFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len); - - JSHandle NewFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len); - - JSHandle NewFromUtf8Literal(const uint8_t *utf8Data, uint32_t utf8Len); - - JSHandle NewFromUtf16Literal(const uint16_t *utf16Data, uint32_t utf16Len); - - JSHandle NewFromString(EcmaString *str); - - JSHandle ConcatFromString(const JSHandle &prefix, const JSHandle &suffix); - - JSHandle ConcatFromChar(const char *prefix, const char *suffix); - - JSHandle SubString(const JSHandle &src, uint32_t start, uint32_t utf16_length); - JSHandle GetEmptyString() const; JSHandle EmptyArray() const; @@ -321,14 +306,14 @@ public: void NewJSRegExpByteCodeData(const JSHandle ®exp, void *buffer, size_t size); - template + template inline void NewJSIntlIcuData(const JSHandle &obj, const S &icu, const DeleteEntryPoint &callback); EcmaString *InternString(const JSHandle &key); inline JSHandle NewJSNativePointer(void *externalPointer, bool nonMovable = false); - inline JSHandle NewJSNativePointer(void *externalPointer, DeleteEntryPoint callBack, void *data, - bool nonMovable = false); + inline JSHandle NewJSNativePointer(void *externalPointer, const DeleteEntryPoint &callBack, + void *data, bool nonMovable = false); JSHandle NewJSObjectByClass(const JSHandle &keys, const JSHandle &values); JSHandle NewJSObjectByClass(const JSHandle &properties, size_t length); @@ -350,11 +335,34 @@ public: const JSHandle &newTarget); uintptr_t NewSpaceBySnapShotAllocator(size_t size); + JSHandle NewMachineCodeObject(size_t length, const uint8_t *data); JSHandle NewJSNativeObject(void *externalPointer); JSHandle NewJSNativeObject(void *externalPointer, DeleteEntryPoint callback, void *data); ~ObjectFactory() = default; + // ----------------------------------- new string ---------------------------------------- + JSHandle NewFromString(const CString &data); + JSHandle NewFromCanBeCompressString(const CString &data); + + JSHandle NewFromStdString(const std::string &data); + JSHandle NewFromStdStringUnCheck(const std::string &data, bool canBeCompress); + + JSHandle NewFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len); + JSHandle NewFromUtf8UnCheck(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress); + + JSHandle NewFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len); + JSHandle NewFromUtf16UnCheck(const uint16_t *utf16Data, uint32_t utf16Len, bool canBeCompress); + + JSHandle NewFromUtf8Literal(const uint8_t *utf8Data, uint32_t utf8Len); + JSHandle NewFromUtf8LiteralUnCheck(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress); + + JSHandle NewFromUtf16Literal(const uint16_t *utf16Data, uint32_t utf16Len); + JSHandle NewFromUtf16LiteralUnCheck(const uint16_t *utf16Data, uint32_t utf16Len, bool canBeCompress); + + JSHandle NewFromString(EcmaString *str); + JSHandle ConcatFromString(const JSHandle &prefix, const JSHandle &suffix); + private: friend class GlobalEnv; friend class GlobalEnvConstants; @@ -363,49 +371,50 @@ private: void InitObjectFields(const TaggedObject *object); - JSThread *thread_{nullptr}; - bool isTriggerGc_{false}; - bool triggerSemiGC_{false}; + JSThread *thread_ {nullptr}; + bool isTriggerGc_ {false}; + bool triggerSemiGC_ {false}; EcmaHeapManager heapHelper_; - JSHClass *hclassClass_{nullptr}; - JSHClass *stringClass_{nullptr}; - JSHClass *arrayClass_{nullptr}; - JSHClass *dictionaryClass_{nullptr}; - JSHClass *freeObjectWithNoneFieldClass_{nullptr}; - JSHClass *freeObjectWithOneFieldClass_{nullptr}; - JSHClass *freeObjectWithTwoFieldClass_{nullptr}; - - JSHClass *completionRecordClass_{nullptr}; - JSHClass *generatorContextClass_{nullptr}; - JSHClass *envClass_{nullptr}; - JSHClass *symbolClass_{nullptr}; - JSHClass *accessorDataClass_{nullptr}; - JSHClass *internalAccessorClass_{nullptr}; - JSHClass *capabilityRecordClass_{nullptr}; - JSHClass *reactionsRecordClass_{nullptr}; - JSHClass *promiseIteratorRecordClass_{nullptr}; - JSHClass *microJobQueueClass_{nullptr}; - JSHClass *pendingJobClass_{nullptr}; - JSHClass *jsProxyOrdinaryClass_{nullptr}; - JSHClass *jsProxyCallableClass_{nullptr}; - JSHClass *jsProxyConstructClass_{nullptr}; - JSHClass *objectWrapperClass_{nullptr}; - JSHClass *PropertyBoxClass_{nullptr}; - JSHClass *protoChangeDetailsClass_{nullptr}; - JSHClass *protoChangeMarkerClass_{nullptr}; - JSHClass *promiseRecordClass_{nullptr}; - JSHClass *promiseResolvingFunctionsRecord_{nullptr}; - JSHClass *jsNativePointerClass_{nullptr}; - JSHClass *transitionHandlerClass_{nullptr}; - JSHClass *prototypeHandlerClass_{nullptr}; - JSHClass *functionExtraInfo_{nullptr}; - JSHClass *jsRealmClass_{nullptr}; - JSHClass *programClass_{nullptr}; - JSHClass *ecmaModuleClass_{nullptr}; - - EcmaVM *vm_{nullptr}; - Heap *heap_{nullptr}; + JSHClass *hclassClass_ {nullptr}; + JSHClass *stringClass_ {nullptr}; + JSHClass *arrayClass_ {nullptr}; + JSHClass *dictionaryClass_ {nullptr}; + JSHClass *freeObjectWithNoneFieldClass_ {nullptr}; + JSHClass *freeObjectWithOneFieldClass_ {nullptr}; + JSHClass *freeObjectWithTwoFieldClass_ {nullptr}; + + JSHClass *completionRecordClass_ {nullptr}; + JSHClass *generatorContextClass_ {nullptr}; + JSHClass *envClass_ {nullptr}; + JSHClass *symbolClass_ {nullptr}; + JSHClass *accessorDataClass_ {nullptr}; + JSHClass *internalAccessorClass_ {nullptr}; + JSHClass *capabilityRecordClass_ {nullptr}; + JSHClass *reactionsRecordClass_ {nullptr}; + JSHClass *promiseIteratorRecordClass_ {nullptr}; + JSHClass *microJobQueueClass_ {nullptr}; + JSHClass *pendingJobClass_ {nullptr}; + JSHClass *jsProxyOrdinaryClass_ {nullptr}; + JSHClass *jsProxyCallableClass_ {nullptr}; + JSHClass *jsProxyConstructClass_ {nullptr}; + JSHClass *objectWrapperClass_ {nullptr}; + JSHClass *PropertyBoxClass_ {nullptr}; + JSHClass *protoChangeDetailsClass_ {nullptr}; + JSHClass *protoChangeMarkerClass_ {nullptr}; + JSHClass *promiseRecordClass_ {nullptr}; + JSHClass *promiseResolvingFunctionsRecord_ {nullptr}; + JSHClass *jsNativePointerClass_ {nullptr}; + JSHClass *transitionHandlerClass_ {nullptr}; + JSHClass *prototypeHandlerClass_ {nullptr}; + JSHClass *functionExtraInfo_ {nullptr}; + JSHClass *jsRealmClass_ {nullptr}; + JSHClass *programClass_ {nullptr}; + JSHClass *machineCodeClass_ {nullptr}; + JSHClass *ecmaModuleClass_ {nullptr}; + + EcmaVM *vm_ {nullptr}; + Heap *heap_ {nullptr}; NO_COPY_SEMANTIC(ObjectFactory); NO_MOVE_SEMANTIC(ObjectFactory); @@ -436,11 +445,12 @@ private: JSHandle NewJSPrimitiveRef(const JSHandle &dynKlass, const JSHandle &object); - JSHandle GetStringFromStringTable(const uint8_t *utf8Data, uint32_t utf8Len) const; + JSHandle GetStringFromStringTable(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress) const; // For MUtf-8 string data EcmaString *GetRawStringFromStringTable(const uint8_t *mutf8Data, uint32_t utf16Len) const; - JSHandle GetStringFromStringTable(const uint16_t *utf16Data, uint32_t utf16Len) const; + JSHandle GetStringFromStringTable(const uint16_t *utf16Data, uint32_t utf16Len, + bool canBeCompress) const; JSHandle GetStringFromStringTable(EcmaString *string) const; @@ -452,10 +462,10 @@ private: JSHandle CreateJSArrayInstanceClass(JSHandle proto); JSHandle CreateJSRegExpInstanceClass(JSHandle proto); - friend class Builtins; // create builtins object need dynclass - friend class JSFunction; // create prototype_or_dynclass need dynclass - friend class JSHClass; // HC transition need dynclass - friend class EcmaVM; // hold the factory instance + friend class Builtins; // create builtins object need dynclass + friend class JSFunction; // create prototype_or_dynclass need dynclass + friend class JSHClass; // HC transition need dynclass + friend class EcmaVM; // hold the factory instance friend class JsVerificationTest; friend class PandaFileTranslator; friend class LiteralDataExtractor; @@ -463,8 +473,8 @@ private: class ClassLinkerFactory { private: - friend class GlobalEnv; // root class in class_linker need dynclass - friend class EcmaVM; // root class in class_linker need dynclass + friend class GlobalEnv; // root class in class_linker need dynclass + friend class EcmaVM; // root class in class_linker need dynclass }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_OBJECT_FACTORY_H +#endif // ECMASCRIPT_OBJECT_FACTORY_H diff --git a/ecmascript/object_operator.h b/ecmascript/object_operator.h index 9dbffc0c68bae964c0b4e177401c13d5fd580de0..0ca931ffbab69dabae014a2d4b5cf8d3bb55756f 100644 --- a/ecmascript/object_operator.h +++ b/ecmascript/object_operator.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_OBJECT_OPERATOR_H -#define PANDA_RUNTIME_ECMASCRIPT_OBJECT_OPERATOR_H +#ifndef ECMASCRIPT_OBJECT_OPERATOR_H +#define ECMASCRIPT_OBJECT_OPERATOR_H #include "ecmascript/js_handle.h" #include "ecmascript/js_object.h" @@ -304,4 +304,4 @@ private: uint32_t metaData_{0}; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_OBJECT_OPERATOR_H +#endif // ECMASCRIPT_OBJECT_OPERATOR_H diff --git a/ecmascript/object_wrapper.h b/ecmascript/object_wrapper.h index 8cba82605bee52c13889b59210d1cf780662defa..359be165e130ff53711a604b971d18b29ab28d94 100644 --- a/ecmascript/object_wrapper.h +++ b/ecmascript/object_wrapper.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_WRAPPER_OBJECT_H -#define PANDA_RUNTIME_ECMASCRIPT_WRAPPER_OBJECT_H +#ifndef ECMASCRIPT_WRAPPER_OBJECT_H +#define ECMASCRIPT_WRAPPER_OBJECT_H #include "ecmascript/ecma_macros.h" #include "ecmascript/js_tagged_value.h" @@ -28,10 +28,10 @@ public: return static_cast(object); } - static constexpr size_t VALUE_OFFSET = ObjectHeaderSize(); + static constexpr size_t VALUE_OFFSET = TaggedObjectSize(); ACCESSORS(Value, VALUE_OFFSET, SIZE) DECL_VISIT_OBJECT(VALUE_OFFSET, SIZE) }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_WRAPPER_OBJECT_H \ No newline at end of file +#endif // ECMASCRIPT_WRAPPER_OBJECT_H \ No newline at end of file diff --git a/ecmascript/property_attributes.h b/ecmascript/property_attributes.h index 0dae6320a7fc42c3d7c12d78d23548544ecb8b2a..b7d07eb1b2dfa91bdcea9f2318800722a0722d4b 100644 --- a/ecmascript/property_attributes.h +++ b/ecmascript/property_attributes.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_PROPERTY_ATTRIBUTES_H -#define PANDA_RUNTIME_ECMASCRIPT_PROPERTY_ATTRIBUTES_H +#ifndef ECMASCRIPT_PROPERTY_ATTRIBUTES_H +#define ECMASCRIPT_PROPERTY_ATTRIBUTES_H #include "ecmascript/js_tagged_value.h" #include "utils/bit_field.h" @@ -297,4 +297,4 @@ private: uint32_t value_{0}; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_PROPERTY_ATTRIBUTES_H +#endif // ECMASCRIPT_PROPERTY_ATTRIBUTES_H diff --git a/ecmascript/record.h b/ecmascript/record.h index e2defb0d51b6fbec3b35b936b4c4572f11235a37..47247cfaaf9169e37b2d91a8f88529858647b798 100644 --- a/ecmascript/record.h +++ b/ecmascript/record.h @@ -13,15 +13,15 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_RECORD_H -#define PANDA_RUNTIME_ECMASCRIPT_RECORD_H +#ifndef ECMASCRIPT_RECORD_H +#define ECMASCRIPT_RECORD_H #include "ecmascript/mem/tagged_object.h" namespace panda::ecmascript { class Record : public TaggedObject { public: - static constexpr size_t SIZE = sizeof(TaggedObject); + static constexpr size_t SIZE = TaggedObjectSize(); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_RECORD_H \ No newline at end of file +#endif // ECMASCRIPT_RECORD_H \ No newline at end of file diff --git a/ecmascript/regexp/dyn_chunk.h b/ecmascript/regexp/dyn_chunk.h index e0d43c56ba02a08cb50a2c366a3ba681aa98ba94..e85b7054a6c5dc2fccac5734dd34338ee71af9c2 100644 --- a/ecmascript/regexp/dyn_chunk.h +++ b/ecmascript/regexp/dyn_chunk.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_DYN_BUFFER_H -#define PANDA_RUNTIME_ECMASCRIPT_DYN_BUFFER_H +#ifndef ECMASCRIPT_REGEXP_DYN_BUFFER_H +#define ECMASCRIPT_REGEXP_DYN_BUFFER_H #include #include "ecmascript/ecma_vm.h" @@ -146,4 +146,4 @@ private: Chunk *chunk_ {nullptr}; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_DYN_BUFFER_H +#endif // ECMASCRIPT_REGEXP_DYN_BUFFER_H diff --git a/ecmascript/regexp/regexp_executor.cpp b/ecmascript/regexp/regexp_executor.cpp index 930b72f455e8773f4e878b21a17ecd06499a072f..b5ef4bc715f40f3ef27b916242b131544ca1f1bb 100644 --- a/ecmascript/regexp/regexp_executor.cpp +++ b/ecmascript/regexp/regexp_executor.cpp @@ -591,8 +591,7 @@ void RegExpExecutor::DumpResult(std::ostream &out) const CaptureState *captureState = &captureResultList_[i]; int32_t len = captureState->captureEnd - captureState->captureStart; if ((captureState->captureStart != nullptr && captureState->captureEnd != nullptr) && (len >= 0)) { - out << i << ":\t" << CString(reinterpret_cast(captureState->captureStart), len) - << std::endl; + out << i << ":\t" << CString(reinterpret_cast(captureState->captureStart), len) << std::endl; } else { out << i << ":\t" << "undefined" << std::endl; @@ -622,8 +621,8 @@ MatchResult RegExpExecutor::GetResult(const JSThread *thread, bool isSuccess) co pair.first = false; if (isWideChar_) { // create utf-16 string - pair.second = - factory->NewFromUtf16(reinterpret_cast(captureState->captureStart), len / 2); + pair.second = factory->NewFromUtf16UnCheck( + reinterpret_cast(captureState->captureStart), len / 2, false); } else { // create utf-8 string CVector buffer(len + 1); @@ -634,7 +633,8 @@ MatchResult RegExpExecutor::GetResult(const JSThread *thread, bool isSuccess) co UNREACHABLE(); } dest[len] = '\0'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) - pair.second = factory->NewFromUtf8(reinterpret_cast(buffer.data()), len); + pair.second = + factory->NewFromUtf8UnCheck(reinterpret_cast(buffer.data()), len, true); } } else { // undefined diff --git a/ecmascript/regexp/regexp_executor.h b/ecmascript/regexp/regexp_executor.h index 5eca696139092774affa2634d9c8617a5c992ec3..a62f3b9e8f601edde0ee83fb1dbfe3e739bc0dc4 100644 --- a/ecmascript/regexp/regexp_executor.h +++ b/ecmascript/regexp/regexp_executor.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_REGEXP_EXECUTOR_H -#define PANDA_RUNTIME_ECMASCRIPT_REGEXP_EXECUTOR_H +#ifndef ECMASCRIPT_REGEXP_REGEXP_EXECUTOR_H +#define ECMASCRIPT_REGEXP_REGEXP_EXECUTOR_H #include "ecmascript/regexp/regexp_parser.h" #include "ecmascript/mem/chunk.h" @@ -367,4 +367,4 @@ private: Chunk *chunk_ = nullptr; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_REGEXP_EXECUTOR_H +#endif // ECMASCRIPT_REGEXP_REGEXP_EXECUTOR_H diff --git a/ecmascript/regexp/regexp_opcode.h b/ecmascript/regexp/regexp_opcode.h index efe4cf9a8dea5af4abf28bf854859418278145d2..b91743f97d8ad98bd6c87e4ca34784229aa819e5 100644 --- a/ecmascript/regexp/regexp_opcode.h +++ b/ecmascript/regexp/regexp_opcode.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMA_REGEXP_OPCODE_H -#define PANDA_RUNTIME_ECMA_REGEXP_OPCODE_H +#ifndef ECMASCRIPT_REGEXP_OPCODE_H +#define ECMASCRIPT_REGEXP_OPCODE_H #include diff --git a/ecmascript/regexp/regexp_parser.h b/ecmascript/regexp/regexp_parser.h index 751f9f716bb6689c9b3bf31a97ab733812b0afb8..3d2ded8b34664913adb2b669877b77b67ab2e564 100644 --- a/ecmascript/regexp/regexp_parser.h +++ b/ecmascript/regexp/regexp_parser.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMA_REGEXP_PARSER_H -#define PANDA_RUNTIME_ECMA_REGEXP_PARSER_H +#ifndef ECMASCRIPT_REGEXP_PARSER_H +#define ECMASCRIPT_REGEXP_PARSER_H #include #include @@ -230,4 +230,4 @@ private: DynChunk groupNames_; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMA_REGEXP_PARSER_H \ No newline at end of file +#endif // ECMASCRIPT_REGEXP_PARSER_H \ No newline at end of file diff --git a/ecmascript/regexp/regexp_parser_cache.h b/ecmascript/regexp/regexp_parser_cache.h index e9cbf0cdbe9cd0d5c14e861205c7da12ed165c0b..24490c55fedd70660ea52f8e1d26babb49ce99aa 100644 --- a/ecmascript/regexp/regexp_parser_cache.h +++ b/ecmascript/regexp/regexp_parser_cache.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMA_REGEXP_PARSER_CACHE_H -#define PANDA_RUNTIME_ECMA_REGEXP_PARSER_CACHE_H +#ifndef ECMASCRIPT_REGEXP_PARSER_CACHE_H +#define ECMASCRIPT_REGEXP_PARSER_CACHE_H #include @@ -46,4 +46,4 @@ private: std::array info_{}; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMA_REGEXP_PARSER_CACHE_H +#endif // ECMASCRIPT_REGEXP_PARSER_CACHE_H diff --git a/ecmascript/regexp/tests/regexp_test.cpp b/ecmascript/regexp/tests/regexp_test.cpp index 299442c30ba20893754b0bb2fda8b9406722b167..013b96019d6134127cb76951fccfee40f7fe185c 100644 --- a/ecmascript/regexp/tests/regexp_test.cpp +++ b/ecmascript/regexp/tests/regexp_test.cpp @@ -622,7 +622,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec1) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("ab"); + JSHandle str = factory->NewFromCanBeCompressString("ab"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -644,7 +644,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec2) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 10); - JSHandle str = factory->NewFromString("ab"); + JSHandle str = factory->NewFromCanBeCompressString("ab"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str) == 0); ASSERT_TRUE(result.captures_[2].second->Compare(*str) == 0); @@ -675,8 +675,8 @@ HWTEST_F_L0(RegExpTest, ParseAndExec3) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 2); - JSHandle str1 = factory->NewFromString("aaba"); - JSHandle str2 = factory->NewFromString("ba"); + JSHandle str1 = factory->NewFromCanBeCompressString("aaba"); + JSHandle str2 = factory->NewFromCanBeCompressString("ba"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); } @@ -699,7 +699,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec4) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("aa"); + JSHandle str = factory->NewFromCanBeCompressString("aa"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -721,7 +721,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec5) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString(""); + JSHandle str = factory->NewFromCanBeCompressString(""); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -743,11 +743,11 @@ HWTEST_F_L0(RegExpTest, ParseAndExec6) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 6); - JSHandle str1 = factory->NewFromString("zaacbbbcac"); - JSHandle str2 = factory->NewFromString("z"); - JSHandle str3 = factory->NewFromString("ac"); - JSHandle str4 = factory->NewFromString("a"); - JSHandle str5 = factory->NewFromString("c"); + JSHandle str1 = factory->NewFromCanBeCompressString("zaacbbbcac"); + JSHandle str2 = factory->NewFromCanBeCompressString("z"); + JSHandle str3 = factory->NewFromCanBeCompressString("ac"); + JSHandle str4 = factory->NewFromCanBeCompressString("a"); + JSHandle str5 = factory->NewFromCanBeCompressString("c"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); ASSERT_TRUE(result.captures_[2].second->Compare(*str3) == 0); @@ -774,7 +774,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec7) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("abc"); + JSHandle str = factory->NewFromCanBeCompressString("abc"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -796,7 +796,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec8) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("abc"); + JSHandle str = factory->NewFromCanBeCompressString("abc"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -818,7 +818,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec9) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("er"); + JSHandle str = factory->NewFromCanBeCompressString("er"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -840,7 +840,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec10) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("d"); + JSHandle str = factory->NewFromCanBeCompressString("d"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -862,7 +862,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec11) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("a"); + JSHandle str = factory->NewFromCanBeCompressString("a"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -884,7 +884,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec12) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("\n"); + JSHandle str = factory->NewFromCanBeCompressString("\n"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -906,7 +906,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec13) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("abc"); + JSHandle str = factory->NewFromCanBeCompressString("abc"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -928,7 +928,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec14) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("abc"); + JSHandle str = factory->NewFromCanBeCompressString("abc"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -950,7 +950,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec15) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("a"); + JSHandle str = factory->NewFromCanBeCompressString("a"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -972,7 +972,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec16) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("ABC"); + JSHandle str = factory->NewFromCanBeCompressString("ABC"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -994,7 +994,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec17) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("a\n"); + JSHandle str = factory->NewFromCanBeCompressString("a\n"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1032,7 +1032,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec19) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("a"); + JSHandle str = factory->NewFromCanBeCompressString("a"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1054,8 +1054,8 @@ HWTEST_F_L0(RegExpTest, ParseAndExec20) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 2); - JSHandle str1 = factory->NewFromString(""); - JSHandle str2 = factory->NewFromString("aaa"); + JSHandle str1 = factory->NewFromCanBeCompressString(""); + JSHandle str2 = factory->NewFromCanBeCompressString("aaa"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); } @@ -1078,7 +1078,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec21) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("a"); + JSHandle str = factory->NewFromCanBeCompressString("a"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1100,7 +1100,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec22) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("aaaa:"); + JSHandle str = factory->NewFromCanBeCompressString("aaaa:"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1122,7 +1122,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec23) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("a"); + JSHandle str = factory->NewFromCanBeCompressString("a"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1160,8 +1160,8 @@ HWTEST_F_L0(RegExpTest, ParseAndExec25) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 2); - JSHandle str1 = factory->NewFromString(""); - JSHandle str2 = factory->NewFromString("ab"); + JSHandle str1 = factory->NewFromCanBeCompressString(""); + JSHandle str2 = factory->NewFromCanBeCompressString("ab"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); } @@ -1184,7 +1184,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec26) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("A"); + JSHandle str = factory->NewFromCanBeCompressString("A"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1206,7 +1206,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec27) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("Z"); + JSHandle str = factory->NewFromCanBeCompressString("Z"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1228,7 +1228,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec28) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("\n"); + JSHandle str = factory->NewFromCanBeCompressString("\n"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1250,7 +1250,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec29) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 2); - JSHandle str = factory->NewFromString(""); + JSHandle str = factory->NewFromCanBeCompressString(""); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str) == 0); } @@ -1273,7 +1273,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec30) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 2); - JSHandle str = factory->NewFromString(""); + JSHandle str = factory->NewFromCanBeCompressString(""); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); ASSERT_TRUE(result.captures_[1].first); } @@ -1294,8 +1294,8 @@ HWTEST_F_L0(RegExpTest, ParseAndExec31) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 2); - JSHandle str1 = factory->NewFromString("abb"); - JSHandle str2 = factory->NewFromString("b"); + JSHandle str1 = factory->NewFromCanBeCompressString("abb"); + JSHandle str2 = factory->NewFromCanBeCompressString("b"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); } @@ -1316,9 +1316,9 @@ HWTEST_F_L0(RegExpTest, ParseAndExec32) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 3); - JSHandle str1 = factory->NewFromString("abb"); - JSHandle str2 = factory->NewFromString("ab"); - JSHandle str3 = factory->NewFromString("b"); + JSHandle str1 = factory->NewFromCanBeCompressString("abb"); + JSHandle str2 = factory->NewFromCanBeCompressString("ab"); + JSHandle str3 = factory->NewFromCanBeCompressString("b"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); ASSERT_TRUE(result.captures_[2].second->Compare(*str3) == 0); @@ -1340,7 +1340,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec33) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("qya"); + JSHandle str = factory->NewFromCanBeCompressString("qya"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1360,7 +1360,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec34) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("qy"); + JSHandle str = factory->NewFromCanBeCompressString("qy"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1380,10 +1380,10 @@ HWTEST_F_L0(RegExpTest, ParseAndExec35) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 4); - JSHandle str1 = factory->NewFromString("2021-01-09"); - JSHandle str2 = factory->NewFromString("2021"); - JSHandle str3 = factory->NewFromString("01"); - JSHandle str4 = factory->NewFromString("09"); + JSHandle str1 = factory->NewFromCanBeCompressString("2021-01-09"); + JSHandle str2 = factory->NewFromCanBeCompressString("2021"); + JSHandle str3 = factory->NewFromCanBeCompressString("01"); + JSHandle str4 = factory->NewFromCanBeCompressString("09"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); ASSERT_TRUE(result.captures_[2].second->Compare(*str3) == 0); @@ -1406,9 +1406,9 @@ HWTEST_F_L0(RegExpTest, ParseAndExec36) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 3); - JSHandle str1 = factory->NewFromString("Quick Brown Fox Jumps"); - JSHandle str2 = factory->NewFromString("Brown"); - JSHandle str3 = factory->NewFromString("Jumps"); + JSHandle str1 = factory->NewFromCanBeCompressString("Quick Brown Fox Jumps"); + JSHandle str2 = factory->NewFromCanBeCompressString("Brown"); + JSHandle str3 = factory->NewFromCanBeCompressString("Jumps"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); ASSERT_TRUE(result.captures_[2].second->Compare(*str3) == 0); @@ -1430,8 +1430,8 @@ HWTEST_F_L0(RegExpTest, ParseAndExec37) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 2); - JSHandle str1 = factory->NewFromString("abABc"); - JSHandle str2 = factory->NewFromString("AB"); + JSHandle str1 = factory->NewFromCanBeCompressString("abABc"); + JSHandle str2 = factory->NewFromCanBeCompressString("AB"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); } @@ -1452,9 +1452,9 @@ HWTEST_F_L0(RegExpTest, ParseAndExec38) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 3); - JSHandle str1 = factory->NewFromString("www.netscape.com"); - JSHandle str2 = factory->NewFromString("netscape."); - JSHandle str3 = factory->NewFromString("netscap"); + JSHandle str1 = factory->NewFromCanBeCompressString("www.netscape.com"); + JSHandle str2 = factory->NewFromCanBeCompressString("netscape."); + JSHandle str3 = factory->NewFromCanBeCompressString("netscap"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); ASSERT_TRUE(result.captures_[2].second->Compare(*str3) == 0); @@ -1476,8 +1476,8 @@ HWTEST_F_L0(RegExpTest, ParseAndExec39) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 2); - JSHandle str1 = factory->NewFromString("b"); - JSHandle str2 = factory->NewFromString(""); + JSHandle str1 = factory->NewFromCanBeCompressString("b"); + JSHandle str2 = factory->NewFromCanBeCompressString(""); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); } @@ -1498,7 +1498,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec40) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString(""); + JSHandle str = factory->NewFromCanBeCompressString(""); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1518,9 +1518,9 @@ HWTEST_F_L0(RegExpTest, ParseAndExec41) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 4); - JSHandle str1 = factory->NewFromString("baaabaac"); - JSHandle str2 = factory->NewFromString("ba"); - JSHandle str3 = factory->NewFromString("abaac"); + JSHandle str1 = factory->NewFromCanBeCompressString("baaabaac"); + JSHandle str2 = factory->NewFromCanBeCompressString("ba"); + JSHandle str3 = factory->NewFromCanBeCompressString("abaac"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); ASSERT_TRUE(result.captures_[2].first); @@ -1543,7 +1543,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec42) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("abc324234"); + JSHandle str = factory->NewFromCanBeCompressString("abc324234"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1563,7 +1563,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec43) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("1\nl"); + JSHandle str = factory->NewFromCanBeCompressString("1\nl"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1583,7 +1583,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec44) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("c\bd"); + JSHandle str = factory->NewFromCanBeCompressString("c\bd"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1603,7 +1603,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec45) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("easy"); + JSHandle str = factory->NewFromCanBeCompressString("easy"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1623,8 +1623,8 @@ HWTEST_F_L0(RegExpTest, ParseAndExec46) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 3); - JSHandle str1 = factory->NewFromString("Course_Creator = Test"); - JSHandle str2 = factory->NewFromString("Course_Creator"); + JSHandle str1 = factory->NewFromCanBeCompressString("Course_Creator = Test"); + JSHandle str2 = factory->NewFromCanBeCompressString("Course_Creator"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_FALSE(result.captures_[1].first); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); @@ -1647,7 +1647,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec47) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("et"); + JSHandle str = factory->NewFromCanBeCompressString("et"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1667,11 +1667,11 @@ HWTEST_F_L0(RegExpTest, ParseAndExec49) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 5); - JSHandle str1 = factory->NewFromString("ab55"); - JSHandle str2 = factory->NewFromString("ab55"); - JSHandle str3 = factory->NewFromString("b"); - JSHandle str4 = factory->NewFromString("5"); - JSHandle str5 = factory->NewFromString("5"); + JSHandle str1 = factory->NewFromCanBeCompressString("ab55"); + JSHandle str2 = factory->NewFromCanBeCompressString("ab55"); + JSHandle str3 = factory->NewFromCanBeCompressString("b"); + JSHandle str4 = factory->NewFromCanBeCompressString("5"); + JSHandle str5 = factory->NewFromCanBeCompressString("5"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); ASSERT_TRUE(result.captures_[2].second->Compare(*str3) == 0); @@ -1695,10 +1695,10 @@ HWTEST_F_L0(RegExpTest, ParseAndExec50) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 4); - JSHandle str1 = factory->NewFromString("2020-12-31"); - JSHandle str2 = factory->NewFromString("2020"); - JSHandle str3 = factory->NewFromString("12-31"); - JSHandle str4 = factory->NewFromString("31"); + JSHandle str1 = factory->NewFromCanBeCompressString("2020-12-31"); + JSHandle str2 = factory->NewFromCanBeCompressString("2020"); + JSHandle str3 = factory->NewFromCanBeCompressString("12-31"); + JSHandle str4 = factory->NewFromCanBeCompressString("31"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); ASSERT_TRUE(result.captures_[2].second->Compare(*str3) == 0); @@ -1738,8 +1738,8 @@ HWTEST_F_L0(RegExpTest, ParseAndExec52) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 2); - JSHandle str1 = factory->NewFromString("aabcdaa"); - JSHandle str2 = factory->NewFromString("aa"); + JSHandle str1 = factory->NewFromCanBeCompressString("aabcdaa"); + JSHandle str2 = factory->NewFromCanBeCompressString("aa"); ASSERT_TRUE(result.captures_[0].second->Compare(*str1) == 0); ASSERT_TRUE(result.captures_[1].second->Compare(*str2) == 0); } @@ -1760,7 +1760,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec53) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("\u0001"); + JSHandle str = factory->NewFromCanBeCompressString("\u0001"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1795,7 +1795,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec55) ASSERT_TRUE(ret); MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("e"); + JSHandle str = factory->NewFromCanBeCompressString("e"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1849,7 +1849,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec58) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); char16_t data1[] = {0xdf06}; - JSHandle str = factory->NewFromUtf16(reinterpret_cast(data1), 1); + JSHandle str = factory->NewFromUtf16UnCheck(reinterpret_cast(data1), 1, true); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } @@ -1871,7 +1871,7 @@ HWTEST_F_L0(RegExpTest, ParseAndExec59) MatchResult result = executor.GetResult(thread, ret); ASSERT_EQ(result.captures_.size(), 1); - JSHandle str = factory->NewFromString("\u000B"); + JSHandle str = factory->NewFromCanBeCompressString("\u000B"); ASSERT_TRUE(result.captures_[0].second->Compare(*str) == 0); } diff --git a/ecmascript/runtime_call_id.h b/ecmascript/runtime_call_id.h index 6032ebc626ed9c47747ec1881cc81fe95243ceb5..7dbd98352fe4d73e238277dcca0cc23f3bcb2c15 100644 --- a/ecmascript/runtime_call_id.h +++ b/ecmascript/runtime_call_id.h @@ -13,8 +13,10 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMA_RUNTIME_CALL_ID_H -#define PANDA_RUNTIME_ECMA_RUNTIME_CALL_ID_H +#ifndef ECMASCRIPT_RUNTIME_CALL_ID_H +#define ECMASCRIPT_RUNTIME_CALL_ID_H + +#include "ecmascript/base/config.h" namespace panda::ecmascript { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -123,6 +125,16 @@ namespace panda::ecmascript { V(CloseIterator) \ V(StArraySpread) \ V(GetCallSpreadArgs) \ + V(TryLoadICByName) \ + V(LoadICByName) \ + V(GetPropertyByName) \ + V(TryLoadICByValue) \ + V(LoadICByValue) \ + V(TryStoreICByName) \ + V(StoreICByName) \ + V(TryStoreICByValue) \ + V(StoreICByValue) \ + V(NotifyInlineCache) \ V(GetIteratorNext) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -435,7 +447,7 @@ enum EcmaRuntimeCallerId { RUNTIME_CALLER_NUMBER, }; -#ifdef PANDA_ECMASCRIPT_ENABLE_RUNTIME_STAT +#if ECMASCRIPT_ENABLE_RUNTIME_STAT // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define INTERPRETER_TRACE(thread, name) \ [[maybe_unused]] JSThread *_js_thread_ = thread; \ @@ -458,6 +470,6 @@ enum EcmaRuntimeCallerId { #define INTERPRETER_TRACE(thread, name) static_cast(0) // NOLINT(cppcoreguidelines-macro-usage) #define BUILTINS_API_TRACE(thread, class, name) static_cast(0) // NOLINT(cppcoreguidelines-macro-usage) #define ABSTRACT_OPERATION_TRACE(thread, class, name) static_cast(0) // NOLINT(cppcoreguidelines-macro-usage) -#endif // PANDA_ECMASCRIPT_ENABLE_RUNTIME_STAT +#endif // ECMASCRIPT_ENABLE_RUNTIME_STAT } // namespace panda::ecmascript #endif diff --git a/ecmascript/runtime_trampolines.cpp b/ecmascript/runtime_trampolines.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1df5a198186c68b9a6e5f7a2ce098d74a0067d78 --- /dev/null +++ b/ecmascript/runtime_trampolines.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "runtime_trampolines.h" +#include "ecmascript/accessor_data.h" +#include "ecmascript/ecma_macros.h" +#include "ecmascript/js_object.h" +#include "ecmascript/js_proxy.h" +#include "ecmascript/message_string.h" +#include "ecmascript/object_factory.h" + +namespace panda::ecmascript { +bool RuntimeTrampolines::AddElementInternal(uint64_t argThread, uint64_t argReceiver, uint32_t argIndex, + uint64_t argValue, uint32_t argAttr) +{ + auto thread = reinterpret_cast(argThread); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + JSHandle receiver(thread, reinterpret_cast(argReceiver)); + JSHandle value(thread, JSTaggedValue(reinterpret_cast(argValue))); + auto attr = static_cast(argAttr); + return JSObject::AddElementInternal(thread, receiver, argIndex, value, attr); +} + +bool RuntimeTrampolines::CallSetter(uint64_t argThread, uint64_t argSetter, uint64_t argReceiver, + uint64_t argValue, bool argMayThrow) +{ + auto thread = reinterpret_cast(argThread); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + JSHandle receiver(thread, JSTaggedValue(reinterpret_cast(argReceiver))); + JSHandle value(thread, JSTaggedValue(reinterpret_cast(argValue))); + auto setter = AccessorData::Cast((reinterpret_cast(argSetter))); + return JSObject::CallSetter(thread, *setter, receiver, value, argMayThrow); +} + +void RuntimeTrampolines::ThrowTypeError(uint64_t argThread, int argMessageStringId) +{ + auto thread = reinterpret_cast(argThread); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + std::string message = MessageString::GetMessageString(argMessageStringId); + ObjectFactory *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory(); + JSHandle error = factory->GetJSError(ErrorType::TYPE_ERROR, message.c_str()); + THROW_NEW_ERROR_AND_RETURN(thread, error.GetTaggedValue()); +} + +bool RuntimeTrampolines::JSProxySetProperty(uint64_t argThread, uint64_t argProxy, uint64_t argKey, + uint64_t argValue, uint64_t argReceiver, bool argMayThrow) +{ + auto thread = reinterpret_cast(argThread); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + JSHandle proxy(thread, JSTaggedValue(reinterpret_cast(argProxy))); + JSHandle index(thread, JSTaggedValue(reinterpret_cast(argKey))); + JSHandle value(thread, JSTaggedValue(reinterpret_cast(argValue))); + JSHandle receiver(thread, JSTaggedValue(reinterpret_cast(argReceiver))); + + return JSProxy::SetProperty(thread, proxy, index, value, receiver, argMayThrow); +} + +uint32_t RuntimeTrampolines::GetHash32(uint64_t key, uint64_t len) +{ + auto pkey = reinterpret_cast(key); + return panda::GetHash32(pkey, static_cast(len)); +} +} // namespace panda::ecmascript diff --git a/ecmascript/js_int16_array.h b/ecmascript/runtime_trampolines.h similarity index 31% rename from ecmascript/js_int16_array.h rename to ecmascript/runtime_trampolines.h index 66e9bd0b48eca3ae68bfd6063b859d401437a462..e63f3469adcd27e85b7b5facdfe47b0a91793820 100644 --- a/ecmascript/js_int16_array.h +++ b/ecmascript/runtime_trampolines.h @@ -1,45 +1,49 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef PANDA_RUNTIME_ECMASCRIPT_JS_INT16_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_JS_INT16_ARRAY_H - -#include -#include "ecmascript/js_object.h" -#include "ecmascript/js_tagged_value-inl.h" -#include "ecmascript/js_tagged_value.h" - -namespace panda::ecmascript { -class JSInt16Array : public JSObject { -public: - static JSInt16Array *Cast(ObjectHeader *object) - { - ASSERT(JSTaggedValue(object).IsJSInt16Array()); - return static_cast(object); - } - - static constexpr size_t VIEWED_ARRAY_BUFFER_OFFSET = JSObject::SIZE; - ACCESSORS(ViewedArrayBuffer, VIEWED_ARRAY_BUFFER_OFFSET, TYPED_ARRAY_NAME_OFFSET) - ACCESSORS(TypedArrayName, TYPED_ARRAY_NAME_OFFSET, BYTE_LENGTH_OFFSET) - ACCESSORS(ByteLength, BYTE_LENGTH_OFFSET, BYTE_OFFSET_OFFSET) - ACCESSORS(ByteOffset, BYTE_OFFSET_OFFSET, ARRAY_LENGTH_OFFSET) - ACCESSORS(ArrayLength, ARRAY_LENGTH_OFFSET, SIZE) - DECL_DUMP() - - DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VIEWED_ARRAY_BUFFER_OFFSET, SIZE) -}; // namespace panda::ecmascript -} // namespace panda::ecmascript - -#endif // PANDA_RUNTIME_ECMASCRIPT_JS_INT16_ARRAY_H +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_RUNTIME_TRAMPOLINES_H +#define ECMASCRIPT_RUNTIME_TRAMPOLINES_H +#include "ecmascript/compiler/fast_stub_define.h" +#include "ecmascript/js_thread.h" + +namespace panda::ecmascript { +class RuntimeTrampolines { +public: + enum RuntimeTrampolineId { +#define DEF_RUNTIME_STUB(name, counter) RUNTIME_ID_##name, + EXTERNAL_RUNTIMESTUB_LIST(DEF_RUNTIME_STUB) +#undef DEF_RUNTIME_STUB + EXTERNAL_RUNTIME_STUB_MAXID + }; + static void InitializeRuntimeTrampolines(JSThread *thread) + { + #define DEF_RUNTIME_STUB(name, counter) RuntimeTrampolineId::RUNTIME_ID_##name + #define INITIAL_RUNTIME_FUNCTIONS(name, count) \ + thread->SetRuntimeFunction(DEF_RUNTIME_STUB(name, count), reinterpret_cast(name)); + EXTERNAL_RUNTIMESTUB_LIST(INITIAL_RUNTIME_FUNCTIONS) + #undef INITIAL_RUNTIME_FUNCTIONS + #undef DEF_RUNTIME_STUB + } + static bool AddElementInternal(uint64_t argThread, uint64_t argReceiver, uint32_t argIndex, + uint64_t argValue, uint32_t argAttr); + static bool CallSetter(uint64_t argThread, uint64_t argSetter, uint64_t argReceiver, uint64_t argValue, + bool argMayThrow); + static void ThrowTypeError(uint64_t argThread, int argMessageStringId); + static bool JSProxySetProperty(uint64_t argThread, uint64_t argProxy, uint64_t argKey, uint64_t argValue, + uint64_t argReceiver, bool argMayThrow); + static uint32_t GetHash32(uint64_t key, uint64_t len); +}; +} // namespace panda::ecmascript +#endif \ No newline at end of file diff --git a/ecmascript/snapshot/mem/constants.h b/ecmascript/snapshot/mem/constants.h index 943482bd3ab7c3386e569e6c83e20d31e410f7ff..23a71c69cdaa1d58994a271cc18bf1a4072e04fd 100644 --- a/ecmascript/snapshot/mem/constants.h +++ b/ecmascript/snapshot/mem/constants.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_ECMASCRIPT_MEM_CONSTANTS_H -#define PANDA_ECMASCRIPT_MEM_CONSTANTS_H +#ifndef ECMASCRIPT_SNAPSHOT_MEM_CONSTANTS_H +#define ECMASCRIPT_SNAPSHOT_MEM_CONSTANTS_H // slot bit static constexpr int OBJECT_INDEX_BIT_NUMBER = 13; // object index @@ -47,4 +47,4 @@ static constexpr int NATIVE_METHOD_SIZE = 427; static constexpr size_t MANAGED_OBJECT_OFFSET = 16; -#endif // PANDA_ECMASCRIPT_MEM_CONSTANTS_H +#endif // ECMASCRIPT_SNAPSHOT_MEM_CONSTANTS_H diff --git a/ecmascript/snapshot/mem/slot_bit.h b/ecmascript/snapshot/mem/slot_bit.h index a9c79edf5d006e1f9f0e8d049338fcf90be46390..b5c63a4f9078557cca3b6addda5d3a166b0870ae 100644 --- a/ecmascript/snapshot/mem/slot_bit.h +++ b/ecmascript/snapshot/mem/slot_bit.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_ECMASCRIPT_MEM_SLOT_BIT_H -#define PANDA_ECMASCRIPT_MEM_SLOT_BIT_H +#ifndef ECMASCRIPT_SNAPSHOT_MEM_SLOT_BIT_H +#define ECMASCRIPT_SNAPSHOT_MEM_SLOT_BIT_H #include "ecmascript/mem/c_containers.h" #include "ecmascript/mem/slots.h" @@ -131,4 +131,4 @@ public: }; } // namespace panda::ecmascript -#endif // PANDA_ECMASCRIPT_MEM_SLOT_BIT_H +#endif // ECMASCRIPT_SNAPSHOT_MEM_SLOT_BIT_H diff --git a/ecmascript/snapshot/mem/snapshot.cpp b/ecmascript/snapshot/mem/snapshot.cpp index 978c19b69c37eb4a4b0d3a5215588439ef920729..30c2370068d2f8faa593008da2ed447827e0b986 100644 --- a/ecmascript/snapshot/mem/snapshot.cpp +++ b/ecmascript/snapshot/mem/snapshot.cpp @@ -145,7 +145,8 @@ std::unique_ptr SnapShot::DeserializeGlobalEnvAndProgram uintptr_t snapshot_begin = readFile + sizeof(Header); for (size_t i = 0; i < hdr.snapshot_size / DEFAULT_SNAPSHOT_SPACE_SIZE; i++) { - Region *region = vm_->GetHeap()->GetRegionFactory()->AllocateAlignedRegion(space, DEFAULT_SNAPSHOT_SPACE_SIZE); + Region *region = const_cast(vm_->GetHeap()->GetRegionFactory()) + ->AllocateAlignedRegion(space, DEFAULT_SNAPSHOT_SPACE_SIZE); auto fileRegion = ToNativePtr(snapshot_begin + i * DEFAULT_SNAPSHOT_SPACE_SIZE); uint64_t base = region->allocateBase_; diff --git a/ecmascript/snapshot/mem/snapshot.h b/ecmascript/snapshot/mem/snapshot.h index e8fcbbe6b80d7bed2caa2fbeea0d19d1c17c3652..05dfec162a60d9b90b8940b5d57619a52bffa031 100644 --- a/ecmascript/snapshot/mem/snapshot.h +++ b/ecmascript/snapshot/mem/snapshot.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_ECMASCRIPT_MEM_SNAPSHOT_H -#define PANDA_ECMASCRIPT_MEM_SNAPSHOT_H +#ifndef ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_H +#define ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_H #include "libpandabase/macros.h" #include "libpandafile/file.h" @@ -52,4 +52,4 @@ private: EcmaVM *vm_; }; } // namespace panda::ecmascript -#endif // PANDA_ECMASCRIPT_MEM_SNAPSHOT_H \ No newline at end of file +#endif // ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_H \ No newline at end of file diff --git a/ecmascript/snapshot/mem/snapshot_serialize.cpp b/ecmascript/snapshot/mem/snapshot_serialize.cpp index 125885ca2bf99e814fe6a19596b5745bc5147145..75df4559e69a3306e2d2f9e6a7be89e1112b39d6 100644 --- a/ecmascript/snapshot/mem/snapshot_serialize.cpp +++ b/ecmascript/snapshot/mem/snapshot_serialize.cpp @@ -20,24 +20,31 @@ #include "ecmascript/builtins/builtins_arraybuffer.h" #include "ecmascript/builtins/builtins_async_function.h" #include "ecmascript/builtins/builtins_boolean.h" +#include "ecmascript/builtins/builtins_collator.h" #include "ecmascript/builtins/builtins_dataview.h" #include "ecmascript/builtins/builtins_date.h" +#include "ecmascript/builtins/builtins_date_time_format.h" #include "ecmascript/builtins/builtins_errors.h" #include "ecmascript/builtins/builtins_function.h" #include "ecmascript/builtins/builtins_generator.h" #include "ecmascript/builtins/builtins_global.h" +#include "ecmascript/builtins/builtins_intl.h" #include "ecmascript/builtins/builtins_iterator.h" #include "ecmascript/builtins/builtins_json.h" +#include "ecmascript/builtins/builtins_locale.h" #include "ecmascript/builtins/builtins_map.h" #include "ecmascript/builtins/builtins_math.h" #include "ecmascript/builtins/builtins_number.h" +#include "ecmascript/builtins/builtins_number_format.h" #include "ecmascript/builtins/builtins_object.h" +#include "ecmascript/builtins/builtins_plural_rules.h" #include "ecmascript/builtins/builtins_promise.h" #include "ecmascript/builtins/builtins_promise_handler.h" #include "ecmascript/builtins/builtins_promise_job.h" #include "ecmascript/builtins/builtins_proxy.h" #include "ecmascript/builtins/builtins_reflect.h" #include "ecmascript/builtins/builtins_regexp.h" +#include "ecmascript/builtins/builtins_relative_time_format.h" #include "ecmascript/builtins/builtins_set.h" #include "ecmascript/builtins/builtins_string.h" #include "ecmascript/builtins/builtins_string_iterator.h" @@ -96,9 +103,16 @@ using BuiltinsPromiseHandler = builtins::BuiltinsPromiseHandler; using BuiltinsPromiseJob = builtins::BuiltinsPromiseJob; using ErrorType = base::ErrorType; using DataView = builtins::BuiltinsDataView; +using Intl = builtins::BuiltinsIntl; +using Locale = builtins::BuiltinsLocale; +using DateTimeFormat = builtins::BuiltinsDateTimeFormat; +using NumberFormat = builtins::BuiltinsNumberFormat; +using RelativeTimeFormat = builtins::BuiltinsRelativeTimeFormat; +using Collator = builtins::BuiltinsCollator; +using PluralRules = builtins::BuiltinsPluralRules; constexpr int TAGGED_SIZE = JSTaggedValue::TaggedTypeSize(); -constexpr int OBJECT_HEADER_SIZE = TaggedObject::ObjectHeaderSize(); +constexpr int OBJECT_HEADER_SIZE = TaggedObject::TaggedObjectSize(); constexpr int METHOD_SIZE = sizeof(JSMethod); // NOLINTNEXTLINE(modernize-avoid-c-arrays) @@ -132,6 +146,7 @@ static uintptr_t g_nativeTable[] = { reinterpret_cast(Number::NumberConstructor), reinterpret_cast(Number::ToExponential), reinterpret_cast(Number::ToFixed), + reinterpret_cast(Number::ToLocaleString), reinterpret_cast(Number::ToPrecision), reinterpret_cast(Number::ToString), reinterpret_cast(Number::ValueOf), @@ -186,6 +201,9 @@ static uintptr_t g_nativeTable[] = { reinterpret_cast(Date::ToDateString), reinterpret_cast(Date::ToISOString), reinterpret_cast(Date::ToJSON), + reinterpret_cast(Date::ToLocaleDateString), + reinterpret_cast(Date::ToLocaleString), + reinterpret_cast(Date::ToLocaleTimeString), reinterpret_cast(Date::ToString), reinterpret_cast(Date::ToTimeString), reinterpret_cast(Date::ToUTCString), @@ -356,6 +374,7 @@ static uintptr_t g_nativeTable[] = { reinterpret_cast(BuiltinsString::LastIndexOf), reinterpret_cast(BuiltinsString::LocaleCompare), reinterpret_cast(BuiltinsString::Match), + reinterpret_cast(BuiltinsString::Normalize), reinterpret_cast(BuiltinsString::Repeat), reinterpret_cast(BuiltinsString::Replace), reinterpret_cast(BuiltinsString::Search), @@ -364,6 +383,8 @@ static uintptr_t g_nativeTable[] = { reinterpret_cast(BuiltinsString::StartsWith), reinterpret_cast(BuiltinsString::Substring), reinterpret_cast(BuiltinsString::SubStr), + reinterpret_cast(BuiltinsString::ToLocaleLowerCase), + reinterpret_cast(BuiltinsString::ToLocaleUpperCase), reinterpret_cast(BuiltinsString::ToLowerCase), reinterpret_cast(BuiltinsString::ToString), reinterpret_cast(BuiltinsString::ToUpperCase), @@ -482,12 +503,52 @@ static uintptr_t g_nativeTable[] = { reinterpret_cast(Promise::GetSpecies), reinterpret_cast(BuiltinsPromiseJob::PromiseReactionJob), reinterpret_cast(BuiltinsPromiseJob::PromiseResolveThenableJob), + reinterpret_cast(Intl::GetCanonicalLocales), + reinterpret_cast(Locale::LocaleConstructor), + reinterpret_cast(Locale::Maximize), + reinterpret_cast(Locale::Minimize), + reinterpret_cast(Locale::ToString), + reinterpret_cast(Locale::GetBaseName), + reinterpret_cast(Locale::GetCalendar), + reinterpret_cast(Locale::GetCaseFirst), + reinterpret_cast(Locale::GetCollation), + reinterpret_cast(Locale::GetHourCycle), + reinterpret_cast(Locale::GetNumeric), + reinterpret_cast(Locale::GetNumberingSystem), + reinterpret_cast(Locale::GetLanguage), + reinterpret_cast(Locale::GetScript), + reinterpret_cast(Locale::GetRegion), + reinterpret_cast(DateTimeFormat::DateTimeFormatConstructor), + reinterpret_cast(DateTimeFormat::SupportedLocalesOf), + reinterpret_cast(DateTimeFormat::Format), + reinterpret_cast(DateTimeFormat::FormatToParts), + reinterpret_cast(DateTimeFormat::ResolvedOptions), + reinterpret_cast(DateTimeFormat::FormatRange), + reinterpret_cast(DateTimeFormat::FormatRangeToParts), + reinterpret_cast(NumberFormat::NumberFormatConstructor), + reinterpret_cast(NumberFormat::SupportedLocalesOf), + reinterpret_cast(NumberFormat::Format), + reinterpret_cast(NumberFormat::FormatToParts), + reinterpret_cast(NumberFormat::ResolvedOptions), + reinterpret_cast(NumberFormat::NumberFormatInternalFormatNumber), + reinterpret_cast(RelativeTimeFormat::RelativeTimeFormatConstructor), + reinterpret_cast(RelativeTimeFormat::SupportedLocalesOf), + reinterpret_cast(RelativeTimeFormat::Format), + reinterpret_cast(RelativeTimeFormat::FormatToParts), + reinterpret_cast(RelativeTimeFormat::ResolvedOptions), + reinterpret_cast(Collator::CollatorConstructor), + reinterpret_cast(Collator::SupportedLocalesOf), + reinterpret_cast(Collator::Compare), + reinterpret_cast(Collator::ResolvedOptions), + reinterpret_cast(PluralRules::PluralRulesConstructor), + reinterpret_cast(PluralRules::SupportedLocalesOf), + reinterpret_cast(PluralRules::Select), + reinterpret_cast(PluralRules::ResolvedOptions), // not builtins method reinterpret_cast(JSFunction::PrototypeSetter), reinterpret_cast(JSFunction::PrototypeGetter), reinterpret_cast(JSFunction::NameGetter), - reinterpret_cast(JSFunction::LengthGetter), reinterpret_cast(JSArray::LengthSetter), reinterpret_cast(JSArray::LengthGetter), }; @@ -527,7 +588,7 @@ void SnapShotSerialize::Serialize(TaggedObject *objectHeader, CQueueGetObjectSize(); if (objectSize > MAX_REGULAR_HEAP_OBJECT_SIZE) { - LOG_ECMA_MEM(FATAL) << "It is a large object. Not Support."; + LOG_ECMA_MEM(FATAL) << "It is a huge object. Not Support."; } if (objectSize == 0) { @@ -941,7 +1002,7 @@ void SnapShotSerialize::NativePointerDeserialize(uint64_t *objectHeader) if (native.GetObjectIndex() == MAX_OBJECT_INDEX) { return; } - JSNativePointer::Cast(object)->SetExternalPointer(NativePointerSlotBitToAddr(native)); + JSNativePointer::Cast(object)->ResetExternalPointer(NativePointerSlotBitToAddr(native)); } void SnapShotSerialize::JSObjectSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize, diff --git a/ecmascript/snapshot/mem/snapshot_serialize.h b/ecmascript/snapshot/mem/snapshot_serialize.h index 0aadd70ea04a419f87d309584cff4ba46cd74e4d..e732a00c092275664d82ba703982cc339dadfa5a 100644 --- a/ecmascript/snapshot/mem/snapshot_serialize.h +++ b/ecmascript/snapshot/mem/snapshot_serialize.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_ECMASCRIPT_MEM_SNAPSHOT_SERIALIZE_H -#define PANDA_ECMASCRIPT_MEM_SNAPSHOT_SERIALIZE_H +#ifndef ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_SERIALIZE_H +#define ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_SERIALIZE_H #include #include @@ -92,7 +92,7 @@ private: *addr = value; } - template + template T GetAddress(size_t index) { return *reinterpret_cast(addressSlot_ + index * ADDRESS_SIZE); @@ -115,4 +115,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_ECMASCRIPT_MEM_SNAPSHOT_SERIALIZE_H +#endif // ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_SERIALIZE_H diff --git a/ecmascript/symbol_table-inl.h b/ecmascript/symbol_table-inl.h index 6ca03f5a28aa2649f3acc64b301a7c9e4a882994..2d95039ebd674f2e6264aefb589294da5a61f9f0 100644 --- a/ecmascript/symbol_table-inl.h +++ b/ecmascript/symbol_table-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_SYMBOL_TABLE_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_SYMBOL_TABLE_INL_H +#ifndef ECMASCRIPT_SYMBOL_TABLE_INL_H +#define ECMASCRIPT_SYMBOL_TABLE_INL_H #include "symbol_table.h" #include "js_symbol.h" @@ -22,14 +22,14 @@ #include "libpandabase/utils/hash.h" namespace panda::ecmascript { -int SymbolTable::Hash(const JSTaggedValue &obj) +uint32_t SymbolTable::Hash(const JSTaggedValue &obj) { if (obj.IsHeapObject()) { if (obj.IsString()) { auto *nameString = static_cast(obj.GetTaggedObject()); - return static_cast(nameString->GetHashcode()); + return nameString->GetHashcode(); } - return static_cast(JSSymbol::ComputeHash()); + return JSSymbol::ComputeHash(); } UNREACHABLE(); } @@ -70,4 +70,4 @@ JSTaggedValue SymbolTable::FindSymbol(JSThread *thread, const JSTaggedValue &val return JSTaggedValue::Undefined(); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_SYMBOL_TABLE_INL_H \ No newline at end of file +#endif // ECMASCRIPT_SYMBOL_TABLE_INL_H \ No newline at end of file diff --git a/ecmascript/symbol_table.h b/ecmascript/symbol_table.h index cdafcf1e8c1c05bfd4325feefef1d745c3c087f3..03b2d90981aa481b52e2f6f30402dfe28d9ae9d2 100644 --- a/ecmascript/symbol_table.h +++ b/ecmascript/symbol_table.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_SYMBOL_TABLE_H -#define PANDA_RUNTIME_ECMASCRIPT_SYMBOL_TABLE_H +#ifndef ECMASCRIPT_SYMBOL_TABLE_H +#define ECMASCRIPT_SYMBOL_TABLE_H #include "ecmascript/tagged_hash_table.h" #include "ecmascript/ecma_string.h" @@ -45,7 +45,7 @@ public: return ENTRY_SIZE; } static inline bool IsMatch(const JSTaggedValue &name, const JSTaggedValue &other); - static inline int Hash(const JSTaggedValue &obj); + static inline uint32_t Hash(const JSTaggedValue &obj); static const int DEFAULT_ELEMENTS_NUMBER = 64; static SymbolTable *Create(JSThread *thread, int numberOfElements = DEFAULT_ELEMENTS_NUMBER) @@ -63,4 +63,4 @@ public: static constexpr int ENTRY_SIZE = 2; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_SYMBOL_TABLE_H \ No newline at end of file +#endif // ECMASCRIPT_SYMBOL_TABLE_H \ No newline at end of file diff --git a/ecmascript/tagged_array-inl.h b/ecmascript/tagged_array-inl.h index d2ffd6f86ea401237fd35a719b842fc6cae0f2b8..a340d85726b5de5df385643bd1027d78cf64bd78 100644 --- a/ecmascript/tagged_array-inl.h +++ b/ecmascript/tagged_array-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_ARRAY_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_ARRAY_INL_H +#ifndef ECMASCRIPT_TAGGED_ARRAY_INL_H +#define ECMASCRIPT_TAGGED_ARRAY_INL_H #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/js_thread.h" @@ -53,7 +53,7 @@ inline array_size_t TaggedArray::GetIdx(const JSTaggedValue &value) const return TaggedArray::MAX_ARRAY_INDEX; } -template +template inline void TaggedArray::Set(const JSThread *thread, array_size_t idx, const JSHandle &value) { ASSERT(idx < GetLength()); @@ -175,4 +175,4 @@ void TaggedArray::Trim(JSThread *thread, array_size_t newLength) SetLength(newLength); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TAGGED_ARRAY_INL_H +#endif // ECMASCRIPT_TAGGED_ARRAY_INL_H diff --git a/ecmascript/tagged_array.h b/ecmascript/tagged_array.h index 68827987b03ca0a83ed40967c8aefdd39c178214..56124a242864fb99efa4e3c8210e2ce87091511c 100644 --- a/ecmascript/tagged_array.h +++ b/ecmascript/tagged_array.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_ARRAY_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_ARRAY_H +#ifndef ECMASCRIPT_TAGGED_ARRAY_H +#define ECMASCRIPT_TAGGED_ARRAY_H #include "ecmascript/js_hclass.h" #include "ecmascript/js_tagged_value.h" @@ -26,6 +26,7 @@ class ObjectFactory; class TaggedArray : public TaggedObject { public: static constexpr array_size_t MAX_ARRAY_INDEX = std::numeric_limits::max(); + static constexpr array_size_t MAX_END_UNUSED = 4; inline static TaggedArray *Cast(ObjectHeader *obj) { @@ -39,7 +40,7 @@ public: array_size_t GetIdx(const JSTaggedValue &value) const; - template + template void Set(const JSThread *thread, array_size_t idx, const JSHandle &value); JSTaggedValue Get(const JSThread *thread, array_size_t idx) const; @@ -93,6 +94,10 @@ public: inline void InitializeWithSpecialValue(JSTaggedValue initValue, array_size_t length); + static inline bool ShouldTrim(array_size_t oldLength, array_size_t newLength) + { + return oldLength - newLength > MAX_END_UNUSED; + } inline void Trim(JSThread *thread, array_size_t newLength); void Visitor(const EcmaObjectRangeVisitor &v) { @@ -114,4 +119,4 @@ private: __extension__ alignas(sizeof(JSTaggedType)) JSTaggedType data_[0]; // NOLINT(modernize-avoid-c-arrays) }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TAGGED_ARRAY_H +#endif // ECMASCRIPT_TAGGED_ARRAY_H diff --git a/ecmascript/tagged_dictionary.h b/ecmascript/tagged_dictionary.h index d69022e9935b92e0c4219764f950bcda111ddde9..33c9cd075d4fb133c5f82bb1ca9beea2705888b1 100644 --- a/ecmascript/tagged_dictionary.h +++ b/ecmascript/tagged_dictionary.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_DICTIONARY_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_DICTIONARY_H +#ifndef ECMASCRIPT_TAGGED_DICTIONARY_H +#define ECMASCRIPT_TAGGED_DICTIONARY_H #include "ecmascript/tagged_hash_table.h" @@ -118,4 +118,4 @@ public: static constexpr int ENTRY_SIZE = 3; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_NEW_DICTIONARY_H +#endif // ECMASCRIPT_NEW_DICTIONARY_H diff --git a/ecmascript/tagged_hash_table-inl.h b/ecmascript/tagged_hash_table-inl.h index 0a3823ea087083000a2c3e362a6a9522558c733c..8a7831311398027edac7f6ee723d4cb781ebf220 100644 --- a/ecmascript/tagged_hash_table-inl.h +++ b/ecmascript/tagged_hash_table-inl.h @@ -13,64 +13,64 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_HASH_TABLE_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_HASH_TABLE_INL_H +#ifndef ECMASCRIPT_TAGGED_HASH_TABLE_INL_H +#define ECMASCRIPT_TAGGED_HASH_TABLE_INL_H #include "ecmascript/object_factory.h" #include "ecmascript/tagged_array-inl.h" #include "ecmascript/tagged_hash_table.h" namespace panda::ecmascript { -template +template int TaggedHashTable::EntriesCount() const { return Get(NUMBER_OF_ENTRIES_INDEX).GetInt(); } -template +template int TaggedHashTable::HoleEntriesCount() const { return Get(NUMBER_OF_HOLE_ENTRIES_INDEX).GetInt(); } -template +template int TaggedHashTable::Size() const { return Get(SIZE_INDEX).GetInt(); } -template +template void TaggedHashTable::IncreaseEntries(const JSThread *thread) { SetEntriesCount(thread, EntriesCount() + 1); } -template +template void TaggedHashTable::IncreaseHoleEntriesCount(const JSThread *thread, int number) { SetEntriesCount(thread, EntriesCount() - number); SetHoleEntriesCount(thread, HoleEntriesCount() + number); } -template +template void TaggedHashTable::SetEntriesCount(const JSThread *thread, int nof) { Set(thread, NUMBER_OF_ENTRIES_INDEX, JSTaggedValue(nof)); } -template +template void TaggedHashTable::SetHoleEntriesCount(const JSThread *thread, int nod) { Set(thread, NUMBER_OF_HOLE_ENTRIES_INDEX, JSTaggedValue(nod)); } -template +template void TaggedHashTable::SetHashTableSize(const JSThread *thread, int size) { Set(thread, SIZE_INDEX, JSTaggedValue(size)); } -template +template void TaggedHashTable::GetAllKeys(const JSThread *thread, int offset, TaggedArray *keyArray) const { ASSERT_PRINT(offset + EntriesCount() <= static_cast(keyArray->GetLength()), @@ -87,7 +87,7 @@ void TaggedHashTable::GetAllKeys(const JSThread *thread, int offset, Ta } // Find entry for key otherwise return -1. -template +template int TaggedHashTable::FindEntry(const JSTaggedValue &key) { size_t size = Size(); @@ -111,7 +111,7 @@ int TaggedHashTable::FindEntry(const JSTaggedValue &key) } // static -template +template int TaggedHashTable::RecalculateTableSize(int currentSize, int atLeastSize) { // When the filled entries is greater than a quart of currentSize @@ -130,7 +130,7 @@ int TaggedHashTable::RecalculateTableSize(int currentSize, int atLeastS } // static -template +template Derived *TaggedHashTable::Shrink(const JSThread *thread, const JSHandle &table, int additionalSize) { int newSize = RecalculateTableSize(table->Size(), table->EntriesCount() + additionalSize); @@ -144,7 +144,7 @@ Derived *TaggedHashTable::Shrink(const JSThread *thread, const JSHandle return newTable; } -template +template bool TaggedHashTable::IsNeedGrowHashTable(int numOfAddEntries) { int entriesCount = EntriesCount(); @@ -164,7 +164,7 @@ bool TaggedHashTable::IsNeedGrowHashTable(int numOfAddEntries) return true; } -template +template void TaggedHashTable::AddElement(const JSThread *thread, int entry, const JSHandle &key, const JSHandle &value) { @@ -173,7 +173,7 @@ void TaggedHashTable::AddElement(const JSThread *thread, int entry, con this->IncreaseEntries(thread); } -template +template void TaggedHashTable::RemoveElement(const JSThread *thread, int entry) { JSTaggedValue defaultValue(JSTaggedValue::Hole()); @@ -182,7 +182,7 @@ void TaggedHashTable::RemoveElement(const JSThread *thread, int entry) this->IncreaseHoleEntriesCount(thread); } -template +template Derived *TaggedHashTable::Insert(const JSThread *thread, JSHandle &table, const JSHandle &key, const JSHandle &value) { @@ -199,7 +199,7 @@ Derived *TaggedHashTable::Insert(const JSThread *thread, JSHandle +template Derived *TaggedHashTable::Remove(const JSThread *thread, JSHandle &table, const JSHandle &key) { @@ -212,7 +212,7 @@ Derived *TaggedHashTable::Remove(const JSThread *thread, JSHandle +template void TaggedHashTable::Rehash(const JSThread *thread, Derived *newTable) { if ((newTable == nullptr) || (newTable->Size() < EntriesCount())) { @@ -240,7 +240,7 @@ void TaggedHashTable::Rehash(const JSThread *thread, Derived *newTable) } // static -template +template int TaggedHashTable::ComputeHashTableSize(uint32_t atLeastSize) { // increase size for hash-collision @@ -249,7 +249,7 @@ int TaggedHashTable::ComputeHashTableSize(uint32_t atLeastSize) return (newSize > MIN_SIZE) ? newSize : MIN_SIZE; } -template +template Derived *TaggedHashTable::GrowHashTable(const JSThread *thread, const JSHandle &table, int numOfAddedElements) { @@ -264,7 +264,7 @@ Derived *TaggedHashTable::GrowHashTable(const JSThread *thread, const J return newTable; } -template +template Derived *TaggedHashTable::Create(const JSThread *thread, int entriesCount) { ASSERT_PRINT((entriesCount > 0), "the size must be greater than zero"); @@ -280,7 +280,7 @@ Derived *TaggedHashTable::Create(const JSThread *thread, int entriesCou return table; } -template +template void TaggedHashTable::SetKey(const JSThread *thread, int entry, const JSTaggedValue &key) { int index = Derived::GetKeyIndex(entry); @@ -290,7 +290,7 @@ void TaggedHashTable::SetKey(const JSThread *thread, int entry, const J Set(thread, index, key); } -template +template JSTaggedValue TaggedHashTable::GetKey(int entry) const { int index = Derived::GetKeyIndex(entry); @@ -300,7 +300,7 @@ JSTaggedValue TaggedHashTable::GetKey(int entry) const return Get(index); } -template +template void TaggedHashTable::SetValue(const JSThread *thread, int entry, const JSTaggedValue &value) { int index = Derived::GetValueIndex(entry); @@ -310,7 +310,7 @@ void TaggedHashTable::SetValue(const JSThread *thread, int entry, const Set(thread, index, value); } -template +template JSTaggedValue TaggedHashTable::GetValue(int entry) const { int index = Derived::GetValueIndex(entry); @@ -320,7 +320,7 @@ JSTaggedValue TaggedHashTable::GetValue(int entry) const return Get(index); } -template +template int TaggedHashTable::FindInsertIndex(int hash) { int size = Size(); @@ -333,7 +333,7 @@ int TaggedHashTable::FindInsertIndex(int hash) } } -template +template Derived *OrderTaggedHashTable::Create(const JSThread *thread, int numberOfElements) { Derived *dict = HashTableT::Create(thread, numberOfElements); @@ -341,7 +341,7 @@ Derived *OrderTaggedHashTable::Create(const JSThread *thread, int numbe return dict; } -template +template Derived *OrderTaggedHashTable::PutIfAbsent(const JSThread *thread, const JSHandle &table, const JSHandle &key, const JSHandle &value, @@ -369,7 +369,7 @@ Derived *OrderTaggedHashTable::PutIfAbsent(const JSThread *thread, cons return newTable; } -template +template Derived *OrderTaggedHashTable::Put(const JSThread *thread, const JSHandle &table, const JSHandle &key, const JSHandle &value, const PropertyAttributes &metaData) @@ -395,7 +395,7 @@ Derived *OrderTaggedHashTable::Put(const JSThread *thread, const JSHand return newTable; } -template +template void TaggedHashTable::GetAllKeysIntoVector(const JSThread *thread, std::vector &vector) const { int capacity = Size(); @@ -407,7 +407,7 @@ void TaggedHashTable::GetAllKeysIntoVector(const JSThread *thread, std: } } -template +template Derived *OrderTaggedHashTable::Remove(const JSThread *thread, const JSHandle &table, int entry) { if (!(table->IsKey(table->GetKey(entry)))) { @@ -418,7 +418,7 @@ Derived *OrderTaggedHashTable::Remove(const JSThread *thread, const JSH return Shrink(thread, table); } -template +template int OrderTaggedHashTable::NextEnumerationIndex(const JSThread *thread) { int index = GetNextEnumerationIndex(); @@ -439,7 +439,7 @@ int OrderTaggedHashTable::NextEnumerationIndex(const JSThread *thread) return index; } -template +template std::vector OrderTaggedHashTable::GetEnumerationOrder() { std::vector result; @@ -458,4 +458,4 @@ std::vector OrderTaggedHashTable::GetEnumerationOrder() return result; } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TAGGED_HASH_TABLE_INL_H +#endif // ECMASCRIPT_TAGGED_HASH_TABLE_INL_H diff --git a/ecmascript/tagged_hash_table.h b/ecmascript/tagged_hash_table.h index 4611ba6a775b29ddea03352ecee70df6502f1b75..dac8fd882eaba7f68823787b25f1c144eeff57d4 100644 --- a/ecmascript/tagged_hash_table.h +++ b/ecmascript/tagged_hash_table.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_HASH_TABLE_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_HASH_TABLE_H +#ifndef ECMASCRIPT_TAGGED_HASH_TABLE_H +#define ECMASCRIPT_TAGGED_HASH_TABLE_H #include @@ -22,7 +22,7 @@ #include "tagged_array.h" namespace panda::ecmascript { -template +template class TaggedHashTable : public TaggedArray { public: inline int EntriesCount() const; @@ -115,7 +115,7 @@ protected: void Rehash(const JSThread *thread, Derived *newTable); }; -template +template class OrderTaggedHashTable : public TaggedHashTable { public: using HashTableT = TaggedHashTable; @@ -158,4 +158,4 @@ public: static constexpr int TABLE_HEADER_SIZE = 4; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_NEW_HASH_TABLE_H \ No newline at end of file +#endif // ECMASCRIPT_NEW_HASH_TABLE_H \ No newline at end of file diff --git a/ecmascript/tagged_queue-inl.h b/ecmascript/tagged_queue-inl.h index e655e40538ff0dd70f401309a5ec1120aaff14ed..50cedce12ae63f49bfe1437b75336ed2074441b0 100644 --- a/ecmascript/tagged_queue-inl.h +++ b/ecmascript/tagged_queue-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_QUEUE_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_QUEUE_INL_H +#ifndef ECMASCRIPT_TAGGED_QUEUE_INL_H +#define ECMASCRIPT_TAGGED_QUEUE_INL_H #include "ecmascript/tagged_queue.h" @@ -40,8 +40,9 @@ inline JSTaggedValue TaggedQueue::Pop(JSThread *thread) JSTaggedValue value = Get(start); array_size_t capacity = GetCapacity().GetArrayLength(); + ASSERT(capacity != 0); SetStart(thread, JSTaggedValue((start + 1) % capacity)); return value; } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TAGGED_QUEUE_INL_H \ No newline at end of file +#endif // ECMASCRIPT_TAGGED_QUEUE_INL_H \ No newline at end of file diff --git a/ecmascript/tagged_queue.h b/ecmascript/tagged_queue.h index cdf400fde5393d8ebfa702a0c9295dd004fc265d..c5ca3717b800b1de48c605cb97d4baf766e259bb 100644 --- a/ecmascript/tagged_queue.h +++ b/ecmascript/tagged_queue.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TAGGED_QUEUE_H -#define PANDA_RUNTIME_ECMASCRIPT_TAGGED_QUEUE_H +#ifndef ECMASCRIPT_TAGGED_QUEUE_H +#define ECMASCRIPT_TAGGED_QUEUE_H #include "ecmascript/js_tagged_value.h" #include "ecmascript/js_thread.h" @@ -82,6 +82,7 @@ public: { array_size_t end = queue->GetEnd().GetArrayLength(); array_size_t capacity = queue->GetCapacity().GetArrayLength(); + ASSERT(capacity != 0); queue->Set(thread, end, value.GetTaggedValue()); queue->SetEnd(thread, JSTaggedValue((end + 1) % capacity)); } @@ -177,4 +178,4 @@ private: static TaggedQueue *Create(JSThread *thread, array_size_t capacity, JSTaggedValue initVal = JSTaggedValue::Hole()); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TAGGED_QUEUE_H \ No newline at end of file +#endif // ECMASCRIPT_TAGGED_QUEUE_H \ No newline at end of file diff --git a/ecmascript/template_map.h b/ecmascript/template_map.h index 355c03404a855eb0a4e07f1f0da54416749460af..cc3ea99a60bef7ea0878f198fe355ab4854ae640 100644 --- a/ecmascript/template_map.h +++ b/ecmascript/template_map.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TEMPLATE_MAP_H -#define PANDA_RUNTIME_ECMASCRIPT_TEMPLATE_MAP_H +#ifndef ECMASCRIPT_TEMPLATE_MAP_H +#define ECMASCRIPT_TEMPLATE_MAP_H #include "ecmascript/tagged_hash_table-inl.h" #include "ecmascript/js_array.h" @@ -64,4 +64,4 @@ public: static const int ENTRY_VALUE_INDEX = 1; }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TEMPLATE_MAP_H \ No newline at end of file +#endif // ECMASCRIPT_TEMPLATE_MAP_H \ No newline at end of file diff --git a/ecmascript/template_string.cpp b/ecmascript/template_string.cpp index 4073a96f52dbdc6aad52c1b4fc68f5b372512b12..79fcfcb311b4363eb4b6bd6e38ee9ef606355a24 100644 --- a/ecmascript/template_string.cpp +++ b/ecmascript/template_string.cpp @@ -51,7 +51,7 @@ JSHandle TemplateString::GetTemplateObject(JSThread *thread, JSHa } JSObject::SetIntegrityLevel(thread, rawObj, IntegrityLevel::FROZEN); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle raw(factory->NewFromString("raw")); + JSHandle raw(factory->NewFromCanBeCompressString("raw")); PropertyDescriptor desc(thread, rawArr, false, false, false); JSArray::DefineOwnProperty(thread, templateObj, raw, desc); JSObject::SetIntegrityLevel(thread, templateObj, IntegrityLevel::FROZEN); diff --git a/ecmascript/template_string.h b/ecmascript/template_string.h index 080291e7ef43dce7116f617f99df78d5ae48f8ae..223174c58a6daf2916531c6731338461c6a22643 100644 --- a/ecmascript/template_string.h +++ b/ecmascript/template_string.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TEMPLATE_STRING_H -#define PANDA_RUNTIME_ECMASCRIPT_TEMPLATE_STRING_H +#ifndef ECMASCRIPT_TEMPLATE_STRING_H +#define ECMASCRIPT_TEMPLATE_STRING_H #include "ecmascript/js_array.h" @@ -24,4 +24,4 @@ public: static JSHandle GetTemplateObject(JSThread *thread, JSHandle templateLiteral); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_TEMPLATE_STRING_H \ No newline at end of file +#endif // ECMASCRIPT_TEMPLATE_STRING_H \ No newline at end of file diff --git a/ecmascript/tests/BUILD.gn b/ecmascript/tests/BUILD.gn index cd2527e89b8aa9ef019cede724edf3d8c2e0dfb3..d87cbea2d3bbb9866ef4ae3609f73e332e8a7f9a 100644 --- a/ecmascript/tests/BUILD.gn +++ b/ecmascript/tests/BUILD.gn @@ -434,12 +434,12 @@ host_unittest_action("JsVerificationTest") { ] } -host_unittest_action("JargeObjectTest") { +host_unittest_action("HugeObjectTest") { module_out_path = module_output_path sources = [ # test file - "large_object_test.cpp", + "huge_object_test.cpp", ] configs = [ @@ -456,7 +456,7 @@ host_unittest_action("JargeObjectTest") { ] } -host_unittest_action("JexicalEnvTest") { +host_unittest_action("LexicalEnvTest") { module_out_path = module_output_path sources = [ @@ -478,7 +478,7 @@ host_unittest_action("JexicalEnvTest") { ] } -host_unittest_action("JinkedHashTableTest") { +host_unittest_action("LinkedHashTableTest") { module_out_path = module_output_path sources = [ @@ -686,9 +686,7 @@ group("unittest") { ":DumpTest", ":GcTest", ":GlueRegsTest", - ":JargeObjectTest", - ":JexicalEnvTest", - ":JinkedHashTableTest", + ":HugeObjectTest", ":JsArrayTest", ":JsDateTest", ":JsForinIteratorTest", @@ -700,12 +698,13 @@ group("unittest") { ":JsPrimitiveRefTest", ":JsPromiseTest", ":JsProxyTest", - - # ":JsSerializerTest", + ":JsSerializerTest", ":JsSetTest", ":JsSymbolTest", ":JsTaggedQueueTest", ":JsVerificationTest", + ":LexicalEnvTest", + ":LinkedHashTableTest", ":NameDictionaryTest", ":NativePointerTest", ":ObjectFactoryTest", @@ -725,9 +724,7 @@ group("host_unittest") { ":DumpTestAction(${host_toolchain})", ":GcTestAction(${host_toolchain})", ":GlueRegsTestAction(${host_toolchain})", - ":JargeObjectTestAction(${host_toolchain})", - ":JexicalEnvTestAction(${host_toolchain})", - ":JinkedHashTableTestAction(${host_toolchain})", + ":HugeObjectTestAction(${host_toolchain})", ":JsArrayTestAction(${host_toolchain})", ":JsDateTestAction(${host_toolchain})", ":JsForinIteratorTestAction(${host_toolchain})", @@ -739,12 +736,13 @@ group("host_unittest") { ":JsPrimitiveRefTestAction(${host_toolchain})", ":JsPromiseTestAction(${host_toolchain})", ":JsProxyTestAction(${host_toolchain})", - - # ":JsSerializerTestAction(${host_toolchain})", + ":JsSerializerTestAction(${host_toolchain})", ":JsSetTestAction(${host_toolchain})", ":JsSymbolTestAction(${host_toolchain})", ":JsTaggedQueueTestAction(${host_toolchain})", ":JsVerificationTestAction(${host_toolchain})", + ":LexicalEnvTestAction(${host_toolchain})", + ":LinkedHashTableTestAction(${host_toolchain})", ":NameDictionaryTestAction(${host_toolchain})", ":NativePointerTestAction(${host_toolchain})", ":ObjectFactoryTestAction(${host_toolchain})", diff --git a/ecmascript/tests/builtins_test.cpp b/ecmascript/tests/builtins_test.cpp index db5dd7a209787bd7c9759cf9ac0a052e85d3586a..9a77fd0bebae7aa8982a657717166c89a32aa8b5 100644 --- a/ecmascript/tests/builtins_test.cpp +++ b/ecmascript/tests/builtins_test.cpp @@ -57,7 +57,6 @@ public: HWTEST_F_L0(BuiltinsTest, ObjectInit) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -67,7 +66,6 @@ HWTEST_F_L0(BuiltinsTest, ObjectInit) HWTEST_F_L0(BuiltinsTest, FunctionInit) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -77,7 +75,6 @@ HWTEST_F_L0(BuiltinsTest, FunctionInit) HWTEST_F_L0(BuiltinsTest, NumberInit) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -87,7 +84,6 @@ HWTEST_F_L0(BuiltinsTest, NumberInit) HWTEST_F_L0(BuiltinsTest, SetInit) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -97,7 +93,6 @@ HWTEST_F_L0(BuiltinsTest, SetInit) HWTEST_F_L0(BuiltinsTest, MapInit) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -107,7 +102,6 @@ HWTEST_F_L0(BuiltinsTest, MapInit) HWTEST_F_L0(BuiltinsTest, StrictModeForbiddenAccess) { - ASSERT_NE(thread, nullptr); auto ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); @@ -115,8 +109,8 @@ HWTEST_F_L0(BuiltinsTest, StrictModeForbiddenAccess) JSHandle function = factory->NewJSFunction(env, static_cast(nullptr)); - JSHandle callerKey(factory->NewFromString("caller")); - JSHandle argumentsKey(factory->NewFromString("arguments")); + JSHandle callerKey(factory->NewFromCanBeCompressString("caller")); + JSHandle argumentsKey(factory->NewFromCanBeCompressString("arguments")); JSObject::GetProperty(thread, JSHandle(function), callerKey); ASSERT_EQ(thread->HasPendingException(), true); diff --git a/ecmascript/tests/large_object_test.cpp b/ecmascript/tests/huge_object_test.cpp similarity index 91% rename from ecmascript/tests/large_object_test.cpp rename to ecmascript/tests/huge_object_test.cpp index 807fcb5f8bb78380a1c2ff24bb3558a225fca54a..22b5d4e7c770e93b6b341c0182973a9ced13e50a 100644 --- a/ecmascript/tests/large_object_test.cpp +++ b/ecmascript/tests/huge_object_test.cpp @@ -25,7 +25,7 @@ using namespace panda::ecmascript; namespace panda::test { -class LargeObjectTest : public testing::Test { +class HugeObjectTest : public testing::Test { public: static void SetUpTestCase() { @@ -76,7 +76,7 @@ static TaggedArray *LargeArrayTestCreate(JSThread *thread) } #endif -HWTEST_F_L0(LargeObjectTest, LargeArrayKeep) +HWTEST_F_L0(HugeObjectTest, LargeArrayKeep) { #if !defined(NDEBUG) TaggedArray *array = LargeArrayTestCreate(thread); @@ -87,13 +87,13 @@ HWTEST_F_L0(LargeObjectTest, LargeArrayKeep) auto ecmaVm = thread->GetEcmaVM(); EXPECT_EQ(*arrayHandle, reinterpret_cast(array)); ecmaVm->CollectGarbage(TriggerGCType::SEMI_GC); // Trigger GC. - ecmaVm->CollectGarbage(TriggerGCType::LARGE_GC); // Trigger GC. + ecmaVm->CollectGarbage(TriggerGCType::HUGE_GC); // Trigger GC. EXPECT_EQ(*newObj, array->Get(0).GetTaggedObject()); EXPECT_EQ(*arrayHandle, reinterpret_cast(array)); #endif } -HWTEST_F_L0(LargeObjectTest, MultipleArrays) +HWTEST_F_L0(HugeObjectTest, MultipleArrays) { #if !defined(NDEBUG) auto ecmaVm = thread->GetEcmaVM(); @@ -101,7 +101,6 @@ HWTEST_F_L0(LargeObjectTest, MultipleArrays) Region *firstPage = nullptr; Region *secondPage = nullptr; Region *thirdPage = nullptr; - JSHandle array1(thread, LargeArrayTestCreate(thread)); firstPage = Region::ObjectAddressToRange(*array1); { @@ -115,13 +114,13 @@ HWTEST_F_L0(LargeObjectTest, MultipleArrays) EXPECT_EQ(firstPage->GetNext(), secondPage); EXPECT_EQ(secondPage->GetNext(), thirdPage); - ecmaVm->CollectGarbage(TriggerGCType::LARGE_GC); // Trigger GC. + ecmaVm->CollectGarbage(TriggerGCType::HUGE_GC); // Trigger GC. EXPECT_EQ(firstPage->GetNext(), thirdPage); size_t failCount = 0; VerifyObjectVisitor objVerifier(heap, &failCount); - heap->GetLargeObjectSpace()->IterateOverObjects(objVerifier); // newspace reference the old space + heap->GetHugeObjectSpace()->IterateOverObjects(objVerifier); // newspace reference the old space EXPECT_TRUE(failCount == 0); #endif } diff --git a/ecmascript/tests/js_array_test.cpp b/ecmascript/tests/js_array_test.cpp index 07beb38389eecc1a71f619c86120997289ea91cf..8acf52fc86ae633ab8e9f19f3bf5454c73ddb520 100644 --- a/ecmascript/tests/js_array_test.cpp +++ b/ecmascript/tests/js_array_test.cpp @@ -95,7 +95,7 @@ HWTEST_F_L0(JSArrayTest, DefineOwnProperty) PropertyDescriptor desc(thread, JSHandle(thread, JSTaggedValue(100)), true, true, true); - EcmaString *string1 = *factory->NewFromString("1"); + EcmaString *string1 = *factory->NewFromCanBeCompressString("1"); JSHandle key1(thread, static_cast(string1)); JSHandle index1(thread, JSTaggedValue(1)); EXPECT_TRUE(JSArray::DefineOwnProperty(thread, JSHandle(obj), key1, desc)); @@ -106,7 +106,7 @@ HWTEST_F_L0(JSArrayTest, DefineOwnProperty) EXPECT_EQ(v.GetInt(), 100); EXPECT_EQ(JSArray::GetProperty(thread, obj, lengthKeyHandle).GetValue()->GetInt(), 2); - EcmaString *string100 = *factory->NewFromString("100"); + EcmaString *string100 = *factory->NewFromCanBeCompressString("100"); JSHandle key100(thread, static_cast(string100)); JSHandle index100(thread, JSTaggedValue(100)); @@ -115,7 +115,7 @@ HWTEST_F_L0(JSArrayTest, DefineOwnProperty) EXPECT_EQ(JSArray::GetProperty(thread, obj, index100).GetValue()->GetInt(), 100); EXPECT_EQ(JSArray::GetProperty(thread, obj, lengthKeyHandle).GetValue()->GetInt(), 101); - EcmaString *stringx = *factory->NewFromString("2147483646"); + EcmaString *stringx = *factory->NewFromCanBeCompressString("2147483646"); JSHandle keyx(thread, static_cast(stringx)); JSHandle indexx(thread, JSTaggedValue(2147483646U)); // 2147483646U diff --git a/ecmascript/tests/js_forin_iterator_test.cpp b/ecmascript/tests/js_forin_iterator_test.cpp index fd3f3e615494062cb1d938b8dcc6a2593d358f97..3a5b441c61b5afc495d503421170090923d5d9de 100644 --- a/ecmascript/tests/js_forin_iterator_test.cpp +++ b/ecmascript/tests/js_forin_iterator_test.cpp @@ -59,9 +59,9 @@ HWTEST_F_L0(JSForinIteratorTest, Create) JSHandle son = JSObject::ObjectCreate(thread, father); - JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString("key1")); - JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromString("key2")); - JSHandle key3(thread->GetEcmaVM()->GetFactory()->NewFromString("key3")); + JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key1")); + JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key2")); + JSHandle key3(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key3")); JSHandle key1Value(thread, JSTaggedValue(1)); JSHandle key2Value(thread, JSTaggedValue(2)); JSHandle key3Value(thread, JSTaggedValue(3)); diff --git a/ecmascript/tests/js_function_test.cpp b/ecmascript/tests/js_function_test.cpp index 9fdd1752294d9f93096cdfe599d061c4f236b92a..2dff3f98d59b35eb168d7e2dc14d24b9d29c2857 100644 --- a/ecmascript/tests/js_function_test.cpp +++ b/ecmascript/tests/js_function_test.cpp @@ -18,6 +18,7 @@ #include "ecmascript/ecma_string.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_function_extra_info.h" #include "ecmascript/js_handle.h" #include "ecmascript/js_hclass.h" @@ -94,9 +95,10 @@ HWTEST_F_L0(JSFunctionTest, MakeConstructor) JSFunction::MakeConstructor(thread, func, objValue); - JSHandle constructorKey(thread->GetEcmaVM()->GetFactory()->NewFromString("constructor")); + JSHandle constructorKey( + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("constructor")); - JSHandle protoKey(thread->GetEcmaVM()->GetFactory()->NewFromString("prototype")); + JSHandle protoKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("prototype")); JSTaggedValue proto = JSObject::GetProperty(thread, funcHandle, protoKey).GetValue().GetTaggedValue(); JSTaggedValue constructor = JSObject::GetProperty(thread, JSHandle(obj), constructorKey).GetValue().GetTaggedValue(); @@ -139,17 +141,16 @@ HWTEST_F_L0(JSFunctionTest, Invoke) EXPECT_TRUE(*callee != nullptr); char keyArray[] = "invoked"; - JSHandle calleeKey(thread->GetEcmaVM()->GetFactory()->NewFromString(&keyArray[0])); + JSHandle calleeKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(&keyArray[0])); JSHandle calleeFunc = thread->GetEcmaVM()->GetFactory()->NewJSFunction(env, reinterpret_cast(TestInvokeInternal)); calleeFunc->SetCallable(true); JSHandle calleeValue(calleeFunc); JSObject::SetProperty(thread, JSHandle(callee), calleeKey, calleeValue); - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle arguments = factory->NewTaggedArray(1); - arguments->Set(thread, 0, JSTaggedValue(1)); - JSTaggedValue res = JSFunction::Invoke(thread, callee, calleeKey, arguments); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(1)); + JSTaggedValue res = JSFunction::Invoke(thread, callee, calleeKey, 1, arguments->GetArgv()); JSTaggedValue ruler = BuiltinsBase::GetTaggedBoolean(true); EXPECT_EQ(res.GetRawData(), ruler.GetRawData()); @@ -161,7 +162,7 @@ HWTEST_F_L0(JSFunctionTest, SetSymbolFunctionName) JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle jsFunction = factory->NewJSFunction(env); JSHandle symbol = factory->NewPublicSymbolWithChar("name"); - JSHandle name = factory->NewFromString("[name]"); + JSHandle name = factory->NewFromCanBeCompressString("[name]"); JSHandle prefix(thread, JSTaggedValue::Undefined()); JSFunction::SetFunctionName(thread, JSHandle(jsFunction), JSHandle(symbol), prefix); JSHandle functionName = diff --git a/ecmascript/tests/js_handle_test.cpp b/ecmascript/tests/js_handle_test.cpp index 1068f610ae7c692c2d3e3c1df83e4f908826ee30..5d19659c065caf428e62c94aa5c772b4e2f8c93f 100644 --- a/ecmascript/tests/js_handle_test.cpp +++ b/ecmascript/tests/js_handle_test.cpp @@ -14,8 +14,8 @@ */ #include "ecmascript/ecma_string-inl.h" +#include "ecmascript/ecma_global_storage-inl.h" #include "ecmascript/ecma_vm.h" -#include "ecmascript/global_handle_collection.h" #include "ecmascript/js_handle.h" #include "ecmascript/object_factory.h" #include "ecmascript/tests/test_helper.h" @@ -48,112 +48,50 @@ public: PandaVM *instance {nullptr}; ecmascript::EcmaHandleScope *scope {nullptr}; JSThread *thread {nullptr}; - - CVector> TestGlobalHandleNewBlock(GlobalHandleCollection global); - void TestGlobalHandleFree(GlobalHandleCollection global); }; -CVector> JSHandleTest::TestGlobalHandleNewBlock(GlobalHandleCollection global) +HWTEST_F_L0(JSHandleTest, NewGlobalHandle) { - ecmascript::EcmaHandleScope scope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - CString test = "test"; - CVector> vec; - // 10 : test case - for (int i = 0; i < 10; i++) { - test.append(ToCString(i)); - vec.push_back(global.NewHandle(factory->NewFromString(test).GetTaggedType())); - } - - [[maybe_unused]] auto storage = thread->GetGlobalHandleStorage(); - ASSERT(storage->GetNodes()->size() == 1); - return vec; -} - -HWTEST_F_L0(JSHandleTest, GlobalHandleNewBlock) -{ - GlobalHandleCollection global(thread); - CVector> vec = TestGlobalHandleNewBlock(global); + auto global = thread->GetEcmaGlobalStorage(); + uintptr_t globalString = 0; + { + [[maybe_unused]] EcmaHandleScope scope(thread); + auto string1 = factory->NewFromString("test1"); + globalString = global->NewGlobalHandle(string1.GetTaggedType()); + } // trigger GC - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - factory->NewFromString("trigger gc"); + thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); - for (auto v : vec) { - global.Dispose(v); - } + // check result + EXPECT_TRUE(factory->NewFromString("test1")->Compare(*reinterpret_cast(globalString)) == 0); } -void JSHandleTest::TestGlobalHandleFree(GlobalHandleCollection global) +HWTEST_F_L0(JSHandleTest, NewWeakGlobalHandle) { - EcmaHandleScope scope(thread); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - CString test = "test"; - // 10 : test case - for (int i = 0; i < 10; i++) { - test.append(ToCString(i)); - JSHandle str = global.NewHandle(factory->NewFromString(test).GetTaggedType()); - global.Dispose(str); - } - - [[maybe_unused]] auto storage = thread->GetGlobalHandleStorage(); - ASSERT(storage->GetNodes()->size() == 1); -} + auto global = thread->GetEcmaGlobalStorage(); -HWTEST_F_L0(JSHandleTest, GlobalHandleFree) -{ - GlobalHandleCollection global(thread); - TestGlobalHandleFree(global); -} - -HWTEST_F_L0(JSHandleTest, HandleScopeFree) -{ - // enable this check after add zapfree in ecma handlescope - JSHandle string = thread->GetEcmaVM()->GetFactory()->NewFromString("test1"); + uintptr_t globalString = 0; { - ecmascript::EcmaHandleScope scope(thread); - JSHandle string2 = thread->GetEcmaVM()->GetFactory()->NewFromString("test2"); - string = string2; - } -} + [[maybe_unused]] EcmaHandleScope scope(thread); + auto string1 = factory->NewFromString("test1"); + globalString = global->NewGlobalHandle(string1.GetTaggedType()); + globalString = global->SetWeak(globalString); -HWTEST_F_L0(JSHandleTest, NewHandle) -{ - JSHandle string = thread->GetEcmaVM()->GetFactory()->NewFromString("test1"); - JSHandle string2(string); - JSHandle string3 = thread->GetEcmaVM()->GetFactory()->NewFromString("test2"); - string = string3; - ASSERT_TRUE(string2.GetTaggedValue().GetTaggedObject() != string.GetTaggedValue().GetTaggedObject()); - JSMutableHandle mutable_string( - thread, thread->GetEcmaVM()->GetFactory()->NewFromString("test1").GetTaggedValue()); - JSHandle mutable_string2(mutable_string); - JSHandle mutable_string3 = thread->GetEcmaVM()->GetFactory()->NewFromString("test2"); - mutable_string.Update(mutable_string3.GetTaggedValue()); - ASSERT_TRUE(mutable_string.GetTaggedValue().GetTaggedObject() == - mutable_string2.GetTaggedValue().GetTaggedObject()); -} - -HWTEST_F_L0(JSHandleTest, NewHandleScope) -{ - EcmaHandleScope scope(thread); + // trigger GC + thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); - JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromString("test"); - for (int32_t i = 10; i > 0; i--) { - JSHandle(thread, str.GetTaggedValue()); + // check result + EXPECT_TRUE(factory->NewFromString("test1")->Compare(*reinterpret_cast(globalString)) == 0); + EXPECT_TRUE(global->IsWeak(globalString)); } + // trigger GC + thread->GetEcmaVM()->CollectGarbage(TriggerGCType::COMPRESS_FULL_GC); - for (int i = 5; i > 0; i--) { - int32_t loop = 2; - while (loop) { - ecmascript::EcmaHandleScope scope2(thread); - - JSHandle str2 = thread->GetEcmaVM()->GetFactory()->NewFromString("test2"); - for (int32_t i = 1024; i > 0; i--) { - JSHandle(thread, str.GetTaggedValue()); - } - str2 = thread->GetEcmaVM()->GetFactory()->NewFromString("test3"); - loop--; - } - } + // check weak reference + JSTaggedType result = *reinterpret_cast(globalString); + EXPECT_TRUE(result == JSTaggedValue::Undefined().GetRawData()); } } // namespace panda::test diff --git a/ecmascript/tests/js_map_test.cpp b/ecmascript/tests/js_map_test.cpp index 42d8727996ebca4f0f9e8e0d48ec6c310f8b5e65..5699a2989fb9b04f88909b9fa8bbb87fae54cb4d 100644 --- a/ecmascript/tests/js_map_test.cpp +++ b/ecmascript/tests/js_map_test.cpp @@ -85,7 +85,7 @@ HWTEST_F_L0(JSMapTest, AddAndHas) // create jsMap JSHandle map(thread, CreateMap()); - JSHandle key(factory->NewFromString("key")); + JSHandle key(factory->NewFromCanBeCompressString("key")); JSHandle value(thread, JSTaggedValue(1)); JSMap::Set(thread, map, key, value); EXPECT_TRUE(map->Has(key.GetTaggedValue())); @@ -101,7 +101,7 @@ HWTEST_F_L0(JSMapTest, DeleteAndGet) char keyArray[] = "key0"; for (int i = 0; i < 40; i++) { keyArray[3] = '1' + i; - JSHandle key(factory->NewFromString(keyArray)); + JSHandle key(factory->NewFromCanBeCompressString(keyArray)); JSHandle value(thread, JSTaggedValue(i)); JSMap::Set(thread, map, key, value); EXPECT_TRUE(map->Has(key.GetTaggedValue())); @@ -109,7 +109,7 @@ HWTEST_F_L0(JSMapTest, DeleteAndGet) EXPECT_EQ(map->GetSize(), 40); // whether jsMap has delete key keyArray[3] = '1' + 8; - JSHandle deleteKey(factory->NewFromString(keyArray)); + JSHandle deleteKey(factory->NewFromCanBeCompressString(keyArray)); EXPECT_EQ(map->GetValue(8), JSTaggedValue(8)); JSMap::Delete(thread, map, deleteKey); EXPECT_FALSE(map->Has(deleteKey.GetTaggedValue())); diff --git a/ecmascript/tests/js_object_test.cpp b/ecmascript/tests/js_object_test.cpp index 313aabf72342136ba7a9d6901bbd8b1e7dba2f15..e004cb4da561362eefd63258770dca0a30398055 100644 --- a/ecmascript/tests/js_object_test.cpp +++ b/ecmascript/tests/js_object_test.cpp @@ -86,7 +86,7 @@ HWTEST_F_L0(JSObjectTest, SetProperty) EXPECT_TRUE(*jsobject != nullptr); char array[] = "x"; - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString(array)); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(array)); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(jsobject), key, value); @@ -105,7 +105,7 @@ HWTEST_F_L0(JSObjectTest, GetProperty) EXPECT_TRUE(*obj != nullptr); char array[] = "x"; - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString(array)); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(array)); JSHandle value(thread, JSTaggedValue(1)); EXPECT_TRUE(JSObject::GetProperty(thread, JSHandle(obj), key).GetValue()->IsUndefined()); @@ -122,7 +122,7 @@ HWTEST_F_L0(JSObjectTest, DeleteProperty) EXPECT_TRUE(*obj != nullptr); char array[] = "print"; - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString(array)); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(array)); JSHandle value(thread, JSTaggedValue(1)); JSObject::DeleteProperty(thread, (obj), key); @@ -131,7 +131,7 @@ HWTEST_F_L0(JSObjectTest, DeleteProperty) JSObject::SetProperty(thread, JSHandle(obj), key, value); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(obj), key).GetValue()->GetInt(), 1); - JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromString("print_test")); + JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("print_test")); JSObject::SetProperty(thread, JSHandle(obj), key2, JSHandle(thread, JSTaggedValue(10))); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(obj), key2).GetValue()->GetInt(), 10); @@ -145,8 +145,8 @@ HWTEST_F_L0(JSObjectTest, DeletePropertyGlobal) { JSHandle globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle global(thread, globalEnv->GetGlobalObject()); - JSHandle printKey(thread->GetEcmaVM()->GetFactory()->NewFromString("print")); - JSHandle printTestKey(thread->GetEcmaVM()->GetFactory()->NewFromString("print_test")); + JSHandle printKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("print")); + JSHandle printTestKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("print_test")); JSHandle value = JSObject::GetProperty(thread, global, printKey).GetValue(); @@ -166,9 +166,9 @@ HWTEST_F_L0(JSObjectTest, GetPropertyInPrototypeChain) JSHandle father = JSObject::ObjectCreate(thread, grandfather); JSHandle son = JSObject::ObjectCreate(thread, father); - JSHandle sonKey(thread->GetEcmaVM()->GetFactory()->NewFromString("key1")); - JSHandle fatherKey(thread->GetEcmaVM()->GetFactory()->NewFromString("key2")); - JSHandle grandfatherKey(thread->GetEcmaVM()->GetFactory()->NewFromString("key3")); + JSHandle sonKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key1")); + JSHandle fatherKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key2")); + JSHandle grandfatherKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key3")); JSHandle sonValue(thread, JSTaggedValue(1)); JSHandle fatherValue(thread, JSTaggedValue(2)); JSHandle grandfatherValue(thread, JSTaggedValue(3)); @@ -193,8 +193,8 @@ HWTEST_F_L0(JSObjectTest, PropertyAttribute) JSHandle obj2 = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(constructor), constructor); - JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString("key3")); - JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromString("key3")); + JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key3")); + JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key3")); JSHandle value1(thread, JSTaggedValue(1)); JSHandle value2(thread, JSTaggedValue(2)); @@ -235,7 +235,7 @@ HWTEST_F_L0(JSObjectTest, CreateDataProperty) EXPECT_TRUE(*obj != nullptr); char array[] = "x"; - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString(array)); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(array)); JSHandle value(thread, JSTaggedValue(1)); bool success = JSObject::CreateDataProperty(thread, obj, key, value); @@ -260,7 +260,7 @@ HWTEST_F_L0(JSObjectTest, CreateMethodProperty) EXPECT_TRUE(*obj != nullptr); char array[] = "x"; - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString(array)); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(array)); JSHandle value(thread, JSTaggedValue(1)); bool success = JSObject::CreateMethodProperty(thread, obj, key, value); @@ -285,7 +285,7 @@ HWTEST_F_L0(JSObjectTest, DefinePropertyOrThrow) EXPECT_TRUE(*obj != nullptr); char array[] = "x"; - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString(array)); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(array)); PropertyDescriptor desc1(thread, JSHandle(thread, JSTaggedValue(1)), true, true, true); bool success = JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle(obj), key, desc1); @@ -336,7 +336,7 @@ HWTEST_F_L0(JSObjectTest, HasProperty) EXPECT_TRUE(*obj != nullptr); char array[] = "x"; - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString(array)); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(array)); JSHandle value(thread, JSTaggedValue(1)); bool flag = JSObject::HasProperty(thread, obj, key); @@ -363,9 +363,9 @@ HWTEST_F_L0(JSObjectTest, HasPropertyWithProtoType) auto testSon = son->GetPrototype(thread); EXPECT_TRUE(testSon != testFather); EXPECT_TRUE(testGrand != testFather); - JSHandle sonKey(thread->GetEcmaVM()->GetFactory()->NewFromString("key1")); - JSHandle fatherKey(thread->GetEcmaVM()->GetFactory()->NewFromString("key2")); - JSHandle grandfatherKey(thread->GetEcmaVM()->GetFactory()->NewFromString("key3")); + JSHandle sonKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key1")); + JSHandle fatherKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key2")); + JSHandle grandfatherKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key3")); JSHandle sonValue(thread, JSTaggedValue(1)); JSHandle fatherValue(thread, JSTaggedValue(2)); JSHandle grandfatherValue(thread, JSTaggedValue(3)); @@ -389,9 +389,9 @@ HWTEST_F_L0(JSObjectTest, HasOwnProperty) JSHandle father = JSObject::ObjectCreate(thread, grandfather); JSHandle son = JSObject::ObjectCreate(thread, father); - JSHandle sonKey(thread->GetEcmaVM()->GetFactory()->NewFromString("key1")); - JSHandle fatherKey(thread->GetEcmaVM()->GetFactory()->NewFromString("key2")); - JSHandle grandfatherKey(thread->GetEcmaVM()->GetFactory()->NewFromString("key3")); + JSHandle sonKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key1")); + JSHandle fatherKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key2")); + JSHandle grandfatherKey(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key3")); JSHandle sonValue(thread, JSTaggedValue(1)); JSHandle fatherValue(thread, JSTaggedValue(2)); JSHandle grandfatherValue(thread, JSTaggedValue(3)); @@ -414,10 +414,10 @@ HWTEST_F_L0(JSObjectTest, GetOwnPropertyKeys) JSHandle obj = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(constructor), constructor); - JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString("x")); - JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromString("y")); - JSHandle key3(thread->GetEcmaVM()->GetFactory()->NewFromString("3")); - JSHandle key4(thread->GetEcmaVM()->GetFactory()->NewFromString("4")); + JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("x")); + JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("y")); + JSHandle key3(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("3")); + JSHandle key4(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("4")); JSHandle value1(thread, JSTaggedValue(1)); JSHandle value2(thread, JSTaggedValue(2)); JSHandle value3(thread, JSTaggedValue(3)); @@ -459,7 +459,7 @@ HWTEST_F_L0(JSObjectTest, GetMethod) JSHandle func(thread->GetEcmaVM()->GetFactory()->NewJSFunction(env)); JSHandle::Cast(func)->GetJSHClass()->SetCallable(true); EXPECT_TRUE(*func != nullptr); - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("1")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1")); JSObject::SetProperty(thread, JSHandle(obj), key, func); EXPECT_EQ(JSObject::GetProperty(thread, JSHandle(obj), key).GetValue().GetTaggedValue(), func.GetTaggedValue()); @@ -473,7 +473,7 @@ HWTEST_F_L0(JSObjectTest, EnumerableOwnNames) EXPECT_TRUE(*obj != nullptr); CString tagCStr = "x"; - JSHandle tagString = thread->GetEcmaVM()->GetFactory()->NewFromString(&tagCStr[0]); + JSHandle tagString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(&tagCStr[0]); JSHandle key(tagString); JSHandle value(thread, JSTaggedValue(1)); @@ -513,7 +513,7 @@ HWTEST_F_L0(JSObjectTest, SetIntegrityLevelSealed) thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); EXPECT_TRUE(*obj1 != nullptr); CString undefinedCStr = "x"; - JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString(&undefinedCStr[0])); + JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(&undefinedCStr[0])); JSHandle value1(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(obj1), key1, value1); @@ -539,7 +539,7 @@ HWTEST_F_L0(JSObjectTest, SetIntegrityLevelFrozen) EXPECT_TRUE(*obj1 != nullptr); CString undefinedCStr = "x"; - JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString(&undefinedCStr[0])); + JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(&undefinedCStr[0])); JSHandle value1(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(obj1), key1, value1); @@ -562,7 +562,7 @@ HWTEST_F_L0(JSObjectTest, TestIntegrityLevelSealed) JSHandle obj1 = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); CString undefinedCStr = "level"; - JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString(&undefinedCStr[0])); + JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(&undefinedCStr[0])); JSHandle value1(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(obj1), key1, value1); obj1->GetJSHClass()->SetExtensible(false); @@ -586,7 +586,7 @@ HWTEST_F_L0(JSObjectTest, TestIntegrityLevelFrozen) JSHandle obj1 = thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); CString undefinedCStr = "level"; - JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString(&undefinedCStr[0])); + JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(&undefinedCStr[0])); JSHandle value1(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(obj1), key1, value1); obj1->GetJSHClass()->SetExtensible(false); @@ -611,7 +611,7 @@ HWTEST_F_L0(JSObjectTest, TestIntegrityLevelWithoutProperty) thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1)); JSHandle::Cast(obj1)->GetJSHClass()->SetExtensible(false); CString undefinedCStr = "level"; - JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromString(&undefinedCStr[0])); + JSHandle key1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(&undefinedCStr[0])); // test SetIntegrityLevel::FROZEN JSHandle jsobject(obj1); @@ -630,7 +630,7 @@ JSTaggedValue TestGetter(EcmaRuntimeCallInfo *argv) auto thread = argv->GetThread(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle obj(BuiltinsBase::GetThis(argv)); - JSHandle key(factory->NewFromString("y")); + JSHandle key(factory->NewFromCanBeCompressString("y")); JSTaggedValue value = JSObject::GetProperty(thread, JSHandle(obj), key).GetValue().GetTaggedValue(); return JSTaggedValue(value.GetInt() + 1); @@ -641,8 +641,8 @@ HWTEST_F_L0(JSObjectTest, Getter) JSHandle dynclass1(thread, JSObjectTestCreate(thread)); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); - JSHandle key1(factory->NewFromString("x")); - JSHandle key2(factory->NewFromString("y")); + JSHandle key1(factory->NewFromCanBeCompressString("x")); + JSHandle key2(factory->NewFromCanBeCompressString("y")); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle getter = thread->GetEcmaVM()->GetFactory()->NewJSFunction(env, reinterpret_cast(TestGetter)); @@ -666,7 +666,7 @@ JSTaggedValue TestSetter(EcmaRuntimeCallInfo *argv) JSThread *thread = argv->GetThread(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle obj(BuiltinsBase::GetThis(argv)); - JSHandle key(factory->NewFromString("y")); + JSHandle key(factory->NewFromCanBeCompressString("y")); JSTaggedValue value(JSObject::GetProperty(thread, JSHandle(obj), key).GetValue().GetTaggedValue()); JSHandle valueHandle(thread, JSTaggedValue(value.GetInt() + 1)); JSObject::SetProperty(thread, JSHandle(obj), key, valueHandle); @@ -679,8 +679,8 @@ HWTEST_F_L0(JSObjectTest, Setter) JSHandle dynclass1(thread, JSObjectTestCreate(thread)); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); - JSHandle key1(factory->NewFromString("x")); - JSHandle key2(factory->NewFromString("y")); + JSHandle key1(factory->NewFromCanBeCompressString("x")); + JSHandle key2(factory->NewFromCanBeCompressString("y")); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle setter = thread->GetEcmaVM()->GetFactory()->NewJSFunction(env, reinterpret_cast(TestSetter)); @@ -751,7 +751,7 @@ HWTEST_F_L0(JSObjectTest, GetterIsUndefined) JSHandle dynclass1(thread, JSObjectTestCreate(thread)); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); - JSHandle key(factory->NewFromString("property")); + JSHandle key(factory->NewFromCanBeCompressString("property")); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle getter = thread->GetEcmaVM()->GetFactory()->NewJSFunction(env, reinterpret_cast(TestUndefinedGetter)); @@ -784,7 +784,7 @@ HWTEST_F_L0(JSObjectTest, SetterIsUndefined) JSHandle dynclass1(thread, JSObjectTestCreate(thread)); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(dynclass1), dynclass1); - JSHandle key(factory->NewFromString("property")); + JSHandle key(factory->NewFromCanBeCompressString("property")); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle getter = thread->GetEcmaVM()->GetFactory()->NewJSFunction(env, reinterpret_cast(TestUndefinedGetter)); @@ -821,9 +821,9 @@ HWTEST_F_L0(JSObjectTest, HClass) JSHandle obj1 = factory->NewJSObjectByConstructor(JSHandle(objFunc), objFunc); JSHandle hc0(thread, obj1->GetJSHClass()); - JSHandle key1(factory->NewFromString("x")); - JSHandle key2(factory->NewFromString("y")); - JSHandle key3(factory->NewFromString("z")); + JSHandle key1(factory->NewFromCanBeCompressString("x")); + JSHandle key2(factory->NewFromCanBeCompressString("y")); + JSHandle key3(factory->NewFromCanBeCompressString("z")); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, JSHandle(obj1), key1, value); @@ -868,7 +868,7 @@ HWTEST_F_L0(JSObjectTest, FastToSlow) JSHandle objFunc(thread, JSObjectTestCreate(thread)); JSHandle obj1 = factory->NewJSObjectByConstructor(JSHandle(objFunc), objFunc); - JSMutableHandle key(factory->NewFromString("x")); + JSMutableHandle key(factory->NewFromCanBeCompressString("x")); JSMutableHandle number(thread, JSTaggedValue(0)); JSMutableHandle newkey(thread, JSTaggedValue(0)); JSHandle value(thread, JSTaggedValue(1)); @@ -905,7 +905,7 @@ HWTEST_F_L0(JSObjectTest, DeleteMiddle) JSHandle objFunc(thread, JSObjectTestCreate(thread)); JSHandle obj1 = factory->NewJSObjectByConstructor(JSHandle(objFunc), objFunc); - JSMutableHandle key(factory->NewFromString("x")); + JSMutableHandle key(factory->NewFromCanBeCompressString("x")); JSMutableHandle number(thread, JSTaggedValue(0)); JSMutableHandle newkey(thread, JSTaggedValue(0)); JSHandle value(thread, JSTaggedValue(1)); @@ -920,7 +920,7 @@ HWTEST_F_L0(JSObjectTest, DeleteMiddle) EXPECT_FALSE(TaggedArray::Cast(obj1->GetProperties().GetTaggedObject())->IsDictionaryMode()); - JSMutableHandle key5(factory->NewFromString("x5")); + JSMutableHandle key5(factory->NewFromCanBeCompressString("x5")); JSObject::DeleteProperty(thread, (obj1), key5); EXPECT_TRUE(TaggedArray::Cast(obj1->GetProperties().GetTaggedObject())->IsDictionaryMode()); @@ -937,7 +937,7 @@ HWTEST_F_L0(JSObjectTest, ElementFastToSlow) JSHandle key1(thread, JSTaggedValue(1)); JSHandle key2(thread, JSTaggedValue(2)); JSHandle key2000(thread, JSTaggedValue(2000)); - JSHandle keyStr(factory->NewFromString("str")); + JSHandle keyStr(factory->NewFromCanBeCompressString("str")); // test dictionary [0,1,2,...,2000] JSHandle obj1 = factory->NewJSObjectByConstructor(JSHandle(objFunc), objFunc); @@ -1004,9 +1004,9 @@ HWTEST_F_L0(JSObjectTest, EnableProtoChangeMarker) JSHandle obj2 = JSObject::ObjectCreate(thread, obj1); JSHandle obj3 = JSObject::ObjectCreate(thread, obj2); - JSHandle obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key1")); - JSHandle obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key2")); - JSHandle obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key3")); + JSHandle obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key1")); + JSHandle obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key2")); + JSHandle obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key3")); JSHandle obj1Value(thread, JSTaggedValue(1)); JSHandle obj2Value(thread, JSTaggedValue(2)); JSHandle obj3Value(thread, JSTaggedValue(3)); @@ -1054,13 +1054,13 @@ HWTEST_F_L0(JSObjectTest, BuildRegisterTree) JSHandle obj6 = JSObject::ObjectCreate(thread, obj2); JSHandle obj7 = JSObject::ObjectCreate(thread, obj6); - JSHandle obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key1")); - JSHandle obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key2")); - JSHandle obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key3")); - JSHandle obj4Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key4")); - JSHandle obj5Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key5")); - JSHandle obj6Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key6")); - JSHandle obj7Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key7")); + JSHandle obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key1")); + JSHandle obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key2")); + JSHandle obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key3")); + JSHandle obj4Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key4")); + JSHandle obj5Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key5")); + JSHandle obj6Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key6")); + JSHandle obj7Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key7")); JSHandle obj1Value(thread, JSTaggedValue(1)); JSHandle obj2Value(thread, JSTaggedValue(2)); @@ -1137,13 +1137,13 @@ HWTEST_F_L0(JSObjectTest, NoticeThroughChain) JSHandle obj6 = JSObject::ObjectCreate(thread, obj2); JSHandle obj7 = JSObject::ObjectCreate(thread, obj6); - JSHandle obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key1")); - JSHandle obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key2")); - JSHandle obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key3")); - JSHandle obj4Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key4")); - JSHandle obj5Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key5")); - JSHandle obj6Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key6")); - JSHandle obj7Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key7")); + JSHandle obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key1")); + JSHandle obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key2")); + JSHandle obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key3")); + JSHandle obj4Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key4")); + JSHandle obj5Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key5")); + JSHandle obj6Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key6")); + JSHandle obj7Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key7")); JSHandle obj1Value(thread, JSTaggedValue(1)); JSHandle obj2Value(thread, JSTaggedValue(2)); @@ -1212,13 +1212,13 @@ HWTEST_F_L0(JSObjectTest, ChangeProtoAndNoticeTheChain) JSHandle obj6 = JSObject::ObjectCreate(thread, obj2); JSHandle obj7 = JSObject::ObjectCreate(thread, obj6); - JSHandle obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key1")); - JSHandle obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key2")); - JSHandle obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key3")); - JSHandle obj4Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key4")); - JSHandle obj5Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key5")); - JSHandle obj6Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key6")); - JSHandle obj7Key(thread->GetEcmaVM()->GetFactory()->NewFromString("key7")); + JSHandle obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key1")); + JSHandle obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key2")); + JSHandle obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key3")); + JSHandle obj4Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key4")); + JSHandle obj5Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key5")); + JSHandle obj6Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key6")); + JSHandle obj7Key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key7")); JSHandle obj1Value(thread, JSTaggedValue(1)); JSHandle obj2Value(thread, JSTaggedValue(2)); @@ -1293,4 +1293,21 @@ HWTEST_F_L0(JSObjectTest, ChangeProtoAndNoticeTheChain) EXPECT_TRUE(result4 == obj4Dynclass.GetTaggedValue()); EXPECT_TRUE(result6 == obj6Dynclass.GetTaggedValue()); } + +HWTEST_F_L0(JSObjectTest, NativePointerField) +{ + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle objFunc(thread, JSObjectTestCreate(thread)); + JSHandle obj = factory->NewJSObjectByConstructor(JSHandle(objFunc), objFunc); + obj->SetHash(87); + EXPECT_TRUE(obj->GetHash() == 87); + + obj->SetNativePointerFieldCount(1); + char array[] = "Hello World!"; + obj->SetNativePointerField(0, array); + int32_t count = obj->GetNativePointerFieldCount(); + EXPECT_TRUE(count == 1); + void *pointer = obj->GetNativePointerField(0); + EXPECT_TRUE(pointer == array); +} } // namespace panda::test diff --git a/ecmascript/tests/js_primitive_ref_test.cpp b/ecmascript/tests/js_primitive_ref_test.cpp index 012404989573eef978dfd7ca79822e23e7663dd8..d1591915c227eed427d27147c59509eea333d9e9 100644 --- a/ecmascript/tests/js_primitive_ref_test.cpp +++ b/ecmascript/tests/js_primitive_ref_test.cpp @@ -56,17 +56,17 @@ public: HWTEST_F_L0(JSPrimitiveRefTest, StringCreate) { - JSHandle hello(thread->GetEcmaVM()->GetFactory()->NewFromString("hello")); + JSHandle hello(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("hello")); JSHandle str(JSPrimitiveRef::StringCreate(thread, hello)); - JSHandle idx(thread->GetEcmaVM()->GetFactory()->NewFromString("0")); + JSHandle idx(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0")); bool status = JSPrimitiveRef::HasProperty(thread, str, idx); ASSERT_TRUE(status); PropertyDescriptor desc(thread); status = JSPrimitiveRef::GetOwnProperty(thread, str, idx, desc); ASSERT_TRUE(status); - JSHandle h = thread->GetEcmaVM()->GetFactory()->NewFromString("h"); + JSHandle h = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("h"); JSHandle h2 = JSTaggedValue::ToString(thread, desc.GetValue()); ASSERT_TRUE(h->Compare(*h2) == 0); } diff --git a/ecmascript/tests/js_promise_test.cpp b/ecmascript/tests/js_promise_test.cpp index c93a6c13fee8c3175ab51339081e6d6b1f493c98..4ffbb4c7913f869464269a3e88a5db6c7cbcbc72 100644 --- a/ecmascript/tests/js_promise_test.cpp +++ b/ecmascript/tests/js_promise_test.cpp @@ -13,16 +13,16 @@ * limitations under the License. */ -#include "ecmascript/tests/test_helper.h" - #include "ecmascript/base/builtins_base.h" #include "ecmascript/ecma_runtime_call_info.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env.h" +#include "ecmascript/internal_call_params.h" #include "ecmascript/js_function.h" #include "ecmascript/js_promise.h" #include "ecmascript/js_thread.h" #include "ecmascript/object_factory.h" +#include "ecmascript/tests/test_helper.h" using namespace panda::ecmascript; using namespace panda::ecmascript::base; @@ -98,7 +98,6 @@ HWTEST_F_L0(JSPromiseTest, FullFillPromise) { EcmaVM *ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); - ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle promise = env->GetPromiseFunction(); JSHandle capbility = JSPromise::NewPromiseCapability(thread, promise); JSHandle newPromise(thread, capbility->GetPromise()); @@ -107,12 +106,11 @@ HWTEST_F_L0(JSPromiseTest, FullFillPromise) true); EXPECT_EQ(newPromise->GetPromiseResult().IsUndefined(), true); - array_size_t length = 1; - JSHandle array = factory->NewTaggedArray(length); - array->Set(thread, 0, JSTaggedValue(33)); JSHandle resolve(thread, capbility->GetResolve()); JSHandle undefined(thread, JSTaggedValue::Undefined()); - JSFunction::Call(thread, resolve, undefined, array); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(33)); + JSFunction::Call(thread, resolve, undefined, 1, arguments->GetArgv()); EXPECT_EQ(JSTaggedValue::SameValue(newPromise->GetPromiseState(), JSTaggedValue(static_cast(PromiseStatus::FULFILLED))), true); @@ -123,7 +121,6 @@ HWTEST_F_L0(JSPromiseTest, RejectPromise) { EcmaVM *ecmaVM = thread->GetEcmaVM(); JSHandle env = ecmaVM->GetGlobalEnv(); - ObjectFactory *factory = ecmaVM->GetFactory(); JSHandle promise = env->GetPromiseFunction(); JSHandle capbility = JSPromise::NewPromiseCapability(thread, promise); JSHandle newPromise(thread, capbility->GetPromise()); @@ -132,12 +129,11 @@ HWTEST_F_L0(JSPromiseTest, RejectPromise) true); EXPECT_EQ(newPromise->GetPromiseResult().IsUndefined(), true); - array_size_t length = 1; - JSHandle array = factory->NewTaggedArray(length); - array->Set(thread, 0, JSTaggedValue(44)); JSHandle reject(thread, capbility->GetReject()); JSHandle undefined(thread, JSTaggedValue::Undefined()); - JSFunction::Call(thread, reject, undefined, array); + InternalCallParams *arguments = thread->GetInternalCallParams(); + arguments->MakeArgv(JSTaggedValue(44)); + JSFunction::Call(thread, reject, undefined, 1, arguments->GetArgv()); EXPECT_EQ(JSTaggedValue::SameValue(newPromise->GetPromiseState(), JSTaggedValue(static_cast(PromiseStatus::REJECTED))), true); diff --git a/ecmascript/tests/js_proxy_test.cpp b/ecmascript/tests/js_proxy_test.cpp index eaf16495beda4cbfbcb6f23b032922989e2fd6d8..19913dc0015a49809d74488ca8029791a8e2e673 100644 --- a/ecmascript/tests/js_proxy_test.cpp +++ b/ecmascript/tests/js_proxy_test.cpp @@ -70,7 +70,7 @@ HWTEST_F_L0(JSProxyTest, ProxyCreate) JSHandle targetHandle( thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle::Cast(dynclass), dynclass)); - JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromString("x")); + JSHandle key(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("x")); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, targetHandle, key, value); EXPECT_EQ(JSObject::GetProperty(thread, targetHandle, key).GetValue()->GetInt(), 1); @@ -103,7 +103,7 @@ HWTEST_F_L0(JSProxyTest, GetProperty) JSHandle targetHandle(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); EXPECT_TRUE(targetHandle->IsECMAObject()); - JSHandle key(factory->NewFromString("x")); + JSHandle key(factory->NewFromCanBeCompressString("x")); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, targetHandle, key, value); EXPECT_EQ(JSObject::GetProperty(thread, targetHandle, key).GetValue()->GetInt(), 1); @@ -125,7 +125,7 @@ HWTEST_F_L0(JSProxyTest, GetProperty) JSHandle proxyHandle2(JSProxy::ProxyCreate(thread, targetHandle, handlerHandle)); EXPECT_TRUE(*proxyHandle2 != nullptr); - JSHandle key2(factory->NewFromString("y")); + JSHandle key2(factory->NewFromCanBeCompressString("y")); EXPECT_EQ(JSProxy::GetProperty(thread, proxyHandle2, key2).GetValue()->GetInt(), 10); } @@ -144,7 +144,7 @@ HWTEST_F_L0(JSProxyTest, GetOwnProperty) JSHandle targetHandle(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); EXPECT_TRUE(targetHandle->IsECMAObject()); - JSHandle key(factory->NewFromString("x")); + JSHandle key(factory->NewFromCanBeCompressString("x")); JSHandle value(thread, JSTaggedValue(1)); JSObject::SetProperty(thread, targetHandle, key, value); EXPECT_EQ(JSObject::GetProperty(thread, targetHandle, key).GetValue()->GetInt(), 1); @@ -168,7 +168,7 @@ HWTEST_F_L0(JSProxyTest, GetOwnProperty) JSHandle proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle); EXPECT_TRUE(*proxyHandle2 != nullptr); - JSHandle key2(factory->NewFromString("y")); + JSHandle key2(factory->NewFromCanBeCompressString("y")); PropertyDescriptor desc2(thread); EXPECT_FALSE(JSProxy::GetOwnProperty(thread, proxyHandle2, key2, desc2)); } @@ -188,7 +188,7 @@ HWTEST_F_L0(JSProxyTest, SetProperty) JSHandle targetHandle(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); EXPECT_TRUE(targetHandle->IsECMAObject()); - JSHandle key(factory->NewFromString("x")); + JSHandle key(factory->NewFromCanBeCompressString("x")); JSHandle value(thread, JSTaggedValue(1)); JSHandle handlerHandle(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); @@ -229,7 +229,7 @@ HWTEST_F_L0(JSProxyTest, DefineOwnProperty) JSHandle targetHandle(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); EXPECT_TRUE(targetHandle->IsECMAObject()); - JSHandle key(factory->NewFromString("x")); + JSHandle key(factory->NewFromCanBeCompressString("x")); JSHandle value(thread, JSTaggedValue(1)); JSHandle handlerHandle(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); @@ -271,7 +271,7 @@ HWTEST_F_L0(JSProxyTest, DeleteProperty) JSHandle targetHandle(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); EXPECT_TRUE(targetHandle->IsECMAObject()); - JSHandle key(factory->NewFromString("x")); + JSHandle key(factory->NewFromCanBeCompressString("x")); JSHandle value(thread, JSTaggedValue(1)); JSHandle handlerHandle(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); @@ -467,7 +467,7 @@ HWTEST_F_L0(JSProxyTest, HasProperty) JSHandle targetHandle(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); EXPECT_TRUE(targetHandle->IsECMAObject()); - JSHandle key(factory->NewFromString("x")); + JSHandle key(factory->NewFromCanBeCompressString("x")); PropertyDescriptor desc(thread, JSHandle(thread, JSTaggedValue(1))); JSObject::DefineOwnProperty(thread, JSHandle::Cast(targetHandle), key, desc); @@ -508,7 +508,7 @@ HWTEST_F_L0(JSProxyTest, OwnPropertyKeys) JSHandle targetHandle(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); EXPECT_TRUE(targetHandle->IsECMAObject()); - JSHandle key(factory->NewFromString("x")); + JSHandle key(factory->NewFromCanBeCompressString("x")); PropertyDescriptor desc(thread, JSHandle(thread, JSTaggedValue(1))); JSObject::DefineOwnProperty(thread, JSHandle::Cast(targetHandle), key, desc); @@ -558,8 +558,8 @@ HWTEST_F_L0(JSProxyTest, Call) JSHandle proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle); EXPECT_TRUE(*proxyHandle != nullptr); - JSHandle arg = factory->EmptyArray(); - JSTaggedValue res = JSProxy::CallInternal(thread, proxyHandle, JSHandle::Cast(proxyHandle), arg); + JSTaggedValue res = + JSProxy::CallInternal(thread, proxyHandle, JSHandle::Cast(proxyHandle), 0, nullptr); JSHandle taggedRes(thread, res); EXPECT_TRUE(JSTaggedValue::SameValue(taggedRes.GetTaggedValue(), JSTaggedValue::True())); @@ -571,9 +571,8 @@ HWTEST_F_L0(JSProxyTest, Call) JSHandle proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle); EXPECT_TRUE(*proxyHandle2 != nullptr); - JSHandle arg2 = factory->EmptyArray(); JSTaggedValue res2 = - JSProxy::CallInternal(thread, proxyHandle2, JSHandle::Cast(proxyHandle2), arg2); + JSProxy::CallInternal(thread, proxyHandle2, JSHandle::Cast(proxyHandle2), 0, nullptr); JSHandle taggedRes2(thread, res2); EXPECT_TRUE(JSTaggedValue::SameValue(taggedRes2.GetTaggedValue(), JSTaggedValue::False())); @@ -586,7 +585,7 @@ JSTaggedValue HandlerConstruct([[maybe_unused]] EcmaRuntimeCallInfo *argv) JSHandle dynclass(thread, JSObjectTestCreate(thread)); JSHandle obj(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); - JSHandle key(factory->NewFromString("x")); + JSHandle key(factory->NewFromCanBeCompressString("x")); PropertyDescriptor desc(thread, JSHandle(thread, JSTaggedValue(2))); // 2 : test case JSObject::DefineOwnProperty(argv->GetThread(), JSHandle::Cast(obj), key, desc); return JSTaggedValue(obj.GetTaggedValue()); @@ -598,7 +597,7 @@ JSTaggedValue HandlerConFunc([[maybe_unused]] EcmaRuntimeCallInfo *argv) JSHandle dynclass(thread, JSObjectTestCreate(thread)); JSHandle obj(factory->NewJSObjectByConstructor(JSHandle(dynclass), dynclass)); - JSHandle key(factory->NewFromString("x")); + JSHandle key(factory->NewFromCanBeCompressString("x")); PropertyDescriptor desc(thread, JSHandle(thread, JSTaggedValue(1))); JSObject::DefineOwnProperty(argv->GetThread(), JSHandle::Cast(obj), key, desc); return JSTaggedValue(obj.GetTaggedValue()); @@ -620,10 +619,9 @@ HWTEST_F_L0(JSProxyTest, Construct) JSHandle proxyHandle = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle); EXPECT_TRUE(*proxyHandle != nullptr); - JSHandle arg = factory->EmptyArray(); - JSTaggedValue res = JSProxy::ConstructInternal(thread, proxyHandle, arg, targetHandle); + JSTaggedValue res = JSProxy::ConstructInternal(thread, proxyHandle, 0, nullptr, targetHandle); JSHandle taggedRes(thread, res); - JSHandle key(factory->NewFromString("x")); + JSHandle key(factory->NewFromCanBeCompressString("x")); EXPECT_EQ(JSObject::GetProperty(thread, taggedRes, key).GetValue()->GetInt(), 1); // 2. handler has "Construct" @@ -633,8 +631,7 @@ HWTEST_F_L0(JSProxyTest, Construct) JSHandle proxyHandle2 = JSProxy::ProxyCreate(thread, targetHandle, handlerHandle); EXPECT_TRUE(*proxyHandle2 != nullptr); - JSHandle arg2 = factory->EmptyArray(); - JSTaggedValue res2 = JSProxy::ConstructInternal(thread, proxyHandle2, arg2, targetHandle); + JSTaggedValue res2 = JSProxy::ConstructInternal(thread, proxyHandle2, 0, nullptr, targetHandle); JSHandle taggedRes2(thread, res2); EXPECT_EQ(JSObject::GetProperty(thread, taggedRes2, key).GetValue()->GetInt(), 2); } diff --git a/ecmascript/tests/js_serializer_test.cpp b/ecmascript/tests/js_serializer_test.cpp index bbe607a7f2b27e9a6bd981baaa70273ab684d5d8..e40c6341dc852fd8d3710bf3d694eb73ba790f20 100644 --- a/ecmascript/tests/js_serializer_test.cpp +++ b/ecmascript/tests/js_serializer_test.cpp @@ -21,20 +21,12 @@ #include "ecmascript/global_env.h" #include "ecmascript/js_array.h" #include "ecmascript/js_arraybuffer.h" -#include "ecmascript/js_float32_array.h" -#include "ecmascript/js_float64_array.h" #include "ecmascript/js_hclass.h" -#include "ecmascript/js_int16_array.h" -#include "ecmascript/js_int32_array.h" -#include "ecmascript/js_int8_array.h" #include "ecmascript/js_regexp.h" #include "ecmascript/js_serializer.h" #include "ecmascript/js_set.h" #include "ecmascript/js_thread.h" -#include "ecmascript/js_uint16_array.h" -#include "ecmascript/js_uint32_array.h" -#include "ecmascript/js_uint8_array.h" -#include "ecmascript/js_uint8_clamped_array.h" +#include "ecmascript/js_typed_array.h" #include "ecmascript/linked_hash_table-inl.h" #include "ecmascript/object_factory.h" #include "ecmascript/tests/test_helper.h" @@ -65,8 +57,8 @@ public: void Destroy() { delete scope; + scope = nullptr; ecmaVm->GetFactory()->SetTriggerGc(false); - auto thread = ecmaVm->GetJSThread(); thread->ClearException(); [[maybe_unused]] bool success = EcmaVM::Destroy(ecmaVm); EXPECT_TRUE(success) << "Cannot destroy Runtime"; @@ -135,8 +127,8 @@ public: { Init(); ObjectFactory *factory = ecmaVm->GetFactory(); - JSHandle key1(factory->NewFromString("x")); - JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromString("y")); + JSHandle key1(factory->NewFromCanBeCompressString("x")); + JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("y")); JSHandle value1(thread, JSTaggedValue(1)); JSHandle value2(thread, JSTaggedValue(2)); // 2 : test case @@ -172,8 +164,8 @@ public: ObjectFactory *factory = ecmaVm->GetFactory(); JSHandle value1(thread, JSTaggedValue(7)); // 7 : test case JSHandle value2(thread, JSTaggedValue(9)); // 9 : test case - JSHandle value3(factory->NewFromString("x")); - JSHandle value4(factory->NewFromString("y")); + JSHandle value3(factory->NewFromCanBeCompressString("x")); + JSHandle value4(factory->NewFromCanBeCompressString("y")); JSDeserializer deserializer(thread, data.first, data.second); JSHandle setValue = deserializer.DeserializeJSTaggedValue(); @@ -220,8 +212,8 @@ public: // test get value from array for (int i = 0; i < 20; i++) { // 20 : test case - JSHandle data = JSArray::FastGetPropertyByValue(thread, arrayValue, i); - EXPECT_EQ(i, data.GetTaggedValue().GetInt()); + JSHandle value = JSArray::FastGetPropertyByValue(thread, arrayValue, i); + EXPECT_EQ(i, value.GetTaggedValue().GetInt()); } Destroy(); } @@ -241,7 +233,7 @@ public: { Init(); const char *rawStr = "this is a test ecmaString"; - JSHandle ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromString(rawStr); + JSHandle ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(rawStr); JSDeserializer deserializer(thread, data.first, data.second); JSHandle res = deserializer.DeserializeJSTaggedValue(); @@ -340,9 +332,11 @@ public: JSHandle bufferData(thread, originArrayBuffer->GetArrayBufferData()); auto np = JSHandle::Cast(bufferData); void *buffer = np->GetExternalPointer(); + ASSERT_NE(buffer, nullptr); JSHandle resBufferData(thread, resJSArrayBuffer->GetArrayBufferData()); JSHandle resNp = JSHandle::Cast(resBufferData); void *resBuffer = resNp->GetExternalPointer(); + ASSERT_NE(resBuffer, nullptr); for (int32_t i = 0; i < resByteLength; i++) { EXPECT_TRUE(static_cast(resBuffer)[i] == static_cast(buffer)[i]) << "Not Same Buffer"; @@ -350,7 +344,7 @@ public: if (msg != nullptr) { if (memcpy_s(resBuffer, byteLength, msg, byteLength) != EOK) { - EXPECT_TRUE(false) << " memcpy error"; + EXPECT_TRUE(false) << " memcpy error!"; } } Destroy(); @@ -359,8 +353,8 @@ public: void JSRegexpTest(std::pair data) { Init(); - JSHandle pattern = thread->GetEcmaVM()->GetFactory()->NewFromString("key2"); - JSHandle flags = thread->GetEcmaVM()->GetFactory()->NewFromString("i"); + JSHandle pattern = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key2"); + JSHandle flags = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("i"); char buffer[] = "1234567"; // use char buffer to simulate byteCodeBuffer uint32_t bufferSize = 7; @@ -382,6 +376,7 @@ public: JSHandle resBufferData(thread, resJSRegexp->GetByteCodeBuffer()); JSHandle resNp = JSHandle::Cast(resBufferData); void *resBuffer = resNp->GetExternalPointer(); + ASSERT_NE(resBuffer, nullptr); for (uint32_t i = 0; i < resBufferSize; i++) { EXPECT_TRUE(static_cast(resBuffer)[i] == buffer[i]) << "Not Same ByteCode"; @@ -389,7 +384,7 @@ public: Destroy(); } - void TypedArrayTest(std::pair data, const JSHandle &originTypedArray) + void TypedArrayTest(std::pair data, const JSHandle &originTypedArray) { Init(); JSHandle originTypedArrayName(thread, originTypedArray->GetTypedArrayName()); @@ -397,7 +392,7 @@ public: JSHandle res = deserializer.DeserializeJSTaggedValue(); EXPECT_TRUE(!res.IsEmpty()) << "[Empty] Deserialize TypedArray fail"; EXPECT_TRUE(res->IsJSInt8Array()) << "[NotJSInt8Array] Deserialize TypedArray fail"; - JSHandle resJSInt8Array = JSHandle::Cast(res); + JSHandle resJSInt8Array = JSHandle::Cast(res); JSHandle typedArrayName(thread, resJSInt8Array->GetTypedArrayName()); JSTaggedValue byteLength = resJSInt8Array->GetByteLength(); @@ -490,14 +485,14 @@ HWTEST_F_L0(JSSerializerTest, SerializeJSPlainObject) JSHandle obj1 = factory->NewEmptyJSObject(); JSHandle obj2 = factory->NewEmptyJSObject(); - JSHandle key1(factory->NewFromString("2")); - JSHandle key2(factory->NewFromString("3")); - JSHandle key3(factory->NewFromString("x")); - JSHandle key4(factory->NewFromString("y")); - JSHandle key5(factory->NewFromString("a")); - JSHandle key6(factory->NewFromString("b")); - JSHandle key7(factory->NewFromString("5")); - JSHandle key8(factory->NewFromString("6")); + JSHandle key1(factory->NewFromCanBeCompressString("2")); + JSHandle key2(factory->NewFromCanBeCompressString("3")); + JSHandle key3(factory->NewFromCanBeCompressString("x")); + JSHandle key4(factory->NewFromCanBeCompressString("y")); + JSHandle key5(factory->NewFromCanBeCompressString("a")); + JSHandle key6(factory->NewFromCanBeCompressString("b")); + JSHandle key7(factory->NewFromCanBeCompressString("5")); + JSHandle key8(factory->NewFromCanBeCompressString("6")); JSHandle value1(thread, JSTaggedValue(1)); JSHandle value2(thread, JSTaggedValue(2)); JSHandle value3(thread, JSTaggedValue(3)); @@ -533,8 +528,8 @@ HWTEST_F_L0(JSSerializerTest, TestSerializeDescription) ObjectFactory *factory = ecmaVm->GetFactory(); JSHandle obj = factory->NewEmptyJSObject(); - JSHandle key1(factory->NewFromString("x")); - JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromString("y")); + JSHandle key1(factory->NewFromCanBeCompressString("x")); + JSHandle key2(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("y")); PropertyDescriptor desc1(thread); JSHandle value1(thread, JSTaggedValue(1)); @@ -574,8 +569,8 @@ HWTEST_F_L0(JSSerializerTest, TestSerializeJSSet) // set property to set JSHandle value1(thread, JSTaggedValue(7)); JSHandle value2(thread, JSTaggedValue(9)); - JSHandle value3(factory->NewFromString("x")); - JSHandle value4(factory->NewFromString("y")); + JSHandle value3(factory->NewFromCanBeCompressString("x")); + JSHandle value4(factory->NewFromCanBeCompressString("y")); JSSet::Add(thread, set, value1); JSSet::Add(thread, set, value2); @@ -583,8 +578,8 @@ HWTEST_F_L0(JSSerializerTest, TestSerializeJSSet) JSSet::Add(thread, set, value4); // set property to object - JSHandle key1(factory->NewFromString("5")); - JSHandle key2(factory->NewFromString("6")); + JSHandle key1(factory->NewFromCanBeCompressString("5")); + JSHandle key2(factory->NewFromCanBeCompressString("6")); JSObject::SetProperty(thread, JSHandle(set), key1, value1); JSObject::SetProperty(thread, JSHandle(set), key2, value2); @@ -604,8 +599,8 @@ HWTEST_F_L0(JSSerializerTest, TestSerializeJSArray) JSHandle array = factory->NewJSArray(); // set property to object - JSHandle key1(factory->NewFromString("abasd")); - JSHandle key2(factory->NewFromString("qweqwedasd")); + JSHandle key1(factory->NewFromCanBeCompressString("abasd")); + JSHandle key2(factory->NewFromCanBeCompressString("qweqwedasd")); JSHandle value1(thread, JSTaggedValue(7)); JSHandle value2(thread, JSTaggedValue(9)); @@ -637,10 +632,10 @@ HWTEST_F_L0(JSSerializerTest, TestObjectsPropertyReference) JSHandle obj2 = factory->NewEmptyJSObject(); [[maybe_unused]] JSHandle obj3 = factory->NewEmptyJSObject(); - JSHandle key1(factory->NewFromString("abc")); - JSHandle key2(factory->NewFromString("def")); - JSHandle key3(factory->NewFromString("dgsdgf")); - JSHandle key4(factory->NewFromString("qwjhrf")); + JSHandle key1(factory->NewFromCanBeCompressString("abc")); + JSHandle key2(factory->NewFromCanBeCompressString("def")); + JSHandle key3(factory->NewFromCanBeCompressString("dgsdgf")); + JSHandle key4(factory->NewFromCanBeCompressString("qwjhrf")); JSHandle value3(thread, JSTaggedValue(10)); JSHandle value4(thread, JSTaggedValue(5)); @@ -667,7 +662,7 @@ HWTEST_F_L0(JSSerializerTest, TestObjectsPropertyReference) HWTEST_F_L0(JSSerializerTest, SerializeEcmaString) { const char *rawStr = "this is a test ecmaString"; - JSHandle ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromString(rawStr); + JSHandle ecmaString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(rawStr); JSSerializer *serializer = new JSSerializer(thread); bool success = serializer->SerializeJSTaggedValue(JSHandle(ecmaString)); EXPECT_TRUE(success) << "Serialize EcmaString fail"; @@ -746,10 +741,10 @@ HWTEST_F_L0(JSSerializerTest, SerializeJSMap) { JSHandle map(thread, CreateMap(thread)); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSHandle key1(factory->NewFromString("3")); + JSHandle key1(factory->NewFromCanBeCompressString("3")); JSHandle value1(thread, JSTaggedValue(12345)); JSMap::Set(thread, map, key1, value1); - JSHandle key2(factory->NewFromString("key1")); + JSHandle key2(factory->NewFromCanBeCompressString("key1")); JSHandle value2(thread, JSTaggedValue(34567)); JSMap::Set(thread, map, key2, value2); @@ -845,8 +840,8 @@ HWTEST_F_L0(JSSerializerTest, SerializeJSRegExp) JSHandle target = env->GetRegExpFunction(); JSHandle jsRegexp = JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); - JSHandle pattern = thread->GetEcmaVM()->GetFactory()->NewFromString("key2"); - JSHandle flags = thread->GetEcmaVM()->GetFactory()->NewFromString("i"); + JSHandle pattern = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("key2"); + JSHandle flags = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("i"); char buffer[] = "1234567"; // use char to simulate bytecode uint32_t bufferSize = 7; factory->NewJSRegExpByteCodeData(jsRegexp, static_cast(buffer), bufferSize); @@ -881,8 +876,8 @@ HWTEST_F_L0(JSSerializerTest, SerializeJSTypedArray) ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle target = env->GetInt8ArrayFunction(); - JSHandle int8Array = - JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); + JSHandle int8Array = + JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(target), target)); JSHandle viewedArrayBuffer(thread, CreateTestJSArrayBuffer(thread)); int8Array->SetViewedArrayBuffer(thread, viewedArrayBuffer); int byteLength = 10; @@ -908,7 +903,7 @@ HWTEST_F_L0(JSSerializerTest, SerializeObjectWithFunction) JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); JSHandle function = env->GetRegExpFunction(); EXPECT_TRUE(function->IsJSFunction()); - JSHandle key(factory->NewFromString("2")); + JSHandle key(factory->NewFromCanBeCompressString("2")); JSHandle obj = factory->NewEmptyJSObject(); JSObject::SetProperty(thread, JSHandle(obj), key, function); @@ -926,8 +921,8 @@ HWTEST_F_L0(JSSerializerTest, SerializeSymbolWithProperty) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle jsSymbol = factory->NewJSSymbol(); - JSHandle key1(factory->NewFromString("2")); - JSHandle key2(factory->NewFromString("x")); + JSHandle key1(factory->NewFromCanBeCompressString("2")); + JSHandle key2(factory->NewFromCanBeCompressString("x")); JSHandle value1(thread, JSTaggedValue(1)); JSHandle value2(thread, JSTaggedValue(8)); JSObject::SetProperty(thread, JSHandle(jsSymbol), key1, value1); diff --git a/ecmascript/tests/js_set_test.cpp b/ecmascript/tests/js_set_test.cpp index 1c900407b6f1e7d1de043fed7be91f17e56a340c..35c4c807b0fa8f86153648138aacb80aec343c0d 100644 --- a/ecmascript/tests/js_set_test.cpp +++ b/ecmascript/tests/js_set_test.cpp @@ -86,7 +86,7 @@ HWTEST_F_L0(JSSetTest, AddAndHas) // create jsSet JSHandle set(thread, CreateSet()); - JSHandle key(factory->NewFromString("key")); + JSHandle key(factory->NewFromCanBeCompressString("key")); JSSet::Add(thread, set, key); EXPECT_TRUE(set->Has(key.GetTaggedValue())); } @@ -101,14 +101,14 @@ HWTEST_F_L0(JSSetTest, DeleteAndGet) char keyArray[] = "key0"; for (int i = 0; i < 40; i++) { keyArray[3] = '1' + i; - JSHandle key(factory->NewFromString(keyArray)); + JSHandle key(factory->NewFromCanBeCompressString(keyArray)); JSSet::Add(thread, set, key); EXPECT_TRUE(set->Has(key.GetTaggedValue())); } EXPECT_EQ(set->GetSize(), 40); // whether jsSet has delete key keyArray[3] = '1' + 8; - JSHandle deleteKey(factory->NewFromString(keyArray)); + JSHandle deleteKey(factory->NewFromCanBeCompressString(keyArray)); JSSet::Delete(thread, set, deleteKey); EXPECT_FALSE(set->Has(deleteKey.GetTaggedValue())); EXPECT_EQ(set->GetSize(), 39); diff --git a/ecmascript/tests/js_symbol_test.cpp b/ecmascript/tests/js_symbol_test.cpp index 80e2625b723685e6b77ee0d4863148e67354ff1f..e11765d2903bbdfd786e6b1c5478d5583f5f4c6f 100644 --- a/ecmascript/tests/js_symbol_test.cpp +++ b/ecmascript/tests/js_symbol_test.cpp @@ -27,7 +27,7 @@ using LexicalEnv = panda::ecmascript::LexicalEnv; using JSHClass = panda::ecmascript::JSHClass; using ObjectFactory = panda::ecmascript::ObjectFactory; -template +template using JSHandle = panda::ecmascript::JSHandle; namespace panda::test { diff --git a/ecmascript/tests/js_verification_test.cpp b/ecmascript/tests/js_verification_test.cpp index 04336aed791f8b52d49081fc5be0d83a57357fb0..c4491b170642c9e745bc64891ec4d431673be13c 100644 --- a/ecmascript/tests/js_verification_test.cpp +++ b/ecmascript/tests/js_verification_test.cpp @@ -75,7 +75,7 @@ HWTEST_F_L0(JSVerificationTest, IsHeapAddress) }; // new space object - JSHandle string = objectFactory->NewFromString("123"); + JSHandle string = objectFactory->NewFromCanBeCompressString("123"); funcVerify(*string, verifier, heap); // old space object diff --git a/ecmascript/tests/linked_hash_table_test.cpp b/ecmascript/tests/linked_hash_table_test.cpp index 80fc2d589efb2f1773b92c6b6cc1c2e8c19928d3..aab1bcf4a19764b9ee9e0787118a06cc8a47dddc 100644 --- a/ecmascript/tests/linked_hash_table_test.cpp +++ b/ecmascript/tests/linked_hash_table_test.cpp @@ -87,12 +87,12 @@ HWTEST_F_L0(LinkedHashTableTest, addKeyAndValue) JSHandle objFun = GetGlobalEnv()->GetObjectFunction(); char keyArray[] = "hello"; - JSHandle stringKey1 = factory->NewFromString(keyArray); + JSHandle stringKey1 = factory->NewFromCanBeCompressString(keyArray); JSHandle key1(stringKey1); JSHandle value1(factory->NewJSObjectByConstructor(JSHandle(objFun), objFun)); char key2Array[] = "hello2"; - JSHandle stringKey2 = factory->NewFromString(key2Array); + JSHandle stringKey2 = factory->NewFromCanBeCompressString(key2Array); JSHandle key2(stringKey2); JSHandle value2(factory->NewJSObjectByConstructor(JSHandle(objFun), objFun)); @@ -129,12 +129,12 @@ HWTEST_F_L0(LinkedHashTableTest, SetaddKeyAndValue) JSHandle objFun = GetGlobalEnv()->GetObjectFunction(); char keyArray[] = "hello"; - JSHandle stringKey1 = factory->NewFromString(keyArray); + JSHandle stringKey1 = factory->NewFromCanBeCompressString(keyArray); JSHandle key1(stringKey1); JSHandle value1(factory->NewJSObjectByConstructor(JSHandle(objFun), objFun)); char key2Array[] = "hello2"; - JSHandle stringKey2 = factory->NewFromString(key2Array); + JSHandle stringKey2 = factory->NewFromCanBeCompressString(key2Array); JSHandle key2(stringKey2); JSHandle value2(factory->NewJSObjectByConstructor(JSHandle(objFun), objFun)); @@ -169,7 +169,7 @@ HWTEST_F_L0(LinkedHashTableTest, GrowCapacity) JSHandle dictHandle(thread, dict); keyArray[5] = '1' + i; keyArray[6] = 0; - JSHandle key(factory->NewFromString(keyArray)); + JSHandle key(factory->NewFromCanBeCompressString(keyArray)); JSHandle value(thread, JSTaggedValue(i)); // test insert() @@ -182,7 +182,7 @@ HWTEST_F_L0(LinkedHashTableTest, GrowCapacity) for (int i = 0; i < 33; i++) { keyArray[5] = '1' + i; keyArray[6] = 0; - JSHandle stringKey = factory->NewFromString(keyArray); + JSHandle stringKey = factory->NewFromCanBeCompressString(keyArray); // test insert() EXPECT_EQ(i, dictHandle->FindElement(stringKey.GetTaggedValue())); } @@ -204,7 +204,7 @@ HWTEST_F_L0(LinkedHashTableTest, SetGrowCapacity) keyArray[5] = '1' + i; keyArray[6] = 0; - JSHandle stringKey = factory->NewFromString(keyArray); + JSHandle stringKey = factory->NewFromCanBeCompressString(keyArray); JSHandle key(stringKey); // test insert() @@ -217,7 +217,7 @@ HWTEST_F_L0(LinkedHashTableTest, SetGrowCapacity) for (int i = 0; i < 33; i++) { keyArray[5] = '1' + i; keyArray[6] = 0; - JSHandle stringKey = factory->NewFromString(keyArray); + JSHandle stringKey = factory->NewFromCanBeCompressString(keyArray); // test insert() EXPECT_EQ(i, setHandle->FindElement(stringKey.GetTaggedValue())); } @@ -237,7 +237,7 @@ HWTEST_F_L0(LinkedHashTableTest, ShrinkCapacity) JSHandle dictHandle(thread, dict); keyArray[5] = '1' + i; keyArray[6] = 0; - JSHandle key(factory->NewFromString(keyArray)); + JSHandle key(factory->NewFromCanBeCompressString(keyArray)); JSHandle value(thread, JSTaggedValue(i)); // test insert() @@ -245,14 +245,14 @@ HWTEST_F_L0(LinkedHashTableTest, ShrinkCapacity) } JSHandle dictHandle(thread, dict); keyArray[5] = '1' + 9; - JSHandle key(factory->NewFromString(keyArray)); + JSHandle key(factory->NewFromCanBeCompressString(keyArray)); dict = LinkedHashMap::Cast(LinkedHashMap::Delete(thread, dictHandle, key).GetTaggedObject()); JSHandle handle(thread, dict); // test order for (int i = 0; i < 9; i++) { keyArray[5] = '1' + i; keyArray[6] = 0; - JSHandle stringKey = factory->NewFromString(keyArray); + JSHandle stringKey = factory->NewFromCanBeCompressString(keyArray); // test insert() EXPECT_EQ(i, handle->FindElement(stringKey.GetTaggedValue())); } @@ -273,21 +273,21 @@ HWTEST_F_L0(LinkedHashTableTest, SetShrinkCapacity) JSHandle setHandle(thread, set); keyArray[5] = '1' + i; keyArray[6] = 0; - JSHandle key(factory->NewFromString(keyArray)); + JSHandle key(factory->NewFromCanBeCompressString(keyArray)); // test insert() set = LinkedHashSet::Cast(LinkedHashSet::Add(thread, setHandle, key).GetTaggedObject()); } JSHandle setHandle(thread, set); keyArray[5] = '1' + 9; - JSHandle keyHandle(factory->NewFromString(keyArray)); + JSHandle keyHandle(factory->NewFromCanBeCompressString(keyArray)); set = LinkedHashSet::Cast(LinkedHashSet::Delete(thread, setHandle, keyHandle).GetTaggedObject()); JSHandle handle(thread, set); // test order for (int i = 0; i < 9; i++) { keyArray[5] = '1' + i; keyArray[6] = 0; - JSHandle stringKey = factory->NewFromString(keyArray); + JSHandle stringKey = factory->NewFromCanBeCompressString(keyArray); // test insert() EXPECT_EQ(i, handle->FindElement(stringKey.GetTaggedValue())); } diff --git a/ecmascript/tests/name_dictionary_test.cpp b/ecmascript/tests/name_dictionary_test.cpp index 2336141f547b514dfa6650e8ae3b0f6649c12ef9..cd8dbe8e7b8242936e3858546059c8e91edc0825 100644 --- a/ecmascript/tests/name_dictionary_test.cpp +++ b/ecmascript/tests/name_dictionary_test.cpp @@ -87,7 +87,7 @@ HWTEST_F_L0(NameDictionaryTest, addKeyAndValue) EXPECT_TRUE(*jsObject != nullptr); char keyArray[] = "hello"; - JSHandle stringKey1 = thread->GetEcmaVM()->GetFactory()->NewFromString(keyArray); + JSHandle stringKey1 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(keyArray); JSHandle key1(stringKey1); JSHandle taggedkey1(stringKey1); JSHandle value1( @@ -95,7 +95,7 @@ HWTEST_F_L0(NameDictionaryTest, addKeyAndValue) PropertyAttributes metaData1; char key2Array[] = "hello2"; - JSHandle stringKey2 = thread->GetEcmaVM()->GetFactory()->NewFromString(key2Array); + JSHandle stringKey2 = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(key2Array); JSHandle key2(stringKey2); JSHandle taggedkey2(stringKey2); JSHandle value2( @@ -136,7 +136,7 @@ HWTEST_F_L0(NameDictionaryTest, GrowCapacity) keyArray[5] = '1' + i; keyArray[6] = 0; - JSHandle stringKey = thread->GetEcmaVM()->GetFactory()->NewFromString(keyArray); + JSHandle stringKey = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(keyArray); ecmascript::JSHandle key(stringKey); JSHandle keyHandle(key); ecmascript::JSHandle value(thread, JSTaggedValue(i)); @@ -167,7 +167,7 @@ HWTEST_F_L0(NameDictionaryTest, ShrinkCapacity) keyArray[5] = '0' + i; keyArray[6] = 0; - JSHandle key(thread, stringTable->GetOrInternString(keyArray, utf::Mutf8Size(keyArray))); + JSHandle key(thread, stringTable->GetOrInternString(keyArray, utf::Mutf8Size(keyArray), true)); JSHandle value(thread, JSTaggedValue(i)); PropertyAttributes metaData; @@ -177,7 +177,8 @@ HWTEST_F_L0(NameDictionaryTest, ShrinkCapacity) keyArray[5] = '2'; keyArray[6] = 0; - JSHandle arrayHandle(thread, stringTable->GetOrInternString(keyArray, utf::Mutf8Size(keyArray))); + JSHandle arrayHandle(thread, + stringTable->GetOrInternString(keyArray, utf::Mutf8Size(keyArray), true)); int entry = dictHandle->FindEntry(arrayHandle.GetTaggedValue()); EXPECT_NE(entry, -1); diff --git a/ecmascript/tests/native_pointer_test.cpp b/ecmascript/tests/native_pointer_test.cpp index 4cabc96694d4c53e20a415ee454c3e31b71c393c..3b1150045cafdbf88cf2e77aa9e94e999f180164 100644 --- a/ecmascript/tests/native_pointer_test.cpp +++ b/ecmascript/tests/native_pointer_test.cpp @@ -60,7 +60,7 @@ HWTEST_F_L0(NativePointerTest, Print) char array[] = "Hello World!"; ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); - JSHandle str = factory->NewFromString(array); + JSHandle str = factory->NewFromCanBeCompressString(array); EXPECT_TRUE(*str != nullptr); JSHandle jsFunction = factory->NewJSFunction(env); diff --git a/ecmascript/tests/object_factory_test.cpp b/ecmascript/tests/object_factory_test.cpp index 8ccf0bc74bfffafb6c9c3b0b7a695b55645dc824..a71f6b396477757fe1cd4371e5acad73c6be0896 100644 --- a/ecmascript/tests/object_factory_test.cpp +++ b/ecmascript/tests/object_factory_test.cpp @@ -92,6 +92,7 @@ HWTEST_F_L0(ObjectFactoryTest, NewJSObjectByConstructor) auto *prototype = cls->GetPrototype().GetTaggedObject(); [[maybe_unused]] JSHandle newObj2 = factory->NewJSObjectByConstructor(JSHandle(objFun), objFun); + // CompressGC not the same EXPECT_TRUE(prototype != newObjCls->GetPrototype().GetTaggedObject()); } #endif diff --git a/ecmascript/tests/tagged_value_test.cpp b/ecmascript/tests/tagged_value_test.cpp index 4a012555ce9dd4a8c7e0c6b71cb11038f918403b..0cefd004dd17c2cd3806651a8c567664e9727f10 100644 --- a/ecmascript/tests/tagged_value_test.cpp +++ b/ecmascript/tests/tagged_value_test.cpp @@ -192,7 +192,7 @@ HWTEST_F_L0(JSTaggedValueTest, ToBoolean) EXPECT_TRUE(JSTaggedValue::True().ToBoolean()); EXPECT_FALSE(thread->GetEcmaVM()->GetFactory()->GetEmptyString().GetTaggedValue().ToBoolean()); - EXPECT_TRUE(thread->GetEcmaVM()->GetFactory()->NewFromString("test").GetTaggedValue().ToBoolean()); + EXPECT_TRUE(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("test").GetTaggedValue().ToBoolean()); } HWTEST_F_L0(JSTaggedValueTest, ToNumber) @@ -227,127 +227,127 @@ HWTEST_F_L0(JSTaggedValueTest, ToNumber) result = JSTaggedValue::ToNumber(thread, JSHandle(thread, trueV)); EXPECT_EQ(result.GetNumber(), 1); - JSHandle stringV0(thread->GetEcmaVM()->GetFactory()->NewFromString(" 1234 ")); + JSHandle stringV0(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 1234 ")); result = JSTaggedValue::ToNumber(thread, stringV0); EXPECT_EQ(result.GetNumber(), 1234); - JSHandle stringV1(thread->GetEcmaVM()->GetFactory()->NewFromString(" 0b1010 ")); + JSHandle stringV1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0b1010 ")); result = JSTaggedValue::ToNumber(thread, stringV1); EXPECT_EQ(result.GetNumber(), 10); - JSHandle stringV2(thread->GetEcmaVM()->GetFactory()->NewFromString(" 0O11 ")); + JSHandle stringV2(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0O11 ")); result = JSTaggedValue::ToNumber(thread, stringV2); EXPECT_EQ(result.GetNumber(), 9); - JSHandle stringV3(thread->GetEcmaVM()->GetFactory()->NewFromString(" 0x2d ")); + JSHandle stringV3(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0x2d ")); result = JSTaggedValue::ToNumber(thread, stringV3); EXPECT_EQ(result.GetNumber(), 45); - JSHandle stringV4(thread->GetEcmaVM()->GetFactory()->NewFromString(" 0.000001 ")); + JSHandle stringV4(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0.000001 ")); result = JSTaggedValue::ToNumber(thread, stringV4); EXPECT_EQ(result.GetNumber(), 0.000001); - JSHandle stringV5(thread->GetEcmaVM()->GetFactory()->NewFromString(" 1.23 ")); + JSHandle stringV5(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 1.23 ")); result = JSTaggedValue::ToNumber(thread, stringV5); EXPECT_EQ(result.GetNumber(), 1.23); - JSHandle stringV6(thread->GetEcmaVM()->GetFactory()->NewFromString(" -1.23e2 ")); + JSHandle stringV6(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" -1.23e2 ")); result = JSTaggedValue::ToNumber(thread, stringV6); EXPECT_EQ(result.GetNumber(), -123); - JSHandle stringV7(thread->GetEcmaVM()->GetFactory()->NewFromString(" -123e-2")); + JSHandle stringV7(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" -123e-2")); result = JSTaggedValue::ToNumber(thread, stringV7); EXPECT_EQ(result.GetNumber(), -1.23); - JSHandle stringV8(thread->GetEcmaVM()->GetFactory()->NewFromString(" Infinity ")); + JSHandle stringV8(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" Infinity ")); result = JSTaggedValue::ToNumber(thread, stringV8); EXPECT_TRUE(std::isinf(result.GetNumber())); - JSHandle stringV9(thread->GetEcmaVM()->GetFactory()->NewFromString("100e307")); + JSHandle stringV9(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("100e307")); result = JSTaggedValue::ToNumber(thread, stringV9); EXPECT_TRUE(std::isinf(result.GetNumber())); - JSHandle stringV10(thread->GetEcmaVM()->GetFactory()->NewFromString(" .")); + JSHandle stringV10(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" .")); result = JSTaggedValue::ToNumber(thread, stringV10); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV11(thread->GetEcmaVM()->GetFactory()->NewFromString("12e+")); + JSHandle stringV11(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("12e+")); result = JSTaggedValue::ToNumber(thread, stringV11); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV12(thread->GetEcmaVM()->GetFactory()->NewFromString(".e3")); + JSHandle stringV12(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(".e3")); result = JSTaggedValue::ToNumber(thread, stringV12); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV13(thread->GetEcmaVM()->GetFactory()->NewFromString("23eE")); + JSHandle stringV13(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("23eE")); result = JSTaggedValue::ToNumber(thread, stringV13); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV14(thread->GetEcmaVM()->GetFactory()->NewFromString("a")); + JSHandle stringV14(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("a")); result = JSTaggedValue::ToNumber(thread, stringV14); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV15(thread->GetEcmaVM()->GetFactory()->NewFromString("0o12e3")); + JSHandle stringV15(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0o12e3")); result = JSTaggedValue::ToNumber(thread, stringV15); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV16(thread->GetEcmaVM()->GetFactory()->NewFromString("0x12.3")); + JSHandle stringV16(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0x12.3")); result = JSTaggedValue::ToNumber(thread, stringV16); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV17(thread->GetEcmaVM()->GetFactory()->NewFromString(" 12.4.")); + JSHandle stringV17(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 12.4.")); result = JSTaggedValue::ToNumber(thread, stringV17); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV18(thread->GetEcmaVM()->GetFactory()->NewFromString("123test")); + JSHandle stringV18(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("123test")); result = JSTaggedValue::ToNumber(thread, stringV18); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV19(thread->GetEcmaVM()->GetFactory()->NewFromString("123test")); + JSHandle stringV19(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("123test")); result = JSTaggedValue::ToNumber(thread, stringV19); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV20(thread->GetEcmaVM()->GetFactory()->NewFromString(" 0b ")); + JSHandle stringV20(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0b ")); result = JSTaggedValue::ToNumber(thread, stringV20); EXPECT_TRUE(std::isnan(result.GetNumber())); - JSHandle stringV21(thread->GetEcmaVM()->GetFactory()->NewFromString(" 0b0000 ")); + JSHandle stringV21(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0b0000 ")); result = JSTaggedValue::ToNumber(thread, stringV21); EXPECT_EQ(result.GetNumber(), 0); - JSHandle stringV22(thread->GetEcmaVM()->GetFactory()->NewFromString(" 0o0000 ")); + JSHandle stringV22(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0o0000 ")); result = JSTaggedValue::ToNumber(thread, stringV22); EXPECT_EQ(result.GetNumber(), 0); - JSHandle stringV23(thread->GetEcmaVM()->GetFactory()->NewFromString(" 0X0000 ")); + JSHandle stringV23(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0X0000 ")); result = JSTaggedValue::ToNumber(thread, stringV23); EXPECT_EQ(result.GetNumber(), 0); - JSHandle stringV24(thread->GetEcmaVM()->GetFactory()->NewFromString(" 000.00000 ")); + JSHandle stringV24(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 000.00000 ")); result = JSTaggedValue::ToNumber(thread, stringV24); EXPECT_EQ(result.GetNumber(), 0); - JSHandle stringV25(thread->GetEcmaVM()->GetFactory()->NewFromString("")); + JSHandle stringV25(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("")); result = JSTaggedValue::ToNumber(thread, stringV25); EXPECT_EQ(result.GetNumber(), 0); - JSHandle stringV26(thread->GetEcmaVM()->GetFactory()->NewFromString(" ")); + JSHandle stringV26(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" ")); result = JSTaggedValue::ToNumber(thread, stringV26); EXPECT_EQ(result.GetNumber(), 0); - JSHandle stringV27(thread->GetEcmaVM()->GetFactory()->NewFromString("0")); + JSHandle stringV27(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0")); result = JSTaggedValue::ToNumber(thread, stringV27); EXPECT_EQ(result.GetNumber(), 0); - JSHandle stringV28(thread->GetEcmaVM()->GetFactory()->NewFromString(" 0 ")); + JSHandle stringV28(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 0 ")); result = JSTaggedValue::ToNumber(thread, stringV28); EXPECT_EQ(result.GetNumber(), 0); - JSHandle stringV29(thread->GetEcmaVM()->GetFactory()->NewFromString("00000000")); + JSHandle stringV29(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("00000000")); result = JSTaggedValue::ToNumber(thread, stringV29); EXPECT_EQ(result.GetNumber(), 0); - JSHandle stringV30(thread->GetEcmaVM()->GetFactory()->NewFromString(" 00000000 ")); + JSHandle stringV30(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(" 00000000 ")); result = JSTaggedValue::ToNumber(thread, stringV30); EXPECT_EQ(result.GetNumber(), 0); @@ -767,7 +767,7 @@ HWTEST_F_L0(JSTaggedValueTest, ToUint8Clamp) HWTEST_F_L0(JSTaggedValueTest, ToPropertyKey) { JSTaggedValue result; - JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromString("null"); + JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("null"); JSTaggedValue key = str.GetTaggedValue(); result = JSTaggedValue::ToPropertyKey(thread, JSHandle(thread, key)).GetTaggedValue(); EXPECT_TRUE(key == result); @@ -776,7 +776,7 @@ HWTEST_F_L0(JSTaggedValueTest, ToPropertyKey) void CheckOkString(JSThread *thread, const JSHandle &tagged, CString &rightCStr) { JSHandle result = JSTaggedValue::ToString(thread, tagged); - JSHandle rightString = thread->GetEcmaVM()->GetFactory()->NewFromString(rightCStr); + JSHandle rightString = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(rightCStr); EXPECT_TRUE(EcmaString::StringsAreEqual(EcmaString::Cast(result.GetObject()), EcmaString::Cast(rightString.GetObject()))); } @@ -799,8 +799,9 @@ HWTEST_F_L0(JSTaggedValueTest, ToString) CheckOkString(thread, JSHandle(thread, JSTaggedValue::False()), rightCStr); rightCStr = "hello world"; - CheckOkString(thread, JSHandle(thread->GetEcmaVM()->GetFactory()->NewFromString(rightCStr)), - rightCStr); + CheckOkString(thread, + JSHandle(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString(rightCStr)), + rightCStr); double num = 1; JSTaggedNumber numberNum = JSTaggedNumber(num); @@ -831,7 +832,7 @@ HWTEST_F_L0(JSTaggedValueTest, ToString) HWTEST_F_L0(JSTaggedValueTest, CanonicalNumericIndexString) { JSTaggedValue result; - JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromString("-0"); + JSHandle str = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-0"); JSTaggedValue tmpStr = str.GetTaggedValue(); result = JSTaggedValue::CanonicalNumericIndexString(thread, JSHandle(thread, tmpStr)); EXPECT_EQ(result.GetDouble(), -0.0); @@ -864,14 +865,14 @@ HWTEST_F_L0(JSTaggedValueTest, ToObject) JSTaggedValue(JSHandle::Cast(JSTaggedValue::ToObject(thread, value3))->GetValue()); EXPECT_EQ(tagged3.GetRawData(), JSTaggedValue::True().GetRawData()); - JSHandle value4(factory->NewFromString("aaa")); + JSHandle value4(factory->NewFromCanBeCompressString("aaa")); JSTaggedValue tagged4 = JSTaggedValue(JSHandle::Cast(JSTaggedValue::ToObject(thread, value4))->GetValue()); EXPECT_TRUE(tagged4.IsString()); EXPECT_EQ(reinterpret_cast(tagged4.GetRawData())->Compare(value4.GetObject()), 0); JSHandle symbol = factory->NewPublicSymbolWithChar("bbb"); - JSHandle str = factory->NewFromString("bbb"); + JSHandle str = factory->NewFromCanBeCompressString("bbb"); JSHandle value5(symbol); JSTaggedValue tagged5 = JSTaggedValue(JSHandle::Cast(JSTaggedValue::ToObject(thread, value5))->GetValue()); @@ -947,7 +948,8 @@ HWTEST_F_L0(JSTaggedValueTest, IsArray) ASSERT_TRUE(jsObj->IsJSArray()); ASSERT_FALSE(JSTaggedValue(1).IsArray(thread)); - ASSERT_FALSE(thread->GetEcmaVM()->GetFactory()->NewFromString("test").GetTaggedValue().IsArray(thread)); + ASSERT_FALSE( + thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("test").GetTaggedValue().IsArray(thread)); } HWTEST_F_L0(JSTaggedValueTest, IsCallable_IsConstructor_IsExtensible) @@ -988,18 +990,18 @@ HWTEST_F_L0(JSTaggedValueTest, IsInteger) ASSERT_FALSE(JSTaggedValue::Null().IsInteger()); ASSERT_FALSE(JSTaggedValue::False().IsInteger()); ASSERT_FALSE(JSTaggedValue::Hole().IsInteger()); - ASSERT_FALSE(thread->GetEcmaVM()->GetFactory()->NewFromString("test").GetTaggedValue().IsInteger()); + ASSERT_FALSE(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("test").GetTaggedValue().IsInteger()); } HWTEST_F_L0(JSTaggedValueTest, IsPropertyKey) { ASSERT_TRUE(JSTaggedValue::IsPropertyKey( - JSHandle(thread->GetEcmaVM()->GetFactory()->NewFromString("test")))); + JSHandle(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("test")))); } HWTEST_F_L0(JSTaggedValueTest, IsRegExp) { - JSHandle string = thread->GetEcmaVM()->GetFactory()->NewFromString("test"); + JSHandle string = thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("test"); JSHandle obj = JSHandle::Cast(string); ASSERT_FALSE(JSObject::IsRegExp(thread, obj)); } @@ -1009,16 +1011,15 @@ HWTEST_F_L0(JSTaggedValueTest, SameValue) EcmaVM *ecma = thread->GetEcmaVM(); JSHandle objectFun = ecma->GetGlobalEnv()->GetObjectFunction(); - JSHandle jsObj = - ecma->GetFactory()->NewJSObjectByConstructor(JSHandle(objectFun), objectFun); + JSHandle jsObj = ecma->GetFactory()->NewJSObjectByConstructor(JSHandle(objectFun), objectFun); // not same type ASSERT_FALSE(JSTaggedValue::SameValue(JSTaggedValue(1), JSTaggedValue::False())); ASSERT_FALSE(JSTaggedValue::SameValue(JSTaggedValue(1.0), JSTaggedValue::True())); - ASSERT_FALSE( - JSTaggedValue::SameValue(JSTaggedValue(1), ecma->GetFactory()->NewFromString("test").GetTaggedValue())); + ASSERT_FALSE(JSTaggedValue::SameValue(JSTaggedValue(1), + ecma->GetFactory()->NewFromCanBeCompressString("test").GetTaggedValue())); ASSERT_FALSE(JSTaggedValue::SameValue(JSTaggedValue(1), JSTaggedValue(*jsObj))); - JSHandle test(ecma->GetFactory()->NewFromString("test")); + JSHandle test(ecma->GetFactory()->NewFromCanBeCompressString("test")); ASSERT_FALSE(JSTaggedValue::SameValue(test.GetTaggedValue(), JSTaggedValue(*jsObj))); // number compare @@ -1035,7 +1036,7 @@ HWTEST_F_L0(JSTaggedValueTest, SameValue) ASSERT_FALSE(JSTaggedValue::SameValue(JSTaggedValue(1.0), JSTaggedValue(-1.0))); // string compare - JSHandle test1(ecma->GetFactory()->NewFromString("test1")); + JSHandle test1(ecma->GetFactory()->NewFromCanBeCompressString("test1")); ASSERT_FALSE(JSTaggedValue::SameValue(test.GetTaggedValue(), test1.GetTaggedValue())); ASSERT_TRUE(JSTaggedValue::SameValue(test.GetTaggedValue(), test.GetTaggedValue())); @@ -1063,9 +1064,9 @@ HWTEST_F_L0(JSTaggedValueTest, SameValueZero) HWTEST_F_L0(JSTaggedValueTest, Less) { - JSHandle test(thread->GetEcmaVM()->GetFactory()->NewFromString("test")); - JSHandle test1(thread->GetEcmaVM()->GetFactory()->NewFromString("test1")); - JSHandle test2(thread->GetEcmaVM()->GetFactory()->NewFromString("test2")); + JSHandle test(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("test")); + JSHandle test1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("test1")); + JSHandle test2(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("test2")); ASSERT_TRUE(JSTaggedValue::Less(thread, JSHandle(thread, JSTaggedValue(1.0)), JSHandle(thread, JSTaggedValue(2.0)))); @@ -1079,11 +1080,12 @@ HWTEST_F_L0(JSTaggedValueTest, Less) ASSERT_FALSE(JSTaggedValue::Less(thread, JSHandle(thread, JSTaggedValue(1)), test1)); ASSERT_FALSE(JSTaggedValue::Less(thread, test2, JSHandle(thread, JSTaggedValue(2)))); - ASSERT_TRUE(JSTaggedValue::Less(thread, - JSHandle(thread->GetEcmaVM()->GetFactory()->NewFromString("1")), - JSHandle(thread, JSTaggedValue(2)))); - ASSERT_TRUE(JSTaggedValue::Less(thread, JSHandle(thread, JSTaggedValue(1)), - JSHandle(thread->GetEcmaVM()->GetFactory()->NewFromString("2")))); + ASSERT_TRUE(JSTaggedValue::Less( + thread, JSHandle(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1")), + JSHandle(thread, JSTaggedValue(2)))); + ASSERT_TRUE(JSTaggedValue::Less( + thread, JSHandle(thread, JSTaggedValue(1)), + JSHandle(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("2")))); ASSERT_TRUE(JSTaggedValue::Less(thread, JSHandle(thread, JSTaggedValue::False()), JSHandle(thread, JSTaggedValue::True()))); @@ -1134,16 +1136,16 @@ HWTEST_F_L0(JSTaggedValueTest, Equal) ASSERT_FALSE(JSTaggedValue::Equal(thread, JSHandle(thread, JSTaggedValue(0)), JSHandle(thread, JSTaggedValue::Null()))); - JSHandle test(thread->GetEcmaVM()->GetFactory()->NewFromString("test")); - JSHandle test1(thread->GetEcmaVM()->GetFactory()->NewFromString("test1")); - JSHandle empty(thread->GetEcmaVM()->GetFactory()->NewFromString("")); - JSHandle char0(thread->GetEcmaVM()->GetFactory()->NewFromString("0")); - JSHandle char0Point0(thread->GetEcmaVM()->GetFactory()->NewFromString("0.0")); - JSHandle char1(thread->GetEcmaVM()->GetFactory()->NewFromString("1")); - JSHandle char1Point0(thread->GetEcmaVM()->GetFactory()->NewFromString("1.0")); - JSHandle charM1(thread->GetEcmaVM()->GetFactory()->NewFromString("-1")); - JSHandle charM0Point0(thread->GetEcmaVM()->GetFactory()->NewFromString("-0.0")); - JSHandle charM0Point1(thread->GetEcmaVM()->GetFactory()->NewFromString("-0.1")); + JSHandle test(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("test")); + JSHandle test1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("test1")); + JSHandle empty(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("")); + JSHandle char0(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0")); + JSHandle char0Point0(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("0.0")); + JSHandle char1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1")); + JSHandle char1Point0(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("1.0")); + JSHandle charM1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-1")); + JSHandle charM0Point0(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-0.0")); + JSHandle charM0Point1(thread->GetEcmaVM()->GetFactory()->NewFromCanBeCompressString("-0.1")); ASSERT_TRUE(JSTaggedValue::Equal(thread, JSHandle(thread, JSTaggedValue(0)), char0)); ASSERT_TRUE(JSTaggedValue::Equal(thread, JSHandle(thread, JSTaggedValue(0.0)), char0)); @@ -1158,7 +1160,6 @@ HWTEST_F_L0(JSTaggedValueTest, Equal) ASSERT_FALSE(JSTaggedValue::Equal(thread, test, empty)); ASSERT_TRUE(JSTaggedValue::Equal(thread, empty, empty)); - ASSERT_TRUE(JSTaggedValue::Equal(thread, char1, JSHandle(thread, JSTaggedValue(1)))); ASSERT_TRUE(JSTaggedValue::Equal(thread, char1, JSHandle(thread, JSTaggedValue::True()))); ASSERT_TRUE(JSTaggedValue::Equal(thread, char0, JSHandle(thread, JSTaggedValue::False()))); diff --git a/ecmascript/tests/test_helper.h b/ecmascript/tests/test_helper.h index 6d3cd4c088065a9de099ea0063e08c0f9fd1d696..4a5a202f9e68100756d2e562ddf55cec6a6bdd4c 100644 --- a/ecmascript/tests/test_helper.h +++ b/ecmascript/tests/test_helper.h @@ -13,6 +13,9 @@ * limitations under the License. */ +#ifndef ECMASCRIPT_TESTS_TEST_HELPER_H +#define ECMASCRIPT_TESTS_TEST_HELPER_H + #include "ecmascript/interpreter/interpreter.h" #include "ecmascript/ecma_language_context.h" #include "ecmascript/ecma_runtime_call_info.h" @@ -44,7 +47,7 @@ public: // argvLength includes number of int64_t to store value and tag of function, 'this' and call args // It doesn't include new.target argument uint32_t numActualArgs = argvLength / testDecodedSize + 1; - JSTaggedType *sp = thread->GetCurrentSPFrame(); + JSTaggedType *sp = const_cast(thread->GetCurrentSPFrame()); size_t frameSize = ecmascript::FRAME_STATE_SIZE + numActualArgs; JSTaggedType *newSp = sp - frameSize; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -56,7 +59,7 @@ public: static JSTaggedType *SetupFrame(JSThread *thread, EcmaRuntimeCallInfo *info) { - JSTaggedType *sp = thread->GetCurrentSPFrame(); + JSTaggedType *sp = const_cast(thread->GetCurrentSPFrame()); size_t frameSize = ecmascript::FRAME_STATE_SIZE + info->GetArgsNumber() + NUM_MANDATORY_JSFUNC_ARGS; JSTaggedType *newSp = sp - frameSize; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -105,3 +108,4 @@ public: } }; } // namespace panda::test +#endif // ECMASCRIPT_TESTS_TEST_HELPER_H diff --git a/ecmascript/thread/thread_pool.h b/ecmascript/thread/thread_pool.h index 8004a7023c56588e14312faf0056ec80714290ba..7af95c55db3a6da561bd190e4d359e284c507e7a 100644 --- a/ecmascript/thread/thread_pool.h +++ b/ecmascript/thread/thread_pool.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_ECMASCRIPT_THREAD_THREAD_POOL_H -#define PANDA_ECMASCRIPT_THREAD_THREAD_POOL_H +#ifndef ECMASCRIPT_THREAD_THREAD_POOL_H +#define ECMASCRIPT_THREAD_THREAD_POOL_H #include #include @@ -127,4 +127,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_ECMASCRIPT_THREAD_THREAD_POOL_H +#endif // ECMASCRIPT_THREAD_THREAD_POOL_H diff --git a/ecmascript/thread/thread_safe_queue.h b/ecmascript/thread/thread_safe_queue.h index 7fff073b13101633b2ffd4899002ff545af5a33e..27d8b2cca29fc94c530c4683efd1107aeafaee65 100644 --- a/ecmascript/thread/thread_safe_queue.h +++ b/ecmascript/thread/thread_safe_queue.h @@ -13,14 +13,14 @@ * limitations under the License. */ -#ifndef PANDA_ECMASCRIPT_THREAD_THREAD_SAFE_QUEUE_H -#define PANDA_ECMASCRIPT_THREAD_THREAD_SAFE_QUEUE_H +#ifndef ECMASCRIPT_THREAD_THREAD_SAFE_QUEUE_H +#define ECMASCRIPT_THREAD_THREAD_SAFE_QUEUE_H #include "os/mutex.h" #include namespace panda::ecmascript { -template +template class ThreadSafeQueue { public: explicit ThreadSafeQueue() = default; @@ -65,4 +65,4 @@ private: }; } // namespace panda::ecmascript -#endif // PANDA_ECMASCRIPT_THREAD_THREAD_SAFE_QUEUE_H +#endif // ECMASCRIPT_THREAD_THREAD_SAFE_QUEUE_H diff --git a/ecmascript/tooling/BUILD.gn b/ecmascript/tooling/BUILD.gn index 17816722078ecdd7d0adb6ed3b7fe55131f839c0..01125eafdc7d51019d8b48311ed9e0e2e8f89230 100644 --- a/ecmascript/tooling/BUILD.gn +++ b/ecmascript/tooling/BUILD.gn @@ -68,8 +68,6 @@ ohos_shared_library("libark_ecma_debugger") { part_name = "ark_js_runtime" output_extension = "so" - if (!is_standard_system) { - relative_install_dir = "ark" - } + relative_install_dir = "ark" subsystem_name = "ark" } diff --git a/ecmascript/tooling/agent/debugger_impl.cpp b/ecmascript/tooling/agent/debugger_impl.cpp index a032b798b3dd47d3c1ccd141f427d74aed596f2a..d888667e588c231e66c5abc581d49564de4434a4 100644 --- a/ecmascript/tooling/agent/debugger_impl.cpp +++ b/ecmascript/tooling/agent/debugger_impl.cpp @@ -184,7 +184,9 @@ void DebuggerImpl::DispatcherImpl::SetBlackboxPatterns(const DispatchRequest &re DispatchResponse DebuggerImpl::Enable([[maybe_unused]] std::unique_ptr params, UniqueDebuggerId *id) { - ASSERT(id != nullptr); + if (id == nullptr) { + return DispatchResponse::Fail("id is nullptr!"); + } *id = "0"; return DispatchResponse::Ok(); } @@ -208,12 +210,11 @@ DispatchResponse DebuggerImpl::GetPossibleBreakpoints(std::unique_ptr params, CString *source) { - if (!backend_->MatchScripts( - [source](PtScript *script) -> bool { - *source = script->GetScriptSource(); - return true; - }, - params->GetScriptId(), ScriptMatchType::SCRIPT_ID)) { + auto scriptFunc = [source](PtScript *script) -> bool { + *source = script->GetScriptSource(); + return true; + }; + if (!backend_->MatchScripts(scriptFunc, params->GetScriptId(), ScriptMatchType::SCRIPT_ID)) { *source = ""; return DispatchResponse::Fail("unknown script id: " + params->GetScriptId()); } diff --git a/ecmascript/tooling/agent/debugger_impl.h b/ecmascript/tooling/agent/debugger_impl.h index 946e6c974be59cdb6166db414a1df4b97577cf5f..9aa5f1c6eac8c4b695b6e08975812a2505246814 100644 --- a/ecmascript/tooling/agent/debugger_impl.h +++ b/ecmascript/tooling/agent/debugger_impl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_DEBUGGER_IMPL_H -#define PANDA_TOOLING_ECMASCRIPT_DEBUGGER_IMPL_H +#ifndef ECMASCRIPT_TOOLING_AGENT_DEBUGGER_IMPL_H +#define ECMASCRIPT_TOOLING_AGENT_DEBUGGER_IMPL_H #include "libpandabase/macros.h" #include "ecmascript/tooling/agent/js_backend.h" diff --git a/ecmascript/tooling/agent/js_backend.cpp b/ecmascript/tooling/agent/js_backend.cpp index e165c32b872bff0885c7a1c1107aae0e2241fb12..6172d2ae76ec2dd19e44961b1a0f4cd8c08f11a2 100644 --- a/ecmascript/tooling/agent/js_backend.cpp +++ b/ecmascript/tooling/agent/js_backend.cpp @@ -66,21 +66,18 @@ void JSBackend::NotifyPaused(std::optional location, PauseReason rea if (location.has_value()) { BreakpointDetails detail; PtJSExtractor *extractor = nullptr; - if (!MatchScripts([this, &extractor, &detail](PtScript *script) -> bool { + auto scriptFunc = [this, &extractor, &detail](PtScript *script) -> bool { detail.url_ = script->GetUrl(); extractor = GetExtractor(detail.url_); return true; - }, - location.value().GetPandaFile(), - ScriptMatchType::FILE_NAME) || - extractor == nullptr || - !extractor->MatchWithOffset([&detail](int32_t line) -> bool { + }; + auto offsetFunc = [&detail](int32_t line) -> bool { detail.line_ = line; return true; - }, - location.value().GetMethodId(), - location.value().GetBytecodeOffset())) { - LOG(ERROR, DEBUGGER) << "NotifyPaused: unknown " << location.value().GetPandaFile(); + }; + if (!MatchScripts(scriptFunc, location->GetPandaFile(), ScriptMatchType::FILE_NAME) || extractor == nullptr || + !extractor->MatchWithOffset(offsetFunc, location->GetMethodId(), location->GetBytecodeOffset())) { + LOG(ERROR, DEBUGGER) << "NotifyPaused: unknown " << location->GetPandaFile(); return; } detail.column_ = 0; @@ -110,9 +107,10 @@ void JSBackend::NotifyResume() bool JSBackend::NotifyScriptParsed(int32_t scriptId, const CString &fileName) { - if (MatchScripts([]([[maybe_unused]] PtScript *script) -> bool { return true; }, - fileName, - ScriptMatchType::FILE_NAME)) { + auto scriptFunc = []([[maybe_unused]] PtScript *script) -> bool { + return true; + }; + if (MatchScripts(scriptFunc, fileName, ScriptMatchType::FILE_NAME)) { LOG(WARNING, DEBUGGER) << "NotifyScriptParsed: already loaded: " << fileName; return false; } @@ -182,16 +180,15 @@ bool JSBackend::NotifyScriptParsed(int32_t scriptId, const CString &fileName) bool JSBackend::StepComplete(const PtLocation &location) { PtJSExtractor *extractor = nullptr; - if (MatchScripts([this, &extractor](PtScript *script) -> bool { + auto scriptFunc = [this, &extractor](PtScript *script) -> bool { extractor = GetExtractor(script->GetUrl()); return true; - }, - location.GetPandaFile(), - ScriptMatchType::FILE_NAME) && - extractor != nullptr && - extractor->MatchWithOffset([](int32_t line) -> bool { return line == SPECIAL_LINE_MARK; }, - location.GetMethodId(), - location.GetBytecodeOffset())) { + }; + auto offsetFunc = [](int32_t line) -> bool { + return line == SPECIAL_LINE_MARK; + }; + if (MatchScripts(scriptFunc, location.GetPandaFile(), ScriptMatchType::FILE_NAME) && extractor != nullptr && + extractor->MatchWithOffset(offsetFunc, location.GetMethodId(), location.GetBytecodeOffset())) { LOG(INFO, DEBUGGER) << "StepComplete: skip -1"; return false; } @@ -206,21 +203,23 @@ bool JSBackend::StepComplete(const PtLocation &location) return false; } -std::optional JSBackend::GetPossibleBreakpoints( - Location *start, [[maybe_unused]] Location *end, CVector> *locations) +std::optional JSBackend::GetPossibleBreakpoints(Location *start, [[maybe_unused]] Location *end, + CVector> *locations) { PtJSExtractor *extractor = nullptr; - if (!MatchScripts([this, &extractor](PtScript *script) -> bool { + auto scriptFunc = [this, &extractor](PtScript *script) -> bool { extractor = GetExtractor(script->GetUrl()); return true; - }, - start->GetScriptId(), - ScriptMatchType::SCRIPT_ID) || extractor == nullptr) { + }; + if (!MatchScripts(scriptFunc, start->GetScriptId(), ScriptMatchType::SCRIPT_ID) || extractor == nullptr) { return Error(Error::Type::INVALID_BREAKPOINT, "extractor not found"); } int32_t line = start->GetLine(); - if (extractor->MatchWithLine([](File::EntityId, uint32_t) -> bool { return true; }, line)) { + auto lineFunc = []([[maybe_unused]] File::EntityId id, [[maybe_unused]] uint32_t offset) -> bool { + return true; + }; + if (extractor->MatchWithLine(lineFunc, line)) { std::unique_ptr location = std::make_unique(); location->SetScriptId(start->GetScriptId()).SetLine(line).SetColumn(0); locations->emplace_back(std::move(location)); @@ -240,24 +239,23 @@ std::optional JSBackend::SetBreakpointByUrl(const CString &url, int32_t l CString scriptId; CString fileName; - if (!MatchScripts([&scriptId, &fileName](PtScript *script) -> bool { + auto scriptFunc = [&scriptId, &fileName](PtScript *script) -> bool { scriptId = script->GetScriptId(); fileName = script->GetFileName(); return true; - }, - url, - ScriptMatchType::URL)) { + }; + if (!MatchScripts(scriptFunc, url, ScriptMatchType::URL)) { LOG(ERROR, DEBUGGER) << "SetBreakpointByUrl: Unknown url: " << url; return Error(Error::Type::INVALID_BREAKPOINT, "Url not found"); } std::optional ret = std::nullopt; - if (!extractor->MatchWithLine([this, fileName, &ret](File::EntityId id, uint32_t offset) -> bool { + auto lineFunc = [this, fileName, &ret](File::EntityId id, uint32_t offset) -> bool { PtLocation location {fileName.c_str(), id, offset}; ret = DebuggerApi::SetBreakpoint(debugger_, location); return true; - }, - lineNumber)) { + }; + if (!extractor->MatchWithLine(lineFunc, lineNumber)) { LOG(ERROR, DEBUGGER) << "failed to set breakpoint line number: " << lineNumber; return Error(Error::Type::INVALID_BREAKPOINT, "Breakpoint not found"); } @@ -283,23 +281,22 @@ std::optional JSBackend::RemoveBreakpoint(const BreakpointDetails &metaDa } CString fileName; - if (!MatchScripts([&fileName](PtScript *script) -> bool { + auto scriptFunc = [&fileName](PtScript *script) -> bool { fileName = script->GetFileName(); return true; - }, - metaData.url_, - ScriptMatchType::URL)) { + }; + if (!MatchScripts(scriptFunc, metaData.url_, ScriptMatchType::URL)) { LOG(ERROR, DEBUGGER) << "RemoveBreakpoint: Unknown url: " << metaData.url_; return Error(Error::Type::INVALID_BREAKPOINT, "Url not found"); } std::optional ret = std::nullopt; - if (!extractor->MatchWithLine([this, fileName, &ret](File::EntityId id, uint32_t offset) -> bool { + auto lineFunc = [this, fileName, &ret](File::EntityId id, uint32_t offset) -> bool { PtLocation location {fileName.c_str(), id, offset}; ret = DebuggerApi::RemoveBreakpoint(debugger_, location); return true; - }, - metaData.line_)) { + }; + if (!extractor->MatchWithLine(lineFunc, metaData.line_)) { LOG(ERROR, DEBUGGER) << "failed to set breakpoint line number: " << metaData.line_; return Error(Error::Type::INVALID_BREAKPOINT, "Breakpoint not found"); } @@ -367,21 +364,21 @@ std::optional JSBackend::StepOut() return {}; } -std::optional JSBackend::EvaluateValue( - const CString &callFrameId, const CString &expression, std::unique_ptr *result) +std::optional JSBackend::EvaluateValue(const CString &callFrameId, const CString &expression, + std::unique_ptr *result) { JSMethod *method = DebuggerApi::GetMethod(ecmaVm_); if (method->IsNative()) { LOG(ERROR, DEBUGGER) << "EvaluateValue: Native Frame not support"; - *result = RemoteObject::FromTagged( - ecmaVm_, Exception::EvalError(ecmaVm_, StringRef::NewFromUtf8(ecmaVm_, "Runtime internal error"))); + *result = RemoteObject::FromTagged(ecmaVm_, + Exception::EvalError(ecmaVm_, StringRef::NewFromUtf8(ecmaVm_, "Runtime internal error"))); return Error(Error::Type::METHOD_NOT_FOUND, "Native Frame not support"); } DebugInfoExtractor *extractor = GetExtractor(method->GetPandaFile()); if (extractor == nullptr) { LOG(ERROR, DEBUGGER) << "EvaluateValue: extractor is null"; - *result = RemoteObject::FromTagged( - ecmaVm_, Exception::EvalError(ecmaVm_, StringRef::NewFromUtf8(ecmaVm_, "Runtime internal error"))); + *result = RemoteObject::FromTagged(ecmaVm_, + Exception::EvalError(ecmaVm_, StringRef::NewFromUtf8(ecmaVm_, "Runtime internal error"))); return Error(Error::Type::METHOD_NOT_FOUND, "Extractor not found"); } CString varName = expression; @@ -399,8 +396,8 @@ std::optional JSBackend::EvaluateValue( } } if (regIndex == -1) { - *result = RemoteObject::FromTagged( - ecmaVm_, Exception::EvalError(ecmaVm_, StringRef::NewFromUtf8(ecmaVm_, "Unknow input params"))); + *result = RemoteObject::FromTagged(ecmaVm_, + Exception::EvalError(ecmaVm_, StringRef::NewFromUtf8(ecmaVm_, "Unknow input params"))); return Error(Error::Type::METHOD_NOT_FOUND, "Unsupport expression"); } if (varValue.empty()) { @@ -461,24 +458,24 @@ PtJSExtractor *JSBackend::GetExtractor(const CString &url) bool JSBackend::GenerateCallFrames(CVector> *callFrames) { int32_t callFrameId = 0; - return DebuggerApi::StackWalker( - ecmaVm_, [this, &callFrameId, &callFrames](const EcmaFrameHandler *frameHandler) -> StackState { - JSMethod *method = DebuggerApi::GetMethod(frameHandler); - if (method->IsNative()) { - LOG(INFO, DEBUGGER) << "GenerateCallFrames: Skip CFrame and Native method"; - return StackState::CONTINUE; - } - std::unique_ptr callFrame = std::make_unique(); - if (!GenerateCallFrame(callFrame.get(), frameHandler, callFrameId)) { - if (callFrameId == 0) { - return StackState::FAILED; - } + auto walkerFunc = [this, &callFrameId, &callFrames](const EcmaFrameHandler *frameHandler) -> StackState { + JSMethod *method = DebuggerApi::GetMethod(frameHandler); + if (method->IsNative()) { + LOG(INFO, DEBUGGER) << "GenerateCallFrames: Skip CFrame and Native method"; + return StackState::CONTINUE; + } + std::unique_ptr callFrame = std::make_unique(); + if (!GenerateCallFrame(callFrame.get(), frameHandler, callFrameId)) { + if (callFrameId == 0) { + return StackState::FAILED; } + } else { callFrames->emplace_back(std::move(callFrame)); callFrameId++; - return StackState::CONTINUE; - }); - return true; + } + return StackState::CONTINUE; + }; + return DebuggerApi::StackWalker(ecmaVm_, walkerFunc); } bool JSBackend::GenerateCallFrame(CallFrame *callFrame, const EcmaFrameHandler *frameHandler, int32_t callFrameId) @@ -494,21 +491,19 @@ bool JSBackend::GenerateCallFrame(CallFrame *callFrame, const EcmaFrameHandler * // location std::unique_ptr location = std::make_unique(); CString url = extractor->GetSourceFile(method->GetFileId()); - if (!MatchScripts([&location](PtScript *script) -> bool { + auto scriptFunc = [&location](PtScript *script) -> bool { location->SetScriptId(script->GetScriptId()); return true; - }, - url, - ScriptMatchType::URL)) { + }; + if (!MatchScripts(scriptFunc, url, ScriptMatchType::URL)) { LOG(ERROR, DEBUGGER) << "GenerateCallFrame: Unknown url: " << url; return false; } - if (!extractor->MatchWithOffset([&location](int32_t line) -> bool { + auto offsetFunc = [&location](int32_t line) -> bool { location->SetLine(line); return true; - }, - method->GetFileId(), - DebuggerApi::GetBytecodeOffset(frameHandler))) { + }; + if (!extractor->MatchWithOffset(offsetFunc, method->GetFileId(), DebuggerApi::GetBytecodeOffset(frameHandler))) { LOG(ERROR, DEBUGGER) << "GenerateCallFrame: unknown offset: " << DebuggerApi::GetBytecodeOffset(frameHandler); return false; } @@ -522,9 +517,7 @@ bool JSBackend::GenerateCallFrame(CallFrame *callFrame, const EcmaFrameHandler * scopeChain.emplace_back(GetGlobalScopeChain()); // functionName - panda_file::MethodDataAccessor mda(*pf, method->GetFileId()); - CString functionName = CString(utf::Mutf8AsCString(pf->GetStringData( - panda_file::File::EntityId(mda.GetNumericalAnnotation(JSMethod::AnnotationField::FUNCTION_NAME))).data)); + CString functionName = DebuggerApi::ParseFunctionName(method); callFrame->SetCallFrameId(DebuggerApi::ToCString(callFrameId)) .SetFunctionName(functionName) @@ -535,8 +528,8 @@ bool JSBackend::GenerateCallFrame(CallFrame *callFrame, const EcmaFrameHandler * return true; } -std::unique_ptr JSBackend::GetLocalScopeChain( - const EcmaFrameHandler *frameHandler, std::unique_ptr *thisObj) +std::unique_ptr JSBackend::GetLocalScopeChain(const EcmaFrameHandler *frameHandler, + std::unique_ptr *thisObj) { auto localScope = std::make_unique(); @@ -574,17 +567,16 @@ std::unique_ptr JSBackend::GetLocalScopeChain( const panda_file::LineNumberTable &lines = extractor->GetLineNumberTable(methodId); std::unique_ptr startLoc = std::make_unique(); std::unique_ptr endLoc = std::make_unique(); - if (MatchScripts([&startLoc, &endLoc, lines](PtScript *script) -> bool { + auto scriptFunc = [&startLoc, &endLoc, lines](PtScript *script) -> bool { startLoc->SetScriptId(script->GetScriptId()) - .SetLine(static_cast(lines.front().line)) - .SetColumn(0); + .SetLine(static_cast(lines.front().line)) + .SetColumn(0); endLoc->SetScriptId(script->GetScriptId()) - .SetLine(static_cast(lines.back().line)) - .SetColumn(0); + .SetLine(static_cast(lines.back().line)) + .SetColumn(0); return true; - }, - extractor->GetSourceFile(methodId), - ScriptMatchType::URL)) { + }; + if (MatchScripts(scriptFunc, extractor->GetSourceFile(methodId), ScriptMatchType::URL)) { localScope->SetType(Scope::Type::Local()) .SetObject(std::move(local)) .SetStartLocation(std::move(startLoc)) @@ -613,8 +605,8 @@ void JSBackend::SetPauseOnException(bool flag) pauseOnException_ = flag; } -std::optional JSBackend::SetValue( - int32_t regIndex, std::unique_ptr *result, const CString &varValue) +std::optional JSBackend::SetValue(int32_t regIndex, std::unique_ptr *result, + const CString &varValue) { Local taggedValue; if (varValue == "false") { @@ -631,8 +623,8 @@ std::optional JSBackend::SetValue( auto end = begin + varValue.length(); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) double d = DebuggerApi::StringToDouble(begin, end, 0); if (std::isnan(d)) { - *result = RemoteObject::FromTagged( - ecmaVm_, Exception::EvalError(ecmaVm_, StringRef::NewFromUtf8(ecmaVm_, "Unsupport value"))); + *result = RemoteObject::FromTagged(ecmaVm_, + Exception::EvalError(ecmaVm_, StringRef::NewFromUtf8(ecmaVm_, "Unsupport value"))); return Error(Error::Type::METHOD_NOT_FOUND, "Unsupport value"); } taggedValue = NumberRef::New(ecmaVm_, d); diff --git a/ecmascript/tooling/agent/js_backend.h b/ecmascript/tooling/agent/js_backend.h index 34584a0ac37c9a4566fbd11f2ff001fb25e1086b..44060029ca835479dd2eb009273dbbff4f06a132 100644 --- a/ecmascript/tooling/agent/js_backend.h +++ b/ecmascript/tooling/agent/js_backend.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_JS_BACKEND_H -#define PANDA_TOOLING_ECMASCRIPT_JS_BACKEND_H +#ifndef ECMASCRIPT_TOOLING_AGENT_JS_BACKEND_H +#define ECMASCRIPT_TOOLING_AGENT_JS_BACKEND_H #include "ecmascript/tooling/agent/js_pt_hooks.h" #include "ecmascript/tooling/base/pt_types.h" @@ -64,7 +64,7 @@ public: * * @return: true means matched and callback execute success */ - template + template bool MatchScripts(const Callback &cb, const CString &matchStr, ScriptMatchType type) const { for (const auto &script : scripts_) { diff --git a/ecmascript/tooling/agent/js_pt_hooks.h b/ecmascript/tooling/agent/js_pt_hooks.h index d8d44ab362718d0ccfd522ff1d21ad3c53be167f..e129e6900788bcd45f6f7b7c8d57e7547e87abcc 100644 --- a/ecmascript/tooling/agent/js_pt_hooks.h +++ b/ecmascript/tooling/agent/js_pt_hooks.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_JS_PT_HOOKS_H -#define PANDA_TOOLING_ECMASCRIPT_JS_PT_HOOKS_H +#ifndef ECMASCRIPT_TOOLING_AGENT_JS_PT_HOOKS_H +#define ECMASCRIPT_TOOLING_AGENT_JS_PT_HOOKS_H #include "libpandabase/macros.h" #include "ecmascript/tooling/pt_js_extractor.h" diff --git a/ecmascript/tooling/agent/runtime_impl.cpp b/ecmascript/tooling/agent/runtime_impl.cpp index 81779c53099575540e52f4d52d0442fba2195ebc..9592a3e85aacc6af60e94d873e207b6c3ce7784e 100644 --- a/ecmascript/tooling/agent/runtime_impl.cpp +++ b/ecmascript/tooling/agent/runtime_impl.cpp @@ -61,8 +61,8 @@ void RuntimeImpl::DispatcherImpl::GetProperties(const DispatchRequest &request) std::optional>> outInternalDescs; std::optional>> outPrivateProperties; std::optional> outExceptionDetails; - DispatchResponse response = runtime_->GetProperties( - std::move(params), &outPropertyDesc, &outInternalDescs, &outPrivateProperties, &outExceptionDetails); + DispatchResponse response = runtime_->GetProperties(std::move(params), &outPropertyDesc, &outInternalDescs, + &outPrivateProperties, &outExceptionDetails); if (outExceptionDetails) { LOG(WARNING, DEBUGGER) << "GetProperties thrown an exception"; } diff --git a/ecmascript/tooling/agent/runtime_impl.h b/ecmascript/tooling/agent/runtime_impl.h index 6036f57d0b797430c580ed76c9a9169a1ad59de5..b2005ef47eb8db0fb90ef612e4158c432ecd55f2 100644 --- a/ecmascript/tooling/agent/runtime_impl.h +++ b/ecmascript/tooling/agent/runtime_impl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_RUNTIME_IMPL_H -#define PANDA_TOOLING_ECMASCRIPT_RUNTIME_IMPL_H +#ifndef ECMASCRIPT_TOOLING_AGENT_RUNTIME_IMPL_H +#define ECMASCRIPT_TOOLING_AGENT_RUNTIME_IMPL_H #include "libpandabase/macros.h" #include "ecmascript/tooling/agent/js_backend.h" diff --git a/ecmascript/tooling/base/pt_events.cpp b/ecmascript/tooling/base/pt_events.cpp index 1d8521dca0802ceda79165d8081548e03195808e..dd082b4372e020a8676740b4481ad8087cba666c 100644 --- a/ecmascript/tooling/base/pt_events.cpp +++ b/ecmascript/tooling/base/pt_events.cpp @@ -97,9 +97,9 @@ std::unique_ptr Paused::Create(const EcmaVM *ecmaVm, const Local key = JSValueRef::Undefined(ecmaVm); for (uint32_t i = 0; i < len; ++i) { key = IntegerRef::New(ecmaVm, i); - Local result = Local(array)->Get(ecmaVm, key->ToString(ecmaVm)); - std::unique_ptr callFrame = CallFrame::Create(ecmaVm, result); - if (result.IsEmpty() || callFrame == nullptr) { + Local resultValue = Local(array)->Get(ecmaVm, key->ToString(ecmaVm)); + std::unique_ptr callFrame = CallFrame::Create(ecmaVm, resultValue); + if (resultValue.IsEmpty() || callFrame == nullptr) { error += "'callFrames' format invalid;"; } paused->callFrames_.emplace_back(std::move(callFrame)); @@ -137,8 +137,8 @@ std::unique_ptr Paused::Create(const EcmaVM *ecmaVm, const Local key = JSValueRef::Undefined(ecmaVm); for (uint32_t i = 0; i < len; ++i) { key = IntegerRef::New(ecmaVm, i); - Local result = Local(array)->Get(ecmaVm, key->ToString(ecmaVm)); - if (result.IsEmpty()) { + Local resultValue = Local(array)->Get(ecmaVm, key->ToString(ecmaVm)); + if (resultValue.IsEmpty()) { error += "'hitBreakpoints' format invalid;"; } breakPoints.emplace_back(DebuggerApi::ConvertToString(StringRef::Cast(*result)->ToString())); @@ -171,8 +171,8 @@ Local Paused::ToObject(const EcmaVM *ecmaVm) Local(StringRef::NewFromUtf8(ecmaVm, "reason")), Local(StringRef::NewFromUtf8(ecmaVm, reason_.c_str()))); if (data_) { - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "data")), Local(data_.value())); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "data")), + Local(data_.value())); } if (hitBreakpoints_) { len = hitBreakpoints_->size(); @@ -301,8 +301,8 @@ std::unique_ptr ScriptFailedToParse::Create(const EcmaVM *e } else { error += "should contain 'hash';"; } - result = Local(params)->Get( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "executionContextAuxData"))); + result = Local(params)->Get(ecmaVm, + Local(StringRef::NewFromUtf8(ecmaVm, "executionContextAuxData"))); if (!result.IsEmpty()) { if (result->IsObject()) { scriptEvent->execContextAuxData_ = Local(result); @@ -384,15 +384,15 @@ Local ScriptFailedToParse::ToObject(const EcmaVM *ecmaVm) params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "url")), Local(StringRef::NewFromUtf8(ecmaVm, url_.c_str()))); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "startLine")), IntegerRef::New(ecmaVm, startLine_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "startLine")), + IntegerRef::New(ecmaVm, startLine_)); params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "startColumn")), IntegerRef::New(ecmaVm, startColumn_)); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "endLine")), IntegerRef::New(ecmaVm, endLine_)); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "endColumn")), IntegerRef::New(ecmaVm, endColumn_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "endLine")), + IntegerRef::New(ecmaVm, endLine_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "endColumn")), + IntegerRef::New(ecmaVm, endColumn_)); params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "executionContextId")), IntegerRef::New(ecmaVm, executionContextId_)); @@ -540,8 +540,8 @@ std::unique_ptr ScriptParsed::Create(const EcmaVM *ecmaVm, const L } else { error += "should contain 'hash';"; } - result = Local(params)->Get( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "executionContextAuxData"))); + result = Local(params)->Get(ecmaVm, + Local(StringRef::NewFromUtf8(ecmaVm, "executionContextAuxData"))); if (!result.IsEmpty()) { if (result->IsObject()) { scriptEvent->execContextAuxData_ = Local(result); @@ -631,15 +631,15 @@ Local ScriptParsed::ToObject(const EcmaVM *ecmaVm) params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "url")), Local(StringRef::NewFromUtf8(ecmaVm, url_.c_str()))); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "startLine")), IntegerRef::New(ecmaVm, startLine_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "startLine")), + IntegerRef::New(ecmaVm, startLine_)); params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "startColumn")), IntegerRef::New(ecmaVm, startColumn_)); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "endLine")), IntegerRef::New(ecmaVm, endLine_)); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "endColumn")), IntegerRef::New(ecmaVm, endColumn_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "endLine")), + IntegerRef::New(ecmaVm, endLine_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "endColumn")), + IntegerRef::New(ecmaVm, endColumn_)); params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "executionContextId")), IntegerRef::New(ecmaVm, executionContextId_)); diff --git a/ecmascript/tooling/base/pt_events.h b/ecmascript/tooling/base/pt_events.h index baa79a38fbcc276e427f8ba219105a22fcdd8e09..f60de50e9b8a2ac44854cd99dafd6a658f698aee 100644 --- a/ecmascript/tooling/base/pt_events.h +++ b/ecmascript/tooling/base/pt_events.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_EVENTS_H -#define PANDA_TOOLING_ECMASCRIPT_EVENTS_H +#ifndef ECMASCRIPT_TOOLING_BASE_PT_EVENTS_H +#define ECMASCRIPT_TOOLING_BASE_PT_EVENTS_H #include #include diff --git a/ecmascript/tooling/base/pt_params.cpp b/ecmascript/tooling/base/pt_params.cpp index 3db16557c4263bd10eff4b53e81d2109bff1f405..156c1bd8017d71ca6500c77305b8e746f8c6e11a 100644 --- a/ecmascript/tooling/base/pt_params.cpp +++ b/ecmascript/tooling/base/pt_params.cpp @@ -43,8 +43,8 @@ std::unique_ptr EnableParams::Create(const EcmaVM *ecmaVm, const L return paramsObject; } -std::unique_ptr EvaluateOnCallFrameParams::Create( - const EcmaVM *ecmaVm, const Local ¶ms) +std::unique_ptr EvaluateOnCallFrameParams::Create(const EcmaVM *ecmaVm, + const Local ¶ms) { ASSERT(ecmaVm); if (params.IsEmpty()) { @@ -82,8 +82,8 @@ std::unique_ptr EvaluateOnCallFrameParams::Create( paramsObject->objectGroup_ = DebuggerApi::ConvertToString(StringRef::Cast(*result)->ToString()); } - result = Local(params)->Get( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "includeCommandLineAPI"))); + result = Local(params)->Get(ecmaVm, + Local(StringRef::NewFromUtf8(ecmaVm, "includeCommandLineAPI"))); if (!result.IsEmpty() && result->IsBoolean()) { paramsObject->includeCommandLineApi_ = result->IsTrue(); } @@ -117,8 +117,8 @@ std::unique_ptr EvaluateOnCallFrameParams::Create( return paramsObject; } -std::unique_ptr GetPossibleBreakpointsParams::Create( - const EcmaVM *ecmaVm, const Local ¶ms) +std::unique_ptr GetPossibleBreakpointsParams::Create(const EcmaVM *ecmaVm, + const Local ¶ms) { ASSERT(ecmaVm); if (params.IsEmpty()) { @@ -174,8 +174,8 @@ std::unique_ptr GetPossibleBreakpointsParams::Crea return paramsObject; } -std::unique_ptr GetScriptSourceParams::Create( - const EcmaVM *ecmaVm, const Local ¶ms) +std::unique_ptr GetScriptSourceParams::Create(const EcmaVM *ecmaVm, + const Local ¶ms) { ASSERT(ecmaVm); if (params.IsEmpty()) { @@ -204,8 +204,8 @@ std::unique_ptr GetScriptSourceParams::Create( return paramsObject; } -std::unique_ptr RemoveBreakpointParams::Create( - const EcmaVM *ecmaVm, const Local ¶ms) +std::unique_ptr RemoveBreakpointParams::Create(const EcmaVM *ecmaVm, + const Local ¶ms) { ASSERT(ecmaVm); if (params.IsEmpty()) { @@ -261,8 +261,8 @@ std::unique_ptr ResumeParams::Create(const EcmaVM *ecmaVm, const L return paramsObject; } -std::unique_ptr SetAsyncCallStackDepthParams::Create( - const EcmaVM *ecmaVm, const Local ¶ms) +std::unique_ptr SetAsyncCallStackDepthParams::Create(const EcmaVM *ecmaVm, + const Local ¶ms) { ASSERT(ecmaVm); if (params.IsEmpty()) { @@ -291,8 +291,8 @@ std::unique_ptr SetAsyncCallStackDepthParams::Crea return paramsObject; } -std::unique_ptr SetBlackboxPatternsParams::Create( - const EcmaVM *ecmaVm, const Local ¶ms) +std::unique_ptr SetBlackboxPatternsParams::Create(const EcmaVM *ecmaVm, + const Local ¶ms) { ASSERT(ecmaVm); if (params.IsEmpty()) { @@ -333,8 +333,8 @@ std::unique_ptr SetBlackboxPatternsParams::Create( return paramsObject; } -std::unique_ptr SetBreakpointByUrlParams::Create( - const EcmaVM *ecmaVm, const Local ¶ms) +std::unique_ptr SetBreakpointByUrlParams::Create(const EcmaVM *ecmaVm, + const Local ¶ms) { ASSERT(ecmaVm); if (params.IsEmpty()) { @@ -403,8 +403,8 @@ std::unique_ptr SetBreakpointByUrlParams::Create( return paramsObject; } -std::unique_ptr SetPauseOnExceptionsParams::Create( - const EcmaVM *ecmaVm, const Local ¶ms) +std::unique_ptr SetPauseOnExceptionsParams::Create(const EcmaVM *ecmaVm, + const Local ¶ms) { ASSERT(ecmaVm); if (params.IsEmpty()) { @@ -558,8 +558,8 @@ std::unique_ptr GetPropertiesParams::Create(const EcmaVM *e error += "'ownProperties' should be a Boolean;"; } } - result = Local(params)->Get( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "accessorPropertiesOnly"))); + result = Local(params)->Get(ecmaVm, + Local(StringRef::NewFromUtf8(ecmaVm, "accessorPropertiesOnly"))); if (!result.IsEmpty()) { if (result->IsBoolean()) { paramsObject->accessorPropertiesOnly_ = result->IsTrue(); diff --git a/ecmascript/tooling/base/pt_params.h b/ecmascript/tooling/base/pt_params.h index 624dad17bf22391a6cfd6ad38b69ac49d2965747..dbb32fad553592bbefe2deb686d8acaa88da70f9 100644 --- a/ecmascript/tooling/base/pt_params.h +++ b/ecmascript/tooling/base/pt_params.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_PARAMS_H -#define PANDA_TOOLING_ECMASCRIPT_PARAMS_H +#ifndef ECMASCRIPT_TOOLING_BASE_PT_PARAMS_H +#define ECMASCRIPT_TOOLING_BASE_PT_PARAMS_H #include "ecmascript/tooling/base/pt_types.h" diff --git a/ecmascript/tooling/base/pt_returns.cpp b/ecmascript/tooling/base/pt_returns.cpp index a21db526f98d0c0f884691bdef334db506dc7220..13c28ca88a4dd1d94570a2a1fafe13afb1bd1247 100644 --- a/ecmascript/tooling/base/pt_returns.cpp +++ b/ecmascript/tooling/base/pt_returns.cpp @@ -130,8 +130,8 @@ Local SetBreakpointReturns::ToObject(const EcmaVM *ecmaVm) Local(StringRef::NewFromUtf8(ecmaVm, breakpointId_.c_str()))); Local location = location_->ToObject(ecmaVm); - result->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "actualLocation")), Local(location)); + result->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "actualLocation")), + Local(location)); return result; } diff --git a/ecmascript/tooling/base/pt_returns.h b/ecmascript/tooling/base/pt_returns.h index 0fe9d88878d4a616c5e6a3a08aeb5dcbc379e8ea..110b6b853d4bbecd0ae5d73ea29e547f131f5b8c 100644 --- a/ecmascript/tooling/base/pt_returns.h +++ b/ecmascript/tooling/base/pt_returns.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_RETURNS_H -#define PANDA_TOOLING_ECMASCRIPT_RETURNS_H +#ifndef ECMASCRIPT_TOOLING_BASE_PT_RETURNS_H +#define ECMASCRIPT_TOOLING_BASE_PT_RETURNS_H #include "ecmascript/tooling/base/pt_types.h" diff --git a/ecmascript/tooling/base/pt_script.h b/ecmascript/tooling/base/pt_script.h index c64f48151a7ffd785b57ef5cc841fd0264faa8c9..a88ece95e388d3ac9f7e210e9db2bb93d92c6c7c 100644 --- a/ecmascript/tooling/base/pt_script.h +++ b/ecmascript/tooling/base/pt_script.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_DEBUGGER_SCRIPT_H -#define PANDA_TOOLING_ECMASCRIPT_DEBUGGER_SCRIPT_H +#ifndef ECMASCRIPT_TOOLING_BASE_PT_SCRIPT_H +#define ECMASCRIPT_TOOLING_BASE_PT_SCRIPT_H #include "libpandabase/macros.h" #include "ecmascript/mem/c_string.h" diff --git a/ecmascript/tooling/base/pt_types.cpp b/ecmascript/tooling/base/pt_types.cpp index 313a73f779cadd24427f64f2937cabcc7f8df8cd..7822525e9a256db8c784bdefc7c0330bb5367ec5 100644 --- a/ecmascript/tooling/base/pt_types.cpp +++ b/ecmascript/tooling/base/pt_types.cpp @@ -140,8 +140,8 @@ std::unique_ptr RemoteObject::FromTagged(const EcmaVM *ecmaVm, con return std::make_unique(ecmaVm, tagged, ObjectClassName::Promise, ObjectSubType::Promise); } if (tagged->IsArrayBuffer()) { - return std::make_unique( - ecmaVm, tagged, ObjectClassName::Arraybuffer, ObjectSubType::Arraybuffer); + return std::make_unique(ecmaVm, tagged, ObjectClassName::Arraybuffer, + ObjectSubType::Arraybuffer); } if (tagged->IsArrayIterator()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::ArrayIterator); @@ -150,12 +150,12 @@ std::unique_ptr RemoteObject::FromTagged(const EcmaVM *ecmaVm, con return std::make_unique(ecmaVm, tagged, ObjectClassName::StringIterator); } if (tagged->IsSetIterator()) { - return std::make_unique( - ecmaVm, tagged, ObjectClassName::SetIterator, ObjectSubType::Iterator); + return std::make_unique(ecmaVm, tagged, ObjectClassName::SetIterator, + ObjectSubType::Iterator); } if (tagged->IsMapIterator()) { - return std::make_unique( - ecmaVm, tagged, ObjectClassName::MapIterator, ObjectSubType::Iterator); + return std::make_unique(ecmaVm, tagged, ObjectClassName::MapIterator, + ObjectSubType::Iterator); } if (tagged->IsObject()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Object); @@ -529,10 +529,10 @@ Local ExceptionDetails::ToObject(const EcmaVM *ecmaVm) params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "text")), Local(StringRef::NewFromUtf8(ecmaVm, text_.c_str()))); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineNumber")), IntegerRef::New(ecmaVm, line_)); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "columnNumber")), IntegerRef::New(ecmaVm, column_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineNumber")), + IntegerRef::New(ecmaVm, line_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "columnNumber")), + IntegerRef::New(ecmaVm, column_)); if (scriptId_) { params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "scriptId")), @@ -558,8 +558,8 @@ Local ExceptionDetails::ToObject(const EcmaVM *ecmaVm) return params; } -std::unique_ptr InternalPropertyDescriptor::Create( - const EcmaVM *ecmaVm, const Local ¶ms) +std::unique_ptr InternalPropertyDescriptor::Create(const EcmaVM *ecmaVm, + const Local ¶ms) { if (params.IsEmpty() || !params->IsObject()) { LOG(ERROR, DEBUGGER) << "InternalPropertyDescriptor::Create params is nullptr"; @@ -617,8 +617,8 @@ Local InternalPropertyDescriptor::ToObject(const EcmaVM *ecmaVm) return params; } -std::unique_ptr PrivatePropertyDescriptor::Create( - const EcmaVM *ecmaVm, const Local ¶ms) +std::unique_ptr PrivatePropertyDescriptor::Create(const EcmaVM *ecmaVm, + const Local ¶ms) { if (params.IsEmpty() || !params->IsObject()) { LOG(ERROR, DEBUGGER) << "PrivatePropertyDescriptor::Create params is nullptr"; @@ -714,8 +714,8 @@ Local PrivatePropertyDescriptor::ToObject(const EcmaVM *ecmaVm) return params; } -std::unique_ptr PropertyDescriptor::FromProperty( - const EcmaVM *ecmaVm, const Local &name, const PropertyAttribute &property) +std::unique_ptr PropertyDescriptor::FromProperty(const EcmaVM *ecmaVm, + const Local &name, const PropertyAttribute &property) { std::unique_ptr debuggerProperty = std::make_unique(); @@ -906,8 +906,8 @@ Local PropertyDescriptor::ToObject(const EcmaVM *ecmaVm) params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "configurable")), BooleanRef::New(ecmaVm, configurable_)); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "enumerable")), BooleanRef::New(ecmaVm, enumerable_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "enumerable")), + BooleanRef::New(ecmaVm, enumerable_)); if (wasThrown_) { params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "wasThrown")), @@ -981,8 +981,8 @@ Local Location::ToObject(const EcmaVM *ecmaVm) params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "scriptId")), Local(StringRef::NewFromUtf8(ecmaVm, scriptId_.c_str()))); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineNumber")), IntegerRef::New(ecmaVm, line_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineNumber")), + IntegerRef::New(ecmaVm, line_)); if (column_) { params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "columnNumber")), @@ -1034,11 +1034,10 @@ Local ScriptPosition::ToObject(const EcmaVM *ecmaVm) { Local params = NewObject(ecmaVm); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineNumber")), IntegerRef::New(ecmaVm, line_)); - - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "columnNumber")), IntegerRef::New(ecmaVm, column_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineNumber")), + IntegerRef::New(ecmaVm, line_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "columnNumber")), + IntegerRef::New(ecmaVm, column_)); return params; } @@ -1087,8 +1086,8 @@ Local SearchMatch::ToObject(const EcmaVM *ecmaVm) { Local params = NewObject(ecmaVm); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineNumber")), IntegerRef::New(ecmaVm, lineNumber_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineNumber")), + IntegerRef::New(ecmaVm, lineNumber_)); params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineContent")), Local(StringRef::NewFromUtf8(ecmaVm, lineContent_.c_str()))); @@ -1165,8 +1164,8 @@ Local LocationRange::ToObject(const EcmaVM *ecmaVm) Local(StringRef::NewFromUtf8(ecmaVm, "object")), Local(start_->ToObject(ecmaVm))); ASSERT(end_ != nullptr); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "object")), Local(end_->ToObject(ecmaVm))); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "object")), + Local(end_->ToObject(ecmaVm))); return params; } @@ -1237,8 +1236,8 @@ Local BreakLocation::ToObject(const EcmaVM *ecmaVm) params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "scriptId")), Local(StringRef::NewFromUtf8(ecmaVm, scriptId_.c_str()))); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineNumber")), IntegerRef::New(ecmaVm, line_)); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "lineNumber")), + IntegerRef::New(ecmaVm, line_)); if (column_) { params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "columnNumber")), @@ -1444,9 +1443,9 @@ std::unique_ptr CallFrame::Create(const EcmaVM *ecmaVm, const Local key = JSValueRef::Undefined(ecmaVm); for (uint32_t i = 0; i < len; ++i) { key = IntegerRef::New(ecmaVm, i); - Local result = Local(array)->Get(ecmaVm, key->ToString(ecmaVm)); - std::unique_ptr scope = Scope::Create(ecmaVm, result); - if (result.IsEmpty() || scope == nullptr) { + Local resultValue = Local(array)->Get(ecmaVm, key->ToString(ecmaVm)); + std::unique_ptr scope = Scope::Create(ecmaVm, resultValue); + if (resultValue.IsEmpty() || scope == nullptr) { error += "'scopeChain' format invalid;"; } callFrame->scopeChain_.emplace_back(std::move(scope)); @@ -1524,8 +1523,8 @@ Local CallFrame::ToObject(const EcmaVM *ecmaVm) } params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "scopeChain")), values); ASSERT(this_ != nullptr); - params->Set( - ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "this")), Local(this_->ToObject(ecmaVm))); + params->Set(ecmaVm, Local(StringRef::NewFromUtf8(ecmaVm, "this")), + Local(this_->ToObject(ecmaVm))); if (returnValue_) { ASSERT(returnValue_.value() != nullptr); params->Set(ecmaVm, diff --git a/ecmascript/tooling/base/pt_types.h b/ecmascript/tooling/base/pt_types.h index f0f6c9e48db2019031fafc31fa9dbdbfe3888146..5c55cae936d30d03692c7e21a7e9c19c19e79a4c 100644 --- a/ecmascript/tooling/base/pt_types.h +++ b/ecmascript/tooling/base/pt_types.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_TYPES_H -#define PANDA_TOOLING_ECMASCRIPT_TYPES_H +#ifndef ECMASCRIPT_TOOLING_BASE_PT_TYPES_H +#define ECMASCRIPT_TOOLING_BASE_PT_TYPES_H #include #include @@ -386,8 +386,8 @@ public: .SetClassName(classname) .SetDescription(DescriptionForObject(ecmaVm, tagged)); } - explicit ObjectRemoteObject( - const EcmaVM *ecmaVm, const Local &tagged, const CString &classname, const CString &subtype) + explicit ObjectRemoteObject(const EcmaVM *ecmaVm, const Local &tagged, const CString &classname, + const CString &subtype) { SetType(RemoteObject::TypeName::Object) .SetSubType(subtype) @@ -680,8 +680,8 @@ public: PropertyDescriptor() = default; ~PropertyDescriptor() override = default; - static std::unique_ptr FromProperty( - const EcmaVM *ecmaVm, const Local &name, const PropertyAttribute &property); + static std::unique_ptr FromProperty(const EcmaVM *ecmaVm, const Local &name, + const PropertyAttribute &property); static std::unique_ptr Create(const EcmaVM *ecmaVm, const Local ¶ms); Local ToObject(const EcmaVM *ecmaVm) override; diff --git a/ecmascript/tooling/debugger_service.cpp b/ecmascript/tooling/debugger_service.cpp index c1452ebf72db76a31ae72aebada934032bb773f5..8cad5b70184ce2f93f7f78d986e69e3ead637d4c 100644 --- a/ecmascript/tooling/debugger_service.cpp +++ b/ecmascript/tooling/debugger_service.cpp @@ -20,7 +20,7 @@ namespace panda::tooling::ecmascript { static std::unique_ptr g_handler = nullptr; // NOLINT(fuchsia-statically-constructed-objects) -void InitializeDebugger(const std::function &onResponse, void *vm) +void InitializeDebugger(const std::function &onResponse, const EcmaVM *vm) { g_handler = std::make_unique(onResponse, vm); } diff --git a/ecmascript/tooling/debugger_service.h b/ecmascript/tooling/debugger_service.h index e788261ffce51b92ce3dab5d4c54a26eae8df914..bad3877ee29315d45bae56987638e54cdf5f8525 100644 --- a/ecmascript/tooling/debugger_service.h +++ b/ecmascript/tooling/debugger_service.h @@ -13,14 +13,18 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_DEBUGGER_SERVICE_H -#define PANDA_TOOLING_ECMASCRIPT_DEBUGGER_SERVICE_H +#ifndef ECMASCRIPT_TOOLING_DEBUGGER_SERVICE_H +#define ECMASCRIPT_TOOLING_DEBUGGER_SERVICE_H #include #include #include "ecmascript/common.h" +namespace panda::ecmascript { +class EcmaVM; +} // panda::ecmascript + namespace panda::tooling::ecmascript { #ifdef __cplusplus #if __cplusplus @@ -28,7 +32,8 @@ extern "C" { #endif #endif /* End of #ifdef __cplusplus */ -PUBLIC_API void InitializeDebugger(const std::function &on_response, void *vm); +PUBLIC_API void InitializeDebugger(const std::function &on_response, + const ::panda::ecmascript::EcmaVM *vm); PUBLIC_API void UninitializeDebugger(); diff --git a/ecmascript/tooling/dispatcher.h b/ecmascript/tooling/dispatcher.h index 0df3225af5fc5d7fae0b83a5152d80c0b0bf97c5..9e3537704e8c4de254c73efd99673e647e9e219e 100644 --- a/ecmascript/tooling/dispatcher.h +++ b/ecmascript/tooling/dispatcher.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_DISPATCHER_H -#define PANDA_TOOLING_ECMASCRIPT_DISPATCHER_H +#ifndef ECMASCRIPT_TOOLING_DISPATCHER_H +#define ECMASCRIPT_TOOLING_DISPATCHER_H #include #include @@ -77,6 +77,8 @@ public: return ecmaVm_; } + ~DispatchRequest() = default; + private: const EcmaVM *ecmaVm_ {nullptr}; int32_t callId_ {-1}; @@ -109,6 +111,8 @@ public: static DispatchResponse Ok(); static DispatchResponse Fail(const CString &message); + ~DispatchResponse() = default; + private: DispatchResponse() = default; @@ -130,7 +134,7 @@ protected: std::unique_ptr result); private: - FrontEnd *frontend_{nullptr}; + FrontEnd *frontend_ {nullptr}; NO_COPY_SEMANTIC(DispatcherBase); NO_MOVE_SEMANTIC(DispatcherBase); @@ -149,4 +153,4 @@ private: NO_MOVE_SEMANTIC(Dispatcher); }; } // namespace panda::tooling::ecmascript -#endif \ No newline at end of file +#endif diff --git a/ecmascript/tooling/front_end.h b/ecmascript/tooling/front_end.h index d66622b2eb8f50bdafae1f13a6fa55b988c3c32b..f46e7da9809b899732fb042274885650dcd299da 100644 --- a/ecmascript/tooling/front_end.h +++ b/ecmascript/tooling/front_end.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_FRONT_END_H -#define PANDA_TOOLING_ECMASCRIPT_FRONT_END_H +#ifndef ECMASCRIPT_TOOLING_FRONT_END_H +#define ECMASCRIPT_TOOLING_FRONT_END_H #include "libpandabase/macros.h" #include "ecmascript/tooling/base/pt_events.h" diff --git a/ecmascript/tooling/interface/debugger_api.cpp b/ecmascript/tooling/interface/debugger_api.cpp index eeaf915bc04ab17a9ecde229c29fd840541f7e1f..56248cddeff797bcd48cc89e1d67da0525f99909 100644 --- a/ecmascript/tooling/interface/debugger_api.cpp +++ b/ecmascript/tooling/interface/debugger_api.cpp @@ -179,4 +179,10 @@ std::optional DebuggerApi::RemoveBreakpoint(JSDebugger *debugger, const P { return debugger->RemoveBreakpoint(location); } + +// JSMethod +CString DebuggerApi::ParseFunctionName(const JSMethod *method) +{ + return method->ParseFunctionName(); +} } // namespace panda::tooling::ecmascript diff --git a/ecmascript/tooling/interface/debugger_api.h b/ecmascript/tooling/interface/debugger_api.h index 78a976b8f0ee75f05f80ef669fac47918d2a41b0..12afcd453d5593759c1533bfaa422b8666f0d207 100644 --- a/ecmascript/tooling/interface/debugger_api.h +++ b/ecmascript/tooling/interface/debugger_api.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_DEBUGGER_API_H -#define PANDA_TOOLING_ECMASCRIPT_DEBUGGER_API_H +#ifndef ECMASCRIPT_TOOLING_INTERFACE_DEBUGGER_API_H +#define ECMASCRIPT_TOOLING_INTERFACE_DEBUGGER_API_H #include @@ -87,7 +87,10 @@ public: static std::optional RegisterHooks(JSDebugger *debugger, PtHooks *hooks); static std::optional SetBreakpoint(JSDebugger *debugger, const PtLocation &location); static std::optional RemoveBreakpoint(JSDebugger *debugger, const PtLocation &location); + + // JSMehthod + static CString ParseFunctionName(const JSMethod *method); }; } // namespace panda::tooling::ecmascript -#endif // PANDA_TOOLING_ECMASCRIPT_DEBUGGER_API_H \ No newline at end of file +#endif // ECMASCRIPT_TOOLING_DEBUGGER_API_H diff --git a/ecmascript/tooling/interface/js_debugger.h b/ecmascript/tooling/interface/js_debugger.h index 68c4186c91a3b61aa2f3526a8e163bd39848ec85..ed2a05b79ee2d933c1f0590f1d5c58a2060e8cde 100644 --- a/ecmascript/tooling/interface/js_debugger.h +++ b/ecmascript/tooling/interface/js_debugger.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_JS_DEBUGGER_H -#define PANDA_TOOLING_ECMASCRIPT_JS_DEBUGGER_H +#ifndef ECMASCRIPT_TOOLING_INTERFACE_JS_DEBUGGER_H +#define ECMASCRIPT_TOOLING_INTERFACE_JS_DEBUGGER_H #include "ecmascript/ecma_vm.h" #include "ecmascript/js_method.h" @@ -136,18 +136,18 @@ public: { return {}; } - std::optional SetVariable( - PtThread thread, uint32_t frameDepth, int32_t regNumber, const PtValue &value) const override + std::optional SetVariable(PtThread thread, uint32_t frameDepth, int32_t regNumber, + const PtValue &value) const override { return {}; } - std::optional GetVariable( - PtThread thread, uint32_t frameDepth, int32_t regNumber, PtValue *result) const override + std::optional GetVariable(PtThread thread, uint32_t frameDepth, int32_t regNumber, + PtValue *result) const override { return {}; } - std::optional GetProperty( - [[maybe_unused]] PtObject object, [[maybe_unused]] PtProperty property, PtValue *value) const override + std::optional GetProperty([[maybe_unused]] PtObject object, [[maybe_unused]] PtProperty property, + PtValue *value) const override { return {}; } @@ -161,18 +161,18 @@ public: { return {}; } - std::optional RetransformClasses( - [[maybe_unused]] int32_t classCount, [[maybe_unused]] const PtClass *classes) const override + std::optional RetransformClasses([[maybe_unused]] int32_t classCount, + [[maybe_unused]] const PtClass *classes) const override { return {}; } - std::optional RedefineClasses( - [[maybe_unused]] int32_t classCount, [[maybe_unused]] const PandaClassDefinition *classes) const override + std::optional RedefineClasses([[maybe_unused]] int32_t classCount, + [[maybe_unused]] const PandaClassDefinition *classes) const override { return {}; } - std::optional RestartFrame( - [[maybe_unused]] PtThread thread, [[maybe_unused]] uint32_t frameNumber) const override + std::optional RestartFrame([[maybe_unused]] PtThread thread, + [[maybe_unused]] uint32_t frameNumber) const override { return {}; } @@ -234,4 +234,4 @@ private: }; } // namespace panda::tooling::ecmascript -#endif // PANDA_TOOLING_ECMASCRIPT_JS_DEBUGGER_H +#endif // ECMASCRIPT_TOOLING_JS_DEBUGGER_H diff --git a/ecmascript/tooling/protocol_handler.cpp b/ecmascript/tooling/protocol_handler.cpp index 3b5546c067afb21ab62bc5b968edcf3ee4095830..aacf3d32a2b9799ed6ea38df4f7a73feebde01a5 100644 --- a/ecmascript/tooling/protocol_handler.cpp +++ b/ecmascript/tooling/protocol_handler.cpp @@ -20,8 +20,8 @@ #include "utils/logger.h" namespace panda::tooling::ecmascript { -ProtocolHandler::ProtocolHandler(std::function callback, const void *vm) - : callback_(std::move(callback)), vm_(static_cast(vm)) +ProtocolHandler::ProtocolHandler(std::function callback, const EcmaVM *vm) + : callback_(std::move(callback)), vm_(vm) { dispatcher_ = std::make_unique(this); } @@ -75,16 +75,15 @@ void ProtocolHandler::SendCommand(const CString &msg) queueLock_.Unlock(); } -void ProtocolHandler::SendResponse( - const DispatchRequest &request, const DispatchResponse &response, std::unique_ptr result) +void ProtocolHandler::SendResponse(const DispatchRequest &request, const DispatchResponse &response, + std::unique_ptr result) { LOG(INFO, DEBUGGER) << "ProtocolHandler::SendResponse: " << (response.IsOk() ? "success" : "failed: " + response.GetMessage()); const EcmaVM *ecmaVm = request.GetEcmaVM(); Local reply = PtBaseTypes::NewObject(ecmaVm); - reply->Set( - ecmaVm, StringRef::NewFromUtf8(ecmaVm, "id"), IntegerRef::New(ecmaVm, request.GetCallId())); + reply->Set(ecmaVm, StringRef::NewFromUtf8(ecmaVm, "id"), IntegerRef::New(ecmaVm, request.GetCallId())); Local resultObj; if (response.IsOk() && result != nullptr) { resultObj = result->ToObject(ecmaVm); diff --git a/ecmascript/tooling/protocol_handler.h b/ecmascript/tooling/protocol_handler.h index 39c76e38ab5977b5c45e2b3ef151168b85f80e68..ef6950bb20b8eeab64f01228a13aa922b025cc05 100644 --- a/ecmascript/tooling/protocol_handler.h +++ b/ecmascript/tooling/protocol_handler.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_ECMASCRIPT_PROTOCOL_HANDLER_H -#define PANDA_TOOLING_ECMASCRIPT_PROTOCOL_HANDLER_H +#ifndef ECMASCRIPT_TOOLING_PROTOCOL_HANDLER_H +#define ECMASCRIPT_TOOLING_PROTOCOL_HANDLER_H #include #include @@ -25,7 +25,7 @@ namespace panda::tooling::ecmascript { class ProtocolHandler final : public FrontEnd { public: - explicit ProtocolHandler(std::function callback, const void *vm); + explicit ProtocolHandler(std::function callback, const EcmaVM *vm); ~ProtocolHandler() override = default; void WaitForDebugger(const EcmaVM *ecmaVm) override; @@ -35,7 +35,7 @@ public: void SendResponse(const DispatchRequest &request, const DispatchResponse &response, std::unique_ptr result) override; void SendNotification(const EcmaVM *ecmaVm, std::unique_ptr events) override; - const EcmaVM *GetEcmaVM() + const EcmaVM *GetEcmaVM() const { return vm_; } @@ -57,4 +57,4 @@ private: }; } // namespace panda::tooling::ecmascript -#endif \ No newline at end of file +#endif diff --git a/ecmascript/tooling/pt_js_extractor.cpp b/ecmascript/tooling/pt_js_extractor.cpp index c84f898e04b1c86c76b9e5b701e83076e36c794e..7498f82b05b302ae6a890c9d41d687bcffd23956 100644 --- a/ecmascript/tooling/pt_js_extractor.cpp +++ b/ecmascript/tooling/pt_js_extractor.cpp @@ -86,20 +86,19 @@ std::unique_ptr PtJSExtractor::GetStepOutStepper(c CList PtJSExtractor::GetStepRanges(File::EntityId methodId, uint32_t offset) { - CList ranges; + CList ranges {}; auto table = GetLineNumberTable(methodId); - MatchWithOffset( - [table, &ranges](int32_t line) -> bool { - for (auto it = table.begin(); it != table.end();) { - auto next = it + 1; - if (static_cast(it->line) == line) { - ranges.push_back({it->offset, next != table.end() ? next->offset : UINT32_MAX}); - } - it = next; + auto offsetFunc = [table, &ranges](int32_t line) -> bool { + for (auto it = table.begin(); it != table.end(); ++it) { + auto next = it + 1; + if (static_cast(it->line) == line) { + PtStepRange range {it->offset, next != table.end() ? next->offset : UINT32_MAX}; + ranges.push_back(range); } - return true; - }, - methodId, offset); + } + return true; + }; + MatchWithOffset(offsetFunc, methodId, offset); return ranges; } diff --git a/ecmascript/tooling/pt_js_extractor.h b/ecmascript/tooling/pt_js_extractor.h index 581a71ec5331e822c10e5c07fd5d7d646df071b5..40b23512267e621b470a3a6a0e502ece02f1d5f1 100644 --- a/ecmascript/tooling/pt_js_extractor.h +++ b/ecmascript/tooling/pt_js_extractor.h @@ -21,6 +21,7 @@ #include "ecmascript/mem/c_containers.h" #include "libpandafile/debug_info_extractor.h" #include "libpandabase/macros.h" +#include "include/tooling/debug_interface.h" namespace panda::tooling::ecmascript { using panda::ecmascript::CList; @@ -62,7 +63,7 @@ public: explicit PtJSExtractor(const File *pf) : DebugInfoExtractor(pf) {} virtual ~PtJSExtractor() = default; - template + template bool MatchWithLine(const Callback &cb, int32_t line) { auto methods = GetMethodIdList(); @@ -77,7 +78,7 @@ public: return false; } - template + template bool MatchWithOffset(const Callback &cb, File::EntityId methodId, uint32_t offset) { auto table = GetLineNumberTable(methodId); diff --git a/ecmascript/tooling/test/BUILD.gn b/ecmascript/tooling/test/BUILD.gn index 8b00c1fa1e909eab5c808f4a04e3e1b8b7e653ab..74523e0ccaa5c002f1472d9ac632b55310201bd6 100644 --- a/ecmascript/tooling/test/BUILD.gn +++ b/ecmascript/tooling/test/BUILD.gn @@ -87,6 +87,7 @@ ohos_shared_library("jsdebugtest") { deps = [ "$ark_root/libpandabase:libarkbase", "$ark_root/libpandafile:libarkfile", + "//ark/js_runtime:libark_js_intl_static", "//ark/js_runtime:libark_jsruntime_static", "//ark/js_runtime/ecmascript/tooling:libark_ecma_debugger_static", ] @@ -195,7 +196,7 @@ group("unittest") { # deps file deps = [ - # ":DebuggerCommandsTest", + ":DebuggerCommandsTest", ":DebuggerEventsTest", ":DebuggerTypesTest", ":EcmaDebugApiTest", @@ -207,7 +208,7 @@ group("host_unittest") { # deps file deps = [ - # ":DebuggerCommandsTestAction(${host_toolchain})", + ":DebuggerCommandsTestAction(${host_toolchain})", ":DebuggerEventsTestAction(${host_toolchain})", ":DebuggerTypesTestAction(${host_toolchain})", ] diff --git a/ecmascript/tooling/test/api_test.h b/ecmascript/tooling/test/api_test.h index 1e9f5461539c17566ec74ff9c7d19e825ee1a1b2..39e520e4ddafd86d649d8ff6640faa04cec70472 100644 --- a/ecmascript/tooling/test/api_test.h +++ b/ecmascript/tooling/test/api_test.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_DEBUG_TEST_API_TEST_H -#define PANDA_RUNTIME_DEBUG_TEST_API_TEST_H +#ifndef ECMASCRIPT_TOOLING_TEST_API_TEST_H +#define ECMASCRIPT_TOOLING_TEST_API_TEST_H #include #include "ecmascript/tooling/agent/js_backend.h" @@ -68,4 +68,4 @@ struct ApiTest { }; } // namespace panda::tooling::ecmascript::test -#endif // PANDA_RUNTIME_DEBUG_TEST_API_TEST_H +#endif // ECMASCRIPT_TOOLING_TEST_API_TEST_H diff --git a/ecmascript/tooling/test/api_tests/api_tests.h b/ecmascript/tooling/test/api_tests/api_tests.h index d1a5773fb79abd9e72de73cecf0e0ea71e7ebb7a..d06c8abd0df9596cdbccbb370b9e768beba67554 100644 --- a/ecmascript/tooling/test/api_tests/api_tests.h +++ b/ecmascript/tooling/test/api_tests/api_tests.h @@ -14,5 +14,10 @@ */ // Js +#ifndef ECMASCRIPT_TOOLING_TEST_JS_VM_EVENT_TEST_H +#define ECMASCRIPT_TOOLING_TEST_JS_VM_EVENT_TEST_H + #include "js/js_breakpoint_test.h" #include "js/js_single_step_test.h" + +#endif // ECMASCRIPT_TOOLING_TEST_JS_VM_EVENT_TEST_H \ No newline at end of file diff --git a/ecmascript/tooling/test/api_tests/js/js_breakpoint_test.h b/ecmascript/tooling/test/api_tests/js/js_breakpoint_test.h index bb20e04af6529f0e8064caf8f2bf05d2305b0e60..2b510861b43a56e5d8ba8e72a239445a601654a9 100644 --- a/ecmascript/tooling/test/api_tests/js/js_breakpoint_test.h +++ b/ecmascript/tooling/test/api_tests/js/js_breakpoint_test.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_TEST_JS_BREAKPOINT_TEST_H -#define PANDA_TOOLING_TEST_JS_BREAKPOINT_TEST_H +#ifndef ECMASCRIPT_TOOLING_TEST_JS_BREAKPOINT_TEST_H +#define ECMASCRIPT_TOOLING_TEST_JS_BREAKPOINT_TEST_H #include "ecmascript/tooling/test/test_util.h" #include "ecmascript/mem/c_string.h" @@ -72,9 +72,7 @@ public: { return {panda_file_, entry_point_}; } - ~JsBreakpointTest() = default; - private: CString panda_file_ = "/data/app/Sample.abc"; CString entry_point_ = "_GLOBAL::func_main_0"; @@ -89,4 +87,4 @@ std::unique_ptr GetJsBreakpointTest() } } // namespace panda::tooling::ecmascript::test -#endif // PANDA_TOOLING_TEST_JS_BREAKPOINT_TEST_H +#endif // ECMASCRIPT_TOOLING_TEST_JS_BREAKPOINT_TEST_H diff --git a/ecmascript/tooling/test/api_tests/js/js_single_step_test.h b/ecmascript/tooling/test/api_tests/js/js_single_step_test.h index 9de0f6396bb59cf9701eb47b0a8a6c01b45b5b75..bb85191e6d73d603b63c143c3b5f8ac0c427fc11 100644 --- a/ecmascript/tooling/test/api_tests/js/js_single_step_test.h +++ b/ecmascript/tooling/test/api_tests/js/js_single_step_test.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_TOOLING_TEST_JS_SINGLE_STEP_TEST_H -#define PANDA_TOOLING_TEST_JS_SINGLE_STEP_TEST_H +#ifndef ECMASCRIPT_TOOLING_TEST_JS_SINGLE_STEP_TEST_H +#define ECMASCRIPT_TOOLING_TEST_JS_SINGLE_STEP_TEST_H #include "ecmascript/tooling/test/test_util.h" @@ -99,4 +99,4 @@ std::unique_ptr GetJsSingleStepTest() } } // namespace panda::tooling::ecmascript::test -#endif // PANDA_TOOLING_TEST_JS_SINGLE_STEP_TEST_H +#endif // ECMASCRIPT_TOOLING_TEST_JS_SINGLE_STEP_TEST_H diff --git a/ecmascript/tooling/test/debugger_commands_test.cpp b/ecmascript/tooling/test/debugger_commands_test.cpp index 1a04e912e998428e97f88dd57d7e7a0557e939f0..d2d9c537db2bf384be2aed5513e5d634c8224c3c 100644 --- a/ecmascript/tooling/test/debugger_commands_test.cpp +++ b/ecmascript/tooling/test/debugger_commands_test.cpp @@ -28,7 +28,6 @@ using namespace panda::tooling::ecmascript; using namespace panda::tooling; namespace panda::test { - class DebuggerCommandsTest : public testing::Test { public: static void SetUpTestCase() diff --git a/ecmascript/tooling/test/debugger_events_test.cpp b/ecmascript/tooling/test/debugger_events_test.cpp index 11f6615f22016859359afa8be8afac4fa68aa67f..36125f5b52169f7b3b98a5356541937e6957c95b 100644 --- a/ecmascript/tooling/test/debugger_events_test.cpp +++ b/ecmascript/tooling/test/debugger_events_test.cpp @@ -28,7 +28,6 @@ using ObjectSubType = RemoteObject::SubTypeName; using ObjectClassName = RemoteObject::ClassName; namespace panda::test { - class DebuggerEventsTest : public testing::Test { public: static void SetUpTestCase() @@ -911,5 +910,4 @@ HWTEST_F_L0(DebuggerEventsTest, ScriptParsedToObjectTest) ASSERT_TRUE(!result.IsEmpty()); EXPECT_EQ("hh", Local(result)->ToString()); } - } // namespace panda::test \ No newline at end of file diff --git a/ecmascript/tooling/test/debugger_types_test.cpp b/ecmascript/tooling/test/debugger_types_test.cpp index 6818eac7732b0bda31b9bde8d5e31d974ab71f01..3a626ca6f6f6c264d27c98fabbbd6496783dd451 100644 --- a/ecmascript/tooling/test/debugger_types_test.cpp +++ b/ecmascript/tooling/test/debugger_types_test.cpp @@ -1780,5 +1780,4 @@ HWTEST_F_L0(DebuggerTypesTest, CallFrameToObjectTest) ASSERT_TRUE(!subResult.IsEmpty()); EXPECT_EQ(std::string(ObjectSubType::I64.c_str()), Local(subResult)->ToString()); } - } // namespace panda::test diff --git a/ecmascript/tooling/test/init.cpp b/ecmascript/tooling/test/init.cpp index a1a0c155a0e15ecef2bae08c68e871dd0ae9285f..ccc0d1b80358a815f2606aa0fbd1c2039c87677d 100644 --- a/ecmascript/tooling/test/init.cpp +++ b/ecmascript/tooling/test/init.cpp @@ -26,7 +26,7 @@ static std::thread g_debuggerThread; static std::unique_ptr g_runner{nullptr}; -extern "C" int32_t StartDebugger(EcmaVM *vm) +extern "C" int32_t StartDebugger(const EcmaVM *vm) { const char *testName = GetCurrentTestName(); g_runner = std::make_unique(testName, vm); diff --git a/ecmascript/tooling/test/test_extractor.h b/ecmascript/tooling/test/test_extractor.h index d1f9b713439590b01a3f73d32d41a493c5b84e46..2e085a9b7bd81669c685ff7b4b8aaafcda25fd4b 100644 --- a/ecmascript/tooling/test/test_extractor.h +++ b/ecmascript/tooling/test/test_extractor.h @@ -12,9 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// Taken from panda-tools/panda-debugger/debugger -#ifndef PANDA_RUNTIME_DEBUG_TEST_DEBUG_INFO_EXTRACTOR_H -#define PANDA_RUNTIME_DEBUG_TEST_DEBUG_INFO_EXTRACTOR_H + +#ifndef ECMASCRIPT_TOOLING_TEST_DEBUG_INFO_EXTRACTOR_H +#define ECMASCRIPT_TOOLING_TEST_DEBUG_INFO_EXTRACTOR_H #include "ecmascript/mem/c_string.h" #include "ecmascript/tooling/pt_js_extractor.h" @@ -58,4 +58,4 @@ public: }; } // namespace panda::tooling::ecmascript::test -#endif // PANDA_RUNTIME_DEBUG_TEST_DEBUG_INFO_EXTRACTOR_H +#endif // ECMASCRIPT_TOOLING_TEST_DEBUG_INFO_EXTRACTOR_H diff --git a/ecmascript/tooling/test/test_list.h b/ecmascript/tooling/test/test_list.h index 93500a4fef8afbff7f36d9e20364f8146da942b0..705dba7ead0084c480004c68977a2308d29ff3f0 100644 --- a/ecmascript/tooling/test/test_list.h +++ b/ecmascript/tooling/test/test_list.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_DEBUG_TEST_TEST_LIST_H -#define PANDA_RUNTIME_DEBUG_TEST_TEST_LIST_H +#ifndef ECMASCRIPT_TOOLING_TEST_TEST_LIST_H +#define ECMASCRIPT_TOOLING_TEST_TEST_LIST_H #include #include @@ -32,4 +32,4 @@ void SetCurrentTestName(const char *testName); std::pair GetTestEntryPoint(const char *testName); } // namespace panda::tooling::ecmascript::test -#endif // PANDA_RUNTIME_DEBUG_TEST_TEST_LIST_H +#endif // ECMASCRIPT_TOOLING_TEST_TEST_LIST_H diff --git a/ecmascript/tooling/test/test_runner.h b/ecmascript/tooling/test/test_runner.h index 11ed3577b81c01e69a7070afe689a03558fa684d..634ac45ac92fe23b2e8e491a7e539fc7e0f6de1a 100644 --- a/ecmascript/tooling/test/test_runner.h +++ b/ecmascript/tooling/test/test_runner.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_DEBUG_TEST_TEST_RUNNER_H -#define PANDA_RUNTIME_DEBUG_TEST_TEST_RUNNER_H +#ifndef ECMASCRIPT_TOOLING_TEST_TEST_RUNNER_H +#define ECMASCRIPT_TOOLING_TEST_TEST_RUNNER_H #include "ecmascript/tooling/test/test_util.h" #include "ecmascript/tooling/agent/js_pt_hooks.h" @@ -23,7 +23,7 @@ namespace panda::tooling::ecmascript::test { class TestRunner : public PtHooks { public: - TestRunner(const char *test_name, EcmaVM *vm) + TestRunner(const char *test_name, const EcmaVM *vm) { backend_ = std::make_unique(vm); test_name_ = test_name; @@ -149,4 +149,4 @@ private: }; } // namespace panda::tooling::ecmascript::test -#endif // PANDA_RUNTIME_DEBUG_TEST_TEST_RUNNER_H +#endif // ECMASCRIPT_TOOLING_TEST_TEST_RUNNER_H diff --git a/ecmascript/tooling/test/test_util.h b/ecmascript/tooling/test/test_util.h index 55eebc5cd58d974527b27522f13f1a4ae7ec912b..5d214eb37946dc0368996394b7071e670b361f0b 100644 --- a/ecmascript/tooling/test/test_util.h +++ b/ecmascript/tooling/test/test_util.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_DEBUG_TEST_TEST_UTIL_H -#define PANDA_RUNTIME_DEBUG_TEST_TEST_UTIL_H +#ifndef ECMASCRIPT_TOOLING_TEST_TEST_UTIL_H +#define ECMASCRIPT_TOOLING_TEST_TEST_UTIL_H #include #include @@ -74,14 +74,14 @@ public: static bool WaitForExit() { - return WaitForEvent( - DebugEvent::VM_DEATH, []() REQUIRES(eventMutex_) { return lastEvent_ == DebugEvent::VM_DEATH; }, [] {}); + return WaitForEvent(DebugEvent::VM_DEATH, + []() REQUIRES(eventMutex_) { return lastEvent_ == DebugEvent::VM_DEATH; }, [] {}); } static bool WaitForInit() { - return WaitForEvent( - DebugEvent::VM_INITIALIZATION, []() REQUIRES(eventMutex_) { return initialized_; }, [] {}); + return WaitForEvent(DebugEvent::VM_INITIALIZATION, + []() REQUIRES(eventMutex_) { return initialized_; }, [] {}); } static void Event(DebugEvent event, PtThread ecmaVm = PtThread::NONE, @@ -172,7 +172,7 @@ public: } private: - template + template static bool WaitForEvent(DebugEvent event, Predicate predicate, OnSuccessAction action) { os::memory::LockHolder holder(eventMutex_); @@ -289,4 +289,4 @@ std::ostream &operator<<(std::ostream &out, std::nullptr_t); ASSERT_THREAD_VALID(suspended); \ } while (0); } // namespace panda::tooling::ecmascript::test -#endif // PANDA_RUNTIME_DEBUG_TEST_TEST_UTIL_H +#endif // ECMASCRIPT_TOOLING_TEST_TEST_UTIL_H diff --git a/ecmascript/transitions_dictionary.h b/ecmascript/transitions_dictionary.h index de114ab494317192529319969060187bd947e1bb..c9daf38f3f25b2d04a7bddd320b2ee1e37f4503b 100644 --- a/ecmascript/transitions_dictionary.h +++ b/ecmascript/transitions_dictionary.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_TRANSITIONS_DICTIONARY_H -#define PANDA_RUNTIME_ECMASCRIPT_TRANSITIONS_DICTIONARY_H +#ifndef ECMASCRIPT_TRANSITIONS_DICTIONARY_H +#define ECMASCRIPT_TRANSITIONS_DICTIONARY_H #include "ecmascript/tagged_hash_table-inl.h" #include "ecmascript/js_symbol.h" diff --git a/ecmascript/vmstat/caller_stat.h b/ecmascript/vmstat/caller_stat.h index f2c406c905bbe939c6e96f9b54206c438d2d1b3b..88bc26f71cf524698f7d321d7f61701ac966f3f9 100644 --- a/ecmascript/vmstat/caller_stat.h +++ b/ecmascript/vmstat/caller_stat.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_CALLER_STAT_H -#define PANDA_RUNTIME_CALLER_STAT_H +#ifndef ECMASCRIPT_VMSTAT_CALLER_STAT_H +#define ECMASCRIPT_VMSTAT_CALLER_STAT_H #include #include diff --git a/ecmascript/vmstat/runtime_stat.cpp b/ecmascript/vmstat/runtime_stat.cpp index 711678e49a37d5d30af616353a1c8d5b26486fdc..9c0df112e50b4b54d800ad2b8817b2c354a76cd9 100644 --- a/ecmascript/vmstat/runtime_stat.cpp +++ b/ecmascript/vmstat/runtime_stat.cpp @@ -22,7 +22,7 @@ namespace panda::ecmascript { // NOLINTNEXTLINE(modernize-avoid-c-arrays) -EcmaRuntimeStat::EcmaRuntimeStat(const char * const runtimeCallerNames[], int count) +EcmaRuntimeStat::EcmaRuntimeStat(const char *const runtimeCallerNames[], int count) { for (int i = 0; i < count; i++) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -55,7 +55,7 @@ void EcmaRuntimeStat::Print() const if (currentTimer_ != nullptr) { currentTimer_->Snapshot(); } - LOG_ECMA(INFO) << GetAllStats(); + LOG_ECMA(ERROR) << GetAllStats(); } void EcmaRuntimeStat::ResetAllCount() diff --git a/ecmascript/vmstat/runtime_stat.h b/ecmascript/vmstat/runtime_stat.h index 15806f6e521014e27319f055f16fc3f877e06958..8367d58d9a200c6c1d4b30866b606d9d8bec8018 100644 --- a/ecmascript/vmstat/runtime_stat.h +++ b/ecmascript/vmstat/runtime_stat.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_ECMA_RUNTIME_RUNTIME_STAT_H -#define PANDA_ECMA_RUNTIME_RUNTIME_STAT_H +#ifndef ECMASCRIPT_VMSTAT_RUNTIME_STAT_H +#define ECMASCRIPT_VMSTAT_RUNTIME_STAT_H #include "ecmascript/ecma_vm.h" #include "ecmascript/js_thread.h" diff --git a/ecmascript/weak_vector-inl.h b/ecmascript/weak_vector-inl.h index f2a85dcbc3ad8e0556a9c839c1e3b95c7185279f..9f27e48850ce5a4f490b5f49c78e8f9b45ce1006 100644 --- a/ecmascript/weak_vector-inl.h +++ b/ecmascript/weak_vector-inl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_WEAK_VECTOR_INL_H -#define PANDA_RUNTIME_ECMASCRIPT_WEAK_VECTOR_INL_H +#ifndef ECMASCRIPT_WEAK_VECTOR_INL_H +#define ECMASCRIPT_WEAK_VECTOR_INL_H #include "weak_vector.h" #include "tagged_array-inl.h" @@ -58,4 +58,4 @@ void WeakVector::SetEnd(const JSThread *thread, array_size_t end) TaggedArray::Set(thread, END_INDEX, JSTaggedValue(end)); } } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_WEAK_VECTOR_INL_H \ No newline at end of file +#endif // ECMASCRIPT_WEAK_VECTOR_INL_H \ No newline at end of file diff --git a/ecmascript/weak_vector.h b/ecmascript/weak_vector.h index 73e357e0d23df4a69445160f4a983f671742aca5..0e8eb02c967d5e3b9a8dd23fcc0963f99960fc1b 100644 --- a/ecmascript/weak_vector.h +++ b/ecmascript/weak_vector.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef PANDA_RUNTIME_ECMASCRIPT_WEAK_VECTOR_H -#define PANDA_RUNTIME_ECMASCRIPT_WEAK_VECTOR_H +#ifndef ECMASCRIPT_WEAK_VECTOR_H +#define ECMASCRIPT_WEAK_VECTOR_H #include "ecmascript/js_handle.h" #include "ecmascript/js_thread.h" @@ -61,4 +61,4 @@ private: inline void SetEnd(const JSThread *thread, array_size_t end); }; } // namespace panda::ecmascript -#endif // PANDA_RUNTIME_ECMASCRIPT_WEAK_VECTOR_H +#endif // ECMASCRIPT_WEAK_VECTOR_H diff --git a/ohos.build b/ohos.build index 3782b5c069197f21f153fe5f7a13f992cb4922a3..414d8769961d94684525dc5576b7d34df1989c27 100644 --- a/ohos.build +++ b/ohos.build @@ -12,8 +12,7 @@ "inner_kits": [], "system_kits": [], "test_list": [ - "//ark/js_runtime:ark_js_unittest", - "//ark/js_runtime:ark_js_host_unittest" + "//ark/js_runtime:ark_js_unittest" ] } } diff --git a/test/test_helper.gni b/test/test_helper.gni index 5cfa05eec28e0a6eb72bb6d6c59cb0bbdd782579..3a709bd090cdaaa41102e7e095896d5d2b679a83 100644 --- a/test/test_helper.gni +++ b/test/test_helper.gni @@ -26,7 +26,14 @@ template("host_unittest_action") { _target_name_ = "${target_name}" _deps_ = invoker.deps - _deps_ += [ "//ark/js_runtime:libark_jsruntime_static" ] + _deps_ += [ + "//ark/js_runtime:libark_jsruntime_static", + "//ark/js_runtime:libark_js_intl_static", + ] + + if (!is_standard_system) { + _deps_ += [ "//ark/runtime/runtime:libarkruntime" ] + } # unittest for phone running ohos_unittest(_target_name_) { @@ -107,7 +114,7 @@ template("host_moduletest_action") { "--script-file", rebase_path(root_out_dir) + "/ark/ark_js_runtime/ark_js_vm", "--script-args", - rebase_path(_test_abc_path_) + " _GLOBAL::func_main_0", + rebase_path(_test_abc_path_), "--expect-file", rebase_path(_test_expect_path_), "--env-path",