• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ECMASCRIPT_COMPILER_INTERPRETER_STUB_INL_H
17 #define ECMASCRIPT_COMPILER_INTERPRETER_STUB_INL_H
18 
19 #include "ecmascript/compiler/interpreter_stub.h"
20 
21 namespace panda::ecmascript::kungfu {
SetVregValue(GateRef glue,GateRef sp,GateRef idx,GateRef val)22 void InterpreterStub::SetVregValue(GateRef glue, GateRef sp, GateRef idx, GateRef val)
23 {
24     Store(StubMachineType::UINT64, glue, sp, IntPtrMul(GetIntPtrConstant(sizeof(JSTaggedType)), idx), val);
25 }
26 
GetVregValue(GateRef sp,GateRef idx)27 GateRef InterpreterStub::GetVregValue(GateRef sp, GateRef idx)
28 {
29     return Load(StubMachineType::TAGGED, sp, IntPtrMul(GetIntPtrConstant(sizeof(JSTaggedType)), idx));
30 }
31 
ReadInst8_0(GateRef pc)32 GateRef InterpreterStub::ReadInst8_0(GateRef pc)
33 {
34     return Load(StubMachineType::UINT8, pc, GetIntPtrConstant(1));
35 }
36 
ReadInst8_1(GateRef pc)37 GateRef InterpreterStub::ReadInst8_1(GateRef pc)
38 {
39     return Load(StubMachineType::UINT8, pc, GetIntPtrConstant(2));  // 2 : skip 1 byte of bytecode
40 }
41 
ReadInst8_2(GateRef pc)42 GateRef InterpreterStub::ReadInst8_2(GateRef pc)
43 {
44     return Load(StubMachineType::UINT8, pc, GetIntPtrConstant(3));  // 3 : skip 1 byte of bytecode
45 }
46 
ReadInst8_3(GateRef pc)47 GateRef InterpreterStub::ReadInst8_3(GateRef pc)
48 {
49     return Load(StubMachineType::UINT8, pc, GetIntPtrConstant(4));  // 4 : skip 1 byte of bytecode
50 }
51 
ReadInst8_4(GateRef pc)52 GateRef InterpreterStub::ReadInst8_4(GateRef pc)
53 {
54     return Load(StubMachineType::UINT8, pc, GetIntPtrConstant(5));  // 5 : skip 1 byte of bytecode
55 }
56 
ReadInst8_5(GateRef pc)57 GateRef InterpreterStub::ReadInst8_5(GateRef pc)
58 {
59     return Load(StubMachineType::UINT8, pc, GetIntPtrConstant(6));  // 6 : skip 1 byte of bytecode
60 }
61 
ReadInst8_6(GateRef pc)62 GateRef InterpreterStub::ReadInst8_6(GateRef pc)
63 {
64     return Load(StubMachineType::UINT8, pc, GetIntPtrConstant(7));  // 7 : skip 1 byte of bytecode
65 }
66 
ReadInst8_7(GateRef pc)67 GateRef InterpreterStub::ReadInst8_7(GateRef pc)
68 {
69     return Load(StubMachineType::UINT8, pc, GetIntPtrConstant(8));  // 8 : skip 1 byte of bytecode
70 }
71 
ReadInst8_8(GateRef pc)72 GateRef InterpreterStub::ReadInst8_8(GateRef pc)
73 {
74     return Load(StubMachineType::UINT8, pc, GetIntPtrConstant(9));  // 9 : skip 1 byte of bytecode
75 }
76 
ReadInst4_0(GateRef pc)77 GateRef InterpreterStub::ReadInst4_0(GateRef pc)
78 {
79     return Int8And(Load(StubMachineType::UINT8, pc, GetIntPtrConstant(1)), GetInt8Constant(0xf));
80 }
81 
ReadInst4_1(GateRef pc)82 GateRef InterpreterStub::ReadInst4_1(GateRef pc)
83 {
84     return Int8And(Int8LSR(Load(StubMachineType::UINT8, pc, GetIntPtrConstant(1)),
85         GetInt8Constant(4)), GetInt8Constant(0xf)); // 4 : read 4 byte of bytecode
86 }
87 
ReadInst4_2(GateRef pc)88 GateRef InterpreterStub::ReadInst4_2(GateRef pc)
89 {
90     // 2 : skip 1 byte of bytecode
91     return Int8And(Load(StubMachineType::UINT8, pc, GetIntPtrConstant(2)), GetInt8Constant(0xf));
92 }
93 
ReadInst4_3(GateRef pc)94 GateRef InterpreterStub::ReadInst4_3(GateRef pc)
95 {
96     // 4: read 4 byte of bytecode
97     return Int8And(
98         Int8LSR(Load(StubMachineType::UINT8, pc, GetIntPtrConstant(2)), GetInt8Constant(4)), GetInt8Constant(0xf));
99 }
100 
ReadInstSigned8_0(GateRef pc)101 GateRef InterpreterStub::ReadInstSigned8_0(GateRef pc)
102 {
103     GateRef x = Load(StubMachineType::INT8, pc, GetIntPtrConstant(1));
104     return GetEnvironment()->GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SEXT_TO_INT32), x);
105 }
106 
ReadInstSigned16_0(GateRef pc)107 GateRef InterpreterStub::ReadInstSigned16_0(GateRef pc)
108 {
109     /* 2 : skip 8 bits of opcode and 8 bits of low bits */
110     GateRef currentInst = Load(StubMachineType::INT8, pc, GetIntPtrConstant(2));
111     GateRef currentInst1 = GetEnvironment()->GetCircuitBuilder().NewArithmeticGate(
112         OpCode(OpCode::SEXT_TO_INT32), currentInst);
113     GateRef currentInst2 = Int32LSL(currentInst1, GetInt32Constant(8));  // 8 : set as high 8 bits
114     return Int32Add(currentInst2, ZExtInt8ToInt32(ReadInst8_0(pc)));
115 }
116 
ReadInstSigned32_0(GateRef pc)117 GateRef InterpreterStub::ReadInstSigned32_0(GateRef pc)
118 {
119     /* 4 : skip 8 bits of opcode and 24 bits of low bits */
120     GateRef x = Load(StubMachineType::INT8, pc, GetIntPtrConstant(4));
121     GateRef currentInst = GetEnvironment()->GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SEXT_TO_INT32), x);
122     GateRef currentInst1 = Int32LSL(currentInst, GetInt32Constant(8));
123     GateRef currentInst2 = Int32Add(currentInst1, ZExtInt8ToInt32(ReadInst8_2(pc)));
124     GateRef currentInst3 = Int32LSL(currentInst2, GetInt32Constant(8));
125     GateRef currentInst4 = Int32Add(currentInst3, ZExtInt8ToInt32(ReadInst8_1(pc)));
126     GateRef currentInst5 = Int32LSL(currentInst4, GetInt32Constant(8));
127     return Int32Add(currentInst5, ZExtInt8ToInt32(ReadInst8_0(pc)));
128 }
129 
ReadInst16_0(GateRef pc)130 GateRef InterpreterStub::ReadInst16_0(GateRef pc)
131 {
132     /* 2 : skip 8 bits of opcode and 8 bits of low bits */
133     GateRef currentInst1 = ZExtInt8ToInt16(ReadInst8_1(pc));
134     GateRef currentInst2 = Int16LSL(currentInst1, GetInt16Constant(8));  // 8 : set as high 8 bits
135     return Int16Add(currentInst2, ZExtInt8ToInt16(ReadInst8_0(pc)));
136 }
137 
ReadInst16_1(GateRef pc)138 GateRef InterpreterStub::ReadInst16_1(GateRef pc)
139 {
140     /* 3 : skip 8 bits of opcode, 8 bits of prefix and 8 bits of low bits */
141     GateRef currentInst1 = ZExtInt8ToInt16(ReadInst8_2(pc));
142     GateRef currentInst2 = Int16LSL(currentInst1, GetInt16Constant(8));  // 8 : set as high 8 bits
143     /* 2: skip 8 bits of opcode and 8 bits of prefix */
144     return Int16Add(currentInst2, ZExtInt8ToInt16(ReadInst8_1(pc)));
145 }
146 
ReadInst16_2(GateRef pc)147 GateRef InterpreterStub::ReadInst16_2(GateRef pc)
148 {
149     /* 4 : skip 8 bits of opcode, first parameter of 16 bits and 8 bits of low bits */
150     GateRef currentInst1 = ZExtInt8ToInt16(ReadInst8_3(pc));
151     GateRef currentInst2 = Int16LSL(currentInst1, GetInt16Constant(8));  // 8 : set as high 8 bits
152     /* 3: skip 8 bits of opcode and first parameter of 16 bits */
153     return Int16Add(currentInst2, ZExtInt8ToInt16(ReadInst8_2(pc)));
154 }
155 
ReadInst16_3(GateRef pc)156 GateRef InterpreterStub::ReadInst16_3(GateRef pc)
157 {
158     /* 5 : skip 8 bits of opcode, 8 bits of prefix, first parameter of 16 bits and 8 bits of low bits */
159     GateRef currentInst1 = ZExtInt8ToInt16(ReadInst8_4(pc));
160     GateRef currentInst2 = Int16LSL(currentInst1, GetInt16Constant(8));  // 8 : set as high 8 bits
161     /* 4: skip 8 bits of opcode, 8 bits of prefix and first parameter of 16 bits */
162     return Int16Add(currentInst2, ZExtInt8ToInt16(ReadInst8_3(pc)));
163 }
164 
ReadInst16_5(GateRef pc)165 GateRef InterpreterStub::ReadInst16_5(GateRef pc)
166 {
167     /* 7 : skip 8 bits of opcode, 8 bits of prefix, first 2 parameters of 16 bits and 8 bits of low bits */
168     GateRef currentInst1 = ZExtInt8ToInt16(ReadInst8_6(pc));
169     GateRef currentInst2 = Int16LSL(currentInst1, GetInt16Constant(8));  // 8 : set as high 8 bits
170     /* 6: skip 8 bits of opcode, 8 bits of prefix and first 2 parameters of 16 bits */
171     return Int16Add(currentInst2, ZExtInt8ToInt16(ReadInst8_5(pc)));
172 }
173 
GetFrame(GateRef CurrentSp)174 GateRef InterpreterStub::GetFrame(GateRef CurrentSp)
175 {
176     return IntPtrSub(CurrentSp, GetIntPtrConstant(InterpretedFrame::GetSize(GetEnvironment()->IsArch32Bit())));
177 }
178 
GetPcFromFrame(GateRef frame)179 GateRef InterpreterStub::GetPcFromFrame(GateRef frame)
180 {
181     return Load(StubMachineType::NATIVE_POINTER, frame, GetIntPtrConstant(0));
182 }
183 
GetFunctionFromFrame(GateRef frame)184 GateRef InterpreterStub::GetFunctionFromFrame(GateRef frame)
185 {
186     return Load(StubMachineType::TAGGED_POINTER, frame,
187         GetIntPtrConstant(InterpretedFrame::GetFunctionOffset(GetEnvironment()->IsArch32Bit())));
188 }
189 
GetAccFromFrame(GateRef frame)190 GateRef InterpreterStub::GetAccFromFrame(GateRef frame)
191 {
192     return Load(StubMachineType::TAGGED, frame,
193         GetIntPtrConstant(InterpretedFrame::GetAccOffset(GetEnvironment()->IsArch32Bit())));
194 }
195 
GetEnvFromFrame(GateRef frame)196 GateRef InterpreterStub::GetEnvFromFrame(GateRef frame)
197 {
198     return Load(StubMachineType::TAGGED_POINTER, frame,
199         GetIntPtrConstant(InterpretedFrame::GetEnvOffset(GetEnvironment()->IsArch32Bit())));
200 }
201 
GetProfileTypeInfoFromFunction(GateRef function)202 GateRef InterpreterStub::GetProfileTypeInfoFromFunction(GateRef function)
203 {
204     return Load(StubMachineType::TAGGED_POINTER, function, GetIntPtrConstant(JSFunction::PROFILE_TYPE_INFO_OFFSET));
205 }
206 
GetConstpoolFromFunction(GateRef function)207 GateRef InterpreterStub::GetConstpoolFromFunction(GateRef function)
208 {
209     return Load(StubMachineType::TAGGED_POINTER, function, GetIntPtrConstant(JSFunction::CONSTANT_POOL_OFFSET));
210 }
211 
SetEnvToFrame(GateRef glue,GateRef frame,GateRef value)212 void InterpreterStub::SetEnvToFrame(GateRef glue, GateRef frame, GateRef value)
213 {
214     Store(StubMachineType::UINT64, glue, frame,
215         GetIntPtrConstant(InterpretedFrame::GetEnvOffset(GetEnvironment()->IsArch32Bit())), value);
216 }
217 
SetPcToFrame(GateRef glue,GateRef frame,GateRef value)218 void InterpreterStub::SetPcToFrame(GateRef glue, GateRef frame, GateRef value)
219 {
220     Store(StubMachineType::UINT64, glue, frame, GetIntPtrConstant(0), value);
221 }
222 
SetAccToFrame(GateRef glue,GateRef frame,GateRef value)223 void InterpreterStub::SetAccToFrame(GateRef glue, GateRef frame, GateRef value)
224 {
225     Store(StubMachineType::UINT64, glue, frame,
226           GetIntPtrConstant(InterpretedFrame::GetAccOffset(GetEnvironment()->IsArch32Bit())), value);
227 }
228 
SetFunctionToFrame(GateRef glue,GateRef frame,GateRef value)229 void InterpreterStub::SetFunctionToFrame(GateRef glue, GateRef frame, GateRef value)
230 {
231     Store(StubMachineType::UINT64, glue, frame,
232           GetIntPtrConstant(InterpretedFrame::GetFunctionOffset(GetEnvironment()->IsArch32Bit())), value);
233 }
234 
GetCurrentSpFrame(GateRef glue)235 GateRef InterpreterStub::GetCurrentSpFrame(GateRef glue)
236 {
237     GateRef spOffset = GetIntPtrConstant(
238         GetEnvironment()->GetGlueOffset(JSThread::GlueID::CURRENT_FRAME));
239     return Load(StubMachineType::NATIVE_POINTER, glue, spOffset);
240 }
241 
SetCurrentSpFrame(GateRef glue,GateRef value)242 void InterpreterStub::SetCurrentSpFrame(GateRef glue, GateRef value)
243 {
244     GateRef spOffset = GetIntPtrConstant(
245         GetEnvironment()->GetGlueOffset(JSThread::GlueID::CURRENT_FRAME));
246     Store(StubMachineType::NATIVE_POINTER, glue, glue, spOffset, value);
247 }
248 
ReadInst32_0(GateRef pc)249 GateRef InterpreterStub::ReadInst32_0(GateRef pc)
250 {
251     GateRef currentInst = ZExtInt8ToInt32(ReadInst8_3(pc));
252     GateRef currentInst1 = Int32LSL(currentInst, GetInt32Constant(8));
253     GateRef currentInst2 = Int32Add(currentInst1, ZExtInt8ToInt32(ReadInst8_2(pc)));
254     GateRef currentInst3 = Int32LSL(currentInst2, GetInt32Constant(8));
255     GateRef currentInst4 = Int32Add(currentInst3, ZExtInt8ToInt32(ReadInst8_1(pc)));
256     GateRef currentInst5 = Int32LSL(currentInst4, GetInt32Constant(8));
257     return Int32Add(currentInst5, ZExtInt8ToInt32(ReadInst8_0(pc)));
258 }
259 
ReadInst32_1(GateRef pc)260 GateRef InterpreterStub::ReadInst32_1(GateRef pc)
261 {
262     GateRef currentInst = ZExtInt8ToInt32(ReadInst8_4(pc));
263     GateRef currentInst1 = Int32LSL(currentInst, GetInt32Constant(8));
264     GateRef currentInst2 = Int32Add(currentInst1, ZExtInt8ToInt32(ReadInst8_3(pc)));
265     GateRef currentInst3 = Int32LSL(currentInst2, GetInt32Constant(8));
266     GateRef currentInst4 = Int32Add(currentInst3, ZExtInt8ToInt32(ReadInst8_2(pc)));
267     GateRef currentInst5 = Int32LSL(currentInst4, GetInt32Constant(8));
268     return Int32Add(currentInst5, ZExtInt8ToInt32(ReadInst8_1(pc)));
269 }
270 
ReadInst32_2(GateRef pc)271 GateRef InterpreterStub::ReadInst32_2(GateRef pc)
272 {
273     GateRef currentInst = ZExtInt8ToInt32(ReadInst8_5(pc));
274     GateRef currentInst1 = Int32LSL(currentInst, GetInt32Constant(8));
275     GateRef currentInst2 = Int32Add(currentInst1, ZExtInt8ToInt32(ReadInst8_4(pc)));
276     GateRef currentInst3 = Int32LSL(currentInst2, GetInt32Constant(8));
277     GateRef currentInst4 = Int32Add(currentInst3, ZExtInt8ToInt32(ReadInst8_3(pc)));
278     GateRef currentInst5 = Int32LSL(currentInst4, GetInt32Constant(8));
279     return Int32Add(currentInst5, ZExtInt8ToInt32(ReadInst8_2(pc)));
280 }
281 
ReadInst64_0(GateRef pc)282 GateRef InterpreterStub::ReadInst64_0(GateRef pc)
283 {
284     GateRef currentInst = ZExtInt8ToInt64(ReadInst8_7(pc));
285     GateRef currentInst1 = Int64LSL(currentInst, GetInt64Constant(8));
286     GateRef currentInst2 = Int64Add(currentInst1, ZExtInt8ToInt64(ReadInst8_6(pc)));
287     GateRef currentInst3 = Int64LSL(currentInst2, GetInt64Constant(8));
288     GateRef currentInst4 = Int64Add(currentInst3, ZExtInt8ToInt64(ReadInst8_5(pc)));
289     GateRef currentInst5 = Int64LSL(currentInst4, GetInt64Constant(8));
290     GateRef currentInst6 = Int64Add(currentInst5, ZExtInt8ToInt64(ReadInst8_4(pc)));
291     GateRef currentInst7 = Int64LSL(currentInst6, GetInt64Constant(8));
292     GateRef currentInst8 = Int64Add(currentInst7, ZExtInt8ToInt64(ReadInst8_3(pc)));
293     GateRef currentInst9 = Int64LSL(currentInst8, GetInt64Constant(8));
294     GateRef currentInst10 = Int64Add(currentInst9, ZExtInt8ToInt64(ReadInst8_2(pc)));
295     GateRef currentInst11 = Int64LSL(currentInst10, GetInt64Constant(8));
296     GateRef currentInst12 = Int64Add(currentInst11, ZExtInt8ToInt64(ReadInst8_1(pc)));
297     GateRef currentInst13 = Int64LSL(currentInst12, GetInt64Constant(8));
298     return Int64Add(currentInst13, ZExtInt8ToInt64(ReadInst8_0(pc)));
299 }
300 
Dispatch(GateRef glue,GateRef pc,GateRef sp,GateRef constpool,GateRef profileTypeInfo,GateRef acc,GateRef hotnessCounter,GateRef format)301 void InterpreterStub::Dispatch(GateRef glue, GateRef pc, GateRef sp, GateRef constpool, GateRef profileTypeInfo,
302                                GateRef acc, GateRef hotnessCounter, GateRef format)
303 {
304     GateRef newPc = IntPtrAdd(pc, format);
305     GateRef opcode = Load(StubMachineType::UINT8, newPc);
306     GateRef opcodeOffset = IntPtrMul(
307         ChangeInt32ToIntPtr(ZExtInt8ToInt32(opcode)), GetIntPtrSize());
308     StubDescriptor *bytecodeHandler = GET_STUBDESCRIPTOR(BytecodeHandler);
309     auto depend = GetEnvironment()->GetCurrentLabel()->GetDepend();
310     GateRef result = GetEnvironment()->GetCircuitBuilder().NewBytecodeCallGate(bytecodeHandler, glue, opcodeOffset,
311         depend, {glue, newPc, sp, constpool, profileTypeInfo, acc, hotnessCounter});
312     GetEnvironment()->GetCurrentLabel()->SetDepend(result);
313     Return();
314 }
315 
DispatchLast(GateRef glue,GateRef pc,GateRef sp,GateRef constpool,GateRef profileTypeInfo,GateRef acc,GateRef hotnessCounter)316 void InterpreterStub::DispatchLast(GateRef glue, GateRef pc, GateRef sp, GateRef constpool,
317                                    GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter)
318 {
319     GateRef opcodeOffset = IntPtrMul(
320         GetIntPtrConstant(EcmaOpcode::LAST_OPCODE), GetIntPtrSize());
321     StubDescriptor *bytecodeHandler = GET_STUBDESCRIPTOR(BytecodeHandler);
322     auto depend = GetEnvironment()->GetCurrentLabel()->GetDepend();
323     GateRef result = GetEnvironment()->GetCircuitBuilder().NewBytecodeCallGate(bytecodeHandler, glue, opcodeOffset,
324         depend, {glue, pc, sp, constpool, profileTypeInfo, acc, hotnessCounter});
325     GetEnvironment()->GetCurrentLabel()->SetDepend(result);
326     Return();
327 }
328 
GetObjectFromConstPool(GateRef constpool,GateRef index)329 GateRef InterpreterStub::GetObjectFromConstPool(GateRef constpool, GateRef index)
330 {
331     return GetValueFromTaggedArray(StubMachineType::TAGGED, constpool, index);
332 }
333 
FunctionIsResolved(GateRef object)334 GateRef InterpreterStub::FunctionIsResolved(GateRef object)
335 {
336     GateRef bitfield = TaggedGetInt(GetFunctionBitFieldFromJSFunction(object));
337     // decode
338     return Int32NotEqual(
339         Int32And(
340             UInt32LSR(bitfield, GetInt32Constant(JSFunction::ResolvedBits::START_BIT)),
341             GetInt32Constant((1LU << JSFunction::ResolvedBits::SIZE) - 1)),
342         GetInt32Constant(0));
343 }
344 } //  namespace panda::ecmascript::kungfu
345 #endif // ECMASCRIPT_COMPILER_INTERPRETER_STUB_INL_H
346