Skip to content

Commit

Permalink
IC: added basic test case for methods (nim-lang#17679)
Browse files Browse the repository at this point in the history
* IC: added basic test case for methods

* IC: better methods test
  • Loading branch information
Araq authored Apr 9, 2021
1 parent e4b64ee commit 13b958e
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 6 deletions.
31 changes: 26 additions & 5 deletions compiler/ic/cbackend.nim
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@ proc unpackTree(g: ModuleGraph; thisModule: int;
var decoder = initPackedDecoder(g.config, g.cache)
result = loadNodes(decoder, g.packed, thisModule, tree, n)

proc generateCodeForModule(g: ModuleGraph; m: var LoadedModule; alive: var AliveSyms) =
proc setupBackendModule(g: ModuleGraph; m: var LoadedModule) =
if g.backend == nil:
g.backend = cgendata.newModuleList(g)

assert g.backend != nil
var bmod = cgen.newModule(BModuleList(g.backend), m.module, g.config)
bmod.idgen = idgenFromLoadedModule(m)

proc generateCodeForModule(g: ModuleGraph; m: var LoadedModule; alive: var AliveSyms) =
var bmod = BModuleList(g.backend).modules[m.module.position]
assert bmod != nil
bmod.flags.incl useAliveDataFromDce
bmod.alive = move alive[m.module.position]

Expand Down Expand Up @@ -118,6 +122,8 @@ proc generateCode*(g: ModuleGraph) =
for i in 0..high(g.packed):
echo i, " is of status ", g.packed[i].status, " ", toFullPath(g.config, FileIndex(i))

# First pass: Setup all the backend modules for all the modules that have
# changed:
for i in 0..high(g.packed):
# case statement here to enforce exhaustive checks.
case g.packed[i].status
Expand All @@ -126,15 +132,30 @@ proc generateCode*(g: ModuleGraph) =
of loading, stored:
assert false
of storing, outdated:
generateCodeForModule(g, g.packed[i], alive)
closeRodFile(g, g.packed[i].module)
storeAliveSyms(g.config, g.packed[i].module.position, alive)
setupBackendModule(g, g.packed[i])
of loaded:
# Even though this module didn't change, DCE might trigger a change.
# Consider this case: Module A uses symbol S from B and B does not use
# S itself. A is then edited not to use S either. Thus we have to
# recompile B in order to remove S from the final result.
if aliveSymsChanged(g.config, g.packed[i].module.position, alive):
g.packed[i].loadedButAliveSetChanged = true
setupBackendModule(g, g.packed[i])

# Second pass: Code generation.
for i in 0..high(g.packed):
# case statement here to enforce exhaustive checks.
case g.packed[i].status
of undefined:
discard "nothing to do"
of loading, stored:
assert false
of storing, outdated:
generateCodeForModule(g, g.packed[i], alive)
closeRodFile(g, g.packed[i].module)
storeAliveSyms(g.config, g.packed[i].module.position, alive)
of loaded:
if g.packed[i].loadedButAliveSetChanged:
generateCodeForModule(g, g.packed[i], alive)
else:
addFileToLink(g.config, g.packed[i].module)
Expand Down
2 changes: 1 addition & 1 deletion compiler/ic/ic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ type

LoadedModule* = object
status*: ModuleStatus
symsInit, typesInit: bool
symsInit, typesInit, loadedButAliveSetChanged*: bool
fromDisk*: PackedModule
syms: seq[PSym] # indexed by itemId
types: seq[PType]
Expand Down
7 changes: 7 additions & 0 deletions tests/ic/mbaseobj.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

type
Base* = ref object of RootObj
s*: string

method m*(b: Base) {.base.} =
echo "Base ", b.s
28 changes: 28 additions & 0 deletions tests/ic/tmethods.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
discard """
output: '''Base abc'''
"""

import mbaseobj

var c = Base(s: "abc")
m c

#!EDIT!#

discard """
output: '''Base abc
Inherited abc'''
"""

import mbaseobj

type
Inherited = ref object of Base

method m(i: Inherited) =
procCall m(Base i)
echo "Inherited ", i.s

var c = Inherited(s: "abc")
m c

0 comments on commit 13b958e

Please sign in to comment.