selfhost/cmd/w6a: strip *arena cascade (γ-3)
amalloc has 0 callers post-γ-2; the *arena threaded through w6a's init/dupstr/bufinit and the asm_.a / buf.a fields are vestigial. Drop `import mem;` from opcodes/parse/obj/main, remove asm_.a and buf.a struct fields, strip *arena from init/dupstr/bufinit signatures, update 12 call sites. main.combined.ww auto-regenerated. Comment at main.ww:36 retidied "argv/arena" → "argv-style" to match post-strip reality. Verified 132/132 incl. 991_w6a_ww + 995_self_rebuild byte-identity.
This commit is contained in:
@@ -750,98 +750,6 @@ package rt;
|
||||
// a future task (task #39). ref/hare/rt/malloc.ha:27.
|
||||
@symbol("rt_malloc") export fn malloc(n: u64) *void;
|
||||
|
||||
// selfhost/cmd/wcc/mem.ww — port of cmd/wcc/mem.c.
|
||||
//
|
||||
// Bump arena allocator. Backed by the runtime page allocator
|
||||
// (rt_malloc / rt_free), no libc. Each chunk is mmap'd; when the
|
||||
// current chunk runs out we link a fresh one. Freeing the arena
|
||||
// unmaps the chain.
|
||||
//
|
||||
// Memory handed out is 16-byte aligned. The C version under
|
||||
// cmd/wcc/ is retained until the three-stage bootstrap diffs clean.
|
||||
|
||||
package wcc;
|
||||
|
||||
import os;
|
||||
import rt;
|
||||
|
||||
def ALIGN: u64 = 16u64;
|
||||
def INIT_CHUNK: u64 = 65536u64;
|
||||
def MAX_CHUNK: u64 = 4194304u64;
|
||||
def ARENA_SZ: u64 = 48u64; // sizeof(arena), kept in sync below
|
||||
|
||||
type arena = struct {
|
||||
buf: *u8,
|
||||
off: u64,
|
||||
cap: u64,
|
||||
next: *arena,
|
||||
total: u64,
|
||||
};
|
||||
|
||||
fn roundup(n: u64, a: u64) u64 = {
|
||||
return (n + a - 1u64) & ~(a - 1u64);
|
||||
};
|
||||
|
||||
export fn newarena() *arena = {
|
||||
let a: *arena = rt.malloc(ARENA_SZ): *arena;
|
||||
a.buf = rt.malloc(INIT_CHUNK): *u8;
|
||||
a.off = 0u64;
|
||||
a.cap = INIT_CHUNK;
|
||||
a.next = nil;
|
||||
a.total = 0u64;
|
||||
return a;
|
||||
};
|
||||
|
||||
// Grow: link a fresh chunk in front of the head. We push the old
|
||||
// chunk into `next` so the head always describes the current bump
|
||||
// region. Chunk size doubles up to MAX_CHUNK.
|
||||
fn grow(a: *arena, need: u64) bool = {
|
||||
let want: u64 = a.cap * 2u64;
|
||||
if (want < need) { want = need; };
|
||||
if (want > MAX_CHUNK) { want = MAX_CHUNK; };
|
||||
if (want < need) { return false; }; // single allocation too big
|
||||
|
||||
let old: *arena = rt.malloc(ARENA_SZ): *arena;
|
||||
old.buf = a.buf;
|
||||
old.off = a.off;
|
||||
old.cap = a.cap;
|
||||
old.next = a.next;
|
||||
old.total = 0u64;
|
||||
|
||||
a.buf = rt.malloc(want): *u8;
|
||||
a.off = 0u64;
|
||||
a.cap = want;
|
||||
a.next = old;
|
||||
return true;
|
||||
};
|
||||
|
||||
export fn amalloc(a: *arena, n: u64) *void = {
|
||||
let need: u64 = roundup(n, ALIGN);
|
||||
if (need > a.cap - a.off) {
|
||||
if (!grow(a, need)) { return nil; };
|
||||
};
|
||||
let p: *u8 = a.buf + a.off;
|
||||
a.off += need;
|
||||
a.total += need;
|
||||
// Zero the region. Plan 9 amalloc zeroes; we mirror that here so
|
||||
// the checker can assume freshly allocated nodes start at 0.
|
||||
let i: u64 = 0u64;
|
||||
for (i < need) {
|
||||
p[i] = 0u8;
|
||||
i += 1u64;
|
||||
};
|
||||
return p: *void;
|
||||
};
|
||||
|
||||
export fn freearena(a: *arena) void = {
|
||||
for (a != nil) {
|
||||
let next: *arena = a.next;
|
||||
os.free(a.buf: *void, a.cap);
|
||||
os.free(a: *void, ARENA_SZ);
|
||||
a = next;
|
||||
};
|
||||
};
|
||||
|
||||
// types — integer limits. Mirrors Hare's types::limits (I8_MAX, …)
|
||||
// platform-fixed for amd64. Numeric helpers live in lib/math, matching
|
||||
// Hare's split between types::limits and math::.
|
||||
@@ -2778,8 +2686,6 @@ export fn rpad(s: str, p: rune, maxlen: i32) str = {
|
||||
|
||||
package w6a;
|
||||
|
||||
import mem;
|
||||
|
||||
// ---- registers + operand kinds (from 6.out.h) -------------------------
|
||||
// These must stay numerically aligned with the C enum so that ww-cgen
|
||||
// output (which reads them via `D_AX(SB)` etc.) lands on the same
|
||||
@@ -2965,7 +2871,6 @@ type afixup = struct {
|
||||
};
|
||||
|
||||
type asm_ = struct {
|
||||
a: *arena,
|
||||
file: str,
|
||||
src: *u8,
|
||||
srclen: u64,
|
||||
@@ -3078,7 +2983,6 @@ export fn parsenum(p: *u8, n: u64) (i64, u64) = {
|
||||
package w6a;
|
||||
|
||||
import os;
|
||||
import mem;
|
||||
import strings;
|
||||
import lex;
|
||||
import opcodes;
|
||||
@@ -3203,8 +3107,7 @@ fn reglookup(p: *u8, n: u64) i32 = {
|
||||
return D_NONE;
|
||||
};
|
||||
|
||||
export fn init(a: *asm_, ar: *arena, file: str, src: *u8, len: u64) void = {
|
||||
a.a = ar;
|
||||
export fn init(a: *asm_, file: str, src: *u8, len: u64) void = {
|
||||
a.file = file;
|
||||
a.src = src;
|
||||
a.srclen = len;
|
||||
@@ -3245,7 +3148,7 @@ fn perr(a: *asm_, msg: str) void = {
|
||||
};
|
||||
|
||||
// dupstr — copy n bytes from p into a fresh heap str.
|
||||
fn dupstr(a: *arena, p: *u8, n: u64) str = {
|
||||
fn dupstr(p: *u8, n: u64) str = {
|
||||
let view: str;
|
||||
view.ptr = p;
|
||||
view.len = n: i32;
|
||||
@@ -3397,7 +3300,7 @@ fn parseoperand(a: *asm_, p: *u8, offin: u64, n: u64, out: *aoperand) u64 = {
|
||||
let r: i32 = reglookup(p + rstart, rn);
|
||||
if (r == D_PSB) {
|
||||
out.atype = D_EXTERN;
|
||||
out.asym = dupstr(a.a, p + istart, in_);
|
||||
out.asym = dupstr(p + istart, in_);
|
||||
out.offset = symdisp;
|
||||
} else {
|
||||
out.atype = D_INDIR;
|
||||
@@ -3415,7 +3318,7 @@ fn parseoperand(a: *asm_, p: *u8, offin: u64, n: u64, out: *aoperand) u64 = {
|
||||
return off;
|
||||
};
|
||||
out.atype = D_BRANCH;
|
||||
out.asym = dupstr(a.a, p + istart, in_);
|
||||
out.asym = dupstr(p + istart, in_);
|
||||
return off;
|
||||
};
|
||||
// EOF inside ident
|
||||
@@ -3423,7 +3326,7 @@ fn parseoperand(a: *asm_, p: *u8, offin: u64, n: u64, out: *aoperand) u64 = {
|
||||
let r: i32 = reglookup(p + istart, in_);
|
||||
if (r != D_NONE) { out.atype = r; return off; };
|
||||
out.atype = D_BRANCH;
|
||||
out.asym = dupstr(a.a, p + istart, in_);
|
||||
out.asym = dupstr(p + istart, in_);
|
||||
return off;
|
||||
};
|
||||
|
||||
@@ -3476,7 +3379,7 @@ export fn parse(a: *asm_) i32 = {
|
||||
else { scanid = false; }; };
|
||||
};
|
||||
if (q < n) { if (line[q] == 58u8) { // ':'
|
||||
let nm: str = dupstr(a.a, line + i, q - i);
|
||||
let nm: str = dupstr(line + i, q - i);
|
||||
// Pending label gets a NOP prog so addresses pin.
|
||||
if (pending.len > 0) {
|
||||
let np: *aprog = addprog(a, A_NOP, pending);
|
||||
@@ -3527,7 +3430,7 @@ export fn parse(a: *asm_) i32 = {
|
||||
};
|
||||
let toop: *aoperand = pr.to;
|
||||
toop.atype = D_EXTERN;
|
||||
toop.asym = dupstr(a.a, line + r0, commapos - r0);
|
||||
toop.asym = dupstr(line + r0, commapos - r0);
|
||||
if (commapos < n) {
|
||||
let p2: u64 = commapos + 1u64;
|
||||
p2 = skipws(line, p2, n);
|
||||
@@ -3555,7 +3458,7 @@ export fn parse(a: *asm_) i32 = {
|
||||
};
|
||||
let toop: *aoperand = pr.to;
|
||||
toop.atype = D_EXTERN;
|
||||
toop.asym = dupstr(a.a, line + r0, lparen - r0);
|
||||
toop.asym = dupstr(line + r0, lparen - r0);
|
||||
// Skip past `(SB)` to land just after ')'.
|
||||
let p2: u64 = lparen;
|
||||
let scand2: bool = true;
|
||||
@@ -3652,6 +3555,98 @@ export fn parse(a: *asm_) i32 = {
|
||||
return a.errs;
|
||||
};
|
||||
|
||||
// selfhost/cmd/wcc/mem.ww — port of cmd/wcc/mem.c.
|
||||
//
|
||||
// Bump arena allocator. Backed by the runtime page allocator
|
||||
// (rt_malloc / rt_free), no libc. Each chunk is mmap'd; when the
|
||||
// current chunk runs out we link a fresh one. Freeing the arena
|
||||
// unmaps the chain.
|
||||
//
|
||||
// Memory handed out is 16-byte aligned. The C version under
|
||||
// cmd/wcc/ is retained until the three-stage bootstrap diffs clean.
|
||||
|
||||
package wcc;
|
||||
|
||||
import os;
|
||||
import rt;
|
||||
|
||||
def ALIGN: u64 = 16u64;
|
||||
def INIT_CHUNK: u64 = 65536u64;
|
||||
def MAX_CHUNK: u64 = 4194304u64;
|
||||
def ARENA_SZ: u64 = 48u64; // sizeof(arena), kept in sync below
|
||||
|
||||
type arena = struct {
|
||||
buf: *u8,
|
||||
off: u64,
|
||||
cap: u64,
|
||||
next: *arena,
|
||||
total: u64,
|
||||
};
|
||||
|
||||
fn roundup(n: u64, a: u64) u64 = {
|
||||
return (n + a - 1u64) & ~(a - 1u64);
|
||||
};
|
||||
|
||||
export fn newarena() *arena = {
|
||||
let a: *arena = rt.malloc(ARENA_SZ): *arena;
|
||||
a.buf = rt.malloc(INIT_CHUNK): *u8;
|
||||
a.off = 0u64;
|
||||
a.cap = INIT_CHUNK;
|
||||
a.next = nil;
|
||||
a.total = 0u64;
|
||||
return a;
|
||||
};
|
||||
|
||||
// Grow: link a fresh chunk in front of the head. We push the old
|
||||
// chunk into `next` so the head always describes the current bump
|
||||
// region. Chunk size doubles up to MAX_CHUNK.
|
||||
fn grow(a: *arena, need: u64) bool = {
|
||||
let want: u64 = a.cap * 2u64;
|
||||
if (want < need) { want = need; };
|
||||
if (want > MAX_CHUNK) { want = MAX_CHUNK; };
|
||||
if (want < need) { return false; }; // single allocation too big
|
||||
|
||||
let old: *arena = rt.malloc(ARENA_SZ): *arena;
|
||||
old.buf = a.buf;
|
||||
old.off = a.off;
|
||||
old.cap = a.cap;
|
||||
old.next = a.next;
|
||||
old.total = 0u64;
|
||||
|
||||
a.buf = rt.malloc(want): *u8;
|
||||
a.off = 0u64;
|
||||
a.cap = want;
|
||||
a.next = old;
|
||||
return true;
|
||||
};
|
||||
|
||||
export fn amalloc(a: *arena, n: u64) *void = {
|
||||
let need: u64 = roundup(n, ALIGN);
|
||||
if (need > a.cap - a.off) {
|
||||
if (!grow(a, need)) { return nil; };
|
||||
};
|
||||
let p: *u8 = a.buf + a.off;
|
||||
a.off += need;
|
||||
a.total += need;
|
||||
// Zero the region. Plan 9 amalloc zeroes; we mirror that here so
|
||||
// the checker can assume freshly allocated nodes start at 0.
|
||||
let i: u64 = 0u64;
|
||||
for (i < need) {
|
||||
p[i] = 0u8;
|
||||
i += 1u64;
|
||||
};
|
||||
return p: *void;
|
||||
};
|
||||
|
||||
export fn freearena(a: *arena) void = {
|
||||
for (a != nil) {
|
||||
let next: *arena = a.next;
|
||||
os.free(a.buf: *void, a.cap);
|
||||
os.free(a: *void, ARENA_SZ);
|
||||
a = next;
|
||||
};
|
||||
};
|
||||
|
||||
// selfhost/cmd/w6a/asm.ww — port of cmd/w6a/asm.c.
|
||||
//
|
||||
// Encode the parsed aprog list into amd64 machine bytes, appending to
|
||||
@@ -4521,7 +4516,6 @@ export fn encode(a: *asm_) i32 = {
|
||||
package w6a;
|
||||
|
||||
import os;
|
||||
import mem;
|
||||
import opcodes;
|
||||
|
||||
// Local wrappers around os.writeall's tagged return — collapse the
|
||||
@@ -4594,14 +4588,12 @@ fn wru64(p: *u8, off: u64, v: u64) void = {
|
||||
// ---- growable byte buffer ---------------------------------------------
|
||||
|
||||
type buf = struct {
|
||||
a: *arena,
|
||||
p: *u8,
|
||||
n: u64,
|
||||
cap: u64,
|
||||
};
|
||||
|
||||
fn bufinit(b: *buf, a: *arena) void = {
|
||||
b.a = a;
|
||||
fn bufinit(b: *buf) void = {
|
||||
b.cap = 256u64;
|
||||
b.n = 0u64;
|
||||
let np: []u8 = alloc([], b.cap)!;
|
||||
@@ -4641,11 +4633,11 @@ fn bufputcstr(b: *buf, s: str) u32 = {
|
||||
// ---- emitelf ---------------------------------------------------------
|
||||
|
||||
export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
let shstr: buf; bufinit(&shstr, a.a);
|
||||
let str_: buf; bufinit(&str_, a.a);
|
||||
let sym: buf; bufinit(&sym, a.a);
|
||||
let rela: buf; bufinit(&rela, a.a);
|
||||
let relad: buf; bufinit(&relad, a.a);
|
||||
let shstr: buf; bufinit(&shstr);
|
||||
let str_: buf; bufinit(&str_);
|
||||
let sym: buf; bufinit(&sym);
|
||||
let rela: buf; bufinit(&rela);
|
||||
let relad: buf; bufinit(&relad);
|
||||
|
||||
// Index 0 = empty.
|
||||
let zero: u8 = 0u8;
|
||||
@@ -4931,7 +4923,6 @@ package main;
|
||||
|
||||
import os;
|
||||
import rt;
|
||||
import mem;
|
||||
import strings;
|
||||
import opcodes;
|
||||
import lex;
|
||||
@@ -4957,7 +4948,7 @@ fn cstrlen(p: *u8) u64 = {
|
||||
return n;
|
||||
};
|
||||
|
||||
// pathstr — view a NUL-terminated *u8 as a str. Bridges argv/arena
|
||||
// pathstr — view a NUL-terminated *u8 as a str. Bridges argv-style
|
||||
// callers to lib/os entrypoints (str post-task-#23).
|
||||
fn pathstr(p: *u8) str = {
|
||||
let r: str;
|
||||
@@ -5035,14 +5026,13 @@ export fn main(argc: i32, argv: **u8) i32 = {
|
||||
return 1;
|
||||
};
|
||||
|
||||
let ar: *arena = newarena();
|
||||
let s: asm_;
|
||||
let nlen: u64 = cstrlen(src);
|
||||
let view: str;
|
||||
view.ptr = src;
|
||||
view.len = nlen: i32;
|
||||
let fname: str = strings.dup(view);
|
||||
init(&s, ar, fname, buf, blen);
|
||||
init(&s, fname, buf, blen);
|
||||
|
||||
if (parse(&s) != 0) { return 1; };
|
||||
if (encode(&s) != 0) { return 1; };
|
||||
|
||||
@@ -8,7 +8,6 @@ package main;
|
||||
|
||||
import os;
|
||||
import rt;
|
||||
import mem;
|
||||
import strings;
|
||||
import opcodes;
|
||||
import lex;
|
||||
@@ -34,7 +33,7 @@ fn cstrlen(p: *u8) u64 = {
|
||||
return n;
|
||||
};
|
||||
|
||||
// pathstr — view a NUL-terminated *u8 as a str. Bridges argv/arena
|
||||
// pathstr — view a NUL-terminated *u8 as a str. Bridges argv-style
|
||||
// callers to lib/os entrypoints (str post-task-#23).
|
||||
fn pathstr(p: *u8) str = {
|
||||
let r: str;
|
||||
@@ -112,14 +111,13 @@ export fn main(argc: i32, argv: **u8) i32 = {
|
||||
return 1;
|
||||
};
|
||||
|
||||
let ar: *arena = newarena();
|
||||
let s: asm_;
|
||||
let nlen: u64 = cstrlen(src);
|
||||
let view: str;
|
||||
view.ptr = src;
|
||||
view.len = nlen: i32;
|
||||
let fname: str = strings.dup(view);
|
||||
init(&s, ar, fname, buf, blen);
|
||||
init(&s, fname, buf, blen);
|
||||
|
||||
if (parse(&s) != 0) { return 1; };
|
||||
if (encode(&s) != 0) { return 1; };
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
package w6a;
|
||||
|
||||
import os;
|
||||
import mem;
|
||||
import opcodes;
|
||||
|
||||
// Local wrappers around os.writeall's tagged return — collapse the
|
||||
@@ -87,14 +86,12 @@ fn wru64(p: *u8, off: u64, v: u64) void = {
|
||||
// ---- growable byte buffer ---------------------------------------------
|
||||
|
||||
type buf = struct {
|
||||
a: *arena,
|
||||
p: *u8,
|
||||
n: u64,
|
||||
cap: u64,
|
||||
};
|
||||
|
||||
fn bufinit(b: *buf, a: *arena) void = {
|
||||
b.a = a;
|
||||
fn bufinit(b: *buf) void = {
|
||||
b.cap = 256u64;
|
||||
b.n = 0u64;
|
||||
let np: []u8 = alloc([], b.cap)!;
|
||||
@@ -134,11 +131,11 @@ fn bufputcstr(b: *buf, s: str) u32 = {
|
||||
// ---- emitelf ---------------------------------------------------------
|
||||
|
||||
export fn emitelf(a: *asm_, fd: i32) i32 = {
|
||||
let shstr: buf; bufinit(&shstr, a.a);
|
||||
let str_: buf; bufinit(&str_, a.a);
|
||||
let sym: buf; bufinit(&sym, a.a);
|
||||
let rela: buf; bufinit(&rela, a.a);
|
||||
let relad: buf; bufinit(&relad, a.a);
|
||||
let shstr: buf; bufinit(&shstr);
|
||||
let str_: buf; bufinit(&str_);
|
||||
let sym: buf; bufinit(&sym);
|
||||
let rela: buf; bufinit(&rela);
|
||||
let relad: buf; bufinit(&relad);
|
||||
|
||||
// Index 0 = empty.
|
||||
let zero: u8 = 0u8;
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
package w6a;
|
||||
|
||||
import mem;
|
||||
|
||||
// ---- registers + operand kinds (from 6.out.h) -------------------------
|
||||
// These must stay numerically aligned with the C enum so that ww-cgen
|
||||
// output (which reads them via `D_AX(SB)` etc.) lands on the same
|
||||
@@ -190,7 +188,6 @@ type afixup = struct {
|
||||
};
|
||||
|
||||
type asm_ = struct {
|
||||
a: *arena,
|
||||
file: str,
|
||||
src: *u8,
|
||||
srclen: u64,
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
package w6a;
|
||||
|
||||
import os;
|
||||
import mem;
|
||||
import strings;
|
||||
import lex;
|
||||
import opcodes;
|
||||
@@ -138,8 +137,7 @@ fn reglookup(p: *u8, n: u64) i32 = {
|
||||
return D_NONE;
|
||||
};
|
||||
|
||||
export fn init(a: *asm_, ar: *arena, file: str, src: *u8, len: u64) void = {
|
||||
a.a = ar;
|
||||
export fn init(a: *asm_, file: str, src: *u8, len: u64) void = {
|
||||
a.file = file;
|
||||
a.src = src;
|
||||
a.srclen = len;
|
||||
@@ -180,7 +178,7 @@ fn perr(a: *asm_, msg: str) void = {
|
||||
};
|
||||
|
||||
// dupstr — copy n bytes from p into a fresh heap str.
|
||||
fn dupstr(a: *arena, p: *u8, n: u64) str = {
|
||||
fn dupstr(p: *u8, n: u64) str = {
|
||||
let view: str;
|
||||
view.ptr = p;
|
||||
view.len = n: i32;
|
||||
@@ -332,7 +330,7 @@ fn parseoperand(a: *asm_, p: *u8, offin: u64, n: u64, out: *aoperand) u64 = {
|
||||
let r: i32 = reglookup(p + rstart, rn);
|
||||
if (r == D_PSB) {
|
||||
out.atype = D_EXTERN;
|
||||
out.asym = dupstr(a.a, p + istart, in_);
|
||||
out.asym = dupstr(p + istart, in_);
|
||||
out.offset = symdisp;
|
||||
} else {
|
||||
out.atype = D_INDIR;
|
||||
@@ -350,7 +348,7 @@ fn parseoperand(a: *asm_, p: *u8, offin: u64, n: u64, out: *aoperand) u64 = {
|
||||
return off;
|
||||
};
|
||||
out.atype = D_BRANCH;
|
||||
out.asym = dupstr(a.a, p + istart, in_);
|
||||
out.asym = dupstr(p + istart, in_);
|
||||
return off;
|
||||
};
|
||||
// EOF inside ident
|
||||
@@ -358,7 +356,7 @@ fn parseoperand(a: *asm_, p: *u8, offin: u64, n: u64, out: *aoperand) u64 = {
|
||||
let r: i32 = reglookup(p + istart, in_);
|
||||
if (r != D_NONE) { out.atype = r; return off; };
|
||||
out.atype = D_BRANCH;
|
||||
out.asym = dupstr(a.a, p + istart, in_);
|
||||
out.asym = dupstr(p + istart, in_);
|
||||
return off;
|
||||
};
|
||||
|
||||
@@ -411,7 +409,7 @@ export fn parse(a: *asm_) i32 = {
|
||||
else { scanid = false; }; };
|
||||
};
|
||||
if (q < n) { if (line[q] == 58u8) { // ':'
|
||||
let nm: str = dupstr(a.a, line + i, q - i);
|
||||
let nm: str = dupstr(line + i, q - i);
|
||||
// Pending label gets a NOP prog so addresses pin.
|
||||
if (pending.len > 0) {
|
||||
let np: *aprog = addprog(a, A_NOP, pending);
|
||||
@@ -462,7 +460,7 @@ export fn parse(a: *asm_) i32 = {
|
||||
};
|
||||
let toop: *aoperand = pr.to;
|
||||
toop.atype = D_EXTERN;
|
||||
toop.asym = dupstr(a.a, line + r0, commapos - r0);
|
||||
toop.asym = dupstr(line + r0, commapos - r0);
|
||||
if (commapos < n) {
|
||||
let p2: u64 = commapos + 1u64;
|
||||
p2 = skipws(line, p2, n);
|
||||
@@ -490,7 +488,7 @@ export fn parse(a: *asm_) i32 = {
|
||||
};
|
||||
let toop: *aoperand = pr.to;
|
||||
toop.atype = D_EXTERN;
|
||||
toop.asym = dupstr(a.a, line + r0, lparen - r0);
|
||||
toop.asym = dupstr(line + r0, lparen - r0);
|
||||
// Skip past `(SB)` to land just after ')'.
|
||||
let p2: u64 = lparen;
|
||||
let scand2: bool = true;
|
||||
|
||||
Reference in New Issue
Block a user