[swfinterp] Basic support for constants (only ints for now)

This commit is contained in:
Philipp Hagemeister 2014-11-17 07:14:02 +01:00
parent 162f54eca6
commit cd9ad1d7e8
2 changed files with 45 additions and 10 deletions

View file

@ -0,0 +1,12 @@
// input: []
// output: 2
package {
public class ConstantInt {
private static const x:int = 2;
public static function main():int{
return x;
}
}
}

View file

@ -71,6 +71,7 @@ class _AVMClass(object):
self.method_pyfunctions = {} self.method_pyfunctions = {}
self.variables = _ScopeDict(self) self.variables = _ScopeDict(self)
self.constants = {}
def make_object(self): def make_object(self):
return _AVMClass_Object(self) return _AVMClass_Object(self)
@ -189,11 +190,13 @@ class SWFInterpreter(object):
# Constant pool # Constant pool
int_count = u30() int_count = u30()
self.constant_ints = [0]
for _c in range(1, int_count): for _c in range(1, int_count):
s32() self.constant_ints.append(s32())
self.constant_uints = [0]
uint_count = u30() uint_count = u30()
for _c in range(1, uint_count): for _c in range(1, uint_count):
u32() self.constant_uints.append(u32())
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()
@ -281,13 +284,28 @@ class SWFInterpreter(object):
kind = kind_full & 0x0f kind = kind_full & 0x0f
attrs = kind_full >> 4 attrs = kind_full >> 4
methods = {} methods = {}
if kind in [0x00, 0x06]: # Slot or Const constants = None
if kind == 0x00: # Slot
u30() # Slot id u30() # Slot id
u30() # type_name_idx u30() # type_name_idx
vindex = u30() vindex = u30()
if vindex != 0: if vindex != 0:
read_byte() # vkind read_byte() # vkind
elif kind in [0x01, 0x02, 0x03]: # Method / Getter / Setter elif kind == 0x06: # Const
u30() # Slot id
u30() # type_name_idx
vindex = u30()
vkind = 'any'
if vindex != 0:
vkind = read_byte()
if vkind == 0x03: # Constant_Int
value = self.constant_ints[vindex]
elif vkind == 0x04: # Constant_UInt
value = self.constant_uints[vindex]
else:
return {}, None # Ignore silently for now
constants = {self.multinames[trait_name_idx]: value}
elif kind in (0x01, 0x02, 0x03): # Method / Getter / Setter
u30() # disp_id u30() # disp_id
method_idx = u30() method_idx = u30()
methods[self.multinames[trait_name_idx]] = method_idx methods[self.multinames[trait_name_idx]] = method_idx
@ -306,7 +324,7 @@ class SWFInterpreter(object):
for _c3 in range(metadata_count): for _c3 in range(metadata_count):
u30() # metadata index u30() # metadata index
return methods return methods, constants
# Classes # Classes
class_count = u30() class_count = u30()
@ -328,8 +346,9 @@ class SWFInterpreter(object):
u30() # iinit u30() # iinit
trait_count = u30() trait_count = u30()
for _c2 in range(trait_count): for _c2 in range(trait_count):
trait_methods = parse_traits_info() trait_methods, constants = parse_traits_info()
avm_class.register_methods(trait_methods) avm_class.register_methods(trait_methods)
assert constants is None
assert len(classes) == class_count assert len(classes) == class_count
self._classes_by_name = dict((c.name, c) for c in classes) self._classes_by_name = dict((c.name, c) for c in classes)
@ -338,8 +357,10 @@ class SWFInterpreter(object):
u30() # cinit u30() # cinit
trait_count = u30() trait_count = u30()
for _c2 in range(trait_count): for _c2 in range(trait_count):
trait_methods = parse_traits_info() trait_methods, trait_constants = parse_traits_info()
avm_class.register_methods(trait_methods) avm_class.register_methods(trait_methods)
if trait_constants:
avm_class.constants.update(trait_constants)
# Scripts # Scripts
script_count = u30() script_count = u30()
@ -633,9 +654,11 @@ class SWFInterpreter(object):
break break
else: else:
scope = avm_class.variables scope = avm_class.variables
# I cannot find where static variables are initialized
# so let's just return None if mname in scope:
res = scope.get(mname) res = scope[mname]
else:
res = avm_class.constants[mname]
stack.append(res) stack.append(res)
elif opcode == 97: # setproperty elif opcode == 97: # setproperty
index = u30() index = u30()