rubinius-compiler 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -0
  3. data/lib/rubinius/compiler/compiled_file.rb +32 -32
  4. data/lib/rubinius/compiler/version.rb +2 -2
  5. data/rubinius-compiler.gemspec +6 -0
  6. data/spec/alias_spec.rb +39 -0
  7. data/spec/and_spec.rb +44 -0
  8. data/spec/array_spec.rb +110 -0
  9. data/spec/attrasgn_spec.rb +186 -0
  10. data/spec/back_ref_spec.rb +11 -0
  11. data/spec/call_spec.rb +580 -0
  12. data/spec/case_spec.rb +576 -0
  13. data/spec/cdecl_spec.rb +70 -0
  14. data/spec/class_spec.rb +120 -0
  15. data/spec/colon2_spec.rb +8 -0
  16. data/spec/colon3_spec.rb +8 -0
  17. data/spec/const_spec.rb +7 -0
  18. data/spec/custom/guards/profiler.rb +18 -0
  19. data/spec/custom/helpers/generator.rb +828 -0
  20. data/spec/custom/matchers/compile_as.rb +46 -0
  21. data/spec/custom/mspec.rb +15 -0
  22. data/spec/custom/runner/actions/debug.rb +10 -0
  23. data/spec/custom/runner/actions/gcstats.rb +17 -0
  24. data/spec/custom/runner/actions/memory.rb +11 -0
  25. data/spec/custom/runner/actions/parser.rb +14 -0
  26. data/spec/custom/runner/actions/profiler.rb +19 -0
  27. data/spec/custom/runner/relates.rb +86 -0
  28. data/spec/custom/utils/options.rb +40 -0
  29. data/spec/custom/utils/script.rb +50 -0
  30. data/spec/cvar_spec.rb +39 -0
  31. data/spec/cvasgn_spec.rb +33 -0
  32. data/spec/cvdecl_spec.rb +17 -0
  33. data/spec/defined_spec.rb +616 -0
  34. data/spec/defn_spec.rb +732 -0
  35. data/spec/defs_spec.rb +113 -0
  36. data/spec/dot2_spec.rb +16 -0
  37. data/spec/dot3_spec.rb +17 -0
  38. data/spec/dregx_spec.rb +160 -0
  39. data/spec/dstr_spec.rb +424 -0
  40. data/spec/dsym_spec.rb +18 -0
  41. data/spec/dxstr_spec.rb +24 -0
  42. data/spec/ensure_spec.rb +196 -0
  43. data/spec/false_spec.rb +7 -0
  44. data/spec/flip2_spec.rb +21 -0
  45. data/spec/flip3_spec.rb +12 -0
  46. data/spec/for_spec.rb +228 -0
  47. data/spec/gasgn_spec.rb +15 -0
  48. data/spec/generator/encode_spec.rb +34 -0
  49. data/spec/gvar_spec.rb +37 -0
  50. data/spec/hash_spec.rb +108 -0
  51. data/spec/iasgn_spec.rb +26 -0
  52. data/spec/if_spec.rb +415 -0
  53. data/spec/iter_spec.rb +1011 -0
  54. data/spec/lasgn_spec.rb +561 -0
  55. data/spec/lit_spec.rb +61 -0
  56. data/spec/masgn_spec.rb +1558 -0
  57. data/spec/match2_spec.rb +42 -0
  58. data/spec/match3_spec.rb +54 -0
  59. data/spec/match_spec.rb +29 -0
  60. data/spec/module_spec.rb +73 -0
  61. data/spec/nil_spec.rb +7 -0
  62. data/spec/not_spec.rb +47 -0
  63. data/spec/nth_ref_spec.rb +7 -0
  64. data/spec/op_asgn_spec.rb +563 -0
  65. data/spec/or_spec.rb +126 -0
  66. data/spec/postexe_spec.rb +11 -0
  67. data/spec/preexe_spec.rb +21 -0
  68. data/spec/regex_spec.rb +54 -0
  69. data/spec/rescue_spec.rb +763 -0
  70. data/spec/return_spec.rb +152 -0
  71. data/spec/sclass_spec.rb +138 -0
  72. data/spec/spec_helper.rb +12 -0
  73. data/spec/str_spec.rb +118 -0
  74. data/spec/super_spec.rb +170 -0
  75. data/spec/transforms/assembly_spec.rb +195 -0
  76. data/spec/transforms/block_given_spec.rb +75 -0
  77. data/spec/transforms/fast_coerce_spec.rb +112 -0
  78. data/spec/transforms/fast_new_spec.rb +255 -0
  79. data/spec/transforms/invoke_primitive_spec.rb +14 -0
  80. data/spec/transforms/kernel_methods_spec.rb +29 -0
  81. data/spec/transforms/primitive_spec.rb +33 -0
  82. data/spec/transforms/privately_spec.rb +24 -0
  83. data/spec/true_spec.rb +7 -0
  84. data/spec/undef_spec.rb +133 -0
  85. data/spec/until_spec.rb +254 -0
  86. data/spec/valias_spec.rb +11 -0
  87. data/spec/while_spec.rb +494 -0
  88. data/spec/xstr_spec.rb +10 -0
  89. data/spec/yield_spec.rb +92 -0
  90. data/spec/zsuper_spec.rb +63 -0
  91. metadata +258 -3
@@ -0,0 +1,46 @@
1
+ require 'spec/custom/helpers/generator'
2
+
3
+ # The CompileAsMatcher wraps the logic for checking that a string of Ruby code
4
+ # is converted to the expected bytecode. It is combined with the #compile_as
5
+ # spec helper and enables specs of the form:
6
+ #
7
+ # "a = 1".should compile_as(<some bytecode>)
8
+ #
9
+ class CompileAsMatcher
10
+ def initialize(expected, plugins)
11
+ @expected = expected
12
+ @plugins = plugins
13
+ end
14
+
15
+ def matches?(actual)
16
+ @actual = Rubinius::ToolSets::Spec::Compiler.compile_test_bytecode actual, @plugins
17
+ @actual == @expected
18
+ end
19
+
20
+ def diff(actual, expected)
21
+ actual = actual.pretty_inspect.each_line.to_a
22
+ expected = expected.pretty_inspect.each_line.to_a
23
+
24
+ line = actual.each_with_index do |item, index|
25
+ break index unless item == expected[index]
26
+ end
27
+
28
+ /^( +)/ =~ actual[line]
29
+ marker = "#{' ' * $1.size if $1}^ differs\n\n"
30
+ actual.insert line+1, marker
31
+ expected.insert line+1, marker
32
+
33
+ return actual.join, expected.join
34
+ end
35
+
36
+ def failure_message
37
+ actual, expected = diff @actual, @expected
38
+ ["Expected:\n#{actual}\n", "to equal:\n#{expected}"]
39
+ end
40
+ end
41
+
42
+ class Object
43
+ def compile_as(bytecode, *plugins)
44
+ CompileAsMatcher.new bytecode, plugins
45
+ end
46
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec/custom/utils/options'
2
+
3
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
4
+ require 'spec/custom/matchers/compile_as'
5
+ require 'spec/custom/helpers/generator'
6
+ require 'spec/custom/guards/profiler'
7
+ require 'spec/custom/runner/relates'
8
+ require 'spec/custom/runner/actions/debug'
9
+ require 'spec/custom/runner/actions/gcstats'
10
+ require 'spec/custom/runner/actions/memory'
11
+ require 'spec/custom/runner/actions/parser'
12
+ require 'spec/custom/runner/actions/profiler'
13
+ end
14
+
15
+ require 'spec/custom/utils/script'
@@ -0,0 +1,10 @@
1
+ class DebugAction < ActionFilter
2
+ def initialize(tags=nil, descs=nil)
3
+ super
4
+ require 'rubinius/debugger'
5
+ end
6
+
7
+ def before(state)
8
+ Rubinius::Debugger.start if self === state.description
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ # Custom MSpec action that prints GC stats after a spec run
2
+ #
3
+ class GCStatsAction
4
+ def register
5
+ MSpec.register :start, self
6
+ MSpec.register :finish, self
7
+ end
8
+
9
+ def start
10
+ @stats = Rubinius::Stats::GC.new
11
+ @stats.clear
12
+ end
13
+
14
+ def finish
15
+ @stats.show
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ class MemoryAction
2
+ def register
3
+ MSpec.register :finish, self
4
+ end
5
+
6
+ def finish
7
+ require 'rubinius/analyst'
8
+
9
+ puts "\nTotal memory: #{Rubinius::Analyst.new.total_memory}"
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ class Parser19Action
2
+ def register
3
+ MSpec.register :load, self
4
+ MSpec.register :unload, self
5
+ end
6
+
7
+ def load
8
+ SpecGuard.ruby_version_override = "1.9.2"
9
+ end
10
+
11
+ def unload
12
+ SpecGuard.ruby_version_override = nil
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ # Custom MSpec action that prints profiler stats after a spec run
2
+ #
3
+ class ProfilerAction
4
+ def register
5
+ MSpec.register :start, self
6
+ MSpec.register :finish, self
7
+ end
8
+
9
+ def start
10
+ @profiler = Rubinius::Profiler::Instrumenter.new(
11
+ :sort => [:self_seconds, :calls])
12
+ @profiler.start
13
+ end
14
+
15
+ def finish
16
+ @profiler.stop
17
+ @profiler.show
18
+ end
19
+ end
@@ -0,0 +1,86 @@
1
+ # SpecDataRelation enables concise specs that involve several different forms
2
+ # of the same data. This is specifically useful for the parser and compiler
3
+ # specs where the output of each stage is essentially related to the input
4
+ # Ruby source. Together with the #relates spec method, it enables specs like:
5
+ #
6
+ # describe "An If node" do
7
+ # relates "a if b" do
8
+ # parse do
9
+ # # return the expected sexp
10
+ # end
11
+ #
12
+ # compile do |g|
13
+ # # return the expected bytecode
14
+ # end
15
+ #
16
+ # jit do |as|
17
+ # # return the expected asm/machine code
18
+ # end
19
+ # end
20
+ #
21
+ # relates "if a; b; end" do
22
+ # # ...
23
+ # end
24
+ # end
25
+
26
+ class SpecDataRelation
27
+ # Provides a simple configurability so that any one or more of the possible
28
+ # processes can be run. See the custom options in custom/utils/options.rb.
29
+ def self.enable(process)
30
+ @processors ||= []
31
+ @processors << process
32
+ end
33
+
34
+ # Returns true if no process is specifically set or if +process+ is in the
35
+ # list of enabled processes. In other words, all processes are enabled by
36
+ # default, or any combination of them may be enabled.
37
+ def self.enabled?(process)
38
+ @processors.nil? or @processors.include?(process)
39
+ end
40
+
41
+ def initialize(ruby)
42
+ @ruby = ruby
43
+ end
44
+
45
+ # Formats the Ruby source code for reabable output in the -fs formatter
46
+ # option. If the source contains no newline characters, wraps the source in
47
+ # single quotes to set if off from the rest of the description string. If
48
+ # the source does contain newline characters, sets the indent level to four
49
+ # characters.
50
+ def format(ruby)
51
+ if /\n/ =~ ruby
52
+ lines = ruby.rstrip.each_line.to_a
53
+ if /( *)/ =~ lines.first
54
+ if $1.size > 4
55
+ dedent = $1.size - 4
56
+ ruby = lines.map { |l| l[dedent..-1] }.join
57
+ else
58
+ indent = " " * (4 - $1.size)
59
+ ruby = lines.map { |l| "#{indent}#{l}" }.join
60
+ end
61
+ end
62
+ "\n#{ruby}"
63
+ else
64
+ "'#{ruby}'"
65
+ end
66
+ end
67
+
68
+ # Creates spec example blocks if the compile process is enabled.
69
+ def compile(*plugins, &block)
70
+ return unless self.class.enabled? :compiler
71
+
72
+ ruby = @ruby
73
+ it "is compiled from #{format ruby}" do
74
+ generator = Rubinius::TestGenerator.new
75
+ generator.instance_eval(&block)
76
+
77
+ ruby.should compile_as(generator, *plugins)
78
+ end
79
+ end
80
+ end
81
+
82
+ class Object
83
+ def relates(str, &block)
84
+ SpecDataRelation.new(str).instance_eval(&block)
85
+ end
86
+ end
@@ -0,0 +1,40 @@
1
+ # Custom MSpec options
2
+ #
3
+ class MSpecOptions
4
+ def compiler
5
+ on("--compiler", "Run only the compile part of the compiler specs") do
6
+ SpecDataRelation.enable :compiler
7
+ end
8
+ end
9
+
10
+ def parser_19
11
+ on("--parser-1.9", "Run the compiler specs with the 1.9 parser") do
12
+ require 'spec/custom/matchers/compile_as_19'
13
+ config[:parser_19] = true
14
+ end
15
+ end
16
+
17
+ def memory
18
+ on("--memory", "Display total memory in use before exiting") do
19
+ config[:memory] = true
20
+ end
21
+ end
22
+
23
+ def gc_stats
24
+ on("--gc-stats", "Show GC stats at the end") do
25
+ config[:gc_stats] = true
26
+ end
27
+ end
28
+
29
+ def profiler
30
+ on("--profiler", "Show profiler data at the end") do
31
+ config[:profiler] = true
32
+ end
33
+ end
34
+
35
+ def agent
36
+ on("--agent", "Start the Rubinius agent") do
37
+ config[:launch] << "-Xagent.start"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,50 @@
1
+ # Registers custom actions, etc. for all MSpec scripts
2
+ #
3
+ class MSpecScript
4
+ def custom_register
5
+ GCStatsAction.new.register if config[:gc_stats]
6
+ ProfilerAction.new.register if config[:profiler]
7
+ Parser19Action.new.register if config[:parser_19]
8
+ MemoryAction.new.register if config[:memory]
9
+ end
10
+ end
11
+
12
+ # Custom options for mspec
13
+ #
14
+ class MSpecMain
15
+ def custom_options(options)
16
+ options.agent
17
+ end
18
+ end
19
+
20
+ # Custom options for mspec-run
21
+ #
22
+ class MSpecRun
23
+ def custom_options(options)
24
+ options.compiler
25
+ options.parser_19
26
+ options.memory
27
+ options.gc_stats
28
+ options.profiler
29
+ end
30
+ end
31
+
32
+ # Custom options for mspec-ci
33
+ #
34
+ class MSpecCI
35
+ def custom_options(options)
36
+ options.compiler
37
+ options.parser_19
38
+ options.memory
39
+ options.gc_stats
40
+ options.profiler
41
+ end
42
+ end
43
+
44
+ # Custom options for mspec-tag
45
+ #
46
+ class MSpecTag
47
+ def custom_options(options)
48
+ options.compiler
49
+ end
50
+ end
data/spec/cvar_spec.rb ADDED
@@ -0,0 +1,39 @@
1
+ describe "A Cvar node" do
2
+ relates "@@x" do
3
+ compile do |g|
4
+ g.push_scope
5
+ g.push_literal :@@x
6
+ g.send :class_variable_get, 1
7
+ end
8
+ end
9
+
10
+ relates <<-ruby do
11
+ class A
12
+ @@a
13
+ end
14
+ ruby
15
+
16
+ compile do |g|
17
+ in_class :A do |d|
18
+ d.push :self
19
+ d.push_literal :@@a
20
+ d.send :class_variable_get, 1
21
+ end
22
+ end
23
+ end
24
+
25
+ relates <<-ruby do
26
+ module M
27
+ @@a
28
+ end
29
+ ruby
30
+
31
+ compile do |g|
32
+ in_module :M do |d|
33
+ d.push :self
34
+ d.push_literal :@@a
35
+ d.send :class_variable_get, 1
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ describe "A Cvasgn node" do
2
+ relates <<-ruby do
3
+ def x
4
+ @@blah = 1
5
+ end
6
+ ruby
7
+
8
+ compile do |g|
9
+ in_method :x do |d|
10
+ d.push_scope
11
+ d.push_literal :@@blah
12
+ d.push 1
13
+ d.send :class_variable_set, 2
14
+ end
15
+ end
16
+ end
17
+
18
+ relates <<-ruby do
19
+ def self.quiet_mode=(boolean)
20
+ @@quiet_mode = boolean
21
+ end
22
+ ruby
23
+
24
+ compile do |g|
25
+ in_singleton_method :quiet_mode=, [:push, :self] do |d|
26
+ d.push_scope
27
+ d.push_literal :@@quiet_mode
28
+ d.push_local 0
29
+ d.send :class_variable_set, 2
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ describe "A Cvdecl node" do
2
+ relates <<-ruby do
3
+ class X
4
+ @@blah = 1
5
+ end
6
+ ruby
7
+
8
+ compile do |g|
9
+ in_class :X do |d|
10
+ d.push :self
11
+ d.push_literal :@@blah
12
+ d.push 1
13
+ d.send :class_variable_set, 2
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,616 @@
1
+ describe "A Defined node" do
2
+ relates "defined? $x" do
3
+ compile do |g|
4
+ f = g.new_label
5
+ done = g.new_label
6
+
7
+ g.push_rubinius
8
+ g.find_const :Globals
9
+ g.push_literal :$x
10
+ g.send :key?, 1
11
+ g.gif f
12
+ g.push_literal "global-variable"
13
+ g.goto done
14
+
15
+ f.set!
16
+ g.push :nil
17
+
18
+ done.set!
19
+ end
20
+ end
21
+
22
+ relates "defined? a" do
23
+ compile do |g|
24
+ f = g.new_label
25
+ done = g.new_label
26
+
27
+ g.push :self
28
+ g.push_literal :a
29
+ g.push :true
30
+ g.send :__respond_to_p__, 2
31
+ g.gif f
32
+ g.push_literal "method"
33
+ g.goto done
34
+
35
+ f.set!
36
+ g.push :nil
37
+
38
+ done.set!
39
+ end
40
+ end
41
+
42
+ relates <<-ruby do
43
+ a = 1
44
+ defined? a
45
+ ruby
46
+
47
+ compile do |g|
48
+ g.push 1
49
+ g.set_local 0
50
+ g.pop
51
+
52
+ g.push_literal "local-variable"
53
+ end
54
+ end
55
+
56
+ relates "defined? x = 1" do
57
+ compile do |g|
58
+ g.push_literal "assignment"
59
+ end
60
+ end
61
+
62
+ relates "defined? x += 1" do
63
+ compile do |g|
64
+ g.push_literal "assignment"
65
+ end
66
+ end
67
+
68
+ relates "defined? x ||= 1" do
69
+ compile do |g|
70
+ g.push_literal "assignment"
71
+ end
72
+ end
73
+
74
+ relates "defined? x &&= 1" do
75
+ compile do |g|
76
+ g.push_literal "assignment"
77
+ end
78
+ end
79
+
80
+ relates "defined? X" do
81
+ compile do |g|
82
+ g.push_exception_state
83
+ outer_exc_state = g.new_stack_local
84
+ g.set_stack_local outer_exc_state
85
+ g.pop
86
+
87
+ f = g.new_label
88
+ done = g.new_label
89
+
90
+ ex = g.new_label
91
+ ok = g.new_label
92
+ g.setup_unwind ex
93
+
94
+ g.push_literal :X
95
+ g.invoke_primitive :vm_const_defined, 1
96
+ g.pop_unwind
97
+ g.goto ok
98
+
99
+ ex.set!
100
+ g.clear_exception
101
+ g.push_stack_local outer_exc_state
102
+ g.restore_exception_state
103
+ g.goto f
104
+
105
+ ok.set!
106
+ g.pop
107
+ g.push_literal "constant"
108
+ g.goto done
109
+
110
+ f.set!
111
+ g.push :nil
112
+
113
+ done.set!
114
+ end
115
+ end
116
+
117
+ relates "defined? ::X" do
118
+ compile do |g|
119
+ g.push_exception_state
120
+ outer_exc_state = g.new_stack_local
121
+ g.set_stack_local outer_exc_state
122
+ g.pop
123
+
124
+ f = g.new_label
125
+ done = g.new_label
126
+
127
+ ex = g.new_label
128
+ ok = g.new_label
129
+ g.setup_unwind ex
130
+
131
+ g.push_cpath_top
132
+ g.push_literal :X
133
+ g.push :false
134
+ g.invoke_primitive :vm_const_defined_under, 3
135
+ g.pop_unwind
136
+ g.goto ok
137
+
138
+ ex.set!
139
+ g.clear_exception
140
+ g.push_stack_local outer_exc_state
141
+ g.restore_exception_state
142
+ g.goto f
143
+
144
+ ok.set!
145
+ g.pop
146
+ g.push_literal "constant"
147
+ g.goto done
148
+
149
+ f.set!
150
+ g.push :nil
151
+
152
+ done.set!
153
+ end
154
+ end
155
+
156
+ relates "defined? X::Y" do
157
+ compile do |g|
158
+ g.push_exception_state
159
+ outer_exc_state = g.new_stack_local
160
+ g.set_stack_local outer_exc_state
161
+ g.pop
162
+
163
+ f = g.new_label
164
+ done = g.new_label
165
+
166
+ ex = g.new_label
167
+ ok = g.new_label
168
+ g.setup_unwind ex
169
+
170
+ g.push_const :X
171
+ g.push_literal :Y
172
+ g.push :false
173
+ g.invoke_primitive :vm_const_defined_under, 3
174
+ g.pop_unwind
175
+ g.goto ok
176
+
177
+ ex.set!
178
+ g.clear_exception
179
+ g.push_stack_local outer_exc_state
180
+ g.restore_exception_state
181
+ g.goto f
182
+
183
+ ok.set!
184
+ g.pop
185
+ g.push_literal "constant"
186
+ g.goto done
187
+
188
+ f.set!
189
+ g.push :nil
190
+
191
+ done.set!
192
+ end
193
+ end
194
+
195
+ relates "defined? X::Y::Z" do
196
+ compile do |g|
197
+ g.push_exception_state
198
+ outer_exc_state = g.new_stack_local
199
+ g.set_stack_local outer_exc_state
200
+ g.pop
201
+
202
+ f = g.new_label
203
+ done = g.new_label
204
+
205
+ ex = g.new_label
206
+ ok = g.new_label
207
+ g.setup_unwind ex
208
+
209
+ g.push_const :X
210
+ g.find_const :Y
211
+ g.push_literal :Z
212
+ g.push :false
213
+ g.invoke_primitive :vm_const_defined_under, 3
214
+ g.pop_unwind
215
+ g.goto ok
216
+
217
+ ex.set!
218
+ g.clear_exception
219
+ g.push_stack_local outer_exc_state
220
+ g.restore_exception_state
221
+ g.goto f
222
+
223
+ ok.set!
224
+ g.pop
225
+ g.push_literal "constant"
226
+ g.goto done
227
+
228
+ f.set!
229
+ g.push :nil
230
+
231
+ done.set!
232
+ end
233
+ end
234
+
235
+ relates "defined? self::A" do
236
+ compile do |g|
237
+ g.push_exception_state
238
+ outer_exc_state = g.new_stack_local
239
+ g.set_stack_local outer_exc_state
240
+ g.pop
241
+
242
+ f = g.new_label
243
+ done = g.new_label
244
+
245
+ ex = g.new_label
246
+ ok = g.new_label
247
+ g.setup_unwind ex
248
+
249
+ g.push :self
250
+ g.push_literal :A
251
+ g.push :false
252
+ g.invoke_primitive :vm_const_defined_under, 3
253
+ g.pop_unwind
254
+ g.goto ok
255
+
256
+ ex.set!
257
+ g.clear_exception
258
+ g.push_stack_local outer_exc_state
259
+ g.restore_exception_state
260
+ g.goto f
261
+
262
+ ok.set!
263
+ g.pop
264
+ g.push_literal "constant"
265
+ g.goto done
266
+
267
+ f.set!
268
+ g.push :nil
269
+
270
+ done.set!
271
+ end
272
+ end
273
+
274
+ relates "defined? self" do
275
+ compile do |g|
276
+ g.push_literal "self"
277
+ end
278
+ end
279
+
280
+ relates "defined? true" do
281
+ compile do |g|
282
+ g.push_literal "true"
283
+ end
284
+ end
285
+
286
+ relates "defined? false" do
287
+ compile do |g|
288
+ g.push_literal "false"
289
+ end
290
+ end
291
+
292
+ relates "defined? nil" do
293
+ compile do |g|
294
+ g.push_literal "nil"
295
+ end
296
+ end
297
+
298
+ relates "defined? @var" do
299
+ compile do |g|
300
+ f = g.new_label
301
+ done = g.new_label
302
+
303
+ g.push :self
304
+ g.push_literal :@var
305
+ g.send :__instance_variable_defined_p__, 1
306
+ g.gif f
307
+ g.push_literal "instance-variable"
308
+ g.goto done
309
+
310
+ f.set!
311
+ g.push :nil
312
+
313
+ done.set!
314
+ end
315
+ end
316
+
317
+ relates "defined? @@var" do
318
+ compile do |g|
319
+ f = g.new_label
320
+ done = g.new_label
321
+
322
+ g.push_scope
323
+ g.push_literal :@@var
324
+ g.send :class_variable_defined?, 1
325
+ g.gif f
326
+ g.push_literal "class variable"
327
+ g.goto done
328
+
329
+ f.set!
330
+ g.push :nil
331
+
332
+ done.set!
333
+ end
334
+ end
335
+
336
+ relates "defined? :a" do
337
+ compile do |g|
338
+ g.push_literal "expression"
339
+ end
340
+ end
341
+
342
+ relates "defined? 'a'" do
343
+ compile do |g|
344
+ g.push_literal "expression"
345
+ end
346
+ end
347
+
348
+ relates "defined? 0" do
349
+ compile do |g|
350
+ g.push_literal "expression"
351
+ end
352
+ end
353
+
354
+ relates "defined? yield" do
355
+ compile do |g|
356
+ t = g.new_label
357
+ f = g.new_label
358
+
359
+ g.push_block
360
+ g.git t
361
+ g.push :nil
362
+ g.goto f
363
+
364
+ t.set!
365
+ g.push_literal "yield"
366
+
367
+ f.set!
368
+ end
369
+ end
370
+
371
+ relates "defined? A.m" do
372
+ compile do |g|
373
+ g.push_exception_state
374
+ outer_exc_state = g.new_stack_local
375
+ g.set_stack_local outer_exc_state
376
+ g.pop
377
+
378
+ f = g.new_label
379
+ done = g.new_label
380
+
381
+ ex = g.new_label
382
+ ok = g.new_label
383
+ g.setup_unwind ex
384
+
385
+ g.push_literal :A
386
+ g.invoke_primitive :vm_const_defined, 1
387
+
388
+ g.pop_unwind
389
+ g.goto ok
390
+
391
+ ex.set!
392
+ g.clear_exception
393
+ g.push_stack_local outer_exc_state
394
+ g.restore_exception_state
395
+ g.goto f
396
+
397
+ ok.set!
398
+ g.push_literal :m
399
+ g.push_self
400
+ g.invoke_primitive :vm_check_callable, 3
401
+ g.gif f
402
+ g.push_literal "method"
403
+ g.goto done
404
+
405
+ f.set!
406
+ g.push :nil
407
+
408
+ done.set!
409
+ end
410
+ end
411
+
412
+ relates "defined? ::A.m" do
413
+ compile do |g|
414
+ g.push_exception_state
415
+ outer_exc_state = g.new_stack_local
416
+ g.set_stack_local outer_exc_state
417
+ g.pop
418
+
419
+ f = g.new_label
420
+ done = g.new_label
421
+
422
+ ex = g.new_label
423
+ ok = g.new_label
424
+ g.setup_unwind ex
425
+
426
+ g.push_cpath_top
427
+ g.push_literal :A
428
+ g.push :false
429
+ g.invoke_primitive :vm_const_defined_under, 3
430
+
431
+ g.pop_unwind
432
+ g.goto ok
433
+
434
+ ex.set!
435
+ g.clear_exception
436
+ g.push_stack_local outer_exc_state
437
+ g.restore_exception_state
438
+ g.goto f
439
+
440
+ ok.set!
441
+ g.push_literal :m
442
+ g.push_self
443
+ g.invoke_primitive :vm_check_callable, 3
444
+ g.gif f
445
+ g.push_literal "method"
446
+ g.goto done
447
+
448
+ f.set!
449
+ g.push :nil
450
+
451
+ done.set!
452
+ end
453
+ end
454
+
455
+ relates "defined? A::B.m" do
456
+ compile do |g|
457
+ g.push_exception_state
458
+ outer_exc_state = g.new_stack_local
459
+ g.set_stack_local outer_exc_state
460
+ g.pop
461
+
462
+ f = g.new_label
463
+ done = g.new_label
464
+
465
+ ex = g.new_label
466
+ ok = g.new_label
467
+ g.setup_unwind ex
468
+
469
+ g.push_const :A
470
+ g.push_literal :B
471
+ g.push :true
472
+ g.invoke_primitive :vm_const_defined_under, 3
473
+
474
+ g.pop_unwind
475
+ g.goto ok
476
+
477
+ ex.set!
478
+ g.clear_exception
479
+ g.push_stack_local outer_exc_state
480
+ g.restore_exception_state
481
+ g.goto f
482
+
483
+ ok.set!
484
+ g.push_literal :m
485
+ g.push_self
486
+ g.invoke_primitive :vm_check_callable, 3
487
+ g.gif f
488
+ g.push_literal "method"
489
+ g.goto done
490
+
491
+ f.set!
492
+ g.push :nil
493
+
494
+ done.set!
495
+ end
496
+ end
497
+
498
+ relates "defined? a.b" do
499
+ compile do |g|
500
+ g.push_exception_state
501
+ outer_exc_state = g.new_stack_local
502
+ g.set_stack_local outer_exc_state
503
+ g.pop
504
+
505
+ f = g.new_label
506
+ done = g.new_label
507
+
508
+ ex = g.new_label
509
+ ok = g.new_label
510
+ g.setup_unwind ex
511
+
512
+ g.push :self
513
+ g.send :a, 0, true
514
+
515
+ g.pop_unwind
516
+ g.goto ok
517
+
518
+ ex.set!
519
+ g.clear_exception
520
+ g.push_stack_local outer_exc_state
521
+ g.restore_exception_state
522
+ g.goto f
523
+
524
+ ok.set!
525
+ g.push_literal :b
526
+ g.push_self
527
+ g.invoke_primitive :vm_check_callable, 3
528
+ g.gif f
529
+ g.push_literal "method"
530
+ g.goto done
531
+
532
+ f.set!
533
+ g.push :nil
534
+
535
+ done.set!
536
+ end
537
+ end
538
+
539
+ relates "defined? [X]" do
540
+ compile do |g|
541
+ g.push_exception_state
542
+ outer_exc_state = g.new_stack_local
543
+ g.set_stack_local outer_exc_state
544
+ g.pop
545
+
546
+ f = g.new_label
547
+ done = g.new_label
548
+
549
+ ex = g.new_label
550
+ ok = g.new_label
551
+ g.setup_unwind ex
552
+
553
+ g.push_literal :X
554
+ g.invoke_primitive :vm_const_defined, 1
555
+ g.pop_unwind
556
+ g.goto ok
557
+
558
+ ex.set!
559
+ g.clear_exception
560
+ g.push_stack_local outer_exc_state
561
+ g.restore_exception_state
562
+ g.goto f
563
+
564
+ ok.set!
565
+ g.pop
566
+ g.push_literal "constant"
567
+ g.goto done
568
+
569
+ f.set!
570
+ g.push :nil
571
+
572
+ done.set!
573
+
574
+ not_found = g.new_label
575
+ finished = g.new_label
576
+
577
+ g.gif not_found
578
+ g.push_literal "expression"
579
+ g.goto finished
580
+
581
+ not_found.set!
582
+ g.push_nil
583
+ g.goto finished
584
+
585
+ finished.set!
586
+ end
587
+ end
588
+
589
+ relates <<-ruby do
590
+ a = 1
591
+ defined? a.to_s
592
+ ruby
593
+
594
+ compile do |g|
595
+ f = g.new_label
596
+ done = g.new_label
597
+
598
+ g.push 1
599
+ g.set_local 0
600
+ g.pop
601
+
602
+ g.push_local 0
603
+ g.push_literal :to_s
604
+ g.push_self
605
+ g.invoke_primitive :vm_check_callable, 3
606
+ g.gif f
607
+ g.push_literal "method"
608
+ g.goto done
609
+
610
+ f.set!
611
+ g.push :nil
612
+
613
+ done.set!
614
+ end
615
+ end
616
+ end