Perf(Aot): nbody optimization

1. Optimize CallTargetCheck lowering
2. StoreProperty bugfix

Issue: #I6V1KU
Change-Id: I818c1df9454f745ff9245cdff9d9c4a45cbf282e
Signed-off-by: yingguofeng@huawei.com <yingguofeng@huawei.com>
This commit is contained in:
yingguofeng@huawei.com 2023-04-12 15:26:21 +08:00
parent de66e1b3c0
commit e705f7a167
21 changed files with 223 additions and 89 deletions

View File

@ -2716,11 +2716,15 @@ JSHandle<JSFunction> Builtins::NewFunction(const JSHandle<GlobalEnv> &env, const
kungfu::BuiltinsStubCSigns::ID builtinId) const
{
JSHandle<JSFunction> function = factory_->NewJSFunction(env, reinterpret_cast<void *>(func),
FunctionKind::NORMAL_FUNCTION, builtinId);
FunctionKind::NORMAL_FUNCTION, builtinId, MemSpaceType::NON_MOVABLE);
JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(length));
JSHandle<JSFunctionBase> baseFunction(function);
JSHandle<JSTaggedValue> handleUndefine(thread_, JSTaggedValue::Undefined());
JSFunction::SetFunctionName(thread_, baseFunction, key, handleUndefine);
if (IS_TYPED_BUILTINS_ID(builtinId)) {
auto globalConst = const_cast<GlobalEnvConstants *>(thread_->GlobalConstants());
globalConst->SetConstant(GET_TYPED_CONSTANT_INDEX(builtinId), function);
}
return function;
}

View File

@ -18,6 +18,7 @@
#include "ecmascript/base/config.h"
#include "ecmascript/compiler/rt_call_signature.h"
#include "ecmascript/global_env_constants.h"
namespace panda::ecmascript::kungfu {
@ -103,6 +104,63 @@ public:
{
return builtinId > NONE && builtinId < NUM_OF_BUILTINS_STUBS;
}
static bool IsTypedBuiltin(ID builtinId)
{
switch (builtinId) {
case BuiltinsStubCSigns::ID::COS:
case BuiltinsStubCSigns::ID::SIN:
case BuiltinsStubCSigns::ID::ACOS:
case BuiltinsStubCSigns::ID::ATAN:
case BuiltinsStubCSigns::ID::ABS:
case BuiltinsStubCSigns::ID::FLOOR:
case BuiltinsStubCSigns::ID::SQRT:
return true;
default:
return false;
}
}
static ConstantIndex GetConstantIndex(ID builtinId)
{
switch (builtinId) {
case BuiltinsStubCSigns::ID::COS:
return ConstantIndex::MATH_COS_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::SIN:
return ConstantIndex::MATH_SIN_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::ACOS:
return ConstantIndex::MATH_ACOS_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::ATAN:
return ConstantIndex::MATH_ATAN_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::ABS:
return ConstantIndex::MATH_ABS_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::FLOOR:
return ConstantIndex::MATH_FLOOR_FUNCTION_INDEX;
case BuiltinsStubCSigns::ID::SQRT:
return ConstantIndex::MATH_SQRT_FUNCTION_INDEX;
default:
LOG_COMPILER(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
}
static ID GetBuiltinId(std::string idStr)
{
const std::map<std::string, BuiltinsStubCSigns::ID> str2BuiltinId = {
{"sqrt", SQRT},
{"cos", COS},
{"sin", SIN},
{"acos", ACOS},
{"atan", ATAN},
{"abs", ABS},
{"floor", FLOOR},
};
if (str2BuiltinId.count(idStr) > 0) {
return str2BuiltinId.at(idStr);
}
return NONE;
}
private:
static CallSignature callSigns_[NUM_OF_BUILTINS_STUBS];
static CallSignature builtinsCSign_;
@ -123,5 +181,7 @@ enum class BuiltinsArgs : size_t {
};
#define BUILTINS_STUB_ID(name) kungfu::BuiltinsStubCSigns::name
#define IS_TYPED_BUILTINS_ID(id) kungfu::BuiltinsStubCSigns::IsTypedBuiltin(id)
#define GET_TYPED_CONSTANT_INDEX(id) kungfu::BuiltinsStubCSigns::GetConstantIndex(id)
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_BUILTINS_CALL_SIGNATURE_H

View File

@ -965,8 +965,7 @@ DECLARE_BUILTINS(ArrayConstructor)
GateRef glueGlobalEnvOffset = IntPtr(JSThread::GlueData::GetGlueGlobalEnvOffset(env->Is32Bit()));
GateRef glueGlobalEnv = Load(VariableType::NATIVE_POINTER(), glue, glueGlobalEnvOffset);
auto arrayFunc = GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv, GlobalEnv::ARRAY_FUNCTION_INDEX);
Branch(Equal(ChangeTaggedPointerToInt64(arrayFunc), ChangeTaggedPointerToInt64(newTarget)), &fastGetHclass,
&slowPath);
Branch(Equal(arrayFunc, newTarget), &fastGetHclass, &slowPath);
Bind(&fastGetHclass);
GateRef intialHClass = Load(VariableType::JS_ANY(), newTarget, IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
DEFVARIABLE(arrayLength, VariableType::INT64(), Int64(0));

View File

@ -178,51 +178,14 @@ GateRef BuiltinLowering::TypedAbs(GateRef gate)
GateRef BuiltinLowering::LowerCallTargetCheck(Environment *env, GateRef gate)
{
builder_.SetEnvironment(env);
Label entry(&builder_);
env->SubCfgEntry(&entry);
GateRef idGate = acc_.GetValueIn(gate, 1);
BuiltinsStubCSigns::ID id = static_cast<BuiltinsStubCSigns::ID>(acc_.GetConstantValue(idGate));
GateRef glue = acc_.GetGlueFromArgList();
GateRef constantFunction =
builder_.GetGlobalConstantValue(VariableType::JS_POINTER(), glue, GET_TYPED_CONSTANT_INDEX(id));
GateRef function = acc_.GetValueIn(gate, 0); // 0: function
GateRef id = acc_.GetValueIn(gate, 1); // 1: buitin id
Label isHeapObject(&builder_);
Label funcIsCallable(&builder_);
Label exit(&builder_);
GateRef isObject = builder_.TaggedIsHeapObject(function);
DEFVAlUE(result, (&builder_), VariableType::BOOL(), builder_.False());
builder_.Branch(isObject, &isHeapObject, &exit);
builder_.Bind(&isHeapObject);
{
GateRef callable = builder_.IsCallable(function);
builder_.Branch(callable, &funcIsCallable, &exit);
builder_.Bind(&funcIsCallable);
{
GateRef method = builder_.Load(VariableType::JS_ANY(), function,
builder_.IntPtr(JSFunctionBase::METHOD_OFFSET));
GateRef builtinId = builder_.GetCallBuiltinId(method);
result = builder_.Int64Equal(builtinId, id);
builder_.Jump(&exit);
}
}
builder_.Bind(&exit);
auto ret = *result;
env->SubCfgExit();
return ret;
}
BuiltinsStubCSigns::ID BuiltinLowering::GetBuiltinId(std::string idStr)
{
const std::map<std::string, BuiltinsStubCSigns::ID> str2BuiltinId = {
{"sqrt", BUILTINS_STUB_ID(SQRT)},
{"cos", BUILTINS_STUB_ID(COS)},
{"sin", BUILTINS_STUB_ID(SIN)},
{"acos", BUILTINS_STUB_ID(ACOS)},
{"atan", BUILTINS_STUB_ID(ATAN)},
{"abs", BUILTINS_STUB_ID(ABS)},
{"floor", BUILTINS_STUB_ID(FLOOR)},
};
if (str2BuiltinId.count(idStr) > 0) {
return str2BuiltinId.at(idStr);
}
return BUILTINS_STUB_ID(NONE);
return builder_.Equal(function, constantFunction);
}
GateRef BuiltinLowering::CheckPara(GateRef gate, GateRef funcCheck)

View File

@ -29,7 +29,6 @@ public:
void LowerTypedCallBuitin(GateRef gate);
GateRef LowerCallTargetCheck(Environment *env, GateRef gate);
void LowerTypedSqrt(GateRef gate);
static BuiltinsStubCSigns::ID GetBuiltinId(std::string idStr);
GateRef CheckPara(GateRef gate, GateRef funcCheck);
private:
void LowerTypedTrigonometric(GateRef gate, BuiltinsStubCSigns::ID id);

View File

@ -1277,7 +1277,7 @@ GateRef CircuitBuilder::GetCodeAddr(GateRef method)
GateRef CircuitBuilder::GetGlobalConstantValue(VariableType type, GateRef glue, ConstantIndex index)
{
GateRef gConstAddr = PtrAdd(glue,
IntPtr(JSThread::GlueData::GetGlobalConstOffset(cmpCfg_->Is32Bit())));
IntPtr(JSThread::GlueData::GetGlobalConstOffset(env_->Is32Bit())));
auto constantIndex = IntPtr(JSTaggedValue::TaggedTypeSize() * static_cast<size_t>(index));
return Load(type, gConstAddr, constantIndex);
}

View File

@ -38,6 +38,7 @@ using namespace panda::ecmascript;
class Environment;
class Label;
class Variable;
class StubBuilder;
#define BINARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(V) \
V(Int16Add, Add, MachineType::I16) \
@ -109,7 +110,6 @@ class Variable;
V(TruncFloatToInt32, TruncFloatToInt32, MachineType::I32) \
V(ExtFloat32ToDouble, Fext, MachineType::F64) \
V(TruncDoubleToFloat32, Ftrunc, MachineType::F32) \
V(ChangeTaggedPointerToInt64, TaggedToInt64, MachineType::I64) \
V(ChangeInt32ToFloat64, SignedIntToFloat, MachineType::F64) \
V(ChangeInt32ToFloat32, SignedIntToFloat, MachineType::F32) \
V(ChangeUInt32ToFloat64, UnsignedIntToFloat, MachineType::F64) \
@ -119,6 +119,9 @@ class Variable;
V(SExtInt8ToInt32, Sext, MachineType::I32) \
V(SExtInt8ToInt64, Sext, MachineType::I64) \
#define UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH_PRIVATE(V) \
V(ChangeTaggedPointerToInt64, TaggedToInt64, MachineType::I64)
#define BINARY_CMP_METHOD_LIST_WITHOUT_BITWIDTH(V) \
V(DoubleLessThan, Fcmp, static_cast<BitField>(FCmpCondition::OLT)) \
V(DoubleLessThanOrEqual, Fcmp, static_cast<BitField>(FCmpCondition::OLE)) \
@ -568,10 +571,20 @@ public:
GateRef IsBase(GateRef ctor);
private:
#define ARITHMETIC_UNARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID) \
inline GateRef NAME(GateRef x) \
{ \
return circuit_->NewGate(circuit_->OPCODEID(), MACHINETYPEID, { x }, GateType::NJSValue()); \
}
UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH_PRIVATE(ARITHMETIC_UNARY_OP_WITH_BITWIDTH)
#undef ARITHMETIC_UNARY_OP_WITH_BITWIDTH
Circuit *circuit_ {nullptr};
GateAccessor acc_;
Environment *env_ {nullptr};
CompilationConfig *cmpCfg_ {nullptr};
friend StubBuilder;
};
class Label {

View File

@ -56,10 +56,6 @@ void NumberSpeculativeLowering::VisitGate(GateRef gate)
VisitConstant(gate);
break;
}
case OpCode::STORE_PROPERTY: {
VisitStoreProperty(gate);
break;
}
case OpCode::TYPED_CALL_BUILTIN: {
VisitCallBuiltins(gate);
break;
@ -331,20 +327,6 @@ void NumberSpeculativeLowering::VisitUndefinedStrictEq(GateRef gate)
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
}
void NumberSpeculativeLowering::VisitStoreProperty(GateRef gate)
{
TypeInfo output = typeInfos_[acc_.GetId(gate)];
switch (output) {
case TypeInfo::INT1:
case TypeInfo::INT32:
case TypeInfo::FLOAT64:
builder_.StorePropertyNoBarrier(gate);
break;
default:
break;
}
}
void NumberSpeculativeLowering::VisitCallBuiltins(GateRef gate)
{
auto valuesIn = acc_.GetNumValueIn(gate);

View File

@ -40,7 +40,6 @@ private:
void VisitConstant(GateRef gate);
void VisitPhi(GateRef gate);
void VisitUndefinedStrictEq(GateRef gate);
void VisitStoreProperty(GateRef gate);
void VisitCallBuiltins(GateRef gate);
template<TypedBinOp Op>

View File

@ -70,6 +70,8 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate)
return VisitConstant(gate);
case OpCode::TYPED_CALL_BUILTIN:
return VisitCallBuiltins(gate);
case OpCode::STORE_PROPERTY:
return VisitStoreProperty(gate);
default:
return VisitOthers(gate);
}
@ -663,6 +665,32 @@ GateRef NumberSpeculativeRetype::VisitStoreElement(GateRef gate)
return Circuit::NullGate();
}
GateRef NumberSpeculativeRetype::VisitStoreProperty(GateRef gate)
{
if (IsRetype()) {
return SetOutputType(gate, GateType::AnyType());
}
if (IsConvert()) {
GateRef value = acc_.GetValueIn(gate, 2);
TypeInfo valueType = typeInfos_[acc_.GetId(value)];
switch (valueType) {
case TypeInfo::INT1:
case TypeInfo::INT32:
case TypeInfo::FLOAT64:
builder_.StorePropertyNoBarrier(gate);
break;
default:
break;
}
size_t valueNum = acc_.GetNumValueIn(gate);
for (size_t i = 0; i < valueNum; ++i) {
GateRef input = acc_.GetValueIn(gate, i);
acc_.ReplaceValueIn(gate, ConvertToTagged(input), i);
}
}
return Circuit::NullGate();
}
GateRef NumberSpeculativeRetype::VisitNumberDiv(GateRef gate)
{
if (IsRetype()) {

View File

@ -73,6 +73,7 @@ private:
GateRef VisitIndexCheck(GateRef gate);
GateRef VisitLoadElement(GateRef gate);
GateRef VisitStoreElement(GateRef gate);
GateRef VisitStoreProperty(GateRef gate);
GateRef VisitNumberRelated(GateRef gate);
GateRef VisitCallBuiltins(GateRef gate);
GateRef VisitOthers(GateRef gate);

View File

@ -469,7 +469,6 @@ public:
GateRef ChangeInt32ToFloat64(GateRef x);
GateRef ChangeUInt32ToFloat64(GateRef x);
GateRef ChangeFloat64ToInt32(GateRef x);
GateRef ChangeTaggedPointerToInt64(GateRef x);
GateRef Int64ToTaggedPtr(GateRef x);
GateRef TruncInt16ToInt8(GateRef x);
GateRef CastInt32ToFloat32(GateRef x);
@ -608,6 +607,7 @@ public:
GateRef ToNumber(GateRef glue, GateRef tagged);
private:
using BinaryOperation = std::function<GateRef(Environment*, GateRef, GateRef)>;
GateRef ChangeTaggedPointerToInt64(GateRef x);
template<OpCode Op>
GateRef FastAddSubAndMul(GateRef left, GateRef right, ProfileOperation callback);
GateRef FastBinaryOp(GateRef left, GateRef right,

View File

@ -102,7 +102,7 @@ HWTEST_F_L0(LoweringRelateGateTests, HeapAllocTest)
auto arg1 = builder.Arguments(2);
auto array = builder.HeapAlloc(arg0, GateType::AnyType(), RegionSpaceFlag::IN_YOUNG_SPACE);
auto offset = builder.Int64(JSThread::GlueData::GetGlueGlobalConstOffset(false));
auto offset = builder.Int64(JSThread::GlueData::GetGlobalConstOffset(false));
auto globalEnv = builder.Load(VariableType::JS_POINTER(), glue, offset);
auto lenthOffset = builder.IntPtr(GlobalEnvConstants::GetOffsetOfLengthString());
auto lengthString = builder.Load(VariableType::JS_POINTER(), globalEnv, lenthOffset);

View File

@ -875,7 +875,7 @@ BuiltinsStubCSigns::ID TSTypeLowering::GetBuiltinId(GateRef func)
return BuiltinsStubCSigns::ID::NONE;
}
std::string name = tsManager_->GetFuncName(funcType);
BuiltinsStubCSigns::ID id = BuiltinLowering::GetBuiltinId(name);
BuiltinsStubCSigns::ID id = BuiltinsStubCSigns::GetBuiltinId(name);
return id;
}

View File

@ -965,7 +965,7 @@ void EcmaVM::GenerateInternalNativeMethods()
size_t length = static_cast<size_t>(MethodIndex::METHOD_END);
for (size_t i = 0; i < length; i++) {
uint32_t numArgs = 2; // function object and this
auto method = factory_->NewMethod(nullptr);
auto method = factory_->NewMethod(nullptr, MemSpaceType::NON_MOVABLE);
method->SetNativePointer(InternalMethodTable[i]);
method->SetNativeBit(true);
method->SetNumArgsWithCallField(numArgs);

View File

@ -130,7 +130,15 @@ class JSThread;
V(JSTaggedValue, EmptyArray, EMPTY_ARRAY_OBJECT_INDEX, ecma_roots_special) \
V(JSTaggedValue, EmptyWeakVector, EMPTY_WEAK_VECTOR_OBJECT_INDEX, ecma_roots_special) \
V(JSTaggedValue, EmptyTaggedQueue, EMPTY_TAGGED_QUEUE_OBJECT_INDEX, ecma_roots_special) \
V(JSTaggedValue, UndefinedCompletionRecord, UNDEFINED_COMPLRTION_RECORD_INDEX, ecma_roots_special)
V(JSTaggedValue, UndefinedCompletionRecord, UNDEFINED_COMPLRTION_RECORD_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathSqrtFunction, MATH_SQRT_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathCosFunction, MATH_COS_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathSinFunction, MATH_SIN_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathACosFunction, MATH_ACOS_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathATanFunction, MATH_ATAN_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathAbsFunction, MATH_ABS_FUNCTION_INDEX, ecma_roots_special) \
V(JSTaggedValue, MathFloorFunction, MATH_FLOOR_FUNCTION_INDEX, ecma_roots_special)
/* GlobalConstant */
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define GLOBAL_ENV_CONSTANT_CONSTANT(V) \

View File

@ -816,11 +816,6 @@ public:
return GetOffset<static_cast<size_t>(Index::GlueGlobalEnvIndex)>(isArch32);
}
static size_t GetGlueGlobalConstOffset(bool isArch32)
{
return GetOffset<static_cast<size_t>(Index::GlobalConstIndex)>(isArch32);
}
static size_t GetAllowCrossThreadExecutionOffset(bool isArch32)
{
return GetOffset<static_cast<size_t>(Index::AllowCrossThreadExecutionIndex)>(isArch32);

View File

@ -149,10 +149,11 @@ ObjectFactory::ObjectFactory(JSThread *thread, Heap *heap)
: thread_(thread), vm_(thread->GetEcmaVM()), heap_(heap) {}
JSHandle<Method> ObjectFactory::NewMethodForNativeFunction(const void *func, FunctionKind kind,
kungfu::BuiltinsStubCSigns::ID builtinId)
kungfu::BuiltinsStubCSigns::ID builtinId,
MemSpaceType spaceType)
{
uint32_t numArgs = 2; // function object and this
auto method = NewMethod(nullptr);
auto method = NewMethod(nullptr, spaceType);
method->SetNativePointer(const_cast<void *>(func));
method->SetNativeBit(true);
if (builtinId != kungfu::BuiltinsStubCSigns::INVALID) {
@ -1400,9 +1401,10 @@ JSHandle<JSObject> ObjectFactory::OrdinaryNewJSObjectCreate(const JSHandle<JSTag
}
JSHandle<JSFunction> ObjectFactory::NewJSFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc,
FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId)
FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId,
MemSpaceType spaceType)
{
JSHandle<Method> target = NewMethodForNativeFunction(nativeFunc, kind, builtinId);
JSHandle<Method> target = NewMethodForNativeFunction(nativeFunc, kind, builtinId, spaceType);
return NewJSFunction(env, target);
}
@ -1575,11 +1577,17 @@ JSHandle<JSFunction> ObjectFactory::NewJSFunctionByHClass(const void *func, cons
return function;
}
JSHandle<Method> ObjectFactory::NewMethod(const MethodLiteral *methodLiteral)
JSHandle<Method> ObjectFactory::NewMethod(const MethodLiteral *methodLiteral, MemSpaceType spaceType)
{
NewObjectHook();
TaggedObject *header = heap_->AllocateOldOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
TaggedObject *header = nullptr;
if (spaceType == NON_MOVABLE) {
header = heap_->AllocateNonMovableOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
} else {
header = heap_->AllocateOldOrHugeObject(
JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
}
JSHandle<Method> method(thread_, header);
if (methodLiteral != nullptr) {
method->SetCallField(methodLiteral->GetCallField());

View File

@ -191,7 +191,8 @@ public:
~ObjectFactory() = default;
JSHandle<Method> NewMethodForNativeFunction(const void *func, FunctionKind kind = FunctionKind::NORMAL_FUNCTION,
kungfu::BuiltinsStubCSigns::ID builtinId =
kungfu::BuiltinsStubCSigns::INVALID);
kungfu::BuiltinsStubCSigns::INVALID,
MemSpaceType spaceType = OLD_SPACE);
JSHandle<ProfileTypeInfo> NewProfileTypeInfo(uint32_t length);
JSHandle<ConstantPool> NewConstantPool(uint32_t capacity);
@ -218,7 +219,8 @@ public:
// use for native function
JSHandle<JSFunction> NewJSFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc = nullptr,
FunctionKind kind = FunctionKind::NORMAL_FUNCTION,
kungfu::BuiltinsStubCSigns::ID builtinId = kungfu::BuiltinsStubCSigns::INVALID);
kungfu::BuiltinsStubCSigns::ID builtinId = kungfu::BuiltinsStubCSigns::INVALID,
MemSpaceType spaceType = OLD_SPACE);
// use for method
JSHandle<JSFunction> NewJSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<Method> &method);
@ -470,7 +472,7 @@ public:
MemSpaceType type = MemSpaceType::SEMI_SPACE);
JSHandle<JSFunction> NewJSFunctionByHClass(const void *func, const JSHandle<JSHClass> &clazz,
FunctionKind kind = FunctionKind::NORMAL_FUNCTION);
JSHandle<Method> NewMethod(const MethodLiteral *methodLiteral);
JSHandle<Method> NewMethod(const MethodLiteral *methodLiteral, MemSpaceType spaceType = OLD_SPACE);
// used for creating jsobject by constructor
JSHandle<JSObject> NewJSObjectByConstructor(const JSHandle<JSFunction> &constructor,

View File

@ -14,6 +14,10 @@
*/
declare function print(arg:any):string;
function replace(a : number)
{
return a;
}
let len:number = 1;
len = 1 / Math.sqrt(len);
print(len);
@ -25,10 +29,33 @@ print(NaN);
len = Math.sqrt(NaN);
print(len);
len = Math.sqrt(+0); // 0
print(len)
len = Math.sqrt(Number.POSITIVE_INFINITY); // Infinity
print(len)
len = Math.sqrt(Number.NEGATIVE_INFINITY); // NaN
print(len)
len = Math.sqrt(-1); // NaN
print(len)
function sqrt()
{
Math.sqrt = replace;
len = Math.sqrt(9)
print(len)
}
sqrt()
len = Math.cos(0); // 1
print(len);
len = Math.cos(1); // 0.5....
print(len);
function cos()
{
Math.cos = replace;
len = Math.cos(1);
print(len)
}
cos()
len = Math.sin(0); // 0
print(len);
@ -36,12 +63,33 @@ len = Math.sin(1); // 0.84
print(len);
len = Math.sin(Math.PI / 2);
print(len);
function sin()
{
Math.sin = replace;
len = Math.sin(1)
print(len)
}
sin()
len = Math.acos(0.5);// 1.0471975511965979
print(len);
function acos()
{
Math.acos = replace
len = Math.acos(0.5)
print(len)
}
acos()
len = Math.atan(2); // 1.1071487177940904
print(len);
function atan()
{
Math.atan = replace
len = Math.atan(2)
print(len)
}
atan()
len = Math.abs(Number.NaN);
print(len);
@ -59,6 +107,13 @@ len = Math.abs(-9.6);
print(len);
len = Math.abs(-6);
print(len);
function abs()
{
Math.abs = replace
len = Math.abs(-9.6)
print(len)
}
abs()
len = Math.floor(Number.NaN);
print(len);
@ -71,4 +126,11 @@ print(len);
len = Math.floor(9.6);
print(len);
len = Math.floor(-9.6);
print(len);
print(len);
function floor()
{
Math.floor = replace
len = Math.floor(-9.6)
print(len)
}
floor()

View File

@ -15,13 +15,22 @@
3
NaN
NaN
0
Infinity
NaN
NaN
9
1
0.5403023058681398
1
0
0.8414709848078965
1
1
1.0471975511965979
0.5
1.1071487177940904
2
NaN
NaN
Infinity
@ -30,9 +39,11 @@ Infinity
6
9.6
6
-9.6
NaN
NaN
-Infinity
Infinity
9
-10
-9.6