ruby-internal 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +59 -0
- data/LGPL +515 -0
- data/LICENSE +9 -0
- data/README +31 -0
- data/Rakefile +20 -0
- data/TODO +9 -0
- data/example/README +5 -0
- data/example/simple_client.rb +12 -0
- data/example/simple_server.rb +11 -0
- data/example/triangle_client.rb +7 -0
- data/example/triangle_server.rb +24 -0
- data/ext/cached/ruby-1.8.0/internal/binding/block.h +37 -0
- data/ext/cached/ruby-1.8.0/internal/method/method.h +19 -0
- data/ext/cached/ruby-1.8.0/internal/module/classpath.c +27 -0
- data/ext/cached/ruby-1.8.0/internal/module/classpath.h +14 -0
- data/ext/cached/ruby-1.8.0/internal/node/block.h +37 -0
- data/ext/cached/ruby-1.8.0/internal/node/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.0/internal/node/node_type_descrip.c +155 -0
- data/ext/cached/ruby-1.8.0/internal/node/nodeinfo.c +5741 -0
- data/ext/cached/ruby-1.8.0/internal/node/nodeinfo.h +69 -0
- data/ext/cached/ruby-1.8.0/internal/proc/block.h +37 -0
- data/ext/cached/ruby-1.8.0/internal/tag/tag.h +15 -0
- data/ext/cached/ruby-1.8.0/internal/vm/instruction/insns_info.c +39 -0
- data/ext/cached/ruby-1.8.0/internal/vm/instruction/insns_info.h +21 -0
- data/ext/cached/ruby-1.8.0/internal/vm/iseq/insns_info.inc +12 -0
- data/ext/cached/ruby-1.8.1/internal/binding/block.h +31 -0
- data/ext/cached/ruby-1.8.1/internal/method/method.h +19 -0
- data/ext/cached/ruby-1.8.1/internal/module/classpath.c +27 -0
- data/ext/cached/ruby-1.8.1/internal/module/classpath.h +14 -0
- data/ext/cached/ruby-1.8.1/internal/node/block.h +31 -0
- data/ext/cached/ruby-1.8.1/internal/node/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.1/internal/node/node_type_descrip.c +154 -0
- data/ext/cached/ruby-1.8.1/internal/node/nodeinfo.c +5733 -0
- data/ext/cached/ruby-1.8.1/internal/node/nodeinfo.h +69 -0
- data/ext/cached/ruby-1.8.1/internal/proc/block.h +31 -0
- data/ext/cached/ruby-1.8.1/internal/tag/tag.h +16 -0
- data/ext/cached/ruby-1.8.1/internal/vm/instruction/insns_info.c +39 -0
- data/ext/cached/ruby-1.8.1/internal/vm/instruction/insns_info.h +21 -0
- data/ext/cached/ruby-1.8.1/internal/vm/iseq/insns_info.inc +12 -0
- data/ext/cached/ruby-1.8.2/internal/binding/block.h +32 -0
- data/ext/cached/ruby-1.8.2/internal/method/method.h +19 -0
- data/ext/cached/ruby-1.8.2/internal/module/classpath.c +45 -0
- data/ext/cached/ruby-1.8.2/internal/module/classpath.h +17 -0
- data/ext/cached/ruby-1.8.2/internal/node/block.h +32 -0
- data/ext/cached/ruby-1.8.2/internal/node/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.2/internal/node/node_type_descrip.c +154 -0
- data/ext/cached/ruby-1.8.2/internal/node/nodeinfo.c +5733 -0
- data/ext/cached/ruby-1.8.2/internal/node/nodeinfo.h +69 -0
- data/ext/cached/ruby-1.8.2/internal/proc/block.h +32 -0
- data/ext/cached/ruby-1.8.2/internal/tag/tag.h +16 -0
- data/ext/cached/ruby-1.8.2/internal/vm/instruction/insns_info.c +39 -0
- data/ext/cached/ruby-1.8.2/internal/vm/instruction/insns_info.h +21 -0
- data/ext/cached/ruby-1.8.2/internal/vm/iseq/insns_info.inc +12 -0
- data/ext/cached/ruby-1.8.3/internal/binding/block.h +32 -0
- data/ext/cached/ruby-1.8.3/internal/method/method.h +20 -0
- data/ext/cached/ruby-1.8.3/internal/module/classpath.c +45 -0
- data/ext/cached/ruby-1.8.3/internal/module/classpath.h +17 -0
- data/ext/cached/ruby-1.8.3/internal/node/block.h +32 -0
- data/ext/cached/ruby-1.8.3/internal/node/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.3/internal/node/node_type_descrip.c +154 -0
- data/ext/cached/ruby-1.8.3/internal/node/nodeinfo.c +5733 -0
- data/ext/cached/ruby-1.8.3/internal/node/nodeinfo.h +69 -0
- data/ext/cached/ruby-1.8.3/internal/proc/block.h +32 -0
- data/ext/cached/ruby-1.8.3/internal/tag/tag.h +16 -0
- data/ext/cached/ruby-1.8.3/internal/vm/instruction/insns_info.c +39 -0
- data/ext/cached/ruby-1.8.3/internal/vm/instruction/insns_info.h +21 -0
- data/ext/cached/ruby-1.8.3/internal/vm/iseq/insns_info.inc +12 -0
- data/ext/cached/ruby-1.8.4/internal/binding/block.h +32 -0
- data/ext/cached/ruby-1.8.4/internal/method/method.h +20 -0
- data/ext/cached/ruby-1.8.4/internal/module/classpath.c +45 -0
- data/ext/cached/ruby-1.8.4/internal/module/classpath.h +17 -0
- data/ext/cached/ruby-1.8.4/internal/node/block.h +32 -0
- data/ext/cached/ruby-1.8.4/internal/node/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.4/internal/node/node_type_descrip.c +154 -0
- data/ext/cached/ruby-1.8.4/internal/node/nodeinfo.c +5733 -0
- data/ext/cached/ruby-1.8.4/internal/node/nodeinfo.h +69 -0
- data/ext/cached/ruby-1.8.4/internal/proc/block.h +32 -0
- data/ext/cached/ruby-1.8.4/internal/tag/tag.h +16 -0
- data/ext/cached/ruby-1.8.4/internal/vm/instruction/insns_info.c +39 -0
- data/ext/cached/ruby-1.8.4/internal/vm/instruction/insns_info.h +21 -0
- data/ext/cached/ruby-1.8.4/internal/vm/iseq/insns_info.inc +12 -0
- data/ext/cached/ruby-1.8.5/internal/binding/block.h +32 -0
- data/ext/cached/ruby-1.8.5/internal/method/method.h +20 -0
- data/ext/cached/ruby-1.8.5/internal/module/classpath.c +45 -0
- data/ext/cached/ruby-1.8.5/internal/module/classpath.h +17 -0
- data/ext/cached/ruby-1.8.5/internal/node/block.h +32 -0
- data/ext/cached/ruby-1.8.5/internal/node/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.5/internal/node/node_type_descrip.c +154 -0
- data/ext/cached/ruby-1.8.5/internal/node/nodeinfo.c +5732 -0
- data/ext/cached/ruby-1.8.5/internal/node/nodeinfo.h +67 -0
- data/ext/cached/ruby-1.8.5/internal/proc/block.h +32 -0
- data/ext/cached/ruby-1.8.5/internal/tag/tag.h +16 -0
- data/ext/cached/ruby-1.8.5/internal/vm/instruction/insns_info.c +39 -0
- data/ext/cached/ruby-1.8.5/internal/vm/instruction/insns_info.h +21 -0
- data/ext/cached/ruby-1.8.5/internal/vm/iseq/insns_info.inc +12 -0
- data/ext/cached/ruby-1.8.6/internal/binding/block.h +32 -0
- data/ext/cached/ruby-1.8.6/internal/method/method.h +20 -0
- data/ext/cached/ruby-1.8.6/internal/module/classpath.c +45 -0
- data/ext/cached/ruby-1.8.6/internal/module/classpath.h +17 -0
- data/ext/cached/ruby-1.8.6/internal/node/block.h +32 -0
- data/ext/cached/ruby-1.8.6/internal/node/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.6/internal/node/node_type_descrip.c +154 -0
- data/ext/cached/ruby-1.8.6/internal/node/nodeinfo.c +5732 -0
- data/ext/cached/ruby-1.8.6/internal/node/nodeinfo.h +67 -0
- data/ext/cached/ruby-1.8.6/internal/proc/block.h +32 -0
- data/ext/cached/ruby-1.8.6/internal/tag/tag.h +16 -0
- data/ext/cached/ruby-1.8.6/internal/vm/instruction/insns_info.c +39 -0
- data/ext/cached/ruby-1.8.6/internal/vm/instruction/insns_info.h +21 -0
- data/ext/cached/ruby-1.8.6/internal/vm/iseq/insns_info.inc +12 -0
- data/ext/cached/ruby-1.8.7/internal/binding/block.h +32 -0
- data/ext/cached/ruby-1.8.7/internal/method/method.h +20 -0
- data/ext/cached/ruby-1.8.7/internal/module/classpath.c +45 -0
- data/ext/cached/ruby-1.8.7/internal/module/classpath.h +17 -0
- data/ext/cached/ruby-1.8.7/internal/node/block.h +32 -0
- data/ext/cached/ruby-1.8.7/internal/node/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.7/internal/node/node_type_descrip.c +154 -0
- data/ext/cached/ruby-1.8.7/internal/node/nodeinfo.c +5732 -0
- data/ext/cached/ruby-1.8.7/internal/node/nodeinfo.h +67 -0
- data/ext/cached/ruby-1.8.7/internal/proc/block.h +32 -0
- data/ext/cached/ruby-1.8.7/internal/tag/tag.h +16 -0
- data/ext/cached/ruby-1.8.7/internal/vm/instruction/insns_info.c +39 -0
- data/ext/cached/ruby-1.8.7/internal/vm/instruction/insns_info.h +21 -0
- data/ext/cached/ruby-1.8.7/internal/vm/iseq/insns_info.inc +12 -0
- data/ext/cached/ruby-1.9.0/internal/binding/block.h +12 -0
- data/ext/cached/ruby-1.9.0/internal/method/method.h +20 -0
- data/ext/cached/ruby-1.9.0/internal/module/classpath.c +42 -0
- data/ext/cached/ruby-1.9.0/internal/module/classpath.h +17 -0
- data/ext/cached/ruby-1.9.0/internal/node/block.h +12 -0
- data/ext/cached/ruby-1.9.0/internal/node/global_entry.h +10 -0
- data/ext/cached/ruby-1.9.0/internal/node/node_type_descrip.c +149 -0
- data/ext/cached/ruby-1.9.0/internal/node/nodeinfo.c +5579 -0
- data/ext/cached/ruby-1.9.0/internal/node/nodeinfo.h +70 -0
- data/ext/cached/ruby-1.9.0/internal/proc/block.h +12 -0
- data/ext/cached/ruby-1.9.0/internal/tag/tag.h +6 -0
- data/ext/cached/ruby-1.9.0/internal/vm/instruction/insns_info.c +5936 -0
- data/ext/cached/ruby-1.9.0/internal/vm/instruction/insns_info.h +891 -0
- data/ext/cached/ruby-1.9.0/internal/vm/iseq/insns_info.inc +700 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/debug.h +36 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/dln.h +41 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/encdb.h +147 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/eval_intern.h +221 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/gc.h +75 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/id.h +83 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/iseq.h +94 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/node.h +516 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/parse.h +303 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/regenc.h +207 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/regint.h +842 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/regparse.h +351 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/revision.h +1 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/thread_pthread.h +24 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/thread_win32.h +33 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/transcode_data.h +99 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/transdb.h +67 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/version.h +57 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_core.h +663 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_exec.h +187 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_insnhelper.h +191 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/vm_opts.h +51 -0
- data/ext/cached/ruby-1.9.1/internal/binding/block.h +12 -0
- data/ext/cached/ruby-1.9.1/internal/method/method.h +20 -0
- data/ext/cached/ruby-1.9.1/internal/module/classpath.c +42 -0
- data/ext/cached/ruby-1.9.1/internal/module/classpath.h +17 -0
- data/ext/cached/ruby-1.9.1/internal/node/block.h +12 -0
- data/ext/cached/ruby-1.9.1/internal/node/global_entry.h +10 -0
- data/ext/cached/ruby-1.9.1/internal/node/node_type_descrip.c +149 -0
- data/ext/cached/ruby-1.9.1/internal/node/nodeinfo.c +5579 -0
- data/ext/cached/ruby-1.9.1/internal/node/nodeinfo.h +70 -0
- data/ext/cached/ruby-1.9.1/internal/proc/block.h +12 -0
- data/ext/cached/ruby-1.9.1/internal/tag/tag.h +6 -0
- data/ext/cached/ruby-1.9.1/internal/vm/instruction/insns_info.c +5936 -0
- data/ext/cached/ruby-1.9.1/internal/vm/instruction/insns_info.h +891 -0
- data/ext/cached/ruby-1.9.1/internal/vm/iseq/insns_info.inc +700 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/debug.h +36 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/dln.h +41 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/encdb.h +147 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/eval_intern.h +209 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/gc.h +75 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/id.h +184 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/iseq.h +94 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/node.h +516 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/parse.h +303 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/regenc.h +207 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/regint.h +842 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/regparse.h +351 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/revision.h +1 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/thread_pthread.h +24 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/thread_win32.h +33 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/transcode_data.h +99 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/transdb.h +85 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/version.h +60 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_core.h +655 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_exec.h +187 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_insnhelper.h +194 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_opts.h +51 -0
- data/ext/internal/binding/binding.c +45 -0
- data/ext/internal/binding/block.h.rpp +44 -0
- data/ext/internal/binding/extconf.rb +6 -0
- data/ext/internal/method/extconf.rb +8 -0
- data/ext/internal/method/method.c +269 -0
- data/ext/internal/method/method.h.rpp +58 -0
- data/ext/internal/module/classpath.c.rpp +29 -0
- data/ext/internal/module/classpath.h.rpp +36 -0
- data/ext/internal/module/extconf.rb +11 -0
- data/ext/internal/module/module.c +797 -0
- data/ext/internal/module/module.h +7 -0
- data/ext/internal/node/block.h.rpp +44 -0
- data/ext/internal/node/builtins.h +41 -0
- data/ext/internal/node/extconf.rb +66 -0
- data/ext/internal/node/global_entry.h.rpp +26 -0
- data/ext/internal/node/node.c +1147 -0
- data/ext/internal/node/node_type_descrip.c.rpp +72 -0
- data/ext/internal/node/node_type_descrip.h +17 -0
- data/ext/internal/node/node_type_descrip.rb +39 -0
- data/ext/internal/node/nodeinfo.c.rpp +587 -0
- data/ext/internal/node/nodeinfo.h.rpp +30 -0
- data/ext/internal/node/nodes.rb +78 -0
- data/ext/internal/node/read_node_h.rb +34 -0
- data/ext/internal/node/ruby_internal_node.h +31 -0
- data/ext/internal/noex/extconf.rb +6 -0
- data/ext/internal/noex/noex.c +44 -0
- data/ext/internal/object/extconf.rb +4 -0
- data/ext/internal/object/object.c +75 -0
- data/ext/internal/proc/block.h.rpp +44 -0
- data/ext/internal/proc/extconf.rb +9 -0
- data/ext/internal/proc/proc.c +331 -0
- data/ext/internal/tag/extconf.rb +3 -0
- data/ext/internal/tag/tag.c +17 -0
- data/ext/internal/tag/tag.h.rpp +22 -0
- data/ext/internal/thread/extconf.rb +3 -0
- data/ext/internal/thread/thread.c +107 -0
- data/ext/internal/vm/constants/constants.c +33 -0
- data/ext/internal/vm/constants/extconf.rb +3 -0
- data/ext/internal/vm/control_frame/control_frame.c +185 -0
- data/ext/internal/vm/control_frame/control_frame.h +18 -0
- data/ext/internal/vm/control_frame/extconf.rb +3 -0
- data/ext/internal/vm/extconf.rb +3 -0
- data/ext/internal/vm/inline_cache/extconf.rb +6 -0
- data/ext/internal/vm/inline_cache/inline_cache.c +79 -0
- data/ext/internal/vm/instruction/extconf.rb +6 -0
- data/ext/internal/vm/instruction/insns_info.c.rpp +213 -0
- data/ext/internal/vm/instruction/insns_info.h.rpp +53 -0
- data/ext/internal/vm/instruction/instruction.c +78 -0
- data/ext/internal/vm/instruction/instruction.h +10 -0
- data/ext/internal/vm/iseq/extconf.rb +7 -0
- data/ext/internal/vm/iseq/insns_info.inc.rpp +30 -0
- data/ext/internal/vm/iseq/internal_iseq.h +9 -0
- data/ext/internal/vm/iseq/iseq.c +555 -0
- data/ext/internal/vm/vm.c +55 -0
- data/ext/mkmf-ruby-internal.rb +111 -0
- data/ext/ruby_source_dir.rb +24 -0
- data/ext/rubypp.rb +97 -0
- data/generate_rdoc.rb +33 -0
- data/lib/internal/binding.rb +1 -0
- data/lib/internal/classtree.rb +55 -0
- data/lib/internal/debug.rb +16 -0
- data/lib/internal/method.rb +1 -0
- data/lib/internal/method/as_code.rb +33 -0
- data/lib/internal/method/as_expression.rb +34 -0
- data/lib/internal/method/signature.rb +442 -0
- data/lib/internal/module.rb +1 -0
- data/lib/internal/module/as_code.rb +45 -0
- data/lib/internal/node.rb +3 -0
- data/lib/internal/node/as_code.rb +233 -0
- data/lib/internal/node/as_expression.rb +619 -0
- data/lib/internal/node/dump.rb +53 -0
- data/lib/internal/node/pp.rb +72 -0
- data/lib/internal/node/to_a.rb +52 -0
- data/lib/internal/noex.rb +1 -0
- data/lib/internal/obfusc.rb +57 -0
- data/lib/internal/object.rb +1 -0
- data/lib/internal/object/as_code.rb +10 -0
- data/lib/internal/proc.rb +1 -0
- data/lib/internal/proc/as_code.rb +21 -0
- data/lib/internal/proc/as_expression.rb +14 -0
- data/lib/internal/proc/signature.rb +184 -0
- data/lib/internal/tag.rb +1 -0
- data/lib/internal/thread.rb +1 -0
- data/lib/internal/vm.rb +1 -0
- data/lib/internal/vm/bytedecoder.rb +866 -0
- data/lib/internal/vm/constants.rb +1 -0
- data/lib/internal/vm/control_frame.rb +1 -0
- data/lib/internal/vm/inline_cache.rb +1 -0
- data/lib/internal/vm/instruction.rb +1 -0
- data/lib/internal/vm/iseq.rb +1 -0
- data/lib/internal/vm/iseq/as_code.rb +27 -0
- data/lib/internal/vm/iseq/as_expression.rb +26 -0
- data/metaconfig +19 -0
- data/post-config.rb +1 -0
- data/post-install.rb +4 -0
- data/post-setup.rb +7 -0
- data/pre-config.rb +96 -0
- data/pre-install.rb +13 -0
- data/pre-setup.rb +8 -0
- data/run_tests.rb +26 -0
- data/setup.rb +1599 -0
- data/test/expression_samples.rb +160 -0
- data/test/node_samples.rb +122 -0
- data/test/test_as_code.rb +261 -0
- data/test/test_as_expression.rb +229 -0
- data/test/test_dump_class.rb +187 -0
- data/test/test_dump_method.rb +144 -0
- data/test/test_dump_proc.rb +118 -0
- data/test/test_helpers.rb +61 -0
- data/test/test_method.rb +72 -0
- data/test/test_methodsig.rb +267 -0
- data/test/test_module.rb +49 -0
- data/test/test_node.rb +77 -0
- data/test/test_proc.rb +47 -0
- metadata +377 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
$: << '../..'
|
|
2
|
+
require 'mkmf-ruby-internal'
|
|
3
|
+
|
|
4
|
+
have_func('vm_get_ruby_level_cfp')
|
|
5
|
+
have_func('vm_get_ruby_level_next_cfp')
|
|
6
|
+
have_header('ruby/node.h') or have_header('node.h')
|
|
7
|
+
|
|
8
|
+
ruby_version_code = RUBY_VERSION.gsub(/\./, '').to_i
|
|
9
|
+
$CPPFLAGS << " -DRUBY_VERSION_CODE=#{ruby_version_code}"
|
|
10
|
+
|
|
11
|
+
create_ruby_internal_makefile 'internal/module/module'
|
|
@@ -0,0 +1,797 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
#include "internal/node/ruby_internal_node.h"
|
|
3
|
+
|
|
4
|
+
#ifdef RUBY_VM
|
|
5
|
+
#include <ruby/st.h>
|
|
6
|
+
#include "vm_core.h"
|
|
7
|
+
#include "eval_intern.h"
|
|
8
|
+
#else
|
|
9
|
+
#include <rubysig.h>
|
|
10
|
+
#include <st.h>
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
#ifndef RCLASS_SUPER
|
|
14
|
+
#define RCLASS_SUPER(c) RCLASS(c)->super
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
#ifndef RCLASS_IV_TBL
|
|
18
|
+
#define RCLASS_IV_TBL(c) RCLASS(c)->iv_tbl
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
#ifndef RCLASS_M_TBL
|
|
22
|
+
#define RCLASS_M_TBL(c) RCLASS(c)->m_tbl
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
#ifndef RARRAY_LEN
|
|
26
|
+
#define RARRAY_LEN(a) RARRAY(a)->len
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
#ifndef RARRAY_PTR
|
|
30
|
+
#define RARRAY_PTR(a) RARRAY(a)->ptr
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
static VALUE rb_cNode;
|
|
34
|
+
|
|
35
|
+
static VALUE rb_mMarshal;
|
|
36
|
+
|
|
37
|
+
static VALUE rb_cClass_Restorer;
|
|
38
|
+
|
|
39
|
+
static VALUE marshal_dump(VALUE obj, VALUE limit)
|
|
40
|
+
{
|
|
41
|
+
return rb_funcall(rb_mMarshal, rb_intern("dump"), 2, obj, limit);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static VALUE marshal_load(VALUE obj)
|
|
45
|
+
{
|
|
46
|
+
return rb_funcall(rb_mMarshal, rb_intern("load"), 1, obj);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#if RUBY_VERSION_CODE >= 180
|
|
50
|
+
struct Class_Restorer
|
|
51
|
+
{
|
|
52
|
+
VALUE klass;
|
|
53
|
+
struct st_table m_tbl;
|
|
54
|
+
struct st_table iv_tbl;
|
|
55
|
+
#ifndef RUBY_VM
|
|
56
|
+
int thread_critical;
|
|
57
|
+
#endif
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
#if RUBY_VERSION_CODE >= 180
|
|
61
|
+
static void mark_class_restorer(struct Class_Restorer * class_restorer)
|
|
62
|
+
{
|
|
63
|
+
rb_mark_tbl(&class_restorer->m_tbl);
|
|
64
|
+
rb_mark_tbl(&class_restorer->iv_tbl);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static VALUE create_class_restorer(VALUE klass)
|
|
68
|
+
{
|
|
69
|
+
/* On Ruby 1.8, there is a check in marshal_dump() to ensure that
|
|
70
|
+
* the object being dumped has no modifications to its singleton
|
|
71
|
+
* class (e.g. no singleton instance variables, and no singleton
|
|
72
|
+
* methods defined). Since we need to dump the class's singleton
|
|
73
|
+
* class in order to dump class methods, we need a way around this
|
|
74
|
+
* restriction. The solution found here temporarily removes the
|
|
75
|
+
* singleton instance variables and singleton methods while the
|
|
76
|
+
* class is being dumped, and sets a special singleton instance
|
|
77
|
+
* variable that restores the tables when dumping is complete. A
|
|
78
|
+
* hack for sure, but it seems to work.
|
|
79
|
+
*/
|
|
80
|
+
struct RClass * singleton_class = RCLASS(CLASS_OF(klass));
|
|
81
|
+
struct Class_Restorer * class_restorer;
|
|
82
|
+
|
|
83
|
+
if(!RCLASS_IV_TBL(singleton_class))
|
|
84
|
+
{
|
|
85
|
+
rb_raise(
|
|
86
|
+
rb_eTypeError,
|
|
87
|
+
"can't dump singleton class on Ruby 1.8 without iv_tbl");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
class_restorer = ALLOC(struct Class_Restorer);
|
|
91
|
+
class_restorer->klass = CLASS_OF(klass);
|
|
92
|
+
class_restorer->m_tbl = *RCLASS_M_TBL(singleton_class);
|
|
93
|
+
class_restorer->iv_tbl = *RCLASS_IV_TBL(singleton_class);
|
|
94
|
+
#ifndef RUBY_VM
|
|
95
|
+
class_restorer->thread_critical = rb_thread_critical;
|
|
96
|
+
#endif
|
|
97
|
+
return Data_Wrap_Struct(
|
|
98
|
+
rb_cClass_Restorer, mark_class_restorer, ruby_xfree,
|
|
99
|
+
class_restorer);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static void set_class_restore_state(VALUE klass)
|
|
103
|
+
{
|
|
104
|
+
struct RClass * singleton_class = RCLASS(CLASS_OF(klass));
|
|
105
|
+
RCLASS_IV_TBL(singleton_class)->num_entries = 1;
|
|
106
|
+
RCLASS_M_TBL(singleton_class)->num_entries = 0;
|
|
107
|
+
#ifndef RUBY_VM
|
|
108
|
+
rb_thread_critical = 1;
|
|
109
|
+
#endif
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static void restore_class(VALUE ruby_class_restorer)
|
|
113
|
+
{
|
|
114
|
+
struct Class_Restorer * class_restorer;
|
|
115
|
+
struct RClass * klass;
|
|
116
|
+
|
|
117
|
+
Data_Get_Struct(
|
|
118
|
+
ruby_class_restorer,
|
|
119
|
+
struct Class_Restorer,
|
|
120
|
+
class_restorer);
|
|
121
|
+
klass = RCLASS(class_restorer->klass);
|
|
122
|
+
*RCLASS_M_TBL(klass) = class_restorer->m_tbl;
|
|
123
|
+
*RCLASS_IV_TBL(klass) = class_restorer->iv_tbl;
|
|
124
|
+
#ifndef RUBY_VM
|
|
125
|
+
rb_thread_critical = class_restorer->thread_critical;
|
|
126
|
+
#endif
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/*
|
|
130
|
+
* call-seq:
|
|
131
|
+
* class_restorer.dump => String
|
|
132
|
+
*
|
|
133
|
+
* Do not call this function.
|
|
134
|
+
*/
|
|
135
|
+
static VALUE class_restorer_dump(VALUE ruby_class_restorer, VALUE limit)
|
|
136
|
+
{
|
|
137
|
+
restore_class(ruby_class_restorer);
|
|
138
|
+
return rb_str_new2("");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/*
|
|
142
|
+
* call-seq:
|
|
143
|
+
* Nodewrap::ClassRestorer.load => ClassRestorer
|
|
144
|
+
*
|
|
145
|
+
* Do not call this function.
|
|
146
|
+
*/
|
|
147
|
+
static VALUE class_restorer_load(VALUE klass, VALUE str)
|
|
148
|
+
{
|
|
149
|
+
return Qnil;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
#endif
|
|
153
|
+
|
|
154
|
+
static VALUE rb_cClass_Restorer = Qnil;
|
|
155
|
+
|
|
156
|
+
#if RUBY_VERSION_CODE == 180
|
|
157
|
+
|
|
158
|
+
static VALUE ruby180_marshal_dump(int argc, VALUE * argv, VALUE klass)
|
|
159
|
+
{
|
|
160
|
+
VALUE class_restorer = Qnil;
|
|
161
|
+
|
|
162
|
+
if(argc >= 1 && (TYPE(argv[0]) == T_CLASS || TYPE(argv[0]) == T_MODULE))
|
|
163
|
+
{
|
|
164
|
+
class_restorer = create_class_restorer(argv[0]);
|
|
165
|
+
set_class_restore_state(argv[0]);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
VALUE str = rb_funcall2(klass, rb_intern("_Nodewrap__orig_dump"), argc, argv);
|
|
169
|
+
|
|
170
|
+
if(class_restorer != Qnil)
|
|
171
|
+
{
|
|
172
|
+
restore_class(class_restorer);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return str;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
#endif
|
|
179
|
+
|
|
180
|
+
#if RUBY_VERSION_CODE >= 180
|
|
181
|
+
static VALUE module_instance_allocate(VALUE klass)
|
|
182
|
+
{
|
|
183
|
+
NEWOBJ(obj, struct RClass);
|
|
184
|
+
OBJSETUP(obj, klass, T_CLASS);
|
|
185
|
+
return (VALUE)obj;
|
|
186
|
+
}
|
|
187
|
+
#endif
|
|
188
|
+
|
|
189
|
+
static int add_to_method_hash(ID id, NODE * body, VALUE methods)
|
|
190
|
+
{
|
|
191
|
+
VALUE v = wrap_node(body);
|
|
192
|
+
rb_hash_aset(methods, ID2SYM(id), v);
|
|
193
|
+
|
|
194
|
+
return ST_CONTINUE;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
static VALUE instance_method_hash(VALUE module)
|
|
198
|
+
{
|
|
199
|
+
VALUE methods = rb_hash_new();
|
|
200
|
+
st_foreach(
|
|
201
|
+
RCLASS(module)->m_tbl,
|
|
202
|
+
add_to_method_hash,
|
|
203
|
+
#ifdef ST_DATA_T_DEFINED
|
|
204
|
+
(st_data_t)methods
|
|
205
|
+
#else
|
|
206
|
+
methods
|
|
207
|
+
#endif
|
|
208
|
+
);
|
|
209
|
+
return methods;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
static VALUE included_modules_list(VALUE module)
|
|
213
|
+
{
|
|
214
|
+
VALUE included_modules = rb_mod_included_modules(module);
|
|
215
|
+
VALUE included_module_list = rb_ary_new();
|
|
216
|
+
size_t j;
|
|
217
|
+
|
|
218
|
+
for(j = 0; j < RARRAY_LEN(included_modules); ++j)
|
|
219
|
+
{
|
|
220
|
+
rb_ary_push(
|
|
221
|
+
included_module_list,
|
|
222
|
+
rb_mod_name(RARRAY_PTR(included_modules)[j]));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return included_module_list;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
static VALUE superclass_name(VALUE module)
|
|
229
|
+
{
|
|
230
|
+
if(TYPE(module) == T_MODULE)
|
|
231
|
+
{
|
|
232
|
+
return Qnil;
|
|
233
|
+
}
|
|
234
|
+
else
|
|
235
|
+
{
|
|
236
|
+
VALUE super = RCLASS_SUPER(module);
|
|
237
|
+
|
|
238
|
+
while(TYPE(super) == T_ICLASS)
|
|
239
|
+
{
|
|
240
|
+
super = RCLASS_SUPER(super);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if(!super)
|
|
244
|
+
{
|
|
245
|
+
return Qnil;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if(FL_TEST(super, FL_SINGLETON))
|
|
249
|
+
{
|
|
250
|
+
VALUE v = rb_iv_get(super, "__attached__");
|
|
251
|
+
VALUE name = rb_mod_name(v);
|
|
252
|
+
rb_str_cat2(name, "::<Singleton>");
|
|
253
|
+
return name;
|
|
254
|
+
}
|
|
255
|
+
else
|
|
256
|
+
{
|
|
257
|
+
return rb_mod_name(super);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
static int add_var_to_hash(ID key, VALUE value, VALUE hash)
|
|
263
|
+
{
|
|
264
|
+
/* These are special variables and should not be dumped */
|
|
265
|
+
if( key != rb_intern("__classpath__")
|
|
266
|
+
&& key != rb_intern("__classid__")
|
|
267
|
+
&& key != rb_intern("__attached__"))
|
|
268
|
+
{
|
|
269
|
+
rb_hash_aset(hash, ID2SYM(key), value);
|
|
270
|
+
}
|
|
271
|
+
return ST_CONTINUE;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
static VALUE class_variable_hash(VALUE module)
|
|
275
|
+
{
|
|
276
|
+
VALUE class_variables = rb_hash_new();
|
|
277
|
+
#if RUBY_VERSION_CODE < 190
|
|
278
|
+
struct st_table * iv_tbl = ROBJECT(module)->iv_tbl;
|
|
279
|
+
if (iv_tbl)
|
|
280
|
+
{
|
|
281
|
+
st_foreach(iv_tbl, add_var_to_hash, class_variables);
|
|
282
|
+
}
|
|
283
|
+
#else
|
|
284
|
+
rb_ivar_foreach(module, add_var_to_hash, class_variables);
|
|
285
|
+
#endif
|
|
286
|
+
return class_variables;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
static void mark_class_restorer(struct Class_Restorer * class_restorer);
|
|
290
|
+
#endif
|
|
291
|
+
|
|
292
|
+
static char const * lookup_module_str =
|
|
293
|
+
"proc { |name|\n"
|
|
294
|
+
" o = Object\n"
|
|
295
|
+
" name.to_s.split('::').each do |subname|\n"
|
|
296
|
+
" if subname == '<Singleton>' then\n"
|
|
297
|
+
" o = o.singleton_class\n"
|
|
298
|
+
" else\n"
|
|
299
|
+
" o = o.const_get(subname)\n"
|
|
300
|
+
" end\n"
|
|
301
|
+
" end\n"
|
|
302
|
+
" o\n"
|
|
303
|
+
"}\n";
|
|
304
|
+
static VALUE lookup_module_proc = Qnil;
|
|
305
|
+
|
|
306
|
+
VALUE lookup_module(VALUE name)
|
|
307
|
+
{
|
|
308
|
+
return rb_funcall(lookup_module_proc, rb_intern("call"), 1, name);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
static char const * outer_module_str =
|
|
312
|
+
"proc { |name|\n"
|
|
313
|
+
" o = Object\n"
|
|
314
|
+
" names = name.to_s.split('::')\n"
|
|
315
|
+
" names.pop\n"
|
|
316
|
+
" names.each do |subname|\n"
|
|
317
|
+
" if subname == '<Singleton>' then\n"
|
|
318
|
+
" o = o.singleton_class\n"
|
|
319
|
+
" else\n"
|
|
320
|
+
" o = o.const_get(subname)\n"
|
|
321
|
+
" end\n"
|
|
322
|
+
" end\n"
|
|
323
|
+
" o\n"
|
|
324
|
+
"}\n";
|
|
325
|
+
|
|
326
|
+
static VALUE outer_module_proc = Qnil;
|
|
327
|
+
|
|
328
|
+
static char const * module_name_str =
|
|
329
|
+
"proc { |name|\n"
|
|
330
|
+
" names = name.to_s.split('::')\n"
|
|
331
|
+
" names[-1].intern\n"
|
|
332
|
+
"}\n";
|
|
333
|
+
|
|
334
|
+
static VALUE module_name_proc = Qnil;
|
|
335
|
+
|
|
336
|
+
#ifdef RUBY_VM
|
|
337
|
+
|
|
338
|
+
#if defined(HAVE_VM_GET_RUBY_LEVEL_NEXT_CFP)
|
|
339
|
+
/* Declared and defined in vm.c */
|
|
340
|
+
rb_control_frame_t *
|
|
341
|
+
vm_get_ruby_level_next_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
|
|
342
|
+
#endif
|
|
343
|
+
|
|
344
|
+
static void set_cref_stack(rb_iseq_t * iseqdat, VALUE klass, VALUE noex)
|
|
345
|
+
{
|
|
346
|
+
rb_thread_t * th = GET_THREAD();
|
|
347
|
+
#if defined(HAVE_VM_GET_RUBY_LEVEL_NEXT_CFP)
|
|
348
|
+
rb_control_frame_t * cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
|
|
349
|
+
#elif defined(HAVE_VM_GET_RUBY_LEVEL_CFP)
|
|
350
|
+
rb_control_frame_t * cfp = vm_get_ruby_level_cfp(th, th->cfp);
|
|
351
|
+
#else
|
|
352
|
+
#error No function to get cfp
|
|
353
|
+
#endif
|
|
354
|
+
iseqdat->cref_stack = NEW_BLOCK(klass);
|
|
355
|
+
iseqdat->cref_stack->nd_visi = noex;
|
|
356
|
+
iseqdat->cref_stack->nd_next = cfp->iseq->cref_stack; /* TODO: use lfp? */
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/* From iseq.c */
|
|
360
|
+
static rb_iseq_t *
|
|
361
|
+
iseq_check(VALUE val)
|
|
362
|
+
{
|
|
363
|
+
rb_iseq_t *iseq;
|
|
364
|
+
if(!rb_obj_is_kind_of(val, rb_cISeq))
|
|
365
|
+
{
|
|
366
|
+
rb_raise(
|
|
367
|
+
rb_eTypeError,
|
|
368
|
+
"Expected VM::InstructionSequence, but got %s",
|
|
369
|
+
rb_class2name(CLASS_OF(val)));
|
|
370
|
+
}
|
|
371
|
+
GetISeqPtr(val, iseq);
|
|
372
|
+
if (!iseq->name) {
|
|
373
|
+
rb_raise(rb_eTypeError, "uninitialized InstructionSequence");
|
|
374
|
+
}
|
|
375
|
+
return iseq;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
#endif
|
|
379
|
+
|
|
380
|
+
/*
|
|
381
|
+
* call-seq:
|
|
382
|
+
* class.add_method(id, node or iseq, noex) #=> nil
|
|
383
|
+
*
|
|
384
|
+
* Adds the method as an instance method to the given class.
|
|
385
|
+
*
|
|
386
|
+
* To add a singleton method to a class, add the method to its singleton
|
|
387
|
+
* class.
|
|
388
|
+
*/
|
|
389
|
+
static VALUE module_add_method(VALUE klass, VALUE id, VALUE node, VALUE noex)
|
|
390
|
+
{
|
|
391
|
+
NODE * n = 0;
|
|
392
|
+
|
|
393
|
+
if(rb_safe_level() >= 2)
|
|
394
|
+
{
|
|
395
|
+
/* adding a method with the wrong node type can cause a crash */
|
|
396
|
+
rb_raise(rb_eSecurityError, "Insecure: can't add method");
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
#ifdef RUBY_VM
|
|
400
|
+
if(rb_obj_is_kind_of(node, rb_cISeq))
|
|
401
|
+
{
|
|
402
|
+
rb_iseq_t *iseqdat = iseq_check(node);
|
|
403
|
+
/* TODO: any restrictions on what kinds of iseqs we can add here?
|
|
404
|
+
*/
|
|
405
|
+
set_cref_stack(iseqdat, klass, noex);
|
|
406
|
+
iseqdat->klass = klass;
|
|
407
|
+
iseqdat->defined_method_id = SYM2ID(id);
|
|
408
|
+
n = NEW_METHOD(iseqdat->self, klass, NUM2INT(noex));
|
|
409
|
+
goto add_node;
|
|
410
|
+
}
|
|
411
|
+
#endif
|
|
412
|
+
|
|
413
|
+
if(!rb_obj_is_kind_of(node, rb_cNode))
|
|
414
|
+
{
|
|
415
|
+
rb_raise(
|
|
416
|
+
rb_eTypeError,
|
|
417
|
+
"Expected Node for 2nd parameter, got %s",
|
|
418
|
+
rb_class2name(CLASS_OF(n)));
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
Data_Get_Struct(node, NODE, n);
|
|
422
|
+
|
|
423
|
+
#ifdef RUBY_VM
|
|
424
|
+
if(nd_type(n) != NODE_METHOD)
|
|
425
|
+
{
|
|
426
|
+
rb_raise(
|
|
427
|
+
rb_eTypeError,
|
|
428
|
+
"Expected METHOD node, got %s",
|
|
429
|
+
rb_class2name(CLASS_OF(n)));
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
rb_iseq_t *iseqdat = iseq_check((VALUE)n->nd_body);
|
|
433
|
+
set_cref_stack(iseqdat, klass, noex);
|
|
434
|
+
iseqdat->klass = klass;
|
|
435
|
+
iseqdat->defined_method_id = SYM2ID(id);
|
|
436
|
+
n = NEW_METHOD(iseqdat->self, klass, NUM2INT(noex));
|
|
437
|
+
|
|
438
|
+
add_node:
|
|
439
|
+
#endif
|
|
440
|
+
/* TODO: if noex is NOEX_MODFUNC, add this method as a module function
|
|
441
|
+
* (that is, both as an instance and singleton method)
|
|
442
|
+
*/
|
|
443
|
+
rb_add_method(klass, SYM2ID(id), n, NUM2INT(noex));
|
|
444
|
+
return Qnil;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/*
|
|
448
|
+
* call-seq:
|
|
449
|
+
* uninclude(module, ...) => self
|
|
450
|
+
*
|
|
451
|
+
* Removes the specified module(s) from the inheritance chain.
|
|
452
|
+
*/
|
|
453
|
+
static VALUE module_uninclude(int argc, VALUE * argv, VALUE module)
|
|
454
|
+
{
|
|
455
|
+
int i;
|
|
456
|
+
|
|
457
|
+
for (i = 0; i < argc; i++)
|
|
458
|
+
Check_Type(argv[i], T_MODULE);
|
|
459
|
+
while (argc--) {
|
|
460
|
+
rb_funcall(argv[argc], rb_intern("remove_features"), 1, module);
|
|
461
|
+
rb_funcall(argv[argc], rb_intern("unincluded"), 1, module);
|
|
462
|
+
}
|
|
463
|
+
return module;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/*
|
|
467
|
+
* call-seq:
|
|
468
|
+
* remove_features(mod) => mod
|
|
469
|
+
*
|
|
470
|
+
* When this module is unincluded from another, Nodewrap calls
|
|
471
|
+
* remove_features in this module. The default behavior is to remove
|
|
472
|
+
* the constants, methods, and module variables of this module from
|
|
473
|
+
* _mod_. If this module has not been included by _mod_, an exception
|
|
474
|
+
* will be raised.
|
|
475
|
+
*/
|
|
476
|
+
static VALUE module_remove_features(VALUE module, VALUE uninclude)
|
|
477
|
+
{
|
|
478
|
+
VALUE prev, mod;
|
|
479
|
+
|
|
480
|
+
if(TYPE(uninclude) != T_CLASS && TYPE(uninclude) != T_MODULE)
|
|
481
|
+
{
|
|
482
|
+
Check_Type(uninclude, T_CLASS);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
rb_frozen_class_p(uninclude);
|
|
486
|
+
if(!OBJ_TAINTED(uninclude))
|
|
487
|
+
{
|
|
488
|
+
rb_secure(4);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
OBJ_INFECT(uninclude, module);
|
|
492
|
+
|
|
493
|
+
if(RCLASS(uninclude)->m_tbl == RCLASS(module)->m_tbl)
|
|
494
|
+
{
|
|
495
|
+
rb_raise(rb_eArgError, "Cannot remove module from itself");
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
prev = uninclude;
|
|
499
|
+
mod = RCLASS_SUPER(uninclude);
|
|
500
|
+
|
|
501
|
+
while(mod)
|
|
502
|
+
{
|
|
503
|
+
if(RCLASS(module)->m_tbl == RCLASS(mod)->m_tbl)
|
|
504
|
+
{
|
|
505
|
+
RCLASS_SUPER(prev) = RCLASS_SUPER(mod);
|
|
506
|
+
rb_clear_cache();
|
|
507
|
+
return module;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if(BUILTIN_TYPE(mod) == T_CLASS)
|
|
511
|
+
{
|
|
512
|
+
break;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
prev = mod;
|
|
516
|
+
mod = RCLASS_SUPER(mod);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
rb_raise(rb_eArgError, "Could not find included module");
|
|
520
|
+
return module;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/*
|
|
524
|
+
* call-seq:
|
|
525
|
+
* module.unincluded(uninclude) => nil
|
|
526
|
+
*
|
|
527
|
+
* Callback when a module is unincluded. Should not normally be called
|
|
528
|
+
* by the user.
|
|
529
|
+
*/
|
|
530
|
+
static VALUE module_unincluded(VALUE module, VALUE uninclude)
|
|
531
|
+
{
|
|
532
|
+
return Qnil;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/*
|
|
536
|
+
* call-seq:
|
|
537
|
+
* class.real_superclass => Class
|
|
538
|
+
*
|
|
539
|
+
* Return the immediate superclass of a class or module. This may be a
|
|
540
|
+
* base class, a singleton class, or a module singleton.
|
|
541
|
+
*/
|
|
542
|
+
VALUE module_real_superclass(VALUE self)
|
|
543
|
+
{
|
|
544
|
+
VALUE super = RCLASS_SUPER(self);
|
|
545
|
+
rb_include_module(rb_class_of(super), rb_mKernel);
|
|
546
|
+
return super;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/*
|
|
550
|
+
* call-seq:
|
|
551
|
+
* module.dump(limit) => String
|
|
552
|
+
*
|
|
553
|
+
* Dump a module to a string. The module will be dumped along with its
|
|
554
|
+
* instance methods, class variables, names of included modules, name of
|
|
555
|
+
* superclass, its entire metaclass, and the name of the class.
|
|
556
|
+
*
|
|
557
|
+
* Note that on ruby 1.8 and newer the module is temporarily modified
|
|
558
|
+
* while dumping in order to allow singleton classes to be dumped. To
|
|
559
|
+
* prevent access to the modifed module, Thread.critical is temporarily
|
|
560
|
+
* set, then restored to its original value once dumping is complete.
|
|
561
|
+
* Note also that because YARV does not support Thread.critical, the
|
|
562
|
+
* user must synchronize access to the class with a Mutex in order to
|
|
563
|
+
* prevent accessing the modified class.
|
|
564
|
+
*/
|
|
565
|
+
static VALUE module_dump(VALUE self, VALUE limit)
|
|
566
|
+
{
|
|
567
|
+
VALUE flags, instance_methods, class_variables;
|
|
568
|
+
VALUE included_modules, superclass, metaclass, arr, str, class_name;
|
|
569
|
+
|
|
570
|
+
limit = INT2NUM(NUM2INT(limit) - 1);
|
|
571
|
+
|
|
572
|
+
if(rb_safe_level() >= 4)
|
|
573
|
+
{
|
|
574
|
+
/* no access to potentially sensitive data from the sandbox */
|
|
575
|
+
rb_raise(rb_eSecurityError, "Insecure: can't dump module");
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
flags = INT2NUM(RBASIC(self)->flags);
|
|
579
|
+
instance_methods = instance_method_hash(self);
|
|
580
|
+
class_variables = class_variable_hash(self);
|
|
581
|
+
included_modules = included_modules_list(self);
|
|
582
|
+
superclass = superclass_name(self);
|
|
583
|
+
arr = rb_ary_new();
|
|
584
|
+
|
|
585
|
+
if(FL_TEST(self, FL_SINGLETON))
|
|
586
|
+
{
|
|
587
|
+
metaclass = Qnil;
|
|
588
|
+
class_name = Qnil;
|
|
589
|
+
}
|
|
590
|
+
else
|
|
591
|
+
{
|
|
592
|
+
metaclass = rb_singleton_class(self);
|
|
593
|
+
class_name = rb_class_path(self);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
rb_ary_push(arr, flags);
|
|
597
|
+
rb_ary_push(arr, marshal_dump(instance_methods, limit));
|
|
598
|
+
rb_ary_push(arr, marshal_dump(class_variables, limit));
|
|
599
|
+
rb_ary_push(arr, included_modules);
|
|
600
|
+
rb_ary_push(arr, superclass);
|
|
601
|
+
rb_ary_push(arr, marshal_dump(metaclass, limit));
|
|
602
|
+
rb_ary_push(arr, class_name);
|
|
603
|
+
|
|
604
|
+
str = marshal_dump(arr, limit);
|
|
605
|
+
|
|
606
|
+
#if RUBY_VERSION_CODE > 180
|
|
607
|
+
{
|
|
608
|
+
VALUE class_restorer = create_class_restorer(self);
|
|
609
|
+
rb_iv_set(str, "__class_restorer__", class_restorer);
|
|
610
|
+
set_class_restore_state(self);
|
|
611
|
+
}
|
|
612
|
+
#endif
|
|
613
|
+
|
|
614
|
+
return str;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
static void include_modules(module, included_modules)
|
|
618
|
+
{
|
|
619
|
+
size_t j;
|
|
620
|
+
VALUE v;
|
|
621
|
+
VALUE name;
|
|
622
|
+
|
|
623
|
+
rb_check_type(included_modules, T_ARRAY);
|
|
624
|
+
for(j = 0; j < RARRAY_LEN(included_modules); ++j)
|
|
625
|
+
{
|
|
626
|
+
name = RARRAY_PTR(included_modules)[j];
|
|
627
|
+
v = lookup_module(name);
|
|
628
|
+
rb_funcall(module, rb_intern("include"), 1, v);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
static int add_method_iter(VALUE name, VALUE value, VALUE module)
|
|
633
|
+
{
|
|
634
|
+
NODE * n;
|
|
635
|
+
rb_check_type(name, T_SYMBOL);
|
|
636
|
+
if(!rb_obj_is_kind_of(value, rb_cNode))
|
|
637
|
+
{
|
|
638
|
+
rb_raise(
|
|
639
|
+
rb_eTypeError,
|
|
640
|
+
"Expected Node, but got %s",
|
|
641
|
+
rb_class2name(CLASS_OF(value)));
|
|
642
|
+
}
|
|
643
|
+
Data_Get_Struct(value, NODE, n);
|
|
644
|
+
rb_add_method(module, SYM2ID(name), n->nd_body, n->nd_noex);
|
|
645
|
+
return ST_CONTINUE;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
static void add_methods(VALUE module, VALUE methods)
|
|
649
|
+
{
|
|
650
|
+
rb_check_type(methods, T_HASH);
|
|
651
|
+
#ifdef RUBY_VM
|
|
652
|
+
if(RHASH(methods)->ntbl)
|
|
653
|
+
{
|
|
654
|
+
st_foreach(RHASH(methods)->ntbl, add_method_iter, module);
|
|
655
|
+
}
|
|
656
|
+
#else
|
|
657
|
+
st_foreach(RHASH(methods)->tbl, add_method_iter, module);
|
|
658
|
+
#endif
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
static int set_cvar_from_hash(VALUE key, VALUE value, VALUE module)
|
|
662
|
+
{
|
|
663
|
+
#ifdef RB_CVAR_SET_4ARGS
|
|
664
|
+
rb_cvar_set(module, SYM2ID(key), value, Qtrue);
|
|
665
|
+
#else
|
|
666
|
+
rb_cvar_set(module, SYM2ID(key), value);
|
|
667
|
+
#endif
|
|
668
|
+
return ST_CONTINUE;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
static void add_class_variables(VALUE module, VALUE class_variables)
|
|
672
|
+
{
|
|
673
|
+
rb_check_type(class_variables, T_HASH);
|
|
674
|
+
#ifdef RUBY_VM
|
|
675
|
+
if(RHASH(class_variables)->ntbl)
|
|
676
|
+
{
|
|
677
|
+
st_foreach(RHASH(class_variables)->ntbl, set_cvar_from_hash, module);
|
|
678
|
+
}
|
|
679
|
+
#else
|
|
680
|
+
st_foreach(RHASH(class_variables)->tbl, set_cvar_from_hash, module);
|
|
681
|
+
#endif
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/*
|
|
685
|
+
* call-seq:
|
|
686
|
+
* Module.load(String) => Module
|
|
687
|
+
*
|
|
688
|
+
* Load a module from a string.
|
|
689
|
+
*/
|
|
690
|
+
static VALUE module_load(VALUE klass, VALUE str)
|
|
691
|
+
{
|
|
692
|
+
VALUE arr, class_name, metaclass_str, metaclass, superclass_name,
|
|
693
|
+
included_modules, class_variables_str, class_variables,
|
|
694
|
+
instance_methods_str, instance_methods, flags, module;
|
|
695
|
+
|
|
696
|
+
if( rb_safe_level() >= 4
|
|
697
|
+
|| (rb_safe_level() >= 1 && OBJ_TAINTED(str)))
|
|
698
|
+
{
|
|
699
|
+
/* no playing with knives in the sandbox */
|
|
700
|
+
rb_raise(rb_eSecurityError, "Insecure: can't load module");
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
arr = marshal_load(str);
|
|
704
|
+
class_name = rb_ary_pop(arr);
|
|
705
|
+
metaclass_str = rb_ary_pop(arr);
|
|
706
|
+
superclass_name = rb_ary_pop(arr);
|
|
707
|
+
included_modules = rb_ary_pop(arr);
|
|
708
|
+
class_variables_str = rb_ary_pop(arr);
|
|
709
|
+
instance_methods_str = rb_ary_pop(arr);
|
|
710
|
+
flags = rb_ary_pop(arr);
|
|
711
|
+
|
|
712
|
+
if(RTEST(superclass_name))
|
|
713
|
+
{
|
|
714
|
+
VALUE superclass;
|
|
715
|
+
rb_check_type(superclass_name, T_STRING);
|
|
716
|
+
superclass = rb_funcall(
|
|
717
|
+
lookup_module_proc,
|
|
718
|
+
rb_intern("call"),
|
|
719
|
+
1,
|
|
720
|
+
superclass_name);
|
|
721
|
+
#if RUBY_VERSION_CODE >= 180
|
|
722
|
+
/* Can't make subclass of Class on 1.8.x */
|
|
723
|
+
module = rb_class_boot(superclass);
|
|
724
|
+
rb_define_alloc_func(module, module_instance_allocate);
|
|
725
|
+
#else
|
|
726
|
+
module = rb_class_new(superclass);
|
|
727
|
+
#endif
|
|
728
|
+
}
|
|
729
|
+
else
|
|
730
|
+
{
|
|
731
|
+
module = rb_module_new();
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
if(!NIL_P(class_name))
|
|
735
|
+
{
|
|
736
|
+
VALUE outer_module = rb_funcall(outer_module_proc, rb_intern("call"), 1, class_name);
|
|
737
|
+
VALUE module_name = rb_funcall(module_name_proc, rb_intern("call"), 1, class_name);
|
|
738
|
+
rb_const_set(outer_module, SYM2ID(module_name), module);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
RBASIC(module)->flags = NUM2INT(flags);
|
|
742
|
+
include_modules(module, included_modules);
|
|
743
|
+
class_variables = marshal_load(class_variables_str);
|
|
744
|
+
add_class_variables(module, class_variables);
|
|
745
|
+
instance_methods = marshal_load(instance_methods_str);
|
|
746
|
+
add_methods(module, instance_methods);
|
|
747
|
+
|
|
748
|
+
metaclass = marshal_load(metaclass_str);
|
|
749
|
+
if(RTEST(metaclass))
|
|
750
|
+
{
|
|
751
|
+
rb_singleton_class_attached(metaclass, module);
|
|
752
|
+
RBASIC(module)->klass = metaclass;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
return module;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
void Init_module(void)
|
|
759
|
+
{
|
|
760
|
+
rb_require("internal/node");
|
|
761
|
+
rb_cNode = rb_const_get(rb_cObject, rb_intern("Node"));
|
|
762
|
+
|
|
763
|
+
rb_mMarshal = rb_const_get(rb_cObject, rb_intern("Marshal"));
|
|
764
|
+
|
|
765
|
+
/* For rdoc: rb_cModule = rb_define_class("Module", rb_cObject) */
|
|
766
|
+
rb_cModule = rb_const_get(rb_cObject, rb_intern("Module"));
|
|
767
|
+
rb_define_method(rb_cModule, "add_method", module_add_method, 3);
|
|
768
|
+
rb_define_private_method(rb_cModule, "uninclude", module_uninclude, -1);
|
|
769
|
+
rb_define_private_method(rb_cModule, "remove_features", module_remove_features, 1);
|
|
770
|
+
rb_define_private_method(rb_cModule, "unincluded", module_unincluded, 1);
|
|
771
|
+
rb_define_method(rb_cModule, "real_superclass", module_real_superclass, 0);
|
|
772
|
+
|
|
773
|
+
lookup_module_proc = rb_eval_string(lookup_module_str);
|
|
774
|
+
rb_global_variable(&lookup_module_proc);
|
|
775
|
+
|
|
776
|
+
outer_module_proc = rb_eval_string(outer_module_str);
|
|
777
|
+
rb_global_variable(&outer_module_proc);
|
|
778
|
+
|
|
779
|
+
module_name_proc = rb_eval_string(module_name_str);
|
|
780
|
+
rb_global_variable(&module_name_proc);
|
|
781
|
+
|
|
782
|
+
#if RUBY_VERSION_CODE >= 180
|
|
783
|
+
VALUE rb_mNodewrap = rb_define_module("Nodewrap");
|
|
784
|
+
rb_cClass_Restorer = rb_define_class_under(rb_mNodewrap, "ClassRestorer", rb_cObject);
|
|
785
|
+
rb_define_method(rb_cClass_Restorer, "_dump", class_restorer_dump, 1);
|
|
786
|
+
rb_define_singleton_method(rb_cClass_Restorer, "_load", class_restorer_load, 1);
|
|
787
|
+
#endif
|
|
788
|
+
|
|
789
|
+
#if RUBY_VERSION_CODE == 180
|
|
790
|
+
rb_alias(CLASS_OF(rb_mMarshal), rb_intern("_Nodewrap__orig_dump"), rb_intern("dump"));
|
|
791
|
+
rb_define_singleton_method(rb_mMarshal, "dump", ruby180_marshal_dump, -1);
|
|
792
|
+
#endif
|
|
793
|
+
|
|
794
|
+
rb_define_method(rb_cModule, "_dump", module_dump, 1);
|
|
795
|
+
rb_define_singleton_method(rb_cModule, "_load", module_load, 1);
|
|
796
|
+
}
|
|
797
|
+
|