mirror of
https://github.com/darlinghq/darling-JavaScriptCore.git
synced 2024-11-26 21:50:53 +00:00
1808 lines
38 KiB
Ruby
1808 lines
38 KiB
Ruby
# 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,
|
|
:ECMAMode,
|
|
:ErrorTypeWithExtension,
|
|
:GetByIdMode,
|
|
:GetByIdModeMetadata,
|
|
:GetByValHistory,
|
|
:GetPutInfo,
|
|
:IndexingType,
|
|
:IterationModeMetadata,
|
|
:JSCell,
|
|
:JSGlobalLexicalEnvironment,
|
|
:JSGlobalObject,
|
|
:JSModuleEnvironment,
|
|
:JSObject,
|
|
:JSScope,
|
|
:JSType,
|
|
:JSValue,
|
|
:LLIntCallLinkInfo,
|
|
:ResultType,
|
|
:OperandTypes,
|
|
:PrivateFieldPutKind,
|
|
:ProfileTypeBytecodeFlag,
|
|
:PropertyOffset,
|
|
:PutByIdFlags,
|
|
:ResolveType,
|
|
:Structure,
|
|
:StructureID,
|
|
:StructureChain,
|
|
:SymbolTable,
|
|
:SymbolTableOrScopeDepth,
|
|
:ToThisStatus,
|
|
:TypeLocation,
|
|
:WasmBoundLabel,
|
|
:WatchpointSet,
|
|
|
|
:ValueProfile,
|
|
:ValueProfileAndVirtualRegisterBuffer,
|
|
: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_arguments_butterfly,
|
|
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,
|
|
ecmaMode: ECMAMode,
|
|
},
|
|
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,
|
|
:typeof_is_undefined,
|
|
:typeof_is_object,
|
|
:typeof_is_function,
|
|
:is_undefined_or_null,
|
|
:is_boolean,
|
|
:is_number,
|
|
:is_big_int,
|
|
:is_object,
|
|
:is_callable,
|
|
:is_constructor,
|
|
],
|
|
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 :get_prototype_of,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
value: VirtualRegister,
|
|
},
|
|
metadata: {
|
|
profile: ValueProfile,
|
|
}
|
|
|
|
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,
|
|
ecmaMode: ECMAMode,
|
|
}
|
|
|
|
op :del_by_id,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
base: VirtualRegister,
|
|
property: unsigned,
|
|
ecmaMode: ECMAMode,
|
|
}
|
|
|
|
op :get_by_val,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
base: VirtualRegister,
|
|
property: VirtualRegister,
|
|
},
|
|
metadata: {
|
|
profile: ValueProfile,
|
|
arrayProfile: ArrayProfile,
|
|
seenIdentifiers: GetByValHistory,
|
|
}
|
|
|
|
op :get_private_name,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
base: VirtualRegister,
|
|
property: VirtualRegister,
|
|
},
|
|
metadata: {
|
|
profile: ValueProfile,
|
|
structureID: StructureID,
|
|
offset: unsigned,
|
|
property: WriteBarrier[JSCell],
|
|
}
|
|
|
|
op :put_private_name,
|
|
args: {
|
|
base: VirtualRegister,
|
|
property: VirtualRegister,
|
|
value: VirtualRegister,
|
|
putKind: PrivateFieldPutKind,
|
|
},
|
|
metadata: {
|
|
oldStructureID: StructureID,
|
|
property: WriteBarrier[JSCell],
|
|
offset: unsigned,
|
|
newStructureID: StructureID,
|
|
}
|
|
|
|
op :put_by_val,
|
|
args: {
|
|
base: VirtualRegister,
|
|
property: VirtualRegister,
|
|
value: VirtualRegister,
|
|
ecmaMode: ECMAMode,
|
|
},
|
|
metadata: {
|
|
arrayProfile: ArrayProfile,
|
|
}
|
|
|
|
op :put_by_val_with_this,
|
|
args: {
|
|
base: VirtualRegister,
|
|
thisValue: VirtualRegister,
|
|
property: VirtualRegister,
|
|
value: VirtualRegister,
|
|
ecmaMode: ECMAMode,
|
|
}
|
|
|
|
op :put_by_val_direct,
|
|
args: {
|
|
base: VirtualRegister,
|
|
property: VirtualRegister,
|
|
value: VirtualRegister,
|
|
ecmaMode: ECMAMode,
|
|
},
|
|
metadata: {
|
|
arrayProfile: ArrayProfile,
|
|
}
|
|
|
|
op :del_by_val,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
base: VirtualRegister,
|
|
property: VirtualRegister,
|
|
ecmaMode: ECMAMode,
|
|
}
|
|
|
|
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,
|
|
ecmaMode: ECMAMode,
|
|
},
|
|
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,
|
|
},
|
|
tmps: {
|
|
argCountIncludingThis: unsigned,
|
|
},
|
|
checkpoints: {
|
|
determiningArgCount: nil,
|
|
makeCall: nil,
|
|
}
|
|
|
|
op :tail_call_varargs,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
callee: VirtualRegister,
|
|
thisValue?: VirtualRegister,
|
|
arguments?: VirtualRegister,
|
|
firstFree: VirtualRegister,
|
|
firstVarArg: int,
|
|
},
|
|
metadata: {
|
|
arrayProfile: ArrayProfile,
|
|
profile: ValueProfile,
|
|
},
|
|
tmps: {
|
|
argCountIncludingThis: unsigned
|
|
},
|
|
checkpoints: {
|
|
determiningArgCount: nil,
|
|
makeCall: nil,
|
|
}
|
|
|
|
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,
|
|
},
|
|
tmps: {
|
|
argCountIncludingThis: unsigned
|
|
},
|
|
checkpoints: {
|
|
determiningArgCount: nil,
|
|
makeCall: nil,
|
|
}
|
|
|
|
op :ret,
|
|
args: {
|
|
value: VirtualRegister,
|
|
}
|
|
|
|
op :strcat,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
src: VirtualRegister,
|
|
count: int,
|
|
}
|
|
|
|
op :to_primitive,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
src: VirtualRegister,
|
|
}
|
|
|
|
op :to_property_key,
|
|
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: ValueProfileAndVirtualRegisterBuffer.*,
|
|
}
|
|
|
|
op :throw,
|
|
args: {
|
|
value: VirtualRegister,
|
|
}
|
|
|
|
op :throw_static_error,
|
|
args: {
|
|
message: VirtualRegister,
|
|
errorType: ErrorTypeWithExtension,
|
|
}
|
|
|
|
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_enumerable_indexed_property,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
base: VirtualRegister,
|
|
property: VirtualRegister,
|
|
},
|
|
metadata: {
|
|
arrayProfile: ArrayProfile,
|
|
}
|
|
|
|
op :has_enumerable_structure_property,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
base: VirtualRegister,
|
|
property: VirtualRegister,
|
|
enumerator: VirtualRegister,
|
|
}
|
|
|
|
op :has_own_structure_property,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
base: VirtualRegister,
|
|
property: VirtualRegister,
|
|
enumerator: VirtualRegister,
|
|
}
|
|
|
|
op :in_structure_property,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
base: VirtualRegister,
|
|
property: VirtualRegister,
|
|
enumerator: VirtualRegister,
|
|
}
|
|
|
|
op :has_enumerable_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,
|
|
}
|
|
|
|
# Semantically, this is iterator = symbolIterator.@call(iterable); next = iterator.next;
|
|
# where symbolIterator the result of iterable[Symbol.iterator] (which is done in a different bytecode).
|
|
# For builtin iterators, however, this has special behavior where next becomes the empty value, which
|
|
# indicates that we are in a known iteration mode to op_iterator_next.
|
|
op :iterator_open,
|
|
args: {
|
|
iterator: VirtualRegister,
|
|
next: VirtualRegister,
|
|
symbolIterator: VirtualRegister,
|
|
iterable: VirtualRegister,
|
|
stackOffset: unsigned,
|
|
},
|
|
metadata: {
|
|
iterationMetadata: IterationModeMetadata,
|
|
iterableProfile: ValueProfile,
|
|
callLinkInfo: LLIntCallLinkInfo,
|
|
iteratorProfile: ValueProfile,
|
|
modeMetadata: GetByIdModeMetadata,
|
|
nextProfile: ValueProfile,
|
|
},
|
|
checkpoints: {
|
|
symbolCall: nil,
|
|
getNext: nil,
|
|
}
|
|
|
|
# Semantically, this is nextResult = next.@call(iterator); done = nextResult.done; value = done ? undefined : nextResult.value;
|
|
op :iterator_next,
|
|
args: {
|
|
done: VirtualRegister,
|
|
value: VirtualRegister,
|
|
iterable: VirtualRegister,
|
|
next: VirtualRegister,
|
|
iterator: VirtualRegister,
|
|
stackOffset: unsigned,
|
|
},
|
|
metadata: {
|
|
iterationMetadata: IterationModeMetadata,
|
|
iterableProfile: ArrayProfile,
|
|
callLinkInfo: LLIntCallLinkInfo,
|
|
nextResultProfile: ValueProfile,
|
|
doneModeMetadata: GetByIdModeMetadata,
|
|
doneProfile: ValueProfile,
|
|
valueModeMetadata: GetByIdModeMetadata,
|
|
valueProfile: ValueProfile,
|
|
},
|
|
tmps: {
|
|
nextResult: JSValue,
|
|
},
|
|
checkpoints: {
|
|
computeNext: nil,
|
|
getDone: nil,
|
|
getValue: nil,
|
|
}
|
|
|
|
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 :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
|
|
op :llint_cloop_did_return_from_js_35
|
|
op :llint_cloop_did_return_from_js_36
|
|
op :llint_cloop_did_return_from_js_37
|
|
op :llint_cloop_did_return_from_js_38
|
|
op :llint_cloop_did_return_from_js_39
|
|
op :llint_cloop_did_return_from_js_40
|
|
op :llint_cloop_did_return_from_js_41
|
|
op :llint_cloop_did_return_from_js_42
|
|
op :llint_cloop_did_return_from_js_43
|
|
op :llint_cloop_did_return_from_js_44
|
|
op :llint_cloop_did_return_from_js_45
|
|
op :llint_cloop_did_return_from_js_46
|
|
|
|
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 :checkpoint_osr_exit_from_inlined_call_trampoline
|
|
op :checkpoint_osr_exit_trampoline
|
|
op :normal_osr_exit_trampoline
|
|
op :fuzzer_return_early_from_loop_hint
|
|
op :llint_get_host_call_return_value
|
|
op :llint_handle_uncaught_exception
|
|
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 :op_iterator_open_return_location
|
|
op :op_iterator_next_return_location
|
|
op :wasm_function_prologue
|
|
op :wasm_function_prologue_no_tls
|
|
|
|
op :op_call_slow_return_location
|
|
op :op_construct_slow_return_location
|
|
op :op_iterator_open_slow_return_location
|
|
op :op_iterator_next_slow_return_location
|
|
op :op_tail_call_return_location
|
|
op :op_tail_call_slow_return_location
|
|
op :op_tail_call_forward_arguments_slow_return_location
|
|
op :op_tail_call_varargs_slow_return_location
|
|
op :op_call_eval_slow_return_location
|
|
|
|
op :js_trampoline_op_call
|
|
op :js_trampoline_op_tail_call
|
|
op :js_trampoline_op_construct
|
|
op :js_trampoline_op_iterator_next
|
|
op :js_trampoline_op_iterator_open
|
|
op :js_trampoline_op_call_slow
|
|
op :js_trampoline_op_tail_call_slow
|
|
op :js_trampoline_op_construct_slow
|
|
op :js_trampoline_op_call_varargs_slow
|
|
op :js_trampoline_op_tail_call_varargs_slow
|
|
op :js_trampoline_op_tail_call_forward_arguments_slow
|
|
op :js_trampoline_op_construct_varargs_slow
|
|
op :js_trampoline_op_call_eval_slow
|
|
op :js_trampoline_op_iterator_next_slow
|
|
op :js_trampoline_op_iterator_open_slow
|
|
op :js_trampoline_llint_function_for_call_arity_check_untag
|
|
op :js_trampoline_llint_function_for_call_arity_check_tag
|
|
op :js_trampoline_llint_function_for_construct_arity_check_untag
|
|
op :js_trampoline_llint_function_for_construct_arity_check_tag
|
|
op :wasm_trampoline_wasm_call
|
|
op :wasm_trampoline_wasm_call_no_tls
|
|
op :wasm_trampoline_wasm_call_indirect
|
|
op :wasm_trampoline_wasm_call_indirect_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
|
|
op :throw_from_fault_handler_trampoline
|
|
|
|
op :call_return_location
|
|
op :call_no_tls_return_location
|
|
op :call_indirect_return_location
|
|
op :call_indirect_no_tls_return_location
|
|
|
|
# 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 :get_global_portable_binding,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
globalIndex: unsigned,
|
|
}
|
|
|
|
op :set_global_portable_binding,
|
|
args: {
|
|
globalIndex: unsigned,
|
|
value: VirtualRegister,
|
|
}
|
|
|
|
op :set_global_ref_portable_binding,
|
|
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_init,
|
|
args: {
|
|
dstOffset: VirtualRegister,
|
|
srcOffset: VirtualRegister,
|
|
length: VirtualRegister,
|
|
elementIndex: unsigned,
|
|
tableIndex: unsigned,
|
|
}
|
|
|
|
op :elem_drop,
|
|
args: {
|
|
elementIndex: 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 :table_copy,
|
|
args: {
|
|
dstOffset: VirtualRegister,
|
|
srcOffset: VirtualRegister,
|
|
length: VirtualRegister,
|
|
dstTableIndex: unsigned,
|
|
srcTableIndex: 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 :memory_fill,
|
|
args: {
|
|
dstAddress: VirtualRegister,
|
|
targetValue: VirtualRegister,
|
|
count: VirtualRegister,
|
|
}
|
|
|
|
op :memory_copy,
|
|
args: {
|
|
dstAddress: VirtualRegister,
|
|
srcAddress: VirtualRegister,
|
|
count: VirtualRegister,
|
|
}
|
|
|
|
op :memory_init,
|
|
args: {
|
|
dstAddress: VirtualRegister,
|
|
srcAddress: VirtualRegister,
|
|
length: VirtualRegister,
|
|
dataSegmentIndex: unsigned,
|
|
}
|
|
|
|
op :data_drop,
|
|
args: {
|
|
dataSegmentIndex: unsigned,
|
|
}
|
|
|
|
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,
|
|
}
|
|
|
|
op_group :AtomicBinaryRMW,
|
|
[
|
|
"add",
|
|
"sub",
|
|
"and",
|
|
"or",
|
|
"xor",
|
|
"xchg",
|
|
].flat_map {|op|
|
|
[
|
|
"i64_atomic_rmw_#{op}",
|
|
"i64_atomic_rmw8_#{op}_u",
|
|
"i64_atomic_rmw16_#{op}_u",
|
|
"i64_atomic_rmw32_#{op}_u",
|
|
]
|
|
}.map {|op| op.to_sym },
|
|
args: {
|
|
dst: VirtualRegister,
|
|
pointer: VirtualRegister,
|
|
offset: unsigned,
|
|
value: VirtualRegister,
|
|
}
|
|
|
|
op_group :AtomicCompareExchange,
|
|
[
|
|
:i64_atomic_rmw_cmpxchg,
|
|
:i64_atomic_rmw8_cmpxchg_u,
|
|
:i64_atomic_rmw16_cmpxchg_u,
|
|
:i64_atomic_rmw32_cmpxchg_u,
|
|
],
|
|
args: {
|
|
dst: VirtualRegister,
|
|
pointer: VirtualRegister,
|
|
offset: unsigned,
|
|
expected: VirtualRegister,
|
|
value: VirtualRegister,
|
|
}
|
|
|
|
op_group :AtomicWait,
|
|
[
|
|
:memory_atomic_wait32,
|
|
:memory_atomic_wait64,
|
|
],
|
|
args: {
|
|
dst: VirtualRegister,
|
|
pointer: VirtualRegister,
|
|
offset: unsigned,
|
|
value: VirtualRegister,
|
|
timeout: VirtualRegister,
|
|
}
|
|
|
|
op :memory_atomic_notify,
|
|
args: {
|
|
dst: VirtualRegister,
|
|
pointer: VirtualRegister,
|
|
offset: unsigned,
|
|
count: VirtualRegister,
|
|
}
|
|
|
|
op :atomic_fence,
|
|
args: {
|
|
}
|
|
|
|
end_section :Wasm
|