[pypy-svn] r55569 - pypy/branch/js-refactoring/pypy/lang/js

fijal at codespeak.net fijal at codespeak.net
Wed Jun 4 19:24:28 CEST 2008


Author: fijal
Date: Wed Jun  4 19:24:27 2008
New Revision: 55569

Modified:
   pypy/branch/js-refactoring/pypy/lang/js/baseop.py
   pypy/branch/js-refactoring/pypy/lang/js/interpreter.py
   pypy/branch/js-refactoring/pypy/lang/js/jscode.py
   pypy/branch/js-refactoring/pypy/lang/js/jsobj.py
   pypy/branch/js-refactoring/pypy/lang/js/operations.py
Log:
* Make annotator happier by supporting different emit_xxx
* Revert 55548, hack differently
* Minor translation fixes


Modified: pypy/branch/js-refactoring/pypy/lang/js/baseop.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/baseop.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/baseop.py	Wed Jun  4 19:24:27 2008
@@ -7,6 +7,7 @@
 from pypy.rlib.rarithmetic import r_uint, intmask, INFINITY, NAN, ovfcheck,\
      isnan, isinf
 from pypy.lang.js.execution import ThrowException, JsTypeError
+import math
 
 def plus(ctx, nleft, nright):
     if isinstance(nleft, W_String) or isinstance(nright, W_String):
@@ -59,7 +60,7 @@
 def mod(ctx, nleft, nright): # XXX this one is really not following spec
     fleft = nleft.ToNumber(ctx)
     fright = nright.ToNumber(ctx)
-    return W_FloatNumber(fleft % fright)
+    return W_FloatNumber(math.fmod(fleft, fright))
 
 def division(ctx, nleft, nright):
     # XXX optimise for ints and floats

Modified: pypy/branch/js-refactoring/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/interpreter.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/interpreter.py	Wed Jun  4 19:24:27 2008
@@ -11,7 +11,8 @@
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.streamio import open_file_as_stream
 from pypy.lang.js.jscode import JsCode
-from pypy.rlib.rarithmetic import NAN, INFINITY, isnan, isinf
+from pypy.rlib.rarithmetic import NAN, INFINITY, isnan, isinf, r_uint
+from pypy.rlib.objectmodel import specialize
 
 ASTBUILDER = ASTBuilder()
 
@@ -342,14 +343,15 @@
     mytype = 'string'
 
 
-def get_value_of(type, ctx):
+ at specialize.memo()
+def get_value_of(type):
     class W_ValueValueOf(W_NewBuiltin):
         "this is the valueOf function for objects with Value"
         def Call(self, ctx, args=[], this=None):
             if type != this.Class:
                 raise JsTypeError('%s.prototype.valueOf called with incompatible type' % self.type())
             return this.Value
-    return W_ValueValueOf(ctx)
+    return W_ValueValueOf
 
 class W_CharAt(W_NewBuiltin):
     def Call(self, ctx, args=[], this=None):
@@ -463,13 +465,13 @@
 def pypy_repr(ctx, repr, w_arg):
     return W_String(w_arg.__class__.__name__)
 
+def put_values(ctx, obj, dictvalues):
+    for key,value in dictvalues.iteritems():
+        obj.Put(ctx, key, value)
+
 class Interpreter(object):
     """Creates a js interpreter"""
-    def __init__(self):
-        def put_values(obj, dictvalues):
-            for key,value in dictvalues.iteritems():
-                obj.Put(ctx, key, value)
-        
+    def __init__(self):        
         allon = DE | DD | RO
         w_Global = W_Object(Class="global")
         
@@ -494,7 +496,7 @@
         
         toString = W_ToString(ctx)
         
-        put_values(w_ObjPrototype, {
+        put_values(ctx, w_ObjPrototype, {
             'constructor': w_Object,
             '__proto__': w_FncPrototype,
             'toString': toString,
@@ -506,7 +508,7 @@
         })
         
         #properties of the function prototype
-        put_values(w_FncPrototype, {
+        put_values(ctx, w_FncPrototype, {
             'constructor': w_Function,
             '__proto__': w_FncPrototype,
             'toString': W_FToString(ctx),
@@ -522,11 +524,11 @@
         w_BoolPrototype = create_object(ctx, 'Object', Value=newbool(False))
         w_BoolPrototype.Class = 'Boolean'
         
-        put_values(w_BoolPrototype, {
+        put_values(ctx, w_BoolPrototype, {
             'constructor': w_FncPrototype,
             '__proto__': w_ObjPrototype,
             'toString': W_BooleanValueToString(ctx),
-            'valueOf': get_value_of('Boolean', ctx),
+            'valueOf': get_value_of('Boolean')(ctx),
         })
 
         w_Boolean.Put(ctx, 'prototype', w_BoolPrototype, flags = allon)
@@ -539,14 +541,14 @@
 
         w_NumPrototype = create_object(ctx, 'Object', Value=W_FloatNumber(0.0))
         w_NumPrototype.Class = 'Number'
-        put_values(w_NumPrototype, {
+        put_values(ctx, w_NumPrototype, {
             'constructor': w_Number,
             '__proto__': w_empty_fun,
             'toString': W_NumberValueToString(ctx),
-            'valueOf': get_value_of('Number', ctx),
+            'valueOf': get_value_of('Number')(ctx),
         })
 
-        put_values(w_Number, {
+        put_values(ctx, w_Number, {
             'constructor': w_FncPrototype,
             'prototype': w_NumPrototype,
             '__proto__': w_empty_fun,
@@ -570,11 +572,11 @@
         w_StrPrototype = create_object(ctx, 'Object', Value=W_String(''))
         w_StrPrototype.Class = 'String'
         
-        put_values(w_StrPrototype, {
+        put_values(ctx, w_StrPrototype, {
             'constructor': w_FncPrototype,
             '__proto__': w_StrPrototype,
             'toString': W_StringValueToString(ctx),
-            'valueOf': get_value_of('String', ctx),
+            'valueOf': get_value_of('String')(ctx),
             'charAt': W_CharAt(ctx),
             'concat': W_Concat(ctx),
             'indexOf': W_IndexOf(ctx),
@@ -590,7 +592,7 @@
         w_arr_join = W_ArrayJoin(ctx)
         w_arr_join.Put(ctx, 'length', W_IntNumber(1), flags=allon)
         
-        put_values(w_ArrPrototype, {
+        put_values(ctx, w_ArrPrototype, {
             'constructor': w_FncPrototype,
             '__proto__': w_ArrPrototype,
             'toString': W_ArrayToString(ctx),

Modified: pypy/branch/js-refactoring/pypy/lang/js/jscode.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/jscode.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/jscode.py	Wed Jun  4 19:24:27 2008
@@ -84,6 +84,7 @@
         self.has_labels = True
         self.startlooplabel = []
         self.endlooplabel = []
+        self.stack = []
 
     def emit_label(self, num = -1):
         if num == -1:
@@ -122,15 +123,21 @@
         self.emit('JUMP', self.startlooplabel[-1])
 
     def emit(self, operation, *args):
-        opcode = None
-        for name, opcodeclass in opcode_unrolling:
-            if operation == name:
-                opcode = opcodeclass(*args)
-                self.opcodes.append(opcode)
-                return opcode
-        raise ValueError("Unknown opcode %s" % (operation,))
+        opcode = getattr(opcodes, operation)(*args)
+        self.opcodes.append(opcode)
+        return opcode
     emit._annspecialcase_ = 'specialize:arg(1)'
 
+    def emit_store(self, operation, identifier):
+        opcode = store_opcodes[operation](identifier)
+        self.opcodes.append(opcode)
+        return opcode
+
+    def emit_store_member(self, operation):
+        opcode = store_member_opcodes[operation]()
+        self.opcodes.append(opcode)
+        return opcode        
+
     def run(self, ctx, check_stack=True, retlast=False):
         if self.has_labels:
             self.remove_labels()
@@ -222,8 +229,9 @@
         s5 = stack.pop().ToInt32(ctx)
         s6 = stack.pop().ToInt32(ctx)
         stack.append(self.operation(ctx, s5, s6))
-    
-    def operation(self, ctx, op1, op2):
+
+    @staticmethod
+    def operation(ctx, op1, op2):
         raise NotImplementedError
 
 class BaseBinaryOperation(Opcode):
@@ -563,7 +571,7 @@
         left = stack.pop()
         elem = stack.pop()
         value = stack.pop()
-        name = elem.ToString()
+        name = elem.ToString(ctx)
         value = self.operation(ctx, left, name, value)
         left.ToObject(ctx).Put(ctx, name, value)
         stack.append(value)
@@ -903,6 +911,8 @@
         obj = stack.pop().ToObject(ctx)
         stack.append(newbool(obj.Delete(what)))
 
+# different opcode mappings, to make annotator happy
+
 OpcodeMap = {}
 
 for name, value in locals().items():
@@ -910,3 +920,16 @@
         OpcodeMap[name] = value
 
 opcode_unrolling = unrolling_iterable(OpcodeMap.items())
+
+class Opcodes:
+    pass
+
+opcodes = Opcodes()
+store_opcodes = {}
+store_member_opcodes = {}
+for name, value in OpcodeMap.items():
+    if name.startswith('STORE_MEMBER'):
+        store_member_opcodes[name] = value
+    elif name.startswith('STORE'):
+        store_opcodes[name] = value
+    setattr(opcodes, name, value)

Modified: pypy/branch/js-refactoring/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/jsobj.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/jsobj.py	Wed Jun  4 19:24:27 2008
@@ -29,7 +29,7 @@
     #def GetValue(self):
     #    return self
 
-    def ToBoolean(self, ctx):
+    def ToBoolean(self):
         raise NotImplementedError(self.__class__)
 
     def ToPrimitive(self, ctx, hint=""):
@@ -358,7 +358,6 @@
 
 class W_Boolean(W_Primitive):
     def __init__(self, boolval):
-        W_Primitive.__init__(self)
         self.boolval = bool(boolval)
     
     def ToObject(self, ctx):
@@ -492,7 +491,9 @@
 
         res = str(self.floatval)
         if (res[-3] == '+' or res[-3] == '-') and res[-2] == '0':
-            res = res[:-2] + res[-1]
+            cut = len(res) - 2
+            assert cut >= 0
+            res = res[:cut] + res[-1]
         return res
     
     def ToBoolean(self):

Modified: pypy/branch/js-refactoring/pypy/lang/js/operations.py
==============================================================================
--- pypy/branch/js-refactoring/pypy/lang/js/operations.py	(original)
+++ pypy/branch/js-refactoring/pypy/lang/js/operations.py	Wed Jun  4 19:24:27 2008
@@ -13,7 +13,6 @@
 from pypy.lang.js.jscode import JsCode, JsFunction
 from constants import unescapedict
 from pypy.rlib.unroll import unrolling_iterable
-from pypy.rlib.objectmodel import specialize
 
 import sys
 import os
@@ -120,14 +119,14 @@
             element.emit(bytecode)
         bytecode.emit('LOAD_ARRAY', len(self.nodes))
 
- at specialize.memo()
-def _get_name(prefix, operand):
-    addoper = OPERANDS[operand]
-    if addoper:
-        addoper = '_' + prefix.upper() + addoper
-    else:
-        addoper = ''
-    return addoper
+class Assignment(Expression):
+    def _get_name(self):
+        addoper = OPERANDS[self.operand]
+        if addoper:
+            addoper = '_' + self.prefix.upper() + addoper
+        else:
+            addoper = ''
+        return addoper
 
 OPERANDS = {
     '='  : '',
@@ -156,32 +155,21 @@
         elif self.atype == '--':
             bytecode.emit('DECR')
 
-def new_simple_assignment(operand, prefix=''):
-    bytecode_name = 'STORE' + _get_name(prefix, operand)
-    class SimpleAssignment(Expression):
-        def __init__(self, pos, left, right):
-            self.identifier = left.get_literal()
-            self.right = right
-            self.pos = pos
+class SimpleAssignment(Assignment):
+    def __init__(self, pos, left, right, operand, prefix=''):
+        self.identifier = left.get_literal()
+        self.right = right
+        self.pos = pos
+        self.operand = operand
+        self.prefix = prefix
 
-        def emit(self, bytecode):
-            if self.right is not None:
-                self.right.emit(bytecode)
-            bytecode.emit(bytecode_name, self.identifier)
-    return SimpleAssignment
-
-SIMPLE_ASSIGNMENTS = {}
-
-for operand in OPERANDS:
-    for prefix in ['', 'pre', 'post']:
-        SIMPLE_ASSIGNMENTS[(operand, prefix)] = new_simple_assignment(operand, prefix)
-
-def SimpleAssignment(pos, left, right, operand, prefix=''):
-    return SIMPLE_ASSIGNMENTS[(operand, prefix)](pos, left, right)
-
-# XXX VariableAssignment is not used at all, even should explode when
-#     translating, fix it with STORE_FAST and LOAD_FAST
-class VariableAssignment(Expression):
+    def emit(self, bytecode):
+        if self.right is not None:
+            self.right.emit(bytecode)
+        bytecode_name = 'STORE' + self._get_name()
+        bytecode.emit_store(bytecode_name, self.identifier)
+
+class VariableAssignment(Assignment):
     def __init__(self, pos, left, right, operand):
         xxx # shall never land here for now
         self.identifier = left.identifier
@@ -194,60 +182,40 @@
         self.right.emit(bytecode)
         bytecode.emit('STORE_VAR', self.depth, self.identifier)
 
-def new_member_assignment(operand, prefix):
-    bytecode_name = 'STORE_MEMBER' + _get_name(prefix, operand)
-    class MemberAssignment(Expression):
-        def __init__(self, pos, what, item, right):
-            # XXX we can optimise here what happens if what is identifier,
-            #     but let's leave it alone for now
-            self.pos = pos
-            self.what = what
-            self.item = item
-            self.right = right
+class MemberAssignment(Assignment):
+    def __init__(self, pos, what, item, right, operand, prefix=''):
+        # XXX we can optimise here what happens if what is identifier,
+        #     but let's leave it alone for now
+        self.pos = pos
+        self.what = what
+        self.item = item
+        self.right = right
+        self.operand = operand
+        self.prefix = prefix
 
-        def emit(self, bytecode):
-            if self.right is not None:
-                self.right.emit(bytecode)
-            self.item.emit(bytecode)
-            self.what.emit(bytecode)
-            bytecode.emit(bytecode_name)
-    return MemberAssignment
-
-MEMBER_ASSIGNMENTS = {}
-
-for operand in OPERANDS:
-    for prefix in ['', 'pre', 'post']:
-        MEMBER_ASSIGNMENTS[(operand, prefix)] = new_member_assignment(operand, prefix)
-
-def MemberAssignment(pos, what, item, right, operand, prefix=''):
-    return MEMBER_ASSIGNMENTS[(operand, prefix)](pos, what, item, right)
-
-def new_member_dot_assignment(operand, prefix):
-    bytecode_name = 'STORE_MEMBER' + _get_name(prefix, operand)
-    class MemberDotAssignment(Expression):
-        def __init__(self, pos, what, name, right):
-            self.pos = pos
-            self.what = what
-            self.itemname = name
-            self.right = right
+    def emit(self, bytecode):
+        if self.right is not None:
+            self.right.emit(bytecode)
+        self.item.emit(bytecode)
+        self.what.emit(bytecode)
+        bytecode.emit_store_member('STORE_MEMBER' + self._get_name())
 
-        def emit(self, bytecode):
-            # XXX optimize this a bit
-            if self.right is not None:
-                self.right.emit(bytecode)
-            bytecode.emit('LOAD_STRINGCONSTANT', self.itemname)
-            self.what.emit(bytecode)
-            bytecode.emit(bytecode_name)
-    return MemberDotAssignment
-
-MEMBER_DOT_ASSIGNMENTS = {}
-
-for operand in OPERANDS:
-    for prefix in ['', 'pre', 'post']:
-        MEMBER_DOT_ASSIGNMENTS[(operand, prefix)] = new_member_dot_assignment(operand, prefix)
+class MemberDotAssignment(Assignment):
+    def __init__(self, pos, what, name, right, operand, prefix=''):
+        self.pos = pos
+        self.what = what
+        self.itemname = name
+        self.right = right
+        self.operand = operand
+        self.prefix = prefix
 
-def MemberDotAssignment(pos, what, item, right, operand, prefix=''):
-    return MEMBER_DOT_ASSIGNMENTS[(operand, prefix)](pos, what, item, right)
+    def emit(self, bytecode):
+        # XXX optimize this a bit
+        if self.right is not None:
+            self.right.emit(bytecode)
+        bytecode.emit('LOAD_STRINGCONSTANT', self.itemname)
+        self.what.emit(bytecode)
+        bytecode.emit_store_member('STORE_MEMBER' + self._get_name())
 
 class Block(Statement):
     def __init__(self, pos, nodes):



More information about the Pypy-commit mailing list