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

support methods with the VM backend #775

Merged
merged 2 commits into from
Jun 27, 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
9 changes: 4 additions & 5 deletions compiler/vm/vmbackend.nim
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import
lineinfos
],
compiler/backend/[
backends
backends,
cgmeth
],
compiler/front/[
msgs,
Expand Down Expand Up @@ -357,14 +358,12 @@ proc generateCode*(g: ModuleGraph, mlist: sink ModuleList) =
for s in m.structs.threadvars.items:
declareGlobal(s)

generateMethodDispatchers(g)

# generate code for all alive routines
generateAliveProcs(c, mlist)
reset(c.linkState.newProcs) # free the occupied memory already

# XXX: generation of method dispatchers would go here. Note that `method`
# support will require adjustments to DCE handling
#generateMethods(c)

# create procs from the global initializer code fragments
for m in mlist.modules.mitems:
template frag: untyped = m.initGlobalsCode
Expand Down
20 changes: 11 additions & 9 deletions compiler/vm/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ proc genRegLoad(c: var TCtx, n: PNode, dest, src: TRegister)
template isUnset(x: TDest): bool = x < 0


proc realType(s: PSym): PType {.inline.} =
## Returns the signature type of the routine `s`
if s.kind == skMacro: s.internal
else: s.typ

func underlyingLoc(n: PNode): PSym =
## Computes and returns the symbol of the complete location (i.e., a location
## not part of a compound location) that l-value expression `n` names. If no
Expand Down Expand Up @@ -942,7 +947,7 @@ proc writeBackResult(c: var TCtx, info: PNode) =
## If the result value fits into a register but is not stored in one
## (because it has its address taken, etc.), emits the code for storing it
## back into a register. `info` is only used to provide line information.
if resultPos < c.prc.sym.ast.len:
if not isEmptyType(c.prc.sym.realType[0]):
let
res = c.prc.sym.ast[resultPos]
typ = res.typ
Expand Down Expand Up @@ -3011,7 +3016,9 @@ proc gen(c: var TCtx; n: PNode; dest: var TDest) =
let s = n[0].sym
if s.magic != mNone:
genMagic(c, n, dest, s.magic)
elif s.kind == skMethod:
elif s.kind == skMethod and c.mode != emStandalone:
# XXX: detect and reject this earlier -- it's not a code
# generation error
fail(n.info, vmGenDiagCannotCallMethod, sym = s)
else:
genCall(c, n, dest)
Expand Down Expand Up @@ -3180,20 +3187,15 @@ proc genExpr*(c: var TCtx; n: PNode): Result[TRegister, VmGenDiag] =

result = typeof(result).ok(TRegister(d))

proc realType(s: PSym): PType {.inline.} =
## Returns the signature type of the routine `s`
if s.kind == skMacro: s.internal
else: s.typ

proc genParams(prc: PProc; s: PSym) =
let
params = s.realType.n
res = if resultPos < s.ast.len: s.ast[resultPos] else: nil

setLen(prc.regInfo, max(params.len, 1))

if res != nil:
prc.locals[res.sym.id] = 0
if not isEmptyType(s.realType[0]):
prc.locals[s.ast[resultPos].sym.id] = 0
prc.regInfo[0] = RegInfo(refCount: 1, kind: slotFixedVar)

for i in 1..<params.len:
Expand Down
3 changes: 3 additions & 0 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2242,6 +2242,9 @@ when not defined(js):
# Error: system module needs: nimGCvisit
{.pop.} # stackTrace: off, profiler: off

proc chckNilDisp(p: pointer) {.compilerproc.} =
if p.isNil:
sysFatal(NilAccessDefect, "cannot dispatch; dispatcher is nil")


when notJSnotNims:
Expand Down
4 changes: 0 additions & 4 deletions lib/system/chcks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,6 @@ proc chckNil(p: pointer) =
if p == nil:
sysFatal(NilAccessDefect, "attempt to write to a nil address")

proc chckNilDisp(p: pointer) {.compilerproc.} =
if p == nil:
sysFatal(NilAccessDefect, "cannot dispatch; dispatcher is nil")

when defined(nimV2):
proc raiseObjectCaseTransition() {.compilerproc.} =
sysFatal(FieldDefect, "assignment to discriminant changes object branch")
4 changes: 0 additions & 4 deletions lib/system/jssys.nim
Original file line number Diff line number Diff line change
Expand Up @@ -528,10 +528,6 @@ when not defined(nimNoZeroExtendMagic):
proc nimMin(a, b: int): int {.compilerproc.} = return if a <= b: a else: b
proc nimMax(a, b: int): int {.compilerproc.} = return if a >= b: a else: b

proc chckNilDisp(p: pointer) {.compilerproc.} =
if p == nil:
sysFatal(NilAccessDefect, "cannot dispatch; dispatcher is nil")

include "system/hti"

proc isFatPointer(ti: PNimType): bool =
Expand Down
4 changes: 3 additions & 1 deletion tests/lang_callable/generics/tobjecttyperel.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ cool
test'''
"""

# disabled on VM until it supports methods (knownIssue)
# knownIssue: fails for the VM target because ``astgen`` emits the
# incorrect conversion operator for ``ref`` types involving
# generics

# bug #5241
type
Expand Down
3 changes: 0 additions & 3 deletions tests/lang_callable/method/tgeneric_methods.nim
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
discard """
target: !vm
output: '''wow2
X 1
X 3'''
"""

# disabled on VM until we support methods (knownIssue)

type
First[T] = ref object of RootObj
value: T
Expand Down
2 changes: 0 additions & 2 deletions tests/lang_callable/method/tmethod_issues.nim
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
discard """
target: "!vm"
output: '''
wof!
wof!
'''
"""

# disabled on VM until we support methods (knownIssue)


# bug #1659
Expand Down
3 changes: 0 additions & 3 deletions tests/lang_callable/method/tmethod_various.nim
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
discard """
target: "!vm"
output: '''
do nothing
HELLO WORLD!
'''
"""

# disabled on VM until we support methods (knownIssue)


# tmethods1
method somethin(obj: RootObj) {.base.} =
Expand Down
4 changes: 2 additions & 2 deletions tests/lang_callable/method/tmultim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ do nothing
'''
"""

# disabled on VM until we support methods (knownIssue)

# knownIssue: the ``of`` operator only considers the static type when using
# the VM backend

# tmultim2
type
Expand Down
4 changes: 1 addition & 3 deletions tests/lang_callable/method/tnildispatcher.nim
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
discard """
target: "!vm !js"
target: "!js"
outputsub: '''Error: unhandled exception: cannot dispatch; dispatcher is nil [NilAccessDefect]'''
exitcode: 1
"""

# disabled on VM until we support methods (knownIssue)

# disabled on JS because sem/codegen lets it through and we get a runtime NPE

# bug #5599
Expand Down
3 changes: 0 additions & 3 deletions tests/lang_callable/method/treturn_var_t.nim
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
discard """
target: "!vm"
output: '''Inh
45'''
"""

# disabled on VM until we support methods (knownIssue)

type
Base = ref object of RootObj
field: int
Expand Down
3 changes: 0 additions & 3 deletions tests/lang_callable/method/tsingle_methods.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
discard """
matrix: "--multimethods:off"
target: "!vm"
output: '''base
base
base
Expand All @@ -10,8 +9,6 @@ base
'''
"""

# disabled on VM until we support methods (knownIssue)

# bug #10912

type
Expand Down