[pypy-commit] lang-js default: replaced bindings dict of EnvironmentRecord with map

stepahn noreply at buildbot.pypy.org
Fri Dec 28 11:35:10 CET 2012


Author: Stephan <stephan at stzal.com>
Branch: 
Changeset: r288:4cd0097a6f22
Date: 2012-08-25 21:40 +0200
http://bitbucket.org/pypy/lang-js/changeset/4cd0097a6f22/

Log:	replaced bindings dict of EnvironmentRecord with map

diff --git a/js/environment_record.py b/js/environment_record.py
--- a/js/environment_record.py
+++ b/js/environment_record.py
@@ -1,4 +1,10 @@
 from js.jsobj import w_Undefined
+from js.object_map import ROOT_MAP
+
+
+def _new_map():
+    return ROOT_MAP
+
 
 class EnvironmentRecord(object):
     def __init__(self):
@@ -25,30 +31,63 @@
 class DeclarativeEnvironmentRecord(EnvironmentRecord):
     def __init__(self):
         EnvironmentRecord.__init__(self)
-        self.bindings = {}
-        self.mutable_bindings = {}
-        self.deletable_bindings = {}
+        self._binding_map_ = _new_map()
+        self._binding_slots_ = []
+        self._mutable_bindings_map_ = _new_map()
+        self._deletable_bindings_map_ = _new_map()
 
     def _is_mutable_binding(self, identifier):
-        return self.mutable_bindings.get(identifier, False) == True
+        return self._mutable_bindings_map_.contains(identifier)
 
     def _set_mutable_binding(self, identifier):
-        self.mutable_bindings[identifier] = True
+        self._mutable_bindings_map_ = self._mutable_bindings_map_.add(identifier)
 
     def _is_deletable_binding(self, identifier):
-        return self.deletable_bindings.get(identifier, False) == True
+        return self._deletable_bindings_map_.contains(identifier)
 
     def _set_deletable_binding(self, identifier):
-        self.deletable_bindings[identifier] = True
+        self._deletable_bindings_ = self._deletable_bindings_map_.add(identifier)
 
     # 10.2.1.1.1
     def has_binding(self, identifier):
-        return identifier in self.bindings
+        return self._binding_map_.contains(identifier)
+
+    def _get_binding(self, name):
+        idx = self._binding_map_.lookup(name)
+
+        if self._binding_map_.not_found(idx):
+            return
+        if idx >= len(self._binding_slots_):
+            return
+
+        binding = self._binding_slots_[idx]
+        return binding
+
+    def _set_binding(self, name, value):
+        idx = self._binding_map_.lookup(name)
+
+        if self._binding_map_.not_found(idx):
+            self._binding_map_ = self._binding_map_.add(name)
+            idx = self._binding_map_.index
+
+        if idx >= len(self._binding_slots_):
+            self._binding_slots_ += ([None] * (1 + idx - len(self._binding_slots_)))
+
+        self._binding_slots_[idx] = value
+
+    def _del_binding(self, name):
+        idx = self._binding_map_.lookup(name)
+
+        if self._binding_map_.not_found(idx):
+            return
+
+        del(self._binding_slots_[idx])
+        self._binding_map_ = self._binding_map_.delete(name)
 
     # 10.2.1.1.2
     def create_mutuable_binding(self, identifier, deletable):
         assert not self.has_binding(identifier)
-        self.bindings[identifier] = w_Undefined
+        self._set_binding(identifier, w_Undefined)
         self._set_mutable_binding(identifier)
         if deletable:
             self._set_deletable_binding(identifier)
@@ -60,18 +99,12 @@
         if not self._is_mutable_binding(identifier):
             from js.execution import JsTypeError
             raise JsTypeError(u'immutable binding')
-        self.bindings[identifier] = value
+        self._set_binding(identifier, value)
 
     # 10.2.1.1.4
     def get_binding_value(self, identifier, strict=False):
         assert self.has_binding(identifier)
-        if not identifier in self.bindings:
-            if strict:
-                from js.execution import JsReferenceError
-                raise JsReferenceError(identifier)
-            else:
-                return w_Undefined
-        return self.bindings[identifier]
+        return self._get_binding(identifier)
 
     # 10.2.1.1.5
     def delete_binding(self, identifier):
@@ -81,9 +114,9 @@
             return False
         if self._is_deletable_binding(identifier) is False:
             return False
-        del(self.deletable_bindings[identifier])
-        del(self.mutable_bindings[identifier])
-        del(self.bindings[identifier])
+        self._deletable_bindings_map__ = self._deletable_bindings_map_.delete(identifier)
+        self._mutable_bindings_map_ = self._mutable_bindings_map_.delete(identifier)
+        self._del_binding(identifier)
         return False
 
     # 10.2.1.1.6
diff --git a/js/object_map.py b/js/object_map.py
--- a/js/object_map.py
+++ b/js/object_map.py
@@ -1,19 +1,30 @@
 from pypy.rlib import jit
 
+
 class Map(object):
     NOT_FOUND = -1
-    _immutable_fields_ = ['index', 'back', 'name', 'flags']
+    _immutable_fields_ = ['index', 'back', 'name', 'forward_pointers']
+
     def __init__(self):
         self.index = self.NOT_FOUND
         self.forward_pointers = {}
         self.back = None
         self.name = None
-        self.flags = 0
 
     def __repr__(self):
-        return "%(back)s, [%(index)d]:%(name)s(%(flags)d)" % \
-            {'back': repr(self.back), 'index': self.index, 'name': self.name, 'flags': self.flags}
+        return "%(back)s, [%(index)d]:%(name)s" % \
+            {'back': repr(self.back), 'index': self.index, 'name': self.name}
 
+    @jit.elidable
+    def contains(self, name):
+        idx = self.lookup(name)
+        return self.not_found(idx)
+
+    @jit.elidable
+    def not_found(self, idx):
+        return idx == self.NOT_FOUND
+
+    @jit.elidable
     def lookup(self, name):
         jit.promote(self)
         node = self._find_node_with_name(name)
@@ -21,40 +32,25 @@
             return node.index
         return self.NOT_FOUND
 
-    def lookup_flag(self, name):
-        jit.promote(self)
-        node = self._find_node_with_name(name)
-        if node is not None:
-            return node.flags
-        return self.NOT_FOUND
-
     def _find_node_with_name(self, name):
         if self.name == name:
             return self
         if self.back is not None:
             return self.back._find_node_with_name(name)
 
-    def _find_node_with_name_and_flags(self, name, flags):
-        if self.name == name and self.flags == flags:
-            return self
-        node = None
-        if self.back is not None:
-            node = self.back._find_node_with_name_and_flags(name, flags)
-        if node is None:
-            return self.forward_pointers.get((name, flags), None)
-
     def _key(self):
-        return (self.name, self.flags)
+        return (self.name)
 
     @jit.elidable
-    def add(self, name, flags=0):
+    def add(self, name):
         assert self.lookup(name) == self.NOT_FOUND
-        node = self.forward_pointers.get((name, flags), None)
+        node = self.forward_pointers.get((name), None)
         if node is None:
-            node = MapNode(self, name, flags)
+            node = MapNode(self, name)
             self.forward_pointers[node._key()] = node
         return node
 
+    @jit.elidable
     def keys(self):
         if self.name is None:
             return []
@@ -65,42 +61,33 @@
 
         return k
 
-    def set_flags(self, name, flags):
-        return self
-
     def delete(self, key):
         return self
 
+
 class MapRoot(Map):
     def __repr__(self):
-        return "[%(index)d]:%(name)s(%(flags)d)" % {'index': self.index, 'name': self.name, 'flags': self.flags}
+        return "[%(index)d]:%(name)s" % {'index': self.index, 'name': self.name}
+
 
 class MapNode(Map):
-    def __init__(self, back, name, flags = 0):
+    def __init__(self, back, name):
         Map.__init__(self)
         self.back = back
         self.name = name
         self.index = back.index + 1
-        self.flags = flags
 
+    @jit.elidable
     def delete(self, name):
         if self.name == name:
             return self.back
         else:
             n = self.back.delete(name)
-            return n.add(self.name, self.flags)
+            return n.add(self.name)
 
-    def set_flags(self, name, flags):
-        if self.name == name:
-            if self.flags == flags:
-                return self
-            else:
-                return self.back.add(name, flags)
-        else:
-            n = self.back.set_flags(name, flags)
-            return n.add(self.name, self.flags)
 
 ROOT_MAP = MapRoot()
 
+
 def root_map():
     return ROOT_MAP


More information about the pypy-commit mailing list