mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 21:40:32 +00:00
'noStackFrame' implies 'naked' in the generated C code
This commit is contained in:
@@ -387,7 +387,7 @@ type
|
|||||||
tfNeedsInit, # type constains a "not nil" constraint somewhere or some
|
tfNeedsInit, # type constains a "not nil" constraint somewhere or some
|
||||||
# other type so that it requires inititalization
|
# other type so that it requires inititalization
|
||||||
tfHasShared, # type constains a "shared" constraint modifier somewhere
|
tfHasShared, # type constains a "shared" constraint modifier somewhere
|
||||||
tfHasMeta, # type has "typedesc" or "expr" somewhere
|
tfHasMeta, # type has "typedesc" or "expr" somewhere; or uses '|'
|
||||||
tfHasGCedMem, # type contains GC'ed memory
|
tfHasGCedMem, # type contains GC'ed memory
|
||||||
|
|
||||||
TTypeFlags* = set[TTypeFlag]
|
TTypeFlags* = set[TTypeFlag]
|
||||||
@@ -1210,7 +1210,7 @@ proc newSons(father: PNode, length: int) =
|
|||||||
setlen(father.sons, length)
|
setlen(father.sons, length)
|
||||||
|
|
||||||
proc propagateToOwner*(owner, elem: PType) =
|
proc propagateToOwner*(owner, elem: PType) =
|
||||||
const HaveTheirOwnEmpty = {tySequence, tySet}
|
const HaveTheirOwnEmpty = {tySequence, tySet}
|
||||||
owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta,
|
owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta,
|
||||||
tfHasGCedMem})
|
tfHasGCedMem})
|
||||||
if tfNotNil in elem.flags:
|
if tfNotNil in elem.flags:
|
||||||
|
|||||||
@@ -761,6 +761,7 @@ proc genProcAux(m: BModule, prc: PSym) =
|
|||||||
if skipTypes(res.typ, abstractInst).kind == tyArray:
|
if skipTypes(res.typ, abstractInst).kind == tyArray:
|
||||||
incl(res.loc.flags, lfIndirect)
|
incl(res.loc.flags, lfIndirect)
|
||||||
res.loc.s = OnUnknown
|
res.loc.s = OnUnknown
|
||||||
|
|
||||||
for i in countup(1, sonsLen(prc.typ.n) - 1):
|
for i in countup(1, sonsLen(prc.typ.n) - 1):
|
||||||
var param = prc.typ.n.sons[i].sym
|
var param = prc.typ.n.sons[i].sym
|
||||||
if param.typ.isCompileTimeOnly: continue
|
if param.typ.isCompileTimeOnly: continue
|
||||||
@@ -768,7 +769,9 @@ proc genProcAux(m: BModule, prc: PSym) =
|
|||||||
closureSetup(p, prc)
|
closureSetup(p, prc)
|
||||||
genStmts(p, prc.getBody) # modifies p.locals, p.init, etc.
|
genStmts(p, prc.getBody) # modifies p.locals, p.init, etc.
|
||||||
var generatedProc: PRope
|
var generatedProc: PRope
|
||||||
if sfPure in prc.flags:
|
if sfPure in prc.flags:
|
||||||
|
if hasNakedDeclspec in extccomp.CC[extccomp.ccompiler].props:
|
||||||
|
header = con("__declspec(naked) ", header)
|
||||||
generatedProc = rfmt(nil, "$N$1 {$n$2$3$4}$N$N",
|
generatedProc = rfmt(nil, "$N$1 {$n$2$3$4}$N$N",
|
||||||
header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts))
|
header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts))
|
||||||
else:
|
else:
|
||||||
@@ -801,8 +804,11 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
|||||||
app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
|
app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
|
||||||
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
|
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
|
||||||
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
|
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
|
||||||
elif not ContainsOrIncl(m.declaredProtos, sym.id):
|
elif not ContainsOrIncl(m.declaredProtos, sym.id):
|
||||||
app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", genProcHeader(m, sym)))
|
var header = genProcHeader(m, sym)
|
||||||
|
if sfPure in sym.flags and hasNakedAttribute in CC[ccompiler].props:
|
||||||
|
header.app(" __attribute__((naked))")
|
||||||
|
app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header))
|
||||||
|
|
||||||
proc genProcNoForward(m: BModule, prc: PSym) =
|
proc genProcNoForward(m: BModule, prc: PSym) =
|
||||||
fillProcLoc(prc)
|
fillProcLoc(prc)
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ type
|
|||||||
hasCpp, # CC is/contains a C++ compiler
|
hasCpp, # CC is/contains a C++ compiler
|
||||||
hasAssume, # CC has __assume (Visual C extension)
|
hasAssume, # CC has __assume (Visual C extension)
|
||||||
hasGcGuard, # CC supports GC_GUARD to keep stack roots
|
hasGcGuard, # CC supports GC_GUARD to keep stack roots
|
||||||
hasGnuAsm # CC's asm uses the absurd GNU assembler syntax
|
hasGnuAsm, # CC's asm uses the absurd GNU assembler syntax
|
||||||
|
hasNakedDeclspec, # CC has __declspec(naked)
|
||||||
|
hasNakedAttribute # CC has __attribute__((naked))
|
||||||
TInfoCCProps* = set[TInfoCCProp]
|
TInfoCCProps* = set[TInfoCCProp]
|
||||||
TInfoCC* = tuple[
|
TInfoCC* = tuple[
|
||||||
name: string, # the short name of the compiler
|
name: string, # the short name of the compiler
|
||||||
@@ -73,7 +75,8 @@ compiler gcc:
|
|||||||
debug: "",
|
debug: "",
|
||||||
pic: "-fPIC",
|
pic: "-fPIC",
|
||||||
asmStmtFrmt: "asm($1);$n",
|
asmStmtFrmt: "asm($1);$n",
|
||||||
props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm})
|
props: {hasSwitchRange, hasComputedGoto, hasCpp, hasGcGuard, hasGnuAsm,
|
||||||
|
hasNakedAttribute})
|
||||||
|
|
||||||
compiler gpp:
|
compiler gpp:
|
||||||
result = gcc()
|
result = gcc()
|
||||||
@@ -120,7 +123,7 @@ compiler vcc:
|
|||||||
debug: " /GZ /Zi ",
|
debug: " /GZ /Zi ",
|
||||||
pic: "",
|
pic: "",
|
||||||
asmStmtFrmt: "__asm{$n$1$n}$n",
|
asmStmtFrmt: "__asm{$n$1$n}$n",
|
||||||
props: {hasCpp, hasAssume})
|
props: {hasCpp, hasAssume, hasNakedDeclspec})
|
||||||
|
|
||||||
compiler icl:
|
compiler icl:
|
||||||
# Intel compilers try to imitate the native ones (gcc and msvc)
|
# Intel compilers try to imitate the native ones (gcc and msvc)
|
||||||
|
|||||||
@@ -333,13 +333,11 @@ proc analyse(c: PProcCtx, n: PNode): TThreadOwner =
|
|||||||
result = toNil
|
result = toNil
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var it = n.sons[i]
|
var it = n.sons[i]
|
||||||
case it.kind
|
if it.len == 2:
|
||||||
of nkElifExpr:
|
|
||||||
discard analyse(c, it.sons[0])
|
discard analyse(c, it.sons[0])
|
||||||
aggregateOwner(result, analyse(c, it.sons[1]))
|
aggregateOwner(result, analyse(c, it.sons[1]))
|
||||||
of nkElseExpr:
|
else:
|
||||||
aggregateOwner(result, analyse(c, it.sons[0]))
|
aggregateOwner(result, analyse(c, it.sons[0]))
|
||||||
else: internalError(n.info, "analyseIfExpr()")
|
|
||||||
of nkStmtListExpr, nkBlockExpr:
|
of nkStmtListExpr, nkBlockExpr:
|
||||||
var n = if n.kind == nkBlockExpr: n.sons[1] else: n
|
var n = if n.kind == nkBlockExpr: n.sons[1] else: n
|
||||||
var L = sonsLen(n)
|
var L = sonsLen(n)
|
||||||
|
|||||||
@@ -924,6 +924,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
|||||||
result.addSonSkipIntLit(t1)
|
result.addSonSkipIntLit(t1)
|
||||||
result.addSonSkipIntLit(t2)
|
result.addSonSkipIntLit(t2)
|
||||||
result.flags.incl(if op.id == ord(wAnd): tfAll else: tfAny)
|
result.flags.incl(if op.id == ord(wAnd): tfAll else: tfAny)
|
||||||
|
result.flags.incl(tfHasMeta)
|
||||||
elif op.id == ord(wNot):
|
elif op.id == ord(wNot):
|
||||||
checkSonsLen(n, 3)
|
checkSonsLen(n, 3)
|
||||||
result = semTypeNode(c, n.sons[1], prev)
|
result = semTypeNode(c, n.sons[1], prev)
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
|||||||
result = ReplaceTypeVarsT(cl, lastSon(t))
|
result = ReplaceTypeVarsT(cl, lastSon(t))
|
||||||
of tyInt:
|
of tyInt:
|
||||||
result = skipIntLit(t)
|
result = skipIntLit(t)
|
||||||
|
# XXX now there are also float literals
|
||||||
else:
|
else:
|
||||||
if t.kind == tyArray:
|
if t.kind == tyArray:
|
||||||
let idxt = t.sons[0]
|
let idxt = t.sons[0]
|
||||||
|
|||||||
@@ -4671,8 +4671,10 @@ NoStackFrame pragma
|
|||||||
-------------------
|
-------------------
|
||||||
A proc can be marked with the `noStackFrame`:idx: pragma to tell the compiler
|
A proc can be marked with the `noStackFrame`:idx: pragma to tell the compiler
|
||||||
it should not generate a stack frame for the proc. There are also no exit
|
it should not generate a stack frame for the proc. There are also no exit
|
||||||
statements like ``return result;`` generated. This is useful for procs that
|
statements like ``return result;`` generated and the generated C function is
|
||||||
only consist of an assembler statement.
|
declared as ``__declspec(naked)`` or ``__attribute__((naked))`` (depending on
|
||||||
|
the used C compiler). This is useful for procs that only consist of an
|
||||||
|
assembler statement.
|
||||||
|
|
||||||
|
|
||||||
error pragma
|
error pragma
|
||||||
|
|||||||
Reference in New Issue
Block a user