NIR: VM + refactorings (#22835)

This commit is contained in:
Andreas Rumpf
2023-10-29 14:47:22 +01:00
committed by GitHub
parent 94ffc18332
commit 0c26d19e22
11 changed files with 1530 additions and 641 deletions

View File

@@ -221,7 +221,7 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode; result: var Rope) =
let (x, y) = genOpenArraySlice(p, q, formalType, n.typ[0])
result.add x & ", " & y
else:
var a: TLoc = initLocExpr(p, if n.kind == nkHiddenStdConv: n[1] else: n)
var a = initLocExpr(p, if n.kind == nkHiddenStdConv: n[1] else: n)
case skipTypes(a.t, abstractVar+{tyStatic}).kind
of tyOpenArray, tyVarargs:
if reifiedOpenArray(n):
@@ -277,7 +277,7 @@ proc literalsNeedsTmp(p: BProc, a: TLoc): TLoc =
genAssignment(p, result, a, {})
proc genArgStringToCString(p: BProc, n: PNode; result: var Rope; needsTmp: bool) {.inline.} =
var a: TLoc = initLocExpr(p, n[0])
var a = initLocExpr(p, n[0])
appcg(p.module, result, "#nimToCStringConv($1)", [withTmpIfNeeded(p, a, needsTmp).rdLoc])
proc genArg(p: BProc, n: PNode, param: PSym; call: PNode; result: var Rope; needsTmp = false) =
@@ -287,7 +287,7 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode; result: var Rope; need
elif skipTypes(param.typ, abstractVar).kind in {tyOpenArray, tyVarargs}:
var n = if n.kind != nkHiddenAddr: n else: n[0]
openArrayLoc(p, param.typ, n, result)
elif ccgIntroducedPtr(p.config, param, call[0].typ[0]) and
elif ccgIntroducedPtr(p.config, param, call[0].typ[0]) and
(optByRef notin param.options or not p.module.compileToCpp):
a = initLocExpr(p, n)
if n.kind in {nkCharLit..nkNilLit}:
@@ -417,7 +417,7 @@ proc addActualSuffixForHCR(res: var Rope, module: PSym, sym: PSym) =
proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
# this is a hotspot in the compiler
var op: TLoc = initLocExpr(p, ri[0])
var op = initLocExpr(p, ri[0])
# getUniqueType() is too expensive here:
var typ = skipTypes(ri[0].typ, abstractInstOwned)
assert(typ.kind == tyProc)
@@ -439,7 +439,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
const PatProc = "$1.ClE_0? $1.ClP_0($3$1.ClE_0):(($4)($1.ClP_0))($2)"
const PatIter = "$1.ClP_0($3$1.ClE_0)" # we know the env exists
var op: TLoc = initLocExpr(p, ri[0])
var op = initLocExpr(p, ri[0])
# getUniqueType() is too expensive here:
var typ = skipTypes(ri[0].typ, abstractInstOwned)
@@ -672,7 +672,7 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType; result: var Ro
result.add(substr(pat, start, i - 1))
proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op: TLoc = initLocExpr(p, ri[0])
var op = initLocExpr(p, ri[0])
# getUniqueType() is too expensive here:
var typ = skipTypes(ri[0].typ, abstractInst)
assert(typ.kind == tyProc)
@@ -716,7 +716,7 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
# generates a crappy ObjC call
var op: TLoc = initLocExpr(p, ri[0])
var op = initLocExpr(p, ri[0])
var pl = "["
# getUniqueType() is too expensive here:
var typ = skipTypes(ri[0].typ, abstractInst)

View File

@@ -98,6 +98,7 @@ type
backendFlagsSection
aliveSymsSection # beware, this is stored in a `.alivesyms` file.
sideChannelSection
symnamesSection
RodFileError* = enum
ok, tooBig, cannotOpen, ioFailure, wrongHeader, wrongSection, configMismatch,

File diff suppressed because it is too large Load Diff

View File

@@ -12,8 +12,9 @@
from os import addFileExt, `/`, createDir
import std / assertions
import ".." / [ast, modulegraphs, renderer, transf, options, msgs, lineinfos]
import nirtypes, nirinsts, ast2ir, nirlineinfos
import nirtypes, nirinsts, ast2ir, nirlineinfos, nirfiles, nirvm
import ".." / ic / [rodfiles, bitabs]
@@ -22,13 +23,18 @@ type
m: ModuleCon
c: ProcCon
oldErrorCount: int
bytecode: Bytecode
proc newCtx*(module: PSym; g: ModuleGraph; idgen: IdGenerator): PCtx =
let m = initModuleCon(g, g.config, idgen, module)
PCtx(m: m, c: initProcCon(m, nil, g.config), idgen: idgen)
var lit = Literals()
var nirm = (ref NirModule)(types: initTypeGraph(lit), lit: lit)
var m = initModuleCon(g, g.config, idgen, module, nirm)
m.noModularity = true
PCtx(m: m, c: initProcCon(m, nil, g.config), idgen: idgen, bytecode: initBytecode(nirm))
proc refresh*(c: PCtx; module: PSym; idgen: IdGenerator) =
c.m = initModuleCon(c.m.graph, c.m.graph.config, idgen, module)
#c.m = initModuleCon(c.m.graph, c.m.graph.config, idgen, module, c.m.nirm)
#c.m.noModularity = true
c.c = initProcCon(c.m, nil, c.m.graph.config)
c.idgen = idgen
@@ -46,14 +52,13 @@ proc setupNirReplGen*(graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPa
proc evalStmt(c: PCtx; n: PNode) =
let n = transformExpr(c.m.graph, c.idgen, c.m.module, n)
let pc = genStmt(c.c, n)
var res = ""
if pc < c.c.code.len:
toString c.c.code, NodePos(pc), c.m.lit.strings, c.m.lit.numbers, res
#var res = ""
#toString c.m.nirm.code, NodePos(pc), c.m.nirm.lit.strings, c.m.nirm.lit.numbers, c.m.symnames, res
#res.add "\n--------------------------\n"
#toString res, c.m.types.g
echo res
if pc.int < c.m.nirm.code.len:
execCode c.bytecode, c.m.nirm.code, pc
#echo res
proc runCode*(c: PPassContext; n: PNode): PNode =
let c = PCtx(c)
@@ -71,7 +76,9 @@ type
c: ProcCon
proc openNirBackend*(g: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext =
let m = initModuleCon(g, g.config, idgen, module)
var lit = Literals()
var nirm = (ref NirModule)(types: initTypeGraph(lit), lit: lit)
let m = initModuleCon(g, g.config, idgen, module, nirm)
NirPassContext(m: m, c: initProcCon(m, nil, g.config), idgen: idgen)
proc gen(c: NirPassContext; n: PNode) =
@@ -89,27 +96,9 @@ proc closeNirBackend*(c: PPassContext; finalNode: PNode) =
let nimcache = getNimcacheDir(c.c.config).string
createDir nimcache
let outp = nimcache / c.m.module.name.s.addFileExt("nir")
var r = rodfiles.create(outp)
#c.m.nirm.code = move c.c.code
try:
r.storeHeader(nirCookie)
r.storeSection stringsSection
r.store c.m.lit.strings
r.storeSection numbersSection
r.store c.m.lit.numbers
r.storeSection bodiesSection
r.store c.c.code
r.storeSection typesSection
r.store c.m.types.g
r.storeSection sideChannelSection
r.store c.m.man
finally:
r.close()
if r.err != ok:
rawMessage(c.c.config, errFatal, "serialization failed: " & outp)
else:
store c.m.nirm[], outp
echo "created: ", outp
except IOError:
rawMessage(c.c.config, errFatal, "serialization failed: " & outp)

View File

@@ -10,41 +10,46 @@
## Nir Compiler. Currently only supports a "view" command.
import ".." / ic / [bitabs, rodfiles]
import nirinsts, nirtypes, nirlineinfos
import nirinsts, nirtypes, nirlineinfos, nirfiles #, nir2gcc
proc view(filename: string) =
var lit = Literals()
var r = rodfiles.open(filename)
var code = default Tree
var man = default LineInfoManager
var types = initTypeGraph(lit)
try:
r.loadHeader(nirCookie)
r.loadSection stringsSection
r.load lit.strings
r.loadSection numbersSection
r.load lit.numbers
r.loadSection bodiesSection
r.load code
r.loadSection typesSection
r.load types
r.loadSection sideChannelSection
r.load man
finally:
r.close()
let m = load(filename)
var res = ""
allTreesToString code, lit.strings, lit.numbers, res
allTreesToString m.code, m.lit.strings, m.lit.numbers, m.symnames, res
res.add "\n# TYPES\n"
nirtypes.toString res, types
nirtypes.toString res, m.types
echo res
import std / os
proc libgcc(filename: string) =
let m = load(filename)
#gcc m, filename
view paramStr(1)
import std / [syncio, parseopt]
proc writeHelp =
echo """Usage: nirc view|gcc <file.nir>"""
quit 0
proc main =
var inp = ""
var cmd = ""
for kind, key, val in getopt():
case kind
of cmdArgument:
if cmd.len == 0: cmd = key
elif inp.len == 0: inp = key
else: quit "Error: too many arguments"
of cmdLongOption, cmdShortOption:
case key
of "help", "h": writeHelp()
of "version", "v": stdout.write "1.0\n"
of cmdEnd: discard
if inp.len == 0:
quit "Error: no input file specified"
case cmd
of "", "view":
view inp
of "gcc":
libgcc inp
main()

73
compiler/nir/nirfiles.nim Normal file
View File

@@ -0,0 +1,73 @@
#
#
# The Nim Compiler
# (c) Copyright 2023 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
import ".." / ic / [bitabs, rodfiles]
import nirinsts, nirtypes, nirlineinfos
type
NirModule* = object
code*: Tree
man*: LineInfoManager
types*: TypeGraph
lit*: Literals
symnames*: SymNames
proc load*(filename: string): NirModule =
let lit = Literals()
result = NirModule(lit: lit, types: initTypeGraph(lit))
var r = rodfiles.open(filename)
try:
r.loadHeader(nirCookie)
r.loadSection stringsSection
r.load result.lit.strings
r.loadSection numbersSection
r.load result.lit.numbers
r.loadSection bodiesSection
r.load result.code
r.loadSection typesSection
r.load result.types
r.loadSection sideChannelSection
r.load result.man
r.loadSection symnamesSection
r.load result.symnames
finally:
r.close()
proc store*(m: NirModule; outp: string) =
var r = rodfiles.create(outp)
try:
r.storeHeader(nirCookie)
r.storeSection stringsSection
r.store m.lit.strings
r.storeSection numbersSection
r.store m.lit.numbers
r.storeSection bodiesSection
r.store m.code
r.storeSection typesSection
r.store m.types
r.storeSection sideChannelSection
r.store m.man
r.storeSection symnamesSection
r.store m.symnames
finally:
r.close()
if r.err != ok:
raise newException(IOError, "could store into: " & outp)

View File

@@ -57,6 +57,7 @@ type
SummonGlobal,
SummonThreadLocal,
Summon, # x = Summon Typed <Type ID>; x begins to live
SummonResult,
SummonParam,
SummonConst,
Kill, # `Kill x`: scope end for `x`
@@ -110,6 +111,7 @@ type
type
PragmaKey* = enum
FastCall, StdCall, CDeclCall, SafeCall, SysCall, InlineCall, NoinlineCall, ThisCall, NoCall,
CoreName,
ExternName,
HeaderImport,
DllImport,
@@ -167,7 +169,7 @@ const
type
Instr* = object # 8 bytes
x: uint32
info: PackedLineInfo
info*: PackedLineInfo
template kind*(n: Instr): Opcode = Opcode(n.x and OpcodeMask)
template operand(n: Instr): uint32 = (n.x shr OpcodeBits)
@@ -234,6 +236,10 @@ proc nextChild(tree: Tree; pos: var int) {.inline.} =
else:
inc pos
proc next*(tree: Tree; pos: var NodePos) {.inline.} = nextChild tree, int(pos)
template firstSon*(n: NodePos): NodePos = NodePos(n.int+1)
iterator sons*(tree: Tree; n: NodePos): NodePos =
var pos = n.int
assert tree.nodes[pos].kind > LastAtomicValue
@@ -243,6 +249,16 @@ iterator sons*(tree: Tree; n: NodePos): NodePos =
yield NodePos pos
nextChild tree, pos
iterator sonsFrom1*(tree: Tree; n: NodePos): NodePos =
var pos = n.int
assert tree.nodes[pos].kind > LastAtomicValue
let last = pos + tree.nodes[pos].rawSpan
inc pos
nextChild tree, pos
while pos < last:
yield NodePos pos
nextChild tree, pos
template `[]`*(t: Tree; n: NodePos): Instr = t.nodes[n.int]
proc span(tree: Tree; pos: int): int {.inline.} =
@@ -257,9 +273,46 @@ proc copyTree*(dest: var Tree; src: Tree) =
for i in 0..<L:
dest.nodes[d+i] = src.nodes[pos+i]
proc sons2*(tree: Tree; n: NodePos): (NodePos, NodePos) =
assert(not isAtom(tree, n.int))
let a = n.int+1
let b = a + span(tree, a)
result = (NodePos a, NodePos b)
proc sons3*(tree: Tree; n: NodePos): (NodePos, NodePos, NodePos) =
assert(not isAtom(tree, n.int))
let a = n.int+1
let b = a + span(tree, a)
let c = b + span(tree, b)
result = (NodePos a, NodePos b, NodePos c)
proc typeId*(ins: Instr): TypeId {.inline.} =
assert ins.kind == Typed
result = TypeId(ins.operand)
proc symId*(ins: Instr): SymId {.inline.} =
assert ins.kind in {SymUse, SymDef}
result = SymId(ins.operand)
proc immediateVal*(ins: Instr): int {.inline.} =
assert ins.kind == ImmediateVal
result = cast[int](ins.operand)
proc litId*(ins: Instr): LitId {.inline.} =
assert ins.kind in {StrVal, IntVal}
result = LitId(ins.operand)
type
LabelId* = distinct int
proc `==`*(a, b: LabelId): bool {.borrow.}
proc hash*(a: LabelId): Hash {.borrow.}
proc label*(ins: Instr): LabelId {.inline.} =
assert ins.kind in {Label, LoopLabel, Goto, GotoLoop, CheckedGoto}
result = LabelId(ins.operand)
proc newLabel*(labelGen: var int): LabelId {.inline.} =
result = LabelId labelGen
inc labelGen
@@ -297,7 +350,7 @@ proc addTyped*(t: var Tree; info: PackedLineInfo; typ: TypeId) {.inline.} =
proc addSummon*(t: var Tree; info: PackedLineInfo; s: SymId; typ: TypeId; opc = Summon) {.inline.} =
assert typ.int >= 0
assert opc in {Summon, SummonConst, SummonGlobal, SummonThreadLocal, SummonParam}
assert opc in {Summon, SummonConst, SummonGlobal, SummonThreadLocal, SummonParam, SummonResult}
let x = prepare(t, info, opc)
t.nodes.add Instr(x: toX(Typed, uint32(typ)), info: info)
t.nodes.add Instr(x: toX(SymDef, uint32(s)), info: info)
@@ -345,7 +398,32 @@ proc escapeToNimLit(s: string; result: var string) =
result.add c
result.add '"'
type
SymNames* = object
s: seq[LitId]
proc `[]=`*(t: var SymNames; key: SymId; val: LitId) =
let k = int(key)
if k >= t.s.len: t.s.setLen k+1
t.s[k] = val
proc `[]`*(t: SymNames; key: SymId): LitId =
let k = int(key)
if k < t.s.len: result = t.s[k]
else: result = LitId(0)
template localName(s: SymId): string =
let name = names[s]
if name != LitId(0):
strings[name]
else:
$s.int
proc store*(r: var RodFile; t: SymNames) = storeSeq(r, t.s)
proc load*(r: var RodFile; t: var SymNames) = loadSeq(r, t.s)
proc toString*(t: Tree; pos: NodePos; strings: BiTable[string]; integers: BiTable[int64];
names: SymNames;
r: var string; nesting = 0) =
if r.len > 0 and r[r.len-1] notin {' ', '\n', '(', '[', '{'}:
r.add ' '
@@ -361,10 +439,10 @@ proc toString*(t: Tree; pos: NodePos; strings: BiTable[string]; integers: BiTabl
escapeToNimLit(strings[LitId t[pos].operand], r)
of SymDef:
r.add "SymDef "
r.add $t[pos].operand
r.add localName(SymId t[pos].operand)
of SymUse:
r.add "SymUse "
r.add $t[pos].operand
r.add localName(SymId t[pos].operand)
of PragmaId:
r.add $cast[PragmaKey](t[pos].operand)
of Typed:
@@ -374,7 +452,11 @@ proc toString*(t: Tree; pos: NodePos; strings: BiTable[string]; integers: BiTabl
of NilVal:
r.add "NilVal"
of Label:
r.add "L"
# undo the nesting:
var spaces = r.len-1
while spaces >= 0 and r[spaces] == ' ': dec spaces
r.setLen spaces+1
r.add "\n L"
r.add $t[pos].operand
of Goto, CheckedGoto, LoopLabel, GotoLoop:
r.add $t[pos].kind
@@ -385,16 +467,17 @@ proc toString*(t: Tree; pos: NodePos; strings: BiTable[string]; integers: BiTabl
r.add "{\n"
for i in 0..<(nesting+1)*2: r.add ' '
for p in sons(t, pos):
toString t, p, strings, integers, r, nesting+1
toString t, p, strings, integers, names, r, nesting+1
r.add "\n"
for i in 0..<nesting*2: r.add ' '
r.add "}"
proc allTreesToString*(t: Tree; strings: BiTable[string]; integers: BiTable[int64];
names: SymNames;
r: var string) =
var i = 0
while i < t.len:
toString t, NodePos(i), strings, integers, r
toString t, NodePos(i), strings, integers, names, r
nextChild t, i
type

View File

@@ -42,6 +42,11 @@ type
template kind*(n: TypeNode): NirTypeKind = NirTypeKind(n.x and TypeKindMask)
template operand(n: TypeNode): uint32 = (n.x shr TypeKindBits)
proc integralBits*(n: TypeNode): int {.inline.} =
# Number of bits in the IntTy, etc. Only valid for integral types.
assert n.kind in {IntTy, UIntTy, FloatTy, BoolTy, CharTy}
result = int(n.operand)
template toX(k: NirTypeKind; operand: uint32): uint32 =
uint32(k) or (operand shl TypeKindBits)
@@ -150,6 +155,10 @@ proc elementType*(tree: TypeGraph; n: TypeId): TypeId {.inline.} =
assert tree[n].kind in {APtrTy, UPtrTy, AArrayPtrTy, UArrayPtrTy, ArrayTy, LastArrayTy}
result = TypeId(n.int+1)
proc litId*(n: TypeNode): LitId {.inline.} =
assert n.kind in {NameVal, IntVal, SizeVal, AlignVal, OffsetVal, AnnotationVal, ObjectTy, UnionTy}
result = LitId(n.operand)
proc kind*(tree: TypeGraph; n: TypeId): NirTypeKind {.inline.} = tree[n].kind
proc span(tree: TypeGraph; pos: int): int {.inline.} =
@@ -170,7 +179,8 @@ proc sons3(tree: TypeGraph; n: TypeId): (TypeId, TypeId, TypeId) =
proc arrayLen*(tree: TypeGraph; n: TypeId): BiggestInt =
assert tree[n].kind == ArrayTy
result = tree.lit.numbers[LitId tree[n].operand]
let (_, b) = sons2(tree, n)
result = tree.lit.numbers[LitId tree[b].operand]
proc openType*(tree: var TypeGraph; kind: NirTypeKind): TypePatchPos =
assert kind in {APtrTy, UPtrTy, AArrayPtrTy, UArrayPtrTy,
@@ -227,6 +237,10 @@ proc addNominalType*(tree: var TypeGraph; kind: NirTypeKind; name: string) =
assert kind in {ObjectTy, UnionTy}
tree.nodes.add TypeNode(x: toX(kind, tree.lit.strings.getOrIncl(name)))
proc getTypeTag*(tree: TypeGraph; t: TypeId): string =
assert tree[t].kind in {ObjectTy, UnionTy}
result = tree.lit.strings[LitId tree[t].operand]
proc addVarargs*(tree: var TypeGraph) =
tree.nodes.add TypeNode(x: toX(VarargsTy, 0'u32))
@@ -237,7 +251,7 @@ proc getFloat128Type*(tree: var TypeGraph): TypeId =
proc addBuiltinType*(g: var TypeGraph; id: TypeId) =
g.nodes.add g[id]
template firstSon(n: TypeId): TypeId = TypeId(n.int+1)
template firstSon*(n: TypeId): TypeId = TypeId(n.int+1)
proc addType*(g: var TypeGraph; t: TypeId) =
# We cannot simply copy `*Decl` nodes. We have to introduce `*Ty` nodes instead:
@@ -360,7 +374,9 @@ proc toString*(dest: var string; g: TypeGraph; i: TypeId) =
dest.add g.lit.strings[LitId g[i].operand]
of ProcTy:
dest.add "proc["
for t in sons(g, i): toString(dest, g, t)
for t in sons(g, i):
dest.add ' '
toString(dest, g, t)
dest.add "]"
of ObjectDecl:
dest.add "object["
@@ -399,6 +415,12 @@ proc toString*(dest: var string; g: TypeGraph) =
dest.add '\n'
nextChild g, i
iterator allTypes*(g: TypeGraph; start = 0): TypeId =
var i = start
while i < g.len:
yield TypeId i
nextChild g, i
proc `$`(g: TypeGraph): string =
result = ""
toString(result, g)

File diff suppressed because it is too large Load Diff

View File

@@ -15,11 +15,11 @@ type
TypesCon* = object
processed: Table[ItemId, TypeId]
recursionCheck: HashSet[ItemId]
g*: TypeGraph
conf: ConfigRef
stringType: TypeId
proc initTypesCon*(conf: ConfigRef; lit: Literals): TypesCon =
TypesCon(g: initTypeGraph(lit), conf: conf)
proc initTypesCon*(conf: ConfigRef): TypesCon =
TypesCon(conf: conf, stringType: TypeId(-1))
proc mangle(c: var TypesCon; t: PType): string =
result = $sighashes.hashType(t, c.conf)
@@ -30,131 +30,131 @@ template cached(c: var TypesCon; t: PType; body: untyped) =
body
c.processed[t.itemId] = result
proc typeToIr*(c: var TypesCon; t: PType): TypeId
proc typeToIr*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId
proc collectFieldTypes(c: var TypesCon; n: PNode; dest: var Table[ItemId, TypeId]) =
proc collectFieldTypes(c: var TypesCon; g: var TypeGraph; n: PNode; dest: var Table[ItemId, TypeId]) =
case n.kind
of nkRecList:
for i in 0..<n.len:
collectFieldTypes(c, n[i], dest)
collectFieldTypes(c, g, n[i], dest)
of nkRecCase:
assert(n[0].kind == nkSym)
collectFieldTypes(c, n[0], dest)
collectFieldTypes(c, g, n[0], dest)
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
collectFieldTypes c, lastSon(n[i]), dest
collectFieldTypes c, g, lastSon(n[i]), dest
else: discard
of nkSym:
dest[n.sym.itemId] = typeToIr(c, n.sym.typ)
dest[n.sym.itemId] = typeToIr(c, g, n.sym.typ)
else:
assert false, "unknown node kind: " & $n.kind
proc objectToIr(c: var TypesCon; n: PNode; fieldTypes: Table[ItemId, TypeId]; unionId: var int) =
proc objectToIr(c: var TypesCon; g: var TypeGraph; n: PNode; fieldTypes: Table[ItemId, TypeId]; unionId: var int) =
case n.kind
of nkRecList:
for i in 0..<n.len:
objectToIr(c, n[i], fieldTypes, unionId)
objectToIr(c, g, n[i], fieldTypes, unionId)
of nkRecCase:
assert(n[0].kind == nkSym)
objectToIr(c, n[0], fieldTypes, unionId)
let u = openType(c.g, UnionDecl)
c.g.addName "u_" & $unionId
objectToIr(c, g, n[0], fieldTypes, unionId)
let u = openType(g, UnionDecl)
g.addName "u_" & $unionId
inc unionId
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
let subObj = openType(c.g, ObjectDecl)
c.g.addName "uo_" & $unionId & "_" & $i
objectToIr c, lastSon(n[i]), fieldTypes, unionId
sealType(c.g, subObj)
let subObj = openType(g, ObjectDecl)
g.addName "uo_" & $unionId & "_" & $i
objectToIr c, g, lastSon(n[i]), fieldTypes, unionId
sealType(g, subObj)
else: discard
sealType(c.g, u)
sealType(g, u)
of nkSym:
c.g.addField n.sym.name.s & "_" & $n.sym.position, fieldTypes[n.sym.itemId], n.sym.offset
g.addField n.sym.name.s & "_" & $n.sym.position, fieldTypes[n.sym.itemId], n.sym.offset
else:
assert false, "unknown node kind: " & $n.kind
proc objectToIr(c: var TypesCon; t: PType): TypeId =
proc objectToIr(c: var TypesCon; g: var TypeGraph; t: PType): TypeId =
if t[0] != nil:
# ensure we emitted the base type:
discard typeToIr(c, t[0])
discard typeToIr(c, g, t[0])
var unionId = 0
var fieldTypes = initTable[ItemId, TypeId]()
collectFieldTypes c, t.n, fieldTypes
let obj = openType(c.g, ObjectDecl)
c.g.addName mangle(c, t)
c.g.addSize c.conf.getSize(t)
c.g.addAlign c.conf.getAlign(t)
collectFieldTypes c, g, t.n, fieldTypes
let obj = openType(g, ObjectDecl)
g.addName mangle(c, t)
g.addSize c.conf.getSize(t)
g.addAlign c.conf.getAlign(t)
if t[0] != nil:
c.g.addNominalType(ObjectTy, mangle(c, t[0]))
g.addNominalType(ObjectTy, mangle(c, t[0]))
else:
c.g.addBuiltinType VoidId # object does not inherit
g.addBuiltinType VoidId # object does not inherit
if not lacksMTypeField(t):
let f2 = c.g.openType FieldDecl
let voidPtr = openType(c.g, APtrTy)
c.g.addBuiltinType(VoidId)
sealType(c.g, voidPtr)
c.g.addOffset 0 # type field is always at offset 0
c.g.addName "m_type"
sealType(c.g, f2) # FieldDecl
let f2 = g.openType FieldDecl
let voidPtr = openType(g, APtrTy)
g.addBuiltinType(VoidId)
sealType(g, voidPtr)
g.addOffset 0 # type field is always at offset 0
g.addName "m_type"
sealType(g, f2) # FieldDecl
objectToIr c, t.n, fieldTypes, unionId
result = finishType(c.g, obj)
objectToIr c, g, t.n, fieldTypes, unionId
result = finishType(g, obj)
proc objectHeaderToIr(c: var TypesCon; t: PType): TypeId =
result = c.g.nominalType(ObjectTy, mangle(c, t))
proc objectHeaderToIr(c: var TypesCon; g: var TypeGraph; t: PType): TypeId =
result = g.nominalType(ObjectTy, mangle(c, t))
proc tupleToIr(c: var TypesCon; t: PType): TypeId =
proc tupleToIr(c: var TypesCon; g: var TypeGraph; t: PType): TypeId =
var fieldTypes = newSeq[TypeId](t.len)
for i in 0..<t.len:
fieldTypes[i] = typeToIr(c, t[i])
let obj = openType(c.g, ObjectDecl)
c.g.addName mangle(c, t)
c.g.addSize c.conf.getSize(t)
c.g.addAlign c.conf.getAlign(t)
fieldTypes[i] = typeToIr(c, g, t[i])
let obj = openType(g, ObjectDecl)
g.addName mangle(c, t)
g.addSize c.conf.getSize(t)
g.addAlign c.conf.getAlign(t)
var accum = OffsetAccum(maxAlign: 1)
for i in 0..<t.len:
let child = t[i]
c.g.addField "f_" & $i, fieldTypes[i], accum.offset
g.addField "f_" & $i, fieldTypes[i], accum.offset
computeSizeAlign(c.conf, child)
accum.align(child.align)
accum.inc(int32(child.size))
result = finishType(c.g, obj)
result = finishType(g, obj)
proc procToIr(c: var TypesCon; t: PType; addEnv = false): TypeId =
proc procToIr(c: var TypesCon; g: var TypeGraph; t: PType; addEnv = false): TypeId =
var fieldTypes = newSeq[TypeId](0)
for i in 0..<t.len:
if t[i] == nil or not isCompileTimeOnly(t[i]):
fieldTypes.add typeToIr(c, t[i])
let obj = openType(c.g, ProcTy)
fieldTypes.add typeToIr(c, g, t[i])
let obj = openType(g, ProcTy)
case t.callConv
of ccNimCall, ccFastCall, ccClosure: c.g.addAnnotation "__fastcall"
of ccStdCall: c.g.addAnnotation "__stdcall"
of ccCDecl: c.g.addAnnotation "__cdecl"
of ccSafeCall: c.g.addAnnotation "__safecall"
of ccSysCall: c.g.addAnnotation "__syscall"
of ccInline: c.g.addAnnotation "__inline"
of ccNoInline: c.g.addAnnotation "__noinline"
of ccThisCall: c.g.addAnnotation "__thiscall"
of ccNoConvention: c.g.addAnnotation ""
of ccNimCall, ccFastCall, ccClosure: g.addAnnotation "__fastcall"
of ccStdCall: g.addAnnotation "__stdcall"
of ccCDecl: g.addAnnotation "__cdecl"
of ccSafeCall: g.addAnnotation "__safecall"
of ccSysCall: g.addAnnotation "__syscall"
of ccInline: g.addAnnotation "__inline"
of ccNoInline: g.addAnnotation "__noinline"
of ccThisCall: g.addAnnotation "__thiscall"
of ccNoConvention: g.addAnnotation ""
for i in 0..<fieldTypes.len:
c.g.addType fieldTypes[i]
g.addType fieldTypes[i]
if addEnv:
let a = openType(c.g, APtrTy)
c.g.addBuiltinType(VoidId)
sealType(c.g, a)
let a = openType(g, APtrTy)
g.addBuiltinType(VoidId)
sealType(g, a)
if tfVarargs in t.flags:
c.g.addVarargs()
result = finishType(c.g, obj)
g.addVarargs()
result = finishType(g, obj)
proc nativeInt(c: TypesCon): TypeId =
case c.conf.target.intSize
@@ -162,65 +162,65 @@ proc nativeInt(c: TypesCon): TypeId =
of 4: result = Int32Id
else: result = Int64Id
proc openArrayPayloadType*(c: var TypesCon; t: PType): TypeId =
proc openArrayPayloadType*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId =
let e = lastSon(t)
let elementType = typeToIr(c, e)
let arr = c.g.openType AArrayPtrTy
c.g.addType elementType
result = finishType(c.g, arr) # LastArrayTy
let elementType = typeToIr(c, g, e)
let arr = g.openType AArrayPtrTy
g.addType elementType
result = finishType(g, arr) # LastArrayTy
proc openArrayToIr(c: var TypesCon; t: PType): TypeId =
proc openArrayToIr(c: var TypesCon; g: var TypeGraph; t: PType): TypeId =
# object (a: ArrayPtr[T], len: int)
let e = lastSon(t)
let mangledBase = mangle(c, e)
let typeName = "NimOpenArray" & mangledBase
let elementType = typeToIr(c, e)
let elementType = typeToIr(c, g, e)
#assert elementType.int >= 0, typeToString(t)
let p = openType(c.g, ObjectDecl)
c.g.addName typeName
c.g.addSize c.conf.target.ptrSize*2
c.g.addAlign c.conf.target.ptrSize
let p = openType(g, ObjectDecl)
g.addName typeName
g.addSize c.conf.target.ptrSize*2
g.addAlign c.conf.target.ptrSize
let f = c.g.openType FieldDecl
let arr = c.g.openType AArrayPtrTy
c.g.addType elementType
sealType(c.g, arr) # LastArrayTy
c.g.addOffset 0
c.g.addName "data"
sealType(c.g, f) # FieldDecl
let f = g.openType FieldDecl
let arr = g.openType AArrayPtrTy
g.addType elementType
sealType(g, arr) # LastArrayTy
g.addOffset 0
g.addName "data"
sealType(g, f) # FieldDecl
c.g.addField "len", c.nativeInt, c.conf.target.ptrSize
g.addField "len", c.nativeInt, c.conf.target.ptrSize
result = finishType(c.g, p) # ObjectDecl
result = finishType(g, p) # ObjectDecl
proc strPayloadType(c: var TypesCon): string =
result = "NimStrPayload"
let p = openType(c.g, ObjectDecl)
c.g.addName result
c.g.addSize c.conf.target.ptrSize*2
c.g.addAlign c.conf.target.ptrSize
proc strPayloadType(c: var TypesCon; g: var TypeGraph): (string, TypeId) =
result = ("NimStrPayload", TypeId(-1))
let p = openType(g, ObjectDecl)
g.addName result[0]
g.addSize c.conf.target.ptrSize*2
g.addAlign c.conf.target.ptrSize
c.g.addField "cap", c.nativeInt, 0
g.addField "cap", c.nativeInt, 0
let f = c.g.openType FieldDecl
let arr = c.g.openType LastArrayTy
c.g.addBuiltinType Char8Id
sealType(c.g, arr) # LastArrayTy
c.g.addOffset c.conf.target.ptrSize # comes after the len field
c.g.addName "data"
sealType(c.g, f) # FieldDecl
let f = g.openType FieldDecl
let arr = g.openType LastArrayTy
g.addBuiltinType Char8Id
result[1] = finishType(g, arr) # LastArrayTy
g.addOffset c.conf.target.ptrSize # comes after the len field
g.addName "data"
sealType(g, f) # FieldDecl
sealType(c.g, p)
sealType(g, p)
proc strPayloadPtrType*(c: var TypesCon): TypeId =
let mangled = strPayloadType(c)
let ffp = c.g.openType APtrTy
c.g.addNominalType ObjectTy, mangled
result = finishType(c.g, ffp) # APtrTy
proc strPayloadPtrType*(c: var TypesCon; g: var TypeGraph): (TypeId, TypeId) =
let (mangled, arrayType) = strPayloadType(c, g)
let ffp = g.openType APtrTy
g.addNominalType ObjectTy, mangled
result = (finishType(g, ffp), arrayType) # APtrTy
proc stringToIr(c: var TypesCon): TypeId =
proc stringToIr(c: var TypesCon; g: var TypeGraph): TypeId =
#[
NimStrPayload = object
@@ -232,86 +232,86 @@ proc stringToIr(c: var TypesCon): TypeId =
p: ptr NimStrPayload
]#
let payload = strPayloadType(c)
let payload = strPayloadType(c, g)
let str = openType(c.g, ObjectDecl)
c.g.addName "NimStringV2"
c.g.addSize c.conf.target.ptrSize*2
c.g.addAlign c.conf.target.ptrSize
let str = openType(g, ObjectDecl)
g.addName "NimStringV2"
g.addSize c.conf.target.ptrSize*2
g.addAlign c.conf.target.ptrSize
c.g.addField "len", c.nativeInt, 0
g.addField "len", c.nativeInt, 0
let fp = c.g.openType FieldDecl
let ffp = c.g.openType APtrTy
c.g.addNominalType ObjectTy, "NimStrPayload"
sealType(c.g, ffp) # APtrTy
c.g.addOffset c.conf.target.ptrSize # comes after 'len' field
c.g.addName "p"
sealType(c.g, fp) # FieldDecl
let fp = g.openType FieldDecl
let ffp = g.openType APtrTy
g.addNominalType ObjectTy, "NimStrPayload"
sealType(g, ffp) # APtrTy
g.addOffset c.conf.target.ptrSize # comes after 'len' field
g.addName "p"
sealType(g, fp) # FieldDecl
result = finishType(c.g, str) # ObjectDecl
result = finishType(g, str) # ObjectDecl
proc seqPayloadType(c: var TypesCon; t: PType): string =
proc seqPayloadType(c: var TypesCon; g: var TypeGraph; t: PType): (string, TypeId) =
#[
NimSeqPayload[T] = object
cap: int
data: UncheckedArray[T]
]#
let e = lastSon(t)
result = mangle(c, e)
let payloadName = "NimSeqPayload" & result
result = (mangle(c, e), TypeId(-1))
let payloadName = "NimSeqPayload" & result[0]
let elementType = typeToIr(c, e)
let elementType = typeToIr(c, g, e)
let p = openType(c.g, ObjectDecl)
c.g.addName payloadName
c.g.addSize c.conf.target.intSize
c.g.addAlign c.conf.target.intSize
let p = openType(g, ObjectDecl)
g.addName payloadName
g.addSize c.conf.target.intSize
g.addAlign c.conf.target.intSize
c.g.addField "cap", c.nativeInt, 0
g.addField "cap", c.nativeInt, 0
let f = c.g.openType FieldDecl
let arr = c.g.openType LastArrayTy
c.g.addType elementType
sealType(c.g, arr) # LastArrayTy
c.g.addOffset c.conf.target.ptrSize
c.g.addName "data"
sealType(c.g, f) # FieldDecl
sealType(c.g, p)
let f = g.openType FieldDecl
let arr = g.openType LastArrayTy
g.addType elementType
result[1] = finishType(g, arr) # LastArrayTy
g.addOffset c.conf.target.ptrSize
g.addName "data"
sealType(g, f) # FieldDecl
sealType(g, p)
proc seqPayloadPtrType*(c: var TypesCon; t: PType): TypeId =
let mangledBase = seqPayloadType(c, t)
let ffp = c.g.openType APtrTy
c.g.addNominalType ObjectTy, "NimSeqPayload" & mangledBase
result = finishType(c.g, ffp) # APtrTy
proc seqPayloadPtrType*(c: var TypesCon; g: var TypeGraph; t: PType): (TypeId, TypeId) =
let (mangledBase, arrayType) = seqPayloadType(c, g, t)
let ffp = g.openType APtrTy
g.addNominalType ObjectTy, "NimSeqPayload" & mangledBase
result = (finishType(g, ffp), arrayType) # APtrTy
proc seqToIr(c: var TypesCon; t: PType): TypeId =
proc seqToIr(c: var TypesCon; g: var TypeGraph; t: PType): TypeId =
#[
NimSeqV2*[T] = object
len: int
p: ptr NimSeqPayload[T]
]#
let mangledBase = seqPayloadType(c, t)
let (mangledBase, _) = seqPayloadType(c, g, t)
let sq = openType(c.g, ObjectDecl)
c.g.addName "NimSeqV2" & mangledBase
c.g.addSize c.conf.getSize(t)
c.g.addAlign c.conf.getAlign(t)
let sq = openType(g, ObjectDecl)
g.addName "NimSeqV2" & mangledBase
g.addSize c.conf.getSize(t)
g.addAlign c.conf.getAlign(t)
c.g.addField "len", c.nativeInt, 0
g.addField "len", c.nativeInt, 0
let fp = c.g.openType FieldDecl
let ffp = c.g.openType APtrTy
c.g.addNominalType ObjectTy, "NimSeqPayload" & mangledBase
sealType(c.g, ffp) # APtrTy
c.g.addOffset c.conf.target.ptrSize
c.g.addName "p"
sealType(c.g, fp) # FieldDecl
let fp = g.openType FieldDecl
let ffp = g.openType APtrTy
g.addNominalType ObjectTy, "NimSeqPayload" & mangledBase
sealType(g, ffp) # APtrTy
g.addOffset c.conf.target.ptrSize
g.addName "p"
sealType(g, fp) # FieldDecl
result = finishType(c.g, sq) # ObjectDecl
result = finishType(g, sq) # ObjectDecl
proc closureToIr(c: var TypesCon; t: PType): TypeId =
proc closureToIr(c: var TypesCon; g: var TypeGraph; t: PType): TypeId =
# struct {fn(args, void* env), env}
# typedef struct {$n" &
# "N_NIMCALL_PTR($2, ClP_0) $3;$n" &
@@ -319,31 +319,31 @@ proc closureToIr(c: var TypesCon; t: PType): TypeId =
let mangledBase = mangle(c, t)
let typeName = "NimClosure" & mangledBase
let procType = procToIr(c, t, addEnv=true)
let procType = procToIr(c, g, t, addEnv=true)
let p = openType(c.g, ObjectDecl)
c.g.addName typeName
c.g.addSize c.conf.getSize(t)
c.g.addAlign c.conf.getAlign(t)
let p = openType(g, ObjectDecl)
g.addName typeName
g.addSize c.conf.getSize(t)
g.addAlign c.conf.getAlign(t)
let f = c.g.openType FieldDecl
c.g.addType procType
c.g.addOffset 0
c.g.addName "ClP_0"
sealType(c.g, f) # FieldDecl
let f = g.openType FieldDecl
g.addType procType
g.addOffset 0
g.addName "ClP_0"
sealType(g, f) # FieldDecl
let f2 = c.g.openType FieldDecl
let voidPtr = openType(c.g, APtrTy)
c.g.addBuiltinType(VoidId)
sealType(c.g, voidPtr)
let f2 = g.openType FieldDecl
let voidPtr = openType(g, APtrTy)
g.addBuiltinType(VoidId)
sealType(g, voidPtr)
c.g.addOffset c.conf.target.ptrSize
c.g.addName "ClE_0"
sealType(c.g, f2) # FieldDecl
g.addOffset c.conf.target.ptrSize
g.addName "ClE_0"
sealType(g, f2) # FieldDecl
result = finishType(c.g, p) # ObjectDecl
result = finishType(g, p) # ObjectDecl
proc bitsetBasetype*(c: var TypesCon; t: PType): TypeId =
proc bitsetBasetype*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId =
let s = int(getSize(c.conf, t))
case s
of 1: result = UInt8Id
@@ -352,7 +352,7 @@ proc bitsetBasetype*(c: var TypesCon; t: PType): TypeId =
of 8: result = UInt64Id
else: result = UInt8Id
proc typeToIr*(c: var TypesCon; t: PType): TypeId =
proc typeToIr*(c: var TypesCon; g: var TypeGraph; t: PType): TypeId =
if t == nil: return VoidId
case t.kind
of tyInt:
@@ -370,7 +370,7 @@ proc typeToIr*(c: var TypesCon; t: PType): TypeId =
else: result = Float64Id
of tyFloat32: result = Float32Id
of tyFloat64: result = Float64Id
of tyFloat128: result = getFloat128Type(c.g)
of tyFloat128: result = getFloat128Type(g)
of tyUInt:
case int(getSize(c.conf, t))
of 2: result = UInt16Id
@@ -384,7 +384,7 @@ proc typeToIr*(c: var TypesCon; t: PType): TypeId =
of tyChar: result = Char8Id
of tyVoid: result = VoidId
of tySink, tyGenericInst, tyDistinct, tyAlias, tyOwned, tyRange:
result = typeToIr(c, t.lastSon)
result = typeToIr(c, g, t.lastSon)
of tyEnum:
if firstOrd(c.conf, t) < 0:
result = Int32Id
@@ -397,47 +397,47 @@ proc typeToIr*(c: var TypesCon; t: PType): TypeId =
else: result = Int32Id
of tyOrdinal, tyGenericBody, tyGenericParam, tyInferred, tyStatic:
if t.len > 0:
result = typeToIr(c, t.lastSon)
result = typeToIr(c, g, t.lastSon)
else:
result = TypeId(-1)
of tyFromExpr:
if t.n != nil and t.n.typ != nil:
result = typeToIr(c, t.n.typ)
result = typeToIr(c, g, t.n.typ)
else:
result = TypeId(-1)
of tyArray:
cached(c, t):
var n = toInt64(lengthOrd(c.conf, t))
if n <= 0: n = 1 # make an array of at least one element
let elemType = typeToIr(c, t[1])
let a = openType(c.g, ArrayTy)
c.g.addType(elemType)
c.g.addArrayLen n
result = finishType(c.g, a)
let elemType = typeToIr(c, g, t[1])
let a = openType(g, ArrayTy)
g.addType(elemType)
g.addArrayLen n
result = finishType(g, a)
of tyPtr, tyRef:
cached(c, t):
let e = t.lastSon
if e.kind == tyUncheckedArray:
let elemType = typeToIr(c, e.lastSon)
let a = openType(c.g, AArrayPtrTy)
c.g.addType(elemType)
result = finishType(c.g, a)
let elemType = typeToIr(c, g, e.lastSon)
let a = openType(g, AArrayPtrTy)
g.addType(elemType)
result = finishType(g, a)
else:
let elemType = typeToIr(c, t.lastSon)
let a = openType(c.g, APtrTy)
c.g.addType(elemType)
result = finishType(c.g, a)
let elemType = typeToIr(c, g, t.lastSon)
let a = openType(g, APtrTy)
g.addType(elemType)
result = finishType(g, a)
of tyVar, tyLent:
cached(c, t):
let e = t.lastSon
if e.skipTypes(abstractInst).kind in {tyOpenArray, tyVarargs}:
# skip the modifier, `var openArray` is a (ptr, len) pair too:
result = typeToIr(c, e)
result = typeToIr(c, g, e)
else:
let elemType = typeToIr(c, e)
let a = openType(c.g, APtrTy)
c.g.addType(elemType)
result = finishType(c.g, a)
let elemType = typeToIr(c, g, e)
let a = openType(g, APtrTy)
g.addType(elemType)
result = finishType(g, a)
of tySet:
let s = int(getSize(c.conf, t))
case s
@@ -448,54 +448,57 @@ proc typeToIr*(c: var TypesCon; t: PType): TypeId =
else:
# array[U8, s]
cached(c, t):
let a = openType(c.g, ArrayTy)
c.g.addType(UInt8Id)
c.g.addArrayLen s
result = finishType(c.g, a)
let a = openType(g, ArrayTy)
g.addType(UInt8Id)
g.addArrayLen s
result = finishType(g, a)
of tyPointer, tyNil:
# tyNil can happen for code like: `const CRAP = nil` which we have in posix.nim
let a = openType(c.g, APtrTy)
c.g.addBuiltinType(VoidId)
result = finishType(c.g, a)
let a = openType(g, APtrTy)
g.addBuiltinType(VoidId)
result = finishType(g, a)
of tyObject:
# Objects are special as they can be recursive in Nim. This is easily solvable.
# We check if we are already "processing" t. If so, we produce `ObjectTy`
# instead of `ObjectDecl`.
cached(c, t):
if not c.recursionCheck.containsOrIncl(t.itemId):
result = objectToIr(c, t)
result = objectToIr(c, g, t)
else:
result = objectHeaderToIr(c, t)
result = objectHeaderToIr(c, g, t)
of tyTuple:
cached(c, t):
result = tupleToIr(c, t)
result = tupleToIr(c, g, t)
of tyProc:
cached(c, t):
if t.callConv == ccClosure:
result = closureToIr(c, t)
result = closureToIr(c, g, t)
else:
result = procToIr(c, t)
result = procToIr(c, g, t)
of tyVarargs, tyOpenArray:
cached(c, t):
result = openArrayToIr(c, t)
result = openArrayToIr(c, g, t)
of tyString:
cached(c, t):
result = stringToIr(c)
if c.stringType.int < 0:
result = stringToIr(c, g)
c.stringType = result
else:
result = c.stringType
of tySequence:
cached(c, t):
result = seqToIr(c, t)
result = seqToIr(c, g, t)
of tyCstring:
cached(c, t):
let a = openType(c.g, AArrayPtrTy)
c.g.addBuiltinType Char8Id
result = finishType(c.g, a)
let a = openType(g, AArrayPtrTy)
g.addBuiltinType Char8Id
result = finishType(g, a)
of tyUncheckedArray:
# We already handled the `ptr UncheckedArray` in a special way.
cached(c, t):
let elemType = typeToIr(c, t.lastSon)
let a = openType(c.g, LastArrayTy)
c.g.addType(elemType)
result = finishType(c.g, a)
let elemType = typeToIr(c, g, t.lastSon)
let a = openType(g, LastArrayTy)
g.addType(elemType)
result = finishType(g, a)
of tyUntyped, tyTyped:
# this avoids a special case for system.echo which is not a generic but
# uses `varargs[typed]`:

View File

@@ -65,7 +65,7 @@ elif defined(macosx) or defined(linux) or defined(freebsd) or
SIGSEGV* = cint(11)
SIGTERM* = cint(15)
SIGPIPE* = cint(13)
SIG_DFL* = cast[CSighandlerT](0)
SIG_DFL* = CSighandlerT(nil)
elif defined(haiku):
const
SIGABRT* = cint(6)
@@ -75,7 +75,7 @@ elif defined(haiku):
SIGSEGV* = cint(11)
SIGTERM* = cint(15)
SIGPIPE* = cint(7)
SIG_DFL* = cast[CSighandlerT](0)
SIG_DFL* = CSighandlerT(nil)
else:
when defined(nimscript):
{.error: "SIGABRT not ported to your platform".}