[pypy-commit] lang-js default: move run code from JsCode to JsFunction
stepahn
noreply at buildbot.pypy.org
Fri May 13 13:45:15 CEST 2011
Author: Stephan <stephan at stzal.com>
Branch:
Changeset: r43:0d73a6637419
Date: 2011-05-12 15:06 +0200
http://bitbucket.org/pypy/lang-js/changeset/0d73a6637419/
Log: move run code from JsCode to JsFunction
diff --git a/js/interpreter.py b/js/interpreter.py
--- a/js/interpreter.py
+++ b/js/interpreter.py
@@ -149,7 +149,8 @@
bytecode = JsCode()
node.emit(bytecode)
- return bytecode.run(ctx, retlast=True)
+ func = bytecode.make_js_function()
+ return func.run(ctx, retlast = True)
class W_ParseInt(W_NewBuiltin):
length = 1
@@ -317,7 +318,8 @@
ast = ASTBUILDER.dispatch(funcnode)
bytecode = JsCode()
ast.emit(bytecode)
- return bytecode.run(ctx, retlast=True)
+ func = bytecode.make_js_function()
+ return func.run(ctx, retlast=True)
def Construct(self, ctx, args=[]):
return self.Call(ctx, args, this=None)
@@ -894,7 +896,8 @@
if not we_are_translated():
# debugging
self._code = bytecode
+ func = bytecode.make_js_function()
if interactive:
- return bytecode.run(self.global_context, retlast=True)
+ return func.run(self.global_context, retlast=True)
else:
- bytecode.run(self.global_context)
+ func.run(self.global_context)
diff --git a/js/jscode.py b/js/jscode.py
--- a/js/jscode.py
+++ b/js/jscode.py
@@ -15,61 +15,6 @@
class AlreadyRun(Exception):
pass
-def run_bytecode(opcodes, ctx, stack, check_stack=True, retlast=False):
- popped = False
- if retlast:
- if isinstance(opcodes[-1], POP):
- opcodes.pop()
- popped = True
-
- i = 0
- to_pop = 0
- try:
- while i < len(opcodes):
- opcode = opcodes[i]
- #if we_are_translated():
- # #this is an optimization strategy for translated code
- # #on top of cpython it destroys the performance
- # #besides, this code might be completely wrong
- # for name, op in opcode_unrolling:
- # opcode = hint(opcode, deepfreeze=True)
- # if isinstance(opcode, op):
- # result = opcode.eval(ctx, stack)
- # assert result is None
- # break
- #else:
- result = opcode.eval(ctx, stack)
- assert result is None
-
- if isinstance(opcode, BaseJump):
- i = opcode.do_jump(stack, i)
- else:
- i += 1
- if isinstance(opcode, WITH_START):
- to_pop += 1
- elif isinstance(opcode, WITH_END):
- to_pop -= 1
- finally:
- for i in range(to_pop):
- ctx.pop_object()
-
- if retlast:
- if popped:
- assert len(stack) == 1
- return stack[0]
- else:
- assert not stack
- return w_Undefined
- if check_stack:
- assert not stack
-
-#def run_bytecode_unguarded(opcodes, ctx, stack, check_stack=True, retlast=False):
-# try:
-# run_bytecode(opcodes, ctx, stack, check_stack, retlast)
-# except ThrowException:
-# print
-# raise
-
class T(list):
def append(self, element):
assert isinstance(element, W_Root)
@@ -153,19 +98,10 @@
self.opcodes.append(opcode)
return opcode
- def run(self, ctx, check_stack=True, retlast=False):
+ def make_js_function(self, name='__dont_care__', params=None):
if self.has_labels:
self.remove_labels()
- if 1:
- if we_are_translated():
- stack = []
- else:
- stack = T()
- return run_bytecode(self.opcodes, ctx, stack, check_stack,
- retlast)
- else:
- return run_bytecode_unguarded(self.opcodes, ctx, self,stack,
- check_stack, retlast)
+ return JsFunction(name, params, self.opcodes)
def _freeze_(self):
if self.has_labels:
@@ -206,14 +142,64 @@
def __init__(self, name, params, code):
self.name = name
self.params = params
- self.code = code
+ self.opcodes = code
- def run(self, ctx):
+ def run(self, ctx, check_stack=True, retlast=False):
+ if we_are_translated():
+ stack = []
+ else:
+ stack = T()
try:
- self.code.run(ctx)
+ return self.run_bytecode(ctx, stack, check_stack, retlast)
except ReturnException, e:
return e.value
- return w_Undefined
+
+ def run_bytecode(self, ctx, stack, check_stack=True, retlast=False):
+ popped = False
+ if retlast and self.opcodes and isinstance(self.opcodes[-1], POP):
+ self.opcodes.pop()
+ popped = True
+
+ i = 0
+ to_pop = 0
+ try:
+ while i < len(self.opcodes):
+ opcode = self.opcodes[i]
+ #if we_are_translated():
+ # #this is an optimization strategy for translated code
+ # #on top of cpython it destroys the performance
+ # #besides, this code might be completely wrong
+ # for name, op in opcode_unrolling:
+ # opcode = hint(opcode, deepfreeze=True)
+ # if isinstance(opcode, op):
+ # result = opcode.eval(ctx, stack)
+ # assert result is None
+ # break
+ #else:
+ result = opcode.eval(ctx, stack)
+ assert result is None
+
+ if isinstance(opcode, BaseJump):
+ i = opcode.do_jump(stack, i)
+ else:
+ i += 1
+ if isinstance(opcode, WITH_START):
+ to_pop += 1
+ elif isinstance(opcode, WITH_END):
+ to_pop -= 1
+ finally:
+ for i in range(to_pop):
+ ctx.pop_object()
+
+ if retlast:
+ if popped:
+ assert len(stack) == 1
+ return stack[0]
+ else:
+ assert not stack
+ return w_Undefined
+ if check_stack:
+ assert not stack
class Opcode(object):
def __init__(self):
@@ -804,7 +790,7 @@
name = ""
else:
name = funcobj.name + " "
- codestr = '\n'.join([' %r' % (op,) for op in funcobj.code.opcodes])
+ 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):
@@ -861,34 +847,34 @@
raise ThrowException(val)
class TRYCATCHBLOCK(Opcode):
- def __init__(self, trycode, catchparam, catchcode, finallycode):
- self.trycode = trycode
- self.catchcode = catchcode
+ def __init__(self, tryfunc, catchparam, catchfunc, finallyfunc):
+ self.tryfunc = tryfunc
+ self.catchfunc = catchfunc
self.catchparam = catchparam
- self.finallycode = finallycode
+ self.finallyfunc = finallyfunc
def eval(self, ctx, stack):
try:
try:
- self.trycode.run(ctx)
+ self.tryfunc.run(ctx)
except ThrowException, e:
- if self.catchcode is not None:
+ 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.catchcode.run(ctx)
+ self.catchfunc.run(ctx)
finally:
ctx.pop_object()
- if self.finallycode is not None:
- self.finallycode.run(ctx)
- if not self.catchcode:
+ 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.finallycode is not None:
- self.finallycode.run(ctx)
+ if self.finallyfunc is not None:
+ self.finallyfunc.run(ctx)
raise
def __repr__(self):
diff --git a/js/jsobj.py b/js/jsobj.py
--- a/js/jsobj.py
+++ b/js/jsobj.py
@@ -147,7 +147,7 @@
w_Arguments = W_Arguments(self, args)
act.Put(ctx, 'arguments', w_Arguments)
newctx = function_context(self.Scope, act, this)
- val = self.callfunc.run(ctx=newctx)
+ val = self.callfunc.run(ctx=newctx, retlast=True)
return val
def Construct(self, ctx, args=[]):
diff --git a/js/operations.py b/js/operations.py
--- a/js/operations.py
+++ b/js/operations.py
@@ -313,7 +313,7 @@
code = JsCode()
if self.body is not None:
self.body.emit(code)
- funcobj = JsFunction(self.name, self.params, code)
+ funcobj = code.make_js_function(self.name, self.params)
bytecode.emit('DECLARE_FUNCTION', funcobj)
if self.name is None:
bytecode.emit('LOAD_FUNCTION', funcobj)
@@ -648,18 +648,20 @@
# a bit naive operator for now
trycode = JsCode()
self.tryblock.emit(trycode)
+ tryfunc = trycode.make_js_function()
if self.catchblock:
catchcode = JsCode()
self.catchblock.emit(catchcode)
+ catchfunc = catchcode.make_js_function()
+ finallyfunc = finallycode.make_js_function()
else:
- catchcode = None
+ catchfunc = None
if self.finallyblock:
finallycode = JsCode()
self.finallyblock.emit(finallycode)
else:
- finallycode = None
- bytecode.emit('TRYCATCHBLOCK', trycode, self.catchparam.get_literal(),
- catchcode, finallycode)
+ finallyfunc = None
+ bytecode.emit('TRYCATCHBLOCK', tryfunc, self.catchparam.get_literal(), catchfunc, finallyfunc)
class VariableDeclaration(Expression):
def __init__(self, pos, identifier, expr=None):
diff --git a/js/test/test_interp.py b/js/test/test_interp.py
--- a/js/test/test_interp.py
+++ b/js/test/test_interp.py
@@ -13,7 +13,8 @@
bytecode.emit('LOAD_FLOATCONSTANT', 4)
bytecode.emit('ADD')
bytecode.emit('POP')
- res = bytecode.run(ExecutionContext([W_Object()]), check_stack=False, retlast=True)
+ func = bytecode.make_js_function()
+ res = func.run(ExecutionContext([W_Object()]), check_stack=False, retlast=True)
assert res.ToNumber(None) == 6.0
def assertp(code, prints):
@@ -37,7 +38,8 @@
try:
bytecode = JsCode()
interpreter.load_source(code, '').emit(bytecode)
- code_val = bytecode.run(ExecutionContext([ctx]), retlast=True)
+ func = bytecode.make_js_function()
+ code_val = func.run(ExecutionContext([ctx]), retlast=True)
except ThrowException, excpt:
code_val = excpt.exception
print code_val, value
More information about the pypy-commit
mailing list