Add DateConstructor in builtins stubs

Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I649EV

Signed-off-by: ding <dingding5@huawei.com>
Change-Id: I22d1b4f2ec92f45c04b816c3a35e7a43ab6d9922
This commit is contained in:
ding 2022-12-02 11:12:46 +08:00
parent a67b34361f
commit 1d0c851fcd
28 changed files with 349 additions and 119 deletions

View File

@ -824,7 +824,8 @@ void Builtins::InitializeDate(const JSHandle<GlobalEnv> &env, const JSHandle<JSH
// Date = new Function()
JSHandle<JSObject> dateFunction(
NewBuiltinConstructor(env, dateFuncPrototype, Date::DateConstructor, "Date", FunctionLength::ONE));
NewBuiltinConstructor(env, dateFuncPrototype, Date::DateConstructor, "Date", FunctionLength::ONE,
BUILTINS_STUB_ID(DateConstructor)));
JSHandle<JSFunction>(dateFunction)->SetFunctionPrototype(thread_, dateFuncInstanceHClass.GetTaggedValue());
// Date.prototype method
@ -905,7 +906,7 @@ void Builtins::InitializeBoolean(const JSHandle<GlobalEnv> &env, const JSHandle<
// new Boolean Function()
JSHandle<JSFunction> booleanFunction = NewBuiltinConstructor(env, booleanFuncPrototype, Boolean::BooleanConstructor,
"Boolean", FunctionLength::ONE, static_cast<uint8_t>(BUILTINS_STUB_ID(BooleanConstructor)));
"Boolean", FunctionLength::ONE, BUILTINS_STUB_ID(BooleanConstructor));
booleanFunction->SetFunctionPrototype(thread_, booleanFuncInstanceHClass.GetTaggedValue());
// Boolean.prototype method
@ -1494,25 +1495,22 @@ void Builtins::InitializeMath(const JSHandle<GlobalEnv> &env, const JSHandle<JST
[[maybe_unused]] EcmaHandleScope scope(thread_);
JSHandle<JSHClass> mathClass = factory_->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, objFuncPrototypeVal);
JSHandle<JSObject> mathObject = factory_->NewJSObjectWithInit(mathClass);
SetFunction(env, mathObject, "abs", Math::Abs, FunctionLength::ONE, static_cast<uint8_t>(BUILTINS_STUB_ID(ABS)));
SetFunction(env, mathObject, "acos", Math::Acos, FunctionLength::ONE,
static_cast<uint8_t>(BUILTINS_STUB_ID(ACOS)));
SetFunction(env, mathObject, "abs", Math::Abs, FunctionLength::ONE, BUILTINS_STUB_ID(ABS));
SetFunction(env, mathObject, "acos", Math::Acos, FunctionLength::ONE, BUILTINS_STUB_ID(ACOS));
SetFunction(env, mathObject, "acosh", Math::Acosh, FunctionLength::ONE);
SetFunction(env, mathObject, "asin", Math::Asin, FunctionLength::ONE);
SetFunction(env, mathObject, "asinh", Math::Asinh, FunctionLength::ONE);
SetFunction(env, mathObject, "atan", Math::Atan, FunctionLength::ONE,
static_cast<uint8_t>(BUILTINS_STUB_ID(ATAN)));
SetFunction(env, mathObject, "atan", Math::Atan, FunctionLength::ONE, BUILTINS_STUB_ID(ATAN));
SetFunction(env, mathObject, "atanh", Math::Atanh, FunctionLength::ONE);
SetFunction(env, mathObject, "atan2", Math::Atan2, FunctionLength::TWO);
SetFunction(env, mathObject, "cbrt", Math::Cbrt, FunctionLength::ONE);
SetFunction(env, mathObject, "ceil", Math::Ceil, FunctionLength::ONE);
SetFunction(env, mathObject, "clz32", Math::Clz32, FunctionLength::ONE);
SetFunction(env, mathObject, "cos", Math::Cos, FunctionLength::ONE, static_cast<uint8_t>(BUILTINS_STUB_ID(COS)));
SetFunction(env, mathObject, "cos", Math::Cos, FunctionLength::ONE, BUILTINS_STUB_ID(COS));
SetFunction(env, mathObject, "cosh", Math::Cosh, FunctionLength::ONE);
SetFunction(env, mathObject, "exp", Math::Exp, FunctionLength::ONE);
SetFunction(env, mathObject, "expm1", Math::Expm1, FunctionLength::ONE);
SetFunction(env, mathObject, "floor", Math::Floor, FunctionLength::ONE,
static_cast<uint8_t>(BUILTINS_STUB_ID(FLOOR)));
SetFunction(env, mathObject, "floor", Math::Floor, FunctionLength::ONE, BUILTINS_STUB_ID(FLOOR));
SetFunction(env, mathObject, "fround", Math::Fround, FunctionLength::ONE);
SetFunction(env, mathObject, "hypot", Math::Hypot, FunctionLength::TWO);
SetFunction(env, mathObject, "imul", Math::Imul, FunctionLength::TWO);
@ -1526,10 +1524,9 @@ void Builtins::InitializeMath(const JSHandle<GlobalEnv> &env, const JSHandle<JST
SetFunction(env, mathObject, "random", Math::Random, FunctionLength::ZERO);
SetFunction(env, mathObject, "round", Math::Round, FunctionLength::ONE);
SetFunction(env, mathObject, "sign", Math::Sign, FunctionLength::ONE);
SetFunction(env, mathObject, "sin", Math::Sin, FunctionLength::ONE, static_cast<uint8_t>(BUILTINS_STUB_ID(SIN)));
SetFunction(env, mathObject, "sin", Math::Sin, FunctionLength::ONE, BUILTINS_STUB_ID(SIN));
SetFunction(env, mathObject, "sinh", Math::Sinh, FunctionLength::ONE);
SetFunction(env, mathObject, "sqrt", Math::Sqrt, FunctionLength::ONE,
static_cast<uint8_t>(BUILTINS_STUB_ID(SQRT)));
SetFunction(env, mathObject, "sqrt", Math::Sqrt, FunctionLength::ONE, BUILTINS_STUB_ID(SQRT));
SetFunction(env, mathObject, "tan", Math::Tan, FunctionLength::ONE);
SetFunction(env, mathObject, "tanh", Math::Tanh, FunctionLength::ONE);
SetFunction(env, mathObject, "trunc", Math::Trunc, FunctionLength::ONE);
@ -2643,7 +2640,8 @@ void Builtins::InitializeDataView(const JSHandle<GlobalEnv> &env, const JSHandle
JSHandle<JSFunction> Builtins::NewBuiltinConstructor(const JSHandle<GlobalEnv> &env,
const JSHandle<JSObject> &prototype, EcmaEntrypoint ctorFunc,
const char *name, int length, uint8_t builtinId) const
const char *name, int length,
kungfu::BuiltinsStubCSigns::ID builtinId) const
{
JSHandle<JSFunction> ctor =
factory_->NewJSFunction(env, reinterpret_cast<void *>(ctorFunc), FunctionKind::BUILTIN_CONSTRUCTOR, builtinId);
@ -2671,7 +2669,8 @@ JSHandle<JSFunction> Builtins::NewBuiltinCjsCtor(const JSHandle<GlobalEnv> &env,
}
JSHandle<JSFunction> Builtins::NewFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &key,
EcmaEntrypoint func, int length, uint8_t builtinId) const
EcmaEntrypoint func, int length,
kungfu::BuiltinsStubCSigns::ID builtinId) const
{
JSHandle<JSFunction> function = factory_->NewJSFunction(env, reinterpret_cast<void *>(func),
FunctionKind::NORMAL_FUNCTION, builtinId);
@ -2683,7 +2682,7 @@ JSHandle<JSFunction> Builtins::NewFunction(const JSHandle<GlobalEnv> &env, const
}
void Builtins::SetFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, const char *key,
EcmaEntrypoint func, int length, uint8_t builtinId) const
EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId) const
{
JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8(key));
SetFunction(env, obj, keyString, func, length, builtinId);
@ -2691,7 +2690,7 @@ void Builtins::SetFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObje
void Builtins::SetFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, int length,
uint8_t builtinId) const
kungfu::BuiltinsStubCSigns::ID builtinId) const
{
JSHandle<JSFunction> function(NewFunction(env, key, func, length, builtinId));
PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>(function), true, false, true);

View File

@ -50,7 +50,8 @@ private:
JSHandle<JSFunction> NewBuiltinConstructor(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &prototype,
EcmaEntrypoint ctorFunc, const char *name, int length,
uint8_t builtinId = INVALID_BUILTINS_ID) const;
kungfu::BuiltinsStubCSigns::ID builtinId =
kungfu::BuiltinsStubCSigns::INVALID) const;
JSHandle<JSFunction> NewBuiltinCjsCtor(const JSHandle<GlobalEnv> &env,
const JSHandle<JSObject> &prototype, EcmaEntrypoint ctorFunc,
@ -58,7 +59,8 @@ private:
JSHandle<JSFunction> NewFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &key,
EcmaEntrypoint func, int length,
uint8_t builtinId = INVALID_BUILTINS_ID) const;
kungfu::BuiltinsStubCSigns::ID builtinId =
kungfu::BuiltinsStubCSigns::INVALID) const;
void InitializeCtor(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &prototype,
const JSHandle<JSFunction> &ctor, const char *name, int length) const;
@ -216,10 +218,12 @@ private:
void InitializeCjsRequire(const JSHandle<GlobalEnv> &env) const;
void SetFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, const char *key,
EcmaEntrypoint func, int length, uint8_t builtinId = INVALID_BUILTINS_ID) const;
EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId =
kungfu::BuiltinsStubCSigns::INVALID) const;
void SetFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &key,
EcmaEntrypoint func, int length, uint8_t builtinId = INVALID_BUILTINS_ID) const;
EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId =
kungfu::BuiltinsStubCSigns::INVALID) const;
void SetFuncToObjAndGlobal(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &globalObject,
const JSHandle<JSObject> &obj, const char *key, EcmaEntrypoint func, int length);

View File

@ -31,6 +31,7 @@ namespace panda::ecmascript::builtins {
// constructor
JSTaggedValue BuiltinsDate::DateConstructor(EcmaRuntimeCallInfo *argv)
{
BUILTINS_ENTRY_DEBUG_LOG();
BUILTINS_API_TRACE(argv->GetThread(), Date, Constructor);
JSThread *thread = argv->GetThread();
[[maybe_unused]] EcmaHandleScope handleScope(thread);
@ -92,7 +93,7 @@ JSTaggedValue BuiltinsDate::DateConstructor(EcmaRuntimeCallInfo *argv)
JSHandle<JSDate>::Cast(factory->NewJSObjectByConstructor(constructor, newTarget));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
dateObject->SetTimeValue(thread, timeValue);
return JSTaggedValue(JSObject::Cast(static_cast<TaggedObject *>(*dateObject)));
return dateObject.GetTaggedValue();
}
// 20.4.3.1

View File

@ -52,6 +52,7 @@ namespace panda::ecmascript::kungfu {
#define BUILTINS_CONSTRUCTOR_STUB_LIST(V) \
V(BooleanConstructor) \
V(DateConstructor) \
#define AOT_BUILTINS_STUB_LIST(V) \
V(SQRT) \
@ -74,6 +75,7 @@ public:
AOT_BUILTINS_STUB_LIST(DEF_STUB_ID)
#undef DEF_STUB_ID
BUILTINS_CONSTRUCTOR_STUB_FIRST = BooleanConstructor,
INVALID = 0xFF,
};
static void Initialize();

View File

@ -25,6 +25,7 @@
#include "ecmascript/compiler/new_object_stub_builder.h"
#include "ecmascript/compiler/stub_builder-inl.h"
#include "ecmascript/compiler/variable_type.h"
#include "ecmascript/js_date.h"
#include "ecmascript/js_primitive_ref.h"
namespace panda::ecmascript::kungfu {
@ -59,7 +60,7 @@ void name##StubBuilder::GenerateCircuitImpl(GateRef glue, GateRef nativeCode, Ga
GateRef newTarget, GateRef thisValue, GateRef numArgs)
#endif
GateRef BuiltinsStubBuilder::GetCallArgWithArgv(GateRef numArgs, GateRef index)
GateRef BuiltinsStubBuilder::GetArg(GateRef numArgs, GateRef index)
{
auto env = GetEnvironment();
Label entry(env);
@ -70,8 +71,8 @@ GateRef BuiltinsStubBuilder::GetCallArgWithArgv(GateRef numArgs, GateRef index)
Branch(IntPtrGreaterThan(numArgs, index), &validIndex, &exit);
Bind(&validIndex);
{
GateRef argv = GetCallArgv();
arg = Load(VariableType::JS_ANY(), argv, PtrMul(index, IntPtr(sizeof(JSTaggedType))));
GateRef argv = GetArgv();
arg = Load(VariableType::JS_ANY(), argv, PtrMul(index, IntPtr(JSTaggedValue::TaggedTypeSize())));
Jump(&exit);
}
Bind(&exit);
@ -98,8 +99,7 @@ GateRef BuiltinsStubBuilder::CallSlowPath(GateRef nativeCode, GateRef glue, Gate
Branch(Int64Equal(numArgs, IntPtr(0)), &callThis0, &notcallThis0);
Bind(&callThis0);
{
result = CallNGCRuntime(glue, RTSTUB_ID(PushCallArgsAndDispatchNative),
{ nativeCode, glue, runtimeCallInfoArgs, func, newTarget, thisValue });
result = CallBuiltinRuntime(glue, { nativeCode, glue, runtimeCallInfoArgs, func, newTarget, thisValue });
Jump(&exit);
}
Bind(&notcallThis0);
@ -108,8 +108,8 @@ GateRef BuiltinsStubBuilder::CallSlowPath(GateRef nativeCode, GateRef glue, Gate
Bind(&callThis1);
{
GateRef arg0 = GetCallArg0();
result = CallNGCRuntime(glue, RTSTUB_ID(PushCallArgsAndDispatchNative),
{ nativeCode, glue, runtimeCallInfoArgs, func, newTarget, thisValue, arg0 });
result =
CallBuiltinRuntime(glue, { nativeCode, glue, runtimeCallInfoArgs, func, newTarget, thisValue, arg0 });
Jump(&exit);
}
Bind(&notcallThis1);
@ -119,7 +119,7 @@ GateRef BuiltinsStubBuilder::CallSlowPath(GateRef nativeCode, GateRef glue, Gate
{
GateRef arg0 = GetCallArg0();
GateRef arg1 = GetCallArg1();
result = CallNGCRuntime(glue, RTSTUB_ID(PushCallArgsAndDispatchNative),
result = CallBuiltinRuntime(glue,
{ nativeCode, glue, runtimeCallInfoArgs, func, newTarget, thisValue, arg0, arg1 });
Jump(&exit);
}
@ -128,7 +128,7 @@ GateRef BuiltinsStubBuilder::CallSlowPath(GateRef nativeCode, GateRef glue, Gate
GateRef arg0 = GetCallArg0();
GateRef arg1 = GetCallArg1();
GateRef arg2 = GetCallArg2();
result = CallNGCRuntime(glue, RTSTUB_ID(PushCallArgsAndDispatchNative),
result = CallBuiltinRuntime(glue,
{ nativeCode, glue, runtimeCallInfoArgs, func, newTarget, thisValue, arg0, arg1, arg2 });
Jump(&exit);
}
@ -851,7 +851,7 @@ DECLARE_BUILTINS(BooleanConstructor)
Bind(&afterNew);
{
GateRef valueOffset = IntPtr(JSPrimitiveRef::VALUE_OFFSET);
GateRef value = GetCallArgWithArgv(numArgs, IntPtr(0));
GateRef value = GetArg(numArgs, IntPtr(0));
Store(VariableType::INT64(), glue, *res, valueOffset, FastToBoolean(value));
Jump(&exit);
}
@ -859,9 +859,89 @@ DECLARE_BUILTINS(BooleanConstructor)
}
Bind(&slowPath);
{
GateRef argv = GetCallArgv();
res = CallNGCRuntime(glue, RTSTUB_ID(PushCallNewAndDispatchNative),
{ glue, nativeCode, func, thisValue, numArgs, argv });
GateRef argv = GetArgv();
res = CallBuiltinRuntime(glue, { glue, nativeCode, func, thisValue, numArgs, argv }, true);
Jump(&exit);
}
Bind(&exit);
Return(*res);
}
DECLARE_BUILTINS(DateConstructor)
{
auto env = GetEnvironment();
DEFVARIABLE(res, VariableType::JS_ANY(), Undefined());
Label newTargetIsJSFunction(env);
Label slowPath(env);
Label exit(env);
Branch(IsJSFunction(newTarget), &newTargetIsJSFunction, &slowPath);
Bind(&newTargetIsJSFunction);
{
Label intialHClassIsHClass(env);
GateRef intialHClass = Load(VariableType::JS_ANY(), newTarget,
IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
Branch(IsJSHClass(intialHClass), &intialHClassIsHClass, &slowPath);
Bind(&intialHClassIsHClass);
{
Label oneArg(env);
Label notOneArg(env);
Label newJSDate(env);
DEFVARIABLE(timeValue, VariableType::FLOAT64(), Double(0));
Branch(Int64Equal(numArgs, IntPtr(1)), &oneArg, &notOneArg);
Bind(&oneArg);
{
Label valueIsNumber(env);
GateRef value = GetArgNCheck(IntPtr(0));
Branch(TaggedIsNumber(value), &valueIsNumber, &slowPath);
Bind(&valueIsNumber);
{
timeValue = CallNGCRuntime(glue, RTSTUB_ID(TimeClip), {GetDoubleOfTNumber(value)});
Jump(&newJSDate);
}
}
Bind(&notOneArg);
{
Label threeArgs(env);
Branch(Int64Equal(numArgs, IntPtr(3)), &threeArgs, &slowPath); // 3: year month day
Bind(&threeArgs);
{
Label numberYearMonthDay(env);
GateRef year = GetArgNCheck(IntPtr(0));
GateRef month = GetArgNCheck(IntPtr(1));
GateRef day = GetArgNCheck(IntPtr(2));
Branch(IsNumberYearMonthDay(year, month, day), &numberYearMonthDay, &slowPath);
Bind(&numberYearMonthDay);
{
GateRef y = GetDoubleOfTNumber(year);
GateRef m = GetDoubleOfTNumber(month);
GateRef d = GetDoubleOfTNumber(day);
timeValue = CallNGCRuntime(glue, RTSTUB_ID(SetDateValues), {y, m, d});
Jump(&newJSDate);
}
}
}
Bind(&newJSDate);
{
NewObjectStubBuilder newBuilder(this);
newBuilder.SetParameters(glue, 0);
Label afterNew(env);
newBuilder.NewJSObject(&res, &afterNew, intialHClass);
Bind(&afterNew);
{
GateRef timeValueOffset = IntPtr(JSDate::TIME_VALUE_OFFSET);
Store(VariableType::JS_NOT_POINTER(), glue, *res, timeValueOffset,
DoubleToTaggedDoublePtr(*timeValue));
Jump(&exit);
}
}
}
}
Bind(&slowPath);
{
GateRef argv = GetArgv();
res = CallBuiltinRuntime(glue, { glue, nativeCode, func, thisValue, numArgs, argv }, true);
Jump(&exit);
}
Bind(&exit);

View File

@ -79,15 +79,28 @@ public:
return TaggedArgument(static_cast<size_t>(BuiltinsArgs::ARG2));
}
inline GateRef GetCallArgv()
inline GateRef GetArgv()
{
return PtrArgument(static_cast<size_t>(BuiltinsArgs::ARG0_OR_ARGV));
}
GateRef GetCallArgWithArgv(GateRef numArgs, GateRef index);
// not check whether index is valid, if not sure, invoke GetArg
inline GateRef GetArgNCheck(GateRef index)
{
GateRef argv = GetArgv();
return Load(VariableType::JS_ANY(), argv, PtrMul(index, IntPtr(JSTaggedValue::TaggedTypeSize())));
}
GateRef GetArg(GateRef numArgs, GateRef index);
GateRef CallSlowPath(GateRef nativeCode, GateRef glue, GateRef thisValue, GateRef numArgs, GateRef func,
GateRef newTarget);
inline GateRef IsNumberYearMonthDay(GateRef year, GateRef month, GateRef day)
{
GateRef condition = BoolAnd(TaggedIsNumber(year), TaggedIsNumber(month));
return BoolAnd(condition, TaggedIsNumber(day));
}
};
#define DECLARE_BUILTINS_STUB_CLASS(name) \

View File

@ -63,59 +63,42 @@ GateRef BuiltinLowering::TypeTrigonometric(GateRef gate, BuiltinsStubCSigns::ID
builder_.Branch(builder_.TaggedIsNumber(a0), &numberBranch, &notNumberBranch);
builder_.Bind(&numberBranch);
{
Label IsInt(&builder_);
Label NotInt(&builder_);
Label calc(&builder_);
DEFVAlUE(value, (&builder_), VariableType::FLOAT64(), builder_.Double(0));
builder_.Branch(builder_.TaggedIsInt(a0), &IsInt, &NotInt);
builder_.Bind(&IsInt);
GateRef value = builder_.GetDoubleOfTNumber(a0);
Label IsNan(&builder_);
Label NotNan(&builder_);
GateRef condition = builder_.DoubleIsNAN(value);
builder_.Branch(condition, &IsNan, &NotNan);
builder_.Bind(&NotNan);
{
value = builder_.ChangeInt32ToFloat64(builder_.GetInt32OfTInt(a0));
builder_.Jump(&calc);
}
builder_.Bind(&NotInt);
{
value = builder_.GetDoubleOfTDouble(a0);
builder_.Jump(&calc);
}
builder_.Bind(&calc);
{
Label IsNan(&builder_);
Label NotNan(&builder_);
GateRef condition = builder_.DoubleIsNAN(*value);
builder_.Branch(condition, &IsNan, &NotNan);
builder_.Bind(&NotNan);
{
GateRef glue = acc_.GetGlueFromArgList();
int index = RTSTUB_ID(FloatCos);
switch (id) {
case BUILTINS_STUB_ID(FLOOR):
index = RTSTUB_ID(FloatFloor);
break;
case BUILTINS_STUB_ID(ACOS):
index = RTSTUB_ID(FloatACos);
break;
case BUILTINS_STUB_ID(ATAN):
index = RTSTUB_ID(FloatATan);
break;
case BUILTINS_STUB_ID(COS):
index = RTSTUB_ID(FloatCos);
break;
case BUILTINS_STUB_ID(SIN):
index = RTSTUB_ID(FloatSin);
break;
default:
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
result = builder_.CallNGCRuntime(glue, index, Gate::InvalidGateRef, {*value});
builder_.Jump(&exit);
}
builder_.Bind(&IsNan);
{
result = builder_.DoubleToTaggedDoublePtr(builder_.Double(base::NAN_VALUE));
builder_.Jump(&exit);
GateRef glue = acc_.GetGlueFromArgList();
int index = RTSTUB_ID(FloatCos);
switch (id) {
case BUILTINS_STUB_ID(FLOOR):
index = RTSTUB_ID(FloatFloor);
break;
case BUILTINS_STUB_ID(ACOS):
index = RTSTUB_ID(FloatACos);
break;
case BUILTINS_STUB_ID(ATAN):
index = RTSTUB_ID(FloatATan);
break;
case BUILTINS_STUB_ID(COS):
index = RTSTUB_ID(FloatCos);
break;
case BUILTINS_STUB_ID(SIN):
index = RTSTUB_ID(FloatSin);
break;
default:
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
result = builder_.CallNGCRuntime(glue, index, Gate::InvalidGateRef, {value});
builder_.Jump(&exit);
}
builder_.Bind(&IsNan);
{
result = builder_.DoubleToTaggedDoublePtr(builder_.Double(base::NAN_VALUE));
builder_.Jump(&exit);
}
}
builder_.Bind(&notNumberBranch);

View File

@ -1485,4 +1485,34 @@ DEF_CALL_SIGNATURE(DeoptHandlerAsm)
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
callSign->SetTargetKind(CallSignature::TargetKind::DEOPT_STUB);
}
DEF_CALL_SIGNATURE(TimeClip)
{
// 1 : 1 input parameters
CallSignature index("TimeClip", 0, 1, ArgumentsOrder::DEFAULT_ORDER, VariableType::FLOAT64());
*callSign = index;
// 1 : 1 input parameters
std::array<VariableType, 1> params = {
VariableType::FLOAT64(),
};
callSign->SetParameters(params.data());
callSign->SetGCLeafFunction(true);
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
}
DEF_CALL_SIGNATURE(SetDateValues)
{
// 3 : 3 input parameters
CallSignature index("SetDateValues", 0, 3, ArgumentsOrder::DEFAULT_ORDER, VariableType::FLOAT64());
*callSign = index;
// 3 : 3 input parameters
std::array<VariableType, 3> params = {
VariableType::FLOAT64(),
VariableType::FLOAT64(),
VariableType::FLOAT64(),
};
callSign->SetParameters(params.data());
callSign->SetGCLeafFunction(true);
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
}
} // namespace panda::ecmascript::kungfu

View File

@ -402,6 +402,8 @@ private:
V(DeoptHandlerAsm) \
V(JSCallNew) \
V(JSCallNewWithArgV) \
V(TimeClip) \
V(SetDateValues) \
TEST_STUB_SIGNATRUE_LIST(V)
#define DECL_CALL_SIGNATURE(name) \

View File

@ -116,6 +116,31 @@ GateRef CircuitBuilder::GetDoubleOfTDouble(GateRef x)
return CastInt64ToFloat64(val);
}
GateRef CircuitBuilder::GetDoubleOfTNumber(GateRef x)
{
Label subentry(env_);
SubCfgEntry(&subentry);
Label isInt(env_);
Label isDouble(env_);
Label exit(env_);
DEFVAlUE(result, env_, VariableType::FLOAT64(), Double(0));
Branch(TaggedIsInt(x), &isInt, &isDouble);
Bind(&isInt);
{
result = ChangeInt32ToFloat64(GetInt32OfTInt(x));
Jump(&exit);
}
Bind(&isDouble);
{
result = GetDoubleOfTDouble(x);
Jump(&exit);
}
Bind(&exit);
GateRef ret = *result;
SubCfgExit();
return ret;
}
GateRef CircuitBuilder::Int8Equal(GateRef x, GateRef y)
{
return Equal(x, y);

View File

@ -390,6 +390,26 @@ GateRef CircuitBuilder::CallStub(GateRef glue, int index, const std::vector<Gate
return result;
}
GateRef CircuitBuilder::CallBuiltinRuntime(GateRef glue, GateRef depend, const std::vector<GateRef> &args, bool isNew)
{
int index = 0;
if (!isNew) {
index = static_cast<int>(RTSTUB_ID(PushCallArgsAndDispatchNative));
} else {
index = static_cast<int>(RTSTUB_ID(PushCallNewAndDispatchNative));
}
const CallSignature *cs = RuntimeStubCSigns::Get(index);
GateRef target = IntPtr(index);
auto label = GetCurrentLabel();
if (depend == Gate::InvalidGateRef) {
depend = label->GetDepend();
}
GateRef result = Call(cs, glue, target, depend, args);
label->SetDepend(result);
return result;
}
GateRef CircuitBuilder::Call(const CallSignature* cs, GateRef glue, GateRef target, GateRef depend,
const std::vector<GateRef> &args)
{

View File

@ -280,6 +280,7 @@ public:
GateRef CallRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args);
GateRef CallNGCRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args);
GateRef CallStub(GateRef glue, int index, const std::vector<GateRef> &args);
GateRef CallBuiltinRuntime(GateRef glue, GateRef depend, const std::vector<GateRef> &args, bool isNew = false);
GateRef Call(const CallSignature* cs, GateRef glue, GateRef target, GateRef depend,
const std::vector<GateRef> &args);
@ -323,6 +324,7 @@ public:
inline GateRef GetInt32OfTInt(GateRef x);
inline GateRef TaggedCastToIntPtr(GateRef x);
inline GateRef GetDoubleOfTDouble(GateRef x);
inline GateRef GetDoubleOfTNumber(GateRef x);
inline GateRef Int32ToTaggedPtr(GateRef x);
inline GateRef Int64ToTaggedPtr(GateRef x);
inline GateRef Int32ToTaggedInt(GateRef x);

View File

@ -212,6 +212,12 @@ inline GateRef StubBuilder::CallStub(GateRef glue, int index, const std::initial
return result;
}
inline GateRef StubBuilder::CallBuiltinRuntime(GateRef glue, const std::initializer_list<GateRef>& args, bool isNew)
{
GateRef result = env_->GetBuilder()->CallBuiltinRuntime(glue, Gate::InvalidGateRef, args, isNew);
return result;
}
inline void StubBuilder::DebugPrint(GateRef glue, std::initializer_list<GateRef> args)
{
CallNGCRuntime(glue, RTSTUB_ID(DebugPrint), args);
@ -1566,6 +1572,11 @@ inline GateRef StubBuilder::GetDoubleOfTDouble(GateRef x)
return env_->GetBuilder()->GetDoubleOfTDouble(x);
}
inline GateRef StubBuilder::GetDoubleOfTNumber(GateRef x)
{
return env_->GetBuilder()->GetDoubleOfTNumber(x);
}
inline GateRef StubBuilder::LoadObjectFromWeakRef(GateRef x)
{
return env_->GetBuilder()->PtrAdd(x, IntPtr(-JSTaggedValue::TAG_WEAK));

View File

@ -105,6 +105,7 @@ public:
GateRef CallRuntime(GateRef glue, int index, GateRef argc, GateRef argv);
GateRef CallNGCRuntime(GateRef glue, int index, const std::initializer_list<GateRef>& args);
GateRef CallStub(GateRef glue, int index, const std::initializer_list<GateRef>& args);
GateRef CallBuiltinRuntime(GateRef glue, const std::initializer_list<GateRef>& args, bool isNew = false);
void DebugPrint(GateRef thread, std::initializer_list<GateRef> args);
void FatalPrint(GateRef thread, std::initializer_list<GateRef> args);
// memory
@ -400,6 +401,7 @@ public:
GateRef GetInt64OfTInt(GateRef x);
GateRef GetInt32OfTInt(GateRef x);
GateRef GetDoubleOfTDouble(GateRef x);
GateRef GetDoubleOfTNumber(GateRef x);
GateRef LoadObjectFromWeakRef(GateRef x);
GateRef ChangeInt32ToFloat64(GateRef x);
GateRef ChangeUInt32ToFloat64(GateRef x);

View File

@ -190,7 +190,7 @@ JSHandle<JSFunction> ContainersPrivate::NewContainerConstructor(JSThread *thread
}
void ContainersPrivate::SetFrozenFunction(JSThread *thread, const JSHandle<JSObject> &obj, const char *key,
EcmaEntrypoint func, int length, uint8_t builtinId)
EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSTaggedValue> keyString(factory->NewFromASCII(key));
@ -210,7 +210,8 @@ void ContainersPrivate::SetFrozenConstructor(JSThread *thread, const JSHandle<JS
}
JSHandle<JSFunction> ContainersPrivate::NewFunction(JSThread *thread, const JSHandle<JSTaggedValue> &key,
EcmaEntrypoint func, int length, uint8_t builtinId)
EcmaEntrypoint func, int length,
kungfu::BuiltinsStubCSigns::ID builtinId)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSFunction> function =
@ -307,12 +308,12 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeArrayList(JSThread *thread)
SetFrozenFunction(thread, prototype, "remove", ContainersArrayList::Remove, FuncLength::ONE);
SetFrozenFunction(thread, prototype, "removeByRange", ContainersArrayList::RemoveByRange, FuncLength::TWO);
SetFrozenFunction(thread, prototype, "replaceAllElements", ContainersArrayList::ReplaceAllElements,
FuncLength::TWO, static_cast<uint8_t>(BUILTINS_STUB_ID(ArrayListReplaceAllElements)));
FuncLength::TWO, BUILTINS_STUB_ID(ArrayListReplaceAllElements));
SetFrozenFunction(thread, prototype, "sort", ContainersArrayList::Sort, FuncLength::ONE);
SetFrozenFunction(thread, prototype, "subArrayList", ContainersArrayList::SubArrayList, FuncLength::TWO);
SetFrozenFunction(thread, prototype, "convertToArray", ContainersArrayList::ConvertToArray, FuncLength::ZERO);
SetFrozenFunction(thread, prototype, "forEach", ContainersArrayList::ForEach, FuncLength::TWO,
static_cast<uint8_t>(BUILTINS_STUB_ID(ArrayListForEach)));
BUILTINS_STUB_ID(ArrayListForEach));
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
SetStringTagSymbol(thread, env, prototype, "ArrayList");
@ -384,7 +385,7 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeLightWeightMap(JSThread *th
SetFrozenFunction(thread, funcPrototype, "clear", ContainersLightWeightMap::Clear, FuncLength::ONE);
SetFrozenFunction(thread, funcPrototype, "setValueAt", ContainersLightWeightMap::SetValueAt, FuncLength::ONE);
SetFrozenFunction(thread, funcPrototype, "forEach", ContainersLightWeightMap::ForEach, FuncLength::ONE,
static_cast<uint8_t>(BUILTINS_STUB_ID(LightWeightMapForEach)));
BUILTINS_STUB_ID(LightWeightMapForEach));
SetFrozenFunction(thread, funcPrototype, "toString", ContainersLightWeightMap::ToString, FuncLength::ONE);
SetFrozenFunction(thread, funcPrototype, "getValueAt", ContainersLightWeightMap::GetValueAt, FuncLength::ONE);
SetFrozenFunction(thread, funcPrototype, "values", ContainersLightWeightMap::Values, FuncLength::ONE);
@ -445,7 +446,7 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeLightWeightSet(JSThread *th
SetFrozenFunction(thread, funcPrototype, "increaseCapacityTo",
ContainersLightWeightSet::IncreaseCapacityTo, FuncLength::ONE);
SetFrozenFunction(thread, funcPrototype, "forEach", ContainersLightWeightSet::ForEach, FuncLength::ONE,
static_cast<uint8_t>(BUILTINS_STUB_ID(LightWeightSetForEach)));
BUILTINS_STUB_ID(LightWeightSetForEach));
SetFrozenFunction(thread, funcPrototype, "getIndexOf", ContainersLightWeightSet::GetIndexOf, FuncLength::ONE);
SetFrozenFunction(thread, funcPrototype, "remove", ContainersLightWeightSet::Remove, FuncLength::ZERO);
SetFrozenFunction(thread, funcPrototype, "removeAt", ContainersLightWeightSet::RemoveAt, FuncLength::ZERO);
@ -656,7 +657,7 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializePlainArray(JSThread *thread
SetFrozenFunction(thread, plainArrayFuncPrototype, "has", ContainersPlainArray::Has, FuncLength::ONE);
SetFrozenFunction(thread, plainArrayFuncPrototype, "get", ContainersPlainArray::Get, FuncLength::ONE);
SetFrozenFunction(thread, plainArrayFuncPrototype, "forEach", ContainersPlainArray::ForEach, FuncLength::ONE,
static_cast<uint8_t>(BUILTINS_STUB_ID(PlainArrayForEach)));
BUILTINS_STUB_ID(PlainArrayForEach));
SetFrozenFunction(thread, plainArrayFuncPrototype, "toString", ContainersPlainArray::ToString,
FuncLength::ZERO);
SetFrozenFunction(thread, plainArrayFuncPrototype, "getIndexOfKey", ContainersPlainArray::GetIndexOfKey,
@ -735,7 +736,7 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeStack(JSThread *thread)
SetFrozenFunction(thread, stackFuncPrototype, "locate", ContainersStack::Locate, FuncLength::ONE);
// Stack.prototype.forEach()
SetFrozenFunction(thread, stackFuncPrototype, "forEach", ContainersStack::ForEach, FuncLength::ONE,
static_cast<uint8_t>(BUILTINS_STUB_ID(StackForEach)));
BUILTINS_STUB_ID(StackForEach));
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
SetStringTagSymbol(thread, env, stackFuncPrototype, "Stack");
@ -801,9 +802,9 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeVector(JSThread *thread)
SetFrozenFunction(thread, prototype, "subVector", ContainersVector::SubVector, FuncLength::TWO);
SetFrozenFunction(thread, prototype, "toString", ContainersVector::ToString, FuncLength::ZERO);
SetFrozenFunction(thread, prototype, "forEach", ContainersVector::ForEach, FuncLength::TWO,
static_cast<uint8_t>(BUILTINS_STUB_ID(VectorForEach)));
BUILTINS_STUB_ID(VectorForEach));
SetFrozenFunction(thread, prototype, "replaceAllElements", ContainersVector::ReplaceAllElements, FuncLength::TWO,
static_cast<uint8_t>(BUILTINS_STUB_ID(VectorReplaceAllElements)));
BUILTINS_STUB_ID(VectorReplaceAllElements));
SetFrozenFunction(thread, prototype, "has", ContainersVector::Has, FuncLength::ONE);
SetFrozenFunction(thread, prototype, "sort", ContainersVector::Sort, FuncLength::ZERO);
SetFrozenFunction(thread, prototype, "clear", ContainersVector::Clear, FuncLength::ZERO);
@ -867,7 +868,7 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeQueue(JSThread *thread)
SetFrozenFunction(thread, queueFuncPrototype, "getFirst", ContainersQueue::GetFirst, FuncLength::ZERO);
SetFrozenFunction(thread, queueFuncPrototype, "pop", ContainersQueue::Pop, FuncLength::ZERO);
SetFrozenFunction(thread, queueFuncPrototype, "forEach", ContainersQueue::ForEach, FuncLength::TWO,
static_cast<uint8_t>(BUILTINS_STUB_ID(QueueForEach)));
BUILTINS_STUB_ID(QueueForEach));
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
SetStringTagSymbol(thread, env, queueFuncPrototype, "Queue");
@ -924,7 +925,7 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeDeque(JSThread *thread)
SetFrozenFunction(thread, dequeFuncPrototype, "popFirst", ContainersDeque::PopFirst, FuncLength::ZERO);
SetFrozenFunction(thread, dequeFuncPrototype, "popLast", ContainersDeque::PopLast, FuncLength::ZERO);
SetFrozenFunction(thread, dequeFuncPrototype, "forEach", ContainersDeque::ForEach, FuncLength::TWO,
static_cast<uint8_t>(BUILTINS_STUB_ID(DequeForEach)));
BUILTINS_STUB_ID(DequeForEach));
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
SetStringTagSymbol(thread, env, dequeFuncPrototype, "Deque");
@ -982,7 +983,7 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeList(JSThread *thread)
SetFrozenFunction(thread, listFuncPrototype, "getLastIndexOf", ContainersList::GetLastIndexOf, FuncLength::ONE);
SetFrozenFunction(thread, listFuncPrototype, "set", ContainersList::Set, FuncLength::ONE);
SetFrozenFunction(thread, listFuncPrototype, "forEach", ContainersList::ForEach, FuncLength::ONE,
static_cast<uint8_t>(BUILTINS_STUB_ID(ListForEach)));
BUILTINS_STUB_ID(ListForEach));
SetFrozenFunction(thread, listFuncPrototype, "replaceAllElements", ContainersList::ReplaceAllElements,
FuncLength::ONE);
SetFrozenFunction(thread, listFuncPrototype, "equal", ContainersList::Equal, FuncLength::ONE);
@ -1045,7 +1046,7 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeLinkedList(JSThread *thread
FuncLength::ONE);
SetFrozenFunction(thread, linkedListFuncPrototype, "set", ContainersLinkedList::Set, FuncLength::ONE);
SetFrozenFunction(thread, linkedListFuncPrototype, "forEach", ContainersLinkedList::ForEach, FuncLength::ONE,
static_cast<uint8_t>(BUILTINS_STUB_ID(LinkedListForEach)));
BUILTINS_STUB_ID(LinkedListForEach));
JSHandle<JSTaggedValue> lengthGetter = CreateGetter(thread, ContainersLinkedList::Length, "length",
FuncLength::ZERO);
@ -1118,7 +1119,7 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeHashMap(JSThread *thread)
SetFrozenFunction(thread, hashMapFuncPrototype, "get", ContainersHashMap::Get, FuncLength::ONE);
// HashMap.prototype.forEach()
SetFrozenFunction(thread, hashMapFuncPrototype, "forEach", ContainersHashMap::ForEach, FuncLength::TWO,
static_cast<uint8_t>(BUILTINS_STUB_ID(HashMapForEach)));
BUILTINS_STUB_ID(HashMapForEach));
// HashMap.prototype.hasKey()
SetFrozenFunction(thread, hashMapFuncPrototype, "hasKey", ContainersHashMap::HasKey, FuncLength::ONE);
// HashMap.prototype.hasValue()
@ -1195,7 +1196,7 @@ JSHandle<JSTaggedValue> ContainersPrivate::InitializeHashSet(JSThread *thread)
SetFrozenFunction(thread, hashSetFuncPrototype, "values", ContainersHashSet::Values, FuncLength::ZERO);
SetFrozenFunction(thread, hashSetFuncPrototype, "entries", ContainersHashSet::Entries, FuncLength::ZERO);
SetFrozenFunction(thread, hashSetFuncPrototype, "forEach", ContainersHashSet::ForEach, FuncLength::TWO,
static_cast<uint8_t>(BUILTINS_STUB_ID(HashSetForEach)));
BUILTINS_STUB_ID(HashSetForEach));
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
// @@ToStringTag

View File

@ -50,9 +50,11 @@ private:
static JSHandle<JSFunction> NewContainerConstructor(JSThread *thread, const JSHandle<JSObject> &prototype,
EcmaEntrypoint ctorFunc, const char *name, int length);
static JSHandle<JSFunction> NewFunction(JSThread *thread, const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func,
int length, uint8_t builtinId = INVALID_BUILTINS_ID);
int length, kungfu::BuiltinsStubCSigns::ID builtinId =
kungfu::BuiltinsStubCSigns::INVALID);
static void SetFrozenFunction(JSThread *thread, const JSHandle<JSObject> &obj, const char *key, EcmaEntrypoint func,
int length, uint8_t builtinId = INVALID_BUILTINS_ID);
int length, kungfu::BuiltinsStubCSigns::ID builtinId =
kungfu::BuiltinsStubCSigns::INVALID);
static void SetFrozenConstructor(JSThread *thread, const JSHandle<JSObject> &obj, const char *keyChar,
JSHandle<JSTaggedValue> &value);
static JSHandle<JSTaggedValue> CreateGetter(JSThread *thread, EcmaEntrypoint func, const char *name,

View File

@ -435,6 +435,7 @@ JSTaggedValue EcmaVM::InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, JSH
JSTaggedValue EcmaVM::ExecuteAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp,
OptimizedEntryFrame::CallType callType)
{
INTERPRETER_TRACE(thread_, ExecuteAot);
auto entry = thread_->GetRTInterface(kungfu::RuntimeStubCSigns::ID_JSFunctionEntry);
auto res = reinterpret_cast<JSFunctionEntryType>(entry)(thread_->GetGlueAddr(),
actualNumArgs,

View File

@ -924,4 +924,24 @@ double JSDate::SetDateValues(const std::array<int64_t, DATE_LENGTH> *date, bool
}
return TimeClip(result);
}
double JSDate::SetDateValues(int64_t year, int64_t month, int64_t day)
{
if (year >= 0 && year < HUNDRED) {
year += NINETEEN_HUNDRED_YEAR;
}
int64_t m = DateUtils::Mod(month, MONTH_PER_YEAR);
int64_t y = year + (month - m) / MONTH_PER_YEAR;
int64_t d = DateUtils::GetDaysFromYear(y);
int index = DateUtils::IsLeap(y) ? 1 : 0;
d += DAYS_FROM_MONTH[index][m] + day - 1;
int64_t result = d * MS_PER_DAY;
int64_t offset = GetLocalOffsetFromOS(result, true) * SEC_PER_MINUTE * MS_PER_SECOND;
if (result < CHINA_1901_MS && (offset / MS_PER_MINUTE) == CHINA_AFTER_1901_MIN) {
offset += CHINA_BEFORE_1901_ADDMS;
}
result -= offset;
return TimeClip(result);
}
} // namespace panda::ecmascript

View File

@ -150,6 +150,7 @@ public:
static constexpr uint16_t HUNDRED = 100;
static constexpr uint16_t THOUSAND = 1000;
static double SetDateValues(const std::array<int64_t, DATE_LENGTH> *date, bool isLocal);
static double SetDateValues(int64_t year, int64_t month, int64_t day);
static void GetDateValues(double timeMs, std::array<int64_t, DATE_LENGTH> *date, bool isLocal);
static CString StrToTargetLength(const CString &str, int length);
DECL_DUMP()

View File

@ -152,7 +152,7 @@ struct BCDebuggerStubEntries {
};
struct BuiltinStubEntries {
static constexpr size_t COUNT = kungfu::BuiltinsStubCSigns::NUM_OF_BUILTINS_STUBS + 1;
static constexpr size_t COUNT = kungfu::BuiltinsStubCSigns::NUM_OF_BUILTINS_STUBS;
Address stubEntries_[COUNT];
static constexpr size_t SizeArch32 = sizeof(uint32_t) * COUNT;

View File

@ -60,7 +60,7 @@ public:
MAX_MESSAGE_COUNT,
ASM_INTERPRETER_START = Message_INT32_VALUE + 1,
BUILTINS_STUB_START = Message_CharCodeAt,
BUILTINS_STUB_LAST = Message_BooleanConstructor,
BUILTINS_STUB_LAST = Message_DateConstructor,
};
static const std::string& GetMessageString(int id);

View File

@ -143,16 +143,17 @@ using ErrorHelper = base::ErrorHelper;
ObjectFactory::ObjectFactory(JSThread *thread, Heap *heap)
: thread_(thread), vm_(thread->GetEcmaVM()), heap_(heap) {}
JSHandle<Method> ObjectFactory::NewMethodForNativeFunction(const void *func, FunctionKind kind, uint8_t builtinId)
JSHandle<Method> ObjectFactory::NewMethodForNativeFunction(const void *func, FunctionKind kind,
kungfu::BuiltinsStubCSigns::ID builtinId)
{
uint32_t numArgs = 2; // function object and this
auto method = NewMethod(nullptr);
method->SetNativePointer(const_cast<void *>(func));
method->SetNativeBit(true);
if (builtinId != INVALID_BUILTINS_ID) {
bool isFast = kungfu::BuiltinsStubCSigns::IsFastBuiltin(static_cast<kungfu::BuiltinsStubCSigns::ID>(builtinId));
if (builtinId != kungfu::BuiltinsStubCSigns::INVALID) {
bool isFast = kungfu::BuiltinsStubCSigns::IsFastBuiltin(builtinId);
method->SetFastBuiltinBit(isFast);
method->SetBuiltinId(builtinId);
method->SetBuiltinId(static_cast<uint8_t>(builtinId));
}
method->SetNumArgsWithCallField(numArgs);
method->SetFunctionKind(kind);
@ -1367,7 +1368,7 @@ JSHandle<JSObject> ObjectFactory::OrdinaryNewJSObjectCreate(const JSHandle<JSTag
}
JSHandle<JSFunction> ObjectFactory::NewJSFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc,
FunctionKind kind, uint8_t builtinId)
FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId)
{
JSHandle<Method> target = NewMethodForNativeFunction(nativeFunc, kind, builtinId);
return NewJSFunction(env, target);

View File

@ -178,14 +178,13 @@ using DeleteEntryPoint = void (*)(void *, void *);
enum class RemoveSlots { YES, NO };
enum class GrowMode { KEEP, GROW };
constexpr uint8_t INVALID_BUILTINS_ID = 0xFF;
class ObjectFactory {
public:
ObjectFactory(JSThread *thread, Heap *heap);
~ObjectFactory() = default;
JSHandle<Method> NewMethodForNativeFunction(const void *func, FunctionKind kind = FunctionKind::NORMAL_FUNCTION,
uint8_t builtinId = INVALID_BUILTINS_ID);
kungfu::BuiltinsStubCSigns::ID builtinId =
kungfu::BuiltinsStubCSigns::INVALID);
JSHandle<ProfileTypeInfo> NewProfileTypeInfo(uint32_t length);
JSHandle<ConstantPool> NewConstantPool(uint32_t capacity);
@ -208,7 +207,7 @@ public:
// use for native function
JSHandle<JSFunction> NewJSFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc = nullptr,
FunctionKind kind = FunctionKind::NORMAL_FUNCTION,
uint8_t builtinId = INVALID_BUILTINS_ID);
kungfu::BuiltinsStubCSigns::ID builtinId = kungfu::BuiltinsStubCSigns::INVALID);
// use for method
JSHandle<JSFunction> NewJSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<Method> &method);

View File

@ -161,6 +161,7 @@ namespace panda::ecmascript {
V(ExecuteNative) \
V(Execute) \
V(AsmExecute) \
V(ExecuteAot) \
V(ToJSTaggedValueWithInt32) \
V(ToJSTaggedValueWithUint32) \
V(ThrowIfSuperNotCorrectCall) \

View File

@ -34,6 +34,7 @@
#include "ecmascript/interpreter/interpreter-inl.h"
#include "ecmascript/interpreter/interpreter_assembly.h"
#include "ecmascript/js_api/js_api_arraylist.h"
#include "ecmascript/js_date.h"
#include "ecmascript/js_function.h"
#include "ecmascript/js_object.h"
#include "ecmascript/js_proxy.h"
@ -2035,6 +2036,21 @@ bool RuntimeStubs::BigIntEquals(JSTaggedType left, JSTaggedType right)
return BigInt::Equal(JSTaggedValue(left), JSTaggedValue(right));
}
double RuntimeStubs::TimeClip(double time)
{
return JSDate::TimeClip(time);
}
double RuntimeStubs::SetDateValues(double year, double month, double day)
{
if (std::isnan(year) || !std::isfinite(year) || std::isnan(month) || !std::isfinite(month) || std::isnan(day) ||
!std::isfinite(day)) {
return base::NAN_VALUE;
}
return JSDate::SetDateValues(static_cast<int64_t>(year), static_cast<int64_t>(month), static_cast<int64_t>(day));
}
JSTaggedValue RuntimeStubs::NewObject(EcmaRuntimeCallInfo *info)
{
ASSERT(info);

View File

@ -103,7 +103,9 @@ using JSFunctionEntryType = JSTaggedValue (*)(uintptr_t glue, uint32_t argc, con
V(FindElementWithCache) \
V(CreateArrayFromList) \
V(StringsAreEquals) \
V(BigIntEquals)
V(BigIntEquals) \
V(TimeClip) \
V(SetDateValues)
#define RUNTIME_STUB_WITH_GC_LIST(V) \
V(AddElementInternal) \
@ -343,6 +345,8 @@ public:
JSTaggedType key, int32_t num);
static bool StringsAreEquals(EcmaString *str1, EcmaString *str2);
static bool BigIntEquals(JSTaggedType left, JSTaggedType right);
static double TimeClip(double time);
static double SetDateValues(double year, double month, double day);
static JSTaggedValue CallBoundFunction(EcmaRuntimeCallInfo *info);
private:

View File

@ -36,4 +36,11 @@ class MyBoolean extends Boolean {
}
let b = new MyBoolean(true);
print(b instanceof MyBoolean);
print(b instanceof Boolean);
print(b instanceof Boolean);
let d1 = new Date(16455456000);
print(d1);
let d2 = new Date(2022, 3, 4);
print(d2);
let d3 = new Date(2022, NaN, 4);
print(d3);

View File

@ -20,3 +20,6 @@ true
false
true
true
Fri Jul 10 1970 18:57:36 GMT+0800
Mon Apr 04 2022 00:00:00 GMT+0800
Invalid Date