mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
AOT support js stacktrace
1. add pcOffset into stackmap before call In AOT 2. parse stackmap to find pcOffset before any OptimziedJSFunctionFrame 3. remove use code of stubs in AOT 4. add testcase for js stacktrace of AOT Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6GXRR?from=project-issue Signed-off-by: zhangyukun8 <zhangyukun8@huawei.com> Change-Id: Ib21646b7319628fb425ac8ce489dc2370a347b81
This commit is contained in:
parent
9cd0d162b6
commit
62a3e35295
@ -494,16 +494,6 @@ JSTaggedValue BuiltinsGlobal::PrintEntrypoint(EcmaRuntimeCallInfo *msg)
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
PrintString(thread, *stringContent);
|
||||
|
||||
// print bc offset for ts aot
|
||||
if (GetCallArg(msg, i)->IsJSError() && thread->IsPrintBCOffset()) {
|
||||
auto list = thread->GetEcmaVM()->GetBCOffsetInfoList();
|
||||
if (!list.empty()) {
|
||||
for (auto info : list) {
|
||||
std::cout << "\nException at function " << info.first << ": " << info.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i != numArgs - 1) {
|
||||
std::cout << " ";
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ GateRef BuiltinLowering::TypedTrigonometric(GateRef gate, BuiltinsStubCSigns::ID
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
}
|
||||
result = builder_.CallNGCRuntime(glue, index, Gate::InvalidGateRef, {value});
|
||||
result = builder_.CallNGCRuntime(glue, index, Gate::InvalidGateRef, {value}, gate);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&IsNan);
|
||||
@ -191,7 +191,7 @@ GateRef BuiltinLowering::TypedSqrt(GateRef gate)
|
||||
{
|
||||
GateRef glue = acc_.GetGlueFromArgList();
|
||||
result = builder_.CallNGCRuntime(
|
||||
glue, RTSTUB_ID(FloatSqrt), Gate::InvalidGateRef, {*value});
|
||||
glue, RTSTUB_ID(FloatSqrt), Gate::InvalidGateRef, {*value}, gate);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
// If value is NaN, the result is NaN
|
||||
|
@ -821,8 +821,9 @@ void BytecodeCircuitBuilder::NewJSGate(BytecodeRegion &bb, GateRef &state, GateR
|
||||
size_t numValueInputs = bytecodeInfo.ComputeValueInputCount();
|
||||
GateRef gate = 0;
|
||||
bool writable = !bytecodeInfo.NoSideEffects();
|
||||
size_t pcOffset = GetPcOffset(iterator.Index());
|
||||
auto meta = circuit_->JSBytecode(numValueInputs,
|
||||
bytecodeInfo.GetOpcode(), iterator.Index(), writable);
|
||||
bytecodeInfo.GetOpcode(), pcOffset, writable);
|
||||
std::vector<GateRef> inList = CreateGateInList(bytecodeInfo, meta);
|
||||
if (bytecodeInfo.IsDef()) {
|
||||
gate = circuit_->NewGate(meta, MachineType::I64, inList.size(),
|
||||
@ -906,8 +907,8 @@ void BytecodeCircuitBuilder::NewJump(BytecodeRegion &bb, GateRef &state, GateRef
|
||||
auto offset = GetJumpOffset(iterator.Index());
|
||||
if (bytecodeInfo.IsCondJump()) {
|
||||
ASSERT(!bytecodeInfo.Deopt());
|
||||
auto meta = circuit_->JSBytecode(numValueInputs,
|
||||
bytecodeInfo.GetOpcode(), iterator.Index(), false);
|
||||
size_t pcOffset = GetPcOffset(iterator.Index());
|
||||
auto meta = circuit_->JSBytecode(numValueInputs, bytecodeInfo.GetOpcode(), pcOffset, false);
|
||||
auto numValues = meta->GetNumIns();
|
||||
GateRef gate = circuit_->NewGate(meta, std::vector<GateRef>(numValues, Circuit::NullGate()));
|
||||
gateAcc_.NewIn(gate, 0, state);
|
||||
|
@ -84,6 +84,16 @@ DEF_CALL_SIGNATURE(NotEqual)
|
||||
BINARY_CALL_SIGNATURE(NotEqual)
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(StrictEqual)
|
||||
{
|
||||
BINARY_CALL_SIGNATURE(StrictEqual)
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(StrictNotEqual)
|
||||
{
|
||||
BINARY_CALL_SIGNATURE(StrictNotEqual)
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(Less)
|
||||
{
|
||||
BINARY_CALL_SIGNATURE(Less)
|
||||
@ -632,6 +642,51 @@ DEF_CALL_SIGNATURE(ConstructorCheck)
|
||||
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(CreateEmptyArray)
|
||||
{
|
||||
// 1 : 1 input parameters
|
||||
CallSignature signature("CreateEmptyArray", 0, 1,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = signature;
|
||||
// 1 : 1 input parameters
|
||||
std::array<VariableType, 1> params = {
|
||||
VariableType::NATIVE_POINTER(), // glue
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(CreateArrayWithBuffer)
|
||||
{
|
||||
// 3 : 3 input parameters
|
||||
CallSignature signature("CreateArrayWithBuffer", 0, 3,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = signature;
|
||||
// 3 : 3 input parameters
|
||||
std::array<VariableType, 3> params = {
|
||||
VariableType::NATIVE_POINTER(), // glue
|
||||
VariableType::INT32(), // index
|
||||
VariableType::JS_ANY(), // jsFunc
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(NewJSObject)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
CallSignature signature("NewJSObject", 0, 2,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = signature;
|
||||
// 2 : 2 input parameters
|
||||
std::array<VariableType, 2> params = {
|
||||
VariableType::NATIVE_POINTER(), // glue
|
||||
VariableType::JS_ANY(), // hclass
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(NewLexicalEnv)
|
||||
{
|
||||
// 3 : 3 input parameters
|
||||
|
@ -314,6 +314,8 @@ private:
|
||||
V(TypeOf) \
|
||||
V(Equal) \
|
||||
V(NotEqual) \
|
||||
V(StrictEqual) \
|
||||
V(StrictNotEqual) \
|
||||
V(Less) \
|
||||
V(LessEq) \
|
||||
V(Greater) \
|
||||
@ -356,6 +358,9 @@ private:
|
||||
V(GetUnmapedArgs) \
|
||||
V(NewThisObjectChecked) \
|
||||
V(ConstructorCheck) \
|
||||
V(CreateEmptyArray) \
|
||||
V(CreateArrayWithBuffer) \
|
||||
V(NewJSObject) \
|
||||
V(GetTaggedArrayPtrTest) \
|
||||
V(BytecodeHandler) \
|
||||
V(Builtins) \
|
||||
|
@ -121,10 +121,10 @@ public:
|
||||
}
|
||||
|
||||
const GateMetaData* JSBytecode(size_t valuesIn, EcmaOpcode opcode,
|
||||
uint32_t bcIndex, bool writable)
|
||||
uint32_t pcOffset, bool writable)
|
||||
{
|
||||
GateFlags flags = writable ? GateFlags::NONE_FLAG : GateFlags::NO_WRITE;
|
||||
return metaBuilder_.JSBytecode(valuesIn, opcode, bcIndex, flags);
|
||||
return metaBuilder_.JSBytecode(valuesIn, opcode, pcOffset, flags);
|
||||
}
|
||||
|
||||
const GateMetaData* TypedBinaryOp(uint64_t value, TypedBinOp binOp)
|
||||
@ -151,6 +151,11 @@ public:
|
||||
return static_cast<size_t>(gateCount_ - 1);
|
||||
}
|
||||
|
||||
bool IsOptimizedJSFunctionFrame() const
|
||||
{
|
||||
return frameType_ == panda::ecmascript::FrameType::OPTIMIZED_JS_FUNCTION_FRAME;
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t CIRCUIT_SPACE = 1U << 30U; // 1GB
|
||||
|
||||
|
@ -403,45 +403,50 @@ GateRef CircuitBuilder::BinaryCmp(const GateMetaData* meta, GateRef left, GateRe
|
||||
|
||||
GateRef CircuitBuilder::CallBCHandler(GateRef glue, GateRef target, const std::vector<GateRef> &args)
|
||||
{
|
||||
ASSERT(!GetCircuit()->IsOptimizedJSFunctionFrame());
|
||||
const CallSignature *cs = BytecodeStubCSigns::BCHandler();
|
||||
ASSERT(cs->IsBCStub());
|
||||
auto label = GetCurrentLabel();
|
||||
auto depend = label->GetDepend();
|
||||
GateRef result = Call(cs, glue, target, depend, args);
|
||||
GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate());
|
||||
return result;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::CallBuiltin(GateRef glue, GateRef target, const std::vector<GateRef> &args)
|
||||
{
|
||||
ASSERT(!GetCircuit()->IsOptimizedJSFunctionFrame());
|
||||
const CallSignature *cs = BuiltinsStubCSigns::BuiltinsCSign();
|
||||
ASSERT(cs->IsBuiltinsStub());
|
||||
auto label = GetCurrentLabel();
|
||||
auto depend = label->GetDepend();
|
||||
GateRef result = Call(cs, glue, target, depend, args);
|
||||
GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate());
|
||||
return result;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::CallBuiltinWithArgv(GateRef glue, GateRef target, const std::vector<GateRef> &args)
|
||||
{
|
||||
ASSERT(!GetCircuit()->IsOptimizedJSFunctionFrame());
|
||||
const CallSignature *cs = BuiltinsStubCSigns::BuiltinsWithArgvCSign();
|
||||
ASSERT(cs->IsBuiltinsWithArgvStub());
|
||||
auto label = GetCurrentLabel();
|
||||
auto depend = label->GetDepend();
|
||||
GateRef result = Call(cs, glue, target, depend, args);
|
||||
GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate());
|
||||
return result;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::CallBCDebugger(GateRef glue, GateRef target, const std::vector<GateRef> &args)
|
||||
{
|
||||
ASSERT(!GetCircuit()->IsOptimizedJSFunctionFrame());
|
||||
const CallSignature *cs = BytecodeStubCSigns::BCDebuggerHandler();
|
||||
ASSERT(cs->IsBCDebuggerStub());
|
||||
auto label = GetCurrentLabel();
|
||||
auto depend = label->GetDepend();
|
||||
GateRef result = Call(cs, glue, target, depend, args);
|
||||
GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate());
|
||||
return result;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::CallRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args)
|
||||
GateRef CircuitBuilder::CallRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args,
|
||||
GateRef hirGate)
|
||||
{
|
||||
GateRef target = IntPtr(index);
|
||||
const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntime));
|
||||
@ -450,23 +455,29 @@ GateRef CircuitBuilder::CallRuntime(GateRef glue, int index, GateRef depend, con
|
||||
if (depend == Gate::InvalidGateRef) {
|
||||
depend = label->GetDepend();
|
||||
}
|
||||
GateRef result = Call(cs, glue, target, depend, args);
|
||||
GateRef filteredHirGate = Circuit::NullGate();
|
||||
if (GetCircuit()->IsOptimizedJSFunctionFrame()) {
|
||||
ASSERT(hirGate != Circuit::NullGate());
|
||||
filteredHirGate = hirGate;
|
||||
}
|
||||
GateRef result = Call(cs, glue, target, depend, args, filteredHirGate);
|
||||
return result;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::CallRuntimeVarargs(GateRef glue, int index, GateRef argc, GateRef argv)
|
||||
{
|
||||
ASSERT(!GetCircuit()->IsOptimizedJSFunctionFrame());
|
||||
const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntimeWithArgv));
|
||||
GateRef target = IntPtr(index);
|
||||
auto label = GetCurrentLabel();
|
||||
auto depend = label->GetDepend();
|
||||
ASSERT(cs->IsRuntimeVAStub());
|
||||
GateRef result = Call(cs, glue, target, depend, {argc, argv});
|
||||
GateRef result = Call(cs, glue, target, depend, {argc, argv}, Circuit::NullGate());
|
||||
return result;
|
||||
}
|
||||
|
||||
// call operation
|
||||
GateRef CircuitBuilder::CallNGCRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args)
|
||||
GateRef CircuitBuilder::CallNGCRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args,
|
||||
GateRef hirGate)
|
||||
{
|
||||
const CallSignature *cs = RuntimeStubCSigns::Get(index);
|
||||
ASSERT(cs->IsRuntimeNGCStub());
|
||||
@ -475,23 +486,35 @@ GateRef CircuitBuilder::CallNGCRuntime(GateRef glue, int index, GateRef depend,
|
||||
if (depend == Gate::InvalidGateRef) {
|
||||
depend = label->GetDepend();
|
||||
}
|
||||
GateRef result = Call(cs, glue, target, depend, args);
|
||||
GateRef filteredHirGate = Circuit::NullGate();
|
||||
if (GetCircuit()->IsOptimizedJSFunctionFrame() && RuntimeStubCSigns::IsAsmStub(index)) {
|
||||
ASSERT(hirGate != Circuit::NullGate());
|
||||
filteredHirGate = hirGate;
|
||||
}
|
||||
GateRef result = Call(cs, glue, target, depend, args, filteredHirGate);
|
||||
return result;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::CallStub(GateRef glue, int index, const std::vector<GateRef> &args)
|
||||
GateRef CircuitBuilder::CallStub(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args)
|
||||
{
|
||||
const CallSignature *cs = CommonStubCSigns::Get(index);
|
||||
ASSERT(cs->IsCommonStub());
|
||||
GateRef target = IntPtr(index);
|
||||
auto label = GetCurrentLabel();
|
||||
auto depend = label->GetDepend();
|
||||
GateRef result = Call(cs, glue, target, depend, args);
|
||||
GateRef result;
|
||||
if (GetCircuit()->IsOptimizedJSFunctionFrame()) {
|
||||
ASSERT(hirGate != Circuit::NullGate());
|
||||
result = Call(cs, glue, target, depend, args, hirGate);
|
||||
} else {
|
||||
result = Call(cs, glue, target, depend, args, Circuit::NullGate());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::CallBuiltinRuntime(GateRef glue, GateRef depend, const std::vector<GateRef> &args, bool isNew)
|
||||
{
|
||||
ASSERT(!GetCircuit()->IsOptimizedJSFunctionFrame());
|
||||
int index = 0;
|
||||
if (!isNew) {
|
||||
index = static_cast<int>(RTSTUB_ID(PushCallArgsAndDispatchNative));
|
||||
@ -505,16 +528,23 @@ GateRef CircuitBuilder::CallBuiltinRuntime(GateRef glue, GateRef depend, const s
|
||||
if (depend == Gate::InvalidGateRef) {
|
||||
depend = label->GetDepend();
|
||||
}
|
||||
GateRef result = Call(cs, glue, target, depend, args);
|
||||
GateRef result = Call(cs, glue, target, depend, args, Circuit::NullGate());
|
||||
return result;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::Call(const CallSignature* cs, GateRef glue, GateRef target, GateRef depend,
|
||||
const std::vector<GateRef> &args)
|
||||
const std::vector<GateRef> &args, GateRef hirGate)
|
||||
{
|
||||
std::vector<GateRef> inputs { depend, target, glue };
|
||||
inputs.insert(inputs.end(), args.begin(), args.end());
|
||||
auto numValuesIn = args.size() + 2; // 2: target & glue
|
||||
if (GetCircuit()->IsOptimizedJSFunctionFrame() && hirGate != Circuit::NullGate()) {
|
||||
GateRef pcOffset = (acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE) ?
|
||||
Int64(acc_.GetPcOffset(hirGate)) : Int64(0);
|
||||
inputs.emplace_back(pcOffset);
|
||||
numValuesIn += 1;
|
||||
}
|
||||
|
||||
const GateMetaData* meta = nullptr;
|
||||
if (cs->IsCommonStub()) {
|
||||
meta = circuit_->Call(numValuesIn);
|
||||
@ -554,7 +584,7 @@ void CircuitBuilder::Store(VariableType type, GateRef glue, GateRef base, GateRe
|
||||
MachineType::NOVALUE, { depend, value, ptr }, type.GetGateType());
|
||||
label->SetDepend(result);
|
||||
if (type == VariableType::JS_POINTER() || type == VariableType::JS_ANY()) {
|
||||
CallStub(glue, CommonStubCSigns::SetValueWithBarrier, { glue, base, offset, value });
|
||||
CallStub(glue, base, CommonStubCSigns::SetValueWithBarrier, { glue, base, offset, value });
|
||||
}
|
||||
}
|
||||
|
||||
@ -736,15 +766,16 @@ GateRef CircuitBuilder::GetConstPool(GateRef jsFunc)
|
||||
return Load(VariableType::JS_ANY(), method, IntPtr(Method::CONSTANT_POOL_OFFSET));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef jsFunc, GateRef index, ConstPoolType type)
|
||||
GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef jsFunc, GateRef index,
|
||||
ConstPoolType type)
|
||||
{
|
||||
GateRef constPool = GetConstPool(jsFunc);
|
||||
GateRef module = GetModuleFromFunction(jsFunc);
|
||||
return GetObjectFromConstPool(glue, constPool, module, index, type);
|
||||
return GetObjectFromConstPool(glue, hirGate, constPool, module, index, type);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef constPool, GateRef module, GateRef index,
|
||||
ConstPoolType type)
|
||||
GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef constPool, GateRef module,
|
||||
GateRef index, ConstPoolType type)
|
||||
{
|
||||
Label entry(env_);
|
||||
SubCfgEntry(&entry);
|
||||
@ -759,16 +790,16 @@ GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef constPool,
|
||||
{
|
||||
if (type == ConstPoolType::STRING) {
|
||||
result = CallRuntime(glue, RTSTUB_ID(GetStringFromCache), Gate::InvalidGateRef,
|
||||
{ constPool, Int32ToTaggedInt(index) });
|
||||
{ constPool, Int32ToTaggedInt(index) }, hirGate);
|
||||
} else if (type == ConstPoolType::ARRAY_LITERAL) {
|
||||
result = CallRuntime(glue, RTSTUB_ID(GetArrayLiteralFromCache), Gate::InvalidGateRef,
|
||||
{ constPool, Int32ToTaggedInt(index), module });
|
||||
{ constPool, Int32ToTaggedInt(index), module }, hirGate);
|
||||
} else if (type == ConstPoolType::OBJECT_LITERAL) {
|
||||
result = CallRuntime(glue, RTSTUB_ID(GetObjectLiteralFromCache), Gate::InvalidGateRef,
|
||||
{ constPool, Int32ToTaggedInt(index), module });
|
||||
{ constPool, Int32ToTaggedInt(index), module }, hirGate);
|
||||
} else {
|
||||
result = CallRuntime(glue, RTSTUB_ID(GetMethodFromCache), Gate::InvalidGateRef,
|
||||
{ constPool, Int32ToTaggedInt(index) });
|
||||
{ constPool, Int32ToTaggedInt(index) }, hirGate);
|
||||
}
|
||||
Jump(&exit);
|
||||
}
|
||||
@ -780,7 +811,7 @@ GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef constPool,
|
||||
Bind(&isInt);
|
||||
{
|
||||
result = CallRuntime(glue, RTSTUB_ID(GetMethodFromCache), Gate::InvalidGateRef,
|
||||
{ constPool, Int32ToTaggedInt(index) });
|
||||
{ constPool, Int32ToTaggedInt(index) }, hirGate);
|
||||
Jump(&exit);
|
||||
}
|
||||
} else if (type == ConstPoolType::ARRAY_LITERAL) {
|
||||
@ -789,7 +820,7 @@ GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef constPool,
|
||||
Bind(&isAOTLiteralInfo);
|
||||
{
|
||||
result = CallRuntime(glue, RTSTUB_ID(GetArrayLiteralFromCache), Gate::InvalidGateRef,
|
||||
{ constPool, Int32ToTaggedInt(index), module });
|
||||
{ constPool, Int32ToTaggedInt(index), module }, hirGate);
|
||||
Jump(&exit);
|
||||
}
|
||||
} else if (type == ConstPoolType::OBJECT_LITERAL) {
|
||||
@ -798,7 +829,7 @@ GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef constPool,
|
||||
Bind(&isAOTLiteralInfo);
|
||||
{
|
||||
result = CallRuntime(glue, RTSTUB_ID(GetObjectLiteralFromCache), Gate::InvalidGateRef,
|
||||
{ constPool, Int32ToTaggedInt(index), module });
|
||||
{ constPool, Int32ToTaggedInt(index), module }, hirGate);
|
||||
Jump(&exit);
|
||||
}
|
||||
} else {
|
||||
@ -838,6 +869,7 @@ GateRef CircuitBuilder::TryGetHashcodeFromString(GateRef string)
|
||||
|
||||
GateRef CircuitBuilder::GetHashcodeFromString(GateRef glue, GateRef value)
|
||||
{
|
||||
ASSERT(!GetCircuit()->IsOptimizedJSFunctionFrame());
|
||||
Label subentry(env_);
|
||||
SubCfgEntry(&subentry);
|
||||
Label noRawHashcode(env_);
|
||||
@ -847,7 +879,8 @@ GateRef CircuitBuilder::GetHashcodeFromString(GateRef glue, GateRef value)
|
||||
Branch(Int32Equal(*hashcode, Int32(0)), &noRawHashcode, &exit);
|
||||
Bind(&noRawHashcode);
|
||||
{
|
||||
hashcode = GetInt32OfTInt(CallRuntime(glue, RTSTUB_ID(ComputeHashcode), Gate::InvalidGateRef, { value }));
|
||||
hashcode = GetInt32OfTInt(
|
||||
CallRuntime(glue, RTSTUB_ID(ComputeHashcode), Gate::InvalidGateRef, { value }, Circuit::NullGate()));
|
||||
Store(VariableType::INT32(), glue, value, IntPtr(EcmaString::HASHCODE_OFFSET), *hashcode);
|
||||
Jump(&exit);
|
||||
}
|
||||
|
@ -293,12 +293,12 @@ public:
|
||||
GateRef CallBuiltin(GateRef glue, GateRef target, const std::vector<GateRef> &args);
|
||||
GateRef CallBuiltinWithArgv(GateRef glue, GateRef target, const std::vector<GateRef> &args);
|
||||
GateRef CallRuntimeVarargs(GateRef glue, int index, GateRef argc, GateRef argv);
|
||||
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 CallRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args, GateRef hirGate);
|
||||
GateRef CallNGCRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args, GateRef hirGate);
|
||||
GateRef CallStub(GateRef glue, GateRef hirGate, 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);
|
||||
const std::vector<GateRef> &args, GateRef hirGate);
|
||||
|
||||
// memory
|
||||
inline GateRef Load(VariableType type, GateRef base, GateRef offset);
|
||||
@ -469,8 +469,8 @@ public:
|
||||
GateRef value, GateRef attrOffset, VariableType type);
|
||||
void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
GateRef GetConstPool(GateRef jsFunc);
|
||||
GateRef GetObjectFromConstPool(GateRef glue, GateRef jsFunc, GateRef index, ConstPoolType type);
|
||||
GateRef GetObjectFromConstPool(GateRef glue, GateRef constPool, GateRef module, GateRef index,
|
||||
GateRef GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef jsFunc, GateRef index, ConstPoolType type);
|
||||
GateRef GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef constPool, GateRef module, GateRef index,
|
||||
ConstPoolType type);
|
||||
void SetEnvironment(Environment *env)
|
||||
{
|
||||
|
@ -100,6 +100,24 @@ void NotEqualStubBuilder::GenerateCircuit()
|
||||
Return(operationBuilder.NotEqual(glue, x, y));
|
||||
}
|
||||
|
||||
void StrictEqualStubBuilder::GenerateCircuit()
|
||||
{
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef x = TaggedArgument(1);
|
||||
GateRef y = TaggedArgument(2); // 2: 3rd argument
|
||||
OperationsStubBuilder operationBuilder(this);
|
||||
Return(operationBuilder.StrictEqual(glue, x, y));
|
||||
}
|
||||
|
||||
void StrictNotEqualStubBuilder::GenerateCircuit()
|
||||
{
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef x = TaggedArgument(1);
|
||||
GateRef y = TaggedArgument(2); // 2: 3rd argument
|
||||
OperationsStubBuilder operationBuilder(this);
|
||||
Return(operationBuilder.StrictNotEqual(glue, x, y));
|
||||
}
|
||||
|
||||
void LessStubBuilder::GenerateCircuit()
|
||||
{
|
||||
GateRef glue = PtrArgument(0);
|
||||
@ -642,6 +660,30 @@ void ConstructorCheckStubBuilder::GenerateCircuit()
|
||||
Return(ConstructorCheck(glue, ctor, value, thisObj));
|
||||
}
|
||||
|
||||
void CreateEmptyArrayStubBuilder::GenerateCircuit()
|
||||
{
|
||||
GateRef glue = PtrArgument(0);
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
Return(newBuilder.CreateEmptyArray(glue));
|
||||
}
|
||||
|
||||
void CreateArrayWithBufferStubBuilder::GenerateCircuit()
|
||||
{
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef index = Int32Argument(1);
|
||||
GateRef jsFunc = TaggedArgument(2); // 2 : 3rd para
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
Return(newBuilder.CreateArrayWithBuffer(glue, index, jsFunc));
|
||||
}
|
||||
|
||||
void NewJSObjectStubBuilder::GenerateCircuit()
|
||||
{
|
||||
GateRef glue = PtrArgument(0);
|
||||
GateRef hclass = TaggedArgument(1);
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
Return(newBuilder.NewJSObject(glue, hclass));
|
||||
}
|
||||
|
||||
void JsProxyCallInternalStubBuilder::GenerateCircuit()
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
|
@ -28,6 +28,8 @@ namespace panda::ecmascript::kungfu {
|
||||
V(Mod) \
|
||||
V(Equal) \
|
||||
V(NotEqual) \
|
||||
V(StrictEqual) \
|
||||
V(StrictNotEqual) \
|
||||
V(Less) \
|
||||
V(LessEq) \
|
||||
V(Greater) \
|
||||
@ -71,6 +73,9 @@ namespace panda::ecmascript::kungfu {
|
||||
V(GetUnmapedArgs) \
|
||||
V(NewThisObjectChecked) \
|
||||
V(ConstructorCheck) \
|
||||
V(CreateEmptyArray) \
|
||||
V(CreateArrayWithBuffer) \
|
||||
V(NewJSObject) \
|
||||
V(JsProxyCallInternal)
|
||||
|
||||
#define COMMON_STUB_ID_LIST(V) \
|
||||
|
@ -175,11 +175,11 @@ const ChunkVector<char>& GateAccessor::GetConstantString(GateRef gate) const
|
||||
return gatePtr->GetStringMetaData()->GetString();
|
||||
}
|
||||
|
||||
uint32_t GateAccessor::GetBytecodeIndex(GateRef gate) const
|
||||
uint32_t GateAccessor::GetPcOffset(GateRef gate) const
|
||||
{
|
||||
ASSERT(GetOpCode(gate) == OpCode::JS_BYTECODE);
|
||||
Gate *gatePtr = circuit_->LoadGatePtr(gate);
|
||||
return gatePtr->GetJSBytecodeMetaData()->GetBytecodeIndex();
|
||||
return gatePtr->GetJSBytecodeMetaData()->GetPcOffset();
|
||||
}
|
||||
|
||||
EcmaOpcode GateAccessor::GetByteCodeOpcode(GateRef gate) const
|
||||
|
@ -380,7 +380,7 @@ public:
|
||||
TypedUnaryAccessor GetTypedUnOp(GateRef gate) const;
|
||||
uint64_t GetConstantValue(GateRef gate) const;
|
||||
const ChunkVector<char>& GetConstantString(GateRef gate) const;
|
||||
uint32_t GetBytecodeIndex(GateRef gate) const;
|
||||
uint32_t GetPcOffset(GateRef gate) const;
|
||||
EcmaOpcode GetByteCodeOpcode(GateRef gate) const;
|
||||
void Print(GateRef gate) const;
|
||||
void ShortPrint(GateRef gate) const;
|
||||
|
@ -461,9 +461,9 @@ inline std::ostream& operator<<(std::ostream& os, OpCode opcode)
|
||||
|
||||
class JSBytecodeMetaData : public GateMetaData {
|
||||
public:
|
||||
explicit JSBytecodeMetaData(size_t valuesIn, EcmaOpcode opcode, uint32_t bcIndex, GateFlags flags)
|
||||
explicit JSBytecodeMetaData(size_t valuesIn, EcmaOpcode opcode, uint32_t pcOffset, GateFlags flags)
|
||||
: GateMetaData(OpCode::JS_BYTECODE, flags, 1, 1, valuesIn),
|
||||
opcode_(opcode), bcIndex_(bcIndex)
|
||||
opcode_(opcode), pcOffset_(pcOffset)
|
||||
{
|
||||
SetKind(GateMetaData::Kind::JSBYTECODE);
|
||||
}
|
||||
@ -474,9 +474,9 @@ public:
|
||||
return static_cast<const JSBytecodeMetaData*>(meta);
|
||||
}
|
||||
|
||||
uint32_t GetBytecodeIndex() const
|
||||
uint32_t GetPcOffset() const
|
||||
{
|
||||
return bcIndex_;
|
||||
return pcOffset_;
|
||||
}
|
||||
|
||||
EcmaOpcode GetByteCodeOpcode() const
|
||||
@ -485,7 +485,7 @@ public:
|
||||
}
|
||||
private:
|
||||
EcmaOpcode opcode_;
|
||||
uint32_t bcIndex_;
|
||||
uint32_t pcOffset_;
|
||||
};
|
||||
|
||||
class OneParameterMetaData : public GateMetaData {
|
||||
|
@ -108,9 +108,9 @@ public:
|
||||
#undef DECLARE_GATE_META
|
||||
|
||||
explicit GateMetaBuilder(Chunk* chunk);
|
||||
const GateMetaData* JSBytecode(size_t valuesIn, EcmaOpcode opcode, uint32_t bcIndex, GateFlags flags)
|
||||
const GateMetaData* JSBytecode(size_t valuesIn, EcmaOpcode opcode, uint32_t pcOffset, GateFlags flags)
|
||||
{
|
||||
return new (chunk_) JSBytecodeMetaData(valuesIn, opcode, bcIndex, flags);
|
||||
return new (chunk_) JSBytecodeMetaData(valuesIn, opcode, pcOffset, flags);
|
||||
}
|
||||
|
||||
const GateMetaData* TypedBinaryOp(uint64_t value, TypedBinOp binOp)
|
||||
|
@ -399,16 +399,16 @@ DECLARE_ASM_HANDLER(HandleCreateemptyobject)
|
||||
DECLARE_ASM_HANDLER(HandleCreateemptyarrayImm8)
|
||||
{
|
||||
DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc);
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(CreateEmptyArray), {});
|
||||
varAcc = res;
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
varAcc = newBuilder.CreateEmptyArray(glue);
|
||||
DISPATCH_WITH_ACC(CREATEEMPTYARRAY_IMM8);
|
||||
}
|
||||
|
||||
DECLARE_ASM_HANDLER(HandleCreateemptyarrayImm16)
|
||||
{
|
||||
DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc);
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(CreateEmptyArray), {});
|
||||
varAcc = res;
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
varAcc = newBuilder.CreateEmptyArray(glue);
|
||||
DISPATCH_WITH_ACC(CREATEEMPTYARRAY_IMM16);
|
||||
}
|
||||
|
||||
@ -892,55 +892,25 @@ DECLARE_ASM_HANDLER(HandleInstanceofImm8V8)
|
||||
|
||||
DECLARE_ASM_HANDLER(HandleStrictnoteqImm8V8)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc);
|
||||
|
||||
GateRef v0 = ReadInst8_1(pc);
|
||||
GateRef left = GetVregValue(sp, ZExtInt8ToPtr(v0));
|
||||
|
||||
Label strictEqual(env);
|
||||
Label notStrictEqual(env);
|
||||
Label dispatch(env);
|
||||
Branch(FastStrictEqual(glue, left, acc), &strictEqual, ¬StrictEqual);
|
||||
Bind(&strictEqual);
|
||||
{
|
||||
varAcc = TaggedFalse();
|
||||
Jump(&dispatch);
|
||||
}
|
||||
|
||||
Bind(¬StrictEqual);
|
||||
{
|
||||
varAcc = TaggedTrue();
|
||||
Jump(&dispatch);
|
||||
}
|
||||
Bind(&dispatch);
|
||||
OperationsStubBuilder builder(this);
|
||||
varAcc = builder.StrictNotEqual(glue, left, acc);
|
||||
DISPATCH_WITH_ACC(STRICTNOTEQ_IMM8_V8);
|
||||
}
|
||||
|
||||
DECLARE_ASM_HANDLER(HandleStricteqImm8V8)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc);
|
||||
|
||||
GateRef v0 = ReadInst8_1(pc);
|
||||
GateRef left = GetVregValue(sp, ZExtInt8ToPtr(v0));
|
||||
|
||||
Label strictEqual(env);
|
||||
Label notStrictEqual(env);
|
||||
Label dispatch(env);
|
||||
Branch(FastStrictEqual(glue, left, acc), &strictEqual, ¬StrictEqual);
|
||||
Bind(&strictEqual);
|
||||
{
|
||||
varAcc = TaggedTrue();
|
||||
Jump(&dispatch);
|
||||
}
|
||||
|
||||
Bind(¬StrictEqual);
|
||||
{
|
||||
varAcc = TaggedFalse();
|
||||
Jump(&dispatch);
|
||||
}
|
||||
Bind(&dispatch);
|
||||
OperationsStubBuilder builder(this);
|
||||
varAcc = builder.StrictEqual(glue, left, acc);
|
||||
DISPATCH_WITH_ACC(STRICTEQ_IMM8_V8);
|
||||
}
|
||||
|
||||
@ -3780,9 +3750,9 @@ DECLARE_ASM_HANDLER(HandleCreatearraywithbufferImm8Id16)
|
||||
{
|
||||
GateRef imm = ZExtInt16ToInt32(ReadInst16_1(pc));
|
||||
GateRef currentFunc = GetFunctionFromFrame(GetFrame(sp));
|
||||
GateRef module = GetModuleFromFunction(currentFunc);
|
||||
GateRef result = GetArrayLiteralFromConstPool(glue, constpool, imm, module);
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(CreateArrayWithBuffer), { result });
|
||||
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
GateRef res = newBuilder.CreateArrayWithBuffer(glue, imm, currentFunc);
|
||||
CHECK_EXCEPTION_WITH_ACC(res, INT_PTR(CREATEARRAYWITHBUFFER_IMM8_ID16));
|
||||
}
|
||||
|
||||
@ -3790,9 +3760,9 @@ DECLARE_ASM_HANDLER(HandleCreatearraywithbufferImm16Id16)
|
||||
{
|
||||
GateRef imm = ZExtInt16ToInt32(ReadInst16_2(pc));
|
||||
GateRef currentFunc = GetFunctionFromFrame(GetFrame(sp));
|
||||
GateRef module = GetModuleFromFunction(currentFunc);
|
||||
GateRef result = GetArrayLiteralFromConstPool(glue, constpool, imm, module);
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(CreateArrayWithBuffer), { result });
|
||||
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
GateRef res = newBuilder.CreateArrayWithBuffer(glue, imm, currentFunc);
|
||||
CHECK_EXCEPTION_WITH_ACC(res, INT_PTR(CREATEARRAYWITHBUFFER_IMM16_ID16));
|
||||
}
|
||||
|
||||
@ -3800,9 +3770,9 @@ DECLARE_ASM_HANDLER(HandleDeprecatedCreatearraywithbufferPrefImm16)
|
||||
{
|
||||
GateRef imm = ZExtInt16ToInt32(ReadInst16_1(pc));
|
||||
GateRef currentFunc = GetFunctionFromFrame(GetFrame(sp));
|
||||
GateRef module = GetModuleFromFunction(currentFunc);
|
||||
GateRef result = GetArrayLiteralFromConstPool(glue, constpool, imm, module);
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(CreateArrayWithBuffer), { result });
|
||||
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
GateRef res = newBuilder.CreateArrayWithBuffer(glue, imm, currentFunc);
|
||||
CHECK_EXCEPTION_WITH_ACC(res, INT_PTR(DEPRECATED_CREATEARRAYWITHBUFFER_PREF_IMM16));
|
||||
}
|
||||
|
||||
|
@ -512,16 +512,21 @@ LLVMValueRef LLVMIRBuilder::GetFunctionFromGlobalValue([[maybe_unused]] LLVMValu
|
||||
return callee;
|
||||
}
|
||||
|
||||
bool LLVMIRBuilder::IsInterpreted()
|
||||
bool LLVMIRBuilder::IsInterpreted() const
|
||||
{
|
||||
return circuit_->GetFrameType() == FrameType::ASM_INTERPRETER_FRAME;
|
||||
}
|
||||
|
||||
bool LLVMIRBuilder::IsOptimized()
|
||||
bool LLVMIRBuilder::IsOptimized() const
|
||||
{
|
||||
return circuit_->GetFrameType() == FrameType::OPTIMIZED_FRAME;
|
||||
}
|
||||
|
||||
bool LLVMIRBuilder::IsOptimizedJSFunction() const
|
||||
{
|
||||
return circuit_->GetFrameType() == FrameType::OPTIMIZED_JS_FUNCTION_FRAME;
|
||||
}
|
||||
|
||||
void LLVMIRBuilder::VisitRuntimeCall(GateRef gate, const std::vector<GateRef> &inList)
|
||||
{
|
||||
ASSERT(llvmModule_ != nullptr);
|
||||
@ -532,13 +537,19 @@ void LLVMIRBuilder::VisitRuntimeCall(GateRef gate, const std::vector<GateRef> &i
|
||||
LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, glue, rtoffset, "");
|
||||
const CallSignature *signature = RuntimeStubCSigns::Get(std::get<RuntimeStubCSigns::ID>(stubId));
|
||||
|
||||
auto kind = GetCallExceptionKind(stubIndex, OpCode::RUNTIME_CALL);
|
||||
|
||||
size_t actualNumArgs = 0;
|
||||
LLVMValueRef pcOffset = LLVMConstInt(LLVMInt32Type(), 0, 0);
|
||||
ComputeArgCountAndPCOffset(actualNumArgs, pcOffset, inList, kind);
|
||||
|
||||
std::vector<LLVMValueRef> params;
|
||||
params.push_back(glue); // glue
|
||||
const int index = static_cast<int>(acc_.GetConstantValue(inList[static_cast<int>(CallInputs::TARGET)]));
|
||||
params.push_back(LLVMConstInt(LLVMInt64Type(), index, 0)); // target
|
||||
params.push_back(LLVMConstInt(LLVMInt64Type(),
|
||||
inList.size() - static_cast<size_t>(CallInputs::FIRST_PARAMETER), 0)); // argc
|
||||
for (size_t paraIdx = static_cast<size_t>(CallInputs::FIRST_PARAMETER); paraIdx < inList.size(); ++paraIdx) {
|
||||
actualNumArgs - static_cast<size_t>(CallInputs::FIRST_PARAMETER), 0)); // argc
|
||||
for (size_t paraIdx = static_cast<size_t>(CallInputs::FIRST_PARAMETER); paraIdx < actualNumArgs; ++paraIdx) {
|
||||
GateRef gateTmp = inList[paraIdx];
|
||||
params.push_back(gate2LValue_[gateTmp]);
|
||||
}
|
||||
@ -547,7 +558,18 @@ void LLVMIRBuilder::VisitRuntimeCall(GateRef gate, const std::vector<GateRef> &i
|
||||
std::string targetName = RuntimeStubCSigns::GetRTName(index);
|
||||
LLVMValueRef callee = GetFunction(glue, signature, rtbaseoffset, targetName);
|
||||
callee = LLVMBuildPointerCast(builder_, callee, LLVMPointerType(funcType, 0), "");
|
||||
LLVMValueRef runtimeCall = LLVMBuildCall2(builder_, funcType, callee, params.data(), inList.size(), "");
|
||||
LLVMValueRef runtimeCall = nullptr;
|
||||
if (kind == CallExceptionKind::HAS_PC_OFFSET) {
|
||||
std::vector<LLVMValueRef> values;
|
||||
auto pcIndex = LLVMConstInt(LLVMInt64Type(), static_cast<int>(SpecVregIndex::PC_OFFSET_INDEX), 1);
|
||||
values.push_back(pcIndex);
|
||||
values.push_back(pcOffset);
|
||||
runtimeCall = LLVMBuildCall3(builder_, funcType, callee, params.data(), actualNumArgs,
|
||||
"", values.data(), values.size());
|
||||
} else {
|
||||
runtimeCall = LLVMBuildCall2(builder_, funcType, callee, params.data(), actualNumArgs, "");
|
||||
}
|
||||
|
||||
if (!compCfg_->Is32Bit()) { // Arm32 not support webkit jscc calling convention
|
||||
LLVMSetInstructionCallConv(runtimeCall, LLVMWebKitJSCallConv);
|
||||
}
|
||||
@ -686,12 +708,13 @@ LLVMValueRef LLVMIRBuilder::GetBuiltinsStubOffset(LLVMValueRef glue)
|
||||
return LLVMConstInt(glueType, JSThread::GlueData::GetBuiltinsStubEntriesOffset(compCfg_->Is32Bit()), 0);
|
||||
}
|
||||
|
||||
void LLVMIRBuilder::ComputeArgCountAndBCOffset(size_t &actualNumArgs, LLVMValueRef &bcOffset,
|
||||
void LLVMIRBuilder::ComputeArgCountAndPCOffset(size_t &actualNumArgs, LLVMValueRef &pcOffset,
|
||||
const std::vector<GateRef> &inList, CallExceptionKind kind)
|
||||
{
|
||||
if (kind == CallExceptionKind::HAS_BC_OFFSET) {
|
||||
if (kind == CallExceptionKind::HAS_PC_OFFSET) {
|
||||
actualNumArgs = inList.size() - 1;
|
||||
bcOffset = gate2LValue_[inList[actualNumArgs]];
|
||||
pcOffset = gate2LValue_[inList[actualNumArgs]];
|
||||
ASSERT(acc_.GetOpCode(inList[actualNumArgs]) == OpCode::CONSTANT);
|
||||
} else {
|
||||
actualNumArgs = inList.size();
|
||||
}
|
||||
@ -699,9 +722,11 @@ void LLVMIRBuilder::ComputeArgCountAndBCOffset(size_t &actualNumArgs, LLVMValueR
|
||||
|
||||
LLVMIRBuilder::CallExceptionKind LLVMIRBuilder::GetCallExceptionKind(size_t index, OpCode op) const
|
||||
{
|
||||
bool hasBcOffset = (callConv_ == CallSignature::CallConv::WebKitJSCallConv && op == OpCode::NOGC_RUNTIME_CALL &&
|
||||
index == RTSTUB_ID(JSCall));
|
||||
return hasBcOffset ? CallExceptionKind::HAS_BC_OFFSET : CallExceptionKind::NO_BC_OFFSET;
|
||||
bool hasPcOffset = IsOptimizedJSFunction() &&
|
||||
((op == OpCode::NOGC_RUNTIME_CALL && (kungfu::RuntimeStubCSigns::IsAsmStub(index))) ||
|
||||
(op == OpCode::CALL) ||
|
||||
(op == OpCode::RUNTIME_CALL));
|
||||
return hasPcOffset ? CallExceptionKind::HAS_PC_OFFSET : CallExceptionKind::NO_PC_OFFSET;
|
||||
}
|
||||
|
||||
void LLVMIRBuilder::UpdateLeaveFrame(LLVMValueRef glue)
|
||||
@ -724,13 +749,14 @@ void LLVMIRBuilder::VisitCall(GateRef gate, const std::vector<GateRef> &inList,
|
||||
LLVMValueRef rtoffset;
|
||||
LLVMValueRef rtbaseoffset;
|
||||
LLVMValueRef callee;
|
||||
CallExceptionKind kind = CallExceptionKind::NO_BC_OFFSET;
|
||||
CallExceptionKind kind = CallExceptionKind::NO_PC_OFFSET;
|
||||
if (op == OpCode::CALL) {
|
||||
const size_t index = acc_.GetConstantValue(inList[targetIndex]);
|
||||
calleeDescriptor = CommonStubCSigns::Get(index);
|
||||
rtoffset = GetCoStubOffset(glue, index);
|
||||
rtbaseoffset = LLVMBuildAdd(builder_, glue, rtoffset, "");
|
||||
callee = GetFunction(glue, calleeDescriptor, rtbaseoffset);
|
||||
kind = GetCallExceptionKind(index, op);
|
||||
} else if (op == OpCode::NOGC_RUNTIME_CALL) {
|
||||
UpdateLeaveFrame(glue);
|
||||
const size_t index = acc_.GetConstantValue(inList[targetIndex]);
|
||||
@ -765,8 +791,8 @@ void LLVMIRBuilder::VisitCall(GateRef gate, const std::vector<GateRef> &inList,
|
||||
|
||||
int extraParameterCnt = 0;
|
||||
size_t actualNumArgs = 0;
|
||||
LLVMValueRef bcOffset = LLVMConstInt(LLVMInt32Type(), 0, 0);
|
||||
ComputeArgCountAndBCOffset(actualNumArgs, bcOffset, inList, kind);
|
||||
LLVMValueRef pcOffset = LLVMConstInt(LLVMInt32Type(), 0, 0);
|
||||
ComputeArgCountAndPCOffset(actualNumArgs, pcOffset, inList, kind);
|
||||
|
||||
// then push the actual parameter for js function call
|
||||
for (size_t paraIdx = firstArg + 1; paraIdx < actualNumArgs; ++paraIdx) {
|
||||
@ -790,11 +816,11 @@ void LLVMIRBuilder::VisitCall(GateRef gate, const std::vector<GateRef> &inList,
|
||||
LLVMValueRef call = nullptr;
|
||||
LLVMTypeRef funcType = llvmModule_->GenerateFuncType(params, calleeDescriptor);
|
||||
callee = LLVMBuildPointerCast(builder_, callee, LLVMPointerType(funcType, 0), "");
|
||||
if (kind == CallExceptionKind::HAS_BC_OFFSET) {
|
||||
if (kind == CallExceptionKind::HAS_PC_OFFSET) {
|
||||
std::vector<LLVMValueRef> values;
|
||||
auto bcIndex = LLVMConstInt(LLVMInt64Type(), static_cast<int>(SpecVregIndex::BC_OFFSET_INDEX), 1);
|
||||
values.push_back(bcIndex);
|
||||
values.push_back(bcOffset);
|
||||
auto pcIndex = LLVMConstInt(LLVMInt64Type(), static_cast<int>(SpecVregIndex::PC_OFFSET_INDEX), 1);
|
||||
values.push_back(pcIndex);
|
||||
values.push_back(pcOffset);
|
||||
call = LLVMBuildCall3(builder_, funcType, callee, params.data(), actualNumArgs - firstArg + extraParameterCnt,
|
||||
"", values.data(), values.size());
|
||||
} else {
|
||||
|
@ -302,8 +302,9 @@ private:
|
||||
const std::string &realName = "") const;
|
||||
LLVMValueRef GetFunctionFromGlobalValue(LLVMValueRef glue, const CallSignature *signature,
|
||||
LLVMValueRef reloc) const;
|
||||
bool IsInterpreted();
|
||||
bool IsOptimized();
|
||||
bool IsInterpreted() const;
|
||||
bool IsOptimized() const;
|
||||
bool IsOptimizedJSFunction() const;
|
||||
void SetGCLeafFunction(LLVMValueRef call);
|
||||
void SetCallConvAttr(const CallSignature *calleeDescriptor, LLVMValueRef call);
|
||||
bool IsHeapPointerType(LLVMTypeRef valueType);
|
||||
@ -316,8 +317,8 @@ private:
|
||||
FIRST_PARAMETER
|
||||
};
|
||||
enum class CallExceptionKind : bool {
|
||||
HAS_BC_OFFSET = true,
|
||||
NO_BC_OFFSET = false
|
||||
HAS_PC_OFFSET = true,
|
||||
NO_PC_OFFSET = false
|
||||
};
|
||||
LLVMRealPredicate ConvertLLVMPredicateFromFCMP(FCmpCondition cond);
|
||||
LLVMIntPredicate ConvertLLVMPredicateFromICMP(ICmpCondition cond);
|
||||
@ -330,7 +331,7 @@ private:
|
||||
LLVMValueRef GetBuiltinsStubOffset(LLVMValueRef glue);
|
||||
LLVMValueRef GetBaseOffset(GateRef gate, LLVMValueRef glue);
|
||||
CallExceptionKind GetCallExceptionKind(size_t index, OpCode op) const;
|
||||
void ComputeArgCountAndBCOffset(size_t &actualNumArgs, LLVMValueRef &bcOffset, const std::vector<GateRef> &inList,
|
||||
void ComputeArgCountAndPCOffset(size_t &actualNumArgs, LLVMValueRef &pcOffset, const std::vector<GateRef> &inList,
|
||||
CallExceptionKind kind);
|
||||
void SaveLexicalEnvOnOptJSFuncFrame(LLVMValueRef value);
|
||||
void SaveJSFuncOnOptJSFuncFrame(LLVMValueRef value);
|
||||
|
@ -105,6 +105,23 @@ void NewObjectStubBuilder::NewJSObject(Variable *result, Label *exit, GateRef hc
|
||||
}
|
||||
}
|
||||
|
||||
GateRef NewObjectStubBuilder::NewJSObject(GateRef glue, GateRef hclass)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
env->SubCfgEntry(&entry);
|
||||
Label exit(env);
|
||||
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
|
||||
SetGlue(glue);
|
||||
NewJSObject(&result, &exit, hclass);
|
||||
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NewObjectStubBuilder::NewArgumentsList(Variable *result, Label *exit,
|
||||
GateRef sp, GateRef startIdx, GateRef numArgs)
|
||||
{
|
||||
@ -394,4 +411,58 @@ GateRef NewObjectStubBuilder::NewThisObjectChecked(GateRef glue, GateRef ctor)
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef NewObjectStubBuilder::CreateEmptyArray(GateRef glue)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
env->SubCfgEntry(&entry);
|
||||
Label exit(env);
|
||||
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
|
||||
|
||||
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);
|
||||
auto hclass = Load(VariableType::JS_POINTER(), arrayFunc, IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
|
||||
GateRef size = GetObjectSizeFromHClass(hclass);
|
||||
auto emptyArray = GetGlobalConstantValue(VariableType::JS_POINTER(), glue, ConstantIndex::EMPTY_ARRAY_OBJECT_INDEX);
|
||||
|
||||
SetParameters(glue, size);
|
||||
NewJSArrayLiteral(&result, &exit, RegionSpaceFlag::IN_YOUNG_SPACE, emptyArray, hclass, true);
|
||||
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef NewObjectStubBuilder::CreateArrayWithBuffer(GateRef glue, GateRef index, GateRef jsFunc)
|
||||
{
|
||||
(void)glue;
|
||||
(void)index;
|
||||
(void)jsFunc;
|
||||
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
env->SubCfgEntry(&entry);
|
||||
Label exit(env);
|
||||
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
|
||||
GateRef method = GetMethodFromFunction(jsFunc);
|
||||
GateRef constPool = Load(VariableType::JS_ANY(), method, IntPtr(Method::CONSTANT_POOL_OFFSET));
|
||||
GateRef module = GetModuleFromFunction(jsFunc);
|
||||
|
||||
auto obj = GetArrayLiteralFromConstPool(glue, constPool, index, module);
|
||||
auto hclass = LoadHClass(obj);
|
||||
GateRef size = GetObjectSizeFromHClass(hclass);
|
||||
|
||||
SetParameters(glue, size);
|
||||
NewJSArrayLiteral(&result, &exit, RegionSpaceFlag::IN_YOUNG_SPACE, obj, hclass, false);
|
||||
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -35,13 +35,14 @@ public:
|
||||
size_ = size;
|
||||
}
|
||||
|
||||
void SetGule(GateRef glue)
|
||||
void SetGlue(GateRef glue)
|
||||
{
|
||||
glue_ = glue;
|
||||
}
|
||||
|
||||
void NewLexicalEnv(Variable *result, Label *exit, GateRef numSlots, GateRef parent);
|
||||
void NewJSObject(Variable *result, Label *exit, GateRef hclass);
|
||||
GateRef NewJSObject(GateRef glue, GateRef hclass);
|
||||
void NewArgumentsList(Variable *result, Label *exit, GateRef sp, GateRef startIdx, GateRef numArgs);
|
||||
void NewArgumentsObj(Variable *result, Label *exit, GateRef argumentsList, GateRef numArgs);
|
||||
void AllocLineStringObject(Variable *result, Label *exit, GateRef length, bool compressed);
|
||||
@ -51,6 +52,9 @@ public:
|
||||
void InitializeWithSpeicalValue(Label *exit, GateRef object, GateRef value, GateRef start, GateRef end);
|
||||
GateRef FastNewThisObject(GateRef glue, GateRef ctor);
|
||||
GateRef NewThisObjectChecked(GateRef glue, GateRef ctor);
|
||||
GateRef CreateEmptyArray(GateRef glue);
|
||||
GateRef CreateArrayWithBuffer(GateRef glue, GateRef index, GateRef jsFunc);
|
||||
|
||||
private:
|
||||
void AllocateInYoung(Variable *result, Label *exit);
|
||||
void InitializeTaggedArrayWithSpeicalValue(Label *exit,
|
||||
|
@ -81,6 +81,46 @@ GateRef OperationsStubBuilder::NotEqual(GateRef glue, GateRef left, GateRef righ
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef OperationsStubBuilder::StrictEqual(GateRef glue, GateRef left, GateRef right)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
env->SubCfgEntry(&entry);
|
||||
Label exit(env);
|
||||
Label notStrictEqual(env);
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), TaggedTrue());
|
||||
Branch(FastStrictEqual(glue, left, right), &exit, ¬StrictEqual);
|
||||
Bind(¬StrictEqual);
|
||||
{
|
||||
result = TaggedFalse();
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef OperationsStubBuilder::StrictNotEqual(GateRef glue, GateRef left, GateRef right)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entry(env);
|
||||
env->SubCfgEntry(&entry);
|
||||
Label exit(env);
|
||||
Label strictEqual(env);
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), TaggedTrue());
|
||||
Branch(FastStrictEqual(glue, left, right), &strictEqual, &exit);
|
||||
Bind(&strictEqual);
|
||||
{
|
||||
result = TaggedFalse();
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef OperationsStubBuilder::Less(GateRef glue, GateRef left, GateRef right)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
// binary op
|
||||
GateRef Equal(GateRef glue, GateRef left, GateRef right);
|
||||
GateRef NotEqual(GateRef glue, GateRef left, GateRef right);
|
||||
GateRef StrictEqual(GateRef glue, GateRef left, GateRef right);
|
||||
GateRef StrictNotEqual(GateRef glue, GateRef left, GateRef right);
|
||||
GateRef Less(GateRef glue, GateRef left, GateRef right);
|
||||
GateRef LessEq(GateRef glue, GateRef left, GateRef right);
|
||||
GateRef Greater(GateRef glue, GateRef left, GateRef right);
|
||||
|
@ -89,6 +89,7 @@ bool PassManager::Compile(const std::string &fileName, AOTFileGenerator &generat
|
||||
}
|
||||
|
||||
Circuit circuit(vm_->GetNativeAreaAllocator(), cmpCfg->Is64Bit());
|
||||
circuit.SetFrameType(FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
|
||||
BytecodeCircuitBuilder builder(jsPandaFile, methodLiteral, methodPCInfo, tsManager, &circuit,
|
||||
info.GetByteCodes(), hasTypes, enableMethodLog && log_->OutputCIR(),
|
||||
EnableTypeLowering(), fullName, recordName);
|
||||
|
@ -37,8 +37,20 @@ public:
|
||||
NUM_OF_RTSTUBS_WITHOUT_GC
|
||||
};
|
||||
|
||||
enum AsmStubID {
|
||||
#define DEF_RUNTIME_STUB_ID(name) ASM_STUB_ID_##name,
|
||||
RUNTIME_ASM_STUB_LIST(DEF_RUNTIME_STUB_ID)
|
||||
#undef DEF_RUNTIME_STUB_ID
|
||||
NUM_OF_ASM_STUBS
|
||||
};
|
||||
|
||||
static void Initialize();
|
||||
|
||||
static bool IsAsmStub(uint32_t index)
|
||||
{
|
||||
return index < AsmStubID::NUM_OF_ASM_STUBS;
|
||||
}
|
||||
|
||||
static void GetASMCSigns(std::vector<const CallSignature*>& callSigns);
|
||||
|
||||
static const CallSignature *Get(size_t index)
|
||||
@ -63,6 +75,10 @@ RUNTIME_STUB_LIST(DEF_STUB_NAME)
|
||||
private:
|
||||
static CallSignature callSigns_[NUM_OF_RTSTUBS_WITHOUT_GC];
|
||||
};
|
||||
static_assert(static_cast<int>(kungfu::RuntimeStubCSigns::ID_CallRuntime) ==
|
||||
static_cast<int>(kungfu::RuntimeStubCSigns::ASM_STUB_ID_CallRuntime));
|
||||
static_assert(static_cast<int>(kungfu::RuntimeStubCSigns::ID_AsmInterpreterEntry) ==
|
||||
static_cast<int>(kungfu::RuntimeStubCSigns::ASM_STUB_ID_AsmInterpreterEntry));
|
||||
#define RTSTUB_ID(name) kungfu::RuntimeStubCSigns::ID_##name
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
#endif // ECMASCRIPT_COMPILER_RT_CALL_SIGNATURE_H
|
File diff suppressed because it is too large
Load Diff
@ -280,8 +280,8 @@ private:
|
||||
void LowerDefineMethod(GateRef gate, GateRef jsFunc);
|
||||
void LowerGetUnmappedArgs(GateRef gate, GateRef actualArgc);
|
||||
void LowerCopyRestArgs(GateRef gate, GateRef actualArgc);
|
||||
GateRef LowerCallRuntime(int index, const std::vector<GateRef> &args, bool useLabel = false);
|
||||
GateRef LowerCallNGCRuntime(int index, const std::vector<GateRef> &args, bool useLabel = false);
|
||||
GateRef LowerCallRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel = false);
|
||||
GateRef LowerCallNGCRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel = false);
|
||||
int32_t ComputeCallArgc(GateRef gate, EcmaOpcode op);
|
||||
void LowerCreateAsyncGeneratorObj(GateRef gate);
|
||||
void LowerAsyncGeneratorResolve(GateRef gate);
|
||||
|
@ -194,7 +194,7 @@ inline void StubBuilder::Bind(Label *label)
|
||||
inline GateRef StubBuilder::CallRuntime(GateRef glue, int index, const std::initializer_list<GateRef>& args)
|
||||
{
|
||||
SavePcIfNeeded(glue);
|
||||
GateRef result = env_->GetBuilder()->CallRuntime(glue, index, Gate::InvalidGateRef, args);
|
||||
GateRef result = env_->GetBuilder()->CallRuntime(glue, index, Gate::InvalidGateRef, args, Circuit::NullGate());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -207,14 +207,14 @@ inline GateRef StubBuilder::CallRuntime(GateRef glue, int index, GateRef argc, G
|
||||
|
||||
inline GateRef StubBuilder::CallNGCRuntime(GateRef glue, int index, const std::initializer_list<GateRef>& args)
|
||||
{
|
||||
GateRef result = env_->GetBuilder()->CallNGCRuntime(glue, index, Gate::InvalidGateRef, args);
|
||||
GateRef result = env_->GetBuilder()->CallNGCRuntime(glue, index, Gate::InvalidGateRef, args, Circuit::NullGate());
|
||||
return result;
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::CallStub(GateRef glue, int index, const std::initializer_list<GateRef>& args)
|
||||
{
|
||||
SavePcIfNeeded(glue);
|
||||
GateRef result = env_->GetBuilder()->CallStub(glue, index, args);
|
||||
GateRef result = env_->GetBuilder()->CallStub(glue, Circuit::NullGate(), index, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2021,6 +2021,16 @@ inline GateRef StubBuilder::GetGlobalObject(GateRef glue)
|
||||
return Load(VariableType::JS_ANY(), glue, offset);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetMethodFromFunction(GateRef function)
|
||||
{
|
||||
return env_->GetBuilder()->GetMethodFromFunction(function);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetModuleFromFunction(GateRef function)
|
||||
{
|
||||
return env_->GetBuilder()->GetModuleFromFunction(function);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetEntryIndexOfGlobalDictionary(GateRef entry)
|
||||
{
|
||||
return Int32Add(Int32(OrderTaggedHashTable<GlobalDictionary>::TABLE_HEADER_SIZE),
|
||||
|
@ -4331,23 +4331,29 @@ GateRef StubBuilder::GetGlobalOwnProperty(GateRef glue, GateRef receiver, GateRe
|
||||
GateRef StubBuilder::GetStringFromConstPool(GateRef glue, GateRef constpool, GateRef index)
|
||||
{
|
||||
GateRef module = Circuit::NullGate();
|
||||
return env_->GetBuilder()->GetObjectFromConstPool(glue, constpool, module, index, ConstPoolType::STRING);
|
||||
GateRef hirGate = Circuit::NullGate();
|
||||
return env_->GetBuilder()->GetObjectFromConstPool(glue, hirGate, constpool, module, index, ConstPoolType::STRING);
|
||||
}
|
||||
|
||||
GateRef StubBuilder::GetMethodFromConstPool(GateRef glue, GateRef constpool, GateRef index)
|
||||
{
|
||||
GateRef module = Circuit::NullGate();
|
||||
return env_->GetBuilder()->GetObjectFromConstPool(glue, constpool, module, index, ConstPoolType::METHOD);
|
||||
GateRef hirGate = Circuit::NullGate();
|
||||
return env_->GetBuilder()->GetObjectFromConstPool(glue, hirGate, constpool, module, index, ConstPoolType::METHOD);
|
||||
}
|
||||
|
||||
GateRef StubBuilder::GetArrayLiteralFromConstPool(GateRef glue, GateRef constpool, GateRef index, GateRef module)
|
||||
{
|
||||
return env_->GetBuilder()->GetObjectFromConstPool(glue, constpool, module, index, ConstPoolType::ARRAY_LITERAL);
|
||||
GateRef hirGate = Circuit::NullGate();
|
||||
return env_->GetBuilder()->GetObjectFromConstPool(glue, hirGate, constpool, module, index,
|
||||
ConstPoolType::ARRAY_LITERAL);
|
||||
}
|
||||
|
||||
GateRef StubBuilder::GetObjectLiteralFromConstPool(GateRef glue, GateRef constpool, GateRef index, GateRef module)
|
||||
{
|
||||
return env_->GetBuilder()->GetObjectFromConstPool(glue, constpool, module, index, ConstPoolType::OBJECT_LITERAL);
|
||||
GateRef hirGate = Circuit::NullGate();
|
||||
return env_->GetBuilder()->GetObjectFromConstPool(glue, hirGate, constpool, module, index,
|
||||
ConstPoolType::OBJECT_LITERAL);
|
||||
}
|
||||
|
||||
GateRef StubBuilder::JSAPIContainerGet(GateRef glue, GateRef receiver, GateRef index)
|
||||
|
@ -503,6 +503,8 @@ public:
|
||||
inline GateRef GetBuiltinId(GateRef method);
|
||||
void SetLexicalEnvToFunction(GateRef glue, GateRef object, GateRef lexicalEnv);
|
||||
GateRef GetGlobalObject(GateRef glue);
|
||||
GateRef GetMethodFromFunction(GateRef function);
|
||||
GateRef GetModuleFromFunction(GateRef function);
|
||||
GateRef GetEntryIndexOfGlobalDictionary(GateRef entry);
|
||||
GateRef GetBoxFromGlobalDictionary(GateRef object, GateRef entry);
|
||||
GateRef GetValueFromGlobalDictionary(GateRef object, GateRef entry);
|
||||
|
@ -33,13 +33,13 @@ void FooAOTStubBuilder::GenerateCircuit()
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
GateRef pcOffset = Int32(1);
|
||||
(void)calltarget;
|
||||
GateRef barIndex = IntToTaggedInt(Int32(CommonStubCSigns::BarAOT));
|
||||
GateRef numArgs = IntToTaggedInt(Int32(2));
|
||||
GateRef barfunc = CallRuntime(glue, RTSTUB_ID(DefineAotFunc), {barIndex, numArgs});
|
||||
GateRef result =
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, barfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, barfunc, newtarget, thisObj, a, b, pcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
@ -67,13 +67,13 @@ void Foo1AOTStubBuilder::GenerateCircuit()
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
GateRef pcOffset = Int32(1);
|
||||
(void)calltarget;
|
||||
GateRef barIndex = IntToTaggedInt(Int32(CommonStubCSigns::Bar1AOT));
|
||||
GateRef numArgs = IntToTaggedInt(Int32(3));
|
||||
GateRef barfunc = CallRuntime(glue, RTSTUB_ID(DefineAotFunc), {barIndex, numArgs});
|
||||
GateRef result =
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, barfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, barfunc, newtarget, thisObj, a, b, pcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
@ -108,14 +108,14 @@ void Foo2AOTStubBuilder::GenerateCircuit()
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
GateRef pcOffset = Int32(1);
|
||||
(void)calltarget;
|
||||
GateRef actualArgC = Int64Add(argc, Int64(1));
|
||||
GateRef barIndex = IntToTaggedInt(Int32(CommonStubCSigns::BarAOT));
|
||||
GateRef numArgs = IntToTaggedInt(Int32(2));
|
||||
GateRef barfunc = CallRuntime(glue, RTSTUB_ID(DefineAotFunc), {barIndex, numArgs});
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, actualArgC, barfunc, newtarget, thisObj,
|
||||
a, b, Undefined(), bcOffset});
|
||||
a, b, Undefined(), pcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
@ -129,12 +129,12 @@ void FooNativeAOTStubBuilder::GenerateCircuit()
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
GateRef pcOffset = Int32(1);
|
||||
(void)calltarget;
|
||||
GateRef actualArgC = Int64Add(argc, Int64(1));
|
||||
GateRef printfunc = CallRuntime(glue, RTSTUB_ID(GetPrintFunc), {});
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, actualArgC, printfunc, newtarget, thisObj,
|
||||
a, b, Undefined(), bcOffset});
|
||||
a, b, Undefined(), pcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
@ -149,16 +149,16 @@ void FooBoundAOTStubBuilder::GenerateCircuit()
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bindArguments = IntToTaggedInt(Int32(37));
|
||||
GateRef bcOffset = Int32(1);
|
||||
GateRef pcOffset = Int32(1);
|
||||
(void)calltarget;
|
||||
GateRef numArgs = IntToTaggedInt(Int32(2));
|
||||
GateRef barIndex = IntToTaggedInt(Int32(CommonStubCSigns::BarAOT));
|
||||
GateRef barfunc = CallRuntime(glue, RTSTUB_ID(DefineAotFunc), {barIndex, numArgs});
|
||||
GateRef bindfunc = CallRuntime(glue, RTSTUB_ID(GetBindFunc), {barfunc});
|
||||
GateRef newjsfunc = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, Int64(5), bindfunc, newtarget, barfunc,
|
||||
Int64(0x02), bindArguments, bcOffset});
|
||||
Int64(0x02), bindArguments, pcOffset});
|
||||
GateRef result = CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, newjsfunc, newtarget, thisObj,
|
||||
a, b, bcOffset});
|
||||
a, b, pcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ void FooProxyAOTStubBuilder::GenerateCircuit()
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
GateRef pcOffset = Int32(1);
|
||||
|
||||
GateRef barIndex = IntToTaggedInt(Int32(CommonStubCSigns::BarAOT));
|
||||
GateRef numArgs = IntToTaggedInt(Int32(2));
|
||||
@ -180,7 +180,7 @@ void FooProxyAOTStubBuilder::GenerateCircuit()
|
||||
|
||||
GateRef proxyfunc = CallRuntime(glue, RTSTUB_ID(DefineProxyFunc), {barfunc});
|
||||
GateRef result =
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, proxyfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, proxyfunc, newtarget, thisObj, a, b, pcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ void FooProxy2AOTStubBuilder::GenerateCircuit()
|
||||
GateRef thisObj = TaggedArgument(5);
|
||||
GateRef a = TaggedArgument(6);
|
||||
GateRef b = TaggedArgument(7);
|
||||
GateRef bcOffset = Int32(1);
|
||||
GateRef pcOffset = Int32(1);
|
||||
|
||||
GateRef barIndex = IntToTaggedInt(Int32(CommonStubCSigns::Bar2AOT));
|
||||
GateRef numArgs = IntToTaggedInt(Int32(2));
|
||||
@ -203,7 +203,7 @@ void FooProxy2AOTStubBuilder::GenerateCircuit()
|
||||
|
||||
GateRef proxyfunc = CallRuntime(glue, RTSTUB_ID(DefineProxyFunc2), {barfunc, proxyHandler});
|
||||
GateRef result =
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, proxyfunc, newtarget, thisObj, a, b, bcOffset});
|
||||
CallNGCRuntime(glue, RTSTUB_ID(JSCall), {glue, env, argc, proxyfunc, newtarget, thisObj, a, b, pcOffset});
|
||||
Return(result);
|
||||
}
|
||||
|
||||
|
@ -855,8 +855,6 @@ void TSTypeLowering::LowerTypedNewObjRange(GateRef gate)
|
||||
for (size_t i = 1; i < range; ++i) { // 1:skip ctor
|
||||
args.emplace_back(acc_.GetValueIn(gate, i));
|
||||
}
|
||||
GateRef bcIndex = builder_.Int64(acc_.GetBytecodeIndex(gate));
|
||||
args.emplace_back(bcIndex);
|
||||
|
||||
GateRef constructGate = builder_.Construct(args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), constructGate);
|
||||
@ -888,8 +886,6 @@ void TSTypeLowering::LowerTypedSuperCall(GateRef gate, GateRef ctor, GateRef new
|
||||
for (size_t i = 0; i < range; ++i) {
|
||||
args.emplace_back(acc_.GetValueIn(gate, i));
|
||||
}
|
||||
GateRef bcIndex = builder_.Int64(acc_.GetBytecodeIndex(gate));
|
||||
args.emplace_back(bcIndex);
|
||||
|
||||
GateRef constructGate = builder_.Construct(args);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), constructGate);
|
||||
@ -955,7 +951,7 @@ void TSTypeLowering::AddProfiling(GateRef gate)
|
||||
GateRef mode =
|
||||
builder_.Int32ToTaggedInt(builder_.Int32(static_cast<int32_t>(OptCodeProfiler::Mode::TYPED_PATH)));
|
||||
GateRef profiling = builder_.CallRuntime(glue_, RTSTUB_ID(ProfileOptimizedCode), acc_.GetDep(current),
|
||||
{constOpcode, mode});
|
||||
{ constOpcode, mode }, gate);
|
||||
acc_.SetDep(current, profiling);
|
||||
builder_.SetDepend(acc_.GetDep(gate)); // set gate depend: profiling or STATE_SPLIT
|
||||
}
|
||||
|
@ -392,15 +392,16 @@ void TypeLowering::LowerTypedNegOverflowCheck(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
GateRef TypeLowering::LowerCallRuntime(GateRef glue, int index, const std::vector<GateRef> &args, bool useLabel)
|
||||
GateRef TypeLowering::LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
|
||||
bool useLabel)
|
||||
{
|
||||
if (useLabel) {
|
||||
GateRef result = builder_.CallRuntime(glue, index, Gate::InvalidGateRef, args);
|
||||
GateRef result = builder_.CallRuntime(glue, index, Gate::InvalidGateRef, args, hirGate);
|
||||
return result;
|
||||
} else {
|
||||
const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(CallRuntime));
|
||||
GateRef target = builder_.IntPtr(index);
|
||||
GateRef result = builder_.Call(cs, glue, target, dependEntry_, args);
|
||||
GateRef result = builder_.Call(cs, glue, target, dependEntry_, args, hirGate);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -694,7 +695,7 @@ void TypeLowering::LowerHeapAllocateInYoung(GateRef gate, GateRef glue)
|
||||
}
|
||||
builder_.Bind(&callRuntime);
|
||||
{
|
||||
result = LowerCallRuntime(glue, RTSTUB_ID(AllocateInYoung), {builder_.ToTaggedInt(size)}, true);
|
||||
result = LowerCallRuntime(glue, gate, RTSTUB_ID(AllocateInYoung), {builder_.ToTaggedInt(size)}, true);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
@ -2586,7 +2587,8 @@ GateRef TypeLowering::ModNumbers(GateRef left, GateRef right, GateType leftType,
|
||||
{
|
||||
GateRef glue = acc_.GetGlueFromArgList();
|
||||
result = builder_.CallNGCRuntime(
|
||||
glue, RTSTUB_ID(FloatMod), Gate::InvalidGateRef, {*doubleLeft, *doubleRight});
|
||||
glue, RTSTUB_ID(FloatMod), Gate::InvalidGateRef, {*doubleLeft, *doubleRight},
|
||||
Circuit::NullGate());
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
@ -2896,9 +2898,8 @@ void TypeLowering::LowerTypedNewAllocateThis(GateRef gate, GateRef glue)
|
||||
GateRef frameState = GetFrameState(gate);
|
||||
builder_.DeoptCheck(check, frameState);
|
||||
|
||||
NewObjectStubBuilder stubBuilder(&env);
|
||||
stubBuilder.SetGule(glue);
|
||||
stubBuilder.NewJSObject(&thisObj, &exit, protoOrHclass);
|
||||
thisObj = builder_.CallStub(glue, gate, CommonStubCSigns::NewJSObject, { glue, protoOrHclass });
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
builder_.SetDepend(*thisObj);
|
||||
@ -2925,9 +2926,8 @@ void TypeLowering::LowerTypedSuperAllocateThis(GateRef gate, GateRef glue)
|
||||
GateRef frameState = GetFrameState(gate);
|
||||
builder_.DeoptCheck(check, frameState);
|
||||
|
||||
NewObjectStubBuilder stubBuilder(&env);
|
||||
stubBuilder.SetGule(glue);
|
||||
stubBuilder.NewJSObject(&thisObj, &exit, protoOrHclass);
|
||||
thisObj = builder_.CallStub(glue, gate, CommonStubCSigns::NewJSObject, { glue, protoOrHclass });
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
builder_.SetDepend(*thisObj);
|
||||
|
@ -204,7 +204,8 @@ private:
|
||||
void LowerTypedSuperAllocateThis(GateRef gate, GateRef glue);
|
||||
void LowerGetSuperConstructor(GateRef gate);
|
||||
|
||||
GateRef LowerCallRuntime(GateRef glue, int index, const std::vector<GateRef> &args, bool useLabel = false);
|
||||
GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
|
||||
bool useLabel = false);
|
||||
|
||||
template<OpCode Op>
|
||||
GateRef CalculateNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType);
|
||||
|
@ -30,7 +30,7 @@ class JSThread;
|
||||
enum class SpecVregIndex: int {
|
||||
PC_INDEX = -1,
|
||||
ACC_INDEX = -2,
|
||||
BC_OFFSET_INDEX = -3,
|
||||
PC_OFFSET_INDEX = -3,
|
||||
};
|
||||
|
||||
struct Context {
|
||||
|
@ -744,19 +744,21 @@ void HeapSnapshot::AddTraceNodeId(MethodLiteral *methodLiteral)
|
||||
int HeapSnapshot::AddTraceNode(int sequenceId, int size)
|
||||
{
|
||||
traceNodeIndex_.clear();
|
||||
FrameHandler frameHandler(vm_->GetAssociatedJSThread());
|
||||
for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
|
||||
if (!frameHandler.IsJSFrame()) {
|
||||
auto thread = vm_->GetJSThread();
|
||||
JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetCurrentFrame());
|
||||
FrameIterator it(current, thread);
|
||||
for (; !it.Done(); it.Advance<GCVisitedFlag::VISITED>()) {
|
||||
if (!it.IsJSFrame()) {
|
||||
continue;
|
||||
}
|
||||
auto method = frameHandler.CheckAndGetMethod();
|
||||
auto method = it.CheckAndGetMethod();
|
||||
if (method == nullptr || method->IsNativeWithCallField()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MethodLiteral *methodLiteral = method->GetMethodLiteral();
|
||||
if (stackInfo_.count(methodLiteral) == 0) {
|
||||
AddMethodInfo(methodLiteral, frameHandler, method->GetJSPandaFile(), sequenceId);
|
||||
AddMethodInfo(methodLiteral, it, method->GetJSPandaFile(), sequenceId);
|
||||
}
|
||||
AddTraceNodeId(methodLiteral);
|
||||
}
|
||||
@ -775,7 +777,7 @@ int HeapSnapshot::AddTraceNode(int sequenceId, int size)
|
||||
}
|
||||
|
||||
void HeapSnapshot::AddMethodInfo(MethodLiteral *methodLiteral,
|
||||
const FrameHandler &frameHandler,
|
||||
const FrameIterator &it,
|
||||
const JSPandaFile *jsPandaFile,
|
||||
int sequenceId)
|
||||
{
|
||||
@ -819,7 +821,7 @@ void HeapSnapshot::AddMethodInfo(MethodLiteral *methodLiteral,
|
||||
columnNumber = column + 1;
|
||||
return true;
|
||||
};
|
||||
uint32_t offset = frameHandler.GetBytecodeOffset();
|
||||
uint32_t offset = it.GetBytecodeOffset();
|
||||
if (!debugExtractor->MatchLineWithOffset(callbackLineFunc, methodId, offset) ||
|
||||
!debugExtractor->MatchColumnWithOffset(callbackColumnFunc, methodId, offset)) {
|
||||
codeEntry.lineNumber = 0;
|
||||
|
@ -380,7 +380,7 @@ public:
|
||||
bool FinishSnapshot();
|
||||
void PushHeapStat(Stream* stream);
|
||||
int AddTraceNode(int sequenceId, int size);
|
||||
void AddMethodInfo(MethodLiteral *methodLiteral, const FrameHandler &frameHandler,
|
||||
void AddMethodInfo(MethodLiteral *methodLiteral, const FrameIterator &it,
|
||||
const JSPandaFile *jsPandaFile, int sequenceId);
|
||||
void AddTraceNodeId(MethodLiteral *methodLiteral);
|
||||
|
||||
|
@ -67,17 +67,18 @@ std::string JsStackInfo::BuildMethodTrace(Method *method, uint32_t pcOffset)
|
||||
std::string JsStackInfo::BuildJsStackTrace(JSThread *thread, bool needNative)
|
||||
{
|
||||
std::string data;
|
||||
FrameHandler frameHandler(thread);
|
||||
for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
|
||||
if (!frameHandler.IsJSFrame()) {
|
||||
JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetCurrentFrame());
|
||||
FrameIterator it(current, thread);
|
||||
for (; !it.Done(); it.Advance<GCVisitedFlag::VISITED>()) {
|
||||
if (!it.IsJSFrame()) {
|
||||
continue;
|
||||
}
|
||||
auto method = frameHandler.CheckAndGetMethod();
|
||||
auto method = it.CheckAndGetMethod();
|
||||
if (method == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (!method->IsNativeWithCallField()) {
|
||||
auto pcOffset = frameHandler.GetBytecodeOffset();
|
||||
auto pcOffset = it.GetBytecodeOffset();
|
||||
data += BuildMethodTrace(method, pcOffset);
|
||||
} else if (needNative) {
|
||||
auto addr = method->GetNativePointer();
|
||||
@ -98,14 +99,15 @@ std::string JsStackInfo::BuildJsStackTrace(JSThread *thread, bool needNative)
|
||||
|
||||
std::vector<struct JsFrameInfo> JsStackInfo::BuildJsStackInfo(JSThread *thread)
|
||||
{
|
||||
FrameHandler frameHandler(thread);
|
||||
std::vector<struct JsFrameInfo> jsframe;
|
||||
uintptr_t *native = nullptr;
|
||||
for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
|
||||
if (!frameHandler.IsJSFrame()) {
|
||||
JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetCurrentFrame());
|
||||
FrameIterator it(current, thread);
|
||||
for (; !it.Done(); it.Advance<GCVisitedFlag::VISITED>()) {
|
||||
if (!it.IsJSFrame()) {
|
||||
continue;
|
||||
}
|
||||
auto method = frameHandler.CheckAndGetMethod();
|
||||
auto method = it.CheckAndGetMethod();
|
||||
if (method == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@ -142,14 +144,14 @@ std::vector<struct JsFrameInfo> JsStackInfo::BuildJsStackInfo(JSThread *thread)
|
||||
return true;
|
||||
};
|
||||
panda_file::File::EntityId methodId = method->GetMethodId();
|
||||
uint32_t offset = frameHandler.GetBytecodeOffset();
|
||||
uint32_t offset = it.GetBytecodeOffset();
|
||||
if (!debugExtractor->MatchLineWithOffset(callbackLineFunc, methodId, offset) ||
|
||||
!debugExtractor->MatchColumnWithOffset(callbackColumnFunc, methodId, offset)) {
|
||||
frameInfo.pos = "?";
|
||||
}
|
||||
jsframe.push_back(frameInfo);
|
||||
} else {
|
||||
JSTaggedValue function = frameHandler.GetFunction();
|
||||
JSTaggedValue function = it.GetFunction();
|
||||
JSHandle<JSTaggedValue> extraInfoValue(
|
||||
thread, JSFunction::Cast(function.GetTaggedObject())->GetFunctionExtraInfo());
|
||||
if (extraInfoValue->IsJSNativePointer()) {
|
||||
|
@ -276,9 +276,6 @@
|
||||
do { \
|
||||
if (!(thread)->HasPendingException()) { \
|
||||
(thread)->SetException(error); \
|
||||
if ((thread)->IsPrintBCOffset()) { \
|
||||
(thread)->CollectBCOffsetInfo(); \
|
||||
} \
|
||||
} \
|
||||
return; \
|
||||
} while (false)
|
||||
@ -292,9 +289,6 @@
|
||||
ObjectFactory *_factory = (thread)->GetEcmaVM()->GetFactory(); \
|
||||
JSHandle<JSObject> _error = _factory->GetJSError(type, message); \
|
||||
(thread)->SetException(_error.GetTaggedValue()); \
|
||||
if ((thread)->IsPrintBCOffset()) { \
|
||||
(thread)->CollectBCOffsetInfo(); \
|
||||
} \
|
||||
return; \
|
||||
} while (false)
|
||||
|
||||
@ -303,9 +297,6 @@
|
||||
do { \
|
||||
if (!(thread)->HasPendingException()) { \
|
||||
(thread)->SetException(error); \
|
||||
if ((thread)->IsPrintBCOffset()) { \
|
||||
(thread)->CollectBCOffsetInfo(); \
|
||||
} \
|
||||
} \
|
||||
return (value); \
|
||||
} while (false)
|
||||
@ -319,9 +310,6 @@
|
||||
ObjectFactory *_factory = (thread)->GetEcmaVM()->GetFactory(); \
|
||||
JSHandle<JSObject> _error = _factory->GetJSError(errorType, message); \
|
||||
(thread)->SetException(_error.GetTaggedValue()); \
|
||||
if ((thread)->IsPrintBCOffset()) { \
|
||||
(thread)->CollectBCOffsetInfo(); \
|
||||
} \
|
||||
return JSHandle<type>(thread, JSTaggedValue::Exception()); \
|
||||
} while (false)
|
||||
|
||||
@ -334,9 +322,6 @@
|
||||
ObjectFactory *_factory = (thread)->GetEcmaVM()->GetFactory(); \
|
||||
JSHandle<JSObject> _error = _factory->GetJSError(errorType, message); \
|
||||
(thread)->SetException(_error.GetTaggedValue()); \
|
||||
if ((thread)->IsPrintBCOffset()) { \
|
||||
(thread)->CollectBCOffsetInfo(); \
|
||||
} \
|
||||
return (value); \
|
||||
} while (false)
|
||||
|
||||
|
@ -493,7 +493,6 @@ Expected<JSTaggedValue, bool> EcmaVM::InvokeEcmaEntrypoint(const JSPandaFile *js
|
||||
|
||||
JSTaggedValue result;
|
||||
if (aotFileManager_->IsLoadMain(jsPandaFile, entryPoint.data())) {
|
||||
thread_->SetPrintBCOffset(true);
|
||||
EcmaRuntimeStatScope runtimeStatScope(this);
|
||||
result = InvokeEcmaAotEntrypoint(func, global, jsPandaFile, entryPoint);
|
||||
} else {
|
||||
@ -673,11 +672,6 @@ void EcmaVM::HandleUncaughtException(JSTaggedValue exception)
|
||||
thread_->ClearException();
|
||||
if (exceptionHandle->IsJSError()) {
|
||||
PrintJSErrorInfo(exceptionHandle);
|
||||
if (thread_->IsPrintBCOffset() && exceptionBCList_.size() != 0) {
|
||||
for (const auto &[methodName, bcOffset] : exceptionBCList_) {
|
||||
LOG_ECMA(ERROR) << "Exception at function " << methodName << ": " << bcOffset;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
JSHandle<EcmaString> result = JSTaggedValue::ToString(thread_, exceptionHandle);
|
||||
|
@ -395,21 +395,6 @@ public:
|
||||
panda_file::File::EntityId id);
|
||||
void CreateAllConstpool(const JSPandaFile *jsPandaFile);
|
||||
|
||||
void StoreBCOffsetInfo(const std::string& methodName, int32_t bcOffset)
|
||||
{
|
||||
exceptionBCList_.emplace_back(std::pair<std::string, int32_t>(methodName, bcOffset));
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, int32_t>> GetBCOffsetInfoList() const
|
||||
{
|
||||
return exceptionBCList_;
|
||||
}
|
||||
|
||||
void ClearExceptionBCList()
|
||||
{
|
||||
exceptionBCList_.clear();
|
||||
}
|
||||
|
||||
void WorkersetInfo(EcmaVM *hostVm, EcmaVM *workerVm)
|
||||
{
|
||||
os::memory::LockHolder lock(mutex_);
|
||||
@ -660,7 +645,6 @@ private:
|
||||
// atomics
|
||||
bool AllowAtomicWait_ {true};
|
||||
WaiterListNode waiterListNode_;
|
||||
std::vector<std::pair<std::string, int32_t>> exceptionBCList_;
|
||||
|
||||
// CJS resolve path Callbacks
|
||||
ResolvePathCallback resolvePathCallback_ {nullptr};
|
||||
|
@ -379,6 +379,15 @@ uint32_t FrameIterator::GetBytecodeOffset() const
|
||||
auto offset = frame->GetPc() - method->GetBytecodeArray();
|
||||
return static_cast<uint32_t>(offset);
|
||||
}
|
||||
case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
|
||||
auto frame = this->GetFrame<OptimizedJSFunctionFrame>();
|
||||
kungfu::ConstInfo constInfo;
|
||||
frame->CollectPcOffsetInfo(*this, constInfo);
|
||||
if (!constInfo.empty()) {
|
||||
return constInfo[0];
|
||||
}
|
||||
LOG_ECMA(FATAL) << "error: empty pcOffset in stackmap!";
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
}
|
||||
@ -437,7 +446,7 @@ ARK_INLINE void OptimizedFrame::GCIterate(const FrameIterator &it,
|
||||
}
|
||||
}
|
||||
|
||||
void FrameIterator::CollectBCOffsetInfo(kungfu::ConstInfo &info) const
|
||||
void FrameIterator::CollectPcOffsetInfo(kungfu::ConstInfo &info) const
|
||||
{
|
||||
arkStackMapParser_->GetConstInfo(optimizedReturnAddr_, info, stackMapAddr_);
|
||||
}
|
||||
@ -463,9 +472,9 @@ ARK_INLINE uintptr_t* OptimizedJSFunctionFrame::ComputePrevFrameSp(const FrameIt
|
||||
}
|
||||
|
||||
|
||||
void OptimizedJSFunctionFrame::CollectBCOffsetInfo(const FrameIterator &it, kungfu::ConstInfo &info) const
|
||||
void OptimizedJSFunctionFrame::CollectPcOffsetInfo(const FrameIterator &it, kungfu::ConstInfo &info) const
|
||||
{
|
||||
it.CollectBCOffsetInfo(info);
|
||||
it.CollectPcOffsetInfo(info);
|
||||
}
|
||||
|
||||
ARK_INLINE void OptimizedJSFunctionFrame::GCIterate(const FrameIterator &it,
|
||||
|
@ -412,7 +412,7 @@ public:
|
||||
|
||||
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
|
||||
const RootBaseAndDerivedVisitor &derivedVisitor) const;
|
||||
void CollectBCOffsetInfo(const FrameIterator &it, kungfu::ConstInfo &info) const;
|
||||
void CollectPcOffsetInfo(const FrameIterator &it, kungfu::ConstInfo &info) const;
|
||||
|
||||
inline JSTaggedValue GetEnv() const
|
||||
{
|
||||
@ -1409,7 +1409,7 @@ public:
|
||||
return thread_;
|
||||
}
|
||||
bool IteratorStackMap(const RootVisitor &visitor, const RootBaseAndDerivedVisitor &derivedVisitor) const;
|
||||
void CollectBCOffsetInfo(kungfu::ConstInfo &info) const;
|
||||
void CollectPcOffsetInfo(kungfu::ConstInfo &info) const;
|
||||
void CollectArkDeopt(std::vector<kungfu::ARKDeopt>& deopts) const;
|
||||
std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr) const;
|
||||
int GetCallSiteDelta(uintptr_t retAddr) const;
|
||||
@ -1429,10 +1429,26 @@ public:
|
||||
return (type == FrameType::OPTIMIZED_FRAME);
|
||||
}
|
||||
|
||||
bool IsInterpretedFrame(FrameType type) const
|
||||
{
|
||||
return (type >= FrameType::INTERPRETER_FIRST) && (type <= FrameType::INTERPRETER_LAST);
|
||||
}
|
||||
|
||||
bool IsJSFrame() const
|
||||
{
|
||||
FrameType type = GetFrameType();
|
||||
return IsInterpretedFrame(type) || IsOptimizedJSFunctionFrame(type);
|
||||
}
|
||||
|
||||
bool IsOptimizedJSFunctionFrame(FrameType type) const
|
||||
{
|
||||
return type == FrameType::OPTIMIZED_JS_FUNCTION_FRAME;
|
||||
}
|
||||
|
||||
bool IsOptimizedJSFunctionFrame() const
|
||||
{
|
||||
FrameType type = GetFrameType();
|
||||
return (type == FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
|
||||
return IsOptimizedJSFunctionFrame(type);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -168,7 +168,7 @@ JSTaggedValue LoadICRuntime::LoadMiss(JSHandle<JSTaggedValue> receiver, JSHandle
|
||||
ObjectOperator op(GetThread(), receiver, key);
|
||||
auto result = JSHandle<JSTaggedValue>(thread_, JSObject::GetProperty(GetThread(), &op));
|
||||
if (!op.IsFound() && kind == ICKind::NamedGlobalTryLoadIC) {
|
||||
return SlowRuntimeStub::ThrowReferenceError(GetThread(), key.GetTaggedValue(), " is not definded");
|
||||
return SlowRuntimeStub::ThrowReferenceError(GetThread(), key.GetTaggedValue(), " is not defined");
|
||||
}
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(GetThread());
|
||||
// ic-switch
|
||||
|
@ -127,7 +127,7 @@ JSTaggedValue FrameHandler::GetAcc() const
|
||||
|
||||
uint32_t FrameHandler::GetBytecodeOffset() const
|
||||
{
|
||||
ASSERT(IsJSFrame());
|
||||
ASSERT(IsInterpretedFrame());
|
||||
Method *method = GetMethod();
|
||||
auto offset = GetPc() - method->GetBytecodeArray();
|
||||
return static_cast<uint32_t>(offset);
|
||||
@ -438,58 +438,4 @@ void FrameHandler::IterateFrameChain(JSTaggedType *start, const RootVisitor &vis
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string FrameBcCollector::GetAotExceptionFuncName(JSTaggedType* argv) const
|
||||
{
|
||||
JSTaggedValue func = JSTaggedValue(*(argv)); // 3: skip returnaddr and argc
|
||||
Method *method = JSFunction::Cast(func.GetTaggedObject())->GetCallTarget();
|
||||
return method->GetMethodName();
|
||||
}
|
||||
|
||||
void FrameBcCollector::CollectBCOffsetInfo()
|
||||
{
|
||||
thread_->GetEcmaVM()->ClearExceptionBCList();
|
||||
JSTaggedType *current = const_cast<JSTaggedType *>(thread_->GetLastLeaveFrame());
|
||||
FrameIterator it(current, thread_);
|
||||
it.Advance<GCVisitedFlag::VISITED>();
|
||||
|
||||
for (; !it.Done(); it.Advance<GCVisitedFlag::VISITED>()) {
|
||||
FrameType type = it.GetFrameType();
|
||||
switch (type) {
|
||||
case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
|
||||
auto frame = it.GetFrame<OptimizedJSFunctionFrame>();
|
||||
kungfu::ConstInfo constInfo;
|
||||
frame->CollectBCOffsetInfo(it, constInfo);
|
||||
if (!constInfo.empty()) {
|
||||
auto name = GetAotExceptionFuncName(frame->GetArgv(it));
|
||||
thread_->GetEcmaVM()->StoreBCOffsetInfo(name, constInfo[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME:
|
||||
case FrameType::BUILTIN_CALL_LEAVE_FRAME:
|
||||
case FrameType::LEAVE_FRAME:
|
||||
case FrameType::OPTIMIZED_ENTRY_FRAME:
|
||||
case FrameType::ASM_INTERPRETER_BRIDGE_FRAME:
|
||||
case FrameType::ASM_INTERPRETER_ENTRY_FRAME:
|
||||
case FrameType::ASM_INTERPRETER_FRAME:
|
||||
case FrameType::INTERPRETER_CONSTRUCTOR_FRAME:
|
||||
case FrameType::INTERPRETER_FRAME:
|
||||
case FrameType::INTERPRETER_FAST_NEW_FRAME:
|
||||
case FrameType::OPTIMIZED_FRAME:
|
||||
case FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME:
|
||||
case FrameType::LEAVE_FRAME_WITH_ARGV:
|
||||
case FrameType::BUILTIN_FRAME_WITH_ARGV:
|
||||
case FrameType::BUILTIN_ENTRY_FRAME:
|
||||
case FrameType::BUILTIN_FRAME:
|
||||
case FrameType::INTERPRETER_ENTRY_FRAME: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG_FULL(FATAL) << "frame type error!";
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -84,6 +84,12 @@ public:
|
||||
return IsJSFrame(type);
|
||||
}
|
||||
|
||||
bool IsOptimizedJSFunctionFrame() const
|
||||
{
|
||||
FrameType type = GetFrameType();
|
||||
return type == FrameType::OPTIMIZED_JS_FUNCTION_FRAME;
|
||||
}
|
||||
|
||||
bool IsJSFrame(FrameType type) const
|
||||
{
|
||||
return IsInterpretedFrame(type) || IsOptimizedJSFunctionFrame(type);
|
||||
@ -253,19 +259,6 @@ private:
|
||||
JSThread *thread_ {nullptr};
|
||||
const JSTaggedType *oldSp_ {nullptr};
|
||||
};
|
||||
|
||||
class FrameBcCollector {
|
||||
public:
|
||||
explicit FrameBcCollector(const JSThread *thread) : thread_(thread)
|
||||
{
|
||||
}
|
||||
~FrameBcCollector() = default;
|
||||
// for collecting bc offset in aot
|
||||
void CollectBCOffsetInfo();
|
||||
private:
|
||||
std::string GetAotExceptionFuncName(JSTaggedType* fp) const;
|
||||
const JSThread *thread_ {nullptr};
|
||||
};
|
||||
}; // namespace ecmascript
|
||||
} // namespace panda
|
||||
#endif // ECMASCRIPT_INTERPRETER_FRAME_HANDLER_H
|
||||
|
@ -493,12 +493,6 @@ bool JSThread::CpuProfilerCheckJSTaggedType(JSTaggedType value) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void JSThread::CollectBCOffsetInfo()
|
||||
{
|
||||
FrameBcCollector collector(this);
|
||||
collector.CollectBCOffsetInfo();
|
||||
}
|
||||
|
||||
// static
|
||||
size_t JSThread::GetAsmStackLimit()
|
||||
{
|
||||
|
@ -555,18 +555,6 @@ public:
|
||||
|
||||
bool IsLegalSp(uintptr_t sp) const;
|
||||
|
||||
bool IsPrintBCOffset() const
|
||||
{
|
||||
return enablePrintBCOffset_;
|
||||
}
|
||||
|
||||
void SetPrintBCOffset(bool flag)
|
||||
{
|
||||
enablePrintBCOffset_ = flag;
|
||||
}
|
||||
|
||||
void CollectBCOffsetInfo();
|
||||
|
||||
void SetCheckAndCallEnterState(bool state)
|
||||
{
|
||||
finalizationCheckState_ = state;
|
||||
@ -861,7 +849,6 @@ private:
|
||||
bool runtimeState_ {false};
|
||||
bool isAsmInterpreter_ {false};
|
||||
VmThreadControl *vmThreadControl_ {nullptr};
|
||||
bool enablePrintBCOffset_ {false};
|
||||
bool stableArrayElementsGuardians_ {true};
|
||||
|
||||
bool finalizationCheckState_ {false};
|
||||
|
@ -75,7 +75,7 @@ void ArkStackMapParser::GetConstInfo(uintptr_t callSiteAddr, ConstInfo &info, ui
|
||||
}
|
||||
|
||||
ARKDeopt target;
|
||||
OffsetType id = static_cast<OffsetType>(SpecVregIndex::BC_OFFSET_INDEX);
|
||||
OffsetType id = static_cast<OffsetType>(SpecVregIndex::PC_OFFSET_INDEX);
|
||||
target.Id = id;
|
||||
auto it = std::lower_bound(deopts.begin(), deopts.end(), target,
|
||||
[](const ARKDeopt& a, const ARKDeopt& b) {
|
||||
|
@ -115,9 +115,9 @@ HWTEST_F_L0(JSCollatorTest, InitializeCollatorAndGetIcuCollator)
|
||||
JSHandle<JSCollator> collator =
|
||||
JSHandle<JSCollator>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(ctor), ctor));
|
||||
JSHandle<JSTaggedValue> localeStr = thread->GlobalConstants()->GetHandledEnUsString();
|
||||
JSHandle<JSTaggedValue> undefindedHandle(thread, JSTaggedValue::Undefined());
|
||||
JSHandle<JSTaggedValue> undefinedHandle(thread, JSTaggedValue::Undefined());
|
||||
|
||||
JSHandle<JSCollator> initCollator = JSCollator::InitializeCollator(thread, collator, localeStr, undefindedHandle);
|
||||
JSHandle<JSCollator> initCollator = JSCollator::InitializeCollator(thread, collator, localeStr, undefinedHandle);
|
||||
EXPECT_EQ(JSTaggedValue::SameValue(collator.GetTaggedValue(), initCollator.GetTaggedValue()), true);
|
||||
// check attributes
|
||||
EXPECT_TRUE(initCollator->GetBoundCompare().IsUndefined());
|
||||
|
@ -70,7 +70,17 @@ group("ark_aot_test") {
|
||||
"div:divAotAction",
|
||||
"duplicatefunctions:duplicatefunctionsAotAction",
|
||||
"duplicatekey:duplicatekeyAotAction",
|
||||
"exceptionhandler:exceptionhandlerAotAction",
|
||||
"exception_case1:exceptionhandlerAotAction",
|
||||
|
||||
# "exception_case10:exceptionhandlerAotAction",
|
||||
"exception_case2:exceptionhandlerAotAction",
|
||||
"exception_case3:exceptionhandlerAotAction",
|
||||
"exception_case4:exceptionhandlerAotAction",
|
||||
"exception_case5:exceptionhandlerAotAction",
|
||||
"exception_case6:exceptionhandlerAotAction",
|
||||
"exception_case7:exceptionhandlerAotAction",
|
||||
"exception_case8:exceptionhandlerAotAction",
|
||||
"exception_case9:exceptionhandlerAotAction",
|
||||
"exp:expAotAction",
|
||||
"forloop:forloopAotAction",
|
||||
"framestatesasync:framestatesasyncAotAction",
|
||||
|
@ -27,4 +27,3 @@ true
|
||||
true
|
||||
xxxx
|
||||
TypeError: CallObj is NonCallable
|
||||
Exception at function func_main_0: 310
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_test_action("exceptionhandler") {
|
||||
host_aot_js_test_action("exceptionhandler") {
|
||||
deps = []
|
||||
is_disable_type_lowering = true
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@ -13,14 +13,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
declare function print(str:string):string;
|
||||
|
||||
try {
|
||||
function foo() {
|
||||
JSON.parse("[1, 2");
|
||||
}
|
||||
foo();
|
||||
} catch(e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
print(e)
|
||||
let stack = e.stack
|
||||
let array = stack.split('\n')
|
||||
for (let line of array) {
|
||||
let start = line.lastIndexOf('/') + 1
|
||||
let end = line.length - 1
|
||||
if (start < end) {
|
||||
print(line.slice(start, end))
|
||||
} else {
|
||||
print(line)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
@ -12,5 +12,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
SyntaxError: Unexpected Array in JSON
|
||||
Exception at function foo: 7
|
||||
Exception at function func_main_0: 9
|
||||
exceptionhandler.js:18:18
|
||||
exceptionhandler.js:20:1
|
||||
|
19
test/aottest/exception_case10/BUILD.gn
Normal file
19
test/aottest/exception_case10/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_js_test_action("exceptionhandler") {
|
||||
deps = []
|
||||
is_disable_type_lowering = true
|
||||
}
|
37
test/aottest/exception_case10/exceptionhandler.js
Normal file
37
test/aottest/exception_case10/exceptionhandler.js
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
try {
|
||||
function foo() {
|
||||
a.b
|
||||
}
|
||||
function bar() {
|
||||
foo()
|
||||
}
|
||||
bar(...[1, 2])
|
||||
} catch (e) {
|
||||
print(e)
|
||||
let stack = e.stack
|
||||
let array = stack.split('\n')
|
||||
for (let line of array) {
|
||||
let start = line.lastIndexOf('/') + 1
|
||||
let end = line.length - 1
|
||||
if (start < end) {
|
||||
print(line.slice(start, end))
|
||||
} else {
|
||||
print(line)
|
||||
}
|
||||
}
|
||||
}
|
18
test/aottest/exception_case10/expect_output.txt
Normal file
18
test/aottest/exception_case10/expect_output.txt
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ReferenceError: a is not defined
|
||||
exceptionhandler.js:18:18
|
||||
exceptionhandler.js:21:21
|
||||
exceptionhandler.js:23:1
|
||||
|
19
test/aottest/exception_case2/BUILD.gn
Normal file
19
test/aottest/exception_case2/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_js_test_action("exceptionhandler") {
|
||||
deps = []
|
||||
is_disable_type_lowering = true
|
||||
}
|
34
test/aottest/exception_case2/exceptionhandler.js
Normal file
34
test/aottest/exception_case2/exceptionhandler.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
try {
|
||||
function foo(a) {
|
||||
b.c;
|
||||
}
|
||||
foo(1, 2);
|
||||
} catch (e) {
|
||||
print(e)
|
||||
let stack = e.stack
|
||||
let array = stack.split('\n')
|
||||
for (let line of array) {
|
||||
let start = line.lastIndexOf('/') + 1
|
||||
let end = line.length - 1
|
||||
if (start < end) {
|
||||
print(line.slice(start, end))
|
||||
} else {
|
||||
print(line)
|
||||
}
|
||||
}
|
||||
}
|
17
test/aottest/exception_case2/expect_output.txt
Normal file
17
test/aottest/exception_case2/expect_output.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ReferenceError: b is not defined
|
||||
exceptionhandler.js:18:18
|
||||
exceptionhandler.js:20:1
|
||||
|
19
test/aottest/exception_case3/BUILD.gn
Normal file
19
test/aottest/exception_case3/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_js_test_action("exceptionhandler") {
|
||||
deps = []
|
||||
is_disable_type_lowering = true
|
||||
}
|
34
test/aottest/exception_case3/exceptionhandler.js
Normal file
34
test/aottest/exception_case3/exceptionhandler.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
try {
|
||||
function foo(a, b, c) {
|
||||
d.e;
|
||||
}
|
||||
foo(1)
|
||||
} catch (e) {
|
||||
print(e)
|
||||
let stack = e.stack
|
||||
let array = stack.split('\n')
|
||||
for (let line of array) {
|
||||
let start = line.lastIndexOf('/') + 1
|
||||
let end = line.length - 1
|
||||
if (start < end) {
|
||||
print(line.slice(start, end))
|
||||
} else {
|
||||
print(line)
|
||||
}
|
||||
}
|
||||
}
|
17
test/aottest/exception_case3/expect_output.txt
Normal file
17
test/aottest/exception_case3/expect_output.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ReferenceError: d is not defined
|
||||
exceptionhandler.js:18:18
|
||||
exceptionhandler.js:20:1
|
||||
|
19
test/aottest/exception_case4/BUILD.gn
Normal file
19
test/aottest/exception_case4/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_js_test_action("exceptionhandler") {
|
||||
deps = []
|
||||
is_disable_type_lowering = true
|
||||
}
|
34
test/aottest/exception_case4/exceptionhandler.js
Normal file
34
test/aottest/exception_case4/exceptionhandler.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
try {
|
||||
function foo() {
|
||||
new Array(111111111111111111111)
|
||||
}
|
||||
foo();
|
||||
} catch (e) {
|
||||
print(e)
|
||||
let stack = e.stack
|
||||
let array = stack.split('\n')
|
||||
for (let line of array) {
|
||||
let start = line.lastIndexOf('/') + 1
|
||||
let end = line.length - 1
|
||||
if (start < end) {
|
||||
print(line.slice(start, end))
|
||||
} else {
|
||||
print(line)
|
||||
}
|
||||
}
|
||||
}
|
17
test/aottest/exception_case4/expect_output.txt
Normal file
17
test/aottest/exception_case4/expect_output.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
RangeError: The length is out of range.
|
||||
exceptionhandler.js:18:18
|
||||
exceptionhandler.js:20:1
|
||||
|
19
test/aottest/exception_case5/BUILD.gn
Normal file
19
test/aottest/exception_case5/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_js_test_action("exceptionhandler") {
|
||||
deps = []
|
||||
is_disable_type_lowering = true
|
||||
}
|
32
test/aottest/exception_case5/exceptionhandler.js
Normal file
32
test/aottest/exception_case5/exceptionhandler.js
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
try {
|
||||
var foo = 1;
|
||||
foo();
|
||||
} catch (e) {
|
||||
print(e)
|
||||
let stack = e.stack
|
||||
let array = stack.split('\n')
|
||||
for (let line of array) {
|
||||
let start = line.lastIndexOf('/') + 1
|
||||
let end = line.length - 1
|
||||
if (start < end) {
|
||||
print(line.slice(start, end))
|
||||
} else {
|
||||
print(line)
|
||||
}
|
||||
}
|
||||
}
|
16
test/aottest/exception_case5/expect_output.txt
Normal file
16
test/aottest/exception_case5/expect_output.txt
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
TypeError: CallObj is NonCallable
|
||||
exceptionhandler.js:18:1
|
||||
|
19
test/aottest/exception_case6/BUILD.gn
Normal file
19
test/aottest/exception_case6/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_js_test_action("exceptionhandler") {
|
||||
deps = []
|
||||
is_disable_type_lowering = true
|
||||
}
|
35
test/aottest/exception_case6/exceptionhandler.js
Normal file
35
test/aottest/exception_case6/exceptionhandler.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
try {
|
||||
function foo(a, b, c) {
|
||||
d.e;
|
||||
}
|
||||
var bar = foo.bind(undefined, [2, 3])
|
||||
bar(1);
|
||||
} catch (e) {
|
||||
print(e)
|
||||
let stack = e.stack
|
||||
let array = stack.split('\n')
|
||||
for (let line of array) {
|
||||
let start = line.lastIndexOf('/') + 1
|
||||
let end = line.length - 1
|
||||
if (start < end) {
|
||||
print(line.slice(start, end))
|
||||
} else {
|
||||
print(line)
|
||||
}
|
||||
}
|
||||
}
|
17
test/aottest/exception_case6/expect_output.txt
Normal file
17
test/aottest/exception_case6/expect_output.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ReferenceError: d is not defined
|
||||
exceptionhandler.js:18:18
|
||||
exceptionhandler.js:21:1
|
||||
|
19
test/aottest/exception_case7/BUILD.gn
Normal file
19
test/aottest/exception_case7/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_js_test_action("exceptionhandler") {
|
||||
deps = []
|
||||
is_disable_type_lowering = true
|
||||
}
|
37
test/aottest/exception_case7/exceptionhandler.js
Normal file
37
test/aottest/exception_case7/exceptionhandler.js
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
try {
|
||||
const handler = {
|
||||
get: function(obj, prop) {
|
||||
return a.b
|
||||
}
|
||||
}
|
||||
const p = new Proxy({}, handler)
|
||||
p.c
|
||||
} catch (e) {
|
||||
print(e)
|
||||
let stack = e.stack
|
||||
let array = stack.split('\n')
|
||||
for (let line of array) {
|
||||
let start = line.lastIndexOf('/') + 1
|
||||
let end = line.length - 1
|
||||
if (start < end) {
|
||||
print(line.slice(start, end))
|
||||
} else {
|
||||
print(line)
|
||||
}
|
||||
}
|
||||
}
|
17
test/aottest/exception_case7/expect_output.txt
Normal file
17
test/aottest/exception_case7/expect_output.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ReferenceError: a is not defined
|
||||
exceptionhandler.js:19:19
|
||||
exceptionhandler.js:23:1
|
||||
|
19
test/aottest/exception_case8/BUILD.gn
Normal file
19
test/aottest/exception_case8/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_js_test_action("exceptionhandler") {
|
||||
deps = []
|
||||
is_disable_type_lowering = true
|
||||
}
|
38
test/aottest/exception_case8/exceptionhandler.js
Normal file
38
test/aottest/exception_case8/exceptionhandler.js
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
try {
|
||||
function bar() {
|
||||
JSON.parse("[1, 2");
|
||||
}
|
||||
|
||||
function foo(a, b, c) {
|
||||
bar.apply(undefined, [])
|
||||
}
|
||||
foo(1);
|
||||
} catch (e) {
|
||||
print(e)
|
||||
let stack = e.stack
|
||||
let array = stack.split('\n')
|
||||
for (let line of array) {
|
||||
let start = line.lastIndexOf('/') + 1
|
||||
let end = line.length - 1
|
||||
if (start < end) {
|
||||
print(line.slice(start, end))
|
||||
} else {
|
||||
print(line)
|
||||
}
|
||||
}
|
||||
}
|
18
test/aottest/exception_case8/expect_output.txt
Normal file
18
test/aottest/exception_case8/expect_output.txt
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
SyntaxError: Unexpected Array in JSON
|
||||
exceptionhandler.js:18:18
|
||||
exceptionhandler.js:22:22
|
||||
exceptionhandler.js:24:1
|
||||
|
19
test/aottest/exception_case9/BUILD.gn
Normal file
19
test/aottest/exception_case9/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_js_test_action("exceptionhandler") {
|
||||
deps = []
|
||||
is_disable_type_lowering = true
|
||||
}
|
40
test/aottest/exception_case9/exceptionhandler.js
Normal file
40
test/aottest/exception_case9/exceptionhandler.js
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
try {
|
||||
function foo() {
|
||||
a.b
|
||||
}
|
||||
let o = {
|
||||
get name() {
|
||||
foo()
|
||||
},
|
||||
set name(a) {}
|
||||
}
|
||||
o.name
|
||||
} catch (e) {
|
||||
print(e)
|
||||
let stack = e.stack
|
||||
let array = stack.split('\n')
|
||||
for (let line of array) {
|
||||
let start = line.lastIndexOf('/') + 1
|
||||
let end = line.length - 1
|
||||
if (start < end) {
|
||||
print(line.slice(start, end))
|
||||
} else {
|
||||
print(line)
|
||||
}
|
||||
}
|
||||
}
|
18
test/aottest/exception_case9/expect_output.txt
Normal file
18
test/aottest/exception_case9/expect_output.txt
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ReferenceError: a is not defined
|
||||
exceptionhandler.js:18:18
|
||||
exceptionhandler.js:22:22
|
||||
exceptionhandler.js:26:1
|
||||
|
Loading…
Reference in New Issue
Block a user