def make_constant(self, constbox): """Replace 'self.box' with a Const box.""" assert isinstance(constbox, Const) self.box = constbox self.level = LEVEL_CONSTANT if isinstance(constbox, ConstInt): val = constbox.getint() self.intbound = IntBound(val, val) else: self.intbound = IntUnbounded()
def make_constant(self, constbox): """Replace 'self.box' with a Const box.""" assert isinstance(constbox, Const) self.box = constbox self.level = LEVEL_CONSTANT if isinstance(constbox, ConstInt): val = constbox.getint() self.intbound = IntBound(val, val) else: self.intbound = IntUnbounded()
def __init__(self, value): self.known_class = value.known_class self.level = value.level if value.intbound is None: self.intbound = IntUnbounded() else: self.intbound = value.intbound.clone() if value.is_constant(): self.constbox = value.box else: self.constbox = None self.position_in_notvirtuals = -1 self.lenbound = value.lenbound
def __init__(self, box, level=None, known_class=None, intbound=None): self.box = box if level is not None: self.level = level self.known_class = known_class if intbound: self.intbound = intbound else: if isinstance(box, BoxInt): self.intbound = IntBound(MININT, MAXINT) else: self.intbound = IntUnbounded() if isinstance(box, Const): self.make_constant(box)
def __init__(self, box, level=None, known_class=None, intbound=None): self.box = box if level is not None: self.level = level self.known_class = known_class if intbound: self.intbound = intbound else: if isinstance(box, BoxInt): self.intbound = IntBound(MININT, MAXINT) else: self.intbound = IntUnbounded() if isinstance(box, Const): self.make_constant(box)
def bound(a, b): if a is None and b is None: return IntUnbounded() elif a is None: return IntUpperBound(b) elif b is None: return IntLowerBound(a) else: return IntBound(a, b)
def __init__(self, value): self.known_class = value.known_class self.level = value.level if value.intbound is None: self.intbound = IntUnbounded() else: self.intbound = value.intbound.clone() if value.is_constant(): self.constbox = value.box else: self.constbox = None self.position_in_notvirtuals = -1 self.lenbound = value.lenbound
def test_make(): for _, _, b1 in some_bounds(): for _, _, b2 in some_bounds(): lt = IntUnbounded() lt.make_lt(b1) lt.make_lt(b2) for n in nbr: c = const(n) if b1.known_le(c) or b2.known_le(c): assert lt.known_lt(c) else: assert not lt.known_lt(c) assert not lt.known_gt(c) assert not lt.known_ge(c) gt = IntUnbounded() gt.make_gt(b1) gt.make_gt(b2) for n in nbr: c = const(n) if b1.known_ge(c) or b2.known_ge(c): assert gt.known_gt(c) else: assert not gt.known_gt(c) assert not gt.known_lt(c) assert not gt.known_le(c) le = IntUnbounded() le.make_le(b1) le.make_le(b2) for n in nbr: c = const(n) if b1.known_le(c) or b2.known_le(c): assert le.known_le(c) else: assert not le.known_le(c) assert not le.known_gt(c) assert not le.known_ge(c) ge = IntUnbounded() ge.make_ge(b1) ge.make_ge(b2) for n in nbr: c = const(n) if b1.known_ge(c) or b2.known_ge(c): assert ge.known_ge(c) else: assert not ge.known_ge(c) assert not ge.known_lt(c) assert not ge.known_le(c) gl = IntUnbounded() gl.make_ge(b1) gl.make_le(b2) for n in nbr: c = const(n) if b1.known_ge(c): assert gl.known_ge(c) else: assert not gl.known_ge(c) assert not gl.known_gt(c) if b2.known_le(c): assert gl.known_le(c) else: assert not gl.known_le(c) assert not gl.known_lt(c)
class NotVirtualStateInfo(AbstractVirtualStateInfo): def __init__(self, value): self.known_class = value.known_class self.level = value.level if value.intbound is None: self.intbound = IntUnbounded() else: self.intbound = value.intbound.clone() if value.is_constant(): self.constbox = value.box else: self.constbox = None self.position_in_notvirtuals = -1 self.lenbound = value.lenbound def generalization_of(self, other, renum, bad): # XXX This will always retrace instead of forcing anything which # might be what we want sometimes? assert self.position != -1 if self.position in renum: if renum[self.position] == other.position: return True bad[self] = True bad[other] = True return False renum[self.position] = other.position if not isinstance(other, NotVirtualStateInfo): bad[self] = True bad[other] = True return False if other.level < self.level: bad[self] = True bad[other] = True return False if self.level == LEVEL_CONSTANT: if not self.constbox.same_constant(other.constbox): bad[self] = True bad[other] = True return False elif self.level == LEVEL_KNOWNCLASS: if not self.known_class.same_constant(other.known_class): bad[self] = True bad[other] = True return False if not self.intbound.contains_bound(other.intbound): bad[self] = True bad[other] = True return False if self.lenbound and other.lenbound: if self.lenbound.mode != other.lenbound.mode or \ self.lenbound.descr != other.lenbound.descr or \ not self.lenbound.bound.contains_bound(other.lenbound.bound): bad[self] = True bad[other] = True return False elif self.lenbound: bad[self] = True bad[other] = True return False return True def _generate_guards(self, other, box, cpu, extra_guards): if not isinstance(other, NotVirtualStateInfo): raise InvalidLoop('The VirtualStates does not match as a ' + 'virtual appears where a pointer is needed ' + 'and it is too late to force it.') if self.lenbound or other.lenbound: raise InvalidLoop('The array length bounds does not match.') if self.level == LEVEL_KNOWNCLASS and \ box.nonnull() and \ self.known_class.same_constant(cpu.ts.cls_of_box(box)): # Note: This is only a hint on what the class of box was # during the trace. There are actually no guarentees that this # box realy comes from a trace. The hint is used here to choose # between either eimtting a guard_class and jumping to an # excisting compiled loop or retracing the loop. Both # alternatives will always generate correct behaviour, but # performace will differ. op = ResOperation(rop.GUARD_NONNULL, [box], None) extra_guards.append(op) op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None) extra_guards.append(op) return if self.level == LEVEL_NONNULL and \ other.level == LEVEL_UNKNOWN and \ isinstance(box, BoxPtr) and \ box.nonnull(): op = ResOperation(rop.GUARD_NONNULL, [box], None) extra_guards.append(op) return if self.level == LEVEL_UNKNOWN and \ other.level == LEVEL_UNKNOWN and \ isinstance(box, BoxInt) and \ self.intbound.contains(box.getint()): if self.intbound.has_lower: bound = self.intbound.lower if not (other.intbound.has_lower and \ other.intbound.lower >= bound): res = BoxInt() op = ResOperation(rop.INT_GE, [box, ConstInt(bound)], res) extra_guards.append(op) op = ResOperation(rop.GUARD_TRUE, [res], None) extra_guards.append(op) if self.intbound.has_upper: bound = self.intbound.upper if not (other.intbound.has_upper and \ other.intbound.upper <= bound): res = BoxInt() op = ResOperation(rop.INT_LE, [box, ConstInt(bound)], res) extra_guards.append(op) op = ResOperation(rop.GUARD_TRUE, [res], None) extra_guards.append(op) return # Remaining cases are probably not interesting raise InvalidLoop('Generating guards for making the VirtualStates ' + 'at hand match have not been implemented') if self.level == LEVEL_CONSTANT: import pdb; pdb.set_trace() raise NotImplementedError def enum_forced_boxes(self, boxes, value, optimizer): if self.level == LEVEL_CONSTANT: return assert 0 <= self.position_in_notvirtuals if optimizer: box = value.force_box(optimizer) else: if value.is_virtual(): raise BadVirtualState box = value.get_key_box() boxes[self.position_in_notvirtuals] = box def _enum(self, virtual_state): if self.level == LEVEL_CONSTANT: return self.position_in_notvirtuals = len(virtual_state.notvirtuals) virtual_state.notvirtuals.append(self) def debug_print(self, indent, seen, bad): mark = '' if self in bad: mark = '*' if we_are_translated(): l = {LEVEL_UNKNOWN: 'Unknown', LEVEL_NONNULL: 'NonNull', LEVEL_KNOWNCLASS: 'KnownClass', LEVEL_CONSTANT: 'Constant', }[self.level] else: l = {LEVEL_UNKNOWN: 'Unknown', LEVEL_NONNULL: 'NonNull', LEVEL_KNOWNCLASS: 'KnownClass(%r)' % self.known_class, LEVEL_CONSTANT: 'Constant(%r)' % self.constbox, }[self.level] lb = '' if self.lenbound: lb = ', ' + self.lenbound.bound.__repr__() debug_print(indent + mark + 'NotVirtualInfo(%d' % self.position + ', ' + l + ', ' + self.intbound.__repr__() + lb + ')')
class OptValue(object): __metaclass__ = extendabletype _attrs_ = ('box', 'known_class', 'last_guard', 'level', 'intbound', 'lenbound') last_guard = None level = LEVEL_UNKNOWN known_class = None intbound = ImmutableIntUnbounded() lenbound = None def __init__(self, box, level=None, known_class=None, intbound=None): self.box = box if level is not None: self.level = level self.known_class = known_class if intbound: self.intbound = intbound else: if isinstance(box, BoxInt): self.intbound = IntBound(MININT, MAXINT) else: self.intbound = IntUnbounded() if isinstance(box, Const): self.make_constant(box) # invariant: box is a Const if and only if level == LEVEL_CONSTANT def make_len_gt(self, mode, descr, val): if self.lenbound: assert self.lenbound.mode == mode assert self.lenbound.descr == descr self.lenbound.bound.make_gt(IntBound(val, val)) else: self.lenbound = LenBound(mode, descr, IntLowerBound(val + 1)) def make_guards(self, box): guards = [] if self.level == LEVEL_CONSTANT: op = ResOperation(rop.GUARD_VALUE, [box, self.box], None) guards.append(op) elif self.level == LEVEL_KNOWNCLASS: op = ResOperation(rop.GUARD_NONNULL, [box], None) guards.append(op) op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None) guards.append(op) else: if self.level == LEVEL_NONNULL: op = ResOperation(rop.GUARD_NONNULL, [box], None) guards.append(op) self.intbound.make_guards(box, guards) if self.lenbound: lenbox = BoxInt() if self.lenbound.mode == MODE_ARRAY: op = ResOperation(rop.ARRAYLEN_GC, [box], lenbox, self.lenbound.descr) elif self.lenbound.mode == MODE_STR: op = ResOperation(rop.STRLEN, [box], lenbox, self.lenbound.descr) elif self.lenbound.mode == MODE_UNICODE: op = ResOperation(rop.UNICODELEN, [box], lenbox, self.lenbound.descr) else: debug_print("Unknown lenbound mode") assert False guards.append(op) self.lenbound.bound.make_guards(lenbox, guards) return guards def import_from(self, other, optimizer): if self.level == LEVEL_CONSTANT: assert other.level == LEVEL_CONSTANT assert other.box.same_constant(self.box) return assert self.level <= LEVEL_NONNULL if other.level == LEVEL_CONSTANT: self.make_constant(other.get_key_box()) optimizer.turned_constant(self) elif other.level == LEVEL_KNOWNCLASS: self.make_constant_class(other.known_class, None) else: if other.level == LEVEL_NONNULL: self.ensure_nonnull() self.intbound.intersect(other.intbound) if other.lenbound: if self.lenbound: assert other.lenbound.mode == self.lenbound.mode assert other.lenbound.descr == self.lenbound.descr self.lenbound.bound.intersect(other.lenbound.bound) else: self.lenbound = other.lenbound.clone() def force_box(self, optforce): return self.box def get_key_box(self): return self.box def force_at_end_of_preamble(self, already_forced, optforce): return self def get_args_for_fail(self, modifier): pass def make_virtual_info(self, modifier, fieldnums): #raise NotImplementedError # should not be called on this level assert fieldnums is None return modifier.make_not_virtual(self) def is_constant(self): return self.level == LEVEL_CONSTANT def is_null(self): if self.is_constant(): box = self.box assert isinstance(box, Const) return not box.nonnull() return False def same_value(self, other): if not other: return False if self.is_constant() and other.is_constant(): return self.box.same_constant(other.box) return self is other def make_constant(self, constbox): """Replace 'self.box' with a Const box.""" assert isinstance(constbox, Const) self.box = constbox self.level = LEVEL_CONSTANT if isinstance(constbox, ConstInt): val = constbox.getint() self.intbound = IntBound(val, val) else: self.intbound = IntUnbounded() def get_constant_class(self, cpu): level = self.level if level == LEVEL_KNOWNCLASS: return self.known_class elif level == LEVEL_CONSTANT: return cpu.ts.cls_of_box(self.box) else: return None def make_constant_class(self, classbox, guardop): assert self.level < LEVEL_KNOWNCLASS self.known_class = classbox self.level = LEVEL_KNOWNCLASS self.last_guard = guardop def make_nonnull(self, guardop): assert self.level < LEVEL_NONNULL self.level = LEVEL_NONNULL self.last_guard = guardop def is_nonnull(self): level = self.level if level == LEVEL_NONNULL or level == LEVEL_KNOWNCLASS: return True elif level == LEVEL_CONSTANT: box = self.box assert isinstance(box, Const) return box.nonnull() elif self.intbound: if self.intbound.known_gt(IntBound(0, 0)) or \ self.intbound.known_lt(IntBound(0, 0)): return True else: return False else: return False def ensure_nonnull(self): if self.level < LEVEL_NONNULL: self.level = LEVEL_NONNULL def is_virtual(self): # Don't check this with 'isinstance(_, VirtualValue)'! # Even if it is a VirtualValue, the 'box' can be non-None, # meaning it has been forced. return self.box is None def is_forced_virtual(self): return False def getfield(self, ofs, default): raise NotImplementedError def setfield(self, ofs, value): raise NotImplementedError def getlength(self): raise NotImplementedError def getitem(self, index): raise NotImplementedError def setitem(self, index, value): raise NotImplementedError def getinteriorfield(self, index, ofs, default): raise NotImplementedError def setinteriorfield(self, index, ofs, value): raise NotImplementedError
class OptValue(object): __metaclass__ = extendabletype _attrs_ = ('box', 'known_class', 'last_guard', 'level', 'intbound', 'lenbound') last_guard = None level = LEVEL_UNKNOWN known_class = None intbound = ImmutableIntUnbounded() lenbound = None def __init__(self, box, level=None, known_class=None, intbound=None): self.box = box if level is not None: self.level = level self.known_class = known_class if intbound: self.intbound = intbound else: if isinstance(box, BoxInt): self.intbound = IntBound(MININT, MAXINT) else: self.intbound = IntUnbounded() if isinstance(box, Const): self.make_constant(box) # invariant: box is a Const if and only if level == LEVEL_CONSTANT def make_len_gt(self, mode, descr, val): if self.lenbound: assert self.lenbound.mode == mode assert self.lenbound.descr == descr self.lenbound.bound.make_gt(IntBound(val, val)) else: self.lenbound = LenBound(mode, descr, IntLowerBound(val + 1)) def make_guards(self, box): guards = [] if self.level == LEVEL_CONSTANT: op = ResOperation(rop.GUARD_VALUE, [box, self.box], None) guards.append(op) elif self.level == LEVEL_KNOWNCLASS: op = ResOperation(rop.GUARD_NONNULL, [box], None) guards.append(op) op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None) guards.append(op) else: if self.level == LEVEL_NONNULL: op = ResOperation(rop.GUARD_NONNULL, [box], None) guards.append(op) self.intbound.make_guards(box, guards) if self.lenbound: lenbox = BoxInt() if self.lenbound.mode == MODE_ARRAY: op = ResOperation(rop.ARRAYLEN_GC, [box], lenbox, self.lenbound.descr) elif self.lenbound.mode == MODE_STR: op = ResOperation(rop.STRLEN, [box], lenbox, self.lenbound.descr) elif self.lenbound.mode == MODE_UNICODE: op = ResOperation(rop.UNICODELEN, [box], lenbox, self.lenbound.descr) else: debug_print("Unknown lenbound mode") assert False guards.append(op) self.lenbound.bound.make_guards(lenbox, guards) return guards def import_from(self, other, optimizer): if self.level == LEVEL_CONSTANT: assert other.level == LEVEL_CONSTANT assert other.box.same_constant(self.box) return assert self.level <= LEVEL_NONNULL if other.level == LEVEL_CONSTANT: self.make_constant(other.get_key_box()) optimizer.turned_constant(self) elif other.level == LEVEL_KNOWNCLASS: self.make_constant_class(other.known_class, None) else: if other.level == LEVEL_NONNULL: self.ensure_nonnull() self.intbound.intersect(other.intbound) if other.lenbound: if self.lenbound: assert other.lenbound.mode == self.lenbound.mode assert other.lenbound.descr == self.lenbound.descr self.lenbound.bound.intersect(other.lenbound.bound) else: self.lenbound = other.lenbound.clone() def force_box(self, optforce): return self.box def get_key_box(self): return self.box def force_at_end_of_preamble(self, already_forced, optforce): return self def get_args_for_fail(self, modifier): pass def make_virtual_info(self, modifier, fieldnums): #raise NotImplementedError # should not be called on this level assert fieldnums is None return modifier.make_not_virtual(self) def is_constant(self): return self.level == LEVEL_CONSTANT def is_null(self): if self.is_constant(): box = self.box assert isinstance(box, Const) return not box.nonnull() return False def same_value(self, other): if not other: return False if self.is_constant() and other.is_constant(): return self.box.same_constant(other.box) return self is other def make_constant(self, constbox): """Replace 'self.box' with a Const box.""" assert isinstance(constbox, Const) self.box = constbox self.level = LEVEL_CONSTANT if isinstance(constbox, ConstInt): val = constbox.getint() self.intbound = IntBound(val, val) else: self.intbound = IntUnbounded() def get_constant_class(self, cpu): level = self.level if level == LEVEL_KNOWNCLASS: return self.known_class elif level == LEVEL_CONSTANT: return cpu.ts.cls_of_box(self.box) else: return None def make_constant_class(self, classbox, guardop): assert self.level < LEVEL_KNOWNCLASS self.known_class = classbox self.level = LEVEL_KNOWNCLASS self.last_guard = guardop def make_nonnull(self, guardop): assert self.level < LEVEL_NONNULL self.level = LEVEL_NONNULL self.last_guard = guardop def is_nonnull(self): level = self.level if level == LEVEL_NONNULL or level == LEVEL_KNOWNCLASS: return True elif level == LEVEL_CONSTANT: box = self.box assert isinstance(box, Const) return box.nonnull() elif self.intbound: if self.intbound.known_gt(IntBound(0, 0)) or \ self.intbound.known_lt(IntBound(0, 0)): return True else: return False else: return False def ensure_nonnull(self): if self.level < LEVEL_NONNULL: self.level = LEVEL_NONNULL def is_virtual(self): # Don't check this with 'isinstance(_, VirtualValue)'! # Even if it is a VirtualValue, the 'box' can be non-None, # meaning it has been forced. return self.box is None def is_forced_virtual(self): return False def getfield(self, ofs, default): raise NotImplementedError def setfield(self, ofs, value): raise NotImplementedError def getlength(self): raise NotImplementedError def getitem(self, index): raise NotImplementedError def setitem(self, index, value): raise NotImplementedError def getinteriorfield(self, index, ofs, default): raise NotImplementedError def setinteriorfield(self, index, ofs, value): raise NotImplementedError
class NotVirtualStateInfo(AbstractVirtualStateInfo): def __init__(self, value): self.known_class = value.known_class self.level = value.level if value.intbound is None: self.intbound = IntUnbounded() else: self.intbound = value.intbound.clone() if value.is_constant(): self.constbox = value.box else: self.constbox = None self.position_in_notvirtuals = -1 self.lenbound = value.lenbound def generalization_of(self, other, renum, bad): # XXX This will always retrace instead of forcing anything which # might be what we want sometimes? assert self.position != -1 if self.position in renum: if renum[self.position] == other.position: return True bad[self] = True bad[other] = True return False renum[self.position] = other.position if not isinstance(other, NotVirtualStateInfo): bad[self] = True bad[other] = True return False if other.level < self.level: bad[self] = True bad[other] = True return False if self.level == LEVEL_CONSTANT: if not self.constbox.same_constant(other.constbox): bad[self] = True bad[other] = True return False elif self.level == LEVEL_KNOWNCLASS: if not self.known_class.same_constant(other.known_class): bad[self] = True bad[other] = True return False if not self.intbound.contains_bound(other.intbound): bad[self] = True bad[other] = True return False if self.lenbound and other.lenbound: if self.lenbound.mode != other.lenbound.mode or \ self.lenbound.descr != other.lenbound.descr or \ not self.lenbound.bound.contains_bound(other.lenbound.bound): bad[self] = True bad[other] = True return False elif self.lenbound: bad[self] = True bad[other] = True return False return True def _generate_guards(self, other, box, cpu, extra_guards): if not isinstance(other, NotVirtualStateInfo): raise InvalidLoop('The VirtualStates does not match as a ' + 'virtual appears where a pointer is needed ' + 'and it is too late to force it.') if self.lenbound or other.lenbound: raise InvalidLoop('The array length bounds does not match.') if self.level == LEVEL_KNOWNCLASS and \ box.nonnull() and \ self.known_class.same_constant(cpu.ts.cls_of_box(box)): # Note: This is only a hint on what the class of box was # during the trace. There are actually no guarentees that this # box realy comes from a trace. The hint is used here to choose # between either eimtting a guard_class and jumping to an # excisting compiled loop or retracing the loop. Both # alternatives will always generate correct behaviour, but # performace will differ. op = ResOperation(rop.GUARD_NONNULL, [box], None) extra_guards.append(op) op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None) extra_guards.append(op) return if self.level == LEVEL_NONNULL and \ other.level == LEVEL_UNKNOWN and \ isinstance(box, BoxPtr) and \ box.nonnull(): op = ResOperation(rop.GUARD_NONNULL, [box], None) extra_guards.append(op) return if self.level == LEVEL_UNKNOWN and \ other.level == LEVEL_UNKNOWN and \ isinstance(box, BoxInt) and \ self.intbound.contains(box.getint()): if self.intbound.has_lower: bound = self.intbound.lower if not (other.intbound.has_lower and \ other.intbound.lower >= bound): res = BoxInt() op = ResOperation(rop.INT_GE, [box, ConstInt(bound)], res) extra_guards.append(op) op = ResOperation(rop.GUARD_TRUE, [res], None) extra_guards.append(op) if self.intbound.has_upper: bound = self.intbound.upper if not (other.intbound.has_upper and \ other.intbound.upper <= bound): res = BoxInt() op = ResOperation(rop.INT_LE, [box, ConstInt(bound)], res) extra_guards.append(op) op = ResOperation(rop.GUARD_TRUE, [res], None) extra_guards.append(op) return # Remaining cases are probably not interesting raise InvalidLoop('Generating guards for making the VirtualStates ' + 'at hand match have not been implemented') if self.level == LEVEL_CONSTANT: import pdb pdb.set_trace() raise NotImplementedError def enum_forced_boxes(self, boxes, value, optimizer): if self.level == LEVEL_CONSTANT: return assert 0 <= self.position_in_notvirtuals if optimizer: box = value.force_box(optimizer) else: if value.is_virtual(): raise BadVirtualState box = value.get_key_box() boxes[self.position_in_notvirtuals] = box def _enum(self, virtual_state): if self.level == LEVEL_CONSTANT: return self.position_in_notvirtuals = len(virtual_state.notvirtuals) virtual_state.notvirtuals.append(self) def debug_print(self, indent, seen, bad): mark = '' if self in bad: mark = '*' if we_are_translated(): l = { LEVEL_UNKNOWN: 'Unknown', LEVEL_NONNULL: 'NonNull', LEVEL_KNOWNCLASS: 'KnownClass', LEVEL_CONSTANT: 'Constant', }[self.level] else: l = { LEVEL_UNKNOWN: 'Unknown', LEVEL_NONNULL: 'NonNull', LEVEL_KNOWNCLASS: 'KnownClass(%r)' % self.known_class, LEVEL_CONSTANT: 'Constant(%r)' % self.constbox, }[self.level] lb = '' if self.lenbound: lb = ', ' + self.lenbound.bound.__repr__() debug_print(indent + mark + 'NotVirtualInfo(%d' % self.position + ', ' + l + ', ' + self.intbound.__repr__() + lb + ')')
def __init__(self, box): self.box = box self.intbound = IntBound(MININT, MAXINT) #IntUnbounded() if isinstance(box, Const): self.make_constant(box)
class OptValue(object): __metaclass__ = extendabletype _attrs_ = ('box', 'known_class', 'last_guard_index', 'level', 'intbound') last_guard_index = -1 level = LEVEL_UNKNOWN known_class = None intbound = None def __init__(self, box): self.box = box self.intbound = IntBound(MININT, MAXINT) #IntUnbounded() if isinstance(box, Const): self.make_constant(box) # invariant: box is a Const if and only if level == LEVEL_CONSTANT def force_box(self): return self.box def get_key_box(self): return self.box def enum_forced_boxes(self, boxes, already_seen): key = self.get_key_box() if key not in already_seen: boxes.append(self.force_box()) already_seen[self.get_key_box()] = None def get_reconstructed(self, optimizer, valuemap): if self in valuemap: return valuemap[self] new = self.reconstruct_for_next_iteration(optimizer) valuemap[self] = new self.reconstruct_childs(new, valuemap) return new def reconstruct_for_next_iteration(self, optimizer): return self def reconstruct_childs(self, new, valuemap): pass def get_args_for_fail(self, modifier): pass def make_virtual_info(self, modifier, fieldnums): #raise NotImplementedError # should not be called on this level assert fieldnums is None return modifier.make_not_virtual(self) def is_constant(self): return self.level == LEVEL_CONSTANT def is_null(self): if self.is_constant(): box = self.box assert isinstance(box, Const) return not box.nonnull() return False def make_constant(self, constbox): """Replace 'self.box' with a Const box.""" assert isinstance(constbox, Const) self.box = constbox self.level = LEVEL_CONSTANT if isinstance(constbox, ConstInt): val = constbox.getint() self.intbound = IntBound(val, val) else: self.intbound = IntUnbounded() def get_constant_class(self, cpu): level = self.level if level == LEVEL_KNOWNCLASS: return self.known_class elif level == LEVEL_CONSTANT: return cpu.ts.cls_of_box(self.box) else: return None def make_constant_class(self, classbox, opindex): assert self.level < LEVEL_KNOWNCLASS self.known_class = classbox self.level = LEVEL_KNOWNCLASS self.last_guard_index = opindex def make_nonnull(self, opindex): assert self.level < LEVEL_NONNULL self.level = LEVEL_NONNULL self.last_guard_index = opindex def is_nonnull(self): level = self.level if level == LEVEL_NONNULL or level == LEVEL_KNOWNCLASS: return True elif level == LEVEL_CONSTANT: box = self.box assert isinstance(box, Const) return box.nonnull() elif self.intbound: if self.intbound.known_gt(IntBound(0, 0)) or \ self.intbound.known_lt(IntBound(0, 0)): return True else: return False else: return False def ensure_nonnull(self): if self.level < LEVEL_NONNULL: self.level = LEVEL_NONNULL def is_virtual(self): # Don't check this with 'isinstance(_, VirtualValue)'! # Even if it is a VirtualValue, the 'box' can be non-None, # meaning it has been forced. return self.box is None def getfield(self, ofs, default): raise NotImplementedError def setfield(self, ofs, value): raise NotImplementedError def getitem(self, index): raise NotImplementedError def getlength(self): raise NotImplementedError def setitem(self, index, value): raise NotImplementedError
def test_make(): for _, _, b1 in some_bounds(): for _, _, b2 in some_bounds(): lt = IntUnbounded() lt.make_lt(b1) lt.make_lt(b2) for n in nbr: c = const(n) if b1.known_le(c) or b2.known_le(c): assert lt.known_lt(c) else: assert not lt.known_lt(c) assert not lt.known_gt(c) assert not lt.known_ge(c) gt = IntUnbounded() gt.make_gt(b1) gt.make_gt(b2) for n in nbr: c = const(n) if b1.known_ge(c) or b2.known_ge(c): assert gt.known_gt(c) else: assert not gt.known_gt(c) assert not gt.known_lt(c) assert not gt.known_le(c) le = IntUnbounded() le.make_le(b1) le.make_le(b2) for n in nbr: c = const(n) if b1.known_le(c) or b2.known_le(c): assert le.known_le(c) else: assert not le.known_le(c) assert not le.known_gt(c) assert not le.known_ge(c) ge = IntUnbounded() ge.make_ge(b1) ge.make_ge(b2) for n in nbr: c = const(n) if b1.known_ge(c) or b2.known_ge(c): assert ge.known_ge(c) else: assert not ge.known_ge(c) assert not ge.known_lt(c) assert not ge.known_le(c) gl = IntUnbounded() gl.make_ge(b1) gl.make_le(b2) for n in nbr: c = const(n) if b1.known_ge(c): assert gl.known_ge(c) else: assert not gl.known_ge(c) assert not gl.known_gt(c) if b2.known_le(c): assert gl.known_le(c) else: assert not gl.known_le(c) assert not gl.known_lt(c)