mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 01:14:41 +00:00
compilation cache: multi methods now work
This commit is contained in:
@@ -13,9 +13,9 @@ import
|
||||
msgs, hashes, nversion, options, strutils, crc, ropes, idents, lists,
|
||||
intsets, idgen
|
||||
|
||||
const
|
||||
ImportTablePos* = 0
|
||||
ModuleTablePos* = 1
|
||||
const
|
||||
ImportTablePos* = 0 # imported symbols are at level 0
|
||||
ModuleTablePos* = 1 # module's top level symbols are at level 1
|
||||
|
||||
type
|
||||
TCallingConvention* = enum
|
||||
@@ -173,20 +173,20 @@ type
|
||||
nkStmtListType, # a statement list ending in a type; for macros
|
||||
nkBlockType, # a statement block ending in a type; for macros
|
||||
# types as syntactic trees:
|
||||
nkTypeOfExpr,
|
||||
nkObjectTy,
|
||||
nkTupleTy,
|
||||
nkTypeOfExpr, # type(1+2)
|
||||
nkObjectTy, # object body
|
||||
nkTupleTy, # tuple body
|
||||
nkRecList, # list of object parts
|
||||
nkRecCase, # case section of object
|
||||
nkRecWhen, # when section of object
|
||||
nkRefTy,
|
||||
nkPtrTy,
|
||||
nkVarTy,
|
||||
nkRefTy, # ``ref T``
|
||||
nkPtrTy, # ``ptr T``
|
||||
nkVarTy, # ``var T``
|
||||
nkConstTy, # ``const T``
|
||||
nkMutableTy, # ``mutable T``
|
||||
nkDistinctTy, # distinct type
|
||||
nkProcTy,
|
||||
nkEnumTy,
|
||||
nkProcTy, # proc type
|
||||
nkEnumTy, # enum body
|
||||
nkEnumFieldDef, # `ident = expr` in an enumeration
|
||||
nkReturnToken # token used for interpretation
|
||||
TNodeKinds* = set[TNodeKind]
|
||||
@@ -235,7 +235,8 @@ type
|
||||
TSymFlags* = set[TSymFlag]
|
||||
|
||||
const
|
||||
sfFakeConst* = sfDeadCodeElim # const cannot be put into a data section
|
||||
sfFakeConst* = sfDeadCodeElim # const cannot be put into a data section
|
||||
sfDispatcher* = sfDeadCodeElim # copied method symbol is the dispatcher
|
||||
|
||||
type
|
||||
TTypeKind* = enum # order is important!
|
||||
@@ -246,7 +247,7 @@ type
|
||||
tyGenericInvokation, # ``T[a, b]`` for types to invoke
|
||||
tyGenericBody, # ``T[a, b, body]`` last parameter is the body
|
||||
tyGenericInst, # ``T[a, b, realInstance]`` instantiated generic type
|
||||
tyGenericParam, # ``a`` in the example
|
||||
tyGenericParam, # ``a`` in the above patterns
|
||||
tyDistinct,
|
||||
tyEnum,
|
||||
tyOrdinal, # misnamed: should become 'tyConstraint'
|
||||
@@ -575,7 +576,7 @@ const
|
||||
pragmasPos* = 3
|
||||
codePos* = 4
|
||||
resultPos* = 5
|
||||
dispatcherPos* = 6
|
||||
dispatcherPos* = 6 # caution: if method has no 'result' it can be position 5!
|
||||
|
||||
# creator procs:
|
||||
proc NewSym*(symKind: TSymKind, Name: PIdent, owner: PSym): PSym
|
||||
|
||||
@@ -34,9 +34,11 @@ proc genConv(n: PNode, d: PType, downcast: bool): PNode =
|
||||
|
||||
proc methodCall*(n: PNode): PNode =
|
||||
result = n
|
||||
# replace ordinary method by dispatcher method:
|
||||
var disp = lastSon(result.sons[0].sym.ast).sym
|
||||
result.sons[0].sym = disp
|
||||
for i in countup(1, sonsLen(result) - 1):
|
||||
# change the arguments to up/downcasts to fit the dispatcher's parameters:
|
||||
for i in countup(1, sonsLen(result)-1):
|
||||
result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true)
|
||||
|
||||
# save for incremental compilation:
|
||||
@@ -67,24 +69,36 @@ proc sameMethodBucket(a, b: PSym): bool =
|
||||
return
|
||||
result = true
|
||||
|
||||
proc attachDispatcher(s: PSym, dispatcher: PNode) =
|
||||
var L = s.ast.len-1
|
||||
var x = s.ast.sons[L]
|
||||
if x.kind == nkSym and sfDispatcher in x.sym.flags:
|
||||
# we've added a dispatcher already, so overwrite it
|
||||
s.ast.sons[L] = dispatcher
|
||||
else:
|
||||
s.ast.add(dispatcher)
|
||||
|
||||
proc methodDef*(s: PSym, fromCache: bool) =
|
||||
var L = len(gMethods)
|
||||
for i in countup(0, L - 1):
|
||||
if sameMethodBucket(gMethods[i][0], s):
|
||||
add(gMethods[i], s) # store a symbol to the dispatcher:
|
||||
addSon(s.ast, lastSon(gMethods[i][0].ast))
|
||||
add(gMethods[i], s)
|
||||
attachDispatcher(s, lastSon(gMethods[i][0].ast))
|
||||
return
|
||||
add(gMethods, @[s])
|
||||
# create a new dispatcher:
|
||||
if not fromCache:
|
||||
var disp = copySym(s)
|
||||
incl(disp.flags, sfDispatcher)
|
||||
excl(disp.flags, sfExported)
|
||||
disp.typ = copyType(disp.typ, disp.typ.owner, false)
|
||||
# we can't inline the dispatcher itself (for now):
|
||||
if disp.typ.callConv == ccInline: disp.typ.callConv = ccDefault
|
||||
disp.ast = copyTree(s.ast)
|
||||
disp.ast.sons[codePos] = ast.emptyNode
|
||||
if s.typ.sons[0] != nil:
|
||||
disp.ast.sons[resultPos].sym = copySym(s.ast.sons[resultPos].sym)
|
||||
addSon(s.ast, newSymNode(disp))
|
||||
attachDispatcher(s, newSymNode(disp))
|
||||
|
||||
proc relevantCol(methods: TSymSeq, col: int): bool =
|
||||
# returns true iff the position is relevant
|
||||
|
||||
@@ -103,6 +103,7 @@ proc CommandGenDepend(filename: string) =
|
||||
proc CommandCheck(filename: string) =
|
||||
msgs.gErrorMax = high(int) # do not stop after first error
|
||||
semanticPasses() # use an empty backend for semantic checking only
|
||||
registerPass(rodwrite.rodwritePass())
|
||||
compileProject(filename)
|
||||
|
||||
proc CommandCompileToC(filename: string) =
|
||||
|
||||
@@ -322,7 +322,7 @@ proc addToIndex(w: var TIndex, key, val: int) =
|
||||
w.lastIdxVal = val
|
||||
IiTablePut(w.tab, key, val)
|
||||
|
||||
var debugWritten: TIntSet
|
||||
#var debugWritten = initIntSet()
|
||||
|
||||
proc symStack(w: PRodWriter) =
|
||||
var i = 0
|
||||
@@ -351,7 +351,7 @@ proc symStack(w: PRodWriter) =
|
||||
if s.kind == skConverter:
|
||||
if w.converters.len != 0: add(w.converters, ' ')
|
||||
encodeVInt(s.id, w.converters)
|
||||
elif s.kind == skMethod:
|
||||
elif s.kind == skMethod and sfDispatcher notin s.flags:
|
||||
if w.methods.len != 0: add(w.methods, ' ')
|
||||
encodeVInt(s.id, w.methods)
|
||||
elif IiTableGet(w.imports.tab, s.id) == invalidKey:
|
||||
@@ -569,4 +569,3 @@ proc rodwritePass(): TPass =
|
||||
result.close = myClose
|
||||
result.process = process
|
||||
|
||||
debugWritten = initIntSet()
|
||||
|
||||
10
todo.txt
10
todo.txt
@@ -1,16 +1,16 @@
|
||||
Version 0.8.14
|
||||
==============
|
||||
|
||||
- optimize unused constants away (affected by HLO)
|
||||
- optimize unused constants away (affected by HLO); get rid of nfAllConst
|
||||
- 'let x = y'
|
||||
- fix actors.nim
|
||||
- make threadvar efficient again on linux after testing
|
||||
- test the sort implementation again
|
||||
- document & test splicing; don't forget to test negative indexes
|
||||
- implement lib/pure/memfiles properly
|
||||
- eval context is per module; this way modularity is kept; global id generation
|
||||
macro can still be done once macros support basic IO (store current id in
|
||||
some file)
|
||||
- methods for JS backend (very easy to do!)
|
||||
|
||||
|
||||
incremental compilation
|
||||
@@ -18,7 +18,6 @@ incremental compilation
|
||||
|
||||
- adapt thread var implementation to care about the new merge operation
|
||||
- write test cases: needs test script support
|
||||
- fix method generation
|
||||
- test thread var
|
||||
- test DLL interfacing!
|
||||
- stress test with whole compiler
|
||||
@@ -26,13 +25,14 @@ incremental compilation
|
||||
- automate tests:
|
||||
- test basic recompilation scheme
|
||||
- test type converters
|
||||
- test G, A, B example from the documentation
|
||||
- test init sections
|
||||
- test G, A, B example from the documentation; test init sections
|
||||
- test method generation
|
||||
|
||||
|
||||
version 0.9.0
|
||||
=============
|
||||
|
||||
- test the sort implementation again
|
||||
- const ptr/ref
|
||||
- unsigned ints and bignums
|
||||
- implement the high level optimizer
|
||||
|
||||
Reference in New Issue
Block a user