[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