class
Crystal::Repl
Defined in:
compiler/crystal/interpreter/closure_context.crcompiler/crystal/interpreter/compiled_block.cr
compiler/crystal/interpreter/compiled_def.cr
compiler/crystal/interpreter/repl.cr
Constant Summary
-
Instructions =
{ put_nil: { code: nil, }, put_i64: { operands: [value : Int64], push: true, code: value, }, put_i128: { operands: [value : Int128], push: true, code: value, }, i64_to_i8: { pop_values: [value : Int64], push: true, overflow: true, code: value.to_i8, }, i64_to_i16: { pop_values: [value : Int64], push: true, overflow: true, code: value.to_i16, }, i64_to_i32: { pop_values: [value : Int64], push: true, overflow: true, code: value.to_i32, }, i64_to_u8: { pop_values: [value : Int64], push: true, overflow: true, code: value.to_u8, }, i64_to_u16: { pop_values: [value : Int64], push: true, overflow: true, code: value.to_u16, }, i64_to_u32: { pop_values: [value : Int64], push: true, overflow: true, code: value.to_u32, }, i64_to_u64: { pop_values: [value : Int64], push: true, overflow: true, code: value.to_u64, }, i64_to_f32: { pop_values: [value : Int64], push: true, code: value.to_f32, }, i64_to_f64: { pop_values: [value : Int64], push: true, code: value.to_f64, }, u64_to_i8: { pop_values: [value : UInt64], push: true, overflow: true, code: value.to_i8, }, u64_to_i16: { pop_values: [value : UInt64], push: true, overflow: true, code: value.to_i16, }, u64_to_i32: { pop_values: [value : UInt64], push: true, overflow: true, code: value.to_i32, }, u64_to_i64: { pop_values: [value : UInt64], push: true, overflow: true, code: value.to_i64, }, u64_to_u8: { pop_values: [value : UInt64], push: true, overflow: true, code: value.to_u8, }, u64_to_u16: { pop_values: [value : UInt64], push: true, overflow: true, code: value.to_u16, }, u64_to_u32: { pop_values: [value : UInt64], push: true, overflow: true, code: value.to_u32, }, u64_to_f32: { pop_values: [value : UInt64], push: true, code: value.to_f32, }, u64_to_f64: { pop_values: [value : UInt64], push: true, code: value.to_f64, }, i128_to_i8: { pop_values: [value : Int128], push: true, overflow: true, code: value.to_i8, }, i128_to_i16: { pop_values: [value : Int128], push: true, overflow: true, code: value.to_i16, }, i128_to_i32: { pop_values: [value : Int128], push: true, overflow: true, code: value.to_i32, }, i128_to_i64: { pop_values: [value : Int128], push: true, overflow: true, code: value.to_i64, }, i128_to_u8: { pop_values: [value : Int128], push: true, overflow: true, code: value.to_u8, }, i128_to_u16: { pop_values: [value : Int128], push: true, overflow: true, code: value.to_u16, }, i128_to_u32: { pop_values: [value : Int128], push: true, overflow: true, code: value.to_u32, }, i128_to_u64: { pop_values: [value : Int128], push: true, overflow: true, code: value.to_u64, }, i128_to_u128: { pop_values: [value : Int128], push: true, overflow: true, code: value.to_u128, }, i128_to_f32: { pop_values: [value : Int128], push: true, code: value.to_f32, }, i128_to_f64: { pop_values: [value : Int128], push: true, code: value.to_f64, }, u128_to_i8: { pop_values: [value : UInt128], push: true, overflow: true, code: value.to_i8, }, u128_to_i16: { pop_values: [value : UInt128], push: true, overflow: true, code: value.to_i16, }, u128_to_i32: { pop_values: [value : UInt128], push: true, overflow: true, code: value.to_i32, }, u128_to_i64: { pop_values: [value : UInt128], push: true, overflow: true, code: value.to_i64, }, u128_to_i128: { pop_values: [value : UInt128], push: true, overflow: true, code: value.to_i128, }, u128_to_u8: { pop_values: [value : UInt128], push: true, overflow: true, code: value.to_u8, }, u128_to_u16: { pop_values: [value : UInt128], push: true, overflow: true, code: value.to_u16, }, u128_to_u32: { pop_values: [value : UInt128], push: true, overflow: true, code: value.to_u32, }, u128_to_u64: { pop_values: [value : UInt128], push: true, overflow: true, code: value.to_u64, }, u128_to_f32: { pop_values: [value : UInt128], push: true, overflow: true, code: value.to_f32, }, u128_to_f64: { pop_values: [value : UInt128], push: true, code: value.to_f64, }, u128_to_f32_bang: { pop_values: [value : UInt128], push: true, code: value.to_f32!, }, f32_to_f64: { pop_values: [value : Float32], push: true, code: value.to_f64, }, f32_to_u32_bang: { pop_values: [value : Float32], push: true, code: value.to_u32!, }, f32_to_u64_bang: { pop_values: [value : Float32], push: true, code: value.to_u64!, }, f64_to_i8: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_i8, }, f64_to_i16: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_i16, }, f64_to_i32: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_i32, }, f64_to_i64: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_i64, }, f64_to_i128: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_i128, }, f64_to_i128_bang: { pop_values: [value : Float64], push: true, code: value.to_i128!, }, f64_to_u128: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_u128, }, f64_to_u8: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_u8, }, f64_to_u16: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_u16, }, f64_to_u32: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_u32, }, f64_to_u32_bang: { pop_values: [value : Float64], push: true, overflow: false, code: value.to_u32!, }, f64_to_u64: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_u64, }, f64_to_i64_bang: { pop_values: [value : Float64], push: true, code: value.to_i64!, }, f64_to_u64_bang: { pop_values: [value : Float64], push: true, code: value.to_u64!, }, f64_to_f32: { pop_values: [value : Float64], push: true, overflow: true, code: value.to_f32, }, f64_to_f32_bang: { pop_values: [value : Float64], push: true, code: value.to_f32!, }, sign_extend: { operands: [amount : Int32], code: begin if amount >= 8 stack_grow_by(8) end if (((stack - amount) - 1).as(::Pointer(Int8))).value < 0 Intrinsics.memset((stack - amount).as(::Pointer(Void)), 255_u8, amount, false) else (stack - amount).clear(amount) end end, }, zero_extend: { operands: [amount : Int32], code: begin if amount >= 8 stack_grow_by(8) end (stack - amount).clear(amount) end, }, add_i32: { pop_values: [a : Int32, b : Int32], push: true, overflow: true, code: a + b, }, add_wrap_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a &+ b, }, sub_i32: { pop_values: [a : Int32, b : Int32], push: true, overflow: true, code: a - b, }, sub_wrap_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a &- b, }, mul_i32: { pop_values: [a : Int32, b : Int32], push: true, overflow: true, code: a * b, }, mul_wrap_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a &* b, }, xor_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a ^ b, }, or_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a | b, }, and_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a & b, }, unsafe_shr_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a.unsafe_shr(b), }, unsafe_shl_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a.unsafe_shl(b), }, unsafe_div_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a.unsafe_div(b), }, unsafe_mod_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a.unsafe_mod(b), }, add_u32: { pop_values: [a : UInt32, b : UInt32], push: true, overflow: true, code: a + b, }, sub_u32: { pop_values: [a : UInt32, b : UInt32], push: true, overflow: true, code: a - b, }, mul_u32: { pop_values: [a : UInt32, b : UInt32], push: true, overflow: true, code: a * b, }, unsafe_shr_u32: { pop_values: [a : UInt32, b : UInt32], push: true, code: a.unsafe_shr(b), }, unsafe_div_u32: { pop_values: [a : UInt32, b : UInt32], push: true, code: a.unsafe_div(b), }, unsafe_mod_u32: { pop_values: [a : UInt32, b : UInt32], push: true, code: a.unsafe_mod(b), }, add_i64: { pop_values: [a : Int64, b : Int64], push: true, overflow: true, code: a + b, }, add_wrap_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a &+ b, }, sub_i64: { pop_values: [a : Int64, b : Int64], push: true, overflow: true, code: a - b, }, sub_wrap_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a &- b, }, mul_i64: { pop_values: [a : Int64, b : Int64], push: true, overflow: true, code: a * b, }, mul_wrap_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a &* b, }, xor_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a ^ b, }, or_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a | b, }, and_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a & b, }, unsafe_shr_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a.unsafe_shr(b), }, unsafe_shl_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a.unsafe_shl(b), }, unsafe_div_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a.unsafe_div(b), }, unsafe_mod_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a.unsafe_mod(b), }, add_u64: { pop_values: [a : UInt64, b : UInt64], push: true, overflow: true, code: a + b, }, sub_u64: { pop_values: [a : UInt64, b : UInt64], push: true, overflow: true, code: a - b, }, mul_u64: { pop_values: [a : UInt64, b : UInt64], push: true, overflow: true, code: a * b, }, unsafe_shr_u64: { pop_values: [a : UInt64, b : UInt64], push: true, code: a.unsafe_shr(b), }, unsafe_div_u64: { pop_values: [a : UInt64, b : UInt64], push: true, code: a.unsafe_div(b), }, unsafe_mod_u64: { pop_values: [a : UInt64, b : UInt64], push: true, code: a.unsafe_mod(b), }, add_i128: { pop_values: [a : Int128, b : Int128], push: true, overflow: true, code: a + b, }, add_wrap_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a &+ b, }, sub_i128: { pop_values: [a : Int128, b : Int128], push: true, overflow: true, code: a - b, }, sub_wrap_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a &- b, }, mul_i128: { pop_values: [a : Int128, b : Int128], push: true, overflow: true, code: a * b, }, mul_wrap_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a &* b, }, xor_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a ^ b, }, or_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a | b, }, and_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a & b, }, unsafe_shr_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a.unsafe_shr(b), }, unsafe_shl_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a.unsafe_shl(b), }, unsafe_div_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a.unsafe_div(b), }, unsafe_mod_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a.unsafe_mod(b), }, add_u128: { pop_values: [a : UInt128, b : UInt128], push: true, overflow: true, code: a + b, }, sub_u128: { pop_values: [a : UInt128, b : UInt128], push: true, overflow: true, code: a - b, }, mul_u128: { pop_values: [a : UInt128, b : UInt128], push: true, overflow: true, code: a * b, }, unsafe_shr_u128: { pop_values: [a : UInt128, b : UInt128], push: true, code: a.unsafe_shr(b), }, unsafe_div_u128: { pop_values: [a : UInt128, b : UInt128], push: true, code: a.unsafe_div(b), }, unsafe_mod_u128: { pop_values: [a : UInt128, b : UInt128], push: true, code: a.unsafe_mod(b), }, add_f32: { pop_values: [a : Float32, b : Float32], push: true, code: a + b, }, sub_f32: { pop_values: [a : Float32, b : Float32], push: true, code: a - b, }, mul_f32: { pop_values: [a : Float32, b : Float32], push: true, code: a * b, }, div_f32: { pop_values: [a : Float32, b : Float32], push: true, code: a / b, }, add_f64: { pop_values: [a : Float64, b : Float64], push: true, code: a + b, }, sub_f64: { pop_values: [a : Float64, b : Float64], push: true, code: a - b, }, mul_f64: { pop_values: [a : Float64, b : Float64], push: true, code: a * b, }, div_f64: { pop_values: [a : Float64, b : Float64], push: true, code: a / b, }, add_u64_i64: { pop_values: [a : UInt64, b : Int64], push: true, overflow: true, code: a + b, }, sub_u64_i64: { pop_values: [a : UInt64, b : Int64], push: true, overflow: true, code: a - b, }, mul_u64_i64: { pop_values: [a : UInt64, b : Int64], push: true, overflow: true, code: a * b, }, unsafe_shr_u64_i64: { pop_values: [a : UInt64, b : Int64], push: true, code: a.unsafe_shr(b), }, unsafe_div_u64_i64: { pop_values: [a : UInt64, b : Int64], push: true, code: a.unsafe_div(b), }, unsafe_mod_u64_i64: { pop_values: [a : UInt64, b : Int64], push: true, code: a.unsafe_mod(b), }, add_i64_u64: { pop_values: [a : Int64, b : UInt64], push: true, overflow: true, code: a + b, }, sub_i64_u64: { pop_values: [a : Int64, b : UInt64], push: true, overflow: true, code: a - b, }, mul_i64_u64: { pop_values: [a : Int64, b : UInt64], push: true, overflow: true, code: a * b, }, unsafe_shr_i64_u64: { pop_values: [a : Int64, b : UInt64], push: true, code: a.unsafe_shr(b), }, unsafe_div_i64_u64: { pop_values: [a : Int64, b : UInt64], push: true, code: a.unsafe_div(b), }, unsafe_mod_i64_u64: { pop_values: [a : Int64, b : UInt64], push: true, code: a.unsafe_mod(b), }, add_u128_i128: { pop_values: [a : UInt128, b : Int128], push: true, overflow: true, code: a + b, }, sub_u128_i128: { pop_values: [a : UInt128, b : Int128], push: true, overflow: true, code: a - b, }, mul_u128_i128: { pop_values: [a : UInt128, b : Int128], push: true, overflow: true, code: a * b, }, unsafe_shr_u128_i128: { pop_values: [a : UInt128, b : Int128], push: true, code: a.unsafe_shr(b), }, unsafe_div_u128_i128: { pop_values: [a : UInt128, b : Int128], push: true, code: a.unsafe_div(b), }, unsafe_mod_u128_i128: { pop_values: [a : UInt128, b : Int128], push: true, code: a.unsafe_mod(b), }, add_i128_u128: { pop_values: [a : Int128, b : UInt128], push: true, overflow: true, code: a + b, }, sub_i128_u128: { pop_values: [a : Int128, b : UInt128], push: true, overflow: true, code: a - b, }, mul_i128_u128: { pop_values: [a : Int128, b : UInt128], push: true, overflow: true, code: a * b, }, unsafe_shr_i128_u128: { pop_values: [a : Int128, b : UInt128], push: true, code: a.unsafe_shr(b), }, unsafe_div_i128_u128: { pop_values: [a : Int128, b : UInt128], push: true, code: a.unsafe_div(b), }, unsafe_mod_i128_u128: { pop_values: [a : Int128, b : UInt128], push: true, code: a.unsafe_mod(b), }, cmp_i32: { pop_values: [a : Int32, b : Int32], push: true, code: a == b ? 0 : (a < b ? -1 : 1), }, cmp_u32: { pop_values: [a : UInt32, b : UInt32], push: true, code: a == b ? 0 : (a < b ? -1 : 1), }, cmp_i64: { pop_values: [a : Int64, b : Int64], push: true, code: a == b ? 0 : (a < b ? -1 : 1), }, cmp_u64: { pop_values: [a : UInt64, b : UInt64], push: true, code: a == b ? 0 : (a < b ? -1 : 1), }, cmp_i128: { pop_values: [a : Int128, b : Int128], push: true, code: a == b ? 0 : (a < b ? -1 : 1), }, cmp_u128: { pop_values: [a : UInt128, b : UInt128], push: true, code: a == b ? 0 : (a < b ? -1 : 1), }, cmp_u64_i64: { pop_values: [a : UInt64, b : Int64], push: true, code: a == b ? 0 : (a < b ? -1 : 1), }, cmp_i64_u64: { pop_values: [a : Int64, b : UInt64], push: true, code: a == b ? 0 : (a < b ? -1 : 1), }, cmp_u128_i128: { pop_values: [a : UInt128, b : Int128], push: true, code: a == b ? 0 : (a < b ? -1 : 1), }, cmp_i128_u128: { pop_values: [a : Int128, b : UInt128], push: true, code: a == b ? 0 : (a < b ? -1 : 1), }, cmp_f32: { operands: [predicate : Compiler::FloatPredicate], pop_values: [a : Float32, b : Float32], push: true, code: predicate.compare(a, b), }, cmp_f64: { operands: [predicate : Compiler::FloatPredicate], pop_values: [a : Float64, b : Float64], push: true, code: predicate.compare(a, b), }, cmp_eq: { pop_values: [cmp : Int32], push: true, code: cmp == 0, }, cmp_neq: { pop_values: [cmp : Int32], push: true, code: cmp != 0, }, cmp_lt: { pop_values: [cmp : Int32], push: true, code: cmp < 0, }, cmp_le: { pop_values: [cmp : Int32], push: true, code: cmp <= 0, }, cmp_gt: { pop_values: [cmp : Int32], push: true, code: cmp > 0, }, cmp_ge: { pop_values: [cmp : Int32], push: true, code: cmp >= 0, }, logical_not: { pop_values: [value : Bool], push: true, code: !value, }, pointer_malloc: { operands: [element_size : Int32], pop_values: [size : UInt64], push: true, code: (Pointer(Void).malloc(size * element_size)).as(::Pointer(UInt8)), }, pointer_realloc: { operands: [element_size : Int32], pop_values: [pointer : Pointer(UInt8), size : UInt64], push: true, code: pointer.realloc(size * element_size), }, pointer_set: { operands: [element_size : Int32], pop_values: [pointer : Pointer(UInt8)], code: stack_move_to(pointer, element_size), }, pointer_get: { operands: [element_size : Int32], pop_values: [pointer : Pointer(UInt8)], code: stack_move_from(pointer, element_size), }, pointer_new: { pop_values: [type_id : Int32, address : UInt64], push: true, code: Pointer(UInt8).new(address), }, pointer_address: { pop_values: [pointer : Pointer(UInt8)], push: true, code: pointer.address, }, pointer_diff: { operands: [element_size : Int32], pop_values: [pointer1 : Pointer(UInt8), pointer2 : Pointer(UInt8)], push: true, code: if pointer1.address > pointer2.address (pointer1 - pointer2) // element_size else -((pointer2.address - pointer1.address).to_i64! // element_size) end, }, pointer_add: { operands: [element_size : Int32], pop_values: [pointer : Pointer(UInt8), offset : Int64], push: true, code: pointer + (offset * element_size), }, pointer_is_null: { pop_values: [pointer : Pointer(UInt8)], push: true, code: pointer.null?, }, pointer_is_not_null: { pop_values: [pointer : Pointer(UInt8)], push: true, code: !pointer.null?, }, set_local: { operands: [index : Int32, size : Int32], code: set_local_var(index, size), disassemble: { index: case node when Var "#{node}@#{index}" when Assign "#{node.target}@#{index}" else "@#{index}" end, }, }, get_local: { operands: [index : Int32, size : Int32], code: get_local_var(index, size), disassemble: { index: case node when Var "#{node}@#{index}" when Assign "#{node.target}@#{index}" else "@#{index}" end, }, }, get_self_ivar: { operands: [offset : Int32, size : Int32], code: stack_move_from(self_class_pointer + offset, size), }, set_self_ivar: { operands: [offset : Int32, size : Int32], code: stack_move_to(self_class_pointer + offset, size), }, get_class_ivar: { operands: [offset : Int32, size : Int32], pop_values: [pointer : Pointer(UInt8)], code: stack_move_from(pointer + offset, size), }, get_struct_ivar: { operands: [offset : Int32, size : Int32, total_size : Int32], code: begin (stack - total_size).move_from((stack - total_size) + offset, size) stack_shrink_by(total_size - size) stack_grow_by((align(size)) - size) end, }, const_initialized: { operands: [index : Int32], push: true, code: const_initialized?(index), }, get_const: { operands: [index : Int32, size : Int32], code: get_const(index, size), }, set_const: { operands: [index : Int32, size : Int32], code: set_const(index, size), }, get_const_pointer: { operands: [index : Int32], push: true, code: get_const_pointer(index), }, class_var_initialized: { operands: [index : Int32], push: true, code: class_var_initialized?(index), }, get_class_var: { operands: [index : Int32, size : Int32], code: get_class_var(index, size), }, set_class_var: { operands: [index : Int32, size : Int32], code: set_class_var(index, size), }, pop: { operands: [size : Int32], code: stack_shrink_by(size), }, pop_from_offset: { operands: [size : Int32, offset : Int32], code: begin ((stack - offset) - size).move_from(stack - offset, offset) stack_shrink_by(size) end, }, dup: { operands: [size : Int32], code: stack_move_from(stack - size, size), }, push_zeros: { operands: [amount : Int32], code: stack_grow_by(amount), }, put_stack_top_pointer: { operands: [size : Int32], push: true, code: stack - size, }, branch_if: { operands: [index : Int32], pop_values: [cond : Bool], code: (if cond set_ip(index) end), }, branch_unless: { operands: [index : Int32], pop_values: [cond : Bool], code: (if cond else set_ip(index) end), }, jump: { operands: [index : Int32], code: set_ip(index), }, pointerof_var: { operands: [index : Int32], push: true, code: get_local_var_pointer(index), }, pointerof_ivar: { operands: [offset : Int32], push: true, code: get_ivar_pointer(offset), }, pointerof_class_var: { operands: [index : Int32], push: true, code: get_class_var_pointer(index), }, call: { operands: [compiled_def : CompiledDef], code: call(compiled_def), disassemble: { compiled_def: "#{compiled_def.owner}##{compiled_def.def.name}", }, }, call_with_block: { operands: [compiled_def : CompiledDef], code: call_with_block(compiled_def), disassemble: { compiled_def: "#{compiled_def.owner}##{compiled_def.def.name}", }, }, call_block: { operands: [compiled_block : CompiledBlock], code: call_block(compiled_block), }, lib_call: { operands: [lib_function : LibFunction], code: lib_call(lib_function), }, leave: { operands: [size : Int32], code: leave(size), }, leave_def: { operands: [size : Int32], code: leave_def(size), }, break_block: { operands: [size : Int32], code: break_block(size), }, allocate_class: { operands: [size : Int32, type_id : Int32], push: true, code: begin ptr = (Pointer(Void).malloc(size)).as(::Pointer(UInt8)) (ptr.as(::Pointer(Int32))).value = type_id ptr end, }, reset_class: { operands: [size : Int32, type_id : Int32], pop_values: [pointer : Pointer(UInt8)], push: true, code: begin pointer.clear(size) if type_id == 0 else (pointer.as(::Pointer(Int32))).value = type_id end pointer end, }, put_metaclass: { operands: [size : Int32, union_type : Bool], push: true, code: begin type_id = if union_type ((stack - size).as(::Pointer(Int32))).value else (((stack - size).as(::Pointer(::Pointer(Void)))).value.as(::Pointer(Int32))).value end stack_shrink_by(size) type = context.type_from_id(type_id) context.type_id(type.metaclass) end, }, put_in_union: { operands: [type_id : Int32, from_size : Int32, union_size : Int32], code: begin tmp_stack = stack stack_grow_by(union_size - from_size) (tmp_stack - from_size).move_to((tmp_stack - from_size) + type_id_bytesize, from_size) ((tmp_stack - from_size).as(::Pointer(Int64))).value = type_id.to_i64! end, disassemble: { type_id: context.type_from_id(type_id), }, }, put_reference_type_in_union: { operands: [union_size : Int32], code: begin from_size = sizeof(Pointer(UInt8)) reference = ((stack - from_size).as(::Pointer(::Pointer(UInt8)))).value type_id = if reference.null? 0 else (reference.as(::Pointer(Int32))).value end tmp_stack = stack stack_grow_by(union_size - from_size) (tmp_stack - from_size).copy_to((tmp_stack - from_size) + type_id_bytesize, from_size) ((tmp_stack - from_size).as(::Pointer(Int64))).value = type_id.to_i64! end, }, put_nilable_type_in_union: { operands: [union_size : Int32], pop_values: [pointer : Pointer(UInt8)], code: begin if pointer.null? stack_grow_by(union_size) else type_id = (pointer.as(::Pointer(Int32))).value stack_push(type_id) stack_push(pointer) remaining = (union_size - (sizeof(Pointer(Void)))) - type_id_bytesize if remaining > 0 stack_grow_by(remaining) end end end, }, remove_from_union: { operands: [union_size : Int32, from_size : Int32], code: begin (stack - union_size).move_from((stack - union_size) + type_id_bytesize, from_size) stack_shrink_by(union_size - from_size) end, }, union_to_bool: { operands: [union_size : Int32], push: true, code: begin type_id = ((stack - union_size).as(::Pointer(Int32))).value type = type_from_type_id(type_id) value = case type when NilType false when BoolType (((stack - union_size) + 8).as(::Pointer(Bool))).value when PointerInstanceType !(((stack - union_size) + 8).as(::Pointer(::Pointer(UInt8)))).value.null? else true end stack_shrink_by(union_size) value end, }, get_union_type_id: { operands: [union_size : Int32], push: true, code: ((stack - union_size).as(::Pointer(Int32))).value, }, put_union_type_id: { operands: [type_id : Int32, union_size : Int32], push: false, code: ((stack - union_size).as(::Pointer(Int32))).value = type_id, }, reference_is_a: { operands: [filter_type_id : Int32], pop_values: [pointer : Pointer(UInt8)], push: true, code: begin if pointer.null? false else type_id = (pointer.as(::Pointer(Int32))).value type = type_from_type_id(type_id) filter_type = type_from_type_id(filter_type_id) !!(type.filter_by(filter_type)) end end, disassemble: { filter_type_id: context.type_from_id(filter_type_id), }, }, metaclass_is_a: { operands: [filter_type_id : Int32], pop_values: [metaclass_id : Int32], push: true, code: begin type = type_from_type_id(metaclass_id) filter_type = type_from_type_id(filter_type_id) if type.is_a?(VirtualMetaclassType) type.devirtualize == filter_type else !!(type.filter_by(filter_type)) end end, disassemble: { filter_type_id: context.type_from_id(filter_type_id), }, }, union_is_a: { operands: [union_size : Int32, filter_type_id : Int32], push: true, code: begin type_id = ((stack - union_size).as(::Pointer(Int32))).value type = type_from_type_id(type_id) stack_shrink_by(union_size) filter_type = type_from_type_id(filter_type_id) !!(type.filter_by(filter_type)) end, disassemble: { filter_type_id: context.type_from_id(filter_type_id), }, }, tuple_indexer_known_index: { operands: [tuple_size : Int32, offset : Int32, value_size : Int32], code: begin (stack - tuple_size).move_from((stack - tuple_size) + offset, value_size) aligned_value_size = align(value_size) stack_shrink_by(tuple_size - value_size) stack_grow_by(aligned_value_size - value_size) end, }, copy_from: { operands: [offset : Int32, size : Int32], code: stack_move_from(stack - offset, size), }, tuple_copy_element: { operands: [tuple_size : Int32, old_offset : Int32, new_offset : Int32, element_size : Int32], code: ((stack - tuple_size) + new_offset).move_from((stack - tuple_size) + old_offset, element_size), }, symbol_to_s: { pop_values: [index : Int32], push: true, code: (@context.index_to_symbol(index)).object_id.to_u64!, }, proc_call: { pop_values: [compiled_def : CompiledDef, closure_data : Pointer(Void)], push: true, code: begin if closure_data.null? else stack_push(closure_data) end call(compiled_def) end, }, proc_to_c_fun: { operands: [ffi_call_interface : FFI::CallInterface], pop_values: [compiled_def : CompiledDef, closure_data : ::Pointer(Void)], push: true, code: begin ffi_closure = FFI::Closure.new(ffi_call_interface, @context.ffi_closure_fun, (@context.ffi_closure_context(self, compiled_def)).as(::Pointer(Void))) @context.ffi_closure_to_compiled_def[ffi_closure.to_unsafe] = compiled_def ffi_closure.to_unsafe.unsafe_as(Int64) end, disassemble: { ffi_call_interface: "<ffi_call_interface>", }, }, c_fun_to_proc: { pop_values: [ffi_closure_code : ::Pointer(Void)], push: true, code: begin compiled_def = @context.ffi_closure_to_compiled_def[ffi_closure_code] {Pointer(Void).new(compiled_def.object_id), Pointer(Void).null} end, }, load_atomic: { operands: [element_size : Int32], pop_values: [ptr : Pointer(UInt8), ordering : Symbol, volatile : Bool], code: begin case element_size when 1 i8 = Atomic::Ops.load(ptr, :sequentially_consistent, true) stack_push(i8) when 2 i16 = Atomic::Ops.load(ptr.as(::Pointer(Int16)), :sequentially_consistent, true) stack_push(i16) when 4 i32 = Atomic::Ops.load(ptr.as(::Pointer(Int32)), :sequentially_consistent, true) stack_push(i32) when 8 i64 = Atomic::Ops.load(ptr.as(::Pointer(Int64)), :sequentially_consistent, true) stack_push(i64) else raise("BUG: unhandled element size for load_atomic instruction: #{element_size}") end end, }, store_atomic: { operands: [element_size : Int32], pop_values: [ptr : Pointer(UInt8), value : UInt64, ordering : Symbol, volatile : Bool], code: begin case element_size when 1 i8 = Atomic::Ops.store(ptr, value.to_u8!, :sequentially_consistent, true) stack_push(i8) when 2 i16 = Atomic::Ops.store(ptr.as(::Pointer(Int16)), value.to_i16!, :sequentially_consistent, true) stack_push(i16) when 4 i32 = Atomic::Ops.store(ptr.as(::Pointer(Int32)), value.to_i32!, :sequentially_consistent, true) stack_push(i32) when 8 i64 = Atomic::Ops.store(ptr.as(::Pointer(Int64)), value.to_i64!, :sequentially_consistent, true) stack_push(i64) else raise("BUG: unhandled element size for store_atomic instruction: #{element_size}") end end, }, atomicrmw: { operands: [element_size : Int32], pop_values: [op_i : Int32, ptr : Pointer(UInt8), value : UInt64, ordering : Symbol, singlethread : Bool], code: begin op = @context.index_to_symbol(op_i) case op when "add" atomicrmw_op(:add) when "sub" atomicrmw_op(:sub) when "and" atomicrmw_op(:and) when "nand" atomicrmw_op(:nand) when "or" atomicrmw_op(:or) when "xor" atomicrmw_op(:xor) when "max" atomicrmw_op(:max) when "umax" atomicrmw_op(:umax) when "min" atomicrmw_op(:min) when "umin" atomicrmw_op(:umin) when "xchg" atomicrmw_op(:xchg) else raise("BUG: missing atomicrmw #{op}") end end, }, cmpxchg: { operands: [element_size : Int32], pop_values: [ptr : Pointer(UInt8), cmp : UInt64, new : UInt64, success_ordering : Symbol, failure_ordering : Symbol], code: begin case element_size when 1 i8 = Atomic::Ops.cmpxchg(ptr, cmp.to_u8!, new.to_u8!, :sequentially_consistent, :sequentially_consistent) stack_push(i8) when 2 i16 = Atomic::Ops.cmpxchg(ptr.as(::Pointer(Int16)), cmp.to_i16!, new.to_i16!, :sequentially_consistent, :sequentially_consistent) stack_push(i16) when 4 i32 = Atomic::Ops.cmpxchg(ptr.as(::Pointer(Int32)), cmp.to_i32!, new.to_i32!, :sequentially_consistent, :sequentially_consistent) stack_push(i32) when 8 i64 = Atomic::Ops.cmpxchg(ptr.as(::Pointer(Int64)), cmp.to_i64!, new.to_i64!, :sequentially_consistent, :sequentially_consistent) stack_push(i64) else raise("BUG: unhandled element size for cmpxchg instruction: #{element_size}") end end, }, argc_unsafe: { push: true, code: argc_unsafe, }, argv_unsafe: { push: true, code: argv_unsafe, }, interpreter_proc_new: { operands: [proc_type_id : Int32], pop_values: [pointer : ::Pointer(Void), closure_data : ::Pointer(Void)], push: true, code: begin if @context.compiled_procs.includes?(pointer.address) {pointer, closure_data} else if closure_data raise("BUG: closure_data not nil but pointer is not a CompiledDef") end proc_type = (type_from_type_id(proc_type_id)).as(ProcInstanceType) compiled_def = @context.extern_proc_wrapper(proc_type, pointer) {compiled_def.as(::Pointer(Void)), Pointer(Void).null} end end, }, interpreter_call_stack_unwind: { push: true, code: backtrace, }, interpreter_raise_without_backtrace: { pop_values: [exception : ::Pointer(UInt8)], code: raise_exception(exception), }, throw: { code: throw, }, interpreter_current_fiber: { push: true, code: Fiber.current.as(::Pointer(Void)), }, interpreter_spawn: { pop_values: [fiber : ::Pointer(Void), fiber_main : ::Pointer(Void)], push: true, code: spawn_interpreter(fiber, fiber_main), }, interpreter_fiber_swapcontext: { pop_values: [current_context : ::Pointer(Void), new_context : ::Pointer(Void)], code: swapcontext(current_context, new_context), }, interpreter_fiber_resumable: { pop_values: [context : ::Pointer(Void)], push: true, code: fiber_resumable(context), }, interpreter_signal_descriptor: { pop_values: [fd : Int32], code: signal_descriptor(fd), }, interpreter_signal: { pop_values: [signum : Int32, handler : Int32], code: signal(signum, handler), }, interpreter_intrinsics_memcpy: { pop_values: [dest : Pointer(Void), src : Pointer(Void), len : UInt64, is_volatile : Bool], code: begin if is_volatile LibIntrinsics.memcpy(dest, src, len, true) else LibIntrinsics.memcpy(dest, src, len, false) end end, }, interpreter_intrinsics_memmove: { pop_values: [dest : Pointer(Void), src : Pointer(Void), len : UInt64, is_volatile : Bool], code: begin if is_volatile LibIntrinsics.memmove(dest, src, len, true) else LibIntrinsics.memmove(dest, src, len, false) end end, }, interpreter_intrinsics_memset: { pop_values: [dest : Pointer(Void), val : UInt8, len : UInt64, is_volatile : Bool], code: begin if is_volatile LibIntrinsics.memset(dest, val, len, true) else LibIntrinsics.memset(dest, val, len, false) end end, }, interpreter_intrinsics_debugtrap: { code: pry, }, interpreter_intrinsics_pause: { code: LibIntrinsics.pause, }, interpreter_intrinsics_read_cycle_counter: { push: true, code: LibIntrinsics.read_cycle_counter, }, interpreter_intrinsics_bitreverse8: { pop_values: [value : UInt8], push: true, code: LibIntrinsics.bitreverse8(value), }, interpreter_intrinsics_popcount8: { pop_values: [value : Int8], push: true, code: LibIntrinsics.popcount8(value), }, interpreter_intrinsics_countleading8: { pop_values: [src : Int8, zero_is_undef : Bool], push: true, code: begin if zero_is_undef LibIntrinsics.countleading8(src, true) else LibIntrinsics.countleading8(src, false) end end, }, interpreter_intrinsics_counttrailing8: { pop_values: [src : Int8, zero_is_undef : Bool], push: true, code: begin if zero_is_undef LibIntrinsics.counttrailing8(src, true) else LibIntrinsics.counttrailing8(src, false) end end, }, interpreter_intrinsics_fshl8: { pop_values: [a : UInt8, b : UInt8, count : UInt8], push: true, code: LibIntrinsics.fshl8(a, b, count), }, interpreter_intrinsics_fshr8: { pop_values: [a : UInt8, b : UInt8, count : UInt8], push: true, code: LibIntrinsics.fshr8(a, b, count), }, interpreter_intrinsics_bitreverse16: { pop_values: [value : UInt16], push: true, code: LibIntrinsics.bitreverse16(value), }, interpreter_intrinsics_bswap16: { pop_values: [value : UInt16], push: true, code: LibIntrinsics.bswap16(value), }, interpreter_intrinsics_popcount16: { pop_values: [value : Int16], push: true, code: LibIntrinsics.popcount16(value), }, interpreter_intrinsics_countleading16: { pop_values: [src : Int16, zero_is_undef : Bool], push: true, code: begin if zero_is_undef LibIntrinsics.countleading16(src, true) else LibIntrinsics.countleading16(src, false) end end, }, interpreter_intrinsics_counttrailing16: { pop_values: [src : Int16, zero_is_undef : Bool], push: true, code: begin if zero_is_undef LibIntrinsics.counttrailing16(src, true) else LibIntrinsics.counttrailing16(src, false) end end, }, interpreter_intrinsics_fshl16: { pop_values: [a : UInt16, b : UInt16, count : UInt16], push: true, code: LibIntrinsics.fshl16(a, b, count), }, interpreter_intrinsics_fshr16: { pop_values: [a : UInt16, b : UInt16, count : UInt16], push: true, code: LibIntrinsics.fshr16(a, b, count), }, interpreter_intrinsics_bitreverse32: { pop_values: [value : UInt32], push: true, code: LibIntrinsics.bitreverse32(value), }, interpreter_intrinsics_bswap32: { pop_values: [value : UInt32], push: true, code: LibIntrinsics.bswap32(value), }, interpreter_intrinsics_popcount32: { pop_values: [value : Int32], push: true, code: LibIntrinsics.popcount32(value), }, interpreter_intrinsics_countleading32: { pop_values: [src : Int32, zero_is_undef : Bool], push: true, code: begin if zero_is_undef LibIntrinsics.countleading32(src, true) else LibIntrinsics.countleading32(src, false) end end, }, interpreter_intrinsics_counttrailing32: { pop_values: [src : Int32, zero_is_undef : Bool], push: true, code: begin if zero_is_undef LibIntrinsics.counttrailing32(src, true) else LibIntrinsics.counttrailing32(src, false) end end, }, interpreter_intrinsics_fshl32: { pop_values: [a : UInt32, b : UInt32, count : UInt32], push: true, code: LibIntrinsics.fshl32(a, b, count), }, interpreter_intrinsics_fshr32: { pop_values: [a : UInt32, b : UInt32, count : UInt32], push: true, code: LibIntrinsics.fshr32(a, b, count), }, interpreter_intrinsics_bitreverse64: { pop_values: [value : UInt64], push: true, code: LibIntrinsics.bitreverse64(value), }, interpreter_intrinsics_bswap64: { pop_values: [value : UInt64], push: true, code: LibIntrinsics.bswap64(value), }, interpreter_intrinsics_popcount64: { pop_values: [value : Int64], push: true, code: LibIntrinsics.popcount64(value), }, interpreter_intrinsics_countleading64: { pop_values: [src : Int64, zero_is_undef : Bool], push: true, code: begin if zero_is_undef LibIntrinsics.countleading64(src, true) else LibIntrinsics.countleading64(src, false) end end, }, interpreter_intrinsics_counttrailing64: { pop_values: [src : Int64, zero_is_undef : Bool], push: true, code: begin if zero_is_undef LibIntrinsics.counttrailing64(src, true) else LibIntrinsics.counttrailing64(src, false) end end, }, interpreter_intrinsics_fshl64: { pop_values: [a : UInt64, b : UInt64, count : UInt64], push: true, code: LibIntrinsics.fshl64(a, b, count), }, interpreter_intrinsics_fshr64: { pop_values: [a : UInt64, b : UInt64, count : UInt64], push: true, code: LibIntrinsics.fshr64(a, b, count), }, interpreter_intrinsics_bitreverse128: { pop_values: [value : UInt128], push: true, code: LibIntrinsics.bitreverse128(value), }, interpreter_intrinsics_bswap128: { pop_values: [value : UInt128], push: true, code: LibIntrinsics.bswap128(value), }, interpreter_intrinsics_popcount128: { pop_values: [value : Int128], push: true, code: LibIntrinsics.popcount128(value), }, interpreter_intrinsics_countleading128: { pop_values: [src : Int128, zero_is_undef : Bool], push: true, code: begin if zero_is_undef LibIntrinsics.countleading128(src, true) else LibIntrinsics.countleading128(src, false) end end, }, interpreter_intrinsics_counttrailing128: { pop_values: [src : Int128, zero_is_undef : Bool], push: true, code: begin if zero_is_undef LibIntrinsics.counttrailing128(src, true) else LibIntrinsics.counttrailing128(src, false) end end, }, interpreter_intrinsics_fshl128: { pop_values: [a : UInt128, b : UInt128, count : UInt128], push: true, code: LibIntrinsics.fshl128(a, b, count), }, interpreter_intrinsics_fshr128: { pop_values: [a : UInt128, b : UInt128, count : UInt128], push: true, code: LibIntrinsics.fshr128(a, b, count), }, libm_ceil_f32: { pop_values: [value : Float32], push: true, code: LibM.ceil_f32(value), }, libm_ceil_f64: { pop_values: [value : Float64], push: true, code: LibM.ceil_f64(value), }, libm_cos_f32: { pop_values: [value : Float32], push: true, code: LibM.cos_f32(value), }, libm_cos_f64: { pop_values: [value : Float64], push: true, code: LibM.cos_f64(value), }, libm_exp_f32: { pop_values: [value : Float32], push: true, code: LibM.exp_f32(value), }, libm_exp_f64: { pop_values: [value : Float64], push: true, code: LibM.exp_f64(value), }, libm_exp2_f32: { pop_values: [value : Float32], push: true, code: LibM.exp2_f32(value), }, libm_exp2_f64: { pop_values: [value : Float64], push: true, code: LibM.exp2_f64(value), }, libm_floor_f32: { pop_values: [value : Float32], push: true, code: LibM.floor_f32(value), }, libm_floor_f64: { pop_values: [value : Float64], push: true, code: LibM.floor_f64(value), }, libm_fma_f32: { pop_values: [value1 : Float32, value2 : Float32, value3 : Float32], push: true, code: LibM.fma_f32(value1, value2, value3), }, libm_fma_f64: { pop_values: [value1 : Float64, value2 : Float64, value3 : Float64], push: true, code: LibM.fma_f64(value1, value2, value3), }, libm_log_f32: { pop_values: [value : Float32], push: true, code: LibM.log_f32(value), }, libm_log_f64: { pop_values: [value : Float64], push: true, code: LibM.log_f64(value), }, libm_log2_f32: { pop_values: [value : Float32], push: true, code: LibM.log2_f32(value), }, libm_log2_f64: { pop_values: [value : Float64], push: true, code: LibM.log2_f64(value), }, libm_log10_f32: { pop_values: [value : Float32], push: true, code: LibM.log10_f32(value), }, libm_log10_f64: { pop_values: [value : Float64], push: true, code: LibM.log10_f64(value), }, libm_round_f32: { pop_values: [value : Float32], push: true, code: LibM.round_f32(value), }, libm_round_f64: { pop_values: [value : Float64], push: true, code: LibM.round_f64(value), }, libm_rint_f32: { pop_values: [value : Float32], push: true, code: LibM.rint_f32(value), }, libm_rint_f64: { pop_values: [value : Float64], push: true, code: LibM.rint_f64(value), }, libm_sin_f32: { pop_values: [value : Float32], push: true, code: LibM.sin_f32(value), }, libm_sin_f64: { pop_values: [value : Float64], push: true, code: LibM.sin_f64(value), }, libm_sqrt_f32: { pop_values: [value : Float32], push: true, code: LibM.sqrt_f32(value), }, libm_sqrt_f64: { pop_values: [value : Float64], push: true, code: LibM.sqrt_f64(value), }, libm_trunc_f32: { pop_values: [value : Float32], push: true, code: LibM.trunc_f32(value), }, libm_trunc_f64: { pop_values: [value : Float64], push: true, code: LibM.trunc_f64(value), }, libm_powi_f32: { pop_values: [value : Float32, power : Int32], push: true, code: LibM.powi_f32(value, power), }, libm_powi_f64: { pop_values: [value : Float64, power : Int32], push: true, code: LibM.powi_f64(value, power), }, libm_min_f32: { pop_values: [value1 : Float32, value2 : Float32], push: true, code: LibM.min_f32(value1, value2), }, libm_min_f64: { pop_values: [value1 : Float64, value2 : Float64], push: true, code: LibM.min_f64(value1, value2), }, libm_max_f32: { pop_values: [value1 : Float32, value2 : Float32], push: true, code: LibM.max_f32(value1, value2), }, libm_max_f64: { pop_values: [value1 : Float64, value2 : Float64], push: true, code: LibM.max_f64(value1, value2), }, libm_pow_f32: { pop_values: [value : Float32, power : Float32], push: true, code: LibM.pow_f32(value, power), }, libm_pow_f64: { pop_values: [value : Float64, power : Float64], push: true, code: LibM.pow_f64(value, power), }, libm_copysign_f32: { pop_values: [magnitude : Float32, sign : Float32], push: true, code: LibM.copysign_f32(magnitude, sign), }, libm_copysign_f64: { pop_values: [magnitude : Float64, sign : Float64], push: true, code: LibM.copysign_f64(magnitude, sign), }, unreachable: { operands: [message : String], code: raise(message), }, }
Constructors
Instance Method Summary
- #context : Context
- #load_prelude
- #parse_and_interpret(expression : String) : EvalResult
- #prelude : String
- #prelude=(prelude : String)
- #program : Program
- #run
- #run_code(code, argv = [] of String)
- #run_file(filename, argv)
Instance methods inherited from class Reference
==(other : self)==(other : JSON::Any)
==(other : YAML::Any)
==(other) ==, dup dup, hash(hasher) hash, initialize initialize, inspect(io : IO) : Nil inspect, object_id : UInt64 object_id, pretty_print(pp) : Nil pretty_print, same?(other : Reference) : Bool
same?(other : Nil) same?, to_s(io : IO) : Nil to_s
Constructor methods inherited from class Reference
new
new,
unsafe_construct(address : Pointer, *args, **opts) : self
unsafe_construct
Class methods inherited from class Reference
pre_initialize(address : Pointer)
pre_initialize
Instance methods inherited from class Object
! : Bool
!,
!=(other)
!=,
!~(other)
!~,
==(other)
==,
===(other : JSON::Any)===(other : YAML::Any)
===(other) ===, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash hash, in?(collection : Object) : Bool
in?(*values : Object) : Bool in?, inspect(io : IO) : Nil
inspect : String inspect, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String to_json, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil to_pretty_json, to_s(io : IO) : Nil
to_s : String to_s, to_yaml(io : IO) : Nil
to_yaml : String to_yaml, try(&) try, unsafe_as(type : T.class) forall T unsafe_as
Class methods inherited from class Object
from_json(string_or_io : String | IO, root : String)from_json(string_or_io : String | IO) from_json, from_yaml(string_or_io : String | IO) from_yaml