6 This archive is the Rune language suite and tool chain, written by
7 Matthew Dillon. It is distributed under the Rune copyright which
8 can be found in the COPYRIGHT file. This is basically an open-source
9 copyright but with some restrictions to disallow project forking for
10 a period of time, and a few other things. It will eventually sunset into
11 a 2-clause BSD copyright and I may change the dates to sunset sooner,
12 but for the moment I need to keep relatively tight control over the
15 Rune is a powerful object-oriented language with built-in high-
16 performance threading, automatic object locking, bounds checking,
17 and many other powerful features. The current distribution implements
18 the Rune interpreter and the Rune code generator. The interpreter
19 should be easily ported to linux (its DragonFly/BSD specific at the
20 moment). The code generator is x86-64 (64 bit intel) only for now. We
21 will also be soliciting for help writing an ARM generator or making the
22 LLVM backend work (a lot more difficult then it might seem, I immediately
23 hit regressions in LLVM that results in 10-20 minute llvm compilation
24 times for simple programs).
26 Rune uses the standard BSD build system.
28 This README is meant only as a 'getting started' overview. More extensive
29 documentation is in docs/ and, frankly, at least until we get people on
30 board to help write documentation, understanding the language mostly
31 means going through the examples in classes/* and tests/*.
33 libruntime - Support library for rune utilities and runtime for
36 librune - Rune Language parser and resolver.
38 libgen - Rune Language Interpreter and Code Generator.
40 ext_x11 - Basic X11 interface (dynamically loaded at
41 parse-time and run-time), demonstrative of how to
42 add core APIs to the language.
44 rune - RUNE language front-end utility.
46 ras - RAS Rune Assembler utility.
48 classes - Rune Language - base classes shipped with the
49 language (gadgets gfx stdio sys etc)
51 tests - Rune Language - Test programs.
53 docs - Documentation (mostly HTML).
57 You can obtain the repository with the following GIT command:
59 git clone git://git.dragonflybsd.org/rune.git
61 If you are a DragonFly committer with permission to commit to the master
62 repo, we recommend these additional steps after creating the initial
65 # configure reasonable push defaults and set your username and
66 # email address for pushes.
68 git config --global push.default simple
69 git config --global --edit
71 # Then edit .git/config and change the repository to the master
72 # repo for pushes by changing the url line:
76 (edit the file, change the url line)
77 url = ssh://crater.dragonflybsd.org/repository/git/rune.git
81 On a DragonFly system the repo can be built as a user or as root.
83 as root - (recommended) This will install Rune in
84 /usr/local/rune/ plus two symlinks in /usr/local/bin
87 as user - (not recommended) This will install Rune in
88 ~/.rune/ plus two symlinks in ~/bin/ for 'ras' and
89 'rune'. Be sure that you have a ~/bin for your
90 user and that your $PATH includes it.
92 You can also build with or without an independend object hierarchy. We
93 recommend with (i.e. use make obj). Make sure the source tree is clean
94 before creating the object hierarchy. That way the source tree will
97 The suggested build sequence:
99 # WARNING! Be sure not to mix builds without the object hierarchy
100 # with builds with the object hierarchy. Your source
101 # tree should remain clean when building with the object
102 # hierarchy so make sure there aren't any junk object or
105 make clean cleandepend
113 Interpreter. From the rune repo:
117 Compiler (x86 64-bit only for now) examples. You can generate
118 intermediate Rune assembly by specifying a '.m' suffix, or x86 assembly
119 with a '.s' suffix. Otherwise rune will do everything needed to create
122 rune tests/hello.d -o x
125 # Generates intermediate RUNE assembly file only. This stops
126 # after the rune build stage and does not run 'ras'.
128 rune tests/hello.d -o x.m
130 # Generates machine assembly file only. This stops after
131 # 'ras' is run and does not run the platform assembler or linker.
133 rune tests/hello.d -o x.s
135 # Generates an actual binary. This runs all stages, through ras,
136 # and into the platform assembler and linker to generate a binary.
137 # The binary requires the rune infrastructure in ~/.rune or
138 # /usr/local/rune (depending on how you built rune) to operate.
140 rune tests/hello.d -o x -g
142 X11 basic tests w/threads. This will create a window with 900
143 simple input requestors each with a blinking cursor (which is
144 a thread, so 900+1 Rune threads and typically ~4-8 pthreads). Under
149 And under the compiler:
151 rune tests/gfxinput2.d -o x
156 You can interpret a rune script by making the script executable and
157 giving it a script startup as the first line:
159 #!/usr/local/bin/rune -x
161 See examples, in tests/*.d. The interpreter can run just about
162 everything but threading is still a bit primitive and it will have
163 problems with the few things in Rune which don't use the event handler
164 and block in real system calls. Be sure to use the -x option above to
165 tell rune to stop argument processing after the first filename, so
166 additional arguments you supply when you run it get fed into your
167 rune program verbatim.
169 The interpreter optimizes itself on the fly and is very fast, probably
170 near the top-end of performance for non-JIT interpreters. Nominal code
171 will run only 4-8x slower and tight loops only 25x slower in the
172 interpreter. For example, on a 3.4GHz Haswell the interpreter can
173 execute a tight loop for (i = 0; i < 1000000000L; ++i); with an overhead
174 of around 7ns per loop, which is significantly better than most other
175 interpreted languages.
179 Currently the only operational code generator is the 64-bit x86 backend
180 in the rune assembler. This is the default code generation path which
181 you get when you specify an output file on the rune command line. The
182 llvm backend is currently non-operational. I was able to get it to work
183 previously but its a real bitch to interface to and I seem to be hitting
184 degenerate conditions which cause it to twiddle its thumbs for a very
185 long time on simple programs (sometimes upwards of 15 minutes!). So I've
186 had to set it aside for now.
188 Rune generates pseudo-assembly output that it will feed into RAS (the
189 Rune assembler), which then optimizes and converts it to x86. That is
190 fed into the normal compiler backend ('as', then 'cc' in linker mode).
191 RAS makes use of a number of special ELF features such as section
192 grouping and weak stubs. My original intend was to develop an entire
193 toolchain but it simply became too much work so Rune generates assembly.
195 Currently Rune cannot really generate independent object modules for
196 Rune source files. It really needs to generate a single output file
197 which gets fed through the assembler, compiler, and linker. Ultimately
198 the intent is to be able to generate an object module at each library
203 Rune's pseudo-assembly implements a nice orthogonal instruction set along
204 with some meta-instructions for locking and ref-counting to interface
205 with the runtime. Rune generates the assembly (you can see it if you
206 output to a *.m file). The assembly implements an infinite register
207 set and RAS is capable of optimizing stack-based memory objects into
208 registers when given appropriate hints, which RUNE generates.
210 RAS implements a fairly sophisticated register optimizer. It certainly
211 can't compete with GCC but it's fast and it works pretty well. It
212 converts the pseudo-assembly into a basic-block model, adding JMPs as
213 needed (it does not require RUNE to generate basic blocks as output).
215 RAS implements graph-based object life calculations for cacheable
216 stack-based memory objects and virtual registers and can do some
217 instruction pruning based on that. It also implements extra-register
218 spills around calls if it thinks they are needed.
220 It implements conditional optimizations and is capable of both reversing
221 AND inverting conditional tests to produce relatively optimal code
224 RAS does not implement constant expression collapses, that's actually
225 something the RUNE frontend does during the compilation process so RAS
226 does not have (and does not need) any sort of complex expression handler.
228 RAS implements a number of simple instruction optimizations, patricularly
229 when zeroing small blocks with BZERO, using the instruction extension
230 as an alignment hint.
232 RUNE and RAS implement 32, 64, and 128-bit floats but do not implement any
233 floating point vectorization, and in-fact I might never implement
234 vectorization as a native feature. What I may do instead is implement
235 core types for matrices and vectors and basic operations (there aren't
236 actually too many) that do. That is way in the future though.
238 The Rune call model is *NOT* heavily optimized yet. It uses a memory
239 vector for both call arguments AND return values which is not yet
240 registerized. Also the mandatory locking is not heavily optimized yet,
241 so there is a lot of overhead associated with object locks and refs.
243 Despite that, Rune binaries should run quite fast.
247 Rune's run-time threading model is very sophisticated. Basically it
248 uses sigjmpbuf()s without signal masking which is pretty much the
249 ultimate in terms of switching speed and compactness (roughly spills
250 14 registers and switches without having to make any system calls).
252 Rune uses N:M threading so the number of pthreads it creates is
253 relatively limited, making Rune threads EXTREMELY light-weight. Since
254 Rune is a threading-centric language this winds up being very important.
255 The tests/gfxinput2.d test program demonstrates light-weight threading.
259 The documentation will improve as the project progresses. For the moment
260 you will need to learn by example, primariliy by looking at the various
261 tests in tests/*.d and the class hierarchy in classes/*. The
262 docs/grammer.html and docs/overview.html files are fairly complete.