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