mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-19 08:32:33 +00:00
Minor changes
This commit is contained in:
@@ -78,7 +78,6 @@ decode_one :: proc(
|
||||
return
|
||||
}
|
||||
|
||||
// --- opcode (and optional misc sub-opcode) ------------------------------
|
||||
b0 := data[off]
|
||||
off += 1
|
||||
|
||||
@@ -111,7 +110,6 @@ decode_one :: proc(
|
||||
inst.mnemonic = m
|
||||
inst.flags = {}
|
||||
|
||||
// --- immediates ---------------------------------------------------------
|
||||
slot := 0
|
||||
for k, ki in form.imm {
|
||||
switch k {
|
||||
@@ -120,37 +118,39 @@ decode_one :: proc(
|
||||
|
||||
case .BLOCKTYPE:
|
||||
v := read_sleb(data, &off) or_return
|
||||
inst.ops[slot] = Operand{immediate = v, kind = .BLOCK_TYPE}
|
||||
inst.ops[slot] = Operand{kind = .BLOCK_TYPE, immediate = v}
|
||||
slot += 1
|
||||
|
||||
case .I32:
|
||||
v := read_sleb(data, &off) or_return
|
||||
inst.ops[slot] = Operand{immediate = v, kind = .IMMEDIATE, size = 4}
|
||||
inst.ops[slot] = Operand{kind = .IMMEDIATE, immediate = v, size = 4}
|
||||
slot += 1
|
||||
|
||||
case .I64:
|
||||
v := read_sleb(data, &off) or_return
|
||||
inst.ops[slot] = Operand{immediate = v, kind = .IMMEDIATE, size = 8}
|
||||
inst.ops[slot] = Operand{kind = .IMMEDIATE, immediate = v, size = 8}
|
||||
slot += 1
|
||||
|
||||
case .F32:
|
||||
bits := read_u32le(data, &off) or_return
|
||||
bits := read_u32_block(data, &off) or_return
|
||||
inst.ops[slot] = Operand{
|
||||
immediate = i64(bits), kind = .IMMEDIATE, size = 4, flags = {is_float = true},
|
||||
kind = .IMMEDIATE,
|
||||
immediate = i64(bits), size = 4, flags = {is_float = true},
|
||||
}
|
||||
slot += 1
|
||||
|
||||
case .F64:
|
||||
bits := read_u64le(data, &off) or_return
|
||||
bits := read_u64_block(data, &off) or_return
|
||||
inst.ops[slot] = Operand{
|
||||
immediate = i64(bits), kind = .IMMEDIATE, size = 8, flags = {is_float = true},
|
||||
kind = .IMMEDIATE,
|
||||
immediate = i64(bits), size = 8, flags = {is_float = true},
|
||||
}
|
||||
slot += 1
|
||||
|
||||
case .IDX:
|
||||
field := off
|
||||
raw := read_uleb(data, &off) or_return
|
||||
op := Operand{index = u32(raw), kind = .INDEX, idx_kind = idx_kind_for(m, ki)}
|
||||
op := Operand{kind = .INDEX, index = u32(raw), idx_kind = idx_kind_for(m, ki)}
|
||||
if lid, found := reloc_label_at(relocs, field); found {
|
||||
op.index = lid
|
||||
op.flags.symbolic = true
|
||||
@@ -162,9 +162,11 @@ decode_one :: proc(
|
||||
slot += 1
|
||||
|
||||
case .MEMARG:
|
||||
// TODO(bill): Is this fully correct?
|
||||
// See: https://webassembly.github.io/spec/core/binary/instructions.html#memory-instructions
|
||||
align := read_uleb(data, &off) or_return
|
||||
offset := read_uleb(data, &off) or_return
|
||||
inst.ops[slot] = Operand{memarg = Memarg{align = u32(align), offset = u32(offset)}, kind = .MEMARG}
|
||||
inst.ops[slot] = Operand{kind = .MEMARG, memarg = Memarg{align = u32(align), offset = u32(offset)}}
|
||||
slot += 1
|
||||
|
||||
case .REFTYPE:
|
||||
@@ -174,7 +176,7 @@ decode_one :: proc(
|
||||
}
|
||||
t := data[off]
|
||||
off += 1
|
||||
inst.ops[slot] = Operand{immediate = i64(t), kind = .IMMEDIATE, size = 1}
|
||||
inst.ops[slot] = Operand{kind = .IMMEDIATE, immediate = i64(t), size = 1}
|
||||
slot += 1
|
||||
|
||||
case .BR_TABLE:
|
||||
@@ -186,7 +188,7 @@ decode_one :: proc(
|
||||
}
|
||||
def := read_uleb(data, &off) or_return
|
||||
inst.targets = targets
|
||||
inst.ops[slot] = Operand{index = u32(def), kind = .INDEX, idx_kind = .LABEL}
|
||||
inst.ops[slot] = Operand{kind = .INDEX, index = u32(def), idx_kind = .LABEL}
|
||||
slot += 1
|
||||
|
||||
case .ZERO_BYTE:
|
||||
@@ -194,7 +196,7 @@ decode_one :: proc(
|
||||
next = pc
|
||||
return
|
||||
}
|
||||
off += 1 // reserved 0x00, consumes no operand
|
||||
off += 1 // reserved 0x00, consumes no operand
|
||||
|
||||
case .LANE:
|
||||
if off >= u32(len(data)) {
|
||||
@@ -203,7 +205,7 @@ decode_one :: proc(
|
||||
}
|
||||
l := data[off]
|
||||
off += 1
|
||||
inst.ops[slot] = Operand{immediate = i64(l), kind = .IMMEDIATE, size = 1}
|
||||
inst.ops[slot] = Operand{kind = .IMMEDIATE, immediate = i64(l), size = 1}
|
||||
slot += 1
|
||||
|
||||
case .LANES16:
|
||||
@@ -211,8 +213,8 @@ decode_one :: proc(
|
||||
next = pc
|
||||
return
|
||||
}
|
||||
copy(inst.bytes[:], data[off:off + 16])
|
||||
off += 16 // value lives in inst.bytes, no operand
|
||||
copy(inst.bytes[:], data[off:][:16])
|
||||
off += 16 // value lives in inst.bytes, no operand
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,11 +233,11 @@ idx_kind_for :: #force_inline proc "contextless" (m: Mnemonic, which: int) -> In
|
||||
#partial switch m {
|
||||
case .BR, .BR_IF: return .LABEL
|
||||
case .CALL, .REF_FUNC: return .FUNC
|
||||
case .CALL_INDIRECT: return which == 0 ? .TYPE : .TABLE
|
||||
case .CALL_INDIRECT: return .TYPE if which == 0 else .TABLE
|
||||
case .LOCAL_GET, .LOCAL_SET, .LOCAL_TEE: return .LOCAL
|
||||
case .GLOBAL_GET, .GLOBAL_SET: return .GLOBAL
|
||||
case .MEMORY_INIT, .DATA_DROP: return .DATA
|
||||
case .TABLE_INIT: return which == 0 ? .ELEM : .TABLE
|
||||
case .TABLE_INIT: return .ELEM if which == 0 else .TABLE
|
||||
case .ELEM_DROP: return .ELEM
|
||||
case .TABLE_COPY: return .TABLE
|
||||
case .TABLE_GROW, .TABLE_SIZE, .TABLE_FILL: return .TABLE
|
||||
|
||||
@@ -54,7 +54,7 @@ encode :: proc(
|
||||
}
|
||||
|
||||
|
||||
encode_one :: #force_inline proc(
|
||||
encode_one :: proc(
|
||||
inst: ^Instruction,
|
||||
pc: u32,
|
||||
inst_idx: u16,
|
||||
@@ -96,10 +96,10 @@ encode_one :: #force_inline proc(
|
||||
write_sleb(code, &off, inst.ops[opi].immediate)
|
||||
opi += 1
|
||||
case .F32:
|
||||
write_u32le(code, &off, u32(inst.ops[opi].immediate))
|
||||
write_u32_block(code, &off, u32(inst.ops[opi].immediate))
|
||||
opi += 1
|
||||
case .F64:
|
||||
write_u64le(code, &off, u64(inst.ops[opi].immediate))
|
||||
write_u64_block(code, &off, u64(inst.ops[opi].immediate))
|
||||
opi += 1
|
||||
case .IDX:
|
||||
op := &inst.ops[opi]
|
||||
|
||||
@@ -146,6 +146,7 @@ sleb_size :: #force_inline proc "contextless" (value: i64) -> u32 {
|
||||
|
||||
// Read unsigned LEB128 starting at `*offset`; advances it. `ok` is false on
|
||||
// truncation. Reads at most `max` bytes (10 covers u64).
|
||||
@(require_results)
|
||||
read_uleb :: #force_inline proc "contextless" (data: []u8, offset: ^u32) -> (value: u64, ok: bool) {
|
||||
shift: uint = 0
|
||||
for i := 0; i < 10 && offset^ < u32(len(data)); i += 1 {
|
||||
@@ -161,6 +162,7 @@ read_uleb :: #force_inline proc "contextless" (data: []u8, offset: ^u32) -> (val
|
||||
}
|
||||
|
||||
// Read signed LEB128 starting at `*offset`; advances it.
|
||||
@(require_results)
|
||||
read_sleb :: #force_inline proc "contextless" (data: []u8, offset: ^u32) -> (value: i64, ok: bool) {
|
||||
shift: uint = 0
|
||||
b: u8 = 0
|
||||
@@ -180,7 +182,7 @@ read_sleb :: #force_inline proc "contextless" (data: []u8, offset: ^u32) -> (val
|
||||
return
|
||||
}
|
||||
|
||||
write_u32le :: #force_inline proc(code: []u8, offset: ^u32, v: u32) {
|
||||
write_u32_block :: #force_inline proc(code: []u8, offset: ^u32, v: u32) {
|
||||
assert(offset^+ 4 <= u32(len(code)))
|
||||
code[offset^+0] = u8(v)
|
||||
code[offset^+1] = u8(v >> 8)
|
||||
@@ -189,7 +191,7 @@ write_u32le :: #force_inline proc(code: []u8, offset: ^u32, v: u32) {
|
||||
offset^ += 4
|
||||
}
|
||||
|
||||
write_u64le :: #force_inline proc(code: []u8, offset: ^u32, v: u64) {
|
||||
write_u64_block :: #force_inline proc(code: []u8, offset: ^u32, v: u64) {
|
||||
assert(offset^+ 8 <= u32(len(code)))
|
||||
for i in u32(0)..<8 {
|
||||
code[offset^+i] = u8(v >> (8 * i))
|
||||
@@ -197,7 +199,8 @@ write_u64le :: #force_inline proc(code: []u8, offset: ^u32, v: u64) {
|
||||
offset^ += 8
|
||||
}
|
||||
|
||||
read_u32le :: #force_inline proc "contextless" (data: []u8, offset: ^u32) -> (u32, bool) {
|
||||
@(require_results)
|
||||
read_u32_block :: #force_inline proc "contextless" (data: []u8, offset: ^u32) -> (u32, bool) {
|
||||
if offset^ + 4 > u32(len(data)) {
|
||||
return 0, false
|
||||
}
|
||||
@@ -209,7 +212,8 @@ read_u32le :: #force_inline proc "contextless" (data: []u8, offset: ^u32) -> (u3
|
||||
return v, true
|
||||
}
|
||||
|
||||
read_u64le :: #force_inline proc "contextless" (data: []u8, offset: ^u32) -> (u64, bool) {
|
||||
@(require_results)
|
||||
read_u64_block :: #force_inline proc "contextless" (data: []u8, offset: ^u32) -> (u64, bool) {
|
||||
if offset^ + 8 > u32(len(data)) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user