Author: Stephan <[email protected]>
Branch:
Changeset: r91:fecdd3a25f53
Date: 2011-05-27 14:03 +0200
http://bitbucket.org/pypy/lang-js/changeset/fecdd3a25f53/
Log: moved opcodes from jscode to opcodes
diff --git a/js/jscode.py b/js/jscode.py
--- a/js/jscode.py
+++ b/js/jscode.py
@@ -1,18 +1,10 @@
+from pypy.rlib.jit import hint
+from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.jit import JitDriver, purefunction
-from js.jsobj import W_IntNumber, W_FloatNumber, W_String,\
- W_Array, W_PrimitiveObject, ActivationObject,\
- create_object, W_Object, w_Undefined, newbool,\
- w_True, w_False, W_List, w_Null, W_Iterator, W_Root
-import js.jsobj as jsobj
from js.execution import JsTypeError, ReturnException, ThrowException
-from pypy.rlib.unroll import unrolling_iterable
-from js.baseop import plus, sub, compare, AbstractEC, StrictEC,\
- compare_e, increment, decrement, commonnew, mult, division, uminus, mod
-from pypy.rlib.jit import hint
-from pypy.rlib.rarithmetic import intmask
-from pypy.rlib.objectmodel import we_are_translated
-
-from pypy.rlib.jit import JitDriver, purefunction
+from js.opcodes import opcodes, POP, LABEL, BaseJump, WITH_START, WITH_END
+from js.jsobj import W_Root, W_String
def get_printable_location(pc, jsfunction):
return str(jsfunction.opcodes[pc])
@@ -239,630 +231,3 @@
if check_stack:
stack.check()
return stack.top()
-
-class Opcode(object):
- def __init__(self):
- pass
-
- def eval(self, ctx, stack):
- """ Execute in context ctx
- """
- raise NotImplementedError
-
- def __repr__(self):
- return self.__class__.__name__
-
-class BaseBinaryComparison(Opcode):
- def eval(self, ctx, stack):
- s4 = stack.pop()
- s2 = stack.pop()
- stack.append(self.decision(ctx, s2, s4))
-
- def decision(self, ctx, op1, op2):
- raise NotImplementedError
-
-class BaseBinaryBitwiseOp(Opcode):
- def eval(self, ctx, stack):
- s5 = stack.pop().ToInt32(ctx)
- s6 = stack.pop().ToInt32(ctx)
- stack.append(self.operation(ctx, s5, s6))
-
- def operation(self, ctx, op1, op2):
- raise NotImplementedError
-
-class BaseBinaryOperation(Opcode):
- def eval(self, ctx, stack):
- right = stack.pop()
- left = stack.pop()
- stack.append(self.operation(ctx, left, right))
-
-class BaseUnaryOperation(Opcode):
- pass
-
-class Undefined(Opcode):
- def eval(self, ctx, stack):
- stack.append(w_Undefined)
-
-class LOAD_INTCONSTANT(Opcode):
- _immutable_fields_ = ['w_intvalue']
- def __init__(self, value):
- self.w_intvalue = W_IntNumber(int(value))
-
- def eval(self, ctx, stack):
- stack.append(self.w_intvalue)
-
- def __repr__(self):
- return 'LOAD_INTCONSTANT %s' % (self.w_intvalue.intval,)
-
-class LOAD_BOOLCONSTANT(Opcode):
- def __init__(self, value):
- self.boolval = value
-
- def eval(self, ctx, stack):
- stack.append(newbool(self.boolval))
-
-class LOAD_FLOATCONSTANT(Opcode):
- def __init__(self, value):
- self.w_floatvalue = W_FloatNumber(float(value))
-
- def eval(self, ctx, stack):
- stack.append(self.w_floatvalue)
-
- def __repr__(self):
- return 'LOAD_FLOATCONSTANT %s' % (self.w_floatvalue.floatval,)
-
-class LOAD_STRINGCONSTANT(Opcode):
- def __init__(self, value):
- self.w_stringvalue = W_String(value)
-
- def eval(self, ctx, stack):
- stack.append(self.w_stringvalue)
-
- #def get_literal(self, ctx):
- # return W_String(self.strval).ToString(ctx)
-
- def __repr__(self):
- return 'LOAD_STRINGCONSTANT "%s"' % (self.w_stringvalue.strval,)
-
-class LOAD_UNDEFINED(Opcode):
- def eval(self, ctx, stack):
- stack.append(w_Undefined)
-
-class LOAD_NULL(Opcode):
- def eval(self, ctx, stack):
- stack.append(w_Null)
-
-class LOAD_VARIABLE(Opcode):
- _immutable_fields_ = ['identifier']
- def __init__(self, identifier):
- self.identifier = identifier
-
- def eval(self, ctx, stack):
- stack.append(ctx.resolve_identifier(ctx, self.identifier))
-
- def __repr__(self):
- return 'LOAD_VARIABLE "%s"' % (self.identifier,)
-
-class LOAD_REALVAR(Opcode):
- def __init__(self, depth, identifier):
- self.depth = depth
- self.identifier = identifier
-
- def eval(self, ctx, stack):
- raise NotImplementedError()
- # XXX
- # scope = ctx.scope[self.depth]
- # stack.append(scope.Get(ctx, self.identifier))
- #stack.append(W_Reference(self.identifier, scope))
-
- def __repr__(self):
- return 'LOAD_VARIABLE "%s"' % (self.identifier,)
-
-class LOAD_ARRAY(Opcode):
- def __init__(self, counter):
- self.counter = counter
-
- def eval(self, ctx, stack):
- proto = ctx.get_global().Get(ctx, 'Array').Get(ctx, 'prototype')
- array = W_Array(ctx, Prototype=proto, Class = proto.Class)
- for i in range(self.counter):
- array.Put(ctx, str(self.counter - i - 1), stack.pop())
- stack.append(array)
-
- def __repr__(self):
- return 'LOAD_ARRAY %d' % (self.counter,)
-
-class LOAD_LIST(Opcode):
- def __init__(self, counter):
- self.counter = counter
-
- def eval(self, ctx, stack):
- list_w = stack.pop_n(self.counter)
- stack.append(W_List(list_w))
-
- def __repr__(self):
- return 'LOAD_LIST %d' % (self.counter,)
-
-class LOAD_FUNCTION(Opcode):
- def __init__(self, funcobj):
- self.funcobj = funcobj
-
- def eval(self, ctx, stack):
- proto = ctx.get_global().Get(ctx, 'Function').Get(ctx, 'prototype')
- w_func = W_Object(ctx=ctx, Prototype=proto, Class='Function',
- callfunc=self.funcobj)
- w_func.Put(ctx, 'length', W_IntNumber(len(self.funcobj.params)))
- w_obj = create_object(ctx, 'Object')
- w_obj.Put(ctx, 'constructor', w_func, flags = jsobj.DE)
- w_func.Put(ctx, 'prototype', w_obj)
- stack.append(w_func)
-
- def __repr__(self):
- return 'LOAD_FUNCTION' # XXX
-
-# class STORE_VAR(Opcode):
-# def __init__(self, depth, name):
-# self.name = name
-# self.depth = depth
-
-# def eval(self, ctx, stack):
-# value = stack[-1]
-# ctx.scope[self.depth].Put(ctx, self.name, value)
-
-# def __repr__(self):
-# return 'STORE_VAR "%s"' % self.name
-
-class LOAD_OBJECT(Opcode):
- def __init__(self, counter):
- self.counter = counter
-
- def eval(self, ctx, stack):
- w_obj = create_object(ctx, 'Object')
- for _ in range(self.counter):
- name = stack.pop().ToString(ctx)
- w_elem = stack.pop()
- w_obj.Put(ctx, name, w_elem)
- stack.append(w_obj)
-
- def __repr__(self):
- return 'LOAD_OBJECT %d' % (self.counter,)
-
-class LOAD_MEMBER(Opcode):
- def eval(self, ctx, stack):
- w_obj = stack.pop().ToObject(ctx)
- name = stack.pop().ToString(ctx)
- stack.append(w_obj.Get(ctx, name))
-
-class COMMA(BaseUnaryOperation):
- def eval(self, ctx, stack):
- one = stack.pop()
- stack.pop()
- stack.append(one)
- # XXX
-
-class SUB(BaseBinaryOperation):
- def operation(self, ctx, left, right):
- return sub(ctx, left, right)
-
-class IN(BaseBinaryOperation):
- def operation(self, ctx, left, right):
- if not isinstance(right, W_Object):
- raise ThrowException(W_String("TypeError"))
- name = left.ToString(ctx)
- return newbool(right.HasProperty(name))
-
-class TYPEOF(BaseUnaryOperation):
- def eval(self, ctx, stack):
- one = stack.pop()
- stack.append(W_String(one.type()))
-
-class TYPEOF_VARIABLE(Opcode):
- def __init__(self, name):
- self.name = name
-
- def eval(self, ctx, stack):
- try:
- var = ctx.resolve_identifier(ctx, self.name)
- stack.append(W_String(var.type()))
- except ThrowException:
- stack.append(W_String('undefined'))
-
-#class Typeof(UnaryOp):
-# def eval(self, ctx):
-# val = self.expr.eval(ctx)
-# if isinstance(val, W_Reference) and val.GetBase() is None:
-# return W_String("undefined")
-# return W_String(val.GetValue().type())
-
-
-class ADD(BaseBinaryOperation):
- def operation(self, ctx, left, right):
- return plus(ctx, left, right)
-
-class BITAND(BaseBinaryBitwiseOp):
- def operation(self, ctx, op1, op2):
- return W_IntNumber(op1&op2)
-
-class BITXOR(BaseBinaryBitwiseOp):
- def operation(self, ctx, op1, op2):
- return W_IntNumber(op1^op2)
-
-class BITOR(BaseBinaryBitwiseOp):
- def operation(self, ctx, op1, op2):
- return W_IntNumber(op1|op2)
-
-class BITNOT(BaseUnaryOperation):
- def eval(self, ctx, stack):
- op = stack.pop().ToInt32(ctx)
- stack.append(W_IntNumber(~op))
-
-class URSH(BaseBinaryBitwiseOp):
- def eval(self, ctx, stack):
- op2 = stack.pop().ToUInt32(ctx)
- op1 = stack.pop().ToUInt32(ctx)
- # XXX check if it could fit into int
- stack.append(W_FloatNumber(op1 >> (op2 & 0x1F)))
-
-class RSH(BaseBinaryBitwiseOp):
- def eval(self, ctx, stack):
- op2 = stack.pop().ToUInt32(ctx)
- op1 = stack.pop().ToInt32(ctx)
- stack.append(W_IntNumber(op1 >> intmask(op2 & 0x1F)))
-
-class LSH(BaseBinaryBitwiseOp):
- def eval(self, ctx, stack):
- op2 = stack.pop().ToUInt32(ctx)
- op1 = stack.pop().ToInt32(ctx)
- stack.append(W_IntNumber(op1 << intmask(op2 & 0x1F)))
-
-class MUL(BaseBinaryOperation):
- def operation(self, ctx, op1, op2):
- return mult(ctx, op1, op2)
-
-class DIV(BaseBinaryOperation):
- def operation(self, ctx, op1, op2):
- return division(ctx, op1, op2)
-
-class MOD(BaseBinaryOperation):
- def operation(self, ctx, op1, op2):
- return mod(ctx, op1, op2)
-
-class UPLUS(BaseUnaryOperation):
- def eval(self, ctx, stack):
- if isinstance(stack.top(), W_IntNumber):
- return
- if isinstance(stack.top(), W_FloatNumber):
- return
- stack.append(W_FloatNumber(stack.pop().ToNumber(ctx)))
-
-class UMINUS(BaseUnaryOperation):
- def eval(self, ctx, stack):
- stack.append(uminus(stack.pop(), ctx))
-
-class NOT(BaseUnaryOperation):
- def eval(self, ctx, stack):
- stack.append(newbool(not stack.pop().ToBoolean()))
-
-class INCR(BaseUnaryOperation):
- def eval(self, ctx, stack):
- value = stack.pop()
- newvalue = increment(ctx, value)
- stack.append(newvalue)
-
-class DECR(BaseUnaryOperation):
- def eval(self, ctx, stack):
- value = stack.pop()
- newvalue = decrement(ctx, value)
- stack.append(newvalue)
-
-class GT(BaseBinaryComparison):
- def decision(self, ctx, op1, op2):
- return newbool(compare(ctx, op1, op2))
-
-class GE(BaseBinaryComparison):
- def decision(self, ctx, op1, op2):
- return newbool(compare_e(ctx, op1, op2))
-
-class LT(BaseBinaryComparison):
- def decision(self, ctx, op1, op2):
- return newbool(compare(ctx, op2, op1))
-
-class LE(BaseBinaryComparison):
- def decision(self, ctx, op1, op2):
- return newbool(compare_e(ctx, op2, op1))
-
-class EQ(BaseBinaryComparison):
- def decision(self, ctx, op1, op2):
- return newbool(AbstractEC(ctx, op1, op2))
-
-class NE(BaseBinaryComparison):
- def decision(self, ctx, op1, op2):
- return newbool(not AbstractEC(ctx, op1, op2))
-
-class IS(BaseBinaryComparison):
- def decision(self, ctx, op1, op2):
- return newbool(StrictEC(ctx, op1, op2))
-
-class ISNOT(BaseBinaryComparison):
- def decision(self, ctx, op1, op2):
- return newbool(not StrictEC(ctx, op1, op2))
-
-class STORE_MEMBER(Opcode):
- def eval(self, ctx, stack):
- left = stack.pop()
- member = stack.pop()
- value = stack.pop()
- name = member.ToString(ctx)
- left.ToObject(ctx).Put(ctx, name, value)
- stack.append(value)
-
-class STORE(Opcode):
- _immutable_fields_ = ['name']
- def __init__(self, name):
- self.name = name
-
- def eval(self, ctx, stack):
- value = stack.top()
- ctx.assign(self.name, value)
-
- def __repr__(self):
- return '%s "%s"' % (self.__class__.__name__, self.name)
-
-class LABEL(Opcode):
- def __init__(self, num):
- self.num = num
-
- def __repr__(self):
- return 'LABEL %d' % (self.num,)
-
-class BaseJump(Opcode):
- _immutable_fields_ = ['where']
- def __init__(self, where):
- self.where = where
- self.decision = False
-
- def do_jump(self, stack, pos):
- return 0
-
- def __repr__(self):
- return '%s %d' % (self.__class__.__name__, self.where)
-
-class JUMP(BaseJump):
- def eval(self, ctx, stack):
- pass
-
- def do_jump(self, stack, pos):
- return self.where
-
-class BaseIfJump(BaseJump):
- def eval(self, ctx, stack):
- value = stack.pop()
- self.decision = value.ToBoolean()
-
-class BaseIfNopopJump(BaseJump):
- def eval(self, ctx, stack):
- value = stack.top()
- self.decision = value.ToBoolean()
-
-class JUMP_IF_FALSE(BaseIfJump):
- def do_jump(self, stack, pos):
- if self.decision:
- return pos + 1
- return self.where
-
-class JUMP_IF_FALSE_NOPOP(BaseIfNopopJump):
- def do_jump(self, stack, pos):
- if self.decision:
- stack.pop()
- return pos + 1
- return self.where
-
-class JUMP_IF_TRUE(BaseIfJump):
- def do_jump(self, stack, pos):
- if self.decision:
- return self.where
- return pos + 1
-
-class JUMP_IF_TRUE_NOPOP(BaseIfNopopJump):
- def do_jump(self, stack, pos):
- if self.decision:
- return self.where
- stack.pop()
- return pos + 1
-
-class DECLARE_FUNCTION(Opcode):
- def __init__(self, funcobj):
- self.funcobj = funcobj
-
- def eval(self, ctx, stack):
- # function declaration actyally don't run anything
- proto = ctx.get_global().Get(ctx, 'Function').Get(ctx, 'prototype')
- w_func = W_Object(ctx=ctx, Prototype=proto, Class='Function',
callfunc=self.funcobj)
- w_func.Put(ctx, 'length', W_IntNumber(len(self.funcobj.params)))
- w_obj = create_object(ctx, 'Object')
- w_obj.Put(ctx, 'constructor', w_func, flags = jsobj.DE)
- w_func.Put(ctx, 'prototype', w_obj)
- if self.funcobj.name is not None:
- ctx.scope[-1].Put(ctx, self.funcobj.name, w_func)
-
- def __repr__(self):
- funcobj = self.funcobj
- if funcobj.name is None:
- name = ""
- else:
- name = funcobj.name + " "
- codestr = '\n'.join([' %r' % (op,) for op in funcobj.opcodes])
- return 'DECLARE_FUNCTION %s%r [\n%s\n]' % (name, funcobj.params,
codestr)
-
-class DECLARE_VAR(Opcode):
- def __init__(self, name):
- self.name = name
-
- def eval(self, ctx, stack):
- ctx.scope[-1].Put(ctx, self.name, w_Undefined, flags = jsobj.DD)
-
- def __repr__(self):
- return 'DECLARE_VAR "%s"' % (self.name,)
-
-class RETURN(Opcode):
- def eval(self, ctx, stack):
- raise ReturnException(stack.pop())
-
-class POP(Opcode):
- def eval(self, ctx, stack):
- stack.pop()
-
-def common_call(ctx, r1, args, this, name):
- if not isinstance(r1, W_PrimitiveObject):
- raise ThrowException(W_String("%s is not a callable
(%s)"%(r1.ToString(ctx), name)))
- try:
- res = r1.Call(ctx=ctx, args=args.tolist(), this=this)
- except JsTypeError:
- raise ThrowException(W_String("%s is not a function
(%s)"%(r1.ToString(ctx), name)))
- return res
-
-class CALL(Opcode):
- def eval(self, ctx, stack):
- r1 = stack.pop()
- args = stack.pop()
- name = r1.ToString(ctx)
- #XXX hack, this should be comming from context
- stack.append(common_call(ctx, r1, args, ctx.scope[-1], name))
-
-class CALL_METHOD(Opcode):
- def eval(self, ctx, stack):
- method = stack.pop()
- what = stack.pop().ToObject(ctx)
- args = stack.pop()
- name = method.ToString(ctx)
- r1 = what.Get(ctx, name)
- stack.append(common_call(ctx, r1, args, what, name))
-
-class DUP(Opcode):
- def eval(self, ctx, stack):
- stack.append(stack.top())
-
-class THROW(Opcode):
- def eval(self, ctx, stack):
- val = stack.pop()
- raise ThrowException(val)
-
-class TRYCATCHBLOCK(Opcode):
- def __init__(self, tryfunc, catchparam, catchfunc, finallyfunc):
- self.tryfunc = tryfunc
- self.catchfunc = catchfunc
- self.catchparam = catchparam
- self.finallyfunc = finallyfunc
-
- def eval(self, ctx, stack):
- try:
- try:
- self.tryfunc.run(ctx)
- except ThrowException, e:
- if self.catchfunc is not None:
- # XXX just copied, I don't know if it's right
- obj = W_Object()
- obj.Put(ctx, self.catchparam, e.exception)
- ctx.push_object(obj)
- try:
- self.catchfunc.run(ctx)
- finally:
- ctx.pop_object()
- if self.finallyfunc is not None:
- self.finallyfunc.run(ctx)
- if not self.catchfunc:
- raise
- except ReturnException:
- # we run finally block here and re-raise the exception
- if self.finallyfunc is not None:
- self.finallyfunc.run(ctx)
- raise
-
- def __repr__(self):
- return "TRYCATCHBLOCK" # XXX shall we add stuff here???
-
-class NEW(Opcode):
- def eval(self, ctx, stack):
- y = stack.pop()
- x = stack.pop()
- assert isinstance(y, W_List)
- args = y.get_args()
- stack.append(commonnew(ctx, x, args))
-
-class NEW_NO_ARGS(Opcode):
- def eval(self, ctx, stack):
- x = stack.pop()
- stack.append(commonnew(ctx, x, []))
-
-# ------------ iterator support ----------------
-
-class LOAD_ITERATOR(Opcode):
- def eval(self, ctx, stack):
- obj = stack.pop().ToObject(ctx)
- props = [prop.value for prop in obj.propdict.values() if not
prop.flags & jsobj.DE]
- stack.append(W_Iterator(props))
-
-class JUMP_IF_ITERATOR_EMPTY(BaseJump):
- def eval(self, ctx, stack):
- pass
-
- def do_jump(self, stack, pos):
- iterator = stack.top()
- assert isinstance(iterator, W_Iterator)
- if iterator.empty():
- return self.where
- return pos + 1
-
-class NEXT_ITERATOR(Opcode):
- def __init__(self, name):
- self.name = name
-
- def eval(self, ctx, stack):
- iterator = stack.top()
- assert isinstance(iterator, W_Iterator)
- ctx.assign(self.name, iterator.next())
-
-# ---------------- with support ---------------------
-
-class WITH_START(Opcode):
- def eval(self, ctx, stack):
- obj = stack.pop().ToObject(ctx)
- ctx.push_object(obj)
-
-class WITH_END(Opcode):
- def eval(self, ctx, stack):
- ctx.pop_object()
-
-# ------------------ delete -------------------------
-
-class DELETE(Opcode):
- def __init__(self, name):
- self.name = name
-
- def eval(self, ctx, stack):
- stack.append(newbool(ctx.delete_identifier(self.name)))
-
-class DELETE_MEMBER(Opcode):
- def eval(self, ctx, stack):
- what = stack.pop().ToString(ctx)
- 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():
- if name.upper() == name and type(value) == type(Opcode) and
issubclass(value, Opcode):
- 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():
- setattr(opcodes, name, value)
diff --git a/js/opcodes.py b/js/opcodes.py
new file mode 100644
--- /dev/null
+++ b/js/opcodes.py
@@ -0,0 +1,652 @@
+from js.jsobj import W_IntNumber, W_FloatNumber, W_String,\
+ W_Array, W_PrimitiveObject, ActivationObject,\
+ create_object, W_Object, w_Undefined, newbool,\
+ w_True, w_False, W_List, w_Null, W_Iterator, W_Root
+import js.jsobj as jsobj
+from js.execution import JsTypeError, ReturnException, ThrowException
+from pypy.rlib.unroll import unrolling_iterable
+from js.baseop import plus, sub, compare, AbstractEC, StrictEC,\
+ compare_e, increment, decrement, commonnew, mult, division, uminus, mod
+from pypy.rlib.rarithmetic import intmask
+
+class Opcode(object):
+ def __init__(self):
+ pass
+
+ def eval(self, ctx, stack):
+ """ Execute in context ctx
+ """
+ raise NotImplementedError
+
+ def __repr__(self):
+ return self.__class__.__name__
+
+class BaseBinaryComparison(Opcode):
+ def eval(self, ctx, stack):
+ s4 = stack.pop()
+ s2 = stack.pop()
+ stack.append(self.decision(ctx, s2, s4))
+
+ def decision(self, ctx, op1, op2):
+ raise NotImplementedError
+
+class BaseBinaryBitwiseOp(Opcode):
+ def eval(self, ctx, stack):
+ s5 = stack.pop().ToInt32(ctx)
+ s6 = stack.pop().ToInt32(ctx)
+ stack.append(self.operation(ctx, s5, s6))
+
+ def operation(self, ctx, op1, op2):
+ raise NotImplementedError
+
+class BaseBinaryOperation(Opcode):
+ def eval(self, ctx, stack):
+ right = stack.pop()
+ left = stack.pop()
+ stack.append(self.operation(ctx, left, right))
+
+class BaseUnaryOperation(Opcode):
+ pass
+
+class Undefined(Opcode):
+ def eval(self, ctx, stack):
+ stack.append(w_Undefined)
+
+class LOAD_INTCONSTANT(Opcode):
+ _immutable_fields_ = ['w_intvalue']
+ def __init__(self, value):
+ self.w_intvalue = W_IntNumber(int(value))
+
+ def eval(self, ctx, stack):
+ stack.append(self.w_intvalue)
+
+ def __repr__(self):
+ return 'LOAD_INTCONSTANT %s' % (self.w_intvalue.intval,)
+
+class LOAD_BOOLCONSTANT(Opcode):
+ def __init__(self, value):
+ self.boolval = value
+
+ def eval(self, ctx, stack):
+ stack.append(newbool(self.boolval))
+
+class LOAD_FLOATCONSTANT(Opcode):
+ def __init__(self, value):
+ self.w_floatvalue = W_FloatNumber(float(value))
+
+ def eval(self, ctx, stack):
+ stack.append(self.w_floatvalue)
+
+ def __repr__(self):
+ return 'LOAD_FLOATCONSTANT %s' % (self.w_floatvalue.floatval,)
+
+class LOAD_STRINGCONSTANT(Opcode):
+ def __init__(self, value):
+ self.w_stringvalue = W_String(value)
+
+ def eval(self, ctx, stack):
+ stack.append(self.w_stringvalue)
+
+ #def get_literal(self, ctx):
+ # return W_String(self.strval).ToString(ctx)
+
+ def __repr__(self):
+ return 'LOAD_STRINGCONSTANT "%s"' % (self.w_stringvalue.strval,)
+
+class LOAD_UNDEFINED(Opcode):
+ def eval(self, ctx, stack):
+ stack.append(w_Undefined)
+
+class LOAD_NULL(Opcode):
+ def eval(self, ctx, stack):
+ stack.append(w_Null)
+
+class LOAD_VARIABLE(Opcode):
+ _immutable_fields_ = ['identifier']
+ def __init__(self, identifier):
+ self.identifier = identifier
+
+ def eval(self, ctx, stack):
+ stack.append(ctx.resolve_identifier(ctx, self.identifier))
+
+ def __repr__(self):
+ return 'LOAD_VARIABLE "%s"' % (self.identifier,)
+
+class LOAD_REALVAR(Opcode):
+ def __init__(self, depth, identifier):
+ self.depth = depth
+ self.identifier = identifier
+
+ def eval(self, ctx, stack):
+ raise NotImplementedError()
+ # XXX
+ # scope = ctx.scope[self.depth]
+ # stack.append(scope.Get(ctx, self.identifier))
+ #stack.append(W_Reference(self.identifier, scope))
+
+ def __repr__(self):
+ return 'LOAD_VARIABLE "%s"' % (self.identifier,)
+
+class LOAD_ARRAY(Opcode):
+ def __init__(self, counter):
+ self.counter = counter
+
+ def eval(self, ctx, stack):
+ proto = ctx.get_global().Get(ctx, 'Array').Get(ctx, 'prototype')
+ array = W_Array(ctx, Prototype=proto, Class = proto.Class)
+ for i in range(self.counter):
+ array.Put(ctx, str(self.counter - i - 1), stack.pop())
+ stack.append(array)
+
+ def __repr__(self):
+ return 'LOAD_ARRAY %d' % (self.counter,)
+
+class LOAD_LIST(Opcode):
+ def __init__(self, counter):
+ self.counter = counter
+
+ def eval(self, ctx, stack):
+ list_w = stack.pop_n(self.counter)
+ stack.append(W_List(list_w))
+
+ def __repr__(self):
+ return 'LOAD_LIST %d' % (self.counter,)
+
+class LOAD_FUNCTION(Opcode):
+ def __init__(self, funcobj):
+ self.funcobj = funcobj
+
+ def eval(self, ctx, stack):
+ proto = ctx.get_global().Get(ctx, 'Function').Get(ctx, 'prototype')
+ w_func = W_Object(ctx=ctx, Prototype=proto, Class='Function',
+ callfunc=self.funcobj)
+ w_func.Put(ctx, 'length', W_IntNumber(len(self.funcobj.params)))
+ w_obj = create_object(ctx, 'Object')
+ w_obj.Put(ctx, 'constructor', w_func, flags = jsobj.DE)
+ w_func.Put(ctx, 'prototype', w_obj)
+ stack.append(w_func)
+
+ def __repr__(self):
+ return 'LOAD_FUNCTION' # XXX
+
+# class STORE_VAR(Opcode):
+# def __init__(self, depth, name):
+# self.name = name
+# self.depth = depth
+
+# def eval(self, ctx, stack):
+# value = stack[-1]
+# ctx.scope[self.depth].Put(ctx, self.name, value)
+
+# def __repr__(self):
+# return 'STORE_VAR "%s"' % self.name
+
+class LOAD_OBJECT(Opcode):
+ def __init__(self, counter):
+ self.counter = counter
+
+ def eval(self, ctx, stack):
+ w_obj = create_object(ctx, 'Object')
+ for _ in range(self.counter):
+ name = stack.pop().ToString(ctx)
+ w_elem = stack.pop()
+ w_obj.Put(ctx, name, w_elem)
+ stack.append(w_obj)
+
+ def __repr__(self):
+ return 'LOAD_OBJECT %d' % (self.counter,)
+
+class LOAD_MEMBER(Opcode):
+ def eval(self, ctx, stack):
+ w_obj = stack.pop().ToObject(ctx)
+ name = stack.pop().ToString(ctx)
+ stack.append(w_obj.Get(ctx, name))
+
+class COMMA(BaseUnaryOperation):
+ def eval(self, ctx, stack):
+ one = stack.pop()
+ stack.pop()
+ stack.append(one)
+ # XXX
+
+class SUB(BaseBinaryOperation):
+ def operation(self, ctx, left, right):
+ return sub(ctx, left, right)
+
+class IN(BaseBinaryOperation):
+ def operation(self, ctx, left, right):
+ if not isinstance(right, W_Object):
+ raise ThrowException(W_String("TypeError"))
+ name = left.ToString(ctx)
+ return newbool(right.HasProperty(name))
+
+class TYPEOF(BaseUnaryOperation):
+ def eval(self, ctx, stack):
+ one = stack.pop()
+ stack.append(W_String(one.type()))
+
+class TYPEOF_VARIABLE(Opcode):
+ def __init__(self, name):
+ self.name = name
+
+ def eval(self, ctx, stack):
+ try:
+ var = ctx.resolve_identifier(ctx, self.name)
+ stack.append(W_String(var.type()))
+ except ThrowException:
+ stack.append(W_String('undefined'))
+
+#class Typeof(UnaryOp):
+# def eval(self, ctx):
+# val = self.expr.eval(ctx)
+# if isinstance(val, W_Reference) and val.GetBase() is None:
+# return W_String("undefined")
+# return W_String(val.GetValue().type())
+
+class ADD(BaseBinaryOperation):
+ def operation(self, ctx, left, right):
+ return plus(ctx, left, right)
+
+class BITAND(BaseBinaryBitwiseOp):
+ def operation(self, ctx, op1, op2):
+ return W_IntNumber(op1&op2)
+
+class BITXOR(BaseBinaryBitwiseOp):
+ def operation(self, ctx, op1, op2):
+ return W_IntNumber(op1^op2)
+
+class BITOR(BaseBinaryBitwiseOp):
+ def operation(self, ctx, op1, op2):
+ return W_IntNumber(op1|op2)
+
+class BITNOT(BaseUnaryOperation):
+ def eval(self, ctx, stack):
+ op = stack.pop().ToInt32(ctx)
+ stack.append(W_IntNumber(~op))
+
+class URSH(BaseBinaryBitwiseOp):
+ def eval(self, ctx, stack):
+ op2 = stack.pop().ToUInt32(ctx)
+ op1 = stack.pop().ToUInt32(ctx)
+ # XXX check if it could fit into int
+ stack.append(W_FloatNumber(op1 >> (op2 & 0x1F)))
+
+class RSH(BaseBinaryBitwiseOp):
+ def eval(self, ctx, stack):
+ op2 = stack.pop().ToUInt32(ctx)
+ op1 = stack.pop().ToInt32(ctx)
+ stack.append(W_IntNumber(op1 >> intmask(op2 & 0x1F)))
+
+class LSH(BaseBinaryBitwiseOp):
+ def eval(self, ctx, stack):
+ op2 = stack.pop().ToUInt32(ctx)
+ op1 = stack.pop().ToInt32(ctx)
+ stack.append(W_IntNumber(op1 << intmask(op2 & 0x1F)))
+
+class MUL(BaseBinaryOperation):
+ def operation(self, ctx, op1, op2):
+ return mult(ctx, op1, op2)
+
+class DIV(BaseBinaryOperation):
+ def operation(self, ctx, op1, op2):
+ return division(ctx, op1, op2)
+
+class MOD(BaseBinaryOperation):
+ def operation(self, ctx, op1, op2):
+ return mod(ctx, op1, op2)
+
+class UPLUS(BaseUnaryOperation):
+ def eval(self, ctx, stack):
+ if isinstance(stack.top(), W_IntNumber):
+ return
+ if isinstance(stack.top(), W_FloatNumber):
+ return
+ stack.append(W_FloatNumber(stack.pop().ToNumber(ctx)))
+
+class UMINUS(BaseUnaryOperation):
+ def eval(self, ctx, stack):
+ stack.append(uminus(stack.pop(), ctx))
+
+class NOT(BaseUnaryOperation):
+ def eval(self, ctx, stack):
+ stack.append(newbool(not stack.pop().ToBoolean()))
+
+class INCR(BaseUnaryOperation):
+ def eval(self, ctx, stack):
+ value = stack.pop()
+ newvalue = increment(ctx, value)
+ stack.append(newvalue)
+
+class DECR(BaseUnaryOperation):
+ def eval(self, ctx, stack):
+ value = stack.pop()
+ newvalue = decrement(ctx, value)
+ stack.append(newvalue)
+
+class GT(BaseBinaryComparison):
+ def decision(self, ctx, op1, op2):
+ return newbool(compare(ctx, op1, op2))
+
+class GE(BaseBinaryComparison):
+ def decision(self, ctx, op1, op2):
+ return newbool(compare_e(ctx, op1, op2))
+
+class LT(BaseBinaryComparison):
+ def decision(self, ctx, op1, op2):
+ return newbool(compare(ctx, op2, op1))
+
+class LE(BaseBinaryComparison):
+ def decision(self, ctx, op1, op2):
+ return newbool(compare_e(ctx, op2, op1))
+
+class EQ(BaseBinaryComparison):
+ def decision(self, ctx, op1, op2):
+ return newbool(AbstractEC(ctx, op1, op2))
+
+class NE(BaseBinaryComparison):
+ def decision(self, ctx, op1, op2):
+ return newbool(not AbstractEC(ctx, op1, op2))
+
+class IS(BaseBinaryComparison):
+ def decision(self, ctx, op1, op2):
+ return newbool(StrictEC(ctx, op1, op2))
+
+class ISNOT(BaseBinaryComparison):
+ def decision(self, ctx, op1, op2):
+ return newbool(not StrictEC(ctx, op1, op2))
+
+class STORE_MEMBER(Opcode):
+ def eval(self, ctx, stack):
+ left = stack.pop()
+ member = stack.pop()
+ value = stack.pop()
+ name = member.ToString(ctx)
+ left.ToObject(ctx).Put(ctx, name, value)
+ stack.append(value)
+
+class STORE(Opcode):
+ _immutable_fields_ = ['name']
+ def __init__(self, name):
+ self.name = name
+
+ def eval(self, ctx, stack):
+ value = stack.top()
+ ctx.assign(self.name, value)
+
+ def __repr__(self):
+ return '%s "%s"' % (self.__class__.__name__, self.name)
+
+class LABEL(Opcode):
+ def __init__(self, num):
+ self.num = num
+
+ def __repr__(self):
+ return 'LABEL %d' % (self.num,)
+
+class BaseJump(Opcode):
+ _immutable_fields_ = ['where']
+ def __init__(self, where):
+ self.where = where
+ self.decision = False
+
+ def do_jump(self, stack, pos):
+ return 0
+
+ def __repr__(self):
+ return '%s %d' % (self.__class__.__name__, self.where)
+
+class JUMP(BaseJump):
+ def eval(self, ctx, stack):
+ pass
+
+ def do_jump(self, stack, pos):
+ return self.where
+
+class BaseIfJump(BaseJump):
+ def eval(self, ctx, stack):
+ value = stack.pop()
+ self.decision = value.ToBoolean()
+
+class BaseIfNopopJump(BaseJump):
+ def eval(self, ctx, stack):
+ value = stack.top()
+ self.decision = value.ToBoolean()
+
+class JUMP_IF_FALSE(BaseIfJump):
+ def do_jump(self, stack, pos):
+ if self.decision:
+ return pos + 1
+ return self.where
+
+class JUMP_IF_FALSE_NOPOP(BaseIfNopopJump):
+ def do_jump(self, stack, pos):
+ if self.decision:
+ stack.pop()
+ return pos + 1
+ return self.where
+
+class JUMP_IF_TRUE(BaseIfJump):
+ def do_jump(self, stack, pos):
+ if self.decision:
+ return self.where
+ return pos + 1
+
+class JUMP_IF_TRUE_NOPOP(BaseIfNopopJump):
+ def do_jump(self, stack, pos):
+ if self.decision:
+ return self.where
+ stack.pop()
+ return pos + 1
+
+class DECLARE_FUNCTION(Opcode):
+ def __init__(self, funcobj):
+ self.funcobj = funcobj
+
+ def eval(self, ctx, stack):
+ # function declaration actyally don't run anything
+ proto = ctx.get_global().Get(ctx, 'Function').Get(ctx, 'prototype')
+ w_func = W_Object(ctx=ctx, Prototype=proto, Class='Function',
callfunc=self.funcobj)
+ w_func.Put(ctx, 'length', W_IntNumber(len(self.funcobj.params)))
+ w_obj = create_object(ctx, 'Object')
+ w_obj.Put(ctx, 'constructor', w_func, flags = jsobj.DE)
+ w_func.Put(ctx, 'prototype', w_obj)
+ if self.funcobj.name is not None:
+ ctx.scope[-1].Put(ctx, self.funcobj.name, w_func)
+
+ def __repr__(self):
+ funcobj = self.funcobj
+ if funcobj.name is None:
+ name = ""
+ else:
+ name = funcobj.name + " "
+ codestr = '\n'.join([' %r' % (op,) for op in funcobj.opcodes])
+ return 'DECLARE_FUNCTION %s%r [\n%s\n]' % (name, funcobj.params,
codestr)
+
+class DECLARE_VAR(Opcode):
+ def __init__(self, name):
+ self.name = name
+
+ def eval(self, ctx, stack):
+ ctx.scope[-1].Put(ctx, self.name, w_Undefined, flags = jsobj.DD)
+
+ def __repr__(self):
+ return 'DECLARE_VAR "%s"' % (self.name,)
+
+class RETURN(Opcode):
+ def eval(self, ctx, stack):
+ raise ReturnException(stack.pop())
+
+class POP(Opcode):
+ def eval(self, ctx, stack):
+ stack.pop()
+
+def common_call(ctx, r1, args, this, name):
+ if not isinstance(r1, W_PrimitiveObject):
+ raise ThrowException(W_String("%s is not a callable
(%s)"%(r1.ToString(ctx), name)))
+ try:
+ res = r1.Call(ctx=ctx, args=args.tolist(), this=this)
+ except JsTypeError:
+ raise ThrowException(W_String("%s is not a function
(%s)"%(r1.ToString(ctx), name)))
+ return res
+
+class CALL(Opcode):
+ def eval(self, ctx, stack):
+ r1 = stack.pop()
+ args = stack.pop()
+ name = r1.ToString(ctx)
+ #XXX hack, this should be comming from context
+ stack.append(common_call(ctx, r1, args, ctx.scope[-1], name))
+
+class CALL_METHOD(Opcode):
+ def eval(self, ctx, stack):
+ method = stack.pop()
+ what = stack.pop().ToObject(ctx)
+ args = stack.pop()
+ name = method.ToString(ctx)
+ r1 = what.Get(ctx, name)
+ stack.append(common_call(ctx, r1, args, what, name))
+
+#class CALL_BASEOP(Opcode):
+ #def __init__(self, baseop):
+ #self.baseop = baseop
+
+ #def eval(self, ctx, stack):
+ #from js.baseop import get_baseop_func
+ #func = get_baseop_func(self.baseop)
+ #args = stack.pop_n(func.argcount)
+ #kwargs = {'ctx':ctx}
+ #val = func(*args, **kwargs)
+ #stack.append(val)
+
+ #def __repr__(self):
+ #from js.baseop import get_baseop_name, get_baseop_func
+ #return "CALL_BASEOP %s (%d)" % (get_baseop_name(self.baseop),
self.baseop)
+
+class DUP(Opcode):
+ def eval(self, ctx, stack):
+ stack.append(stack.top())
+
+class THROW(Opcode):
+ def eval(self, ctx, stack):
+ val = stack.pop()
+ raise ThrowException(val)
+
+class TRYCATCHBLOCK(Opcode):
+ def __init__(self, tryfunc, catchparam, catchfunc, finallyfunc):
+ self.tryfunc = tryfunc
+ self.catchfunc = catchfunc
+ self.catchparam = catchparam
+ self.finallyfunc = finallyfunc
+
+ def eval(self, ctx, stack):
+ try:
+ try:
+ self.tryfunc.run(ctx)
+ except ThrowException, e:
+ if self.catchfunc is not None:
+ # XXX just copied, I don't know if it's right
+ obj = W_Object()
+ obj.Put(ctx, self.catchparam, e.exception)
+ ctx.push_object(obj)
+ try:
+ self.catchfunc.run(ctx)
+ finally:
+ ctx.pop_object()
+ if self.finallyfunc is not None:
+ self.finallyfunc.run(ctx)
+ if not self.catchfunc:
+ raise
+ except ReturnException:
+ # we run finally block here and re-raise the exception
+ if self.finallyfunc is not None:
+ self.finallyfunc.run(ctx)
+ raise
+
+ def __repr__(self):
+ return "TRYCATCHBLOCK" # XXX shall we add stuff here???
+
+class NEW(Opcode):
+ def eval(self, ctx, stack):
+ y = stack.pop()
+ x = stack.pop()
+ assert isinstance(y, W_List)
+ args = y.get_args()
+ stack.append(commonnew(ctx, x, args))
+
+class NEW_NO_ARGS(Opcode):
+ def eval(self, ctx, stack):
+ x = stack.pop()
+ stack.append(commonnew(ctx, x, []))
+
+# ------------ iterator support ----------------
+
+class LOAD_ITERATOR(Opcode):
+ def eval(self, ctx, stack):
+ obj = stack.pop().ToObject(ctx)
+ props = [prop.value for prop in obj.propdict.values() if not
prop.flags & jsobj.DE]
+ stack.append(W_Iterator(props))
+
+class JUMP_IF_ITERATOR_EMPTY(BaseJump):
+ def eval(self, ctx, stack):
+ pass
+
+ def do_jump(self, stack, pos):
+ iterator = stack.top()
+ assert isinstance(iterator, W_Iterator)
+ if iterator.empty():
+ return self.where
+ return pos + 1
+
+class NEXT_ITERATOR(Opcode):
+ def __init__(self, name):
+ self.name = name
+
+ def eval(self, ctx, stack):
+ iterator = stack.top()
+ assert isinstance(iterator, W_Iterator)
+ ctx.assign(self.name, iterator.next())
+
+# ---------------- with support ---------------------
+
+class WITH_START(Opcode):
+ def eval(self, ctx, stack):
+ obj = stack.pop().ToObject(ctx)
+ ctx.push_object(obj)
+
+class WITH_END(Opcode):
+ def eval(self, ctx, stack):
+ ctx.pop_object()
+
+# ------------------ delete -------------------------
+
+class DELETE(Opcode):
+ def __init__(self, name):
+ self.name = name
+
+ def eval(self, ctx, stack):
+ stack.append(newbool(ctx.delete_identifier(self.name)))
+
+class DELETE_MEMBER(Opcode):
+ def eval(self, ctx, stack):
+ what = stack.pop().ToString(ctx)
+ 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():
+ if name.upper() == name and type(value) == type(Opcode) and
issubclass(value, Opcode):
+ 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():
+ setattr(opcodes, name, value)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit