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