parsetree19 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +21 -0
- data/NEWS +5 -0
- data/README.md +34 -1
- data/Rakefile +43 -94
- data/ext/add_to_parse_tree.inc +14 -0
- data/ext/parse_tree.c +4 -6
- data/include/vm_core_mini.h +8 -8
- metadata +4 -4
data/ChangeLog
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
2011-06-08 r <rocky@gnu.org>
|
2
|
+
|
3
|
+
* ext/add_to_parse_tree.inc: Add NODE_BLOCK and NODE_BLOCK_ARG.
|
4
|
+
|
5
|
+
2011-06-08 r <rocky@gnu.org>
|
6
|
+
|
7
|
+
* ext/parse_tree.c: Guard against dereferencing NULL iseq pointer.
|
8
|
+
|
9
|
+
2010-12-28 r <rocky@gnu.org>
|
10
|
+
|
11
|
+
* .gemspec, Rakefile, ext/parse_tree.c: Add .gemspec. bump version
|
12
|
+
number.
|
13
|
+
|
14
|
+
2010-12-25 rocky <rockyb@rubyforge.org>
|
15
|
+
|
16
|
+
* README.md: Update README.md
|
17
|
+
|
18
|
+
2010-12-25 rocky <rockyb@rubyforge.org>
|
19
|
+
|
20
|
+
* ChangeLog: See above.
|
21
|
+
|
1
22
|
2010-12-25 rocky <rockyb@rubyforge.org>
|
2
23
|
|
3
24
|
* ChangeLog: Update README.md to include usage.
|
data/NEWS
CHANGED
data/README.md
CHANGED
@@ -5,4 +5,37 @@ A C extension to support ParseTree in Ruby 1.9
|
|
5
5
|
## Requirements
|
6
6
|
|
7
7
|
A patched version of Ruby 1.9.2 is needed. In fact the same patched version
|
8
|
-
as needed by rb-threadframe (and thus
|
8
|
+
as needed by rb-threadframe (and thus trepanning).
|
9
|
+
|
10
|
+
Usage:
|
11
|
+
|
12
|
+
require 'parse_tree'
|
13
|
+
processor = ParseTree19.new(false)
|
14
|
+
processor.parse_tree_for_str('x=1; y=2', '(string'), 1)
|
15
|
+
=> [:scope, [:block, [:lasgn, :x, [:lit, 1]], [:block, [:lasgn, :y, [:lit, 2]]]]]
|
16
|
+
def five; 5 end
|
17
|
+
processor.parse_tree_for_method(method(:five), true)
|
18
|
+
=> [:scope, [:args, 0, [:args_aux]], [:lit, 5]]
|
19
|
+
puts processor.parse_tree_for_method(method(:five, false)
|
20
|
+
=> nil
|
21
|
+
###########################################################
|
22
|
+
## Do NOT use this node dump for any purpose other than ##
|
23
|
+
## debug and research. Compatibility is not guaranteed. ##
|
24
|
+
###########################################################
|
25
|
+
|
26
|
+
# @ NODE_SCOPE (line: 6)
|
27
|
+
# +- nd_tbl: (empty)
|
28
|
+
# +- nd_args:
|
29
|
+
# | @ NODE_ARGS (line: 6)
|
30
|
+
# | +- nd_frml: 0
|
31
|
+
# | +- nd_next:
|
32
|
+
# | | @ NODE_ARGS_AUX (line: 6)
|
33
|
+
# | | +- nd_rest: (null)
|
34
|
+
# | | +- nd_body: (null)
|
35
|
+
# | | +- nd_next:
|
36
|
+
# | | (null node)
|
37
|
+
# | +- nd_opt:
|
38
|
+
# | (null node)
|
39
|
+
# +- nd_body:
|
40
|
+
# @ NODE_LIT (line: 6)
|
41
|
+
# +- nd_lit: 5
|
data/Rakefile
CHANGED
@@ -1,30 +1,34 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
2
|
# -*- Ruby -*-
|
3
3
|
require 'rubygems'
|
4
|
+
|
5
|
+
ROOT_DIR = File.dirname(__FILE__)
|
6
|
+
def gemspec
|
7
|
+
@gemspec ||= eval(File.read('.gemspec'), binding, '.gemspec')
|
8
|
+
end
|
9
|
+
|
4
10
|
require 'rake/gempackagetask'
|
5
|
-
|
6
|
-
|
11
|
+
desc "Build the gem"
|
12
|
+
task :package=>:gem
|
13
|
+
task :gem=>:gemspec do
|
14
|
+
Dir.chdir(ROOT_DIR) do
|
15
|
+
sh "gem build .gemspec"
|
16
|
+
FileUtils.mkdir_p 'pkg'
|
17
|
+
FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
|
18
|
+
end
|
19
|
+
end
|
7
20
|
|
8
|
-
|
21
|
+
desc "Install the gem locally"
|
22
|
+
task :install => :gem do
|
23
|
+
Dir.chdir(ROOT_DIR) do
|
24
|
+
sh %{gem install --local pkg/#{gemspec.name}-#{gemspec.version}}
|
25
|
+
end
|
26
|
+
end
|
9
27
|
|
10
28
|
require 'rbconfig'
|
11
29
|
RUBY_PATH = File.join(Config::CONFIG['bindir'],
|
12
30
|
Config::CONFIG['RUBY_INSTALL_NAME'])
|
13
31
|
|
14
|
-
SO_NAME = 'parsetree19.so'
|
15
|
-
|
16
|
-
PACKAGE_VERSION = open("ext/parse_tree.c") do |f|
|
17
|
-
f.grep(/^#define PARSETREE19_VERSION/).first[/"(.+)"/,1]
|
18
|
-
end
|
19
|
-
|
20
|
-
EXT_FILES = FileList[%w(ext/*.c ext/*.h ext/*.inc)]
|
21
|
-
INCLUDE_FILES = FileList['include/*.h']
|
22
|
-
LIB_FILES = FileList['lib/*.rb']
|
23
|
-
TEST_FILES = FileList['test/*/*.rb']
|
24
|
-
COMMON_FILES = FileList[%w(README.md Rakefile NEWS ChangeLog)]
|
25
|
-
ALL_FILES = COMMON_FILES + INCLUDE_FILES + LIB_FILES + EXT_FILES +
|
26
|
-
TEST_FILES
|
27
|
-
|
28
32
|
desc 'Create the core thread-frame shared library extension'
|
29
33
|
task :ext do
|
30
34
|
Dir.chdir('ext') do
|
@@ -54,13 +58,12 @@ def run_standalone_ruby_file(directory)
|
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
57
|
-
desc
|
61
|
+
desc 'Create a GNU-style ChangeLog via git2cl'
|
58
62
|
task :ChangeLog do
|
59
|
-
system(
|
63
|
+
system('git log --pretty --numstat --summary | git2cl > ChangeLog')
|
60
64
|
end
|
61
65
|
|
62
|
-
|
63
|
-
|
66
|
+
require 'rake/testtask'
|
64
67
|
desc 'Test units - the smaller tests'
|
65
68
|
Rake::TestTask.new(:'test:unit') do |t|
|
66
69
|
t.libs << './ext'
|
@@ -70,89 +73,35 @@ Rake::TestTask.new(:'test:unit') do |t|
|
|
70
73
|
end
|
71
74
|
task :'test:unit' => [:ext]
|
72
75
|
|
73
|
-
desc 'Test everything - unit tests for now.'
|
74
|
-
task :test do
|
75
|
-
exceptions = ['test:unit'].collect do |task|
|
76
|
-
begin
|
77
|
-
Rake::Task[task].invoke
|
78
|
-
nil
|
79
|
-
rescue => e
|
80
|
-
e
|
81
|
-
end
|
82
|
-
end.compact
|
83
|
-
|
84
|
-
exceptions.each {|e| puts e;puts e.backtrace }
|
85
|
-
raise "Test failures" unless exceptions.empty?
|
86
|
-
end
|
87
|
-
|
88
76
|
desc "Test everything - same as test."
|
89
77
|
|
90
78
|
task :'check' do
|
91
|
-
run_standalone_ruby_file(File.join(%W(#{
|
79
|
+
run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} test unit)))
|
92
80
|
end
|
93
81
|
|
82
|
+
task :default => [:test]
|
83
|
+
task :test => [:'test:unit']
|
84
|
+
|
85
|
+
desc "Generate the gemspec"
|
86
|
+
task :generate do
|
87
|
+
puts gemspec.to_ruby
|
88
|
+
end
|
89
|
+
|
90
|
+
desc "Validate the gemspec"
|
91
|
+
task :gemspec do
|
92
|
+
gemspec.validate
|
93
|
+
end
|
94
|
+
|
95
|
+
|
94
96
|
# --------- RDoc Documentation ------
|
97
|
+
require 'rake/rdoctask'
|
95
98
|
desc 'Generate rdoc documentation'
|
96
99
|
Rake::RDocTask.new('rdoc') do |rdoc|
|
97
|
-
rdoc.rdoc_dir = 'doc
|
98
|
-
rdoc.title =
|
100
|
+
rdoc.rdoc_dir = 'doc'
|
101
|
+
rdoc.title = "ParseTree Documentation"
|
99
102
|
# Show source inline with line numbers
|
100
103
|
rdoc.options << '--inline-source' << '--line-numbers'
|
101
104
|
# Make the readme file the start page for the generated html
|
102
105
|
rdoc.options << '--main' << 'README.md'
|
103
|
-
rdoc.rdoc_files.include(
|
104
|
-
'README.md')
|
105
|
-
end
|
106
|
-
|
107
|
-
# Base GEM Specification
|
108
|
-
spec = Gem::Specification.new do |spec|
|
109
|
-
spec.name = "parsetree19"
|
110
|
-
|
111
|
-
spec.homepage = "http://github.com/rocky/rb-parsetree19/tree/master"
|
112
|
-
spec.summary = "Frame introspection"
|
113
|
-
spec.description = <<-EOF
|
114
|
-
|
115
|
-
rb-parsetree is the C extension part of ParseTree for Ruby 1.9.
|
116
|
-
EOF
|
117
|
-
|
118
|
-
spec.version = PACKAGE_VERSION
|
119
|
-
spec.require_path = 'lib'
|
120
|
-
spec.extensions = ["ext/extconf.rb"]
|
121
|
-
|
122
|
-
spec.author = "R. Bernstein"
|
123
|
-
spec.email = "rockyb@rubyforge.org"
|
124
|
-
spec.platform = Gem::Platform::RUBY
|
125
|
-
spec.files = ALL_FILES.to_a
|
126
|
-
|
127
|
-
spec.required_ruby_version = '~> 1.9.2frame'
|
128
|
-
spec.date = Time.now
|
129
|
-
# spec.rubyforge_project = 'rocky-hacks'
|
130
|
-
|
131
|
-
# rdoc
|
132
|
-
spec.has_rdoc = true
|
133
|
-
spec.extra_rdoc_files = ['README.md'] + FileList['ext/*.c']
|
134
|
-
end
|
135
|
-
|
136
|
-
# Rake task to build the default package
|
137
|
-
Rake::GemPackageTask.new(spec) do |pkg|
|
138
|
-
pkg.need_tar = true
|
139
|
-
end
|
140
|
-
|
141
|
-
def install(spec, *opts)
|
142
|
-
args = ['gem', 'install', "pkg/#{spec.name}-#{spec.version}.gem"] + opts
|
143
|
-
system(*args)
|
106
|
+
rdoc.rdoc_files.include(%w(ext/**/*.c README.md))
|
144
107
|
end
|
145
|
-
|
146
|
-
desc 'Install locally'
|
147
|
-
task :install => :package do
|
148
|
-
Dir.chdir(File::dirname(__FILE__)) do
|
149
|
-
# ri and rdoc take lots of time
|
150
|
-
install(spec, '--no-ri', '--no-rdoc')
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
task :install_full => :package do
|
155
|
-
Dir.chdir(File::dirname(__FILE__)) do
|
156
|
-
install(spec)
|
157
|
-
end
|
158
|
-
end
|
data/ext/add_to_parse_tree.inc
CHANGED
@@ -899,6 +899,20 @@ add_to_parse_tree(VALUE self, VALUE ary, NODE *node, ID *locals)
|
|
899
899
|
F_NODE(nd_body, "body");
|
900
900
|
break;
|
901
901
|
|
902
|
+
case NODE_MEMO:
|
903
|
+
ANN("NODE MEMO");
|
904
|
+
ANN("format: filename, safe_level, 0");
|
905
|
+
rb_aray_push(current, node->u1.value);
|
906
|
+
rb_aray_push(current, node->u2.value);
|
907
|
+
rb_aray_push(current, node->u3.value);
|
908
|
+
break;
|
909
|
+
|
910
|
+
case NODE_BLOCK_ARG:
|
911
|
+
ANN("NODE BLOCK ARG");
|
912
|
+
ANN("format: v 0, local_cnt(v)");
|
913
|
+
F_NODE(nd_head, "v");
|
914
|
+
break;
|
915
|
+
|
902
916
|
default:
|
903
917
|
rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node)));
|
904
918
|
}
|
data/ext/parse_tree.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/* What release we got? */
|
2
|
-
#define PARSETREE19_VERSION "0.
|
2
|
+
#define PARSETREE19_VERSION "0.3"
|
3
3
|
#include "../include/vm_core_mini.h" /* Pulls in ruby.h and node.h */
|
4
4
|
#include "../include/ruby19_externs.h"
|
5
5
|
|
@@ -49,7 +49,7 @@ parse_tree_for_iseq_internal(VALUE self, rb_iseq_t *iseq, VALUE tree)
|
|
49
49
|
{
|
50
50
|
VALUE result = rb_ary_new();
|
51
51
|
|
52
|
-
if (iseq->tree_node) {
|
52
|
+
if (iseq && iseq->tree_node) {
|
53
53
|
if (Qfalse == tree)
|
54
54
|
result = rb_parser_dump_tree(iseq->tree_node, 0);
|
55
55
|
else
|
@@ -63,10 +63,9 @@ static VALUE
|
|
63
63
|
parse_tree_for_iseq(VALUE self, VALUE iseqval, VALUE tree)
|
64
64
|
{
|
65
65
|
rb_iseq_t *iseq;
|
66
|
-
VALUE result = rb_ary_new();
|
67
66
|
|
68
67
|
GetISeqPtr(iseqval, iseq);
|
69
|
-
parse_tree_for_iseq_internal(self, iseq, tree);
|
68
|
+
return parse_tree_for_iseq_internal(self, iseq, tree);
|
70
69
|
}
|
71
70
|
|
72
71
|
/* Defined in Ruby 1.9 proc.c */
|
@@ -76,7 +75,7 @@ static VALUE
|
|
76
75
|
parse_tree_for_method(VALUE self, VALUE method, VALUE tree)
|
77
76
|
{
|
78
77
|
rb_iseq_t *iseq = rb_method_get_iseq(method);
|
79
|
-
parse_tree_for_iseq_internal(self, iseq, tree);
|
78
|
+
return parse_tree_for_iseq_internal(self, iseq, tree);
|
80
79
|
}
|
81
80
|
|
82
81
|
static VALUE
|
@@ -84,7 +83,6 @@ parse_tree_common(VALUE self, VALUE source, VALUE filename, VALUE line,
|
|
84
83
|
VALUE tree)
|
85
84
|
{
|
86
85
|
VALUE tmp;
|
87
|
-
VALUE result = rb_ary_new();
|
88
86
|
NODE *node = NULL;
|
89
87
|
|
90
88
|
#ifdef FIXED
|
data/include/vm_core_mini.h
CHANGED
@@ -94,13 +94,13 @@ typedef struct rb_iseq_struct {
|
|
94
94
|
/***************/
|
95
95
|
|
96
96
|
VALUE type; /* instruction sequence type */
|
97
|
-
VALUE name;
|
97
|
+
VALUE name; /* String: iseq name */
|
98
98
|
VALUE filename; /* file information where this sequence from */
|
99
99
|
VALUE filepath; /* real file path or nil */
|
100
100
|
VALUE *iseq; /* iseq (insn number and operands) */
|
101
101
|
VALUE *iseq_encoded; /* encoded iseq */
|
102
102
|
unsigned long iseq_size;
|
103
|
-
VALUE mark_ary;
|
103
|
+
VALUE mark_ary; /* Array: includes operands which should be GC marked */
|
104
104
|
VALUE coverage; /* coverage array */
|
105
105
|
unsigned short line_no;
|
106
106
|
|
@@ -108,7 +108,7 @@ typedef struct rb_iseq_struct {
|
|
108
108
|
struct iseq_insn_info_entry *insn_info_table;
|
109
109
|
size_t insn_info_size;
|
110
110
|
|
111
|
-
ID *local_table;
|
111
|
+
ID *local_table; /* must free */
|
112
112
|
int local_table_size;
|
113
113
|
|
114
114
|
/* method, class frame: sizeof(vars) + 1, block frame: sizeof(vars) */
|
@@ -165,7 +165,7 @@ typedef struct rb_iseq_struct {
|
|
165
165
|
/****************/
|
166
166
|
|
167
167
|
VALUE self;
|
168
|
-
VALUE orig;
|
168
|
+
VALUE orig; /* non-NULL if its data have origin */
|
169
169
|
|
170
170
|
/* block inlining */
|
171
171
|
/*
|
@@ -189,7 +189,7 @@ typedef struct rb_iseq_struct {
|
|
189
189
|
|
190
190
|
/* If this instruction sequence came from eval, the string of the
|
191
191
|
source as a String. */
|
192
|
-
VALUE
|
192
|
+
VALUE eval_source;
|
193
193
|
|
194
194
|
/* If we are saving tree nodes (a compile option), then tree_node
|
195
195
|
is the internal parse tree node representation for this
|
@@ -234,8 +234,8 @@ typedef struct rb_vm_struct {
|
|
234
234
|
|
235
235
|
/* signal */
|
236
236
|
struct {
|
237
|
-
|
238
|
-
|
237
|
+
VALUE cmd;
|
238
|
+
int safe;
|
239
239
|
} trap_list[RUBY_NSIG];
|
240
240
|
|
241
241
|
/* hook */
|
@@ -308,8 +308,8 @@ typedef struct rb_thread_struct
|
|
308
308
|
rb_event_flag_t event_flags;
|
309
309
|
int tracing; /* 0 if not tracing. If less than 0, skip that many
|
310
310
|
C call/return pairs */
|
311
|
+
|
311
312
|
int exec_event_tracing; /* 0 if not in rb_threadptr_evec_event_hooks. */
|
312
|
-
int trace_skip_insn_count; /* # of VM instructions to skip */
|
313
313
|
|
314
314
|
/* misc */
|
315
315
|
int method_missing_reason;
|
metadata
CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
version: "0.
|
7
|
+
- 3
|
8
|
+
version: "0.3"
|
9
9
|
platform: ruby
|
10
10
|
authors:
|
11
11
|
- R. Bernstein
|
@@ -13,12 +13,12 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date:
|
16
|
+
date: 2011-06-12 00:00:00 -04:00
|
17
17
|
default_executable:
|
18
18
|
dependencies: []
|
19
19
|
|
20
20
|
description: "\n\
|
21
|
-
rb-parsetree is the C extension part of ParseTree for Ruby 1.9.\n"
|
21
|
+
rb-parsetree is the C extension part of ParseTree for Ruby 1.9. A patched version of Ruby 1.9.2 is required.\n"
|
22
22
|
email: rockyb@rubyforge.org
|
23
23
|
executables: []
|
24
24
|
|