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
parent 3e91b456e5
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
lfDynamicLib, # link symbol to dynamic library
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
OnUnknown, # location is unknown (stack, heap or static)
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,
mInSet:
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
if lfNoDecl notin opr.loc.flags:
discard cgsym(p.module, opr.loc.r.ropeToStr)

View File

@@ -666,17 +666,21 @@ proc genProcPrototype(m: BModule, sym: PSym) =
proc genProcNoForward(m: BModule, prc: PSym) =
fillProcLoc(prc)
useHeader(m, prc)
if lfImportCompilerProc in prc.loc.flags:
# dependency to a compilerproc:
discard cgsym(m, prc.name.s)
return
genProcPrototype(m, prc)
if lfNoDecl in prc.loc.Flags: return
if prc.typ.callConv == ccInline:
if lfNoDecl in prc.loc.Flags: nil
elif prc.typ.callConv == ccInline:
# 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
# a check for ``m.declaredThings``.
if not ContainsOrIncl(m.declaredThings, prc.id): genProcAux(m, prc)
elif lfDynamicLib in prc.loc.flags:
elif lfDynamicLib in prc.loc.flags:
if not ContainsOrIncl(gGeneratedSyms, prc.id):
SymInDynamicLib(findPendingModule(m, prc), prc)
elif not (sfImportc in prc.flags):
elif sfImportc notin prc.flags:
if not ContainsOrIncl(gGeneratedSyms, prc.id):
genProcAux(findPendingModule(m, prc), prc)

View File

@@ -22,7 +22,7 @@ const
procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
wBorrow, wExtern}
wBorrow, wExtern, wImportCompilerProc}
converterPragmas* = procPragmas
methodPragmas* = procPragmas
macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
@@ -80,6 +80,12 @@ proc MakeExternExport(s: PSym, extname: string) =
setExternName(s, extname)
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 =
if n.kind != nkExprColonExpr:
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))
incl(sym.flags, sfUsed) # avoid wrong hints
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 wAlign:
if sym.typ == nil: invalidPragma(it)

View File

@@ -33,8 +33,9 @@ type
wWithout, wXor, wYield,
wColon, wColonColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus,
wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks, wImportc, wExportc,
wExtern,
wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks,
wImportCompilerProc,
wImportc, wExportc, wExtern,
wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader,
wNosideeffect, wNoreturn, wMerge, wLib, wDynlib, wCompilerproc, wProcVar,
wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef,
@@ -79,8 +80,8 @@ const
"yield",
":", "::", "=", ".", "..", "^", "*", "-",
"magic", "typecheck", "final", "profiler", "objchecks", "importc",
"exportc", "extern",
"magic", "typecheck", "final", "profiler", "objchecks",
"importcompilerproc", "importc", "exportc", "extern",
"align", "nodecl", "pure", "volatile", "register", "sideeffect",
"header", "nosideeffect", "noreturn", "merge", "lib", "dynlib",
"compilerproc", "procvar", "fatal", "error", "warning", "hint", "line",

View File

@@ -178,7 +178,11 @@ proc clean(args: string) =
proc tests(args: string) =
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() =
quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)),

View File

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

View File

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

View File

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