浏览代码

[swfinterp] Implement charCodeAt

Philipp Hagemeister 10 年之前
父节点
当前提交
33a266f4ba
共有 2 个文件被更改,包括 36 次插入1 次删除
  1. 11 0
      test/swftests/StringCharCodeAt.as
  2. 25 1
      youtube_dl/swfinterp.py

+ 11 - 0
test/swftests/StringCharCodeAt.as

@@ -0,0 +1,11 @@
+// input: []
+// output: 9897
+
+package {
+public class StringCharCodeAt {
+    public static function main():int{
+        var s:String = "abc";
+        return s.charCodeAt(1) * 100 + s.charCodeAt();
+    }
+}
+}

+ 25 - 1
youtube_dl/swfinterp.py

@@ -411,7 +411,9 @@ class SWFInterpreter(object):
                 self._classes_by_name, avm_class.variables])
             while True:
                 opcode = _read_byte(coder)
-                if opcode == 16:  # jump
+                if opcode == 9:  # label
+                    pass  # Spec says: "Do nothing."
+                elif opcode == 16:  # jump
                     offset = s24()
                     coder.seek(coder.tell() + offset)
                 elif opcode == 17:  # iftrue
@@ -436,6 +438,12 @@ class SWFInterpreter(object):
                     value1 = stack.pop()
                     if value2 != value1:
                         coder.seek(coder.tell() + offset)
+                elif opcode == 21:  # iflt
+                    offset = s24()
+                    value2 = stack.pop()
+                    value1 = stack.pop()
+                    if value1 < value2:
+                        coder.seek(coder.tell() + offset)
                 elif opcode == 32:  # pushnull
                     stack.append(None)
                 elif opcode == 33:  # pushundefined
@@ -516,6 +524,13 @@ class SWFInterpreter(object):
                                 res = obj.split(args[0])
                             stack.append(res)
                             continue
+                        elif mname == 'charCodeAt':
+                            assert len(args) <= 1
+                            idx = 0 if len(args) == 0 else args[0]
+                            assert isinstance(idx, int)
+                            res = ord(obj[idx])
+                            stack.append(res)
+                            continue
                     elif isinstance(obj, list):
                         if mname == 'slice':
                             assert len(args) == 1
@@ -687,6 +702,11 @@ class SWFInterpreter(object):
                     value1 = stack.pop()
                     res = value1 - value2
                     stack.append(res)
+                elif opcode == 162:  # multiply
+                    value2 = stack.pop()
+                    value1 = stack.pop()
+                    res = value1 * value2
+                    stack.append(res)
                 elif opcode == 164:  # modulo
                     value2 = stack.pop()
                     value1 = stack.pop()
@@ -702,6 +722,10 @@ class SWFInterpreter(object):
                     value1 = stack.pop()
                     result = value1 >= value2
                     stack.append(result)
+                elif opcode == 192:  # increment_i
+                    value = stack.pop()
+                    assert isinstance(value, int)
+                    stack.append(value + 1)
                 elif opcode == 208:  # getlocal_0
                     stack.append(registers[0])
                 elif opcode == 209:  # getlocal_1