From d63436b6c901b6d8bd756d7b7b3b923baa87970e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E4=BA=91=E9=A3=9E?= Date: Mon, 25 Aug 2025 10:37:30 +0800 Subject: [PATCH] cherry pick !12901to 5.0.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICU4KW?from=project-issue Signed-off-by: 杨云飞 --- .../compiler/operations_stub_builder.cpp | 34 +++++++++++++++---- ecmascript/interpreter/interpreter-inl.cpp | 28 ++++++++++++--- ecmascript/js_tagged_number.h | 14 ++++++-- test/moduletest/typearray/expect_output.txt | 5 ++- test/moduletest/typearray/typearray.js | 16 +++++++++ 5 files changed, 84 insertions(+), 13 deletions(-) diff --git a/ecmascript/compiler/operations_stub_builder.cpp b/ecmascript/compiler/operations_stub_builder.cpp index 6979ad04b9..d7ae11ecdd 100644 --- a/ecmascript/compiler/operations_stub_builder.cpp +++ b/ecmascript/compiler/operations_stub_builder.cpp @@ -1265,13 +1265,24 @@ GateRef OperationsStubBuilder::Inc(GateRef glue, GateRef value, ProfileOperation Bind(&valueNotInt); { Label valueIsDouble(env); + Label valueIsNanOrInf(env); + Label valueIsNotNanOrInf(env); BRANCH(TaggedIsDouble(value), &valueIsDouble, &slowPath); Bind(&valueIsDouble); { - callback.ProfileOpType(Int32(PGOSampleType::DoubleType())); GateRef valueDouble = GetDoubleOfTDouble(value); - result = DoubleToTaggedDoublePtr(DoubleAdd(valueDouble, Double(1.0))); - Jump(&exit); + callback.ProfileOpType(Int32(PGOSampleType::DoubleType())); + BRANCH_UNLIKELY(DoubleIsNanOrInf(valueDouble), &valueIsNanOrInf, &valueIsNotNanOrInf); + Bind(&valueIsNanOrInf); + { + result = value; + Jump(&exit); + } + Bind(&valueIsNotNanOrInf); + { + result = DoubleToTaggedDoublePtr(DoubleAdd(valueDouble, Double(1.0))); + Jump(&exit); + } } } Bind(&slowPath); @@ -1313,13 +1324,24 @@ GateRef OperationsStubBuilder::Dec(GateRef glue, GateRef value, ProfileOperation Bind(&valueNotInt); { Label valueIsDouble(env); + Label valueIsNanOrInf(env); + Label valueIsNotNanOrInf(env); BRANCH(TaggedIsDouble(value), &valueIsDouble, &slowPath); Bind(&valueIsDouble); { - callback.ProfileOpType(Int32(PGOSampleType::DoubleType())); GateRef valueDouble = GetDoubleOfTDouble(value); - result = DoubleToTaggedDoublePtr(DoubleSub(valueDouble, Double(1.0))); - Jump(&exit); + callback.ProfileOpType(Int32(PGOSampleType::DoubleType())); + BRANCH_UNLIKELY(DoubleIsNanOrInf(valueDouble), &valueIsNanOrInf, &valueIsNotNanOrInf); + Bind(&valueIsNanOrInf); + { + result = value; + Jump(&exit); + } + Bind(&valueIsNotNanOrInf); + { + result = DoubleToTaggedDoublePtr(DoubleSub(valueDouble, Double(1.0))); + Jump(&exit); + } } } Bind(&slowPath); diff --git a/ecmascript/interpreter/interpreter-inl.cpp b/ecmascript/interpreter/interpreter-inl.cpp index a99cb75aae..be4747459c 100644 --- a/ecmascript/interpreter/interpreter-inl.cpp +++ b/ecmascript/interpreter/interpreter-inl.cpp @@ -4846,7 +4846,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t SET_ACC(JSTaggedValue(a0 + 1)); } } else if (value.IsDouble()) { - SET_ACC(JSTaggedValue(value.GetDouble() + 1.0)); + double doubleVal = value.GetDouble(); + if (UNLIKELY(std::isnan(doubleVal) || !std::isfinite(doubleVal))) { + SET_ACC(value); + } else { + SET_ACC(JSTaggedValue(doubleVal + 1.0)); + } } else { // slow path SAVE_PC(); @@ -4873,7 +4878,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t SET_ACC(JSTaggedValue(a0 + 1)); } } else if (value.IsDouble()) { - SET_ACC(JSTaggedValue(value.GetDouble() + 1.0)); + double doubleVal = value.GetDouble(); + if (UNLIKELY(std::isnan(doubleVal) || !std::isfinite(doubleVal))) { + SET_ACC(value); + } else { + SET_ACC(JSTaggedValue(doubleVal + 1.0)); + } } else { // slow path SAVE_PC(); @@ -4897,7 +4907,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t SET_ACC(JSTaggedValue(a0 - 1)); } } else if (value.IsDouble()) { - SET_ACC(JSTaggedValue(value.GetDouble() - 1.0)); + double doubleVal = value.GetDouble(); + if (UNLIKELY(std::isnan(doubleVal) || !std::isfinite(doubleVal))) { + SET_ACC(value); + } else { + SET_ACC(JSTaggedValue(doubleVal - 1.0)); + } } else { // slow path SAVE_PC(); @@ -4923,7 +4938,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, const uint8_t SET_ACC(JSTaggedValue(a0 - 1)); } } else if (value.IsDouble()) { - SET_ACC(JSTaggedValue(value.GetDouble() - 1.0)); + double doubleVal = value.GetDouble(); + if (UNLIKELY(std::isnan(doubleVal) || !std::isfinite(doubleVal))) { + SET_ACC(value); + } else { + SET_ACC(JSTaggedValue(doubleVal - 1.0)); + } } else { // slow path SAVE_PC(); diff --git a/ecmascript/js_tagged_number.h b/ecmascript/js_tagged_number.h index fd67f78ce6..6df81f25fc 100644 --- a/ecmascript/js_tagged_number.h +++ b/ecmascript/js_tagged_number.h @@ -130,7 +130,12 @@ public: } return JSTaggedNumber(value + 1); } - return JSTaggedNumber(GetDouble() + 1.0); + ASSERT(IsDouble()); + double doubleVal = GetDouble(); + if (UNLIKELY(std::isnan(doubleVal) || !std::isfinite(doubleVal))) { + return JSTaggedNumber(doubleVal); + } + return JSTaggedNumber(doubleVal + 1.0); } JSTaggedNumber operator--() const @@ -142,7 +147,12 @@ public: } return JSTaggedNumber(value - 1); } - return JSTaggedNumber(GetDouble() - 1.0); + ASSERT(IsDouble()); + double doubleVal = GetDouble(); + if (UNLIKELY(std::isnan(doubleVal) || !std::isfinite(doubleVal))) { + return JSTaggedNumber(doubleVal); + } + return JSTaggedNumber(doubleVal - 1.0); } inline bool operator!=(const JSTaggedNumber &number) const diff --git a/test/moduletest/typearray/expect_output.txt b/test/moduletest/typearray/expect_output.txt index 127183c051..29cdba8436 100644 --- a/test/moduletest/typearray/expect_output.txt +++ b/test/moduletest/typearray/expect_output.txt @@ -266,4 +266,7 @@ true true true true -true \ No newline at end of file +true +true +Infinity +-Infinity diff --git a/test/moduletest/typearray/typearray.js b/test/moduletest/typearray/typearray.js index e0ce6e5d54..27ec6bb1f5 100644 --- a/test/moduletest/typearray/typearray.js +++ b/test/moduletest/typearray/typearray.js @@ -1078,4 +1078,20 @@ try { arr_reduceRight.reduceRight(sum, 0); } catch (e) { print(e instanceof TypeError); +} + +{ + var v0 = new ArrayBuffer(16); + var v1 = new Int32Array(v0); + v1[1] = 0xfff7ffff; + let v2 = new Float64Array(v0); + v2[0]++; + v2[0]--; + print(Number.isNaN(v2[0])); + let v3 = Infinity; + v3++; + let v4 = -Infinity; + v4--; + print(v3); + print(v4); } \ No newline at end of file -- Gitee