bycopy/byref for object/tuple types

This commit is contained in:
Araq
2012-08-16 17:54:11 +02:00
parent d37fe6e0a5
commit e4c432387e
6 changed files with 49 additions and 17 deletions

View File

@@ -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]

View File

@@ -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):

View File

@@ -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)

View File

@@ -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

View File

@@ -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:

View File

@@ -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