rubinius-compiler 1.0.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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/rubinius/compiler.rb +11 -0
- data/lib/rubinius/compiler/compiled_file.rb +338 -0
- data/lib/rubinius/compiler/compiler.rb +377 -0
- data/lib/rubinius/compiler/evaluator.rb +334 -0
- data/lib/rubinius/compiler/generator.rb +646 -0
- data/lib/rubinius/compiler/generator_methods.rb +802 -0
- data/lib/rubinius/compiler/iseq.rb +146 -0
- data/lib/rubinius/compiler/locals.rb +147 -0
- data/lib/rubinius/compiler/opcodes.rb +150 -0
- data/lib/rubinius/compiler/printers.rb +115 -0
- data/lib/rubinius/compiler/runtime.rb +72 -0
- data/lib/rubinius/compiler/stages.rb +254 -0
- data/lib/rubinius/compiler/version.rb +5 -0
- data/rubinius-compiler.gemspec +22 -0
- metadata +91 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
# -*- encoding: us-ascii -*-
|
2
|
+
|
3
|
+
module Rubinius::ToolSet.current::TS
|
4
|
+
module Compiler::Runtime
|
5
|
+
def self.matches_when(array, receiver)
|
6
|
+
array.each { |x| return true if x === receiver }
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.unwrap_block_arg(arg)
|
11
|
+
if arg.size == 1
|
12
|
+
elem = arg.at(0)
|
13
|
+
return elem if elem.kind_of?(Array)
|
14
|
+
end
|
15
|
+
|
16
|
+
arg
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.find_constant_for_op_asign_or(name, scope)
|
20
|
+
name = Rubinius::Type.coerce_to_constant_name name
|
21
|
+
|
22
|
+
current, constant = scope.module, undefined
|
23
|
+
|
24
|
+
while current
|
25
|
+
if entry = current.constant_table.lookup(name)
|
26
|
+
constant = entry.constant
|
27
|
+
constant = constant.call if constant.kind_of?(Autoload)
|
28
|
+
return constant
|
29
|
+
end
|
30
|
+
|
31
|
+
current = current.direct_superclass
|
32
|
+
end
|
33
|
+
|
34
|
+
if instance_of?(Module)
|
35
|
+
if entry = Object.constant_table.lookup(name)
|
36
|
+
constant = entry.constant
|
37
|
+
constant = constant.call if constant.kind_of?(Autoload)
|
38
|
+
return constant
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.get_flip_flop(scope, index)
|
46
|
+
scope.flip_flops ||= {}
|
47
|
+
scope.flip_flops[index]
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.set_flip_flop(scope, index, value)
|
51
|
+
scope.flip_flops ||= {}
|
52
|
+
scope.flip_flops[index] = value
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.rbx_marshal_constant
|
56
|
+
name
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.get_encoding(name)
|
60
|
+
if defined?(Encoding)
|
61
|
+
Encoding.find name
|
62
|
+
else
|
63
|
+
name
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.pre_exe
|
68
|
+
yield
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
@@ -0,0 +1,254 @@
|
|
1
|
+
# -*- encoding: us-ascii -*-
|
2
|
+
|
3
|
+
module Rubinius::ToolSet.current::TS
|
4
|
+
class Compiler
|
5
|
+
Stages = { }
|
6
|
+
|
7
|
+
class Stage
|
8
|
+
attr_accessor :next_stage, :printer
|
9
|
+
|
10
|
+
def self.stage(name)
|
11
|
+
@stage = name
|
12
|
+
Stages[name] = self
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.stage_name
|
16
|
+
@stage
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.next_stage(klass)
|
20
|
+
@next_stage_class = klass
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.next_stage_class
|
24
|
+
@next_stage_class
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(compiler, last)
|
28
|
+
@next_stage = create_next_stage compiler, last
|
29
|
+
end
|
30
|
+
|
31
|
+
def input(data)
|
32
|
+
@input = data
|
33
|
+
end
|
34
|
+
|
35
|
+
def processor(klass)
|
36
|
+
@processor = klass
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_next_stage(compiler, last)
|
40
|
+
return if self.class.stage_name == last
|
41
|
+
|
42
|
+
stage = self.class.next_stage_class
|
43
|
+
stage.new compiler, last if stage
|
44
|
+
end
|
45
|
+
|
46
|
+
def insert(stage)
|
47
|
+
@next_stage, stage.next_stage = stage.next_stage, self
|
48
|
+
end
|
49
|
+
|
50
|
+
def run_next
|
51
|
+
if @next_stage
|
52
|
+
@next_stage.input @output
|
53
|
+
@next_stage.run
|
54
|
+
else
|
55
|
+
@output
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# compiled method -> compiled file
|
61
|
+
class Writer < Stage
|
62
|
+
stage :compiled_file
|
63
|
+
|
64
|
+
attr_accessor :name, :version
|
65
|
+
|
66
|
+
def initialize(compiler, last)
|
67
|
+
super
|
68
|
+
compiler.writer = self
|
69
|
+
|
70
|
+
@version = 0
|
71
|
+
@processor = CompiledFile
|
72
|
+
@signature = Rubinius::Signature
|
73
|
+
end
|
74
|
+
|
75
|
+
def run
|
76
|
+
return @input unless @name
|
77
|
+
|
78
|
+
dir = File.dirname(@name)
|
79
|
+
unless File.directory?(dir)
|
80
|
+
parts = []
|
81
|
+
|
82
|
+
until dir == "/" or dir == "."
|
83
|
+
parts << dir
|
84
|
+
dir = File.dirname(dir)
|
85
|
+
end
|
86
|
+
|
87
|
+
parts.reverse_each do |d|
|
88
|
+
Dir.mkdir d unless File.directory?(d)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
@processor.dump @input, @name, @signature, @version
|
93
|
+
@input
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# encoded bytecode -> compiled method
|
98
|
+
class Packager < Stage
|
99
|
+
stage :compiled_code
|
100
|
+
next_stage Writer
|
101
|
+
|
102
|
+
def initialize(compiler, last)
|
103
|
+
super
|
104
|
+
compiler.packager = self
|
105
|
+
end
|
106
|
+
|
107
|
+
def print(klass=MethodPrinter)
|
108
|
+
@printer = klass.new
|
109
|
+
@printer.insert self
|
110
|
+
@printer
|
111
|
+
end
|
112
|
+
|
113
|
+
def run
|
114
|
+
@output = @input.package Rubinius::CompiledCode
|
115
|
+
run_next
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# symbolic bytecode -> encoded bytecode
|
120
|
+
class Encoder < Stage
|
121
|
+
stage :encoded_bytecode
|
122
|
+
next_stage Packager
|
123
|
+
|
124
|
+
def initialize(compiler, last)
|
125
|
+
super
|
126
|
+
compiler.encoder = self
|
127
|
+
end
|
128
|
+
|
129
|
+
def run
|
130
|
+
@input.encode
|
131
|
+
@output = @input
|
132
|
+
run_next
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# AST -> symbolic bytecode
|
137
|
+
class Generator < Stage
|
138
|
+
stage :bytecode
|
139
|
+
next_stage Encoder
|
140
|
+
|
141
|
+
attr_accessor :variable_scope
|
142
|
+
|
143
|
+
def initialize(compiler, last)
|
144
|
+
super
|
145
|
+
@variable_scope = nil
|
146
|
+
compiler.generator = self
|
147
|
+
@processor = ToolSet::Generator
|
148
|
+
end
|
149
|
+
|
150
|
+
def run
|
151
|
+
@output = @processor.new
|
152
|
+
@input.variable_scope = @variable_scope
|
153
|
+
@input.bytecode @output
|
154
|
+
@output.close
|
155
|
+
run_next
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# source -> AST
|
160
|
+
class Parser < Stage
|
161
|
+
attr_accessor :transforms
|
162
|
+
|
163
|
+
def initialize(compiler, last)
|
164
|
+
super
|
165
|
+
compiler.parser = self
|
166
|
+
@transforms = []
|
167
|
+
@processor = Melbourne
|
168
|
+
end
|
169
|
+
|
170
|
+
def root(klass)
|
171
|
+
@root = klass
|
172
|
+
end
|
173
|
+
|
174
|
+
def default_transforms
|
175
|
+
@transforms.concat AST::Transforms.category(:default)
|
176
|
+
end
|
177
|
+
|
178
|
+
def print(klass=ASTPrinter)
|
179
|
+
@printer = klass.new
|
180
|
+
@printer.insert self
|
181
|
+
@printer
|
182
|
+
end
|
183
|
+
|
184
|
+
def enable_category(name)
|
185
|
+
transforms = AST::Transforms.category name
|
186
|
+
@transforms.concat transforms if transforms
|
187
|
+
end
|
188
|
+
|
189
|
+
def enable_transform(name)
|
190
|
+
transform = AST::Transforms[name]
|
191
|
+
@transforms << transform if transform
|
192
|
+
end
|
193
|
+
|
194
|
+
def create
|
195
|
+
@parser = @processor.new(@file, @line, @transforms)
|
196
|
+
@parser.magic_handler = self
|
197
|
+
@parser
|
198
|
+
end
|
199
|
+
|
200
|
+
def add_magic_comment(str)
|
201
|
+
if m = /-\*-\s*(.*?)\s*(-\*-)$/.match(str)
|
202
|
+
enable_transform(m[1].to_sym)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def run
|
207
|
+
@output = @root.new parse
|
208
|
+
@output.file = @file
|
209
|
+
@output.pre_exe = @parser.pre_exe
|
210
|
+
run_next
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
# source file -> AST
|
215
|
+
class FileParser < Parser
|
216
|
+
stage :file
|
217
|
+
next_stage Generator
|
218
|
+
|
219
|
+
def input(file, line=1)
|
220
|
+
@file = file
|
221
|
+
@line = line
|
222
|
+
end
|
223
|
+
|
224
|
+
def parse
|
225
|
+
create.parse_file
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# source string -> AST
|
230
|
+
class StringParser < Parser
|
231
|
+
stage :string
|
232
|
+
next_stage Generator
|
233
|
+
|
234
|
+
def input(string, name="(eval)", line=1)
|
235
|
+
@input = string
|
236
|
+
@file = name
|
237
|
+
@line = line
|
238
|
+
end
|
239
|
+
|
240
|
+
def parse
|
241
|
+
create.parse_string(@input)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
class EvalParser < StringParser
|
246
|
+
stage :eval
|
247
|
+
next_stage Generator
|
248
|
+
|
249
|
+
def should_cache?
|
250
|
+
@output.should_cache?
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'rubinius/toolset'
|
3
|
+
require './lib/rubinius/compiler/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "rubinius-compiler"
|
7
|
+
spec.version = Rubinius::ToolSet.current::TS::Compiler::VERSION
|
8
|
+
spec.authors = ["Brian Shirai"]
|
9
|
+
spec.email = ["brixen@gmail.com"]
|
10
|
+
spec.description = %q{Rubinius bytecode compiler.}
|
11
|
+
spec.summary = %q{Rubinius bytecode compiler.}
|
12
|
+
spec.homepage = "https://github.com/rubinius/rubinius-compiler"
|
13
|
+
spec.license = "BSD"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
21
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubinius-compiler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Shirai
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description: Rubinius bytecode compiler.
|
42
|
+
email:
|
43
|
+
- brixen@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- lib/rubinius/compiler.rb
|
54
|
+
- lib/rubinius/compiler/compiled_file.rb
|
55
|
+
- lib/rubinius/compiler/compiler.rb
|
56
|
+
- lib/rubinius/compiler/evaluator.rb
|
57
|
+
- lib/rubinius/compiler/generator.rb
|
58
|
+
- lib/rubinius/compiler/generator_methods.rb
|
59
|
+
- lib/rubinius/compiler/iseq.rb
|
60
|
+
- lib/rubinius/compiler/locals.rb
|
61
|
+
- lib/rubinius/compiler/opcodes.rb
|
62
|
+
- lib/rubinius/compiler/printers.rb
|
63
|
+
- lib/rubinius/compiler/runtime.rb
|
64
|
+
- lib/rubinius/compiler/stages.rb
|
65
|
+
- lib/rubinius/compiler/version.rb
|
66
|
+
- rubinius-compiler.gemspec
|
67
|
+
homepage: https://github.com/rubinius/rubinius-compiler
|
68
|
+
licenses:
|
69
|
+
- BSD
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.0.7
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: Rubinius bytecode compiler.
|
91
|
+
test_files: []
|