[pypy-commit] lang-js default: moved stack into ExecutionContext
stepahn
noreply at buildbot.pypy.org
Fri Dec 28 11:32:00 CET 2012
Author: Stephan <stephan at stzal.com>
Branch:
Changeset: r105:00760baa5669
Date: 2011-07-04 15:52 +0200
http://bitbucket.org/pypy/lang-js/changeset/00760baa5669/
Log: moved stack into ExecutionContext
diff --git a/js/jscode.py b/js/jscode.py
--- a/js/jscode.py
+++ b/js/jscode.py
@@ -14,7 +14,7 @@
except IndexError:
return "???"
-jitdriver = JitDriver(greens=['pc', 'self'], reds=['to_pop', 'stack', 'ctx'], get_printable_location = get_printable_location, virtualizables=['stack'])
+jitdriver = JitDriver(greens=['pc', 'self'], reds=['to_pop', 'ctx'], get_printable_location = get_printable_location, virtualizables=['ctx'])
class AlreadyRun(Exception):
pass
@@ -135,6 +135,21 @@
def __repr__(self):
return "\n".join([repr(i) for i in self.opcodes])
+ at jit.dont_look_inside
+def _save_stack(ctx, size):
+ old_stack = ctx.stack
+ old_stack_pointer = ctx.stack_pointer
+
+ ctx.stack_pointer = 0
+ ctx.stack = [None] * size
+ return old_stack, old_stack_pointer
+
+ at jit.dont_look_inside
+def _restore_stack(ctx, state):
+ old_stack, old_stack_pointer = state
+ ctx.stack_pointer = old_stack_pointer
+ ctx.stack = old_stack
+
class JsFunction(object):
_immutable_fields_ = ["opcodes[*]"]
@@ -145,10 +160,12 @@
self.opcodes = make_sure_not_resized(code)
def run(self, ctx, check_stack=True):
- from js.utils import Stack
- stack = Stack(len(self.opcodes) * 2)
+ state = _save_stack(ctx, len(self.opcodes) * 2)
+
try:
- return self.run_bytecode(ctx, stack, check_stack)
+ r = self.run_bytecode(ctx, check_stack)
+ _restore_stack(ctx, state)
+ return r
except ReturnException, e:
return e.value
@@ -156,12 +173,12 @@
assert pc >= 0
return self.opcodes[pc]
- def run_bytecode(self, ctx, stack, check_stack=True):
+ def run_bytecode(self, ctx, check_stack=True):
pc = 0
to_pop = 0
try:
while True:
- jitdriver.jit_merge_point(pc=pc, stack=stack, self=self, ctx=ctx, to_pop=to_pop)
+ jitdriver.jit_merge_point(pc=pc, self=self, ctx=ctx, to_pop=to_pop)
if pc >= len(self.opcodes):
break
@@ -177,15 +194,15 @@
# assert result is None
# break
#else:
- result = opcode.eval(ctx, stack)
+ result = opcode.eval(ctx)
assert result is None
if isinstance(opcode, BaseJump):
- new_pc = opcode.do_jump(stack, pc)
+ new_pc = opcode.do_jump(ctx, pc)
condition = new_pc < pc
pc = new_pc
if condition:
- jitdriver.can_enter_jit(pc=pc, stack=stack, self=self, ctx=ctx, to_pop=to_pop)
+ jitdriver.can_enter_jit(pc=pc, self=self, ctx=ctx, to_pop=to_pop)
continue
else:
pc += 1
@@ -198,5 +215,5 @@
ctx.pop_object()
if check_stack:
- stack.check()
- return stack.top()
+ ctx.check_stack()
+ return ctx.top()
diff --git a/js/jsobj.py b/js/jsobj.py
--- a/js/jsobj.py
+++ b/js/jsobj.py
@@ -2,16 +2,18 @@
from pypy.rpython.lltypesystem import rffi
from pypy.rlib.rarithmetic import r_uint, intmask, ovfcheck_float_to_int
from pypy.rlib.rfloat import isnan, isinf, NAN, formatd
-from js.execution import ThrowException, JsTypeError,\
- RangeError, ReturnException
+from js.execution import ThrowException, JsTypeError, RangeError, ReturnException
+
+from pypy.rlib.jit import hint
+from pypy.rlib import jit, debug
+from js.utils import StackMixin
+
import string
DE = 1
DD = 2
RO = 4
IT = 8
-from pypy.rlib import jit
-
class SeePage(NotImplementedError):
pass
@@ -571,7 +573,7 @@
def __repr__(self):
return 'W_List(%s)' % (self.list_w,)
-class ExecutionContext(object):
+class ExecutionContext(StackMixin):
def __init__(self, scope, this=None, variable=None,
debug=False, jsproperty=None):
assert scope is not None
@@ -592,6 +594,7 @@
self.property = jsproperty
self.local_identifiers = []
self.local_values = []
+ StackMixin.__init__(self)
def __str__(self):
return "<ExCtx %s, var: %s>"%(self.scope, self.variable)
diff --git a/js/opcodes.py b/js/opcodes.py
--- a/js/opcodes.py
+++ b/js/opcodes.py
@@ -12,7 +12,7 @@
def __init__(self):
pass
- def eval(self, ctx, stack):
+ def eval(self, ctx):
""" Execute in context ctx
"""
raise NotImplementedError
@@ -21,43 +21,43 @@
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 eval(self, ctx):
+ s4 = ctx.pop()
+ s2 = ctx.pop()
+ ctx.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 eval(self, ctx):
+ s5 = ctx.pop().ToInt32(ctx)
+ s6 = ctx.pop().ToInt32(ctx)
+ ctx.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))
+ def eval(self, ctx):
+ right = ctx.pop()
+ left = ctx.pop()
+ ctx.append(self.operation(ctx, left, right))
class BaseUnaryOperation(Opcode):
pass
class Undefined(Opcode):
- def eval(self, ctx, stack):
- stack.append(w_Undefined)
+ def eval(self, ctx):
+ ctx.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 eval(self, ctx):
+ ctx.append(self.w_intvalue)
def __repr__(self):
return 'LOAD_INTCONSTANT %s' % (self.w_intvalue.intval,)
@@ -66,15 +66,15 @@
def __init__(self, value):
self.boolval = value
- def eval(self, ctx, stack):
- stack.append(newbool(self.boolval))
+ def eval(self, ctx):
+ ctx.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 eval(self, ctx):
+ ctx.append(self.w_floatvalue)
def __repr__(self):
return 'LOAD_FLOATCONSTANT %s' % (self.w_floatvalue.floatval,)
@@ -84,8 +84,8 @@
def __init__(self, value):
self.w_stringvalue = W_String(value)
- def eval(self, ctx, stack):
- stack.append(self.w_stringvalue)
+ def eval(self, ctx):
+ ctx.append(self.w_stringvalue)
#def get_literal(self, ctx):
# return W_String(self.strval).ToString(ctx)
@@ -94,20 +94,20 @@
return 'LOAD_STRINGCONSTANT "%s"' % (self.w_stringvalue.strval,)
class LOAD_UNDEFINED(Opcode):
- def eval(self, ctx, stack):
- stack.append(w_Undefined)
+ def eval(self, ctx):
+ ctx.append(w_Undefined)
class LOAD_NULL(Opcode):
- def eval(self, ctx, stack):
- stack.append(w_Null)
+ def eval(self, ctx):
+ ctx.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 eval(self, ctx):
+ ctx.append(ctx.resolve_identifier(ctx, self.identifier))
def __repr__(self):
return 'LOAD_VARIABLE "%s"' % (self.identifier,)
@@ -117,7 +117,7 @@
self.depth = depth
self.identifier = identifier
- def eval(self, ctx, stack):
+ def eval(self, ctx):
raise NotImplementedError()
# XXX
# scope = ctx.scope[self.depth]
@@ -131,12 +131,12 @@
def __init__(self, counter):
self.counter = counter
- def eval(self, ctx, stack):
+ def eval(self, ctx):
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)
+ array.Put(ctx, str(self.counter - i - 1), ctx.pop())
+ ctx.append(array)
def __repr__(self):
return 'LOAD_ARRAY %d' % (self.counter,)
@@ -146,9 +146,9 @@
def __init__(self, counter):
self.counter = counter
- def eval(self, ctx, stack):
- list_w = stack.pop_n(self.counter)[:] # pop_n returns a non-resizable list
- stack.append(W_List(list_w))
+ def eval(self, ctx):
+ list_w = ctx.pop_n(self.counter)[:] # pop_n returns a non-resizable list
+ ctx.append(W_List(list_w))
def __repr__(self):
return 'LOAD_LIST %d' % (self.counter,)
@@ -157,7 +157,7 @@
def __init__(self, funcobj):
self.funcobj = funcobj
- def eval(self, ctx, stack):
+ def eval(self, ctx):
proto = ctx.get_global().Get(ctx, 'Function').Get(ctx, 'prototype')
w_func = W_Object(ctx=ctx, Prototype=proto, Class='Function',
callfunc=self.funcobj)
@@ -165,7 +165,7 @@
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)
+ ctx.append(w_func)
def __repr__(self):
return 'LOAD_FUNCTION' # XXX
@@ -186,28 +186,28 @@
def __init__(self, counter):
self.counter = counter
- def eval(self, ctx, stack):
+ def eval(self, ctx):
w_obj = create_object(ctx, 'Object')
for _ in range(self.counter):
- name = stack.pop().ToString(ctx)
- w_elem = stack.pop()
+ name = ctx.pop().ToString(ctx)
+ w_elem = ctx.pop()
w_obj.Put(ctx, name, w_elem)
- stack.append(w_obj)
+ ctx.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))
+ def eval(self, ctx):
+ w_obj = ctx.pop().ToObject(ctx)
+ name = ctx.pop().ToString(ctx)
+ ctx.append(w_obj.Get(ctx, name))
class COMMA(BaseUnaryOperation):
- def eval(self, ctx, stack):
- one = stack.pop()
- stack.pop()
- stack.append(one)
+ def eval(self, ctx):
+ one = ctx.pop()
+ ctx.pop()
+ ctx.append(one)
# XXX
class SUB(BaseBinaryOperation):
@@ -222,20 +222,20 @@
return newbool(right.HasProperty(name))
class TYPEOF(BaseUnaryOperation):
- def eval(self, ctx, stack):
- one = stack.pop()
- stack.append(W_String(one.type()))
+ def eval(self, ctx):
+ one = ctx.pop()
+ ctx.append(W_String(one.type()))
class TYPEOF_VARIABLE(Opcode):
def __init__(self, name):
self.name = name
- def eval(self, ctx, stack):
+ def eval(self, ctx):
try:
var = ctx.resolve_identifier(ctx, self.name)
- stack.append(W_String(var.type()))
+ ctx.append(W_String(var.type()))
except ThrowException:
- stack.append(W_String('undefined'))
+ ctx.append(W_String('undefined'))
#class Typeof(UnaryOp):
# def eval(self, ctx):
@@ -261,28 +261,28 @@
return W_IntNumber(op1|op2)
class BITNOT(BaseUnaryOperation):
- def eval(self, ctx, stack):
- op = stack.pop().ToInt32(ctx)
- stack.append(W_IntNumber(~op))
+ def eval(self, ctx):
+ op = ctx.pop().ToInt32(ctx)
+ ctx.append(W_IntNumber(~op))
class URSH(BaseBinaryBitwiseOp):
- def eval(self, ctx, stack):
- op2 = stack.pop().ToUInt32(ctx)
- op1 = stack.pop().ToUInt32(ctx)
+ def eval(self, ctx):
+ op2 = ctx.pop().ToUInt32(ctx)
+ op1 = ctx.pop().ToUInt32(ctx)
# XXX check if it could fit into int
- stack.append(W_FloatNumber(op1 >> (op2 & 0x1F)))
+ ctx.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)))
+ def eval(self, ctx):
+ op2 = ctx.pop().ToUInt32(ctx)
+ op1 = ctx.pop().ToInt32(ctx)
+ ctx.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)))
+ def eval(self, ctx):
+ op2 = ctx.pop().ToUInt32(ctx)
+ op1 = ctx.pop().ToInt32(ctx)
+ ctx.append(W_IntNumber(op1 << intmask(op2 & 0x1F)))
class MUL(BaseBinaryOperation):
def operation(self, ctx, op1, op2):
@@ -297,32 +297,32 @@
return mod(ctx, op1, op2)
class UPLUS(BaseUnaryOperation):
- def eval(self, ctx, stack):
- if isinstance(stack.top(), W_IntNumber):
+ def eval(self, ctx):
+ if isinstance(ctx.top(), W_IntNumber):
return
- if isinstance(stack.top(), W_FloatNumber):
+ if isinstance(ctx.top(), W_FloatNumber):
return
- stack.append(W_FloatNumber(stack.pop().ToNumber(ctx)))
+ ctx.append(W_FloatNumber(ctx.pop().ToNumber(ctx)))
class UMINUS(BaseUnaryOperation):
- def eval(self, ctx, stack):
- stack.append(uminus(stack.pop(), ctx))
+ def eval(self, ctx):
+ ctx.append(uminus(ctx.pop(), ctx))
class NOT(BaseUnaryOperation):
- def eval(self, ctx, stack):
- stack.append(newbool(not stack.pop().ToBoolean()))
+ def eval(self, ctx):
+ ctx.append(newbool(not ctx.pop().ToBoolean()))
class INCR(BaseUnaryOperation):
- def eval(self, ctx, stack):
- value = stack.pop()
+ def eval(self, ctx):
+ value = ctx.pop()
newvalue = increment(ctx, value)
- stack.append(newvalue)
+ ctx.append(newvalue)
class DECR(BaseUnaryOperation):
- def eval(self, ctx, stack):
- value = stack.pop()
+ def eval(self, ctx):
+ value = ctx.pop()
newvalue = decrement(ctx, value)
- stack.append(newvalue)
+ ctx.append(newvalue)
class GT(BaseBinaryComparison):
def decision(self, ctx, op1, op2):
@@ -357,21 +357,21 @@
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()
+ def eval(self, ctx):
+ left = ctx.pop()
+ member = ctx.pop()
+ value = ctx.pop()
name = member.ToString(ctx)
left.ToObject(ctx).Put(ctx, name, value)
- stack.append(value)
+ ctx.append(value)
class STORE(Opcode):
_immutable_fields_ = ['name']
def __init__(self, name):
self.name = name
- def eval(self, ctx, stack):
- value = stack.top()
+ def eval(self, ctx):
+ value = ctx.top()
ctx.assign(self.name, value)
def __repr__(self):
@@ -390,60 +390,60 @@
self.where = where
self.decision = False
- def do_jump(self, stack, pos):
+ def do_jump(self, ctx, pos):
return 0
def __repr__(self):
return '%s %d' % (self.__class__.__name__, self.where)
class JUMP(BaseJump):
- def eval(self, ctx, stack):
+ def eval(self, ctx):
pass
- def do_jump(self, stack, pos):
+ def do_jump(self, ctx, pos):
return self.where
class BaseIfJump(BaseJump):
- def eval(self, ctx, stack):
- value = stack.pop()
+ def eval(self, ctx):
+ value = ctx.pop()
self.decision = value.ToBoolean()
class BaseIfNopopJump(BaseJump):
- def eval(self, ctx, stack):
- value = stack.top()
+ def eval(self, ctx):
+ value = ctx.top()
self.decision = value.ToBoolean()
class JUMP_IF_FALSE(BaseIfJump):
- def do_jump(self, stack, pos):
+ def do_jump(self, ctx, pos):
if self.decision:
return pos + 1
return self.where
class JUMP_IF_FALSE_NOPOP(BaseIfNopopJump):
- def do_jump(self, stack, pos):
+ def do_jump(self, ctx, pos):
if self.decision:
- stack.pop()
+ ctx.pop()
return pos + 1
return self.where
class JUMP_IF_TRUE(BaseIfJump):
- def do_jump(self, stack, pos):
+ def do_jump(self, ctx, pos):
if self.decision:
return self.where
return pos + 1
class JUMP_IF_TRUE_NOPOP(BaseIfNopopJump):
- def do_jump(self, stack, pos):
+ def do_jump(self, ctx, pos):
if self.decision:
return self.where
- stack.pop()
+ ctx.pop()
return pos + 1
class DECLARE_FUNCTION(Opcode):
def __init__(self, funcobj):
self.funcobj = funcobj
- def eval(self, ctx, stack):
+ def eval(self, ctx):
# 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)
@@ -467,19 +467,19 @@
def __init__(self, name):
self.name = name
- def eval(self, ctx, stack):
+ def eval(self, ctx):
ctx.declare_variable(self.name)
def __repr__(self):
return 'DECLARE_VAR "%s"' % (self.name,)
class RETURN(Opcode):
- def eval(self, ctx, stack):
- raise ReturnException(stack.pop())
+ def eval(self, ctx):
+ raise ReturnException(ctx.pop())
class POP(Opcode):
- def eval(self, ctx, stack):
- stack.pop()
+ def eval(self, ctx):
+ ctx.pop()
def common_call(ctx, r1, args, this, name):
if not isinstance(r1, W_PrimitiveObject):
@@ -491,45 +491,29 @@
return res
class CALL(Opcode):
- def eval(self, ctx, stack):
- r1 = stack.pop()
- args = stack.pop()
+ def eval(self, ctx):
+ r1 = ctx.pop()
+ args = ctx.pop()
name = r1.ToString(ctx)
#XXX hack, this should be comming from context
- stack.append(common_call(ctx, r1, args, ctx.scope[-1], name))
+ ctx.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()
+ def eval(self, ctx):
+ method = ctx.pop()
+ what = ctx.pop().ToObject(ctx)
+ args = ctx.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)
+ ctx.append(common_call(ctx, r1, args, what, name))
class DUP(Opcode):
- def eval(self, ctx, stack):
- stack.append(stack.top())
+ def eval(self, ctx):
+ ctx.append(ctx.top())
class THROW(Opcode):
- def eval(self, ctx, stack):
- val = stack.pop()
+ def eval(self, ctx):
+ val = ctx.pop()
raise ThrowException(val)
class TRYCATCHBLOCK(Opcode):
@@ -539,7 +523,7 @@
self.catchparam = catchparam
self.finallyfunc = finallyfunc
- def eval(self, ctx, stack):
+ def eval(self, ctx):
try:
try:
self.tryfunc.run(ctx)
@@ -567,32 +551,32 @@
return "TRYCATCHBLOCK" # XXX shall we add stuff here???
class NEW(Opcode):
- def eval(self, ctx, stack):
- y = stack.pop()
- x = stack.pop()
+ def eval(self, ctx):
+ y = ctx.pop()
+ x = ctx.pop()
assert isinstance(y, W_List)
args = y.get_args()
- stack.append(commonnew(ctx, x, args))
+ ctx.append(commonnew(ctx, x, args))
class NEW_NO_ARGS(Opcode):
- def eval(self, ctx, stack):
- x = stack.pop()
- stack.append(commonnew(ctx, x, []))
+ def eval(self, ctx):
+ x = ctx.pop()
+ ctx.append(commonnew(ctx, x, []))
# ------------ iterator support ----------------
class LOAD_ITERATOR(Opcode):
- def eval(self, ctx, stack):
- obj = stack.pop().ToObject(ctx)
+ def eval(self, ctx):
+ obj = ctx.pop().ToObject(ctx)
props = [prop.value for prop in obj.propdict.values() if not prop.flags & jsobj.DE]
- stack.append(W_Iterator(props))
+ ctx.append(W_Iterator(props))
class JUMP_IF_ITERATOR_EMPTY(BaseJump):
- def eval(self, ctx, stack):
+ def eval(self, ctx):
pass
- def do_jump(self, stack, pos):
- iterator = stack.top()
+ def do_jump(self, ctx, pos):
+ iterator = ctx.top()
assert isinstance(iterator, W_Iterator)
if iterator.empty():
return self.where
@@ -602,20 +586,20 @@
def __init__(self, name):
self.name = name
- def eval(self, ctx, stack):
- iterator = stack.top()
+ def eval(self, ctx):
+ iterator = ctx.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)
+ def eval(self, ctx):
+ obj = ctx.pop().ToObject(ctx)
ctx.push_object(obj)
class WITH_END(Opcode):
- def eval(self, ctx, stack):
+ def eval(self, ctx):
ctx.pop_object()
# ------------------ delete -------------------------
@@ -624,22 +608,22 @@
def __init__(self, name):
self.name = name
- def eval(self, ctx, stack):
- stack.append(newbool(ctx.delete_identifier(self.name)))
+ def eval(self, ctx):
+ ctx.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)))
+ def eval(self, ctx):
+ what = ctx.pop().ToString(ctx)
+ obj = ctx.pop().ToObject(ctx)
+ ctx.append(newbool(obj.Delete(what)))
class LOAD_LOCAL(Opcode):
_immutable_fields_ = ['local']
def __init__(self, local):
self.local = local
- def eval(self, ctx, stack):
- stack.append(ctx.get_local_value(self.local))
+ def eval(self, ctx):
+ ctx.append(ctx.get_local_value(self.local))
def __repr__(self):
return 'LOAD_LOCAL %d' % (self.local,)
@@ -649,8 +633,8 @@
def __init__(self, local):
self.local = local
- def eval(self, ctx, stack):
- value = stack.top()
+ def eval(self, ctx):
+ value = ctx.top()
ctx.assign_local(self.local, value)
def __repr__(self):
diff --git a/js/test/test_stack.py b/js/test/test_stack.py
--- a/js/test/test_stack.py
+++ b/js/test/test_stack.py
@@ -1,30 +1,35 @@
import py
-from js.utils import Stack
+from js.utils import StackMixin
from js.jsobj import W_IntNumber
one = W_IntNumber(1)
two = W_IntNumber(2)
three = W_IntNumber(3)
+class Stack(StackMixin):
+ def __init__(self, size):
+ StackMixin.__init__(self)
+ self.stack = [None] * size
+
def test_stack_push():
s = Stack(99)
- assert len(s.content) == 99
- assert s.content == [None] * 99
+ assert len(s.stack) == 99
+ assert s.stack == [None] * 99
s = Stack(99)
s.append(one)
- assert s.content[0] == one
- assert s.pointer == 1
+ assert s.stack[0] == one
+ assert s.stack_pointer == 1
s = Stack(99)
s.append(one)
s.append(two)
s.append(three)
- assert s.content[0] == one
- assert s.content[1] == two
- assert s.content[2] == three
- assert s.pointer == 3
+ assert s.stack[0] == one
+ assert s.stack[1] == two
+ assert s.stack[2] == three
+ assert s.stack_pointer == 3
def test_stack_pop():
s = Stack(99)
@@ -32,8 +37,8 @@
s.append(two)
s.append(three)
assert s.pop() == three
- assert s.pointer == 2
- assert s.content[2] == None
+ assert s.stack_pointer == 2
+ assert s.stack[2] == None
s = Stack(99)
s.append(one)
@@ -61,9 +66,9 @@
s.append(three)
x = s.pop_n(2)
assert x == [two, three]
- assert s.pointer == 1
- assert s.content[1] == None
- assert s.content[2] == None
+ assert s.stack_pointer == 1
+ assert s.stack[1] == None
+ assert s.stack[2] == None
def test_stack_max():
s = Stack(2)
diff --git a/js/utils.py b/js/utils.py
--- a/js/utils.py
+++ b/js/utils.py
@@ -1,38 +1,34 @@
# encoding: utf-8
-from js.jsobj import W_Root
from pypy.rlib.jit import hint
from pypy.rlib import jit, debug
-class Stack(object):
- _virtualizable2_ = ['content[*]', 'pointer']
- def __init__(self, size):
- self = hint(self, access_directly = True, fresh_virtualizable = True)
- self.content = [None] * size
- self.pointer = 0
-
- def __repr__(self):
- return "<Stack %(content)s@%(pointer)d>" % {'pointer': self.pointer, 'content': self.content}
+class StackMixin(object):
+ _mixin_ = True
+ def __init__(self):
+ self.stack = [None]
+ self.stack_pointer = 0
def pop(self):
e = self.top()
- i = self.pointer - 1
+ i = self.stack_pointer - 1
assert i >= 0
- self.content[i] = None
- self.pointer = i
+ self.stack[i] = None
+ self.stack_pointer = i
return e
def top(self):
- i = self.pointer - 1
+ i = self.stack_pointer - 1
if i < 0:
raise IndexError
- return self.content[i]
+ return self.stack[i]
def append(self, element):
+ from js.jsobj import W_Root
assert isinstance(element, W_Root)
- i = self.pointer
+ i = self.stack_pointer
assert i >= 0
- self.content[i] = element
- self.pointer = i + 1
+ self.stack[i] = element
+ self.stack_pointer = i + 1
@jit.unroll_safe
def pop_n(self, n):
@@ -42,5 +38,5 @@
debug.make_sure_not_resized(l)
return l
- def check(self):
- assert self.pointer == 1
+ def check_stack(self):
+ assert self.stack_pointer == 1
More information about the pypy-commit
mailing list