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