Ruby [DRAFT]
Created at 2017-04-21T16:32:41+09:00

TODO

  • require, gem
  • class/module/object basics
    • type of variables
    • attr
    • include and ancestors
    • method resolution
  • scope, stack frame
  • block, yield semantics
  • object memory layout (on heap, on stack)
  • threading
  • garbage collection
  • builtin (native), non-builtin
  • standard library, bundled_gem
  • Init_xxx
  • concurrency primitive
    • why explicit mutex even if there's GIL (for Jruby compativility ?)

Build from source

$ mkdir -p _install
$ ./configure --prefix=$PWD/_install CC=clang
$ make install -j 3

Main path

- main =>
  - ruby_init_stack (?)
  - ruby_init =>
    - ruby_setup =>
      - ruby_init_stack
      - Init_BareVM =>
        - alloc rb_vm_t and rb_thread_t
        - ruby_current_thread = th
        - vm_init2
        - ruby_current_vm = vm
        - Init_native_thread
        - th->vm = vm
        - th_init(th, 0) => th->waiting_fd = -1
      - Init_heap
      - Init_vm_objects
      - rb_call_inits =>
        - Init_xxx (e.g. sym, var_tables, Object, top_self, ...)
      - ruby_prog_init => define ARGV kinds of variables
  - ruby_options =>
    - ruby_process_options =>
      - ruby_script
      - process_options =>
        - proc_options => (fill ruby_cmdline_options_t)
        - parser = rb_parser_new
        - GetBindingPtr(... toplevel_binding) => ?
        - base_block = toplevel_context(toplevel_binding)
        - rb_parser_set_context(parser, base_block, TRUE)
        - tree = load_file(parser, opt->script_name, 1, opt) => ?
        - base_block = toplevel_context(toplevel_binding)
        - rb_iseq_new_main(tree, ..., vm_block_iseq(base_block)) => ?
  - ruby_run_node =>
    - ruby_exec_node
      - ruby_init_stack
      - return ruby_exec_internal =>
        - rb_iseq_eval_main
          - vm_set_main_stack
          - vm_exec (SEE BELOW)

[ Init things ]
- Init_sym =>
  - (setup global_symbols)
  - Init_op_tbl
  - Init_id =>

- Init_var_tables =>
  - (setup rb_global_tbl and generic_iv_tbl)

- Init_Object =>
  - InitVM(Object) (macro of InitVM_Object)
    - InitVM_Object =>
      - Init_class_hierarchy =>

- Init_top_self =>
  - GET_VM()->top_self = rb_obj_alloc(rb_cObject)

[ vm ]
- vm_exec =>
  - vm_exec_core =>
    - INSN_DISPATCH =>
      - GET_CURRENT_INSN
    - END_INSNS_DISPATCH

Q.
- kinds of state
- check rb_thread_t's fields
- vm state (register, frame)


(vm_core.h)
rb_vm_t
'-' rb_thread_t
  '-' rb_control_frame_t

- rb_call_info
- rb_iseq_t
- rb_binding_t
- rb_env_t ?
- rb_proc_t
- rb_vm_defineclass_type_t
- rb_block

VM_FRAME_xxx

Ruby runtime globals

  • global_symbols
  • rb_global_tbl
  • generic_iv_tbl
  • rb_objspace

Data Structure

  • include/ruby/

    • ruby.h
    • RBasic, RObject, RString, ...
    • gc related tags (write barrier (remember set?), promotion)
  • internal.h
    • RClass

-

  • rb_global_variable

    • rb_binding_t

    • Q

  • do we unbox some type of value ?

- class and instance
- scope and stack frame
- method call


RBasic
'-' flags (comsists of ruby_fl_type)
'-' klass

RObject
'-' RBasic


(internal.h)
RClass
'-' RBasic
'-' super

Threading

  • thread_pthread.c, .h
  • man 7 pthread
  • gvl acquiring/releasing and its usage pattern
```


# Installed directory structure

Try installing using brand-new gem executable:

$ ./_install/bin/gem install bundler $ ./_install/bin/gem list --local *** LOCAL GEMS ***

bigdecimal (default: 1.3.2) bundler (1.14.6) cmath (default: 0.0.1) ...

Here is how it looks:
  • lib/ruby/
    • 2.5.0/
    • bigdecimal/
    • ... (standard libraries)
    • x86_64-linux/
      • bigdecimal.so (c part of standard library)
      • ...
    • gems/2.5.0/
    • gems/
      • bundler-1.14.6/ (ruby gem installed by gem)
    • specifications/
      • default/
      • bigdecimal-1.3.2.gemspec ... (standard libraries)
      • bundler-1.14.6.gemspec (ruby gem installed by gem)
    • site_ruby/ (?)
    • vendor_ruby/ (?) ```

Reference