11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ 61cb0ef41Sopenharmony_ci#define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/ast/ast.h" 91cb0ef41Sopenharmony_ci#include "src/base/compiler-specific.h" 101cb0ef41Sopenharmony_ci#include "src/base/export-template.h" 111cb0ef41Sopenharmony_ci#include "src/common/globals.h" 121cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-array-writer.h" 131cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-flags.h" 141cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-register-allocator.h" 151cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-register.h" 161cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-source-info.h" 171cb0ef41Sopenharmony_ci#include "src/interpreter/bytecodes.h" 181cb0ef41Sopenharmony_ci#include "src/interpreter/constant-array-builder.h" 191cb0ef41Sopenharmony_ci#include "src/interpreter/handler-table-builder.h" 201cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h" 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_cinamespace v8 { 231cb0ef41Sopenharmony_cinamespace internal { 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ciclass BytecodeArray; 261cb0ef41Sopenharmony_ciclass FeedbackVectorSpec; 271cb0ef41Sopenharmony_ciclass Isolate; 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_cinamespace interpreter { 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ciclass BytecodeLabel; 321cb0ef41Sopenharmony_ciclass BytecodeLoopHeader; 331cb0ef41Sopenharmony_ciclass BytecodeNode; 341cb0ef41Sopenharmony_ciclass BytecodeRegisterOptimizer; 351cb0ef41Sopenharmony_ciclass BytecodeJumpTable; 361cb0ef41Sopenharmony_ciclass Register; 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE BytecodeArrayBuilder final { 391cb0ef41Sopenharmony_ci public: 401cb0ef41Sopenharmony_ci BytecodeArrayBuilder( 411cb0ef41Sopenharmony_ci Zone* zone, int parameter_count, int locals_count, 421cb0ef41Sopenharmony_ci FeedbackVectorSpec* feedback_vector_spec = nullptr, 431cb0ef41Sopenharmony_ci SourcePositionTableBuilder::RecordingMode source_position_mode = 441cb0ef41Sopenharmony_ci SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS); 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci BytecodeArrayBuilder(const BytecodeArrayBuilder&) = delete; 471cb0ef41Sopenharmony_ci BytecodeArrayBuilder& operator=(const BytecodeArrayBuilder&) = delete; 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci template <typename IsolateT> 501cb0ef41Sopenharmony_ci EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 511cb0ef41Sopenharmony_ci Handle<BytecodeArray> ToBytecodeArray(IsolateT* isolate); 521cb0ef41Sopenharmony_ci template <typename IsolateT> 531cb0ef41Sopenharmony_ci EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 541cb0ef41Sopenharmony_ci Handle<ByteArray> ToSourcePositionTable(IsolateT* isolate); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci#ifdef DEBUG 571cb0ef41Sopenharmony_ci int CheckBytecodeMatches(BytecodeArray bytecode); 581cb0ef41Sopenharmony_ci#endif 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci // Get the number of parameters expected by function. 611cb0ef41Sopenharmony_ci int parameter_count() const { 621cb0ef41Sopenharmony_ci DCHECK_GE(parameter_count_, 0); 631cb0ef41Sopenharmony_ci return parameter_count_; 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci // Get the number of locals required for bytecode array. 671cb0ef41Sopenharmony_ci int locals_count() const { 681cb0ef41Sopenharmony_ci DCHECK_GE(local_register_count_, 0); 691cb0ef41Sopenharmony_ci return local_register_count_; 701cb0ef41Sopenharmony_ci } 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci // Returns the number of fixed (non-temporary) registers. 731cb0ef41Sopenharmony_ci int fixed_register_count() const { return locals_count(); } 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci // Returns the number of fixed and temporary registers. 761cb0ef41Sopenharmony_ci int total_register_count() const { 771cb0ef41Sopenharmony_ci DCHECK_LE(fixed_register_count(), 781cb0ef41Sopenharmony_ci register_allocator()->maximum_register_count()); 791cb0ef41Sopenharmony_ci return register_allocator()->maximum_register_count(); 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci Register Local(int index) const; 831cb0ef41Sopenharmony_ci Register Parameter(int parameter_index) const; 841cb0ef41Sopenharmony_ci Register Receiver() const; 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci // Constant loads to accumulator. 871cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadConstantPoolEntry(size_t entry); 881cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadLiteral(Smi value); 891cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadLiteral(double value); 901cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadLiteral(const AstRawString* raw_string); 911cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadLiteral(const Scope* scope); 921cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadLiteral(AstBigInt bigint); 931cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadUndefined(); 941cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadNull(); 951cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadTheHole(); 961cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadTrue(); 971cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadFalse(); 981cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadBoolean(bool value); 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci // Global loads to the accumulator and stores from the accumulator. 1011cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadGlobal(const AstRawString* name, int feedback_slot, 1021cb0ef41Sopenharmony_ci TypeofMode typeof_mode); 1031cb0ef41Sopenharmony_ci BytecodeArrayBuilder& StoreGlobal(const AstRawString* name, 1041cb0ef41Sopenharmony_ci int feedback_slot); 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci // Load the object at |slot_index| at |depth| in the context chain starting 1071cb0ef41Sopenharmony_ci // with |context| into the accumulator. 1081cb0ef41Sopenharmony_ci enum ContextSlotMutability { kImmutableSlot, kMutableSlot }; 1091cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadContextSlot(Register context, int slot_index, 1101cb0ef41Sopenharmony_ci int depth, 1111cb0ef41Sopenharmony_ci ContextSlotMutability immutable); 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci // Stores the object in the accumulator into |slot_index| at |depth| in the 1141cb0ef41Sopenharmony_ci // context chain starting with |context|. 1151cb0ef41Sopenharmony_ci BytecodeArrayBuilder& StoreContextSlot(Register context, int slot_index, 1161cb0ef41Sopenharmony_ci int depth); 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci // Load from a module variable into the accumulator. |depth| is the depth of 1191cb0ef41Sopenharmony_ci // the current context relative to the module context. 1201cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadModuleVariable(int cell_index, int depth); 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci // Store from the accumulator into a module variable. |depth| is the depth of 1231cb0ef41Sopenharmony_ci // the current context relative to the module context. 1241cb0ef41Sopenharmony_ci BytecodeArrayBuilder& StoreModuleVariable(int cell_index, int depth); 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci // Register-accumulator transfers. 1271cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadAccumulatorWithRegister(Register reg); 1281cb0ef41Sopenharmony_ci BytecodeArrayBuilder& StoreAccumulatorInRegister(Register reg); 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci // Register-register transfer. 1311cb0ef41Sopenharmony_ci BytecodeArrayBuilder& MoveRegister(Register from, Register to); 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci // Named load property. 1341cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadNamedProperty(Register object, 1351cb0ef41Sopenharmony_ci const AstRawString* name, 1361cb0ef41Sopenharmony_ci int feedback_slot); 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadNamedPropertyFromSuper(Register object, 1391cb0ef41Sopenharmony_ci const AstRawString* name, 1401cb0ef41Sopenharmony_ci int feedback_slot); 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci // Keyed load property. The key should be in the accumulator. 1431cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadKeyedProperty(Register object, int feedback_slot); 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ci // Named load property of the @@iterator symbol. 1461cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadIteratorProperty(Register object, 1471cb0ef41Sopenharmony_ci int feedback_slot); 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci // Load and call property of the @@iterator symbol 1501cb0ef41Sopenharmony_ci BytecodeArrayBuilder& GetIterator(Register object, int load_feedback_slot, 1511cb0ef41Sopenharmony_ci int call_feedback_slot); 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci // Named load property of the @@asyncIterator symbol. 1541cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadAsyncIteratorProperty(Register object, 1551cb0ef41Sopenharmony_ci int feedback_slot); 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci // Store properties. Flag for NeedsSetFunctionName() should 1581cb0ef41Sopenharmony_ci // be in the accumulator. 1591cb0ef41Sopenharmony_ci BytecodeArrayBuilder& DefineKeyedOwnPropertyInLiteral( 1601cb0ef41Sopenharmony_ci Register object, Register name, 1611cb0ef41Sopenharmony_ci DefineKeyedOwnPropertyInLiteralFlags flags, int feedback_slot); 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci // Collect type information for developer tools. The value for which we 1641cb0ef41Sopenharmony_ci // record the type is stored in the accumulator. 1651cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CollectTypeProfile(int position); 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci // Set a property named by a property name, trigger the setters and 1681cb0ef41Sopenharmony_ci // set traps if necessary. The value to be set should be in the 1691cb0ef41Sopenharmony_ci // accumulator. 1701cb0ef41Sopenharmony_ci BytecodeArrayBuilder& SetNamedProperty(Register object, 1711cb0ef41Sopenharmony_ci const AstRawString* name, 1721cb0ef41Sopenharmony_ci int feedback_slot, 1731cb0ef41Sopenharmony_ci LanguageMode language_mode); 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci // Set a property named by a constant from the constant pool, 1761cb0ef41Sopenharmony_ci // trigger the setters and set traps if necessary. The value to be 1771cb0ef41Sopenharmony_ci // set should be in the accumulator. 1781cb0ef41Sopenharmony_ci BytecodeArrayBuilder& SetNamedProperty(Register object, 1791cb0ef41Sopenharmony_ci size_t constant_pool_entry, 1801cb0ef41Sopenharmony_ci int feedback_slot, 1811cb0ef41Sopenharmony_ci LanguageMode language_mode); 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci // Define an own property named by a constant from the constant pool, 1841cb0ef41Sopenharmony_ci // trigger the defineProperty traps if necessary. The value to be 1851cb0ef41Sopenharmony_ci // defined should be in the accumulator. 1861cb0ef41Sopenharmony_ci BytecodeArrayBuilder& DefineNamedOwnProperty(Register object, 1871cb0ef41Sopenharmony_ci const AstRawString* name, 1881cb0ef41Sopenharmony_ci int feedback_slot); 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci // Set a property keyed by a value in a register, trigger the setters and 1911cb0ef41Sopenharmony_ci // set traps if necessary. The value to be set should be in the 1921cb0ef41Sopenharmony_ci // accumulator. 1931cb0ef41Sopenharmony_ci BytecodeArrayBuilder& SetKeyedProperty(Register object, Register key, 1941cb0ef41Sopenharmony_ci int feedback_slot, 1951cb0ef41Sopenharmony_ci LanguageMode language_mode); 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci // Define an own property keyed by a value in a register, trigger the 1981cb0ef41Sopenharmony_ci // defineProperty traps if necessary. The value to be defined should be 1991cb0ef41Sopenharmony_ci // in the accumulator. 2001cb0ef41Sopenharmony_ci BytecodeArrayBuilder& DefineKeyedOwnProperty(Register object, Register key, 2011cb0ef41Sopenharmony_ci int feedback_slot); 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci // Store an own element in an array literal. The value to be stored should be 2041cb0ef41Sopenharmony_ci // in the accumulator. 2051cb0ef41Sopenharmony_ci BytecodeArrayBuilder& StoreInArrayLiteral(Register array, Register index, 2061cb0ef41Sopenharmony_ci int feedback_slot); 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci // Store the class fields property. The initializer to be stored should 2091cb0ef41Sopenharmony_ci // be in the accumulator. 2101cb0ef41Sopenharmony_ci BytecodeArrayBuilder& StoreClassFieldsInitializer(Register constructor, 2111cb0ef41Sopenharmony_ci int feedback_slot); 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ci // Load class fields property. 2141cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadClassFieldsInitializer(Register constructor, 2151cb0ef41Sopenharmony_ci int feedback_slot); 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci // Lookup the variable with |name|. 2181cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadLookupSlot(const AstRawString* name, 2191cb0ef41Sopenharmony_ci TypeofMode typeof_mode); 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci // Lookup the variable with |name|, which is known to be at |slot_index| at 2221cb0ef41Sopenharmony_ci // |depth| in the context chain if not shadowed by a context extension 2231cb0ef41Sopenharmony_ci // somewhere in that context chain. 2241cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadLookupContextSlot(const AstRawString* name, 2251cb0ef41Sopenharmony_ci TypeofMode typeof_mode, 2261cb0ef41Sopenharmony_ci int slot_index, int depth); 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci // Lookup the variable with |name|, which has its feedback in |feedback_slot| 2291cb0ef41Sopenharmony_ci // and is known to be global if not shadowed by a context extension somewhere 2301cb0ef41Sopenharmony_ci // up to |depth| in that context chain. 2311cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LoadLookupGlobalSlot(const AstRawString* name, 2321cb0ef41Sopenharmony_ci TypeofMode typeof_mode, 2331cb0ef41Sopenharmony_ci int feedback_slot, int depth); 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ci // Store value in the accumulator into the variable with |name|. 2361cb0ef41Sopenharmony_ci BytecodeArrayBuilder& StoreLookupSlot( 2371cb0ef41Sopenharmony_ci const AstRawString* name, LanguageMode language_mode, 2381cb0ef41Sopenharmony_ci LookupHoistingMode lookup_hoisting_mode); 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ci // Create a new closure for a SharedFunctionInfo which will be inserted at 2411cb0ef41Sopenharmony_ci // constant pool index |shared_function_info_entry|. 2421cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateClosure(size_t shared_function_info_entry, 2431cb0ef41Sopenharmony_ci int slot, int flags); 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci // Create a new local context for a |scope|. 2461cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateBlockContext(const Scope* scope); 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci // Create a new context for a catch block with |exception| and |scope|. 2491cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateCatchContext(Register exception, 2501cb0ef41Sopenharmony_ci const Scope* scope); 2511cb0ef41Sopenharmony_ci 2521cb0ef41Sopenharmony_ci // Create a new context with the given |scope| and size |slots|. 2531cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateFunctionContext(const Scope* scope, int slots); 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci // Create a new eval context with the given |scope| and size |slots|. 2561cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateEvalContext(const Scope* scope, int slots); 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ci // Creates a new context with the given |scope| for a with-statement 2591cb0ef41Sopenharmony_ci // with the |object| in a register. 2601cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateWithContext(Register object, const Scope* scope); 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci // Create a new arguments object in the accumulator. 2631cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type); 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_ci // Literals creation. Constant elements should be in the accumulator. 2661cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateRegExpLiteral(const AstRawString* pattern, 2671cb0ef41Sopenharmony_ci int literal_index, int flags); 2681cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateArrayLiteral(size_t constant_elements_entry, 2691cb0ef41Sopenharmony_ci int literal_index, int flags); 2701cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateEmptyArrayLiteral(int literal_index); 2711cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateArrayFromIterable(); 2721cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateObjectLiteral(size_t constant_properties_entry, 2731cb0ef41Sopenharmony_ci int literal_index, int flags); 2741cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CreateEmptyObjectLiteral(); 2751cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CloneObject(Register source, int flags, 2761cb0ef41Sopenharmony_ci int feedback_slot); 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ci // Gets or creates the template for a TemplateObjectDescription which will 2791cb0ef41Sopenharmony_ci // be inserted at constant pool index |template_object_description_entry|. 2801cb0ef41Sopenharmony_ci BytecodeArrayBuilder& GetTemplateObject( 2811cb0ef41Sopenharmony_ci size_t template_object_description_entry, int feedback_slot); 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci // Push the context in accumulator as the new context, and store in register 2841cb0ef41Sopenharmony_ci // |context|. 2851cb0ef41Sopenharmony_ci BytecodeArrayBuilder& PushContext(Register context); 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci // Pop the current context and replace with |context|. 2881cb0ef41Sopenharmony_ci BytecodeArrayBuilder& PopContext(Register context); 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_ci // Call a JS function which is known to be a property of a JS object. The 2911cb0ef41Sopenharmony_ci // JSFunction or Callable to be called should be in |callable|. The arguments 2921cb0ef41Sopenharmony_ci // should be in |args|, with the receiver in |args[0]|. The call type of the 2931cb0ef41Sopenharmony_ci // expression is in |call_type|. Type feedback is recorded in the 2941cb0ef41Sopenharmony_ci // |feedback_slot| in the type feedback vector. 2951cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CallProperty(Register callable, RegisterList args, 2961cb0ef41Sopenharmony_ci int feedback_slot); 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ci // Call a JS function with an known undefined receiver. The JSFunction or 2991cb0ef41Sopenharmony_ci // Callable to be called should be in |callable|. The arguments should be in 3001cb0ef41Sopenharmony_ci // |args|, with no receiver as it is implicitly set to undefined. Type 3011cb0ef41Sopenharmony_ci // feedback is recorded in the |feedback_slot| in the type feedback vector. 3021cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CallUndefinedReceiver(Register callable, 3031cb0ef41Sopenharmony_ci RegisterList args, 3041cb0ef41Sopenharmony_ci int feedback_slot); 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci // Call a JS function with an any receiver, possibly (but not necessarily) 3071cb0ef41Sopenharmony_ci // undefined. The JSFunction or Callable to be called should be in |callable|. 3081cb0ef41Sopenharmony_ci // The arguments should be in |args|, with the receiver in |args[0]|. Type 3091cb0ef41Sopenharmony_ci // feedback is recorded in the |feedback_slot| in the type feedback vector. 3101cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CallAnyReceiver(Register callable, RegisterList args, 3111cb0ef41Sopenharmony_ci int feedback_slot); 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci // Tail call into a JS function. The JSFunction or Callable to be called 3141cb0ef41Sopenharmony_ci // should be in |callable|. The arguments should be in |args|, with the 3151cb0ef41Sopenharmony_ci // receiver in |args[0]|. Type feedback is recorded in the |feedback_slot| in 3161cb0ef41Sopenharmony_ci // the type feedback vector. 3171cb0ef41Sopenharmony_ci BytecodeArrayBuilder& TailCall(Register callable, RegisterList args, 3181cb0ef41Sopenharmony_ci int feedback_slot); 3191cb0ef41Sopenharmony_ci 3201cb0ef41Sopenharmony_ci // Call a JS function. The JSFunction or Callable to be called should be in 3211cb0ef41Sopenharmony_ci // |callable|, the receiver in |args[0]| and the arguments in |args[1]| 3221cb0ef41Sopenharmony_ci // onwards. The final argument must be a spread. 3231cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CallWithSpread(Register callable, RegisterList args, 3241cb0ef41Sopenharmony_ci int feedback_slot); 3251cb0ef41Sopenharmony_ci 3261cb0ef41Sopenharmony_ci // Call the Construct operator. The accumulator holds the |new_target|. 3271cb0ef41Sopenharmony_ci // The |constructor| is in a register and arguments are in |args|. 3281cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Construct(Register constructor, RegisterList args, 3291cb0ef41Sopenharmony_ci int feedback_slot); 3301cb0ef41Sopenharmony_ci 3311cb0ef41Sopenharmony_ci // Call the Construct operator for use with a spread. The accumulator holds 3321cb0ef41Sopenharmony_ci // the |new_target|. The |constructor| is in a register and arguments are in 3331cb0ef41Sopenharmony_ci // |args|. The final argument must be a spread. 3341cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ConstructWithSpread(Register constructor, 3351cb0ef41Sopenharmony_ci RegisterList args, 3361cb0ef41Sopenharmony_ci int feedback_slot); 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ci // Call the runtime function with |function_id| and arguments |args|. 3391cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id, 3401cb0ef41Sopenharmony_ci RegisterList args); 3411cb0ef41Sopenharmony_ci // Call the runtime function with |function_id| with single argument |arg|. 3421cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id, 3431cb0ef41Sopenharmony_ci Register arg); 3441cb0ef41Sopenharmony_ci // Call the runtime function with |function_id| with no arguments. 3451cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id); 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_ci // Call the runtime function with |function_id| and arguments |args|, that 3481cb0ef41Sopenharmony_ci // returns a pair of values. The return values will be returned in 3491cb0ef41Sopenharmony_ci // |return_pair|. 3501cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id, 3511cb0ef41Sopenharmony_ci RegisterList args, 3521cb0ef41Sopenharmony_ci RegisterList return_pair); 3531cb0ef41Sopenharmony_ci // Call the runtime function with |function_id| with single argument |arg| 3541cb0ef41Sopenharmony_ci // that returns a pair of values. The return values will be returned in 3551cb0ef41Sopenharmony_ci // |return_pair|. 3561cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id, 3571cb0ef41Sopenharmony_ci Register arg, 3581cb0ef41Sopenharmony_ci RegisterList return_pair); 3591cb0ef41Sopenharmony_ci 3601cb0ef41Sopenharmony_ci // Call the JS runtime function with |context_index| and arguments |args|, 3611cb0ef41Sopenharmony_ci // with no receiver as it is implicitly set to undefined. 3621cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CallJSRuntime(int context_index, RegisterList args); 3631cb0ef41Sopenharmony_ci 3641cb0ef41Sopenharmony_ci // Operators (register holds the lhs value, accumulator holds the rhs value). 3651cb0ef41Sopenharmony_ci // Type feedback will be recorded in the |feedback_slot| 3661cb0ef41Sopenharmony_ci BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg, 3671cb0ef41Sopenharmony_ci int feedback_slot); 3681cb0ef41Sopenharmony_ci // Same as above, but lhs in the accumulator and rhs in |literal|. 3691cb0ef41Sopenharmony_ci BytecodeArrayBuilder& BinaryOperationSmiLiteral(Token::Value binop, 3701cb0ef41Sopenharmony_ci Smi literal, 3711cb0ef41Sopenharmony_ci int feedback_slot); 3721cb0ef41Sopenharmony_ci 3731cb0ef41Sopenharmony_ci // Unary and Count Operators (value stored in accumulator). 3741cb0ef41Sopenharmony_ci // Type feedback will be recorded in the |feedback_slot| 3751cb0ef41Sopenharmony_ci BytecodeArrayBuilder& UnaryOperation(Token::Value op, int feedback_slot); 3761cb0ef41Sopenharmony_ci 3771cb0ef41Sopenharmony_ci enum class ToBooleanMode { 3781cb0ef41Sopenharmony_ci kConvertToBoolean, // Perform ToBoolean conversion on accumulator. 3791cb0ef41Sopenharmony_ci kAlreadyBoolean, // Accumulator is already a Boolean. 3801cb0ef41Sopenharmony_ci }; 3811cb0ef41Sopenharmony_ci 3821cb0ef41Sopenharmony_ci // Unary Operators. 3831cb0ef41Sopenharmony_ci BytecodeArrayBuilder& LogicalNot(ToBooleanMode mode); 3841cb0ef41Sopenharmony_ci BytecodeArrayBuilder& TypeOf(); 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_ci // Expects a heap object in the accumulator. Returns its super constructor in 3871cb0ef41Sopenharmony_ci // the register |out| if it passes the IsConstructor test. Otherwise, it 3881cb0ef41Sopenharmony_ci // throws a TypeError exception. 3891cb0ef41Sopenharmony_ci BytecodeArrayBuilder& GetSuperConstructor(Register out); 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci // Deletes property from an object. This expects that accumulator contains 3921cb0ef41Sopenharmony_ci // the key to be deleted and the register contains a reference to the object. 3931cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Delete(Register object, LanguageMode language_mode); 3941cb0ef41Sopenharmony_ci 3951cb0ef41Sopenharmony_ci // JavaScript defines two kinds of 'nil'. 3961cb0ef41Sopenharmony_ci enum NilValue { kNullValue, kUndefinedValue }; 3971cb0ef41Sopenharmony_ci 3981cb0ef41Sopenharmony_ci // Tests. 3991cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg, 4001cb0ef41Sopenharmony_ci int feedback_slot); 4011cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CompareReference(Register reg); 4021cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CompareUndetectable(); 4031cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CompareUndefined(); 4041cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CompareNull(); 4051cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CompareNil(Token::Value op, NilValue nil); 4061cb0ef41Sopenharmony_ci BytecodeArrayBuilder& CompareTypeOf( 4071cb0ef41Sopenharmony_ci TestTypeOfFlags::LiteralFlag literal_flag); 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci // Converts accumulator and stores result in register |out|. 4101cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ToObject(Register out); 4111cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ToName(Register out); 4121cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ToString(); 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci // Converts accumulator and stores result back in accumulator. 4151cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ToNumber(int feedback_slot); 4161cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ToNumeric(int feedback_slot); 4171cb0ef41Sopenharmony_ci 4181cb0ef41Sopenharmony_ci // Exception handling. 4191cb0ef41Sopenharmony_ci BytecodeArrayBuilder& MarkHandler(int handler_id, 4201cb0ef41Sopenharmony_ci HandlerTable::CatchPrediction will_catch); 4211cb0ef41Sopenharmony_ci BytecodeArrayBuilder& MarkTryBegin(int handler_id, Register context); 4221cb0ef41Sopenharmony_ci BytecodeArrayBuilder& MarkTryEnd(int handler_id); 4231cb0ef41Sopenharmony_ci 4241cb0ef41Sopenharmony_ci // Flow Control. 4251cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Bind(BytecodeLabel* label); 4261cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Bind(BytecodeLoopHeader* label); 4271cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Bind(BytecodeJumpTable* jump_table, int case_value); 4281cb0ef41Sopenharmony_ci 4291cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Jump(BytecodeLabel* label); 4301cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpLoop(BytecodeLoopHeader* loop_header, 4311cb0ef41Sopenharmony_ci int loop_depth, int position); 4321cb0ef41Sopenharmony_ci 4331cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpIfTrue(ToBooleanMode mode, BytecodeLabel* label); 4341cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpIfFalse(ToBooleanMode mode, BytecodeLabel* label); 4351cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpIfJSReceiver(BytecodeLabel* label); 4361cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label); 4371cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpIfNotNull(BytecodeLabel* label); 4381cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpIfUndefined(BytecodeLabel* label); 4391cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpIfUndefinedOrNull(BytecodeLabel* label); 4401cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpIfNotUndefined(BytecodeLabel* label); 4411cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpIfNil(BytecodeLabel* label, Token::Value op, 4421cb0ef41Sopenharmony_ci NilValue nil); 4431cb0ef41Sopenharmony_ci BytecodeArrayBuilder& JumpIfNotNil(BytecodeLabel* label, Token::Value op, 4441cb0ef41Sopenharmony_ci NilValue nil); 4451cb0ef41Sopenharmony_ci 4461cb0ef41Sopenharmony_ci BytecodeArrayBuilder& SwitchOnSmiNoFeedback(BytecodeJumpTable* jump_table); 4471cb0ef41Sopenharmony_ci 4481cb0ef41Sopenharmony_ci // Sets the pending message to the value in the accumulator, and returns the 4491cb0ef41Sopenharmony_ci // previous pending message in the accumulator. 4501cb0ef41Sopenharmony_ci BytecodeArrayBuilder& SetPendingMessage(); 4511cb0ef41Sopenharmony_ci 4521cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Throw(); 4531cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ReThrow(); 4541cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Abort(AbortReason reason); 4551cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Return(); 4561cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ThrowReferenceErrorIfHole(const AstRawString* name); 4571cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ThrowSuperNotCalledIfHole(); 4581cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ThrowSuperAlreadyCalledIfNotHole(); 4591cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ThrowIfNotSuperConstructor(Register constructor); 4601cb0ef41Sopenharmony_ci 4611cb0ef41Sopenharmony_ci // Debugger. 4621cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Debugger(); 4631cb0ef41Sopenharmony_ci 4641cb0ef41Sopenharmony_ci // Increment the block counter at the given slot (block code coverage). 4651cb0ef41Sopenharmony_ci BytecodeArrayBuilder& IncBlockCounter(int slot); 4661cb0ef41Sopenharmony_ci 4671cb0ef41Sopenharmony_ci // Complex flow control. 4681cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ForInEnumerate(Register receiver); 4691cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ForInPrepare(RegisterList cache_info_triple, 4701cb0ef41Sopenharmony_ci int feedback_slot); 4711cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ForInContinue(Register index, Register cache_length); 4721cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ForInNext(Register receiver, Register index, 4731cb0ef41Sopenharmony_ci RegisterList cache_type_array_pair, 4741cb0ef41Sopenharmony_ci int feedback_slot); 4751cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ForInStep(Register index); 4761cb0ef41Sopenharmony_ci 4771cb0ef41Sopenharmony_ci // Generators. 4781cb0ef41Sopenharmony_ci BytecodeArrayBuilder& SuspendGenerator(Register generator, 4791cb0ef41Sopenharmony_ci RegisterList registers, 4801cb0ef41Sopenharmony_ci int suspend_id); 4811cb0ef41Sopenharmony_ci BytecodeArrayBuilder& SwitchOnGeneratorState(Register generator, 4821cb0ef41Sopenharmony_ci BytecodeJumpTable* jump_table); 4831cb0ef41Sopenharmony_ci BytecodeArrayBuilder& ResumeGenerator(Register generator, 4841cb0ef41Sopenharmony_ci RegisterList registers); 4851cb0ef41Sopenharmony_ci 4861cb0ef41Sopenharmony_ci // Creates a new handler table entry and returns a {hander_id} identifying the 4871cb0ef41Sopenharmony_ci // entry, so that it can be referenced by above exception handling support. 4881cb0ef41Sopenharmony_ci int NewHandlerEntry() { return handler_table_builder()->NewHandlerEntry(); } 4891cb0ef41Sopenharmony_ci 4901cb0ef41Sopenharmony_ci // Allocates a new jump table of given |size| and |case_value_base| in the 4911cb0ef41Sopenharmony_ci // constant pool. 4921cb0ef41Sopenharmony_ci BytecodeJumpTable* AllocateJumpTable(int size, int case_value_base); 4931cb0ef41Sopenharmony_ci 4941cb0ef41Sopenharmony_ci // Gets a constant pool entry. 4951cb0ef41Sopenharmony_ci size_t GetConstantPoolEntry(const AstRawString* raw_string); 4961cb0ef41Sopenharmony_ci size_t GetConstantPoolEntry(AstBigInt bigint); 4971cb0ef41Sopenharmony_ci size_t GetConstantPoolEntry(const Scope* scope); 4981cb0ef41Sopenharmony_ci size_t GetConstantPoolEntry(double number); 4991cb0ef41Sopenharmony_ci#define ENTRY_GETTER(NAME, ...) size_t NAME##ConstantPoolEntry(); 5001cb0ef41Sopenharmony_ci SINGLETON_CONSTANT_ENTRY_TYPES(ENTRY_GETTER) 5011cb0ef41Sopenharmony_ci#undef ENTRY_GETTER 5021cb0ef41Sopenharmony_ci 5031cb0ef41Sopenharmony_ci // Allocates a slot in the constant pool which can later be set. 5041cb0ef41Sopenharmony_ci size_t AllocateDeferredConstantPoolEntry(); 5051cb0ef41Sopenharmony_ci // Sets the deferred value into an allocated constant pool entry. 5061cb0ef41Sopenharmony_ci void SetDeferredConstantPoolEntry(size_t entry, Handle<Object> object); 5071cb0ef41Sopenharmony_ci 5081cb0ef41Sopenharmony_ci void InitializeReturnPosition(FunctionLiteral* literal); 5091cb0ef41Sopenharmony_ci 5101cb0ef41Sopenharmony_ci void SetStatementPosition(Statement* stmt) { 5111cb0ef41Sopenharmony_ci SetStatementPosition(stmt->position()); 5121cb0ef41Sopenharmony_ci } 5131cb0ef41Sopenharmony_ci 5141cb0ef41Sopenharmony_ci BytecodeSourceInfo PopSourcePosition() { 5151cb0ef41Sopenharmony_ci BytecodeSourceInfo source_info = latest_source_info_; 5161cb0ef41Sopenharmony_ci latest_source_info_.set_invalid(); 5171cb0ef41Sopenharmony_ci return source_info; 5181cb0ef41Sopenharmony_ci } 5191cb0ef41Sopenharmony_ci 5201cb0ef41Sopenharmony_ci void PushSourcePosition(BytecodeSourceInfo source_info) { 5211cb0ef41Sopenharmony_ci DCHECK(!latest_source_info_.is_valid()); 5221cb0ef41Sopenharmony_ci latest_source_info_ = source_info; 5231cb0ef41Sopenharmony_ci } 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_ci void SetStatementPosition(int position) { 5261cb0ef41Sopenharmony_ci if (position == kNoSourcePosition) return; 5271cb0ef41Sopenharmony_ci latest_source_info_.MakeStatementPosition(position); 5281cb0ef41Sopenharmony_ci } 5291cb0ef41Sopenharmony_ci 5301cb0ef41Sopenharmony_ci void SetExpressionPosition(Expression* expr) { 5311cb0ef41Sopenharmony_ci SetExpressionPosition(expr->position()); 5321cb0ef41Sopenharmony_ci } 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ci void SetExpressionPosition(int position) { 5351cb0ef41Sopenharmony_ci if (position == kNoSourcePosition) return; 5361cb0ef41Sopenharmony_ci if (!latest_source_info_.is_statement()) { 5371cb0ef41Sopenharmony_ci // Ensure the current expression position is overwritten with the 5381cb0ef41Sopenharmony_ci // latest value. 5391cb0ef41Sopenharmony_ci latest_source_info_.MakeExpressionPosition(position); 5401cb0ef41Sopenharmony_ci } 5411cb0ef41Sopenharmony_ci } 5421cb0ef41Sopenharmony_ci 5431cb0ef41Sopenharmony_ci void SetExpressionAsStatementPosition(Expression* expr) { 5441cb0ef41Sopenharmony_ci SetStatementPosition(expr->position()); 5451cb0ef41Sopenharmony_ci } 5461cb0ef41Sopenharmony_ci 5471cb0ef41Sopenharmony_ci bool RemainderOfBlockIsDead() const { 5481cb0ef41Sopenharmony_ci return bytecode_array_writer_.RemainderOfBlockIsDead(); 5491cb0ef41Sopenharmony_ci } 5501cb0ef41Sopenharmony_ci 5511cb0ef41Sopenharmony_ci // Returns the raw operand value for the given register or register list. 5521cb0ef41Sopenharmony_ci uint32_t GetInputRegisterOperand(Register reg); 5531cb0ef41Sopenharmony_ci uint32_t GetOutputRegisterOperand(Register reg); 5541cb0ef41Sopenharmony_ci uint32_t GetInputRegisterListOperand(RegisterList reg_list); 5551cb0ef41Sopenharmony_ci uint32_t GetOutputRegisterListOperand(RegisterList reg_list); 5561cb0ef41Sopenharmony_ci 5571cb0ef41Sopenharmony_ci // Outputs raw register transfer bytecodes without going through the register 5581cb0ef41Sopenharmony_ci // optimizer. 5591cb0ef41Sopenharmony_ci void OutputLdarRaw(Register reg); 5601cb0ef41Sopenharmony_ci void OutputStarRaw(Register reg); 5611cb0ef41Sopenharmony_ci void OutputMovRaw(Register src, Register dest); 5621cb0ef41Sopenharmony_ci 5631cb0ef41Sopenharmony_ci void EmitFunctionStartSourcePosition(int position); 5641cb0ef41Sopenharmony_ci 5651cb0ef41Sopenharmony_ci // Accessors 5661cb0ef41Sopenharmony_ci BytecodeRegisterAllocator* register_allocator() { 5671cb0ef41Sopenharmony_ci return ®ister_allocator_; 5681cb0ef41Sopenharmony_ci } 5691cb0ef41Sopenharmony_ci const BytecodeRegisterAllocator* register_allocator() const { 5701cb0ef41Sopenharmony_ci return ®ister_allocator_; 5711cb0ef41Sopenharmony_ci } 5721cb0ef41Sopenharmony_ci Zone* zone() const { return zone_; } 5731cb0ef41Sopenharmony_ci 5741cb0ef41Sopenharmony_ci private: 5751cb0ef41Sopenharmony_ci friend class BytecodeRegisterAllocator; 5761cb0ef41Sopenharmony_ci template <Bytecode bytecode, ImplicitRegisterUse implicit_register_use, 5771cb0ef41Sopenharmony_ci OperandType... operand_types> 5781cb0ef41Sopenharmony_ci friend class BytecodeNodeBuilder; 5791cb0ef41Sopenharmony_ci 5801cb0ef41Sopenharmony_ci const FeedbackVectorSpec* feedback_vector_spec() const { 5811cb0ef41Sopenharmony_ci return feedback_vector_spec_; 5821cb0ef41Sopenharmony_ci } 5831cb0ef41Sopenharmony_ci 5841cb0ef41Sopenharmony_ci // Returns the current source position for the given |bytecode|. 5851cb0ef41Sopenharmony_ci V8_INLINE BytecodeSourceInfo CurrentSourcePosition(Bytecode bytecode); 5861cb0ef41Sopenharmony_ci 5871cb0ef41Sopenharmony_ci#define DECLARE_BYTECODE_OUTPUT(Name, ...) \ 5881cb0ef41Sopenharmony_ci template <typename... Operands> \ 5891cb0ef41Sopenharmony_ci V8_INLINE BytecodeNode Create##Name##Node(Operands... operands); \ 5901cb0ef41Sopenharmony_ci template <typename... Operands> \ 5911cb0ef41Sopenharmony_ci V8_INLINE void Output##Name(Operands... operands); \ 5921cb0ef41Sopenharmony_ci template <typename... Operands> \ 5931cb0ef41Sopenharmony_ci V8_INLINE void Output##Name(BytecodeLabel* label, Operands... operands); 5941cb0ef41Sopenharmony_ci BYTECODE_LIST(DECLARE_BYTECODE_OUTPUT) 5951cb0ef41Sopenharmony_ci#undef DECLARE_OPERAND_TYPE_INFO 5961cb0ef41Sopenharmony_ci 5971cb0ef41Sopenharmony_ci V8_INLINE void OutputJumpLoop(BytecodeLoopHeader* loop_header, 5981cb0ef41Sopenharmony_ci int loop_depth); 5991cb0ef41Sopenharmony_ci V8_INLINE void OutputSwitchOnSmiNoFeedback(BytecodeJumpTable* jump_table); 6001cb0ef41Sopenharmony_ci 6011cb0ef41Sopenharmony_ci bool RegisterIsValid(Register reg) const; 6021cb0ef41Sopenharmony_ci bool RegisterListIsValid(RegisterList reg_list) const; 6031cb0ef41Sopenharmony_ci 6041cb0ef41Sopenharmony_ci // Sets a deferred source info which should be emitted before any future 6051cb0ef41Sopenharmony_ci // source info (either attached to a following bytecode or as a nop). 6061cb0ef41Sopenharmony_ci void SetDeferredSourceInfo(BytecodeSourceInfo source_info); 6071cb0ef41Sopenharmony_ci // Either attach deferred source info to node, or emit it as a nop bytecode 6081cb0ef41Sopenharmony_ci // if node already have valid source info. 6091cb0ef41Sopenharmony_ci void AttachOrEmitDeferredSourceInfo(BytecodeNode* node); 6101cb0ef41Sopenharmony_ci 6111cb0ef41Sopenharmony_ci // Write bytecode to bytecode array. 6121cb0ef41Sopenharmony_ci void Write(BytecodeNode* node); 6131cb0ef41Sopenharmony_ci void WriteJump(BytecodeNode* node, BytecodeLabel* label); 6141cb0ef41Sopenharmony_ci void WriteJumpLoop(BytecodeNode* node, BytecodeLoopHeader* loop_header); 6151cb0ef41Sopenharmony_ci void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* label); 6161cb0ef41Sopenharmony_ci 6171cb0ef41Sopenharmony_ci // Not implemented as the illegal bytecode is used inside internally 6181cb0ef41Sopenharmony_ci // to indicate a bytecode field is not valid or an error has occurred 6191cb0ef41Sopenharmony_ci // during bytecode generation. 6201cb0ef41Sopenharmony_ci BytecodeArrayBuilder& Illegal(); 6211cb0ef41Sopenharmony_ci 6221cb0ef41Sopenharmony_ci template <Bytecode bytecode, ImplicitRegisterUse implicit_register_use> 6231cb0ef41Sopenharmony_ci void PrepareToOutputBytecode(); 6241cb0ef41Sopenharmony_ci 6251cb0ef41Sopenharmony_ci BytecodeArrayWriter* bytecode_array_writer() { 6261cb0ef41Sopenharmony_ci return &bytecode_array_writer_; 6271cb0ef41Sopenharmony_ci } 6281cb0ef41Sopenharmony_ci ConstantArrayBuilder* constant_array_builder() { 6291cb0ef41Sopenharmony_ci return &constant_array_builder_; 6301cb0ef41Sopenharmony_ci } 6311cb0ef41Sopenharmony_ci const ConstantArrayBuilder* constant_array_builder() const { 6321cb0ef41Sopenharmony_ci return &constant_array_builder_; 6331cb0ef41Sopenharmony_ci } 6341cb0ef41Sopenharmony_ci HandlerTableBuilder* handler_table_builder() { 6351cb0ef41Sopenharmony_ci return &handler_table_builder_; 6361cb0ef41Sopenharmony_ci } 6371cb0ef41Sopenharmony_ci 6381cb0ef41Sopenharmony_ci Zone* zone_; 6391cb0ef41Sopenharmony_ci FeedbackVectorSpec* feedback_vector_spec_; 6401cb0ef41Sopenharmony_ci bool bytecode_generated_; 6411cb0ef41Sopenharmony_ci ConstantArrayBuilder constant_array_builder_; 6421cb0ef41Sopenharmony_ci HandlerTableBuilder handler_table_builder_; 6431cb0ef41Sopenharmony_ci int parameter_count_; 6441cb0ef41Sopenharmony_ci int local_register_count_; 6451cb0ef41Sopenharmony_ci BytecodeRegisterAllocator register_allocator_; 6461cb0ef41Sopenharmony_ci BytecodeArrayWriter bytecode_array_writer_; 6471cb0ef41Sopenharmony_ci BytecodeRegisterOptimizer* register_optimizer_; 6481cb0ef41Sopenharmony_ci BytecodeSourceInfo latest_source_info_; 6491cb0ef41Sopenharmony_ci BytecodeSourceInfo deferred_source_info_; 6501cb0ef41Sopenharmony_ci}; 6511cb0ef41Sopenharmony_ci 6521cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<( 6531cb0ef41Sopenharmony_ci std::ostream& os, const BytecodeArrayBuilder::ToBooleanMode& mode); 6541cb0ef41Sopenharmony_ci 6551cb0ef41Sopenharmony_ci} // namespace interpreter 6561cb0ef41Sopenharmony_ci} // namespace internal 6571cb0ef41Sopenharmony_ci} // namespace v8 6581cb0ef41Sopenharmony_ci 6591cb0ef41Sopenharmony_ci#endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ 660