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 getitem_raw(self, offset, length, descr): raise NotImplementedError def setitem_raw(self, offset, length, descr, value): raise NotImplementedError def getinteriorfield(self, index, ofs, default): raise NotImplementedError def setinteriorfield(self, index, ofs, value): raise NotImplementedError