From e683c65bde8b0bcc451094dc7adac13c23a587dd 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:40:38 +0800 Subject: [PATCH] cherry pick !12901to 5.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICU4KY?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/typearray.js | 16 +++++++++ 4 files changed, 80 insertions(+), 12 deletions(-) diff --git a/ecmascript/compiler/operations_stub_builder.cpp b/ecmascript/compiler/operations_stub_builder.cpp index 28f17fd46d..8c9802c1d4 100644 --- a/ecmascript/compiler/operations_stub_builder.cpp +++ b/ecmascript/compiler/operations_stub_builder.cpp @@ -1263,13 +1263,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(TaggedInt(PGOSampleType::DoubleType())); GateRef valueDouble = GetDoubleOfTDouble(value); - result = DoubleToTaggedDoublePtr(DoubleAdd(valueDouble, Double(1.0))); - Jump(&exit); + callback.ProfileOpType(TaggedInt(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); @@ -1311,13 +1322,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(TaggedInt(PGOSampleType::DoubleType())); GateRef valueDouble = GetDoubleOfTDouble(value); - result = DoubleToTaggedDoublePtr(DoubleSub(valueDouble, Double(1.0))); - Jump(&exit); + callback.ProfileOpType(TaggedInt(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 88c696c84a..6e574b1121 100644 --- a/ecmascript/interpreter/interpreter-inl.cpp +++ b/ecmascript/interpreter/interpreter-inl.cpp @@ -4868,7 +4868,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(); @@ -4895,7 +4900,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(); @@ -4919,7 +4929,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(); @@ -4945,7 +4960,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/typearray.js b/test/moduletest/typearray/typearray.js index ffd142804e..d7de157276 100644 --- a/test/moduletest/typearray/typearray.js +++ b/test/moduletest/typearray/typearray.js @@ -1676,4 +1676,20 @@ for (let typedArrEle of iterForTypedArrEntry) { assert_equal(typedArrEleAssertRes,typedArrEleAssertEqual); assert_equal(typedArrEleAssertLengthRes,typedArrEleAssertLengthEqual); +{ + var v0 = new ArrayBuffer(16); + var v1 = new Int32Array(v0); + v1[1] = 0xfff7ffff; + let v2 = new Float64Array(v0); + v2[0]++; + v2[0]--; + assert_equal(Number.isNaN(v2[0]), true); + let v3 = Infinity; + v3++; + let v4 = -Infinity; + v4--; + assert_equal(v3, Infinity); + assert_equal(v4, -Infinity); +} + test_end(); \ No newline at end of file -- Gitee