[swfinterp] Add support for multiple classes
This commit is contained in:
		
							parent
							
								
									e75c24e889
								
							
						
					
					
						commit
						70f767dc65
					
				
					 2 changed files with 57 additions and 6 deletions
				
			
		
							
								
								
									
										15
									
								
								test/swftests/ClassConstruction.as
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/swftests/ClassConstruction.as
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					// input: []
 | 
				
			||||||
 | 
					// output: 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package {
 | 
				
			||||||
 | 
					public class ClassConstruction {
 | 
				
			||||||
 | 
					    public static function main():int{
 | 
				
			||||||
 | 
					    	var f:Foo = new Foo();
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Foo {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,10 @@ import io
 | 
				
			||||||
import struct
 | 
					import struct
 | 
				
			||||||
import zlib
 | 
					import zlib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .utils import ExtractorError
 | 
					from .utils import (
 | 
				
			||||||
 | 
					    compat_str,
 | 
				
			||||||
 | 
					    ExtractorError,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _extract_tags(file_contents):
 | 
					def _extract_tags(file_contents):
 | 
				
			||||||
| 
						 | 
					@ -65,7 +68,26 @@ class _AVMClass(object):
 | 
				
			||||||
        self.method_idxs = {}
 | 
					        self.method_idxs = {}
 | 
				
			||||||
        self.methods = {}
 | 
					        self.methods = {}
 | 
				
			||||||
        self.method_pyfunctions = {}
 | 
					        self.method_pyfunctions = {}
 | 
				
			||||||
        self.variables = {}
 | 
					
 | 
				
			||||||
 | 
					        class ScopeDict(dict):
 | 
				
			||||||
 | 
					            def __init__(self, avm_class):
 | 
				
			||||||
 | 
					                super(ScopeDict, self).__init__()
 | 
				
			||||||
 | 
					                self.avm_class = avm_class
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def __getitem__(self, k):
 | 
				
			||||||
 | 
					                print('getting %r' % k)
 | 
				
			||||||
 | 
					                return super(ScopeDict, self).__getitem__(k)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def __contains__(self, k):
 | 
				
			||||||
 | 
					                print('contains %r' % k)
 | 
				
			||||||
 | 
					                return super(ScopeDict, self).__contains__(k)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def __repr__(self):
 | 
				
			||||||
 | 
					                return '%s__Scope(%s)' % (
 | 
				
			||||||
 | 
					                    self.avm_class.name,
 | 
				
			||||||
 | 
					                    super(ScopeDict, self).__repr__())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.variables = ScopeDict(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_object(self):
 | 
					    def make_object(self):
 | 
				
			||||||
        return _AVMClass_Object(self)
 | 
					        return _AVMClass_Object(self)
 | 
				
			||||||
| 
						 | 
					@ -156,10 +178,10 @@ class SWFInterpreter(object):
 | 
				
			||||||
        double_count = u30()
 | 
					        double_count = u30()
 | 
				
			||||||
        read_bytes(max(0, (double_count - 1)) * 8)
 | 
					        read_bytes(max(0, (double_count - 1)) * 8)
 | 
				
			||||||
        string_count = u30()
 | 
					        string_count = u30()
 | 
				
			||||||
        constant_strings = ['']
 | 
					        self.constant_strings = ['']
 | 
				
			||||||
        for _c in range(1, string_count):
 | 
					        for _c in range(1, string_count):
 | 
				
			||||||
            s = _read_string(code_reader)
 | 
					            s = _read_string(code_reader)
 | 
				
			||||||
            constant_strings.append(s)
 | 
					            self.constant_strings.append(s)
 | 
				
			||||||
        namespace_count = u30()
 | 
					        namespace_count = u30()
 | 
				
			||||||
        for _c in range(1, namespace_count):
 | 
					        for _c in range(1, namespace_count):
 | 
				
			||||||
            read_bytes(1)  # kind
 | 
					            read_bytes(1)  # kind
 | 
				
			||||||
| 
						 | 
					@ -189,7 +211,7 @@ class SWFInterpreter(object):
 | 
				
			||||||
            if kind == 0x07:
 | 
					            if kind == 0x07:
 | 
				
			||||||
                u30()  # namespace_idx
 | 
					                u30()  # namespace_idx
 | 
				
			||||||
                name_idx = u30()
 | 
					                name_idx = u30()
 | 
				
			||||||
                self.multinames.append(constant_strings[name_idx])
 | 
					                self.multinames.append(self.constant_strings[name_idx])
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                self.multinames.append('[MULTINAME kind: %d]' % kind)
 | 
					                self.multinames.append('[MULTINAME kind: %d]' % kind)
 | 
				
			||||||
                for _c2 in range(MULTINAME_SIZES[kind]):
 | 
					                for _c2 in range(MULTINAME_SIZES[kind]):
 | 
				
			||||||
| 
						 | 
					@ -375,7 +397,7 @@ class SWFInterpreter(object):
 | 
				
			||||||
                    stack.append(value)
 | 
					                    stack.append(value)
 | 
				
			||||||
                elif opcode == 44:  # pushstring
 | 
					                elif opcode == 44:  # pushstring
 | 
				
			||||||
                    idx = u30()
 | 
					                    idx = u30()
 | 
				
			||||||
                    stack.append(constant_strings[idx])
 | 
					                    stack.append(self.constant_strings[idx])
 | 
				
			||||||
                elif opcode == 48:  # pushscope
 | 
					                elif opcode == 48:  # pushscope
 | 
				
			||||||
                    new_scope = stack.pop()
 | 
					                    new_scope = stack.pop()
 | 
				
			||||||
                    scopes.append(new_scope)
 | 
					                    scopes.append(new_scope)
 | 
				
			||||||
| 
						 | 
					@ -450,6 +472,16 @@ class SWFInterpreter(object):
 | 
				
			||||||
                        arr.append(stack.pop())
 | 
					                        arr.append(stack.pop())
 | 
				
			||||||
                    arr = arr[::-1]
 | 
					                    arr = arr[::-1]
 | 
				
			||||||
                    stack.append(arr)
 | 
					                    stack.append(arr)
 | 
				
			||||||
 | 
					                elif opcode == 93:  # findpropstrict
 | 
				
			||||||
 | 
					                    index = u30()
 | 
				
			||||||
 | 
					                    mname = self.multinames[index]
 | 
				
			||||||
 | 
					                    for s in reversed(scopes):
 | 
				
			||||||
 | 
					                        if mname in s:
 | 
				
			||||||
 | 
					                            res = s
 | 
				
			||||||
 | 
					                            break
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        res = scopes[0]
 | 
				
			||||||
 | 
					                    stack.append(res)
 | 
				
			||||||
                elif opcode == 94:  # findproperty
 | 
					                elif opcode == 94:  # findproperty
 | 
				
			||||||
                    index = u30()
 | 
					                    index = u30()
 | 
				
			||||||
                    mname = self.multinames[index]
 | 
					                    mname = self.multinames[index]
 | 
				
			||||||
| 
						 | 
					@ -535,6 +567,10 @@ class SWFInterpreter(object):
 | 
				
			||||||
                    stack.append(registers[2])
 | 
					                    stack.append(registers[2])
 | 
				
			||||||
                elif opcode == 211:  # getlocal_3
 | 
					                elif opcode == 211:  # getlocal_3
 | 
				
			||||||
                    stack.append(registers[3])
 | 
					                    stack.append(registers[3])
 | 
				
			||||||
 | 
					                elif opcode == 212:  # setlocal_0
 | 
				
			||||||
 | 
					                    registers[0] = stack.pop()
 | 
				
			||||||
 | 
					                elif opcode == 213:  # setlocal_1
 | 
				
			||||||
 | 
					                    registers[1] = stack.pop()
 | 
				
			||||||
                elif opcode == 214:  # setlocal_2
 | 
					                elif opcode == 214:  # setlocal_2
 | 
				
			||||||
                    registers[2] = stack.pop()
 | 
					                    registers[2] = stack.pop()
 | 
				
			||||||
                elif opcode == 215:  # setlocal_3
 | 
					                elif opcode == 215:  # setlocal_3
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue