public
Description: Red Sun - Ruby to Flash compiler and framework
Homepage: http://jonathanbranam.net
Clone URL: git://github.com/jonathanbranam/redsun.git
redsun / plan.txt
100755 304 lines (231 sloc) 9.855 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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
pretty print as3 so I can read it and understand what's happening
write some as3, compile it, and look at the output
 
translate basic ruby calls to as3
insert byte codes into existing abc_file
- have to search/update constant_pool - strings, multinames, namespaces
 
goals:
- enable code generation from Ruby to AS3 bytecode
-- implement methods and event handlers
-- shortcuts for properties and handling changes in commitProperties()
-- automatic xxChanged:boolean generation and callback in commitProperties() based on some convention
- enable tx of Flash vector definitions
-- transform vectors into Degrafa definitions
- transform fonts into Degrafa definitions
- pointcut expressions to modify existing methods
 
Awful things I don't want to think about:
* converting floating point numbers
 
 
New plans:
 
* Implement a bunch of AS3 to support Ruby
* Implement different send_external on Object.prototype and RObject.prototype
* Don't use AS3 classes to implement Ruby classes
* Ruby inheritance hierarchy implemented in plain AS3 to support proper semantics and method dispatch
 
Problems:
* How do you "subclass" Sprite; implement a Sprite object in Ruby if you cannot inherit from flash.display.Sprite?
* method for proxying a typed class? include_typed_class Flash::Display::Sprite
 
 
Const (and other) scoping issues:
 
Here's the code in question:
 
class A
  class B
    def d
      C
    end
  end
  class C
  end
end
 
b = A::B.new
b.d # returns A::C
 
How does this work? The :getconstant bytecode searches upwards in the scope
stack at the time of definition to find the constant. When I define classes
and methods, I'm not saving the scope stack currently so I don't know where
to search for the constant definition.
 
Solution: Obviously, the scope stack must be searched by this opcode and
others. Is there a way to call up the scope stack that is created by AVM2?
 
Looks like it is very hard to use the Flash call stack to look up this
information. Decent solution is to store the call stack at each level, but
where would this actually be stored? Then would local variables not really
be local variables in the AS3 version? It seems like we are getting further
and further away from a bytecode translater into a bytecode interpretter
at this point. Is this a good idea?
 
We have closures already in Flash, but do the opcodes for accessing closure
variables allow us to translate into something that can be used in AS3?
What are the opcodes in AS3 also?
 
10/8/2008
 
Moved test/files which are not used in tests to /research. This seems like
a more appropriate and descriptive name.
 
10/9/2008
 
 
"YARVInstructionSequence/SimpleDataFormat", 1, 1, 1,
{:arg_size=>1, :local_size=>5, :stack_max=>2},
"blah", "<compiled>",
:method,
[:parm1, :i, :i2, :ar],
1,
[
  [:break, nil, :label_32, :label_40, :label_40, 0],
  [:break, nil, :label_41, :label_49, :label_49, 0],
  [:break, nil, :label_50, :label_58, :label_58, 0],
]
 
 
10/14/2008
 
Migrating Red Sun work to new MacBook Pro. Authorizing github access and
testing commit privileges. Installing Ruby 1.9.0-4, looking into mspec instead
of rspec.
 
Making new plan for conference deadline:
 
Focus on establishing baseline through generating as3. Accept the possibility
that storing stack information may be necessary fo lookups. May need a
structure for stack information. Use HotRuby as a guide. Get into the Ruby
source further and track down the execution of the bytecode.
 
Using anonymous functions as block scope might work. Pass the surrounding
blocks structure as a parameter to the function as in:
 
// root
function ():* {
  scope = new Scope();
  // blah
  function (upper:Scope):* {
    scope = new Scope(upper);
    // blah
    scope.getdynamic(/* ?? */);
  }();
}
 
 
10/15/2008
 
You cannot subclass Class:
>> class B < Class
>> end
TypeError: can't make subclass of Class
from (irb):1
>>
 
class.c:60
rb_class_new(VALUE super)
...
    if (super == rb_cClass) {
rb_raise(rb_eTypeError, "can't make subclass of Class");
    }
...
}
 
10/16/2008
 
Further research into initialization and basic structures.
Have been reading through the Ruby Hacker's Guide.
 
Plan is to generate AS3 bytecode from Ruby bytecode that operates as an AS3
Ruby VM. Instead of interpretting the Ruby bytecode at runtime, the Ruby
project will translate the Ruby bytecode into AS3 bytecode that interacts
with the Ruby AS3 VM.
 
Renamed research files from *.txt to *.c to help Emacs highlight them better.
Probably a better way to convince Emacs to do that, but this is easy.
 
5pm EDT
Tagged previous version as 0.1 indicating last version that attempted to target
the Flash AS3 VM directly with the Ruby bytecode translation. Further versions
will include a Ruby VM in AS3 and will translate Ruby bytecode into AS3
bytecode which will make calls into this VM.
 
This means that lots of tests will completely break as the structure will be
radically different. Breaking tests will be deleted and can be recovered
(along with the previous implementation) through tag 0.1.
 
6pm EDT
Implementing lots of methods from Ruby source as AS3 methods. Trying to get
basic object structure setup: Object, Class, and Module.
 
10/17/2008
 
Finished implementing basic opcodes and internal Ruby code. Wrote a real
rb_intern solution (probably wrong and/or naive). Ran a blank test.
 
10/18/2008
 
Going to step back from creating classes for a while and just compile:
  puts "hi"
until that works (directing puts to trace)
 
Once method dispatch works for that basic case, then look at local vars such
as:
  var = "hi"
  puts var
 
 
Note: control frame is stored at the bottom of the stack in an upside-down
stack that pops from the top to bottom. Not totally sure how overflow is
controlled; probably through the stack_size field that is compared before
execution begins.
 
Completed method dispatch for puts "hi". Amazing amount of work to do it
"the right way" as opposed to just faking the whole thing. Had to add a bunch
of class initializations, setup lots of different intermediate structures and
methods. Execution path from VM initiated calls is different than execution
path from Ruby C initiated calls.
 
Split a bunch of methods into their Ruby C equivalent files for easier
organization. Clearly a better structure could be devised for OO, but this
layout helps when searching for methods from Ruby C.
 
10/20/2008
 
Here's the plan:
- local vars
- class creation
- class instantiation
- class method creation
- calling method on object
- method params
- class instance vars
- block passing
- yield
- block exception tags - break, redo, continue
- Arrays (maybe need this earlier?)
- Numbers
 
Reassess after this is done, but probably:
- more Kernel methods
- operators
- Enumerable and Arrays
- Numeric methods
- mspec execution
-- class methods
-- namespaces
-- modules
-- ??
 
Progress:
- local vars
- class creation
- (untested) class instantiation
- (untested) class method creation
 
10/21/2008
 
Progress:
- class instantiation
- class method creation
- calling method on object
 
Finding that much of the functionality internal to Ruby is also implemented
through the Ruby C API by adding methods to the base Ruby classes such as
Object, BasicObject, Class, and Module. This means that I find method_missing
errors typically indicate I need to revisit the various Init_* functions
(particularly Init_Object) and fill out some more methods and implement
their Ruby C versions.
 
Spent time working on the Ruby bytecode -> AS3 bytecode translation part.
Current solution simply opens a precompiled SWF with the Ruby VM already
inside and then rewrite the methods that are called in the client code that
return the Ruby VM Function. This is certainly the fastest path given the
state of the Ruby SWF lib, but loading the code from a SWC would make more
sense.
 
Currently putting some fragile code in that remembers the opcodes and
internal ids of various multinames. This should be fixed to lookup the
proper info from the SWF itself.
 
10/22/2008
 
Goal: Ruby bytcoode compiling generically to AS3 bytecode, calling methods
on RubyFrame with same name as bytecode.
 
2ndary: Special case instructions such as branching to generate branching AS3
code.
 
10/24/2008
 
Stupid research goal of the morning: stackless VM in 3 hours?
 
Stackless VM began working quickly, but exposed lots of other problems with
stack handling. This led to rewriting the stack and related pointers to use
a new class StackPointer that keeps the Array and top index separate. This
class enables the stack Array to be shared across the app instead of making
copies everywhere.
 
The stack and argument handling was adjusted all over to exactly mimic the
Ruby C VM behavior which resulted in correct behavior eventually.
 
10/25/2008
 
Finally found remaining bug in implementation of leave opcode. Didn't realize
that the return value from the called function is popped off the stack and
re-added at the new stack level after the vm_pop_frame() completes.
 
10/27/2008
 
Revisiting the 'compilation' of Ruby bytecode which is now mostly translating
it into a string (with the require calls already handled). Don't really need
to modify the .swf anymore to achieve the functionality, but it might be
nice to bake the Ruby into the SWF just for convenience sake.
 
Todo:
- check class code and update it for the new stackless, bytecode VM
- ensure modules work
- implement operators
- work on Asterism rendering
 
10/29/2008
 
Update: Executing large blocks of Ruby code is now working successfully.
Arrays work with a few very basic operations. Calling to and from Flash
objects and classes has been improved. A Ramaze webapp was written that
will compile Ruby bytecode either on the harddrive or passed to it as
POST data.
 
AIR client developed which can browse for Ruby source to execute or send
arbitrary Ruby code directly. It runs the Ruby in a new window.