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,213 @@
|
|
|
1
|
+
#include "insns_info.h"
|
|
2
|
+
|
|
3
|
+
#ifdef RUBY_VM
|
|
4
|
+
|
|
5
|
+
#ruby <<END
|
|
6
|
+
$:.unshift '../../..'
|
|
7
|
+
require 'ruby_source_dir'
|
|
8
|
+
insns_location = "#{RUBY_SOURCE_DIR}/insns.inc"
|
|
9
|
+
insns_info_location = "#{RUBY_SOURCE_DIR}/insns_info.inc"
|
|
10
|
+
insns_def_location = "#{RUBY_SOURCE_DIR}/insns.def"
|
|
11
|
+
iseq_c_location = "#{RUBY_SOURCE_DIR}/iseq.c"
|
|
12
|
+
|
|
13
|
+
INSTRUCTION_NAMES = []
|
|
14
|
+
record_instruction_names = false
|
|
15
|
+
|
|
16
|
+
[ insns_location, insns_info_location ].each do |file|
|
|
17
|
+
next if not File.exist?(file)
|
|
18
|
+
|
|
19
|
+
File.open(file) do |input|
|
|
20
|
+
while (line = input.gets) != nil do
|
|
21
|
+
line.chomp!
|
|
22
|
+
if line =~ /^\}/ then
|
|
23
|
+
record_instruction_names = false
|
|
24
|
+
end
|
|
25
|
+
if record_instruction_names then
|
|
26
|
+
name = line.chomp(',').gsub(/"/, '').lstrip.upcase
|
|
27
|
+
INSTRUCTION_NAMES.push(name) if name != ''
|
|
28
|
+
end
|
|
29
|
+
if line =~ /static.*insn_name_info.*=/ then
|
|
30
|
+
record_instruction_names = true
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
write = false
|
|
37
|
+
|
|
38
|
+
[ iseq_c_location ].each do |file|
|
|
39
|
+
next if not File.exist?(file)
|
|
40
|
+
|
|
41
|
+
File.open(file) do |input|
|
|
42
|
+
while (line = input.gets) != nil do
|
|
43
|
+
line.chomp!
|
|
44
|
+
case line
|
|
45
|
+
when /^make_compile_option\(/
|
|
46
|
+
puts 'void'
|
|
47
|
+
write = true
|
|
48
|
+
when /^static.*COMPILE_OPTION_DEFAULT.*=/
|
|
49
|
+
write = true
|
|
50
|
+
when /^static.*COMPILE_OPTION_FALSE.*;/
|
|
51
|
+
puts line
|
|
52
|
+
end
|
|
53
|
+
puts line if write
|
|
54
|
+
if line =~ /^\}/ then
|
|
55
|
+
write = false
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
INSTRUCTION_OPERAND_NAMES = {}
|
|
62
|
+
|
|
63
|
+
[ insns_def_location ].each do |file|
|
|
64
|
+
next if not File.exist?(file)
|
|
65
|
+
|
|
66
|
+
File.open(file) do |input|
|
|
67
|
+
if input.respond_to?(:set_encoding) then
|
|
68
|
+
input.set_encoding(Encoding::ASCII_8BIT)
|
|
69
|
+
end
|
|
70
|
+
while (line = input.gets) != nil do
|
|
71
|
+
line.chomp!
|
|
72
|
+
case line
|
|
73
|
+
when /^DEFINE_INSN/
|
|
74
|
+
name = input.gets.chomp
|
|
75
|
+
operand_line = input.gets.chomp
|
|
76
|
+
operand_line.gsub!(/\((.*)\)/, '\1')
|
|
77
|
+
operands = operand_line.split(',')
|
|
78
|
+
operand_names = operands.map { |x| x.split[1] }
|
|
79
|
+
INSTRUCTION_OPERAND_NAMES[name] = operand_names
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
nil
|
|
86
|
+
END
|
|
87
|
+
|
|
88
|
+
VALUE instruction_class[VM_INSTRUCTION_SIZE];
|
|
89
|
+
|
|
90
|
+
static ID operand_type_name_of(int operand_type)
|
|
91
|
+
{
|
|
92
|
+
char const * retval = "????";
|
|
93
|
+
|
|
94
|
+
switch(operand_type)
|
|
95
|
+
{
|
|
96
|
+
case TS_ISEQ: retval = "iseq"; break;
|
|
97
|
+
case TS_GENTRY: retval = "gentry"; break;
|
|
98
|
+
case TS_OFFSET: retval = "operand"; break;
|
|
99
|
+
case TS_DINDEX: retval = "dindex"; break;
|
|
100
|
+
case TS_VARIABLE: retval = "variable"; break;
|
|
101
|
+
case TS_CDHASH: retval = "cdhash"; break;
|
|
102
|
+
case TS_IC: retval = "ic"; break;
|
|
103
|
+
case TS_ID: retval = "id"; break;
|
|
104
|
+
case TS_VALUE: retval = "value"; break;
|
|
105
|
+
case TS_LINDEX: retval = "lindex"; break;
|
|
106
|
+
case TS_NUM: retval = "num"; break;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return rb_intern(retval);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#ruby <<END
|
|
113
|
+
INSTRUCTION_NAMES.each_with_index do |name, index|
|
|
114
|
+
$operand_names = INSTRUCTION_OPERAND_NAMES[name.downcase]
|
|
115
|
+
|
|
116
|
+
# 1 #<VM::Instruction::TRACE:0x402d991c @length=2, @operands=[1],
|
|
117
|
+
# @instruction=45, @operand_types=[:num], @name=:trace>
|
|
118
|
+
puts <<-END
|
|
119
|
+
/*
|
|
120
|
+
* call-seq:
|
|
121
|
+
* insn.length => Integer
|
|
122
|
+
*
|
|
123
|
+
* Returns the length of the instruction.
|
|
124
|
+
*/
|
|
125
|
+
static VALUE insn_#{name}_length(VALUE self)
|
|
126
|
+
{
|
|
127
|
+
return LONG2NUM(insn_len(#{index}));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/*
|
|
131
|
+
* call-seq:
|
|
132
|
+
* insn.to_i => Integer
|
|
133
|
+
*
|
|
134
|
+
* Returns the numeric instruction number.
|
|
135
|
+
*/
|
|
136
|
+
static VALUE insn_#{name}_to_i(VALUE self)
|
|
137
|
+
{
|
|
138
|
+
return NUM2LONG(#{index});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/*
|
|
142
|
+
* call-seq:
|
|
143
|
+
* insn.operand_types => Array of Symbol
|
|
144
|
+
*
|
|
145
|
+
* Returns an array containing the types of the operands.
|
|
146
|
+
*/
|
|
147
|
+
static VALUE insn_#{name}_operand_types(VALUE self)
|
|
148
|
+
{
|
|
149
|
+
VALUE operand_types = rb_ary_new();
|
|
150
|
+
char const * s;
|
|
151
|
+
|
|
152
|
+
for(s = insn_op_types(#{index}); *s != '\\0'; ++s)
|
|
153
|
+
{
|
|
154
|
+
rb_ary_push(operand_types, ID2SYM(operand_type_name_of(*s)));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return operand_types;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/*
|
|
161
|
+
* call-seq:
|
|
162
|
+
* insn.name => Symbol
|
|
163
|
+
*
|
|
164
|
+
* Returns the name of the instruction.
|
|
165
|
+
*/
|
|
166
|
+
static VALUE insn_#{name}_name(VALUE self)
|
|
167
|
+
{
|
|
168
|
+
return rb_intern("#{name}");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/*
|
|
172
|
+
* call-seq:
|
|
173
|
+
* insn.name => Symbol
|
|
174
|
+
*
|
|
175
|
+
* Returns the name of the operands for this instruction.
|
|
176
|
+
*/
|
|
177
|
+
static VALUE insn_#{name}_operand_names(VALUE self)
|
|
178
|
+
{
|
|
179
|
+
VALUE v[] = {
|
|
180
|
+
#{$operand_names.map { |x| "ID2SYM(rb_intern(\"#{x}\"))" }.join(', ')}
|
|
181
|
+
};
|
|
182
|
+
return rb_ary_new4(#{$operand_names.size}, v);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
END
|
|
186
|
+
end
|
|
187
|
+
nil
|
|
188
|
+
END
|
|
189
|
+
|
|
190
|
+
void define_instruction_subclasses(VALUE rb_cInstruction)
|
|
191
|
+
{
|
|
192
|
+
/* For rdoc: rb_cVM = rb_define_class("VM", rb_cObject); */
|
|
193
|
+
/* For rdoc: rb_cInstruction = rb_define_class_under(rb_cVM, "Instruction", rb_cObject); */
|
|
194
|
+
|
|
195
|
+
#ruby <<END
|
|
196
|
+
INSTRUCTION_NAMES.each_with_index do |name, index|
|
|
197
|
+
puts <<-END
|
|
198
|
+
{
|
|
199
|
+
VALUE rb_cInstruction_#{name} = instruction_class[#{index}] = rb_define_class_under(rb_cInstruction, "#{name}", rb_cInstruction);
|
|
200
|
+
rb_define_method(rb_cInstruction_#{name}, "length", insn_#{name}_length, 0);
|
|
201
|
+
rb_define_method(rb_cInstruction_#{name}, "to_i", insn_#{name}_to_i, 0);
|
|
202
|
+
rb_define_method(rb_cInstruction_#{name}, "operand_types", insn_#{name}_operand_types, 0);
|
|
203
|
+
rb_define_method(rb_cInstruction_#{name}, "operand_names", insn_#{name}_operand_names, 0);
|
|
204
|
+
rb_define_method(rb_cInstruction_#{name}, "name", insn_#{name}_name, 0);
|
|
205
|
+
}
|
|
206
|
+
END
|
|
207
|
+
end
|
|
208
|
+
nil
|
|
209
|
+
END
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
#endif
|
|
213
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#ifndef insns_info__h_
|
|
2
|
+
#define insns_info__h_
|
|
3
|
+
|
|
4
|
+
#include "ruby.h"
|
|
5
|
+
|
|
6
|
+
#ifdef RUBY_VM
|
|
7
|
+
|
|
8
|
+
#include "vm_core.h"
|
|
9
|
+
|
|
10
|
+
#ifdef HAVE_VM_H
|
|
11
|
+
#include "vm.h"
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
#ruby <<END
|
|
15
|
+
$:.unshift '../../..'
|
|
16
|
+
require 'ruby_source_dir'
|
|
17
|
+
insns_location = "#{RUBY_SOURCE_DIR}/insns.inc"
|
|
18
|
+
insns_info_location = "#{RUBY_SOURCE_DIR}/insns_info.inc"
|
|
19
|
+
iseq_c_location = "#{RUBY_SOURCE_DIR}/iseq.c"
|
|
20
|
+
|
|
21
|
+
[ insns_location, insns_info_location ].each do |file|
|
|
22
|
+
next if not File.exist?(file)
|
|
23
|
+
|
|
24
|
+
File.open(file) do |input|
|
|
25
|
+
while (line = input.gets) != nil do
|
|
26
|
+
puts line
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
[ iseq_c_location ].each do |file|
|
|
32
|
+
next if not File.exist?(file)
|
|
33
|
+
|
|
34
|
+
File.open(file) do |input|
|
|
35
|
+
while (line = input.gets) != nil do
|
|
36
|
+
line.chomp!
|
|
37
|
+
if line =~ /^make_compile_option/ then
|
|
38
|
+
puts 'void'
|
|
39
|
+
puts "#{line};"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
nil
|
|
45
|
+
END
|
|
46
|
+
|
|
47
|
+
extern VALUE instruction_class[VM_INSTRUCTION_SIZE];
|
|
48
|
+
void define_instruction_subclasses(VALUE rb_cInstruction);
|
|
49
|
+
|
|
50
|
+
#endif
|
|
51
|
+
|
|
52
|
+
#endif
|
|
53
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#include "instruction.h"
|
|
2
|
+
#include "insns_info.h"
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
|
|
5
|
+
#ifndef RARRAY_LEN
|
|
6
|
+
#define RARRAY_LEN(a) RARRAY(a)->len
|
|
7
|
+
#endif
|
|
8
|
+
|
|
9
|
+
#ifndef RARRAY_PTR
|
|
10
|
+
#define RARRAY_PTR(a) RARRAY(a)->ptr
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
#ifdef RUBY_VM
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* call-seq:
|
|
17
|
+
* Instruction.new(*operands) => Instruction
|
|
18
|
+
*
|
|
19
|
+
* Create a new instruction with the given operands.
|
|
20
|
+
*/
|
|
21
|
+
static VALUE instruction_initialize(int argc, VALUE * argv, VALUE self)
|
|
22
|
+
{
|
|
23
|
+
VALUE operands = rb_ary_new4(argc, argv);
|
|
24
|
+
rb_iv_set(self, "@operands", operands);
|
|
25
|
+
return Qnil;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* call-seq:
|
|
30
|
+
* instruction.operands => Array
|
|
31
|
+
*
|
|
32
|
+
* Returns the instructions operands.
|
|
33
|
+
*/
|
|
34
|
+
static VALUE instruction_operands(VALUE self)
|
|
35
|
+
{
|
|
36
|
+
return rb_iv_get(self, "@operands");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
VALUE allocate_instruction(int instruction, VALUE args)
|
|
40
|
+
{
|
|
41
|
+
return rb_class_new_instance(
|
|
42
|
+
RARRAY_LEN(args),
|
|
43
|
+
RARRAY_PTR(args),
|
|
44
|
+
instruction_class[instruction]);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
void Init_instruction(void)
|
|
50
|
+
{
|
|
51
|
+
#ifdef RUBY_VM
|
|
52
|
+
VALUE rb_cRubyVM;
|
|
53
|
+
VALUE rb_cInstruction;
|
|
54
|
+
|
|
55
|
+
if(!rb_const_defined(rb_cObject, rb_intern("RubyVM")))
|
|
56
|
+
{
|
|
57
|
+
rb_define_const(
|
|
58
|
+
rb_cObject,
|
|
59
|
+
"RubyVM",
|
|
60
|
+
rb_const_get(rb_cObject, rb_intern("VM")));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
rb_cRubyVM = rb_define_class("RubyVM", rb_cObject);
|
|
64
|
+
|
|
65
|
+
rb_cInstruction = rb_define_class_under(rb_cRubyVM, "Instruction", rb_cObject);
|
|
66
|
+
rb_define_method(rb_cInstruction, "initialize", instruction_initialize, -1);
|
|
67
|
+
rb_define_method(rb_cInstruction, "operands", instruction_operands, 0);
|
|
68
|
+
rb_undef_method(rb_cInstruction, "new");
|
|
69
|
+
|
|
70
|
+
define_instruction_subclasses(rb_cInstruction);
|
|
71
|
+
|
|
72
|
+
/* Silence compiler warnings about unused static functions */
|
|
73
|
+
insn_name(0);
|
|
74
|
+
insn_op_type(0, 0);
|
|
75
|
+
insn_op_types(0);
|
|
76
|
+
#endif
|
|
77
|
+
}
|
|
78
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#ifndef ruby_internal_insns_info__inc_
|
|
2
|
+
#define ruby_internal_insns_info__inc_
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#ifndef RUBY_VM
|
|
7
|
+
#include "env.h"
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
#ruby <<END
|
|
11
|
+
ruby_version_code = RUBY_VERSION.gsub(/\./, '').to_i
|
|
12
|
+
|
|
13
|
+
if ruby_version_code >= 190 then
|
|
14
|
+
|
|
15
|
+
$: << '../../..'
|
|
16
|
+
require 'ruby_source_dir'
|
|
17
|
+
insns_info_location = "#{RUBY_SOURCE_DIR}/insns_info.inc"
|
|
18
|
+
|
|
19
|
+
File.open(insns_info_location) do |input|
|
|
20
|
+
input.each_line do |line|
|
|
21
|
+
puts line
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
nil
|
|
27
|
+
END
|
|
28
|
+
|
|
29
|
+
#endif
|
|
30
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#ifndef ruby_internal_vm__internal_iseq_h_
|
|
2
|
+
#define ruby_internal_vm__internal_iseq_h_
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
void dump_iseq_to_hash(VALUE iseq, VALUE node_hash);
|
|
7
|
+
VALUE load_iseq_from_hash(VALUE iseq, VALUE orig_node_id, VALUE node_hash, VALUE id_hash);
|
|
8
|
+
|
|
9
|
+
#endif
|
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
#include "internal_iseq.h"
|
|
2
|
+
#include "insns_info.inc"
|
|
3
|
+
|
|
4
|
+
#include "internal/node/ruby_internal_node.h"
|
|
5
|
+
#include "internal/module/module.h"
|
|
6
|
+
#include "internal/vm/instruction/instruction.h"
|
|
7
|
+
|
|
8
|
+
#include <ruby.h>
|
|
9
|
+
|
|
10
|
+
#ifdef RUBY_VM
|
|
11
|
+
|
|
12
|
+
#include "vm_core.h"
|
|
13
|
+
|
|
14
|
+
#ifdef HAVE_ISEQ_H
|
|
15
|
+
#include "iseq.h"
|
|
16
|
+
#endif
|
|
17
|
+
|
|
18
|
+
#ifndef RARRAY_LEN
|
|
19
|
+
#define RARRAY_LEN(a) RARRAY(a)->len
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
#ifndef RARRAY_PTR
|
|
23
|
+
#define RARRAY_PTR(a) RARRAY(a)->ptr
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
// Defined but not declared by ruby
|
|
27
|
+
VALUE iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt);
|
|
28
|
+
|
|
29
|
+
static VALUE rb_cModulePlaceholder;
|
|
30
|
+
|
|
31
|
+
static VALUE rb_mMarshal;
|
|
32
|
+
|
|
33
|
+
static VALUE rb_cInlineCache;
|
|
34
|
+
|
|
35
|
+
static VALUE rb_cCatchTableEntry;
|
|
36
|
+
|
|
37
|
+
static VALUE marshal_dump(VALUE obj, VALUE limit)
|
|
38
|
+
{
|
|
39
|
+
return rb_funcall(rb_mMarshal, rb_intern("dump"), 2, obj, limit);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static VALUE marshal_load(VALUE obj)
|
|
43
|
+
{
|
|
44
|
+
return rb_funcall(rb_mMarshal, rb_intern("load"), 1, obj);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static rb_iseq_t *
|
|
48
|
+
iseq_check(VALUE val)
|
|
49
|
+
{
|
|
50
|
+
rb_iseq_t *iseq;
|
|
51
|
+
if(!rb_obj_is_kind_of(val, rb_cISeq))
|
|
52
|
+
{
|
|
53
|
+
rb_raise(
|
|
54
|
+
rb_eTypeError,
|
|
55
|
+
"Expected VM::InstructionSequence, but got %s",
|
|
56
|
+
rb_class2name(CLASS_OF(val)));
|
|
57
|
+
}
|
|
58
|
+
GetISeqPtr(val, iseq);
|
|
59
|
+
if (!iseq->name) {
|
|
60
|
+
rb_raise(rb_eTypeError, "uninitialized InstructionSequence");
|
|
61
|
+
}
|
|
62
|
+
return iseq;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* call-seq:
|
|
66
|
+
* iseq.self => VM::InstructionSequence
|
|
67
|
+
*
|
|
68
|
+
* Returns the self member of the instruction sequence.
|
|
69
|
+
*/
|
|
70
|
+
static VALUE iseq_self(VALUE self)
|
|
71
|
+
{
|
|
72
|
+
rb_iseq_t * iseqdat = iseq_check(self);
|
|
73
|
+
return iseqdat->self;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* call-seq:
|
|
77
|
+
* iseq.parent_iseq => VM::InstructionSequence or nil
|
|
78
|
+
*
|
|
79
|
+
* Returns the parent instruction sequence.
|
|
80
|
+
*/
|
|
81
|
+
static VALUE iseq_parent_iseq(VALUE self)
|
|
82
|
+
{
|
|
83
|
+
rb_iseq_t * iseqdat = iseq_check(self);
|
|
84
|
+
rb_iseq_t * parent = iseqdat->parent_iseq;
|
|
85
|
+
if(parent)
|
|
86
|
+
{
|
|
87
|
+
return parent->self;
|
|
88
|
+
}
|
|
89
|
+
else
|
|
90
|
+
{
|
|
91
|
+
return Qnil;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* call-seq:
|
|
96
|
+
* iseq.local_iseq => VM::InstructionSequence or nil
|
|
97
|
+
*
|
|
98
|
+
* Returns the instruction sequence that contains the local variables.
|
|
99
|
+
*/
|
|
100
|
+
static VALUE iseq_local_iseq(VALUE self)
|
|
101
|
+
{
|
|
102
|
+
rb_iseq_t * iseqdat = iseq_check(self);
|
|
103
|
+
rb_iseq_t * local_iseq = iseqdat->local_iseq;
|
|
104
|
+
if(local_iseq)
|
|
105
|
+
{
|
|
106
|
+
return local_iseq->self;
|
|
107
|
+
}
|
|
108
|
+
else
|
|
109
|
+
{
|
|
110
|
+
return Qnil;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/* call-seq:
|
|
114
|
+
* iseq.name => String
|
|
115
|
+
*
|
|
116
|
+
* Returns the name of the instruction sequence.
|
|
117
|
+
*/
|
|
118
|
+
static VALUE iseq_name(VALUE self)
|
|
119
|
+
{
|
|
120
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
121
|
+
return iseqdat->name;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* call-seq:
|
|
125
|
+
* iseq.filename => String
|
|
126
|
+
*
|
|
127
|
+
* Returns the filename of the instruction sequence.
|
|
128
|
+
*/
|
|
129
|
+
static VALUE iseq_filename(VALUE self)
|
|
130
|
+
{
|
|
131
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
132
|
+
return iseqdat->filename;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* call-seq:
|
|
136
|
+
* iseq.local_table => String
|
|
137
|
+
*
|
|
138
|
+
* Returns the sequence's local table.
|
|
139
|
+
*/
|
|
140
|
+
static VALUE iseq_local_table(VALUE self)
|
|
141
|
+
{
|
|
142
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
143
|
+
VALUE ary = rb_ary_new();
|
|
144
|
+
int j;
|
|
145
|
+
|
|
146
|
+
for(j = 0; j < iseqdat->local_table_size; ++j)
|
|
147
|
+
{
|
|
148
|
+
ID id = iseqdat->local_table[j];
|
|
149
|
+
if(rb_id2name(id))
|
|
150
|
+
{
|
|
151
|
+
rb_ary_push(ary, ID2SYM(id));
|
|
152
|
+
}
|
|
153
|
+
else
|
|
154
|
+
{
|
|
155
|
+
// Temporary
|
|
156
|
+
rb_ary_push(ary, Qnil);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return ary;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* call-seq:
|
|
164
|
+
* iseq.argc => String
|
|
165
|
+
*
|
|
166
|
+
* Returns the number of non-optional arguments.
|
|
167
|
+
*/
|
|
168
|
+
static VALUE iseq_argc(VALUE self)
|
|
169
|
+
{
|
|
170
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
171
|
+
return INT2NUM(iseqdat->argc);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* call-seq:
|
|
175
|
+
* iseq.arg_simple => true or false
|
|
176
|
+
*
|
|
177
|
+
* Returns true if this sequence takes only simple (non-rest, non-opt,
|
|
178
|
+
* non-block) args.
|
|
179
|
+
*/
|
|
180
|
+
static VALUE iseq_arg_simple(VALUE self)
|
|
181
|
+
{
|
|
182
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
183
|
+
return iseqdat->arg_simple ? Qtrue : Qfalse;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* call-seq:
|
|
187
|
+
* iseq.arg_rest => true or false
|
|
188
|
+
*
|
|
189
|
+
* Returns the index of the rest (*x) arg.
|
|
190
|
+
*/
|
|
191
|
+
static VALUE iseq_arg_rest(VALUE self)
|
|
192
|
+
{
|
|
193
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
194
|
+
return INT2NUM(iseqdat->arg_rest);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* call-seq:
|
|
198
|
+
* iseq.arg_block => true or false
|
|
199
|
+
*
|
|
200
|
+
* Returns the index of the block (&x) arg.
|
|
201
|
+
*/
|
|
202
|
+
static VALUE iseq_arg_block(VALUE self)
|
|
203
|
+
{
|
|
204
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
205
|
+
return INT2NUM(iseqdat->arg_block);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* call-seq:
|
|
209
|
+
* iseq.arg_opt_table => Array of Integer
|
|
210
|
+
*
|
|
211
|
+
* Returns optional argument table. The value in the table represent
|
|
212
|
+
* the index into the instruction sequence of the code to set the
|
|
213
|
+
* optional argument. The last element is the index of the start of the
|
|
214
|
+
* code sequence.
|
|
215
|
+
*/
|
|
216
|
+
static VALUE iseq_arg_opt_table(VALUE self)
|
|
217
|
+
{
|
|
218
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
219
|
+
VALUE ary = rb_ary_new();
|
|
220
|
+
int j;
|
|
221
|
+
|
|
222
|
+
for(j = 0; j < iseqdat->arg_opts; ++j)
|
|
223
|
+
{
|
|
224
|
+
rb_ary_push(ary, INT2NUM(iseqdat->arg_opt_table[j]));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return ary;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* call-seq:
|
|
231
|
+
* iseq.each(pc_start=0, &block) => nil
|
|
232
|
+
*
|
|
233
|
+
* Yields each instruction in the sequence.
|
|
234
|
+
*
|
|
235
|
+
* If pc_start is supplied, begins iteration at the given offset from
|
|
236
|
+
* the beginning of the sequence.
|
|
237
|
+
*
|
|
238
|
+
*/
|
|
239
|
+
static VALUE iseq_each(int argc, VALUE * argv, VALUE self)
|
|
240
|
+
{
|
|
241
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
242
|
+
VALUE * seq;
|
|
243
|
+
VALUE pc_start_v = Qnil;
|
|
244
|
+
unsigned long pc_start = 0;
|
|
245
|
+
|
|
246
|
+
rb_scan_args(argc, argv, "01", &pc_start_v);
|
|
247
|
+
|
|
248
|
+
if(RTEST(pc_start_v))
|
|
249
|
+
{
|
|
250
|
+
pc_start = NUM2ULONG(pc_start_v);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
for(seq = iseqdat->iseq + pc_start;
|
|
254
|
+
seq < iseqdat->iseq + iseqdat->iseq_size;
|
|
255
|
+
)
|
|
256
|
+
{
|
|
257
|
+
VALUE insn = *seq++;
|
|
258
|
+
int op_type_idx;
|
|
259
|
+
int len = insn_len(insn);
|
|
260
|
+
VALUE args = rb_ary_new();
|
|
261
|
+
|
|
262
|
+
for(op_type_idx = 0; op_type_idx < len-1; ++op_type_idx, ++seq)
|
|
263
|
+
{
|
|
264
|
+
switch(insn_op_type(insn, op_type_idx))
|
|
265
|
+
{
|
|
266
|
+
case TS_VALUE:
|
|
267
|
+
rb_ary_push(args, *seq);
|
|
268
|
+
break;
|
|
269
|
+
|
|
270
|
+
case TS_LINDEX:
|
|
271
|
+
case TS_DINDEX:
|
|
272
|
+
case TS_NUM:
|
|
273
|
+
rb_ary_push(args, INT2FIX(*seq));
|
|
274
|
+
break;
|
|
275
|
+
|
|
276
|
+
case TS_ISEQ:
|
|
277
|
+
{
|
|
278
|
+
rb_iseq_t * iseq = (rb_iseq_t *)*seq;
|
|
279
|
+
if(iseq)
|
|
280
|
+
{
|
|
281
|
+
rb_ary_push(args, iseq->self);
|
|
282
|
+
}
|
|
283
|
+
else
|
|
284
|
+
{
|
|
285
|
+
rb_ary_push(args, Qnil);
|
|
286
|
+
}
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
case TS_GENTRY:
|
|
291
|
+
{
|
|
292
|
+
struct global_entry *entry = (struct global_entry *)*seq;
|
|
293
|
+
rb_ary_push(args, ID2SYM(rb_intern(rb_id2name(entry->id))));
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
case TS_OFFSET:
|
|
298
|
+
rb_ary_push(args, LONG2NUM(*seq));
|
|
299
|
+
/* TODO */
|
|
300
|
+
break;
|
|
301
|
+
|
|
302
|
+
case TS_VARIABLE:
|
|
303
|
+
rb_ary_push(args, Qnil);
|
|
304
|
+
/* TODO */
|
|
305
|
+
break;
|
|
306
|
+
|
|
307
|
+
case TS_CDHASH:
|
|
308
|
+
rb_ary_push(args, Qnil);
|
|
309
|
+
/* TODO */
|
|
310
|
+
break;
|
|
311
|
+
|
|
312
|
+
case TS_IC:
|
|
313
|
+
{
|
|
314
|
+
NODE * ic = (NODE *)*seq;
|
|
315
|
+
rb_ary_push(args, wrap_node_as(ic, rb_cInlineCache));
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
case TS_ID:
|
|
320
|
+
rb_ary_push(args, ID2SYM(*seq));
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
rb_yield(allocate_instruction(insn, args));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return Qnil;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* call-seq:
|
|
332
|
+
* iseq.insn_line(n) => Integer
|
|
333
|
+
*
|
|
334
|
+
* Returns the line number of the nth instruction in the sequence.
|
|
335
|
+
*/
|
|
336
|
+
static VALUE iseq_insn_line(VALUE self, VALUE n)
|
|
337
|
+
{
|
|
338
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
339
|
+
unsigned long pos = NUM2LONG(n);
|
|
340
|
+
unsigned long i, size = iseqdat->insn_info_size;
|
|
341
|
+
struct iseq_insn_info_entry *iiary = iseqdat->insn_info_table;
|
|
342
|
+
|
|
343
|
+
for (i = 0; i < size; i++) {
|
|
344
|
+
if (iiary[i].position == pos) {
|
|
345
|
+
return INT2NUM(iiary[i].line_no);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return Qnil;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/* call-seq:
|
|
352
|
+
* iseq.catch_table => Array of CatchTableEntry
|
|
353
|
+
*
|
|
354
|
+
* Returns the catch table for the sequence
|
|
355
|
+
*/
|
|
356
|
+
static VALUE iseq_catch_table(VALUE self)
|
|
357
|
+
{
|
|
358
|
+
rb_iseq_t *iseqdat = iseq_check(self);
|
|
359
|
+
unsigned long j;
|
|
360
|
+
|
|
361
|
+
VALUE catch_table = rb_ary_new();
|
|
362
|
+
|
|
363
|
+
for(j = 0; j < iseqdat->catch_table_size; ++j)
|
|
364
|
+
{
|
|
365
|
+
VALUE catch_table_entry = rb_struct_new(
|
|
366
|
+
rb_cCatchTableEntry,
|
|
367
|
+
iseqdat->catch_table[j].type,
|
|
368
|
+
iseqdat->catch_table[j].iseq,
|
|
369
|
+
ULONG2NUM(iseqdat->catch_table[j].start),
|
|
370
|
+
ULONG2NUM(iseqdat->catch_table[j].end),
|
|
371
|
+
ULONG2NUM(iseqdat->catch_table[j].cont),
|
|
372
|
+
ULONG2NUM(iseqdat->catch_table[j].sp));
|
|
373
|
+
rb_ary_push(catch_table, catch_table_entry);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return catch_table;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/* The putobject instruction takes a VALUE as a parameter. But if this
|
|
380
|
+
* value is a class, we'll end up trying to dump the class! That's
|
|
381
|
+
* probably not what we want, so we use a placeholder instead.
|
|
382
|
+
*/
|
|
383
|
+
void convert_modules_to_placeholders(VALUE array)
|
|
384
|
+
{
|
|
385
|
+
int j;
|
|
386
|
+
|
|
387
|
+
for(j = 0; j < RARRAY_LEN(array); ++j)
|
|
388
|
+
{
|
|
389
|
+
VALUE v = RARRAY_PTR(array)[j];
|
|
390
|
+
if(TYPE(v) == T_ARRAY)
|
|
391
|
+
{
|
|
392
|
+
convert_modules_to_placeholders(v);
|
|
393
|
+
}
|
|
394
|
+
else if(TYPE(v) == T_MODULE || TYPE(v) == T_CLASS)
|
|
395
|
+
{
|
|
396
|
+
VALUE p = rb_class_new_instance(0, 0, rb_cModulePlaceholder);
|
|
397
|
+
VALUE sym = rb_mod_name(v);
|
|
398
|
+
rb_iv_set(p, "name", sym);
|
|
399
|
+
RARRAY_PTR(array)[j] = p;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
void convert_placeholders_to_modules(VALUE array)
|
|
405
|
+
{
|
|
406
|
+
int j;
|
|
407
|
+
|
|
408
|
+
for(j = 0; j < RARRAY_LEN(array); ++j)
|
|
409
|
+
{
|
|
410
|
+
VALUE v = RARRAY_PTR(array)[j];
|
|
411
|
+
if(TYPE(v) == T_ARRAY)
|
|
412
|
+
{
|
|
413
|
+
convert_placeholders_to_modules(v);
|
|
414
|
+
}
|
|
415
|
+
else if(CLASS_OF(v) == rb_cModulePlaceholder)
|
|
416
|
+
{
|
|
417
|
+
VALUE sym = rb_ivar_get(v, rb_intern("name"));
|
|
418
|
+
VALUE klass = lookup_module(sym);
|
|
419
|
+
RARRAY_PTR(array)[j] = klass;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/*
|
|
425
|
+
* call-seq:
|
|
426
|
+
* iseq.dump(limit) => String
|
|
427
|
+
*
|
|
428
|
+
* Dumps VM::InstuctionSequence to a string (only available on YARV).
|
|
429
|
+
*/
|
|
430
|
+
static VALUE iseq_marshal_dump(VALUE self, VALUE limit)
|
|
431
|
+
{
|
|
432
|
+
VALUE arr;
|
|
433
|
+
|
|
434
|
+
if(rb_safe_level() >= 4)
|
|
435
|
+
{
|
|
436
|
+
/* no access to potentially sensitive data from the sandbox */
|
|
437
|
+
rb_raise(rb_eSecurityError, "Insecure: can't dump iseq");
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
arr = rb_funcall(self, rb_intern("to_a"), 0);
|
|
441
|
+
convert_modules_to_placeholders(arr);
|
|
442
|
+
|
|
443
|
+
return marshal_dump(arr, limit);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/*
|
|
447
|
+
* call-seq:
|
|
448
|
+
* VM::InstructionSequence.load(String) => VM::InstructionSequence
|
|
449
|
+
*
|
|
450
|
+
* Load a VM::InstuctionSequence from a string (only available on YARV).
|
|
451
|
+
*/
|
|
452
|
+
static VALUE iseq_marshal_load(VALUE klass, VALUE str)
|
|
453
|
+
{
|
|
454
|
+
VALUE arr;
|
|
455
|
+
|
|
456
|
+
if( rb_safe_level() >= 4
|
|
457
|
+
|| (rb_safe_level() >= 1 && OBJ_TAINTED(str)))
|
|
458
|
+
{
|
|
459
|
+
/* no playing with knives in the sandbox */
|
|
460
|
+
rb_raise(rb_eSecurityError, "Insecure: can't load iseq");
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
arr = marshal_load(str);
|
|
464
|
+
convert_placeholders_to_modules(arr);
|
|
465
|
+
|
|
466
|
+
VALUE iseq = iseq_load(Qnil, arr, 0, Qnil);
|
|
467
|
+
return iseq;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
void dump_iseq_to_hash(VALUE iseq, VALUE node_hash)
|
|
471
|
+
{
|
|
472
|
+
if(RTEST(rb_hash_aref(node_hash, rb_obj_id(iseq))))
|
|
473
|
+
{
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
rb_hash_aset(node_hash, rb_obj_id(iseq), iseq);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
VALUE load_iseq_from_hash(VALUE iseq, VALUE orig_node_id, VALUE node_hash, VALUE id_hash)
|
|
481
|
+
{
|
|
482
|
+
rb_hash_aset(id_hash, orig_node_id, rb_obj_id(iseq));
|
|
483
|
+
return iseq;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
#endif
|
|
487
|
+
|
|
488
|
+
void Init_iseq(void)
|
|
489
|
+
{
|
|
490
|
+
#ifdef RUBY_VM
|
|
491
|
+
VALUE rb_cRubyVM;
|
|
492
|
+
|
|
493
|
+
rb_require("internal/node");
|
|
494
|
+
rb_require("internal/module");
|
|
495
|
+
rb_require("internal/vm/instruction");
|
|
496
|
+
rb_require("internal/vm/inline_cache");
|
|
497
|
+
|
|
498
|
+
rb_mMarshal = rb_const_get(rb_cObject, rb_intern("Marshal"));
|
|
499
|
+
|
|
500
|
+
rb_cModulePlaceholder = rb_define_class("ModulePlaceholder", rb_cObject);
|
|
501
|
+
|
|
502
|
+
if(!rb_const_defined(rb_cObject, rb_intern("RubyVM")))
|
|
503
|
+
{
|
|
504
|
+
rb_define_const(
|
|
505
|
+
rb_cObject,
|
|
506
|
+
"RubyVM",
|
|
507
|
+
rb_const_get(rb_cObject, rb_intern("VM")));
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
rb_cRubyVM = rb_define_class("RubyVM", rb_cObject);
|
|
511
|
+
rb_cInlineCache = rb_const_get(rb_cRubyVM, rb_intern("InlineCache"));
|
|
512
|
+
|
|
513
|
+
/* For rdoc: rb_cISeq = rb_define_class_under(rb_cRubyVM, "InstructionSequence", rb_cObject) */
|
|
514
|
+
rb_define_method(rb_cISeq, "self", iseq_self, 0);
|
|
515
|
+
rb_define_method(rb_cISeq, "parent_iseq", iseq_parent_iseq, 0);
|
|
516
|
+
rb_define_method(rb_cISeq, "local_iseq", iseq_local_iseq, 0);
|
|
517
|
+
rb_define_method(rb_cISeq, "name", iseq_name, 0);
|
|
518
|
+
rb_define_method(rb_cISeq, "filename", iseq_filename, 0);
|
|
519
|
+
rb_define_method(rb_cISeq, "local_table", iseq_local_table, 0);
|
|
520
|
+
rb_define_method(rb_cISeq, "argc", iseq_argc, 0);
|
|
521
|
+
rb_define_method(rb_cISeq, "arg_simple", iseq_arg_simple, 0);
|
|
522
|
+
rb_define_method(rb_cISeq, "arg_rest", iseq_arg_rest, 0);
|
|
523
|
+
rb_define_method(rb_cISeq, "arg_block", iseq_arg_block, 0);
|
|
524
|
+
rb_define_method(rb_cISeq, "arg_opt_table", iseq_arg_opt_table, 0);
|
|
525
|
+
rb_define_method(rb_cISeq, "each", iseq_each, -1);
|
|
526
|
+
rb_define_method(rb_cISeq, "insn_line", iseq_insn_line, 1);
|
|
527
|
+
rb_define_method(rb_cISeq, "catch_table", iseq_catch_table, 0);
|
|
528
|
+
rb_include_module(rb_cISeq, rb_mEnumerable);
|
|
529
|
+
rb_define_method(rb_cISeq, "_dump", iseq_marshal_dump, 1);
|
|
530
|
+
rb_define_singleton_method(rb_cISeq, "_load", iseq_marshal_load, 1);
|
|
531
|
+
|
|
532
|
+
rb_cCatchTableEntry = rb_struct_define(
|
|
533
|
+
0,
|
|
534
|
+
"type",
|
|
535
|
+
"iseq",
|
|
536
|
+
"start",
|
|
537
|
+
"end",
|
|
538
|
+
"cont",
|
|
539
|
+
"sp",
|
|
540
|
+
0);
|
|
541
|
+
rb_const_set(rb_cISeq, rb_intern("CatchTableEntry"), rb_cCatchTableEntry);
|
|
542
|
+
|
|
543
|
+
rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_RESCUE"), CATCH_TYPE_RESCUE);
|
|
544
|
+
rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_ENSURE"), CATCH_TYPE_ENSURE);
|
|
545
|
+
rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_RETRY"), CATCH_TYPE_RETRY);
|
|
546
|
+
rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_BREAK"), CATCH_TYPE_BREAK);
|
|
547
|
+
rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_REDO"), CATCH_TYPE_REDO);
|
|
548
|
+
rb_const_set(rb_cISeq, rb_intern("CATCH_TYPE_NEXT"), CATCH_TYPE_NEXT);
|
|
549
|
+
|
|
550
|
+
/* Prevent compiler warnings about unused static functions */
|
|
551
|
+
insn_name(0);
|
|
552
|
+
insn_op_types(0);
|
|
553
|
+
#endif
|
|
554
|
+
}
|
|
555
|
+
|