0
+ ...And `git push` to send back any of your commits to the C++ branch.
0
- Same here with the Rbx Rake tasks.
0
+ # nn the vm subdirectory
0
+ Compiling to .rbc with MRI
0
+----------------------------
0
+MRI can be used to compile Ruby files to bytecode, which can then be run by
0
+the VM. To compile 'file.rb' to 'file.rbc':
0
+ # in the root of the cpp directory
0
+ $ ruby lib/compiler/mri_compile.rb -frbx-kernel file.rb file.rbc
0
+ Running bytecode with the VM
0
+------------------------------
0
+Once a Ruby file has been compiled to bytecode (.rbc), it can be run by the VM
0
+with the following command:
0
+ # in the vm subdirectory
0
+Primitives are normal methods on C++ classes. Comment annotation links the C++
0
+method to a symbol with which the primitive is accessed in Ruby code.
0
+For example, consider the Ruby LookupTable class:
0
+ Ruby.primitive :lookuptable_fetch
0
+ raise PrimitiveFailure, "LookupTable#[] primitive failed"
0
+In the C++ file, rbx/vm/builtin_lookuptable.hpp, the primitive is annotated:
0
+ class LookupTable : public Object {
0
+ // Ruby.primitive :lookuptable_fetch
0
+ OBJECT fetch(STATE, OBJECT key);
0
+The magic for this happens in rbx/vm/field_extract.rb and the output goes to
0
+rbx/vm/gen/primitives_declare.hpp and rbx/vm/gen/primitives_glue.gen.cpp.
0
+ Overloaded C++ Methods as Primitives
0
+--------------------------------------
0
+There are two ways to annotate the C++ methods as primitives. If there is a
0
+single C++ method, use 'Ruby.primitive :name_of_primitive'. If there are
0
+multiple C++ methods (i.e. overloaded methods), use 'Ruby.primitive!
0
+:name_of_primitive'. The difference is the '!' method for defining overloaded
0
+methods as primitives. The resulting glue code for overloaded methods looks
0
+something like the following:
0
+bool Primitives::float_mul(STATE, VMExecutable* exec,
0
+ Task* task, Message& msg) {
0
+ if(Float* arg = try_as<Float>(msg.get_argument(0))) {
0
+ return as<Float>(msg.recv)->mul(state, arg);
0
+ if(Integer* arg = try_as<Integer>(msg.get_argument(0))) {
0
+ return as<Float>(msg.recv)->mul(state, arg);
0
+ throw new Assertion("unable to resolve primitive float_mul types");
0
+ } catch(PrimitiveFailed& e) {
0
+ task->primitive_return(ret, msg);
0
+Since the "primitives" are ordinary C++ methods, tests for them are written
0
+along with the other VM tests. Each builtin_xxx.cpp method has a corresponding
0
+rbx/vm/test/test_xxx.hpp method. See the existing files for more examples.
Comments
No one has commented yet.