Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

executable file 304 lines (231 sloc) 9.855 kB
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.
Jump to Line
Something went wrong with that request. Please try again.