mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 20:04:18 +00:00
bycopy/byref for object/tuple types
This commit is contained in:
@@ -328,7 +328,7 @@ type
|
||||
nfSem # node has been checked for semantics
|
||||
|
||||
TNodeFlags* = set[TNodeFlag]
|
||||
TTypeFlag* = enum
|
||||
TTypeFlag* = enum # keep below 15 for efficiency reasons (now: 13)
|
||||
tfVarargs, # procedure has C styled varargs
|
||||
tfNoSideEffect, # procedure type does not allow side effects
|
||||
tfFinal, # is the object final?
|
||||
@@ -341,7 +341,9 @@ type
|
||||
# type equality has to be used
|
||||
tfAll, # type class requires all constraints to be met (default)
|
||||
tfAny, # type class requires any constraint to be met
|
||||
tfCapturesEnv # whether proc really captures some environment
|
||||
tfCapturesEnv, # whether proc really captures some environment
|
||||
tfByCopy, # pass object/tuple by copy (C backend)
|
||||
tfByRef # pass object/tuple by reference (C backend)
|
||||
|
||||
TTypeFlags* = set[TTypeFlag]
|
||||
|
||||
|
||||
@@ -249,6 +249,8 @@ proc getGlobalTempName(): PRope =
|
||||
proc ccgIntroducedPtr(s: PSym): bool =
|
||||
var pt = skipTypes(s.typ, abstractInst)
|
||||
assert skResult != s.kind
|
||||
if tfByRef in pt.flags: return true
|
||||
elif tfByCopy in pt.flags: return false
|
||||
case pt.Kind
|
||||
of tyObject:
|
||||
if (optByRef in s.options) or (getSize(pt) > platform.floatSize * 2):
|
||||
|
||||
@@ -46,7 +46,7 @@ const
|
||||
wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame}
|
||||
typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl,
|
||||
wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow,
|
||||
wImportcpp, wImportobjc, wError, wIncompleteStruct}
|
||||
wImportcpp, wImportobjc, wError, wIncompleteStruct, wByCopy, wByRef}
|
||||
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
||||
wImportcpp, wImportobjc, wError}
|
||||
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
||||
@@ -483,8 +483,8 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
||||
processImportCompilerProc(sym, getOptionalStr(c, it, sym.name.s))
|
||||
of wExtern: setExternName(sym, expectStrLit(c, it))
|
||||
of wImmediate:
|
||||
if sym.kind notin {skTemplate, skMacro}: invalidPragma(it)
|
||||
incl(sym.flags, sfImmediate)
|
||||
if sym.kind in {skTemplate, skMacro}: incl(sym.flags, sfImmediate)
|
||||
else: invalidPragma(it)
|
||||
of wImportCpp:
|
||||
processImportCpp(sym, getOptionalStr(c, it, sym.name.s))
|
||||
of wImportObjC:
|
||||
@@ -571,22 +571,22 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
||||
of wVarargs:
|
||||
noVal(it)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
incl(sym.typ.flags, tfVarargs)
|
||||
else: incl(sym.typ.flags, tfVarargs)
|
||||
of wBorrow:
|
||||
noVal(it)
|
||||
incl(sym.flags, sfBorrow)
|
||||
of wFinal:
|
||||
noVal(it)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
incl(sym.typ.flags, tfFinal)
|
||||
else: incl(sym.typ.flags, tfFinal)
|
||||
of wAcyclic:
|
||||
noVal(it)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
incl(sym.typ.flags, tfAcyclic)
|
||||
else: incl(sym.typ.flags, tfAcyclic)
|
||||
of wShallow:
|
||||
noVal(it)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
incl(sym.typ.flags, tfShallow)
|
||||
else: incl(sym.typ.flags, tfShallow)
|
||||
of wThread:
|
||||
noVal(it)
|
||||
incl(sym.flags, sfThread)
|
||||
@@ -627,29 +627,37 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
||||
of wNoInit:
|
||||
noVal(it)
|
||||
if sym != nil: incl(sym.flags, sfNoInit)
|
||||
of wByCopy:
|
||||
noVal(it)
|
||||
if sym != nil: incl(sym.flags, sfByCopy)
|
||||
of wHoist:
|
||||
noVal(it)
|
||||
if sym != nil: incl(sym.flags, sfHoist)
|
||||
of wChecks, wObjChecks, wFieldChecks, wRangechecks, wBoundchecks,
|
||||
wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
||||
wLinedir, wStacktrace, wLinetrace, wOptimization, wByRef,
|
||||
wLinedir, wStacktrace, wLinetrace, wOptimization,
|
||||
wCallConv,
|
||||
wDebugger, wProfiler, wFloatChecks, wNanChecks, wInfChecks:
|
||||
processOption(c, it) # calling conventions (boring...):
|
||||
of firstCallConv..lastCallConv:
|
||||
assert(sym != nil)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
sym.typ.callConv = wordToCallConv(k)
|
||||
else: sym.typ.callConv = wordToCallConv(k)
|
||||
of wEmit: PragmaEmit(c, it)
|
||||
of wUnroll: PragmaUnroll(c, it)
|
||||
of wLinearScanEnd: PragmaLinearScanEnd(c, it)
|
||||
of wIncompleteStruct:
|
||||
noVal(it)
|
||||
if sym.typ == nil: invalidPragma(it)
|
||||
incl(sym.typ.flags, tfIncompleteStruct)
|
||||
else: incl(sym.typ.flags, tfIncompleteStruct)
|
||||
of wByRef:
|
||||
noVal(it)
|
||||
if sym == nil or sym.typ == nil:
|
||||
processOption(c, it)
|
||||
else:
|
||||
incl(sym.typ.flags, tfByRef)
|
||||
of wByCopy:
|
||||
noVal(it)
|
||||
if sym.kind != skType: incl(sym.flags, sfByCopy)
|
||||
elif sym.typ == nil: invalidPragma(it)
|
||||
else: incl(sym.typ.flags, tfByCopy)
|
||||
of wLine: PragmaLine(c, it)
|
||||
else: invalidPragma(it)
|
||||
else: invalidPragma(it)
|
||||
|
||||
@@ -2836,7 +2836,7 @@ Ordinary vs immediate templates
|
||||
|
||||
There are two different kinds of templates: `immediate`:idx: templates and
|
||||
ordinary templates. Ordinary templates take part in overloading resolution. As
|
||||
such their arguments needs to be type checked before the template is invoked.
|
||||
such their arguments need to be type checked before the template is invoked.
|
||||
So ordinary templates cannot receive undeclared identifiers:
|
||||
|
||||
.. code-block:: nimrod
|
||||
@@ -3657,6 +3657,25 @@ identifier *exactly as spelled*:
|
||||
|
||||
Note that this pragma is somewhat of a misnomer: Other backends will provide
|
||||
the same feature under the same name.
|
||||
|
||||
|
||||
Bycopy pragma
|
||||
-------------
|
||||
|
||||
The `bycopy`:idx: pragma can be applied to an object or tuple type and
|
||||
instructs the compiler to pass the type by value to procs:
|
||||
|
||||
.. code-block:: nimrod
|
||||
type
|
||||
TVector {.bycopy, pure.} = object
|
||||
x, y, z: float
|
||||
|
||||
|
||||
Byref pragma
|
||||
------------
|
||||
|
||||
The `byref`:idx: pragma can be applied to an object or tuple type and instructs
|
||||
the compiler to pass the type by reference (hidden pointer) to procs.
|
||||
|
||||
|
||||
Varargs pragma
|
||||
|
||||
1
todo.txt
1
todo.txt
@@ -7,7 +7,6 @@ version 0.9.0
|
||||
|
||||
- implicit deref for parameter matching
|
||||
- ``final`` should be the default for objects
|
||||
- ``bycopy`` pragma for imported C types
|
||||
- optimize genericAssign in the code generator
|
||||
- the lookup rules for generics really are too permissive
|
||||
- fix remaining closure bugs:
|
||||
|
||||
@@ -124,6 +124,8 @@ Compiler Additions
|
||||
of the compiler and can thus generate documentation for symbols hiding in
|
||||
macros.
|
||||
- The compiler now supports the ``dynlib`` pragma for variables.
|
||||
- The compiler now supports ``bycopy`` and ``byref`` pragmas that affect how
|
||||
objects/tuples are passed.
|
||||
|
||||
|
||||
Language Additions
|
||||
|
||||
Reference in New Issue
Block a user