2022-02-19 02:09:52 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2021 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef ECMASCRIPT_COMPILER_INTERPRETER_STUB_INL_H
|
|
|
|
#define ECMASCRIPT_COMPILER_INTERPRETER_STUB_INL_H
|
|
|
|
|
|
|
|
#include "ecmascript/compiler/interpreter_stub.h"
|
2022-03-16 10:12:15 +00:00
|
|
|
#include "ecmascript/js_function.h"
|
2022-03-26 04:04:44 +00:00
|
|
|
#include "ecmascript/js_generator_object.h"
|
2022-02-19 02:09:52 +00:00
|
|
|
|
|
|
|
namespace panda::ecmascript::kungfu {
|
|
|
|
void InterpreterStub::SetVregValue(GateRef glue, GateRef sp, GateRef idx, GateRef val)
|
|
|
|
{
|
2022-04-21 12:08:23 +00:00
|
|
|
Store(VariableType::INT64(), glue, sp, PtrMul(IntPtr(sizeof(JSTaggedType)), idx), val);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::GetVregValue(GateRef sp, GateRef idx)
|
|
|
|
{
|
2022-04-21 12:08:23 +00:00
|
|
|
return Load(VariableType::JS_ANY(), sp, PtrMul(IntPtr(sizeof(JSTaggedType)), idx));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst8_0(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::INT8(), pc, IntPtr(1));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst8_1(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::INT8(), pc, IntPtr(2)); // 2 : skip 1 byte of bytecode
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst8_2(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::INT8(), pc, IntPtr(3)); // 3 : skip 1 byte of bytecode
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst8_3(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::INT8(), pc, IntPtr(4)); // 4 : skip 1 byte of bytecode
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst8_4(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::INT8(), pc, IntPtr(5)); // 5 : skip 1 byte of bytecode
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst8_5(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::INT8(), pc, IntPtr(6)); // 6 : skip 1 byte of bytecode
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst8_6(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::INT8(), pc, IntPtr(7)); // 7 : skip 1 byte of bytecode
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst8_7(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::INT8(), pc, IntPtr(8)); // 8 : skip 1 byte of bytecode
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst8_8(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::INT8(), pc, IntPtr(9)); // 9 : skip 1 byte of bytecode
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst4_0(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Int8And(Load(VariableType::INT8(), pc, IntPtr(1)), Int8(0xf));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst4_1(GateRef pc)
|
|
|
|
{
|
|
|
|
return Int8And(
|
2022-03-31 09:26:17 +00:00
|
|
|
Int8LSR(Load(VariableType::INT8(), pc, IntPtr(1)), Int8(4)), Int8(0xf));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst4_2(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Int8And(Load(VariableType::INT8(), pc, IntPtr(2)), Int8(0xf));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst4_3(GateRef pc)
|
|
|
|
{
|
|
|
|
return Int8And(
|
2022-03-31 09:26:17 +00:00
|
|
|
Int8LSR(Load(VariableType::INT8(), pc, IntPtr(2)), Int8(4)), Int8(0xf));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInstSigned8_0(GateRef pc)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef x = Load(VariableType::INT8(), pc, IntPtr(1));
|
2022-05-10 12:52:16 +00:00
|
|
|
return GetEnvironment()->GetBulder()->UnaryArithmetic(OpCode(OpCode::SEXT_TO_INT32), x);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInstSigned16_0(GateRef pc)
|
|
|
|
{
|
|
|
|
/* 2 : skip 8 bits of opcode and 8 bits of low bits */
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst = Load(VariableType::INT8(), pc, IntPtr(2));
|
2022-05-10 12:52:16 +00:00
|
|
|
GateRef currentInst1 = GetEnvironment()->GetBulder()->UnaryArithmetic(
|
2022-02-19 02:09:52 +00:00
|
|
|
OpCode(OpCode::SEXT_TO_INT32), currentInst);
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst2 = Int32LSL(currentInst1, Int32(8)); // 8 : set as high 8 bits
|
2022-02-19 02:09:52 +00:00
|
|
|
return Int32Add(currentInst2, ZExtInt8ToInt32(ReadInst8_0(pc)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInstSigned32_0(GateRef pc)
|
|
|
|
{
|
|
|
|
/* 4 : skip 8 bits of opcode and 24 bits of low bits */
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef x = Load(VariableType::INT8(), pc, IntPtr(4));
|
2022-05-10 12:52:16 +00:00
|
|
|
GateRef currentInst = GetEnvironment()->GetBulder()->UnaryArithmetic(OpCode(OpCode::SEXT_TO_INT32), x);
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst1 = Int32LSL(currentInst, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst2 = Int32Add(currentInst1, ZExtInt8ToInt32(ReadInst8_2(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst3 = Int32LSL(currentInst2, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst4 = Int32Add(currentInst3, ZExtInt8ToInt32(ReadInst8_1(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst5 = Int32LSL(currentInst4, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
return Int32Add(currentInst5, ZExtInt8ToInt32(ReadInst8_0(pc)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst16_0(GateRef pc)
|
|
|
|
{
|
|
|
|
/* 2 : skip 8 bits of opcode and 8 bits of low bits */
|
|
|
|
GateRef currentInst1 = ZExtInt8ToInt16(ReadInst8_1(pc));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst2 = Int16LSL(currentInst1, Int16(8)); // 8 : set as high 8 bits
|
2022-02-19 02:09:52 +00:00
|
|
|
return Int16Add(currentInst2, ZExtInt8ToInt16(ReadInst8_0(pc)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst16_1(GateRef pc)
|
|
|
|
{
|
|
|
|
/* 3 : skip 8 bits of opcode, 8 bits of prefix and 8 bits of low bits */
|
|
|
|
GateRef currentInst1 = ZExtInt8ToInt16(ReadInst8_2(pc));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst2 = Int16LSL(currentInst1, Int16(8)); // 8 : set as high 8 bits
|
2022-02-19 02:09:52 +00:00
|
|
|
/* 2: skip 8 bits of opcode and 8 bits of prefix */
|
|
|
|
return Int16Add(currentInst2, ZExtInt8ToInt16(ReadInst8_1(pc)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst16_2(GateRef pc)
|
|
|
|
{
|
|
|
|
/* 4 : skip 8 bits of opcode, first parameter of 16 bits and 8 bits of low bits */
|
|
|
|
GateRef currentInst1 = ZExtInt8ToInt16(ReadInst8_3(pc));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst2 = Int16LSL(currentInst1, Int16(8)); // 8 : set as high 8 bits
|
2022-02-19 02:09:52 +00:00
|
|
|
/* 3: skip 8 bits of opcode and first parameter of 16 bits */
|
|
|
|
return Int16Add(currentInst2, ZExtInt8ToInt16(ReadInst8_2(pc)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst16_3(GateRef pc)
|
|
|
|
{
|
|
|
|
/* 5 : skip 8 bits of opcode, 8 bits of prefix, first parameter of 16 bits and 8 bits of low bits */
|
|
|
|
GateRef currentInst1 = ZExtInt8ToInt16(ReadInst8_4(pc));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst2 = Int16LSL(currentInst1, Int16(8)); // 8 : set as high 8 bits
|
2022-02-19 02:09:52 +00:00
|
|
|
/* 4: skip 8 bits of opcode, 8 bits of prefix and first parameter of 16 bits */
|
|
|
|
return Int16Add(currentInst2, ZExtInt8ToInt16(ReadInst8_3(pc)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst16_5(GateRef pc)
|
|
|
|
{
|
|
|
|
/* 7 : skip 8 bits of opcode, 8 bits of prefix, first 2 parameters of 16 bits and 8 bits of low bits */
|
|
|
|
GateRef currentInst1 = ZExtInt8ToInt16(ReadInst8_6(pc));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst2 = Int16LSL(currentInst1, Int16(8)); // 8 : set as high 8 bits
|
2022-02-19 02:09:52 +00:00
|
|
|
/* 6: skip 8 bits of opcode, 8 bits of prefix and first 2 parameters of 16 bits */
|
|
|
|
return Int16Add(currentInst2, ZExtInt8ToInt16(ReadInst8_5(pc)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::GetFrame(GateRef CurrentSp)
|
|
|
|
{
|
2022-04-21 12:08:23 +00:00
|
|
|
return PtrSub(CurrentSp, IntPtr(AsmInterpretedFrame::GetSize(GetEnvironment()->IsArch32Bit())));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::GetPcFromFrame(GateRef frame)
|
|
|
|
{
|
2022-04-16 08:54:51 +00:00
|
|
|
return Load(VariableType::NATIVE_POINTER(), frame,
|
2022-04-14 02:57:58 +00:00
|
|
|
IntPtr(AsmInterpretedFrame::GetPcOffset(GetEnvironment()->IsArch32Bit())));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::GetFunctionFromFrame(GateRef frame)
|
|
|
|
{
|
2022-03-01 08:31:08 +00:00
|
|
|
return Load(VariableType::JS_POINTER(), frame,
|
2022-03-31 09:26:17 +00:00
|
|
|
IntPtr(AsmInterpretedFrame::GetFunctionOffset(GetEnvironment()->IsArch32Bit())));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-03-22 03:30:26 +00:00
|
|
|
GateRef InterpreterStub::GetCallSizeFromFrame(GateRef frame)
|
|
|
|
{
|
2022-04-16 08:54:51 +00:00
|
|
|
return Load(VariableType::NATIVE_POINTER(), frame,
|
2022-03-31 09:26:17 +00:00
|
|
|
IntPtr(AsmInterpretedFrame::GetCallSizeOffset(GetEnvironment()->IsArch32Bit())));
|
2022-03-22 03:30:26 +00:00
|
|
|
}
|
|
|
|
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef InterpreterStub::GetAccFromFrame(GateRef frame)
|
|
|
|
{
|
2022-03-01 08:31:08 +00:00
|
|
|
return Load(VariableType::JS_ANY(), frame,
|
2022-03-31 09:26:17 +00:00
|
|
|
IntPtr(AsmInterpretedFrame::GetAccOffset(GetEnvironment()->IsArch32Bit())));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::GetEnvFromFrame(GateRef frame)
|
|
|
|
{
|
2022-03-01 08:31:08 +00:00
|
|
|
return Load(VariableType::JS_POINTER(), frame,
|
2022-03-31 09:26:17 +00:00
|
|
|
IntPtr(AsmInterpretedFrame::GetEnvOffset(GetEnvironment()->IsArch32Bit())));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-03-12 10:47:21 +00:00
|
|
|
GateRef InterpreterStub::GetEnvFromFunction(GateRef function)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::JS_POINTER(), function, IntPtr(JSFunction::LEXICAL_ENV_OFFSET));
|
2022-03-12 10:47:21 +00:00
|
|
|
}
|
|
|
|
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef InterpreterStub::GetProfileTypeInfoFromFunction(GateRef function)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::JS_POINTER(), function, IntPtr(JSFunction::PROFILE_TYPE_INFO_OFFSET));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-03-24 03:30:19 +00:00
|
|
|
GateRef InterpreterStub::GetModuleFromFunction(GateRef function)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::JS_POINTER(), function, IntPtr(JSFunction::ECMA_MODULE_OFFSET));
|
2022-03-24 03:30:19 +00:00
|
|
|
}
|
|
|
|
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef InterpreterStub::GetConstpoolFromFunction(GateRef function)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
return Load(VariableType::JS_POINTER(), function, IntPtr(JSFunction::CONSTANT_POOL_OFFSET));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 01:06:56 +00:00
|
|
|
// only use for fast new, not universal API
|
|
|
|
GateRef InterpreterStub::GetThisObjectFromFastNewFrame(GateRef prevSp)
|
|
|
|
{
|
2022-06-08 03:57:26 +00:00
|
|
|
auto idx = AsmInterpretedFrame::ReverseIndex::THIS_OBJECT_REVERSE_INDEX;
|
|
|
|
return Load(VariableType::JS_ANY(), prevSp, IntPtr(idx * sizeof(JSTaggedType)));
|
2022-04-26 01:06:56 +00:00
|
|
|
}
|
|
|
|
|
2022-03-26 04:04:44 +00:00
|
|
|
GateRef InterpreterStub::GetResumeModeFromGeneratorObject(GateRef obj)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef bitfieldOffset = IntPtr(JSGeneratorObject::BIT_FIELD_OFFSET);
|
2022-03-26 04:04:44 +00:00
|
|
|
GateRef bitfield = Load(VariableType::INT32(), obj, bitfieldOffset);
|
|
|
|
return Int32And(
|
2022-04-21 12:08:23 +00:00
|
|
|
Int32LSR(bitfield, Int32(JSGeneratorObject::ResumeModeBits::START_BIT)),
|
2022-03-31 09:26:17 +00:00
|
|
|
Int32((1LU << JSGeneratorObject::ResumeModeBits::SIZE) - 1));
|
2022-03-26 04:04:44 +00:00
|
|
|
}
|
|
|
|
|
2022-02-19 02:09:52 +00:00
|
|
|
void InterpreterStub::SetPcToFrame(GateRef glue, GateRef frame, GateRef value)
|
|
|
|
{
|
2022-04-14 02:57:58 +00:00
|
|
|
Store(VariableType::INT64(), glue, frame,
|
|
|
|
IntPtr(AsmInterpretedFrame::GetPcOffset(GetEnvironment()->IsArch32Bit())), value);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-03-22 03:30:26 +00:00
|
|
|
void InterpreterStub::SetCallSizeToFrame(GateRef glue, GateRef frame, GateRef value)
|
|
|
|
{
|
2022-04-16 08:54:51 +00:00
|
|
|
Store(VariableType::NATIVE_POINTER(), glue, frame,
|
2022-03-31 09:26:17 +00:00
|
|
|
IntPtr(AsmInterpretedFrame::GetCallSizeOffset(GetEnvironment()->IsArch32Bit())), value);
|
2022-03-22 03:30:26 +00:00
|
|
|
}
|
|
|
|
|
2022-02-19 02:09:52 +00:00
|
|
|
void InterpreterStub::SetAccToFrame(GateRef glue, GateRef frame, GateRef value)
|
|
|
|
{
|
2022-03-01 08:31:08 +00:00
|
|
|
Store(VariableType::INT64(), glue, frame,
|
2022-03-31 09:26:17 +00:00
|
|
|
IntPtr(AsmInterpretedFrame::GetAccOffset(GetEnvironment()->IsArch32Bit())), value);
|
2022-03-18 07:17:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InterpreterStub::SetEnvToFrame(GateRef glue, GateRef frame, GateRef value)
|
|
|
|
{
|
|
|
|
Store(VariableType::INT64(), glue, frame,
|
2022-03-31 09:26:17 +00:00
|
|
|
IntPtr(AsmInterpretedFrame::GetEnvOffset(GetEnvironment()->IsArch32Bit())), value);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InterpreterStub::SetFunctionToFrame(GateRef glue, GateRef frame, GateRef value)
|
|
|
|
{
|
2022-03-01 08:31:08 +00:00
|
|
|
Store(VariableType::INT64(), glue, frame,
|
2022-03-31 09:26:17 +00:00
|
|
|
IntPtr(AsmInterpretedFrame::GetFunctionOffset(GetEnvironment()->IsArch32Bit())), value);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-02-25 03:59:11 +00:00
|
|
|
void InterpreterStub::SetConstantPoolToFunction(GateRef glue, GateRef function, GateRef value)
|
|
|
|
{
|
|
|
|
Store(VariableType::INT64(), glue, function,
|
2022-03-31 09:26:17 +00:00
|
|
|
IntPtr(JSFunction::CONSTANT_POOL_OFFSET), value);
|
2022-02-25 03:59:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InterpreterStub::SetResolvedToFunction(GateRef glue, GateRef function, GateRef value)
|
|
|
|
{
|
|
|
|
GateRef bitfield = GetFunctionBitFieldFromJSFunction(function);
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef mask = Int32(
|
2022-02-25 03:59:11 +00:00
|
|
|
~(((1<<JSFunction::ResolvedBits::SIZE) - 1) << JSFunction::ResolvedBits::START_BIT));
|
|
|
|
GateRef result = Int32Or(Int32And(bitfield, mask),
|
2022-03-31 09:26:17 +00:00
|
|
|
Int32LSL(ZExtInt1ToInt32(value), Int32(JSFunction::ResolvedBits::START_BIT)));
|
|
|
|
Store(VariableType::INT32(), glue, function, IntPtr(JSFunction::BIT_FIELD_OFFSET), result);
|
2022-02-25 03:59:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InterpreterStub::SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef offset = IntPtr(JSFunction::HOME_OBJECT_OFFSET);
|
2022-05-20 09:24:45 +00:00
|
|
|
Store(VariableType::JS_ANY(), glue, function, offset, value);
|
2022-02-25 03:59:11 +00:00
|
|
|
}
|
|
|
|
|
2022-03-24 03:30:19 +00:00
|
|
|
void InterpreterStub::SetModuleToFunction(GateRef glue, GateRef function, GateRef value)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef offset = IntPtr(JSFunction::ECMA_MODULE_OFFSET);
|
2022-03-24 03:30:19 +00:00
|
|
|
Store(VariableType::JS_POINTER(), glue, function, offset, value);
|
|
|
|
}
|
|
|
|
|
2022-04-26 01:06:56 +00:00
|
|
|
void InterpreterStub::SetFrameState(GateRef glue, GateRef sp, GateRef function, GateRef acc,
|
|
|
|
GateRef env, GateRef pc, GateRef prev, GateRef type)
|
|
|
|
{
|
|
|
|
GateRef state = GetFrame(sp);
|
|
|
|
SetFunctionToFrame(glue, state, function);
|
|
|
|
SetAccToFrame(glue, state, acc);
|
|
|
|
SetEnvToFrame(glue, state, env);
|
|
|
|
SetPcToFrame(glue, state, pc);
|
|
|
|
GateRef prevOffset = IntPtr(AsmInterpretedFrame::GetBaseOffset(GetEnvironment()->IsArch32Bit()));
|
|
|
|
Store(VariableType::NATIVE_POINTER(), glue, state, prevOffset, prev);
|
|
|
|
GateRef frameTypeOffset = PtrAdd(prevOffset, IntPtr(
|
|
|
|
InterpretedFrameBase::GetTypeOffset(GetEnvironment()->IsArch32Bit())));
|
|
|
|
Store(VariableType::INT64(), glue, state, frameTypeOffset, type);
|
|
|
|
}
|
|
|
|
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef InterpreterStub::GetCurrentSpFrame(GateRef glue)
|
|
|
|
{
|
2022-03-09 09:53:59 +00:00
|
|
|
bool isArch32 = GetEnvironment()->Is32Bit();
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef spOffset = IntPtr(JSThread::GlueData::GetCurrentFrameOffset(isArch32));
|
2022-04-16 08:54:51 +00:00
|
|
|
return Load(VariableType::NATIVE_POINTER(), glue, spOffset);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InterpreterStub::SetCurrentSpFrame(GateRef glue, GateRef value)
|
|
|
|
{
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef spOffset = IntPtr(JSThread::GlueData::GetCurrentFrameOffset(GetEnvironment()->Is32Bit()));
|
2022-04-16 08:54:51 +00:00
|
|
|
Store(VariableType::NATIVE_POINTER(), glue, glue, spOffset, value);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-05-06 07:51:52 +00:00
|
|
|
GateRef InterpreterStub::GetLastLeaveFrame(GateRef glue)
|
|
|
|
{
|
|
|
|
bool isArch32 = GetEnvironment()->Is32Bit();
|
|
|
|
GateRef spOffset = IntPtr(JSThread::GlueData::GetLeaveFrameOffset(isArch32));
|
|
|
|
return Load(VariableType::NATIVE_POINTER(), glue, spOffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void InterpreterStub::SetLastLeaveFrame(GateRef glue, GateRef value)
|
|
|
|
{
|
|
|
|
GateRef spOffset = IntPtr(JSThread::GlueData::GetLeaveFrameOffset(GetEnvironment()->Is32Bit()));
|
|
|
|
Store(VariableType::NATIVE_POINTER(), glue, glue, spOffset, value);
|
|
|
|
}
|
|
|
|
|
2022-04-26 01:06:56 +00:00
|
|
|
GateRef InterpreterStub::CheckStackOverflow(GateRef glue, GateRef sp)
|
|
|
|
{
|
|
|
|
GateRef frameBaseOffset = IntPtr(JSThread::GlueData::GetFrameBaseOffset(GetEnvironment()->IsArch32Bit()));
|
|
|
|
GateRef frameBase = Load(VariableType::NATIVE_POINTER(), glue, frameBaseOffset);
|
|
|
|
return Int64UnsignedLessThanOrEqual(sp,
|
|
|
|
PtrAdd(frameBase, IntPtr(JSThread::RESERVE_STACK_SIZE * sizeof(JSTaggedType))));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::PushArg(GateRef glue, GateRef sp, GateRef value)
|
|
|
|
{
|
|
|
|
GateRef newSp = PointerSub(sp, IntPtr(sizeof(JSTaggedType)));
|
|
|
|
Store(VariableType::INT64(), glue, newSp, IntPtr(0), value);
|
|
|
|
return newSp;
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::PushUndefined(GateRef glue, GateRef sp, GateRef num)
|
|
|
|
{
|
|
|
|
auto env = GetEnvironment();
|
|
|
|
Label subEntry(env);
|
|
|
|
env->SubCfgEntry(&subEntry);
|
|
|
|
DEFVARIABLE(newSp, VariableType::NATIVE_POINTER(), sp);
|
|
|
|
DEFVARIABLE(i, VariableType::INT32(), Int32(0));
|
|
|
|
Label pushUndefinedBegin(env);
|
|
|
|
Label pushUndefinedAgain(env);
|
|
|
|
Label pushUndefinedEnd(env);
|
|
|
|
Branch(Int32LessThan(*i, num), &pushUndefinedBegin, &pushUndefinedEnd);
|
|
|
|
LoopBegin(&pushUndefinedBegin);
|
|
|
|
newSp = PushArg(glue, *newSp, Int64(JSTaggedValue::VALUE_UNDEFINED));
|
|
|
|
i = Int32Add(*i, Int32(1));
|
|
|
|
Branch(Int32LessThan(*i, num), &pushUndefinedAgain, &pushUndefinedEnd);
|
|
|
|
Bind(&pushUndefinedAgain);
|
|
|
|
LoopEnd(&pushUndefinedBegin);
|
|
|
|
Bind(&pushUndefinedEnd);
|
|
|
|
auto ret = *newSp;
|
|
|
|
env->SubCfgExit();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::PushRange(GateRef glue, GateRef sp, GateRef array, GateRef startIndex, GateRef endIndex)
|
|
|
|
{
|
|
|
|
auto env = GetEnvironment();
|
|
|
|
Label subEntry(env);
|
|
|
|
env->SubCfgEntry(&subEntry);
|
|
|
|
DEFVARIABLE(newSp, VariableType::NATIVE_POINTER(), sp);
|
|
|
|
DEFVARIABLE(i, VariableType::INT32(), endIndex);
|
|
|
|
Label pushArgsBegin(env);
|
|
|
|
Label pushArgsAgain(env);
|
|
|
|
Label pushArgsEnd(env);
|
|
|
|
Branch(Int32GreaterThanOrEqual(*i, startIndex), &pushArgsBegin, &pushArgsEnd);
|
|
|
|
LoopBegin(&pushArgsBegin);
|
|
|
|
GateRef arg = GetVregValue(array, ChangeInt32ToIntPtr(*i));
|
|
|
|
newSp = PushArg(glue, *newSp, arg);
|
|
|
|
i = Int32Sub(*i, Int32(1));
|
|
|
|
Branch(Int32GreaterThanOrEqual(*i, startIndex), &pushArgsAgain, &pushArgsEnd);
|
|
|
|
Bind(&pushArgsAgain);
|
|
|
|
LoopEnd(&pushArgsBegin);
|
|
|
|
Bind(&pushArgsEnd);
|
|
|
|
auto ret = *newSp;
|
|
|
|
env->SubCfgExit();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-05-12 07:50:47 +00:00
|
|
|
GateRef InterpreterStub::GetCurrentFrame(GateRef glue)
|
|
|
|
{
|
|
|
|
return GetLastLeaveFrame(glue);
|
|
|
|
}
|
|
|
|
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef InterpreterStub::ReadInst32_0(GateRef pc)
|
|
|
|
{
|
|
|
|
GateRef currentInst = ZExtInt8ToInt32(ReadInst8_3(pc));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst1 = Int32LSL(currentInst, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst2 = Int32Add(currentInst1, ZExtInt8ToInt32(ReadInst8_2(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst3 = Int32LSL(currentInst2, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst4 = Int32Add(currentInst3, ZExtInt8ToInt32(ReadInst8_1(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst5 = Int32LSL(currentInst4, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
return Int32Add(currentInst5, ZExtInt8ToInt32(ReadInst8_0(pc)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst32_1(GateRef pc)
|
|
|
|
{
|
|
|
|
GateRef currentInst = ZExtInt8ToInt32(ReadInst8_4(pc));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst1 = Int32LSL(currentInst, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst2 = Int32Add(currentInst1, ZExtInt8ToInt32(ReadInst8_3(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst3 = Int32LSL(currentInst2, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst4 = Int32Add(currentInst3, ZExtInt8ToInt32(ReadInst8_2(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst5 = Int32LSL(currentInst4, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
return Int32Add(currentInst5, ZExtInt8ToInt32(ReadInst8_1(pc)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst32_2(GateRef pc)
|
|
|
|
{
|
|
|
|
GateRef currentInst = ZExtInt8ToInt32(ReadInst8_5(pc));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst1 = Int32LSL(currentInst, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst2 = Int32Add(currentInst1, ZExtInt8ToInt32(ReadInst8_4(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst3 = Int32LSL(currentInst2, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst4 = Int32Add(currentInst3, ZExtInt8ToInt32(ReadInst8_3(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst5 = Int32LSL(currentInst4, Int32(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
return Int32Add(currentInst5, ZExtInt8ToInt32(ReadInst8_2(pc)));
|
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::ReadInst64_0(GateRef pc)
|
|
|
|
{
|
|
|
|
GateRef currentInst = ZExtInt8ToInt64(ReadInst8_7(pc));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst1 = Int64LSL(currentInst, Int64(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst2 = Int64Add(currentInst1, ZExtInt8ToInt64(ReadInst8_6(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst3 = Int64LSL(currentInst2, Int64(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst4 = Int64Add(currentInst3, ZExtInt8ToInt64(ReadInst8_5(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst5 = Int64LSL(currentInst4, Int64(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst6 = Int64Add(currentInst5, ZExtInt8ToInt64(ReadInst8_4(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst7 = Int64LSL(currentInst6, Int64(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst8 = Int64Add(currentInst7, ZExtInt8ToInt64(ReadInst8_3(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst9 = Int64LSL(currentInst8, Int64(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst10 = Int64Add(currentInst9, ZExtInt8ToInt64(ReadInst8_2(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst11 = Int64LSL(currentInst10, Int64(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef currentInst12 = Int64Add(currentInst11, ZExtInt8ToInt64(ReadInst8_1(pc)));
|
2022-03-31 09:26:17 +00:00
|
|
|
GateRef currentInst13 = Int64LSL(currentInst12, Int64(8));
|
2022-02-19 02:09:52 +00:00
|
|
|
return Int64Add(currentInst13, ZExtInt8ToInt64(ReadInst8_0(pc)));
|
|
|
|
}
|
|
|
|
|
2022-03-21 07:18:47 +00:00
|
|
|
template<typename... Args>
|
2022-05-15 02:41:02 +00:00
|
|
|
void InterpreterStub::DispatchBase(GateRef target, GateRef glue, Args... args)
|
2022-03-21 07:18:47 +00:00
|
|
|
{
|
2022-05-15 02:41:02 +00:00
|
|
|
GetEnvironment()->GetBulder()->CallBCHandler(glue, target, {glue, args...});
|
2022-03-21 07:18:47 +00:00
|
|
|
}
|
|
|
|
|
2022-04-24 01:07:45 +00:00
|
|
|
void InterpreterStub::Dispatch(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, GateRef profileTypeInfo,
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef acc, GateRef hotnessCounter, GateRef format)
|
|
|
|
{
|
2022-04-21 12:08:23 +00:00
|
|
|
GateRef newPc = PtrAdd(pc, format);
|
2022-03-01 08:31:08 +00:00
|
|
|
GateRef opcode = Load(VariableType::INT8(), newPc);
|
2022-05-15 02:41:02 +00:00
|
|
|
GateRef target = PtrMul(ChangeInt32ToIntPtr(ZExtInt8ToInt32(opcode)), IntPtrSize());
|
|
|
|
DispatchBase(target, glue, sp, newPc, constpool, profileTypeInfo, acc, hotnessCounter);
|
2022-02-19 02:09:52 +00:00
|
|
|
Return();
|
|
|
|
}
|
|
|
|
|
2022-04-24 01:07:45 +00:00
|
|
|
void InterpreterStub::DispatchLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter)
|
|
|
|
{
|
2022-05-15 02:41:02 +00:00
|
|
|
GateRef target = PtrMul(IntPtr(BytecodeStubCSigns::ID_ExceptionHandler), IntPtrSize());
|
|
|
|
DispatchBase(target, glue, sp, pc, constpool, profileTypeInfo, acc, hotnessCounter);
|
2022-03-21 07:18:47 +00:00
|
|
|
Return();
|
|
|
|
}
|
|
|
|
|
2022-04-21 12:58:15 +00:00
|
|
|
void InterpreterStub::DispatchDebugger(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
|
|
|
|
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter)
|
|
|
|
{
|
|
|
|
GateRef opcode = Load(VariableType::INT8(), pc);
|
2022-05-15 02:41:02 +00:00
|
|
|
GateRef target = PtrMul(ChangeInt32ToIntPtr(ZExtInt8ToInt32(opcode)), IntPtrSize());
|
|
|
|
auto args = { glue, sp, pc, constpool, profileTypeInfo, acc, hotnessCounter };
|
|
|
|
GetEnvironment()->GetBulder()->CallBCDebugger(glue, target, args);
|
2022-04-21 12:58:15 +00:00
|
|
|
Return();
|
|
|
|
}
|
|
|
|
|
|
|
|
void InterpreterStub::DispatchDebuggerLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
|
|
|
|
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter)
|
|
|
|
{
|
2022-05-15 02:41:02 +00:00
|
|
|
GateRef target = PtrMul(IntPtr(BytecodeStubCSigns::ID_ExceptionHandler), IntPtrSize());
|
|
|
|
auto args = { glue, sp, pc, constpool, profileTypeInfo, acc, hotnessCounter };
|
|
|
|
GetEnvironment()->GetBulder()->CallBCDebugger(glue, target, args);
|
2022-04-21 12:58:15 +00:00
|
|
|
Return();
|
|
|
|
}
|
|
|
|
|
2022-02-19 02:09:52 +00:00
|
|
|
GateRef InterpreterStub::GetObjectFromConstPool(GateRef constpool, GateRef index)
|
|
|
|
{
|
2022-03-01 08:31:08 +00:00
|
|
|
return GetValueFromTaggedArray(VariableType::JS_ANY(), constpool, index);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GateRef InterpreterStub::FunctionIsResolved(GateRef object)
|
|
|
|
{
|
2022-02-25 03:59:11 +00:00
|
|
|
GateRef bitfield = GetFunctionBitFieldFromJSFunction(object);
|
2022-02-19 02:09:52 +00:00
|
|
|
// decode
|
|
|
|
return Int32NotEqual(
|
|
|
|
Int32And(
|
2022-04-21 12:08:23 +00:00
|
|
|
Int32LSR(bitfield, Int32(JSFunction::ResolvedBits::START_BIT)),
|
2022-03-31 09:26:17 +00:00
|
|
|
Int32((1LU << JSFunction::ResolvedBits::SIZE) - 1)),
|
|
|
|
Int32(0));
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
2022-04-27 12:43:40 +00:00
|
|
|
|
|
|
|
GateRef InterpreterStub::GetHotnessCounterFromMethod(GateRef method)
|
|
|
|
{
|
|
|
|
auto env = GetEnvironment();
|
|
|
|
GateRef x = Load(VariableType::INT16(), method,
|
|
|
|
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit())));
|
2022-05-10 12:52:16 +00:00
|
|
|
return GetEnvironment()->GetBulder()->UnaryArithmetic(OpCode(OpCode::SEXT_TO_INT32), x);
|
2022-04-27 12:43:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InterpreterStub::SetHotnessCounter(GateRef glue, GateRef method, GateRef value)
|
|
|
|
{
|
|
|
|
auto env = GetEnvironment();
|
2022-05-10 12:52:16 +00:00
|
|
|
GateRef newValue = env->GetBulder()->UnaryArithmetic(OpCode(OpCode::TRUNC_TO_INT16), value);
|
2022-04-27 12:43:40 +00:00
|
|
|
Store(VariableType::INT16(), glue, method,
|
|
|
|
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit())), newValue);
|
|
|
|
}
|
2022-06-09 02:30:14 +00:00
|
|
|
|
|
|
|
void InterpreterStub::DispatchWithId(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
|
|
|
|
GateRef profileTypeInfo, GateRef acc,
|
|
|
|
GateRef hotnessCounter, int index)
|
|
|
|
{
|
|
|
|
GateRef target = PtrMul(IntPtr(index), IntPtrSize());
|
|
|
|
DispatchBase(target, glue, sp, pc, constpool, profileTypeInfo, acc, hotnessCounter);
|
|
|
|
Return();
|
|
|
|
}
|
2022-02-19 02:09:52 +00:00
|
|
|
} // namespace panda::ecmascript::kungfu
|
|
|
|
#endif // ECMASCRIPT_COMPILER_INTERPRETER_STUB_INL_H
|