bo0liu / as3-commons

Automatically exported from code.google.com/p/as3-commons
0 stars 0 forks source link

Strange behavior, possible bug in emit class creation #52

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. run https://github.com/nodename/ClassCreationTest program
2.
3.

What is the expected output? What do you see instead?
expected: able to create instance of generated class without error.
see instead: Reference error: unable to create property _first on 
com.classes.generated.PointPair

What version of the product are you using? On what operating system?
bytecode/RC3
lang, logging, reflect: trunk
OS: Win7

Please provide any additional information below.

Original issue reported on code.google.com by noden...@gmail.com on 17 Apr 2011 at 7:28

GoogleCodeExporter commented 9 years ago
Hey there,

I've had a look at your code and can see where things go wrong, you are adding 
the opcodes by using a string based ASM block:

const ctorSource:String = (<![CDATA[
getlocal_0
pushscope
getlocal_0
constructsuper (0)
getlocal_0
getlocal_1
initproperty private:_first
getlocal_0
getlocal_2
initproperty private:_second
returnvoid
]]>).toString();

Unfortunately, the asm parser doesn't convert multinames yet, therefore these 
statements will not be properly converted:

initproperty private:_second

For now I suggest you use the emit API's .addOpcode() methods to construct your 
method body. I will try and find a little spare time to have a look at the ASM 
parser again and see if its possible to also support multinames.

Thanks for bringing this up!

cheers,

Roland

Original comment by ihatelivelyids on 19 Apr 2011 at 11:52

GoogleCodeExporter commented 9 years ago
I cannot see how to invoke initproperty on a private or protected property.

If the propertyBuilder's visibility is MemberVisibility.PUBLIC, then this 
appears to work:

ctorBuilder.addOpcode(Opcode.initproperty, [new QualifiedName("_first", 
LNamespace.PUBLIC)]);

But I have been trying to initialize a private or protected property without 
success.
What is the proper params array for initproperty in these cases?

Original comment by noden...@gmail.com on 20 Apr 2011 at 2:34

GoogleCodeExporter commented 9 years ago
From the top of my head I think this is how to construct a qualifiedname for 
your protected namespace:

new QualifiedName("_first", new 
LNamespace(NamespaceKind.PROTECTED_NAMESPACE,"com.classes.generated.MyClassName"
));

Hope that helps,

cheers,

Roland

Original comment by ihatelivelyids on 20 Apr 2011 at 8:39

GoogleCodeExporter commented 9 years ago
This led to the ReferenceError: Error #1056: Cannot create property 
com.classes.generated.Pair<Point>::first on com.classes.generated.Pair<Point>.
when the constructor was invoked...

Original comment by noden...@gmail.com on 20 Apr 2011 at 7:25

GoogleCodeExporter commented 9 years ago
Does the private or protected need a different MultinameKind than the default 
MultinameKind.QNAME?

Original comment by noden...@gmail.com on 20 Apr 2011 at 7:30

GoogleCodeExporter commented 9 years ago
hey there, no, the multinamekind is te same, it should both be a qualifiedname.
In this case what I usually do is just create the class I want to generate 
nomrally in actionscript, compile it and use either swfdump.exe or nemo440 
(http://www.docsultant.com/nemo440/) to check out the opcodes. Your problem is 
simply a matter of naming things wrong, I think once you use one of these utils 
you'll easily be able to find the correct one.

let me know how you're progressing.

Original comment by ihatelivelyids on 21 Apr 2011 at 5:53

GoogleCodeExporter commented 9 years ago
Of course I have disassembled the class written normally. That is how I got my 
first version of the asm code, which I have been using all along.  But the 
disassembly shows the operands as strings, namely private:first and 
private:second. But as you said I should not use the addAsmSource() method, my 
question is how to represent these as qualified names as required by the 
addOpcode() function.

BTW I am building with Flash Builder 4.5.0.308971 and SDK 4.5.  Nemo440 cannot 
even open the swf.  But swfdump works.

Original comment by noden...@gmail.com on 21 Apr 2011 at 6:43

GoogleCodeExporter commented 9 years ago
OK now I have the constructor working with the proper multinames/namespaces for 
all three visibilities. There are just two small issues that show up when the 
abc is written out to a swf file; these are confirmed by Burak:

1. the swf lacks the end tag (two bytes of 0);

2. the swf has version 16 (can this have something to do with MINOR_VERSION in 
AbcSerializer?)

Original comment by noden...@gmail.com on 27 Apr 2011 at 2:44

GoogleCodeExporter commented 9 years ago
AHA! AbcFileUtil.SWF_HEADER, fourth byte (version) is 0x10!

Original comment by noden...@gmail.com on 27 Apr 2011 at 3:04

GoogleCodeExporter commented 9 years ago
and AHA! if I add two more 0x00's to SWF_FOOTER, ASV no longer complains about 
missing end tag!

Original comment by noden...@gmail.com on 27 Apr 2011 at 3:23

GoogleCodeExporter commented 9 years ago
Hey there,

James Ward already fixed these bugs AFAIK, so the latest trunk of 
as3commons-bytecode should already be working without the bugs you're 
describing.
(You're using the RC3 .swc, right?)

cheers,

Roland

Original comment by rol...@stackandheap.com on 27 Apr 2011 at 7:05

GoogleCodeExporter commented 9 years ago
Setting this to fixed since I'm pretty sure its working now.

Original comment by ihatelivelyids on 25 Jul 2011 at 9:40