[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