Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

so close... #22885

Merged
merged 11 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
progress
  • Loading branch information
Araq committed Oct 31, 2023
commit 083222a42d72924fdfab5ef793f56948f3a6b37a
15 changes: 5 additions & 10 deletions compiler/nir/ast2ir.nim
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,7 @@ proc tempToDest(c: var ProcCon; n: PNode; d: var Value; tmp: Value) =
d = tmp
else:
let info = toLineInfo(c, n.info)
build c.code, info, Asgn:
c.code.addTyped info, typeToIr(c.m, n.typ)
buildTyped c.code, info, Asgn, typeToIr(c.m, n.typ):
c.code.copyTree d
c.code.copyTree tmp
freeTemp(c, tmp)
Expand Down Expand Up @@ -406,8 +405,7 @@ proc genCase(c: var ProcCon; n: PNode; d: var Value) =
let ending = newLabel(c.labelGen)
let info = toLineInfo(c, n.info)
withTemp(tmp, n[0]):
build c.code, info, Select:
c.code.addTyped info, typeToIr(c.m, n[0].typ)
buildTyped c.code, info, Select, typeToIr(c.m, n[0].typ):
c.gen(n[0], tmp)
for i in 1..<n.len:
let section = newLabel(c.labelGen)
Expand All @@ -432,8 +430,7 @@ proc genCase(c: var ProcCon; n: PNode; d: var Value) =
c.code.addLabel info, Label, ending

proc rawCall(c: var ProcCon; info: PackedLineInfo; opc: Opcode; t: TypeId; args: var openArray[Value]) =
build c.code, info, opc:
c.code.addTyped info, t
buildTyped c.code, info, opc, t:
if opc in {CheckedCall, CheckedIndirectCall}:
c.code.addLabel info, CheckedGoto, c.exitLabel
for a in mitems(args):
Expand Down Expand Up @@ -479,8 +476,7 @@ proc genCall(c: var ProcCon; n: PNode; d: var Value) =
if not isEmptyType(n.typ):
if isEmpty(d): d = getTemp(c, n)
# XXX Handle problematic aliasing here: `a = f_canRaise(a)`.
build c.code, info, Asgn:
c.code.addTyped info, tb
buildTyped c.code, info, Asgn, tb:
c.code.copyTree d
rawCall c, info, opc, tb, args
else:
Expand All @@ -492,8 +488,7 @@ proc genRaise(c: var ProcCon; n: PNode) =
let tb = typeToIr(c.m, n[0].typ)

let d = genx(c, n[0])
build c.code, info, SetExc:
c.code.addTyped info, tb
buildTyped c.code, info, SetExc, tb:
c.code.copyTree d
c.freeTemp(d)
c.code.addLabel info, Goto, c.exitLabel
Expand Down
6 changes: 3 additions & 3 deletions compiler/nir/nirinsts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,13 @@ iterator sonsFrom1*(tree: Tree; n: NodePos): NodePos =
yield NodePos pos
nextChild tree, pos

iterator sonsFrom2*(tree: Tree; n: NodePos): NodePos =
iterator sonsFromN*(tree: Tree; n: NodePos; toSkip = 2): NodePos =
var pos = n.int
assert tree.nodes[pos].kind > LastAtomicValue
let last = pos + tree.nodes[pos].rawSpan
inc pos
nextChild tree, pos
nextChild tree, pos
for i in 1..toSkip:
nextChild tree, pos
while pos < last:
yield NodePos pos
nextChild tree, pos
Expand Down
44 changes: 30 additions & 14 deletions compiler/nir/nirvm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ type
CheckedIndexM,

CallM,
CheckedCallM, # call that can raise
CheckedAddM, # with overflow checking etc.
CheckedSubM,
CheckedMulM,
Expand Down Expand Up @@ -609,12 +608,14 @@ proc preprocess(c: var Preprocessing; bc: var Bytecode; t: Tree; n: NodePos; fla
build bc, info, CallM:
preprocess(c, bc, t, src.skipTyped, {WantAddr})
preprocess(c, bc, t, dest, {WantAddr})
for ch in sonsFrom2(t, src): preprocess(c, bc, t, ch, {WantAddr})
for ch in sonsFromN(t, src, 2): preprocess(c, bc, t, ch, {WantAddr})
elif t[src].kind in {CheckedCall, CheckedIndirectCall}:
build bc, info, CheckedCallM:
preprocess(c, bc, t, src.skipTyped, {WantAddr})
let (_, gotoInstr, fn) = sons3(t, src)
build bc, info, CallM:
preprocess(c, bc, t, fn, {WantAddr})
preprocess(c, bc, t, dest, {WantAddr})
for ch in sonsFrom2(t, src): preprocess(c, bc, t, ch, {WantAddr})
for ch in sonsFromN(t, src, 3): preprocess(c, bc, t, ch, {WantAddr})
preprocess c, bc, t, gotoInstr, {}
elif t[dest].kind == Load:
let (typ, a) = sons2(t, dest)
let s = computeSize(bc, tid)[0]
Expand Down Expand Up @@ -642,8 +643,11 @@ proc preprocess(c: var Preprocessing; bc: var Bytecode; t: Tree; n: NodePos; fla
for ch in sonsFrom1(t, n): preprocess(c, bc, t, ch, {WantAddr})
of CheckedCall, CheckedIndirectCall:
# avoid the Typed thing at position 0:
build bc, info, CheckedCallM:
for ch in sonsFrom1(t, n): preprocess(c, bc, t, ch, {WantAddr})
let (_, gotoInstr, fn) = sons3(t, n)
build bc, info, CallM:
preprocess(c, bc, t, fn, {WantAddr})
for ch in sonsFromN(t, n, 3): preprocess(c, bc, t, ch, {WantAddr})
preprocess c, bc, t, gotoInstr, {WantAddr}
of CheckedAdd:
recurse CheckedAddM
of CheckedSub:
Expand Down Expand Up @@ -1052,7 +1056,11 @@ proc echoImpl(c: Bytecode; pc: CodePos; frame: StackFrame) =
stdout.write "\n"
stdout.flushFile()

proc evalBuiltin(c: Bytecode; pc: CodePos; s: StackFrame; prc: CodePos; didEval: var bool): CodePos =
type
EvalBuiltinState = enum
DidNothing, DidEval, DidError

proc evalBuiltin(c: Bytecode; pc: CodePos; s: StackFrame; prc: CodePos; state: var EvalBuiltinState): CodePos =
var prc = prc
while true:
case c[prc].kind
Expand All @@ -1066,7 +1074,7 @@ proc evalBuiltin(c: Bytecode; pc: CodePos; s: StackFrame; prc: CodePos; didEval:
of "echoBinSafe": echoImpl(c, pc, s)
else:
raiseAssert "cannot eval: " & c.m.lit.strings[lit]
didEval = true
state = DidEval
of HeaderImport, DllImport:
let lit = c[y].litId
raiseAssert "cannot eval: " & c.m.lit.strings[lit]
Expand Down Expand Up @@ -1100,10 +1108,15 @@ proc exec(c: Bytecode; pc: CodePos; u: ref Universe) =
assert c.code[prc.firstSon].kind == AllocLocals
let frameSize = int c.code[prc.firstSon].operand
# skip stupid stuff:
var didEval = false
prc = evalBuiltin(c, pc, frame, prc.firstSon, didEval)
if didEval:
var evalState = DidNothing
prc = evalBuiltin(c, pc, frame, prc.firstSon, evalState)
if evalState != DidNothing:
next c, pc
if pc.int < c.code.len and c.code[pc].kind == CheckedGotoM:
if evalState == DidEval:
next c, pc
else:
pc = CodePos(c.code[pc].operand)
else:
# setup storage for the proc already:
let callInstr = pc
Expand All @@ -1121,6 +1134,8 @@ proc exec(c: Bytecode; pc: CodePos; u: ref Universe) =
pc = prc
of RetM:
pc = frame.returnAddr
if c.code[pc].kind == CheckedGotoM:
pc = frame.jumpTo
frame = popStackFrame(frame)
of SelectM:
let pc2 = evalSelect(c, pc, frame)
Expand All @@ -1140,8 +1155,9 @@ proc execCode*(bc: var Bytecode; t: Tree; n: NodePos) =
let start = CodePos(bc.code.len)
var pc = n
while pc.int < t.len:
#echo "RUnning: "
#debug bc, t, pc
#if bc.interactive:
# echo "RUnning: "
# debug bc, t, pc
preprocess c, bc, t, pc, {}
next t, pc
exec bc, start, nil