forked from jruby/jruby
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjruby.rb
More file actions
140 lines (113 loc) · 3.89 KB
/
Copy pathjruby.rb
File metadata and controls
140 lines (113 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
require 'java'
module JRuby
def self.init_asm
begin
JRuby.const_set(:TraceClassVisitor, org.jruby.org.objectweb.asm.util.TraceClassVisitor)
JRuby.const_set(:ClassReader, org.jruby.org.objectweb.asm.ClassReader)
rescue
JRuby.const_set(:TraceClassVisitor, org.objectweb.asm.util.TraceClassVisitor)
JRuby.const_set(:ClassReader, org.objectweb.asm.ClassReader)
end
end
class << self
# Get a Java integration reference to the given object
def reference(obj); end
# Turn a Java integration reference to a Ruby object back into a normal Ruby
# object reference.
def dereference(obj); end
# Get the current JRuby runtime.
def runtime
# reference nil, since it is guaranteed to be a normal object
reference0(nil).runtime
end
# Run the provided (required) block with the "global runtime" set to the
# current runtime, for libraries that expect to operate against the global
# runtime.
def with_current_runtime_as_global
current = runtime
global = org.jruby.Ruby.global_runtime
begin
if current != global
current.use_as_global_runtime
end
yield
ensure
if org.jruby.Ruby.global_runtime != global
global.use_as_global_runtime
end
end
end
# Parse the given block or the provided content, returning a JRuby AST node.
def parse(content = nil, filename = (default_filename = true; '-'), extra_position_info = false, &block)
if block
block_r = reference0(block)
body = block_r.body
if org.jruby.runtime.CompiledBlock === body
raise ArgumentError, "cannot get parse tree from compiled block"
end
body.body_node
else
content = content.to_str
filename = filename.to_str unless default_filename
runtime.parse(reference0(content).byte_list, filename, nil, 0, extra_position_info)
end
end
alias ast_for parse
# Parse and compile the given block or provided content, returning a new
# CompiledScript instance.
def compile(content = nil, filename = (default_filename = true; '-'), extra_position_info = false, &block)
node = if default_filename
parse(content, &block)
else
parse(content, filename, extra_position_info, &block)
end
content = content.to_str
filename = filename.to_str unless default_filename
if filename == "-e"
classname = "__dash_e__"
else
classname = filename.gsub(/\\/, '/')
classname.gsub!(/\.rb/, '')
classname.gsub!(/-/, 'dash')
end
inspector = org.jruby.compiler.ASTInspector.new
inspector.inspect(node)
generator = org.jruby.compiler.impl.StandardASMCompiler.new(classname, filename)
compiler = runtime.instance_config.new_compiler
compiler.compile_root(node, generator, inspector)
bytes = generator.class_byte_array
script = CompiledScript.new
script.name = filename
script.class_name = classname
script.original_script = content
script.code = bytes
script
end
end
# NOTE: This is not a public API and is subject to change at our whim
module IR
def self.debug=(value)
org.jruby.RubyInstanceConfig.IR_DEBUG = !!value
end
def self.compiler_debug=(value)
org.jruby.RubyInstanceConfig.IR_COMPILER_DEBUG = !!value
end
end
class CompiledScript
attr_accessor :name, :class_name, :original_script, :code
def to_s
@original_script
end
def inspect
"\#<JRuby::CompiledScript #{@name}>"
end
def inspect_bytecode
JRuby.init_asm
writer = java.io.StringWriter.new
reader = ClassReader.new(@code)
tracer = TraceClassVisitor.new(java.io.PrintWriter.new(writer))
reader.accept(tracer, ClassReader::SKIP_DEBUG)
writer.to_s
end
end
end