Upgrade to Pro — share decks privately, control downloads, hide ads and more …

So you want to design a programming language

brixen
February 15, 2013
130

So you want to design a programming language

Talk about Rubinius as a language platform at Copious.

brixen

February 15, 2013
Tweet

Transcript

  1. class Array : public Object { private: Fixnum* total_; //

    slot Tuple* tuple_; // slot public: attr_accessor(total, Fixnum); attr_accessor(tuple, Tuple); }
  2. instruction send_method(literal) [ receiver -- value ] => send flush_ip();

    Object* recv = stack_top(); InlineCache* cache = reinterpret_cast<InlineCache*>(literal); Arguments args(cache->name, recv, cNil, 0, 0); Object* ret = cache->execute(state, call_frame, args); (void)stack_pop(); CHECK_AND_PUSH(ret); end
  3. class OneArgument { public: static bool call(STATE, VMMethod* vmm, StackVariables*

    scope, Arguments& args) { if(args.total() != 1) return false; scope->set_local(0, args.get_argument(0)); return true; } };
  4. def self.compile_string(string, file="(eval)", line=1) compiler = new :string, :compiled_code parser

    = compiler.parser parser.root AST::Script parser.default_transforms parser.input string, file, line compiler.run end
  5. $ rbx compile -e 'def m(a, b=1) a + b

    end' -N m -B ================== :m ================== Arguments: 1 required, 0 post, 2 total Locals: 2: a, b Stack size: 4 Lines to IP: 1: -1..14 0000: passed_arg 1 0002: goto_if_true 8 0004: meta_push_1 0005: set_local 1 # b 0007: pop 0008: push_local 0 # a 0010: push_local 1 # b 0012: meta_send_op_plus :+ 0014: ret ----------------------------------------
  6. $ rbx compile -e 'def m(a, b=1) a + b

    end' -B ============= :__script__ ============== Arguments: 0 required, 0 post, 0 total Locals: 0 Stack size: 5 Lines to IP: 1: 0..15 0000: push_rubinius 0001: push_literal :m 0003: push_literal #<Rubinius::CompiledCode m file=(snippet)> 0005: push_scope 0006: push_variables 0007: send_stack :method_visibility, 0 0010: send_stack :add_defn_method, 4 0013: pop 0014: push_true 0015: ret ----------------------------------------
  7. irb(main):007:0> m.hi you rang? [#<Rubinius::Executable:0xf3c>, :hi] => nil irb(main):008:0> m.hi

    "hello" you rang? [#<Rubinius::Executable:0xf3c>, :hi, "hello"] => nil
  8. $ rbx irb(main):001:0> class Cat irb(main):002:1> dynamic_method :meow do |g|

    irb(main):003:2* g.push :self irb(main):004:2> g.push_literal "meow" irb(main):005:2> g.send :puts, 1, true irb(main):006:2> g.ret irb(main):007:2> end irb(main):008:1> end
  9. $ rbx -Xprofile -e '10000.times { |x| x * x

    + x * 2 }' Thread 1: total running time: 0.073496367s % cumulative self self total time seconds seconds calls ms/call ms/call name ------------------------------------------------------------ 70.58 0.05 0.05 1 52.05 52.05 Rubinius::Tooling.disable 12.43 0.01 0.01 10000 0.00 0.00 Object::__script__<1> {} 7.24 0.02 0.01 1 5.34 16.74 Integer#times 3.03 0.00 0.00 20000 0.00 0.00 Fixnum#* 1.61 0.00 0.00 1 1.19 1.19 Rubinius::AST::Send#bytecode 1.38 0.00 0.00 1 1.02 2.78 Rubinius::Compiler::Parser#run 1.07 0.00 0.00 1 0.79 3.58 Rubinius::Compiler.compile_eval 0.74 0.00 0.00 4 0.14 0.44 Rubinius::Compiler::Stage#run_next 0.58 0.00 0.00 1 0.42 1.75 Rubinius::Compiler::Generator#run 0.53 0.02 0.00 1 0.39 20.97 Rubinius::Loader#evals 0.19 0.05 0.00 1 0.14 52.19 Rubinius::Profiler::Instrumenter#__stop__ 0.18 0.02 0.00 1 0.13 20.58 Kernel#eval 0.15 0.00 0.00 1 0.11 3.69 Rubinius::Compiler.construct_block 0.09 0.00 0.00 1 0.06 1.25 Rubinius::AST::EvalExpression::bytecode<906> 0.06 0.00 0.00 1 0.05 1.30 Rubinius::AST::Container#container_bytecode 0.05 0.05 0.00 1 0.04 52.25 Rubinius::Loader#epilogue 0.03 0.00 0.00 1 0.02 1.32 Rubinius::AST::EvalExpression#bytecode 0.01 0.00 0.00 1 0.01 2.79 Rubinius::Compiler#run 0.01 0.05 0.00 1 0.01 52.21 Object::__script__<4> {} 0.01 0.02 0.00 1 0.01 16.75 Object::__script__<1> {} 0.01 0.02 0.00 1 0.01 16.75 Rubinius::BlockEnvironment#call_on_instance 0.01 0.05 0.00 1 0.01 52.20 Profiler__.stop_profile 0.01 0.05 0.00 1 0.00 52.19 Rubinius::Profiler::Instrumenter#stop 0.01 0.05 0.00 1 0.00 52.20 Profiler__.print_profile 24 methods called a total of 30,025 times
  10. $ rbx console VM: rbx -Xagent.start Connecting to VM on

    port 56488 Connected to localhost:56488, host type: x86_64-apple-darw console>
  11. $ console> get system var system = [ "name", "backtrace",

    "threads", "gc", "memory", "pid", "jit", ]
  12. $ console> get system.pid var system.pid = [ 69118, ]

    $ console> get system.threads var system.threads = [ "count", "backtrace", ] $ console> get system.threads.count var system.threads.count = 2
  13. require "rubinius/agent" agent = Rubinius::Agent.loopback agent.request :set_config, "system.memory.dump", "before.d array

    = (0..10).map { |i| "x" * rand(i) } p array agent.request :set_config, "system.memory.dump", "after.du
  14. $ rbx -I /source/heap_dump/lib/ /source/heap_dump/bin/histo.rb before.dump 20738 Rubinius::Tuple 3763200 5820

    Object 279312 5001 Rubinius::MethodTable::Bucket 280056 4388 Rubinius::CompiledMethod 877600 4388 Rubinius::InstructionSequence 140416 3269 String 209216 3166 Rubinius::CharArray 166864 1815 Rubinius::LookupTable::Bucket 87120 1130 Rubinius::LookupTable 54240 1100 Rubinius::GlobalCacheEntry 52800 1047 Rubinius::MethodTable 50256 1001 Class 100384 835 Rubinius::StaticScope 40080 676 Rubinius::AccessVariable 54080 456 Array 25536 141 Hash::Entry 7896 123 Rubinius::CompactLookupTable 15744 105 Rubinius::NativeFunction 10920 102 Rubinius::InstructionSet::OpCode 13872 46 Module 2944 46 Float 1472 46 Rubinius::IncludedModule 3312 39 Rubinius::CompiledMethod::Script 2808 22 Hash 1760
  15. $ rbx -I /source/../lib /source/.../histo.rb before.dump after.dump 54 Object 2592

    11 String 704 11 Rubinius::CharArray 440 8 Rubinius::GlobalCacheEntry 384 2 Rubinius::CompactLookupTable 256 2 Rubinius::ByteArray 2624 2 Rubinius::Tuple 184 1 Rubinius::Randomizer 48 1 Bignum 56 1 Rubinius::VariableScope 104 1 Array 56