summary refs log tree commit diff stats
path: root/compiler/rodread.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rodread.nim')
-rwxr-xr-xcompiler/rodread.nim49
1 files changed, 37 insertions, 12 deletions
diff --git a/compiler/rodread.nim b/compiler/rodread.nim
index 6191218fe..baffac4c4 100755
--- a/compiler/rodread.nim
+++ b/compiler/rodread.nim
@@ -9,10 +9,11 @@
 
 # This module is responsible for loading of rod files.
 #
-#  Reading and writing binary files are really hard to debug. Therefore we use
-#  a special text format. ROD-files are more efficient to process because
-#  symbols are only loaded on demand.
-#  It consists of:
+# Reading and writing binary files are really hard to debug. Therefore we use
+# a "creative" text/binary hybrid format. ROD-files are more efficient
+# to process because symbols are can be loaded on demand.
+# 
+# A ROD file consists of:
 #
 #  - a header:
 #    NIM:$fileversion\n
@@ -28,7 +29,7 @@
 #    myfile.inc
 #    lib/mymodA
 #    )
-#  - a include file dependency section:
+#  - an include file dependency section:
 #    INCLUDES(
 #    <fileidx> <CRC of myfile.inc>\n # fileidx is the LINE in the file section!
 #    )
@@ -48,6 +49,11 @@
 #    id-diff idx-diff\n
 #    id-diff idx-diff\n
 #    )
+#
+#    Since the whole index has to be read in advance, we compress it by 
+#    storing the integer differences to the last entry instead of using the
+#    real numbers.
+#
 #  - an import index consisting of (ID, moduleID)-pairs:
 #    IMPORTS(
 #    id-diff moduleID-diff\n
@@ -55,7 +61,12 @@
 #    )
 #  - a list of all exported type converters because they are needed for correct
 #    semantic checking:
-#    CONVERTERS:id id\n   # position of the symbol in the DATA section
+#    CONVERTERS:id id\n   # symbol ID
+#
+#  - a list of all (private or exported) methods because they are needed for
+#    correct dispatcher generation:
+#    METHODS: id id\n   # symbol ID
+#
 #  - an AST section that contains the module's AST:
 #    INIT(
 #    idx\n  # position of the node in the DATA section
@@ -72,8 +83,6 @@
 #    stops immediately after ``DATA(`` and the rest is only loaded on demand
 #    by using mem'mapped a file.
 #
-#  We now also do index compression, because an index always needs to be read.
-#
 
 import 
   os, options, strutils, nversion, ast, astalgo, msgs, platform, condsyms, 
@@ -116,7 +125,7 @@ type
     files: TStringSeq
     dataIdx: int             # offset of start of data section
     convertersIdx: int       # offset of start of converters section
-    initIdx, interfIdx, compilerProcsIdx: int
+    initIdx, interfIdx, compilerProcsIdx, methodsIdx: int
     filename: string
     index, imports: TIndex
     readerIndex: int
@@ -125,6 +134,7 @@ type
     syms: TIdTable       # already processed symbols
     memfile: TMemFile    # unfortunately there is no point in time where we
                          # can close this! XXX
+    methods*: TSymSeq
   
   PRodReader* = ref TRodReader
 
@@ -547,6 +557,9 @@ proc processRodFile(r: PRodReader, crc: TCrc32) =
     of "CONVERTERS": 
       r.convertersIdx = r.pos + 1
       skipSection(r)
+    of "METHODS":
+      r.methodsIdx = r.pos + 1
+      skipSection(r)
     of "DATA": 
       r.dataIdx = r.pos + 2 # "(\10"
       # We do not read the DATA section here! We read the needed objects on
@@ -573,6 +586,7 @@ proc newRodReader(modfilename: string, crc: TCrc32,
   new(result)
   result.files = @[]
   result.modDeps = @[]
+  result.methods = @[]
   var r = result
   r.reason = rrNone
   r.pos = 0
@@ -599,7 +613,7 @@ proc newRodReader(modfilename: string, crc: TCrc32,
       processRodFile(r, crc)
     else: 
       result = nil
-  else: 
+  else:
     result = nil
   
 proc rrGetType(r: PRodReader, id: int, info: TLineInfo): PType = 
@@ -681,7 +695,8 @@ proc loadInitSection(r: PRodReader): PNode =
   r.pos = oldPos
 
 proc loadConverters(r: PRodReader) = 
-  # We have to ensure that no exported converter is a stub anymore.
+  # We have to ensure that no exported converter is a stub anymore, and the
+  # import mechanism takes care of the rest.
   if r.convertersIdx == 0 or r.dataIdx == 0: 
     InternalError("importConverters")
   r.pos = r.convertersIdx
@@ -689,6 +704,15 @@ proc loadConverters(r: PRodReader) =
     var d = decodeVInt(r.s, r.pos)
     discard rrGetSym(r, d, UnknownLineInfo())
     if r.s[r.pos] == ' ': inc(r.pos)
+
+proc loadMethods(r: PRodReader) =
+  if r.methodsIdx == 0 or r.dataIdx == 0:
+    InternalError("loadMethods")
+  r.pos = r.methodsIdx
+  while r.s[r.pos] > '\x0A':
+    var d = decodeVInt(r.s, r.pos)
+    r.methods.add(rrGetSym(r, d, UnknownLineInfo()))
+    if r.s[r.pos] == ' ': inc(r.pos)
   
 proc getModuleIdx(filename: string): int = 
   for i in countup(0, high(gMods)): 
@@ -752,7 +776,8 @@ proc handleSymbolFile(module: PSym, filename: string): PRodReader =
     processInterf(result, module)
     processCompilerProcs(result, module)
     loadConverters(result)
-  else: 
+    loadMethods(result)
+  else:
     module.id = getID()
   
 proc GetCRC*(filename: string): TCrc32 =