| # Copyright (C) 2018-2019 Apple Inc. All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions |
| # are met: |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution. |
| # |
| # THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| types [ |
| :VirtualRegister, |
| |
| :BasicBlockLocation, |
| :BoundLabel, |
| :DebugHookType, |
| :ErrorType, |
| :GetByIdMode, |
| :GetByIdModeMetadata, |
| :GetByValHistory, |
| :GetPutInfo, |
| :IndexingType, |
| :JSCell, |
| :JSGlobalLexicalEnvironment, |
| :JSGlobalObject, |
| :JSModuleEnvironment, |
| :JSObject, |
| :JSScope, |
| :JSType, |
| :JSValue, |
| :LLIntCallLinkInfo, |
| :ResultType, |
| :OperandTypes, |
| :ProfileTypeBytecodeFlag, |
| :PropertyOffset, |
| :PutByIdFlags, |
| :ResolveType, |
| :Structure, |
| :StructureID, |
| :StructureChain, |
| :SymbolTable, |
| :SymbolTableOrScopeDepth, |
| :ToThisStatus, |
| :TypeLocation, |
| :WasmBoundLabel, |
| :WatchpointSet, |
| |
| :ValueProfile, |
| :ValueProfileAndOperandBuffer, |
| :UnaryArithProfile, |
| :BinaryArithProfile, |
| :ArrayProfile, |
| :ArrayAllocationProfile, |
| :ObjectAllocationProfile, |
| ] |
| |
| templates [ |
| :WriteBarrier, |
| :WriteBarrierBase, |
| ] |
| |
| |
| begin_section :Bytecode, |
| emit_in_h_file: true, |
| emit_in_structs_file: true, |
| emit_in_asm_file: true, |
| emit_opcode_id_string_values_in_h_file: true, |
| macro_name_component: :BYTECODE, |
| asm_prefix: "llint_", |
| op_prefix: "op_" |
| |
| op :wide16 |
| op :wide32 |
| |
| op :enter |
| |
| op :get_scope, |
| args: { |
| dst: VirtualRegister |
| } |
| |
| op :create_direct_arguments, |
| args: { |
| dst: VirtualRegister, |
| } |
| |
| op :create_scoped_arguments, |
| args: { |
| dst: VirtualRegister, |
| scope: VirtualRegister, |
| } |
| |
| op :create_cloned_arguments, |
| args: { |
| dst: VirtualRegister, |
| } |
| |
| op :create_this, |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| inlineCapacity: unsigned, |
| }, |
| metadata: { |
| cachedCallee: WriteBarrier[JSCell] |
| } |
| |
| op :create_promise, |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| isInternalPromise: bool, |
| }, |
| metadata: { |
| cachedCallee: WriteBarrier[JSCell] |
| } |
| |
| op :new_promise, |
| args: { |
| dst: VirtualRegister, |
| isInternalPromise: bool, |
| } |
| |
| op :new_generator, |
| args: { |
| dst: VirtualRegister, |
| } |
| |
| op_group :CreateInternalFieldObjectOp, |
| [ |
| :create_generator, |
| :create_async_generator, |
| ], |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| }, |
| metadata: { |
| cachedCallee: WriteBarrier[JSCell] |
| } |
| |
| op :get_argument, |
| args: { |
| dst: VirtualRegister, |
| index: int, |
| }, |
| metadata: { |
| profile: ValueProfile, |
| } |
| |
| op :argument_count, |
| args: { |
| dst: VirtualRegister, |
| } |
| |
| op :to_this, |
| args: { |
| srcDst: VirtualRegister, |
| }, |
| metadata: { |
| cachedStructureID: StructureID, |
| toThisStatus: ToThisStatus, |
| profile: ValueProfile, |
| } |
| |
| op :check_tdz, |
| args: { |
| targetVirtualRegister: VirtualRegister, |
| } |
| |
| op :new_object, |
| args: { |
| dst: VirtualRegister, |
| inlineCapacity: unsigned, |
| }, |
| metadata: { |
| objectAllocationProfile: ObjectAllocationProfile, |
| } |
| |
| op :new_array, |
| args: { |
| dst: VirtualRegister, |
| argv: VirtualRegister, |
| argc: unsigned, |
| recommendedIndexingType: IndexingType, |
| }, |
| metadata: { |
| arrayAllocationProfile: ArrayAllocationProfile, |
| } |
| |
| op :new_array_with_size, |
| args: { |
| dst: VirtualRegister, |
| length: VirtualRegister, |
| }, |
| metadata: { |
| arrayAllocationProfile: ArrayAllocationProfile, |
| } |
| |
| op :new_array_buffer, |
| args: { |
| dst: VirtualRegister, |
| immutableButterfly: VirtualRegister, |
| recommendedIndexingType: IndexingType |
| }, |
| metadata: { |
| arrayAllocationProfile: ArrayAllocationProfile, |
| } |
| |
| op :new_array_with_spread, |
| args: { |
| dst: VirtualRegister, |
| argv: VirtualRegister, |
| argc: unsigned, |
| bitVector: unsigned, |
| } |
| |
| op :spread, |
| args: { |
| dst: VirtualRegister, |
| argument: VirtualRegister, |
| } |
| |
| op :new_regexp, |
| args: { |
| dst: VirtualRegister, |
| regexp: VirtualRegister, |
| } |
| |
| op :mov, |
| args: { |
| dst: VirtualRegister, |
| src: VirtualRegister, |
| } |
| |
| op_group :BinaryOp, |
| [ |
| :eq, |
| :neq, |
| :stricteq, |
| :nstricteq, |
| :less, |
| :lesseq, |
| :greater, |
| :greatereq, |
| :below, |
| :beloweq, |
| :mod, |
| :pow, |
| :urshift, |
| ], |
| args: { |
| dst: VirtualRegister, |
| lhs: VirtualRegister, |
| rhs: VirtualRegister, |
| } |
| |
| op_group :ProfiledBinaryOp, |
| [ |
| :add, |
| :mul, |
| :div, |
| :sub, |
| ], |
| args: { |
| dst: VirtualRegister, |
| lhs: VirtualRegister, |
| rhs: VirtualRegister, |
| operandTypes: OperandTypes, |
| }, |
| metadata: { |
| arithProfile: BinaryArithProfile |
| } |
| |
| op_group :ValueProfiledBinaryOp, |
| [ |
| :bitand, |
| :bitor, |
| :bitxor, |
| :lshift, |
| :rshift, |
| ], |
| args: { |
| dst: VirtualRegister, |
| lhs: VirtualRegister, |
| rhs: VirtualRegister, |
| }, |
| metadata: { |
| profile: ValueProfile |
| } |
| |
| op :bitnot, |
| args: { |
| dst: VirtualRegister, |
| operand: VirtualRegister, |
| }, |
| metadata: { |
| profile: ValueProfile |
| } |
| |
| op_group :UnaryOp, |
| [ |
| :eq_null, |
| :neq_null, |
| :to_string, |
| :unsigned, |
| :is_empty, |
| :is_undefined, |
| :is_undefined_or_null, |
| :is_boolean, |
| :is_number, |
| :is_object, |
| :is_object_or_null, |
| :is_function, |
| ], |
| args: { |
| dst: VirtualRegister, |
| operand: VirtualRegister, |
| } |
| |
| op_group :UnaryInPlaceProfiledOp, |
| [ |
| :inc, |
| :dec, |
| ], |
| args: { |
| srcDst: VirtualRegister, |
| }, |
| metadata: { |
| arithProfile: UnaryArithProfile |
| } |
| |
| op :to_object, |
| args: { |
| dst: VirtualRegister, |
| operand: VirtualRegister, |
| message: unsigned, |
| }, |
| metadata: { |
| profile: ValueProfile, |
| } |
| |
| op_group :ValueProfiledUnaryOp, |
| [ |
| :to_number, |
| :to_numeric, |
| ], |
| args: { |
| dst: VirtualRegister, |
| operand: VirtualRegister, |
| }, |
| metadata: { |
| profile: ValueProfile, |
| } |
| |
| op :negate, |
| args: { |
| dst: VirtualRegister, |
| operand: VirtualRegister, |
| resultType: ResultType, |
| }, |
| metadata: { |
| arithProfile: UnaryArithProfile, |
| } |
| |
| op :not, |
| args: { |
| dst: VirtualRegister, |
| operand: VirtualRegister, |
| } |
| |
| |
| op :identity_with_profile, |
| args: { |
| srcDst: VirtualRegister, |
| topProfile: unsigned, |
| bottomProfile: unsigned, |
| } |
| |
| op :overrides_has_instance, |
| args: { |
| dst: VirtualRegister, |
| constructor: VirtualRegister, |
| hasInstanceValue: VirtualRegister, |
| } |
| |
| op :instanceof, |
| args: { |
| dst: VirtualRegister, |
| value: VirtualRegister, |
| prototype: VirtualRegister, |
| } |
| |
| op :instanceof_custom, |
| args: { |
| dst: VirtualRegister, |
| value: VirtualRegister, |
| constructor: VirtualRegister, |
| hasInstanceValue: VirtualRegister, |
| } |
| |
| op :typeof, |
| args: { |
| dst: VirtualRegister, |
| value: VirtualRegister, |
| } |
| |
| op :is_cell_with_type, |
| args: { |
| dst: VirtualRegister, |
| operand: VirtualRegister, |
| type: JSType, |
| } |
| |
| op :in_by_val, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: VirtualRegister, |
| }, |
| metadata: { |
| arrayProfile: ArrayProfile, |
| } |
| |
| op :in_by_id, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: unsigned, |
| } |
| |
| op :get_by_id, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: unsigned, |
| }, |
| metadata: { |
| modeMetadata: GetByIdModeMetadata, |
| profile: ValueProfile, |
| } |
| |
| op :get_by_id_with_this, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| thisValue: VirtualRegister, |
| property: unsigned, |
| }, |
| metadata: { |
| profile: ValueProfile, |
| } |
| |
| op :get_by_val_with_this, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| thisValue: VirtualRegister, |
| property: VirtualRegister, |
| }, |
| metadata: { |
| profile: ValueProfile, |
| } |
| |
| op :get_by_id_direct, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: unsigned, |
| }, |
| metadata: { |
| profile: ValueProfile, # not used in llint |
| structureID: StructureID, |
| offset: unsigned, |
| } |
| |
| op :try_get_by_id, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: unsigned, |
| }, |
| metadata: { |
| profile: ValueProfile, |
| } |
| |
| op :put_by_id, |
| args: { |
| base: VirtualRegister, |
| property: unsigned, |
| value: VirtualRegister, |
| flags: PutByIdFlags, |
| }, |
| metadata: { |
| oldStructureID: StructureID, |
| offset: unsigned, |
| newStructureID: StructureID, |
| structureChain: WriteBarrierBase[StructureChain], |
| } |
| |
| op :put_by_id_with_this, |
| args: { |
| base: VirtualRegister, |
| thisValue: VirtualRegister, |
| property: unsigned, |
| value: VirtualRegister, |
| } |
| |
| op :del_by_id, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: unsigned, |
| } |
| |
| op :get_by_val, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: VirtualRegister, |
| }, |
| metadata: { |
| profile: ValueProfile, |
| arrayProfile: ArrayProfile, |
| seenIdentifiers: GetByValHistory, |
| } |
| |
| op :put_by_val, |
| args: { |
| base: VirtualRegister, |
| property: VirtualRegister, |
| value: VirtualRegister, |
| }, |
| metadata: { |
| arrayProfile: ArrayProfile, |
| } |
| |
| op :put_by_val_with_this, |
| args: { |
| base: VirtualRegister, |
| thisValue: VirtualRegister, |
| property: VirtualRegister, |
| value: VirtualRegister, |
| } |
| |
| op :put_by_val_direct, |
| args: { |
| base: VirtualRegister, |
| property: VirtualRegister, |
| value: VirtualRegister, |
| }, |
| metadata: { |
| arrayProfile: ArrayProfile, |
| } |
| |
| op :del_by_val, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: VirtualRegister, |
| } |
| |
| op :put_getter_by_id, |
| args: { |
| base: VirtualRegister, |
| property: unsigned, |
| attributes: unsigned, |
| accessor: VirtualRegister, |
| } |
| |
| op :put_setter_by_id, |
| args: { |
| base: VirtualRegister, |
| property: unsigned, |
| attributes: unsigned, |
| accessor: VirtualRegister, |
| } |
| |
| op :put_getter_setter_by_id, |
| args: { |
| base: VirtualRegister, |
| property: unsigned, |
| attributes: unsigned, |
| getter: VirtualRegister, |
| setter: VirtualRegister, |
| } |
| |
| op :put_getter_by_val, |
| args: { |
| base: VirtualRegister, |
| property: VirtualRegister, |
| attributes: unsigned, |
| accessor: VirtualRegister, |
| } |
| |
| op :put_setter_by_val, |
| args: { |
| base: VirtualRegister, |
| property: VirtualRegister, |
| attributes: unsigned, |
| accessor: VirtualRegister, |
| } |
| |
| op :define_data_property, |
| args: { |
| base: VirtualRegister, |
| property: VirtualRegister, |
| value: VirtualRegister, |
| attributes: VirtualRegister, |
| } |
| |
| op :define_accessor_property, |
| args: { |
| base: VirtualRegister, |
| property: VirtualRegister, |
| getter: VirtualRegister, |
| setter: VirtualRegister, |
| attributes: VirtualRegister, |
| } |
| |
| op :jmp, |
| args: { |
| targetLabel: BoundLabel, |
| } |
| |
| op :jtrue, |
| args: { |
| condition: VirtualRegister, |
| targetLabel: BoundLabel, |
| } |
| |
| op :jfalse, |
| args: { |
| condition: VirtualRegister, |
| targetLabel: BoundLabel, |
| } |
| |
| op :jeq_null, |
| args: { |
| value: VirtualRegister, |
| targetLabel: BoundLabel, |
| } |
| |
| op :jneq_null, |
| args: { |
| value: VirtualRegister, |
| targetLabel: BoundLabel, |
| } |
| |
| op :jundefined_or_null, |
| args: { |
| value: VirtualRegister, |
| targetLabel: BoundLabel, |
| } |
| |
| op :jnundefined_or_null, |
| args: { |
| value: VirtualRegister, |
| targetLabel: BoundLabel, |
| } |
| |
| op :jneq_ptr, |
| args: { |
| value: VirtualRegister, |
| specialPointer: VirtualRegister, |
| targetLabel: BoundLabel, |
| }, |
| metadata: { |
| hasJumped: bool, |
| } |
| |
| op_group :BinaryJmp, |
| [ |
| :jeq, |
| :jstricteq, |
| :jneq, |
| :jnstricteq, |
| :jless, |
| :jlesseq, |
| :jgreater, |
| :jgreatereq, |
| :jnless, |
| :jnlesseq, |
| :jngreater, |
| :jngreatereq, |
| :jbelow, |
| :jbeloweq, |
| ], |
| args: { |
| lhs: VirtualRegister, |
| rhs: VirtualRegister, |
| targetLabel: BoundLabel, |
| } |
| |
| op :loop_hint |
| |
| op_group :SwitchValue, |
| [ |
| :switch_imm, |
| :switch_char, |
| :switch_string, |
| ], |
| args: { |
| tableIndex: unsigned, |
| defaultOffset: BoundLabel, |
| scrutinee: VirtualRegister, |
| } |
| |
| op_group :NewFunction, |
| [ |
| :new_func, |
| :new_func_exp, |
| :new_generator_func, |
| :new_generator_func_exp, |
| :new_async_func, |
| :new_async_func_exp, |
| :new_async_generator_func, |
| :new_async_generator_func_exp, |
| ], |
| args: { |
| dst: VirtualRegister, |
| scope: VirtualRegister, |
| functionDecl: unsigned, |
| } |
| |
| op :set_function_name, |
| args: { |
| function: VirtualRegister, |
| name: VirtualRegister, |
| } |
| |
| # op_call variations |
| op :call, |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| argc: unsigned, |
| argv: unsigned, |
| }, |
| metadata: { |
| callLinkInfo: LLIntCallLinkInfo, |
| profile: ValueProfile, |
| } |
| |
| op :tail_call, |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| argc: unsigned, |
| argv: unsigned, |
| }, |
| metadata: { |
| callLinkInfo: LLIntCallLinkInfo, |
| profile: ValueProfile, |
| } |
| |
| op :call_eval, |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| argc: unsigned, |
| argv: unsigned, |
| }, |
| metadata: { |
| callLinkInfo: LLIntCallLinkInfo, |
| profile: ValueProfile, |
| } |
| |
| op :call_varargs, |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| thisValue?: VirtualRegister, |
| arguments?: VirtualRegister, |
| firstFree: VirtualRegister, |
| firstVarArg: int, |
| }, |
| metadata: { |
| arrayProfile: ArrayProfile, |
| profile: ValueProfile, |
| } |
| |
| op :tail_call_varargs, |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| thisValue?: VirtualRegister, |
| arguments?: VirtualRegister, |
| firstFree: VirtualRegister, |
| firstVarArg: int, |
| }, |
| metadata: { |
| arrayProfile: ArrayProfile, |
| profile: ValueProfile, |
| } |
| |
| op :tail_call_forward_arguments, |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| thisValue?: VirtualRegister, |
| arguments?: VirtualRegister, |
| firstFree: VirtualRegister, |
| firstVarArg: int, |
| }, |
| metadata: { |
| arrayProfile: ArrayProfile, |
| profile: ValueProfile, |
| } |
| |
| op :construct, |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| argc: unsigned, |
| argv: unsigned, |
| }, |
| metadata: { |
| callLinkInfo: LLIntCallLinkInfo, |
| profile: ValueProfile, |
| } |
| |
| op :construct_varargs, |
| args: { |
| dst: VirtualRegister, |
| callee: VirtualRegister, |
| thisValue?: VirtualRegister, |
| arguments?: VirtualRegister, |
| firstFree: VirtualRegister, |
| firstVarArg: int, |
| }, |
| metadata: { |
| arrayProfile: ArrayProfile, |
| profile: ValueProfile, |
| } |
| |
| op :ret, |
| args: { |
| value: VirtualRegister, |
| } |
| |
| op :strcat, |
| args: { |
| dst: VirtualRegister, |
| src: VirtualRegister, |
| count: int, |
| } |
| |
| op :to_primitive, |
| args: { |
| dst: VirtualRegister, |
| src: VirtualRegister, |
| } |
| |
| op :resolve_scope, |
| args: { |
| dst: VirtualRegister, # offset 1 |
| scope: VirtualRegister, # offset 2 |
| var: unsigned, # offset 3 |
| # $begin: :private, |
| resolveType: ResolveType, |
| localScopeDepth: unsigned, |
| }, |
| metadata: { |
| resolveType: ResolveType, # offset 4 |
| _0: { # offset 5 |
| localScopeDepth: unsigned, |
| globalLexicalBindingEpoch: unsigned, |
| }, |
| _1: { # offset 6 |
| # written during linking |
| lexicalEnvironment: WriteBarrierBase[JSCell], # lexicalEnvironment && type == ModuleVar |
| symbolTable: WriteBarrierBase[SymbolTable], # lexicalEnvironment && type != ModuleVar |
| |
| constantScope: WriteBarrierBase[JSScope], |
| |
| # written from the slow path |
| globalLexicalEnvironment: WriteBarrierBase[JSGlobalLexicalEnvironment], |
| globalObject: WriteBarrierBase[JSGlobalObject], |
| }, |
| } |
| |
| op :get_from_scope, |
| args: { |
| dst: VirtualRegister, # offset 1 |
| scope: VirtualRegister, # offset 2 |
| var: unsigned, # offset 3 |
| # $begin: :private, |
| getPutInfo: GetPutInfo, |
| localScopeDepth: unsigned, |
| offset: unsigned, |
| }, |
| metadata: { |
| getPutInfo: GetPutInfo, # offset 4 |
| _: { #previously offset 5 |
| watchpointSet: WatchpointSet.*, |
| structure: WriteBarrierBase[Structure], |
| }, |
| operand: uintptr_t, #offset 6 |
| profile: ValueProfile, # offset 7 |
| }, |
| metadata_initializers: { |
| getPutInfo: :getPutInfo, |
| operand: :offset, |
| } |
| |
| op :put_to_scope, |
| args: { |
| scope: VirtualRegister, # offset 1 |
| var: unsigned, # offset 2 |
| value: VirtualRegister, # offset 3 |
| # $begin: :private, |
| getPutInfo: GetPutInfo, |
| symbolTableOrScopeDepth: SymbolTableOrScopeDepth, |
| offset: unsigned, |
| }, |
| metadata: { |
| getPutInfo: GetPutInfo, # offset 4 |
| _: { # offset 5 |
| structure: WriteBarrierBase[Structure], |
| watchpointSet: WatchpointSet.*, |
| }, |
| operand: uintptr_t, # offset 6 |
| }, |
| metadata_initializers: { |
| getPutInfo: :getPutInfo, |
| operand: :offset, |
| } |
| |
| op :get_from_arguments, |
| args: { |
| dst: VirtualRegister, |
| arguments: VirtualRegister, |
| index: unsigned, |
| }, |
| metadata: { |
| profile: ValueProfile, |
| } |
| |
| op :put_to_arguments, |
| args: { |
| arguments: VirtualRegister, |
| index: unsigned, |
| value: VirtualRegister, |
| } |
| |
| op :push_with_scope, |
| args: { |
| dst: VirtualRegister, |
| currentScope: VirtualRegister, |
| newScope: VirtualRegister, |
| } |
| |
| op :create_lexical_environment, |
| args: { |
| dst: VirtualRegister, |
| scope: VirtualRegister, |
| symbolTable: VirtualRegister, |
| initialValue: VirtualRegister, |
| } |
| |
| op :create_generator_frame_environment, |
| args: { |
| dst: VirtualRegister, |
| scope: VirtualRegister, |
| symbolTable: VirtualRegister, |
| initialValue: VirtualRegister, |
| } |
| |
| op :get_parent_scope, |
| args: { |
| dst: VirtualRegister, |
| scope: VirtualRegister, |
| } |
| |
| op :catch, |
| args: { |
| exception: VirtualRegister, |
| thrownValue: VirtualRegister, |
| }, |
| metadata: { |
| buffer: ValueProfileAndOperandBuffer.*, |
| } |
| |
| op :throw, |
| args: { |
| value: VirtualRegister, |
| } |
| |
| op :throw_static_error, |
| args: { |
| message: VirtualRegister, |
| errorType: ErrorType, |
| } |
| |
| op :debug, |
| args: { |
| debugHookType: DebugHookType, |
| hasBreakpoint: bool, |
| } |
| |
| op :end, |
| args: { |
| value: VirtualRegister, |
| } |
| |
| op :profile_type, |
| args: { |
| targetVirtualRegister: VirtualRegister, |
| symbolTableOrScopeDepth: SymbolTableOrScopeDepth, |
| flag: ProfileTypeBytecodeFlag, |
| identifier?: unsigned, |
| resolveType: ResolveType, |
| }, |
| metadata: { |
| typeLocation: TypeLocation.*, |
| } |
| |
| op :profile_control_flow, |
| args: { |
| textOffset: int, |
| }, |
| metadata: { |
| basicBlockLocation: BasicBlockLocation.*, |
| } |
| |
| op :get_enumerable_length, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| } |
| |
| op :has_indexed_property, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: VirtualRegister, |
| }, |
| metadata: { |
| arrayProfile: ArrayProfile, |
| } |
| |
| op :has_structure_property, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: VirtualRegister, |
| enumerator: VirtualRegister, |
| } |
| |
| op :has_generic_property, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: VirtualRegister, |
| } |
| |
| op :get_direct_pname, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| property: VirtualRegister, |
| index: VirtualRegister, |
| enumerator: VirtualRegister, |
| }, |
| metadata: { |
| profile: ValueProfile, |
| } |
| |
| op :get_property_enumerator, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| } |
| |
| op :enumerator_structure_pname, |
| args: { |
| dst: VirtualRegister, |
| enumerator: VirtualRegister, |
| index: VirtualRegister, |
| } |
| |
| op :enumerator_generic_pname, |
| args: { |
| dst: VirtualRegister, |
| enumerator: VirtualRegister, |
| index: VirtualRegister, |
| } |
| |
| op :to_index_string, |
| args: { |
| dst: VirtualRegister, |
| index: VirtualRegister, |
| } |
| |
| op :unreachable |
| |
| op :create_rest, |
| args: { |
| dst: VirtualRegister, |
| arraySize: VirtualRegister, |
| numParametersToSkip: unsigned, |
| } |
| |
| op :get_rest_length, |
| args: { |
| dst: VirtualRegister, |
| numParametersToSkip: unsigned, |
| } |
| |
| op :yield, |
| args: { |
| generator: VirtualRegister, |
| yieldPoint: unsigned, |
| argument: VirtualRegister, |
| } |
| |
| op :check_traps |
| |
| op :log_shadow_chicken_prologue, |
| args: { |
| scope: VirtualRegister, |
| } |
| |
| op :log_shadow_chicken_tail, |
| args: { |
| thisValue: VirtualRegister, |
| scope: VirtualRegister, |
| } |
| |
| op :resolve_scope_for_hoisting_func_decl_in_eval, |
| args: { |
| dst: VirtualRegister, |
| scope: VirtualRegister, |
| property: unsigned, |
| } |
| |
| op :get_internal_field, |
| args: { |
| dst: VirtualRegister, |
| base: VirtualRegister, |
| index: unsigned, |
| }, |
| metadata: { |
| profile: ValueProfile, |
| } |
| |
| op :put_internal_field, |
| args: { |
| base: VirtualRegister, |
| index: unsigned, |
| value: VirtualRegister, |
| } |
| |
| op :nop |
| |
| op :super_sampler_begin |
| |
| op :super_sampler_end |
| |
| end_section :Bytecode |
| |
| begin_section :CLoopHelpers, |
| emit_in_h_file: true, |
| macro_name_component: :CLOOP_BYTECODE_HELPER |
| |
| op :llint_entry |
| op :getHostCallReturnValue |
| op :llint_return_to_host |
| op :llint_vm_entry_to_javascript |
| op :llint_vm_entry_to_native |
| op :llint_cloop_did_return_from_js_1 |
| op :llint_cloop_did_return_from_js_2 |
| op :llint_cloop_did_return_from_js_3 |
| op :llint_cloop_did_return_from_js_4 |
| op :llint_cloop_did_return_from_js_5 |
| op :llint_cloop_did_return_from_js_6 |
| op :llint_cloop_did_return_from_js_7 |
| op :llint_cloop_did_return_from_js_8 |
| op :llint_cloop_did_return_from_js_9 |
| op :llint_cloop_did_return_from_js_10 |
| op :llint_cloop_did_return_from_js_11 |
| op :llint_cloop_did_return_from_js_12 |
| op :llint_cloop_did_return_from_js_13 |
| op :llint_cloop_did_return_from_js_14 |
| op :llint_cloop_did_return_from_js_15 |
| op :llint_cloop_did_return_from_js_16 |
| op :llint_cloop_did_return_from_js_17 |
| op :llint_cloop_did_return_from_js_18 |
| op :llint_cloop_did_return_from_js_19 |
| op :llint_cloop_did_return_from_js_20 |
| op :llint_cloop_did_return_from_js_21 |
| op :llint_cloop_did_return_from_js_22 |
| op :llint_cloop_did_return_from_js_23 |
| op :llint_cloop_did_return_from_js_24 |
| op :llint_cloop_did_return_from_js_25 |
| op :llint_cloop_did_return_from_js_26 |
| op :llint_cloop_did_return_from_js_27 |
| op :llint_cloop_did_return_from_js_28 |
| op :llint_cloop_did_return_from_js_29 |
| op :llint_cloop_did_return_from_js_30 |
| op :llint_cloop_did_return_from_js_31 |
| op :llint_cloop_did_return_from_js_32 |
| op :llint_cloop_did_return_from_js_33 |
| op :llint_cloop_did_return_from_js_34 |
| |
| end_section :CLoopHelpers |
| |
| begin_section :NativeHelpers, |
| emit_in_h_file: true, |
| emit_in_asm_file: true, |
| macro_name_component: :BYTECODE_HELPER |
| |
| op :llint_program_prologue |
| op :llint_eval_prologue |
| op :llint_module_program_prologue |
| op :llint_function_for_call_prologue |
| op :llint_function_for_construct_prologue |
| op :llint_function_for_call_arity_check |
| op :llint_function_for_construct_arity_check |
| op :llint_generic_return_point |
| op :llint_throw_from_slow_path_trampoline |
| op :llint_throw_during_call_trampoline |
| op :llint_native_call_trampoline |
| op :llint_native_construct_trampoline |
| op :llint_internal_function_call_trampoline |
| op :llint_internal_function_construct_trampoline |
| op :handleUncaughtException |
| op :op_call_return_location |
| op :op_construct_return_location |
| op :op_call_varargs_slow_return_location |
| op :op_construct_varargs_slow_return_location |
| op :op_get_by_id_return_location |
| op :op_get_by_val_return_location |
| op :op_put_by_id_return_location |
| op :op_put_by_val_return_location |
| op :wasm_function_prologue |
| op :wasm_function_prologue_no_tls |
| |
| end_section :NativeHelpers |
| |
| begin_section :Wasm, |
| emit_in_h_file: true, |
| emit_in_structs_file: true, |
| macro_name_component: :WASM, |
| op_prefix: "wasm_" |
| |
| autogenerate_wasm_opcodes |
| |
| # Helpers |
| |
| op :throw_from_slow_path_trampoline |
| |
| # FIXME: Wasm and JS LLInt should share common opcodes |
| # https://bugs.webkit.org/show_bug.cgi?id=203656 |
| |
| op :wide16 |
| op :wide32 |
| |
| op :enter |
| op :nop |
| op :loop_hint |
| |
| op :mov, |
| args: { |
| dst: VirtualRegister, |
| src: VirtualRegister, |
| } |
| |
| op_group :ConditionalJump, |
| [ |
| :jtrue, |
| :jfalse, |
| ], |
| args: { |
| condition: VirtualRegister, |
| targetLabel: WasmBoundLabel, |
| } |
| |
| op :jmp, |
| args: { |
| targetLabel: WasmBoundLabel, |
| } |
| |
| op :ret |
| |
| op :switch, |
| args: { |
| scrutinee: VirtualRegister, |
| tableIndex: unsigned, |
| } |
| |
| # Wasm specific bytecodes |
| |
| op :unreachable |
| op :ret_void |
| |
| op :drop_keep, |
| args: { |
| startOffset: unsigned, |
| dropCount: unsigned, |
| keepCount: unsigned, |
| } |
| |
| op :ref_is_null, |
| args: { |
| dst: VirtualRegister, |
| ref: VirtualRegister, |
| } |
| |
| op :ref_func, |
| args: { |
| dst: VirtualRegister, |
| functionIndex: unsigned, |
| } |
| |
| op :get_global, |
| args: { |
| dst: VirtualRegister, |
| globalIndex: unsigned, |
| } |
| |
| op :set_global, |
| args: { |
| globalIndex: unsigned, |
| value: VirtualRegister, |
| } |
| |
| op :set_global_ref, |
| args: { |
| globalIndex: unsigned, |
| value: VirtualRegister, |
| } |
| |
| op :table_get, |
| args: { |
| dst: VirtualRegister, |
| index: VirtualRegister, |
| tableIndex: unsigned, |
| } |
| |
| op :table_set, |
| args: { |
| index: VirtualRegister, |
| value: VirtualRegister, |
| tableIndex: unsigned, |
| } |
| |
| op :table_size, |
| args: { |
| dst: VirtualRegister, |
| tableIndex: unsigned, |
| } |
| |
| op :table_grow, |
| args: { |
| dst: VirtualRegister, |
| fill: VirtualRegister, |
| size: VirtualRegister, |
| tableIndex: unsigned, |
| } |
| |
| op :table_fill, |
| args: { |
| offset: VirtualRegister, |
| fill: VirtualRegister, |
| size: VirtualRegister, |
| tableIndex: unsigned, |
| } |
| |
| op :call, |
| args: { |
| functionIndex: unsigned, |
| stackOffset: unsigned, |
| numberOfStackArgs: unsigned, |
| } |
| |
| op :call_no_tls, |
| args: { |
| functionIndex: unsigned, |
| stackOffset: unsigned, |
| numberOfStackArgs: unsigned, |
| } |
| |
| op :call_indirect, |
| args: { |
| functionIndex: VirtualRegister, |
| signatureIndex: unsigned, |
| stackOffset: unsigned, |
| numberOfStackArgs: unsigned, |
| tableIndex: unsigned, |
| } |
| |
| op :call_indirect_no_tls, |
| args: { |
| functionIndex: VirtualRegister, |
| signatureIndex: unsigned, |
| stackOffset: unsigned, |
| numberOfStackArgs: unsigned, |
| tableIndex: unsigned, |
| } |
| |
| op :current_memory, |
| args: { |
| dst: VirtualRegister, |
| } |
| |
| op :grow_memory, |
| args: { |
| dst: VirtualRegister, |
| delta: VirtualRegister |
| } |
| |
| op :select, |
| args: { |
| dst: VirtualRegister, |
| condition: VirtualRegister, |
| nonZero: VirtualRegister, |
| zero: VirtualRegister, |
| } |
| |
| op_group :Load, |
| [ |
| :load8_u, |
| :load16_u, |
| :load32_u, |
| :load64_u, |
| :i32_load8_s, |
| :i64_load8_s, |
| :i32_load16_s, |
| :i64_load16_s, |
| :i64_load32_s, |
| ], |
| args: { |
| dst: VirtualRegister, |
| pointer: VirtualRegister, |
| offset: unsigned, |
| } |
| |
| op_group :Store, |
| [ |
| :store8, |
| :store16, |
| :store32, |
| :store64, |
| ], |
| args: { |
| pointer: VirtualRegister, |
| value: VirtualRegister, |
| offset: unsigned, |
| } |
| |
| end_section :Wasm |