[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