[pypy-commit] lang-js default: undeclared variables fall back to global context
stepahn
noreply at buildbot.pypy.org
Fri Dec 28 11:32:15 CET 2012
Author: Stephan <stephan at stzal.com>
Branch:
Changeset: r118:9337ab6d62ef
Date: 2011-09-04 17:18 +0200
http://bitbucket.org/pypy/lang-js/changeset/9337ab6d62ef/
Log: undeclared variables fall back to global context
diff --git a/js/jsexecution_context.py b/js/jsexecution_context.py
--- a/js/jsexecution_context.py
+++ b/js/jsexecution_context.py
@@ -1,4 +1,5 @@
from js.utils import MapDict, StackMixin
+from js.jsobj import DD
class JSContext(object):
def __init__(self, parent=None):
@@ -35,13 +36,12 @@
return
p.value = value
except KeyError:
- p = Property(name, value)
- self._identifier_set(name, p)
+ self.get_global_context().put(name, value, flags=0)
- def declare_variable(self, identifier):
- from js.jsobj import w_Undefined, DD, Property
+ def declare_variable(self, identifier, flags=DD):
+ from js.jsobj import w_Undefined, Property
self.values.addname(identifier)
- p = Property(identifier, w_Undefined, flags = DD)
+ p = Property(identifier, w_Undefined, flags)
self._identifier_set_local(identifier, p)
def get_local_value(self, idx):
@@ -87,17 +87,20 @@
prop.value = value
def get_global(self):
+ return self.get_global_context().to_context_object()
+
+ def get_global_context(self):
if self.parent:
- return self.parent.get_global()
+ return self.parent.get_global_context()
else:
- return self.to_context_object()
+ return self
def to_context_object(self):
from jsobj import W_ContextObject
return W_ContextObject(self)
- def put(self, name, value):
- self.declare_variable(name)
+ def put(self, name, value, flags=DD):
+ self.declare_variable(name, flags)
self.assign(name, value)
def delete_identifier(self, name):
diff --git a/js/jsobj.py b/js/jsobj.py
--- a/js/jsobj.py
+++ b/js/jsobj.py
@@ -9,10 +9,11 @@
from js.utils import StackMixin
import string
-DE = 1
-DD = 2
-RO = 4
-IT = 8
+# see ECMA 8.6.1 Property attributes
+DE = 1 # DontEnum
+DD = 2 # DontDelete
+RO = 4 # ReadOnly
+IT = 8 # Internal
class SeePage(NotImplementedError):
pass
diff --git a/js/test/test_execution_context.py b/js/test/test_execution_context.py
--- a/js/test/test_execution_context.py
+++ b/js/test/test_execution_context.py
@@ -181,3 +181,17 @@
p_foo = Property('foo', 0)
parent._identifier_set_local('foo', p_foo)
py.test.raises(KeyError, context.get_local_value, 0)
+
+ def test_assign_global_default(self):
+ global_ctx = ExecutionContext()
+ parent = ExecutionContext(global_ctx)
+ context = ExecutionContext(parent)
+
+ context.assign('foo', 0)
+ py.test.raises(KeyError, context._identifier_get_local, 'foo')
+ py.test.raises(KeyError, parent._identifier_get_local, 'foo')
+ assert global_ctx._identifier_get_local('foo')
+ parent.assign('bar', 0)
+ py.test.raises(KeyError, context._identifier_get_local, 'bar')
+ py.test.raises(KeyError, parent._identifier_get_local, 'bar')
+ assert global_ctx._identifier_get_local('bar')
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
@@ -117,6 +117,14 @@
print(x(), y, p);
""", ["5,3,0"])
+def test_var_scoping_default_global():
+ yield assertv, 'd = 1; function x() { d=2;}; x(); d;', 2
+ yield assertv, 'd = 1; function x() { var d=2;}; x(); d;', 1
+ yield assertv, 'function x() { d=2;}; x(); d;', 2
+ yield assertv, 'var d = 1; function x() { d=2; }; x(); d;', 2
+ yield assertv, 'function x() { d=2;}; function y() { return d; }; x(); y();', 2
+ yield assertv, 'var d; function x() { d=2;}; function y() { return d; }; x(); y();', 2
+
def test_function_args():
assertv("""
x = function (t,r) {
More information about the pypy-commit
mailing list