1 /*
2 * Copyright (c) 2021-2022 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 #include "ecmascript/jspandafile/panda_file_translator.h"
17
18 #include "ecmascript/aot_file_manager.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/interpreter/interpreter-inl.h"
21 #include "ecmascript/jspandafile/class_info_extractor.h"
22 #include "ecmascript/jspandafile/literal_data_extractor.h"
23 #include "ecmascript/jspandafile/js_pandafile_manager.h"
24 #include "ecmascript/jspandafile/program_object.h"
25 #include "ecmascript/js_array.h"
26 #include "ecmascript/js_function.h"
27 #include "ecmascript/js_thread.h"
28 #include "ecmascript/object_factory.h"
29 #include "ecmascript/tagged_array.h"
30 #include "ecmascript/ts_types/ts_manager.h"
31 #include "ecmascript/ts_types/ts_type_table.h"
32 #include "libpandabase/utils/utf.h"
33 #include "libpandafile/class_data_accessor-inl.h"
34
35 namespace panda::ecmascript {
36 template<class T, class... Args>
InitializeMemory(T * mem,Args...args)37 static T *InitializeMemory(T *mem, Args... args)
38 {
39 return new (mem) T(std::forward<Args>(args)...);
40 }
41
TranslateClasses(JSPandaFile * jsPandaFile,const CString & methodName)42 void PandaFileTranslator::TranslateClasses(JSPandaFile *jsPandaFile, const CString &methodName)
43 {
44 ASSERT(jsPandaFile != nullptr && jsPandaFile->GetMethodLiterals() != nullptr);
45 MethodLiteral *methodLiterals = jsPandaFile->GetMethodLiterals();
46 const panda_file::File *pf = jsPandaFile->GetPandaFile();
47 size_t methodIdx = 0;
48 std::set<const uint8_t *> translatedCode;
49 Span<const uint32_t> classIndexes = jsPandaFile->GetClasses();
50 for (const uint32_t index : classIndexes) {
51 panda_file::File::EntityId classId(index);
52 if (pf->IsExternal(classId)) {
53 continue;
54 }
55 panda_file::ClassDataAccessor cda(*pf, classId);
56 CString recordName = jsPandaFile->ParseEntryPoint(utf::Mutf8AsCString(cda.GetDescriptor()));
57 bool isUpdateMainMethodIndex = false;
58 cda.EnumerateMethods([jsPandaFile, &translatedCode, methodLiterals, &methodIdx, pf, &methodName, &recordName,
59 &isUpdateMainMethodIndex]
60 (panda_file::MethodDataAccessor &mda) {
61 auto codeId = mda.GetCodeId();
62 auto methodId = mda.GetMethodId();
63 ASSERT(codeId.has_value());
64
65 MethodLiteral *methodLiteral = methodLiterals + (methodIdx++);
66 panda_file::CodeDataAccessor codeDataAccessor(*pf, codeId.value());
67 uint32_t codeSize = codeDataAccessor.GetCodeSize();
68
69 CString name = reinterpret_cast<const char *>(pf->GetStringData(mda.GetNameId()).data);
70 auto methodOffset = methodId.GetOffset();
71 if (jsPandaFile->IsBundlePack()) {
72 if (!isUpdateMainMethodIndex && name == methodName) {
73 jsPandaFile->UpdateMainMethodIndex(methodOffset);
74 isUpdateMainMethodIndex = true;
75 }
76 } else {
77 if (!isUpdateMainMethodIndex && JSPandaFile::IsEntryOrPatch(name)) {
78 jsPandaFile->UpdateMainMethodIndex(methodOffset, recordName);
79 isUpdateMainMethodIndex = true;
80 }
81 }
82
83 InitializeMemory(methodLiteral, jsPandaFile, methodId);
84 methodLiteral->SetHotnessCounter(EcmaInterpreter::GetHotnessCounter(codeSize));
85 methodLiteral->Initialize(jsPandaFile, codeDataAccessor.GetNumVregs(), codeDataAccessor.GetNumArgs());
86 if (jsPandaFile->IsNewVersion()) {
87 panda_file::IndexAccessor indexAccessor(*pf, methodId);
88 panda_file::FunctionKind funcKind = indexAccessor.GetFunctionKind();
89 FunctionKind kind = JSPandaFile::GetFunctionKind(funcKind);
90 methodLiteral->SetFunctionKind(kind);
91 } else {
92 const uint8_t *insns = codeDataAccessor.GetInstructions();
93 if (translatedCode.find(insns) == translatedCode.end()) {
94 translatedCode.insert(insns);
95 if (jsPandaFile->IsBundlePack()) {
96 TranslateBytecode(jsPandaFile, codeSize, insns, methodLiteral);
97 } else {
98 TranslateBytecode(jsPandaFile, codeSize, insns, methodLiteral, recordName);
99 }
100 }
101 }
102 jsPandaFile->SetMethodLiteralToMap(methodLiteral);
103 });
104 }
105 }
106
GenerateProgram(EcmaVM * vm,const JSPandaFile * jsPandaFile,std::string_view entryPoint)107 JSHandle<Program> PandaFileTranslator::GenerateProgram(EcmaVM *vm, const JSPandaFile *jsPandaFile,
108 std::string_view entryPoint)
109 {
110 uint32_t mainMethodIndex = jsPandaFile->GetMainMethodIndex(entryPoint.data());
111 JSHandle<ConstantPool> constpool;
112 bool isNewVersion = jsPandaFile->IsNewVersion();
113 if (isNewVersion) {
114 constpool = vm->FindOrCreateConstPool(jsPandaFile, panda_file::File::EntityId(mainMethodIndex));
115 } else {
116 JSTaggedValue constpoolVal = vm->FindConstpool(jsPandaFile, 0);
117 if (constpoolVal.IsHole()) {
118 constpool = ParseConstPool(vm, jsPandaFile);
119 // old version dont support multi constpool
120 vm->AddConstpool(jsPandaFile, constpool.GetTaggedValue());
121 } else {
122 constpool = JSHandle<ConstantPool>(vm->GetJSThread(), constpoolVal);
123 }
124
125 if (!jsPandaFile->IsBundlePack()) {
126 ParseFuncAndLiteralConstPool(vm, jsPandaFile, entryPoint.data(), constpool);
127 }
128 }
129
130 return GenerateProgramInternal(vm, jsPandaFile, mainMethodIndex, constpool);
131 }
132
GenerateProgramInternal(EcmaVM * vm,const JSPandaFile * jsPandaFile,uint32_t mainMethodIndex,JSHandle<ConstantPool> constpool)133 JSHandle<Program> PandaFileTranslator::GenerateProgramInternal(EcmaVM *vm, const JSPandaFile *jsPandaFile,
134 uint32_t mainMethodIndex,
135 JSHandle<ConstantPool> constpool)
136 {
137 JSThread *thread = vm->GetJSThread();
138 ObjectFactory *factory = vm->GetFactory();
139 JSHandle<Program> program = factory->NewProgram();
140
141 [[maybe_unused]] EcmaHandleScope handleScope(thread);
142 auto methodLiteral = jsPandaFile->FindMethodLiteral(mainMethodIndex);
143 if (methodLiteral == nullptr) {
144 program->SetMainFunction(thread, JSTaggedValue::Undefined());
145 } else {
146 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
147 JSHandle<Method> method = factory->NewMethod(methodLiteral);
148 JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto());
149 JSHandle<JSFunction> mainFunc = factory->NewJSFunctionByHClass(method, hclass);
150
151 program->SetMainFunction(thread, mainFunc.GetTaggedValue());
152 method->SetConstantPool(thread, constpool);
153 }
154 return program;
155 }
156
ParseConstPool(EcmaVM * vm,const JSPandaFile * jsPandaFile)157 JSHandle<ConstantPool> PandaFileTranslator::ParseConstPool(EcmaVM *vm, const JSPandaFile *jsPandaFile)
158 {
159 JSThread *thread = vm->GetJSThread();
160 ObjectFactory *factory = vm->GetFactory();
161 JSHandle<ConstantPool> constpool = AllocateConstPool(vm, jsPandaFile);
162
163 [[maybe_unused]] EcmaHandleScope handleScope(thread);
164 const CUnorderedMap<uint32_t, uint64_t> &constpoolMap = jsPandaFile->GetConstpoolMap();
165 const panda_file::File *pf = jsPandaFile->GetPandaFile();
166
167 for (const auto &it : constpoolMap) {
168 ConstPoolValue value(it.second);
169 ConstPoolType type = value.GetConstpoolType();
170 if (type == ConstPoolType::STRING) {
171 panda_file::File::EntityId id(it.first);
172 auto foundStr = pf->GetStringData(id);
173 auto string = factory->GetRawStringFromStringTable(foundStr.data, foundStr.utf16_length, foundStr.is_ascii,
174 MemSpaceType::OLD_SPACE);
175 constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), JSTaggedValue(string));
176 } else if (type == ConstPoolType::OBJECT_LITERAL) {
177 size_t index = static_cast<size_t>(it.first);
178 JSMutableHandle<TaggedArray> elements(thread, JSTaggedValue::Undefined());
179 JSMutableHandle<TaggedArray> properties(thread, JSTaggedValue::Undefined());
180 LiteralDataExtractor::ExtractObjectDatas(
181 thread, jsPandaFile, index, elements, properties, constpool);
182 JSHandle<JSObject> obj = JSObject::CreateObjectFromProperties(thread, properties);
183 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
184 JSMutableHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue::Undefined());
185 size_t elementsLen = elements->GetLength();
186 for (size_t i = 0; i < elementsLen; i += 2) { // 2: Each literal buffer contains a pair of key-value.
187 key.Update(elements->Get(i));
188 if (key->IsHole()) {
189 break;
190 }
191 valueHandle.Update(elements->Get(i + 1));
192 JSObject::DefinePropertyByLiteral(thread, obj, key, valueHandle);
193 }
194 constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), obj.GetTaggedValue());
195 } else if (value.GetConstpoolType() == ConstPoolType::ARRAY_LITERAL) {
196 size_t index = static_cast<size_t>(it.first);
197 JSHandle<TaggedArray> literal = LiteralDataExtractor::GetDatasIgnoreType(
198 thread, jsPandaFile, index, constpool);
199 uint32_t length = literal->GetLength();
200
201 JSHandle<JSArray> arr(JSArray::ArrayCreate(thread, JSTaggedNumber(length)));
202 arr->SetElements(thread, literal);
203 constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), arr.GetTaggedValue());
204 } else if (value.GetConstpoolType() == ConstPoolType::CLASS_LITERAL) {
205 size_t index = static_cast<size_t>(it.first);
206 JSHandle<TaggedArray> literal = LiteralDataExtractor::GetDatasIgnoreTypeForClass(
207 thread, jsPandaFile, index, constpool);
208 JSHandle<ClassLiteral> classLiteral = factory->NewClassLiteral();
209 classLiteral->SetArray(thread, literal);
210 constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), classLiteral.GetTaggedValue());
211 } else {
212 ASSERT(type == ConstPoolType::BASE_FUNCTION || type == ConstPoolType::NC_FUNCTION ||
213 type == ConstPoolType::GENERATOR_FUNCTION || type == ConstPoolType::ASYNC_FUNCTION ||
214 type == ConstPoolType::CLASS_FUNCTION || type == ConstPoolType::METHOD ||
215 type == ConstPoolType::ASYNC_GENERATOR_FUNCTION);
216 MethodLiteral *methodLiteral = jsPandaFile->FindMethodLiteral(it.first);
217 ASSERT(methodLiteral != nullptr);
218 methodLiteral->SetFunctionKind(JSPandaFile::GetFunctionKind(type));
219
220 JSHandle<Method> method = factory->NewMethod(methodLiteral);
221 constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), method.GetTaggedValue());
222 method->SetConstantPool(thread, constpool.GetTaggedValue());
223 }
224 }
225 return constpool;
226 }
227
ParseFuncAndLiteralConstPool(EcmaVM * vm,const JSPandaFile * jsPandaFile,const CString & entryPoint,JSHandle<ConstantPool> constpool)228 void PandaFileTranslator::ParseFuncAndLiteralConstPool(EcmaVM *vm, const JSPandaFile *jsPandaFile,
229 const CString &entryPoint,
230 JSHandle<ConstantPool> constpool)
231 {
232 auto &recordInfo = const_cast<JSPandaFile *>(jsPandaFile)->FindRecordInfo(entryPoint);
233 JSThread *thread = vm->GetJSThread();
234 ASSERT(!thread->HasPendingException());
235 if (recordInfo.IsParsedConstpoolOfCurrentVM(vm)) {
236 return;
237 }
238
239 ObjectFactory *factory = vm->GetFactory();
240
241 [[maybe_unused]] EcmaHandleScope handleScope(thread);
242 CUnorderedMap<uint32_t, uint64_t> constpoolMap = *jsPandaFile->GetConstpoolMapByReocrd(entryPoint);
243 for (const auto &it : constpoolMap) {
244 ConstPoolValue value(it.second);
245 ConstPoolType type = value.GetConstpoolType();
246 if (type == ConstPoolType::OBJECT_LITERAL) {
247 size_t index = static_cast<size_t>(it.first);
248 JSMutableHandle<TaggedArray> elements(thread, JSTaggedValue::Undefined());
249 JSMutableHandle<TaggedArray> properties(thread, JSTaggedValue::Undefined());
250 LiteralDataExtractor::ExtractObjectDatas(
251 thread, jsPandaFile, index, elements, properties, constpool, entryPoint);
252 JSHandle<JSObject> obj = JSObject::CreateObjectFromProperties(thread, properties);
253 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
254 JSMutableHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue::Undefined());
255 size_t elementsLen = elements->GetLength();
256 for (size_t i = 0; i < elementsLen; i += 2) { // 2: Each literal buffer contains a pair of key-value.
257 key.Update(elements->Get(i));
258 if (key->IsHole()) {
259 break;
260 }
261 valueHandle.Update(elements->Get(i + 1));
262 JSObject::DefinePropertyByLiteral(thread, obj, key, valueHandle);
263 }
264 constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), obj.GetTaggedValue());
265 } else if (type == ConstPoolType::ARRAY_LITERAL) {
266 size_t index = static_cast<size_t>(it.first);
267 JSHandle<TaggedArray> literal = LiteralDataExtractor::GetDatasIgnoreType(
268 thread, jsPandaFile, index, constpool, entryPoint);
269 uint32_t length = literal->GetLength();
270 JSHandle<JSArray> arr(JSArray::ArrayCreate(thread, JSTaggedNumber(length)));
271 arr->SetElements(thread, literal);
272 constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), arr.GetTaggedValue());
273 } else if (type == ConstPoolType::CLASS_LITERAL) {
274 size_t index = static_cast<size_t>(it.first);
275 JSHandle<TaggedArray> literal = LiteralDataExtractor::GetDatasIgnoreTypeForClass(
276 thread, jsPandaFile, index, constpool, entryPoint);
277 JSHandle<ClassLiteral> classLiteral = factory->NewClassLiteral();
278 classLiteral->SetArray(thread, literal);
279 constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), classLiteral.GetTaggedValue());
280 } else {
281 ASSERT(type == ConstPoolType::BASE_FUNCTION || type == ConstPoolType::NC_FUNCTION ||
282 type == ConstPoolType::GENERATOR_FUNCTION || type == ConstPoolType::ASYNC_FUNCTION ||
283 type == ConstPoolType::CLASS_FUNCTION || type == ConstPoolType::METHOD ||
284 type == ConstPoolType::ASYNC_GENERATOR_FUNCTION);
285 MethodLiteral *methodLiteral = jsPandaFile->FindMethodLiteral(it.first);
286 ASSERT(methodLiteral != nullptr);
287 methodLiteral->SetFunctionKind(JSPandaFile::GetFunctionKind(type));
288
289 JSHandle<Method> method = factory->NewMethod(methodLiteral);
290 constpool->SetObjectToCache(thread, value.GetConstpoolIndex(), method.GetTaggedValue());
291 method->SetConstantPool(thread, constpool.GetTaggedValue());
292 }
293 }
294 recordInfo.SetParsedConstpoolVM(vm);
295 }
296
AllocateConstPool(EcmaVM * vm,const JSPandaFile * jsPandaFile)297 JSHandle<ConstantPool> PandaFileTranslator::AllocateConstPool(EcmaVM *vm, const JSPandaFile *jsPandaFile)
298 {
299 ObjectFactory *factory = vm->GetFactory();
300 uint32_t constpoolIndex = jsPandaFile->GetConstpoolIndex();
301 JSHandle<ConstantPool> constpool = factory->NewConstantPool(constpoolIndex);
302 constpool->SetJSPandaFile(jsPandaFile);
303 return constpool;
304 }
305
306 #define ADD_NOP_INST(pc, oldLen, newOpcode) \
307 do { \
308 int newLen = static_cast<int>(BytecodeInstruction::Size(newOpcode)); \
309 int paddingSize = static_cast<int>(oldLen) - newLen; \
310 for (int i = 0; i < paddingSize; i++) { \
311 *(pc + newLen + i) = static_cast<uint8_t>(EcmaOpcode::NOP); \
312 } \
313 } while (false)
314
FixOpcode(MethodLiteral * method,const OldBytecodeInst & inst)315 void PandaFileTranslator::FixOpcode(MethodLiteral *method, const OldBytecodeInst &inst)
316 {
317 auto opcode = inst.GetOpcode();
318 EcmaOpcode newOpcode;
319 auto oldLen = OldBytecodeInst::Size(OldBytecodeInst::GetFormat(opcode));
320 auto pc = const_cast<uint8_t *>(inst.GetAddress());
321
322 // First level opcode
323 if (static_cast<uint16_t>(opcode) < 236) { // 236: second level bytecode index
324 switch (opcode) {
325 case OldBytecodeInst::Opcode::MOV_V4_V4: {
326 *pc = static_cast<uint8_t>(EcmaOpcode::MOV_V4_V4);
327 break;
328 }
329 case OldBytecodeInst::Opcode::MOV_DYN_V8_V8: {
330 *pc = static_cast<uint8_t>(EcmaOpcode::MOV_V8_V8);
331 break;
332 }
333 case OldBytecodeInst::Opcode::MOV_DYN_V16_V16: {
334 *pc = static_cast<uint8_t>(EcmaOpcode::MOV_V16_V16);
335 break;
336 }
337 case OldBytecodeInst::Opcode::LDA_STR_ID32: {
338 newOpcode = EcmaOpcode::LDA_STR_ID16;
339 uint32_t id = inst.GetId();
340 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
341 *pc = static_cast<uint8_t>(newOpcode);
342 uint16_t newId = static_cast<uint16_t>(id);
343 if (memcpy_s(pc + 1, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) {
344 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
345 UNREACHABLE();
346 }
347 ADD_NOP_INST(pc, oldLen, newOpcode);
348 break;
349 }
350 case OldBytecodeInst::Opcode::JMP_IMM8: {
351 *pc = static_cast<uint8_t>(EcmaOpcode::JMP_IMM8);
352 break;
353 }
354 case OldBytecodeInst::Opcode::JMP_IMM16: {
355 *pc = static_cast<uint8_t>(EcmaOpcode::JMP_IMM16);
356 break;
357 }
358 case OldBytecodeInst::Opcode::JMP_IMM32: {
359 *pc = static_cast<uint8_t>(EcmaOpcode::JMP_IMM32);
360 break;
361 }
362 case OldBytecodeInst::Opcode::JEQZ_IMM8: {
363 *pc = static_cast<uint8_t>(EcmaOpcode::JEQZ_IMM8);
364 break;
365 }
366 case OldBytecodeInst::Opcode::JEQZ_IMM16: {
367 *pc = static_cast<uint8_t>(EcmaOpcode::JEQZ_IMM16);
368 break;
369 }
370 case OldBytecodeInst::Opcode::JNEZ_IMM8: {
371 *pc = static_cast<uint8_t>(EcmaOpcode::JNEZ_IMM8);
372 break;
373 }
374 case OldBytecodeInst::Opcode::JNEZ_IMM16: {
375 *pc = static_cast<uint8_t>(EcmaOpcode::JNEZ_IMM16);
376 break;
377 }
378 case OldBytecodeInst::Opcode::LDA_DYN_V8: {
379 *pc = static_cast<uint8_t>(EcmaOpcode::LDA_V8);
380 break;
381 }
382 case OldBytecodeInst::Opcode::STA_DYN_V8: {
383 *pc = static_cast<uint8_t>(EcmaOpcode::STA_V8);
384 break;
385 }
386 case OldBytecodeInst::Opcode::LDAI_DYN_IMM32: {
387 *pc = static_cast<uint8_t>(EcmaOpcode::LDAI_IMM32);
388 break;
389 }
390 case OldBytecodeInst::Opcode::FLDAI_DYN_IMM64: {
391 *pc = static_cast<uint8_t>(EcmaOpcode::FLDAI_IMM64);
392 break;
393 }
394 case OldBytecodeInst::Opcode::RETURN_DYN: {
395 *pc = static_cast<uint8_t>(EcmaOpcode::RETURN);
396 break;
397 }
398 default:
399 LOG_FULL(FATAL) << "FixOpcode fail: " << static_cast<uint32_t>(opcode);
400 UNREACHABLE();
401 }
402 return;
403 }
404
405 // New second level bytecode translate
406 constexpr uint8_t opShifLen = 8;
407 constexpr EcmaOpcode throwPrefOp = EcmaOpcode::THROW_PREF_NONE;
408 constexpr EcmaOpcode widePrefOp = EcmaOpcode::WIDE_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8;
409 constexpr EcmaOpcode deprecatedPrefOp = EcmaOpcode::DEPRECATED_LDLEXENV_PREF_NONE;
410 switch (opcode) {
411 // Translate to throw
412 case OldBytecodeInst::Opcode::ECMA_THROWIFSUPERNOTCORRECTCALL_PREF_IMM16: {
413 newOpcode = EcmaOpcode::THROW_IFSUPERNOTCORRECTCALL_PREF_IMM16;
414 *pc = static_cast<uint8_t>(throwPrefOp);
415 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
416 break;
417 }
418 case OldBytecodeInst::Opcode::ECMA_THROWUNDEFINEDIFHOLE_PREF_V8_V8: {
419 newOpcode = EcmaOpcode::THROW_UNDEFINEDIFHOLE_PREF_V8_V8;
420 *pc = static_cast<uint8_t>(throwPrefOp);
421 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
422 break;
423 }
424 case OldBytecodeInst::Opcode::ECMA_THROWIFNOTOBJECT_PREF_V8: {
425 newOpcode = EcmaOpcode::THROW_IFNOTOBJECT_PREF_V8;
426 *pc = static_cast<uint8_t>(throwPrefOp);
427 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
428 break;
429 }
430 case OldBytecodeInst::Opcode::ECMA_THROWCONSTASSIGNMENT_PREF_V8: {
431 newOpcode = EcmaOpcode::THROW_CONSTASSIGNMENT_PREF_V8;
432 *pc = static_cast<uint8_t>(throwPrefOp);
433 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
434 break;
435 }
436 case OldBytecodeInst::Opcode::ECMA_THROWDELETESUPERPROPERTY_PREF_NONE: {
437 newOpcode = EcmaOpcode::THROW_DELETESUPERPROPERTY_PREF_NONE;
438 *pc = static_cast<uint8_t>(throwPrefOp);
439 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
440 break;
441 }
442 case OldBytecodeInst::Opcode::ECMA_THROWPATTERNNONCOERCIBLE_PREF_NONE: {
443 newOpcode = EcmaOpcode::THROW_PATTERNNONCOERCIBLE_PREF_NONE;
444 *pc = static_cast<uint8_t>(throwPrefOp);
445 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
446 break;
447 }
448 case OldBytecodeInst::Opcode::ECMA_THROWTHROWNOTEXISTS_PREF_NONE: {
449 newOpcode = EcmaOpcode::THROW_NOTEXISTS_PREF_NONE;
450 *pc = static_cast<uint8_t>(throwPrefOp);
451 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
452 break;
453 }
454 case OldBytecodeInst::Opcode::ECMA_THROWDYN_PREF_NONE: {
455 newOpcode = EcmaOpcode::THROW_PREF_NONE;
456 *pc = static_cast<uint8_t>(throwPrefOp);
457 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
458 break;
459 }
460 // Translate to wide
461 case OldBytecodeInst::Opcode::ECMA_LDLEXVARDYN_PREF_IMM16_IMM16: {
462 newOpcode = EcmaOpcode::WIDE_LDLEXVAR_PREF_IMM16_IMM16;
463 *pc = static_cast<uint8_t>(widePrefOp);
464 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
465 break;
466 }
467 case OldBytecodeInst::Opcode::ECMA_COPYRESTARGS_PREF_IMM16: {
468 newOpcode = EcmaOpcode::WIDE_COPYRESTARGS_PREF_IMM16;
469 *pc = static_cast<uint8_t>(widePrefOp);
470 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
471 break;
472 }
473 case OldBytecodeInst::Opcode::ECMA_STOWNBYINDEX_PREF_V8_IMM32: {
474 newOpcode = EcmaOpcode::WIDE_STOWNBYINDEX_PREF_V8_IMM32;
475 *pc = static_cast<uint8_t>(widePrefOp);
476 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
477 break;
478 }
479 case OldBytecodeInst::Opcode::ECMA_STOBJBYINDEX_PREF_V8_IMM32: {
480 newOpcode = EcmaOpcode::WIDE_STOBJBYINDEX_PREF_V8_IMM32;
481 *pc = static_cast<uint8_t>(widePrefOp);
482 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
483 break;
484 }
485 case OldBytecodeInst::Opcode::ECMA_NEWLEXENVWITHNAMEDYN_PREF_IMM16_IMM16: {
486 newOpcode = EcmaOpcode::WIDE_NEWLEXENVWITHNAME_PREF_IMM16_ID16;
487 *pc = static_cast<uint8_t>(widePrefOp);
488 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
489 break;
490 }
491 case OldBytecodeInst::Opcode::ECMA_NEWLEXENVDYN_PREF_IMM16: {
492 newOpcode = EcmaOpcode::WIDE_NEWLEXENV_PREF_IMM16;
493 *pc = static_cast<uint8_t>(widePrefOp);
494 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
495 break;
496 }
497 case OldBytecodeInst::Opcode::ECMA_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8: {
498 newOpcode = EcmaOpcode::WIDE_CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8;
499 *pc = static_cast<uint8_t>(widePrefOp);
500 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
501 break;
502 }
503 case OldBytecodeInst::Opcode::ECMA_SUPERCALL_PREF_IMM16_V8: {
504 newOpcode = EcmaOpcode::WIDE_SUPERCALLARROWRANGE_PREF_IMM16_V8;
505 *pc = static_cast<uint8_t>(widePrefOp);
506 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
507 break;
508 }
509 case OldBytecodeInst::Opcode::ECMA_LDPATCHVAR_PREF_IMM16: {
510 newOpcode = EcmaOpcode::WIDE_LDPATCHVAR_PREF_IMM16;
511 *pc = static_cast<uint8_t>(widePrefOp);
512 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
513 break;
514 }
515 case OldBytecodeInst::Opcode::ECMA_STPATCHVAR_PREF_IMM16: {
516 newOpcode = EcmaOpcode::WIDE_STPATCHVAR_PREF_IMM16;
517 *pc = static_cast<uint8_t>(widePrefOp);
518 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
519 break;
520 }
521 // Translate to deprecated
522 case OldBytecodeInst::Opcode::ECMA_STCLASSTOGLOBALRECORD_PREF_ID32: {
523 newOpcode = EcmaOpcode::DEPRECATED_STCLASSTOGLOBALRECORD_PREF_ID32;
524 *pc = static_cast<uint8_t>(deprecatedPrefOp);
525 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
526 break;
527 }
528 case OldBytecodeInst::Opcode::ECMA_STLETTOGLOBALRECORD_PREF_ID32: {
529 newOpcode = EcmaOpcode::DEPRECATED_STLETTOGLOBALRECORD_PREF_ID32;
530 *pc = static_cast<uint8_t>(deprecatedPrefOp);
531 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
532 break;
533 }
534 case OldBytecodeInst::Opcode::ECMA_STCONSTTOGLOBALRECORD_PREF_ID32: {
535 newOpcode = EcmaOpcode::DEPRECATED_STCONSTTOGLOBALRECORD_PREF_ID32;
536 *pc = static_cast<uint8_t>(deprecatedPrefOp);
537 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
538 break;
539 }
540 case OldBytecodeInst::Opcode::ECMA_LDMODULEVAR_PREF_ID32_IMM8: {
541 newOpcode = EcmaOpcode::DEPRECATED_LDMODULEVAR_PREF_ID32_IMM8;
542 *pc = static_cast<uint8_t>(deprecatedPrefOp);
543 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
544 break;
545 }
546 case OldBytecodeInst::Opcode::ECMA_LDSUPERBYNAME_PREF_ID32_V8: {
547 newOpcode = EcmaOpcode::DEPRECATED_LDSUPERBYNAME_PREF_ID32_V8;
548 *pc = static_cast<uint8_t>(deprecatedPrefOp);
549 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
550 break;
551 }
552 case OldBytecodeInst::Opcode::ECMA_LDOBJBYNAME_PREF_ID32_V8: {
553 newOpcode = EcmaOpcode::DEPRECATED_LDOBJBYNAME_PREF_ID32_V8;
554 *pc = static_cast<uint8_t>(deprecatedPrefOp);
555 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
556 break;
557 }
558 case OldBytecodeInst::Opcode::ECMA_STMODULEVAR_PREF_ID32: {
559 newOpcode = EcmaOpcode::DEPRECATED_STMODULEVAR_PREF_ID32;
560 *pc = static_cast<uint8_t>(deprecatedPrefOp);
561 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
562 break;
563 }
564 case OldBytecodeInst::Opcode::ECMA_GETMODULENAMESPACE_PREF_ID32: {
565 newOpcode = EcmaOpcode::DEPRECATED_GETMODULENAMESPACE_PREF_ID32;
566 *pc = static_cast<uint8_t>(deprecatedPrefOp);
567 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
568 break;
569 }
570 case OldBytecodeInst::Opcode::ECMA_STLEXVARDYN_PREF_IMM16_IMM16_V8: {
571 newOpcode = EcmaOpcode::DEPRECATED_STLEXVAR_PREF_IMM16_IMM16_V8;
572 *pc = static_cast<uint8_t>(deprecatedPrefOp);
573 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
574 break;
575 }
576 case OldBytecodeInst::Opcode::ECMA_STLEXVARDYN_PREF_IMM8_IMM8_V8: {
577 newOpcode = EcmaOpcode::DEPRECATED_STLEXVAR_PREF_IMM8_IMM8_V8;
578 *pc = static_cast<uint8_t>(deprecatedPrefOp);
579 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
580 break;
581 }
582 case OldBytecodeInst::Opcode::ECMA_STLEXVARDYN_PREF_IMM4_IMM4_V8: {
583 newOpcode = EcmaOpcode::DEPRECATED_STLEXVAR_PREF_IMM4_IMM4_V8;
584 *pc = static_cast<uint8_t>(deprecatedPrefOp);
585 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
586 break;
587 }
588 case OldBytecodeInst::Opcode::ECMA_ASYNCFUNCTIONREJECT_PREF_V8_V8_V8: {
589 newOpcode = EcmaOpcode::DEPRECATED_ASYNCFUNCTIONREJECT_PREF_V8_V8_V8;
590 *pc = static_cast<uint8_t>(deprecatedPrefOp);
591 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
592 break;
593 }
594 case OldBytecodeInst::Opcode::ECMA_ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8: {
595 newOpcode = EcmaOpcode::DEPRECATED_ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8;
596 *pc = static_cast<uint8_t>(deprecatedPrefOp);
597 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
598 break;
599 }
600 case OldBytecodeInst::Opcode::ECMA_LDOBJBYINDEX_PREF_V8_IMM32: {
601 newOpcode = EcmaOpcode::DEPRECATED_LDOBJBYINDEX_PREF_V8_IMM32;
602 *pc = static_cast<uint8_t>(deprecatedPrefOp);
603 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
604 break;
605 }
606 case OldBytecodeInst::Opcode::ECMA_LDSUPERBYVALUE_PREF_V8_V8: {
607 newOpcode = EcmaOpcode::DEPRECATED_LDSUPERBYVALUE_PREF_V8_V8;
608 *pc = static_cast<uint8_t>(deprecatedPrefOp);
609 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
610 break;
611 }
612 case OldBytecodeInst::Opcode::ECMA_LDOBJBYVALUE_PREF_V8_V8: {
613 newOpcode = EcmaOpcode::DEPRECATED_LDOBJBYVALUE_PREF_V8_V8;
614 *pc = static_cast<uint8_t>(deprecatedPrefOp);
615 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
616 break;
617 }
618 case OldBytecodeInst::Opcode::ECMA_SETOBJECTWITHPROTO_PREF_V8_V8: {
619 newOpcode = EcmaOpcode::DEPRECATED_SETOBJECTWITHPROTO_PREF_V8_V8;
620 *pc = static_cast<uint8_t>(deprecatedPrefOp);
621 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
622 break;
623 }
624 case OldBytecodeInst::Opcode::ECMA_COPYDATAPROPERTIES_PREF_V8_V8: {
625 newOpcode = EcmaOpcode::DEPRECATED_COPYDATAPROPERTIES_PREF_V8_V8;
626 *pc = static_cast<uint8_t>(deprecatedPrefOp);
627 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
628 break;
629 }
630 case OldBytecodeInst::Opcode::ECMA_ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8: {
631 newOpcode = EcmaOpcode::DEPRECATED_ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8;
632 *pc = static_cast<uint8_t>(deprecatedPrefOp);
633 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
634 break;
635 }
636 case OldBytecodeInst::Opcode::ECMA_SUSPENDGENERATOR_PREF_V8_V8: {
637 newOpcode = EcmaOpcode::DEPRECATED_SUSPENDGENERATOR_PREF_V8_V8;
638 *pc = static_cast<uint8_t>(deprecatedPrefOp);
639 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
640 break;
641 }
642 case OldBytecodeInst::Opcode::ECMA_DELOBJPROP_PREF_V8_V8: {
643 newOpcode = EcmaOpcode::DEPRECATED_DELOBJPROP_PREF_V8_V8;
644 *pc = static_cast<uint8_t>(deprecatedPrefOp);
645 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
646 break;
647 }
648 case OldBytecodeInst::Opcode::ECMA_GETTEMPLATEOBJECT_PREF_V8: {
649 newOpcode = EcmaOpcode::DEPRECATED_GETTEMPLATEOBJECT_PREF_V8;
650 *pc = static_cast<uint8_t>(deprecatedPrefOp);
651 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
652 break;
653 }
654 case OldBytecodeInst::Opcode::ECMA_GETRESUMEMODE_PREF_V8: {
655 newOpcode = EcmaOpcode::DEPRECATED_GETRESUMEMODE_PREF_V8;
656 *pc = static_cast<uint8_t>(deprecatedPrefOp);
657 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
658 break;
659 }
660 case OldBytecodeInst::Opcode::ECMA_RESUMEGENERATOR_PREF_V8: {
661 newOpcode = EcmaOpcode::DEPRECATED_RESUMEGENERATOR_PREF_V8;
662 *pc = static_cast<uint8_t>(deprecatedPrefOp);
663 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
664 break;
665 }
666 case OldBytecodeInst::Opcode::ECMA_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8: {
667 newOpcode = EcmaOpcode::DEPRECATED_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8;
668 *pc = static_cast<uint8_t>(deprecatedPrefOp);
669 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
670 break;
671 }
672 case OldBytecodeInst::Opcode::ECMA_CALLTHISRANGEDYN_PREF_IMM16_V8: {
673 newOpcode = EcmaOpcode::DEPRECATED_CALLTHISRANGE_PREF_IMM16_V8;
674 *pc = static_cast<uint8_t>(deprecatedPrefOp);
675 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
676 break;
677 }
678 case OldBytecodeInst::Opcode::ECMA_CALLSPREADDYN_PREF_V8_V8_V8: {
679 newOpcode = EcmaOpcode::DEPRECATED_CALLSPREAD_PREF_V8_V8_V8;
680 *pc = static_cast<uint8_t>(deprecatedPrefOp);
681 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
682 break;
683 }
684 case OldBytecodeInst::Opcode::ECMA_CALLRANGEDYN_PREF_IMM16_V8: {
685 newOpcode = EcmaOpcode::DEPRECATED_CALLRANGE_PREF_IMM16_V8;
686 *pc = static_cast<uint8_t>(deprecatedPrefOp);
687 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
688 break;
689 }
690 case OldBytecodeInst::Opcode::ECMA_CALLARGS3DYN_PREF_V8_V8_V8_V8: {
691 newOpcode = EcmaOpcode::DEPRECATED_CALLARGS3_PREF_V8_V8_V8_V8;
692 *pc = static_cast<uint8_t>(deprecatedPrefOp);
693 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
694 break;
695 }
696 case OldBytecodeInst::Opcode::ECMA_CALLARGS2DYN_PREF_V8_V8_V8: {
697 newOpcode = EcmaOpcode::DEPRECATED_CALLARGS2_PREF_V8_V8_V8;
698 *pc = static_cast<uint8_t>(deprecatedPrefOp);
699 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
700 break;
701 }
702 case OldBytecodeInst::Opcode::ECMA_CALLARG1DYN_PREF_V8_V8: {
703 newOpcode = EcmaOpcode::DEPRECATED_CALLARG1_PREF_V8_V8;
704 *pc = static_cast<uint8_t>(deprecatedPrefOp);
705 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
706 break;
707 }
708 case OldBytecodeInst::Opcode::ECMA_CALLARG0DYN_PREF_V8: {
709 newOpcode = EcmaOpcode::DEPRECATED_CALLARG0_PREF_V8;
710 *pc = static_cast<uint8_t>(deprecatedPrefOp);
711 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
712 break;
713 }
714 case OldBytecodeInst::Opcode::ECMA_DECDYN_PREF_V8: {
715 newOpcode = EcmaOpcode::DEPRECATED_DEC_PREF_V8;
716 *pc = static_cast<uint8_t>(deprecatedPrefOp);
717 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
718 break;
719 }
720 case OldBytecodeInst::Opcode::ECMA_INCDYN_PREF_V8: {
721 newOpcode = EcmaOpcode::DEPRECATED_INC_PREF_V8;
722 *pc = static_cast<uint8_t>(deprecatedPrefOp);
723 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
724 break;
725 }
726 case OldBytecodeInst::Opcode::ECMA_NOTDYN_PREF_V8: {
727 newOpcode = EcmaOpcode::DEPRECATED_NOT_PREF_V8;
728 *pc = static_cast<uint8_t>(deprecatedPrefOp);
729 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
730 break;
731 }
732 case OldBytecodeInst::Opcode::ECMA_NEGDYN_PREF_V8: {
733 newOpcode = EcmaOpcode::DEPRECATED_NEG_PREF_V8;
734 *pc = static_cast<uint8_t>(deprecatedPrefOp);
735 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
736 break;
737 }
738 case OldBytecodeInst::Opcode::ECMA_TONUMERIC_PREF_V8: {
739 newOpcode = EcmaOpcode::DEPRECATED_TONUMERIC_PREF_V8;
740 *pc = static_cast<uint8_t>(deprecatedPrefOp);
741 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
742 break;
743 }
744 case OldBytecodeInst::Opcode::ECMA_TONUMBER_PREF_V8: {
745 newOpcode = EcmaOpcode::DEPRECATED_TONUMBER_PREF_V8;
746 *pc = static_cast<uint8_t>(deprecatedPrefOp);
747 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
748 break;
749 }
750 case OldBytecodeInst::Opcode::ECMA_CREATEOBJECTWITHBUFFER_PREF_IMM16: {
751 newOpcode = EcmaOpcode::DEPRECATED_CREATEOBJECTWITHBUFFER_PREF_IMM16;
752 *pc = static_cast<uint8_t>(deprecatedPrefOp);
753 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
754 break;
755 }
756 case OldBytecodeInst::Opcode::ECMA_CREATEARRAYWITHBUFFER_PREF_IMM16: {
757 newOpcode = EcmaOpcode::DEPRECATED_CREATEARRAYWITHBUFFER_PREF_IMM16;
758 *pc = static_cast<uint8_t>(deprecatedPrefOp);
759 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
760 break;
761 }
762 case OldBytecodeInst::Opcode::ECMA_GETITERATORNEXT_PREF_V8_V8: {
763 newOpcode = EcmaOpcode::DEPRECATED_GETITERATORNEXT_PREF_V8_V8;
764 *pc = static_cast<uint8_t>(deprecatedPrefOp);
765 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
766 break;
767 }
768 case OldBytecodeInst::Opcode::ECMA_POPLEXENVDYN_PREF_NONE: {
769 newOpcode = EcmaOpcode::DEPRECATED_POPLEXENV_PREF_NONE;
770 *pc = static_cast<uint8_t>(deprecatedPrefOp);
771 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
772 break;
773 }
774 case OldBytecodeInst::Opcode::ECMA_LDLEXENVDYN_PREF_NONE: {
775 newOpcode = EcmaOpcode::DEPRECATED_LDLEXENV_PREF_NONE;
776 *pc = static_cast<uint8_t>(deprecatedPrefOp);
777 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
778 break;
779 }
780 case OldBytecodeInst::Opcode::ECMA_LDHOMEOBJECT_PREF_NONE: {
781 newOpcode = EcmaOpcode::DEPRECATED_LDHOMEOBJECT_PREF_NONE;
782 *pc = static_cast<uint8_t>(deprecatedPrefOp);
783 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
784 break;
785 }
786 case OldBytecodeInst::Opcode::ECMA_CREATEOBJECTHAVINGMETHOD_PREF_IMM16: {
787 newOpcode = EcmaOpcode::DEPRECATED_CREATEOBJECTHAVINGMETHOD_PREF_IMM16;
788 *pc = static_cast<uint8_t>(deprecatedPrefOp);
789 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
790 break;
791 }
792 case OldBytecodeInst::Opcode::ECMA_DYNAMICIMPORT_PREF_V8: {
793 newOpcode = EcmaOpcode::DEPRECATED_DYNAMICIMPORT_PREF_V8;
794 *pc = static_cast<uint8_t>(deprecatedPrefOp);
795 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
796 break;
797 }
798 case OldBytecodeInst::Opcode::ECMA_ASYNCGENERATORREJECT_PREF_V8_V8: {
799 newOpcode = EcmaOpcode::DEPRECATED_ASYNCGENERATORREJECT_PREF_V8_V8;
800 *pc = static_cast<uint8_t>(deprecatedPrefOp);
801 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
802 break;
803 }
804 // The same format has IC
805 case OldBytecodeInst::Opcode::ECMA_TYPEOFDYN_PREF_NONE: {
806 newOpcode = EcmaOpcode::TYPEOF_IMM8;
807 *pc = static_cast<uint8_t>(newOpcode);
808 *(pc + 1) = 0x00;
809 break;
810 }
811 case OldBytecodeInst::Opcode::ECMA_INSTANCEOFDYN_PREF_V8: {
812 newOpcode = EcmaOpcode::INSTANCEOF_IMM8_V8;
813 *pc = static_cast<uint8_t>(newOpcode);
814 *(pc + 1) = 0x00;
815 break;
816 }
817 case OldBytecodeInst::Opcode::ECMA_CREATEEMPTYARRAY_PREF_NONE: {
818 newOpcode = EcmaOpcode::CREATEEMPTYARRAY_IMM8;
819 *pc = static_cast<uint8_t>(newOpcode);
820 *(pc + 1) = 0x00;
821 break;
822 }
823 case OldBytecodeInst::Opcode::ECMA_GETITERATOR_PREF_NONE: {
824 newOpcode = EcmaOpcode::GETITERATOR_IMM8;
825 *pc = static_cast<uint8_t>(newOpcode);
826 *(pc + 1) = 0x00;
827 break;
828 }
829 case OldBytecodeInst::Opcode::ECMA_ADD2DYN_PREF_V8: {
830 newOpcode = EcmaOpcode::ADD2_IMM8_V8;
831 *pc = static_cast<uint8_t>(newOpcode);
832 *(pc + 1) = 0x00;
833 break;
834 }
835 case OldBytecodeInst::Opcode::ECMA_SUB2DYN_PREF_V8: {
836 newOpcode = EcmaOpcode::SUB2_IMM8_V8;
837 *pc = static_cast<uint8_t>(newOpcode);
838 *(pc + 1) = 0x00;
839 break;
840 }
841 case OldBytecodeInst::Opcode::ECMA_MUL2DYN_PREF_V8: {
842 newOpcode = EcmaOpcode::MUL2_IMM8_V8;
843 *pc = static_cast<uint8_t>(newOpcode);
844 *(pc + 1) = 0x00;
845 break;
846 }
847 case OldBytecodeInst::Opcode::ECMA_DIV2DYN_PREF_V8: {
848 newOpcode = EcmaOpcode::DIV2_IMM8_V8;
849 *pc = static_cast<uint8_t>(newOpcode);
850 *(pc + 1) = 0x00;
851 break;
852 }
853 case OldBytecodeInst::Opcode::ECMA_MOD2DYN_PREF_V8: {
854 newOpcode = EcmaOpcode::MOD2_IMM8_V8;
855 *pc = static_cast<uint8_t>(newOpcode);
856 *(pc + 1) = 0x00;
857 break;
858 }
859 case OldBytecodeInst::Opcode::ECMA_EQDYN_PREF_V8: {
860 newOpcode = EcmaOpcode::EQ_IMM8_V8;
861 *pc = static_cast<uint8_t>(newOpcode);
862 *(pc + 1) = 0x00;
863 break;
864 }
865 case OldBytecodeInst::Opcode::ECMA_NOTEQDYN_PREF_V8: {
866 newOpcode = EcmaOpcode::NOTEQ_IMM8_V8;
867 *pc = static_cast<uint8_t>(newOpcode);
868 *(pc + 1) = 0x00;
869 break;
870 }
871 case OldBytecodeInst::Opcode::ECMA_LESSDYN_PREF_V8: {
872 newOpcode = EcmaOpcode::LESS_IMM8_V8;
873 *pc = static_cast<uint8_t>(newOpcode);
874 *(pc + 1) = 0x00;
875 break;
876 }
877 case OldBytecodeInst::Opcode::ECMA_LESSEQDYN_PREF_V8: {
878 newOpcode = EcmaOpcode::LESSEQ_IMM8_V8;
879 *pc = static_cast<uint8_t>(newOpcode);
880 *(pc + 1) = 0x00;
881 break;
882 }
883 case OldBytecodeInst::Opcode::ECMA_GREATERDYN_PREF_V8: {
884 newOpcode = EcmaOpcode::GREATER_IMM8_V8;
885 *pc = static_cast<uint8_t>(newOpcode);
886 *(pc + 1) = 0x00;
887 break;
888 }
889 case OldBytecodeInst::Opcode::ECMA_GREATEREQDYN_PREF_V8: {
890 newOpcode = EcmaOpcode::GREATEREQ_IMM8_V8;
891 *pc = static_cast<uint8_t>(newOpcode);
892 *(pc + 1) = 0x00;
893 break;
894 }
895 case OldBytecodeInst::Opcode::ECMA_SHL2DYN_PREF_V8: {
896 newOpcode = EcmaOpcode::SHL2_IMM8_V8;
897 *pc = static_cast<uint8_t>(newOpcode);
898 *(pc + 1) = 0x00;
899 break;
900 }
901 case OldBytecodeInst::Opcode::ECMA_ASHR2DYN_PREF_V8: {
902 newOpcode = EcmaOpcode::SHR2_IMM8_V8; // old instruction was wrong
903 *pc = static_cast<uint8_t>(newOpcode);
904 *(pc + 1) = 0x00;
905 break;
906 }
907 case OldBytecodeInst::Opcode::ECMA_SHR2DYN_PREF_V8: {
908 newOpcode = EcmaOpcode::ASHR2_IMM8_V8; // old instruction was wrong
909 *pc = static_cast<uint8_t>(newOpcode);
910 *(pc + 1) = 0x00;
911 break;
912 }
913 case OldBytecodeInst::Opcode::ECMA_AND2DYN_PREF_V8: {
914 newOpcode = EcmaOpcode::AND2_IMM8_V8;
915 *pc = static_cast<uint8_t>(newOpcode);
916 *(pc + 1) = 0x00;
917 break;
918 }
919 case OldBytecodeInst::Opcode::ECMA_OR2DYN_PREF_V8: {
920 newOpcode = EcmaOpcode::OR2_IMM8_V8;
921 *pc = static_cast<uint8_t>(newOpcode);
922 *(pc + 1) = 0x00;
923 break;
924 }
925 case OldBytecodeInst::Opcode::ECMA_XOR2DYN_PREF_V8: {
926 newOpcode = EcmaOpcode::XOR2_IMM8_V8;
927 *pc = static_cast<uint8_t>(newOpcode);
928 *(pc + 1) = 0x00;
929 break;
930 }
931 case OldBytecodeInst::Opcode::ECMA_EXPDYN_PREF_V8: {
932 newOpcode = EcmaOpcode::EXP_IMM8_V8;
933 *pc = static_cast<uint8_t>(newOpcode);
934 *(pc + 1) = 0x00;
935 break;
936 }
937 case OldBytecodeInst::Opcode::ECMA_ISINDYN_PREF_V8: {
938 newOpcode = EcmaOpcode::ISIN_IMM8_V8;
939 *pc = static_cast<uint8_t>(newOpcode);
940 *(pc + 1) = 0x00;
941 break;
942 }
943 case OldBytecodeInst::Opcode::ECMA_STRICTNOTEQDYN_PREF_V8: {
944 newOpcode = EcmaOpcode::STRICTNOTEQ_IMM8_V8;
945 *pc = static_cast<uint8_t>(newOpcode);
946 *(pc + 1) = 0x00;
947 break;
948 }
949 case OldBytecodeInst::Opcode::ECMA_STRICTEQDYN_PREF_V8: {
950 newOpcode = EcmaOpcode::STRICTEQ_IMM8_V8;
951 *pc = static_cast<uint8_t>(newOpcode);
952 *(pc + 1) = 0x00;
953 break;
954 }
955 case OldBytecodeInst::Opcode::ECMA_ITERNEXT_PREF_V8: {
956 // *pc = static_cast<uint8_t>(EcmaOpcode::new_op_xxxxxxxx);
957 // *(pc + 1) = 0x00;
958 LOG_FULL(FATAL) << "Need Add ITERNEXT Deprecated";
959 return;
960 }
961 case OldBytecodeInst::Opcode::ECMA_CLOSEITERATOR_PREF_V8: {
962 newOpcode = EcmaOpcode::CLOSEITERATOR_IMM8_V8;
963 *pc = static_cast<uint8_t>(newOpcode);
964 *(pc + 1) = 0x00;
965 break;
966 }
967 case OldBytecodeInst::Opcode::ECMA_SUPERCALLSPREAD_PREF_V8: {
968 newOpcode = EcmaOpcode::SUPERCALLSPREAD_IMM8_V8;
969 *pc = static_cast<uint8_t>(newOpcode);
970 *(pc + 1) = 0x00;
971 break;
972 }
973 case OldBytecodeInst::Opcode::ECMA_STOBJBYVALUE_PREF_V8_V8: {
974 newOpcode = EcmaOpcode::STOBJBYVALUE_IMM8_V8_V8;
975 *pc = static_cast<uint8_t>(newOpcode);
976 *(pc + 1) = 0x00;
977 break;
978 }
979 case OldBytecodeInst::Opcode::ECMA_STOWNBYVALUE_PREF_V8_V8: {
980 newOpcode = EcmaOpcode::STOWNBYVALUE_IMM8_V8_V8;
981 *pc = static_cast<uint8_t>(newOpcode);
982 *(pc + 1) = 0x00;
983 break;
984 }
985 case OldBytecodeInst::Opcode::ECMA_STSUPERBYVALUE_PREF_V8_V8: {
986 newOpcode = EcmaOpcode::STSUPERBYVALUE_IMM8_V8_V8;
987 *pc = static_cast<uint8_t>(newOpcode);
988 *(pc + 1) = 0x00;
989 break;
990 }
991 case OldBytecodeInst::Opcode::ECMA_STOWNBYVALUEWITHNAMESET_PREF_V8_V8: {
992 newOpcode = EcmaOpcode::STOWNBYVALUEWITHNAMESET_IMM8_V8_V8;
993 *pc = static_cast<uint8_t>(newOpcode);
994 *(pc + 1) = 0x00;
995 break;
996 }
997 // The same format no IC
998 case OldBytecodeInst::Opcode::ECMA_ASYNCFUNCTIONENTER_PREF_NONE: {
999 newOpcode = EcmaOpcode::ASYNCFUNCTIONENTER;
1000 *pc = static_cast<uint8_t>(newOpcode);
1001 break;
1002 }
1003 case OldBytecodeInst::Opcode::ECMA_ASYNCGENERATORRESOLVE_PREF_V8_V8_V8: {
1004 newOpcode = EcmaOpcode::ASYNCGENERATORRESOLVE_V8_V8_V8;
1005 *pc = static_cast<uint8_t>(newOpcode);
1006 auto newLen = BytecodeInstruction::Size(newOpcode);
1007 if (memmove_s(pc + 1, newLen - 1, pc + 2, oldLen - 2) != EOK) { // 2: skip second level inst and pref
1008 LOG_FULL(FATAL) << "FixOpcode memmove_s fail";
1009 UNREACHABLE();
1010 }
1011 break;
1012 }
1013 case OldBytecodeInst::Opcode::ECMA_CREATEASYNCGENERATOROBJ_PREF_V8: {
1014 newOpcode = EcmaOpcode::CREATEASYNCGENERATOROBJ_V8;
1015 *pc = static_cast<uint8_t>(newOpcode);
1016 auto newLen = BytecodeInstruction::Size(newOpcode);
1017 if (memmove_s(pc + 1, newLen - 1, pc + 2, oldLen - 2) != EOK) { // 2: skip second level inst and pref
1018 LOG_FULL(FATAL) << "FixOpcode memmove_s fail";
1019 UNREACHABLE();
1020 }
1021 break;
1022 }
1023 case OldBytecodeInst::Opcode::ECMA_CREATEEMPTYOBJECT_PREF_NONE: {
1024 newOpcode = EcmaOpcode::CREATEEMPTYOBJECT;
1025 *pc = static_cast<uint8_t>(newOpcode);
1026 break;
1027 }
1028 case OldBytecodeInst::Opcode::ECMA_CREATEGENERATOROBJ_PREF_V8: {
1029 newOpcode = EcmaOpcode::CREATEGENERATOROBJ_V8;
1030 *pc = static_cast<uint8_t>(newOpcode);
1031 auto newLen = BytecodeInstruction::Size(newOpcode);
1032 if (memmove_s(pc + 1, newLen - 1, pc + 2, oldLen - 2) != EOK) { // 2: skip second level inst and pref
1033 LOG_FULL(FATAL) << "FixOpcode memmove_s fail";
1034 UNREACHABLE();
1035 }
1036 break;
1037 }
1038 case OldBytecodeInst::Opcode::ECMA_CREATEITERRESULTOBJ_PREF_V8_V8: {
1039 newOpcode = EcmaOpcode::CREATEITERRESULTOBJ_V8_V8;
1040 *pc = static_cast<uint8_t>(newOpcode);
1041 auto newLen = BytecodeInstruction::Size(newOpcode);
1042 if (memmove_s(pc + 1, newLen - 1, pc + 2, oldLen - 2) != EOK) { // 2: skip second level inst and pref
1043 LOG_FULL(FATAL) << "FixOpcode memmove_s fail";
1044 UNREACHABLE();
1045 }
1046 break;
1047 }
1048 case OldBytecodeInst::Opcode::ECMA_DEBUGGER_PREF_NONE: {
1049 newOpcode = EcmaOpcode::DEBUGGER;
1050 *pc = static_cast<uint8_t>(newOpcode);
1051 break;
1052 }
1053 case OldBytecodeInst::Opcode::ECMA_DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8: {
1054 newOpcode = EcmaOpcode::DEFINEGETTERSETTERBYVALUE_V8_V8_V8_V8;
1055 *pc = static_cast<uint8_t>(newOpcode);
1056 auto newLen = BytecodeInstruction::Size(newOpcode);
1057 if (memmove_s(pc + 1, newLen - 1, pc + 2, oldLen - 2) != EOK) { // 2: skip second level inst and pref
1058 LOG_FULL(FATAL) << "FixOpcode memmove_s fail";
1059 UNREACHABLE();
1060 }
1061 break;
1062 }
1063 case OldBytecodeInst::Opcode::ECMA_GETNEXTPROPNAME_PREF_V8: {
1064 newOpcode = EcmaOpcode::GETNEXTPROPNAME_V8;
1065 *pc = static_cast<uint8_t>(newOpcode);
1066 auto newLen = BytecodeInstruction::Size(newOpcode);
1067 if (memmove_s(pc + 1, newLen - 1, pc + 2, oldLen - 2) != EOK) { // 2: skip second level inst and pref
1068 LOG_FULL(FATAL) << "FixOpcode memmove_s fail";
1069 UNREACHABLE();
1070 }
1071 break;
1072 }
1073 case OldBytecodeInst::Opcode::ECMA_GETPROPITERATOR_PREF_NONE: {
1074 newOpcode = EcmaOpcode::GETPROPITERATOR;
1075 *pc = static_cast<uint8_t>(newOpcode);
1076 break;
1077 }
1078 case OldBytecodeInst::Opcode::ECMA_GETUNMAPPEDARGS_PREF_NONE: {
1079 newOpcode = EcmaOpcode::GETUNMAPPEDARGS;
1080 *pc = static_cast<uint8_t>(newOpcode);
1081 break;
1082 }
1083 case OldBytecodeInst::Opcode::ECMA_ISFALSE_PREF_NONE: {
1084 newOpcode = EcmaOpcode::ISFALSE;
1085 *pc = static_cast<uint8_t>(newOpcode);
1086 break;
1087 }
1088 case OldBytecodeInst::Opcode::ECMA_ISTRUE_PREF_NONE: {
1089 newOpcode = EcmaOpcode::ISTRUE;
1090 *pc = static_cast<uint8_t>(newOpcode);
1091 break;
1092 }
1093 case OldBytecodeInst::Opcode::ECMA_LDFALSE_PREF_NONE: {
1094 newOpcode = EcmaOpcode::LDFALSE;
1095 *pc = static_cast<uint8_t>(newOpcode);
1096 break;
1097 }
1098 case OldBytecodeInst::Opcode::ECMA_LDTRUE_PREF_NONE: {
1099 newOpcode = EcmaOpcode::LDTRUE;
1100 *pc = static_cast<uint8_t>(newOpcode);
1101 break;
1102 }
1103 case OldBytecodeInst::Opcode::ECMA_LDFUNCTION_PREF_NONE: {
1104 newOpcode = EcmaOpcode::LDFUNCTION;
1105 *pc = static_cast<uint8_t>(newOpcode);
1106 break;
1107 }
1108 case OldBytecodeInst::Opcode::ECMA_LDGLOBALTHIS_PREF_NONE: {
1109 newOpcode = EcmaOpcode::LDGLOBAL;
1110 *pc = static_cast<uint8_t>(newOpcode);
1111 break;
1112 }
1113 case OldBytecodeInst::Opcode::ECMA_LDGLOBAL_PREF_NONE: {
1114 newOpcode = EcmaOpcode::LDGLOBAL;
1115 *pc = static_cast<uint8_t>(newOpcode);
1116 break;
1117 }
1118 case OldBytecodeInst::Opcode::ECMA_LDHOLE_PREF_NONE: {
1119 newOpcode = EcmaOpcode::LDHOLE;
1120 *pc = static_cast<uint8_t>(newOpcode);
1121 break;
1122 }
1123 case OldBytecodeInst::Opcode::ECMA_LDNULL_PREF_NONE: {
1124 newOpcode = EcmaOpcode::LDNULL;
1125 *pc = static_cast<uint8_t>(newOpcode);
1126 break;
1127 }
1128 case OldBytecodeInst::Opcode::ECMA_LDSYMBOL_PREF_NONE: {
1129 newOpcode = EcmaOpcode::LDSYMBOL;
1130 *pc = static_cast<uint8_t>(newOpcode);
1131 break;
1132 }
1133 case OldBytecodeInst::Opcode::ECMA_LDUNDEFINED_PREF_NONE: {
1134 newOpcode = EcmaOpcode::LDUNDEFINED;
1135 *pc = static_cast<uint8_t>(newOpcode);
1136 break;
1137 }
1138 case OldBytecodeInst::Opcode::ECMA_LDNAN_PREF_NONE: {
1139 newOpcode = EcmaOpcode::LDNAN;
1140 *pc = static_cast<uint8_t>(newOpcode);
1141 break;
1142 }
1143 case OldBytecodeInst::Opcode::ECMA_LDINFINITY_PREF_NONE: {
1144 newOpcode = EcmaOpcode::LDINFINITY;
1145 *pc = static_cast<uint8_t>(newOpcode);
1146 break;
1147 }
1148 case OldBytecodeInst::Opcode::ECMA_RETURNUNDEFINED_PREF_NONE: {
1149 newOpcode = EcmaOpcode::RETURNUNDEFINED;
1150 *pc = static_cast<uint8_t>(newOpcode);
1151 break;
1152 }
1153 case OldBytecodeInst::Opcode::ECMA_NEWOBJDYNRANGE_PREF_IMM16_V8: {
1154 newOpcode = EcmaOpcode::WIDE_NEWOBJRANGE_PREF_IMM16_V8;
1155 *pc = static_cast<uint8_t>(widePrefOp);
1156 *(pc + 1) = static_cast<uint16_t>(newOpcode) >> opShifLen;
1157
1158 uint16_t imm = static_cast<uint16_t>(inst.GetImm<OldBytecodeInst::Format::PREF_IMM16_V8>() - 1);
1159 if (memcpy_s(pc + 2, sizeof(uint16_t), &imm, sizeof(uint16_t)) != EOK) { // 2: skip opcode and ic slot
1160 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1161 UNREACHABLE();
1162 }
1163 *(pc + 4) = *(pc + 4) + 1;
1164 break;
1165 }
1166 case OldBytecodeInst::Opcode::ECMA_LDLEXVARDYN_PREF_IMM4_IMM4: {
1167 newOpcode = EcmaOpcode::LDLEXVAR_IMM4_IMM4;
1168 *pc = static_cast<uint8_t>(newOpcode);
1169 auto newLen = BytecodeInstruction::Size(newOpcode);
1170 if (memmove_s(pc + 1, newLen - 1, pc + 2, oldLen - 2) != EOK) { // 2: skip second level inst and pref
1171 LOG_FULL(FATAL) << "FixOpcode memmove_s fail";
1172 UNREACHABLE();
1173 }
1174 break;
1175 }
1176 case OldBytecodeInst::Opcode::ECMA_LDLEXVARDYN_PREF_IMM8_IMM8: {
1177 newOpcode = EcmaOpcode::LDLEXVAR_IMM8_IMM8;
1178 *pc = static_cast<uint8_t>(newOpcode);
1179 auto newLen = BytecodeInstruction::Size(newOpcode);
1180 if (memmove_s(pc + 1, newLen - 1, pc + 2, oldLen - 2) != EOK) { // 2: skip second level inst and pref
1181 LOG_FULL(FATAL) << "FixOpcode memmove_s fail";
1182 UNREACHABLE();
1183 }
1184 break;
1185 }
1186 case OldBytecodeInst::Opcode::ECMA_STARRAYSPREAD_PREF_V8_V8: {
1187 newOpcode = EcmaOpcode::STARRAYSPREAD_V8_V8;
1188 *pc = static_cast<uint8_t>(newOpcode);
1189 auto newLen = BytecodeInstruction::Size(newOpcode);
1190 // 2: skip opcode and second level pref
1191 if (memmove_s(pc + 1, newLen - 1, pc + 2, oldLen - 2) != EOK) {
1192 LOG_FULL(FATAL) << "FixOpcode memmove_s fail";
1193 UNREACHABLE();
1194 }
1195 break;
1196 }
1197 // ID32 to ID16 has IC (PREF_ID32)
1198 case OldBytecodeInst::Opcode::ECMA_TRYLDGLOBALBYNAME_PREF_ID32: {
1199 newOpcode = EcmaOpcode::TRYLDGLOBALBYNAME_IMM8_ID16;
1200 uint32_t id = inst.GetId();
1201 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
1202 *pc = static_cast<uint8_t>(newOpcode);
1203 *(pc + 1) = 0x00;
1204 uint16_t newId = static_cast<uint16_t>(id);
1205 if (memcpy_s(pc + 2, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) { // 2: skip opcode and ic slot
1206 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1207 UNREACHABLE();
1208 }
1209 break;
1210 }
1211 case OldBytecodeInst::Opcode::ECMA_TRYSTGLOBALBYNAME_PREF_ID32: {
1212 newOpcode = EcmaOpcode::TRYSTGLOBALBYNAME_IMM8_ID16;
1213 uint32_t id = inst.GetId();
1214 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
1215 *pc = static_cast<uint8_t>(newOpcode);
1216 *(pc + 1) = 0x00;
1217 uint16_t newId = static_cast<uint16_t>(id);
1218 if (memcpy_s(pc + 2, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) { // 2: skip opcode and ic slot
1219 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1220 UNREACHABLE();
1221 }
1222 break;
1223 }
1224 // ID32 to ID16 has IC (ID32_V8 & ID32_IMM8)
1225 case OldBytecodeInst::Opcode::ECMA_STOBJBYNAME_PREF_ID32_V8: {
1226 newOpcode = EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8;
1227 uint32_t id = inst.GetId();
1228 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
1229 *pc = static_cast<uint8_t>(newOpcode);
1230 *(pc + 1) = 0x00;
1231 uint16_t newId = static_cast<uint16_t>(id);
1232 if (memcpy_s(pc + 2, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) { // 2: skip opcode and ic slot
1233 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1234 UNREACHABLE();
1235 }
1236 *(pc + 4) = *(pc + 6); // 4: index of new opcode; 6: index of old opcode
1237 break;
1238 }
1239 case OldBytecodeInst::Opcode::ECMA_STOWNBYNAME_PREF_ID32_V8: {
1240 newOpcode = EcmaOpcode::STOWNBYNAME_IMM8_ID16_V8;
1241 uint32_t id = inst.GetId();
1242 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
1243 *pc = static_cast<uint8_t>(newOpcode);
1244 *(pc + 1) = 0x00;
1245 uint16_t newId = static_cast<uint16_t>(id);
1246 if (memcpy_s(pc + 2, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) { // 2: skip opcode and ic slot
1247 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1248 UNREACHABLE();
1249 }
1250 *(pc + 4) = *(pc + 6); // 4: index of new opcode; 6: index of old opcode
1251 break;
1252 }
1253 case OldBytecodeInst::Opcode::ECMA_STSUPERBYNAME_PREF_ID32_V8: {
1254 newOpcode = EcmaOpcode::STSUPERBYNAME_IMM8_ID16_V8;
1255 uint32_t id = inst.GetId();
1256 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
1257 *pc = static_cast<uint8_t>(newOpcode);
1258 *(pc + 1) = 0x00;
1259 uint16_t newId = static_cast<uint16_t>(id);
1260 if (memcpy_s(pc + 2, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) { // 2: skip opcode and ic slot
1261 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1262 UNREACHABLE();
1263 }
1264 *(pc + 4) = *(pc + 6); // 4: index of new opcode; 6: index of old opcode
1265 break;
1266 }
1267 case OldBytecodeInst::Opcode::ECMA_STOWNBYNAMEWITHNAMESET_PREF_ID32_V8: {
1268 newOpcode = EcmaOpcode::STOWNBYNAMEWITHNAMESET_IMM8_ID16_V8;
1269 uint32_t id = inst.GetId();
1270 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
1271 *pc = static_cast<uint8_t>(newOpcode);
1272 *(pc + 1) = 0x00;
1273 uint16_t newId = static_cast<uint16_t>(id);
1274 if (memcpy_s(pc + 2, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) { // 2: skip opcode and ic slot
1275 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1276 UNREACHABLE();
1277 }
1278 *(pc + 4) = *(pc + 6); // 4: index of new opcode; 6: index of old opcode
1279 break;
1280 }
1281 case OldBytecodeInst::Opcode::ECMA_CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8: {
1282 newOpcode = EcmaOpcode::CREATEREGEXPWITHLITERAL_IMM8_ID16_IMM8;
1283 uint32_t id = inst.GetId();
1284 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
1285 *pc = static_cast<uint8_t>(newOpcode);
1286 *(pc + 1) = 0x00;
1287 uint16_t newId = static_cast<uint16_t>(id);
1288 if (memcpy_s(pc + 2, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) { // 2: skip opcode and ic slot
1289 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1290 UNREACHABLE();
1291 }
1292 *(pc + 4) = *(pc + 6); // 4: index of new opcode; 6: index of old opcode
1293 break;
1294 }
1295 // ID32 to ID16 no IC (PREF_ID32)
1296 case OldBytecodeInst::Opcode::ECMA_LDBIGINT_PREF_ID32: {
1297 newOpcode = EcmaOpcode::LDBIGINT_ID16;
1298 uint32_t id = inst.GetId();
1299 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
1300 *pc = static_cast<uint8_t>(newOpcode);
1301 uint16_t newId = static_cast<uint16_t>(id);
1302 if (memcpy_s(pc + 1, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) {
1303 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1304 UNREACHABLE();
1305 }
1306 break;
1307 }
1308 // Translate to other first level opcode
1309 case OldBytecodeInst::Opcode::ECMA_NEWOBJSPREADDYN_PREF_V8_V8: {
1310 newOpcode = EcmaOpcode::NEWOBJAPPLY_IMM8_V8;
1311 *pc = static_cast<uint8_t>(newOpcode);
1312 *(pc + 1) = 0x00;
1313 *(pc + 2) = *(pc + 3); // 2 & 3: skip newtarget, so move vreg1 to vreg0
1314 break;
1315 }
1316 case OldBytecodeInst::Opcode::ECMA_LDGLOBALVAR_PREF_ID32: {
1317 newOpcode = EcmaOpcode::LDGLOBALVAR_IMM16_ID16;
1318 uint32_t id = inst.GetId();
1319 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
1320 *pc = static_cast<uint8_t>(newOpcode);
1321 *(pc + 1) = 0x00;
1322 *(pc + 2) = 0x00;
1323 uint16_t newId = static_cast<uint16_t>(id);
1324 if (memcpy_s(pc + 3, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) { // 3: offset of id
1325 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1326 UNREACHABLE();
1327 }
1328 break;
1329 }
1330 case OldBytecodeInst::Opcode::ECMA_STGLOBALVAR_PREF_ID32: {
1331 newOpcode = EcmaOpcode::STGLOBALVAR_IMM16_ID16;
1332 uint32_t id = inst.GetId();
1333 LOG_ECMA_IF(id > std::numeric_limits<uint16_t>::max(), FATAL) << "Cannot translate to 16 bits: " << id;
1334 *pc = static_cast<uint8_t>(newOpcode);
1335 *(pc + 1) = 0x00;
1336 *(pc + 2) = 0x00;
1337 uint16_t newId = static_cast<uint16_t>(id);
1338 if (memcpy_s(pc + 3, sizeof(uint16_t), &newId, sizeof(uint16_t)) != EOK) { // 3: offset of id
1339 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1340 UNREACHABLE();
1341 }
1342 break;
1343 }
1344 case OldBytecodeInst::Opcode::ECMA_DEFINEMETHOD_PREF_ID16_IMM16_V8: {
1345 newOpcode = EcmaOpcode::DEFINEMETHOD_IMM8_ID16_IMM8;
1346 *pc = static_cast<uint8_t>(newOpcode);
1347 uint16_t imm = static_cast<uint16_t>(inst.GetImm<OldBytecodeInst::Format::PREF_ID16_IMM16_V8>());
1348 uint8_t newImm = static_cast<uint8_t>(imm);
1349 if (memcpy_s(pc + 4, sizeof(uint8_t), &newImm, sizeof(uint8_t)) != EOK) { // 4: offset of imm
1350 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1351 UNREACHABLE();
1352 }
1353 break;
1354 }
1355 case OldBytecodeInst::Opcode::ECMA_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8:
1356 U_FALLTHROUGH;
1357 case OldBytecodeInst::Opcode::ECMA_DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8:
1358 U_FALLTHROUGH;
1359 case OldBytecodeInst::Opcode::ECMA_DEFINENCFUNCDYN_PREF_ID16_IMM16_V8:
1360 U_FALLTHROUGH;
1361 case OldBytecodeInst::Opcode::ECMA_DEFINEFUNCDYN_PREF_ID16_IMM16_V8:
1362 U_FALLTHROUGH;
1363 case OldBytecodeInst::Opcode::ECMA_DEFINEASYNCGENERATORFUNC_PREF_ID16_IMM16_V8: {
1364 newOpcode = EcmaOpcode::DEFINEFUNC_IMM8_ID16_IMM8;
1365 *pc = static_cast<uint8_t>(newOpcode);
1366 uint16_t imm = static_cast<uint16_t>(inst.GetImm<OldBytecodeInst::Format::PREF_ID16_IMM16_V8>());
1367 uint8_t newImm = static_cast<uint8_t>(imm);
1368 if (memcpy_s(pc + 4, sizeof(uint8_t), &newImm, sizeof(uint8_t)) != EOK) { // 4: offset of imm
1369 LOG_FULL(FATAL) << "FixOpcode memcpy_s fail";
1370 UNREACHABLE();
1371 }
1372 break;
1373 }
1374 default:
1375 LOG_FULL(FATAL) << "Is not an Ecma Opcode opcode: " << static_cast<uint32_t>(opcode);
1376 UNREACHABLE();
1377 break;
1378 }
1379 ADD_NOP_INST(pc, oldLen, newOpcode);
1380 UpdateICOffset(method, pc);
1381 }
1382
1383 // reuse prefix 8bits to store slotid
UpdateICOffset(MethodLiteral * methodLiteral,uint8_t * pc)1384 void PandaFileTranslator::UpdateICOffset(MethodLiteral *methodLiteral, uint8_t *pc)
1385 {
1386 uint8_t offset = MethodLiteral::INVALID_IC_SLOT;
1387 BytecodeInstruction inst(pc);
1388 auto opcode = inst.GetOpcode();
1389 switch (opcode) {
1390 case EcmaOpcode::TRYLDGLOBALBYNAME_IMM8_ID16:
1391 U_FALLTHROUGH;
1392 case EcmaOpcode::TRYSTGLOBALBYNAME_IMM8_ID16:
1393 U_FALLTHROUGH;
1394 case EcmaOpcode::LDGLOBALVAR_IMM16_ID16:
1395 U_FALLTHROUGH;
1396 case EcmaOpcode::STGLOBALVAR_IMM16_ID16:
1397 offset = methodLiteral->UpdateSlotSizeWith8Bit(1);
1398 break;
1399 case EcmaOpcode::STOBJBYVALUE_IMM8_V8_V8:
1400 U_FALLTHROUGH;
1401 case EcmaOpcode::STOWNBYVALUE_IMM8_V8_V8:
1402 U_FALLTHROUGH;
1403 case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
1404 U_FALLTHROUGH;
1405 case EcmaOpcode::STOWNBYNAME_IMM8_ID16_V8:
1406 U_FALLTHROUGH;
1407 case EcmaOpcode::STSUPERBYVALUE_IMM8_V8_V8:
1408 U_FALLTHROUGH;
1409 case EcmaOpcode::STSUPERBYNAME_IMM8_ID16_V8:
1410 offset = methodLiteral->UpdateSlotSizeWith8Bit(2); // 2: occupy two ic slot
1411 break;
1412 default:
1413 return;
1414 }
1415
1416 if (opcode == EcmaOpcode::LDGLOBALVAR_IMM16_ID16 || opcode == EcmaOpcode::STGLOBALVAR_IMM16_ID16) {
1417 uint16_t icSlot = static_cast<uint16_t>(offset);
1418 if (memcpy_s(pc + 1, sizeof(uint16_t), &icSlot, sizeof(uint16_t)) != EOK) {
1419 LOG_FULL(FATAL) << "UpdateICOffset memcpy_s fail";
1420 UNREACHABLE();
1421 }
1422 } else {
1423 *(pc + 1) = offset;
1424 }
1425 }
1426
FixInstructionId32(const OldBytecodeInst & inst,uint32_t index,uint32_t fixOrder)1427 void PandaFileTranslator::FixInstructionId32(const OldBytecodeInst &inst, uint32_t index, uint32_t fixOrder)
1428 {
1429 // NOLINTNEXTLINE(hicpp-use-auto)
1430 auto pc = const_cast<uint8_t *>(inst.GetAddress());
1431 switch (OldBytecodeInst::GetFormat(inst.GetOpcode())) {
1432 case OldBytecodeInst::Format::ID32: {
1433 uint8_t size = sizeof(uint32_t);
1434 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1435 if (memcpy_s(pc + FixInstructionIndex::FIX_ONE, size, &index, size) != EOK) {
1436 LOG_FULL(FATAL) << "memcpy_s failed";
1437 UNREACHABLE();
1438 }
1439 break;
1440 }
1441 case OldBytecodeInst::Format::PREF_ID16_IMM16_V8: {
1442 uint16_t u16Index = index;
1443 uint8_t size = sizeof(uint16_t);
1444 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1445 if (memcpy_s(pc + FixInstructionIndex::FIX_TWO, size, &u16Index, size) != EOK) {
1446 LOG_FULL(FATAL) << "memcpy_s failed";
1447 UNREACHABLE();
1448 }
1449 break;
1450 }
1451 case OldBytecodeInst::Format::PREF_ID32:
1452 U_FALLTHROUGH;
1453 case OldBytecodeInst::Format::PREF_ID32_V8:
1454 U_FALLTHROUGH;
1455 case OldBytecodeInst::Format::PREF_ID32_IMM8: {
1456 uint8_t size = sizeof(uint32_t);
1457 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1458 if (memcpy_s(pc + FixInstructionIndex::FIX_TWO, size, &index, size) != EOK) {
1459 LOG_FULL(FATAL) << "memcpy_s failed";
1460 UNREACHABLE();
1461 }
1462 break;
1463 }
1464 case OldBytecodeInst::Format::PREF_IMM16: {
1465 ASSERT(static_cast<uint16_t>(index) == index);
1466 uint16_t u16Index = index;
1467 uint8_t size = sizeof(uint16_t);
1468 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1469 if (memcpy_s(pc + FixInstructionIndex::FIX_TWO, size, &u16Index, size) != EOK) {
1470 LOG_FULL(FATAL) << "memcpy_s failed";
1471 UNREACHABLE();
1472 }
1473 break;
1474 }
1475 case OldBytecodeInst::Format::PREF_ID16_IMM16_IMM16_V8_V8: {
1476 // Usually, we fix one part of instruction one time. But as for instruction DefineClassWithBuffer,
1477 // which use both method id and literal buffer id.Using fixOrder indicates fix Location.
1478 if (fixOrder == 0) {
1479 uint8_t size = sizeof(uint16_t);
1480 ASSERT(static_cast<uint16_t>(index) == index);
1481 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1482 if (memcpy_s(pc + FixInstructionIndex::FIX_TWO, size, &index, size) != EOK) {
1483 LOG_FULL(FATAL) << "memcpy_s failed";
1484 UNREACHABLE();
1485 }
1486 break;
1487 }
1488 if (fixOrder == 1) {
1489 ASSERT(static_cast<uint16_t>(index) == index);
1490 uint16_t u16Index = index;
1491 uint8_t size = sizeof(uint16_t);
1492 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1493 if (memcpy_s(pc + FixInstructionIndex::FIX_FOUR, size, &u16Index, size) != EOK) {
1494 LOG_FULL(FATAL) << "memcpy_s failed";
1495 UNREACHABLE();
1496 }
1497 break;
1498 }
1499 break;
1500 }
1501 default:
1502 UNREACHABLE();
1503 }
1504 }
1505
TranslateBytecode(JSPandaFile * jsPandaFile,uint32_t insSz,const uint8_t * insArr,const MethodLiteral * method,const CString & entryPoint)1506 void PandaFileTranslator::TranslateBytecode(JSPandaFile *jsPandaFile, uint32_t insSz, const uint8_t *insArr,
1507 const MethodLiteral *method, const CString &entryPoint)
1508 {
1509 const panda_file::File *pf = jsPandaFile->GetPandaFile();
1510 auto bcIns = OldBytecodeInst(insArr);
1511 auto bcInsLast = bcIns.JumpTo(insSz);
1512 const CUnorderedMap<uint32_t, uint64_t> *ConstpoolMap = jsPandaFile->GetConstpoolMapByReocrd(entryPoint);
1513 while (bcIns.GetAddress() != bcInsLast.GetAddress()) {
1514 if (bcIns.HasFlag(OldBytecodeInst::Flags::STRING_ID) &&
1515 OldBytecodeInst::HasId(OldBytecodeInst::GetFormat(bcIns.GetOpcode()), 0)) {
1516 auto index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::STRING, bcIns.GetId());
1517 FixInstructionId32(bcIns, index);
1518 } else {
1519 OldBytecodeInst::Opcode opcode = static_cast<OldBytecodeInst::Opcode>(bcIns.GetOpcode());
1520 switch (opcode) {
1521 uint32_t index;
1522 uint32_t methodId;
1523 case OldBytecodeInst::Opcode::ECMA_DEFINEFUNCDYN_PREF_ID16_IMM16_V8:
1524 methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId()).GetOffset();
1525 index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::BASE_FUNCTION, methodId, ConstpoolMap);
1526 FixInstructionId32(bcIns, index);
1527 break;
1528 case OldBytecodeInst::Opcode::ECMA_DEFINENCFUNCDYN_PREF_ID16_IMM16_V8:
1529 methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId()).GetOffset();
1530 index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::NC_FUNCTION, methodId, ConstpoolMap);
1531 FixInstructionId32(bcIns, index);
1532 break;
1533 case OldBytecodeInst::Opcode::ECMA_DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8:
1534 methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId()).GetOffset();
1535 index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::GENERATOR_FUNCTION, methodId,
1536 ConstpoolMap);
1537 FixInstructionId32(bcIns, index);
1538 break;
1539 case OldBytecodeInst::Opcode::ECMA_DEFINEASYNCGENERATORFUNC_PREF_ID16_IMM16_V8:
1540 methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId()).GetOffset();
1541 index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::ASYNC_GENERATOR_FUNCTION, methodId,
1542 ConstpoolMap);
1543 FixInstructionId32(bcIns, index);
1544 break;
1545 case OldBytecodeInst::Opcode::ECMA_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8:
1546 methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId()).GetOffset();
1547 index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::ASYNC_FUNCTION, methodId, ConstpoolMap);
1548 FixInstructionId32(bcIns, index);
1549 break;
1550 case OldBytecodeInst::Opcode::ECMA_DEFINEMETHOD_PREF_ID16_IMM16_V8:
1551 methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId()).GetOffset();
1552 index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::METHOD, methodId, ConstpoolMap);
1553 FixInstructionId32(bcIns, index);
1554 break;
1555 case OldBytecodeInst::Opcode::ECMA_CREATEOBJECTWITHBUFFER_PREF_IMM16:
1556 U_FALLTHROUGH;
1557 case OldBytecodeInst::Opcode::ECMA_CREATEOBJECTHAVINGMETHOD_PREF_IMM16: {
1558 auto imm = bcIns.GetImm<OldBytecodeInst::Format::PREF_IMM16>();
1559 index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::OBJECT_LITERAL,
1560 static_cast<uint16_t>(imm), ConstpoolMap);
1561 FixInstructionId32(bcIns, index);
1562 break;
1563 }
1564 case OldBytecodeInst::Opcode::ECMA_CREATEARRAYWITHBUFFER_PREF_IMM16: {
1565 auto imm = bcIns.GetImm<OldBytecodeInst::Format::PREF_IMM16>();
1566 index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::ARRAY_LITERAL,
1567 static_cast<uint16_t>(imm), ConstpoolMap);
1568 FixInstructionId32(bcIns, index);
1569 break;
1570 }
1571 case OldBytecodeInst::Opcode::ECMA_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8: {
1572 methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId()).GetOffset();
1573 index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::CLASS_FUNCTION, methodId, ConstpoolMap);
1574 FixInstructionId32(bcIns, index);
1575 auto imm = bcIns.GetImm<OldBytecodeInst::Format::PREF_ID16_IMM16_IMM16_V8_V8>();
1576 index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::CLASS_LITERAL,
1577 static_cast<uint16_t>(imm), ConstpoolMap);
1578 FixInstructionId32(bcIns, index, 1);
1579 break;
1580 }
1581 default:
1582 break;
1583 }
1584 }
1585 // NOLINTNEXTLINE(hicpp-use-auto)
1586 auto nextInst = bcIns.GetNext();
1587 FixOpcode(const_cast<MethodLiteral *>(method), bcIns);
1588 bcIns = nextInst;
1589 }
1590 }
1591 } // namespace panda::ecmascript
1592