Author: Stephan <[email protected]>
Branch:
Changeset: r257:dcc0d7e2c80c
Date: 2012-06-06 12:27 +0200
http://bitbucket.org/pypy/lang-js/changeset/dcc0d7e2c80c/
Log: added instanceof operator
diff --git a/js/astbuilder.py b/js/astbuilder.py
--- a/js/astbuilder.py
+++ b/js/astbuilder.py
@@ -87,6 +87,7 @@
'[': operations.Member,
',': operations.Comma,
'in': operations.In,
+ 'instanceof': operations.InstanceOf,
}
UNOP_TO_CLS = {
'~': operations.BitwiseNot,
diff --git a/js/jsobj.py b/js/jsobj.py
--- a/js/jsobj.py
+++ b/js/jsobj.py
@@ -578,6 +578,8 @@
def ToObject(self):
return self
+ def has_instance(self, other):
+ raise JsTypeError()
###
def named_properties(self):
@@ -676,6 +678,23 @@
def _to_string_(self):
return 'function() {}'
+ # 15.3.5.3
+ def has_instance(self, v):
+ if not isinstance(v, W_BasicObject):
+ return False
+
+ o = self.get('prototype')
+
+ if not isinstance(o, W_BasicObject):
+ raise JsTypeError()
+
+ while True:
+ v = v.prototype()
+ if isnull_or_undefined(v):
+ return False
+ if v == o:
+ return True
+
class W_ObjectConstructor(W_BasicFunction):
def Call(self, args = [], this = None, calling_context = None):
from js.builtins import get_arg
diff --git a/js/opcodes.py b/js/opcodes.py
--- a/js/opcodes.py
+++ b/js/opcodes.py
@@ -800,24 +800,15 @@
#def __repr__(self):
#return 'STORE_LOCAL %d' % (self.local,)
-class SETUP_TRY(Opcode):
- def __init__(self, end):
- self.end = end
-
+class INSTANCEOF(Opcode):
def eval(self, ctx):
- from js.jsobj import W_Try
- ctx.stack_push(W_Try(self.end))
-
- def __str__(self):
- return 'SETUP_TRY %d' % (self.end)
-
-class POP_BLOCK(Opcode):
- def eval(self, ctx):
- from js.jsobj import W_Block
- while True:
- b = ctx.stack_pop()
- if isinstance(b, W_Block):
- break
+ rval = ctx.stack_pop()
+ lval = ctx.stack_pop()
+ from js.jsobj import W_BasicObject
+ if not isinstance(rval, W_BasicObject):
+ raise JsTypeError(str(rval))
+ res = rval.has_instance(lval)
+ ctx.stack_append(_w(res))
# different opcode mappings, to make annotator happy
diff --git a/js/operations.py b/js/operations.py
--- a/js/operations.py
+++ b/js/operations.py
@@ -521,6 +521,7 @@
StrictNe = create_binary_op('ISNOT')
In = create_binary_op('IN')
+InstanceOf = create_binary_op('INSTANCEOF')
class Typeof(Expression):
def __init__(self, pos, left):
@@ -743,6 +744,7 @@
catchcode = JsCode()
self.catchblock.emit(catchcode)
catchexec = JsExecutableCode(catchcode)
+ catchparam = self.catchparam.get_literal()
else:
catchfunc = 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
@@ -973,3 +973,7 @@
assertv("function f() { try { return 1; } catch(e) { return -1; } }; f()",
1)
assertv("function f() { try { throw('foo'); return 1; } catch(e) { return
-1; } }; f()", -1)
assertv("function f() { try { throw('foo'); return 1; } catch(e) { return
-1; } finally { return 0; } }; f()", 0)
+
+def test_instanceof():
+ assertv("function f(){this.a = 1;}; x = new f(); x instanceof f;", True);
+ assertv("function f(){this.a = 1;}; function g(){this.a = b;}; x = new
f(); x instanceof g;", False);
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit