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,44 @@
|
|
|
1
|
+
#ifndef ruby_internal_block__h_
|
|
2
|
+
#define ruby_internal_block__h_
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#ifndef RUBY_VM
|
|
7
|
+
#include "env.h"
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
#ruby <<END
|
|
11
|
+
$: << '../..'
|
|
12
|
+
require 'ruby_source_dir'
|
|
13
|
+
vm_c_location = "#{RUBY_SOURCE_DIR}/vm.c"
|
|
14
|
+
eval_c_location = "#{RUBY_SOURCE_DIR}/eval.c"
|
|
15
|
+
|
|
16
|
+
[ vm_c_location, eval_c_location ].each do |file|
|
|
17
|
+
next if not File.exist?(file)
|
|
18
|
+
|
|
19
|
+
File.open(file) do |eval_c|
|
|
20
|
+
write = false
|
|
21
|
+
stopwrite = false
|
|
22
|
+
while (line = eval_c.gets) != nil do
|
|
23
|
+
case line
|
|
24
|
+
when /^struct (BLOCK)/
|
|
25
|
+
write = true
|
|
26
|
+
stopwrite = false
|
|
27
|
+
when /^\}/
|
|
28
|
+
stopwrite = true
|
|
29
|
+
end
|
|
30
|
+
puts line if write
|
|
31
|
+
if write and stopwrite then
|
|
32
|
+
stopwrite = false
|
|
33
|
+
write = false
|
|
34
|
+
puts ''
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
nil
|
|
41
|
+
END
|
|
42
|
+
|
|
43
|
+
#endif
|
|
44
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#ifndef BUILTINS_H
|
|
2
|
+
#define BUILTINS_H
|
|
3
|
+
|
|
4
|
+
#include "ruby.h"
|
|
5
|
+
|
|
6
|
+
/* Macros for manipulating builtins */
|
|
7
|
+
|
|
8
|
+
#ifndef RARRAY_LEN
|
|
9
|
+
#define RARRAY_LEN(a) RARRAY(a)->len
|
|
10
|
+
#endif
|
|
11
|
+
|
|
12
|
+
#ifndef RARRAY_PTR
|
|
13
|
+
#define RARRAY_PTR(a) RARRAY(a)->ptr
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
#ifndef RSTRING_LEN
|
|
17
|
+
#define RSTRING_LEN(a) RSTRING(a)->len
|
|
18
|
+
#endif
|
|
19
|
+
|
|
20
|
+
#ifndef RSTRING_PTR
|
|
21
|
+
#define RSTRING_PTR(a) RSTRING(a)->ptr
|
|
22
|
+
#endif
|
|
23
|
+
|
|
24
|
+
#ifndef RCLASS_SUPER
|
|
25
|
+
#define RCLASS_SUPER(c) RCLASS(c)->super
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
#ifndef RCLASS_IV_TBL
|
|
29
|
+
#define RCLASS_IV_TBL(c) RCLASS(c)->iv_tbl
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
#ifndef RCLASS_M_TBL
|
|
33
|
+
#define RCLASS_M_TBL(c) RCLASS(c)->m_tbl
|
|
34
|
+
#endif
|
|
35
|
+
|
|
36
|
+
#ifndef NEW_NODE
|
|
37
|
+
#define NEW_NODE(t,a0,a1,a2) \
|
|
38
|
+
rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))
|
|
39
|
+
#endif
|
|
40
|
+
|
|
41
|
+
#endif
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
$: << '../..'
|
|
2
|
+
require 'mkmf-ruby-internal'
|
|
3
|
+
|
|
4
|
+
module Kernel
|
|
5
|
+
if not method_defined?(:try_const)
|
|
6
|
+
alias_method :try_const, :try_constant
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
if not method_defined?(:checking_message)
|
|
10
|
+
def checking_message(checking_for, headers = nil, opt = "")
|
|
11
|
+
return checking_for
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
if not method_defined?(:have_const)
|
|
16
|
+
def have_const(const, headers = nil, opt = "", &b)
|
|
17
|
+
checking_for checking_message([*const].compact.join(' '), headers, opt) do
|
|
18
|
+
try_const(const, headers, opt, &b)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
ruby_version_code = RUBY_VERSION.gsub(/\./, '').to_i
|
|
25
|
+
|
|
26
|
+
have_type('st_data_t', [ 'ruby.h', 'st.h' ]) or
|
|
27
|
+
have_type('st_data_t', [ 'ruby.h', 'ruby/st.h'])
|
|
28
|
+
|
|
29
|
+
have_const('NODE_ALLOCA', [ 'ruby.h', 'node.h' ]) or
|
|
30
|
+
have_const('NODE_ALLOCA', [ 'ruby.h', 'ruby/node.h' ])
|
|
31
|
+
|
|
32
|
+
have_func('rb_protect_inspect', 'ruby.h')
|
|
33
|
+
have_func('rb_obj_respond_to', 'ruby.h')
|
|
34
|
+
have_func('rb_define_alloc_func', 'ruby.h')
|
|
35
|
+
have_func('rb_is_local_id', 'ruby.h')
|
|
36
|
+
have_func('rb_source_filename', 'ruby.h')
|
|
37
|
+
|
|
38
|
+
checking_for("ruby_top_cref") do
|
|
39
|
+
if try_link(<<-END) then
|
|
40
|
+
#include <stdio.h>
|
|
41
|
+
extern void * ruby_top_cref;
|
|
42
|
+
int main() { printf("%p\\n", ruby_top_cref); return 0; }
|
|
43
|
+
END
|
|
44
|
+
$defs.push "-DHAVE_RUBY_TOP_CREF"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
checking_for("ruby_cref") do
|
|
49
|
+
if try_link(<<-END) then
|
|
50
|
+
#include <stdio.h>
|
|
51
|
+
extern void * ruby_cref;
|
|
52
|
+
int main() { printf("%p\\n", ruby_cref); return 0; }
|
|
53
|
+
END
|
|
54
|
+
$defs.push "-DHAVE_RUBY_CREF"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
have_header('iseq.h')
|
|
59
|
+
|
|
60
|
+
ruby_version_code = RUBY_VERSION.gsub(/\./, '').to_i
|
|
61
|
+
$CPPFLAGS << " -DRUBY_VERSION_CODE=#{ruby_version_code}"
|
|
62
|
+
|
|
63
|
+
have_header('ruby/node.h') or have_header('node.h')
|
|
64
|
+
|
|
65
|
+
create_ruby_internal_makefile 'internal/node/node'
|
|
66
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#ifndef global_entry__h_
|
|
2
|
+
#define global_entry__h_
|
|
3
|
+
|
|
4
|
+
#ruby <<END
|
|
5
|
+
$: << '../..'
|
|
6
|
+
require 'ruby_source_dir'
|
|
7
|
+
variable_c_location = "#{RUBY_SOURCE_DIR}/variable.c"
|
|
8
|
+
File.open(variable_c_location) do |variable_c|
|
|
9
|
+
write = false
|
|
10
|
+
stopwrite = false
|
|
11
|
+
while (line = variable_c.gets) != nil do
|
|
12
|
+
case line
|
|
13
|
+
when /^struct global_entry/
|
|
14
|
+
write = true
|
|
15
|
+
stopwrite = false
|
|
16
|
+
when /^\}/
|
|
17
|
+
stopwrite = true if write
|
|
18
|
+
end
|
|
19
|
+
puts line if write
|
|
20
|
+
break if stopwrite
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
END
|
|
24
|
+
|
|
25
|
+
#endif
|
|
26
|
+
|
|
@@ -0,0 +1,1147 @@
|
|
|
1
|
+
#include "nodeinfo.h"
|
|
2
|
+
#include "ruby_internal_node.h"
|
|
3
|
+
#include "node_type_descrip.h"
|
|
4
|
+
#include "block.h"
|
|
5
|
+
#include "builtins.h"
|
|
6
|
+
#include "internal/vm/iseq/internal_iseq.h"
|
|
7
|
+
|
|
8
|
+
#include <ruby.h>
|
|
9
|
+
|
|
10
|
+
#ifdef RUBY_VM
|
|
11
|
+
#include <ruby/st.h>
|
|
12
|
+
#else
|
|
13
|
+
#include <rubysig.h>
|
|
14
|
+
#include <st.h>
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
#include <ctype.h>
|
|
18
|
+
|
|
19
|
+
#ifdef RUBY_VM
|
|
20
|
+
#include "eval_intern.h"
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
#ifdef HAVE_ISEQ_H
|
|
24
|
+
#include "iseq.h"
|
|
25
|
+
#endif
|
|
26
|
+
|
|
27
|
+
#ifndef RARRAY_LEN
|
|
28
|
+
#define RARRAY_LEN(a) RARRAY(a)->len
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
#ifndef RARRAY_PTR
|
|
32
|
+
#define RARRAY_PTR(a) RARRAY(a)->ptr
|
|
33
|
+
#endif
|
|
34
|
+
|
|
35
|
+
static VALUE rb_cNode = Qnil;
|
|
36
|
+
static VALUE rb_cNodeType = Qnil;
|
|
37
|
+
VALUE rb_cNodeSubclass[NODE_LAST];
|
|
38
|
+
static VALUE rb_mMarshal = Qnil;
|
|
39
|
+
|
|
40
|
+
#ifndef HAVE_TYPE_ST_DATA_T
|
|
41
|
+
typedef void st_data_t;
|
|
42
|
+
#endif
|
|
43
|
+
|
|
44
|
+
static VALUE wrapped_nodes = Qnil;
|
|
45
|
+
|
|
46
|
+
/* ---------------------------------------------------------------------
|
|
47
|
+
* Node helper functions
|
|
48
|
+
* ---------------------------------------------------------------------
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
static void wrapped_nodes_end_proc(VALUE data)
|
|
52
|
+
{
|
|
53
|
+
wrapped_nodes = Qnil;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static void mark_node(
|
|
57
|
+
void * data)
|
|
58
|
+
{
|
|
59
|
+
rb_gc_mark((VALUE)data);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static void free_node(
|
|
63
|
+
void * data)
|
|
64
|
+
{
|
|
65
|
+
VALUE key, node_id;
|
|
66
|
+
|
|
67
|
+
if(wrapped_nodes == Qnil)
|
|
68
|
+
{
|
|
69
|
+
/* We're finalizing at exit, so don't clean up */
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
key = LONG2FIX((long)data / 4);
|
|
74
|
+
node_id = rb_hash_aref(wrapped_nodes, key);
|
|
75
|
+
|
|
76
|
+
if(NIL_P(node_id))
|
|
77
|
+
{
|
|
78
|
+
rb_bug("tried to free a node that wasn't wrapped!");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
rb_funcall(wrapped_nodes, rb_intern("delete"), 1, LONG2NUM((long)data / 4));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
VALUE wrap_node_as(NODE * n, VALUE klass)
|
|
85
|
+
{
|
|
86
|
+
VALUE node_id;
|
|
87
|
+
|
|
88
|
+
if(!n)
|
|
89
|
+
{
|
|
90
|
+
return Qnil;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if(wrapped_nodes == Qnil)
|
|
94
|
+
{
|
|
95
|
+
/* We're finalizing at exit so we can't function properly */
|
|
96
|
+
rb_raise(rb_eRuntimeError, "Unable to wrap node during cleanup");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
node_id = rb_hash_aref(wrapped_nodes, LONG2FIX((long)n / 4));
|
|
100
|
+
|
|
101
|
+
if(!NIL_P(node_id))
|
|
102
|
+
{
|
|
103
|
+
return (VALUE)(node_id ^ FIXNUM_FLAG);
|
|
104
|
+
}
|
|
105
|
+
else
|
|
106
|
+
{
|
|
107
|
+
VALUE node = Data_Wrap_Struct(klass, mark_node, free_node, n);
|
|
108
|
+
VALUE node_id = rb_obj_id(node);
|
|
109
|
+
rb_hash_aset(wrapped_nodes, LONG2FIX((long)n / 4), node_id);
|
|
110
|
+
return node;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
VALUE wrap_node(NODE * n)
|
|
115
|
+
{
|
|
116
|
+
if(!n)
|
|
117
|
+
{
|
|
118
|
+
return Qnil;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if(nd_type(n) > NODE_LAST || rb_cNodeSubclass[nd_type(n)] == Qnil)
|
|
122
|
+
{
|
|
123
|
+
rb_raise(rb_eRuntimeError, "Unknown node type %d", nd_type(n));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return wrap_node_as(n, rb_cNodeSubclass[nd_type(n)]);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
NODE * unwrap_node(VALUE r)
|
|
130
|
+
{
|
|
131
|
+
if(!RTEST(r))
|
|
132
|
+
{
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
else
|
|
136
|
+
{
|
|
137
|
+
NODE * n;
|
|
138
|
+
if(TYPE(r) == 0)
|
|
139
|
+
{
|
|
140
|
+
rb_bug("Tried to unwrap recycled node");
|
|
141
|
+
}
|
|
142
|
+
if(!rb_obj_is_kind_of(r, rb_cNode))
|
|
143
|
+
{
|
|
144
|
+
rb_raise(rb_eTypeError, "Expected Node");
|
|
145
|
+
}
|
|
146
|
+
Data_Get_Struct(r, NODE, n);
|
|
147
|
+
return n;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* ---------------------------------------------------------------------
|
|
152
|
+
* Marshalling
|
|
153
|
+
* ---------------------------------------------------------------------
|
|
154
|
+
*/
|
|
155
|
+
|
|
156
|
+
VALUE marshal_dump(VALUE obj, VALUE limit)
|
|
157
|
+
{
|
|
158
|
+
return rb_funcall(rb_mMarshal, rb_intern("dump"), 2, obj, limit);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
VALUE marshal_load(VALUE obj)
|
|
162
|
+
{
|
|
163
|
+
return rb_funcall(rb_mMarshal, rb_intern("load"), 1, obj);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* ---------------------------------------------------------------------
|
|
167
|
+
* Node methods
|
|
168
|
+
* ---------------------------------------------------------------------
|
|
169
|
+
*/
|
|
170
|
+
|
|
171
|
+
/*
|
|
172
|
+
* Document-class: Node
|
|
173
|
+
*
|
|
174
|
+
* Node is a wrapper for Ruby's Nodes, which are not objects. Nodes
|
|
175
|
+
* can be obtained from many of the other methods in the nodewrap
|
|
176
|
+
* library (see Method#body and Proc#body, for example).
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
|
|
180
|
+
/*
|
|
181
|
+
* call-seq:
|
|
182
|
+
* Node.allocate() => Node
|
|
183
|
+
*
|
|
184
|
+
* Allocate a new node.
|
|
185
|
+
*/
|
|
186
|
+
static VALUE node_allocate(VALUE klass)
|
|
187
|
+
{
|
|
188
|
+
NODE * n = NEW_NIL();
|
|
189
|
+
return wrap_node(n);
|
|
190
|
+
}
|
|
191
|
+
#endif
|
|
192
|
+
|
|
193
|
+
/*
|
|
194
|
+
* call-seq:
|
|
195
|
+
* node.address() => Numeric
|
|
196
|
+
*
|
|
197
|
+
* Returns a node's address.
|
|
198
|
+
*/
|
|
199
|
+
static VALUE node_address(VALUE self)
|
|
200
|
+
{
|
|
201
|
+
NODE * n;
|
|
202
|
+
Data_Get_Struct(self, NODE, n);
|
|
203
|
+
return ULONG2NUM((unsigned long)(n));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/*
|
|
207
|
+
* call-seq:
|
|
208
|
+
* node.flags() => Numeric
|
|
209
|
+
*
|
|
210
|
+
* Returns a node's flags.
|
|
211
|
+
*/
|
|
212
|
+
static VALUE node_flags(VALUE self)
|
|
213
|
+
{
|
|
214
|
+
NODE * n;
|
|
215
|
+
Data_Get_Struct(self, NODE, n);
|
|
216
|
+
return INT2NUM(n->flags);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/*
|
|
220
|
+
* call-seq:
|
|
221
|
+
* node.nd_file => String or nil
|
|
222
|
+
*
|
|
223
|
+
* Returns the file the node is associated with
|
|
224
|
+
*/
|
|
225
|
+
static VALUE node_nd_file(VALUE self)
|
|
226
|
+
{
|
|
227
|
+
NODE * n;
|
|
228
|
+
Data_Get_Struct(self, NODE, n);
|
|
229
|
+
#ifdef HAVE_RB_SOURCE_FILENAME
|
|
230
|
+
if(n->nd_file)
|
|
231
|
+
{
|
|
232
|
+
return rb_str_new2(n->nd_file);
|
|
233
|
+
}
|
|
234
|
+
else
|
|
235
|
+
{
|
|
236
|
+
return Qnil;
|
|
237
|
+
}
|
|
238
|
+
#else
|
|
239
|
+
/* nd_file has been removed in 1.9 */
|
|
240
|
+
return Qnil;
|
|
241
|
+
#endif
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/*
|
|
245
|
+
* call-seq:
|
|
246
|
+
* node.nd_line => Numeric
|
|
247
|
+
*
|
|
248
|
+
* Returns the line number the node is associated with.
|
|
249
|
+
*/
|
|
250
|
+
static VALUE node_nd_line(VALUE self)
|
|
251
|
+
{
|
|
252
|
+
NODE * n;
|
|
253
|
+
Data_Get_Struct(self, NODE, n);
|
|
254
|
+
return LONG2NUM(nd_line(n));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/*
|
|
258
|
+
* call-seq:
|
|
259
|
+
* node.nd_type => NodeType
|
|
260
|
+
*
|
|
261
|
+
* Returns a NodeType structure representing the type of the node.
|
|
262
|
+
*/
|
|
263
|
+
static VALUE node_nd_type(VALUE self)
|
|
264
|
+
{
|
|
265
|
+
NODE * n;
|
|
266
|
+
const Node_Type_Descrip * descrip;
|
|
267
|
+
Data_Get_Struct(self, NODE, n);
|
|
268
|
+
rb_check_type((VALUE)(self), T_DATA);
|
|
269
|
+
descrip = node_type_descrip(nd_type(n));
|
|
270
|
+
return rb_struct_new(
|
|
271
|
+
rb_cNodeType,
|
|
272
|
+
rb_str_new2(descrip->name),
|
|
273
|
+
INT2NUM(descrip->nt));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
VALUE node_id(NODE * n)
|
|
277
|
+
{
|
|
278
|
+
return rb_obj_id((VALUE)n);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
NODE * id_to_node(VALUE id)
|
|
282
|
+
{
|
|
283
|
+
unsigned long n = NUM2INT(id);
|
|
284
|
+
return (NODE *)n;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/*
|
|
288
|
+
* call-seq:
|
|
289
|
+
* node.members => Array of String
|
|
290
|
+
*
|
|
291
|
+
* Return an array of strings containing the names of a node's
|
|
292
|
+
* members.
|
|
293
|
+
*/
|
|
294
|
+
static VALUE node_members(VALUE node)
|
|
295
|
+
{
|
|
296
|
+
return node_s_members(rb_class_of(node));
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/*
|
|
300
|
+
* call-seq:
|
|
301
|
+
* node[member] => Object
|
|
302
|
+
*
|
|
303
|
+
* Return the given member of a node.
|
|
304
|
+
*/
|
|
305
|
+
static VALUE node_bracket(VALUE node, VALUE member)
|
|
306
|
+
{
|
|
307
|
+
ID id = SYMBOL_P(member)
|
|
308
|
+
? SYM2ID(member)
|
|
309
|
+
: rb_intern(STR2CSTR(member));
|
|
310
|
+
return rb_funcall(node, id, 0);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
#ifdef HAVE_RB_PROTECT_INSPECT
|
|
314
|
+
static VALUE node_inspect_protect(VALUE node)
|
|
315
|
+
#else
|
|
316
|
+
static VALUE node_inspect_protect(VALUE node, VALUE dummy, int recur)
|
|
317
|
+
#endif
|
|
318
|
+
{
|
|
319
|
+
VALUE str = rb_str_new2("#<");
|
|
320
|
+
rb_str_cat2(str, rb_class2name(CLASS_OF(node)));
|
|
321
|
+
rb_str_cat2(str, " ");
|
|
322
|
+
VALUE members = node_members(node);
|
|
323
|
+
int j;
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
for(j = 0; j < RARRAY_LEN(members); ++j)
|
|
327
|
+
{
|
|
328
|
+
VALUE name = RARRAY_PTR(members)[j];
|
|
329
|
+
VALUE value = node_bracket(node, name);
|
|
330
|
+
rb_str_append(str, name);
|
|
331
|
+
rb_str_cat2(str, "=");
|
|
332
|
+
if(TYPE(value) == T_NODE)
|
|
333
|
+
{
|
|
334
|
+
rb_str_append(str, rb_funcall(value, rb_intern("to_s"), 0));
|
|
335
|
+
}
|
|
336
|
+
else
|
|
337
|
+
{
|
|
338
|
+
rb_str_append(str, rb_funcall(value, rb_intern("inspect"), 0));
|
|
339
|
+
}
|
|
340
|
+
if(j != RARRAY_LEN(members) - 1)
|
|
341
|
+
{
|
|
342
|
+
rb_str_cat2(str, ", ");
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
rb_str_cat2(str, ">");
|
|
347
|
+
|
|
348
|
+
return str;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/*
|
|
352
|
+
* call-seq:
|
|
353
|
+
* node.inspect => String
|
|
354
|
+
*
|
|
355
|
+
* Returns a string representation of the node's data.
|
|
356
|
+
*/
|
|
357
|
+
static VALUE node_inspect(VALUE node)
|
|
358
|
+
{
|
|
359
|
+
#ifdef HAVE_RB_PROTECT_INSPECT
|
|
360
|
+
if(rb_inspecting_p(node))
|
|
361
|
+
{
|
|
362
|
+
VALUE str = rb_str_new2("#<");
|
|
363
|
+
rb_str_cat2(str, rb_class2name(CLASS_OF(node)));
|
|
364
|
+
rb_str_cat2(str, ":...>");
|
|
365
|
+
return str;
|
|
366
|
+
}
|
|
367
|
+
else
|
|
368
|
+
{
|
|
369
|
+
return rb_protect_inspect(node_inspect_protect, node, 0);
|
|
370
|
+
}
|
|
371
|
+
#else
|
|
372
|
+
return rb_exec_recursive(node_inspect_protect, node, 0);
|
|
373
|
+
#endif
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/*
|
|
377
|
+
* call-seq:
|
|
378
|
+
* node.nd_type => NodeType
|
|
379
|
+
*
|
|
380
|
+
* Returns a NodeType structure representing the type of the node.
|
|
381
|
+
*/
|
|
382
|
+
static VALUE node_s_type(VALUE self)
|
|
383
|
+
{
|
|
384
|
+
const Node_Type_Descrip * descrip;
|
|
385
|
+
descrip = node_type_descrip(
|
|
386
|
+
NUM2INT(rb_iv_get(self, "__type__")));
|
|
387
|
+
return rb_struct_new(
|
|
388
|
+
rb_cNodeType,
|
|
389
|
+
rb_str_new2(descrip->name),
|
|
390
|
+
INT2NUM(descrip->nt));
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/* ---------------------------------------------------------------------
|
|
394
|
+
* NodeType methods
|
|
395
|
+
* ---------------------------------------------------------------------
|
|
396
|
+
*/
|
|
397
|
+
|
|
398
|
+
/*
|
|
399
|
+
* Document-class: NodeType
|
|
400
|
+
*
|
|
401
|
+
* NodeType is an abstraction for the C type of a node. It is a Struct
|
|
402
|
+
* which has two members, +name+ and +value+.
|
|
403
|
+
*/
|
|
404
|
+
|
|
405
|
+
/*
|
|
406
|
+
* call-seq:
|
|
407
|
+
* node_type.name => String
|
|
408
|
+
*
|
|
409
|
+
* Returns the name of the node.
|
|
410
|
+
*/
|
|
411
|
+
static VALUE node_type_to_s(VALUE node_type)
|
|
412
|
+
{
|
|
413
|
+
return rb_struct_getmember(node_type, rb_intern("name"));
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/*
|
|
417
|
+
* call-seq:
|
|
418
|
+
* node_type.to_i => Numeric
|
|
419
|
+
*
|
|
420
|
+
* Returns an integer representing integer type of a node. This is the
|
|
421
|
+
* value you would see for the type of the node if you were examining it
|
|
422
|
+
* in gdb.
|
|
423
|
+
*/
|
|
424
|
+
static VALUE node_type_to_i(VALUE node_type)
|
|
425
|
+
{
|
|
426
|
+
return rb_struct_getmember(node_type, rb_intern("value"));
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/* ---------------------------------------------------------------------
|
|
430
|
+
* Node evaluation
|
|
431
|
+
* ---------------------------------------------------------------------
|
|
432
|
+
*/
|
|
433
|
+
|
|
434
|
+
/* TODO: copied from proc.c */
|
|
435
|
+
|
|
436
|
+
#ifndef RUBY_VM
|
|
437
|
+
|
|
438
|
+
static VALUE create_proc(VALUE klass, VALUE binding, NODE * body, NODE * var)
|
|
439
|
+
{
|
|
440
|
+
/* Calling eval will do a security check */
|
|
441
|
+
VALUE new_proc = rb_funcall(
|
|
442
|
+
rb_cObject, rb_intern("eval"), 2, rb_str_new2("proc { }"), binding);
|
|
443
|
+
struct BLOCK * b;
|
|
444
|
+
Data_Get_Struct(new_proc, struct BLOCK, b);
|
|
445
|
+
b->body = body;
|
|
446
|
+
b->var = var;
|
|
447
|
+
RBASIC(new_proc)->klass = klass;
|
|
448
|
+
return new_proc;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
#else
|
|
452
|
+
|
|
453
|
+
/* From iseq.c */
|
|
454
|
+
static rb_iseq_t *
|
|
455
|
+
iseq_check(VALUE val)
|
|
456
|
+
{
|
|
457
|
+
rb_iseq_t *iseq;
|
|
458
|
+
if(!rb_obj_is_kind_of(val, rb_cISeq))
|
|
459
|
+
{
|
|
460
|
+
rb_raise(
|
|
461
|
+
rb_eTypeError,
|
|
462
|
+
"Expected VM::InstructionSequence, but got %s",
|
|
463
|
+
rb_class2name(CLASS_OF(val)));
|
|
464
|
+
}
|
|
465
|
+
GetISeqPtr(val, iseq);
|
|
466
|
+
if (!iseq->name) {
|
|
467
|
+
rb_raise(rb_eTypeError, "uninitialized InstructionSequence");
|
|
468
|
+
}
|
|
469
|
+
return iseq;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
static VALUE create_proc(VALUE klass, VALUE binding, rb_iseq_t * iseq)
|
|
473
|
+
{
|
|
474
|
+
VALUE new_proc;
|
|
475
|
+
rb_proc_t * p;
|
|
476
|
+
|
|
477
|
+
if(binding == Qnil)
|
|
478
|
+
{
|
|
479
|
+
binding = rb_binding_new();
|
|
480
|
+
}
|
|
481
|
+
new_proc = rb_funcall(
|
|
482
|
+
rb_cObject, rb_intern("eval"), 2, rb_str_new2("proc { }"), binding);
|
|
483
|
+
GetProcPtr(new_proc, p);
|
|
484
|
+
p->block.iseq = iseq;
|
|
485
|
+
RBASIC(new_proc)->klass = klass;
|
|
486
|
+
return new_proc;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
#endif
|
|
490
|
+
|
|
491
|
+
/* TODO: It would be nicer if we could eval the node in the current
|
|
492
|
+
* scope, but we have to create a new scope both on 1.8 and on 1.9. */
|
|
493
|
+
VALUE eval_ruby_node(NODE * node, VALUE self, VALUE cref)
|
|
494
|
+
{
|
|
495
|
+
#ifdef RUBY_VM
|
|
496
|
+
if(RTEST(cref))
|
|
497
|
+
{
|
|
498
|
+
rb_raise(
|
|
499
|
+
rb_eArgError,
|
|
500
|
+
"Cannot set cref on YARV");
|
|
501
|
+
}
|
|
502
|
+
else
|
|
503
|
+
{
|
|
504
|
+
VALUE filename = node->nd_file
|
|
505
|
+
? rb_str_new2(node->nd_file)
|
|
506
|
+
: rb_str_new2("<unknown>");
|
|
507
|
+
VALUE iseq;
|
|
508
|
+
|
|
509
|
+
if(nd_type(node) != NODE_SCOPE)
|
|
510
|
+
{
|
|
511
|
+
/* TODO: This is kinda hokey */
|
|
512
|
+
ID * local_tbl = ruby_current_thread->cfp->iseq
|
|
513
|
+
? ruby_current_thread->cfp->iseq->local_table
|
|
514
|
+
: 0;
|
|
515
|
+
node = NEW_NODE(NODE_SCOPE, local_tbl, node, 0);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
iseq = rb_iseq_new(
|
|
519
|
+
node,
|
|
520
|
+
rb_str_new2("<compiled>"),
|
|
521
|
+
filename,
|
|
522
|
+
self,
|
|
523
|
+
ISEQ_TYPE_TOP);
|
|
524
|
+
|
|
525
|
+
/* VALUE str = ruby_iseq_disasm(iseq);
|
|
526
|
+
rb_io_puts(1, &str, rb_stdout); */
|
|
527
|
+
|
|
528
|
+
/* VALUE result = rb_iseq_eval(iseq);
|
|
529
|
+
return result; */
|
|
530
|
+
|
|
531
|
+
rb_proc_t * p;
|
|
532
|
+
VALUE proc;
|
|
533
|
+
|
|
534
|
+
proc = create_proc(rb_cProc, Qnil, iseq_check(iseq));
|
|
535
|
+
GetProcPtr(proc, p);
|
|
536
|
+
p->block.self = self;
|
|
537
|
+
|
|
538
|
+
/* TODO: cref */
|
|
539
|
+
|
|
540
|
+
return rb_funcall(proc, rb_intern("call"), 0);
|
|
541
|
+
}
|
|
542
|
+
#else
|
|
543
|
+
{
|
|
544
|
+
/* Ruby doesn't give us access to rb_eval, so we have to fake it. */
|
|
545
|
+
struct BLOCK * b;
|
|
546
|
+
VALUE proc;
|
|
547
|
+
|
|
548
|
+
proc = create_proc(rb_cProc, Qnil, node, 0);
|
|
549
|
+
Data_Get_Struct(proc, struct BLOCK, b);
|
|
550
|
+
b->self = self;
|
|
551
|
+
|
|
552
|
+
if(RTEST(cref))
|
|
553
|
+
{
|
|
554
|
+
b->cref = unwrap_node(cref);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return rb_funcall(proc, rb_intern("call"), 0);
|
|
558
|
+
}
|
|
559
|
+
#endif
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/*
|
|
563
|
+
* call-seq:
|
|
564
|
+
* node.eval(Object) => Object
|
|
565
|
+
*
|
|
566
|
+
* Evaluate a node with the given object as self and returns the result.
|
|
567
|
+
*/
|
|
568
|
+
static VALUE node_eval(int argc, VALUE * argv, VALUE node)
|
|
569
|
+
{
|
|
570
|
+
NODE * n = unwrap_node(node);
|
|
571
|
+
|
|
572
|
+
VALUE self;
|
|
573
|
+
VALUE cref = Qnil;
|
|
574
|
+
rb_scan_args(argc, argv, "11", &self, &cref);
|
|
575
|
+
|
|
576
|
+
if(rb_safe_level() >= 2)
|
|
577
|
+
{
|
|
578
|
+
/* evaluating a node can cause a crash */
|
|
579
|
+
rb_raise(rb_eSecurityError, "Insecure: can't eval node");
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
return eval_ruby_node(n, self, cref);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/* ---------------------------------------------------------------------
|
|
586
|
+
* Node marshalling
|
|
587
|
+
* ---------------------------------------------------------------------
|
|
588
|
+
*/
|
|
589
|
+
|
|
590
|
+
void dump_node_to_hash(NODE * n, int node_type, VALUE node_hash)
|
|
591
|
+
{
|
|
592
|
+
VALUE s1 = Qnil, s2 = Qnil, s3 = Qnil;
|
|
593
|
+
Node_Type_Descrip const *descrip = node_type_descrip(node_type);
|
|
594
|
+
VALUE nd_file;
|
|
595
|
+
VALUE arr;
|
|
596
|
+
|
|
597
|
+
if(RTEST(rb_hash_aref(node_hash, node_id(n))))
|
|
598
|
+
{
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
if(TYPE(n) != T_NODE)
|
|
603
|
+
{
|
|
604
|
+
rb_raise(
|
|
605
|
+
rb_eTypeError,
|
|
606
|
+
"wrong argument type %s (expected Node)",
|
|
607
|
+
rb_class2name(CLASS_OF(n)));
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
s1 = dump_node_elem(descrip->n1, n, node_hash);
|
|
611
|
+
s2 = dump_node_elem(descrip->n2, n, node_hash);
|
|
612
|
+
s3 = dump_node_elem(descrip->n3, n, node_hash);
|
|
613
|
+
|
|
614
|
+
nd_file = Qnil;
|
|
615
|
+
#ifdef HAVE_RB_SOURCE_FILENAME
|
|
616
|
+
if(n->nd_file)
|
|
617
|
+
{
|
|
618
|
+
nd_file = rb_str_new2(n->nd_file);
|
|
619
|
+
}
|
|
620
|
+
#endif
|
|
621
|
+
|
|
622
|
+
arr = rb_ary_new();
|
|
623
|
+
rb_ary_push(arr, INT2NUM(n->flags));
|
|
624
|
+
rb_ary_push(arr, nd_file);
|
|
625
|
+
rb_ary_push(arr, s1);
|
|
626
|
+
rb_ary_push(arr, s2);
|
|
627
|
+
rb_ary_push(arr, s3);
|
|
628
|
+
|
|
629
|
+
rb_hash_aset(node_hash, node_id(n), arr);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
void dump_node_or_iseq_to_hash(VALUE n, int node_type, VALUE node_hash)
|
|
633
|
+
{
|
|
634
|
+
#ifdef RUBY_VM
|
|
635
|
+
if(TYPE(n) == T_DATA && CLASS_OF(n) == rb_cISeq)
|
|
636
|
+
{
|
|
637
|
+
return dump_iseq_to_hash(n, node_hash);
|
|
638
|
+
}
|
|
639
|
+
#endif
|
|
640
|
+
|
|
641
|
+
dump_node_to_hash((NODE *)n, node_type, node_hash);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
NODE * load_node_from_hash(VALUE arr, VALUE orig_node_id, VALUE node_hash, VALUE id_hash)
|
|
645
|
+
{
|
|
646
|
+
NODE * n = NEW_NIL();
|
|
647
|
+
VALUE s3, s2, s1, rb_nd_file, rb_flags;
|
|
648
|
+
unsigned long flags;
|
|
649
|
+
char *nd_file = 0;
|
|
650
|
+
Node_Type_Descrip const *descrip;
|
|
651
|
+
NODE tmp_node;
|
|
652
|
+
|
|
653
|
+
nd_set_type(&tmp_node, NODE_NIL);
|
|
654
|
+
|
|
655
|
+
Check_Type(arr, T_ARRAY);
|
|
656
|
+
s3 = rb_ary_pop(arr);
|
|
657
|
+
s2 = rb_ary_pop(arr);
|
|
658
|
+
s1 = rb_ary_pop(arr);
|
|
659
|
+
rb_nd_file = rb_ary_pop(arr);
|
|
660
|
+
rb_flags = rb_ary_pop(arr);
|
|
661
|
+
flags = NUM2INT(rb_flags);
|
|
662
|
+
tmp_node.flags = flags;
|
|
663
|
+
|
|
664
|
+
rb_hash_aset(id_hash, orig_node_id, node_id(n));
|
|
665
|
+
|
|
666
|
+
descrip = node_type_descrip(nd_type(&tmp_node));
|
|
667
|
+
load_node_elem(descrip->n1, s1, &tmp_node, node_hash, id_hash);
|
|
668
|
+
load_node_elem(descrip->n2, s2, &tmp_node, node_hash, id_hash);
|
|
669
|
+
load_node_elem(descrip->n3, s3, &tmp_node, node_hash, id_hash);
|
|
670
|
+
|
|
671
|
+
#ifdef HAVE_RB_SOURCE_FILENAME
|
|
672
|
+
/* Note that the garbage collector CAN be invoked at this point, so
|
|
673
|
+
* any node object the GC knowns about must be in a consistent state.
|
|
674
|
+
*/
|
|
675
|
+
if(rb_nd_file != Qnil)
|
|
676
|
+
{
|
|
677
|
+
Check_Type(rb_nd_file, T_STRING);
|
|
678
|
+
nd_file = rb_source_filename(RSTRING_PTR(rb_nd_file));
|
|
679
|
+
}
|
|
680
|
+
#endif
|
|
681
|
+
|
|
682
|
+
/* 1) We must NOT get an exception from here on out, since we are
|
|
683
|
+
* modifying a live node, and so nd_file_buf won't be leaked.
|
|
684
|
+
* 2) We must NOT invoke the garbage collector from here on out, since
|
|
685
|
+
* we are modifying a live node.
|
|
686
|
+
*/
|
|
687
|
+
memcpy(n, &tmp_node, sizeof(NODE));
|
|
688
|
+
n->flags = flags;
|
|
689
|
+
n->nd_file = nd_file;
|
|
690
|
+
|
|
691
|
+
return n;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
VALUE load_node_or_iseq_from_hash(VALUE orig_node_id, VALUE node_hash, VALUE id_hash)
|
|
696
|
+
{
|
|
697
|
+
VALUE data = rb_hash_aref(node_hash, orig_node_id);
|
|
698
|
+
|
|
699
|
+
if(!RTEST(data))
|
|
700
|
+
{
|
|
701
|
+
rb_raise(rb_eArgError, "Could not find node %d in hash", NUM2INT(orig_node_id));
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
#ifdef RUBY_VM
|
|
705
|
+
if(TYPE(data) == T_DATA)
|
|
706
|
+
{
|
|
707
|
+
return (VALUE)load_iseq_from_hash(data, orig_node_id, node_hash, id_hash);
|
|
708
|
+
}
|
|
709
|
+
#endif
|
|
710
|
+
|
|
711
|
+
return (VALUE)load_node_from_hash(data, orig_node_id, node_hash, id_hash);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
static VALUE node_to_hash(NODE * n)
|
|
716
|
+
{
|
|
717
|
+
VALUE node_hash;
|
|
718
|
+
node_hash = rb_hash_new();
|
|
719
|
+
dump_node_to_hash(n, nd_type(n), node_hash);
|
|
720
|
+
return node_hash;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
#ifndef RUBY_VM
|
|
724
|
+
/* From eval.c */
|
|
725
|
+
static void
|
|
726
|
+
compile_error(at)
|
|
727
|
+
const char *at;
|
|
728
|
+
{
|
|
729
|
+
VALUE str;
|
|
730
|
+
|
|
731
|
+
ruby_nerrs = 0;
|
|
732
|
+
str = rb_str_buf_new2("compile error");
|
|
733
|
+
if (at) {
|
|
734
|
+
rb_str_buf_cat2(str, " in ");
|
|
735
|
+
rb_str_buf_cat2(str, at);
|
|
736
|
+
}
|
|
737
|
+
rb_str_buf_cat(str, "\n", 1);
|
|
738
|
+
if (!NIL_P(ruby_errinfo)) {
|
|
739
|
+
rb_str_append(str, rb_obj_as_string(ruby_errinfo));
|
|
740
|
+
}
|
|
741
|
+
rb_exc_raise(rb_exc_new3(rb_eSyntaxError, str));
|
|
742
|
+
}
|
|
743
|
+
#endif
|
|
744
|
+
|
|
745
|
+
/*
|
|
746
|
+
* call-seq:
|
|
747
|
+
* Node.compile_string(str) => Node
|
|
748
|
+
*
|
|
749
|
+
* Compile a string into a node.
|
|
750
|
+
*/
|
|
751
|
+
static VALUE node_compile_string(int argc, VALUE * argv, VALUE self)
|
|
752
|
+
{
|
|
753
|
+
NODE * node;
|
|
754
|
+
VALUE str = Qnil, file = Qnil, line = Qnil;
|
|
755
|
+
|
|
756
|
+
rb_scan_args(argc, argv, "12", &str, &file, &line);
|
|
757
|
+
|
|
758
|
+
file = NIL_P(file) ? rb_str_new2("(compiled)") : file;
|
|
759
|
+
line = NIL_P(line) ? INT2NUM(1) : line;
|
|
760
|
+
|
|
761
|
+
node = rb_compile_string(STR2CSTR(file), str, NUM2INT(line));
|
|
762
|
+
|
|
763
|
+
#ifdef RUBY_VM
|
|
764
|
+
if(!node)
|
|
765
|
+
{
|
|
766
|
+
rb_exc_raise(GET_THREAD()->errinfo);
|
|
767
|
+
}
|
|
768
|
+
#else
|
|
769
|
+
if(ruby_nerrs > 0)
|
|
770
|
+
{
|
|
771
|
+
ruby_nerrs = 0;
|
|
772
|
+
compile_error(0);
|
|
773
|
+
}
|
|
774
|
+
#endif
|
|
775
|
+
|
|
776
|
+
return wrap_node(node);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
#ifdef RUBY_VM
|
|
780
|
+
/*
|
|
781
|
+
* call-seq:
|
|
782
|
+
* node.bytecode_compile => VM::InstructionSequence
|
|
783
|
+
*
|
|
784
|
+
* Compile a parsed node tree into a bytecode sequence.
|
|
785
|
+
*
|
|
786
|
+
* @param name the name of the new iseq (default <unknown>)
|
|
787
|
+
* @param filename the filename for the new iseq (default same as name)
|
|
788
|
+
*/
|
|
789
|
+
static VALUE node_bytecode_compile(int argc, VALUE * argv, VALUE self)
|
|
790
|
+
{
|
|
791
|
+
VALUE name = Qnil;
|
|
792
|
+
VALUE filename = Qnil;
|
|
793
|
+
rb_scan_args(argc, argv, "02", &name, &filename);
|
|
794
|
+
|
|
795
|
+
if(name == Qnil)
|
|
796
|
+
{
|
|
797
|
+
name = rb_str_new2("<unknown>");
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
if(filename == Qnil)
|
|
801
|
+
{
|
|
802
|
+
filename = name;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
NODE * node = unwrap_node(self);
|
|
806
|
+
|
|
807
|
+
return rb_iseq_new(
|
|
808
|
+
node,
|
|
809
|
+
name,
|
|
810
|
+
filename,
|
|
811
|
+
Qfalse,
|
|
812
|
+
ISEQ_TYPE_TOP);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
#endif
|
|
816
|
+
|
|
817
|
+
/*
|
|
818
|
+
* call-seq:
|
|
819
|
+
* node._dump => String
|
|
820
|
+
*
|
|
821
|
+
* Dump a node.
|
|
822
|
+
*/
|
|
823
|
+
static VALUE node_dump(VALUE self, VALUE limit)
|
|
824
|
+
{
|
|
825
|
+
NODE * n;
|
|
826
|
+
VALUE node_hash, arr;
|
|
827
|
+
|
|
828
|
+
if(rb_safe_level() >= 4)
|
|
829
|
+
{
|
|
830
|
+
/* no access to potentially sensitive data from the sandbox */
|
|
831
|
+
rb_raise(rb_eSecurityError, "Insecure: can't dump node");
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
Data_Get_Struct(self, NODE, n);
|
|
835
|
+
node_hash = node_to_hash(n);
|
|
836
|
+
arr = rb_ary_new();
|
|
837
|
+
rb_ary_push(arr, node_id(n));
|
|
838
|
+
rb_ary_push(arr, node_hash);
|
|
839
|
+
VALUE s = marshal_dump(arr, limit);
|
|
840
|
+
return s;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
/*
|
|
844
|
+
* call-seq:
|
|
845
|
+
* Node._load(str) => Node
|
|
846
|
+
*
|
|
847
|
+
* Load a dumped node.
|
|
848
|
+
*/
|
|
849
|
+
static VALUE node_load(VALUE klass, VALUE str)
|
|
850
|
+
{
|
|
851
|
+
VALUE arr, node_hash, node_id, id_hash;
|
|
852
|
+
NODE * n;
|
|
853
|
+
VALUE data;
|
|
854
|
+
|
|
855
|
+
if( rb_safe_level() >= 4
|
|
856
|
+
|| (rb_safe_level() >= 1 && OBJ_TAINTED(str)))
|
|
857
|
+
{
|
|
858
|
+
/* no playing with knives in the sandbox */
|
|
859
|
+
rb_raise(rb_eSecurityError, "Insecure: can't load node");
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
arr = marshal_load(str);
|
|
863
|
+
node_hash = rb_ary_pop(arr);
|
|
864
|
+
node_id = rb_ary_pop(arr);
|
|
865
|
+
id_hash = rb_hash_new();
|
|
866
|
+
data = rb_hash_aref(node_hash, node_id);
|
|
867
|
+
n = load_node_from_hash(data, node_id, node_hash, id_hash);
|
|
868
|
+
/* TODO: Need a free function in this case */
|
|
869
|
+
return wrap_node(n);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
#ifndef HAVE_RB_OBJ_RESPOND_TO
|
|
873
|
+
static VALUE rb_obj_respond_to(VALUE obj, ID id, int priv)
|
|
874
|
+
{
|
|
875
|
+
VALUE include_private = priv ? Qtrue : Qfalse;
|
|
876
|
+
return rb_funcall(obj, rb_intern("respond_to?"), 2, ID2SYM(id), include_private);
|
|
877
|
+
}
|
|
878
|
+
#endif
|
|
879
|
+
|
|
880
|
+
/*
|
|
881
|
+
* call-seq:
|
|
882
|
+
* node.swap(another_node) => Node
|
|
883
|
+
*
|
|
884
|
+
* Swap one node with another. Both nodes must respond to the #swap
|
|
885
|
+
* method. Returns the receiver.
|
|
886
|
+
*/
|
|
887
|
+
static VALUE node_swap(VALUE self, VALUE other)
|
|
888
|
+
{
|
|
889
|
+
NODE * n1;
|
|
890
|
+
NODE * n2;
|
|
891
|
+
NODE tmp;
|
|
892
|
+
|
|
893
|
+
if(!rb_obj_respond_to(other, rb_intern("swap"), 0))
|
|
894
|
+
{
|
|
895
|
+
rb_raise(rb_eArgError, "Argument must respond to #swap");
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
if( rb_safe_level() >= 4
|
|
899
|
+
|| (rb_safe_level() >= 1 && (OBJ_TAINTED(other) || OBJ_TAINTED(self))))
|
|
900
|
+
{
|
|
901
|
+
/* no playing with knives in the sandbox */
|
|
902
|
+
rb_raise(rb_eSecurityError, "Insecure: can't swap node");
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
Data_Get_Struct(self, NODE, n1);
|
|
906
|
+
Data_Get_Struct(other, NODE, n2);
|
|
907
|
+
|
|
908
|
+
tmp = *n1;
|
|
909
|
+
*n1 = *n2;
|
|
910
|
+
*n2 = tmp;
|
|
911
|
+
|
|
912
|
+
return self;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
/* ---------------------------------------------------------------------
|
|
916
|
+
* Eval tree
|
|
917
|
+
* ---------------------------------------------------------------------
|
|
918
|
+
*/
|
|
919
|
+
|
|
920
|
+
/* TODO Not quite sure how to get BEGIN nodes on 1.9.x... */
|
|
921
|
+
#ifndef RUBY_VM
|
|
922
|
+
extern NODE *ruby_eval_tree_begin;
|
|
923
|
+
|
|
924
|
+
extern NODE *ruby_eval_tree;
|
|
925
|
+
|
|
926
|
+
static VALUE ruby_eval_tree_begin_getter(ID id, void * data, struct global_entry * entry)
|
|
927
|
+
{
|
|
928
|
+
if(rb_safe_level() >= 4)
|
|
929
|
+
{
|
|
930
|
+
/* no access to potentially sensitive data from the sandbox */
|
|
931
|
+
rb_raise(rb_eSecurityError, "Insecure: can't get eval tree");
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
if(ruby_eval_tree_begin)
|
|
935
|
+
{
|
|
936
|
+
return wrap_node(ruby_eval_tree_begin);
|
|
937
|
+
}
|
|
938
|
+
else
|
|
939
|
+
{
|
|
940
|
+
return Qnil;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
static void ruby_eval_tree_begin_setter(VALUE val, ID id, void * data, struct global_entry * entry)
|
|
945
|
+
{
|
|
946
|
+
rb_raise(rb_eNotImpError, "ruby_eval_tree_begin_setter() not implemented");
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
static VALUE ruby_eval_tree_getter(ID id, void * data, struct global_entry * entry)
|
|
950
|
+
{
|
|
951
|
+
if(rb_safe_level() >= 4)
|
|
952
|
+
{
|
|
953
|
+
/* no access to potentially sensitive data from the sandbox */
|
|
954
|
+
rb_raise(rb_eSecurityError, "Insecure: can't get eval tree");
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
if(ruby_eval_tree)
|
|
958
|
+
{
|
|
959
|
+
return wrap_node(ruby_eval_tree);
|
|
960
|
+
}
|
|
961
|
+
else
|
|
962
|
+
{
|
|
963
|
+
return Qnil;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
static void ruby_eval_tree_setter(VALUE val, ID id, void * data, struct global_entry * entry)
|
|
968
|
+
{
|
|
969
|
+
rb_raise(rb_eNotImpError, "ruby_eval_tree_setter() not implemented");
|
|
970
|
+
}
|
|
971
|
+
#endif
|
|
972
|
+
|
|
973
|
+
#ifdef HAVE_RUBY_TOP_CREF
|
|
974
|
+
static VALUE ruby_top_cref_getter(ID id, void * data, struct global_entry * entry)
|
|
975
|
+
{
|
|
976
|
+
if(rb_safe_level() >= 4)
|
|
977
|
+
{
|
|
978
|
+
/* no access to potentially sensitive data from the sandbox */
|
|
979
|
+
rb_raise(rb_eSecurityError, "Insecure: can't get top cref");
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
if(ruby_eval_tree_begin)
|
|
983
|
+
{
|
|
984
|
+
return wrap_node(ruby_eval_tree_begin);
|
|
985
|
+
}
|
|
986
|
+
else
|
|
987
|
+
{
|
|
988
|
+
return Qnil;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
static void ruby_top_cref_setter(VALUE val, ID id, void * data, struct global_entry * entry)
|
|
993
|
+
{
|
|
994
|
+
if(rb_safe_level() >= 2)
|
|
995
|
+
{
|
|
996
|
+
rb_raise(rb_eSecurityError, "Insecure: can't set top cref");
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
ruby_top_cref = unwrap_node(val);
|
|
1000
|
+
}
|
|
1001
|
+
#endif
|
|
1002
|
+
|
|
1003
|
+
#ifdef HAVE_RUBY_CREF
|
|
1004
|
+
static VALUE ruby_cref_getter(ID id, void * data, struct global_entry * entry)
|
|
1005
|
+
{
|
|
1006
|
+
if(rb_safe_level() >= 4)
|
|
1007
|
+
{
|
|
1008
|
+
/* no access to potentially sensitive data from the sandbox */
|
|
1009
|
+
rb_raise(rb_eSecurityError, "Insecure: can't get current cref");
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
if(ruby_cref)
|
|
1013
|
+
{
|
|
1014
|
+
return wrap_node(ruby_cref);
|
|
1015
|
+
}
|
|
1016
|
+
else
|
|
1017
|
+
{
|
|
1018
|
+
return Qnil;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
static void ruby_cref_setter(VALUE val, ID id, void * data, struct global_entry * entry)
|
|
1023
|
+
{
|
|
1024
|
+
if(rb_safe_level() >= 2)
|
|
1025
|
+
{
|
|
1026
|
+
rb_raise(rb_eSecurityError, "Insecure: can't set current cref");
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
ruby_cref = unwrap_node(val);
|
|
1030
|
+
}
|
|
1031
|
+
#endif
|
|
1032
|
+
|
|
1033
|
+
/* ---------------------------------------------------------------------
|
|
1034
|
+
* Initialization
|
|
1035
|
+
* ---------------------------------------------------------------------
|
|
1036
|
+
*/
|
|
1037
|
+
|
|
1038
|
+
void Init_node(void)
|
|
1039
|
+
{
|
|
1040
|
+
/* This needs to be defined before we require any other files, because
|
|
1041
|
+
* we have a circular dependency.
|
|
1042
|
+
* (node.so depends on iseq.so depends on module.so depends on
|
|
1043
|
+
* node.so)
|
|
1044
|
+
*/
|
|
1045
|
+
rb_cNode = rb_define_class("Node", rb_cObject);
|
|
1046
|
+
|
|
1047
|
+
#ifdef RUBY_VM
|
|
1048
|
+
rb_require("internal/vm/iseq");
|
|
1049
|
+
#endif
|
|
1050
|
+
|
|
1051
|
+
{
|
|
1052
|
+
int actual_ruby_version_code = 0;
|
|
1053
|
+
VALUE ruby_version_str = rb_const_get(rb_cObject, rb_intern("RUBY_VERSION"));
|
|
1054
|
+
char const * s = STR2CSTR(ruby_version_str);
|
|
1055
|
+
|
|
1056
|
+
for(; *s != '\0'; ++s)
|
|
1057
|
+
{
|
|
1058
|
+
if(isdigit(*s))
|
|
1059
|
+
{
|
|
1060
|
+
actual_ruby_version_code *= 10;
|
|
1061
|
+
actual_ruby_version_code += *s - '0';
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
if(actual_ruby_version_code != RUBY_VERSION_CODE)
|
|
1066
|
+
{
|
|
1067
|
+
rb_raise(
|
|
1068
|
+
rb_eRuntimeError,
|
|
1069
|
+
"This version of Ruby/Internal was built with a different "
|
|
1070
|
+
"version of ruby (built with %d, running on %d)",
|
|
1071
|
+
RUBY_VERSION_CODE,
|
|
1072
|
+
actual_ruby_version_code);
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
|
|
1077
|
+
rb_define_alloc_func(rb_cNode, node_allocate);
|
|
1078
|
+
#endif
|
|
1079
|
+
|
|
1080
|
+
rb_define_method(rb_cNode, "address", node_address, 0);
|
|
1081
|
+
rb_define_method(rb_cNode, "flags", node_flags, 0);
|
|
1082
|
+
rb_define_method(rb_cNode, "nd_file", node_nd_file, 0);
|
|
1083
|
+
rb_define_method(rb_cNode, "nd_line", node_nd_line, 0);
|
|
1084
|
+
rb_define_method(rb_cNode, "nd_type", node_nd_type, 0);
|
|
1085
|
+
rb_define_method(rb_cNode, "members", node_members, 0);
|
|
1086
|
+
rb_define_method(rb_cNode, "eval", node_eval, -1);
|
|
1087
|
+
rb_define_method(rb_cNode, "[]", node_bracket, 1);
|
|
1088
|
+
rb_define_method(rb_cNode, "inspect", node_inspect, 0);
|
|
1089
|
+
rb_define_singleton_method(rb_cNode, "type", node_s_type, 0);
|
|
1090
|
+
|
|
1091
|
+
rb_define_singleton_method(rb_cNode, "compile_string", node_compile_string, -1);
|
|
1092
|
+
#ifdef RUBY_VM
|
|
1093
|
+
rb_define_method(rb_cNode, "bytecode_compile", node_bytecode_compile, -1);
|
|
1094
|
+
#endif
|
|
1095
|
+
rb_define_method(rb_cNode, "_dump", node_dump, 1);
|
|
1096
|
+
rb_define_singleton_method(rb_cNode, "_load", node_load, 1);
|
|
1097
|
+
|
|
1098
|
+
/* TODO: undefine swap for types that are "unsafe" to swap */
|
|
1099
|
+
rb_define_method(rb_cNode, "swap", node_swap, 1);
|
|
1100
|
+
|
|
1101
|
+
define_node_subclass_methods();
|
|
1102
|
+
|
|
1103
|
+
/* For rdoc: rb_cNodeType = rb_define_class("NodeType", rb_cObject) */
|
|
1104
|
+
rb_cNodeType = rb_funcall(
|
|
1105
|
+
rb_cStruct,
|
|
1106
|
+
rb_intern("new"),
|
|
1107
|
+
2,
|
|
1108
|
+
ID2SYM(rb_intern("name")),
|
|
1109
|
+
ID2SYM(rb_intern("value")));
|
|
1110
|
+
rb_const_set(rb_cNode, rb_intern("Type"), rb_cNodeType);
|
|
1111
|
+
rb_define_method(rb_cNodeType, "to_s", node_type_to_s, 0);
|
|
1112
|
+
rb_define_method(rb_cNodeType, "to_i", node_type_to_i, 0);
|
|
1113
|
+
|
|
1114
|
+
rb_mMarshal = rb_const_get(rb_cObject, rb_intern("Marshal"));
|
|
1115
|
+
|
|
1116
|
+
wrapped_nodes = rb_hash_new();
|
|
1117
|
+
|
|
1118
|
+
rb_global_variable(&wrapped_nodes);
|
|
1119
|
+
rb_set_end_proc(wrapped_nodes_end_proc, Qnil);
|
|
1120
|
+
|
|
1121
|
+
#ifndef RUBY_VM
|
|
1122
|
+
rb_define_virtual_variable(
|
|
1123
|
+
"$ruby_eval_tree_begin",
|
|
1124
|
+
ruby_eval_tree_begin_getter,
|
|
1125
|
+
ruby_eval_tree_begin_setter);
|
|
1126
|
+
|
|
1127
|
+
rb_define_virtual_variable(
|
|
1128
|
+
"$ruby_eval_tree",
|
|
1129
|
+
ruby_eval_tree_getter,
|
|
1130
|
+
ruby_eval_tree_setter);
|
|
1131
|
+
#endif
|
|
1132
|
+
|
|
1133
|
+
#ifdef HAVE_RUBY_TOP_CREF
|
|
1134
|
+
rb_define_virtual_variable(
|
|
1135
|
+
"$ruby_top_cref",
|
|
1136
|
+
ruby_top_cref_getter,
|
|
1137
|
+
ruby_top_cref_setter);
|
|
1138
|
+
#endif
|
|
1139
|
+
|
|
1140
|
+
#ifdef HAVE_RUBY_CREF
|
|
1141
|
+
rb_define_virtual_variable(
|
|
1142
|
+
"$ruby_cref",
|
|
1143
|
+
ruby_cref_getter,
|
|
1144
|
+
ruby_cref_setter);
|
|
1145
|
+
#endif
|
|
1146
|
+
}
|
|
1147
|
+
|