importCompilerProc pragma introduced because the hacks for typeinfo.nim did not suffice

This commit is contained in:
Araq 2011-06-27 08:33:03 +02:00
commit 3091bc4958
9 changed files with 96 additions and 38 deletions

View file

@ -406,7 +406,8 @@ type
lfNoDecl, # do not declare it in C lfNoDecl, # do not declare it in C
lfDynamicLib, # link symbol to dynamic library lfDynamicLib, # link symbol to dynamic library
lfExportLib, # export symbol for dynamic library generation lfExportLib, # export symbol for dynamic library generation
lfHeader # include header file for symbol lfHeader, # include header file for symbol
lfImportCompilerProc # ``importc`` of a compilerproc
TStorageLoc* = enum TStorageLoc* = enum
OnUnknown, # location is unknown (stack, heap or static) OnUnknown, # location is unknown (stack, heap or static)
OnStack, # location is on hardware stack OnStack, # location is on hardware stack

View file

@ -1452,7 +1452,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet, of mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet,
mInSet: mInSet:
genSetOp(p, e, d, op) genSetOp(p, e, d, op)
of mNewString, mNewStringOfCap, mCopyStr, mCopyStrLast, mExit, mCreateThread: of mCreateThread: genCall(p, e, d)
of mNewString, mNewStringOfCap, mCopyStr, mCopyStrLast, mExit:
var opr = e.sons[0].sym var opr = e.sons[0].sym
if lfNoDecl notin opr.loc.flags: if lfNoDecl notin opr.loc.flags:
discard cgsym(p.module, opr.loc.r.ropeToStr) discard cgsym(p.module, opr.loc.r.ropeToStr)

View file

@ -666,9 +666,13 @@ proc genProcPrototype(m: BModule, sym: PSym) =
proc genProcNoForward(m: BModule, prc: PSym) = proc genProcNoForward(m: BModule, prc: PSym) =
fillProcLoc(prc) fillProcLoc(prc)
useHeader(m, prc) useHeader(m, prc)
if lfImportCompilerProc in prc.loc.flags:
# dependency to a compilerproc:
discard cgsym(m, prc.name.s)
return
genProcPrototype(m, prc) genProcPrototype(m, prc)
if lfNoDecl in prc.loc.Flags: return if lfNoDecl in prc.loc.Flags: nil
if prc.typ.callConv == ccInline: elif prc.typ.callConv == ccInline:
# We add inline procs to the calling module to enable C based inlining. # We add inline procs to the calling module to enable C based inlining.
# This also means that a check with ``gGeneratedSyms`` is wrong, we need # This also means that a check with ``gGeneratedSyms`` is wrong, we need
# a check for ``m.declaredThings``. # a check for ``m.declaredThings``.
@ -676,7 +680,7 @@ proc genProcNoForward(m: BModule, prc: PSym) =
elif lfDynamicLib in prc.loc.flags: elif lfDynamicLib in prc.loc.flags:
if not ContainsOrIncl(gGeneratedSyms, prc.id): if not ContainsOrIncl(gGeneratedSyms, prc.id):
SymInDynamicLib(findPendingModule(m, prc), prc) SymInDynamicLib(findPendingModule(m, prc), prc)
elif not (sfImportc in prc.flags): elif sfImportc notin prc.flags:
if not ContainsOrIncl(gGeneratedSyms, prc.id): if not ContainsOrIncl(gGeneratedSyms, prc.id):
genProcAux(findPendingModule(m, prc), prc) genProcAux(findPendingModule(m, prc), prc)

View file

@ -22,7 +22,7 @@ const
procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
wBorrow, wExtern} wBorrow, wExtern, wImportCompilerProc}
converterPragmas* = procPragmas converterPragmas* = procPragmas
methodPragmas* = procPragmas methodPragmas* = procPragmas
macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
@ -80,6 +80,12 @@ proc MakeExternExport(s: PSym, extname: string) =
setExternName(s, extname) setExternName(s, extname)
incl(s.flags, sfExportc) incl(s.flags, sfExportc)
proc processImportCompilerProc(s: PSym, extname: string) =
setExternName(s, extname)
incl(s.flags, sfImportc)
excl(s.flags, sfForward)
incl(s.loc.flags, lfImportCompilerProc)
proc getStrLitNode(c: PContext, n: PNode): PNode = proc getStrLitNode(c: PContext, n: PNode): PNode =
if n.kind != nkExprColonExpr: if n.kind != nkExprColonExpr:
GlobalError(n.info, errStringLiteralExpected) GlobalError(n.info, errStringLiteralExpected)
@ -401,6 +407,8 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
makeExternExport(sym, getOptionalStr(c, it, sym.name.s)) makeExternExport(sym, getOptionalStr(c, it, sym.name.s))
incl(sym.flags, sfUsed) # avoid wrong hints incl(sym.flags, sfUsed) # avoid wrong hints
of wImportc: makeExternImport(sym, getOptionalStr(c, it, sym.name.s)) of wImportc: makeExternImport(sym, getOptionalStr(c, it, sym.name.s))
of wImportCompilerProc:
processImportCompilerProc(sym, getOptionalStr(c, it, sym.name.s))
of wExtern: setExternName(sym, expectStrLit(c, it)) of wExtern: setExternName(sym, expectStrLit(c, it))
of wAlign: of wAlign:
if sym.typ == nil: invalidPragma(it) if sym.typ == nil: invalidPragma(it)

View file

@ -33,8 +33,9 @@ type
wWithout, wXor, wYield, wWithout, wXor, wYield,
wColon, wColonColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus, wColon, wColonColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus,
wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks, wImportc, wExportc, wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks,
wExtern, wImportCompilerProc,
wImportc, wExportc, wExtern,
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,
@ -79,8 +80,8 @@ const
"yield", "yield",
":", "::", "=", ".", "..", "^", "*", "-", ":", "::", "=", ".", "..", "^", "*", "-",
"magic", "typecheck", "final", "profiler", "objchecks", "importc", "magic", "typecheck", "final", "profiler", "objchecks",
"exportc", "extern", "importcompilerproc", "importc", "exportc", "extern",
"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

@ -178,7 +178,11 @@ proc clean(args: string) =
proc tests(args: string) = proc tests(args: string) =
exec("nimrod cc tests/tester") exec("nimrod cc tests/tester")
exec("tests/tester") exec("tests/tester reject")
exec("tests/tester compile")
exec("tests/tester examples")
exec("tests/tester run")
exec("tests/tester merge")
proc showHelp() = proc showHelp() =
quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)), quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)),

View file

@ -60,12 +60,13 @@ type
const const
GenericSeqSize = (2 * sizeof(int)) GenericSeqSize = (2 * sizeof(int))
proc genericAssign(dest, src: Pointer, mt: PNimType) {.importc.} proc genericAssign(dest, src: Pointer, mt: PNimType) {.importCompilerProc.}
proc genericShallowAssign(dest, src: Pointer, mt: PNimType) {.importc.} proc genericShallowAssign(dest, src: Pointer, mt: PNimType) {.
proc incrSeq(seq: PGenSeq, elemSize: int): PGenSeq {.importc, nodecl.} importCompilerProc.}
proc newObj(typ: PNimType, size: int): pointer {.importc, nodecl.} proc incrSeq(seq: PGenSeq, elemSize: int): PGenSeq {.importCompilerProc.}
proc newSeq(typ: PNimType, len: int): pointer {.importc.} proc newObj(typ: PNimType, size: int): pointer {.importCompilerProc.}
proc objectInit(dest: Pointer, typ: PNimType) {.importc.} proc newSeq(typ: PNimType, len: int): pointer {.importCompilerProc.}
proc objectInit(dest: Pointer, typ: PNimType) {.importCompilerProc.}
template `+!!`(a, b: expr): expr = cast[pointer](cast[TAddress](a) + b) template `+!!`(a, b: expr): expr = cast[pointer](cast[TAddress](a) + b)
@ -228,7 +229,9 @@ iterator fields*(x: TAny): tuple[name: string, any: TAny] =
assert x.rawType.kind in {tyTuple, tyPureObject, tyObject} assert x.rawType.kind in {tyTuple, tyPureObject, tyObject}
var p = x.value var p = x.value
var t = x.rawType var t = x.rawType
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[] # XXX BUG: does not work yet, however is questionable anyway
when false:
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[]
var n = t.node var n = t.node
var ret: seq[tuple[name: cstring, any: TAny]] = @[] var ret: seq[tuple[name: cstring, any: TAny]] = @[]
fieldsAux(p, n, ret) fieldsAux(p, n, ret)
@ -272,7 +275,9 @@ proc getFieldNode(p: pointer, n: ptr TNimNode,
proc `[]=`*(x: TAny, fieldName: string, value: TAny) = proc `[]=`*(x: TAny, fieldName: string, value: TAny) =
## sets a field of `x`; `x` represents an object or a tuple. ## sets a field of `x`; `x` represents an object or a tuple.
var t = x.rawType var t = x.rawType
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[] # XXX BUG: does not work yet, however is questionable anyway
when false:
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[]
assert x.rawType.kind in {tyTuple, tyPureObject, tyObject} assert x.rawType.kind in {tyTuple, tyPureObject, tyObject}
var n = getFieldNode(x.value, t.node, fieldname) var n = getFieldNode(x.value, t.node, fieldname)
if n != nil: if n != nil:
@ -284,7 +289,9 @@ proc `[]=`*(x: TAny, fieldName: string, value: TAny) =
proc `[]`*(x: TAny, fieldName: string): TAny = proc `[]`*(x: TAny, fieldName: string): TAny =
## gets a field of `x`; `x` represents an object or a tuple. ## gets a field of `x`; `x` represents an object or a tuple.
var t = x.rawType var t = x.rawType
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[] # XXX BUG: does not work yet, however is questionable anyway
when false:
if x.rawType.kind == tyObject: t = cast[ptr PNimType](x.value)[]
assert x.rawType.kind in {tyTuple, tyPureObject, tyObject} assert x.rawType.kind in {tyTuple, tyPureObject, tyObject}
var n = getFieldNode(x.value, t.node, fieldname) var n = getFieldNode(x.value, t.node, fieldname)
if n != nil: if n != nil:

View file

@ -10,12 +10,14 @@
## This program verifies Nimrod against the testcases. ## This program verifies Nimrod against the testcases.
import import
parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json parseutils, strutils, pegs, os, osproc, streams, parsecfg, browsers, json,
marshal
const const
cmdTemplate = r"nimrod cc --hints:on $# $#" cmdTemplate = r"nimrod cc --hints:on $# $#"
resultsFile = "testresults.html" resultsFile = "testresults.html"
jsonFile = "testresults.json" jsonFile = "testresults.json"
Usage = "usage: tester reject|compile|examples|run|merge [nimrod options]"
type type
TTestAction = enum TTestAction = enum
@ -141,6 +143,12 @@ proc initResults: TResults =
result.skipped = 0 result.skipped = 0
result.data = "" result.data = ""
proc readResults(filename: string): TResults =
result = marshal.to[TResults](readFile(filename))
proc writeResults(filename: string, r: TResults) =
writeFile(filename, $$r)
proc `$`(x: TResults): string = proc `$`(x: TResults): string =
result = ("Tests passed: $1 / $3 <br />\n" & result = ("Tests passed: $1 / $3 <br />\n" &
"Tests skipped: $2 / $3 <br />\n") % "Tests skipped: $2 / $3 <br />\n") %
@ -275,22 +283,45 @@ proc outputJSON(reject, compile, run: TResults) =
var s = pretty(doc) var s = pretty(doc)
writeFile(jsonFile, s) writeFile(jsonFile, s)
var options = "" proc main(action: string) =
var rejectRes = initResults() const
var compileRes = initResults() compileJson = "compile.json"
var runRes = initResults() runJson = "run.json"
rejectJson = "reject.json"
var options = ""
for i in 2.. paramCount():
add(options, " ")
add(options, paramStr(i))
for i in 1.. paramCount(): case action
add(options, " ") of "reject":
add(options, paramStr(i)) var rejectRes = initResults()
reject(rejectRes, "tests/reject", options)
writeResults(rejectJson, rejectRes)
of "compile":
var compileRes = initResults()
compile(compileRes, "tests/accept/compile/t*.nim", options)
writeResults(compileJson, compileRes)
of "examples":
var compileRes = readResults(compileJson)
compileExample(compileRes, "lib/pure/*.nim", options)
compileExample(compileRes, "examples/*.nim", options)
compileExample(compileRes, "examples/gtk/*.nim", options)
writeResults(compileJson, compileRes)
of "run":
var runRes = initResults()
run(runRes, "tests/accept/run", options)
writeResults(runJson, runRes)
of "merge":
var rejectRes = readResults(rejectJson)
var compileRes = readResults(compileJson)
var runRes = readResults(runJson)
listResults(rejectRes, compileRes, runRes)
outputJSON(rejectRes, compileRes, runRes)
else:
quit usage
reject(rejectRes, "tests/reject", options) if paramCount() == 0:
compile(compileRes, "tests/accept/compile/t*.nim", options) quit usage
compileExample(compileRes, "lib/pure/*.nim", options) main(paramStr(1))
compileExample(compileRes, "examples/*.nim", options)
compileExample(compileRes, "examples/gtk/*.nim", options)
run(runRes, "tests/accept/run", options)
listResults(rejectRes, compileRes, runRes)
outputJSON(rejectRes, compileRes, runRes)
openDefaultBrowser(resultsFile)

View file

@ -3,6 +3,7 @@ High priority (version 0.8.12)
* test threads on windows; thread analysis needs to be even more restrictive! * test threads on windows; thread analysis needs to be even more restrictive!
* implement message passing built-ins: channels/queues * implement message passing built-ins: channels/queues
* bug: {:}.toTable[int, string]() * bug: {:}.toTable[int, string]()
* test tester
version 0.9.0 version 0.9.0