From 9ed984201db1c16d91c3137b622008afb19dfc5a Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sat, 21 Jun 2014 19:35:40 +0200 Subject: [PATCH 01/10] Hyperlinks together importc like pragmas. --- doc/manual.txt | 5 ++++- doc/nimrodc.txt | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/doc/manual.txt b/doc/manual.txt index 3af41faecf..2f0387b19f 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -5488,7 +5488,10 @@ spelled*: proc printf(formatstr: cstring) {.header: "", importc: "printf", varargs.} Note that this pragma is somewhat of a misnomer: Other backends will provide -the same feature under the same name. +the same feature under the same name. Also, if you are interfacing with C++ +you can use the `ImportCpp pragma `_ and +interfacing with Objective-C the `ImportObjC pragma +`_. Exportc pragma diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt index fea1037dad..58c234bcb9 100644 --- a/doc/nimrodc.txt +++ b/doc/nimrodc.txt @@ -384,10 +384,11 @@ Example: ImportCpp pragma ---------------- -The ``importcpp`` pragma can be used to import `C++`:idx: methods. The -generated code then uses the C++ method calling syntax: ``obj->method(arg)``. -In addition with the ``header`` and ``emit`` pragmas this allows *sloppy* -interfacing with libraries written in C++: +Similar to the `importc pragma for C `_, the +``importcpp`` pragma can be used to import `C++`:idx: methods. The generated +code then uses the C++ method calling syntax: ``obj->method(arg)``. In +addition with the ``header`` and ``emit`` pragmas this allows *sloppy* +interfacing with libraries written in C++: .. code-block:: Nimrod # Horrible example of how to interface with a C++ engine ... ;-) @@ -422,11 +423,11 @@ emits C++ code. ImportObjC pragma ----------------- -The ``importobjc`` pragma can be used to import `Objective C`:idx: methods. -The generated code then uses the Objective C method calling -syntax: ``[obj method param1: arg]``. -In addition with the ``header`` and ``emit`` pragmas this allows *sloppy* -interfacing with libraries written in Objective C: +Similar to the `importc pragma for C `_, the +``importobjc`` pragma can be used to import `Objective C`:idx: methods. The +generated code then uses the Objective C method calling syntax: ``[obj method +param1: arg]``. In addition with the ``header`` and ``emit`` pragmas this +allows *sloppy* interfacing with libraries written in Objective C: .. code-block:: Nimrod # horrible example of how to interface with GNUStep ... From 6a2bb0058ca6e7024a690b1459d425014883f66c Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sat, 21 Jun 2014 21:47:12 +0200 Subject: [PATCH 02/10] Starts backends.txt with bits from nimrodc.txt. --- doc/advopt.txt | 7 +-- doc/backends.txt | 113 +++++++++++++++++++++++++++++++++++++++++++++++ doc/nimrodc.txt | 46 +++++-------------- web/nimrod.ini | 2 +- 4 files changed, 130 insertions(+), 38 deletions(-) create mode 100644 doc/backends.txt diff --git a/doc/advopt.txt b/doc/advopt.txt index f5ff90791b..e3a62c31bc 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -1,7 +1,8 @@ Advanced commands: - //compileToC, cc compile project with C code generator - //compileToCpp, cpp compile project to C++ code - //compileToOC, objc compile project to Objective C code + //compileToC, cc compile project with C code generator, see `Backend language options`_ + //compileToCpp, cpp compile project to C++ code, see `Backend language options`_ + //compileToOC, objc compile project to Objective C code, see `Backend language options`_ + //js compile project to Javascript, see `Backend language options`_ //rst2html convert a reStructuredText file to HTML //rst2tex convert a reStructuredText file to TeX //jsondoc extract the documentation to a json file diff --git a/doc/backends.txt b/doc/backends.txt new file mode 100644 index 0000000000..2d70753239 --- /dev/null +++ b/doc/backends.txt @@ -0,0 +1,113 @@ +================================ + Nimrod Backend Integration +================================ + +:Author: Puppet Master +:Version: |nimrodversion| + +.. contents:: + + "If we all reacted the same way, we'd be predictable, and there's + always more than one way to view a situation. What's true for the + group is also true for the individual. It's simple: overspecialize, + and you breed in weakness. It's slow death." -- Major Motoko + Kusanagi + + +Introduction +============ + +The `Nimrod Compiler User Guide `_ documents the typical +compiler usage, using the ``compile`` or ``c`` command to transform a ``.nim`` +file into one or more ``.c`` files which are then compiled with the platform's +C compiler into a static binary. However there are other commands to compile +to C++, Objective-C or JavaScript. This document tries to concentrate in a +single place all the backend and interfacing options. + +The Nimrod compiler supports mainly two backends: the C (and derivate) and +the JavaScript targets. The C target creates source files which can be +compiled into a library or a final executable. The JavaScript target generates +a ``.js`` file which you call from an HTML file. + + +Backends +======== + +The C like targets +------------------ + +The commands to compile to either C, C++ or Objective-C are: + + //compileToC, cc compile project with C code generator + //compileToCpp, cpp compile project to C++ code + //compileToOC, objc compile project to Objective C code + +The most significant difference between these commands is that if you look +into the ``nimcache`` directory you will find ``.c``, ``.cpp`` or ``.m`` +files, other than that all of them will produce a native binary for your +project. This allows you to take the generated code and place it directly +into a project using any of these languages. Here are some typical command +line invocations:: + + $ nimrod c hallo.nim + $ nimrod cpp hallo.nim + $ nimrod objc hallo.nim + +The compiler commands select the backend but if you need to specify more +carefully the backend compiler… + + +The JavaScript target +--------------------- + +Nimrod can also generate `JavaScript`:idx: code through the ``js`` command. +However, the JavaScript code generator is experimental! + +Nimrod targets JavaScript 1.5 which is supported by any widely used browser. +Since JavaScript does not have a portable means to include another module, +Nimrod just generates a long ``.js`` file. + +Features or modules that the JavaScript platform does not support are not +available. This includes: + +* manual memory management (``alloc``, etc.) +* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.) +* file management +* most modules of the Standard library +* proper 64 bit integer arithmetic +* unsigned integer arithmetic + +However, the modules `strutils `_, `math `_, and +`times `_ are available! To access the DOM, use the `dom +`_ module that is only available for the JavaScript platform. + +To compile a Nimrod module into a ``.js`` file use the ``js`` command; the +default is a ``.js`` file that is supposed to be referenced in an ``.html`` +file. However, you can also run the code with `nodejs`:idx:, a `software +platform for easily building fast, scalable network applications +`_:: + + nimrod js -d:nodejs -r examples/hallo.nim + + +Interfacing +=========== + +intro + +Nimrod code calling the backend +-------------------------------- + +Backend code calling Nimrod +--------------------------- + +mention NimMain + +Memory management +================= + +Garbage collection, life of objects +----------------------------------- + +Thread coordination +------------------- diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt index 58c234bcb9..428c42f39d 100644 --- a/doc/nimrodc.txt +++ b/doc/nimrodc.txt @@ -551,8 +551,18 @@ against. For instance, to link statically against Lua this command might work on Linux:: nimrod c --dynlibOverride:lua --passL:liblua.lib program.nim - - + + +Backend language options +======================== + +The typical compiler usage involves using the ``compile`` or ``c`` command to +transform a ``.nim`` file into one or more ``.c`` files which are then +compiled with the platform's C compiler into a static binary. However there +are other commands to compile to C++, Objective-C or Javascript. More details +can be read in the `Nimrod Backend Integration document `_. + + Nimrod documentation tools ========================== @@ -696,35 +706,3 @@ efficient: else: quit(errorStr(p, "expected: console or gui")) of "license": c.license = UnixToNativePath(k.value) else: quit(errorStr(p, "unknown variable: " & k.key)) - - -The JavaScript target -===================== - -Nimrod can also generate `JavaScript`:idx: code. However, the -JavaScript code generator is experimental! - -Nimrod targets JavaScript 1.5 which is supported by any widely used browser. -Since JavaScript does not have a portable means to include another module, -Nimrod just generates a long ``.js`` file. - -Features or modules that the JavaScript platform does not support are not -available. This includes: - -* manual memory management (``alloc``, etc.) -* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.) -* file management -* most modules of the Standard library -* proper 64 bit integer arithmetic -* unsigned integer arithmetic - -However, the modules `strutils`:idx:, `math`:idx:, and `times`:idx: are -available! To access the DOM, use the `dom`:idx: module that is only -available for the JavaScript platform. - -To compile a Nimrod module into a ``.js`` file use the ``js`` command; the -default is a ``.js`` file that is supposed to be referenced in an ``.html`` -file. However, you can also run the code with `nodejs`:idx:\: - - nimrod js -d:nodejs -r examples/hallo.nim - diff --git a/web/nimrod.ini b/web/nimrod.ini index ed8236c3ee..fc652c158e 100644 --- a/web/nimrod.ini +++ b/web/nimrod.ini @@ -37,7 +37,7 @@ UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson.""" [Documentation] doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview;filters;trmacros" -doc: "tools;c2nim;niminst;nimgrep;gc;estp;idetools;docgen;koch" +doc: "tools;c2nim;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt" pdf: "manual;lib;tut1;tut2;nimrodc;c2nim;niminst;gc" srcdoc2: "system.nim;impure/graphics;wrappers/sdl" srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned" From 2353b5633e1c5ce3374e07883aaffde79fdac0b5 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sat, 21 Jun 2014 22:52:55 +0200 Subject: [PATCH 03/10] Hyperlinks back JavaScript target. --- lib/js/dom.nim | 3 ++- lib/pure/math.nim | 3 ++- lib/pure/strutils.nim | 2 ++ lib/pure/times.nim | 3 ++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/js/dom.nim b/lib/js/dom.nim index d900671769..951d8e8359 100644 --- a/lib/js/dom.nim +++ b/lib/js/dom.nim @@ -7,7 +7,8 @@ # distribution, for details about the copyright. # -## Declaration of the Document Object Model for the JavaScript backend. +## Declaration of the Document Object Model for the `JavaScript backend +## `_. when not defined(js) and not defined(Nimdoc): {.error: "This module only works on the JavaScript platform".} diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 78ea02cbfc..2f7a696b90 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -10,7 +10,8 @@ ## Constructive mathematics is naturally typed. -- Simon Thompson ## ## Basic math routines for Nimrod. -## This module is available for the JavaScript target. +## This module is available for the `JavaScript target +## `_. include "system/inclrtl" diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index bd6814dcca..e642f6a99d 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -10,6 +10,8 @@ ## This module contains various string utility routines. ## See the module `re `_ for regular expression support. ## See the module `pegs `_ for PEG support. +## This module is available for the `JavaScript target +## `_. import parseutils diff --git a/lib/pure/times.nim b/lib/pure/times.nim index fdff06b2a7..4985118998 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -9,7 +9,8 @@ ## This module contains routines and types for dealing with time. -## This module is available for the JavaScript target. +## This module is available for the `JavaScript target +## `_. {.push debugger:off.} # the user does not want to trace a part # of the standard library! From 9c8ce45bcaedf24bc718e4c18f1b81ad81e36165 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sat, 21 Jun 2014 23:53:01 +0200 Subject: [PATCH 04/10] Starts nimrod calling backend section. --- doc/backends.txt | 72 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/doc/backends.txt b/doc/backends.txt index 2d70753239..9d57450dd0 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -18,16 +18,18 @@ Introduction ============ The `Nimrod Compiler User Guide `_ documents the typical -compiler usage, using the ``compile`` or ``c`` command to transform a ``.nim`` -file into one or more ``.c`` files which are then compiled with the platform's -C compiler into a static binary. However there are other commands to compile -to C++, Objective-C or JavaScript. This document tries to concentrate in a -single place all the backend and interfacing options. +compiler invocation, using the ``compile`` or ``c`` command to transform a +``.nim`` file into one or more ``.c`` files which are then compiled with the +platform's C compiler into a static binary. However there are other commands +to compile to C++, Objective-C or JavaScript. This document tries to +concentrate in a single place all the backend and interfacing options. -The Nimrod compiler supports mainly two backends: the C (and derivate) and -the JavaScript targets. The C target creates source files which can be -compiled into a library or a final executable. The JavaScript target generates -a ``.js`` file which you call from an HTML file. +The Nimrod compiler supports mainly two backends: the C (and derivate) and the +JavaScript targets. The C target creates source files which can be compiled +into a library or a final executable. The JavaScript target generates a +``.js`` file which you call from an HTML file. On top of generating a library +or executable, Nimrod offers bidirectional interfacing with the backend +targets through generic and specific pragmas. Backends @@ -53,8 +55,10 @@ line invocations:: $ nimrod cpp hallo.nim $ nimrod objc hallo.nim -The compiler commands select the backend but if you need to specify more -carefully the backend compiler… +The compiler commands select the target backend, but if needed you can +`specify additional switches for cross compilation +`_ to select the target CPU, operative system +or compiler/linker commands. The JavaScript target @@ -93,11 +97,55 @@ platform for easily building fast, scalable network applications Interfacing =========== -intro +Nimrod offers bidirectional interfacing with the target backend. This means +that you can call backend code from Nimrod and Nimrod code can be called by +the backend code. Usually the direction of which calls which depends on your +software architecture (is Nimrod your main program or is Nimrod providing a +component?). + Nimrod code calling the backend -------------------------------- +Nimrod code can interface with the backend through the `Foreign function +interface `_ mainly through the +`importc pragma `_. The ``importc`` pragma is the +*generic* way of making backend code available in Nimrod and is available in +all the target backends (JavaScript too). The C++ or Objective-C backends +have their respective `ImportCpp `_ and +`ImportObjC `_ pragmas to call methods from +classes. + +Whenever you use any of these pragmas you need to integrate native code into +your final binary. In the case of JavaScript this is no problem at all, the +same html file which hosts the generated JavaScript will likely provide other +JavaScript functions which you are importing with ``importc``. + +However, for the C like targets you need to link external code either +statically or dynamically. The preferred way of integrating native code is to +use dynamic linking because it allows you to compile Nimrod programs without +the need for having the related development libraries installed. This is done +through the `dynlib pragma for import +`_, though more specific control can be +gained using the `dynlib module `_. + +The `dynlibOverride `_ command line switch allows +to avoid dynamic linking if you need to statically link something instead. +Nimrod wrappers designed to statically link source files can use the `compile +pragma `_ if there are few sources or providing +them along the Nimrod code is easier than using a system library. Libraries +installed on the host system can be linked in with the `PassL pragma +`_. + +To wrap native code, take a look at the `c2nim tool `_ which helps +with the process of scanning and transforming header files into a Nimrod +interface. + +Example in C. + +Example in JS. + + Backend code calling Nimrod --------------------------- From 299e711a77f1c4e47c35f26735d7b5a3d1ec0571 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sun, 22 Jun 2014 17:22:23 +0200 Subject: [PATCH 05/10] Adds nimrod to backend examples. --- doc/backends.txt | 70 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/doc/backends.txt b/doc/backends.txt index 9d57450dd0..957a2d2ed4 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -141,9 +141,75 @@ To wrap native code, take a look at the `c2nim tool `_ which helps with the process of scanning and transforming header files into a Nimrod interface. -Example in C. +C invocation example +~~~~~~~~~~~~~~~~~~~~ -Example in JS. +Create a ``logic.c`` file with the following content: + +.. code-block:: c + int addTwoIntegers(int a, int b) + { + return a + b; + } + +Create a ``calculator.nim`` file with the following content: + +.. code-block:: nimrod + + {.compile: "logic.c".} + proc addTwoIntegers(a, b: int): int {.importc.} + + when isMainModule: + echo addTwoIntegers(3, 7) + +With these two files in place, you can run ``nimrod c -r calculator.nim`` and +the Nimrod compiler will compile the ``logic.c`` file in addition to +``calculator.nim`` and link both into an executable, which outputs ``10`` when +run. Another way to link the C file statically and get the same effect would +be remove the line with the ``compile`` pragma and run the following typical +Unix commands:: + + $ gcc -c logic.c + $ ar rvs mylib.a logic.o + $ nimrod c --passL:mylib.a -r calculator.nim + +Just like in this example we pass the path to the ``mylib.a`` library (and we +could as well pass ``logic.o``) we could be passing switches to link any other +static C library. + + +JavaScript invocation example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create a ``host.html`` file with the following content: + +.. code-block:: + + + + + + +Create a ``calculator.nim`` file with the following content (or reuse the one +from the previous section): + +.. code-block:: nimrod + + proc addTwoIntegers(a, b: int): int {.importc.} + + when isMainModule: + echo addTwoIntegers(3, 7) + +Compile the Nimrod code to JavaScript with ``nimrod js -o:calculator.js +calculator.nim`` and open ``host.html`` in a browser. If the browser supports +javascript, you should see the value ``10``. In JavaScript the `echo proc +`_ will modify the HTML DOM and append the string. Use the +`dom module `_ for specific DOM querying and modification procs. Backend code calling Nimrod From f10d3b5fa6ffa4bb177dc2b7d63d07edcd234244 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sun, 22 Jun 2014 19:38:33 +0200 Subject: [PATCH 06/10] Adds examples of backend calling nimrod. --- doc/backends.txt | 113 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 3 deletions(-) diff --git a/doc/backends.txt b/doc/backends.txt index 957a2d2ed4..8bf353ff72 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -110,8 +110,8 @@ Nimrod code calling the backend Nimrod code can interface with the backend through the `Foreign function interface `_ mainly through the `importc pragma `_. The ``importc`` pragma is the -*generic* way of making backend code available in Nimrod and is available in -all the target backends (JavaScript too). The C++ or Objective-C backends +*generic* way of making backend symbols available in Nimrod and is available +in all the target backends (JavaScript too). The C++ or Objective-C backends have their respective `ImportCpp `_ and `ImportObjC `_ pragmas to call methods from classes. @@ -215,11 +215,118 @@ javascript, you should see the value ``10``. In JavaScript the `echo proc Backend code calling Nimrod --------------------------- -mention NimMain +Backend code can interface with Nimrod code exposed through the `exportc +pragma `_. The ``exportc`` pragma is the *generic* +way of making Nimrod symbols available to the backends. By default the Nimrod +compiler will mangle all the Nimrod symbols to avoid any name collision, so +the most significant thing the ``exportc`` pragma does is maintain the Nimrod +symbol name, or if specified, use an alternative symbol for the backend in +case the symbol rules don't match. + +The JavaScript target doesn't have any further interfacing considerations +since it also has garbage collection, but the C targets require you to +initialize Nimrod's internals, which is done calling a ``NimMain`` function. +Also, C code requires you to specify a forward declaration for functions or +the compiler will asume certain types for the return value and parameters +which will likely make your program crash at runtime. + +The Nimrod compiler can generate a C interface header through the ``--header`` +command line switch. The generated header will contain all the exported +symbols and the ``NimMain`` proc which you need to call before any other +Nimrod code. + + +Nimrod invocation example from C +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create a ``fib.nim`` file with the following content: + +.. code-block:: nimrod + + proc fib(a: cint): cint {.exportc.} = + if a <= 2: + result = 1 + else: + result = fib(a - 1) + fib(a - 2) + +Create a ``maths.c`` file with the following content: + +.. code-block:: c + + #include "fib.h" + #include + + int main(void) + { + NimMain(); + for (int f = 0; f < 10; f++) + printf("Fib of %d is %d\n", f, fib(f)); + return 0; + } + +Now you can run the following Unix like commands to first generate C sources +form the Nimrod code, then link it into a static binary:: + + $ nimrod c --noMain --noLinking --header:fib.h fib.nim + $ gcc -o m -Inimcache -Ipath/to/nimrod/lib nimcache/*.c maths.c + +The first command runs the Nimrod compiler with three special options to avoid +generating a ``main()`` function in the generated files, avoid linking the +object files into a final binary, and explicitly generate a header file for C +integration. All the generated files are placed into the ``nimcache`` +directory. That's why the next command compiles the ``maths.c`` source plus +all the ``.c`` files form ``nimcache``. In addition to this path, you also +have to tell the C compiler where to find Nimrod's ``nimbase.h`` header file. + +Instead of depending on the generation of the individual ``.c`` files you can +also ask the Nimrod compiler to generate a statically linked library:: + + $ nimrod c --app:staticLib --noMain --header fib.nim + $ gcc -o m -Inimcache -Ipath/to/nimrod/lib libfib.nim.a maths.c + +The Nimrod compiler will handle linking the source files generated in the +``nimcache`` directory into the ``libfib.nim.a`` static library, which you can +then link into your C program. Note that these commands are generic and will +vary for each system. For instance, on Linux systems you will likely need to +use ``-ldl`` too to link in required dlopen functionality. + + +Nimrod invocation example from JavaScript +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create a ``mhost.html`` file with the following content: + +.. code-block:: + + + + + + +Create a ``fib.nim`` file with the following content (or reuse the one +from the previous section): + +.. code-block:: nimrod + + proc fib(a: cint): cint {.exportc.} = + if a <= 2: + result = 1 + else: + result = fib(a - 1) + fib(a - 2) + +Compile the Nimrod code to JavaScript with ``nimrod js -o:fib.js fib.nim`` and +open ``mhost.html`` in a browser. If the browser supports javascript, you +should see an alert box displaying the text ``Fib for 9 is 34``. + Memory management ================= +Strings and C strings +--------------------- + Garbage collection, life of objects ----------------------------------- From ff1fe8b4ec64264171b419faff5fba4cf88b9a78 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sun, 22 Jun 2014 20:12:57 +0200 Subject: [PATCH 07/10] Mentions memory management. --- doc/backends.txt | 66 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/doc/backends.txt b/doc/backends.txt index 8bf353ff72..66d702f4e6 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -265,7 +265,8 @@ Create a ``maths.c`` file with the following content: } Now you can run the following Unix like commands to first generate C sources -form the Nimrod code, then link it into a static binary:: +form the Nimrod code, then link them into a static binary along your main C +program:: $ nimrod c --noMain --noLinking --header:fib.h fib.nim $ gcc -o m -Inimcache -Ipath/to/nimrod/lib nimcache/*.c maths.c @@ -318,17 +319,72 @@ from the previous section): Compile the Nimrod code to JavaScript with ``nimrod js -o:fib.js fib.nim`` and open ``mhost.html`` in a browser. If the browser supports javascript, you -should see an alert box displaying the text ``Fib for 9 is 34``. +should see an alert box displaying the text ``Fib for 9 is 34``. As mentioned +earlier, JavaScript doesn't require an initialisation call to ``NimMain`` or +similar function and you can call the exported Nimrod proc directly. Memory management ================= +In the previous sections the ``NimMain()`` function reared its head. Since +JavaScript already provides automatic memory management, you can freely pass +objects between the two language without problems. In C and derivate languages +you need to be careful about what you do and how you share memory. The +previous examples only dealt with simple scalar values, but passing a Nimrod +string to C, or reading back a C string in Nimrod already requires you to be +aware of who controls what to avoid crashing. + + Strings and C strings --------------------- -Garbage collection, life of objects ------------------------------------ +The manual mentions that `Nimrod strings are implicitly convertible to +cstrings `_ which makes interaction usually +painless. Most C functions accepting a Nimrod string converted to a +``cstring`` will likely not need to keep this string around and by the time +they return the string won't be needed any more. However, for the rare cases +where a Nimrod string has to be preserved and made available to the C backend +as a ``cstring``, you will need to manually prevent the string data from being +freed with `GC_ref `_ and `GC_unref +`_. + +A similar thing happens with C code invoking Nimrod code which returns a +``cstring``. Consider the following proc: + +.. code-block:: nimrod + + proc gimme(): cstring {.exportc.} = + result = "Hey there C code! " & $random(100) + +Since Nimrod's garbage collector is not aware of the C code, once the +``gimme`` proc has finished it can reclaim the memory of the ``cstring``. +However, from a practical standpoint, the C code invoking the ``gimme`` +function directly will be able to use it since Nimrod's garbage collector has +not had a chance to run *yet*. This gives you enough time to make a copy for +the C side of the program, as calling any further Nimrod procs *might* trigger +garbage collection making the previously returned string garbage. Or maybe you +are `triggering yourself the collection `_. + + +Custom data types +----------------- + +Just like strings, custom data types that are to be shared between Nimrod and +the backend will need careful consideration of who controlls who. If you want +to hand a Nimrod reference to C code, you will need to use `GC_ref +`_ to mark the reference as used, so it does not get +freed. And for the C backend you will need to expose the `GC_unref +`_ proc to clean up this memory when it is not required +any more. + +Again, if you are wrapping a library which *mallocs* and *frees* data +structures, you need to expose the appropriate *free* function to Nimrod so +you can clean it up. And of course, once cleaned you should avoid accessing it +from Nimrod (or C for that matter). Typically C data structures have their own +``malloc_structure`` and ``free_structure`` specific functions, so wrapping +these for the Nimrod side should be enough. + Thread coordination -------------------- +=================== From 6ca24cd246a38bf353219f38e1725baf982c9f6e Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Sun, 22 Jun 2014 20:19:09 +0200 Subject: [PATCH 08/10] Adds tidbit about threads. --- doc/backends.txt | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/doc/backends.txt b/doc/backends.txt index 66d702f4e6..8e16502e7a 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -387,4 +387,24 @@ these for the Nimrod side should be enough. Thread coordination -=================== +------------------- + +When the ``NimMain()`` function is called Nimrod initializes the garbage +collector to the current thread, which is usually the main thread of your +application. If your C code later spawns a different thread and calls Nimrod +code, the garbage collector will fail to work properly and you will crash. + +As long as you don't use the threadvar emulation Nimrod uses native thread +variables, of which you get a fresh version whenever you create a thread. You +can then attach a GC to this thread via + +.. code-block:: nimrod + + setStackBottom(addr(someLocal)) + initGC() + +At the moment this support is still experimental so you need to expose these +functions yourself or submit patches to request a public API. If the Nimrod +code you are calling is short lived, another possible solution is to disable +the garbage collector and enable it after the call from your background +thread. From b8982b78d032c25192b639971e671e35b7fe5a10 Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Thu, 26 Jun 2014 12:15:26 +0200 Subject: [PATCH 09/10] Rewords C derivate backend. Refs #1299. --- doc/backends.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/backends.txt b/doc/backends.txt index 8e16502e7a..6e77dfb3c0 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -24,12 +24,12 @@ platform's C compiler into a static binary. However there are other commands to compile to C++, Objective-C or JavaScript. This document tries to concentrate in a single place all the backend and interfacing options. -The Nimrod compiler supports mainly two backends: the C (and derivate) and the -JavaScript targets. The C target creates source files which can be compiled -into a library or a final executable. The JavaScript target generates a -``.js`` file which you call from an HTML file. On top of generating a library -or executable, Nimrod offers bidirectional interfacing with the backend -targets through generic and specific pragmas. +The Nimrod compiler supports mainly two backend families: the C, C++ and +Objective-C targets and the JavaScript target. `The C like targets`_ creates +source files which can be compiled into a library or a final executable. The +JavaScript target generates a ``.js`` file which you call from an HTML file. +On top of generating a library or executable, Nimrod offers bidirectional +interfacing with the backend targets through generic and specific pragmas. Backends From 14ba5263d3b6613156ce7b45b83b3d33dfc6840e Mon Sep 17 00:00:00 2001 From: Grzegorz Adam Hankiewicz Date: Thu, 26 Jun 2014 12:27:09 +0200 Subject: [PATCH 10/10] Mentions nodejs in js intro. Refs #1299. --- doc/backends.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/backends.txt b/doc/backends.txt index 6e77dfb3c0..0ab682c290 100644 --- a/doc/backends.txt +++ b/doc/backends.txt @@ -26,10 +26,13 @@ concentrate in a single place all the backend and interfacing options. The Nimrod compiler supports mainly two backend families: the C, C++ and Objective-C targets and the JavaScript target. `The C like targets`_ creates -source files which can be compiled into a library or a final executable. The -JavaScript target generates a ``.js`` file which you call from an HTML file. -On top of generating a library or executable, Nimrod offers bidirectional -interfacing with the backend targets through generic and specific pragmas. +source files which can be compiled into a library or a final executable. `The +JavaScript target`_ can generate a ``.js`` file which you reference from an +HTML file or create a `standalone nodejs program `_. + +On top of generating libraries or standalone applications, Nimrod offers +bidirectional interfacing with the backend targets through generic and +specific pragmas. Backends