implemented incompleteStruct pragma; embedded debugger works with posix module

This commit is contained in:
Araq 2012-01-05 00:46:51 +01:00
commit 8aa4e46707
19 changed files with 85 additions and 47 deletions

View file

@ -339,6 +339,7 @@ type
const const
routineKinds* = {skProc, skMethod, skIterator, skConverter, routineKinds* = {skProc, skMethod, skIterator, skConverter,
skMacro, skTemplate} skMacro, skTemplate}
tfIncompleteStruct* = tfVarargs
type type
TMagic* = enum # symbols that require compiler magic: TMagic* = enum # symbols that require compiler magic:

View file

@ -241,8 +241,8 @@ proc typeNameOrLiteral(t: PType, literal: string): PRope =
proc getSimpleTypeDesc(m: BModule, typ: PType): PRope = proc getSimpleTypeDesc(m: BModule, typ: PType): PRope =
const const
NumericalTypeToStr: array[tyInt..tyFloat128, string] = ["NI", "NI8", "NI16", NumericalTypeToStr: array[tyInt..tyFloat128, string] = ["NI", "NI8",
"NI32", "NI64", "NF", "NF32", "NF64", "NF128"] "NI16", "NI32", "NI64", "NF", "NF32", "NF64", "NF128"]
case typ.Kind case typ.Kind
of tyPointer: of tyPointer:
result = typeNameOrLiteral(typ, "void*") result = typeNameOrLiteral(typ, "void*")
@ -301,7 +301,8 @@ proc mangleRecFieldName(field: PSym, rectype: PType): PRope =
result = toRope(mangle(field.name.s)) result = toRope(mangle(field.name.s))
if result == nil: InternalError(field.info, "mangleRecFieldName") if result == nil: InternalError(field.info, "mangleRecFieldName")
proc genRecordFieldsAux(m: BModule, n: PNode, accessExpr: PRope, rectype: PType, proc genRecordFieldsAux(m: BModule, n: PNode,
accessExpr: PRope, rectype: PType,
check: var TIntSet): PRope = check: var TIntSet): PRope =
var var
ae, uname, sname, a: PRope ae, uname, sname, a: PRope
@ -560,9 +561,13 @@ proc genTypeInfoAuxBase(m: BModule, typ: PType, name, base: PRope) =
nimtypeKind = ord(tyPureObject) nimtypeKind = ord(tyPureObject)
else: else:
nimtypeKind = ord(typ.kind) nimtypeKind = ord(typ.kind)
var size: PRope
if tfIncompleteStruct in typ.flags: size = toRope"void*"
else: size = getTypeDesc(m, typ)
appf(m.s[cfsTypeInit3], appf(m.s[cfsTypeInit3],
"$1->size = sizeof($2);$n" & "$1->kind = $3;$n" & "$1->base = $4;$n", "$1->size = sizeof($2);$n" & "$1->kind = $3;$n" & "$1->base = $4;$n",
[name, getTypeDesc(m, typ), toRope(nimtypeKind), base]) [name, size, toRope(nimtypeKind), base])
# compute type flags for GC optimization # compute type flags for GC optimization
var flags = 0 var flags = 0
if not containsGarbageCollectedRef(typ): flags = flags or 1 if not containsGarbageCollectedRef(typ): flags = flags or 1

View file

@ -90,7 +90,7 @@ proc GetUniqueType*(key: PType): PType =
result = GetUniqueType(lastSon(key)) result = GetUniqueType(lastSon(key))
of tyArrayConstr, tyGenericInvokation, tyGenericBody, tyGenericParam, of tyArrayConstr, tyGenericInvokation, tyGenericBody, tyGenericParam,
tyOpenArray, tyArray, tyTuple, tySet, tyRange, tyOpenArray, tyArray, tyTuple, tySet, tyRange,
tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy: tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar:
# we have to do a slow linear search because types may need # we have to do a slow linear search because types may need
# to be compared by their structure: # to be compared by their structure:
if IdTableHasObjectAsKey(gTypeTable[k], key): return key if IdTableHasObjectAsKey(gTypeTable[k], key): return key
@ -121,8 +121,8 @@ proc GetUniqueType*(key: PType): PType =
if result == nil: if result == nil:
IdTablePut(gTypeTable[k], key, key) IdTablePut(gTypeTable[k], key, key)
result = key result = key
of tyProc, tyVar: of tyProc:
# tyVar is not 100% correct, but speeds things up a little: # tyVar is not 100% correct, but would speeds things up a little:
result = key result = key
proc TableGetType*(tab: TIdTable, key: PType): PObject = proc TableGetType*(tab: TIdTable, key: PType): PObject =

View file

@ -383,8 +383,8 @@ proc assignLocalVar(p: BProc, s: PSym) =
if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy) if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy)
app(p.s[cpsLocals], getTypeDesc(p.module, s.loc.t)) app(p.s[cpsLocals], getTypeDesc(p.module, s.loc.t))
if sfRegister in s.flags: app(p.s[cpsLocals], " register") if sfRegister in s.flags: app(p.s[cpsLocals], " register")
elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds: #elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
app(p.s[cpsLocals], " GC_GUARD") # app(p.s[cpsLocals], " GC_GUARD")
if (sfVolatile in s.flags) or (p.nestedTryStmts.len > 0): if (sfVolatile in s.flags) or (p.nestedTryStmts.len > 0):
app(p.s[cpsLocals], " volatile") app(p.s[cpsLocals], " volatile")
appf(p.s[cpsLocals], " $1;$n", [s.loc.r]) appf(p.s[cpsLocals], " $1;$n", [s.loc.r])

View file

@ -44,7 +44,7 @@ const
wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame} wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame}
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow, wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow,
wImportcpp, wImportobjc, wError} wImportcpp, wImportobjc, wError, wIncompleteStruct}
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
wImportcpp, wImportobjc, wError} wImportcpp, wImportobjc, wError}
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
@ -571,6 +571,10 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
of wEmit: PragmaEmit(c, it) of wEmit: PragmaEmit(c, it)
of wUnroll: PragmaUnroll(c, it) of wUnroll: PragmaUnroll(c, it)
of wLinearScanEnd: PragmaLinearScanEnd(c, it) of wLinearScanEnd: PragmaLinearScanEnd(c, it)
of wIncompleteStruct:
noVal(it)
if sym.typ == nil: invalidPragma(it)
incl(sym.typ.flags, tfIncompleteStruct)
else: invalidPragma(it) else: invalidPragma(it)
else: invalidPragma(it) else: invalidPragma(it)
else: processNote(c, it) else: processNote(c, it)

View file

@ -36,7 +36,7 @@ type
wMagic, wThread, wFinal, wProfiler, wObjChecks, wMagic, wThread, wFinal, wProfiler, wObjChecks,
wImportCpp, wImportObjC, wImportCpp, wImportObjC,
wImportCompilerProc, wImportCompilerProc,
wImportc, wExportc, wExtern, wImportc, wExportc, wExtern, wIncompleteStruct,
wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader, wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader,
wNosideeffect, wNoreturn, wMerge, wLib, wDynlib, wCompilerproc, wProcVar, wNosideeffect, wNoreturn, wMerge, wLib, wDynlib, wCompilerproc, wProcVar,
wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef, wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef,
@ -80,7 +80,7 @@ const
"magic", "thread", "final", "profiler", "objchecks", "magic", "thread", "final", "profiler", "objchecks",
"importcpp", "importobjc", "importcpp", "importobjc",
"importcompilerproc", "importc", "exportc", "extern", "importcompilerproc", "importc", "exportc", "extern", "incompletestruct",
"align", "nodecl", "pure", "volatile", "register", "sideeffect", "align", "nodecl", "pure", "volatile", "register", "sideeffect",
"header", "nosideeffect", "noreturn", "merge", "lib", "dynlib", "header", "nosideeffect", "noreturn", "merge", "lib", "dynlib",
"compilerproc", "procvar", "fatal", "error", "warning", "hint", "line", "compilerproc", "procvar", "fatal", "error", "warning", "hint", "line",

View file

@ -167,6 +167,17 @@ encloses the header file in ``""`` in the generated C code.
**Note**: This will not work for the LLVM backend. **Note**: This will not work for the LLVM backend.
IncompleteStruct pragma
-----------------------
The `incompleteStruct`:idx: pragma tells the compiler to not use the
underlying C ``struct`` in a ``sizeof`` expression:
.. code-block:: Nimrod
type
TDIR* {.importc: "DIR", header: "<dirent.h>",
final, pure, incompleteStruct.} = object
Compile pragma Compile pragma
-------------- --------------
The `compile`:idx: pragma can be used to compile and link a C/C++ source file The `compile`:idx: pragma can be used to compile and link a C/C++ source file

View file

@ -85,8 +85,8 @@ proc web(args: string) =
proc update(args: string) = proc update(args: string) =
when defined(windows): when defined(windows):
echo("Windows Users: Make sure to be running this in Bash. If you aren't, press CTRL+C now.") echo("Windows users: Make sure to be running this in Bash. ",
"If you aren't, press CTRL+C now.")
var thisDir = getAppDir() var thisDir = getAppDir()
var git = findExe("git") var git = findExe("git")
@ -109,42 +109,36 @@ proc update(args: string) =
echo("Fetching updates from repo...") echo("Fetching updates from repo...")
var pullout = execCmdEx(git & " pull origin master") var pullout = execCmdEx(git & " pull origin master")
if pullout[1] != 0: if pullout[1] != 0:
echo("An error has occured.") quit("An error has occured.")
return
else: else:
if pullout[0] == "Already up-to-date.\r\n": if pullout[0].startsWith("Already up-to-date."):
echo("No new changes fetched from the repo. Local branch must be ahead of it. Exiting...") quit("No new changes fetched from the repo. " &
return "Local branch must be ahead of it. Exiting...")
else: else:
echo("An error has occured.") quit("An error has occured.")
return
else: else:
echo("No repo or executable found!") echo("No repo or executable found!")
when defined(haveZipLib): when defined(haveZipLib):
echo("Falling back.. Downloading source code from repo...") echo("Falling back.. Downloading source code from repo...")
# use dom96's httpclient to download zip # use dom96's httpclient to download zip
downloadFile("https://github.com/Araq/Nimrod/zipball/master",thisDir & "/update.zip") downloadFile("https://github.com/Araq/Nimrod/zipball/master",
thisDir / "update.zip")
try: try:
echo("Extracting source code from archive...") echo("Extracting source code from archive...")
var zip :TZipArchive var zip: TZipArchive
discard open(zip,thisDir & "/update.zip", fmRead) # will add error checking later discard open(zip, thisDir & "/update.zip", fmRead)
extractAll(zip, thisDir & "/") extractAll(zip, thisDir & "/")
except: except:
echo("Error reading archive.") quit("Error reading archive.")
return
else: else:
echo("No failback available. Exiting...") quit("No failback available. Exiting...")
return
echo("Starting update...") echo("Starting update...")
boot(args) boot(args)
echo("Update complete!") echo("Update complete!")
# -------------- boot --------------------------------------------------------- # -------------- boot ---------------------------------------------------------
const const

View file

@ -1,7 +1,7 @@
/* /*
Nimrod's Runtime Library Nimrod's Runtime Library
(c) Copyright 2011 Andreas Rumpf (c) Copyright 2012 Andreas Rumpf
See the file "copying.txt", included in this See the file "copying.txt", included in this
distribution, for details about the copyright. distribution, for details about the copyright.
@ -438,7 +438,9 @@ __declspec(naked) int __fastcall NimXadd(volatile int* pNum, int val) {
# define unlikely(x) (x) # define unlikely(x) (x)
#endif #endif
#if defined(__GNUC__) || defined(__clang__) #if 0 // defined(__GNUC__) || defined(__clang__)
// not needed anymore because the stack marking cares about
// interior pointers now
static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); } static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
# define GC_GUARD __attribute__ ((cleanup(GCGuard))) # define GC_GUARD __attribute__ ((cleanup(GCGuard)))
#else #else

View file

@ -68,10 +68,19 @@ const
STDIN_FILENO* = 0 ## File number of stdin; STDIN_FILENO* = 0 ## File number of stdin;
STDOUT_FILENO* = 1 ## File number of stdout; STDOUT_FILENO* = 1 ## File number of stdout;
type when defined(endb):
TDIR* {.importc: "DIR", header: "<dirent.h>", final, pure.} = object # to not break bootstrapping again ...
## A type representing a directory stream. type
TDIR* {.importc: "DIR", header: "<dirent.h>",
final, pure, incompleteStruct.} = object
## A type representing a directory stream.
else:
type
TDIR* {.importc: "DIR", header: "<dirent.h>",
final, pure.} = object
## A type representing a directory stream.
type
Tdirent* {.importc: "struct dirent", Tdirent* {.importc: "struct dirent",
header: "<dirent.h>", final, pure.} = object ## dirent_t struct header: "<dirent.h>", final, pure.} = object ## dirent_t struct
d_ino*: TIno ## File serial number. d_ino*: TIno ## File serial number.

View file

@ -683,6 +683,10 @@ proc getOccupiedMem(a: TMemRegion): int {.inline.} =
# ---------------------- thread memory region ------------------------------- # ---------------------- thread memory region -------------------------------
template InstantiateForRegion(allocator: expr) = template InstantiateForRegion(allocator: expr) =
when false:
proc interiorAllocatedPtr*(p: pointer): pointer =
result = interiorAllocatedPtr(allocator, p)
proc deallocOsPages = deallocOsPages(allocator) proc deallocOsPages = deallocOsPages(allocator)
proc alloc(size: int): pointer = proc alloc(size: int): pointer =

View file

@ -138,7 +138,7 @@ proc rejectThreadTests(r: var TResults, options: string) =
rejectSingleTest(r, "tests/threads/tthreadanalysis3", options) rejectSingleTest(r, "tests/threads/tthreadanalysis3", options)
rejectSingleTest(r, "tests/threads/tthreadheapviolation1", options) rejectSingleTest(r, "tests/threads/tthreadheapviolation1", options)
# ------------------------- IO tests ----------------------------------- # ------------------------- IO tests ------------------------------------------
proc runIOTests(r: var TResults, options: string) = proc runIOTests(r: var TResults, options: string) =
# We need readall_echo to be compiled for this test to run. # We need readall_echo to be compiled for this test to run.
@ -147,6 +147,12 @@ proc runIOTests(r: var TResults, options: string) =
compileSingleTest(c, "tests/system/helpers/readall_echo", options) compileSingleTest(c, "tests/system/helpers/readall_echo", options)
runSingleTest(r, "tests/system/io", options) runSingleTest(r, "tests/system/io", options)
# ------------------------- debugger tests ------------------------------------
proc compileDebuggerTests(r: var TResults, options: string) =
compileSingleTest(r, "tools/nimgrep", options &
" --debugger:on")
# ------------------------- register special tests here ----------------------- # ------------------------- register special tests here -----------------------
proc runSpecialTests(r: var TResults, options: string) = proc runSpecialTests(r: var TResults, options: string) =
runRodFiles(r, options) runRodFiles(r, options)
@ -165,4 +171,5 @@ proc compileSpecialTests(r: var TResults, options: string) =
compileSingleTest(r, "compiler/pas2nim/pas2nim.nim", options) compileSingleTest(r, "compiler/pas2nim/pas2nim.nim", options)
compileDLLTests(r, options) compileDLLTests(r, options)
compileDebuggerTests(r, options)

View file

@ -2,8 +2,7 @@ version 0.8.14
============== ==============
- BUG: type TX = TTable[string, int] - BUG: type TX = TTable[string, int]
- BUG: temp3.nim triggers weird compiler bug - BUG: temp2.nim triggers weird compiler bug
- BUG: --debugger:on does not work with talloc.nim
- implicit invokation of `items`/`pairs` seems nice; ensure items(23) does - implicit invokation of `items`/`pairs` seems nice; ensure items(23) does
not compile though not compile though

View file

@ -1,7 +1,7 @@
# #
# #
# Nimrod Grep Utility # Nimrod Grep Utility
# (c) Copyright 2011 Andreas Rumpf # (c) Copyright 2012 Andreas Rumpf
# #
# See the file "copying.txt", included in this # See the file "copying.txt", included in this
# distribution, for details about the copyright. # distribution, for details about the copyright.
@ -14,7 +14,7 @@ const
Version = "0.8" Version = "0.8"
Usage = "nimgrep - Nimrod Grep Utility Version " & version & """ Usage = "nimgrep - Nimrod Grep Utility Version " & version & """
(c) 2011 Andreas Rumpf (c) 2012 Andreas Rumpf
Usage: Usage:
nimgrep [options] [pattern] [replacement] (file/directory)* nimgrep [options] [pattern] [replacement] (file/directory)*
Options: Options:

View file

@ -1,7 +1,7 @@
# #
# #
# The Nimrod Installation Generator # The Nimrod Installation Generator
# (c) Copyright 2011 Andreas Rumpf # (c) Copyright 2012 Andreas Rumpf
# #
# See the file "copying.txt", included in this # See the file "copying.txt", included in this
# distribution, for details about the copyright. # distribution, for details about the copyright.
@ -104,7 +104,7 @@ const
Version = "0.9" Version = "0.9"
Usage = "niminst - Nimrod Installation Generator Version " & version & """ Usage = "niminst - Nimrod Installation Generator Version " & version & """
(c) 2010 Andreas Rumpf (c) 2012 Andreas Rumpf
Usage: Usage:
niminst [options] command[;command2...] ini-file[.ini] [compile_options] niminst [options] command[;command2...] ini-file[.ini] [compile_options]
Command: Command:

View file

@ -1,7 +1,7 @@
# #
# #
# Nimrod REPL # Nimrod REPL
# (c) Copyright 2010 Dominik Picheta # (c) Copyright 2012 Dominik Picheta
# #
# See the file "copying.txt", included in this # See the file "copying.txt", included in this
# distribution, for details about the copyright. # distribution, for details about the copyright.

View file

@ -1,7 +1,7 @@
# #
# #
# Nimrod Website Generator # Nimrod Website Generator
# (c) Copyright 2011 Andreas Rumpf # (c) Copyright 2012 Andreas Rumpf
# #
# See the file "copying.txt", included in this # See the file "copying.txt", included in this
# distribution, for details about the copyright. # distribution, for details about the copyright.
@ -44,7 +44,7 @@ const
Version = "0.7" Version = "0.7"
Usage = "nimweb - Nimrod Website Generator Version " & version & """ Usage = "nimweb - Nimrod Website Generator Version " & version & """
(c) 2011 Andreas Rumpf (c) 2012 Andreas Rumpf
Usage: Usage:
nimweb [options] ini-file[.ini] [compile_options] nimweb [options] ini-file[.ini] [compile_options]
Options: Options:

View file

@ -65,7 +65,7 @@
</div> </div>
</div> </div>
<div id="footer"> <div id="footer">
copyright &copy; 2011 $c.authors | Last update: ${getDateStr()} copyright &copy; 2012 $c.authors | Last update: ${getDateStr()}
| <a class="reference" href="http://validator.w3.org/check?uri=referer">XHTML 1.1</a> | <a class="reference" href="http://validator.w3.org/check?uri=referer">XHTML 1.1</a>
| <a class="reference" href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> | <a class="reference" href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>
| <a class="reference" href="http://www.dcarter.co.uk">design by dcarter</a> | <a class="reference" href="http://www.dcarter.co.uk">design by dcarter</a>

View file

@ -89,6 +89,8 @@ Compiler Additions
Objective C. Objective C.
- The new pragmas ``importcpp`` and ``importobjc`` make interfacing with C++ - The new pragmas ``importcpp`` and ``importobjc`` make interfacing with C++
and Objective C somewhat easier. and Objective C somewhat easier.
- Added a new pragma ``incompleteStruct`` to deal with incomplete C struct
definitions.
- Added a ``--nimcache:PATH`` configuration option for control over the output - Added a ``--nimcache:PATH`` configuration option for control over the output
directory for generated code. directory for generated code.
- The ``--genScript`` option now produces different compilation scripts - The ``--genScript`` option now produces different compilation scripts