rubinius-compiler 2.1.0 → 2.1.1
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.
- checksums.yaml +4 -4
- data/.travis.yml +8 -0
- data/lib/rubinius/compiler/compiled_file.rb +32 -32
- data/lib/rubinius/compiler/version.rb +2 -2
- data/rubinius-compiler.gemspec +6 -0
- data/spec/alias_spec.rb +39 -0
- data/spec/and_spec.rb +44 -0
- data/spec/array_spec.rb +110 -0
- data/spec/attrasgn_spec.rb +186 -0
- data/spec/back_ref_spec.rb +11 -0
- data/spec/call_spec.rb +580 -0
- data/spec/case_spec.rb +576 -0
- data/spec/cdecl_spec.rb +70 -0
- data/spec/class_spec.rb +120 -0
- data/spec/colon2_spec.rb +8 -0
- data/spec/colon3_spec.rb +8 -0
- data/spec/const_spec.rb +7 -0
- data/spec/custom/guards/profiler.rb +18 -0
- data/spec/custom/helpers/generator.rb +828 -0
- data/spec/custom/matchers/compile_as.rb +46 -0
- data/spec/custom/mspec.rb +15 -0
- data/spec/custom/runner/actions/debug.rb +10 -0
- data/spec/custom/runner/actions/gcstats.rb +17 -0
- data/spec/custom/runner/actions/memory.rb +11 -0
- data/spec/custom/runner/actions/parser.rb +14 -0
- data/spec/custom/runner/actions/profiler.rb +19 -0
- data/spec/custom/runner/relates.rb +86 -0
- data/spec/custom/utils/options.rb +40 -0
- data/spec/custom/utils/script.rb +50 -0
- data/spec/cvar_spec.rb +39 -0
- data/spec/cvasgn_spec.rb +33 -0
- data/spec/cvdecl_spec.rb +17 -0
- data/spec/defined_spec.rb +616 -0
- data/spec/defn_spec.rb +732 -0
- data/spec/defs_spec.rb +113 -0
- data/spec/dot2_spec.rb +16 -0
- data/spec/dot3_spec.rb +17 -0
- data/spec/dregx_spec.rb +160 -0
- data/spec/dstr_spec.rb +424 -0
- data/spec/dsym_spec.rb +18 -0
- data/spec/dxstr_spec.rb +24 -0
- data/spec/ensure_spec.rb +196 -0
- data/spec/false_spec.rb +7 -0
- data/spec/flip2_spec.rb +21 -0
- data/spec/flip3_spec.rb +12 -0
- data/spec/for_spec.rb +228 -0
- data/spec/gasgn_spec.rb +15 -0
- data/spec/generator/encode_spec.rb +34 -0
- data/spec/gvar_spec.rb +37 -0
- data/spec/hash_spec.rb +108 -0
- data/spec/iasgn_spec.rb +26 -0
- data/spec/if_spec.rb +415 -0
- data/spec/iter_spec.rb +1011 -0
- data/spec/lasgn_spec.rb +561 -0
- data/spec/lit_spec.rb +61 -0
- data/spec/masgn_spec.rb +1558 -0
- data/spec/match2_spec.rb +42 -0
- data/spec/match3_spec.rb +54 -0
- data/spec/match_spec.rb +29 -0
- data/spec/module_spec.rb +73 -0
- data/spec/nil_spec.rb +7 -0
- data/spec/not_spec.rb +47 -0
- data/spec/nth_ref_spec.rb +7 -0
- data/spec/op_asgn_spec.rb +563 -0
- data/spec/or_spec.rb +126 -0
- data/spec/postexe_spec.rb +11 -0
- data/spec/preexe_spec.rb +21 -0
- data/spec/regex_spec.rb +54 -0
- data/spec/rescue_spec.rb +763 -0
- data/spec/return_spec.rb +152 -0
- data/spec/sclass_spec.rb +138 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/str_spec.rb +118 -0
- data/spec/super_spec.rb +170 -0
- data/spec/transforms/assembly_spec.rb +195 -0
- data/spec/transforms/block_given_spec.rb +75 -0
- data/spec/transforms/fast_coerce_spec.rb +112 -0
- data/spec/transforms/fast_new_spec.rb +255 -0
- data/spec/transforms/invoke_primitive_spec.rb +14 -0
- data/spec/transforms/kernel_methods_spec.rb +29 -0
- data/spec/transforms/primitive_spec.rb +33 -0
- data/spec/transforms/privately_spec.rb +24 -0
- data/spec/true_spec.rb +7 -0
- data/spec/undef_spec.rb +133 -0
- data/spec/until_spec.rb +254 -0
- data/spec/valias_spec.rb +11 -0
- data/spec/while_spec.rb +494 -0
- data/spec/xstr_spec.rb +10 -0
- data/spec/yield_spec.rb +92 -0
- data/spec/zsuper_spec.rb +63 -0
- 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,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,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
|
data/spec/cvasgn_spec.rb
ADDED
@@ -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
|
data/spec/cvdecl_spec.rb
ADDED
@@ -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
|