[pypy-commit] lang-js default: wip
stepahn
noreply at buildbot.pypy.org
Fri Dec 28 11:33:24 CET 2012
Author: Stephan <stephan at stzal.com>
Branch:
Changeset: r184:ef92b18137ba
Date: 2012-05-09 23:15 +0200
http://bitbucket.org/pypy/lang-js/changeset/ef92b18137ba/
Log: wip
diff --git a/js/execution.py b/js/execution.py
--- a/js/execution.py
+++ b/js/execution.py
@@ -23,17 +23,24 @@
self.exception = exception
self.args = [exception]
-class JsThrowException(ThrowException):
+class JsException(Exception):
+ def __init__(self, value = None):
+ from js.jsobj import _w
+ self.value = _w(value)
+
+class JsThrowException(JsException):
pass
-class JsTypeError(JsBaseExcept):
+class JsTypeError(JsException):
pass
-class JsReferenceError(JsBaseExcept):
+class JsReferenceError(JsException):
+ def __init__(self, identifier):
+ s = "ReferenceError: %s is not defined" % (identifier)
+ JsException.__init__(self, s)
+
+class JsRangeError(JsException):
pass
-class JsRangeError(JsBaseExcept):
+class JsSyntaxError(JsException):
pass
-
-class JsSyntaxError(JsBaseExcept):
- pass
diff --git a/js/execution_context.py b/js/execution_context.py
--- a/js/execution_context.py
+++ b/js/execution_context.py
@@ -45,6 +45,9 @@
def lexical_environment(self):
return self._lexical_environment_
+ def set_lexical_environment(self, lex_env):
+ self._lexical_environment_ = lex_env
+
def declaration_binding_initialization(self):
env = self._variable_environment_.environment_record
strict = self._strict_
diff --git a/js/jscode.py b/js/jscode.py
--- a/js/jscode.py
+++ b/js/jscode.py
@@ -3,7 +3,7 @@
from pypy.rlib.jit import JitDriver, purefunction
from js.execution import JsTypeError, ReturnException, ThrowException, JsReferenceError
-from js.opcodes import opcodes, LABEL, BaseJump, WITH_START, WITH_END
+from js.opcodes import opcodes, LABEL, BaseJump
from js.jsobj import W_Root, W_String, _w, w_Null, w_Undefined
from pypy.rlib import jit, debug
@@ -171,6 +171,11 @@
#self.unpop()
return self.opcodes
+ def to_executable_opcodes(self):
+ self.unlabel()
+ self.unpop()
+ return self.opcodes
+
def remove_labels(self):
""" Basic optimization to remove all labels and change
jumps to addresses. Necessary to run code at all
diff --git a/js/jsobj.py b/js/jsobj.py
--- a/js/jsobj.py
+++ b/js/jsobj.py
@@ -2,7 +2,7 @@
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, JsRangeError, ReturnException
+from js.execution import JsTypeError, JsRangeError, ReturnException
from pypy.rlib.jit import hint
from pypy.rlib import jit, debug
diff --git a/js/lexical_environment.py b/js/lexical_environment.py
--- a/js/lexical_environment.py
+++ b/js/lexical_environment.py
@@ -81,7 +81,8 @@
base = v.get_base()
if v.is_unresolvable_reference():
- raise JsReferenceError()
+ referenced = v.get_referenced_name()
+ raise JsReferenceError(referenced)
if v.is_property_reference():
raise NotImplementedError('8.7.1 4.')
@@ -100,7 +101,8 @@
base = v.get_base()
if v.is_unresolvable_reference():
if v.is_strict_reference():
- raise JsReferenceError()
+ referenced = v.get_referenced_name()
+ raise JsReferenceError(referenced)
else:
name = v.get_referenced_name()
# TODO how to solve this ????
diff --git a/js/opcodes.py b/js/opcodes.py
--- a/js/opcodes.py
+++ b/js/opcodes.py
@@ -233,7 +233,7 @@
class TYPEOF(BaseUnaryOperation):
def eval(self, ctx):
- one = ctx.stack_pop()
+ var = ctx.stack_pop()
ctx.stack_append(W_String(one.type()))
class TYPEOF_VARIABLE(Opcode):
@@ -242,20 +242,13 @@
self.name = name
def eval(self, ctx):
- try:
- ref = ctx.get_ref(self.name)
+ ref = ctx.get_ref(self.name)
+ if ref.is_unresolvable_reference():
+ var_type = 'undefined'
+ else:
var = ref.get_value()
var_type = var.type()
- ctx.stack_append(W_String(var_type))
- except ThrowException:
- ctx.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())
+ ctx.stack_append(W_String(var_type))
class ADD(BaseBinaryOperation):
def operation(self, ctx, left, right):
@@ -568,33 +561,39 @@
class TRYCATCHBLOCK(Opcode):
_stack_change = 0
def __init__(self, tryfunc, catchparam, catchfunc, finallyfunc):
- self.tryfunc = tryfunc
- self.catchfunc = catchfunc
+ self.tryexec = tryfunc
+ self.catchexec = catchfunc
self.catchparam = catchparam
- self.finallyfunc = finallyfunc
+ self.finallyexec = finallyfunc
def eval(self, ctx):
+ from js.execution import JsException
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
- from js.jsexecution_context import make_catch_context
- newctx = make_catch_context(ctx, self.catchparam, e.exception)
- self.catchfunc.run(newctx)
- 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
+ b = self.tryexec.run(ctx)
+ except JsException, e:
+ if self.catchexec is not None:
+ old_env = ctx.lexical_environment()
- #def __repr__(self):
- #return "TRYCATCHBLOCK" # XXX shall we add stuff here???
+ from js.lexical_environment import DeclarativeEnvironment
+ catch_env = DeclarativeEnvironment(old_env)
+ catch_env_rec = catch_env.environment_record
+ catch_env_rec.create_mutuable_binding(self.catchparam, True)
+ b = e.value
+ catch_env_rec.set_mutable_binding(self.catchparam, b, False)
+ ctx.set_lexical_environment(catch_env)
+ c = self.catchexec.run(ctx)
+ ctx.set_lexical_environment(old_env)
+ else:
+ c = b
+
+ if self.finallyexec is not None:
+ f = self.finallyexec.run(ctx)
+ if f is None:
+ f = c
+ else:
+ f = c
+
+ ctx.stack_append(f)
class NEW(Opcode):
_stack_change = 0
@@ -651,23 +650,27 @@
# ---------------- with support ---------------------
-class WITH_START(Opcode):
- _stack_change = 0
- def __init__(self):
- self.newctx = None
+class WITH(Opcode):
+ def __init__(self, expr, body):
+ self.expr = expr
+ self.body = body
def eval(self, ctx):
- from js.lexical_environment import ObjectEnvironment
- obj = ctx.stack_pop().ToObject()
+ from lexical_environment import ObjectEnvironment
+ # 12.10
+ expr = self.expr.run(ctx)
+ expr_obj = expr.ToObject()
+
old_env = ctx.lexical_environment()
- new_env = ObjectEnvironment(obj, outer_environment = old_env)
+ new_env = ObjectEnvironment(expr_obj, outer_environment = old_env)
new_env.environment_record.provide_this = True
- ctx._lexical_environment_ = new_env
+ ctx.set_lexical_environment(new_env)
-class WITH_END(Opcode):
- _stack_change = 0
- def eval(self, ctx):
- ctx._lexical_environment_ = ctx.lexical_environment().outer_environment
+ try:
+ c = self.body.run(ctx)
+ ctx.stack_append(c)
+ finally:
+ ctx.set_lexical_environment(old_env)
# ------------------ delete -------------------------
diff --git a/js/operations.py b/js/operations.py
--- a/js/operations.py
+++ b/js/operations.py
@@ -730,25 +730,27 @@
def emit(self, bytecode):
from js.jscode import JsCode
- # a bit naive operator for now
+ from js.functions import JsExecutableCode
+
trycode = JsCode()
self.tryblock.emit(trycode)
+ tryexec = JsExecutableCode(trycode)
- #tryfunc = trycode.make_js_function()
if self.catchblock:
catchcode = JsCode()
self.catchblock.emit(catchcode)
- # catchfunc = catchcode.make_js_function()
+ catchexec = JsExecutableCode(catchcode)
else:
catchfunc = None
+
if self.finallyblock:
finallycode = JsCode()
self.finallyblock.emit(finallycode)
- # finallyfunc = finallycode.make_js_function()
+ finallyexec = JsExecutableCode(finallycode)
else:
- finallyfunc = None
- raise NotImplementedError()
- bytecode.emit('TRYCATCHBLOCK', tryfunc, self.catchparam.get_literal(), catchfunc, finallyfunc)
+ finallyexec = None
+ catchparam = self.catchparam.get_literal()
+ bytecode.emit('TRYCATCHBLOCK', tryexec, catchparam, catchexec, finallyexec)
class VariableDeclaration(Expression):
def __init__(self, pos, identifier, index, expr=None):
@@ -860,10 +862,18 @@
self.body = body
def emit(self, bytecode):
- self.expr.emit(bytecode)
- bytecode.emit('WITH_START')
- self.body.emit(bytecode)
- bytecode.emit('WITH_END')
+ from js.jscode import JsCode
+ from js.functions import JsExecutableCode
+
+ expr_code = JsCode()
+ self.expr.emit(expr_code)
+ expr_exec = JsExecutableCode(expr_code)
+
+ body_code = JsCode()
+ self.body.emit(body_code)
+ body_exec = JsExecutableCode(body_code)
+
+ bytecode.emit('WITH', expr_exec, body_exec)
class WhileBase(Statement):
def __init__(self, pos, condition, body):
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
@@ -216,9 +216,9 @@
print(x.length)
""", '\n0', capsys)
- at xfail
def test_throw(capsys):
- assertp("throw(3);", "uncaught exception: 3", capsys)
+ from js.execution import JsThrowException
+ asserte("throw(3);", JsThrowException)
def test_group():
assertv("(2+1);", 3)
@@ -230,7 +230,6 @@
assertp("{print(5);}", '5', capsys)
assertp("{3; print(5);}", '5', capsys)
- at xfail
def test_try_catch_finally(capsys):
assertp("""
try {
@@ -321,14 +320,13 @@
o;
""", "[object Object]")
- at xfail
def test_var_decl(capsys):
assertp("print(x); var x;", "undefined", capsys)
assertp("""
try {
print(z);
}
- catch (e) {
+ catch(e){
print(e);
}
""", "ReferenceError: z is not defined", capsys)
@@ -395,7 +393,6 @@
}
print('out');""", "out", capsys)
- at xfail
def test_typeof():
assertv("""
var x = 3;
@@ -555,7 +552,6 @@
assertv("2 !== 3;", True)
assertv("2 !== 2;", False)
- at xfail
def test_with(capsys):
assertp("""
var mock = {x:2};
More information about the pypy-commit
mailing list