mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
!7407 IR Number.toString()
Merge pull request !7407 from maojunwei/toString
This commit is contained in:
commit
fea1d192c9
@ -64,7 +64,7 @@
|
||||
/* Number.prototype.toPrecision ( precision ) */ \
|
||||
V("toPrecision", ToPrecision, 1, INVALID) \
|
||||
/* Number.prototype.toString ( [ radix ] ) */ \
|
||||
V("toString", ToString, 1, INVALID) \
|
||||
V("toString", ToString, 1, NumberToString) \
|
||||
/* Number.prototype.valueOf ( ) */ \
|
||||
V("valueOf", ValueOf, 0, INVALID)
|
||||
|
||||
|
@ -138,7 +138,8 @@ namespace panda::ecmascript::kungfu {
|
||||
V(PrototypeApply, Function, Undefined())
|
||||
|
||||
#define BUILTINS_WITH_NUMBER_STUB_BUILDER(V) \
|
||||
V(ParseFloat, Number, Undefined())
|
||||
V(ParseFloat, Number, Undefined()) \
|
||||
V(ToString, Number, Undefined())
|
||||
|
||||
#define BUILTINS_WITH_TYPEDARRAY_STUB_BUILDER(V) \
|
||||
V(Reverse, TypedArray, Undefined()) \
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "ecmascript/compiler/builtins/builtins_number_stub_builder.h"
|
||||
|
||||
#include "ecmascript/builtins/builtins_number.h"
|
||||
#include "ecmascript/compiler/new_object_stub_builder.h"
|
||||
#include "ecmascript/compiler/stub_builder-inl.h"
|
||||
#include "ecmascript/js_arguments.h"
|
||||
@ -123,4 +124,171 @@ void BuiltinsNumberStubBuilder::GenNumberConstructor(GateRef nativeCode, GateRef
|
||||
Bind(&exit);
|
||||
Return(*res);
|
||||
}
|
||||
|
||||
void BuiltinsNumberStubBuilder::ToString(Variable *result, Label *exit, Label *slowPath)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label definedMsg(env);
|
||||
Label undefinedMsg(env);
|
||||
Label thisIsInt(env);
|
||||
Label msgIsInt(env);
|
||||
BRANCH(TaggedIsInt(thisValue_), &thisIsInt, slowPath);
|
||||
Bind(&thisIsInt);
|
||||
GateRef thisValueInt = GetInt32OfTInt(thisValue_);
|
||||
GateRef msg = GetCallArg0(numArgs_);
|
||||
BRANCH(TaggedIsUndefined(msg), &undefinedMsg, &definedMsg);
|
||||
Bind(&undefinedMsg);
|
||||
{
|
||||
*result = NumberToString(thisValueInt, Int32(10)); // 10: means radix
|
||||
Jump(exit);
|
||||
}
|
||||
Bind(&definedMsg);
|
||||
BRANCH(TaggedIsInt(msg), &msgIsInt, slowPath);
|
||||
Bind(&msgIsInt);
|
||||
{
|
||||
Label throwError(env);
|
||||
Label notThrowError(env);
|
||||
GateRef msgValue = GetInt32OfTInt(msg);
|
||||
GateRef outOfRange = BoolOr(Int32LessThan(msgValue, Int32(base::MIN_RADIX)),
|
||||
Int32GreaterThan(msgValue, Int32(base::MAX_RADIX)));
|
||||
BRANCH(outOfRange, &throwError, ¬ThrowError);
|
||||
Bind(&throwError);
|
||||
{
|
||||
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(InvalidRadixLength));
|
||||
CallRuntime(glue_, RTSTUB_ID(ThrowRangeError), { IntToTaggedInt(taggedId) });
|
||||
Jump(exit);
|
||||
}
|
||||
Bind(¬ThrowError);
|
||||
{
|
||||
*result = NumberToString(thisValueInt, msgValue);
|
||||
Jump(exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GateRef BuiltinsNumberStubBuilder::NumberToString(GateRef number, GateRef radix)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
DEFVARIABLE(result, VariableType::JS_POINTER(), Hole());
|
||||
DEFVARIABLE(n, VariableType::INT32(), number);
|
||||
|
||||
Label exit(env);
|
||||
Label numIsNegative(env);
|
||||
Label numNotNegative(env);
|
||||
Label afterFast(env);
|
||||
Label afterNew(env);
|
||||
GateRef isNegative = Int32LessThan(number, Int32(0));
|
||||
BRANCH(isNegative, &numIsNegative, &numNotNegative);
|
||||
Bind(&numIsNegative);
|
||||
{
|
||||
n = Int32Sub(Int32(0), *n);
|
||||
Jump(&afterFast);
|
||||
}
|
||||
Bind(&numNotNegative);
|
||||
{
|
||||
Label thisIsZero(env);
|
||||
Label thisNotZero(env);
|
||||
Label thisIsSingle(env);
|
||||
Label thisNotSingle(env);
|
||||
BRANCH(Int32Equal(number, Int32(0)), &thisIsZero, &thisNotZero);
|
||||
Bind(&thisIsZero);
|
||||
{
|
||||
result = GetGlobalConstantValue(VariableType::JS_POINTER(), glue_, ConstantIndex::ZERO_INDEX);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&thisNotZero);
|
||||
{
|
||||
BRANCH(Int32LessThan(number, radix), &thisIsSingle, &afterFast);
|
||||
Bind(&thisIsSingle);
|
||||
GateRef singleCharTable = GetSingleCharTable(glue_);
|
||||
GateRef index = ToCharCode(number);
|
||||
result = GetValueFromTaggedArray(singleCharTable, index);
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
Bind(&afterFast);
|
||||
{
|
||||
DEFVARIABLE(temp, VariableType::INT32(), *n);
|
||||
DEFVARIABLE(length, VariableType::INT32(), Int32(0));
|
||||
Label lenAddOne(env);
|
||||
Label lenNotAddOne(env);
|
||||
BRANCH(isNegative, &lenAddOne, &lenNotAddOne);
|
||||
Bind(&lenAddOne);
|
||||
{
|
||||
length = Int32Add(*length, Int32(1));
|
||||
Jump(&lenNotAddOne);
|
||||
}
|
||||
Bind(&lenNotAddOne);
|
||||
{
|
||||
Label loopHead(env);
|
||||
Label loopEnd(env);
|
||||
Label next(env);
|
||||
Label loopExit(env);
|
||||
Jump(&loopHead);
|
||||
LoopBegin(&loopHead);
|
||||
{
|
||||
BRANCH(Int32GreaterThan(*temp, Int32(0)), &next, &loopExit);
|
||||
Bind(&next);
|
||||
{
|
||||
temp = Int32Div(*temp, radix);
|
||||
length = Int32Add(*length, Int32(1));
|
||||
Jump(&loopEnd);
|
||||
}
|
||||
}
|
||||
Bind(&loopEnd);
|
||||
LoopEnd(&loopHead, env, glue_);
|
||||
Bind(&loopExit);
|
||||
{
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
newBuilder.SetParameters(glue_, 0);
|
||||
newBuilder.AllocLineStringObject(&result, &afterNew, *length, true);
|
||||
Bind(&afterNew);
|
||||
{
|
||||
GateRef dst = ChangeTaggedPointerToInt64(PtrAdd(*result, IntPtr(LineEcmaString::DATA_OFFSET)));
|
||||
DEFVARIABLE(cursor, VariableType::INT32(), Int32Sub(*length, Int32(1)));
|
||||
DEFVARIABLE(digit, VariableType::INT32(), Int32(0));
|
||||
DEFVARIABLE(dstTmp, VariableType::NATIVE_POINTER(), dst);
|
||||
dstTmp = PtrAdd(*dstTmp, PtrMul(ZExtInt32ToPtr(*cursor), IntPtr(sizeof(uint8_t))));
|
||||
Label loopHead1(env);
|
||||
Label loopEnd1(env);
|
||||
Label next1(env);
|
||||
Label loopExit1(env);
|
||||
Jump(&loopHead1);
|
||||
LoopBegin(&loopHead1);
|
||||
{
|
||||
BRANCH(Int32GreaterThan(*n, Int32(0)), &next1, &loopExit1);
|
||||
Bind(&next1);
|
||||
{
|
||||
digit = Int32Mod(*n, radix);
|
||||
n = Int32Div(*n, radix);
|
||||
GateRef digitChar = ToCharCode(*digit);
|
||||
Store(VariableType::INT8(), glue_, *dstTmp, IntPtr(0), TruncInt32ToInt8(digitChar));
|
||||
cursor = Int32Sub(*cursor, Int32(1));
|
||||
Jump(&loopEnd1);
|
||||
}
|
||||
}
|
||||
Bind(&loopEnd1);
|
||||
dstTmp = PtrSub(*dstTmp, IntPtr(sizeof(uint8_t)));
|
||||
LoopEnd(&loopHead1, env, glue_);
|
||||
Bind(&loopExit1);
|
||||
{
|
||||
Label strInsertSign(env);
|
||||
Label strNotInsertSign(env);
|
||||
BRANCH(isNegative, &strInsertSign, &exit);
|
||||
Bind(&strInsertSign);
|
||||
{
|
||||
dstTmp = PtrSub(*dstTmp, IntPtr(sizeof(uint8_t)));
|
||||
Store(VariableType::INT8(), glue_, dst, IntPtr(0), Int8(45)); // 45: means '-'
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -34,6 +34,7 @@ BUILTINS_WITH_NUMBER_STUB_BUILDER(DECLARE_BUILTINS_NUMBER_STUB_BUILDER)
|
||||
#undef DECLARE_BUILTINS_NUMBER_STUB_BUILDER
|
||||
|
||||
void GenNumberConstructor(GateRef nativeCode, GateRef func, GateRef newTarget);
|
||||
GateRef NumberToString(GateRef number, GateRef radix);
|
||||
|
||||
private:
|
||||
GateRef glue_ { Circuit::NullGate() };
|
||||
|
@ -9732,6 +9732,34 @@ GateRef StubBuilder::AppendSkipHole(GateRef glue, GateRef first, GateRef second,
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef StubBuilder::ToCharCode(GateRef number)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label subEntry(env);
|
||||
env->SubCfgEntry(&subEntry);
|
||||
Label exit(env);
|
||||
DEFVARIABLE(result, VariableType::INT32(), number);
|
||||
|
||||
Label lessThanTen(env);
|
||||
Label notLessThanTen(env);
|
||||
BRANCH(Int32LessThan(number, Int32(10)), &lessThanTen, ¬LessThanTen); // 10: means number
|
||||
Bind(&lessThanTen);
|
||||
{
|
||||
result = Int32Add(Int32('0'), *result);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(¬LessThanTen);
|
||||
{
|
||||
result = Int32Sub(*result, Int32(10)); // 10: means number
|
||||
result = Int32Add(Int32('a'), *result);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef StubBuilder::IntToEcmaString(GateRef glue, GateRef number)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
|
@ -870,6 +870,7 @@ public:
|
||||
GateRef CalArrayRelativePos(GateRef index, GateRef arrayLen);
|
||||
GateRef AppendSkipHole(GateRef glue, GateRef first, GateRef second, GateRef copyLength);
|
||||
GateRef IntToEcmaString(GateRef glue, GateRef number);
|
||||
GateRef ToCharCode(GateRef number);
|
||||
GateRef NumberToString(GateRef glue, GateRef number);
|
||||
inline GateRef GetViewedArrayBuffer(GateRef dataView);
|
||||
inline GateRef GetByteOffset(GateRef dataView);
|
||||
|
@ -60,7 +60,8 @@ namespace panda::ecmascript {
|
||||
V(InvalidStringLength, "Invalid string length") \
|
||||
V(InvalidNewTarget, "new.target is not an object") \
|
||||
V(ObjIsNotCallable, "obj is not Callable") \
|
||||
V(SharedObjectRefersLocalObject, "shared object refers a local object")
|
||||
V(SharedObjectRefersLocalObject, "shared object refers a local object") \
|
||||
V(InvalidRadixLength, "radix must be 2 to 36")
|
||||
|
||||
#define DEBUG_CHECK_MESSAGE_STRING_LIST(V) \
|
||||
V(IsCallable) \
|
||||
|
@ -102,3 +102,18 @@
|
||||
-12
|
||||
-1.2e+3
|
||||
-1.235e+4
|
||||
0
|
||||
1
|
||||
-9
|
||||
1234567
|
||||
-1234567
|
||||
10000
|
||||
67345
|
||||
0
|
||||
9
|
||||
5a
|
||||
0
|
||||
-5a
|
||||
5yc1z
|
||||
3lnj8l
|
||||
-3lnj8l
|
||||
|
@ -133,4 +133,26 @@ testToPrecision(Number(-.00012345), (2));
|
||||
testToPrecision(Number(-1.2345), (2));
|
||||
testToPrecision(Number(-12.345), (2));
|
||||
testToPrecision(Number(-1234.5), (2));
|
||||
testToPrecision(Number(-12345.67), (4));
|
||||
testToPrecision(Number(-12345.67), (4));
|
||||
|
||||
|
||||
// toString, Only Test InttoString
|
||||
function testToString(a, b) {
|
||||
print(a.toString(b));
|
||||
}
|
||||
print((-0).toString());
|
||||
print((1).toString());
|
||||
print((-9).toString());
|
||||
print((1234567).toString());
|
||||
print((-1234567).toString());
|
||||
print((10000).toString());
|
||||
print((67345).toString());
|
||||
|
||||
testToString((0), (16));
|
||||
testToString((9), (16));
|
||||
testToString((90), (16));
|
||||
testToString((-0), (16));
|
||||
testToString((-90), (16));
|
||||
testToString((10000007), (36));
|
||||
testToString((123456789), (32));
|
||||
testToString((-123456789), (32));
|
Loading…
Reference in New Issue
Block a user