Author: Stephan <step...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit