From dan at codespeak.net Sat Jan 2 03:02:06 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Sat, 2 Jan 2010 03:02:06 +0100 (CET) Subject: [pypy-svn] r70376 - pypy/branch/micronumpy/pypy/module/micronumpy Message-ID: <20100102020206.8A276168026@codespeak.net> Author: dan Date: Sat Jan 2 03:02:05 2010 New Revision: 70376 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py Log: Reverted to working revision using merge. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py Sat Jan 2 03:02:05 2010 @@ -25,123 +25,45 @@ current *= d return pos -def compute_slices(space, slices, dim): - strides = [] - i = 1 - for d in dim: - strides.append(i) - i *= d - strides.reverse() - length = i - shape = [] - sliceout = [] - for v in space.unpackiterable(slices): - sliceoutnew=[] #FIXME: Not RPYthon - there are no slices. - if space.is_true(space.isinstance(v, space.w_slice)): - sl=space.unwrap(v) - if sl.step<0: - reverse=True - sl=slice(sl.stop, sl.start, -sl.step) - else: - reverse=False - stride=strides.pop(0) - if sl.step == 1: - newsl = [slice(stride*sl.start, stride*sl.stop)] - else: - newsl = [] - for i in range(sl.start, sl.stop, sl.step): - newsl.append(slice(stride*i, stride*(i+1))) - - if reverse: - newsl.reverse() - - shape.append((sl.stop-sl.start)//sl.step) - - #here multiple old slices x new slices. - for sl in sliceout: - for sl2 in newsl: - pass #I have no time - - else: - #extract item from slices, without appending to shape - - sliceout = sliceoutnew - - return shape, sliceout - -#Was undetectable -class MultiDimArrayAbstract(BaseNumArray): - - def dtype(self, data): - return self.__class__.data_type(data) - - def unwrap(self, w_data): #XXX: NOT USED - return self.__class__.data_w(w_data) - - def coerce(self, data): - return self.__class__.data_coerce(data) - - def __init__(self, space, shape): - self.shape = shape - self.space = space - size = 1 - for dimension in shape: - size *= dimension - self.storage = [self.dtype(0.0)] * size - make_sure_not_resized(self.storage) - - def _unpack_indexes(self, space, w_index): - indexes = [space.int_w(w_i) for w_i in space.fixedview(w_index)] - if len(indexes) != len(self.shape): - raise OperationError(space.w_IndexError, space.wrap( - 'Wrong index')) - return indexes - - def getitem(self, w_index): - space = self.space - indexes = self._unpack_indexes(space, w_index) - pos = compute_pos(space, indexes, self.shape) - return space.wrap(self.storage[pos]) - - def setitem(self, w_index, w_value): - space = self.space - indexes = self._unpack_indexes(space, w_index) - pos = compute_pos(space, indexes, self.shape) - self.storage[pos] = self.coerce(space, w_value) - return space.w_None #XXX: necessary? - - def len(self): - space = self.space - return space.wrap(self.shape[0]) - - def load_iterable(self, space, w_values): - self._load_iter(space, w_values, 0) - - def _load_iter(self, space, w_values, start): #TODO: shape check - vals=space.unpackiterable(w_values) - if space.is_true(space.isinstance(vals[0], space.w_tuple) or space.is_true(space.isinstance(vals[0], space.w_list): - idx=start - for v in vals: - add=self._load_iter(space, v, idx) - idx+=add - return idx - else: - idx=start - for v in vals: - self.storage[idx]=self.unwrap(val) - idx+=1 - return idx - - -mdarraytype=MultiDimArrayAbstract - -class MultiDimIntArray(MultiDimArrayAbstact): - data_type, data_w, data_coerce = int, unwrap_int, coerce_int +def create_mdarray(data_type, unwrap, coerce): + class MultiDimArray(BaseNumArray): + def __init__(self, space, shape): + self.shape = shape + self.space = space + size = 1 + for dimension in shape: + size *= dimension + self.storage = [data_type(0.0)] * size + make_sure_not_resized(self.storage) + + def _unpack_indexes(self, space, w_index): + indexes = [space.int_w(w_i) for w_i in space.fixedview(w_index)] + if len(indexes) != len(self.shape): + raise OperationError(space.w_IndexError, space.wrap( + 'Wrong index')) + return indexes + + def getitem(self, w_index): + space = self.space + indexes = self._unpack_indexes(space, w_index) + pos = compute_pos(space, indexes, self.shape) + return space.wrap(self.storage[pos]) + + def setitem(self, w_index, w_value): + space = self.space + indexes = self._unpack_indexes(space, w_index) + pos = compute_pos(space, indexes, self.shape) + self.storage[pos] = coerce(space, w_value) + return space.w_None #XXX: necessary? + + def len(self): + space = self.space + return space.wrap(self.shape[0]) + return MultiDimArray +MultiDimIntArray = create_mdarray(int, unwrap_int, coerce_int) MultiDimArray = MultiDimIntArray #XXX: compatibility - -class MultiDimFloatArray(MultiDimArrayAbstact): - data_type, data_w, data_coerce = float, unwrap_float, coerce_float +MultiDimFloatArray = create_mdarray(float, unwrap_float, coerce_float) class ResultFactory(object): def __init__(self, space): Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py Sat Jan 2 03:02:05 2010 @@ -50,7 +50,7 @@ self.space = space if w_dtype == space.w_None: #TODO: infer type from w_values (better than this) - w_dtype = space.type(space.getitem(w_values, space.wrap(0))) #FIXED + w_dtype = space.type(space.fixedview(w_values)[0]) #FIXME: Allocates an entire array and throws it away! self.dtype = w_dtype if w_shape == space.w_None: @@ -64,7 +64,7 @@ length = shape_w[0] self.array = sdresult(space, w_dtype)(space, length) else: - self.array = mdresult(space, w_dtype)(space, shape_w) #w_shape still may be w_None + self.array = mdresult(space, w_dtype)(space, unpack_shape(space, w_shape)) except KeyError, e: raise OperationError(space.w_NotImplementedError, space.wrap("Haven't implemented generic array yet!")) Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Sat Jan 2 03:02:05 2010 @@ -13,104 +13,87 @@ from pypy.module.micronumpy.dtype import unwrap_float32, coerce_float32, float32 def create_sdarray(data_type, unwrap, coerce): -class NumArrayAbstract(BaseNumArray): - - def dtype(self, data): - return self.__class__.data_type(data) - - def unwrap(self, w_data): - return self.__class__.data_w(w_data) - - def coerce(self, data): - return self.__class__.data_coerce(data) - - def __init__(self, space, length): - self.shape = (length,) #As in numpy - self.length = length - self.space = space - self.storage = [self.dtype(0.0)] * length - make_sure_not_resized(self.storage) - - mul = mul_operation() - div = div_operation() - add = add_operation() - sub = sub_operation() - copy = copy_operation() - - def create_scalar_op(f): - def scalar_operation(self, space, source, w_x): - space = self.space - x = self.coerce(space, w_x) - for i in range(source.length): - self.storage[i] = f(source.storage[i], x) - return scalar_operation + class NumArray(BaseNumArray): + def __init__(self, space, length): + self.shape = (1,) + self.length = length + self.space = space + self.storage = [data_type(0.0)] * length + make_sure_not_resized(self.storage) + + mul = mul_operation() + div = div_operation() + add = add_operation() + sub = sub_operation() + copy = copy_operation() + + def create_scalar_op(f): + def scalar_operation(self, space, source, w_x): + space = self.space + x = self.coerce(space, w_x) + for i in range(source.length): + self.storage[i] = f(source.storage[i], x) + return scalar_operation - mul_scalar = create_scalar_op(mul) + mul_scalar = create_scalar_op(mul) # div_scalar = create_scalar_op(div) # add_scalar = create_scalar_op(add) # sub_scalar = create_scalar_op(sub) - def create_fixedview_op(f): - def fixedview_operation(self, w_xs): - space = self.space - try: - xs = space.fixedview(w_xs, len(self.storage)) - except UnpackValueError, e: - # w_xs is of the wrong size - raise OperationError(space.w_ValueError, - space.wrap("shape mismatch: objects cannot be broadcast to the same shape")) + def create_fixedview_op(f): + def fixedview_operation(self, w_xs): + space = self.space + try: + xs = space.fixedview(w_xs, len(self.storage)) + except UnpackValueError, e: + # w_xs is of the wrong size + raise OperationError(space.w_ValueError, + space.wrap("shape mismatch: objects cannot be broadcast to the same shape")) + + i = 0 + for w_x in xs: + self.storage[i] = f(source.storage[i], self.coerce(w_x)) #TODO: probably shouldn't coerce + i += 1 + return result + return fixedview_operation + + copy_iterable = create_fixedview_op(copy) + def load_iterable(self, space, w_values): #FIXME: less than ideal i = 0 - for w_x in xs: - self.storage[i] = f(source.storage[i], self.coerce(w_x)) #TODO: probably shouldn't coerce + for x in space.fixedview(w_values, self.length): + self.storage[i] = unwrap(space, x) i += 1 - return result - return fixedview_operation - copy_iterable = create_fixedview_op(copy) - - def load_iterable(self, space, w_values): #FIXME: less than ideal - i = 0 - for x in space.fixedview(w_values, self.length): - self.storage[i] = self.unwrap(space, x) - i += 1 - - def getitem(self, w_index): - space = self.space - index = space.int_w(w_index) - try: - return space.wrap(self.storage[index]) - except IndexError: - raise OperationError(space.w_IndexError, - space.wrap("list index out of range")) - - def setitem(self, w_index, w_value): - space = self.space - index = space.int_w(w_index) - try: - self.storage[index] = self.coerce(space, w_value) - except IndexError: - raise OperationError(space.w_IndexError, - space.wrap("list index out of range")) - return space.w_None - - def len(self): - space = self.space - return space.wrap(len(self.storage)) - -sdarraytype=NumArrayAbstact - -class IntArray(NumArrayAbstact): - data_type, data_w, data_coerce = int, unwrap_int, coerce_int + def getitem(self, w_index): + space = self.space + index = space.int_w(w_index) + try: + return space.wrap(self.storage[index]) + except IndexError: + raise OperationError(space.w_IndexError, + space.wrap("list index out of range")) -NumArray = IntArray #XXX: compatibility + def setitem(self, w_index, w_value): + space = self.space + index = space.int_w(w_index) + try: + self.storage[index] = coerce(space, w_value) + except IndexError: + raise OperationError(space.w_IndexError, + space.wrap("list index out of range")) + return space.w_None -class FloatArray(NumArrayAbstact): - data_type, data_w, data_coerce = float, unwrap_float, coerce_float + def len(self): + space = self.space + return space.wrap(len(self.storage)) -class Float32Array(NumArrayAbstract): - data_type, data_w, data_coerce = float32, unwrap_float32, coerce_float32 + return NumArray +IntArray = create_sdarray(int, unwrap_int, coerce_int) +NumArray = IntArray # FIXME: compatibility for now +FloatArray = create_sdarray(float, unwrap_float, coerce_float) +Float32Array = create_sdarray(float32, unwrap_float32, coerce_float32) GenericArray = None class ResultFactory(object): Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py Sat Jan 2 03:02:05 2010 @@ -1,16 +1,11 @@ from pypy.module.micronumpy.ndarray import array, zeros, ndarray -from pypy.module.micronumpy.sdarray import sdarrytype -from pypy.module.micronumpy.mdarray import mdarrytype from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError -def _assert_both(space, w_a, w_b): +def minimum(space, w_a, w_b): if not isinstance(w_a, ndarray) or not isinstance(w_b, ndarray): raise OperationError(space.w_TypeError, space.wrap("expecting ndarray object")) - -def minimum(space, w_a, w_b): - _assert_both(w_a, w_b) if w_a.array.length != w_b.array.length: raise OperationError(space.w_ValueError, space.wrap("minimum of arrays of different length")) @@ -24,15 +19,3 @@ res.array.storage[i] = two return space.wrap(res) minimum.unwrap_spec = [ObjSpace, W_Root, W_Root] - -def dot(space, w_a, w_b): - _assert_both(w_a, w_b) - if len(w_b.array.shape)==1: - w_b_new=zeros(space, space.newtuple([space.wrap(1), space.wrap(w_b.array.shape[0])])) - for idx, value in enumerate(w_b.array.storage): - w_b_new.array.storage[idx]=value - w_b=w_b_new - - #waiting for slice. - - From dan at codespeak.net Sat Jan 2 04:31:25 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Sat, 2 Jan 2010 04:31:25 +0100 (CET) Subject: [pypy-svn] r70377 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test Message-ID: <20100102033125.DEDBD16802C@codespeak.net> Author: dan Date: Sat Jan 2 04:31:25 2010 New Revision: 70377 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: Added support for multiplying single dimensional arrays. First iteration, needs refactoring. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py Sat Jan 2 04:31:25 2010 @@ -8,7 +8,6 @@ from pypy.module.micronumpy.dtype import unwrap_int, coerce_int from pypy.module.micronumpy.dtype import unwrap_float, coerce_float -from pypy.module.micronumpy.dtype import unwrap_float32, coerce_float32, float32 def compute_pos(space, indexes, dim): current = 1 @@ -25,8 +24,10 @@ current *= d return pos +class BaseMultiDimArray(BaseNumArray): pass + def create_mdarray(data_type, unwrap, coerce): - class MultiDimArray(BaseNumArray): + class MultiDimArray(BaseMultiDimArray): def __init__(self, space, shape): self.shape = shape self.space = space @@ -54,11 +55,16 @@ indexes = self._unpack_indexes(space, w_index) pos = compute_pos(space, indexes, self.shape) self.storage[pos] = coerce(space, w_value) - return space.w_None #XXX: necessary? + + def load_iterable(self, w_xs): + space = self.space + raise OperationError(space.w_NotImplementedError, + space.wrap("Haven't implemented iterable loading yet!")) def len(self): space = self.space return space.wrap(self.shape[0]) + return MultiDimArray MultiDimIntArray = create_mdarray(int, unwrap_int, coerce_int) Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py Sat Jan 2 04:31:25 2010 @@ -10,6 +10,15 @@ from pypy.module.micronumpy.mdarray import mdresult +def result_type(space, w_types): + types = { + (space.w_int, space.w_int): space.w_int, + (space.w_int, space.w_float): space.w_float, + (space.w_float, space.w_int): space.w_float, + (space.w_float, space.w_float): space.w_float + } + return types[w_types] + def unpack_shape(space, w_shape): if space.is_true(space.isinstance(w_shape, space.w_int)): return [space.int_w(w_shape)] @@ -42,43 +51,43 @@ next = interp2app(ArrayIter.descr_next)) def infer_shape(space, w_values): - return space.len(w_values) #TODO: handle multi-dimensional arrays... + return [space.int_w(space.len(w_values))] #TODO: handle multi-dimensional arrays... class ndarray(Wrappable): - def __init__(self, space, w_values, w_shape, w_dtype): + #FIXME: blows up (NoneNotWrapped != None) when not called by applevel? + def __init__(self, space, w_values, w_shape=NoneNotWrapped, w_dtype=NoneNotWrapped): self.array = None self.space = space - if w_dtype == space.w_None: + if w_dtype is None and not space.is_w(w_values, space.w_None): #TODO: infer type from w_values (better than this) w_dtype = space.type(space.fixedview(w_values)[0]) #FIXME: Allocates an entire array and throws it away! self.dtype = w_dtype - if w_shape == space.w_None: - values_shape = infer_shape(space, w_values) - shape_w = unpack_shape(space, values_shape) + shape_w = None + if w_shape is None: + try: + shape_w = infer_shape(space, w_values) + except OperationError, e: + if e.match(space, space.w_TypeError): pass + else: raise else: shape_w = unpack_shape(space, w_shape) - try: - if len(shape_w) == 1: - length = shape_w[0] - self.array = sdresult(space, w_dtype)(space, length) - else: - self.array = mdresult(space, w_dtype)(space, unpack_shape(space, w_shape)) - except KeyError, e: - raise OperationError(space.w_NotImplementedError, - space.wrap("Haven't implemented generic array yet!")) + if not shape_w is None and not w_dtype is None: + try: + if len(shape_w) == 1: + length = shape_w[0] + self.array = sdresult(space, w_dtype)(space, length) + else: + self.array = mdresult(space, w_dtype)(space, shape_w) + except KeyError, e: + raise OperationError(space.w_NotImplementedError, + space.wrap("Haven't implemented generic array yet!")) - if not w_values == space.w_None: - self.array.load_iterable(space, w_values) #TODO: implement loading for multi-dimensional arrays + if not w_values is None and not space.is_w(w_values, space.w_None): + self.array.load_iterable(w_values) #TODO: implement loading for multi-dimensional arrays def validate_index(self, space, w_i): - if space.type(w_i) == space.w_int: return - - if space.type(w_i) == space.w_str: - raise OperationError(space.w_NotImplementedError, - space.wrap("Haven't implemented field access yet!")) - try: index_dimensionality = space.int_w(space.len(w_i)) array_dimensionality = len(self.array.shape) @@ -91,14 +100,19 @@ def descr_mul(self, w_x): space = self.space - if space.type(w_x) in (W_ListType, W_TupleType): #TODO: fooo + if space.type(w_x) in (space.w_list, space.w_tuple): #xs = space.fixedview(w_x) - pass + raise OperationError(space.w_NotImplementedError, + space.wrap("Haven't implemented array * iterable yet!")) else: - result_array = sdresult(space, space.type(w_x))(space, self.array.length) - result_array.mul_scalar(self.array, w_x) - result = ndarray(space, space.w_None, space.wrap(result_array.length), space.w_None) #FIXME: make ndarray.__init__ understand null args + result_t = result_type(space, (space.type(w_x), self.dtype)) + result_array = sdresult(space, result_t)(space, self.array.length) #FIXME: support multi-dimensional array! + result_array.mul_scalar(self.array, w_x) #TODO: reverse so that result_array = self.array.mul_scalar(w_x) + + result = ndarray(space, space.w_None, None, None) result.array = result_array + w_result = space.wrap(result) + return w_result descr_mul.unwrap_spec = ['self', W_Root] def descr_iter(self): @@ -120,19 +134,30 @@ return self.array.len() descr_len.unwrap_spec = ['self', ObjSpace] +def descr_new(space, w_cls, w_shape, + w_buffer=NoneNotWrapped, w_offset=NoneNotWrapped, + w_strides=NoneNotWrapped, order=NoneNotWrapped): + result = ndarray(space, w_None, w_shape, None) + return space.wrap(result) +descr_new.unwrap_spec = [ObjSpace, W_Root, W_Root, + W_Root, W_Root, + W_Root, str] + ndarray.typedef = TypeDef( 'ndarray', #__init__ = interp2app(descr_init), #FIXME + __new__ = interp2app(descr_new), __iter__ = interp2app(ndarray.descr_iter), + __mul__ = interp2app(ndarray.descr_mul), __getitem__ = interp2app(ndarray.descr_getitem), __setitem__ = interp2app(ndarray.descr_setitem), __len__ = interp2app(ndarray.descr_len), ) -def array(space, w_values, w_shape=None, w_dtype=None): +def array(space, w_values, w_shape=NoneNotWrapped, w_dtype=NoneNotWrapped): return ndarray(space, w_values, w_shape, w_dtype) array.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root] -def zeros(space, w_shape, w_dtype): - return array(space, space.w_None, w_shape, w_dtype) +def zeros(space, w_shape, w_dtype=NoneNotWrapped): + return ndarray(space, None, w_shape, w_dtype) zeros.unwrap_spec = [ObjSpace, W_Root, W_Root] Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Sat Jan 2 04:31:25 2010 @@ -12,8 +12,12 @@ from pypy.module.micronumpy.dtype import unwrap_float, coerce_float from pypy.module.micronumpy.dtype import unwrap_float32, coerce_float32, float32 +# from pypy.interpreter.gateway import unwrap_spec #TODO: merge unwrap_spec decorator + +class BaseSingleDimArray(BaseNumArray): pass + def create_sdarray(data_type, unwrap, coerce): - class NumArray(BaseNumArray): + class NumArray(BaseSingleDimArray): def __init__(self, space, length): self.shape = (1,) self.length = length @@ -28,9 +32,9 @@ copy = copy_operation() def create_scalar_op(f): - def scalar_operation(self, space, source, w_x): + def scalar_operation(self, source, w_x): space = self.space - x = self.coerce(space, w_x) + x = coerce(space, w_x) for i in range(source.length): self.storage[i] = f(source.storage[i], x) return scalar_operation @@ -59,7 +63,8 @@ copy_iterable = create_fixedview_op(copy) - def load_iterable(self, space, w_values): #FIXME: less than ideal + def load_iterable(self, w_values): #FIXME: less than ideal + space = self.space i = 0 for x in space.fixedview(w_values, self.length): self.storage[i] = unwrap(space, x) @@ -98,8 +103,6 @@ class ResultFactory(object): def __init__(self, space): - self.space = space - self.types = { space.w_int: IntArray, space.w_float: FloatArray, Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Sat Jan 2 04:31:25 2010 @@ -26,6 +26,13 @@ def test_int_array(self): self.array_type_test(int) def test_float_array(self): self.array_type_test(float) + def test_array_mul(self): + compare = self.compare + from numpy import array + data = range(4) + ar = array(data) + assert compare(ar * 4, [x * 4 for x in data]) + def test_iterable_construction(self): compare = self.compare from numpy import array From dan at codespeak.net Sat Jan 2 13:19:50 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Sat, 2 Jan 2010 13:19:50 +0100 (CET) Subject: [pypy-svn] r70378 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test Message-ID: <20100102121950.41B35168032@codespeak.net> Author: dan Date: Sat Jan 2 13:19:49 2010 New Revision: 70378 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py pypy/branch/micronumpy/pypy/module/micronumpy/array.py pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: Generalized multiplication to all arithmetic operations with single dimensional array and scalar operators. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py Sat Jan 2 13:19:49 2010 @@ -4,12 +4,11 @@ class Module(MixedModule): applevel_name = 'numpy' - appleveldefs = { - #'array' : 'app_numarray.array', - } + appleveldefs = {} interpleveldefs = { 'array' : 'ndarray.array', + 'ndarray' : 'ndarray.ndarray', 'zeros' : 'ndarray.zeros', 'minimum' : 'ufunc.minimum', } Modified: pypy/branch/micronumpy/pypy/module/micronumpy/array.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/array.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/array.py Sat Jan 2 13:19:49 2010 @@ -17,7 +17,7 @@ return div def add_operation(): - def add(x, y): return x * y + def add(x, y): return x + y return add def sub_operation(): Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py Sat Jan 2 13:19:49 2010 @@ -8,7 +8,7 @@ def coerce_float(space, w_x): return unwrap_float(space, space.float(w_x)) -from rlib.rarithmetic import r_singlefloat as float32 +from pypy.rlib.rarithmetic import r_singlefloat as float32 def unwrap_float32(space, w_x): return float32(space.float_w(w_x)) def coerce_float32(space, w_x): Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py Sat Jan 2 13:19:49 2010 @@ -19,6 +19,18 @@ } return types[w_types] +def mul_scalar(result, source, w_x): result.mul_scalar(source, w_x) +def mul_fixedview(result, source, w_xs): result.mul_fixedview(source, w_xs) + +def div_scalar(result, source, w_x): result.div_scalar(source, w_x) +def div_fixedview(result, source, w_xs): result.div_fixedview(source, w_xs) + +def add_scalar(result, source, w_x): result.add_scalar(source, w_x) +def add_fixedview(result, source, w_xs): result.add_fixedview(source, w_xs) + +def sub_scalar(result, source, w_x): result.sub_scalar(source, w_x) +def sub_fixedview(result, source, w_xs): result.sub_fixedview(source, w_xs) + def unpack_shape(space, w_shape): if space.is_true(space.isinstance(w_shape, space.w_int)): return [space.int_w(w_shape)] @@ -54,7 +66,6 @@ return [space.int_w(space.len(w_values))] #TODO: handle multi-dimensional arrays... class ndarray(Wrappable): - #FIXME: blows up (NoneNotWrapped != None) when not called by applevel? def __init__(self, space, w_values, w_shape=NoneNotWrapped, w_dtype=NoneNotWrapped): self.array = None self.space = space @@ -98,22 +109,30 @@ if e.match(space, space.w_TypeError): pass else: raise - def descr_mul(self, w_x): - space = self.space - if space.type(w_x) in (space.w_list, space.w_tuple): - #xs = space.fixedview(w_x) - raise OperationError(space.w_NotImplementedError, - space.wrap("Haven't implemented array * iterable yet!")) - else: - result_t = result_type(space, (space.type(w_x), self.dtype)) - result_array = sdresult(space, result_t)(space, self.array.length) #FIXME: support multi-dimensional array! - result_array.mul_scalar(self.array, w_x) #TODO: reverse so that result_array = self.array.mul_scalar(w_x) - - result = ndarray(space, space.w_None, None, None) - result.array = result_array - w_result = space.wrap(result) - return w_result - descr_mul.unwrap_spec = ['self', W_Root] + def create_math_operation(f): + def math_operation(self, w_x): + space = self.space + if space.type(w_x) in (space.w_list, space.w_tuple): + raise OperationError(space.w_NotImplementedError, + space.wrap("Haven't implemented array * iterable yet!")) + else: + result_t = result_type(space, (space.type(w_x), self.dtype)) + result_array = sdresult(space, result_t)(space, self.array.length) #FIXME: support multi-dimensional array! + #result_array.mul_scalar(self.array, w_x) #TODO: reverse so that result_array = self.array.mul_scalar(w_x) + f(result_array, self.array, w_x) #TODO: can i use member function pointers? + + result = ndarray(space, space.w_None, None, None) + result.array = result_array + w_result = space.wrap(result) + return w_result + math_operation.unwrap_spec = ['self', W_Root] + return math_operation + + # Math Operations + descr_mul = create_math_operation(mul_scalar) + descr_div = create_math_operation(div_scalar) + descr_add = create_math_operation(add_scalar) + descr_sub = create_math_operation(sub_scalar) def descr_iter(self): space = self.space @@ -149,6 +168,9 @@ __new__ = interp2app(descr_new), __iter__ = interp2app(ndarray.descr_iter), __mul__ = interp2app(ndarray.descr_mul), + __div__ = interp2app(ndarray.descr_div), + __add__ = interp2app(ndarray.descr_add), + __sub__ = interp2app(ndarray.descr_sub), __getitem__ = interp2app(ndarray.descr_getitem), __setitem__ = interp2app(ndarray.descr_setitem), __len__ = interp2app(ndarray.descr_len), Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Sat Jan 2 13:19:49 2010 @@ -36,14 +36,15 @@ space = self.space x = coerce(space, w_x) for i in range(source.length): - self.storage[i] = f(source.storage[i], x) + self.storage[i] = f(data_type(source.storage[i]), x) return scalar_operation mul_scalar = create_scalar_op(mul) -# div_scalar = create_scalar_op(div) -# add_scalar = create_scalar_op(add) -# sub_scalar = create_scalar_op(sub) + div_scalar = create_scalar_op(div) + add_scalar = create_scalar_op(add) + sub_scalar = create_scalar_op(sub) + #TODO: wrap up fixedview and scalar together def create_fixedview_op(f): def fixedview_operation(self, w_xs): space = self.space Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Sat Jan 2 13:19:49 2010 @@ -22,16 +22,26 @@ assert compare(ar, data) return array_type_test """) + cls.w_array_scalar_op_test = cls.space.appexec([cls.w_compare], + """(compare): + def array_scalar_op_test(self, data_type, f, value, length): + compare = self.compare + from numpy import array + data = [data_type(x) for x in range(length)] + ar = array(data) + assert compare(f(ar, value), [f(x, value) for x in data]) + return array_scalar_op_test + """) def test_int_array(self): self.array_type_test(int) def test_float_array(self): self.array_type_test(float) - def test_array_mul(self): - compare = self.compare - from numpy import array - data = range(4) - ar = array(data) - assert compare(ar * 4, [x * 4 for x in data]) + def test_sdarray_operators(self): + from operator import mul, div, add, sub + self.array_scalar_op_test(self, float, mul, 2.0, 16) + self.array_scalar_op_test(self, float, div, 2.0, 16) + self.array_scalar_op_test(self, float, add, 2.0, 16) + self.array_scalar_op_test(self, float, sub, 2.0, 16) def test_iterable_construction(self): compare = self.compare From dan at codespeak.net Sat Jan 2 13:40:19 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Sat, 2 Jan 2010 13:40:19 +0100 (CET) Subject: [pypy-svn] r70379 - pypy/branch/micronumpy/pypy/module/micronumpy Message-ID: <20100102124019.DCE42168039@codespeak.net> Author: dan Date: Sat Jan 2 13:40:19 2010 New Revision: 70379 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Log: Added str() and repr() methods to ndarray instances, only implemented for single dimensional arrays, as always... Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py Sat Jan 2 13:40:19 2010 @@ -153,6 +153,15 @@ return self.array.len() descr_len.unwrap_spec = ['self', ObjSpace] + def descr_str(self, space): + return space.wrap("[%s]" % self.array.str()) + descr_str.unwrap_spec = ['self', ObjSpace] + + def descr_repr(self, space): + return space.wrap("array([%s])" % self.array.str()) + descr_repr.unwrap_spec = ['self', ObjSpace] + + def descr_new(space, w_cls, w_shape, w_buffer=NoneNotWrapped, w_offset=NoneNotWrapped, w_strides=NoneNotWrapped, order=NoneNotWrapped): @@ -171,6 +180,8 @@ __div__ = interp2app(ndarray.descr_div), __add__ = interp2app(ndarray.descr_add), __sub__ = interp2app(ndarray.descr_sub), + __str__ = interp2app(ndarray.descr_str), + __repr__ = interp2app(ndarray.descr_repr), __getitem__ = interp2app(ndarray.descr_getitem), __setitem__ = interp2app(ndarray.descr_setitem), __len__ = interp2app(ndarray.descr_len), Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Sat Jan 2 13:40:19 2010 @@ -94,6 +94,9 @@ space = self.space return space.wrap(len(self.storage)) + def str(self): + return ', '.join([str(x) for x in self.storage]) + return NumArray IntArray = create_sdarray(int, unwrap_int, coerce_int) From pedronis at codespeak.net Sat Jan 2 19:00:44 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 2 Jan 2010 19:00:44 +0100 (CET) Subject: [pypy-svn] r70383 - pypy/trunk Message-ID: <20100102180044.58559168032@codespeak.net> Author: pedronis Date: Sat Jan 2 19:00:43 2010 New Revision: 70383 Modified: pypy/trunk/LICENSE Log: bump the copyright range, I'm sure will checkin code in 2010 :) Modified: pypy/trunk/LICENSE ============================================================================== --- pypy/trunk/LICENSE (original) +++ pypy/trunk/LICENSE Sat Jan 2 19:00:43 2010 @@ -27,7 +27,7 @@ DEALINGS IN THE SOFTWARE. -PyPy Copyright holders 2003-2009 +PyPy Copyright holders 2003-2010 ----------------------------------- Except when otherwise stated (look for LICENSE files or information at From arigo at codespeak.net Sun Jan 3 00:35:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 3 Jan 2010 00:35:02 +0100 (CET) Subject: [pypy-svn] r70384 - pypy/trunk/pypy/module/posix/test Message-ID: <20100102233502.6E171168032@codespeak.net> Author: arigo Date: Sun Jan 3 00:35:01 2010 New Revision: 70384 Modified: pypy/trunk/pypy/module/posix/test/test_posix2.py Log: Increase sleep()ing time to be greater than 1 second. Exactly 1 second might lead to corner cases. The test failed once because it started at time x+0.003, and the actual time it slept was lower than 0.997 seconds. Modified: pypy/trunk/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/trunk/pypy/module/posix/test/test_posix2.py (original) +++ pypy/trunk/pypy/module/posix/test/test_posix2.py Sun Jan 3 00:35:01 2010 @@ -312,7 +312,7 @@ fh.close() from time import time, sleep t0 = time() - sleep(1) + sleep(1.1) os.utime(path, None) assert os.stat(path).st_atime > t0 os.utime(path, (int(t0), int(t0))) From arigo at codespeak.net Sun Jan 3 16:40:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 3 Jan 2010 16:40:26 +0100 (CET) Subject: [pypy-svn] r70386 - in pypy/branch/virtual-forcing/pypy/jit: backend/test backend/x86 metainterp Message-ID: <20100103154026.8CA5416801D@codespeak.net> Author: arigo Date: Sun Jan 3 16:40:25 2010 New Revision: 70386 Modified: pypy/branch/virtual-forcing/pypy/jit/backend/test/test_random.py pypy/branch/virtual-forcing/pypy/jit/backend/x86/assembler.py pypy/branch/virtual-forcing/pypy/jit/backend/x86/regalloc.py pypy/branch/virtual-forcing/pypy/jit/metainterp/resoperation.py Log: Systematize the handling of "comparison" operations. Now a "comparison" is anything always pure and returning a boolean. Systematically implement it in the x86 backend. This should prevent a number of very slow machine code sequences, e.g. for float comparison. Modified: pypy/branch/virtual-forcing/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/backend/test/test_random.py Sun Jan 3 16:40:25 2010 @@ -431,10 +431,11 @@ for _op in [rop.FLOAT_NEG, rop.FLOAT_ABS, - rop.FLOAT_IS_TRUE, ]: OPERATIONS.append(UnaryFloatOperation(_op)) +OPERATIONS.append(UnaryFloatOperation(rop.FLOAT_IS_TRUE, boolres=True)) + OPERATIONS.append(CastFloatToIntOperation(rop.CAST_FLOAT_TO_INT)) OPERATIONS.append(CastIntToFloatOperation(rop.CAST_INT_TO_FLOAT)) Modified: pypy/branch/virtual-forcing/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/backend/x86/assembler.py Sun Jan 3 16:40:25 2010 @@ -368,19 +368,18 @@ def genop_cmp(self, op, arglocs, result_loc): if isinstance(op.args[0], Const): self.mc.CMP(arglocs[1], arglocs[0]) - self.mc.MOV(result_loc, imm8(0)) getattr(self.mc, 'SET' + rev_cond)(lower_byte(result_loc)) else: self.mc.CMP(arglocs[0], arglocs[1]) - self.mc.MOV(result_loc, imm8(0)) getattr(self.mc, 'SET' + cond)(lower_byte(result_loc)) + self.mc.MOVZX(result_loc, lower_byte(result_loc)) return genop_cmp def _cmpop_float(cond): def genop_cmp(self, op, arglocs, result_loc): self.mc.UCOMISD(arglocs[0], arglocs[1]) - self.mc.MOV(result_loc, imm8(0)) getattr(self.mc, 'SET' + cond)(lower_byte(result_loc)) + self.mc.MOVZX(result_loc, lower_byte(result_loc)) return genop_cmp def _cmpop_guard(cond, rev_cond, false_cond, false_rev_cond): @@ -404,6 +403,19 @@ return self.implement_guard(addr, getattr(self.mc, name)) return genop_cmp_guard + def _cmpop_guard_float(cond, false_cond): + def genop_cmp_guard_float(self, op, guard_op, addr, arglocs, + result_loc): + guard_opnum = guard_op.opnum + self.mc.UCOMISD(arglocs[0], arglocs[1]) + if guard_opnum == rop.GUARD_FALSE: + name = 'J' + cond + return self.implement_guard(addr, getattr(self.mc, name)) + else: + name = 'J' + false_cond + return self.implement_guard(addr, getattr(self.mc, name)) + return genop_cmp_guard_float + def _emit_call(self, x, arglocs, start=0, tmp=eax): p = 0 n = len(arglocs) @@ -454,11 +466,11 @@ genop_int_lt = _cmpop("L", "G") genop_int_le = _cmpop("LE", "GE") genop_int_eq = _cmpop("E", "E") - genop_oois = genop_int_eq genop_int_ne = _cmpop("NE", "NE") - genop_ooisnot = genop_int_ne genop_int_gt = _cmpop("G", "L") genop_int_ge = _cmpop("GE", "LE") + genop_oois = genop_int_eq + genop_ooisnot = genop_int_ne genop_float_lt = _cmpop_float('B') genop_float_le = _cmpop_float('BE') @@ -478,12 +490,21 @@ genop_guard_int_ne = _cmpop_guard("NE", "NE", "E", "E") genop_guard_int_gt = _cmpop_guard("G", "L", "LE", "GE") genop_guard_int_ge = _cmpop_guard("GE", "LE", "L", "G") + genop_guard_oois = genop_guard_int_eq + genop_guard_ooisnot = genop_guard_int_ne genop_guard_uint_gt = _cmpop_guard("A", "B", "BE", "AE") genop_guard_uint_lt = _cmpop_guard("B", "A", "AE", "BE") genop_guard_uint_le = _cmpop_guard("BE", "AE", "A", "B") genop_guard_uint_ge = _cmpop_guard("AE", "BE", "B", "A") + genop_guard_float_lt = _cmpop_guard_float("B", "AE") + genop_guard_float_le = _cmpop_guard_float("BE", "A") + genop_guard_float_eq = _cmpop_guard_float("E", "NE") + genop_guard_float_ne = _cmpop_guard_float("NE", "E") + genop_guard_float_gt = _cmpop_guard_float("A", "BE") + genop_guard_float_ge = _cmpop_guard_float("AE", "B") + def genop_float_neg(self, op, arglocs, resloc): # Following what gcc does: res = x ^ 0x8000000000000000 self.mc.XORPD(arglocs[0], self.loc_float_const_neg) @@ -492,6 +513,16 @@ # Following what gcc does: res = x & 0x7FFFFFFFFFFFFFFF self.mc.ANDPD(arglocs[0], self.loc_float_const_abs) + def genop_guard_float_is_true(self, op, guard_op, addr, arglocs, resloc): + guard_opnum = guard_op.opnum + loc0, loc1 = arglocs + self.mc.XORPD(loc0, loc0) + self.mc.UCOMISD(loc0, loc1) + if guard_opnum == rop.GUARD_TRUE: + return self.implement_guard(addr, self.mc.JZ) + else: + return self.implement_guard(addr, self.mc.JNZ) + def genop_float_is_true(self, op, arglocs, resloc): loc0, loc1 = arglocs self.mc.XORPD(loc0, loc0) @@ -505,9 +536,6 @@ def genop_cast_int_to_float(self, op, arglocs, resloc): self.mc.CVTSI2SD(resloc, arglocs[0]) - def genop_bool_not(self, op, arglocs, resloc): - self.mc.XOR(arglocs[0], imm8(1)) - def genop_int_lshift(self, op, arglocs, resloc): loc, loc2 = arglocs if loc2 is ecx: @@ -528,8 +556,7 @@ def genop_guard_int_is_true(self, op, guard_op, addr, arglocs, resloc): guard_opnum = guard_op.opnum - loc = arglocs[0] - self.mc.TEST(loc, loc) + self.mc.CMP(arglocs[0], imm8(0)) if guard_opnum == rop.GUARD_TRUE: return self.implement_guard(addr, self.mc.JZ) else: @@ -537,8 +564,19 @@ def genop_int_is_true(self, op, arglocs, resloc): self.mc.CMP(arglocs[0], imm8(0)) - self.mc.MOV(resloc, imm8(0)) self.mc.SETNE(lower_byte(resloc)) + self.mc.MOVZX(resloc, lower_byte(resloc)) + + def genop_guard_bool_not(self, op, guard_op, addr, arglocs, resloc): + guard_opnum = guard_op.opnum + self.mc.CMP(arglocs[0], imm8(0)) + if guard_opnum == rop.GUARD_TRUE: + return self.implement_guard(addr, self.mc.JNZ) + else: + return self.implement_guard(addr, self.mc.JZ) + + def genop_bool_not(self, op, arglocs, resloc): + self.mc.XOR(arglocs[0], imm8(1)) def genop_same_as(self, op, arglocs, resloc): self.mov(arglocs[0], resloc) Modified: pypy/branch/virtual-forcing/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/backend/x86/regalloc.py Sun Jan 3 16:40:25 2010 @@ -345,10 +345,10 @@ self.possibly_free_vars(op.args) continue if self.can_merge_with_next_guard(op, i, operations): - oplist[op.opnum](self, op, operations[i + 1]) + oplist_with_guard[op.opnum](self, op, operations[i + 1]) i += 1 else: - oplist[op.opnum](self, op, None) + oplist[op.opnum](self, op) if op.result is not None: self.possibly_free_var(op.result) self.rm._check_invariants() @@ -397,7 +397,7 @@ return self.xrm.loc(v) return self.rm.loc(v) - def _consider_guard(self, op, ignored): + def _consider_guard(self, op): loc = self.rm.make_sure_var_in_reg(op.args[0]) self.perform_guard(op, [loc], None) self.rm.possibly_free_var(op.args[0]) @@ -407,7 +407,7 @@ consider_guard_nonnull = _consider_guard consider_guard_isnull = _consider_guard - def consider_finish(self, op, ignored): + def consider_finish(self, op): locs = [self.loc(v) for v in op.args] locs_are_ref = [v.type == REF for v in op.args] fail_index = self.assembler.cpu.get_fail_descr_number(op.descr) @@ -415,10 +415,10 @@ self.exc, locs_are_ref) self.possibly_free_vars(op.args) - def consider_guard_no_exception(self, op, ignored): + def consider_guard_no_exception(self, op): self.perform_guard(op, [], None) - def consider_guard_exception(self, op, ignored): + def consider_guard_exception(self, op): loc = self.rm.make_sure_var_in_reg(op.args[0]) box = TempBox() loc1 = self.rm.force_allocate_reg(box, op.args) @@ -434,13 +434,13 @@ consider_guard_no_overflow = consider_guard_no_exception consider_guard_overflow = consider_guard_no_exception - def consider_guard_value(self, op, ignored): + def consider_guard_value(self, op): x = self.make_sure_var_in_reg(op.args[0]) y = self.loc(op.args[1]) self.perform_guard(op, [x, y], None) self.possibly_free_vars(op.args) - def consider_guard_class(self, op, ignored): + def consider_guard_class(self, op): assert isinstance(op.args[0], Box) x = self.rm.make_sure_var_in_reg(op.args[0]) y = self.loc(op.args[1]) @@ -449,15 +449,15 @@ consider_guard_nonnull_class = consider_guard_class - def _consider_binop_part(self, op, ignored): + def _consider_binop_part(self, op): x = op.args[0] argloc = self.loc(op.args[1]) loc = self.rm.force_result_in_reg(op.result, x, op.args) self.rm.possibly_free_var(op.args[1]) return loc, argloc - def _consider_binop(self, op, ignored): - loc, argloc = self._consider_binop_part(op, ignored) + def _consider_binop(self, op): + loc, argloc = self._consider_binop_part(op) self.Perform(op, [loc, argloc], loc) consider_int_add = _consider_binop @@ -471,14 +471,13 @@ consider_int_sub_ovf = _consider_binop consider_int_add_ovf = _consider_binop - def consider_int_neg(self, op, ignored): + def consider_int_neg(self, op): res = self.rm.force_result_in_reg(op.result, op.args[0]) self.Perform(op, [res], res) consider_int_invert = consider_int_neg - consider_bool_not = consider_int_neg - def consider_int_lshift(self, op, ignored): + def consider_int_lshift(self, op): if isinstance(op.args[1], Const): loc2 = self.rm.convert_to_imm(op.args[1]) else: @@ -504,11 +503,11 @@ self.rm.possibly_free_vars(op.args) self.rm.possibly_free_var(tmpvar) - def consider_int_mod(self, op, ignored): + def consider_int_mod(self, op): self._consider_int_div_or_mod(op, edx, eax) self.Perform(op, [eax, ecx], edx) - def consider_int_floordiv(self, op, ignored): + def consider_int_floordiv(self, op): self._consider_int_div_or_mod(op, eax, edx) self.Perform(op, [eax, ecx], eax) @@ -542,7 +541,7 @@ consider_oois = _consider_compop consider_ooisnot = _consider_compop - def _consider_float_op(self, op, ignored): + def _consider_float_op(self, op): loc1 = self.xrm.loc(op.args[1]) loc0 = self.xrm.force_result_in_reg(op.result, op.args[0], op.args) self.Perform(op, [loc0, loc1], loc0) @@ -553,15 +552,17 @@ consider_float_mul = _consider_float_op consider_float_truediv = _consider_float_op - def _consider_float_cmp(self, op, ignored): - assert ignored is None - # XXX so far we don't have guards here, but we want them + def _consider_float_cmp(self, op, guard_op): loc0 = self.xrm.make_sure_var_in_reg(op.args[0], op.args, imm_fine=False) loc1 = self.xrm.loc(op.args[1]) - res = self.rm.force_allocate_reg(op.result, need_lower_byte=True) - self.Perform(op, [loc0, loc1], res) - self.xrm.possibly_free_vars(op.args) + arglocs = [loc0, loc1] + self.xrm.possibly_free_vars(op.args) + if guard_op is None: + res = self.rm.force_allocate_reg(op.result, need_lower_byte=True) + self.Perform(op, arglocs, res) + else: + self.perform_with_guard(op, guard_op, arglocs, None) consider_float_lt = _consider_float_cmp consider_float_le = _consider_float_cmp @@ -570,32 +571,37 @@ consider_float_gt = _consider_float_cmp consider_float_ge = _consider_float_cmp - def consider_float_neg(self, op, ignored): + def consider_float_neg(self, op): loc0 = self.xrm.force_result_in_reg(op.result, op.args[0]) self.Perform(op, [loc0], loc0) self.xrm.possibly_free_var(op.args[0]) - def consider_float_abs(self, op, ignored): + def consider_float_abs(self, op): loc0 = self.xrm.force_result_in_reg(op.result, op.args[0]) self.Perform(op, [loc0], loc0) self.xrm.possibly_free_var(op.args[0]) - def consider_float_is_true(self, op, ignored): + def consider_float_is_true(self, op, guard_op): + # doesn't need arg to be in a register tmpbox0 = TempBox() loc0 = self.xrm.force_allocate_reg(tmpbox0) loc1 = self.xrm.loc(op.args[0]) - loc2 = self.rm.force_allocate_reg(op.result, need_lower_byte=True) - self.Perform(op, [loc0, loc1], loc2) + arglocs = [loc0, loc1] self.xrm.possibly_free_var(op.args[0]) self.xrm.possibly_free_var(tmpbox0) + if guard_op is not None: + self.perform_with_guard(op, guard_op, arglocs, None) + else: + loc2 = self.rm.force_allocate_reg(op.result, need_lower_byte=True) + self.Perform(op, arglocs, loc2) - def consider_cast_float_to_int(self, op, ignored): + def consider_cast_float_to_int(self, op): loc0 = self.xrm.make_sure_var_in_reg(op.args[0], imm_fine=False) loc1 = self.rm.force_allocate_reg(op.result) self.Perform(op, [loc0], loc1) self.xrm.possibly_free_var(op.args[0]) - def consider_cast_int_to_float(self, op, ignored): + def consider_cast_int_to_float(self, op): loc0 = self.rm.loc(op.args[0]) loc1 = self.xrm.force_allocate_reg(op.result) self.Perform(op, [loc0], loc1) @@ -625,7 +631,7 @@ self._call(op, [imm(size)] + [self.loc(arg) for arg in op.args], guard_not_forced_op=guard_not_forced_op) - def consider_call(self, op, ignored): + def consider_call(self, op): self._consider_call(op) consider_call_pure = consider_call @@ -633,7 +639,7 @@ assert guard_op is not None self._consider_call(op, guard_op) - def consider_cond_call_gc_wb(self, op, ignored): + def consider_cond_call_gc_wb(self, op): assert op.result is None arglocs = [self.loc(arg) for arg in op.args] # add eax, ecx and edx as extra "arguments" to ensure they are @@ -675,7 +681,7 @@ gc_ll_descr.get_malloc_fixedsize_slowpath_addr(), ) - def consider_new(self, op, ignored): + def consider_new(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.can_inline_malloc(op.descr): self._fastpath_malloc(op, op.descr) @@ -684,7 +690,7 @@ arglocs = [imm(x) for x in args] return self._call(op, arglocs) - def consider_new_with_vtable(self, op, ignored): + def consider_new_with_vtable(self, op): classint = op.args[0].getint() descrsize = self.assembler.cpu.class_sizes[classint] if self.assembler.cpu.gc_ll_descr.can_inline_malloc(descrsize): @@ -697,7 +703,7 @@ arglocs.append(self.loc(op.args[0])) return self._call(op, arglocs) - def consider_newstr(self, op, ignored): + def consider_newstr(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.get_funcptr_for_newstr is not None: # framework GC @@ -709,7 +715,7 @@ return self._malloc_varsize(ofs_items, ofs, 0, op.args[0], op.result) - def consider_newunicode(self, op, ignored): + def consider_newunicode(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.get_funcptr_for_newunicode is not None: # framework GC @@ -747,7 +753,7 @@ self.PerformDiscard(ResOperation(rop.SETFIELD_GC, [], None), [eax, imm(ofs_length), imm(WORD), loc]) - def consider_new_array(self, op, ignored): + def consider_new_array(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.get_funcptr_for_newarray is not None: # framework GC @@ -778,7 +784,7 @@ ptr = fielddescr.is_pointer_field() return imm(ofs), imm(size), ptr - def consider_setfield_gc(self, op, ignored): + def consider_setfield_gc(self, op): ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr) assert isinstance(size_loc, IMM32) if size_loc.value == 1: @@ -793,7 +799,7 @@ consider_setfield_raw = consider_setfield_gc - def consider_strsetitem(self, op, ignored): + def consider_strsetitem(self, op): base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args) value_loc = self.rm.make_sure_var_in_reg(op.args[2], op.args, @@ -803,7 +809,7 @@ consider_unicodesetitem = consider_strsetitem - def consider_setarrayitem_gc(self, op, ignored): + def consider_setarrayitem_gc(self, op): scale, ofs, ptr = self._unpack_arraydescr(op.descr) base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) if scale == 0: @@ -819,7 +825,7 @@ consider_setarrayitem_raw = consider_setarrayitem_gc - def consider_getfield_gc(self, op, ignored): + def consider_getfield_gc(self, op): ofs_loc, size_loc, _ = self._unpack_fielddescr(op.descr) base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) self.rm.possibly_free_vars(op.args) @@ -830,7 +836,7 @@ consider_getfield_raw_pure = consider_getfield_gc consider_getfield_gc_pure = consider_getfield_gc - def consider_getarrayitem_gc(self, op, ignored): + def consider_getarrayitem_gc(self, op): scale, ofs, _ = self._unpack_arraydescr(op.descr) base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args) @@ -840,22 +846,26 @@ consider_getarrayitem_gc_pure = consider_getarrayitem_gc - - def _consider_nullity(self, op, guard_op): - # doesn't need a register in arg + def consider_int_is_true(self, op, guard_op): + # doesn't need arg to be in a register + argloc = self.loc(op.args[0]) + self.rm.possibly_free_var(op.args[0]) if guard_op is not None: - argloc = self.rm.make_sure_var_in_reg(op.args[0]) - self.rm.possibly_free_var(op.args[0]) self.perform_with_guard(op, guard_op, [argloc], None) else: - argloc = self.loc(op.args[0]) - self.rm.possibly_free_var(op.args[0]) resloc = self.rm.force_allocate_reg(op.result, need_lower_byte=True) self.Perform(op, [argloc], resloc) - consider_int_is_true = _consider_nullity + def consider_bool_not(self, op, guard_op): + if guard_op is not None: + # doesn't need arg to be in a register + argloc = self.loc(op.args[0]) + self.rm.possibly_free_var(op.args[0]) + self.perform_with_guard(op, guard_op, [argloc], None) + else: + self.consider_int_neg(op) - def consider_same_as(self, op, ignored): + def consider_same_as(self, op): argloc = self.loc(op.args[0]) self.possibly_free_var(op.args[0]) resloc = self.force_allocate_reg(op.result) @@ -863,7 +873,7 @@ consider_cast_ptr_to_int = consider_same_as consider_virtual_ref = consider_same_as - def consider_strlen(self, op, ignored): + def consider_strlen(self, op): base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) self.rm.possibly_free_vars(op.args) result_loc = self.rm.force_allocate_reg(op.result) @@ -871,7 +881,7 @@ consider_unicodelen = consider_strlen - def consider_arraylen_gc(self, op, ignored): + def consider_arraylen_gc(self, op): arraydescr = op.descr assert isinstance(arraydescr, BaseArrayDescr) ofs = arraydescr.get_ofs_length(self.translate_support_code) @@ -880,7 +890,7 @@ result_loc = self.rm.force_allocate_reg(op.result) self.Perform(op, [base_loc, imm(ofs)], result_loc) - def consider_strgetitem(self, op, ignored): + def consider_strgetitem(self, op): base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args) self.rm.possibly_free_vars(op.args) @@ -889,7 +899,7 @@ consider_unicodegetitem = consider_strgetitem - def consider_jump(self, op, ignored): + def consider_jump(self, op): assembler = self.assembler assert self.jump_target_descr is None descr = op.descr @@ -917,10 +927,10 @@ self.possibly_free_vars(op.args) assembler.closing_jump(self.jump_target_descr) - def consider_debug_merge_point(self, op, ignored): + def consider_debug_merge_point(self, op): pass - def consider_virtual_ref_finish(self, op, ignored): + def consider_virtual_ref_finish(self, op): self.possibly_free_vars(op.args) def get_mark_gc_roots(self, gcrootmap): @@ -941,22 +951,37 @@ assert reg is eax # ok to ignore this one return gcrootmap.compress_callshape(shape) - def consider_force_token(self, op, ignored): + def consider_force_token(self, op): loc = self.rm.force_allocate_reg(op.result) self.Perform(op, [], loc) - def not_implemented_op(self, op, ignored): + def not_implemented_op(self, op): msg = "[regalloc] Not implemented operation: %s" % op.getopname() print msg raise NotImplementedError(msg) + def not_implemented_op_with_guard(self, op, guard_op): + msg = "[regalloc] Not implemented operation with guard: %s" % ( + op.getopname(),) + print msg + raise NotImplementedError(msg) + oplist = [RegAlloc.not_implemented_op] * rop._LAST +oplist_with_guard = [RegAlloc.not_implemented_op_with_guard] * rop._LAST + +def add_none_argument(fn): + return lambda self, op: fn(self, op, None) for name, value in RegAlloc.__dict__.iteritems(): if name.startswith('consider_'): name = name[len('consider_'):] num = getattr(rop, name.upper()) - oplist[num] = value + if (ResOperation(num, [], None).is_comparison() + or num == rop.CALL_MAY_FORCE): + oplist_with_guard[num] = value + oplist[num] = add_none_argument(value) + else: + oplist[num] = value def get_ebp_ofs(position): # Argument is a frame position (0, 1, 2...). Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/resoperation.py Sun Jan 3 16:40:25 2010 @@ -90,7 +90,7 @@ return rop._OVF_FIRST <= self.opnum <= rop._OVF_LAST def is_comparison(self): - return rop._COMPARISON_FIRST <= self.opnum <= rop._COMPARISON_LAST + return self.is_always_pure() and self.returns_bool_result() def is_final(self): return rop._FINAL_FIRST <= self.opnum <= rop._FINAL_LAST @@ -155,7 +155,6 @@ 'CAST_FLOAT_TO_INT/1', 'CAST_INT_TO_FLOAT/1', # - '_COMPARISON_FIRST', 'INT_LT/2b', 'INT_LE/2b', 'INT_EQ/2b', @@ -166,8 +165,7 @@ 'UINT_LE/2b', 'UINT_GT/2b', 'UINT_GE/2b', - '_COMPARISON_LAST', - 'FLOAT_LT/2b', # maybe these ones should be comparisons too + 'FLOAT_LT/2b', 'FLOAT_LE/2b', 'FLOAT_EQ/2b', 'FLOAT_NE/2b', From arigo at codespeak.net Sun Jan 3 16:44:39 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 3 Jan 2010 16:44:39 +0100 (CET) Subject: [pypy-svn] r70387 - pypy/branch/virtual-forcing/pypy/jit/backend/x86/test Message-ID: <20100103154439.548DA168020@codespeak.net> Author: arigo Date: Sun Jan 3 16:44:38 2010 New Revision: 70387 Modified: pypy/branch/virtual-forcing/pypy/jit/backend/x86/test/test_gc_integration.py Log: Fix test. Modified: pypy/branch/virtual-forcing/pypy/jit/backend/x86/test/test_gc_integration.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/backend/x86/test/test_gc_integration.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/backend/x86/test/test_gc_integration.py Sun Jan 3 16:44:38 2010 @@ -78,7 +78,7 @@ box = boxes[0] regalloc.position = 0 regalloc.consider_call(ResOperation(rop.CALL, [box], BoxInt(), - calldescr), None) + calldescr)) assert len(regalloc.assembler.movs) == 3 # mark = regalloc.get_mark_gc_roots(cpu.gc_ll_descr.gcrootmap) From arigo at codespeak.net Sun Jan 3 16:53:32 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 3 Jan 2010 16:53:32 +0100 (CET) Subject: [pypy-svn] r70388 - pypy/branch/virtual-forcing/pypy/jit/metainterp/test Message-ID: <20100103155332.7B498168020@codespeak.net> Author: arigo Date: Sun Jan 3 16:53:31 2010 New Revision: 70388 Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_executor.py Log: This case should not occur. Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_executor.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_executor.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_executor.py Sun Jan 3 16:53:31 2010 @@ -273,4 +273,4 @@ elif rettype == 'int': assert box.getint() == retvalue else: - assert retvalue is None + assert 0, "rettype is %r" % (rettype,) From arigo at codespeak.net Sun Jan 3 17:47:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 3 Jan 2010 17:47:15 +0100 (CET) Subject: [pypy-svn] r70389 - in pypy/branch/virtual-forcing/pypy/jit/metainterp: . test Message-ID: <20100103164715.5A07E16801B@codespeak.net> Author: arigo Date: Sun Jan 3 17:47:14 2010 New Revision: 70389 Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/codewriter.py pypy/branch/virtual-forcing/pypy/jit/metainterp/compile.py pypy/branch/virtual-forcing/pypy/jit/metainterp/optimizeopt.py pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_basic.py pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualref.py pypy/branch/virtual-forcing/pypy/jit/metainterp/virtualref.py pypy/branch/virtual-forcing/pypy/jit/metainterp/warmspot.py Log: Rewrite virtualref.py to have everything in a class instead of globally, like virtualizable.py. Fixes an issue with running many tests in the same process: the JIT_VIRTUAL_REF was a global GcStruct that was transformed by ll2ctypes and later that was passed to the C backend. Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/codewriter.py Sun Jan 3 17:47:14 2010 @@ -1308,10 +1308,9 @@ self.emit(self.var_position(args[0])) self.register_var(op.result) # - from pypy.jit.metainterp.virtualref import jit_virtual_ref_vtable - from pypy.jit.metainterp.virtualref import JIT_VIRTUAL_REF - self.codewriter.register_known_gctype(jit_virtual_ref_vtable, - JIT_VIRTUAL_REF) + vrefinfo = self.codewriter.metainterp_sd.virtualref_info + self.codewriter.register_known_gctype(vrefinfo.jit_virtual_ref_vtable, + vrefinfo.JIT_VIRTUAL_REF) def _array_of_voids(self, ARRAY): if isinstance(ARRAY, ootype.Array): Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/compile.py Sun Jan 3 17:47:14 2010 @@ -256,7 +256,6 @@ def handle_async_forcing(self, force_token): from pypy.jit.metainterp.pyjitpl import MetaInterp from pypy.jit.metainterp.resume import force_from_resumedata - from pypy.jit.metainterp.virtualref import forced_single_vref # To handle the forcing itself, we create a temporary MetaInterp # as a convenience to move the various data to its proper place. metainterp_sd = self.metainterp_sd @@ -270,10 +269,12 @@ virtualizable_boxes, virtualref_boxes, all_virtuals = forced_data # # Handle virtualref_boxes: mark each JIT_VIRTUAL_REF as forced + vrefinfo = metainterp_sd.virtualref_info for i in range(0, len(virtualref_boxes), 2): virtualbox = virtualref_boxes[i] vrefbox = virtualref_boxes[i+1] - forced_single_vref(vrefbox.getref_base(), virtualbox.getref_base()) + vrefinfo.forced_single_vref(vrefbox.getref_base(), + virtualbox.getref_base()) # Handle virtualizable_boxes: store them on the real virtualizable now if expect_virtualizable: metainterp_sd.virtualizable_info.forced_vable(virtualizable_boxes) Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/optimizeopt.py Sun Jan 3 17:47:14 2010 @@ -740,12 +740,11 @@ def optimize_VIRTUAL_REF(self, op): indexbox = op.args[1] # - # get some constants (these calls are all 'memo') - from pypy.jit.metainterp import virtualref - cpu = self.cpu - c_cls = virtualref.get_jit_virtual_ref_const_class(cpu) - descr_virtual_token = virtualref.get_descr_virtual_token(cpu) - descr_virtualref_index = virtualref.get_descr_virtualref_index(cpu) + # get some constants + vrefinfo = self.metainterp_sd.virtualref_info + c_cls = vrefinfo.jit_virtual_ref_const_class + descr_virtual_token = vrefinfo.descr_virtual_token + descr_virtualref_index = vrefinfo.descr_virtualref_index # # Replace the VIRTUAL_REF operation with a virtual structure of type # 'jit_virtual_ref'. The jit_virtual_ref structure may be forced soon, @@ -764,15 +763,15 @@ # opposed to much earlier. This is important because the object is # typically a PyPy PyFrame, and now is the end of its execution, so # forcing it now does not have catastrophic effects. - from pypy.jit.metainterp import virtualref + vrefinfo = self.metainterp_sd.virtualref_info # - set 'forced' to point to the real object op1 = ResOperation(rop.SETFIELD_GC, op.args, None, - descr = virtualref.get_descr_forced(self.cpu)) + descr = vrefinfo.descr_forced) self.optimize_SETFIELD_GC(op1) # - set 'virtual_token' to TOKEN_NONE args = [op.args[0], ConstInt(0)] op1 = ResOperation(rop.SETFIELD_GC, args, None, - descr = virtualref.get_descr_virtual_token(self.cpu)) + descr = vrefinfo.descr_virtual_token) self.optimize_SETFIELD_GC(op1) # Note that in some cases the virtual in op.args[1] has been forced # already. This is fine. In that case, and *if* a residual Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py Sun Jan 3 17:47:14 2010 @@ -5,7 +5,7 @@ from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.debug import debug_start, debug_stop, debug_print -from pypy.jit.metainterp import history, compile, resume, virtualref +from pypy.jit.metainterp import history, compile, resume from pypy.jit.metainterp.history import Const, ConstInt, Box from pypy.jit.metainterp.resoperation import rop from pypy.jit.metainterp import codewriter, executor @@ -903,8 +903,9 @@ if metainterp.is_blackholing(): resbox = box # good enough when blackholing else: + vrefinfo = metainterp.staticdata.virtualref_info obj = box.getref_base() - vref = virtualref.virtual_ref_during_tracing(obj) + vref = vrefinfo.virtual_ref_during_tracing(obj) resbox = history.BoxPtr(vref) cindex = history.ConstInt(len(metainterp.virtualref_boxes) // 2) metainterp.history.record(rop.VIRTUAL_REF, [box, cindex], resbox) @@ -928,8 +929,9 @@ lastbox = metainterp.virtualref_boxes.pop() assert box.getref_base() == lastbox.getref_base() if not metainterp.is_blackholing(): + vrefinfo = metainterp.staticdata.virtualref_info vref = vrefbox.getref_base() - if virtualref.is_virtual_ref(vref): + if vrefinfo.is_virtual_ref(vref): metainterp.history.record(rop.VIRTUAL_REF_FINISH, [vrefbox, lastbox], None) @@ -1775,10 +1777,11 @@ if self.is_blackholing(): return # + vrefinfo = self.staticdata.virtualref_info for i in range(1, len(self.virtualref_boxes), 2): vrefbox = self.virtualref_boxes[i] vref = vrefbox.getref_base() - virtualref.tracing_before_residual_call(vref) + vrefinfo.tracing_before_residual_call(vref) # the FORCE_TOKEN is already set at runtime in each vref when # it is created, by optimizeopt.py. # @@ -1800,11 +1803,12 @@ else: escapes = False # + vrefinfo = self.staticdata.virtualref_info for i in range(0, len(self.virtualref_boxes), 2): virtualbox = self.virtualref_boxes[i] vrefbox = self.virtualref_boxes[i+1] vref = vrefbox.getref_base() - if virtualref.tracing_after_residual_call(vref): + if vrefinfo.tracing_after_residual_call(vref): # this vref was really a virtual_ref, but it escaped # during this CALL_MAY_FORCE. Mark this fact by # generating a VIRTUAL_REF_FINISH on it and replacing @@ -1874,11 +1878,12 @@ # # virtual refs: make the vrefs point to the freshly allocated virtuals self.virtualref_boxes = virtualref_boxes + vrefinfo = self.staticdata.virtualref_info for i in range(0, len(virtualref_boxes), 2): virtualbox = virtualref_boxes[i] vrefbox = virtualref_boxes[i+1] - virtualref.continue_tracing(vrefbox.getref_base(), - virtualbox.getref_base()) + vrefinfo.continue_tracing(vrefbox.getref_base(), + virtualbox.getref_base()) # # virtualizable: synchronize the real virtualizable and the local # boxes, in whichever direction is appropriate Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_basic.py Sun Jan 3 17:47:14 2010 @@ -86,6 +86,9 @@ metainterp, rtyper = _get_bare_metainterp(f, args, self.CPUClass, self.type_system, **kwds) + metainterp.staticdata.state = FakeWarmRunnerState() + metainterp.staticdata.state.cpu = metainterp.staticdata.cpu + self.finish_metainterp_for_interp_operations(metainterp) portal_graph = rtyper.annotator.translator.graphs[0] cw = codewriter.CodeWriter(rtyper) @@ -97,7 +100,6 @@ cw.finish_making_bytecodes() metainterp.staticdata.portal_code = maingraph metainterp.staticdata._class_sizes = cw.class_sizes - metainterp.staticdata.state = FakeWarmRunnerState() metainterp.staticdata.DoneWithThisFrameInt = DoneWithThisFrame metainterp.staticdata.DoneWithThisFrameRef = DoneWithThisFrameRef metainterp.staticdata.DoneWithThisFrameFloat = DoneWithThisFrame @@ -111,6 +113,9 @@ else: raise Exception("FAILED") + def finish_metainterp_for_interp_operations(self, metainterp): + pass + def check_history(self, expected=None, **isns): # this can be used after calling meta_interp get_stats().check_history(expected, **isns) Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualref.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualref.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualref.py Sun Jan 3 17:47:14 2010 @@ -5,13 +5,17 @@ from pypy.rlib.objectmodel import compute_unique_id from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin from pypy.jit.metainterp.resoperation import rop -from pypy.jit.metainterp.virtualref import JIT_VIRTUAL_REF +from pypy.jit.metainterp.virtualref import VirtualRefInfo debug_print = lloperation.llop.debug_print class VRefTests: + def finish_metainterp_for_interp_operations(self, metainterp): + self.vrefinfo = VirtualRefInfo(metainterp.staticdata.state) + metainterp.staticdata.virtualref_info = self.vrefinfo + def test_make_vref_simple(self): class X: pass @@ -73,6 +77,7 @@ bxs2 = [box for box in guard_op.fail_args if str(box._getrepr_()).endswith('JitVirtualRef')] assert len(bxs2) == 1 + JIT_VIRTUAL_REF = self.vrefinfo.JIT_VIRTUAL_REF bxs2[0].getref(lltype.Ptr(JIT_VIRTUAL_REF)).virtual_token = 1234567 # self.metainterp.rebuild_state_after_failure(guard_op.descr, Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/virtualref.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/virtualref.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/virtualref.py Sun Jan 3 17:47:14 2010 @@ -1,157 +1,155 @@ from pypy.rpython.rmodel import inputconst, log from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass -from pypy.rlib.objectmodel import specialize from pypy.jit.metainterp import history -def replace_force_virtual_with_call(warmrunnerdesc, graphs): - # similar to rvirtualizable2.replace_force_virtualizable_with_call(). - c_funcptr = None - count = 0 - for graph in graphs: - for block in graph.iterblocks(): - for op in block.operations: - if op.opname == 'jit_force_virtual': - # first compute c_funcptr, but only if there is any - # 'jit_force_virtual' around - if c_funcptr is None: - c_funcptr = get_force_virtual_fnptr(warmrunnerdesc) - # - op.opname = 'direct_call' - op.args = [c_funcptr, op.args[0]] - count += 1 - if c_funcptr is not None: - log("replaced %d 'jit_force_virtual' with %r" % (count, - c_funcptr.value)) - # - # record the type JIT_VIRTUAL_REF explicitly in the rtyper, too - warmrunnerdesc.rtyper.set_type_for_typeptr(jit_virtual_ref_vtable, - JIT_VIRTUAL_REF) - -# ____________________________________________________________ - - -# we make the low-level type of an RPython class directly -JIT_VIRTUAL_REF = lltype.GcStruct('JitVirtualRef', - ('super', rclass.OBJECT), - ('virtual_token', lltype.Signed), - ('virtualref_index', lltype.Signed), - ('forced', rclass.OBJECTPTR)) -jit_virtual_ref_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True, - flavor='raw') -jit_virtual_ref_vtable.name = rclass.alloc_array_name('jit_virtual_ref') - -# The 'virtual_token' field has the same meaning as the 'vable_token' field -# of a virtualizable. It is equal to: -# * 0 (TOKEN_NONE) when tracing, except as described below; -# * -1 (TOKEN_TRACING_RESCALL) during tracing when we do a residual call; -# * addr in the CPU stack (set by FORCE_TOKEN) when running the assembler; -# * 0 (TOKEN_NONE) after the virtual is forced, if it is forced at all. -TOKEN_NONE = 0 -TOKEN_TRACING_RESCALL = -1 - - at specialize.memo() -def get_jit_virtual_ref_const_class(cpu): - adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable) - return history.ConstAddr(adr, cpu) - - at specialize.memo() -def get_descr_virtual_token(cpu): - return cpu.fielddescrof(JIT_VIRTUAL_REF, 'virtual_token') - - at specialize.memo() -def get_descr_virtualref_index(cpu): - return cpu.fielddescrof(JIT_VIRTUAL_REF, 'virtualref_index') - - at specialize.memo() -def get_descr_forced(cpu): - return cpu.fielddescrof(JIT_VIRTUAL_REF, 'forced') - -def virtual_ref_during_tracing(real_object): - assert real_object - vref = lltype.malloc(JIT_VIRTUAL_REF) - p = lltype.cast_pointer(rclass.OBJECTPTR, vref) - p.typeptr = jit_virtual_ref_vtable - vref.virtual_token = TOKEN_NONE - vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object) - return lltype.cast_opaque_ptr(llmemory.GCREF, vref) - -def is_virtual_ref(gcref): - if not gcref: - return False - inst = lltype.cast_opaque_ptr(rclass.OBJECTPTR, gcref) - return inst.typeptr == jit_virtual_ref_vtable - -def tracing_before_residual_call(gcref): - if not is_virtual_ref(gcref): - return - vref = lltype.cast_opaque_ptr(lltype.Ptr(JIT_VIRTUAL_REF), gcref) - assert not vref.virtual_token - vref.virtual_token = TOKEN_TRACING_RESCALL - -def tracing_after_residual_call(gcref): - if not is_virtual_ref(gcref): - return False - vref = lltype.cast_opaque_ptr(lltype.Ptr(JIT_VIRTUAL_REF), gcref) - if vref.virtual_token: - # not modified by the residual call; assert that it is still - # set to TOKEN_TRACING_RESCALL and clear it. - assert vref.virtual_token == TOKEN_TRACING_RESCALL - vref.virtual_token = TOKEN_NONE - return False - else: - # marker "modified during residual call" set. +class VirtualRefInfo: + + def __init__(self, warmrunnerdesc): + self.warmrunnerdesc = warmrunnerdesc + self.cpu = warmrunnerdesc.cpu + # we make the low-level type of an RPython class directly + self.JIT_VIRTUAL_REF = lltype.GcStruct('JitVirtualRef', + ('super', rclass.OBJECT), + ('virtual_token', lltype.Signed), + ('virtualref_index', lltype.Signed), + ('forced', rclass.OBJECTPTR)) + self.jit_virtual_ref_vtable = lltype.malloc(rclass.OBJECT_VTABLE, + zero=True, flavor='raw') + self.jit_virtual_ref_vtable.name = rclass.alloc_array_name( + 'jit_virtual_ref') + # build some constants + adr = llmemory.cast_ptr_to_adr(self.jit_virtual_ref_vtable) + self.jit_virtual_ref_const_class = history.ConstAddr(adr, self.cpu) + fielddescrof = self.cpu.fielddescrof + self.descr_virtual_token = fielddescrof(self.JIT_VIRTUAL_REF, + 'virtual_token') + self.descr_virtualref_index = fielddescrof(self.JIT_VIRTUAL_REF, + 'virtualref_index') + self.descr_forced = fielddescrof(self.JIT_VIRTUAL_REF, 'forced') + + def _freeze_(self): return True -def forced_single_vref(gcref, real_object): - if not is_virtual_ref(gcref): - return - assert real_object - vref = lltype.cast_opaque_ptr(lltype.Ptr(JIT_VIRTUAL_REF), gcref) - assert (vref.virtual_token != TOKEN_NONE and - vref.virtual_token != TOKEN_TRACING_RESCALL) - vref.virtual_token = TOKEN_NONE - vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object) - -def continue_tracing(gcref, real_object): - if not is_virtual_ref(gcref): - return - vref = lltype.cast_opaque_ptr(lltype.Ptr(JIT_VIRTUAL_REF), gcref) - assert vref.virtual_token != TOKEN_TRACING_RESCALL - vref.virtual_token = TOKEN_NONE - vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object) - -# ____________________________________________________________ - -def get_force_virtual_fnptr(warmrunnerdesc): - cpu = warmrunnerdesc.cpu - # - def force_virtual_if_necessary(inst): - if not inst or inst.typeptr != jit_virtual_ref_vtable: - return inst # common, fast case - return force_virtual(cpu, inst) - # - FUNC = lltype.FuncType([rclass.OBJECTPTR], rclass.OBJECTPTR) - funcptr = warmrunnerdesc.helper_func( - lltype.Ptr(FUNC), - force_virtual_if_necessary) - return inputconst(lltype.typeOf(funcptr), funcptr) - -def force_virtual(cpu, inst): - vref = lltype.cast_pointer(lltype.Ptr(JIT_VIRTUAL_REF), inst) - token = vref.virtual_token - if token != TOKEN_NONE: - if token == TOKEN_TRACING_RESCALL: - # The "virtual" is not a virtual at all during tracing. - # We only need to reset virtual_token to TOKEN_NONE - # as a marker for the tracing, to tell it that this - # "virtual" escapes. - vref.virtual_token = TOKEN_NONE + def replace_force_virtual_with_call(self, graphs): + # similar to rvirtualizable2.replace_force_virtualizable_with_call(). + c_funcptr = None + count = 0 + for graph in graphs: + for block in graph.iterblocks(): + for op in block.operations: + if op.opname == 'jit_force_virtual': + # first compute c_funcptr, but only if there is any + # 'jit_force_virtual' around + if c_funcptr is None: + c_funcptr = self.get_force_virtual_fnptr() + # + op.opname = 'direct_call' + op.args = [c_funcptr, op.args[0]] + count += 1 + if c_funcptr is not None: + log("replaced %d 'jit_force_virtual' with %r" % (count, + c_funcptr.value)) + # + # record the type JIT_VIRTUAL_REF explicitly in the rtyper, too + self.warmrunnerdesc.rtyper.set_type_for_typeptr( + self.jit_virtual_ref_vtable, self.JIT_VIRTUAL_REF) + + # ____________________________________________________________ + + # The 'virtual_token' field has the same meaning as the 'vable_token' field + # of a virtualizable. It is equal to: + # * 0 (TOKEN_NONE) when tracing, except as described below; + # * -1 (TOKEN_TRACING_RESCALL) during tracing when we do a residual call; + # * addr in the CPU stack (set by FORCE_TOKEN) when running the assembler; + # * 0 (TOKEN_NONE) after the virtual is forced, if it is forced at all. + TOKEN_NONE = 0 + TOKEN_TRACING_RESCALL = -1 + + def virtual_ref_during_tracing(self, real_object): + assert real_object + vref = lltype.malloc(self.JIT_VIRTUAL_REF) + p = lltype.cast_pointer(rclass.OBJECTPTR, vref) + p.typeptr = self.jit_virtual_ref_vtable + vref.virtual_token = self.TOKEN_NONE + vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object) + return lltype.cast_opaque_ptr(llmemory.GCREF, vref) + + def is_virtual_ref(self, gcref): + if not gcref: + return False + inst = lltype.cast_opaque_ptr(rclass.OBJECTPTR, gcref) + return inst.typeptr == self.jit_virtual_ref_vtable + + def tracing_before_residual_call(self, gcref): + if not self.is_virtual_ref(gcref): + return + vref = lltype.cast_opaque_ptr(lltype.Ptr(self.JIT_VIRTUAL_REF), gcref) + assert not vref.virtual_token + vref.virtual_token = self.TOKEN_TRACING_RESCALL + + def tracing_after_residual_call(self, gcref): + if not self.is_virtual_ref(gcref): + return False + vref = lltype.cast_opaque_ptr(lltype.Ptr(self.JIT_VIRTUAL_REF), gcref) + if vref.virtual_token: + # not modified by the residual call; assert that it is still + # set to TOKEN_TRACING_RESCALL and clear it. + assert vref.virtual_token == self.TOKEN_TRACING_RESCALL + vref.virtual_token = self.TOKEN_NONE + return False else: - assert not vref.forced - from pypy.jit.metainterp.compile import ResumeGuardForcedDescr - ResumeGuardForcedDescr.force_now(cpu, token) - assert vref.virtual_token == TOKEN_NONE - assert vref.forced - return vref.forced -force_virtual._dont_inline_ = True + # marker "modified during residual call" set. + return True + + def forced_single_vref(self, gcref, real_object): + if not self.is_virtual_ref(gcref): + return + assert real_object + vref = lltype.cast_opaque_ptr(lltype.Ptr(self.JIT_VIRTUAL_REF), gcref) + assert (vref.virtual_token != self.TOKEN_NONE and + vref.virtual_token != self.TOKEN_TRACING_RESCALL) + vref.virtual_token = self.TOKEN_NONE + vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object) + + def continue_tracing(self, gcref, real_object): + if not self.is_virtual_ref(gcref): + return + vref = lltype.cast_opaque_ptr(lltype.Ptr(self.JIT_VIRTUAL_REF), gcref) + assert vref.virtual_token != self.TOKEN_TRACING_RESCALL + vref.virtual_token = self.TOKEN_NONE + vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object) + + # ____________________________________________________________ + + def get_force_virtual_fnptr(self): + # + def force_virtual_if_necessary(inst): + if not inst or inst.typeptr != self.jit_virtual_ref_vtable: + return inst # common, fast case + return self.force_virtual(inst) + # + FUNC = lltype.FuncType([rclass.OBJECTPTR], rclass.OBJECTPTR) + funcptr = self.warmrunnerdesc.helper_func( + lltype.Ptr(FUNC), + force_virtual_if_necessary) + return inputconst(lltype.typeOf(funcptr), funcptr) + + def force_virtual(self, inst): + vref = lltype.cast_pointer(lltype.Ptr(self.JIT_VIRTUAL_REF), inst) + token = vref.virtual_token + if token != self.TOKEN_NONE: + if token == self.TOKEN_TRACING_RESCALL: + # The "virtual" is not a virtual at all during tracing. + # We only need to reset virtual_token to TOKEN_NONE + # as a marker for the tracing, to tell it that this + # "virtual" escapes. + vref.virtual_token = self.TOKEN_NONE + else: + assert not vref.forced + from pypy.jit.metainterp.compile import ResumeGuardForcedDescr + ResumeGuardForcedDescr.force_now(self.cpu, token) + assert vref.virtual_token == self.TOKEN_NONE + assert vref.forced + return vref.forced + force_virtual._dont_inline_ = True Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/warmspot.py Sun Jan 3 17:47:14 2010 @@ -17,7 +17,7 @@ from pypy.translator.unsimplify import call_final_function from pypy.jit.metainterp import codewriter -from pypy.jit.metainterp import support, history, pyjitpl, gc, virtualref +from pypy.jit.metainterp import support, history, pyjitpl, gc from pypy.jit.metainterp.pyjitpl import MetaInterpStaticData, MetaInterp from pypy.jit.metainterp.policy import JitPolicy from pypy.jit.metainterp.typesystem import LLTypeHelper, OOTypeHelper @@ -162,9 +162,13 @@ self.build_meta_interp(CPUClass, **kwds) self.make_args_specification() + # + from pypy.jit.metainterp.virtualref import VirtualRefInfo + self.metainterp_sd.virtualref_info = VirtualRefInfo(self) if self.jitdriver.virtualizables: from pypy.jit.metainterp.virtualizable import VirtualizableInfo self.metainterp_sd.virtualizable_info = VirtualizableInfo(self) + # self.make_exception_classes() self.make_driverhook_graphs() self.make_enter_function() @@ -604,7 +608,8 @@ if self.cpu.ts.name != 'lltype': py.test.skip("rewrite_force_virtual: port it to ootype") all_graphs = self.translator.graphs - virtualref.replace_force_virtual_with_call(self, all_graphs) + vrefinfo = self.metainterp_sd.virtualref_info + vrefinfo.replace_force_virtual_with_call(all_graphs) def decode_hp_hint_args(op): From arigo at codespeak.net Sun Jan 3 17:51:21 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 3 Jan 2010 17:51:21 +0100 (CET) Subject: [pypy-svn] r70390 - pypy/branch/virtual-forcing/pypy/jit/metainterp/test Message-ID: <20100103165121.4016616801B@codespeak.net> Author: arigo Date: Sun Jan 3 17:51:20 2010 New Revision: 70390 Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_codewriter.py Log: Add missing fake stuff. Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_codewriter.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_codewriter.py Sun Jan 3 17:51:20 2010 @@ -436,6 +436,12 @@ assert effectinfo_g2.forces_virtual_or_virtualizable assert not effectinfo_h.forces_virtual_or_virtualizable + def make_vrefinfo(self): + from pypy.jit.metainterp.virtualref import VirtualRefInfo + class FakeWarmRunnerDesc: + cpu = self.metainterp_sd.cpu + self.metainterp_sd.virtualref_info = VirtualRefInfo(FakeWarmRunnerDesc) + def test_vref_simple(self): class X: pass @@ -444,6 +450,7 @@ graphs = self.make_graphs(f, []) assert graphs[0].func is f assert graphs[1].func is jit.virtual_ref + self.make_vrefinfo() cw = CodeWriter(self.rtyper) cw.candidate_graphs = [graphs[0]] cw._start(self.metainterp_sd, None) @@ -459,6 +466,7 @@ graphs = self.make_graphs(f, []) assert graphs[0].func is f assert graphs[1].func is jit.virtual_ref + self.make_vrefinfo() cw = CodeWriter(self.rtyper) cw.candidate_graphs = [graphs[0]] cw._start(self.metainterp_sd, None) From arigo at codespeak.net Sun Jan 3 17:55:25 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 3 Jan 2010 17:55:25 +0100 (CET) Subject: [pypy-svn] r70391 - pypy/branch/virtual-forcing/pypy/jit/metainterp/test Message-ID: <20100103165525.73CFB16801B@codespeak.net> Author: arigo Date: Sun Jan 3 17:55:24 2010 New Revision: 70391 Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizefindnode.py Log: More fixes. Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizefindnode.py Sun Jan 3 17:55:24 2010 @@ -115,18 +115,22 @@ EffectInfo([nextdescr], [], [], forces_virtual_or_virtualizable=True)) - from pypy.jit.metainterp.virtualref import jit_virtual_ref_vtable - from pypy.jit.metainterp.virtualref import JIT_VIRTUAL_REF - virtualtokendescr = cpu.fielddescrof(JIT_VIRTUAL_REF, 'virtual_token') - virtualrefindexdescr = cpu.fielddescrof(JIT_VIRTUAL_REF,'virtualref_index') - virtualforceddescr = cpu.fielddescrof(JIT_VIRTUAL_REF, 'forced') - jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable) + from pypy.jit.metainterp.virtualref import VirtualRefInfo + class FakeWarmRunnerDesc: + pass + FakeWarmRunnerDesc.cpu = cpu + vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc) + virtualtokendescr = vrefinfo.descr_virtual_token + virtualrefindexdescr = vrefinfo.descr_virtualref_index + virtualforceddescr = vrefinfo.descr_forced + jvr_vtable_adr = llmemory.cast_ptr_to_adr(vrefinfo.jit_virtual_ref_vtable) cpu.class_sizes = { cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE), cpu.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2), cpu.cast_adr_to_int(u_vtable_adr): cpu.sizeof(U), - cpu.cast_adr_to_int(jvr_vtable_adr): cpu.sizeof(JIT_VIRTUAL_REF), + cpu.cast_adr_to_int(jvr_vtable_adr): cpu.sizeof( + vrefinfo.JIT_VIRTUAL_REF), } namespace = locals() From arigo at codespeak.net Sun Jan 3 18:04:52 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 3 Jan 2010 18:04:52 +0100 (CET) Subject: [pypy-svn] r70392 - pypy/branch/virtual-forcing/pypy/jit/metainterp/test Message-ID: <20100103170452.3C8ED16801B@codespeak.net> Author: arigo Date: Sun Jan 3 18:04:51 2010 New Revision: 70392 Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizeopt.py Log: More fixes. Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizefindnode.py Sun Jan 3 18:04:51 2010 @@ -123,7 +123,8 @@ virtualtokendescr = vrefinfo.descr_virtual_token virtualrefindexdescr = vrefinfo.descr_virtualref_index virtualforceddescr = vrefinfo.descr_forced - jvr_vtable_adr = llmemory.cast_ptr_to_adr(vrefinfo.jit_virtual_ref_vtable) + jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable + jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable) cpu.class_sizes = { cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE), Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_optimizeopt.py Sun Jan 3 18:04:51 2010 @@ -249,7 +249,10 @@ loop.token.specnodes = self.unpack_specnodes(spectext) # self.loop = loop - optimize_loop_1(FakeMetaInterpStaticData(self.cpu), loop) + metainterp_sd = FakeMetaInterpStaticData(self.cpu) + if hasattr(self, 'vrefinfo'): + metainterp_sd.virtualref_info = self.vrefinfo + optimize_loop_1(metainterp_sd, loop) # expected = self.parse(optops) self.assert_equal(loop, expected) From arigo at codespeak.net Sun Jan 3 18:12:24 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 3 Jan 2010 18:12:24 +0100 (CET) Subject: [pypy-svn] r70393 - pypy/branch/virtual-forcing/pypy/jit/metainterp/test Message-ID: <20100103171224.36B81168006@codespeak.net> Author: arigo Date: Sun Jan 3 18:12:22 2010 New Revision: 70393 Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_basic.py Log: Fix for backend/x86/test/test_virtual. This method would hide the method from metainterp/test/test_virtualref in that case. Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_basic.py Sun Jan 3 18:12:22 2010 @@ -88,7 +88,8 @@ **kwds) metainterp.staticdata.state = FakeWarmRunnerState() metainterp.staticdata.state.cpu = metainterp.staticdata.cpu - self.finish_metainterp_for_interp_operations(metainterp) + if hasattr(self, 'finish_metainterp_for_interp_operations'): + self.finish_metainterp_for_interp_operations(metainterp) portal_graph = rtyper.annotator.translator.graphs[0] cw = codewriter.CodeWriter(rtyper) @@ -113,9 +114,6 @@ else: raise Exception("FAILED") - def finish_metainterp_for_interp_operations(self, metainterp): - pass - def check_history(self, expected=None, **isns): # this can be used after calling meta_interp get_stats().check_history(expected, **isns) From arigo at codespeak.net Mon Jan 4 17:16:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 4 Jan 2010 17:16:09 +0100 (CET) Subject: [pypy-svn] r70397 - pypy/trunk/pypy/lib/app_test/ctypes_tests Message-ID: <20100104161609.B8638168012@codespeak.net> Author: arigo Date: Mon Jan 4 17:16:09 2010 New Revision: 70397 Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py Log: A failing test that shows a missing keepalive in our ctypes. Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py (original) +++ pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py Mon Jan 4 17:16:09 2010 @@ -205,3 +205,20 @@ s.r = r # obscure assert s._objects == {'1': {}, '0:1': {'1': stuff}} + + def test_c_char_p(self): + class datum(Structure): + _fields_ = [ + ('dptr', c_char_p), + ('dsize', c_int), + ] + n = 2 + xs = "hello" * n + dat = datum() + dat.dptr = c_char_p(xs) + dat.dsize = 15 + import gc; gc.collect() + print 'dat.dptr =', repr(dat.dptr) + print 'dat._objects =', repr(dat._objects) + assert dat.dptr == "hellohello" + assert dat._objects == {'0': 'hellohello'} From arigo at codespeak.net Mon Jan 4 17:33:21 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 4 Jan 2010 17:33:21 +0100 (CET) Subject: [pypy-svn] r70399 - pypy/trunk/pypy/lib/app_test/ctypes_tests Message-ID: <20100104163321.8E44116801B@codespeak.net> Author: arigo Date: Mon Jan 4 17:33:20 2010 New Revision: 70399 Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py Log: Improve the test. Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py (original) +++ pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py Mon Jan 4 17:33:20 2010 @@ -207,18 +207,31 @@ assert s._objects == {'1': {}, '0:1': {'1': stuff}} def test_c_char_p(self): + n = 2 + xs = "hello" * n + x = c_char_p(xs) + del xs + import gc; gc.collect() + print 'x =', repr(x) + assert x.value == 'hellohello' + assert x._objects.keys() == ['0'] + # class datum(Structure): _fields_ = [ ('dptr', c_char_p), ('dsize', c_int), ] - n = 2 - xs = "hello" * n - dat = datum() - dat.dptr = c_char_p(xs) - dat.dsize = 15 - import gc; gc.collect() - print 'dat.dptr =', repr(dat.dptr) - print 'dat._objects =', repr(dat._objects) - assert dat.dptr == "hellohello" - assert dat._objects == {'0': 'hellohello'} + for wrap in [False, True]: + n = 2 + xs = "hello" * n + if wrap: + xs = c_char_p(xs) + dat = datum() + dat.dptr = xs + dat.dsize = 15 + del xs + import gc; gc.collect() + print 'dat.dptr =', repr(dat.dptr) + print 'dat._objects =', repr(dat._objects) + assert dat.dptr == "hellohello" + assert dat._objects.keys() == ['0'] From arigo at codespeak.net Mon Jan 4 17:48:35 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 4 Jan 2010 17:48:35 +0100 (CET) Subject: [pypy-svn] r70400 - in pypy/branch/virtual-forcing: . pypy/doc pypy/lib/app_test/ctypes_tests pypy/module/imp/test pypy/module/posix/test pypy/translator/goal Message-ID: <20100104164835.25DA816801B@codespeak.net> Author: arigo Date: Mon Jan 4 17:48:34 2010 New Revision: 70400 Modified: pypy/branch/virtual-forcing/LICENSE pypy/branch/virtual-forcing/pypy/doc/coding-guide.txt pypy/branch/virtual-forcing/pypy/doc/getting-started.txt pypy/branch/virtual-forcing/pypy/lib/app_test/ctypes_tests/test_keepalive.py pypy/branch/virtual-forcing/pypy/module/imp/test/test_import.py pypy/branch/virtual-forcing/pypy/module/posix/test/test_posix2.py pypy/branch/virtual-forcing/pypy/translator/goal/app_main.py Log: Merge changes from trunk, r70326:70399. Modified: pypy/branch/virtual-forcing/LICENSE ============================================================================== --- pypy/branch/virtual-forcing/LICENSE (original) +++ pypy/branch/virtual-forcing/LICENSE Mon Jan 4 17:48:34 2010 @@ -27,7 +27,7 @@ DEALINGS IN THE SOFTWARE. -PyPy Copyright holders 2003-2009 +PyPy Copyright holders 2003-2010 ----------------------------------- Except when otherwise stated (look for LICENSE files or information at Modified: pypy/branch/virtual-forcing/pypy/doc/coding-guide.txt ============================================================================== --- pypy/branch/virtual-forcing/pypy/doc/coding-guide.txt (original) +++ pypy/branch/virtual-forcing/pypy/doc/coding-guide.txt Mon Jan 4 17:48:34 2010 @@ -160,7 +160,8 @@ An example can be found in the current implementation which is quite elegant: For the definition of all the opcodes of the Python interpreter, the module ``dis`` is imported and used to initialize our -bytecode interpreter. (See ``__initclass__`` in `pyopcode.py`_). This +bytecode interpreter. (See ``__initclass__`` in +`pypy/interpreter/pyopcode.py`_). This saves us from adding extra modules to PyPy. The import code is run at startup time, and we are allowed to use the CPython builtin import function. @@ -173,8 +174,6 @@ enables the code generator to emit efficient machine level replacements for pure integer objects, for instance. -.. _`pyopcode.py`: http://codespeak.net/svn/pypy/dist/pypy/interpreter/pyopcode.py - Restricted Python ================= Modified: pypy/branch/virtual-forcing/pypy/doc/getting-started.txt ============================================================================== --- pypy/branch/virtual-forcing/pypy/doc/getting-started.txt (original) +++ pypy/branch/virtual-forcing/pypy/doc/getting-started.txt Mon Jan 4 17:48:34 2010 @@ -35,22 +35,31 @@ Before you can play with PyPy, you will need to obtain a copy of the sources. This can be done either by `downloading them from the download page`_ or by checking them out from the -repository using subversion. We suggest using subversion as it -offers access to the most recent versions. +repository using subversion. We suggest using subversion if one +wants to access the current development. .. _`downloading them from the download page`: download.html If you choose to use subversion, you must issue the following command on your command line, DOS box, or terminal:: - svn co http://codespeak.net/svn/pypy/dist pypy-dist + svn co http://codespeak.net/svn/pypy/trunk pypy-trunk + +This will check out the subversion head and place it into a directory +named ``pypy-trunk``, and will get you the PyPy source in +``pypy-trunk/pypy`` and documentation files in ``pypy-trunk/pypy/doc``. +We try to ensure that the head is always stable, but it might +occasionally be broken. You may want to check out `our nightly tests:`_ +find a revision (5-digit number) that passed at least the +``{own}`` and ``{applevel}`` tests (corresponding to a ``+`` sign on the +line ``success``) and then check out using:: + + svn co -rXXXXX http://codespeak.net/svn/pypy/trunk pypy-trunk + +where XXXXX is the revision number. + +.. _`our nightly tests:`: http://codespeak.net:8099/summary?branch= -This will check out the most recent stable release from subversion and -place it into a directory named ``pypy-dist``, and will get you the PyPy -source in ``pypy-dist/pypy`` and documentation files in -``pypy-dist/pypy/doc``. If you would prefer to check out the "cutting edge" -version of PyPy - which may not always be stable! - then check out -from ``http://codespeak.net/svn/pypy/trunk`` intead. Where to go from here ---------------------- Modified: pypy/branch/virtual-forcing/pypy/lib/app_test/ctypes_tests/test_keepalive.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/lib/app_test/ctypes_tests/test_keepalive.py (original) +++ pypy/branch/virtual-forcing/pypy/lib/app_test/ctypes_tests/test_keepalive.py Mon Jan 4 17:48:34 2010 @@ -205,3 +205,33 @@ s.r = r # obscure assert s._objects == {'1': {}, '0:1': {'1': stuff}} + + def test_c_char_p(self): + n = 2 + xs = "hello" * n + x = c_char_p(xs) + del xs + import gc; gc.collect() + print 'x =', repr(x) + assert x.value == 'hellohello' + assert x._objects.keys() == ['0'] + # + class datum(Structure): + _fields_ = [ + ('dptr', c_char_p), + ('dsize', c_int), + ] + for wrap in [False, True]: + n = 2 + xs = "hello" * n + if wrap: + xs = c_char_p(xs) + dat = datum() + dat.dptr = xs + dat.dsize = 15 + del xs + import gc; gc.collect() + print 'dat.dptr =', repr(dat.dptr) + print 'dat._objects =', repr(dat._objects) + assert dat.dptr == "hellohello" + assert dat._objects.keys() == ['0'] Modified: pypy/branch/virtual-forcing/pypy/module/imp/test/test_import.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/module/imp/test/test_import.py (original) +++ pypy/branch/virtual-forcing/pypy/module/imp/test/test_import.py Mon Jan 4 17:48:34 2010 @@ -348,7 +348,7 @@ def test_future_relative_import_error_when_in_non_package(self): exec """def imp(): from .string import inpackage - """ + """.rstrip() raises(ValueError, imp) def test_relative_import_with___name__(self): @@ -434,11 +434,15 @@ def test_reload_builtin(self): import sys + oldpath = sys.path try: del sys.setdefaultencoding except AttributeError: pass + reload(sys) + + assert sys.path is oldpath assert 'setdefaultencoding' in dir(sys) def test_reload_infinite(self): Modified: pypy/branch/virtual-forcing/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/module/posix/test/test_posix2.py (original) +++ pypy/branch/virtual-forcing/pypy/module/posix/test/test_posix2.py Mon Jan 4 17:48:34 2010 @@ -312,7 +312,7 @@ fh.close() from time import time, sleep t0 = time() - sleep(1) + sleep(1.1) os.utime(path, None) assert os.stat(path).st_atime > t0 os.utime(path, (int(t0), int(t0))) Modified: pypy/branch/virtual-forcing/pypy/translator/goal/app_main.py ============================================================================== --- pypy/branch/virtual-forcing/pypy/translator/goal/app_main.py (original) +++ pypy/branch/virtual-forcing/pypy/translator/goal/app_main.py Mon Jan 4 17:48:34 2010 @@ -228,7 +228,7 @@ newpath.insert(0, '') # remove duplicates _seen = {} - sys.path = [] + del sys.path[:] for dir in newpath: if dir not in _seen: sys.path.append(dir) From arigo at codespeak.net Mon Jan 4 18:41:48 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 4 Jan 2010 18:41:48 +0100 (CET) Subject: [pypy-svn] r70402 - in pypy/trunk/pypy: interpreter interpreter/test jit/backend jit/backend/llgraph jit/backend/test jit/backend/x86 jit/backend/x86/test jit/metainterp jit/metainterp/test jit/tool jit/tool/test module/_stackless module/pypyjit module/pypyjit/test module/sys objspace/flow rlib rlib/test rpython rpython/lltypesystem rpython/lltypesystem/test rpython/test translator/c translator/cli translator/jvm Message-ID: <20100104174148.B1B22168032@codespeak.net> Author: arigo Date: Mon Jan 4 18:41:45 2010 New Revision: 70402 Added: pypy/trunk/pypy/jit/backend/x86/test/test_virtualref.py - copied unchanged from r70400, pypy/branch/virtual-forcing/pypy/jit/backend/x86/test/test_virtualref.py pypy/trunk/pypy/jit/metainterp/test/test_virtualref.py - copied unchanged from r70400, pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualref.py pypy/trunk/pypy/jit/metainterp/virtualref.py - copied unchanged from r70400, pypy/branch/virtual-forcing/pypy/jit/metainterp/virtualref.py pypy/trunk/pypy/rlib/_jit_vref.py - copied unchanged from r70400, pypy/branch/virtual-forcing/pypy/rlib/_jit_vref.py pypy/trunk/pypy/rlib/test/test__jit_vref.py - copied unchanged from r70400, pypy/branch/virtual-forcing/pypy/rlib/test/test__jit_vref.py Modified: pypy/trunk/pypy/interpreter/executioncontext.py pypy/trunk/pypy/interpreter/generator.py pypy/trunk/pypy/interpreter/pyframe.py pypy/trunk/pypy/interpreter/pytraceback.py pypy/trunk/pypy/interpreter/test/test_executioncontext.py pypy/trunk/pypy/interpreter/test/test_zzpickle_and_slow.py pypy/trunk/pypy/jit/backend/llgraph/llimpl.py pypy/trunk/pypy/jit/backend/model.py pypy/trunk/pypy/jit/backend/test/runner_test.py pypy/trunk/pypy/jit/backend/test/support.py pypy/trunk/pypy/jit/backend/test/test_random.py pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/regalloc.py pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py pypy/trunk/pypy/jit/backend/x86/test/test_tlc.py pypy/trunk/pypy/jit/metainterp/codewriter.py pypy/trunk/pypy/jit/metainterp/compile.py pypy/trunk/pypy/jit/metainterp/effectinfo.py pypy/trunk/pypy/jit/metainterp/executor.py pypy/trunk/pypy/jit/metainterp/jitprof.py pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/pyjitpl.py pypy/trunk/pypy/jit/metainterp/resoperation.py pypy/trunk/pypy/jit/metainterp/resume.py pypy/trunk/pypy/jit/metainterp/support.py pypy/trunk/pypy/jit/metainterp/test/test_basic.py pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py pypy/trunk/pypy/jit/metainterp/test/test_executor.py pypy/trunk/pypy/jit/metainterp/test/test_jitprof.py pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py pypy/trunk/pypy/jit/metainterp/test/test_resume.py pypy/trunk/pypy/jit/metainterp/test/test_virtualizable.py pypy/trunk/pypy/jit/metainterp/virtualizable.py pypy/trunk/pypy/jit/metainterp/warmspot.py pypy/trunk/pypy/jit/tool/jitoutput.py pypy/trunk/pypy/jit/tool/test/test_jitoutput.py pypy/trunk/pypy/module/_stackless/interp_coroutine.py pypy/trunk/pypy/module/pypyjit/interp_jit.py pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py pypy/trunk/pypy/module/sys/vm.py pypy/trunk/pypy/objspace/flow/flowcontext.py pypy/trunk/pypy/rlib/jit.py pypy/trunk/pypy/rpython/llinterp.py pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py pypy/trunk/pypy/rpython/lltypesystem/lloperation.py pypy/trunk/pypy/rpython/lltypesystem/opimpl.py pypy/trunk/pypy/rpython/lltypesystem/rclass.py pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py pypy/trunk/pypy/rpython/rtyper.py pypy/trunk/pypy/rpython/rvirtualizable2.py pypy/trunk/pypy/rpython/test/test_rvirtualizable2.py pypy/trunk/pypy/translator/c/funcgen.py pypy/trunk/pypy/translator/cli/opcodes.py pypy/trunk/pypy/translator/jvm/opcodes.py Log: Merge the virtual-forcing branch, adding support for virtualrefs. Allows a big revert of the messy code in pypy/interpreter/ about chains of frames. I am merging this even though it's still giving a slow-down, notably on "pypy-c-jit richards", because it's really simplifying stuff and I don't want it to remain on a branch forever. Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Mon Jan 4 18:41:45 2010 @@ -17,7 +17,8 @@ def __init__(self, space): self.space = space - self._init_frame_chain() + self.topframeref = jit.vref_None + self.framestackdepth = 0 # tracing: space.frame_trace_action.fire() must be called to ensure # that tracing occurs whenever self.w_tracefunc or self.is_tracing # is modified. @@ -27,169 +28,43 @@ self.profilefunc = None self.w_profilefuncarg = None + def gettopframe(self): + return self.topframeref() + def gettopframe_nohidden(self): - frame = self.gettopframe() - # I guess this should just use getnextframe_nohidden XXX + frame = self.topframeref() while frame and frame.hide(): - frame = frame.f_back() + frame = frame.f_backref() return frame @staticmethod def getnextframe_nohidden(frame): - frame = frame.f_back() + frame = frame.f_backref() while frame and frame.hide(): - frame = frame.f_back() + frame = frame.f_backref() return frame def enter(self, frame): if self.framestackdepth > self.space.sys.recursionlimit: raise OperationError(self.space.w_RuntimeError, self.space.wrap("maximum recursion depth exceeded")) - self._chain(frame) + self.framestackdepth += 1 + frame.f_backref = self.topframeref + self.topframeref = jit.virtual_ref(frame) def leave(self, frame): - if self.profilefunc: - self._trace(frame, 'leaveframe', self.space.w_None) + try: + if self.profilefunc: + self._trace(frame, 'leaveframe', self.space.w_None) + finally: + self.topframeref = frame.f_backref + self.framestackdepth -= 1 + jit.virtual_ref_finish(frame) - self._unchain(frame) - if self.w_tracefunc is not None and not frame.hide(): self.space.frame_trace_action.fire() # ________________________________________________________________ - # the methods below are used for chaining frames in JIT-friendly way - # part of that stuff is obscure - - @jit.unroll_safe - def gettopframe(self): - frame = self.some_frame - if frame is not None: - while frame.f_forward is not None: - frame = frame.f_forward - return frame - - def _init_frame_chain(self): - # 'some_frame' points to any frame from this thread's frame stack - # (although in general it should point to the top one). - # XXX not true: some_frame must point to a frame from which we can - # reach the top frame by following the chain of f_forward - self.some_frame = None - self.framestackdepth = 0 - - @staticmethod - def _init_chaining_attributes(frame): - """ - explanation of the f_back handling: - ----------------------------------- - - in the non-JIT case, the frames simply form a doubly linked list via the - attributes f_back_some and f_forward. - - When the JIT is used, things become more complex, as functions can be - inlined into each other. In this case a frame chain can look like this: - - +---------------+ - | real_frame | - +---------------+ - | - | f_back_some - | - | - | +--------------+ - | | virtual frame| - | +--------------+ - | ^ - | | f_forward - | +--------------+ - | | virtual frame| - | +--------------+ - | ^ - | | - v | f_forward - +---------------+ - | real_frame | - +---------------+ - | - | - v - ... - - This ensures that the virtual frames don't escape via the f_back of the - real frames. For the same reason, the executioncontext's some_frame - attribute should only point to real frames. - - All places where a frame can become accessed from applevel-code (like - sys._getframe and traceback catching) need to call force_f_back to ensure - that the intermediate virtual frames are forced to be real ones. - - """ - frame.f_back_some = None - frame.f_forward = None - frame.f_back_forced = False - - def _chain(self, frame): - self.framestackdepth += 1 - # - frame.f_back_some = self.some_frame - if self._we_are_jitted(): - curtopframe = self.gettopframe() - assert curtopframe is not None - curtopframe.f_forward = frame - else: - self.some_frame = frame - - def _unchain(self, frame): - #assert frame is self.gettopframe() --- slowish - if self.some_frame is frame: - self.some_frame = frame.f_back_some - else: - f_back = frame.f_back() - if f_back is not None: - f_back.f_forward = None - - self.framestackdepth -= 1 - - @staticmethod - def _jit_rechain_frame(ec, frame): - # this method is called after the jit has seen enter (and thus _chain) - # of a frame, but then does not actually inline it. This method thus - # needs to make sure that the state is as if the _chain method had been - # executed outside of the jit. Note that this makes it important that - # _unchain does not call we_are_jitted - frame.f_back().f_forward = None - ec.some_frame = frame - - @staticmethod - @jit.unroll_safe - def _extract_back_from_frame(frame): - back_some = frame.f_back_some - if frame.f_back_forced: - # don't check back_some.f_forward in this case - return back_some - if back_some is None: - return None - while True: - f_forward = back_some.f_forward - if f_forward is frame or f_forward is None: - return back_some - back_some = f_forward - - @staticmethod - def _force_back_of_frame(frame): - orig_frame = frame - while frame is not None and not frame.f_back_forced: - frame.f_back_some = f_back = ExecutionContext._extract_back_from_frame(frame) - frame.f_back_forced = True - # now that we force the whole chain, we also have to set the - # forward links to None - frame.f_forward = None - frame = f_back - return orig_frame.f_back_some - - _we_are_jitted = staticmethod(we_are_jitted) # indirection for testing - - # the methods above are used for chaining frames in JIT-friendly way - # ________________________________________________________________ class Subcontext(object): @@ -204,7 +79,7 @@ self.is_tracing = 0 def enter(self, ec): - ec.some_frame = self.topframe + ec.topframeref = jit.non_virtual_ref(self.topframe) ec.framestackdepth = self.framestackdepth ec.w_tracefunc = self.w_tracefunc ec.profilefunc = self.profilefunc @@ -247,7 +122,7 @@ while index > 0: index -= 1 lst[index] = f - f = f.f_back() + f = f.f_backref() assert f is None return lst # coroutine: I think this is all, folks! Modified: pypy/trunk/pypy/interpreter/generator.py ============================================================================== --- pypy/trunk/pypy/interpreter/generator.py (original) +++ pypy/trunk/pypy/interpreter/generator.py Mon Jan 4 18:41:45 2010 @@ -2,6 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import NoneNotWrapped from pypy.rlib.rarithmetic import intmask +from pypy.rlib import jit from pypy.interpreter.pyopcode import LoopBlock @@ -64,7 +65,7 @@ else: return w_result # YIELDed finally: - self.frame.f_back_some = None + self.frame.f_backref = jit.vref_None self.running = False def descr_throw(self, w_type, w_val=None, w_tb=None): Modified: pypy/trunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/pypy/interpreter/pyframe.py Mon Jan 4 18:41:45 2010 @@ -34,13 +34,13 @@ * 'builtin' is the attached built-in module * 'valuestack_w', 'blockstack', control the interpretation """ - __metaclass__ = extendabletype frame_finished_execution = False last_instr = -1 last_exception = None + f_backref = jit.vref_None w_f_trace = None # For tracing instr_lb = 0 @@ -64,7 +64,6 @@ self.fastlocals_w = [None]*self.numlocals make_sure_not_resized(self.fastlocals_w) self.f_lineno = code.co_firstlineno - ExecutionContext._init_chaining_attributes(self) def append_block(self, block): block.previous = self.lastblock @@ -308,7 +307,7 @@ w_tb = w(self.last_exception.application_traceback) tup_state = [ - w(self.f_back()), + w(self.f_backref()), w(self.get_builtin()), w(self.pycode), w_valuestack, @@ -360,8 +359,8 @@ # do not use the instance's __init__ but the base's, because we set # everything like cells from here PyFrame.__init__(self, space, pycode, w_globals, closure) - new_frame.f_back_some = space.interp_w(PyFrame, w_f_back, can_be_None=True) - new_frame.f_back_forced = True + f_back = space.interp_w(PyFrame, w_f_back, can_be_None=True) + new_frame.f_backref = jit.non_virtual_ref(f_back) new_frame.builtin = space.interp_w(Module, w_builtin) new_frame.set_blocklist([unpickle_block(space, w_blk) @@ -431,12 +430,6 @@ def _setcellvars(self, cellvars): pass - def f_back(self): - return ExecutionContext._extract_back_from_frame(self) - - def force_f_back(self): - return ExecutionContext._force_back_of_frame(self) - ### line numbers ### # for f*_f_* unwrapping through unwrap_spec in typedef.py @@ -584,7 +577,7 @@ return self.get_builtin().getdict() def fget_f_back(space, self): - return self.space.wrap(self.f_back()) + return self.space.wrap(self.f_backref()) def fget_f_lasti(space, self): return self.space.wrap(self.last_instr) @@ -605,27 +598,27 @@ def fget_f_exc_type(space, self): if self.last_exception is not None: - f = self.f_back() + f = self.f_backref() while f is not None and f.last_exception is None: - f = f.f_back() + f = f.f_backref() if f is not None: return f.last_exception.w_type return space.w_None def fget_f_exc_value(space, self): if self.last_exception is not None: - f = self.f_back() + f = self.f_backref() while f is not None and f.last_exception is None: - f = f.f_back() + f = f.f_backref() if f is not None: return f.last_exception.w_value return space.w_None def fget_f_exc_traceback(space, self): if self.last_exception is not None: - f = self.f_back() + f = self.f_backref() while f is not None and f.last_exception is None: - f = f.f_back() + f = f.f_backref() if f is not None: return space.wrap(f.last_exception.application_traceback) return space.w_None Modified: pypy/trunk/pypy/interpreter/pytraceback.py ============================================================================== --- pypy/trunk/pypy/interpreter/pytraceback.py (original) +++ pypy/trunk/pypy/interpreter/pytraceback.py Mon Jan 4 18:41:45 2010 @@ -49,7 +49,6 @@ self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) def record_application_traceback(space, operror, frame, last_instruction): - frame.force_f_back() if frame.pycode.hidden_applevel: return tb = operror.application_traceback Modified: pypy/trunk/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/test/test_executioncontext.py Mon Jan 4 18:41:45 2010 @@ -1,6 +1,5 @@ import py from pypy.interpreter import executioncontext -from pypy.interpreter.executioncontext import ExecutionContext from pypy.conftest import gettestobjspace class Finished(Exception): @@ -220,542 +219,3 @@ """) events = space.unwrap(w_events) assert [i[0] for i in events] == ['c_call', 'c_return', 'c_call'] - - - -class TestFrameChaining(object): - class EC(ExecutionContext): - _some_frame = None - def __init__(self, jitted=False): - self.jitted = jitted - self.virtualizable = None - self.framestackdepth = 0 - self._init_frame_chain() - - def _we_are_jitted(self): - return self.jitted - - def _get_some_frame(self): - if self._some_frame: - self._some_frame.look_at() - return self._some_frame - def _set_some_frame(self, frame): - if frame is not None: - frame.force() - self._some_frame = frame - some_frame = property(_get_some_frame, _set_some_frame) - - class Frame(object): - _f_back_some = None - _f_forward = None - - def __init__(self, ec, virtual_with_base_frame=None): - self.ec = ec - self.virtual_with_base_frame = virtual_with_base_frame - self.escaped = not virtual_with_base_frame - ExecutionContext._init_chaining_attributes(self) - - def f_back(self): - return ExecutionContext._extract_back_from_frame(self) - - def force_f_back(self): - return ExecutionContext._force_back_of_frame(self) - - def force(self): - if not self.escaped: - self.virtual_with_base_frame = None - self.escaped = True - if self._f_back_some: - self._f_back_some.force() - if self._f_forward: - self._f_back_some.force() - - def look_at(self): - if (not self.ec.jitted or - self.ec.virtualizable is not self.virtual_with_base_frame): - self.force() - - def store_ref_to(self, other): - if (other.virtual_with_base_frame is not self and - other.virtual_with_base_frame is not self.virtual_with_base_frame): - other.force() - - def _get_f_back_some(self): - self.look_at() - return self._f_back_some - def _set_f_back_some(self, frame): - self.look_at() - if frame: - frame.look_at() - self.store_ref_to(frame) - self._f_back_some = frame - f_back_some = property(_get_f_back_some, _set_f_back_some) - - def _get_f_forward(self): - self.look_at() - return self._f_forward - def _set_f_forward(self, frame): - self.look_at() - if frame: - frame.look_at() - self.store_ref_to(frame) - self._f_forward = frame - f_forward = property(_get_f_forward, _set_f_forward) - - def test_f_back_no_jit(self): - ec = self.EC() - frame = self.Frame(ec) - frame2 = self.Frame(ec) - frame2.f_back_some = frame - - frame3 = self.Frame(ec) - frame3.f_back_some = frame2 - - assert frame3.f_back() is frame2 - assert frame2.f_back() is frame - assert frame.f_back() is None - - def test_f_back_jit(self): - ec = self.EC() - frame = self.Frame(ec) # real frame - frame2 = self.Frame(ec) # virtual frame - frame2.f_back_some = frame - frame.f_forward = frame2 - - frame3 = self.Frame(ec) # virtual frame - frame3.f_back_some = frame - frame2.f_forward = frame3 - - assert frame3.f_back() is frame2 - assert frame2.f_back() is frame - assert frame.f_back() is None - - frame4 = self.Frame(ec) # real frame again - frame4.f_back_some = frame - assert frame4.f_back() is frame3 - - def test_gettopframe_no_jit(self): - ec = self.EC() - frame = self.Frame(ec) - ec.some_frame = frame - assert ec.gettopframe() is frame - - def test_gettopframe_jit(self): - ec = self.EC() - frame = self.Frame(ec) # real frame - ec.some_frame = frame - assert ec.gettopframe() is frame - - frame2 = self.Frame(ec) # virtual frame - frame2.f_back_some = frame - frame.f_forward = frame2 - assert ec.gettopframe() is frame2 - - frame3 = self.Frame(ec) # virtual frame - frame3.f_back_some = frame - frame2.f_forward = frame3 - assert ec.gettopframe() is frame3 - - frame4 = self.Frame(ec) # real frame again - frame4.f_back_some = frame - ec.some_frame = frame4 - assert ec.gettopframe() is frame4 - - def test_frame_chain(self): - - ec = self.EC() - - assert ec.some_frame is None - assert ec.framestackdepth == 0 - - frame = self.Frame(ec) - ec._chain(frame) - assert ec.some_frame is frame - assert ec.framestackdepth == 1 - assert frame.f_back_some is None - assert frame.f_forward is None - assert ec.gettopframe() is frame - assert ec._extract_back_from_frame(frame) is None - - frame2 = self.Frame(ec) - ec._chain(frame2) - assert ec.some_frame is frame2 - assert ec.framestackdepth == 2 - assert frame2.f_back_some is frame - assert frame.f_forward is None - assert frame2.f_forward is None - assert ec.gettopframe() is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - frame3 = self.Frame(ec) - ec._chain(frame3) - assert ec.some_frame is frame3 - assert frame3.f_back_some is frame2 - assert frame2.f_forward is None - assert ec.gettopframe() is frame3 - assert ec._extract_back_from_frame(frame3) is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - assert frame3.f_back() is frame2 - ec._unchain(frame3) - assert ec.some_frame is frame2 - assert ec.framestackdepth == 2 - assert frame2.f_forward is None - assert frame3.f_back_some is frame2 - assert ec.gettopframe() is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - assert frame2.f_back() is frame - ec._unchain(frame2) - assert ec.some_frame is frame - assert ec.framestackdepth == 1 - assert frame.f_forward is None - assert frame2.f_back_some is frame - assert ec.gettopframe() is frame - assert ec._extract_back_from_frame(frame) is None - - assert frame.f_back() is None - ec._unchain(frame) - assert ec.some_frame is None - assert ec.framestackdepth == 0 - assert frame.f_back_some is None - assert ec.gettopframe() is None - - def test_frame_chain_forced(self): - - ec = self.EC() - - frame = self.Frame(ec) - ec._chain(frame) - assert ec.gettopframe() is frame - assert ec._extract_back_from_frame(frame) is None - - frame2 = self.Frame(ec) - ec._chain(frame2) - assert ec.some_frame is frame2 - assert ec.framestackdepth == 2 - assert frame2.f_back_some is frame - assert frame.f_forward is None - assert frame2.f_forward is None - res = frame2.force_f_back() - assert res is frame - assert frame.f_back_forced - assert ec.gettopframe() is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - frame3 = self.Frame(ec) - ec._chain(frame3) - assert ec.gettopframe() is frame3 - assert ec._extract_back_from_frame(frame3) is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - assert frame3.f_back() is frame2 - ec._unchain(frame3) - assert ec.some_frame is frame2 - assert frame3.f_back_some is frame2 - assert ec.gettopframe() is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - assert frame2.f_back() is frame - ec._unchain(frame2) - assert frame2.f_back_some is frame - assert ec.gettopframe() is frame - assert ec._extract_back_from_frame(frame) is None - - assert frame.f_back() is None - ec._unchain(frame) - assert ec.some_frame is None - assert frame.f_back_some is None - - assert frame2.f_back() is frame - assert frame.f_back() is None - assert ec.gettopframe() is None - - - def test_frame_chain_jitted(self): - - ec = self.EC() - - assert ec.some_frame is None - assert ec.framestackdepth == 0 - assert ec.gettopframe() is None - - frame = self.Frame(ec) - ec._chain(frame) - assert ec.some_frame is frame - assert ec.framestackdepth == 1 - assert frame.f_back_some is None - assert frame.f_forward is None - assert ec.gettopframe() is frame - assert ec._extract_back_from_frame(frame) is None - - ec.jitted = True - ec.virtualizable = frame - frame2 = self.Frame(ec, frame) - ec._chain(frame2) - assert ec.some_frame is frame - assert ec.framestackdepth == 2 - assert frame2.f_back_some is frame - assert frame.f_forward is frame2 - assert frame2.f_forward is None - assert ec.gettopframe() is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - # recursive enter/leave seen by the jit - frame3 = self.Frame(ec, frame) - ec._chain(frame3) - assert ec.some_frame is frame - assert frame3.f_back_some is frame - assert frame2.f_forward is frame3 - assert ec.gettopframe() is frame3 - assert ec._extract_back_from_frame(frame3) is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - assert frame3.f_back() is frame2 - ec._unchain(frame3) - assert ec.some_frame is frame - assert ec.framestackdepth == 2 - assert frame2.f_forward is None - assert frame3.f_back_some is frame - assert not frame3.escaped - assert not frame2.escaped - assert ec.gettopframe() is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - # recursive enter/leave not seen by the jit - ec.jitted = False - ec.virtualizable = None - ec._chain(frame3) - assert not frame2.escaped - assert ec.some_frame is frame3 - assert frame3.f_back_some is frame - assert frame2.f_forward is None - assert frame3.escaped - assert ec.gettopframe() is frame3 - assert ec._extract_back_from_frame(frame3) is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - assert frame3.f_back() is frame2 - ec._unchain(frame3) - assert ec.some_frame is frame - assert ec.framestackdepth == 2 - assert frame2.f_forward is None - assert frame3.f_back_some is frame - assert ec.gettopframe() is frame2 - assert ec._extract_back_from_frame(frame2) is frame - assert ec._extract_back_from_frame(frame) is None - - ec.jitted = True - ec.virtualizable = frame - - assert frame2.f_back() is frame - ec._unchain(frame2) - assert ec.some_frame is frame - assert ec.framestackdepth == 1 - assert frame.f_forward is None - assert frame2.f_back_some is frame - assert ec.gettopframe() is frame - assert ec._extract_back_from_frame(frame) is None - - ec.jitted = False - assert frame.f_back() is None - ec._unchain(frame) - assert ec.some_frame is None - assert ec.framestackdepth == 0 - assert frame.f_back_some is None - assert ec.gettopframe() is None - - @py.test.mark.xfail - def test_frame_chain_jitted_forced(self): - - ec = self.EC() - - assert ec.some_frame is None - assert ec.framestackdepth == 0 - - frame = self.Frame(ec) - ec._chain(frame) - - ec.jitted = True - frame2 = self.Frame(ec) - ec._chain(frame2) - - # recursive enter/leave seen by the jit - frame3 = self.Frame(ec) - ec._chain(frame3) - assert ec.gettopframe() is frame3 - res = frame3.force_f_back() - assert res is frame2 - assert ec.gettopframe() is frame3 - - assert frame3.f_back() is frame2 - ec._unchain(frame3) - - assert frame2.f_back() is frame - ec._unchain(frame2) - ec.jitted = False - assert frame.f_back() is None - ec._unchain(frame) - - assert frame3.f_back() is frame2 - assert frame2.f_back() is frame - assert frame.f_back() is None - - def enter_two_jitted_levels(self): - ec = self.EC() - - assert ec.some_frame is None - assert ec.framestackdepth == 0 - - frame = self.Frame(ec) - ec._chain(frame) - - ec.jitted = True - ec.virtualizable = frame - frame2 = self.Frame(ec, frame) - ec._chain(frame2) - assert not frame2.escaped - return ec, frame, frame2 - - def leave_two_jitted_levels(self, ec, frame, frame2): - assert frame2.f_back() is frame - ec._unchain(frame2) - ec.jitted = False - assert frame.f_back() is None - ec._unchain(frame) - - - def test_check_escaping_all_inlined(self): - ec, frame, frame2 = self.enter_two_jitted_levels() - - # recursive enter/leave seen by the jit - frame3 = self.Frame(ec, frame) - ec._chain(frame3) - assert not frame2.escaped - assert not frame3.escaped - - assert frame3.f_back() is frame2 - ec._unchain(frame3) - assert not frame2.escaped - self.leave_two_jitted_levels(ec, frame, frame2) - - - def test_check_escaping_not_all_inlined_enter_leave_not_seen(self): - ec, frame, frame2 = self.enter_two_jitted_levels() - - ec.jitted = False - # recursive enter/leave not seen by the jit - frame3 = self.Frame(ec) - ec._chain(frame3) - - assert not frame2.escaped - assert frame3.escaped - - ec._unchain(frame3) - ec.jitted = True - assert not frame2.escaped - - self.leave_two_jitted_levels(ec, frame, frame2) - - def test_check_escaping_not_all_inlined_enter_leave_seen(self): - ec, frame, frame2 = self.enter_two_jitted_levels() - - # recursive enter/leave seen by the jit - frame3 = self.Frame(ec, frame) - ec._chain(frame3) - ExecutionContext._jit_rechain_frame(ec, frame3) - ec.jitted = False - frame3.look_at() - assert not frame2.escaped - assert frame3.escaped - - ec.jitted = True - assert frame3.f_back() is frame2 - ec._unchain(frame3) - assert not frame2.escaped - - self.leave_two_jitted_levels(ec, frame, frame2) - - - def test_check_escaping_multi_non_jitted_levels(self): - ec, frame, frame2 = self.enter_two_jitted_levels() - - # recursive enter/leave seen by the jit - frame3 = self.Frame(ec, frame) - ec._chain(frame3) - ExecutionContext._jit_rechain_frame(ec, frame3) - ec.jitted = False - - assert frame3.escaped - assert not frame2.escaped - assert frame3.escaped - - frame4 = self.Frame(ec) - ec._chain(frame4) - assert ec.framestackdepth == 4 - - ec._unchain(frame4) - assert frame3.escaped - assert not frame2.escaped - - ec.jitted = True - assert frame3.f_back() is frame2 - ec._unchain(frame3) - assert not frame2.escaped - - self.leave_two_jitted_levels(ec, frame, frame2) - - def test_check_escaping_jitted_with_two_different_virtualizables(self): - ec, frame, frame2 = self.enter_two_jitted_levels() - - frame3 = self.Frame(ec, frame) - ec._chain(frame3) - # frame3 is not inlined, but contains a loop itself, for which code has - # been generated - ExecutionContext._jit_rechain_frame(ec, frame3) - ec.virtualizable = frame3 - - frame3.look_at() - assert not frame2.escaped - assert frame3.escaped - - frame4 = self.Frame(ec, frame3) - ec._chain(frame4) - assert ec.framestackdepth == 4 - assert not frame4.escaped - - ec._unchain(frame4) - assert frame3.escaped - assert not frame2.escaped - - ec.virtualizable = frame - - ec._unchain(frame3) - assert not frame2.escaped - - def test_frame_top_is_virtualizable(self): - ec, frame, frame2 = self.enter_two_jitted_levels() - frame3 = self.Frame(ec, frame2) - ec.jitted = False - ec._chain(frame3) - ec.gettopframe() - frame3.force_f_back() - ec._unchain(frame3) - assert not frame2.f_forward - assert ec.gettopframe() is frame2 - ec.jitted = True - ec._unchain(frame2) - assert not frame.f_forward - assert ec.gettopframe() is frame - ec._unchain(frame) - assert ec.gettopframe() is None Modified: pypy/trunk/pypy/interpreter/test/test_zzpickle_and_slow.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_zzpickle_and_slow.py (original) +++ pypy/trunk/pypy/interpreter/test/test_zzpickle_and_slow.py Mon Jan 4 18:41:45 2010 @@ -2,6 +2,7 @@ from pypy import conftest from pypy.conftest import gettestobjspace from pypy.interpreter import gateway +from pypy.rlib.jit import non_virtual_ref, vref_None class AppTestSlow: def setup_class(cls): @@ -30,21 +31,18 @@ from pypy.interpreter import pytraceback def hide_top_frame(space, w_frame): w_last = None - while w_frame.f_back(): - # should have been forced by traceback capturing - assert w_frame.f_back_forced + while w_frame.f_backref(): w_last = w_frame - w_frame = w_frame.f_back() + w_frame = w_frame.f_backref() assert w_last - w_saved = w_last.f_back() - w_last.f_back_some = None + w_saved = w_last.f_backref() + w_last.f_backref = vref_None return w_saved def restore_top_frame(space, w_frame, w_saved): - while w_frame.f_back(): - assert w_frame.f_back_forced - w_frame = w_frame.f_back() - w_frame.f_back_some = w_saved + while w_frame.f_backref(): + w_frame = w_frame.f_backref() + w_frame.f_backref = non_virtual_ref(w_saved) def read_exc_type(space, w_frame): if w_frame.last_exception is None: Modified: pypy/trunk/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/trunk/pypy/jit/backend/llgraph/llimpl.py Mon Jan 4 18:41:45 2010 @@ -152,7 +152,9 @@ 'debug_merge_point': (('ref',), None), 'force_token' : ((), 'int'), 'call_may_force' : (('int', 'varargs'), 'intorptr'), - 'guard_not_forced': ((), None) + 'guard_not_forced': ((), None), + 'virtual_ref' : (('ref', 'int'), 'ref'), + 'virtual_ref_finish': (('ref', 'ref'), None), #'getitem' : (('void', 'ref', 'int'), 'int'), #'setitem' : (('void', 'ref', 'int', 'int'), None), #'newlist' : (('void', 'varargs'), 'ref'), @@ -813,6 +815,12 @@ if forced: raise GuardFailed + def op_virtual_ref(self, _, virtual, index): + return virtual + + def op_virtual_ref_finish(self, _, vref, virtual): + pass + class OOFrame(Frame): Modified: pypy/trunk/pypy/jit/backend/model.py ============================================================================== --- pypy/trunk/pypy/jit/backend/model.py (original) +++ pypy/trunk/pypy/jit/backend/model.py Mon Jan 4 18:41:45 2010 @@ -219,10 +219,6 @@ def do_cast_ptr_to_int(self, ptrbox): raise NotImplementedError - def do_force_token(self): - # this should not be implemented at all by the backends - raise NotImplementedError - def do_call_may_force(self, args, calldescr): return self.do_call(args, calldescr) Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/runner_test.py (original) +++ pypy/trunk/pypy/jit/backend/test/runner_test.py Mon Jan 4 18:41:45 2010 @@ -803,6 +803,19 @@ r = self.execute_operation(rop.SAME_AS, [BoxFloat(5.5)], 'float') assert r.value == 5.5 + def test_virtual_ref(self): + # if VIRTUAL_REF reaches the backend, it should just be a SAME_AS + u_box = self.alloc_unicode(u"hello\u1234") + r = self.execute_operation(rop.VIRTUAL_REF, [u_box, ConstInt(2)], + 'ref') + assert r.value == u_box.value + + def test_virtual_ref_finish(self): + # if VIRTUAL_REF_FINISH reaches the backend, it is a no-op + self.execute_operation(rop.VIRTUAL_REF_FINISH, + [BoxInt(123), BoxInt(234)], + 'void') + def test_jump(self): # this test generates small loops where the JUMP passes many # arguments of various types, shuffling them around. Modified: pypy/trunk/pypy/jit/backend/test/support.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/support.py (original) +++ pypy/trunk/pypy/jit/backend/test/support.py Mon Jan 4 18:41:45 2010 @@ -100,6 +100,9 @@ def check_aborted_count(self, *args, **kwds): pass + def check_aborted_count_at_least(self, *args, **kwds): + pass + def interp_operations(self, *args, **kwds): py.test.skip("interp_operations test skipped") Modified: pypy/trunk/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/test_random.py (original) +++ pypy/trunk/pypy/jit/backend/test/test_random.py Mon Jan 4 18:41:45 2010 @@ -431,10 +431,11 @@ for _op in [rop.FLOAT_NEG, rop.FLOAT_ABS, - rop.FLOAT_IS_TRUE, ]: OPERATIONS.append(UnaryFloatOperation(_op)) +OPERATIONS.append(UnaryFloatOperation(rop.FLOAT_IS_TRUE, boolres=True)) + OPERATIONS.append(CastFloatToIntOperation(rop.CAST_FLOAT_TO_INT)) OPERATIONS.append(CastIntToFloatOperation(rop.CAST_INT_TO_FLOAT)) Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Mon Jan 4 18:41:45 2010 @@ -368,19 +368,18 @@ def genop_cmp(self, op, arglocs, result_loc): if isinstance(op.args[0], Const): self.mc.CMP(arglocs[1], arglocs[0]) - self.mc.MOV(result_loc, imm8(0)) getattr(self.mc, 'SET' + rev_cond)(lower_byte(result_loc)) else: self.mc.CMP(arglocs[0], arglocs[1]) - self.mc.MOV(result_loc, imm8(0)) getattr(self.mc, 'SET' + cond)(lower_byte(result_loc)) + self.mc.MOVZX(result_loc, lower_byte(result_loc)) return genop_cmp def _cmpop_float(cond): def genop_cmp(self, op, arglocs, result_loc): self.mc.UCOMISD(arglocs[0], arglocs[1]) - self.mc.MOV(result_loc, imm8(0)) getattr(self.mc, 'SET' + cond)(lower_byte(result_loc)) + self.mc.MOVZX(result_loc, lower_byte(result_loc)) return genop_cmp def _cmpop_guard(cond, rev_cond, false_cond, false_rev_cond): @@ -404,6 +403,19 @@ return self.implement_guard(addr, getattr(self.mc, name)) return genop_cmp_guard + def _cmpop_guard_float(cond, false_cond): + def genop_cmp_guard_float(self, op, guard_op, addr, arglocs, + result_loc): + guard_opnum = guard_op.opnum + self.mc.UCOMISD(arglocs[0], arglocs[1]) + if guard_opnum == rop.GUARD_FALSE: + name = 'J' + cond + return self.implement_guard(addr, getattr(self.mc, name)) + else: + name = 'J' + false_cond + return self.implement_guard(addr, getattr(self.mc, name)) + return genop_cmp_guard_float + def _emit_call(self, x, arglocs, start=0, tmp=eax): p = 0 n = len(arglocs) @@ -454,11 +466,11 @@ genop_int_lt = _cmpop("L", "G") genop_int_le = _cmpop("LE", "GE") genop_int_eq = _cmpop("E", "E") - genop_oois = genop_int_eq genop_int_ne = _cmpop("NE", "NE") - genop_ooisnot = genop_int_ne genop_int_gt = _cmpop("G", "L") genop_int_ge = _cmpop("GE", "LE") + genop_oois = genop_int_eq + genop_ooisnot = genop_int_ne genop_float_lt = _cmpop_float('B') genop_float_le = _cmpop_float('BE') @@ -478,12 +490,21 @@ genop_guard_int_ne = _cmpop_guard("NE", "NE", "E", "E") genop_guard_int_gt = _cmpop_guard("G", "L", "LE", "GE") genop_guard_int_ge = _cmpop_guard("GE", "LE", "L", "G") + genop_guard_oois = genop_guard_int_eq + genop_guard_ooisnot = genop_guard_int_ne genop_guard_uint_gt = _cmpop_guard("A", "B", "BE", "AE") genop_guard_uint_lt = _cmpop_guard("B", "A", "AE", "BE") genop_guard_uint_le = _cmpop_guard("BE", "AE", "A", "B") genop_guard_uint_ge = _cmpop_guard("AE", "BE", "B", "A") + genop_guard_float_lt = _cmpop_guard_float("B", "AE") + genop_guard_float_le = _cmpop_guard_float("BE", "A") + genop_guard_float_eq = _cmpop_guard_float("E", "NE") + genop_guard_float_ne = _cmpop_guard_float("NE", "E") + genop_guard_float_gt = _cmpop_guard_float("A", "BE") + genop_guard_float_ge = _cmpop_guard_float("AE", "B") + def genop_float_neg(self, op, arglocs, resloc): # Following what gcc does: res = x ^ 0x8000000000000000 self.mc.XORPD(arglocs[0], self.loc_float_const_neg) @@ -492,6 +513,16 @@ # Following what gcc does: res = x & 0x7FFFFFFFFFFFFFFF self.mc.ANDPD(arglocs[0], self.loc_float_const_abs) + def genop_guard_float_is_true(self, op, guard_op, addr, arglocs, resloc): + guard_opnum = guard_op.opnum + loc0, loc1 = arglocs + self.mc.XORPD(loc0, loc0) + self.mc.UCOMISD(loc0, loc1) + if guard_opnum == rop.GUARD_TRUE: + return self.implement_guard(addr, self.mc.JZ) + else: + return self.implement_guard(addr, self.mc.JNZ) + def genop_float_is_true(self, op, arglocs, resloc): loc0, loc1 = arglocs self.mc.XORPD(loc0, loc0) @@ -505,9 +536,6 @@ def genop_cast_int_to_float(self, op, arglocs, resloc): self.mc.CVTSI2SD(resloc, arglocs[0]) - def genop_bool_not(self, op, arglocs, resloc): - self.mc.XOR(arglocs[0], imm8(1)) - def genop_int_lshift(self, op, arglocs, resloc): loc, loc2 = arglocs if loc2 is ecx: @@ -528,8 +556,7 @@ def genop_guard_int_is_true(self, op, guard_op, addr, arglocs, resloc): guard_opnum = guard_op.opnum - loc = arglocs[0] - self.mc.TEST(loc, loc) + self.mc.CMP(arglocs[0], imm8(0)) if guard_opnum == rop.GUARD_TRUE: return self.implement_guard(addr, self.mc.JZ) else: @@ -537,12 +564,24 @@ def genop_int_is_true(self, op, arglocs, resloc): self.mc.CMP(arglocs[0], imm8(0)) - self.mc.MOV(resloc, imm8(0)) self.mc.SETNE(lower_byte(resloc)) + self.mc.MOVZX(resloc, lower_byte(resloc)) + + def genop_guard_bool_not(self, op, guard_op, addr, arglocs, resloc): + guard_opnum = guard_op.opnum + self.mc.CMP(arglocs[0], imm8(0)) + if guard_opnum == rop.GUARD_TRUE: + return self.implement_guard(addr, self.mc.JNZ) + else: + return self.implement_guard(addr, self.mc.JZ) + + def genop_bool_not(self, op, arglocs, resloc): + self.mc.XOR(arglocs[0], imm8(1)) def genop_same_as(self, op, arglocs, resloc): self.mov(arglocs[0], resloc) genop_cast_ptr_to_int = genop_same_as + genop_virtual_ref = genop_same_as def genop_int_mod(self, op, arglocs, resloc): self.mc.CDQ() Modified: pypy/trunk/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/trunk/pypy/jit/backend/x86/regalloc.py Mon Jan 4 18:41:45 2010 @@ -345,10 +345,10 @@ self.possibly_free_vars(op.args) continue if self.can_merge_with_next_guard(op, i, operations): - oplist[op.opnum](self, op, operations[i + 1]) + oplist_with_guard[op.opnum](self, op, operations[i + 1]) i += 1 else: - oplist[op.opnum](self, op, None) + oplist[op.opnum](self, op) if op.result is not None: self.possibly_free_var(op.result) self.rm._check_invariants() @@ -397,7 +397,7 @@ return self.xrm.loc(v) return self.rm.loc(v) - def _consider_guard(self, op, ignored): + def _consider_guard(self, op): loc = self.rm.make_sure_var_in_reg(op.args[0]) self.perform_guard(op, [loc], None) self.rm.possibly_free_var(op.args[0]) @@ -407,7 +407,7 @@ consider_guard_nonnull = _consider_guard consider_guard_isnull = _consider_guard - def consider_finish(self, op, ignored): + def consider_finish(self, op): locs = [self.loc(v) for v in op.args] locs_are_ref = [v.type == REF for v in op.args] fail_index = self.assembler.cpu.get_fail_descr_number(op.descr) @@ -415,10 +415,10 @@ self.exc, locs_are_ref) self.possibly_free_vars(op.args) - def consider_guard_no_exception(self, op, ignored): + def consider_guard_no_exception(self, op): self.perform_guard(op, [], None) - def consider_guard_exception(self, op, ignored): + def consider_guard_exception(self, op): loc = self.rm.make_sure_var_in_reg(op.args[0]) box = TempBox() loc1 = self.rm.force_allocate_reg(box, op.args) @@ -434,13 +434,13 @@ consider_guard_no_overflow = consider_guard_no_exception consider_guard_overflow = consider_guard_no_exception - def consider_guard_value(self, op, ignored): + def consider_guard_value(self, op): x = self.make_sure_var_in_reg(op.args[0]) y = self.loc(op.args[1]) self.perform_guard(op, [x, y], None) self.possibly_free_vars(op.args) - def consider_guard_class(self, op, ignored): + def consider_guard_class(self, op): assert isinstance(op.args[0], Box) x = self.rm.make_sure_var_in_reg(op.args[0]) y = self.loc(op.args[1]) @@ -449,15 +449,15 @@ consider_guard_nonnull_class = consider_guard_class - def _consider_binop_part(self, op, ignored): + def _consider_binop_part(self, op): x = op.args[0] argloc = self.loc(op.args[1]) loc = self.rm.force_result_in_reg(op.result, x, op.args) self.rm.possibly_free_var(op.args[1]) return loc, argloc - def _consider_binop(self, op, ignored): - loc, argloc = self._consider_binop_part(op, ignored) + def _consider_binop(self, op): + loc, argloc = self._consider_binop_part(op) self.Perform(op, [loc, argloc], loc) consider_int_add = _consider_binop @@ -471,14 +471,13 @@ consider_int_sub_ovf = _consider_binop consider_int_add_ovf = _consider_binop - def consider_int_neg(self, op, ignored): + def consider_int_neg(self, op): res = self.rm.force_result_in_reg(op.result, op.args[0]) self.Perform(op, [res], res) consider_int_invert = consider_int_neg - consider_bool_not = consider_int_neg - def consider_int_lshift(self, op, ignored): + def consider_int_lshift(self, op): if isinstance(op.args[1], Const): loc2 = self.rm.convert_to_imm(op.args[1]) else: @@ -504,11 +503,11 @@ self.rm.possibly_free_vars(op.args) self.rm.possibly_free_var(tmpvar) - def consider_int_mod(self, op, ignored): + def consider_int_mod(self, op): self._consider_int_div_or_mod(op, edx, eax) self.Perform(op, [eax, ecx], edx) - def consider_int_floordiv(self, op, ignored): + def consider_int_floordiv(self, op): self._consider_int_div_or_mod(op, eax, edx) self.Perform(op, [eax, ecx], eax) @@ -542,7 +541,7 @@ consider_oois = _consider_compop consider_ooisnot = _consider_compop - def _consider_float_op(self, op, ignored): + def _consider_float_op(self, op): loc1 = self.xrm.loc(op.args[1]) loc0 = self.xrm.force_result_in_reg(op.result, op.args[0], op.args) self.Perform(op, [loc0, loc1], loc0) @@ -553,15 +552,17 @@ consider_float_mul = _consider_float_op consider_float_truediv = _consider_float_op - def _consider_float_cmp(self, op, ignored): - assert ignored is None - # XXX so far we don't have guards here, but we want them + def _consider_float_cmp(self, op, guard_op): loc0 = self.xrm.make_sure_var_in_reg(op.args[0], op.args, imm_fine=False) loc1 = self.xrm.loc(op.args[1]) - res = self.rm.force_allocate_reg(op.result, need_lower_byte=True) - self.Perform(op, [loc0, loc1], res) - self.xrm.possibly_free_vars(op.args) + arglocs = [loc0, loc1] + self.xrm.possibly_free_vars(op.args) + if guard_op is None: + res = self.rm.force_allocate_reg(op.result, need_lower_byte=True) + self.Perform(op, arglocs, res) + else: + self.perform_with_guard(op, guard_op, arglocs, None) consider_float_lt = _consider_float_cmp consider_float_le = _consider_float_cmp @@ -570,32 +571,37 @@ consider_float_gt = _consider_float_cmp consider_float_ge = _consider_float_cmp - def consider_float_neg(self, op, ignored): + def consider_float_neg(self, op): loc0 = self.xrm.force_result_in_reg(op.result, op.args[0]) self.Perform(op, [loc0], loc0) self.xrm.possibly_free_var(op.args[0]) - def consider_float_abs(self, op, ignored): + def consider_float_abs(self, op): loc0 = self.xrm.force_result_in_reg(op.result, op.args[0]) self.Perform(op, [loc0], loc0) self.xrm.possibly_free_var(op.args[0]) - def consider_float_is_true(self, op, ignored): + def consider_float_is_true(self, op, guard_op): + # doesn't need arg to be in a register tmpbox0 = TempBox() loc0 = self.xrm.force_allocate_reg(tmpbox0) loc1 = self.xrm.loc(op.args[0]) - loc2 = self.rm.force_allocate_reg(op.result, need_lower_byte=True) - self.Perform(op, [loc0, loc1], loc2) + arglocs = [loc0, loc1] self.xrm.possibly_free_var(op.args[0]) self.xrm.possibly_free_var(tmpbox0) + if guard_op is not None: + self.perform_with_guard(op, guard_op, arglocs, None) + else: + loc2 = self.rm.force_allocate_reg(op.result, need_lower_byte=True) + self.Perform(op, arglocs, loc2) - def consider_cast_float_to_int(self, op, ignored): + def consider_cast_float_to_int(self, op): loc0 = self.xrm.make_sure_var_in_reg(op.args[0], imm_fine=False) loc1 = self.rm.force_allocate_reg(op.result) self.Perform(op, [loc0], loc1) self.xrm.possibly_free_var(op.args[0]) - def consider_cast_int_to_float(self, op, ignored): + def consider_cast_int_to_float(self, op): loc0 = self.rm.loc(op.args[0]) loc1 = self.xrm.force_allocate_reg(op.result) self.Perform(op, [loc0], loc1) @@ -625,7 +631,7 @@ self._call(op, [imm(size)] + [self.loc(arg) for arg in op.args], guard_not_forced_op=guard_not_forced_op) - def consider_call(self, op, ignored): + def consider_call(self, op): self._consider_call(op) consider_call_pure = consider_call @@ -633,7 +639,7 @@ assert guard_op is not None self._consider_call(op, guard_op) - def consider_cond_call_gc_wb(self, op, ignored): + def consider_cond_call_gc_wb(self, op): assert op.result is None arglocs = [self.loc(arg) for arg in op.args] # add eax, ecx and edx as extra "arguments" to ensure they are @@ -675,7 +681,7 @@ gc_ll_descr.get_malloc_fixedsize_slowpath_addr(), ) - def consider_new(self, op, ignored): + def consider_new(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.can_inline_malloc(op.descr): self._fastpath_malloc(op, op.descr) @@ -684,7 +690,7 @@ arglocs = [imm(x) for x in args] return self._call(op, arglocs) - def consider_new_with_vtable(self, op, ignored): + def consider_new_with_vtable(self, op): classint = op.args[0].getint() descrsize = self.assembler.cpu.class_sizes[classint] if self.assembler.cpu.gc_ll_descr.can_inline_malloc(descrsize): @@ -697,7 +703,7 @@ arglocs.append(self.loc(op.args[0])) return self._call(op, arglocs) - def consider_newstr(self, op, ignored): + def consider_newstr(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.get_funcptr_for_newstr is not None: # framework GC @@ -709,7 +715,7 @@ return self._malloc_varsize(ofs_items, ofs, 0, op.args[0], op.result) - def consider_newunicode(self, op, ignored): + def consider_newunicode(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.get_funcptr_for_newunicode is not None: # framework GC @@ -747,7 +753,7 @@ self.PerformDiscard(ResOperation(rop.SETFIELD_GC, [], None), [eax, imm(ofs_length), imm(WORD), loc]) - def consider_new_array(self, op, ignored): + def consider_new_array(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.get_funcptr_for_newarray is not None: # framework GC @@ -778,7 +784,7 @@ ptr = fielddescr.is_pointer_field() return imm(ofs), imm(size), ptr - def consider_setfield_gc(self, op, ignored): + def consider_setfield_gc(self, op): ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr) assert isinstance(size_loc, IMM32) if size_loc.value == 1: @@ -793,7 +799,7 @@ consider_setfield_raw = consider_setfield_gc - def consider_strsetitem(self, op, ignored): + def consider_strsetitem(self, op): base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args) value_loc = self.rm.make_sure_var_in_reg(op.args[2], op.args, @@ -803,7 +809,7 @@ consider_unicodesetitem = consider_strsetitem - def consider_setarrayitem_gc(self, op, ignored): + def consider_setarrayitem_gc(self, op): scale, ofs, ptr = self._unpack_arraydescr(op.descr) base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) if scale == 0: @@ -819,7 +825,7 @@ consider_setarrayitem_raw = consider_setarrayitem_gc - def consider_getfield_gc(self, op, ignored): + def consider_getfield_gc(self, op): ofs_loc, size_loc, _ = self._unpack_fielddescr(op.descr) base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) self.rm.possibly_free_vars(op.args) @@ -830,7 +836,7 @@ consider_getfield_raw_pure = consider_getfield_gc consider_getfield_gc_pure = consider_getfield_gc - def consider_getarrayitem_gc(self, op, ignored): + def consider_getarrayitem_gc(self, op): scale, ofs, _ = self._unpack_arraydescr(op.descr) base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args) @@ -840,29 +846,34 @@ consider_getarrayitem_gc_pure = consider_getarrayitem_gc - - def _consider_nullity(self, op, guard_op): - # doesn't need a register in arg + def consider_int_is_true(self, op, guard_op): + # doesn't need arg to be in a register + argloc = self.loc(op.args[0]) + self.rm.possibly_free_var(op.args[0]) if guard_op is not None: - argloc = self.rm.make_sure_var_in_reg(op.args[0]) - self.rm.possibly_free_var(op.args[0]) self.perform_with_guard(op, guard_op, [argloc], None) else: - argloc = self.loc(op.args[0]) - self.rm.possibly_free_var(op.args[0]) resloc = self.rm.force_allocate_reg(op.result, need_lower_byte=True) self.Perform(op, [argloc], resloc) - consider_int_is_true = _consider_nullity + def consider_bool_not(self, op, guard_op): + if guard_op is not None: + # doesn't need arg to be in a register + argloc = self.loc(op.args[0]) + self.rm.possibly_free_var(op.args[0]) + self.perform_with_guard(op, guard_op, [argloc], None) + else: + self.consider_int_neg(op) - def consider_same_as(self, op, ignored): + def consider_same_as(self, op): argloc = self.loc(op.args[0]) self.possibly_free_var(op.args[0]) resloc = self.force_allocate_reg(op.result) self.Perform(op, [argloc], resloc) consider_cast_ptr_to_int = consider_same_as + consider_virtual_ref = consider_same_as - def consider_strlen(self, op, ignored): + def consider_strlen(self, op): base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) self.rm.possibly_free_vars(op.args) result_loc = self.rm.force_allocate_reg(op.result) @@ -870,7 +881,7 @@ consider_unicodelen = consider_strlen - def consider_arraylen_gc(self, op, ignored): + def consider_arraylen_gc(self, op): arraydescr = op.descr assert isinstance(arraydescr, BaseArrayDescr) ofs = arraydescr.get_ofs_length(self.translate_support_code) @@ -879,7 +890,7 @@ result_loc = self.rm.force_allocate_reg(op.result) self.Perform(op, [base_loc, imm(ofs)], result_loc) - def consider_strgetitem(self, op, ignored): + def consider_strgetitem(self, op): base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args) self.rm.possibly_free_vars(op.args) @@ -888,7 +899,7 @@ consider_unicodegetitem = consider_strgetitem - def consider_jump(self, op, ignored): + def consider_jump(self, op): assembler = self.assembler assert self.jump_target_descr is None descr = op.descr @@ -916,9 +927,12 @@ self.possibly_free_vars(op.args) assembler.closing_jump(self.jump_target_descr) - def consider_debug_merge_point(self, op, ignored): + def consider_debug_merge_point(self, op): pass + def consider_virtual_ref_finish(self, op): + self.possibly_free_vars(op.args) + def get_mark_gc_roots(self, gcrootmap): shape = gcrootmap.get_basic_shape() for v, val in self.fm.frame_bindings.items(): @@ -937,22 +951,37 @@ assert reg is eax # ok to ignore this one return gcrootmap.compress_callshape(shape) - def consider_force_token(self, op, ignored): + def consider_force_token(self, op): loc = self.rm.force_allocate_reg(op.result) self.Perform(op, [], loc) - def not_implemented_op(self, op, ignored): + def not_implemented_op(self, op): msg = "[regalloc] Not implemented operation: %s" % op.getopname() print msg raise NotImplementedError(msg) + def not_implemented_op_with_guard(self, op, guard_op): + msg = "[regalloc] Not implemented operation with guard: %s" % ( + op.getopname(),) + print msg + raise NotImplementedError(msg) + oplist = [RegAlloc.not_implemented_op] * rop._LAST +oplist_with_guard = [RegAlloc.not_implemented_op_with_guard] * rop._LAST + +def add_none_argument(fn): + return lambda self, op: fn(self, op, None) for name, value in RegAlloc.__dict__.iteritems(): if name.startswith('consider_'): name = name[len('consider_'):] num = getattr(rop, name.upper()) - oplist[num] = value + if (ResOperation(num, [], None).is_comparison() + or num == rop.CALL_MAY_FORCE): + oplist_with_guard[num] = value + oplist[num] = add_none_argument(value) + else: + oplist[num] = value def get_ebp_ofs(position): # Argument is a frame position (0, 1, 2...). Modified: pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py Mon Jan 4 18:41:45 2010 @@ -78,7 +78,7 @@ box = boxes[0] regalloc.position = 0 regalloc.consider_call(ResOperation(rop.CALL, [box], BoxInt(), - calldescr), None) + calldescr)) assert len(regalloc.assembler.movs) == 3 # mark = regalloc.get_mark_gc_roots(cpu.gc_ll_descr.gcrootmap) Modified: pypy/trunk/pypy/jit/backend/x86/test/test_tlc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_tlc.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_tlc.py Mon Jan 4 18:41:45 2010 @@ -1,6 +1,5 @@ import py -py.test.skip("Widening to trash error") from pypy.jit.backend.x86.test.test_basic import Jit386Mixin from pypy.jit.metainterp.test.test_tlc import TLCTests from pypy.jit.tl import tlc @@ -10,6 +9,7 @@ # ====> ../../test/test_tlc.py def test_accumulator(self): + py.test.skip("investigate, maybe") path = py.path.local(tlc.__file__).dirpath('accumulator.tlc.src') code = path.read() res = self.exec_code(code, 20) @@ -18,6 +18,7 @@ assert res == 10 def test_fib(self): + py.test.skip("investigate, maybe") path = py.path.local(tlc.__file__).dirpath('fibo.tlc.src') code = path.read() res = self.exec_code(code, 7) Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/codewriter.py Mon Jan 4 18:41:45 2010 @@ -1158,16 +1158,17 @@ self.var_position(op.args[3])) def serialize_op_jit_marker(self, op): - if op.args[0].value == 'jit_merge_point': - assert self.portal, "jit_merge_point in non-main graph!" - self.emit('jit_merge_point') - assert ([self.var_position(i) for i in op.args[2:]] == - range(0, 2*(len(op.args) - 2), 2)) - #for i in range(2, len(op.args)): - # arg = op.args[i] - # self._eventualy_builtin(arg) - elif op.args[0].value == 'can_enter_jit': - self.emit('can_enter_jit') + key = op.args[0].value + getattr(self, 'handle_jit_marker__%s' % key)(op) + + def handle_jit_marker__jit_merge_point(self, op): + assert self.portal, "jit_merge_point in non-main graph!" + self.emit('jit_merge_point') + assert ([self.var_position(i) for i in op.args[2:]] == + range(0, 2*(len(op.args) - 2), 2)) + + def handle_jit_marker__can_enter_jit(self, op): + self.emit('can_enter_jit') def serialize_op_direct_call(self, op): kind = self.codewriter.guess_call_kind(op) @@ -1213,7 +1214,7 @@ if pure and not all_promoted_args: effectinfo = calldescr.get_extra_info() assert (effectinfo is not None and - not effectinfo.promotes_virtualizables) + not effectinfo.forces_virtual_or_virtualizable) try: canraise = self.codewriter.raise_analyzer.can_raise(op) except lltype.DelayedPointer: @@ -1279,6 +1280,9 @@ return self._do_builtin_call(op, oopspec_name, args) def _do_builtin_call(self, op, oopspec_name, args): + if oopspec_name.startswith('virtual_ref'): + self.handle_virtual_ref_call(op, oopspec_name, args) + return argtypes = [v.concretetype for v in args] resulttype = op.result.concretetype c_func, TP = support.builtin_func_for_spec(self.codewriter.rtyper, @@ -1299,6 +1303,15 @@ self.emit_varargs([c_func] + non_void_args) self.register_var(op.result) + def handle_virtual_ref_call(self, op, oopspec_name, args): + self.emit(oopspec_name) # 'virtual_ref' or 'virtual_ref_finish' + self.emit(self.var_position(args[0])) + self.register_var(op.result) + # + vrefinfo = self.codewriter.metainterp_sd.virtualref_info + self.codewriter.register_known_gctype(vrefinfo.jit_virtual_ref_vtable, + vrefinfo.JIT_VIRTUAL_REF) + def _array_of_voids(self, ARRAY): if isinstance(ARRAY, ootype.Array): return ARRAY.ITEM == ootype.Void @@ -1557,12 +1570,15 @@ log.WARNING("found debug_assert in %r; should have be removed" % (self.graph,)) - def serialize_op_promote_virtualizable(self, op): + def serialize_op_jit_force_virtualizable(self, op): vinfo = self.codewriter.metainterp_sd.virtualizable_info assert vinfo is not None assert vinfo.is_vtypeptr(op.args[0].concretetype) self.vable_flags[op.args[0]] = op.args[2].value + def serialize_op_jit_force_virtual(self, op): + self._do_builtin_call(op, 'jit_force_virtual', op.args) + serialize_op_oostring = handle_builtin_call serialize_op_oounicode = handle_builtin_call serialize_op_gc_identityhash = handle_builtin_call Modified: pypy/trunk/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/compile.py (original) +++ pypy/trunk/pypy/jit/metainterp/compile.py Mon Jan 4 18:41:45 2010 @@ -237,23 +237,50 @@ from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) token = metainterp_sd.cpu.get_latest_force_token() - data = self.fetch_data(token) - if data is None: - data = [] - metainterp._already_allocated_resume_virtuals = data + all_virtuals = self.fetch_data(token) + if all_virtuals is None: + all_virtuals = [] + metainterp._already_allocated_resume_virtuals = all_virtuals self.counter = -2 # never compile return metainterp.handle_guard_failure(self) - def force_virtualizable(self, vinfo, virtualizable, force_token): + @staticmethod + def force_now(cpu, token): + # Called during a residual call from the assembler, if the code + # actually needs to force one of the virtualrefs or the virtualizable. + # Implemented by forcing *all* virtualrefs and the virtualizable. + faildescr = cpu.force(token) + assert isinstance(faildescr, ResumeGuardForcedDescr) + faildescr.handle_async_forcing(token) + + def handle_async_forcing(self, force_token): from pypy.jit.metainterp.pyjitpl import MetaInterp from pypy.jit.metainterp.resume import force_from_resumedata - metainterp = MetaInterp(self.metainterp_sd) + # To handle the forcing itself, we create a temporary MetaInterp + # as a convenience to move the various data to its proper place. + metainterp_sd = self.metainterp_sd + metainterp = MetaInterp(metainterp_sd) metainterp.history = None # blackholing - liveboxes = metainterp.cpu.make_boxes_from_latest_values(self) - virtualizable_boxes, data = force_from_resumedata(metainterp, - liveboxes, self) - vinfo.write_boxes(virtualizable, virtualizable_boxes) - self.save_data(force_token, data) + liveboxes = metainterp_sd.cpu.make_boxes_from_latest_values(self) + # + expect_virtualizable = metainterp_sd.virtualizable_info is not None + forced_data = force_from_resumedata(metainterp, liveboxes, self, + expect_virtualizable) + virtualizable_boxes, virtualref_boxes, all_virtuals = forced_data + # + # Handle virtualref_boxes: mark each JIT_VIRTUAL_REF as forced + vrefinfo = metainterp_sd.virtualref_info + for i in range(0, len(virtualref_boxes), 2): + virtualbox = virtualref_boxes[i] + vrefbox = virtualref_boxes[i+1] + vrefinfo.forced_single_vref(vrefbox.getref_base(), + virtualbox.getref_base()) + # Handle virtualizable_boxes: store them on the real virtualizable now + if expect_virtualizable: + metainterp_sd.virtualizable_info.forced_vable(virtualizable_boxes) + # Handle all_virtuals: keep them for later blackholing from the + # future failure of the GUARD_NOT_FORCED + self.save_data(force_token, all_virtuals) def save_data(self, key, value): globaldata = self.metainterp_sd.globaldata Modified: pypy/trunk/pypy/jit/metainterp/effectinfo.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/effectinfo.py (original) +++ pypy/trunk/pypy/jit/metainterp/effectinfo.py Mon Jan 4 18:41:45 2010 @@ -7,23 +7,25 @@ class EffectInfo(object): _cache = {} - def __new__(cls, readonly_descrs_fields, write_descrs_fields, - write_descrs_arrays, promotes_virtualizables=False): + def __new__(cls, readonly_descrs_fields, + write_descrs_fields, write_descrs_arrays, + forces_virtual_or_virtualizable=False): key = (frozenset(readonly_descrs_fields), frozenset(write_descrs_fields), frozenset(write_descrs_arrays), - promotes_virtualizables) + forces_virtual_or_virtualizable) if key in cls._cache: return cls._cache[key] result = object.__new__(cls) result.readonly_descrs_fields = readonly_descrs_fields result.write_descrs_fields = write_descrs_fields result.write_descrs_arrays = write_descrs_arrays - result.promotes_virtualizables = promotes_virtualizables + result.forces_virtual_or_virtualizable= forces_virtual_or_virtualizable cls._cache[key] = result return result -def effectinfo_from_writeanalyze(effects, cpu, promotes_virtualizables=False): +def effectinfo_from_writeanalyze(effects, cpu, + forces_virtual_or_virtualizable=False): from pypy.translator.backendopt.writeanalyze import top_set if effects is top_set: return None @@ -60,7 +62,7 @@ return EffectInfo(readonly_descrs_fields, write_descrs_fields, write_descrs_arrays, - promotes_virtualizables) + forces_virtual_or_virtualizable) def consider_struct(TYPE, fieldname): if fieldType(TYPE, fieldname) is lltype.Void: @@ -89,4 +91,5 @@ class VirtualizableAnalyzer(BoolGraphAnalyzer): def analyze_simple_operation(self, op): - return op.opname == 'promote_virtualizable' + return op.opname in ('jit_force_virtualizable', + 'jit_force_virtual') Modified: pypy/trunk/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/executor.py (original) +++ pypy/trunk/pypy/jit/metainterp/executor.py Mon Jan 4 18:41:45 2010 @@ -6,7 +6,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.rarithmetic import ovfcheck, r_uint, intmask -from pypy.jit.metainterp.history import BoxInt, ConstInt, check_descr +from pypy.jit.metainterp.history import BoxInt, BoxPtr, ConstInt, check_descr from pypy.jit.metainterp.history import INT, REF, ConstFloat from pypy.jit.metainterp import resoperation from pypy.jit.metainterp.resoperation import rop @@ -220,6 +220,15 @@ # ____________________________________________________________ +def do_force_token(cpu): + raise NotImplementedError + +def do_virtual_ref(cpu, box1, box2): + raise NotImplementedError + +def do_virtual_ref_finish(cpu, box1, box2): + raise NotImplementedError + def do_debug_merge_point(cpu, box1): from pypy.jit.metainterp.warmspot import get_stats loc = box1._get_str() Modified: pypy/trunk/pypy/jit/metainterp/jitprof.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/jitprof.py (original) +++ pypy/trunk/pypy/jit/metainterp/jitprof.py Mon Jan 4 18:41:45 2010 @@ -20,6 +20,7 @@ OPT_FORCINGS ABORT_TOO_LONG ABORT_BRIDGE +ABORT_ESCAPE NVIRTUALS NVHOLES NVREUSED @@ -176,8 +177,9 @@ self._print_intline("opt ops", cnt[OPT_OPS]) self._print_intline("opt guards", cnt[OPT_GUARDS]) self._print_intline("forcings", cnt[OPT_FORCINGS]) - self._print_intline("trace too long", cnt[ABORT_TOO_LONG]) - self._print_intline("bridge abort", cnt[ABORT_BRIDGE]) + self._print_intline("abort: trace too long", cnt[ABORT_TOO_LONG]) + self._print_intline("abort: compiling", cnt[ABORT_BRIDGE]) + self._print_intline("abort: vable escape", cnt[ABORT_ESCAPE]) self._print_intline("nvirtuals", cnt[NVIRTUALS]) self._print_intline("nvholes", cnt[NVHOLES]) self._print_intline("nvreused", cnt[NVREUSED]) Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Mon Jan 4 18:41:45 2010 @@ -737,6 +737,49 @@ def optimize_OOIS(self, op): self._optimize_oois_ooisnot(op, False) + def optimize_VIRTUAL_REF(self, op): + indexbox = op.args[1] + # + # get some constants + vrefinfo = self.metainterp_sd.virtualref_info + c_cls = vrefinfo.jit_virtual_ref_const_class + descr_virtual_token = vrefinfo.descr_virtual_token + descr_virtualref_index = vrefinfo.descr_virtualref_index + # + # Replace the VIRTUAL_REF operation with a virtual structure of type + # 'jit_virtual_ref'. The jit_virtual_ref structure may be forced soon, + # but the point is that doing so does not force the original structure. + op = ResOperation(rop.NEW_WITH_VTABLE, [c_cls], op.result) + vrefvalue = self.make_virtual(c_cls, op.result, op) + tokenbox = BoxInt() + self.emit_operation(ResOperation(rop.FORCE_TOKEN, [], tokenbox)) + vrefvalue.setfield(descr_virtual_token, self.getvalue(tokenbox)) + vrefvalue.setfield(descr_virtualref_index, self.getvalue(indexbox)) + + def optimize_VIRTUAL_REF_FINISH(self, op): + # Set the 'forced' field of the virtual_ref. + # In good cases, this is all virtual, so has no effect. + # Otherwise, this forces the real object -- but only now, as + # opposed to much earlier. This is important because the object is + # typically a PyPy PyFrame, and now is the end of its execution, so + # forcing it now does not have catastrophic effects. + vrefinfo = self.metainterp_sd.virtualref_info + # - set 'forced' to point to the real object + op1 = ResOperation(rop.SETFIELD_GC, op.args, None, + descr = vrefinfo.descr_forced) + self.optimize_SETFIELD_GC(op1) + # - set 'virtual_token' to TOKEN_NONE + args = [op.args[0], ConstInt(0)] + op1 = ResOperation(rop.SETFIELD_GC, args, None, + descr = vrefinfo.descr_virtual_token) + self.optimize_SETFIELD_GC(op1) + # Note that in some cases the virtual in op.args[1] has been forced + # already. This is fine. In that case, and *if* a residual + # CALL_MAY_FORCE suddenly turns out to access it, then it will + # trigger a ResumeGuardForcedDescr.handle_async_forcing() which + # will work too (but just be a little pointless, as the structure + # was already forced). + def optimize_GETFIELD_GC(self, op): value = self.getvalue(op.args[0]) if value.is_virtual(): Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Mon Jan 4 18:41:45 2010 @@ -11,7 +11,7 @@ from pypy.jit.metainterp import codewriter, executor from pypy.jit.metainterp.logger import Logger from pypy.jit.metainterp.jitprof import BLACKHOLED_OPS, EmptyProfiler -from pypy.jit.metainterp.jitprof import GUARDS, RECORDED_OPS +from pypy.jit.metainterp.jitprof import GUARDS, RECORDED_OPS, ABORT_ESCAPE from pypy.jit.metainterp.jitprof import ABORT_TOO_LONG, ABORT_BRIDGE from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import specialize @@ -834,8 +834,7 @@ try: self.metainterp.reached_can_enter_jit(self.env) except GiveUp: - self.metainterp.staticdata.profiler.count(ABORT_BRIDGE) - self.metainterp.switch_to_blackhole() + self.metainterp.switch_to_blackhole(ABORT_BRIDGE) if self.metainterp.is_blackholing(): self.blackhole_reached_merge_point(self.env) return True @@ -846,6 +845,7 @@ greenkey = self.env[:num_green_args] sd = self.metainterp.staticdata loc = sd.state.get_location_str(greenkey) + debug_print(loc) constloc = self.metainterp.cpu.ts.conststr(loc) self.metainterp.history.record(rop.DEBUG_MERGE_POINT, [constloc], None) @@ -886,6 +886,55 @@ return self.metainterp.finishframe_exception(self.exception_box, self.exc_value_box) + @arguments("box") + def opimpl_virtual_ref(self, box): + # Details on the content of metainterp.virtualref_boxes: + # + # * it's a list whose items go two by two, containing first the + # virtual box (e.g. the PyFrame) and then the vref box (e.g. + # the 'virtual_ref(frame)'). + # + # * if we detect that the virtual box escapes during tracing + # already (by generating a CALl_MAY_FORCE that marks the flags + # in the vref), then we replace the vref in the list with + # ConstPtr(NULL). + # + metainterp = self.metainterp + if metainterp.is_blackholing(): + resbox = box # good enough when blackholing + else: + vrefinfo = metainterp.staticdata.virtualref_info + obj = box.getref_base() + vref = vrefinfo.virtual_ref_during_tracing(obj) + resbox = history.BoxPtr(vref) + cindex = history.ConstInt(len(metainterp.virtualref_boxes) // 2) + metainterp.history.record(rop.VIRTUAL_REF, [box, cindex], resbox) + # Note: we allocate a JIT_VIRTUAL_REF here + # (in virtual_ref_during_tracing()), in order to detect when + # the virtual escapes during tracing already. We record it as a + # VIRTUAL_REF operation, although the backend sees this operation + # as a no-op. The point is that the backend should not really see + # it in practice, as optimizeopt.py should either kill it or + # replace it with a NEW_WITH_VTABLE followed by SETFIELD_GCs. + metainterp.virtualref_boxes.append(box) + metainterp.virtualref_boxes.append(resbox) + self.make_result_box(resbox) + + @arguments("box") + def opimpl_virtual_ref_finish(self, box): + # virtual_ref_finish() assumes that we have a stack-like, last-in + # first-out order. + metainterp = self.metainterp + vrefbox = metainterp.virtualref_boxes.pop() + lastbox = metainterp.virtualref_boxes.pop() + assert box.getref_base() == lastbox.getref_base() + if not metainterp.is_blackholing(): + vrefinfo = metainterp.staticdata.virtualref_info + vref = vrefbox.getref_base() + if vrefinfo.is_virtual_ref(vref): + metainterp.history.record(rop.VIRTUAL_REF_FINISH, + [vrefbox, lastbox], None) + # ------------------------------ def setup_call(self, argboxes): @@ -947,7 +996,7 @@ if metainterp.staticdata.virtualizable_info is not None: virtualizable_boxes = metainterp.virtualizable_boxes resume.capture_resumedata(metainterp.framestack, virtualizable_boxes, - resumedescr) + metainterp.virtualref_boxes, resumedescr) self.metainterp.staticdata.profiler.count_ops(opnum, GUARDS) # count metainterp.attach_debug_info(guard_op) @@ -988,13 +1037,13 @@ def do_residual_call(self, argboxes, descr, exc): effectinfo = descr.get_extra_info() - if effectinfo is None or effectinfo.promotes_virtualizables: + if effectinfo is None or effectinfo.forces_virtual_or_virtualizable: # residual calls require attention to keep virtualizables in-sync - self.metainterp.vable_before_residual_call() + self.metainterp.vable_and_vrefs_before_residual_call() # xxx do something about code duplication resbox = self.metainterp.execute_and_record_varargs( rop.CALL_MAY_FORCE, argboxes, descr=descr) - self.metainterp.vable_after_residual_call() + self.metainterp.vable_and_vrefs_after_residual_call() if resbox is not None: self.make_result_box(resbox) self.generate_guard(self.pc, rop.GUARD_NOT_FORCED, None, []) @@ -1234,8 +1283,7 @@ try: self.compile_done_with_this_frame(resultbox) except GiveUp: - self.staticdata.profiler.count(ABORT_BRIDGE) - self.switch_to_blackhole() + self.switch_to_blackhole(ABORT_BRIDGE) sd = self.staticdata if sd.result_type == 'void': assert resultbox is None @@ -1272,8 +1320,7 @@ try: self.compile_exit_frame_with_exception(excvaluebox) except GiveUp: - self.staticdata.profiler.count(ABORT_BRIDGE) - self.switch_to_blackhole() + self.switch_to_blackhole(ABORT_BRIDGE) raise self.staticdata.ExitFrameWithExceptionRef(self.cpu, excvaluebox.getref_base()) def check_recursion_invariant(self): @@ -1391,7 +1438,8 @@ op.pc = self.framestack[-1].pc op.name = self.framestack[-1].jitcode.name - def switch_to_blackhole(self): + def switch_to_blackhole(self, reason): + self.staticdata.profiler.count(reason) debug_print('~~~ ABORTING TRACING') debug_stop('jit-tracing') debug_start('jit-blackhole') @@ -1399,15 +1447,15 @@ self.staticdata.stats.aborted() self.staticdata.profiler.end_tracing() self.staticdata.profiler.start_blackhole() + switch_to_blackhole._dont_inline_ = True def switch_to_blackhole_if_trace_too_long(self): if not self.is_blackholing(): warmrunnerstate = self.staticdata.state if len(self.history.operations) > warmrunnerstate.trace_limit: - self.staticdata.profiler.count(ABORT_TOO_LONG) self.greenkey_of_huge_function = self.find_biggest_function() self.portal_trace_positions = None - self.switch_to_blackhole() + self.switch_to_blackhole(ABORT_TOO_LONG) def _interpret(self): # Execute the frames forward until we raise a DoneWithThisFrame, @@ -1531,6 +1579,7 @@ len(self.virtualizable_boxes)-1, duplicates) live_arg_boxes += self.virtualizable_boxes[:-1] + assert len(self.virtualref_boxes) == 0, "missing virtual_ref_finish()?" # Called whenever we reach the 'can_enter_jit' hint. # First, attempt to make a bridge: # - if self.resumekey is a ResumeGuardDescr, it starts from a guard @@ -1686,6 +1735,7 @@ f = self.newframe(self.staticdata.portal_code) f.pc = 0 f.env = original_boxes[:] + self.virtualref_boxes = [] self.initialize_virtualizable(original_boxes) return original_boxes @@ -1723,9 +1773,18 @@ virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box) vinfo.clear_vable_token(virtualizable) - def vable_before_residual_call(self): + def vable_and_vrefs_before_residual_call(self): if self.is_blackholing(): return + # + vrefinfo = self.staticdata.virtualref_info + for i in range(1, len(self.virtualref_boxes), 2): + vrefbox = self.virtualref_boxes[i] + vref = vrefbox.getref_base() + vrefinfo.tracing_before_residual_call(vref) + # the FORCE_TOKEN is already set at runtime in each vref when + # it is created, by optimizeopt.py. + # vinfo = self.staticdata.virtualizable_info if vinfo is not None: virtualizable_box = self.virtualizable_boxes[-1] @@ -1738,23 +1797,50 @@ force_token_box], None, descr=vinfo.vable_token_descr) - def vable_after_residual_call(self): + def vable_and_vrefs_after_residual_call(self): if self.is_blackholing(): - vable_escapes = True + escapes = True else: - vable_escapes = False + escapes = False + # + vrefinfo = self.staticdata.virtualref_info + for i in range(0, len(self.virtualref_boxes), 2): + virtualbox = self.virtualref_boxes[i] + vrefbox = self.virtualref_boxes[i+1] + vref = vrefbox.getref_base() + if vrefinfo.tracing_after_residual_call(vref): + # this vref was really a virtual_ref, but it escaped + # during this CALL_MAY_FORCE. Mark this fact by + # generating a VIRTUAL_REF_FINISH on it and replacing + # it by ConstPtr(NULL). + self.stop_tracking_virtualref(i) + # vinfo = self.staticdata.virtualizable_info if vinfo is not None: virtualizable_box = self.virtualizable_boxes[-1] virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box) if vinfo.tracing_after_residual_call(virtualizable): - # We just did the residual call, and it shows that the - # virtualizable escapes. - self.switch_to_blackhole() - vable_escapes = True - if vable_escapes: + # the virtualizable escaped during CALL_MAY_FORCE. + escapes = True + # + if escapes: + self.switch_to_blackhole(ABORT_ESCAPE) + # + if escapes: self.load_fields_from_virtualizable() + def stop_tracking_virtualref(self, i): + virtualbox = self.virtualref_boxes[i] + vrefbox = self.virtualref_boxes[i+1] + # record VIRTUAL_REF_FINISH just before the current CALL_MAY_FORCE + call_may_force_op = self.history.operations.pop() + assert call_may_force_op.opnum == rop.CALL_MAY_FORCE + self.history.record(rop.VIRTUAL_REF_FINISH, + [vrefbox, virtualbox], None) + self.history.operations.append(call_may_force_op) + # mark by replacing it with ConstPtr(NULL) + self.virtualref_boxes[i+1] = self.cpu.ts.CONST_NULL + def handle_exception(self): etype = self.cpu.get_exception() evalue = self.cpu.get_exc_value() @@ -1787,7 +1873,20 @@ vinfo = self.staticdata.virtualizable_info self.framestack = [] expect_virtualizable = vinfo is not None - virtualizable_boxes = resume.rebuild_from_resumedata(self, newboxes, resumedescr, expect_virtualizable) + virtualizable_boxes, virtualref_boxes = resume.rebuild_from_resumedata( + self, newboxes, resumedescr, expect_virtualizable) + # + # virtual refs: make the vrefs point to the freshly allocated virtuals + self.virtualref_boxes = virtualref_boxes + vrefinfo = self.staticdata.virtualref_info + for i in range(0, len(virtualref_boxes), 2): + virtualbox = virtualref_boxes[i] + vrefbox = virtualref_boxes[i+1] + vrefinfo.continue_tracing(vrefbox.getref_base(), + virtualbox.getref_base()) + # + # virtualizable: synchronize the real virtualizable and the local + # boxes, in whichever direction is appropriate if expect_virtualizable: self.virtualizable_boxes = virtualizable_boxes if self._already_allocated_resume_virtuals is not None: @@ -1796,12 +1895,19 @@ self.load_fields_from_virtualizable() return # just jumped away from assembler (case 4 in the comment in - # virtualizable.py) into tracing (case 2); check that vable_rti - # is and stays NULL. + # virtualizable.py) into tracing (case 2); check that vable_token + # is and stays 0. Note the call to reset_vable_token() in + # warmstate.py. virtualizable_box = self.virtualizable_boxes[-1] virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box) assert not virtualizable.vable_token - self.synchronize_virtualizable() + if self._already_allocated_resume_virtuals is not None: + # resuming from a ResumeGuardForcedDescr: load the new values + # currently stored on the virtualizable fields + self.load_fields_from_virtualizable() + else: + # normal case: fill the virtualizable with the local boxes + self.synchronize_virtualizable() def check_synchronized_virtualizable(self): if not we_are_translated(): @@ -1856,6 +1962,10 @@ for i in range(len(boxes)): if boxes[i] is oldbox: boxes[i] = newbox + boxes = self.virtualref_boxes + for i in range(len(boxes)): + if boxes[i] is oldbox: + boxes[i] = newbox if self.staticdata.virtualizable_info is not None: boxes = self.virtualizable_boxes for i in range(len(boxes)): Modified: pypy/trunk/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/resoperation.py (original) +++ pypy/trunk/pypy/jit/metainterp/resoperation.py Mon Jan 4 18:41:45 2010 @@ -90,7 +90,7 @@ return rop._OVF_FIRST <= self.opnum <= rop._OVF_LAST def is_comparison(self): - return rop._COMPARISON_FIRST <= self.opnum <= rop._COMPARISON_LAST + return self.is_always_pure() and self.returns_bool_result() def is_final(self): return rop._FINAL_FIRST <= self.opnum <= rop._FINAL_LAST @@ -155,7 +155,6 @@ 'CAST_FLOAT_TO_INT/1', 'CAST_INT_TO_FLOAT/1', # - '_COMPARISON_FIRST', 'INT_LT/2b', 'INT_LE/2b', 'INT_EQ/2b', @@ -166,8 +165,7 @@ 'UINT_LE/2b', 'UINT_GT/2b', 'UINT_GE/2b', - '_COMPARISON_LAST', - 'FLOAT_LT/2b', # maybe these ones should be comparisons too + 'FLOAT_LT/2b', 'FLOAT_LE/2b', 'FLOAT_EQ/2b', 'FLOAT_NE/2b', @@ -205,6 +203,8 @@ 'NEW/0d', 'NEW_WITH_VTABLE/1', 'NEW_ARRAY/1d', + 'FORCE_TOKEN/0', + 'VIRTUAL_REF/2', '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- 'SETARRAYITEM_GC/3d', @@ -221,7 +221,7 @@ 'COND_CALL_GC_MALLOC', # [a, b, if_(a<=b)_result, if_(a>b)_call, args...] # => result (for mallocs) 'DEBUG_MERGE_POINT/1', # debugging only - 'FORCE_TOKEN/0', + 'VIRTUAL_REF_FINISH/2', '_CANRAISE_FIRST', # ----- start of can_raise operations ----- 'CALL', Modified: pypy/trunk/pypy/jit/metainterp/resume.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/resume.py (original) +++ pypy/trunk/pypy/jit/metainterp/resume.py Mon Jan 4 18:41:45 2010 @@ -42,7 +42,8 @@ back.parent_resumedata_snapshot, back.env[:]) -def capture_resumedata(framestack, virtualizable_boxes, storage): +def capture_resumedata(framestack, virtualizable_boxes, virtualref_boxes, + storage): n = len(framestack)-1 top = framestack[n] _ensure_parent_resumedata(framestack, n) @@ -50,6 +51,7 @@ top) storage.rd_frame_info_list = frame_info_list snapshot = Snapshot(top.parent_resumedata_snapshot, top.env[:]) + snapshot = Snapshot(snapshot, virtualref_boxes[:]) # xxx for now if virtualizable_boxes is not None: snapshot = Snapshot(snapshot, virtualizable_boxes[:]) # xxx for now storage.rd_snapshot = snapshot @@ -462,11 +464,13 @@ debug_print("\t\t", str(untag(i))) -def rebuild_from_resumedata(metainterp, newboxes, storage, expects_virtualizables): +def rebuild_from_resumedata(metainterp, newboxes, storage, + expects_virtualizables): resumereader = ResumeDataReader(storage, newboxes, metainterp) virtualizable_boxes = None if expects_virtualizables: virtualizable_boxes = resumereader.consume_boxes() + virtualref_boxes = resumereader.consume_boxes() frameinfo = storage.rd_frame_info_list while True: env = resumereader.consume_boxes() @@ -476,11 +480,16 @@ if frameinfo is None: break metainterp.framestack.reverse() - return virtualizable_boxes + return virtualizable_boxes, virtualref_boxes -def force_from_resumedata(metainterp, newboxes, storage): +def force_from_resumedata(metainterp, newboxes, storage, + expects_virtualizables): resumereader = ResumeDataReader(storage, newboxes, metainterp) - return resumereader.consume_boxes(), resumereader.virtuals + virtualizable_boxes = None + if expects_virtualizables: + virtualizable_boxes = resumereader.consume_boxes() + virtualref_boxes = resumereader.consume_boxes() + return virtualizable_boxes, virtualref_boxes, resumereader.virtuals class ResumeDataReader(object): Modified: pypy/trunk/pypy/jit/metainterp/support.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/support.py (original) +++ pypy/trunk/pypy/jit/metainterp/support.py Mon Jan 4 18:41:45 2010 @@ -3,6 +3,7 @@ from pypy.rpython import rlist from pypy.rpython.lltypesystem import rstr as ll_rstr, rdict as ll_rdict from pypy.rpython.lltypesystem import rlist as lltypesystem_rlist +from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.ootypesystem import rdict as oo_rdict from pypy.rpython.llinterp import LLInterpreter from pypy.rpython.extregistry import ExtRegistryEntry @@ -136,6 +137,9 @@ def _ll_1_gc_identityhash(x): return lltype.identityhash(x) +def _ll_1_jit_force_virtual(inst): + return llop.jit_force_virtual(lltype.typeOf(inst), inst) + class LLtypeHelpers: Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_basic.py Mon Jan 4 18:41:45 2010 @@ -52,6 +52,8 @@ assert get_stats().exec_jumps <= maxcount def check_aborted_count(self, count): assert get_stats().aborted_count == count + def check_aborted_count_at_least(self, count): + assert get_stats().aborted_count >= count def meta_interp(self, *args, **kwds): kwds['CPUClass'] = self.CPUClass @@ -84,6 +86,10 @@ metainterp, rtyper = _get_bare_metainterp(f, args, self.CPUClass, self.type_system, **kwds) + metainterp.staticdata.state = FakeWarmRunnerState() + metainterp.staticdata.state.cpu = metainterp.staticdata.cpu + if hasattr(self, 'finish_metainterp_for_interp_operations'): + self.finish_metainterp_for_interp_operations(metainterp) portal_graph = rtyper.annotator.translator.graphs[0] cw = codewriter.CodeWriter(rtyper) @@ -95,7 +101,6 @@ cw.finish_making_bytecodes() metainterp.staticdata.portal_code = maingraph metainterp.staticdata._class_sizes = cw.class_sizes - metainterp.staticdata.state = FakeWarmRunnerState() metainterp.staticdata.DoneWithThisFrameInt = DoneWithThisFrame metainterp.staticdata.DoneWithThisFrameRef = DoneWithThisFrameRef metainterp.staticdata.DoneWithThisFrameFloat = DoneWithThisFrame Modified: pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py Mon Jan 4 18:41:45 2010 @@ -101,6 +101,8 @@ def make_graphs(self, func, values, type_system='lltype'): class FakeMetaInterpSd: virtualizable_info = None + class options: + listops = True def find_opcode(self, name): default = len(self.opname_to_index) return self.opname_to_index.setdefault(name, default) @@ -283,7 +285,7 @@ assert calldescrs[0][4] is not None assert not calldescrs[0][4].write_descrs_fields assert not calldescrs[0][4].write_descrs_arrays - assert not calldescrs[0][4].promotes_virtualizables + assert not calldescrs[0][4].forces_virtual_or_virtualizable def test_oosend_look_inside_only_one(self): class A: @@ -394,7 +396,7 @@ assert cw.list_of_addr2name[0][1].endswith('.A1') assert cw.list_of_addr2name[1][1] == 'A1.g' - def test_promote_virtualizable_effectinfo(self): + def test_jit_force_virtualizable_effectinfo(self): class Frame(object): _virtualizable2_ = ['x'] @@ -430,9 +432,49 @@ effectinfo_g1 = calldescrs[1][4] effectinfo_g2 = calldescrs[2][4] effectinfo_h = calldescrs[3][4] - assert effectinfo_g1.promotes_virtualizables - assert effectinfo_g2.promotes_virtualizables - assert not effectinfo_h.promotes_virtualizables + assert effectinfo_g1.forces_virtual_or_virtualizable + assert effectinfo_g2.forces_virtual_or_virtualizable + assert not effectinfo_h.forces_virtual_or_virtualizable + + def make_vrefinfo(self): + from pypy.jit.metainterp.virtualref import VirtualRefInfo + class FakeWarmRunnerDesc: + cpu = self.metainterp_sd.cpu + self.metainterp_sd.virtualref_info = VirtualRefInfo(FakeWarmRunnerDesc) + + def test_vref_simple(self): + class X: + pass + def f(): + return jit.virtual_ref(X()) + graphs = self.make_graphs(f, []) + assert graphs[0].func is f + assert graphs[1].func is jit.virtual_ref + self.make_vrefinfo() + cw = CodeWriter(self.rtyper) + cw.candidate_graphs = [graphs[0]] + cw._start(self.metainterp_sd, None) + jitcode = cw.make_one_bytecode((graphs[0], None), False) + assert 'virtual_ref' in jitcode._source + + def test_vref_forced(self): + class X: + pass + def f(): + vref = jit.virtual_ref(X()) + return vref() + graphs = self.make_graphs(f, []) + assert graphs[0].func is f + assert graphs[1].func is jit.virtual_ref + self.make_vrefinfo() + cw = CodeWriter(self.rtyper) + cw.candidate_graphs = [graphs[0]] + cw._start(self.metainterp_sd, None) + jitcode = cw.make_one_bytecode((graphs[0], None), False) + assert 'virtual_ref' in jitcode._source + # the call vref() becomes a residual call to a helper that contains + # itself a copy of the call. + assert 'residual_call' in jitcode._source class ImmutableFieldsTests: Modified: pypy/trunk/pypy/jit/metainterp/test/test_executor.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_executor.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_executor.py Mon Jan 4 18:41:45 2010 @@ -273,4 +273,4 @@ elif rettype == 'int': assert box.getint() == retvalue else: - assert retvalue is None + assert 0, "rettype is %r" % (rettype,) Modified: pypy/trunk/pypy/jit/metainterp/test/test_jitprof.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_jitprof.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_jitprof.py Mon Jan 4 18:41:45 2010 @@ -64,7 +64,7 @@ assert profiler.events == expected assert profiler.times == [2, 1, 1, 1] assert profiler.counters == [1, 1, 1, 1, 4, 3, 1, 1, 7, 1, 0, 0, 0, - 0, 0, 0] + 0, 0, 0, 0] def test_simple_loop_with_call(self): @dont_look_inside Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Jan 4 18:41:45 2010 @@ -1,6 +1,6 @@ import py, random -from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.lltypesystem import lltype, llmemory, rclass from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE @@ -38,12 +38,13 @@ type_system = 'lltype' def get_class_of_box(self, box): - from pypy.rpython.lltypesystem import rclass return box.getref(rclass.OBJECTPTR).typeptr node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) + node_vtable.name = rclass.alloc_array_name('node') node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable) node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True) + node_vtable2.name = rclass.alloc_array_name('node2') node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2) cpu = runner.LLtypeCPU(None) @@ -67,6 +68,12 @@ nextdescr = cpu.fielddescrof(NODE, 'next') otherdescr = cpu.fielddescrof(NODE2, 'other') + NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT), + ('ref', lltype.Ptr(OBJECT))) + nodeobj = lltype.malloc(NODEOBJ) + nodeobjvalue = lltype.cast_opaque_ptr(llmemory.GCREF, nodeobj) + refdescr = cpu.fielddescrof(NODEOBJ, 'ref') + arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed)) floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float)) @@ -104,10 +111,28 @@ EffectInfo([], [adescr], [arraydescr])) readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([adescr], [], [])) - - cpu.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE), - cpu.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2), - cpu.cast_adr_to_int(u_vtable_adr): cpu.sizeof(U)} + mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo([nextdescr], [], [], + forces_virtual_or_virtualizable=True)) + + from pypy.jit.metainterp.virtualref import VirtualRefInfo + class FakeWarmRunnerDesc: + pass + FakeWarmRunnerDesc.cpu = cpu + vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc) + virtualtokendescr = vrefinfo.descr_virtual_token + virtualrefindexdescr = vrefinfo.descr_virtualref_index + virtualforceddescr = vrefinfo.descr_forced + jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable + jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable) + + cpu.class_sizes = { + cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE), + cpu.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2), + cpu.cast_adr_to_int(u_vtable_adr): cpu.sizeof(U), + cpu.cast_adr_to_int(jvr_vtable_adr): cpu.sizeof( + vrefinfo.JIT_VIRTUAL_REF), + } namespace = locals() class OOtypeMixin(object): Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Mon Jan 4 18:41:45 2010 @@ -249,7 +249,10 @@ loop.token.specnodes = self.unpack_specnodes(spectext) # self.loop = loop - optimize_loop_1(FakeMetaInterpStaticData(self.cpu), loop) + metainterp_sd = FakeMetaInterpStaticData(self.cpu) + if hasattr(self, 'vrefinfo'): + metainterp_sd.virtualref_info = self.vrefinfo + optimize_loop_1(metainterp_sd, loop) # expected = self.parse(optops) self.assert_equal(loop, expected) @@ -2353,6 +2356,171 @@ """ self.optimize_loop(ops, 'Not, Not, Not, Not', ops) + def test_vref_nonvirtual_nonescape(self): + ops = """ + [p1] + p2 = virtual_ref(p1, 5) + virtual_ref_finish(p2, p1) + jump(p1) + """ + expected = """ + [p1] + i0 = force_token() + jump(p1) + """ + self.optimize_loop(ops, 'Not', expected) + + def test_vref_nonvirtual_escape(self): + ops = """ + [p1] + p2 = virtual_ref(p1, 5) + escape(p2) + virtual_ref_finish(p2, p1) + jump(p1) + """ + expected = """ + [p1] + i0 = force_token() + p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable)) + setfield_gc(p2, i0, descr=virtualtokendescr) + setfield_gc(p2, 5, descr=virtualrefindexdescr) + escape(p2) + setfield_gc(p2, p1, descr=virtualforceddescr) + setfield_gc(p2, 0, descr=virtualtokendescr) + jump(p1) + """ + # XXX we should optimize a bit more the case of a nonvirtual. + # in theory it is enough to just do 'p2 = p1'. + self.optimize_loop(ops, 'Not', expected) + + def test_vref_virtual_1(self): + ops = """ + [p0, i1] + # + p1 = new_with_vtable(ConstClass(node_vtable)) + p1b = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1b, 252, descr=valuedescr) + setfield_gc(p1, p1b, descr=nextdescr) + # + p2 = virtual_ref(p1, 3) + setfield_gc(p0, p2, descr=nextdescr) + call_may_force(i1, descr=mayforcevirtdescr) + guard_not_forced() [i1] + virtual_ref_finish(p2, p1) + setfield_gc(p0, NULL, descr=nextdescr) + jump(p0, i1) + """ + expected = """ + [p0, i1] + i3 = force_token() + # + p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable)) + setfield_gc(p2, i3, descr=virtualtokendescr) + setfield_gc(p2, 3, descr=virtualrefindexdescr) + setfield_gc(p0, p2, descr=nextdescr) + # + call_may_force(i1, descr=mayforcevirtdescr) + guard_not_forced() [i1] + setfield_gc(p0, NULL, descr=nextdescr) + # + p1 = new_with_vtable(ConstClass(node_vtable)) + p1b = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1b, 252, descr=valuedescr) + setfield_gc(p1, p1b, descr=nextdescr) + setfield_gc(p2, p1, descr=virtualforceddescr) + setfield_gc(p2, 0, descr=virtualtokendescr) + # + jump(p0, i1) + """ + self.optimize_loop(ops, 'Not, Not', expected) + + def test_vref_virtual_2(self): + self.make_fail_descr() + ops = """ + [p0, i1] + # + p1 = new_with_vtable(ConstClass(node_vtable)) + p1b = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1b, i1, descr=valuedescr) + setfield_gc(p1, p1b, descr=nextdescr) + # + p2 = virtual_ref(p1, 2) + setfield_gc(p0, p2, descr=nextdescr) + call_may_force(i1, descr=mayforcevirtdescr) + guard_not_forced(descr=fdescr) [p2, p1] + virtual_ref_finish(p2, p1) + setfield_gc(p0, NULL, descr=nextdescr) + jump(p0, i1) + """ + expected = """ + [p0, i1] + i3 = force_token() + # + p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable)) + setfield_gc(p2, i3, descr=virtualtokendescr) + setfield_gc(p2, 2, descr=virtualrefindexdescr) + setfield_gc(p0, p2, descr=nextdescr) + # + call_may_force(i1, descr=mayforcevirtdescr) + guard_not_forced(descr=fdescr) [p2, i1] + setfield_gc(p0, NULL, descr=nextdescr) + # + p1 = new_with_vtable(ConstClass(node_vtable)) + p1b = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1b, i1, descr=valuedescr) + setfield_gc(p1, p1b, descr=nextdescr) + setfield_gc(p2, p1, descr=virtualforceddescr) + setfield_gc(p2, 0, descr=virtualtokendescr) + # + jump(p0, i1) + """ + # the point of this test is that 'i1' should show up in the fail_args + # of 'guard_not_forced', because it was stored in the virtual 'p1b'. + self.optimize_loop(ops, 'Not, Not', expected) + self.check_expanded_fail_descr('''p2, p1 + where p1 is a node_vtable, nextdescr=p1b + where p1b is a node_vtable, valuedescr=i1 + ''') + + def test_vref_virtual_and_lazy_setfield(self): + self.make_fail_descr() + ops = """ + [p0, i1] + # + p1 = new_with_vtable(ConstClass(node_vtable)) + p1b = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1b, i1, descr=valuedescr) + setfield_gc(p1, p1b, descr=nextdescr) + # + p2 = virtual_ref(p1, 2) + setfield_gc(p0, p2, descr=refdescr) + call(i1, descr=nonwritedescr) + guard_no_exception(descr=fdescr) [p2, p1] + virtual_ref_finish(p2, p1) + setfield_gc(p0, NULL, descr=refdescr) + jump(p0, i1) + """ + expected = """ + [p0, i1] + i3 = force_token() + call(i1, descr=nonwritedescr) + guard_no_exception(descr=fdescr) [i3, i1, p0] + setfield_gc(p0, NULL, descr=refdescr) + jump(p0, i1) + """ + self.optimize_loop(ops, 'Not, Not', expected) + # the fail_args contain [i3, i1, p0]: + # - i3 is from the virtual expansion of p2 + # - i1 is from the virtual expansion of p1 + # - p0 is from the extra pendingfields + self.loop.inputargs[0].value = self.nodeobjvalue + self.check_expanded_fail_descr('''p2, p1 + p0.refdescr = p2 + where p2 is a jit_virtual_ref_vtable, virtualtokendescr=i3, virtualrefindexdescr=2 + where p1 is a node_vtable, nextdescr=p1b + where p1b is a node_vtable, valuedescr=i1 + ''') + class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin): Modified: pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py Mon Jan 4 18:41:45 2010 @@ -33,7 +33,8 @@ def test_simple_opimpl_exist(): rop = resoperation.rop for opnum, opname in resoperation.opname.items(): - if opnum in (rop.SAME_AS, rop.CALL_PURE, rop.OOSEND_PURE): + if opnum in (rop.SAME_AS, rop.CALL_PURE, rop.OOSEND_PURE, + rop.FORCE_TOKEN): continue if rop._NOSIDEEFFECT_FIRST <= opnum <= rop._NOSIDEEFFECT_LAST: assert hasattr(pyjitpl.MIFrame, 'opimpl_' + opname.lower()), opname Modified: pypy/trunk/pypy/jit/metainterp/test/test_resume.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_resume.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_resume.py Mon Jan 4 18:41:45 2010 @@ -208,29 +208,32 @@ fs = [FakeFrame("code0", 0, -1, b1, c1, b2)] storage = Storage() - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) assert fs[0].parent_resumedata_snapshot is None assert fs[0].parent_resumedata_frame_info_list is None assert storage.rd_frame_info_list.prev is None assert storage.rd_frame_info_list.jitcode == 'code0' - assert storage.rd_snapshot.prev is None - assert storage.rd_snapshot.boxes == fs[0].env - assert storage.rd_snapshot.boxes is not fs[0].env + assert storage.rd_snapshot.boxes == [] # for virtualrefs + snapshot = storage.rd_snapshot.prev + assert snapshot.prev is None + assert snapshot.boxes == fs[0].env + assert snapshot.boxes is not fs[0].env storage = Storage() fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) frame_info_list = storage.rd_frame_info_list assert frame_info_list.prev is fs[2].parent_resumedata_frame_info_list assert frame_info_list.jitcode == 'code2' assert frame_info_list.pc == 9 - snapshot = storage.rd_snapshot + assert storage.rd_snapshot.boxes == [] # for virtualrefs + snapshot = storage.rd_snapshot.prev assert snapshot.prev is fs[2].parent_resumedata_snapshot assert snapshot.boxes == fs[2].env assert snapshot.boxes is not fs[2].env @@ -254,8 +257,9 @@ fs[2].env = [b2, b3] fs[2].pc = 15 vbs = [b1, b2] - capture_resumedata(fs, vbs, storage) - + vrs = [b3] + capture_resumedata(fs, vbs, vrs, storage) + frame_info_list = storage.rd_frame_info_list assert frame_info_list.prev is fs[2].parent_resumedata_frame_info_list assert frame_info_list.jitcode == 'code2' @@ -266,6 +270,10 @@ assert snapshot.boxes is not vbs snapshot = snapshot.prev + assert snapshot.boxes == vrs + assert snapshot.boxes is not vrs + + snapshot = snapshot.prev assert snapshot.prev is fs[2].parent_resumedata_snapshot assert snapshot.boxes == fs[2].env @@ -283,7 +291,7 @@ fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(storage, memo) liveboxes = modifier.finish({}) @@ -294,7 +302,7 @@ result = rebuild_from_resumedata(metainterp, newboxes, storage, False) - assert result is None + assert result == (None, []) fs2 = [FakeFrame("code0", 0, -1, b1t, c1, b2t), FakeFrame("code1", 3, 7, b3t, c2, b1t), FakeFrame("code2", 9, -1, c3, b2t)] @@ -307,7 +315,7 @@ fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] - capture_resumedata(fs, [b4], storage) + capture_resumedata(fs, [b4], [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(storage, memo) liveboxes = modifier.finish({}) @@ -318,7 +326,7 @@ result = rebuild_from_resumedata(metainterp, newboxes, storage, True) - assert result == [b4t] + assert result == ([b4t], []) fs2 = [FakeFrame("code0", 0, -1, b1t, c1, b2t), FakeFrame("code1", 3, 7, b3t, c2, b1t), FakeFrame("code2", 9, -1, c3, b2t)] @@ -331,10 +339,10 @@ fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) storage2 = Storage() fs = fs[:-1] + [FakeFrame("code2", 10, -1, c3, b2, b4)] - capture_resumedata(fs, None, storage2) + capture_resumedata(fs, None, [], storage2) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(storage, memo) @@ -350,7 +358,7 @@ result = rebuild_from_resumedata(metainterp, newboxes, storage, False) - assert result is None + assert result == (None, []) fs2 = [FakeFrame("code0", 0, -1, b1t, c1, b2t), FakeFrame("code1", 3, 7, b3t, c2, b1t), FakeFrame("code2", 9, -1, c3, b2t)] @@ -361,7 +369,7 @@ metainterp.framestack = [] result = rebuild_from_resumedata(metainterp, newboxes, storage2, False) - assert result is None + assert result == (None, []) fs2 = fs2[:-1] + [FakeFrame("code2", 10, -1, c3, b2t, b4t)] assert metainterp.framestack == fs2 @@ -389,10 +397,10 @@ fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) storage2 = Storage() fs = fs[:-1] + [FakeFrame("code2", 10, -1, c3, b2, b4)] - capture_resumedata(fs, None, storage2) + capture_resumedata(fs, None, [], storage2) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) values = {b2: virtual_value(b2, b5, c4)} @@ -448,7 +456,7 @@ LLtypeMixin.nodebox.constbox()] storage = Storage() fs = [FakeFrame("code0", 0, -1, c1, b2, b3)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) values = {b2: virtual_value(b2, b5, c4)} @@ -460,7 +468,7 @@ storage2 = Storage() fs = [FakeFrame("code0", 0, -1, b1, b4, b2)] - capture_resumedata(fs, None, storage2) + capture_resumedata(fs, None, [], storage2) values[b4] = virtual_value(b4, b6, c4) modifier = ResumeDataVirtualAdder(storage2, memo) liveboxes = modifier.finish(values) @@ -473,7 +481,7 @@ b1, b2, b3 = [BoxPtr(), BoxPtr(), BoxInt()] storage = Storage() fs = [FakeFrame("code0", 0, -1, b1, b2)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) v1 = virtual_value(b1, b3, None) Modified: pypy/trunk/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_virtualizable.py Mon Jan 4 18:41:45 2010 @@ -28,7 +28,7 @@ hop.inputconst(lltype.Void, hop.args_v[1].value), hop.inputconst(lltype.Void, {})] hop.exception_cannot_occur() - return hop.genop('promote_virtualizable', + return hop.genop('jit_force_virtualizable', args_v, resulttype=lltype.Void) debug_print = lloperation.llop.debug_print @@ -907,6 +907,39 @@ res = self.meta_interp(f, [123], policy=StopAtXPolicy(g)) assert res == f(123) + def test_bridge_forces(self): + jitdriver = JitDriver(greens = [], reds = ['frame'], + virtualizables = ['frame']) + + class Frame(object): + _virtualizable2_ = ['x', 'y'] + class SomewhereElse: + pass + somewhere_else = SomewhereElse() + + def g(): + n = somewhere_else.top_frame.y + 700 + debug_print(lltype.Void, '-+-+-+-+- external write:', n) + somewhere_else.top_frame.y = n + + def f(n): + frame = Frame() + frame.x = n + frame.y = 10 + somewhere_else.counter = 0 + somewhere_else.top_frame = frame + while frame.x > 0: + jitdriver.can_enter_jit(frame=frame) + jitdriver.jit_merge_point(frame=frame) + if frame.y > 17: + g() + frame.x -= 5 + frame.y += 1 + return frame.y + + res = self.meta_interp(f, [123], policy=StopAtXPolicy(g)) + assert res == f(123) + def test_promote_index_in_virtualizable_list(self): jitdriver = JitDriver(greens = [], reds = ['frame', 'n'], virtualizables = ['frame']) @@ -980,9 +1013,11 @@ for block, op in graph.iterblockops() if op.opname == 'direct_call'] - assert direct_calls(f_graph) == ['__init__', 'force_if_necessary', 'll_portal_runner'] - assert direct_calls(portal_graph) == ['force_if_necessary', 'maybe_enter_jit'] - + assert direct_calls(f_graph) == ['__init__', + 'force_virtualizable_if_necessary', + 'll_portal_runner'] + assert direct_calls(portal_graph)==['force_virtualizable_if_necessary', + 'maybe_enter_jit'] assert direct_calls(init_graph) == [] def test_virtual_child_frame(self): @@ -1158,8 +1193,7 @@ self.check_loops(getfield_gc=0, setfield_gc=0) def test_blackhole_should_not_reenter(self): - from pypy.jit.backend.test.support import BaseCompiledMixin - if isinstance(self, BaseCompiledMixin): + if not self.basic: py.test.skip("purely frontend test") myjitdriver = JitDriver(greens = [], reds = ['frame', 'fail'], Modified: pypy/trunk/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/trunk/pypy/jit/metainterp/virtualizable.py Mon Jan 4 18:41:45 2010 @@ -11,8 +11,8 @@ class VirtualizableInfo: - token_none = 0 - token_tracing = -1 + TOKEN_NONE = 0 + TOKEN_TRACING_RESCALL = -1 def __init__(self, warmrunnerdesc): self.warmrunnerdesc = warmrunnerdesc @@ -153,16 +153,17 @@ def finish(self): # - def force_if_necessary(virtualizable): + def force_virtualizable_if_necessary(virtualizable): if virtualizable.vable_token: self.force_now(virtualizable) - force_if_necessary._always_inline_ = True + force_virtualizable_if_necessary._always_inline_ = True # all_graphs = self.warmrunnerdesc.translator.graphs ts = self.warmrunnerdesc.cpu.ts (_, FUNCPTR) = ts.get_FuncType([self.VTYPEPTR], lltype.Void) - funcptr = self.warmrunnerdesc.helper_func(FUNCPTR, force_if_necessary) - rvirtualizable2.replace_promote_virtualizable_with_call( + funcptr = self.warmrunnerdesc.helper_func( + FUNCPTR, force_virtualizable_if_necessary) + rvirtualizable2.replace_force_virtualizable_with_call( all_graphs, self.VTYPEPTR, funcptr) def unwrap_virtualizable_box(self, virtualizable_box): @@ -176,7 +177,7 @@ return rvirtualizable2.match_virtualizable_type(TYPE, self.VTYPEPTR) def reset_vable_token(self, virtualizable): - virtualizable.vable_token = self.token_none + virtualizable.vable_token = self.TOKEN_NONE def clear_vable_token(self, virtualizable): if virtualizable.vable_token: @@ -185,14 +186,14 @@ def tracing_before_residual_call(self, virtualizable): assert not virtualizable.vable_token - virtualizable.vable_token = self.token_tracing + virtualizable.vable_token = self.TOKEN_TRACING_RESCALL def tracing_after_residual_call(self, virtualizable): if virtualizable.vable_token: # not modified by the residual call; assert that it is still - # set to 'tracing_vable_rti' and clear it. - assert virtualizable.vable_token == self.token_tracing - virtualizable.vable_token = self.token_none + # set to TOKEN_TRACING_RESCALL and clear it. + assert virtualizable.vable_token == self.TOKEN_TRACING_RESCALL + virtualizable.vable_token = self.TOKEN_NONE return False else: # marker "modified during residual call" set. @@ -200,32 +201,36 @@ def force_now(self, virtualizable): token = virtualizable.vable_token - virtualizable.vable_token = self.token_none - if token == self.token_tracing: + if token == self.TOKEN_TRACING_RESCALL: # The values in the virtualizable are always correct during - # tracing. We only need to reset vable_token to token_none + # tracing. We only need to reset vable_token to TOKEN_NONE # as a marker for the tracing, to tell it that this # virtualizable escapes. - pass + virtualizable.vable_token = self.TOKEN_NONE else: from pypy.jit.metainterp.compile import ResumeGuardForcedDescr - faildescr = self.cpu.force(token) - assert isinstance(faildescr, ResumeGuardForcedDescr) - faildescr.force_virtualizable(self, virtualizable, token) + ResumeGuardForcedDescr.force_now(self.cpu, token) + assert virtualizable.vable_token == self.TOKEN_NONE force_now._dont_inline_ = True + def forced_vable(self, virtualizable_boxes): + virtualizable_box = virtualizable_boxes[-1] + virtualizable = self.unwrap_virtualizable_box(virtualizable_box) + self.write_boxes(virtualizable, virtualizable_boxes) + virtualizable.vable_token = self.TOKEN_NONE + # ____________________________________________________________ # # The 'vable_token' field of a virtualizable is either 0, -1, or points # into the CPU stack to a particular field in the current frame. It is: # -# 1. 0 (token_none) if not in the JIT at all, except as described below. +# 1. 0 (TOKEN_NONE) if not in the JIT at all, except as described below. # # 2. equal to 0 when tracing is in progress; except: # -# 3. equal to -1 (token_tracing) during tracing when we do a residual call, -# calling random unknown other parts of the interpreter; it is -# reset to 0 as soon as something occurs to the virtualizable. +# 3. equal to -1 (TOKEN_TRACING_RESCALL) during tracing when we do a +# residual call, calling random unknown other parts of the interpreter; +# it is reset to 0 as soon as something occurs to the virtualizable. # # 4. when running the machine code with a virtualizable, it is set # to the address in the CPU stack by the FORCE_TOKEN operation. Modified: pypy/trunk/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/warmspot.py (original) +++ pypy/trunk/pypy/jit/metainterp/warmspot.py Mon Jan 4 18:41:45 2010 @@ -1,4 +1,4 @@ -import sys +import sys, py from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr from pypy.rpython.ootypesystem import ootype from pypy.rpython.annlowlevel import llhelper, MixLevelHelperAnnotator,\ @@ -162,9 +162,13 @@ self.build_meta_interp(CPUClass, **kwds) self.make_args_specification() + # + from pypy.jit.metainterp.virtualref import VirtualRefInfo + self.metainterp_sd.virtualref_info = VirtualRefInfo(self) if self.jitdriver.virtualizables: from pypy.jit.metainterp.virtualizable import VirtualizableInfo self.metainterp_sd.virtualizable_info = VirtualizableInfo(self) + # self.make_exception_classes() self.make_driverhook_graphs() self.make_enter_function() @@ -177,6 +181,7 @@ ) self.rewrite_can_enter_jit() self.rewrite_set_param() + self.rewrite_force_virtual() self.add_profiler_finish() self.metainterp_sd.finish_setup(optimizer=optimizer) @@ -599,6 +604,13 @@ op.opname = 'direct_call' op.args[:3] = [closures[funcname]] + def rewrite_force_virtual(self): + if self.cpu.ts.name != 'lltype': + py.test.skip("rewrite_force_virtual: port it to ootype") + all_graphs = self.translator.graphs + vrefinfo = self.metainterp_sd.virtualref_info + vrefinfo.replace_force_virtual_with_call(all_graphs) + def decode_hp_hint_args(op): # Returns (list-of-green-vars, list-of-red-vars) without Voids. Modified: pypy/trunk/pypy/jit/tool/jitoutput.py ============================================================================== --- pypy/trunk/pypy/jit/tool/jitoutput.py (original) +++ pypy/trunk/pypy/jit/tool/jitoutput.py Mon Jan 4 18:41:45 2010 @@ -26,8 +26,12 @@ (('opt_ops',), '^opt ops:\s+(\d+)$'), (('opt_guards',), '^opt guards:\s+(\d+)$'), (('forcings',), '^forcings:\s+(\d+)$'), - (('trace_too_long',), '^trace too long:\s+(\d+)$'), - (('bridge_abort',), '^bridge abort:\s+(\d+)$'), + (('abort.trace_too_long',), '^abort: trace too long:\s+(\d+)$'), + (('abort.compiling',), '^abort: compiling:\s+(\d+)$'), + (('abort.vable_escape',), '^abort: vable escape:\s+(\d+)$'), + (('nvirtuals',), '^nvirtuals:\s+(\d+)$'), + (('nvholes',), '^nvholes:\s+(\d+)$'), + (('nvreused',), '^nvreused:\s+(\d+)$'), ] class Ops(object): @@ -35,6 +39,11 @@ calls = 0 pure_calls = 0 +class Aborts(object): + trace_too_long = 0 + compiling = 0 + vable_escape = 0 + class OutputInfo(object): tracing_no = 0 tracing_time = 0.0 @@ -45,13 +54,16 @@ guards = 0 opt_ops = 0 opt_guards = 0 - trace_too_long = 0 - bridge_abort = 0 + forcings = 0 + nvirtuals = 0 + nvholes = 0 + nvreused = 0 def __init__(self): self.ops = Ops() self.recorded_ops = Ops() self.blackholed_ops = Ops() + self.abort = Aborts() def parse_prof(output): lines = output.splitlines() Modified: pypy/trunk/pypy/jit/tool/test/test_jitoutput.py ============================================================================== --- pypy/trunk/pypy/jit/tool/test/test_jitoutput.py (original) +++ pypy/trunk/pypy/jit/tool/test/test_jitoutput.py Mon Jan 4 18:41:45 2010 @@ -46,8 +46,6 @@ assert info.opt_ops == 6 assert info.opt_guards == 1 assert info.forcings == 0 - assert info.trace_too_long == 0 - assert info.bridge_abort == 0 DATA = '''Tracing: 1 0.006992 Backend: 1 0.000525 @@ -66,8 +64,12 @@ opt ops: 6 opt guards: 1 forcings: 1 -trace too long: 2 -bridge abort: 3 +abort: trace too long: 10 +abort: compiling: 11 +abort: vable escape: 12 +nvirtuals: 13 +nvholes: 14 +nvreused: 15 ''' def test_parse(): @@ -90,5 +92,9 @@ assert info.opt_ops == 6 assert info.opt_guards == 1 assert info.forcings == 1 - assert info.trace_too_long == 2 - assert info.bridge_abort == 3 + assert info.abort.trace_too_long == 10 + assert info.abort.compiling == 11 + assert info.abort.vable_escape == 12 + assert info.nvirtuals == 13 + assert info.nvholes == 14 + assert info.nvreused == 15 Modified: pypy/trunk/pypy/module/_stackless/interp_coroutine.py ============================================================================== --- pypy/trunk/pypy/module/_stackless/interp_coroutine.py (original) +++ pypy/trunk/pypy/module/_stackless/interp_coroutine.py Mon Jan 4 18:41:45 2010 @@ -275,11 +275,10 @@ return space.newtuple([]) items = [None] * index f = self.subctx.topframe - f.force_f_back() while index > 0: index -= 1 items[index] = space.wrap(f) - f = f.f_back() + f = f.f_backref() assert f is None return space.newtuple(items) Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/trunk/pypy/module/pypyjit/interp_jit.py Mon Jan 4 18:41:45 2010 @@ -21,7 +21,7 @@ PyFrame._virtualizable2_ = ['last_instr', 'pycode', 'valuestackdepth', 'valuestack_w[*]', - 'fastlocals_w[*]', 'f_forward', + 'fastlocals_w[*]', 'last_exception', ] @@ -35,12 +35,6 @@ name = opcode_method_names[ord(bytecode.co_code[next_instr])] return '%s #%d %s' % (bytecode.get_repr(), next_instr, name) -def leave(next_instr, pycode, frame, ec): - from pypy.interpreter.executioncontext import ExecutionContext - # can't use a method here, since this function is seen later than the main - # annotation XXX no longer true, could be fixed - ExecutionContext._jit_rechain_frame(ec, frame) - def get_jitcell_at(next_instr, bytecode): return bytecode.jit_cells.get(next_instr, None) @@ -63,7 +57,6 @@ pypyjitdriver = PyPyJitDriver(can_inline = can_inline, get_printable_location = get_printable_location, - leave = leave, get_jitcell_at = get_jitcell_at, set_jitcell_at = set_jitcell_at) Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Mon Jan 4 18:41:45 2010 @@ -113,8 +113,8 @@ assert result assert result.splitlines()[-1].strip() == 'OK :-)' self.parse_loops(logfilepath) + self.print_loops() if self.total_ops > expected_max_ops: - self.print_loops() assert 0, "too many operations: got %d, expected maximum %d" % ( self.total_ops, expected_max_ops) @@ -205,7 +205,7 @@ def main(): return richards.main(iterations = 1) - ''' % (sys.path,), 7000, + ''' % (sys.path,), 7200, ([], 42)) def test_simple_call(self): @@ -267,7 +267,9 @@ ops = self.get_by_bytecode("LOAD_ATTR") assert len(ops) == 2 assert ops[0].get_opnames() == ["getfield_gc", "getarrayitem_gc", + "setfield_gc", # (*) "guard_nonnull_class"] + # (*) delayed write of the frames depth assert not ops[1] # second LOAD_ATTR folded away def test_default_and_kw(self): @@ -445,7 +447,27 @@ def setup_class(cls): if option.pypy_c is None: py.test.skip("pass --pypy!") + if not has_info(option.pypy_c, 'translation.jit'): + py.test.skip("must give a pypy-c with the jit enabled") + if has_info(option.pypy_c, 'translation.thread'): + py.test.skip("for now, must give a pypy-c-jit without threads") cls.tmpdir = udir.join('pypy-jit') cls.tmpdir.ensure(dir=1) cls.counter = 0 cls.pypy_c = option.pypy_c + +def has_info(pypy_c, option): + g = os.popen('"%s" --info' % pypy_c, 'r') + lines = g.readlines() + g.close() + for line in lines: + line = line.strip() + if line.startswith(option + ':'): + line = line[len(option)+1:].strip() + if line == 'True': + return True + elif line == 'False': + return False + else: + return line + raise ValueError(option + ' not found in ' + pypy_c) Modified: pypy/trunk/pypy/module/sys/vm.py ============================================================================== --- pypy/trunk/pypy/module/sys/vm.py (original) +++ pypy/trunk/pypy/module/sys/vm.py Mon Jan 4 18:41:45 2010 @@ -31,7 +31,6 @@ space.wrap("frame index must not be negative")) ec = space.getexecutioncontext() f = ec.gettopframe_nohidden() - f.force_f_back() while True: if f is None: raise OperationError(space.w_ValueError, Modified: pypy/trunk/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/flowcontext.py (original) +++ pypy/trunk/pypy/objspace/flow/flowcontext.py Mon Jan 4 18:41:45 2010 @@ -5,6 +5,7 @@ from pypy.interpreter.argument import ArgumentsForTranslation from pypy.objspace.flow.model import * from pypy.objspace.flow.framestate import FrameState +from pypy.rlib import jit class OperationThatShouldNotBePropagatedError(OperationError): @@ -260,8 +261,8 @@ except StopFlowing: continue # restarting a dead SpamBlock try: - old_frame = self.some_frame - self.some_frame = frame + old_frameref = self.topframeref + self.topframeref = jit.non_virtual_ref(frame) self.crnt_frame = frame try: w_result = frame.dispatch(frame.pycode, @@ -269,7 +270,7 @@ self) finally: self.crnt_frame = None - self.some_frame = old_frame + self.topframeref = old_frameref except OperationThatShouldNotBePropagatedError, e: raise Exception( Modified: pypy/trunk/pypy/rlib/jit.py ============================================================================== --- pypy/trunk/pypy/rlib/jit.py (original) +++ pypy/trunk/pypy/rlib/jit.py Mon Jan 4 18:41:45 2010 @@ -2,6 +2,7 @@ import sys from pypy.rpython.extregistry import ExtRegistryEntry from pypy.rlib.objectmodel import CDefinedIntSymbolic +from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.unroll import unrolling_iterable def purefunction(func): @@ -99,6 +100,66 @@ return hop.inputconst(lltype.Signed, _we_are_jitted) # ____________________________________________________________ +# VRefs + +def virtual_ref(x): + + """Creates a 'vref' object that contains a reference to 'x'. Calls + to virtual_ref/virtual_ref_finish must be properly nested. The idea + is that the object 'x' is supposed to be JITted as a virtual between + the calls to virtual_ref and virtual_ref_finish, but the 'vref' + object can escape at any point in time. If at runtime it is + dereferenced (by the call syntax 'vref()'), it returns 'x', which is + then forced.""" + return DirectJitVRef(x) +virtual_ref.oopspec = 'virtual_ref(x)' + +def virtual_ref_finish(x): + """See docstring in virtual_ref(x). Note that virtual_ref_finish + takes as argument the real object, not the vref.""" + keepalive_until_here(x) # otherwise the whole function call is removed +virtual_ref_finish.oopspec = 'virtual_ref_finish(x)' + +def non_virtual_ref(x): + """Creates a 'vref' that just returns x when called; nothing more special. + Used for None or for frames outside JIT scope.""" + return DirectVRef(x) + +# ---------- implementation-specific ---------- + +class DirectVRef(object): + def __init__(self, x): + self._x = x + def __call__(self): + return self._x + +class DirectJitVRef(DirectVRef): + def __init__(self, x): + assert x is not None, "virtual_ref(None) is not allowed" + DirectVRef.__init__(self, x) + +class Entry(ExtRegistryEntry): + _about_ = (non_virtual_ref, DirectJitVRef) + + def compute_result_annotation(self, s_obj): + from pypy.rlib import _jit_vref + return _jit_vref.SomeVRef(s_obj) + + def specialize_call(self, hop): + return hop.r_result.specialize_call(hop) + +class Entry(ExtRegistryEntry): + _type_ = DirectVRef + + def compute_annotation(self): + from pypy.rlib import _jit_vref + assert isinstance(self.instance, DirectVRef) + s_obj = self.bookkeeper.immutablevalue(self.instance()) + return _jit_vref.SomeVRef(s_obj) + +vref_None = non_virtual_ref(None) + +# ____________________________________________________________ # User interface for the hotpath JIT policy class JitHintError(Exception): @@ -135,7 +196,7 @@ def __init__(self, greens=None, reds=None, virtualizables=None, get_jitcell_at=None, set_jitcell_at=None, can_inline=None, get_printable_location=None, - leave=None): + leave=None): # XXX 'leave' is deprecated if greens is not None: self.greens = greens if reds is not None: Modified: pypy/trunk/pypy/rpython/llinterp.py ============================================================================== --- pypy/trunk/pypy/rpython/llinterp.py (original) +++ pypy/trunk/pypy/rpython/llinterp.py Mon Jan 4 18:41:45 2010 @@ -546,9 +546,6 @@ def op_jit_marker(self, *args): pass - def op_promote_virtualizable(self, *args): - pass - def op_get_exception_addr(self, *args): raise NotImplementedError Modified: pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py Mon Jan 4 18:41:45 2010 @@ -21,8 +21,7 @@ from pypy.rlib.rarithmetic import r_uint, r_singlefloat, intmask from pypy.annotation import model as annmodel from pypy.rpython.llinterp import LLInterpreter, LLException -from pypy.rpython.lltypesystem.rclass import OBJECT -from pypy.rpython.annlowlevel import base_ptr_lltype +from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE from pypy.rpython import raddress from pypy.translator.platform import platform @@ -31,7 +30,6 @@ _ctypes_cache = {} _eci_cache = {} -_parent_cache = {} def _setup_ctypes_cache(): from pypy.rpython.lltypesystem import rffi @@ -255,7 +253,6 @@ convert_struct(field_value, csubstruct) subcontainer = getattr(container, field_name) substorage = subcontainer._storage - update_parent_cache(substorage, subcontainer) elif field_name == STRUCT._arrayfld: # inlined var-sized part csubarray = getattr(cstruct, field_name) convert_array(field_value, csubarray) @@ -314,7 +311,6 @@ struct_storage = getattr(ctypes_storage, field_name) struct_use_ctypes_storage(struct_container, struct_storage) struct_container._setparentstructure(container, field_name) - update_parent_cache(ctypes_storage, struct_container) elif isinstance(FIELDTYPE, lltype.Array): assert FIELDTYPE._hints.get('nolength', False) == False arraycontainer = _array_of_known_length(FIELDTYPE) @@ -500,25 +496,6 @@ _callback2obj = {} _callback_exc_info = None -# this is just another hack that passes around references to applevel types -# disguised as base_ptr_lltype -class Dummy(object): - pass - -_opaque_cache = {Dummy():0} -_opaque_list = [Dummy()] - -def new_opaque_object(llobj): - try: - return _opaque_cache[llobj] - except KeyError: - assert len(_opaque_cache) == len(_opaque_list) - ctypes_type = get_ctypes_type(base_ptr_lltype()) - val = ctypes.cast(len(_opaque_cache), ctypes_type) - _opaque_list.append(llobj) - _opaque_cache[llobj] = val - return val - def get_rtyper(): llinterp = LLInterpreter.current_interpreter if llinterp is not None: @@ -542,8 +519,6 @@ return ctypes.c_void_p(0) return get_ctypes_type(T)() - if T is base_ptr_lltype(): - return new_opaque_object(llobj) if T == llmemory.GCREF: if isinstance(llobj._obj, _llgcopaque): return ctypes.c_void_p(llobj._obj.intval) @@ -655,8 +630,6 @@ raise NotImplementedError(T) container._ctypes_storage_was_allocated() storage = container._storage - if lltype.parentlink(container)[0] is not None: - update_parent_cache(storage, container) p = ctypes.pointer(storage) if index: p = ctypes.cast(p, ctypes.c_void_p) @@ -694,29 +667,37 @@ if isinstance(T, lltype.Ptr): if not cobj: # NULL pointer return lltype.nullptr(T.TO) - if T is base_ptr_lltype(): - return _opaque_list[ctypes.cast(cobj, ctypes.c_void_p).value] if isinstance(T.TO, lltype.Struct): + REAL_TYPE = T.TO if T.TO._arrayfld is not None: carray = getattr(cobj.contents, T.TO._arrayfld) container = lltype._struct(T.TO, carray.length) else: # special treatment of 'OBJECT' subclasses - if get_rtyper() and lltype._castdepth(T.TO, OBJECT) > 0: - ctypes_object = get_ctypes_type(lltype.Ptr(OBJECT)) - as_obj = ctypes2lltype(lltype.Ptr(OBJECT), - ctypes.cast(cobj, ctypes_object)) - TObj = get_rtyper().get_type_for_typeptr(as_obj.typeptr) - if TObj != T.TO: - ctypes_instance = get_ctypes_type(lltype.Ptr(TObj)) - return lltype.cast_pointer(T, - ctypes2lltype(lltype.Ptr(TObj), - ctypes.cast(cobj, ctypes_instance))) - container = lltype._struct(T.TO) + if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT) >= 0: + # figure out the real type of the object + containerheader = lltype._struct(OBJECT) + cobjheader = ctypes.cast(cobj, + get_ctypes_type(lltype.Ptr(OBJECT))) + struct_use_ctypes_storage(containerheader, + cobjheader.contents) + REAL_TYPE = get_rtyper().get_type_for_typeptr( + containerheader.typeptr) + REAL_T = lltype.Ptr(REAL_TYPE) + cobj = ctypes.cast(cobj, get_ctypes_type(REAL_T)) + container = lltype._struct(REAL_TYPE) struct_use_ctypes_storage(container, cobj.contents) - addr = ctypes.addressof(cobj.contents) - if addr in _parent_cache: - setparentstructure(container, _parent_cache[addr]) + if REAL_TYPE != T.TO: + p = container._as_ptr() + container = lltype.cast_pointer(T, p)._as_obj() + # special treatment of 'OBJECT_VTABLE' subclasses + if get_rtyper() and lltype._castdepth(REAL_TYPE, + OBJECT_VTABLE) >= 0: + # figure out the real object that this vtable points to, + # and just return that + p = get_rtyper().get_real_typeptr_for_typeptr( + container._as_ptr()) + container = lltype.cast_pointer(T, p)._as_obj() elif isinstance(T.TO, lltype.Array): if T.TO._hints.get('nolength', False): container = _array_of_unknown_length(T.TO) @@ -1163,46 +1144,6 @@ return hop.genop('cast_adr_to_int', [adr], resulttype = lltype.Signed) -# ------------------------------------------------------------ - -def parentchain(container): - current = container - links = [] - while True: - link = lltype.parentlink(current) - if link[0] is None: - try: - addr = ctypes.addressof(container._storage) - actual = _parent_cache[addr] - if len(links) < len(actual): - return actual - except KeyError: - pass - return links - links.append(link) - current = link[0] - -def update_parent_cache(storage, container): - chain = parentchain(container) - addr = ctypes.addressof(storage) - try: - current = _parent_cache[addr] - if len(chain) > len(current): - _parent_cache[addr] = chain - except KeyError: - _parent_cache[addr] = chain - -def setparentstructure(container, chain): - TP = lltype.typeOf(container) - current = container - for i, elem in enumerate(chain): - if lltype.typeOf(elem[0]) == TP: - chain = chain[i + 1:] - break - for elem in chain: - current._setparentstructure(*elem) - current = elem[0] - # ____________________________________________________________ # errno Modified: pypy/trunk/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/lloperation.py Mon Jan 4 18:41:45 2010 @@ -427,7 +427,8 @@ # __________ used by the JIT ________ 'jit_marker': LLOp(), - 'promote_virtualizable':LLOp(canrun=True), + 'jit_force_virtualizable':LLOp(canrun=True), + 'jit_force_virtual': LLOp(canrun=True), 'get_exception_addr': LLOp(), 'get_exc_value_addr': LLOp(), 'do_malloc_fixedsize_clear': LLOp(canunwindgc=True), Modified: pypy/trunk/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/opimpl.py Mon Jan 4 18:41:45 2010 @@ -444,8 +444,11 @@ def op_gc_stack_bottom(): pass # marker for trackgcroot.py -def op_promote_virtualizable(object, fieldname, flags): - pass # XXX should do something +def op_jit_force_virtualizable(*args): + pass + +def op_jit_force_virtual(x): + return x def op_get_group_member(TYPE, grpptr, memberoffset): from pypy.rpython.lltypesystem import llgroup Modified: pypy/trunk/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rclass.py Mon Jan 4 18:41:45 2010 @@ -86,6 +86,13 @@ vtable = vtable.super return vtable +def alloc_array_name(name): + p = malloc(Array(Char), len(name)+1, immortal=True) + for i in range(len(name)): + p[i] = name[i] + p[len(name)] = '\x00' + return p + class ClassRepr(AbstractClassRepr): def __init__(self, rtyper, classdef): @@ -192,10 +199,7 @@ name = 'object' else: name = rsubcls.classdef.shortname - vtable.name = malloc(Array(Char), len(name)+1, immortal=True) - for i in range(len(name)): - vtable.name[i] = name[i] - vtable.name[len(name)] = '\x00' + vtable.name = alloc_array_name(name) if hasattr(rsubcls.classdef, 'my_instantiate_graph'): graph = rsubcls.classdef.my_instantiate_graph vtable.instantiate = self.rtyper.getcallable(graph) @@ -379,7 +383,7 @@ ll_runtime_type_info, OBJECT, destrptr) vtable = self.rclass.getvtable() - self.rtyper.type_for_typeptr[vtable._obj] = self.lowleveltype.TO + self.rtyper.set_type_for_typeptr(vtable, self.lowleveltype.TO) self.rtyper.lltype2vtable[self.lowleveltype.TO] = vtable def common_repr(self): # -> object or nongcobject reprs @@ -689,3 +693,23 @@ break raise AttributeError("%s has no field %s" % (lltype.typeOf(widest), name)) + +def declare_type_for_typeptr(vtable, TYPE): + """Hack for custom low-level-only 'subclasses' of OBJECT: + call this somewhere annotated, in order to declare that it is + of the given TYPE and has got the corresponding vtable.""" + +class Entry(ExtRegistryEntry): + _about_ = declare_type_for_typeptr + def compute_result_annotation(self, s_vtable, s_TYPE): + assert s_vtable.is_constant() + assert s_TYPE.is_constant() + return annmodel.s_None + def specialize_call(self, hop): + vtable = hop.args_v[0].value + TYPE = hop.args_v[1].value + assert lltype.typeOf(vtable) == CLASSTYPE + assert isinstance(TYPE, GcStruct) + assert lltype._castdepth(TYPE, OBJECT) > 0 + hop.rtyper.set_type_for_typeptr(vtable, TYPE) + return hop.inputconst(lltype.Void, None) Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Mon Jan 4 18:41:45 2010 @@ -928,34 +928,6 @@ assert op.args[1].value == pypy.rpython.lltypesystem.rstr.LLHelpers assert op.args[3].value == -2 - def test_pass_around_t_object(self): - from pypy.rpython.annlowlevel import base_ptr_lltype - T = base_ptr_lltype() - - class X(object): - _TYPE = T - x = 10 - - def callback(x): - return x.x - - c_source = py.code.Source(""" - long eating_callback(void *arg, long(*call)(void*)) - { - return call(arg); - } - """) - - eci = ExternalCompilationInfo(separate_module_sources=[c_source], - export_symbols=['eating_callback']) - - args = [T, rffi.CCallback([T], rffi.LONG)] - eating_callback = rffi.llexternal('eating_callback', args, rffi.LONG, - compilation_info=eci) - - res = eating_callback(X(), callback) - assert res == 10 - def test_recursive_struct_more(self): NODE = lltype.ForwardReference() NODE.become(lltype.Struct('NODE', ('value', lltype.Signed), @@ -1134,7 +1106,104 @@ #import pdb; pdb.set_trace() assert adr1_2 == adr1 assert adr1 == adr1_2 - + + def test_object_subclass(self): + from pypy.rpython.lltypesystem import rclass + from pypy.rpython.annlowlevel import cast_instance_to_base_ptr + from pypy.rpython.annlowlevel import cast_base_ptr_to_instance + class S: + pass + def f(n): + s = S() + s.x = n + ls = cast_instance_to_base_ptr(s) + as_num = rffi.cast(lltype.Signed, ls) + # --- around this point, only 'as_num' is passed + t = rffi.cast(rclass.OBJECTPTR, as_num) + u = cast_base_ptr_to_instance(S, t) + return u.x + res = interpret(f, [123]) + assert res == 123 + + def test_object_subclass_2(self): + from pypy.rpython.lltypesystem import rclass + SCLASS = lltype.GcStruct('SCLASS', + ('parent', rclass.OBJECT), + ('n', lltype.Signed)) + sclass_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True, + immortal=True) + sclass_vtable.name = rclass.alloc_array_name('SClass') + def f(n): + rclass.declare_type_for_typeptr(sclass_vtable, SCLASS) + s = lltype.malloc(SCLASS) + s.parent.typeptr = sclass_vtable + s.n = n + as_num = rffi.cast(lltype.Signed, s) + # --- around this point, only 'as_num' is passed + t = rffi.cast(lltype.Ptr(SCLASS), as_num) + return t.n + res = interpret(f, [123]) + assert res == 123 + + def test_object_subclass_3(self): + from pypy.rpython.lltypesystem import rclass + from pypy.rpython.annlowlevel import cast_instance_to_base_ptr + from pypy.rpython.annlowlevel import cast_base_ptr_to_instance + class S: + pass + def f(n): + s = S() + s.x = n + ls = cast_instance_to_base_ptr(s) + as_num = rffi.cast(lltype.Signed, ls) + # --- around this point, only 'as_num' is passed + r = rffi.cast(llmemory.GCREF, as_num) + t = lltype.cast_opaque_ptr(rclass.OBJECTPTR, r) + u = cast_base_ptr_to_instance(S, t) + return u.x + res = interpret(f, [123]) + assert res == 123 + + def test_object_subclass_4(self): + from pypy.rpython.lltypesystem import rclass + SCLASS = lltype.GcStruct('SCLASS', + ('parent', rclass.OBJECT), + ('n', lltype.Signed)) + sclass_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True, + immortal=True) + sclass_vtable.name = rclass.alloc_array_name('SClass') + def f(n): + rclass.declare_type_for_typeptr(sclass_vtable, SCLASS) + s = lltype.malloc(SCLASS) + s.parent.typeptr = sclass_vtable + s.n = n + as_num = rffi.cast(lltype.Signed, s) + # --- around this point, only 'as_num' is passed + r = rffi.cast(llmemory.GCREF, as_num) + t = lltype.cast_opaque_ptr(lltype.Ptr(SCLASS), r) + return t.n + res = interpret(f, [123]) + assert res == 123 + + def test_object_subclass_5(self): + from pypy.rpython.lltypesystem import rclass + from pypy.rpython.annlowlevel import cast_instance_to_base_ptr + from pypy.rpython.annlowlevel import cast_base_ptr_to_instance + class S: + x = 5 # entry in the vtable + class T(S): + x = 6 + def f(): + s = T() + ls = cast_instance_to_base_ptr(s) + as_num = rffi.cast(lltype.Signed, ls) + # --- around this point, only 'as_num' is passed + t = rffi.cast(rclass.OBJECTPTR, as_num) + u = cast_base_ptr_to_instance(S, t) + return u.x + res = interpret(f, []) + assert res == 6 + class TestPlatform(object): def test_lib_on_libpaths(self): from pypy.translator.platform import platform Modified: pypy/trunk/pypy/rpython/rtyper.py ============================================================================== --- pypy/trunk/pypy/rpython/rtyper.py (original) +++ pypy/trunk/pypy/rpython/rtyper.py Mon Jan 4 18:41:45 2010 @@ -133,15 +133,33 @@ return result def get_type_for_typeptr(self, typeptr): + search = typeptr._obj try: - return self.type_for_typeptr[typeptr._obj] + return self.type_for_typeptr[search] except KeyError: - # rehash the dictionary + # rehash the dictionary, and perform a linear scan + # for the case of ll2ctypes typeptr + found = None type_for_typeptr = {} for key, value in self.type_for_typeptr.items(): type_for_typeptr[key] = value + if key == search: + found = value self.type_for_typeptr = type_for_typeptr - return self.type_for_typeptr[typeptr._obj] + if found is None: + raise KeyError(search) + return found + + def set_type_for_typeptr(self, typeptr, TYPE): + self.type_for_typeptr[typeptr._obj] = TYPE + + def get_real_typeptr_for_typeptr(self, typeptr): + # perform a linear scan for the case of ll2ctypes typeptr + search = typeptr._obj + for key, value in self.type_for_typeptr.items(): + if key == search: + return key._as_ptr() + raise KeyError(search) def makekey(self, s_obj): return pair(self.type_system, s_obj).rtyper_makekey(self) Modified: pypy/trunk/pypy/rpython/rvirtualizable2.py ============================================================================== --- pypy/trunk/pypy/rpython/rvirtualizable2.py (original) +++ pypy/trunk/pypy/rpython/rvirtualizable2.py Mon Jan 4 18:41:45 2010 @@ -52,10 +52,10 @@ #if not flags.get('access_directly'): if cname.value in self.my_redirected_fields: cflags = inputconst(lltype.Void, flags) - llops.genop('promote_virtualizable', [vinst, cname, cflags]) + llops.genop('jit_force_virtualizable', [vinst, cname, cflags]) -def replace_promote_virtualizable_with_call(graphs, VTYPEPTR, funcptr): +def replace_force_virtualizable_with_call(graphs, VTYPEPTR, funcptr): # funcptr should be an ll or oo function pointer with a VTYPEPTR argument c_funcptr = inputconst(lltype.typeOf(funcptr), funcptr) count = 0 @@ -65,7 +65,7 @@ continue newoplist = [] for i, op in enumerate(block.operations): - if (op.opname == 'promote_virtualizable' and + if (op.opname == 'jit_force_virtualizable' and match_virtualizable_type(op.args[0].concretetype, VTYPEPTR)): if op.args[-1].value.get('access_directly', False): @@ -75,7 +75,7 @@ count += 1 newoplist.append(op) block.operations = newoplist - log("replaced %d 'promote_virtualizable' with %r" % (count, funcptr)) + log("replaced %d 'jit_force_virtualizable' with %r" % (count, funcptr)) def match_virtualizable_type(TYPE, VTYPEPTR): if isinstance(TYPE, ootype.Instance): Modified: pypy/trunk/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/trunk/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/trunk/pypy/rpython/test/test_rvirtualizable2.py Mon Jan 4 18:41:45 2010 @@ -1,7 +1,7 @@ import py from pypy.rpython.lltypesystem import lltype from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rpython.rvirtualizable2 import replace_promote_virtualizable_with_call +from pypy.rpython.rvirtualizable2 import replace_force_virtualizable_with_call from pypy.rlib.jit import hint from pypy.objspace.flow.model import summary from pypy.rpython.llinterp import LLInterpreter @@ -33,15 +33,15 @@ def __init__(self, v0): self.v0 = v0 -def get_promote_virtualizable_flags(graph): +def get_force_virtualizable_flags(graph): res = [] for block, op in graph.iterblockops(): - if op.opname == 'promote_virtualizable': + if op.opname == 'jit_force_virtualizable': res.append(op.args[-1].value) return res class BaseTest(BaseRtypingTest): - def test_generate_promote_virtualizable(self): + def test_generate_force_virtualizable(self): def fn(n): vinst = V(n) return vinst.v @@ -51,11 +51,11 @@ op_getfield = block.operations[-1] assert op_getfield.opname in ('getfield', 'oogetfield') v_inst = op_getfield.args[0] - assert op_promote.opname == 'promote_virtualizable' + assert op_promote.opname == 'jit_force_virtualizable' assert op_promote.args[0] is v_inst assert op_promote.args[-1].value == {} - def test_generate_promote_virtualizable_subclass(self): + def test_generate_force_virtualizable_subclass(self): def fn(n): V(n) # to attach v to V vinst = SubclassV(n) @@ -66,11 +66,11 @@ op_getfield = block.operations[-1] assert op_getfield.opname in ('getfield', 'oogetfield') v_inst = op_getfield.args[0] - assert op_promote.opname == 'promote_virtualizable' + assert op_promote.opname == 'jit_force_virtualizable' assert op_promote.args[0] is v_inst assert op_promote.args[-1].value == {} - def test_no_promote_virtualizable_for_other_fields(self): + def test_no_force_virtualizable_for_other_fields(self): def fn(n): vinst = V(n) return vinst.w @@ -81,7 +81,7 @@ assert op_getfield.opname in ('getfield', 'oogetfield') assert op_call.opname == 'direct_call' # to V.__init__ - def test_generate_promote_virtualizable_array(self): + def test_generate_force_virtualizable_array(self): def fn(n): vinst = VArray([n, n+1]) return vinst.lst[1] @@ -93,7 +93,7 @@ assert op_getarrayitem.opname == 'direct_call' # to ll_getitem_xxx assert op_getfield.opname in ('getfield', 'oogetfield') v_inst = op_getfield.args[0] - assert op_promote.opname == 'promote_virtualizable' + assert op_promote.opname == 'jit_force_virtualizable' assert op_promote.args[0] is v_inst assert op_promote.args[-1].value == {} @@ -130,13 +130,13 @@ TYPE = self.gettype(w_inst) assert 'virtualizable2_accessor' not in TYPE._hints - def replace_promote_virtualizable(self, rtyper, graphs): + def replace_force_virtualizable(self, rtyper, graphs): from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator graph = graphs[0] for block, op in graph.iterblockops(): - if op.opname == 'promote_virtualizable': + if op.opname == 'jit_force_virtualizable': v_inst_ll_type = op.args[0].concretetype break @@ -150,11 +150,10 @@ s_vinst = annmodel.SomeOOInstance(v_inst_ll_type) funcptr = annhelper.delayedfunction(mycall, [s_vinst], annmodel.s_None) annhelper.finish() - replace_promote_virtualizable_with_call(graphs, v_inst_ll_type, - funcptr) + replace_force_virtualizable_with_call(graphs, v_inst_ll_type, funcptr) return funcptr - def test_replace_promote_virtualizable_with_call(self): + def test_replace_force_virtualizable_with_call(self): def fn(n): vinst = V(n) return vinst.v @@ -162,7 +161,7 @@ block = graph.startblock op_getfield = block.operations[-1] assert op_getfield.opname in ('getfield', 'oogetfield') - funcptr = self.replace_promote_virtualizable(rtyper, [graph]) + funcptr = self.replace_force_virtualizable(rtyper, [graph]) if getattr(conftest.option, 'view', False): graph.show() op_promote = block.operations[-2] @@ -190,9 +189,9 @@ g_graph = t._graphof(g) expected = [{'access_directly': True}] * 3 - assert get_promote_virtualizable_flags(g_graph) == expected + assert get_force_virtualizable_flags(g_graph) == expected - self.replace_promote_virtualizable(typer, [g_graph]) + self.replace_force_virtualizable(typer, [g_graph]) assert summary(g_graph) == {self.GETFIELD: 2, self.SETFIELD: 1, 'int_add': 1} res = self.interpret(f, [23]) @@ -213,7 +212,7 @@ f_graph = t._graphof(f) g_graph = t._graphof(g) - self.replace_promote_virtualizable(typer, [f_graph, g_graph]) + self.replace_force_virtualizable(typer, [f_graph, g_graph]) t.checkgraphs() res = self.interpret(f, [23]) @@ -236,12 +235,12 @@ g_graphs.sort() assert g_graphs[0][0] is None - assert get_promote_virtualizable_flags(g_graphs[0][1]) == [{}] + assert get_force_virtualizable_flags(g_graphs[0][1]) == [{}] expected = [{'access_directly': True}] - assert get_promote_virtualizable_flags(g_graphs[1][1]) == expected + assert get_force_virtualizable_flags(g_graphs[1][1]) == expected - self.replace_promote_virtualizable(typer, [g_graphs[0][1], - g_graphs[1][1]]) + self.replace_force_virtualizable(typer, [g_graphs[0][1], + g_graphs[1][1]]) assert summary(g_graphs[0][1]) == {'direct_call': 1, self.GETFIELD: 1} assert summary(g_graphs[1][1]) == {self.GETFIELD: 1} @@ -276,8 +275,9 @@ assert summary(g_graphs[1][1]) == {self.SETFIELD: 1} h_graph = t._graphof(h) - assert summary(h_graph) == {'promote_virtualizable': 1, self.GETFIELD: 1} - assert get_promote_virtualizable_flags(h_graph) == [{}] + assert summary(h_graph) == {'jit_force_virtualizable': 1, + self.GETFIELD: 1} + assert get_force_virtualizable_flags(h_graph) == [{}] res = self.interpret(f, [23]) assert res == 23 @@ -303,7 +303,7 @@ t, typer, graph = self.gengraph(f, [int]) g_graph = t._graphof(A.g.im_func) - self.replace_promote_virtualizable(typer, [g_graph]) + self.replace_force_virtualizable(typer, [g_graph]) assert summary(g_graph) == {self.GETFIELD: 1, 'int_mul': 1} Modified: pypy/trunk/pypy/translator/c/funcgen.py ============================================================================== --- pypy/trunk/pypy/translator/c/funcgen.py (original) +++ pypy/trunk/pypy/translator/c/funcgen.py Mon Jan 4 18:41:45 2010 @@ -793,8 +793,12 @@ def OP_JIT_MARKER(self, op): return '/* JIT_MARKER %s */' % op - def OP_PROMOTE_VIRTUALIZABLE(self, op): - return '/* PROMOTE_VIRTUALIZABLE %s */' % op + def OP_JIT_FORCE_VIRTUALIZABLE(self, op): + return '/* JIT_FORCE_VIRTUALIZABLE %s */' % op + + def OP_JIT_FORCE_VIRTUAL(self, op): + return '%s = %s; /* JIT_FORCE_VIRTUAL */' % (self.expr(op.result), + self.expr(op.args[0])) def OP_GET_GROUP_MEMBER(self, op): typename = self.db.gettype(op.result.concretetype) Modified: pypy/trunk/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/trunk/pypy/translator/cli/opcodes.py (original) +++ pypy/trunk/pypy/translator/cli/opcodes.py Mon Jan 4 18:41:45 2010 @@ -84,7 +84,8 @@ 'debug_fatalerror': [PushAllArgs, 'call void [pypylib]pypy.runtime.Debug::DEBUG_FATALERROR(string)'], 'keepalive': Ignore, 'jit_marker': Ignore, - 'promote_virtualizable': Ignore, + 'jit_force_virtualizable': Ignore, + 'jit_force_virtual': DoNothing, } # __________ numeric operations __________ Modified: pypy/trunk/pypy/translator/jvm/opcodes.py ============================================================================== --- pypy/trunk/pypy/translator/jvm/opcodes.py (original) +++ pypy/trunk/pypy/translator/jvm/opcodes.py Mon Jan 4 18:41:45 2010 @@ -97,7 +97,8 @@ 'gc_set_max_heap_size': Ignore, 'resume_point': Ignore, 'jit_marker': Ignore, - 'promote_virtualizable': Ignore, + 'jit_force_virtualizable': Ignore, + 'jit_force_virtual': DoNothing, 'debug_assert': [], # TODO: implement? From afa at codespeak.net Mon Jan 4 19:48:48 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 4 Jan 2010 19:48:48 +0100 (CET) Subject: [pypy-svn] r70404 - pypy/trunk/pypy/lib/app_test Message-ID: <20100104184848.2FA30168032@codespeak.net> Author: afa Date: Mon Jan 4 19:48:47 2010 New Revision: 70404 Modified: pypy/trunk/pypy/lib/app_test/test_runpy.py Log: Fix test_runpy on Windows ('c:\temp' needs to be escaped correctly) Modified: pypy/trunk/pypy/lib/app_test/test_runpy.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/test_runpy.py (original) +++ pypy/trunk/pypy/lib/app_test/test_runpy.py Mon Jan 4 19:48:47 2010 @@ -102,7 +102,7 @@ if verbose: print " Next level in:", sub_dir pkg_fname = os.path.join(sub_dir, init_fname) pkg_file = open(pkg_fname, "w") - pkg_file.write("__path__ = ['%s']\n" % sub_dir) + pkg_file.write("__path__ = [%r]\n" % sub_dir) pkg_file.close() if verbose: print " Created:", pkg_fname mod_fname = os.path.join(sub_dir, test_fname) From arigo at codespeak.net Mon Jan 4 20:57:20 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 4 Jan 2010 20:57:20 +0100 (CET) Subject: [pypy-svn] r70405 - in pypy/trunk/pypy/jit/metainterp: . test Message-ID: <20100104195720.9AD40168039@codespeak.net> Author: arigo Date: Mon Jan 4 20:57:20 2010 New Revision: 70405 Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py Log: Constant-fold some paths, e.g. "if we_are_jitted:" paths, when producing jitcodes. Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/codewriter.py Mon Jan 4 20:57:20 2010 @@ -417,7 +417,6 @@ """Generate a constant of the given value. Returns its index in the list self.positions[]. """ - if constvalue is _we_are_jitted: constvalue = True const = Const._new(constvalue, self.cpu) return self.get_position(const) @@ -496,9 +495,22 @@ linkfalse, linktrue = block.exits if linkfalse.llexitcase == True: linkfalse, linktrue = linktrue, linkfalse + vpos = self.var_position(block.exitswitch) + # + # constant-fold an exitswitch + cv = self.get_constant_value(vpos) + if cv is not None: + if cv.value: + link = linktrue + else: + link = linkfalse + self.emit(*self.insert_renaming(link)) + self.make_bytecode_block(link.target) + return + # self.emit("goto_if_not", tlabel(linkfalse), - self.var_position(block.exitswitch)) + vpos) self.minimize_variables(argument_only=True, exitswitch=False) truerenaming = self.insert_renaming(linktrue) falserenaming = self.insert_renaming(linkfalse) @@ -818,15 +830,21 @@ self.serialize_op_same_as(op) def serialize_op_int_is_true(self, op): - if isinstance(op.args[0], Constant): - if op.args[0].value is objectmodel.malloc_zero_filled: + vpos = self.var_position(op.args[0]) + cv = self.get_constant_value(vpos) + if cv is not None: + if cv.value is objectmodel.malloc_zero_filled: # always True for now warmrunnerdesc = self.codewriter.metainterp_sd.warmrunnerdesc if warmrunnerdesc is not None: assert warmrunnerdesc.gcdescr.malloc_zero_filled self.var_positions[op.result] = self.var_position(Constant(1)) return - self.emit('int_is_true', self.var_position(op.args[0])) + if cv.value is _we_are_jitted: + # always True + self.var_positions[op.result] = self.var_position(Constant(1)) + return + self.emit('int_is_true', vpos) self.register_var(op.result) serialize_op_uint_is_true = serialize_op_int_is_true @@ -1612,6 +1630,14 @@ raise VirtualizableArrayField(self.graph) raise + def get_constant_value(self, vpos): + """Reverse of var_position(). Returns either None or a Constant.""" + if vpos & 1: + value = self.constants[vpos // 2].value + return Constant(value) + else: + return None + def emit(self, *stuff): self.assembler.extend(stuff) Modified: pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py Mon Jan 4 20:57:20 2010 @@ -2,6 +2,7 @@ from pypy.rlib import jit from pypy.jit.metainterp import support, typesystem from pypy.jit.metainterp.policy import JitPolicy +from pypy.jit.metainterp.history import ConstInt from pypy.jit.metainterp.codewriter import CodeWriter from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin from pypy.translator.translator import graphof @@ -476,6 +477,21 @@ # itself a copy of the call. assert 'residual_call' in jitcode._source + def test_we_are_jitted(self): + def f(): + if jit.we_are_jitted(): + return 55 + else: + return 66 + graphs = self.make_graphs(f, []) + cw = CodeWriter(self.rtyper) + cw.candidate_graphs = [graphs[0]] + cw._start(self.metainterp_sd, None) + jitcode = cw.make_one_bytecode((graphs[0], None), False) + assert 'goto_if_not' not in jitcode._source + assert ConstInt(55) in jitcode.constants + assert ConstInt(66) not in jitcode.constants + class ImmutableFieldsTests: From arigo at codespeak.net Mon Jan 4 21:19:58 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 4 Jan 2010 21:19:58 +0100 (CET) Subject: [pypy-svn] r70406 - pypy/branch/jit-trace Message-ID: <20100104201958.A4967168039@codespeak.net> Author: arigo Date: Mon Jan 4 21:19:56 2010 New Revision: 70406 Added: pypy/branch/jit-trace/ - copied from r70405, pypy/trunk/ Log: A branch in which to implement proper support for detecting and leaving the JIT in the case a sys.settrace() or similar is done. From arigo at codespeak.net Mon Jan 4 21:57:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 4 Jan 2010 21:57:40 +0100 (CET) Subject: [pypy-svn] r70407 - pypy/branch/jit-trace/pypy/rlib Message-ID: <20100104205740.3FA64168039@codespeak.net> Author: arigo Date: Mon Jan 4 21:57:39 2010 New Revision: 70407 Modified: pypy/branch/jit-trace/pypy/rlib/jit.py Log: Some code, but it seems that jit.force_virtualizable() does not need to be explicitly called after all. Modified: pypy/branch/jit-trace/pypy/rlib/jit.py ============================================================================== --- pypy/branch/jit-trace/pypy/rlib/jit.py (original) +++ pypy/branch/jit-trace/pypy/rlib/jit.py Mon Jan 4 21:57:39 2010 @@ -99,6 +99,25 @@ hop.exception_cannot_occur() return hop.inputconst(lltype.Signed, _we_are_jitted) + +##def force_virtualizable(virtualizable): +## pass + +##class Entry(ExtRegistryEntry): +## _about_ = force_virtualizable + +## def compute_result_annotation(self): +## from pypy.annotation import model as annmodel +## return annmodel.s_None + +## def specialize_call(self, hop): +## [vinst] = hop.inputargs(hop.args_r[0]) +## cname = inputconst(lltype.Void, None) +## cflags = inputconst(lltype.Void, {}) +## hop.exception_cannot_occur() +## return hop.genop('jit_force_virtualizable', [vinst, cname, cflags], +## resulttype=lltype.Void) + # ____________________________________________________________ # VRefs From arigo at codespeak.net Mon Jan 4 21:58:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 4 Jan 2010 21:58:10 +0100 (CET) Subject: [pypy-svn] r70408 - pypy/branch/jit-trace/pypy/interpreter Message-ID: <20100104205810.33707168039@codespeak.net> Author: arigo Date: Mon Jan 4 21:58:09 2010 New Revision: 70408 Modified: pypy/branch/jit-trace/pypy/interpreter/baseobjspace.py pypy/branch/jit-trace/pypy/interpreter/executioncontext.py pypy/branch/jit-trace/pypy/interpreter/pyframe.py Log: Some progress in detecting and leaving the JIT in case one of the tracing or profiling hooks gets set. Modified: pypy/branch/jit-trace/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/jit-trace/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/jit-trace/pypy/interpreter/baseobjspace.py Mon Jan 4 21:58:09 2010 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer -from pypy.rlib.jit import we_are_jitted, dont_look_inside, unroll_safe +from pypy.rlib.jit import we_are_jitted, unroll_safe import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -819,7 +819,6 @@ args = frame.make_arguments(nargs) return self.call_args(w_func, args) - @dont_look_inside def call_args_and_c_profile(self, frame, w_func, args): ec = self.getexecutioncontext() ec.c_call_trace(frame, w_func) Modified: pypy/branch/jit-trace/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/jit-trace/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/jit-trace/pypy/interpreter/executioncontext.py Mon Jan 4 21:58:09 2010 @@ -3,7 +3,6 @@ from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import LONG_BIT from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.jit import we_are_jitted from pypy.rlib import jit def app_profile_call(space, w_callable, frame, event, w_arg): @@ -22,10 +21,10 @@ # tracing: space.frame_trace_action.fire() must be called to ensure # that tracing occurs whenever self.w_tracefunc or self.is_tracing # is modified. - self.w_tracefunc = None + self.w_tracefunc = None # if not None, no JIT self.is_tracing = 0 self.compiler = space.createcompiler() - self.profilefunc = None + self.profilefunc = None # if not None, no JIT self.w_profilefuncarg = None def gettopframe(self): @@ -54,15 +53,17 @@ def leave(self, frame): try: - if self.profilefunc: - self._trace(frame, 'leaveframe', self.space.w_None) + if not jit.we_are_jitted(): + if self.profilefunc: + self._trace(frame, 'leaveframe', self.space.w_None) finally: self.topframeref = frame.f_backref self.framestackdepth -= 1 jit.virtual_ref_finish(frame) - if self.w_tracefunc is not None and not frame.hide(): - self.space.frame_trace_action.fire() + if not jit.we_are_jitted(): + if self.w_tracefunc is not None and not frame.hide(): + self.space.frame_trace_action.fire() # ________________________________________________________________ @@ -144,7 +145,6 @@ space.setitem(w_globals, w_key, w_value) return w_globals - @jit.dont_look_inside def c_call_trace(self, frame, w_func): "Profile the call of a builtin function" if self.profilefunc is None: @@ -152,7 +152,6 @@ else: self._trace(frame, 'c_call', w_func) - @jit.dont_look_inside def c_return_trace(self, frame, w_retval): "Profile the return from a builtin function" if self.profilefunc is None: @@ -160,7 +159,6 @@ else: self._trace(frame, 'c_return', w_retval) - @jit.dont_look_inside def c_exception_trace(self, frame, w_exc): "Profile function called upon OperationError." if self.profilefunc is None: @@ -168,7 +166,6 @@ else: self._trace(frame, 'c_exception', w_exc) - @jit.dont_look_inside def call_trace(self, frame): "Trace the call of a function" if self.w_tracefunc is not None or self.profilefunc is not None: @@ -176,7 +173,6 @@ if self.profilefunc: frame.is_being_profiled = True - @jit.dont_look_inside def return_trace(self, frame, w_retval): "Trace the return from a function" if self.w_tracefunc is not None: @@ -195,7 +191,6 @@ actionflag.action_dispatcher(self, frame) # slow path bytecode_trace._always_inline_ = True - @jit.dont_look_inside def exception_trace(self, frame, operationerr): "Trace function called upon OperationError." operationerr.record_interpreter_traceback() @@ -218,6 +213,7 @@ if self.space.is_w(w_func, self.space.w_None): self.w_tracefunc = None else: + self.force_all_frames() self.w_tracefunc = w_func self.space.frame_trace_action.fire() @@ -230,16 +226,27 @@ self.setllprofile(app_profile_call, w_func) def setllprofile(self, func, w_arg): - self.profilefunc = func if func is not None: if w_arg is None: raise ValueError("Cannot call setllprofile with real None") - frame = self.gettopframe_nohidden() - while frame: - frame.is_being_profiled = True - frame = self.getnextframe_nohidden(frame) + self.force_all_frames(is_being_profiled=True) + self.profilefunc = func self.w_profilefuncarg = w_arg + def force_all_frames(self, is_being_profiled=False): + # "Force" all frames in the sense of the jit, and optionally + # set the flag 'is_being_profiled' on them. A forced frame is + # one out of which the jit will exit: if it is running so far, + # in a piece of assembler currently running a CALL_MAY_FORCE, + # then being forced means that it will fail the following + # GUARD_NOT_FORCED operation, and so fall back to interpreted + # execution. + frame = self.gettopframe_nohidden() + while frame: + if is_being_profiled: + frame.is_being_profiled = True + frame = self.getnextframe_nohidden(frame) + def call_tracing(self, w_func, w_args): is_tracing = self.is_tracing self.is_tracing = 0 @@ -448,7 +455,7 @@ def fire_after_thread_switch(self): """Bit of a hack: fire() the action but only the next time the GIL - is released and re-acquired (i.e. after a portential thread switch). + is released and re-acquired (i.e. after a potential thread switch). Don't call this if threads are not enabled. """ from pypy.module.thread.gil import spacestate Modified: pypy/branch/jit-trace/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/jit-trace/pypy/interpreter/pyframe.py (original) +++ pypy/branch/jit-trace/pypy/interpreter/pyframe.py Mon Jan 4 21:58:09 2010 @@ -391,6 +391,7 @@ new_frame.instr_prev = space.int_w(w_instr_prev) self._setcellvars(cellvars) + # XXX what if the frame is in another thread?? space.frame_trace_action.fire() def hide(self): From arigo at codespeak.net Mon Jan 4 22:14:36 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 4 Jan 2010 22:14:36 +0100 (CET) Subject: [pypy-svn] r70409 - in pypy/branch/jit-trace/pypy: jit/metainterp jit/metainterp/test rlib Message-ID: <20100104211436.E7551168039@codespeak.net> Author: arigo Date: Mon Jan 4 22:14:36 2010 New Revision: 70409 Modified: pypy/branch/jit-trace/pypy/jit/metainterp/test/test_basic.py pypy/branch/jit-trace/pypy/jit/metainterp/warmspot.py pypy/branch/jit-trace/pypy/jit/metainterp/warmstate.py pypy/branch/jit-trace/pypy/rlib/jit.py Log: Add a callback to JitDriver. Modified: pypy/branch/jit-trace/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/jit-trace/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/jit-trace/pypy/jit/metainterp/test/test_basic.py Mon Jan 4 22:14:36 2010 @@ -385,6 +385,26 @@ res = self.meta_interp(f, [55]) assert res == -1 + def test_confirm_enter_jit(self): + def confirm_enter_jit(x): + return x <= 5 + myjitdriver = JitDriver(greens = ['x'], reds = ['y'], + confirm_enter_jit = confirm_enter_jit) + def f(x, y): + while y >= 0: + myjitdriver.can_enter_jit(x=x, y=y) + myjitdriver.jit_merge_point(x=x, y=y) + y -= x + return y + # + res = self.meta_interp(f, [10, 84]) + assert res == -6 + self.check_loop_count(0) + # + res = self.meta_interp(f, [3, 19]) + assert res == -2 + self.check_loop_count(1) + def test_format(self): def f(n): return len("<%d>" % n) Modified: pypy/branch/jit-trace/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/jit-trace/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/jit-trace/pypy/jit/metainterp/warmspot.py Mon Jan 4 22:14:36 2010 @@ -402,6 +402,8 @@ annhelper, self.jitdriver.can_inline, annmodel.s_Bool) self.get_printable_location_ptr = self._make_hook_graph( annhelper, self.jitdriver.get_printable_location, s_Str) + self.confirm_enter_jit_ptr = self._make_hook_graph( + annhelper, self.jitdriver.confirm_enter_jit, annmodel.s_Bool) annhelper.finish() def _make_hook_graph(self, annhelper, func, s_result, s_first_arg=None): Modified: pypy/branch/jit-trace/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/branch/jit-trace/pypy/jit/metainterp/warmstate.py (original) +++ pypy/branch/jit-trace/pypy/jit/metainterp/warmstate.py Mon Jan 4 22:14:36 2010 @@ -196,6 +196,7 @@ get_jitcell = self.make_jitcell_getter() set_future_values = self.make_set_future_values() self.make_jitdriver_callbacks() + confirm_enter_jit = self.confirm_enter_jit def maybe_compile_and_run(*args): """Entry point to the JIT. Called at the point with the @@ -227,6 +228,9 @@ cell.counter = n return # bound reached; start tracing + if not confirm_enter_jit(*greenargs): + cell.counter = 0 + return from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) try: @@ -237,6 +241,8 @@ self.disable_noninlinable_function(metainterp) raise else: + if not confirm_enter_jit(*greenargs): + return # machine code was already compiled for these greenargs # get the assembler and fill in the boxes set_future_values(*args[num_green_args:]) @@ -465,7 +471,6 @@ greenargs = unwrap_greenkey(greenkey) return can_inline(*greenargs) self.can_inline_callable = can_inline_greenkey - # get_location_ptr = self.warmrunnerdesc.get_printable_location_ptr if get_location_ptr is None: @@ -483,3 +488,16 @@ res = hlstr(res) return res self.get_location_str = get_location_str + # + confirm_enter_jit_ptr = self.warmrunnerdesc.confirm_enter_jit_ptr + if confirm_enter_jit_ptr is None: + def confirm_enter_jit(*greenargs): + return True + else: + rtyper = self.warmrunnerdesc.rtyper + # + def confirm_enter_jit(*greenargs): + fn = support.maybe_on_top_of_llinterp(rtyper, + confirm_enter_jit_ptr) + return fn(*greenargs) + self.confirm_enter_jit = confirm_enter_jit Modified: pypy/branch/jit-trace/pypy/rlib/jit.py ============================================================================== --- pypy/branch/jit-trace/pypy/rlib/jit.py (original) +++ pypy/branch/jit-trace/pypy/rlib/jit.py Mon Jan 4 22:14:36 2010 @@ -215,6 +215,7 @@ def __init__(self, greens=None, reds=None, virtualizables=None, get_jitcell_at=None, set_jitcell_at=None, can_inline=None, get_printable_location=None, + confirm_enter_jit=None, leave=None): # XXX 'leave' is deprecated if greens is not None: self.greens = greens @@ -232,6 +233,7 @@ self.set_jitcell_at = set_jitcell_at self.get_printable_location = get_printable_location self.can_inline = can_inline + self.confirm_enter_jit = confirm_enter_jit self.leave = leave def _freeze_(self): From arigo at codespeak.net Mon Jan 4 22:22:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 4 Jan 2010 22:22:55 +0100 (CET) Subject: [pypy-svn] r70410 - in pypy/branch/jit-trace/pypy: jit/metainterp jit/metainterp/test module/pypyjit Message-ID: <20100104212255.9EE2D168039@codespeak.net> Author: arigo Date: Mon Jan 4 22:22:55 2010 New Revision: 70410 Modified: pypy/branch/jit-trace/pypy/jit/metainterp/test/test_basic.py pypy/branch/jit-trace/pypy/jit/metainterp/warmspot.py pypy/branch/jit-trace/pypy/jit/metainterp/warmstate.py pypy/branch/jit-trace/pypy/module/pypyjit/interp_jit.py Log: Implement confirm_enter_jit() in interp_jit.py. Modified: pypy/branch/jit-trace/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/jit-trace/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/jit-trace/pypy/jit/metainterp/test/test_basic.py Mon Jan 4 22:22:55 2010 @@ -386,7 +386,7 @@ assert res == -1 def test_confirm_enter_jit(self): - def confirm_enter_jit(x): + def confirm_enter_jit(x, y): return x <= 5 myjitdriver = JitDriver(greens = ['x'], reds = ['y'], confirm_enter_jit = confirm_enter_jit) Modified: pypy/branch/jit-trace/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/jit-trace/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/jit-trace/pypy/jit/metainterp/warmspot.py Mon Jan 4 22:22:55 2010 @@ -403,10 +403,12 @@ self.get_printable_location_ptr = self._make_hook_graph( annhelper, self.jitdriver.get_printable_location, s_Str) self.confirm_enter_jit_ptr = self._make_hook_graph( - annhelper, self.jitdriver.confirm_enter_jit, annmodel.s_Bool) + annhelper, self.jitdriver.confirm_enter_jit, annmodel.s_Bool, + onlygreens=False) annhelper.finish() - def _make_hook_graph(self, annhelper, func, s_result, s_first_arg=None): + def _make_hook_graph(self, annhelper, func, s_result, s_first_arg=None, + onlygreens=True): if func is None: return None # @@ -414,7 +416,9 @@ if s_first_arg is not None: extra_args_s.append(s_first_arg) # - args_s = self.portal_args_s[:len(self.green_args_spec)] + args_s = self.portal_args_s + if onlygreens: + args_s = args_s[:len(self.green_args_spec)] graph = annhelper.getgraph(func, extra_args_s + args_s, s_result) funcptr = annhelper.graph2delayed(graph) return funcptr Modified: pypy/branch/jit-trace/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/branch/jit-trace/pypy/jit/metainterp/warmstate.py (original) +++ pypy/branch/jit-trace/pypy/jit/metainterp/warmstate.py Mon Jan 4 22:22:55 2010 @@ -228,7 +228,7 @@ cell.counter = n return # bound reached; start tracing - if not confirm_enter_jit(*greenargs): + if not confirm_enter_jit(*args): cell.counter = 0 return from pypy.jit.metainterp.pyjitpl import MetaInterp @@ -241,7 +241,7 @@ self.disable_noninlinable_function(metainterp) raise else: - if not confirm_enter_jit(*greenargs): + if not confirm_enter_jit(*args): return # machine code was already compiled for these greenargs # get the assembler and fill in the boxes @@ -491,13 +491,13 @@ # confirm_enter_jit_ptr = self.warmrunnerdesc.confirm_enter_jit_ptr if confirm_enter_jit_ptr is None: - def confirm_enter_jit(*greenargs): + def confirm_enter_jit(*args): return True else: rtyper = self.warmrunnerdesc.rtyper # - def confirm_enter_jit(*greenargs): + def confirm_enter_jit(*args): fn = support.maybe_on_top_of_llinterp(rtyper, confirm_enter_jit_ptr) - return fn(*greenargs) + return fn(*args) self.confirm_enter_jit = confirm_enter_jit Modified: pypy/branch/jit-trace/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/jit-trace/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/jit-trace/pypy/module/pypyjit/interp_jit.py Mon Jan 4 22:22:55 2010 @@ -41,6 +41,11 @@ def set_jitcell_at(newcell, next_instr, bytecode): bytecode.jit_cells[next_instr] = newcell +def confirm_enter_jit(next_instr, bytecode, frame, ec): + return (frame.w_f_trace is None and + ec.profilefunc is None and + ec.w_tracefunc is None) + class PyPyJitDriver(JitDriver): reds = ['frame', 'ec'] @@ -58,7 +63,8 @@ pypyjitdriver = PyPyJitDriver(can_inline = can_inline, get_printable_location = get_printable_location, get_jitcell_at = get_jitcell_at, - set_jitcell_at = set_jitcell_at) + set_jitcell_at = set_jitcell_at, + confirm_enter_jit = confirm_enter_jit) class __extend__(PyFrame): From arigo at codespeak.net Tue Jan 5 10:59:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 5 Jan 2010 10:59:27 +0100 (CET) Subject: [pypy-svn] r70411 - pypy/trunk/pypy/translator/c/test Message-ID: <20100105095927.6415816803B@codespeak.net> Author: arigo Date: Tue Jan 5 10:59:25 2010 New Revision: 70411 Modified: pypy/trunk/pypy/translator/c/test/test_genc.py Log: Add a gc.collect() as a tentative to avoid random occasional failure of that test. Modified: pypy/trunk/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_genc.py (original) +++ pypy/trunk/pypy/translator/c/test/test_genc.py Tue Jan 5 10:59:25 2010 @@ -334,6 +334,7 @@ f = compile(prob_with_pyobj, [object]) from sys import getrefcount as g obj = None + import gc; gc.collect() before = g(obj) f(obj) after = g(obj) From arigo at codespeak.net Tue Jan 5 11:01:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 5 Jan 2010 11:01:17 +0100 (CET) Subject: [pypy-svn] r70412 - pypy/trunk/pypy/interpreter/test Message-ID: <20100105100117.4FED216803B@codespeak.net> Author: arigo Date: Tue Jan 5 11:01:16 2010 New Revision: 70412 Modified: pypy/trunk/pypy/interpreter/test/test_module.py Log: Another try to fix this test for Windows. Modified: pypy/trunk/pypy/interpreter/test/test_module.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_module.py (original) +++ pypy/trunk/pypy/interpreter/test/test_module.py Tue Jan 5 11:01:16 2010 @@ -58,7 +58,7 @@ r = repr(_pypy_interact) assert (r.startswith("')) nofile = type(_pypy_interact)('nofile', 'foo') assert repr(nofile) == "" From arigo at codespeak.net Tue Jan 5 11:17:29 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 5 Jan 2010 11:17:29 +0100 (CET) Subject: [pypy-svn] r70413 - pypy/branch/virtual-forcing Message-ID: <20100105101729.22F3716803B@codespeak.net> Author: arigo Date: Tue Jan 5 11:17:28 2010 New Revision: 70413 Removed: pypy/branch/virtual-forcing/ Log: Remove merged branch. From arigo at codespeak.net Tue Jan 5 12:29:14 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 5 Jan 2010 12:29:14 +0100 (CET) Subject: [pypy-svn] r70414 - pypy/branch/jit-trace/pypy/jit/metainterp/test Message-ID: <20100105112914.13C9816803B@codespeak.net> Author: arigo Date: Tue Jan 5 12:29:14 2010 New Revision: 70414 Modified: pypy/branch/jit-trace/pypy/jit/metainterp/test/test_warmstate.py Log: Fix test. Modified: pypy/branch/jit-trace/pypy/jit/metainterp/test/test_warmstate.py ============================================================================== --- pypy/branch/jit-trace/pypy/jit/metainterp/test/test_warmstate.py (original) +++ pypy/branch/jit-trace/pypy/jit/metainterp/test/test_warmstate.py Tue Jan 5 12:29:14 2010 @@ -165,6 +165,7 @@ class FakeWarmRunnerDesc: can_inline_ptr = None get_printable_location_ptr = None + confirm_enter_jit_ptr = None green_args_spec = [lltype.Signed, lltype.Float] class FakeCell: dont_trace_here = False @@ -192,6 +193,7 @@ green_args_spec = [lltype.Signed, lltype.Float] can_inline_ptr = llhelper(CAN_INLINE, can_inline) get_printable_location_ptr = None + confirm_enter_jit_ptr = None state = WarmEnterState(FakeWarmRunnerDesc()) def jit_getter(*args): return FakeCell() @@ -212,7 +214,27 @@ green_args_spec = [lltype.Signed, lltype.Float] can_inline_ptr = None get_printable_location_ptr = llhelper(GET_LOCATION, get_location) + confirm_enter_jit_ptr = None state = WarmEnterState(FakeWarmRunnerDesc()) state.make_jitdriver_callbacks() res = state.get_location_str([BoxInt(5), BoxFloat(42.5)]) assert res == "hi there" + +def test_make_jitdriver_callbacks_4(): + def confirm_enter_jit(x, y, z): + assert x == 5 + assert y == 42.5 + assert z == 3 + return True + ENTER_JIT = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Float, + lltype.Signed], lltype.Bool)) + class FakeWarmRunnerDesc: + rtyper = None + green_args_spec = [lltype.Signed, lltype.Float] + can_inline_ptr = None + get_printable_location_ptr = None + confirm_enter_jit_ptr = llhelper(ENTER_JIT, confirm_enter_jit) + state = WarmEnterState(FakeWarmRunnerDesc()) + state.make_jitdriver_callbacks() + res = state.confirm_enter_jit(5, 42.5, 3) + assert res is True From arigo at codespeak.net Tue Jan 5 12:31:21 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 5 Jan 2010 12:31:21 +0100 (CET) Subject: [pypy-svn] r70415 - in pypy/trunk/pypy: interpreter jit/metainterp jit/metainterp/test module/pypyjit rlib Message-ID: <20100105113121.2D23016803B@codespeak.net> Author: arigo Date: Tue Jan 5 12:31:20 2010 New Revision: 70415 Modified: pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/interpreter/executioncontext.py pypy/trunk/pypy/interpreter/pyframe.py pypy/trunk/pypy/jit/metainterp/test/test_basic.py pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py pypy/trunk/pypy/jit/metainterp/warmspot.py pypy/trunk/pypy/jit/metainterp/warmstate.py pypy/trunk/pypy/module/pypyjit/interp_jit.py pypy/trunk/pypy/rlib/jit.py Log: Merge the branch/jit-trace, trying to be safe JIT-wise against using the profile or tracing hooks. Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Tue Jan 5 12:31:20 2010 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer -from pypy.rlib.jit import we_are_jitted, dont_look_inside, unroll_safe +from pypy.rlib.jit import we_are_jitted, unroll_safe import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -819,7 +819,6 @@ args = frame.make_arguments(nargs) return self.call_args(w_func, args) - @dont_look_inside def call_args_and_c_profile(self, frame, w_func, args): ec = self.getexecutioncontext() ec.c_call_trace(frame, w_func) Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Tue Jan 5 12:31:20 2010 @@ -3,7 +3,6 @@ from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import LONG_BIT from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.jit import we_are_jitted from pypy.rlib import jit def app_profile_call(space, w_callable, frame, event, w_arg): @@ -22,10 +21,10 @@ # tracing: space.frame_trace_action.fire() must be called to ensure # that tracing occurs whenever self.w_tracefunc or self.is_tracing # is modified. - self.w_tracefunc = None + self.w_tracefunc = None # if not None, no JIT self.is_tracing = 0 self.compiler = space.createcompiler() - self.profilefunc = None + self.profilefunc = None # if not None, no JIT self.w_profilefuncarg = None def gettopframe(self): @@ -54,15 +53,17 @@ def leave(self, frame): try: - if self.profilefunc: - self._trace(frame, 'leaveframe', self.space.w_None) + if not jit.we_are_jitted(): + if self.profilefunc: + self._trace(frame, 'leaveframe', self.space.w_None) finally: self.topframeref = frame.f_backref self.framestackdepth -= 1 jit.virtual_ref_finish(frame) - if self.w_tracefunc is not None and not frame.hide(): - self.space.frame_trace_action.fire() + if not jit.we_are_jitted(): + if self.w_tracefunc is not None and not frame.hide(): + self.space.frame_trace_action.fire() # ________________________________________________________________ @@ -144,7 +145,6 @@ space.setitem(w_globals, w_key, w_value) return w_globals - @jit.dont_look_inside def c_call_trace(self, frame, w_func): "Profile the call of a builtin function" if self.profilefunc is None: @@ -152,7 +152,6 @@ else: self._trace(frame, 'c_call', w_func) - @jit.dont_look_inside def c_return_trace(self, frame, w_retval): "Profile the return from a builtin function" if self.profilefunc is None: @@ -160,7 +159,6 @@ else: self._trace(frame, 'c_return', w_retval) - @jit.dont_look_inside def c_exception_trace(self, frame, w_exc): "Profile function called upon OperationError." if self.profilefunc is None: @@ -168,7 +166,6 @@ else: self._trace(frame, 'c_exception', w_exc) - @jit.dont_look_inside def call_trace(self, frame): "Trace the call of a function" if self.w_tracefunc is not None or self.profilefunc is not None: @@ -176,7 +173,6 @@ if self.profilefunc: frame.is_being_profiled = True - @jit.dont_look_inside def return_trace(self, frame, w_retval): "Trace the return from a function" if self.w_tracefunc is not None: @@ -195,7 +191,6 @@ actionflag.action_dispatcher(self, frame) # slow path bytecode_trace._always_inline_ = True - @jit.dont_look_inside def exception_trace(self, frame, operationerr): "Trace function called upon OperationError." operationerr.record_interpreter_traceback() @@ -218,6 +213,7 @@ if self.space.is_w(w_func, self.space.w_None): self.w_tracefunc = None else: + self.force_all_frames() self.w_tracefunc = w_func self.space.frame_trace_action.fire() @@ -230,16 +226,27 @@ self.setllprofile(app_profile_call, w_func) def setllprofile(self, func, w_arg): - self.profilefunc = func if func is not None: if w_arg is None: raise ValueError("Cannot call setllprofile with real None") - frame = self.gettopframe_nohidden() - while frame: - frame.is_being_profiled = True - frame = self.getnextframe_nohidden(frame) + self.force_all_frames(is_being_profiled=True) + self.profilefunc = func self.w_profilefuncarg = w_arg + def force_all_frames(self, is_being_profiled=False): + # "Force" all frames in the sense of the jit, and optionally + # set the flag 'is_being_profiled' on them. A forced frame is + # one out of which the jit will exit: if it is running so far, + # in a piece of assembler currently running a CALL_MAY_FORCE, + # then being forced means that it will fail the following + # GUARD_NOT_FORCED operation, and so fall back to interpreted + # execution. + frame = self.gettopframe_nohidden() + while frame: + if is_being_profiled: + frame.is_being_profiled = True + frame = self.getnextframe_nohidden(frame) + def call_tracing(self, w_func, w_args): is_tracing = self.is_tracing self.is_tracing = 0 @@ -448,7 +455,7 @@ def fire_after_thread_switch(self): """Bit of a hack: fire() the action but only the next time the GIL - is released and re-acquired (i.e. after a portential thread switch). + is released and re-acquired (i.e. after a potential thread switch). Don't call this if threads are not enabled. """ from pypy.module.thread.gil import spacestate Modified: pypy/trunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/pypy/interpreter/pyframe.py Tue Jan 5 12:31:20 2010 @@ -391,6 +391,7 @@ new_frame.instr_prev = space.int_w(w_instr_prev) self._setcellvars(cellvars) + # XXX what if the frame is in another thread?? space.frame_trace_action.fire() def hide(self): Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_basic.py Tue Jan 5 12:31:20 2010 @@ -385,6 +385,26 @@ res = self.meta_interp(f, [55]) assert res == -1 + def test_confirm_enter_jit(self): + def confirm_enter_jit(x, y): + return x <= 5 + myjitdriver = JitDriver(greens = ['x'], reds = ['y'], + confirm_enter_jit = confirm_enter_jit) + def f(x, y): + while y >= 0: + myjitdriver.can_enter_jit(x=x, y=y) + myjitdriver.jit_merge_point(x=x, y=y) + y -= x + return y + # + res = self.meta_interp(f, [10, 84]) + assert res == -6 + self.check_loop_count(0) + # + res = self.meta_interp(f, [3, 19]) + assert res == -2 + self.check_loop_count(1) + def test_format(self): def f(n): return len("<%d>" % n) Modified: pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py Tue Jan 5 12:31:20 2010 @@ -165,6 +165,7 @@ class FakeWarmRunnerDesc: can_inline_ptr = None get_printable_location_ptr = None + confirm_enter_jit_ptr = None green_args_spec = [lltype.Signed, lltype.Float] class FakeCell: dont_trace_here = False @@ -192,6 +193,7 @@ green_args_spec = [lltype.Signed, lltype.Float] can_inline_ptr = llhelper(CAN_INLINE, can_inline) get_printable_location_ptr = None + confirm_enter_jit_ptr = None state = WarmEnterState(FakeWarmRunnerDesc()) def jit_getter(*args): return FakeCell() @@ -212,7 +214,27 @@ green_args_spec = [lltype.Signed, lltype.Float] can_inline_ptr = None get_printable_location_ptr = llhelper(GET_LOCATION, get_location) + confirm_enter_jit_ptr = None state = WarmEnterState(FakeWarmRunnerDesc()) state.make_jitdriver_callbacks() res = state.get_location_str([BoxInt(5), BoxFloat(42.5)]) assert res == "hi there" + +def test_make_jitdriver_callbacks_4(): + def confirm_enter_jit(x, y, z): + assert x == 5 + assert y == 42.5 + assert z == 3 + return True + ENTER_JIT = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Float, + lltype.Signed], lltype.Bool)) + class FakeWarmRunnerDesc: + rtyper = None + green_args_spec = [lltype.Signed, lltype.Float] + can_inline_ptr = None + get_printable_location_ptr = None + confirm_enter_jit_ptr = llhelper(ENTER_JIT, confirm_enter_jit) + state = WarmEnterState(FakeWarmRunnerDesc()) + state.make_jitdriver_callbacks() + res = state.confirm_enter_jit(5, 42.5, 3) + assert res is True Modified: pypy/trunk/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/warmspot.py (original) +++ pypy/trunk/pypy/jit/metainterp/warmspot.py Tue Jan 5 12:31:20 2010 @@ -402,9 +402,13 @@ annhelper, self.jitdriver.can_inline, annmodel.s_Bool) self.get_printable_location_ptr = self._make_hook_graph( annhelper, self.jitdriver.get_printable_location, s_Str) + self.confirm_enter_jit_ptr = self._make_hook_graph( + annhelper, self.jitdriver.confirm_enter_jit, annmodel.s_Bool, + onlygreens=False) annhelper.finish() - def _make_hook_graph(self, annhelper, func, s_result, s_first_arg=None): + def _make_hook_graph(self, annhelper, func, s_result, s_first_arg=None, + onlygreens=True): if func is None: return None # @@ -412,7 +416,9 @@ if s_first_arg is not None: extra_args_s.append(s_first_arg) # - args_s = self.portal_args_s[:len(self.green_args_spec)] + args_s = self.portal_args_s + if onlygreens: + args_s = args_s[:len(self.green_args_spec)] graph = annhelper.getgraph(func, extra_args_s + args_s, s_result) funcptr = annhelper.graph2delayed(graph) return funcptr Modified: pypy/trunk/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/warmstate.py (original) +++ pypy/trunk/pypy/jit/metainterp/warmstate.py Tue Jan 5 12:31:20 2010 @@ -196,6 +196,7 @@ get_jitcell = self.make_jitcell_getter() set_future_values = self.make_set_future_values() self.make_jitdriver_callbacks() + confirm_enter_jit = self.confirm_enter_jit def maybe_compile_and_run(*args): """Entry point to the JIT. Called at the point with the @@ -227,6 +228,9 @@ cell.counter = n return # bound reached; start tracing + if not confirm_enter_jit(*args): + cell.counter = 0 + return from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) try: @@ -237,6 +241,8 @@ self.disable_noninlinable_function(metainterp) raise else: + if not confirm_enter_jit(*args): + return # machine code was already compiled for these greenargs # get the assembler and fill in the boxes set_future_values(*args[num_green_args:]) @@ -465,7 +471,6 @@ greenargs = unwrap_greenkey(greenkey) return can_inline(*greenargs) self.can_inline_callable = can_inline_greenkey - # get_location_ptr = self.warmrunnerdesc.get_printable_location_ptr if get_location_ptr is None: @@ -483,3 +488,16 @@ res = hlstr(res) return res self.get_location_str = get_location_str + # + confirm_enter_jit_ptr = self.warmrunnerdesc.confirm_enter_jit_ptr + if confirm_enter_jit_ptr is None: + def confirm_enter_jit(*args): + return True + else: + rtyper = self.warmrunnerdesc.rtyper + # + def confirm_enter_jit(*args): + fn = support.maybe_on_top_of_llinterp(rtyper, + confirm_enter_jit_ptr) + return fn(*args) + self.confirm_enter_jit = confirm_enter_jit Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/trunk/pypy/module/pypyjit/interp_jit.py Tue Jan 5 12:31:20 2010 @@ -41,6 +41,11 @@ def set_jitcell_at(newcell, next_instr, bytecode): bytecode.jit_cells[next_instr] = newcell +def confirm_enter_jit(next_instr, bytecode, frame, ec): + return (frame.w_f_trace is None and + ec.profilefunc is None and + ec.w_tracefunc is None) + class PyPyJitDriver(JitDriver): reds = ['frame', 'ec'] @@ -58,7 +63,8 @@ pypyjitdriver = PyPyJitDriver(can_inline = can_inline, get_printable_location = get_printable_location, get_jitcell_at = get_jitcell_at, - set_jitcell_at = set_jitcell_at) + set_jitcell_at = set_jitcell_at, + confirm_enter_jit = confirm_enter_jit) class __extend__(PyFrame): Modified: pypy/trunk/pypy/rlib/jit.py ============================================================================== --- pypy/trunk/pypy/rlib/jit.py (original) +++ pypy/trunk/pypy/rlib/jit.py Tue Jan 5 12:31:20 2010 @@ -99,6 +99,25 @@ hop.exception_cannot_occur() return hop.inputconst(lltype.Signed, _we_are_jitted) + +##def force_virtualizable(virtualizable): +## pass + +##class Entry(ExtRegistryEntry): +## _about_ = force_virtualizable + +## def compute_result_annotation(self): +## from pypy.annotation import model as annmodel +## return annmodel.s_None + +## def specialize_call(self, hop): +## [vinst] = hop.inputargs(hop.args_r[0]) +## cname = inputconst(lltype.Void, None) +## cflags = inputconst(lltype.Void, {}) +## hop.exception_cannot_occur() +## return hop.genop('jit_force_virtualizable', [vinst, cname, cflags], +## resulttype=lltype.Void) + # ____________________________________________________________ # VRefs @@ -196,6 +215,7 @@ def __init__(self, greens=None, reds=None, virtualizables=None, get_jitcell_at=None, set_jitcell_at=None, can_inline=None, get_printable_location=None, + confirm_enter_jit=None, leave=None): # XXX 'leave' is deprecated if greens is not None: self.greens = greens @@ -213,6 +233,7 @@ self.set_jitcell_at = set_jitcell_at self.get_printable_location = get_printable_location self.can_inline = can_inline + self.confirm_enter_jit = confirm_enter_jit self.leave = leave def _freeze_(self): From arigo at codespeak.net Tue Jan 5 12:31:39 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 5 Jan 2010 12:31:39 +0100 (CET) Subject: [pypy-svn] r70416 - pypy/branch/jit-trace Message-ID: <20100105113139.7235716803B@codespeak.net> Author: arigo Date: Tue Jan 5 12:31:38 2010 New Revision: 70416 Removed: pypy/branch/jit-trace/ Log: Remove merged branch. From cfbolz at codespeak.net Wed Jan 6 12:16:19 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 6 Jan 2010 12:16:19 +0100 (CET) Subject: [pypy-svn] r70419 - pypy/trunk/pypy/interpreter Message-ID: <20100106111619.C201F168106@codespeak.net> Author: cfbolz Date: Wed Jan 6 12:16:18 2010 New Revision: 70419 Modified: pypy/trunk/pypy/interpreter/executioncontext.py Log: this function is unused Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Wed Jan 6 12:16:18 2010 @@ -136,15 +136,6 @@ else: return self.space.builtin - # XXX this one should probably be dropped in favor of a module - def make_standard_w_globals(self): - "Create a new empty 'globals' dictionary." - w_key = self.space.wrap("__builtins__") - w_value = self.space.wrap(self.get_builtin()) - w_globals = self.space.newdict() - space.setitem(w_globals, w_key, w_value) - return w_globals - def c_call_trace(self, frame, w_func): "Profile the call of a builtin function" if self.profilefunc is None: From cfbolz at codespeak.net Wed Jan 6 14:43:37 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 6 Jan 2010 14:43:37 +0100 (CET) Subject: [pypy-svn] r70420 - pypy/extradoc/planning Message-ID: <20100106134337.3B83B16810B@codespeak.net> Author: cfbolz Date: Wed Jan 6 14:43:35 2010 New Revision: 70420 Modified: pypy/extradoc/planning/jit.txt Log: those two seem to be done Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Wed Jan 6 14:43:35 2010 @@ -52,16 +52,10 @@ website and stability that need sorting out too. However, they are beyond the scope of this section) -required: -- merge the virtual-forcing branch (this might need implementing store sinking - to make the performance not suck) - wishlist: - improve on predictability: don't trace into signals ... but produce just a conditional call (or just abort the trace) - directly call assembler for residual portal calls -- we would like probably enabling sys.settrace() to leave the jit instead of - just being ignored - maybe think again about the recursion limit checking, which slows down calls quite a bit - since threads are enabled with the JIT, getexecutioncontext cannot be folded From arigo at codespeak.net Wed Jan 6 22:38:25 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 6 Jan 2010 22:38:25 +0100 (CET) Subject: [pypy-svn] r70421 - pypy/branch/morearraycopy Message-ID: <20100106213825.5ED6F168108@codespeak.net> Author: arigo Date: Wed Jan 6 22:38:23 2010 New Revision: 70421 Added: pypy/branch/morearraycopy/ - copied from r70420, pypy/trunk/ Log: A branch in which to play with using ll_arraycopy() more systematically in rpython/rlist.py and rpython/lltypesystem/rlist.py. From arigo at codespeak.net Wed Jan 6 23:26:18 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 6 Jan 2010 23:26:18 +0100 (CET) Subject: [pypy-svn] r70422 - in pypy/branch/morearraycopy/pypy/rpython: . lltypesystem test Message-ID: <20100106222618.9DC48168029@codespeak.net> Author: arigo Date: Wed Jan 6 23:26:18 2010 New Revision: 70422 Modified: pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py pypy/branch/morearraycopy/pypy/rpython/rlist.py pypy/branch/morearraycopy/pypy/rpython/test/test_rlist.py Log: Add an ADT method ll_copyitems(), and start using it for ll_copy(). Only on lltype for now. Modified: pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py ============================================================================== --- pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py (original) +++ pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py Wed Jan 6 23:26:18 2010 @@ -72,6 +72,7 @@ "ll_newemptylist": ll_fixed_newemptylist, "ll_length": ll_fixed_length, "ll_items": ll_fixed_items, + "ll_copyitems": ll_fixed_copyitems, "ITEM": ITEM, "ll_getitem_fast": ll_fixed_getitem_fast, "ll_setitem_fast": ll_fixed_setitem_fast, @@ -105,6 +106,7 @@ "ll_newemptylist": ll_newemptylist, "ll_length": ll_length, "ll_items": ll_items, + "ll_copyitems": ll_copyitems, "ITEM": ITEM, "ll_getitem_fast": ll_getitem_fast, "ll_setitem_fast": ll_setitem_fast, @@ -302,6 +304,9 @@ def ll_items(l): return l.items +def ll_copyitems(dst, dstindex, src, srcindex, length): + rgc.ll_arraycopy(src.ll_items(), dst.items, srcindex, dstindex, length) + def ll_getitem_fast(l, index): ll_assert(index < l.length, "getitem out of bounds") return l.ll_items()[index] @@ -332,6 +337,9 @@ def ll_fixed_items(l): return l +def ll_fixed_copyitems(dst, dstindex, src, srcindex, length): + rgc.ll_arraycopy(src.ll_items(), dst, srcindex, dstindex, length) + def ll_fixed_getitem_fast(l, index): ll_assert(index < len(l), "fixed getitem out of bounds") return l[index] Modified: pypy/branch/morearraycopy/pypy/rpython/rlist.py ============================================================================== --- pypy/branch/morearraycopy/pypy/rpython/rlist.py (original) +++ pypy/branch/morearraycopy/pypy/rpython/rlist.py Wed Jan 6 23:26:18 2010 @@ -17,6 +17,9 @@ 'll_length': (['self' ], Signed), 'll_getitem_fast': (['self', Signed ], 'item'), 'll_setitem_fast': (['self', Signed, 'item'], Void), + 'll_copyitems': (['self', Signed, None, Signed, Signed], Void), + # uses a catch-everything None because it can be + # either a fixed or a non-fixed list }) ADTIList = ADTInterface(ADTIFixedList, { '_ll_resize_ge': (['self', Signed ], Void), @@ -528,10 +531,7 @@ def ll_copy(RESLIST, l): length = l.ll_length() new_lst = RESLIST.ll_newlist(length) - i = 0 - while i < length: - new_lst.ll_setitem_fast(i, l.ll_getitem_fast(i)) - i += 1 + new_lst.ll_copyitems(0, l, 0, length) return new_lst def ll_len(l): Modified: pypy/branch/morearraycopy/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/branch/morearraycopy/pypy/rpython/test/test_rlist.py (original) +++ pypy/branch/morearraycopy/pypy/rpython/test/test_rlist.py Wed Jan 6 23:26:18 2010 @@ -410,13 +410,18 @@ assert res.item2 == 9 def test_bltn_list(self): - def dummyfn(): - l1 = [42] - l2 = list(l1) - l2[0] = 0 - return l1[0] - res = self.interpret(dummyfn, ()) - assert res == 42 + # test for ll_copy() + for resize1 in [False, True]: + for resize2 in [False, True]: + def dummyfn(): + l1 = [42] + if resize1: l1.append(43) + l2 = list(l1) + if resize2: l2.append(44) + l2[0] = 0 + return l1[0] + res = self.interpret(dummyfn, ()) + assert res == 42 def test_is_true(self): def is_true(lst): From cfbolz at codespeak.net Thu Jan 7 14:18:10 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 14:18:10 +0100 (CET) Subject: [pypy-svn] r70423 - in pypy/trunk/pypy/jit: backend/llgraph metainterp metainterp/test Message-ID: <20100107131810.8DE1D168102@codespeak.net> Author: cfbolz Date: Thu Jan 7 14:18:09 2010 New Revision: 70423 Modified: pypy/trunk/pypy/jit/backend/llgraph/llimpl.py pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Log: Tiny optimization: when forcing a virtual, don't generate code for setting fields to NULL, since malloc returns zero-filled objects. This works fine with the x86 backend, but needs a fix in the llgraph backend to actually zero the memory (at least for structs, arrays have always been zeroed). Modified: pypy/trunk/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/trunk/pypy/jit/backend/llgraph/llimpl.py Thu Jan 7 14:18:09 2010 @@ -1067,7 +1067,7 @@ else: # for tests, a random emulated ll_inst will do if Class not in _pseudo_exceptions: - ll_inst = lltype.malloc(rclass.OBJECT) + ll_inst = lltype.malloc(rclass.OBJECT, zero=True) ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) _pseudo_exceptions[Class] = LLException(ll_inst.typeptr, ll_inst) @@ -1209,7 +1209,7 @@ def do_new(size): TYPE = symbolic.Size2Type[size] - x = lltype.malloc(TYPE) + x = lltype.malloc(TYPE, zero=True) return cast_to_ptr(x) def do_new_array(arraynum, count): Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Thu Jan 7 14:18:09 2010 @@ -207,6 +207,8 @@ iteritems = list(iteritems) iteritems.sort(key = lambda (x,y): x.sort_key()) for ofs, value in iteritems: + if value.is_null(): + continue subbox = value.force_box() op = ResOperation(rop.SETFIELD_GC, [box, subbox], None, descr=ofs) @@ -293,6 +295,8 @@ for index in range(len(self._items)): subvalue = self._items[index] if subvalue is not self.constvalue: + if subvalue.is_null(): + continue subbox = subvalue.force_box() op = ResOperation(rop.SETARRAYITEM_GC, [box, ConstInt(index), subbox], None, Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Thu Jan 7 14:18:09 2010 @@ -925,6 +925,26 @@ """ self.optimize_loop(ops, 'Not', expected) + def test_nonvirtual_dont_write_null_fields_on_force(self): + ops = """ + [i] + p1 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1, i, descr=valuedescr) + i1 = getfield_gc(p1, descr=valuedescr) + setfield_gc(p1, 0, descr=valuedescr) + escape(p1) + i2 = getfield_gc(p1, descr=valuedescr) + jump(i2) + """ + expected = """ + [i] + p1 = new_with_vtable(ConstClass(node_vtable)) + escape(p1) + i2 = getfield_gc(p1, descr=valuedescr) + jump(i2) + """ + self.optimize_loop(ops, 'Not', expected) + def test_getfield_gc_pure_1(self): ops = """ [i] @@ -1025,6 +1045,24 @@ """ self.optimize_loop(ops, 'Not, Not', expected) + def test_nonvirtual_array_dont_write_null_fields_on_force(self): + ops = """ + [i1] + p1 = new_array(5, descr=arraydescr) + setarrayitem_gc(p1, 0, i1, descr=arraydescr) + setarrayitem_gc(p1, 1, 0, descr=arraydescr) + escape(p1) + jump(i1) + """ + expected = """ + [i1] + p1 = new_array(5, descr=arraydescr) + setarrayitem_gc(p1, 0, i1, descr=arraydescr) + escape(p1) + jump(i1) + """ + self.optimize_loop(ops, 'Not', expected) + def test_varray_2(self): ops = """ [i0, p1] From cfbolz at codespeak.net Thu Jan 7 14:24:58 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 14:24:58 +0100 (CET) Subject: [pypy-svn] r70424 - pypy/branch/change-celldict2 Message-ID: <20100107132458.B4C561680FF@codespeak.net> Author: cfbolz Date: Thu Jan 7 14:24:58 2010 New Revision: 70424 Added: pypy/branch/change-celldict2/ - copied from r70423, pypy/trunk/ Log: branch again to bring change-celldict up-to-date From cfbolz at codespeak.net Thu Jan 7 14:34:36 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 14:34:36 +0100 (CET) Subject: [pypy-svn] r70425 - in pypy/branch/change-celldict2/pypy: interpreter module/pypyjit/test objspace/std objspace/std/test Message-ID: <20100107133436.B48F11680FF@codespeak.net> Author: cfbolz Date: Thu Jan 7 14:34:36 2010 New Revision: 70425 Modified: pypy/branch/change-celldict2/pypy/interpreter/pycode.py pypy/branch/change-celldict2/pypy/module/pypyjit/test/test_pypy_c.py pypy/branch/change-celldict2/pypy/objspace/std/celldict.py pypy/branch/change-celldict2/pypy/objspace/std/objspace.py pypy/branch/change-celldict2/pypy/objspace/std/test/test_celldict.py Log: merge in changes from change-celldict Modified: pypy/branch/change-celldict2/pypy/interpreter/pycode.py ============================================================================== --- pypy/branch/change-celldict2/pypy/interpreter/pycode.py (original) +++ pypy/branch/change-celldict2/pypy/interpreter/pycode.py Thu Jan 7 14:34:36 2010 @@ -117,9 +117,6 @@ self._compute_flatcall() - if self.space.config.objspace.std.withcelldict: - from pypy.objspace.std.celldict import init_code - init_code(self) def _init_flags(self): co_code = self.co_code Modified: pypy/branch/change-celldict2/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/branch/change-celldict2/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/branch/change-celldict2/pypy/module/pypyjit/test/test_pypy_c.py Thu Jan 7 14:34:36 2010 @@ -210,21 +210,31 @@ def test_simple_call(self): self.run_source(''' + OFFSET = 0 def f(i): - return i + 1 + return i + 1 + OFFSET def main(n): i = 0 - while i < n: + while i < n+OFFSET: i = f(f(i)) return i - ''', 76, + ''', 96, ([20], 20), ([31], 32)) ops = self.get_by_bytecode("LOAD_GLOBAL") - assert len(ops) == 2 - assert ops[0].get_opnames() == ["getfield_gc", "getarrayitem_gc", + assert len(ops) == 5 + assert ops[0].get_opnames() == ["getfield_gc", "guard_value", + "getfield_gc", "guard_isnull", "getfield_gc", "guard_nonnull_class"] - assert not ops[1] # second LOAD_GLOBAL folded away + # the second getfield on the same globals is quicker + assert ops[1].get_opnames() == ["getfield_gc", "guard_nonnull_class"] + assert not ops[2] # second LOAD_GLOBAL of the same name folded away + # LOAD_GLOBAL of the same name but in different function partially + # folded away + # XXX could be improved + assert ops[3].get_opnames() == ["guard_value", + "getfield_gc", "guard_isnull"] + assert not ops[4] ops = self.get_by_bytecode("CALL_FUNCTION") assert len(ops) == 2 for bytecode in ops: @@ -281,7 +291,7 @@ while i < n: i = f(f(i), j=1) return i - ''', 98, + ''', 100, ([20], 20), ([31], 32)) ops = self.get_by_bytecode("CALL_FUNCTION") @@ -305,7 +315,7 @@ a.x = 2 i = i + a.x return i - ''', 63, + ''', 65, ([20], 20), ([31], 32)) Modified: pypy/branch/change-celldict2/pypy/objspace/std/celldict.py ============================================================================== --- pypy/branch/change-celldict2/pypy/objspace/std/celldict.py (original) +++ pypy/branch/change-celldict2/pypy/objspace/std/celldict.py Thu Jan 7 14:34:36 2010 @@ -1,4 +1,8 @@ -from pypy.interpreter.pycode import CO_CONTAINSGLOBALS +""" A very simple cell dict implementation. The dictionary maps keys to cell. +This ensures that the function (dict, key) -> cell is pure. By itself, this +optimization is not helping at all, but in conjunction with the JIT it can +speed up global lookups a lot.""" + from pypy.objspace.std.dictmultiobject import IteratorImplementation from pypy.objspace.std.dictmultiobject import W_DictMultiObject, _is_sane_hash from pypy.rlib import jit @@ -19,31 +23,22 @@ def __init__(self, space): self.space = space self.content = {} - self.unshadowed_builtins = {} - def getcell(self, key, make_new=True): + def getcell(self, key, makenew): + if makenew or jit.we_are_jitted(): + # when we are jitting, we always go through the pure function + # below, to ensure that we have no residual dict lookup + return self._getcell_makenew(key) + return self.content.get(key, None) + + @jit.purefunction_promote + def _getcell_makenew(self, key): res = self.content.get(key, None) if res is not None: return res - if not make_new: - return None result = self.content[key] = ModuleCell() return result - def add_unshadowed_builtin(self, name, builtin_impl): - assert isinstance(builtin_impl, ModuleDictImplementation) - self.unshadowed_builtins[name] = builtin_impl - - def invalidate_unshadowed_builtin(self, name): - impl = self.unshadowed_builtins[name] - try: - cell = impl.content[name] - except KeyError: - pass - else: - w_value = cell.invalidate() - cell = impl.content[name] = ModuleCell(w_value) - def impl_setitem(self, w_key, w_value): space = self.space if space.is_w(space.type(w_key), space.w_str): @@ -52,11 +47,7 @@ self._as_rdict().setitem(w_key, w_value) def impl_setitem_str(self, name, w_value, shadows_type=True): - self.getcell(name).w_value = w_value - - if name in self.unshadowed_builtins: - self.invalidate_unshadowed_builtin(name) - del self.unshadowed_builtins[name] + self.getcell(name, True).w_value = w_value def impl_delitem(self, w_key): space = self.space @@ -64,17 +55,25 @@ if space.is_w(w_key_type, space.w_str): key = space.str_w(w_key) cell = self.getcell(key, False) - if cell is None: + if cell is None or cell.w_value is None: raise KeyError + # note that we don't remove the cell from self.content, to make + # sure that a key that was found at any point in the dict, still + # maps to the same cell later (even if this cell no longer + # represents a key) cell.invalidate() - del self.content[key] elif _is_sane_hash(space, w_key_type): raise KeyError else: self._as_rdict().delitem(w_key) def impl_length(self): - return len(self.content) + # inefficient, but do we care? + res = 0 + for cell in self.content.itervalues(): + if cell.w_value is not None: + res += 1 + return res def impl_getitem(self, w_lookup): space = self.space @@ -91,6 +90,7 @@ res = self.getcell(lookup, False) if res is None: return None + # note that even if the res.w_value is None, the next line is fine return res.w_value def impl_iter(self): @@ -98,39 +98,34 @@ def impl_keys(self): space = self.space - return [space.wrap(key) for key in self.content.iterkeys()] + return [space.wrap(key) for key, cell in self.content.iteritems() + if cell.w_value is not None] def impl_values(self): - return [cell.w_value for cell in self.content.itervalues()] + return [cell.w_value for cell in self.content.itervalues() + if cell.w_value is not None] def impl_items(self): space = self.space return [space.newtuple([space.wrap(key), cell.w_value]) - for (key, cell) in self.content.iteritems()] + for (key, cell) in self.content.iteritems() + if cell.w_value is not None] def impl_clear(self): - # inefficient, but who cares for k, cell in self.content.iteritems(): cell.invalidate() - for k in self.unshadowed_builtins: - self.invalidate_unshadowed_builtin(k) - self.content.clear() - self.unshadowed_builtins.clear() - def _as_rdict(self): r_dict_content = self.initialize_as_rdict() for k, cell in self.content.iteritems(): - r_dict_content[self.space.wrap(k)] = cell.w_value + if cell.w_value is not None: + r_dict_content[self.space.wrap(k)] = cell.w_value cell.invalidate() - for k in self.unshadowed_builtins: - self.invalidate_unshadowed_builtin(k) self._clear_fields() return self def _clear_fields(self): self.content = None - self.unshadowed_builtins = None class ModuleDictIteratorImplementation(IteratorImplementation): def __init__(self, space, dictimplementation): @@ -138,99 +133,8 @@ self.iterator = dictimplementation.content.iteritems() def next_entry(self): - # note that this 'for' loop only runs once, at most for key, cell in self.iterator: - return (self.space.wrap(key), cell.w_value) + if cell.w_value is not None: + return (self.space.wrap(key), cell.w_value) else: return None, None - - -class State(object): - def __init__(self, space): - self.space = space - self.invalidcell = ModuleCell() - self.always_invalid_cache = [] - self.neverused_dictcontent = {} - -class GlobalCacheHolder(object): - def __init__(self, space): - self.cache = None - state = space.fromcache(State) - self.dictcontent = state.neverused_dictcontent - - def getcache(self, space, code, w_globals): - if type(w_globals) is ModuleDictImplementation: - content = w_globals.content - else: - content = None - if self.dictcontent is content: - return self.cache - return self.getcache_slow(space, code, w_globals, content) - getcache._always_inline_ = True - - def getcache_slow(self, space, code, w_globals, content): - state = space.fromcache(State) - if content is None: - cache = state.always_invalid_cache - if len(code.co_names_w) > len(cache): - cache = [state.invalidcell] * len(code.co_names_w) - state.always_invalid_cache = cache - else: - cache = [state.invalidcell] * len(code.co_names_w) - self.cache = cache - self.dictcontent = content - return cache - getcache_slow._dont_inline_ = True - -def init_code(code): - if code.co_flags & CO_CONTAINSGLOBALS: - code.globalcacheholder = GlobalCacheHolder(code.space) - else: - code.globalcacheholder = None - - -def get_global_cache(space, code, w_globals): - from pypy.interpreter.pycode import PyCode - assert isinstance(code, PyCode) - holder = code.globalcacheholder - if holder is not None: - return holder.getcache(space, code, w_globals) - return None - -def getimplementation(w_dict): - if type(w_dict) is ModuleDictImplementation and w_dict.r_dict_content is None: - return w_dict - else: - return None - -def LOAD_GLOBAL(f, nameindex, *ignored): - cell = f.cache_for_globals[nameindex] - w_value = cell.w_value - if w_value is None: - # slow path - w_value = load_global_fill_cache(f, nameindex) - f.pushvalue(w_value) -LOAD_GLOBAL._always_inline_ = True - -def find_cell_from_dict(implementation, name): - if implementation is not None: - return implementation.getcell(name, False) - return None - - at jit.dont_look_inside -def load_global_fill_cache(f, nameindex): - name = f.space.str_w(f.getname_w(nameindex)) - implementation = getimplementation(f.w_globals) - if implementation is not None: - cell = implementation.getcell(name, False) - if cell is None: - builtin_impl = getimplementation(f.get_builtin().getdict()) - cell = find_cell_from_dict(builtin_impl, name) - if cell is not None: - implementation.add_unshadowed_builtin(name, builtin_impl) - - if cell is not None: - f.cache_for_globals[nameindex] = cell - return cell.w_value - return f._load_global(f.getname_u(nameindex)) -load_global_fill_cache._dont_inline_ = True Modified: pypy/branch/change-celldict2/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/change-celldict2/pypy/objspace/std/objspace.py (original) +++ pypy/branch/change-celldict2/pypy/objspace/std/objspace.py Thu Jan 7 14:34:36 2010 @@ -71,16 +71,8 @@ # Import all the object types and implementations self.model = StdTypeModel(self.config) - from pypy.objspace.std.celldict import get_global_cache class StdObjSpaceFrame(pyframe.PyFrame): - if self.config.objspace.std.withcelldict: - def __init__(self, space, code, w_globals, closure): - pyframe.PyFrame.__init__(self, space, code, w_globals, closure) - self.cache_for_globals = get_global_cache(space, code, w_globals) - - from pypy.objspace.std.celldict import LOAD_GLOBAL - if self.config.objspace.std.optimized_int_add: if self.config.objspace.std.withsmallint: def BINARY_ADD(f, oparg, *ignored): Modified: pypy/branch/change-celldict2/pypy/objspace/std/test/test_celldict.py ============================================================================== --- pypy/branch/change-celldict2/pypy/objspace/std/test/test_celldict.py (original) +++ pypy/branch/change-celldict2/pypy/objspace/std/test/test_celldict.py Thu Jan 7 14:34:36 2010 @@ -1,262 +1,31 @@ import py from pypy.conftest import gettestobjspace, option -from pypy.objspace.std.celldict import get_global_cache, ModuleCell, ModuleDictImplementation +from pypy.objspace.std.celldict import ModuleCell, ModuleDictImplementation +from pypy.objspace.std.test.test_dictmultiobject import FakeSpace from pypy.interpreter import gateway -# this file tests mostly the effects of caching global lookup. The dict -# implementation itself is tested in test_dictmultiobject.py - - -class AppTestCellDict(object): - def setup_class(cls): - if option.runappdirect: - py.test.skip("not appdirect tests") - cls.space = gettestobjspace(**{"objspace.std.withcelldict": True}) - cls.w_impl_used = cls.space.appexec([], """(): - import __pypy__ - def impl_used(obj): - assert "ModuleDictImplementation" in __pypy__.internal_repr(obj) - return impl_used - """) - def is_in_cache(space, w_code, w_globals, w_name): - name = space.str_w(w_name) - cache = get_global_cache(space, w_code, w_globals) - index = [space.str_w(w_n) for w_n in w_code.co_names_w].index(name) - return space.wrap(cache[index].w_value is not None) - is_in_cache = gateway.interp2app(is_in_cache) - cls.w_is_in_cache = cls.space.wrap(is_in_cache) - stored_builtins = [] - def rescue_builtins(space): - w_dict = space.builtin.getdict() - content = {} - for key, cell in w_dict.content.iteritems(): - newcell = ModuleCell() - newcell.w_value = cell.w_value - content[key] = newcell - stored_builtins.append(content) - rescue_builtins = gateway.interp2app(rescue_builtins) - cls.w_rescue_builtins = cls.space.wrap(rescue_builtins) - def restore_builtins(space): - w_dict = space.builtin.getdict() - assert isinstance(w_dict, ModuleDictImplementation) - w_dict.content = stored_builtins.pop() - w_dict.fallback = None - restore_builtins = gateway.interp2app(restore_builtins) - cls.w_restore_builtins = cls.space.wrap(restore_builtins) - - def test_same_code_in_different_modules(self): - import sys - mod1 = type(sys)("abc") - self.impl_used(mod1.__dict__) - glob1 = mod1.__dict__ - mod2 = type(sys)("abc") - self.impl_used(mod2.__dict__) - glob2 = mod2.__dict__ - def f(): - return x + 1 - code = f.func_code - f1 = type(f)(code, glob1) - mod1.x = 1 - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - mod1.x = 2 - assert f1() == 3 - assert self.is_in_cache(code, glob1, "x") - assert f1() == 3 - assert self.is_in_cache(code, glob1, "x") - f2 = type(f)(code, glob2) - mod2.x = 5 - assert not self.is_in_cache(code, glob2, "x") - assert f2() == 6 - assert self.is_in_cache(code, glob2, "x") - assert f2() == 6 - assert self.is_in_cache(code, glob2, "x") - mod2.x = 7 - assert f2() == 8 - assert self.is_in_cache(code, glob2, "x") - assert f2() == 8 - assert self.is_in_cache(code, glob2, "x") - - def test_override_builtins(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - glob1 = mod1.__dict__ - self.impl_used(mod1.__dict__) - def f(): - return len(x) - code = f.func_code - f1 = type(f)(f.func_code, glob1) - mod1.x = [] - assert not self.is_in_cache(code, glob1, "len") - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 0 - assert self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - assert f1() == 0 - mod1.x.append(1) - assert f1() == 1 - assert self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - mod1.len = lambda x: 15 - assert not self.is_in_cache(code, glob1, "len") - mod1.x.append(1) - assert f1() == 15 - assert self.is_in_cache(code, glob1, "len") - assert f1() == 15 - assert self.is_in_cache(code, glob1, "len") - del mod1.len - mod1.x.append(1) - assert not self.is_in_cache(code, glob1, "len") - assert f1() == 3 - assert self.is_in_cache(code, glob1, "len") - assert f1() == 3 - assert self.is_in_cache(code, glob1, "len") - orig_len = __builtins__.len - try: - __builtins__.len = lambda x: 12 - mod1.x.append(1) - assert self.is_in_cache(code, glob1, "len") - assert f1() == 12 - assert self.is_in_cache(code, glob1, "len") - assert f1() == 12 - assert self.is_in_cache(code, glob1, "len") - finally: - __builtins__.len = orig_len - - def test_override_builtins2(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - glob1 = mod1.__dict__ - self.impl_used(mod1.__dict__) - def f(): - return l(x) - code = f.func_code - f1 = type(f)(f.func_code, glob1) - mod1.x = [] - __builtin__.l = len - try: - assert not self.is_in_cache(code, glob1, "l") - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 0 - assert self.is_in_cache(code, glob1, "l") - assert self.is_in_cache(code, glob1, "x") - assert f1() == 0 - mod1.x.append(1) - assert f1() == 1 - assert self.is_in_cache(code, glob1, "l") - assert self.is_in_cache(code, glob1, "x") - del __builtin__.l - mod1.l = len - mod1.x.append(1) - assert not self.is_in_cache(code, glob1, "l") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "l") - assert self.is_in_cache(code, glob1, "x") - finally: - if hasattr(__builtins__, "l"): - del __builtins__.l - - def test_generator(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - glob1 = mod1.__dict__ - self.impl_used(mod1.__dict__) - def f(): - yield 1 - yield x - yield len(x) - code = f.func_code - f1 = type(f)(f.func_code, glob1) - mod1.x = [] - gen = f1() - assert not self.is_in_cache(code, glob1, "len") - assert not self.is_in_cache(code, glob1, "x") - v = gen.next() - assert v == 1 - assert not self.is_in_cache(code, glob1, "len") - assert not self.is_in_cache(code, glob1, "x") - v = gen.next() - assert v is mod1.x - assert not self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - v = gen.next() - assert v == 0 - assert self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - - def test_degenerate_to_rdict(self): - import sys - mod1 = type(sys)("abc") - self.impl_used(mod1.__dict__) - glob1 = mod1.__dict__ - def f(): - return x + 1 - code = f.func_code - f1 = type(f)(code, glob1) - mod1.x = 1 - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - glob1[1] = 2 - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert not self.is_in_cache(code, glob1, "x") - - def test_degenerate_builtin_to_rdict(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - self.impl_used(mod1.__dict__) - glob1 = mod1.__dict__ - def f(): - return len(x) - code = f.func_code - f1 = type(f)(code, glob1) - mod1.x = [1, 2] - assert not self.is_in_cache(code, glob1, "x") - assert not self.is_in_cache(code, glob1, "len") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - assert self.is_in_cache(code, glob1, "len") - self.rescue_builtins() - try: - __builtin__.__dict__[1] = 2 - assert not self.is_in_cache(code, glob1, "len") - assert f1() == 2 - assert not self.is_in_cache(code, glob1, "len") - finally: - self.restore_builtins() - - def test_mapping_as_locals(self): - import sys - if sys.version_info < (2,5) or not hasattr(sys, 'pypy_objspaceclass'): - skip("need CPython 2.5 or PyPy for non-dictionaries in exec statements") - class M(object): - def __getitem__(self, key): - return key - def __setitem__(self, key, value): - self.result[key] = value - m = M() - m.result = {} - exec "x=m" in {}, m - assert m.result == {'x': 'm'} - exec "y=n" in m # NOTE: this doesn't work in CPython 2.4 - assert m.result == {'x': 'm', 'y': 'n'} - - def test_subclass_of_dict_as_locals(self): - import sys - if sys.version_info < (2,5) or not hasattr(sys, 'pypy_objspaceclass'): - skip("need CPython 2.5 or PyPy for non-dictionaries in exec statements") - class M(dict): - def __getitem__(self, key): - return key - def __setitem__(self, key, value): - dict.__setitem__(self, key, value) - m = M() - exec "x=m" in {}, m - assert m == {'x': 'm'} - exec "y=n" in m # NOTE: this doesn't work in CPython 2.4 - assert m == {'x': 'm', 'y': 'n'} +space = FakeSpace() +class TestCellDict(object): + def test_basic_property(self): + d = ModuleDictImplementation(space) + d.setitem("a", 1) + assert d.getcell("a", False) is d.getcell("a", False) + acell = d.getcell("a", False) + d.setitem("b", 2) + assert d.getcell("b", False) is d.getcell("b", False) + assert d.getcell("c", True) is d.getcell("c", True) + + assert d.getitem("a") == 1 + assert d.getitem("b") == 2 + + d.delitem("a") + py.test.raises(KeyError, d.delitem, "a") + assert d.getitem("a") is None + assert d.getcell("a", False) is acell + assert d.length() == 1 + + d.clear() + assert d.getitem("a") is None + assert d.getcell("a", False) is acell + assert d.length() == 1 From cfbolz at codespeak.net Thu Jan 7 14:34:48 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 14:34:48 +0100 (CET) Subject: [pypy-svn] r70426 - pypy/branch/change-celldict Message-ID: <20100107133448.F261F1680FF@codespeak.net> Author: cfbolz Date: Thu Jan 7 14:34:48 2010 New Revision: 70426 Removed: pypy/branch/change-celldict/ Log: remove merged branch From cfbolz at codespeak.net Thu Jan 7 15:05:34 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 15:05:34 +0100 (CET) Subject: [pypy-svn] r70427 - pypy/trunk/pypy/interpreter/test Message-ID: <20100107140534.3312F1680FA@codespeak.net> Author: cfbolz Date: Thu Jan 7 15:05:32 2010 New Revision: 70427 Modified: pypy/trunk/pypy/interpreter/test/test_pyframe.py Log: a test that fails when running apptests with a pypy-c-jit Modified: pypy/trunk/pypy/interpreter/test/test_pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_pyframe.py (original) +++ pypy/trunk/pypy/interpreter/test/test_pyframe.py Thu Jan 7 15:05:32 2010 @@ -369,3 +369,38 @@ res = f(1) sys.settrace(None) assert res == 42 + +class AppTestJitTraceInteraction(object): + + def setup_class(cls): + from pypy import conftest + if not conftest.option.runappdirect: + py.test.skip("only for py.test -A") + + def test_trace_while_blackholing(self): + import sys + l = [] + def trace(frame, event, arg): + l.append((frame.f_code.co_name, event)) + return trace + def g(i, x): + if i > x - 10: + print i + if i == x - 5: + sys.settrace(trace) + + def f(x): + res = 0 + for i in range(x): + res += i + g(i, x) + + f(10) + sys.settrace(None) + assert l == [('g', 'call'), ('g', 'line'), ('g', 'line'), ('g', 'line'), ('g', 'return')] * 4 + l1 = l + l = [] + f(10000) + sys.settrace(None) + + assert l == l1 From cfbolz at codespeak.net Thu Jan 7 15:07:13 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 15:07:13 +0100 (CET) Subject: [pypy-svn] r70428 - pypy/extradoc/planning Message-ID: <20100107140713.145CC1680FA@codespeak.net> Author: cfbolz Date: Thu Jan 7 15:07:12 2010 New Revision: 70428 Modified: pypy/extradoc/planning/jit.txt Log: make a note to not forget Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Thu Jan 7 15:07:12 2010 @@ -61,6 +61,9 @@ - since threads are enabled with the JIT, getexecutioncontext cannot be folded by the JIT anymore. we need to do something in that direction +known bugs: +- the trace-hook is not correctly called while blackholing, see + test_pyframe.py:AppTestJitTraceInteraction From afa at codespeak.net Thu Jan 7 15:49:15 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 7 Jan 2010 15:49:15 +0100 (CET) Subject: [pypy-svn] r70429 - pypy/branch/import-builtin Message-ID: <20100107144915.037011680F7@codespeak.net> Author: afa Date: Thu Jan 7 15:49:15 2010 New Revision: 70429 Removed: pypy/branch/import-builtin/ Log: removed merged branch From cfbolz at codespeak.net Thu Jan 7 17:48:02 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 17:48:02 +0100 (CET) Subject: [pypy-svn] r70433 - pypy/branch/change-celldict2/pypy/objspace/std/test Message-ID: <20100107164802.007361680FF@codespeak.net> Author: cfbolz Date: Thu Jan 7 17:48:02 2010 New Revision: 70433 Modified: pypy/branch/change-celldict2/pypy/objspace/std/test/test_celldict.py Log: huh? This is silly. Fix typo or something. Modified: pypy/branch/change-celldict2/pypy/objspace/std/test/test_celldict.py ============================================================================== --- pypy/branch/change-celldict2/pypy/objspace/std/test/test_celldict.py (original) +++ pypy/branch/change-celldict2/pypy/objspace/std/test/test_celldict.py Thu Jan 7 17:48:02 2010 @@ -28,4 +28,4 @@ d.clear() assert d.getitem("a") is None assert d.getcell("a", False) is acell - assert d.length() == 1 + assert d.length() == 0 From cfbolz at codespeak.net Thu Jan 7 17:55:26 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 17:55:26 +0100 (CET) Subject: [pypy-svn] r70434 - pypy/branch/jit-trace-hook Message-ID: <20100107165526.AF8CA1680FF@codespeak.net> Author: cfbolz Date: Thu Jan 7 17:55:25 2010 New Revision: 70434 Added: pypy/branch/jit-trace-hook/ - copied from r70433, pypy/trunk/ Log: A branch where I'll try to fix the trace hook problems. From cfbolz at codespeak.net Thu Jan 7 18:13:32 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 18:13:32 +0100 (CET) Subject: [pypy-svn] r70435 - pypy/branch/jit-trace-hook/pypy/interpreter Message-ID: <20100107171332.3F2C41680FC@codespeak.net> Author: cfbolz Date: Thu Jan 7 18:13:31 2010 New Revision: 70435 Modified: pypy/branch/jit-trace-hook/pypy/interpreter/baseobjspace.py pypy/branch/jit-trace-hook/pypy/interpreter/executioncontext.py pypy/branch/jit-trace-hook/pypy/interpreter/pyframe.py pypy/branch/jit-trace-hook/pypy/interpreter/pyopcode.py Log: Let the JIT see all points where the trace hook is called. This gives horrible code so far, going to try some things whether this can be fixed. Modified: pypy/branch/jit-trace-hook/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/jit-trace-hook/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/jit-trace-hook/pypy/interpreter/baseobjspace.py Thu Jan 7 18:13:31 2010 @@ -791,8 +791,7 @@ def call_valuestack(self, w_func, nargs, frame): from pypy.interpreter.function import Function, Method, is_builtin_code - if (not we_are_jitted() and frame.is_being_profiled and - is_builtin_code(w_func)): + if frame.is_being_profiled and is_builtin_code(w_func): # XXX: this code is copied&pasted :-( from the slow path below # call_valuestack(). args = frame.make_arguments(nargs) Modified: pypy/branch/jit-trace-hook/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/jit-trace-hook/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/jit-trace-hook/pypy/interpreter/executioncontext.py Thu Jan 7 18:13:31 2010 @@ -53,17 +53,15 @@ def leave(self, frame): try: - if not jit.we_are_jitted(): - if self.profilefunc: - self._trace(frame, 'leaveframe', self.space.w_None) + if self.profilefunc: + self._trace(frame, 'leaveframe', self.space.w_None) finally: self.topframeref = frame.f_backref self.framestackdepth -= 1 jit.virtual_ref_finish(frame) - if not jit.we_are_jitted(): - if self.w_tracefunc is not None and not frame.hide(): - self.space.frame_trace_action.fire() + if self.w_tracefunc is not None and not frame.hide(): + self.space.frame_trace_action.fire() # ________________________________________________________________ Modified: pypy/branch/jit-trace-hook/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/jit-trace-hook/pypy/interpreter/pyframe.py (original) +++ pypy/branch/jit-trace-hook/pypy/interpreter/pyframe.py Thu Jan 7 18:13:31 2010 @@ -141,8 +141,7 @@ executioncontext = self.space.getexecutioncontext() executioncontext.enter(self) try: - if not we_are_jitted(): - executioncontext.call_trace(self) + executioncontext.call_trace(self) # Execution starts just after the last_instr. Initially, # last_instr is -1. After a generator suspends it points to # the YIELD_VALUE instruction. @@ -153,11 +152,9 @@ rstack.resume_point("execute_frame", self, executioncontext, returns=w_exitvalue) except Exception: - if not we_are_jitted(): - executioncontext.return_trace(self, self.space.w_None) + executioncontext.return_trace(self, self.space.w_None) raise - if not we_are_jitted(): - executioncontext.return_trace(self, w_exitvalue) + executioncontext.return_trace(self, w_exitvalue) finally: executioncontext.leave(self) return w_exitvalue Modified: pypy/branch/jit-trace-hook/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/jit-trace-hook/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/jit-trace-hook/pypy/interpreter/pyopcode.py Thu Jan 7 18:13:31 2010 @@ -131,6 +131,8 @@ def handle_operation_error(self, ec, operr, attach_tb=True): if attach_tb: if not jit.we_are_jitted(): + # XXX no clue how this hack interacts with the JIT :-( + # xxx this is a hack. It allows bytecode_trace() to # call a signal handler which raises, and catch the # raised exception immediately. See test_alarm_raise in @@ -153,8 +155,7 @@ operr = e pytraceback.record_application_traceback( self.space, operr, self, self.last_instr) - if not jit.we_are_jitted(): - ec.exception_trace(self, operr) + ec.exception_trace(self, operr) block = self.unrollstack(SApplicationException.kind) if block is None: @@ -176,8 +177,8 @@ space = self.space while True: self.last_instr = intmask(next_instr) + ec.bytecode_trace(self) if not jit.we_are_jitted(): - ec.bytecode_trace(self) next_instr = r_uint(self.last_instr) opcode = ord(co_code[next_instr]) next_instr += 1 @@ -913,13 +914,10 @@ arguments = f.popvalues(n_arguments) args = f.argument_factory(arguments, keywords, keywords_w, w_star, w_starstar) w_function = f.popvalue() - if jit.we_are_jitted(): - w_result = f.space.call_args(w_function, args) + if f.is_being_profiled and is_builtin_code(w_function): + w_result = f.space.call_args_and_c_profile(f, w_function, args) else: - if f.is_being_profiled and is_builtin_code(w_function): - w_result = f.space.call_args_and_c_profile(f, w_function, args) - else: - w_result = f.space.call_args(w_function, args) + w_result = f.space.call_args(w_function, args) rstack.resume_point("call_function", f, returns=w_result) f.pushvalue(w_result) From cfbolz at codespeak.net Thu Jan 7 18:44:44 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 18:44:44 +0100 (CET) Subject: [pypy-svn] r70436 - in pypy/branch/jit-trace-hook/pypy/jit/metainterp: . test Message-ID: <20100107174444.363891680FC@codespeak.net> Author: cfbolz Date: Thu Jan 7 18:44:43 2010 New Revision: 70436 Modified: pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeutil.py pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py Log: Add an optimization that removes a pure operation if it has already been seen. Modified: pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py Thu Jan 7 18:44:43 2010 @@ -11,7 +11,7 @@ from pypy.jit.metainterp.specnode import VirtualStructSpecNode from pypy.jit.metainterp.optimizeutil import _findall, sort_descrs from pypy.jit.metainterp.optimizeutil import descrlist_dict -from pypy.jit.metainterp.optimizeutil import InvalidLoop +from pypy.jit.metainterp.optimizeutil import InvalidLoop, args_dict from pypy.jit.metainterp import resume, compile from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.rlib.objectmodel import we_are_translated @@ -388,6 +388,7 @@ self.resumedata_memo = resume.ResumeDataLoopMemo(metainterp_sd) self.heap_op_optimizer = HeapOpOptimizer(self) self.bool_boxes = {} + self.pure_operations = args_dict() def forget_numberings(self, virtualbox): self.metainterp_sd.profiler.count(jitprof.OPT_FORCINGS) @@ -574,6 +575,22 @@ resbox = execute_nonspec(self.cpu, op.opnum, argboxes, op.descr) self.make_constant(op.result, resbox.constbox()) return + + # did we do the exact same operation already? + args = op.args[:] + for i in range(len(args)): + arg = args[i] + if arg in self.values: + args[i] = self.values[arg].get_key_box() + args.append(ConstInt(op.opnum)) + oldop = self.pure_operations.get(args, None) + if oldop is not None: + assert oldop.opnum == op.opnum + self.make_equal_to(op.result, self.getvalue(oldop.result)) + return + else: + self.pure_operations[args] = op + # otherwise, the operation remains self.emit_operation(op) Modified: pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeutil.py ============================================================================== --- pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeutil.py (original) +++ pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeutil.py Thu Jan 7 18:44:43 2010 @@ -1,7 +1,7 @@ from pypy.rlib.objectmodel import r_dict, compute_identity_hash from pypy.rlib.rarithmetic import intmask from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp import resoperation +from pypy.jit.metainterp import resoperation, history class InvalidLoop(Exception): """Raised when the optimize*.py detect that the loop that @@ -59,3 +59,35 @@ def descrlist_dict(): return r_dict(descrlist_eq, descrlist_hash) +# ____________________________________________________________ + +def args_eq(args1, args2): + if len(args1) != len(args2): + return False + for i in range(len(args1)): + arg1 = args1[i] + arg2 = args2[i] + if isinstance(arg1, history.Const): + if arg1.__class__ is not arg2.__class__: + return False + if not arg1.same_constant(arg2): + return False + else: + if not arg1 is arg2: + return False + return True + +def args_hash(args): + res = 0x345678 + for arg in args: + if isinstance(arg, history.Const): + y = arg._get_hash_() + else: + y = compute_identity_hash(arg) + res = intmask((1000003 * res) ^ y) + return res + +def args_dict(): + return r_dict(args_eq, args_hash) + + Modified: pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py Thu Jan 7 18:44:43 2010 @@ -1834,6 +1834,30 @@ """ self.optimize_loop(ops, "Not", expected) + def test_remove_duplicate_pure_op(self): + ops = """ + [p1, p2] + i1 = oois(p1, p2) + i2 = oois(p1, p2) + i3 = int_add(i1, 1) + i4 = int_add(i2, 1) + escape(i3) + escape(i4) + guard_true(i1) [] + guard_true(i2) [] + jump(p1, p2) + """ + expected = """ + [p1, p2] + i1 = oois(p1, p2) + i3 = int_add(i1, 1) + escape(i3) + escape(i3) + guard_true(i1) [] + jump(p1, p2) + """ + self.optimize_loop(ops, "Not, Not", expected) + # ---------- def make_fail_descr(self): From afa at codespeak.net Thu Jan 7 18:50:23 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 7 Jan 2010 18:50:23 +0100 (CET) Subject: [pypy-svn] r70437 - in pypy/trunk/pypy/lib: _ctypes app_test/ctypes_tests Message-ID: <20100107175023.885D11680FC@codespeak.net> Author: afa Date: Thu Jan 7 18:50:21 2010 New Revision: 70437 Modified: pypy/trunk/pypy/lib/_ctypes/array.py pypy/trunk/pypy/lib/_ctypes/primitive.py pypy/trunk/pypy/lib/_ctypes/structure.py pypy/trunk/pypy/lib/_ctypes/union.py pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py Log: Fix a keepalive problem in ctypes: When setting a struct member, the structure did not track keepalives if the value needs to be converted. Modified: pypy/trunk/pypy/lib/_ctypes/array.py ============================================================================== --- pypy/trunk/pypy/lib/_ctypes/array.py (original) +++ pypy/trunk/pypy/lib/_ctypes/array.py Thu Jan 7 18:50:21 2010 @@ -90,7 +90,7 @@ def _CData_retval(self, resbuffer): raise NotImplementedError - def _CData_value(self, value): + def from_param(self, value): # array accepts very strange parameters as part of structure # or function argument... from ctypes import c_char, c_wchar @@ -104,7 +104,7 @@ if len(value) > self._length_: raise RuntimeError("Invalid length") value = self(*value) - return _CDataMeta._CData_value(self, value) + return _CDataMeta.from_param(self, value) def array_get_slice_params(self, index): if index.step is not None: Modified: pypy/trunk/pypy/lib/_ctypes/primitive.py ============================================================================== --- pypy/trunk/pypy/lib/_ctypes/primitive.py (original) +++ pypy/trunk/pypy/lib/_ctypes/primitive.py Thu Jan 7 18:50:21 2010 @@ -290,6 +290,8 @@ self.value = value def _ensure_objects(self): + if self._type_ in 'zZ': + return self._objects return None def _getvalue(self): Modified: pypy/trunk/pypy/lib/_ctypes/structure.py ============================================================================== --- pypy/trunk/pypy/lib/_ctypes/structure.py (original) +++ pypy/trunk/pypy/lib/_ctypes/structure.py Thu Jan 7 18:50:21 2010 @@ -130,10 +130,10 @@ def _alignmentofinstances(self): return self._ffistruct.alignment - def _CData_value(self, value): + def from_param(self, value): if isinstance(value, tuple): value = self(*value) - return _CDataMeta._CData_value(self, value) + return _CDataMeta.from_param(self, value) def _CData_output(self, resarray, base=None, index=-1): res = self.__new__(self) @@ -183,10 +183,11 @@ fieldtype = self._fieldtypes[name].ctype except KeyError: return _CData.__setattr__(self, name, value) - if ensure_objects(value) is not None: + cobj = fieldtype.from_param(value) + if ensure_objects(cobj) is not None: key = keepalive_key(getattr(self.__class__, name).num) - store_reference(self, key, value._objects) - arg = fieldtype._CData_value(value) + store_reference(self, key, cobj._objects) + arg = cobj._get_buffer_value() if fieldtype._fficompositesize is not None: from ctypes import memmove dest = self._buffer.fieldaddress(name) Modified: pypy/trunk/pypy/lib/_ctypes/union.py ============================================================================== --- pypy/trunk/pypy/lib/_ctypes/union.py (original) +++ pypy/trunk/pypy/lib/_ctypes/union.py Thu Jan 7 18:50:21 2010 @@ -99,10 +99,11 @@ fieldtype = self._fieldtypes[name].ctype except KeyError: raise AttributeError(name) - if ensure_objects(value) is not None: + cobj = fieldtype.from_param(value) + if ensure_objects(cobj) is not None: key = keepalive_key(getattr(self.__class__, name).num) - store_reference(self, key, value._objects) - arg = fieldtype._CData_value(value) + store_reference(self, key, cobj._objects) + arg = cobj._get_buffer_value() if fieldtype._fficompositesize is not None: from ctypes import memmove dest = self._buffer.buffer Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py (original) +++ pypy/trunk/pypy/lib/app_test/ctypes_tests/test_keepalive.py Thu Jan 7 18:50:21 2010 @@ -221,6 +221,11 @@ ('dptr', c_char_p), ('dsize', c_int), ] + class union(Union): + _fields_ = [ + ('dptr', c_char_p), + ('dsize', c_int), + ] for wrap in [False, True]: n = 2 xs = "hello" * n @@ -235,3 +240,15 @@ print 'dat._objects =', repr(dat._objects) assert dat.dptr == "hellohello" assert dat._objects.keys() == ['0'] + + xs = "hello" * n + if wrap: + xs = c_char_p(xs) + dat = union() + dat.dptr = xs + del xs + import gc; gc.collect() + print 'dat.dptr =', repr(dat.dptr) + print 'dat._objects =', repr(dat._objects) + assert dat.dptr == "hellohello" + assert dat._objects.keys() == ['0'] From cfbolz at codespeak.net Thu Jan 7 19:08:27 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 19:08:27 +0100 (CET) Subject: [pypy-svn] r70438 - in pypy/branch/jit-trace-hook/pypy/jit/metainterp: . test Message-ID: <20100107180827.D51341680FC@codespeak.net> Author: cfbolz Date: Thu Jan 7 19:08:27 2010 New Revision: 70438 Modified: pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py Log: don't bypass optimize_default for int_is_true. Modified: pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/jit-trace-hook/pypy/jit/metainterp/optimizeopt.py Thu Jan 7 19:08:27 2010 @@ -721,7 +721,7 @@ elif value.is_null(): self.make_constant_int(op.result, not expect_nonnull) else: - self.emit_operation(op) + self.optimize_default(op) def optimize_INT_IS_TRUE(self, op): self._optimize_nullness(op, op.args[0], True) Modified: pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/jit-trace-hook/pypy/jit/metainterp/test/test_optimizeopt.py Thu Jan 7 19:08:27 2010 @@ -1840,7 +1840,11 @@ i1 = oois(p1, p2) i2 = oois(p1, p2) i3 = int_add(i1, 1) + i3b = int_is_true(i3) + guard_true(i3b) [] i4 = int_add(i2, 1) + i4b = int_is_true(i4) + guard_true(i4b) [] escape(i3) escape(i4) guard_true(i1) [] @@ -1851,6 +1855,8 @@ [p1, p2] i1 = oois(p1, p2) i3 = int_add(i1, 1) + i3b = int_is_true(i3) + guard_true(i3b) [] escape(i3) escape(i3) guard_true(i1) [] From cfbolz at codespeak.net Thu Jan 7 19:28:23 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 19:28:23 +0100 (CET) Subject: [pypy-svn] r70439 - pypy/branch/change-celldict2/pypy/doc/config Message-ID: <20100107182823.ABA971680FF@codespeak.net> Author: cfbolz Date: Thu Jan 7 19:28:22 2010 New Revision: 70439 Modified: pypy/branch/change-celldict2/pypy/doc/config/objspace.std.withcelldict.txt Log: update docs Modified: pypy/branch/change-celldict2/pypy/doc/config/objspace.std.withcelldict.txt ============================================================================== --- pypy/branch/change-celldict2/pypy/doc/config/objspace.std.withcelldict.txt (original) +++ pypy/branch/change-celldict2/pypy/doc/config/objspace.std.withcelldict.txt Thu Jan 7 19:28:22 2010 @@ -1,2 +1,2 @@ -Enable cell-dicts. This makes global lookups nearly as fast as the lookup of a -local. +Enable cell-dicts. This optimization is not helpful without the JIT. In the +presence of the JIT, it greatly helps looking up globals. From cfbolz at codespeak.net Thu Jan 7 20:04:50 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 20:04:50 +0100 (CET) Subject: [pypy-svn] r70440 - in pypy/trunk/pypy: doc/config interpreter module/pypyjit/test objspace/std objspace/std/test Message-ID: <20100107190450.246791680FF@codespeak.net> Author: cfbolz Date: Thu Jan 7 20:04:49 2010 New Revision: 70440 Modified: pypy/trunk/pypy/doc/config/objspace.std.withcelldict.txt pypy/trunk/pypy/interpreter/pycode.py pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py pypy/trunk/pypy/objspace/std/celldict.py pypy/trunk/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/std/test/test_celldict.py Log: Merge the change-celldict2 branch: Strip the cell dict down to something radically simple. Now it is really just a dict mapping names to cells. For the non-JIT case this makes global-lookups non-optimized (but the caching seems to not have helped much anyway). For the JIT-case the effect is nearly as good as the old code, and even better, if the same key is looked up many times in the same module (which is quite common for libraries). Modified: pypy/trunk/pypy/doc/config/objspace.std.withcelldict.txt ============================================================================== --- pypy/trunk/pypy/doc/config/objspace.std.withcelldict.txt (original) +++ pypy/trunk/pypy/doc/config/objspace.std.withcelldict.txt Thu Jan 7 20:04:49 2010 @@ -1,2 +1,2 @@ -Enable cell-dicts. This makes global lookups nearly as fast as the lookup of a -local. +Enable cell-dicts. This optimization is not helpful without the JIT. In the +presence of the JIT, it greatly helps looking up globals. Modified: pypy/trunk/pypy/interpreter/pycode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pycode.py (original) +++ pypy/trunk/pypy/interpreter/pycode.py Thu Jan 7 20:04:49 2010 @@ -117,9 +117,6 @@ self._compute_flatcall() - if self.space.config.objspace.std.withcelldict: - from pypy.objspace.std.celldict import init_code - init_code(self) def _init_flags(self): co_code = self.co_code Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Thu Jan 7 20:04:49 2010 @@ -210,21 +210,31 @@ def test_simple_call(self): self.run_source(''' + OFFSET = 0 def f(i): - return i + 1 + return i + 1 + OFFSET def main(n): i = 0 - while i < n: + while i < n+OFFSET: i = f(f(i)) return i - ''', 76, + ''', 96, ([20], 20), ([31], 32)) ops = self.get_by_bytecode("LOAD_GLOBAL") - assert len(ops) == 2 - assert ops[0].get_opnames() == ["getfield_gc", "getarrayitem_gc", + assert len(ops) == 5 + assert ops[0].get_opnames() == ["getfield_gc", "guard_value", + "getfield_gc", "guard_isnull", "getfield_gc", "guard_nonnull_class"] - assert not ops[1] # second LOAD_GLOBAL folded away + # the second getfield on the same globals is quicker + assert ops[1].get_opnames() == ["getfield_gc", "guard_nonnull_class"] + assert not ops[2] # second LOAD_GLOBAL of the same name folded away + # LOAD_GLOBAL of the same name but in different function partially + # folded away + # XXX could be improved + assert ops[3].get_opnames() == ["guard_value", + "getfield_gc", "guard_isnull"] + assert not ops[4] ops = self.get_by_bytecode("CALL_FUNCTION") assert len(ops) == 2 for bytecode in ops: @@ -281,7 +291,7 @@ while i < n: i = f(f(i), j=1) return i - ''', 98, + ''', 100, ([20], 20), ([31], 32)) ops = self.get_by_bytecode("CALL_FUNCTION") @@ -305,7 +315,7 @@ a.x = 2 i = i + a.x return i - ''', 63, + ''', 65, ([20], 20), ([31], 32)) Modified: pypy/trunk/pypy/objspace/std/celldict.py ============================================================================== --- pypy/trunk/pypy/objspace/std/celldict.py (original) +++ pypy/trunk/pypy/objspace/std/celldict.py Thu Jan 7 20:04:49 2010 @@ -1,4 +1,8 @@ -from pypy.interpreter.pycode import CO_CONTAINSGLOBALS +""" A very simple cell dict implementation. The dictionary maps keys to cell. +This ensures that the function (dict, key) -> cell is pure. By itself, this +optimization is not helping at all, but in conjunction with the JIT it can +speed up global lookups a lot.""" + from pypy.objspace.std.dictmultiobject import IteratorImplementation from pypy.objspace.std.dictmultiobject import W_DictMultiObject, _is_sane_hash from pypy.rlib import jit @@ -19,31 +23,22 @@ def __init__(self, space): self.space = space self.content = {} - self.unshadowed_builtins = {} - def getcell(self, key, make_new=True): + def getcell(self, key, makenew): + if makenew or jit.we_are_jitted(): + # when we are jitting, we always go through the pure function + # below, to ensure that we have no residual dict lookup + return self._getcell_makenew(key) + return self.content.get(key, None) + + @jit.purefunction_promote + def _getcell_makenew(self, key): res = self.content.get(key, None) if res is not None: return res - if not make_new: - return None result = self.content[key] = ModuleCell() return result - def add_unshadowed_builtin(self, name, builtin_impl): - assert isinstance(builtin_impl, ModuleDictImplementation) - self.unshadowed_builtins[name] = builtin_impl - - def invalidate_unshadowed_builtin(self, name): - impl = self.unshadowed_builtins[name] - try: - cell = impl.content[name] - except KeyError: - pass - else: - w_value = cell.invalidate() - cell = impl.content[name] = ModuleCell(w_value) - def impl_setitem(self, w_key, w_value): space = self.space if space.is_w(space.type(w_key), space.w_str): @@ -52,11 +47,7 @@ self._as_rdict().setitem(w_key, w_value) def impl_setitem_str(self, name, w_value, shadows_type=True): - self.getcell(name).w_value = w_value - - if name in self.unshadowed_builtins: - self.invalidate_unshadowed_builtin(name) - del self.unshadowed_builtins[name] + self.getcell(name, True).w_value = w_value def impl_delitem(self, w_key): space = self.space @@ -64,17 +55,25 @@ if space.is_w(w_key_type, space.w_str): key = space.str_w(w_key) cell = self.getcell(key, False) - if cell is None: + if cell is None or cell.w_value is None: raise KeyError + # note that we don't remove the cell from self.content, to make + # sure that a key that was found at any point in the dict, still + # maps to the same cell later (even if this cell no longer + # represents a key) cell.invalidate() - del self.content[key] elif _is_sane_hash(space, w_key_type): raise KeyError else: self._as_rdict().delitem(w_key) def impl_length(self): - return len(self.content) + # inefficient, but do we care? + res = 0 + for cell in self.content.itervalues(): + if cell.w_value is not None: + res += 1 + return res def impl_getitem(self, w_lookup): space = self.space @@ -91,6 +90,7 @@ res = self.getcell(lookup, False) if res is None: return None + # note that even if the res.w_value is None, the next line is fine return res.w_value def impl_iter(self): @@ -98,39 +98,34 @@ def impl_keys(self): space = self.space - return [space.wrap(key) for key in self.content.iterkeys()] + return [space.wrap(key) for key, cell in self.content.iteritems() + if cell.w_value is not None] def impl_values(self): - return [cell.w_value for cell in self.content.itervalues()] + return [cell.w_value for cell in self.content.itervalues() + if cell.w_value is not None] def impl_items(self): space = self.space return [space.newtuple([space.wrap(key), cell.w_value]) - for (key, cell) in self.content.iteritems()] + for (key, cell) in self.content.iteritems() + if cell.w_value is not None] def impl_clear(self): - # inefficient, but who cares for k, cell in self.content.iteritems(): cell.invalidate() - for k in self.unshadowed_builtins: - self.invalidate_unshadowed_builtin(k) - self.content.clear() - self.unshadowed_builtins.clear() - def _as_rdict(self): r_dict_content = self.initialize_as_rdict() for k, cell in self.content.iteritems(): - r_dict_content[self.space.wrap(k)] = cell.w_value + if cell.w_value is not None: + r_dict_content[self.space.wrap(k)] = cell.w_value cell.invalidate() - for k in self.unshadowed_builtins: - self.invalidate_unshadowed_builtin(k) self._clear_fields() return self def _clear_fields(self): self.content = None - self.unshadowed_builtins = None class ModuleDictIteratorImplementation(IteratorImplementation): def __init__(self, space, dictimplementation): @@ -138,99 +133,8 @@ self.iterator = dictimplementation.content.iteritems() def next_entry(self): - # note that this 'for' loop only runs once, at most for key, cell in self.iterator: - return (self.space.wrap(key), cell.w_value) + if cell.w_value is not None: + return (self.space.wrap(key), cell.w_value) else: return None, None - - -class State(object): - def __init__(self, space): - self.space = space - self.invalidcell = ModuleCell() - self.always_invalid_cache = [] - self.neverused_dictcontent = {} - -class GlobalCacheHolder(object): - def __init__(self, space): - self.cache = None - state = space.fromcache(State) - self.dictcontent = state.neverused_dictcontent - - def getcache(self, space, code, w_globals): - if type(w_globals) is ModuleDictImplementation: - content = w_globals.content - else: - content = None - if self.dictcontent is content: - return self.cache - return self.getcache_slow(space, code, w_globals, content) - getcache._always_inline_ = True - - def getcache_slow(self, space, code, w_globals, content): - state = space.fromcache(State) - if content is None: - cache = state.always_invalid_cache - if len(code.co_names_w) > len(cache): - cache = [state.invalidcell] * len(code.co_names_w) - state.always_invalid_cache = cache - else: - cache = [state.invalidcell] * len(code.co_names_w) - self.cache = cache - self.dictcontent = content - return cache - getcache_slow._dont_inline_ = True - -def init_code(code): - if code.co_flags & CO_CONTAINSGLOBALS: - code.globalcacheholder = GlobalCacheHolder(code.space) - else: - code.globalcacheholder = None - - -def get_global_cache(space, code, w_globals): - from pypy.interpreter.pycode import PyCode - assert isinstance(code, PyCode) - holder = code.globalcacheholder - if holder is not None: - return holder.getcache(space, code, w_globals) - return None - -def getimplementation(w_dict): - if type(w_dict) is ModuleDictImplementation and w_dict.r_dict_content is None: - return w_dict - else: - return None - -def LOAD_GLOBAL(f, nameindex, *ignored): - cell = f.cache_for_globals[nameindex] - w_value = cell.w_value - if w_value is None: - # slow path - w_value = load_global_fill_cache(f, nameindex) - f.pushvalue(w_value) -LOAD_GLOBAL._always_inline_ = True - -def find_cell_from_dict(implementation, name): - if implementation is not None: - return implementation.getcell(name, False) - return None - - at jit.dont_look_inside -def load_global_fill_cache(f, nameindex): - name = f.space.str_w(f.getname_w(nameindex)) - implementation = getimplementation(f.w_globals) - if implementation is not None: - cell = implementation.getcell(name, False) - if cell is None: - builtin_impl = getimplementation(f.get_builtin().getdict()) - cell = find_cell_from_dict(builtin_impl, name) - if cell is not None: - implementation.add_unshadowed_builtin(name, builtin_impl) - - if cell is not None: - f.cache_for_globals[nameindex] = cell - return cell.w_value - return f._load_global(f.getname_u(nameindex)) -load_global_fill_cache._dont_inline_ = True Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Thu Jan 7 20:04:49 2010 @@ -71,16 +71,8 @@ # Import all the object types and implementations self.model = StdTypeModel(self.config) - from pypy.objspace.std.celldict import get_global_cache class StdObjSpaceFrame(pyframe.PyFrame): - if self.config.objspace.std.withcelldict: - def __init__(self, space, code, w_globals, closure): - pyframe.PyFrame.__init__(self, space, code, w_globals, closure) - self.cache_for_globals = get_global_cache(space, code, w_globals) - - from pypy.objspace.std.celldict import LOAD_GLOBAL - if self.config.objspace.std.optimized_int_add: if self.config.objspace.std.withsmallint: def BINARY_ADD(f, oparg, *ignored): Modified: pypy/trunk/pypy/objspace/std/test/test_celldict.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_celldict.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_celldict.py Thu Jan 7 20:04:49 2010 @@ -1,262 +1,31 @@ import py from pypy.conftest import gettestobjspace, option -from pypy.objspace.std.celldict import get_global_cache, ModuleCell, ModuleDictImplementation +from pypy.objspace.std.celldict import ModuleCell, ModuleDictImplementation +from pypy.objspace.std.test.test_dictmultiobject import FakeSpace from pypy.interpreter import gateway -# this file tests mostly the effects of caching global lookup. The dict -# implementation itself is tested in test_dictmultiobject.py - - -class AppTestCellDict(object): - def setup_class(cls): - if option.runappdirect: - py.test.skip("not appdirect tests") - cls.space = gettestobjspace(**{"objspace.std.withcelldict": True}) - cls.w_impl_used = cls.space.appexec([], """(): - import __pypy__ - def impl_used(obj): - assert "ModuleDictImplementation" in __pypy__.internal_repr(obj) - return impl_used - """) - def is_in_cache(space, w_code, w_globals, w_name): - name = space.str_w(w_name) - cache = get_global_cache(space, w_code, w_globals) - index = [space.str_w(w_n) for w_n in w_code.co_names_w].index(name) - return space.wrap(cache[index].w_value is not None) - is_in_cache = gateway.interp2app(is_in_cache) - cls.w_is_in_cache = cls.space.wrap(is_in_cache) - stored_builtins = [] - def rescue_builtins(space): - w_dict = space.builtin.getdict() - content = {} - for key, cell in w_dict.content.iteritems(): - newcell = ModuleCell() - newcell.w_value = cell.w_value - content[key] = newcell - stored_builtins.append(content) - rescue_builtins = gateway.interp2app(rescue_builtins) - cls.w_rescue_builtins = cls.space.wrap(rescue_builtins) - def restore_builtins(space): - w_dict = space.builtin.getdict() - assert isinstance(w_dict, ModuleDictImplementation) - w_dict.content = stored_builtins.pop() - w_dict.fallback = None - restore_builtins = gateway.interp2app(restore_builtins) - cls.w_restore_builtins = cls.space.wrap(restore_builtins) - - def test_same_code_in_different_modules(self): - import sys - mod1 = type(sys)("abc") - self.impl_used(mod1.__dict__) - glob1 = mod1.__dict__ - mod2 = type(sys)("abc") - self.impl_used(mod2.__dict__) - glob2 = mod2.__dict__ - def f(): - return x + 1 - code = f.func_code - f1 = type(f)(code, glob1) - mod1.x = 1 - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - mod1.x = 2 - assert f1() == 3 - assert self.is_in_cache(code, glob1, "x") - assert f1() == 3 - assert self.is_in_cache(code, glob1, "x") - f2 = type(f)(code, glob2) - mod2.x = 5 - assert not self.is_in_cache(code, glob2, "x") - assert f2() == 6 - assert self.is_in_cache(code, glob2, "x") - assert f2() == 6 - assert self.is_in_cache(code, glob2, "x") - mod2.x = 7 - assert f2() == 8 - assert self.is_in_cache(code, glob2, "x") - assert f2() == 8 - assert self.is_in_cache(code, glob2, "x") - - def test_override_builtins(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - glob1 = mod1.__dict__ - self.impl_used(mod1.__dict__) - def f(): - return len(x) - code = f.func_code - f1 = type(f)(f.func_code, glob1) - mod1.x = [] - assert not self.is_in_cache(code, glob1, "len") - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 0 - assert self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - assert f1() == 0 - mod1.x.append(1) - assert f1() == 1 - assert self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - mod1.len = lambda x: 15 - assert not self.is_in_cache(code, glob1, "len") - mod1.x.append(1) - assert f1() == 15 - assert self.is_in_cache(code, glob1, "len") - assert f1() == 15 - assert self.is_in_cache(code, glob1, "len") - del mod1.len - mod1.x.append(1) - assert not self.is_in_cache(code, glob1, "len") - assert f1() == 3 - assert self.is_in_cache(code, glob1, "len") - assert f1() == 3 - assert self.is_in_cache(code, glob1, "len") - orig_len = __builtins__.len - try: - __builtins__.len = lambda x: 12 - mod1.x.append(1) - assert self.is_in_cache(code, glob1, "len") - assert f1() == 12 - assert self.is_in_cache(code, glob1, "len") - assert f1() == 12 - assert self.is_in_cache(code, glob1, "len") - finally: - __builtins__.len = orig_len - - def test_override_builtins2(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - glob1 = mod1.__dict__ - self.impl_used(mod1.__dict__) - def f(): - return l(x) - code = f.func_code - f1 = type(f)(f.func_code, glob1) - mod1.x = [] - __builtin__.l = len - try: - assert not self.is_in_cache(code, glob1, "l") - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 0 - assert self.is_in_cache(code, glob1, "l") - assert self.is_in_cache(code, glob1, "x") - assert f1() == 0 - mod1.x.append(1) - assert f1() == 1 - assert self.is_in_cache(code, glob1, "l") - assert self.is_in_cache(code, glob1, "x") - del __builtin__.l - mod1.l = len - mod1.x.append(1) - assert not self.is_in_cache(code, glob1, "l") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "l") - assert self.is_in_cache(code, glob1, "x") - finally: - if hasattr(__builtins__, "l"): - del __builtins__.l - - def test_generator(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - glob1 = mod1.__dict__ - self.impl_used(mod1.__dict__) - def f(): - yield 1 - yield x - yield len(x) - code = f.func_code - f1 = type(f)(f.func_code, glob1) - mod1.x = [] - gen = f1() - assert not self.is_in_cache(code, glob1, "len") - assert not self.is_in_cache(code, glob1, "x") - v = gen.next() - assert v == 1 - assert not self.is_in_cache(code, glob1, "len") - assert not self.is_in_cache(code, glob1, "x") - v = gen.next() - assert v is mod1.x - assert not self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - v = gen.next() - assert v == 0 - assert self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - - def test_degenerate_to_rdict(self): - import sys - mod1 = type(sys)("abc") - self.impl_used(mod1.__dict__) - glob1 = mod1.__dict__ - def f(): - return x + 1 - code = f.func_code - f1 = type(f)(code, glob1) - mod1.x = 1 - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - glob1[1] = 2 - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert not self.is_in_cache(code, glob1, "x") - - def test_degenerate_builtin_to_rdict(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - self.impl_used(mod1.__dict__) - glob1 = mod1.__dict__ - def f(): - return len(x) - code = f.func_code - f1 = type(f)(code, glob1) - mod1.x = [1, 2] - assert not self.is_in_cache(code, glob1, "x") - assert not self.is_in_cache(code, glob1, "len") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - assert self.is_in_cache(code, glob1, "len") - self.rescue_builtins() - try: - __builtin__.__dict__[1] = 2 - assert not self.is_in_cache(code, glob1, "len") - assert f1() == 2 - assert not self.is_in_cache(code, glob1, "len") - finally: - self.restore_builtins() - - def test_mapping_as_locals(self): - import sys - if sys.version_info < (2,5) or not hasattr(sys, 'pypy_objspaceclass'): - skip("need CPython 2.5 or PyPy for non-dictionaries in exec statements") - class M(object): - def __getitem__(self, key): - return key - def __setitem__(self, key, value): - self.result[key] = value - m = M() - m.result = {} - exec "x=m" in {}, m - assert m.result == {'x': 'm'} - exec "y=n" in m # NOTE: this doesn't work in CPython 2.4 - assert m.result == {'x': 'm', 'y': 'n'} - - def test_subclass_of_dict_as_locals(self): - import sys - if sys.version_info < (2,5) or not hasattr(sys, 'pypy_objspaceclass'): - skip("need CPython 2.5 or PyPy for non-dictionaries in exec statements") - class M(dict): - def __getitem__(self, key): - return key - def __setitem__(self, key, value): - dict.__setitem__(self, key, value) - m = M() - exec "x=m" in {}, m - assert m == {'x': 'm'} - exec "y=n" in m # NOTE: this doesn't work in CPython 2.4 - assert m == {'x': 'm', 'y': 'n'} +space = FakeSpace() +class TestCellDict(object): + def test_basic_property(self): + d = ModuleDictImplementation(space) + d.setitem("a", 1) + assert d.getcell("a", False) is d.getcell("a", False) + acell = d.getcell("a", False) + d.setitem("b", 2) + assert d.getcell("b", False) is d.getcell("b", False) + assert d.getcell("c", True) is d.getcell("c", True) + + assert d.getitem("a") == 1 + assert d.getitem("b") == 2 + + d.delitem("a") + py.test.raises(KeyError, d.delitem, "a") + assert d.getitem("a") is None + assert d.getcell("a", False) is acell + assert d.length() == 1 + + d.clear() + assert d.getitem("a") is None + assert d.getcell("a", False) is acell + assert d.length() == 0 From cfbolz at codespeak.net Thu Jan 7 20:05:11 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 7 Jan 2010 20:05:11 +0100 (CET) Subject: [pypy-svn] r70441 - pypy/branch/change-celldict2 Message-ID: <20100107190511.91D431680FF@codespeak.net> Author: cfbolz Date: Thu Jan 7 20:05:10 2010 New Revision: 70441 Removed: pypy/branch/change-celldict2/ Log: remove merged branch From arigo at codespeak.net Thu Jan 7 21:12:37 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 7 Jan 2010 21:12:37 +0100 (CET) Subject: [pypy-svn] r70442 - pypy/branch/morearraycopy/pypy/rpython Message-ID: <20100107201237.885BF1680FF@codespeak.net> Author: arigo Date: Thu Jan 7 21:12:33 2010 New Revision: 70442 Modified: pypy/branch/morearraycopy/pypy/rpython/rlist.py Log: Use ll_copyitems() more or less systematically from rpython/rlist.py. Modified: pypy/branch/morearraycopy/pypy/rpython/rlist.py ============================================================================== --- pypy/branch/morearraycopy/pypy/rpython/rlist.py (original) +++ pypy/branch/morearraycopy/pypy/rpython/rlist.py Thu Jan 7 21:12:33 2010 @@ -574,15 +574,8 @@ except OverflowError: raise MemoryError l = RESLIST.ll_newlist(newlength) - j = 0 - while j < len1: - l.ll_setitem_fast(j, l1.ll_getitem_fast(j)) - j += 1 - i = 0 - while i < len2: - l.ll_setitem_fast(j, l2.ll_getitem_fast(i)) - i += 1 - j += 1 + l.ll_copyitems(0, l1, 0, len1) + l.ll_copyitems(len1, l2, 0, len2) return l def ll_insert_nonneg(l, index, newitem): @@ -769,12 +762,7 @@ except OverflowError: raise MemoryError l1._ll_resize_ge(newlength) - i = 0 - j = len1 - while i < len2: - l1.ll_setitem_fast(j, l2.ll_getitem_fast(i)) - i += 1 - j += 1 + l1.ll_copyitems(len1, l2, 0, len2) ll_extend.oopspec = 'list.extend(l1, l2)' def ll_extend_with_str(lst, s, getstrlen, getstritem): @@ -867,12 +855,7 @@ ll_assert(start <= len1, "list slice start larger than list length") newlength = len1 - start l = RESLIST.ll_newlist(newlength) - j = 0 - i = start - while i < len1: - l.ll_setitem_fast(j, l1.ll_getitem_fast(i)) - i += 1 - j += 1 + l.ll_copyitems(0, l1, start, newlength) return l ll_listslice_startonly._annenforceargs_ = (None, None, int) @@ -885,22 +868,14 @@ stop = length newlength = stop - start l = RESLIST.ll_newlist(newlength) - j = 0 - i = start - while i < stop: - l.ll_setitem_fast(j, l1.ll_getitem_fast(i)) - i += 1 - j += 1 + l.ll_copyitems(0, l1, start, newlength) return l def ll_listslice_minusone(RESLIST, l1): newlength = l1.ll_length() - 1 ll_assert(newlength >= 0, "empty list is sliced with [:-1]") l = RESLIST.ll_newlist(newlength) - j = 0 - while j < newlength: - l.ll_setitem_fast(j, l1.ll_getitem_fast(j)) - j += 1 + l.ll_copyitems(0, l1, 0, newlength) return l def ll_listdelslice_startonly(l, start): @@ -945,13 +920,8 @@ ll_assert(start <= l1.ll_length(), "l[start:x] = l with start > len(l)") ll_assert(count == stop - start, "setslice cannot resize lists in RPython") - # XXX but it should be easy enough to support, soon - j = start - i = 0 - while i < count: - l1.ll_setitem_fast(j, l2.ll_getitem_fast(i)) - i += 1 - j += 1 + # XXX ...but it would be easy enough to support if really needed + l1.ll_copyitems(start, l2, 0, count) ll_listsetslice.oopspec = 'list.setslice(l1, start, stop, l2)' # ____________________________________________________________ From arigo at codespeak.net Thu Jan 7 21:18:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 7 Jan 2010 21:18:17 +0100 (CET) Subject: [pypy-svn] r70443 - pypy/branch/morearraycopy/pypy/rpython/lltypesystem Message-ID: <20100107201817.A501E1680FF@codespeak.net> Author: arigo Date: Thu Jan 7 21:18:17 2010 New Revision: 70443 Modified: pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py Log: Use rgc.ll_arraycopy in the only loop in rpython/lltypesystem/rlist.py. Modified: pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py ============================================================================== --- pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py (original) +++ pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py Thu Jan 7 21:18:17 2010 @@ -376,8 +376,7 @@ else: LIST = typeOf(l).TO newitems = malloc(LIST.items.TO, n) - for i in range(n): - newitems[i] = olditems[i] + rgc.ll_arraycopy(olditems, newitems, 0, 0, n) return newitems ll_list2fixed.oopspec = 'list.list2fixed(l)' From arigo at codespeak.net Thu Jan 7 21:34:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 7 Jan 2010 21:34:26 +0100 (CET) Subject: [pypy-svn] r70444 - in pypy/branch/morearraycopy/pypy: rlib rpython rpython/lltypesystem Message-ID: <20100107203426.4F3B1318139@codespeak.net> Author: arigo Date: Thu Jan 7 21:34:25 2010 New Revision: 70444 Modified: pypy/branch/morearraycopy/pypy/rlib/rgc.py pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py pypy/branch/morearraycopy/pypy/rpython/rlist.py Log: Use another approach, more oo-friendly. Modified: pypy/branch/morearraycopy/pypy/rlib/rgc.py ============================================================================== --- pypy/branch/morearraycopy/pypy/rlib/rgc.py (original) +++ pypy/branch/morearraycopy/pypy/rlib/rgc.py Thu Jan 7 21:34:25 2010 @@ -1,5 +1,7 @@ import gc from pypy.rpython.extregistry import ExtRegistryEntry +from pypy.rlib.objectmodel import we_are_translated + # ____________________________________________________________ # General GC features @@ -334,7 +336,12 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rlib.objectmodel import keepalive_until_here - assert source != dest + # supports non-overlapping copies only + if not we_are_translated(): + if source == dest: + assert (source_start + length <= dest_start or + dest_start + length <= source_start) + TP = lltype.typeOf(source).TO assert TP == lltype.typeOf(dest).TO if isinstance(TP.OF, lltype.Ptr) and TP.OF.TO._gckind == 'gc': Modified: pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py ============================================================================== --- pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py (original) +++ pypy/branch/morearraycopy/pypy/rpython/lltypesystem/rlist.py Thu Jan 7 21:34:25 2010 @@ -72,7 +72,6 @@ "ll_newemptylist": ll_fixed_newemptylist, "ll_length": ll_fixed_length, "ll_items": ll_fixed_items, - "ll_copyitems": ll_fixed_copyitems, "ITEM": ITEM, "ll_getitem_fast": ll_fixed_getitem_fast, "ll_setitem_fast": ll_fixed_setitem_fast, @@ -106,7 +105,6 @@ "ll_newemptylist": ll_newemptylist, "ll_length": ll_length, "ll_items": ll_items, - "ll_copyitems": ll_copyitems, "ITEM": ITEM, "ll_getitem_fast": ll_getitem_fast, "ll_setitem_fast": ll_setitem_fast, @@ -304,9 +302,6 @@ def ll_items(l): return l.items -def ll_copyitems(dst, dstindex, src, srcindex, length): - rgc.ll_arraycopy(src.ll_items(), dst.items, srcindex, dstindex, length) - def ll_getitem_fast(l, index): ll_assert(index < l.length, "getitem out of bounds") return l.ll_items()[index] @@ -337,9 +332,6 @@ def ll_fixed_items(l): return l -def ll_fixed_copyitems(dst, dstindex, src, srcindex, length): - rgc.ll_arraycopy(src.ll_items(), dst, srcindex, dstindex, length) - def ll_fixed_getitem_fast(l, index): ll_assert(index < len(l), "fixed getitem out of bounds") return l[index] Modified: pypy/branch/morearraycopy/pypy/rpython/rlist.py ============================================================================== --- pypy/branch/morearraycopy/pypy/rpython/rlist.py (original) +++ pypy/branch/morearraycopy/pypy/rpython/rlist.py Thu Jan 7 21:34:25 2010 @@ -11,15 +11,13 @@ from pypy.rlib.debug import ll_assert from pypy.rlib.rarithmetic import ovfcheck, widen from pypy.rpython.annlowlevel import ADTInterface +from pypy.rlib import rgc ADTIFixedList = ADTInterface(None, { 'll_newlist': (['SELF', Signed ], 'self'), 'll_length': (['self' ], Signed), 'll_getitem_fast': (['self', Signed ], 'item'), 'll_setitem_fast': (['self', Signed, 'item'], Void), - 'll_copyitems': (['self', Signed, None, Signed, Signed], Void), - # uses a catch-everything None because it can be - # either a fixed or a non-fixed list }) ADTIList = ADTInterface(ADTIFixedList, { '_ll_resize_ge': (['self', Signed ], Void), @@ -528,10 +526,24 @@ return LIST.ITEM +def ll_arraycopy(source, dest, source_start, dest_start, length): + SRCTYPE = typeOf(source) + if isinstance(SRCTYPE, Ptr): + # lltype + rgc.ll_arraycopy(source.ll_items(), dest.ll_items(), + source_start, dest_start, length) + else: + # ootype -- XXX improve the case of array->array copy? + i = 0 + while i < length: + item = source.ll_getitem_fast(source_start + i) + dest.ll_setitem_fast(dest_start + i, item) + i += 1 + def ll_copy(RESLIST, l): length = l.ll_length() new_lst = RESLIST.ll_newlist(length) - new_lst.ll_copyitems(0, l, 0, length) + ll_arraycopy(l, new_lst, 0, 0, length) return new_lst def ll_len(l): @@ -574,8 +586,8 @@ except OverflowError: raise MemoryError l = RESLIST.ll_newlist(newlength) - l.ll_copyitems(0, l1, 0, len1) - l.ll_copyitems(len1, l2, 0, len2) + ll_arraycopy(l1, l, 0, 0, len1) + ll_arraycopy(l2, l, 0, len1, len2) return l def ll_insert_nonneg(l, index, newitem): @@ -762,7 +774,7 @@ except OverflowError: raise MemoryError l1._ll_resize_ge(newlength) - l1.ll_copyitems(len1, l2, 0, len2) + ll_arraycopy(l2, l1, 0, len1, len2) ll_extend.oopspec = 'list.extend(l1, l2)' def ll_extend_with_str(lst, s, getstrlen, getstritem): @@ -855,7 +867,7 @@ ll_assert(start <= len1, "list slice start larger than list length") newlength = len1 - start l = RESLIST.ll_newlist(newlength) - l.ll_copyitems(0, l1, start, newlength) + ll_arraycopy(l1, l, start, 0, newlength) return l ll_listslice_startonly._annenforceargs_ = (None, None, int) @@ -868,14 +880,14 @@ stop = length newlength = stop - start l = RESLIST.ll_newlist(newlength) - l.ll_copyitems(0, l1, start, newlength) + ll_arraycopy(l1, l, start, 0, newlength) return l def ll_listslice_minusone(RESLIST, l1): newlength = l1.ll_length() - 1 ll_assert(newlength >= 0, "empty list is sliced with [:-1]") l = RESLIST.ll_newlist(newlength) - l.ll_copyitems(0, l1, 0, newlength) + ll_arraycopy(l1, l, 0, 0, newlength) return l def ll_listdelslice_startonly(l, start): @@ -921,7 +933,7 @@ ll_assert(count == stop - start, "setslice cannot resize lists in RPython") # XXX ...but it would be easy enough to support if really needed - l1.ll_copyitems(start, l2, 0, count) + ll_arraycopy(l2, l1, 0, start, count) ll_listsetslice.oopspec = 'list.setslice(l1, start, stop, l2)' # ____________________________________________________________ From arigo at codespeak.net Thu Jan 7 21:50:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 7 Jan 2010 21:50:06 +0100 (CET) Subject: [pypy-svn] r70445 - in pypy/branch/morearraycopy/pypy: jit/metainterp rlib Message-ID: <20100107205006.CB8E3168100@codespeak.net> Author: arigo Date: Thu Jan 7 21:50:05 2010 New Revision: 70445 Modified: pypy/branch/morearraycopy/pypy/jit/metainterp/codewriter.py pypy/branch/morearraycopy/pypy/jit/metainterp/policy.py pypy/branch/morearraycopy/pypy/rlib/rgc.py Log: Fix, and add a nice way to print the traceback of calls from codewriter.py. Modified: pypy/branch/morearraycopy/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/morearraycopy/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/morearraycopy/pypy/jit/metainterp/codewriter.py Thu Jan 7 21:50:05 2010 @@ -86,12 +86,22 @@ if leave_graph is not None: todo.append(leave_graph) self.candidate_graphs = seen = set(todo) + + def callers(): + graph = top_graph + print graph + while graph in coming_from: + graph = coming_from[graph] + print '<-', graph + coming_from = {} + while todo: top_graph = todo.pop() for _, op in top_graph.iterblockops(): if op.opname not in ("direct_call", "indirect_call", "oosend"): continue kind = self.guess_call_kind(op, is_candidate) + # use callers() to view the calling chain in pdb if kind != "regular": continue for graph in self.graphs_from(op, is_candidate): @@ -100,6 +110,7 @@ assert is_candidate(graph) todo.append(graph) seen.add(graph) + coming_from[graph] = top_graph return self.candidate_graphs def graphs_from(self, op, is_candidate=None): Modified: pypy/branch/morearraycopy/pypy/jit/metainterp/policy.py ============================================================================== --- pypy/branch/morearraycopy/pypy/jit/metainterp/policy.py (original) +++ pypy/branch/morearraycopy/pypy/jit/metainterp/policy.py Thu Jan 7 21:50:05 2010 @@ -49,8 +49,6 @@ def look_inside_graph(self, graph): from pypy.translator.backendopt.support import find_backedges contains_loop = bool(find_backedges(graph)) - unsupported = contains_unsupported_variable_type(graph, - self.supports_floats) try: func = graph.func except AttributeError: @@ -61,7 +59,8 @@ contains_loop = contains_loop and not getattr( func, '_jit_unroll_safe_', False) - res = see_function and not unsupported + res = see_function and not contains_unsupported_variable_type(graph, + self.supports_floats) if res and contains_loop: self.unsafe_loopy_graphs.add(graph) return res and not contains_loop Modified: pypy/branch/morearraycopy/pypy/rlib/rgc.py ============================================================================== --- pypy/branch/morearraycopy/pypy/rlib/rgc.py (original) +++ pypy/branch/morearraycopy/pypy/rlib/rgc.py Thu Jan 7 21:50:05 2010 @@ -364,6 +364,7 @@ keepalive_until_here(source) keepalive_until_here(dest) ll_arraycopy._annspecialcase_ = 'specialize:ll' +ll_arraycopy._jit_look_inside_ = False def no_collect(func): func._dont_inline_ = True From cfbolz at codespeak.net Fri Jan 8 10:47:23 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 8 Jan 2010 10:47:23 +0100 (CET) Subject: [pypy-svn] r70446 - pypy/trunk/pypy/interpreter/test Message-ID: <20100108094723.48611168106@codespeak.net> Author: cfbolz Date: Fri Jan 8 10:47:21 2010 New Revision: 70446 Modified: pypy/trunk/pypy/interpreter/test/test_pyframe.py Log: allow the test I wrote yesterday to be properly skipped Modified: pypy/trunk/pypy/interpreter/test/test_pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_pyframe.py (original) +++ pypy/trunk/pypy/interpreter/test/test_pyframe.py Fri Jan 8 10:47:21 2010 @@ -1,3 +1,4 @@ +import py class AppTestPyFrame: From cfbolz at codespeak.net Fri Jan 8 11:26:42 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 8 Jan 2010 11:26:42 +0100 (CET) Subject: [pypy-svn] r70447 - pypy/branch/jit-trace-hook/pypy/interpreter/test Message-ID: <20100108102642.C7ADC168106@codespeak.net> Author: cfbolz Date: Fri Jan 8 11:26:42 2010 New Revision: 70447 Modified: pypy/branch/jit-trace-hook/pypy/interpreter/test/test_pyframe.py Log: simplify test a bit Modified: pypy/branch/jit-trace-hook/pypy/interpreter/test/test_pyframe.py ============================================================================== --- pypy/branch/jit-trace-hook/pypy/interpreter/test/test_pyframe.py (original) +++ pypy/branch/jit-trace-hook/pypy/interpreter/test/test_pyframe.py Fri Jan 8 11:26:42 2010 @@ -1,3 +1,4 @@ +import py class AppTestPyFrame: @@ -384,8 +385,6 @@ l.append((frame.f_code.co_name, event)) return trace def g(i, x): - if i > x - 10: - print i if i == x - 5: sys.settrace(trace) @@ -397,7 +396,7 @@ f(10) sys.settrace(None) - assert l == [('g', 'call'), ('g', 'line'), ('g', 'line'), ('g', 'line'), ('g', 'return')] * 4 + assert l == [('g', 'call'), ('g', 'line'), ('g', 'return')] * 4 l1 = l l = [] f(10000) From cfbolz at codespeak.net Fri Jan 8 12:22:09 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 8 Jan 2010 12:22:09 +0100 (CET) Subject: [pypy-svn] r70448 - pypy/branch/loop-invariant-decorator Message-ID: <20100108112209.EF136168109@codespeak.net> Author: cfbolz Date: Fri Jan 8 12:22:09 2010 New Revision: 70448 Added: pypy/branch/loop-invariant-decorator/ - copied from r70447, pypy/trunk/ Log: A new branch to implement the loop_invariant decorator needed to deal with reading the executioncontext out of TLS. From pedronis at codespeak.net Fri Jan 8 12:30:25 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 8 Jan 2010 12:30:25 +0100 (CET) Subject: [pypy-svn] r70449 - pypy/extradoc/planning Message-ID: <20100108113025.C609C168109@codespeak.net> Author: pedronis Date: Fri Jan 8 12:30:25 2010 New Revision: 70449 Modified: pypy/extradoc/planning/jit.txt Log: add JIT+threads vs binaries consideration Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Fri Jan 8 12:30:25 2010 @@ -52,6 +52,8 @@ website and stability that need sorting out too. However, they are beyond the scope of this section) +consideration: if we plan to ship binaries the threads+JIT combination need to have a reasonable story (too confusing to pick one or the other) + wishlist: - improve on predictability: don't trace into signals ... but produce just a conditional call (or just abort the trace) From arigo at codespeak.net Fri Jan 8 13:15:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 8 Jan 2010 13:15:31 +0100 (CET) Subject: [pypy-svn] r70450 - pypy/trunk/pypy/interpreter/test Message-ID: <20100108121531.1488C16810A@codespeak.net> Author: arigo Date: Fri Jan 8 13:15:31 2010 New Revision: 70450 Modified: pypy/trunk/pypy/interpreter/test/test_pyframe.py Log: Cannot print while sys.settracing(). If run with py.test without the -s option, it will trace the py lib output capturing logic. Modified: pypy/trunk/pypy/interpreter/test/test_pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_pyframe.py (original) +++ pypy/trunk/pypy/interpreter/test/test_pyframe.py Fri Jan 8 13:15:31 2010 @@ -381,12 +381,13 @@ def test_trace_while_blackholing(self): import sys l = [] + printed = [] def trace(frame, event, arg): l.append((frame.f_code.co_name, event)) return trace def g(i, x): if i > x - 10: - print i + printed.append(i) if i == x - 5: sys.settrace(trace) @@ -398,10 +399,13 @@ f(10) sys.settrace(None) + print printed assert l == [('g', 'call'), ('g', 'line'), ('g', 'line'), ('g', 'line'), ('g', 'return')] * 4 l1 = l l = [] + printed = [] f(10000) sys.settrace(None) + print printed assert l == l1 From arigo at codespeak.net Fri Jan 8 13:33:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 8 Jan 2010 13:33:55 +0100 (CET) Subject: [pypy-svn] r70451 - pypy/trunk/pypy/module/pypyjit/test Message-ID: <20100108123355.BA049168109@codespeak.net> Author: arigo Date: Fri Jan 8 13:33:54 2010 New Revision: 70451 Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: Make the error message clearer for the case where we make a typo in --pypy. Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Fri Jan 8 13:33:54 2010 @@ -470,6 +470,8 @@ g = os.popen('"%s" --info' % pypy_c, 'r') lines = g.readlines() g.close() + if not lines: + raise ValueError("cannot execute %r" % pypy_c) for line in lines: line = line.strip() if line.startswith(option + ':'): From arigo at codespeak.net Fri Jan 8 13:36:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 8 Jan 2010 13:36:10 +0100 (CET) Subject: [pypy-svn] r70452 - pypy/build/bot2/pypybuildbot Message-ID: <20100108123610.DC32016810B@codespeak.net> Author: arigo Date: Fri Jan 8 13:36:10 2010 New Revision: 70452 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Run all test files in module/pypyjit instead of just test_pypy_c. Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 8 13:36:10 2010 @@ -149,7 +149,7 @@ command=["python", "pypy/test_all.py", "--pypy=pypy/translator/goal/pypy-c", "--resultlog=pypyjit.log", - "pypy/module/pypyjit/test/test_pypy_c.py"], + "pypy/module/pypyjit/test"], logfiles={'pytestLog': 'pypyjit.log'})) From arigo at codespeak.net Fri Jan 8 13:43:30 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 8 Jan 2010 13:43:30 +0100 (CET) Subject: [pypy-svn] r70453 - in pypy/trunk/pypy: interpreter/test module/pypyjit/test Message-ID: <20100108124330.3729516810B@codespeak.net> Author: arigo Date: Fri Jan 8 13:43:29 2010 New Revision: 70453 Added: pypy/trunk/pypy/module/pypyjit/test/test_pyframe.py - copied, changed from r70450, pypy/trunk/pypy/interpreter/test/test_pyframe.py Modified: pypy/trunk/pypy/interpreter/test/test_pyframe.py Log: Move the test to module/pypyjit, where it should be taken on by the nightly runners. Modified: pypy/trunk/pypy/interpreter/test/test_pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_pyframe.py (original) +++ pypy/trunk/pypy/interpreter/test/test_pyframe.py Fri Jan 8 13:43:29 2010 @@ -1,4 +1,3 @@ -import py class AppTestPyFrame: @@ -370,42 +369,3 @@ res = f(1) sys.settrace(None) assert res == 42 - -class AppTestJitTraceInteraction(object): - - def setup_class(cls): - from pypy import conftest - if not conftest.option.runappdirect: - py.test.skip("only for py.test -A") - - def test_trace_while_blackholing(self): - import sys - l = [] - printed = [] - def trace(frame, event, arg): - l.append((frame.f_code.co_name, event)) - return trace - def g(i, x): - if i > x - 10: - printed.append(i) - if i == x - 5: - sys.settrace(trace) - - def f(x): - res = 0 - for i in range(x): - res += i - g(i, x) - - f(10) - sys.settrace(None) - print printed - assert l == [('g', 'call'), ('g', 'line'), ('g', 'line'), ('g', 'line'), ('g', 'return')] * 4 - l1 = l - l = [] - printed = [] - f(10000) - sys.settrace(None) - print printed - - assert l == l1 Copied: pypy/trunk/pypy/module/pypyjit/test/test_pyframe.py (from r70450, pypy/trunk/pypy/interpreter/test/test_pyframe.py) ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_pyframe.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pyframe.py Fri Jan 8 13:43:29 2010 @@ -1,382 +1,7 @@ import py -class AppTestPyFrame: - # test for the presence of the attributes, not functionality - - def test_f_locals(self): - import sys - f = sys._getframe() - assert f.f_locals is locals() - - def test_f_globals(self): - import sys - f = sys._getframe() - assert f.f_globals is globals() - - def test_f_builtins(self): - import sys, __builtin__ - f = sys._getframe() - assert f.f_builtins is __builtin__.__dict__ - - def test_f_code(self): - def g(): - import sys - f = sys._getframe() - return f.f_code - assert g() is g.func_code - - def test_f_trace_del(self): - import sys - f = sys._getframe() - del f.f_trace - assert f.f_trace is None - - def test_f_lineno(self): - def g(): - import sys - f = sys._getframe() - x = f.f_lineno - y = f.f_lineno - z = f.f_lineno - return [x, y, z] - origin = g.func_code.co_firstlineno - assert g() == [origin+3, origin+4, origin+5] - - def test_f_lineno_set(self): - def tracer(f, *args): - def x(f, *args): - if f.f_lineno == origin + 1: - f.f_lineno = origin + 2 - return x - - def function(): - xyz - return 3 - - def g(): - import sys - sys.settrace(tracer) - function() - sys.settrace(None) - origin = function.func_code.co_firstlineno - g() # assert did not crash - - def test_f_back(self): - import sys - def f(): - assert sys._getframe().f_code.co_name == g() - def g(): - return sys._getframe().f_back.f_code.co_name - f() - - def test_f_exc_xxx(self): - import sys - - class OuterException(Exception): - pass - class InnerException(Exception): - pass - - def g(exc_info): - f = sys._getframe() - assert f.f_exc_type is None - assert f.f_exc_value is None - assert f.f_exc_traceback is None - try: - raise InnerException - except: - assert f.f_exc_type is exc_info[0] - assert f.f_exc_value is exc_info[1] - assert f.f_exc_traceback is exc_info[2] - try: - raise OuterException - except: - g(sys.exc_info()) - - def test_trace_basic(self): - import sys - l = [] - class Tracer: - def __init__(self, i): - self.i = i - def trace(self, frame, event, arg): - l.append((self.i, frame.f_code.co_name, event, arg)) - if frame.f_code.co_name == 'g2': - return None # don't trace g2 - return Tracer(self.i+1).trace - def g3(n): - n -= 5 - return n - def g2(n): - n += g3(2) - n += g3(7) - return n - def g(n): - n += g2(3) - return n - def f(n): - n = g(n) - return n * 7 - sys.settrace(Tracer(0).trace) - x = f(4) - sys.settrace(None) - assert x == 42 - print l - assert l == [(0, 'f', 'call', None), - (1, 'f', 'line', None), - (0, 'g', 'call', None), - (1, 'g', 'line', None), - (0, 'g2', 'call', None), - (0, 'g3', 'call', None), - (1, 'g3', 'line', None), - (2, 'g3', 'line', None), - (3, 'g3', 'return', -3), - (0, 'g3', 'call', None), - (1, 'g3', 'line', None), - (2, 'g3', 'line', None), - (3, 'g3', 'return', 2), - (2, 'g', 'line', None), - (3, 'g', 'return', 6), - (2, 'f', 'line', None), - (3, 'f', 'return', 42)] - - def test_trace_exc(self): - import sys - l = [] - def ltrace(a,b,c): - if b == 'exception': - l.append(c) - return ltrace - def trace(a,b,c): return ltrace - def f(): - try: - raise Exception - except: - pass - sys.settrace(trace) - f() - sys.settrace(None) - assert len(l) == 1 - assert isinstance(l[0][1], Exception) - - def test_trace_ignore_hidden(self): - import sys - import _testing - - l = [] - def trace(a,b,c): - l.append((a,b,c)) - - def f(): - h = _testing.Hidden() - r = h.meth() - return r - - sys.settrace(trace) - res = f() - sys.settrace(None) - assert len(l) == 1 - assert l[0][1] == 'call' - assert res == 'hidden' # sanity - - def test_trace_return_exc(self): - import sys - l = [] - def trace(a,b,c): - if b in ('exception', 'return'): - l.append((b, c)) - return trace - - def g(): - raise Exception - def f(): - try: - g() - except: - pass - sys.settrace(trace) - f() - sys.settrace(None) - assert len(l) == 4 - assert l[0][0] == 'exception' - assert isinstance(l[0][1][1], Exception) - assert l[1] == ('return', None) - assert l[2][0] == 'exception' - assert isinstance(l[2][1][1], Exception) - assert l[3] == ('return', None) - - def test_trace_raises_on_return(self): - import sys - def trace(frame, event, arg): - if event == 'return': - raise ValueError - else: - return trace - - def f(): return 1 - - for i in xrange(sys.getrecursionlimit() + 1): - sys.settrace(trace) - try: - f() - except ValueError: - pass - - def test_trace_try_finally(self): - import sys - l = [] - def trace(frame, event, arg): - if event == 'exception': - l.append(arg) - return trace - - def g(): - try: - raise Exception - finally: - pass - - def f(): - try: - g() - except: - pass - - sys.settrace(trace) - f() - sys.settrace(None) - assert len(l) == 2 - assert issubclass(l[0][0], Exception) - assert issubclass(l[1][0], Exception) - - def test_trace_raise_three_arg(self): - import sys - l = [] - def trace(frame, event, arg): - if event == 'exception': - l.append(arg) - return trace - - def g(): - try: - raise Exception - except Exception, e: - import sys - raise Exception, e, sys.exc_info()[2] - - def f(): - try: - g() - except: - pass - - sys.settrace(trace) - f() - sys.settrace(None) - assert len(l) == 2 - assert issubclass(l[0][0], Exception) - assert issubclass(l[1][0], Exception) - - - def test_trace_generator_finalisation(self): - # XXX expand to check more aspects - import sys - l = [] - def trace(frame, event, arg): - if event == 'exception': - l.append(arg) - return trace - - d = {} - exec """if 1: - def g(): - try: - yield True - finally: - pass - - def f(): - try: - gen = g() - gen.next() - gen.close() - except: - pass - """ in d - f = d['f'] - - sys.settrace(trace) - f() - sys.settrace(None) - assert len(l) == 1 - assert issubclass(l[0][0], GeneratorExit) - - def test_dont_trace_on_reraise(self): - import sys - l = [] - def ltrace(a,b,c): - if b == 'exception': - l.append(c) - return ltrace - def trace(a,b,c): return ltrace - def f(): - try: - 1/0 - except: - try: - raise - except: - pass - sys.settrace(trace) - f() - sys.settrace(None) - assert len(l) == 1 - assert issubclass(l[0][0], Exception) - - def test_dont_trace_on_raise_with_tb(self): - import sys - l = [] - def ltrace(a,b,c): - if b == 'exception': - l.append(c) - return ltrace - def trace(a,b,c): return ltrace - def f(): - try: - raise Exception - except: - return sys.exc_info() - def g(): - exc, val, tb = f() - try: - raise exc, val, tb - except: - pass - sys.settrace(trace) - g() - sys.settrace(None) - assert len(l) == 1 - assert isinstance(l[0][1], Exception) - - def test_trace_changes_locals(self): - import sys - def trace(frame, what, arg): - frame.f_locals['x'] = 42 - return trace - def f(x): - return x - sys.settrace(trace) - res = f(1) - sys.settrace(None) - assert res == 42 - -class AppTestJitTraceInteraction(object): - - def setup_class(cls): - from pypy import conftest - if not conftest.option.runappdirect: - py.test.skip("only for py.test -A") +class TestJitTraceInteraction(object): def test_trace_while_blackholing(self): import sys From arigo at codespeak.net Fri Jan 8 14:41:51 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 8 Jan 2010 14:41:51 +0100 (CET) Subject: [pypy-svn] r70454 - pypy/trunk/pypy/interpreter Message-ID: <20100108134151.3377D168106@codespeak.net> Author: arigo Date: Fri Jan 8 14:41:50 2010 New Revision: 70454 Modified: pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/interpreter/executioncontext.py pypy/trunk/pypy/interpreter/pyframe.py pypy/trunk/pypy/interpreter/pyopcode.py Log: For now, just killing a lot of "if we_are_jitted" is enough. These changes should be consistent with the branch/jit-trace-hook. Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Fri Jan 8 14:41:50 2010 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer -from pypy.rlib.jit import we_are_jitted, unroll_safe +from pypy.rlib.jit import unroll_safe import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -791,8 +791,7 @@ def call_valuestack(self, w_func, nargs, frame): from pypy.interpreter.function import Function, Method, is_builtin_code - if (not we_are_jitted() and frame.is_being_profiled and - is_builtin_code(w_func)): + if frame.is_being_profiled and is_builtin_code(w_func): # XXX: this code is copied&pasted :-( from the slow path below # call_valuestack(). args = frame.make_arguments(nargs) Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Fri Jan 8 14:41:50 2010 @@ -14,6 +14,11 @@ """An ExecutionContext holds the state of an execution thread in the Python interpreter.""" + # XXX JIT: when tracing (but not when blackholing!), the following + # XXX fields should be known to a constant None or False: + # XXX self.w_tracefunc, self.profilefunc + # XXX frame.is_being_profiled + def __init__(self, space): self.space = space self.topframeref = jit.vref_None @@ -53,17 +58,15 @@ def leave(self, frame): try: - if not jit.we_are_jitted(): - if self.profilefunc: - self._trace(frame, 'leaveframe', self.space.w_None) + if self.profilefunc: + self._trace(frame, 'leaveframe', self.space.w_None) finally: self.topframeref = frame.f_backref self.framestackdepth -= 1 jit.virtual_ref_finish(frame) - if not jit.we_are_jitted(): - if self.w_tracefunc is not None and not frame.hide(): - self.space.frame_trace_action.fire() + if self.w_tracefunc is not None and not frame.hide(): + self.space.frame_trace_action.fire() # ________________________________________________________________ @@ -182,6 +185,14 @@ actionflag.action_dispatcher(self, frame) # slow path bytecode_trace._always_inline_ = True + def bytecode_trace_after_exception(self, frame): + "Like bytecode_trace(), but without increasing the ticker." + actionflag = self.space.actionflag + ticker = actionflag.get() + if ticker & actionflag.interesting_bits: # fast check + actionflag.action_dispatcher(self, frame) # slow path + bytecode_trace_after_exception._always_inline_ = True + def exception_trace(self, frame, operationerr): "Trace function called upon OperationError." operationerr.record_interpreter_traceback() Modified: pypy/trunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/pypy/interpreter/pyframe.py Fri Jan 8 14:41:50 2010 @@ -9,7 +9,7 @@ from pypy.interpreter import pytraceback import opcode from pypy.rlib.objectmodel import we_are_translated, instantiate -from pypy.rlib.jit import we_are_jitted, hint +from pypy.rlib.jit import hint from pypy.rlib.debug import make_sure_not_resized from pypy.rlib import jit @@ -141,8 +141,7 @@ executioncontext = self.space.getexecutioncontext() executioncontext.enter(self) try: - if not we_are_jitted(): - executioncontext.call_trace(self) + executioncontext.call_trace(self) # Execution starts just after the last_instr. Initially, # last_instr is -1. After a generator suspends it points to # the YIELD_VALUE instruction. @@ -153,11 +152,9 @@ rstack.resume_point("execute_frame", self, executioncontext, returns=w_exitvalue) except Exception: - if not we_are_jitted(): - executioncontext.return_trace(self, self.space.w_None) + executioncontext.return_trace(self, self.space.w_None) raise - if not we_are_jitted(): - executioncontext.return_trace(self, w_exitvalue) + executioncontext.return_trace(self, w_exitvalue) finally: executioncontext.leave(self) return w_exitvalue Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Fri Jan 8 14:41:50 2010 @@ -130,7 +130,7 @@ def handle_operation_error(self, ec, operr, attach_tb=True): if attach_tb: - if not jit.we_are_jitted(): + if 1: # xxx this is a hack. It allows bytecode_trace() to # call a signal handler which raises, and catch the # raised exception immediately. See test_alarm_raise in @@ -146,15 +146,14 @@ trace = self.w_f_trace self.w_f_trace = None try: - ec.bytecode_trace(self) + ec.bytecode_trace_after_exception(self) finally: self.w_f_trace = trace except OperationError, e: operr = e pytraceback.record_application_traceback( self.space, operr, self, self.last_instr) - if not jit.we_are_jitted(): - ec.exception_trace(self, operr) + ec.exception_trace(self, operr) block = self.unrollstack(SApplicationException.kind) if block is None: @@ -913,13 +912,10 @@ arguments = f.popvalues(n_arguments) args = f.argument_factory(arguments, keywords, keywords_w, w_star, w_starstar) w_function = f.popvalue() - if jit.we_are_jitted(): - w_result = f.space.call_args(w_function, args) + if f.is_being_profiled and is_builtin_code(w_function): + w_result = f.space.call_args_and_c_profile(f, w_function, args) else: - if f.is_being_profiled and is_builtin_code(w_function): - w_result = f.space.call_args_and_c_profile(f, w_function, args) - else: - w_result = f.space.call_args(w_function, args) + w_result = f.space.call_args(w_function, args) rstack.resume_point("call_function", f, returns=w_result) f.pushvalue(w_result) From cfbolz at codespeak.net Fri Jan 8 17:20:03 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 8 Jan 2010 17:20:03 +0100 (CET) Subject: [pypy-svn] r70456 - pypy/branch/jit-trace-hook Message-ID: <20100108162003.A534C168109@codespeak.net> Author: cfbolz Date: Fri Jan 8 17:20:03 2010 New Revision: 70456 Removed: pypy/branch/jit-trace-hook/ Log: Killing the branch. Seems I misunderstood how the local trace function works, I'm sort of convinced now that r70454 is enough. From arigo at codespeak.net Fri Jan 8 20:23:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 8 Jan 2010 20:23:31 +0100 (CET) Subject: [pypy-svn] r70459 - in pypy/trunk/pypy/objspace: . test Message-ID: <20100108192331.E3F2F16810B@codespeak.net> Author: arigo Date: Fri Jan 8 20:23:31 2010 New Revision: 70459 Modified: pypy/trunk/pypy/objspace/descroperation.py pypy/trunk/pypy/objspace/test/test_descroperation.py Log: Test and fix for the case of an object defining __getslice__ but not __len__, and slicing with [x:y] with x >= 0 but y < 0. Modified: pypy/trunk/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/pypy/objspace/descroperation.py (original) +++ pypy/trunk/pypy/objspace/descroperation.py Fri Jan 8 20:23:31 2010 @@ -505,30 +505,42 @@ slice_max = Temp()[:] del Temp +def old_slice_range_getlength(space, w_obj): + # NB. the language ref is inconsistent with the new-style class + # behavior when w_obj doesn't implement __len__(), so we just + # follow cpython. Also note that CPython slots make it easier + # to check for object implementing it or not. We just catch errors + # so this behavior is slightly different + try: + return space.len(w_obj) + except OperationError, e: + if not ((e.match(space, space.w_AttributeError) or + e.match(space, space.w_TypeError))): + raise + return None + def old_slice_range(space, w_obj, w_start, w_stop): """Only for backward compatibility for __getslice__()&co methods.""" + w_length = None if space.is_w(w_start, space.w_None): w_start = space.wrap(0) else: - w_start = space.wrap(space.getindex_w(w_start, None)) - if space.is_true(space.lt(w_start, space.wrap(0))): - try: - w_start = space.add(w_start, space.len(w_obj)) - except OperationError, e: - if not ((e.match(space, space.w_AttributeError) or - e.match(space, space.w_TypeError))): - raise - # NB. the language ref is inconsistent with the new-style class - # behavior when w_obj doesn't implement __len__(), so we just - # follow cpython. Also note that CPython slots make it easier - # to check for object implementing it or not. We just catch errors - # so this behavior is slightly different + start = space.getindex_w(w_start, None) + w_start = space.wrap(start) + if start < 0: + w_length = old_slice_range_getlength(space, w_obj) + if w_length is not None: + w_start = space.add(w_start, w_length) if space.is_w(w_stop, space.w_None): w_stop = space.wrap(slice_max) else: - w_stop = space.wrap(space.getindex_w(w_stop, None)) - if space.is_true(space.lt(w_stop, space.wrap(0))): - w_stop = space.add(w_stop, space.len(w_obj)) + stop = space.getindex_w(w_stop, None) + w_stop = space.wrap(stop) + if stop < 0: + if w_length is None: + w_length = old_slice_range_getlength(space, w_obj) + if w_length is not None: + w_stop = space.add(w_stop, w_length) return w_start, w_stop # regular methods def helpers Modified: pypy/trunk/pypy/objspace/test/test_descroperation.py ============================================================================== --- pypy/trunk/pypy/objspace/test/test_descroperation.py (original) +++ pypy/trunk/pypy/objspace/test/test_descroperation.py Fri Jan 8 20:23:31 2010 @@ -174,6 +174,29 @@ (0, slice_max), ] + def test_getslice_nolength(self): + class Sq(object): + def __getslice__(self, start, stop): + return (start, stop) + def __getitem__(self, key): + return "booh" + + sq = Sq() + + assert sq[1:3] == (1,3) + slice_min, slice_max = sq[:] + assert slice_min == 0 + assert slice_max >= 2**31-1 + assert sq[1:] == (1, slice_max) + assert sq[:3] == (0, 3) + assert sq[:] == (0, slice_max) + # negative indices, but no __len__ + assert sq[-1:3] == (-1, 3) + assert sq[1:-3] == (1, -3) + assert sq[-1:-3] == (-1, -3) + # extended slice syntax always uses __getitem__() + assert sq[::] == "booh" + def test_ipow(self): x = 2 x **= 5 From arigo at codespeak.net Fri Jan 8 21:52:30 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 8 Jan 2010 21:52:30 +0100 (CET) Subject: [pypy-svn] r70461 - pypy/trunk/pypy/interpreter Message-ID: <20100108205230.876A91680F7@codespeak.net> Author: arigo Date: Fri Jan 8 21:52:28 2010 New Revision: 70461 Modified: pypy/trunk/pypy/interpreter/executioncontext.py Log: More precise comment. Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Fri Jan 8 21:52:28 2010 @@ -242,7 +242,8 @@ # in a piece of assembler currently running a CALL_MAY_FORCE, # then being forced means that it will fail the following # GUARD_NOT_FORCED operation, and so fall back to interpreted - # execution. + # execution. (We get this effect simply by reading the f_back + # field of all frames, during the loop below.) frame = self.gettopframe_nohidden() while frame: if is_being_profiled: From arigo at codespeak.net Fri Jan 8 21:55:16 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 8 Jan 2010 21:55:16 +0100 (CET) Subject: [pypy-svn] r70462 - in pypy/trunk/pypy: jit/metainterp rlib rpython rpython/lltypesystem rpython/test Message-ID: <20100108205516.6242A1680F8@codespeak.net> Author: arigo Date: Fri Jan 8 21:55:15 2010 New Revision: 70462 Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py pypy/trunk/pypy/jit/metainterp/policy.py pypy/trunk/pypy/rlib/rgc.py pypy/trunk/pypy/rpython/lltypesystem/rlist.py pypy/trunk/pypy/rpython/rlist.py pypy/trunk/pypy/rpython/test/test_rlist.py Log: Merge branch/morearraycopy: use rgc.ll_arraycopy more or less systematically. Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/codewriter.py Fri Jan 8 21:55:15 2010 @@ -86,12 +86,22 @@ if leave_graph is not None: todo.append(leave_graph) self.candidate_graphs = seen = set(todo) + + def callers(): + graph = top_graph + print graph + while graph in coming_from: + graph = coming_from[graph] + print '<-', graph + coming_from = {} + while todo: top_graph = todo.pop() for _, op in top_graph.iterblockops(): if op.opname not in ("direct_call", "indirect_call", "oosend"): continue kind = self.guess_call_kind(op, is_candidate) + # use callers() to view the calling chain in pdb if kind != "regular": continue for graph in self.graphs_from(op, is_candidate): @@ -100,6 +110,7 @@ assert is_candidate(graph) todo.append(graph) seen.add(graph) + coming_from[graph] = top_graph return self.candidate_graphs def graphs_from(self, op, is_candidate=None): Modified: pypy/trunk/pypy/jit/metainterp/policy.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/policy.py (original) +++ pypy/trunk/pypy/jit/metainterp/policy.py Fri Jan 8 21:55:15 2010 @@ -49,8 +49,6 @@ def look_inside_graph(self, graph): from pypy.translator.backendopt.support import find_backedges contains_loop = bool(find_backedges(graph)) - unsupported = contains_unsupported_variable_type(graph, - self.supports_floats) try: func = graph.func except AttributeError: @@ -61,7 +59,8 @@ contains_loop = contains_loop and not getattr( func, '_jit_unroll_safe_', False) - res = see_function and not unsupported + res = see_function and not contains_unsupported_variable_type(graph, + self.supports_floats) if res and contains_loop: self.unsafe_loopy_graphs.add(graph) return res and not contains_loop Modified: pypy/trunk/pypy/rlib/rgc.py ============================================================================== --- pypy/trunk/pypy/rlib/rgc.py (original) +++ pypy/trunk/pypy/rlib/rgc.py Fri Jan 8 21:55:15 2010 @@ -1,5 +1,7 @@ import gc from pypy.rpython.extregistry import ExtRegistryEntry +from pypy.rlib.objectmodel import we_are_translated + # ____________________________________________________________ # General GC features @@ -334,7 +336,12 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rlib.objectmodel import keepalive_until_here - assert source != dest + # supports non-overlapping copies only + if not we_are_translated(): + if source == dest: + assert (source_start + length <= dest_start or + dest_start + length <= source_start) + TP = lltype.typeOf(source).TO assert TP == lltype.typeOf(dest).TO if isinstance(TP.OF, lltype.Ptr) and TP.OF.TO._gckind == 'gc': @@ -357,6 +364,7 @@ keepalive_until_here(source) keepalive_until_here(dest) ll_arraycopy._annspecialcase_ = 'specialize:ll' +ll_arraycopy._jit_look_inside_ = False def no_collect(func): func._dont_inline_ = True Modified: pypy/trunk/pypy/rpython/lltypesystem/rlist.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rlist.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rlist.py Fri Jan 8 21:55:15 2010 @@ -368,8 +368,7 @@ else: LIST = typeOf(l).TO newitems = malloc(LIST.items.TO, n) - for i in range(n): - newitems[i] = olditems[i] + rgc.ll_arraycopy(olditems, newitems, 0, 0, n) return newitems ll_list2fixed.oopspec = 'list.list2fixed(l)' Modified: pypy/trunk/pypy/rpython/rlist.py ============================================================================== --- pypy/trunk/pypy/rpython/rlist.py (original) +++ pypy/trunk/pypy/rpython/rlist.py Fri Jan 8 21:55:15 2010 @@ -11,6 +11,7 @@ from pypy.rlib.debug import ll_assert from pypy.rlib.rarithmetic import ovfcheck, widen from pypy.rpython.annlowlevel import ADTInterface +from pypy.rlib import rgc ADTIFixedList = ADTInterface(None, { 'll_newlist': (['SELF', Signed ], 'self'), @@ -525,13 +526,24 @@ return LIST.ITEM +def ll_arraycopy(source, dest, source_start, dest_start, length): + SRCTYPE = typeOf(source) + if isinstance(SRCTYPE, Ptr): + # lltype + rgc.ll_arraycopy(source.ll_items(), dest.ll_items(), + source_start, dest_start, length) + else: + # ootype -- XXX improve the case of array->array copy? + i = 0 + while i < length: + item = source.ll_getitem_fast(source_start + i) + dest.ll_setitem_fast(dest_start + i, item) + i += 1 + def ll_copy(RESLIST, l): length = l.ll_length() new_lst = RESLIST.ll_newlist(length) - i = 0 - while i < length: - new_lst.ll_setitem_fast(i, l.ll_getitem_fast(i)) - i += 1 + ll_arraycopy(l, new_lst, 0, 0, length) return new_lst def ll_len(l): @@ -574,15 +586,8 @@ except OverflowError: raise MemoryError l = RESLIST.ll_newlist(newlength) - j = 0 - while j < len1: - l.ll_setitem_fast(j, l1.ll_getitem_fast(j)) - j += 1 - i = 0 - while i < len2: - l.ll_setitem_fast(j, l2.ll_getitem_fast(i)) - i += 1 - j += 1 + ll_arraycopy(l1, l, 0, 0, len1) + ll_arraycopy(l2, l, 0, len1, len2) return l def ll_insert_nonneg(l, index, newitem): @@ -769,12 +774,7 @@ except OverflowError: raise MemoryError l1._ll_resize_ge(newlength) - i = 0 - j = len1 - while i < len2: - l1.ll_setitem_fast(j, l2.ll_getitem_fast(i)) - i += 1 - j += 1 + ll_arraycopy(l2, l1, 0, len1, len2) ll_extend.oopspec = 'list.extend(l1, l2)' def ll_extend_with_str(lst, s, getstrlen, getstritem): @@ -867,12 +867,7 @@ ll_assert(start <= len1, "list slice start larger than list length") newlength = len1 - start l = RESLIST.ll_newlist(newlength) - j = 0 - i = start - while i < len1: - l.ll_setitem_fast(j, l1.ll_getitem_fast(i)) - i += 1 - j += 1 + ll_arraycopy(l1, l, start, 0, newlength) return l ll_listslice_startonly._annenforceargs_ = (None, None, int) @@ -885,22 +880,14 @@ stop = length newlength = stop - start l = RESLIST.ll_newlist(newlength) - j = 0 - i = start - while i < stop: - l.ll_setitem_fast(j, l1.ll_getitem_fast(i)) - i += 1 - j += 1 + ll_arraycopy(l1, l, start, 0, newlength) return l def ll_listslice_minusone(RESLIST, l1): newlength = l1.ll_length() - 1 ll_assert(newlength >= 0, "empty list is sliced with [:-1]") l = RESLIST.ll_newlist(newlength) - j = 0 - while j < newlength: - l.ll_setitem_fast(j, l1.ll_getitem_fast(j)) - j += 1 + ll_arraycopy(l1, l, 0, 0, newlength) return l def ll_listdelslice_startonly(l, start): @@ -945,13 +932,8 @@ ll_assert(start <= l1.ll_length(), "l[start:x] = l with start > len(l)") ll_assert(count == stop - start, "setslice cannot resize lists in RPython") - # XXX but it should be easy enough to support, soon - j = start - i = 0 - while i < count: - l1.ll_setitem_fast(j, l2.ll_getitem_fast(i)) - i += 1 - j += 1 + # XXX ...but it would be easy enough to support if really needed + ll_arraycopy(l2, l1, 0, start, count) ll_listsetslice.oopspec = 'list.setslice(l1, start, stop, l2)' # ____________________________________________________________ Modified: pypy/trunk/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/trunk/pypy/rpython/test/test_rlist.py (original) +++ pypy/trunk/pypy/rpython/test/test_rlist.py Fri Jan 8 21:55:15 2010 @@ -410,13 +410,18 @@ assert res.item2 == 9 def test_bltn_list(self): - def dummyfn(): - l1 = [42] - l2 = list(l1) - l2[0] = 0 - return l1[0] - res = self.interpret(dummyfn, ()) - assert res == 42 + # test for ll_copy() + for resize1 in [False, True]: + for resize2 in [False, True]: + def dummyfn(): + l1 = [42] + if resize1: l1.append(43) + l2 = list(l1) + if resize2: l2.append(44) + l2[0] = 0 + return l1[0] + res = self.interpret(dummyfn, ()) + assert res == 42 def test_is_true(self): def is_true(lst): From arigo at codespeak.net Fri Jan 8 21:55:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 8 Jan 2010 21:55:40 +0100 (CET) Subject: [pypy-svn] r70463 - pypy/branch/morearraycopy Message-ID: <20100108205540.714F71680F8@codespeak.net> Author: arigo Date: Fri Jan 8 21:55:39 2010 New Revision: 70463 Removed: pypy/branch/morearraycopy/ Log: Remove merged branch. From arigo at codespeak.net Fri Jan 8 23:11:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 8 Jan 2010 23:11:31 +0100 (CET) Subject: [pypy-svn] r70464 - pypy/trunk/pypy/translator/benchmark Message-ID: <20100108221131.89B201680FA@codespeak.net> Author: arigo Date: Fri Jan 8 23:11:29 2010 New Revision: 70464 Modified: pypy/trunk/pypy/translator/benchmark/bench-custom.py pypy/trunk/pypy/translator/benchmark/jitbench.py Log: Print errors to stdout instead of sending them to SystemExit to avoid a broken order of output (they are printed to stderr in that case). Modified: pypy/trunk/pypy/translator/benchmark/bench-custom.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/bench-custom.py (original) +++ pypy/trunk/pypy/translator/benchmark/bench-custom.py Fri Jan 8 23:11:29 2010 @@ -88,7 +88,8 @@ print if final_error_count: - raise SystemExit("%d benchmark run(s) failed" % final_error_count) + raise SystemExit("%d benchmark run(s) failed (see -FAILED- above)" + % final_error_count) if __name__ == '__main__': from optparse import OptionParser Modified: pypy/trunk/pypy/translator/benchmark/jitbench.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/jitbench.py (original) +++ pypy/trunk/pypy/translator/benchmark/jitbench.py Fri Jan 8 23:11:29 2010 @@ -23,7 +23,8 @@ try: execfile('bench-custom.py') except SystemExit, e: - errors.append(str(e)) + errors.append('%s:*%s: %s' % (executable, sizefactor, e)) if errors: - raise SystemExit('\n'.join(errors)) + print '\n'.join(errors) + sys.exit(1) From arigo at codespeak.net Sat Jan 9 12:05:54 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 9 Jan 2010 12:05:54 +0100 (CET) Subject: [pypy-svn] r70466 - pypy/trunk/pypy/translator/c/test Message-ID: <20100109110554.E71B01683B6@codespeak.net> Author: arigo Date: Sat Jan 9 12:05:53 2010 New Revision: 70466 Modified: pypy/trunk/pypy/translator/c/test/test_boehm.py Log: A missing keepalive_until_here() to keep the list alive. Unfortunately the test keeps failing on wyvern, even with this change. Modified: pypy/trunk/pypy/translator/c/test/test_boehm.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_boehm.py (original) +++ pypy/trunk/pypy/translator/c/test/test_boehm.py Sat Jan 9 12:05:53 2010 @@ -4,6 +4,7 @@ from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.memory.test import snippet from pypy.translator.c.genc import CExtModuleBuilder +from pypy.rlib.objectmodel import keepalive_until_here from pypy import conftest def setup_module(mod): @@ -290,6 +291,7 @@ assert a.index == i & ~1 else: count_free += 1 + keepalive_until_here(keepalive) return count_free c_fn = self.getcompiled(fn, [int]) res = c_fn(7000) From arigo at codespeak.net Sat Jan 9 12:27:52 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 9 Jan 2010 12:27:52 +0100 (CET) Subject: [pypy-svn] r70467 - pypy/trunk/pypy/translator/c Message-ID: <20100109112752.490E11683B6@codespeak.net> Author: arigo Date: Sat Jan 9 12:27:51 2010 New Revision: 70467 Modified: pypy/trunk/pypy/translator/c/gc.py Log: Fix test_boehm: we cannot ignore keepalives in case of Boehm, because we might be unlucky and at the C level the variable gets overridden with another variable. No clue why test_boehm started to fail now, though. Modified: pypy/trunk/pypy/translator/c/gc.py ============================================================================== --- pypy/trunk/pypy/translator/c/gc.py (original) +++ pypy/trunk/pypy/translator/c/gc.py Sat Jan 9 12:27:51 2010 @@ -253,6 +253,9 @@ nbytes = funcgen.expr(op.args[0]) return 'GC_set_max_heap_size(%s);' % (nbytes,) + def GC_KEEPALIVE(self, funcgen, v): + return 'pypy_asm_keepalive(%s);' % funcgen.expr(v) + class BoehmGcRuntimeTypeInfo_OpaqueNode(ContainerNode): nodekind = 'boehm rtti' globalcontainer = True From arigo at codespeak.net Sat Jan 9 14:48:36 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 9 Jan 2010 14:48:36 +0100 (CET) Subject: [pypy-svn] r70469 - pypy/branch/c-traceback Message-ID: <20100109134836.B52681683B6@codespeak.net> Author: arigo Date: Sat Jan 9 14:48:36 2010 New Revision: 70469 Added: pypy/branch/c-traceback/ - copied from r70467, pypy/trunk/ Log: A branch in which to try to improve the reporting of fatal RPython errors. This concerns mostly the situation in which we get the message "Fatal RPython error: SomeExceptionClass", but might also concern the failing RPyAsserts or "NULL ptr or bad array index" errors (handled differently). From dan at codespeak.net Sat Jan 9 20:17:20 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Sat, 9 Jan 2010 20:17:20 +0100 (CET) Subject: [pypy-svn] r70470 - pypy/branch/micronumpy/pypy/module/micronumpy Message-ID: <20100109191720.8904F1683BC@codespeak.net> Author: dan Date: Sat Jan 9 20:17:18 2010 New Revision: 70470 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py pypy/branch/micronumpy/pypy/module/micronumpy/array.py pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py Log: Refactored to remove ndarray.py as it was becomming a thinner and thinner wrapper around sdarray and mdarray. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/__init__.py Sat Jan 9 20:17:18 2010 @@ -7,9 +7,9 @@ appleveldefs = {} interpleveldefs = { - 'array' : 'ndarray.array', - 'ndarray' : 'ndarray.ndarray', - 'zeros' : 'ndarray.zeros', + 'array' : 'array.array', + 'ndarray' : 'array.ndarray', + 'zeros' : 'array.zeros', 'minimum' : 'ufunc.minimum', } Modified: pypy/branch/micronumpy/pypy/module/micronumpy/array.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/array.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/array.py Sat Jan 9 20:17:18 2010 @@ -1,12 +1,25 @@ -class BaseNumArray(object): +from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable +from pypy.interpreter.error import OperationError +from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.gateway import NoneNotWrapped +from pypy.interpreter.gateway import interp2app, NoneNotWrapped + +from pypy.module.micronumpy.dtype import iterable_type + +class BaseNumArray(Wrappable): pass -def iterable_type(space, w_xs): - xs = space.fixedview(w_xs) - type = int - for i in range(len(xs)): - type = result_types[type, xs[i]] - return type +def validate_index(array, space, w_i): + try: + index_dimensionality = space.int_w(space.len(w_i)) + array_dimensionality = len(array.shape) + if index_dimensionality > array_dimensionality: + raise OperationError(space.w_IndexError, + space.wrap("Index dimensionality (%d) greater than array dimensionality (%d)." % (index_dimensionality, array_dimensionality))) + except OperationError, e: + if e.match(space, space.w_TypeError): pass + else: raise + def mul_operation(): def mul(x, y): return x * y @@ -47,3 +60,62 @@ def sub(space, x, y): return space.sub(x, y) return sub + +def unpack_shape(space, w_shape): + if space.is_true(space.isinstance(w_shape, space.w_int)): + return [space.int_w(w_shape)] + shape_w = space.fixedview(w_shape) + return [space.int_w(w_i) for w_i in shape_w] + +def infer_shape(space, w_values): + return [space.int_w(space.len(w_values))] #TODO: handle multi-dimensional arrays... + +def construct_array(space, shape, w_dtype): + from pypy.module.micronumpy.sdarray import sdresult + from pypy.module.micronumpy.mdarray import mdresult + try: + if len(shape) == 1: + length = shape[0] + return sdresult(space, w_dtype)(space, length, w_dtype) + else: + return mdresult(space, w_dtype)(space, shape) + except KeyError, e: + raise OperationError(space.w_NotImplementedError, + space.wrap("Haven't implemented generic array yet!")) + +def descr_new(space, w_cls, w_shape, w_dtype=NoneNotWrapped, + w_buffer=NoneNotWrapped, w_offset=NoneNotWrapped, + w_strides=NoneNotWrapped, order='C'): + shape_w = unpack_shape(space, w_shape) + result = construct_array(space, shape_w, w_dtype) + #TODO: load from buffer? + return space.wrap(result) +descr_new.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root, + W_Root, W_Root, + W_Root, str] + +BaseNumArray.typedef = TypeDef("ndarray", + __new__ = interp2app(descr_new), + ) +base_typedef = BaseNumArray.typedef +ndarray = BaseNumArray + +def array(space, w_values, w_dtype=NoneNotWrapped, + copy=True, order='C', + subok=False, ndim=1): + shape = infer_shape(space, w_values) + + if w_dtype is None: + w_dtype = iterable_type(space, w_values) + result = construct_array(space, shape, w_dtype) + result.load_iterable(w_values) + return space.wrap(result) +array.unwrap_spec = [ObjSpace, W_Root, W_Root, + bool, str, + bool, int] + +def zeros(space, w_shape, w_dtype=NoneNotWrapped, order='C'): + shape_w = unpack_shape(space, w_shape) + result = construct_array(space, shape_w, w_dtype) + return space.wrap(result) +zeros.unwrap_spec = [ObjSpace, W_Root, W_Root, str] Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py Sat Jan 9 20:17:18 2010 @@ -13,3 +13,19 @@ return float32(space.float_w(w_x)) def coerce_float32(space, w_x): return unwrap_float32(space, space.float(w_x)) + +def result_mapping(space, w_types): + types = { + (space.w_int, space.w_int): space.w_int, + (space.w_int, space.w_float): space.w_float, + (space.w_float, space.w_int): space.w_float, + (space.w_float, space.w_float): space.w_float + } + return types[w_types] + +def iterable_type(space, w_xs): + xs = space.fixedview(w_xs) + result_type = space.w_int + for i in range(len(xs)): + result_type = result_mapping(space, (result_type, space.type(xs[i]))) + return result_type Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py Sat Jan 9 20:17:18 2010 @@ -5,6 +5,7 @@ from pypy.rlib.debug import make_sure_not_resized from pypy.module.micronumpy.array import BaseNumArray +from pypy.module.micronumpy.array import base_typedef from pypy.module.micronumpy.dtype import unwrap_int, coerce_int from pypy.module.micronumpy.dtype import unwrap_float, coerce_float @@ -37,6 +38,18 @@ self.storage = [data_type(0.0)] * size make_sure_not_resized(self.storage) + def load_iterable(self, w_xs): + self._internal_load(w_xs, self.shape) + + def _internal_load(self, w_xs, shape): + space = self.space + length = shape[0] + xs = space.fixedview(w_xs, length) + + #FIXME: brain no work, do later + #for x in xs: + #self + def _unpack_indexes(self, space, w_index): indexes = [space.int_w(w_i) for w_i in space.fixedview(w_index)] if len(indexes) != len(self.shape): @@ -44,17 +57,19 @@ 'Wrong index')) return indexes - def getitem(self, w_index): + def descr_getitem(self, w_index): space = self.space indexes = self._unpack_indexes(space, w_index) pos = compute_pos(space, indexes, self.shape) return space.wrap(self.storage[pos]) + descr_getitem.unwrap_spec = ['self', W_Root] - def setitem(self, w_index, w_value): + def descr_setitem(self, w_index, w_value): space = self.space indexes = self._unpack_indexes(space, w_index) pos = compute_pos(space, indexes, self.shape) self.storage[pos] = coerce(space, w_value) + descr_setitem.unwrap_spec = ['self', W_Root, W_Root] def load_iterable(self, w_xs): space = self.space @@ -62,13 +77,21 @@ space.wrap("Haven't implemented iterable loading yet!")) def len(self): + return self.shape[0] + + def descr_len(self): space = self.space - return space.wrap(self.shape[0]) + return space.wrap(self.len()) + descr_len.unwrap_spec = ['self'] + MultiDimArray.typedef = TypeDef('ndarray', base_typedef, + __len__ = interp2app(MultiDimArray.descr_len), + __getitem__ = interp2app(MultiDimArray.descr_getitem), + __setitem__ = interp2app(MultiDimArray.descr_setitem), + ) return MultiDimArray MultiDimIntArray = create_mdarray(int, unwrap_int, coerce_int) -MultiDimArray = MultiDimIntArray #XXX: compatibility MultiDimFloatArray = create_mdarray(float, unwrap_float, coerce_float) class ResultFactory(object): Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Sat Jan 9 20:17:18 2010 @@ -3,49 +3,69 @@ from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import interp2app, NoneNotWrapped from pypy.rlib.debug import make_sure_not_resized -from pypy.objspace.std.typeobject import W_TypeObject from pypy.module.micronumpy.array import BaseNumArray +from pypy.module.micronumpy.array import base_typedef from pypy.module.micronumpy.array import mul_operation, div_operation, add_operation, sub_operation from pypy.module.micronumpy.array import copy_operation + from pypy.module.micronumpy.dtype import unwrap_int, coerce_int from pypy.module.micronumpy.dtype import unwrap_float, coerce_float from pypy.module.micronumpy.dtype import unwrap_float32, coerce_float32, float32 +from pypy.module.micronumpy.dtype import result_mapping # from pypy.interpreter.gateway import unwrap_spec #TODO: merge unwrap_spec decorator class BaseSingleDimArray(BaseNumArray): pass def create_sdarray(data_type, unwrap, coerce): + class SingleDimIterator(Wrappable): + def __init__(self, space, array, i): + self.space = space + self.array = array + self.i = i + + def descr_iter(self): + self.space = space + return space.wrap(self) + descr_iter.unwrap_spec = ['self'] + + def descr_next(self): + space = self.space + try: + result = self.array.storage[self.i] + self.i += 1 + return space.wrap(result) + except IndexError, e: + raise OperationError(space.w_StopIteration, space.wrap("")) + descr_iter.unwrap_spec = ['self'] + + SingleDimIterator.typedef = TypeDef('iterator', + __iter__ = interp2app(SingleDimIterator.descr_iter), + next = interp2app(SingleDimIterator.descr_next) + ) + + mul = mul_operation() + div = div_operation() + add = add_operation() + sub = sub_operation() + copy = copy_operation() + class NumArray(BaseSingleDimArray): - def __init__(self, space, length): - self.shape = (1,) - self.length = length + def __init__(self, space, length, dtype): + self.shape = (length,) self.space = space - self.storage = [data_type(0.0)] * length + self.storage = [data_type()] * length + self.dtype = dtype make_sure_not_resized(self.storage) - mul = mul_operation() - div = div_operation() - add = add_operation() - sub = sub_operation() - copy = copy_operation() - - def create_scalar_op(f): - def scalar_operation(self, source, w_x): - space = self.space + def create_math_operation(f): + def scalar_operation(result, source, w_x): + space = result.space x = coerce(space, w_x) - for i in range(source.length): - self.storage[i] = f(data_type(source.storage[i]), x) - return scalar_operation - - mul_scalar = create_scalar_op(mul) - div_scalar = create_scalar_op(div) - add_scalar = create_scalar_op(add) - sub_scalar = create_scalar_op(sub) + for i in range(len(source.storage)): + result.storage[i] = f(data_type(source.storage[i]), x) - #TODO: wrap up fixedview and scalar together - def create_fixedview_op(f): def fixedview_operation(self, w_xs): space = self.space try: @@ -60,47 +80,100 @@ self.storage[i] = f(source.storage[i], self.coerce(w_x)) #TODO: probably shouldn't coerce i += 1 return result - return fixedview_operation - copy_iterable = create_fixedview_op(copy) + def math_operation(self, w_x): + space = self.space + if space.type(w_x) in (space.w_list, space.w_tuple): + raise OperationError(space.w_NotImplementedError, + space.wrap("Haven't implemented array * iterable yet!")) + else: + result_t = result_mapping(space, (space.type(w_x), self.dtype)) + result = sdresult(space, result_t)(space, self.len(), self.dtype) + scalar_operation(result, self, w_x) + + w_result = space.wrap(result) + return w_result + math_operation.unwrap_spec = ['self', W_Root] + return math_operation + + descr_mul = create_math_operation(mul) + descr_mul.__name__ = 'descr_mul' + + descr_div = create_math_operation(div) + descr_div.__name__ = 'descr_div' + + descr_add = create_math_operation(add) + descr_add.__name__ = 'descr_add' + + descr_sub = create_math_operation(sub) + descr_sub.__name__ = 'descr_sub' - def load_iterable(self, w_values): #FIXME: less than ideal + def load_iterable(self, w_values): space = self.space i = 0 - for x in space.fixedview(w_values, self.length): - self.storage[i] = unwrap(space, x) + for x in space.fixedview(w_values, self.len()): + self.storage[i] = coerce(space, x) i += 1 - def getitem(self, w_index): + def descr_iter(self): + return space.wrap(SingleDimIterator(space, self, 0)) + descr_iter.unwrap_spec = ['self'] + + def descr_getitem(self, index): space = self.space - index = space.int_w(w_index) try: return space.wrap(self.storage[index]) except IndexError: raise OperationError(space.w_IndexError, space.wrap("list index out of range")) + descr_getitem.unwrap_spec = ['self', int] - def setitem(self, w_index, w_value): + def descr_setitem(self, index, w_value): space = self.space - index = space.int_w(w_index) try: self.storage[index] = coerce(space, w_value) except IndexError: raise OperationError(space.w_IndexError, space.wrap("list index out of range")) return space.w_None + descr_setitem.unwrap_spec = ['self', int, W_Root] def len(self): + return len(self.storage) + + def descr_len(self): space = self.space - return space.wrap(len(self.storage)) + return space.wrap(self.len()) + descr_len.unwrap_spec = ['self'] def str(self): return ', '.join([str(x) for x in self.storage]) + def descr_str(self): + space = self.space + return space.wrap("[%s]" % self.str()) + descr_str.unwrap_spec = ['self'] + + def descr_repr(self): + space = self.space + return space.wrap("array([%s])" % self.str()) + descr_repr.unwrap_spec = ['self'] + + NumArray.typedef = TypeDef('ndarray', base_typedef, + __mul__ = interp2app(NumArray.descr_mul), + __div__ = interp2app(NumArray.descr_div), + __add__ = interp2app(NumArray.descr_add), + __sub__ = interp2app(NumArray.descr_sub), + __getitem__ = interp2app(NumArray.descr_getitem), + __setitem__ = interp2app(NumArray.descr_setitem), + __len__ = interp2app(NumArray.descr_len), + __str__ = interp2app(NumArray.descr_str), + __repr__ = interp2app(NumArray.descr_repr), + ) + return NumArray IntArray = create_sdarray(int, unwrap_int, coerce_int) -NumArray = IntArray # FIXME: compatibility for now FloatArray = create_sdarray(float, unwrap_float, coerce_float) Float32Array = create_sdarray(float32, unwrap_float32, coerce_float32) GenericArray = None Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py Sat Jan 9 20:17:18 2010 @@ -1,4 +1,4 @@ -from pypy.module.micronumpy.ndarray import array, zeros, ndarray +from pypy.module.micronumpy.array import array, zeros, ndarray from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError @@ -6,16 +6,16 @@ if not isinstance(w_a, ndarray) or not isinstance(w_b, ndarray): raise OperationError(space.w_TypeError, space.wrap("expecting ndarray object")) - if w_a.array.length != w_b.array.length: + if w_a.len()!= w_b.len(): raise OperationError(space.w_ValueError, space.wrap("minimum of arrays of different length")) - res = zeros(space, space.wrap(w_a.array.length), w_a.dtype) - for i in range(len(w_a.array.storage)): - one = w_a.array.storage[i] - two = w_b.array.storage[i] + res = zeros(space, space.wrap(w_a.len()), w_a.dtype) + for i in range(len(w_a.storage)): + one = w_a.storage[i] + two = w_b.storage[i] if one < two: - res.array.storage[i] = one + res.storage[i] = one else: - res.array.storage[i] = two + res.storage[i] = two return space.wrap(res) minimum.unwrap_spec = [ObjSpace, W_Root, W_Root] From arigo at codespeak.net Sat Jan 9 21:49:50 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 9 Jan 2010 21:49:50 +0100 (CET) Subject: [pypy-svn] r70471 - pypy/branch/c-traceback/pypy/translator Message-ID: <20100109204950.DC7031683BA@codespeak.net> Author: arigo Date: Sat Jan 9 21:49:48 2010 New Revision: 70471 Modified: pypy/branch/c-traceback/pypy/translator/exceptiontransform.py Log: Remove these two lines. Modified: pypy/branch/c-traceback/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/exceptiontransform.py (original) +++ pypy/branch/c-traceback/pypy/translator/exceptiontransform.py Sat Jan 9 21:49:48 2010 @@ -80,8 +80,6 @@ def rpyexc_raise(etype, evalue): # assert(!RPyExceptionOccurred()); - ll_assert(etype != assertion_error_ll_exc_type, "AssertionError!") - ll_assert(etype != n_i_error_ll_exc_type, "NotImplementedError!") exc_data.exc_type = etype exc_data.exc_value = evalue From arigo at codespeak.net Sat Jan 9 21:50:08 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 9 Jan 2010 21:50:08 +0100 (CET) Subject: [pypy-svn] r70472 - in pypy/branch/c-traceback/pypy/translator/c: . test Message-ID: <20100109205008.BF6CB1683BA@codespeak.net> Author: arigo Date: Sat Jan 9 21:50:06 2010 New Revision: 70472 Modified: pypy/branch/c-traceback/pypy/translator/c/genc.py pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Log: Add a test, not passing so far. Modified: pypy/branch/c-traceback/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/genc.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/genc.py Sat Jan 9 21:50:06 2010 @@ -430,12 +430,16 @@ bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph()) - def cmdexec(self, args='', env=None, err=False): + def cmdexec(self, args='', env=None, err=False, expect_crash=False): assert self._compiled res = self.translator.platform.execute(self.executable_name, args, env=env) if res.returncode != 0: + if expect_crash: + return res.out, res.err raise Exception("Returned %d" % (res.returncode,)) + if expect_crash: + raise Exception("Program did not crash!") if err: return res.out, res.err return res.out Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Sat Jan 9 21:50:06 2010 @@ -377,6 +377,39 @@ assert not err assert path.check(file=0) + def test_fatal_error(self): + def g(x): + if x == 1: + raise ValueError + else: + raise KeyError + def entry_point(argv): + if len(argv) < 3: + g(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: ValueError' + assert len(lines) >= 4 + l0, l1, l2 = lines[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in g', l1) + assert re.match(r' File "\w+.c", line \d+, in entry_point', l2) + # + out2, err2 = cbuilder.cmdexec("x", expect_crash=True) + assert out2.strip() == '' + lines2 = err2.strip().splitlines() + assert lines2[-1] == 'Fatal RPython error: KeyError' + l0, l1, l2 = lines2[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in g', l1) + assert re.match(r' File "\w+.c", line \d+, in entry_point', l2) + assert lines2[-3] != lines[-3] + assert lines2[-2] == lines[-2] + class TestMaemo(TestStandalone): def setup_class(cls): From arigo at codespeak.net Sat Jan 9 21:54:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 9 Jan 2010 21:54:31 +0100 (CET) Subject: [pypy-svn] r70473 - pypy/branch/c-traceback/pypy/translator/c/test Message-ID: <20100109205431.81F5E1683BA@codespeak.net> Author: arigo Date: Sat Jan 9 21:54:30 2010 New Revision: 70473 Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Log: Another test. Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Sat Jan 9 21:54:30 2010 @@ -410,6 +410,30 @@ assert lines2[-3] != lines[-3] assert lines2[-2] == lines[-2] + def test_assertion_error(self): + def g(x): + assert x != 1 + def f(argv): + try: + g(len(argv)) + finally: + print 'done' + def entry_point(argv): + f(argv) + return 0 + t, cbuilder = self.compile(entry_point) + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: AssertionError' + assert len(lines) >= 4 + l0, l1, l2 = lines[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in g', l1) + assert re.match(r' File "\w+.c", line \d+, in f', l2) + # The traceback stops at f() because it's the first function that + # captures the AssertionError, which makes the program abort. + class TestMaemo(TestStandalone): def setup_class(cls): From arigo at codespeak.net Sat Jan 9 22:06:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 9 Jan 2010 22:06:09 +0100 (CET) Subject: [pypy-svn] r70474 - pypy/branch/c-traceback/pypy/translator/c/test Message-ID: <20100109210609.C7E601683BA@codespeak.net> Author: arigo Date: Sat Jan 9 22:06:09 2010 New Revision: 70474 Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Log: A third (non-passing) test describing how I would like pypy-c to display fatal errors. Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Sat Jan 9 22:06:09 2010 @@ -21,7 +21,7 @@ t.buildrtyper().specialize() cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() + cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() return t, cbuilder @@ -434,6 +434,30 @@ # The traceback stops at f() because it's the first function that # captures the AssertionError, which makes the program abort. + def test_ll_assert_error(self): + def g(x): + ll_assert(x != 1, "foobar") + def f(argv): + try: + g(len(argv)) + finally: + print 'done' + def entry_point(argv): + f(argv) + return 0 + t, cbuilder = self.compile(entry_point) + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'PyPy assertion failed: foobar' + assert len(lines) >= 4 + l0, l1, l2 = lines[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in g', l1) + assert re.match(r' File "\w+.c", line \d+, in f', l2) + # The traceback stops at f() because it's the first function that + # captures the AssertionError, which makes the program abort. + class TestMaemo(TestStandalone): def setup_class(cls): @@ -464,7 +488,7 @@ t.buildrtyper().specialize() # cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() + cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() # return t, cbuilder From benjamin at codespeak.net Sun Jan 10 00:50:32 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 10 Jan 2010 00:50:32 +0100 (CET) Subject: [pypy-svn] r70475 - in pypy/trunk/pypy/module/imp: . test Message-ID: <20100109235032.38DE41683BE@codespeak.net> Author: benjamin Date: Sun Jan 10 00:50:30 2010 New Revision: 70475 Modified: pypy/trunk/pypy/module/imp/importing.py pypy/trunk/pypy/module/imp/test/test_import.py Log: reload loaded modules from sys.modules during import like cpython does Modified: pypy/trunk/pypy/module/imp/importing.py ============================================================================== --- pypy/trunk/pypy/module/imp/importing.py (original) +++ pypy/trunk/pypy/module/imp/importing.py Sun Jan 10 00:50:30 2010 @@ -389,6 +389,7 @@ try: if find_info: w_mod = load_module(space, w_modulename, find_info) + w_mod = space.getitem(space.sys.get("modules"), w_modulename) if w_parent is not None: space.setattr(w_parent, space.wrap(partname), w_mod) return w_mod Modified: pypy/trunk/pypy/module/imp/test/test_import.py ============================================================================== --- pypy/trunk/pypy/module/imp/test/test_import.py (original) +++ pypy/trunk/pypy/module/imp/test/test_import.py Sun Jan 10 00:50:30 2010 @@ -69,6 +69,11 @@ "print 'TOTO', __name__\n" "sys.modules[__name__] = pkg_substituted") setuppkg("pkg_substituted", mod='') + setuppkg("evil_pkg", + evil = "import sys\n" + "from evil_pkg import good\n" + "sys.modules['evil_pkg.evil'] = good", + good = "a = 42") p = setuppkg("readonly", x='') p = setuppkg("pkg_univnewlines") p.join('__init__.py').write( @@ -134,6 +139,10 @@ def teardown_class(cls): # interpreter-level _teardown(cls.space, cls.saved_modules) + def test_set_sys_modules_during_import(self): + from evil_pkg import evil + assert evil.a == 42 + def test_import_bare_dir_fails(self): def imp(): import notapackage @@ -823,6 +832,7 @@ class Importer(object): def find_module(self, fullname, path=None): if fullname == "a": + sys.modules["a"] = self return self def load_module(self, name): From benjamin at codespeak.net Sun Jan 10 04:47:03 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 10 Jan 2010 04:47:03 +0100 (CET) Subject: [pypy-svn] r70476 - pypy/trunk/pypy/module/imp Message-ID: <20100110034703.614D11683B6@codespeak.net> Author: benjamin Date: Sun Jan 10 04:47:01 2010 New Revision: 70476 Modified: pypy/trunk/pypy/module/imp/importing.py Log: simplify by using space.finditem Modified: pypy/trunk/pypy/module/imp/importing.py ============================================================================== --- pypy/trunk/pypy/module/imp/importing.py (original) +++ pypy/trunk/pypy/module/imp/importing.py Sun Jan 10 04:47:01 2010 @@ -77,26 +77,8 @@ # hasattr, which eats all exceptions. return None -def try_getitem(space, w_obj, w_key): - try: - return space.getitem(w_obj, w_key) - except OperationError, e: - if not e.match(space, space.w_KeyError): - raise - return None - - def check_sys_modules(space, w_modulename): - w_modules = space.sys.get('modules') - try: - w_mod = space.getitem(w_modules, w_modulename) - except OperationError, e: - pass - else: - return w_mod - if not e.match(space, space.w_KeyError): - raise - return None + return space.finditem(space.sys.get('modules'), w_modulename) def importhook(space, modulename, w_globals=None, w_locals=None, w_fromlist=None, level=-1): @@ -110,8 +92,8 @@ ctxt_name = None if w_globals is not None and not space.is_w(w_globals, space.w_None): - ctxt_w_name = try_getitem(space, w_globals, w('__name__')) - ctxt_w_path = try_getitem(space, w_globals, w('__path__')) + ctxt_w_name = space.finditem(w_globals, w('__name__')) + ctxt_w_path = space.finditem(w_globals, w('__path__')) if ctxt_w_name is not None: try: ctxt_name = space.str_w(ctxt_w_name) @@ -224,11 +206,8 @@ def find_in_path_hooks(space, w_modulename, w_pathitem): w_path_importer_cache = space.sys.get("path_importer_cache") - try: - w_importer = space.getitem(w_path_importer_cache, w_pathitem) - except OperationError, e: - if not e.match(space, space.w_KeyError): - raise + w_importer = space.finditem(w_path_importer_cache, w_pathitem) + if w_importer is None: w_importer = space.w_None space.setitem(w_path_importer_cache, w_pathitem, w_importer) for w_hook in space.unpackiterable(space.sys.get("path_hooks")): From exarkun at codespeak.net Sun Jan 10 17:52:27 2010 From: exarkun at codespeak.net (exarkun at codespeak.net) Date: Sun, 10 Jan 2010 17:52:27 +0100 (CET) Subject: [pypy-svn] r70477 - in pypy/trunk: lib-python pypy/module/posix pypy/module/posix/test pypy/rpython/module Message-ID: <20100110165227.7A532168026@codespeak.net> Author: exarkun Date: Sun Jan 10 17:52:26 2010 New Revision: 70477 Modified: pypy/trunk/lib-python/conftest.py pypy/trunk/pypy/module/posix/__init__.py pypy/trunk/pypy/module/posix/interp_posix.py pypy/trunk/pypy/module/posix/test/test_posix2.py pypy/trunk/pypy/rpython/module/ll_os.py Log: implement os.openpty Modified: pypy/trunk/lib-python/conftest.py ============================================================================== --- pypy/trunk/lib-python/conftest.py (original) +++ pypy/trunk/lib-python/conftest.py Sun Jan 10 17:52:26 2010 @@ -311,7 +311,7 @@ RegrTest('test_normalization.py'), RegrTest('test_ntpath.py'), RegrTest('test_opcodes.py', core=True), - RegrTest('test_openpty.py', skip="unsupported extension module"), + RegrTest('test_openpty.py'), RegrTest('test_operations.py', core=True), RegrTest('test_operator.py', core=True), RegrTest('test_optparse.py'), Modified: pypy/trunk/pypy/module/posix/__init__.py ============================================================================== --- pypy/trunk/pypy/module/posix/__init__.py (original) +++ pypy/trunk/pypy/module/posix/__init__.py Sun Jan 10 17:52:26 2010 @@ -93,6 +93,8 @@ interpleveldefs['readlink'] = 'interp_posix.readlink' if hasattr(os, 'fork'): interpleveldefs['fork'] = 'interp_posix.fork' + if hasattr(os, 'openpty'): + interpleveldefs['openpty'] = 'interp_posix.openpty' if hasattr(os, 'waitpid'): interpleveldefs['waitpid'] = 'interp_posix.waitpid' if hasattr(os, 'execv'): Modified: pypy/trunk/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/trunk/pypy/module/posix/interp_posix.py (original) +++ pypy/trunk/pypy/module/posix/interp_posix.py Sun Jan 10 17:52:26 2010 @@ -507,6 +507,14 @@ raise wrap_oserror(space, e) return space.wrap(pid) +def openpty(space): + "Open a pseudo-terminal, returning open fd's for both master and slave end." + try: + master_fd, slave_fd = os.openpty() + except OSError, e: + raise wrap_oserror(space, e) + return space.newtuple([space.wrap(master_fd), space.wrap(slave_fd)]) + def waitpid(space, pid, options): """ waitpid(pid, options) -> (pid, status) Modified: pypy/trunk/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/trunk/pypy/module/posix/test/test_posix2.py (original) +++ pypy/trunk/pypy/module/posix/test/test_posix2.py Sun Jan 10 17:52:26 2010 @@ -245,6 +245,21 @@ assert os.WEXITSTATUS(status1) == 4 pass # <- please, inspect.getsource(), don't crash + + if hasattr(__import__(os.name), "openpty"): + def test_openpty(self): + os = self.posix + master_fd, slave_fd = self.posix.openpty() + try: + assert isinstance(master_fd, int) + assert isinstance(slave_fd, int) + os.write(slave_fd, 'x') + assert os.read(master_fd, 1) == 'x' + finally: + os.close(master_fd) + os.close(slave_fd) + + if hasattr(__import__(os.name), "execv"): def test_execv(self): os = self.posix Modified: pypy/trunk/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/trunk/pypy/rpython/module/ll_os.py (original) +++ pypy/trunk/pypy/rpython/module/ll_os.py Sun Jan 10 17:52:26 2010 @@ -1400,6 +1400,30 @@ return extdef([], int, llimpl=fork_llimpl, export_name="ll_os.ll_os_fork") + @registering_if(os, 'openpty') + def register_os_openpty(self): + os_openpty = self.llexternal( + 'openpty', + [rffi.INTP, rffi.INTP, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP], + rffi.INT, + compilation_info=ExternalCompilationInfo(libraries=['util'])) + def openpty_llimpl(): + master_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + slave_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + result = os_openpty(master_p, slave_p, None, None, None) + master_fd = master_p[0] + slave_fd = slave_p[0] + lltype.free(master_p, flavor='raw') + lltype.free(slave_p, flavor='raw') + if result == -1: + raise OSError(rposix.get_errno(), "os_openpty failed") + return (rffi.cast(lltype.Signed, master_fd), + rffi.cast(lltype.Signed, slave_fd)) + + return extdef([], (int, int), "ll_os.ll_os_openpty", + llimpl=openpty_llimpl) + + @registering(os._exit) def register_os__exit(self): os__exit = self.llexternal('_exit', [rffi.INT], lltype.Void) From benjamin at codespeak.net Sun Jan 10 18:09:42 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 10 Jan 2010 18:09:42 +0100 (CET) Subject: [pypy-svn] r70478 - pypy/trunk/pypy/module/imp/test Message-ID: <20100110170942.18B3816802C@codespeak.net> Author: benjamin Date: Sun Jan 10 18:09:42 2010 New Revision: 70478 Modified: pypy/trunk/pypy/module/imp/test/test_import.py Log: follow loader protocol correctly Modified: pypy/trunk/pypy/module/imp/test/test_import.py ============================================================================== --- pypy/trunk/pypy/module/imp/test/test_import.py (original) +++ pypy/trunk/pypy/module/imp/test/test_import.py Sun Jan 10 18:09:42 2010 @@ -832,10 +832,10 @@ class Importer(object): def find_module(self, fullname, path=None): if fullname == "a": - sys.modules["a"] = self return self def load_module(self, name): + sys.modules[name] = sys return sys def importer_for_path(path): From arigo at codespeak.net Sun Jan 10 18:22:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 10 Jan 2010 18:22:03 +0100 (CET) Subject: [pypy-svn] r70479 - pypy/branch/c-traceback/pypy/translator/c/src Message-ID: <20100110172203.09E0E16802A@codespeak.net> Author: arigo Date: Sun Jan 10 18:22:03 2010 New Revision: 70479 Removed: pypy/branch/c-traceback/pypy/translator/c/src/debuginfo.h Log: Kill this old file, not used any more. From arigo at codespeak.net Sun Jan 10 18:22:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 10 Jan 2010 18:22:57 +0100 (CET) Subject: [pypy-svn] r70480 - pypy/branch/c-traceback/pypy/translator/c/src Message-ID: <20100110172257.289E716802A@codespeak.net> Author: arigo Date: Sun Jan 10 18:22:56 2010 New Revision: 70480 Added: pypy/branch/c-traceback/pypy/translator/c/src/debug_print.h - copied unchanged from r70474, pypy/branch/c-traceback/pypy/translator/c/src/debug.h Removed: pypy/branch/c-traceback/pypy/translator/c/src/debug.h Modified: pypy/branch/c-traceback/pypy/translator/c/src/g_include.h Log: Rename debug.h into debug_print.h. Modified: pypy/branch/c-traceback/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/src/g_include.h (original) +++ pypy/branch/c-traceback/pypy/translator/c/src/g_include.h Sun Jan 10 18:22:56 2010 @@ -51,7 +51,7 @@ /*** modules ***/ #ifdef HAVE_RTYPER /* only if we have an RTyper */ # include "src/rtyper.h" -# include "src/debug.h" +# include "src/debug_print.h" #ifndef AVR # include "src/ll_os.h" # include "src/ll_strtod.h" From arigo at codespeak.net Mon Jan 11 10:10:20 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 11 Jan 2010 10:10:20 +0100 (CET) Subject: [pypy-svn] r70481 - pypy/trunk/pypy/doc/jit Message-ID: <20100111091020.7F4C8168023@codespeak.net> Author: arigo Date: Mon Jan 11 10:10:18 2010 New Revision: 70481 Modified: pypy/trunk/pypy/doc/jit/pyjitpl5.txt Log: Typo. Modified: pypy/trunk/pypy/doc/jit/pyjitpl5.txt ============================================================================== --- pypy/trunk/pypy/doc/jit/pyjitpl5.txt (original) +++ pypy/trunk/pypy/doc/jit/pyjitpl5.txt Mon Jan 11 10:10:18 2010 @@ -2,7 +2,7 @@ PyJitPl5 ========== -This document describes the fith generation of PyPy's JIT. +This document describes the fifth generation of PyPy's JIT. Implementation of the JIT From fijal at codespeak.net Mon Jan 11 10:43:16 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 10:43:16 +0100 (CET) Subject: [pypy-svn] r70482 - pypy/extradoc/planning Message-ID: <20100111094316.D87EB16802A@codespeak.net> Author: fijal Date: Mon Jan 11 10:43:16 2010 New Revision: 70482 Modified: pypy/extradoc/planning/jit.txt Log: This is done Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Mon Jan 11 10:43:16 2010 @@ -36,10 +36,6 @@ - look into failing pypy-c-jit apptests, pypy-c-jit translate.py - -- list copy as ll operations, to avoid calling write barriers again and - again while growing lists (lists of pointers are extra slow on pypy) - - improve ''.join and u''.join by using stringbuilder, enable realloc for hybrid GC (on stringbuilder branch so far). From pedronis at codespeak.net Mon Jan 11 11:53:39 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 11 Jan 2010 11:53:39 +0100 (CET) Subject: [pypy-svn] r70485 - pypy/trunk/pypy/translator/benchmark/test Message-ID: <20100111105339.953CF168023@codespeak.net> Author: pedronis Date: Mon Jan 11 11:53:39 2010 New Revision: 70485 Removed: pypy/trunk/pypy/translator/benchmark/test/ Log: (fijal, pedronis) just sad skipped stuff From fijal at codespeak.net Mon Jan 11 12:01:40 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 12:01:40 +0100 (CET) Subject: [pypy-svn] r70486 - pypy/trunk/pypy/translator/benchmark Message-ID: <20100111110140.20D5E168022@codespeak.net> Author: fijal Date: Mon Jan 11 12:01:39 2010 New Revision: 70486 Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py Log: (pedronis, fijal) Kill docutils, they're not used for a long while Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/trunk/pypy/translator/benchmark/benchmarks.py Mon Jan 11 12:01:39 2010 @@ -100,38 +100,6 @@ raise BenchmarkFailed(status) return r -def run_docutils(executable='/usr/local/bin/python'): - docutilssvnpath = 'docutils' # subdir of the local dir - translatetxt = py.path.local(__file__).dirpath().dirpath().dirpath().join('doc').join('translation.txt') - command = """import sys -sys.modules['unicodedata'] = sys # docutils need 'import unicodedata' to work, but no more... -sys.path[0:0] = ['%s', '%s/extras'] -from docutils.core import publish_cmdline -publish_cmdline(writer_name='html') -"""%(docutilssvnpath, docutilssvnpath) - T = time.time() - pid = os.fork() - if not pid: - davenull = os.open('/dev/null', os.O_RDWR) - os.dup2(davenull, 0) - os.dup2(davenull, 1) - os.dup2(davenull, 2) - status = os.spawnv(os.P_WAIT, executable, [executable, '-c', command, str(translatetxt)]) - os._exit(status) - else: - status = os.waitpid(pid, 0)[1] - r = time.time() - T - if status: - raise BenchmarkFailed(status) - return r - -def check_docutils(): - return False # useless benchmark - I've seen 15% of difference - # between two successive runs on the same machine! - #return external_dependency('docutils', - # 'svn://svn.berlios.de/docutils/trunk/docutils', - # 4821) - def run_templess(executable='/usr/local/bin/python', sizefactor=1): """ run some script in the templess package @@ -189,7 +157,7 @@ def check_mako(): return external_dependency('mako', 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/mako', - 70118) + 70118) def check_translate(): return False # XXX what should we do about the dependency on ctypes? @@ -197,8 +165,6 @@ BENCHMARKS = [Benchmark('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'), Benchmark('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''), Benchmark('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms', check_translate), - Benchmark('docutils', run_docutils, RICHARDS_ASCENDING_GOOD, - 's', check_docutils), Benchmark('templess', run_templess, RICHARDS_ASCENDING_GOOD, 's', check_templess), Benchmark('gadfly2', run_gadfly, RICHARDS_ASCENDING_GOOD, From fijal at codespeak.net Mon Jan 11 12:21:04 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 12:21:04 +0100 (CET) Subject: [pypy-svn] r70487 - in pypy/trunk/pypy/translator/benchmark: . test Message-ID: <20100111112104.C6577168022@codespeak.net> Author: fijal Date: Mon Jan 11 12:21:04 2010 New Revision: 70487 Added: pypy/trunk/pypy/translator/benchmark/test/ pypy/trunk/pypy/translator/benchmark/test/__init__.py (contents, props changed) pypy/trunk/pypy/translator/benchmark/test/test_run.py (contents, props changed) Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py Log: (pedronis, fijal) Add some real tests, even if small start refactoring benchmark.py to be a bit saner Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/trunk/pypy/translator/benchmark/benchmarks.py Mon Jan 11 12:21:04 2010 @@ -5,11 +5,9 @@ PYSTONE_CMD = 'from test import pystone;pystone.main(%s)' PYSTONE_PATTERN = 'This machine benchmarks at' -PYSTONE_ASCENDING_GOOD = True RICHARDS_CMD = 'from richards import *;main(iterations=%d)' RICHARDS_PATTERN = 'Average time per iteration:' -RICHARDS_ASCENDING_GOOD = False def get_result(txt, pattern): for line in txt.split('\n'): @@ -36,10 +34,8 @@ return Benchmark(self._basename, self._run, self.asc_good, self.units, self.check, self.sizefactor * n) def run(self, exe): - global latest_output - latest_output = '' try: - result = self._run(exe, self.sizefactor) + result, latest_output = self._run(exe, self.sizefactor) except BenchmarkFailed, e: result = '-FAILED-' self.latest_output = latest_output @@ -67,12 +63,10 @@ return True def run_cmd(cmd): - global latest_output #print "running", cmd pipe = os.popen(cmd + ' 2>&1') r = pipe.read() status = pipe.close() - latest_output = r if status: raise BenchmarkFailed(status) return r @@ -82,12 +76,12 @@ distdir = py.path.local(autopath.pypydir).dirpath() pystone = py.path.local(autopath.libpythondir).join('test', 'pystone.py') txt = run_cmd('"%s" "%s" %d' % (executable, pystone, 50000 * sizefactor)) - return get_result(txt, PYSTONE_PATTERN) + return get_result(txt, PYSTONE_PATTERN), txt def run_richards(executable='/usr/local/bin/python', sizefactor=1): richards = py.path.local(__file__).dirpath().dirpath().join('goal').join('richards.py') txt = run_cmd('"%s" %s %d' % (executable, richards, 5 * sizefactor)) - return get_result(txt, RICHARDS_PATTERN) + return get_result(txt, RICHARDS_PATTERN), txt def run_translate(executable='/usr/local/bin/python'): translate = py.path.local(__file__).dirpath().dirpath().join('goal').join('translate.py') @@ -117,7 +111,7 @@ for line in txt.split('\n'): if '.' in line: try: - return float(line) / sizefactor + return float(line) / sizefactor, txt except ValueError: pass else: @@ -136,7 +130,7 @@ command = 'PYTHONPATH="%s" "%s" "%s" %d' % (gadfly, executable, testscript, sizefactor) txt = run_cmd(command) - return get_result(txt, 'Total running time:') / sizefactor + return get_result(txt, 'Total running time:') / sizefactor, txt def check_gadfly(): return external_dependency('gadfly', @@ -152,7 +146,7 @@ executable, testscript, 2000 * sizefactor) txt = run_cmd(command) - return get_result(txt, 'Mako:') + return get_result(txt, 'Mako:'), txt def check_mako(): return external_dependency('mako', @@ -162,14 +156,15 @@ def check_translate(): return False # XXX what should we do about the dependency on ctypes? -BENCHMARKS = [Benchmark('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'), - Benchmark('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''), - Benchmark('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms', check_translate), - Benchmark('templess', run_templess, RICHARDS_ASCENDING_GOOD, +BENCHMARKS = [Benchmark('richards', run_richards, False, 'ms'), + Benchmark('pystone', run_pystone, True, ''), + Benchmark('translate', run_translate, False, 'ms', + check_translate), + Benchmark('templess', run_templess, False, 's', check_templess), - Benchmark('gadfly2', run_gadfly, RICHARDS_ASCENDING_GOOD, + Benchmark('gadfly2', run_gadfly, False, 's', check_gadfly), - Benchmark('mako', run_mako, RICHARDS_ASCENDING_GOOD, + Benchmark('mako', run_mako, False, 's', check_mako), ] Added: pypy/trunk/pypy/translator/benchmark/test/__init__.py ============================================================================== Added: pypy/trunk/pypy/translator/benchmark/test/test_run.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/translator/benchmark/test/test_run.py Mon Jan 11 12:21:04 2010 @@ -0,0 +1,17 @@ + +import sys +from pypy.translator.benchmark.benchmarks import (run_richards, Benchmark, + run_mako, check_mako) + +def test_run_richards(): + bm = Benchmark('richards', run_richards, False, 'ms') + assert bm.check() + res = bm.run(sys.executable) + assert isinstance(res, float) + +def test_run_mako(): + bm = Benchmark('mako', run_mako, False, + 's', check_mako) + assert bm.check() + res = bm.run(sys.executable) + assert isinstance(res, float) From fijal at codespeak.net Mon Jan 11 12:24:01 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 12:24:01 +0100 (CET) Subject: [pypy-svn] r70488 - pypy/trunk/pypy/translator/benchmark Message-ID: <20100111112401.B6991168022@codespeak.net> Author: fijal Date: Mon Jan 11 12:24:00 2010 New Revision: 70488 Modified: pypy/trunk/pypy/translator/benchmark/bench-custom.py Log: "update" python list Modified: pypy/trunk/pypy/translator/benchmark/bench-custom.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/bench-custom.py (original) +++ pypy/trunk/pypy/translator/benchmark/bench-custom.py Mon Jan 11 12:24:00 2010 @@ -34,7 +34,7 @@ benchmarks.append(b) exes = get_executables(args) - pythons = 'python2.5 python2.4 python2.3'.split() + pythons = 'python2.6 python2.5 python2.4'.split() full_pythons = [] for python in pythons: full_python = py.path.local.sysfind(python) From afa at codespeak.net Mon Jan 11 13:24:32 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 11 Jan 2010 13:24:32 +0100 (CET) Subject: [pypy-svn] r70492 - pypy/branch/separate-compilation Message-ID: <20100111122432.3230C16802A@codespeak.net> Author: afa Date: Mon Jan 11 13:24:31 2010 New Revision: 70492 Added: pypy/branch/separate-compilation/ - copied from r70491, pypy/trunk/ Log: A branch to integrate xorAxAx work on separate compilation of modules From fijal at codespeak.net Mon Jan 11 14:06:31 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 14:06:31 +0100 (CET) Subject: [pypy-svn] r70493 - in pypy/trunk/pypy/translator/benchmark: . test Message-ID: <20100111130631.C99D0168029@codespeak.net> Author: fijal Date: Mon Jan 11 14:06:31 2010 New Revision: 70493 Modified: pypy/trunk/pypy/translator/benchmark/ (props changed) pypy/trunk/pypy/translator/benchmark/benchmarks.py pypy/trunk/pypy/translator/benchmark/test/test_run.py Log: (pedronis, fijal) Add infrastructure for running computer language shootout benchmarks Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/trunk/pypy/translator/benchmark/benchmarks.py Mon Jan 11 14:06:31 2010 @@ -1,4 +1,5 @@ import os, sys, time, pickle, re, py +import yaml class BenchmarkFailed(Exception): pass @@ -9,6 +10,8 @@ RICHARDS_CMD = 'from richards import *;main(iterations=%d)' RICHARDS_PATTERN = 'Average time per iteration:' +TIME_FMT = 'max mem used: %Mk\nelapsed time: %e\nsystem time: %S\nuser time: %U\nCPU use: %P' + def get_result(txt, pattern): for line in txt.split('\n'): if line.startswith(pattern): @@ -36,34 +39,19 @@ def run(self, exe): try: result, latest_output = self._run(exe, self.sizefactor) + self.latest_output = latest_output except BenchmarkFailed, e: result = '-FAILED-' - self.latest_output = latest_output return result -def external_dependency(dirname, svnurl, revision): - """Check out (if necessary) a given fixed revision of a svn url.""" - dirpath = py.path.local(__file__).dirpath().join(dirname) - revtag = dirpath.join('-svn-rev-') - if dirpath.check(): - if not revtag.check() or int(revtag.read()) != revision: - print >> sys.stderr, ("Out-of-date benchmark checkout!" - " I won't update it automatically.") - print >> sys.stderr, ("To continue, move away or remove the " - "%r directory." % (dirname,)) - sys.exit(1) - return True - CMD = "svn co -r%d %s@%d %s" % (revision, svnurl, revision, dirpath) - print >> sys.stderr, CMD - err = os.system(CMD) - if err != 0: - print >> sys.stderr, "* checkout failed, skipping this benchmark" - return False - revtag.write(str(revision)) +def external_dependency(dirname, svnurl, revision=None): + directory = py.path.local(__file__).dirpath().join(dirname) + wc = py.path.svnwc(directory) + wc.checkout(svnurl, rev=revision) return True def run_cmd(cmd): - #print "running", cmd + print "running", cmd pipe = os.popen(cmd + ' 2>&1') r = pipe.read() status = pipe.close() @@ -71,19 +59,19 @@ raise BenchmarkFailed(status) return r -def run_pystone(executable='/usr/local/bin/python', sizefactor=1): +def run_pystone(executable, sizefactor=1): from pypy.tool import autopath distdir = py.path.local(autopath.pypydir).dirpath() pystone = py.path.local(autopath.libpythondir).join('test', 'pystone.py') txt = run_cmd('"%s" "%s" %d' % (executable, pystone, 50000 * sizefactor)) return get_result(txt, PYSTONE_PATTERN), txt -def run_richards(executable='/usr/local/bin/python', sizefactor=1): +def run_richards(executable, sizefactor=1): richards = py.path.local(__file__).dirpath().dirpath().join('goal').join('richards.py') txt = run_cmd('"%s" %s %d' % (executable, richards, 5 * sizefactor)) return get_result(txt, RICHARDS_PATTERN), txt -def run_translate(executable='/usr/local/bin/python'): +def run_translate(executable): translate = py.path.local(__file__).dirpath().dirpath().join('goal').join('translate.py') target = py.path.local(__file__).dirpath().dirpath().join('goal').join('targetrpystonedalone.py') argstr = '%s %s --batch --backendopt --no-compile %s > /dev/null 2> /dev/null' @@ -94,7 +82,7 @@ raise BenchmarkFailed(status) return r -def run_templess(executable='/usr/local/bin/python', sizefactor=1): +def run_templess(executable, sizefactor=1): """ run some script in the templess package templess is some simple templating language, to check out use @@ -122,7 +110,7 @@ 'http://johnnydebris.net/templess/trunk', 100) -def run_gadfly(executable='/usr/local/bin/python', sizefactor=1): +def run_gadfly(executable, sizefactor=1): """ run some tests in the gadfly pure Python database """ here = py.path.local(__file__).dirpath() gadfly = here.join('gadfly') @@ -137,7 +125,7 @@ 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/gadflyZip', 70117) -def run_mako(executable='/usr/local/bin/python', sizefactor=1): +def run_mako(executable, sizefactor=1): """ run some tests in the mako templating system """ here = py.path.local(__file__).dirpath() mako = here.join('mako') @@ -156,6 +144,34 @@ def check_translate(): return False # XXX what should we do about the dependency on ctypes? +class LanguageShootoutBenchmark(Benchmark): + def __init__(self, name, sizefactor=1, test=False): + self.test = test + Benchmark.__init__(self, name, self.runner, False, 'ms', + self.check, sizefactor) + + def __mul__(self, i): + return LookingGlassBenchmark(self.name, self.sizefactor * i) + + def runner(self, executable, sizefactor=1): + shootout = py.path.local(__file__).dirpath().join( + 'shootout_benchmarks') + argsfile = shootout.join('tests.yml') + if self.test: + kind = 'test' + else: + kind = 'run' + args = yaml.load(argsfile.read())[self.name][kind]['args'] + progname = str(shootout.join(self.name)) + '.py' + cmd = 'time -f "%s" %s %s %s' % (TIME_FMT, executable, progname, + " ".join(args)) + txt = run_cmd(cmd) + return get_result(txt, 'elapsed time:'), txt + + def check(self): + return external_dependency('shootout_benchmarks', + 'http://codespeak.net/svn/pypy/benchmarks/shootout') + BENCHMARKS = [Benchmark('richards', run_richards, False, 'ms'), Benchmark('pystone', run_pystone, True, ''), Benchmark('translate', run_translate, False, 'ms', Modified: pypy/trunk/pypy/translator/benchmark/test/test_run.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/test/test_run.py (original) +++ pypy/trunk/pypy/translator/benchmark/test/test_run.py Mon Jan 11 14:06:31 2010 @@ -1,7 +1,7 @@ import sys from pypy.translator.benchmark.benchmarks import (run_richards, Benchmark, - run_mako, check_mako) + run_mako, check_mako, LanguageShootoutBenchmark) def test_run_richards(): bm = Benchmark('richards', run_richards, False, 'ms') @@ -15,3 +15,9 @@ assert bm.check() res = bm.run(sys.executable) assert isinstance(res, float) + +def test_run_binary_trees(): + bm = LanguageShootoutBenchmark('binary-trees', test=True) + assert bm.check() + res = bm.run(sys.executable) + assert isinstance(res, float) From fijal at codespeak.net Mon Jan 11 14:08:02 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 14:08:02 +0100 (CET) Subject: [pypy-svn] r70494 - pypy/trunk/pypy/translator/benchmark Message-ID: <20100111130802.86076168029@codespeak.net> Author: fijal Date: Mon Jan 11 14:08:02 2010 New Revision: 70494 Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py Log: (fijal, pedronis) Run more benchmarks Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/trunk/pypy/translator/benchmark/benchmarks.py Mon Jan 11 14:08:02 2010 @@ -184,6 +184,10 @@ 's', check_mako), ] +for name in ['binary-trees', 'fannkuch', 'fasta', 'float', 'meteor-contest', + 'nbody', 'spectral-norm']: + BENCHMARKS.append(LanguageShootoutBenchmark(name)) + BENCHMARKS_BY_NAME = {} for _b in BENCHMARKS: BENCHMARKS_BY_NAME[_b.name] = _b From afa at codespeak.net Mon Jan 11 14:09:32 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 11 Jan 2010 14:09:32 +0100 (CET) Subject: [pypy-svn] r70495 - in pypy/branch/separate-compilation/pypy/translator/c: . test Message-ID: <20100111130932.E04EB168029@codespeak.net> Author: afa Date: Mon Jan 11 14:09:32 2010 New Revision: 70495 Added: pypy/branch/separate-compilation/pypy/translator/c/separate.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py Log: Introduce CSharedModuleBuilder: it builds a .so or .dll which exports RPython functions. Other modules can link with it and call the functions without the help of dlopen or ctypes. Only works with primitive types so far. Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/genc.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/genc.py Mon Jan 11 14:09:32 2010 @@ -7,7 +7,7 @@ from pypy.translator.llsupport.wrapper import new_wrapper from pypy.translator.gensupp import uniquemodulename, NameManager from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, rffi from pypy.tool.udir import udir from pypy.tool import isolate from pypy.translator.c.support import log, c_string_constant @@ -300,27 +300,24 @@ except KeyError: pass - -class CExtModuleBuilder(CBuilder): +class CSharedModuleBuilder(CBuilder): + "Builds a simple .so or .dll file" standalone = False - _module = None - _wrapper = None - def getentrypointptr(self): # xxx - if self._wrapper is None: - self._wrapper = new_wrapper(self.entrypoint, self.translator) - return self._wrapper + def getentrypointptr(self): + return self.entrypoint.values() + + def getexportsymbols(self): + self.export_node_names = dict( + (funcname, self.db.get(funcptr)) + for funcname, funcptr in self.entrypoint.items()) + return self.export_node_names.values() def compile(self): - assert self.c_source_filename + assert self.c_source_filename assert not self._compiled - export_symbols = [self.db.get(self.getentrypointptr()), - 'RPython_StartupCode', - ] - if self.config.translation.countmallocs: - export_symbols.append('malloc_counters') - extsymeci = ExternalCompilationInfo(export_symbols=export_symbols) - self.eci = self.eci.merge(extsymeci) + self.eci = self.eci.merge(ExternalCompilationInfo( + export_symbols=self.getexportsymbols())) if sys.platform == 'win32': self.eci = self.eci.merge(ExternalCompilationInfo( @@ -329,11 +326,62 @@ ], )) - files = [self.c_source_filename] + self.extrafiles - self.translator.platform.compile(files, self.eci, standalone=False) + + self.so_name = str(self.targetdir.join(self.modulename)) + self.translator.platform.compile( + files, self.eci, standalone=False, + outputfilename=str(self.so_name) + ) self._compiled = True + def make_import_module(self): + class Module: + pass + mod = Module() + mod.__file__ = self.so_name + + forwards = [] + node_names = self.export_node_names.values() + for node in self.db.globalcontainers(): + if node.nodekind == 'func' and node.name in node_names: + forwards.append('\n'.join(node.forward_declaration())) + + import_eci = ExternalCompilationInfo( + libraries = [self.so_name], + post_include_bits = forwards + ) + + for funcname, import_name in self.export_node_names.items(): + functype = lltype.typeOf(self.entrypoint[funcname]) + setattr(mod, funcname, + rffi.llexternal( + import_name, functype.TO.ARGS, functype.TO.RESULT, + compilation_info=import_eci, + )) + return mod + + def gen_makefile(self, targetdir): + pass + +class CExtModuleBuilder(CSharedModuleBuilder): + "Build a CPython extension module" + _module = None + _wrapper = None + + def getentrypointptr(self): # xxx + if self._wrapper is None: + self._wrapper = new_wrapper(self.entrypoint, self.translator) + return self._wrapper + + def getexportsymbols(self): + export_symbols = [self.db.get(self.getentrypointptr()), + 'RPython_StartupCode', + ] + if self.config.translation.countmallocs: + export_symbols.append('malloc_counters') + return export_symbols + def _make_wrapper_module(self): fname = 'wrap_' + self.c_source_filename.purebasename modfile = self.c_source_filename.new(purebasename=fname, ext=".py") @@ -399,9 +447,6 @@ if isinstance(self._module, isolate.Isolate): isolate.close_isolate(self._module) - def gen_makefile(self, targetdir): - pass - class CStandaloneBuilder(CBuilder): standalone = True executable_name = None Added: pypy/branch/separate-compilation/pypy/translator/c/separate.py ============================================================================== --- (empty file) +++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Mon Jan 11 14:09:32 2010 @@ -0,0 +1,29 @@ +import types + +class export(object): + """decorator to mark a function as exported by a shared module. + Can be used with a signature:: + @export([float, float]) + def f(x, y): + return x + y + or without any argument at all:: + @export + def f(x, y): + return x + y + in which case the function must be used somewhere else, which will + trigger its annotation.""" + argtypes = None + + def __new__(cls, *args, **kwds): + if len(args) == 1 and isinstance(args[0], types.FunctionType): + func = args[0] + return export()(func) + return object.__new__(cls, *args, **kwds) + + def __init__(self, args=None): + self.argtypes = args + + def __call__(self, func): + if self.argtypes is not None: + func.argtypes = self.argtypes + return func Added: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- (empty file) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Mon Jan 11 14:09:32 2010 @@ -0,0 +1,101 @@ +from pypy.translator.c.separate import export +from pypy.translator.translator import TranslationContext +from pypy.translator.c.genc import CExtModuleBuilder, CSharedModuleBuilder, gen_forwarddecl +from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.rpython.typesystem import getfunctionptr +from pypy.rpython.lltypesystem import rffi, lltype +import py +import sys, os + +class TestSeparation: + def compile_function(self, func, argtypes): + t = TranslationContext() + t.buildannotator().build_types(func, argtypes) + t.buildrtyper().specialize() + builder = CExtModuleBuilder(t, func, config=t.config) + builder.generate_source() + builder.compile() + return builder.get_entry_point() + + def compile_separated(self, name, **exports): + t = TranslationContext() + t.buildannotator() + for funcname, func in exports.items(): + if hasattr(func, 'argtypes'): + t.annotator.build_types(func, func.argtypes) + t.buildrtyper().specialize() + + exported_funcptr = {} + for funcname, func in exports.items(): + bk = t.annotator.bookkeeper + graph = bk.getdesc(func).getuniquegraph() + funcptr = getfunctionptr(graph) + + exported_funcptr[funcname] = funcptr + + builder = CSharedModuleBuilder(t, exported_funcptr, config=t.config) + builder.generate_source() + builder.compile() + + mod = builder.make_import_module() + return mod + + def test_simple_call(self): + # function exported from the 'first' module + @export(args=[float]) + def f(x): + return x + 1.5 + firstmodule = self.compile_separated("first", f=f) + + # call it from a function compiled in another module + def fn(): + return firstmodule.f(41.0) + + assert fn() == 42.5 + c_fn = self.compile_function(fn, []) + assert c_fn() == 42.5 + + def test_nested_call(self): + # function exported from the 'first' module + @export(args=[float]) + def f(x): + return x + 1.5 + firstmodule = self.compile_separated("first", f=f) + + # function exported from the 'second' module + @export(args=[float]) + def g(x): + return firstmodule.f(x) / 2 + secondmodule = self.compile_separated("second", g=g) + + # call it from a function compiled in another module + def fn(): + return secondmodule.g(41) + + if sys.platform == 'win32': + filepath = os.path.dirname(firstmodule.__file__) + os.environ['PATH'] = "%s;%s" % (filepath, os.environ['PATH']) + + assert fn() == 21.25 + c_fn = self.compile_function(fn, []) + assert c_fn() == 21.25 + + def test_implied_signature(self): + # function exported from the 'first' module + @export + def f(x): + return x + 1.5 + @export(args=[]) + def f2(): + f(1.0) + f(2.0) + firstmodule = self.compile_separated("first", f=f, f2=f2) + + # call it from a function compiled in another module + def fn(): + return firstmodule.f(41) + + assert fn() == 42.5 + c_fn = self.compile_function(fn, []) + assert c_fn() == 42.5 + From fijal at codespeak.net Mon Jan 11 14:45:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 14:45:20 +0100 (CET) Subject: [pypy-svn] r70497 - in pypy/trunk/pypy/translator/benchmark: . test Message-ID: <20100111134520.1FB57168030@codespeak.net> Author: fijal Date: Mon Jan 11 14:45:19 2010 New Revision: 70497 Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py pypy/trunk/pypy/translator/benchmark/test/test_run.py Log: (pedronis, fijal) Accept a sizefactor for each of shootout benchmarks Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/trunk/pypy/translator/benchmark/benchmarks.py Mon Jan 11 14:45:19 2010 @@ -147,11 +147,12 @@ class LanguageShootoutBenchmark(Benchmark): def __init__(self, name, sizefactor=1, test=False): self.test = test + self.basename = name Benchmark.__init__(self, name, self.runner, False, 'ms', self.check, sizefactor) def __mul__(self, i): - return LookingGlassBenchmark(self.name, self.sizefactor * i) + return LanguageShootoutBenchmark(self.name, self.sizefactor * i) def runner(self, executable, sizefactor=1): shootout = py.path.local(__file__).dirpath().join( @@ -161,10 +162,10 @@ kind = 'test' else: kind = 'run' - args = yaml.load(argsfile.read())[self.name][kind]['args'] - progname = str(shootout.join(self.name)) + '.py' - cmd = 'time -f "%s" %s %s %s' % (TIME_FMT, executable, progname, - " ".join(args)) + args = yaml.load(argsfile.read())[self.basename][kind]['args'] + progname = str(shootout.join(self.basename)) + '.py' + cmd = 'time -f "%s" %s %s %s %d' % (TIME_FMT, executable, progname, + " ".join(args), sizefactor) txt = run_cmd(cmd) return get_result(txt, 'elapsed time:'), txt @@ -184,8 +185,10 @@ 's', check_mako), ] -for name in ['binary-trees', 'fannkuch', 'fasta', 'float', 'meteor-contest', - 'nbody', 'spectral-norm']: +SHOOTOUT_NAMES = ['binary-trees', 'fannkuch', 'fasta', 'float', + 'meteor-contest', 'nbody', 'spectral-norm'] + +for name in SHOOTOUT_NAMES: BENCHMARKS.append(LanguageShootoutBenchmark(name)) BENCHMARKS_BY_NAME = {} Modified: pypy/trunk/pypy/translator/benchmark/test/test_run.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/test/test_run.py (original) +++ pypy/trunk/pypy/translator/benchmark/test/test_run.py Mon Jan 11 14:45:19 2010 @@ -1,7 +1,7 @@ import sys from pypy.translator.benchmark.benchmarks import (run_richards, Benchmark, - run_mako, check_mako, LanguageShootoutBenchmark) + run_mako, check_mako, LanguageShootoutBenchmark, SHOOTOUT_NAMES) def test_run_richards(): bm = Benchmark('richards', run_richards, False, 'ms') @@ -17,7 +17,8 @@ assert isinstance(res, float) def test_run_binary_trees(): - bm = LanguageShootoutBenchmark('binary-trees', test=True) - assert bm.check() - res = bm.run(sys.executable) - assert isinstance(res, float) + for name in SHOOTOUT_NAMES: + bm = LanguageShootoutBenchmark(name, test=True) + assert bm.check() + res = bm.run(sys.executable) + assert isinstance(res, float) From fijal at codespeak.net Mon Jan 11 14:46:44 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 14:46:44 +0100 (CET) Subject: [pypy-svn] r70498 - pypy/trunk/pypy/translator/benchmark Message-ID: <20100111134644.02619168030@codespeak.net> Author: fijal Date: Mon Jan 11 14:46:44 2010 New Revision: 70498 Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py Log: improve test Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/trunk/pypy/translator/benchmark/benchmarks.py Mon Jan 11 14:46:44 2010 @@ -152,7 +152,8 @@ self.check, sizefactor) def __mul__(self, i): - return LanguageShootoutBenchmark(self.name, self.sizefactor * i) + return LanguageShootoutBenchmark(self.name, self.sizefactor * i, + self.test) def runner(self, executable, sizefactor=1): shootout = py.path.local(__file__).dirpath().join( From cfbolz at codespeak.net Mon Jan 11 14:59:11 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 11 Jan 2010 14:59:11 +0100 (CET) Subject: [pypy-svn] r70499 - pypy/branch/loop-invariant-decorator/pypy/rlib Message-ID: <20100111135911.6789B168030@codespeak.net> Author: cfbolz Date: Mon Jan 11 14:59:10 2010 New Revision: 70499 Modified: pypy/branch/loop-invariant-decorator/pypy/rlib/jit.py Log: add the loop_invariant decorator Modified: pypy/branch/loop-invariant-decorator/pypy/rlib/jit.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/rlib/jit.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/rlib/jit.py Mon Jan 11 14:59:10 2010 @@ -20,6 +20,12 @@ func._jit_unroll_safe_ = True return func +def loop_invariant(func): + dont_look_inside(func) + func._jit_loop_invariant_ = True + return func + + def purefunction_promote(func): import inspect purefunction(func) From cfbolz at codespeak.net Mon Jan 11 15:00:12 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 11 Jan 2010 15:00:12 +0100 (CET) Subject: [pypy-svn] r70500 - pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test Message-ID: <20100111140012.417B3168030@codespeak.net> Author: cfbolz Date: Mon Jan 11 15:00:11 2010 New Revision: 70500 Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_basic.py Log: the test that I would like to pass Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_basic.py Mon Jan 11 15:00:11 2010 @@ -1,7 +1,7 @@ import py import sys from pypy.rlib.jit import JitDriver, we_are_jitted, hint, dont_look_inside -from pypy.rlib.jit import OPTIMIZER_FULL, OPTIMIZER_SIMPLE +from pypy.rlib.jit import OPTIMIZER_FULL, OPTIMIZER_SIMPLE, loop_invariant from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats from pypy.jit.backend.llgraph import runner from pypy.jit.metainterp import support, codewriter, pyjitpl, history @@ -1221,6 +1221,34 @@ res = self.meta_interp(f, [21]) assert res == 42 self.check_loops(guard_nonnull=1, guard_isnull=1) + + def test_loop_invariant(self): + myjitdriver = JitDriver(greens = [], reds = ['x', 'res']) + class A(object): + pass + a = A() + a.current_a = A() + a.current_a.x = 1 + @loop_invariant + def f(): + return a.current_a + + def g(x): + res = 0 + while x > 0: + myjitdriver.can_enter_jit(x=x, res=res) + myjitdriver.jit_merge_point(x=x, res=res) + res += f().x + res += f().x + res += f().x + x -= 1 + a.current_a = A() + a.current_a.x = 2 + return res + res = self.meta_interp(g, [21]) + assert res == 3 * 21 + self.check_loops(call=1) + class TestOOtype(BasicTests, OOJitMixin): From cfbolz at codespeak.net Mon Jan 11 15:13:22 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 11 Jan 2010 15:13:22 +0100 (CET) Subject: [pypy-svn] r70501 - in pypy/branch/loop-invariant-decorator/pypy/jit: backend metainterp Message-ID: <20100111141322.81B8E168030@codespeak.net> Author: cfbolz Date: Mon Jan 11 15:13:21 2010 New Revision: 70501 Modified: pypy/branch/loop-invariant-decorator/pypy/jit/backend/model.py pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/resoperation.py Log: Add a new operation CALL_LOOPINVARIANT. The operation behaves exactly like CALL. The idea is that the backend never has to generate code for this operation, because the optimizer turns it into a normal CALL. Modified: pypy/branch/loop-invariant-decorator/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/jit/backend/model.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/jit/backend/model.py Mon Jan 11 15:13:21 2010 @@ -209,6 +209,9 @@ def do_call(self, args, calldescr): raise NotImplementedError + def do_call_loopinvariant(self, args, calldescr): + return self.do_call(args, calldescr) + def do_cond_call_gc_wb(self, args, calldescr): if args[0].getint() & args[1].getint(): self.do_call(args[2:], calldescr) Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/resoperation.py Mon Jan 11 15:13:21 2010 @@ -226,6 +226,7 @@ '_CANRAISE_FIRST', # ----- start of can_raise operations ----- 'CALL', 'CALL_MAY_FORCE', + 'CALL_LOOPINVARIANT', 'OOSEND', # ootype operation '_CANRAISE_LAST', # ----- end of can_raise operations ----- From cfbolz at codespeak.net Mon Jan 11 15:15:16 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 11 Jan 2010 15:15:16 +0100 (CET) Subject: [pypy-svn] r70502 - pypy/branch/loop-invariant-decorator/pypy/jit/metainterp Message-ID: <20100111141516.05374168030@codespeak.net> Author: cfbolz Date: Mon Jan 11 15:15:16 2010 New Revision: 70502 Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/codewriter.py pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/pyjitpl.py Log: Make the codewriter produce a new opcode, "residual_call_loopinvariant" and implement it in the metainterp. Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/codewriter.py Mon Jan 11 15:15:16 2010 @@ -1224,9 +1224,11 @@ calldescr, non_void_args = self.codewriter.getcalldescr( op.args[0], args, op.result, consider_effects_of=op) pure = False + loopinvariant = False if op.opname == "direct_call": func = getattr(get_funcobj(op.args[0].value), '_callable', None) pure = getattr(func, "_pure_function_", False) + loopinvariant = getattr(func, "_jit_loop_invariant_", False) all_promoted_args = getattr(func, "_pure_function_with_all_promoted_args_", False) if pure and not all_promoted_args: @@ -1238,7 +1240,10 @@ except lltype.DelayedPointer: canraise = True # if we need to look into the delayed ptr that is # the portal, then it's certainly going to raise - if pure: + if loopinvariant: + self.emit("residual_call_loopinvariant") + assert not non_void_args, "arguments not supported for loop-invariant function!" + elif pure: # XXX check what to do about exceptions (also MemoryError?) self.emit('residual_call_pure') elif canraise: Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/pyjitpl.py Mon Jan 11 15:15:16 2010 @@ -654,6 +654,10 @@ def opimpl_residual_call(self, calldescr, varargs): return self.do_residual_call(varargs, descr=calldescr, exc=True) + @arguments("descr", "varargs") + def opimpl_residual_call_loopinvariant(self, calldescr, varargs): + return self.execute_varargs(rop.CALL_LOOPINVARIANT, varargs, calldescr, exc=True) + @arguments("varargs") def opimpl_recursion_leave_prep(self, varargs): warmrunnerstate = self.metainterp.staticdata.state From cfbolz at codespeak.net Mon Jan 11 15:18:54 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 11 Jan 2010 15:18:54 +0100 (CET) Subject: [pypy-svn] r70503 - in pypy/branch/loop-invariant-decorator/pypy/jit/metainterp: . test Message-ID: <20100111141854.D65F2168030@codespeak.net> Author: cfbolz Date: Mon Jan 11 15:18:53 2010 New Revision: 70503 Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/optimizeopt.py pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_optimizeopt.py Log: An optimization that replaces several loop-invariant calls to the same function by one call. Also add a direct test for that optimization. This implements the original test. Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/optimizeopt.py Mon Jan 11 15:18:53 2010 @@ -388,6 +388,7 @@ self.resumedata_memo = resume.ResumeDataLoopMemo(metainterp_sd) self.heap_op_optimizer = HeapOpOptimizer(self) self.bool_boxes = {} + self.loop_invariant_results = {} def forget_numberings(self, virtualbox): self.metainterp_sd.profiler.count(jitprof.OPT_FORCINGS) @@ -874,6 +875,23 @@ def optimize_DEBUG_MERGE_POINT(self, op): self.emit_operation(op) + def optimize_CALL_LOOPINVARIANT(self, op): + funcvalue = self.getvalue(op.args[0]) + if not funcvalue.is_constant(): + self.optimize_default(op) + return + resvalue = self.loop_invariant_results.get(op.args[0], None) + if resvalue is not None: + self.make_equal_to(op.result, resvalue) + return + # change the op to be a normal call, from the backend's point of view + # there is no reason to have a separate operation for this + op.opnum = rop.CALL + self.optimize_default(op) + resvalue = self.getvalue(op.result) + self.loop_invariant_results[op.args[0]] = resvalue + + optimize_ops = _findall(Optimizer, 'optimize_') Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_optimizeopt.py Mon Jan 11 15:18:53 2010 @@ -648,6 +648,32 @@ # ---------- + def test_call_loopinvariant(self): + ops = """ + [i1] + i2 = call_loopinvariant(i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + i3 = call_loopinvariant(i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + i4 = call_loopinvariant(i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + jump(i1) + """ + expected = """ + [i1] + i2 = call(i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + jump(i1) + """ + self.optimize_loop(ops, 'Not', expected) + + + # ---------- + def test_virtual_1(self): ops = """ [i, p0] From cfbolz at codespeak.net Mon Jan 11 15:20:44 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 11 Jan 2010 15:20:44 +0100 (CET) Subject: [pypy-svn] r70504 - pypy/branch/loop-invariant-decorator/pypy/interpreter Message-ID: <20100111142044.D6B79168030@codespeak.net> Author: cfbolz Date: Mon Jan 11 15:20:44 2010 New Revision: 70504 Modified: pypy/branch/loop-invariant-decorator/pypy/interpreter/baseobjspace.py Log: Declare getexecutioncontext to be loop-invariant. Modified: pypy/branch/loop-invariant-decorator/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/interpreter/baseobjspace.py Mon Jan 11 15:20:44 2010 @@ -531,6 +531,7 @@ def leave_cache_building_mode(self, val): "hook for the flow object space" + @jit.loop_invariant def getexecutioncontext(self): "Return what we consider to be the active execution context." # Important: the annotator must not see a prebuilt ExecutionContext: From cfbolz at codespeak.net Mon Jan 11 15:27:40 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 11 Jan 2010 15:27:40 +0100 (CET) Subject: [pypy-svn] r70505 - pypy/branch/loop-invariant-decorator/pypy/interpreter Message-ID: <20100111142740.69765168030@codespeak.net> Author: cfbolz Date: Mon Jan 11 15:27:39 2010 New Revision: 70505 Modified: pypy/branch/loop-invariant-decorator/pypy/interpreter/baseobjspace.py Log: missing import, of course Modified: pypy/branch/loop-invariant-decorator/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/interpreter/baseobjspace.py Mon Jan 11 15:27:39 2010 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer -from pypy.rlib.jit import we_are_jitted, unroll_safe +from pypy.rlib import jit import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -736,7 +736,7 @@ """ return self.unpackiterable(w_iterable, expected_length) - @unroll_safe + @jit.unroll_safe def exception_match(self, w_exc_type, w_check_class): """Checks if the given exception type matches 'w_check_class'.""" if self.is_w(w_exc_type, w_check_class): @@ -792,7 +792,7 @@ def call_valuestack(self, w_func, nargs, frame): from pypy.interpreter.function import Function, Method, is_builtin_code - if (not we_are_jitted() and frame.is_being_profiled and + if (not jit.we_are_jitted() and frame.is_being_profiled and is_builtin_code(w_func)): # XXX: this code is copied&pasted :-( from the slow path below # call_valuestack(). From afa at codespeak.net Mon Jan 11 15:53:29 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 11 Jan 2010 15:53:29 +0100 (CET) Subject: [pypy-svn] r70506 - in pypy/branch/separate-compilation/pypy/translator/c: . test Message-ID: <20100111145329.12066168030@codespeak.net> Author: afa Date: Mon Jan 11 15:53:26 2010 New Revision: 70506 Modified: pypy/branch/separate-compilation/pypy/translator/c/dlltool.py pypy/branch/separate-compilation/pypy/translator/c/genc.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Merge the new CSharedModuleBuilder into the already existing CLibraryBuilder. Modified: pypy/branch/separate-compilation/pypy/translator/c/dlltool.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/dlltool.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/dlltool.py Mon Jan 11 15:53:26 2010 @@ -1,40 +1,9 @@ from pypy.translator.driver import TranslationDriver -from pypy.translator.c.genc import CBuilder, CCompilerDriver +from pypy.translator.c.genc import CLibraryBuilder, CCompilerDriver from pypy.rpython.typesystem import getfunctionptr from pypy.translator.tool.cbuild import ExternalCompilationInfo -class CLibraryBuilder(CBuilder): - standalone = False - split = True - - def __init__(self, *args, **kwds): - self.functions = kwds.pop('functions') - self.name = kwds.pop('name') - CBuilder.__init__(self, *args, **kwds) - - def getentrypointptr(self): - bk = self.translator.annotator.bookkeeper - graphs = [bk.getdesc(f).cachedgraph(None) for f, _ in self.functions] - return [getfunctionptr(graph) for graph in graphs] - - def gen_makefile(self, targetdir): - pass # XXX finish - - def compile(self): - export_symbols = ([self.db.get(ep) for ep in self.getentrypointptr()] + - ['RPython_StartupCode']) - extsymeci = ExternalCompilationInfo(export_symbols=export_symbols) - self.eci = self.eci.merge(extsymeci) - files = [self.c_source_filename] + self.extrafiles - oname = self.name - self.so_name = self.translator.platform.compile(files, self.eci, - standalone=False, - outputfilename=oname) - - def get_entry_point(self, isolated=False): - return self.so_name - class DLLDef(object): def __init__(self, name, functions=[], policy=None, config=None): self.name = name @@ -44,8 +13,13 @@ def compile(self): self.driver.proceed(['compile_c']) - return self.driver.c_entryp + return self.driver.cbuilder.so_name def getcbuilder(self, translator, config): - return CLibraryBuilder(translator, None, config, - functions=self.functions, name=self.name) + bk = translator.annotator.bookkeeper + entrypoints = {} + for f, _ in self.functions: + graph = bk.getdesc(f).cachedgraph(None) + entrypoints[f.func_name] = getfunctionptr(graph) + + return CLibraryBuilder(translator, entrypoints, config) Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/genc.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/genc.py Mon Jan 11 15:53:26 2010 @@ -300,18 +300,22 @@ except KeyError: pass -class CSharedModuleBuilder(CBuilder): +class CLibraryBuilder(CBuilder): "Builds a simple .so or .dll file" standalone = False + split = True def getentrypointptr(self): return self.entrypoint.values() + def get_entry_point(self, isolated=False): + return None + def getexportsymbols(self): self.export_node_names = dict( (funcname, self.db.get(funcptr)) for funcname, funcptr in self.entrypoint.items()) - return self.export_node_names.values() + return self.export_node_names.values() + ['RPython_StartupCode'] def compile(self): assert self.c_source_filename @@ -364,7 +368,7 @@ def gen_makefile(self, targetdir): pass -class CExtModuleBuilder(CSharedModuleBuilder): +class CExtModuleBuilder(CLibraryBuilder): "Build a CPython extension module" _module = None _wrapper = None Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Mon Jan 11 15:53:26 2010 @@ -1,6 +1,6 @@ from pypy.translator.c.separate import export from pypy.translator.translator import TranslationContext -from pypy.translator.c.genc import CExtModuleBuilder, CSharedModuleBuilder, gen_forwarddecl +from pypy.translator.c.genc import CExtModuleBuilder, CLibraryBuilder, gen_forwarddecl from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import rffi, lltype @@ -33,7 +33,7 @@ exported_funcptr[funcname] = funcptr - builder = CSharedModuleBuilder(t, exported_funcptr, config=t.config) + builder = CLibraryBuilder(t, exported_funcptr, config=t.config) builder.generate_source() builder.compile() From afa at codespeak.net Mon Jan 11 16:04:28 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 11 Jan 2010 16:04:28 +0100 (CET) Subject: [pypy-svn] r70507 - in pypy/branch/separate-compilation/pypy/translator/c: . test Message-ID: <20100111150428.24EBC168030@codespeak.net> Author: afa Date: Mon Jan 11 16:04:27 2010 New Revision: 70507 Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: make our @export decorator closer to the one used by carbonpython Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Mon Jan 11 16:04:27 2010 @@ -3,7 +3,7 @@ class export(object): """decorator to mark a function as exported by a shared module. Can be used with a signature:: - @export([float, float]) + @export(float, float) def f(x, y): return x + y or without any argument at all:: @@ -17,10 +17,12 @@ def __new__(cls, *args, **kwds): if len(args) == 1 and isinstance(args[0], types.FunctionType): func = args[0] - return export()(func) + decorated = export()(func) + del decorated.argtypes + return decorated return object.__new__(cls, *args, **kwds) - def __init__(self, args=None): + def __init__(self, *args): self.argtypes = args def __call__(self, func): Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Mon Jan 11 16:04:27 2010 @@ -42,7 +42,7 @@ def test_simple_call(self): # function exported from the 'first' module - @export(args=[float]) + @export(float) def f(x): return x + 1.5 firstmodule = self.compile_separated("first", f=f) @@ -57,13 +57,13 @@ def test_nested_call(self): # function exported from the 'first' module - @export(args=[float]) + @export(float) def f(x): return x + 1.5 firstmodule = self.compile_separated("first", f=f) # function exported from the 'second' module - @export(args=[float]) + @export(float) def g(x): return firstmodule.f(x) / 2 secondmodule = self.compile_separated("second", g=g) @@ -85,7 +85,7 @@ @export def f(x): return x + 1.5 - @export(args=[]) + @export() def f2(): f(1.0) f(2.0) From cfbolz at codespeak.net Mon Jan 11 16:10:51 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 11 Jan 2010 16:10:51 +0100 (CET) Subject: [pypy-svn] r70508 - in pypy/branch/loop-invariant-decorator/pypy/jit/metainterp: . test Message-ID: <20100111151051.8E697168030@codespeak.net> Author: cfbolz Date: Mon Jan 11 16:10:50 2010 New Revision: 70508 Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/optimizeopt.py pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_optimizeopt.py Log: Called functions are ConstAddrs, use the address itself as keys. Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/optimizeopt.py Mon Jan 11 16:10:50 2010 @@ -880,7 +880,7 @@ if not funcvalue.is_constant(): self.optimize_default(op) return - resvalue = self.loop_invariant_results.get(op.args[0], None) + resvalue = self.loop_invariant_results.get(op.args[0].getint(), None) if resvalue is not None: self.make_equal_to(op.result, resvalue) return @@ -889,7 +889,7 @@ op.opnum = rop.CALL self.optimize_default(op) resvalue = self.getvalue(op.result) - self.loop_invariant_results[op.args[0]] = resvalue + self.loop_invariant_results[op.args[0].getint()] = resvalue optimize_ops = _findall(Optimizer, 'optimize_') Modified: pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_optimizeopt.py Mon Jan 11 16:10:50 2010 @@ -651,20 +651,20 @@ def test_call_loopinvariant(self): ops = """ [i1] - i2 = call_loopinvariant(i1, descr=nonwritedescr) + i2 = call_loopinvariant(1, i1, descr=nonwritedescr) guard_no_exception() [] guard_value(i2, 1) [] - i3 = call_loopinvariant(i1, descr=nonwritedescr) + i3 = call_loopinvariant(1, i1, descr=nonwritedescr) guard_no_exception() [] guard_value(i2, 1) [] - i4 = call_loopinvariant(i1, descr=nonwritedescr) + i4 = call_loopinvariant(1, i1, descr=nonwritedescr) guard_no_exception() [] guard_value(i2, 1) [] jump(i1) """ expected = """ [i1] - i2 = call(i1, descr=nonwritedescr) + i2 = call(1, i1, descr=nonwritedescr) guard_no_exception() [] guard_value(i2, 1) [] jump(i1) From afa at codespeak.net Mon Jan 11 17:31:58 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 11 Jan 2010 17:31:58 +0100 (CET) Subject: [pypy-svn] r70510 - in pypy/branch/separate-compilation/pypy/translator: . c c/test test Message-ID: <20100111163158.1E66F16802A@codespeak.net> Author: afa Date: Mon Jan 11 17:31:57 2010 New Revision: 70510 Added: pypy/branch/separate-compilation/pypy/translator/separate.py (contents, props changed) - copied, changed from r70507, pypy/branch/separate-compilation/pypy/translator/c/separate.py pypy/branch/separate-compilation/pypy/translator/test/test_separate.py (contents, props changed) Removed: pypy/branch/separate-compilation/pypy/translator/c/separate.py Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Move @export to pypy/translate/, and make it compatible with the one used by cli/carbonpython.py Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Mon Jan 11 17:31:57 2010 @@ -1,4 +1,4 @@ -from pypy.translator.c.separate import export +from pypy.translator.separate import export from pypy.translator.translator import TranslationContext from pypy.translator.c.genc import CExtModuleBuilder, CLibraryBuilder, gen_forwarddecl from pypy.translator.tool.cbuild import ExternalCompilationInfo Copied: pypy/branch/separate-compilation/pypy/translator/separate.py (from r70507, pypy/branch/separate-compilation/pypy/translator/c/separate.py) ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/separate.py Mon Jan 11 17:31:57 2010 @@ -1,31 +1,37 @@ -import types - -class export(object): - """decorator to mark a function as exported by a shared module. - Can be used with a signature:: - @export(float, float) - def f(x, y): - return x + y - or without any argument at all:: - @export - def f(x, y): - return x + y - in which case the function must be used somewhere else, which will - trigger its annotation.""" - argtypes = None - - def __new__(cls, *args, **kwds): - if len(args) == 1 and isinstance(args[0], types.FunctionType): - func = args[0] - decorated = export()(func) - del decorated.argtypes - return decorated - return object.__new__(cls, *args, **kwds) - - def __init__(self, *args): - self.argtypes = args - - def __call__(self, func): - if self.argtypes is not None: - func.argtypes = self.argtypes - return func +import types + +class export(object): + """decorator to mark a function as exported by a shared module. + Can be used with a signature:: + @export(float, float) + def f(x, y): + return x + y + or without any argument at all:: + @export + def f(x, y): + return x + y + in which case the function must be used somewhere else, which will + trigger its annotation.""" + + argtypes = None + namespace = None + + def __new__(cls, *args, **kwds): + if len(args) == 1 and isinstance(args[0], types.FunctionType): + func = args[0] + decorated = export()(func) + del decorated.argtypes + return decorated + return object.__new__(cls, *args, **kwds) + + def __init__(self, *args, **kwargs): + self.argtypes = args + self.namespace = kwargs.get('namespace') + + def __call__(self, func): + func.exported = True + if self.argtypes is not None: + func.argtypes = self.argtypes + if self.namespace is not None: + func.namespace = self.namespace + return func Added: pypy/branch/separate-compilation/pypy/translator/test/test_separate.py ============================================================================== --- (empty file) +++ pypy/branch/separate-compilation/pypy/translator/test/test_separate.py Mon Jan 11 17:31:57 2010 @@ -0,0 +1,20 @@ +from pypy.translator.separate import export + +class TestSeparate: + def test_export(self): + @export(int, float) + def foo(x, y): + pass + @export(int, float, namespace='test') + def bar(x, y): + pass + @export + def baz(): + pass + + assert foo.argtypes == (int, float) + assert not hasattr(foo, '_namespace_') + assert bar.argtypes == (int, float) + assert bar.namespace == 'test' + assert not hasattr(baz, 'argtypes') + assert baz.exported From fijal at codespeak.net Mon Jan 11 17:40:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 17:40:20 +0100 (CET) Subject: [pypy-svn] r70511 - pypy/branch/jit-profiling Message-ID: <20100111164020.A1E1416802A@codespeak.net> Author: fijal Date: Mon Jan 11 17:40:20 2010 New Revision: 70511 Added: pypy/branch/jit-profiling/ - copied from r70510, pypy/trunk/ Log: (pedronis, fijal) A branch to experiment with jit-aware profiling From fijal at codespeak.net Mon Jan 11 17:56:02 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 17:56:02 +0100 (CET) Subject: [pypy-svn] r70512 - pypy/trunk/pypy/translator/c/src Message-ID: <20100111165602.C045B168027@codespeak.net> Author: fijal Date: Mon Jan 11 17:56:02 2010 New Revision: 70512 Removed: pypy/trunk/pypy/translator/c/src/trace.h Modified: pypy/trunk/pypy/translator/c/src/g_include.h Log: remove some oooold stuff, not used Modified: pypy/trunk/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/g_include.h (original) +++ pypy/trunk/pypy/translator/c/src/g_include.h Mon Jan 11 17:56:02 2010 @@ -17,11 +17,7 @@ #include "src/mem.h" #include "src/exception.h" #include "src/support.h" -#ifndef AVR -#include "src/trace.h" -#else - #define PY_LONG_LONG long long -#endif +#define PY_LONG_LONG long long #ifndef PYPY_STANDALONE # include "src/pyobj.h" From afa at codespeak.net Mon Jan 11 20:22:08 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 11 Jan 2010 20:22:08 +0100 (CET) Subject: [pypy-svn] r70513 - pypy/branch/separate-compilation/pypy/translator/cli/test Message-ID: <20100111192208.81EE5168029@codespeak.net> Author: afa Date: Mon Jan 11 20:22:07 2010 New Revision: 70513 Modified: pypy/branch/separate-compilation/pypy/translator/cli/test/test_carbonpython.py Log: Unskip test_carbonpython (maybe temporary) and make it pass on Windows Modified: pypy/branch/separate-compilation/pypy/translator/cli/test/test_carbonpython.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/cli/test/test_carbonpython.py (original) +++ pypy/branch/separate-compilation/pypy/translator/cli/test/test_carbonpython.py Mon Jan 11 20:22:07 2010 @@ -1,8 +1,7 @@ import py -py.test.skip("it passes usually, but fails on buildbot, no clue why") +#py.test.skip("it passes usually, but fails on buildbot, no clue why") -import os -import os.path +import sys, os from pypy.tool import udir from pypy.translator.cli.rte import Target from pypy.translator.cli.carbonpython import DllDef, export, collect_entrypoints,\ @@ -24,9 +23,15 @@ def _csharp(self, source, references=[], netmodules=[]): tmpfile = udir.udir.join('tmp.cs') tmpfile.write(TEMPLATE % source) - flags = ['/r:%s' % ref for ref in references] - flags += ['/addmodule:%s' % mod for mod in netmodules] - + if sys.platform == 'win32': + flags = ['/r:%s.dll' % ref for ref in references] + else: + flags = ['/r:%s' % ref for ref in references] + if sys.platform == 'win32': + flags += ['/addmodule:%s.netmodule' % mod for mod in netmodules] + else: + flags += ['/addmodule:%s' % mod for mod in netmodules] + class MyTarget(Target): SOURCES = [str(tmpfile)] FLAGS = flags From fijal at codespeak.net Mon Jan 11 21:01:17 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 11 Jan 2010 21:01:17 +0100 (CET) Subject: [pypy-svn] r70514 - in pypy/branch/jit-profiling/pypy: interpreter interpreter/test module/_lsprof Message-ID: <20100111200117.EBB5C318139@codespeak.net> Author: fijal Date: Mon Jan 11 21:01:15 2010 New Revision: 70514 Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py pypy/branch/jit-profiling/pypy/module/_lsprof/interp_lsprof.py Log: Change the internal mode of profiling to pass around numbers instead of strings. Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py Mon Jan 11 21:01:15 2010 @@ -5,10 +5,27 @@ from pypy.rlib.unroll import unrolling_iterable from pypy.rlib import jit +TRACE_EXCEPTION = 0 +TRACE_RETURN = 1 +_PROFILING_FIRST = 2 +TRACE_CALL = 2 +TRACE_LEAVEFRAME = 3 +TRACE_C_CALL = 4 +TRACE_C_RETURN = 5 +TRACE_C_EXCEPTION = 6 +_PROFILING_LAST = 6 +TRACE_LINE = 7 + +TRACE_TO_NAME = [] +for i, k in enumerate(['exception', 'return', 'call', 'leaveframe', 'c_call', + 'c_return', 'c_exception', 'line']): + TRACE_TO_NAME.append(k) + assert globals()['TRACE_' + k.upper()] == i + def app_profile_call(space, w_callable, frame, event, w_arg): space.call_function(w_callable, space.wrap(frame), - space.wrap(event), w_arg) + space.wrap(TRACE_TO_NAME[event]), w_arg) class ExecutionContext(object): """An ExecutionContext holds the state of an execution thread @@ -59,7 +76,7 @@ def leave(self, frame): try: if self.profilefunc: - self._trace(frame, 'leaveframe', self.space.w_None) + self._trace(frame, TRACE_LEAVEFRAME, self.space.w_None) finally: self.topframeref = frame.f_backref self.framestackdepth -= 1 @@ -144,33 +161,33 @@ if self.profilefunc is None: frame.is_being_profiled = False else: - self._trace(frame, 'c_call', w_func) + self._trace(frame, TRACE_C_CALL, w_func) def c_return_trace(self, frame, w_retval): "Profile the return from a builtin function" if self.profilefunc is None: frame.is_being_profiled = False else: - self._trace(frame, 'c_return', w_retval) + self._trace(frame, TRACE_C_RETURN, w_retval) def c_exception_trace(self, frame, w_exc): "Profile function called upon OperationError." if self.profilefunc is None: frame.is_being_profiled = False else: - self._trace(frame, 'c_exception', w_exc) + self._trace(frame, TRACE_C_EXCEPTION, w_exc) def call_trace(self, frame): "Trace the call of a function" if self.w_tracefunc is not None or self.profilefunc is not None: - self._trace(frame, 'call', self.space.w_None) + self._trace(frame, TRACE_CALL, self.space.w_None) if self.profilefunc: frame.is_being_profiled = True def return_trace(self, frame, w_retval): "Trace the return from a function" if self.w_tracefunc is not None: - self._trace(frame, 'return', w_retval) + self._trace(frame, TRACE_RETURN, w_retval) def bytecode_trace(self, frame): "Trace function called before each bytecode." @@ -197,7 +214,7 @@ "Trace function called upon OperationError." operationerr.record_interpreter_traceback() if self.w_tracefunc is not None: - self._trace(frame, 'exception', None, operationerr) + self._trace(frame, TRACE_EXCEPTION, None, operationerr) #operationerr.print_detailed_traceback(self.space) def sys_exc_info(self): # attn: the result is not the wrapped sys.exc_info() !!! @@ -260,18 +277,19 @@ self.is_tracing = is_tracing def _trace(self, frame, event, w_arg, operr=None): + assert isinstance(event, int) if self.is_tracing or frame.hide(): return space = self.space # Tracing cases - if event == 'call': + if event == TRACE_CALL: w_callback = self.w_tracefunc else: w_callback = frame.w_f_trace - if w_callback is not None and event != "leaveframe": + if w_callback is not None and event != TRACE_LEAVEFRAME: if operr is not None: w_arg = space.newtuple([operr.w_type, operr.w_value, space.wrap(operr.application_traceback)]) @@ -280,7 +298,7 @@ self.is_tracing += 1 try: try: - w_result = space.call_function(w_callback, space.wrap(frame), space.wrap(event), w_arg) + w_result = space.call_function(w_callback, space.wrap(frame), space.wrap(TRACE_TO_NAME[event]), w_arg) if space.is_w(w_result, space.w_None): frame.w_f_trace = None else: @@ -296,14 +314,13 @@ # Profile cases if self.profilefunc is not None: - if event not in ['leaveframe', 'call', 'c_call', - 'c_return', 'c_exception']: + if event < _PROFILING_FIRST or event > _PROFILING_LAST: return last_exception = None - if event == 'leaveframe': + if event == TRACE_LEAVEFRAME: last_exception = frame.last_exception - event = 'return' + event = TRACE_RETURN assert self.is_tracing == 0 self.is_tracing += 1 @@ -523,7 +540,7 @@ if frame.instr_lb <= frame.last_instr < frame.instr_ub: if frame.last_instr <= frame.instr_prev: # We jumped backwards in the same line. - executioncontext._trace(frame, 'line', self.space.w_None) + executioncontext._trace(frame, TRACE_LINE, self.space.w_None) else: size = len(code.co_lnotab) / 2 addr = 0 @@ -557,7 +574,7 @@ if frame.instr_lb == frame.last_instr: # At start of line! frame.f_lineno = line - executioncontext._trace(frame, 'line', self.space.w_None) + executioncontext._trace(frame, TRACE_LINE, self.space.w_None) frame.instr_prev = frame.last_instr self.space.frame_trace_action.fire() # continue tracing Modified: pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py Mon Jan 11 21:01:15 2010 @@ -1,6 +1,9 @@ import py from pypy.interpreter import executioncontext from pypy.conftest import gettestobjspace +from pypy.interpreter.executioncontext import (TRACE_CALL, TRACE_RETURN, + TRACE_C_CALL, TRACE_C_RETURN, TRACE_C_EXCEPTION, TRACE_EXCEPTION, + TRACE_LEAVEFRAME, TRACE_LINE) class Finished(Exception): pass @@ -74,7 +77,7 @@ pass """) space.getexecutioncontext().setllprofile(None, None) - assert l == ['call', 'return', 'call', 'return'] + assert l == [TRACE_CALL, TRACE_RETURN] * 2 def test_llprofile_c_call(self): l = [] @@ -92,7 +95,8 @@ return """ % snippet) space.getexecutioncontext().setllprofile(None, None) - assert l == ['call', 'return', 'call', 'c_call', 'c_return', 'return'] + assert l == [TRACE_CALL, TRACE_RETURN, TRACE_CALL, TRACE_C_CALL, + TRACE_C_RETURN, TRACE_RETURN] check_snippet('l = []; l.append(42)') check_snippet('max(1, 2)') @@ -120,7 +124,8 @@ return """ % snippet) space.getexecutioncontext().setllprofile(None, None) - assert l == ['call', 'return', 'call', 'c_call', 'c_exception', 'return'] + assert l == [TRACE_CALL, TRACE_RETURN, TRACE_CALL, + TRACE_C_CALL, TRACE_C_EXCEPTION, TRACE_RETURN] check_snippet('d = {}; d.__getitem__(42)') @@ -144,7 +149,8 @@ return l """) events = space.unwrap(w_events) - assert events == ['return', 'c_call', 'c_return', 'return', 'c_call'] + assert events == [TRACE_RETURN, TRACE_C_CALL, TRACE_C_RETURN, + TRACE_RETURN, TRACE_C_CALL] def test_c_call_setprofile_strange_method(self): space = self.space @@ -173,7 +179,8 @@ return l """) events = space.unwrap(w_events) - assert events == ['return', 'call', 'return', 'return', 'c_call'] + assert events == [TRACE_RETURN, TRACE_CALL, TRACE_RETURN, + TRACE_RETURN, TRACE_C_CALL] def test_c_call_profiles_immediately(self): space = self.space @@ -192,7 +199,8 @@ return l """) events = space.unwrap(w_events) - assert [i[0] for i in events] == ['c_call', 'c_return', 'return', 'c_call'] + assert [i[0] for i in events] == [TRACE_C_CALL, TRACE_C_RETURN, + TRACE_RETURN, TRACE_C_CALL] assert events[0][1] == events[1][1] def test_tracing_range_builtinshortcut(self): @@ -218,4 +226,5 @@ return l """) events = space.unwrap(w_events) - assert [i[0] for i in events] == ['c_call', 'c_return', 'c_call'] + assert [i[0] for i in events] == [TRACE_C_CALL, TRACE_C_RETURN, + TRACE_C_CALL] Modified: pypy/branch/jit-profiling/pypy/module/_lsprof/interp_lsprof.py ============================================================================== --- pypy/branch/jit-profiling/pypy/module/_lsprof/interp_lsprof.py (original) +++ pypy/branch/jit-profiling/pypy/module/_lsprof/interp_lsprof.py Mon Jan 11 21:01:15 2010 @@ -5,6 +5,8 @@ interp_attrproperty) from pypy.interpreter.gateway import interp2app, NoneNotWrapped from pypy.interpreter.function import Method, Function +from pypy.interpreter.executioncontext import (TRACE_CALL, TRACE_RETURN, + TRACE_C_CALL, TRACE_C_RETURN) import time, sys class W_StatsEntry(Wrappable): @@ -180,17 +182,17 @@ def lsprof_call(space, w_self, frame, event, w_arg): assert isinstance(w_self, W_Profiler) - if event == 'call': + if event == TRACE_CALL: code = frame.getcode() w_self._enter_call(code) - elif event == 'return': + elif event == TRACE_RETURN: code = frame.getcode() w_self._enter_return(code) - elif event == 'c_call': + elif event == TRACE_C_CALL: if w_self.builtins: key = create_spec(space, w_arg) w_self._enter_builtin_call(key) - elif event == 'c_return': + elif event == TRACE_C_RETURN: if w_self.builtins: key = create_spec(space, w_arg) w_self._enter_builtin_return(key) From afa at codespeak.net Mon Jan 11 21:12:55 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 11 Jan 2010 21:12:55 +0100 (CET) Subject: [pypy-svn] r70515 - in pypy/branch/separate-compilation/pypy/translator: . cli cli/test Message-ID: <20100111201255.86EF6168027@codespeak.net> Author: afa Date: Mon Jan 11 21:12:53 2010 New Revision: 70515 Modified: pypy/branch/separate-compilation/pypy/translator/cli/carbonpython.py pypy/branch/separate-compilation/pypy/translator/cli/cts.py pypy/branch/separate-compilation/pypy/translator/cli/function.py pypy/branch/separate-compilation/pypy/translator/cli/test/test_carbonpython.py pypy/branch/separate-compilation/pypy/translator/separate.py Log: Start sharing code between CarbonPython and the C backend. Modified: pypy/branch/separate-compilation/pypy/translator/cli/carbonpython.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/cli/carbonpython.py (original) +++ pypy/branch/separate-compilation/pypy/translator/cli/carbonpython.py Mon Jan 11 21:12:53 2010 @@ -13,6 +13,7 @@ from pypy.translator.driver import TranslationDriver from pypy.translator.cli.entrypoint import DllEntryPoint +from pypy.translator.separate import export, is_exported class DllDef: def __init__(self, name, namespace, functions=[], dontmangle=True, isnetmodule=False): @@ -36,39 +37,15 @@ # add all functions to the appropriate namespace if self.namespace: for func, _ in self.functions: - if not hasattr(func, '_namespace_'): - func._namespace_ = self.namespace + if not hasattr(func, 'namespace'): + func.namespace = self.namespace self.driver.proceed(['compile_cli']) -class export(object): - def __new__(self, *args, **kwds): - if len(args) == 1 and isinstance(args[0], types.FunctionType): - func = args[0] - func._inputtypes_ = () - return func - return object.__new__(self, *args, **kwds) - - def __init__(self, *args, **kwds): - self.inputtypes = args - self.namespace = kwds.pop('namespace', None) - if len(kwds) > 0: - raise TypeError, "unexpected keyword argument: '%s'" % kwds.keys()[0] - - def __call__(self, func): - func._inputtypes_ = self.inputtypes - if self.namespace is not None: - func._namespace_ = self.namespace - return func - -def is_exported(obj): - return isinstance(obj, (types.FunctionType, types.UnboundMethodType)) \ - and hasattr(obj, '_inputtypes_') - def collect_entrypoints(dic): entrypoints = [] for item in dic.itervalues(): if is_exported(item): - entrypoints.append((item, item._inputtypes_)) + entrypoints.append((item, item.argtypes)) elif isinstance(item, types.ClassType) or isinstance(item, type): entrypoints += collect_class_entrypoints(item) return entrypoints @@ -81,10 +58,10 @@ except AttributeError: return [] - entrypoints = [(wrap_init(cls, __init__), __init__._inputtypes_)] + entrypoints = [(wrap_init(cls, __init__), __init__.argtypes)] for item in cls.__dict__.itervalues(): if item is not __init__.im_func and is_exported(item): - inputtypes = (cls,) + item._inputtypes_ + inputtypes = (cls,) + item.argtypes entrypoints.append((wrap_method(item), inputtypes)) return entrypoints @@ -126,7 +103,7 @@ elif dllname.endswith('.dll'): dllname, _ = os.path.splitext(dllname) module = new.module(dllname) - namespace = module.__dict__.get('_namespace_', dllname) + namespace = module.__dict__.get('namespace', dllname) sys.path.insert(0, dirname) execfile(filename, module.__dict__) sys.path.pop(0) Modified: pypy/branch/separate-compilation/pypy/translator/cli/cts.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/cli/cts.py (original) +++ pypy/branch/separate-compilation/pypy/translator/cli/cts.py Mon Jan 11 21:12:53 2010 @@ -318,7 +318,7 @@ def graph_to_signature(self, graph, is_method = False, func_name = None): func_name = func_name or graph.name func_name = self.escape_name(func_name) - namespace = getattr(graph.func, '_namespace_', None) + namespace = getattr(graph.func, 'namespace', None) if namespace: func_name = '%s::%s' % (namespace, func_name) Modified: pypy/branch/separate-compilation/pypy/translator/cli/function.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/cli/function.py (original) +++ pypy/branch/separate-compilation/pypy/translator/cli/function.py Mon Jan 11 21:12:53 2010 @@ -24,7 +24,7 @@ if hasattr(self.db.genoo, 'exceptiontransformer'): self.auto_propagate_exceptions = False - namespace = getattr(self.graph.func, '_namespace_', None) + namespace = getattr(self.graph.func, 'namespace', None) if namespace: if '.' in namespace: self.namespace, self.classname = namespace.rsplit('.', 1) Modified: pypy/branch/separate-compilation/pypy/translator/cli/test/test_carbonpython.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/cli/test/test_carbonpython.py (original) +++ pypy/branch/separate-compilation/pypy/translator/cli/test/test_carbonpython.py Mon Jan 11 21:12:53 2010 @@ -77,11 +77,12 @@ def baz(): pass - assert foo._inputtypes_ == (int, float) + assert foo.argtypes == (int, float) assert not hasattr(foo, '_namespace_') - assert bar._inputtypes_ == (int, float) - assert bar._namespace_ == 'test' - assert baz._inputtypes_ == () + assert bar.argtypes == (int, float) + assert bar.namespace == 'test' + assert baz.exported + assert not hasattr(baz, 'argtypes') def test_collect_entrypoints(self): @export(int, float) @@ -99,7 +100,7 @@ pass class MyClass: - @export + @export() def __init__(self): pass @export(int) @@ -134,7 +135,7 @@ assert res == 42 def test_export_cliclass(self): - py.test.skip('it fails every other day on builbot, no clue why') + #py.test.skip('it fails every other day on builbot, no clue why') from pypy.translator.cli.dotnet import CLR @export(CLR.System.Collections.ArrayList, int) @@ -152,7 +153,7 @@ assert res == 42 def test_compile_dll(self): - py.test.skip('This test fails every other day. No clue why :-(') + #py.test.skip('This test fails every other day. No clue why :-(') cwd, _ = os.path.split(__file__) mylib_py = os.path.join(cwd, 'mylib.py') compile_dll(mylib_py, copy_dll=False) Modified: pypy/branch/separate-compilation/pypy/translator/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/separate.py Mon Jan 11 21:12:53 2010 @@ -24,9 +24,11 @@ return decorated return object.__new__(cls, *args, **kwds) - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwds): self.argtypes = args - self.namespace = kwargs.get('namespace') + self.namespace = kwds.pop('namespace', None) + if kwds: + raise TypeError("unexpected keyword arguments: %s" % kwds.keys()) def __call__(self, func): func.exported = True @@ -35,3 +37,8 @@ if self.namespace is not None: func.namespace = self.namespace return func + +def is_exported(obj): + return (isinstance(obj, (types.FunctionType, types.UnboundMethodType)) + and getattr(obj, 'exported', False)) + From afa at codespeak.net Mon Jan 11 21:31:58 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 11 Jan 2010 21:31:58 +0100 (CET) Subject: [pypy-svn] r70516 - pypy/branch/separate-compilation/pypy/translator/c/test Message-ID: <20100111203158.5DC86168038@codespeak.net> Author: afa Date: Mon Jan 11 21:31:57 2010 New Revision: 70516 Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: When a function is "annotated by example", constant propagation may occur and gives wrong results. In this case, reflow the annotation with non-constant parameters. Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Mon Jan 11 21:31:57 2010 @@ -4,6 +4,7 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import rffi, lltype +from pypy.annotation import model import py import sys, os @@ -20,14 +21,29 @@ def compile_separated(self, name, **exports): t = TranslationContext() t.buildannotator() + bk = t.annotator.bookkeeper + + # annotate functions with signatures for funcname, func in exports.items(): if hasattr(func, 'argtypes'): t.annotator.build_types(func, func.argtypes) + + # ensure that functions without signature are not constant-folded + for funcname, func in exports.items(): + if not hasattr(func, 'argtypes'): + # build a list of arguments where constants are erased + newargs = [] + graph = bk.getdesc(func).getuniquegraph() + for arg in graph.startblock.inputargs: + newarg = model.not_const(t.annotator.binding(arg)) + newargs.append(newarg) + # and reflow + t.annotator.build_types(func, newargs) + t.buildrtyper().specialize() exported_funcptr = {} for funcname, func in exports.items(): - bk = t.annotator.bookkeeper graph = bk.getdesc(func).getuniquegraph() funcptr = getfunctionptr(graph) @@ -88,7 +104,6 @@ @export() def f2(): f(1.0) - f(2.0) firstmodule = self.compile_separated("first", f=f, f2=f2) # call it from a function compiled in another module From afa at codespeak.net Tue Jan 12 00:34:52 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 12 Jan 2010 00:34:52 +0100 (CET) Subject: [pypy-svn] r70517 - pypy/branch/separate-compilation/pypy/translator/c/test Message-ID: <20100111233452.92EB616802A@codespeak.net> Author: afa Date: Tue Jan 12 00:34:51 2010 New Revision: 70517 Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Work in progress: try to export classes and pass them between modules. This does not work yet: llexternal does not convert instances to GcStruct. Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Tue Jan 12 00:34:51 2010 @@ -4,7 +4,7 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import rffi, lltype -from pypy.annotation import model +from pypy.annotation import model, description import py import sys, os @@ -26,25 +26,36 @@ # annotate functions with signatures for funcname, func in exports.items(): if hasattr(func, 'argtypes'): - t.annotator.build_types(func, func.argtypes) + t.annotator.build_types(func, func.argtypes, + complete_now=False) # ensure that functions without signature are not constant-folded for funcname, func in exports.items(): if not hasattr(func, 'argtypes'): # build a list of arguments where constants are erased newargs = [] - graph = bk.getdesc(func).getuniquegraph() - for arg in graph.startblock.inputargs: - newarg = model.not_const(t.annotator.binding(arg)) - newargs.append(newarg) - # and reflow - t.annotator.build_types(func, newargs) + desc = bk.getdesc(func) + if isinstance(desc, description.FunctionDesc): + graph = desc.getuniquegraph() + for arg in graph.startblock.inputargs: + newarg = model.not_const(t.annotator.binding(arg)) + newargs.append(newarg) + # and reflow + t.annotator.build_types(func, newargs) + elif isinstance(desc, description.ClassDesc): + s_init = desc.s_read_attribute('__init__') + initfunc = s_init.const + newargs = [func, float] + t.annotator.build_types(initfunc, newargs) t.buildrtyper().specialize() exported_funcptr = {} for funcname, func in exports.items(): - graph = bk.getdesc(func).getuniquegraph() + desc = bk.getdesc(func) + if not isinstance(desc, description.FunctionDesc): + continue + graph = desc.getuniquegraph() funcptr = getfunctionptr(graph) exported_funcptr[funcname] = funcptr @@ -114,3 +125,23 @@ c_fn = self.compile_function(fn, []) assert c_fn() == 42.5 + def test_pass_structure(self): + class S: + @export + def __init__(self, x): + self.x = x + + # function exported from the 'first' module + @export(S) + def f(s): + return s.x + 1.5 + firstmodule = self.compile_separated("first", f=f, S=S) + + # call it from a function compiled in another module + def fn(): + s = S(41.0) + return firstmodule.f(s) + + #assert fn() == 42.5 + c_fn = self.compile_function(fn, []) + assert c_fn() == 42.5 From fijal at codespeak.net Tue Jan 12 10:19:24 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 10:19:24 +0100 (CET) Subject: [pypy-svn] r70518 - pypy/trunk/pypy/translator/benchmark Message-ID: <20100112091924.0039C168038@codespeak.net> Author: fijal Date: Tue Jan 12 10:19:23 2010 New Revision: 70518 Modified: pypy/trunk/pypy/translator/benchmark/result.py Log: Cut lines to 80, if more are present Modified: pypy/trunk/pypy/translator/benchmark/result.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/result.py (original) +++ pypy/trunk/pypy/translator/benchmark/result.py Tue Jan 12 10:19:23 2010 @@ -97,8 +97,11 @@ print new_result if verbose: print '{' - for line in benchmark.latest_output.splitlines(False): + lines = benchmark.latest_output.splitlines(False) + for line in lines[:80]: print '\t' + line + if len(lines) > 80: + print '\t....' print '}' self.run_counts[benchmark.name] = self.run_counts.get(benchmark.name, 0) + 1 if new_result == '-FAILED-': From fijal at codespeak.net Tue Jan 12 10:42:06 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 10:42:06 +0100 (CET) Subject: [pypy-svn] r70519 - pypy/branch/jit-profiling/pypy/interpreter/test Message-ID: <20100112094206.ECBA216803C@codespeak.net> Author: fijal Date: Tue Jan 12 10:42:06 2010 New Revision: 70519 Added: pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py (contents, props changed) Log: Start writing tests for the new profiling case, for starters something simple Added: pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py ============================================================================== --- (empty file) +++ pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py Tue Jan 12 10:42:06 2010 @@ -0,0 +1,27 @@ + +from pypy.interpreter.executioncontext import ExecutionContext, TRACE_CALL,\ + TRACE_RETURN + +class MockExecutionContext(ExecutionContext): + pass + +class MockFrame(object): + w_f_trace = None + last_exception = None + + def hide(self): + return False + +class TestProfiling(object): + def test_simple(self): + events = [] + def profilefunc(space, ignored, frame, event, w_arg): + events.append(event) + + ec = MockExecutionContext(self.space) + frame = MockFrame() + ec.setllprofile(profilefunc, self.space.w_None) + ec.enter(frame) + ec.call_trace(frame) + ec.leave(frame) + assert events == [TRACE_CALL, TRACE_RETURN] From fijal at codespeak.net Tue Jan 12 11:42:47 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 11:42:47 +0100 (CET) Subject: [pypy-svn] r70521 - in pypy/branch/jit-profiling/pypy/interpreter: . test Message-ID: <20100112104247.BF56D168038@codespeak.net> Author: fijal Date: Tue Jan 12 11:42:46 2010 New Revision: 70521 Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py Log: A bit break everything. Now the profiling hook is invoked depending on us being jitted or not (except for leave) Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py Tue Jan 12 11:42:46 2010 @@ -36,6 +36,9 @@ # XXX self.w_tracefunc, self.profilefunc # XXX frame.is_being_profiled + # bind it here, so tests can overwrite it + _we_are_jitted = staticmethod(jit.we_are_jitted) + def __init__(self, space): self.space = space self.topframeref = jit.vref_None @@ -75,7 +78,10 @@ def leave(self, frame): try: - if self.profilefunc: + # below we need to check if is_being_profiled is set, instead + # of profilefunc, since when jitted we have profilefunc, but not + # is_being_profiled + if frame.is_being_profiled: self._trace(frame, TRACE_LEAVEFRAME, self.space.w_None) finally: self.topframeref = frame.f_backref @@ -179,7 +185,8 @@ def call_trace(self, frame): "Trace the call of a function" - if self.w_tracefunc is not None or self.profilefunc is not None: + if (self.w_tracefunc is not None or + (not self._we_are_jitted() and self.profilefunc is not None)): self._trace(frame, TRACE_CALL, self.space.w_None) if self.profilefunc: frame.is_being_profiled = True Modified: pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py Tue Jan 12 11:42:46 2010 @@ -3,17 +3,31 @@ TRACE_RETURN class MockExecutionContext(ExecutionContext): - pass + _jitted = False + + def _we_are_jitted(self): + return self._jitted + + def enter_jit(self): + self._jitted = True + + def leave_jit(self): + self._jitted = False + + def call(self, frame): + self.enter(frame) + self.call_trace(frame) class MockFrame(object): - w_f_trace = None - last_exception = None + w_f_trace = None + last_exception = None + is_being_profiled = False def hide(self): return False class TestProfiling(object): - def test_simple(self): + def test_no_jit(self): events = [] def profilefunc(space, ignored, frame, event, w_arg): events.append(event) @@ -21,7 +35,25 @@ ec = MockExecutionContext(self.space) frame = MockFrame() ec.setllprofile(profilefunc, self.space.w_None) - ec.enter(frame) - ec.call_trace(frame) + ec.call(frame) ec.leave(frame) assert events == [TRACE_CALL, TRACE_RETURN] + + def test_inlined_call(self): + events = [] + def profilefunc(space, ignored, frame, event, w_arg): + events.append((event, frame)) + + ec = MockExecutionContext(self.space) + frame = MockFrame() + frame2 = MockFrame() + ec.setllprofile(profilefunc, self.space.w_None) + ec.call(frame) + ec.enter_jit() + ec.call(frame2) + ec.leave(frame2) + ec.call(frame2) + ec.leave(frame2) + ec.leave_jit() + ec.leave(frame) + assert events == [(TRACE_CALL, frame), (TRACE_RETURN, frame)] From fijal at codespeak.net Tue Jan 12 11:43:13 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 11:43:13 +0100 (CET) Subject: [pypy-svn] r70522 - pypy/branch/jit-profiling/pypy/module/pypyjit Message-ID: <20100112104313.64250168038@codespeak.net> Author: fijal Date: Tue Jan 12 11:43:12 2010 New Revision: 70522 Modified: pypy/branch/jit-profiling/pypy/module/pypyjit/interp_jit.py Log: remove dependency on is_being_profiled being False for entering JIT Modified: pypy/branch/jit-profiling/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/jit-profiling/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/jit-profiling/pypy/module/pypyjit/interp_jit.py Tue Jan 12 11:43:12 2010 @@ -42,10 +42,7 @@ bytecode.jit_cells[next_instr] = newcell def confirm_enter_jit(next_instr, bytecode, frame, ec): - return (frame.w_f_trace is None and - ec.profilefunc is None and - ec.w_tracefunc is None) - + return frame.w_f_trace is None and ec.w_tracefunc is None class PyPyJitDriver(JitDriver): reds = ['frame', 'ec'] From fijal at codespeak.net Tue Jan 12 11:51:24 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 11:51:24 +0100 (CET) Subject: [pypy-svn] r70523 - pypy/branch/jit-profiling/pypy/interpreter/test Message-ID: <20100112105124.B320C168038@codespeak.net> Author: fijal Date: Tue Jan 12 11:51:24 2010 New Revision: 70523 Modified: pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py Log: Eh, fix tests Modified: pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py Tue Jan 12 11:51:24 2010 @@ -149,8 +149,7 @@ return l """) events = space.unwrap(w_events) - assert events == [TRACE_RETURN, TRACE_C_CALL, TRACE_C_RETURN, - TRACE_RETURN, TRACE_C_CALL] + assert events == ['return', 'c_call', 'c_return', 'return' ,'c_call'] def test_c_call_setprofile_strange_method(self): space = self.space @@ -179,8 +178,7 @@ return l """) events = space.unwrap(w_events) - assert events == [TRACE_RETURN, TRACE_CALL, TRACE_RETURN, - TRACE_RETURN, TRACE_C_CALL] + assert events == ['return', 'call', 'return', 'return', 'c_call'] def test_c_call_profiles_immediately(self): space = self.space @@ -199,8 +197,8 @@ return l """) events = space.unwrap(w_events) - assert [i[0] for i in events] == [TRACE_C_CALL, TRACE_C_RETURN, - TRACE_RETURN, TRACE_C_CALL] + assert [i[0] for i in events] == ['c_call', 'c_return', 'return', + 'c_call'] assert events[0][1] == events[1][1] def test_tracing_range_builtinshortcut(self): @@ -226,5 +224,4 @@ return l """) events = space.unwrap(w_events) - assert [i[0] for i in events] == [TRACE_C_CALL, TRACE_C_RETURN, - TRACE_C_CALL] + assert [i[0] for i in events] == ['c_call', 'c_return', 'c_call'] From fijal at codespeak.net Tue Jan 12 12:34:52 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 12:34:52 +0100 (CET) Subject: [pypy-svn] r70524 - pypy/branch/jit-profiling/pypy/interpreter Message-ID: <20100112113452.3B31016803C@codespeak.net> Author: fijal Date: Tue Jan 12 12:34:51 2010 New Revision: 70524 Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py Log: add is_being_profiled lazily. This makes frame not escape in case we set a profiling hook (since we don't call force_all_frames) Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py Tue Jan 12 12:34:51 2010 @@ -83,6 +83,9 @@ # is_being_profiled if frame.is_being_profiled: self._trace(frame, TRACE_LEAVEFRAME, self.space.w_None) + nextframe = frame.f_backref() + if nextframe is not None: + nextframe.is_being_profiled = True finally: self.topframeref = frame.f_backref self.framestackdepth -= 1 @@ -255,11 +258,13 @@ if func is not None: if w_arg is None: raise ValueError("Cannot call setllprofile with real None") - self.force_all_frames(is_being_profiled=True) + topframe = self.gettopframe_nohidden() + if topframe is not None: + topframe.is_being_profiled = True self.profilefunc = func self.w_profilefuncarg = w_arg - def force_all_frames(self, is_being_profiled=False): + def force_all_frames(self): # "Force" all frames in the sense of the jit, and optionally # set the flag 'is_being_profiled' on them. A forced frame is # one out of which the jit will exit: if it is running so far, @@ -270,8 +275,6 @@ # field of all frames, during the loop below.) frame = self.gettopframe_nohidden() while frame: - if is_being_profiled: - frame.is_being_profiled = True frame = self.getnextframe_nohidden(frame) def call_tracing(self, w_func, w_args): From fijal at codespeak.net Tue Jan 12 12:52:13 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 12:52:13 +0100 (CET) Subject: [pypy-svn] r70525 - pypy/branch/jit-profiling/pypy/rlib Message-ID: <20100112115213.E8BF0168020@codespeak.net> Author: fijal Date: Tue Jan 12 12:52:13 2010 New Revision: 70525 Modified: pypy/branch/jit-profiling/pypy/rlib/jit.py Log: I *think* exception can't occur here Modified: pypy/branch/jit-profiling/pypy/rlib/jit.py ============================================================================== --- pypy/branch/jit-profiling/pypy/rlib/jit.py (original) +++ pypy/branch/jit-profiling/pypy/rlib/jit.py Tue Jan 12 12:52:13 2010 @@ -165,6 +165,7 @@ return _jit_vref.SomeVRef(s_obj) def specialize_call(self, hop): + hop.exception_cannot_occur() return hop.r_result.specialize_call(hop) class Entry(ExtRegistryEntry): From cfbolz at codespeak.net Tue Jan 12 12:54:31 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 12 Jan 2010 12:54:31 +0100 (CET) Subject: [pypy-svn] r70526 - pypy/extradoc/planning Message-ID: <20100112115431.BB610168020@codespeak.net> Author: cfbolz Date: Tue Jan 12 12:54:31 2010 New Revision: 70526 Modified: pypy/extradoc/planning/jit.txt Log: I tried to disable recursion limit checking, didn't help. Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Tue Jan 12 12:54:31 2010 @@ -54,8 +54,6 @@ - improve on predictability: don't trace into signals ... but produce just a conditional call (or just abort the trace) - directly call assembler for residual portal calls -- maybe think again about the recursion limit checking, which slows down calls - quite a bit - since threads are enabled with the JIT, getexecutioncontext cannot be folded by the JIT anymore. we need to do something in that direction From fijal at codespeak.net Tue Jan 12 13:04:25 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 13:04:25 +0100 (CET) Subject: [pypy-svn] r70527 - pypy/branch/jit-profiling/pypy/rlib Message-ID: <20100112120425.1F5BC168038@codespeak.net> Author: fijal Date: Tue Jan 12 13:04:24 2010 New Revision: 70527 Modified: pypy/branch/jit-profiling/pypy/rlib/_jit_vref.py Log: one more exception_cannot_occur Modified: pypy/branch/jit-profiling/pypy/rlib/_jit_vref.py ============================================================================== --- pypy/branch/jit-profiling/pypy/rlib/_jit_vref.py (original) +++ pypy/branch/jit-profiling/pypy/rlib/_jit_vref.py Tue Jan 12 13:04:24 2010 @@ -46,6 +46,7 @@ def rtype_simple_call(self, hop): [v] = hop.inputargs(self) v = hop.genop('jit_force_virtual', [v], resulttype = OBJECTPTR) + hop.exception_cannot_occur() return hop.genop('cast_pointer', [v], resulttype = hop.r_result) def convert_const(self, value): From fijal at codespeak.net Tue Jan 12 13:11:41 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 13:11:41 +0100 (CET) Subject: [pypy-svn] r70528 - pypy/branch/jit-profiling/pypy/rlib/test Message-ID: <20100112121141.CC06016803B@codespeak.net> Author: fijal Date: Tue Jan 12 13:11:41 2010 New Revision: 70528 Modified: pypy/branch/jit-profiling/pypy/rlib/test/test__jit_vref.py Log: A test for 70527 Modified: pypy/branch/jit-profiling/pypy/rlib/test/test__jit_vref.py ============================================================================== --- pypy/branch/jit-profiling/pypy/rlib/test/test__jit_vref.py (original) +++ pypy/branch/jit-profiling/pypy/rlib/test/test__jit_vref.py Tue Jan 12 13:11:41 2010 @@ -113,3 +113,18 @@ x = interpret(f, [-5]) assert lltype.typeOf(x) == OBJECTPTR assert not x + +def test_rtype_5(): + l = [] + def f(): + x = virtual_ref(Y()) + try: + y = x() + finally: + l.append(0) + if y is not None: + return 0 + return 1 + + x = interpret(f, []) + From fijal at codespeak.net Tue Jan 12 14:56:49 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 14:56:49 +0100 (CET) Subject: [pypy-svn] r70529 - pypy/branch/jit-profiling/pypy/module/pypyjit Message-ID: <20100112135649.EA2FB16803D@codespeak.net> Author: fijal Date: Tue Jan 12 14:56:48 2010 New Revision: 70529 Modified: pypy/branch/jit-profiling/pypy/module/pypyjit/policy.py Log: add _lsprof to policy to look into Modified: pypy/branch/jit-profiling/pypy/module/pypyjit/policy.py ============================================================================== --- pypy/branch/jit-profiling/pypy/module/pypyjit/policy.py (original) +++ pypy/branch/jit-profiling/pypy/module/pypyjit/policy.py Tue Jan 12 14:56:48 2010 @@ -8,7 +8,8 @@ if '.' in modname: modname, _ = modname.split('.', 1) - if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions']: + if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions', + '_lsprof']: return True return False From cfbolz at codespeak.net Tue Jan 12 15:00:30 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 12 Jan 2010 15:00:30 +0100 (CET) Subject: [pypy-svn] r70530 - pypy/branch/loop-invariant-decorator/pypy/module/pypyjit/test Message-ID: <20100112140030.1BE0316803D@codespeak.net> Author: cfbolz Date: Tue Jan 12 15:00:29 2010 New Revision: 70530 Modified: pypy/branch/loop-invariant-decorator/pypy/module/pypyjit/test/test_pypy_c.py Log: Adapt the test to be fine with the threading stuff. Modified: pypy/branch/loop-invariant-decorator/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/branch/loop-invariant-decorator/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/branch/loop-invariant-decorator/pypy/module/pypyjit/test/test_pypy_c.py Tue Jan 12 15:00:29 2010 @@ -172,7 +172,7 @@ x = x + (i&j) i = i + 1 return x - ''', 194, + ''', 220, ([2117], 1083876708)) def test_factorial(self): @@ -183,7 +183,7 @@ r *= n n -= 1 return r - ''', 26, + ''', 28, ([5], 120), ([20], 2432902008176640000L)) @@ -237,8 +237,11 @@ assert not ops[4] ops = self.get_by_bytecode("CALL_FUNCTION") assert len(ops) == 2 - for bytecode in ops: - assert not bytecode.get_opnames("call") + for i, bytecode in enumerate(ops): + if i == 0: + assert "call(getexecutioncontext)" in str(bytecode) + else: + assert not bytecode.get_opnames("call") assert not bytecode.get_opnames("new") assert len(bytecode.get_opnames("guard")) <= 10 @@ -268,8 +271,11 @@ ops = self.get_by_bytecode("CALL_METHOD") assert len(ops) == 2 - for bytecode in ops: - assert not bytecode.get_opnames("call") + for i, bytecode in enumerate(ops): + if i == 0: + assert "call(getexecutioncontext)" in str(bytecode) + else: + assert not bytecode.get_opnames("call") assert not bytecode.get_opnames("new") assert len(bytecode.get_opnames("guard")) <= 9 assert len(ops[1]) < len(ops[0]) @@ -296,8 +302,11 @@ ([31], 32)) ops = self.get_by_bytecode("CALL_FUNCTION") assert len(ops) == 2 - for bytecode in ops: - assert not bytecode.get_opnames("call") + for i, bytecode in enumerate(ops): + if i == 0: + assert "call(getexecutioncontext)" in str(bytecode) + else: + assert not bytecode.get_opnames("call") assert not bytecode.get_opnames("new") assert len(ops[0].get_opnames("guard")) <= 14 assert len(ops[1].get_opnames("guard")) <= 3 @@ -315,7 +324,7 @@ a.x = 2 i = i + a.x return i - ''', 65, + ''', 67, ([20], 20), ([31], 32)) @@ -346,7 +355,7 @@ while i < n: i = i + a.x return i - ''', 39, + ''', 41, ([20], 20), ([31], 32)) @@ -459,8 +468,6 @@ py.test.skip("pass --pypy!") if not has_info(option.pypy_c, 'translation.jit'): py.test.skip("must give a pypy-c with the jit enabled") - if has_info(option.pypy_c, 'translation.thread'): - py.test.skip("for now, must give a pypy-c-jit without threads") cls.tmpdir = udir.join('pypy-jit') cls.tmpdir.ensure(dir=1) cls.counter = 0 From fijal at codespeak.net Tue Jan 12 15:28:02 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 15:28:02 +0100 (CET) Subject: [pypy-svn] r70531 - pypy/branch/jit-profiling/pypy/interpreter Message-ID: <20100112142802.6558C16803D@codespeak.net> Author: fijal Date: Tue Jan 12 15:28:01 2010 New Revision: 70531 Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py Log: disable c_*_trace while we're jitted Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py Tue Jan 12 15:28:01 2010 @@ -167,6 +167,8 @@ def c_call_trace(self, frame, w_func): "Profile the call of a builtin function" + if self._we_are_jitted(): + return if self.profilefunc is None: frame.is_being_profiled = False else: @@ -174,6 +176,8 @@ def c_return_trace(self, frame, w_retval): "Profile the return from a builtin function" + if self._we_are_jitted(): + return if self.profilefunc is None: frame.is_being_profiled = False else: @@ -181,6 +185,8 @@ def c_exception_trace(self, frame, w_exc): "Profile function called upon OperationError." + if self._we_are_jitted(): + return if self.profilefunc is None: frame.is_being_profiled = False else: From fijal at codespeak.net Tue Jan 12 16:24:31 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 16:24:31 +0100 (CET) Subject: [pypy-svn] r70532 - in pypy/trunk/pypy/interpreter: . test Message-ID: <20100112152431.4B3D1168041@codespeak.net> Author: fijal Date: Tue Jan 12 16:24:30 2010 New Revision: 70532 Modified: pypy/trunk/pypy/interpreter/executioncontext.py pypy/trunk/pypy/interpreter/test/test_executioncontext.py Log: (pedronis, fijal) Shave a yak. We didn't consider that c_* trace events should not clean the last_exception bit Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Tue Jan 12 16:24:30 2010 @@ -300,9 +300,8 @@ 'c_return', 'c_exception']: return - last_exception = None + last_exception = frame.last_exception if event == 'leaveframe': - last_exception = frame.last_exception event = 'return' assert self.is_tracing == 0 Modified: pypy/trunk/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/test/test_executioncontext.py Tue Jan 12 16:24:30 2010 @@ -219,3 +219,26 @@ """) events = space.unwrap(w_events) assert [i[0] for i in events] == ['c_call', 'c_return', 'c_call'] + + def test_profile_and_exception(self): + space = self.space + w_res = space.appexec([], """(): + l = [] + + def profile(*args): + l.append(sys.exc_info()[0]) + + import sys + try: + sys.setprofile(profile) + try: + x + except: + expected = sys.exc_info()[0] + assert expected is NameError + for i in l: + assert expected is l[0] + finally: + sys.setprofile(None) + """) + From fijal at codespeak.net Tue Jan 12 16:26:19 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 12 Jan 2010 16:26:19 +0100 (CET) Subject: [pypy-svn] r70533 - in pypy/branch/jit-profiling/pypy/interpreter: . test Message-ID: <20100112152619.9894F168047@codespeak.net> Author: fijal Date: Tue Jan 12 16:26:19 2010 New Revision: 70533 Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py Log: (pedronis, fijal) Merge 70531 to branch Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py Tue Jan 12 16:26:19 2010 @@ -333,9 +333,8 @@ if event < _PROFILING_FIRST or event > _PROFILING_LAST: return - last_exception = None + last_exception = frame.last_exception if event == TRACE_LEAVEFRAME: - last_exception = frame.last_exception event = TRACE_RETURN assert self.is_tracing == 0 Modified: pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/test/test_executioncontext.py Tue Jan 12 16:26:19 2010 @@ -225,3 +225,26 @@ """) events = space.unwrap(w_events) assert [i[0] for i in events] == ['c_call', 'c_return', 'c_call'] + + def test_profile_and_exception(self): + space = self.space + w_res = space.appexec([], """(): + l = [] + + def profile(*args): + l.append(sys.exc_info()[0]) + + import sys + try: + sys.setprofile(profile) + try: + x + except: + expected = sys.exc_info()[0] + assert expected is NameError + for i in l: + assert expected is l[0] + finally: + sys.setprofile(None) + """) + From cfbolz at codespeak.net Tue Jan 12 16:49:26 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 12 Jan 2010 16:49:26 +0100 (CET) Subject: [pypy-svn] r70534 - in pypy/trunk/pypy: interpreter jit/backend jit/metainterp jit/metainterp/test module/pypyjit/test rlib Message-ID: <20100112154926.EA300168045@codespeak.net> Author: cfbolz Date: Tue Jan 12 16:49:26 2010 New Revision: 70534 Modified: pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/jit/backend/model.py pypy/trunk/pypy/jit/metainterp/codewriter.py pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/pyjitpl.py pypy/trunk/pypy/jit/metainterp/resoperation.py pypy/trunk/pypy/jit/metainterp/test/test_basic.py pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py pypy/trunk/pypy/rlib/jit.py Log: merge loop-invariant-decorator branch: ------------------------------------------------------------------------ r70448 | cfbolz | 2010-01-08 12:22:09 +0100 (Fri, 08 Jan 2010) | 3 lines Changed paths: A /pypy/branch/loop-invariant-decorator (from /pypy/trunk:70447) A new branch to implement the loop_invariant decorator needed to deal with reading the executioncontext out of TLS. ------------------------------------------------------------------------ r70499 | cfbolz | 2010-01-11 14:59:10 +0100 (Mon, 11 Jan 2010) | 2 lines Changed paths: M /pypy/branch/loop-invariant-decorator/pypy/rlib/jit.py add the loop_invariant decorator ------------------------------------------------------------------------ r70500 | cfbolz | 2010-01-11 15:00:11 +0100 (Mon, 11 Jan 2010) | 2 lines Changed paths: M /pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_basic.py the test that I would like to pass ------------------------------------------------------------------------ r70501 | cfbolz | 2010-01-11 15:13:21 +0100 (Mon, 11 Jan 2010) | 4 lines Changed paths: M /pypy/branch/loop-invariant-decorator/pypy/jit/backend/model.py M /pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/resoperation.py Add a new operation CALL_LOOPINVARIANT. The operation behaves exactly like CALL. The idea is that the backend never has to generate code for this operation, because the optimizer turns it into a normal CALL. ------------------------------------------------------------------------ r70502 | cfbolz | 2010-01-11 15:15:16 +0100 (Mon, 11 Jan 2010) | 3 lines Changed paths: M /pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/codewriter.py M /pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/pyjitpl.py Make the codewriter produce a new opcode, "residual_call_loopinvariant" and implement it in the metainterp. ------------------------------------------------------------------------ r70503 | cfbolz | 2010-01-11 15:18:53 +0100 (Mon, 11 Jan 2010) | 4 lines Changed paths: M /pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/optimizeopt.py M /pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_optimizeopt.py An optimization that replaces several loop-invariant calls to the same function by one call. Also add a direct test for that optimization. This implements the original test. ------------------------------------------------------------------------ r70504 | cfbolz | 2010-01-11 15:20:44 +0100 (Mon, 11 Jan 2010) | 2 lines Changed paths: M /pypy/branch/loop-invariant-decorator/pypy/interpreter/baseobjspace.py Declare getexecutioncontext to be loop-invariant. ------------------------------------------------------------------------ r70505 | cfbolz | 2010-01-11 15:27:39 +0100 (Mon, 11 Jan 2010) | 2 lines Changed paths: M /pypy/branch/loop-invariant-decorator/pypy/interpreter/baseobjspace.py missing import, of course ------------------------------------------------------------------------ r70508 | cfbolz | 2010-01-11 16:10:50 +0100 (Mon, 11 Jan 2010) | 2 lines Changed paths: M /pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/optimizeopt.py M /pypy/branch/loop-invariant-decorator/pypy/jit/metainterp/test/test_optimizeopt.py Called functions are ConstAddrs, use the address itself as keys. ------------------------------------------------------------------------ r70530 | cfbolz | 2010-01-12 15:00:29 +0100 (Tue, 12 Jan 2010) | 2 lines Changed paths: M /pypy/branch/loop-invariant-decorator/pypy/module/pypyjit/test/test_pypy_c.py Adapt the test to be fine with the threading stuff. ------------------------------------------------------------------------ Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Tue Jan 12 16:49:26 2010 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer -from pypy.rlib.jit import unroll_safe +from pypy.rlib import jit import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -531,6 +531,7 @@ def leave_cache_building_mode(self, val): "hook for the flow object space" + @jit.loop_invariant def getexecutioncontext(self): "Return what we consider to be the active execution context." # Important: the annotator must not see a prebuilt ExecutionContext: @@ -735,7 +736,7 @@ """ return self.unpackiterable(w_iterable, expected_length) - @unroll_safe + @jit.unroll_safe def exception_match(self, w_exc_type, w_check_class): """Checks if the given exception type matches 'w_check_class'.""" if self.is_w(w_exc_type, w_check_class): Modified: pypy/trunk/pypy/jit/backend/model.py ============================================================================== --- pypy/trunk/pypy/jit/backend/model.py (original) +++ pypy/trunk/pypy/jit/backend/model.py Tue Jan 12 16:49:26 2010 @@ -209,6 +209,9 @@ def do_call(self, args, calldescr): raise NotImplementedError + def do_call_loopinvariant(self, args, calldescr): + return self.do_call(args, calldescr) + def do_cond_call_gc_wb(self, args, calldescr): if args[0].getint() & args[1].getint(): self.do_call(args[2:], calldescr) Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/codewriter.py Tue Jan 12 16:49:26 2010 @@ -1235,9 +1235,11 @@ calldescr, non_void_args = self.codewriter.getcalldescr( op.args[0], args, op.result, consider_effects_of=op) pure = False + loopinvariant = False if op.opname == "direct_call": func = getattr(get_funcobj(op.args[0].value), '_callable', None) pure = getattr(func, "_pure_function_", False) + loopinvariant = getattr(func, "_jit_loop_invariant_", False) all_promoted_args = getattr(func, "_pure_function_with_all_promoted_args_", False) if pure and not all_promoted_args: @@ -1249,7 +1251,10 @@ except lltype.DelayedPointer: canraise = True # if we need to look into the delayed ptr that is # the portal, then it's certainly going to raise - if pure: + if loopinvariant: + self.emit("residual_call_loopinvariant") + assert not non_void_args, "arguments not supported for loop-invariant function!" + elif pure: # XXX check what to do about exceptions (also MemoryError?) self.emit('residual_call_pure') elif canraise: Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Tue Jan 12 16:49:26 2010 @@ -388,6 +388,7 @@ self.resumedata_memo = resume.ResumeDataLoopMemo(metainterp_sd) self.heap_op_optimizer = HeapOpOptimizer(self) self.bool_boxes = {} + self.loop_invariant_results = {} def forget_numberings(self, virtualbox): self.metainterp_sd.profiler.count(jitprof.OPT_FORCINGS) @@ -874,6 +875,23 @@ def optimize_DEBUG_MERGE_POINT(self, op): self.emit_operation(op) + def optimize_CALL_LOOPINVARIANT(self, op): + funcvalue = self.getvalue(op.args[0]) + if not funcvalue.is_constant(): + self.optimize_default(op) + return + resvalue = self.loop_invariant_results.get(op.args[0].getint(), None) + if resvalue is not None: + self.make_equal_to(op.result, resvalue) + return + # change the op to be a normal call, from the backend's point of view + # there is no reason to have a separate operation for this + op.opnum = rop.CALL + self.optimize_default(op) + resvalue = self.getvalue(op.result) + self.loop_invariant_results[op.args[0].getint()] = resvalue + + optimize_ops = _findall(Optimizer, 'optimize_') Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Tue Jan 12 16:49:26 2010 @@ -654,6 +654,10 @@ def opimpl_residual_call(self, calldescr, varargs): return self.do_residual_call(varargs, descr=calldescr, exc=True) + @arguments("descr", "varargs") + def opimpl_residual_call_loopinvariant(self, calldescr, varargs): + return self.execute_varargs(rop.CALL_LOOPINVARIANT, varargs, calldescr, exc=True) + @arguments("varargs") def opimpl_recursion_leave_prep(self, varargs): warmrunnerstate = self.metainterp.staticdata.state Modified: pypy/trunk/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/resoperation.py (original) +++ pypy/trunk/pypy/jit/metainterp/resoperation.py Tue Jan 12 16:49:26 2010 @@ -226,6 +226,7 @@ '_CANRAISE_FIRST', # ----- start of can_raise operations ----- 'CALL', 'CALL_MAY_FORCE', + 'CALL_LOOPINVARIANT', 'OOSEND', # ootype operation '_CANRAISE_LAST', # ----- end of can_raise operations ----- Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_basic.py Tue Jan 12 16:49:26 2010 @@ -1,7 +1,7 @@ import py import sys from pypy.rlib.jit import JitDriver, we_are_jitted, hint, dont_look_inside -from pypy.rlib.jit import OPTIMIZER_FULL, OPTIMIZER_SIMPLE +from pypy.rlib.jit import OPTIMIZER_FULL, OPTIMIZER_SIMPLE, loop_invariant from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats from pypy.jit.backend.llgraph import runner from pypy.jit.metainterp import support, codewriter, pyjitpl, history @@ -1221,6 +1221,34 @@ res = self.meta_interp(f, [21]) assert res == 42 self.check_loops(guard_nonnull=1, guard_isnull=1) + + def test_loop_invariant(self): + myjitdriver = JitDriver(greens = [], reds = ['x', 'res']) + class A(object): + pass + a = A() + a.current_a = A() + a.current_a.x = 1 + @loop_invariant + def f(): + return a.current_a + + def g(x): + res = 0 + while x > 0: + myjitdriver.can_enter_jit(x=x, res=res) + myjitdriver.jit_merge_point(x=x, res=res) + res += f().x + res += f().x + res += f().x + x -= 1 + a.current_a = A() + a.current_a.x = 2 + return res + res = self.meta_interp(g, [21]) + assert res == 3 * 21 + self.check_loops(call=1) + class TestOOtype(BasicTests, OOJitMixin): Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Tue Jan 12 16:49:26 2010 @@ -648,6 +648,32 @@ # ---------- + def test_call_loopinvariant(self): + ops = """ + [i1] + i2 = call_loopinvariant(1, i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + i3 = call_loopinvariant(1, i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + i4 = call_loopinvariant(1, i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + jump(i1) + """ + expected = """ + [i1] + i2 = call(1, i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + jump(i1) + """ + self.optimize_loop(ops, 'Not', expected) + + + # ---------- + def test_virtual_1(self): ops = """ [i, p0] Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Tue Jan 12 16:49:26 2010 @@ -172,7 +172,7 @@ x = x + (i&j) i = i + 1 return x - ''', 194, + ''', 220, ([2117], 1083876708)) def test_factorial(self): @@ -183,7 +183,7 @@ r *= n n -= 1 return r - ''', 26, + ''', 28, ([5], 120), ([20], 2432902008176640000L)) @@ -237,8 +237,11 @@ assert not ops[4] ops = self.get_by_bytecode("CALL_FUNCTION") assert len(ops) == 2 - for bytecode in ops: - assert not bytecode.get_opnames("call") + for i, bytecode in enumerate(ops): + if i == 0: + assert "call(getexecutioncontext)" in str(bytecode) + else: + assert not bytecode.get_opnames("call") assert not bytecode.get_opnames("new") assert len(bytecode.get_opnames("guard")) <= 10 @@ -268,8 +271,11 @@ ops = self.get_by_bytecode("CALL_METHOD") assert len(ops) == 2 - for bytecode in ops: - assert not bytecode.get_opnames("call") + for i, bytecode in enumerate(ops): + if i == 0: + assert "call(getexecutioncontext)" in str(bytecode) + else: + assert not bytecode.get_opnames("call") assert not bytecode.get_opnames("new") assert len(bytecode.get_opnames("guard")) <= 9 assert len(ops[1]) < len(ops[0]) @@ -296,8 +302,11 @@ ([31], 32)) ops = self.get_by_bytecode("CALL_FUNCTION") assert len(ops) == 2 - for bytecode in ops: - assert not bytecode.get_opnames("call") + for i, bytecode in enumerate(ops): + if i == 0: + assert "call(getexecutioncontext)" in str(bytecode) + else: + assert not bytecode.get_opnames("call") assert not bytecode.get_opnames("new") assert len(ops[0].get_opnames("guard")) <= 14 assert len(ops[1].get_opnames("guard")) <= 3 @@ -315,7 +324,7 @@ a.x = 2 i = i + a.x return i - ''', 65, + ''', 67, ([20], 20), ([31], 32)) @@ -346,7 +355,7 @@ while i < n: i = i + a.x return i - ''', 39, + ''', 41, ([20], 20), ([31], 32)) @@ -459,8 +468,6 @@ py.test.skip("pass --pypy!") if not has_info(option.pypy_c, 'translation.jit'): py.test.skip("must give a pypy-c with the jit enabled") - if has_info(option.pypy_c, 'translation.thread'): - py.test.skip("for now, must give a pypy-c-jit without threads") cls.tmpdir = udir.join('pypy-jit') cls.tmpdir.ensure(dir=1) cls.counter = 0 Modified: pypy/trunk/pypy/rlib/jit.py ============================================================================== --- pypy/trunk/pypy/rlib/jit.py (original) +++ pypy/trunk/pypy/rlib/jit.py Tue Jan 12 16:49:26 2010 @@ -20,6 +20,12 @@ func._jit_unroll_safe_ = True return func +def loop_invariant(func): + dont_look_inside(func) + func._jit_loop_invariant_ = True + return func + + def purefunction_promote(func): import inspect purefunction(func) From cfbolz at codespeak.net Tue Jan 12 16:50:18 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 12 Jan 2010 16:50:18 +0100 (CET) Subject: [pypy-svn] r70535 - pypy/trunk/pypy/module/pypyjit/test Message-ID: <20100112155018.3F03A168045@codespeak.net> Author: cfbolz Date: Tue Jan 12 16:50:17 2010 New Revision: 70535 Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: Due to differently aligned stars, this setfield appears now somewhere else. Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Tue Jan 12 16:50:17 2010 @@ -283,9 +283,7 @@ ops = self.get_by_bytecode("LOAD_ATTR") assert len(ops) == 2 assert ops[0].get_opnames() == ["getfield_gc", "getarrayitem_gc", - "setfield_gc", # (*) "guard_nonnull_class"] - # (*) delayed write of the frames depth assert not ops[1] # second LOAD_ATTR folded away def test_default_and_kw(self): From cfbolz at codespeak.net Tue Jan 12 16:50:58 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 12 Jan 2010 16:50:58 +0100 (CET) Subject: [pypy-svn] r70536 - pypy/branch/loop-invariant-decorator Message-ID: <20100112155058.380BB168045@codespeak.net> Author: cfbolz Date: Tue Jan 12 16:50:57 2010 New Revision: 70536 Removed: pypy/branch/loop-invariant-decorator/ Log: remove merged branch From pedronis at codespeak.net Tue Jan 12 16:58:34 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 12 Jan 2010 16:58:34 +0100 (CET) Subject: [pypy-svn] r70537 - pypy/trunk/pypy/rlib Message-ID: <20100112155834.B8224168048@codespeak.net> Author: pedronis Date: Tue Jan 12 16:58:34 2010 New Revision: 70537 Modified: pypy/trunk/pypy/rlib/jit.py Log: clarify comment for the new tracing world Modified: pypy/trunk/pypy/rlib/jit.py ============================================================================== --- pypy/trunk/pypy/rlib/jit.py (original) +++ pypy/trunk/pypy/rlib/jit.py Tue Jan 12 16:58:34 2010 @@ -87,8 +87,9 @@ def we_are_jitted(): + """ Considered as true during tracing and blackholing, + so its consquences are reflected into jitted code """ return False -# timeshifts to True _we_are_jitted = CDefinedIntSymbolic('0 /* we are not jitted here */', default=0) From pedronis at codespeak.net Tue Jan 12 17:09:41 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 12 Jan 2010 17:09:41 +0100 (CET) Subject: [pypy-svn] r70538 - pypy/branch/jit-profiling/pypy/interpreter Message-ID: <20100112160941.086D416804C@codespeak.net> Author: pedronis Date: Tue Jan 12 17:09:41 2010 New Revision: 70538 Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py Log: (fijal, pedronis) update comment Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py Tue Jan 12 17:09:41 2010 @@ -31,10 +31,9 @@ """An ExecutionContext holds the state of an execution thread in the Python interpreter.""" - # XXX JIT: when tracing (but not when blackholing!), the following - # XXX fields should be known to a constant None or False: - # XXX self.w_tracefunc, self.profilefunc - # XXX frame.is_being_profiled + # JIT: when tracing (but not when blackholing!), the following + # self.w_tracefunc should be a constant None + # frame.is_being_profiled should be False for virtual frames # bind it here, so tests can overwrite it _we_are_jitted = staticmethod(jit.we_are_jitted) From afa at codespeak.net Tue Jan 12 17:32:25 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 12 Jan 2010 17:32:25 +0100 (CET) Subject: [pypy-svn] r70539 - in pypy/branch/separate-compilation/pypy/translator: . c c/test Message-ID: <20100112163225.77416168048@codespeak.net> Author: afa Date: Tue Jan 12 17:32:24 2010 New Revision: 70539 Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py pypy/branch/separate-compilation/pypy/translator/exceptiontransform.py pypy/branch/separate-compilation/pypy/translator/separate.py Log: Finally found how to convert a SomeInstance(classdef=S) to a pointer to a GCStruct for the same class. Now a RPython instance can be passed (as reference) between compilation units. Still in-progress. Next step: move this code to another file. The hack in exceptiontransform.py is obscure; it seems that some dealloc function is attached to the GCstruct, together with its graph from the first annotation. Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/genc.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/genc.py Tue Jan 12 17:32:24 2010 @@ -358,11 +358,44 @@ for funcname, import_name in self.export_node_names.items(): functype = lltype.typeOf(self.entrypoint[funcname]) - setattr(mod, funcname, - rffi.llexternal( - import_name, functype.TO.ARGS, functype.TO.RESULT, - compilation_info=import_eci, - )) + from pypy.annotation import model + + imported_func = rffi.llexternal( + import_name, functype.TO.ARGS, functype.TO.RESULT, + compilation_info=import_eci, + ) + + if not functype.TO.ARGS: + func = imported_func + elif len(functype.TO.ARGS) == 1: + ARG = functype.TO.ARGS[0] + from pypy.rpython.lltypesystem import llmemory + from pypy.rpython.extregistry import ExtRegistryEntry + + if isinstance(ARG, lltype.Ptr): # XXX more precise check? + def convert(x): + raiseNameError + + class Entry(ExtRegistryEntry): + _about_ = convert + s_result_annotation = model.lltype_to_annotation(ARG) + + def specialize_call(self, hop): + # TODO: input type check + [v_instance] = hop.inputargs(*hop.args_r) + return hop.genop('force_cast', [v_instance], + resulttype = ARG) + else: + def convert(x): + return x + + def func(arg0): + ll_arg0 = convert(arg0) + ll_res = imported_func(ll_arg0) + return ll_res + else: + raise NotImplementedError("Not supported") + setattr(mod, funcname, func) return mod def gen_makefile(self, targetdir): Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Tue Jan 12 17:32:24 2010 @@ -7,6 +7,7 @@ from pypy.annotation import model, description import py import sys, os +import types class TestSeparation: def compile_function(self, func, argtypes): @@ -28,6 +29,21 @@ if hasattr(func, 'argtypes'): t.annotator.build_types(func, func.argtypes, complete_now=False) + # annotate classes + for funcname, cls in exports.items(): + if not isinstance(cls, (type, types.ClassType)): + continue + desc = bk.getdesc(cls) + classdef = desc.getuniqueclassdef() + s_init = desc.s_read_attribute('__init__') + if isinstance(s_init, model.SomeImpossibleValue): + continue + + argtypes = (model.SomeInstance(classdef),) + argtypes += tuple(cls.__init__.argtypes) + t.annotator.build_types(cls.__init__.im_func, argtypes, + complete_now=False) + t.annotator.complete() # ensure that functions without signature are not constant-folded for funcname, func in exports.items(): @@ -42,11 +58,6 @@ newargs.append(newarg) # and reflow t.annotator.build_types(func, newargs) - elif isinstance(desc, description.ClassDesc): - s_init = desc.s_read_attribute('__init__') - initfunc = s_init.const - newargs = [func, float] - t.annotator.build_types(initfunc, newargs) t.buildrtyper().specialize() @@ -127,7 +138,7 @@ def test_pass_structure(self): class S: - @export + @export(float) def __init__(self, x): self.x = x @@ -138,10 +149,19 @@ firstmodule = self.compile_separated("first", f=f, S=S) # call it from a function compiled in another module - def fn(): + @export() + def g(): s = S(41.0) return firstmodule.f(s) + secondmodule = self.compile_separated("second", g=g) - #assert fn() == 42.5 + def fn(): + return secondmodule.g() + + if sys.platform == 'win32': + filepath = os.path.dirname(firstmodule.__file__) + os.environ['PATH'] = "%s;%s" % (filepath, os.environ['PATH']) + + assert fn() == 42.5 c_fn = self.compile_function(fn, []) assert c_fn() == 42.5 Modified: pypy/branch/separate-compilation/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/exceptiontransform.py (original) +++ pypy/branch/separate-compilation/pypy/translator/exceptiontransform.py Tue Jan 12 17:32:24 2010 @@ -173,11 +173,10 @@ Because of the added exitswitch we need an additional block. """ if hasattr(graph, 'exceptiontransformed'): - assert self.same_obj(self.exc_data_ptr, graph.exceptiontransformed) - return - else: - self.raise_analyzer.analyze_direct_call(graph) - graph.exceptiontransformed = self.exc_data_ptr + if self.same_obj(self.exc_data_ptr, graph.exceptiontransformed): + return + self.raise_analyzer.analyze_direct_call(graph) + graph.exceptiontransformed = self.exc_data_ptr self.always_exc_clear = always_exc_clear join_blocks(graph) Modified: pypy/branch/separate-compilation/pypy/translator/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/separate.py Tue Jan 12 17:32:24 2010 @@ -22,7 +22,7 @@ decorated = export()(func) del decorated.argtypes return decorated - return object.__new__(cls, *args, **kwds) + return object.__new__(cls) def __init__(self, *args, **kwds): self.argtypes = args From cfbolz at codespeak.net Tue Jan 12 18:30:25 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 12 Jan 2010 18:30:25 +0100 (CET) Subject: [pypy-svn] r70540 - pypy/extradoc/planning Message-ID: <20100112173025.DDED416804C@codespeak.net> Author: cfbolz Date: Tue Jan 12 18:30:25 2010 New Revision: 70540 Modified: pypy/extradoc/planning/jit.txt Log: Two things that are done. Add a line about the expensiveness of checking for the presence of tracing/profiling. Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Tue Jan 12 18:30:25 2010 @@ -54,12 +54,9 @@ - improve on predictability: don't trace into signals ... but produce just a conditional call (or just abort the trace) - directly call assembler for residual portal calls -- since threads are enabled with the JIT, getexecutioncontext cannot be folded - by the JIT anymore. we need to do something in that direction +- the checks that look whether profiling/tracing in the Python interpreter is + enabled look expensive. Do we want to do something about them? -known bugs: -- the trace-hook is not correctly called while blackholing, see - test_pyframe.py:AppTestJitTraceInteraction From afa at codespeak.net Tue Jan 12 18:37:35 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 12 Jan 2010 18:37:35 +0100 (CET) Subject: [pypy-svn] r70541 - in pypy/branch/separate-compilation/pypy/translator: . c Message-ID: <20100112173735.A474116804C@codespeak.net> Author: afa Date: Tue Jan 12 18:37:35 2010 New Revision: 70541 Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py pypy/branch/separate-compilation/pypy/translator/separate.py Log: It's probably not the best place, but at least move the code out of genc.py. Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/genc.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/genc.py Tue Jan 12 18:37:35 2010 @@ -7,7 +7,7 @@ from pypy.translator.llsupport.wrapper import new_wrapper from pypy.translator.gensupp import uniquemodulename, NameManager from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.rpython.lltypesystem import lltype, rffi +from pypy.rpython.lltypesystem import lltype from pypy.tool.udir import udir from pypy.tool import isolate from pypy.translator.c.support import log, c_string_constant @@ -356,45 +356,10 @@ post_include_bits = forwards ) + from pypy.translator.separate import make_ll_import_function for funcname, import_name in self.export_node_names.items(): functype = lltype.typeOf(self.entrypoint[funcname]) - from pypy.annotation import model - - imported_func = rffi.llexternal( - import_name, functype.TO.ARGS, functype.TO.RESULT, - compilation_info=import_eci, - ) - - if not functype.TO.ARGS: - func = imported_func - elif len(functype.TO.ARGS) == 1: - ARG = functype.TO.ARGS[0] - from pypy.rpython.lltypesystem import llmemory - from pypy.rpython.extregistry import ExtRegistryEntry - - if isinstance(ARG, lltype.Ptr): # XXX more precise check? - def convert(x): - raiseNameError - - class Entry(ExtRegistryEntry): - _about_ = convert - s_result_annotation = model.lltype_to_annotation(ARG) - - def specialize_call(self, hop): - # TODO: input type check - [v_instance] = hop.inputargs(*hop.args_r) - return hop.genop('force_cast', [v_instance], - resulttype = ARG) - else: - def convert(x): - return x - - def func(arg0): - ll_arg0 = convert(arg0) - ll_res = imported_func(ll_arg0) - return ll_res - else: - raise NotImplementedError("Not supported") + func = make_ll_import_function(import_name, functype, import_eci) setattr(mod, funcname, func) return mod Modified: pypy/branch/separate-compilation/pypy/translator/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/separate.py Tue Jan 12 18:37:35 2010 @@ -42,3 +42,44 @@ return (isinstance(obj, (types.FunctionType, types.UnboundMethodType)) and getattr(obj, 'exported', False)) +def make_ll_import_function(name, functype, eci): + from pypy.rpython.lltypesystem import lltype, rffi + from pypy.annotation import model + + imported_func = rffi.llexternal( + name, functype.TO.ARGS, functype.TO.RESULT, + compilation_info=eci, + ) + + if not functype.TO.ARGS: + func = imported_func + elif len(functype.TO.ARGS) == 1: + ARG = functype.TO.ARGS[0] + from pypy.rpython.lltypesystem import llmemory + from pypy.rpython.extregistry import ExtRegistryEntry + + if isinstance(ARG, lltype.Ptr): # XXX more precise check? + def convert(x): + raiseNameError + + class Entry(ExtRegistryEntry): + _about_ = convert + s_result_annotation = model.lltype_to_annotation(ARG) + + def specialize_call(self, hop): + # TODO: input type check + [v_instance] = hop.inputargs(*hop.args_r) + return hop.genop('force_cast', [v_instance], + resulttype = ARG) + else: + def convert(x): + return x + + def func(arg0): + ll_arg0 = convert(arg0) + ll_res = imported_func(ll_arg0) + return ll_res + else: + raise NotImplementedError("Not supported") + return func + From cfbolz at codespeak.net Tue Jan 12 18:57:21 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 12 Jan 2010 18:57:21 +0100 (CET) Subject: [pypy-svn] r70542 - in pypy/trunk/pypy/module/__builtin__: . test Message-ID: <20100112175721.904AF16804E@codespeak.net> Author: cfbolz Date: Tue Jan 12 18:57:20 2010 New Revision: 70542 Modified: pypy/trunk/pypy/module/__builtin__/descriptor.py pypy/trunk/pypy/module/__builtin__/test/test_descriptor.py Log: issue492 testing be a bit less crazy in property.__setattr__: prevent only the writing of the attributes the property object has, to make it possible to sanely subclass property. Modified: pypy/trunk/pypy/module/__builtin__/descriptor.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/descriptor.py (original) +++ pypy/trunk/pypy/module/__builtin__/descriptor.py Tue Jan 12 18:57:20 2010 @@ -4,7 +4,7 @@ Arguments from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError -from pypy.objspace.descroperation import object_getattribute +from pypy.objspace.descroperation import object_getattribute, object_setattr from pypy.interpreter.function import StaticMethod, ClassMethod from pypy.interpreter.typedef import GetSetProperty, descr_get_dict, \ descr_set_dict, interp_attrproperty_w @@ -153,8 +153,11 @@ # XXX kill me? This is mostly to make tests happy, raising # a TypeError instead of an AttributeError and using "readonly" # instead of "read-only" in the error message :-/ - raise OperationError(space.w_TypeError, space.wrap( - "Trying to set readonly attribute %s on property" % (attr,))) + if attr in ["__doc__", "fget", "fset", "fdel"]: + raise OperationError(space.w_TypeError, space.wrap( + "Trying to set readonly attribute %s on property" % (attr,))) + return space.call_function(object_setattr(space), + space.wrap(self), space.wrap(attr), w_value) setattr.unwrap_spec = ['self', ObjSpace, str, W_Root] W_Property.typedef = TypeDef( Modified: pypy/trunk/pypy/module/__builtin__/test/test_descriptor.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/test/test_descriptor.py (original) +++ pypy/trunk/pypy/module/__builtin__/test/test_descriptor.py Tue Jan 12 18:57:20 2010 @@ -301,3 +301,13 @@ pass else: raise Exception, "expected ZeroDivisionError from bad property" + + def test_property_subclass(self): + class P(property): + pass + + p = P() + p.name = 0 + assert p.name == 0 + + From arigo at codespeak.net Tue Jan 12 19:02:21 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 12 Jan 2010 19:02:21 +0100 (CET) Subject: [pypy-svn] r70543 - in pypy/branch/c-traceback/pypy: rpython/lltypesystem translator translator/c translator/c/src translator/c/test Message-ID: <20100112180221.ED7F5168048@codespeak.net> Author: arigo Date: Tue Jan 12 19:02:21 2010 New Revision: 70543 Added: pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h (contents, props changed) Modified: pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py pypy/branch/c-traceback/pypy/translator/c/funcgen.py pypy/branch/c-traceback/pypy/translator/c/genc.py pypy/branch/c-traceback/pypy/translator/c/src/g_include.h pypy/branch/c-traceback/pypy/translator/c/src/main.h pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py pypy/branch/c-traceback/pypy/translator/exceptiontransform.py Log: Pass the first 2 tests. Modified: pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py Tue Jan 12 19:02:21 2010 @@ -87,6 +87,7 @@ def is_pure(self, args_v): return (self.canfold or # canfold => pure operation self is llop.debug_assert or # debug_assert is pure enough + self is llop.debug_assert_with_tb or # reading from immutable (self in (llop.getfield, llop.getarrayitem) and args_v[0].concretetype.TO._hints.get('immutable')) or @@ -536,6 +537,8 @@ 'debug_fatalerror': LLOp(), 'debug_llinterpcall': LLOp(), # Python func call 'res=arg[0](*arg[1:])' # in backends, abort() or whatever is fine + 'debug_start_traceback':LLOp(), + 'debug_catch_exception':LLOp(), # __________ instrumentation _________ 'instrument_count': LLOp(), Modified: pypy/branch/c-traceback/pypy/translator/c/funcgen.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/funcgen.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/funcgen.py Tue Jan 12 19:02:21 2010 @@ -817,5 +817,19 @@ self.expr(op.args[1]), self.expr(op.args[2])) + def OP_DEBUG_RECORD_TRACEBACK(self, op): + if self.functionname is None: + return '/* debug_record_traceback skipped: no functionname */' + return 'PYPY_DEBUG_RECORD_TRACEBACK("%s");' % self.functionname + + def OP_DEBUG_CATCH_EXCEPTION(self, op): + gottype = self.expr(op.args[0]) + exprs = [] + for c_limited_type in op.args[1:]: + exprs.append('%s == %s' % (gottype, self.expr(c_limited_type))) + return (self.OP_DEBUG_RECORD_TRACEBACK(None) + + ' if (%s) { pypy_debug_catch_exception(); }' % ( + ' || '.join(exprs),)) + assert not USESLOTS or '__dict__' not in dir(FunctionCodeGenerator) Modified: pypy/branch/c-traceback/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/genc.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/genc.py Tue Jan 12 19:02:21 2010 @@ -715,6 +715,7 @@ print >> fc, '/*** Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' + print >> fc, '#define PYPY_FILE_NAME "%s"' % name print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' @@ -787,6 +788,7 @@ print >> f, '/***********************************************************/' print >> f, '/*** Implementations ***/' print >> f + print >> f, '#define PYPY_FILE_NAME "%s"' % os.path.basename(f.name) for line in preimplementationlines: print >> f, line print >> f, '#include "src/g_include.h"' Added: pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h ============================================================================== --- (empty file) +++ pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h Tue Jan 12 19:02:21 2010 @@ -0,0 +1,66 @@ +/**************************************************************/ + /*** C header subsection: RPython tracebacks for debugging ***/ + + +#define PYPY_DEBUG_TRACEBACK_DEPTH 8 + +#define OP_DEBUG_START_TRACEBACK() \ + pypy_debug_traceback_count = PYPY_DEBUG_TRACEBACK_DEPTH + +#define PYPY_DEBUG_RECORD_TRACEBACK(funcname) \ + if ((--pypy_debug_traceback_count) >= 0) { \ + static struct pydtentry_s entry = { PYPY_FILE_NAME, funcname, __LINE__ }; \ + pypy_debug_tracebacks[pypy_debug_traceback_count] = &entry; \ + } + +/* Format of the data: to represent a location in the source code, we + use for now just a pointer to a 'pypy_debug_traceback_entry_s'. +*/ +struct pydtentry_s { + const char *filename; + const char *funcname; + int lineno; +}; + +extern int pypy_debug_traceback_count; +extern struct pydtentry_s *pypy_debug_tracebacks[PYPY_DEBUG_TRACEBACK_DEPTH]; + +void pypy_debug_catch_exception(void); + + +/************************************************************/ + + +#ifndef PYPY_NOT_MAIN_FILE + +int pypy_debug_traceback_count = PYPY_DEBUG_TRACEBACK_DEPTH; +struct pydtentry_s *pypy_debug_tracebacks[PYPY_DEBUG_TRACEBACK_DEPTH]; + +void pypy_debug_traceback_print(void) +{ + int i, lineno; + const char *filename; + const char *funcname; + + fprintf(stderr, "RPython traceback:\n"); + for (i=PYPY_DEBUG_TRACEBACK_DEPTH-1; i>=0; i--) + { + if (i < pypy_debug_traceback_count) + break; + filename = pypy_debug_tracebacks[i]->filename; + funcname = pypy_debug_tracebacks[i]->funcname; + lineno = pypy_debug_tracebacks[i]->lineno; + fprintf(stderr, " File \"%s\", line %d, in %s\n", + filename, lineno, funcname); + } +} + +void pypy_debug_catch_exception(void) +{ + pypy_debug_traceback_print(); + fprintf(stderr, "Fatal RPython error: %s\n", + RPyFetchExceptionType()->ov_name->items); + abort(); +} + +#endif /* PYPY_NOT_MAIN_FILE */ Modified: pypy/branch/c-traceback/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/src/g_include.h (original) +++ pypy/branch/c-traceback/pypy/translator/c/src/g_include.h Tue Jan 12 19:02:21 2010 @@ -52,6 +52,7 @@ #ifdef HAVE_RTYPER /* only if we have an RTyper */ # include "src/rtyper.h" # include "src/debug_print.h" +# include "src/debug_traceback.h" #ifndef AVR # include "src/ll_os.h" # include "src/ll_strtod.h" Modified: pypy/branch/c-traceback/pypy/translator/c/src/main.h ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/src/main.h (original) +++ pypy/branch/c-traceback/pypy/translator/c/src/main.h Tue Jan 12 19:02:21 2010 @@ -37,11 +37,7 @@ exitcode = STANDALONE_ENTRY_POINT(list); if (RPyExceptionOccurred()) { /* fish for the exception type, at least */ -#ifndef AVR - fprintf(stderr, "Fatal RPython error: %s\n", - RPyFetchExceptionType()->ov_name->items); -#endif - abort(); + pypy_debug_catch_exception(); } return exitcode; Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Tue Jan 12 19:02:21 2010 @@ -396,8 +396,8 @@ assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in g', l1) - assert re.match(r' File "\w+.c", line \d+, in entry_point', l2) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l1) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l2) # out2, err2 = cbuilder.cmdexec("x", expect_crash=True) assert out2.strip() == '' @@ -405,10 +405,10 @@ assert lines2[-1] == 'Fatal RPython error: KeyError' l0, l1, l2 = lines2[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in g', l1) - assert re.match(r' File "\w+.c", line \d+, in entry_point', l2) - assert lines2[-3] != lines[-3] - assert lines2[-2] == lines[-2] + assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l1) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l2) + assert lines2[-3] != lines[-3] # different line number + assert lines2[-2] == lines[-2] # same line number def test_assertion_error(self): def g(x): @@ -429,8 +429,8 @@ assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in g', l1) - assert re.match(r' File "\w+.c", line \d+, in f', l2) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l1) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_f', l2) # The traceback stops at f() because it's the first function that # captures the AssertionError, which makes the program abort. Modified: pypy/branch/c-traceback/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/exceptiontransform.py (original) +++ pypy/branch/c-traceback/pypy/translator/exceptiontransform.py Tue Jan 12 19:02:21 2010 @@ -16,6 +16,7 @@ from pypy.rlib.debug import ll_assert from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator +from pypy.tool.sourcetools import func_with_new_name PrimitiveErrorValue = {lltype.Signed: -1, lltype.Unsigned: r_uint(-1), @@ -45,6 +46,9 @@ def error_constant(T): return Constant(error_value(T), T) +def constant_value(llvalue): + return Constant(llvalue, lltype.typeOf(llvalue)) + class BaseExceptionTransformer(object): def __init__(self, translator): @@ -64,6 +68,10 @@ (n_i_error_ll_exc_type, n_i_error_ll_exc) = self.get_builtin_exception(NotImplementedError) + self.c_assertion_error_ll_exc_type = constant_value( + assertion_error_ll_exc_type) + self.c_n_i_error_ll_exc_type = constant_value(n_i_error_ll_exc_type) + def rpyexc_occured(): exc_type = exc_data.exc_type return bool(exc_type) @@ -82,6 +90,7 @@ # assert(!RPyExceptionOccurred()); exc_data.exc_type = etype exc_data.exc_value = evalue + lloperation.llop.debug_start_traceback(lltype.Void) def rpyexc_fetch_exception(): evalue = rpyexc_fetch_value() @@ -90,7 +99,8 @@ def rpyexc_restore_exception(evalue): if evalue: - rpyexc_raise(rclass.ll_inst_type(evalue), evalue) + exc_data.exc_type = rclass.ll_inst_type(evalue) + exc_data.exc_value = evalue def rpyexc_raise_runtime_error(): rpyexc_raise(runtime_error_ll_exc_type, runtime_error_ll_exc) @@ -117,14 +127,14 @@ self.rpyexc_raise_ptr = self.build_func( "RPyRaiseException", - rpyexc_raise, + self.noinline(rpyexc_raise), [self.lltype_of_exception_type, self.lltype_of_exception_value], lltype.Void, jitcallkind='rpyexc_raise') # for the JIT self.rpyexc_raise_runtime_error_ptr = self.build_func( "RPyRaiseRuntimeError", - rpyexc_raise_runtime_error, + self.noinline(rpyexc_raise_runtime_error), [], lltype.Void) self.rpyexc_fetch_exception_ptr = self.build_func( @@ -134,7 +144,7 @@ self.rpyexc_restore_exception_ptr = self.build_func( "RPyRestoreException", - rpyexc_restore_exception, + self.noinline(rpyexc_restore_exception), [self.lltype_of_exception_value], lltype.Void) self.build_extra_funcs() @@ -142,6 +152,11 @@ self.mixlevelannotator.finish() self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping() + def noinline(self, fn): + fn = func_with_new_name(fn, fn.__name__ + '_noinline') + fn._dont_inline_ = True + return fn + def build_func(self, name, fn, inputtypes, rettype, **kwds): l2a = annmodel.lltype_to_annotation graph = self.mixlevelannotator.getgraph(fn, map(l2a, inputtypes), l2a(rettype)) @@ -185,10 +200,10 @@ for block in list(graph.iterblocks()): self.replace_stack_unwind(block) self.replace_fetch_restore_operations(block) + self.transform_jump_to_except_block(graph, block.exits) need_exc_matching, gen_exc_checks = self.transform_block(graph, block) n_need_exc_matching_blocks += need_exc_matching n_gen_exc_checks += gen_exc_checks - self.transform_except_block(graph, graph.exceptblock) cleanup_graph(graph) removenoops.remove_superfluous_keep_alive(graph) return n_need_exc_matching_blocks, n_gen_exc_checks @@ -266,19 +281,23 @@ self.insert_matching(lastblock, graph) return need_exc_matching, n_gen_exc_checks - def transform_except_block(self, graph, block): - # attach an except block -- let's hope that nobody uses it - graph.exceptblock = Block([Variable('etype'), # exception class - Variable('evalue')]) # exception value - graph.exceptblock.operations = () - graph.exceptblock.closeblock() - - result = Variable() - result.concretetype = lltype.Void - block.operations = [SpaceOperation( - "direct_call", [self.rpyexc_raise_ptr] + block.inputargs, result)] - l = Link([error_constant(graph.returnblock.inputargs[0].concretetype)], graph.returnblock) - block.recloseblock(l) + def transform_jump_to_except_block(self, graph, exits): + for link in exits: + if link.target is graph.exceptblock: + result = Variable() + result.concretetype = lltype.Void + block = Block([copyvar(None, v) + for v in graph.exceptblock.inputargs]) + block.operations = [ + SpaceOperation("direct_call", + [self.rpyexc_raise_ptr] + block.inputargs, + result), + SpaceOperation('debug_record_traceback', [], + varoftype(lltype.Void))] + link.target = block + RETTYPE = graph.returnblock.inputargs[0].concretetype + l = Link([error_constant(RETTYPE)], graph.returnblock) + block.recloseblock(l) def insert_matching(self, block, graph): proxygraph, op = self.create_proxy_graph(block.operations[-1]) @@ -326,6 +345,11 @@ llops = rtyper.LowLevelOpList(None) var_value = self.gen_getfield('exc_value', llops) var_type = self.gen_getfield('exc_type' , llops) + # + c_check1 = self.c_assertion_error_ll_exc_type + c_check2 = self.c_n_i_error_ll_exc_type + llops.genop('debug_catch_exception', [var_type, c_check1, c_check2]) + # self.gen_setfield('exc_value', self.c_null_evalue, llops) self.gen_setfield('exc_type', self.c_null_etype, llops) excblock.operations[:] = llops @@ -359,7 +383,12 @@ block.exitswitch = var_no_exc #exception occurred case + b = Block([]) + b.operations = [SpaceOperation('debug_record_traceback', [], + varoftype(lltype.Void))] l = Link([error_constant(returnblock.inputargs[0].concretetype)], returnblock) + b.closeblock(l) + l = Link([], b) l.exitcase = l.llexitcase = False #non-exception case From arigo at codespeak.net Tue Jan 12 19:07:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 12 Jan 2010 19:07:10 +0100 (CET) Subject: [pypy-svn] r70544 - pypy/branch/c-traceback/pypy/rpython/lltypesystem Message-ID: <20100112180710.CC6E016804E@codespeak.net> Author: arigo Date: Tue Jan 12 19:07:09 2010 New Revision: 70544 Modified: pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py Log: Oups. Modified: pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py Tue Jan 12 19:07:09 2010 @@ -87,7 +87,6 @@ def is_pure(self, args_v): return (self.canfold or # canfold => pure operation self is llop.debug_assert or # debug_assert is pure enough - self is llop.debug_assert_with_tb or # reading from immutable (self in (llop.getfield, llop.getarrayitem) and args_v[0].concretetype.TO._hints.get('immutable')) or From arigo at codespeak.net Tue Jan 12 19:10:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 12 Jan 2010 19:10:17 +0100 (CET) Subject: [pypy-svn] r70545 - in pypy/branch/c-traceback/pypy: rpython/lltypesystem translator translator/c/test translator/cli translator/jvm Message-ID: <20100112181017.B2982168071@codespeak.net> Author: arigo Date: Tue Jan 12 19:10:16 2010 New Revision: 70545 Modified: pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py pypy/branch/c-traceback/pypy/translator/cli/opcodes.py pypy/branch/c-traceback/pypy/translator/exceptiontransform.py pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py Log: Tweaks. Modified: pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py Tue Jan 12 19:10:16 2010 @@ -537,6 +537,7 @@ 'debug_llinterpcall': LLOp(), # Python func call 'res=arg[0](*arg[1:])' # in backends, abort() or whatever is fine 'debug_start_traceback':LLOp(), + 'debug_record_traceback':LLOp(), 'debug_catch_exception':LLOp(), # __________ instrumentation _________ Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Tue Jan 12 19:10:16 2010 @@ -435,6 +435,7 @@ # captures the AssertionError, which makes the program abort. def test_ll_assert_error(self): + py.test.skip("implement later, maybe: tracebacks even with ll_assert") def g(x): ll_assert(x != 1, "foobar") def f(argv): Modified: pypy/branch/c-traceback/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/cli/opcodes.py (original) +++ pypy/branch/c-traceback/pypy/translator/cli/opcodes.py Tue Jan 12 19:10:16 2010 @@ -77,6 +77,9 @@ 'gc_set_max_heap_size': Ignore, 'resume_point': Ignore, 'debug_assert': Ignore, + 'debug_start_traceback': Ignore, + 'debug_record_traceback': Ignore, + 'debug_catch_exception': Ignore, 'debug_print': [DebugPrint], 'debug_start': [PushAllArgs, 'call void [pypylib]pypy.runtime.DebugPrint::DEBUG_START(string)'], 'debug_stop': [PushAllArgs, 'call void [pypylib]pypy.runtime.DebugPrint::DEBUG_STOP(string)'], Modified: pypy/branch/c-traceback/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/exceptiontransform.py (original) +++ pypy/branch/c-traceback/pypy/translator/exceptiontransform.py Tue Jan 12 19:10:16 2010 @@ -153,7 +153,7 @@ self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping() def noinline(self, fn): - fn = func_with_new_name(fn, fn.__name__ + '_noinline') + fn = func_with_new_name(fn, fn.__name__) fn._dont_inline_ = True return fn Modified: pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py (original) +++ pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py Tue Jan 12 19:10:16 2010 @@ -101,6 +101,9 @@ 'jit_force_virtual': DoNothing, 'debug_assert': [], # TODO: implement? + 'debug_start_traceback': Ignore, + 'debug_record_traceback': Ignore, + 'debug_catch_exception': Ignore, # __________ numeric operations __________ From arigo at codespeak.net Tue Jan 12 20:03:05 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 12 Jan 2010 20:03:05 +0100 (CET) Subject: [pypy-svn] r70546 - in pypy/branch/c-traceback/pypy/translator/c: src test Message-ID: <20100112190305.A8F46168071@codespeak.net> Author: arigo Date: Tue Jan 12 20:03:03 2010 New Revision: 70546 Modified: pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Log: Oups. The traceback was in reverse order (when compared with standard Python tracebacks). Modified: pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h (original) +++ pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h Tue Jan 12 20:03:03 2010 @@ -43,10 +43,10 @@ const char *funcname; fprintf(stderr, "RPython traceback:\n"); - for (i=PYPY_DEBUG_TRACEBACK_DEPTH-1; i>=0; i--) + for (i = 0; i < PYPY_DEBUG_TRACEBACK_DEPTH; i++) { if (i < pypy_debug_traceback_count) - break; + continue; filename = pypy_debug_tracebacks[i]->filename; funcname = pypy_debug_tracebacks[i]->funcname; lineno = pypy_debug_tracebacks[i]->lineno; Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Tue Jan 12 20:03:03 2010 @@ -396,8 +396,8 @@ assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l1) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l2) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l2) # out2, err2 = cbuilder.cmdexec("x", expect_crash=True) assert out2.strip() == '' @@ -405,10 +405,10 @@ assert lines2[-1] == 'Fatal RPython error: KeyError' l0, l1, l2 = lines2[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l1) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l2) - assert lines2[-3] != lines[-3] # different line number - assert lines2[-2] == lines[-2] # same line number + assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l2) + assert lines2[-2] != lines[-2] # different line number + assert lines2[-3] == lines[-3] # same line number def test_assertion_error(self): def g(x): @@ -429,8 +429,8 @@ assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l1) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_f', l2) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_f', l1) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l2) # The traceback stops at f() because it's the first function that # captures the AssertionError, which makes the program abort. @@ -454,8 +454,8 @@ assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in g', l1) - assert re.match(r' File "\w+.c", line \d+, in f', l2) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_f', l1) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l2) # The traceback stops at f() because it's the first function that # captures the AssertionError, which makes the program abort. From antocuni at codespeak.net Tue Jan 12 21:57:13 2010 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 12 Jan 2010 21:57:13 +0100 (CET) Subject: [pypy-svn] r70547 - in pypy/branch/cli-jit/pypy/translator: cli oosupport/test_template Message-ID: <20100112205713.E092E168077@codespeak.net> Author: antocuni Date: Tue Jan 12 21:57:12 2010 New Revision: 70547 Modified: pypy/branch/cli-jit/pypy/translator/cli/opcodes.py pypy/branch/cli-jit/pypy/translator/oosupport/test_template/operations.py Log: what is not tested is broken...: test&fix for llong_lshift Modified: pypy/branch/cli-jit/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/branch/cli-jit/pypy/translator/cli/opcodes.py (original) +++ pypy/branch/cli-jit/pypy/translator/cli/opcodes.py Tue Jan 12 21:57:12 2010 @@ -242,7 +242,7 @@ 'llong_ge': _not('clt'), 'llong_and': 'and', 'llong_or': 'or', - 'llong_lshift': 'shl', + 'llong_lshift': [PushAllArgs, 'conv.i4', 'shl'], 'llong_rshift': [PushAllArgs, 'conv.i4', 'shr'], 'llong_xor': 'xor', Modified: pypy/branch/cli-jit/pypy/translator/oosupport/test_template/operations.py ============================================================================== --- pypy/branch/cli-jit/pypy/translator/oosupport/test_template/operations.py (original) +++ pypy/branch/cli-jit/pypy/translator/oosupport/test_template/operations.py Tue Jan 12 21:57:12 2010 @@ -118,6 +118,11 @@ return x >> y assert self.interpret(fn, [r_longlong(32), 1]) == 16 + def test_lshift(self): + def fn(x, y): + return x << y + assert self.interpret(fn, [r_longlong(32), 1]) == 64 + def test_uint_neg(self): def fn(x): return -x From afa at codespeak.net Tue Jan 12 23:41:37 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 12 Jan 2010 23:41:37 +0100 (CET) Subject: [pypy-svn] r70548 - in pypy/branch/separate-compilation/pypy/translator: . c/test Message-ID: <20100112224137.8BA32168075@codespeak.net> Author: afa Date: Tue Jan 12 23:41:36 2010 New Revision: 70548 Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py pypy/branch/separate-compilation/pypy/translator/separate.py Log: Handle exported functions with more than one argument... Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Tue Jan 12 23:41:36 2010 @@ -143,16 +143,17 @@ self.x = x # function exported from the 'first' module - @export(S) - def f(s): - return s.x + 1.5 + @export(S, S, int) + def f(s, t, v): + return s.x + t.x + v firstmodule = self.compile_separated("first", f=f, S=S) # call it from a function compiled in another module @export() def g(): s = S(41.0) - return firstmodule.f(s) + t = S(25.5) + return firstmodule.f(s, t, 7) secondmodule = self.compile_separated("second", g=g) def fn(): @@ -162,6 +163,6 @@ filepath = os.path.dirname(firstmodule.__file__) os.environ['PATH'] = "%s;%s" % (filepath, os.environ['PATH']) - assert fn() == 42.5 + assert fn() == 73.5 c_fn = self.compile_function(fn, []) - assert c_fn() == 42.5 + assert c_fn() == 73.5 Modified: pypy/branch/separate-compilation/pypy/translator/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/separate.py Tue Jan 12 23:41:36 2010 @@ -1,3 +1,6 @@ +from pypy.tool.sourcetools import func_with_new_name +from pypy.rlib.unroll import unrolling_iterable +from pypy.rpython.extregistry import ExtRegistryEntry import types class export(object): @@ -42,44 +45,46 @@ return (isinstance(obj, (types.FunctionType, types.UnboundMethodType)) and getattr(obj, 'exported', False)) +def make_ll_import_arg_converter(TARGET): + from pypy.annotation import model + + def convert(x): + XXX + + class Entry(ExtRegistryEntry): + _about_ = convert + s_result_annotation = model.lltype_to_annotation(TARGET) + + def specialize_call(self, hop): + # TODO: input type check + [v_instance] = hop.inputargs(*hop.args_r) + return hop.genop('force_cast', [v_instance], + resulttype=TARGET) + + return convert +make_ll_import_arg_converter._annspecialcase_ = 'specialize:memo' + def make_ll_import_function(name, functype, eci): from pypy.rpython.lltypesystem import lltype, rffi - from pypy.annotation import model imported_func = rffi.llexternal( name, functype.TO.ARGS, functype.TO.RESULT, compilation_info=eci, ) - if not functype.TO.ARGS: - func = imported_func - elif len(functype.TO.ARGS) == 1: - ARG = functype.TO.ARGS[0] - from pypy.rpython.lltypesystem import llmemory - from pypy.rpython.extregistry import ExtRegistryEntry - - if isinstance(ARG, lltype.Ptr): # XXX more precise check? - def convert(x): - raiseNameError - - class Entry(ExtRegistryEntry): - _about_ = convert - s_result_annotation = model.lltype_to_annotation(ARG) - - def specialize_call(self, hop): - # TODO: input type check - [v_instance] = hop.inputargs(*hop.args_r) - return hop.genop('force_cast', [v_instance], - resulttype = ARG) - else: - def convert(x): - return x - - def func(arg0): - ll_arg0 = convert(arg0) - ll_res = imported_func(ll_arg0) - return ll_res - else: - raise NotImplementedError("Not supported") - return func + ARGS = functype.TO.ARGS + unrolling_ARGS = unrolling_iterable(enumerate(ARGS)) + def wrapper(*args): + real_args = () + for i, TARGET in unrolling_ARGS: + arg = args[i] + if isinstance(TARGET, lltype.Ptr): # XXX more precise check? + arg = make_ll_import_arg_converter(TARGET)(arg) + + real_args = real_args + (arg,) + res = imported_func(*real_args) + return res + wrapper._annspecialcase_ = 'specialize:ll' + wrapper._always_inline_ = True + return func_with_new_name(wrapper, name) From afa at codespeak.net Wed Jan 13 11:48:39 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 13 Jan 2010 11:48:39 +0100 (CET) Subject: [pypy-svn] r70552 - in pypy/branch/separate-compilation/pypy/translator: . c c/test Message-ID: <20100113104839.948B3168041@codespeak.net> Author: afa Date: Wed Jan 13 11:48:38 2010 New Revision: 70552 Added: pypy/branch/separate-compilation/pypy/translator/c/separate.py Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py pypy/branch/separate-compilation/pypy/translator/separate.py Log: Move code to a more proper place. Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/genc.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/genc.py Wed Jan 13 11:48:38 2010 @@ -339,30 +339,6 @@ ) self._compiled = True - def make_import_module(self): - class Module: - pass - mod = Module() - mod.__file__ = self.so_name - - forwards = [] - node_names = self.export_node_names.values() - for node in self.db.globalcontainers(): - if node.nodekind == 'func' and node.name in node_names: - forwards.append('\n'.join(node.forward_declaration())) - - import_eci = ExternalCompilationInfo( - libraries = [self.so_name], - post_include_bits = forwards - ) - - from pypy.translator.separate import make_ll_import_function - for funcname, import_name in self.export_node_names.items(): - functype = lltype.typeOf(self.entrypoint[funcname]) - func = make_ll_import_function(import_name, functype, import_eci) - setattr(mod, funcname, func) - return mod - def gen_makefile(self, targetdir): pass Added: pypy/branch/separate-compilation/pypy/translator/c/separate.py ============================================================================== --- (empty file) +++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Wed Jan 13 11:48:38 2010 @@ -0,0 +1,129 @@ +from pypy.annotation import model, description +from pypy.tool.sourcetools import func_with_new_name +from pypy.rlib.unroll import unrolling_iterable +from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.rpython.typesystem import getfunctionptr +from pypy.rpython.lltypesystem import lltype, rffi +from pypy.rpython.extregistry import ExtRegistryEntry + +import types + +def annotate_exported_functions(annotator, exports): + bk = annotator.bookkeeper + + # annotate functions with signatures + for funcname, func in exports.items(): + if hasattr(func, 'argtypes'): + annotator.build_types(func, func.argtypes, + complete_now=False) + # annotate classes + for funcname, cls in exports.items(): + if not isinstance(cls, (type, types.ClassType)): + continue + desc = bk.getdesc(cls) + classdef = desc.getuniqueclassdef() + s_init = desc.s_read_attribute('__init__') + if isinstance(s_init, model.SomeImpossibleValue): + continue + + argtypes = (model.SomeInstance(classdef),) + argtypes += tuple(cls.__init__.argtypes) + annotator.build_types(cls.__init__.im_func, argtypes, + complete_now=False) + + annotator.complete() + + # ensure that functions without signature are not constant-folded + for funcname, func in exports.items(): + if not hasattr(func, 'argtypes'): + # build a list of arguments where constants are erased + newargs = [] + desc = bk.getdesc(func) + if isinstance(desc, description.FunctionDesc): + graph = desc.getuniquegraph() + for arg in graph.startblock.inputargs: + newarg = model.not_const(annotator.binding(arg)) + newargs.append(newarg) + # and reflow + annotator.build_types(func, newargs) + +def get_exported_functions(annotator, exports): + bk = annotator.bookkeeper + + exported_funcptr = {} + for funcname, func in exports.items(): + desc = bk.getdesc(func) + if not isinstance(desc, description.FunctionDesc): + continue + graph = desc.getuniquegraph() + funcptr = getfunctionptr(graph) + + exported_funcptr[funcname] = funcptr + return exported_funcptr + +def make_import_module(builder): + class Module: + pass + mod = Module() + mod.__file__ = builder.so_name + + forwards = [] + node_names = builder.export_node_names.values() + for node in builder.db.globalcontainers(): + if node.nodekind == 'func' and node.name in node_names: + forwards.append('\n'.join(node.forward_declaration())) + + import_eci = ExternalCompilationInfo( + libraries = [builder.so_name], + post_include_bits = forwards + ) + + for funcname, import_name in builder.export_node_names.items(): + functype = lltype.typeOf(builder.entrypoint[funcname]) + func = make_ll_import_function(import_name, functype, import_eci) + setattr(mod, funcname, func) + return mod + +def make_ll_import_arg_converter(TARGET): + from pypy.annotation import model + + def convert(x): + XXX + + class Entry(ExtRegistryEntry): + _about_ = convert + s_result_annotation = model.lltype_to_annotation(TARGET) + + def specialize_call(self, hop): + # TODO: input type check + [v_instance] = hop.inputargs(*hop.args_r) + return hop.genop('force_cast', [v_instance], + resulttype=TARGET) + + return convert +make_ll_import_arg_converter._annspecialcase_ = 'specialize:memo' + +def make_ll_import_function(name, functype, eci): + from pypy.rpython.lltypesystem import lltype, rffi + + imported_func = rffi.llexternal( + name, functype.TO.ARGS, functype.TO.RESULT, + compilation_info=eci, + ) + + ARGS = functype.TO.ARGS + unrolling_ARGS = unrolling_iterable(enumerate(ARGS)) + def wrapper(*args): + real_args = () + for i, TARGET in unrolling_ARGS: + arg = args[i] + if isinstance(TARGET, lltype.Ptr): # XXX more precise check? + arg = make_ll_import_arg_converter(TARGET)(arg) + + real_args = real_args + (arg,) + res = imported_func(*real_args) + return res + wrapper._annspecialcase_ = 'specialize:ll' + wrapper._always_inline_ = True + return func_with_new_name(wrapper, name) + Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Wed Jan 13 11:48:38 2010 @@ -1,13 +1,10 @@ from pypy.translator.separate import export from pypy.translator.translator import TranslationContext -from pypy.translator.c.genc import CExtModuleBuilder, CLibraryBuilder, gen_forwarddecl +from pypy.translator.c.genc import CExtModuleBuilder, CLibraryBuilder +from pypy.translator.c import separate from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.rpython.typesystem import getfunctionptr -from pypy.rpython.lltypesystem import rffi, lltype -from pypy.annotation import model, description import py import sys, os -import types class TestSeparation: def compile_function(self, func, argtypes): @@ -22,60 +19,18 @@ def compile_separated(self, name, **exports): t = TranslationContext() t.buildannotator() - bk = t.annotator.bookkeeper - # annotate functions with signatures - for funcname, func in exports.items(): - if hasattr(func, 'argtypes'): - t.annotator.build_types(func, func.argtypes, - complete_now=False) - # annotate classes - for funcname, cls in exports.items(): - if not isinstance(cls, (type, types.ClassType)): - continue - desc = bk.getdesc(cls) - classdef = desc.getuniqueclassdef() - s_init = desc.s_read_attribute('__init__') - if isinstance(s_init, model.SomeImpossibleValue): - continue - - argtypes = (model.SomeInstance(classdef),) - argtypes += tuple(cls.__init__.argtypes) - t.annotator.build_types(cls.__init__.im_func, argtypes, - complete_now=False) - t.annotator.complete() - - # ensure that functions without signature are not constant-folded - for funcname, func in exports.items(): - if not hasattr(func, 'argtypes'): - # build a list of arguments where constants are erased - newargs = [] - desc = bk.getdesc(func) - if isinstance(desc, description.FunctionDesc): - graph = desc.getuniquegraph() - for arg in graph.startblock.inputargs: - newarg = model.not_const(t.annotator.binding(arg)) - newargs.append(newarg) - # and reflow - t.annotator.build_types(func, newargs) + separate.annotate_exported_functions(t.annotator, exports) t.buildrtyper().specialize() - exported_funcptr = {} - for funcname, func in exports.items(): - desc = bk.getdesc(func) - if not isinstance(desc, description.FunctionDesc): - continue - graph = desc.getuniquegraph() - funcptr = getfunctionptr(graph) - - exported_funcptr[funcname] = funcptr + exported_funcptr = separate.get_exported_functions(t.annotator, exports) builder = CLibraryBuilder(t, exported_funcptr, config=t.config) builder.generate_source() builder.compile() - mod = builder.make_import_module() + mod = separate.make_import_module(builder) return mod def test_simple_call(self): Modified: pypy/branch/separate-compilation/pypy/translator/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/separate.py Wed Jan 13 11:48:38 2010 @@ -1,6 +1,3 @@ -from pypy.tool.sourcetools import func_with_new_name -from pypy.rlib.unroll import unrolling_iterable -from pypy.rpython.extregistry import ExtRegistryEntry import types class export(object): @@ -45,46 +42,3 @@ return (isinstance(obj, (types.FunctionType, types.UnboundMethodType)) and getattr(obj, 'exported', False)) -def make_ll_import_arg_converter(TARGET): - from pypy.annotation import model - - def convert(x): - XXX - - class Entry(ExtRegistryEntry): - _about_ = convert - s_result_annotation = model.lltype_to_annotation(TARGET) - - def specialize_call(self, hop): - # TODO: input type check - [v_instance] = hop.inputargs(*hop.args_r) - return hop.genop('force_cast', [v_instance], - resulttype=TARGET) - - return convert -make_ll_import_arg_converter._annspecialcase_ = 'specialize:memo' - -def make_ll_import_function(name, functype, eci): - from pypy.rpython.lltypesystem import lltype, rffi - - imported_func = rffi.llexternal( - name, functype.TO.ARGS, functype.TO.RESULT, - compilation_info=eci, - ) - - ARGS = functype.TO.ARGS - unrolling_ARGS = unrolling_iterable(enumerate(ARGS)) - def wrapper(*args): - real_args = () - for i, TARGET in unrolling_ARGS: - arg = args[i] - if isinstance(TARGET, lltype.Ptr): # XXX more precise check? - arg = make_ll_import_arg_converter(TARGET)(arg) - - real_args = real_args + (arg,) - res = imported_func(*real_args) - return res - wrapper._annspecialcase_ = 'specialize:ll' - wrapper._always_inline_ = True - return func_with_new_name(wrapper, name) - From fijal at codespeak.net Wed Jan 13 12:19:08 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 13 Jan 2010 12:19:08 +0100 (CET) Subject: [pypy-svn] r70553 - pypy/branch/jit-profiling/pypy/jit/backend/x86 Message-ID: <20100113111908.EBF57168045@codespeak.net> Author: fijal Date: Wed Jan 13 12:19:08 2010 New Revision: 70553 Modified: pypy/branch/jit-profiling/pypy/jit/backend/x86/assembler.py Log: Improve debugging Modified: pypy/branch/jit-profiling/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/jit-profiling/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/jit-profiling/pypy/jit/backend/x86/assembler.py Wed Jan 13 12:19:08 2010 @@ -171,6 +171,7 @@ self._patch_stackadjust(adr_stackadjust, frame_depth+param_depth) looptoken._x86_frame_depth = frame_depth looptoken._x86_param_depth = param_depth + debug_print("Loop #", looptoken.number, "has address", looptoken._x86_loop_code) def assemble_bridge(self, faildescr, inputargs, operations): self.make_sure_mc_exists() @@ -193,6 +194,9 @@ faildescr._x86_bridge_param_depth = param_depth # patch the jump from original guard self.patch_jump(faildescr, adr_bridge) + debug_print("Bridge out of guard", + self.cpu.get_fail_descr_number(faildescr), + "has address", adr_bridge) def patch_jump(self, faildescr, adr_new_target): adr_jump_offset = faildescr._x86_adr_jump_offset From fijal at codespeak.net Wed Jan 13 12:21:47 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 13 Jan 2010 12:21:47 +0100 (CET) Subject: [pypy-svn] r70554 - pypy/branch/jit-profiling/pypy/jit/backend/x86 Message-ID: <20100113112147.014E2168045@codespeak.net> Author: fijal Date: Wed Jan 13 12:21:47 2010 New Revision: 70554 Modified: pypy/branch/jit-profiling/pypy/jit/backend/x86/assembler.py Log: improve debugging even more Modified: pypy/branch/jit-profiling/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/jit-profiling/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/jit-profiling/pypy/jit/backend/x86/assembler.py Wed Jan 13 12:21:47 2010 @@ -171,7 +171,8 @@ self._patch_stackadjust(adr_stackadjust, frame_depth+param_depth) looptoken._x86_frame_depth = frame_depth looptoken._x86_param_depth = param_depth - debug_print("Loop #", looptoken.number, "has address", looptoken._x86_loop_code) + debug_print("Loop #", looptoken.number, "has address", + looptoken._x86_loop_code, "to", self.mc.tell()) def assemble_bridge(self, faildescr, inputargs, operations): self.make_sure_mc_exists() @@ -196,7 +197,7 @@ self.patch_jump(faildescr, adr_bridge) debug_print("Bridge out of guard", self.cpu.get_fail_descr_number(faildescr), - "has address", adr_bridge) + "has address", adr_bridge, "to", self.mc.tell()) def patch_jump(self, faildescr, adr_new_target): adr_jump_offset = faildescr._x86_adr_jump_offset From afa at codespeak.net Wed Jan 13 13:17:29 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 13 Jan 2010 13:17:29 +0100 (CET) Subject: [pypy-svn] r70555 - pypy/branch/separate-compilation/pypy/translator/c/test Message-ID: <20100113121729.223A5168051@codespeak.net> Author: afa Date: Wed Jan 13 13:17:28 2010 New Revision: 70555 Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Add a test, which works. Next: directly call the constructor Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Wed Jan 13 13:17:28 2010 @@ -121,3 +121,38 @@ assert fn() == 73.5 c_fn = self.compile_function(fn, []) assert c_fn() == 73.5 + + def test_create_structure(self): + class S: + @export(float) + def __init__(self, x): + self.x = x + + # functions exported from the 'first' module + @export(float) + def newS(x): + return S(x) + + @export(S) + def f(s): + return s.x + 1.5 + firstmodule = self.compile_separated("first", newS=newS, f=f) + + # call them from a function compiled in another module + @export() + def g(): + s = firstmodule.newS(41.0) + return firstmodule.f(s) + secondmodule = self.compile_separated("second", g=g) + + def fn(): + return secondmodule.g() + + if sys.platform == 'win32': + filepath = os.path.dirname(firstmodule.__file__) + os.environ['PATH'] = "%s;%s" % (filepath, os.environ['PATH']) + + assert fn() == 42.5 + c_fn = self.compile_function(fn, []) + assert c_fn() == 42.5 + From afa at codespeak.net Wed Jan 13 14:52:39 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 13 Jan 2010 14:52:39 +0100 (CET) Subject: [pypy-svn] r70556 - in pypy/branch/separate-compilation/pypy/translator/c: . test Message-ID: <20100113135239.11EAC168048@codespeak.net> Author: afa Date: Wed Jan 13 14:52:37 2010 New Revision: 70556 Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Expose the constructor directly. Next step: access to struct members Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Wed Jan 13 14:52:37 2010 @@ -1,23 +1,36 @@ from pypy.annotation import model, description from pypy.tool.sourcetools import func_with_new_name from pypy.rlib.unroll import unrolling_iterable +from pypy.rlib.objectmodel import instantiate from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import lltype, rffi from pypy.rpython.extregistry import ExtRegistryEntry - +import py import types +def make_wrapper_for_constructor(cls, name): + nbargs = len(cls.__init__.argtypes) + args = ', '.join(['arg%d' % d for d in range(nbargs)]) + + source = py.code.Source(r""" + def wrapper(%s): + obj = instantiate(cls) + obj.__init__(%s) + return obj + """ % (args, args)) + miniglobals = {'cls': cls, 'instantiate': instantiate} + exec source.compile() in miniglobals + wrapper = miniglobals['wrapper'] + wrapper._annspecialcase_ = 'specialize:ll' + wrapper._always_inline_ = True + return func_with_new_name(wrapper, name) + def annotate_exported_functions(annotator, exports): bk = annotator.bookkeeper - # annotate functions with signatures - for funcname, func in exports.items(): - if hasattr(func, 'argtypes'): - annotator.build_types(func, func.argtypes, - complete_now=False) # annotate classes - for funcname, cls in exports.items(): + for clsname, cls in exports.items(): if not isinstance(cls, (type, types.ClassType)): continue desc = bk.getdesc(cls) @@ -26,11 +39,17 @@ if isinstance(s_init, model.SomeImpossibleValue): continue - argtypes = (model.SomeInstance(classdef),) - argtypes += tuple(cls.__init__.argtypes) - annotator.build_types(cls.__init__.im_func, argtypes, + wrapper = make_wrapper_for_constructor(cls, clsname) + exports[clsname] = wrapper + + annotator.build_types(wrapper, cls.__init__.argtypes, complete_now=False) + # annotate functions with signatures + for funcname, func in exports.items(): + if hasattr(func, 'argtypes'): + annotator.build_types(func, func.argtypes, + complete_now=False) annotator.complete() # ensure that functions without signature are not constant-folded @@ -51,14 +70,15 @@ bk = annotator.bookkeeper exported_funcptr = {} - for funcname, func in exports.items(): - desc = bk.getdesc(func) - if not isinstance(desc, description.FunctionDesc): + for itemname, item in exports.items(): + desc = bk.getdesc(item) + if isinstance(desc, description.FunctionDesc): + graph = desc.getuniquegraph() + funcptr = getfunctionptr(graph) + elif isinstance(desc, description.ClassDesc): continue - graph = desc.getuniquegraph() - funcptr = getfunctionptr(graph) - exported_funcptr[funcname] = funcptr + exported_funcptr[itemname] = funcptr return exported_funcptr def make_import_module(builder): Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Wed Jan 13 14:52:37 2010 @@ -7,6 +7,25 @@ import sys, os class TestSeparation: + def setup_method(self, method): + class S: + @export(float) + def __init__(self, x): + self.x = x + + # functions exported from the 'first' module + @export(float) + def newS(x): + return S(x) + + @export(S, S, int) + def f2S(s, t, v): + return s.x + t.x + v + + self.S = S + self.newS = newS + self.f2S = f2S + def compile_function(self, func, argtypes): t = TranslationContext() t.buildannotator().build_types(func, argtypes) @@ -92,16 +111,8 @@ assert c_fn() == 42.5 def test_pass_structure(self): - class S: - @export(float) - def __init__(self, x): - self.x = x - - # function exported from the 'first' module - @export(S, S, int) - def f(s, t, v): - return s.x + t.x + v - firstmodule = self.compile_separated("first", f=f, S=S) + firstmodule = self.compile_separated("first", f=self.f2S, S=self.S) + S = self.S # call it from a function compiled in another module @export() @@ -123,26 +134,15 @@ assert c_fn() == 73.5 def test_create_structure(self): - class S: - @export(float) - def __init__(self, x): - self.x = x - - # functions exported from the 'first' module - @export(float) - def newS(x): - return S(x) - - @export(S) - def f(s): - return s.x + 1.5 - firstmodule = self.compile_separated("first", newS=newS, f=f) + firstmodule = self.compile_separated( + "first", newS=self.newS, S=self.S, f=self.f2S) # call them from a function compiled in another module @export() def g(): s = firstmodule.newS(41.0) - return firstmodule.f(s) + t = firstmodule.S(25.5) + return firstmodule.f(s, t, 7) secondmodule = self.compile_separated("second", g=g) def fn(): @@ -152,7 +152,7 @@ filepath = os.path.dirname(firstmodule.__file__) os.environ['PATH'] = "%s;%s" % (filepath, os.environ['PATH']) - assert fn() == 42.5 + assert fn() == 73.5 c_fn = self.compile_function(fn, []) - assert c_fn() == 42.5 + assert c_fn() == 73.5 From cfbolz at codespeak.net Wed Jan 13 16:24:01 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 13 Jan 2010 16:24:01 +0100 (CET) Subject: [pypy-svn] r70562 - pypy/trunk/pypy/objspace/std Message-ID: <20100113152401.68DAF168047@codespeak.net> Author: cfbolz Date: Wed Jan 13 16:24:00 2010 New Revision: 70562 Modified: pypy/trunk/pypy/objspace/std/rangeobject.py Log: Unrelated things I found when staring at traces: make range object a bit more efficient, reducing the number of comparisons when iterating over it (removes 2 guards when jitted). Test in test_pypy_c.py will follow. Modified: pypy/trunk/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/rangeobject.py (original) +++ pypy/trunk/pypy/objspace/std/rangeobject.py Wed Jan 13 16:24:00 2010 @@ -56,7 +56,9 @@ def getitem(w_self, i): if i < 0: i += w_self.length - if i >= w_self.length or i < 0: + if i < 0: + raise IndexError + elif i >= w_self.length: raise IndexError return w_self.start + i * w_self.step @@ -194,24 +196,24 @@ if w_rangelist is None: raise OperationError(space.w_StopIteration, space.w_None) assert isinstance(w_rangelist, W_RangeListObject) + index = w_rangeiter.index if w_rangelist.w_list is not None: try: w_item = space.getitem(w_rangelist.w_list, - wrapint(space, w_rangeiter.index)) + wrapint(space, index)) except OperationError, e: w_rangeiter.w_seq = None if not e.match(space, space.w_IndexError): raise raise OperationError(space.w_StopIteration, space.w_None) else: - try: - w_item = wrapint( - space, - w_rangelist.getitem(w_rangeiter.index)) - except IndexError: + if index >= w_rangelist.length: w_rangeiter.w_seq = None raise OperationError(space.w_StopIteration, space.w_None) - w_rangeiter.index += 1 + w_item = wrapint( + space, + w_rangelist.getitem_unchecked(index)) + w_rangeiter.index = index + 1 return w_item # XXX __length_hint__() From afa at codespeak.net Wed Jan 13 16:24:32 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 13 Jan 2010 16:24:32 +0100 (CET) Subject: [pypy-svn] r70563 - pypy/branch/separate-compilation/pypy/translator/c/test Message-ID: <20100113152432.2F99B168047@codespeak.net> Author: afa Date: Wed Jan 13 16:24:31 2010 New Revision: 70563 Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Refactor tests a bit, and add the next test I want to pass Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Wed Jan 13 16:24:31 2010 @@ -8,6 +8,8 @@ class TestSeparation: def setup_method(self, method): + self.additional_PATH = [] + class S: @export(float) def __init__(self, x): @@ -50,8 +52,23 @@ builder.compile() mod = separate.make_import_module(builder) + + if sys.platform == 'win32': + filepath = os.path.dirname(builder.so_name) + self.additional_PATH.append(filepath) + return mod + def call_exported(self, func): + if sys.platform == 'win32': + for path in self.additional_PATH: + os.environ['PATH'] = "%s;%s" % (path, os.environ['PATH']) + + def fn(): + return func() + + return fn + def test_simple_call(self): # function exported from the 'first' module @export(float) @@ -81,12 +98,7 @@ secondmodule = self.compile_separated("second", g=g) # call it from a function compiled in another module - def fn(): - return secondmodule.g(41) - - if sys.platform == 'win32': - filepath = os.path.dirname(firstmodule.__file__) - os.environ['PATH'] = "%s;%s" % (filepath, os.environ['PATH']) + fn = self.call_exported(lambda: secondmodule.g(41)) assert fn() == 21.25 c_fn = self.compile_function(fn, []) @@ -114,7 +126,6 @@ firstmodule = self.compile_separated("first", f=self.f2S, S=self.S) S = self.S - # call it from a function compiled in another module @export() def g(): s = S(41.0) @@ -122,12 +133,7 @@ return firstmodule.f(s, t, 7) secondmodule = self.compile_separated("second", g=g) - def fn(): - return secondmodule.g() - - if sys.platform == 'win32': - filepath = os.path.dirname(firstmodule.__file__) - os.environ['PATH'] = "%s;%s" % (filepath, os.environ['PATH']) + fn = self.call_exported(secondmodule.g) assert fn() == 73.5 c_fn = self.compile_function(fn, []) @@ -137,7 +143,6 @@ firstmodule = self.compile_separated( "first", newS=self.newS, S=self.S, f=self.f2S) - # call them from a function compiled in another module @export() def g(): s = firstmodule.newS(41.0) @@ -145,14 +150,26 @@ return firstmodule.f(s, t, 7) secondmodule = self.compile_separated("second", g=g) - def fn(): - return secondmodule.g() - - if sys.platform == 'win32': - filepath = os.path.dirname(firstmodule.__file__) - os.environ['PATH'] = "%s;%s" % (filepath, os.environ['PATH']) + fn = self.call_exported(secondmodule.g) assert fn() == 73.5 c_fn = self.compile_function(fn, []) assert c_fn() == 73.5 + def test_structure_attributes(self): + firstmodule = self.compile_separated( + "first", S=self.S) + + @export() + def g(): + s = firstmodule.S(41.5) + s.x /= 2 + return s.x + secondmodule = self.compile_separated("second", g=g) + + fn = self.call_exported(secondmodule.g) + + assert fn() == 20.25 + c_fn = self.compile_function(fn, []) + assert c_fn() == 20.25 + From cfbolz at codespeak.net Wed Jan 13 16:50:33 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 13 Jan 2010 16:50:33 +0100 (CET) Subject: [pypy-svn] r70564 - pypy/trunk/pypy/module/pypyjit/test Message-ID: <20100113155033.DE499168051@codespeak.net> Author: cfbolz Date: Wed Jan 13 16:50:33 2010 New Revision: 70564 Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: check the behaviour of the range list Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Wed Jan 13 16:50:33 2010 @@ -403,6 +403,29 @@ assert len(bytecode.get_opnames("call")) == 1 # the call to append assert len(bytecode.get_opnames("guard")) == 1 # guard_no_exception after the call + def test_range_iter(self): + self.run_source(''' + def g(n): + return range(n) + + def main(n): + s = 0 + for i in range(n): + s += g(n)[i] + return s + ''', 143, ([1000], 1000 * 999 / 2)) + bytecode, = self.get_by_bytecode("BINARY_SUBSCR") + assert bytecode.get_opnames("guard") == [ + "guard_isnull", # check that the range list is not forced + "guard_false", # check that the index is lower than the current length + ] + bytecode, _ = self.get_by_bytecode("FOR_ITER") # second bytecode is the end of the loop + assert bytecode.get_opnames("guard") == [ + "guard_nonnull", # check that the iterator is not finished + "guard_isnull", # check that the range list is not forced + "guard_false", # check that the index is lower than the current length + ] + def test_exception_inside_loop_1(self): py.test.skip("exceptions: in-progress") self.run_source(''' From fijal at codespeak.net Wed Jan 13 16:59:54 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 13 Jan 2010 16:59:54 +0100 (CET) Subject: [pypy-svn] r70565 - pypy/trunk/pypy/interpreter Message-ID: <20100113155954.B5286168051@codespeak.net> Author: fijal Date: Wed Jan 13 16:59:54 2010 New Revision: 70565 Modified: pypy/trunk/pypy/interpreter/executioncontext.py Log: Kill seems-to-be-unused function Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Wed Jan 13 16:59:54 2010 @@ -131,14 +131,6 @@ return lst # coroutine: I think this is all, folks! - - def get_builtin(self): - frame = self.gettopframe_nohidden() - if frame is not None: - return frame.builtin - else: - return self.space.builtin - def c_call_trace(self, frame, w_func): "Profile the call of a builtin function" if self.profilefunc is None: From magcius at codespeak.net Wed Jan 13 19:26:33 2010 From: magcius at codespeak.net (magcius at codespeak.net) Date: Wed, 13 Jan 2010 19:26:33 +0100 (CET) Subject: [pypy-svn] r70568 - in pypy/branch/avm: . pypy/translator/avm1 pypy/translator/avm1/test pypy/translator/avm2 pypy/translator/avm2/intrinsic pypy/translator/avm2/test Message-ID: <20100113182633.B34DA318139@codespeak.net> Author: magcius Date: Wed Jan 13 19:26:30 2010 New Revision: 70568 Added: pypy/branch/avm/pypy/translator/avm2/_playerglobal.py (contents, props changed) pypy/branch/avm/pypy/translator/avm2/test/test_script.py Modified: pypy/branch/avm/ (props changed) pypy/branch/avm/README pypy/branch/avm/pypy/translator/avm1/avm1gen.py pypy/branch/avm/pypy/translator/avm1/function.py pypy/branch/avm/pypy/translator/avm1/genavm.py pypy/branch/avm/pypy/translator/avm1/opcodes.py pypy/branch/avm/pypy/translator/avm1/test/bootstrap.py pypy/branch/avm/pypy/translator/avm1/test/harness.py pypy/branch/avm/pypy/translator/avm1/test/test_harness.py pypy/branch/avm/pypy/translator/avm2/ (props changed) pypy/branch/avm/pypy/translator/avm2/avm2gen.py pypy/branch/avm/pypy/translator/avm2/class_.py pypy/branch/avm/pypy/translator/avm2/constant.py pypy/branch/avm/pypy/translator/avm2/database.py pypy/branch/avm/pypy/translator/avm2/function.py pypy/branch/avm/pypy/translator/avm2/genavm.py pypy/branch/avm/pypy/translator/avm2/intrinsic/intrgen.py pypy/branch/avm/pypy/translator/avm2/metavm.py pypy/branch/avm/pypy/translator/avm2/opcodes.py pypy/branch/avm/pypy/translator/avm2/query.py pypy/branch/avm/pypy/translator/avm2/record.py pypy/branch/avm/pypy/translator/avm2/runtime.py pypy/branch/avm/pypy/translator/avm2/test/ (props changed) pypy/branch/avm/pypy/translator/avm2/test/browsertest.py pypy/branch/avm/pypy/translator/avm2/test/harness.py pypy/branch/avm/pypy/translator/avm2/test/runtest.py pypy/branch/avm/pypy/translator/avm2/types_.py Log: New version of the AVM2 branch. Passes more tests. Requires mecheye-fusion from PyPI, which evolved out of the original work on this branch, but was separated when the Gnash team wanted a SWF export library to create test cases for AVM2. Modified: pypy/branch/avm/README ============================================================================== --- pypy/branch/avm/README (original) +++ pypy/branch/avm/README Wed Jan 13 19:26:30 2010 @@ -21,6 +21,15 @@ PyPy. It will also point you to our documentation section which is generated from information in the pypy/doc directory. +The AVM1/AVM2 translator backends require mecheye-fusion, which is +easily installable from PyPI: + +easy_install mecheye-fusion + +or + +pip install mecheye-fusion + Enjoy and send us feedback! the pypy-dev team Modified: pypy/branch/avm/pypy/translator/avm1/avm1gen.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/avm1gen.py (original) +++ pypy/branch/avm/pypy/translator/avm1/avm1gen.py Wed Jan 13 19:26:30 2010 @@ -4,12 +4,14 @@ from pypy.objspace.flow import model as flowmodel from pypy.rpython.ootypesystem import ootype -from pypy.translator.avm1 import avm1, types_ as types +#from pypy.translator.avm1 import types_ as types from pypy.translator.oosupport.treebuilder import SubOperation from pypy.translator.oosupport.metavm import Generator as OOGenerator, InstructionList from pypy.translator.oosupport.constant import push_constant from collections import namedtuple +from mech.fusion.avm1 import actions, types_ as types, avm1gen + ClassName = namedtuple("ClassName", "namespace classname") Scope = namedtuple("Scope", "block parent callback islabel") @@ -30,478 +32,26 @@ instr_list.render(generator, op) # now the value is on the stack -def make_variable(name): - if isinstance(name, Variable): - return name - return Variable(name) - -class StackDummy(object): - def __init__(self, name): - self.name = name - -class Variable(StackDummy): - def __str__(self): - return 'Variable(name="%s")' % self.name - __repr__ = __str__ - - def __add__(self, other): - if isinstance(other, StackDummy): - other = other.name - return Variable("ADD %r %r" % (self.name, other)) - - def __radd__(self, other): - return other + self - -class ScriptObject(StackDummy): - pass - -class Function(StackDummy): - pass - -class AVM1Gen(OOGenerator): - """ AVM1 'assembler' generator routines """ - - def __init__(self, block=None): - self.stack = [] - self.namespaces = {} - self.block = block or avm1.Block(None, True) - self.scope = Scope(self.block, None, None, False) - self.action(self.block.constants) - self.ilasm = self - - def new_label(self): - return self.fn_block.new_label() - - def push_stack(self, *values): - print "PUSHSTACK:", values - for element in values: - self.stack.append(element) - - @property - def fn_block(self): - if self.scope.islabel: - return self.scope.parent.block - return self.scope.block - - def pop_stack(self, n=1): - v = [self.stack.pop() for i in xrange(n)] - print "POPSTACK:", v - return v - - def store_register(self, name, index=-1): - index = self.fn_block.store_register(name, index) - self.action(avm1.ActionStoreRegister(index)) - return index - - def find_register(self, name): - print "FINDING REGISTER:", name - return self.fn_block.find_register(name) - - def action(self, action): - return self.scope.block.add_action(action) - - def set_label(self, label): - print "SETLABEL:", label - - if self.scope.islabel: - self.exit_scope() - - label, block = self._branch_start(label) - self.enter_scope(block, islabel=True) - - def enter_scope(self, new_code_obj, exit_callback=None, islabel=False): - print "ENTERSCOPE" - self.scope = Scope(new_code_obj, self.scope, exit_callback, islabel) - - def in_function(self): - return self.fn_block.FUNCTION_TYPE - - def exit_scope(self): - print "EXITSCOPE" - block_len = self.finalize_block(self.scope.block) - exit_callback = self.scope.callback - - # Go up to the parent scope. - self.scope = self.scope.parent - - self.scope.block.current_offset += block_len - if exit_callback is not None: - exit_callback() - - def finalize_block(self, block): - for label, branch_block in block.branch_blocks: - if not branch_block.sealed: - branch_block.seal() - - # Set the label. - block.labels[label] = block.current_offset - - print label, block.current_offset - - # Add the actions, which updates current_offset - for act in branch_block.actions: - - block.add_action(act) - return block.seal() - - # def begin_namespace(self, _namespace): - # n = _namespace.split('.') - # namespace = self.namespaces - # if n[0] not in self.namespaces: - # self.namespaces[n[0]] = {} - # self.push_const(n[0]) - # self.init_object() - # self.set_variable() - # self.push_var(n[0]) - # for ns in n[1:]: - # if not ns in namespace: - # namespace[ns] = {} - # namespace = namespace[ns] - # self.push_const(ns) - # self.init_object() - # self.set_member() - - def begin_function(self, name, arglist): - self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, name, arglist))) - - def begin_static_method(self, function_name, _class, arglist): - def exit_callback(block): - self.set_member() - self.load(_class) - self.push_const(function_name) - self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, "", arglist, 0)), exit_callback) - self.push_stack(Function(function_name)) - - def begin_method(self, function_name, _class, arglist): - def exit_callback(block): - self.set_member() - self.load(_class) - self.push_const("prototype") - self.get_member() - self.push_const(function_name) - self.enter_scope(self.action(avm1.ActionDefineFunction2(self.block, "", arglist, 0)), exit_callback) - self.push_stack(Function(function_name)) +class PyPyAVM1Gen(avm1gen.AVM1Gen, OOGenerator): + """ + AVM1 'assembler' generator routines + """ - def set_variable(self): - value, name = self.pop_stack(2) - print "SETVARIABLE: %r = %r" % (name, value) - if isinstance(name, Variable): - name = name.name - assert isinstance(name, basestring) - if self.find_register(name) >= 0 and self.in_function() == 2: - self.store_register(name) - self.action(avm1.ActionSetVariable()) - - def get_variable(self): - name, = self.pop_stack() - print "GETVARIABLE:", name - self.action(avm1.ActionGetVariable()) - self.push_stack(make_variable(name)) - - def set_member(self): - self.action(avm1.ActionSetMember()) - value, name, obj = self.pop_stack(3) - print "SETMEMBER: %s.%s = %r" % (obj, name, value) - - def get_member(self): - self.action(avm1.ActionGetMember()) - name, obj = self.pop_stack(2) - print "GETMEMBER:", name, obj - self.push_stack(Variable("%s.%s" % (obj, name))) - - def push_reg_index(self, index): - self.action(avm1.ActionPush((index, avm1.REGISTER))) - - def push_arg(self, v): - assert self.in_function() > 0, "avm1gen::push_arg called while not in function scope." - self.push_local(v) - -# def push_value(self, v): -# self.action(avm1.ActionPush(v.name)) - - def push_var(self, v): - k = self.find_register(v) - print k - if k >= 0: - self.push_stack(Variable(v)) - self.push_reg_index(k) - else: - if self.in_function() == 2: - if v in avm1.preload: - setattr(self.scope.block, avm1.preload[v]) - self.scope.block.eval_flags() - return self.push_var(v) - self.push_const(v) - self.get_variable() - if self.in_function() == 2: - self.store_register(v) - - def push_this(self): - self.push_var("this") - - def push_local(self, v): - self.push_var(v.name) - - def push_const(self, *args): - self.push_stack(*args) - self.action(avm1.ActionPush(types.pytype_to_avm1(v) for v in args)) - - def return_stmt(self): - print "RETURNSTMT" - self.pop_stack() - self.action(avm1.ActionReturn()) - - def swap(self): - a, b = self.pop_stack(2) - self.push_stack(b, a) - self.action(avm1.ActionSwap()) - - def is_equal(self, value=None): - if value is not None: - self.push_const(value) - self.action(avm1.ActionEquals()) - self.pop_stack(2) - - def is_not_equal(self, value=None): - self.is_equal(value) - self.action(avm1.ActionNot()) - self.pop_stack(2) - - def init_object(self, members={}): - self.load(members.items()) - self.push_const(len(members)) - self.action(avm1.ActionInitObject()) - self.pop_stack(self.pop_stack()[0]) - self.push_stack(ScriptObject("object")) - - def init_array(self, members=[]): - self.load(members) - self.push_const(len(members)) - self.action(avm1.ActionInitArray()) - self.pop_stack(self.pop_stack()[0]) - self.push_stack(ScriptObject("array")) - - # Assumes the args and number of args are on the stack. - def call_function(self, func_name): - self.push_const(func_name) - self.action(avm1.ActionCallFunction()) - name, nargs = self.pop_stack() - self.pop_stack(nargs) - self.push_stack(Variable("%s_RETURN" % func_name)) - - def call_function_constargs(self, func_name, *args): - p = self.push_const(*reversed((func_name, len(args))+args)) - self.action(avm1.ActionCallFunction()) - self.pop_stack(2+len(args)) - self.push_stack(Variable("%s_RETURN" % func_name)) - - # Assumes the args and number of args and ScriptObject are on the stack. - def call_method_n(self, func_name): - self.load(func_name) - self.action(avm1.ActionCallMethod()) - name, obj, nargs = self.pop_stack(3) - self.pop_stack(nargs) - self.push_stack(Variable("%s.%s_RETURN" % (obj.name, name))) - - # Assumes the args and number of args are on the stack. - def call_method_constvar(self, _class, func_name): - self.push_var(_class) - self.call_method_n(func_name) - - # Assumes the value is on the stack. - # def set_proto_field(self, objname, member_name): - # self.push_const("prototype") - # self.push_var(objname) - # self.get_member() - # self.swap() - # self.push_const(member_name) - # self.swap() - # self.set_member() - - # Assumes the value is on the stack. - # def set_static_field(self, objname, member_name): - # self.push_var(objname) - # self.swap() - # self.push_const(member_name) - # self.swap() - # self.set_member() - - # If no args are passed then it is assumed that the args and number of args are on the stack. - def newobject_constthis(self, obj, *args): - if len(args) > 0: - self.load(args+(len(args), obj)) - else: - self.load(obj) - self.newobject() - - - def newobject(self): - self.action(avm1.ActionNewObject()) - name, nargs = self.pop_stack(2) - args = self.pop_stack(nargs) - self.push_stack(ScriptObject(name)) - - # FIXME: will refactor later - #load_str = load_const - - def begin_switch_varname(self, varname): - self.push_var(varname) - self.switch_register = self.store_register(varname) - - def write_case(self, testee): - self.push_const(avm1.RegisterByIndex(self.switch_register), testee) - self.action(avm1.ActionStrictEquals()) - self.pop_stack(2) - if len(self.case_label) < 1: - self.case_label, self.case_block = self.branch_if_true() - else: - self.branch_if_true(self.case_label) - - def write_break(self): - self.exit_scope() - self.case_flag = False - self.case_block = None - - def enter_case_branch(self): - self.enter_scope(self.case_block) - - def throw(self): # Assumes the value to be thrown is on the stack. - self.action(avm1.ActionThrow()) - self.pop_stack() - - # oosupport Generator routines - def emit(self, op): - a = avm1.SHORT_ACTIONS[op] - if a.push_count > 0: - a.push_stack(StackDummy("Generated by %r" % op)) - elif a.push_count < 0: - self.pop_stack(-a.push_count) - self.action(a()) - - def pop(self, TYPE): - self.action(avm1.ActionPop()) - self.pop_stack() - - def dup(self, TYPE): - self.action(avm1.ActionDuplicate()) - self.push_stack(*[self.pop_stack()] * 2) - - def load(self, v): - if hasattr(v, "__iter__") and not isinstance(v, basestring): - for i in v: - self.load(i) - elif isinstance(v, ClassName): - if v.namespace: - ns = v.namespace.split('.') - self.push_var(ns[0]) - for i in ns[:0:-1]: - self.push_const(i) - self.get_member() - else: - self.push_var(v.classname) - elif isinstance(v, flowmodel.Variable): + def load(self, v, *args): + if isinstance(v, flowmodel.Variable): if v.concretetype is ootype.Void: return # ignore it - elif self.load_variable_hook(v): - return else: self.push_local(v) elif isinstance(v, flowmodel.Constant): push_constant(self.db, v.concretetype, v.value, self) elif isinstance(v, SubOperation): render_sub_op(v, self.db, self) - else: - self.push_const(v) - #self.push_var(v) - - def load_variable_hook(self, v): - return False - - #def downcast(self, TYPE): - # pass - - #def getclassobject(self, OOINSTANCE): - # pass - - #def instantiate(self): - # pass - - #def instanceof(self, TYPE): - # pass - - def _make_label(self, label): - print "MAKE LABEL:", label - if label == "" or label is None: - label = self.new_label() - - blocks = dict(self.fn_block.branch_blocks) - if label in self.fn_block.branch_blocks: - block = blocks[label] - else: - block = avm1.Block(self.block, False) - self.fn_block.branch_blocks.append((label, block)) - - return (label, block) - - def _branch_start(self, label): - return self._make_label(label) - - # Boolean value should be on stack when this is called - def branch_unconditionally(self, label): - print "BRANCH TO:", label - label, block = self._branch_start(label) - self.action(avm1.ActionJump(label)) - return label, block + super(PyPyAVM1Gen, self).load(v, *args) - def branch_conditionally(self, iftrue, label): - label, block = self._branch_start(label) - if not iftrue: - self.action(avm1.ActionNot()) - self.action(avm1.ActionIf(label)) - self.pop_stack() - return label, block - - def branch_if_equal(self, label): - label, block = self._branch_start(label) - self.action(avm1.ActionEquals()) - self.action(avm1.ActionIf(label)) - self.pop_stack(2) - return label, block - - def call_graph(self, graph): - self.call_function(graph.func_name) - - def call_method(self, OOCLASS, method_name): - pass - - def call_oostring(self, OOTYPE): - self.action(avm1.ActionConvertToString()) - - call_oounicode = call_oostring def new(self, TYPE): if isinstance(TYPE, ootype.List): self.oonewarray(None) - def oonewarray(self, TYPE, length=1): - self.newobject_constthis("Array", length) - - def push_null(self, TYPE=None): - self.action(avm1.ActionPush(avm1.NULL)) - self.push_stack(avm1.NULL) - - def push_undefined(self): - self.action(avm1.ActionPush(avm1.UNDEFINED)) - self.push_stack(avm1.UNDEFINED) - - def push_primitive_constant(self, TYPE, value): - if TYPE is ootype.Void: - self.push_null() - elif TYPE is ootype.String: - if value._str is None: - self.push_null() - else: - self.push_const(value._str) - else: - self.push_const(value) Modified: pypy/branch/avm/pypy/translator/avm1/function.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/function.py (original) +++ pypy/branch/avm/pypy/translator/avm1/function.py Wed Jan 13 19:26:30 2010 @@ -4,7 +4,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem.lltype import Void from pypy.translator.oosupport.function import Function as OOFunction -from pypy.translator.avm1.node import Node +from pypy.translator.cli.node import Node from pypy.translator.avm1.avm1gen import ClassName def load_variable_hook(self, v): Modified: pypy/branch/avm/pypy/translator/avm1/genavm.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/genavm.py (original) +++ pypy/branch/avm/pypy/translator/avm1/genavm.py Wed Jan 13 19:26:30 2010 @@ -1,12 +1,12 @@ import py from pypy.translator.oosupport.genoo import GenOO -from pypy.translator.avm1.avm1gen import AVM1Gen +from pypy.translator.avm1.avm1gen import PyPyAVM1Gen from pypy.translator.avm1.constant import AVM1ConstGenerator from pypy.translator.avm1.database import LowLevelDatabase from pypy.translator.avm1.function import Function from pypy.translator.avm1.opcodes import opcodes -from pypy.translator.avm1.types import AVM1TypeSystem +from pypy.translator.avm1.types_ import AVM1TypeSystem class GenAVM1(GenOO): @@ -23,7 +23,7 @@ self.ilasm = None def create_assembler(self): - return AVM1Gen() + return PyPyAVM1Gen() def generate_source(self): if self.ilasm is None: Modified: pypy/branch/avm/pypy/translator/avm1/opcodes.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/opcodes.py (original) +++ pypy/branch/avm/pypy/translator/avm1/opcodes.py Wed Jan 13 19:26:30 2010 @@ -1,6 +1,6 @@ from pypy.translator.oosupport import metavm as om -from pypy.translator.avm1 import metavm as am, avm1 as a +from pypy.translator.avm1 import metavm as am DoNothing = [om.PushAllArgs] Modified: pypy/branch/avm/pypy/translator/avm1/test/bootstrap.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/bootstrap.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/bootstrap.py Wed Jan 13 19:26:30 2010 @@ -1,6 +1,7 @@ import autopath -from pypy.translator.avm import swf as s, avm1 as a, tags as t, records as r +from mech.fusion.swf import swfdata as s, tags as t, records as r +from mech.fusion import avm1 as a if __name__ == "__main__": with open("test.swf", "w") as f: Modified: pypy/branch/avm/pypy/translator/avm1/test/harness.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/harness.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/harness.py Wed Jan 13 19:26:30 2010 @@ -1,6 +1,7 @@ from pypy.translator.avm1.test import browsertest as b -from pypy.translator.avm1 import avm1 as a, avm1gen as g, swf as s, tags as t, records as r +from mech.fusion.swf import swfdata as s, tags as t, records as r +from mech.fusion import avm1 as a class TestHarness(object): def __init__(self, name): Modified: pypy/branch/avm/pypy/translator/avm1/test/test_harness.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm1/test/test_harness.py (original) +++ pypy/branch/avm/pypy/translator/avm1/test/test_harness.py Wed Jan 13 19:26:30 2010 @@ -1,7 +1,7 @@ import autopath -from pypy.translator.avm.test import browsertest, harness as h -from pypy.translator.avm import avm1 as a +from pypy.translator.avm1.test import browsertest, harness as h +from mech.fusion import avm1 as a def test_harness(): harness = h.TestHarness("harness") Added: pypy/branch/avm/pypy/translator/avm2/_playerglobal.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/_playerglobal.py Wed Jan 13 19:26:30 2010 @@ -0,0 +1,15115 @@ +# This file has been autogenerated by intrgen.py -- DO NOT EDIT + +from pypy.translator.avm2.query import ClassDesc + +types = {} + +desc = ClassDesc() +desc.FullName = 'Namespace' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', '*'), + ('prefix', ''), + ('uri', 'ootype.String'), +] +types['Namespace'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'ArgumentError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['ArgumentError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'XML' +desc.BaseType = 'Object' +desc.Methods = [ + ('addNamespace', [''], 'XML'), + ('appendChild', [''], 'XML'), + ('attribute', [''], 'XMLList'), + ('attributes', [''], 'XMLList'), + ('child', [''], 'XMLList'), + ('childIndex', [''], 'ootype.SignedLongLong'), + ('children', [''], 'XMLList'), + ('comments', [''], 'XMLList'), + ('contains', [''], 'ootype.Bool'), + ('copy', [''], 'XML'), + ('descendants', [''], 'XMLList'), + ('elements', [''], 'XMLList'), + ('hasComplexContent', [''], 'ootype.Bool'), + ('hasOwnProperty', [''], 'ootype.Bool'), + ('hasSimpleContent', [''], 'ootype.Bool'), + ('inScopeNamespaces', [''], 'ootype.List'), + ('insertChildAfter', ['', ''], ''), + ('insertChildBefore', ['', ''], ''), + ('length', [''], 'ootype.SignedLongLong'), + ('localName', [''], 'ootype.Dict'), + ('name', [''], 'ootype.Dict'), + ('namespace', [''], ''), + ('namespaceDeclarations', [''], 'ootype.List'), + ('nodeKind', [''], 'ootype.String'), + ('normalize', [''], 'XML'), + ('notification', [''], 'Function'), + ('parent', [''], ''), + ('prependChild', [''], 'XML'), + ('processingInstructions', [''], 'XMLList'), + ('propertyIsEnumerable', [''], 'ootype.Bool'), + ('removeNamespace', [''], 'XML'), + ('replace', ['', ''], 'XML'), + ('setChildren', [''], 'XML'), + ('setLocalName', [''], 'ootype.Void'), + ('setName', [''], 'ootype.Void'), + ('setNamespace', [''], 'ootype.Void'), + ('setNotification', ['Function'], ''), + ('text', [''], 'XMLList'), + ('toString', [''], 'ootype.String'), + ('toXMLString', [''], 'ootype.String'), + ('valueOf', [''], 'XML'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('defaultSettings', [''], 'ootype.Dict'), + ('setSettings', ['ootype.Dict'], 'ootype.Void'), + ('settings', [''], 'ootype.Dict'), +] +desc.Fields = [] +desc.StaticFields = [ + ('length', '*'), + ('ignoreComments', 'ootype.Bool'), + ('ignoreProcessingInstructions', 'ootype.Bool'), + ('ignoreWhitespace', 'ootype.Bool'), + ('prettyIndent', 'ootype.SignedLongLong'), + ('prettyPrinting', 'ootype.Bool'), +] +types['XML'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Number' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('toExponential', [''], 'ootype.String'), + ('toFixed', [''], 'ootype.String'), + ('toPrecision', [''], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.Float'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('MAX_VALUE', 'Number'), + ('MIN_VALUE', 'Number'), + ('NaN', 'Number'), + ('NEGATIVE_INFINITY', 'Number'), + ('POSITIVE_INFINITY', 'Number'), +] +types['Number'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'QName' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'QName'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', '*'), + ('localName', 'ootype.String'), + ('uri', ''), +] +types['QName'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'TypeError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['TypeError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'UninitializedError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['UninitializedError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Class' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('prototype', ''), +] +types['Class'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'DefinitionError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['DefinitionError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'EvalError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['EvalError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'int' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('toExponential', [''], 'ootype.String'), + ('toFixed', [''], 'ootype.String'), + ('toPrecision', [''], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.SignedLongLong'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('MAX_VALUE', 'int'), + ('MIN_VALUE', 'int'), +] +types['int'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Array' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['*args'], None), + ('concat', ['*args'], 'ootype.List'), + ('every', ['Function', ''], 'ootype.Bool'), + ('filter', ['Function', ''], 'ootype.List'), + ('forEach', ['Function', ''], 'ootype.Void'), + ('indexOf', ['', ''], 'ootype.SignedLongLong'), + ('join', [''], 'ootype.String'), + ('lastIndexOf', ['', ''], 'ootype.SignedLongLong'), + ('map', ['Function', ''], 'ootype.List'), + ('pop', [''], ''), + ('push', ['*args'], 'ootype.UnsignedLongLong'), + ('reverse', [''], 'ootype.List'), + ('shift', [''], ''), + ('slice', ['', ''], 'ootype.List'), + ('some', ['Function', ''], 'ootype.Bool'), + ('sort', ['*args'], ''), + ('sortOn', ['', ''], ''), + ('splice', ['ootype.SignedLongLong', 'ootype.UnsignedLongLong', '*args'], ''), + ('unshift', ['*args'], 'ootype.UnsignedLongLong'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CASEINSENSITIVE', 'uint'), + ('DESCENDING', 'uint'), + ('length', 'int'), + ('NUMERIC', 'uint'), + ('RETURNINDEXEDARRAY', 'uint'), + ('UNIQUESORT', 'uint'), + ('length', 'ootype.UnsignedLongLong'), +] +types['Array'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('trace', ['*args'], 'ootype.Void'), + ('decodeURI', ['ootype.String'], 'ootype.String'), + ('decodeURIComponent', ['ootype.String'], 'ootype.String'), + ('encodeURI', ['ootype.String'], 'ootype.String'), + ('encodeURIComponent', ['ootype.String'], 'ootype.String'), + ('escape', ['ootype.String'], 'ootype.String'), + ('isFinite', ['ootype.Float'], 'ootype.Bool'), + ('isNaN', ['ootype.Float'], 'ootype.Bool'), + ('isXMLName', ['ootype.String'], 'ootype.Bool'), + ('parseInt', ['ootype.String', 'ootype.UnsignedLongLong'], 'ootype.Float'), + ('parseFloat', ['ootype.String'], 'ootype.Float'), + ('unescape', ['ootype.String'], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'RangeError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['RangeError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Math' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('abs', ['ootype.Float'], 'ootype.Float'), + ('acos', ['ootype.Float'], 'ootype.Float'), + ('asin', ['ootype.Float'], 'ootype.Float'), + ('atan', ['ootype.Float'], 'ootype.Float'), + ('atan2', ['ootype.Float', 'ootype.Float'], 'ootype.Float'), + ('ceil', ['ootype.Float'], 'ootype.Float'), + ('cos', ['ootype.Float'], 'ootype.Float'), + ('exp', ['ootype.Float'], 'ootype.Float'), + ('floor', ['ootype.Float'], 'ootype.Float'), + ('log', ['ootype.Float'], 'ootype.Float'), + ('max', ['ootype.Float', 'ootype.Float', '*args'], 'ootype.Float'), + ('min', ['ootype.Float', 'ootype.Float', '*args'], 'ootype.Float'), + ('pow', ['ootype.Float', 'ootype.Float'], 'ootype.Float'), + ('random', [''], 'ootype.Float'), + ('round', ['ootype.Float'], 'ootype.Float'), + ('sin', ['ootype.Float'], 'ootype.Float'), + ('sqrt', ['ootype.Float'], 'ootype.Float'), + ('tan', ['ootype.Float'], 'ootype.Float'), +] +desc.Fields = [] +desc.StaticFields = [ + ('E', 'Number'), + ('LN10', 'Number'), + ('LN2', 'Number'), + ('LOG10E', 'Number'), + ('LOG2E', 'Number'), + ('PI', 'Number'), + ('SQRT1_2', 'Number'), + ('SQRT2', 'Number'), +] +types['Math'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'uint' +desc.BaseType = 'Object' +desc.Methods = [ + ('toExponential', [''], 'ootype.String'), + ('toFixed', [''], 'ootype.String'), + ('toPrecision', [''], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('!CONSTRUCTOR!', [''], None), + ('valueOf', [''], 'ootype.UnsignedLongLong'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('MAX_VALUE', 'uint'), + ('MIN_VALUE', 'uint'), +] +types['uint'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'XMLList' +desc.BaseType = 'Object' +desc.Methods = [ + ('addNamespace', [''], 'XML'), + ('appendChild', [''], 'XML'), + ('attribute', [''], 'XMLList'), + ('attributes', [''], 'XMLList'), + ('child', [''], 'XMLList'), + ('childIndex', [''], 'ootype.SignedLongLong'), + ('children', [''], 'XMLList'), + ('comments', [''], 'XMLList'), + ('contains', [''], 'ootype.Bool'), + ('copy', [''], 'XMLList'), + ('descendants', [''], 'XMLList'), + ('elements', [''], 'XMLList'), + ('hasComplexContent', [''], 'ootype.Bool'), + ('hasOwnProperty', [''], 'ootype.Bool'), + ('hasSimpleContent', [''], 'ootype.Bool'), + ('inScopeNamespaces', [''], 'ootype.List'), + ('insertChildAfter', ['', ''], ''), + ('insertChildBefore', ['', ''], ''), + ('length', [''], 'ootype.SignedLongLong'), + ('localName', [''], 'ootype.Dict'), + ('name', [''], 'ootype.Dict'), + ('namespace', [''], ''), + ('namespaceDeclarations', [''], 'ootype.List'), + ('nodeKind', [''], 'ootype.String'), + ('normalize', [''], 'XMLList'), + ('parent', [''], ''), + ('prependChild', [''], 'XML'), + ('processingInstructions', [''], 'XMLList'), + ('propertyIsEnumerable', [''], 'ootype.Bool'), + ('removeNamespace', [''], 'XML'), + ('replace', ['', ''], 'XML'), + ('setChildren', [''], 'XML'), + ('setLocalName', [''], 'ootype.Void'), + ('setName', [''], 'ootype.Void'), + ('setNamespace', [''], 'ootype.Void'), + ('text', [''], 'XMLList'), + ('toString', [''], 'ootype.String'), + ('toXMLString', [''], 'ootype.String'), + ('valueOf', [''], 'XMLList'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', '*'), +] +types['XMLList'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'URIError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['URIError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'arguments' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('callee', 'Function'), + ('length', 'Number'), +] +types['arguments'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Date' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', '', '', '', '', '', ''], None), + ('getDate', [''], 'ootype.Float'), + ('getDay', [''], 'ootype.Float'), + ('getFullYear', [''], 'ootype.Float'), + ('getHours', [''], 'ootype.Float'), + ('getMilliseconds', [''], 'ootype.Float'), + ('getMinutes', [''], 'ootype.Float'), + ('getMonth', [''], 'ootype.Float'), + ('getSeconds', [''], 'ootype.Float'), + ('getTime', [''], 'ootype.Float'), + ('getTimezoneOffset', [''], 'ootype.Float'), + ('getUTCDate', [''], 'ootype.Float'), + ('getUTCDay', [''], 'ootype.Float'), + ('getUTCFullYear', [''], 'ootype.Float'), + ('getUTCHours', [''], 'ootype.Float'), + ('getUTCMilliseconds', [''], 'ootype.Float'), + ('getUTCMinutes', [''], 'ootype.Float'), + ('getUTCMonth', [''], 'ootype.Float'), + ('getUTCSeconds', [''], 'ootype.Float'), + ('setDate', [''], 'ootype.Float'), + ('setFullYear', ['', '', ''], 'ootype.Float'), + ('setHours', ['', '', '', ''], 'ootype.Float'), + ('setMilliseconds', [''], 'ootype.Float'), + ('setMinutes', ['', '', ''], 'ootype.Float'), + ('setMonth', ['', ''], 'ootype.Float'), + ('setSeconds', ['', ''], 'ootype.Float'), + ('setTime', [''], 'ootype.Float'), + ('setUTCDate', [''], 'ootype.Float'), + ('setUTCFullYear', ['', '', ''], 'ootype.Float'), + ('setUTCHours', ['', '', '', ''], 'ootype.Float'), + ('setUTCMilliseconds', [''], 'ootype.Float'), + ('setUTCMinutes', ['', '', ''], 'ootype.Float'), + ('setUTCMonth', ['', ''], 'ootype.Float'), + ('setUTCSeconds', ['', ''], 'ootype.Float'), + ('toDateString', [''], 'ootype.String'), + ('toLocaleDateString', [''], 'ootype.String'), + ('toLocaleString', [''], 'ootype.String'), + ('toLocaleTimeString', [''], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('toTimeString', [''], 'ootype.String'), + ('toUTCString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.Float'), +] +desc.StaticMethods = [ + ('parse', [''], 'ootype.Float'), + ('UTC', ['', '', '', '', '', '', '', '*args'], 'ootype.Float'), +] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('date', 'ootype.Float'), + ('dateUTC', 'ootype.Float'), + ('day', 'ootype.Float'), + ('dayUTC', 'ootype.Float'), + ('fullYear', 'ootype.Float'), + ('fullYearUTC', 'ootype.Float'), + ('hours', 'ootype.Float'), + ('hoursUTC', 'ootype.Float'), + ('milliseconds', 'ootype.Float'), + ('millisecondsUTC', 'ootype.Float'), + ('minutes', 'ootype.Float'), + ('minutesUTC', 'ootype.Float'), + ('month', 'ootype.Float'), + ('monthUTC', 'ootype.Float'), + ('seconds', 'ootype.Float'), + ('secondsUTC', 'ootype.Float'), + ('time', 'ootype.Float'), + ('timezoneOffset', 'ootype.Float'), +] +types['Date'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'VerifyError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['VerifyError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Function' +desc.BaseType = 'Object' +desc.Methods = [ + ('apply', ['', ''], ''), + ('call', ['', '*args'], ''), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('length', 'ootype.SignedLongLong'), + ('prototype', ''), +] +types['Function'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'ReferenceError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['ReferenceError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'String' +desc.BaseType = 'Object' +desc.Methods = [ + ('charAt', ['ootype.Float'], 'ootype.String'), + ('charCodeAt', ['ootype.Float'], 'ootype.Float'), + ('concat', ['*args'], 'ootype.String'), + ('indexOf', ['ootype.String', 'ootype.Float'], 'ootype.SignedLongLong'), + ('lastIndexOf', ['ootype.String', 'ootype.Float'], 'ootype.SignedLongLong'), + ('localeCompare', ['ootype.String'], 'ootype.SignedLongLong'), + ('match', [''], 'ootype.List'), + ('replace', ['', ''], 'ootype.String'), + ('search', [''], 'ootype.SignedLongLong'), + ('slice', ['ootype.Float', 'ootype.Float'], 'ootype.String'), + ('split', ['', ''], 'ootype.List'), + ('!CONSTRUCTOR!', [''], None), + ('substr', ['ootype.Float', 'ootype.Float'], 'ootype.String'), + ('substring', ['ootype.Float', 'ootype.Float'], 'ootype.String'), + ('toLocaleLowerCase', [''], 'ootype.String'), + ('toLocaleUpperCase', [''], 'ootype.String'), + ('toLowerCase', [''], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('toUpperCase', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.String'), +] +desc.StaticMethods = [ + ('fromCharCode', ['*args'], 'ootype.String'), +] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('length', 'ootype.SignedLongLong'), +] +types['String'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'SyntaxError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['SyntaxError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'RegExp' +desc.BaseType = 'Object' +desc.Methods = [ + ('exec', ['ootype.String'], ''), + ('!CONSTRUCTOR!', ['', ''], None), + ('test', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('dotall', 'ootype.Bool'), + ('extended', 'ootype.Bool'), + ('global', 'ootype.Bool'), + ('ignoreCase', 'ootype.Bool'), + ('lastIndex', 'ootype.SignedLongLong'), + ('multiline', 'ootype.Bool'), + ('source', 'ootype.String'), +] +types['RegExp'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'SecurityError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['SecurityError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Boolean' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['Boolean'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Error' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), + ('getStackTrace', [''], 'ootype.String'), +] +desc.StaticMethods = [ + ('getErrorMessage', ['ootype.SignedLongLong'], 'ootype.String'), + ('throwError', ['Class', 'ootype.UnsignedLongLong', '*args'], ''), +] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('errorID', 'ootype.SignedLongLong'), +] +types['Error'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Object' +desc.BaseType = '*' +desc.Methods = [ + ('hasOwnProperty', [''], 'ootype.Bool'), + ('isPrototypeOf', [''], 'ootype.Bool'), + ('!CONSTRUCTOR!', [''], None), + ('propertyIsEnumerable', [''], 'ootype.Bool'), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.Dict'), + ('setPropertyIsEnumerable', ['ootype.String', 'ootype.Bool'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['Object'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Vector.' +desc.BaseType = '' +desc.Methods = [ + ('Vector', ['ootype.UnsignedLongLong', 'ootype.Bool'], 'oolean'), + ('concat', ['*args'], 'T[]'), + ('every', ['Function', 'ootype.Dict'], 'ootype.Bool'), + ('filter', ['Function', 'ootype.Dict'], 'T[]'), + ('forEach', ['Function', 'ootype.Dict'], 'ootype.Void'), + ('indexOf', ['T', 'ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('join', ['ootype.String', '"'], 'ootype.String'), + ('lastIndexOf', ['T', 'ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('map', ['Function', 'ootype.Dict'], 'T[]'), + ('pop', [''], 'T'), + ('push', ['*args'], 'ootype.UnsignedLongLong'), + ('reverse', [''], 'T[]'), + ('shift', [''], 'T'), + ('slice', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'T[]'), + ('some', ['Function', 'ootype.Dict'], 'ootype.Bool'), + ('sort', ['Function'], 'T[]'), + ('splice', ['ootype.SignedLongLong', 'ootype.UnsignedLongLong', '*args'], 'T[]'), + ('toString', [''], 'ootype.String'), + ('toLocaleString', [''], 'ootype.String'), + ('unshift', ['*args'], 'ootype.UnsignedLongLong'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['Vector.'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'authoring.authObject' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.UnsignedLongLong'], None), + ('BlendingMode', [''], 'ootype.String'), + ('Bounds', ['ootype.UnsignedLongLong', 'ootype.SignedLongLong', 'ootype.SignedLongLong'], 'flash.geom.Rectangle'), + ('CacheAsBitmap', [''], 'ootype.Bool'), + ('CenterPoint', [''], 'flash.geom.Point'), + ('ColorXForm', [''], 'flash.geom.ColorTransform'), + ('EndPosition', [''], 'ootype.SignedLongLong'), + ('Filters', [''], 'ootype.List'), + ('FrameForFrameNumber', ['ootype.SignedLongLong'], 'authoring.authObject'), + ('FrameOffset', [''], 'ootype.SignedLongLong'), + ('FrameType', [''], 'ootype.UnsignedLongLong'), + ('HasEmptyPath', [''], 'ootype.Bool'), + ('HasShapeSelection', [''], 'ootype.Bool'), + ('IsFloater', [''], 'ootype.Bool'), + ('IsPrimitive', [''], 'ootype.Bool'), + ('IsSelected', [''], 'ootype.Bool'), + ('IsVisible', ['ootype.Bool'], 'ootype.Bool'), + ('LivePreviewSize', [''], 'flash.geom.Point'), + ('Locked', [''], 'ootype.Bool'), + ('MotionPath', [''], 'authoring.authObject'), + ('ObjMatrix', [''], 'flash.geom.Matrix'), + ('OutlineColor', [''], 'ootype.UnsignedLongLong'), + ('OutlineMode', [''], 'ootype.Bool'), + ('RegistrationPoint', [''], 'flash.geom.Point'), + ('Scale9Grid', [''], 'flash.geom.Rectangle'), + ('StartPosition', [''], 'ootype.SignedLongLong'), + ('SymbolBehavior', [''], 'ootype.SignedLongLong'), + ('SymbolMode', [''], 'ootype.SignedLongLong'), + ('ThreeDMatrix', [''], 'flash.geom.Matrix3D'), + ('ThreeDTranslationHandlePoints', [''], 'ootype.List'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FirstChild', 'authoring.authObject'), + ('Key', 'ootype.UnsignedLongLong'), + ('NextSibling', 'authoring.authObject'), + ('offScreenSurfaceRenderingEnabled', 'ootype.Bool'), + ('SwfKey', 'ootype.UnsignedLongLong'), + ('Type', 'ootype.UnsignedLongLong'), +] +types['authoring.authObject'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'authoring.authObject' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.UnsignedLongLong'], None), + ('BlendingMode', [''], 'ootype.String'), + ('Bounds', ['ootype.UnsignedLongLong', 'ootype.SignedLongLong', 'ootype.SignedLongLong'], 'flash.geom.Rectangle'), + ('CacheAsBitmap', [''], 'ootype.Bool'), + ('CenterPoint', [''], 'flash.geom.Point'), + ('ColorXForm', [''], 'flash.geom.ColorTransform'), + ('EndPosition', [''], 'ootype.SignedLongLong'), + ('Filters', [''], 'ootype.List'), + ('FrameForFrameNumber', ['ootype.SignedLongLong'], 'authoring.authObject'), + ('FrameOffset', [''], 'ootype.SignedLongLong'), + ('FrameType', [''], 'ootype.UnsignedLongLong'), + ('HasEmptyPath', [''], 'ootype.Bool'), + ('HasShapeSelection', [''], 'ootype.Bool'), + ('IsFloater', [''], 'ootype.Bool'), + ('IsPrimitive', [''], 'ootype.Bool'), + ('IsSelected', [''], 'ootype.Bool'), + ('IsVisible', ['ootype.Bool'], 'ootype.Bool'), + ('LivePreviewSize', [''], 'flash.geom.Point'), + ('Locked', [''], 'ootype.Bool'), + ('MotionPath', [''], 'authoring.authObject'), + ('ObjMatrix', [''], 'flash.geom.Matrix'), + ('OutlineColor', [''], 'ootype.UnsignedLongLong'), + ('OutlineMode', [''], 'ootype.Bool'), + ('RegistrationPoint', [''], 'flash.geom.Point'), + ('Scale9Grid', [''], 'flash.geom.Rectangle'), + ('StartPosition', [''], 'ootype.SignedLongLong'), + ('SymbolBehavior', [''], 'ootype.SignedLongLong'), + ('SymbolMode', [''], 'ootype.SignedLongLong'), + ('ThreeDMatrix', [''], 'flash.geom.Matrix3D'), + ('ThreeDTranslationHandlePoints', [''], 'ootype.List'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FirstChild', 'authoring.authObject'), + ('Key', 'ootype.UnsignedLongLong'), + ('NextSibling', 'authoring.authObject'), + ('offScreenSurfaceRenderingEnabled', 'ootype.Bool'), + ('SwfKey', 'ootype.UnsignedLongLong'), + ('Type', 'ootype.UnsignedLongLong'), +] +types['authoring.authObject'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'ArgumentError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['ArgumentError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'TypeError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['TypeError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'int' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('toExponential', [''], 'ootype.String'), + ('toFixed', [''], 'ootype.String'), + ('toPrecision', [''], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.SignedLongLong'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('MAX_VALUE', 'int'), + ('MIN_VALUE', 'int'), +] +types['int'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Class' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('prototype', ''), +] +types['Class'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'XML' +desc.BaseType = 'Object' +desc.Methods = [ + ('addNamespace', [''], 'XML'), + ('appendChild', [''], 'XML'), + ('attribute', [''], 'XMLList'), + ('attributes', [''], 'XMLList'), + ('child', [''], 'XMLList'), + ('childIndex', [''], 'ootype.SignedLongLong'), + ('children', [''], 'XMLList'), + ('comments', [''], 'XMLList'), + ('contains', [''], 'ootype.Bool'), + ('copy', [''], 'XML'), + ('descendants', [''], 'XMLList'), + ('elements', [''], 'XMLList'), + ('hasComplexContent', [''], 'ootype.Bool'), + ('hasOwnProperty', [''], 'ootype.Bool'), + ('hasSimpleContent', [''], 'ootype.Bool'), + ('inScopeNamespaces', [''], 'ootype.List'), + ('insertChildAfter', ['', ''], ''), + ('insertChildBefore', ['', ''], ''), + ('length', [''], 'ootype.SignedLongLong'), + ('localName', [''], 'ootype.Dict'), + ('name', [''], 'ootype.Dict'), + ('namespace', [''], ''), + ('namespaceDeclarations', [''], 'ootype.List'), + ('nodeKind', [''], 'ootype.String'), + ('normalize', [''], 'XML'), + ('notification', [''], 'Function'), + ('parent', [''], ''), + ('prependChild', [''], 'XML'), + ('processingInstructions', [''], 'XMLList'), + ('propertyIsEnumerable', [''], 'ootype.Bool'), + ('removeNamespace', [''], 'XML'), + ('replace', ['', ''], 'XML'), + ('setChildren', [''], 'XML'), + ('setLocalName', [''], 'ootype.Void'), + ('setName', [''], 'ootype.Void'), + ('setNamespace', [''], 'ootype.Void'), + ('setNotification', ['Function'], ''), + ('text', [''], 'XMLList'), + ('toString', [''], 'ootype.String'), + ('toXMLString', [''], 'ootype.String'), + ('valueOf', [''], 'XML'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('defaultSettings', [''], 'ootype.Dict'), + ('setSettings', ['ootype.Dict'], 'ootype.Void'), + ('settings', [''], 'ootype.Dict'), +] +desc.Fields = [] +desc.StaticFields = [ + ('length', '*'), + ('ignoreComments', 'ootype.Bool'), + ('ignoreProcessingInstructions', 'ootype.Bool'), + ('ignoreWhitespace', 'ootype.Bool'), + ('prettyIndent', 'ootype.SignedLongLong'), + ('prettyPrinting', 'ootype.Bool'), +] +types['XML'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'arguments' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('callee', 'Function'), + ('length', 'Number'), +] +types['arguments'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Date' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', '', '', '', '', '', ''], None), + ('getDate', [''], 'ootype.Float'), + ('getDay', [''], 'ootype.Float'), + ('getFullYear', [''], 'ootype.Float'), + ('getHours', [''], 'ootype.Float'), + ('getMilliseconds', [''], 'ootype.Float'), + ('getMinutes', [''], 'ootype.Float'), + ('getMonth', [''], 'ootype.Float'), + ('getSeconds', [''], 'ootype.Float'), + ('getTime', [''], 'ootype.Float'), + ('getTimezoneOffset', [''], 'ootype.Float'), + ('getUTCDate', [''], 'ootype.Float'), + ('getUTCDay', [''], 'ootype.Float'), + ('getUTCFullYear', [''], 'ootype.Float'), + ('getUTCHours', [''], 'ootype.Float'), + ('getUTCMilliseconds', [''], 'ootype.Float'), + ('getUTCMinutes', [''], 'ootype.Float'), + ('getUTCMonth', [''], 'ootype.Float'), + ('getUTCSeconds', [''], 'ootype.Float'), + ('setDate', [''], 'ootype.Float'), + ('setFullYear', ['', '', ''], 'ootype.Float'), + ('setHours', ['', '', '', ''], 'ootype.Float'), + ('setMilliseconds', [''], 'ootype.Float'), + ('setMinutes', ['', '', ''], 'ootype.Float'), + ('setMonth', ['', ''], 'ootype.Float'), + ('setSeconds', ['', ''], 'ootype.Float'), + ('setTime', [''], 'ootype.Float'), + ('setUTCDate', [''], 'ootype.Float'), + ('setUTCFullYear', ['', '', ''], 'ootype.Float'), + ('setUTCHours', ['', '', '', ''], 'ootype.Float'), + ('setUTCMilliseconds', [''], 'ootype.Float'), + ('setUTCMinutes', ['', '', ''], 'ootype.Float'), + ('setUTCMonth', ['', ''], 'ootype.Float'), + ('setUTCSeconds', ['', ''], 'ootype.Float'), + ('toDateString', [''], 'ootype.String'), + ('toLocaleDateString', [''], 'ootype.String'), + ('toLocaleString', [''], 'ootype.String'), + ('toLocaleTimeString', [''], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('toTimeString', [''], 'ootype.String'), + ('toUTCString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.Float'), +] +desc.StaticMethods = [ + ('parse', [''], 'ootype.Float'), + ('UTC', ['', '', '', '', '', '', '', '*args'], 'ootype.Float'), +] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('date', 'ootype.Float'), + ('dateUTC', 'ootype.Float'), + ('day', 'ootype.Float'), + ('dayUTC', 'ootype.Float'), + ('fullYear', 'ootype.Float'), + ('fullYearUTC', 'ootype.Float'), + ('hours', 'ootype.Float'), + ('hoursUTC', 'ootype.Float'), + ('milliseconds', 'ootype.Float'), + ('millisecondsUTC', 'ootype.Float'), + ('minutes', 'ootype.Float'), + ('minutesUTC', 'ootype.Float'), + ('month', 'ootype.Float'), + ('monthUTC', 'ootype.Float'), + ('seconds', 'ootype.Float'), + ('secondsUTC', 'ootype.Float'), + ('time', 'ootype.Float'), + ('timezoneOffset', 'ootype.Float'), +] +types['Date'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Boolean' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['Boolean'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('trace', ['*args'], 'ootype.Void'), + ('decodeURI', ['ootype.String'], 'ootype.String'), + ('decodeURIComponent', ['ootype.String'], 'ootype.String'), + ('encodeURI', ['ootype.String'], 'ootype.String'), + ('encodeURIComponent', ['ootype.String'], 'ootype.String'), + ('escape', ['ootype.String'], 'ootype.String'), + ('isFinite', ['ootype.Float'], 'ootype.Bool'), + ('isNaN', ['ootype.Float'], 'ootype.Bool'), + ('isXMLName', ['ootype.String'], 'ootype.Bool'), + ('parseInt', ['ootype.String', 'ootype.UnsignedLongLong'], 'ootype.Float'), + ('parseFloat', ['ootype.String'], 'ootype.Float'), + ('unescape', ['ootype.String'], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Function' +desc.BaseType = 'Object' +desc.Methods = [ + ('apply', ['', ''], ''), + ('call', ['', '*args'], ''), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('length', 'ootype.SignedLongLong'), + ('prototype', ''), +] +types['Function'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Vector.' +desc.BaseType = '' +desc.Methods = [ + ('Vector', ['ootype.UnsignedLongLong', 'ootype.Bool'], 'oolean'), + ('concat', ['*args'], 'T[]'), + ('every', ['Function', 'ootype.Dict'], 'ootype.Bool'), + ('filter', ['Function', 'ootype.Dict'], 'T[]'), + ('forEach', ['Function', 'ootype.Dict'], 'ootype.Void'), + ('indexOf', ['T', 'ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('join', ['ootype.String', '"'], 'ootype.String'), + ('lastIndexOf', ['T', 'ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('map', ['Function', 'ootype.Dict'], 'T[]'), + ('pop', [''], 'T'), + ('push', ['*args'], 'ootype.UnsignedLongLong'), + ('reverse', [''], 'T[]'), + ('shift', [''], 'T'), + ('slice', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'T[]'), + ('some', ['Function', 'ootype.Dict'], 'ootype.Bool'), + ('sort', ['Function'], 'T[]'), + ('splice', ['ootype.SignedLongLong', 'ootype.UnsignedLongLong', '*args'], 'T[]'), + ('toString', [''], 'ootype.String'), + ('toLocaleString', [''], 'ootype.String'), + ('unshift', ['*args'], 'ootype.UnsignedLongLong'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['Vector.'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'QName' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'QName'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', '*'), + ('localName', 'ootype.String'), + ('uri', ''), +] +types['QName'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'RangeError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['RangeError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'DefinitionError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['DefinitionError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Namespace' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', '*'), + ('prefix', ''), + ('uri', 'ootype.String'), +] +types['Namespace'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'SyntaxError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['SyntaxError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'uint' +desc.BaseType = 'Object' +desc.Methods = [ + ('toExponential', [''], 'ootype.String'), + ('toFixed', [''], 'ootype.String'), + ('toPrecision', [''], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('!CONSTRUCTOR!', [''], None), + ('valueOf', [''], 'ootype.UnsignedLongLong'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('MAX_VALUE', 'uint'), + ('MIN_VALUE', 'uint'), +] +types['uint'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'ReferenceError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['ReferenceError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Math' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('abs', ['ootype.Float'], 'ootype.Float'), + ('acos', ['ootype.Float'], 'ootype.Float'), + ('asin', ['ootype.Float'], 'ootype.Float'), + ('atan', ['ootype.Float'], 'ootype.Float'), + ('atan2', ['ootype.Float', 'ootype.Float'], 'ootype.Float'), + ('ceil', ['ootype.Float'], 'ootype.Float'), + ('cos', ['ootype.Float'], 'ootype.Float'), + ('exp', ['ootype.Float'], 'ootype.Float'), + ('floor', ['ootype.Float'], 'ootype.Float'), + ('log', ['ootype.Float'], 'ootype.Float'), + ('max', ['ootype.Float', 'ootype.Float', '*args'], 'ootype.Float'), + ('min', ['ootype.Float', 'ootype.Float', '*args'], 'ootype.Float'), + ('pow', ['ootype.Float', 'ootype.Float'], 'ootype.Float'), + ('random', [''], 'ootype.Float'), + ('round', ['ootype.Float'], 'ootype.Float'), + ('sin', ['ootype.Float'], 'ootype.Float'), + ('sqrt', ['ootype.Float'], 'ootype.Float'), + ('tan', ['ootype.Float'], 'ootype.Float'), +] +desc.Fields = [] +desc.StaticFields = [ + ('E', 'Number'), + ('LN10', 'Number'), + ('LN2', 'Number'), + ('LOG10E', 'Number'), + ('LOG2E', 'Number'), + ('PI', 'Number'), + ('SQRT1_2', 'Number'), + ('SQRT2', 'Number'), +] +types['Math'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'UninitializedError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['UninitializedError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'SecurityError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['SecurityError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'RegExp' +desc.BaseType = 'Object' +desc.Methods = [ + ('exec', ['ootype.String'], ''), + ('!CONSTRUCTOR!', ['', ''], None), + ('test', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('dotall', 'ootype.Bool'), + ('extended', 'ootype.Bool'), + ('global', 'ootype.Bool'), + ('ignoreCase', 'ootype.Bool'), + ('lastIndex', 'ootype.SignedLongLong'), + ('multiline', 'ootype.Bool'), + ('source', 'ootype.String'), +] +types['RegExp'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'URIError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['URIError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'String' +desc.BaseType = 'Object' +desc.Methods = [ + ('charAt', ['ootype.Float'], 'ootype.String'), + ('charCodeAt', ['ootype.Float'], 'ootype.Float'), + ('concat', ['*args'], 'ootype.String'), + ('indexOf', ['ootype.String', 'ootype.Float'], 'ootype.SignedLongLong'), + ('lastIndexOf', ['ootype.String', 'ootype.Float'], 'ootype.SignedLongLong'), + ('localeCompare', ['ootype.String'], 'ootype.SignedLongLong'), + ('match', [''], 'ootype.List'), + ('replace', ['', ''], 'ootype.String'), + ('search', [''], 'ootype.SignedLongLong'), + ('slice', ['ootype.Float', 'ootype.Float'], 'ootype.String'), + ('split', ['', ''], 'ootype.List'), + ('!CONSTRUCTOR!', [''], None), + ('substr', ['ootype.Float', 'ootype.Float'], 'ootype.String'), + ('substring', ['ootype.Float', 'ootype.Float'], 'ootype.String'), + ('toLocaleLowerCase', [''], 'ootype.String'), + ('toLocaleUpperCase', [''], 'ootype.String'), + ('toLowerCase', [''], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('toUpperCase', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.String'), +] +desc.StaticMethods = [ + ('fromCharCode', ['*args'], 'ootype.String'), +] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('length', 'ootype.SignedLongLong'), +] +types['String'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Error' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), + ('getStackTrace', [''], 'ootype.String'), +] +desc.StaticMethods = [ + ('getErrorMessage', ['ootype.SignedLongLong'], 'ootype.String'), + ('throwError', ['Class', 'ootype.UnsignedLongLong', '*args'], ''), +] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('errorID', 'ootype.SignedLongLong'), +] +types['Error'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Object' +desc.BaseType = '*' +desc.Methods = [ + ('hasOwnProperty', [''], 'ootype.Bool'), + ('isPrototypeOf', [''], 'ootype.Bool'), + ('!CONSTRUCTOR!', [''], None), + ('propertyIsEnumerable', [''], 'ootype.Bool'), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.Dict'), + ('setPropertyIsEnumerable', ['ootype.String', 'ootype.Bool'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['Object'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Number' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('toExponential', [''], 'ootype.String'), + ('toFixed', [''], 'ootype.String'), + ('toPrecision', [''], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('valueOf', [''], 'ootype.Float'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), + ('MAX_VALUE', 'Number'), + ('MIN_VALUE', 'Number'), + ('NaN', 'Number'), + ('NEGATIVE_INFINITY', 'Number'), + ('POSITIVE_INFINITY', 'Number'), +] +types['Number'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'XMLList' +desc.BaseType = 'Object' +desc.Methods = [ + ('addNamespace', [''], 'XML'), + ('appendChild', [''], 'XML'), + ('attribute', [''], 'XMLList'), + ('attributes', [''], 'XMLList'), + ('child', [''], 'XMLList'), + ('childIndex', [''], 'ootype.SignedLongLong'), + ('children', [''], 'XMLList'), + ('comments', [''], 'XMLList'), + ('contains', [''], 'ootype.Bool'), + ('copy', [''], 'XMLList'), + ('descendants', [''], 'XMLList'), + ('elements', [''], 'XMLList'), + ('hasComplexContent', [''], 'ootype.Bool'), + ('hasOwnProperty', [''], 'ootype.Bool'), + ('hasSimpleContent', [''], 'ootype.Bool'), + ('inScopeNamespaces', [''], 'ootype.List'), + ('insertChildAfter', ['', ''], ''), + ('insertChildBefore', ['', ''], ''), + ('length', [''], 'ootype.SignedLongLong'), + ('localName', [''], 'ootype.Dict'), + ('name', [''], 'ootype.Dict'), + ('namespace', [''], ''), + ('namespaceDeclarations', [''], 'ootype.List'), + ('nodeKind', [''], 'ootype.String'), + ('normalize', [''], 'XMLList'), + ('parent', [''], ''), + ('prependChild', [''], 'XML'), + ('processingInstructions', [''], 'XMLList'), + ('propertyIsEnumerable', [''], 'ootype.Bool'), + ('removeNamespace', [''], 'XML'), + ('replace', ['', ''], 'XML'), + ('setChildren', [''], 'XML'), + ('setLocalName', [''], 'ootype.Void'), + ('setName', [''], 'ootype.Void'), + ('setNamespace', [''], 'ootype.Void'), + ('text', [''], 'XMLList'), + ('toString', [''], 'ootype.String'), + ('toXMLString', [''], 'ootype.String'), + ('valueOf', [''], 'XMLList'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', '*'), +] +types['XMLList'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'EvalError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['EvalError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'Array' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['*args'], None), + ('concat', ['*args'], 'ootype.List'), + ('every', ['Function', ''], 'ootype.Bool'), + ('filter', ['Function', ''], 'ootype.List'), + ('forEach', ['Function', ''], 'ootype.Void'), + ('indexOf', ['', ''], 'ootype.SignedLongLong'), + ('join', [''], 'ootype.String'), + ('lastIndexOf', ['', ''], 'ootype.SignedLongLong'), + ('map', ['Function', ''], 'ootype.List'), + ('pop', [''], ''), + ('push', ['*args'], 'ootype.UnsignedLongLong'), + ('reverse', [''], 'ootype.List'), + ('shift', [''], ''), + ('slice', ['', ''], 'ootype.List'), + ('some', ['Function', ''], 'ootype.Bool'), + ('sort', ['*args'], ''), + ('sortOn', ['', ''], ''), + ('splice', ['ootype.SignedLongLong', 'ootype.UnsignedLongLong', '*args'], ''), + ('unshift', ['*args'], 'ootype.UnsignedLongLong'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CASEINSENSITIVE', 'uint'), + ('DESCENDING', 'uint'), + ('length', 'int'), + ('NUMERIC', 'uint'), + ('RETURNINDEXEDARRAY', 'uint'), + ('UNIQUESORT', 'uint'), + ('length', 'ootype.UnsignedLongLong'), +] +types['Array'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'VerifyError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['', ''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'int'), +] +types['VerifyError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('showRedrawRegions', ['ootype.Bool', 'ootype.UnsignedLongLong'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('showRedrawRegions', ['ootype.Bool', 'ootype.UnsignedLongLong'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.PerspectiveProjection' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('toMatrix3D', [''], 'flash.geom.Matrix3D'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('fieldOfView', 'ootype.Float'), + ('focalLength', 'ootype.Float'), + ('projectionCenter', 'flash.geom.Point'), +] +types['flash.geom.PerspectiveProjection'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Transform' +desc.BaseType = 'Object' +desc.Methods = [ + ('getRelativeMatrix3D', ['flash.display.DisplayObject'], 'flash.geom.Matrix3D'), + ('!CONSTRUCTOR!', ['flash.display.DisplayObject'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('colorTransform', 'flash.geom.ColorTransform'), + ('concatenatedColorTransform', 'flash.geom.ColorTransform'), + ('concatenatedMatrix', 'flash.geom.Matrix'), + ('matrix', 'flash.geom.Matrix'), + ('matrix3D', 'flash.geom.Matrix3D'), + ('perspectiveProjection', 'flash.geom.PerspectiveProjection'), + ('pixelBounds', 'flash.geom.Rectangle'), +] +types['flash.geom.Transform'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Matrix3D' +desc.BaseType = 'Object' +desc.Methods = [ + ('append', ['flash.geom.Matrix3D'], 'ootype.Void'), + ('appendRotation', ['ootype.Float', 'flash.geom.Vector3D', 'flash.geom.Vector3D'], 'ootype.Void'), + ('appendScale', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('appendTranslation', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('clone', [''], 'flash.geom.Matrix3D'), + ('decompose', ['ootype.String'], 'Vector3D[]'), + ('deltaTransformVector', ['flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('identity', [''], 'ootype.Void'), + ('interpolateTo', ['flash.geom.Matrix3D', 'ootype.Float'], 'ootype.Void'), + ('invert', [''], 'ootype.Bool'), + ('!CONSTRUCTOR!', ['ootype.Float[]'], None), + ('pointAt', ['flash.geom.Vector3D', 'flash.geom.Vector3D', 'flash.geom.Vector3D'], 'ootype.Void'), + ('prepend', ['flash.geom.Matrix3D'], 'ootype.Void'), + ('prependRotation', ['ootype.Float', 'flash.geom.Vector3D', 'flash.geom.Vector3D'], 'ootype.Void'), + ('prependScale', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('prependTranslation', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('recompose', ['Vector3D[]', 'ootype.String'], 'ootype.Bool'), + ('transformVector', ['flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('transformVectors', ['ootype.Float[]', 'ootype.Float[]'], 'ootype.Void'), + ('transpose', [''], 'ootype.Void'), +] +desc.StaticMethods = [ + ('interpolate', ['flash.geom.Matrix3D', 'flash.geom.Matrix3D', 'ootype.Float'], 'flash.geom.Matrix3D'), +] +desc.Fields = [] +desc.StaticFields = [ + ('determinant', 'ootype.Float'), + ('position', 'flash.geom.Vector3D'), + ('rawData', 'ootype.Float[]'), +] +types['flash.geom.Matrix3D'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Rectangle' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.geom.Rectangle'), + ('contains', ['ootype.Float', 'ootype.Float'], 'ootype.Bool'), + ('containsPoint', ['flash.geom.Point'], 'ootype.Bool'), + ('containsRect', ['flash.geom.Rectangle'], 'ootype.Bool'), + ('equals', ['flash.geom.Rectangle'], 'ootype.Bool'), + ('inflate', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('inflatePoint', ['flash.geom.Point'], 'ootype.Void'), + ('intersection', ['flash.geom.Rectangle'], 'flash.geom.Rectangle'), + ('intersects', ['flash.geom.Rectangle'], 'ootype.Bool'), + ('isEmpty', [''], 'ootype.Bool'), + ('offset', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('offsetPoint', ['flash.geom.Point'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), + ('setEmpty', [''], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('union', ['flash.geom.Rectangle'], 'flash.geom.Rectangle'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bottom', 'ootype.Float'), + ('bottomRight', 'flash.geom.Point'), + ('left', 'ootype.Float'), + ('right', 'ootype.Float'), + ('size', 'flash.geom.Point'), + ('top', 'ootype.Float'), + ('topLeft', 'flash.geom.Point'), +] +types['flash.geom.Rectangle'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Vector3D' +desc.BaseType = 'Object' +desc.Methods = [ + ('add', ['flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('clone', [''], 'flash.geom.Vector3D'), + ('crossProduct', ['flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('decrementBy', ['flash.geom.Vector3D'], 'ootype.Void'), + ('dotProduct', ['flash.geom.Vector3D'], 'ootype.Float'), + ('equals', ['flash.geom.Vector3D', 'ootype.Bool'], 'ootype.Bool'), + ('incrementBy', ['flash.geom.Vector3D'], 'ootype.Void'), + ('nearEquals', ['flash.geom.Vector3D', 'ootype.Float', 'ootype.Bool'], 'ootype.Bool'), + ('negate', [''], 'ootype.Void'), + ('normalize', [''], 'ootype.Float'), + ('project', [''], 'ootype.Void'), + ('scaleBy', ['ootype.Float'], 'ootype.Void'), + ('subtract', ['flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('toString', [''], 'ootype.String'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [ + ('angleBetween', ['flash.geom.Vector3D', 'flash.geom.Vector3D'], 'ootype.Float'), + ('distance', ['flash.geom.Vector3D', 'flash.geom.Vector3D'], 'ootype.Float'), +] +desc.Fields = [] +desc.StaticFields = [ + ('X_AXIS', 'Vector3D'), + ('Y_AXIS', 'Vector3D'), + ('Z_AXIS', 'Vector3D'), + ('length', 'ootype.Float'), + ('lengthSquared', 'ootype.Float'), +] +types['flash.geom.Vector3D'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Utils3D' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('pointTowards', ['ootype.Float', 'flash.geom.Matrix3D', 'flash.geom.Vector3D', 'flash.geom.Vector3D', 'flash.geom.Vector3D'], 'flash.geom.Matrix3D'), + ('projectVector', ['flash.geom.Matrix3D', 'flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('projectVectors', ['flash.geom.Matrix3D', 'ootype.Float[]', 'ootype.Float[]', 'ootype.Float[]'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [] +types['flash.geom.Utils3D'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Orientation3D' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('AXIS_ANGLE', 'String'), + ('EULER_ANGLES', 'String'), + ('QUATERNION', 'String'), +] +types['flash.geom.Orientation3D'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Matrix' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.geom.Matrix'), + ('concat', ['flash.geom.Matrix'], 'ootype.Void'), + ('createBox', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('createGradientBox', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('deltaTransformPoint', ['flash.geom.Point'], 'flash.geom.Point'), + ('identity', [''], 'ootype.Void'), + ('invert', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), + ('rotate', ['ootype.Float'], 'ootype.Void'), + ('scale', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('transformPoint', ['flash.geom.Point'], 'flash.geom.Point'), + ('translate', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.geom.Matrix'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.ColorTransform' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), + ('concat', ['flash.geom.ColorTransform'], 'ootype.Void'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('color', 'ootype.UnsignedLongLong'), +] +types['flash.geom.ColorTransform'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Point' +desc.BaseType = 'Object' +desc.Methods = [ + ('add', ['flash.geom.Point'], 'flash.geom.Point'), + ('clone', [''], 'flash.geom.Point'), + ('equals', ['flash.geom.Point'], 'ootype.Bool'), + ('normalize', ['ootype.Float'], 'ootype.Void'), + ('offset', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float'], None), + ('subtract', ['flash.geom.Point'], 'flash.geom.Point'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [ + ('distance', ['flash.geom.Point', 'flash.geom.Point'], 'ootype.Float'), + ('interpolate', ['flash.geom.Point', 'flash.geom.Point', 'ootype.Float'], 'flash.geom.Point'), + ('polar', ['ootype.Float', 'ootype.Float'], 'flash.geom.Point'), +] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'ootype.Float'), +] +types['flash.geom.Point'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.PerspectiveProjection' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('toMatrix3D', [''], 'flash.geom.Matrix3D'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('fieldOfView', 'ootype.Float'), + ('focalLength', 'ootype.Float'), + ('projectionCenter', 'flash.geom.Point'), +] +types['flash.geom.PerspectiveProjection'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Matrix' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.geom.Matrix'), + ('concat', ['flash.geom.Matrix'], 'ootype.Void'), + ('createBox', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('createGradientBox', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('deltaTransformPoint', ['flash.geom.Point'], 'flash.geom.Point'), + ('identity', [''], 'ootype.Void'), + ('invert', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), + ('rotate', ['ootype.Float'], 'ootype.Void'), + ('scale', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('transformPoint', ['flash.geom.Point'], 'flash.geom.Point'), + ('translate', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.geom.Matrix'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.ColorTransform' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), + ('concat', ['flash.geom.ColorTransform'], 'ootype.Void'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('color', 'ootype.UnsignedLongLong'), +] +types['flash.geom.ColorTransform'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Matrix3D' +desc.BaseType = 'Object' +desc.Methods = [ + ('append', ['flash.geom.Matrix3D'], 'ootype.Void'), + ('appendRotation', ['ootype.Float', 'flash.geom.Vector3D', 'flash.geom.Vector3D'], 'ootype.Void'), + ('appendScale', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('appendTranslation', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('clone', [''], 'flash.geom.Matrix3D'), + ('decompose', ['ootype.String'], 'Vector3D[]'), + ('deltaTransformVector', ['flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('identity', [''], 'ootype.Void'), + ('interpolateTo', ['flash.geom.Matrix3D', 'ootype.Float'], 'ootype.Void'), + ('invert', [''], 'ootype.Bool'), + ('!CONSTRUCTOR!', ['ootype.Float[]'], None), + ('pointAt', ['flash.geom.Vector3D', 'flash.geom.Vector3D', 'flash.geom.Vector3D'], 'ootype.Void'), + ('prepend', ['flash.geom.Matrix3D'], 'ootype.Void'), + ('prependRotation', ['ootype.Float', 'flash.geom.Vector3D', 'flash.geom.Vector3D'], 'ootype.Void'), + ('prependScale', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('prependTranslation', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('recompose', ['Vector3D[]', 'ootype.String'], 'ootype.Bool'), + ('transformVector', ['flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('transformVectors', ['ootype.Float[]', 'ootype.Float[]'], 'ootype.Void'), + ('transpose', [''], 'ootype.Void'), +] +desc.StaticMethods = [ + ('interpolate', ['flash.geom.Matrix3D', 'flash.geom.Matrix3D', 'ootype.Float'], 'flash.geom.Matrix3D'), +] +desc.Fields = [] +desc.StaticFields = [ + ('determinant', 'ootype.Float'), + ('position', 'flash.geom.Vector3D'), + ('rawData', 'ootype.Float[]'), +] +types['flash.geom.Matrix3D'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Utils3D' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('pointTowards', ['ootype.Float', 'flash.geom.Matrix3D', 'flash.geom.Vector3D', 'flash.geom.Vector3D', 'flash.geom.Vector3D'], 'flash.geom.Matrix3D'), + ('projectVector', ['flash.geom.Matrix3D', 'flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('projectVectors', ['flash.geom.Matrix3D', 'ootype.Float[]', 'ootype.Float[]', 'ootype.Float[]'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [] +types['flash.geom.Utils3D'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Orientation3D' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('AXIS_ANGLE', 'String'), + ('EULER_ANGLES', 'String'), + ('QUATERNION', 'String'), +] +types['flash.geom.Orientation3D'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Vector3D' +desc.BaseType = 'Object' +desc.Methods = [ + ('add', ['flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('clone', [''], 'flash.geom.Vector3D'), + ('crossProduct', ['flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('decrementBy', ['flash.geom.Vector3D'], 'ootype.Void'), + ('dotProduct', ['flash.geom.Vector3D'], 'ootype.Float'), + ('equals', ['flash.geom.Vector3D', 'ootype.Bool'], 'ootype.Bool'), + ('incrementBy', ['flash.geom.Vector3D'], 'ootype.Void'), + ('nearEquals', ['flash.geom.Vector3D', 'ootype.Float', 'ootype.Bool'], 'ootype.Bool'), + ('negate', [''], 'ootype.Void'), + ('normalize', [''], 'ootype.Float'), + ('project', [''], 'ootype.Void'), + ('scaleBy', ['ootype.Float'], 'ootype.Void'), + ('subtract', ['flash.geom.Vector3D'], 'flash.geom.Vector3D'), + ('toString', [''], 'ootype.String'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [ + ('angleBetween', ['flash.geom.Vector3D', 'flash.geom.Vector3D'], 'ootype.Float'), + ('distance', ['flash.geom.Vector3D', 'flash.geom.Vector3D'], 'ootype.Float'), +] +desc.Fields = [] +desc.StaticFields = [ + ('X_AXIS', 'Vector3D'), + ('Y_AXIS', 'Vector3D'), + ('Z_AXIS', 'Vector3D'), + ('length', 'ootype.Float'), + ('lengthSquared', 'ootype.Float'), +] +types['flash.geom.Vector3D'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Rectangle' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.geom.Rectangle'), + ('contains', ['ootype.Float', 'ootype.Float'], 'ootype.Bool'), + ('containsPoint', ['flash.geom.Point'], 'ootype.Bool'), + ('containsRect', ['flash.geom.Rectangle'], 'ootype.Bool'), + ('equals', ['flash.geom.Rectangle'], 'ootype.Bool'), + ('inflate', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('inflatePoint', ['flash.geom.Point'], 'ootype.Void'), + ('intersection', ['flash.geom.Rectangle'], 'flash.geom.Rectangle'), + ('intersects', ['flash.geom.Rectangle'], 'ootype.Bool'), + ('isEmpty', [''], 'ootype.Bool'), + ('offset', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('offsetPoint', ['flash.geom.Point'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), + ('setEmpty', [''], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('union', ['flash.geom.Rectangle'], 'flash.geom.Rectangle'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bottom', 'ootype.Float'), + ('bottomRight', 'flash.geom.Point'), + ('left', 'ootype.Float'), + ('right', 'ootype.Float'), + ('size', 'flash.geom.Point'), + ('top', 'ootype.Float'), + ('topLeft', 'flash.geom.Point'), +] +types['flash.geom.Rectangle'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Transform' +desc.BaseType = 'Object' +desc.Methods = [ + ('getRelativeMatrix3D', ['flash.display.DisplayObject'], 'flash.geom.Matrix3D'), + ('!CONSTRUCTOR!', ['flash.display.DisplayObject'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('colorTransform', 'flash.geom.ColorTransform'), + ('concatenatedColorTransform', 'flash.geom.ColorTransform'), + ('concatenatedMatrix', 'flash.geom.Matrix'), + ('matrix', 'flash.geom.Matrix'), + ('matrix3D', 'flash.geom.Matrix3D'), + ('perspectiveProjection', 'flash.geom.PerspectiveProjection'), + ('pixelBounds', 'flash.geom.Rectangle'), +] +types['flash.geom.Transform'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.geom.Point' +desc.BaseType = 'Object' +desc.Methods = [ + ('add', ['flash.geom.Point'], 'flash.geom.Point'), + ('clone', [''], 'flash.geom.Point'), + ('equals', ['flash.geom.Point'], 'ootype.Bool'), + ('normalize', ['ootype.Float'], 'ootype.Void'), + ('offset', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float'], None), + ('subtract', ['flash.geom.Point'], 'flash.geom.Point'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [ + ('distance', ['flash.geom.Point', 'flash.geom.Point'], 'ootype.Float'), + ('interpolate', ['flash.geom.Point', 'flash.geom.Point', 'ootype.Float'], 'flash.geom.Point'), + ('polar', ['ootype.Float', 'ootype.Float'], 'flash.geom.Point'), +] +desc.Fields = [] +desc.StaticFields = [ + ('length', 'ootype.Float'), +] +types['flash.geom.Point'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.SampleDataEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Float', 'flash.utils.ByteArray'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('SAMPLE_DATA', 'String'), + ('data', 'flash.utils.ByteArray'), + ('position', 'ootype.Float'), +] +types['flash.events.SampleDataEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.KeyboardEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool'], None), + ('toString', [''], 'ootype.String'), + ('updateAfterEvent', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('KEY_DOWN', 'String'), + ('KEY_UP', 'String'), + ('altKey', 'ootype.Bool'), + ('charCode', 'ootype.UnsignedLongLong'), + ('ctrlKey', 'ootype.Bool'), + ('keyCode', 'ootype.UnsignedLongLong'), + ('keyLocation', 'ootype.UnsignedLongLong'), + ('shiftKey', 'ootype.Bool'), +] +types['flash.events.KeyboardEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.NetStatusEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Dict'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('NET_STATUS', 'String'), + ('info', 'ootype.Dict'), +] +types['flash.events.NetStatusEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.IMEEvent' +desc.BaseType = 'TextEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('IME_COMPOSITION', 'String'), +] +types['flash.events.IMEEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.NetFilterEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'flash.utils.ByteArray', 'flash.utils.ByteArray'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.events.NetFilterEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.SyncEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.List'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('SYNC', 'String'), + ('changeList', 'ootype.List'), +] +types['flash.events.SyncEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.ProgressEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('PROGRESS', 'String'), + ('SOCKET_DATA', 'String'), + ('bytesLoaded', 'ootype.UnsignedLongLong'), + ('bytesTotal', 'ootype.UnsignedLongLong'), +] +types['flash.events.ProgressEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.EventPhase' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('AT_TARGET', 'uint'), + ('BUBBLING_PHASE', 'uint'), + ('CAPTURING_PHASE', 'uint'), +] +types['flash.events.EventPhase'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.ContextMenuEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'flash.display.InteractiveObject', 'flash.display.InteractiveObject'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('MENU_ITEM_SELECT', 'String'), + ('MENU_SELECT', 'String'), + ('contextMenuOwner', 'flash.display.InteractiveObject'), + ('isMouseTargetInaccessible', 'ootype.Bool'), + ('mouseTarget', 'flash.display.InteractiveObject'), +] +types['flash.events.ContextMenuEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.TimerEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool'], None), + ('toString', [''], 'ootype.String'), + ('updateAfterEvent', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('TIMER', 'String'), + ('TIMER_COMPLETE', 'String'), +] +types['flash.events.TimerEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.EventDispatcher' +desc.BaseType = 'Object' +desc.Methods = [ + ('addEventListener', ['ootype.String', 'Function', 'ootype.Bool', 'ootype.SignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('dispatchEvent', ['flash.events.Event'], 'ootype.Bool'), + ('!CONSTRUCTOR!', ['flash.events.IEventDispatcher'], None), + ('hasEventListener', ['ootype.String'], 'ootype.Bool'), + ('removeEventListener', ['ootype.String', 'Function', 'ootype.Bool'], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('willTrigger', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.events.EventDispatcher'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.ShaderEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'flash.display.BitmapData', 'flash.utils.ByteArray', 'ootype.Float[]'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('COMPLETE', 'String'), + ('bitmapData', 'flash.display.BitmapData'), + ('byteArray', 'flash.utils.ByteArray'), + ('vector', 'ootype.Float[]'), +] +types['flash.events.ShaderEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.AsyncErrorEvent' +desc.BaseType = 'ErrorEvent' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String', 'Error'], None), + ('clone', [''], 'flash.events.Event'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ASYNC_ERROR', 'String'), +] +types['flash.events.AsyncErrorEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.TextEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('LINK', 'String'), + ('TEXT_INPUT', 'String'), + ('text', 'ootype.String'), +] +types['flash.events.TextEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.WeakFunctionClosure' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.events.WeakFunctionClosure'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.SecurityErrorEvent' +desc.BaseType = 'ErrorEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('SECURITY_ERROR', 'String'), +] +types['flash.events.SecurityErrorEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('addEventListener', ['ootype.String', 'Function', 'ootype.Bool', 'ootype.SignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('dispatchEvent', ['flash.events.Event'], 'ootype.Bool'), + ('hasEventListener', ['ootype.String'], 'ootype.Bool'), + ('removeEventListener', ['ootype.String', 'Function', 'ootype.Bool'], 'ootype.Void'), + ('willTrigger', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.FocusEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'flash.display.InteractiveObject', 'ootype.Bool', 'ootype.UnsignedLongLong'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FOCUS_IN', 'String'), + ('FOCUS_OUT', 'String'), + ('KEY_FOCUS_CHANGE', 'String'), + ('MOUSE_FOCUS_CHANGE', 'String'), + ('isRelatedObjectInaccessible', 'ootype.Bool'), + ('keyCode', 'ootype.UnsignedLongLong'), + ('relatedObject', 'flash.display.InteractiveObject'), + ('shiftKey', 'ootype.Bool'), +] +types['flash.events.FocusEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.HTTPStatusEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.SignedLongLong'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('HTTP_STATUS', 'String'), + ('status', 'ootype.SignedLongLong'), +] +types['flash.events.HTTPStatusEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.ErrorEvent' +desc.BaseType = 'TextEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ERROR', 'String'), +] +types['flash.events.ErrorEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.Event' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool'], None), + ('formatToString', ['ootype.String', '*args'], 'ootype.String'), + ('isDefaultPrevented', [''], 'ootype.Bool'), + ('preventDefault', [''], 'ootype.Void'), + ('stopImmediatePropagation', [''], 'ootype.Void'), + ('stopPropagation', [''], 'ootype.Void'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ACTIVATE', 'String'), + ('ADDED', 'String'), + ('ADDED_TO_STAGE', 'String'), + ('CANCEL', 'String'), + ('CHANGE', 'String'), + ('CLEAR', 'String'), + ('CLOSE', 'String'), + ('COMPLETE', 'String'), + ('CONNECT', 'String'), + ('COPY', 'String'), + ('CUT', 'String'), + ('DEACTIVATE', 'String'), + ('ENTER_FRAME', 'String'), + ('EXIT_FRAME', 'String'), + ('FRAME_CONSTRUCTED', 'String'), + ('FULLSCREEN', 'String'), + ('ID3', 'String'), + ('INIT', 'String'), + ('MOUSE_LEAVE', 'String'), + ('OPEN', 'String'), + ('PASTE', 'String'), + ('REMOVED', 'String'), + ('REMOVED_FROM_STAGE', 'String'), + ('RENDER', 'String'), + ('RESIZE', 'String'), + ('SCROLL', 'String'), + ('SELECT', 'String'), + ('SELECT_ALL', 'String'), + ('SOUND_COMPLETE', 'String'), + ('TAB_CHILDREN_CHANGE', 'String'), + ('TAB_ENABLED_CHANGE', 'String'), + ('TAB_INDEX_CHANGE', 'String'), + ('UNLOAD', 'String'), + ('bubbles', 'ootype.Bool'), + ('cancelable', 'ootype.Bool'), + ('currentTarget', 'ootype.Dict'), + ('eventPhase', 'ootype.UnsignedLongLong'), + ('target', 'ootype.Dict'), + ('type', 'ootype.String'), +] +types['flash.events.Event'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.MouseEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Float', 'ootype.Float', 'flash.display.InteractiveObject', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool', 'ootype.SignedLongLong'], None), + ('toString', [''], 'ootype.String'), + ('updateAfterEvent', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CLICK', 'String'), + ('DOUBLE_CLICK', 'String'), + ('MOUSE_DOWN', 'String'), + ('MOUSE_MOVE', 'String'), + ('MOUSE_OUT', 'String'), + ('MOUSE_OVER', 'String'), + ('MOUSE_UP', 'String'), + ('MOUSE_WHEEL', 'String'), + ('ROLL_OUT', 'String'), + ('ROLL_OVER', 'String'), + ('altKey', 'ootype.Bool'), + ('buttonDown', 'ootype.Bool'), + ('ctrlKey', 'ootype.Bool'), + ('delta', 'ootype.SignedLongLong'), + ('isRelatedObjectInaccessible', 'ootype.Bool'), + ('localX', 'ootype.Float'), + ('localY', 'ootype.Float'), + ('relatedObject', 'flash.display.InteractiveObject'), + ('shiftKey', 'ootype.Bool'), + ('stageX', 'ootype.Float'), + ('stageY', 'ootype.Float'), +] +types['flash.events.MouseEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.StatusEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('STATUS', 'String'), + ('code', 'ootype.String'), + ('level', 'ootype.String'), +] +types['flash.events.StatusEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.ActivityEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool'], None), + ('clone', [''], 'flash.events.Event'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ACTIVITY', 'String'), + ('activating', 'ootype.Bool'), +] +types['flash.events.ActivityEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.WeakMethodClosure' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.events.WeakMethodClosure'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.IOErrorEvent' +desc.BaseType = 'ErrorEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DISK_ERROR', 'String'), + ('IO_ERROR', 'String'), + ('NETWORK_ERROR', 'String'), + ('VERIFY_ERROR', 'String'), +] +types['flash.events.IOErrorEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.FullScreenEvent' +desc.BaseType = 'ActivityEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FULL_SCREEN', 'String'), + ('fullScreen', 'ootype.Bool'), +] +types['flash.events.FullScreenEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.DataEvent' +desc.BaseType = 'TextEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DATA', 'String'), + ('UPLOAD_COMPLETE_DATA', 'String'), + ('data', 'ootype.String'), +] +types['flash.events.DataEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.SampleDataEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Float', 'flash.utils.ByteArray'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('SAMPLE_DATA', 'String'), + ('data', 'flash.utils.ByteArray'), + ('position', 'ootype.Float'), +] +types['flash.events.SampleDataEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.Event' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool'], None), + ('formatToString', ['ootype.String', '*args'], 'ootype.String'), + ('isDefaultPrevented', [''], 'ootype.Bool'), + ('preventDefault', [''], 'ootype.Void'), + ('stopImmediatePropagation', [''], 'ootype.Void'), + ('stopPropagation', [''], 'ootype.Void'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ACTIVATE', 'String'), + ('ADDED', 'String'), + ('ADDED_TO_STAGE', 'String'), + ('CANCEL', 'String'), + ('CHANGE', 'String'), + ('CLEAR', 'String'), + ('CLOSE', 'String'), + ('COMPLETE', 'String'), + ('CONNECT', 'String'), + ('COPY', 'String'), + ('CUT', 'String'), + ('DEACTIVATE', 'String'), + ('ENTER_FRAME', 'String'), + ('EXIT_FRAME', 'String'), + ('FRAME_CONSTRUCTED', 'String'), + ('FULLSCREEN', 'String'), + ('ID3', 'String'), + ('INIT', 'String'), + ('MOUSE_LEAVE', 'String'), + ('OPEN', 'String'), + ('PASTE', 'String'), + ('REMOVED', 'String'), + ('REMOVED_FROM_STAGE', 'String'), + ('RENDER', 'String'), + ('RESIZE', 'String'), + ('SCROLL', 'String'), + ('SELECT', 'String'), + ('SELECT_ALL', 'String'), + ('SOUND_COMPLETE', 'String'), + ('TAB_CHILDREN_CHANGE', 'String'), + ('TAB_ENABLED_CHANGE', 'String'), + ('TAB_INDEX_CHANGE', 'String'), + ('UNLOAD', 'String'), + ('bubbles', 'ootype.Bool'), + ('cancelable', 'ootype.Bool'), + ('currentTarget', 'ootype.Dict'), + ('eventPhase', 'ootype.UnsignedLongLong'), + ('target', 'ootype.Dict'), + ('type', 'ootype.String'), +] +types['flash.events.Event'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.AsyncErrorEvent' +desc.BaseType = 'ErrorEvent' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String', 'Error'], None), + ('clone', [''], 'flash.events.Event'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ASYNC_ERROR', 'String'), +] +types['flash.events.AsyncErrorEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.EventPhase' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('AT_TARGET', 'uint'), + ('BUBBLING_PHASE', 'uint'), + ('CAPTURING_PHASE', 'uint'), +] +types['flash.events.EventPhase'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.IOErrorEvent' +desc.BaseType = 'ErrorEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DISK_ERROR', 'String'), + ('IO_ERROR', 'String'), + ('NETWORK_ERROR', 'String'), + ('VERIFY_ERROR', 'String'), +] +types['flash.events.IOErrorEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.StatusEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('STATUS', 'String'), + ('code', 'ootype.String'), + ('level', 'ootype.String'), +] +types['flash.events.StatusEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.DataEvent' +desc.BaseType = 'TextEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DATA', 'String'), + ('UPLOAD_COMPLETE_DATA', 'String'), + ('data', 'ootype.String'), +] +types['flash.events.DataEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.WeakFunctionClosure' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.events.WeakFunctionClosure'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.WeakMethodClosure' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.events.WeakMethodClosure'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.SecurityErrorEvent' +desc.BaseType = 'ErrorEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('SECURITY_ERROR', 'String'), +] +types['flash.events.SecurityErrorEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.TextEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('LINK', 'String'), + ('TEXT_INPUT', 'String'), + ('text', 'ootype.String'), +] +types['flash.events.TextEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.ShaderEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'flash.display.BitmapData', 'flash.utils.ByteArray', 'ootype.Float[]'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('COMPLETE', 'String'), + ('bitmapData', 'flash.display.BitmapData'), + ('byteArray', 'flash.utils.ByteArray'), + ('vector', 'ootype.Float[]'), +] +types['flash.events.ShaderEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.NetStatusEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Dict'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('NET_STATUS', 'String'), + ('info', 'ootype.Dict'), +] +types['flash.events.NetStatusEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.MouseEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Float', 'ootype.Float', 'flash.display.InteractiveObject', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool', 'ootype.SignedLongLong'], None), + ('toString', [''], 'ootype.String'), + ('updateAfterEvent', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CLICK', 'String'), + ('DOUBLE_CLICK', 'String'), + ('MOUSE_DOWN', 'String'), + ('MOUSE_MOVE', 'String'), + ('MOUSE_OUT', 'String'), + ('MOUSE_OVER', 'String'), + ('MOUSE_UP', 'String'), + ('MOUSE_WHEEL', 'String'), + ('ROLL_OUT', 'String'), + ('ROLL_OVER', 'String'), + ('altKey', 'ootype.Bool'), + ('buttonDown', 'ootype.Bool'), + ('ctrlKey', 'ootype.Bool'), + ('delta', 'ootype.SignedLongLong'), + ('isRelatedObjectInaccessible', 'ootype.Bool'), + ('localX', 'ootype.Float'), + ('localY', 'ootype.Float'), + ('relatedObject', 'flash.display.InteractiveObject'), + ('shiftKey', 'ootype.Bool'), + ('stageX', 'ootype.Float'), + ('stageY', 'ootype.Float'), +] +types['flash.events.MouseEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.IMEEvent' +desc.BaseType = 'TextEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('IME_COMPOSITION', 'String'), +] +types['flash.events.IMEEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.HTTPStatusEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.SignedLongLong'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('HTTP_STATUS', 'String'), + ('status', 'ootype.SignedLongLong'), +] +types['flash.events.HTTPStatusEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.ContextMenuEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'flash.display.InteractiveObject', 'flash.display.InteractiveObject'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('MENU_ITEM_SELECT', 'String'), + ('MENU_SELECT', 'String'), + ('contextMenuOwner', 'flash.display.InteractiveObject'), + ('isMouseTargetInaccessible', 'ootype.Bool'), + ('mouseTarget', 'flash.display.InteractiveObject'), +] +types['flash.events.ContextMenuEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.NetFilterEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'flash.utils.ByteArray', 'flash.utils.ByteArray'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.events.NetFilterEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.ActivityEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool'], None), + ('clone', [''], 'flash.events.Event'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ACTIVITY', 'String'), + ('activating', 'ootype.Bool'), +] +types['flash.events.ActivityEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.EventDispatcher' +desc.BaseType = 'Object' +desc.Methods = [ + ('addEventListener', ['ootype.String', 'Function', 'ootype.Bool', 'ootype.SignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('dispatchEvent', ['flash.events.Event'], 'ootype.Bool'), + ('!CONSTRUCTOR!', ['flash.events.IEventDispatcher'], None), + ('hasEventListener', ['ootype.String'], 'ootype.Bool'), + ('removeEventListener', ['ootype.String', 'Function', 'ootype.Bool'], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('willTrigger', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.events.EventDispatcher'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.ErrorEvent' +desc.BaseType = 'TextEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.String'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ERROR', 'String'), +] +types['flash.events.ErrorEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.TimerEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool'], None), + ('toString', [''], 'ootype.String'), + ('updateAfterEvent', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('TIMER', 'String'), + ('TIMER_COMPLETE', 'String'), +] +types['flash.events.TimerEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('addEventListener', ['ootype.String', 'Function', 'ootype.Bool', 'ootype.SignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('dispatchEvent', ['flash.events.Event'], 'ootype.Bool'), + ('hasEventListener', ['ootype.String'], 'ootype.Bool'), + ('removeEventListener', ['ootype.String', 'Function', 'ootype.Bool'], 'ootype.Void'), + ('willTrigger', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.ProgressEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('PROGRESS', 'String'), + ('SOCKET_DATA', 'String'), + ('bytesLoaded', 'ootype.UnsignedLongLong'), + ('bytesTotal', 'ootype.UnsignedLongLong'), +] +types['flash.events.ProgressEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.SyncEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.List'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('SYNC', 'String'), + ('changeList', 'ootype.List'), +] +types['flash.events.SyncEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.KeyboardEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool'], None), + ('toString', [''], 'ootype.String'), + ('updateAfterEvent', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('KEY_DOWN', 'String'), + ('KEY_UP', 'String'), + ('altKey', 'ootype.Bool'), + ('charCode', 'ootype.UnsignedLongLong'), + ('ctrlKey', 'ootype.Bool'), + ('keyCode', 'ootype.UnsignedLongLong'), + ('keyLocation', 'ootype.UnsignedLongLong'), + ('shiftKey', 'ootype.Bool'), +] +types['flash.events.KeyboardEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.FullScreenEvent' +desc.BaseType = 'ActivityEvent' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FULL_SCREEN', 'String'), + ('fullScreen', 'ootype.Bool'), +] +types['flash.events.FullScreenEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.events.FocusEvent' +desc.BaseType = 'Event' +desc.Methods = [ + ('clone', [''], 'flash.events.Event'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'flash.display.InteractiveObject', 'ootype.Bool', 'ootype.UnsignedLongLong'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FOCUS_IN', 'String'), + ('FOCUS_OUT', 'String'), + ('KEY_FOCUS_CHANGE', 'String'), + ('MOUSE_FOCUS_CHANGE', 'String'), + ('isRelatedObjectInaccessible', 'ootype.Bool'), + ('keyCode', 'ootype.UnsignedLongLong'), + ('relatedObject', 'flash.display.InteractiveObject'), + ('shiftKey', 'ootype.Bool'), +] +types['flash.events.FocusEvent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.trace.Trace' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('getLevel', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getListener', [''], 'Function'), + ('setLevel', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], ''), + ('setListener', ['Function'], ''), +] +desc.Fields = [] +desc.StaticFields = [ + ('FILE', '*'), + ('LISTENER', '*'), + ('METHODS', 'int'), + ('METHODS_AND_LINES', 'int'), + ('METHODS_AND_LINES_WITH_ARGS', 'int'), + ('METHODS_WITH_ARGS', 'int'), + ('OFF', 'int'), +] +types['flash.trace.Trace'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.trace.Trace' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('getLevel', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getListener', [''], 'Function'), + ('setLevel', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], ''), + ('setListener', ['Function'], ''), +] +desc.Fields = [] +desc.StaticFields = [ + ('FILE', '*'), + ('LISTENER', '*'), + ('METHODS', 'int'), + ('METHODS_AND_LINES', 'int'), + ('METHODS_AND_LINES_WITH_ARGS', 'int'), + ('METHODS_WITH_ARGS', 'int'), + ('OFF', 'int'), +] +types['flash.trace.Trace'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.Socket' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('close', [''], 'ootype.Void'), + ('connect', ['ootype.String', 'ootype.SignedLongLong'], 'ootype.Void'), + ('flush', [''], 'ootype.Void'), + ('readBoolean', [''], 'ootype.Bool'), + ('readByte', [''], 'ootype.SignedLongLong'), + ('readBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('readDouble', [''], 'ootype.Float'), + ('readFloat', [''], 'ootype.Float'), + ('readInt', [''], 'ootype.SignedLongLong'), + ('readMultiByte', ['ootype.UnsignedLongLong', 'ootype.String'], 'ootype.String'), + ('readObject', [''], ''), + ('readShort', [''], 'ootype.SignedLongLong'), + ('readUnsignedByte', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedInt', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedShort', [''], 'ootype.UnsignedLongLong'), + ('readUTF', [''], 'ootype.String'), + ('readUTFBytes', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), + ('writeBoolean', ['ootype.Bool'], 'ootype.Void'), + ('writeByte', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeDouble', ['ootype.Float'], 'ootype.Void'), + ('writeFloat', ['ootype.Float'], 'ootype.Void'), + ('writeInt', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeMultiByte', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('writeObject', [''], 'ootype.Void'), + ('writeShort', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeUnsignedInt', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeUTF', ['ootype.String'], 'ootype.Void'), + ('writeUTFBytes', ['ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesAvailable', 'ootype.UnsignedLongLong'), + ('connected', 'ootype.Bool'), + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), + ('timeout', 'ootype.UnsignedLongLong'), +] +types['flash.net.Socket'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.SharedObjectFlushStatus' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FLUSHED', 'String'), + ('PENDING', 'String'), +] +types['flash.net.SharedObjectFlushStatus'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('writeDynamicProperties', ['ootype.Dict', 'flash.net.IDynamicPropertyOutput'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLRequestHeader' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.URLRequestHeader'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLRequestMethod' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('GET', 'String'), + ('POST', 'String'), +] +types['flash.net.URLRequestMethod'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLStream' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('close', [''], 'ootype.Void'), + ('load', ['flash.net.URLRequest'], 'ootype.Void'), + ('readBoolean', [''], 'ootype.Bool'), + ('readByte', [''], 'ootype.SignedLongLong'), + ('readBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('readDouble', [''], 'ootype.Float'), + ('readFloat', [''], 'ootype.Float'), + ('readInt', [''], 'ootype.SignedLongLong'), + ('readMultiByte', ['ootype.UnsignedLongLong', 'ootype.String'], 'ootype.String'), + ('readObject', [''], ''), + ('readShort', [''], 'ootype.SignedLongLong'), + ('readUnsignedByte', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedInt', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedShort', [''], 'ootype.UnsignedLongLong'), + ('readUTF', [''], 'ootype.String'), + ('readUTFBytes', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesAvailable', 'ootype.UnsignedLongLong'), + ('connected', 'ootype.Bool'), + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), +] +types['flash.net.URLStream'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.FileReference' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('browse', ['ootype.List'], 'ootype.Bool'), + ('cancel', [''], 'ootype.Void'), + ('download', ['flash.net.URLRequest', 'ootype.String'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('load', [''], 'ootype.Void'), + ('save', ['', 'ootype.String'], 'ootype.Void'), + ('upload', ['flash.net.URLRequest', 'ootype.String', 'ootype.Bool'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('creationDate', 'Date'), + ('creator', 'ootype.String'), + ('data', 'flash.utils.ByteArray'), + ('modificationDate', 'Date'), + ('name', 'ootype.String'), + ('size', 'ootype.UnsignedLongLong'), + ('type', 'ootype.String'), +] +types['flash.net.FileReference'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.Responder' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['Function', 'Function'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.Responder'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.FileReferenceList' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('browse', ['ootype.List'], 'ootype.Bool'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('fileList', 'ootype.List'), +] +types['flash.net.FileReferenceList'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.NetStreamPlayTransitions' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('APPEND', '*'), + ('RESET', '*'), + ('STOP', '*'), + ('SWAP', '*'), + ('SWITCH', '*'), +] +types['flash.net.NetStreamPlayTransitions'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.LocalConnection' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('allowDomain', ['*args'], 'ootype.Void'), + ('allowInsecureDomain', ['*args'], 'ootype.Void'), + ('close', [''], 'ootype.Void'), + ('connect', ['ootype.String'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('send', ['ootype.String', 'ootype.String', '*args'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('client', 'ootype.Dict'), + ('domain', 'ootype.String'), +] +types['flash.net.LocalConnection'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.FileFilter' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('description', 'ootype.String'), + ('extension', 'ootype.String'), + ('macType', 'ootype.String'), +] +types['flash.net.FileFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('writeDynamicProperty', ['ootype.String', ''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLLoaderDataFormat' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BINARY', 'String'), + ('TEXT', 'String'), + ('VARIABLES', 'String'), +] +types['flash.net.URLLoaderDataFormat'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLLoader' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('close', [''], 'ootype.Void'), + ('load', ['flash.net.URLRequest'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['flash.net.URLRequest'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.URLLoader'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.ObjectEncoding' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('AMF0', 'uint'), + ('AMF3', 'uint'), + ('DEFAULT', 'uint'), + ('dynamicPropertyWriter', 'flash.net.IDynamicPropertyWriter'), +] +types['flash.net.ObjectEncoding'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.NetConnection' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('addHeader', ['ootype.String', 'ootype.Bool', 'ootype.Dict'], 'ootype.Void'), + ('call', ['ootype.String', 'flash.net.Responder', '*args'], 'ootype.Void'), + ('close', [''], 'ootype.Void'), + ('connect', ['ootype.String', '*args'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('client', 'ootype.Dict'), + ('connected', 'ootype.Bool'), + ('connectedProxyType', 'ootype.String'), + ('defaultObjectEncoding', 'ootype.UnsignedLongLong'), + ('farID', 'ootype.String'), + ('farNonce', 'ootype.String'), + ('maxPeerConnections', 'ootype.UnsignedLongLong'), + ('nearID', 'ootype.String'), + ('nearNonce', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), + ('protocol', 'ootype.String'), + ('proxyType', 'ootype.String'), + ('unconnectedPeerStreams', 'ootype.List'), + ('uri', 'ootype.String'), + ('usingTLS', 'ootype.Bool'), +] +types['flash.net.NetConnection'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.XMLSocket' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('close', [''], 'ootype.Void'), + ('connect', ['ootype.String', 'ootype.SignedLongLong'], 'ootype.Void'), + ('send', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('connected', 'ootype.Bool'), + ('timeout', 'ootype.SignedLongLong'), +] +types['flash.net.XMLSocket'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.NetStreamPlayOptions' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.NetStreamPlayOptions'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.NetStream' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('attachAudio', ['flash.media.Microphone'], 'ootype.Void'), + ('attachCamera', ['flash.media.Camera', 'ootype.SignedLongLong'], 'ootype.Void'), + ('close', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['flash.net.NetConnection', 'ootype.String'], None), + ('onPeerConnect', ['flash.net.NetStream'], 'ootype.Bool'), + ('pause', [''], 'ootype.Void'), + ('play', ['*args'], 'ootype.Void'), + ('play2', ['flash.net.NetStreamPlayOptions'], 'ootype.Void'), + ('publish', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('receiveAudio', ['ootype.Bool'], 'ootype.Void'), + ('receiveVideo', ['ootype.Bool'], 'ootype.Void'), + ('receiveVideoFPS', ['ootype.Float'], 'ootype.Void'), + ('resume', [''], 'ootype.Void'), + ('seek', ['ootype.Float'], 'ootype.Void'), + ('send', ['ootype.String', '*args'], 'ootype.Void'), + ('togglePause', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CONNECT_TO_FMS', 'String'), + ('DIRECT_CONNECTIONS', 'String'), + ('audioCodec', 'ootype.UnsignedLongLong'), + ('bufferLength', 'ootype.Float'), + ('bufferTime', 'ootype.Float'), + ('bytesLoaded', 'ootype.UnsignedLongLong'), + ('bytesTotal', 'ootype.UnsignedLongLong'), + ('checkPolicyFile', 'ootype.Bool'), + ('client', 'ootype.Dict'), + ('currentFPS', 'ootype.Float'), + ('decodedFrames', 'ootype.UnsignedLongLong'), + ('farID', 'ootype.String'), + ('farNonce', 'ootype.String'), + ('info', 'flash.net.NetStreamInfo'), + ('liveDelay', 'ootype.Float'), + ('maxPauseBufferTime', 'ootype.Float'), + ('nearNonce', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), + ('peerStreams', 'ootype.List'), + ('soundTransform', 'flash.media.SoundTransform'), + ('time', 'ootype.Float'), + ('videoCodec', 'ootype.UnsignedLongLong'), +] +types['flash.net.NetStream'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLVariables' +desc.BaseType = 'Object' +desc.Methods = [ + ('decode', ['ootype.String'], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('!CONSTRUCTOR!', ['ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.URLVariables'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.NetStreamInfo' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('audioBufferByteLength', 'ootype.Float'), + ('audioBufferLength', 'ootype.Float'), + ('audioByteCount', 'ootype.Float'), + ('audioBytesPerSecond', 'ootype.Float'), + ('audioLossRate', 'ootype.Float'), + ('byteCount', 'ootype.Float'), + ('currentBytesPerSecond', 'ootype.Float'), + ('dataBufferByteLength', 'ootype.Float'), + ('dataBufferLength', 'ootype.Float'), + ('dataByteCount', 'ootype.Float'), + ('dataBytesPerSecond', 'ootype.Float'), + ('droppedFrames', 'ootype.Float'), + ('maxBytesPerSecond', 'ootype.Float'), + ('playbackBytesPerSecond', 'ootype.Float'), + ('SRTT', 'ootype.Float'), + ('videoBufferByteLength', 'ootype.Float'), + ('videoBufferLength', 'ootype.Float'), + ('videoByteCount', 'ootype.Float'), + ('videoBytesPerSecond', 'ootype.Float'), +] +types['flash.net.NetStreamInfo'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('registerClassAlias', ['ootype.String', 'Class'], 'ootype.Void'), + ('getClassByAlias', ['ootype.String'], 'Class'), + ('navigateToURL', ['flash.net.URLRequest', 'ootype.String'], 'ootype.Void'), + ('sendToURL', ['flash.net.URLRequest'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.SharedObject' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('clear', [''], 'ootype.Void'), + ('close', [''], 'ootype.Void'), + ('connect', ['flash.net.NetConnection', 'ootype.String'], 'ootype.Void'), + ('flush', ['ootype.SignedLongLong'], 'ootype.String'), + ('send', ['*args'], 'ootype.Void'), + ('setDirty', ['ootype.String'], 'ootype.Void'), + ('setProperty', ['ootype.String', 'ootype.Dict'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('deleteAll', ['ootype.String'], 'ootype.SignedLongLong'), + ('getDiskUsage', ['ootype.String'], 'ootype.SignedLongLong'), + ('getLocal', ['ootype.String', 'ootype.String', 'ootype.Bool'], 'flash.net.SharedObject'), + ('getRemote', ['ootype.String', 'ootype.String', 'ootype.Dict', 'ootype.Bool'], 'flash.net.SharedObject'), +] +desc.Fields = [] +desc.StaticFields = [ + ('client', 'ootype.Dict'), + ('data', 'ootype.Dict'), + ('defaultObjectEncoding', 'ootype.UnsignedLongLong'), + ('fps', 'ootype.Float'), + ('objectEncoding', 'ootype.UnsignedLongLong'), + ('size', 'ootype.UnsignedLongLong'), +] +types['flash.net.SharedObject'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.DynamicPropertyOutput' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('writeDynamicProperty', ['ootype.String', ''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.DynamicPropertyOutput'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLRequest' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('contentType', 'ootype.String'), + ('data', 'ootype.Dict'), + ('digest', 'ootype.String'), + ('method', 'ootype.String'), + ('requestHeaders', 'ootype.List'), + ('url', 'ootype.String'), +] +types['flash.net.URLRequest'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.SharedObject' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('clear', [''], 'ootype.Void'), + ('close', [''], 'ootype.Void'), + ('connect', ['flash.net.NetConnection', 'ootype.String'], 'ootype.Void'), + ('flush', ['ootype.SignedLongLong'], 'ootype.String'), + ('send', ['*args'], 'ootype.Void'), + ('setDirty', ['ootype.String'], 'ootype.Void'), + ('setProperty', ['ootype.String', 'ootype.Dict'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('deleteAll', ['ootype.String'], 'ootype.SignedLongLong'), + ('getDiskUsage', ['ootype.String'], 'ootype.SignedLongLong'), + ('getLocal', ['ootype.String', 'ootype.String', 'ootype.Bool'], 'flash.net.SharedObject'), + ('getRemote', ['ootype.String', 'ootype.String', 'ootype.Dict', 'ootype.Bool'], 'flash.net.SharedObject'), +] +desc.Fields = [] +desc.StaticFields = [ + ('client', 'ootype.Dict'), + ('data', 'ootype.Dict'), + ('defaultObjectEncoding', 'ootype.UnsignedLongLong'), + ('fps', 'ootype.Float'), + ('objectEncoding', 'ootype.UnsignedLongLong'), + ('size', 'ootype.UnsignedLongLong'), +] +types['flash.net.SharedObject'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.NetStreamPlayOptions' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.NetStreamPlayOptions'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.NetStreamInfo' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('audioBufferByteLength', 'ootype.Float'), + ('audioBufferLength', 'ootype.Float'), + ('audioByteCount', 'ootype.Float'), + ('audioBytesPerSecond', 'ootype.Float'), + ('audioLossRate', 'ootype.Float'), + ('byteCount', 'ootype.Float'), + ('currentBytesPerSecond', 'ootype.Float'), + ('dataBufferByteLength', 'ootype.Float'), + ('dataBufferLength', 'ootype.Float'), + ('dataByteCount', 'ootype.Float'), + ('dataBytesPerSecond', 'ootype.Float'), + ('droppedFrames', 'ootype.Float'), + ('maxBytesPerSecond', 'ootype.Float'), + ('playbackBytesPerSecond', 'ootype.Float'), + ('SRTT', 'ootype.Float'), + ('videoBufferByteLength', 'ootype.Float'), + ('videoBufferLength', 'ootype.Float'), + ('videoByteCount', 'ootype.Float'), + ('videoBytesPerSecond', 'ootype.Float'), +] +types['flash.net.NetStreamInfo'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLRequestMethod' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('GET', 'String'), + ('POST', 'String'), +] +types['flash.net.URLRequestMethod'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('registerClassAlias', ['ootype.String', 'Class'], 'ootype.Void'), + ('getClassByAlias', ['ootype.String'], 'Class'), + ('navigateToURL', ['flash.net.URLRequest', 'ootype.String'], 'ootype.Void'), + ('sendToURL', ['flash.net.URLRequest'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.NetConnection' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('addHeader', ['ootype.String', 'ootype.Bool', 'ootype.Dict'], 'ootype.Void'), + ('call', ['ootype.String', 'flash.net.Responder', '*args'], 'ootype.Void'), + ('close', [''], 'ootype.Void'), + ('connect', ['ootype.String', '*args'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('client', 'ootype.Dict'), + ('connected', 'ootype.Bool'), + ('connectedProxyType', 'ootype.String'), + ('defaultObjectEncoding', 'ootype.UnsignedLongLong'), + ('farID', 'ootype.String'), + ('farNonce', 'ootype.String'), + ('maxPeerConnections', 'ootype.UnsignedLongLong'), + ('nearID', 'ootype.String'), + ('nearNonce', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), + ('protocol', 'ootype.String'), + ('proxyType', 'ootype.String'), + ('unconnectedPeerStreams', 'ootype.List'), + ('uri', 'ootype.String'), + ('usingTLS', 'ootype.Bool'), +] +types['flash.net.NetConnection'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLStream' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('close', [''], 'ootype.Void'), + ('load', ['flash.net.URLRequest'], 'ootype.Void'), + ('readBoolean', [''], 'ootype.Bool'), + ('readByte', [''], 'ootype.SignedLongLong'), + ('readBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('readDouble', [''], 'ootype.Float'), + ('readFloat', [''], 'ootype.Float'), + ('readInt', [''], 'ootype.SignedLongLong'), + ('readMultiByte', ['ootype.UnsignedLongLong', 'ootype.String'], 'ootype.String'), + ('readObject', [''], ''), + ('readShort', [''], 'ootype.SignedLongLong'), + ('readUnsignedByte', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedInt', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedShort', [''], 'ootype.UnsignedLongLong'), + ('readUTF', [''], 'ootype.String'), + ('readUTFBytes', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesAvailable', 'ootype.UnsignedLongLong'), + ('connected', 'ootype.Bool'), + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), +] +types['flash.net.URLStream'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.DynamicPropertyOutput' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('writeDynamicProperty', ['ootype.String', ''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.DynamicPropertyOutput'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('writeDynamicProperties', ['ootype.Dict', 'flash.net.IDynamicPropertyOutput'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLRequestHeader' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.URLRequestHeader'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLVariables' +desc.BaseType = 'Object' +desc.Methods = [ + ('decode', ['ootype.String'], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('!CONSTRUCTOR!', ['ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.URLVariables'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.XMLSocket' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('close', [''], 'ootype.Void'), + ('connect', ['ootype.String', 'ootype.SignedLongLong'], 'ootype.Void'), + ('send', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('connected', 'ootype.Bool'), + ('timeout', 'ootype.SignedLongLong'), +] +types['flash.net.XMLSocket'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.LocalConnection' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('allowDomain', ['*args'], 'ootype.Void'), + ('allowInsecureDomain', ['*args'], 'ootype.Void'), + ('close', [''], 'ootype.Void'), + ('connect', ['ootype.String'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('send', ['ootype.String', 'ootype.String', '*args'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('client', 'ootype.Dict'), + ('domain', 'ootype.String'), +] +types['flash.net.LocalConnection'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.ObjectEncoding' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('AMF0', 'uint'), + ('AMF3', 'uint'), + ('DEFAULT', 'uint'), + ('dynamicPropertyWriter', 'flash.net.IDynamicPropertyWriter'), +] +types['flash.net.ObjectEncoding'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.NetStreamPlayTransitions' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('APPEND', '*'), + ('RESET', '*'), + ('STOP', '*'), + ('SWAP', '*'), + ('SWITCH', '*'), +] +types['flash.net.NetStreamPlayTransitions'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.FileFilter' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('description', 'ootype.String'), + ('extension', 'ootype.String'), + ('macType', 'ootype.String'), +] +types['flash.net.FileFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.NetStream' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('attachAudio', ['flash.media.Microphone'], 'ootype.Void'), + ('attachCamera', ['flash.media.Camera', 'ootype.SignedLongLong'], 'ootype.Void'), + ('close', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['flash.net.NetConnection', 'ootype.String'], None), + ('onPeerConnect', ['flash.net.NetStream'], 'ootype.Bool'), + ('pause', [''], 'ootype.Void'), + ('play', ['*args'], 'ootype.Void'), + ('play2', ['flash.net.NetStreamPlayOptions'], 'ootype.Void'), + ('publish', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('receiveAudio', ['ootype.Bool'], 'ootype.Void'), + ('receiveVideo', ['ootype.Bool'], 'ootype.Void'), + ('receiveVideoFPS', ['ootype.Float'], 'ootype.Void'), + ('resume', [''], 'ootype.Void'), + ('seek', ['ootype.Float'], 'ootype.Void'), + ('send', ['ootype.String', '*args'], 'ootype.Void'), + ('togglePause', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CONNECT_TO_FMS', 'String'), + ('DIRECT_CONNECTIONS', 'String'), + ('audioCodec', 'ootype.UnsignedLongLong'), + ('bufferLength', 'ootype.Float'), + ('bufferTime', 'ootype.Float'), + ('bytesLoaded', 'ootype.UnsignedLongLong'), + ('bytesTotal', 'ootype.UnsignedLongLong'), + ('checkPolicyFile', 'ootype.Bool'), + ('client', 'ootype.Dict'), + ('currentFPS', 'ootype.Float'), + ('decodedFrames', 'ootype.UnsignedLongLong'), + ('farID', 'ootype.String'), + ('farNonce', 'ootype.String'), + ('info', 'flash.net.NetStreamInfo'), + ('liveDelay', 'ootype.Float'), + ('maxPauseBufferTime', 'ootype.Float'), + ('nearNonce', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), + ('peerStreams', 'ootype.List'), + ('soundTransform', 'flash.media.SoundTransform'), + ('time', 'ootype.Float'), + ('videoCodec', 'ootype.UnsignedLongLong'), +] +types['flash.net.NetStream'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.FileReferenceList' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('browse', ['ootype.List'], 'ootype.Bool'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('fileList', 'ootype.List'), +] +types['flash.net.FileReferenceList'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.Responder' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['Function', 'Function'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.Responder'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.FileReference' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('browse', ['ootype.List'], 'ootype.Bool'), + ('cancel', [''], 'ootype.Void'), + ('download', ['flash.net.URLRequest', 'ootype.String'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('load', [''], 'ootype.Void'), + ('save', ['', 'ootype.String'], 'ootype.Void'), + ('upload', ['flash.net.URLRequest', 'ootype.String', 'ootype.Bool'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('creationDate', 'Date'), + ('creator', 'ootype.String'), + ('data', 'flash.utils.ByteArray'), + ('modificationDate', 'Date'), + ('name', 'ootype.String'), + ('size', 'ootype.UnsignedLongLong'), + ('type', 'ootype.String'), +] +types['flash.net.FileReference'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('writeDynamicProperty', ['ootype.String', ''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLLoader' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('close', [''], 'ootype.Void'), + ('load', ['flash.net.URLRequest'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['flash.net.URLRequest'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.net.URLLoader'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLRequest' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('contentType', 'ootype.String'), + ('data', 'ootype.Dict'), + ('digest', 'ootype.String'), + ('method', 'ootype.String'), + ('requestHeaders', 'ootype.List'), + ('url', 'ootype.String'), +] +types['flash.net.URLRequest'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.URLLoaderDataFormat' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BINARY', 'String'), + ('TEXT', 'String'), + ('VARIABLES', 'String'), +] +types['flash.net.URLLoaderDataFormat'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.Socket' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('close', [''], 'ootype.Void'), + ('connect', ['ootype.String', 'ootype.SignedLongLong'], 'ootype.Void'), + ('flush', [''], 'ootype.Void'), + ('readBoolean', [''], 'ootype.Bool'), + ('readByte', [''], 'ootype.SignedLongLong'), + ('readBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('readDouble', [''], 'ootype.Float'), + ('readFloat', [''], 'ootype.Float'), + ('readInt', [''], 'ootype.SignedLongLong'), + ('readMultiByte', ['ootype.UnsignedLongLong', 'ootype.String'], 'ootype.String'), + ('readObject', [''], ''), + ('readShort', [''], 'ootype.SignedLongLong'), + ('readUnsignedByte', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedInt', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedShort', [''], 'ootype.UnsignedLongLong'), + ('readUTF', [''], 'ootype.String'), + ('readUTFBytes', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), + ('writeBoolean', ['ootype.Bool'], 'ootype.Void'), + ('writeByte', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeDouble', ['ootype.Float'], 'ootype.Void'), + ('writeFloat', ['ootype.Float'], 'ootype.Void'), + ('writeInt', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeMultiByte', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('writeObject', [''], 'ootype.Void'), + ('writeShort', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeUnsignedInt', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeUTF', ['ootype.String'], 'ootype.Void'), + ('writeUTFBytes', ['ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesAvailable', 'ootype.UnsignedLongLong'), + ('connected', 'ootype.Bool'), + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), + ('timeout', 'ootype.UnsignedLongLong'), +] +types['flash.net.Socket'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.net.SharedObjectFlushStatus' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FLUSHED', 'String'), + ('PENDING', 'String'), +] +types['flash.net.SharedObjectFlushStatus'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.InvalidSWFError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.InvalidSWFError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.EOFError' +desc.BaseType = 'IOError' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.EOFError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.MemoryError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.MemoryError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.StackOverflowError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.StackOverflowError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.IOError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.IOError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.ScriptTimeoutError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.ScriptTimeoutError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.IllegalOperationError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.IllegalOperationError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.IOError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.IOError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.ScriptTimeoutError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.ScriptTimeoutError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.IllegalOperationError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.IllegalOperationError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.EOFError' +desc.BaseType = 'IOError' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.EOFError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.MemoryError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.MemoryError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.StackOverflowError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.StackOverflowError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.errors.InvalidSWFError' +desc.BaseType = 'Error' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.errors.InvalidSWFError'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.external.ExternalInterface' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('addCallback', ['ootype.String', 'Function'], 'ootype.Void'), + ('call', ['ootype.String', '*args'], ''), +] +desc.Fields = [] +desc.StaticFields = [ + ('marshallExceptions', 'Boolean'), + ('available', 'ootype.Bool'), + ('objectID', 'ootype.String'), +] +types['flash.external.ExternalInterface'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.external.ExternalInterface' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('addCallback', ['ootype.String', 'Function'], 'ootype.Void'), + ('call', ['ootype.String', '*args'], ''), +] +desc.Fields = [] +desc.StaticFields = [ + ('marshallExceptions', 'Boolean'), + ('available', 'ootype.Bool'), + ('objectID', 'ootype.String'), +] +types['flash.external.ExternalInterface'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.CapsStyle' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('NONE', 'String'), + ('ROUND', 'String'), + ('SQUARE', 'String'), +] +types['flash.display.CapsStyle'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsBitmapFill' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.BitmapData', 'flash.geom.Matrix', 'ootype.Bool', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.GraphicsBitmapFill'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsStroke' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Bool', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.Float', 'flash.display.IGraphicsFill'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('caps', 'ootype.String'), + ('joints', 'ootype.String'), + ('scaleMode', 'ootype.String'), +] +types['flash.display.GraphicsStroke'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.StageDisplayState' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FULL_SCREEN', 'String'), + ('NORMAL', 'String'), +] +types['flash.display.StageDisplayState'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsShaderFill' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.Shader', 'flash.geom.Matrix'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.GraphicsShaderFill'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsGradientFill' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.List', 'ootype.List', 'ootype.List', '', '', 'ootype.String', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('interpolationMethod', 'ootype.String'), + ('spreadMethod', 'ootype.String'), + ('type', 'ootype.String'), +] +types['flash.display.GraphicsGradientFill'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.BitmapDataChannel' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ALPHA', 'uint'), + ('BLUE', 'uint'), + ('GREEN', 'uint'), + ('RED', 'uint'), +] +types['flash.display.BitmapDataChannel'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.BitmapData' +desc.BaseType = 'Object' +desc.Methods = [ + ('applyFilter', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'flash.filters.BitmapFilter'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.Bool', 'ootype.UnsignedLongLong'], None), + ('clone', [''], 'flash.display.BitmapData'), + ('colorTransform', ['flash.geom.Rectangle', 'flash.geom.ColorTransform'], 'ootype.Void'), + ('compare', ['flash.display.BitmapData'], 'ootype.Dict'), + ('copyChannel', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('copyPixels', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'flash.display.BitmapData', 'flash.geom.Point', 'ootype.Bool'], 'ootype.Void'), + ('dispose', [''], 'ootype.Void'), + ('draw', ['flash.display.IBitmapDrawable', 'flash.geom.Matrix', 'flash.geom.ColorTransform', 'ootype.String', 'flash.geom.Rectangle', 'ootype.Bool'], 'ootype.Void'), + ('fillRect', ['flash.geom.Rectangle', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('floodFill', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('generateFilterRect', ['flash.geom.Rectangle', 'flash.filters.BitmapFilter'], 'flash.geom.Rectangle'), + ('getColorBoundsRect', ['ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Bool'], 'flash.geom.Rectangle'), + ('getPixel', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.UnsignedLongLong'), + ('getPixel32', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.UnsignedLongLong'), + ('getPixels', ['flash.geom.Rectangle'], 'flash.utils.ByteArray'), + ('getVector', ['flash.geom.Rectangle'], 'ootype.UnsignedLongLong[]'), + ('histogram', ['flash.geom.Rectangle'], 'ootype.Float[][]'), + ('hitTest', ['flash.geom.Point', 'ootype.UnsignedLongLong', 'ootype.Dict', 'flash.geom.Point', 'ootype.UnsignedLongLong'], 'ootype.Bool'), + ('lock', [''], 'ootype.Void'), + ('merge', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('noise', ['ootype.SignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('paletteMap', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'ootype.List', 'ootype.List', 'ootype.List', 'ootype.List'], 'ootype.Void'), + ('perlinNoise', ['ootype.Float', 'ootype.Float', 'ootype.UnsignedLongLong', 'ootype.SignedLongLong', 'ootype.Bool', 'ootype.Bool', 'ootype.UnsignedLongLong', 'ootype.Bool', 'ootype.List'], 'ootype.Void'), + ('pixelDissolve', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.SignedLongLong'), + ('scroll', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), + ('setPixel', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('setPixel32', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('setPixels', ['flash.geom.Rectangle', 'flash.utils.ByteArray'], 'ootype.Void'), + ('setVector', ['flash.geom.Rectangle', 'ootype.UnsignedLongLong[]'], 'ootype.Void'), + ('threshold', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'ootype.String', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Bool'], 'ootype.UnsignedLongLong'), + ('unlock', ['flash.geom.Rectangle'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('height', 'ootype.SignedLongLong'), + ('rect', 'flash.geom.Rectangle'), + ('transparent', 'ootype.Bool'), + ('width', 'ootype.SignedLongLong'), +] +types['flash.display.BitmapData'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Graphics' +desc.BaseType = 'Object' +desc.Methods = [ + ('beginBitmapFill', ['flash.display.BitmapData', 'flash.geom.Matrix', 'ootype.Bool', 'ootype.Bool'], 'ootype.Void'), + ('beginFill', ['ootype.UnsignedLongLong', 'ootype.Float'], 'ootype.Void'), + ('beginGradientFill', ['ootype.String', 'ootype.List', 'ootype.List', 'ootype.List', 'flash.geom.Matrix', 'ootype.String', 'ootype.String', 'ootype.Float'], 'ootype.Void'), + ('beginShaderFill', ['flash.display.Shader', 'flash.geom.Matrix'], 'ootype.Void'), + ('clear', [''], 'ootype.Void'), + ('copyFrom', ['flash.display.Graphics'], 'ootype.Void'), + ('curveTo', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawCircle', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawEllipse', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawGraphicsData', ['IGraphicsData[]'], 'ootype.Void'), + ('drawPath', ['ootype.SignedLongLong[]', 'ootype.Float[]', 'ootype.String'], 'ootype.Void'), + ('drawRect', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawRoundRect', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawRoundRectComplex', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawTriangles', ['ootype.Float[]', 'ootype.SignedLongLong[]', 'ootype.Float[]', 'ootype.String'], 'ootype.Void'), + ('endFill', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('lineBitmapStyle', ['flash.display.BitmapData', 'flash.geom.Matrix', 'ootype.Bool', 'ootype.Bool'], 'ootype.Void'), + ('lineGradientStyle', ['ootype.String', 'ootype.List', 'ootype.List', 'ootype.List', 'flash.geom.Matrix', 'ootype.String', 'ootype.String', 'ootype.Float'], 'ootype.Void'), + ('lineShaderStyle', ['flash.display.Shader', 'flash.geom.Matrix'], 'ootype.Void'), + ('lineStyle', ['ootype.Float', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.Bool', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.Float'], 'ootype.Void'), + ('lineTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('moveTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.Graphics'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Stage' +desc.BaseType = 'DisplayObjectContainer' +desc.Methods = [ + ('addChild', ['flash.display.DisplayObject'], 'flash.display.DisplayObject'), + ('addChildAt', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('addEventListener', ['ootype.String', 'Function', 'ootype.Bool', 'ootype.SignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('dispatchEvent', ['flash.events.Event'], 'ootype.Bool'), + ('hasEventListener', ['ootype.String'], 'ootype.Bool'), + ('invalidate', [''], 'ootype.Void'), + ('isFocusInaccessible', [''], 'ootype.Bool'), + ('removeChildAt', ['ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('setChildIndex', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('swapChildrenAt', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), + ('willTrigger', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('accessibilityImplementation', 'flash.accessibility.AccessibilityImplementation'), + ('accessibilityProperties', 'flash.accessibility.AccessibilityProperties'), + ('align', 'ootype.String'), + ('alpha', 'ootype.Float'), + ('blendMode', 'ootype.String'), + ('cacheAsBitmap', 'ootype.Bool'), + ('colorCorrection', 'ootype.String'), + ('colorCorrectionSupport', 'ootype.String'), + ('contextMenu', 'flash.ui.ContextMenu'), + ('displayState', 'ootype.String'), + ('filters', 'ootype.List'), + ('focus', 'flash.display.InteractiveObject'), + ('focusRect', 'ootype.Dict'), + ('frameRate', 'ootype.Float'), + ('fullScreenHeight', 'ootype.UnsignedLongLong'), + ('fullScreenSourceRect', 'flash.geom.Rectangle'), + ('fullScreenWidth', 'ootype.UnsignedLongLong'), + ('height', 'ootype.Float'), + ('mask', 'flash.display.DisplayObject'), + ('mouseChildren', 'ootype.Bool'), + ('mouseEnabled', 'ootype.Bool'), + ('name', 'ootype.String'), + ('numChildren', 'ootype.SignedLongLong'), + ('opaqueBackground', 'ootype.Dict'), + ('quality', 'ootype.String'), + ('rotation', 'ootype.Float'), + ('rotationX', 'ootype.Float'), + ('rotationY', 'ootype.Float'), + ('rotationZ', 'ootype.Float'), + ('scale9Grid', 'flash.geom.Rectangle'), + ('scaleMode', 'ootype.String'), + ('scaleX', 'ootype.Float'), + ('scaleY', 'ootype.Float'), + ('scaleZ', 'ootype.Float'), + ('scrollRect', 'flash.geom.Rectangle'), + ('showDefaultContextMenu', 'ootype.Bool'), + ('stageFocusRect', 'ootype.Bool'), + ('stageHeight', 'ootype.SignedLongLong'), + ('stageWidth', 'ootype.SignedLongLong'), + ('tabChildren', 'ootype.Bool'), + ('tabEnabled', 'ootype.Bool'), + ('tabIndex', 'ootype.SignedLongLong'), + ('textSnapshot', 'flash.text.TextSnapshot'), + ('transform', 'flash.geom.Transform'), + ('width', 'ootype.Float'), + ('visible', 'ootype.Bool'), + ('x', 'ootype.Float'), + ('y', 'ootype.Float'), + ('z', 'ootype.Float'), +] +types['flash.display.Stage'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.DisplayObjectContainer' +desc.BaseType = 'InteractiveObject' +desc.Methods = [ + ('addChild', ['flash.display.DisplayObject'], 'flash.display.DisplayObject'), + ('addChildAt', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('areInaccessibleObjectsUnderPoint', ['flash.geom.Point'], 'ootype.Bool'), + ('contains', ['flash.display.DisplayObject'], 'ootype.Bool'), + ('!CONSTRUCTOR!', [''], None), + ('getChildAt', ['ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('getChildByName', ['ootype.String'], 'flash.display.DisplayObject'), + ('getChildIndex', ['flash.display.DisplayObject'], 'ootype.SignedLongLong'), + ('getObjectsUnderPoint', ['flash.geom.Point'], 'ootype.List'), + ('removeChild', ['flash.display.DisplayObject'], 'flash.display.DisplayObject'), + ('removeChildAt', ['ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('setChildIndex', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'ootype.Void'), + ('swapChildren', ['flash.display.DisplayObject', 'flash.display.DisplayObject'], 'ootype.Void'), + ('swapChildrenAt', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('mouseChildren', 'ootype.Bool'), + ('numChildren', 'ootype.SignedLongLong'), + ('tabChildren', 'ootype.Bool'), + ('textSnapshot', 'flash.text.TextSnapshot'), +] +types['flash.display.DisplayObjectContainer'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GradientType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('LINEAR', 'String'), + ('RADIAL', 'String'), +] +types['flash.display.GradientType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.SpreadMethod' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('PAD', 'String'), + ('REFLECT', 'String'), + ('REPEAT', 'String'), +] +types['flash.display.SpreadMethod'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.LineScaleMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('HORIZONTAL', 'String'), + ('NONE', 'String'), + ('NORMAL', 'String'), + ('VERTICAL', 'String'), +] +types['flash.display.LineScaleMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ColorCorrection' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEFAULT', 'String'), + ('OFF', 'String'), + ('ON', 'String'), +] +types['flash.display.ColorCorrection'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.InteractiveObject' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('accessibilityImplementation', 'flash.accessibility.AccessibilityImplementation'), + ('contextMenu', 'flash.ui.ContextMenu'), + ('doubleClickEnabled', 'ootype.Bool'), + ('focusRect', 'ootype.Dict'), + ('mouseEnabled', 'ootype.Bool'), + ('tabEnabled', 'ootype.Bool'), + ('tabIndex', 'ootype.SignedLongLong'), +] +types['flash.display.InteractiveObject'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.FrameLabel' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('frame', 'ootype.SignedLongLong'), + ('name', 'ootype.String'), +] +types['flash.display.FrameLabel'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Bitmap' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.BitmapData', 'ootype.String', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bitmapData', 'flash.display.BitmapData'), + ('pixelSnapping', 'ootype.String'), + ('smoothing', 'ootype.Bool'), +] +types['flash.display.Bitmap'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsEndFill' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.GraphicsEndFill'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsPath' +desc.BaseType = 'Object' +desc.Methods = [ + ('curveTo', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.SignedLongLong[]', 'ootype.Float[]', 'ootype.String'], None), + ('lineTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('moveTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('wideLineTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('wideMoveTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('winding', 'ootype.String'), +] +types['flash.display.GraphicsPath'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.PixelSnapping' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ALWAYS', 'String'), + ('AUTO', 'String'), + ('NEVER', 'String'), +] +types['flash.display.PixelSnapping'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderPrecision' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FAST', 'String'), + ('FULL', 'String'), +] +types['flash.display.ShaderPrecision'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.JointStyle' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BEVEL', 'String'), + ('MITER', 'String'), + ('ROUND', 'String'), +] +types['flash.display.JointStyle'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.StageScaleMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('EXACT_FIT', 'String'), + ('NO_BORDER', 'String'), + ('NO_SCALE', 'String'), + ('SHOW_ALL', 'String'), +] +types['flash.display.StageScaleMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.MovieClip' +desc.BaseType = 'Sprite' +desc.Methods = [ + ('addFrameScript', ['ootype.SignedLongLong', 'Function'], 'ootype.Void'), + ('gotoAndPlay', ['ootype.Dict', 'ootype.String'], 'ootype.Void'), + ('gotoAndStop', ['ootype.Dict', 'ootype.String'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('nextFrame', [''], 'ootype.Void'), + ('nextScene', [''], 'ootype.Void'), + ('play', [''], 'ootype.Void'), + ('prevFrame', [''], 'ootype.Void'), + ('prevScene', [''], 'ootype.Void'), + ('stop', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('currentFrame', 'ootype.SignedLongLong'), + ('currentFrameLabel', 'ootype.String'), + ('currentLabel', 'ootype.String'), + ('currentLabels', 'ootype.List'), + ('currentScene', 'flash.display.Scene'), + ('enabled', 'ootype.Bool'), + ('framesLoaded', 'ootype.SignedLongLong'), + ('scenes', 'ootype.List'), + ('totalFrames', 'ootype.SignedLongLong'), + ('trackAsMenu', 'ootype.Bool'), +] +types['flash.display.MovieClip'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Shape' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('graphics', 'flash.display.Graphics'), +] +types['flash.display.Shape'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderJob' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('cancel', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['flash.display.Shader', 'ootype.Dict', 'ootype.SignedLongLong', 'ootype.SignedLongLong'], None), + ('start', ['ootype.Bool'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('height', 'ootype.SignedLongLong'), + ('progress', 'ootype.Float'), + ('shader', 'flash.display.Shader'), + ('target', 'ootype.Dict'), + ('width', 'ootype.SignedLongLong'), +] +types['flash.display.ShaderJob'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.TriangleCulling' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('NEGATIVE', 'String'), + ('NONE', 'String'), + ('POSITIVE', 'String'), +] +types['flash.display.TriangleCulling'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.AVM1Movie' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('addCallback', ['ootype.String', 'Function'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('call', ['ootype.String', '*args'], ''), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.AVM1Movie'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsPathWinding' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('EVEN_ODD', 'String'), + ('NON_ZERO', 'String'), +] +types['flash.display.GraphicsPathWinding'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderData' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.utils.ByteArray'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.ShaderData'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsSolidFill' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.UnsignedLongLong', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.GraphicsSolidFill'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.DisplayObject' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('getBounds', ['flash.display.DisplayObject'], 'flash.geom.Rectangle'), + ('getRect', ['flash.display.DisplayObject'], 'flash.geom.Rectangle'), + ('globalToLocal', ['flash.geom.Point'], 'flash.geom.Point'), + ('globalToLocal3D', ['flash.geom.Point'], 'flash.geom.Vector3D'), + ('hitTestObject', ['flash.display.DisplayObject'], 'ootype.Bool'), + ('hitTestPoint', ['ootype.Float', 'ootype.Float', 'ootype.Bool'], 'ootype.Bool'), + ('local3DToGlobal', ['flash.geom.Vector3D'], 'flash.geom.Point'), + ('localToGlobal', ['flash.geom.Point'], 'flash.geom.Point'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('accessibilityProperties', 'flash.accessibility.AccessibilityProperties'), + ('alpha', 'ootype.Float'), + ('blendMode', 'ootype.String'), + ('blendShader', 'flash.display.Shader'), + ('cacheAsBitmap', 'ootype.Bool'), + ('filters', 'ootype.List'), + ('height', 'ootype.Float'), + ('loaderInfo', 'flash.display.LoaderInfo'), + ('mask', 'flash.display.DisplayObject'), + ('mouseX', 'ootype.Float'), + ('mouseY', 'ootype.Float'), + ('name', 'ootype.String'), + ('opaqueBackground', 'ootype.Dict'), + ('parent', 'flash.display.DisplayObjectContainer'), + ('root', 'flash.display.DisplayObject'), + ('rotation', 'ootype.Float'), + ('rotationX', 'ootype.Float'), + ('rotationY', 'ootype.Float'), + ('rotationZ', 'ootype.Float'), + ('scale9Grid', 'flash.geom.Rectangle'), + ('scaleX', 'ootype.Float'), + ('scaleY', 'ootype.Float'), + ('scaleZ', 'ootype.Float'), + ('scrollRect', 'flash.geom.Rectangle'), + ('stage', 'flash.display.Stage'), + ('transform', 'flash.geom.Transform'), + ('width', 'ootype.Float'), + ('visible', 'ootype.Bool'), + ('x', 'ootype.Float'), + ('y', 'ootype.Float'), + ('z', 'ootype.Float'), +] +types['flash.display.DisplayObject'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsTrianglePath' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float[]', 'ootype.SignedLongLong[]', 'ootype.Float[]', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('culling', 'ootype.String'), +] +types['flash.display.GraphicsTrianglePath'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Scene' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.List', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('labels', 'ootype.List'), + ('name', 'ootype.String'), + ('numFrames', 'ootype.SignedLongLong'), +] +types['flash.display.Scene'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.StageAlign' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BOTTOM', 'String'), + ('BOTTOM_LEFT', 'String'), + ('BOTTOM_RIGHT', 'String'), + ('LEFT', 'String'), + ('RIGHT', 'String'), + ('TOP', 'String'), + ('TOP_LEFT', 'String'), + ('TOP_RIGHT', 'String'), +] +types['flash.display.StageAlign'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Sprite' +desc.BaseType = 'DisplayObjectContainer' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('startDrag', ['ootype.Bool', 'flash.geom.Rectangle'], 'ootype.Void'), + ('stopDrag', [''], 'ootype.Void'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('buttonMode', 'ootype.Bool'), + ('dropTarget', 'flash.display.DisplayObject'), + ('graphics', 'flash.display.Graphics'), + ('hitArea', 'flash.display.Sprite'), + ('soundTransform', 'flash.media.SoundTransform'), + ('useHandCursor', 'ootype.Bool'), +] +types['flash.display.Sprite'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.InterpolationMethod' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('LINEAR_RGB', 'String'), + ('RGB', 'String'), +] +types['flash.display.InterpolationMethod'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.SimpleButton' +desc.BaseType = 'InteractiveObject' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.DisplayObject', 'flash.display.DisplayObject', 'flash.display.DisplayObject', 'flash.display.DisplayObject'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('downState', 'flash.display.DisplayObject'), + ('enabled', 'ootype.Bool'), + ('hitTestState', 'flash.display.DisplayObject'), + ('overState', 'flash.display.DisplayObject'), + ('soundTransform', 'flash.media.SoundTransform'), + ('trackAsMenu', 'ootype.Bool'), + ('upState', 'flash.display.DisplayObject'), + ('useHandCursor', 'ootype.Bool'), +] +types['flash.display.SimpleButton'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsPathCommand' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CURVE_TO', 'int'), + ('LINE_TO', 'int'), + ('MOVE_TO', 'int'), + ('NO_OP', 'int'), + ('WIDE_LINE_TO', 'int'), + ('WIDE_MOVE_TO', 'int'), +] +types['flash.display.GraphicsPathCommand'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ActionScriptVersion' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ACTIONSCRIPT2', 'uint'), + ('ACTIONSCRIPT3', 'uint'), +] +types['flash.display.ActionScriptVersion'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Shader' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.utils.ByteArray'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('byteCode', 'flash.utils.ByteArray'), + ('data', 'flash.display.ShaderData'), + ('precisionHint', 'ootype.String'), +] +types['flash.display.Shader'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.SWFVersion' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FLASH1', 'uint'), + ('FLASH10', 'uint'), + ('FLASH2', 'uint'), + ('FLASH3', 'uint'), + ('FLASH4', 'uint'), + ('FLASH5', 'uint'), + ('FLASH6', 'uint'), + ('FLASH7', 'uint'), + ('FLASH8', 'uint'), + ('FLASH9', 'uint'), +] +types['flash.display.SWFVersion'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.BlendMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ADD', 'String'), + ('ALPHA', 'String'), + ('DARKEN', 'String'), + ('DIFFERENCE', 'String'), + ('ERASE', 'String'), + ('HARDLIGHT', 'String'), + ('INVERT', 'String'), + ('LAYER', 'String'), + ('LIGHTEN', 'String'), + ('MULTIPLY', 'String'), + ('NORMAL', 'String'), + ('OVERLAY', 'String'), + ('SCREEN', 'String'), + ('SHADER', 'String'), + ('SUBTRACT', 'String'), +] +types['flash.display.BlendMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.LoaderInfo' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('dispatchEvent', ['flash.events.Event'], 'ootype.Bool'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('getLoaderInfoByDefinition', ['ootype.Dict'], 'flash.display.LoaderInfo'), +] +desc.Fields = [] +desc.StaticFields = [ + ('actionScriptVersion', 'ootype.UnsignedLongLong'), + ('applicationDomain', 'flash.system.ApplicationDomain'), + ('bytes', 'flash.utils.ByteArray'), + ('bytesLoaded', 'ootype.UnsignedLongLong'), + ('bytesTotal', 'ootype.UnsignedLongLong'), + ('childAllowsParent', 'ootype.Bool'), + ('content', 'flash.display.DisplayObject'), + ('contentType', 'ootype.String'), + ('frameRate', 'ootype.Float'), + ('height', 'ootype.SignedLongLong'), + ('loader', 'flash.display.Loader'), + ('loaderURL', 'ootype.String'), + ('parameters', 'ootype.Dict'), + ('parentAllowsChild', 'ootype.Bool'), + ('sameDomain', 'ootype.Bool'), + ('sharedEvents', 'flash.events.EventDispatcher'), + ('swfVersion', 'ootype.UnsignedLongLong'), + ('url', 'ootype.String'), + ('width', 'ootype.SignedLongLong'), +] +types['flash.display.LoaderInfo'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderParameterType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BOOL', 'String'), + ('BOOL2', 'String'), + ('BOOL3', 'String'), + ('BOOL4', 'String'), + ('FLOAT', 'String'), + ('FLOAT2', 'String'), + ('FLOAT3', 'String'), + ('FLOAT4', 'String'), + ('INT', 'String'), + ('INT2', 'String'), + ('INT3', 'String'), + ('INT4', 'String'), + ('MATRIX2X2', 'String'), + ('MATRIX3X3', 'String'), + ('MATRIX4X4', 'String'), +] +types['flash.display.ShaderParameterType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.MorphShape' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.MorphShape'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Loader' +desc.BaseType = 'DisplayObjectContainer' +desc.Methods = [ + ('addChild', ['flash.display.DisplayObject'], 'flash.display.DisplayObject'), + ('addChildAt', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('close', [''], 'ootype.Void'), + ('load', ['flash.net.URLRequest', 'flash.system.LoaderContext'], 'ootype.Void'), + ('loadBytes', ['flash.utils.ByteArray', 'flash.system.LoaderContext'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('removeChild', ['flash.display.DisplayObject'], 'flash.display.DisplayObject'), + ('removeChildAt', ['ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('setChildIndex', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'ootype.Void'), + ('unload', [''], 'ootype.Void'), + ('unloadAndStop', ['ootype.Bool'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('content', 'flash.display.DisplayObject'), + ('contentLoaderInfo', 'flash.display.LoaderInfo'), +] +types['flash.display.Loader'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.StageQuality' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BEST', 'String'), + ('HIGH', 'String'), + ('LOW', 'String'), + ('MEDIUM', 'String'), +] +types['flash.display.StageQuality'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderParameter' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('index', 'ootype.SignedLongLong'), + ('type', 'ootype.String'), + ('value', 'ootype.List'), +] +types['flash.display.ShaderParameter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderInput' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('channels', 'ootype.SignedLongLong'), + ('height', 'ootype.SignedLongLong'), + ('index', 'ootype.SignedLongLong'), + ('input', 'ootype.Dict'), + ('width', 'ootype.SignedLongLong'), +] +types['flash.display.ShaderInput'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ColorCorrectionSupport' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEFAULT_OFF', 'String'), + ('DEFAULT_ON', 'String'), + ('UNSUPPORTED', 'String'), +] +types['flash.display.ColorCorrectionSupport'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Bitmap' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.BitmapData', 'ootype.String', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bitmapData', 'flash.display.BitmapData'), + ('pixelSnapping', 'ootype.String'), + ('smoothing', 'ootype.Bool'), +] +types['flash.display.Bitmap'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderParameterType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BOOL', 'String'), + ('BOOL2', 'String'), + ('BOOL3', 'String'), + ('BOOL4', 'String'), + ('FLOAT', 'String'), + ('FLOAT2', 'String'), + ('FLOAT3', 'String'), + ('FLOAT4', 'String'), + ('INT', 'String'), + ('INT2', 'String'), + ('INT3', 'String'), + ('INT4', 'String'), + ('MATRIX2X2', 'String'), + ('MATRIX3X3', 'String'), + ('MATRIX4X4', 'String'), +] +types['flash.display.ShaderParameterType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Shape' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('graphics', 'flash.display.Graphics'), +] +types['flash.display.Shape'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Loader' +desc.BaseType = 'DisplayObjectContainer' +desc.Methods = [ + ('addChild', ['flash.display.DisplayObject'], 'flash.display.DisplayObject'), + ('addChildAt', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('close', [''], 'ootype.Void'), + ('load', ['flash.net.URLRequest', 'flash.system.LoaderContext'], 'ootype.Void'), + ('loadBytes', ['flash.utils.ByteArray', 'flash.system.LoaderContext'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('removeChild', ['flash.display.DisplayObject'], 'flash.display.DisplayObject'), + ('removeChildAt', ['ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('setChildIndex', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'ootype.Void'), + ('unload', [''], 'ootype.Void'), + ('unloadAndStop', ['ootype.Bool'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('content', 'flash.display.DisplayObject'), + ('contentLoaderInfo', 'flash.display.LoaderInfo'), +] +types['flash.display.Loader'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.MorphShape' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.MorphShape'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Graphics' +desc.BaseType = 'Object' +desc.Methods = [ + ('beginBitmapFill', ['flash.display.BitmapData', 'flash.geom.Matrix', 'ootype.Bool', 'ootype.Bool'], 'ootype.Void'), + ('beginFill', ['ootype.UnsignedLongLong', 'ootype.Float'], 'ootype.Void'), + ('beginGradientFill', ['ootype.String', 'ootype.List', 'ootype.List', 'ootype.List', 'flash.geom.Matrix', 'ootype.String', 'ootype.String', 'ootype.Float'], 'ootype.Void'), + ('beginShaderFill', ['flash.display.Shader', 'flash.geom.Matrix'], 'ootype.Void'), + ('clear', [''], 'ootype.Void'), + ('copyFrom', ['flash.display.Graphics'], 'ootype.Void'), + ('curveTo', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawCircle', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawEllipse', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawGraphicsData', ['IGraphicsData[]'], 'ootype.Void'), + ('drawPath', ['ootype.SignedLongLong[]', 'ootype.Float[]', 'ootype.String'], 'ootype.Void'), + ('drawRect', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawRoundRect', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawRoundRectComplex', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('drawTriangles', ['ootype.Float[]', 'ootype.SignedLongLong[]', 'ootype.Float[]', 'ootype.String'], 'ootype.Void'), + ('endFill', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('lineBitmapStyle', ['flash.display.BitmapData', 'flash.geom.Matrix', 'ootype.Bool', 'ootype.Bool'], 'ootype.Void'), + ('lineGradientStyle', ['ootype.String', 'ootype.List', 'ootype.List', 'ootype.List', 'flash.geom.Matrix', 'ootype.String', 'ootype.String', 'ootype.Float'], 'ootype.Void'), + ('lineShaderStyle', ['flash.display.Shader', 'flash.geom.Matrix'], 'ootype.Void'), + ('lineStyle', ['ootype.Float', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.Bool', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.Float'], 'ootype.Void'), + ('lineTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('moveTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.Graphics'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsShaderFill' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.Shader', 'flash.geom.Matrix'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.GraphicsShaderFill'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.SimpleButton' +desc.BaseType = 'InteractiveObject' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.DisplayObject', 'flash.display.DisplayObject', 'flash.display.DisplayObject', 'flash.display.DisplayObject'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('downState', 'flash.display.DisplayObject'), + ('enabled', 'ootype.Bool'), + ('hitTestState', 'flash.display.DisplayObject'), + ('overState', 'flash.display.DisplayObject'), + ('soundTransform', 'flash.media.SoundTransform'), + ('trackAsMenu', 'ootype.Bool'), + ('upState', 'flash.display.DisplayObject'), + ('useHandCursor', 'ootype.Bool'), +] +types['flash.display.SimpleButton'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsTrianglePath' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float[]', 'ootype.SignedLongLong[]', 'ootype.Float[]', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('culling', 'ootype.String'), +] +types['flash.display.GraphicsTrianglePath'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GradientType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('LINEAR', 'String'), + ('RADIAL', 'String'), +] +types['flash.display.GradientType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Scene' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.List', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('labels', 'ootype.List'), + ('name', 'ootype.String'), + ('numFrames', 'ootype.SignedLongLong'), +] +types['flash.display.Scene'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Shader' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.utils.ByteArray'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('byteCode', 'flash.utils.ByteArray'), + ('data', 'flash.display.ShaderData'), + ('precisionHint', 'ootype.String'), +] +types['flash.display.Shader'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.SWFVersion' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FLASH1', 'uint'), + ('FLASH10', 'uint'), + ('FLASH2', 'uint'), + ('FLASH3', 'uint'), + ('FLASH4', 'uint'), + ('FLASH5', 'uint'), + ('FLASH6', 'uint'), + ('FLASH7', 'uint'), + ('FLASH8', 'uint'), + ('FLASH9', 'uint'), +] +types['flash.display.SWFVersion'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.StageScaleMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('EXACT_FIT', 'String'), + ('NO_BORDER', 'String'), + ('NO_SCALE', 'String'), + ('SHOW_ALL', 'String'), +] +types['flash.display.StageScaleMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ColorCorrection' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEFAULT', 'String'), + ('OFF', 'String'), + ('ON', 'String'), +] +types['flash.display.ColorCorrection'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.StageDisplayState' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FULL_SCREEN', 'String'), + ('NORMAL', 'String'), +] +types['flash.display.StageDisplayState'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.CapsStyle' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('NONE', 'String'), + ('ROUND', 'String'), + ('SQUARE', 'String'), +] +types['flash.display.CapsStyle'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsSolidFill' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.UnsignedLongLong', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.GraphicsSolidFill'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.LineScaleMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('HORIZONTAL', 'String'), + ('NONE', 'String'), + ('NORMAL', 'String'), + ('VERTICAL', 'String'), +] +types['flash.display.LineScaleMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.DisplayObject' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('getBounds', ['flash.display.DisplayObject'], 'flash.geom.Rectangle'), + ('getRect', ['flash.display.DisplayObject'], 'flash.geom.Rectangle'), + ('globalToLocal', ['flash.geom.Point'], 'flash.geom.Point'), + ('globalToLocal3D', ['flash.geom.Point'], 'flash.geom.Vector3D'), + ('hitTestObject', ['flash.display.DisplayObject'], 'ootype.Bool'), + ('hitTestPoint', ['ootype.Float', 'ootype.Float', 'ootype.Bool'], 'ootype.Bool'), + ('local3DToGlobal', ['flash.geom.Vector3D'], 'flash.geom.Point'), + ('localToGlobal', ['flash.geom.Point'], 'flash.geom.Point'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('accessibilityProperties', 'flash.accessibility.AccessibilityProperties'), + ('alpha', 'ootype.Float'), + ('blendMode', 'ootype.String'), + ('blendShader', 'flash.display.Shader'), + ('cacheAsBitmap', 'ootype.Bool'), + ('filters', 'ootype.List'), + ('height', 'ootype.Float'), + ('loaderInfo', 'flash.display.LoaderInfo'), + ('mask', 'flash.display.DisplayObject'), + ('mouseX', 'ootype.Float'), + ('mouseY', 'ootype.Float'), + ('name', 'ootype.String'), + ('opaqueBackground', 'ootype.Dict'), + ('parent', 'flash.display.DisplayObjectContainer'), + ('root', 'flash.display.DisplayObject'), + ('rotation', 'ootype.Float'), + ('rotationX', 'ootype.Float'), + ('rotationY', 'ootype.Float'), + ('rotationZ', 'ootype.Float'), + ('scale9Grid', 'flash.geom.Rectangle'), + ('scaleX', 'ootype.Float'), + ('scaleY', 'ootype.Float'), + ('scaleZ', 'ootype.Float'), + ('scrollRect', 'flash.geom.Rectangle'), + ('stage', 'flash.display.Stage'), + ('transform', 'flash.geom.Transform'), + ('width', 'ootype.Float'), + ('visible', 'ootype.Bool'), + ('x', 'ootype.Float'), + ('y', 'ootype.Float'), + ('z', 'ootype.Float'), +] +types['flash.display.DisplayObject'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.PixelSnapping' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ALWAYS', 'String'), + ('AUTO', 'String'), + ('NEVER', 'String'), +] +types['flash.display.PixelSnapping'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsStroke' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Bool', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.Float', 'flash.display.IGraphicsFill'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('caps', 'ootype.String'), + ('joints', 'ootype.String'), + ('scaleMode', 'ootype.String'), +] +types['flash.display.GraphicsStroke'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.MovieClip' +desc.BaseType = 'Sprite' +desc.Methods = [ + ('addFrameScript', ['ootype.SignedLongLong', 'Function'], 'ootype.Void'), + ('gotoAndPlay', ['ootype.Dict', 'ootype.String'], 'ootype.Void'), + ('gotoAndStop', ['ootype.Dict', 'ootype.String'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('nextFrame', [''], 'ootype.Void'), + ('nextScene', [''], 'ootype.Void'), + ('play', [''], 'ootype.Void'), + ('prevFrame', [''], 'ootype.Void'), + ('prevScene', [''], 'ootype.Void'), + ('stop', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('currentFrame', 'ootype.SignedLongLong'), + ('currentFrameLabel', 'ootype.String'), + ('currentLabel', 'ootype.String'), + ('currentLabels', 'ootype.List'), + ('currentScene', 'flash.display.Scene'), + ('enabled', 'ootype.Bool'), + ('framesLoaded', 'ootype.SignedLongLong'), + ('scenes', 'ootype.List'), + ('totalFrames', 'ootype.SignedLongLong'), + ('trackAsMenu', 'ootype.Bool'), +] +types['flash.display.MovieClip'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.JointStyle' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BEVEL', 'String'), + ('MITER', 'String'), + ('ROUND', 'String'), +] +types['flash.display.JointStyle'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.StageAlign' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BOTTOM', 'String'), + ('BOTTOM_LEFT', 'String'), + ('BOTTOM_RIGHT', 'String'), + ('LEFT', 'String'), + ('RIGHT', 'String'), + ('TOP', 'String'), + ('TOP_LEFT', 'String'), + ('TOP_RIGHT', 'String'), +] +types['flash.display.StageAlign'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ActionScriptVersion' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ACTIONSCRIPT2', 'uint'), + ('ACTIONSCRIPT3', 'uint'), +] +types['flash.display.ActionScriptVersion'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Sprite' +desc.BaseType = 'DisplayObjectContainer' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('startDrag', ['ootype.Bool', 'flash.geom.Rectangle'], 'ootype.Void'), + ('stopDrag', [''], 'ootype.Void'), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('buttonMode', 'ootype.Bool'), + ('dropTarget', 'flash.display.DisplayObject'), + ('graphics', 'flash.display.Graphics'), + ('hitArea', 'flash.display.Sprite'), + ('soundTransform', 'flash.media.SoundTransform'), + ('useHandCursor', 'ootype.Bool'), +] +types['flash.display.Sprite'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderPrecision' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FAST', 'String'), + ('FULL', 'String'), +] +types['flash.display.ShaderPrecision'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.BlendMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ADD', 'String'), + ('ALPHA', 'String'), + ('DARKEN', 'String'), + ('DIFFERENCE', 'String'), + ('ERASE', 'String'), + ('HARDLIGHT', 'String'), + ('INVERT', 'String'), + ('LAYER', 'String'), + ('LIGHTEN', 'String'), + ('MULTIPLY', 'String'), + ('NORMAL', 'String'), + ('OVERLAY', 'String'), + ('SCREEN', 'String'), + ('SHADER', 'String'), + ('SUBTRACT', 'String'), +] +types['flash.display.BlendMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsGradientFill' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.List', 'ootype.List', 'ootype.List', '', '', 'ootype.String', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('interpolationMethod', 'ootype.String'), + ('spreadMethod', 'ootype.String'), + ('type', 'ootype.String'), +] +types['flash.display.GraphicsGradientFill'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsPath' +desc.BaseType = 'Object' +desc.Methods = [ + ('curveTo', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.SignedLongLong[]', 'ootype.Float[]', 'ootype.String'], None), + ('lineTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('moveTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('wideLineTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), + ('wideMoveTo', ['ootype.Float', 'ootype.Float'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('winding', 'ootype.String'), +] +types['flash.display.GraphicsPath'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderData' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.utils.ByteArray'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.ShaderData'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderParameter' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('index', 'ootype.SignedLongLong'), + ('type', 'ootype.String'), + ('value', 'ootype.List'), +] +types['flash.display.ShaderParameter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.TriangleCulling' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('NEGATIVE', 'String'), + ('NONE', 'String'), + ('POSITIVE', 'String'), +] +types['flash.display.TriangleCulling'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.AVM1Movie' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('addCallback', ['ootype.String', 'Function'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('call', ['ootype.String', '*args'], ''), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.AVM1Movie'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderInput' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('channels', 'ootype.SignedLongLong'), + ('height', 'ootype.SignedLongLong'), + ('index', 'ootype.SignedLongLong'), + ('input', 'ootype.Dict'), + ('width', 'ootype.SignedLongLong'), +] +types['flash.display.ShaderInput'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsEndFill' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.GraphicsEndFill'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.InterpolationMethod' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('LINEAR_RGB', 'String'), + ('RGB', 'String'), +] +types['flash.display.InterpolationMethod'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ColorCorrectionSupport' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEFAULT_OFF', 'String'), + ('DEFAULT_ON', 'String'), + ('UNSUPPORTED', 'String'), +] +types['flash.display.ColorCorrectionSupport'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsPathCommand' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CURVE_TO', 'int'), + ('LINE_TO', 'int'), + ('MOVE_TO', 'int'), + ('NO_OP', 'int'), + ('WIDE_LINE_TO', 'int'), + ('WIDE_MOVE_TO', 'int'), +] +types['flash.display.GraphicsPathCommand'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.SpreadMethod' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('PAD', 'String'), + ('REFLECT', 'String'), + ('REPEAT', 'String'), +] +types['flash.display.SpreadMethod'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.InteractiveObject' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('accessibilityImplementation', 'flash.accessibility.AccessibilityImplementation'), + ('contextMenu', 'flash.ui.ContextMenu'), + ('doubleClickEnabled', 'ootype.Bool'), + ('focusRect', 'ootype.Dict'), + ('mouseEnabled', 'ootype.Bool'), + ('tabEnabled', 'ootype.Bool'), + ('tabIndex', 'ootype.SignedLongLong'), +] +types['flash.display.InteractiveObject'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsPathWinding' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('EVEN_ODD', 'String'), + ('NON_ZERO', 'String'), +] +types['flash.display.GraphicsPathWinding'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.BitmapData' +desc.BaseType = 'Object' +desc.Methods = [ + ('applyFilter', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'flash.filters.BitmapFilter'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.Bool', 'ootype.UnsignedLongLong'], None), + ('clone', [''], 'flash.display.BitmapData'), + ('colorTransform', ['flash.geom.Rectangle', 'flash.geom.ColorTransform'], 'ootype.Void'), + ('compare', ['flash.display.BitmapData'], 'ootype.Dict'), + ('copyChannel', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('copyPixels', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'flash.display.BitmapData', 'flash.geom.Point', 'ootype.Bool'], 'ootype.Void'), + ('dispose', [''], 'ootype.Void'), + ('draw', ['flash.display.IBitmapDrawable', 'flash.geom.Matrix', 'flash.geom.ColorTransform', 'ootype.String', 'flash.geom.Rectangle', 'ootype.Bool'], 'ootype.Void'), + ('fillRect', ['flash.geom.Rectangle', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('floodFill', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('generateFilterRect', ['flash.geom.Rectangle', 'flash.filters.BitmapFilter'], 'flash.geom.Rectangle'), + ('getColorBoundsRect', ['ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Bool'], 'flash.geom.Rectangle'), + ('getPixel', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.UnsignedLongLong'), + ('getPixel32', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.UnsignedLongLong'), + ('getPixels', ['flash.geom.Rectangle'], 'flash.utils.ByteArray'), + ('getVector', ['flash.geom.Rectangle'], 'ootype.UnsignedLongLong[]'), + ('histogram', ['flash.geom.Rectangle'], 'ootype.Float[][]'), + ('hitTest', ['flash.geom.Point', 'ootype.UnsignedLongLong', 'ootype.Dict', 'flash.geom.Point', 'ootype.UnsignedLongLong'], 'ootype.Bool'), + ('lock', [''], 'ootype.Void'), + ('merge', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('noise', ['ootype.SignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('paletteMap', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'ootype.List', 'ootype.List', 'ootype.List', 'ootype.List'], 'ootype.Void'), + ('perlinNoise', ['ootype.Float', 'ootype.Float', 'ootype.UnsignedLongLong', 'ootype.SignedLongLong', 'ootype.Bool', 'ootype.Bool', 'ootype.UnsignedLongLong', 'ootype.Bool', 'ootype.List'], 'ootype.Void'), + ('pixelDissolve', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.SignedLongLong'), + ('scroll', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), + ('setPixel', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('setPixel32', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('setPixels', ['flash.geom.Rectangle', 'flash.utils.ByteArray'], 'ootype.Void'), + ('setVector', ['flash.geom.Rectangle', 'ootype.UnsignedLongLong[]'], 'ootype.Void'), + ('threshold', ['flash.display.BitmapData', 'flash.geom.Rectangle', 'flash.geom.Point', 'ootype.String', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Bool'], 'ootype.UnsignedLongLong'), + ('unlock', ['flash.geom.Rectangle'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('height', 'ootype.SignedLongLong'), + ('rect', 'flash.geom.Rectangle'), + ('transparent', 'ootype.Bool'), + ('width', 'ootype.SignedLongLong'), +] +types['flash.display.BitmapData'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.GraphicsBitmapFill' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.BitmapData', 'flash.geom.Matrix', 'ootype.Bool', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.display.GraphicsBitmapFill'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.DisplayObjectContainer' +desc.BaseType = 'InteractiveObject' +desc.Methods = [ + ('addChild', ['flash.display.DisplayObject'], 'flash.display.DisplayObject'), + ('addChildAt', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('areInaccessibleObjectsUnderPoint', ['flash.geom.Point'], 'ootype.Bool'), + ('contains', ['flash.display.DisplayObject'], 'ootype.Bool'), + ('!CONSTRUCTOR!', [''], None), + ('getChildAt', ['ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('getChildByName', ['ootype.String'], 'flash.display.DisplayObject'), + ('getChildIndex', ['flash.display.DisplayObject'], 'ootype.SignedLongLong'), + ('getObjectsUnderPoint', ['flash.geom.Point'], 'ootype.List'), + ('removeChild', ['flash.display.DisplayObject'], 'flash.display.DisplayObject'), + ('removeChildAt', ['ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('setChildIndex', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'ootype.Void'), + ('swapChildren', ['flash.display.DisplayObject', 'flash.display.DisplayObject'], 'ootype.Void'), + ('swapChildrenAt', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('mouseChildren', 'ootype.Bool'), + ('numChildren', 'ootype.SignedLongLong'), + ('tabChildren', 'ootype.Bool'), + ('textSnapshot', 'flash.text.TextSnapshot'), +] +types['flash.display.DisplayObjectContainer'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.Stage' +desc.BaseType = 'DisplayObjectContainer' +desc.Methods = [ + ('addChild', ['flash.display.DisplayObject'], 'flash.display.DisplayObject'), + ('addChildAt', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('addEventListener', ['ootype.String', 'Function', 'ootype.Bool', 'ootype.SignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('dispatchEvent', ['flash.events.Event'], 'ootype.Bool'), + ('hasEventListener', ['ootype.String'], 'ootype.Bool'), + ('invalidate', [''], 'ootype.Void'), + ('isFocusInaccessible', [''], 'ootype.Bool'), + ('removeChildAt', ['ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('setChildIndex', ['flash.display.DisplayObject', 'ootype.SignedLongLong'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('swapChildrenAt', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), + ('willTrigger', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('accessibilityImplementation', 'flash.accessibility.AccessibilityImplementation'), + ('accessibilityProperties', 'flash.accessibility.AccessibilityProperties'), + ('align', 'ootype.String'), + ('alpha', 'ootype.Float'), + ('blendMode', 'ootype.String'), + ('cacheAsBitmap', 'ootype.Bool'), + ('colorCorrection', 'ootype.String'), + ('colorCorrectionSupport', 'ootype.String'), + ('contextMenu', 'flash.ui.ContextMenu'), + ('displayState', 'ootype.String'), + ('filters', 'ootype.List'), + ('focus', 'flash.display.InteractiveObject'), + ('focusRect', 'ootype.Dict'), + ('frameRate', 'ootype.Float'), + ('fullScreenHeight', 'ootype.UnsignedLongLong'), + ('fullScreenSourceRect', 'flash.geom.Rectangle'), + ('fullScreenWidth', 'ootype.UnsignedLongLong'), + ('height', 'ootype.Float'), + ('mask', 'flash.display.DisplayObject'), + ('mouseChildren', 'ootype.Bool'), + ('mouseEnabled', 'ootype.Bool'), + ('name', 'ootype.String'), + ('numChildren', 'ootype.SignedLongLong'), + ('opaqueBackground', 'ootype.Dict'), + ('quality', 'ootype.String'), + ('rotation', 'ootype.Float'), + ('rotationX', 'ootype.Float'), + ('rotationY', 'ootype.Float'), + ('rotationZ', 'ootype.Float'), + ('scale9Grid', 'flash.geom.Rectangle'), + ('scaleMode', 'ootype.String'), + ('scaleX', 'ootype.Float'), + ('scaleY', 'ootype.Float'), + ('scaleZ', 'ootype.Float'), + ('scrollRect', 'flash.geom.Rectangle'), + ('showDefaultContextMenu', 'ootype.Bool'), + ('stageFocusRect', 'ootype.Bool'), + ('stageHeight', 'ootype.SignedLongLong'), + ('stageWidth', 'ootype.SignedLongLong'), + ('tabChildren', 'ootype.Bool'), + ('tabEnabled', 'ootype.Bool'), + ('tabIndex', 'ootype.SignedLongLong'), + ('textSnapshot', 'flash.text.TextSnapshot'), + ('transform', 'flash.geom.Transform'), + ('width', 'ootype.Float'), + ('visible', 'ootype.Bool'), + ('x', 'ootype.Float'), + ('y', 'ootype.Float'), + ('z', 'ootype.Float'), +] +types['flash.display.Stage'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.ShaderJob' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('cancel', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['flash.display.Shader', 'ootype.Dict', 'ootype.SignedLongLong', 'ootype.SignedLongLong'], None), + ('start', ['ootype.Bool'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('height', 'ootype.SignedLongLong'), + ('progress', 'ootype.Float'), + ('shader', 'flash.display.Shader'), + ('target', 'ootype.Dict'), + ('width', 'ootype.SignedLongLong'), +] +types['flash.display.ShaderJob'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.FrameLabel' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('frame', 'ootype.SignedLongLong'), + ('name', 'ootype.String'), +] +types['flash.display.FrameLabel'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.BitmapDataChannel' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ALPHA', 'uint'), + ('BLUE', 'uint'), + ('GREEN', 'uint'), + ('RED', 'uint'), +] +types['flash.display.BitmapDataChannel'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.LoaderInfo' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('dispatchEvent', ['flash.events.Event'], 'ootype.Bool'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('getLoaderInfoByDefinition', ['ootype.Dict'], 'flash.display.LoaderInfo'), +] +desc.Fields = [] +desc.StaticFields = [ + ('actionScriptVersion', 'ootype.UnsignedLongLong'), + ('applicationDomain', 'flash.system.ApplicationDomain'), + ('bytes', 'flash.utils.ByteArray'), + ('bytesLoaded', 'ootype.UnsignedLongLong'), + ('bytesTotal', 'ootype.UnsignedLongLong'), + ('childAllowsParent', 'ootype.Bool'), + ('content', 'flash.display.DisplayObject'), + ('contentType', 'ootype.String'), + ('frameRate', 'ootype.Float'), + ('height', 'ootype.SignedLongLong'), + ('loader', 'flash.display.Loader'), + ('loaderURL', 'ootype.String'), + ('parameters', 'ootype.Dict'), + ('parentAllowsChild', 'ootype.Bool'), + ('sameDomain', 'ootype.Bool'), + ('sharedEvents', 'flash.events.EventDispatcher'), + ('swfVersion', 'ootype.UnsignedLongLong'), + ('url', 'ootype.String'), + ('width', 'ootype.SignedLongLong'), +] +types['flash.display.LoaderInfo'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.display.StageQuality' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BEST', 'String'), + ('HIGH', 'String'), + ('LOW', 'String'), + ('MEDIUM', 'String'), +] +types['flash.display.StageQuality'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.accessibility.AccessibilityProperties' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.accessibility.AccessibilityProperties'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.accessibility.Accessibility' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('sendEvent', ['flash.display.DisplayObject', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('updateProperties', [''], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('active', 'ootype.Bool'), +] +types['flash.accessibility.Accessibility'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.accessibility.AccessibilityImplementation' +desc.BaseType = 'Object' +desc.Methods = [ + ('accDoDefaultAction', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('accLocation', ['ootype.UnsignedLongLong'], ''), + ('accSelect', ['ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('get_accDefaultAction', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('get_accFocus', [''], 'ootype.UnsignedLongLong'), + ('get_accName', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('get_accRole', ['ootype.UnsignedLongLong'], 'ootype.UnsignedLongLong'), + ('get_accSelection', [''], 'ootype.List'), + ('get_accState', ['ootype.UnsignedLongLong'], 'ootype.UnsignedLongLong'), + ('get_accValue', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('getChildIDArray', [''], 'ootype.List'), + ('isLabeledBy', ['flash.geom.Rectangle'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.accessibility.AccessibilityImplementation'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.accessibility.AccessibilityProperties' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.accessibility.AccessibilityProperties'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.accessibility.AccessibilityImplementation' +desc.BaseType = 'Object' +desc.Methods = [ + ('accDoDefaultAction', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('accLocation', ['ootype.UnsignedLongLong'], ''), + ('accSelect', ['ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('get_accDefaultAction', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('get_accFocus', [''], 'ootype.UnsignedLongLong'), + ('get_accName', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('get_accRole', ['ootype.UnsignedLongLong'], 'ootype.UnsignedLongLong'), + ('get_accSelection', [''], 'ootype.List'), + ('get_accState', ['ootype.UnsignedLongLong'], 'ootype.UnsignedLongLong'), + ('get_accValue', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('getChildIDArray', [''], 'ootype.List'), + ('isLabeledBy', ['flash.geom.Rectangle'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.accessibility.AccessibilityImplementation'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.accessibility.Accessibility' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('sendEvent', ['flash.display.DisplayObject', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('updateProperties', [''], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('active', 'ootype.Bool'), +] +types['flash.accessibility.Accessibility'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.BlurFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.SignedLongLong'], None), + ('clone', [''], 'flash.filters.BitmapFilter'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('quality', 'ootype.SignedLongLong'), +] +types['flash.filters.BlurFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.BitmapFilterType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FULL', 'String'), + ('INNER', 'String'), + ('OUTER', 'String'), +] +types['flash.filters.BitmapFilterType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.GradientGlowFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.List', 'ootype.List', 'ootype.List', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.SignedLongLong', 'ootype.String', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alphas', 'ootype.List'), + ('angle', 'ootype.Float'), + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('colors', 'ootype.List'), + ('distance', 'ootype.Float'), + ('knockout', 'ootype.Bool'), + ('quality', 'ootype.SignedLongLong'), + ('ratios', 'ootype.List'), + ('strength', 'ootype.Float'), + ('type', 'ootype.String'), +] +types['flash.filters.GradientGlowFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.BitmapFilter' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('clone', [''], 'flash.filters.BitmapFilter'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.filters.BitmapFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.BitmapFilterQuality' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('HIGH', 'int'), + ('LOW', 'int'), + ('MEDIUM', 'int'), +] +types['flash.filters.BitmapFilterQuality'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.DisplacementMapFilterMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CLAMP', 'String'), + ('COLOR', 'String'), + ('IGNORE', 'String'), + ('WRAP', 'String'), +] +types['flash.filters.DisplacementMapFilterMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.GlowFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.UnsignedLongLong', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.SignedLongLong', 'ootype.Bool', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alpha', 'ootype.Float'), + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('color', 'ootype.UnsignedLongLong'), + ('inner', 'ootype.Bool'), + ('knockout', 'ootype.Bool'), + ('quality', 'ootype.SignedLongLong'), + ('strength', 'ootype.Float'), +] +types['flash.filters.GlowFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.DisplacementMapFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['flash.display.BitmapData', 'flash.geom.Point', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.Float', 'ootype.String', 'ootype.UnsignedLongLong', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alpha', 'ootype.Float'), + ('color', 'ootype.UnsignedLongLong'), + ('componentX', 'ootype.UnsignedLongLong'), + ('componentY', 'ootype.UnsignedLongLong'), + ('mapBitmap', 'flash.display.BitmapData'), + ('mapPoint', 'flash.geom.Point'), + ('mode', 'ootype.String'), + ('scaleX', 'ootype.Float'), + ('scaleY', 'ootype.Float'), +] +types['flash.filters.DisplacementMapFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.ShaderFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.Shader'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bottomExtension', 'ootype.SignedLongLong'), + ('leftExtension', 'ootype.SignedLongLong'), + ('rightExtension', 'ootype.SignedLongLong'), + ('shader', 'flash.display.Shader'), + ('topExtension', 'ootype.SignedLongLong'), +] +types['flash.filters.ShaderFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.GradientBevelFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.List', 'ootype.List', 'ootype.List', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.SignedLongLong', 'ootype.String', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alphas', 'ootype.List'), + ('angle', 'ootype.Float'), + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('colors', 'ootype.List'), + ('distance', 'ootype.Float'), + ('knockout', 'ootype.Bool'), + ('quality', 'ootype.SignedLongLong'), + ('ratios', 'ootype.List'), + ('strength', 'ootype.Float'), + ('type', 'ootype.String'), +] +types['flash.filters.GradientBevelFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.DropShadowFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.SignedLongLong', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alpha', 'ootype.Float'), + ('angle', 'ootype.Float'), + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('color', 'ootype.UnsignedLongLong'), + ('distance', 'ootype.Float'), + ('hideObject', 'ootype.Bool'), + ('inner', 'ootype.Bool'), + ('knockout', 'ootype.Bool'), + ('quality', 'ootype.SignedLongLong'), + ('strength', 'ootype.Float'), +] +types['flash.filters.DropShadowFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.ColorMatrixFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.List'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('matrix', 'ootype.List'), +] +types['flash.filters.ColorMatrixFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.ConvolutionFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.List', 'ootype.Float', 'ootype.Float', 'ootype.Bool', 'ootype.Bool', 'ootype.UnsignedLongLong', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alpha', 'ootype.Float'), + ('bias', 'ootype.Float'), + ('clamp', 'ootype.Bool'), + ('color', 'ootype.UnsignedLongLong'), + ('divisor', 'ootype.Float'), + ('matrix', 'ootype.List'), + ('matrixX', 'ootype.Float'), + ('matrixY', 'ootype.Float'), + ('preserveAlpha', 'ootype.Bool'), +] +types['flash.filters.ConvolutionFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.BevelFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.SignedLongLong', 'ootype.String', 'ootype.Bool'], None), + ('clone', [''], 'flash.filters.BitmapFilter'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('angle', 'ootype.Float'), + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('distance', 'ootype.Float'), + ('highlightAlpha', 'ootype.Float'), + ('highlightColor', 'ootype.UnsignedLongLong'), + ('knockout', 'ootype.Bool'), + ('quality', 'ootype.SignedLongLong'), + ('shadowAlpha', 'ootype.Float'), + ('shadowColor', 'ootype.UnsignedLongLong'), + ('strength', 'ootype.Float'), + ('type', 'ootype.String'), +] +types['flash.filters.BevelFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.BitmapFilter' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('clone', [''], 'flash.filters.BitmapFilter'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.filters.BitmapFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.DisplacementMapFilterMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CLAMP', 'String'), + ('COLOR', 'String'), + ('IGNORE', 'String'), + ('WRAP', 'String'), +] +types['flash.filters.DisplacementMapFilterMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.GradientBevelFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.List', 'ootype.List', 'ootype.List', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.SignedLongLong', 'ootype.String', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alphas', 'ootype.List'), + ('angle', 'ootype.Float'), + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('colors', 'ootype.List'), + ('distance', 'ootype.Float'), + ('knockout', 'ootype.Bool'), + ('quality', 'ootype.SignedLongLong'), + ('ratios', 'ootype.List'), + ('strength', 'ootype.Float'), + ('type', 'ootype.String'), +] +types['flash.filters.GradientBevelFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.BlurFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.SignedLongLong'], None), + ('clone', [''], 'flash.filters.BitmapFilter'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('quality', 'ootype.SignedLongLong'), +] +types['flash.filters.BlurFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.GradientGlowFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.List', 'ootype.List', 'ootype.List', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.SignedLongLong', 'ootype.String', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alphas', 'ootype.List'), + ('angle', 'ootype.Float'), + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('colors', 'ootype.List'), + ('distance', 'ootype.Float'), + ('knockout', 'ootype.Bool'), + ('quality', 'ootype.SignedLongLong'), + ('ratios', 'ootype.List'), + ('strength', 'ootype.Float'), + ('type', 'ootype.String'), +] +types['flash.filters.GradientGlowFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.BitmapFilterType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('FULL', 'String'), + ('INNER', 'String'), + ('OUTER', 'String'), +] +types['flash.filters.BitmapFilterType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.BitmapFilterQuality' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('HIGH', 'int'), + ('LOW', 'int'), + ('MEDIUM', 'int'), +] +types['flash.filters.BitmapFilterQuality'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.DropShadowFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.SignedLongLong', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alpha', 'ootype.Float'), + ('angle', 'ootype.Float'), + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('color', 'ootype.UnsignedLongLong'), + ('distance', 'ootype.Float'), + ('hideObject', 'ootype.Bool'), + ('inner', 'ootype.Bool'), + ('knockout', 'ootype.Bool'), + ('quality', 'ootype.SignedLongLong'), + ('strength', 'ootype.Float'), +] +types['flash.filters.DropShadowFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.ColorMatrixFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.List'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('matrix', 'ootype.List'), +] +types['flash.filters.ColorMatrixFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.GlowFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.UnsignedLongLong', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.SignedLongLong', 'ootype.Bool', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alpha', 'ootype.Float'), + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('color', 'ootype.UnsignedLongLong'), + ('inner', 'ootype.Bool'), + ('knockout', 'ootype.Bool'), + ('quality', 'ootype.SignedLongLong'), + ('strength', 'ootype.Float'), +] +types['flash.filters.GlowFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.BevelFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.SignedLongLong', 'ootype.String', 'ootype.Bool'], None), + ('clone', [''], 'flash.filters.BitmapFilter'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('angle', 'ootype.Float'), + ('blurX', 'ootype.Float'), + ('blurY', 'ootype.Float'), + ('distance', 'ootype.Float'), + ('highlightAlpha', 'ootype.Float'), + ('highlightColor', 'ootype.UnsignedLongLong'), + ('knockout', 'ootype.Bool'), + ('quality', 'ootype.SignedLongLong'), + ('shadowAlpha', 'ootype.Float'), + ('shadowColor', 'ootype.UnsignedLongLong'), + ('strength', 'ootype.Float'), + ('type', 'ootype.String'), +] +types['flash.filters.BevelFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.ShaderFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.Shader'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bottomExtension', 'ootype.SignedLongLong'), + ('leftExtension', 'ootype.SignedLongLong'), + ('rightExtension', 'ootype.SignedLongLong'), + ('shader', 'flash.display.Shader'), + ('topExtension', 'ootype.SignedLongLong'), +] +types['flash.filters.ShaderFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.ConvolutionFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.List', 'ootype.Float', 'ootype.Float', 'ootype.Bool', 'ootype.Bool', 'ootype.UnsignedLongLong', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alpha', 'ootype.Float'), + ('bias', 'ootype.Float'), + ('clamp', 'ootype.Bool'), + ('color', 'ootype.UnsignedLongLong'), + ('divisor', 'ootype.Float'), + ('matrix', 'ootype.List'), + ('matrixX', 'ootype.Float'), + ('matrixY', 'ootype.Float'), + ('preserveAlpha', 'ootype.Bool'), +] +types['flash.filters.ConvolutionFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.filters.DisplacementMapFilter' +desc.BaseType = 'BitmapFilter' +desc.Methods = [ + ('clone', [''], 'flash.filters.BitmapFilter'), + ('!CONSTRUCTOR!', ['flash.display.BitmapData', 'flash.geom.Point', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.Float', 'ootype.String', 'ootype.UnsignedLongLong', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alpha', 'ootype.Float'), + ('color', 'ootype.UnsignedLongLong'), + ('componentX', 'ootype.UnsignedLongLong'), + ('componentY', 'ootype.UnsignedLongLong'), + ('mapBitmap', 'flash.display.BitmapData'), + ('mapPoint', 'flash.geom.Point'), + ('mode', 'ootype.String'), + ('scaleX', 'ootype.Float'), + ('scaleY', 'ootype.Float'), +] +types['flash.filters.DisplacementMapFilter'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextRenderer' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('setAdvancedAntiAliasingTable', ['ootype.String', 'ootype.String', 'ootype.String', 'ootype.List'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('antiAliasType', 'ootype.String'), + ('displayMode', 'ootype.String'), + ('maxLevel', 'ootype.SignedLongLong'), +] +types['flash.text.TextRenderer'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.FontStyle' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BOLD', 'String'), + ('BOLD_ITALIC', 'String'), + ('ITALIC', 'String'), + ('REGULAR', 'String'), +] +types['flash.text.FontStyle'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextColorType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DARK_COLOR', 'String'), + ('LIGHT_COLOR', 'String'), +] +types['flash.text.TextColorType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.FontType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEVICE', 'String'), + ('EMBEDDED', 'String'), + ('EMBEDDED_CFF', 'String'), +] +types['flash.text.FontType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextSnapshot' +desc.BaseType = 'Object' +desc.Methods = [ + ('findText', ['ootype.SignedLongLong', 'ootype.String', 'ootype.Bool'], 'ootype.SignedLongLong'), + ('getSelected', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Bool'), + ('getSelectedText', ['ootype.Bool'], 'ootype.String'), + ('getText', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.Bool'], 'ootype.String'), + ('getTextRunInfo', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.List'), + ('hitTestTextNearPos', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Float'), + ('setSelectColor', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('setSelected', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('charCount', 'ootype.SignedLongLong'), +] +types['flash.text.TextSnapshot'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextFormatDisplay' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BLOCK', 'String'), + ('INLINE', 'String'), +] +types['flash.text.TextFormatDisplay'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.StaticText' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('text', 'ootype.String'), +] +types['flash.text.StaticText'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.CSMSettings' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.text.CSMSettings'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextFieldType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DYNAMIC', 'String'), + ('INPUT', 'String'), +] +types['flash.text.TextFieldType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.AntiAliasType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ADVANCED', 'String'), + ('NORMAL', 'String'), +] +types['flash.text.AntiAliasType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextField' +desc.BaseType = 'InteractiveObject' +desc.Methods = [ + ('appendText', ['ootype.String'], 'ootype.Void'), + ('getCharBoundaries', ['ootype.SignedLongLong'], 'flash.geom.Rectangle'), + ('getCharIndexAtPoint', ['ootype.Float', 'ootype.Float'], 'ootype.SignedLongLong'), + ('getFirstCharInParagraph', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getImageReference', ['ootype.String'], 'flash.display.DisplayObject'), + ('getLineIndexAtPoint', ['ootype.Float', 'ootype.Float'], 'ootype.SignedLongLong'), + ('getLineIndexOfChar', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getLineLength', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getLineMetrics', ['ootype.SignedLongLong'], 'flash.text.TextLineMetrics'), + ('getLineOffset', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getLineText', ['ootype.SignedLongLong'], 'ootype.String'), + ('getParagraphLength', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getRawText', [''], 'ootype.String'), + ('getTextFormat', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'flash.text.TextFormat'), + ('getTextRuns', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.List'), + ('getXMLText', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.String'), + ('insertXMLText', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.String', 'ootype.Bool'], 'ootype.Void'), + ('replaceSelectedText', ['ootype.String'], 'ootype.Void'), + ('replaceText', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.String'], 'ootype.Void'), + ('setSelection', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), + ('setTextFormat', ['flash.text.TextFormat', 'ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('isFontCompatible', ['ootype.String', 'ootype.String'], 'ootype.Bool'), +] +desc.Fields = [] +desc.StaticFields = [ + ('alwaysShowSelection', 'ootype.Bool'), + ('antiAliasType', 'ootype.String'), + ('autoSize', 'ootype.String'), + ('background', 'ootype.Bool'), + ('backgroundColor', 'ootype.UnsignedLongLong'), + ('border', 'ootype.Bool'), + ('borderColor', 'ootype.UnsignedLongLong'), + ('bottomScrollV', 'ootype.SignedLongLong'), + ('caretIndex', 'ootype.SignedLongLong'), + ('condenseWhite', 'ootype.Bool'), + ('defaultTextFormat', 'flash.text.TextFormat'), + ('displayAsPassword', 'ootype.Bool'), + ('embedFonts', 'ootype.Bool'), + ('gridFitType', 'ootype.String'), + ('htmlText', 'ootype.String'), + ('length', 'ootype.SignedLongLong'), + ('maxChars', 'ootype.SignedLongLong'), + ('maxScrollH', 'ootype.SignedLongLong'), + ('maxScrollV', 'ootype.SignedLongLong'), + ('mouseWheelEnabled', 'ootype.Bool'), + ('multiline', 'ootype.Bool'), + ('numLines', 'ootype.SignedLongLong'), + ('restrict', 'ootype.String'), + ('scrollH', 'ootype.SignedLongLong'), + ('scrollV', 'ootype.SignedLongLong'), + ('selectable', 'ootype.Bool'), + ('selectedText', 'ootype.String'), + ('selectionBeginIndex', 'ootype.SignedLongLong'), + ('selectionEndIndex', 'ootype.SignedLongLong'), + ('sharpness', 'ootype.Float'), + ('styleSheet', 'flash.text.StyleSheet'), + ('text', 'ootype.String'), + ('textColor', 'ootype.UnsignedLongLong'), + ('textHeight', 'ootype.Float'), + ('textWidth', 'ootype.Float'), + ('thickness', 'ootype.Float'), + ('type', 'ootype.String'), + ('useRichTextClipboard', 'ootype.Bool'), + ('wordWrap', 'ootype.Bool'), +] +types['flash.text.TextField'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextDisplayMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CRT', 'String'), + ('DEFAULT', 'String'), + ('LCD', 'String'), +] +types['flash.text.TextDisplayMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextFieldAutoSize' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CENTER', 'String'), + ('LEFT', 'String'), + ('NONE', 'String'), + ('RIGHT', 'String'), +] +types['flash.text.TextFieldAutoSize'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextExtent' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.text.TextExtent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextFormatAlign' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CENTER', 'String'), + ('JUSTIFY', 'String'), + ('LEFT', 'String'), + ('RIGHT', 'String'), +] +types['flash.text.TextFormatAlign'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextRun' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'flash.text.TextFormat'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.text.TextRun'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextLineMetrics' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.text.TextLineMetrics'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextFormat' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Dict', 'ootype.Dict', 'ootype.Dict', 'ootype.Dict', 'ootype.Dict', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.Dict', 'ootype.Dict', 'ootype.Dict', 'ootype.Dict'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('align', 'ootype.String'), + ('blockIndent', 'ootype.Dict'), + ('bold', 'ootype.Dict'), + ('bullet', 'ootype.Dict'), + ('color', 'ootype.Dict'), + ('display', 'ootype.String'), + ('font', 'ootype.String'), + ('indent', 'ootype.Dict'), + ('italic', 'ootype.Dict'), + ('kerning', 'ootype.Dict'), + ('leading', 'ootype.Dict'), + ('leftMargin', 'ootype.Dict'), + ('letterSpacing', 'ootype.Dict'), + ('rightMargin', 'ootype.Dict'), + ('size', 'ootype.Dict'), + ('tabStops', 'ootype.List'), + ('target', 'ootype.String'), + ('underline', 'ootype.Dict'), + ('url', 'ootype.String'), +] +types['flash.text.TextFormat'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.Font' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('hasGlyphs', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [ + ('enumerateFonts', ['ootype.Bool'], 'ootype.List'), + ('registerFont', ['Class'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('fontName', 'ootype.String'), + ('fontStyle', 'ootype.String'), + ('fontType', 'ootype.String'), +] +types['flash.text.Font'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.StyleSheet' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('clear', [''], 'ootype.Void'), + ('getStyle', ['ootype.String'], 'ootype.Dict'), + ('parseCSS', ['ootype.String'], 'ootype.Void'), + ('setStyle', ['ootype.String', 'ootype.Dict'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('transform', ['ootype.Dict'], 'flash.text.TextFormat'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('styleNames', 'ootype.List'), +] +types['flash.text.StyleSheet'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.GridFitType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('NONE', 'String'), + ('PIXEL', 'String'), + ('SUBPIXEL', 'String'), +] +types['flash.text.GridFitType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextColorType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DARK_COLOR', 'String'), + ('LIGHT_COLOR', 'String'), +] +types['flash.text.TextColorType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextDisplayMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CRT', 'String'), + ('DEFAULT', 'String'), + ('LCD', 'String'), +] +types['flash.text.TextDisplayMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.CSMSettings' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.text.CSMSettings'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.StaticText' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('text', 'ootype.String'), +] +types['flash.text.StaticText'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextSnapshot' +desc.BaseType = 'Object' +desc.Methods = [ + ('findText', ['ootype.SignedLongLong', 'ootype.String', 'ootype.Bool'], 'ootype.SignedLongLong'), + ('getSelected', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Bool'), + ('getSelectedText', ['ootype.Bool'], 'ootype.String'), + ('getText', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.Bool'], 'ootype.String'), + ('getTextRunInfo', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.List'), + ('hitTestTextNearPos', ['ootype.Float', 'ootype.Float', 'ootype.Float'], 'ootype.Float'), + ('setSelectColor', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('setSelected', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.Bool'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('charCount', 'ootype.SignedLongLong'), +] +types['flash.text.TextSnapshot'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextLineMetrics' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.text.TextLineMetrics'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.AntiAliasType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ADVANCED', 'String'), + ('NORMAL', 'String'), +] +types['flash.text.AntiAliasType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.FontType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEVICE', 'String'), + ('EMBEDDED', 'String'), + ('EMBEDDED_CFF', 'String'), +] +types['flash.text.FontType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextRun' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'flash.text.TextFormat'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.text.TextRun'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextExtent' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.text.TextExtent'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.Font' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('hasGlyphs', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [ + ('enumerateFonts', ['ootype.Bool'], 'ootype.List'), + ('registerFont', ['Class'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('fontName', 'ootype.String'), + ('fontStyle', 'ootype.String'), + ('fontType', 'ootype.String'), +] +types['flash.text.Font'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextFieldAutoSize' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CENTER', 'String'), + ('LEFT', 'String'), + ('NONE', 'String'), + ('RIGHT', 'String'), +] +types['flash.text.TextFieldAutoSize'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.StyleSheet' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('clear', [''], 'ootype.Void'), + ('getStyle', ['ootype.String'], 'ootype.Dict'), + ('parseCSS', ['ootype.String'], 'ootype.Void'), + ('setStyle', ['ootype.String', 'ootype.Dict'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('transform', ['ootype.Dict'], 'flash.text.TextFormat'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('styleNames', 'ootype.List'), +] +types['flash.text.StyleSheet'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextFieldType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DYNAMIC', 'String'), + ('INPUT', 'String'), +] +types['flash.text.TextFieldType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextFormat' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Dict', 'ootype.Dict', 'ootype.Dict', 'ootype.Dict', 'ootype.Dict', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.Dict', 'ootype.Dict', 'ootype.Dict', 'ootype.Dict'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('align', 'ootype.String'), + ('blockIndent', 'ootype.Dict'), + ('bold', 'ootype.Dict'), + ('bullet', 'ootype.Dict'), + ('color', 'ootype.Dict'), + ('display', 'ootype.String'), + ('font', 'ootype.String'), + ('indent', 'ootype.Dict'), + ('italic', 'ootype.Dict'), + ('kerning', 'ootype.Dict'), + ('leading', 'ootype.Dict'), + ('leftMargin', 'ootype.Dict'), + ('letterSpacing', 'ootype.Dict'), + ('rightMargin', 'ootype.Dict'), + ('size', 'ootype.Dict'), + ('tabStops', 'ootype.List'), + ('target', 'ootype.String'), + ('underline', 'ootype.Dict'), + ('url', 'ootype.String'), +] +types['flash.text.TextFormat'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextFormatAlign' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CENTER', 'String'), + ('JUSTIFY', 'String'), + ('LEFT', 'String'), + ('RIGHT', 'String'), +] +types['flash.text.TextFormatAlign'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextRenderer' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('setAdvancedAntiAliasingTable', ['ootype.String', 'ootype.String', 'ootype.String', 'ootype.List'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('antiAliasType', 'ootype.String'), + ('displayMode', 'ootype.String'), + ('maxLevel', 'ootype.SignedLongLong'), +] +types['flash.text.TextRenderer'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextFormatDisplay' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BLOCK', 'String'), + ('INLINE', 'String'), +] +types['flash.text.TextFormatDisplay'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.TextField' +desc.BaseType = 'InteractiveObject' +desc.Methods = [ + ('appendText', ['ootype.String'], 'ootype.Void'), + ('getCharBoundaries', ['ootype.SignedLongLong'], 'flash.geom.Rectangle'), + ('getCharIndexAtPoint', ['ootype.Float', 'ootype.Float'], 'ootype.SignedLongLong'), + ('getFirstCharInParagraph', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getImageReference', ['ootype.String'], 'flash.display.DisplayObject'), + ('getLineIndexAtPoint', ['ootype.Float', 'ootype.Float'], 'ootype.SignedLongLong'), + ('getLineIndexOfChar', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getLineLength', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getLineMetrics', ['ootype.SignedLongLong'], 'flash.text.TextLineMetrics'), + ('getLineOffset', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getLineText', ['ootype.SignedLongLong'], 'ootype.String'), + ('getParagraphLength', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getRawText', [''], 'ootype.String'), + ('getTextFormat', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'flash.text.TextFormat'), + ('getTextRuns', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.List'), + ('getXMLText', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.String'), + ('insertXMLText', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.String', 'ootype.Bool'], 'ootype.Void'), + ('replaceSelectedText', ['ootype.String'], 'ootype.Void'), + ('replaceText', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.String'], 'ootype.Void'), + ('setSelection', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), + ('setTextFormat', ['flash.text.TextFormat', 'ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('isFontCompatible', ['ootype.String', 'ootype.String'], 'ootype.Bool'), +] +desc.Fields = [] +desc.StaticFields = [ + ('alwaysShowSelection', 'ootype.Bool'), + ('antiAliasType', 'ootype.String'), + ('autoSize', 'ootype.String'), + ('background', 'ootype.Bool'), + ('backgroundColor', 'ootype.UnsignedLongLong'), + ('border', 'ootype.Bool'), + ('borderColor', 'ootype.UnsignedLongLong'), + ('bottomScrollV', 'ootype.SignedLongLong'), + ('caretIndex', 'ootype.SignedLongLong'), + ('condenseWhite', 'ootype.Bool'), + ('defaultTextFormat', 'flash.text.TextFormat'), + ('displayAsPassword', 'ootype.Bool'), + ('embedFonts', 'ootype.Bool'), + ('gridFitType', 'ootype.String'), + ('htmlText', 'ootype.String'), + ('length', 'ootype.SignedLongLong'), + ('maxChars', 'ootype.SignedLongLong'), + ('maxScrollH', 'ootype.SignedLongLong'), + ('maxScrollV', 'ootype.SignedLongLong'), + ('mouseWheelEnabled', 'ootype.Bool'), + ('multiline', 'ootype.Bool'), + ('numLines', 'ootype.SignedLongLong'), + ('restrict', 'ootype.String'), + ('scrollH', 'ootype.SignedLongLong'), + ('scrollV', 'ootype.SignedLongLong'), + ('selectable', 'ootype.Bool'), + ('selectedText', 'ootype.String'), + ('selectionBeginIndex', 'ootype.SignedLongLong'), + ('selectionEndIndex', 'ootype.SignedLongLong'), + ('sharpness', 'ootype.Float'), + ('styleSheet', 'flash.text.StyleSheet'), + ('text', 'ootype.String'), + ('textColor', 'ootype.UnsignedLongLong'), + ('textHeight', 'ootype.Float'), + ('textWidth', 'ootype.Float'), + ('thickness', 'ootype.Float'), + ('type', 'ootype.String'), + ('useRichTextClipboard', 'ootype.Bool'), + ('wordWrap', 'ootype.Bool'), +] +types['flash.text.TextField'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.FontStyle' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BOLD', 'String'), + ('BOLD_ITALIC', 'String'), + ('ITALIC', 'String'), + ('REGULAR', 'String'), +] +types['flash.text.FontStyle'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.GridFitType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('NONE', 'String'), + ('PIXEL', 'String'), + ('SUBPIXEL', 'String'), +] +types['flash.text.GridFitType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.ElementFormat' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.text.engine.ElementFormat'), + ('!CONSTRUCTOR!', ['flash.text.engine.FontDescription', 'ootype.Float', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.Float', 'ootype.String', 'ootype.Float', 'ootype.Float', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.String'], None), + ('getFontMetrics', [''], 'flash.text.engine.FontMetrics'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alignmentBaseline', 'ootype.String'), + ('alpha', 'ootype.Float'), + ('baselineShift', 'ootype.Float'), + ('breakOpportunity', 'ootype.String'), + ('color', 'ootype.UnsignedLongLong'), + ('digitCase', 'ootype.String'), + ('digitWidth', 'ootype.String'), + ('dominantBaseline', 'ootype.String'), + ('fontDescription', 'flash.text.engine.FontDescription'), + ('fontSize', 'ootype.Float'), + ('kerning', 'ootype.String'), + ('ligatureLevel', 'ootype.String'), + ('locale', 'ootype.String'), + ('locked', 'ootype.Bool'), + ('textRotation', 'ootype.String'), + ('trackingLeft', 'ootype.Float'), + ('trackingRight', 'ootype.Float'), + ('typographicCase', 'ootype.String'), +] +types['flash.text.engine.ElementFormat'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.FontLookup' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEVICE', 'String'), + ('EMBEDDED_CFF', 'String'), +] +types['flash.text.engine.FontLookup'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.FontMetrics' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.geom.Rectangle', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.text.engine.FontMetrics'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.JustificationStyle' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('PRIORITIZE_LEAST_ADJUSTMENT', 'String'), + ('PUSH_IN_KINSOKU', 'String'), + ('PUSH_OUT_ONLY', 'String'), +] +types['flash.text.engine.JustificationStyle'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.RenderingMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CFF', 'String'), + ('NORMAL', 'String'), +] +types['flash.text.engine.RenderingMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextBlock' +desc.BaseType = 'Object' +desc.Methods = [ + ('createTextLine', ['flash.text.engine.TextLine', 'ootype.Float', 'ootype.Float', 'ootype.Bool'], 'flash.text.engine.TextLine'), + ('dump', [''], 'ootype.String'), + ('findNextAtomBoundary', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('findNextWordBoundary', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('findPreviousAtomBoundary', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('findPreviousWordBoundary', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getTextLineAtCharIndex', ['ootype.SignedLongLong'], 'flash.text.engine.TextLine'), + ('releaseLines', ['flash.text.engine.TextLine', 'flash.text.engine.TextLine'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['flash.text.engine.ContentElement', 'TabStop[]', 'flash.text.engine.TextJustifier', 'ootype.String', 'ootype.String', 'ootype.SignedLongLong', 'ootype.Bool', 'flash.text.engine.FontDescription', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('applyNonLinearFontScaling', 'ootype.Bool'), + ('baselineFontDescription', 'flash.text.engine.FontDescription'), + ('baselineFontSize', 'ootype.Float'), + ('baselineZero', 'ootype.String'), + ('bidiLevel', 'ootype.SignedLongLong'), + ('content', 'flash.text.engine.ContentElement'), + ('firstInvalidLine', 'flash.text.engine.TextLine'), + ('firstLine', 'flash.text.engine.TextLine'), + ('lastLine', 'flash.text.engine.TextLine'), + ('lineRotation', 'ootype.String'), + ('tabStops', 'TabStop[]'), + ('textJustifier', 'flash.text.engine.TextJustifier'), + ('textLineCreationResult', 'ootype.String'), +] +types['flash.text.engine.TextBlock'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.DigitWidth' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEFAULT', 'String'), + ('PROPORTIONAL', 'String'), + ('TABULAR', 'String'), +] +types['flash.text.engine.DigitWidth'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.FontDescription' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.text.engine.FontDescription'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.String'], None), +] +desc.StaticMethods = [ + ('isFontCompatible', ['ootype.String', 'ootype.String', 'ootype.String'], 'ootype.Bool'), +] +desc.Fields = [] +desc.StaticFields = [ + ('cffHinting', 'ootype.String'), + ('fontLookup', 'ootype.String'), + ('fontName', 'ootype.String'), + ('fontPosture', 'ootype.String'), + ('fontWeight', 'ootype.String'), + ('locked', 'ootype.Bool'), + ('renderingMode', 'ootype.String'), +] +types['flash.text.engine.FontDescription'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.GroupElement' +desc.BaseType = 'ContentElement' +desc.Methods = [ + ('getElementAt', ['ootype.SignedLongLong'], 'flash.text.engine.ContentElement'), + ('getElementAtCharIndex', ['ootype.SignedLongLong'], 'flash.text.engine.ContentElement'), + ('getElementIndex', ['flash.text.engine.ContentElement'], 'ootype.SignedLongLong'), + ('!CONSTRUCTOR!', ['ContentElement[]', 'flash.text.engine.ElementFormat', 'flash.events.EventDispatcher', 'ootype.String'], None), + ('groupElements', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'flash.text.engine.GroupElement'), + ('mergeTextElements', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'flash.text.engine.TextElement'), + ('replaceElements', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ContentElement[]'], 'ContentElement[]'), + ('setElements', ['ContentElement[]'], 'ootype.Void'), + ('splitTextElement', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'flash.text.engine.TextElement'), + ('ungroupElements', ['ootype.SignedLongLong'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('elementCount', 'ootype.SignedLongLong'), +] +types['flash.text.engine.GroupElement'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.LineJustification' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ALL_BUT_LAST', 'String'), + ('ALL_INCLUDING_LAST', 'String'), + ('UNJUSTIFIED', 'String'), +] +types['flash.text.engine.LineJustification'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TabAlignment' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CENTER', 'String'), + ('DECIMAL', 'String'), + ('END', 'String'), + ('START', 'String'), +] +types['flash.text.engine.TabAlignment'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.EastAsianJustifier' +desc.BaseType = 'TextJustifier' +desc.Methods = [ + ('clone', [''], 'flash.text.engine.TextJustifier'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('justificationStyle', 'ootype.String'), +] +types['flash.text.engine.EastAsianJustifier'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TypographicCase' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CAPS', 'String'), + ('CAPS_AND_SMALL_CAPS', 'String'), + ('DEFAULT', 'String'), + ('LOWERCASE', 'String'), + ('SMALL_CAPS', 'String'), + ('TITLE', 'String'), + ('UPPERCASE', 'String'), +] +types['flash.text.engine.TypographicCase'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.CFFHinting' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('HORIZONTAL_STEM', 'String'), + ('NONE', 'String'), +] +types['flash.text.engine.CFFHinting'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.SpaceJustifier' +desc.BaseType = 'TextJustifier' +desc.Methods = [ + ('clone', [''], 'flash.text.engine.TextJustifier'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('letterSpacing', 'ootype.Bool'), +] +types['flash.text.engine.SpaceJustifier'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TabStop' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Float', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alignment', 'ootype.String'), + ('decimalAlignmentToken', 'ootype.String'), + ('position', 'ootype.Float'), +] +types['flash.text.engine.TabStop'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextLineMirrorRegion' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bounds', 'flash.geom.Rectangle'), + ('element', 'flash.text.engine.ContentElement'), + ('mirror', 'flash.events.EventDispatcher'), + ('nextRegion', 'flash.text.engine.TextLineMirrorRegion'), + ('previousRegion', 'flash.text.engine.TextLineMirrorRegion'), + ('textLine', 'flash.text.engine.TextLine'), +] +types['flash.text.engine.TextLineMirrorRegion'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextJustifier' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.text.engine.TextJustifier'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String'], None), +] +desc.StaticMethods = [ + ('getJustifierForLocale', ['ootype.String'], 'flash.text.engine.TextJustifier'), +] +desc.Fields = [] +desc.StaticFields = [ + ('lineJustification', 'ootype.String'), + ('locale', 'ootype.String'), +] +types['flash.text.engine.TextJustifier'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.FontPosture' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ITALIC', 'String'), + ('NORMAL', 'String'), +] +types['flash.text.engine.FontPosture'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextLine' +desc.BaseType = 'DisplayObjectContainer' +desc.Methods = [ + ('dump', [''], 'ootype.String'), + ('flushAtomData', [''], 'ootype.Void'), + ('getAtomBidiLevel', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getAtomBounds', ['ootype.SignedLongLong'], 'flash.geom.Rectangle'), + ('getAtomCenter', ['ootype.SignedLongLong'], 'ootype.Float'), + ('getAtomGraphic', ['ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('getAtomIndexAtCharIndex', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getAtomIndexAtPoint', ['ootype.Float', 'ootype.Float'], 'ootype.SignedLongLong'), + ('getAtomTextBlockBeginIndex', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getAtomTextBlockEndIndex', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getAtomTextRotation', ['ootype.SignedLongLong'], 'ootype.String'), + ('getAtomWordBoundaryOnLeft', ['ootype.SignedLongLong'], 'ootype.Bool'), + ('getBaselinePosition', ['ootype.String'], 'ootype.Float'), + ('getMirrorRegion', ['flash.events.EventDispatcher'], 'flash.text.engine.TextLineMirrorRegion'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('MAX_LINE_WIDTH', 'int'), + ('ascent', 'ootype.Float'), + ('atomCount', 'ootype.SignedLongLong'), + ('contextMenu', 'flash.ui.ContextMenu'), + ('descent', 'ootype.Float'), + ('focusRect', 'ootype.Dict'), + ('hasGraphicElement', 'ootype.Bool'), + ('mirrorRegions', 'TextLineMirrorRegion[]'), + ('nextLine', 'flash.text.engine.TextLine'), + ('previousLine', 'flash.text.engine.TextLine'), + ('rawTextLength', 'ootype.SignedLongLong'), + ('specifiedWidth', 'ootype.Float'), + ('tabChildren', 'ootype.Bool'), + ('tabEnabled', 'ootype.Bool'), + ('tabIndex', 'ootype.SignedLongLong'), + ('textBlock', 'flash.text.engine.TextBlock'), + ('textBlockBeginIndex', 'ootype.SignedLongLong'), + ('textHeight', 'ootype.Float'), + ('textWidth', 'ootype.Float'), + ('unjustifiedTextWidth', 'ootype.Float'), + ('validity', 'ootype.String'), +] +types['flash.text.engine.TextLine'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.FontWeight' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BOLD', 'String'), + ('NORMAL', 'String'), +] +types['flash.text.engine.FontWeight'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextLineValidity' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('INVALID', 'String'), + ('POSSIBLY_INVALID', 'String'), + ('STATIC', 'String'), + ('VALID', 'String'), +] +types['flash.text.engine.TextLineValidity'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextBaseline' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ASCENT', 'String'), + ('DESCENT', 'String'), + ('IDEOGRAPHIC_BOTTOM', 'String'), + ('IDEOGRAPHIC_CENTER', 'String'), + ('IDEOGRAPHIC_TOP', 'String'), + ('ROMAN', 'String'), + ('USE_DOMINANT_BASELINE', 'String'), +] +types['flash.text.engine.TextBaseline'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.Kerning' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('AUTO', 'String'), + ('OFF', 'String'), + ('ON', 'String'), +] +types['flash.text.engine.Kerning'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.BreakOpportunity' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ALL', 'String'), + ('ANY', 'String'), + ('AUTO', 'String'), + ('NONE', 'String'), +] +types['flash.text.engine.BreakOpportunity'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.GraphicElement' +desc.BaseType = 'ContentElement' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.DisplayObject', 'ootype.Float', 'ootype.Float', 'flash.text.engine.ElementFormat', 'flash.events.EventDispatcher', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('elementHeight', 'ootype.Float'), + ('elementWidth', 'ootype.Float'), + ('graphic', 'flash.display.DisplayObject'), +] +types['flash.text.engine.GraphicElement'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.ContentElement' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.text.engine.ElementFormat', 'flash.events.EventDispatcher', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('GRAPHIC_ELEMENT', 'uint'), + ('elementFormat', 'flash.text.engine.ElementFormat'), + ('eventMirror', 'flash.events.EventDispatcher'), + ('groupElement', 'flash.text.engine.GroupElement'), + ('rawText', 'ootype.String'), + ('text', 'ootype.String'), + ('textBlock', 'flash.text.engine.TextBlock'), + ('textBlockBeginIndex', 'ootype.SignedLongLong'), + ('textRotation', 'ootype.String'), +] +types['flash.text.engine.ContentElement'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextLineCreationResult' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('COMPLETE', 'String'), + ('EMERGENCY', 'String'), + ('INSUFFICIENT_WIDTH', 'String'), + ('SUCCESS', 'String'), +] +types['flash.text.engine.TextLineCreationResult'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.DigitCase' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEFAULT', 'String'), + ('LINING', 'String'), + ('OLD_STYLE', 'String'), +] +types['flash.text.engine.DigitCase'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextRotation' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('AUTO', 'String'), + ('ROTATE_0', 'String'), + ('ROTATE_180', 'String'), + ('ROTATE_270', 'String'), + ('ROTATE_90', 'String'), +] +types['flash.text.engine.TextRotation'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.LigatureLevel' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('COMMON', 'String'), + ('EXOTIC', 'String'), + ('MINIMUM', 'String'), + ('NONE', 'String'), + ('UNCOMMON', 'String'), +] +types['flash.text.engine.LigatureLevel'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextElement' +desc.BaseType = 'ContentElement' +desc.Methods = [ + ('replaceText', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.String'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.String', 'flash.text.engine.ElementFormat', 'flash.events.EventDispatcher', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('text', 'ootype.String'), +] +types['flash.text.engine.TextElement'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.DigitCase' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEFAULT', 'String'), + ('LINING', 'String'), + ('OLD_STYLE', 'String'), +] +types['flash.text.engine.DigitCase'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.DigitWidth' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEFAULT', 'String'), + ('PROPORTIONAL', 'String'), + ('TABULAR', 'String'), +] +types['flash.text.engine.DigitWidth'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.LineJustification' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ALL_BUT_LAST', 'String'), + ('ALL_INCLUDING_LAST', 'String'), + ('UNJUSTIFIED', 'String'), +] +types['flash.text.engine.LineJustification'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.FontLookup' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('DEVICE', 'String'), + ('EMBEDDED_CFF', 'String'), +] +types['flash.text.engine.FontLookup'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.FontMetrics' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.geom.Rectangle', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.text.engine.FontMetrics'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextBlock' +desc.BaseType = 'Object' +desc.Methods = [ + ('createTextLine', ['flash.text.engine.TextLine', 'ootype.Float', 'ootype.Float', 'ootype.Bool'], 'flash.text.engine.TextLine'), + ('dump', [''], 'ootype.String'), + ('findNextAtomBoundary', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('findNextWordBoundary', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('findPreviousAtomBoundary', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('findPreviousWordBoundary', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getTextLineAtCharIndex', ['ootype.SignedLongLong'], 'flash.text.engine.TextLine'), + ('releaseLines', ['flash.text.engine.TextLine', 'flash.text.engine.TextLine'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['flash.text.engine.ContentElement', 'TabStop[]', 'flash.text.engine.TextJustifier', 'ootype.String', 'ootype.String', 'ootype.SignedLongLong', 'ootype.Bool', 'flash.text.engine.FontDescription', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('applyNonLinearFontScaling', 'ootype.Bool'), + ('baselineFontDescription', 'flash.text.engine.FontDescription'), + ('baselineFontSize', 'ootype.Float'), + ('baselineZero', 'ootype.String'), + ('bidiLevel', 'ootype.SignedLongLong'), + ('content', 'flash.text.engine.ContentElement'), + ('firstInvalidLine', 'flash.text.engine.TextLine'), + ('firstLine', 'flash.text.engine.TextLine'), + ('lastLine', 'flash.text.engine.TextLine'), + ('lineRotation', 'ootype.String'), + ('tabStops', 'TabStop[]'), + ('textJustifier', 'flash.text.engine.TextJustifier'), + ('textLineCreationResult', 'ootype.String'), +] +types['flash.text.engine.TextBlock'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.JustificationStyle' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('PRIORITIZE_LEAST_ADJUSTMENT', 'String'), + ('PUSH_IN_KINSOKU', 'String'), + ('PUSH_OUT_ONLY', 'String'), +] +types['flash.text.engine.JustificationStyle'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.ElementFormat' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.text.engine.ElementFormat'), + ('!CONSTRUCTOR!', ['flash.text.engine.FontDescription', 'ootype.Float', 'ootype.UnsignedLongLong', 'ootype.Float', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.Float', 'ootype.String', 'ootype.Float', 'ootype.Float', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.String'], None), + ('getFontMetrics', [''], 'flash.text.engine.FontMetrics'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alignmentBaseline', 'ootype.String'), + ('alpha', 'ootype.Float'), + ('baselineShift', 'ootype.Float'), + ('breakOpportunity', 'ootype.String'), + ('color', 'ootype.UnsignedLongLong'), + ('digitCase', 'ootype.String'), + ('digitWidth', 'ootype.String'), + ('dominantBaseline', 'ootype.String'), + ('fontDescription', 'flash.text.engine.FontDescription'), + ('fontSize', 'ootype.Float'), + ('kerning', 'ootype.String'), + ('ligatureLevel', 'ootype.String'), + ('locale', 'ootype.String'), + ('locked', 'ootype.Bool'), + ('textRotation', 'ootype.String'), + ('trackingLeft', 'ootype.Float'), + ('trackingRight', 'ootype.Float'), + ('typographicCase', 'ootype.String'), +] +types['flash.text.engine.ElementFormat'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextLineValidity' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('INVALID', 'String'), + ('POSSIBLY_INVALID', 'String'), + ('STATIC', 'String'), + ('VALID', 'String'), +] +types['flash.text.engine.TextLineValidity'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.ContentElement' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.text.engine.ElementFormat', 'flash.events.EventDispatcher', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('GRAPHIC_ELEMENT', 'uint'), + ('elementFormat', 'flash.text.engine.ElementFormat'), + ('eventMirror', 'flash.events.EventDispatcher'), + ('groupElement', 'flash.text.engine.GroupElement'), + ('rawText', 'ootype.String'), + ('text', 'ootype.String'), + ('textBlock', 'flash.text.engine.TextBlock'), + ('textBlockBeginIndex', 'ootype.SignedLongLong'), + ('textRotation', 'ootype.String'), +] +types['flash.text.engine.ContentElement'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextRotation' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('AUTO', 'String'), + ('ROTATE_0', 'String'), + ('ROTATE_180', 'String'), + ('ROTATE_270', 'String'), + ('ROTATE_90', 'String'), +] +types['flash.text.engine.TextRotation'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.BreakOpportunity' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ALL', 'String'), + ('ANY', 'String'), + ('AUTO', 'String'), + ('NONE', 'String'), +] +types['flash.text.engine.BreakOpportunity'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.LigatureLevel' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('COMMON', 'String'), + ('EXOTIC', 'String'), + ('MINIMUM', 'String'), + ('NONE', 'String'), + ('UNCOMMON', 'String'), +] +types['flash.text.engine.LigatureLevel'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.RenderingMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CFF', 'String'), + ('NORMAL', 'String'), +] +types['flash.text.engine.RenderingMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.GraphicElement' +desc.BaseType = 'ContentElement' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.display.DisplayObject', 'ootype.Float', 'ootype.Float', 'flash.text.engine.ElementFormat', 'flash.events.EventDispatcher', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('elementHeight', 'ootype.Float'), + ('elementWidth', 'ootype.Float'), + ('graphic', 'flash.display.DisplayObject'), +] +types['flash.text.engine.GraphicElement'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextBaseline' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ASCENT', 'String'), + ('DESCENT', 'String'), + ('IDEOGRAPHIC_BOTTOM', 'String'), + ('IDEOGRAPHIC_CENTER', 'String'), + ('IDEOGRAPHIC_TOP', 'String'), + ('ROMAN', 'String'), + ('USE_DOMINANT_BASELINE', 'String'), +] +types['flash.text.engine.TextBaseline'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextLineCreationResult' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('COMPLETE', 'String'), + ('EMERGENCY', 'String'), + ('INSUFFICIENT_WIDTH', 'String'), + ('SUCCESS', 'String'), +] +types['flash.text.engine.TextLineCreationResult'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextElement' +desc.BaseType = 'ContentElement' +desc.Methods = [ + ('replaceText', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.String'], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.String', 'flash.text.engine.ElementFormat', 'flash.events.EventDispatcher', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('text', 'ootype.String'), +] +types['flash.text.engine.TextElement'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.EastAsianJustifier' +desc.BaseType = 'TextJustifier' +desc.Methods = [ + ('clone', [''], 'flash.text.engine.TextJustifier'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('justificationStyle', 'ootype.String'), +] +types['flash.text.engine.EastAsianJustifier'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.FontDescription' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.text.engine.FontDescription'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.String', 'ootype.String'], None), +] +desc.StaticMethods = [ + ('isFontCompatible', ['ootype.String', 'ootype.String', 'ootype.String'], 'ootype.Bool'), +] +desc.Fields = [] +desc.StaticFields = [ + ('cffHinting', 'ootype.String'), + ('fontLookup', 'ootype.String'), + ('fontName', 'ootype.String'), + ('fontPosture', 'ootype.String'), + ('fontWeight', 'ootype.String'), + ('locked', 'ootype.Bool'), + ('renderingMode', 'ootype.String'), +] +types['flash.text.engine.FontDescription'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.GroupElement' +desc.BaseType = 'ContentElement' +desc.Methods = [ + ('getElementAt', ['ootype.SignedLongLong'], 'flash.text.engine.ContentElement'), + ('getElementAtCharIndex', ['ootype.SignedLongLong'], 'flash.text.engine.ContentElement'), + ('getElementIndex', ['flash.text.engine.ContentElement'], 'ootype.SignedLongLong'), + ('!CONSTRUCTOR!', ['ContentElement[]', 'flash.text.engine.ElementFormat', 'flash.events.EventDispatcher', 'ootype.String'], None), + ('groupElements', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'flash.text.engine.GroupElement'), + ('mergeTextElements', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'flash.text.engine.TextElement'), + ('replaceElements', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ContentElement[]'], 'ContentElement[]'), + ('setElements', ['ContentElement[]'], 'ootype.Void'), + ('splitTextElement', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'flash.text.engine.TextElement'), + ('ungroupElements', ['ootype.SignedLongLong'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('elementCount', 'ootype.SignedLongLong'), +] +types['flash.text.engine.GroupElement'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.Kerning' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('AUTO', 'String'), + ('OFF', 'String'), + ('ON', 'String'), +] +types['flash.text.engine.Kerning'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.FontPosture' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ITALIC', 'String'), + ('NORMAL', 'String'), +] +types['flash.text.engine.FontPosture'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.CFFHinting' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('HORIZONTAL_STEM', 'String'), + ('NONE', 'String'), +] +types['flash.text.engine.CFFHinting'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.FontWeight' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BOLD', 'String'), + ('NORMAL', 'String'), +] +types['flash.text.engine.FontWeight'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextLine' +desc.BaseType = 'DisplayObjectContainer' +desc.Methods = [ + ('dump', [''], 'ootype.String'), + ('flushAtomData', [''], 'ootype.Void'), + ('getAtomBidiLevel', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getAtomBounds', ['ootype.SignedLongLong'], 'flash.geom.Rectangle'), + ('getAtomCenter', ['ootype.SignedLongLong'], 'ootype.Float'), + ('getAtomGraphic', ['ootype.SignedLongLong'], 'flash.display.DisplayObject'), + ('getAtomIndexAtCharIndex', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getAtomIndexAtPoint', ['ootype.Float', 'ootype.Float'], 'ootype.SignedLongLong'), + ('getAtomTextBlockBeginIndex', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getAtomTextBlockEndIndex', ['ootype.SignedLongLong'], 'ootype.SignedLongLong'), + ('getAtomTextRotation', ['ootype.SignedLongLong'], 'ootype.String'), + ('getAtomWordBoundaryOnLeft', ['ootype.SignedLongLong'], 'ootype.Bool'), + ('getBaselinePosition', ['ootype.String'], 'ootype.Float'), + ('getMirrorRegion', ['flash.events.EventDispatcher'], 'flash.text.engine.TextLineMirrorRegion'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('MAX_LINE_WIDTH', 'int'), + ('ascent', 'ootype.Float'), + ('atomCount', 'ootype.SignedLongLong'), + ('contextMenu', 'flash.ui.ContextMenu'), + ('descent', 'ootype.Float'), + ('focusRect', 'ootype.Dict'), + ('hasGraphicElement', 'ootype.Bool'), + ('mirrorRegions', 'TextLineMirrorRegion[]'), + ('nextLine', 'flash.text.engine.TextLine'), + ('previousLine', 'flash.text.engine.TextLine'), + ('rawTextLength', 'ootype.SignedLongLong'), + ('specifiedWidth', 'ootype.Float'), + ('tabChildren', 'ootype.Bool'), + ('tabEnabled', 'ootype.Bool'), + ('tabIndex', 'ootype.SignedLongLong'), + ('textBlock', 'flash.text.engine.TextBlock'), + ('textBlockBeginIndex', 'ootype.SignedLongLong'), + ('textHeight', 'ootype.Float'), + ('textWidth', 'ootype.Float'), + ('unjustifiedTextWidth', 'ootype.Float'), + ('validity', 'ootype.String'), +] +types['flash.text.engine.TextLine'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.SpaceJustifier' +desc.BaseType = 'TextJustifier' +desc.Methods = [ + ('clone', [''], 'flash.text.engine.TextJustifier'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('letterSpacing', 'ootype.Bool'), +] +types['flash.text.engine.SpaceJustifier'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TabAlignment' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CENTER', 'String'), + ('DECIMAL', 'String'), + ('END', 'String'), + ('START', 'String'), +] +types['flash.text.engine.TabAlignment'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TypographicCase' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CAPS', 'String'), + ('CAPS_AND_SMALL_CAPS', 'String'), + ('DEFAULT', 'String'), + ('LOWERCASE', 'String'), + ('SMALL_CAPS', 'String'), + ('TITLE', 'String'), + ('UPPERCASE', 'String'), +] +types['flash.text.engine.TypographicCase'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TabStop' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Float', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('alignment', 'ootype.String'), + ('decimalAlignmentToken', 'ootype.String'), + ('position', 'ootype.Float'), +] +types['flash.text.engine.TabStop'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextJustifier' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.text.engine.TextJustifier'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.String'], None), +] +desc.StaticMethods = [ + ('getJustifierForLocale', ['ootype.String'], 'flash.text.engine.TextJustifier'), +] +desc.Fields = [] +desc.StaticFields = [ + ('lineJustification', 'ootype.String'), + ('locale', 'ootype.String'), +] +types['flash.text.engine.TextJustifier'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.text.engine.TextLineMirrorRegion' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bounds', 'flash.geom.Rectangle'), + ('element', 'flash.text.engine.ContentElement'), + ('mirror', 'flash.events.EventDispatcher'), + ('nextRegion', 'flash.text.engine.TextLineMirrorRegion'), + ('previousRegion', 'flash.text.engine.TextLineMirrorRegion'), + ('textLine', 'flash.text.engine.TextLine'), +] +types['flash.text.engine.TextLineMirrorRegion'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.xml.XMLTag' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('attrs', 'ootype.Dict'), + ('empty', 'ootype.Bool'), + ('type', 'ootype.UnsignedLongLong'), + ('value', 'ootype.String'), +] +types['flash.xml.XMLTag'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.xml.XMLNodeType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CDATA_NODE', 'uint'), + ('COMMENT_NODE', 'uint'), + ('DOCUMENT_TYPE_NODE', 'uint'), + ('ELEMENT_NODE', 'uint'), + ('PROCESSING_INSTRUCTION_NODE', 'uint'), + ('TEXT_NODE', 'uint'), + ('XML_DECLARATION', 'uint'), +] +types['flash.xml.XMLNodeType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.xml.XMLDocument' +desc.BaseType = 'XMLNode' +desc.Methods = [ + ('createElement', ['ootype.String'], 'flash.xml.XMLNode'), + ('createTextNode', ['ootype.String'], 'flash.xml.XMLNode'), + ('parseXML', ['ootype.String'], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('!CONSTRUCTOR!', ['ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.xml.XMLDocument'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.xml.XMLParser' +desc.BaseType = 'Object' +desc.Methods = [ + ('getNext', ['flash.xml.XMLTag'], 'ootype.SignedLongLong'), + ('startParse', ['ootype.String', 'ootype.Bool'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.xml.XMLParser'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.xml.XMLNode' +desc.BaseType = 'Object' +desc.Methods = [ + ('appendChild', ['flash.xml.XMLNode'], 'ootype.Void'), + ('cloneNode', ['ootype.Bool'], 'flash.xml.XMLNode'), + ('getNamespaceForPrefix', ['ootype.String'], 'ootype.String'), + ('getPrefixForNamespace', ['ootype.String'], 'ootype.String'), + ('hasChildNodes', [''], 'ootype.Bool'), + ('insertBefore', ['flash.xml.XMLNode', 'flash.xml.XMLNode'], 'ootype.Void'), + ('removeNode', [''], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('!CONSTRUCTOR!', ['ootype.UnsignedLongLong', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('attributes', 'ootype.Dict'), + ('childNodes', 'ootype.List'), + ('localName', 'ootype.String'), + ('namespaceURI', 'ootype.String'), + ('prefix', 'ootype.String'), +] +types['flash.xml.XMLNode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.xml.XMLDocument' +desc.BaseType = 'XMLNode' +desc.Methods = [ + ('createElement', ['ootype.String'], 'flash.xml.XMLNode'), + ('createTextNode', ['ootype.String'], 'flash.xml.XMLNode'), + ('parseXML', ['ootype.String'], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('!CONSTRUCTOR!', ['ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.xml.XMLDocument'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.xml.XMLNode' +desc.BaseType = 'Object' +desc.Methods = [ + ('appendChild', ['flash.xml.XMLNode'], 'ootype.Void'), + ('cloneNode', ['ootype.Bool'], 'flash.xml.XMLNode'), + ('getNamespaceForPrefix', ['ootype.String'], 'ootype.String'), + ('getPrefixForNamespace', ['ootype.String'], 'ootype.String'), + ('hasChildNodes', [''], 'ootype.Bool'), + ('insertBefore', ['flash.xml.XMLNode', 'flash.xml.XMLNode'], 'ootype.Void'), + ('removeNode', [''], 'ootype.Void'), + ('toString', [''], 'ootype.String'), + ('!CONSTRUCTOR!', ['ootype.UnsignedLongLong', 'ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('attributes', 'ootype.Dict'), + ('childNodes', 'ootype.List'), + ('localName', 'ootype.String'), + ('namespaceURI', 'ootype.String'), + ('prefix', 'ootype.String'), +] +types['flash.xml.XMLNode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.xml.XMLParser' +desc.BaseType = 'Object' +desc.Methods = [ + ('getNext', ['flash.xml.XMLTag'], 'ootype.SignedLongLong'), + ('startParse', ['ootype.String', 'ootype.Bool'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.xml.XMLParser'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.xml.XMLTag' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('attrs', 'ootype.Dict'), + ('empty', 'ootype.Bool'), + ('type', 'ootype.UnsignedLongLong'), + ('value', 'ootype.String'), +] +types['flash.xml.XMLTag'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.xml.XMLNodeType' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CDATA_NODE', 'uint'), + ('COMMENT_NODE', 'uint'), + ('DOCUMENT_TYPE_NODE', 'uint'), + ('ELEMENT_NODE', 'uint'), + ('PROCESSING_INSTRUCTION_NODE', 'uint'), + ('TEXT_NODE', 'uint'), + ('XML_DECLARATION', 'uint'), +] +types['flash.xml.XMLNodeType'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.desktop.ClipboardFormats' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('HTML_FORMAT', 'String'), + ('RICH_TEXT_FORMAT', 'String'), + ('TEXT_FORMAT', 'String'), +] +types['flash.desktop.ClipboardFormats'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.desktop.Clipboard' +desc.BaseType = 'Object' +desc.Methods = [ + ('clear', [''], 'ootype.Void'), + ('clearData', ['ootype.String'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('getData', ['ootype.String', 'ootype.String'], 'ootype.Dict'), + ('hasFormat', ['ootype.String'], 'ootype.Bool'), + ('setData', ['ootype.String', 'ootype.Dict', 'ootype.Bool'], 'ootype.Bool'), + ('setDataHandler', ['ootype.String', 'Function', 'ootype.Bool'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('formats', 'ootype.List'), + ('generalClipboard', 'flash.desktop.Clipboard'), +] +types['flash.desktop.Clipboard'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.desktop.ClipboardTransferMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CLONE_ONLY', 'String'), + ('CLONE_PREFERRED', 'String'), + ('ORIGINAL_ONLY', 'String'), + ('ORIGINAL_PREFERRED', 'String'), +] +types['flash.desktop.ClipboardTransferMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.desktop.Clipboard' +desc.BaseType = 'Object' +desc.Methods = [ + ('clear', [''], 'ootype.Void'), + ('clearData', ['ootype.String'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('getData', ['ootype.String', 'ootype.String'], 'ootype.Dict'), + ('hasFormat', ['ootype.String'], 'ootype.Bool'), + ('setData', ['ootype.String', 'ootype.Dict', 'ootype.Bool'], 'ootype.Bool'), + ('setDataHandler', ['ootype.String', 'Function', 'ootype.Bool'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('formats', 'ootype.List'), + ('generalClipboard', 'flash.desktop.Clipboard'), +] +types['flash.desktop.Clipboard'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.desktop.ClipboardTransferMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CLONE_ONLY', 'String'), + ('CLONE_PREFERRED', 'String'), + ('ORIGINAL_ONLY', 'String'), + ('ORIGINAL_PREFERRED', 'String'), +] +types['flash.desktop.ClipboardTransferMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.desktop.ClipboardFormats' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('HTML_FORMAT', 'String'), + ('RICH_TEXT_FORMAT', 'String'), + ('TEXT_FORMAT', 'String'), +] +types['flash.desktop.ClipboardFormats'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.MouseCursor' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ARROW', 'String'), + ('AUTO', 'String'), + ('BUTTON', 'String'), + ('HAND', 'String'), + ('IBEAM', 'String'), +] +types['flash.ui.MouseCursor'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.Keyboard' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('isAccessible', [''], 'ootype.Bool'), +] +desc.Fields = [] +desc.StaticFields = [ + ('BACKSPACE', 'uint'), + ('CAPS_LOCK', 'uint'), + ('CONTROL', 'uint'), + ('DELETE', 'uint'), + ('DOWN', 'uint'), + ('END', 'uint'), + ('ENTER', 'uint'), + ('ESCAPE', 'uint'), + ('F1', 'uint'), + ('F10', 'uint'), + ('F11', 'uint'), + ('F12', 'uint'), + ('F13', 'uint'), + ('F14', 'uint'), + ('F15', 'uint'), + ('F2', 'uint'), + ('F3', 'uint'), + ('F4', 'uint'), + ('F5', 'uint'), + ('F6', 'uint'), + ('F7', 'uint'), + ('F8', 'uint'), + ('F9', 'uint'), + ('HOME', 'uint'), + ('INSERT', 'uint'), + ('LEFT', 'uint'), + ('NUMPAD_0', 'uint'), + ('NUMPAD_1', 'uint'), + ('NUMPAD_2', 'uint'), + ('NUMPAD_3', 'uint'), + ('NUMPAD_4', 'uint'), + ('NUMPAD_5', 'uint'), + ('NUMPAD_6', 'uint'), + ('NUMPAD_7', 'uint'), + ('NUMPAD_8', 'uint'), + ('NUMPAD_9', 'uint'), + ('NUMPAD_ADD', 'uint'), + ('NUMPAD_DECIMAL', 'uint'), + ('NUMPAD_DIVIDE', 'uint'), + ('NUMPAD_ENTER', 'uint'), + ('NUMPAD_MULTIPLY', 'uint'), + ('NUMPAD_SUBTRACT', 'uint'), + ('PAGE_DOWN', 'uint'), + ('PAGE_UP', 'uint'), + ('RIGHT', 'uint'), + ('SHIFT', 'uint'), + ('SPACE', 'uint'), + ('TAB', 'uint'), + ('UP', 'uint'), + ('capsLock', 'ootype.Bool'), + ('numLock', 'ootype.Bool'), +] +types['flash.ui.Keyboard'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.ContextMenuClipboardItems' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.ui.ContextMenuClipboardItems'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.ui.ContextMenuClipboardItems'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.ContextMenu' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('clone', [''], 'flash.ui.ContextMenu'), + ('!CONSTRUCTOR!', [''], None), + ('hideBuiltInItems', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('builtInItems', 'flash.ui.ContextMenuBuiltInItems'), + ('clipboardItems', 'flash.ui.ContextMenuClipboardItems'), + ('clipboardMenu', 'ootype.Bool'), + ('customItems', 'ootype.List'), + ('link', 'flash.net.URLRequest'), +] +types['flash.ui.ContextMenu'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.KeyLocation' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('LEFT', 'uint'), + ('NUM_PAD', 'uint'), + ('RIGHT', 'uint'), + ('STANDARD', 'uint'), +] +types['flash.ui.KeyLocation'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.Mouse' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('hide', [''], 'ootype.Void'), + ('show', [''], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('cursor', 'ootype.String'), +] +types['flash.ui.Mouse'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.ContextMenuBuiltInItems' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.ui.ContextMenuBuiltInItems'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.ui.ContextMenuBuiltInItems'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.ContextMenuItem' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('clone', [''], 'flash.ui.ContextMenuItem'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('caption', 'ootype.String'), + ('enabled', 'ootype.Bool'), + ('separatorBefore', 'ootype.Bool'), + ('visible', 'ootype.Bool'), +] +types['flash.ui.ContextMenuItem'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.Keyboard' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('isAccessible', [''], 'ootype.Bool'), +] +desc.Fields = [] +desc.StaticFields = [ + ('BACKSPACE', 'uint'), + ('CAPS_LOCK', 'uint'), + ('CONTROL', 'uint'), + ('DELETE', 'uint'), + ('DOWN', 'uint'), + ('END', 'uint'), + ('ENTER', 'uint'), + ('ESCAPE', 'uint'), + ('F1', 'uint'), + ('F10', 'uint'), + ('F11', 'uint'), + ('F12', 'uint'), + ('F13', 'uint'), + ('F14', 'uint'), + ('F15', 'uint'), + ('F2', 'uint'), + ('F3', 'uint'), + ('F4', 'uint'), + ('F5', 'uint'), + ('F6', 'uint'), + ('F7', 'uint'), + ('F8', 'uint'), + ('F9', 'uint'), + ('HOME', 'uint'), + ('INSERT', 'uint'), + ('LEFT', 'uint'), + ('NUMPAD_0', 'uint'), + ('NUMPAD_1', 'uint'), + ('NUMPAD_2', 'uint'), + ('NUMPAD_3', 'uint'), + ('NUMPAD_4', 'uint'), + ('NUMPAD_5', 'uint'), + ('NUMPAD_6', 'uint'), + ('NUMPAD_7', 'uint'), + ('NUMPAD_8', 'uint'), + ('NUMPAD_9', 'uint'), + ('NUMPAD_ADD', 'uint'), + ('NUMPAD_DECIMAL', 'uint'), + ('NUMPAD_DIVIDE', 'uint'), + ('NUMPAD_ENTER', 'uint'), + ('NUMPAD_MULTIPLY', 'uint'), + ('NUMPAD_SUBTRACT', 'uint'), + ('PAGE_DOWN', 'uint'), + ('PAGE_UP', 'uint'), + ('RIGHT', 'uint'), + ('SHIFT', 'uint'), + ('SPACE', 'uint'), + ('TAB', 'uint'), + ('UP', 'uint'), + ('capsLock', 'ootype.Bool'), + ('numLock', 'ootype.Bool'), +] +types['flash.ui.Keyboard'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.ContextMenuBuiltInItems' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.ui.ContextMenuBuiltInItems'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.ui.ContextMenuBuiltInItems'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.ContextMenuItem' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('clone', [''], 'flash.ui.ContextMenuItem'), + ('!CONSTRUCTOR!', ['ootype.String', 'ootype.Bool', 'ootype.Bool', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('caption', 'ootype.String'), + ('enabled', 'ootype.Bool'), + ('separatorBefore', 'ootype.Bool'), + ('visible', 'ootype.Bool'), +] +types['flash.ui.ContextMenuItem'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.ContextMenu' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('clone', [''], 'flash.ui.ContextMenu'), + ('!CONSTRUCTOR!', [''], None), + ('hideBuiltInItems', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('builtInItems', 'flash.ui.ContextMenuBuiltInItems'), + ('clipboardItems', 'flash.ui.ContextMenuClipboardItems'), + ('clipboardMenu', 'ootype.Bool'), + ('customItems', 'ootype.List'), + ('link', 'flash.net.URLRequest'), +] +types['flash.ui.ContextMenu'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.Mouse' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('hide', [''], 'ootype.Void'), + ('show', [''], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('cursor', 'ootype.String'), +] +types['flash.ui.Mouse'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.KeyLocation' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('LEFT', 'uint'), + ('NUM_PAD', 'uint'), + ('RIGHT', 'uint'), + ('STANDARD', 'uint'), +] +types['flash.ui.KeyLocation'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.MouseCursor' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ARROW', 'String'), + ('AUTO', 'String'), + ('BUTTON', 'String'), + ('HAND', 'String'), + ('IBEAM', 'String'), +] +types['flash.ui.MouseCursor'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.ui.ContextMenuClipboardItems' +desc.BaseType = 'Object' +desc.Methods = [ + ('clone', [''], 'flash.ui.ContextMenuClipboardItems'), + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.ui.ContextMenuClipboardItems'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.IMEConversionMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ALPHANUMERIC_FULL', 'String'), + ('ALPHANUMERIC_HALF', 'String'), + ('CHINESE', 'String'), + ('JAPANESE_HIRAGANA', 'String'), + ('JAPANESE_KATAKANA_FULL', 'String'), + ('JAPANESE_KATAKANA_HALF', 'String'), + ('KOREAN', 'String'), + ('UNKNOWN', 'String'), +] +types['flash.system.IMEConversionMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.IME' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('doConversion', [''], 'ootype.Void'), + ('setCompositionString', ['ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('constructOK', 'ootype.Bool'), + ('conversionMode', 'ootype.String'), + ('enabled', 'ootype.Bool'), +] +types['flash.system.IME'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.Capabilities' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('_internal', 'ootype.UnsignedLongLong'), + ('avHardwareDisable', 'ootype.Bool'), + ('hasAccessibility', 'ootype.Bool'), + ('hasAudio', 'ootype.Bool'), + ('hasAudioEncoder', 'ootype.Bool'), + ('hasEmbeddedVideo', 'ootype.Bool'), + ('hasIME', 'ootype.Bool'), + ('hasMP3', 'ootype.Bool'), + ('hasPrinting', 'ootype.Bool'), + ('hasScreenBroadcast', 'ootype.Bool'), + ('hasScreenPlayback', 'ootype.Bool'), + ('hasStreamingAudio', 'ootype.Bool'), + ('hasStreamingVideo', 'ootype.Bool'), + ('hasTLS', 'ootype.Bool'), + ('hasVideoEncoder', 'ootype.Bool'), + ('isDebugger', 'ootype.Bool'), + ('language', 'ootype.String'), + ('localFileReadDisable', 'ootype.Bool'), + ('manufacturer', 'ootype.String'), + ('maxLevelIDC', 'ootype.String'), + ('os', 'ootype.String'), + ('pixelAspectRatio', 'ootype.Float'), + ('playerType', 'ootype.String'), + ('screenColor', 'ootype.String'), + ('screenDPI', 'ootype.Float'), + ('screenResolutionX', 'ootype.Float'), + ('screenResolutionY', 'ootype.Float'), + ('serverString', 'ootype.String'), + ('version', 'ootype.String'), +] +types['flash.system.Capabilities'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.JPEGLoaderContext' +desc.BaseType = 'LoaderContext' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Bool', 'flash.system.ApplicationDomain', 'flash.system.SecurityDomain'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.system.JPEGLoaderContext'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.ApplicationDomain' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.system.ApplicationDomain'], None), + ('getDefinition', ['ootype.String'], 'ootype.Dict'), + ('hasDefinition', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('currentDomain', 'flash.system.ApplicationDomain'), + ('domainMemory', 'flash.utils.ByteArray'), + ('MIN_DOMAIN_MEMORY_LENGTH', 'ootype.UnsignedLongLong'), + ('parentDomain', 'flash.system.ApplicationDomain'), +] +types['flash.system.ApplicationDomain'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.Security' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('allowDomain', ['*args'], 'ootype.Void'), + ('allowInsecureDomain', ['*args'], 'ootype.Void'), + ('loadPolicyFile', ['ootype.String'], 'ootype.Void'), + ('showSettings', ['ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('LOCAL_TRUSTED', 'String'), + ('LOCAL_WITH_FILE', 'String'), + ('LOCAL_WITH_NETWORK', 'String'), + ('REMOTE', 'String'), + ('disableAVM1Loading', 'ootype.Bool'), + ('exactSettings', 'ootype.Bool'), + ('sandboxType', 'ootype.String'), +] +types['flash.system.Security'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.SecurityDomain' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('currentDomain', 'flash.system.SecurityDomain'), +] +types['flash.system.SecurityDomain'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.LoaderContext' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Bool', 'flash.system.ApplicationDomain', 'flash.system.SecurityDomain'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.system.LoaderContext'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.System' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('exit', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('gc', [''], 'ootype.Void'), + ('pause', [''], 'ootype.Void'), + ('resume', [''], 'ootype.Void'), + ('setClipboard', ['ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('ime', 'flash.system.IME'), + ('totalMemory', 'ootype.UnsignedLongLong'), + ('useCodePage', 'ootype.Bool'), + ('vmVersion', 'ootype.String'), +] +types['flash.system.System'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.FSCommand' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('_fscommand', ['ootype.String', 'ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [] +types['flash.system.FSCommand'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('fscommand', ['ootype.String', 'ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.SecurityPanel' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CAMERA', 'String'), + ('DEFAULT', 'String'), + ('DISPLAY', 'String'), + ('LOCAL_STORAGE', 'String'), + ('MICROPHONE', 'String'), + ('PRIVACY', 'String'), + ('SETTINGS_MANAGER', 'String'), +] +types['flash.system.SecurityPanel'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.SecurityDomain' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('currentDomain', 'flash.system.SecurityDomain'), +] +types['flash.system.SecurityDomain'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.Security' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('allowDomain', ['*args'], 'ootype.Void'), + ('allowInsecureDomain', ['*args'], 'ootype.Void'), + ('loadPolicyFile', ['ootype.String'], 'ootype.Void'), + ('showSettings', ['ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('LOCAL_TRUSTED', 'String'), + ('LOCAL_WITH_FILE', 'String'), + ('LOCAL_WITH_NETWORK', 'String'), + ('REMOTE', 'String'), + ('disableAVM1Loading', 'ootype.Bool'), + ('exactSettings', 'ootype.Bool'), + ('sandboxType', 'ootype.String'), +] +types['flash.system.Security'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.JPEGLoaderContext' +desc.BaseType = 'LoaderContext' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Bool', 'flash.system.ApplicationDomain', 'flash.system.SecurityDomain'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.system.JPEGLoaderContext'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('fscommand', ['ootype.String', 'ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.System' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('exit', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('gc', [''], 'ootype.Void'), + ('pause', [''], 'ootype.Void'), + ('resume', [''], 'ootype.Void'), + ('setClipboard', ['ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('ime', 'flash.system.IME'), + ('totalMemory', 'ootype.UnsignedLongLong'), + ('useCodePage', 'ootype.Bool'), + ('vmVersion', 'ootype.String'), +] +types['flash.system.System'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.IME' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('doConversion', [''], 'ootype.Void'), + ('setCompositionString', ['ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('constructOK', 'ootype.Bool'), + ('conversionMode', 'ootype.String'), + ('enabled', 'ootype.Bool'), +] +types['flash.system.IME'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.SecurityPanel' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('CAMERA', 'String'), + ('DEFAULT', 'String'), + ('DISPLAY', 'String'), + ('LOCAL_STORAGE', 'String'), + ('MICROPHONE', 'String'), + ('PRIVACY', 'String'), + ('SETTINGS_MANAGER', 'String'), +] +types['flash.system.SecurityPanel'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.Capabilities' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('_internal', 'ootype.UnsignedLongLong'), + ('avHardwareDisable', 'ootype.Bool'), + ('hasAccessibility', 'ootype.Bool'), + ('hasAudio', 'ootype.Bool'), + ('hasAudioEncoder', 'ootype.Bool'), + ('hasEmbeddedVideo', 'ootype.Bool'), + ('hasIME', 'ootype.Bool'), + ('hasMP3', 'ootype.Bool'), + ('hasPrinting', 'ootype.Bool'), + ('hasScreenBroadcast', 'ootype.Bool'), + ('hasScreenPlayback', 'ootype.Bool'), + ('hasStreamingAudio', 'ootype.Bool'), + ('hasStreamingVideo', 'ootype.Bool'), + ('hasTLS', 'ootype.Bool'), + ('hasVideoEncoder', 'ootype.Bool'), + ('isDebugger', 'ootype.Bool'), + ('language', 'ootype.String'), + ('localFileReadDisable', 'ootype.Bool'), + ('manufacturer', 'ootype.String'), + ('maxLevelIDC', 'ootype.String'), + ('os', 'ootype.String'), + ('pixelAspectRatio', 'ootype.Float'), + ('playerType', 'ootype.String'), + ('screenColor', 'ootype.String'), + ('screenDPI', 'ootype.Float'), + ('screenResolutionX', 'ootype.Float'), + ('screenResolutionY', 'ootype.Float'), + ('serverString', 'ootype.String'), + ('version', 'ootype.String'), +] +types['flash.system.Capabilities'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.ApplicationDomain' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['flash.system.ApplicationDomain'], None), + ('getDefinition', ['ootype.String'], 'ootype.Dict'), + ('hasDefinition', ['ootype.String'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('currentDomain', 'flash.system.ApplicationDomain'), + ('domainMemory', 'flash.utils.ByteArray'), + ('MIN_DOMAIN_MEMORY_LENGTH', 'ootype.UnsignedLongLong'), + ('parentDomain', 'flash.system.ApplicationDomain'), +] +types['flash.system.ApplicationDomain'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.IMEConversionMode' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('ALPHANUMERIC_FULL', 'String'), + ('ALPHANUMERIC_HALF', 'String'), + ('CHINESE', 'String'), + ('JAPANESE_HIRAGANA', 'String'), + ('JAPANESE_KATAKANA_FULL', 'String'), + ('JAPANESE_KATAKANA_HALF', 'String'), + ('KOREAN', 'String'), + ('UNKNOWN', 'String'), +] +types['flash.system.IMEConversionMode'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.LoaderContext' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Bool', 'flash.system.ApplicationDomain', 'flash.system.SecurityDomain'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.system.LoaderContext'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.system.FSCommand' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('_fscommand', ['ootype.String', 'ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [] +types['flash.system.FSCommand'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('writeBoolean', ['ootype.Bool'], 'ootype.Void'), + ('writeByte', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeDouble', ['ootype.Float'], 'ootype.Void'), + ('writeFloat', ['ootype.Float'], 'ootype.Void'), + ('writeInt', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeMultiByte', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('writeObject', [''], 'ootype.Void'), + ('writeShort', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeUnsignedInt', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeUTF', ['ootype.String'], 'ootype.Void'), + ('writeUTFBytes', ['ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), +] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.Endian' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BIG_ENDIAN', 'String'), + ('LITTLE_ENDIAN', 'String'), +] +types['flash.utils.Endian'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.Proxy' +desc.BaseType = 'Object' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.utils.Proxy'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('readBoolean', [''], 'ootype.Bool'), + ('readByte', [''], 'ootype.SignedLongLong'), + ('readBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('readDouble', [''], 'ootype.Float'), + ('readFloat', [''], 'ootype.Float'), + ('readInt', [''], 'ootype.SignedLongLong'), + ('readMultiByte', ['ootype.UnsignedLongLong', 'ootype.String'], 'ootype.String'), + ('readObject', [''], ''), + ('readShort', [''], 'ootype.SignedLongLong'), + ('readUnsignedByte', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedInt', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedShort', [''], 'ootype.UnsignedLongLong'), + ('readUTF', [''], 'ootype.String'), + ('readUTFBytes', ['ootype.UnsignedLongLong'], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesAvailable', 'ootype.UnsignedLongLong'), + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), +] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.SetIntervalTimer' +desc.BaseType = 'Timer' +desc.Methods = [ + ('!CONSTRUCTOR!', ['Function', 'ootype.Float', 'ootype.Bool', 'ootype.List'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.utils.SetIntervalTimer'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.ObjectInput' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('readBoolean', [''], 'ootype.Bool'), + ('readByte', [''], 'ootype.SignedLongLong'), + ('readBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('readDouble', [''], 'ootype.Float'), + ('readFloat', [''], 'ootype.Float'), + ('readInt', [''], 'ootype.SignedLongLong'), + ('readMultiByte', ['ootype.UnsignedLongLong', 'ootype.String'], 'ootype.String'), + ('readObject', [''], ''), + ('readShort', [''], 'ootype.SignedLongLong'), + ('readUnsignedByte', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedInt', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedShort', [''], 'ootype.UnsignedLongLong'), + ('readUTF', [''], 'ootype.String'), + ('readUTFBytes', ['ootype.UnsignedLongLong'], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesAvailable', 'ootype.UnsignedLongLong'), + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), +] +types['flash.utils.ObjectInput'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.Timer' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('reset', [''], 'ootype.Void'), + ('start', [''], 'ootype.Void'), + ('stop', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('currentCount', 'ootype.SignedLongLong'), + ('delay', 'ootype.Float'), + ('repeatCount', 'ootype.SignedLongLong'), + ('running', 'ootype.Bool'), +] +types['flash.utils.Timer'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('readExternal', ['flash.utils.IDataInput'], 'ootype.Void'), + ('writeExternal', ['flash.utils.IDataOutput'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.ByteArray' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('clear', [''], 'ootype.Void'), + ('compress', [''], 'ootype.Void'), + ('deflate', [''], 'ootype.Void'), + ('inflate', [''], 'ootype.Void'), + ('readBoolean', [''], 'ootype.Bool'), + ('readByte', [''], 'ootype.SignedLongLong'), + ('readBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('readDouble', [''], 'ootype.Float'), + ('readFloat', [''], 'ootype.Float'), + ('readInt', [''], 'ootype.SignedLongLong'), + ('readMultiByte', ['ootype.UnsignedLongLong', 'ootype.String'], 'ootype.String'), + ('readObject', [''], ''), + ('readShort', [''], 'ootype.SignedLongLong'), + ('readUnsignedByte', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedInt', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedShort', [''], 'ootype.UnsignedLongLong'), + ('readUTF', [''], 'ootype.String'), + ('readUTFBytes', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('uncompress', [''], 'ootype.Void'), + ('writeBoolean', ['ootype.Bool'], 'ootype.Void'), + ('writeByte', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeDouble', ['ootype.Float'], 'ootype.Void'), + ('writeFloat', ['ootype.Float'], 'ootype.Void'), + ('writeInt', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeMultiByte', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('writeObject', [''], 'ootype.Void'), + ('writeShort', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeUnsignedInt', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeUTF', ['ootype.String'], 'ootype.Void'), + ('writeUTFBytes', ['ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesAvailable', 'ootype.UnsignedLongLong'), + ('defaultObjectEncoding', 'ootype.UnsignedLongLong'), + ('endian', 'ootype.String'), + ('length', 'ootype.UnsignedLongLong'), + ('objectEncoding', 'ootype.UnsignedLongLong'), + ('position', 'ootype.UnsignedLongLong'), +] +types['flash.utils.ByteArray'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.Dictionary' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.utils.Dictionary'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.ObjectOutput' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('writeBoolean', ['ootype.Bool'], 'ootype.Void'), + ('writeByte', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeDouble', ['ootype.Float'], 'ootype.Void'), + ('writeFloat', ['ootype.Float'], 'ootype.Void'), + ('writeInt', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeMultiByte', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('writeObject', [''], 'ootype.Void'), + ('writeShort', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeUnsignedInt', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeUTF', ['ootype.String'], 'ootype.Void'), + ('writeUTFBytes', ['ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), +] +types['flash.utils.ObjectOutput'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('setInterval', ['Function', 'ootype.Float', '*args'], 'ootype.UnsignedLongLong'), + ('setTimeout', ['Function', 'ootype.Float', '*args'], 'ootype.UnsignedLongLong'), + ('clearInterval', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('clearTimeout', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('describeType', [''], 'XML'), + ('getQualifiedClassName', [''], 'ootype.String'), + ('getDefinitionByName', ['ootype.String'], 'ootype.Dict'), + ('getQualifiedSuperclassName', [''], 'ootype.String'), + ('getTimer', [''], 'ootype.SignedLongLong'), + ('escapeMultiByte', ['ootype.String'], 'ootype.String'), + ('unescapeMultiByte', ['ootype.String'], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.Dictionary' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.utils.Dictionary'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('setInterval', ['Function', 'ootype.Float', '*args'], 'ootype.UnsignedLongLong'), + ('setTimeout', ['Function', 'ootype.Float', '*args'], 'ootype.UnsignedLongLong'), + ('clearInterval', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('clearTimeout', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('describeType', [''], 'XML'), + ('getQualifiedClassName', [''], 'ootype.String'), + ('getDefinitionByName', ['ootype.String'], 'ootype.Dict'), + ('getQualifiedSuperclassName', [''], 'ootype.String'), + ('getTimer', [''], 'ootype.SignedLongLong'), + ('escapeMultiByte', ['ootype.String'], 'ootype.String'), + ('unescapeMultiByte', ['ootype.String'], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.ByteArray' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('clear', [''], 'ootype.Void'), + ('compress', [''], 'ootype.Void'), + ('deflate', [''], 'ootype.Void'), + ('inflate', [''], 'ootype.Void'), + ('readBoolean', [''], 'ootype.Bool'), + ('readByte', [''], 'ootype.SignedLongLong'), + ('readBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('readDouble', [''], 'ootype.Float'), + ('readFloat', [''], 'ootype.Float'), + ('readInt', [''], 'ootype.SignedLongLong'), + ('readMultiByte', ['ootype.UnsignedLongLong', 'ootype.String'], 'ootype.String'), + ('readObject', [''], ''), + ('readShort', [''], 'ootype.SignedLongLong'), + ('readUnsignedByte', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedInt', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedShort', [''], 'ootype.UnsignedLongLong'), + ('readUTF', [''], 'ootype.String'), + ('readUTFBytes', ['ootype.UnsignedLongLong'], 'ootype.String'), + ('toString', [''], 'ootype.String'), + ('uncompress', [''], 'ootype.Void'), + ('writeBoolean', ['ootype.Bool'], 'ootype.Void'), + ('writeByte', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeDouble', ['ootype.Float'], 'ootype.Void'), + ('writeFloat', ['ootype.Float'], 'ootype.Void'), + ('writeInt', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeMultiByte', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('writeObject', [''], 'ootype.Void'), + ('writeShort', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeUnsignedInt', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeUTF', ['ootype.String'], 'ootype.Void'), + ('writeUTFBytes', ['ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesAvailable', 'ootype.UnsignedLongLong'), + ('defaultObjectEncoding', 'ootype.UnsignedLongLong'), + ('endian', 'ootype.String'), + ('length', 'ootype.UnsignedLongLong'), + ('objectEncoding', 'ootype.UnsignedLongLong'), + ('position', 'ootype.UnsignedLongLong'), +] +types['flash.utils.ByteArray'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.SetIntervalTimer' +desc.BaseType = 'Timer' +desc.Methods = [ + ('!CONSTRUCTOR!', ['Function', 'ootype.Float', 'ootype.Bool', 'ootype.List'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.utils.SetIntervalTimer'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.ObjectOutput' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('writeBoolean', ['ootype.Bool'], 'ootype.Void'), + ('writeByte', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeDouble', ['ootype.Float'], 'ootype.Void'), + ('writeFloat', ['ootype.Float'], 'ootype.Void'), + ('writeInt', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeMultiByte', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('writeObject', [''], 'ootype.Void'), + ('writeShort', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeUnsignedInt', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeUTF', ['ootype.String'], 'ootype.Void'), + ('writeUTFBytes', ['ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), +] +types['flash.utils.ObjectOutput'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.Proxy' +desc.BaseType = 'Object' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.utils.Proxy'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.Timer' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('reset', [''], 'ootype.Void'), + ('start', [''], 'ootype.Void'), + ('stop', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('currentCount', 'ootype.SignedLongLong'), + ('delay', 'ootype.Float'), + ('repeatCount', 'ootype.SignedLongLong'), + ('running', 'ootype.Bool'), +] +types['flash.utils.Timer'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('readExternal', ['flash.utils.IDataInput'], 'ootype.Void'), + ('writeExternal', ['flash.utils.IDataOutput'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.ObjectInput' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('readBoolean', [''], 'ootype.Bool'), + ('readByte', [''], 'ootype.SignedLongLong'), + ('readBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('readDouble', [''], 'ootype.Float'), + ('readFloat', [''], 'ootype.Float'), + ('readInt', [''], 'ootype.SignedLongLong'), + ('readMultiByte', ['ootype.UnsignedLongLong', 'ootype.String'], 'ootype.String'), + ('readObject', [''], ''), + ('readShort', [''], 'ootype.SignedLongLong'), + ('readUnsignedByte', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedInt', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedShort', [''], 'ootype.UnsignedLongLong'), + ('readUTF', [''], 'ootype.String'), + ('readUTFBytes', ['ootype.UnsignedLongLong'], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesAvailable', 'ootype.UnsignedLongLong'), + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), +] +types['flash.utils.ObjectInput'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('writeBoolean', ['ootype.Bool'], 'ootype.Void'), + ('writeByte', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeDouble', ['ootype.Float'], 'ootype.Void'), + ('writeFloat', ['ootype.Float'], 'ootype.Void'), + ('writeInt', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeMultiByte', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('writeObject', [''], 'ootype.Void'), + ('writeShort', ['ootype.SignedLongLong'], 'ootype.Void'), + ('writeUnsignedInt', ['ootype.UnsignedLongLong'], 'ootype.Void'), + ('writeUTF', ['ootype.String'], 'ootype.Void'), + ('writeUTFBytes', ['ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), +] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('readBoolean', [''], 'ootype.Bool'), + ('readByte', [''], 'ootype.SignedLongLong'), + ('readBytes', ['flash.utils.ByteArray', 'ootype.UnsignedLongLong', 'ootype.UnsignedLongLong'], 'ootype.Void'), + ('readDouble', [''], 'ootype.Float'), + ('readFloat', [''], 'ootype.Float'), + ('readInt', [''], 'ootype.SignedLongLong'), + ('readMultiByte', ['ootype.UnsignedLongLong', 'ootype.String'], 'ootype.String'), + ('readObject', [''], ''), + ('readShort', [''], 'ootype.SignedLongLong'), + ('readUnsignedByte', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedInt', [''], 'ootype.UnsignedLongLong'), + ('readUnsignedShort', [''], 'ootype.UnsignedLongLong'), + ('readUTF', [''], 'ootype.String'), + ('readUTFBytes', ['ootype.UnsignedLongLong'], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesAvailable', 'ootype.UnsignedLongLong'), + ('endian', 'ootype.String'), + ('objectEncoding', 'ootype.UnsignedLongLong'), +] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.utils.Endian' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('BIG_ENDIAN', 'String'), + ('LITTLE_ENDIAN', 'String'), +] +types['flash.utils.Endian'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.printing.PrintJobOptions' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.printing.PrintJobOptions'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.printing.PrintJob' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('addPage', ['flash.display.Sprite', 'flash.geom.Rectangle', 'flash.printing.PrintJobOptions', 'ootype.SignedLongLong'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('send', [''], 'ootype.Void'), + ('start', [''], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('orientation', 'ootype.String'), + ('pageHeight', 'ootype.SignedLongLong'), + ('pageWidth', 'ootype.SignedLongLong'), + ('paperHeight', 'ootype.SignedLongLong'), + ('paperWidth', 'ootype.SignedLongLong'), +] +types['flash.printing.PrintJob'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.printing.PrintJobOrientation' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('LANDSCAPE', 'String'), + ('PORTRAIT', 'String'), +] +types['flash.printing.PrintJobOrientation'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.printing.PrintJob' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('addPage', ['flash.display.Sprite', 'flash.geom.Rectangle', 'flash.printing.PrintJobOptions', 'ootype.SignedLongLong'], 'ootype.Void'), + ('!CONSTRUCTOR!', [''], None), + ('send', [''], 'ootype.Void'), + ('start', [''], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('orientation', 'ootype.String'), + ('pageHeight', 'ootype.SignedLongLong'), + ('pageWidth', 'ootype.SignedLongLong'), + ('paperHeight', 'ootype.SignedLongLong'), + ('paperWidth', 'ootype.SignedLongLong'), +] +types['flash.printing.PrintJob'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.printing.PrintJobOrientation' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('LANDSCAPE', 'String'), + ('PORTRAIT', 'String'), +] +types['flash.printing.PrintJobOrientation'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.printing.PrintJobOptions' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.printing.PrintJobOptions'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.Microphone' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('setLoopBack', ['ootype.Bool'], 'ootype.Void'), + ('setSilenceLevel', ['ootype.Float', 'ootype.SignedLongLong'], 'ootype.Void'), + ('setUseEchoSuppression', ['ootype.Bool'], 'ootype.Void'), +] +desc.StaticMethods = [ + ('getMicrophone', ['ootype.SignedLongLong'], 'flash.media.Microphone'), +] +desc.Fields = [] +desc.StaticFields = [ + ('activityLevel', 'ootype.Float'), + ('codec', 'ootype.String'), + ('encodeQuality', 'ootype.SignedLongLong'), + ('framesPerPacket', 'ootype.SignedLongLong'), + ('gain', 'ootype.Float'), + ('index', 'ootype.SignedLongLong'), + ('muted', 'ootype.Bool'), + ('name', 'ootype.String'), + ('names', 'ootype.List'), + ('rate', 'ootype.SignedLongLong'), + ('silenceLevel', 'ootype.Float'), + ('silenceTimeout', 'ootype.SignedLongLong'), + ('soundTransform', 'flash.media.SoundTransform'), + ('useEchoSuppression', 'ootype.Bool'), +] +types['flash.media.Microphone'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.Sound' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('close', [''], 'ootype.Void'), + ('extract', ['flash.utils.ByteArray', 'ootype.Float', 'ootype.Float'], 'ootype.Float'), + ('load', ['flash.net.URLRequest', 'flash.media.SoundLoaderContext'], 'ootype.Void'), + ('play', ['ootype.Float', 'ootype.SignedLongLong', 'flash.media.SoundTransform'], 'flash.media.SoundChannel'), + ('!CONSTRUCTOR!', ['flash.net.URLRequest', 'flash.media.SoundLoaderContext'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesLoaded', 'ootype.UnsignedLongLong'), + ('bytesTotal', 'ootype.SignedLongLong'), + ('id3', 'flash.media.ID3Info'), + ('isBuffering', 'ootype.Bool'), + ('length', 'ootype.Float'), + ('url', 'ootype.String'), +] +types['flash.media.Sound'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.Video' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('attachCamera', ['flash.media.Camera'], 'ootype.Void'), + ('attachNetStream', ['flash.net.NetStream'], 'ootype.Void'), + ('clear', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('deblocking', 'ootype.SignedLongLong'), + ('smoothing', 'ootype.Bool'), + ('videoHeight', 'ootype.SignedLongLong'), + ('videoWidth', 'ootype.SignedLongLong'), +] +types['flash.media.Video'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.Camera' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('setCursor', ['ootype.Bool'], 'ootype.Void'), + ('setKeyFrameInterval', ['ootype.SignedLongLong'], 'ootype.Void'), + ('setLoopback', ['ootype.Bool'], 'ootype.Void'), + ('setMode', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.Float', 'ootype.Bool'], 'ootype.Void'), + ('setMotionLevel', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), + ('setQuality', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), +] +desc.StaticMethods = [ + ('getCamera', ['ootype.String'], 'flash.media.Camera'), +] +desc.Fields = [] +desc.StaticFields = [ + ('activityLevel', 'ootype.Float'), + ('bandwidth', 'ootype.SignedLongLong'), + ('currentFPS', 'ootype.Float'), + ('fps', 'ootype.Float'), + ('height', 'ootype.SignedLongLong'), + ('index', 'ootype.SignedLongLong'), + ('keyFrameInterval', 'ootype.SignedLongLong'), + ('loopback', 'ootype.Bool'), + ('motionLevel', 'ootype.SignedLongLong'), + ('motionTimeout', 'ootype.SignedLongLong'), + ('muted', 'ootype.Bool'), + ('name', 'ootype.String'), + ('names', 'ootype.List'), + ('quality', 'ootype.SignedLongLong'), + ('width', 'ootype.SignedLongLong'), +] +types['flash.media.Camera'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.SoundCodec' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('NELLYMOSER', 'String'), + ('SPEEX', 'String'), +] +types['flash.media.SoundCodec'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.SoundChannel' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('stop', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('leftPeak', 'ootype.Float'), + ('position', 'ootype.Float'), + ('rightPeak', 'ootype.Float'), + ('soundTransform', 'flash.media.SoundTransform'), +] +types['flash.media.SoundChannel'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.ID3Info' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.media.ID3Info'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.SoundMixer' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('areSoundsInaccessible', [''], 'ootype.Bool'), + ('computeSpectrum', ['flash.utils.ByteArray', 'ootype.Bool', 'ootype.SignedLongLong'], 'ootype.Void'), + ('stopAll', [''], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('bufferTime', 'ootype.SignedLongLong'), + ('soundTransform', 'flash.media.SoundTransform'), +] +types['flash.media.SoundMixer'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.SoundTransform' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('leftToLeft', 'ootype.Float'), + ('leftToRight', 'ootype.Float'), + ('pan', 'ootype.Float'), + ('rightToLeft', 'ootype.Float'), + ('rightToRight', 'ootype.Float'), + ('volume', 'ootype.Float'), +] +types['flash.media.SoundTransform'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.SoundLoaderContext' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.media.SoundLoaderContext'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('scanHardware():void', [''], 'oid'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.SoundMixer' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('areSoundsInaccessible', [''], 'ootype.Bool'), + ('computeSpectrum', ['flash.utils.ByteArray', 'ootype.Bool', 'ootype.SignedLongLong'], 'ootype.Void'), + ('stopAll', [''], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('bufferTime', 'ootype.SignedLongLong'), + ('soundTransform', 'flash.media.SoundTransform'), +] +types['flash.media.SoundMixer'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.Sound' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('close', [''], 'ootype.Void'), + ('extract', ['flash.utils.ByteArray', 'ootype.Float', 'ootype.Float'], 'ootype.Float'), + ('load', ['flash.net.URLRequest', 'flash.media.SoundLoaderContext'], 'ootype.Void'), + ('play', ['ootype.Float', 'ootype.SignedLongLong', 'flash.media.SoundTransform'], 'flash.media.SoundChannel'), + ('!CONSTRUCTOR!', ['flash.net.URLRequest', 'flash.media.SoundLoaderContext'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('bytesLoaded', 'ootype.UnsignedLongLong'), + ('bytesTotal', 'ootype.SignedLongLong'), + ('id3', 'flash.media.ID3Info'), + ('isBuffering', 'ootype.Bool'), + ('length', 'ootype.Float'), + ('url', 'ootype.String'), +] +types['flash.media.Sound'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('scanHardware():void', [''], 'oid'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.Camera' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('setCursor', ['ootype.Bool'], 'ootype.Void'), + ('setKeyFrameInterval', ['ootype.SignedLongLong'], 'ootype.Void'), + ('setLoopback', ['ootype.Bool'], 'ootype.Void'), + ('setMode', ['ootype.SignedLongLong', 'ootype.SignedLongLong', 'ootype.Float', 'ootype.Bool'], 'ootype.Void'), + ('setMotionLevel', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), + ('setQuality', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], 'ootype.Void'), +] +desc.StaticMethods = [ + ('getCamera', ['ootype.String'], 'flash.media.Camera'), +] +desc.Fields = [] +desc.StaticFields = [ + ('activityLevel', 'ootype.Float'), + ('bandwidth', 'ootype.SignedLongLong'), + ('currentFPS', 'ootype.Float'), + ('fps', 'ootype.Float'), + ('height', 'ootype.SignedLongLong'), + ('index', 'ootype.SignedLongLong'), + ('keyFrameInterval', 'ootype.SignedLongLong'), + ('loopback', 'ootype.Bool'), + ('motionLevel', 'ootype.SignedLongLong'), + ('motionTimeout', 'ootype.SignedLongLong'), + ('muted', 'ootype.Bool'), + ('name', 'ootype.String'), + ('names', 'ootype.List'), + ('quality', 'ootype.SignedLongLong'), + ('width', 'ootype.SignedLongLong'), +] +types['flash.media.Camera'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.SoundTransform' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Float'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('leftToLeft', 'ootype.Float'), + ('leftToRight', 'ootype.Float'), + ('pan', 'ootype.Float'), + ('rightToLeft', 'ootype.Float'), + ('rightToRight', 'ootype.Float'), + ('volume', 'ootype.Float'), +] +types['flash.media.SoundTransform'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.SoundChannel' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('stop', [''], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('leftPeak', 'ootype.Float'), + ('position', 'ootype.Float'), + ('rightPeak', 'ootype.Float'), + ('soundTransform', 'flash.media.SoundTransform'), +] +types['flash.media.SoundChannel'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.Microphone' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('setLoopBack', ['ootype.Bool'], 'ootype.Void'), + ('setSilenceLevel', ['ootype.Float', 'ootype.SignedLongLong'], 'ootype.Void'), + ('setUseEchoSuppression', ['ootype.Bool'], 'ootype.Void'), +] +desc.StaticMethods = [ + ('getMicrophone', ['ootype.SignedLongLong'], 'flash.media.Microphone'), +] +desc.Fields = [] +desc.StaticFields = [ + ('activityLevel', 'ootype.Float'), + ('codec', 'ootype.String'), + ('encodeQuality', 'ootype.SignedLongLong'), + ('framesPerPacket', 'ootype.SignedLongLong'), + ('gain', 'ootype.Float'), + ('index', 'ootype.SignedLongLong'), + ('muted', 'ootype.Bool'), + ('name', 'ootype.String'), + ('names', 'ootype.List'), + ('rate', 'ootype.SignedLongLong'), + ('silenceLevel', 'ootype.Float'), + ('silenceTimeout', 'ootype.SignedLongLong'), + ('soundTransform', 'flash.media.SoundTransform'), + ('useEchoSuppression', 'ootype.Bool'), +] +types['flash.media.Microphone'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.Video' +desc.BaseType = 'DisplayObject' +desc.Methods = [ + ('attachCamera', ['flash.media.Camera'], 'ootype.Void'), + ('attachNetStream', ['flash.net.NetStream'], 'ootype.Void'), + ('clear', [''], 'ootype.Void'), + ('!CONSTRUCTOR!', ['ootype.SignedLongLong', 'ootype.SignedLongLong'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('deblocking', 'ootype.SignedLongLong'), + ('smoothing', 'ootype.Bool'), + ('videoHeight', 'ootype.SignedLongLong'), + ('videoWidth', 'ootype.SignedLongLong'), +] +types['flash.media.Video'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.ID3Info' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.media.ID3Info'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.SoundLoaderContext' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', ['ootype.Float', 'ootype.Bool'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.media.SoundLoaderContext'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.media.SoundCodec' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('NELLYMOSER', 'String'), + ('SPEEX', 'String'), +] +types['flash.media.SoundCodec'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.sampler.Sample' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.sampler.Sample'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.sampler.DeleteObjectSample' +desc.BaseType = 'Sample' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.sampler.DeleteObjectSample'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.sampler.StackFrame' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.sampler.StackFrame'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('clearSamples', [''], 'ootype.Void'), + ('startSampling', [''], 'ootype.Void'), + ('stopSampling', [''], 'ootype.Void'), + ('pauseSampling', [''], 'ootype.Void'), + ('getSize', [''], 'ootype.Float'), + ('getMemberNames', ['ootype.Dict', 'ootype.Bool'], 'ootype.Dict'), + ('getSamples', [''], 'ootype.Dict'), + ('getSampleCount', [''], 'ootype.Float'), + ('getInvocationCount', ['ootype.Dict', 'QName'], 'ootype.Float'), + ('getSetterInvocationCount', ['ootype.Dict', 'QName'], 'ootype.Float'), + ('getGetterInvocationCount', ['ootype.Dict', 'QName'], 'ootype.Float'), + ('isGetterSetter', ['ootype.Dict', 'QName'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.sampler.NewObjectSample' +desc.BaseType = 'Sample' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('object', ''), +] +types['flash.sampler.NewObjectSample'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('clearSamples', [''], 'ootype.Void'), + ('startSampling', [''], 'ootype.Void'), + ('stopSampling', [''], 'ootype.Void'), + ('pauseSampling', [''], 'ootype.Void'), + ('getSize', [''], 'ootype.Float'), + ('getMemberNames', ['ootype.Dict', 'ootype.Bool'], 'ootype.Dict'), + ('getSamples', [''], 'ootype.Dict'), + ('getSampleCount', [''], 'ootype.Float'), + ('getInvocationCount', ['ootype.Dict', 'QName'], 'ootype.Float'), + ('getSetterInvocationCount', ['ootype.Dict', 'QName'], 'ootype.Float'), + ('getGetterInvocationCount', ['ootype.Dict', 'QName'], 'ootype.Float'), + ('isGetterSetter', ['ootype.Dict', 'QName'], 'ootype.Bool'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.sampler.StackFrame' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), + ('toString', [''], 'ootype.String'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.sampler.StackFrame'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.sampler.NewObjectSample' +desc.BaseType = 'Sample' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('object', ''), +] +types['flash.sampler.NewObjectSample'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.sampler.DeleteObjectSample' +desc.BaseType = 'Sample' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.sampler.DeleteObjectSample'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'flash.sampler.Sample' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types['flash.sampler.Sample'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'adobe.utils.ProductManager' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('download', ['ootype.String', 'ootype.String', 'ootype.List'], 'ootype.Bool'), + ('launch', ['ootype.String'], 'ootype.Bool'), + ('!CONSTRUCTOR!', ['ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('installed', 'ootype.Bool'), + ('installedVersion', 'ootype.String'), + ('running', 'ootype.Bool'), +] +types['adobe.utils.ProductManager'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'adobe.utils.CustomActions' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('getActions', ['ootype.String'], 'ootype.String'), + ('installActions', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('uninstallActions', ['ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('actionsList', 'ootype.List'), +] +types['adobe.utils.CustomActions'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'adobe.utils.XMLUI' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('accept', [''], 'ootype.Void'), + ('cancel', [''], 'ootype.Void'), + ('getProperty', ['ootype.String'], 'ootype.String'), + ('setProperty', ['ootype.String', 'ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [] +types['adobe.utils.XMLUI'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('MMExecute', ['ootype.String'], 'ootype.String'), + ('MMEndCommand', ['ootype.Bool', 'ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'adobe.utils.XMLUI' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('accept', [''], 'ootype.Void'), + ('cancel', [''], 'ootype.Void'), + ('getProperty', ['ootype.String'], 'ootype.String'), + ('setProperty', ['ootype.String', 'ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [] +types['adobe.utils.XMLUI'] = desc +del desc + +desc = ClassDesc() +desc.FullName = '' +desc.BaseType = '' +desc.Methods = [ + ('MMExecute', ['ootype.String'], 'ootype.String'), + ('MMEndCommand', ['ootype.Bool', 'ootype.String'], 'ootype.Void'), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [] +types[''] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'adobe.utils.ProductManager' +desc.BaseType = 'EventDispatcher' +desc.Methods = [ + ('download', ['ootype.String', 'ootype.String', 'ootype.List'], 'ootype.Bool'), + ('launch', ['ootype.String'], 'ootype.Bool'), + ('!CONSTRUCTOR!', ['ootype.String'], None), +] +desc.StaticMethods = [] +desc.Fields = [] +desc.StaticFields = [ + ('installed', 'ootype.Bool'), + ('installedVersion', 'ootype.String'), + ('running', 'ootype.Bool'), +] +types['adobe.utils.ProductManager'] = desc +del desc + +desc = ClassDesc() +desc.FullName = 'adobe.utils.CustomActions' +desc.BaseType = 'Object' +desc.Methods = [ + ('!CONSTRUCTOR!', [''], None), +] +desc.StaticMethods = [ + ('getActions', ['ootype.String'], 'ootype.String'), + ('installActions', ['ootype.String', 'ootype.String'], 'ootype.Void'), + ('uninstallActions', ['ootype.String'], 'ootype.Void'), +] +desc.Fields = [] +desc.StaticFields = [ + ('actionsList', 'ootype.List'), +] +types['adobe.utils.CustomActions'] = desc +del desc Modified: pypy/branch/avm/pypy/translator/avm2/avm2gen.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/avm2gen.py (original) +++ pypy/branch/avm/pypy/translator/avm2/avm2gen.py Wed Jan 13 19:26:30 2010 @@ -2,286 +2,41 @@ """ backend generator routines """ +from mech.fusion.avm2 import constants, instructions, \ + abc_ as abc, traits, avm2gen, traits + from pypy.objspace.flow import model as flowmodel from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong from pypy.rpython.ootypesystem import ootype -from pypy.translator.avm2 import assembler, constants, instructions, abc_ as abc, types_ as types, traits, util +from pypy.translator.avm2 import types_ as types, query from pypy.translator.oosupport.treebuilder import SubOperation from pypy.translator.oosupport.metavm import Generator from pypy.translator.oosupport.constant import push_constant from itertools import chain -class GlobalContext(object): - CONTEXT_TYPE = "global" - parent = None - - def __init__(self, gen): - self.gen = gen - - def exit(self): - return None - - def new_script(self): - ctx = ScriptContext(self.gen, self) - self.gen.enter_context(ctx) - return ctx - -class _MethodContextMixin(object): - def new_method(self, name, params, rettype, static=False): - meth = abc.AbcMethodInfo(name, [t.multiname() for t, n in params], rettype.multiname(), param_names=[n for t, n in params]) - trait = traits.AbcMethodTrait(constants.QName(name), meth) - if static: - self.add_static_trait(trait) - else: - self.add_instance_trait(trait) - ctx = MethodContext(self.gen, meth, self, params) - self.gen.enter_context(ctx) - return ctx - -class ScriptContext(_MethodContextMixin): - CONTEXT_TYPE = "script" - - def __init__(self, gen, parent): - self.gen, self.parent = gen, parent - self.traits = [] - self.pending_classes = {} - - def make_init(self): - self.init = abc.AbcMethodInfo("", [], constants.ANY_NAME) - ctx = MethodContext(self.gen, self.init, self, []) - self.gen.enter_context(ctx) - return ctx - - def new_class(self, name, super_name=None, bases=None): - # allow hardcoded bases - ctx = ClassContext(self.gen, name, super_name, self) - self.pending_classes[name] = (ctx, bases) - self.gen.enter_context(ctx) - return ctx - - def add_trait(self, trait): - self.traits.append(trait) +class PyPyAvm2ilasm(avm2gen.Avm2ilasm, Generator): - add_static_trait = add_trait - add_instance_trait = add_trait - - def exit(self): - assert self.parent.CONTEXT_TYPE == "global" - - self.make_init() - - for context, parents in self.pending_classes.itervalues(): - parent = self.pending_classes.get(context.super_name, None) - - if parents is None: - parents = [] - while parent: - parents.append(parent.name) - parent = self.pending_classes.get(parent.super_name, None) - - parents.append(constants.QName("Object")) - - self.gen.I(instructions.getscopeobject(0)) - for parent in reversed(parents): - self.gen.I(instructions.getlex(parent), instructions.pushscope()) - - self.traits.append(traits.AbcClassTrait(context.name, context.classobj)) - self.gen.I(instructions.getlex(context.super_name)) - self.gen.I(instructions.newclass(context.index)) - self.gen.I(*[instructions.popscope()]*len(parents)) - self.gen.I(instructions.initproperty(context.name)) - - self.gen.abc.scripts.index_for(abc.AbcScriptInfo(self.init, self.traits)) - self.gen.exit_context() - return self.parent - -class ClassContext(_MethodContextMixin): - CONTEXT_TYPE = "class" - - def __init__(self, gen, name, super_name, parent): - self.gen, self.name, self.super_name, self.parent = gen, name, super_name or constants.QName("Object"), parent - self.instance_traits = [] - self.static_traits = [] - self.cinit = None - self.iinit = None - - def make_cinit(self): - self.cinit = abc.AbcMethodInfo("", [], constants.ANY_NAME) - ctx = MethodContext(self.gen, self.cinit, self, []) - self.gen.enter_context(ctx) - return ctx - - def make_iinit(self, params=None): - params = params or () - self.iinit = abc.AbcMethodInfo("", [t.multiname() for t, n in params], constants.QName("void"), param_names=[n for t, n in params]) - ctx = MethodContext(self.gen, self.iinit, self, params) - self.gen.enter_context(ctx) - - self.gen.emit('getlocal', 0) - self.gen.emit('constructsuper', 0) - return ctx - - def add_instance_trait(self, trait): - self.instance_traits.append(trait) - return len(self.instance_traits) - - def add_static_trait(self, trait): - self.static_traits.append(trait) - return len(self.static_traits) - - def exit(self): - assert self.parent.CONTEXT_TYPE == "script" - if self.iinit is None: - self.make_iinit() - self.gen.exit_context() - if self.cinit is None: - self.make_cinit() - self.gen.exit_context() - self.instance = abc.AbcInstanceInfo(self.name, self.iinit, traits=self.instance_traits, super_name=self.super_name) - self.classobj = abc.AbcClassInfo(self.cinit, traits=self.static_traits) - self.index = self.gen.abc.instances.index_for(self.instance) - self.gen.abc.classes.index_for(self.classobj) - return self.parent - -class MethodContext(object): - CONTEXT_TYPE = "method" - - def __init__(self, gen, method, parent, params, stdprologue=True): - self.gen, self.method, self.parent = gen, method, parent - param_names = [n for t, n in params] - self.asm = assembler.Avm2CodeAssembler(gen.constants, ['this']+param_names) - self.acv_traits = [] - if stdprologue: - self.asm.add_instruction(instructions.getlocal(0)) - self.asm.add_instruction(instructions.pushscope()) - - def exit(self): - self.asm.add_instruction(instructions.returnvoid()) - self.gen.abc.methods.index_for(self.method) - self.gen.abc.bodies.index_for(abc.AbcMethodBodyInfo(self.method, self.asm, self.acv_traits)) - return self.parent - - def add_activation_trait(self, trait): - self.acv_traits.append(trait) - return len(self.acv_traits) - - def add_instructions(self, *i): - self.asm.add(*i) - - @property - def next_free_local(self): - return self.asm.next_free_local - - def set_local(self, name): - return self.asm.set_local(name) - - def kill_local(self, name): - return self.asm.kill_local(name) - - def get_local(self, name): - return self.asm.get_local(name) - - def has_local(self, name): - return self.asm.has_local(name) - -class Avm2ilasm(Generator): - """ AVM2 'assembler' generator routines """ - def __init__(self, db, abc_=None): - self.abc = abc_ or abc.AbcFile() - self.constants = self.abc.constants - self.context = GlobalContext(self) - self.script0 = self.context.new_script() - self.gen = db + def __init__(self, db, abc): + super(PyPyAvm2ilasm, self).__init__(abc) + self.db = db self.cts = db.genoo.TypeSystem(db) - - def I(self, *i): - self.context.add_instructions(i) - - def M(self, multiname): - return self.constants.multiname_pool.index_for(multiname) - - def SL(self, name): - index = self.context.set_local(name) - self.I(instructions.setlocal(index)) - return index - - def GL(self, name=None): - index = self.context.get_local(name) - self.I(instructions.getlocal(index)) - return index - - def KL(self, name): - index = self.context.kill_local(name) - self.I(instructions.kill(index)) - def HL(self, name): - return self.context.has_local(name) - - def begin_class(self, name, super_name=None, bases=None): - return self.context.new_class(name, super_name, bases) - - def begin_method(self, name, arglist, returntype, static=False): - return self.context.new_method(name, arglist, returntype, static) - - def finish(self): - while self.context: - self.context = self.context.exit() - - # @property - # def current_namespaces(self): - # context = self.scope - # namespaces = [] - # while context is not None: - # namespaces += context.namespaces - # context = context.parent - # return namespaces - - def enter_context(self, ctx): - self.context = ctx - - def exit_context(self): - ctx = self.context - self.context = ctx.exit() - return ctx - - def current_class(self): - context = self.context - while context is not None: - if context.CONTEXT_TYPE == "class": - return context - context = context.parent - return None - - def pop(self, TYPE): - self.I(instructions.pop()) + def _get_type(self, TYPE): + return self.cts.lltype_to_cts(TYPE) - def dup(self, TYPE): - self.I(instructions.dup()) - - def swap(self): - self.I(instructions.swap()) - - def emit(self, instr, *args, **kwargs): - self.I(instructions.INSTRUCTIONS[instr](*args, **kwargs)) - - def set_label(self, label): - self.emit('label', label) - - def branch_unconditionally(self, label): - self.emit('jump', label) - - def branch_conditionally(self, iftrue, label): - if iftrue: - self.emit('iftrue', label) + def get_class_context(self, name, DICT): + class_desc = query.Types.get(name, None) + if class_desc: + BaseType = class_desc.BaseType + if '.' in BaseType: + ns, name = class_desc.BaseType.rsplit('.', 1) + else: + ns, name = '', BaseType + class_desc.super_name = constants.packagedQName(ns, name) + return class_desc else: - self.emit('iffalse', label) - - def call_function_constargs(self, name, *args): - self.emit('getglobalscope') - if args: - self.load(*args) - self.emit('callproperty', constants.QName(name), len(args)) + return super(PyPyAvm2ilasm, self).get_class_context(name, DICT) def load(self, v, *args): if isinstance(v, flowmodel.Variable): @@ -291,20 +46,11 @@ self.push_local(v) elif isinstance(v, flowmodel.Constant): push_constant(self.db, v.concretetype, v.value, self) - elif hasattr(v, "multiname"): - self.I(instructions.getlex(v.multiname())) else: - self.push_const(v) - - for i in args: - self.load(i) + super(PyPyAvm2ilasm, self).load(v) - def store_var(self, name): - self.SL(name) - - def store(self, v): - if v.concretetype is not ootype.Void: - self.store_var(v.name) + for e in args: + self.load(e) # def prepare_call_oostring(self, OOTYPE): # self.I(instructions.findpropstrict(types._str_qname)) @@ -314,62 +60,15 @@ # call_oounicode = call_oostring # prepare_call_oounicode = prepare_call_oostring - - def newarray(self, TYPE, length=1): - self.load(types._arr_qname) - self.push_const(length) - self.I(instructions.construct(1)) - + def oonewarray(self, TYPE, length=1): - self.load(types._vec_qname) + self.load(types.vec_qname) self.load(self.cts.lltype_to_cts(TYPE.ITEM)) self.I(instructions.applytype(1)) self.load(length) self.I(instructions.construct(1)) self.I(instructions.coerce(self.cts.lltype_to_cts(TYPE).multiname())) - - def array_setitem(self, ARRAY): - self.I(instructions.setproperty(constants.MultinameL(constants.PROP_NAMESPACE_SET))) - - def array_getitem(self, ARRAY): - self.I(instructions.getproperty(constants.MultinameL(constants.PROP_NAMESPACE_SET))) - def push_this(self): - self.GL("this") - - def push_local(self, v): - self.push_var(v.name) - - push_arg = push_local - - def push_var(self, v): - self.GL(v) - - def push_const(self, v): - if isinstance(v, (long, int, r_int, r_uint, r_longlong, r_ulonglong, float)): - if isinstance(v, float) or v > util.U32_MAX or v < -util.S32_MAX: - self.I(instructions.pushdouble(self.constants.double_pool.index_for(v))) - elif 0 <= v < 256: - self.I(instructions.pushbyte(v)) - elif v >= 0: - self.I(instructions.pushuint(self.constants.uint_pool.index_for(v))) - else: - self.I(instructions.pushint(self.constants.int_pool.index_for(v))) - elif isinstance(v, basestring): - self.I(instructions.pushstring(self.constants.utf8_pool.index_for(v))) - elif v is True: - self.I(instructions.pushtrue()) - elif v is False: - self.I(instructions.pushfalse()) - else: - assert False, "value for push_const not a literal value" - - def push_undefined(self): - self.I(instructions.pushundefined()) - - def push_null(self, TYPE=None): - self.I(instructions.pushnull()) - def push_primitive_constant(self, TYPE, value): if TYPE is ootype.Void: self.push_null() @@ -381,26 +80,23 @@ else: self.push_const(value) - def init_array(self, members=None): - if members: - self.load(*members) - self.I(instructions.newarray(len(members))) - - def init_object(self, members=None): - if members: - self.load(*chain(*members.iteritems())) - self.I(instructions.newobject(len(members))) - - def init_vector(self, TYPE, members=None): - if members: - self.load(*members) - self.oonewarray(TYPE, len(members)) - - def set_field(self, TYPE, fieldname): - self.emit('setproperty', constants.QName(fieldname)) - def new(self, TYPE): # XXX: assume no args for now t = self.cts.lltype_to_cts(TYPE).multiname() self.emit('findpropstrict', t) self.emit('constructprop', t, 0) + + def array_setitem(self, ARRAY=None): + self.I(instructions.setproperty(constants.MultinameL( + constants.PROP_NAMESPACE_SET))) + # Hack: oosend expects a value to send to StoreResult + # We don't generate one, push a null. + self.push_null() + + def array_getitem(self, ARRAY=None): + self.I(instructions.getproperty(constants.MultinameL( + constants.PROP_NAMESPACE_SET))) + + def array_length(self, ARRAY=None): + self.I(instructions.getproperty(constants.QName("length"))) + Modified: pypy/branch/avm/pypy/translator/avm2/class_.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/class_.py (original) +++ pypy/branch/avm/pypy/translator/avm2/class_.py Wed Jan 13 19:26:30 2010 @@ -1,9 +1,11 @@ from pypy.rpython.ootypesystem import ootype from pypy.translator.cli.node import Node -from pypy.translator.avm2 import types_ as types, constants as c, traits from pypy.translator.oosupport.constant import push_constant from pypy.translator.cli.ilgenerator import CLIBaseGenerator +from mech.fusion.avm2 import constants as c, traits +from pypy.translator.avm2 import types_ as types + try: set except NameError: @@ -45,7 +47,8 @@ if self.is_root(base_class): return c.QName("Object") else: - return c.QName(self.db.class_name(base_class)) + ns, name = self.db.class_name(base_class).rsplit('::', 1) + return c.packagedQName(ns, name) def is_abstract(self): return False # XXX @@ -77,7 +80,7 @@ self.ilasm = ilasm self.gen = CLIBaseGenerator(self.db, ilasm) - ilasm.begin_class(c.QName(self.name), self.get_base_class()) + ilasm.begin_class(c.packagedQName(self.namespace, self.name), self.get_base_class()) for f_name, (f_type, f_default) in self.INSTANCE._fields.iteritems(): cts_type = self.cts.lltype_to_cts(f_type) f_name = self.cts.escape_name(f_name) @@ -98,6 +101,15 @@ if not ootype.isSubclass(self.INSTANCE, SELF): continue f = self.db.genoo.Function(self.db, m_meth.graph, m_name) + + context = self.INSTANCE._superclass + while context: + if m_name in context._methods: + f.override = True + print "Overriding", m_name + break + context = context._superclass + f.render(ilasm) else: # abstract method @@ -130,13 +142,17 @@ self.ilasm.push_this() push_constant(self.db, F_TYPE, f_default, self.gen) # class_name = self.db.class_name(INSTANCE_DEF) - self.ilasm.emit('setproperty', c.packagedQName(f_name)) + self.ilasm.emit('setproperty', c.QName(f_name)) self.ilasm.exit_context() def _toString(self): - self.ilasm.begin_method('toString', [], types.types.string) - self.ilasm.push_this() + if self.is_root(self.INSTANCE._superclass): + override = False + else: + override = True + print "Overriding toString" + self.ilasm.begin_method('toString', [], types.types.string, override=override) self.ilasm.load("InstanceWrapper('%s')" % (self.name)) self.ilasm.emit('returnvalue') self.ilasm.exit_context() Modified: pypy/branch/avm/pypy/translator/avm2/constant.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/constant.py (original) +++ pypy/branch/avm/pypy/translator/avm2/constant.py Wed Jan 13 19:26:30 2010 @@ -31,9 +31,11 @@ BaseConstantGenerator, AbstractConst, ArrayConst from pypy.rpython.ootypesystem import ootype from pypy.translator.cli.comparer import EqualityComparer -from pypy.translator.avm2 import constants, types_ as types, traits +from pypy.translator.avm2 import types_ as types from pypy.rpython.lltypesystem import lltype +from mech.fusion.avm2 import constants, traits + CONST_CLASS = constants.packagedQName("pypy.runtime", "Constants") DEBUG_CONST_INIT = False @@ -82,18 +84,18 @@ return BaseConstantGenerator._get_key_for_const(self, value) def push_constant(self, gen, const): - type_ = const.get_type() gen.emit('getlex', CONST_CLASS) gen.emit('getproperty', constants.QName(const.name)) - #def _push_constant_during_init(self, gen, const): - # self.push_constant(gen, const) - # gen.store_var('current_constant') + def _push_constant_during_init(self, gen, const): + gen.push_this() + gen.emit('getproperty', constants.QName(const.name)) + def _pre_store_constant(self, gen, const): + gen.push_this() + def _store_constant(self, gen, const): - type_ = const.get_type() - gen.emit('getlex', CONST_CLASS) - gen.emit('setproperty', constants.QName(const.name)) + gen.emit('initproperty', constants.QName(const.name)) def _declare_step(self, gen, stepnum): pass @@ -121,17 +123,17 @@ # to each sub-class of that base-class. Kind of awkward. class Avm2BaseConstMixin(object): - """ A mix-in with a few extra methods the CLI backend uses """ + """ A mix-in with a few extra methods the Tamarin backend uses """ def get_type(self): - """ Returns the CLI type for this constant's representation """ + """ Returns the Tamrin type for this constant's representation """ return self.cts.lltype_to_cts(self.value._TYPE) def push_inline(self, gen, TYPE): - """ Overload the oosupport version so that we use the CLI opcode - for pushing NULL """ + """ Overload the oosupport version so that we use the Tamarin + opcode for pushing NULL """ assert self.is_null() - gen.ilasm.opcode('pushnull') + gen.ilasm.push_null() # class Avm2DictMixin(Avm2BaseConstMixin): # def _check_for_void_dict(self, gen): @@ -196,42 +198,42 @@ else: INSTANCE = self.value._INSTANCE classname = self.db.class_name(INSTANCE) - gen.emit('getlex', constants.QName(classname)) + ns, name = classname.rsplit('::', 1) + gen.emit('getlex', constants.packagedQName(ns, name)) return super(Avm2ClassConst, self).push_inline(gen, EXPECTED_TYPE) -# class CLIListConst(CLIBaseConstMixin, ListConst): -# def _do_not_initialize(self): -# # Check if it is a list of all zeroes: -# try: -# if self.value._list == [0] * len(self.value._list): -# return True -# except: -# pass -# return super(CLIListConst, self)._do_not_initialize() - -# def create_pointer(self, gen): -# self.db.const_count.inc('List') -# self.db.const_count.inc('List', self.value._TYPE.ITEM) -# self.db.const_count.inc('List', len(self.value._list)) -# super(CLIListConst, self).create_pointer(gen) - - -# class CLIArrayConst(CLIBaseConstMixin, ArrayConst): - -# def _do_not_initialize(self): -# # Check if it is an array of all zeroes: -# try: -# if self.value._list == [0] * len(self.value._list): -# return True -# except: -# pass -# return super(CLIArrayConst, self)._do_not_initialize() +class Avm2ArrayListConst(Avm2BaseConstMixin, ListConst): -# def _setitem(self, SELFTYPE, gen): -# gen.array_setitem(SELFTYPE) + def _do_not_initialize(self): + # Check if it is a list of all zeroes: + try: + if self.value._list == [0] * len(self.value._list): + return True + except: + pass + return super(Avm2ListConst, self)._do_not_initialize() + + def create_pointer(self, gen): + llen = len(self.value._list) + self.db.const_count.inc('List') + self.db.const_count.inc('List', self.value._TYPE.ITEM) + self.db.const_count.inc('List', llen) + gen.oonewarray(self.value._TYPE, llen) + + def initialize_data(self, constgen, gen): + assert not self.is_null() + + # check for special cases and avoid initialization + if self._do_not_initialize(): + return + # set each item in the list using the OOTYPE methods + for idx, item in enumerate(self.value._array): + gen.dup() + gen.emit('setproperty', constants.Multiname( + str(idx), constants.PROP_NAMESPACE_SET)) # class CLIDictConst(CLIDictMixin, DictConst): # def create_pointer(self, gen): Modified: pypy/branch/avm/pypy/translator/avm2/database.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/database.py (original) +++ pypy/branch/avm/pypy/translator/avm2/database.py Wed Jan 13 19:26:30 2010 @@ -13,6 +13,7 @@ class LowLevelDatabase(OODatabase): def __init__(self, genoo): OODatabase.__init__(self, genoo) + self._pending_nodes = [] self.classes = {} # INSTANCE --> class_name self.classnames = set() # (namespace, name) self.functions = {} # graph --> function_name @@ -117,3 +118,13 @@ self.delegates[TYPE] = name self.pending_node(Delegate(self, TYPE, name)) return name + + def pending_node(self, node): + """ Adds a node to the worklist, so long as it is not already there + and has not already been rendered. """ + assert not self.locked # sanity check + if node in self._pending_nodes or node in self._rendered_nodes: + return + self._pending_nodes.append(node) + node.dependencies() + Modified: pypy/branch/avm/pypy/translator/avm2/function.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/function.py (original) +++ pypy/branch/avm/pypy/translator/avm2/function.py Wed Jan 13 19:26:30 2010 @@ -5,7 +5,8 @@ from pypy.rpython.lltypesystem.lltype import Void from pypy.translator.oosupport.function import Function as OOFunction from pypy.translator.cli.node import Node -from pypy.translator.avm2 import constants, types_ as types +from pypy.translator.avm2 import types_ as types +from mech.fusion.avm2 import constants class Function(OOFunction, Node): @@ -27,7 +28,9 @@ else: self.namespace = None self.classname = None - + + self.override = False + def _create_generator(self, ilasm): ilasm.db = self.db return ilasm @@ -50,9 +53,9 @@ returntype, returnvar = self.cts.llvar_to_cts(self.graph.getreturnvar()) if self.classname: - self.generator.begin_method(self.name, self.args[1:], returntype) + self.generator.begin_method(self.name, self.args[1:], returntype, override=self.override) else: - self.generator.begin_method(self.name, self.args, returntype, static=True) + self.generator.begin_method(self.name, self.args, returntype, static=True, override=self.override) def end_render(self): # if self.generator.scope.islabel: @@ -70,13 +73,19 @@ def set_label(self, label): return self.generator.set_label(label) + def _trace_enabled(self): + return True + + def _trace(self, s, writeline=False): + print "TRACE:", s + + def _trace_value(self, prompt, v): + print "TRACE: P:", prompt, "V:", v def _render_op(self, op): - #instr_list = self.db.genoo.opcodes.get(op.opname, None) - #instr_list.render(self.generator, op) - print op + print "Rendering op:", op super(Function, self)._render_op(op) - + def _setup_link(self, link): target = link.target linkvars = [] @@ -86,7 +95,7 @@ if to_load.concretetype is ootype.Void: continue linkvars.append((to_load, to_store)) - + # after SSI_to_SSA it can happen to have to_load = [a, b] and # to_store = [b, c]. If we store each variable sequentially, # 'b' would be overwritten before being read. To solve, we @@ -104,50 +113,48 @@ self.generator.store(to_store) - # def begin_try(self, cond): - # if cond: - # self.ilasm.begin_try() + def begin_try(self, cond): + if cond: + self.ilasm.begin_try() - # def end_try(self, target_label, cond): - # if cond: - # self.ilasm.leave(target_label) - # self.ilasm.end_try() - # else: - # self.ilasm.branch(target_label) + def end_try(self, target_label, cond): + if cond: + self.ilasm.end_try() + self.ilasm.branch_unconditionally(target_label) + + def begin_catch(self, llexitcase): + ll_meta_exc = llexitcase + ll_exc = ll_meta_exc._INSTANCE + self.ilasm.begin_catch(ll_exc) - # def begin_catch(self, llexitcase): - # ll_meta_exc = llexitcase - # ll_exc = ll_meta_exc._INSTANCE - # cts_exc = self.cts.lltype_to_cts(ll_exc) - # self.ilasm.begin_catch(cts_exc.classname()) - - # def end_catch(self, target_label): - # self.ilasm.leave(target_label) - # self.ilasm.end_catch() + def end_catch(self, target_label): + self.ilasm.end_catch() + self.ilasm.branch_unconditionally(target_label) def render_raise_block(self, block): exc = block.inputargs[1] + print exc self.generator.load(exc) self.generator.emit('throw') - # def store_exception_and_link(self, link): - # if self._is_raise_block(link.target): - # # the exception value is on the stack, use it as the 2nd target arg - # assert len(link.args) == 2 - # assert len(link.target.inputargs) == 2 - # self.store(link.target.inputargs[1]) - # else: - # # the exception value is on the stack, store it in the proper place - # if isinstance(link.last_exception, flowmodel.Variable): - # self.ilasm.opcode('dup') - # self.store(link.last_exc_value) - # self.ilasm.call_method( - # 'class [mscorlib]System.Type object::GetType()', - # virtual=True) - # self.store(link.last_exception) - # else: - # self.store(link.last_exc_value) - # self._setup_link(link) + def store_exception_and_link(self, link): + if self._is_raise_block(link.target): + # the exception value is on the stack, use it as the 2nd target arg + assert len(link.args) == 2 + assert len(link.target.inputargs) == 2 + self.store(link.target.inputargs[1]) + else: + # the exception value is on the stack, store it in the proper place + if isinstance(link.last_exception, flowmodel.Variable): + self.ilasm.opcode('dup') + self.store(link.last_exc_value) + self.ilasm.call_method( + 'class [mscorlib]System.Type object::GetType()', + virtual=True) + self.store(link.last_exception) + else: + self.store(link.last_exc_value) + self._setup_link(link) # def render_numeric_switch(self, block): # if block.exitswitch.concretetype in (ootype.SignedLongLong, ootype.UnsignedLongLong): Modified: pypy/branch/avm/pypy/translator/avm2/genavm.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/genavm.py (original) +++ pypy/branch/avm/pypy/translator/avm2/genavm.py Wed Jan 13 19:26:30 2010 @@ -1,25 +1,27 @@ import py from pypy.translator.oosupport.genoo import GenOO -from pypy.translator.avm2.avm2gen import Avm2ilasm -from pypy.translator.avm2.constant import Avm2ConstGenerator, Avm2ClassConst, Avm2InstanceConst, Avm2RecordConst +from pypy.translator.avm2.avm2gen import PyPyAvm2ilasm +from pypy.translator.avm2.constant import Avm2ConstGenerator, Avm2ClassConst, Avm2InstanceConst, Avm2RecordConst, Avm2ArrayListConst from pypy.translator.avm2.database import LowLevelDatabase -from pypy.translator.avm2.function import Function +from pypy.translator.avm2.function import Function as TamarinFunction from pypy.translator.avm2.opcodes import opcodes from pypy.translator.avm2.types_ import Avm2TypeSystem class GenAVM2(GenOO): - opcodes = opcodes - Function = Function - Database = LowLevelDatabase + opcodes = opcodes + Function = TamarinFunction + Database = LowLevelDatabase TypeSystem = Avm2TypeSystem ConstantGenerator = Avm2ConstGenerator - ClassConst = Avm2ClassConst + ClassConst = Avm2ClassConst InstanceConst = Avm2InstanceConst - RecordConst = Avm2RecordConst + RecordConst = Avm2RecordConst + ListConst = Avm2ArrayListConst + ArrayConst = Avm2ArrayListConst def __init__(self, tmpdir, translator, entrypoint, config=None, exctrans=False): GenOO.__init__(self, tmpdir, translator, entrypoint, config, exctrans) @@ -27,7 +29,7 @@ self.ilasm = None def create_assembler(self): - return Avm2ilasm(self) + return PyPyAvm2ilasm(self) def generate_source(self): if self.ilasm is None: Modified: pypy/branch/avm/pypy/translator/avm2/intrinsic/intrgen.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/intrinsic/intrgen.py (original) +++ pypy/branch/avm/pypy/translator/avm2/intrinsic/intrgen.py Wed Jan 13 19:26:30 2010 @@ -63,8 +63,8 @@ else: FullName = ShortName - if line == "extends": - BaseType = get_ootype(line[2], Resolved) + if "extends" in line: + BaseType = line[2] elif line.startswith(("public function ", "public static function ")): @@ -116,7 +116,7 @@ StaticFields.append((line[3], line[5])) else: StaticFields.append(tuple(line[3].split(":"))) - + desc = ClassDesc() desc.FullName = FullName desc.BaseType = BaseType Modified: pypy/branch/avm/pypy/translator/avm2/metavm.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/metavm.py (original) +++ pypy/branch/avm/pypy/translator/avm2/metavm.py Wed Jan 13 19:26:30 2010 @@ -5,7 +5,8 @@ from pypy.translator.oosupport.metavm import _Call as _OOCall # from pypy.translator.cli.comparer import EqualityComparer from pypy.translator.avm2.runtime import _static_meth, NativeInstance -from pypy.translator.avm2 import types_ as types, constants as c +from pypy.translator.avm2 import types_ as types +from mech.fusion.avm2 import constants STRING_HELPER_CLASS = '[pypylib]pypy.runtime.String' @@ -30,7 +31,6 @@ for func_arg in args[1:]: # push parameters self._load_arg_or_null(generator, func_arg) cts = generator.cts - #signature = '%s %s::%s(%s)' % (ret_type, funcdesc._cls._name, funcdesc._name, arg_list) generator.emit() def _load_arg_or_null(self, generator, arg): @@ -55,7 +55,6 @@ if native: self._load_arg_or_null(generator, arg) else: - print arg generator.load(arg) if isinstance(this.concretetype, ootype.Array) and this.concretetype.ITEM is not ootype.Void: @@ -87,11 +86,11 @@ class _OOString(MicroInstruction): def render(self, generator, op): if op.args[1] == -1: - generator.emit('findpropstrict', types._str_qname) + generator.emit('findpropstrict', types.str_qname) generator.load(op.args[0]) generator.emit('callproperty', 1) else: - generator.emit('findpropstrict', c.QName("parseInt")) + generator.emit('findpropstrict', constants.QName("parseInt")) generator.load(op.args[0]) generator.load(op.args[1]) generator.emit('callproperty', 2) @@ -175,7 +174,7 @@ generator.load(op.args[0]) generator.load(op.args[1]) rettype = generator.cts.lltype_to_cts(op.result.concretetype) - generator.ilasm.opcode('ldelem', rettype) + generator.ilasm.opcode('getproperty', rettype) class _SetArrayElem(MicroInstruction): def render(self, generator, op): @@ -199,8 +198,6 @@ else: cliClass = c_type.value fullname = cliClass._INSTANCE._name - generator.ilasm.opcode('ldtoken', fullname) - generator.ilasm.call('class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)') class _EventHandler(MicroInstruction): def render(self, generator, op): Modified: pypy/branch/avm/pypy/translator/avm2/opcodes.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/opcodes.py (original) +++ pypy/branch/avm/pypy/translator/avm2/opcodes.py Wed Jan 13 19:26:30 2010 @@ -35,15 +35,15 @@ 'oodowncast': [DownCast], # 'clibox': [Box], # 'cliunbox': [Unbox], - 'cli_newarray': [NewArray], - 'cli_getelem': [GetArrayElem], - 'cli_setelem': [SetArrayElem], - 'cli_typeof': [TypeOf], - 'cli_arraylength': 'ldlen', - 'cli_eventhandler': [EventHandler], - 'cli_getstaticfield': [GetStaticField], - 'cli_setstaticfield': [SetStaticField], - 'cli_fieldinfo_for_const': [FieldInfoForConst], + # 'cli_newarray': [NewArray], + # 'cli_getelem': [GetArrayElem], + # 'cli_setelem': [SetArrayElem], + # 'cli_typeof': [TypeOf], + # 'cli_arraylength': 'ldlen', + # 'cli_eventhandler': [EventHandler], + # 'cli_getstaticfield': [GetStaticField], + # 'cli_setstaticfield': [SetStaticField], + # 'cli_fieldinfo_for_const': [FieldInfoForConst], 'oois': 'ceq', # 'oononnull': [PushAllArgs, 'ldnull', 'ceq']+Not, 'classof': [PushAllArgs, 'callvirt instance class [mscorlib]System.Type object::GetType()'], Modified: pypy/branch/avm/pypy/translator/avm2/query.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/query.py (original) +++ pypy/branch/avm/pypy/translator/avm2/query.py Wed Jan 13 19:26:30 2010 @@ -2,18 +2,14 @@ import cPickle as pickle import os.path import py -from py.compat import subprocess +import subprocess from pypy.tool.udir import udir from pypy.rpython.ootypesystem import ootype +from pypy.translator import avm2 from pypy.translator.cli.support import log -Assemblies = set() Types = {} # TypeName -> ClassDesc Namespaces = set() -# mscorlib = 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' -# pypylib = 'pypylib, Version=0.0.0.0, Culture=neutral' -# pypylib2 = 'pypylib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' # this is for mono 1.9 - #_______________________________________________________________________________ # This is the public interface of query.py @@ -38,17 +34,15 @@ # clr.AddReference(pypylib) # load_assembly(pypylib) -def load_assembly(name): - if name in Assemblies: - return +def load_playerglobal(): _cache = get_cachedir() - outfile = _cache.join(name + '.pickle') + outfile = _cache.join('avm2_playerglobal.pickle') if outfile.check(): f = outfile.open('rb') types = pickle.load(f) f.close() else: - types = load_and_cache_assembly(name, outfile) + types = load_and_cache_playerglobal(outfile) for ttype in types: parts = ttype.split('.') @@ -57,7 +51,6 @@ for part in parts[1:-1]: ns = '%s.%s' % (ns, part) Namespaces.add(ns) - Assemblies.add(name) Types.update(types) @@ -66,10 +59,10 @@ _cache = py.path.local(pypy.__file__).new(basename='_cache').ensure(dir=1) return _cache -def load_and_cache_assembly(name, outfile): - tmpfile = udir.join(name) +def load_and_cache_playerglobal(outfile): mydict = {} - execfile(str(tmpfile), mydict) + pipe = subprocess.Popen([sys.executable, str(py.path.local(avm2.__file__).dirpath("intrinsic/intrgen.py"))], stdout=subprocess.PIPE) + exec pipe.stdout in mydict types = mydict['types'] f = outfile.open('wb') pickle.dump(types, f, pickle.HIGHEST_PROTOCOL) @@ -202,6 +195,7 @@ def _buildtree(self): assert self._name is None, '_buildtree can be called only on top-level Runtime, not on namespaces' from pypy.translator.cli.support import getattr_ex + load_playerglobal() for fullname in sorted(list(Namespaces)): if '.' in fullname: parent, name = fullname.rsplit('.', 1) @@ -210,9 +204,12 @@ else: setattr(self, fullname, NativeNamespace(fullname)) - for fullname in Types.keys(): - parent, name = fullname.rsplit('.', 1) - parent = getattr_ex(self, parent) + for fullname in Types.iterkeys(): + if '.' in fullname: + parent, name = fullname.rsplit('.', 1) + parent = getattr_ex(self, parent) + else: + parent = self setattr(parent, name, placeholder) self.Object # XXX hack Modified: pypy/branch/avm/pypy/translator/avm2/record.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/record.py (original) +++ pypy/branch/avm/pypy/translator/avm2/record.py Wed Jan 13 19:26:30 2010 @@ -1,6 +1,8 @@ from pypy.rpython.ootypesystem import ootype from pypy.translator.cli.node import Node -from pypy.translator.avm2 import constants as c, types_ as types, traits + +from mech.fusion.avm2 import constants as c, traits +from pypy.translator.avm2 import types_ as types class Record(Node): def __init__(self, db, record, name): @@ -44,7 +46,7 @@ if not f_name.startswith('item'): return # it's not a tuple - self.ilasm.begin_method('toString', [], types._str_qname) + self.ilasm.begin_method('toString', [], c.QName("String")) self.ilasm.push_const("(") for i in xrange(len(self.record._fields)): f_name = 'item%d' % i Modified: pypy/branch/avm/pypy/translator/avm2/runtime.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/runtime.py (original) +++ pypy/branch/avm/pypy/translator/avm2/runtime.py Wed Jan 13 19:26:30 2010 @@ -234,6 +234,21 @@ #assert ARGS == self._TYPE.ARGS return self +class _overloaded_static_meth(object): + def __init__(self, *overloadings, **attrs): + resolver = attrs.pop('resolver', OverloadingResolver) + assert not attrs + self._resolver = resolver(overloadings) + + def _set_attrs(self, cls, name): + for meth in self._resolver.overloadings: + meth._set_attrs(cls, name) + + def _get_desc(self, ARGS): + meth = self._resolver.resolve(ARGS) + assert isinstance(meth, _static_meth) + return meth._get_desc(ARGS) + class NativeInstance(ootype.Instance): def __init__(self, namespace, name, superclass, fields={}, methods={}, _is_root=False, _hints = {}): @@ -244,6 +259,8 @@ ootype.Instance.__init__(self, fullname, superclass, fields, methods, _is_root, _hints) + + ## RPython interface definition class NativeClass(object): @@ -539,14 +556,15 @@ return v_array # def typeof(Class_or_type): -# if isinstance(Class_or_type, ootype.StaticMethod): - # FUNCTYPE = Class_or_type - # Class = known_delegates[FUNCTYPE] - # else: - # assert isinstance(Class_or_type, CliClass) - # Class = Class_or_type - # TYPE = Class._INSTANCE - # return PythonNet.System.Type.GetType(TYPE._assembly_qualified_name) +# # if isinstance(Class_or_type, ootype.StaticMethod): +# # FUNCTYPE = Class_or_type +# # Class = known_delegates[FUNCTYPE] +# # else: +# # assert isinstance(Class_or_type, CliClass) +# # Class = Class_or_type +# # TYPE = Class._INSTANCE +# # return PythonNet.System.Type.GetType(TYPE._assembly_qualified_name) +# return None # def classof(cliClass_or_type): # if isinstance(cliClass_or_type, ootype.StaticMethod): @@ -569,7 +587,7 @@ # def compute_result_annotation(self, Class_s): # from pypy.translator.avm2.query import get_native_class # assert Class_s.is_constant() -# Type = get_native_class('Class') +# Type = playerglobal.Class # return SomeOOInstance(Type._INSTANCE) # def specialize_call(self, hop): @@ -618,7 +636,7 @@ def cast_record_to_object(record): T = ootype.typeOf(record) assert isinstance(T, ootype.Record) - return ootype._view(CLR.System.Object._INSTANCE, record) + return ootype._view(playerglobal.Object._INSTANCE, record) def cast_object_to_record(T, obj): assert isinstance(T, ootype.Record) @@ -635,7 +653,7 @@ T = s_value.ootype assert isinstance(T, ootype.Record) can_be_None = getattr(s_value, 'can_be_None', False) - return SomeOOInstance(CLR.System.Object._INSTANCE, can_be_None=can_be_None) + return SomeOOInstance(playerglobal.Object._INSTANCE, can_be_None=can_be_None) def specialize_call(self, hop): assert isinstance(hop.args_s[0], annmodel.SomeOOInstance) @@ -659,36 +677,36 @@ v_obj = hop.inputarg(hop.args_r[1], arg=1) return hop.genop('oodowncast', [v_obj], hop.r_result.lowleveltype) -class _fieldinfo(object): - def __init__(self, llvalue): - self._TYPE = CLR.System.Reflection.FieldInfo._INSTANCE - self.llvalue = llvalue +#class _fieldinfo(object): +# def __init__(self, llvalue): +# self._TYPE = CLR.System.Reflection.FieldInfo._INSTANCE +# self.llvalue = llvalue -def fieldinfo_for_const(const): - return _fieldinfo(const) +# def fieldinfo_for_const(const): +# return _fieldinfo(const) -class Entry(ExtRegistryEntry): - _about_ = fieldinfo_for_const +# class Entry(ExtRegistryEntry): +# _about_ = fieldinfo_for_const - def compute_result_annotation(self, s_const): - assert s_const.is_constant() - return SomeOOInstance(CLR.System.Reflection.FieldInfo._INSTANCE) +# def compute_result_annotation(self, s_const): +# assert s_const.is_constant() +# return SomeOOInstance(CLR.System.Reflection.FieldInfo._INSTANCE) - def specialize_call(self, hop): - llvalue = hop.args_v[0].value - c_llvalue = hop.inputconst(ootype.Void, llvalue) - return hop.genop('cli_fieldinfo_for_const', [c_llvalue], resulttype = hop.r_result.lowleveltype) +# def specialize_call(self, hop): +# llvalue = hop.args_v[0].value +# c_llvalue = hop.inputconst(ootype.Void, llvalue) +# return hop.genop('cli_fieldinfo_for_const', [c_llvalue], resulttype = hop.r_result.lowleveltype) -class Entry(ExtRegistryEntry): - _type_ = _fieldinfo +# class Entry(ExtRegistryEntry): +# _type_ = _fieldinfo - def compute_annotation(self): - return SomeOOInstance(CLR.System.Reflection.FieldInfo._INSTANCE) +# def compute_annotation(self): +# return SomeOOInstance(CLR.System.Reflection.FieldInfo._INSTANCE) -# from pypy.translator.cli.query import CliNamespace -# CLR = CliNamespace(None) -# CLR._buildtree() +from pypy.translator.avm2.query import NativeNamespace +playerglobal = NativeNamespace(None) +playerglobal._buildtree() # known_delegates = { # ootype.StaticMethod([ootype.Signed], ootype.Signed): CLR.pypy.test.DelegateType_int__int_1, Modified: pypy/branch/avm/pypy/translator/avm2/test/browsertest.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/test/browsertest.py (original) +++ pypy/branch/avm/pypy/translator/avm2/test/browsertest.py Wed Jan 13 19:26:30 2010 @@ -27,6 +27,8 @@ """ def parse_result(string): + if string.strip() == "": + return None if string == "true": return True elif string == "false": @@ -36,6 +38,8 @@ elif all(c in "123456789-" for c in string): return int(string) elif "," in string: + if string.startswith("(") and string.endswith(")"): + return tuple(parse_result(s) for s in string[1:-1].split(",") if parse_result(s) is not None) return [parse_result(s) for s in string.split(",")] else: try: Modified: pypy/branch/avm/pypy/translator/avm2/test/harness.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/test/harness.py (original) +++ pypy/branch/avm/pypy/translator/avm2/test/harness.py Wed Jan 13 19:26:30 2010 @@ -1,11 +1,15 @@ import py -from pypy.translator.avm1 import swf as s, tags as t, records as r from pypy.translator.avm2.test import browsertest as b -from pypy.translator.avm2 import avm2gen as g, constants as c, abc_ as a, traits +from pypy.translator.avm2 import avm2gen as g + +from mech.fusion.swf import swfdata as s, tags as t, records as r +from mech.fusion.avm2 import constants as c, abc_ as a, traits fl_dis_ns = c.Namespace("flash.display", c.TYPE_NAMESPACE_PackageNamespace) +_test_count = 0 + class TestHarness(object): def __init__(self, name, gen): self.testname = name @@ -15,8 +19,8 @@ self.swf.add_tag(t.DefineEditText(r.Rect(0, 600, 0, 400), "tt", "Testing %s." % (name,), color=r.RGBA(0xFFFFFF))) self.swf.add_tag(t.PlaceObject2(1, 2, name="edittext")) - self.abc = t.DoABC() - self.actions = g.Avm2ilasm(gen.db, self.abc) + self.abc = t.DoABC("PyPy Main") + self.actions = g.PyPyAvm2ilasm(gen.db, self.abc) self.swf.add_tag(self.abc) self.swf.add_tag(t.SymbolClass({0:"PyPyTest_EntryPoint"})) @@ -62,14 +66,7 @@ self.actions.store_var('text') def start_test(self): - self.maincls = self.actions.begin_class(c.QName("PyPyTest_EntryPoint"), c.packagedQName("flash.display", "Sprite"), [ - c.packagedQName("flash.display", "Sprite"), - c.packagedQName("flash.display", "DisplayObjectContainer"), - c.packagedQName("flash.display", "InteractiveObject"), - c.packagedQName("flash.display", "DisplayObject"), - c.packagedQName("flash.events", "EventDispatcher"), - c.QName("Object"), - ]) + self.maincls = self.actions.begin_class(c.QName("PyPyTest_EntryPoint"), c.packagedQName("flash.display", "Sprite")) self.maincls.make_iinit() self.get_edittext() self.maincls.add_instance_trait(traits.AbcSlotTrait(c.QName('edittext'), c.packagedQName("flash.text", "TextField"))) @@ -105,11 +102,24 @@ def do_test(self, debug=False): self.finish_test() if debug: - f = open("test.swf", "w") + import sys + frame = sys._getframe() + while frame: + name = frame.f_code.co_name + if name.startswith("test_"): + break + frame = frame.f_back + if frame is None: + global _test_count + _test_count += 1 + name = "unnamed_test_%s" % (_test_count,) + f = open("%s.swf" % (name,), "w") f.write(self.swf.serialize()) f.close() - f = open("test.abc", "w") + f = open("%s.abc" % (name,), "w") f.write(a.AbcFile.serialize(self.abc)) f.close() - #py.test.fail("debug") - return b.browsertest(self.testname, self.swf) + + asdf + + return b.browsertest(name, self.swf) Modified: pypy/branch/avm/pypy/translator/avm2/test/runtest.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/test/runtest.py (original) +++ pypy/branch/avm/pypy/translator/avm2/test/runtest.py Wed Jan 13 19:26:30 2010 @@ -51,8 +51,7 @@ if backendopt: check_virtual_methods(ootype.ROOT) backend_optimizations(t) - - print func.func_name + if func.func_name in ("fn_view", "ident_view"): t.view() Added: pypy/branch/avm/pypy/translator/avm2/test/test_script.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/test/test_script.py Wed Jan 13 19:26:30 2010 @@ -0,0 +1,67 @@ + +from mech.fusion.swf import swfdata as s, tags as t, records as r +from mech.fusion.avm2 import avm2gen as g, constants as c, abc_ as a, traits + +fl_dis_ns = c.Namespace("flash.display", c.TYPE_NAMESPACE_PackageNamespace) + +swf = s.SwfData() +swf.add_tag(t.FileAttributes()) +swf.add_tag(t.SetBackgroundColor(0x333333)) +swf.add_tag(t.DefineEditText(r.Rect(0, 600, 0, 400), "tt", + "Testing script order.", color=r.RGBA(0xFFFFFF))) +swf.add_tag(t.PlaceObject2(1, 2, name="edittext")) +abc = t.DoABC() +actions = g.Avm2ilasm(abc, False) + +swf.add_tag(abc) +swf.add_tag(t.SymbolClass({0:"ScriptTest_Script0"})) +swf.add_tag(t.ShowFrame()) +swf.add_tag(t.End()) + +actions.context.new_script() +cls = actions.begin_class(c.QName("ScriptTest_Script0"), c.packagedQName("flash.display", "Sprite"), [ + c.packagedQName("flash.display", "Sprite"), + c.packagedQName("flash.display", "DisplayObjectContainer"), + c.packagedQName("flash.display", "InteractiveObject"), + c.packagedQName("flash.display", "DisplayObject"), + c.packagedQName("flash.events", "EventDispatcher"), + c.QName("Object"), + ]) +cls.add_instance_trait(traits.AbcSlotTrait(c.QName('edittext'), c.packagedQName("flash.text", "TextField"))) +cls.make_cinit() +actions.call_function_constargs("trace", "ScriptTest_Script0 here") +actions.exit_context() +cls.make_iinit() +actions.call_function_constargs("trace", "ScriptTest_Script0 constructed") +actions.emit("findpropstrict", c.QName("ScriptTest_Script1")) +actions.emit("constructprop", c.QName("ScriptTest_Script1")) +actions.store_var("script1") +actions.exit_context() +actions.exit_context() +actions.exit_context() + + +actions.context.new_script() +cls = actions.begin_class(c.QName("ScriptTest_Script1")) +cls.make_cinit() +actions.call_function_constargs("trace", "ScriptTest_Script1 here") +actions.exit_context() +actions.exit_context() +actions.exit_context() + +actions.context.new_script() +cls = actions.begin_class(c.QName("ScriptTest_Script2")) +cls.make_cinit() +actions.call_function_constargs("trace", "ScriptTest_Script2 here") +actions.exit_context() +actions.exit_context() +actions.exit_context() + +f = open("test_script.abc", "w") +f.write(a.AbcFile.serialize(abc)) +f.close() + +f = open("test_script.swf", "w") +f.write(swf.serialize()) +f.close() + Modified: pypy/branch/avm/pypy/translator/avm2/types_.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/types_.py (original) +++ pypy/branch/avm/pypy/translator/avm2/types_.py Wed Jan 13 19:26:30 2010 @@ -7,15 +7,16 @@ from py.builtin import set from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype -from pypy.translator.avm2 import constants from pypy.translator.cli import oopspec from pypy.translator.cli.option import getoption +from mech.fusion.avm2 import constants + from pypy.tool.ansi_print import ansi_log -_vec_qname = constants.packagedQName("__AS3__.vec", "Vector") -_str_qname = constants.QName("String") -_arr_qname = constants.QName("Array") +vec_qname = constants.packagedQName("__AS3__.vec", "Vector") +str_qname = constants.QName("String") +arr_qname = constants.QName("Array") class Avm2Type(object): def typename(self): @@ -49,6 +50,7 @@ nstype = constants.TYPE_NAMESPACE_PackageNamespace def __init__(self, name, namespace=''): + print "Namedspaced Type", name if '::' in name and namespace == '': self.ns, self.name = name.rsplit('::', 1) else: @@ -71,7 +73,7 @@ self.itemtype = itemtype def multiname(self): - return constants.TypeName(_vec_qname, self.itemtype.multiname()) + return constants.TypeName(vec_qname, self.itemtype.multiname()) T = Avm2PrimitiveType N = Avm2NamespacedType From fijal at codespeak.net Thu Jan 14 10:20:06 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 14 Jan 2010 10:20:06 +0100 (CET) Subject: [pypy-svn] r70573 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100114092006.9BCD516803D@codespeak.net> Author: fijal Date: Thu Jan 14 10:20:06 2010 New Revision: 70573 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py Log: Port 70553 and 70554 from jit-profiling branch. Improves debugging of assembler backend (associates loops with addresses) Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Thu Jan 14 10:20:06 2010 @@ -171,6 +171,8 @@ self._patch_stackadjust(adr_stackadjust, frame_depth+param_depth) looptoken._x86_frame_depth = frame_depth looptoken._x86_param_depth = param_depth + debug_print("Loop #", looptoken.number, "has address", + looptoken._x86_loop_code, "to", self.mc.tell()) def assemble_bridge(self, faildescr, inputargs, operations): self.make_sure_mc_exists() @@ -193,6 +195,9 @@ faildescr._x86_bridge_param_depth = param_depth # patch the jump from original guard self.patch_jump(faildescr, adr_bridge) + debug_print("Bridge out of guard", + self.cpu.get_fail_descr_number(faildescr), + "has address", adr_bridge, "to", self.mc.tell()) def patch_jump(self, faildescr, adr_new_target): adr_jump_offset = faildescr._x86_adr_jump_offset From fijal at codespeak.net Thu Jan 14 12:42:12 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 14 Jan 2010 12:42:12 +0100 (CET) Subject: [pypy-svn] r70579 - pypy/trunk/pypy/translator/benchmark Message-ID: <20100114114212.5110816803B@codespeak.net> Author: fijal Date: Thu Jan 14 12:42:10 2010 New Revision: 70579 Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py Log: (pedronis, fijal) Kill a breaking print (bah) Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/trunk/pypy/translator/benchmark/benchmarks.py Thu Jan 14 12:42:10 2010 @@ -51,7 +51,6 @@ return True def run_cmd(cmd): - print "running", cmd pipe = os.popen(cmd + ' 2>&1') r = pipe.read() status = pipe.close() From pedronis at codespeak.net Thu Jan 14 15:24:27 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 14 Jan 2010 15:24:27 +0100 (CET) Subject: [pypy-svn] r70589 - in pypy/build: . pypy-c-testing tarball-testing Message-ID: <20100114142427.1F36D16803A@codespeak.net> Author: pedronis Date: Thu Jan 14 15:24:22 2010 New Revision: 70589 Removed: pypy/build/pypy-c-testing/ pypy/build/tarball-testing/ Modified: pypy/build/ (props changed) Log: removed things unused since a long time From pedronis at codespeak.net Thu Jan 14 15:34:43 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 14 Jan 2010 15:34:43 +0100 (CET) Subject: [pypy-svn] r70590 - pypy/build/benchmark Message-ID: <20100114143443.E56DD16803D@codespeak.net> Author: pedronis Date: Thu Jan 14 15:34:39 2010 New Revision: 70590 Removed: pypy/build/benchmark/ Log: (fijal, pedronis) remove unfinished stuff From fijal at codespeak.net Thu Jan 14 15:41:21 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 14 Jan 2010 15:41:21 +0100 (CET) Subject: [pypy-svn] r70591 - pypy/build/buildtool Message-ID: <20100114144121.00F2B16803D@codespeak.net> Author: fijal Date: Thu Jan 14 15:41:19 2010 New Revision: 70591 Removed: pypy/build/buildtool/ Log: Remove old and unused buildtool From arigo at codespeak.net Thu Jan 14 17:54:43 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 14 Jan 2010 17:54:43 +0100 (CET) Subject: [pypy-svn] r70592 - in pypy/branch/c-traceback/pypy: jit/metainterp rlib rpython rpython/lltypesystem translator/c/src translator/c/test translator/cli translator/jvm Message-ID: <20100114165443.C6440168038@codespeak.net> Author: arigo Date: Thu Jan 14 17:54:42 2010 New Revision: 70592 Modified: pypy/branch/c-traceback/pypy/jit/metainterp/history.py pypy/branch/c-traceback/pypy/jit/metainterp/warmspot.py pypy/branch/c-traceback/pypy/rlib/debug.py pypy/branch/c-traceback/pypy/rpython/llinterp.py pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py pypy/branch/c-traceback/pypy/translator/cli/opcodes.py pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py Log: Random progress, in-progress. Modified: pypy/branch/c-traceback/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/c-traceback/pypy/jit/metainterp/history.py (original) +++ pypy/branch/c-traceback/pypy/jit/metainterp/history.py Thu Jan 14 17:54:42 2010 @@ -926,10 +926,6 @@ loops.append(loop) display_loops(loops, errmsg, extraloops) - -class CrashInJIT(Exception): - pass - # ---------------------------------------------------------------- class Options: Modified: pypy/branch/c-traceback/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/c-traceback/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/c-traceback/pypy/jit/metainterp/warmspot.py Thu Jan 14 17:54:42 2010 @@ -11,7 +11,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.rarithmetic import r_uint, intmask -from pypy.rlib.debug import debug_print +from pypy.rlib.debug import debug_print, fatalerror from pypy.rpython.lltypesystem.lloperation import llop from pypy.translator.simplify import get_funcobj, get_functype from pypy.translator.unsimplify import call_final_function @@ -344,9 +344,7 @@ if sys.stdout == sys.__stdout__: import pdb; pdb.post_mortem(sys.exc_info()[2]) raise - debug_print('~~~ Crash in JIT!') - debug_print('~~~ %s' % (e,)) - raise history.CrashInJIT("crash in JIT") + fatalerror('~~~ Crash in JIT! %s' % (e,), traceback=True) crash_in_jit._dont_inline_ = True if self.translator.rtyper.type_system.name == 'lltypesystem': Modified: pypy/branch/c-traceback/pypy/rlib/debug.py ============================================================================== --- pypy/branch/c-traceback/pypy/rlib/debug.py (original) +++ pypy/branch/c-traceback/pypy/rlib/debug.py Thu Jan 14 17:54:42 2010 @@ -19,6 +19,14 @@ hop.exception_cannot_occur() hop.genop('debug_assert', vlist) +def fatalerror(msg, traceback=False): + from pypy.rpython.lltypesystem import lltype + from pypy.rpython.lltypesystem.lloperation import llop + if traceback: + llop.debug_print_traceback(lltype.Void) + llop.debug_fatalerror(lltype.Void, msg) +fatalerror._dont_inline_ = True + class DebugLog(list): def debug_print(self, *args): Modified: pypy/branch/c-traceback/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/c-traceback/pypy/rpython/llinterp.py (original) +++ pypy/branch/c-traceback/pypy/rpython/llinterp.py Thu Jan 14 17:54:42 2010 @@ -543,6 +543,18 @@ def op_debug_llinterpcall(self, pythonfunction, *args_ll): return pythonfunction(*args_ll) + def op_debug_start_traceback(self, *args): + pass # xxx write debugging code here? + + def op_debug_record_traceback(self, *args): + pass # xxx write debugging code here? + + def op_debug_print_traceback(self, *args): + pass # xxx write debugging code here? + + def op_debug_catch_exception(self, *args): + pass # xxx write debugging code here? + def op_jit_marker(self, *args): pass Modified: pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py Thu Jan 14 17:54:42 2010 @@ -539,6 +539,7 @@ 'debug_start_traceback':LLOp(), 'debug_record_traceback':LLOp(), 'debug_catch_exception':LLOp(), + 'debug_print_traceback':LLOp(), # __________ instrumentation _________ 'instrument_count': LLOp(), Modified: pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h (original) +++ pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h Thu Jan 14 17:54:42 2010 @@ -7,6 +7,9 @@ #define OP_DEBUG_START_TRACEBACK() \ pypy_debug_traceback_count = PYPY_DEBUG_TRACEBACK_DEPTH +#define OP_DEBUG_PRINT_TRACEBACK() \ + pypy_debug_traceback_print() + #define PYPY_DEBUG_RECORD_TRACEBACK(funcname) \ if ((--pypy_debug_traceback_count) >= 0) { \ static struct pydtentry_s entry = { PYPY_FILE_NAME, funcname, __LINE__ }; \ @@ -25,6 +28,7 @@ extern int pypy_debug_traceback_count; extern struct pydtentry_s *pypy_debug_tracebacks[PYPY_DEBUG_TRACEBACK_DEPTH]; +void pypy_debug_traceback_print(void); void pypy_debug_catch_exception(void); Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Thu Jan 14 17:54:42 2010 @@ -10,6 +10,7 @@ from pypy.annotation.listdef import s_list_of_strings from pypy.tool.udir import udir from pypy.tool.autopath import pypydir +from pypy.conftest import option class StandaloneTests(object): @@ -23,6 +24,8 @@ cbuilder = CStandaloneBuilder(t, entry_point, t.config) cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() + if option.view: + t.view() return t, cbuilder @@ -410,6 +413,34 @@ assert lines2[-2] != lines[-2] # different line number assert lines2[-3] == lines[-3] # same line number + def test_fatal_error_finally(self): + def g(x): + if x == 1: + raise KeyError + def h(x): + try: + g(x) + finally: + print 'done.' + def entry_point(argv): + if len(argv) < 3: + h(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == 'done.' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: KeyError' + assert len(lines) >= 6 + l0, l1, l2, l3, l4 = lines[-6:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_h', l2) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_h', l3) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l4) + assert l2 != l3 # different line number + def test_assertion_error(self): def g(x): assert x != 1 Modified: pypy/branch/c-traceback/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/cli/opcodes.py (original) +++ pypy/branch/c-traceback/pypy/translator/cli/opcodes.py Thu Jan 14 17:54:42 2010 @@ -79,6 +79,7 @@ 'debug_assert': Ignore, 'debug_start_traceback': Ignore, 'debug_record_traceback': Ignore, + 'debug_print_traceback': Ignore, 'debug_catch_exception': Ignore, 'debug_print': [DebugPrint], 'debug_start': [PushAllArgs, 'call void [pypylib]pypy.runtime.DebugPrint::DEBUG_START(string)'], Modified: pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py (original) +++ pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py Thu Jan 14 17:54:42 2010 @@ -103,6 +103,7 @@ 'debug_assert': [], # TODO: implement? 'debug_start_traceback': Ignore, 'debug_record_traceback': Ignore, + 'debug_print_traceback': Ignore, 'debug_catch_exception': Ignore, # __________ numeric operations __________ From cfbolz at codespeak.net Thu Jan 14 19:44:49 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 14 Jan 2010 19:44:49 +0100 (CET) Subject: [pypy-svn] r70595 - in pypy/trunk/pypy: interpreter module/pypyjit/test Message-ID: <20100114184449.B3E3916803B@codespeak.net> Author: cfbolz Date: Thu Jan 14 19:44:48 2010 New Revision: 70595 Modified: pypy/trunk/pypy/interpreter/argument.py pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: Don't JIT argument parsing when the callsite has a * or ** arg, because this can produce arbitrarily many paths. Will make the test more precise tomorrow. Modified: pypy/trunk/pypy/interpreter/argument.py ============================================================================== --- pypy/trunk/pypy/interpreter/argument.py (original) +++ pypy/trunk/pypy/interpreter/argument.py Thu Jan 14 19:44:48 2010 @@ -4,7 +4,7 @@ from pypy.interpreter.error import OperationError from pypy.rlib.debug import make_sure_not_resized -from pypy.rlib.jit import purefunction, unroll_safe +from pypy.rlib import jit class Signature(object): @@ -17,7 +17,7 @@ self.varargname = varargname self.kwargname = kwargname - @purefunction + @jit.purefunction def find_argname(self, name): try: return self.argnames.index(name) @@ -101,6 +101,11 @@ make_sure_not_resized(self.arguments_w) if w_stararg is not None or w_starstararg is not None: self._combine_wrapped(w_stararg, w_starstararg) + # if we have a call where * or ** args are used at the callsite + # we shouldn't let the JIT see the argument matching + self._dont_jit = True + else: + self._dont_jit = False def __repr__(self): """ NOT_RPYTHON """ @@ -188,13 +193,28 @@ ### Parsing for function calls ### - @unroll_safe # XXX not true always, but for now def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=[], blindargs=0): """Parse args and kwargs according to the signature of a code object, or raise an ArgErr in case of failure. Return the number of arguments filled in. """ + if jit.we_are_jitted() and self._dont_jit: + return self._match_signature_jit_opaque(w_firstarg, scope_w, + signature, defaults_w, + blindargs) + return self._really_match_signature(w_firstarg, scope_w, signature, + defaults_w, blindargs) + + @jit.dont_look_inside + def _match_signature_jit_opaque(self, w_firstarg, scope_w, signature, + defaults_w, blindargs): + return self._really_match_signature(w_firstarg, scope_w, signature, + defaults_w, blindargs) + + @jit.unroll_safe + def _really_match_signature(self, w_firstarg, scope_w, signature, defaults_w=[], + blindargs=0): # # args_w = list of the normal actual parameters, wrapped # kwds_w = real dictionary {'keyword': wrapped parameter} Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Thu Jan 14 19:44:48 2010 @@ -89,8 +89,12 @@ print >> f, source # some support code... print >> f, py.code.Source(""" - import sys, pypyjit - pypyjit.set_param(threshold=3) + import sys + try: # make the file runnable by CPython + import pypyjit + pypyjit.set_param(threshold=3) + except ImportError: + pass def check(args, expected): print >> sys.stderr, 'trying:', args @@ -309,6 +313,28 @@ assert len(ops[0].get_opnames("guard")) <= 14 assert len(ops[1].get_opnames("guard")) <= 3 + def test_kwargs(self): + self.run_source(''' + d = {} + + def g(**args): + return len(args) + + def main(x): + s = 0 + d = {} + for i in range(x): + s += g(**d) + d[str(i)] = i + if i % 100 == 99: + d = {} + return s + ''', 100000, ([100], 4950), + ([1000], 49500), + ([10000], 495000), + ([100000], 4950000)) + assert len(self.loops) < 10 + def test_virtual_instance(self): self.run_source(''' class A(object): From fijal at codespeak.net Fri Jan 15 14:51:10 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 14:51:10 +0100 (CET) Subject: [pypy-svn] r70606 - pypy/benchmarks/unladen-swallow Message-ID: <20100115135110.3EEBD168042@codespeak.net> Author: fijal Date: Fri Jan 15 14:09:05 2010 New Revision: 70606 Modified: pypy/benchmarks/unladen-swallow/perf.py Log: Enable a possibility to disable google charts from being used. Modified: pypy/benchmarks/unladen-swallow/perf.py ============================================================================== --- pypy/benchmarks/unladen-swallow/perf.py (original) +++ pypy/benchmarks/unladen-swallow/perf.py Fri Jan 15 14:09:05 2010 @@ -358,14 +358,18 @@ self.delta_std = delta_std self.timeline_link = timeline_link + def get_timeline(self): + if self.timeline_link is None: + return "" + return "Timeline: %(timeline_link)s" + def string_representation(self): return (("Min: %(min_base)f -> %(min_changed)f:" + " %(delta_min)s\n" + "Avg: %(avg_base)f -> %(avg_changed)f:" + " %(delta_avg)s\n" + self.t_msg + "Stddev: %(std_base).5f -> %(std_changed).5f:" + - " %(delta_std)s\n" + - "Timeline: %(timeline_link)s") + " %(delta_std)s\n" + self.get_timeline()) % self.__dict__) class MemoryUsageResult(object): @@ -375,10 +379,14 @@ self.delta_max = delta_max self.chart_link = chart_link + def get_usage_over_time(self): + if self.chart_link is None: + return "" + return "Usage over time: %(chart_link)s" + def string_representation(self): return (("Mem max: %(max_base).3f -> %(max_changed).3f:" + - " %(delta_max)s\n" + - "Usage over time: %(chart_link)s") + " %(delta_max)s\n" + self.get_usage_over_time()) % self.__dict__) def CompareMemoryUsage(base_usage, changed_usage, options): @@ -440,6 +448,8 @@ Returns: Google Chart API URL as a string. """ + if options.no_charts: + return None # We use these to scale the graph. min_data = min(min(base_data), min(changed_data)) - chart_margin max_data = max(max(base_data), max(changed_data)) + chart_margin @@ -1529,6 +1539,9 @@ help=("Comma-separated list of environment variable names" " that are inherited from the parent environment" " when running benchmarking subprocesses.")) + parser.add_option("--no_charts", default=False, action="store_true", + help=("Don't use google charts for displaying the" + " graph outcome")) options, args = parser.parse_args(argv) if len(args) != 2: From pedronis at codespeak.net Fri Jan 15 15:04:05 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 15 Jan 2010 15:04:05 +0100 (CET) Subject: [pypy-svn] r70607 - in pypy/benchmarks: . unladen-swallow unladen_swallow Message-ID: <20100115140405.40FF7168042@codespeak.net> Author: pedronis Date: Fri Jan 15 15:04:04 2010 New Revision: 70607 Added: pypy/benchmarks/unladen_swallow/ (props changed) - copied from r70606, pypy/benchmarks/unladen-swallow/ Removed: pypy/benchmarks/unladen-swallow/ Modified: pypy/benchmarks/us-import.sh Log: rename unladen-swallow -> unladen_swallow for importing reasons Modified: pypy/benchmarks/us-import.sh ============================================================================== --- pypy/benchmarks/us-import.sh (original) +++ pypy/benchmarks/us-import.sh Fri Jan 15 15:04:04 2010 @@ -1,17 +1,17 @@ USSVN="http://unladen-swallow.googlecode.com/svn" -find unladen-swallow -iname ".svn" -prune -a -iname ".svn" -false -o -type f|rm -rf +find unladen_swallow -iname ".svn" -prune -a -iname ".svn" -false -o -type f|rm -rf -svn export --force --depth files $USSVN/tests unladen-swallow +svn export --force --depth files $USSVN/tests unladen_swallow -svn export --force $USSVN/tests/performance unladen-swallow/performance +svn export --force $USSVN/tests/performance unladen_swallow/performance DIRECT_LIBS="google_appengine lockfile html5lib" for lib in $DIRECT_LIBS; do - svn export --force $USSVN/tests/lib/$lib unladen-swallow/lib/$lib + svn export --force $USSVN/tests/lib/$lib unladen_swallow/lib/$lib done EXTERNAL_LIBS="spitfire|django|rietveld|spambayes" -svn pget svn:externals http://unladen-swallow.googlecode.com/svn/tests|grep -E $EXTERNAL_LIBS|sed -e s[lib/[unladen-swallow/lib/[ |xargs -I{} -n1 sh -c "svn export --force {}" \ No newline at end of file +svn pget svn:externals $USSVN/tests|grep -E $EXTERNAL_LIBS|sed -e s[lib/[unladen_swallow/lib/[ |xargs -I{} -n1 sh -c "svn export --force {}" \ No newline at end of file From fijal at codespeak.net Fri Jan 15 15:11:08 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 15:11:08 +0100 (CET) Subject: [pypy-svn] r70608 - pypy/benchmarks/unladen_swallow Message-ID: <20100115141108.ADBA9168042@codespeak.net> Author: fijal Date: Fri Jan 15 15:11:07 2010 New Revision: 70608 Added: pypy/benchmarks/unladen_swallow/__init__.py (contents, props changed) Log: (pedronis, fijal) Add an __init__ Added: pypy/benchmarks/unladen_swallow/__init__.py ============================================================================== From fijal at codespeak.net Fri Jan 15 15:33:23 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 15:33:23 +0100 (CET) Subject: [pypy-svn] r70609 - pypy/benchmarks/unladen_swallow Message-ID: <20100115143323.A9E7A168047@codespeak.net> Author: fijal Date: Fri Jan 15 15:33:23 2010 New Revision: 70609 Modified: pypy/benchmarks/unladen_swallow/perf.py Log: Use __file__ instead of sys.argv[0], helps when it's imported Modified: pypy/benchmarks/unladen_swallow/perf.py ============================================================================== --- pypy/benchmarks/unladen_swallow/perf.py (original) +++ pypy/benchmarks/unladen_swallow/perf.py Fri Jan 15 15:33:23 2010 @@ -555,7 +555,7 @@ def Relative(path): - return os.path.join(os.path.dirname(sys.argv[0]), path) + return os.path.join(os.path.dirname(__file__), path) def LogCall(command): From fijal at codespeak.net Fri Jan 15 15:53:02 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 15:53:02 +0100 (CET) Subject: [pypy-svn] r70611 - pypy/benchmarks/unladen_swallow Message-ID: <20100115145302.A8CF8168042@codespeak.net> Author: fijal Date: Fri Jan 15 15:53:01 2010 New Revision: 70611 Modified: pypy/benchmarks/unladen_swallow/perf.py Log: Consistently return an object from different ways of running benchmarks Modified: pypy/benchmarks/unladen_swallow/perf.py ============================================================================== --- pypy/benchmarks/unladen_swallow/perf.py (original) +++ pypy/benchmarks/unladen_swallow/perf.py Fri Jan 15 15:53:01 2010 @@ -372,6 +372,13 @@ " %(delta_std)s\n" + self.get_timeline()) % self.__dict__) +class ResultError(object): + def __init__(self, e): + self.msg = str(e) + + def string_representation(self): + return self.msg + class MemoryUsageResult(object): def __init__(self, max_base, max_changed, delta_max, chart_link): self.max_base = max_base @@ -389,6 +396,16 @@ " %(delta_max)s\n" + self.get_usage_over_time()) % self.__dict__) +class SimpleComparisonResult(object): + def __init__(self, base_time, changed_time, time_delta): + self.base_time = base_time + self.changed_time = changed_time + self.time_delta = time_delta + + def string_representation(self): + return ("%(base_time)f -> %(changed_time)f: %(time_delta)s" + % self.__dict__) + def CompareMemoryUsage(base_usage, changed_usage, options): """Like CompareMultipleRuns, but for memory usage.""" max_base, max_changed = max(base_usage), max(changed_usage) @@ -422,8 +439,8 @@ *args, **kwargs: will be passed through to benchmark_function. Returns: - String summarizing the differences between the two benchmark runs, - suitable for human consumption. + An object representing differences between the two benchmark runs. + Comes with string_representation method. """ try: changed_data = benchmark_function(changed_python, options, @@ -431,7 +448,7 @@ base_data = benchmark_function(base_python, options, *args, **kwargs) except subprocess.CalledProcessError, e: - return str(e) + return ResultError(e) return CompareBenchmarkData(base_data, changed_data, options) @@ -646,8 +663,7 @@ # below. base_time, changed_time = base_times[0], changed_times[0] time_delta = TimeDelta(base_time, changed_time) - return ("%(base_time)f -> %(changed_time)f: %(time_delta)s" - % locals()) + return SimpleComparisonResult(base_time, changed_time, time_delta) # Create a chart showing iteration times over time. We round the times so # as not to exceed the GET limit for Google's chart server. From fijal at codespeak.net Fri Jan 15 15:57:10 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 15:57:10 +0100 (CET) Subject: [pypy-svn] r70612 - in pypy/benchmarks: . test Message-ID: <20100115145710.9151F168042@codespeak.net> Author: fijal Date: Fri Jan 15 15:57:10 2010 New Revision: 70612 Added: pypy/benchmarks/runner.py (contents, props changed) pypy/benchmarks/test/ pypy/benchmarks/test/__init__.py (contents, props changed) pypy/benchmarks/test/test_runner.py (contents, props changed) Log: Add a runner that can give you a json file. Added: pypy/benchmarks/runner.py ============================================================================== --- (empty file) +++ pypy/benchmarks/runner.py Fri Jan 15 15:57:10 2010 @@ -0,0 +1,21 @@ +#!/usr/bin/env python +""" Usage: runner.py +""" + +import py +import json +import sys +from unladen_swallow.perf import main + +def run_and_store(benchmarks, result_filename, pypy_c_path): + results = main(['-f', '-b', ','.join(benchmarks), + '--no_charts', sys.executable, pypy_c_path]) + py.path.local(result_filename).write( + json.dumps([(name, result.__class__.__name__, result.__dict__) + for name, result in results]) + ) + +if __name__ == '__main__': + BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', + 'rietveld', 'nbody', 'html5lib', 'ai'] + run_and_store(BENCHMARK_SET, sys.argv[1], sys.argv[2]) Added: pypy/benchmarks/test/__init__.py ============================================================================== Added: pypy/benchmarks/test/test_runner.py ============================================================================== --- (empty file) +++ pypy/benchmarks/test/test_runner.py Fri Jan 15 15:57:10 2010 @@ -0,0 +1,14 @@ + +import py +import json +import sys +from runner import run_and_store + +def test_run_and_store(): + tmpdir = py.test.ensuretemp('bench_runner') + resfile = tmpdir.join('results') + run_and_store(['startup'], resfile, sys.executable) + assert resfile.check() + data = json.loads(resfile.read()) + assert [i[0] for i in data] == ['normal_startup', 'startup_nosite'] + assert [i[1] for i in data] == ['ComparisonResult', 'ComparisonResult'] From fijal at codespeak.net Fri Jan 15 15:59:11 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 15:59:11 +0100 (CET) Subject: [pypy-svn] r70613 - pypy/build/bot2/pypybuildbot Message-ID: <20100115145911.87F4E168042@codespeak.net> Author: fijal Date: Fri Jan 15 15:59:10 2010 New Revision: 70613 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Describe a bit better what the run does Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 15:59:10 2010 @@ -60,7 +60,7 @@ kw['timeout'] = 3600 ShellCmd.__init__(self, workdir, *a, **kw) self.command = (self.command + translationArgs + - [self.translationTarget] + targetArgs) + [self.translationTarget] + targetArgs) # ________________________________________________________________ @@ -161,7 +161,7 @@ self.addStep(Translate(['-Ojit'], [])) self.addStep(ShellCmd( - descritpion="run richards & upload results", + descritpion="run benchmarks", command=["python", "pypy/translator/benchmark/jitbench.py", "pypy/translator/goal/pypy-c"])) From fijal at codespeak.net Fri Jan 15 16:24:43 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 16:24:43 +0100 (CET) Subject: [pypy-svn] r70614 - pypy/build/bot2/pypybuildbot Message-ID: <20100115152443.9A627168042@codespeak.net> Author: fijal Date: Fri Jan 15 16:24:42 2010 New Revision: 70614 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: (pedronis, fijal) Add a new way of running benchmarks to the bot Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 16:24:42 2010 @@ -1,6 +1,7 @@ from buildbot.process import factory -from buildbot.steps import source, shell +from buildbot.steps import source, shell, transfer from buildbot.status.builder import SUCCESS +from buildbot.process.properties import WithProperties import os class ShellCmd(shell.ShellCommand): @@ -158,15 +159,24 @@ factory.BuildFactory.__init__(self) setup_steps(platform, self) - + self.addStep(ShellCmd(description="checkout benchmarks", + command=['svn', 'co', 'http://codespeak.net/svn/pypy/benchmarks', + 'benchmarks'], + workdir='')) self.addStep(Translate(['-Ojit'], [])) self.addStep(ShellCmd( + description="run more benchmarks", + commad=["python", "runner.py", 'result.json', + '../build/pypy/translator/goal/pypy-c'], + workdir='benchmarks')) + self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", + masterdest=WithProperties("~/bench_results/%(revision)s.json") + workdir="")) + self.addStep(ShellCmd( descritpion="run benchmarks", command=["python", "pypy/translator/benchmark/jitbench.py", "pypy/translator/goal/pypy-c"])) - - # xxx keep style class TranslatedScratchbox(factory.BuildFactory): def __init__(self, *a, **kw): From fijal at codespeak.net Fri Jan 15 16:26:16 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 16:26:16 +0100 (CET) Subject: [pypy-svn] r70615 - pypy/build/bot2/pypybuildbot Message-ID: <20100115152616.EDBC9168042@codespeak.net> Author: fijal Date: Fri Jan 15 16:26:16 2010 New Revision: 70615 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: missing coma Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 16:26:16 2010 @@ -170,7 +170,7 @@ '../build/pypy/translator/goal/pypy-c'], workdir='benchmarks')) self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", - masterdest=WithProperties("~/bench_results/%(revision)s.json") + masterdest=WithProperties("~/bench_results/%(revision)s.json"), workdir="")) self.addStep(ShellCmd( descritpion="run benchmarks", From cfbolz at codespeak.net Fri Jan 15 16:52:25 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 15 Jan 2010 16:52:25 +0100 (CET) Subject: [pypy-svn] r70616 - pypy/trunk/pypy/module/pypyjit/test Message-ID: <20100115155225.BF65E168042@codespeak.net> Author: cfbolz Date: Fri Jan 15 16:52:24 2010 New Revision: 70616 Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: missed a guard Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Fri Jan 15 16:52:24 2010 @@ -443,6 +443,7 @@ bytecode, = self.get_by_bytecode("BINARY_SUBSCR") assert bytecode.get_opnames("guard") == [ "guard_isnull", # check that the range list is not forced + "guard_false", # check that the index is >= 0 "guard_false", # check that the index is lower than the current length ] bytecode, _ = self.get_by_bytecode("FOR_ITER") # second bytecode is the end of the loop From cfbolz at codespeak.net Fri Jan 15 17:56:58 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 15 Jan 2010 17:56:58 +0100 (CET) Subject: [pypy-svn] r70617 - pypy/trunk/pypy/module/pypyjit/test Message-ID: <20100115165658.5CE74168042@codespeak.net> Author: cfbolz Date: Fri Jan 15 17:56:57 2010 New Revision: 70617 Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: - fix two failing tests here (by relaxing the restrictions) - make the test about kwargs more precise. There is still too much code generated, but at least we nicely only get two loops (as opposed to hundreds, like before) Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Fri Jan 15 17:56:57 2010 @@ -333,7 +333,10 @@ ([1000], 49500), ([10000], 495000), ([100000], 4950000)) - assert len(self.loops) < 10 + assert len(self.loops) == 2 + op, = self.get_by_bytecode("CALL_FUNCTION_KW") + # XXX a bit too many guards, but better than before + assert len(op.get_opnames("guard")) <= 10 def test_virtual_instance(self): self.run_source(''' @@ -420,14 +423,14 @@ i += 1 l.append(i) return i, len(l) - ''', 37, + ''', 39, ([20], (20, 18)), ([31], (31, 29))) bytecode, = self.get_by_bytecode("CALL_METHOD") assert len(bytecode.get_opnames("new_with_vtable")) == 1 # the forcing of the int assert len(bytecode.get_opnames("call")) == 1 # the call to append - assert len(bytecode.get_opnames("guard")) == 1 # guard_no_exception after the call + assert len(bytecode.get_opnames("guard")) == 2 # guard for profiling disabledness + guard_no_exception after the call def test_range_iter(self): self.run_source(''' @@ -448,6 +451,7 @@ ] bytecode, _ = self.get_by_bytecode("FOR_ITER") # second bytecode is the end of the loop assert bytecode.get_opnames("guard") == [ + "guard_class", # check the class of the iterator "guard_nonnull", # check that the iterator is not finished "guard_isnull", # check that the range list is not forced "guard_false", # check that the index is lower than the current length From fijal at codespeak.net Fri Jan 15 18:11:09 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 18:11:09 +0100 (CET) Subject: [pypy-svn] r70618 - pypy/build/bot2/pypybuildbot Message-ID: <20100115171109.CE979168074@codespeak.net> Author: fijal Date: Fri Jan 15 18:11:07 2010 New Revision: 70618 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: A typo :-( Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 18:11:07 2010 @@ -166,7 +166,7 @@ self.addStep(Translate(['-Ojit'], [])) self.addStep(ShellCmd( description="run more benchmarks", - commad=["python", "runner.py", 'result.json', + command=["python", "runner.py", 'result.json', '../build/pypy/translator/goal/pypy-c'], workdir='benchmarks')) self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", From fijal at codespeak.net Fri Jan 15 18:16:28 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 18:16:28 +0100 (CET) Subject: [pypy-svn] r70619 - pypy/trunk/pypy/translator/platform Message-ID: <20100115171628.693CF168074@codespeak.net> Author: fijal Date: Fri Jan 15 18:16:27 2010 New Revision: 70619 Modified: pypy/trunk/pypy/translator/platform/linux.py Log: issue489 fixed Modified: pypy/trunk/pypy/translator/platform/linux.py ============================================================================== --- pypy/trunk/pypy/translator/platform/linux.py (original) +++ pypy/trunk/pypy/translator/platform/linux.py Fri Jan 15 18:16:27 2010 @@ -11,7 +11,7 @@ link_flags = ['-pthread', '-lrt'] cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] standalone_only = [] - shared_only = [] + shared_only = ['-fPIC'] so_ext = 'so' so_prefixes = ['lib', ''] From cfbolz at codespeak.net Fri Jan 15 18:37:25 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 15 Jan 2010 18:37:25 +0100 (CET) Subject: [pypy-svn] r70620 - in pypy/trunk/pypy: interpreter module/pypyjit/test Message-ID: <20100115173725.2A27416802C@codespeak.net> Author: cfbolz Date: Fri Jan 15 18:37:24 2010 New Revision: 70620 Modified: pypy/trunk/pypy/interpreter/function.py pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: make static and class method objects immutable Modified: pypy/trunk/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/pypy/interpreter/function.py (original) +++ pypy/trunk/pypy/interpreter/function.py Fri Jan 15 18:37:24 2010 @@ -553,6 +553,7 @@ class StaticMethod(Wrappable): """The staticmethod objects.""" + _immutable_ = True def __init__(self, w_function): self.w_function = w_function @@ -566,6 +567,7 @@ class ClassMethod(Wrappable): """The classmethod objects.""" + _immutable_ = True def __init__(self, w_function): self.w_function = w_function Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Fri Jan 15 18:37:24 2010 @@ -290,6 +290,35 @@ "guard_nonnull_class"] assert not ops[1] # second LOAD_ATTR folded away + def test_static_classmethod_call(self): + self.run_source(''' + class A(object): + @classmethod + def f(cls, i): + return i + (cls is A) + 1 + + @staticmethod + def g(i): + return i - 1 + + def main(n): + i = 0 + a = A() + while i < n: + x = a.f(i) + i = a.g(x) + return i + ''', 105, + ([20], 20), + ([31], 31)) + ops = self.get_by_bytecode("LOOKUP_METHOD") + assert len(ops) == 2 + assert not ops[0].get_opnames("call") + assert not ops[0].get_opnames("new") + assert len(ops[0].get_opnames("guard")) <= 7 + assert len(ops[0].get_opnames("getfield")) < 6 + assert not ops[1] # second LOOKUP_METHOD folded away + def test_default_and_kw(self): self.run_source(''' def f(i, j=1): From fijal at codespeak.net Fri Jan 15 19:21:25 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 19:21:25 +0100 (CET) Subject: [pypy-svn] r70621 - pypy/build/bot2/pypybuildbot Message-ID: <20100115182125.2ADE416802D@codespeak.net> Author: fijal Date: Fri Jan 15 19:21:24 2010 New Revision: 70621 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: it seems we have too old version of buildbot to support workdir="" Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 19:21:24 2010 @@ -162,7 +162,7 @@ self.addStep(ShellCmd(description="checkout benchmarks", command=['svn', 'co', 'http://codespeak.net/svn/pypy/benchmarks', 'benchmarks'], - workdir='')) + workdir='./')) self.addStep(Translate(['-Ojit'], [])) self.addStep(ShellCmd( description="run more benchmarks", @@ -171,7 +171,7 @@ workdir='benchmarks')) self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties("~/bench_results/%(revision)s.json"), - workdir="")) + workdir="./")) self.addStep(ShellCmd( descritpion="run benchmarks", command=["python", "pypy/translator/benchmark/jitbench.py", From fijal at codespeak.net Fri Jan 15 20:44:57 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 20:44:57 +0100 (CET) Subject: [pypy-svn] r70622 - pypy/build/bot2/pypybuildbot Message-ID: <20100115194457.2F5A6168042@codespeak.net> Author: fijal Date: Fri Jan 15 20:44:56 2010 New Revision: 70622 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: * An attempt to fix directories * Temporarily copy file instead of translating, saves a bit of time Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 20:44:56 2010 @@ -60,8 +60,9 @@ kw['targetArgs'] = targetArgs kw['timeout'] = 3600 ShellCmd.__init__(self, workdir, *a, **kw) - self.command = (self.command + translationArgs + - [self.translationTarget] + targetArgs) + #self.command = (self.command + translationArgs + + # [self.translationTarget] + targetArgs) + self.command = ['cp', '/tmp/pypy-c', '.'] # ________________________________________________________________ @@ -162,7 +163,7 @@ self.addStep(ShellCmd(description="checkout benchmarks", command=['svn', 'co', 'http://codespeak.net/svn/pypy/benchmarks', 'benchmarks'], - workdir='./')) + workdir='../')) self.addStep(Translate(['-Ojit'], [])) self.addStep(ShellCmd( description="run more benchmarks", @@ -171,7 +172,7 @@ workdir='benchmarks')) self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties("~/bench_results/%(revision)s.json"), - workdir="./")) + workdir="../")) self.addStep(ShellCmd( descritpion="run benchmarks", command=["python", "pypy/translator/benchmark/jitbench.py", From fijal at codespeak.net Fri Jan 15 20:50:24 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 20:50:24 +0100 (CET) Subject: [pypy-svn] r70623 - pypy/build/bot2/pypybuildbot Message-ID: <20100115195024.9DD33168042@codespeak.net> Author: fijal Date: Fri Jan 15 20:50:23 2010 New Revision: 70623 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Another go at directories :-/ Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 20:50:23 2010 @@ -163,16 +163,16 @@ self.addStep(ShellCmd(description="checkout benchmarks", command=['svn', 'co', 'http://codespeak.net/svn/pypy/benchmarks', 'benchmarks'], - workdir='../')) + workdir='.')) self.addStep(Translate(['-Ojit'], [])) self.addStep(ShellCmd( description="run more benchmarks", command=["python", "runner.py", 'result.json', - '../build/pypy/translator/goal/pypy-c'], - workdir='benchmarks')) + './build/pypy/translator/goal/pypy-c'], + workdir='build/benchmarks')) self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties("~/bench_results/%(revision)s.json"), - workdir="../")) + workdir=".")) self.addStep(ShellCmd( descritpion="run benchmarks", command=["python", "pypy/translator/benchmark/jitbench.py", From fijal at codespeak.net Fri Jan 15 20:51:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 20:51:56 +0100 (CET) Subject: [pypy-svn] r70624 - pypy/build/bot2/pypybuildbot Message-ID: <20100115195156.C4A21168042@codespeak.net> Author: fijal Date: Fri Jan 15 20:51:56 2010 New Revision: 70624 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Yet-another-go at paths. It's extremely confusing Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 20:51:56 2010 @@ -169,7 +169,7 @@ description="run more benchmarks", command=["python", "runner.py", 'result.json', './build/pypy/translator/goal/pypy-c'], - workdir='build/benchmarks')) + workdir='./benchmarks')) self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties("~/bench_results/%(revision)s.json"), workdir=".")) From fijal at codespeak.net Fri Jan 15 21:01:51 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 21:01:51 +0100 (CET) Subject: [pypy-svn] r70625 - pypy/benchmarks Message-ID: <20100115200151.66A16318139@codespeak.net> Author: fijal Date: Fri Jan 15 21:01:50 2010 New Revision: 70625 Modified: pypy/benchmarks/runner.py Log: Scrap the need of pylib installed Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Fri Jan 15 21:01:50 2010 @@ -2,7 +2,7 @@ """ Usage: runner.py """ -import py +import os import json import sys from unladen_swallow.perf import main @@ -10,10 +10,10 @@ def run_and_store(benchmarks, result_filename, pypy_c_path): results = main(['-f', '-b', ','.join(benchmarks), '--no_charts', sys.executable, pypy_c_path]) - py.path.local(result_filename).write( - json.dumps([(name, result.__class__.__name__, result.__dict__) - for name, result in results]) - ) + f = open(str(result_filename), "w") + f.write(json.dumps([(name, result.__class__.__name__, result.__dict__) + for name, result in results])) + f.close() if __name__ == '__main__': BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', From fijal at codespeak.net Fri Jan 15 21:03:47 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 21:03:47 +0100 (CET) Subject: [pypy-svn] r70626 - pypy/build/bot2/pypybuildbot Message-ID: <20100115200347.D8FF616802C@codespeak.net> Author: fijal Date: Fri Jan 15 21:03:47 2010 New Revision: 70626 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: our pypy is somewhere else now Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 21:03:47 2010 @@ -168,7 +168,7 @@ self.addStep(ShellCmd( description="run more benchmarks", command=["python", "runner.py", 'result.json', - './build/pypy/translator/goal/pypy-c'], + '../build/pypy/translator/goal/pypy-c'], workdir='./benchmarks')) self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties("~/bench_results/%(revision)s.json"), From fijal at codespeak.net Fri Jan 15 21:06:29 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 21:06:29 +0100 (CET) Subject: [pypy-svn] r70627 - pypy/benchmarks Message-ID: <20100115200629.9201916802C@codespeak.net> Author: fijal Date: Fri Jan 15 21:06:27 2010 New Revision: 70627 Modified: pypy/benchmarks/runner.py Log: Remove nbody for now, it uses itertools.combinations Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Fri Jan 15 21:06:27 2010 @@ -17,5 +17,5 @@ if __name__ == '__main__': BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', - 'rietveld', 'nbody', 'html5lib', 'ai'] + 'rietveld', 'html5lib', 'ai'] run_and_store(BENCHMARK_SET, sys.argv[1], sys.argv[2]) From fijal at codespeak.net Fri Jan 15 21:11:33 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 21:11:33 +0100 (CET) Subject: [pypy-svn] r70628 - pypy/benchmarks Message-ID: <20100115201133.B416116802D@codespeak.net> Author: fijal Date: Fri Jan 15 21:11:30 2010 New Revision: 70628 Modified: pypy/benchmarks/runner.py Log: inherit PATH from the parent env Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Fri Jan 15 21:11:30 2010 @@ -9,6 +9,7 @@ def run_and_store(benchmarks, result_filename, pypy_c_path): results = main(['-f', '-b', ','.join(benchmarks), + '--inherit_env=PATH', '--no_charts', sys.executable, pypy_c_path]) f = open(str(result_filename), "w") f.write(json.dumps([(name, result.__class__.__name__, result.__dict__) From fijal at codespeak.net Fri Jan 15 21:12:05 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 21:12:05 +0100 (CET) Subject: [pypy-svn] r70629 - pypy/build/bot2/pypybuildbot Message-ID: <20100115201205.B036316802D@codespeak.net> Author: fijal Date: Fri Jan 15 21:12:04 2010 New Revision: 70629 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: halt when benchmarks failed Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 21:12:04 2010 @@ -169,7 +169,8 @@ description="run more benchmarks", command=["python", "runner.py", 'result.json', '../build/pypy/translator/goal/pypy-c'], - workdir='./benchmarks')) + workdir='./benchmarks', + haltOnFailure=True)) self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties("~/bench_results/%(revision)s.json"), workdir=".")) From fijal at codespeak.net Fri Jan 15 21:22:04 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 21:22:04 +0100 (CET) Subject: [pypy-svn] r70630 - pypy/build/bot2/pypybuildbot Message-ID: <20100115202204.3EA3A16802D@codespeak.net> Author: fijal Date: Fri Jan 15 21:22:03 2010 New Revision: 70630 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: (pedronis) Use an obscure hack to make expand work Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 21:22:03 2010 @@ -171,8 +171,10 @@ '../build/pypy/translator/goal/pypy-c'], workdir='./benchmarks', haltOnFailure=True)) + # a bit obscure hack to get both os.path.expand and a property + resfile = os.path.expand("~/bench_results/%(revision)s.json") self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", - masterdest=WithProperties("~/bench_results/%(revision)s.json"), + masterdest=WithProperties(resfile), workdir=".")) self.addStep(ShellCmd( descritpion="run benchmarks", From fijal at codespeak.net Fri Jan 15 21:22:42 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 21:22:42 +0100 (CET) Subject: [pypy-svn] r70631 - pypy/build/bot2/pypybuildbot Message-ID: <20100115202242.11FF116802D@codespeak.net> Author: fijal Date: Fri Jan 15 21:22:40 2010 New Revision: 70631 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: oops, wrong function name Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 21:22:40 2010 @@ -172,7 +172,7 @@ workdir='./benchmarks', haltOnFailure=True)) # a bit obscure hack to get both os.path.expand and a property - resfile = os.path.expand("~/bench_results/%(revision)s.json") + resfile = os.path.expanduser("~/bench_results/%(revision)s.json") self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties(resfile), workdir=".")) From fijal at codespeak.net Fri Jan 15 21:28:19 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 21:28:19 +0100 (CET) Subject: [pypy-svn] r70632 - pypy/build/bot2/pypybuildbot Message-ID: <20100115202819.93F0616802D@codespeak.net> Author: fijal Date: Fri Jan 15 21:28:18 2010 New Revision: 70632 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: fix the revision name Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 21:28:18 2010 @@ -172,7 +172,7 @@ workdir='./benchmarks', haltOnFailure=True)) # a bit obscure hack to get both os.path.expand and a property - resfile = os.path.expanduser("~/bench_results/%(revision)s.json") + resfile = os.path.expanduser("~/bench_results/%(got_revision)s.json") self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties(resfile), workdir=".")) From fijal at codespeak.net Fri Jan 15 21:37:55 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 15 Jan 2010 21:37:55 +0100 (CET) Subject: [pypy-svn] r70633 - pypy/build/bot2/pypybuildbot Message-ID: <20100115203755.24D5A16802D@codespeak.net> Author: fijal Date: Fri Jan 15 21:37:54 2010 New Revision: 70633 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Disable the hack, but leave it since it might be useful Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Jan 15 21:37:54 2010 @@ -60,9 +60,9 @@ kw['targetArgs'] = targetArgs kw['timeout'] = 3600 ShellCmd.__init__(self, workdir, *a, **kw) - #self.command = (self.command + translationArgs + - # [self.translationTarget] + targetArgs) - self.command = ['cp', '/tmp/pypy-c', '.'] + self.command = (self.command + translationArgs + + [self.translationTarget] + targetArgs) + #self.command = ['cp', '/tmp/pypy-c', '.'] # ________________________________________________________________ From pedronis at codespeak.net Fri Jan 15 21:42:51 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 15 Jan 2010 21:42:51 +0100 (CET) Subject: [pypy-svn] r70634 - pypy/build/bot2/codespeak-html Message-ID: <20100115204251.BA14216802D@codespeak.net> Author: pedronis Date: Fri Jan 15 21:42:51 2010 New Revision: 70634 Added: pypy/build/bot2/codespeak-html/bench_results (contents, props changed) Log: Check in a link pointing to a place where results are stored Added: pypy/build/bot2/codespeak-html/bench_results ============================================================================== --- (empty file) +++ pypy/build/bot2/codespeak-html/bench_results Fri Jan 15 21:42:51 2010 @@ -0,0 +1 @@ +link ../../bench_results/ \ No newline at end of file From fijal at codespeak.net Sat Jan 16 22:28:34 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 16 Jan 2010 22:28:34 +0100 (CET) Subject: [pypy-svn] r70639 - in pypy/benchmarks: . test Message-ID: <20100116212834.B076A168026@codespeak.net> Author: fijal Date: Sat Jan 16 22:28:33 2010 New Revision: 70639 Modified: pypy/benchmarks/runner.py pypy/benchmarks/test/test_runner.py Log: Store a bit more info in json, including a rev number Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Sat Jan 16 22:28:33 2010 @@ -7,16 +7,20 @@ import sys from unladen_swallow.perf import main -def run_and_store(benchmarks, result_filename, pypy_c_path): +def run_and_store(benchmarks, result_filename, pypy_c_path, revision=0): results = main(['-f', '-b', ','.join(benchmarks), '--inherit_env=PATH', '--no_charts', sys.executable, pypy_c_path]) f = open(str(result_filename), "w") - f.write(json.dumps([(name, result.__class__.__name__, result.__dict__) - for name, result in results])) + res = [(name, result.__class__.__name__, result.__dict__) + for name, result in results] + f.write(json.dumps({ + 'revision' : revision, + 'results' : res, + })) f.close() if __name__ == '__main__': BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', 'rietveld', 'html5lib', 'ai'] - run_and_store(BENCHMARK_SET, sys.argv[1], sys.argv[2]) + run_and_store(BENCHMARK_SET, sys.argv[1], sys.argv[2], int(sys.argv[3])) Modified: pypy/benchmarks/test/test_runner.py ============================================================================== --- pypy/benchmarks/test/test_runner.py (original) +++ pypy/benchmarks/test/test_runner.py Sat Jan 16 22:28:33 2010 @@ -9,6 +9,6 @@ resfile = tmpdir.join('results') run_and_store(['startup'], resfile, sys.executable) assert resfile.check() - data = json.loads(resfile.read()) + data = json.loads(resfile.read())['results'] assert [i[0] for i in data] == ['normal_startup', 'startup_nosite'] assert [i[1] for i in data] == ['ComparisonResult', 'ComparisonResult'] From fijal at codespeak.net Sat Jan 16 22:30:21 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 16 Jan 2010 22:30:21 +0100 (CET) Subject: [pypy-svn] r70640 - pypy/benchmarks Message-ID: <20100116213021.49D0E168026@codespeak.net> Author: fijal Date: Sat Jan 16 22:30:20 2010 New Revision: 70640 Modified: pypy/benchmarks/runner.py Log: Improve comment Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Sat Jan 16 22:30:20 2010 @@ -1,5 +1,5 @@ #!/usr/bin/env python -""" Usage: runner.py +""" Usage: runner.py """ import os From fijal at codespeak.net Sat Jan 16 22:30:50 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 16 Jan 2010 22:30:50 +0100 (CET) Subject: [pypy-svn] r70641 - pypy/build/bot2/pypybuildbot Message-ID: <20100116213050.1C9E9168026@codespeak.net> Author: fijal Date: Sat Jan 16 22:30:49 2010 New Revision: 70641 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Add a revision number as argument to runner, turn on a cheat for testing Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Sat Jan 16 22:30:49 2010 @@ -60,9 +60,9 @@ kw['targetArgs'] = targetArgs kw['timeout'] = 3600 ShellCmd.__init__(self, workdir, *a, **kw) - self.command = (self.command + translationArgs + - [self.translationTarget] + targetArgs) - #self.command = ['cp', '/tmp/pypy-c', '.'] + #self.command = (self.command + translationArgs + + # [self.translationTarget] + targetArgs) + self.command = ['cp', '/tmp/pypy-c', '.'] # ________________________________________________________________ @@ -168,7 +168,8 @@ self.addStep(ShellCmd( description="run more benchmarks", command=["python", "runner.py", 'result.json', - '../build/pypy/translator/goal/pypy-c'], + '../build/pypy/translator/goal/pypy-c', + WithProperties('%(got_revision)s')], workdir='./benchmarks', haltOnFailure=True)) # a bit obscure hack to get both os.path.expand and a property From fijal at codespeak.net Sat Jan 16 22:34:43 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 16 Jan 2010 22:34:43 +0100 (CET) Subject: [pypy-svn] r70642 - pypy/build/bot2/pypybuildbot Message-ID: <20100116213443.17997168026@codespeak.net> Author: fijal Date: Sat Jan 16 22:34:42 2010 New Revision: 70642 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Turn off the hack Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Sat Jan 16 22:34:42 2010 @@ -60,9 +60,9 @@ kw['targetArgs'] = targetArgs kw['timeout'] = 3600 ShellCmd.__init__(self, workdir, *a, **kw) - #self.command = (self.command + translationArgs + - # [self.translationTarget] + targetArgs) - self.command = ['cp', '/tmp/pypy-c', '.'] + self.command = (self.command + translationArgs + + [self.translationTarget] + targetArgs) + #self.command = ['cp', '/tmp/pypy-c', '.'] # ________________________________________________________________ From fijal at codespeak.net Sun Jan 17 14:33:47 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 14:33:47 +0100 (CET) Subject: [pypy-svn] r70650 - pypy/build/bot2/codespeak-html/js Message-ID: <20100117133347.97AD3168007@codespeak.net> Author: fijal Date: Sun Jan 17 14:33:47 2010 New Revision: 70650 Added: pypy/build/bot2/codespeak-html/js/ Log: (pedronis, fijal) A directory for keeping JS data From fijal at codespeak.net Sun Jan 17 15:04:14 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 15:04:14 +0100 (CET) Subject: [pypy-svn] r70651 - pypy/build/bot2/codespeak-html/js Message-ID: <20100117140414.EA4A4168011@codespeak.net> Author: fijal Date: Sun Jan 17 15:04:14 2010 New Revision: 70651 Removed: pypy/build/bot2/codespeak-html/js/ Log: (pedronis, fijal) Remove the JS dir, will become a symlink From fijal at codespeak.net Sun Jan 17 15:06:09 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 15:06:09 +0100 (CET) Subject: [pypy-svn] r70652 - in pypy/build/bot2/jsplot: . css js test test/data Message-ID: <20100117140609.A7D46168011@codespeak.net> Author: fijal Date: Sun Jan 17 15:06:09 2010 New Revision: 70652 Added: pypy/build/bot2/jsplot/ pypy/build/bot2/jsplot/conftest.py (contents, props changed) pypy/build/bot2/jsplot/css/ pypy/build/bot2/jsplot/css/main.css pypy/build/bot2/jsplot/js/ pypy/build/bot2/jsplot/js/jquery.flot.js pypy/build/bot2/jsplot/js/jquery.min.js pypy/build/bot2/jsplot/js/plot.js pypy/build/bot2/jsplot/js/underscore-min.js pypy/build/bot2/jsplot/plot.html pypy/build/bot2/jsplot/test/ pypy/build/bot2/jsplot/test/__init__.py (contents, props changed) pypy/build/bot2/jsplot/test/data/ pypy/build/bot2/jsplot/test/data/70632.json pypy/build/bot2/jsplot/test/data/70634.json pypy/build/bot2/jsplot/test/data/70641.json pypy/build/bot2/jsplot/test/data/70643.json pypy/build/bot2/jsplot/test/data/dir pypy/build/bot2/jsplot/test/data/revnos.json pypy/build/bot2/jsplot/test/jstest_one_any.js Log: (pedronis, fijal) Import stuff from /user/fijal to bot2 Added: pypy/build/bot2/jsplot/conftest.py ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/conftest.py Sun Jan 17 15:06:09 2010 @@ -0,0 +1,7 @@ +import os + +class jstests_setup(object): + staticDirs = { + '/js': os.path.join(os.path.dirname(__file__), 'js') + } + jsRepos = ['/js'] Added: pypy/build/bot2/jsplot/css/main.css ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/css/main.css Sun Jan 17 15:06:09 2010 @@ -0,0 +1,5 @@ + +.plot { + width: 600px; + height: 300px; +} Added: pypy/build/bot2/jsplot/js/jquery.flot.js ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/js/jquery.flot.js Sun Jan 17 15:06:09 2010 @@ -0,0 +1,2119 @@ +/* Javascript plotting library for jQuery, v. 0.6. + * + * Released under the MIT license by IOLA, December 2007. + * + */ + +// first an inline dependency, jquery.colorhelpers.js, we inline it here +// for convenience + +/* Plugin for jQuery for working with colors. + * + * Version 1.0. + * + * Inspiration from jQuery color animation plugin by John Resig. + * + * Released under the MIT license by Ole Laursen, October 2009. + * + * Examples: + * + * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() + * var c = $.color.extract($("#mydiv"), 'background-color'); + * console.log(c.r, c.g, c.b, c.a); + * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" + * + * Note that .scale() and .add() work in-place instead of returning + * new objects. + */ +(function(){jQuery.color={};jQuery.color.make=function(E,D,B,C){var F={};F.r=E||0;F.g=D||0;F.b=B||0;F.a=C!=null?C:1;F.add=function(I,H){for(var G=0;G=1){return"rgb("+[F.r,F.g,F.b].join(",")+")"}else{return"rgba("+[F.r,F.g,F.b,F.a].join(",")+")"}};F.normalize=function(){function G(I,J,H){return JH?H:J)}F.r=G(0,parseInt(F.r),255);F.g=G(0,parseInt(F.g),255);F.b=G(0,parseInt(F.b),255);F.a=G(0,F.a,1);return F};F.clone=function(){return jQuery.color.make(F.r,F.b,F.g,F.a)};return F.normalize()};jQuery.color.extract=function(C,B){var D;do{D=C.css(B).toLowerCase();if(D!=""&&D!="transparent"){break}C=C.parent()}while(!jQuery.nodeName(C.get(0),"body"));if(D=="rgba(0, 0, 0, 0)"){D="transparent"}return jQuery.color.parse(D)};jQuery.color.parse=function(E){var D,B=jQuery.color.make;if(D=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(E)){return B(parseInt(D[1],10),parseInt(D[2],10),parseInt(D[3],10))}if(D=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(E)){return B(parseInt(D[1],10),parseInt(D[2],10),parseInt(D[3],10),parseFloat(D[4]))}if(D=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(E)){return B(parseFloat(D[1])*2.55,parseFloat(D[2])*2.55,parseFloat(D[3])*2.55)}if(D=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(E)){return B(parseFloat(D[1])*2.55,parseFloat(D[2])*2.55,parseFloat(D[3])*2.55,parseFloat(D[4]))}if(D=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(E)){return B(parseInt(D[1],16),parseInt(D[2],16),parseInt(D[3],16))}if(D=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(E)){return B(parseInt(D[1]+D[1],16),parseInt(D[2]+D[2],16),parseInt(D[3]+D[3],16))}var C=jQuery.trim(E).toLowerCase();if(C=="transparent"){return B(255,255,255,0)}else{D=A[C];return B(D[0],D[1],D[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(); + +// the actual Flot code +(function($) { + function Plot(placeholder, data_, options_, plugins) { + // data is on the form: + // [ series1, series2 ... ] + // where series is either just the data as [ [x1, y1], [x2, y2], ... ] + // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } + + var series = [], + options = { + // the color theme used for graphs + colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], + legend: { + show: true, + noColumns: 1, // number of colums in legend table + labelFormatter: null, // fn: string -> string + labelBoxBorderColor: "#ccc", // border color for the little label boxes + container: null, // container (as jQuery object) to put legend in, null means default on top of graph + position: "ne", // position of default legend container within plot + margin: 5, // distance from grid edge to default legend container within plot + backgroundColor: null, // null means auto-detect + backgroundOpacity: 0.85 // set to 0 to avoid background + }, + xaxis: { + mode: null, // null or "time" + transform: null, // null or f: number -> number to transform axis + inverseTransform: null, // if transform is set, this should be the inverse function + min: null, // min. value to show, null means set automatically + max: null, // max. value to show, null means set automatically + autoscaleMargin: null, // margin in % to add if auto-setting min/max + ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks + tickFormatter: null, // fn: number -> string + labelWidth: null, // size of tick labels in pixels + labelHeight: null, + + // mode specific options + tickDecimals: null, // no. of decimals, null means auto + tickSize: null, // number or [number, "unit"] + minTickSize: null, // number or [number, "unit"] + monthNames: null, // list of names of months + timeformat: null, // format string to use + twelveHourClock: false // 12 or 24 time in time mode + }, + yaxis: { + autoscaleMargin: 0.02 + }, + x2axis: { + autoscaleMargin: null + }, + y2axis: { + autoscaleMargin: 0.02 + }, + series: { + points: { + show: false, + radius: 3, + lineWidth: 2, // in pixels + fill: true, + fillColor: "#ffffff" + }, + lines: { + // we don't put in show: false so we can see + // whether lines were actively disabled + lineWidth: 2, // in pixels + fill: false, + fillColor: null, + steps: false + }, + bars: { + show: false, + lineWidth: 2, // in pixels + barWidth: 1, // in units of the x axis + fill: true, + fillColor: null, + align: "left", // or "center" + horizontal: false // when horizontal, left is now top + }, + shadowSize: 3 + }, + grid: { + show: true, + aboveData: false, + color: "#545454", // primary color used for outline and labels + backgroundColor: null, // null for transparent, else color + tickColor: "rgba(0,0,0,0.15)", // color used for the ticks + labelMargin: 5, // in pixels + borderWidth: 2, // in pixels + borderColor: null, // set if different from the grid color + markings: null, // array of ranges or fn: axes -> array of ranges + markingsColor: "#f4f4f4", + markingsLineWidth: 2, + // interactive stuff + clickable: false, + hoverable: false, + autoHighlight: true, // highlight in case mouse is near + mouseActiveRadius: 10 // how far the mouse can be away to activate an item + }, + hooks: {} + }, + canvas = null, // the canvas for the plot itself + overlay = null, // canvas for interactive stuff on top of plot + eventHolder = null, // jQuery object that events should be bound to + ctx = null, octx = null, + axes = { xaxis: {}, yaxis: {}, x2axis: {}, y2axis: {} }, + plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, + canvasWidth = 0, canvasHeight = 0, + plotWidth = 0, plotHeight = 0, + hooks = { + processOptions: [], + processRawData: [], + processDatapoints: [], + draw: [], + bindEvents: [], + drawOverlay: [] + }, + plot = this; + + // public functions + plot.setData = setData; + plot.setupGrid = setupGrid; + plot.draw = draw; + plot.getPlaceholder = function() { return placeholder; }; + plot.getCanvas = function() { return canvas; }; + plot.getPlotOffset = function() { return plotOffset; }; + plot.width = function () { return plotWidth; }; + plot.height = function () { return plotHeight; }; + plot.offset = function () { + var o = eventHolder.offset(); + o.left += plotOffset.left; + o.top += plotOffset.top; + return o; + }; + plot.getData = function() { return series; }; + plot.getAxes = function() { return axes; }; + plot.getOptions = function() { return options; }; + plot.highlight = highlight; + plot.unhighlight = unhighlight; + plot.triggerRedrawOverlay = triggerRedrawOverlay; + plot.pointOffset = function(point) { + return { left: parseInt(axisSpecToRealAxis(point, "xaxis").p2c(+point.x) + plotOffset.left), + top: parseInt(axisSpecToRealAxis(point, "yaxis").p2c(+point.y) + plotOffset.top) }; + }; + + + // public attributes + plot.hooks = hooks; + + // initialize + initPlugins(plot); + parseOptions(options_); + constructCanvas(); + setData(data_); + setupGrid(); + draw(); + bindEvents(); + + + function executeHooks(hook, args) { + args = [plot].concat(args); + for (var i = 0; i < hook.length; ++i) + hook[i].apply(this, args); + } + + function initPlugins() { + for (var i = 0; i < plugins.length; ++i) { + var p = plugins[i]; + p.init(plot); + if (p.options) + $.extend(true, options, p.options); + } + } + + function parseOptions(opts) { + $.extend(true, options, opts); + if (options.grid.borderColor == null) + options.grid.borderColor = options.grid.color; + // backwards compatibility, to be removed in future + if (options.xaxis.noTicks && options.xaxis.ticks == null) + options.xaxis.ticks = options.xaxis.noTicks; + if (options.yaxis.noTicks && options.yaxis.ticks == null) + options.yaxis.ticks = options.yaxis.noTicks; + if (options.grid.coloredAreas) + options.grid.markings = options.grid.coloredAreas; + if (options.grid.coloredAreasColor) + options.grid.markingsColor = options.grid.coloredAreasColor; + if (options.lines) + $.extend(true, options.series.lines, options.lines); + if (options.points) + $.extend(true, options.series.points, options.points); + if (options.bars) + $.extend(true, options.series.bars, options.bars); + if (options.shadowSize) + options.series.shadowSize = options.shadowSize; + + for (var n in hooks) + if (options.hooks[n] && options.hooks[n].length) + hooks[n] = hooks[n].concat(options.hooks[n]); + + executeHooks(hooks.processOptions, [options]); + } + + function setData(d) { + series = parseData(d); + fillInSeriesOptions(); + processData(); + } + + function parseData(d) { + var res = []; + for (var i = 0; i < d.length; ++i) { + var s = $.extend(true, {}, options.series); + + if (d[i].data) { + s.data = d[i].data; // move the data instead of deep-copy + delete d[i].data; + + $.extend(true, s, d[i]); + + d[i].data = s.data; + } + else + s.data = d[i]; + res.push(s); + } + + return res; + } + + function axisSpecToRealAxis(obj, attr) { + var a = obj[attr]; + if (!a || a == 1) + return axes[attr]; + if (typeof a == "number") + return axes[attr.charAt(0) + a + attr.slice(1)]; + return a; // assume it's OK + } + + function fillInSeriesOptions() { + var i; + + // collect what we already got of colors + var neededColors = series.length, + usedColors = [], + assignedColors = []; + for (i = 0; i < series.length; ++i) { + var sc = series[i].color; + if (sc != null) { + --neededColors; + if (typeof sc == "number") + assignedColors.push(sc); + else + usedColors.push($.color.parse(series[i].color)); + } + } + + // we might need to generate more colors if higher indices + // are assigned + for (i = 0; i < assignedColors.length; ++i) { + neededColors = Math.max(neededColors, assignedColors[i] + 1); + } + + // produce colors as needed + var colors = [], variation = 0; + i = 0; + while (colors.length < neededColors) { + var c; + if (options.colors.length == i) // check degenerate case + c = $.color.make(100, 100, 100); + else + c = $.color.parse(options.colors[i]); + + // vary color if needed + var sign = variation % 2 == 1 ? -1 : 1; + c.scale('rgb', 1 + sign * Math.ceil(variation / 2) * 0.2) + + // FIXME: if we're getting to close to something else, + // we should probably skip this one + colors.push(c); + + ++i; + if (i >= options.colors.length) { + i = 0; + ++variation; + } + } + + // fill in the options + var colori = 0, s; + for (i = 0; i < series.length; ++i) { + s = series[i]; + + // assign colors + if (s.color == null) { + s.color = colors[colori].toString(); + ++colori; + } + else if (typeof s.color == "number") + s.color = colors[s.color].toString(); + + // turn on lines automatically in case nothing is set + if (s.lines.show == null) { + var v, show = true; + for (v in s) + if (s[v].show) { + show = false; + break; + } + if (show) + s.lines.show = true; + } + + // setup axes + s.xaxis = axisSpecToRealAxis(s, "xaxis"); + s.yaxis = axisSpecToRealAxis(s, "yaxis"); + } + } + + function processData() { + var topSentry = Number.POSITIVE_INFINITY, + bottomSentry = Number.NEGATIVE_INFINITY, + i, j, k, m, length, + s, points, ps, x, y, axis, val, f, p; + + for (axis in axes) { + axes[axis].datamin = topSentry; + axes[axis].datamax = bottomSentry; + axes[axis].used = false; + } + + function updateAxis(axis, min, max) { + if (min < axis.datamin) + axis.datamin = min; + if (max > axis.datamax) + axis.datamax = max; + } + + for (i = 0; i < series.length; ++i) { + s = series[i]; + s.datapoints = { points: [] }; + + executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]); + } + + // first pass: clean and copy data + for (i = 0; i < series.length; ++i) { + s = series[i]; + + var data = s.data, format = s.datapoints.format; + + if (!format) { + format = []; + // find out how to copy + format.push({ x: true, number: true, required: true }); + format.push({ y: true, number: true, required: true }); + + if (s.bars.show) + format.push({ y: true, number: true, required: false, defaultValue: 0 }); + + s.datapoints.format = format; + } + + if (s.datapoints.pointsize != null) + continue; // already filled in + + if (s.datapoints.pointsize == null) + s.datapoints.pointsize = format.length; + + ps = s.datapoints.pointsize; + points = s.datapoints.points; + + insertSteps = s.lines.show && s.lines.steps; + s.xaxis.used = s.yaxis.used = true; + + for (j = k = 0; j < data.length; ++j, k += ps) { + p = data[j]; + + var nullify = p == null; + if (!nullify) { + for (m = 0; m < ps; ++m) { + val = p[m]; + f = format[m]; + + if (f) { + if (f.number && val != null) { + val = +val; // convert to number + if (isNaN(val)) + val = null; + } + + if (val == null) { + if (f.required) + nullify = true; + + if (f.defaultValue != null) + val = f.defaultValue; + } + } + + points[k + m] = val; + } + } + + if (nullify) { + for (m = 0; m < ps; ++m) { + val = points[k + m]; + if (val != null) { + f = format[m]; + // extract min/max info + if (f.x) + updateAxis(s.xaxis, val, val); + if (f.y) + updateAxis(s.yaxis, val, val); + } + points[k + m] = null; + } + } + else { + // a little bit of line specific stuff that + // perhaps shouldn't be here, but lacking + // better means... + if (insertSteps && k > 0 + && points[k - ps] != null + && points[k - ps] != points[k] + && points[k - ps + 1] != points[k + 1]) { + // copy the point to make room for a middle point + for (m = 0; m < ps; ++m) + points[k + ps + m] = points[k + m]; + + // middle point has same y + points[k + 1] = points[k - ps + 1]; + + // we've added a point, better reflect that + k += ps; + } + } + } + } + + // give the hooks a chance to run + for (i = 0; i < series.length; ++i) { + s = series[i]; + + executeHooks(hooks.processDatapoints, [ s, s.datapoints]); + } + + // second pass: find datamax/datamin for auto-scaling + for (i = 0; i < series.length; ++i) { + s = series[i]; + points = s.datapoints.points, + ps = s.datapoints.pointsize; + + var xmin = topSentry, ymin = topSentry, + xmax = bottomSentry, ymax = bottomSentry; + + for (j = 0; j < points.length; j += ps) { + if (points[j] == null) + continue; + + for (m = 0; m < ps; ++m) { + val = points[j + m]; + f = format[m]; + if (!f) + continue; + + if (f.x) { + if (val < xmin) + xmin = val; + if (val > xmax) + xmax = val; + } + if (f.y) { + if (val < ymin) + ymin = val; + if (val > ymax) + ymax = val; + } + } + } + + if (s.bars.show) { + // make sure we got room for the bar on the dancing floor + var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2; + if (s.bars.horizontal) { + ymin += delta; + ymax += delta + s.bars.barWidth; + } + else { + xmin += delta; + xmax += delta + s.bars.barWidth; + } + } + + updateAxis(s.xaxis, xmin, xmax); + updateAxis(s.yaxis, ymin, ymax); + } + + for (axis in axes) { + if (axes[axis].datamin == topSentry) + axes[axis].datamin = null; + if (axes[axis].datamax == bottomSentry) + axes[axis].datamax = null; + } + } + + function constructCanvas() { + function makeCanvas(width, height) { + var c = document.createElement('canvas'); + c.width = width; + c.height = height; + if ($.browser.msie) // excanvas hack + c = window.G_vmlCanvasManager.initElement(c); + return c; + } + + canvasWidth = placeholder.width(); + canvasHeight = placeholder.height(); + placeholder.html(""); // clear placeholder + if (placeholder.css("position") == 'static') + placeholder.css("position", "relative"); // for positioning labels and overlay + + if (canvasWidth <= 0 || canvasHeight <= 0) + throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight; + + if ($.browser.msie) // excanvas hack + window.G_vmlCanvasManager.init_(document); // make sure everything is setup + + // the canvas + canvas = $(makeCanvas(canvasWidth, canvasHeight)).appendTo(placeholder).get(0); + ctx = canvas.getContext("2d"); + + // overlay canvas for interactive features + overlay = $(makeCanvas(canvasWidth, canvasHeight)).css({ position: 'absolute', left: 0, top: 0 }).appendTo(placeholder).get(0); + octx = overlay.getContext("2d"); + octx.stroke(); + } + + function bindEvents() { + // we include the canvas in the event holder too, because IE 7 + // sometimes has trouble with the stacking order + eventHolder = $([overlay, canvas]); + + // bind events + if (options.grid.hoverable) + eventHolder.mousemove(onMouseMove); + + if (options.grid.clickable) + eventHolder.click(onClick); + + executeHooks(hooks.bindEvents, [eventHolder]); + } + + function setupGrid() { + function setTransformationHelpers(axis, o) { + function identity(x) { return x; } + + var s, m, t = o.transform || identity, + it = o.inverseTransform; + + // add transformation helpers + if (axis == axes.xaxis || axis == axes.x2axis) { + // precompute how much the axis is scaling a point + // in canvas space + s = axis.scale = plotWidth / (t(axis.max) - t(axis.min)); + m = t(axis.min); + + // data point to canvas coordinate + if (t == identity) // slight optimization + axis.p2c = function (p) { return (p - m) * s; }; + else + axis.p2c = function (p) { return (t(p) - m) * s; }; + // canvas coordinate to data point + if (!it) + axis.c2p = function (c) { return m + c / s; }; + else + axis.c2p = function (c) { return it(m + c / s); }; + } + else { + s = axis.scale = plotHeight / (t(axis.max) - t(axis.min)); + m = t(axis.max); + + if (t == identity) + axis.p2c = function (p) { return (m - p) * s; }; + else + axis.p2c = function (p) { return (m - t(p)) * s; }; + if (!it) + axis.c2p = function (c) { return m - c / s; }; + else + axis.c2p = function (c) { return it(m - c / s); }; + } + } + + function measureLabels(axis, axisOptions) { + var i, labels = [], l; + + axis.labelWidth = axisOptions.labelWidth; + axis.labelHeight = axisOptions.labelHeight; + + if (axis == axes.xaxis || axis == axes.x2axis) { + // to avoid measuring the widths of the labels, we + // construct fixed-size boxes and put the labels inside + // them, we don't need the exact figures and the + // fixed-size box content is easy to center + if (axis.labelWidth == null) + axis.labelWidth = canvasWidth / (axis.ticks.length > 0 ? axis.ticks.length : 1); + + // measure x label heights + if (axis.labelHeight == null) { + labels = []; + for (i = 0; i < axis.ticks.length; ++i) { + l = axis.ticks[i].label; + if (l) + labels.push('
' + l + '
'); + } + + if (labels.length > 0) { + var dummyDiv = $('
' + + labels.join("") + '
').appendTo(placeholder); + axis.labelHeight = dummyDiv.height(); + dummyDiv.remove(); + } + } + } + else if (axis.labelWidth == null || axis.labelHeight == null) { + // calculate y label dimensions + for (i = 0; i < axis.ticks.length; ++i) { + l = axis.ticks[i].label; + if (l) + labels.push('
' + l + '
'); + } + + if (labels.length > 0) { + var dummyDiv = $('
' + + labels.join("") + '
').appendTo(placeholder); + if (axis.labelWidth == null) + axis.labelWidth = dummyDiv.width(); + if (axis.labelHeight == null) + axis.labelHeight = dummyDiv.find("div").height(); + dummyDiv.remove(); + } + + } + + if (axis.labelWidth == null) + axis.labelWidth = 0; + if (axis.labelHeight == null) + axis.labelHeight = 0; + } + + function setGridSpacing() { + // get the most space needed around the grid for things + // that may stick out + var maxOutset = options.grid.borderWidth; + for (i = 0; i < series.length; ++i) + maxOutset = Math.max(maxOutset, 2 * (series[i].points.radius + series[i].points.lineWidth/2)); + + plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = maxOutset; + + var margin = options.grid.labelMargin + options.grid.borderWidth; + + if (axes.xaxis.labelHeight > 0) + plotOffset.bottom = Math.max(maxOutset, axes.xaxis.labelHeight + margin); + if (axes.yaxis.labelWidth > 0) + plotOffset.left = Math.max(maxOutset, axes.yaxis.labelWidth + margin); + if (axes.x2axis.labelHeight > 0) + plotOffset.top = Math.max(maxOutset, axes.x2axis.labelHeight + margin); + if (axes.y2axis.labelWidth > 0) + plotOffset.right = Math.max(maxOutset, axes.y2axis.labelWidth + margin); + + plotWidth = canvasWidth - plotOffset.left - plotOffset.right; + plotHeight = canvasHeight - plotOffset.bottom - plotOffset.top; + } + + var axis; + for (axis in axes) + setRange(axes[axis], options[axis]); + + if (options.grid.show) { + for (axis in axes) { + prepareTickGeneration(axes[axis], options[axis]); + setTicks(axes[axis], options[axis]); + measureLabels(axes[axis], options[axis]); + } + + setGridSpacing(); + } + else { + plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = 0; + plotWidth = canvasWidth; + plotHeight = canvasHeight; + } + + for (axis in axes) + setTransformationHelpers(axes[axis], options[axis]); + + if (options.grid.show) + insertLabels(); + + insertLegend(); + } + + function setRange(axis, axisOptions) { + var min = +(axisOptions.min != null ? axisOptions.min : axis.datamin), + max = +(axisOptions.max != null ? axisOptions.max : axis.datamax), + delta = max - min; + + if (delta == 0.0) { + // degenerate case + var widen = max == 0 ? 1 : 0.01; + + if (axisOptions.min == null) + min -= widen; + // alway widen max if we couldn't widen min to ensure we + // don't fall into min == max which doesn't work + if (axisOptions.max == null || axisOptions.min != null) + max += widen; + } + else { + // consider autoscaling + var margin = axisOptions.autoscaleMargin; + if (margin != null) { + if (axisOptions.min == null) { + min -= delta * margin; + // make sure we don't go below zero if all values + // are positive + if (min < 0 && axis.datamin != null && axis.datamin >= 0) + min = 0; + } + if (axisOptions.max == null) { + max += delta * margin; + if (max > 0 && axis.datamax != null && axis.datamax <= 0) + max = 0; + } + } + } + axis.min = min; + axis.max = max; + } + + function prepareTickGeneration(axis, axisOptions) { + // estimate number of ticks + var noTicks; + if (typeof axisOptions.ticks == "number" && axisOptions.ticks > 0) + noTicks = axisOptions.ticks; + else if (axis == axes.xaxis || axis == axes.x2axis) + // heuristic based on the model a*sqrt(x) fitted to + // some reasonable data points + noTicks = 0.3 * Math.sqrt(canvasWidth); + else + noTicks = 0.3 * Math.sqrt(canvasHeight); + + var delta = (axis.max - axis.min) / noTicks, + size, generator, unit, formatter, i, magn, norm; + + if (axisOptions.mode == "time") { + // pretty handling of time + + // map of app. size of time units in milliseconds + var timeUnitSize = { + "second": 1000, + "minute": 60 * 1000, + "hour": 60 * 60 * 1000, + "day": 24 * 60 * 60 * 1000, + "month": 30 * 24 * 60 * 60 * 1000, + "year": 365.2425 * 24 * 60 * 60 * 1000 + }; + + + // the allowed tick sizes, after 1 year we use + // an integer algorithm + var spec = [ + [1, "second"], [2, "second"], [5, "second"], [10, "second"], + [30, "second"], + [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], + [30, "minute"], + [1, "hour"], [2, "hour"], [4, "hour"], + [8, "hour"], [12, "hour"], + [1, "day"], [2, "day"], [3, "day"], + [0.25, "month"], [0.5, "month"], [1, "month"], + [2, "month"], [3, "month"], [6, "month"], + [1, "year"] + ]; + + var minSize = 0; + if (axisOptions.minTickSize != null) { + if (typeof axisOptions.tickSize == "number") + minSize = axisOptions.tickSize; + else + minSize = axisOptions.minTickSize[0] * timeUnitSize[axisOptions.minTickSize[1]]; + } + + for (i = 0; i < spec.length - 1; ++i) + if (delta < (spec[i][0] * timeUnitSize[spec[i][1]] + + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 + && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) + break; + size = spec[i][0]; + unit = spec[i][1]; + + // special-case the possibility of several years + if (unit == "year") { + magn = Math.pow(10, Math.floor(Math.log(delta / timeUnitSize.year) / Math.LN10)); + norm = (delta / timeUnitSize.year) / magn; + if (norm < 1.5) + size = 1; + else if (norm < 3) + size = 2; + else if (norm < 7.5) + size = 5; + else + size = 10; + + size *= magn; + } + + if (axisOptions.tickSize) { + size = axisOptions.tickSize[0]; + unit = axisOptions.tickSize[1]; + } + + generator = function(axis) { + var ticks = [], + tickSize = axis.tickSize[0], unit = axis.tickSize[1], + d = new Date(axis.min); + + var step = tickSize * timeUnitSize[unit]; + + if (unit == "second") + d.setUTCSeconds(floorInBase(d.getUTCSeconds(), tickSize)); + if (unit == "minute") + d.setUTCMinutes(floorInBase(d.getUTCMinutes(), tickSize)); + if (unit == "hour") + d.setUTCHours(floorInBase(d.getUTCHours(), tickSize)); + if (unit == "month") + d.setUTCMonth(floorInBase(d.getUTCMonth(), tickSize)); + if (unit == "year") + d.setUTCFullYear(floorInBase(d.getUTCFullYear(), tickSize)); + + // reset smaller components + d.setUTCMilliseconds(0); + if (step >= timeUnitSize.minute) + d.setUTCSeconds(0); + if (step >= timeUnitSize.hour) + d.setUTCMinutes(0); + if (step >= timeUnitSize.day) + d.setUTCHours(0); + if (step >= timeUnitSize.day * 4) + d.setUTCDate(1); + if (step >= timeUnitSize.year) + d.setUTCMonth(0); + + + var carry = 0, v = Number.NaN, prev; + do { + prev = v; + v = d.getTime(); + ticks.push({ v: v, label: axis.tickFormatter(v, axis) }); + if (unit == "month") { + if (tickSize < 1) { + // a bit complicated - we'll divide the month + // up but we need to take care of fractions + // so we don't end up in the middle of a day + d.setUTCDate(1); + var start = d.getTime(); + d.setUTCMonth(d.getUTCMonth() + 1); + var end = d.getTime(); + d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); + carry = d.getUTCHours(); + d.setUTCHours(0); + } + else + d.setUTCMonth(d.getUTCMonth() + tickSize); + } + else if (unit == "year") { + d.setUTCFullYear(d.getUTCFullYear() + tickSize); + } + else + d.setTime(v + step); + } while (v < axis.max && v != prev); + + return ticks; + }; + + formatter = function (v, axis) { + var d = new Date(v); + + // first check global format + if (axisOptions.timeformat != null) + return $.plot.formatDate(d, axisOptions.timeformat, axisOptions.monthNames); + + var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; + var span = axis.max - axis.min; + var suffix = (axisOptions.twelveHourClock) ? " %p" : ""; + + if (t < timeUnitSize.minute) + fmt = "%h:%M:%S" + suffix; + else if (t < timeUnitSize.day) { + if (span < 2 * timeUnitSize.day) + fmt = "%h:%M" + suffix; + else + fmt = "%b %d %h:%M" + suffix; + } + else if (t < timeUnitSize.month) + fmt = "%b %d"; + else if (t < timeUnitSize.year) { + if (span < timeUnitSize.year) + fmt = "%b"; + else + fmt = "%b %y"; + } + else + fmt = "%y"; + + return $.plot.formatDate(d, fmt, axisOptions.monthNames); + }; + } + else { + // pretty rounding of base-10 numbers + var maxDec = axisOptions.tickDecimals; + var dec = -Math.floor(Math.log(delta) / Math.LN10); + if (maxDec != null && dec > maxDec) + dec = maxDec; + + magn = Math.pow(10, -dec); + norm = delta / magn; // norm is between 1.0 and 10.0 + + if (norm < 1.5) + size = 1; + else if (norm < 3) { + size = 2; + // special case for 2.5, requires an extra decimal + if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { + size = 2.5; + ++dec; + } + } + else if (norm < 7.5) + size = 5; + else + size = 10; + + size *= magn; + + if (axisOptions.minTickSize != null && size < axisOptions.minTickSize) + size = axisOptions.minTickSize; + + if (axisOptions.tickSize != null) + size = axisOptions.tickSize; + + axis.tickDecimals = Math.max(0, (maxDec != null) ? maxDec : dec); + + generator = function (axis) { + var ticks = []; + + // spew out all possible ticks + var start = floorInBase(axis.min, axis.tickSize), + i = 0, v = Number.NaN, prev; + do { + prev = v; + v = start + i * axis.tickSize; + ticks.push({ v: v, label: axis.tickFormatter(v, axis) }); + ++i; + } while (v < axis.max && v != prev); + return ticks; + }; + + formatter = function (v, axis) { + return v.toFixed(axis.tickDecimals); + }; + } + + axis.tickSize = unit ? [size, unit] : size; + axis.tickGenerator = generator; + if ($.isFunction(axisOptions.tickFormatter)) + axis.tickFormatter = function (v, axis) { return "" + axisOptions.tickFormatter(v, axis); }; + else + axis.tickFormatter = formatter; + } + + function setTicks(axis, axisOptions) { + axis.ticks = []; + + if (!axis.used) + return; + + if (axisOptions.ticks == null) + axis.ticks = axis.tickGenerator(axis); + else if (typeof axisOptions.ticks == "number") { + if (axisOptions.ticks > 0) + axis.ticks = axis.tickGenerator(axis); + } + else if (axisOptions.ticks) { + var ticks = axisOptions.ticks; + + if ($.isFunction(ticks)) + // generate the ticks + ticks = ticks({ min: axis.min, max: axis.max }); + + // clean up the user-supplied ticks, copy them over + var i, v; + for (i = 0; i < ticks.length; ++i) { + var label = null; + var t = ticks[i]; + if (typeof t == "object") { + v = t[0]; + if (t.length > 1) + label = t[1]; + } + else + v = t; + if (label == null) + label = axis.tickFormatter(v, axis); + axis.ticks[i] = { v: v, label: label }; + } + } + + if (axisOptions.autoscaleMargin != null && axis.ticks.length > 0) { + // snap to ticks + if (axisOptions.min == null) + axis.min = Math.min(axis.min, axis.ticks[0].v); + if (axisOptions.max == null && axis.ticks.length > 1) + axis.max = Math.max(axis.max, axis.ticks[axis.ticks.length - 1].v); + } + } + + function draw() { + ctx.clearRect(0, 0, canvasWidth, canvasHeight); + + var grid = options.grid; + + if (grid.show && !grid.aboveData) + drawGrid(); + + for (var i = 0; i < series.length; ++i) + drawSeries(series[i]); + + executeHooks(hooks.draw, [ctx]); + + if (grid.show && grid.aboveData) + drawGrid(); + } + + function extractRange(ranges, coord) { + var firstAxis = coord + "axis", + secondaryAxis = coord + "2axis", + axis, from, to, reverse; + + if (ranges[firstAxis]) { + axis = axes[firstAxis]; + from = ranges[firstAxis].from; + to = ranges[firstAxis].to; + } + else if (ranges[secondaryAxis]) { + axis = axes[secondaryAxis]; + from = ranges[secondaryAxis].from; + to = ranges[secondaryAxis].to; + } + else { + // backwards-compat stuff - to be removed in future + axis = axes[firstAxis]; + from = ranges[coord + "1"]; + to = ranges[coord + "2"]; + } + + // auto-reverse as an added bonus + if (from != null && to != null && from > to) + return { from: to, to: from, axis: axis }; + + return { from: from, to: to, axis: axis }; + } + + function drawGrid() { + var i; + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + // draw background, if any + if (options.grid.backgroundColor) { + ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)"); + ctx.fillRect(0, 0, plotWidth, plotHeight); + } + + // draw markings + var markings = options.grid.markings; + if (markings) { + if ($.isFunction(markings)) + // xmin etc. are backwards-compatible, to be removed in future + markings = markings({ xmin: axes.xaxis.min, xmax: axes.xaxis.max, ymin: axes.yaxis.min, ymax: axes.yaxis.max, xaxis: axes.xaxis, yaxis: axes.yaxis, x2axis: axes.x2axis, y2axis: axes.y2axis }); + + for (i = 0; i < markings.length; ++i) { + var m = markings[i], + xrange = extractRange(m, "x"), + yrange = extractRange(m, "y"); + + // fill in missing + if (xrange.from == null) + xrange.from = xrange.axis.min; + if (xrange.to == null) + xrange.to = xrange.axis.max; + if (yrange.from == null) + yrange.from = yrange.axis.min; + if (yrange.to == null) + yrange.to = yrange.axis.max; + + // clip + if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || + yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) + continue; + + xrange.from = Math.max(xrange.from, xrange.axis.min); + xrange.to = Math.min(xrange.to, xrange.axis.max); + yrange.from = Math.max(yrange.from, yrange.axis.min); + yrange.to = Math.min(yrange.to, yrange.axis.max); + + if (xrange.from == xrange.to && yrange.from == yrange.to) + continue; + + // then draw + xrange.from = xrange.axis.p2c(xrange.from); + xrange.to = xrange.axis.p2c(xrange.to); + yrange.from = yrange.axis.p2c(yrange.from); + yrange.to = yrange.axis.p2c(yrange.to); + + if (xrange.from == xrange.to || yrange.from == yrange.to) { + // draw line + ctx.beginPath(); + ctx.strokeStyle = m.color || options.grid.markingsColor; + ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth; + //ctx.moveTo(Math.floor(xrange.from), yrange.from); + //ctx.lineTo(Math.floor(xrange.to), yrange.to); + ctx.moveTo(xrange.from, yrange.from); + ctx.lineTo(xrange.to, yrange.to); + ctx.stroke(); + } + else { + // fill area + ctx.fillStyle = m.color || options.grid.markingsColor; + ctx.fillRect(xrange.from, yrange.to, + xrange.to - xrange.from, + yrange.from - yrange.to); + } + } + } + + // draw the inner grid + ctx.lineWidth = 1; + ctx.strokeStyle = options.grid.tickColor; + ctx.beginPath(); + var v, axis = axes.xaxis; + for (i = 0; i < axis.ticks.length; ++i) { + v = axis.ticks[i].v; + if (v <= axis.min || v >= axes.xaxis.max) + continue; // skip those lying on the axes + + ctx.moveTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, 0); + ctx.lineTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, plotHeight); + } + + axis = axes.yaxis; + for (i = 0; i < axis.ticks.length; ++i) { + v = axis.ticks[i].v; + if (v <= axis.min || v >= axis.max) + continue; + + ctx.moveTo(0, Math.floor(axis.p2c(v)) + ctx.lineWidth/2); + ctx.lineTo(plotWidth, Math.floor(axis.p2c(v)) + ctx.lineWidth/2); + } + + axis = axes.x2axis; + for (i = 0; i < axis.ticks.length; ++i) { + v = axis.ticks[i].v; + if (v <= axis.min || v >= axis.max) + continue; + + ctx.moveTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, -5); + ctx.lineTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, 5); + } + + axis = axes.y2axis; + for (i = 0; i < axis.ticks.length; ++i) { + v = axis.ticks[i].v; + if (v <= axis.min || v >= axis.max) + continue; + + ctx.moveTo(plotWidth-5, Math.floor(axis.p2c(v)) + ctx.lineWidth/2); + ctx.lineTo(plotWidth+5, Math.floor(axis.p2c(v)) + ctx.lineWidth/2); + } + + ctx.stroke(); + + if (options.grid.borderWidth) { + // draw border + var bw = options.grid.borderWidth; + ctx.lineWidth = bw; + ctx.strokeStyle = options.grid.borderColor; + ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw); + } + + ctx.restore(); + } + + function insertLabels() { + placeholder.find(".tickLabels").remove(); + + var html = ['
']; + + function addLabels(axis, labelGenerator) { + for (var i = 0; i < axis.ticks.length; ++i) { + var tick = axis.ticks[i]; + if (!tick.label || tick.v < axis.min || tick.v > axis.max) + continue; + html.push(labelGenerator(tick, axis)); + } + } + + var margin = options.grid.labelMargin + options.grid.borderWidth; + + addLabels(axes.xaxis, function (tick, axis) { + return '
' + tick.label + "
"; + }); + + + addLabels(axes.yaxis, function (tick, axis) { + return '
' + tick.label + "
"; + }); + + addLabels(axes.x2axis, function (tick, axis) { + return '
' + tick.label + "
"; + }); + + addLabels(axes.y2axis, function (tick, axis) { + return '
' + tick.label + "
"; + }); + + html.push('
'); + + placeholder.append(html.join("")); + } + + function drawSeries(series) { + if (series.lines.show) + drawSeriesLines(series); + if (series.bars.show) + drawSeriesBars(series); + if (series.points.show) + drawSeriesPoints(series); + } + + function drawSeriesLines(series) { + function plotLine(datapoints, xoffset, yoffset, axisx, axisy) { + var points = datapoints.points, + ps = datapoints.pointsize, + prevx = null, prevy = null; + + ctx.beginPath(); + for (var i = ps; i < points.length; i += ps) { + var x1 = points[i - ps], y1 = points[i - ps + 1], + x2 = points[i], y2 = points[i + 1]; + + if (x1 == null || x2 == null) + continue; + + // clip with ymin + if (y1 <= y2 && y1 < axisy.min) { + if (y2 < axisy.min) + continue; // line segment is outside + // compute new intersection point + x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.min; + } + else if (y2 <= y1 && y2 < axisy.min) { + if (y1 < axisy.min) + continue; + x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.min; + } + + // clip with ymax + if (y1 >= y2 && y1 > axisy.max) { + if (y2 > axisy.max) + continue; + x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.max; + } + else if (y2 >= y1 && y2 > axisy.max) { + if (y1 > axisy.max) + continue; + x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.max; + } + + // clip with xmin + if (x1 <= x2 && x1 < axisx.min) { + if (x2 < axisx.min) + continue; + y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.min; + } + else if (x2 <= x1 && x2 < axisx.min) { + if (x1 < axisx.min) + continue; + y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.min; + } + + // clip with xmax + if (x1 >= x2 && x1 > axisx.max) { + if (x2 > axisx.max) + continue; + y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.max; + } + else if (x2 >= x1 && x2 > axisx.max) { + if (x1 > axisx.max) + continue; + y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.max; + } + + if (x1 != prevx || y1 != prevy) + ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); + + prevx = x2; + prevy = y2; + ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); + } + ctx.stroke(); + } + + function plotLineArea(datapoints, axisx, axisy) { + var points = datapoints.points, + ps = datapoints.pointsize, + bottom = Math.min(Math.max(0, axisy.min), axisy.max), + top, lastX = 0, areaOpen = false; + + for (var i = ps; i < points.length; i += ps) { + var x1 = points[i - ps], y1 = points[i - ps + 1], + x2 = points[i], y2 = points[i + 1]; + + if (areaOpen && x1 != null && x2 == null) { + // close area + ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom)); + ctx.fill(); + areaOpen = false; + continue; + } + + if (x1 == null || x2 == null) + continue; + + // clip x values + + // clip with xmin + if (x1 <= x2 && x1 < axisx.min) { + if (x2 < axisx.min) + continue; + y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.min; + } + else if (x2 <= x1 && x2 < axisx.min) { + if (x1 < axisx.min) + continue; + y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.min; + } + + // clip with xmax + if (x1 >= x2 && x1 > axisx.max) { + if (x2 > axisx.max) + continue; + y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.max; + } + else if (x2 >= x1 && x2 > axisx.max) { + if (x1 > axisx.max) + continue; + y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.max; + } + + if (!areaOpen) { + // open area + ctx.beginPath(); + ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); + areaOpen = true; + } + + // now first check the case where both is outside + if (y1 >= axisy.max && y2 >= axisy.max) { + ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); + lastX = x2; + continue; + } + else if (y1 <= axisy.min && y2 <= axisy.min) { + ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); + lastX = x2; + continue; + } + + // else it's a bit more complicated, there might + // be two rectangles and two triangles we need to fill + // in; to find these keep track of the current x values + var x1old = x1, x2old = x2; + + // and clip the y values, without shortcutting + + // clip with ymin + if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { + x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.min; + } + else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { + x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.min; + } + + // clip with ymax + if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { + x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.max; + } + else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { + x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.max; + } + + + // if the x value was changed we got a rectangle + // to fill + if (x1 != x1old) { + if (y1 <= axisy.min) + top = axisy.min; + else + top = axisy.max; + + ctx.lineTo(axisx.p2c(x1old), axisy.p2c(top)); + ctx.lineTo(axisx.p2c(x1), axisy.p2c(top)); + } + + // fill the triangles + ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); + + // fill the other rectangle if it's there + if (x2 != x2old) { + if (y2 <= axisy.min) + top = axisy.min; + else + top = axisy.max; + + ctx.lineTo(axisx.p2c(x2), axisy.p2c(top)); + ctx.lineTo(axisx.p2c(x2old), axisy.p2c(top)); + } + + lastX = Math.max(x2, x2old); + } + + if (areaOpen) { + ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom)); + ctx.fill(); + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + ctx.lineJoin = "round"; + + var lw = series.lines.lineWidth, + sw = series.shadowSize; + // FIXME: consider another form of shadow when filling is turned on + if (lw > 0 && sw > 0) { + // draw shadow as a thick and thin line with transparency + ctx.lineWidth = sw; + ctx.strokeStyle = "rgba(0,0,0,0.1)"; + // position shadow at angle from the mid of line + var angle = Math.PI/18; + plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis); + ctx.lineWidth = sw/2; + plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis); + } + + ctx.lineWidth = lw; + ctx.strokeStyle = series.color; + var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); + if (fillStyle) { + ctx.fillStyle = fillStyle; + plotLineArea(series.datapoints, series.xaxis, series.yaxis); + } + + if (lw > 0) + plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis); + ctx.restore(); + } + + function drawSeriesPoints(series) { + function plotPoints(datapoints, radius, fillStyle, offset, circumference, axisx, axisy) { + var points = datapoints.points, ps = datapoints.pointsize; + + for (var i = 0; i < points.length; i += ps) { + var x = points[i], y = points[i + 1]; + if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) + continue; + + ctx.beginPath(); + ctx.arc(axisx.p2c(x), axisy.p2c(y) + offset, radius, 0, circumference, false); + if (fillStyle) { + ctx.fillStyle = fillStyle; + ctx.fill(); + } + ctx.stroke(); + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + var lw = series.lines.lineWidth, + sw = series.shadowSize, + radius = series.points.radius; + if (lw > 0 && sw > 0) { + // draw shadow in two steps + var w = sw / 2; + ctx.lineWidth = w; + ctx.strokeStyle = "rgba(0,0,0,0.1)"; + plotPoints(series.datapoints, radius, null, w + w/2, Math.PI, + series.xaxis, series.yaxis); + + ctx.strokeStyle = "rgba(0,0,0,0.2)"; + plotPoints(series.datapoints, radius, null, w/2, Math.PI, + series.xaxis, series.yaxis); + } + + ctx.lineWidth = lw; + ctx.strokeStyle = series.color; + plotPoints(series.datapoints, radius, + getFillStyle(series.points, series.color), 0, 2 * Math.PI, + series.xaxis, series.yaxis); + ctx.restore(); + } + + function drawBar(x, y, b, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c, horizontal) { + var left, right, bottom, top, + drawLeft, drawRight, drawTop, drawBottom, + tmp; + + if (horizontal) { + drawBottom = drawRight = drawTop = true; + drawLeft = false; + left = b; + right = x; + top = y + barLeft; + bottom = y + barRight; + + // account for negative bars + if (right < left) { + tmp = right; + right = left; + left = tmp; + drawLeft = true; + drawRight = false; + } + } + else { + drawLeft = drawRight = drawTop = true; + drawBottom = false; + left = x + barLeft; + right = x + barRight; + bottom = b; + top = y; + + // account for negative bars + if (top < bottom) { + tmp = top; + top = bottom; + bottom = tmp; + drawBottom = true; + drawTop = false; + } + } + + // clip + if (right < axisx.min || left > axisx.max || + top < axisy.min || bottom > axisy.max) + return; + + if (left < axisx.min) { + left = axisx.min; + drawLeft = false; + } + + if (right > axisx.max) { + right = axisx.max; + drawRight = false; + } + + if (bottom < axisy.min) { + bottom = axisy.min; + drawBottom = false; + } + + if (top > axisy.max) { + top = axisy.max; + drawTop = false; + } + + left = axisx.p2c(left); + bottom = axisy.p2c(bottom); + right = axisx.p2c(right); + top = axisy.p2c(top); + + // fill the bar + if (fillStyleCallback) { + c.beginPath(); + c.moveTo(left, bottom); + c.lineTo(left, top); + c.lineTo(right, top); + c.lineTo(right, bottom); + c.fillStyle = fillStyleCallback(bottom, top); + c.fill(); + } + + // draw outline + if (drawLeft || drawRight || drawTop || drawBottom) { + c.beginPath(); + + // FIXME: inline moveTo is buggy with excanvas + c.moveTo(left, bottom + offset); + if (drawLeft) + c.lineTo(left, top + offset); + else + c.moveTo(left, top + offset); + if (drawTop) + c.lineTo(right, top + offset); + else + c.moveTo(right, top + offset); + if (drawRight) + c.lineTo(right, bottom + offset); + else + c.moveTo(right, bottom + offset); + if (drawBottom) + c.lineTo(left, bottom + offset); + else + c.moveTo(left, bottom + offset); + c.stroke(); + } + } + + function drawSeriesBars(series) { + function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) { + var points = datapoints.points, ps = datapoints.pointsize; + + for (var i = 0; i < points.length; i += ps) { + if (points[i] == null) + continue; + drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal); + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + // FIXME: figure out a way to add shadows (for instance along the right edge) + ctx.lineWidth = series.bars.lineWidth; + ctx.strokeStyle = series.color; + var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2; + var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null; + plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis); + ctx.restore(); + } + + function getFillStyle(filloptions, seriesColor, bottom, top) { + var fill = filloptions.fill; + if (!fill) + return null; + + if (filloptions.fillColor) + return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); + + var c = $.color.parse(seriesColor); + c.a = typeof fill == "number" ? fill : 0.4; + c.normalize(); + return c.toString(); + } + + function insertLegend() { + placeholder.find(".legend").remove(); + + if (!options.legend.show) + return; + + var fragments = [], rowStarted = false, + lf = options.legend.labelFormatter, s, label; + for (i = 0; i < series.length; ++i) { + s = series[i]; + label = s.label; + if (!label) + continue; + + if (i % options.legend.noColumns == 0) { + if (rowStarted) + fragments.push(''); + fragments.push(''); + rowStarted = true; + } + + if (lf) + label = lf(label, s); + + fragments.push( + '
' + + '' + label + ''); + } + if (rowStarted) + fragments.push(''); + + if (fragments.length == 0) + return; + + var table = '' + fragments.join("") + '
'; + if (options.legend.container != null) + $(options.legend.container).html(table); + else { + var pos = "", + p = options.legend.position, + m = options.legend.margin; + if (m[0] == null) + m = [m, m]; + if (p.charAt(0) == "n") + pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; + else if (p.charAt(0) == "s") + pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; + if (p.charAt(1) == "e") + pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; + else if (p.charAt(1) == "w") + pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; + var legend = $('
' + table.replace('style="', 'style="position:absolute;' + pos +';') + '
').appendTo(placeholder); + if (options.legend.backgroundOpacity != 0.0) { + // put in the transparent background + // separately to avoid blended labels and + // label boxes + var c = options.legend.backgroundColor; + if (c == null) { + c = options.grid.backgroundColor; + if (c && typeof c == "string") + c = $.color.parse(c); + else + c = $.color.extract(legend, 'background-color'); + c.a = 1; + c = c.toString(); + } + var div = legend.children(); + $('
').prependTo(legend).css('opacity', options.legend.backgroundOpacity); + } + } + } + + + // interactive features + + var highlights = [], + redrawTimeout = null; + + // returns the data item the mouse is over, or null if none is found + function findNearbyItem(mouseX, mouseY, seriesFilter) { + var maxDistance = options.grid.mouseActiveRadius, + smallestDistance = maxDistance * maxDistance + 1, + item = null, foundPoint = false, i, j; + + for (i = 0; i < series.length; ++i) { + if (!seriesFilter(series[i])) + continue; + + var s = series[i], + axisx = s.xaxis, + axisy = s.yaxis, + points = s.datapoints.points, + ps = s.datapoints.pointsize, + mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster + my = axisy.c2p(mouseY), + maxx = maxDistance / axisx.scale, + maxy = maxDistance / axisy.scale; + + if (s.lines.show || s.points.show) { + for (j = 0; j < points.length; j += ps) { + var x = points[j], y = points[j + 1]; + if (x == null) + continue; + + // For points and lines, the cursor must be within a + // certain distance to the data point + if (x - mx > maxx || x - mx < -maxx || + y - my > maxy || y - my < -maxy) + continue; + + // We have to calculate distances in pixels, not in + // data units, because the scales of the axes may be different + var dx = Math.abs(axisx.p2c(x) - mouseX), + dy = Math.abs(axisy.p2c(y) - mouseY), + dist = dx * dx + dy * dy; // we save the sqrt + + // use <= to ensure last point takes precedence + // (last generally means on top of) + if (dist <= smallestDistance) { + smallestDistance = dist; + item = [i, j / ps]; + } + } + } + + if (s.bars.show && !item) { // no other point can be nearby + var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2, + barRight = barLeft + s.bars.barWidth; + + for (j = 0; j < points.length; j += ps) { + var x = points[j], y = points[j + 1], b = points[j + 2]; + if (x == null) + continue; + + // for a bar graph, the cursor must be inside the bar + if (series[i].bars.horizontal ? + (mx <= Math.max(b, x) && mx >= Math.min(b, x) && + my >= y + barLeft && my <= y + barRight) : + (mx >= x + barLeft && mx <= x + barRight && + my >= Math.min(b, y) && my <= Math.max(b, y))) + item = [i, j / ps]; + } + } + } + + if (item) { + i = item[0]; + j = item[1]; + ps = series[i].datapoints.pointsize; + + return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps), + dataIndex: j, + series: series[i], + seriesIndex: i }; + } + + return null; + } + + function onMouseMove(e) { + if (options.grid.hoverable) + triggerClickHoverEvent("plothover", e, + function (s) { return s["hoverable"] != false; }); + } + + function onClick(e) { + triggerClickHoverEvent("plotclick", e, + function (s) { return s["clickable"] != false; }); + } + + // trigger click or hover event (they send the same parameters + // so we share their code) + function triggerClickHoverEvent(eventname, event, seriesFilter) { + var offset = eventHolder.offset(), + pos = { pageX: event.pageX, pageY: event.pageY }, + canvasX = event.pageX - offset.left - plotOffset.left, + canvasY = event.pageY - offset.top - plotOffset.top; + + if (axes.xaxis.used) + pos.x = axes.xaxis.c2p(canvasX); + if (axes.yaxis.used) + pos.y = axes.yaxis.c2p(canvasY); + if (axes.x2axis.used) + pos.x2 = axes.x2axis.c2p(canvasX); + if (axes.y2axis.used) + pos.y2 = axes.y2axis.c2p(canvasY); + + var item = findNearbyItem(canvasX, canvasY, seriesFilter); + + if (item) { + // fill in mouse pos for any listeners out there + item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left); + item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top); + } + + if (options.grid.autoHighlight) { + // clear auto-highlights + for (var i = 0; i < highlights.length; ++i) { + var h = highlights[i]; + if (h.auto == eventname && + !(item && h.series == item.series && h.point == item.datapoint)) + unhighlight(h.series, h.point); + } + + if (item) + highlight(item.series, item.datapoint, eventname); + } + + placeholder.trigger(eventname, [ pos, item ]); + } + + function triggerRedrawOverlay() { + if (!redrawTimeout) + redrawTimeout = setTimeout(drawOverlay, 30); + } + + function drawOverlay() { + redrawTimeout = null; + + // draw highlights + octx.save(); + octx.clearRect(0, 0, canvasWidth, canvasHeight); + octx.translate(plotOffset.left, plotOffset.top); + + var i, hi; + for (i = 0; i < highlights.length; ++i) { + hi = highlights[i]; + + if (hi.series.bars.show) + drawBarHighlight(hi.series, hi.point); + else + drawPointHighlight(hi.series, hi.point); + } + octx.restore(); + + executeHooks(hooks.drawOverlay, [octx]); + } + + function highlight(s, point, auto) { + if (typeof s == "number") + s = series[s]; + + if (typeof point == "number") + point = s.data[point]; + + var i = indexOfHighlight(s, point); + if (i == -1) { + highlights.push({ series: s, point: point, auto: auto }); + + triggerRedrawOverlay(); + } + else if (!auto) + highlights[i].auto = false; + } + + function unhighlight(s, point) { + if (s == null && point == null) { + highlights = []; + triggerRedrawOverlay(); + } + + if (typeof s == "number") + s = series[s]; + + if (typeof point == "number") + point = s.data[point]; + + var i = indexOfHighlight(s, point); + if (i != -1) { + highlights.splice(i, 1); + + triggerRedrawOverlay(); + } + } + + function indexOfHighlight(s, p) { + for (var i = 0; i < highlights.length; ++i) { + var h = highlights[i]; + if (h.series == s && h.point[0] == p[0] + && h.point[1] == p[1]) + return i; + } + return -1; + } + + function drawPointHighlight(series, point) { + var x = point[0], y = point[1], + axisx = series.xaxis, axisy = series.yaxis; + + if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) + return; + + var pointRadius = series.points.radius + series.points.lineWidth / 2; + octx.lineWidth = pointRadius; + octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString(); + var radius = 1.5 * pointRadius; + octx.beginPath(); + octx.arc(axisx.p2c(x), axisy.p2c(y), radius, 0, 2 * Math.PI, false); + octx.stroke(); + } + + function drawBarHighlight(series, point) { + octx.lineWidth = series.bars.lineWidth; + octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString(); + var fillStyle = $.color.parse(series.color).scale('a', 0.5).toString(); + var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2; + drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth, + 0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal); + } + + function getColorOrGradient(spec, bottom, top, defaultColor) { + if (typeof spec == "string") + return spec; + else { + // assume this is a gradient spec; IE currently only + // supports a simple vertical gradient properly, so that's + // what we support too + var gradient = ctx.createLinearGradient(0, top, 0, bottom); + + for (var i = 0, l = spec.colors.length; i < l; ++i) { + var c = spec.colors[i]; + if (typeof c != "string") { + c = $.color.parse(defaultColor).scale('rgb', c.brightness); + c.a *= c.opacity; + c = c.toString(); + } + gradient.addColorStop(i / (l - 1), c); + } + + return gradient; + } + } + } + + $.plot = function(placeholder, data, options) { + var plot = new Plot($(placeholder), data, options, $.plot.plugins); + /*var t0 = new Date(); + var t1 = new Date(); + var tstr = "time used (msecs): " + (t1.getTime() - t0.getTime()) + if (window.console) + console.log(tstr); + else + alert(tstr);*/ + return plot; + }; + + $.plot.plugins = []; + + // returns a string with the date d formatted according to fmt + $.plot.formatDate = function(d, fmt, monthNames) { + var leftPad = function(n) { + n = "" + n; + return n.length == 1 ? "0" + n : n; + }; + + var r = []; + var escape = false; + var hours = d.getUTCHours(); + var isAM = hours < 12; + if (monthNames == null) + monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + + if (fmt.search(/%p|%P/) != -1) { + if (hours > 12) { + hours = hours - 12; + } else if (hours == 0) { + hours = 12; + } + } + for (var i = 0; i < fmt.length; ++i) { + var c = fmt.charAt(i); + + if (escape) { + switch (c) { + case 'h': c = "" + hours; break; + case 'H': c = leftPad(hours); break; + case 'M': c = leftPad(d.getUTCMinutes()); break; + case 'S': c = leftPad(d.getUTCSeconds()); break; + case 'd': c = "" + d.getUTCDate(); break; + case 'm': c = "" + (d.getUTCMonth() + 1); break; + case 'y': c = "" + d.getUTCFullYear(); break; + case 'b': c = "" + monthNames[d.getUTCMonth()]; break; + case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break; + case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break; + } + r.push(c); + escape = false; + } + else { + if (c == "%") + escape = true; + else + r.push(c); + } + } + return r.join(""); + }; + + // round to nearby lower multiple of base + function floorInBase(n, base) { + return base * Math.floor(n / base); + } + +})(jQuery); Added: pypy/build/bot2/jsplot/js/jquery.min.js ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/js/jquery.min.js Sun Jan 17 15:06:09 2010 @@ -0,0 +1,19 @@ +/* + * jQuery JavaScript Library v1.3.2 + * http://jquery.com/ + * + * Copyright (c) 2009 John Resig + * Dual licensed under the MIT and GPL licenses. + * http://docs.jquery.com/License + * + * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) + * Revision: 6246 + */ +(function(){var window=this,undefined,_jQuery=window.jQuery,_$=window.$,jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context)},quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,isSimple=/^.[^:#\[\.,]*$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;this.context=selector;return this}if(typeof selector==="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1]){selector=jQuery.clean([match[1]],context)}else{var elem=document.getElementById(match[3]);if(elem&&elem.id!=match[3]){return jQuery().find(selector)}var ret=jQuery(elem||[]);ret.context=document;ret.selector=selector;return ret}}else{return jQuery(context).find(selector)}}else{if(jQuery.isFunction(selector)){return jQuery(document).ready(selector)}}if(selector.selector&&selector.context){this.selector=selector.selector;this.context=selector.context}return this.setArray(jQuery.isArray(selector)?selector:jQuery.makeArray(selector))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(num){return num===undefined?Array.prototype.slice.call(this):this[num]},pushStack:function(elems,name,selector){var ret=jQuery(elems);ret.prevObject=this;ret.context=this.context;if(name==="find"){ret.selector=this.selector+(this.selector?" ":"")+selector}else{if(name){ret.selector=this.selector+"."+name+"("+selector+")"}}return ret},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this},each:function(callback,args){return jQuery.each(this,callback,args)},index:function(elem){return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this)},attr:function(name,value,type){var options=name;if(typeof name==="string"){if(value===undefined){return this[0]&&jQuery[type||"attr"](this[0],name)}else{options={};options[name]=value}}return this.each(function(i){for(name in options){jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name))}})},css:function(key,value){if((key=="width"||key=="height")&&parseFloat(value)<0){value=undefined}return this.attr(key,value,"curCSS")},text:function(text){if(typeof text!=="object"&&text!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text))}var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8){ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this])}})});return ret},wrapAll:function(html){if(this[0]){var wrap=jQuery(html,this[0].ownerDocument).clone();if(this[0].parentNode){wrap.insertBefore(this[0])}wrap.map(function(){var elem=this;while(elem.firstChild){elem=elem.firstChild}return elem}).append(this)}return this},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html)})},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html)})},append:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType==1){this.appendChild(elem)}})},prepend:function(){return this.domManip(arguments,true,function(elem){if(this.nodeType==1){this.insertBefore(elem,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this)})},after:function(){return this.domManip(arguments,false,function(elem){this.parentNode.insertBefore(elem,this.nextSibling)})},end:function(){return this.prevObject||jQuery([])},push:[].push,sort:[].sort,splice:[].splice,find:function(selector){if(this.length===1){var ret=this.pushStack([],"find",selector);ret.length=0;jQuery.find(selector,this[0],ret);return ret}else{return this.pushStack(jQuery.unique(jQuery.map(this,function(elem){return jQuery.find(selector,elem)})),"find",selector)}},clone:function(events){var ret=this.map(function(){if(!jQuery.support.noCloneEvent&&!jQuery.isXMLDoc(this)){var html=this.outerHTML;if(!html){var div=this.ownerDocument.createElement("div");div.appendChild(this.cloneNode(true));html=div.innerHTML}return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(events===true){var orig=this.find("*").andSelf(),i=0;ret.find("*").andSelf().each(function(){if(this.nodeName!==orig[i].nodeName){return }var events=jQuery.data(orig[i],"events");for(var type in events){for(var handler in events[type]){jQuery.event.add(this,type,events[type][handler],events[type][handler].data)}}i++})}return ret},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i)})||jQuery.multiFilter(selector,jQuery.grep(this,function(elem){return elem.nodeType===1})),"filter",selector)},closest:function(selector){var pos=jQuery.expr.match.POS.test(selector)?jQuery(selector):null,closer=0;return this.map(function(){var cur=this;while(cur&&cur.ownerDocument){if(pos?pos.index(cur)>-1:jQuery(cur).is(selector)){jQuery.data(cur,"closest",closer);return cur}cur=cur.parentNode;closer++}})},not:function(selector){if(typeof selector==="string"){if(isSimple.test(selector)){return this.pushStack(jQuery.multiFilter(selector,this,true),"not",selector)}else{selector=jQuery.multiFilter(selector,this)}}var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector})},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector==="string"?jQuery(selector):jQuery.makeArray(selector))))},is:function(selector){return !!selector&&jQuery.multiFilter(selector,this).length>0},hasClass:function(selector){return !!selector&&this.is("."+selector)},val:function(value){if(value===undefined){var elem=this[0];if(elem){if(jQuery.nodeName(elem,"option")){return(elem.attributes.value||{}).specified?elem.value:elem.text}if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0){return null}for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0)}else{if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0)});if(!values.length){this.selectedIndex=-1}}else{this.value=value}}})},html:function(value){return value===undefined?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(value)},replaceWith:function(value){return this.after(value).remove()},eq:function(i){return this.slice(i,+i+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(args,table,callback){if(this[0]){var fragment=(this[0].ownerDocument||this[0]).createDocumentFragment(),scripts=jQuery.clean(args,(this[0].ownerDocument||this[0]),fragment),first=fragment.firstChild;if(first){for(var i=0,l=this.length;i1||i>0?fragment.cloneNode(true):fragment)}}if(scripts){jQuery.each(scripts,evalScript)}}return this;function root(elem,cur){return table&&jQuery.nodeName(elem,"table")&&jQuery.nodeName(cur,"tr")?(elem.getElementsByTagName("tbody")[0]||elem.appendChild(elem.ownerDocument.createElement("tbody"))):elem}}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src){jQuery.ajax({url:elem.src,async:false,dataType:"script"})}else{jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"")}if(elem.parentNode){elem.parentNode.removeChild(elem)}}function now(){return +new Date}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(typeof target==="boolean"){deep=target;target=arguments[1]||{};i=2}if(typeof target!=="object"&&!jQuery.isFunction(target)){target={}}if(length==i){target=this;--i}for(;i-1}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name]}callback.call(elem);for(var name in options){elem.style[name]=old[name]}},css:function(elem,name,force,extra){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;if(extra==="border"){return }jQuery.each(which,function(){if(!extra){val-=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0}if(extra==="margin"){val+=parseFloat(jQuery.curCSS(elem,"margin"+this,true))||0}else{val-=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0}})}if(elem.offsetWidth!==0){getWH()}else{jQuery.swap(elem,props,getWH)}return Math.max(0,Math.round(val))}return jQuery.curCSS(elem,name,force)},curCSS:function(elem,name,force){var ret,style=elem.style;if(name=="opacity"&&!jQuery.support.opacity){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret}if(name.match(/float/i)){name=styleFloat}if(!force&&style&&style[name]){ret=style[name]}else{if(defaultView.getComputedStyle){if(name.match(/float/i)){name="float"}name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle){ret=computedStyle.getPropertyValue(name)}if(name=="opacity"&&ret==""){ret="1"}}else{if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase()});ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;style.left=ret||0;ret=style.pixelLeft+"px";style.left=left;elem.runtimeStyle.left=rsLeft}}}}return ret},clean:function(elems,context,fragment){context=context||document;if(typeof context.createElement==="undefined"){context=context.ownerDocument||context[0]&&context[0].ownerDocument||document}if(!fragment&&elems.length===1&&typeof elems[0]==="string"){var match=/^<(\w+)\s*\/?>$/.exec(elems[0]);if(match){return[context.createElement(match[1])]}}var ret=[],scripts=[],div=context.createElement("div");jQuery.each(elems,function(i,elem){if(typeof elem==="number"){elem+=""}if(!elem){return }if(typeof elem==="string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">"});var tags=elem.replace(/^\s+/,"").substring(0,10).toLowerCase();var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||!jQuery.support.htmlSerialize&&[1,"div
","
"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--){div=div.lastChild}if(!jQuery.support.tbody){var hasBody=/"&&!hasBody?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j){if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length){tbody[j].parentNode.removeChild(tbody[j])}}}if(!jQuery.support.leadingWhitespace&&/^\s/.test(elem)){div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild)}elem=jQuery.makeArray(div.childNodes)}if(elem.nodeType){ret.push(elem)}else{ret=jQuery.merge(ret,elem)}});if(fragment){for(var i=0;ret[i];i++){if(jQuery.nodeName(ret[i],"script")&&(!ret[i].type||ret[i].type.toLowerCase()==="text/javascript")){scripts.push(ret[i].parentNode?ret[i].parentNode.removeChild(ret[i]):ret[i])}else{if(ret[i].nodeType===1){ret.splice.apply(ret,[i+1,0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))))}fragment.appendChild(ret[i])}}return scripts}return ret},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8){return undefined}var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&elem.parentNode){elem.parentNode.selectedIndex}if(name in elem&¬xml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode){throw"type property can't be changed"}elem[name]=value}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name)){return elem.getAttributeNode(name).nodeValue}if(name=="tabIndex"){var attributeNode=elem.getAttributeNode("tabIndex");return attributeNode&&attributeNode.specified?attributeNode.value:elem.nodeName.match(/(button|input|object|select|textarea)/i)?0:elem.nodeName.match(/^(a|area)$/i)&&elem.href?0:undefined}return elem[name]}if(!jQuery.support.style&¬xml&&name=="style"){return jQuery.attr(elem.style,"cssText",value)}if(set){elem.setAttribute(name,""+value)}var attr=!jQuery.support.hrefNormalized&¬xml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr}if(!jQuery.support.opacity&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+""=="NaN"?"":"alpha(opacity="+value*100+")")}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase()});if(set){elem[name]=value}return elem[name]},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"")},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||typeof array==="string"||jQuery.isFunction(array)||array.setInterval){ret[0]=array}else{while(i){ret[--i]=array[i]}}}return ret},inArray:function(elem,array){for(var i=0,length=array.length;i0?this.clone(true):this).get();jQuery.fn[original].apply(jQuery(insert[i]),elems);ret=ret.concat(elems)}return this.pushStack(ret,name,selector)}});jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");if(this.nodeType==1){this.removeAttribute(name)}},addClass:function(classNames){jQuery.className.add(this,classNames)},removeClass:function(classNames){jQuery.className.remove(this,classNames)},toggleClass:function(classNames,state){if(typeof state!=="boolean"){state=!jQuery.className.has(this,classNames)}jQuery.className[state?"add":"remove"](this,classNames)},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).length){jQuery("*",this).add([this]).each(function(){jQuery.event.remove(this);jQuery.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){jQuery(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments)}});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0}var expando="jQuery"+now(),uuid=0,windowData={};jQuery.extend({cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id){id=elem[expando]=++uuid}if(name&&!jQuery.cache[id]){jQuery.cache[id]={}}if(data!==undefined){jQuery.cache[id][name]=data}return name?jQuery.cache[id][name]:id},removeData:function(elem,name){elem=elem==window?windowData:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id]){break}if(!name){jQuery.removeData(elem)}}}else{try{delete elem[expando]}catch(e){if(elem.removeAttribute){elem.removeAttribute(expando)}}delete jQuery.cache[id]}},queue:function(elem,type,data){if(elem){type=(type||"fx")+"queue";var q=jQuery.data(elem,type);if(!q||jQuery.isArray(data)){q=jQuery.data(elem,type,jQuery.makeArray(data))}else{if(data){q.push(data)}}}return q},dequeue:function(elem,type){var queue=jQuery.queue(elem,type),fn=queue.shift();if(!type||type==="fx"){fn=queue[0]}if(fn!==undefined){fn.call(elem)}}});jQuery.fn.extend({data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length){data=jQuery.data(this[0],key)}return data===undefined&&parts[1]?this.data(parts[0]):data}else{return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value)})}},removeData:function(key){return this.each(function(){jQuery.removeData(this,key)})},queue:function(type,data){if(typeof type!=="string"){data=type;type="fx"}if(data===undefined){return jQuery.queue(this[0],type)}return this.each(function(){var queue=jQuery.queue(this,type,data);if(type=="fx"&&queue.length==1){queue[0].call(this)}})},dequeue:function(type){return this.each(function(){jQuery.dequeue(this,type)})}}); +/* + * Sizzle CSS Selector Engine - v0.9.3 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var chunker=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,done=0,toString=Object.prototype.toString;var Sizzle=function(selector,context,results,seed){results=results||[];context=context||document;if(context.nodeType!==1&&context.nodeType!==9){return[]}if(!selector||typeof selector!=="string"){return results}var parts=[],m,set,checkSet,check,mode,extra,prune=true;chunker.lastIndex=0;while((m=chunker.exec(selector))!==null){parts.push(m[1]);if(m[2]){extra=RegExp.rightContext;break}}if(parts.length>1&&origPOS.exec(selector)){if(parts.length===2&&Expr.relative[parts[0]]){set=posProcess(parts[0]+parts[1],context)}else{set=Expr.relative[parts[0]]?[context]:Sizzle(parts.shift(),context);while(parts.length){selector=parts.shift();if(Expr.relative[selector]){selector+=parts.shift()}set=posProcess(selector,set)}}}else{var ret=seed?{expr:parts.pop(),set:makeArray(seed)}:Sizzle.find(parts.pop(),parts.length===1&&context.parentNode?context.parentNode:context,isXML(context));set=Sizzle.filter(ret.expr,ret.set);if(parts.length>0){checkSet=makeArray(set)}else{prune=false}while(parts.length){var cur=parts.pop(),pop=cur;if(!Expr.relative[cur]){cur=""}else{pop=parts.pop()}if(pop==null){pop=context}Expr.relative[cur](checkSet,pop,isXML(context))}}if(!checkSet){checkSet=set}if(!checkSet){throw"Syntax error, unrecognized expression: "+(cur||selector)}if(toString.call(checkSet)==="[object Array]"){if(!prune){results.push.apply(results,checkSet)}else{if(context.nodeType===1){for(var i=0;checkSet[i]!=null;i++){if(checkSet[i]&&(checkSet[i]===true||checkSet[i].nodeType===1&&contains(context,checkSet[i]))){results.push(set[i])}}}else{for(var i=0;checkSet[i]!=null;i++){if(checkSet[i]&&checkSet[i].nodeType===1){results.push(set[i])}}}}}else{makeArray(checkSet,results)}if(extra){Sizzle(extra,context,results,seed);if(sortOrder){hasDuplicate=false;results.sort(sortOrder);if(hasDuplicate){for(var i=1;i":function(checkSet,part,isXML){var isPartStr=typeof part==="string";if(isPartStr&&!/\W/.test(part)){part=isXML?part:part.toUpperCase();for(var i=0,l=checkSet.length;i=0)){if(!inplace){result.push(elem)}}else{if(inplace){curLoop[i]=false}}}}return false},ID:function(match){return match[1].replace(/\\/g,"")},TAG:function(match,curLoop){for(var i=0;curLoop[i]===false;i++){}return curLoop[i]&&isXML(curLoop[i])?match[1]:match[1].toUpperCase()},CHILD:function(match){if(match[1]=="nth"){var test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(match[2]=="even"&&"2n"||match[2]=="odd"&&"2n+1"||!/\D/.test(match[2])&&"0n+"+match[2]||match[2]);match[2]=(test[1]+(test[2]||1))-0;match[3]=test[3]-0}match[0]=done++;return match},ATTR:function(match,curLoop,inplace,result,not,isXML){var name=match[1].replace(/\\/g,"");if(!isXML&&Expr.attrMap[name]){match[1]=Expr.attrMap[name]}if(match[2]==="~="){match[4]=" "+match[4]+" "}return match},PSEUDO:function(match,curLoop,inplace,result,not){if(match[1]==="not"){if(match[3].match(chunker).length>1||/^\w/.test(match[3])){match[3]=Sizzle(match[3],null,null,curLoop)}else{var ret=Sizzle.filter(match[3],curLoop,inplace,true^not);if(!inplace){result.push.apply(result,ret)}return false}}else{if(Expr.match.POS.test(match[0])||Expr.match.CHILD.test(match[0])){return true}}return match},POS:function(match){match.unshift(true);return match}},filters:{enabled:function(elem){return elem.disabled===false&&elem.type!=="hidden"},disabled:function(elem){return elem.disabled===true},checked:function(elem){return elem.checked===true},selected:function(elem){elem.parentNode.selectedIndex;return elem.selected===true},parent:function(elem){return !!elem.firstChild},empty:function(elem){return !elem.firstChild},has:function(elem,i,match){return !!Sizzle(match[3],elem).length},header:function(elem){return/h\d/i.test(elem.nodeName)},text:function(elem){return"text"===elem.type},radio:function(elem){return"radio"===elem.type},checkbox:function(elem){return"checkbox"===elem.type},file:function(elem){return"file"===elem.type},password:function(elem){return"password"===elem.type},submit:function(elem){return"submit"===elem.type},image:function(elem){return"image"===elem.type},reset:function(elem){return"reset"===elem.type},button:function(elem){return"button"===elem.type||elem.nodeName.toUpperCase()==="BUTTON"},input:function(elem){return/input|select|textarea|button/i.test(elem.nodeName)}},setFilters:{first:function(elem,i){return i===0},last:function(elem,i,match,array){return i===array.length-1},even:function(elem,i){return i%2===0},odd:function(elem,i){return i%2===1},lt:function(elem,i,match){return imatch[3]-0},nth:function(elem,i,match){return match[3]-0==i},eq:function(elem,i,match){return match[3]-0==i}},filter:{PSEUDO:function(elem,match,i,array){var name=match[1],filter=Expr.filters[name];if(filter){return filter(elem,i,match,array)}else{if(name==="contains"){return(elem.textContent||elem.innerText||"").indexOf(match[3])>=0}else{if(name==="not"){var not=match[3];for(var i=0,l=not.length;i=0)}}},ID:function(elem,match){return elem.nodeType===1&&elem.getAttribute("id")===match},TAG:function(elem,match){return(match==="*"&&elem.nodeType===1)||elem.nodeName===match},CLASS:function(elem,match){return(" "+(elem.className||elem.getAttribute("class"))+" ").indexOf(match)>-1},ATTR:function(elem,match){var name=match[1],result=Expr.attrHandle[name]?Expr.attrHandle[name](elem):elem[name]!=null?elem[name]:elem.getAttribute(name),value=result+"",type=match[2],check=match[4];return result==null?type==="!=":type==="="?value===check:type==="*="?value.indexOf(check)>=0:type==="~="?(" "+value+" ").indexOf(check)>=0:!check?value&&result!==false:type==="!="?value!=check:type==="^="?value.indexOf(check)===0:type==="$="?value.substr(value.length-check.length)===check:type==="|="?value===check||value.substr(0,check.length+1)===check+"-":false},POS:function(elem,match,i,array){var name=match[2],filter=Expr.setFilters[name];if(filter){return filter(elem,i,match,array)}}}};var origPOS=Expr.match.POS;for(var type in Expr.match){Expr.match[type]=RegExp(Expr.match[type].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var makeArray=function(array,results){array=Array.prototype.slice.call(array);if(results){results.push.apply(results,array);return results}return array};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(e){makeArray=function(array,results){var ret=results||[];if(toString.call(array)==="[object Array]"){Array.prototype.push.apply(ret,array)}else{if(typeof array.length==="number"){for(var i=0,l=array.length;i";var root=document.documentElement;root.insertBefore(form,root.firstChild);if(!!document.getElementById(id)){Expr.find.ID=function(match,context,isXML){if(typeof context.getElementById!=="undefined"&&!isXML){var m=context.getElementById(match[1]);return m?m.id===match[1]||typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id").nodeValue===match[1]?[m]:undefined:[]}};Expr.filter.ID=function(elem,match){var node=typeof elem.getAttributeNode!=="undefined"&&elem.getAttributeNode("id");return elem.nodeType===1&&node&&node.nodeValue===match}}root.removeChild(form)})();(function(){var div=document.createElement("div");div.appendChild(document.createComment(""));if(div.getElementsByTagName("*").length>0){Expr.find.TAG=function(match,context){var results=context.getElementsByTagName(match[1]);if(match[1]==="*"){var tmp=[];for(var i=0;results[i];i++){if(results[i].nodeType===1){tmp.push(results[i])}}results=tmp}return results}}div.innerHTML="";if(div.firstChild&&typeof div.firstChild.getAttribute!=="undefined"&&div.firstChild.getAttribute("href")!=="#"){Expr.attrHandle.href=function(elem){return elem.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var oldSizzle=Sizzle,div=document.createElement("div");div.innerHTML="

";if(div.querySelectorAll&&div.querySelectorAll(".TEST").length===0){return }Sizzle=function(query,context,extra,seed){context=context||document;if(!seed&&context.nodeType===9&&!isXML(context)){try{return makeArray(context.querySelectorAll(query),extra)}catch(e){}}return oldSizzle(query,context,extra,seed)};Sizzle.find=oldSizzle.find;Sizzle.filter=oldSizzle.filter;Sizzle.selectors=oldSizzle.selectors;Sizzle.matches=oldSizzle.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var div=document.createElement("div");div.innerHTML="
";if(div.getElementsByClassName("e").length===0){return }div.lastChild.className="e";if(div.getElementsByClassName("e").length===1){return }Expr.order.splice(1,0,"CLASS");Expr.find.CLASS=function(match,context,isXML){if(typeof context.getElementsByClassName!=="undefined"&&!isXML){return context.getElementsByClassName(match[1])}}})()}function dirNodeCheck(dir,cur,doneName,checkSet,nodeCheck,isXML){var sibDir=dir=="previousSibling"&&!isXML;for(var i=0,l=checkSet.length;i0){match=elem;break}}}elem=elem[dir]}checkSet[i]=match}}}var contains=document.compareDocumentPosition?function(a,b){return a.compareDocumentPosition(b)&16}:function(a,b){return a!==b&&(a.contains?a.contains(b):true)};var isXML=function(elem){return elem.nodeType===9&&elem.documentElement.nodeName!=="HTML"||!!elem.ownerDocument&&isXML(elem.ownerDocument)};var posProcess=function(selector,context){var tmpSet=[],later="",match,root=context.nodeType?[context]:context;while((match=Expr.match.PSEUDO.exec(selector))){later+=match[0];selector=selector.replace(Expr.match.PSEUDO,"")}selector=Expr.relative[selector]?selector+"*":selector;for(var i=0,l=root.length;i0||elem.offsetHeight>0};Sizzle.selectors.filters.animated=function(elem){return jQuery.grep(jQuery.timers,function(fn){return elem===fn.elem}).length};jQuery.multiFilter=function(expr,elems,not){if(not){expr=":not("+expr+")"}return Sizzle.matches(expr,elems)};jQuery.dir=function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1){matched.push(cur)}cur=cur[dir]}return matched};jQuery.nth=function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir]){if(cur.nodeType==1&&++num==result){break}}return cur};jQuery.sibling=function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem){r.push(n)}}return r};return ;window.Sizzle=Sizzle})();jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8){return }if(elem.setInterval&&elem!=window){elem=window}if(!handler.guid){handler.guid=this.guid++}if(data!==undefined){var fn=handler;handler=this.proxy(fn);handler.data=data}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){return typeof jQuery!=="undefined"&&!jQuery.event.triggered?jQuery.event.handle.apply(arguments.callee.elem,arguments):undefined});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var namespaces=type.split(".");type=namespaces.shift();handler.type=namespaces.slice().sort().join(".");var handlers=events[type];if(jQuery.event.specialAll[type]){jQuery.event.specialAll[type].setup.call(elem,data,namespaces)}if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem,data,namespaces)===false){if(elem.addEventListener){elem.addEventListener(type,handle,false)}else{if(elem.attachEvent){elem.attachEvent("on"+type,handle)}}}}handlers[handler.guid]=handler;jQuery.event.global[type]=true});elem=null},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8){return }var events=jQuery.data(elem,"events"),ret,index;if(events){if(types===undefined||(typeof types==="string"&&types.charAt(0)==".")){for(var type in events){this.remove(elem,type+(types||""))}}else{if(types.type){handler=types.handler;types=types.type}jQuery.each(types.split(/\s+/),function(index,type){var namespaces=type.split(".");type=namespaces.shift();var namespace=RegExp("(^|\\.)"+namespaces.slice().sort().join(".*\\.")+"(\\.|$)");if(events[type]){if(handler){delete events[type][handler.guid]}else{for(var handle in events[type]){if(namespace.test(events[type][handle].type)){delete events[type][handle]}}}if(jQuery.event.specialAll[type]){jQuery.event.specialAll[type].teardown.call(elem,namespaces)}for(ret in events[type]){break}if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem,namespaces)===false){if(elem.removeEventListener){elem.removeEventListener(type,jQuery.data(elem,"handle"),false)}else{if(elem.detachEvent){elem.detachEvent("on"+type,jQuery.data(elem,"handle"))}}}ret=null;delete events[type]}}})}for(ret in events){break}if(!ret){var handle=jQuery.data(elem,"handle");if(handle){handle.elem=null}jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle")}}},trigger:function(event,data,elem,bubbling){var type=event.type||event;if(!bubbling){event=typeof event==="object"?event[expando]?event:jQuery.extend(jQuery.Event(type),event):jQuery.Event(type);if(type.indexOf("!")>=0){event.type=type=type.slice(0,-1);event.exclusive=true}if(!elem){event.stopPropagation();if(this.global[type]){jQuery.each(jQuery.cache,function(){if(this.events&&this.events[type]){jQuery.event.trigger(event,data,this.handle.elem)}})}}if(!elem||elem.nodeType==3||elem.nodeType==8){return undefined}event.result=undefined;event.target=elem;data=jQuery.makeArray(data);data.unshift(event)}event.currentTarget=elem;var handle=jQuery.data(elem,"handle");if(handle){handle.apply(elem,data)}if((!elem[type]||(jQuery.nodeName(elem,"a")&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false){event.result=false}if(!bubbling&&elem[type]&&!event.isDefaultPrevented()&&!(jQuery.nodeName(elem,"a")&&type=="click")){this.triggered=true;try{elem[type]()}catch(e){}}this.triggered=false;if(!event.isPropagationStopped()){var parent=elem.parentNode||elem.ownerDocument;if(parent){jQuery.event.trigger(event,data,parent,true)}}},handle:function(event){var all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);event.currentTarget=this;var namespaces=event.type.split(".");event.type=namespaces.shift();all=!namespaces.length&&!event.exclusive;var namespace=RegExp("(^|\\.)"+namespaces.slice().sort().join(".*\\.")+"(\\.|$)");handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||namespace.test(handler.type)){event.handler=handler;event.data=handler.data;var ret=handler.apply(this,arguments);if(ret!==undefined){event.result=ret;if(ret===false){event.preventDefault();event.stopPropagation()}}if(event.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(event){if(event[expando]){return event}var originalEvent=event;event=jQuery.Event(originalEvent);for(var i=this.props.length,prop;i;){prop=this.props[--i];event[prop]=originalEvent[prop]}if(!event.target){event.target=event.srcElement||document}if(event.target.nodeType==3){event.target=event.target.parentNode}if(!event.relatedTarget&&event.fromElement){event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement}if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0)}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode)){event.which=event.charCode||event.keyCode}if(!event.metaKey&&event.ctrlKey){event.metaKey=event.ctrlKey}if(!event.which&&event.button){event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)))}return event},proxy:function(fn,proxy){proxy=proxy||function(){return fn.apply(this,arguments)};proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy},special:{ready:{setup:bindReady,teardown:function(){}}},specialAll:{live:{setup:function(selector,namespaces){jQuery.event.add(this,namespaces[0],liveHandler)},teardown:function(namespaces){if(namespaces.length){var remove=0,name=RegExp("(^|\\.)"+namespaces[0]+"(\\.|$)");jQuery.each((jQuery.data(this,"events").live||{}),function(){if(name.test(this.type)){remove++}});if(remove<1){jQuery.event.remove(this,namespaces[0],liveHandler)}}}}}};jQuery.Event=function(src){if(!this.preventDefault){return new jQuery.Event(src)}if(src&&src.type){this.originalEvent=src;this.type=src.type}else{this.type=src}this.timeStamp=now();this[expando]=true};function returnFalse(){return false}function returnTrue(){return true}jQuery.Event.prototype={preventDefault:function(){this.isDefaultPrevented=returnTrue;var e=this.originalEvent;if(!e){return }if(e.preventDefault){e.preventDefault()}e.returnValue=false},stopPropagation:function(){this.isPropagationStopped=returnTrue;var e=this.originalEvent;if(!e){return }if(e.stopPropagation){e.stopPropagation()}e.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=returnTrue;this.stopPropagation()},isDefaultPrevented:returnFalse,isPropagationStopped:returnFalse,isImmediatePropagationStopped:returnFalse};var withinElement=function(event){var parent=event.relatedTarget;while(parent&&parent!=this){try{parent=parent.parentNode}catch(e){parent=this}}if(parent!=this){event.type=event.data;jQuery.event.handle.apply(this,arguments)}};jQuery.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(orig,fix){jQuery.event.special[fix]={setup:function(){jQuery.event.add(this,orig,withinElement,fix)},teardown:function(){jQuery.event.remove(this,orig,withinElement)}}});jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data)})},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments)});return this.each(function(){jQuery.event.add(this,type,one,fn&&data)})},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn)})},trigger:function(type,data){return this.each(function(){jQuery.event.trigger(type,data,this)})},triggerHandler:function(type,data){if(this[0]){var event=jQuery.Event(type);event.preventDefault();event.stopPropagation();jQuery.event.trigger(event,data,this[0]);return event.result}},toggle:function(fn){var args=arguments,i=1;while(i=0){var selector=url.slice(off,url.length);url=url.slice(0,off)}var type="GET";if(params){if(jQuery.isFunction(params)){callback=params;params=null}else{if(typeof params==="object"){params=jQuery.param(params);type="POST"}}}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified"){self.html(selector?jQuery("
").append(res.responseText.replace(//g,"")).find(selector):res.responseText)}if(callback){self.each(callback,[res.responseText,status,res])}}});return this},serialize:function(){return jQuery.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?jQuery.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:jQuery.isArray(val)?jQuery.map(val,function(val,i){return{name:elem.name,value:val}}):{name:elem.name,value:val}}).get()}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f)}});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type})},getScript:function(url,callback){return jQuery.get(url,null,callback,"script")},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json")},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={}}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type})},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!=="string"){s.data=jQuery.param(s.data)}if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre)){s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?"}}else{if(!s.data||!s.data.match(jsre)){s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?"}}s.dataType="json"}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data){s.data=(s.data+"").replace(jsre,"="+jsonp+"$1")}s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp]}catch(e){}if(head){head.removeChild(script)}}}if(s.dataType=="script"&&s.cache==null){s.cache=false}if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"")}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null}if(s.global&&!jQuery.active++){jQuery.event.trigger("ajaxStart")}var parts=/^(\w+:)?\/\/([^\/?#]+)/.exec(s.url);if(s.dataType=="script"&&type=="GET"&&parts&&(parts[1]&&parts[1]!=location.protocol||parts[2]!=location.host)){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset){script.charset=s.scriptCharset}if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();script.onload=script.onreadystatechange=null;head.removeChild(script)}}}head.appendChild(script);return undefined}var requestDone=false;var xhr=s.xhr();if(s.username){xhr.open(type,s.url,s.async,s.username,s.password)}else{xhr.open(type,s.url,s.async)}try{if(s.data){xhr.setRequestHeader("Content-Type",s.contentType)}if(s.ifModified){xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default)}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){if(s.global&&!--jQuery.active){jQuery.event.trigger("ajaxStop")}xhr.abort();return false}if(s.global){jQuery.event.trigger("ajaxSend",[xhr,s])}var onreadystatechange=function(isTimeout){if(xhr.readyState==0){if(ival){clearInterval(ival);ival=null;if(s.global&&!--jQuery.active){jQuery.event.trigger("ajaxStop")}}}else{if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null}status=isTimeout=="timeout"?"timeout":!jQuery.httpSuccess(xhr)?"error":s.ifModified&&jQuery.httpNotModified(xhr,s.url)?"notmodified":"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s)}catch(e){status="parsererror"}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified")}catch(e){}if(s.ifModified&&modRes){jQuery.lastModified[s.url]=modRes}if(!jsonp){success()}}else{jQuery.handleError(s,xhr,status)}complete();if(isTimeout){xhr.abort()}if(s.async){xhr=null}}}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0){setTimeout(function(){if(xhr&&!requestDone){onreadystatechange("timeout")}},s.timeout)}}try{xhr.send(s.data)}catch(e){jQuery.handleError(s,xhr,null,e)}if(!s.async){onreadystatechange()}function success(){if(s.success){s.success(data,status)}if(s.global){jQuery.event.trigger("ajaxSuccess",[xhr,s])}}function complete(){if(s.complete){s.complete(xhr,status)}if(s.global){jQuery.event.trigger("ajaxComplete",[xhr,s])}if(s.global&&!--jQuery.active){jQuery.event.trigger("ajaxStop")}}return xhr},handleError:function(s,xhr,status,e){if(s.error){s.error(xhr,status,e)}if(s.global){jQuery.event.trigger("ajaxError",[xhr,s,e])}},active:0,httpSuccess:function(xhr){try{return !xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223}catch(e){}return false},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]}catch(e){}return false},httpData:function(xhr,type,s){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror"){throw"parsererror"}if(s&&s.dataFilter){data=s.dataFilter(data,type)}if(typeof data==="string"){if(type=="script"){jQuery.globalEval(data)}if(type=="json"){data=window["eval"]("("+data+")")}}return data},param:function(a){var s=[];function add(key,value){s[s.length]=encodeURIComponent(key)+"="+encodeURIComponent(value)}if(jQuery.isArray(a)||a.jquery){jQuery.each(a,function(){add(this.name,this.value)})}else{for(var j in a){if(jQuery.isArray(a[j])){jQuery.each(a[j],function(){add(j,this)})}else{add(j,jQuery.isFunction(a[j])?a[j]():a[j])}}}return s.join("&").replace(/%20/g,"+")}});var elemdisplay={},timerId,fxAttrs=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function genFx(type,num){var obj={};jQuery.each(fxAttrs.concat.apply([],fxAttrs.slice(0,num)),function(){obj[this]=type});return obj}jQuery.fn.extend({show:function(speed,callback){if(speed){return this.animate(genFx("show",3),speed,callback)}else{for(var i=0,l=this.length;i").appendTo("body");display=elem.css("display");if(display==="none"){display="block"}elem.remove();elemdisplay[tagName]=display}jQuery.data(this[i],"olddisplay",display)}}for(var i=0,l=this.length;i=0;i--){if(timers[i].elem==this){if(gotoEnd){timers[i](true)}timers.splice(i,1)}}});if(!gotoEnd){this.dequeue()}return this}});jQuery.each({slideDown:genFx("show",1),slideUp:genFx("hide",1),slideToggle:genFx("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(name,props){jQuery.fn[name]=function(speed,callback){return this.animate(props,speed,callback)}});jQuery.extend({speed:function(speed,easing,fn){var opt=typeof speed==="object"?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&!jQuery.isFunction(easing)&&easing};opt.duration=jQuery.fx.off?0:typeof opt.duration==="number"?opt.duration:jQuery.fx.speeds[opt.duration]||jQuery.fx.speeds._default;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false){jQuery(this).dequeue()}if(jQuery.isFunction(opt.old)){opt.old.call(this)}};return opt},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum}},timers:[],fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig){options.orig={}}}});jQuery.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(force){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;var self=this;function t(gotoEnd){return self.step(gotoEnd)}t.elem=this.elem;if(t()&&jQuery.timers.push(t)&&!timerId){timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim){if(this.options.curAnim[i]!==true){done=false}}if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){jQuery(this.elem).hide()}if(this.options.hide||this.options.show){for(var p in this.options.curAnim){jQuery.attr(this.elem.style,p,this.options.orig[p])}}this.options.complete.call(this.elem)}return false}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now)},_default:function(fx){if(fx.elem.style&&fx.elem.style[fx.prop]!=null){fx.elem.style[fx.prop]=fx.now+fx.unit}else{fx.elem[fx.prop]=fx.now}}}});if(document.documentElement.getBoundingClientRect){jQuery.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return jQuery.offset.bodyOffset(this[0])}var box=this[0].getBoundingClientRect(),doc=this[0].ownerDocument,body=doc.body,docElem=doc.documentElement,clientTop=docElem.clientTop||body.clientTop||0,clientLeft=docElem.clientLeft||body.clientLeft||0,top=box.top+(self.pageYOffset||jQuery.boxModel&&docElem.scrollTop||body.scrollTop)-clientTop,left=box.left+(self.pageXOffset||jQuery.boxModel&&docElem.scrollLeft||body.scrollLeft)-clientLeft;return{top:top,left:left}}}else{jQuery.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return jQuery.offset.bodyOffset(this[0])}jQuery.offset.initialized||jQuery.offset.initialize();var elem=this[0],offsetParent=elem.offsetParent,prevOffsetParent=elem,doc=elem.ownerDocument,computedStyle,docElem=doc.documentElement,body=doc.body,defaultView=doc.defaultView,prevComputedStyle=defaultView.getComputedStyle(elem,null),top=elem.offsetTop,left=elem.offsetLeft;while((elem=elem.parentNode)&&elem!==body&&elem!==docElem){computedStyle=defaultView.getComputedStyle(elem,null);top-=elem.scrollTop,left-=elem.scrollLeft;if(elem===offsetParent){top+=elem.offsetTop,left+=elem.offsetLeft;if(jQuery.offset.doesNotAddBorder&&!(jQuery.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(elem.tagName))){top+=parseInt(computedStyle.borderTopWidth,10)||0,left+=parseInt(computedStyle.borderLeftWidth,10)||0}prevOffsetParent=offsetParent,offsetParent=elem.offsetParent}if(jQuery.offset.subtractsBorderForOverflowNotVisible&&computedStyle.overflow!=="visible"){top+=parseInt(computedStyle.borderTopWidth,10)||0,left+=parseInt(computedStyle.borderLeftWidth,10)||0}prevComputedStyle=computedStyle}if(prevComputedStyle.position==="relative"||prevComputedStyle.position==="static"){top+=body.offsetTop,left+=body.offsetLeft}if(prevComputedStyle.position==="fixed"){top+=Math.max(docElem.scrollTop,body.scrollTop),left+=Math.max(docElem.scrollLeft,body.scrollLeft)}return{top:top,left:left}}}jQuery.offset={initialize:function(){if(this.initialized){return }var body=document.body,container=document.createElement("div"),innerDiv,checkDiv,table,td,rules,prop,bodyMarginTop=body.style.marginTop,html='
';rules={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(prop in rules){container.style[prop]=rules[prop]}container.innerHTML=html;body.insertBefore(container,body.firstChild);innerDiv=container.firstChild,checkDiv=innerDiv.firstChild,td=innerDiv.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(checkDiv.offsetTop!==5);this.doesAddBorderForTableAndCells=(td.offsetTop===5);innerDiv.style.overflow="hidden",innerDiv.style.position="relative";this.subtractsBorderForOverflowNotVisible=(checkDiv.offsetTop===-5);body.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(body.offsetTop===0);body.style.marginTop=bodyMarginTop;body.removeChild(container);this.initialized=true},bodyOffset:function(body){jQuery.offset.initialized||jQuery.offset.initialize();var top=body.offsetTop,left=body.offsetLeft;if(jQuery.offset.doesNotIncludeMarginInBodyOffset){top+=parseInt(jQuery.curCSS(body,"marginTop",true),10)||0,left+=parseInt(jQuery.curCSS(body,"marginLeft",true),10)||0}return{top:top,left:left}}};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,"marginTop");offset.left-=num(this,"marginLeft");parentOffset.top+=num(offsetParent,"borderTopWidth");parentOffset.left+=num(offsetParent,"borderLeftWidth");results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left}}return results},offsetParent:function(){var offsetParent=this[0].offsetParent||document.body;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,"position")=="static")){offsetParent=offsetParent.offsetParent}return jQuery(offsetParent)}});jQuery.each(["Left","Top"],function(i,name){var method="scroll"+name;jQuery.fn[method]=function(val){if(!this[0]){return null}return val!==undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val}):this[0]==window||this[0]==document?self[i?"pageYOffset":"pageXOffset"]||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method]}});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom",lower=name.toLowerCase();jQuery.fn["inner"+name]=function(){return this[0]?jQuery.css(this[0],lower,false,"padding"):null};jQuery.fn["outer"+name]=function(margin){return this[0]?jQuery.css(this[0],lower,false,margin?"margin":"border"):null};var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(document.documentElement["client"+name],document.body["scroll"+name],document.documentElement["scroll"+name],document.body["offset"+name],document.documentElement["offset"+name]):size===undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,typeof size==="string"?size:size+"px")}})})(); \ No newline at end of file Added: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 15:06:09 2010 @@ -0,0 +1,121 @@ + +var JSON_DIR_URL; +var JSON_DIR_LIST; +if (window.location.toString().indexOf('file:///') == -1) { + JSON_DIR_URL = "bench_results/"; + JSON_DIR_LIST = JSON_DIR_URL; +} else { + JSON_DIR_URL = "test/data/"; + JSON_DIR_LIST = JSON_DIR_URL + "dir"; +} + +function Collector(revnos) +{ + this.plotdata = []; + this.counter = revnos.length; + + this.finish_collecting = function() { + this.plotdata = extract_benchmark_data(this.plotdata); + var benchnames = _.keys(this.plotdata.results); + benchnames.sort() + for (var i = 0; i < benchnames.length; ++i) { + var benchname = benchnames[i]; + var benchresults = this.plotdata.results[benchname]; + var cpystart = benchresults[0][0]; + var cpyend = benchresults[benchresults.length - 1][0]; + var cpyval = this.plotdata.cpytimes[benchname]; + var cpython_results = [[cpystart, cpyval], [cpyend, cpyval]] + $("#placeholder").append("

" + benchname + "

"); + $("#placeholder").append("
"); + $.plot($("#placeholder").children(":last"), [benchresults, cpython_results], { + 'series': { + 'points': {'show': true}, + 'lines' : {'show': true}, + }, + 'xaxis': { + 'min': 70630, + 'max': revnos[revnos.length - 1], + 'tickDecimals': 0, + }, + 'yaxis': { + 'min': 0, + } + }); + } + } + + this.collect = function(next) { + this.plotdata.push(next); + this.counter--; + if (this.counter == 0) { + this.finish_collecting() + } + } +} + +$(document).ready(function() { + $.ajax({ + url: JSON_DIR_LIST, + dataType: 'xml', + success: function(xmldoc) { + var revnos = extract_revnos(xmldoc); + collector = new Collector(revnos); + for (var i in revnos) { + $.getJSON(JSON_DIR_URL + revnos[i] + '.json', function(data) { + collector.collect(data) + }); + } + }, + error: function (a, b, c) { + console.log(a, b, c); + }, + }); +}); + +function extract_benchmark_data(data) +{ + var retval = {}; + var cpytimes = {}; + for (var i = 0; i < data.length; i++) { + var revno = data[i]["revision"]; + var results = data[i]["results"]; + for (var j = 0; j < results.length; j++) { + var result = results[j]; + var name = result[0]; + var dataelem = result[2]; + var avg; + if (dataelem["avg_changed"]) { + avg = dataelem["avg_changed"]; + } else { + avg = dataelem["changed_time"]; + } + if (retval[name]) { + retval[name].push([revno, avg]); + } else { + retval[name] = [[revno, avg]]; + } + } + } + var cpyelem = data[data.length - 1] + for (var i = 0; i < cpyelem.results.length; i++) { + var dataelem = cpyelem.results[i][2]; + var benchname = cpyelem.results[i][0]; + if (dataelem.avg_base) { + cpytimes[benchname] = dataelem.avg_base; + } else { + cpytimes[benchname] = dataelem.base_time; + } + } + return {'results': retval, 'cpytimes': cpytimes}; +} + +function extract_revnos(xmldoc) +{ + var res = []; + $(xmldoc).find("a").each(function (no, elem) { + var s = elem.getAttribute("href"); + s = s.substr(0, s.length - ".json".length); + res.push(s); + }); + return res; +} \ No newline at end of file Added: pypy/build/bot2/jsplot/js/underscore-min.js ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/js/underscore-min.js Sun Jan 17 15:06:09 2010 @@ -0,0 +1,16 @@ +(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;gf?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)}); +return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length); +var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false; +if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length== +0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&& +a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g, +" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments); +o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})(); Added: pypy/build/bot2/jsplot/plot.html ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/plot.html Sun Jan 17 15:06:09 2010 @@ -0,0 +1,11 @@ + + + + + + + + + +
+ Added: pypy/build/bot2/jsplot/test/__init__.py ============================================================================== Added: pypy/build/bot2/jsplot/test/data/70632.json ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/test/data/70632.json Sun Jan 17 15:06:09 2010 @@ -0,0 +1 @@ +{"revision":70632, "results":[["ai", "ComparisonResult", {"avg_base": 0.42823686599739996, "timeline_link": null, "avg_changed": 0.43707809448220003, "min_base": 0.42468714714099998, "delta_min": "1.0062x faster", "delta_avg": "1.0206x slower", "std_changed": 0.012726005818366633, "min_changed": 0.42208003997799998, "delta_std": "3.0650x larger", "std_base": 0.0041520307422265711, "t_msg": "Not significant\n"}], ["django", "ComparisonResult", {"avg_base": 0.81657519340500007, "timeline_link": null, "avg_changed": 0.65519900321960001, "min_base": 0.81266403198199999, "delta_min": "1.2518x faster", "delta_avg": "1.2463x faster", "std_changed": 0.0044952507320305752, "min_changed": 0.64918088913000005, "delta_std": "1.3942x larger", "std_base": 0.0032243551665939603, "t_msg": "Significant (t=65.228467, a=0.95)\n"}], ["html5lib", "SimpleComparisonResult", {"changed_time": 18.343158960299998, "base_time": 11.615580081899999, "time_delta": "1.5792x slower"}], ["richards", "ComparisonResult", {"avg_base": 0.29711527824419998, "timeline_link": null, "avg_changed": 0.02986998558044, "min_base": 0.294907093048, "delta_min": "10.4659x faster", "delta_avg": "9.9470x faster", "std_changed": 0.0026994059044399363, "min_changed": 0.028177976608300001, "delta_std": "1.6112x larger", "std_base": 0.0016753501652075743, "t_msg": "Significant (t=188.092824, a=0.95)\n"}], ["rietveld", "ComparisonResult", {"avg_base": 0.48722739219679995, "timeline_link": null, "avg_changed": 1.3687530040759999, "min_base": 0.47341489791899999, "delta_min": "2.2269x slower", "delta_avg": "2.8093x slower", "std_changed": 0.43258857662553413, "min_changed": 1.05424904823, "delta_std": "32.5706x larger", "std_base": 0.013281575319855547, "t_msg": "Significant (t=-4.554496, a=0.95)\n"}], ["slowspitfire", "ComparisonResult", {"avg_base": 0.66682476997380002, "timeline_link": null, "avg_changed": 1.9608736038200001, "min_base": 0.65954208374000001, "delta_min": "2.8464x slower", "delta_avg": "2.9406x slower", "std_changed": 0.083228077676869266, "min_changed": 1.8772940635699999, "delta_std": "7.3959x larger", "std_base": 0.011253331550362244, "t_msg": "Significant (t=-34.453376, a=0.95)\n"}], ["spambayes", "ComparisonResult", {"avg_base": 0.277250432968, "timeline_link": null, "avg_changed": 1.2217754364019999, "min_base": 0.271551132202, "delta_min": "4.2001x slower", "delta_avg": "4.4068x slower", "std_changed": 0.049996851857427985, "min_changed": 1.1405501365699999, "delta_std": "6.7173x larger", "std_base": 0.0074429714916756269, "t_msg": "Significant (t=-41.782647, a=0.95)\n"}]]} \ No newline at end of file Added: pypy/build/bot2/jsplot/test/data/70634.json ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/test/data/70634.json Sun Jan 17 15:06:09 2010 @@ -0,0 +1 @@ +{"revision": 70634, "results":[["ai", "ComparisonResult", {"avg_base": 0.43372206687940001, "timeline_link": null, "avg_changed": 0.42492904663079994, "min_base": 0.42877793312099999, "delta_min": "1.0313x faster", "delta_avg": "1.0207x faster", "std_changed": 0.009510401166913986, "min_changed": 0.41575694084199999, "delta_std": "1.7992x larger", "std_base": 0.0052859436702026143, "t_msg": "Not significant\n"}], ["django", "ComparisonResult", {"avg_base": 0.83942761421200007, "timeline_link": null, "avg_changed": 0.62576680183400002, "min_base": 0.82347989082299999, "delta_min": "1.3384x faster", "delta_avg": "1.3414x faster", "std_changed": 0.0077531344140589591, "min_changed": 0.61528992652900005, "delta_std": "1.3344x smaller", "std_base": 0.010345945675069074, "t_msg": "Significant (t=36.953629, a=0.95)\n"}], ["html5lib", "SimpleComparisonResult", {"changed_time": 18.203540086699999, "base_time": 11.7523989677, "time_delta": "1.5489x slower"}], ["richards", "ComparisonResult", {"avg_base": 0.29309725761400002, "timeline_link": null, "avg_changed": 0.029346752166760005, "min_base": 0.29079818725599998, "delta_min": "10.7564x faster", "delta_avg": "9.9874x faster", "std_changed": 0.0027569315381777483, "min_changed": 0.027034997940099999, "delta_std": "1.3414x smaller", "std_base": 0.0036981163367189014, "t_msg": "Significant (t=127.857380, a=0.95)\n"}], ["rietveld", "ComparisonResult", {"avg_base": 0.48451652526860001, "timeline_link": null, "avg_changed": 1.349235057832, "min_base": 0.47784495353700002, "delta_min": "2.1482x slower", "delta_avg": "2.7847x slower", "std_changed": 0.39820665365252833, "min_changed": 1.026512146, "delta_std": "103.2980x larger", "std_base": 0.003854932363801519, "t_msg": "Significant (t=-4.855466, a=0.95)\n"}], ["slowspitfire", "ComparisonResult", {"avg_base": 0.68639717102039999, "timeline_link": null, "avg_changed": 1.9761237621299999, "min_base": 0.68470287323000001, "delta_min": "2.7438x slower", "delta_avg": "2.8790x slower", "std_changed": 0.094537985877850755, "min_changed": 1.8786580562599999, "delta_std": "76.8531x larger", "std_base": 0.0012301131045974209, "t_msg": "Significant (t=-30.502789, a=0.95)\n"}], ["spambayes", "ComparisonResult", {"avg_base": 0.26852898597700003, "timeline_link": null, "avg_changed": 1.3172614097599999, "min_base": 0.26705503463699998, "delta_min": "4.7040x slower", "delta_avg": "4.9055x slower", "std_changed": 0.044204769473703283, "min_changed": 1.25622391701, "delta_std": "50.6624x larger", "std_base": 0.00087253630828077724, "t_msg": "Significant (t=-53.039080, a=0.95)\n"}]]} \ No newline at end of file Added: pypy/build/bot2/jsplot/test/data/70641.json ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/test/data/70641.json Sun Jan 17 15:06:09 2010 @@ -0,0 +1 @@ +{"results": [["ai", "ComparisonResult", {"avg_base": 0.43650860786439993, "timeline_link": null, "avg_changed": 0.442705011368, "min_base": 0.43069100379899999, "delta_min": "1.0218x faster", "delta_avg": "1.0142x slower", "std_changed": 0.015176545588180972, "min_changed": 0.42150688171400003, "delta_std": "2.5562x larger", "std_base": 0.0059370583842187344, "t_msg": "Not significant\n"}], ["django", "ComparisonResult", {"avg_base": 0.82169790267940002, "timeline_link": null, "avg_changed": 0.69898595809920006, "min_base": 0.82027697563199997, "delta_min": "1.2968x faster", "delta_avg": "1.1756x faster", "std_changed": 0.081716119057663919, "min_changed": 0.632531881332, "delta_std": "70.6753x larger", "std_base": 0.0011562181374290186, "t_msg": "Significant (t=3.357536, a=0.95)\n"}], ["html5lib", "SimpleComparisonResult", {"changed_time": 19.623087883, "base_time": 11.959173917799999, "time_delta": "1.6408x slower"}], ["richards", "ComparisonResult", {"avg_base": 0.29512224197420001, "timeline_link": null, "avg_changed": 0.03177919387816, "min_base": 0.29339599609400002, "delta_min": "10.2271x faster", "delta_avg": "9.2866x faster", "std_changed": 0.0037892084532554202, "min_changed": 0.0286881923676, "delta_std": "2.1989x larger", "std_base": 0.0017232000359110658, "t_msg": "Significant (t=141.461633, a=0.95)\n"}], ["rietveld", "ComparisonResult", {"avg_base": 0.48070883750920002, "timeline_link": null, "avg_changed": 1.3538511276240002, "min_base": 0.47538614273099999, "delta_min": "2.2605x slower", "delta_avg": "2.8164x slower", "std_changed": 0.40768328834823436, "min_changed": 1.0746278762799999, "delta_std": "70.0786x larger", "std_base": 0.0058175149551189928, "t_msg": "Significant (t=-4.788538, a=0.95)\n"}], ["slowspitfire", "ComparisonResult", {"avg_base": 0.68758621215799998, "timeline_link": null, "avg_changed": 2.0196122646339996, "min_base": 0.68043398857100001, "delta_min": "2.7618x slower", "delta_avg": "2.9372x slower", "std_changed": 0.13523633539200772, "min_changed": 1.8791980743400001, "delta_std": "23.2725x larger", "std_base": 0.0058109989882230159, "t_msg": "Significant (t=-22.004108, a=0.95)\n"}], ["spambayes", "ComparisonResult", {"avg_base": 0.2701356887818, "timeline_link": null, "avg_changed": 1.2326191902160002, "min_base": 0.267970085144, "delta_min": "4.2299x slower", "delta_avg": "4.5630x slower", "std_changed": 0.067582750181015727, "min_changed": 1.1334869861600001, "delta_std": "42.1671x larger", "std_base": 0.0016027373677103658, "t_msg": "Significant (t=-31.836135, a=0.95)\n"}]], "revision": 70641} \ No newline at end of file Added: pypy/build/bot2/jsplot/test/data/70643.json ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/test/data/70643.json Sun Jan 17 15:06:09 2010 @@ -0,0 +1 @@ +{"results": [["ai", "ComparisonResult", {"avg_base": 0.43415923118599997, "timeline_link": null, "avg_changed": 0.42739782333359999, "min_base": 0.43198704719499997, "delta_min": "1.0438x faster", "delta_avg": "1.0158x faster", "std_changed": 0.012272627488689064, "min_changed": 0.41386795043899999, "delta_std": "8.6560x larger", "std_base": 0.0014178186351363352, "t_msg": "Not significant\n"}], ["django", "ComparisonResult", {"avg_base": 0.80989360809299993, "timeline_link": null, "avg_changed": 0.64163026809680002, "min_base": 0.80630898475599999, "delta_min": "1.2782x faster", "delta_avg": "1.2622x faster", "std_changed": 0.0070227567315648241, "min_changed": 0.63079690933200006, "delta_std": "1.9215x larger", "std_base": 0.0036548835689524232, "t_msg": "Significant (t=47.524704, a=0.95)\n"}], ["html5lib", "SimpleComparisonResult", {"changed_time": 18.129413127900001, "base_time": 11.712361812599999, "time_delta": "1.5479x slower"}], ["richards", "ComparisonResult", {"avg_base": 0.29192314147940002, "timeline_link": null, "avg_changed": 0.031384038925180005, "min_base": 0.29025983810400002, "delta_min": "10.0443x faster", "delta_avg": "9.3016x faster", "std_changed": 0.0033156199941110453, "min_changed": 0.028898000717200001, "delta_std": "1.7606x larger", "std_base": 0.0018831865621822721, "t_msg": "Significant (t=152.784670, a=0.95)\n"}], ["rietveld", "ComparisonResult", {"avg_base": 0.47546410560600005, "timeline_link": null, "avg_changed": 1.3880088329339997, "min_base": 0.47204089164700003, "delta_min": "2.2544x slower", "delta_avg": "2.9193x slower", "std_changed": 0.41629770389242476, "min_changed": 1.0641720294999999, "delta_std": "74.3362x larger", "std_base": 0.0056001993932710452, "t_msg": "Significant (t=-4.901126, a=0.95)\n"}], ["slowspitfire", "ComparisonResult", {"avg_base": 0.67803196907039998, "timeline_link": null, "avg_changed": 1.977389001848, "min_base": 0.67243814468399998, "delta_min": "2.8218x slower", "delta_avg": "2.9164x slower", "std_changed": 0.063083968572716406, "min_changed": 1.8974800109900001, "delta_std": "7.9309x larger", "std_base": 0.0079542505357995189, "t_msg": "Significant (t=-45.695065, a=0.95)\n"}], ["spambayes", "ComparisonResult", {"avg_base": 0.28002071380620003, "timeline_link": null, "avg_changed": 1.2374196052540001, "min_base": 0.27349185943600002, "delta_min": "4.1977x slower", "delta_avg": "4.4190x slower", "std_changed": 0.054718960566834438, "min_changed": 1.14803814888, "delta_std": "4.3112x larger", "std_base": 0.012692302234967961, "t_msg": "Significant (t=-38.111883, a=0.95)\n"}]], "revision": 70643} \ No newline at end of file Added: pypy/build/bot2/jsplot/test/data/dir ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/test/data/dir Sun Jan 17 15:06:09 2010 @@ -0,0 +1,55 @@ + + + + + Directory listing for /bench_results/ + + + +

Directory listing for /bench_results/ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FilenameContent typeContent encoding
70632.json[text/html]
70634.json[text/html]
70641.json[text/html]
70643.json[text/html]
+ + \ No newline at end of file Added: pypy/build/bot2/jsplot/test/data/revnos.json ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/test/data/revnos.json Sun Jan 17 15:06:09 2010 @@ -0,0 +1 @@ +[70632, 70634, 70641, 70643] \ No newline at end of file Added: pypy/build/bot2/jsplot/test/jstest_one_any.js ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/test/jstest_one_any.js Sun Jan 17 15:06:09 2010 @@ -0,0 +1,48 @@ + +OpenEnd.require("/js/plot.js") +OpenEnd.require("/js/jquery.min.js") +OpenEnd.require("/js/underscore-min.js") + +Tests = { +test_load_data: function() { + var revnos = [70632, 70634]; + var loaded_data = []; + for (var i in revnos) { + $.ajax({ + url: '/test/data/' + revnos[i] + '.json', + dataType: 'json', + success: function(result) { + loaded_data.push(result); + }, + async: false + }); + } + var bench_data = extract_benchmark_data(loaded_data); + aisDeeply(bench_data.results.ai, [[70632, 0.43707809448220003], + [70634, 0.42492904663079994]]); + var benchnames = _.keys(bench_data.results); + benchnames.sort(); + var expected_keys = ['ai', "django", "html5lib", "richards", "rietveld", + "slowspitfire", "spambayes"] + aisDeeply(benchnames, expected_keys); + var benchnames = _.keys(bench_data.cpytimes); + benchnames.sort(); + aisDeeply(benchnames, expected_keys); + ais(bench_data.cpytimes.ai, 0.43372206687940001); +}, + +test_extract_revnos: function() { + var dirdoc; + $.ajax({ + url: "/test/data/dir", + contentType: "text/xml", + dataType: "xml", + success: function (result) { + dirdoc = result; + }, + async: false, + }); + var revnos = extract_revnos(dirdoc); + aisDeeply(revnos, [70632, 70634, 70641, 70643]); +} +} From fijal at codespeak.net Sun Jan 17 15:06:43 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 15:06:43 +0100 (CET) Subject: [pypy-svn] r70653 - pypy/build/bot2/codespeak-html Message-ID: <20100117140643.02614168011@codespeak.net> Author: fijal Date: Sun Jan 17 15:06:43 2010 New Revision: 70653 Added: pypy/build/bot2/codespeak-html/css (contents, props changed) pypy/build/bot2/codespeak-html/js (contents, props changed) pypy/build/bot2/codespeak-html/plot.html (contents, props changed) Log: (pedronis, fijal) Add symlinks to plot Added: pypy/build/bot2/codespeak-html/css ============================================================================== --- (empty file) +++ pypy/build/bot2/codespeak-html/css Sun Jan 17 15:06:43 2010 @@ -0,0 +1 @@ +link ../jsplot/css/ \ No newline at end of file Added: pypy/build/bot2/codespeak-html/js ============================================================================== --- (empty file) +++ pypy/build/bot2/codespeak-html/js Sun Jan 17 15:06:43 2010 @@ -0,0 +1 @@ +link ../jsplot/js/ \ No newline at end of file Added: pypy/build/bot2/codespeak-html/plot.html ============================================================================== --- (empty file) +++ pypy/build/bot2/codespeak-html/plot.html Sun Jan 17 15:06:43 2010 @@ -0,0 +1 @@ +link ../jsplot/plot.html \ No newline at end of file From fijal at codespeak.net Sun Jan 17 15:21:35 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 15:21:35 +0100 (CET) Subject: [pypy-svn] r70654 - in pypy/build/bot2/jsplot: js test Message-ID: <20100117142135.2812D16801B@codespeak.net> Author: fijal Date: Sun Jan 17 15:21:34 2010 New Revision: 70654 Modified: pypy/build/bot2/jsplot/js/plot.js pypy/build/bot2/jsplot/test/jstest_one_any.js Log: (pedronis, fijal) A hack not to require text/xml on directory listings Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 15:21:34 2010 @@ -56,9 +56,9 @@ $(document).ready(function() { $.ajax({ url: JSON_DIR_LIST, - dataType: 'xml', - success: function(xmldoc) { - var revnos = extract_revnos(xmldoc); + dataType: 'html', + success: function(htmlstr) { + var revnos = extract_revnos($(htmlstr)); collector = new Collector(revnos); for (var i in revnos) { $.getJSON(JSON_DIR_URL + revnos[i] + '.json', function(data) { Modified: pypy/build/bot2/jsplot/test/jstest_one_any.js ============================================================================== --- pypy/build/bot2/jsplot/test/jstest_one_any.js (original) +++ pypy/build/bot2/jsplot/test/jstest_one_any.js Sun Jan 17 15:21:34 2010 @@ -36,9 +36,9 @@ $.ajax({ url: "/test/data/dir", contentType: "text/xml", - dataType: "xml", + dataType: "html", success: function (result) { - dirdoc = result; + dirdoc = $(result); }, async: false, }); From fijal at codespeak.net Sun Jan 17 15:23:49 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 15:23:49 +0100 (CET) Subject: [pypy-svn] r70655 - pypy/build/bot2/jsplot/test/data Message-ID: <20100117142349.9A5B016801B@codespeak.net> Author: fijal Date: Sun Jan 17 15:23:49 2010 New Revision: 70655 Removed: pypy/build/bot2/jsplot/test/data/revnos.json Log: (pedronis, fijal) Nobody is using this file any more From fijal at codespeak.net Sun Jan 17 15:38:02 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 15:38:02 +0100 (CET) Subject: [pypy-svn] r70656 - in pypy/build/bot2/jsplot: js test Message-ID: <20100117143802.9EE4516801B@codespeak.net> Author: fijal Date: Sun Jan 17 15:38:02 2010 New Revision: 70656 Modified: pypy/build/bot2/jsplot/js/plot.js pypy/build/bot2/jsplot/test/jstest_one_any.js Log: (pedronis, fijal) Improve situation in case data does not come in order Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 15:38:02 2010 @@ -76,8 +76,14 @@ { var retval = {}; var cpytimes = {}; + var lastrev = 0; + var lastrevindex = 0; for (var i = 0; i < data.length; i++) { var revno = data[i]["revision"]; + if (revno > lastrev) { + lastrev = revno; + lastrevindex = i; + } var results = data[i]["results"]; for (var j = 0; j < results.length; j++) { var result = results[j]; @@ -96,7 +102,16 @@ } } } - var cpyelem = data[data.length - 1] + for (var name in retval) { + retval[name].sort(function (a, b) { + if (a[0] > b[0]) { + return 1; + } else { + return -1; + } + }); + } + var cpyelem = data[lastrevindex] for (var i = 0; i < cpyelem.results.length; i++) { var dataelem = cpyelem.results[i][2]; var benchname = cpyelem.results[i][0]; Modified: pypy/build/bot2/jsplot/test/jstest_one_any.js ============================================================================== --- pypy/build/bot2/jsplot/test/jstest_one_any.js (original) +++ pypy/build/bot2/jsplot/test/jstest_one_any.js Sun Jan 17 15:38:02 2010 @@ -5,7 +5,7 @@ Tests = { test_load_data: function() { - var revnos = [70632, 70634]; + var revnos = [70634, 70632]; var loaded_data = []; for (var i in revnos) { $.ajax({ From arigo at codespeak.net Sun Jan 17 16:21:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 17 Jan 2010 16:21:02 +0100 (CET) Subject: [pypy-svn] r70657 - in pypy/branch/c-traceback/pypy/translator: . c/test Message-ID: <20100117152102.06C6F16801B@codespeak.net> Author: arigo Date: Sun Jan 17 16:21:02 2010 New Revision: 70657 Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py pypy/branch/c-traceback/pypy/translator/exceptiontransform.py Log: Hack until 'test_fatal_error_finally' passes. Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Sun Jan 17 16:21:02 2010 @@ -421,7 +421,7 @@ try: g(x) finally: - print 'done.' + os.write(1, 'done.\n') def entry_point(argv): if len(argv) < 3: h(len(argv)) @@ -432,14 +432,12 @@ assert out.strip() == 'done.' lines = err.strip().splitlines() assert lines[-1] == 'Fatal RPython error: KeyError' - assert len(lines) >= 6 - l0, l1, l2, l3, l4 = lines[-6:-1] + assert len(lines) >= 5 + l0, l1, l2, l3 = lines[-5:-1] assert l0 == 'RPython traceback:' assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) assert re.match(r' File "\w+.c", line \d+, in pypy_g_h', l2) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_h', l3) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l4) - assert l2 != l3 # different line number + assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l3) def test_assertion_error(self): def g(x): Modified: pypy/branch/c-traceback/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/exceptiontransform.py (original) +++ pypy/branch/c-traceback/pypy/translator/exceptiontransform.py Sun Jan 17 16:21:02 2010 @@ -3,11 +3,10 @@ from pypy.translator.unsimplify import insert_empty_block, split_block from pypy.translator.backendopt import canraise, inline, support, removenoops from pypy.objspace.flow.model import Block, Constant, Variable, Link, \ - c_last_exception, SpaceOperation, checkgraph, FunctionGraph + c_last_exception, SpaceOperation, checkgraph, FunctionGraph, mkentrymap from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem import lloperation -from pypy.rpython.lltypesystem.llmemory import NULL from pypy.rpython import rtyper from pypy.rpython import rclass from pypy.rpython.rmodel import inputconst @@ -27,7 +26,7 @@ lltype.Char: chr(255), lltype.UniChar: unichr(0xFFFF), # XXX is this always right? lltype.Bool: True, - llmemory.Address: NULL, + llmemory.Address: llmemory.NULL, lltype.Void: None} for TYPE in rffi.NUMBER_TYPES: @@ -92,6 +91,10 @@ exc_data.exc_value = evalue lloperation.llop.debug_start_traceback(lltype.Void) + def rpyexc_reraise(etype, evalue): + exc_data.exc_type = etype + exc_data.exc_value = evalue + def rpyexc_fetch_exception(): evalue = rpyexc_fetch_value() rpyexc_clear() @@ -132,6 +135,13 @@ lltype.Void, jitcallkind='rpyexc_raise') # for the JIT + self.rpyexc_reraise_ptr = self.build_func( + "RPyReRaiseException", + rpyexc_reraise, + [self.lltype_of_exception_type, self.lltype_of_exception_value], + lltype.Void, + jitcallkind='rpyexc_raise') # for the JIT + self.rpyexc_raise_runtime_error_ptr = self.build_func( "RPyRaiseRuntimeError", self.noinline(rpyexc_raise_runtime_error), @@ -197,10 +207,15 @@ # collect the blocks before changing them n_need_exc_matching_blocks = 0 n_gen_exc_checks = 0 + # + entrymap = mkentrymap(graph) + if graph.exceptblock in entrymap: + for link in entrymap[graph.exceptblock]: + self.transform_jump_to_except_block(graph, entrymap, link) + # for block in list(graph.iterblocks()): self.replace_stack_unwind(block) self.replace_fetch_restore_operations(block) - self.transform_jump_to_except_block(graph, block.exits) need_exc_matching, gen_exc_checks = self.transform_block(graph, block) n_need_exc_matching_blocks += need_exc_matching n_gen_exc_checks += gen_exc_checks @@ -281,23 +296,55 @@ self.insert_matching(lastblock, graph) return need_exc_matching, n_gen_exc_checks - def transform_jump_to_except_block(self, graph, exits): - for link in exits: - if link.target is graph.exceptblock: - result = Variable() - result.concretetype = lltype.Void - block = Block([copyvar(None, v) - for v in graph.exceptblock.inputargs]) - block.operations = [ - SpaceOperation("direct_call", - [self.rpyexc_raise_ptr] + block.inputargs, - result), - SpaceOperation('debug_record_traceback', [], - varoftype(lltype.Void))] - link.target = block - RETTYPE = graph.returnblock.inputargs[0].concretetype - l = Link([error_constant(RETTYPE)], graph.returnblock) - block.recloseblock(l) + def comes_from_last_exception(self, entrymap, link): + block = link.prevblock + v = link.args[1] + seen = {} + pending = [(block, v)] + while pending: + block, v = pending.pop() + if (block, v) in seen: + continue + seen[block, v] = True + for op in block.operations[::-1]: + if v is op.result: + if op.opname == 'cast_pointer': + v = op.args[0] + else: + break + else: + for link in entrymap.get(block, ()): + if link.prevblock is not None: + for inputarg, outputarg in zip(link.args, + block.inputargs): + if outputarg is v: + if inputarg is link.last_exc_value: + return True + pending.append((link.prevblock, inputarg)) + return False + + def transform_jump_to_except_block(self, graph, entrymap, link): + reraise = self.comes_from_last_exception(entrymap, link) + if reraise: + fnptr = self.rpyexc_reraise_ptr + else: + fnptr = self.rpyexc_raise_ptr + result = Variable() + result.concretetype = lltype.Void + block = Block([copyvar(None, v) + for v in graph.exceptblock.inputargs]) + block.operations = [ + SpaceOperation("direct_call", + [fnptr] + block.inputargs, + result)] + if not reraise: + block.operations.append( + SpaceOperation('debug_record_traceback', [], + varoftype(lltype.Void))) + link.target = block + RETTYPE = graph.returnblock.inputargs[0].concretetype + l = Link([error_constant(RETTYPE)], graph.returnblock) + block.recloseblock(l) def insert_matching(self, block, graph): proxygraph, op = self.create_proxy_graph(block.operations[-1]) From fijal at codespeak.net Sun Jan 17 17:01:39 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 17:01:39 +0100 (CET) Subject: [pypy-svn] r70658 - in pypy/build/bot2/jsplot: css js test Message-ID: <20100117160139.0382B16800D@codespeak.net> Author: fijal Date: Sun Jan 17 17:01:39 2010 New Revision: 70658 Modified: pypy/build/bot2/jsplot/css/main.css pypy/build/bot2/jsplot/js/plot.js pypy/build/bot2/jsplot/test/jstest_one_any.js Log: Refactor things and improve testing coverage Modified: pypy/build/bot2/jsplot/css/main.css ============================================================================== --- pypy/build/bot2/jsplot/css/main.css (original) +++ pypy/build/bot2/jsplot/css/main.css Sun Jan 17 17:01:39 2010 @@ -3,3 +3,7 @@ width: 600px; height: 300px; } +.caption { + font-size: 14pt; + font-family: Verdana; +} Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 17:01:39 2010 @@ -25,22 +25,7 @@ var cpyend = benchresults[benchresults.length - 1][0]; var cpyval = this.plotdata.cpytimes[benchname]; var cpython_results = [[cpystart, cpyval], [cpyend, cpyval]] - $("#placeholder").append("

" + benchname + "

"); - $("#placeholder").append("
"); - $.plot($("#placeholder").children(":last"), [benchresults, cpython_results], { - 'series': { - 'points': {'show': true}, - 'lines' : {'show': true}, - }, - 'xaxis': { - 'min': 70630, - 'max': revnos[revnos.length - 1], - 'tickDecimals': 0, - }, - 'yaxis': { - 'min': 0, - } - }); + this.plot(benchname, benchresults, cpython_results) } } @@ -53,23 +38,61 @@ } } -$(document).ready(function() { +function myplot(benchname, benchresults, cpython_results) { + $("#placeholder").append("

" + benchname + "

"); + $("#placeholder").append("
"); + var plotinput = [{ + label: 'pypy-c-jit', + data : benchresults, + }, + { + label: 'cpython', + data : cpython_results + }]; + $.plot($("#placeholder").children(":last"), plotinput, { + 'series': { + 'points': {'show': true}, + 'lines' : {'show': true}, + }, + 'xaxis': { + 'min': 70630, + 'tickDecimals': 0, + }, + 'yaxis': { + 'min': 0, + }, + 'legend' : { + 'position' : 'sw' + } + }); +} + +function collect_data(plot_function, revlist_url, base_url, async) +{ $.ajax({ - url: JSON_DIR_LIST, + url: revlist_url, dataType: 'html', success: function(htmlstr) { var revnos = extract_revnos($(htmlstr)); - collector = new Collector(revnos); + var collector = new Collector(revnos); + collector.plot = plot_function; for (var i in revnos) { - $.getJSON(JSON_DIR_URL + revnos[i] + '.json', function(data) { + $.ajax({ + url: base_url + revnos[i] + '.json', + success: function(data) { collector.collect(data) + }, + dataType: 'json', + async: async, }); } }, - error: function (a, b, c) { - console.log(a, b, c); - }, + async: async, }); +} + +$(document).ready(function() { + collect_data(myplot, JSON_DIR_LIST, JSON_DIR_URL, true); }); function extract_benchmark_data(data) Modified: pypy/build/bot2/jsplot/test/jstest_one_any.js ============================================================================== --- pypy/build/bot2/jsplot/test/jstest_one_any.js (original) +++ pypy/build/bot2/jsplot/test/jstest_one_any.js Sun Jan 17 17:01:39 2010 @@ -3,8 +3,11 @@ OpenEnd.require("/js/jquery.min.js") OpenEnd.require("/js/underscore-min.js") +var expected_benchnames = ['ai', "django", "html5lib", "richards", "rietveld", + "slowspitfire", "spambayes"] + Tests = { -test_load_data: function() { +test_extract_benchmark_data: function() { var revnos = [70634, 70632]; var loaded_data = []; for (var i in revnos) { @@ -22,12 +25,10 @@ [70634, 0.42492904663079994]]); var benchnames = _.keys(bench_data.results); benchnames.sort(); - var expected_keys = ['ai', "django", "html5lib", "richards", "rietveld", - "slowspitfire", "spambayes"] - aisDeeply(benchnames, expected_keys); + aisDeeply(benchnames, expected_benchnames); var benchnames = _.keys(bench_data.cpytimes); benchnames.sort(); - aisDeeply(benchnames, expected_keys); + aisDeeply(benchnames, expected_benchnames); ais(bench_data.cpytimes.ai, 0.43372206687940001); }, @@ -44,5 +45,21 @@ }); var revnos = extract_revnos(dirdoc); aisDeeply(revnos, [70632, 70634, 70641, 70643]); +}, + +test_collect_data: function() { + var checkdata; + var benchnames = []; + function check(benchname, benchresults, cpyresults) { + benchnames.push(benchname); + if (benchname == "html5lib") { + checkdata = [benchresults, cpyresults]; + } + } + collect_data(check, "/test/data/dir", "/test/data/", false); + aisDeeply(benchnames, expected_benchnames); + aisDeeply(checkdata, [[[70632, 18.3431589603], [70634, 18.2035400867], + [70641, 19.623087883], [70643, 18.1294131279]], + [[70632, 11.7123618126], [70643, 11.7123618126]]]); } } From fijal at codespeak.net Sun Jan 17 17:29:02 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 17:29:02 +0100 (CET) Subject: [pypy-svn] r70659 - in pypy/build/bot2/jsplot: . js test Message-ID: <20100117162902.CD0EB168012@codespeak.net> Author: fijal Date: Sun Jan 17 17:29:02 2010 New Revision: 70659 Added: pypy/build/bot2/jsplot/js/collect.js pypy/build/bot2/jsplot/test/jstest_collect_any.js - copied, changed from r70658, pypy/build/bot2/jsplot/test/jstest_one_any.js Removed: pypy/build/bot2/jsplot/test/jstest_one_any.js Modified: pypy/build/bot2/jsplot/js/plot.js pypy/build/bot2/jsplot/plot.html Log: Rename and move stuff around Added: pypy/build/bot2/jsplot/js/collect.js ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/js/collect.js Sun Jan 17 17:29:02 2010 @@ -0,0 +1,116 @@ + +function Collector(revnos) +{ + this.plotdata = []; + this.counter = revnos.length; + + this.finish_collecting = function() { + this.plotdata = extract_benchmark_data(this.plotdata); + var benchnames = _.keys(this.plotdata.results); + benchnames.sort() + for (var i = 0; i < benchnames.length; ++i) { + var benchname = benchnames[i]; + var benchresults = this.plotdata.results[benchname]; + var cpystart = benchresults[0][0]; + var cpyend = benchresults[benchresults.length - 1][0]; + var cpyval = this.plotdata.cpytimes[benchname]; + var cpython_results = [[cpystart, cpyval], [cpyend, cpyval]] + this.plot(benchname, benchresults, cpython_results) + } + } + + this.collect = function(next) { + this.plotdata.push(next); + this.counter--; + if (this.counter == 0) { + this.finish_collecting() + } + } +} + +function collect_data(plot_function, revlist_url, base_url, async) +{ + $.ajax({ + url: revlist_url, + dataType: 'html', + success: function(htmlstr) { + var revnos = extract_revnos($(htmlstr)); + var collector = new Collector(revnos); + collector.plot = plot_function; + for (var i in revnos) { + $.ajax({ + url: base_url + revnos[i] + '.json', + success: function(data) { + collector.collect(data) + }, + dataType: 'json', + async: async, + }); + } + }, + async: async, + }); +} + +function extract_benchmark_data(data) +{ + var retval = {}; + var cpytimes = {}; + var lastrev = 0; + var lastrevindex = 0; + for (var i = 0; i < data.length; i++) { + var revno = data[i]["revision"]; + if (revno > lastrev) { + lastrev = revno; + lastrevindex = i; + } + var results = data[i]["results"]; + for (var j = 0; j < results.length; j++) { + var result = results[j]; + var name = result[0]; + var dataelem = result[2]; + var avg; + if (dataelem["avg_changed"]) { + avg = dataelem["avg_changed"]; + } else { + avg = dataelem["changed_time"]; + } + if (retval[name]) { + retval[name].push([revno, avg]); + } else { + retval[name] = [[revno, avg]]; + } + } + } + for (var name in retval) { + retval[name].sort(function (a, b) { + if (a[0] > b[0]) { + return 1; + } else { + return -1; + } + }); + } + var cpyelem = data[lastrevindex] + for (var i = 0; i < cpyelem.results.length; i++) { + var dataelem = cpyelem.results[i][2]; + var benchname = cpyelem.results[i][0]; + if (dataelem.avg_base) { + cpytimes[benchname] = dataelem.avg_base; + } else { + cpytimes[benchname] = dataelem.base_time; + } + } + return {'results': retval, 'cpytimes': cpytimes}; +} + +function extract_revnos(xmldoc) +{ + var res = []; + $(xmldoc).find("a").each(function (no, elem) { + var s = elem.getAttribute("href"); + s = s.substr(0, s.length - ".json".length); + res.push(s); + }); + return res; +} Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 17:29:02 2010 @@ -9,36 +9,7 @@ JSON_DIR_LIST = JSON_DIR_URL + "dir"; } -function Collector(revnos) -{ - this.plotdata = []; - this.counter = revnos.length; - - this.finish_collecting = function() { - this.plotdata = extract_benchmark_data(this.plotdata); - var benchnames = _.keys(this.plotdata.results); - benchnames.sort() - for (var i = 0; i < benchnames.length; ++i) { - var benchname = benchnames[i]; - var benchresults = this.plotdata.results[benchname]; - var cpystart = benchresults[0][0]; - var cpyend = benchresults[benchresults.length - 1][0]; - var cpyval = this.plotdata.cpytimes[benchname]; - var cpython_results = [[cpystart, cpyval], [cpyend, cpyval]] - this.plot(benchname, benchresults, cpython_results) - } - } - - this.collect = function(next) { - this.plotdata.push(next); - this.counter--; - if (this.counter == 0) { - this.finish_collecting() - } - } -} - -function myplot(benchname, benchresults, cpython_results) { +function plot_main(benchname, benchresults, cpython_results) { $("#placeholder").append("

" + benchname + "

"); $("#placeholder").append("
"); var plotinput = [{ @@ -67,93 +38,3 @@ }); } -function collect_data(plot_function, revlist_url, base_url, async) -{ - $.ajax({ - url: revlist_url, - dataType: 'html', - success: function(htmlstr) { - var revnos = extract_revnos($(htmlstr)); - var collector = new Collector(revnos); - collector.plot = plot_function; - for (var i in revnos) { - $.ajax({ - url: base_url + revnos[i] + '.json', - success: function(data) { - collector.collect(data) - }, - dataType: 'json', - async: async, - }); - } - }, - async: async, - }); -} - -$(document).ready(function() { - collect_data(myplot, JSON_DIR_LIST, JSON_DIR_URL, true); -}); - -function extract_benchmark_data(data) -{ - var retval = {}; - var cpytimes = {}; - var lastrev = 0; - var lastrevindex = 0; - for (var i = 0; i < data.length; i++) { - var revno = data[i]["revision"]; - if (revno > lastrev) { - lastrev = revno; - lastrevindex = i; - } - var results = data[i]["results"]; - for (var j = 0; j < results.length; j++) { - var result = results[j]; - var name = result[0]; - var dataelem = result[2]; - var avg; - if (dataelem["avg_changed"]) { - avg = dataelem["avg_changed"]; - } else { - avg = dataelem["changed_time"]; - } - if (retval[name]) { - retval[name].push([revno, avg]); - } else { - retval[name] = [[revno, avg]]; - } - } - } - for (var name in retval) { - retval[name].sort(function (a, b) { - if (a[0] > b[0]) { - return 1; - } else { - return -1; - } - }); - } - var cpyelem = data[lastrevindex] - for (var i = 0; i < cpyelem.results.length; i++) { - var dataelem = cpyelem.results[i][2]; - var benchname = cpyelem.results[i][0]; - if (dataelem.avg_base) { - cpytimes[benchname] = dataelem.avg_base; - } else { - cpytimes[benchname] = dataelem.base_time; - } - } - return {'results': retval, 'cpytimes': cpytimes}; -} - -function extract_revnos(xmldoc) -{ - var res = []; - $(xmldoc).find("a").each(function (no, elem) { - var s = elem.getAttribute("href"); - s = s.substr(0, s.length - ".json".length); - res.push(s); - }); - return res; -} \ No newline at end of file Modified: pypy/build/bot2/jsplot/plot.html ============================================================================== --- pypy/build/bot2/jsplot/plot.html (original) +++ pypy/build/bot2/jsplot/plot.html Sun Jan 17 17:29:02 2010 @@ -3,7 +3,13 @@ + + Copied: pypy/build/bot2/jsplot/test/jstest_collect_any.js (from r70658, pypy/build/bot2/jsplot/test/jstest_one_any.js) ============================================================================== --- pypy/build/bot2/jsplot/test/jstest_one_any.js (original) +++ pypy/build/bot2/jsplot/test/jstest_collect_any.js Sun Jan 17 17:29:02 2010 @@ -1,5 +1,5 @@ -OpenEnd.require("/js/plot.js") +OpenEnd.require("/js/collect.js") OpenEnd.require("/js/jquery.min.js") OpenEnd.require("/js/underscore-min.js") From fijal at codespeak.net Sun Jan 17 17:29:53 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 17:29:53 +0100 (CET) Subject: [pypy-svn] r70660 - pypy/build/bot2/jsplot Message-ID: <20100117162953.9020D168011@codespeak.net> Author: fijal Date: Sun Jan 17 17:29:52 2010 New Revision: 70660 Modified: pypy/build/bot2/jsplot/plot.html Log: fix typo Modified: pypy/build/bot2/jsplot/plot.html ============================================================================== --- pypy/build/bot2/jsplot/plot.html (original) +++ pypy/build/bot2/jsplot/plot.html Sun Jan 17 17:29:52 2010 @@ -7,7 +7,7 @@ From fijal at codespeak.net Sun Jan 17 20:50:05 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 20:50:05 +0100 (CET) Subject: [pypy-svn] r70661 - in pypy/build/bot2/jsplot: . css js Message-ID: <20100117195005.3310116801D@codespeak.net> Author: fijal Date: Sun Jan 17 20:50:03 2010 New Revision: 70661 Added: pypy/build/bot2/jsplot/plotsummary.html Modified: pypy/build/bot2/jsplot/css/main.css pypy/build/bot2/jsplot/js/plot.js Log: Add a small summary that displays small graphs Modified: pypy/build/bot2/jsplot/css/main.css ============================================================================== --- pypy/build/bot2/jsplot/css/main.css (original) +++ pypy/build/bot2/jsplot/css/main.css Sun Jan 17 20:50:03 2010 @@ -3,7 +3,16 @@ width: 600px; height: 300px; } +.miniplot { + width: 200px; + height: 100px; +} .caption { font-size: 14pt; font-family: Verdana; } +.smallcaption { + font-size: 10pt; + font-family: Verdana; + text-align: center; +} Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 20:50:03 2010 @@ -9,18 +9,9 @@ JSON_DIR_LIST = JSON_DIR_URL + "dir"; } -function plot_main(benchname, benchresults, cpython_results) { - $("#placeholder").append("

" + benchname + "

"); - $("#placeholder").append("
"); - var plotinput = [{ - label: 'pypy-c-jit', - data : benchresults, - }, - { - label: 'cpython', - data : cpython_results - }]; - $.plot($("#placeholder").children(":last"), plotinput, { +function common_attrs() +{ + return { 'series': { 'points': {'show': true}, 'lines' : {'show': true}, @@ -33,8 +24,41 @@ 'min': 0, }, 'legend' : { - 'position' : 'sw' + 'position': 'nw', } - }); + } +} + +function get_plot_input(benchresults, cpython_results) +{ + return [{ + label: 'pypy-c-jit', + data : benchresults, + }, + { + label: 'cpython', + data : cpython_results + }]; } +var MAX_PER_LINE = 4; + +function plot_miniature(benchname, benchresults, cpython_results) +{ + if ($("#placeholder").find("td").length % MAX_PER_LINE == 0) { + $("#placeholder").append(""); + } + $("#placeholder").find("tr:last").append("

" + benchname + "

"); + var elem = $("#placeholder").find("div:last"); + var attrs = common_attrs(); + attrs.xaxis.ticks = 0; + attrs.yaxis.ticks = 0; + $.plot(elem, [benchresults, cpython_results], attrs); +} + +function plot_main(benchname, benchresults, cpython_results) { + $("#placeholder").append("

" + benchname + "

"); + $("#placeholder").append("
"); + var plotinput = get_plot_input(benchresults, cpython_results) + $.plot($("#placeholder").children(":last"), plotinput, common_attrs()); +} Added: pypy/build/bot2/jsplot/plotsummary.html ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/plotsummary.html Sun Jan 17 20:50:03 2010 @@ -0,0 +1,23 @@ + + + + + + + + + + + + +

Benchmarks

+ + + +
+ + From fijal at codespeak.net Sun Jan 17 20:52:46 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 20:52:46 +0100 (CET) Subject: [pypy-svn] r70662 - pypy/build/bot2/codespeak-html Message-ID: <20100117195246.C0E3316801F@codespeak.net> Author: fijal Date: Sun Jan 17 20:52:46 2010 New Revision: 70662 Added: pypy/build/bot2/codespeak-html/plotsummary.html (contents, props changed) Log: another link Added: pypy/build/bot2/codespeak-html/plotsummary.html ============================================================================== --- (empty file) +++ pypy/build/bot2/codespeak-html/plotsummary.html Sun Jan 17 20:52:46 2010 @@ -0,0 +1 @@ +link ../jsplot/plotsummary.html \ No newline at end of file From fijal at codespeak.net Sun Jan 17 21:20:33 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 21:20:33 +0100 (CET) Subject: [pypy-svn] r70663 - in pypy/build/bot2/jsplot: . js test Message-ID: <20100117202033.6DF86318139@codespeak.net> Author: fijal Date: Sun Jan 17 21:20:31 2010 New Revision: 70663 Modified: pypy/build/bot2/jsplot/js/collect.js pypy/build/bot2/jsplot/js/plot.js pypy/build/bot2/jsplot/plotsummary.html pypy/build/bot2/jsplot/test/jstest_collect_any.js Log: Improve the look of benchmarks. Also have some more info there Modified: pypy/build/bot2/jsplot/js/collect.js ============================================================================== --- pypy/build/bot2/jsplot/js/collect.js (original) +++ pypy/build/bot2/jsplot/js/collect.js Sun Jan 17 21:20:31 2010 @@ -15,7 +15,8 @@ var cpyend = benchresults[benchresults.length - 1][0]; var cpyval = this.plotdata.cpytimes[benchname]; var cpython_results = [[cpystart, cpyval], [cpyend, cpyval]] - this.plot(benchname, benchresults, cpython_results) + this.plot(benchname, benchresults, cpython_results, + this.plotdata.lasttimes[benchname]) } } @@ -56,6 +57,7 @@ { var retval = {}; var cpytimes = {}; + var lasttimes = {} var lastrev = 0; var lastrevindex = 0; for (var i = 0; i < data.length; i++) { @@ -97,11 +99,14 @@ var benchname = cpyelem.results[i][0]; if (dataelem.avg_base) { cpytimes[benchname] = dataelem.avg_base; + lasttimes[benchname] = dataelem.delta_avg; } else { cpytimes[benchname] = dataelem.base_time; + lasttimes[benchname] = dataelem.time_delta; } } - return {'results': retval, 'cpytimes': cpytimes}; + return {'results': retval, 'cpytimes': cpytimes, + 'lasttimes': lasttimes}; } function extract_revnos(xmldoc) Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 21:20:31 2010 @@ -43,21 +43,31 @@ var MAX_PER_LINE = 4; -function plot_miniature(benchname, benchresults, cpython_results) +function plot_miniature(benchname, benchresults, cpython_results, lasttime) { if ($("#placeholder").find("td").length % MAX_PER_LINE == 0) { $("#placeholder").append(""); } - $("#placeholder").find("tr:last").append("

" + benchname + "

"); + var capt = benchname + " " + lasttime; + $("#placeholder").find("tr:last").append("

" + capt + "

"); var elem = $("#placeholder").find("div:last"); var attrs = common_attrs(); attrs.xaxis.ticks = 0; attrs.yaxis.ticks = 0; - $.plot(elem, [benchresults, cpython_results], attrs); + var data; + if (!$("#legend").children() == []) { + // a bit of a hack, if we didn't add a legend, do it now + data = get_plot_input(benchresults, cpython_results); + attrs.legend.container = "#legend"; + } else { + data = [benchresults, cpython_results]; + } + $.plot(elem, data, attrs); } -function plot_main(benchname, benchresults, cpython_results) { - $("#placeholder").append("

" + benchname + "

"); +function plot_main(benchname, benchresults, cpython_results, lasttime) { + var capt = benchname + " " + lasttime; + $("#placeholder").append("

" + capt + "

"); $("#placeholder").append("
"); var plotinput = get_plot_input(benchresults, cpython_results) $.plot($("#placeholder").children(":last"), plotinput, common_attrs()); Modified: pypy/build/bot2/jsplot/plotsummary.html ============================================================================== --- pypy/build/bot2/jsplot/plotsummary.html (original) +++ pypy/build/bot2/jsplot/plotsummary.html Sun Jan 17 21:20:31 2010 @@ -15,6 +15,11 @@

Benchmarks

+

+ On X axis revision number, on Y axis time for benchmark (lower is better). +

+
+
Modified: pypy/build/bot2/jsplot/test/jstest_collect_any.js ============================================================================== --- pypy/build/bot2/jsplot/test/jstest_collect_any.js (original) +++ pypy/build/bot2/jsplot/test/jstest_collect_any.js Sun Jan 17 21:20:31 2010 @@ -30,6 +30,7 @@ benchnames.sort(); aisDeeply(benchnames, expected_benchnames); ais(bench_data.cpytimes.ai, 0.43372206687940001); + ais(bench_data.lasttimes.ai, "1.0207x faster"); }, test_extract_revnos: function() { From fijal at codespeak.net Sun Jan 17 21:31:39 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 21:31:39 +0100 (CET) Subject: [pypy-svn] r70664 - pypy/build/bot2/jsplot/js Message-ID: <20100117203139.4504B16801D@codespeak.net> Author: fijal Date: Sun Jan 17 21:31:38 2010 New Revision: 70664 Modified: pypy/build/bot2/jsplot/js/plot.js Log: note cpython version Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 21:31:38 2010 @@ -36,7 +36,7 @@ data : benchresults, }, { - label: 'cpython', + label: 'cpython 2.6.2', data : cpython_results }]; } From fijal at codespeak.net Sun Jan 17 21:36:15 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 21:36:15 +0100 (CET) Subject: [pypy-svn] r70665 - pypy/build/bot2/jsplot/js Message-ID: <20100117203615.CB77216801D@codespeak.net> Author: fijal Date: Sun Jan 17 21:36:15 2010 New Revision: 70665 Modified: pypy/build/bot2/jsplot/js/plot.js Log: Push upper line a bit down, to avoid it being on a border Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 21:36:15 2010 @@ -22,6 +22,7 @@ }, 'yaxis': { 'min': 0, + 'autoscaleMargin': 0.1, }, 'legend' : { 'position': 'nw', From fijal at codespeak.net Sun Jan 17 22:25:13 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 22:25:13 +0100 (CET) Subject: [pypy-svn] r70666 - in pypy/build/bot2/jsplot: . js Message-ID: <20100117212513.46AD916801D@codespeak.net> Author: fijal Date: Sun Jan 17 22:25:12 2010 New Revision: 70666 Modified: pypy/build/bot2/jsplot/js/plot.js pypy/build/bot2/jsplot/plotsummary.html Log: minor tweaks Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 22:25:12 2010 @@ -42,6 +42,14 @@ }]; } +function attrs_for_miniature() +{ + var attrs = common_attrs(); + attrs.xaxis.ticks = 0; + attrs.yaxis.ticks = 0; + return attrs; +} + var MAX_PER_LINE = 4; function plot_miniature(benchname, benchresults, cpython_results, lasttime) @@ -52,12 +60,14 @@ var capt = benchname + " " + lasttime; $("#placeholder").find("tr:last").append(""); var elem = $("#placeholder").find("div:last"); - var attrs = common_attrs(); - attrs.xaxis.ticks = 0; - attrs.yaxis.ticks = 0; + var attrs = attrs_for_miniature(); var data; if (!$("#legend").children() == []) { // a bit of a hack, if we didn't add a legend, do it now + $("#revstart")[0].value = benchresults[0][0]; + $("#revstart").change(function(event) { + redisplay(elem, benchresults, cpython_results); + }); data = get_plot_input(benchresults, cpython_results); attrs.legend.container = "#legend"; } else { @@ -66,6 +76,13 @@ $.plot(elem, data, attrs); } +function redisplay(elem, benchresults, cpython_results) +{ + var attrs = attrs_for_miniature(); + attrs.xaxis.min = $("#revstart")[0].value; + $.plot(elem, [benchresults, cpython_results], attrs); +} + function plot_main(benchname, benchresults, cpython_results, lasttime) { var capt = benchname + " " + lasttime; $("#placeholder").append("

" + capt + "

"); Modified: pypy/build/bot2/jsplot/plotsummary.html ============================================================================== --- pypy/build/bot2/jsplot/plotsummary.html (original) +++ pypy/build/bot2/jsplot/plotsummary.html Sun Jan 17 22:25:12 2010 @@ -16,7 +16,7 @@

Benchmarks

- On X axis revision number, on Y axis time for benchmark (lower is better). + On X axis revision number, on Y axis time for benchmark (lower is better). Revisions from to HEAD.

From fijal at codespeak.net Sun Jan 17 23:02:12 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 23:02:12 +0100 (CET) Subject: [pypy-svn] r70667 - in pypy/build/bot2/jsplot: . css js Message-ID: <20100117220212.CF3E616801D@codespeak.net> Author: fijal Date: Sun Jan 17 23:02:11 2010 New Revision: 70667 Modified: pypy/build/bot2/jsplot/css/main.css pypy/build/bot2/jsplot/js/plot.js pypy/build/bot2/jsplot/plotsummary.html Log: some hacks to make it redisplay correctly under changing revision. Add a display for large graph Modified: pypy/build/bot2/jsplot/css/main.css ============================================================================== --- pypy/build/bot2/jsplot/css/main.css (original) +++ pypy/build/bot2/jsplot/css/main.css Sun Jan 17 23:02:11 2010 @@ -7,6 +7,10 @@ width: 200px; height: 100px; } +.largeplot { + width: 800px; + height: 400px; +} .caption { font-size: 14pt; font-family: Verdana; Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 23:02:11 2010 @@ -9,6 +9,9 @@ JSON_DIR_LIST = JSON_DIR_URL + "dir"; } +var large_displayed = false; +var large_data; + function common_attrs() { return { @@ -58,29 +61,41 @@ $("#placeholder").append(""); } var capt = benchname + " " + lasttime; - $("#placeholder").find("tr:last").append(""); + $("#placeholder").find("tr:last").append(""); + $("#goto_" + benchname).click(function(e) { + display_large(benchname, benchresults, cpython_results); + }); var elem = $("#placeholder").find("div:last"); var attrs = attrs_for_miniature(); var data; - if (!$("#legend").children() == []) { - // a bit of a hack, if we didn't add a legend, do it now - $("#revstart")[0].value = benchresults[0][0]; - $("#revstart").change(function(event) { - redisplay(elem, benchresults, cpython_results); - }); - data = get_plot_input(benchresults, cpython_results); - attrs.legend.container = "#legend"; - } else { - data = [benchresults, cpython_results]; - } + $("#revstart")[0].value = benchresults[0][0]; + $("#revstart").change(function(event) { + redisplay(elem, benchresults, cpython_results); + }); + data = get_plot_input(benchresults, cpython_results); + attrs.legend.container = "#legend"; $.plot(elem, data, attrs); } +function display_large(benchname, benchresults, cpython_results) +{ + $("#large_caption").html(benchname); + var attrs = common_attrs(); + attrs.xaxis.min = $("#revstart")[0].value; + $.plot($("#large_graph"), get_plot_input(benchresults, cpython_results), + attrs); + large_displayed = true; + large_data = [benchname, benchresults, cpython_results]; +} + function redisplay(elem, benchresults, cpython_results) { var attrs = attrs_for_miniature(); attrs.xaxis.min = $("#revstart")[0].value; $.plot(elem, [benchresults, cpython_results], attrs); + if (large_displayed) { + display_large(large_data[0], large_data[1], large_data[2]); + } } function plot_main(benchname, benchresults, cpython_results, lasttime) { Modified: pypy/build/bot2/jsplot/plotsummary.html ============================================================================== --- pypy/build/bot2/jsplot/plotsummary.html (original) +++ pypy/build/bot2/jsplot/plotsummary.html Sun Jan 17 23:02:11 2010 @@ -24,5 +24,7 @@

" + capt + "

" + capt + "

" + capt + "

+

+
From fijal at codespeak.net Sun Jan 17 23:05:23 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 23:05:23 +0100 (CET) Subject: [pypy-svn] r70668 - in pypy/build/bot2/jsplot: . js Message-ID: <20100117220523.6CEE116801D@codespeak.net> Author: fijal Date: Sun Jan 17 23:05:22 2010 New Revision: 70668 Modified: pypy/build/bot2/jsplot/js/plot.js pypy/build/bot2/jsplot/plotsummary.html Log: fix anchoring Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 23:05:22 2010 @@ -61,7 +61,7 @@ $("#placeholder").append(""); } var capt = benchname + " " + lasttime; - $("#placeholder").find("tr:last").append("

" + capt + "

"); + $("#placeholder").find("tr:last").append("

" + capt + "

"); $("#goto_" + benchname).click(function(e) { display_large(benchname, benchresults, cpython_results); }); Modified: pypy/build/bot2/jsplot/plotsummary.html ============================================================================== --- pypy/build/bot2/jsplot/plotsummary.html (original) +++ pypy/build/bot2/jsplot/plotsummary.html Sun Jan 17 23:05:22 2010 @@ -24,6 +24,7 @@ +

From fijal at codespeak.net Sun Jan 17 23:07:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 17 Jan 2010 23:07:20 +0100 (CET) Subject: [pypy-svn] r70669 - pypy/build/bot2/jsplot/js Message-ID: <20100117220720.CB25216801D@codespeak.net> Author: fijal Date: Sun Jan 17 23:07:20 2010 New Revision: 70669 Modified: pypy/build/bot2/jsplot/js/plot.js Log: Repeat the "xxx faster" string at the bottom Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 17 23:07:20 2010 @@ -63,7 +63,7 @@ var capt = benchname + " " + lasttime; $("#placeholder").find("tr:last").append("

" + capt + "

"); $("#goto_" + benchname).click(function(e) { - display_large(benchname, benchresults, cpython_results); + display_large(benchname, benchresults, cpython_results, lasttime); }); var elem = $("#placeholder").find("div:last"); var attrs = attrs_for_miniature(); @@ -77,15 +77,15 @@ $.plot(elem, data, attrs); } -function display_large(benchname, benchresults, cpython_results) +function display_large(benchname, benchresults, cpython_results, lasttime) { - $("#large_caption").html(benchname); + $("#large_caption").html(benchname + " " + lasttime); var attrs = common_attrs(); attrs.xaxis.min = $("#revstart")[0].value; $.plot($("#large_graph"), get_plot_input(benchresults, cpython_results), attrs); large_displayed = true; - large_data = [benchname, benchresults, cpython_results]; + large_data = [benchname, benchresults, cpython_results, lasttime]; } function redisplay(elem, benchresults, cpython_results) @@ -94,7 +94,7 @@ attrs.xaxis.min = $("#revstart")[0].value; $.plot(elem, [benchresults, cpython_results], attrs); if (large_displayed) { - display_large(large_data[0], large_data[1], large_data[2]); + display_large(large_data[0], large_data[1], large_data[2], large_data[3]); } } From afa at codespeak.net Mon Jan 18 00:57:52 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 18 Jan 2010 00:57:52 +0100 (CET) Subject: [pypy-svn] r70671 - in pypy/branch/separate-compilation/pypy/translator/c: . test Message-ID: <20100117235752.E776516801D@codespeak.net> Author: afa Date: Mon Jan 18 00:57:52 2010 New Revision: 70671 Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py pypy/branch/separate-compilation/pypy/translator/c/separate.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Refactor a bit Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/genc.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/genc.py Mon Jan 18 00:57:52 2010 @@ -312,9 +312,6 @@ return None def getexportsymbols(self): - self.export_node_names = dict( - (funcname, self.db.get(funcptr)) - for funcname, funcptr in self.entrypoint.items()) return self.export_node_names.values() + ['RPython_StartupCode'] def compile(self): Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Mon Jan 18 00:57:52 2010 @@ -7,102 +7,107 @@ from pypy.rpython.lltypesystem import lltype, rffi from pypy.rpython.extregistry import ExtRegistryEntry import py -import types -def make_wrapper_for_constructor(cls, name): - nbargs = len(cls.__init__.argtypes) - args = ', '.join(['arg%d' % d for d in range(nbargs)]) - - source = py.code.Source(r""" - def wrapper(%s): - obj = instantiate(cls) - obj.__init__(%s) - return obj - """ % (args, args)) - miniglobals = {'cls': cls, 'instantiate': instantiate} - exec source.compile() in miniglobals - wrapper = miniglobals['wrapper'] - wrapper._annspecialcase_ = 'specialize:ll' - wrapper._always_inline_ = True - return func_with_new_name(wrapper, name) +class ExportTable(object): + """A table with information about the exported symbols of a module + compiled by pypy.""" + + def __init__(self): + self.exported_function = {} + self.exported_class = {} + + def make_wrapper_for_constructor(self, cls, name): + nbargs = len(cls.__init__.argtypes) + args = ', '.join(['arg%d' % d for d in range(nbargs)]) + + source = py.code.Source(r""" + def wrapper(%s): + obj = instantiate(cls) + obj.__init__(%s) + return obj + """ % (args, args)) + miniglobals = {'cls': cls, 'instantiate': instantiate} + exec source.compile() in miniglobals + wrapper = miniglobals['wrapper'] + wrapper._annspecialcase_ = 'specialize:ll' + wrapper._always_inline_ = True + return func_with_new_name(wrapper, name) + + def annotate_exported_functions(self, annotator): + bk = annotator.bookkeeper + + # annotate classes + for clsname, cls in self.exported_class.items(): + desc = bk.getdesc(cls) + classdef = desc.getuniqueclassdef() + s_init = desc.s_read_attribute('__init__') + if isinstance(s_init, model.SomeImpossibleValue): + continue + + # Replace class with its constructor + wrapper = self.make_wrapper_for_constructor(cls, clsname) + self.exported_function[clsname] = wrapper -def annotate_exported_functions(annotator, exports): - bk = annotator.bookkeeper - - # annotate classes - for clsname, cls in exports.items(): - if not isinstance(cls, (type, types.ClassType)): - continue - desc = bk.getdesc(cls) - classdef = desc.getuniqueclassdef() - s_init = desc.s_read_attribute('__init__') - if isinstance(s_init, model.SomeImpossibleValue): - continue - - wrapper = make_wrapper_for_constructor(cls, clsname) - exports[clsname] = wrapper - - annotator.build_types(wrapper, cls.__init__.argtypes, - complete_now=False) - - # annotate functions with signatures - for funcname, func in exports.items(): - if hasattr(func, 'argtypes'): - annotator.build_types(func, func.argtypes, + annotator.build_types(wrapper, cls.__init__.argtypes, complete_now=False) - annotator.complete() - # ensure that functions without signature are not constant-folded - for funcname, func in exports.items(): - if not hasattr(func, 'argtypes'): - # build a list of arguments where constants are erased - newargs = [] - desc = bk.getdesc(func) + # annotate functions with signatures + for funcname, func in self.exported_function.items(): + if hasattr(func, 'argtypes'): + annotator.build_types(func, func.argtypes, + complete_now=False) + annotator.complete() + + # ensure that functions without signature are not constant-folded + for funcname, func in self.exported_function.items(): + if not hasattr(func, 'argtypes'): + # build a list of arguments where constants are erased + newargs = [] + desc = bk.getdesc(func) + if isinstance(desc, description.FunctionDesc): + graph = desc.getuniquegraph() + for arg in graph.startblock.inputargs: + newarg = model.not_const(annotator.binding(arg)) + newargs.append(newarg) + # and reflow + annotator.build_types(func, newargs) + + def get_exported_functions(self, annotator): + bk = annotator.bookkeeper + + exported_funcptr = {} + for itemname, item in self.exported_function.items(): + desc = bk.getdesc(item) if isinstance(desc, description.FunctionDesc): graph = desc.getuniquegraph() - for arg in graph.startblock.inputargs: - newarg = model.not_const(annotator.binding(arg)) - newargs.append(newarg) - # and reflow - annotator.build_types(func, newargs) - -def get_exported_functions(annotator, exports): - bk = annotator.bookkeeper - - exported_funcptr = {} - for itemname, item in exports.items(): - desc = bk.getdesc(item) - if isinstance(desc, description.FunctionDesc): - graph = desc.getuniquegraph() - funcptr = getfunctionptr(graph) - elif isinstance(desc, description.ClassDesc): - continue - - exported_funcptr[itemname] = funcptr - return exported_funcptr - -def make_import_module(builder): - class Module: - pass - mod = Module() - mod.__file__ = builder.so_name - - forwards = [] - node_names = builder.export_node_names.values() - for node in builder.db.globalcontainers(): - if node.nodekind == 'func' and node.name in node_names: - forwards.append('\n'.join(node.forward_declaration())) - - import_eci = ExternalCompilationInfo( - libraries = [builder.so_name], - post_include_bits = forwards - ) - - for funcname, import_name in builder.export_node_names.items(): - functype = lltype.typeOf(builder.entrypoint[funcname]) - func = make_ll_import_function(import_name, functype, import_eci) - setattr(mod, funcname, func) - return mod + funcptr = getfunctionptr(graph) + elif isinstance(desc, description.ClassDesc): + continue + + exported_funcptr[itemname] = funcptr + return exported_funcptr + + def make_import_module(self, builder, node_names): + class Module: + pass + mod = Module() + mod.__file__ = builder.so_name + + forwards = [] + for node in builder.db.globalcontainers(): + if node.nodekind == 'func' and node.name in node_names.values(): + forwards.append('\n'.join(node.forward_declaration())) + + import_eci = ExternalCompilationInfo( + libraries = [builder.so_name], + post_include_bits = forwards + ) + + for funcname, import_name in builder.export_node_names.items(): + functype = lltype.typeOf(builder.entrypoint[funcname]) + func = make_ll_import_function(import_name, functype, import_eci) + setattr(mod, funcname, func) + return mod def make_ll_import_arg_converter(TARGET): from pypy.annotation import model Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Mon Jan 18 00:57:52 2010 @@ -4,7 +4,7 @@ from pypy.translator.c import separate from pypy.translator.tool.cbuild import ExternalCompilationInfo import py -import sys, os +import sys, os, types class TestSeparation: def setup_method(self, method): @@ -41,17 +41,26 @@ t = TranslationContext() t.buildannotator() - separate.annotate_exported_functions(t.annotator, exports) + table = separate.ExportTable() + for name, obj in exports.items(): + if isinstance(obj, (type, types.ClassType)): + table.exported_class[name] = obj + else: + table.exported_function[name] = obj + table.annotate_exported_functions(t.annotator) t.buildrtyper().specialize() - exported_funcptr = separate.get_exported_functions(t.annotator, exports) + exported_funcptr = table.get_exported_functions(t.annotator) builder = CLibraryBuilder(t, exported_funcptr, config=t.config) builder.generate_source() + node_names = dict( + (funcname, builder.db.get(funcptr)) + for funcname, funcptr in builder.entrypoint.items()) builder.compile() - mod = separate.make_import_module(builder) + mod = table.make_import_module(builder, node_names) if sys.platform == 'win32': filepath = os.path.dirname(builder.so_name) From pedronis at codespeak.net Mon Jan 18 12:20:01 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 18 Jan 2010 12:20:01 +0100 (CET) Subject: [pypy-svn] r70672 - in pypy/benchmarks: . unladen_swallow Message-ID: <20100118112001.DA58016801D@codespeak.net> Author: pedronis Date: Mon Jan 18 12:20:00 2010 New Revision: 70672 Modified: pypy/benchmarks/runner.py pypy/benchmarks/unladen_swallow/perf.py Log: (fijal, pedronis) parametrize perf main() more to allow to add external benchmarks Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Mon Jan 18 12:20:00 2010 @@ -5,12 +5,13 @@ import os import json import sys -from unladen_swallow.perf import main +from unladen_swallow.perf import main, BENCH_FUNCS def run_and_store(benchmarks, result_filename, pypy_c_path, revision=0): results = main(['-f', '-b', ','.join(benchmarks), '--inherit_env=PATH', - '--no_charts', sys.executable, pypy_c_path]) + '--no_charts', sys.executable, pypy_c_path], + BENCH_FUNCS) f = open(str(result_filename), "w") res = [(name, result.__class__.__name__, result.__dict__) for name, result in results] Modified: pypy/benchmarks/unladen_swallow/perf.py ============================================================================== --- pypy/benchmarks/unladen_swallow/perf.py (original) +++ pypy/benchmarks/unladen_swallow/perf.py Mon Jan 18 12:20:00 2010 @@ -1419,15 +1419,18 @@ ### End benchmarks, begin main entry point support. -def _FindAllBenchmarks(): +def _FindAllBenchmarks(namespace): return dict((name[3:].lower(), func) - for (name, func) in sorted(globals().iteritems()) + for (name, func) in sorted(namespace.iteritems()) if name.startswith("BM_")) +BENCH_FUNCS = _FindAllBenchmarks(globals()) # Benchmark groups. The "default" group is what's run if no -b option is -# specified. The "all" group includes every benchmark perf.py knows about. +# specified. # If you update the default group, be sure to update the module docstring, too. +# An "all" group which includes every benchmark perf.py knows about is generated +# automatically. BENCH_GROUPS = {"default": ["2to3", "django", "nbody", "slowspitfire", "slowpickle", "slowunpickle", "spambayes"], "startup": ["normal_startup", "startup_nosite"], @@ -1435,12 +1438,12 @@ "threading": ["threaded_count", "iterative_count"], "cpickle": ["pickle", "unpickle"], "micro": ["unpack_sequence", "call_simple"], - "app": ["2to3", "html5lib", "spambayes"], - "all": _FindAllBenchmarks().keys(), + "app": [#"2to3", + "html5lib", "spambayes"] } -def _ExpandBenchmarkName(bm_name): +def _ExpandBenchmarkName(bm_name, bench_groups): """Recursively expand name benchmark names. Args: @@ -1449,16 +1452,16 @@ Yields: Names of actual benchmarks, with all group names fully expanded. """ - expansion = BENCH_GROUPS.get(bm_name) + expansion = bench_groups.get(bm_name) if expansion: for name in expansion: - for name in _ExpandBenchmarkName(name): + for name in _ExpandBenchmarkName(name, bench_groups): yield name else: yield bm_name -def ParseBenchmarksOption(benchmarks_opt): +def ParseBenchmarksOption(benchmarks_opt, bench_groups): """Parses and verifies the --benchmarks option. Args: @@ -1467,7 +1470,7 @@ Returns: A set() of the names of the benchmarks to run. """ - legal_benchmarks = BENCH_GROUPS["all"] + legal_benchmarks = bench_groups["all"] benchmarks = benchmarks_opt.split(",") positive_benchmarks = set( bm.lower() for bm in benchmarks if bm and bm[0] != "-") @@ -1476,16 +1479,16 @@ should_run = set() if not positive_benchmarks: - should_run = set(_ExpandBenchmarkName("default")) + should_run = set(_ExpandBenchmarkName("default", bench_groups)) for name in positive_benchmarks: - for bm in _ExpandBenchmarkName(name): + for bm in _ExpandBenchmarkName(name, bench_groups): if bm not in legal_benchmarks: logging.warning("No benchmark named %s", bm) else: should_run.add(bm) for bm in negative_benchmarks: - if bm in BENCH_GROUPS: + if bm in bench_groups: raise ValueError("Negative groups not supported: -%s" % bm) elif bm not in legal_benchmarks: logging.warning("No benchmark named %s", bm) @@ -1516,9 +1519,10 @@ """Parser callback to --inherit_env var names""" parser.values.inherit_env = [v for v in value.split(",") if v] -def main(argv): - bench_funcs = _FindAllBenchmarks() - all_benchmarks = BENCH_GROUPS["all"] +def main(argv, bench_funcs=BENCH_FUNCS, bench_groups=BENCH_GROUPS): + bench_groups = bench_groups.copy() + all_benchmarks = bench_funcs.keys() + bench_groups["all"] = all_benchmarks parser = optparse.OptionParser( usage="%prog [options] baseline_python changed_python", @@ -1549,7 +1553,7 @@ " benchmarks except the negative arguments. " + " Otherwise we run only the positive arguments. " + " Valid benchmarks are: " + - ", ".join(BENCH_GROUPS.keys() + all_benchmarks))) + ", ".join(bench_groups.keys() + all_benchmarks))) parser.add_option("--inherit_env", metavar="ENVVARS", type="string", action="callback", callback=ParseEnvVars, default=[], help=("Comma-separated list of environment variable names" @@ -1580,7 +1584,7 @@ parser.error("--track_memory requires Windows with PyWin32 or " + "Linux 2.6.16 or above") - should_run = ParseBenchmarksOption(options.benchmarks) + should_run = ParseBenchmarksOption(options.benchmarks, bench_groups) results = [] for name in sorted(should_run): From fijal at codespeak.net Mon Jan 18 12:23:28 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 12:23:28 +0100 (CET) Subject: [pypy-svn] r70673 - pypy/benchmarks Message-ID: <20100118112328.39A18168021@codespeak.net> Author: fijal Date: Mon Jan 18 12:23:27 2010 New Revision: 70673 Modified: pypy/benchmarks/runner.py (props changed) Log: add an executable property From fijal at codespeak.net Mon Jan 18 13:03:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 13:03:56 +0100 (CET) Subject: [pypy-svn] r70674 - pypy/benchmarks/unladen_swallow/performance Message-ID: <20100118120356.8E29431813C@codespeak.net> Author: fijal Date: Mon Jan 18 13:03:56 2010 New Revision: 70674 Added: pypy/benchmarks/unladen_swallow/performance/__init__.py (contents, props changed) Log: make this a module Added: pypy/benchmarks/unladen_swallow/performance/__init__.py ============================================================================== From fijal at codespeak.net Mon Jan 18 13:17:25 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 13:17:25 +0100 (CET) Subject: [pypy-svn] r70675 - in pypy/benchmarks: . shootout unladen_swallow/performance Message-ID: <20100118121725.E600416800D@codespeak.net> Author: fijal Date: Mon Jan 18 13:17:25 2010 New Revision: 70675 Added: pypy/benchmarks/benchmarks.py (contents, props changed) pypy/benchmarks/shootout/__init__.py (contents, props changed) pypy/benchmarks/shootout/setup.py (contents, props changed) pypy/benchmarks/shootout/util.py (contents, props changed) Removed: pypy/benchmarks/unladen_swallow/performance/__init__.py Modified: pypy/benchmarks/runner.py pypy/benchmarks/shootout/float.py (contents, props changed) Log: Start adding benchmarks. Float benchmark comes first Added: pypy/benchmarks/benchmarks.py ============================================================================== --- (empty file) +++ pypy/benchmarks/benchmarks.py Mon Jan 18 13:17:25 2010 @@ -0,0 +1,10 @@ + +import py +from unladen_swallow.perf import SimpleBenchmark, MeasureGeneric + +def MeasureFloat(python, options): + bm_path = str(py.path.local(__file__).dirpath().join("shootout", "float.py")) + return MeasureGeneric(python, options, bm_path) + +def BM_float(*args, **kwds): + return SimpleBenchmark(MeasureFloat, *args, **kwds) Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Mon Jan 18 13:17:25 2010 @@ -5,13 +5,16 @@ import os import json import sys -from unladen_swallow.perf import main, BENCH_FUNCS +from unladen_swallow.perf import main, BENCH_FUNCS, _FindAllBenchmarks +import benchmarks -def run_and_store(benchmarks, result_filename, pypy_c_path, revision=0): - results = main(['-f', '-b', ','.join(benchmarks), +def run_and_store(benchmark_set, result_filename, pypy_c_path, revision=0): + funcs = BENCH_FUNCS.copy() + funcs.update(_FindAllBenchmarks(benchmarks.__dict__)) + results = main(['-f', '-b', ','.join(benchmark_set), '--inherit_env=PATH', '--no_charts', sys.executable, pypy_c_path], - BENCH_FUNCS) + funcs) f = open(str(result_filename), "w") res = [(name, result.__class__.__name__, result.__dict__) for name, result in results] @@ -23,5 +26,5 @@ if __name__ == '__main__': BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', - 'rietveld', 'html5lib', 'ai'] + 'rietveld', 'html5lib', 'ai', 'float'] run_and_store(BENCHMARK_SET, sys.argv[1], sys.argv[2], int(sys.argv[3])) Added: pypy/benchmarks/shootout/__init__.py ============================================================================== Modified: pypy/benchmarks/shootout/float.py ============================================================================== --- pypy/benchmarks/shootout/float.py (original) +++ pypy/benchmarks/shootout/float.py Mon Jan 18 13:17:25 2010 @@ -1,8 +1,9 @@ +#!/usr/bin/env python # -*- coding: utf-8 -*- from math import sin, cos, sqrt -import sys - -NUMBER_OF_RUNS = int(sys.argv[1]) +import util +import optparse +import time class Point(object): @@ -44,15 +45,24 @@ p.normalize() return maximize(points) -def main(): - if len(sys.argv) == 1: - n = 100000 - else: - n = int(sys.argv[1]) - for i in xrange(NUMBER_OF_RUNS): - o = benchmark(n) - print o - -if __name__ == '__main__': - for i in range(int(sys.argv[2])): - main() +POINTS = 100000 + +def main(arg): + # XXX warmup + + times = [] + for i in xrange(arg): + t0 = time.time() + o = benchmark(POINTS) + tk = time.time() + times.append(tk - t0) + return times + +if __name__ == "__main__": + parser = optparse.OptionParser( + usage="%prog [options]", + description="Test the performance of the Float benchmark") + util.add_standard_options_to(parser) + options, args = parser.parse_args() + + util.run_benchmark(options, options.num_runs, main) Added: pypy/benchmarks/shootout/setup.py ============================================================================== --- (empty file) +++ pypy/benchmarks/shootout/setup.py Mon Jan 18 13:17:25 2010 @@ -0,0 +1,4 @@ + +# a bit dirty directory setup +import sys +sys.path.insert(0, '..') Added: pypy/benchmarks/shootout/util.py ============================================================================== --- (empty file) +++ pypy/benchmarks/shootout/util.py Mon Jan 18 13:17:25 2010 @@ -0,0 +1 @@ +link ../unladen_swallow/performance/util.py \ No newline at end of file From fijal at codespeak.net Mon Jan 18 13:38:33 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 13:38:33 +0100 (CET) Subject: [pypy-svn] r70676 - pypy/benchmarks Message-ID: <20100118123833.D12C516801F@codespeak.net> Author: fijal Date: Mon Jan 18 13:38:33 2010 New Revision: 70676 Modified: pypy/benchmarks/runner.py Log: Beautify runner. Add command line options, so we can save some typing. Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Mon Jan 18 13:38:33 2010 @@ -5,13 +5,13 @@ import os import json import sys -from unladen_swallow.perf import main, BENCH_FUNCS, _FindAllBenchmarks +from unladen_swallow import perf import benchmarks def run_and_store(benchmark_set, result_filename, pypy_c_path, revision=0): - funcs = BENCH_FUNCS.copy() - funcs.update(_FindAllBenchmarks(benchmarks.__dict__)) - results = main(['-f', '-b', ','.join(benchmark_set), + funcs = perf.BENCH_FUNCS.copy() + funcs.update(perf._FindAllBenchmarks(benchmarks.__dict__)) + results = perf.main(['-f', '-b', ','.join(benchmark_set), '--inherit_env=PATH', '--no_charts', sys.executable, pypy_c_path], funcs) @@ -24,7 +24,36 @@ })) f.close() +BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', + 'rietveld', 'html5lib', 'ai', 'float'] + +class WrongBenchmark(Exception): + pass + +def main(argv): + import optparse + parser = optparse.OptionParser( + usage="%prog [options]", + description="Run benchmarks and dump json") + parser.add_option("-b", "--benchmarks", metavar="BM_LIST", + default=','.join(BENCHMARK_SET), + help=("Comma-separated list of benchmarks to run" + " Valid benchmarks are: " + + ", ".join(BENCHMARK_SET))) + parser.add_option('-p', '--pypy-c', default=sys.executable, + help=('pypy-c or other modified python to run against')) + parser.add_option('-r', '--revision', default=0, action="store", type=int, + help=('specify revision of pypy-c')) + parser.add_option('-o', '--output-filename', default="result.json", + action="store", + help=('specify output filename to store resulting json')) + options, args = parser.parse_args(argv) + benchmarks = options.benchmarks.split(',') + for benchmark in benchmarks: + if benchmark not in BENCHMARK_SET: + raise WrongBenchmark(benchmark) + run_and_store(benchmarks, options.output_filename, options.pypy_c, + options.revision) + if __name__ == '__main__': - BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', - 'rietveld', 'html5lib', 'ai', 'float'] - run_and_store(BENCHMARK_SET, sys.argv[1], sys.argv[2], int(sys.argv[3])) + main(sys.argv[1:]) From fijal at codespeak.net Mon Jan 18 13:39:42 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 13:39:42 +0100 (CET) Subject: [pypy-svn] r70677 - pypy/build/bot2/pypybuildbot Message-ID: <20100118123942.0632116801F@codespeak.net> Author: fijal Date: Mon Jan 18 13:39:42 2010 New Revision: 70677 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: adapt to changes in runner Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Mon Jan 18 13:39:42 2010 @@ -167,9 +167,9 @@ self.addStep(Translate(['-Ojit'], [])) self.addStep(ShellCmd( description="run more benchmarks", - command=["python", "runner.py", 'result.json', - '../build/pypy/translator/goal/pypy-c', - WithProperties('%(got_revision)s')], + command=["python", "runner.py", '--output-filename', 'result.json', + '--pypy-c', '../build/pypy/translator/goal/pypy-c', + '--revision', WithProperties('%(got_revision)s')], workdir='./benchmarks', haltOnFailure=True)) # a bit obscure hack to get both os.path.expand and a property From fijal at codespeak.net Mon Jan 18 13:46:14 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 13:46:14 +0100 (CET) Subject: [pypy-svn] r70678 - pypy/benchmarks Message-ID: <20100118124614.519B0168011@codespeak.net> Author: fijal Date: Mon Jan 18 13:46:13 2010 New Revision: 70678 Modified: pypy/benchmarks/benchmarks.py Log: kill pylib usage, it's for buildslaves after all, should be as standalone as possible Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Mon Jan 18 13:46:13 2010 @@ -1,9 +1,10 @@ -import py +import os from unladen_swallow.perf import SimpleBenchmark, MeasureGeneric def MeasureFloat(python, options): - bm_path = str(py.path.local(__file__).dirpath().join("shootout", "float.py")) + bm_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'shootout', 'float.py') return MeasureGeneric(python, options, bm_path) def BM_float(*args, **kwds): From fijal at codespeak.net Mon Jan 18 14:03:19 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 14:03:19 +0100 (CET) Subject: [pypy-svn] r70680 - in pypy/benchmarks: . shootout Message-ID: <20100118130319.25126168022@codespeak.net> Author: fijal Date: Mon Jan 18 14:03:18 2010 New Revision: 70680 Added: pypy/benchmarks/shootout/nbody_modified.py - copied, changed from r70675, pypy/benchmarks/shootout/nbody.py Removed: pypy/benchmarks/shootout/nbody.py Modified: pypy/benchmarks/benchmarks.py pypy/benchmarks/runner.py Log: Add a 2.5 compatible version of nbody Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Mon Jan 18 14:03:18 2010 @@ -2,10 +2,20 @@ import os from unladen_swallow.perf import SimpleBenchmark, MeasureGeneric -def MeasureFloat(python, options): - bm_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), - 'shootout', 'float.py') - return MeasureGeneric(python, options, bm_path) +def relative(*args): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), *args) -def BM_float(*args, **kwds): - return SimpleBenchmark(MeasureFloat, *args, **kwds) +def _register_new_bm(name, d): + def Measure(python, options): + bm_path = relative('shootout', name + '.py') + return MeasureGeneric(python, options, bm_path) + Measure.func_name = 'Measure' + name.capitalize() + + def BM(*args, **kwds): + return SimpleBenchmark(Measure, *args, **kwds) + BM.func_name = 'BM_' + name + + d[BM.func_name] = BM + +for name in ['float', 'nbody_modified']: + _register_new_bm(name, globals()) Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Mon Jan 18 14:03:18 2010 @@ -25,7 +25,7 @@ f.close() BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', - 'rietveld', 'html5lib', 'ai', 'float'] + 'rietveld', 'html5lib', 'ai', 'float', 'nbody_modified'] class WrongBenchmark(Exception): pass Copied: pypy/benchmarks/shootout/nbody_modified.py (from r70675, pypy/benchmarks/shootout/nbody.py) ============================================================================== --- pypy/benchmarks/shootout/nbody.py (original) +++ pypy/benchmarks/shootout/nbody_modified.py Mon Jan 18 14:03:18 2010 @@ -6,6 +6,9 @@ # modified by Tupteq, Fredrik Johansson, and Daniel Nanz import sys +import util +import optparse +import time def combinations(l): result = [] @@ -106,13 +109,27 @@ v[1] = py / m v[2] = pz / m +NUMBER_OF_ITERATIONS = 20000 def main(n, ref='sun'): + # XXX warmup + + times = [] + for i in range(n): + t0 = time.time() + offset_momentum(BODIES[ref]) + report_energy() + advance(0.01, NUMBER_OF_ITERATIONS) + report_energy() + tk = time.time() + times.append(tk - t0) + return times + +if __name__ == "__main__": + parser = optparse.OptionParser( + usage="%prog [options]", + description="Test the performance of the 2.5 compatible nbody benchmark") + util.add_standard_options_to(parser) + options, args = parser.parse_args() - offset_momentum(BODIES[ref]) - report_energy() - advance(0.01, n) - report_energy() - -for i in range(int(sys.argv[2])): - main(int(sys.argv[1])) + util.run_benchmark(options, options.num_runs, main) From fijal at codespeak.net Mon Jan 18 14:13:25 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 14:13:25 +0100 (CET) Subject: [pypy-svn] r70681 - in pypy/benchmarks: . shootout Message-ID: <20100118131325.1C26E168022@codespeak.net> Author: fijal Date: Mon Jan 18 14:13:24 2010 New Revision: 70681 Modified: pypy/benchmarks/benchmarks.py pypy/benchmarks/runner.py pypy/benchmarks/shootout/meteor-contest.py pypy/benchmarks/shootout/nbody_modified.py Log: Add meteor-contest, kill a bit of unnecessary prints Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Mon Jan 18 14:13:24 2010 @@ -17,5 +17,5 @@ d[BM.func_name] = BM -for name in ['float', 'nbody_modified']: +for name in ['float', 'nbody_modified', 'meteor-contest']: _register_new_bm(name, globals()) Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Mon Jan 18 14:13:24 2010 @@ -25,7 +25,8 @@ f.close() BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', - 'rietveld', 'html5lib', 'ai', 'float', 'nbody_modified'] + 'rietveld', 'html5lib', 'ai'] +BENCHMARK_SET += perf._FindAllBenchmarks(benchmarks.__dict__).keys() class WrongBenchmark(Exception): pass Modified: pypy/benchmarks/shootout/meteor-contest.py ============================================================================== --- pypy/benchmarks/shootout/meteor-contest.py (original) +++ pypy/benchmarks/shootout/meteor-contest.py Mon Jan 18 14:13:24 2010 @@ -4,7 +4,10 @@ # # contributed by Daniel Nanz, 2008-08-21 +import optparse +import util import sys +import time from bisect import bisect w, h = 5, 10 @@ -130,16 +133,29 @@ return return -def main(n): +SOLVE_ARG = 60 - free = frozenset(xrange(len(board))) - curr_board = [-1] * len(board) - pieces_left = range(len(pieces)) - solutions = [] - solve(n, 0, free, curr_board, pieces_left, solutions) - print len(solutions), 'solutions found\n' - for i in (0, -1): print_board(solutions[i]) +def main(n): + times = [] + for i in range(n): + t0 = time.time() + free = frozenset(xrange(len(board))) + curr_board = [-1] * len(board) + pieces_left = range(len(pieces)) + solutions = [] + solve(SOLVE_ARG, 0, free, curr_board, pieces_left, solutions) + #print len(solutions), 'solutions found\n' + #for i in (0, -1): print_board(solutions[i]) + tk = time.time() + times.append(tk - t0) + return times + +if __name__ == "__main__": + parser = optparse.OptionParser( + usage="%prog [options]", + description="Test the performance of the Float benchmark") + util.add_standard_options_to(parser) + options, args = parser.parse_args() -for i in range(int(sys.argv[2])): - main(int(sys.argv[1])) + util.run_benchmark(options, options.num_runs, main) Modified: pypy/benchmarks/shootout/nbody_modified.py ============================================================================== --- pypy/benchmarks/shootout/nbody_modified.py (original) +++ pypy/benchmarks/shootout/nbody_modified.py Mon Jan 18 14:13:24 2010 @@ -95,8 +95,6 @@ e -= (m1 * m2) / ((dx * dx + dy * dy + dz * dz) ** 0.5) for (r, [vx, vy, vz], m) in bodies: e += m * (vx * vx + vy * vy + vz * vz) / 2. - print "%.9f" % e - def offset_momentum(ref, bodies=SYSTEM, px=0.0, py=0.0, pz=0.0): From fijal at codespeak.net Mon Jan 18 14:21:44 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 14:21:44 +0100 (CET) Subject: [pypy-svn] r70682 - in pypy/benchmarks: . shootout Message-ID: <20100118132144.37C94168021@codespeak.net> Author: fijal Date: Mon Jan 18 14:21:43 2010 New Revision: 70682 Modified: pypy/benchmarks/benchmarks.py pypy/benchmarks/shootout/fannkuch.py pypy/benchmarks/shootout/spectral-norm.py Log: Add two more benchmarks. Two more (fasta and binary-trees) needs a bit of thinking Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Mon Jan 18 14:21:43 2010 @@ -17,5 +17,6 @@ d[BM.func_name] = BM -for name in ['float', 'nbody_modified', 'meteor-contest']: +for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch', + 'spectral-norm']: _register_new_bm(name, globals()) Modified: pypy/benchmarks/shootout/fannkuch.py ============================================================================== --- pypy/benchmarks/shootout/fannkuch.py (original) +++ pypy/benchmarks/shootout/fannkuch.py Mon Jan 18 14:21:43 2010 @@ -5,6 +5,10 @@ # contributed by Sokolov Yura # modified by Tupteq +import optparse +import time +import util + def fannkuch(n): count = range(1, n+1) max_flips = 0 @@ -18,7 +22,7 @@ while 1: if check < 30: - print "".join(str(i+1) for i in perm1) + #print "".join(str(i+1) for i in perm1) check += 1 while r != 1: @@ -46,10 +50,22 @@ else: return max_flips +DEFAULT_ARG = 9 + def main(n): - print "Pfannkuchen(%d) = %d\n" % (n, fannkuch(n)), + times = [] + for i in range(n): + t0 = time.time() + fannkuch(DEFAULT_ARG) + tk = time.time() + times.append(tk - t0) + return times + +if __name__ == "__main__": + parser = optparse.OptionParser( + usage="%prog [options]", + description="Test the performance of the Float benchmark") + util.add_standard_options_to(parser) + options, args = parser.parse_args() -if __name__=="__main__": - import sys - for i in range(int(sys.argv[2])): - main(int(sys.argv[1])) + util.run_benchmark(options, options.num_runs, main) Modified: pypy/benchmarks/shootout/spectral-norm.py ============================================================================== --- pypy/benchmarks/shootout/spectral-norm.py (original) +++ pypy/benchmarks/shootout/spectral-norm.py Mon Jan 18 14:21:43 2010 @@ -9,7 +9,10 @@ from math import sqrt from itertools import izip -from sys import argv +import time +import util +import itertools +import optparse def eval_A (i, j): return 1.0 / ((i + j) * (i + j + 1) / 2 + i + 1) @@ -37,22 +40,32 @@ partial_sum += eval_A (j, i) * u_j return partial_sum -def main(): - n = int(argv[1]) - u = [1] * n +DEFAULT_N = 130 - for dummy in xrange (10): - v = eval_AtA_times_u (u) - u = eval_AtA_times_u (v) +def main(n): + times = [] + for i in range(n): + t0 = time.time() + u = [1] * DEFAULT_N + + for dummy in xrange (10): + v = eval_AtA_times_u (u) + u = eval_AtA_times_u (v) + + vBv = vv = 0 + + for ue, ve in izip (u, v): + vBv += ue * ve + vv += ve * ve + tk = time.time() + times.append(tk - t0) + return times + +if __name__ == "__main__": + parser = optparse.OptionParser( + usage="%prog [options]", + description="Test the performance of the Float benchmark") + util.add_standard_options_to(parser) + options, args = parser.parse_args() - vBv = vv = 0 - - for ue, ve in izip (u, v): - vBv += ue * ve - vv += ve * ve - - print "%0.9f" % (sqrt(vBv/vv)) - -if __name__ == '__main__': - for i in range(int(argv[2])): - main() + util.run_benchmark(options, options.num_runs, main) From fijal at codespeak.net Mon Jan 18 14:25:35 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 14:25:35 +0100 (CET) Subject: [pypy-svn] r70683 - pypy/build/bot2/jsplot/js Message-ID: <20100118132535.D8BAB168021@codespeak.net> Author: fijal Date: Mon Jan 18 14:25:35 2010 New Revision: 70683 Modified: pypy/build/bot2/jsplot/js/plot.js Log: Be robust against different starting revisions Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Mon Jan 18 14:25:35 2010 @@ -68,7 +68,12 @@ var elem = $("#placeholder").find("div:last"); var attrs = attrs_for_miniature(); var data; - $("#revstart")[0].value = benchresults[0][0]; + var oldval = $("#revstart")[0].value; + if (!oldval || benchresults[0][0] < oldval) { + // only update stuff when our starting revision is smaller, so we + // get a minimum + $("#revstart")[0].value = benchresults[0][0]; + } $("#revstart").change(function(event) { redisplay(elem, benchresults, cpython_results); }); From fijal at codespeak.net Mon Jan 18 14:44:18 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 14:44:18 +0100 (CET) Subject: [pypy-svn] r70684 - pypy/build/bot2/codespeak-html Message-ID: <20100118134418.214AF168025@codespeak.net> Author: fijal Date: Mon Jan 18 14:44:17 2010 New Revision: 70684 Modified: pypy/build/bot2/codespeak-html/index.html Log: Add a link to graphs Modified: pypy/build/bot2/codespeak-html/index.html ============================================================================== --- pypy/build/bot2/codespeak-html/index.html (original) +++ pypy/build/bot2/codespeak-html/index.html Mon Jan 18 14:44:17 2010 @@ -9,6 +9,7 @@

Welcome to codespeak's PyPy Buildbot!

    +
  • the performance plots will give you an overview of performance for recent revisions.
  • the Summary Display <trunk> will give you a failure-oriented summary for recent revisions (<trunk> only).
  • From fijal at codespeak.net Mon Jan 18 15:02:24 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 15:02:24 +0100 (CET) Subject: [pypy-svn] r70685 - in pypy/trunk/pypy/translator/benchmark: . test Message-ID: <20100118140224.310DC168026@codespeak.net> Author: fijal Date: Mon Jan 18 15:02:24 2010 New Revision: 70685 Removed: pypy/trunk/pypy/translator/benchmark/test/ Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py Log: Disable shootout benchmark here, kill tests as we don't need it any more Modified: pypy/trunk/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/trunk/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/trunk/pypy/translator/benchmark/benchmarks.py Mon Jan 18 15:02:24 2010 @@ -188,8 +188,8 @@ SHOOTOUT_NAMES = ['binary-trees', 'fannkuch', 'fasta', 'float', 'meteor-contest', 'nbody', 'spectral-norm'] -for name in SHOOTOUT_NAMES: - BENCHMARKS.append(LanguageShootoutBenchmark(name)) +#for name in SHOOTOUT_NAMES: +# BENCHMARKS.append(LanguageShootoutBenchmark(name)) BENCHMARKS_BY_NAME = {} for _b in BENCHMARKS: From cfbolz at codespeak.net Mon Jan 18 15:12:01 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 18 Jan 2010 15:12:01 +0100 (CET) Subject: [pypy-svn] r70686 - in pypy/benchmarks: . own shootout Message-ID: <20100118141201.37C80168026@codespeak.net> Author: cfbolz Date: Mon Jan 18 15:12:00 2010 New Revision: 70686 Added: pypy/benchmarks/own/ - copied from r70685, pypy/benchmarks/shootout/ Removed: pypy/benchmarks/shootout/ Modified: pypy/benchmarks/benchmarks.py Log: rename dir to "own" Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Mon Jan 18 15:12:00 2010 @@ -7,7 +7,7 @@ def _register_new_bm(name, d): def Measure(python, options): - bm_path = relative('shootout', name + '.py') + bm_path = relative('own', name + '.py') return MeasureGeneric(python, options, bm_path) Measure.func_name = 'Measure' + name.capitalize() From cfbolz at codespeak.net Mon Jan 18 15:18:02 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 18 Jan 2010 15:18:02 +0100 (CET) Subject: [pypy-svn] r70687 - in pypy/benchmarks: . own Message-ID: <20100118141802.E63C4168026@codespeak.net> Author: cfbolz Date: Mon Jan 18 15:18:02 2010 New Revision: 70687 Added: pypy/benchmarks/own/chaos.py (contents, props changed) Modified: pypy/benchmarks/benchmarks.py Log: add chaos game benchmark Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Mon Jan 18 15:18:02 2010 @@ -18,5 +18,5 @@ d[BM.func_name] = BM for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch', - 'spectral-norm']: + 'spectral-norm', 'chaos']: _register_new_bm(name, globals()) Added: pypy/benchmarks/own/chaos.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/chaos.py Mon Jan 18 15:18:02 2010 @@ -0,0 +1,279 @@ +# Copyright (C) 2005 Carl Friedrich Bolz + +"""create chaosgame-like fractals +""" + +from __future__ import division + +import operator +import optparse +import random +import math +random.seed(1234) +import sys +import time + +class GVector(object): + def __init__(self, x = 0, y = 0, z = 0): + self.x = x + self.y = y + self.z = z + + def Mag(self): + return math.sqrt(self.x ** 2 + self.y ** 2 + self.z ** 2) + + def dist(self, other): + return math.sqrt((self.x - other.x) ** 2 + + (self.y - other.y) ** 2 + + (self.z - other.z) ** 2) + + def __add__(self, other): + if not isinstance(other, GVector): + raise exceptions.ValueError, \ + "Can't add GVector to " + str(type(other)) + v = GVector(self.x + other.x, self.y + other.y, self.z + other.z) + return v + + def __sub__(self, other): + return self + other * -1 + + def __mul__(self, other): + v = GVector(self.x * other, self.y * other, self.z * other) + return v + __rmul__ = __mul__ + + def linear_combination(self, other, l1, l2=None): + if l2 is None: + l2 = 1 - l1 + v = GVector(self.x * l1 + other.x * l2, + self.y * l1 + other.y * l2, + self.z * l1 + other.z * l2) + return v + + + def __str__(self): + return "<%f, %f, %f>" % (self.x, self.y, self.z) + + def __repr__(self): + return "GVector(%f, %f, %f)" % (self.x, self.y, self.z) + +def GetKnots(points, degree): + knots = [0] * degree + range(1, len(points) - degree) + knots += [len(points) - degree] * degree + return knots + +class Spline(object): + """Class for representing B-Splines and NURBS of arbitrary degree""" + def __init__(self, points, degree = 3, knots = None): + """Creates a Spline. points is a list of GVector, degree is the +degree of the Spline.""" + if knots == None: + self.knots = GetKnots(points, degree) + else: + if len(points) > len(knots) - degree + 1: + raise exceptions.ValueError, "too many control points" + elif len(points) < len(knots) - degree + 1: + raise exceptions.ValueError, "not enough control points" + last = knots[0] + for cur in knots[1:]: + if cur < last: + raise exceptions.ValueError, \ + "knots not strictly increasing" + last = cur + self.knots = knots + self.points = points + self.degree = degree + + def GetDomain(self): + """Returns the domain of the B-Spline""" + return (self.knots[self.degree - 1], + self.knots[len(self.knots) - self.degree]) + + def __call__(self, u): + """Calculates a point of the B-Spline using de Boors Algorithm""" + dom = self.GetDomain() + if u < dom[0] or u > dom[1]: + raise exceptions.ValueError, "Function value not in domain" + if u == dom[0]: + return self.points[0] + if u == dom[1]: + return self.points[-1] + I = self.GetIndex(u) + d = [self.points[I - self.degree + 1 + ii] + for ii in range(self.degree + 1)] + U = self.knots + for ik in range(1, self.degree + 1): + for ii in range(I - self.degree + ik + 1, I + 2): + ua = U[ii + self.degree - ik] + ub = U[ii - 1] + co1 = (ua - u) / (ua - ub) + co2 = (u - ub) / (ua - ub) + index = ii - I + self.degree - ik - 1 + d[index] = d[index].linear_combination(d[index + 1], co1, co2) + return d[0] + + def GetIndex(self, u): + dom = self.GetDomain() + for ii in range(self.degree - 1, len(self.knots) - self.degree): + if u >= self.knots[ii] and u < self.knots[ii + 1]: + I = ii + break + else: + I = dom[1] - 1 + return I + + def __len__(self): + return len(self.points) + + def __repr__(self): + return "Spline(%r, %r, %r)" % (self.points, self.degree, self.knots) + + +def save_im(im, fn): + f = open(fn, "wb") + magic = 'P6\n' + maxval = 255 + w = len(im) + h = len(im[0]) + f.write(magic) + f.write('%i %i\n%i\n' % (w, h, maxval)) + for j in range(h): + for i in range(w): + val = im[i][j] + c = val * 255 + f.write('%c%c%c' % (c, c, c)) + f.close() + +class Chaosgame(object): + def __init__(self, splines, thickness=0.1): + self.splines = splines + self.thickness = thickness + self.minx = min([p.x for spl in splines for p in spl.points]) + self.miny = min([p.y for spl in splines for p in spl.points]) + self.maxx = max([p.x for spl in splines for p in spl.points]) + self.maxy = max([p.y for spl in splines for p in spl.points]) + self.height = self.maxy - self.miny + self.width = self.maxx - self.minx + self.num_trafos = [] + maxlength = thickness * self.width / self.height + for spl in splines: + length = 0 + curr = spl(0) + for i in range(1, 1000): + last = curr + t = 1 / 999 * i + curr = spl(t) + length += curr.dist(last) + self.num_trafos.append(max(1, int(length / maxlength * 1.5))) + self.num_total = reduce(operator.add, self.num_trafos, 0) + + + def get_random_trafo(self): + r = random.randrange(int(self.num_total) + 1) + l = 0 + for i in range(len(self.num_trafos)): + if r >= l and r < l + self.num_trafos[i]: + return i, random.randrange(self.num_trafos[i]) + l += self.num_trafos[i] + return len(self.num_trafos) - 1, random.randrange(self.num_trafos[-1]) + + def transform_point(self, point, trafo=None): + x = (point.x - self.minx) / self.width + y = (point.y - self.miny) / self.height + if trafo is None: + trafo = self.get_random_trafo() + start, end = self.splines[trafo[0]].GetDomain() + length = end - start + seg_length = length / self.num_trafos[trafo[0]] + t = start + seg_length * trafo[1] + seg_length * x + basepoint = self.splines[trafo[0]](t) + if t + 1/50000 > end: + neighbour = self.splines[trafo[0]](t - 1/50000) + derivative = neighbour - basepoint + else: + neighbour = self.splines[trafo[0]](t + 1/50000) + derivative = basepoint - neighbour + if derivative.Mag() != 0: + basepoint.x += derivative.y / derivative.Mag() * (y - 0.5) * \ + self.thickness + basepoint.y += -derivative.x / derivative.Mag() * (y - 0.5) * \ + self.thickness + else: + print "r", + self.truncate(basepoint) + return basepoint + + def truncate(self, point): + if point.x >= self.maxx: + point.x = self.maxx + if point.y >= self.maxy: + point.y = self.maxy + if point.x < self.minx: + point.x = self.minx + if point.y < self.miny: + point.y = self.miny + + def create_image_chaos(self, w, h, name, n): + im = [[1] * h for i in range(w)] + point = GVector((self.maxx + self.minx) / 2, + (self.maxy + self.miny) / 2, 0) + colored = 0 + times = [] + for _ in range(n): + random.seed(1234) + t1 = time.time() + for i in xrange(5000): + point = self.transform_point(point) + x = (point.x - self.minx) / self.width * w + y = (point.y - self.miny) / self.height * h + x = int(x) + y = int(y) + if x == w: + x -= 1 + if y == h: + y -= 1 + im[x][h - y - 1] = 0 + t2 = time.time() + times.append(t2 - t1) + save_im(im, name) + return times + + +def main(n): + splines = [ + Spline([ + GVector(1.597350, 3.304460, 0.000000), + GVector(1.575810, 4.123260, 0.000000), + GVector(1.313210, 5.288350, 0.000000), + GVector(1.618900, 5.329910, 0.000000), + GVector(2.889940, 5.502700, 0.000000), + GVector(2.373060, 4.381830, 0.000000), + GVector(1.662000, 4.360280, 0.000000)], + 3, [0, 0, 0, 1, 1, 1, 2, 2, 2]), + Spline([ + GVector(2.804500, 4.017350, 0.000000), + GVector(2.550500, 3.525230, 0.000000), + GVector(1.979010, 2.620360, 0.000000), + GVector(1.979010, 2.620360, 0.000000)], + 3, [0, 0, 0, 1, 1, 1]), + Spline([ + GVector(2.001670, 4.011320, 0.000000), + GVector(2.335040, 3.312830, 0.000000), + GVector(2.366800, 3.233460, 0.000000), + GVector(2.366800, 3.233460, 0.000000)], + 3, [0, 0, 0, 1, 1, 1]) + ] + c = Chaosgame(splines, 0.3) + return c.create_image_chaos(1000, 1200, "py.ppm", n) + + +if __name__ == "__main__": + import util + parser = optparse.OptionParser( + usage="%prog [options]", + description="Test the performance of the Chaos benchmark") + util.add_standard_options_to(parser) + options, args = parser.parse_args() + + util.run_benchmark(options, options.num_runs, main) + From cfbolz at codespeak.net Mon Jan 18 15:26:50 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 18 Jan 2010 15:26:50 +0100 (CET) Subject: [pypy-svn] r70688 - pypy/benchmarks/own Message-ID: <20100118142650.F3995168027@codespeak.net> Author: cfbolz Date: Mon Jan 18 15:26:48 2010 New Revision: 70688 Modified: pypy/benchmarks/own/chaos.py Log: beauty tweaks Modified: pypy/benchmarks/own/chaos.py ============================================================================== --- pypy/benchmarks/own/chaos.py (original) +++ pypy/benchmarks/own/chaos.py Mon Jan 18 15:26:48 2010 @@ -220,7 +220,6 @@ colored = 0 times = [] for _ in range(n): - random.seed(1234) t1 = time.time() for i in xrange(5000): point = self.transform_point(point) @@ -263,7 +262,7 @@ GVector(2.366800, 3.233460, 0.000000)], 3, [0, 0, 0, 1, 1, 1]) ] - c = Chaosgame(splines, 0.3) + c = Chaosgame(splines, 0.25) return c.create_image_chaos(1000, 1200, "py.ppm", n) From fijal at codespeak.net Mon Jan 18 16:31:49 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 18 Jan 2010 16:31:49 +0100 (CET) Subject: [pypy-svn] r70689 - in pypy/branch/jit-profiling/pypy/interpreter: . test Message-ID: <20100118153149.E91B9168039@codespeak.net> Author: fijal Date: Mon Jan 18 16:31:48 2010 New Revision: 70689 Modified: pypy/branch/jit-profiling/pypy/interpreter/baseobjspace.py pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py pypy/branch/jit-profiling/pypy/interpreter/pyframe.py pypy/branch/jit-profiling/pypy/interpreter/pyopcode.py pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py Log: (pedronis, fijal) A tentative checkin, try to kill frame.is_being_profiled. Modified: pypy/branch/jit-profiling/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/baseobjspace.py Mon Jan 18 16:31:48 2010 @@ -791,7 +791,8 @@ def call_valuestack(self, w_func, nargs, frame): from pypy.interpreter.function import Function, Method, is_builtin_code - if frame.is_being_profiled and is_builtin_code(w_func): + if (self.getexecutioncontext().profilefunc is not None + and is_builtin_code(w_func)): # XXX: this code is copied&pasted :-( from the slow path below # call_valuestack(). args = frame.make_arguments(nargs) Modified: pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/executioncontext.py Mon Jan 18 16:31:48 2010 @@ -33,7 +33,7 @@ # JIT: when tracing (but not when blackholing!), the following # self.w_tracefunc should be a constant None - # frame.is_being_profiled should be False for virtual frames + # we should not profile virtual frames # bind it here, so tests can overwrite it _we_are_jitted = staticmethod(jit.we_are_jitted) @@ -77,14 +77,9 @@ def leave(self, frame): try: - # below we need to check if is_being_profiled is set, instead - # of profilefunc, since when jitted we have profilefunc, but not - # is_being_profiled - if frame.is_being_profiled: - self._trace(frame, TRACE_LEAVEFRAME, self.space.w_None) - nextframe = frame.f_backref() - if nextframe is not None: - nextframe.is_being_profiled = True + if not self._we_are_jitted(): + if self.profilefunc is not None: + self._trace(frame, TRACE_LEAVEFRAME, self.space.w_None) finally: self.topframeref = frame.f_backref self.framestackdepth -= 1 @@ -156,20 +151,10 @@ return lst # coroutine: I think this is all, folks! - - def get_builtin(self): - frame = self.gettopframe_nohidden() - if frame is not None: - return frame.builtin - else: - return self.space.builtin - def c_call_trace(self, frame, w_func): "Profile the call of a builtin function" if self._we_are_jitted(): return - if self.profilefunc is None: - frame.is_being_profiled = False else: self._trace(frame, TRACE_C_CALL, w_func) @@ -177,8 +162,6 @@ "Profile the return from a builtin function" if self._we_are_jitted(): return - if self.profilefunc is None: - frame.is_being_profiled = False else: self._trace(frame, TRACE_C_RETURN, w_retval) @@ -186,18 +169,14 @@ "Profile function called upon OperationError." if self._we_are_jitted(): return - if self.profilefunc is None: - frame.is_being_profiled = False else: self._trace(frame, TRACE_C_EXCEPTION, w_exc) def call_trace(self, frame): "Trace the call of a function" - if (self.w_tracefunc is not None or - (not self._we_are_jitted() and self.profilefunc is not None)): - self._trace(frame, TRACE_CALL, self.space.w_None) - if self.profilefunc: - frame.is_being_profiled = True + if not self._we_are_jitted(): + if (self.w_tracefunc is not None or self.profilefunc is not None): + self._trace(frame, TRACE_CALL, self.space.w_None) def return_trace(self, frame, w_retval): "Trace the return from a function" @@ -263,9 +242,6 @@ if func is not None: if w_arg is None: raise ValueError("Cannot call setllprofile with real None") - topframe = self.gettopframe_nohidden() - if topframe is not None: - topframe.is_being_profiled = True self.profilefunc = func self.w_profilefuncarg = w_arg Modified: pypy/branch/jit-profiling/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/pyframe.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/pyframe.py Mon Jan 18 16:31:48 2010 @@ -8,7 +8,7 @@ from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter import pytraceback import opcode -from pypy.rlib.objectmodel import we_are_translated, instantiate +from pypy.rlib.objectmodel import instantiate from pypy.rlib.jit import hint from pypy.rlib.debug import make_sure_not_resized from pypy.rlib import jit @@ -46,7 +46,6 @@ instr_lb = 0 instr_ub = -1 instr_prev = -1 - is_being_profiled = False def __init__(self, space, code, w_globals, closure): self = hint(self, access_directly=True, fresh_virtualizable=True) Modified: pypy/branch/jit-profiling/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/pyopcode.py Mon Jan 18 16:31:48 2010 @@ -912,7 +912,8 @@ arguments = f.popvalues(n_arguments) args = f.argument_factory(arguments, keywords, keywords_w, w_star, w_starstar) w_function = f.popvalue() - if f.is_being_profiled and is_builtin_code(w_function): + if (f.space.getexecutioncontext().profilefunc is not None and + is_builtin_code(w_function)): w_result = f.space.call_args_and_c_profile(f, w_function, args) else: w_result = f.space.call_args(w_function, args) Modified: pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py ============================================================================== --- pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py (original) +++ pypy/branch/jit-profiling/pypy/interpreter/test/test_profiling.py Mon Jan 18 16:31:48 2010 @@ -21,7 +21,6 @@ class MockFrame(object): w_f_trace = None last_exception = None - is_being_profiled = False def hide(self): return False @@ -57,3 +56,11 @@ ec.leave_jit() ec.leave(frame) assert events == [(TRACE_CALL, frame), (TRACE_RETURN, frame)] + + def test_recursive_call(self): + events = [] + def profilefunc(space, ignored, frame, event, w_arg): + events.append((event, frame)) + + ec = MockExecutionContext(self.space) + From antocuni at codespeak.net Mon Jan 18 20:16:06 2010 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 18 Jan 2010 20:16:06 +0100 (CET) Subject: [pypy-svn] r70690 - pypy/branch/cli-jit/pypy/translator/cli/src Message-ID: <20100118191606.9DDED168011@codespeak.net> Author: antocuni Date: Mon Jan 18 20:16:06 2010 New Revision: 70690 Modified: pypy/branch/cli-jit/pypy/translator/cli/src/pypylib.cs Log: it seems that some benchmarks requires more than 256 input arguments. The arrays should grow automatically, but for now just set it to a larger number Modified: pypy/branch/cli-jit/pypy/translator/cli/src/pypylib.cs ============================================================================== --- pypy/branch/cli-jit/pypy/translator/cli/src/pypylib.cs (original) +++ pypy/branch/cli-jit/pypy/translator/cli/src/pypylib.cs Mon Jan 18 20:16:06 2010 @@ -113,9 +113,9 @@ public delegate void LoopDelegate(InputArgs args); public class InputArgs { - public int[] ints = new int[256]; - public double[] floats = new double[256]; - public object[] objs = new object[256]; + public int[] ints = new int[10000]; + public double[] floats = new double[10000]; + public object[] objs = new object[10000]; public object exc_value = null; public int failed_op = -1; From antocuni at codespeak.net Mon Jan 18 21:04:23 2010 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 18 Jan 2010 21:04:23 +0100 (CET) Subject: [pypy-svn] r70691 - in pypy/branch/cli-jit/pypy: annotation rpython/lltypesystem rpython/ootypesystem rpython/ootypesystem/test rpython/test translator/cli translator/jvm/test Message-ID: <20100118200423.2322816801B@codespeak.net> Author: antocuni Date: Mon Jan 18 21:04:21 2010 New Revision: 70691 Modified: pypy/branch/cli-jit/pypy/annotation/builtin.py pypy/branch/cli-jit/pypy/rpython/lltypesystem/lloperation.py pypy/branch/cli-jit/pypy/rpython/ootypesystem/ooopimpl.py pypy/branch/cli-jit/pypy/rpython/ootypesystem/ootype.py pypy/branch/cli-jit/pypy/rpython/ootypesystem/rbuiltin.py pypy/branch/cli-jit/pypy/rpython/ootypesystem/test/test_ootype.py pypy/branch/cli-jit/pypy/rpython/test/test_rclass.py pypy/branch/cli-jit/pypy/translator/cli/opcodes.py pypy/branch/cli-jit/pypy/translator/jvm/test/test_class.py Log: add a new ootype operations 'getsuperclassof', the get the superclass of objects of type ootype.Class Modified: pypy/branch/cli-jit/pypy/annotation/builtin.py ============================================================================== --- pypy/branch/cli-jit/pypy/annotation/builtin.py (original) +++ pypy/branch/cli-jit/pypy/annotation/builtin.py Mon Jan 18 21:04:21 2010 @@ -562,6 +562,10 @@ assert isinstance(class2, SomeOOClass) return s_Bool +def getsuperclassof(class_): + assert isinstance(class_, SomeOOClass) + return SomeOOClass(class_.ootype._superclass) + def runtimenew(c): assert isinstance(c, SomeOOClass) if c.ootype is None: @@ -609,6 +613,7 @@ BUILTIN_ANALYZERS[ootype.runtimenew] = runtimenew BUILTIN_ANALYZERS[ootype.classof] = classof BUILTIN_ANALYZERS[ootype.subclassof] = subclassof +BUILTIN_ANALYZERS[ootype.getsuperclassof] = getsuperclassof BUILTIN_ANALYZERS[ootype.ooupcast] = ooupcast BUILTIN_ANALYZERS[ootype.oodowncast] = oodowncast BUILTIN_ANALYZERS[ootype.cast_to_object] = cast_to_object Modified: pypy/branch/cli-jit/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/cli-jit/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/cli-jit/pypy/rpython/lltypesystem/lloperation.py Mon Jan 18 21:04:21 2010 @@ -557,6 +557,7 @@ 'instanceof': LLOp(oo=True, canfold=True), 'classof': LLOp(oo=True, canfold=True), 'subclassof': LLOp(oo=True, canfold=True), + 'getsuperclassof': LLOp(oo=True, canfold=True), 'oostring': LLOp(oo=True, sideeffects=False), 'ooparse_int': LLOp(oo=True, canraise=(ValueError,)), 'ooparse_float': LLOp(oo=True, canraise=(ValueError,)), Modified: pypy/branch/cli-jit/pypy/rpython/ootypesystem/ooopimpl.py ============================================================================== --- pypy/branch/cli-jit/pypy/rpython/ootypesystem/ooopimpl.py (original) +++ pypy/branch/cli-jit/pypy/rpython/ootypesystem/ooopimpl.py Mon Jan 18 21:04:21 2010 @@ -51,6 +51,9 @@ def op_subclassof(class1, class2): return ootype.subclassof(class1, class2) +def op_getsuperclassof(class_): + return ootype.getsuperclassof(class_) + def op_oogetfield(inst, name): checkinst(inst) if not ootype.typeOf(inst)._hints.get('immutable'): Modified: pypy/branch/cli-jit/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/branch/cli-jit/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/branch/cli-jit/pypy/rpython/ootypesystem/ootype.py Mon Jan 18 21:04:21 2010 @@ -919,6 +919,10 @@ def _cast_to_object(self): return make_object(self) + def _get_superclass(self): + SUPER = self._INSTANCE._superclass + return runtimeClass(SUPER) + def __repr__(self): return '%s(%s)' % (self.__class__.__name__, self._INSTANCE) @@ -1867,6 +1871,9 @@ assert class2 is not nullruntimeclass return isSubclass(class1._INSTANCE, class2._INSTANCE) +def getsuperclassof(class_): + return class_._get_superclass() + def addFields(INSTANCE, fields, with_default=False): INSTANCE._add_fields(fields, with_default) Modified: pypy/branch/cli-jit/pypy/rpython/ootypesystem/rbuiltin.py ============================================================================== --- pypy/branch/cli-jit/pypy/rpython/ootypesystem/rbuiltin.py (original) +++ pypy/branch/cli-jit/pypy/rpython/ootypesystem/rbuiltin.py Mon Jan 18 21:04:21 2010 @@ -36,6 +36,12 @@ return hop.genop('subclassof', vlist, resulttype = ootype.Bool) +def rtype_getsuperclassof(hop): + assert isinstance(hop.args_s[0], annmodel.SomeOOClass) + vlist = hop.inputargs(hop.args_r[0]) + return hop.genop('getsuperclassof', vlist, + resulttype = ootype.Class) + def rtype_instanceof(hop): INSTANCE = hop.args_v[1].value v_inst = hop.inputarg(hop.args_r[0], arg=0) @@ -124,6 +130,7 @@ BUILTIN_TYPER[ootype.null] = rtype_null BUILTIN_TYPER[ootype.classof] = rtype_classof BUILTIN_TYPER[ootype.subclassof] = rtype_subclassof +BUILTIN_TYPER[ootype.getsuperclassof] = rtype_getsuperclassof BUILTIN_TYPER[ootype.instanceof] = rtype_instanceof BUILTIN_TYPER[ootype.runtimenew] = rtype_runtimenew BUILTIN_TYPER[ootype.ooupcast] = rtype_ooupcast Modified: pypy/branch/cli-jit/pypy/rpython/ootypesystem/test/test_ootype.py ============================================================================== --- pypy/branch/cli-jit/pypy/rpython/ootypesystem/test/test_ootype.py (original) +++ pypy/branch/cli-jit/pypy/rpython/ootypesystem/test/test_ootype.py Mon Jan 18 21:04:21 2010 @@ -377,6 +377,17 @@ 1, 1, 1, ] +def test_getsuperclassof(): + A = Instance("A", ROOT) + B = Instance("B", A) + C = Instance("C", B) + clsA = runtimeClass(A) + clsB = runtimeClass(B) + clsC = runtimeClass(C) + assert getsuperclassof(clsC) is clsB + assert getsuperclassof(clsB) is clsA + assert getsuperclassof(clsA) is runtimeClass(ROOT) + def test_static_method_equality(): SM = StaticMethod([], Signed) SM1 = StaticMethod([], Signed) Modified: pypy/branch/cli-jit/pypy/rpython/test/test_rclass.py ============================================================================== --- pypy/branch/cli-jit/pypy/rpython/test/test_rclass.py (original) +++ pypy/branch/cli-jit/pypy/rpython/test/test_rclass.py Mon Jan 18 21:04:21 2010 @@ -997,3 +997,16 @@ return ootype.NULL res = self.interpret(fn_mix_null, [False]) assert res is ootype.NULL + + def test_getsuperclassof(self): + A = ootype.Instance("A", ootype.ROOT) + B = ootype.Instance("B", A) + clsA = ootype.runtimeClass(A) + clsB = ootype.runtimeClass(B) + + def fn(flag): + cls = flag and clsA or clsB + return ootype.getsuperclassof(cls) is clsA + + res = self.interpret(fn, [False], backendopt=False) + assert res Modified: pypy/branch/cli-jit/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/branch/cli-jit/pypy/translator/cli/opcodes.py (original) +++ pypy/branch/cli-jit/pypy/translator/cli/opcodes.py Mon Jan 18 21:04:21 2010 @@ -59,6 +59,7 @@ 'classof': [PushAllArgs, 'callvirt instance class [mscorlib]System.Type object::GetType()'], 'instanceof': [CastTo, 'ldnull', 'cgt.un'], 'subclassof': [PushAllArgs, 'call bool [pypylib]pypy.runtime.Utils::SubclassOf(class [mscorlib]System.Type, class[mscorlib]System.Type)'], + 'getsuperclassof': [PushAllArgs, 'callvirt instance class [mscorlib]System.Type class [mscorlib]System.Type::get_BaseType()'], 'gc_id': [PushAllArgs, 'call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetHashCode(object)'], # XXX not implemented 'gc_identityhash': [PushAllArgs, 'call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetHashCode(object)'], 'oostring': [OOString], Modified: pypy/branch/cli-jit/pypy/translator/jvm/test/test_class.py ============================================================================== --- pypy/branch/cli-jit/pypy/translator/jvm/test/test_class.py (original) +++ pypy/branch/cli-jit/pypy/translator/jvm/test/test_class.py Mon Jan 18 21:04:21 2010 @@ -27,5 +27,8 @@ def test_specialize_methods(self): py.test.skip('ABSTRACT METHOD FIX: RE-TEST AFTER MERGE') + def test_getsuperclassof(self): + py.test.skip('fixme') + class TestJvmSpecialCase(JvmTest, BaseTestSpecialcase): pass From antocuni at codespeak.net Mon Jan 18 21:52:05 2010 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 18 Jan 2010 21:52:05 +0100 (CET) Subject: [pypy-svn] r70693 - in pypy/branch/cli-jit/pypy/jit/metainterp: . test Message-ID: <20100118205205.0A10916801B@codespeak.net> Author: antocuni Date: Mon Jan 18 21:52:04 2010 New Revision: 70693 Modified: pypy/branch/cli-jit/pypy/jit/metainterp/codewriter.py pypy/branch/cli-jit/pypy/jit/metainterp/history.py pypy/branch/cli-jit/pypy/jit/metainterp/test/test_send.py Log: make AbstractMethDescr.jitcodes much smaller: instead of storing an entry for each possible class, we store it only for classes where the method is actually defined, and then we walk through the superclasses when we need it. The net result is that the static data is waaay smaller: the exe of pypy-cli-jit is now 14MB instead of 26MB, and the startup time is 29s instead of 1m:49s Modified: pypy/branch/cli-jit/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/cli-jit/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/cli-jit/pypy/jit/metainterp/codewriter.py Mon Jan 18 21:52:04 2010 @@ -297,8 +297,8 @@ assert isinstance(INSTANCE, ootype.Instance) TYPES = INSTANCE._all_subclasses() for T in TYPES: - _, meth = T._lookup(methname) - if not getattr(meth, 'abstract', False): + TDEF, meth = T._lookup(methname) + if TDEF is T and not getattr(meth, 'abstract', False): assert meth.graph if self.is_candidate(meth.graph): jitcode = self.get_jitcode(meth.graph, Modified: pypy/branch/cli-jit/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/cli-jit/pypy/jit/metainterp/history.py (original) +++ pypy/branch/cli-jit/pypy/jit/metainterp/history.py Mon Jan 18 21:52:04 2010 @@ -141,7 +141,13 @@ # jitcodes maps { runtimeClass -> jitcode for runtimeClass.methname } self.jitcodes = jitcodes def get_jitcode_for_class(self, oocls): - return self.jitcodes[oocls] + rootcls = ootype.runtimeClass(ootype.ROOT) + while oocls is not rootcls: + try: + return self.jitcodes[oocls] + except KeyError: + oocls = ootype.getsuperclassof(oocls) + assert False, 'we should never get here' class Const(AbstractValue): Modified: pypy/branch/cli-jit/pypy/jit/metainterp/test/test_send.py ============================================================================== --- pypy/branch/cli-jit/pypy/jit/metainterp/test/test_send.py (original) +++ pypy/branch/cli-jit/pypy/jit/metainterp/test/test_send.py Mon Jan 18 21:52:04 2010 @@ -607,6 +607,39 @@ res = self.meta_interp(fn, [20], policy=StopAtXPolicy(extern)) assert res == 21 + def test_call_method_of_base_class(self): + myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'w', 'res']) + class Base: + def foo(self): + return 42 + class W1(Base): + pass + class W2(Base): + def foo(self): + return 43 + + def f(x, y): + if x == 0: + w = Base() + elif x == 1: + w = W1() + else: + w = W2() + res = 0 + while y > 0: + myjitdriver.can_enter_jit(x=x, y=y, w=w, res=res) + myjitdriver.jit_merge_point(x=x, y=y, w=w, res=res) + res = w.foo() + y -= 1 + return res + res = self.meta_interp(f, [0, 10]) + assert res == 42 + res = self.meta_interp(f, [1, 10]) + assert res == 42 + res = self.meta_interp(f, [2, 10]) + assert res == 43 + + class TestOOtype(SendTests, OOJitMixin): pass From benjamin at codespeak.net Tue Jan 19 00:24:05 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 19 Jan 2010 00:24:05 +0100 (CET) Subject: [pypy-svn] r70694 - in pypy/trunk/pypy/objspace: . test Message-ID: <20100118232405.D2EBC16801B@codespeak.net> Author: benjamin Date: Tue Jan 19 00:24:04 2010 New Revision: 70694 Modified: pypy/trunk/pypy/objspace/descroperation.py pypy/trunk/pypy/objspace/test/test_descriptor.py Log: only override values in the instance dictionary if __get__ is defined resolves issue #491 Modified: pypy/trunk/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/pypy/objspace/descroperation.py (original) +++ pypy/trunk/pypy/objspace/descroperation.py Tue Jan 19 00:24:04 2010 @@ -35,7 +35,13 @@ w_descr = space.lookup(w_obj, name) if w_descr is not None: if space.is_data_descr(w_descr): - return space.get(w_descr, w_obj) + # Only override if __get__ is defined, too, for compatibility + # with CPython. + w_get = space.lookup(w_descr, "__get__") + if w_get is not None: + w_type = space.type(w_obj) + return space.get_and_call_function(w_get, w_descr, w_obj, + w_type) w_value = w_obj.getdictvalue_attr_is_in_class(space, name) else: w_value = w_obj.getdictvalue(space, name) Modified: pypy/trunk/pypy/objspace/test/test_descriptor.py ============================================================================== --- pypy/trunk/pypy/objspace/test/test_descriptor.py (original) +++ pypy/trunk/pypy/objspace/test/test_descriptor.py Tue Jan 19 00:24:04 2010 @@ -12,6 +12,24 @@ del x.f assert x.f() == 42 + def test_set_without_get(self): + class Descr(object): + + def __init__(self, name): + self.name = name + + def __set__(self, obj, value): + obj.__dict__[self.name] = value + descr = Descr("a") + + class X(object): + a = descr + + x = X() + assert x.a is descr + x.a = 42 + assert x.a == 42 + def test_member(self): class X(object): def __init__(self): From cfbolz at codespeak.net Tue Jan 19 09:41:08 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 19 Jan 2010 09:41:08 +0100 (CET) Subject: [pypy-svn] r70695 - in pypy/benchmarks: . own Message-ID: <20100119084108.36BA316801D@codespeak.net> Author: cfbolz Date: Tue Jan 19 09:41:06 2010 New Revision: 70695 Added: pypy/benchmarks/own/telco-bench.b (contents, props changed) pypy/benchmarks/own/telco.py (contents, props changed) Modified: pypy/benchmarks/benchmarks.py Log: Add telco benchmark. Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Tue Jan 19 09:41:06 2010 @@ -18,5 +18,5 @@ d[BM.func_name] = BM for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch', - 'spectral-norm', 'chaos']: + 'spectral-norm', 'chaos', 'telco']: _register_new_bm(name, globals()) Added: pypy/benchmarks/own/telco-bench.b ============================================================================== Binary file. No diff available. Added: pypy/benchmarks/own/telco.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/telco.py Tue Jan 19 09:41:06 2010 @@ -0,0 +1,96 @@ +#-*- coding: UTF-8 -*- +""" Telco Benchmark for measuring the performance of decimal calculations + +http://www2.hursley.ibm.com/decimal/telco.html +http://www2.hursley.ibm.com/decimal/telcoSpec.html + +A call type indicator, c, is set from the bottom (least significant) bit of the duration (hence c is 0 or 1). +A r, r, is determined from the call type. Those calls with c=0 have a low r: 0.0013; the remainder (?distance calls?) have a ?premium? r: 0.00894. (The rates are, very roughly, in Euros or dollarates per second.) +A price, p, for the call is then calculated (p=r*n). This is rounded to exactly 2 fractional digits using round-half-even (Banker?s round to nearest). +A basic tax, b, is calculated: b=p*0.0675 (6.75%). This is truncated to exactly 2 fractional digits (round-down), and the total basic tax variable is then incremented (sumB=sumB+b). +For distance calls: a distance tax, d, is calculated: d=p*0.0341 (3.41%). This is truncated to exactly 2 fractional digits (round-down), and then the total distance tax variable is incremented (sumD=sumD+d). +The total price, t, is calculated (t=p+b, and, if a distance call, t=t+d). +The total prices variable is incremented (sumT=sumT+t). +The total price, t, is converted to a string, s. + +""" + +from struct import unpack +from time import clock as time +from decimal import * +import sys, os +def rel_path(path): + return os.path.join(os.path.dirname(__file__), path) + +test = False + +filename = rel_path("telco-bench.b") + +def run(): + getcontext().rounding = ROUND_DOWN + rates = map(Decimal, ('0.0013', '0.00894')) + twodig = Decimal('0.01') + Banker = Context(rounding=ROUND_HALF_EVEN) + basictax = Decimal("0.0675") + disttax = Decimal("0.0341") + + infil = open(filename, "rb") + outfil = open("telco.out", "w") + start = time() + + sumT = Decimal("0") # sum of total prices + sumB = Decimal("0") # sum of basic tax + sumD = Decimal("0") # sum of 'distance' tax + + for i in range(5000): + datum = infil.read(8) + if datum == '': break + n, = unpack('>Q', datum) + + calltype = n & 1 + r = rates[calltype] + + p = Banker.quantize(r * n, twodig) + + b = p * basictax + b = b.quantize(twodig) + sumB += b + + t = p + b + + if calltype: + d = p * disttax + d = d.quantize(twodig) + sumD += d + t += d + + sumT += t + print >> outfil, t + + if test: + print '%6d %1s |%6s %6s %6s |%6s' % (n, 'LD'[calltype], p, b, (not calltype and " " or d), t) + + infil.close() + outfil.close() + end = time() + return end - start + +def main(n): + run() # warmup + times = [] + for i in range(n): + times.append(run()) + return times + + + +if __name__ == "__main__": + import optparse + import util + parser = optparse.OptionParser( + usage="%prog [options]", + description="Test the performance of the Telco decimal benchmark") + util.add_standard_options_to(parser) + options, args = parser.parse_args() + + util.run_benchmark(options, options.num_runs, main) From cfbolz at codespeak.net Tue Jan 19 10:24:47 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 19 Jan 2010 10:24:47 +0100 (CET) Subject: [pypy-svn] r70696 - pypy/branch/bridges-experimental Message-ID: <20100119092447.C066D168020@codespeak.net> Author: cfbolz Date: Tue Jan 19 10:24:47 2010 New Revision: 70696 Added: pypy/branch/bridges-experimental/ - copied from r70695, pypy/trunk/ Log: An experimental, probably not to-be-merged branch where I want to try out an idea about when to attach bridges. From afa at codespeak.net Tue Jan 19 10:34:00 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 19 Jan 2010 10:34:00 +0100 (CET) Subject: [pypy-svn] r70697 - in pypy/branch/separate-compilation/pypy/translator/c: . test Message-ID: <20100119093400.62B4A168020@codespeak.net> Author: afa Date: Tue Jan 19 10:33:59 2010 New Revision: 70697 Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py pypy/branch/separate-compilation/pypy/translator/c/separate.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Fix test Modified: pypy/branch/separate-compilation/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/genc.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/genc.py Tue Jan 19 10:33:59 2010 @@ -312,7 +312,12 @@ return None def getexportsymbols(self): - return self.export_node_names.values() + ['RPython_StartupCode'] + entrypoint = self.getentrypointptr() + if isinstance(entrypoint, (list, tuple)): + export_symbols = [self.db.get(fn) for fn in entrypoint] + else: + export_symbols = [self.db.get(entrypoint)] + return export_symbols + ['RPython_StartupCode'] def compile(self): assert self.c_source_filename Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Tue Jan 19 10:33:59 2010 @@ -31,6 +31,7 @@ wrapper = miniglobals['wrapper'] wrapper._annspecialcase_ = 'specialize:ll' wrapper._always_inline_ = True + wrapper._about = cls return func_with_new_name(wrapper, name) def annotate_exported_functions(self, annotator): @@ -88,8 +89,10 @@ return exported_funcptr def make_import_module(self, builder, node_names): - class Module: - pass + class Module(object): + _annotated = False + + _exported_classes = self.exported_class.values() mod = Module() mod.__file__ = builder.so_name @@ -103,7 +106,7 @@ post_include_bits = forwards ) - for funcname, import_name in builder.export_node_names.items(): + for funcname, import_name in node_names.items(): functype = lltype.typeOf(builder.entrypoint[funcname]) func = make_ll_import_function(import_name, functype, import_eci) setattr(mod, funcname, func) Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Tue Jan 19 10:33:59 2010 @@ -166,6 +166,7 @@ assert c_fn() == 73.5 def test_structure_attributes(self): + py.test.skip("WIP") firstmodule = self.compile_separated( "first", S=self.S) From fijal at codespeak.net Tue Jan 19 12:14:04 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 19 Jan 2010 12:14:04 +0100 (CET) Subject: [pypy-svn] r70698 - pypy/branch/direct-assembler-call Message-ID: <20100119111404.086F5168020@codespeak.net> Author: fijal Date: Tue Jan 19 12:14:04 2010 New Revision: 70698 Removed: pypy/branch/direct-assembler-call/ Log: (pedronis, fijal) Remove the old branch From fijal at codespeak.net Tue Jan 19 12:14:28 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 19 Jan 2010 12:14:28 +0100 (CET) Subject: [pypy-svn] r70699 - pypy/branch/direct-assembler-call Message-ID: <20100119111428.0592B168020@codespeak.net> Author: fijal Date: Tue Jan 19 12:14:27 2010 New Revision: 70699 Added: pypy/branch/direct-assembler-call/ - copied from r70698, pypy/trunk/ Log: (pedronis, fijal) Branch to implement direct assembler calls From fijal at codespeak.net Tue Jan 19 12:18:04 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 19 Jan 2010 12:18:04 +0100 (CET) Subject: [pypy-svn] r70700 - in pypy/branch/direct-assembler-call/pypy/jit/metainterp: . test Message-ID: <20100119111804.68F2D168020@codespeak.net> Author: fijal Date: Tue Jan 19 12:18:03 2010 New Revision: 70700 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py Log: (pedronis, fijal) Merge 69283 from the previous branch, (arigo, fijal) IN-PROGRESS start thinking about direct calls Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Tue Jan 19 12:18:03 2010 @@ -42,16 +42,10 @@ argtypes = unrolling_iterable(self.argtypes) def wrapped(self, orgpc): args = (self, ) - #if DEBUG >= DEBUG_DETAILED: - # s = '%s:%d\t%s' % (self.jitcode.name, orgpc, name) - #else: - s = '' for argspec in argtypes: if argspec == "box": box = self.load_arg() args += (box, ) - #if DEBUG >= DEBUG_DETAILED: - # s += '\t' + box.repr_rpython() elif argspec == "constbox": args += (self.load_const_arg(), ) elif argspec == "int": @@ -82,12 +76,7 @@ args += (methdescr, ) else: assert 0, "unknown argtype declaration: %r" % (argspec,) - #if DEBUG >= DEBUG_DETAILED: - # debug_print(s) val = func(*args) - #if DEBUG >= DEBUG_DETAILED: - # reprboxes = ' '.join([box.repr_rpython() for box in self.env]) - # debug_print(' \x1b[34menv=[%s]\x1b[0m' % (reprboxes,)) if val is None: val = False return val @@ -680,6 +669,9 @@ greenkey = varargs[1:num_green_args + 1] if warmrunnerstate.can_inline_callable(greenkey): return self.perform_call(portal_code, varargs[1:], greenkey) + token = warmrunnerstate.get_assembler_token(greenkey) + if token is not None: + return self.metainterp.direct_assembler_call(varargs, token) return self.do_residual_call(varargs, descr=calldescr, exc=True) @arguments("descr", "varargs") @@ -2000,6 +1992,15 @@ max_key = key return max_key + def direct_assembler_call(self, varargs, token): + """ Generate a direct call to assembler for portal entry point. + """ + num_green_args = self.staticdata.num_green_args + assert self.staticdata.virtualizable_info is None # XXX + args = varargs[num_green_args + 1:] + xxx + self.framestack[-1].execute_varargs(rop.CALL_ASSEMBLER, args, + descr=token, exc=False) class GenerateMergePoint(Exception): def __init__(self, args, target_loop_token): Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Tue Jan 19 12:18:03 2010 @@ -648,7 +648,22 @@ self.check_aborted_count(1) self.check_history(call_may_force=1, call=0) self.check_tree_loop_count(3) - + + def test_directly_call_assembler(self): + driver = JitDriver(greens = ['codeno'], reds = ['i'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno): + i = 0 + while i < 10: + driver.can_enter_jit(codeno = codeno, i = i) + driver.jit_merge_point(codeno = codeno, i = i) + if codeno == 2: + portal(1) + i += 1 + + self.meta_interp(portal, [2], inline=True) class TestLLtype(RecursiveTests, LLJitMixin): pass Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py Tue Jan 19 12:18:03 2010 @@ -454,6 +454,7 @@ unwrap_greenkey = self.make_unwrap_greenkey() if can_inline_ptr is None: def can_inline_callable(*greenargs): + # XXX shouldn't it be False by default? return True else: rtyper = self.warmrunnerdesc.rtyper @@ -471,6 +472,16 @@ greenargs = unwrap_greenkey(greenkey) return can_inline(*greenargs) self.can_inline_callable = can_inline_greenkey + + get_jitcell = self.make_jitcell_getter() + def get_assembler_token(greenkey): + greenargs = unwrap_greenkey(greenkey) + cell = get_jitcell(*greenargs) + if cell.counter >= 0: + return None + return cell.entry_loop_token + self.get_assembler_token = get_assembler_token + # get_location_ptr = self.warmrunnerdesc.get_printable_location_ptr if get_location_ptr is None: From antocuni at codespeak.net Tue Jan 19 14:10:31 2010 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 19 Jan 2010 14:10:31 +0100 (CET) Subject: [pypy-svn] r70701 - pypy/branch/cli-jit/pypy/jit/metainterp Message-ID: <20100119131031.05A2E168020@codespeak.net> Author: antocuni Date: Tue Jan 19 14:10:31 2010 New Revision: 70701 Modified: pypy/branch/cli-jit/pypy/jit/metainterp/typesystem.py Log: don't crash if obj is null Modified: pypy/branch/cli-jit/pypy/jit/metainterp/typesystem.py ============================================================================== --- pypy/branch/cli-jit/pypy/jit/metainterp/typesystem.py (original) +++ pypy/branch/cli-jit/pypy/jit/metainterp/typesystem.py Tue Jan 19 14:10:31 2010 @@ -187,7 +187,10 @@ def cls_of_box(self, cpu, box): obj = box.getref(ootype.ROOT) - oocls = ootype.classof(obj) + if not obj: + oocls = ootype.runtimeClass(ootype.ROOT) + else: + oocls = ootype.classof(obj) return history.ConstObj(ootype.cast_to_object(oocls)) def subclassOf(self, cpu, clsbox1, clsbox2): From antocuni at codespeak.net Tue Jan 19 14:12:00 2010 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Tue, 19 Jan 2010 14:12:00 +0100 (CET) Subject: [pypy-svn] r70702 - in pypy/branch/cli-jit/pypy: interpreter jit/metainterp jit/metainterp/test module/pypyjit rlib Message-ID: <20100119131200.A2E25168020@codespeak.net> Author: antocuni Date: Tue Jan 19 14:11:59 2010 New Revision: 70702 Modified: pypy/branch/cli-jit/pypy/interpreter/baseobjspace.py pypy/branch/cli-jit/pypy/interpreter/executioncontext.py pypy/branch/cli-jit/pypy/interpreter/pyframe.py pypy/branch/cli-jit/pypy/interpreter/pyopcode.py pypy/branch/cli-jit/pypy/jit/metainterp/test/test_basic.py pypy/branch/cli-jit/pypy/jit/metainterp/test/test_warmstate.py pypy/branch/cli-jit/pypy/jit/metainterp/warmspot.py pypy/branch/cli-jit/pypy/jit/metainterp/warmstate.py pypy/branch/cli-jit/pypy/module/pypyjit/interp_jit.py pypy/branch/cli-jit/pypy/rlib/jit.py Log: merge r70415 and r70454 from trunk: merge the jit-trace branch and kill a lot of "we_are_jitted", to make sys.settrace working inside loops Modified: pypy/branch/cli-jit/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/cli-jit/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/cli-jit/pypy/interpreter/baseobjspace.py Tue Jan 19 14:11:59 2010 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer -from pypy.rlib.jit import we_are_jitted, dont_look_inside, unroll_safe +from pypy.rlib.jit import unroll_safe import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -756,8 +756,7 @@ def call_valuestack(self, w_func, nargs, frame): from pypy.interpreter.function import Function, Method, is_builtin_code - if (not we_are_jitted() and frame.is_being_profiled and - is_builtin_code(w_func)): + if frame.is_being_profiled and is_builtin_code(w_func): # XXX: this code is copied&pasted :-( from the slow path below # call_valuestack(). args = frame.make_arguments(nargs) @@ -784,7 +783,6 @@ args = frame.make_arguments(nargs) return self.call_args(w_func, args) - @dont_look_inside def call_args_and_c_profile(self, frame, w_func, args): ec = self.getexecutioncontext() ec.c_call_trace(frame, w_func) Modified: pypy/branch/cli-jit/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/cli-jit/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/cli-jit/pypy/interpreter/executioncontext.py Tue Jan 19 14:11:59 2010 @@ -3,8 +3,8 @@ from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import LONG_BIT from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.jit import we_are_jitted from pypy.rlib import jit +from pypy.rlib.jit import we_are_jitted def app_profile_call(space, w_callable, frame, event, w_arg): space.call_function(w_callable, @@ -15,16 +15,21 @@ """An ExecutionContext holds the state of an execution thread in the Python interpreter.""" + # XXX JIT: when tracing (but not when blackholing!), the following + # XXX fields should be known to a constant None or False: + # XXX self.w_tracefunc, self.profilefunc + # XXX frame.is_being_profiled + def __init__(self, space): self.space = space self._init_frame_chain() # tracing: space.frame_trace_action.fire() must be called to ensure # that tracing occurs whenever self.w_tracefunc or self.is_tracing # is modified. - self.w_tracefunc = None + self.w_tracefunc = None # if not None, no JIT self.is_tracing = 0 self.compiler = space.createcompiler() - self.profilefunc = None + self.profilefunc = None # if not None, no JIT self.w_profilefuncarg = None def gettopframe_nohidden(self): @@ -50,7 +55,6 @@ def leave(self, frame): if self.profilefunc: self._trace(frame, 'leaveframe', self.space.w_None) - self._unchain(frame) if self.w_tracefunc is not None and not frame.hide(): @@ -269,7 +273,6 @@ space.setitem(w_globals, w_key, w_value) return w_globals - @jit.dont_look_inside def c_call_trace(self, frame, w_func): "Profile the call of a builtin function" if self.profilefunc is None: @@ -277,7 +280,6 @@ else: self._trace(frame, 'c_call', w_func) - @jit.dont_look_inside def c_return_trace(self, frame, w_retval): "Profile the return from a builtin function" if self.profilefunc is None: @@ -285,7 +287,6 @@ else: self._trace(frame, 'c_return', w_retval) - @jit.dont_look_inside def c_exception_trace(self, frame, w_exc): "Profile function called upon OperationError." if self.profilefunc is None: @@ -293,7 +294,6 @@ else: self._trace(frame, 'c_exception', w_exc) - @jit.dont_look_inside def call_trace(self, frame): "Trace the call of a function" if self.w_tracefunc is not None or self.profilefunc is not None: @@ -301,7 +301,6 @@ if self.profilefunc: frame.is_being_profiled = True - @jit.dont_look_inside def return_trace(self, frame, w_retval): "Trace the return from a function" if self.w_tracefunc is not None: @@ -320,7 +319,14 @@ actionflag.action_dispatcher(self, frame) # slow path bytecode_trace._always_inline_ = True - @jit.dont_look_inside + def bytecode_trace_after_exception(self, frame): + "Like bytecode_trace(), but without increasing the ticker." + actionflag = self.space.actionflag + ticker = actionflag.get() + if ticker & actionflag.interesting_bits: # fast check + actionflag.action_dispatcher(self, frame) # slow path + bytecode_trace_after_exception._always_inline_ = True + def exception_trace(self, frame, operationerr): "Trace function called upon OperationError." operationerr.record_interpreter_traceback() @@ -343,6 +349,7 @@ if self.space.is_w(w_func, self.space.w_None): self.w_tracefunc = None else: + self.force_all_frames() self.w_tracefunc = w_func self.space.frame_trace_action.fire() @@ -355,16 +362,27 @@ self.setllprofile(app_profile_call, w_func) def setllprofile(self, func, w_arg): - self.profilefunc = func if func is not None: if w_arg is None: raise ValueError("Cannot call setllprofile with real None") - frame = self.gettopframe_nohidden() - while frame: - frame.is_being_profiled = True - frame = self.getnextframe_nohidden(frame) + self.force_all_frames(is_being_profiled=True) + self.profilefunc = func self.w_profilefuncarg = w_arg + def force_all_frames(self, is_being_profiled=False): + # "Force" all frames in the sense of the jit, and optionally + # set the flag 'is_being_profiled' on them. A forced frame is + # one out of which the jit will exit: if it is running so far, + # in a piece of assembler currently running a CALL_MAY_FORCE, + # then being forced means that it will fail the following + # GUARD_NOT_FORCED operation, and so fall back to interpreted + # execution. + frame = self.gettopframe_nohidden() + while frame: + if is_being_profiled: + frame.is_being_profiled = True + frame = self.getnextframe_nohidden(frame) + def call_tracing(self, w_func, w_args): is_tracing = self.is_tracing self.is_tracing = 0 @@ -573,7 +591,7 @@ def fire_after_thread_switch(self): """Bit of a hack: fire() the action but only the next time the GIL - is released and re-acquired (i.e. after a portential thread switch). + is released and re-acquired (i.e. after a potential thread switch). Don't call this if threads are not enabled. """ from pypy.module.thread.gil import spacestate Modified: pypy/branch/cli-jit/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/cli-jit/pypy/interpreter/pyframe.py (original) +++ pypy/branch/cli-jit/pypy/interpreter/pyframe.py Tue Jan 19 14:11:59 2010 @@ -9,7 +9,7 @@ from pypy.interpreter import pytraceback import opcode from pypy.rlib.objectmodel import we_are_translated, instantiate -from pypy.rlib.jit import we_are_jitted, hint +from pypy.rlib.jit import hint from pypy.rlib.debug import make_sure_not_resized from pypy.rlib import jit @@ -142,8 +142,7 @@ executioncontext = self.space.getexecutioncontext() executioncontext.enter(self) try: - if not we_are_jitted(): - executioncontext.call_trace(self) + executioncontext.call_trace(self) # Execution starts just after the last_instr. Initially, # last_instr is -1. After a generator suspends it points to # the YIELD_VALUE instruction. @@ -154,11 +153,9 @@ rstack.resume_point("execute_frame", self, executioncontext, returns=w_exitvalue) except Exception: - if not we_are_jitted(): - executioncontext.return_trace(self, self.space.w_None) + executioncontext.return_trace(self, self.space.w_None) raise - if not we_are_jitted(): - executioncontext.return_trace(self, w_exitvalue) + executioncontext.return_trace(self, w_exitvalue) finally: executioncontext.leave(self) return w_exitvalue @@ -392,6 +389,7 @@ new_frame.instr_prev = space.int_w(w_instr_prev) self._setcellvars(cellvars) + # XXX what if the frame is in another thread?? space.frame_trace_action.fire() def hide(self): Modified: pypy/branch/cli-jit/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/cli-jit/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/cli-jit/pypy/interpreter/pyopcode.py Tue Jan 19 14:11:59 2010 @@ -130,7 +130,7 @@ def handle_operation_error(self, ec, operr, attach_tb=True): if attach_tb: - if not jit.we_are_jitted(): + if 1: # xxx this is a hack. It allows bytecode_trace() to # call a signal handler which raises, and catch the # raised exception immediately. See test_alarm_raise in @@ -146,15 +146,14 @@ trace = self.w_f_trace self.w_f_trace = None try: - ec.bytecode_trace(self) + ec.bytecode_trace_after_exception(self) finally: self.w_f_trace = trace except OperationError, e: operr = e pytraceback.record_application_traceback( self.space, operr, self, self.last_instr) - if not jit.we_are_jitted(): - ec.exception_trace(self, operr) + ec.exception_trace(self, operr) block = self.unrollstack(SApplicationException.kind) if block is None: @@ -913,13 +912,10 @@ arguments = f.popvalues(n_arguments) args = f.argument_factory(arguments, keywords, keywords_w, w_star, w_starstar) w_function = f.popvalue() - if jit.we_are_jitted(): - w_result = f.space.call_args(w_function, args) + if f.is_being_profiled and is_builtin_code(w_function): + w_result = f.space.call_args_and_c_profile(f, w_function, args) else: - if f.is_being_profiled and is_builtin_code(w_function): - w_result = f.space.call_args_and_c_profile(f, w_function, args) - else: - w_result = f.space.call_args(w_function, args) + w_result = f.space.call_args(w_function, args) rstack.resume_point("call_function", f, returns=w_result) f.pushvalue(w_result) Modified: pypy/branch/cli-jit/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/cli-jit/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/cli-jit/pypy/jit/metainterp/test/test_basic.py Tue Jan 19 14:11:59 2010 @@ -377,6 +377,26 @@ res = self.meta_interp(f, [55]) assert res == -1 + def test_confirm_enter_jit(self): + def confirm_enter_jit(x, y): + return x <= 5 + myjitdriver = JitDriver(greens = ['x'], reds = ['y'], + confirm_enter_jit = confirm_enter_jit) + def f(x, y): + while y >= 0: + myjitdriver.can_enter_jit(x=x, y=y) + myjitdriver.jit_merge_point(x=x, y=y) + y -= x + return y + # + res = self.meta_interp(f, [10, 84]) + assert res == -6 + self.check_loop_count(0) + # + res = self.meta_interp(f, [3, 19]) + assert res == -2 + self.check_loop_count(1) + def test_format(self): def f(n): return len("<%d>" % n) Modified: pypy/branch/cli-jit/pypy/jit/metainterp/test/test_warmstate.py ============================================================================== --- pypy/branch/cli-jit/pypy/jit/metainterp/test/test_warmstate.py (original) +++ pypy/branch/cli-jit/pypy/jit/metainterp/test/test_warmstate.py Tue Jan 19 14:11:59 2010 @@ -165,6 +165,7 @@ class FakeWarmRunnerDesc: can_inline_ptr = None get_printable_location_ptr = None + confirm_enter_jit_ptr = None green_args_spec = [lltype.Signed, lltype.Float] class FakeCell: dont_trace_here = False @@ -192,6 +193,7 @@ green_args_spec = [lltype.Signed, lltype.Float] can_inline_ptr = llhelper(CAN_INLINE, can_inline) get_printable_location_ptr = None + confirm_enter_jit_ptr = None state = WarmEnterState(FakeWarmRunnerDesc()) def jit_getter(*args): return FakeCell() @@ -212,7 +214,27 @@ green_args_spec = [lltype.Signed, lltype.Float] can_inline_ptr = None get_printable_location_ptr = llhelper(GET_LOCATION, get_location) + confirm_enter_jit_ptr = None state = WarmEnterState(FakeWarmRunnerDesc()) state.make_jitdriver_callbacks() res = state.get_location_str([BoxInt(5), BoxFloat(42.5)]) assert res == "hi there" + +def test_make_jitdriver_callbacks_4(): + def confirm_enter_jit(x, y, z): + assert x == 5 + assert y == 42.5 + assert z == 3 + return True + ENTER_JIT = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Float, + lltype.Signed], lltype.Bool)) + class FakeWarmRunnerDesc: + rtyper = None + green_args_spec = [lltype.Signed, lltype.Float] + can_inline_ptr = None + get_printable_location_ptr = None + confirm_enter_jit_ptr = llhelper(ENTER_JIT, confirm_enter_jit) + state = WarmEnterState(FakeWarmRunnerDesc()) + state.make_jitdriver_callbacks() + res = state.confirm_enter_jit(5, 42.5, 3) + assert res is True Modified: pypy/branch/cli-jit/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/cli-jit/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/cli-jit/pypy/jit/metainterp/warmspot.py Tue Jan 19 14:11:59 2010 @@ -397,9 +397,13 @@ annhelper, self.jitdriver.can_inline, annmodel.s_Bool) self.get_printable_location_ptr = self._make_hook_graph( annhelper, self.jitdriver.get_printable_location, s_Str) + self.confirm_enter_jit_ptr = self._make_hook_graph( + annhelper, self.jitdriver.confirm_enter_jit, annmodel.s_Bool, + onlygreens=False) annhelper.finish() - def _make_hook_graph(self, annhelper, func, s_result, s_first_arg=None): + def _make_hook_graph(self, annhelper, func, s_result, s_first_arg=None, + onlygreens=True): if func is None: return None # @@ -407,7 +411,9 @@ if s_first_arg is not None: extra_args_s.append(s_first_arg) # - args_s = self.portal_args_s[:len(self.green_args_spec)] + args_s = self.portal_args_s + if onlygreens: + args_s = args_s[:len(self.green_args_spec)] graph = annhelper.getgraph(func, extra_args_s + args_s, s_result) funcptr = annhelper.graph2delayed(graph) return funcptr Modified: pypy/branch/cli-jit/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/branch/cli-jit/pypy/jit/metainterp/warmstate.py (original) +++ pypy/branch/cli-jit/pypy/jit/metainterp/warmstate.py Tue Jan 19 14:11:59 2010 @@ -196,6 +196,7 @@ get_jitcell = self.make_jitcell_getter() set_future_values = self.make_set_future_values() self.make_jitdriver_callbacks() + confirm_enter_jit = self.confirm_enter_jit def maybe_compile_and_run(*args): """Entry point to the JIT. Called at the point with the @@ -225,6 +226,9 @@ cell.counter = n return # bound reached; start tracing + if not confirm_enter_jit(*args): + cell.counter = 0 + return from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) try: @@ -235,6 +239,8 @@ self.disable_noninlinable_function(metainterp) raise else: + if not confirm_enter_jit(*args): + return # machine code was already compiled for these greenargs # get the assembler and fill in the boxes set_future_values(*args[num_green_args:]) @@ -461,7 +467,6 @@ greenargs = unwrap_greenkey(greenkey) return can_inline(*greenargs) self.can_inline_callable = can_inline_greenkey - # get_location_ptr = self.warmrunnerdesc.get_printable_location_ptr if get_location_ptr is None: @@ -479,3 +484,16 @@ res = hlstr(res) return res self.get_location_str = get_location_str + # + confirm_enter_jit_ptr = self.warmrunnerdesc.confirm_enter_jit_ptr + if confirm_enter_jit_ptr is None: + def confirm_enter_jit(*args): + return True + else: + rtyper = self.warmrunnerdesc.rtyper + # + def confirm_enter_jit(*args): + fn = support.maybe_on_top_of_llinterp(rtyper, + confirm_enter_jit_ptr) + return fn(*args) + self.confirm_enter_jit = confirm_enter_jit Modified: pypy/branch/cli-jit/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/cli-jit/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/cli-jit/pypy/module/pypyjit/interp_jit.py Tue Jan 19 14:11:59 2010 @@ -47,6 +47,11 @@ def set_jitcell_at(newcell, next_instr, bytecode): bytecode.jit_cells[next_instr] = newcell +def confirm_enter_jit(next_instr, bytecode, frame, ec): + return (frame.w_f_trace is None and + ec.profilefunc is None and + ec.w_tracefunc is None) + class PyPyJitDriver(JitDriver): reds = ['frame', 'ec'] @@ -65,7 +70,8 @@ get_printable_location = get_printable_location, leave = leave, get_jitcell_at = get_jitcell_at, - set_jitcell_at = set_jitcell_at) + set_jitcell_at = set_jitcell_at, + confirm_enter_jit = confirm_enter_jit) class __extend__(PyFrame): Modified: pypy/branch/cli-jit/pypy/rlib/jit.py ============================================================================== --- pypy/branch/cli-jit/pypy/rlib/jit.py (original) +++ pypy/branch/cli-jit/pypy/rlib/jit.py Tue Jan 19 14:11:59 2010 @@ -97,6 +97,25 @@ hop.exception_cannot_occur() return hop.inputconst(lltype.Signed, _we_are_jitted) + +##def force_virtualizable(virtualizable): +## pass + +##class Entry(ExtRegistryEntry): +## _about_ = force_virtualizable + +## def compute_result_annotation(self): +## from pypy.annotation import model as annmodel +## return annmodel.s_None + +## def specialize_call(self, hop): +## [vinst] = hop.inputargs(hop.args_r[0]) +## cname = inputconst(lltype.Void, None) +## cflags = inputconst(lltype.Void, {}) +## hop.exception_cannot_occur() +## return hop.genop('jit_force_virtualizable', [vinst, cname, cflags], +## resulttype=lltype.Void) + # ____________________________________________________________ # User interface for the hotpath JIT policy @@ -134,7 +153,8 @@ def __init__(self, greens=None, reds=None, virtualizables=None, get_jitcell_at=None, set_jitcell_at=None, can_inline=None, get_printable_location=None, - leave=None): + confirm_enter_jit=None, + leave=None): # XXX 'leave' is deprecated if greens is not None: self.greens = greens if reds is not None: @@ -151,6 +171,7 @@ self.set_jitcell_at = set_jitcell_at self.get_printable_location = get_printable_location self.can_inline = can_inline + self.confirm_enter_jit = confirm_enter_jit self.leave = leave def _freeze_(self): From fijal at codespeak.net Tue Jan 19 14:40:44 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 19 Jan 2010 14:40:44 +0100 (CET) Subject: [pypy-svn] r70703 - in pypy/branch/direct-assembler-call/pypy/jit/metainterp: . test Message-ID: <20100119134044.605AE168020@codespeak.net> Author: fijal Date: Tue Jan 19 14:40:43 2010 New Revision: 70703 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/history.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/resoperation.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_ztranslation.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py Log: (pedronis, fijal) Pass the first test. Trace like a residual call to portal, but instead substitute residual call with a direct assembler call later on. Break translation of llgraph backend for now. Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/history.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/history.py Tue Jan 19 14:40:43 2010 @@ -810,6 +810,10 @@ op = ResOperation(opnum, argboxes, resbox, descr) self.operations.append(op) return op + def substitute_operation(self, position, opnum, argboxes, descr=None): + resbox = self.operations[position].result + op = ResOperation(opnum, argboxes, resbox, descr) + self.operations[position] = op # ____________________________________________________________ Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Tue Jan 19 14:40:43 2010 @@ -663,6 +663,7 @@ @arguments("descr", "varargs") def opimpl_recursive_call(self, calldescr, varargs): warmrunnerstate = self.metainterp.staticdata.state + token = None if warmrunnerstate.inlining: num_green_args = self.metainterp.staticdata.num_green_args portal_code = self.metainterp.staticdata.portal_code @@ -670,9 +671,12 @@ if warmrunnerstate.can_inline_callable(greenkey): return self.perform_call(portal_code, varargs[1:], greenkey) token = warmrunnerstate.get_assembler_token(greenkey) - if token is not None: - return self.metainterp.direct_assembler_call(varargs, token) - return self.do_residual_call(varargs, descr=calldescr, exc=True) + call_position = len(self.metainterp.history.operations) + res = self.do_residual_call(varargs, descr=calldescr, exc=True) + if token is not None: + # this will substitute the residual call with assembler call + self.metainterp.direct_assembler_call(varargs, token, call_position) + return res @arguments("descr", "varargs") def opimpl_residual_call_noexception(self, calldescr, varargs): @@ -1992,15 +1996,15 @@ max_key = key return max_key - def direct_assembler_call(self, varargs, token): + def direct_assembler_call(self, varargs, token, call_position): """ Generate a direct call to assembler for portal entry point. """ + assert not self.is_blackholing() # XXX num_green_args = self.staticdata.num_green_args assert self.staticdata.virtualizable_info is None # XXX args = varargs[num_green_args + 1:] - xxx - self.framestack[-1].execute_varargs(rop.CALL_ASSEMBLER, args, - descr=token, exc=False) + self.history.substitute_operation(call_position, rop.CALL_ASSEMBLER, + args, descr=token) class GenerateMergePoint(Exception): def __init__(self, args, target_loop_token): Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/resoperation.py Tue Jan 19 14:40:43 2010 @@ -225,6 +225,7 @@ '_CANRAISE_FIRST', # ----- start of can_raise operations ----- 'CALL', + 'CALL_ASSEMBLER', 'CALL_MAY_FORCE', 'CALL_LOOPINVARIANT', 'OOSEND', # ootype operation Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_ztranslation.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_ztranslation.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_ztranslation.py Tue Jan 19 14:40:43 2010 @@ -7,6 +7,8 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype +py.test.skip("Broken") + class TranslationTest: CPUClass = None Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py Tue Jan 19 14:40:43 2010 @@ -258,7 +258,7 @@ if vinfo is not None: vinfo.reset_vable_token(virtualizable) loop_token = fail_descr.handle_fail(metainterp_sd) - + maybe_compile_and_run._dont_inline_ = True self.maybe_compile_and_run = maybe_compile_and_run return maybe_compile_and_run From fijal at codespeak.net Tue Jan 19 15:23:03 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 19 Jan 2010 15:23:03 +0100 (CET) Subject: [pypy-svn] r70704 - pypy/branch/direct-assembler-call/pypy/jit/backend/x86 Message-ID: <20100119142303.90B2F168020@codespeak.net> Author: fijal Date: Tue Jan 19 15:23:03 2010 New Revision: 70704 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/runner.py Log: Reformatting Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/runner.py Tue Jan 19 15:23:03 2010 @@ -18,8 +18,8 @@ def __init__(self, rtyper, stats, opts=None, translate_support_code=False, gcdescr=None): - AbstractLLCPU.__init__(self, rtyper, stats, opts, translate_support_code, - gcdescr) + AbstractLLCPU.__init__(self, rtyper, stats, opts, + translate_support_code, gcdescr) def setup(self): if self.opts is not None: From fijal at codespeak.net Tue Jan 19 15:23:58 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 19 Jan 2010 15:23:58 +0100 (CET) Subject: [pypy-svn] r70705 - in pypy/branch/direct-assembler-call/pypy/jit: backend backend/llgraph metainterp metainterp/test Message-ID: <20100119142358.5B1BB168020@codespeak.net> Author: fijal Date: Tue Jan 19 15:23:57 2010 New Revision: 70705 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/runner.py pypy/branch/direct-assembler-call/pypy/jit/backend/model.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmstate.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Log: (pedronis, fijal) Pass the next. We grow helper in warmspot.py that is used in case direct assembler call fails. Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py Tue Jan 19 15:23:57 2010 @@ -125,6 +125,7 @@ 'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'), 'arraylen_gc' : (('ref',), 'int'), 'call' : (('ref', 'varargs'), 'intorptr'), + 'call_assembler' : (('ref', 'varargs'), 'intorptr'), 'call_pure' : (('ref', 'varargs'), 'intorptr'), 'cond_call_gc_wb' : (('int', 'int', 'ptr', 'varargs'), None), 'oosend' : (('varargs',), 'intorptr'), @@ -316,6 +317,11 @@ assert isinstance(type, str) and len(type) == 1 op.descr = Descr(ofs, type) +def compile_add_loop_token(loop, descr): + loop = _from_opaque(loop) + op = loop.operations[-1] + op.descr = descr + def compile_add_var(loop, intvar): loop = _from_opaque(loop) op = loop.operations[-1] @@ -391,8 +397,9 @@ class Frame(object): OPHANDLERS = [None] * (rop._LAST+1) - def __init__(self, memocast): + def __init__(self, memocast, cpu): self.verbose = False + self.cpu = cpu self.memocast = memocast self.opindex = 1 self._forced = False @@ -809,6 +816,24 @@ finally: self._may_force = -1 + def op_call_assembler(self, loop_token, *args): + assert not self._forced + self._may_force = self.opindex + inpargs = _from_opaque(loop_token._llgraph_compiled_version).inputargs + for i, inparg in enumerate(inpargs): + TYPE = inparg.concretetype + if TYPE is lltype.Signed: + set_future_value_int(i, args[i]) + elif isinstance(TYPE, lltype.Ptr): + set_future_value_ref(i, args[i]) + elif TYPE is lltype.Float: + set_future_value_float(i, args[i]) + else: + raise Exception("Nonsense type %s" % TYPE) + + failindex = self.cpu._execute_token(loop_token) + return self.cpu.assembler_helper_ptr(failindex) + def op_guard_not_forced(self, descr): forced = self._forced self._forced = False @@ -969,11 +994,11 @@ return x -def new_frame(memocast, is_oo): +def new_frame(memocast, is_oo, cpu): if is_oo: - frame = OOFrame(memocast) + frame = OOFrame(memocast, cpu) else: - frame = Frame(memocast) + frame = Frame(memocast, cpu) return _to_opaque(frame) _future_values = [] Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/runner.py Tue Jan 19 15:23:57 2010 @@ -74,7 +74,8 @@ class BaseCPU(model.AbstractCPU): supports_floats = True - def __init__(self, rtyper, stats=None, opts=None, translate_support_code=False, + def __init__(self, rtyper, stats=None, opts=None, + translate_support_code=False, annmixlevel=None, gcdescr=None): assert type(opts) is not bool model.AbstractCPU.__init__(self) @@ -147,6 +148,8 @@ descr = op.descr if isinstance(descr, Descr): llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo) + if isinstance(descr, history.LoopToken): + llimpl.compile_add_loop_token(c, descr) if self.is_oo and isinstance(descr, (OODescr, MethDescr)): # hack hack, not rpython c._obj.externalobj.operations[-1].descr = descr @@ -207,18 +210,22 @@ else: assert False, "unknown operation" - def execute_token(self, loop_token): - """Calls the assembler generated for the given loop. - Returns the ResOperation that failed, of type rop.FAIL. - """ + def _execute_token(self, loop_token): compiled_version = loop_token._llgraph_compiled_version - frame = llimpl.new_frame(self.memo_cast, self.is_oo) + frame = llimpl.new_frame(self.memo_cast, self.is_oo, self) # setup the frame llimpl.frame_clear(frame, compiled_version) # run the loop fail_index = llimpl.frame_execute(frame) # we hit a FAIL operation. self.latest_frame = frame + return fail_index + + def execute_token(self, loop_token): + """Calls the assembler generated for the given loop. + Returns the ResOperation that failed, of type rop.FAIL. + """ + fail_index = self._execute_token(loop_token) return self.get_fail_descr_from_number(fail_index) def set_future_value_int(self, index, intvalue): Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/model.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/model.py Tue Jan 19 15:23:57 2010 @@ -3,6 +3,8 @@ class AbstractCPU(object): supports_floats = False + # assembler_helper_ptr - a pointer to helper to call after a direct + # assembler call def __init__(self): self.fail_descr_list = [] @@ -209,6 +211,9 @@ def do_call(self, args, calldescr): raise NotImplementedError + def do_call_assembler(self, args, token): + raise NotImplementedError + def do_call_loopinvariant(self, args, calldescr): return self.do_call(args, calldescr) Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Tue Jan 19 15:23:57 2010 @@ -671,7 +671,9 @@ if warmrunnerstate.can_inline_callable(greenkey): return self.perform_call(portal_code, varargs[1:], greenkey) token = warmrunnerstate.get_assembler_token(greenkey) - call_position = len(self.metainterp.history.operations) + call_position = 0 + if token is not None: + call_position = len(self.metainterp.history.operations) res = self.do_residual_call(varargs, descr=calldescr, exc=True) if token is not None: # this will substitute the residual call with assembler call Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Tue Jan 19 15:23:57 2010 @@ -646,7 +646,7 @@ result += f('-c-----------l-', i+100) self.meta_interp(g, [10], backendopt=True) self.check_aborted_count(1) - self.check_history(call_may_force=1, call=0) + self.check_history(call_assembler=1, call=0) self.check_tree_loop_count(3) def test_directly_call_assembler(self): @@ -664,6 +664,32 @@ i += 1 self.meta_interp(portal, [2], inline=True) + self.check_history(call_assembler=1) + + def test_directly_call_assembler_return(self): + driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno): + i = 0 + k = codeno + while i < 10: + driver.can_enter_jit(codeno = codeno, i = i, k = k) + driver.jit_merge_point(codeno = codeno, i = i, k = k) + if codeno == 2: + k = portal(1) + i += 1 + return k + + self.meta_interp(portal, [2], inline=True) + self.check_history(call_assembler=1) + + def test_directly_call_assembler_raise(self): + pass + + def test_directly_call_assembler_fail_guard(self): + pass class TestLLtype(RecursiveTests, LLJitMixin): pass Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmstate.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmstate.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmstate.py Tue Jan 19 15:23:57 2010 @@ -215,6 +215,7 @@ can_inline_ptr = None get_printable_location_ptr = llhelper(GET_LOCATION, get_location) confirm_enter_jit_ptr = None + get_jitcell_at_ptr = None state = WarmEnterState(FakeWarmRunnerDesc()) state.make_jitdriver_callbacks() res = state.get_location_str([BoxInt(5), BoxFloat(42.5)]) @@ -234,6 +235,8 @@ can_inline_ptr = None get_printable_location_ptr = None confirm_enter_jit_ptr = llhelper(ENTER_JIT, confirm_enter_jit) + get_jitcell_at_ptr = None + state = WarmEnterState(FakeWarmRunnerDesc()) state.make_jitdriver_callbacks() res = state.confirm_enter_jit(5, 42.5, 3) Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Tue Jan 19 15:23:57 2010 @@ -443,7 +443,8 @@ self.PTR_JIT_ENTER_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, lltype.Void) (self.PORTAL_FUNCTYPE, self.PTR_PORTAL_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, RESTYPE) - + (_, self.PTR_ASSEMBLER_HELPER_FUNCTYPE) = self.cpu.ts.get_FuncType( + [lltype.Signed], RESTYPE) def rewrite_can_enter_jit(self): FUNC = self.JIT_ENTER_FUNCTYPE @@ -560,6 +561,37 @@ self.portal_runner_ptr = self.helper_func(self.PTR_PORTAL_FUNCTYPE, ll_portal_runner) + def assembler_call_helper(failindex): + fail_descr = self.cpu.get_fail_descr_from_number(failindex) + try: + while True: + loop_token = fail_descr.handle_fail(self.metainterp_sd) + xxx + except self.DoneWithThisFrameVoid: + assert result_kind == 'void' + return + except self.DoneWithThisFrameInt, e: + assert result_kind == 'int' + return lltype.cast_primitive(RESULT, e.result) + except self.DoneWithThisFrameRef, e: + assert result_kind == 'ref' + return ts.cast_from_ref(RESULT, e.result) + except self.DoneWithThisFrameFloat, e: + assert result_kind == 'float' + return e.result + except self.ExitFrameWithExceptionRef, e: + xxx + value = ts.cast_to_baseclass(e.value) + if not we_are_translated(): + raise LLException(ts.get_typeptr(value), value) + else: + value = cast_base_ptr_to_instance(Exception, value) + raise Exception, value + + self.cpu.assembler_helper_ptr = self.helper_func( + self.PTR_ASSEMBLER_HELPER_FUNCTYPE, + assembler_call_helper) + # ____________________________________________________________ # Now mutate origportalgraph to end with a call to portal_runner_ptr # From fijal at codespeak.net Tue Jan 19 15:34:43 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 19 Jan 2010 15:34:43 +0100 (CET) Subject: [pypy-svn] r70706 - in pypy/branch/direct-assembler-call/pypy/jit: backend/llgraph metainterp metainterp/test Message-ID: <20100119143443.2E501168020@codespeak.net> Author: fijal Date: Tue Jan 19 15:34:42 2010 New Revision: 70706 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Log: (pedronis, fijal) Do the correct thing about raising an exception from a direct assembler call Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py Tue Jan 19 15:34:42 2010 @@ -817,8 +817,9 @@ self._may_force = -1 def op_call_assembler(self, loop_token, *args): - assert not self._forced - self._may_force = self.opindex + global _last_exception + #assert not self._forced + #self._may_force = self.opindex inpargs = _from_opaque(loop_token._llgraph_compiled_version).inputargs for i, inparg in enumerate(inpargs): TYPE = inparg.concretetype @@ -832,7 +833,11 @@ raise Exception("Nonsense type %s" % TYPE) failindex = self.cpu._execute_token(loop_token) - return self.cpu.assembler_helper_ptr(failindex) + try: + return self.cpu.assembler_helper_ptr(failindex) + except LLException, lle: + assert _last_exception is None, "exception left behind" + _last_exception = lle def op_guard_not_forced(self, descr): forced = self._forced Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Tue Jan 19 15:34:42 2010 @@ -686,7 +686,31 @@ self.check_history(call_assembler=1) def test_directly_call_assembler_raise(self): - pass + + class MyException(Exception): + def __init__(self, x): + self.x = x + + driver = JitDriver(greens = ['codeno'], reds = ['i'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno): + i = 0 + while i < 10: + driver.can_enter_jit(codeno = codeno, i = i) + driver.jit_merge_point(codeno = codeno, i = i) + if codeno == 2: + try: + portal(1) + except MyException, me: + i += me.x + i += 1 + if codeno == 1: + raise MyException(1) + + self.meta_interp(portal, [2], inline=True) + self.check_history(call_assembler=1) def test_directly_call_assembler_fail_guard(self): pass Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Tue Jan 19 15:34:42 2010 @@ -567,6 +567,8 @@ while True: loop_token = fail_descr.handle_fail(self.metainterp_sd) xxx + except self.ContinueRunningNormally, e: + xxx except self.DoneWithThisFrameVoid: assert result_kind == 'void' return @@ -580,7 +582,6 @@ assert result_kind == 'float' return e.result except self.ExitFrameWithExceptionRef, e: - xxx value = ts.cast_to_baseclass(e.value) if not we_are_translated(): raise LLException(ts.get_typeptr(value), value) From cfbolz at codespeak.net Tue Jan 19 16:26:57 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 19 Jan 2010 16:26:57 +0100 (CET) Subject: [pypy-svn] r70708 - pypy/trunk/pypy/jit/metainterp Message-ID: <20100119152657.B63DB168020@codespeak.net> Author: cfbolz Date: Tue Jan 19 16:26:57 2010 New Revision: 70708 Modified: pypy/trunk/pypy/jit/metainterp/compile.py pypy/trunk/pypy/jit/metainterp/resume.py Log: Add an assert to resume.py that checks that resume data did not get added to this fail descr before. I'm trying to write a test that makes this assert fail. Modified: pypy/trunk/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/compile.py (original) +++ pypy/trunk/pypy/jit/metainterp/compile.py Tue Jan 19 16:26:57 2010 @@ -207,6 +207,7 @@ class ResumeGuardDescr(ResumeDescr): counter = 0 # this class also gets attributes stored by resume.py code + rd_numb = None def __init__(self, metainterp_sd, original_greenkey): ResumeDescr.__init__(self, original_greenkey) Modified: pypy/trunk/pypy/jit/metainterp/resume.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/resume.py (original) +++ pypy/trunk/pypy/jit/metainterp/resume.py Tue Jan 19 16:26:57 2010 @@ -271,6 +271,8 @@ def finish(self, values, pending_setfields=[]): # compute the numbering storage = self.storage + # make sure that nobody attached resume data to this guard yet + assert storage.rd_numb is None numb, liveboxes_from_env, v = self.memo.number(values, storage.rd_snapshot) self.liveboxes_from_env = liveboxes_from_env From cfbolz at codespeak.net Tue Jan 19 16:29:27 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 19 Jan 2010 16:29:27 +0100 (CET) Subject: [pypy-svn] r70709 - pypy/trunk/pypy/jit/metainterp/test Message-ID: <20100119152927.06DE6168020@codespeak.net> Author: cfbolz Date: Tue Jan 19 16:29:27 2010 New Revision: 70709 Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py Log: Rather intransparent failing test. Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_basic.py Tue Jan 19 16:29:27 2010 @@ -1249,6 +1249,42 @@ assert res == 3 * 21 self.check_loops(call=1) + @py.test.mark.xfail + def test_bug_optimizeopt_mutates_ops(self): + myjitdriver = JitDriver(greens = [], reds = ['x', 'res', 'a', 'const']) + class A(object): + pass + class B(A): + pass + + glob = A() + glob.a = None + def f(x): + res = 0 + a = A() + a.x = 0 + glob.a = A() + const = 2 + while x > 0: + myjitdriver.can_enter_jit(x=x, res=res, a=a, const=const) + myjitdriver.jit_merge_point(x=x, res=res, a=a, const=const) + if glob.a is not None and type(glob.a) is B: + res += 1 + if a is None: + a = A() + a.x = x + glob.a = B() + const = 2 + else: + const = hint(const, promote=True) + x -= const + res += a.x + a = None + glob.a = A() + const = 1 + return res + res = self.meta_interp(f, [21]) + assert res == 120 class TestOOtype(BasicTests, OOJitMixin): From cfbolz at codespeak.net Tue Jan 19 16:30:14 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 19 Jan 2010 16:30:14 +0100 (CET) Subject: [pypy-svn] r70710 - pypy/trunk/pypy/jit/metainterp/test Message-ID: <20100119153014.D51A8168020@codespeak.net> Author: cfbolz Date: Tue Jan 19 16:30:14 2010 New Revision: 70710 Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py Log: simplify it a tiny bit Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_basic.py Tue Jan 19 16:30:14 2010 @@ -1268,7 +1268,7 @@ while x > 0: myjitdriver.can_enter_jit(x=x, res=res, a=a, const=const) myjitdriver.jit_merge_point(x=x, res=res, a=a, const=const) - if glob.a is not None and type(glob.a) is B: + if type(glob.a) is B: res += 1 if a is None: a = A() From fijal at codespeak.net Tue Jan 19 16:32:22 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 19 Jan 2010 16:32:22 +0100 (CET) Subject: [pypy-svn] r70711 - in pypy/branch/direct-assembler-call/pypy/jit/metainterp: . test Message-ID: <20100119153222.E904B168020@codespeak.net> Author: fijal Date: Tue Jan 19 16:32:22 2010 New Revision: 70711 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py Log: Surprisingly, this seems to be enough to cover all cases for direct assembler call helper. Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Tue Jan 19 16:32:22 2010 @@ -713,7 +713,27 @@ self.check_history(call_assembler=1) def test_directly_call_assembler_fail_guard(self): - pass + driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno, k): + i = 0 + while i < 10: + driver.can_enter_jit(codeno=codeno, i=i, k=k) + driver.jit_merge_point(codeno=codeno, i=i, k=k) + if codeno == 2: + k += portal(1, k) + elif k > 40: + if i % 2: + k += 1 + else: + k += 2 + k += 1 + i += 1 + return k + + self.meta_interp(portal, [2, 0], inline=True) class TestLLtype(RecursiveTests, LLJitMixin): pass Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Tue Jan 19 16:32:22 2010 @@ -563,31 +563,35 @@ def assembler_call_helper(failindex): fail_descr = self.cpu.get_fail_descr_from_number(failindex) - try: - while True: + while True: + try: loop_token = fail_descr.handle_fail(self.metainterp_sd) - xxx - except self.ContinueRunningNormally, e: - xxx - except self.DoneWithThisFrameVoid: - assert result_kind == 'void' - return - except self.DoneWithThisFrameInt, e: - assert result_kind == 'int' - return lltype.cast_primitive(RESULT, e.result) - except self.DoneWithThisFrameRef, e: - assert result_kind == 'ref' - return ts.cast_from_ref(RESULT, e.result) - except self.DoneWithThisFrameFloat, e: - assert result_kind == 'float' - return e.result - except self.ExitFrameWithExceptionRef, e: - value = ts.cast_to_baseclass(e.value) - if not we_are_translated(): - raise LLException(ts.get_typeptr(value), value) - else: - value = cast_base_ptr_to_instance(Exception, value) - raise Exception, value + fail_descr = self.cpu.execute_token(loop_token) + except self.ContinueRunningNormally, e: + args = () + for _, name, _ in portalfunc_ARGS: + v = getattr(e, name) + args = args + (v,) + self.state.set_future_values(*args) + except self.DoneWithThisFrameVoid: + assert result_kind == 'void' + return + except self.DoneWithThisFrameInt, e: + assert result_kind == 'int' + return lltype.cast_primitive(RESULT, e.result) + except self.DoneWithThisFrameRef, e: + assert result_kind == 'ref' + return ts.cast_from_ref(RESULT, e.result) + except self.DoneWithThisFrameFloat, e: + assert result_kind == 'float' + return e.result + except self.ExitFrameWithExceptionRef, e: + value = ts.cast_to_baseclass(e.value) + if not we_are_translated(): + raise LLException(ts.get_typeptr(value), value) + else: + value = cast_base_ptr_to_instance(Exception, value) + raise Exception, value self.cpu.assembler_helper_ptr = self.helper_func( self.PTR_ASSEMBLER_HELPER_FUNCTYPE, Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py Tue Jan 19 16:32:22 2010 @@ -194,7 +194,7 @@ ContinueRunningNormally = self.warmrunnerdesc.ContinueRunningNormally num_green_args = self.warmrunnerdesc.num_green_args get_jitcell = self.make_jitcell_getter() - set_future_values = self.make_set_future_values() + self.set_future_values = self.make_set_future_values() self.make_jitdriver_callbacks() confirm_enter_jit = self.confirm_enter_jit @@ -245,7 +245,7 @@ return # machine code was already compiled for these greenargs # get the assembler and fill in the boxes - set_future_values(*args[num_green_args:]) + self.set_future_values(*args[num_green_args:]) loop_token = cell.entry_loop_token # ---------- execute assembler ---------- From pedronis at codespeak.net Tue Jan 19 17:16:38 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 19 Jan 2010 17:16:38 +0100 (CET) Subject: [pypy-svn] r70713 - pypy/branch/direct-assembler-call/pypy/jit/metainterp Message-ID: <20100119161638.76006168020@codespeak.net> Author: pedronis Date: Tue Jan 19 17:16:38 2010 New Revision: 70713 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Log: XXX remarking a confusion point Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Tue Jan 19 17:16:38 2010 @@ -572,6 +572,7 @@ for _, name, _ in portalfunc_ARGS: v = getattr(e, name) args = args + (v,) + # XXX we need to get back to the general portal no? we got new green args as well self.state.set_future_values(*args) except self.DoneWithThisFrameVoid: assert result_kind == 'void' From cfbolz at codespeak.net Tue Jan 19 18:01:17 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 19 Jan 2010 18:01:17 +0100 (CET) Subject: [pypy-svn] r70714 - in pypy/trunk/pypy/jit/metainterp: . test Message-ID: <20100119170117.7E76F16801D@codespeak.net> Author: cfbolz Date: Tue Jan 19 18:01:16 2010 New Revision: 70714 Modified: pypy/trunk/pypy/jit/metainterp/compile.py pypy/trunk/pypy/jit/metainterp/history.py pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/pyjitpl.py pypy/trunk/pypy/jit/metainterp/resoperation.py pypy/trunk/pypy/jit/metainterp/test/test_basic.py pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py pypy/trunk/pypy/jit/metainterp/test/test_virtualref.py Log: Fix the bug that the previous test showed: optimizeopt can mutate operations in ways that become a problem when the loop later proves to be invalid. This fix is conservative in the sense that it always makes a copy of all operations, instead of trying to make optimizeopt more careful. I wasn't sure enough that I would catch all cases I I had tried that. Modified: pypy/trunk/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/compile.py (original) +++ pypy/trunk/pypy/jit/metainterp/compile.py Tue Jan 19 18:01:16 2010 @@ -54,9 +54,11 @@ for box in loop.inputargs: assert isinstance(box, Box) if start > 0: - loop.operations = history.operations[start:] + ops = history.operations[start:] else: - loop.operations = history.operations + ops = history.operations + # make a copy, because optimize_loop can mutate the ops and descrs + loop.operations = [op.clone() for op in ops] metainterp_sd = metainterp.staticdata loop_token = make_loop_token(len(loop.inputargs)) loop.token = loop_token @@ -203,11 +205,18 @@ class ResumeDescr(AbstractFailDescr): def __init__(self, original_greenkey): self.original_greenkey = original_greenkey + def _clone_if_mutable(self): + raise NotImplementedError class ResumeGuardDescr(ResumeDescr): counter = 0 - # this class also gets attributes stored by resume.py code + # this class also gets the following attributes stored by resume.py code + rd_snapshot = None + rd_frame_info_list = None rd_numb = None + rd_consts = None + rd_virtuals = None + rd_pendingfields = None def __init__(self, metainterp_sd, original_greenkey): ResumeDescr.__init__(self, original_greenkey) @@ -232,6 +241,17 @@ new_loop.operations) + def _clone_if_mutable(self): + res = self.__class__(self.metainterp_sd, self.original_greenkey) + # XXX a bit ugly to have to list them all here + res.rd_snapshot = self.rd_snapshot + res.rd_frame_info_list = self.rd_frame_info_list + res.rd_numb = self.rd_numb + res.rd_consts = self.rd_consts + res.rd_virtuals = self.rd_virtuals + res.rd_pendingfields = self.rd_pendingfields + return res + class ResumeGuardForcedDescr(ResumeGuardDescr): def handle_fail(self, metainterp_sd): @@ -337,13 +357,15 @@ # it does not work -- i.e. none of the existing old_loop_tokens match. new_loop = create_empty_loop(metainterp) new_loop.inputargs = metainterp.history.inputargs - new_loop.operations = metainterp.history.operations + # clone ops, as optimize_bridge can mutate the ops + new_loop.operations = [op.clone() for op in metainterp.history.operations] metainterp_sd = metainterp.staticdata try: target_loop_token = metainterp_sd.state.optimize_bridge(metainterp_sd, old_loop_tokens, new_loop) except InvalidLoop: + assert 0 return None # Did it work? if target_loop_token is not None: Modified: pypy/trunk/pypy/jit/metainterp/history.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/history.py (original) +++ pypy/trunk/pypy/jit/metainterp/history.py Tue Jan 19 18:01:16 2010 @@ -122,6 +122,9 @@ def repr_of_descr(self): return '%r' % (self,) + def _clone_if_mutable(self): + return self + class AbstractFailDescr(AbstractDescr): index = -1 Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Tue Jan 19 18:01:16 2010 @@ -515,20 +515,16 @@ # accumulate counters self.resumedata_memo.update_counters(self.metainterp_sd.profiler) - def emit_operation(self, op, must_clone=True): + def emit_operation(self, op): self.heap_op_optimizer.emitting_operation(op) - self._emit_operation(op, must_clone) + self._emit_operation(op) - def _emit_operation(self, op, must_clone=True): + def _emit_operation(self, op): for i in range(len(op.args)): arg = op.args[i] if arg in self.values: box = self.values[arg].force_box() - if box is not arg: - if must_clone: - op = op.clone() - must_clone = False - op.args[i] = box + op.args[i] = box self.metainterp_sd.profiler.count(jitprof.OPT_OPS) if op.is_guard(): self.metainterp_sd.profiler.count(jitprof.OPT_GUARDS) @@ -588,9 +584,8 @@ for i in range(len(specnodes)): value = self.getvalue(op.args[i]) specnodes[i].teardown_virtual_node(self, value, exitargs) - op2 = op.clone() - op2.args = exitargs[:] - self.emit_operation(op2, must_clone=False) + op.args = exitargs[:] + self.emit_operation(op) def optimize_guard(self, op, constbox, emit_operation=True): value = self.getvalue(op.args[0]) Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Tue Jan 19 18:01:16 2010 @@ -1613,17 +1613,9 @@ # we cannot reconstruct the beginning of the proper loop raise GiveUp - oldops = self.history.operations[:] # raises in case it works -- which is the common case self.compile(original_boxes, live_arg_boxes, start) - # creation of the loop was cancelled! Patch - # history.operations so that it contains again - # exactly its old list of operations... - # xxx maybe we could patch history.operations with - # Nones after calling self.compile() instead of - # before... xxx maybe we should just raise GiveUp - del self.history.operations[:] - self.history.operations.extend(oldops) + # creation of the loop was cancelled! # Otherwise, no loop found so far, so continue tracing. start = len(self.history.operations) @@ -1661,6 +1653,7 @@ greenkey, start) if loop_token is not None: # raise if it *worked* correctly raise GenerateMergePoint(live_arg_boxes, loop_token) + self.history.operations.pop() # remove the JUMP def compile_bridge(self, live_arg_boxes): num_green_args = self.staticdata.num_green_args Modified: pypy/trunk/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/resoperation.py (original) +++ pypy/trunk/pypy/jit/metainterp/resoperation.py Tue Jan 19 18:01:16 2010 @@ -31,7 +31,11 @@ self.descr = descr def clone(self): - op = ResOperation(self.opnum, self.args, self.result, self.descr) + descr = self.descr + if descr is not None: + descr = descr._clone_if_mutable() + op = ResOperation(self.opnum, self.args, self.result, descr) + op.fail_args = self.fail_args if not we_are_translated(): op.name = self.name op.pc = self.pc Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_basic.py Tue Jan 19 18:01:16 2010 @@ -1249,7 +1249,6 @@ assert res == 3 * 21 self.check_loops(call=1) - @py.test.mark.xfail def test_bug_optimizeopt_mutates_ops(self): myjitdriver = JitDriver(greens = [], reds = ['x', 'res', 'a', 'const']) class A(object): @@ -1284,7 +1283,7 @@ const = 1 return res res = self.meta_interp(f, [21]) - assert res == 120 + assert res == f(21) class TestOOtype(BasicTests, OOJitMixin): Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Tue Jan 19 18:01:16 2010 @@ -207,8 +207,9 @@ class Storage(compile.ResumeGuardDescr): "for tests." - def __init__(self): - pass + def __init__(self, metainterp_sd=None, original_greenkey=None): + self.metainterp_sd = metainterp_sd + self.original_greenkey = original_greenkey def store_final_boxes(self, op, boxes): op.fail_args = boxes def __eq__(self, other): Modified: pypy/trunk/pypy/jit/metainterp/test/test_virtualref.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_virtualref.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_virtualref.py Tue Jan 19 18:01:16 2010 @@ -69,7 +69,8 @@ assert res == 5 self.check_operations_history(virtual_ref=1, guard_not_forced=1) # - [guard_op] = [op for op in self.metainterp.history.operations + ops = self.metainterp.staticdata.stats.loops[0].operations + [guard_op] = [op for op in ops if op.opnum == rop.GUARD_NOT_FORCED] bxs1 = [box for box in guard_op.fail_args if str(box._getrepr_()).endswith('.X')] From afa at codespeak.net Tue Jan 19 19:49:10 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 19 Jan 2010 19:49:10 +0100 (CET) Subject: [pypy-svn] r70716 - in pypy/branch/separate-compilation/pypy/translator/c: . test Message-ID: <20100119184910.9A61216800D@codespeak.net> Author: afa Date: Tue Jan 19 19:49:10 2010 New Revision: 70716 Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Start using a Controller to wrap the low-level pointer exported by the dll. Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Tue Jan 19 19:49:10 2010 @@ -6,6 +6,8 @@ from pypy.rpython.typesystem import getfunctionptr from pypy.rpython.lltypesystem import lltype, rffi from pypy.rpython.extregistry import ExtRegistryEntry +from pypy.rpython.controllerentry import Controller, ControllerEntry +from pypy.annotation.bookkeeper import getbookkeeper import py class ExportTable(object): @@ -15,24 +17,7 @@ def __init__(self): self.exported_function = {} self.exported_class = {} - - def make_wrapper_for_constructor(self, cls, name): - nbargs = len(cls.__init__.argtypes) - args = ', '.join(['arg%d' % d for d in range(nbargs)]) - - source = py.code.Source(r""" - def wrapper(%s): - obj = instantiate(cls) - obj.__init__(%s) - return obj - """ % (args, args)) - miniglobals = {'cls': cls, 'instantiate': instantiate} - exec source.compile() in miniglobals - wrapper = miniglobals['wrapper'] - wrapper._annspecialcase_ = 'specialize:ll' - wrapper._always_inline_ = True - wrapper._about = cls - return func_with_new_name(wrapper, name) + self.class_repr = {} def annotate_exported_functions(self, annotator): bk = annotator.bookkeeper @@ -45,18 +30,21 @@ if isinstance(s_init, model.SomeImpossibleValue): continue - # Replace class with its constructor - wrapper = self.make_wrapper_for_constructor(cls, clsname) - self.exported_function[clsname] = wrapper - - annotator.build_types(wrapper, cls.__init__.argtypes, - complete_now=False) - - # annotate functions with signatures - for funcname, func in self.exported_function.items(): - if hasattr(func, 'argtypes'): - annotator.build_types(func, func.argtypes, - complete_now=False) + # Annotate constructor + constructor_name = "%s__init__" % (clsname,) + wrapper = func_with_new_name(cls.__init__, constructor_name) + wrapper.argtypes = (cls,) + cls.__init__.argtypes + self.exported_function[constructor_name] = wrapper + + bk.enter(None) + try: + # annotate functions with signatures + for funcname, func in self.exported_function.items(): + if hasattr(func, 'argtypes'): + annotator.build_types(func, func.argtypes, + complete_now=False) + finally: + bk.leave() annotator.complete() # ensure that functions without signature are not constant-folded @@ -73,6 +61,13 @@ # and reflow annotator.build_types(func, newargs) + def compute_exported_repr(self, rtyper): + bookkeeper = rtyper.annotator.bookkeeper + for clsname, cls in self.exported_class.items(): + classdef = bookkeeper.getuniqueclassdef(cls) + classrepr = rtyper.getrepr(model.SomeInstance(classdef)).lowleveltype + self.class_repr[clsname] = classrepr + def get_exported_functions(self, annotator): bk = annotator.bookkeeper @@ -88,14 +83,29 @@ exported_funcptr[itemname] = funcptr return exported_funcptr - def make_import_module(self, builder, node_names): - class Module(object): - _annotated = False + def make_wrapper_for_class(self, name, cls, init_func): + structptr = self.class_repr[name] + assert structptr is not object - _exported_classes = self.exported_class.values() - mod = Module() - mod.__file__ = builder.so_name + class C_Controller(Controller): + knowntype = structptr + def new(self_, *args): + obj = instantiate(cls) + init_func(obj, *args) + return obj + + class Entry(ControllerEntry): + _about_ = structptr + _controller_ = C_Controller + + bookkeeper = getbookkeeper() + classdef = bookkeeper.getuniqueclassdef(cls) + #bookkeeper.classdefs.append(classdef) + + return structptr + + def make_import_module(self, builder, node_names): forwards = [] for node in builder.db.globalcontainers(): if node.nodekind == 'func' and node.name in node_names.values(): @@ -106,6 +116,25 @@ post_include_bits = forwards ) + class Module(object): + _annotated = False + def _freeze_(self): + return True + + __exported_class = self.exported_class + + def __getattr__(self_, name): + if name in self_.__exported_class: + cls = self_.__exported_class[name] + constructor_name = "%s__init__" % (name,) + init_func = getattr(self_, constructor_name) + structptr = self.make_wrapper_for_class(name, cls, init_func) + return structptr + raise AttributeError(name) + + mod = Module() + mod.__file__ = builder.so_name + for funcname, import_name in node_names.items(): functype = lltype.typeOf(builder.entrypoint[funcname]) func = make_ll_import_function(import_name, functype, import_eci) Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Tue Jan 19 19:49:10 2010 @@ -51,6 +51,8 @@ t.buildrtyper().specialize() + table.compute_exported_repr(t.rtyper) + exported_funcptr = table.get_exported_functions(t.annotator) builder = CLibraryBuilder(t, exported_funcptr, config=t.config) From fijal at codespeak.net Tue Jan 19 21:32:29 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 19 Jan 2010 21:32:29 +0100 (CET) Subject: [pypy-svn] r70717 - in pypy/branch/direct-assembler-call/pypy/jit/metainterp: . test Message-ID: <20100119203229.BB28716801D@codespeak.net> Author: fijal Date: Tue Jan 19 21:32:27 2010 New Revision: 70717 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py Log: Call portal directly, instead of setting future values. Should sort-of-work, needs more tests Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Tue Jan 19 21:32:27 2010 @@ -733,7 +733,8 @@ i += 1 return k - self.meta_interp(portal, [2, 0], inline=True) + res = self.meta_interp(portal, [2, 0], inline=True) + assert res == portal(2, 0) class TestLLtype(RecursiveTests, LLJitMixin): pass Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Tue Jan 19 21:32:27 2010 @@ -572,8 +572,7 @@ for _, name, _ in portalfunc_ARGS: v = getattr(e, name) args = args + (v,) - # XXX we need to get back to the general portal no? we got new green args as well - self.state.set_future_values(*args) + return ll_portal_runner(*args) except self.DoneWithThisFrameVoid: assert result_kind == 'void' return Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py Tue Jan 19 21:32:27 2010 @@ -194,7 +194,7 @@ ContinueRunningNormally = self.warmrunnerdesc.ContinueRunningNormally num_green_args = self.warmrunnerdesc.num_green_args get_jitcell = self.make_jitcell_getter() - self.set_future_values = self.make_set_future_values() + set_future_values = self.make_set_future_values() self.make_jitdriver_callbacks() confirm_enter_jit = self.confirm_enter_jit @@ -245,7 +245,7 @@ return # machine code was already compiled for these greenargs # get the assembler and fill in the boxes - self.set_future_values(*args[num_green_args:]) + set_future_values(*args[num_green_args:]) loop_token = cell.entry_loop_token # ---------- execute assembler ---------- From afa at codespeak.net Wed Jan 20 01:11:11 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 20 Jan 2010 01:11:11 +0100 (CET) Subject: [pypy-svn] r70718 - in pypy/branch/separate-compilation/pypy/translator/c: . test Message-ID: <20100120001111.633EE16801D@codespeak.net> Author: afa Date: Wed Jan 20 01:11:09 2010 New Revision: 70718 Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Ensure that the Repr constructed by a class is the same as the one used by function arguments Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Wed Jan 20 01:11:09 2010 @@ -19,6 +19,25 @@ self.exported_class = {} self.class_repr = {} + def make_wrapper_for_constructor(self, cls, name): + nbargs = len(cls.__init__.argtypes) + args = ', '.join(['arg%d' % d for d in range(nbargs)]) + + source = py.code.Source(r""" + def wrapper(%s): + obj = instantiate(cls) + obj.__init__(%s) + return obj + """ % (args, args)) + miniglobals = {'cls': cls, 'instantiate': instantiate} + exec source.compile() in miniglobals + wrapper = miniglobals['wrapper'] + wrapper._annspecialcase_ = 'specialize:ll' + wrapper._always_inline_ = True + wrapper.argtypes = cls.__init__.argtypes + return func_with_new_name(wrapper, name) + + def annotate_exported_functions(self, annotator): bk = annotator.bookkeeper @@ -31,9 +50,8 @@ continue # Annotate constructor - constructor_name = "%s__init__" % (clsname,) - wrapper = func_with_new_name(cls.__init__, constructor_name) - wrapper.argtypes = (cls,) + cls.__init__.argtypes + constructor_name = "__new__%s" % (clsname,) + wrapper = self.make_wrapper_for_constructor(cls, constructor_name) self.exported_function[constructor_name] = wrapper bk.enter(None) @@ -61,13 +79,6 @@ # and reflow annotator.build_types(func, newargs) - def compute_exported_repr(self, rtyper): - bookkeeper = rtyper.annotator.bookkeeper - for clsname, cls in self.exported_class.items(): - classdef = bookkeeper.getuniqueclassdef(cls) - classrepr = rtyper.getrepr(model.SomeInstance(classdef)).lowleveltype - self.class_repr[clsname] = classrepr - def get_exported_functions(self, annotator): bk = annotator.bookkeeper @@ -83,29 +94,32 @@ exported_funcptr[itemname] = funcptr return exported_funcptr - def make_wrapper_for_class(self, name, cls, init_func): - structptr = self.class_repr[name] - assert structptr is not object + def make_wrapper_for_class(self, name, cls, new_func): + STRUCTPTR = self.class_repr[name] class C_Controller(Controller): - knowntype = structptr + knowntype = STRUCTPTR def new(self_, *args): - obj = instantiate(cls) - init_func(obj, *args) - return obj + return new_func(*args) class Entry(ControllerEntry): - _about_ = structptr + _about_ = STRUCTPTR _controller_ = C_Controller bookkeeper = getbookkeeper() classdef = bookkeeper.getuniqueclassdef(cls) - #bookkeeper.classdefs.append(classdef) - return structptr + return STRUCTPTR def make_import_module(self, builder, node_names): + rtyper = builder.db.translator.rtyper + bookkeeper = rtyper.annotator.bookkeeper + for clsname, cls in self.exported_class.items(): + classdef = bookkeeper.getuniqueclassdef(cls) + classrepr = rtyper.getrepr(model.SomeInstance(classdef)).lowleveltype + self.class_repr[clsname] = classrepr + forwards = [] for node in builder.db.globalcontainers(): if node.nodekind == 'func' and node.name in node_names.values(): @@ -126,9 +140,9 @@ def __getattr__(self_, name): if name in self_.__exported_class: cls = self_.__exported_class[name] - constructor_name = "%s__init__" % (name,) - init_func = getattr(self_, constructor_name) - structptr = self.make_wrapper_for_class(name, cls, init_func) + constructor_name = "__new__%s" % (clsname,) + new_func = getattr(self_, constructor_name) + structptr = self.make_wrapper_for_class(name, cls, new_func) return structptr raise AttributeError(name) Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Wed Jan 20 01:11:09 2010 @@ -51,8 +51,6 @@ t.buildrtyper().specialize() - table.compute_exported_repr(t.rtyper) - exported_funcptr = table.get_exported_functions(t.annotator) builder = CLibraryBuilder(t, exported_funcptr, config=t.config) From benjamin at codespeak.net Wed Jan 20 03:25:18 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 20 Jan 2010 03:25:18 +0100 (CET) Subject: [pypy-svn] r70719 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20100120022518.7B0D716801D@codespeak.net> Author: benjamin Date: Wed Jan 20 03:25:16 2010 New Revision: 70719 Modified: pypy/trunk/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/std/test/test_userobject.py Log: fix descriptor handling with getattributeshortcut enabled Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Wed Jan 20 03:25:16 2010 @@ -654,15 +654,15 @@ w_value = w_obj.getdictvalue_attr_is_in_class(self, name) if w_value is not None: return w_value - try: - return self.get(w_descr, w_obj) - except OperationError, e: - if not e.match(self, self.w_AttributeError): - raise - else: - w_value = w_obj.getdictvalue(self, name) - if w_value is not None: - return w_value + w_get = self.lookup(w_descr, "__get__") + if w_get is not None: + return self.get_and_call_function(w_get, w_descr, w_obj, w_type) + w_value = w_obj.getdictvalue(self, name) + if w_value is not None: + return w_value + # No value in __dict__. Fallback to the descriptor if we have it. + if w_descr is not None: + return w_descr w_descr = self.lookup(w_obj, '__getattr__') if w_descr is not None: Modified: pypy/trunk/pypy/objspace/std/test/test_userobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_userobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_userobject.py Wed Jan 20 03:25:16 2010 @@ -1,5 +1,6 @@ import py from pypy.interpreter import gateway +from pypy.objspace.test import test_descriptor class AppTestUserObject: @@ -294,6 +295,19 @@ multimethod.Installer = cls.prev_installer -class AppTestWithGetAttributeShortcut(AppTestUserObject): - OPTIONS = {"objspace.std.getattributeshortcut": True} +class GetAttributeShortcutTest: + def setup_class(cls): + from pypy import conftest + options = {"objspace.std.getattributeshortcut" : True} + cls.space = conftest.gettestobjspace(**options) + + +class AppTestWithGetAttributeShortcut(AppTestUserObject, + GetAttributeShortcutTest): + pass + + +class AppTestDescriptorWithGetAttributeShortcut( + test_descriptor.AppTest_Descriptor, GetAttributeShortcutTest): + pass From antocuni at codespeak.net Wed Jan 20 10:09:24 2010 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Wed, 20 Jan 2010 10:09:24 +0100 (CET) Subject: [pypy-svn] r70720 - in pypy/branch/cli-jit/pypy: config objspace/std Message-ID: <20100120090924.09D8416800B@codespeak.net> Author: antocuni Date: Wed Jan 20 10:09:23 2010 New Revision: 70720 Modified: pypy/branch/cli-jit/pypy/config/pypyoption.py pypy/branch/cli-jit/pypy/objspace/std/sharingdict.py Log: tentative checkin: implement WeakValueDictionary in rpython, without using the implementation in rlib.rweakref. This way it works also with ootype Modified: pypy/branch/cli-jit/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/cli-jit/pypy/config/pypyoption.py (original) +++ pypy/branch/cli-jit/pypy/config/pypyoption.py Wed Jan 20 10:09:23 2010 @@ -360,8 +360,7 @@ # extra optimizations with the JIT if level == 'jit': - if type_system != 'ootype': - config.objspace.std.suggest(withsharingdict=True) + config.objspace.std.suggest(withsharingdict=True) config.objspace.std.suggest(withcelldict=True) config.objspace.std.suggest(withinlineddict=True) Modified: pypy/branch/cli-jit/pypy/objspace/std/sharingdict.py ============================================================================== --- pypy/branch/cli-jit/pypy/objspace/std/sharingdict.py (original) +++ pypy/branch/cli-jit/pypy/objspace/std/sharingdict.py Wed Jan 20 10:09:23 2010 @@ -1,7 +1,26 @@ from pypy.objspace.std.dictmultiobject import IteratorImplementation from pypy.objspace.std.dictmultiobject import W_DictMultiObject, _is_sane_hash from pypy.rlib.jit import purefunction_promote, hint, we_are_jitted, unroll_safe -from pypy.rlib.rweakref import RWeakValueDictionary +#from pypy.rlib.rweakref import RWeakValueDictionary + +import weakref +class WeakValueDictionary: + def __init__(self): + self._dict = {} + + def get(self, key): + wref = self._dict.get(key, None) + if wref is None: + return None + return wref() + + def set(self, key, value): + if value is None: + self._dict.pop(key, None) + else: + #assert isinstance(value, self._valueclass) + self._dict[key] = weakref.ref(value) + NUM_DIGITS = 4 @@ -17,7 +36,8 @@ self.keys = keys self.length = length self.back_struct = back_struct - other_structs = RWeakValueDictionary(SharedStructure) + #other_structs = RWeakValueDictionary(SharedStructure) + other_structs = WeakValueDictionary() self.other_structs = other_structs self.last_key = last_key self._size_estimate = length << NUM_DIGITS From afa at codespeak.net Wed Jan 20 11:33:29 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 20 Jan 2010 11:33:29 +0100 (CET) Subject: [pypy-svn] r70721 - in pypy/branch/separate-compilation/pypy/translator/c: . test Message-ID: <20100120103329.B98DA16801D@codespeak.net> Author: afa Date: Wed Jan 20 11:33:28 2010 New Revision: 70721 Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Implement attribute access for external classes Next: implement method call Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Wed Jan 20 11:33:28 2010 @@ -18,6 +18,7 @@ self.exported_function = {} self.exported_class = {} self.class_repr = {} + self.classdef = {} def make_wrapper_for_constructor(self, cls, name): nbargs = len(cls.__init__.argtypes) @@ -95,6 +96,8 @@ return exported_funcptr def make_wrapper_for_class(self, name, cls, new_func): + classdef = self.classdef[name] + attributes = classdef.attrs STRUCTPTR = self.class_repr[name] class C_Controller(Controller): @@ -103,13 +106,21 @@ def new(self_, *args): return new_func(*args) + def __getattr__(self_, name): + if name.startswith('get_') and name[4:] in classdef.attrs: + def getter(obj): + return getattr(obj, 'inst_' + name[4:]) + return getter + if name.startswith('set_') and name[4:] in classdef.attrs: + def setter(obj, value): + setattr(obj, 'inst_' + name[4:], value) + return setter + raise AttributeError(name) + class Entry(ControllerEntry): _about_ = STRUCTPTR _controller_ = C_Controller - bookkeeper = getbookkeeper() - classdef = bookkeeper.getuniqueclassdef(cls) - return STRUCTPTR def make_import_module(self, builder, node_names): @@ -118,6 +129,7 @@ for clsname, cls in self.exported_class.items(): classdef = bookkeeper.getuniqueclassdef(cls) classrepr = rtyper.getrepr(model.SomeInstance(classdef)).lowleveltype + self.classdef[clsname] = classdef self.class_repr[clsname] = classrepr forwards = [] Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Wed Jan 20 11:33:28 2010 @@ -15,6 +15,10 @@ def __init__(self, x): self.x = x + @export + def invert(self): + self.x = 1 / self.x + # functions exported from the 'first' module @export(float) def newS(x): @@ -166,7 +170,6 @@ assert c_fn() == 73.5 def test_structure_attributes(self): - py.test.skip("WIP") firstmodule = self.compile_separated( "first", S=self.S) @@ -179,7 +182,25 @@ fn = self.call_exported(secondmodule.g) - assert fn() == 20.25 + assert fn() == 20.75 + c_fn = self.compile_function(fn, []) + assert c_fn() == 20.75 + + def test_method_call(self): + firstmodule = self.compile_separated( + "first", S=self.S) + + @export() + def g(): + s = firstmodule.S(8.0) + s.invert() + return s.x + + secondmodule = self.compile_separated("second", g=g) + + fn = self.call_exported(secondmodule.g) + + assert fn() == 0.125 c_fn = self.compile_function(fn, []) - assert c_fn() == 20.25 + assert c_fn() == 0.125 From pedronis at codespeak.net Wed Jan 20 12:17:28 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 20 Jan 2010 12:17:28 +0100 (CET) Subject: [pypy-svn] r70723 - in pypy/build/bot2: codespeak-html jsplot/css Message-ID: <20100120111728.773B116801D@codespeak.net> Author: pedronis Date: Wed Jan 20 12:17:27 2010 New Revision: 70723 Modified: pypy/build/bot2/codespeak-html/index.html pypy/build/bot2/jsplot/css/main.css Log: formatting Modified: pypy/build/bot2/codespeak-html/index.html ============================================================================== --- pypy/build/bot2/codespeak-html/index.html (original) +++ pypy/build/bot2/codespeak-html/index.html Wed Jan 20 12:17:27 2010 @@ -9,7 +9,7 @@

    Welcome to codespeak's PyPy Buildbot!

      -
    • the performance plots will give you an overview of performance for recent revisions.
    • +
    • the Performance Plots will give you an overview of performance for recent revisions.
    • the Summary Display <trunk> will give you a failure-oriented summary for recent revisions (<trunk> only).
    • Modified: pypy/build/bot2/jsplot/css/main.css ============================================================================== --- pypy/build/bot2/jsplot/css/main.css (original) +++ pypy/build/bot2/jsplot/css/main.css Wed Jan 20 12:17:27 2010 @@ -1,3 +1,6 @@ +body { + font-family: Verdana; +} .plot { width: 600px; From fijal at codespeak.net Wed Jan 20 12:42:32 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 20 Jan 2010 12:42:32 +0100 (CET) Subject: [pypy-svn] r70724 - in pypy/branch/direct-assembler-call/pypy/jit/metainterp: . test Message-ID: <20100120114232.E626B16801D@codespeak.net> Author: fijal Date: Wed Jan 20 12:42:32 2010 New Revision: 70724 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmspot.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Log: (pedronis, fijal) Directly test assembler_call_helper Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmspot.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmspot.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmspot.py Wed Jan 20 12:42:32 2010 @@ -4,6 +4,7 @@ from pypy.rlib.jit import JitDriver, OPTIMIZER_FULL, OPTIMIZER_SIMPLE from pypy.rlib.jit import unroll_safe from pypy.jit.backend.llgraph import runner +from pypy.jit.metainterp.history import BoxInt from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin @@ -283,3 +284,80 @@ class TestOOWarmspot(WarmspotTests, OOJitMixin): CPUClass = runner.OOtypeCPU type_system = 'ootype' + +class TestWarmspotDirect(object): + def setup_class(cls): + from pypy.jit.metainterp.typesystem import llhelper + from pypy.jit.metainterp.support import annotate + from pypy.jit.metainterp.warmspot import WarmRunnerDesc + from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE + from pypy.rpython.lltypesystem import lltype, llmemory + exc_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) + cls.exc_vtable = exc_vtable + + class FakeFailDescr(object): + def __init__(self, no): + self.no = no + + def handle_fail(self, metainterp_sd): + if self.no == 0: + raise metainterp_sd.warmrunnerdesc.DoneWithThisFrameInt(3) + if self.no == 1: + raise metainterp_sd.warmrunnerdesc.ContinueRunningNormally( + [BoxInt(0), BoxInt(1)]) + if self.no == 3: + exc = lltype.malloc(OBJECT) + exc.typeptr = exc_vtable + raise metainterp_sd.warmrunnerdesc.ExitFrameWithExceptionRef( + metainterp_sd.cpu, + lltype.cast_opaque_ptr(llmemory.GCREF, exc)) + return self.no + + class FakeCPU(object): + supports_floats = False + ts = llhelper + translate_support_code = False + + def __init__(self, *args, **kwds): + pass + + def nodescr(self, *args, **kwds): + pass + fielddescrof = nodescr + calldescrof = nodescr + sizeof = nodescr + + def get_fail_descr_from_number(self, no): + return FakeFailDescr(no) + + def execute_token(self, token): + assert token == 2 + return FakeFailDescr(1) + + driver = JitDriver(reds = ['red'], greens = ['green']) + + def f(green): + red = 0 + while red < 10: + driver.can_enter_jit(red=red, green=green) + driver.jit_merge_point(red=red, green=green) + red += 1 + return red + + rtyper = annotate(f, [0]) + translator = rtyper.annotator.translator + translator.config.translation.gc = 'hybrid' + cls.desc = WarmRunnerDesc(translator, CPUClass=FakeCPU) + + def test_call_helper(self): + from pypy.rpython.llinterp import LLException + + assert self.desc.assembler_call_helper(0) == 3 + assert self.desc.assembler_call_helper(1) == 10 + assert self.desc.assembler_call_helper(2) == 10 + try: + self.desc.assembler_call_helper(3) + except LLException, lle: + assert lle[0] == self.exc_vtable + else: + py.test.fail("DID NOT RAISE") Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Wed Jan 20 12:42:32 2010 @@ -140,7 +140,7 @@ # ____________________________________________________________ -class WarmRunnerDesc: +class WarmRunnerDesc(object): def __init__(self, translator, policy=None, backendopt=True, CPUClass=None, optimizer=None, **kwds): @@ -557,7 +557,8 @@ else: value = cast_base_ptr_to_instance(Exception, value) raise Exception, value - + + self.ll_portal_runner = ll_portal_runner # for debugging self.portal_runner_ptr = self.helper_func(self.PTR_PORTAL_FUNCTYPE, ll_portal_runner) @@ -593,6 +594,7 @@ value = cast_base_ptr_to_instance(Exception, value) raise Exception, value + self.assembler_call_helper = assembler_call_helper # for debugging self.cpu.assembler_helper_ptr = self.helper_func( self.PTR_ASSEMBLER_HELPER_FUNCTYPE, assembler_call_helper) From fijal at codespeak.net Wed Jan 20 14:30:27 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 20 Jan 2010 14:30:27 +0100 (CET) Subject: [pypy-svn] r70725 - in pypy/branch/direct-assembler-call/pypy/jit/metainterp: . test Message-ID: <20100120133027.0A97416801D@codespeak.net> Author: fijal Date: Wed Jan 20 14:30:26 2010 New Revision: 70725 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/optimizeopt.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_optimizeopt.py Log: (pedronis, fijal) Consider CALL_ASSEMBLER a call with effectinfo=None Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/optimizeopt.py Wed Jan 20 14:30:26 2010 @@ -996,8 +996,12 @@ opnum == rop.DEBUG_MERGE_POINT): return if (opnum == rop.CALL or - opnum == rop.CALL_MAY_FORCE): - effectinfo = op.descr.get_extra_info() + opnum == rop.CALL_MAY_FORCE or + opnum == rop.CALL_ASSEMBLER): + if opnum == rop.CALL_ASSEMBLER: + effectinfo = None + else: + effectinfo = op.descr.get_extra_info() if effectinfo is not None: # XXX we can get the wrong complexity here, if the lists # XXX stored on effectinfo are large Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_optimizefindnode.py Wed Jan 20 14:30:26 2010 @@ -114,6 +114,9 @@ mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([nextdescr], [], [], forces_virtual_or_virtualizable=True)) + class LoopToken(AbstractDescr): + pass + asmdescr = LoopToken() # it can be whatever, it's not a descr though from pypy.jit.metainterp.virtualref import VirtualRefInfo class FakeWarmRunnerDesc: Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_optimizeopt.py Wed Jan 20 14:30:26 2010 @@ -2420,6 +2420,16 @@ """ self.optimize_loop(ops, 'Not, Not, Not, Not', ops) + def test_call_assembler_invalidates_caches(self): + ops = ''' + [p1, i1] + setfield_gc(p1, i1, descr=valuedescr) + i3 = call_assembler(i1, descr=asmdescr) + setfield_gc(p1, i3, descr=valuedescr) + jump(p1, i3) + ''' + self.optimize_loop(ops, 'Not, Not', ops) + def test_vref_nonvirtual_nonescape(self): ops = """ [p1] From fijal at codespeak.net Wed Jan 20 14:30:54 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 20 Jan 2010 14:30:54 +0100 (CET) Subject: [pypy-svn] r70726 - in pypy/branch/direct-assembler-call/pypy/jit/metainterp: . test Message-ID: <20100120133054.16C6B16801D@codespeak.net> Author: fijal Date: Wed Jan 20 14:30:54 2010 New Revision: 70726 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/history.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_history.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Log: (pedronis, fijal) A bit of obscure interface, but pass the virtualizable test of direct assembler call. Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/history.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/history.py Wed Jan 20 14:30:54 2010 @@ -802,19 +802,30 @@ class History(object): - def __init__(self, cpu): - self.cpu = cpu + def __init__(self): self.inputargs = None self.operations = [] + def record(self, opnum, argboxes, resbox, descr=None): op = ResOperation(opnum, argboxes, resbox, descr) self.operations.append(op) return op + def substitute_operation(self, position, opnum, argboxes, descr=None): resbox = self.operations[position].result op = ResOperation(opnum, argboxes, resbox, descr) self.operations[position] = op + def slice_history_at(self, position): + """ a strange function that does this: + history : operation_at_position : rest + it'll kill operation_at_position, store everything before that + in history.operations and return rest + """ + rest = self.operations[position + 1:] + del self.operations[position:] + return rest + # ____________________________________________________________ Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Wed Jan 20 14:30:54 2010 @@ -675,6 +675,13 @@ if token is not None: call_position = len(self.metainterp.history.operations) res = self.do_residual_call(varargs, descr=calldescr, exc=True) + # XXX fix the call position, + while True: + op = self.metainterp.history.operations[call_position] + if op.opnum == rop.CALL or op.opnum == rop.CALL_MAY_FORCE: + break + call_position += 1 + # if token is not None: # this will substitute the residual call with assembler call self.metainterp.direct_assembler_call(varargs, token, call_position) @@ -1357,7 +1364,7 @@ def create_empty_history(self): warmrunnerstate = self.staticdata.state - self.history = history.History(self.cpu) + self.history = history.History() self.staticdata.stats.set_history(self.history) def _all_constants(self, *boxes): @@ -1746,7 +1753,7 @@ self.in_recursion = -1 # always one portal around inputargs_and_holes = self.cpu.make_boxes_from_latest_values(resumedescr) if must_compile: - self.history = history.History(self.cpu) + self.history = history.History() self.history.inputargs = [box for box in inputargs_and_holes if box] self.staticdata.profiler.start_tracing() else: @@ -1958,6 +1965,23 @@ abox, ConstInt(j), itembox) assert i + 1 == len(self.virtualizable_boxes) + def gen_load_from_other_virtualizable(self, vbox): + vinfo = self.staticdata.virtualizable_info + boxes = [] + assert vinfo is not None + for i in range(vinfo.num_static_extra_boxes): + descr = vinfo.static_field_descrs[i] + boxes.append(self.execute_and_record(rop.GETFIELD_GC, descr, vbox)) + virtualizable = vinfo.unwrap_virtualizable_box(vbox) + for k in range(vinfo.num_arrays): + descr = vinfo.array_field_descrs[k] + abox = self.execute_and_record(rop.GETFIELD_GC, descr, vbox) + descr = vinfo.array_descrs[k] + for j in range(vinfo.get_array_length(virtualizable, k)): + boxes.append(self.execute_and_record(rop.GETARRAYITEM_GC, descr, + abox, ConstInt(j))) + return boxes + def replace_box(self, oldbox, newbox): for frame in self.framestack: boxes = frame.env @@ -2003,10 +2027,15 @@ """ assert not self.is_blackholing() # XXX num_green_args = self.staticdata.num_green_args - assert self.staticdata.virtualizable_info is None # XXX args = varargs[num_green_args + 1:] - self.history.substitute_operation(call_position, rop.CALL_ASSEMBLER, - args, descr=token) + resbox = self.history.operations[call_position].result + rest = self.history.slice_history_at(call_position) + if self.staticdata.virtualizable_info is not None: + vindex = self.staticdata.virtualizable_info.index_of_virtualizable + vbox = args[vindex - num_green_args] + args += self.gen_load_from_other_virtualizable(vbox) + self.history.record(rop.CALL_ASSEMBLER, args, resbox, descr=token) + self.history.operations += rest class GenerateMergePoint(Exception): def __init__(self, args, target_loop_token): Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_history.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_history.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_history.py Wed Jan 20 14:30:54 2010 @@ -9,3 +9,10 @@ s = lltype.cast_pointer(lltype.Ptr(S), t) const = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s)) assert const._getrepr_() == "*T" + +def test_slicing(): + h = History() + h.operations = [1, 2, 3, 4, 5] + rest = h.slice_history_at(2) + assert rest == [4, 5] + assert h.operations == [1, 2] Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Wed Jan 20 14:30:54 2010 @@ -736,8 +736,36 @@ res = self.meta_interp(portal, [2, 0], inline=True) assert res == portal(2, 0) + def test_directly_call_assembler_virtualizable(self): + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno): + frame = Frame() + frame.thing = Thing(0) + while frame.thing.val < 10: + driver.can_enter_jit(frame=frame, codeno=codeno) + driver.jit_merge_point(frame=frame, codeno=codeno) + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(frame.thing.val) + portal(1) + frame.thing = Thing(frame.thing.val + 1) + + self.meta_interp(portal, [0], inline=True) + class TestLLtype(RecursiveTests, LLJitMixin): pass class TestOOtype(RecursiveTests, OOJitMixin): pass + From fijal at codespeak.net Wed Jan 20 15:01:25 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 20 Jan 2010 15:01:25 +0100 (CET) Subject: [pypy-svn] r70727 - pypy/trunk/pypy/interpreter Message-ID: <20100120140125.0EC9016801F@codespeak.net> Author: fijal Date: Wed Jan 20 15:01:25 2010 New Revision: 70727 Modified: pypy/trunk/pypy/interpreter/pyframe.py Log: reintorduce change that was removed with faster-raise branch, but might help a bit now (at least does not hurt) Modified: pypy/trunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/pypy/interpreter/pyframe.py Wed Jan 20 15:01:25 2010 @@ -155,6 +155,9 @@ executioncontext.return_trace(self, self.space.w_None) raise executioncontext.return_trace(self, w_exitvalue) + # clean up the exception, might be useful for not + # allocating exception objects in some cases + self.last_exception = None finally: executioncontext.leave(self) return w_exitvalue From fijal at codespeak.net Wed Jan 20 15:33:15 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 20 Jan 2010 15:33:15 +0100 (CET) Subject: [pypy-svn] r70728 - pypy/branch/direct-assembler-call/pypy/jit/metainterp/test Message-ID: <20100120143315.DB1BA168020@codespeak.net> Author: fijal Date: Wed Jan 20 15:33:15 2010 New Revision: 70728 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Log: A test that is supposed to be forcing virtualizable, except it's not Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Wed Jan 20 15:33:15 2010 @@ -744,24 +744,77 @@ class Frame(object): _virtualizable2_ = ['thing'] - driver = JitDriver(greens = ['codeno'], reds = ['frame'], + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], virtualizables = ['frame'], get_printable_location = lambda codeno : str(codeno), can_inline = lambda codeno : False) - def portal(codeno): + def main(codeno): frame = Frame() frame.thing = Thing(0) - while frame.thing.val < 10: - driver.can_enter_jit(frame=frame, codeno=codeno) - driver.jit_merge_point(frame=frame, codeno=codeno) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True) + assert res == main(0) + + def test_directly_call_assembler_virtualizable_force(self): + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + class SomewhereElse(object): + pass + + somewhere_else = SomewhereElse() + + def main(codeno): + frame = Frame() + somewhere_else.frame = frame + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val if codeno == 0: subframe = Frame() - subframe.thing = Thing(frame.thing.val) - portal(1) - frame.thing = Thing(frame.thing.val + 1) + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + elif frame.thing.val > 40: + somewhere_else.frame.thing = Thing(13) + nextval = 13 + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val - self.meta_interp(portal, [0], inline=True) + res = self.meta_interp(main, [0], inline=True) + assert res == main(0) class TestLLtype(RecursiveTests, LLJitMixin): pass From fijal at codespeak.net Wed Jan 20 16:28:53 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 20 Jan 2010 16:28:53 +0100 (CET) Subject: [pypy-svn] r70729 - in pypy/branch/direct-assembler-call/pypy/jit: backend/llgraph backend/x86/test metainterp metainterp/test Message-ID: <20100120152853.40241168023@codespeak.net> Author: fijal Date: Wed Jan 20 16:28:52 2010 New Revision: 70729 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_recursive.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Log: (pedronis, fijal) Hack a bit to make forcing work as expected. Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py Wed Jan 20 16:28:52 2010 @@ -818,26 +818,34 @@ def op_call_assembler(self, loop_token, *args): global _last_exception - #assert not self._forced - #self._may_force = self.opindex - inpargs = _from_opaque(loop_token._llgraph_compiled_version).inputargs - for i, inparg in enumerate(inpargs): - TYPE = inparg.concretetype - if TYPE is lltype.Signed: - set_future_value_int(i, args[i]) - elif isinstance(TYPE, lltype.Ptr): - set_future_value_ref(i, args[i]) - elif TYPE is lltype.Float: - set_future_value_float(i, args[i]) - else: - raise Exception("Nonsense type %s" % TYPE) - - failindex = self.cpu._execute_token(loop_token) + assert not self._forced + self._may_force = self.opindex try: - return self.cpu.assembler_helper_ptr(failindex) - except LLException, lle: - assert _last_exception is None, "exception left behind" - _last_exception = lle + inpargs = _from_opaque(loop_token._llgraph_compiled_version).inputargs + for i, inparg in enumerate(inpargs): + TYPE = inparg.concretetype + if TYPE is lltype.Signed: + set_future_value_int(i, args[i]) + elif isinstance(TYPE, lltype.Ptr): + set_future_value_ref(i, args[i]) + elif TYPE is lltype.Float: + set_future_value_float(i, args[i]) + else: + raise Exception("Nonsense type %s" % TYPE) + + failindex = self.cpu._execute_token(loop_token) + try: + if self.cpu.index_of_virtualizable != -1: + return self.cpu.assembler_helper_ptr(failindex, + args[self.cpu.index_of_virtualizable]) + else: + return self.cpu.assembler_helper_ptr(failindex, + lltype.nullptr(llmemory.GCREF.TO)) + except LLException, lle: + assert _last_exception is None, "exception left behind" + _last_exception = lle + finally: + self._may_force = -1 def op_guard_not_forced(self, descr): forced = self._forced @@ -1124,7 +1132,8 @@ assert frame._may_force >= 0 call_op = frame.loop.operations[frame._may_force] guard_op = frame.loop.operations[frame._may_force+1] - assert call_op.opnum == rop.CALL_MAY_FORCE + opnum = call_op.opnum + assert opnum == rop.CALL_MAY_FORCE or opnum == rop.CALL_ASSEMBLER frame._populate_fail_args(guard_op, skip=call_op.result) return frame.fail_index Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_recursive.py Wed Jan 20 16:28:52 2010 @@ -3,4 +3,6 @@ from pypy.jit.backend.x86.test.test_basic import Jit386Mixin class TestRecursive(Jit386Mixin, RecursiveTests): + # for the individual tests see + # ====> ../../../metainterp/test/test_recursive.py pass Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Wed Jan 20 16:28:52 2010 @@ -789,6 +789,9 @@ somewhere_else = SomewhereElse() + def change(newthing): + somewhere_else.frame.thing = newthing + def main(codeno): frame = Frame() somewhere_else.frame = frame @@ -807,13 +810,14 @@ subframe.thing = Thing(nextval) nextval = portal(1, subframe) elif frame.thing.val > 40: - somewhere_else.frame.thing = Thing(13) + change(Thing(13)) nextval = 13 frame.thing = Thing(nextval + 1) i += 1 return frame.thing.val - res = self.meta_interp(main, [0], inline=True) + res = self.meta_interp(main, [0], inline=True, + policy=StopAtXPolicy(change)) assert res == main(0) class TestLLtype(RecursiveTests, LLJitMixin): Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Wed Jan 20 16:28:52 2010 @@ -444,7 +444,7 @@ (self.PORTAL_FUNCTYPE, self.PTR_PORTAL_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, RESTYPE) (_, self.PTR_ASSEMBLER_HELPER_FUNCTYPE) = self.cpu.ts.get_FuncType( - [lltype.Signed], RESTYPE) + [lltype.Signed, llmemory.GCREF], RESTYPE) def rewrite_can_enter_jit(self): FUNC = self.JIT_ENTER_FUNCTYPE @@ -562,10 +562,16 @@ self.portal_runner_ptr = self.helper_func(self.PTR_PORTAL_FUNCTYPE, ll_portal_runner) - def assembler_call_helper(failindex): + vinfo = self.metainterp_sd.virtualizable_info + + def assembler_call_helper(failindex, virtualizable): fail_descr = self.cpu.get_fail_descr_from_number(failindex) while True: try: + if vinfo is not None: + virtualizable = lltype.cast_opaque_ptr( + vinfo.VTYPEPTR, virtualizable) + vinfo.reset_vable_token(virtualizable) loop_token = fail_descr.handle_fail(self.metainterp_sd) fail_descr = self.cpu.execute_token(loop_token) except self.ContinueRunningNormally, e: @@ -598,6 +604,12 @@ self.cpu.assembler_helper_ptr = self.helper_func( self.PTR_ASSEMBLER_HELPER_FUNCTYPE, assembler_call_helper) + # XXX a bit ugly sticking + if vinfo is not None: + self.cpu.index_of_virtualizable = (vinfo.index_of_virtualizable - + self.num_green_args) + else: + self.cpu.index_of_virtualizable = -1 # ____________________________________________________________ # Now mutate origportalgraph to end with a call to portal_runner_ptr From cfbolz at codespeak.net Wed Jan 20 18:34:17 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 20 Jan 2010 18:34:17 +0100 (CET) Subject: [pypy-svn] r70731 - pypy/trunk/pypy/jit/metainterp Message-ID: <20100120173417.B54FA168026@codespeak.net> Author: cfbolz Date: Wed Jan 20 18:34:16 2010 New Revision: 70731 Modified: pypy/trunk/pypy/jit/metainterp/compile.py Log: I didn't actually mean to check this in, even though I am fairly sure that optimize_bridge should never raise InvalidLoop. Modified: pypy/trunk/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/compile.py (original) +++ pypy/trunk/pypy/jit/metainterp/compile.py Wed Jan 20 18:34:16 2010 @@ -365,7 +365,8 @@ old_loop_tokens, new_loop) except InvalidLoop: - assert 0 + # XXX I am fairly convinced that optimize_bridge cannot actually raise + # InvalidLoop return None # Did it work? if target_loop_token is not None: From cfbolz at codespeak.net Wed Jan 20 18:35:58 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 20 Jan 2010 18:35:58 +0100 (CET) Subject: [pypy-svn] r70732 - in pypy/branch/bridges-experimental/pypy/jit/metainterp: . test Message-ID: <20100120173558.78E1716802D@codespeak.net> Author: cfbolz Date: Wed Jan 20 18:35:57 2010 New Revision: 70732 Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/compile.py pypy/branch/bridges-experimental/pypy/jit/metainterp/history.py pypy/branch/bridges-experimental/pypy/jit/metainterp/optimizeopt.py pypy/branch/bridges-experimental/pypy/jit/metainterp/pyjitpl.py pypy/branch/bridges-experimental/pypy/jit/metainterp/resoperation.py pypy/branch/bridges-experimental/pypy/jit/metainterp/resume.py pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_basic.py pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_optimizeopt.py pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_virtualref.py Log: Port r70708, r70709, r70710, r70714, r70731 from trunk. Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/compile.py Wed Jan 20 18:35:57 2010 @@ -54,9 +54,11 @@ for box in loop.inputargs: assert isinstance(box, Box) if start > 0: - loop.operations = history.operations[start:] + ops = history.operations[start:] else: - loop.operations = history.operations + ops = history.operations + # make a copy, because optimize_loop can mutate the ops and descrs + loop.operations = [op.clone() for op in ops] metainterp_sd = metainterp.staticdata loop_token = make_loop_token(len(loop.inputargs)) loop.token = loop_token @@ -203,10 +205,18 @@ class ResumeDescr(AbstractFailDescr): def __init__(self, original_greenkey): self.original_greenkey = original_greenkey + def _clone_if_mutable(self): + raise NotImplementedError class ResumeGuardDescr(ResumeDescr): counter = 0 - # this class also gets attributes stored by resume.py code + # this class also gets the following attributes stored by resume.py code + rd_snapshot = None + rd_frame_info_list = None + rd_numb = None + rd_consts = None + rd_virtuals = None + rd_pendingfields = None def __init__(self, metainterp_sd, original_greenkey): ResumeDescr.__init__(self, original_greenkey) @@ -231,6 +241,17 @@ new_loop.operations) + def _clone_if_mutable(self): + res = self.__class__(self.metainterp_sd, self.original_greenkey) + # XXX a bit ugly to have to list them all here + res.rd_snapshot = self.rd_snapshot + res.rd_frame_info_list = self.rd_frame_info_list + res.rd_numb = self.rd_numb + res.rd_consts = self.rd_consts + res.rd_virtuals = self.rd_virtuals + res.rd_pendingfields = self.rd_pendingfields + return res + class ResumeGuardForcedDescr(ResumeGuardDescr): def handle_fail(self, metainterp_sd): @@ -336,13 +357,16 @@ # it does not work -- i.e. none of the existing old_loop_tokens match. new_loop = create_empty_loop(metainterp) new_loop.inputargs = metainterp.history.inputargs - new_loop.operations = metainterp.history.operations + # clone ops, as optimize_bridge can mutate the ops + new_loop.operations = [op.clone() for op in metainterp.history.operations] metainterp_sd = metainterp.staticdata try: target_loop_token = metainterp_sd.state.optimize_bridge(metainterp_sd, old_loop_tokens, new_loop) except InvalidLoop: + # XXX I am fairly convinced that optimize_bridge cannot actually raise + # InvalidLoop return None # Did it work? if target_loop_token is not None: Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/history.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/history.py Wed Jan 20 18:35:57 2010 @@ -122,6 +122,9 @@ def repr_of_descr(self): return '%r' % (self,) + def _clone_if_mutable(self): + return self + class AbstractFailDescr(AbstractDescr): index = -1 Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/optimizeopt.py Wed Jan 20 18:35:57 2010 @@ -515,20 +515,16 @@ # accumulate counters self.resumedata_memo.update_counters(self.metainterp_sd.profiler) - def emit_operation(self, op, must_clone=True): + def emit_operation(self, op): self.heap_op_optimizer.emitting_operation(op) - self._emit_operation(op, must_clone) + self._emit_operation(op) - def _emit_operation(self, op, must_clone=True): + def _emit_operation(self, op): for i in range(len(op.args)): arg = op.args[i] if arg in self.values: box = self.values[arg].force_box() - if box is not arg: - if must_clone: - op = op.clone() - must_clone = False - op.args[i] = box + op.args[i] = box self.metainterp_sd.profiler.count(jitprof.OPT_OPS) if op.is_guard(): self.metainterp_sd.profiler.count(jitprof.OPT_GUARDS) @@ -588,9 +584,8 @@ for i in range(len(specnodes)): value = self.getvalue(op.args[i]) specnodes[i].teardown_virtual_node(self, value, exitargs) - op2 = op.clone() - op2.args = exitargs[:] - self.emit_operation(op2, must_clone=False) + op.args = exitargs[:] + self.emit_operation(op) def optimize_guard(self, op, constbox, emit_operation=True): value = self.getvalue(op.args[0]) Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/pyjitpl.py Wed Jan 20 18:35:57 2010 @@ -1613,17 +1613,9 @@ # we cannot reconstruct the beginning of the proper loop raise GiveUp - oldops = self.history.operations[:] # raises in case it works -- which is the common case self.compile(original_boxes, live_arg_boxes, start) - # creation of the loop was cancelled! Patch - # history.operations so that it contains again - # exactly its old list of operations... - # xxx maybe we could patch history.operations with - # Nones after calling self.compile() instead of - # before... xxx maybe we should just raise GiveUp - del self.history.operations[:] - self.history.operations.extend(oldops) + # creation of the loop was cancelled! # Otherwise, no loop found so far, so continue tracing. start = len(self.history.operations) @@ -1661,6 +1653,7 @@ greenkey, start) if loop_token is not None: # raise if it *worked* correctly raise GenerateMergePoint(live_arg_boxes, loop_token) + self.history.operations.pop() # remove the JUMP def compile_bridge(self, live_arg_boxes): num_green_args = self.staticdata.num_green_args Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/resoperation.py Wed Jan 20 18:35:57 2010 @@ -31,7 +31,11 @@ self.descr = descr def clone(self): - op = ResOperation(self.opnum, self.args, self.result, self.descr) + descr = self.descr + if descr is not None: + descr = descr._clone_if_mutable() + op = ResOperation(self.opnum, self.args, self.result, descr) + op.fail_args = self.fail_args if not we_are_translated(): op.name = self.name op.pc = self.pc Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/resume.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/resume.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/resume.py Wed Jan 20 18:35:57 2010 @@ -271,6 +271,8 @@ def finish(self, values, pending_setfields=[]): # compute the numbering storage = self.storage + # make sure that nobody attached resume data to this guard yet + assert storage.rd_numb is None numb, liveboxes_from_env, v = self.memo.number(values, storage.rd_snapshot) self.liveboxes_from_env = liveboxes_from_env Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_basic.py Wed Jan 20 18:35:57 2010 @@ -1249,6 +1249,41 @@ assert res == 3 * 21 self.check_loops(call=1) + def test_bug_optimizeopt_mutates_ops(self): + myjitdriver = JitDriver(greens = [], reds = ['x', 'res', 'a', 'const']) + class A(object): + pass + class B(A): + pass + + glob = A() + glob.a = None + def f(x): + res = 0 + a = A() + a.x = 0 + glob.a = A() + const = 2 + while x > 0: + myjitdriver.can_enter_jit(x=x, res=res, a=a, const=const) + myjitdriver.jit_merge_point(x=x, res=res, a=a, const=const) + if type(glob.a) is B: + res += 1 + if a is None: + a = A() + a.x = x + glob.a = B() + const = 2 + else: + const = hint(const, promote=True) + x -= const + res += a.x + a = None + glob.a = A() + const = 1 + return res + res = self.meta_interp(f, [21]) + assert res == f(21) class TestOOtype(BasicTests, OOJitMixin): Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_optimizeopt.py Wed Jan 20 18:35:57 2010 @@ -207,8 +207,9 @@ class Storage(compile.ResumeGuardDescr): "for tests." - def __init__(self): - pass + def __init__(self, metainterp_sd=None, original_greenkey=None): + self.metainterp_sd = metainterp_sd + self.original_greenkey = original_greenkey def store_final_boxes(self, op, boxes): op.fail_args = boxes def __eq__(self, other): Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_virtualref.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_virtualref.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_virtualref.py Wed Jan 20 18:35:57 2010 @@ -69,7 +69,8 @@ assert res == 5 self.check_operations_history(virtual_ref=1, guard_not_forced=1) # - [guard_op] = [op for op in self.metainterp.history.operations + ops = self.metainterp.staticdata.stats.loops[0].operations + [guard_op] = [op for op in ops if op.opnum == rop.GUARD_NOT_FORCED] bxs1 = [box for box in guard_op.fail_args if str(box._getrepr_()).endswith('.X')] From afa at codespeak.net Wed Jan 20 19:31:05 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 20 Jan 2010 19:31:05 +0100 (CET) Subject: [pypy-svn] r70733 - pypy/branch/separate-compilation/pypy/translator/c/test Message-ID: <20100120183105.76FC5168026@codespeak.net> Author: afa Date: Wed Jan 20 19:31:04 2010 New Revision: 70733 Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Log: Put class handling code in its own class. Modified: pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/test/test_separate.py Wed Jan 20 19:31:04 2010 @@ -48,7 +48,7 @@ table = separate.ExportTable() for name, obj in exports.items(): if isinstance(obj, (type, types.ClassType)): - table.exported_class[name] = obj + table.exported_class[name] = separate.ClassInfo(name, obj) else: table.exported_function[name] = obj table.annotate_exported_functions(t.annotator) From afa at codespeak.net Wed Jan 20 19:31:23 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 20 Jan 2010 19:31:23 +0100 (CET) Subject: [pypy-svn] r70734 - pypy/branch/separate-compilation/pypy/translator/c Message-ID: <20100120183123.339F3168026@codespeak.net> Author: afa Date: Wed Jan 20 19:31:22 2010 New Revision: 70734 Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py Log: This belongs to the previous commit, of course Modified: pypy/branch/separate-compilation/pypy/translator/c/separate.py ============================================================================== --- pypy/branch/separate-compilation/pypy/translator/c/separate.py (original) +++ pypy/branch/separate-compilation/pypy/translator/c/separate.py Wed Jan 20 19:31:22 2010 @@ -10,18 +10,18 @@ from pypy.annotation.bookkeeper import getbookkeeper import py -class ExportTable(object): - """A table with information about the exported symbols of a module - compiled by pypy.""" +class ClassInfo: + def __init__(self, name, cls): + self.name = name + self.cls = cls - def __init__(self): - self.exported_function = {} - self.exported_class = {} - self.class_repr = {} - self.classdef = {} + def get_classdesc(self, bookkeeper): + return bookkeeper.getdesc(self.cls) + + def wrap_constructor(self): + self.constructor_name = "__new__%s" % (self.name,) - def make_wrapper_for_constructor(self, cls, name): - nbargs = len(cls.__init__.argtypes) + nbargs = len(self.cls.__init__.argtypes) args = ', '.join(['arg%d' % d for d in range(nbargs)]) source = py.code.Source(r""" @@ -30,30 +30,79 @@ obj.__init__(%s) return obj """ % (args, args)) - miniglobals = {'cls': cls, 'instantiate': instantiate} + miniglobals = {'cls': self.cls, 'instantiate': instantiate} exec source.compile() in miniglobals wrapper = miniglobals['wrapper'] wrapper._annspecialcase_ = 'specialize:ll' wrapper._always_inline_ = True - wrapper.argtypes = cls.__init__.argtypes - return func_with_new_name(wrapper, name) + wrapper.argtypes = self.cls.__init__.argtypes + + return func_with_new_name(wrapper, self.constructor_name) + + def save_repr(self, rtyper): + bookkeeper = rtyper.annotator.bookkeeper + classdef = bookkeeper.getuniqueclassdef(self.cls) + classrepr = rtyper.getrepr(model.SomeInstance(classdef)).lowleveltype + self.classdef = classdef + self.classrepr = classrepr + + def freeze(self): + """Remove data invalid for the second compilation. + Probably suitable for pickling""" + del self.cls + + def make_repr(self, module): + classdef = self.classdef + attributes = classdef.attrs + STRUCTPTR = self.classrepr + + constructor = getattr(module, self.constructor_name) + + class C_Controller(Controller): + knowntype = STRUCTPTR + + def new(self_, *args): + return constructor(*args) + + def __getattr__(self_, name): + if name.startswith('get_') and name[4:] in classdef.attrs: + def getter(obj): + return getattr(obj, 'inst_' + name[4:]) + return getter + if name.startswith('set_') and name[4:] in classdef.attrs: + def setter(obj, value): + setattr(obj, 'inst_' + name[4:], value) + return setter + raise AttributeError(name) + + class Entry(ControllerEntry): + _about_ = STRUCTPTR + _controller_ = C_Controller + + return STRUCTPTR +class ExportTable(object): + """A table with information about the exported symbols of a module + compiled by pypy.""" + + def __init__(self): + self.exported_function = {} + self.exported_class = {} def annotate_exported_functions(self, annotator): bk = annotator.bookkeeper # annotate classes - for clsname, cls in self.exported_class.items(): - desc = bk.getdesc(cls) + for clsname, class_info in self.exported_class.items(): + desc = class_info.get_classdesc(bk) classdef = desc.getuniqueclassdef() s_init = desc.s_read_attribute('__init__') if isinstance(s_init, model.SomeImpossibleValue): continue # Annotate constructor - constructor_name = "__new__%s" % (clsname,) - wrapper = self.make_wrapper_for_constructor(cls, constructor_name) - self.exported_function[constructor_name] = wrapper + wrapper = class_info.wrap_constructor() + self.exported_function[wrapper.func_name] = wrapper bk.enter(None) try: @@ -95,42 +144,10 @@ exported_funcptr[itemname] = funcptr return exported_funcptr - def make_wrapper_for_class(self, name, cls, new_func): - classdef = self.classdef[name] - attributes = classdef.attrs - STRUCTPTR = self.class_repr[name] - - class C_Controller(Controller): - knowntype = STRUCTPTR - - def new(self_, *args): - return new_func(*args) - - def __getattr__(self_, name): - if name.startswith('get_') and name[4:] in classdef.attrs: - def getter(obj): - return getattr(obj, 'inst_' + name[4:]) - return getter - if name.startswith('set_') and name[4:] in classdef.attrs: - def setter(obj, value): - setattr(obj, 'inst_' + name[4:], value) - return setter - raise AttributeError(name) - - class Entry(ControllerEntry): - _about_ = STRUCTPTR - _controller_ = C_Controller - - return STRUCTPTR - def make_import_module(self, builder, node_names): rtyper = builder.db.translator.rtyper - bookkeeper = rtyper.annotator.bookkeeper - for clsname, cls in self.exported_class.items(): - classdef = bookkeeper.getuniqueclassdef(cls) - classrepr = rtyper.getrepr(model.SomeInstance(classdef)).lowleveltype - self.classdef[clsname] = classdef - self.class_repr[clsname] = classrepr + for clsname, class_info in self.exported_class.items(): + class_info.save_repr(rtyper) forwards = [] for node in builder.db.globalcontainers(): @@ -147,14 +164,9 @@ def _freeze_(self): return True - __exported_class = self.exported_class - def __getattr__(self_, name): - if name in self_.__exported_class: - cls = self_.__exported_class[name] - constructor_name = "__new__%s" % (clsname,) - new_func = getattr(self_, constructor_name) - structptr = self.make_wrapper_for_class(name, cls, new_func) + if name in self.exported_class: + structptr = self.exported_class[name].make_repr(self_) return structptr raise AttributeError(name) From fijal at codespeak.net Wed Jan 20 20:55:28 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 20 Jan 2010 20:55:28 +0100 (CET) Subject: [pypy-svn] r70735 - pypy/branch/direct-assembler-call/pypy/jit/metainterp Message-ID: <20100120195528.1611F16801F@codespeak.net> Author: fijal Date: Wed Jan 20 20:55:27 2010 New Revision: 70735 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Log: (pedronis, fijal) Attach a calldescr to a token Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Wed Jan 20 20:55:27 2010 @@ -683,6 +683,8 @@ call_position += 1 # if token is not None: + # attach a calldescr to token, so we can use it later + token._calldescr = calldescr # this will substitute the residual call with assembler call self.metainterp.direct_assembler_call(varargs, token, call_position) return res From fijal at codespeak.net Wed Jan 20 20:56:08 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 20 Jan 2010 20:56:08 +0100 (CET) Subject: [pypy-svn] r70736 - pypy/branch/direct-assembler-call/pypy/jit/backend/x86 Message-ID: <20100120195608.046A816801F@codespeak.net> Author: fijal Date: Wed Jan 20 20:56:08 2010 New Revision: 70736 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py Log: (pedronis, fijal) IN-PROGRESS start implementing CALL_ASSEMBLER on x86 backend, passes 3 tests so far Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Wed Jan 20 20:56:08 2010 @@ -86,6 +86,7 @@ self.malloc_array_func_addr = 0 self.malloc_str_func_addr = 0 self.malloc_unicode_func_addr = 0 + self.assembler_helper_adr = 0 self.fail_boxes_int = values_array(lltype.Signed, failargs_limit) self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit) self.fail_boxes_float = values_array(lltype.Float, failargs_limit) @@ -118,6 +119,10 @@ ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode() self.malloc_unicode_func_addr = rffi.cast(lltype.Signed, ll_new_unicode) + self.assembler_helper_adr = self.cpu.cast_ptr_to_int( + self.cpu.assembler_helper_ptr) + + # done # we generate the loop body in 'mc' # 'mc2' is for guard recovery code @@ -1193,7 +1198,7 @@ tmp = ecx else: tmp = eax - + self._emit_call(x, arglocs, 2, tmp=tmp) if isinstance(resloc, MODRM64): @@ -1214,6 +1219,17 @@ self.mc.CMP(mem(ebp, FORCE_INDEX_OFS), imm(0)) return self.implement_guard(addr, self.mc.JL) + def genop_guard_call_assembler(self, op, guard_op, addr, + arglocs, result_loc): + self._emit_call(rel32(op.descr._x86_bootstrap_code), arglocs, 2, + tmp=eax) + self._emit_call(rel32(self.assembler_helper_adr), [eax, imm(0)], 0, + tmp=eax) + if isinstance(result_loc, MODRM64): + self.mc.FSTP(result_loc) + else: + assert result_loc is eax or result_loc is None + def genop_discard_cond_call_gc_wb(self, op, arglocs): # use 'mc._mc' directly instead of 'mc', to avoid # bad surprizes if the code buffer is mostly full @@ -1258,7 +1274,7 @@ def not_implemented_op_guard(self, op, guard_op, failaddr, arglocs, resloc): - msg = "not implemented operation (guard): %s" % guard_op.getopname() + msg = "not implemented operation (guard): %s" % op.getopname() print msg raise NotImplementedError(msg) Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py Wed Jan 20 20:56:08 2010 @@ -318,7 +318,7 @@ self.assembler.regalloc_perform_discard(op, arglocs) def can_merge_with_next_guard(self, op, i, operations): - if op.opnum == rop.CALL_MAY_FORCE: + if op.opnum == rop.CALL_MAY_FORCE or op.opnum == rop.CALL_ASSEMBLER: assert operations[i + 1].opnum == rop.GUARD_NOT_FORCED return True if not op.is_comparison(): @@ -639,6 +639,14 @@ assert guard_op is not None self._consider_call(op, guard_op) + def consider_call_assembler(self, op, guard_op): + descr = op.descr + assert isinstance(descr, LoopToken) + size = descr._calldescr.get_result_size(self.translate_support_code) + self._call(op, [imm(size)] + + [self.loc(arg) for arg in op.args], + guard_not_forced_op=guard_op) + def consider_cond_call_gc_wb(self, op): assert op.result is None arglocs = [self.loc(arg) for arg in op.args] @@ -977,7 +985,7 @@ name = name[len('consider_'):] num = getattr(rop, name.upper()) if (ResOperation(num, [], None).is_comparison() - or num == rop.CALL_MAY_FORCE): + or num == rop.CALL_MAY_FORCE or num == rop.CALL_ASSEMBLER): oplist_with_guard[num] = value oplist[num] = add_none_argument(value) else: From fijal at codespeak.net Thu Jan 21 11:14:01 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 21 Jan 2010 11:14:01 +0100 (CET) Subject: [pypy-svn] r70740 - pypy/benchmarks/unladen_swallow Message-ID: <20100121101401.5E7C316802C@codespeak.net> Author: fijal Date: Thu Jan 21 11:14:00 2010 New Revision: 70740 Modified: pypy/benchmarks/unladen_swallow/perf.py Log: Grumble, forgotten to check that in Modified: pypy/benchmarks/unladen_swallow/perf.py ============================================================================== --- pypy/benchmarks/unladen_swallow/perf.py (original) +++ pypy/benchmarks/unladen_swallow/perf.py Thu Jan 21 11:14:00 2010 @@ -612,6 +612,8 @@ def QuantityDelta(old, new): + if old == 0 or new == 0: + return "uncomparable" if new > old: return "%.4fx larger" % (new / old) elif new < old: From arigo at codespeak.net Thu Jan 21 13:31:35 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 21 Jan 2010 13:31:35 +0100 (CET) Subject: [pypy-svn] r70742 - in pypy/branch/c-traceback/pypy: rpython/lltypesystem translator translator/c translator/c/src translator/c/test Message-ID: <20100121123135.5C94E168026@codespeak.net> Author: arigo Date: Thu Jan 21 13:31:34 2010 New Revision: 70742 Modified: pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py pypy/branch/c-traceback/pypy/translator/c/funcgen.py pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h pypy/branch/c-traceback/pypy/translator/c/src/main.h pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py pypy/branch/c-traceback/pypy/translator/exceptiontransform.py Log: Change the implementation to make it more or less work with nested tracebacks. Modified: pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/c-traceback/pypy/rpython/lltypesystem/lloperation.py Thu Jan 21 13:31:34 2010 @@ -536,10 +536,11 @@ 'debug_fatalerror': LLOp(), 'debug_llinterpcall': LLOp(), # Python func call 'res=arg[0](*arg[1:])' # in backends, abort() or whatever is fine - 'debug_start_traceback':LLOp(), - 'debug_record_traceback':LLOp(), - 'debug_catch_exception':LLOp(), - 'debug_print_traceback':LLOp(), + 'debug_start_traceback': LLOp(), + 'debug_record_traceback': LLOp(), + 'debug_catch_exception': LLOp(), + 'debug_reraise_traceback': LLOp(), + 'debug_print_traceback': LLOp(), # __________ instrumentation _________ 'instrument_count': LLOp(), Modified: pypy/branch/c-traceback/pypy/translator/c/funcgen.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/funcgen.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/funcgen.py Thu Jan 21 13:31:34 2010 @@ -818,18 +818,17 @@ self.expr(op.args[2])) def OP_DEBUG_RECORD_TRACEBACK(self, op): - if self.functionname is None: - return '/* debug_record_traceback skipped: no functionname */' - return 'PYPY_DEBUG_RECORD_TRACEBACK("%s");' % self.functionname + #if self.functionname is None, we print "?" as the argument */ + return 'PYPY_DEBUG_RECORD_TRACEBACK("%s");' % ( + self.functionname or "?",) def OP_DEBUG_CATCH_EXCEPTION(self, op): gottype = self.expr(op.args[0]) exprs = [] for c_limited_type in op.args[1:]: exprs.append('%s == %s' % (gottype, self.expr(c_limited_type))) - return (self.OP_DEBUG_RECORD_TRACEBACK(None) + - ' if (%s) { pypy_debug_catch_exception(); }' % ( - ' || '.join(exprs),)) + return 'PYPY_DEBUG_CATCH_EXCEPTION("%s", %s, %s);' % ( + self.functionname or "?", gottype, ' || '.join(exprs)) assert not USESLOTS or '__dict__' not in dir(FunctionCodeGenerator) Modified: pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h (original) +++ pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h Thu Jan 21 13:31:34 2010 @@ -2,34 +2,65 @@ /*** C header subsection: RPython tracebacks for debugging ***/ -#define PYPY_DEBUG_TRACEBACK_DEPTH 8 - -#define OP_DEBUG_START_TRACEBACK() \ - pypy_debug_traceback_count = PYPY_DEBUG_TRACEBACK_DEPTH +/* We store a list of (location, exctype) in a circular buffer that + we hope is large enough. Example of how to interpret the content + of the buffer: + + location exctype meaning + + NULL &KeyError a KeyError was raised + h:5 NULL it was raised at h:5 + g:12 NULL which itself was called from g:12 + f:17 &KeyError called from f:17, where a finally block starts + ... ...more exceptions can occur... + RERAISE &KeyError eventually the KeyError is re-raised by f + entry:25 NULL which itself was called from entry:25 + + Note that decoding the buffer assumes that when exctype matches, it was + really the same exception, for the purpose of going back from the RERAISE + line to the f:17/KeyError line. +*/ -#define OP_DEBUG_PRINT_TRACEBACK() \ - pypy_debug_traceback_print() +#define PYPY_DEBUG_TRACEBACK_DEPTH 128 /* a power of two */ -#define PYPY_DEBUG_RECORD_TRACEBACK(funcname) \ - if ((--pypy_debug_traceback_count) >= 0) { \ - static struct pydtentry_s entry = { PYPY_FILE_NAME, funcname, __LINE__ }; \ - pypy_debug_tracebacks[pypy_debug_traceback_count] = &entry; \ +#define PYPYDTPOS_RERAISE ((struct pypydtpos_s *) -1) +#define PYPYDTSTORE(loc, etype) \ + pypy_debug_tracebacks[pypydtcount].location = loc; \ + pypy_debug_tracebacks[pypydtcount].exctype = etype; \ + pypydtcount = (pypydtcount + 1) & (PYPY_DEBUG_TRACEBACK_DEPTH-1) + +#define OP_DEBUG_START_TRACEBACK(etype, _) PYPYDTSTORE(NULL, etype) +#define OP_DEBUG_RERAISE_TRACEBACK(etp, _) PYPYDTSTORE(PYPYDTPOS_RERAISE, etp) +#define OP_DEBUG_PRINT_TRACEBACK() pypy_debug_traceback_print() + +#define PYPY_DEBUG_RECORD_TRACEBACK(funcname) { \ + static struct pypydtpos_s loc = { \ + PYPY_FILE_NAME, funcname, __LINE__ }; \ + PYPYDTSTORE(&loc, NULL); \ + } +#define PYPY_DEBUG_CATCH_EXCEPTION(funcname, etype, is_fatal) { \ + static struct pypydtpos_s loc = { \ + PYPY_FILE_NAME, funcname, __LINE__ }; \ + PYPYDTSTORE(&loc, etype); \ + if (is_fatal) pypy_debug_catch_fatal_exception(); \ } -/* Format of the data: to represent a location in the source code, we - use for now just a pointer to a 'pypy_debug_traceback_entry_s'. -*/ -struct pydtentry_s { +struct pypydtpos_s { const char *filename; const char *funcname; int lineno; }; -extern int pypy_debug_traceback_count; -extern struct pydtentry_s *pypy_debug_tracebacks[PYPY_DEBUG_TRACEBACK_DEPTH]; +struct pypydtentry_s { + struct pypydtpos_s *location; + void *exctype; +}; + +extern int pypydtcount; +extern struct pypydtentry_s pypy_debug_tracebacks[PYPY_DEBUG_TRACEBACK_DEPTH]; void pypy_debug_traceback_print(void); -void pypy_debug_catch_exception(void); +void pypy_debug_catch_fatal_exception(void); /************************************************************/ @@ -37,29 +68,56 @@ #ifndef PYPY_NOT_MAIN_FILE -int pypy_debug_traceback_count = PYPY_DEBUG_TRACEBACK_DEPTH; -struct pydtentry_s *pypy_debug_tracebacks[PYPY_DEBUG_TRACEBACK_DEPTH]; +int pypydtcount = 0; +struct pypydtentry_s pypy_debug_tracebacks[PYPY_DEBUG_TRACEBACK_DEPTH]; void pypy_debug_traceback_print(void) { - int i, lineno; - const char *filename; - const char *funcname; + int i; + int skipping; + void *my_etype = RPyFetchExceptionType(); + struct pypydtpos_s *location; + void *etype; + int has_loc; + /* This code parses the pypy_debug_tracebacks array. See example + at the start of the file. */ fprintf(stderr, "RPython traceback:\n"); - for (i = 0; i < PYPY_DEBUG_TRACEBACK_DEPTH; i++) + skipping = 0; + i = (pypydtcount - 1) & (PYPY_DEBUG_TRACEBACK_DEPTH-1); + while (i != pypydtcount) { - if (i < pypy_debug_traceback_count) - continue; - filename = pypy_debug_tracebacks[i]->filename; - funcname = pypy_debug_tracebacks[i]->funcname; - lineno = pypy_debug_tracebacks[i]->lineno; - fprintf(stderr, " File \"%s\", line %d, in %s\n", - filename, lineno, funcname); + location = pypy_debug_tracebacks[i].location; + etype = pypy_debug_tracebacks[i].exctype; + has_loc = location != NULL && location != PYPYDTPOS_RERAISE; + + if (skipping && has_loc && etype == my_etype) + skipping = 0; /* found the matching "f:17, &KeyError */ + + if (!skipping) + { + if (has_loc) + fprintf(stderr, " File \"%s\", line %d, in %s\n", + location->filename, location->lineno, location->funcname); + else + { + /* line "NULL, &KeyError" or "RERAISE, &KeyError" */ + if (etype != my_etype) + { + fprintf(stderr, " Note: this traceback is " + "incomplete or corrupted!\n"); + break; + } + if (location == NULL) /* found the place that raised the exc */ + break; + skipping = 1; /* RERAISE: skip until "f:17, &KeyError" */ + } + } + i = (i - 1) & (PYPY_DEBUG_TRACEBACK_DEPTH-1); } } -void pypy_debug_catch_exception(void) +void pypy_debug_catch_fatal_exception(void) { pypy_debug_traceback_print(); fprintf(stderr, "Fatal RPython error: %s\n", Modified: pypy/branch/c-traceback/pypy/translator/c/src/main.h ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/src/main.h (original) +++ pypy/branch/c-traceback/pypy/translator/c/src/main.h Thu Jan 21 13:31:34 2010 @@ -36,8 +36,8 @@ exitcode = STANDALONE_ENTRY_POINT(list); if (RPyExceptionOccurred()) { - /* fish for the exception type, at least */ - pypy_debug_catch_exception(); + /* print the RPython traceback */ + pypy_debug_catch_fatal_exception(); } return exitcode; Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Thu Jan 21 13:31:34 2010 @@ -413,7 +413,8 @@ assert lines2[-2] != lines[-2] # different line number assert lines2[-3] == lines[-3] # same line number - def test_fatal_error_finally(self): + def test_fatal_error_finally_1(self): + # a simple case of try:finally: def g(x): if x == 1: raise KeyError @@ -439,6 +440,77 @@ assert re.match(r' File "\w+.c", line \d+, in pypy_g_h', l2) assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l3) + def test_fatal_error_finally_2(self): + # a try:finally: in which we raise and catch another exception + def raiseme(x): + if x == 1: + raise ValueError + def raise_and_catch(x): + try: + raiseme(x) + except ValueError: + pass + def g(x): + if x == 1: + raise KeyError + def h(x): + try: + g(x) + finally: + raise_and_catch(x) + os.write(1, 'done.\n') + def entry_point(argv): + if len(argv) < 3: + h(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == 'done.' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: KeyError' + assert len(lines) >= 5 + l0, l1, l2, l3 = lines[-5:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_h', l2) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l3) + + def test_fatal_error_finally_3(self): + py.test.skip("not implemented: " + "a try:finally: in which we raise the *same* exception") + + def test_fatal_error_finally_4(self): + # a try:finally: in which we raise (and don't catch) an exception + def raiseme(x): + if x == 1: + raise ValueError + def g(x): + if x == 1: + raise KeyError + def h(x): + try: + g(x) + finally: + raiseme(x) + os.write(1, 'done.\n') + def entry_point(argv): + if len(argv) < 3: + h(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: ValueError' + assert len(lines) >= 5 + l0, l1, l2, l3 = lines[-5:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_h', l2) + assert re.match(r' File "\w+.c", line \d+, in pypy_g_raiseme', l3) + def test_assertion_error(self): def g(x): assert x != 1 Modified: pypy/branch/c-traceback/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/exceptiontransform.py (original) +++ pypy/branch/c-traceback/pypy/translator/exceptiontransform.py Thu Jan 21 13:31:34 2010 @@ -89,11 +89,12 @@ # assert(!RPyExceptionOccurred()); exc_data.exc_type = etype exc_data.exc_value = evalue - lloperation.llop.debug_start_traceback(lltype.Void) + lloperation.llop.debug_start_traceback(lltype.Void, etype) def rpyexc_reraise(etype, evalue): exc_data.exc_type = etype exc_data.exc_value = evalue + lloperation.llop.debug_reraise_traceback(lltype.Void, etype) def rpyexc_fetch_exception(): evalue = rpyexc_fetch_value() @@ -325,22 +326,24 @@ def transform_jump_to_except_block(self, graph, entrymap, link): reraise = self.comes_from_last_exception(entrymap, link) - if reraise: - fnptr = self.rpyexc_reraise_ptr - else: - fnptr = self.rpyexc_raise_ptr result = Variable() result.concretetype = lltype.Void block = Block([copyvar(None, v) for v in graph.exceptblock.inputargs]) - block.operations = [ - SpaceOperation("direct_call", - [fnptr] + block.inputargs, - result)] - if not reraise: - block.operations.append( + if reraise: + block.operations = [ + SpaceOperation("direct_call", + [self.rpyexc_reraise_ptr] + block.inputargs, + result), + ] + else: + block.operations = [ + SpaceOperation("direct_call", + [self.rpyexc_raise_ptr] + block.inputargs, + result), SpaceOperation('debug_record_traceback', [], - varoftype(lltype.Void))) + varoftype(lltype.Void)), + ] link.target = block RETTYPE = graph.returnblock.inputargs[0].concretetype l = Link([error_constant(RETTYPE)], graph.returnblock) From arigo at codespeak.net Thu Jan 21 13:32:20 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 21 Jan 2010 13:32:20 +0100 (CET) Subject: [pypy-svn] r70743 - pypy/branch/c-traceback/pypy/rpython Message-ID: <20100121123220.F31EA168026@codespeak.net> Author: arigo Date: Thu Jan 21 13:32:20 2010 New Revision: 70743 Modified: pypy/branch/c-traceback/pypy/rpython/llinterp.py Log: Add this. Modified: pypy/branch/c-traceback/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/c-traceback/pypy/rpython/llinterp.py (original) +++ pypy/branch/c-traceback/pypy/rpython/llinterp.py Thu Jan 21 13:32:20 2010 @@ -546,6 +546,9 @@ def op_debug_start_traceback(self, *args): pass # xxx write debugging code here? + def op_debug_reraise_traceback(self, *args): + pass # xxx write debugging code here? + def op_debug_record_traceback(self, *args): pass # xxx write debugging code here? From fijal at codespeak.net Thu Jan 21 14:53:59 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 21 Jan 2010 14:53:59 +0100 (CET) Subject: [pypy-svn] r70745 - in pypy/branch/direct-assembler-call/pypy/jit: backend/x86 metainterp/test Message-ID: <20100121135359.5D138168026@codespeak.net> Author: fijal Date: Thu Jan 21 14:53:58 2010 New Revision: 70745 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Log: Do the correct thing. Add an additional _x86_direct_bootstrap_code to LoopToken which represents a compiled portal that has convinient semantics for calling. Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Thu Jan 21 14:53:58 2010 @@ -159,6 +159,7 @@ """adds the following attributes to looptoken: _x86_loop_code (an integer giving an address) _x86_bootstrap_code (an integer giving an address) + _x86_direct_bootstrap_code _x86_frame_depth _x86_param_depth _x86_arglocs @@ -169,13 +170,17 @@ looptoken._x86_arglocs = arglocs looptoken._x86_bootstrap_code = self.mc.tell() adr_stackadjust = self._assemble_bootstrap_code(inputargs, arglocs) - looptoken._x86_loop_code = self.mc.tell() + curadr = self.mc.tell() + looptoken._x86_loop_code = curadr looptoken._x86_frame_depth = -1 # temporarily looptoken._x86_param_depth = -1 # temporarily frame_depth, param_depth = self._assemble(regalloc, operations) self._patch_stackadjust(adr_stackadjust, frame_depth+param_depth) looptoken._x86_frame_depth = frame_depth looptoken._x86_param_depth = param_depth + looptoken._x86_direct_bootstrap_code = self.mc.tell() + self._assemble_bootstrap_direct_call(arglocs, curadr, + frame_depth+param_depth) debug_print("Loop #", looptoken.number, "has address", looptoken._x86_loop_code, "to", self.mc.tell()) @@ -245,8 +250,7 @@ mc.write(packimm32(-WORD * aligned_words)) mc.done() - def _assemble_bootstrap_code(self, inputargs, arglocs): - nonfloatlocs, floatlocs = arglocs + def _call_header(self): self.mc.PUSH(ebp) self.mc.MOV(ebp, esp) self.mc.PUSH(ebx) @@ -254,7 +258,34 @@ self.mc.PUSH(edi) # NB. the shape of the frame is hard-coded in get_basic_shape() too. # Also, make sure this is consistent with FRAME_FIXED_SIZE. - adr_stackadjust = self._patchable_stackadjust() + return self._patchable_stackadjust() + + def _assemble_bootstrap_direct_call(self, arglocs, jmpadr, stackdepth): + # XXX this can be improved greatly. Right now it'll behave like + # a normal call + nonfloatlocs, floatlocs = arglocs + # XXX not to repeat the logic, a bit around + adr_stackadjust = self._call_header() + self._patch_stackadjust(adr_stackadjust, stackdepth) + for loc in floatlocs: + assert loc is None + # XXX no test, so no support for now + for i in range(len(nonfloatlocs)): + loc = nonfloatlocs[i] + if isinstance(loc, REG): + self.mc.MOV(loc, mem(ebp, (2 + i) * WORD)) + tmp = eax + for i in range(len(nonfloatlocs)): + loc = nonfloatlocs[i] + if not isinstance(loc, REG): + self.mc.MOV(tmp, mem(ebp, (2 + i) * WORD)) + self.mc.MOV(loc, tmp) + self.mc.JMP(rel32(jmpadr)) + return adr_stackadjust + + def _assemble_bootstrap_code(self, inputargs, arglocs): + nonfloatlocs, floatlocs = arglocs + adr_stackadjust = self._call_header() tmp = X86RegisterManager.all_regs[0] xmmtmp = X86XMMRegisterManager.all_regs[0] for i in range(len(nonfloatlocs)): @@ -1221,10 +1252,12 @@ def genop_guard_call_assembler(self, op, guard_op, addr, arglocs, result_loc): - self._emit_call(rel32(op.descr._x86_bootstrap_code), arglocs, 2, + # XXX temporary code. We generally want a separate entry point, + # needs more tests + self._emit_call(rel32(op.descr._x86_direct_bootstrap_code), arglocs, 1, tmp=eax) self._emit_call(rel32(self.assembler_helper_adr), [eax, imm(0)], 0, - tmp=eax) + tmp=ecx) if isinstance(result_loc, MODRM64): self.mc.FSTP(result_loc) else: Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Thu Jan 21 14:53:58 2010 @@ -734,7 +734,7 @@ return k res = self.meta_interp(portal, [2, 0], inline=True) - assert res == portal(2, 0) + assert res == 13542 def test_directly_call_assembler_virtualizable(self): class Thing(object): From fijal at codespeak.net Thu Jan 21 15:00:48 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 21 Jan 2010 15:00:48 +0100 (CET) Subject: [pypy-svn] r70746 - pypy/branch/direct-assembler-call/pypy/jit/backend/x86 Message-ID: <20100121140048.4A46F168026@codespeak.net> Author: fijal Date: Thu Jan 21 15:00:47 2010 New Revision: 70746 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py Log: Pass the first virtualizable test. Seems the other one explodes with "already forced" assertion error. Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Thu Jan 21 15:00:47 2010 @@ -1254,9 +1254,9 @@ arglocs, result_loc): # XXX temporary code. We generally want a separate entry point, # needs more tests - self._emit_call(rel32(op.descr._x86_direct_bootstrap_code), arglocs, 1, + self._emit_call(rel32(op.descr._x86_direct_bootstrap_code), arglocs, 2, tmp=eax) - self._emit_call(rel32(self.assembler_helper_adr), [eax, imm(0)], 0, + self._emit_call(rel32(self.assembler_helper_adr), [eax, arglocs[1]], 0, tmp=ecx) if isinstance(result_loc, MODRM64): self.mc.FSTP(result_loc) Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py Thu Jan 21 15:00:47 2010 @@ -643,7 +643,12 @@ descr = op.descr assert isinstance(descr, LoopToken) size = descr._calldescr.get_result_size(self.translate_support_code) - self._call(op, [imm(size)] + + vable_index = self.assembler.cpu.index_of_virtualizable + if vable_index != -1: + vable = self.fm.loc(op.args[vable_index], 1) + else: + vable = imm(0) + self._call(op, [imm(size), vable] + [self.loc(arg) for arg in op.args], guard_not_forced_op=guard_op) From arigo at codespeak.net Thu Jan 21 15:19:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 21 Jan 2010 15:19:09 +0100 (CET) Subject: [pypy-svn] r70747 - pypy/branch/c-traceback/pypy/translator/test Message-ID: <20100121141909.E2164168026@codespeak.net> Author: arigo Date: Thu Jan 21 15:19:09 2010 New Revision: 70747 Modified: pypy/branch/c-traceback/pypy/translator/test/test_exceptiontransform.py Log: Fix the test to account for the extra block containing debug_record_traceback. Modified: pypy/branch/c-traceback/pypy/translator/test/test_exceptiontransform.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/test/test_exceptiontransform.py (original) +++ pypy/branch/c-traceback/pypy/translator/test/test_exceptiontransform.py Thu Jan 21 15:19:09 2010 @@ -95,7 +95,7 @@ return 3 + x return 4 + x t, g = self.transform_func(foo, [int]) - assert len(list(g.iterblocks())) == 9 + assert len(list(g.iterblocks())) == 10 f = self.compile(foo, [int]) result = interpret(foo, [6]) assert result == 2 @@ -126,7 +126,7 @@ return 1 + x return 4 + x t, g = self.transform_func(foo, [int]) - assert len(list(g.iterblocks())) == 5 + assert len(list(g.iterblocks())) == 6 f = self.compile(foo, [int]) result = interpret(foo, [6]) assert result == 2 From fijal at codespeak.net Thu Jan 21 15:49:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 21 Jan 2010 15:49:20 +0100 (CET) Subject: [pypy-svn] r70748 - pypy/branch/direct-assembler-call/pypy/jit/backend/x86 Message-ID: <20100121144920.E0497168021@codespeak.net> Author: fijal Date: Thu Jan 21 15:49:19 2010 New Revision: 70748 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Log: implement guard recovery code, forgot that we have a guard to handle as well Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Thu Jan 21 15:49:19 2010 @@ -1252,8 +1252,9 @@ def genop_guard_call_assembler(self, op, guard_op, addr, arglocs, result_loc): - # XXX temporary code. We generally want a separate entry point, - # needs more tests + faildescr = guard_op.descr + fail_index = self.cpu.get_fail_descr_number(faildescr) + self.mc.MOV(mem(ebp, FORCE_INDEX_OFS), imm(fail_index)) self._emit_call(rel32(op.descr._x86_direct_bootstrap_code), arglocs, 2, tmp=eax) self._emit_call(rel32(self.assembler_helper_adr), [eax, arglocs[1]], 0, @@ -1262,6 +1263,8 @@ self.mc.FSTP(result_loc) else: assert result_loc is eax or result_loc is None + self.mc.CMP(mem(ebp, FORCE_INDEX_OFS), imm(0)) + return self.implement_guard(addr, self.mc.JL) def genop_discard_cond_call_gc_wb(self, op, arglocs): # use 'mc._mc' directly instead of 'mc', to avoid From arigo at codespeak.net Thu Jan 21 15:49:37 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 21 Jan 2010 15:49:37 +0100 (CET) Subject: [pypy-svn] r70749 - in pypy/branch/c-traceback/pypy/translator/c: . test Message-ID: <20100121144937.C0923168029@codespeak.net> Author: arigo Date: Thu Jan 21 15:49:37 2010 New Revision: 70749 Modified: pypy/branch/c-traceback/pypy/translator/c/funcgen.py pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Log: Don't print the prefix 'pypy_g_'. Modified: pypy/branch/c-traceback/pypy/translator/c/funcgen.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/funcgen.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/funcgen.py Thu Jan 21 15:49:37 2010 @@ -817,10 +817,18 @@ self.expr(op.args[1]), self.expr(op.args[2])) + def getdebugfunctionname(self): + name = self.functionname + if not name: + return "?" + if name.startswith('pypy_g_'): + name = name[7:] + return name + def OP_DEBUG_RECORD_TRACEBACK(self, op): #if self.functionname is None, we print "?" as the argument */ return 'PYPY_DEBUG_RECORD_TRACEBACK("%s");' % ( - self.functionname or "?",) + self.getdebugfunctionname(),) def OP_DEBUG_CATCH_EXCEPTION(self, op): gottype = self.expr(op.args[0]) @@ -828,7 +836,7 @@ for c_limited_type in op.args[1:]: exprs.append('%s == %s' % (gottype, self.expr(c_limited_type))) return 'PYPY_DEBUG_CATCH_EXCEPTION("%s", %s, %s);' % ( - self.functionname or "?", gottype, ' || '.join(exprs)) + self.getdebugfunctionname(), gottype, ' || '.join(exprs)) assert not USESLOTS or '__dict__' not in dir(FunctionCodeGenerator) Modified: pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/c-traceback/pypy/translator/c/test/test_standalone.py Thu Jan 21 15:49:37 2010 @@ -399,8 +399,8 @@ assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l2) + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) # out2, err2 = cbuilder.cmdexec("x", expect_crash=True) assert out2.strip() == '' @@ -408,8 +408,8 @@ assert lines2[-1] == 'Fatal RPython error: KeyError' l0, l1, l2 = lines2[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l2) + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) assert lines2[-2] != lines[-2] # different line number assert lines2[-3] == lines[-3] # same line number @@ -436,9 +436,9 @@ assert len(lines) >= 5 l0, l1, l2, l3 = lines[-5:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_h', l2) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l3) + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in h', l2) + assert re.match(r' File "\w+.c", line \d+, in g', l3) def test_fatal_error_finally_2(self): # a try:finally: in which we raise and catch another exception @@ -472,9 +472,9 @@ assert len(lines) >= 5 l0, l1, l2, l3 = lines[-5:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_h', l2) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l3) + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in h', l2) + assert re.match(r' File "\w+.c", line \d+, in g', l3) def test_fatal_error_finally_3(self): py.test.skip("not implemented: " @@ -507,9 +507,9 @@ assert len(lines) >= 5 l0, l1, l2, l3 = lines[-5:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in pypy_g_entry_point', l1) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_h', l2) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_raiseme', l3) + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in h', l2) + assert re.match(r' File "\w+.c", line \d+, in raiseme', l3) def test_assertion_error(self): def g(x): @@ -530,8 +530,8 @@ assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in pypy_g_f', l1) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l2) + assert re.match(r' File "\w+.c", line \d+, in f', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) # The traceback stops at f() because it's the first function that # captures the AssertionError, which makes the program abort. @@ -555,8 +555,8 @@ assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' - assert re.match(r' File "\w+.c", line \d+, in pypy_g_f', l1) - assert re.match(r' File "\w+.c", line \d+, in pypy_g_g', l2) + assert re.match(r' File "\w+.c", line \d+, in f', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) # The traceback stops at f() because it's the first function that # captures the AssertionError, which makes the program abort. From arigo at codespeak.net Thu Jan 21 16:17:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 21 Jan 2010 16:17:15 +0100 (CET) Subject: [pypy-svn] r70750 - pypy/trunk/pypy/interpreter Message-ID: <20100121151715.93057168021@codespeak.net> Author: arigo Date: Thu Jan 21 16:17:14 2010 New Revision: 70750 Modified: pypy/trunk/pypy/interpreter/error.py Log: Fix punctuation. Modified: pypy/trunk/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/pypy/interpreter/error.py (original) +++ pypy/trunk/pypy/interpreter/error.py Thu Jan 21 16:17:14 2010 @@ -203,8 +203,8 @@ w_instclass = space.exception_getclass(w_inst) if not space.exception_is_valid_class_w(w_instclass): instclassname = w_instclass.getname(space, '?') - msg = ("exceptions must be classes, or instances," - "or strings (deprecated) not %s" % (instclassname,)) + msg = ("exceptions must be classes, or instances, " + "or strings (deprecated), not %s" % (instclassname,)) raise OperationError(space.w_TypeError, space.wrap(msg)) if not space.is_w(w_value, space.w_None): From fijal at codespeak.net Thu Jan 21 16:17:49 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 21 Jan 2010 16:17:49 +0100 (CET) Subject: [pypy-svn] r70751 - pypy/branch/direct-assembler-call/pypy/jit/backend/test Message-ID: <20100121151749.D080F168021@codespeak.net> Author: fijal Date: Thu Jan 21 16:17:49 2010 New Revision: 70751 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/test/support.py Log: turn on by default list_comprehenstion_operations. Saves some annoying warnings Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/test/support.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/test/support.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/test/support.py Thu Jan 21 16:17:49 2010 @@ -120,6 +120,7 @@ def _get_TranslationContext(self): t = TranslationContext() t.config.translation.gc = 'boehm' + t.config.translation.list_comprehension_operations = True return t def _compile_and_run(self, t, entry_point, entry_point_graph, args): From cfbolz at codespeak.net Thu Jan 21 16:33:18 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 21 Jan 2010 16:33:18 +0100 (CET) Subject: [pypy-svn] r70752 - in pypy/branch/bridges-experimental/pypy/jit/metainterp: . test Message-ID: <20100121153318.AFBBD168021@codespeak.net> Author: cfbolz Date: Thu Jan 21 16:33:18 2010 New Revision: 70752 Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/pyjitpl.py pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_basic.py pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_exception.py pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_loop.py pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_recursive.py Log: Experimental: after we made a new loop, immediately attach a bridge to it using the same trace. In theory it should cut down on compilation time, in practise it doesn't seem to matter. Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/pyjitpl.py Thu Jan 21 16:33:18 2010 @@ -1644,6 +1644,7 @@ def compile(self, original_boxes, live_arg_boxes, start): num_green_args = self.staticdata.num_green_args + orig_inputargs = self.history.inputargs self.history.inputargs = original_boxes[num_green_args:] greenkey = original_boxes[:num_green_args] glob = self.staticdata.globaldata @@ -1651,7 +1652,17 @@ self.history.record(rop.JUMP, live_arg_boxes[num_green_args:], None) loop_token = compile.compile_new_loop(self, old_loop_tokens, greenkey, start) - if loop_token is not None: # raise if it *worked* correctly + if loop_token is not None: + # try to immediately attach a bridge to the newly created + # loop_token + if orig_inputargs is not None: + self.history.inputargs = orig_inputargs + target_loop_token = compile.compile_new_bridge(self, [loop_token], + self.resumekey) + # target_loop_token can be None or not, we want to use the new loop + # anyway + + # raise if it *worked* correctly raise GenerateMergePoint(live_arg_boxes, loop_token) self.history.operations.pop() # remove the JUMP Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_basic.py Thu Jan 21 16:33:18 2010 @@ -571,11 +571,10 @@ self.meta_interp(f, [20], repeat=7) self.check_tree_loop_count(2) # the loop and the entry path # we get: - # ENTER - compile the new loop + # ENTER - compile the new loop and the entry bridge # ENTER (BlackHole) - leave - # ENTER - compile the entry bridge # ENTER - compile the leaving path - self.check_enter_count(4) + self.check_enter_count(3) def test_bridge_from_interpreter_2(self): # one case for backend - computing of framesize on guard failure @@ -945,7 +944,7 @@ res = self.meta_interp(f, [10, 3]) assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 - self.check_tree_loop_count(1) + self.check_tree_loop_count(2) res = self.meta_interp(f, [10, 13]) assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_exception.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_exception.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_exception.py Thu Jan 21 16:33:18 2010 @@ -516,11 +516,10 @@ assert res == -1 self.check_tree_loop_count(2) # the loop and the entry path # we get: - # ENTER - compile the new loop + # ENTER - compile the new loop and the entry bridge # ENTER (BlackHole) - leave - # ENTER - compile the entry bridge # ENTER - compile the leaving path (raising MyError) - self.check_enter_count(4) + self.check_enter_count(3) def test_bridge_from_interpreter_exc_2(self): Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_loop.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_loop.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_loop.py Thu Jan 21 16:33:18 2010 @@ -84,7 +84,8 @@ return res * 2 res = self.meta_interp(f, [6, 33], policy=StopAtXPolicy(l)) assert res == f(6, 33) - self.check_loop_count(2) + # XXX + self.check_loop_count(3) def test_alternating_loops(self): myjitdriver = JitDriver(greens = [], reds = ['pattern']) Modified: pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/bridges-experimental/pypy/jit/metainterp/test/test_recursive.py Thu Jan 21 16:33:18 2010 @@ -367,7 +367,7 @@ res = self.meta_interp(loop, [100], optimizer=OPTIMIZER_SIMPLE, inline=True, trace_limit=TRACE_LIMIT) assert res == 0 self.check_max_trace_length(TRACE_LIMIT) - self.check_enter_count(15) # maybe + self.check_enter_count(14) # maybe self.check_aborted_count(7) def test_trace_limit_bridge(self): From fijal at codespeak.net Thu Jan 21 16:54:35 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 21 Jan 2010 16:54:35 +0100 (CET) Subject: [pypy-svn] r70753 - in pypy/branch/direct-assembler-call/pypy/jit: backend backend/x86 metainterp Message-ID: <20100121155435.C0CD3168021@codespeak.net> Author: fijal Date: Thu Jan 21 16:54:35 2010 New Revision: 70753 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/model.py pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Log: RPythonization. While we're at it, store portal_calldescr directly on cpu instead of on LoopToken (we can have only one anyway) Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/model.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/model.py Thu Jan 21 16:54:35 2010 @@ -5,6 +5,7 @@ supports_floats = False # assembler_helper_ptr - a pointer to helper to call after a direct # assembler call + portal_calldescr = None def __init__(self): self.fail_descr_list = [] Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Thu Jan 21 16:54:35 2010 @@ -2,7 +2,8 @@ import ctypes from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.history import Const, Box, BoxInt, BoxPtr, BoxFloat -from pypy.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT +from pypy.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT,\ + LoopToken from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory from pypy.rpython.lltypesystem.rclass import OBJECT from pypy.rpython.lltypesystem.lloperation import llop @@ -1255,7 +1256,9 @@ faildescr = guard_op.descr fail_index = self.cpu.get_fail_descr_number(faildescr) self.mc.MOV(mem(ebp, FORCE_INDEX_OFS), imm(fail_index)) - self._emit_call(rel32(op.descr._x86_direct_bootstrap_code), arglocs, 2, + descr = op.descr + assert isinstance(descr, LoopToken) + self._emit_call(rel32(descr._x86_direct_bootstrap_code), arglocs, 2, tmp=eax) self._emit_call(rel32(self.assembler_helper_adr), [eax, arglocs[1]], 0, tmp=ecx) Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py Thu Jan 21 16:54:35 2010 @@ -641,8 +641,8 @@ def consider_call_assembler(self, op, guard_op): descr = op.descr - assert isinstance(descr, LoopToken) - size = descr._calldescr.get_result_size(self.translate_support_code) + portal_calldescr = self.assembler.cpu.portal_calldescr + size = portal_calldescr.get_result_size(self.translate_support_code) vable_index = self.assembler.cpu.index_of_virtualizable if vable_index != -1: vable = self.fm.loc(op.args[vable_index], 1) Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Thu Jan 21 16:54:35 2010 @@ -683,8 +683,6 @@ call_position += 1 # if token is not None: - # attach a calldescr to token, so we can use it later - token._calldescr = calldescr # this will substitute the residual call with assembler call self.metainterp.direct_assembler_call(varargs, token, call_position) return res Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmspot.py Thu Jan 21 16:54:35 2010 @@ -561,16 +561,20 @@ self.ll_portal_runner = ll_portal_runner # for debugging self.portal_runner_ptr = self.helper_func(self.PTR_PORTAL_FUNCTYPE, ll_portal_runner) + self.cpu.portal_calldescr = self.cpu.calldescrof( + self.PTR_PORTAL_FUNCTYPE.TO, + self.PTR_PORTAL_FUNCTYPE.TO.ARGS, + self.PTR_PORTAL_FUNCTYPE.TO.RESULT) vinfo = self.metainterp_sd.virtualizable_info - def assembler_call_helper(failindex, virtualizable): + def assembler_call_helper(failindex, virtualizableref): fail_descr = self.cpu.get_fail_descr_from_number(failindex) while True: try: if vinfo is not None: virtualizable = lltype.cast_opaque_ptr( - vinfo.VTYPEPTR, virtualizable) + vinfo.VTYPEPTR, virtualizableref) vinfo.reset_vable_token(virtualizable) loop_token = fail_descr.handle_fail(self.metainterp_sd) fail_descr = self.cpu.execute_token(loop_token) From fijal at codespeak.net Thu Jan 21 17:19:11 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 21 Jan 2010 17:19:11 +0100 (CET) Subject: [pypy-svn] r70754 - pypy/branch/direct-assembler-call/pypy/jit/metainterp Message-ID: <20100121161911.7AFE4168024@codespeak.net> Author: fijal Date: Thu Jan 21 17:19:10 2010 New Revision: 70754 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Log: This is supposed to be a non-resizable list Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Thu Jan 21 17:19:10 2010 @@ -2034,7 +2034,7 @@ vindex = self.staticdata.virtualizable_info.index_of_virtualizable vbox = args[vindex - num_green_args] args += self.gen_load_from_other_virtualizable(vbox) - self.history.record(rop.CALL_ASSEMBLER, args, resbox, descr=token) + self.history.record(rop.CALL_ASSEMBLER, args[:], resbox, descr=token) self.history.operations += rest class GenerateMergePoint(Exception): From afa at codespeak.net Thu Jan 21 18:00:00 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 21 Jan 2010 18:00:00 +0100 (CET) Subject: [pypy-svn] r70755 - in pypy/trunk/pypy/objspace: std/test test Message-ID: <20100121170000.0114A16801F@codespeak.net> Author: afa Date: Thu Jan 21 17:59:58 2010 New Revision: 70755 Modified: pypy/trunk/pypy/objspace/std/test/test_userobject.py pypy/trunk/pypy/objspace/test/test_descriptor.py Log: Add a descriptor test that fails when objspace.std.getattributeshortcut is True. Also repair AppTestWithGetAttributeShortcut, which was not really testing the option: setup_class() is defined in the base class, so the one from mix-in is ignored. I could not find an easy fix. Remember to run both test_descriptor.py and test_userobject.py... Modified: pypy/trunk/pypy/objspace/std/test/test_userobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_userobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_userobject.py Thu Jan 21 17:59:58 2010 @@ -295,19 +295,13 @@ multimethod.Installer = cls.prev_installer -class GetAttributeShortcutTest: - - def setup_class(cls): - from pypy import conftest - options = {"objspace.std.getattributeshortcut" : True} - cls.space = conftest.gettestobjspace(**options) - - -class AppTestWithGetAttributeShortcut(AppTestUserObject, - GetAttributeShortcutTest): - pass +class AppTestWithGetAttributeShortcut(AppTestUserObject): + OPTIONS = {"objspace.std.getattributeshortcut": True} class AppTestDescriptorWithGetAttributeShortcut( - test_descriptor.AppTest_Descriptor, GetAttributeShortcutTest): - pass + test_descriptor.AppTest_Descriptor): + # for the individual tests see + # ====> ../../test/test_descriptor.py + + OPTIONS = {"objspace.std.getattributeshortcut": True} Modified: pypy/trunk/pypy/objspace/test/test_descriptor.py ============================================================================== --- pypy/trunk/pypy/objspace/test/test_descriptor.py (original) +++ pypy/trunk/pypy/objspace/test/test_descriptor.py Thu Jan 21 17:59:58 2010 @@ -1,6 +1,12 @@ +from pypy.conftest import gettestobjspace class AppTest_Descriptor: + OPTIONS = {} + + def setup_class(cls): + cls.space = gettestobjspace(**cls.OPTIONS) + def test_non_data_descr(self): class X(object): def f(self): @@ -30,6 +36,31 @@ x.a = 42 assert x.a == 42 + def test_failing_get(self): + # when __get__() raises AttributeError, + # __getattr__ is called... + class X(object): + def get_v(self): + raise AttributeError + v = property(get_v) + + def __getattr__(self, name): + if name == 'v': + return 42 + x = X() + assert x.v == 42 + + # ... but the __dict__ is not searched + class Y(object): + def get_w(self): + raise AttributeError + def set_w(self, value): + raise AttributeError + w = property(get_w, set_w) + y = Y() + y.__dict__['w'] = 42 + raises(AttributeError, getattr, y, 'w') + def test_member(self): class X(object): def __init__(self): From fijal at codespeak.net Thu Jan 21 18:24:02 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 21 Jan 2010 18:24:02 +0100 (CET) Subject: [pypy-svn] r70756 - in pypy/branch/direct-assembler-call/pypy/jit/backend: llgraph/test test x86 x86/test Message-ID: <20100121172402.6AF5B168026@codespeak.net> Author: fijal Date: Thu Jan 21 18:24:00 2010 New Revision: 70756 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/branch/direct-assembler-call/pypy/jit/backend/test/runner_test.py pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_runner.py Log: Write direct tests for assembler_call support in the backend. Implement missing cases in x86 backend Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/test/test_llgraph.py Thu Jan 21 18:24:00 2010 @@ -7,7 +7,8 @@ TreeLoop from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.metainterp.executor import execute -from pypy.jit.backend.test.runner_test import LLtypeBackendTest +from pypy.jit.backend.test.runner_test import LLtypeBackendTest, \ + BaseAssemblerCallTests class TestLLTypeLLGraph(LLtypeBackendTest): # for individual tests see: Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/test/runner_test.py Thu Jan 21 18:24:00 2010 @@ -15,6 +15,7 @@ from pypy.jit.metainterp.test.oparser import parse from pypy.rpython.annlowlevel import llhelper from pypy.rpython.llinterp import LLException +from pypy.jit.metainterp.test.oparser import parse class Runner(object): @@ -464,7 +465,7 @@ [funcbox] + args, 'float', descr=calldescr) assert abs(res.value - 4.6) < 0.0001 - + def test_call_stack_alignment(self): # test stack alignment issues, notably for Mac OS/X. # also test the ordering of the arguments. @@ -1609,6 +1610,87 @@ lltype.free(x, flavor='raw') + def test_assembler_call(self): + called = [] + def assembler_helper(failindex, virtualizable): + assert self.cpu.get_latest_value_int(0) == 10 + called.append(failindex) + return 4 + 9 + self.cpu.index_of_virtualizable = -1 + self.cpu.assembler_helper_ptr = llhelper(lltype.Ptr(lltype.FuncType + ([lltype.Signed, llmemory.GCREF], lltype.Signed)), assembler_helper) + + ops = ''' + [i0, i1] + i2 = int_add(i0, i1) + finish(i2)''' + loop = parse(ops) + looptoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + ARGS = [lltype.Signed, lltype.Signed] + RES = lltype.Signed + self.cpu.portal_calldescr = self.cpu.calldescrof( + lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES) + self.cpu.set_future_value_int(0, 1) + self.cpu.set_future_value_int(1, 2) + res = self.cpu.execute_token(looptoken) + assert self.cpu.get_latest_value_int(0) == 3 + ops = ''' + [i4, i5] + i6 = int_add(i4, 1) + i3 = call_assembler(i6, i5, descr=looptoken) + guard_not_forced()[] + finish(i3) + ''' + loop = parse(ops, namespace=locals()) + othertoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + self.cpu.set_future_value_int(0, 4) + self.cpu.set_future_value_int(1, 5) + res = self.cpu.execute_token(othertoken) + assert self.cpu.get_latest_value_int(0) == 13 + assert called + + def test_assembler_call_float(self): + called = [] + def assembler_helper(failindex, virtualizable): + assert self.cpu.get_latest_value_float(0) == 1.2 + 3.2 + called.append(failindex) + return 13.5 + self.cpu.index_of_virtualizable = -1 + self.cpu.assembler_helper_ptr = llhelper(lltype.Ptr(lltype.FuncType + ([lltype.Signed, llmemory.GCREF], lltype.Float)), assembler_helper) + ARGS = [lltype.Float, lltype.Float] + RES = lltype.Float + self.cpu.portal_calldescr = self.cpu.calldescrof( + lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES) + + ops = ''' + [f0, f1] + f2 = float_add(f0, f1) + finish(f2)''' + loop = parse(ops) + looptoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + self.cpu.set_future_value_float(0, 1.2) + self.cpu.set_future_value_float(1, 2.3) + res = self.cpu.execute_token(looptoken) + assert self.cpu.get_latest_value_float(0) == 1.2 + 2.3 + ops = ''' + [f4, f5] + f3 = call_assembler(f4, f5, descr=looptoken) + guard_not_forced()[] + finish(f3) + ''' + loop = parse(ops, namespace=locals()) + othertoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + self.cpu.set_future_value_float(0, 1.2) + self.cpu.set_future_value_float(1, 3.2) + res = self.cpu.execute_token(othertoken) + assert self.cpu.get_latest_value_float(0) == 13.5 + assert called + class OOtypeBackendTest(BaseBackendTest): type_system = 'ootype' @@ -1646,3 +1728,4 @@ def alloc_unicode(self, unicode): py.test.skip("implement me") + Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Thu Jan 21 18:24:00 2010 @@ -120,8 +120,9 @@ ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode() self.malloc_unicode_func_addr = rffi.cast(lltype.Signed, ll_new_unicode) - self.assembler_helper_adr = self.cpu.cast_ptr_to_int( - self.cpu.assembler_helper_ptr) + if self.cpu.assembler_helper_ptr: + self.assembler_helper_adr = self.cpu.cast_ptr_to_int( + self.cpu.assembler_helper_ptr) # done @@ -268,19 +269,24 @@ # XXX not to repeat the logic, a bit around adr_stackadjust = self._call_header() self._patch_stackadjust(adr_stackadjust, stackdepth) - for loc in floatlocs: - assert loc is None - # XXX no test, so no support for now for i in range(len(nonfloatlocs)): loc = nonfloatlocs[i] if isinstance(loc, REG): self.mc.MOV(loc, mem(ebp, (2 + i) * WORD)) + loc = floatlocs[i] + if isinstance(loc, XMMREG): + self.mc.MOVSD(loc, mem64(ebp, (1 + i) * 2 * WORD)) tmp = eax + xmmtmp = xmm0 for i in range(len(nonfloatlocs)): loc = nonfloatlocs[i] - if not isinstance(loc, REG): + if loc is not None and not isinstance(loc, REG): self.mc.MOV(tmp, mem(ebp, (2 + i) * WORD)) self.mc.MOV(loc, tmp) + loc = floatlocs[i] + if loc is not None and not isinstance(loc, XMMREG): + self.mc.MOVSD(xmmtmp, mem64(ebp, (1 + i) * 2 * WORD)) + self.mc.MOVSD(loc, xmmtmp) self.mc.JMP(rel32(jmpadr)) return adr_stackadjust Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_runner.py Thu Jan 21 18:24:00 2010 @@ -25,8 +25,9 @@ # for the individual tests see # ====> ../../test/runner_test.py - def setup_class(cls): - cls.cpu = CPU(rtyper=None, stats=FakeStats()) + def setup_method(self, meth): + self.cpu = CPU(rtyper=None, stats=FakeStats()) + self.cpu.assembler_helper_ptr = None def test_execute_ptr_operation(self): cpu = self.cpu From afa at codespeak.net Thu Jan 21 18:36:54 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 21 Jan 2010 18:36:54 +0100 (CET) Subject: [pypy-svn] r70757 - in pypy/trunk/pypy: interpreter objspace/test Message-ID: <20100121173654.25E4416801F@codespeak.net> Author: afa Date: Thu Jan 21 18:36:53 2010 New Revision: 70757 Modified: pypy/trunk/pypy/interpreter/gateway.py pypy/trunk/pypy/objspace/test/test_descriptor.py Log: It's actually possible to mark applevel tests with @py.test.mark.xfail, with just a little hack in the gateway. Modified: pypy/trunk/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/pypy/interpreter/gateway.py (original) +++ pypy/trunk/pypy/interpreter/gateway.py Thu Jan 21 18:36:53 2010 @@ -1084,6 +1084,11 @@ """ if not isinstance(source, str): source = str(py.code.Source(source).strip()) + while source.startswith('@py.test.mark.'): + # these decorators are known to return the same function + # object, we may ignore them + assert '\n' in source + source = source[source.find('\n') + 1:] assert source.startswith("def "), "can only transform functions" source = source[4:] p = source.find('(') Modified: pypy/trunk/pypy/objspace/test/test_descriptor.py ============================================================================== --- pypy/trunk/pypy/objspace/test/test_descriptor.py (original) +++ pypy/trunk/pypy/objspace/test/test_descriptor.py Thu Jan 21 18:36:53 2010 @@ -1,3 +1,4 @@ +import py from pypy.conftest import gettestobjspace class AppTest_Descriptor: @@ -36,6 +37,7 @@ x.a = 42 assert x.a == 42 + @py.test.mark.xfail def test_failing_get(self): # when __get__() raises AttributeError, # __getattr__ is called... From fijal at codespeak.net Thu Jan 21 18:46:28 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 21 Jan 2010 18:46:28 +0100 (CET) Subject: [pypy-svn] r70758 - pypy/trunk/ctypes_configure Message-ID: <20100121174628.1885516801F@codespeak.net> Author: fijal Date: Thu Jan 21 18:46:27 2010 New Revision: 70758 Modified: pypy/trunk/ctypes_configure/cbuild.py Log: kill the useless dependency on py.log Modified: pypy/trunk/ctypes_configure/cbuild.py ============================================================================== --- pypy/trunk/ctypes_configure/cbuild.py (original) +++ pypy/trunk/ctypes_configure/cbuild.py Thu Jan 21 18:46:27 2010 @@ -5,8 +5,6 @@ debug = 0 -log = py.log.Producer("cbuild") - configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure') class ExternalCompilationInfo(object): @@ -327,7 +325,7 @@ def log_spawned_cmd(spawn): def spawn_and_log(cmd, *args, **kwds): if debug: - log.execute(' '.join(cmd)) + print ' '.join(cmd) return spawn(cmd, *args, **kwds) return spawn_and_log From arigo at codespeak.net Thu Jan 21 18:53:07 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 21 Jan 2010 18:53:07 +0100 (CET) Subject: [pypy-svn] r70759 - in pypy/branch/c-traceback/pypy/translator: . test Message-ID: <20100121175307.DB9DD16801F@codespeak.net> Author: arigo Date: Thu Jan 21 18:53:07 2010 New Revision: 70759 Modified: pypy/branch/c-traceback/pypy/translator/exceptiontransform.py pypy/branch/c-traceback/pypy/translator/test/test_exceptiontransform.py Log: Test and fix for comes_from_last_exception(). Modified: pypy/branch/c-traceback/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/exceptiontransform.py (original) +++ pypy/branch/c-traceback/pypy/translator/exceptiontransform.py Thu Jan 21 18:53:07 2010 @@ -298,30 +298,28 @@ return need_exc_matching, n_gen_exc_checks def comes_from_last_exception(self, entrymap, link): - block = link.prevblock - v = link.args[1] seen = {} - pending = [(block, v)] + pending = [(link, link.args[1])] while pending: - block, v = pending.pop() - if (block, v) in seen: + link, v = pending.pop() + if (link, v) in seen: + continue + seen[link, v] = True + if link.last_exc_value is not None and v is link.last_exc_value: + return True + block = link.prevblock + if block is None: continue - seen[block, v] = True for op in block.operations[::-1]: if v is op.result: if op.opname == 'cast_pointer': v = op.args[0] else: break - else: - for link in entrymap.get(block, ()): - if link.prevblock is not None: - for inputarg, outputarg in zip(link.args, - block.inputargs): - if outputarg is v: - if inputarg is link.last_exc_value: - return True - pending.append((link.prevblock, inputarg)) + for link in entrymap.get(block, ()): + for v1, v2 in zip(link.args, block.inputargs): + if v2 is v: + pending.append((link, v1)) return False def transform_jump_to_except_block(self, graph, entrymap, link): Modified: pypy/branch/c-traceback/pypy/translator/test/test_exceptiontransform.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/test/test_exceptiontransform.py (original) +++ pypy/branch/c-traceback/pypy/translator/test/test_exceptiontransform.py Thu Jan 21 18:53:07 2010 @@ -175,6 +175,34 @@ etrafo.create_exception_handling(g) assert etrafo.raise_analyzer.analyze_direct_call(g) + def test_reraise_is_not_raise(self): + def one(x): + if x == 1: + raise ValueError() + elif x == 2: + raise TypeError() + return x - 5 + def foo(x): + try: + return one(x) + except ValueError: + return -42 + t, g = self.transform_func(foo, [int]) + for block in g.iterblocks(): + for op in block.operations: + # the operation 'debug_record_traceback' should only show up + # in a normal raise, not in a reraise + assert op.opname != 'debug_record_traceback' + f = self.compile(foo, [int]) + result = interpret(foo, [7]) + assert result == 2 + result = f(7) + assert result == 2 + result = interpret(foo, [1]) + assert result == -42 + result = f(1) + assert result == -42 + class TestLLType(BaseTestExceptionTransform): type_system = 'lltype' From arigo at codespeak.net Thu Jan 21 19:30:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 21 Jan 2010 19:30:57 +0100 (CET) Subject: [pypy-svn] r70760 - pypy/branch/c-traceback/pypy/translator/c/src Message-ID: <20100121183057.96569168021@codespeak.net> Author: arigo Date: Thu Jan 21 19:30:57 2010 New Revision: 70760 Modified: pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h Log: Print "..." if the traceback is interrupted because the buffer is not long enough. Modified: pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h ============================================================================== --- pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h (original) +++ pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h Thu Jan 21 19:30:57 2010 @@ -84,9 +84,16 @@ at the start of the file. */ fprintf(stderr, "RPython traceback:\n"); skipping = 0; - i = (pypydtcount - 1) & (PYPY_DEBUG_TRACEBACK_DEPTH-1); - while (i != pypydtcount) + i = pypydtcount; + while (1) { + i = (i - 1) & (PYPY_DEBUG_TRACEBACK_DEPTH-1); + if (i == pypydtcount) + { + fprintf(stderr, " ...\n"); + break; + } + location = pypy_debug_tracebacks[i].location; etype = pypy_debug_tracebacks[i].exctype; has_loc = location != NULL && location != PYPYDTPOS_RERAISE; @@ -113,7 +120,6 @@ skipping = 1; /* RERAISE: skip until "f:17, &KeyError" */ } } - i = (i - 1) & (PYPY_DEBUG_TRACEBACK_DEPTH-1); } } From fijal at codespeak.net Thu Jan 21 22:26:42 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 21 Jan 2010 22:26:42 +0100 (CET) Subject: [pypy-svn] r70762 - in pypy/benchmarks: . own Message-ID: <20100121212642.6B2E616802D@codespeak.net> Author: fijal Date: Thu Jan 21 22:26:40 2010 New Revision: 70762 Added: pypy/benchmarks/own/gcbench.py - copied, changed from r70761, pypy/trunk/pypy/translator/goal/gcbench.py Modified: pypy/benchmarks/benchmarks.py Log: Add gcbench. Mostly for the joy of merging direct-assembler-call branch ;-) Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Thu Jan 21 22:26:40 2010 @@ -5,10 +5,10 @@ def relative(*args): return os.path.join(os.path.dirname(os.path.abspath(__file__)), *args) -def _register_new_bm(name, d): +def _register_new_bm(name, d, **opts): def Measure(python, options): bm_path = relative('own', name + '.py') - return MeasureGeneric(python, options, bm_path) + return MeasureGeneric(python, options, bm_path, **opts) Measure.func_name = 'Measure' + name.capitalize() def BM(*args, **kwds): @@ -17,6 +17,10 @@ d[BM.func_name] = BM +opts = { + 'gcbench' : {'iteration_scaling' : .10}, +} + for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch', - 'spectral-norm', 'chaos', 'telco']: - _register_new_bm(name, globals()) + 'spectral-norm', 'chaos', 'telco', 'gcbench']: + _register_new_bm(name, globals(), **opts.get(name, {})) Copied: pypy/benchmarks/own/gcbench.py (from r70761, pypy/trunk/pypy/translator/goal/gcbench.py) ============================================================================== --- pypy/trunk/pypy/translator/goal/gcbench.py (original) +++ pypy/benchmarks/own/gcbench.py Thu Jan 21 22:26:40 2010 @@ -43,7 +43,7 @@ # - No attempt to measure variation with object size # - Results are sensitive to locking cost, but we dont # check for proper locking -import os, time +import os, time, sys USAGE = """gcbench [num_repetitions] [--depths=N,N,N..] [--threads=N]""" ENABLE_THREADS = True @@ -91,74 +91,87 @@ "ought to print free/total memory" pass -def time_construction(depth): +def time_construction(depth, debug=False): niters = num_iters(depth) - print "Creating %d trees of depth %d" % (niters, depth) + if debug: + print "Creating %d trees of depth %d" % (niters, depth) t_start = time.time() for i in range(niters): temp_tree = Node() populate(depth, temp_tree) temp_tree = None t_finish = time.time() - print "\tTop down constrution took %f ms" % ((t_finish-t_start)*1000.) + if debug: + print "\tTop down constrution took %f ms" % ((t_finish-t_start)*1000.) t_start = time.time() for i in range(niters): temp_tree = make_tree(depth) temp_tree = None t_finish = time.time() - print "\tBottom up constrution took %f ms" % ((t_finish-t_start)*1000.) + if debug: + print "\tBottom up constrution took %f ms" % ((t_finish-t_start)*1000.) DEFAULT_DEPTHS = range(kMinTreeDepth, kMaxTreeDepth+1, 2) -def time_constructions(depths): +def time_constructions(depths, debug=False): for d in depths: - time_construction(d) + time_construction(d, debug) -def time_parallel_constructions(depths, nthreads): +def time_parallel_constructions(depths, nthreads, debug=False): import threading threadlist = [] - print "Starting %d parallel threads..." % (nthreads,) + if debug: + print "Starting %d parallel threads..." % (nthreads,) for n in range(nthreads): - t = threading.Thread(target=time_constructions, args=(depths,)) + t = threading.Thread(target=time_constructions, args=(depths,debug)) t.start() threadlist.append(t) for t in threadlist: t.join() - print "All %d threads finished" % (nthreads,) + if debug: + print "All %d threads finished" % (nthreads,) -def main(depths=DEFAULT_DEPTHS, threads=0): - print "Garbage Collector Test" - print " Stretching memory with a binary tree of depth %d" % kStretchTreeDepth - print_diagnostics() - t_start = time.time() - temp_tree = make_tree(kStretchTreeDepth) - temp_tree = None +def main(numruns, depths=DEFAULT_DEPTHS, threads=0, debug=False): + times = [] + for i in range(numruns): + if debug: + print "Garbage Collector Test" + print " Stretching memory with a binary tree of depth %d" % kStretchTreeDepth + print_diagnostics() + t_start = time.time() + temp_tree = make_tree(kStretchTreeDepth) + temp_tree = None - # Create a long lived object - print " Creating a long-lived binary tree of depth %d" % kLongLivedTreeDepth - long_lived_tree = Node() - populate(kLongLivedTreeDepth, long_lived_tree) - - # Create long-lived array, filling half of it - print " Creating a long-lived array of %d doubles" % kArraySize - array = [0.0] * kArraySize - i = 1 - while i < kArraySize/2: - array[i] = 1.0/i - i += 1 - print_diagnostics() + # Create a long lived object + if debug: + print " Creating a long-lived binary tree of depth %d" % kLongLivedTreeDepth + long_lived_tree = Node() + populate(kLongLivedTreeDepth, long_lived_tree) + + # Create long-lived array, filling half of it + if debug: + print " Creating a long-lived array of %d doubles" % kArraySize + array = [0.0] * kArraySize + i = 1 + while i < kArraySize/2: + array[i] = 1.0/i + i += 1 + print_diagnostics() - if threads: - time_parallel_constructions(depths, threads) - else: - time_constructions(depths) + if threads: + time_parallel_constructions(depths, threads, debug) + else: + time_constructions(depths, debug) - if long_lived_tree is None or array[1024] != 1.0/1024: - raise Failed + if long_lived_tree is None or array[1024] != 1.0/1024: + raise Failed - t_finish = time.time() - print_diagnostics() - print "Completed in %f ms." % ((t_finish-t_start)*1000.) + t_finish = time.time() + print_diagnostics() + if debug: + print "Completed in %f ms." % ((t_finish-t_start)*1000.) + times.append(t_finish - t_start) + return times class Failed(Exception): pass @@ -170,35 +183,26 @@ return 2 def entry_point(argv): - depths = DEFAULT_DEPTHS - threads = 0 - repeatcount = 1 - for arg in argv[1:]: - if arg.startswith('--threads='): - arg = arg[len('--threads='):] - if not ENABLE_THREADS: - print "threads disabled (they cannot be translated)" - return 1 - try: - threads = int(arg) - except ValueError: - return argerror() - elif arg.startswith('--depths='): - arg = arg[len('--depths='):].split(',') - try: - depths = [int(s) for s in arg] - except ValueError: - return argerror() - else: - try: - repeatcount = int(arg) - except ValueError: - return argerror() - for i in range(repeatcount): - main(depths, threads) - return 0 + import optparse + import util + def parse_depths(option, opt_str, value, parser): + parser.values.depths = [v for v in value.split(',') if v] + + parser = optparse.OptionParser( + usage="%prog [options]", + description="Test the performance of the Telco decimal benchmark") + util.add_standard_options_to(parser) + parser.add_option('--threads', default=0, action="store", + help="provide number of threads (default 1)") + parser.add_option('--depths', default=DEFAULT_DEPTHS, type="string", + action="callback", callback=parse_depths, + help='tree depths') + parser.add_option('--debug', default=False, action='store_true', + help="enable debugging") + options, args = parser.parse_args(argv) + util.run_benchmark(options, options.num_runs, main, + options.depths, options.threads, options.debug) if __name__ == '__main__': - import sys - sys.exit(entry_point(sys.argv)) + entry_point(sys.argv[1:]) From fijal at codespeak.net Fri Jan 22 00:33:11 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 00:33:11 +0100 (CET) Subject: [pypy-svn] r70763 - pypy/branch/direct-assembler-call/pypy/jit/metainterp/test Message-ID: <20100121233311.5EA8E16802A@codespeak.net> Author: fijal Date: Fri Jan 22 00:33:10 2010 New Revision: 70763 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Log: add a passing test. At least we test certain path of code Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Fri Jan 22 00:33:10 2010 @@ -1,5 +1,5 @@ import py -from pypy.rlib.jit import JitDriver, we_are_jitted, OPTIMIZER_SIMPLE +from pypy.rlib.jit import JitDriver, we_are_jitted, OPTIMIZER_SIMPLE, hint from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin from pypy.jit.metainterp.policy import StopAtXPolicy from pypy.rpython.annlowlevel import hlstr @@ -820,6 +820,45 @@ policy=StopAtXPolicy(change)) assert res == main(0) + def test_directly_call_assembler_virtualizable_with_array(self): + myjitdriver = JitDriver(greens = ['codeno'], reds = ['n', 'frame', 'x'], + virtualizables = ['frame'], + can_inline = lambda codeno : False) + + class Frame(object): + _virtualizable2_ = ['l[*]', 's'] + + def __init__(self, l, s): + self = hint(self, access_directly=True, + fresh_virtualizable=True) + self.l = l + self.s = s + + def main(codeno, n, a): + frame = Frame([a, a+1, a+2, a+3], 0) + return f(codeno, n, a, frame) + + def f(codeno, n, a, frame): + x = 0 + while n > 0: + myjitdriver.can_enter_jit(codeno=codeno, frame=frame, n=n, x=x) + myjitdriver.jit_merge_point(codeno=codeno, frame=frame, n=n, + x=x) + frame.s = hint(frame.s, promote=True) + n -= 1 + x += frame.l[frame.s] + frame.s += 1 + if codeno == 0: + subframe = Frame([n, n+1, n+2, n+3], 0) + x += f(1, 10, 1, subframe) + x += frame.l[frame.s] + x += len(frame.l) + frame.s -= 1 + return x + + res = self.meta_interp(main, [0, 10, 1], listops=True, inline=True) + assert res == main(0, 10, 1) + class TestLLtype(RecursiveTests, LLJitMixin): pass From fijal at codespeak.net Fri Jan 22 01:25:18 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 01:25:18 +0100 (CET) Subject: [pypy-svn] r70764 - pypy/branch/direct-assembler-call/pypy/jit/backend/x86 Message-ID: <20100122002518.286FC16802D@codespeak.net> Author: fijal Date: Fri Jan 22 01:25:17 2010 New Revision: 70764 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py Log: Seems that we're a bit out of luck in places :( I cannot possible imagine how the virtualizable might not already be on the stack, however, if this is true this will crash something. Since I have no clue, I can't test it a bit, maybe deeper thinking is required. Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/regalloc.py Fri Jan 22 01:25:17 2010 @@ -645,6 +645,7 @@ size = portal_calldescr.get_result_size(self.translate_support_code) vable_index = self.assembler.cpu.index_of_virtualizable if vable_index != -1: + self.rm._sync_var(op.args[vable_index]) vable = self.fm.loc(op.args[vable_index], 1) else: vable = imm(0) From benjamin at codespeak.net Fri Jan 22 02:43:59 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 22 Jan 2010 02:43:59 +0100 (CET) Subject: [pypy-svn] r70765 - in pypy/trunk/pypy/objspace: std test Message-ID: <20100122014359.4181816802D@codespeak.net> Author: benjamin Date: Fri Jan 22 02:43:58 2010 New Revision: 70765 Modified: pypy/trunk/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/test/test_descriptor.py Log: allow __get__ to raise an AttributeError triggering the use of __getattr__ Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Fri Jan 22 02:43:58 2010 @@ -656,7 +656,14 @@ return w_value w_get = self.lookup(w_descr, "__get__") if w_get is not None: - return self.get_and_call_function(w_get, w_descr, w_obj, w_type) + # __get__ is allowed to raise an AttributeError to trigger use + # of __getattr__. + try: + return self.get_and_call_function(w_get, w_descr, w_obj, + w_type) + except OperationError, e: + if not e.match(self, self.w_AttributeError): + raise w_value = w_obj.getdictvalue(self, name) if w_value is not None: return w_value Modified: pypy/trunk/pypy/objspace/test/test_descriptor.py ============================================================================== --- pypy/trunk/pypy/objspace/test/test_descriptor.py (original) +++ pypy/trunk/pypy/objspace/test/test_descriptor.py Fri Jan 22 02:43:58 2010 @@ -37,7 +37,6 @@ x.a = 42 assert x.a == 42 - @py.test.mark.xfail def test_failing_get(self): # when __get__() raises AttributeError, # __getattr__ is called... From fijal at codespeak.net Fri Jan 22 10:42:00 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 10:42:00 +0100 (CET) Subject: [pypy-svn] r70767 - pypy/branch/direct-assembler-call/pypy/jit/backend/x86 Message-ID: <20100122094200.AA87E168041@codespeak.net> Author: fijal Date: Fri Jan 22 10:42:00 2010 New Revision: 70767 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Log: Add a harmless assert Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Fri Jan 22 10:42:00 2010 @@ -1264,6 +1264,7 @@ self.mc.MOV(mem(ebp, FORCE_INDEX_OFS), imm(fail_index)) descr = op.descr assert isinstance(descr, LoopToken) + assert len(arglocs) - 2 == len(descr._x86_arglocs[0]) self._emit_call(rel32(descr._x86_direct_bootstrap_code), arglocs, 2, tmp=eax) self._emit_call(rel32(self.assembler_helper_adr), [eax, arglocs[1]], 0, From fijal at codespeak.net Fri Jan 22 11:24:31 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 11:24:31 +0100 (CET) Subject: [pypy-svn] r70768 - pypy/branch/direct-assembler-call/pypy/jit/backend/x86 Message-ID: <20100122102431.BEB5F168041@codespeak.net> Author: fijal Date: Fri Jan 22 11:24:31 2010 New Revision: 70768 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Log: Leave a comment about a possible performance improvement Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Fri Jan 22 11:24:31 2010 @@ -263,6 +263,8 @@ return self._patchable_stackadjust() def _assemble_bootstrap_direct_call(self, arglocs, jmpadr, stackdepth): + # XXX pushing ebx esi and edi is a bit pointless, since we store + # all regsiters anyway, for the case of guard_not_forced # XXX this can be improved greatly. Right now it'll behave like # a normal call nonfloatlocs, floatlocs = arglocs From fijal at codespeak.net Fri Jan 22 12:06:24 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 12:06:24 +0100 (CET) Subject: [pypy-svn] r70769 - pypy/branch/direct-assembler-call/pypy/jit/metainterp Message-ID: <20100122110624.A9DA6168041@codespeak.net> Author: fijal Date: Fri Jan 22 12:06:23 2010 New Revision: 70769 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Log: yet another harmless assertion Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Fri Jan 22 12:06:23 2010 @@ -676,11 +676,14 @@ call_position = len(self.metainterp.history.operations) res = self.do_residual_call(varargs, descr=calldescr, exc=True) # XXX fix the call position, + found = False while True: op = self.metainterp.history.operations[call_position] if op.opnum == rop.CALL or op.opnum == rop.CALL_MAY_FORCE: + found = True break call_position += 1 + assert found # if token is not None: # this will substitute the residual call with assembler call From fijal at codespeak.net Fri Jan 22 13:22:42 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 13:22:42 +0100 (CET) Subject: [pypy-svn] r70770 - pypy/branch/direct-assembler-call/pypy/jit/metainterp Message-ID: <20100122122242.81777168045@codespeak.net> Author: fijal Date: Fri Jan 22 13:22:41 2010 New Revision: 70770 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Log: argh. doing stuff on history when blackholing is not the smartes idea ever. Test pending Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Fri Jan 22 13:22:41 2010 @@ -675,17 +675,17 @@ if token is not None: call_position = len(self.metainterp.history.operations) res = self.do_residual_call(varargs, descr=calldescr, exc=True) - # XXX fix the call position, - found = False - while True: - op = self.metainterp.history.operations[call_position] - if op.opnum == rop.CALL or op.opnum == rop.CALL_MAY_FORCE: - found = True - break - call_position += 1 - assert found - # if token is not None: + # XXX fix the call position, + found = False + while True: + op = self.metainterp.history.operations[call_position] + if op.opnum == rop.CALL or op.opnum == rop.CALL_MAY_FORCE: + found = True + break + call_position += 1 + assert found + # # this will substitute the residual call with assembler call self.metainterp.direct_assembler_call(varargs, token, call_position) return res From fijal at codespeak.net Fri Jan 22 13:26:01 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 13:26:01 +0100 (CET) Subject: [pypy-svn] r70771 - pypy/branch/direct-assembler-call/pypy/jit/metainterp/test Message-ID: <20100122122601.6884D168045@codespeak.net> Author: fijal Date: Fri Jan 22 13:26:01 2010 New Revision: 70771 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_compile.py Log: fix the test Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_compile.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_compile.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_compile.py Fri Jan 22 13:26:01 2010 @@ -77,7 +77,7 @@ metainterp = FakeMetaInterp() metainterp.staticdata = staticdata metainterp.cpu = cpu - metainterp.history = History(metainterp.cpu) + metainterp.history = History() metainterp.history.operations = loop.operations[:] metainterp.history.inputargs = loop.inputargs[:] # @@ -94,7 +94,7 @@ metainterp = FakeMetaInterp() metainterp.staticdata = staticdata metainterp.cpu = cpu - metainterp.history = History(metainterp.cpu) + metainterp.history = History() metainterp.history.operations = loop.operations[:] metainterp.history.inputargs = loop.inputargs[:] # From fijal at codespeak.net Fri Jan 22 13:28:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 13:28:56 +0100 (CET) Subject: [pypy-svn] r70772 - pypy/branch/direct-assembler-call/pypy/jit/metainterp/test Message-ID: <20100122122856.51356168042@codespeak.net> Author: fijal Date: Fri Jan 22 13:28:55 2010 New Revision: 70772 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_pyjitpl.py Log: Fix the test Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_pyjitpl.py Fri Jan 22 13:28:55 2010 @@ -89,7 +89,7 @@ assert box.value == referencebox.value return True metainterp = pyjitpl.MetaInterp(FakeStaticData()) - metainterp.history = History(None) + metainterp.history = History() b1 = BoxInt(1) b2 = BoxInt(2) c3 = ConstInt(3) From fijal at codespeak.net Fri Jan 22 13:32:48 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 13:32:48 +0100 (CET) Subject: [pypy-svn] r70773 - pypy/branch/direct-assembler-call/pypy/jit/metainterp/test Message-ID: <20100122123248.88FDD168045@codespeak.net> Author: fijal Date: Fri Jan 22 13:32:48 2010 New Revision: 70773 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmspot.py Log: fix the test Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmspot.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmspot.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_warmspot.py Fri Jan 22 13:32:48 2010 @@ -352,11 +352,11 @@ def test_call_helper(self): from pypy.rpython.llinterp import LLException - assert self.desc.assembler_call_helper(0) == 3 - assert self.desc.assembler_call_helper(1) == 10 - assert self.desc.assembler_call_helper(2) == 10 + assert self.desc.assembler_call_helper(0, 0) == 3 + assert self.desc.assembler_call_helper(1, 0) == 10 + assert self.desc.assembler_call_helper(2, 0) == 10 try: - self.desc.assembler_call_helper(3) + self.desc.assembler_call_helper(3, 0) except LLException, lle: assert lle[0] == self.exc_vtable else: From fijal at codespeak.net Fri Jan 22 13:39:50 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 13:39:50 +0100 (CET) Subject: [pypy-svn] r70774 - pypy/branch/direct-assembler-call/pypy/jit/metainterp/test Message-ID: <20100122123950.E7100168045@codespeak.net> Author: fijal Date: Fri Jan 22 13:39:50 2010 New Revision: 70774 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_basic.py Log: For some CPUs (like x86) we need to have at least None as assembler_helper_ptr Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_basic.py Fri Jan 22 13:39:50 2010 @@ -22,6 +22,7 @@ stats = history.Stats() cpu = CPUClass(rtyper, stats, None, False) + cpu.assembler_helper_ptr = None graphs = rtyper.annotator.translator.graphs opt = history.Options(listops=listops) metainterp_sd = pyjitpl.MetaInterpStaticData(graphs[0], cpu, stats, opt) From fijal at codespeak.net Fri Jan 22 14:05:03 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 14:05:03 +0100 (CET) Subject: [pypy-svn] r70775 - in pypy/branch/direct-assembler-call/pypy/jit: backend/x86 backend/x86/test metainterp/test Message-ID: <20100122130503.84262168042@codespeak.net> Author: fijal Date: Fri Jan 22 14:05:03 2010 New Revision: 70775 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_runner.py pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_ztranslation.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_basic.py Log: fix a variety of tests Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Fri Jan 22 14:05:03 2010 @@ -120,10 +120,13 @@ ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode() self.malloc_unicode_func_addr = rffi.cast(lltype.Signed, ll_new_unicode) - if self.cpu.assembler_helper_ptr: + if we_are_translated(): self.assembler_helper_adr = self.cpu.cast_ptr_to_int( self.cpu.assembler_helper_ptr) - + else: + if getattr(self.cpu, 'assembler_helper_ptr', None): + self.assembler_helper_adr = self.cpu.cast_ptr_to_int( + self.cpu.assembler_helper_ptr) # done # we generate the loop body in 'mc' Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_runner.py Fri Jan 22 14:05:03 2010 @@ -27,7 +27,6 @@ def setup_method(self, meth): self.cpu = CPU(rtyper=None, stats=FakeStats()) - self.cpu.assembler_helper_ptr = None def test_execute_ptr_operation(self): cpu = self.cpu @@ -73,45 +72,41 @@ func = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)(f) addr = ctypes.cast(func, ctypes.c_void_p).value - try: - saved_addr = self.cpu.assembler.malloc_func_addr - self.cpu.assembler.malloc_func_addr = addr - ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] - - res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') - assert allocs[0] == 7 + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 7 - - # ------------------------------------------------------------ - - res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref') - assert allocs[0] == 7 + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 7 - - # ------------------------------------------------------------ - - TP = lltype.GcArray(lltype.Signed) - ofs = symbolic.get_field_token(TP, 'length', False)[0] - descr = self.cpu.arraydescrof(TP) - - res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], - 'ref', descr) - assert allocs[0] == 10*WORD + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 10 - - # ------------------------------------------------------------ - - res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], - 'ref', descr) - assert allocs[0] == 10*WORD + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 10 - - finally: - self.cpu.assembler.malloc_func_addr = saved_addr + self.cpu.assembler.make_sure_mc_exists() + self.cpu.assembler.malloc_func_addr = addr + ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] + + res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') + assert allocs[0] == 7 + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 7 + + # ------------------------------------------------------------ + + res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref') + assert allocs[0] == 7 + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 7 + + # ------------------------------------------------------------ + + TP = lltype.GcArray(lltype.Signed) + ofs = symbolic.get_field_token(TP, 'length', False)[0] + descr = self.cpu.arraydescrof(TP) + + res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], + 'ref', descr) + assert allocs[0] == 10*WORD + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 10 + + # ------------------------------------------------------------ + + res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], + 'ref', descr) + assert allocs[0] == 10*WORD + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 10 def test_stringitems(self): from pypy.rpython.lltypesystem.rstr import STR @@ -318,9 +313,9 @@ class TestX86OverflowMC(TestX86): - def setup_class(cls): - cls.cpu = CPU(rtyper=None, stats=FakeStats()) - cls.cpu.assembler.mc_size = 1024 + def setup_method(self, meth): + self.cpu = CPU(rtyper=None, stats=FakeStats()) + self.cpu.assembler.mc_size = 1024 def test_overflow_mc(self): ops = [] @@ -333,6 +328,7 @@ ops.append(ResOperation(rop.FINISH, [v], None, descr=BasicFailDescr())) looptoken = LoopToken() + self.cpu.assembler.make_sure_mc_exists() old_mc_mc = self.cpu.assembler.mc._mc self.cpu.compile_loop([base_v], ops, looptoken) assert self.cpu.assembler.mc._mc != old_mc_mc # overflowed Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_ztranslation.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_ztranslation.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/test/test_ztranslation.py Fri Jan 22 14:05:03 2010 @@ -4,6 +4,7 @@ from pypy.jit.metainterp.jitprof import Profiler from pypy.jit.backend.x86.runner import CPU386 from pypy.jit.backend.test.support import CCompiledMixin +from pypy.jit.metainterp.policy import StopAtXPolicy class TestTranslationX86(CCompiledMixin): CPUClass = CPU386 @@ -94,3 +95,52 @@ return total * 10 res = self.meta_interp(main, [40]) assert res == main(40) + + def test_direct_assembler_call_translates(self): + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + class SomewhereElse(object): + pass + + somewhere_else = SomewhereElse() + + def change(newthing): + somewhere_else.frame.thing = newthing + + def main(codeno): + frame = Frame() + somewhere_else.frame = frame + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + elif frame.thing.val > 40: + change(Thing(13)) + nextval = 13 + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True, + policy=StopAtXPolicy(change)) + assert res == main(0) + Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_basic.py Fri Jan 22 14:05:03 2010 @@ -22,7 +22,6 @@ stats = history.Stats() cpu = CPUClass(rtyper, stats, None, False) - cpu.assembler_helper_ptr = None graphs = rtyper.annotator.translator.graphs opt = history.Options(listops=listops) metainterp_sd = pyjitpl.MetaInterpStaticData(graphs[0], cpu, stats, opt) From fijal at codespeak.net Fri Jan 22 15:07:00 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 15:07:00 +0100 (CET) Subject: [pypy-svn] r70776 - pypy/branch/direct-assembler-call/pypy/jit/metainterp/test Message-ID: <20100122140700.8A892168047@codespeak.net> Author: fijal Date: Fri Jan 22 15:07:00 2010 New Revision: 70776 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Log: Mention tests that I would like to have written Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Fri Jan 22 15:07:00 2010 @@ -859,6 +859,36 @@ res = self.meta_interp(main, [0, 10, 1], listops=True, inline=True) assert res == main(0, 10, 1) + # def test_recursive_call_while_blackholing(self): + # driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], + # get_printable_location = lambda codeno : str(codeno), + # can_inline = lambda codeno : False) + + # def f(codeno, k): + # i = 0 + # while i < 10: + # driver.can_enter_jit(codeno=codeno, i=i, k=k) + # driver.jit_merge_point(codeno=codeno, i=i, k=k) + # if codeno == 0: + # k += indirection(1, k) + # if codeno == 1 and k > 70 or codeno == 0: + # indirection(2, k) + # i += 1 + # if codeno != 2: + # k += 1 + # return k + + # def indirection(a, b): + # return f(a, b) + + # res = self.meta_interp(f, [0, 0], inline=True) + # assert res == f(0, 0) + + # There are two tests which I fail to write. + # 1. what happens if we call recursive_call while blackholing + # 2. what happens if in opimpl_recursive_call we switch to blackhole + # while doing do_residual_call + class TestLLtype(RecursiveTests, LLJitMixin): pass From fijal at codespeak.net Fri Jan 22 16:18:03 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 16:18:03 +0100 (CET) Subject: [pypy-svn] r70777 - in pypy/branch/direct-assembler-call/pypy/jit/metainterp: . test Message-ID: <20100122151803.C5817168021@codespeak.net> Author: fijal Date: Fri Jan 22 16:18:03 2010 New Revision: 70777 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Log: note down a test that I fail to write as a corner-case (it should not happen in practice). Write a test and fix a real issue. Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Fri Jan 22 16:18:03 2010 @@ -664,7 +664,7 @@ def opimpl_recursive_call(self, calldescr, varargs): warmrunnerstate = self.metainterp.staticdata.state token = None - if warmrunnerstate.inlining: + if not self.metainterp.is_blackholing() and warmrunnerstate.inlining: num_green_args = self.metainterp.staticdata.num_green_args portal_code = self.metainterp.staticdata.portal_code greenkey = varargs[1:num_green_args + 1] @@ -675,7 +675,7 @@ if token is not None: call_position = len(self.metainterp.history.operations) res = self.do_residual_call(varargs, descr=calldescr, exc=True) - if token is not None: + if not self.metainterp.is_blackholing() and token is not None: # XXX fix the call position, found = False while True: Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Fri Jan 22 16:18:03 2010 @@ -859,35 +859,62 @@ res = self.meta_interp(main, [0, 10, 1], listops=True, inline=True) assert res == main(0, 10, 1) - # def test_recursive_call_while_blackholing(self): - # driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], - # get_printable_location = lambda codeno : str(codeno), - # can_inline = lambda codeno : False) - - # def f(codeno, k): - # i = 0 - # while i < 10: - # driver.can_enter_jit(codeno=codeno, i=i, k=k) - # driver.jit_merge_point(codeno=codeno, i=i, k=k) - # if codeno == 0: - # k += indirection(1, k) - # if codeno == 1 and k > 70 or codeno == 0: - # indirection(2, k) - # i += 1 - # if codeno != 2: - # k += 1 - # return k - - # def indirection(a, b): - # return f(a, b) - - # res = self.meta_interp(f, [0, 0], inline=True) - # assert res == f(0, 0) - - # There are two tests which I fail to write. - # 1. what happens if we call recursive_call while blackholing - # 2. what happens if in opimpl_recursive_call we switch to blackhole - # while doing do_residual_call + def test_directly_call_assembler_virtualizable_force_blackhole(self): + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + class SomewhereElse(object): + pass + + somewhere_else = SomewhereElse() + + def change(newthing, arg): + print arg + if arg > 30: + somewhere_else.frame.thing = newthing + arg = 13 + return arg + + def main(codeno): + frame = Frame() + somewhere_else.frame = frame + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + else: + nextval = change(Thing(13), frame.thing.val) + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True, + policy=StopAtXPolicy(change)) + assert res == main(0) + + + # There is a test which I fail to write. + # * what happens if we call recursive_call while blackholing + # this seems to be completely corner case and not really happening + # in the wild class TestLLtype(RecursiveTests, LLJitMixin): pass From fijal at codespeak.net Fri Jan 22 17:14:46 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 17:14:46 +0100 (CET) Subject: [pypy-svn] r70779 - pypy/branch/direct-assembler-call/pypy/jit/backend/x86 Message-ID: <20100122161446.7C545168023@codespeak.net> Author: fijal Date: Fri Jan 22 17:14:46 2010 New Revision: 70779 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Log: Try to make sure we don't make a bootstrap code on the edge of machine block. Seems to be causing trouble every now and then. Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Fri Jan 22 17:14:46 2010 @@ -183,6 +183,11 @@ self._patch_stackadjust(adr_stackadjust, frame_depth+param_depth) looptoken._x86_frame_depth = frame_depth looptoken._x86_param_depth = param_depth + # we need to make sure here that we don't overload an mc badly. + # a safe estimate is that we need at most 16 bytes per arg + needed_mem = len(arglocs[0]) * 16 + if needed_mem < self.mc.bytes_free(): + self.mc.make_new_mc() looptoken._x86_direct_bootstrap_code = self.mc.tell() self._assemble_bootstrap_direct_call(arglocs, curadr, frame_depth+param_depth) From fijal at codespeak.net Fri Jan 22 17:27:17 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 22 Jan 2010 17:27:17 +0100 (CET) Subject: [pypy-svn] r70780 - pypy/branch/direct-assembler-call/pypy/jit/backend/x86 Message-ID: <20100122162717.079CC168023@codespeak.net> Author: fijal Date: Fri Jan 22 17:27:17 2010 New Revision: 70780 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Log: Still thinking about how to test it ... Of course reverse the inequality. Also add one about bootstrap code (might this be a source of strange random segfaults?) Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Fri Jan 22 17:27:17 2010 @@ -173,6 +173,9 @@ regalloc = RegAlloc(self, self.cpu.translate_support_code) arglocs = regalloc.prepare_loop(inputargs, operations, looptoken) looptoken._x86_arglocs = arglocs + needed_mem = len(arglocs[0]) * 16 + 16 + if needed_mem >= self.mc.bytes_free(): + self.mc.make_new_mc() looptoken._x86_bootstrap_code = self.mc.tell() adr_stackadjust = self._assemble_bootstrap_code(inputargs, arglocs) curadr = self.mc.tell() @@ -185,8 +188,8 @@ looptoken._x86_param_depth = param_depth # we need to make sure here that we don't overload an mc badly. # a safe estimate is that we need at most 16 bytes per arg - needed_mem = len(arglocs[0]) * 16 - if needed_mem < self.mc.bytes_free(): + needed_mem = len(arglocs[0]) * 16 + 16 + if needed_mem >= self.mc.bytes_free(): self.mc.make_new_mc() looptoken._x86_direct_bootstrap_code = self.mc.tell() self._assemble_bootstrap_direct_call(arglocs, curadr, From arigo at codespeak.net Fri Jan 22 17:59:54 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 22 Jan 2010 17:59:54 +0100 (CET) Subject: [pypy-svn] r70782 - in pypy/branch/c-traceback/pypy/translator: cli jvm Message-ID: <20100122165954.91AB7168023@codespeak.net> Author: arigo Date: Fri Jan 22 17:59:53 2010 New Revision: 70782 Modified: pypy/branch/c-traceback/pypy/translator/cli/opcodes.py pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py Log: Add missing 5th operation. Modified: pypy/branch/c-traceback/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/cli/opcodes.py (original) +++ pypy/branch/c-traceback/pypy/translator/cli/opcodes.py Fri Jan 22 17:59:53 2010 @@ -79,8 +79,9 @@ 'debug_assert': Ignore, 'debug_start_traceback': Ignore, 'debug_record_traceback': Ignore, - 'debug_print_traceback': Ignore, 'debug_catch_exception': Ignore, + 'debug_reraise_traceback': Ignore, + 'debug_print_traceback': Ignore, 'debug_print': [DebugPrint], 'debug_start': [PushAllArgs, 'call void [pypylib]pypy.runtime.DebugPrint::DEBUG_START(string)'], 'debug_stop': [PushAllArgs, 'call void [pypylib]pypy.runtime.DebugPrint::DEBUG_STOP(string)'], Modified: pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py ============================================================================== --- pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py (original) +++ pypy/branch/c-traceback/pypy/translator/jvm/opcodes.py Fri Jan 22 17:59:53 2010 @@ -103,8 +103,9 @@ 'debug_assert': [], # TODO: implement? 'debug_start_traceback': Ignore, 'debug_record_traceback': Ignore, - 'debug_print_traceback': Ignore, 'debug_catch_exception': Ignore, + 'debug_reraise_traceback': Ignore, + 'debug_print_traceback': Ignore, # __________ numeric operations __________ From arigo at codespeak.net Fri Jan 22 18:09:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 22 Jan 2010 18:09:33 +0100 (CET) Subject: [pypy-svn] r70784 - in pypy/trunk/pypy: jit/metainterp rlib rpython rpython/lltypesystem translator translator/c translator/c/src translator/c/test translator/cli translator/jvm translator/test Message-ID: <20100122170933.4FD2E168021@codespeak.net> Author: arigo Date: Fri Jan 22 18:09:32 2010 New Revision: 70784 Added: pypy/trunk/pypy/translator/c/src/debug_print.h - copied unchanged from r70783, pypy/branch/c-traceback/pypy/translator/c/src/debug_print.h pypy/trunk/pypy/translator/c/src/debug_traceback.h - copied unchanged from r70783, pypy/branch/c-traceback/pypy/translator/c/src/debug_traceback.h Removed: pypy/trunk/pypy/translator/c/src/debug.h pypy/trunk/pypy/translator/c/src/debuginfo.h Modified: pypy/trunk/pypy/jit/metainterp/history.py pypy/trunk/pypy/jit/metainterp/warmspot.py pypy/trunk/pypy/rlib/debug.py pypy/trunk/pypy/rpython/llinterp.py pypy/trunk/pypy/rpython/lltypesystem/lloperation.py pypy/trunk/pypy/translator/c/funcgen.py pypy/trunk/pypy/translator/c/genc.py pypy/trunk/pypy/translator/c/src/g_include.h pypy/trunk/pypy/translator/c/src/main.h pypy/trunk/pypy/translator/c/test/test_standalone.py pypy/trunk/pypy/translator/cli/opcodes.py pypy/trunk/pypy/translator/exceptiontransform.py pypy/trunk/pypy/translator/jvm/opcodes.py pypy/trunk/pypy/translator/test/test_exceptiontransform.py Log: Merge branch/c-traceback. It adds to all crashing RPython programs a traceback capability that should let it display where the RPython exception comes from. (Only implemented in the C backend; I except the oo backends to be already able to give such tracebacks.) Modified: pypy/trunk/pypy/jit/metainterp/history.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/history.py (original) +++ pypy/trunk/pypy/jit/metainterp/history.py Fri Jan 22 18:09:32 2010 @@ -929,10 +929,6 @@ loops.append(loop) display_loops(loops, errmsg, extraloops) - -class CrashInJIT(Exception): - pass - # ---------------------------------------------------------------- class Options: Modified: pypy/trunk/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/warmspot.py (original) +++ pypy/trunk/pypy/jit/metainterp/warmspot.py Fri Jan 22 18:09:32 2010 @@ -11,7 +11,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.rarithmetic import r_uint, intmask -from pypy.rlib.debug import debug_print +from pypy.rlib.debug import debug_print, fatalerror from pypy.rpython.lltypesystem.lloperation import llop from pypy.translator.simplify import get_funcobj, get_functype from pypy.translator.unsimplify import call_final_function @@ -344,9 +344,7 @@ if sys.stdout == sys.__stdout__: import pdb; pdb.post_mortem(sys.exc_info()[2]) raise - debug_print('~~~ Crash in JIT!') - debug_print('~~~ %s' % (e,)) - raise history.CrashInJIT("crash in JIT") + fatalerror('~~~ Crash in JIT! %s' % (e,), traceback=True) crash_in_jit._dont_inline_ = True if self.translator.rtyper.type_system.name == 'lltypesystem': Modified: pypy/trunk/pypy/rlib/debug.py ============================================================================== --- pypy/trunk/pypy/rlib/debug.py (original) +++ pypy/trunk/pypy/rlib/debug.py Fri Jan 22 18:09:32 2010 @@ -19,6 +19,14 @@ hop.exception_cannot_occur() hop.genop('debug_assert', vlist) +def fatalerror(msg, traceback=False): + from pypy.rpython.lltypesystem import lltype + from pypy.rpython.lltypesystem.lloperation import llop + if traceback: + llop.debug_print_traceback(lltype.Void) + llop.debug_fatalerror(lltype.Void, msg) +fatalerror._dont_inline_ = True + class DebugLog(list): def debug_print(self, *args): Modified: pypy/trunk/pypy/rpython/llinterp.py ============================================================================== --- pypy/trunk/pypy/rpython/llinterp.py (original) +++ pypy/trunk/pypy/rpython/llinterp.py Fri Jan 22 18:09:32 2010 @@ -543,6 +543,21 @@ def op_debug_llinterpcall(self, pythonfunction, *args_ll): return pythonfunction(*args_ll) + def op_debug_start_traceback(self, *args): + pass # xxx write debugging code here? + + def op_debug_reraise_traceback(self, *args): + pass # xxx write debugging code here? + + def op_debug_record_traceback(self, *args): + pass # xxx write debugging code here? + + def op_debug_print_traceback(self, *args): + pass # xxx write debugging code here? + + def op_debug_catch_exception(self, *args): + pass # xxx write debugging code here? + def op_jit_marker(self, *args): pass Modified: pypy/trunk/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/lloperation.py Fri Jan 22 18:09:32 2010 @@ -536,6 +536,11 @@ 'debug_fatalerror': LLOp(), 'debug_llinterpcall': LLOp(), # Python func call 'res=arg[0](*arg[1:])' # in backends, abort() or whatever is fine + 'debug_start_traceback': LLOp(), + 'debug_record_traceback': LLOp(), + 'debug_catch_exception': LLOp(), + 'debug_reraise_traceback': LLOp(), + 'debug_print_traceback': LLOp(), # __________ instrumentation _________ 'instrument_count': LLOp(), Modified: pypy/trunk/pypy/translator/c/funcgen.py ============================================================================== --- pypy/trunk/pypy/translator/c/funcgen.py (original) +++ pypy/trunk/pypy/translator/c/funcgen.py Fri Jan 22 18:09:32 2010 @@ -817,5 +817,26 @@ self.expr(op.args[1]), self.expr(op.args[2])) + def getdebugfunctionname(self): + name = self.functionname + if not name: + return "?" + if name.startswith('pypy_g_'): + name = name[7:] + return name + + def OP_DEBUG_RECORD_TRACEBACK(self, op): + #if self.functionname is None, we print "?" as the argument */ + return 'PYPY_DEBUG_RECORD_TRACEBACK("%s");' % ( + self.getdebugfunctionname(),) + + def OP_DEBUG_CATCH_EXCEPTION(self, op): + gottype = self.expr(op.args[0]) + exprs = [] + for c_limited_type in op.args[1:]: + exprs.append('%s == %s' % (gottype, self.expr(c_limited_type))) + return 'PYPY_DEBUG_CATCH_EXCEPTION("%s", %s, %s);' % ( + self.getdebugfunctionname(), gottype, ' || '.join(exprs)) + assert not USESLOTS or '__dict__' not in dir(FunctionCodeGenerator) Modified: pypy/trunk/pypy/translator/c/genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/genc.py (original) +++ pypy/trunk/pypy/translator/c/genc.py Fri Jan 22 18:09:32 2010 @@ -430,12 +430,16 @@ bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph()) - def cmdexec(self, args='', env=None, err=False): + def cmdexec(self, args='', env=None, err=False, expect_crash=False): assert self._compiled res = self.translator.platform.execute(self.executable_name, args, env=env) if res.returncode != 0: + if expect_crash: + return res.out, res.err raise Exception("Returned %d" % (res.returncode,)) + if expect_crash: + raise Exception("Program did not crash!") if err: return res.out, res.err return res.out @@ -711,6 +715,7 @@ print >> fc, '/*** Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' + print >> fc, '#define PYPY_FILE_NAME "%s"' % name print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' @@ -783,6 +788,7 @@ print >> f, '/***********************************************************/' print >> f, '/*** Implementations ***/' print >> f + print >> f, '#define PYPY_FILE_NAME "%s"' % os.path.basename(f.name) for line in preimplementationlines: print >> f, line print >> f, '#include "src/g_include.h"' Modified: pypy/trunk/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/g_include.h (original) +++ pypy/trunk/pypy/translator/c/src/g_include.h Fri Jan 22 18:09:32 2010 @@ -47,7 +47,8 @@ /*** modules ***/ #ifdef HAVE_RTYPER /* only if we have an RTyper */ # include "src/rtyper.h" -# include "src/debug.h" +# include "src/debug_print.h" +# include "src/debug_traceback.h" #ifndef AVR # include "src/ll_os.h" # include "src/ll_strtod.h" Modified: pypy/trunk/pypy/translator/c/src/main.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/main.h (original) +++ pypy/trunk/pypy/translator/c/src/main.h Fri Jan 22 18:09:32 2010 @@ -36,12 +36,8 @@ exitcode = STANDALONE_ENTRY_POINT(list); if (RPyExceptionOccurred()) { - /* fish for the exception type, at least */ -#ifndef AVR - fprintf(stderr, "Fatal RPython error: %s\n", - RPyFetchExceptionType()->ov_name->items); -#endif - abort(); + /* print the RPython traceback */ + pypy_debug_catch_fatal_exception(); } return exitcode; Modified: pypy/trunk/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_standalone.py (original) +++ pypy/trunk/pypy/translator/c/test/test_standalone.py Fri Jan 22 18:09:32 2010 @@ -10,6 +10,7 @@ from pypy.annotation.listdef import s_list_of_strings from pypy.tool.udir import udir from pypy.tool.autopath import pypydir +from pypy.conftest import option class StandaloneTests(object): @@ -21,8 +22,10 @@ t.buildrtyper().specialize() cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() + cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() + if option.view: + t.view() return t, cbuilder @@ -377,6 +380,186 @@ assert not err assert path.check(file=0) + def test_fatal_error(self): + def g(x): + if x == 1: + raise ValueError + else: + raise KeyError + def entry_point(argv): + if len(argv) < 3: + g(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: ValueError' + assert len(lines) >= 4 + l0, l1, l2 = lines[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) + # + out2, err2 = cbuilder.cmdexec("x", expect_crash=True) + assert out2.strip() == '' + lines2 = err2.strip().splitlines() + assert lines2[-1] == 'Fatal RPython error: KeyError' + l0, l1, l2 = lines2[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) + assert lines2[-2] != lines[-2] # different line number + assert lines2[-3] == lines[-3] # same line number + + def test_fatal_error_finally_1(self): + # a simple case of try:finally: + def g(x): + if x == 1: + raise KeyError + def h(x): + try: + g(x) + finally: + os.write(1, 'done.\n') + def entry_point(argv): + if len(argv) < 3: + h(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == 'done.' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: KeyError' + assert len(lines) >= 5 + l0, l1, l2, l3 = lines[-5:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in h', l2) + assert re.match(r' File "\w+.c", line \d+, in g', l3) + + def test_fatal_error_finally_2(self): + # a try:finally: in which we raise and catch another exception + def raiseme(x): + if x == 1: + raise ValueError + def raise_and_catch(x): + try: + raiseme(x) + except ValueError: + pass + def g(x): + if x == 1: + raise KeyError + def h(x): + try: + g(x) + finally: + raise_and_catch(x) + os.write(1, 'done.\n') + def entry_point(argv): + if len(argv) < 3: + h(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == 'done.' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: KeyError' + assert len(lines) >= 5 + l0, l1, l2, l3 = lines[-5:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in h', l2) + assert re.match(r' File "\w+.c", line \d+, in g', l3) + + def test_fatal_error_finally_3(self): + py.test.skip("not implemented: " + "a try:finally: in which we raise the *same* exception") + + def test_fatal_error_finally_4(self): + # a try:finally: in which we raise (and don't catch) an exception + def raiseme(x): + if x == 1: + raise ValueError + def g(x): + if x == 1: + raise KeyError + def h(x): + try: + g(x) + finally: + raiseme(x) + os.write(1, 'done.\n') + def entry_point(argv): + if len(argv) < 3: + h(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: ValueError' + assert len(lines) >= 5 + l0, l1, l2, l3 = lines[-5:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in h', l2) + assert re.match(r' File "\w+.c", line \d+, in raiseme', l3) + + def test_assertion_error(self): + def g(x): + assert x != 1 + def f(argv): + try: + g(len(argv)) + finally: + print 'done' + def entry_point(argv): + f(argv) + return 0 + t, cbuilder = self.compile(entry_point) + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: AssertionError' + assert len(lines) >= 4 + l0, l1, l2 = lines[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in f', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) + # The traceback stops at f() because it's the first function that + # captures the AssertionError, which makes the program abort. + + def test_ll_assert_error(self): + py.test.skip("implement later, maybe: tracebacks even with ll_assert") + def g(x): + ll_assert(x != 1, "foobar") + def f(argv): + try: + g(len(argv)) + finally: + print 'done' + def entry_point(argv): + f(argv) + return 0 + t, cbuilder = self.compile(entry_point) + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'PyPy assertion failed: foobar' + assert len(lines) >= 4 + l0, l1, l2 = lines[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in f', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) + # The traceback stops at f() because it's the first function that + # captures the AssertionError, which makes the program abort. + class TestMaemo(TestStandalone): def setup_class(cls): @@ -407,7 +590,7 @@ t.buildrtyper().specialize() # cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() + cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() # return t, cbuilder Modified: pypy/trunk/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/trunk/pypy/translator/cli/opcodes.py (original) +++ pypy/trunk/pypy/translator/cli/opcodes.py Fri Jan 22 18:09:32 2010 @@ -77,6 +77,11 @@ 'gc_set_max_heap_size': Ignore, 'resume_point': Ignore, 'debug_assert': Ignore, + 'debug_start_traceback': Ignore, + 'debug_record_traceback': Ignore, + 'debug_catch_exception': Ignore, + 'debug_reraise_traceback': Ignore, + 'debug_print_traceback': Ignore, 'debug_print': [DebugPrint], 'debug_start': [PushAllArgs, 'call void [pypylib]pypy.runtime.DebugPrint::DEBUG_START(string)'], 'debug_stop': [PushAllArgs, 'call void [pypylib]pypy.runtime.DebugPrint::DEBUG_STOP(string)'], Modified: pypy/trunk/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/trunk/pypy/translator/exceptiontransform.py (original) +++ pypy/trunk/pypy/translator/exceptiontransform.py Fri Jan 22 18:09:32 2010 @@ -3,11 +3,10 @@ from pypy.translator.unsimplify import insert_empty_block, split_block from pypy.translator.backendopt import canraise, inline, support, removenoops from pypy.objspace.flow.model import Block, Constant, Variable, Link, \ - c_last_exception, SpaceOperation, checkgraph, FunctionGraph + c_last_exception, SpaceOperation, checkgraph, FunctionGraph, mkentrymap from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem import lloperation -from pypy.rpython.lltypesystem.llmemory import NULL from pypy.rpython import rtyper from pypy.rpython import rclass from pypy.rpython.rmodel import inputconst @@ -16,6 +15,7 @@ from pypy.rlib.debug import ll_assert from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator +from pypy.tool.sourcetools import func_with_new_name PrimitiveErrorValue = {lltype.Signed: -1, lltype.Unsigned: r_uint(-1), @@ -26,7 +26,7 @@ lltype.Char: chr(255), lltype.UniChar: unichr(0xFFFF), # XXX is this always right? lltype.Bool: True, - llmemory.Address: NULL, + llmemory.Address: llmemory.NULL, lltype.Void: None} for TYPE in rffi.NUMBER_TYPES: @@ -45,6 +45,9 @@ def error_constant(T): return Constant(error_value(T), T) +def constant_value(llvalue): + return Constant(llvalue, lltype.typeOf(llvalue)) + class BaseExceptionTransformer(object): def __init__(self, translator): @@ -64,6 +67,10 @@ (n_i_error_ll_exc_type, n_i_error_ll_exc) = self.get_builtin_exception(NotImplementedError) + self.c_assertion_error_ll_exc_type = constant_value( + assertion_error_ll_exc_type) + self.c_n_i_error_ll_exc_type = constant_value(n_i_error_ll_exc_type) + def rpyexc_occured(): exc_type = exc_data.exc_type return bool(exc_type) @@ -80,10 +87,14 @@ def rpyexc_raise(etype, evalue): # assert(!RPyExceptionOccurred()); - ll_assert(etype != assertion_error_ll_exc_type, "AssertionError!") - ll_assert(etype != n_i_error_ll_exc_type, "NotImplementedError!") exc_data.exc_type = etype exc_data.exc_value = evalue + lloperation.llop.debug_start_traceback(lltype.Void, etype) + + def rpyexc_reraise(etype, evalue): + exc_data.exc_type = etype + exc_data.exc_value = evalue + lloperation.llop.debug_reraise_traceback(lltype.Void, etype) def rpyexc_fetch_exception(): evalue = rpyexc_fetch_value() @@ -92,7 +103,8 @@ def rpyexc_restore_exception(evalue): if evalue: - rpyexc_raise(rclass.ll_inst_type(evalue), evalue) + exc_data.exc_type = rclass.ll_inst_type(evalue) + exc_data.exc_value = evalue def rpyexc_raise_runtime_error(): rpyexc_raise(runtime_error_ll_exc_type, runtime_error_ll_exc) @@ -119,14 +131,21 @@ self.rpyexc_raise_ptr = self.build_func( "RPyRaiseException", - rpyexc_raise, + self.noinline(rpyexc_raise), + [self.lltype_of_exception_type, self.lltype_of_exception_value], + lltype.Void, + jitcallkind='rpyexc_raise') # for the JIT + + self.rpyexc_reraise_ptr = self.build_func( + "RPyReRaiseException", + rpyexc_reraise, [self.lltype_of_exception_type, self.lltype_of_exception_value], lltype.Void, jitcallkind='rpyexc_raise') # for the JIT self.rpyexc_raise_runtime_error_ptr = self.build_func( "RPyRaiseRuntimeError", - rpyexc_raise_runtime_error, + self.noinline(rpyexc_raise_runtime_error), [], lltype.Void) self.rpyexc_fetch_exception_ptr = self.build_func( @@ -136,7 +155,7 @@ self.rpyexc_restore_exception_ptr = self.build_func( "RPyRestoreException", - rpyexc_restore_exception, + self.noinline(rpyexc_restore_exception), [self.lltype_of_exception_value], lltype.Void) self.build_extra_funcs() @@ -144,6 +163,11 @@ self.mixlevelannotator.finish() self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping() + def noinline(self, fn): + fn = func_with_new_name(fn, fn.__name__) + fn._dont_inline_ = True + return fn + def build_func(self, name, fn, inputtypes, rettype, **kwds): l2a = annmodel.lltype_to_annotation graph = self.mixlevelannotator.getgraph(fn, map(l2a, inputtypes), l2a(rettype)) @@ -184,13 +208,18 @@ # collect the blocks before changing them n_need_exc_matching_blocks = 0 n_gen_exc_checks = 0 + # + entrymap = mkentrymap(graph) + if graph.exceptblock in entrymap: + for link in entrymap[graph.exceptblock]: + self.transform_jump_to_except_block(graph, entrymap, link) + # for block in list(graph.iterblocks()): self.replace_stack_unwind(block) self.replace_fetch_restore_operations(block) need_exc_matching, gen_exc_checks = self.transform_block(graph, block) n_need_exc_matching_blocks += need_exc_matching n_gen_exc_checks += gen_exc_checks - self.transform_except_block(graph, graph.exceptblock) cleanup_graph(graph) removenoops.remove_superfluous_keep_alive(graph) return n_need_exc_matching_blocks, n_gen_exc_checks @@ -268,18 +297,54 @@ self.insert_matching(lastblock, graph) return need_exc_matching, n_gen_exc_checks - def transform_except_block(self, graph, block): - # attach an except block -- let's hope that nobody uses it - graph.exceptblock = Block([Variable('etype'), # exception class - Variable('evalue')]) # exception value - graph.exceptblock.operations = () - graph.exceptblock.closeblock() - + def comes_from_last_exception(self, entrymap, link): + seen = {} + pending = [(link, link.args[1])] + while pending: + link, v = pending.pop() + if (link, v) in seen: + continue + seen[link, v] = True + if link.last_exc_value is not None and v is link.last_exc_value: + return True + block = link.prevblock + if block is None: + continue + for op in block.operations[::-1]: + if v is op.result: + if op.opname == 'cast_pointer': + v = op.args[0] + else: + break + for link in entrymap.get(block, ()): + for v1, v2 in zip(link.args, block.inputargs): + if v2 is v: + pending.append((link, v1)) + return False + + def transform_jump_to_except_block(self, graph, entrymap, link): + reraise = self.comes_from_last_exception(entrymap, link) result = Variable() result.concretetype = lltype.Void - block.operations = [SpaceOperation( - "direct_call", [self.rpyexc_raise_ptr] + block.inputargs, result)] - l = Link([error_constant(graph.returnblock.inputargs[0].concretetype)], graph.returnblock) + block = Block([copyvar(None, v) + for v in graph.exceptblock.inputargs]) + if reraise: + block.operations = [ + SpaceOperation("direct_call", + [self.rpyexc_reraise_ptr] + block.inputargs, + result), + ] + else: + block.operations = [ + SpaceOperation("direct_call", + [self.rpyexc_raise_ptr] + block.inputargs, + result), + SpaceOperation('debug_record_traceback', [], + varoftype(lltype.Void)), + ] + link.target = block + RETTYPE = graph.returnblock.inputargs[0].concretetype + l = Link([error_constant(RETTYPE)], graph.returnblock) block.recloseblock(l) def insert_matching(self, block, graph): @@ -328,6 +393,11 @@ llops = rtyper.LowLevelOpList(None) var_value = self.gen_getfield('exc_value', llops) var_type = self.gen_getfield('exc_type' , llops) + # + c_check1 = self.c_assertion_error_ll_exc_type + c_check2 = self.c_n_i_error_ll_exc_type + llops.genop('debug_catch_exception', [var_type, c_check1, c_check2]) + # self.gen_setfield('exc_value', self.c_null_evalue, llops) self.gen_setfield('exc_type', self.c_null_etype, llops) excblock.operations[:] = llops @@ -361,7 +431,12 @@ block.exitswitch = var_no_exc #exception occurred case + b = Block([]) + b.operations = [SpaceOperation('debug_record_traceback', [], + varoftype(lltype.Void))] l = Link([error_constant(returnblock.inputargs[0].concretetype)], returnblock) + b.closeblock(l) + l = Link([], b) l.exitcase = l.llexitcase = False #non-exception case Modified: pypy/trunk/pypy/translator/jvm/opcodes.py ============================================================================== --- pypy/trunk/pypy/translator/jvm/opcodes.py (original) +++ pypy/trunk/pypy/translator/jvm/opcodes.py Fri Jan 22 18:09:32 2010 @@ -101,6 +101,11 @@ 'jit_force_virtual': DoNothing, 'debug_assert': [], # TODO: implement? + 'debug_start_traceback': Ignore, + 'debug_record_traceback': Ignore, + 'debug_catch_exception': Ignore, + 'debug_reraise_traceback': Ignore, + 'debug_print_traceback': Ignore, # __________ numeric operations __________ Modified: pypy/trunk/pypy/translator/test/test_exceptiontransform.py ============================================================================== --- pypy/trunk/pypy/translator/test/test_exceptiontransform.py (original) +++ pypy/trunk/pypy/translator/test/test_exceptiontransform.py Fri Jan 22 18:09:32 2010 @@ -95,7 +95,7 @@ return 3 + x return 4 + x t, g = self.transform_func(foo, [int]) - assert len(list(g.iterblocks())) == 9 + assert len(list(g.iterblocks())) == 10 f = self.compile(foo, [int]) result = interpret(foo, [6]) assert result == 2 @@ -126,7 +126,7 @@ return 1 + x return 4 + x t, g = self.transform_func(foo, [int]) - assert len(list(g.iterblocks())) == 5 + assert len(list(g.iterblocks())) == 6 f = self.compile(foo, [int]) result = interpret(foo, [6]) assert result == 2 @@ -175,6 +175,34 @@ etrafo.create_exception_handling(g) assert etrafo.raise_analyzer.analyze_direct_call(g) + def test_reraise_is_not_raise(self): + def one(x): + if x == 1: + raise ValueError() + elif x == 2: + raise TypeError() + return x - 5 + def foo(x): + try: + return one(x) + except ValueError: + return -42 + t, g = self.transform_func(foo, [int]) + for block in g.iterblocks(): + for op in block.operations: + # the operation 'debug_record_traceback' should only show up + # in a normal raise, not in a reraise + assert op.opname != 'debug_record_traceback' + f = self.compile(foo, [int]) + result = interpret(foo, [7]) + assert result == 2 + result = f(7) + assert result == 2 + result = interpret(foo, [1]) + assert result == -42 + result = f(1) + assert result == -42 + class TestLLType(BaseTestExceptionTransform): type_system = 'lltype' From arigo at codespeak.net Fri Jan 22 18:10:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 22 Jan 2010 18:10:53 +0100 (CET) Subject: [pypy-svn] r70785 - pypy/branch/c-traceback Message-ID: <20100122171053.BD370168023@codespeak.net> Author: arigo Date: Fri Jan 22 18:10:52 2010 New Revision: 70785 Removed: pypy/branch/c-traceback/ Log: Remove merged branch. From afa at codespeak.net Fri Jan 22 18:32:51 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 22 Jan 2010 18:32:51 +0100 (CET) Subject: [pypy-svn] r70786 - pypy/branch/separate-compilation/pypy/rpython/test Message-ID: <20100122173251.40779168023@codespeak.net> Author: afa Date: Fri Jan 22 18:32:50 2010 New Revision: 70786 Modified: pypy/branch/separate-compilation/pypy/rpython/test/test_controllerentry.py Log: A test that I would like to pass: a Controller should be able to support method calls on the Controlled object. Help needed! Modified: pypy/branch/separate-compilation/pypy/rpython/test/test_controllerentry.py ============================================================================== --- pypy/branch/separate-compilation/pypy/rpython/test/test_controllerentry.py (original) +++ pypy/branch/separate-compilation/pypy/rpython/test/test_controllerentry.py Fri Jan 22 18:32:50 2010 @@ -30,6 +30,12 @@ def set_foo(self, obj, value): value.append(obj) + # XXX this is probably not the right way + def get_compute(self, obj): + def compute(obj, arg): + return obj + arg + return compute + def getitem(self, obj, key): return obj + key @@ -112,3 +118,17 @@ assert ''.join(res.item0.chars) == "4_bar" assert ''.join(res.item1.chars) == "4_foo" assert ''.join(res.item2.chars) == "4_baz" + +def fun4(a): + c = C(a) + return c.compute('bar') + +def test_boundmethods_annotate(): + a = RPythonAnnotator() + s = a.build_types(fun4, [a.bookkeeper.immutablevalue("5")]) + assert s.const == "5_bar" + +def test_boundmethods_specialize(): + res = interpret(fun4, ["5"]) + assert ''.join(res.chars) == "5_bar" + From fijal at codespeak.net Sat Jan 23 11:15:12 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 23 Jan 2010 11:15:12 +0100 (CET) Subject: [pypy-svn] r70791 - pypy/branch/direct-assembler-call/pypy/jit/metainterp/test Message-ID: <20100123101512.3171E168030@codespeak.net> Author: fijal Date: Sat Jan 23 11:15:11 2010 New Revision: 70791 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Log: A failing test. Took more than a day to find, but at least it's sort of easy to write. Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Sat Jan 23 11:15:11 2010 @@ -910,6 +910,34 @@ policy=StopAtXPolicy(change)) assert res == main(0) + def test_assembler_call_red_args(self): + py.test.skip("FAIL") + driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def residual(k): + if k > 40: + return 0 + return 1 + + def portal(codeno, k): + i = 0 + while i < 10: + driver.can_enter_jit(codeno=codeno, i=i, k=k) + driver.jit_merge_point(codeno=codeno, i=i, k=k) + if codeno == 2: + k += portal(residual(k), k) + if codeno == 0: + k += 2 + elif codeno == 1: + k += 1 + i += 1 + return k + + res = self.meta_interp(portal, [2, 0], inline=True, + policy=StopAtXPolicy(residual)) + assert res == portal(2, 0) # There is a test which I fail to write. # * what happens if we call recursive_call while blackholing From fijal at codespeak.net Sun Jan 24 11:39:54 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 24 Jan 2010 11:39:54 +0100 (CET) Subject: [pypy-svn] r70795 - in pypy/branch/direct-assembler-call/pypy/jit/metainterp: . test Message-ID: <20100124103954.CA964168075@codespeak.net> Author: fijal Date: Sun Jan 24 11:39:53 2010 New Revision: 70795 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Log: (fijal, SJ train) Implement the correct thing, by generating a guard_value for green args for CALL_ASSEMBLER. they should go away in normal cases Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Sun Jan 24 11:39:53 2010 @@ -660,8 +660,8 @@ return False return self.perform_call(leave_code, varargs) - @arguments("descr", "varargs") - def opimpl_recursive_call(self, calldescr, varargs): + @arguments("orgpc", "descr", "varargs") + def opimpl_recursive_call(self, pc, calldescr, varargs): warmrunnerstate = self.metainterp.staticdata.state token = None if not self.metainterp.is_blackholing() and warmrunnerstate.inlining: @@ -674,6 +674,10 @@ call_position = 0 if token is not None: call_position = len(self.metainterp.history.operations) + # guard value for all green args, needed to make sure + # that assembler that we call is still correct + greenargs = varargs[1:num_green_args + 1] + self.generate_guard_value_for_green_args(pc, greenargs) res = self.do_residual_call(varargs, descr=calldescr, exc=True) if not self.metainterp.is_blackholing() and token is not None: # XXX fix the call position, @@ -687,7 +691,8 @@ assert found # # this will substitute the residual call with assembler call - self.metainterp.direct_assembler_call(varargs, token, call_position) + self.metainterp.direct_assembler_call(pc, varargs, token, + call_position) return res @arguments("descr", "varargs") @@ -798,7 +803,7 @@ def opimpl_keepalive(self, box): pass # xxx? - def generate_merge_point(self, pc, varargs): + def generate_guard_value_for_green_args(self, pc, varargs): num_green_args = self.metainterp.staticdata.num_green_args for i in range(num_green_args): varargs[i] = self.implement_guard_value(pc, varargs[i]) @@ -838,7 +843,7 @@ @arguments("orgpc") def opimpl_jit_merge_point(self, pc): if not self.metainterp.is_blackholing(): - self.generate_merge_point(pc, self.env) + self.generate_guard_value_for_green_args(pc, self.env) # xxx we may disable the following line in some context later self.debug_merge_point() if self.metainterp.seen_can_enter_jit: @@ -2025,7 +2030,7 @@ max_key = key return max_key - def direct_assembler_call(self, varargs, token, call_position): + def direct_assembler_call(self, pc, varargs, token, call_position): """ Generate a direct call to assembler for portal entry point. """ assert not self.is_blackholing() # XXX Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_recursive.py Sun Jan 24 11:39:53 2010 @@ -911,7 +911,6 @@ assert res == main(0) def test_assembler_call_red_args(self): - py.test.skip("FAIL") driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], get_printable_location = lambda codeno : str(codeno), can_inline = lambda codeno : False) @@ -938,6 +937,7 @@ res = self.meta_interp(portal, [2, 0], inline=True, policy=StopAtXPolicy(residual)) assert res == portal(2, 0) + self.check_loops(call_assembler=2) # There is a test which I fail to write. # * what happens if we call recursive_call while blackholing @@ -949,4 +949,3 @@ class TestOOtype(RecursiveTests, OOJitMixin): pass - From cfbolz at codespeak.net Sun Jan 24 18:13:38 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 24 Jan 2010 18:13:38 +0100 (CET) Subject: [pypy-svn] r70797 - pypy/extradoc/planning Message-ID: <20100124171338.198F41680C1@codespeak.net> Author: cfbolz Date: Sun Jan 24 18:13:37 2010 New Revision: 70797 Modified: pypy/extradoc/planning/jit.txt Log: looked at some of the benchmarks, here are some findings Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Sun Jan 24 18:13:37 2010 @@ -29,8 +29,6 @@ - goal: on average <=5 guards per original bytecode -- prevent jitting really general */** calls - - put the class into the structure to get only one promote when using an instance @@ -40,6 +38,27 @@ for hybrid GC (on stringbuilder branch so far). +Benchmark Notes +---------------------------- + + - spitfire: + - spends most of its time in subclass-of-list.append + - does completely horrible hackish things that happen to be fast on CPython + (i.e. calling locals() all the time) + - see http://paste.pocoo.org/show/169366/ for the python code that spitfire + produces for the template used in the benchmark + + - html5lib: + - slowness seems to be mostly the fault of PyUnicode_DecodeCharmap in + module/_codecs/app_codecs.py. Are such things not jitted? + - the tokenizer uses regular expressions and generators, which probably + doesn't help + - calls str.lower a lot + + - spambayes + - uses regular expressions and generators a lot + + JIT-related Release Tasks --------------------------- From fijal at codespeak.net Sun Jan 24 19:32:42 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 24 Jan 2010 19:32:42 +0100 (CET) Subject: [pypy-svn] r70798 - pypy/benchmarks Message-ID: <20100124183242.3E42E31813B@codespeak.net> Author: fijal Date: Sun Jan 24 19:32:41 2010 New Revision: 70798 Modified: pypy/benchmarks/runner.py Log: Store possibly more information in json, unused so far Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Sun Jan 24 19:32:41 2010 @@ -8,7 +8,8 @@ from unladen_swallow import perf import benchmarks -def run_and_store(benchmark_set, result_filename, pypy_c_path, revision=0): +def run_and_store(benchmark_set, result_filename, pypy_c_path, revision=0, + options='', branch='trunk'): funcs = perf.BENCH_FUNCS.copy() funcs.update(perf._FindAllBenchmarks(benchmarks.__dict__)) results = perf.main(['-f', '-b', ','.join(benchmark_set), @@ -21,6 +22,8 @@ f.write(json.dumps({ 'revision' : revision, 'results' : res, + 'options' : options, + 'branch' : branch, })) f.close() @@ -42,12 +45,16 @@ " Valid benchmarks are: " + ", ".join(BENCHMARK_SET))) parser.add_option('-p', '--pypy-c', default=sys.executable, - help=('pypy-c or other modified python to run against')) + help='pypy-c or other modified python to run against') parser.add_option('-r', '--revision', default=0, action="store", type=int, - help=('specify revision of pypy-c')) + help='specify revision of pypy-c') parser.add_option('-o', '--output-filename', default="result.json", action="store", - help=('specify output filename to store resulting json')) + help='specify output filename to store resulting json') + parser.add_option('--options', default='', action='store', + help='a string describing picked options, no spaces') + parser.add_option('--branch', default='trunk', action='store', + help="pypy's branch") options, args = parser.parse_args(argv) benchmarks = options.benchmarks.split(',') for benchmark in benchmarks: From cfbolz at codespeak.net Sun Jan 24 19:52:56 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 24 Jan 2010 19:52:56 +0100 (CET) Subject: [pypy-svn] r70800 - pypy/trunk/pypy/interpreter Message-ID: <20100124185256.A2BEE16804F@codespeak.net> Author: cfbolz Date: Sun Jan 24 19:52:56 2010 New Revision: 70800 Modified: pypy/trunk/pypy/interpreter/pycode.py Log: fix comment, importing lives somewhere else now. Modified: pypy/trunk/pypy/interpreter/pycode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pycode.py (original) +++ pypy/trunk/pypy/interpreter/pycode.py Sun Jan 24 19:52:56 2010 @@ -27,7 +27,7 @@ # Magic numbers for the bytecode version in code objects. -# See comments in pypy/module/__builtin__/importing. +# See comments in pypy/module/imp/importing. cpython_magic, = struct.unpack(" Author: fijal Date: Sun Jan 24 19:53:16 2010 New Revision: 70801 Added: pypy/build/bot2/jsplot/plotone.html pypy/build/bot2/jsplot/test/data/dir.html - copied unchanged from r70799, pypy/build/bot2/jsplot/test/data/dir Removed: pypy/build/bot2/jsplot/test/data/dir Modified: pypy/build/bot2/jsplot/js/collect.js pypy/build/bot2/jsplot/js/plot.js pypy/build/bot2/jsplot/test/jstest_collect_any.js Log: Add plotone.html, which maps last revision on logarithmic scale Modified: pypy/build/bot2/jsplot/js/collect.js ============================================================================== --- pypy/build/bot2/jsplot/js/collect.js (original) +++ pypy/build/bot2/jsplot/js/collect.js Sun Jan 24 19:53:16 2010 @@ -29,30 +29,81 @@ } } -function collect_data(plot_function, revlist_url, base_url, async) +function _collect(foreachrev, plot_function, revlist_url, base_url, async) { $.ajax({ url: revlist_url, dataType: 'html', success: function(htmlstr) { var revnos = extract_revnos($(htmlstr)); - var collector = new Collector(revnos); - collector.plot = plot_function; - for (var i in revnos) { - $.ajax({ - url: base_url + revnos[i] + '.json', - success: function(data) { - collector.collect(data) - }, - dataType: 'json', - async: async, - }); - } + foreachrev(revnos); }, async: async, }); } +function collect_data(plot_function, revlist_url, base_url, async) +{ + _collect(function (revnos) { + var collector = new Collector(revnos); + collector.plot = plot_function; + for (var i in revnos) { + $.ajax({ + url: base_url + revnos[i] + '.json', + success: function(data) { + collector.collect(data) + }, + dataType: 'json', + async: async, + }); + } + }, plot_function, revlist_url, base_url, async); +} + +function collect_latest_data(plot_function, revlist_url, base_url, async) +{ + function extract_ch(elem) { + if (elem.avg_changed) { + return elem.avg_changed; + } + return elem.changed_time; + } + + function extract_base(elem) { + if (elem.avg_base) { + return elem.avg_base; + } + return elem.base_time; + } + + function postprocess(data) { + var res = [[], []]; + var benchnames = []; + for (var i = 0; i < data.results.length; ++i) { + var elem = data.results[i]; + benchnames.push(elem[0]); + res[0].push(extract_ch(elem[2])); + res[1].push(extract_base(elem[2])); + } + data.results = res; + data.benchnames = benchnames; + return data; + } + + _collect(function (revnos) { + revnos.sort(); + var lastrev = revnos[revnos.length - 1]; + $.ajax({ + url: base_url + lastrev + '.json', + success: function(data) { + plot_function(postprocess(data)); + }, + dataType: 'json', + async: async, + }); + }, plot_function, revlist_url, base_url, async); +} + function extract_benchmark_data(data) { var retval = {}; Modified: pypy/build/bot2/jsplot/js/plot.js ============================================================================== --- pypy/build/bot2/jsplot/js/plot.js (original) +++ pypy/build/bot2/jsplot/js/plot.js Sun Jan 24 19:53:16 2010 @@ -6,7 +6,7 @@ JSON_DIR_LIST = JSON_DIR_URL; } else { JSON_DIR_URL = "test/data/"; - JSON_DIR_LIST = JSON_DIR_URL + "dir"; + JSON_DIR_LIST = JSON_DIR_URL + "dir.html"; } var large_displayed = false; @@ -110,3 +110,62 @@ var plotinput = get_plot_input(benchresults, cpython_results) $.plot($("#placeholder").children(":last"), plotinput, common_attrs()); } + +function plot_one(plotdata) { + function lg(v) { + return Math.log(v) / Math.log(2); + } + + var results = plotdata.results; + var data = []; + var min = 1, max = 1; + for (var i = 0; i < results[0].length; ++i) { + var next = lg(results[1][i] / results[0][i]); + if (next < min) { + min = Math.floor(next); + } + if (next > max) { + max = Math.ceil(next); + } + data.push([i - .3, next]); + } + var yticks = []; + for (var i = min; i < max; i++) { + var v = Math.pow(2, i); + if (v < 1) { + yticks.push([i, 1/v + "x slower"]); + } else if (v == 1) { + yticks.push([i, "equal"]); + } else { + yticks.push([i, v + "x faster"]); + } + } + var xticks = []; + for (var i = 0; i < plotdata.benchnames.length; ++i) { + xticks.push([i, plotdata.benchnames[i]]); + } + $.plot($("#placeholder"), [data], + { + series: { + bars: { + show: true, + barWidth: .6, + align: 'left', + }, + hoverable: true, + }, + yaxis: { + ticks: yticks, + }, + xaxis: { + ticks: xticks, + }, + grid: { + hoverable: true, + } + }); + $("#placeholder").bind("plothover", function (event, pos, item) { + if (item) { + } + }); +} \ No newline at end of file Added: pypy/build/bot2/jsplot/plotone.html ============================================================================== --- (empty file) +++ pypy/build/bot2/jsplot/plotone.html Sun Jan 24 19:53:16 2010 @@ -0,0 +1,22 @@ + + + + + + + + + + + + +

      Last run view

      +

      PyPy with JIT against CPython

      +
      +
      + + Modified: pypy/build/bot2/jsplot/test/jstest_collect_any.js ============================================================================== --- pypy/build/bot2/jsplot/test/jstest_collect_any.js (original) +++ pypy/build/bot2/jsplot/test/jstest_collect_any.js Sun Jan 24 19:53:16 2010 @@ -7,60 +7,72 @@ "slowspitfire", "spambayes"] Tests = { -test_extract_benchmark_data: function() { - var revnos = [70634, 70632]; - var loaded_data = []; - for (var i in revnos) { + test_extract_benchmark_data: function() { + var revnos = [70634, 70632]; + var loaded_data = []; + for (var i in revnos) { + $.ajax({ + url: '/test/data/' + revnos[i] + '.json', + dataType: 'json', + success: function(result) { + loaded_data.push(result); + }, + async: false + }); + } + var bench_data = extract_benchmark_data(loaded_data); + aisDeeply(bench_data.results.ai, [[70632, 0.43707809448220003], + [70634, 0.42492904663079994]]); + var benchnames = _.keys(bench_data.results); + benchnames.sort(); + aisDeeply(benchnames, expected_benchnames); + var benchnames = _.keys(bench_data.cpytimes); + benchnames.sort(); + aisDeeply(benchnames, expected_benchnames); + ais(bench_data.cpytimes.ai, 0.43372206687940001); + ais(bench_data.lasttimes.ai, "1.0207x faster"); + }, + + test_extract_revnos: function() { + var dirdoc; $.ajax({ - url: '/test/data/' + revnos[i] + '.json', - dataType: 'json', - success: function(result) { - loaded_data.push(result); + url: "/test/data/dir.html", + contentType: "text/xml", + dataType: "html", + success: function (result) { + dirdoc = $(result); }, - async: false + async: false, }); - } - var bench_data = extract_benchmark_data(loaded_data); - aisDeeply(bench_data.results.ai, [[70632, 0.43707809448220003], - [70634, 0.42492904663079994]]); - var benchnames = _.keys(bench_data.results); - benchnames.sort(); - aisDeeply(benchnames, expected_benchnames); - var benchnames = _.keys(bench_data.cpytimes); - benchnames.sort(); - aisDeeply(benchnames, expected_benchnames); - ais(bench_data.cpytimes.ai, 0.43372206687940001); - ais(bench_data.lasttimes.ai, "1.0207x faster"); -}, - -test_extract_revnos: function() { - var dirdoc; - $.ajax({ - url: "/test/data/dir", - contentType: "text/xml", - dataType: "html", - success: function (result) { - dirdoc = $(result); - }, - async: false, - }); - var revnos = extract_revnos(dirdoc); - aisDeeply(revnos, [70632, 70634, 70641, 70643]); -}, + var revnos = extract_revnos(dirdoc); + aisDeeply(revnos, [70632, 70634, 70641, 70643]); + }, -test_collect_data: function() { - var checkdata; - var benchnames = []; - function check(benchname, benchresults, cpyresults) { - benchnames.push(benchname); - if (benchname == "html5lib") { - checkdata = [benchresults, cpyresults]; + test_collect_data: function() { + var checkdata; + var benchnames = []; + function check(benchname, benchresults, cpyresults) { + benchnames.push(benchname); + if (benchname == "html5lib") { + checkdata = [benchresults, cpyresults]; + } } - } - collect_data(check, "/test/data/dir", "/test/data/", false); - aisDeeply(benchnames, expected_benchnames); - aisDeeply(checkdata, [[[70632, 18.3431589603], [70634, 18.2035400867], - [70641, 19.623087883], [70643, 18.1294131279]], - [[70632, 11.7123618126], [70643, 11.7123618126]]]); -} + collect_data(check, "/test/data/dir.html", "/test/data/", false); + aisDeeply(benchnames, expected_benchnames); + aisDeeply(checkdata, [[[70632, 18.3431589603], [70634, 18.2035400867], + [70641, 19.623087883], [70643, 18.1294131279]], + [[70632, 11.7123618126], + [70643, 11.7123618126]]]); + }, + + test_collect_latest_data: function() { + var checkdata; + function check(data) { + checkdata = data; + }; + collect_latest_data(check, "/test/data/dir.html", "/test/data/", false); + ais(checkdata.results[0][0], 0.4273978233336) + ais(checkdata.results[1][0], 0.43415923118599997); + ais(checkdata.benchnames[0], 'ai'); + }, } From fijal at codespeak.net Sun Jan 24 20:00:10 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 24 Jan 2010 20:00:10 +0100 (CET) Subject: [pypy-svn] r70802 - pypy/branch/direct-assembler-call/pypy/jit/metainterp Message-ID: <20100124190010.31226168078@codespeak.net> Author: fijal Date: Sun Jan 24 20:00:09 2010 New Revision: 70802 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Log: The situation that theoretically should not happen, but happens in practice. Write a test! Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Sun Jan 24 20:00:09 2010 @@ -875,9 +875,13 @@ def opimpl_teardown_exception_block(self): self.exception_target = -1 - @arguments("constbox", "jumptarget") - def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target): - assert isinstance(self.exception_box, Const) # XXX + @arguments("constbox", "jumptarget", "orgpc") + def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target, pc): + # XXX used to be: + # assert isinstance(self.exception_box, Const) # XXX + # seems this can happen that self.exception_box is not a Const, + # but I failed to write a test so far :-( + self.exception_box = self.implement_guard_value(pc, self.exception_box) cpu = self.metainterp.cpu ts = self.metainterp.cpu.ts if not ts.subclassOf(cpu, self.exception_box, vtableref): From fijal at codespeak.net Sun Jan 24 20:02:05 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 24 Jan 2010 20:02:05 +0100 (CET) Subject: [pypy-svn] r70803 - pypy/branch/direct-assembler-call/pypy/jit/backend/x86 Message-ID: <20100124190205.A3D7E16807B@codespeak.net> Author: fijal Date: Sun Jan 24 20:02:05 2010 New Revision: 70803 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Log: Improve performance of a common case (returning with DoneWithThisFrameInt), maybe we should also handle DoneWithThisFrameRef, since it's used by generators Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/x86/assembler.py Sun Jan 24 20:02:05 2010 @@ -477,30 +477,34 @@ return self.implement_guard(addr, getattr(self.mc, name)) return genop_cmp_guard_float - def _emit_call(self, x, arglocs, start=0, tmp=eax): + @specialize.arg(5) + def _emit_call(self, x, arglocs, start=0, tmp=eax, force_mc=False, + mc=None): + if not force_mc: + mc = self.mc p = 0 n = len(arglocs) for i in range(start, n): loc = arglocs[i] if isinstance(loc, REG): if isinstance(loc, XMMREG): - self.mc.MOVSD(mem64(esp, p), loc) + mc.MOVSD(mem64(esp, p), loc) else: - self.mc.MOV(mem(esp, p), loc) + mc.MOV(mem(esp, p), loc) p += round_up_to_4(loc.width) p = 0 for i in range(start, n): loc = arglocs[i] if not isinstance(loc, REG): if isinstance(loc, MODRM64): - self.mc.MOVSD(xmm0, loc) - self.mc.MOVSD(mem64(esp, p), xmm0) + mc.MOVSD(xmm0, loc) + mc.MOVSD(mem64(esp, p), xmm0) else: - self.mc.MOV(tmp, loc) - self.mc.MOV(mem(esp, p), tmp) + mc.MOV(tmp, loc) + mc.MOV(mem(esp, p), tmp) p += round_up_to_4(loc.width) self._regalloc.reserve_param(p//WORD) - self.mc.CALL(x) + mc.CALL(x) self.mark_gc_roots() def call(self, addr, args, res): @@ -1280,8 +1284,21 @@ assert len(arglocs) - 2 == len(descr._x86_arglocs[0]) self._emit_call(rel32(descr._x86_direct_bootstrap_code), arglocs, 2, tmp=eax) + mc = self.mc._mc + mc.CMP(eax, imm(self.cpu.done_with_this_frame_int_v)) + mc.write(constlistofchars('\x74\x00')) # JE below + je_location = mc.get_relative_pos() self._emit_call(rel32(self.assembler_helper_adr), [eax, arglocs[1]], 0, - tmp=ecx) + tmp=ecx, force_mc=True, mc=mc) + mc.write(constlistofchars('\xEB\x00')) # JMP below + jmp_location = mc.get_relative_pos() + offset = jmp_location - je_location + assert 0 < offset <= 127 + mc.overwrite(je_location - 1, [chr(offset)]) + mc.MOV(eax, heap(self.fail_boxes_int.get_addr_for_num(0))) + offset = mc.get_relative_pos() - jmp_location + assert 0 < offset <= 127 + mc.overwrite(jmp_location - 1, [chr(offset)]) if isinstance(result_loc, MODRM64): self.mc.FSTP(result_loc) else: From fijal at codespeak.net Sun Jan 24 20:03:45 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 24 Jan 2010 20:03:45 +0100 (CET) Subject: [pypy-svn] r70804 - pypy/build/bot2/codespeak-html Message-ID: <20100124190345.706261680A3@codespeak.net> Author: fijal Date: Sun Jan 24 20:03:44 2010 New Revision: 70804 Added: pypy/build/bot2/codespeak-html/plotone.html (contents, props changed) Log: Add a link. Consider moving it to a subdir... Added: pypy/build/bot2/codespeak-html/plotone.html ============================================================================== --- (empty file) +++ pypy/build/bot2/codespeak-html/plotone.html Sun Jan 24 20:03:44 2010 @@ -0,0 +1 @@ +link ../jsplot/plotone.html \ No newline at end of file From jacob at codespeak.net Sun Jan 24 20:08:10 2010 From: jacob at codespeak.net (jacob at codespeak.net) Date: Sun, 24 Jan 2010 20:08:10 +0100 (CET) Subject: [pypy-svn] r70805 - pypy/benchmarks/own Message-ID: <20100124190810.8886B1680A3@codespeak.net> Author: jacob Date: Sun Jan 24 20:08:10 2010 New Revision: 70805 Added: pypy/benchmarks/own/schulze.py pypy/benchmarks/own/schulze.votes Log: Added Schulze voting resolution as benchmark. The data is live data from the primary elections of the Swedish Pirate Party. Added: pypy/benchmarks/own/schulze.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/schulze.py Sun Jan 24 20:08:10 2010 @@ -0,0 +1,88 @@ +# Read the votes +fp = open('schulze.votes', 'r') +lines = fp.readlines() +fp.close() + +# Strip superfluous information +lines = [line[14:].rstrip() for line in lines] + +votes = [line.split(' ') for line in lines] + +# Make a canonical set of all the candidates +candidates = {} +for line in votes: + for memberId in line: + candidates[memberId] = 1 + +# Go from member number to an index +for i, k in enumerate(candidates.keys()): + candidates[k] = i + +# And vice versa +reverseCandidates = {} +for k, v in candidates.items(): + reverseCandidates[v] = k + +# Turn the votes in to an index number +numbers = [[candidates[memberId] for memberId in line] for line in votes] + +size = len(candidates) + +# Initialize the d and p matrixes +row = [] +for i in range(size): + row.append(0) + +d = [] +p = [] +for i in range(size): + d.append(row[:]) + p.append(row[:]) + +# Fill in the preferences in the d matrix +for i in range(size): + for line in numbers: + for entry in line: + if entry == i: + break + d[entry][i] += 1 + +# Calculate the p matrix. Algorithm copied straight from wikipedia +# article http://en.wikipedia.org/wiki/Schulze_method +for i in range(size): + for j in range(size): + if i != j: + if d[i][j] > d[j][i]: + p[i][j] = d[i][j] + else: + p[i][j] = 0 + +for i in range(size): + for j in range(size): + if i != j: + for k in range(size): + if i != k: + if j != k: + p[j][k] = max(p[j][k], min(p[j][i], p[i][k])) + +# Find the best candidate (p[candidate, X] >= p[X, candidate]) +# Put the candidate on the final list, remove the candidate from p and +# repeat +order = [] +cl = range(size) + +while cl: + for c in cl: + for n in cl: + if c != n: + if p[c][n] < p[n][c]: + break # Found a better candidate + else: + order.append(c) + cl.remove(c) + +# Display the results +j = 0 +for i in order: + j += 1 + print '%3d %s' % (j, reverseCandidates[i]) Added: pypy/benchmarks/own/schulze.votes ============================================================================== --- (empty file) +++ pypy/benchmarks/own/schulze.votes Sun Jan 24 20:08:10 2010 @@ -0,0 +1,1300 @@ +227AB8KF2FVE 22270 72 3655 273 1 13425 3365 922 15866 18060 7073 19049 19821 +22DPWE323HPZ 63640 1 65252 62473 2607 56668 63081 13454 8715 378 13425 15353 4166 10796 11443 72 +236669ZH3P9A 13454 11443 16759 922 65252 3655 3419 10676 5204 13425 43932 378 1 42694 19049 64064 290 4166 +23B29NMXNQAV 56063 26576 11265 12346 3093 56668 18060 437 11072 12941 51716 63695 33137 15915 12468 63640 1135 34002 47292 61923 378 7073 +247AZ6WC6FKY 1 11443 378 11729 3419 7059 12393 437 1007 3 2608 967 +252HTEFP9YJ7 57909 44 16918 17337 25047 12393 17152 13776 12191 54098 23893 922 15866 16916 8790 63695 42694 34981 15074 53472 9876 9812 +254CTXDVX685 6315 1 58572 273 11443 16403 290 9360 1007 4699 7059 437 13425 22270 +26H3RZ9QPAXH 56475 19374 903 1343 13415 3419 12184 11265 20623 8715 17152 7073 1 39553 64304 43932 180 19049 63695 1306 54098 25047 +283QUQQR8HEC 1 11443 61657 15175 1007 31395 44 +287XCAH8R458 1 11443 1981 3 3365 17591 4166 15915 967 3655 3419 +28MXV6UBHERV 1 11443 378 15915 4166 3 13425 3655 1007 3419 65252 7059 1981 10676 9951 8715 11729 17591 437 22270 61657 72 +28RB4DTEY436 17743 1 11443 +293882MU6J3B 10796 +29F2PECNXJDH 17378 22513 12941 16403 8715 43570 24437 273 64042 +2AECV7MNXWCA 1 13425 2613 2608 61923 34981 12649 437 11443 922 290 54098 10796 1466 +2AQF3JZAEUNA 65252 11443 16916 2613 13454 15915 17591 63274 7059 19374 290 967 3 437 15175 1185 1 8715 1981 57909 3365 3655 +2BDEEKBPW42M 22270 7059 +2BV6FXWAR3A4 17743 1 11443 1135 34981 +2BYNZ6X6KW53 65252 63640 19374 11072 19821 11443 1135 290 1981 +2C7W5BCA7DDA 24394 54098 3419 13218 19374 290 53472 11443 27980 12941 2608 23775 834 1007 30906 22270 4332 12346 63274 7198 25047 56489 +2CETWBZR7D25 15175 11443 3655 +2D29EETKWCH7 11443 1 15791 437 3419 8715 15845 +2EH3T4DQHDA6 1 11443 13454 13425 61657 11729 7059 2613 378 22270 72 65252 12184 10676 3 19374 63274 922 967 31715 3365 3419 +2EKHDUZ4NBNH 3 1 65252 11443 1981 10796 63081 61657 15353 2477 19049 59948 3655 58249 922 4166 13218 24492 13425 8715 15201 10676 +2F7A8VVDCEQX 61923 65457 64042 11265 63914 1 43570 62209 61783 2953 3655 52027 4166 22270 36772 24394 7073 21204 12941 26576 8790 72 +2F7PUB4CCVKU 11262 5115 5204 61657 23608 17325 23775 13167 25047 37047 34799 15442 3093 44 57909 22532 15353 187 180 41676 13454 65203 +2FW5F56XYC73 11443 4166 15201 58572 63081 15915 3 15845 17591 12649 290 21158 1981 12941 180 1185 437 2477 20919 4332 8790 24394 +2FWQR9TAA7XV 61657 11262 5115 37047 13425 25047 9360 +2HR59NXTQNYV 1 15791 11443 3419 72 31715 290 12393 967 1007 27980 3655 10796 +2JKRVKFWK6BB 63914 23608 65597 34002 7073 62639 18060 13454 11443 65252 34981 63274 1 12941 61657 36911 +2JZMW6FMXND5 11443 65252 1 61657 437 2613 8715 10676 10796 15175 13454 1007 3419 13425 22270 967 58572 31395 9360 3365 1402 1681 +2KMQN5QXV5VE 3419 1 11443 19049 56489 +2MEQYV7NVZ95 1 11443 11537 65252 13454 2613 61657 42694 72 63695 1007 10796 3365 39553 378 15175 967 19049 273 3419 16759 31395 +2NB3XRTFAVB3 967 437 10796 65252 31715 2613 22270 43932 15175 922 63274 3655 5204 2477 1402 4166 11443 378 9360 3365 12691 17152 +2NC93AV9D4UP 17152 922 1 +2NJN4WX2QHFV 43570 11262 8715 5204 23608 31395 19049 32200 17325 15175 25047 56489 7198 5115 1135 46705 17378 +2NM47VTKNADQ 9360 2613 967 11262 1185 65252 273 5115 13218 11537 9652 437 42694 15915 4166 43932 1135 7198 3365 1681 20244 +2NX63T873PRF 290 +2PVFQ8H934YZ 57909 12184 9876 27139 29846 8790 58572 11 65457 60694 9635 2242 13415 12691 6786 61923 3655 56677 28084 +2Q53RM43T8PM 24394 5152 11443 65252 22270 10796 46705 19374 7059 63274 19821 41676 1343 +2QJYY8V8FNCX 11 44 8715 17850 +2QTZTQQBB2B3 3419 63081 1 53472 17378 922 43932 7392 56489 +2R2UPKHBYYBY 15175 10796 61923 11072 13425 54098 922 10676 34981 12346 +2RNHANU3448H 8715 63229 13425 23998 31395 17378 34578 12184 11443 28904 22270 15353 1736 16916 54098 65429 10796 72 10676 63274 64288 19821 +2RVM5M3FBQ33 1 1007 72 11443 437 13425 +2TUY4R37T5QM 3419 11443 967 3365 1 8715 8790 72 23893 +2UVNUW7VPBTU 5152 +2VNR52FRZ659 1 9635 967 437 2613 3 12393 65252 3365 64064 15201 3419 1681 11443 15353 9360 22270 378 1981 +2VTM5P4TJ4CW 2242 3655 +2WANXC88YU2M 13454 11443 3419 1 16759 64288 5504 +2X3ED5UF9A4U 11443 1 1736 12393 7198 1981 15175 1135 17378 25047 2607 26576 21158 12184 42694 8715 43932 54098 9876 12649 28084 19049 +2X7X86E4YQ2T 15791 3419 11072 11443 1007 7198 7073 9876 15866 1135 33137 378 18060 15175 19821 +2XRRYNWFVNFH 15791 6315 1 15915 17744 4332 4166 15201 13454 15353 43932 +2Y4X3KBCCXU4 5504 1981 46559 64960 62473 53472 13425 17744 16759 50039 64093 1306 2608 53966 40542 3655 13454 11443 15353 10676 14905 +2ZDD6U5MRPYT 62209 13218 72 967 44493 7198 1 +2ZU34JJFFPMV 10796 8715 437 2477 65252 13454 3419 +3282HV2KK4ER 62923 64064 13454 10796 2607 11443 19821 3365 58249 29846 72 61657 3419 1 27980 18060 12691 16916 61923 60694 15845 +32PA7PZ3FHJU 14696 2608 +33E33F49X6XJ 922 967 31715 15791 2477 10796 21158 3365 3655 17152 3419 3790 437 20623 9876 12346 27980 64064 1402 58249 47292 24492 +34YE5U7WAHDW 11443 1 65252 13454 19374 967 13425 16759 22270 61657 3419 378 922 11729 5204 33137 3655 3790 3365 11265 21158 290 +35AUVUNM63ZZ 63274 11443 1 1736 +35MPXXJXNEUN 1 11443 16916 10796 11729 +36ECCDKFJQQR 72 +375ER86T3WXR 1 11443 12393 65252 3 2613 20244 3419 1007 3655 4166 15175 11729 922 15915 22270 967 8715 437 13425 3365 31715 +37AECVEZ8FVE 1 7059 +37FVPMDW8W58 10676 63274 15866 59948 56677 64081 54449 1 15175 63081 63695 2613 13425 51716 47292 65505 13454 31395 34578 3093 +37MDZNEH8RBA 28904 +37NUYBVRMXJY 41676 1466 +388RRMNPTUER 1 +38YEZ3PHCRUC 967 922 2613 65252 4166 9360 31715 10796 13425 378 15791 3655 11443 63274 1402 7059 43932 2477 15175 3790 17152 437 +394QN4AT78YX 16403 16759 17850 6315 +39NDA2F88U7N 57909 61923 9812 1135 59118 +3A7M9Q4XFBN4 17743 16403 8715 13425 378 11729 3365 46559 20623 54098 +3AHKWMWH68AU 1 65252 11443 3365 11729 7059 3 12184 2613 13454 72 967 437 15915 61657 3419 1981 63640 922 2477 1185 378 +3AJ76YQ23T58 13454 1 11443 11729 378 65252 61657 967 16759 3365 3 8715 7198 7059 1007 19374 3419 2613 34981 3655 922 20244 +3AMN4CCVWP9M 11265 1 11443 437 31715 61923 922 19374 3365 +3BKEBV72NH9P 31715 922 11443 10796 13454 61657 1 46705 43932 15791 290 22270 967 63081 65252 24394 14126 11537 34041 13425 1402 8715 +3C7HXVJ5TT5A 1 11729 11443 3365 7059 65252 967 2608 13454 3419 16916 9360 3 +3DMXBHZCN2DY 49655 65252 10676 8715 13425 61923 9951 22270 12691 56063 3419 922 19821 19374 64042 15175 1306 42694 64304 13218 54098 19049 +3DQ43UQ5C372 19374 11072 4166 378 19049 31715 15866 967 7059 16916 9360 10796 16759 65252 20244 3365 15915 11729 21158 11443 8790 15791 +3DUJNVQD98H8 967 12393 378 11729 1007 922 437 +3FJU5YCBTQCK 11443 1007 378 1 +3JFU5E2NHD5Z 1185 19374 +3MAWQD6UC3NU 72 12393 +3MPUYF32QT63 2608 13425 2242 3 437 15915 11443 8715 3655 1 14696 13415 4166 378 15201 19374 +3N2V5XPFA3J5 11443 967 +3N3EQT4HWV74 23893 +3NRXEBV8PB92 11537 11729 3365 922 8715 378 13425 72 +3P5VKCH6MXD5 1 11443 967 13454 16759 378 3365 19374 922 65252 2613 3419 61657 +3PUDVDAHKCVV 11443 65252 967 3419 11729 10796 16916 57909 3790 72 15353 1 3 2477 54449 7059 437 3655 2613 +3QKJM5WPWHVY 12184 1 11443 3365 13425 1007 11729 1736 72 31715 16916 19374 15866 967 +3QV65WRM67AA 1 967 11443 63640 7073 63274 11072 378 2613 15791 3655 +3RXX9HVZKC6B 62639 28084 63274 3419 57909 64081 11729 20919 +3TW3Q2CFYKFH 11443 65252 13454 65505 5115 61923 2613 13218 3093 967 72 3419 16916 34981 42694 19821 20244 62639 18060 19049 30906 14126 +3U65FFA3WBMJ 61657 13425 7059 72 17591 65252 19374 3 11072 19049 18060 43932 12691 +3UXVHW4PW76F 437 +3VEV9H4FYA6X 1 11443 2613 967 378 19374 1981 11072 61657 64064 63274 13425 7059 12393 3365 21158 273 3093 19821 15866 1736 13454 +3WBQCKYB9CAV 61657 11262 37047 72 16759 1 11443 65252 437 290 13425 +3X6TP3C75KFB 11537 11443 13425 3419 437 10676 3 12393 2608 22270 +3XNDYC7Q48A6 2607 7059 23668 63914 28904 1736 16916 63274 +3YNJDZKKX7EV 65252 27980 30906 34578 1343 2613 11443 19821 31395 3655 3419 47292 19049 42694 39553 65498 31715 922 12691 19374 15175 8715 +3ZD7H9PBE6JH 11443 1 +429Q92TTRA93 16403 +43YH9WT63TXC 64093 61657 23608 56668 22513 7198 72 17743 16129 1 63695 15353 17152 42694 12691 903 4166 17325 11443 53472 3 62473 +4477PZ9ZJ6AK 11443 11729 3419 3365 65252 +44ZCBPET5C4V 11443 3 16759 56489 65597 15915 15175 20244 +459K3A6QCT9N 1 +45YRC9XUW4VU 12184 +46DHKJNJ73XY 61657 65252 3365 5152 20244 13454 31715 11443 16759 43932 11729 13425 437 378 1007 1681 3 11262 15915 3655 19049 10796 +46MYWFFMAFZW 11443 1 3419 +474TC3Z3EBFX 11443 1 64064 65252 378 8715 72 27980 12346 63695 24394 14126 47292 43932 62639 34578 58572 19821 31395 53966 30906 22270 +475ZFQX4YAMJ 13454 11443 1 19049 9635 72 63274 15866 4589 65457 64064 834 11729 17744 20244 46559 1135 922 19374 58249 12393 63229 +47C9UQ2UYV38 11443 13454 22270 13425 1 3655 3419 8715 10676 5204 2607 13218 922 1681 43932 2242 42694 58572 15175 19049 2953 15201 +47QXXWQJFTX8 13454 11443 1 65252 11729 3419 378 922 61657 19374 1007 2613 3365 3655 20244 31715 7059 967 8715 16759 3 5152 +47TPY95NEEF8 11443 11537 922 13454 10796 931 22270 15791 3655 27980 4166 19374 57909 63640 8715 43932 1402 11072 9876 31715 13425 23893 +49UDUBZQPV7K 11729 +4AWV493XHJNQ 3 13425 15845 15915 2613 15201 63081 43932 4166 58572 1981 12941 17591 180 10676 1866 1185 23020 49655 12649 16918 62473 +4AWWUXHZNHYU 28904 +4DE4ABMBXWMH 22270 7198 53472 10796 54098 +4EJTM25DH6EF 5115 +4F28VQ88UHPB 3419 +4F7WD6D4CHXF 1 11443 1185 26576 437 +4H3K3EVYT389 62473 1 11443 10676 29846 58249 34578 16759 47839 51716 30906 65252 56677 +4HX2UVDNHFXY 11443 65252 7059 28084 3365 2613 967 3 15915 11729 3419 64064 1 13454 20623 22270 +4J68PXTYC9DC 967 8715 437 10676 1981 922 10796 11443 43932 13425 31395 15175 15915 +4MMRC8X4CZYV 1 30906 11443 9635 8715 58249 13425 63640 10796 15353 19821 54449 27980 922 57909 187 29846 64064 62923 1135 63735 44 +4MMVF7UPWZVE 1 10676 2608 63640 34981 12649 56063 3093 64304 13425 2607 26576 56489 13218 14126 13415 57909 60694 62923 4166 437 1402 +4N4BKWHXYQF8 57909 61923 10796 11443 +4N6MPQWU8HEE 57909 9876 65429 8715 13218 65203 19821 1135 34799 1466 56677 28084 5204 273 13776 22513 50039 64960 63695 54098 64304 46705 +4NUV82264D8A 11443 8715 13454 11729 13415 46705 20919 6315 46874 15866 +4NYKB8X82JFX 1981 15442 14696 13415 12649 65460 17325 62639 65203 64064 1 65498 +4PWDM29KUDBQ 1 4166 63640 19821 56489 62923 24437 17743 34981 7073 273 62639 13218 40542 64304 56063 63735 13425 56677 23020 187 54188 +4Q3TR8T2VDTU 22270 290 1343 922 +4Q96MPMJFQU3 15915 922 54206 +4QE4EDWDZNH5 11443 437 65252 18060 13425 62639 31715 63640 3655 61657 8715 64064 19374 16759 19821 60694 3419 1007 63081 24394 3365 34981 +4RBHC4AFKPQ2 43932 10676 65252 11443 22270 3419 8715 10796 19821 13425 922 3655 61923 19049 39553 19374 27980 5204 1343 15175 65498 42694 +4RBZC8HZ5XR3 1 11443 4166 15915 15175 1007 437 65252 13425 +4T2ENTXAJ5W4 16916 65252 11443 11729 13454 63735 30906 22270 922 27139 3365 11537 +4U67924DW9BA 15791 72 1 12393 +4UQZMAVJ363X 57909 59948 34578 64960 1981 42618 53472 13218 11072 1402 +4V9FYKHHB35D 1 11443 11729 13454 65252 3365 378 7059 3419 +4WDCUDD2W2AW 65252 11443 1 3419 7059 +4WERQVQM38AA 62209 54098 1 11443 7198 31395 303 3655 65597 2607 23608 13425 36911 922 44 63695 2242 2613 903 34578 23775 9635 +4Y786U4U6HEH 62209 11443 65252 922 42694 1 1135 22513 64304 15353 5115 34578 9635 65505 14126 12393 13415 53472 31715 967 22270 8790 +4YQDK9Z2E4X7 1 11443 17591 1343 72 26576 3419 967 13454 6315 7059 437 1007 +52BHRAHAYNR6 10796 64064 +53277DNY5YYV 17591 437 11443 12649 12393 72 3790 1 62209 56063 13425 +53A9NX8YFDMF 11443 273 65252 3365 2613 3419 19049 15353 39553 11729 1 3655 15175 8715 19374 10676 63695 54098 31395 12691 13425 922 +56YC5XJAR4WM 1 12941 922 16916 1736 23668 11443 +56Z8VN8U9F47 7059 11443 65252 16916 1 72 1343 47292 22532 34578 23775 10796 55614 43932 31715 29846 63695 7073 64064 22513 15175 15353 +57R4Q434VCJM 1 4166 20623 33137 3655 19821 22532 31395 15353 64304 +59VYMZBM75DT 11729 11443 1 2613 16916 65252 15915 378 3419 13454 7059 22270 3365 3655 967 19374 15201 19049 4166 1007 31715 61657 +5AZCZVAYBHRR 11729 61657 13454 922 72 437 9635 12393 16916 967 2477 65252 3365 378 43932 7059 1 3655 1007 1981 11537 12691 +5B4R93V2BCWC 5152 3655 11265 378 13454 3 11443 1 8715 293 2613 +5BAQ5KED5BPW 24394 7059 290 11443 65252 3 2613 21158 +5E8WHDKAQAVP 11443 1 24394 72 290 1007 +5EAXZRQY8NYR 21158 65597 +5F4YYQ7FTENP 72 +5FVWDKWH7VEU 54098 303 +5HBRWZ753JVV 1 922 3655 11443 63640 437 54098 65252 26576 30906 15175 5152 +5HN8RE4Z5N37 11443 1 7059 65252 11729 3365 +5JCVEXYHFT3M 1 19374 +5JJ8UNWNQ4CN 13454 4166 65252 64288 37047 24394 12393 44 2607 19049 42694 11443 7198 1 19374 30906 43932 437 72 65498 22270 3655 +5JP8HE9RFCKW 15791 1 3419 1866 3093 65252 11537 9876 +5K9UZWA3WQCH 1 42694 64304 63695 303 51716 +5MNMUBH9YK4P 11443 65252 3419 +5NM9KHJ62K2K 65252 3 3365 15915 437 12393 11729 1981 11443 1 378 4166 15866 2242 64064 15791 63081 17971 19049 3655 +5NWWATQMM6KY 15201 7198 4166 1981 15915 50039 17591 10796 3365 13454 273 967 3655 +5PF3TND42U7U 34578 17337 27139 19821 1185 43932 60694 30906 65203 11443 56489 54098 56668 65597 12191 65252 42694 63640 58249 19049 28084 2477 +5PZWNRXYQDUH 1306 1343 290 5204 8715 23775 922 61923 34981 22270 14126 48267 15845 15175 2607 62639 11443 10796 13218 13425 3655 12393 +5R4H33HWQNRC 1981 1 56489 58572 +5RJWRQ3WZF25 43932 10676 3 4166 17591 13218 1981 15915 12649 13425 56489 63640 +5RXPPQ6DPV3Q 1 4166 34981 64960 43932 3 +5T72RZXJ43MJ 5152 +5TPZJ52NH6AJ 21158 32200 23608 13167 922 15175 17325 34799 1135 11262 5115 37047 19049 23775 25047 7198 61657 15866 43570 64093 +5UBUADVFEWZ5 3365 1 11443 65252 967 11729 1981 31715 3419 43932 7059 922 378 22270 13454 15915 13425 3655 2477 4166 8715 16916 +5VAEWA9VXAC3 61561 +5VVK45PA6F5E 1 11537 13425 15791 19049 20623 378 15915 12191 2953 49655 61923 39553 187 54206 52027 15353 64064 3419 63640 1866 47292 +5WDTCMWQAKPW 11729 58572 3655 53472 1736 11443 1 18060 378 72 63274 28904 7198 16759 65498 64064 30906 62473 43932 28084 15175 63081 +5X8BP4B24R6N 11443 29846 65252 4166 8715 1185 1343 54098 28904 19821 26576 378 54449 3790 +5YXX7TBX6ZEU 5115 16403 23608 1 7198 +5Z54JHVRZKYU 26576 1 +5Z77BZMK4FZW 21158 +5Z9ZPZWK6URD 3655 21158 10796 10676 +5ZACRKHMQ6UZ 922 967 31715 15791 2477 10796 21158 3365 3655 17152 65252 3790 437 20623 9876 12346 27980 64064 3419 58249 47292 24492 +5ZUV3T52JJP2 4166 1 180 65460 15915 23020 10676 52027 13425 15201 58572 19821 62639 62395 +62UZ57PQWKU2 24394 65252 7059 +6325F3MUYPFN 13425 +63A59YZJM5TU 72 12184 28904 7059 6315 290 16916 62639 48594 22270 12393 +655U5K9UYMHN 17152 +6594X3CZ5WF3 16403 +65VTU67U92TB 13454 3655 2607 +6639D8R7KP3D 1 13454 16759 3365 61657 +66DF4RRZ8NZB 18060 29846 15175 +66MJ9A96A6R6 1 11443 3419 967 437 1007 3 922 57909 8715 12393 3655 3365 1981 7059 290 9635 13425 7198 64064 2613 15175 +6777N7JW35C8 1 11443 65252 2608 437 +696XC87J5YZK 20244 11262 10676 62473 3419 1306 11443 293 +69YDDPHRNZCM 33137 11443 378 +6A2BFD9DA23P 2613 31715 7059 22270 63274 65252 16916 967 43932 63640 26576 11072 2607 4166 1981 50039 3 378 15353 19049 15175 3419 +6AKVDCW4DB5H 1 3093 34578 17325 40542 17378 437 +6AN8MTH8UA6P 2242 27980 21158 22513 64064 3419 9876 56668 17152 2477 10796 1402 967 3655 20623 51716 47292 65446 12346 24492 437 3365 +6C8XE2XJH8JJ 11443 61657 65252 1 3365 61923 378 20623 30906 63640 9635 27980 7073 12393 21158 63735 4166 4699 53472 63274 +6CYXP7UC3RME 10676 43932 11443 +6DBNVZ9JRJHE 11443 3655 378 1 5152 2242 56677 437 4332 293 9652 8715 +6DFRTKKBMWC3 13425 3 65252 11443 43932 1 63640 290 437 1981 2613 +6DHU7QTCEPM9 46874 7059 +6DKVYWNY6J3Q 1 11729 437 54206 +6EXQ3CQ39XU2 46559 +6FR9CNRRXWF7 1 11729 11443 3 15915 +6JXUMV4PY242 57909 59118 1466 23020 10676 39553 2608 12941 22513 18060 6786 51716 59948 31715 64064 56475 +6KRPEBNFCH3K 4166 1007 65252 3 2613 15915 63640 63081 15442 16916 1 11729 17744 64304 3365 12184 3419 1981 10676 1866 922 13415 +6MN3B6C79FKQ 27139 17337 48121 28084 15353 +6PEWNZWPQZTA 26576 1 8715 922 +6PQQ3EKWVWEF 7059 31395 4166 +6Q66PXJJE2DD 1 11443 65252 15866 8715 13454 13218 437 2613 26576 3655 3419 43932 19049 22270 +6QYJ7NUWN3F2 11729 +6R8VWKPQK4MM 12191 61928 63274 14905 61923 63695 58572 62639 64064 +6RZF4AWUNDNJ 1 11443 58249 922 63640 +6T25M2FJR4U3 11262 61657 5115 34799 37047 65252 +6TCYNAHBYDV9 1 11443 10796 19049 42694 +6TEY7UTX7WQ3 27139 +6U5B2VTQ5J92 16403 1 11443 +6VEEKAQJHATJ 57909 47292 17743 62923 3419 49157 903 61923 46559 58249 14126 59948 12191 834 47839 12649 7073 65457 34578 +6VKB6Z87FKJN 72 1466 22270 +6W9UFQ8WP8E3 1 61657 2608 11443 3365 65252 378 967 13415 290 437 1007 273 27980 8715 11265 7198 3 13776 19374 3655 14696 +6XEWBDDBT2QP 16403 +6Y4NXUKKX78E 11729 11262 11443 3655 1 65252 437 5115 13454 8715 +6YUTYRH5UZN6 4699 1 378 11443 11265 5152 13454 8715 65252 3365 +6Z5J56BE9EFB 1306 290 7059 +6ZFF4TVD3VD4 63640 967 10796 19821 17743 65252 53472 1185 8715 15175 18060 54449 63735 27980 55614 13454 16916 29846 62639 3419 11443 1 +6ZKFK6Q4ADKU 54098 17378 11443 8715 5204 31395 65597 12191 1681 34002 48594 11262 39553 23608 4332 14696 58249 1866 2607 7073 62639 834 +722NPZA9HEE9 65252 31715 3419 10796 +72M6NR9KDWTK 17152 +733KMAJ9CNEZ 11262 +7375XDE77KE2 1 72 4589 3419 20623 273 1007 52027 28904 922 3790 +744K3ZVVYDE2 31395 19049 8715 11443 2607 22270 15175 13425 42694 10676 +74539B5RT3H6 1 11443 13454 16759 +74URQMUNAJYK 54206 63081 15845 +75MNVVYPN237 1 11443 4166 3655 5152 18060 63081 65457 29846 10676 +75VHVPAQQDEV 9876 12649 33137 3655 19374 17378 +76E6RAP26TFY 7198 +76T5X8DNR92T 1 13454 11443 1007 22270 11729 13425 15175 64064 7059 63640 1185 3365 18060 437 12184 16916 967 72 12393 3 15866 +788XPCM7AFZP 28084 1 14126 72 65252 17337 47839 3365 19821 63695 30906 19374 65498 13218 2613 59118 8715 62395 19049 10796 43932 61923 +78KKAZ56UXCF 11443 3365 3419 13425 1 1007 13454 437 967 378 7198 65252 16759 922 2613 +78TZDC4E33AH 1007 11443 2607 8715 22270 65252 3655 34981 378 3365 2477 8790 63081 12393 11729 57909 20244 1 +794Q6WYBZVQT 11443 57909 16403 61923 180 65252 46874 3 22270 20244 922 13454 1343 30906 43932 1 1981 2613 4166 65321 10796 19049 +79A24W86RZ48 57909 37047 63640 46874 18060 12346 42694 22513 48594 2608 5152 47839 22532 53966 58572 +7AC4UHHHQJHT 1 11443 65252 +7AU3PY3UUJRN 3419 31715 11443 19374 2613 65252 31395 9876 15791 54188 72 967 7198 11262 4166 12346 1135 51716 61657 17325 23775 3655 +7B3C64ATZ7P3 13454 11443 61657 1 378 19374 16759 922 3365 65252 3419 20244 3655 +7CTUWRXMA8DX 1 +7D35C6NQM78D 19374 11443 31715 19049 15866 15915 4166 11072 63274 2477 11537 1007 16759 7198 378 15791 16916 14696 1681 293 9360 22270 +7D5A7MBVBTNE 72 1 2608 +7E35Y7FKUQPB 1135 13425 11443 1 30906 +7EA8EZBTNAHQ 65252 1 13454 11443 378 3419 11729 2613 3365 3655 16916 967 1007 437 7059 15915 17591 1981 31715 72 3 16403 +7F3H8KTRWEEU 11443 1 15791 64064 61657 20244 63274 17743 43932 4332 967 21158 12468 22270 17971 437 13425 +7F77QZ28AWXX 1 4166 63640 17744 +7H8T6R5P3AP8 13454 922 1 5204 13425 11443 63640 8715 31395 +7J7YUUEY5Z6Z 1 273 11443 29846 39553 27980 +7JCB8D6A99NA 43932 1981 3 1 15915 10676 15175 11443 8715 +7K5DHVYN3K4A 19374 11443 19049 11072 15866 31715 1185 65252 10796 4166 378 11537 293 16916 7059 1681 13218 16759 12649 15791 20244 3365 +7KA4XE6EDNW8 57909 61923 59118 61657 15791 36911 22270 5204 11729 1402 49655 65498 53966 19374 15353 62395 42618 1466 15175 12393 +7M6953KKH2R9 3419 +7MFUJWT784Z2 1135 28084 30906 4166 17744 13425 3655 33137 61928 12346 39553 63640 931 43932 27980 57909 29846 922 14126 11443 62473 +7NC94JHKZPZN 16403 34981 17850 17325 11262 5115 +7P6BMZBBDYNH 57909 3419 64064 65597 18060 16129 61759 6315 43570 61657 34981 44 54188 22532 63229 32200 62473 65446 56668 58249 59118 65203 +7QNPQUJZU6E7 1 378 65252 11443 1007 11265 5152 11729 3365 13454 10796 16916 1185 7059 3655 3419 20623 +7RA6UKHHJH83 13454 11729 61657 +7T24JKERU4FF 1 24437 30906 41676 11443 63229 34578 19374 8715 8790 31715 63914 922 42618 34981 19821 2607 29846 56475 31395 16759 44493 +7UBMH37F495J 1 15791 3419 11443 3 7059 3655 +7UJTJQRDRU3C 922 1 10796 8715 29846 63640 11443 43932 19049 13425 3655 19374 13218 31395 3 2607 42694 +7VHY2RMFU34Z 12184 +7VR3JZM7CB3X 12184 290 19374 16916 8715 +7WQ8BPY7RF5F 16759 1 9652 378 60694 1681 9360 42618 20244 65321 +7XPER8H9NZ5M 290 72 1 1306 1343 11443 437 +7YN8KDZ4P5CM 11443 1 13425 10676 13218 30906 2607 43932 3655 34578 12691 10796 15353 7073 3093 31395 61923 19374 42694 922 54098 15175 +7ZF2K3MVMPEY 11729 11443 1 378 13454 11537 922 15915 72 1007 64304 8715 12184 290 65252 +824VWNDWFK2B 3 13425 15845 15915 2613 15201 63081 43932 4166 58572 1981 12941 17591 180 10676 1866 1185 23020 49655 48594 62395 62473 +8285JKPPZ574 16916 11443 1 21204 +82DYVY9K2YMA 16403 +83K9UJ49F72W 6315 1 4699 11443 1007 58572 16403 437 1736 8715 290 9360 3419 7059 22270 13425 +83TCYFD6UKRE 13454 16759 11443 63229 10676 8715 20623 1306 1 49755 39553 54098 14905 15353 903 +84RJQZ28CJQX 967 +84WYPQZKTYJA 16403 5504 +855JENRM6EK2 4166 23775 23020 17744 22532 61928 16916 15866 1 2953 2613 47292 1306 31715 187 +85ZDEUNBJM42 1 11729 11443 922 2613 13454 5152 3655 12184 15915 61657 20623 65252 378 1343 15353 10676 65498 +866MF3EDE4Q5 15915 3 43932 11443 13425 13454 1 65252 +86K229AQMWTW 13425 2613 10796 7059 63640 31715 22270 8715 11443 65252 12184 3655 5204 922 3419 63274 16916 11729 3365 290 11262 15201 +87M457E5EXNQ 15201 65252 922 967 1 11443 72 13454 13425 437 17152 +88WQ82WQE3DC 1 11729 3365 13454 16759 11443 3419 1007 65252 16916 +8939ZTNDW6Q7 3 13425 15845 15915 2613 15201 63081 43932 4166 +89BPUU3R6CWH 72 44 1135 2477 9635 31395 18060 +8A25DY5BWETB 65252 1135 31395 32200 20919 19049 7198 11443 5204 53472 +8A2KKWHE2YHM 5115 11262 23775 17325 23608 37047 +8BAFQJ753HCQ 57909 7059 7392 56668 65597 1 41676 3093 23831 46874 63081 17325 3790 63640 6786 34041 180 9652 60694 17850 1681 15791 +8CPWMV97XUV7 63274 16916 10796 1736 22270 7059 2607 3419 1 11443 3365 437 1007 +8DBFMUA8XP7U 967 65252 4166 2613 15201 43932 15845 17591 15915 1866 3 62473 58572 13415 922 13425 1185 22270 57909 63274 9360 13454 +8DUDD7N5PYJJ 26576 63640 22270 3 437 1185 7059 +8E5CF2P6A2XP 2613 31715 11443 7059 +8EXKUENAR5W9 1 11443 2242 21158 27980 47292 922 967 31715 15791 2477 10796 3365 3655 17152 3419 3790 437 20623 24492 58249 1402 +8F6QHHWBCJQM 61657 1 11443 7059 65252 2613 290 53472 65457 5204 3093 15175 16759 3365 56489 437 12184 3419 72 378 13454 1981 +8FUCV4NTJD5J 57909 61923 65457 43570 62473 2953 2608 7198 9652 51716 64304 23020 23831 29846 23775 3419 14126 47292 37047 39553 9360 41676 +8H962JEVDKQR 11443 1 922 12649 15791 31715 7059 15201 290 65252 19374 2613 62473 7198 3419 15866 3365 10796 2477 21158 43932 10676 +8JW5M35FXYB5 2608 19374 12191 14696 11072 21158 22513 +8JZJRQF59UJZ 16916 63274 28904 72 17378 22532 +8K6367FU7VRB 4166 15915 15845 10676 378 11443 8715 1 72 43932 1007 12393 7059 437 3365 65252 13454 +8KABJ24Q526M 437 15353 903 3655 16918 13425 187 15175 23775 31395 23608 11443 7198 2607 58572 47292 63274 13218 17325 19821 5115 56489 +8KZ9CDFHZAM7 1 4589 9652 11443 9360 44 19374 +8MXCVQBEMYQN 46559 +8PHA5VRTTV9P 64064 62923 +8PT46PF6CMX5 33137 7198 11729 7059 63274 2477 57909 3365 15915 13454 9876 922 22270 12691 967 13425 15201 3 9635 11262 273 7073 +8QAV73E9MPX9 8715 1 11443 65252 54098 1007 19374 16916 46705 +8QPDJMJPVWY7 1 11443 72 65252 3419 4166 437 16916 +8R3JJHVXHVKQ 37047 64081 11443 3419 18060 42694 34981 7073 63274 63229 64064 +8RBDE5MV4BCZ 2613 11443 10796 290 1 +8RX6AC477AU9 7198 7059 9652 19374 53472 290 19049 22270 15866 13425 16916 8715 16403 31395 1185 21158 3 +8T3B4PWZR6F5 57909 61923 15791 65446 14905 21158 23998 15201 34981 28084 61759 11537 65321 63081 6786 9812 48594 9635 16916 63274 1135 34041 +8T79EUY4XEX2 28084 15353 1 11729 437 65252 1007 3655 13425 7059 11443 3365 8715 +8U7W7WWRFU7Z 2613 967 31715 9360 65252 4166 7059 11443 378 3655 15915 3 43932 3365 437 10796 17591 15791 5204 13425 2477 922 +8UN8D9HA6N3P 16403 3365 +8UQE4WNEPAVP 22270 63640 7198 16759 10796 2953 34799 1 42694 12393 922 63081 64304 8715 21158 187 1402 12184 3419 437 7073 57426 +8UR8KWHAQXJH 11072 +8VZVMV86NWBR 11443 1 290 2607 63274 8715 29846 22270 13218 42694 12393 23893 10796 12184 19821 54098 64064 43932 17378 63640 24394 28904 +8WRDJEVXC9WC 11443 11262 31395 1 65252 11729 +8WRXDYH27W6T 13454 1 20244 30906 11443 10796 +8WWXADYXD6RX 16403 +8X7WARP9Q4EN 58572 11443 1 12393 20244 3419 922 437 8715 42618 13425 30906 39553 65252 14126 1981 12649 967 +8YZ7UF9M7KD8 57909 5152 19374 32200 2613 63640 12184 +92KXRMJ39Y7F 56489 8715 290 7059 1185 72 922 15353 10796 1 437 12184 11443 +933JB9HJ3RQN 11443 54098 1 +93645UZDC3XB 11262 25047 5115 13425 37047 61657 65252 +93A9ZD6WJBZ7 11443 13425 1 26576 290 2613 10796 13454 +93UXK5HWBJZY 2613 1981 3 13425 15915 4166 65252 17591 967 28904 43932 9360 7059 437 10796 5204 3655 922 2477 378 11443 15791 +96U2VUYW6XYU 1 15791 378 11443 1981 2608 19374 58572 3419 65252 +978ER8FZQUFD 18060 2608 903 14696 21158 47292 2242 15074 44 15175 922 43932 58572 10676 12191 11443 9635 12184 13454 +99YFYVAAVD4N 1 16759 20623 11443 2477 3655 56668 922 +9CBZPCUJX8RM 1 1007 922 967 7059 2613 12941 31715 15791 2477 10796 21158 3365 3655 17152 1306 3419 437 3790 +9CV5FT8PBPUJ 11729 22270 19374 11443 20244 16759 1 437 2477 65252 10796 3 61657 4166 9635 16916 2613 63274 15791 21158 12691 31715 +9D52TTTXUUAD 63274 8790 22270 44 16916 7059 10676 11443 +9DMRFCNRQPKV 57426 63640 16916 7059 62639 12184 12941 1736 13425 19821 922 20623 8715 +9E3ZNX8UAK6D 20244 13454 967 922 437 9360 22270 46705 11443 2613 19374 1007 11537 2242 17591 13425 1681 3 15915 43932 378 293 +9EKFJ8R7WTKD 11443 378 437 1 9812 1681 967 1981 26576 10676 13425 10796 65252 3419 57909 2613 72 15915 8790 13454 2242 12393 +9EMBQX6B7ABZ 1 2477 378 43932 64064 56668 922 20623 3655 11443 65252 967 437 13454 2608 3790 3419 +9HCM6Y3QUMP8 14696 +9HRAD4ZW5FTT 1 11443 437 10676 3419 +9HRQDEUH456U 21158 +9HV42YV4MJYE 12691 14696 10796 63081 3 967 17743 11443 13425 1981 13454 1 15915 +9JMBBCE9TJ5M 7059 3 2613 16916 3365 63274 4166 65252 3419 8715 17591 19374 15915 437 24394 1185 1736 22270 290 1981 21204 15353 +9JY3B3QYADZU 28904 13776 1343 62639 +9K27VZNTNMQ3 11443 8715 15866 922 3419 2607 1007 31395 19049 1 43932 15353 1343 +9MCBXYZPKEK3 40542 12941 34041 2607 1007 16916 8715 53966 63735 1185 2613 19049 49755 37047 62473 62395 22270 26576 59948 23020 14126 3093 +9MKQZUMU6MTE 11443 2613 16916 72 15201 1 65252 3419 31395 4166 3655 7059 +9MU3TTJ3P4JT 44 8715 11443 13425 1007 2607 31395 15175 +9PM5DWUAWRFX 11443 3655 12184 63640 13218 1981 378 922 56489 3093 31395 72 1306 +9RD7W69QCHX7 11262 18060 1135 +9TUN33BJWQW6 16403 20244 273 +9VEJ27KUD5B2 1 8715 12393 437 273 63229 +9VNZXYDW6FCN 8790 922 16916 +9VXVBWYWWBMU 57909 37047 65252 63640 15791 61561 59118 41676 46874 18060 12346 42694 22513 48594 2608 5152 47839 22532 53966 58572 44 1981 +9W28KUNMZ32R 65252 1 3 12184 10676 +9X2UJKTQ7YHJ 1 11265 437 378 3655 +9X8Z9J9H3VDZ 63274 65252 +9XXWDF2UUWFH 10676 7059 290 19374 72 +9Z2E326KEPFA 11729 11443 1 65252 378 13425 290 10796 15915 922 12184 2613 16916 22270 17591 3419 7198 3655 15866 31715 13454 3365 +9ZEUJVH5C5EW 11443 43932 1 4166 54098 65252 1007 +A29WTTD6ZWEH 1 3 11443 64064 3419 3365 967 13425 1007 437 378 17591 13454 57909 10796 63274 9635 15201 922 8715 65252 31715 +A35J7JE33WFF 1 3 15175 64064 10796 30906 13167 378 7198 +A3QYQUFEB65E 1 11443 65252 1007 437 28084 180 2613 3 967 +A43TKD6THC7R 65252 43932 3093 3790 378 11443 2613 72 64042 437 7198 290 29846 63695 +A44WP8HBNX7P 16403 +A58D76EKUWAE 64960 +A6MF998R4PPA 65597 11443 2608 15175 12393 437 13425 63640 1 1135 49157 +A6VN8ERNA96Z 1185 +A79D6QUMD2A3 57909 +A8CUCK7T9CUT 1 11443 14696 19374 12191 2608 290 3655 8715 967 437 +A8P4D5XXAX6J 21158 22513 +A94H4FT8AWMC 1 22270 12184 +A94YPHYBUTCQ 1 3419 7059 10796 15915 1007 72 11443 1981 967 19374 7198 3365 922 3 437 65252 12941 15866 63274 13454 14696 +A9Z8U8D95AXJ 65252 9951 967 1 11443 437 1981 +AAWDK4P329A2 11729 3365 1 3419 11443 3655 65252 33137 13454 2608 12184 15791 7059 15866 378 17850 7198 29846 4699 62473 13218 16403 +AB8TCJBR6AA9 5504 +AC29FZYKCZ66 1 11443 57909 72 65252 11729 13454 2613 3419 10796 8790 1007 12184 5204 1981 +AC37V75UBM7B 23998 13454 1 17378 64288 +ACQY3ZM27XVR 17850 11443 1007 +AE4Q89NZMHV5 13454 11729 11443 1 7198 +AEDY33EMWQME 19821 +AF6RZ38PMRF6 11443 13425 2613 43932 10796 922 3419 13218 19049 42694 65252 1343 30906 65498 19374 15353 27980 31395 2607 12691 3655 +AH73HP8634WQ 57909 59118 61923 1466 23020 10676 39553 2608 12941 22513 18060 6786 51716 59948 31715 64064 56475 22532 +AJ5B5MDDWKDN 1 11443 30906 56677 922 54098 3093 1981 967 7073 15791 8715 34578 1185 19049 12468 1007 4166 1402 27980 180 378 +AJ8P3JMRPVEY 13454 10676 16759 22270 11443 15353 10796 8715 15175 1 +AJA24KCFY58D 1 11443 65252 13454 967 3365 378 20244 437 10796 +AJCZ9D7A4DQQ 8715 187 11443 17337 1 19049 +AJD7DRBFE8MJ 5152 +AJE2T3Y5DPX3 1 11443 11729 3419 3 13454 65252 2613 65446 1981 437 72 7059 3655 +AJQ59A7AHR8P 11443 8790 1736 10796 1 12393 9876 3419 3365 2242 54449 43932 2477 13425 +AKEXWXDX9BZ3 11443 1 437 3 7059 3419 7198 12393 1007 1981 3365 11729 922 2613 19374 1736 967 13425 61657 65252 72 273 +AM2FND48K99E 4166 15201 49655 3419 11443 12184 +AME6XRX27NPB 2608 1 +AMQYA5TY59BT 15845 1 11443 4166 63081 437 54206 22270 13425 19374 37047 +AMVNX5D63C9B 16403 1 11443 17850 3419 +ANK22HTYNWHX 63274 13454 +AQJQFE58FFQU 11729 11443 3419 65252 13454 922 19049 8715 20623 16916 3365 +AQZRT3AV532F 11443 11729 72 1981 13454 3419 3655 378 +AR25P4Y75WPX 922 8715 11443 9360 1 +ARD8TXCAH2VC 1 922 56668 2613 72 39553 64064 62923 49655 14905 3655 42694 3419 +ARX9VK8FATDH 3365 11443 378 2613 1 65252 1007 11729 31715 5152 72 11265 922 12184 43932 4166 20244 9360 16759 20623 10796 11537 +AT3DVBWWUWRQ 57909 61923 59118 1466 23020 39553 2608 12941 22513 18060 6786 51716 59948 31715 64064 56475 22532 9876 +AT69K2V6F5VM 65498 +AVDEY5WZW8PE 11262 34799 61657 5115 37047 25047 17325 13425 7198 3 23608 5204 13167 8715 1185 922 1981 +AVE7NY7EEYZY 65446 3655 12184 922 22270 8715 56668 54098 63695 72 22532 +AVHJNRA9F9TN 46705 16916 +AVJQ79ED67RU 11262 61657 37047 5115 65252 22270 10796 25047 64064 2477 17325 72 1981 378 13425 21158 3 34578 437 967 9360 2613 +AW9CTRNKR7M4 28084 3419 967 11443 437 290 17337 1 1007 61657 +AX5JRY4853PJ 11443 1 65252 10796 290 437 15791 +AX82QYEYKXDT 11262 37047 +AXDK63X2PXA4 11443 3655 +AYDFJA8HY5M2 11443 1 20623 8715 15175 34799 23608 31395 +AZ5QWUPPD475 57909 61923 59118 1466 23020 10676 39553 2608 12941 22513 18060 6786 51716 59948 31715 64064 56475 22532 9876 64288 303 49655 +AZJ5ZVJJB7PZ 13454 11729 61657 16759 3365 10796 58572 65252 922 72 1007 20623 437 8715 4166 +B2ATPCTCNHQ4 3790 3655 64064 2477 20623 56668 922 15201 3365 43932 4166 10676 2613 11443 2242 13454 16403 15353 19821 63914 49755 31395 +B2BHWWTN3VPT 1 9360 11443 20244 922 +B4NXRQRXYVDQ 378 11443 65252 8715 11729 4332 9812 11265 5152 17971 10796 2613 19374 57909 2242 15074 17743 16759 13454 1 +B4Z3WNBVAFQN 23668 56063 1007 64064 +B5B7KZ8J3NP8 11265 11443 20623 8715 378 1 437 65252 +B7KJ69AZ2M6A 20244 1 1007 13454 11443 65252 378 922 57909 3365 2613 4166 3419 967 11262 10796 15915 3655 31715 64064 180 15791 +B7QE4DBPV9J6 12184 437 967 13218 11443 3419 22270 10676 63274 72 3365 13454 290 13425 43932 19374 378 11729 64304 15353 15175 23608 +B88QZADPWJJX 3655 20623 +B8M8DWHP5VV5 63081 +B8RJPNQ73C8W 11265 11443 1 378 16759 11729 13454 1007 13425 15915 57909 3419 7059 22270 967 922 3365 17971 15791 3 1981 10796 +B8UR2QMXY9RV 57909 61923 65321 37047 65252 63640 15791 61561 59118 41676 46874 18060 12346 42694 22513 48594 2608 5152 47839 22532 53966 58572 +B8UU2JRNB55A 437 11443 1007 290 3365 1 967 13425 12393 7059 13454 3419 11072 16916 15845 1981 15915 65252 3 2613 +B8WX37HUP8CW 1135 +B9PJB5FDZN9H 1402 1 11443 11729 65252 967 3419 3655 +B9QRT56F86E7 1 11443 30906 3419 1736 65252 54098 3655 15175 12191 +BA54MEDCHRF4 13454 1 834 5152 903 43570 44 64064 27980 1402 16916 11443 7073 22532 65505 922 24394 34002 12393 62923 +BA6VC68BWZ7Y 17744 15201 58572 5504 64960 1185 3 13218 56489 12649 13415 49655 23831 59948 1981 180 9951 15915 43932 64304 47839 65460 +BA99WFEJUARV 11443 1 2613 7198 3419 29846 378 64064 12393 1981 437 15915 65252 11729 3365 4166 13454 3 1007 16916 15845 61657 +BC5EAZDJVXC4 1 3655 922 12346 11443 3 4589 15175 54098 44493 65457 1007 65498 65203 2477 64064 12941 19374 903 8715 16918 30906 +BCRUYUK93PTA 11729 7059 11443 65252 13454 1 10796 922 5152 3365 378 3 13425 3419 437 15915 1007 16759 72 19374 17591 1736 +BDR5JX9BUV37 16918 17378 187 17337 1135 15353 41676 20919 46705 12941 19049 1343 180 27139 5152 49755 +BFKU9WJPBW3M 290 19374 16916 11072 22270 28084 2608 7059 1343 46705 12184 24394 18060 15353 63274 27139 2607 19821 13415 12393 65252 3365 +BK6KDC7XQRNV 1 378 65252 11443 1007 11265 5152 11729 3365 13454 10796 16916 1185 7059 3655 3419 20623 +BMAU7QXBN4FJ 43932 19049 54206 61923 17591 12184 7073 3790 12649 57426 63640 15175 64304 15866 17971 17152 65252 15915 23893 16916 72 63274 +BMPDUT9JBP6K 967 11443 378 2613 9360 3365 15915 65252 4166 22270 3 43932 7059 10796 11729 15845 17591 12941 31715 1981 16918 15201 +BN2JPKKWB7BX 18060 +BN7RJDN29WYK 1 11443 63274 2613 16916 53472 15866 31715 +BP5NMURRTMUN 57909 11072 9812 61923 58249 14126 +BR4MA8RE6RBX 1981 967 15915 3365 922 4166 43932 22270 1681 3 11443 26576 17591 13454 10676 3655 13425 1185 65252 13415 12649 13218 +BRK2XVRKMNW4 57909 61923 59118 1466 23020 10676 39553 2608 12941 22513 18060 6786 51716 59948 31715 64064 56475 22532 9876 437 64288 +BUN755RHTZYQ 1 11443 72 3419 58249 62639 +BUUKD3DPYB3J 13425 11443 4166 3 43932 3655 11262 31715 967 3365 378 9360 10796 437 1681 922 293 2613 19374 22270 63274 13454 +BUW8CUU5DFW4 11729 1 65252 11443 3365 3419 58249 3 11537 922 63081 +BV7PXCX8J235 61657 65252 1 17591 11729 72 1007 9635 16759 22270 903 56668 11443 7392 63274 2242 290 3419 8790 62923 31715 13454 +BVDFY7CH73JU 3365 1 11443 4166 8715 +BWRMWB5CEMY4 11265 11443 378 +BXU9HVRDA4KW 1 11443 57909 12346 2607 12393 31715 63914 +BXZKYTJX9257 1 19374 65429 12691 1466 54188 59118 65498 10796 44493 3655 18060 2607 14696 15353 62639 30906 3093 8715 57909 11443 1007 +BY9RZ74TQP4E 64093 7198 3655 36772 17337 57909 62473 16759 34799 50039 931 12649 62639 24492 23831 65203 47292 2613 27980 4166 23668 15915 +BYD94Q464R2A 1 931 46559 11262 +BYMRNAMFTZD2 72 +BZRQ53A3KZPF 23668 11265 23998 8715 49157 17744 +C2JF6MFBU2ZZ 72 11729 1 12184 1007 3419 +C2ZMJJQFNA7H 33137 42694 1007 7198 1 17971 37047 15915 65252 34002 15866 44634 3 56489 20623 63914 +C33Q52Z5A3MW 3419 11729 65252 13454 3655 61657 13425 16916 11443 1 15175 3365 378 43932 7059 967 5204 72 3 922 1007 15915 +C3R78EZDBD93 15866 11443 43932 47292 922 15175 54098 31715 34578 31395 3655 13425 15353 10676 3419 27980 61923 65498 30906 2613 19374 39553 +C45497E3D6PU 13454 12393 8715 65252 1 11443 1981 15915 +C45MAN24BHJP 1 65252 11443 3419 18060 2608 12184 72 20919 11262 11265 180 34041 31715 58572 3655 31395 19049 +C48R46RYKXEE 8715 11443 1 13454 22270 2953 12941 43932 378 19821 3655 13425 17744 +C4AMX8UFJHR5 61657 15175 11729 1 +C4E7FW5C5QQN 17591 15915 4166 2613 3 13425 43932 15201 1981 1866 15442 13218 12649 15845 967 3655 437 21158 15791 3365 10796 922 +C4ECPZ59BC9R 17152 +C5A3AAWCFY24 1 +C5DPCK6DRKCU 1306 290 1 72 967 437 8715 34578 11443 12393 +C5MZH8A9JZ2V 1 11443 17743 10796 378 72 437 14126 6786 +C5YN9K3TXPHC 16916 +C6KVJJTM5UPC 57909 17325 16403 34002 30906 61923 61928 16918 6315 1402 7198 12941 12191 25047 5204 2953 6786 24492 44634 +C6NJCFDJQTUH 1 11443 967 22270 72 10676 3419 23893 13425 65252 1736 13776 54098 6315 19049 64081 10796 65597 2613 34002 15175 3 +C6QEEAP8N9BV 65252 3 1981 1 437 9360 4166 378 72 3655 1007 8715 11443 15915 19049 9876 +C74E5RNDF8QE 11443 1 967 11729 65252 10796 17850 16759 49655 18060 43932 1007 63081 12941 3 +C7XK3WKZ5CDY 11265 63274 1 2608 19374 14696 4332 13454 +C8CQNDXEW273 13415 8715 65252 10676 43932 42694 19821 44493 9652 19374 +CAMEBF9BQ4Q4 5152 58572 16918 48121 12393 +CCY44DQWAWXJ 65252 61657 13454 967 1 290 3655 13425 3419 11443 5204 11729 +CCZJU5KF3X3T 1 12649 180 +CDN4DR4NBNE7 65252 2607 22270 13425 922 63695 30906 2242 4699 13454 437 3093 17325 20244 58249 15353 7059 29846 65597 15175 11443 26576 +CETZFXEHV3H6 2953 +CF388FZE43KK 1007 13425 1 44 23998 16403 23893 2953 16916 1185 11443 41676 56668 42694 1981 17744 303 903 22270 31395 31715 15201 +CFAPKM6TA6UT 5152 +CJMFFBT2M7FQ 1 11443 65252 180 2613 13218 1981 43932 3365 16916 290 50039 72 +CK2N7A33M7NE 1 29846 8715 15074 23608 63640 44493 34002 +CKABMCZBED84 7073 1 11443 378 65252 1007 57909 33137 11729 +CMQJ6KXWJ59H 11262 65252 13425 5115 37047 11443 1 +CMYXJPD7ZNDQ 11729 3419 7059 2613 11443 16916 3655 967 65252 56475 +CN9MCCATV4NB 34002 13425 9652 2242 64064 290 7198 1 1681 12393 63274 2608 437 9812 10796 72 19374 15201 11443 8715 13415 62639 +CNJMTDTFKANR 1 2607 16916 65252 12393 11443 63274 12184 2613 72 3419 11537 7059 22270 26576 437 3365 13454 967 1185 8715 922 +CNVUW98UM4TX 1 8715 10796 4166 53966 44493 20623 63081 17152 3655 967 +CP55YDKNJJ9D 11729 13454 3365 11443 3 1981 +CPNFFZV6TTQ7 11443 3365 3419 17743 1 1007 +CPVAW4N9RV2Y 15201 +CR6R6T9CA6P8 922 967 31715 15791 2477 10796 21158 3365 3655 17152 3419 3790 437 20623 9876 12346 27980 64064 1402 +CRMVMYUZTWMC 13454 11729 +CTU3VFAW5XTT 10676 25047 +CU3CYDPDKRN6 3655 1 437 16759 4166 31395 63640 290 51716 11729 10796 13425 65457 180 2613 19049 1007 3419 31715 65252 43932 11443 +CVC6NTMW7U78 63274 1 10796 +CW8K5RX3ZTR2 65252 437 11443 1 20623 15791 10796 3655 +CWA9WMJMXCP8 54098 +CY3NMN8VJTJD 1 11443 11729 65252 10676 1007 2613 8715 57909 22270 +CYXYUWV33HDC 10796 65252 1 13454 4166 16916 11443 31395 31715 437 64064 57426 7059 15791 7073 3419 3655 +CZ3FXX8QQ2Q6 65252 2613 1 11443 3365 15175 437 43932 967 3655 10796 16916 16403 378 4166 31715 1981 17591 13454 3 52027 12184 +D355T8YMBZJM 1 7198 187 5152 63229 7073 11537 1007 1736 11265 44493 17971 43932 13415 11072 15866 17591 +D3E6TFTZ7DRW 1 15845 11443 4166 967 43932 64064 +D3KXM2DYKAJ2 5204 46559 922 16403 1981 13218 5504 43932 +D69NE8XM8XTM 1 11443 11072 12191 3655 14696 65252 11729 19374 3419 2608 63081 1981 4166 +D6HFNER43799 11729 39553 +D6M2CU78EWNM 11729 11443 1 65252 16916 2613 13454 7059 15915 72 19374 967 12184 16759 1007 30906 3365 23668 23893 17591 1185 11537 +D7D75DEPX5JC 15175 2477 +D7M4VMW6UBER 16403 +D87X2JTRN32U 378 11443 11729 65252 3365 1 8715 3419 1007 19374 13454 2613 13425 922 43932 437 5204 5152 10676 3655 +D8976PN33EJ9 1 72 2608 19374 +D9EFPHVNB288 11443 1 22270 54098 12649 +DC2NV4FANM7E 11729 72 65252 1 40542 11443 13454 378 16916 3419 1007 1185 10796 8715 58249 12649 50039 +DCR9N485TPZF 13454 11443 65252 437 11729 2613 1007 1 3419 3 3365 922 72 967 16759 64064 +DD97YTB3A25R 1 11443 65252 +DEWM6QW6DCKR 29846 +DFH2U8F3DPP4 11537 19049 +DJXR5Q6F2QFP 1 11443 10676 13425 +DM3QP29QBNYP 6315 1 1736 11443 58572 437 24394 26576 12393 1007 4699 9360 16403 1466 +DMZV48P4RMPU 64304 1 61923 13454 180 2613 12941 65252 11443 378 3655 63640 +DN69Q7RXWVYJ 58572 55614 +DPF7W4JA5YJP 11443 13454 1 3365 22270 21158 15915 180 3419 8715 +DPK3K3WM8AN3 11443 19821 1 48121 28084 +DRCXDHFMD3RC 11443 378 65252 11265 19374 437 3419 17971 22270 9812 10796 3365 922 967 43932 15915 10676 293 8715 290 13218 11072 +DRUKRNAVR7YQ 65321 34578 61657 10796 31715 13454 64064 30906 61923 3655 54449 3419 42694 +DUJYWK2EKP38 23608 11262 37047 5115 3 65252 11443 1 290 61657 1007 1466 42694 19049 25047 15175 15866 64093 53472 293 32200 31395 +DUMA99735WWQ 437 1 37047 11262 21158 17378 19049 58572 1007 20244 1981 49157 65498 54098 61561 52027 15201 63695 64064 13218 61923 187 +DVW2FANQNBA5 11729 1 11443 65252 13425 22270 10796 +DX9M32PQKMYD 61561 +DXV85Y83EU3P 9652 1866 10796 1 +DXVCE89UCY93 11443 13454 65252 1 72 437 3419 42694 1981 +DYW5XRM7ZWE3 65252 11443 1 3 437 10676 43932 4166 58572 15915 +DZ6PNAQAFVN5 11443 11729 13454 3419 290 1 10676 65252 378 +DZHU3AVHHJVX 11443 1 3365 15866 72 65252 1981 13454 3419 11729 7059 +DZTC437PUTHN 16403 1135 +E286V6Q8XAMQ 437 11443 15201 72 1 3365 65252 42694 63640 13454 10796 17591 52027 22270 8715 63081 15915 8790 378 7059 +E2PYRZYCT9WJ 16403 1 14126 10796 16759 293 43932 47292 61923 56475 64064 922 3655 15175 19374 8715 34041 65203 54098 8790 3093 17743 +E3B6DZ6CNETY 1 4166 53966 +E3Q85E9D6JZT 290 1 61657 1343 7392 22270 2613 +E4QXPPXPUK3W 1 11443 3365 13454 1007 11729 65252 378 967 4166 16759 3419 3655 8715 7059 19374 11072 7198 63274 31715 26576 922 +E57XV89NE7AV 53472 8715 13218 2607 34799 56063 1135 24394 1 +E6DRHZZWJQRP 1 3365 63274 7059 18060 13425 4166 967 57909 378 7198 11443 1736 12393 2613 290 437 65252 1185 10676 3419 +E72NZT4YZPQB 12649 65252 13454 3 17591 11443 1981 2613 1 1185 42694 +E7V8FMPXDMMD 1 8715 11443 10796 13218 56063 61923 2607 15353 54098 19049 903 14126 +E9VRVXPZYDE7 3655 20623 2242 2477 56668 437 922 378 967 15915 13425 3 4166 3365 10676 1981 21158 17591 11443 65252 3419 43932 +EBC56CV8UU8C 11443 11729 13454 1 13425 65252 378 15175 1007 +EBENVXH7BK2R 15791 3655 3 15915 922 1 65252 11443 31715 3419 437 +EBJQRQXZBM3Y 11262 65252 61657 21158 5204 5115 37047 23608 25047 34799 17325 19049 3655 15866 9360 +EBTE979DVET3 11262 61657 5204 23608 17325 34799 13167 25047 +EBVJ749KTA2T 3 15915 13415 12649 13425 2613 +EBY5HM5PN357 1 11443 63081 15915 1007 3365 15845 967 11729 20244 1981 4166 54206 3093 378 3 65252 12393 12941 13425 15201 3419 +EC5UCTNHA8P5 1 11443 1007 11729 +ECNAMXQKN69T 11443 3365 13425 437 56489 7198 1402 26576 21158 13167 15442 903 15915 44493 53472 17152 3 8715 63640 10676 12393 1 +ECRHZ2QKAMXM 11443 1 8790 15353 1306 1135 3 3655 +EDFC5W2DQU6R 11443 1 11729 378 12393 437 19821 7198 290 +EF2CAWH33AEA 3655 20623 11443 1 56668 1007 14126 437 42618 967 1981 13218 23020 290 922 16403 22532 61759 72 47839 13454 2477 +EFHEPE4Z2R38 13454 13425 15175 290 3419 1185 +EFZRJ7FM7UX7 15866 19049 1 19374 378 11443 11262 13425 3365 2613 16916 65252 7198 8715 1007 10796 967 922 9360 3419 437 43932 +EFZWT24NXQC7 12468 1 11443 10796 16759 65252 2477 13454 +EH5TK5Y8B8AA 1 4166 3 12649 15915 7059 11443 65252 11729 17591 62473 72 2613 7198 3655 15201 13454 378 1007 1981 12393 26576 +EHEB3B5BY3NR 57909 9812 922 437 378 14126 62639 1007 1 +EHQMBE7U56Y9 57909 34041 6786 25047 14126 16129 16918 2607 23775 17152 54098 293 22513 56063 65505 63640 61759 61923 64042 12468 21204 62395 +EJ3K9Z9YAUZR 1 1007 65252 3 3365 11443 13425 12393 3419 43932 +EJAMZ9CCMW5A 3365 15791 922 967 15175 31715 437 1402 10796 3655 2242 9876 2477 3419 21158 17152 20623 3790 56668 5115 27980 64064 +EJK2MH3KTRXQ 1 13218 22513 44493 15175 8715 61923 10676 54098 30906 43932 11443 27980 42694 15915 36772 13425 15442 63229 64960 15353 2613 +EKNU9ZQWE395 11729 3365 65252 1 11443 64064 378 437 1007 12184 967 11537 180 3419 2613 +EM95HWBZ8TAJ 1 11443 290 8715 7059 29846 11729 3419 13454 437 22270 3365 967 20623 17971 23893 8790 15866 28084 1185 34799 12941 +EMVQK27W5NDD 57909 44 16918 17337 25047 12393 17152 13776 12191 54098 23893 922 15866 16916 8790 63695 42694 21204 61783 14696 34981 15074 +EP9M2C4FBRUB 1 11443 2613 +EPF3FDKYZWEW 2607 13425 46705 54098 13776 64042 437 48267 16918 62473 9812 21158 54206 +EQAB6EW4ZZ7V 11443 16759 65252 13454 61657 15791 1 63640 17591 11729 15915 15201 15845 18060 8790 64064 72 +ERKUDKEXM3VQ 15353 28084 +ERTQFH5VEDKF 28904 437 72 1 1185 26576 7059 7198 +ETAK6XP8AF7F 1 11443 64064 13454 11729 378 2613 3365 1007 16759 61657 17591 922 3 65252 17850 8715 9635 3419 180 967 +EUDREHMDWCMY 11443 437 1 967 1007 43932 12393 8790 61923 3365 7059 65597 2608 922 290 9876 63640 7073 13425 +EUMAH9EN3BBK 12941 26576 43932 10676 13218 10796 +EUPW322BXUKC 437 1135 +EVCJ3X6XMJW2 10796 967 15915 437 65252 922 1185 21158 31715 19374 2477 11443 1 13454 63274 72 57909 +EVDZ7XP8Q6ME 9876 +EWCXDQ6KCHFR 15915 3 11729 2608 +EWVM3RD494DD 11443 1 11262 +EXRZHTDHB85E 967 1 11443 7059 1007 3365 437 3419 65252 16916 10796 +EY45E6QXEERF 13425 3 1981 43932 1 +EZRPDPE94EB4 16403 +F2BEVUVEUWV5 57909 61923 46559 58249 +F2J6YQ64JUEF 1 13454 7059 11443 72 8715 64304 16759 31395 27980 3365 11729 1185 3419 19049 +F3C4R2X2D8Z9 11443 437 65252 43932 13425 1 9951 15915 3 +F44XTQC48KHV 1 1343 2613 11443 +F5VWDRNZR2K4 1 11443 10796 22270 +F6472ZQVM26Y 43932 15353 +F79T86TYKFKA 5152 +F7DE58B8EJJ8 1 7059 11443 +F82NKU9VD9H9 24394 11443 1 3365 4166 967 3419 19049 15201 1185 15915 17591 3655 8715 13425 2613 922 3 43932 46705 +F89V9KWHJCNJ 1 11443 63274 43932 22270 2607 15791 8715 3 15866 +F8FDFYWPBURZ 1 180 10676 3 13218 +F962DZRF6VX8 17591 15915 4166 2613 3 13425 43932 15201 1981 1866 15442 12649 13218 15845 967 3655 437 21158 15791 3365 10796 922 +FCUDBZ6MERYD 11443 23020 22270 1736 290 65597 1 7059 13425 1466 +FFAH3JQJYJP5 3365 11443 3 437 180 967 +FFFBC9DBRVYW 11729 3419 11443 65252 7059 10676 3790 5204 16916 15915 +FFVNYW45ZMUN 15353 28084 11443 11729 1 +FHWAZT5P9XMP 1 11443 7059 3655 26576 3419 4166 43932 2477 19374 1007 65252 3 1981 967 7198 437 64064 63735 922 12468 1135 +FJVEZBNBBFR3 1 13454 63081 42618 15353 28084 2607 59948 7392 10796 21204 7059 273 44493 11 1185 63695 63229 15442 33137 7198 19374 +FJXXJRDJ9CVW 57909 42618 65446 7392 56668 65597 3093 23831 2613 46874 63081 17325 3790 63640 6786 34041 180 9652 60694 17850 15791 +FM2EB9AEX8BD 53472 7198 +FMEF8QK4WWBU 1 11443 15175 +FN6QDDTQ9WFD 437 1 65252 +FN9DH89AFWD9 1 11443 3365 65252 378 1007 437 +FPQ3BTKJPXZW 922 3655 10796 11443 2607 13454 967 437 17152 2477 65252 13425 10676 31715 31395 61657 17591 3365 40542 1185 19374 57909 +FQ7NMWFEVQTN 64081 12393 64064 +FRPNXXU2CBDU 12941 11443 4166 63081 42694 56489 13425 13218 180 290 10796 2607 +FT5PZDQB8DCV 31715 967 15791 15201 17591 2613 11729 22270 16916 2477 10796 +FT5ZK44EJX52 1 11443 3419 58249 +FUK379VYMY56 11443 65252 1 11729 2613 378 34799 44 +FUN2XK8KM8EX 20244 +FUR73RQCJTR6 43570 3655 4166 12941 64304 8790 15353 64081 1981 17325 8715 5115 922 293 43932 63640 3093 903 12184 6786 +FUUBP72BNH29 437 4166 3365 2613 967 13425 15915 9360 12649 3 11443 1681 378 13415 290 8715 13218 1981 10676 1007 7059 3655 +FVUQ2XAX4PA6 7059 22270 1736 63274 3 17591 1 437 15915 16916 +FVXE8QUNVUZJ 61928 967 65498 31715 22532 23831 65429 1185 28904 7073 5152 11072 63695 64081 19374 23893 72 1306 19049 34981 +FWJ2URJVXQ58 11443 1 11729 12393 65252 72 1007 7059 7198 2477 13454 26576 64064 967 +FX87229TXHHV 53966 64064 4166 10676 65460 23020 922 +FXMX8QJ72MCV 2613 187 27139 13425 65457 1866 36772 49755 23020 12941 29846 1306 54098 48267 13218 53966 48594 17744 22270 65597 10676 12346 +FXTA7R9CPWYM 65252 28084 61657 15353 +FXX3F87H3E62 16403 1 16759 +FYHK7CKA44MZ 9876 2608 +FZH8A3P5FPVD 64081 24394 20919 46705 65597 32200 37047 65252 +H2HY7NP8MUVM 3365 1135 72 1681 15915 3 13415 967 15866 1 +H3VAMU9Y4TBK 11729 65252 2613 13454 1 3365 16759 16916 11443 1736 63274 19374 1007 22270 10676 3419 967 3 922 12393 1681 1981 +H4Z23TDEX3CK 903 +H5F7B99BQ57C 37047 11262 65252 21158 63081 63640 25047 23608 29846 12649 56668 65597 72 16403 63274 22270 13167 65457 44493 65446 3655 4332 +H6K8UUTN29X3 1 3419 10676 17743 187 +H6PJVRMK4HJB 1 54098 3093 11443 7198 2607 25047 22270 54206 8790 72 +H8Q3XWF7PFTW 57909 +H8W8JAHWUZJX 17325 50039 44634 23775 17744 42618 65597 47292 64064 63695 11537 15175 12346 37047 11262 5115 13167 34799 23608 31395 61657 7198 +H9A424UQ99PF 15866 8715 65252 15915 2613 8790 29846 11443 4332 63640 15201 3655 16916 437 13218 17591 28084 42694 4166 13454 62639 1306 +H9D4H5HQZAK7 23775 11262 5204 1 11443 31395 +HAENNPB6TEH4 1 4166 65597 +HBCCYK2279J9 1 11443 437 7198 1981 3655 13425 +HBDP4Z53XTWU 11729 1 11443 12393 13454 3365 61657 20623 3419 16916 16759 72 63274 65252 8715 3 +HBWHF6B7NVBY 15175 +HC4E9D3VPCA5 1 12393 11443 2608 3419 17744 12191 22532 17325 +HCVCXVPPPVE9 11729 1 8715 16916 13454 1007 65252 3365 922 15915 11537 3655 378 11443 967 10796 3419 20244 22270 16759 13425 72 +HEPMAKU4T2BA 5152 42618 11443 1 34981 2608 62639 13218 +HF5XFMH6N2HP 12393 437 11443 3 +HFAZ7RHH836D 21158 +HFTCTKVQJEW3 64064 57909 26576 +HHNW8RHQ6ETX 57909 44 16918 17337 25047 12393 17152 13776 12191 54098 23893 922 15866 16916 15915 8790 63695 42694 34981 15074 53472 9812 +HHPHA7958U2J 1135 19374 1007 42694 58249 31395 26576 19049 273 10676 64042 13218 34981 10796 44 40542 34799 30906 13167 1343 22513 43932 +HJX38Y8YRXVN 23668 2613 +HMW5WUDCQF45 29846 62923 +HP5BMFR35Q2F 9635 61657 72 13454 5115 11262 10796 33137 4332 15845 16916 378 15866 23775 7073 3655 11537 7392 11729 63274 5204 21158 +HP73Z3J4UHQJ 16916 26576 23893 7059 17378 12184 +HPQ4B538855P 378 11443 7059 20623 65252 1 3365 11729 437 11265 967 16916 1736 290 7198 17591 1007 15915 21158 17971 5152 61657 +HR5MJJ5PA9H2 57909 +HREMRNK879YN 10796 13218 1135 63640 15175 3419 65252 9812 53472 1185 43932 1981 3 22270 9360 1007 11443 15915 12649 +HV87TAFN8ZZP 1 11443 64304 16759 65252 13425 2613 63640 3655 +HYB3M9ADDUFU 63081 15845 54206 378 1981 3 15915 437 1 34041 16759 7073 11443 14126 3419 12468 +J2XWHQXURCV8 62395 +J398KJ2Z7P9R 1 13454 11443 16759 1007 7059 +J3HKNCU45HYM 11443 10796 1 3365 437 1402 60694 15175 2607 3 30906 4166 27980 9635 62923 63640 18060 43932 7073 72 922 37047 +J45KRHJBEJ5D 967 922 31715 15791 2477 10796 21158 2613 3655 17152 31395 437 9876 12346 3790 20623 27980 64064 1402 58249 47292 24492 +J4P6DUZ665DU 65252 1 65597 19049 3419 15175 15353 +J4PFB53C6NBM 10676 1 11443 1007 3655 15175 42694 65252 72 13425 63640 13415 62209 1866 13218 3419 15915 56489 64304 54206 4166 44 +J4ZBYTBJH2ZM 11443 21158 1 11262 967 65252 +J596PHMJXDTH 437 9360 13425 967 15915 19374 43932 922 13415 7198 1981 15175 15791 65252 2613 10796 11443 1135 903 3655 12649 15201 +J69263ZHY78A 11262 61657 34799 +J6JDAQTX352R 1 1981 52027 12184 23831 11443 11729 437 65252 42694 2613 180 63081 1007 3365 3655 +J795CFWA2DMM 65252 1 +J83WAKD4DKYT 12346 5204 20244 48267 +J84ZZV3Z95PR 65252 11443 63640 8790 922 11729 3419 13454 56489 26576 31395 19374 43932 10676 29846 65446 3365 61657 63735 12649 13218 22270 +J8R89H2RCP9Y 1007 44 293 7059 11072 2477 11265 65252 378 1 11443 3419 3365 61657 13454 11729 72 437 967 290 3655 +J94WQF9ZMEJF 11729 13425 3 4166 3419 3365 15866 11443 1 378 967 16916 29846 17591 13454 65252 61657 2613 922 19374 16759 +JAAU6JMRXUCK 1 27980 11262 23608 43570 +JBDJAZCYKRBC 1 4166 11443 2608 12941 1135 11537 378 43932 23893 64064 12184 65446 18060 63081 1007 63274 13425 +JBFEY7VD3HV4 15915 1981 13425 3 15442 +JBPR89NW64QN 11729 11443 13454 3365 65252 378 7059 3 1007 15915 1 3419 8715 922 3655 2608 72 19374 16916 15175 42694 17971 +JC96WTBJMHWH 22270 11443 3365 13425 15915 16916 31715 437 922 2613 63274 11729 7059 61657 1736 17591 10796 13454 65252 1981 1 3 +JCC2DWBR7XUU 11443 1 8715 437 37047 11729 26576 13425 13415 23608 54206 39553 7198 2613 25047 +JCT64W392E57 11443 1 65252 11729 10796 1007 4166 10676 3419 22270 13425 64064 2607 +JDJ5EEHDZ9JX 378 9812 437 10796 +JDMYJXZNU3CD 1 11443 11729 3365 65252 8715 922 64288 24394 7059 58249 16916 20623 967 1007 64064 3419 22532 19821 12184 23998 1466 +JDPYNTQQPZZX 1 11443 3 7059 22270 3419 8715 437 13454 72 1981 2607 922 13425 1007 13218 12393 42694 10796 65498 3655 +JDT3ABTEJBF8 1135 63274 5115 11443 43570 11262 34799 27980 63695 19049 8715 3655 56475 64064 65457 54449 17744 33137 187 46874 21158 18060 +JERD8N6PZ3TH 11443 +JEXXY67FKFXP 3365 11443 15175 7198 53472 1981 63695 65252 10796 1343 34578 13218 15866 65498 31395 1135 32200 63081 8715 12691 3655 26576 +JEZBK66T7NQX 10796 48267 3655 65321 54098 16129 +JMC6DADPBM6M 1 11443 44 3655 7073 43932 3365 65252 8790 33137 61759 49655 58249 63274 63640 57909 18060 64064 +JMRH28HYZFU7 1 11443 3365 13425 437 7059 1007 3419 65252 15915 3 922 16916 1981 19374 12393 22270 11729 378 15175 19049 13454 +JN2XNZWX2CR9 10676 1 11443 3419 273 437 2613 1007 17591 290 72 7059 922 29846 378 54098 10796 3655 22270 65252 +JN4874FEB985 15791 +JNJ9YR6RHM9M 1866 43932 3 2613 15915 13425 17591 4166 10676 1981 11443 1 62473 65252 15201 23020 +JNVVXV45BR8D 11443 1 3365 65252 378 4166 967 3419 61657 8715 2613 43932 290 437 +JP5YAB4JXTWZ 63274 22270 12184 65252 437 13425 3365 11443 15866 3655 12393 1 3 7059 15915 +JPB84HXA7WX2 1 437 11443 3365 10796 +JPXJC72CDA9F 1 922 15915 13425 11443 3419 7059 13454 4332 7198 967 65252 22270 15791 437 11729 20244 21158 2608 1681 378 10796 +JQBMKEQYTQUW 1 11443 378 +JR78WERUW9C7 37047 1 11443 +JRAJPNPN5TJB 31715 15791 922 13425 10796 +JRATTYM9VD9Z 378 11443 12184 11729 437 65252 17971 15915 +JRFZQHMJQR3E 57909 44 16918 17337 25047 12393 17152 13776 12191 54098 23893 922 15866 16916 8790 63695 42694 61783 14696 15074 53472 9812 +JT876RTR83AV 19374 30906 65252 1 62639 63274 +JTBPWVT97NYY 63274 11443 22270 26576 7059 65252 1 922 11072 19374 5204 53472 +JU77UEC97UDJ 922 1 11443 65252 3365 13425 3419 72 15915 11729 2613 13454 3655 19374 15201 31715 1981 8715 +JVCEDX6RJ4EW 13425 15791 3655 3 15915 7059 50039 17591 31715 437 22270 +JW8XWRMW9VFP 1 3655 3419 8790 1981 43932 5204 63695 8715 19049 65252 2613 27980 13454 +JW9WRT8TQE2E 9652 65498 9360 4589 +JX5VQWN2CHD2 378 922 2477 64064 3419 72 967 65252 16916 20623 21158 11443 31715 17591 7198 3655 11729 1007 10796 437 3365 3 +JYHU927PXJQ6 53472 49755 54206 2607 46705 22270 53966 21158 1007 58572 18060 3419 922 43932 61923 8715 +JYNEVAMQZYKC 1 10796 1007 +JYW5UZBB5CEQ 11443 2613 61928 29846 1007 58572 4699 3365 1 8790 290 1981 12649 8715 7198 187 9812 922 56668 63914 12346 19049 +JZB9VEEEU2P7 11443 3 437 4166 62473 13218 12649 47839 15201 8715 967 15915 3419 13454 14126 2613 43932 10676 17591 13425 1981 1 +JZBWAEVDWH3W 2613 15915 13425 31715 65252 922 4166 43932 3 3655 12393 10796 967 15845 437 49655 12941 22270 47292 13454 16916 72 +JZD9WEZR3A4U 8715 11443 54098 13425 15175 10676 +JZF9NJZ2Y4RB 65252 13454 3 17744 11443 3419 27980 16403 4166 3655 30906 31395 64064 10796 63695 922 19374 39553 31715 12691 +JZRY2PWANY49 1 11443 22532 12393 15353 63640 23020 8715 46705 15845 19821 65429 3 7392 23668 +K2363XD4JVP5 13454 1 11443 11729 437 3655 65252 1007 14696 12191 1306 46705 15866 +K2Q44KQQQ4EC 5115 61657 11262 34799 23608 5204 +K39TAJ7HYJ64 9360 290 65252 1 967 51716 9652 1007 +K3CXMAEJFUBK 16403 +K3R673R5THDW 72 14126 63274 +K5WJ5X9ENBWE 15201 2613 3 4166 17591 10676 17744 43932 13425 62473 11443 1981 65252 922 15791 437 22270 19374 15915 15845 967 57909 +K7JUPV9NCH9F 1 3365 +K86TEMEFVDBP 21158 +K86XA4VXJKK6 10796 3419 1 64064 7198 11443 4166 33137 +K9MHV6U452CJ 967 65252 4166 15915 2613 3 9360 922 15201 13425 43932 31715 63274 7059 10796 63081 1681 15175 20623 11262 22270 16916 +K9UX5PHM9JC8 31715 15791 11443 1 3419 2613 +KCPETHN7Z75R 437 8715 1981 7059 1185 290 1343 62639 1306 1681 3 922 967 72 11443 19049 1 +KDVD3BV6X2RX 56668 3655 20623 +KEM5TQUDBP7B 1 2607 3 11443 12393 3419 72 31715 15915 2613 11537 16916 7059 65252 63274 12184 22270 26576 437 8715 6315 16759 +KEQVMAEN9J42 11443 11262 1007 437 1 61657 378 37047 5115 7059 13425 25047 +KF2VBQBB6N6E 24394 +KFY8YZUJ5VUD 1 56489 15866 14905 49755 +KHHA8F6565PR 3365 57426 10796 1 437 11537 56668 3790 903 +KHWM855CMF85 1 11443 378 1007 3365 13454 64064 65252 8715 2242 +KJ8RMJ7TRZEA 13425 15353 +KJK9HH2XRXHN 15353 58249 10676 60694 42618 12468 19374 +KK7QX44DRJ4B 1 437 1981 290 11443 3 8715 12393 +KKD8TZCYHVP5 65252 13425 53472 62639 12941 15915 63274 15845 +KKHY62AYX98F 1 13454 437 3655 8715 9812 10676 +KKT99HB7D6Z6 13425 +KKWPB7DCUEEH 13454 16759 11265 17591 +KM6UUTJPUTYQ 9876 13454 11443 437 13425 8715 15791 +KM7NCQM5356D 11443 1 4166 54449 3419 9876 65252 +KMPXRN4MTNZN 11072 19049 19374 1 11443 293 15175 32200 15866 +KN226XWZRQQY 72 43932 922 65252 378 +KN3MQB989ZXV 11443 2613 1 8715 13425 43932 3365 13218 290 47292 54098 65252 3655 3419 7198 9652 5204 12691 8790 2242 9635 3093 +KN5B2XWF73ZF 65252 378 11443 64064 11729 922 16916 +KNMP2CDD285H 1 11443 8715 12184 922 10796 42694 43932 22270 3655 13425 15353 15175 10676 54098 13454 65252 13218 63229 9652 56677 7198 +KP2QWK4M9CWK 1 11443 3419 8715 11262 65252 61759 42694 72 25047 23608 34981 24492 30906 +KPT2D5HVD36F 33137 42694 5204 1135 +KPYQQ7DRVP9K 16403 +KQ99E4VRF2M9 967 11443 64064 1 63274 3365 61657 63640 64304 +KQ9AKHJWKFUC 19374 61923 11443 2608 54098 967 12191 3655 19049 15353 290 13425 30906 3365 14126 3093 58249 7198 15175 42618 11072 65252 +KQCYCYK7NY2E 23668 7059 8715 26576 12184 +KR3H8UBTN9K5 31715 15791 922 3655 11729 10676 11443 17591 15915 10796 437 2477 65252 8715 13425 967 3419 22270 +KRDB3868PN2W 5115 37047 61657 13425 14905 34799 +KT2KMZDAXYAU 57909 293 9812 61923 9635 10796 54449 +KVNU8JR4NZV2 19374 10796 1185 3365 4166 11443 65252 28084 293 7059 9360 2613 11072 43932 9951 922 13454 17337 +KW4MU3E52BFP 65252 11443 1 10796 12393 15175 3 63640 967 8715 13454 11729 20244 3419 2608 378 30906 19374 1007 31395 16759 1981 +KWPK3555ZPWE 1 43932 31395 8715 17743 11443 2613 15175 2608 59118 1981 63695 +KWXX5VMQMKMH 1185 3419 13218 9652 11537 56489 922 49157 +KXA2BXX3TVKF 65252 32200 5152 61657 46874 31395 11729 30906 11443 63640 16918 3 2953 12691 19374 17152 46705 61923 23831 437 15866 1185 +KXYXFBYAFQKK 10796 3365 15791 922 2613 967 3655 12346 12941 65252 9876 56668 20623 58249 3419 21158 17152 64064 2477 437 27980 54188 +KZ9NW88KXQTT 63081 15175 15845 922 15791 22270 3 2607 10796 3655 61923 1 8715 54098 43932 11443 56668 10676 +M2326CJCVHTY 15866 47839 6315 58572 56668 42694 65429 24394 4166 53472 12184 11 17325 2242 +M23E5RHH4B4J 1 11443 8715 437 22270 4332 378 +M29BY7VHAV68 1 11443 63274 1736 15175 22270 11072 13218 15201 63640 15915 15353 15442 2242 13425 922 20623 19821 7073 187 49655 1135 +M2C73UYV7UCT 62923 62473 +M2YR6FE4DT6N 11443 1 11729 65252 3655 13454 290 437 7059 1007 1981 +M39W4K75979H 11443 1007 +M4QWZ7BVDKKM 53472 7198 1135 3 437 65252 1 11443 15866 15915 10676 13425 1007 1981 +M7YD6HXQCXER 8715 13425 2607 54098 10676 22270 10796 15175 61923 15442 43932 13218 12691 19374 922 65498 15353 31715 42694 19049 39553 47292 +M84KE8BRXJM6 57909 61923 13218 63735 42618 15845 1306 10796 48121 12941 13167 51716 29846 64304 63914 +M8AV396RE7J7 11443 1 13425 65252 72 15915 967 8715 1466 3365 2613 922 11072 16916 378 1007 437 17591 63274 11729 3 13454 +M96JTCJN9QU3 58572 1 11443 10796 +M9MWNR5CHUDW 1 13425 3 54206 1981 4166 63081 15845 13454 +M9WP275WU5QM 1343 1 48594 3655 8715 +MA7R9ZM476MA 57909 +MANEA2TZZAHN 922 +MCV78CW87ZAN 11729 11443 11537 43932 273 5204 13425 72 9876 4166 41676 22270 +MDA84NUF5Y3M 11729 13454 8790 65252 12184 7059 1981 64064 16759 16916 378 15915 16403 7198 1 13425 2613 19374 10796 11443 15866 19049 +MDQHE8E3WD7X 61928 13425 39553 15175 922 42694 11443 2607 47292 2613 437 3419 9951 27980 22270 43932 10676 54098 3655 13218 30906 31395 +MEZA267RPBZ9 11443 1 +MFC3RC5FTYDY 65597 23668 1981 42694 47292 13167 56677 +MFKR9PHFXUM9 29846 11729 11443 72 967 378 437 65252 1981 1 15915 7198 12393 +MFRU8RHTEHBJ 11443 11265 13167 1135 12393 53472 37047 23608 1 54206 11729 2953 2608 4589 922 7059 17743 54188 10796 64960 65498 17325 +MHEDYU5532J8 1 11443 3365 1007 378 19374 437 7059 3 65252 290 11265 +MJU6E6TN6PKE 11443 1 11262 19374 437 7059 65252 43932 +MKDU8JRZVHK2 19821 +MKP3BMQFANJC 12191 3 12393 16403 64304 3365 967 1 12941 8790 57426 34799 49655 33137 +MMCYNBJCQ7WM 1 13454 54098 12184 59118 43932 2607 10796 +MMUKBMQZN5TM 11443 1 922 967 +MNYB8AMD2QM6 14696 2608 11443 65252 19374 +MPK3CPRMA95Q 1 11443 7059 290 19374 11072 16916 28084 2608 22270 1343 46705 +MPVA7U55QB5Y 1 378 3365 11443 13454 65252 11729 11265 5152 1007 10796 3419 3655 7059 16916 1185 20623 +MR89R37UDPHQ 922 +MRT8FUVX979T 65252 16916 3419 11729 3365 378 4166 22270 1185 1 437 7059 1981 15175 43932 10796 967 17591 8715 15915 3655 13425 +MRXN7YQ6M2H3 1 11443 63640 65252 437 3419 11729 3655 13454 8715 22532 31395 43932 13425 10796 64064 9812 4166 3365 28904 15915 378 +MTZHWE7HDY4P 1 437 1185 28084 1306 63640 2613 61657 922 23998 48594 +MV37BXUM68K5 1 11443 63274 13425 7059 378 2613 3365 11729 922 1736 3655 57909 437 11265 22270 967 3 290 16916 65252 2477 +MV4HHMCUFFYQ 3419 13425 12941 16916 11729 11443 13454 1981 12184 21158 22270 65252 +MV93EMU87Q85 4166 3 64304 62395 49655 31395 32200 1 15175 53472 64960 1981 17744 23831 16403 50039 65460 54206 437 180 13415 9951 +MWFJCDWV2FKA 26576 1135 8715 +MWWF79234ZUA 5115 2607 44493 31395 12191 13218 1185 33137 20623 11729 63229 27139 39553 15915 34041 +MWWR28MQD5QF 60694 13454 922 17743 1 2477 37047 19821 62209 28084 4332 15866 11262 3365 12184 1736 +MX6HWZY6KNFN 1 72 11443 1007 +MXEUDXF2VVN8 1 11443 7059 2477 10796 11729 63640 13454 61657 3655 922 12393 62473 8715 437 15175 18060 54449 1736 4166 63735 20623 +MY8EBUFRNBA6 64081 34002 61928 64064 273 +MYJ5X9VNU3VF 56677 1 12691 8715 62473 19821 29846 27139 1135 43570 43932 54188 3655 63229 64081 57909 22532 922 17378 1402 32200 27980 +N3FWQHE8J2U4 2613 11729 11443 1 3419 65252 +N3M4K873N75F 967 3 1981 378 273 10676 1736 437 65252 1681 72 15175 33137 7198 1402 15915 13454 13425 8715 63640 9652 54449 +N3VK3HQYCRVF 11443 27980 9652 63914 48267 17850 19821 +N63M7WC5PPNE 10676 437 1 3 +N6WH4W9EFDHH 9876 +N6X8M46XZVDK 13425 1 437 4166 15915 378 13415 3 13218 10676 1981 +N86B4K3EXFTB 57909 +N8CENDDZRRM8 5152 +N8T87BUMMCNN 11729 12691 1 1007 53472 7059 19049 2607 +N93DXHJ3YEN8 1 11443 3419 967 3 12393 15791 922 1402 27980 13454 43932 12346 63640 30906 34578 58249 12184 20244 15353 3655 +NAA99D2BZ56X 16403 +NANFQA4T2YHK 34799 +NB5WK7FWHK7M 1981 +NBPHZ683P6R9 1 65252 11443 8715 13454 3 +NBU6VXTNX5FR 1 1981 3 64064 8715 13425 10676 +NCAXTJTRP3RX 57909 65460 52027 49157 34578 3365 63640 26576 34981 42694 46874 64081 21204 34002 48594 14905 1343 11 13425 62923 17591 +NCEV347R2D2B 54206 +NCU3Z8WXH3CY 72 2608 31395 11729 43932 15353 58572 6786 18060 65252 63640 65460 57426 3419 15201 63274 61759 46874 +NCV65E5XARUW 63274 11443 +NCWVNW4HF4DX 43570 +NDBPWYHEBCRT 10796 1981 8715 3 11443 +NDWPCCZXHMCB 61657 1 437 62473 61928 4166 12468 14126 63735 1736 11443 49157 62639 15845 65252 65597 63914 12346 4699 48267 53966 1135 +NEAEUTBQTR28 1 3 43932 +NEH6P56WYJE7 437 +NH3W3XM9PPF9 2608 14696 26576 57426 63735 64042 61759 49755 15845 12346 42618 53966 44634 61657 14126 56677 34981 7392 65321 63695 27980 3655 +NH6HAJMCE79H 57909 44 16918 17337 25047 12393 17152 13776 12191 54098 23893 922 15866 16916 63695 42694 21204 61783 14696 34981 15074 53472 +NJBZJ5Q5DCUU 43932 9360 437 15915 1681 2608 967 1981 1185 10676 3 13425 +NJK2P74WCBD4 2608 64288 11443 11 +NKCNNRHQ7B3V 12191 28084 +NKNTKCT8FDPF 16916 3 11443 437 290 19374 63695 17744 +NKW79CN6XPH9 15791 11443 1007 967 437 378 3 43932 1981 10676 15915 13425 1681 72 3655 12393 13415 +NMDUAREP2KUQ 63274 11443 7059 2613 61657 10796 12393 11072 12184 65252 1 4166 16916 290 3655 378 3365 1185 1736 15915 437 72 +NN6MTYFP4PY9 72 11443 1 3365 1007 65252 3419 +NNNVCB8NER8N 44 +NPNH3HZZ7WYY 967 437 290 11443 378 1 13454 65252 10796 7059 12393 1007 17591 15915 4166 +NR7DZN3X2EBN 1 3655 922 2477 65252 13425 +NT56V858H77J 18060 8790 20244 15866 22270 28084 64064 15201 5204 7059 +NV5EZB7CNPNB 11443 65252 3655 19374 12941 43932 1135 13425 8790 59118 56489 1736 13454 +NWCR9K5XA5QE 1 11443 1007 3365 13454 65252 378 4166 437 1736 967 8715 922 11262 61657 +NWNQCFFYE4VW 1 49157 22513 17152 56668 +NXQPCMM2BKUX 1 3419 31715 63274 3365 13454 29846 65252 2613 44 15866 11443 10796 17850 4332 15845 +NY3VQ7KRM6BZ 7059 +NYKHU586DHW4 1 11443 437 3419 16759 8715 54098 15353 180 7198 34799 54449 15074 23998 922 30906 10676 17743 17152 34981 21158 65252 +P3X2FBDH4WM5 967 65252 10796 9360 922 3365 4166 3 1681 1981 10676 7059 13425 19374 13218 +P4H74M25QJBP 15845 11443 1 31715 3419 59118 62923 2613 48267 834 +P4V6BD6FVWRR 11443 +P5H6H5RART6M 15353 3093 56668 16759 1343 43932 922 12191 2607 7198 1 3 10676 1306 62395 12649 62209 15915 47292 1007 50039 13454 +P5WJ223XPJ22 58249 11443 +P5ZVPDQ8AEXM 13218 1681 65252 13425 54098 290 11443 7198 15201 3365 378 3419 967 +P66VMHTE378C 922 1 2477 +P6NEE6YYV5R7 64093 13218 34578 180 56489 16918 49755 15074 20244 23608 56668 293 56677 23020 8715 65429 17337 25047 63640 65321 7198 3093 +P7D4EUQUX2CZ 1 11443 437 3419 8715 12393 378 967 2613 65252 15791 64064 3 3655 3365 16916 922 +P8F7Z3EUH9DQ 16916 65252 11443 3365 7059 1 15866 2613 63274 3419 15915 22270 31715 21204 11729 19374 17591 +P8HK46UX574W 13425 11262 4166 +P8MXWWZ8CH4W 57909 9635 24394 53472 3365 48594 63640 34578 42694 11443 54449 +P9U4EV6WH8RZ 9652 9360 20244 1681 437 11443 1007 65252 2613 3 7198 11262 1 903 7059 378 967 5115 +PA66F4649TZW 1 13454 11443 378 11265 54449 3419 9812 967 11729 15353 931 20244 2242 14126 7073 16403 4589 18060 8715 43932 65252 +PACD9DYXCWQZ 1 11443 1736 22270 13425 13218 26576 31715 8715 3655 922 65252 3419 4166 61657 9360 11537 293 1135 15866 13454 15791 +PANA8PK8W4UX 3655 10796 10676 11443 8715 13425 2607 15175 13218 922 42694 +PBJQKKXTAETJ 1 65252 11443 26576 72 12191 3419 1981 63274 56668 +PC2QNMKVV4FF 16918 49755 13218 1 61928 34578 15175 13454 65252 19821 53472 63695 1402 13425 42694 14696 37047 44493 25047 63640 10676 10796 +PE747625JT29 20244 +PEEWN86H784Q 15915 43932 3 13425 +PF4D22U9T7KA 63274 19821 +PJYV8V57VMTV 23998 +PK8TNX5C99M5 62473 4166 15201 1866 10676 9951 2613 +PKDF2VFA2MVY 7198 1135 53472 31395 32200 15175 437 1 44 1007 +PKTTVBRURFJA 11729 378 65252 11443 8715 24394 56489 17325 13425 17971 10796 56668 +PME59NQHHNFF 11443 65252 1 13454 1007 3365 2607 +PN38UPZYRCZ5 1 11443 63274 12184 11729 290 16916 64064 34578 31715 +PNBZ6VY8XK4R 1 11729 1007 11443 9360 19374 2613 378 5152 65252 20623 922 31715 11537 20244 4166 22270 10796 43932 13454 12184 9876 +PNVNX5EFYF6Y 1 11443 15915 437 65252 +PPAZE8TZUT7Y 16403 14905 1 +PPC2YMNFW26C 1 65252 1007 11443 3 967 29846 1981 378 16759 15915 3419 11729 17591 3365 4166 437 13415 180 13454 64064 7073 +PPEM5P6P6Z4B 14126 7073 4166 922 22270 10796 19049 3419 11443 1 46874 63640 7059 1185 58572 64064 4699 9635 9876 3365 1007 15866 +PPNHU5B2EMMR 1 11443 23668 30906 12393 29846 +PPUWFP6XX6UW 12184 11443 1 8715 7059 +PPYNW8R2TWNE 8715 1 378 11443 967 13454 +PQWDX8U7Z53P 1 65252 13454 12184 14126 +PR4XHVTMN7VU 1 11443 +PT9V2YWEJ5RN 13415 1 437 11443 15175 3 +PTWUEH5V98RW 1 8715 30906 31395 5204 1981 64081 26576 10796 16403 63274 12468 18060 22513 7073 11443 16918 9635 6786 54098 11537 3419 +PU3ZW8NH4JQH 65252 1 1007 11443 17591 3365 21158 11729 43932 56489 3419 33137 3655 42618 9360 +PVCCZE8WJR8W 12393 12941 64288 1736 19821 7059 17378 +PVJRPT9FVA9D 10796 11443 378 2608 967 13454 +PVX55TM444PT 10676 922 1 3790 64064 11729 1007 +PWVAVEEJTHAP 65252 27139 15353 11729 48121 28084 290 17337 46705 1 23831 11443 2613 437 22270 +PWWJZXDRZEVR 15845 3419 11443 65252 4166 63081 3093 54206 3 15915 15201 12941 17591 180 10676 1866 23020 49655 43932 12649 62473 3365 +PXHUZPJ3KC9B 11443 1 48594 63695 1007 53966 378 3 8715 10676 13425 2613 +PXTKATB9EXNY 21158 +PXZCYUABZ78H 60694 11443 15175 1 2607 3 30906 4166 27980 9635 62923 18060 63640 43932 7073 72 922 37047 42694 3419 57909 12393 +PY2CPJN8XRR5 64064 1 +PY5RKU6PRQAM 3419 3655 11443 1 13454 20919 24394 967 1135 +PZNDXKAJ9NJD 1 11443 13454 72 65252 61657 3365 3655 13425 437 1007 12393 3419 11262 2613 11729 63081 8715 15175 378 25047 1981 +PZWA94R29TM2 2477 180 +Q27V6T2MYPXW 11443 44 65252 1 20244 1007 13454 11262 3419 20623 3 5115 437 3365 13425 12184 3655 12393 19821 967 18060 63274 +Q3APMC7RDRVH 6315 +Q3B5A29H5KCN 16403 +Q44A6V4WQZTE 11262 5115 1 +Q72AXX9R3EKU 1 11443 15791 8715 12393 3419 437 31715 +Q7YYZUCKPWJB 11443 11729 22270 65252 13454 13425 22513 43932 2242 12184 1 +Q89HEEJ44MBA 65252 10796 1 11443 15201 31715 3365 437 16916 7059 290 15175 15915 +QA5EYNB8DFYJ 12941 +QB63QEXYM28T 2477 922 3655 20623 10796 967 31715 15791 21158 3365 17152 3419 3790 437 9876 12346 27980 2607 13425 58249 47292 65252 +QBEVD4RXFYT9 11729 1 11443 +QC45A89Z5FBN 27139 +QC9NFYK3NHAH 1 19821 63274 30906 +QCCQN54M52K2 65252 11443 18060 16916 20244 1343 31395 17744 7392 22532 1 +QCXZA5B5UT7V 3365 24394 9635 19049 50039 1981 22270 16759 18060 23893 32200 14905 +QD7MU8423KB5 1 11443 27139 13425 290 47292 17325 5204 11262 2613 25047 +QDN4ZNCWPVD2 11443 10796 17850 43932 11729 28084 1 49655 18060 1007 1736 63081 12941 +QDP9KW686D46 64064 2477 3655 20623 3790 10796 62923 922 12691 15353 56668 13454 61657 1 273 63274 +QE3K6R47JCU7 1 11262 61657 7198 15866 1135 5115 3365 967 11443 3419 7073 72 3 1007 437 13454 +QEPCNAUU8AHT 1 3365 11443 65252 13454 15915 17591 1981 378 22270 290 19374 3419 3 13425 2613 4166 5204 12691 15175 3655 19049 +QFA3CWJPU4P3 11443 1 290 65252 11729 437 19374 +QFMWW3QFB54W 13425 1 11443 15201 3419 4166 10676 63081 13218 10796 19821 19374 967 72 12691 15353 30906 8715 15915 15175 42694 65498 +QFUFFPVWW4DT 11443 +QHNQ65REWTD6 1981 +QJCXRZH4VD3Y 7059 22270 1185 63274 1736 11443 12393 10796 2613 3 922 8715 43932 28904 19374 31715 437 1681 16916 378 290 +QJYTC7V82N5X 1 16759 13454 378 +QKHP6J47Q5VH 11729 3365 437 12184 64064 34981 2613 3 1007 1 13454 3419 378 48121 9635 22270 16403 3655 63695 180 63914 34041 +QN76N7BKDHWB 72 12393 11443 1 29846 2613 +QNZN77MKWA9F 11729 1 17591 3365 7059 2477 11443 1007 967 4166 2242 +QP8YXW8HT75C 12941 1 +QPVBUK7Z853J 57909 293 27139 61923 64042 17378 54188 34981 15353 21204 23668 44634 5204 62639 834 +QQUHB8K53RCM 13454 12191 19374 14696 31715 11443 922 3655 65252 10796 19049 34578 8715 13425 2613 2608 1185 40542 3419 19821 15201 11072 +QT2W265AB542 2607 23668 11443 26576 22270 72 63229 61928 12393 +QU482E3XMJ57 8715 8790 290 11443 72 +QUE69ZFNDK6N 1 11443 13454 8715 10796 20623 +QUNTF72HAYCU 3655 11262 65252 72 437 11443 7198 13454 1 1007 10676 3365 15915 290 8715 11729 3419 922 27980 61657 31395 3790 +QV56PYX2DA3J 1 11443 13454 922 8790 44 15915 13167 14696 5152 10676 +QV994W2897UN 1135 15175 31395 7198 19049 11443 53472 43570 17325 65252 25047 5204 37047 15866 1 3655 72 23608 +QVNJQ7WNXRH2 303 52027 61561 29846 48267 3419 65252 10796 23831 187 19049 3655 20623 34002 42694 922 1 12393 23668 53966 62209 65498 +QVPCX2RWEXM6 31715 +QYA75786N5VR 16759 1 11443 11729 3365 20244 65252 13454 5152 2613 16403 180 13425 378 4166 10796 3 12184 72 57909 11265 273 +QZCMPV28Q8NJ 1 60694 11443 64064 27980 +QZJQTKAU49N7 922 22532 8715 13218 28904 1 61923 2607 52027 19821 48267 6315 31715 16916 58249 16403 31395 61928 19374 39553 4589 1343 +R2BWWA4WYXKT 922 967 10796 15791 2477 31715 21158 3365 3655 17152 3419 3790 437 20623 9876 12346 27980 64064 1402 58249 47292 24492 +R37EURK4FVEJ 1135 48267 2613 12941 61657 1 61759 15791 17325 34041 65505 23775 13415 31395 15866 42694 43570 11262 17337 28084 32200 56677 +R3PQ86FU27TE 24492 15845 10796 +R45ZR2JY72ED 1 11443 11729 9360 967 +R49N8ZQ8R8UK 1 63274 13454 72 26576 65252 290 11729 1007 16759 12184 11443 7059 3365 1981 967 12393 1736 16916 64064 15866 +R4XW6DPFV2ZV 57909 22513 64081 32200 11072 7392 60694 17152 12691 10796 61923 180 40542 3655 34002 33137 15201 20623 15791 16403 22532 +R4YEAANV6Z8Y 1 3655 12649 11443 61759 10796 64064 13218 56668 12941 3419 15353 34578 65321 +R5RYE939AK6P 1 11443 10796 437 34002 62923 63274 15866 18060 20623 54449 290 12393 12941 15845 64304 +R63MBQDFMYB4 10796 11443 65597 11072 58572 437 63640 40542 +R6BCFY4MC2QC 1 +R7N6PPX438B6 11443 1 13454 13425 8715 65252 437 54206 15845 2607 +R856WY3Q2AJT 63081 63640 19821 13425 11443 187 14126 18060 9876 16403 10796 19049 7073 +RAY544QHDF5J 1007 7198 15866 61657 378 3419 437 922 15791 1 11443 3365 65252 2613 11729 19374 7073 72 63640 +RCHV7F4YN866 16759 61657 5504 11729 3419 3365 15866 11443 1 65252 378 922 +RDB3TWYU22EW 16403 +READ7J9K5VJU 10796 15915 +REB74XH3PANC 8790 13776 3 11443 2608 1135 44493 24437 62473 65203 27139 +REEC7VZ723EF 20919 +REFY5MYH336A 13425 1 23775 15866 61657 1981 7198 1007 34799 15175 5204 43570 +RFN9UJMMTXC8 11443 1 1981 1007 1185 3 3365 7059 16916 15915 11729 3655 17591 437 61923 64064 31715 922 43932 5204 2607 3419 +RH44MDYA6Q2N 7059 63274 11443 64064 11729 1 65252 8790 +RHEMY9BACD99 72 63274 23893 15866 4332 43932 +RHP9BBPU8C89 11729 65252 1 11443 13454 16916 3365 3419 967 15915 1981 15201 15866 43932 28904 7059 3 +RHXMKXF8MZVD 43932 11443 +RJKBWVTV6WM2 11443 65252 2607 43932 3419 15353 922 3655 19821 30906 42694 22270 47292 31395 12691 967 31715 290 437 1 15175 +RJMZBBKNKHKK 65597 72 63640 11443 52027 43932 61759 4332 64064 4589 15175 18060 7059 34981 11265 13425 10796 3365 24394 58249 19821 23893 +RJU7J35UXYPX 11443 11262 437 1007 61657 1 378 5115 37047 13425 7059 25047 +RNJMEEXX8XAT 13454 +RNNFW9J859W8 3419 61923 10796 65252 11443 20623 22270 42694 922 63735 8715 13425 43932 19374 12691 2613 31715 +RNUJATBXHK4C 65252 22513 1 +RP42RDAYHZK6 19374 +RQ7XR7AC2BQC 7059 22270 28904 63274 +RRATXB8ZEK3X 8715 26576 54098 16918 2607 46705 22270 23893 15175 17378 15353 23668 65429 12184 63229 7059 +RTKDYFWETUM9 11443 3655 8715 922 61759 63081 14126 +RTU5BXYNPJJE 1 3419 922 967 378 11443 65252 24394 17378 +RTYQTFEXD4PZ 1736 46705 1466 +RUJCQHF7DQ6N 57909 9812 +RVP8T462KMRQ 49157 9652 1681 20244 12649 273 13454 10676 65252 9360 10796 1736 8790 12393 26576 4589 903 65498 34799 3365 7198 922 +RWRRE2AC8KU7 21158 1185 378 3419 2242 65252 1 44634 11443 +RXZX5UC43P9F 43932 15353 8715 11443 10796 42694 65252 12691 63640 61923 27980 922 13218 13425 10676 19821 30906 +RY9DAJ6DWX74 11443 2613 12941 13454 20244 72 +T243UHET9UPJ 5152 +T2WJZ5YRZ32M 61657 19049 37047 1 +T32J85XRBPJC 1 13425 +T3QJVHBBQATV 1 11443 16916 922 3365 31715 11729 65252 13454 10796 1306 13425 7073 43932 15915 378 1007 15866 63640 20623 64064 4332 +T4VEHVXCYYB4 65252 11443 1 72 8715 2613 7059 7198 +T5VA85ZPRRXV 46705 15866 2613 19049 3655 7198 43932 13218 15915 13425 10796 22270 13454 1681 53472 7059 12649 10676 65252 19374 11072 57909 +T6B63B9J73XB 13425 47839 180 43932 3 4166 10676 +T6D2K938ZT8Z 11443 11537 1 437 20244 7198 63695 273 65252 378 2613 1007 +T7AR8JH7HT8F 7198 15175 437 1 32200 42694 922 62639 8790 11537 1185 8715 31395 22270 180 23020 37047 +T855N6R4FM3F 15353 11443 15175 1 31395 378 +T8QFQMEZ9UZ8 5152 +T8ZHABFJH9CU 13218 11443 22270 7059 1 13425 1185 8715 72 10796 31715 437 922 +TA9VYJR8AE2A 1007 7059 21204 6786 3365 19049 8715 31715 30906 11443 6315 +TBHQ8PHHC9Q6 13454 16916 2613 10676 3365 63640 11729 3419 15791 15915 1 11443 65252 19374 28084 +TCU4MCY636M5 7198 1135 53472 5204 15866 11262 19049 31395 9360 3655 7059 +TE3FHCWUTU7J 3365 11443 3655 63640 72 378 15353 29846 15915 10796 54449 12393 437 10676 24394 13454 63735 19821 18060 43932 8715 1402 +TFHXK5H392AR 922 10676 13454 61759 13167 53472 57426 17591 290 49655 16403 4699 44 15175 63081 1306 42694 54098 11443 19821 15353 3419 +THEXHWAUNVJE 1 11729 13454 11443 72 65252 64064 1185 3 29846 2607 56489 7059 922 27980 18060 10676 12393 43932 12691 15353 3655 +TJ22WUKR2AFT 4332 378 11443 1 437 3655 967 1007 12393 2608 2613 22513 9652 2242 9360 31395 11265 19374 34578 5152 +TJAY7NQNPUHK 1 11443 1007 922 378 13425 72 65252 290 27980 10676 56489 56063 8715 61657 65597 28904 41676 +TJDJA2B2CMB7 11443 3655 8715 1 +TJMT3W5ACQWD 16403 6786 +TJPUCYUEN4XZ 16759 72 1007 1 64064 +TKJW77EQXNQY 1681 11443 54098 8715 378 19821 51716 42694 13425 +TMJ6TWWTXN9J 57909 +TMNHZ8MMHHET 1 437 12393 922 11443 2477 1007 1343 64064 378 967 3 62923 31715 72 26576 +TMNTQP76A874 20623 1 3655 +TMWAWCDX7R6B 13454 1 11443 1981 16759 +TQYZ6WA666AY 3365 65252 11072 11443 12184 13454 967 1981 13415 3419 15915 18060 15866 1007 72 +TT3EU3XC5QJ5 11729 11443 29846 7059 65252 2613 3365 13454 17591 16916 10676 +TTHUV7TNU3XK 15791 3419 15915 967 65252 437 2608 +TUVVBE4J9CP5 11443 1 437 +TVVK444JEM3E 2613 967 31715 9360 65252 4166 7059 43932 17591 3655 378 3 11443 15915 3365 437 13425 15791 5204 19049 2477 12941 +TW2J3ZCFACYT 922 31715 13425 65252 16916 15791 22270 378 967 15201 72 43932 10796 20244 12184 2477 15915 11729 58249 1185 15175 13454 +TWWZUVX4RM49 11729 290 11443 19374 61759 16916 +TXMRJZP38HQE 1 290 28084 26576 27139 16759 17337 187 11443 15791 +TZY5VHNM7DF7 1 11443 20623 3655 2477 56668 11537 437 15175 7198 922 16759 17743 22270 378 64064 8715 967 5204 65498 +TZYHHYRDYX3Q 13454 11443 1 65252 11729 3419 378 922 61657 19374 1007 2613 20244 3655 31715 7059 967 8715 16759 3 5152 3365 +U34X6QYEQRAZ 16403 +U3B5P9CBPNH8 16759 13454 19374 1 378 11443 273 9876 15201 11729 22270 10676 14126 +U3P9DW97DTX6 3365 11443 11729 4166 1 1981 61657 10676 3 65252 15915 17591 12184 2613 16916 +U3WN5AQVUA6R 62209 48121 47292 12184 19049 60694 11729 61923 34578 24437 42618 30906 56677 13425 2242 25047 23608 31715 12393 64093 2607 3365 +U5C9P8AXCXHY 11443 1 11262 437 +U5ZDNNPQDH6V 11443 1 378 4166 3365 1981 65252 3419 61657 967 +U6P53PYQKR5C 1 65252 11729 290 61657 +U83CBETB5NN5 11262 5115 2613 11443 65252 3419 37047 21158 61657 13425 1 11729 290 13454 25047 34799 +U875H8834EB7 1 11443 437 16759 +U8T4YVX8PPNH 437 1 +U9W3JCR4T67K 11443 15442 1866 3419 65446 33137 1 2477 931 61923 56489 39553 54188 378 11729 31395 19049 4166 19821 48121 63274 49655 +UA4PRC8M9TAV 13454 11443 378 5204 3655 11265 922 290 1185 9812 13218 3365 65252 20623 2613 13425 1 40542 12691 22270 967 +UA5VNQ3HBM5Q 13454 9812 437 65252 2613 16403 11729 378 11265 13218 922 +UCEZ9JMWBCUA 1 65252 11443 12393 11729 8715 3365 1981 3419 72 1007 378 64064 5152 3 13425 +UCQAZZ584T6Q 48121 1 28084 58572 1343 17378 63914 49157 17337 1736 64042 64288 27139 44493 12184 62639 41676 15074 54098 11262 15175 63229 +UD2X7353HVBC 11729 11265 19049 8715 15353 +UD3K87MA7VVR 16403 +UDZ42KMHPCBH 13167 23775 23608 1 61657 31395 +UFNP9HPJDKCF 1 3655 11443 +UFVTT9T7Y8X3 11443 1 65252 29846 3655 13425 +UH6HPZBM37Z7 13425 15201 1 72 39553 8715 52027 44493 15175 15353 273 30906 +UJK4547YHT2B 63274 11443 8715 3419 72 65252 11729 3 +UK534QEQRZX9 3 13425 15845 15915 2613 15201 63081 43932 4166 58572 1981 12941 17591 180 10676 1185 12649 62473 17744 9951 61561 1866 +UKPDCWZHQUER 24394 +UME82J5PXHA6 11443 15915 1 7059 1981 +UN75B3AYCWJM 57909 +UN9QH8HFQXM3 13425 1 +UQEU4A8ZPWP2 11443 1 8715 65252 30906 63640 1185 10676 72 61923 3655 15175 47292 19374 2613 43932 7198 15791 31395 12191 12184 11729 +UQTN69QN24M3 11443 378 437 15915 65252 1 3 3365 +UT7W5VD4K2BW 11443 65252 13425 1 3419 2613 43932 10796 3655 14126 72 +UTHAZK5HU7MY 58572 1 11443 +UTV9NTCHH9DQ 5115 13167 11262 37047 25047 5204 61657 23775 23608 34799 17325 +UU55HCYUQP2K 21158 +UUBPVJ8KK5MH 5115 11262 61657 5204 13425 23608 25047 7198 37047 65252 42694 32200 1135 34799 15866 13167 19049 53472 20244 21158 15175 43570 +UUH7CXU2F5UB 34981 7198 31395 1 3 61657 24492 11443 7059 8715 36911 43570 273 437 62923 +UUV7JKZRD5XX 28084 7059 63274 1736 22270 8715 922 18060 16916 1007 3419 43932 13454 11443 13425 3365 1185 378 3 437 15353 187 +UV5RXQB2J7JY 3 43932 7059 437 15442 13218 1 922 3419 50039 4166 1981 12649 62473 378 290 15175 27980 26576 65498 23020 57426 +UWTP2AQ57AZ4 9360 8715 +UXJFRRFTU3CR 1 11443 7073 11262 15866 64064 15915 1135 3365 2608 1736 26576 11265 17971 7198 967 12184 64960 56489 +UXPP68427FYJ 1 1135 7198 437 12393 15175 31395 +UXUKCKEKHZTC 11443 65252 1 19374 1007 11729 3419 +UYNVUUDKUU5H 28904 +UYQUERNW7MR4 11262 56489 2607 63081 22270 28084 11443 7198 967 13167 13425 437 23608 +UYVZ589DMDZD 16403 +UZ8NADHRCXX7 967 10796 31715 3419 437 1402 15791 21158 2477 17152 11443 378 15915 2613 43932 65252 17591 22270 13425 16916 3 1981 +UZE862Q9EBT2 61923 54098 43932 10796 12691 4166 1981 8715 64960 +UZK78KPAVHFJ 922 1 22270 65498 10796 19049 15353 34981 15175 3655 +UZUURNN6VQTE 20244 9652 64042 9635 46705 8715 +V245B46PNCP8 1 437 11443 11262 37047 273 15175 42694 17325 +V2NK5VA3DEFR 1 11443 437 1007 8715 65252 378 967 1981 290 +V37Y7E254PW5 1 18060 8715 13415 13425 11443 1981 922 +V48BR45RD7K6 1 11443 65252 28084 12393 290 1007 13454 +V88EZTAFPZQQ 1 11443 3419 437 1007 61657 378 9360 72 2613 3365 13454 64064 20623 22270 290 3 4166 19374 12468 43932 65252 +V9MMHEMCBEFN 1681 3 65252 3365 13425 11443 967 15845 4166 922 57909 7059 1007 437 12393 21158 54449 31715 3655 11262 43932 61657 +VA8695K9PYRM 11443 378 11729 1 13454 11537 65252 72 12184 3419 1007 967 8715 2608 1981 +VAPBDH4XDTNN 11443 23668 +VBAUCV549FXK 72 15845 65597 3093 290 22270 7392 14126 +VD8BJWEBBP74 12191 28084 13425 22270 72 437 14696 16403 11537 9652 9360 1681 +VDWCKUCUPA6X 922 +VEC5RUU7KR6W 1 65252 16916 3419 11729 967 13425 11443 3365 3655 72 7198 1007 15866 10676 +VEFEU6DUB7CT 16403 12691 3655 12191 2477 +VETVBA9KPA3B 7059 11443 11729 11072 19374 12393 13454 +VFH43WP9EBVR 61657 1 8715 1981 15915 57909 378 922 3365 13454 11443 3655 11729 43932 63081 3419 15353 3093 3 1007 10676 13218 +VHDP8RHWWCJB 65252 11443 1 3419 12393 14126 63640 3365 3 61923 437 30906 57426 27980 8790 63695 62473 28084 16759 28904 4332 72 +VHHYXKE6DMNB 43932 63640 52027 10676 58572 17591 1981 15201 49655 59948 64304 15915 3 15442 4166 23020 50039 56489 64960 62473 53966 17744 +VHRTBQP9D6EE 4166 378 437 9635 16916 33137 15915 11443 61657 15201 3419 +VK87B6X2MQ72 11443 11729 65252 1 33137 +VPDND3UJAANT 7392 7059 16916 1 63274 21204 +VPUZ2AYFUXBF 1 11443 437 2608 15915 290 1007 3 16916 12393 7059 3419 3365 10676 65252 11729 +VQFE7B7WZXFT 1 63274 72 11443 22532 15175 10796 63914 2607 +VQKFQM9AFYPK 7198 1 +VRA7JHQ28MME 2613 3365 7059 65252 7198 11729 1981 13454 20623 437 1007 967 378 15866 1 1135 11443 +VREJEDX8ECKK 57909 61923 13167 22513 63735 61928 6315 187 12393 8790 5115 17152 63274 39553 +VU3TBBX9MYV8 1 1007 10676 +VUXNYJ4EAFKX 1 11443 65252 11729 3365 13425 22270 13454 3790 1681 40542 19374 26576 58249 12346 5152 10796 +VUYUZJ5JTBXF 3 15915 12941 13425 15845 11443 2613 15201 63081 13454 43932 4166 17591 180 23020 +VW4QXAY42W4T 15442 +VX9H4ZH9MNVC 922 967 31715 15791 2477 10796 21158 3365 3655 17152 3419 3790 437 20623 9876 12346 27980 64064 1402 58249 47292 24492 +VXWZMPKN8JM9 11443 1 13425 3419 922 2242 15353 30906 65252 8715 +VXYK4PUPAWKK 1 11443 43932 922 13425 42694 19049 27980 31395 8715 +VY22DV42V2NP 57909 10796 24437 61923 62473 65203 11265 1 15353 13218 +VYDPD5TFPAU9 16403 +VYH8VMK8Z6BA 1 11443 967 437 16916 +VZ3KKW9RXB95 9360 +W2QQ7FJKHRRA 8715 54098 1981 10676 +W32FYTPK3T7D 903 +W4P5NC77A8QU 922 967 31715 15791 2477 10796 21158 3365 3655 17152 3419 3790 437 20623 9876 12346 27980 64064 1402 58249 47292 24492 +W5DWRD4ZT3Q7 1 12393 4166 22270 64064 1007 7059 29846 +W5EZWAHBCT5W 4166 3 +W698ZNNZMQ5Z 12184 1 11443 8715 +W8UB9DYFK5WK 13425 2613 10796 7059 63640 31715 22270 8715 11443 65252 12184 3655 5204 922 3419 63274 16916 11729 3365 290 11262 15201 +W97HYTQEPAAP 1 11443 1007 2613 72 378 3365 57909 5152 20623 11729 16916 65252 31715 15915 967 7073 +WA8E65FB2JJK 63229 63274 9876 4699 23831 39553 +WAMKPF349AZA 63274 16759 +WBCJVU47YNDC 11443 52027 2613 1 967 1681 3365 64064 13454 16759 63274 57909 16403 4166 49655 3 43932 180 13425 15201 15915 9635 +WC5Z5CD97RPT 11443 1 72 293 437 290 9876 1981 64960 43932 15175 13425 31395 15353 2613 39553 19821 19374 65498 30906 65252 10676 +WC7AEQ9DFPPT 18060 1 12393 13415 11443 43932 42694 967 12941 +WDB8AVHZ87BV 11443 1 15915 28084 +WF4HQANVZAXT 1 273 11443 7073 53472 34799 7198 23608 +WFYZR35H8PFJ 14696 +WHJPUWMM6C74 20919 24394 8715 46705 15353 65252 2613 13218 2608 1736 +WJ7FWV6KNPPJ 1 4166 11443 13425 52027 23831 36772 43932 58572 65460 +WKP4VHMWBFN3 922 +WMTA7YAWAXFY 922 2613 65252 43932 13425 11443 10796 31715 5204 19049 22270 10676 15175 3655 967 19374 61923 3419 31395 12691 42694 8715 +WP38PUFJPCP2 15915 +WPK9N5C8VTKW 11729 1 12393 11443 13454 3365 61657 20623 3419 16916 16759 72 63274 65252 8715 3 +WPWCXFC7PRNJ 3365 1 +WREFJA93EPXT 11443 1 13454 +WRWEN9XMCTWD 17744 63081 1866 52027 11262 17743 43570 51716 24394 64064 61923 58249 903 12184 13415 8790 9652 3655 42694 2607 2608 15175 +WU2KZBTCJF3D 28904 +WU4Z2NYR4E6Y 903 +WUFMXYUMW27P 10796 65252 +WUP5565DVDEA 57909 303 64093 53472 63640 59118 42694 1007 58572 13415 3790 63274 1 42618 11443 +WUTHA83388C2 1 11443 11729 2613 437 1007 65252 967 10796 3419 3365 8715 +WUX8M4FYZNT5 1 11443 13454 3419 2242 30906 2477 922 10796 62473 13425 +WV7TU8XYVNQZ 16403 1 +WW6CAP2JCCD8 13454 61657 9635 22270 33137 13425 15201 4166 17971 20244 7059 2477 43932 293 +WW8WE5CC3PTC 1 +WXK5R288NW6C 11537 1402 39553 63695 967 11 437 10796 +WYKDNXXJ74PZ 3 13425 15915 43932 1981 17591 10676 1866 15201 4166 1185 180 52027 15845 2613 65252 11443 1 22270 2242 +WYNURWHBKE3T 20919 65252 11443 32200 13425 13218 63081 290 3655 437 1 1007 46705 54098 31395 +WZCM877WM5Z4 16403 +WZYEPBBJ86ZT 1 61928 12393 7059 23668 12184 23893 1343 2607 +X25PQQENB33R 290 +X3F7RJ3EPT3F 1135 931 65460 180 54188 3655 3419 20244 65597 +X4CAT57AAK85 3419 11443 65252 3365 2613 64064 27980 3655 15201 63274 11729 58249 922 72 24394 63695 14126 10796 57909 3 19374 43932 +X4J276357XFM 61923 63640 10796 13218 3419 13425 43932 10676 922 63695 30906 15175 42694 65252 34578 26576 2607 19049 22270 12691 5204 64304 +X53K8PM7U7ZC 57909 9812 17743 +X57QM22VYYAT 1 63640 11443 31395 2613 19821 65252 +X5F33NP99K2Z 10676 15175 12941 54098 30906 15353 21158 8715 27980 63695 44 65321 7198 +X5FNK8WNWXNB 290 7059 22270 63914 +X5KTMNMD5V6P 57909 5115 6786 34799 5204 62473 15845 1736 +X5QEWF7YRCME 11443 23608 1 +X65JBH3FHJJ4 1 8715 10676 13425 15175 11443 54098 22270 10796 2607 42694 61923 19049 13218 5204 15353 43932 922 47292 39553 65446 3 +X827429KMNMC 11443 13454 1 11729 378 437 24394 +X8YEZEM485N4 1 1007 33137 +X955VMKVT8VP 922 1 1981 15915 +X9M4VEC274X2 56489 34041 12468 54206 64304 28084 10676 26576 12184 11443 2607 13454 19049 10796 8715 72 +XAQU5MPQPMFN 11729 1 11443 3365 65252 1402 +XBMT2PRPC8NC 58572 +XCDUAUNBF9AD 62473 11262 36772 16759 17378 +XCEU3ACKD3U4 47292 +XCJMJTDQXD3V 11443 378 3419 922 13218 1981 967 3655 1007 1 290 2613 9360 15353 +XE2QE9FN7BZZ 13425 10676 13218 12941 44 24492 7073 17325 65597 43932 23893 34002 922 903 15175 61657 273 22513 23775 61928 13415 42694 +XEK2RF4HY4ZM 11729 11443 15915 437 4589 1007 3655 3419 7198 7059 19049 18060 63081 72 15866 11262 5152 12941 65252 17744 4332 24394 +XENUFHNWZNNN 1 11443 15915 17591 922 15201 3 63081 967 15845 62473 +XFC6JN4FNT5R 2607 1306 3655 57426 5204 +XFNNN8EM7AHB 3 13425 15845 15915 2613 15201 63081 43932 4166 58572 1981 12941 17591 180 10676 1866 1185 23020 49655 12649 16918 62473 +XFZ6AFF56DAD 48121 15353 187 28084 27139 922 24394 11443 65252 72 10676 1736 8715 1 +XH6KK4QPE8DT 62473 1866 61657 15845 3419 4166 34578 57909 36911 65460 65457 23020 180 11443 20244 62639 63914 16403 13415 72 14126 53966 +XHAAT5M2WT9M 33137 59118 27980 13454 3655 56063 34578 9635 62639 4166 11443 180 +XHWJZVKXX72B 46874 1 63640 53472 +XJX4DQJK6227 57909 9812 15175 56677 64093 61923 3655 42694 61783 967 39553 58572 1466 23893 31395 22270 20919 65597 17743 15353 9876 64304 +XM2KXDV7YTYN 11443 65252 +XM67FP4HCYW4 64064 13425 62473 18060 11072 3655 10676 10796 15866 14905 62923 922 2607 49755 31395 19049 12346 56489 42694 8715 54098 1736 +XN7DHTMYEZR7 62473 1 19049 56677 6315 47839 34981 12468 2608 39553 15845 9635 12184 58249 55614 7073 11 53966 22513 12393 9951 +XN9CMVYBFKJC 11443 3419 1 3655 65498 13425 65252 922 15175 8715 61923 19374 +XNNAQKZ9ZEBQ 11443 1 922 10676 42694 19374 15353 47292 +XPV3B2J8ARVC 21158 5115 11262 61657 15915 15201 3 72 13425 9360 19374 65252 11443 1 +XR62KNKUKBF8 290 23668 10796 13425 10676 1466 5152 53966 +XRHUAXJJ2V7D 13454 1 11443 11729 16759 65252 3419 378 922 61657 19374 1007 2613 3365 3655 20244 31715 7059 967 8715 3 5152 +XT82R46ERQFQ 16403 +XUQMAZ5AP7DA 13425 +XUYXP9AQW9J2 6315 1343 290 62639 +XWMYDQ2PAFCX 1 11443 3365 63640 3 13454 1007 8715 7073 437 18060 2477 63274 12393 64064 65252 21158 7198 72 11729 290 +XWV3T3PACT6R 19049 22513 21158 1343 13415 63640 15866 53472 5204 1185 58572 5152 30906 15915 23608 26576 5504 922 11072 16403 11443 42694 +XYHYE8P92FDU 61759 11 31395 46874 10796 44 39553 43932 2613 49655 1681 15353 49755 6786 48121 4166 11729 4589 53966 34041 +XZ7UPHKWB7H8 13454 +XZF57EMZ4EUU 29846 63274 7059 1736 52027 16403 64288 58572 23998 56475 63229 6315 62473 41676 17378 23668 65460 4166 3 14126 64081 17591 +XZTZNT8JBVBJ 437 9360 3 2613 9812 7059 +Y278C8EPF9C4 19374 2608 23668 14696 16759 2613 11729 11072 13454 65252 290 +Y2BBJ9WN6MHZ 293 33137 1007 7198 44 9360 8715 290 57909 13454 11729 65252 11443 +Y2QHE4W23TE9 29846 1135 63640 5152 31395 3419 63081 2613 13454 8715 25047 65457 3655 19821 922 180 19049 15442 +Y3C8BK5UZ333 1 11443 13454 11729 378 290 7198 24394 +Y45DNTQKD6DY 11443 +Y49Q8RTU2TQM 11443 1 31715 +Y4B79CKDJY96 7059 26576 11443 378 +Y4EP9PQA7W9X 11537 +Y4TX88K5MA8D 64081 18060 11072 34799 15866 +Y544V9CNBTY8 11262 21158 +Y5REH4Y52UBZ 11443 1 48267 +Y6DXDUDWHYU4 61657 5115 11262 5204 65252 21158 31395 25047 9652 13425 7198 922 +Y76X2YXCVWZX 16759 9360 8715 19821 3419 34578 11443 10676 3093 20244 23998 63695 12393 437 58572 12941 +Y7CRRJW2K7HN 15791 63081 +Y7WVW6VJY4RQ 11443 65252 2607 8715 922 903 1 9360 9652 1007 11729 39553 54098 1736 34799 26576 19821 17744 15866 24394 22513 56489 +Y8NTXZH7XQZQ 57909 15845 5115 15353 17337 42618 56063 62209 60694 56489 34981 903 61923 28904 54206 +Y8UH3A7WKJQE 57909 61923 48121 47292 15175 922 16918 65203 13218 273 13776 22532 63640 41676 15074 47839 46874 10796 43570 +YAT2UX9EEVV8 922 967 31715 15791 2477 10796 21158 3365 3655 17152 3419 3790 437 20623 9876 12346 27980 64064 4589 1402 2613 24492 +YBT3N9DHHMT5 11729 2477 11443 63640 10796 1 65252 11262 13425 3419 1185 11537 21158 64064 1981 15175 1402 63695 63081 15791 922 27980 +YBUJZXVXQ3N6 1 13425 11443 17744 15353 4166 17591 +YCDYWCHU4CKR 1 14126 10676 25047 11443 59948 65597 3419 1007 62473 53472 72 17325 22270 15175 61923 9360 931 63735 3 34002 273 +YD6CC6ECF56N 53966 +YE9ZKMX6JR4J 13454 11443 1 +YEADQ6YRWYKX 17850 +YEZK7MPKDR9Z 15791 11443 19374 2953 7059 11072 12184 13454 56489 3655 63640 33137 13425 65252 12346 54098 63695 39553 +YFTXZF4Y2XP7 11443 8715 9635 63640 +YHYRV7NCNAXK 1 11443 1007 63695 27980 19821 39553 19374 31395 273 51716 19049 +YJTFYDKX9MD8 11443 23668 63081 61657 12184 20623 65252 42694 3365 7198 7059 3 15353 50039 1981 15791 26576 1007 9876 3093 2953 1 +YK87QKJP4E4J 1 5115 11443 7198 437 922 3419 13425 2613 3655 +YMP25U46FWXA 11443 1 65252 11729 8715 13454 2613 3419 3655 1007 3365 31715 7198 +YMPRX5J79CTU 65252 1 11443 437 +YMZRRDBYPZNZ 12393 25047 31395 15353 9812 10676 56668 63735 11443 34799 2242 15175 17152 +YQ7J52MUWTZQ 1 17152 +YQBKQWJVPAKF 15791 967 31715 65252 3419 378 15915 13425 11443 +YQTD7WY9D626 37047 11262 +YR4QCCP4TUKR 3 13425 15845 15915 2613 4166 12941 180 1185 49655 12649 11443 +YRPWUH76BT7E 65252 11443 11729 1 3365 2613 16916 3419 378 13454 967 4166 12184 15866 1007 1981 +YRWCHVA9QY3N 15175 10676 28904 11537 187 4166 57426 72 931 60694 +YTAYCDZQ7ET7 13454 1 11443 65252 378 11729 922 61657 19374 20244 7059 22270 3655 3419 4166 3 31715 13425 5152 16759 1007 967 +YTZPBJPPURET 1185 15915 17850 15353 58249 7198 31395 56489 +YUVXAHVQPAPD 11443 437 8790 43932 18060 31395 29846 15353 1343 62639 19049 13454 56668 27980 26576 65597 14126 30906 65457 63640 54098 17325 +YVPVY3TXAFKK 36911 12468 62639 12941 16403 12184 59118 57426 14696 46559 +YW7MPN5ANYFQ 1 11443 7198 12393 61657 3419 22513 3 1007 437 3365 +YWWHZBV6ERN4 1 64064 57909 15845 63274 3365 18060 11443 15915 +YX73XDVV7WE4 11443 1 16916 43932 8715 13218 922 39553 10796 19374 15175 2607 42694 11537 3655 24394 11 13425 53472 49655 63229 54206 +YXPEK3X3EQED 290 19374 54098 +YXUYAFXRNNBX 25047 15845 11262 +YYNM5XR56N9R 1306 3655 10676 8715 13218 15175 13454 922 +Z25XH22JWR82 9360 15915 437 20244 11443 9652 3 3655 1007 1981 13425 8715 1185 273 +Z2MTE93KQP6V 24394 7059 1 23668 15353 63081 12393 12184 64288 1736 23998 72 13218 27139 63640 22270 28084 63274 3655 64081 922 58572 +Z2ZCQQQVBWNA 11443 61657 17378 52027 65457 34578 15353 10796 378 +Z33P8WXCXA5T 13454 16759 17850 1 1981 11443 3 17591 2477 15201 15915 10796 65252 13425 12184 903 3419 12468 +Z3URK4TAETVV 437 11443 +Z3W92XJE8MXT 46705 15175 922 63640 26576 13776 22270 3655 1981 24394 43932 64304 +Z6WPYE5785HU 922 3655 20623 2477 +Z8BBAUPK4DFK 17743 1 437 6786 11443 72 13425 10796 +Z8EVTTAJKCBU 10676 +Z8YARTYH7KB7 10796 1135 43570 31395 15866 34002 5204 5152 7198 58572 15201 19049 16759 9635 63274 53472 17325 62639 8790 72 27980 5115 +Z999QQWNPYZU 1 12393 +Z9BWKP3436N5 5115 15353 61783 48267 7059 12393 37047 17325 48121 1681 4699 47839 56668 63914 11262 63640 65498 22532 3655 1 12468 42694 +Z9QCC9YBWJQ3 1 11443 11729 65252 12184 63081 +ZA25FDD86V3B 1 +ZA7Z5YDKT65U 1 +ZAV5YV5D4YHH 11262 11443 3655 1 +ZBBQPPYAXNYJ 1 13454 11265 11443 6786 967 64960 +ZBPCN7ZDTJQP +ZDCPF89R2M5W 65252 1 11443 65446 65505 49157 11729 17152 +ZDH5WZMQ53QZ 1 11443 1007 3365 13454 11729 65252 378 967 4166 16759 3419 3655 8715 7059 19374 11072 7198 63274 31715 26576 922 +ZDUAEHV5TBEF 1 11443 13425 18060 8715 437 15175 19821 12393 58572 13415 10796 +ZEDPFUMRHBQB 64288 +ZEFMQ2WB59R2 1 12191 11072 14696 22270 11443 19374 2608 13425 2607 10676 54098 12941 15353 8715 61923 19049 10796 3655 3419 12691 922 +ZEZ4WU4CDQY2 1 11443 24394 +ZFCNCHZR2ZNY 1981 3 10676 +ZFWK7HPBDD63 12941 11443 3 1 +ZJMDDHHPJNJ6 65252 1135 31395 32200 20919 7198 8715 15175 1 19049 11443 53472 +ZJTUCPXF98ZK 293 42694 33137 44 61657 1135 2608 17325 378 11262 +ZJUZMCHC42CP 11443 3 1 1981 +ZM4XYCYZVXR9 33137 44 1007 3365 11443 11729 967 7198 10676 13425 4166 437 13454 2613 3655 3419 12393 15866 72 1 +ZMC5AH9JA4Q5 42694 10676 2953 8715 180 3655 10796 54098 9652 2242 1736 64093 24492 11443 15442 17152 1185 12649 13425 23668 37047 65498 +ZMDUVPK98UNF 11262 3655 437 13454 1 65252 11443 53472 +ZNCAXYK74248 1736 22270 63274 16916 15915 1981 4166 437 19374 967 12184 7059 1185 13425 1681 2613 10676 290 11072 11443 3365 12649 +ZNMUWX3DKWXJ 21158 1 11262 +ZNPPY9MB83MX 11729 11443 1 11265 3655 +ZPRFY43C4Y3W 1 +ZPXZHCQMXRWA 1007 1135 11443 15175 1 15353 19821 +ZQ38NDYN7T55 19049 15866 19374 11443 1 2613 61657 10796 378 11729 65252 7198 922 3655 16916 11072 3365 15915 1007 22270 1135 31715 +ZQ7AH7C7FHU3 7059 437 8715 72 +ZQBZCVHY457E 58249 15791 1 1007 +ZT9NFUMDFP5J 65252 11443 1 31715 +ZUM3MEUB354V 2613 12941 48121 61561 49755 54098 187 54206 16918 27980 15845 12649 51716 3093 303 63081 48267 15791 3 17337 16403 1306 +ZURPT2YWTP3X 2608 14696 57426 49755 64042 62473 12346 14126 61759 7392 44634 48267 53966 42618 34981 2242 61657 834 56677 65321 63695 3655 +ZV83F6MUQPQR 24394 42618 +ZVNW77HQBQD2 922 2477 56668 20623 20244 31715 3 65252 10796 15915 17591 15791 967 72 17152 21158 1185 61657 378 43932 12649 13454 +ZW8N7JQC73FJ 1 11443 3365 378 11729 3419 7059 16916 15915 3 437 1007 967 4166 65252 17591 12393 15175 3655 10796 922 28084 +ZWBXZ3YFKKF9 1 1007 11443 44 3365 42694 378 12468 65252 12393 8715 +ZX9UR5FZBFVY 2613 11262 11443 13454 7198 1 378 1981 65252 5115 16916 23775 61657 12184 +ZZ9FCB54ZREY 11443 1 3419 11729 65252 10796 31715 2613 8715 13454 3 13425 3655 26576 22270 922 15915 16916 7059 19049 12184 15353 +ZZEMKWAX7UFD 72 17378 63274 From cfbolz at codespeak.net Sun Jan 24 20:19:23 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 24 Jan 2010 20:19:23 +0100 (CET) Subject: [pypy-svn] r70806 - in pypy/trunk/pypy/jit/metainterp: . test Message-ID: <20100124191923.0BDB31680B8@codespeak.net> Author: cfbolz Date: Sun Jan 24 20:19:22 2010 New Revision: 70806 Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/optimizeutil.py pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Log: Finally I found a good reason to have folding of pure ops with identical arguments: When using generators, the residual code of the function using the generator is handling the generator frame. Doing this produces many oois instructions, that check again and again whether the generator frame is the virtualizable or not. Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Sun Jan 24 20:19:22 2010 @@ -11,7 +11,7 @@ from pypy.jit.metainterp.specnode import VirtualStructSpecNode from pypy.jit.metainterp.optimizeutil import _findall, sort_descrs from pypy.jit.metainterp.optimizeutil import descrlist_dict -from pypy.jit.metainterp.optimizeutil import InvalidLoop +from pypy.jit.metainterp.optimizeutil import InvalidLoop, args_dict from pypy.jit.metainterp import resume, compile from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.rlib.objectmodel import we_are_translated @@ -389,6 +389,7 @@ self.heap_op_optimizer = HeapOpOptimizer(self) self.bool_boxes = {} self.loop_invariant_results = {} + self.pure_operations = args_dict() def forget_numberings(self, virtualbox): self.metainterp_sd.profiler.count(jitprof.OPT_FORCINGS) @@ -571,6 +572,23 @@ resbox = execute_nonspec(self.cpu, op.opnum, argboxes, op.descr) self.make_constant(op.result, resbox.constbox()) return + + if op.descr is None: + # did we do the exact same operation already? + args = op.args[:] + for i in range(len(args)): + arg = args[i] + if arg in self.values: + args[i] = self.values[arg].get_key_box() + args.append(ConstInt(op.opnum)) + oldop = self.pure_operations.get(args, None) + if oldop is not None: + assert oldop.opnum == op.opnum + self.make_equal_to(op.result, self.getvalue(oldop.result)) + return + else: + self.pure_operations[args] = op + # otherwise, the operation remains self.emit_operation(op) @@ -700,7 +718,7 @@ elif value.is_null(): self.make_constant_int(op.result, not expect_nonnull) else: - self.emit_operation(op) + self.optimize_default(op) def optimize_INT_IS_TRUE(self, op): self._optimize_nullness(op, op.args[0], True) Modified: pypy/trunk/pypy/jit/metainterp/optimizeutil.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeutil.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeutil.py Sun Jan 24 20:19:22 2010 @@ -1,7 +1,7 @@ from pypy.rlib.objectmodel import r_dict, compute_identity_hash from pypy.rlib.rarithmetic import intmask from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp import resoperation +from pypy.jit.metainterp import resoperation, history class InvalidLoop(Exception): """Raised when the optimize*.py detect that the loop that @@ -59,3 +59,35 @@ def descrlist_dict(): return r_dict(descrlist_eq, descrlist_hash) +# ____________________________________________________________ + +def args_eq(args1, args2): + if len(args1) != len(args2): + return False + for i in range(len(args1)): + arg1 = args1[i] + arg2 = args2[i] + if isinstance(arg1, history.Const): + if arg1.__class__ is not arg2.__class__: + return False + if not arg1.same_constant(arg2): + return False + else: + if not arg1 is arg2: + return False + return True + +def args_hash(args): + res = 0x345678 + for arg in args: + if isinstance(arg, history.Const): + y = arg._get_hash_() + else: + y = compute_identity_hash(arg) + res = intmask((1000003 * res) ^ y) + return res + +def args_dict(): + return r_dict(args_eq, args_hash) + + Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Sun Jan 24 20:19:22 2010 @@ -1861,6 +1861,36 @@ """ self.optimize_loop(ops, "Not", expected) + def test_remove_duplicate_pure_op(self): + ops = """ + [p1, p2] + i1 = oois(p1, p2) + i2 = oois(p1, p2) + i3 = int_add(i1, 1) + i3b = int_is_true(i3) + guard_true(i3b) [] + i4 = int_add(i2, 1) + i4b = int_is_true(i4) + guard_true(i4b) [] + escape(i3) + escape(i4) + guard_true(i1) [] + guard_true(i2) [] + jump(p1, p2) + """ + expected = """ + [p1, p2] + i1 = oois(p1, p2) + i3 = int_add(i1, 1) + i3b = int_is_true(i3) + guard_true(i3b) [] + escape(i3) + escape(i3) + guard_true(i1) [] + jump(p1, p2) + """ + self.optimize_loop(ops, "Not, Not", expected) + # ---------- def make_fail_descr(self): From arigo at codespeak.net Sun Jan 24 20:28:13 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 24 Jan 2010 20:28:13 +0100 (CET) Subject: [pypy-svn] r70807 - pypy/branch/lazy-operr-format Message-ID: <20100124192813.B63ED1680B8@codespeak.net> Author: arigo Date: Sun Jan 24 20:28:13 2010 New Revision: 70807 Added: pypy/branch/lazy-operr-format/ - copied from r70806, pypy/trunk/ Log: A branch in which to implement lazy string formatting for building OperationErrors. From arigo at codespeak.net Sun Jan 24 20:29:51 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 24 Jan 2010 20:29:51 +0100 (CET) Subject: [pypy-svn] r70808 - in pypy/branch/lazy-operr-format/pypy/interpreter: . test Message-ID: <20100124192951.45A1B1680B8@codespeak.net> Author: arigo Date: Sun Jan 24 20:29:50 2010 New Revision: 70808 Added: pypy/branch/lazy-operr-format/pypy/interpreter/test/test_error.py (contents, props changed) Modified: pypy/branch/lazy-operr-format/pypy/interpreter/error.py Log: First version. Modified: pypy/branch/lazy-operr-format/pypy/interpreter/error.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/error.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/error.py Sun Jan 24 20:29:50 2010 @@ -21,7 +21,7 @@ from pypy.tool.error import FlowingError raise FlowingError(w_value) self.w_type = w_type - self.w_value = w_value + self._w_value = w_value self.application_traceback = tb if not we_are_translated(): self.debug_excs = [] @@ -29,7 +29,7 @@ def clear(self, space): # for sys.exc_clear() self.w_type = space.w_None - self.w_value = space.w_None + self._w_value = space.w_None self.application_traceback = None if not we_are_translated(): del self.debug_excs[:] @@ -45,14 +45,15 @@ def __str__(self): "NOT_RPYTHON: Convenience for tracebacks." - return '[%s: %s]' % (self.w_type, self.w_value) + return '[%s: %s]' % (self.w_type, self._w_value) def errorstr(self, space): "The exception class and value, as a string." + w_value = self.get_w_value(space) if space is None: # this part NOT_RPYTHON exc_typename = str(self.w_type) - exc_value = str(self.w_value) + exc_value = str(w_value) else: w = space.wrap if space.is_w(space.type(self.w_type), space.w_str): @@ -60,11 +61,11 @@ else: exc_typename = space.str_w( space.getattr(self.w_type, w('__name__'))) - if space.is_w(self.w_value, space.w_None): + if space.is_w(w_value, space.w_None): exc_value = "" else: try: - exc_value = space.str_w(space.str(self.w_value)) + exc_value = space.str_w(space.str(w_value)) except OperationError: # oups, cannot __str__ the exception object exc_value = "" @@ -165,7 +166,7 @@ # (inst, None) (inst.__class__, inst) no # w_type = self.w_type - w_value = self.w_value + w_value = self.get_w_value(space) if space.full_exceptions: while space.is_true(space.isinstance(w_type, space.w_tuple)): w_type = space.getitem(w_type, space.wrap(0)) @@ -214,8 +215,8 @@ w_value = w_inst w_type = w_instclass - self.w_type = w_type - self.w_value = w_value + self.w_type = w_type + self._w_value = w_value def write_unraisable(self, space, where, w_object=None): if w_object is None: @@ -232,6 +233,83 @@ except OperationError: pass # ignored + def get_w_value(self, space): + w_value = self.w_value + if w_value is None: + value = self._compute_value() + self.w_value = w_value = space.wrap(value) + return w_value + + def _compute_value(self): + raise NotImplementedError + +# ____________________________________________________________ +# optimization only: avoid the slowest operation -- the string +# formatting with '%' -- in the common case were we don't +# actually need the message. Only supports %s and %d. + +_fmtcache = {} +_fmtcache2 = {} + +def decompose_valuefmt(valuefmt): + formats = [] + parts = valuefmt.split('%') + i = 1 + while i < len(parts): + if parts[i].startswith('s') or parts[i].startswith('d'): + formats.append(parts[i][0]) + parts[i] = parts[i][1:] + i += 1 + elif parts[i].startswith('%'): + parts[i-1] += parts.pop(i) + else: + raise ValueError("invalid format string (only %s or %d supported)") + return tuple(parts), tuple(formats) + +def get_operrcls2(valuefmt): + strings, formats = decompose_valuefmt(valuefmt) + assert len(strings) == len(formats) + 1 + try: + OpErrFmt = _fmtcache2[formats] + except KeyError: + from pypy.rlib.unroll import unrolling_iterable + attrs = ['x%d' % i for i in range(len(formats))] + entries = unrolling_iterable(enumerate(attrs)) + # + class OpErrFmt(OperationError): + def __init__(self, w_type, strings, *args): + OperationError.__init__(self, w_type, None) + assert len(args) == len(strings) - 1 + self.xstrings = strings + for i, attr in entries: + setattr(self, attr, args[i]) + def _compute_value(self): + lst = [None] * (len(formats) + len(formats) + 1) + for i, attr in entries: + string = self.xstrings[i] + value = getattr(self, attr) + lst[i+i] = string + lst[i+i+1] = str(value) + lst[-1] = self.xstrings[-1] + return ''.join(lst) + # + _fmtcache2[formats] = OpErrFmt + return OpErrFmt, strings + +def get_operationerr_class(valuefmt): + try: + result = _fmtcache[valuefmt] + except KeyError: + result = _fmtcache[valuefmt] = get_operrcls2(valuefmt) + return result +get_operationerr_class._annspecialcase_ = 'specialize:memo' + +def operationerrfmt(w_type, valuefmt, *args): + OpErrFmt, strings = get_operationerr_class(valuefmt) + return OpErrFmt(w_type, strings, *args) + +# ____________________________________________________________ + # Utilities from pypy.tool.ansi_print import ansi_print Added: pypy/branch/lazy-operr-format/pypy/interpreter/test/test_error.py ============================================================================== --- (empty file) +++ pypy/branch/lazy-operr-format/pypy/interpreter/test/test_error.py Sun Jan 24 20:29:50 2010 @@ -0,0 +1,23 @@ +from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.error import decompose_valuefmt, get_operrcls2 + + +def test_decompose_valuefmt(): + assert (decompose_valuefmt("abc %s def") == + (("abc ", " def"), ('s',))) + assert (decompose_valuefmt("%s%d%s") == + (("", "", "", ""), ('s', 'd', 's'))) + +def test_get_operrcls2(): + cls, strings = get_operrcls2('abc %s def %d') + assert strings == ("abc ", " def ", "") + assert issubclass(cls, OperationError) + inst = cls("w_type", strings, "hello", 42) + assert inst._compute_value() == "abc hello def 42" + +def test_operationerrfmt(): + operr = operationerrfmt("w_type", "abc %s def %d", "foo", 42) + assert isinstance(operr, OperationError) + assert operr.w_type == "w_type" + assert operr._w_value is None + assert operr._compute_value() == "abc foo def 42" From fijal at codespeak.net Sun Jan 24 20:30:57 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 24 Jan 2010 20:30:57 +0100 (CET) Subject: [pypy-svn] r70810 - pypy/branch/direct-assembler-call/pypy/jit/backend Message-ID: <20100124193057.17F011680B8@codespeak.net> Author: fijal Date: Sun Jan 24 20:30:56 2010 New Revision: 70810 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/model.py Log: oops, a forgotten fix Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/model.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/model.py Sun Jan 24 20:30:56 2010 @@ -1,4 +1,4 @@ -from pypy.jit.metainterp import history +from pypy.jit.metainterp import history, compile class AbstractCPU(object): @@ -6,6 +6,7 @@ # assembler_helper_ptr - a pointer to helper to call after a direct # assembler call portal_calldescr = None + done_with_this_frame_int_v = -1 def __init__(self): self.fail_descr_list = [] From benjamin at codespeak.net Sun Jan 24 20:32:30 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 24 Jan 2010 20:32:30 +0100 (CET) Subject: [pypy-svn] r70811 - in pypy/trunk/pypy/objspace: std test Message-ID: <20100124193230.763581680B8@codespeak.net> Author: benjamin Date: Sun Jan 24 20:32:29 2010 New Revision: 70811 Modified: pypy/trunk/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/test/test_descriptor.py Log: don't search in the obj dict or return the descr if __get__ raises an AttributeError Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Sun Jan 24 20:32:29 2010 @@ -664,12 +664,13 @@ except OperationError, e: if not e.match(self, self.w_AttributeError): raise - w_value = w_obj.getdictvalue(self, name) - if w_value is not None: - return w_value - # No value in __dict__. Fallback to the descriptor if we have it. - if w_descr is not None: - return w_descr + if e is None: + w_value = w_obj.getdictvalue(self, name) + if w_value is not None: + return w_value + # No value in __dict__. Fallback to the descriptor if we have it. + if w_descr is not None: + return w_descr w_descr = self.lookup(w_obj, '__getattr__') if w_descr is not None: Modified: pypy/trunk/pypy/objspace/test/test_descriptor.py ============================================================================== --- pypy/trunk/pypy/objspace/test/test_descriptor.py (original) +++ pypy/trunk/pypy/objspace/test/test_descriptor.py Sun Jan 24 20:32:29 2010 @@ -49,6 +49,7 @@ if name == 'v': return 42 x = X() + print(x.v) assert x.v == 42 # ... but the __dict__ is not searched From benjamin at codespeak.net Sun Jan 24 20:32:49 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 24 Jan 2010 20:32:49 +0100 (CET) Subject: [pypy-svn] r70812 - pypy/trunk/pypy/objspace/test Message-ID: <20100124193249.4432C1680B8@codespeak.net> Author: benjamin Date: Sun Jan 24 20:32:48 2010 New Revision: 70812 Modified: pypy/trunk/pypy/objspace/test/test_descriptor.py Log: kill print Modified: pypy/trunk/pypy/objspace/test/test_descriptor.py ============================================================================== --- pypy/trunk/pypy/objspace/test/test_descriptor.py (original) +++ pypy/trunk/pypy/objspace/test/test_descriptor.py Sun Jan 24 20:32:48 2010 @@ -49,7 +49,6 @@ if name == 'v': return 42 x = X() - print(x.v) assert x.v == 42 # ... but the __dict__ is not searched From fijal at codespeak.net Sun Jan 24 21:45:26 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 24 Jan 2010 21:45:26 +0100 (CET) Subject: [pypy-svn] r70813 - pypy/benchmarks/own Message-ID: <20100124204526.9576016807B@codespeak.net> Author: fijal Date: Sun Jan 24 21:45:23 2010 New Revision: 70813 Added: pypy/benchmarks/own/b.py (contents, props changed) Log: Here is stripped-down example of spitfire benchmark Added: pypy/benchmarks/own/b.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/b.py Sun Jan 24 21:45:23 2010 @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +table = [range(1000) for i in range(1000)] + +class a(object): + def main(self, table): + _buffer = [] + _buffer_write = _buffer.append + _buffer_write(u'') + _buffer_write(u'\n') + for row in table: + _buffer_write(u'') + _buffer_write(u'\n') + for column in row: + _buffer_write(u'') + _buffer_write(u'\n') + _buffer_write(u'') + _buffer_write(u'\n') + _buffer_write(u'
      ') + _buffer_write('%s' % column) + _buffer_write(u'
      ') + _buffer_write(u'\n') + return ''.join(_buffer) + + +if __name__ == '__main__': + a().main(table) From arigo at codespeak.net Mon Jan 25 10:46:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 10:46:15 +0100 (CET) Subject: [pypy-svn] r70818 - in pypy/branch/lazy-operr-format/pypy: interpreter objspace/flow Message-ID: <20100125094615.0B8791680F4@codespeak.net> Author: arigo Date: Mon Jan 25 10:46:15 2010 New Revision: 70818 Modified: pypy/branch/lazy-operr-format/pypy/interpreter/baseobjspace.py pypy/branch/lazy-operr-format/pypy/interpreter/error.py pypy/branch/lazy-operr-format/pypy/interpreter/executioncontext.py pypy/branch/lazy-operr-format/pypy/interpreter/main.py pypy/branch/lazy-operr-format/pypy/interpreter/typedef.py pypy/branch/lazy-operr-format/pypy/objspace/flow/flowcontext.py Log: In-progress. Modified: pypy/branch/lazy-operr-format/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/baseobjspace.py Mon Jan 25 10:46:15 2010 @@ -825,7 +825,8 @@ try: w_res = self.call_args(w_func, args) except OperationError, e: - ec.c_exception_trace(frame, e.w_value) + w_value = e.get_w_value(self) + ec.c_exception_trace(frame, w_value) raise ec.c_return_trace(frame, w_func) return w_res Modified: pypy/branch/lazy-operr-format/pypy/interpreter/error.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/error.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/error.py Mon Jan 25 10:46:15 2010 @@ -16,6 +16,9 @@ PyTraceback objects making the application-level traceback. """ + __slots__ = ('w_type', '_w_value', 'application_traceback', + 'debug_excs') + def __init__(self, w_type, w_value, tb=None): if w_type is None: from pypy.tool.error import FlowingError @@ -234,10 +237,10 @@ pass # ignored def get_w_value(self, space): - w_value = self.w_value + w_value = self._w_value if w_value is None: value = self._compute_value() - self.w_value = w_value = space.wrap(value) + self._w_value = w_value = space.wrap(value) return w_value def _compute_value(self): @@ -305,6 +308,9 @@ get_operationerr_class._annspecialcase_ = 'specialize:memo' def operationerrfmt(w_type, valuefmt, *args): + """Equivalent to OperationError(w_type, space.wrap(valuefmt % args)). + More efficient in the (common) case where the value is not actually + needed.""" OpErrFmt, strings = get_operationerr_class(valuefmt) return OpErrFmt(w_type, strings, *args) Modified: pypy/branch/lazy-operr-format/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/executioncontext.py Mon Jan 25 10:46:15 2010 @@ -265,7 +265,8 @@ if w_callback is not None and event != "leaveframe": if operr is not None: - w_arg = space.newtuple([operr.w_type, operr.w_value, + w_value = operr.get_w_value(space) + w_arg = space.newtuple([operr.w_type, w_value, space.wrap(operr.application_traceback)]) frame.fast2locals() Modified: pypy/branch/lazy-operr-format/pypy/interpreter/main.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/main.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/main.py Mon Jan 25 10:46:15 2010 @@ -117,7 +117,7 @@ except OperationError, operationerr: operationerr.normalize_exception(space) w_type = operationerr.w_type - w_value = operationerr.w_value + w_value = operationerr.get_w_value(space) w_traceback = space.wrap(operationerr.application_traceback) # for debugging convenience we also insert the exception into @@ -128,7 +128,7 @@ try: # exit if we catch a w_SystemExit if operationerr.match(space, space.w_SystemExit): - w_exitcode = space.getattr(operationerr.w_value, + w_exitcode = space.getattr(w_value, space.wrap('code')) if space.is_w(w_exitcode, space.w_None): exitcode = 0 Modified: pypy/branch/lazy-operr-format/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/typedef.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/typedef.py Mon Jan 25 10:46:15 2010 @@ -7,7 +7,7 @@ from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, W_Root, ObjSpace, \ DescrMismatch -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.tool.sourcetools import compile2, func_with_new_name from pypy.rlib.objectmodel import instantiate, compute_identity_hash from pypy.rlib.jit import hint @@ -52,8 +52,8 @@ def descr__hash__unhashable(space, w_obj): typename = space.type(w_obj).getname(space, '?') - msg = "%s objects are unhashable" % (typename,) - raise OperationError(space.w_TypeError,space.wrap(msg)) + raise operationerrfmt(space.w_TypeError, + "%s objects are unhashable", typename) no_hash_descr = interp2app(descr__hash__unhashable) Modified: pypy/branch/lazy-operr-format/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/flow/flowcontext.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/flow/flowcontext.py Mon Jan 25 10:46:15 2010 @@ -276,7 +276,7 @@ raise Exception( 'found an operation that always raises %s: %s' % ( self.space.unwrap(e.w_type).__name__, - self.space.unwrap(e.w_value))) + self.space.unwrap(e.get_w_value(self.space)))) except ImplicitOperationError, e: if isinstance(e.w_type, Constant): @@ -295,7 +295,8 @@ e.w_type is self.space.w_ImportError): raise ImportError('import statement always raises %s' % ( e,)) - link = self.make_link([e.w_type, e.w_value], self.graph.exceptblock) + w_value = e.get_w_value(self.space) + link = self.make_link([e.w_type, w_value], self.graph.exceptblock) self.recorder.crnt_block.closeblock(link) except StopFlowing: @@ -382,7 +383,8 @@ operr = ExecutionContext.sys_exc_info(self) if isinstance(operr, ImplicitOperationError): # re-raising an implicit operation makes it an explicit one - operr = OperationError(operr.w_type, operr.w_value) + w_value = operr.get_w_value(self.space) + operr = OperationError(operr.w_type, w_value) return operr def exception_trace(self, frame, operationerr): From fijal at codespeak.net Mon Jan 25 10:57:44 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 10:57:44 +0100 (CET) Subject: [pypy-svn] r70819 - pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph Message-ID: <20100125095744.2961316804B@codespeak.net> Author: fijal Date: Mon Jan 25 10:57:44 2010 New Revision: 70819 Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py Log: check the return value while returning with exception Modified: pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/backend/llgraph/llimpl.py Mon Jan 25 10:57:44 2010 @@ -844,6 +844,10 @@ except LLException, lle: assert _last_exception is None, "exception left behind" _last_exception = lle + # fish op + op = self.loop.operations[self.opindex] + if op.result is not None: + return 0 finally: self._may_force = -1 From fijal at codespeak.net Mon Jan 25 12:39:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 12:39:56 +0100 (CET) Subject: [pypy-svn] r70821 - pypy/branch/direct-assembler-call/pypy/jit/metainterp Message-ID: <20100125113956.7D55D1680F7@codespeak.net> Author: fijal Date: Mon Jan 25 12:39:56 2010 New Revision: 70821 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Log: A missing commit Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/pyjitpl.py Mon Jan 25 12:39:56 2010 @@ -1117,6 +1117,9 @@ self._addr2name_values = [] self.__dict__.update(compile.make_done_loop_tokens()) + # store this information for fastpath of call_assembler + d = self.loop_tokens_done_with_this_frame_int[0].finishdescr + self.cpu.done_with_this_frame_int_v = self.cpu.get_fail_descr_number(d) def _freeze_(self): return True From fijal at codespeak.net Mon Jan 25 12:50:51 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 12:50:51 +0100 (CET) Subject: [pypy-svn] r70822 - pypy/branch/direct-assembler-call/pypy/interpreter Message-ID: <20100125115051.93B571680F8@codespeak.net> Author: fijal Date: Mon Jan 25 12:50:51 2010 New Revision: 70822 Modified: pypy/branch/direct-assembler-call/pypy/interpreter/pyopcode.py Log: Always inline handle_bytecode and dispatch_bytecode. There are two important points here: * If we're extremely unlucky, we might end up with call to handle_bytecode becoming a residual call if we abort tracing in an unfortunate moment. This causes starting to compile the same loop again, hence explosion with "entering the same frame via blackhole" * We should always inline any function that has a single call point, this is what gcc does for example. Modified: pypy/branch/direct-assembler-call/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/direct-assembler-call/pypy/interpreter/pyopcode.py Mon Jan 25 12:50:51 2010 @@ -119,6 +119,7 @@ self.space.w_RuntimeError, self.space.wrap(msg)) return next_instr + handle_bytecode._always_inline_ = True def handle_asynchronous_error(self, ec, w_type, w_value=None): # catch asynchronous exceptions and turn them @@ -270,6 +271,7 @@ if jit.we_are_jitted(): return next_instr + dispatch_bytecode._always_inline_ = True @jit.unroll_safe def unrollstack(self, unroller_kind): From fijal at codespeak.net Mon Jan 25 13:12:57 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 13:12:57 +0100 (CET) Subject: [pypy-svn] r70823 - pypy/branch/direct-assembler-call/pypy/jit/metainterp/test Message-ID: <20100125121257.AFD111680F6@codespeak.net> Author: fijal Date: Mon Jan 25 13:12:57 2010 New Revision: 70823 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_codewriter.py Log: A test that checks if _always_inline_ and jit.unroll_safe are compatible Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_codewriter.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_codewriter.py Mon Jan 25 13:12:57 2010 @@ -79,7 +79,27 @@ supports_floats=True) funcs = set([graph.func for graph in res]) assert funcs == set([f, h]) - + +def test_unroll_safe_and_inline(): + @jit.unroll_safe + def h(x): + i = 0 + while i < x: + i += 1 + return i + h._always_inline_ = True + + def g(x): + return h(x) + + rtyper = support.annotate(g, [7]) + cw = CodeWriter(rtyper) + jitpolicy = JitPolicy() + translator = rtyper.annotator.translator + res = cw.find_all_graphs(translator.graphs[0], None, jitpolicy, + supports_floats=True) + funcs = set([graph.func for graph in res]) + assert funcs == set([g, h]) def test_find_all_graphs_str_join(): def i(x, y): From fijal at codespeak.net Mon Jan 25 13:31:46 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 13:31:46 +0100 (CET) Subject: [pypy-svn] r70824 - pypy/branch/direct-assembler-call/pypy/interpreter Message-ID: <20100125123146.816F11680F6@codespeak.net> Author: fijal Date: Mon Jan 25 13:31:46 2010 New Revision: 70824 Modified: pypy/branch/direct-assembler-call/pypy/interpreter/pyopcode.py Log: Revert 70822, to be forgotten Modified: pypy/branch/direct-assembler-call/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/direct-assembler-call/pypy/interpreter/pyopcode.py Mon Jan 25 13:31:46 2010 @@ -119,7 +119,6 @@ self.space.w_RuntimeError, self.space.wrap(msg)) return next_instr - handle_bytecode._always_inline_ = True def handle_asynchronous_error(self, ec, w_type, w_value=None): # catch asynchronous exceptions and turn them @@ -271,7 +270,6 @@ if jit.we_are_jitted(): return next_instr - dispatch_bytecode._always_inline_ = True @jit.unroll_safe def unrollstack(self, unroller_kind): From fijal at codespeak.net Mon Jan 25 13:35:01 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 13:35:01 +0100 (CET) Subject: [pypy-svn] r70825 - in pypy/branch/direct-assembler-call/pypy/jit/metainterp: . test Message-ID: <20100125123501.5EC141680F6@codespeak.net> Author: fijal Date: Mon Jan 25 13:34:59 2010 New Revision: 70825 Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py Log: return instead of assert. it seems to be a bit fragile. this fix is not really a valid one, but it's improving things. to be investigated on trunk. Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/test/test_virtualizable.py Mon Jan 25 13:34:59 2010 @@ -1193,6 +1193,8 @@ self.check_loops(getfield_gc=0, setfield_gc=0) def test_blackhole_should_not_reenter(self): + # Armin thinks this can occur and does not make interpreters slower + # so we don't check for assertionerror, to be discussed if not self.basic: py.test.skip("purely frontend test") @@ -1234,8 +1236,9 @@ f(10, True) return f(10, False) - einfo = py.test.raises(AssertionError, self.meta_interp, main, []) - assert einfo.value.args[0] == "reentering same frame via blackhole" + self.meta_interp(main, []) + #einfo = py.test.raises(AssertionError, self.meta_interp, main, []) + #assert einfo.value.args[0] == "reentering same frame via blackhole" def test_inlining(self): class Frame(object): Modified: pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py (original) +++ pypy/branch/direct-assembler-call/pypy/jit/metainterp/warmstate.py Mon Jan 25 13:34:59 2010 @@ -212,8 +212,8 @@ if vinfo is not None: virtualizable = args[vinfo.index_of_virtualizable] virtualizable = vinfo.cast_to_vtype(virtualizable) - assert virtualizable != globaldata.blackhole_virtualizable, ( - "reentering same frame via blackhole") + if globaldata.blackhole_virtualizable == virtualizable: + return else: virtualizable = None From fijal at codespeak.net Mon Jan 25 13:38:41 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 13:38:41 +0100 (CET) Subject: [pypy-svn] r70826 - pypy/extradoc/planning Message-ID: <20100125123841.257081680F9@codespeak.net> Author: fijal Date: Mon Jan 25 13:38:40 2010 New Revision: 70826 Modified: pypy/extradoc/planning/jit.txt Log: Mention the thing about blackhole/reenter Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Mon Jan 25 13:38:40 2010 @@ -24,6 +24,9 @@ - some guards will always fail if they ever start failing (e.g. the class version tag). Do something more clever about it. +- investigate the case of test_virtualizable.test_blackhole_should_not_reenter + and corresponding code in warmstate.maybe_compile_and_run about return/assert + when we enter the same frame which we are blackholing Python interpreter: From fijal at codespeak.net Mon Jan 25 14:40:59 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 14:40:59 +0100 (CET) Subject: [pypy-svn] r70827 - pypy/trunk/pypy/jit/tool Message-ID: <20100125134059.D8C701680A3@codespeak.net> Author: fijal Date: Mon Jan 25 14:40:59 2010 New Revision: 70827 Modified: pypy/trunk/pypy/jit/tool/showstats.py Log: Improve this tool, laying down in my wc for a while now Modified: pypy/trunk/pypy/jit/tool/showstats.py ============================================================================== --- pypy/trunk/pypy/jit/tool/showstats.py (original) +++ pypy/trunk/pypy/jit/tool/showstats.py Mon Jan 25 14:40:59 2010 @@ -1,4 +1,6 @@ #!/usr/bin/env python +from __future__ import division + import autopath import sys, py from pypy.tool import logparser @@ -9,7 +11,7 @@ def main(argv): log = logparser.parse_log_file(argv[0]) parts = logparser.extract_category(log, "jit-log-opt-") - for oplist in parts: + for i, oplist in enumerate(parts): loop = parse(oplist, no_namespace=True) num_ops = 0 num_dmp = 0 @@ -21,7 +23,7 @@ num_ops += 1 if op.is_guard(): num_guards += 1 - print "Loop, length: %d, opcodes: %d, guards: %d" % (num_ops, num_dmp, num_guards) + print "Loop #%d, length: %d, opcodes: %d, guards: %d, %f" % (i, num_ops, num_dmp, num_guards, num_ops/num_dmp) if __name__ == '__main__': main(sys.argv[1:]) From arigo at codespeak.net Mon Jan 25 14:45:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 14:45:15 +0100 (CET) Subject: [pypy-svn] r70828 - in pypy/branch/lazy-operr-format/pypy/interpreter: . test Message-ID: <20100125134515.7AC3E1680A3@codespeak.net> Author: arigo Date: Mon Jan 25 14:45:14 2010 New Revision: 70828 Modified: pypy/branch/lazy-operr-format/pypy/interpreter/error.py pypy/branch/lazy-operr-format/pypy/interpreter/test/test_error.py Log: Improve the implementation and the tests a bit. Modified: pypy/branch/lazy-operr-format/pypy/interpreter/error.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/error.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/error.py Mon Jan 25 14:45:14 2010 @@ -255,6 +255,8 @@ _fmtcache2 = {} def decompose_valuefmt(valuefmt): + """Returns a tuple of string parts extracted from valuefmt, + and a tuple of format characters.""" formats = [] parts = valuefmt.split('%') i = 1 @@ -263,10 +265,12 @@ formats.append(parts[i][0]) parts[i] = parts[i][1:] i += 1 - elif parts[i].startswith('%'): - parts[i-1] += parts.pop(i) + elif parts[i] == '': # support for '%%' + parts[i-1] += '%' + parts[i+1] + del parts[i:i+2] else: raise ValueError("invalid format string (only %s or %d supported)") + assert len(formats) > 0, "unsupported: no % command found" return tuple(parts), tuple(formats) def get_operrcls2(valuefmt): @@ -313,6 +317,7 @@ needed.""" OpErrFmt, strings = get_operationerr_class(valuefmt) return OpErrFmt(w_type, strings, *args) +operationerrfmt._annspecialcase_ = 'specialize:arg(1)' # ____________________________________________________________ Modified: pypy/branch/lazy-operr-format/pypy/interpreter/test/test_error.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/test/test_error.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/test/test_error.py Mon Jan 25 14:45:14 2010 @@ -1,3 +1,4 @@ +import py from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.error import decompose_valuefmt, get_operrcls2 @@ -7,6 +8,8 @@ (("abc ", " def"), ('s',))) assert (decompose_valuefmt("%s%d%s") == (("", "", "", ""), ('s', 'd', 's'))) + assert (decompose_valuefmt("%s%d%%%s") == + (("", "", "%", ""), ('s', 'd', 's'))) def test_get_operrcls2(): cls, strings = get_operrcls2('abc %s def %d') @@ -14,6 +17,9 @@ assert issubclass(cls, OperationError) inst = cls("w_type", strings, "hello", 42) assert inst._compute_value() == "abc hello def 42" + cls2, strings2 = get_operrcls2('a %s b %d c') + assert cls2 is cls # caching + assert strings2 == ("a ", " b ", " c") def test_operationerrfmt(): operr = operationerrfmt("w_type", "abc %s def %d", "foo", 42) @@ -21,3 +27,10 @@ assert operr.w_type == "w_type" assert operr._w_value is None assert operr._compute_value() == "abc foo def 42" + operr2 = operationerrfmt("w_type2", "a %s b %d c", "bar", 43) + assert operr2.__class__ is operr.__class__ + operr3 = operationerrfmt("w_type2", "a %s b %s c", "bar", "4b") + assert operr3.__class__ is not operr.__class__ + +def test_operationerrfmt_empty(): + py.test.raises(AssertionError, operationerrfmt, "w_type", "foobar") From fijal at codespeak.net Mon Jan 25 14:47:15 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 14:47:15 +0100 (CET) Subject: [pypy-svn] r70829 - in pypy/trunk/pypy/jit: backend backend/llgraph backend/llgraph/test backend/test backend/x86 backend/x86/test metainterp metainterp/test Message-ID: <20100125134715.AD0DB1680A3@codespeak.net> Author: fijal Date: Mon Jan 25 14:47:13 2010 New Revision: 70829 Modified: pypy/trunk/pypy/jit/backend/llgraph/llimpl.py pypy/trunk/pypy/jit/backend/llgraph/runner.py pypy/trunk/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/trunk/pypy/jit/backend/model.py pypy/trunk/pypy/jit/backend/test/runner_test.py pypy/trunk/pypy/jit/backend/test/support.py pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/regalloc.py pypy/trunk/pypy/jit/backend/x86/runner.py pypy/trunk/pypy/jit/backend/x86/test/test_recursive.py pypy/trunk/pypy/jit/backend/x86/test/test_runner.py pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py pypy/trunk/pypy/jit/metainterp/history.py pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/pyjitpl.py pypy/trunk/pypy/jit/metainterp/resoperation.py pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py pypy/trunk/pypy/jit/metainterp/test/test_compile.py pypy/trunk/pypy/jit/metainterp/test/test_history.py pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py pypy/trunk/pypy/jit/metainterp/test/test_recursive.py pypy/trunk/pypy/jit/metainterp/test/test_virtualizable.py pypy/trunk/pypy/jit/metainterp/test/test_warmspot.py pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py pypy/trunk/pypy/jit/metainterp/test/test_ztranslation.py pypy/trunk/pypy/jit/metainterp/warmspot.py pypy/trunk/pypy/jit/metainterp/warmstate.py Log: (pedronis, fijal) Merge the direct-assembler-call branch. This branch implements a new operation CALL_ASSEMBLER, which happens when we encounter a recursive portal call to a place that has assembler already compiled. Speeds up certain cases, some by a significant %. Slows down megamorphic calls, because with this branch, a call that was compiled as CALL_ASSEMBLER is now a guard failure in case code object is not the same. Modified: pypy/trunk/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/trunk/pypy/jit/backend/llgraph/llimpl.py Mon Jan 25 14:47:13 2010 @@ -125,6 +125,7 @@ 'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'), 'arraylen_gc' : (('ref',), 'int'), 'call' : (('ref', 'varargs'), 'intorptr'), + 'call_assembler' : (('ref', 'varargs'), 'intorptr'), 'call_pure' : (('ref', 'varargs'), 'intorptr'), 'cond_call_gc_wb' : (('int', 'int', 'ptr', 'varargs'), None), 'oosend' : (('varargs',), 'intorptr'), @@ -316,6 +317,11 @@ assert isinstance(type, str) and len(type) == 1 op.descr = Descr(ofs, type) +def compile_add_loop_token(loop, descr): + loop = _from_opaque(loop) + op = loop.operations[-1] + op.descr = descr + def compile_add_var(loop, intvar): loop = _from_opaque(loop) op = loop.operations[-1] @@ -391,8 +397,9 @@ class Frame(object): OPHANDLERS = [None] * (rop._LAST+1) - def __init__(self, memocast): + def __init__(self, memocast, cpu): self.verbose = False + self.cpu = cpu self.memocast = memocast self.opindex = 1 self._forced = False @@ -809,6 +816,41 @@ finally: self._may_force = -1 + def op_call_assembler(self, loop_token, *args): + global _last_exception + assert not self._forced + self._may_force = self.opindex + try: + inpargs = _from_opaque(loop_token._llgraph_compiled_version).inputargs + for i, inparg in enumerate(inpargs): + TYPE = inparg.concretetype + if TYPE is lltype.Signed: + set_future_value_int(i, args[i]) + elif isinstance(TYPE, lltype.Ptr): + set_future_value_ref(i, args[i]) + elif TYPE is lltype.Float: + set_future_value_float(i, args[i]) + else: + raise Exception("Nonsense type %s" % TYPE) + + failindex = self.cpu._execute_token(loop_token) + try: + if self.cpu.index_of_virtualizable != -1: + return self.cpu.assembler_helper_ptr(failindex, + args[self.cpu.index_of_virtualizable]) + else: + return self.cpu.assembler_helper_ptr(failindex, + lltype.nullptr(llmemory.GCREF.TO)) + except LLException, lle: + assert _last_exception is None, "exception left behind" + _last_exception = lle + # fish op + op = self.loop.operations[self.opindex] + if op.result is not None: + return 0 + finally: + self._may_force = -1 + def op_guard_not_forced(self, descr): forced = self._forced self._forced = False @@ -969,11 +1011,11 @@ return x -def new_frame(memocast, is_oo): +def new_frame(memocast, is_oo, cpu): if is_oo: - frame = OOFrame(memocast) + frame = OOFrame(memocast, cpu) else: - frame = Frame(memocast) + frame = Frame(memocast, cpu) return _to_opaque(frame) _future_values = [] @@ -1094,7 +1136,8 @@ assert frame._may_force >= 0 call_op = frame.loop.operations[frame._may_force] guard_op = frame.loop.operations[frame._may_force+1] - assert call_op.opnum == rop.CALL_MAY_FORCE + opnum = call_op.opnum + assert opnum == rop.CALL_MAY_FORCE or opnum == rop.CALL_ASSEMBLER frame._populate_fail_args(guard_op, skip=call_op.result) return frame.fail_index Modified: pypy/trunk/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/trunk/pypy/jit/backend/llgraph/runner.py Mon Jan 25 14:47:13 2010 @@ -74,7 +74,8 @@ class BaseCPU(model.AbstractCPU): supports_floats = True - def __init__(self, rtyper, stats=None, opts=None, translate_support_code=False, + def __init__(self, rtyper, stats=None, opts=None, + translate_support_code=False, annmixlevel=None, gcdescr=None): assert type(opts) is not bool model.AbstractCPU.__init__(self) @@ -147,6 +148,8 @@ descr = op.descr if isinstance(descr, Descr): llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo) + if isinstance(descr, history.LoopToken): + llimpl.compile_add_loop_token(c, descr) if self.is_oo and isinstance(descr, (OODescr, MethDescr)): # hack hack, not rpython c._obj.externalobj.operations[-1].descr = descr @@ -207,18 +210,22 @@ else: assert False, "unknown operation" - def execute_token(self, loop_token): - """Calls the assembler generated for the given loop. - Returns the ResOperation that failed, of type rop.FAIL. - """ + def _execute_token(self, loop_token): compiled_version = loop_token._llgraph_compiled_version - frame = llimpl.new_frame(self.memo_cast, self.is_oo) + frame = llimpl.new_frame(self.memo_cast, self.is_oo, self) # setup the frame llimpl.frame_clear(frame, compiled_version) # run the loop fail_index = llimpl.frame_execute(frame) # we hit a FAIL operation. self.latest_frame = frame + return fail_index + + def execute_token(self, loop_token): + """Calls the assembler generated for the given loop. + Returns the ResOperation that failed, of type rop.FAIL. + """ + fail_index = self._execute_token(loop_token) return self.get_fail_descr_from_number(fail_index) def set_future_value_int(self, index, intvalue): Modified: pypy/trunk/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/trunk/pypy/jit/backend/llgraph/test/test_llgraph.py Mon Jan 25 14:47:13 2010 @@ -7,7 +7,8 @@ TreeLoop from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.metainterp.executor import execute -from pypy.jit.backend.test.runner_test import LLtypeBackendTest +from pypy.jit.backend.test.runner_test import LLtypeBackendTest, \ + BaseAssemblerCallTests class TestLLTypeLLGraph(LLtypeBackendTest): # for individual tests see: Modified: pypy/trunk/pypy/jit/backend/model.py ============================================================================== --- pypy/trunk/pypy/jit/backend/model.py (original) +++ pypy/trunk/pypy/jit/backend/model.py Mon Jan 25 14:47:13 2010 @@ -1,8 +1,12 @@ -from pypy.jit.metainterp import history +from pypy.jit.metainterp import history, compile class AbstractCPU(object): supports_floats = False + # assembler_helper_ptr - a pointer to helper to call after a direct + # assembler call + portal_calldescr = None + done_with_this_frame_int_v = -1 def __init__(self): self.fail_descr_list = [] @@ -209,6 +213,9 @@ def do_call(self, args, calldescr): raise NotImplementedError + def do_call_assembler(self, args, token): + raise NotImplementedError + def do_call_loopinvariant(self, args, calldescr): return self.do_call(args, calldescr) Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/runner_test.py (original) +++ pypy/trunk/pypy/jit/backend/test/runner_test.py Mon Jan 25 14:47:13 2010 @@ -15,6 +15,7 @@ from pypy.jit.metainterp.test.oparser import parse from pypy.rpython.annlowlevel import llhelper from pypy.rpython.llinterp import LLException +from pypy.jit.metainterp.test.oparser import parse class Runner(object): @@ -464,7 +465,7 @@ [funcbox] + args, 'float', descr=calldescr) assert abs(res.value - 4.6) < 0.0001 - + def test_call_stack_alignment(self): # test stack alignment issues, notably for Mac OS/X. # also test the ordering of the arguments. @@ -1609,6 +1610,87 @@ lltype.free(x, flavor='raw') + def test_assembler_call(self): + called = [] + def assembler_helper(failindex, virtualizable): + assert self.cpu.get_latest_value_int(0) == 10 + called.append(failindex) + return 4 + 9 + self.cpu.index_of_virtualizable = -1 + self.cpu.assembler_helper_ptr = llhelper(lltype.Ptr(lltype.FuncType + ([lltype.Signed, llmemory.GCREF], lltype.Signed)), assembler_helper) + + ops = ''' + [i0, i1] + i2 = int_add(i0, i1) + finish(i2)''' + loop = parse(ops) + looptoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + ARGS = [lltype.Signed, lltype.Signed] + RES = lltype.Signed + self.cpu.portal_calldescr = self.cpu.calldescrof( + lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES) + self.cpu.set_future_value_int(0, 1) + self.cpu.set_future_value_int(1, 2) + res = self.cpu.execute_token(looptoken) + assert self.cpu.get_latest_value_int(0) == 3 + ops = ''' + [i4, i5] + i6 = int_add(i4, 1) + i3 = call_assembler(i6, i5, descr=looptoken) + guard_not_forced()[] + finish(i3) + ''' + loop = parse(ops, namespace=locals()) + othertoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + self.cpu.set_future_value_int(0, 4) + self.cpu.set_future_value_int(1, 5) + res = self.cpu.execute_token(othertoken) + assert self.cpu.get_latest_value_int(0) == 13 + assert called + + def test_assembler_call_float(self): + called = [] + def assembler_helper(failindex, virtualizable): + assert self.cpu.get_latest_value_float(0) == 1.2 + 3.2 + called.append(failindex) + return 13.5 + self.cpu.index_of_virtualizable = -1 + self.cpu.assembler_helper_ptr = llhelper(lltype.Ptr(lltype.FuncType + ([lltype.Signed, llmemory.GCREF], lltype.Float)), assembler_helper) + ARGS = [lltype.Float, lltype.Float] + RES = lltype.Float + self.cpu.portal_calldescr = self.cpu.calldescrof( + lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES) + + ops = ''' + [f0, f1] + f2 = float_add(f0, f1) + finish(f2)''' + loop = parse(ops) + looptoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + self.cpu.set_future_value_float(0, 1.2) + self.cpu.set_future_value_float(1, 2.3) + res = self.cpu.execute_token(looptoken) + assert self.cpu.get_latest_value_float(0) == 1.2 + 2.3 + ops = ''' + [f4, f5] + f3 = call_assembler(f4, f5, descr=looptoken) + guard_not_forced()[] + finish(f3) + ''' + loop = parse(ops, namespace=locals()) + othertoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + self.cpu.set_future_value_float(0, 1.2) + self.cpu.set_future_value_float(1, 3.2) + res = self.cpu.execute_token(othertoken) + assert self.cpu.get_latest_value_float(0) == 13.5 + assert called + class OOtypeBackendTest(BaseBackendTest): type_system = 'ootype' @@ -1646,3 +1728,4 @@ def alloc_unicode(self, unicode): py.test.skip("implement me") + Modified: pypy/trunk/pypy/jit/backend/test/support.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/support.py (original) +++ pypy/trunk/pypy/jit/backend/test/support.py Mon Jan 25 14:47:13 2010 @@ -120,6 +120,7 @@ def _get_TranslationContext(self): t = TranslationContext() t.config.translation.gc = 'boehm' + t.config.translation.list_comprehension_operations = True return t def _compile_and_run(self, t, entry_point, entry_point_graph, args): Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Mon Jan 25 14:47:13 2010 @@ -2,7 +2,8 @@ import ctypes from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.history import Const, Box, BoxInt, BoxPtr, BoxFloat -from pypy.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT +from pypy.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT,\ + LoopToken from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory from pypy.rpython.lltypesystem.rclass import OBJECT from pypy.rpython.lltypesystem.lloperation import llop @@ -86,6 +87,7 @@ self.malloc_array_func_addr = 0 self.malloc_str_func_addr = 0 self.malloc_unicode_func_addr = 0 + self.assembler_helper_adr = 0 self.fail_boxes_int = values_array(lltype.Signed, failargs_limit) self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit) self.fail_boxes_float = values_array(lltype.Float, failargs_limit) @@ -118,6 +120,14 @@ ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode() self.malloc_unicode_func_addr = rffi.cast(lltype.Signed, ll_new_unicode) + if we_are_translated(): + self.assembler_helper_adr = self.cpu.cast_ptr_to_int( + self.cpu.assembler_helper_ptr) + else: + if getattr(self.cpu, 'assembler_helper_ptr', None): + self.assembler_helper_adr = self.cpu.cast_ptr_to_int( + self.cpu.assembler_helper_ptr) + # done # we generate the loop body in 'mc' # 'mc2' is for guard recovery code @@ -154,6 +164,7 @@ """adds the following attributes to looptoken: _x86_loop_code (an integer giving an address) _x86_bootstrap_code (an integer giving an address) + _x86_direct_bootstrap_code _x86_frame_depth _x86_param_depth _x86_arglocs @@ -162,15 +173,27 @@ regalloc = RegAlloc(self, self.cpu.translate_support_code) arglocs = regalloc.prepare_loop(inputargs, operations, looptoken) looptoken._x86_arglocs = arglocs + needed_mem = len(arglocs[0]) * 16 + 16 + if needed_mem >= self.mc.bytes_free(): + self.mc.make_new_mc() looptoken._x86_bootstrap_code = self.mc.tell() adr_stackadjust = self._assemble_bootstrap_code(inputargs, arglocs) - looptoken._x86_loop_code = self.mc.tell() + curadr = self.mc.tell() + looptoken._x86_loop_code = curadr looptoken._x86_frame_depth = -1 # temporarily looptoken._x86_param_depth = -1 # temporarily frame_depth, param_depth = self._assemble(regalloc, operations) self._patch_stackadjust(adr_stackadjust, frame_depth+param_depth) looptoken._x86_frame_depth = frame_depth looptoken._x86_param_depth = param_depth + # we need to make sure here that we don't overload an mc badly. + # a safe estimate is that we need at most 16 bytes per arg + needed_mem = len(arglocs[0]) * 16 + 16 + if needed_mem >= self.mc.bytes_free(): + self.mc.make_new_mc() + looptoken._x86_direct_bootstrap_code = self.mc.tell() + self._assemble_bootstrap_direct_call(arglocs, curadr, + frame_depth+param_depth) debug_print("Loop #", looptoken.number, "has address", looptoken._x86_loop_code, "to", self.mc.tell()) @@ -240,8 +263,7 @@ mc.write(packimm32(-WORD * aligned_words)) mc.done() - def _assemble_bootstrap_code(self, inputargs, arglocs): - nonfloatlocs, floatlocs = arglocs + def _call_header(self): self.mc.PUSH(ebp) self.mc.MOV(ebp, esp) self.mc.PUSH(ebx) @@ -249,7 +271,41 @@ self.mc.PUSH(edi) # NB. the shape of the frame is hard-coded in get_basic_shape() too. # Also, make sure this is consistent with FRAME_FIXED_SIZE. - adr_stackadjust = self._patchable_stackadjust() + return self._patchable_stackadjust() + + def _assemble_bootstrap_direct_call(self, arglocs, jmpadr, stackdepth): + # XXX pushing ebx esi and edi is a bit pointless, since we store + # all regsiters anyway, for the case of guard_not_forced + # XXX this can be improved greatly. Right now it'll behave like + # a normal call + nonfloatlocs, floatlocs = arglocs + # XXX not to repeat the logic, a bit around + adr_stackadjust = self._call_header() + self._patch_stackadjust(adr_stackadjust, stackdepth) + for i in range(len(nonfloatlocs)): + loc = nonfloatlocs[i] + if isinstance(loc, REG): + self.mc.MOV(loc, mem(ebp, (2 + i) * WORD)) + loc = floatlocs[i] + if isinstance(loc, XMMREG): + self.mc.MOVSD(loc, mem64(ebp, (1 + i) * 2 * WORD)) + tmp = eax + xmmtmp = xmm0 + for i in range(len(nonfloatlocs)): + loc = nonfloatlocs[i] + if loc is not None and not isinstance(loc, REG): + self.mc.MOV(tmp, mem(ebp, (2 + i) * WORD)) + self.mc.MOV(loc, tmp) + loc = floatlocs[i] + if loc is not None and not isinstance(loc, XMMREG): + self.mc.MOVSD(xmmtmp, mem64(ebp, (1 + i) * 2 * WORD)) + self.mc.MOVSD(loc, xmmtmp) + self.mc.JMP(rel32(jmpadr)) + return adr_stackadjust + + def _assemble_bootstrap_code(self, inputargs, arglocs): + nonfloatlocs, floatlocs = arglocs + adr_stackadjust = self._call_header() tmp = X86RegisterManager.all_regs[0] xmmtmp = X86XMMRegisterManager.all_regs[0] for i in range(len(nonfloatlocs)): @@ -421,30 +477,34 @@ return self.implement_guard(addr, getattr(self.mc, name)) return genop_cmp_guard_float - def _emit_call(self, x, arglocs, start=0, tmp=eax): + @specialize.arg(5) + def _emit_call(self, x, arglocs, start=0, tmp=eax, force_mc=False, + mc=None): + if not force_mc: + mc = self.mc p = 0 n = len(arglocs) for i in range(start, n): loc = arglocs[i] if isinstance(loc, REG): if isinstance(loc, XMMREG): - self.mc.MOVSD(mem64(esp, p), loc) + mc.MOVSD(mem64(esp, p), loc) else: - self.mc.MOV(mem(esp, p), loc) + mc.MOV(mem(esp, p), loc) p += round_up_to_4(loc.width) p = 0 for i in range(start, n): loc = arglocs[i] if not isinstance(loc, REG): if isinstance(loc, MODRM64): - self.mc.MOVSD(xmm0, loc) - self.mc.MOVSD(mem64(esp, p), xmm0) + mc.MOVSD(xmm0, loc) + mc.MOVSD(mem64(esp, p), xmm0) else: - self.mc.MOV(tmp, loc) - self.mc.MOV(mem(esp, p), tmp) + mc.MOV(tmp, loc) + mc.MOV(mem(esp, p), tmp) p += round_up_to_4(loc.width) self._regalloc.reserve_param(p//WORD) - self.mc.CALL(x) + mc.CALL(x) self.mark_gc_roots() def call(self, addr, args, res): @@ -1193,7 +1253,7 @@ tmp = ecx else: tmp = eax - + self._emit_call(x, arglocs, 2, tmp=tmp) if isinstance(resloc, MODRM64): @@ -1214,6 +1274,38 @@ self.mc.CMP(mem(ebp, FORCE_INDEX_OFS), imm(0)) return self.implement_guard(addr, self.mc.JL) + def genop_guard_call_assembler(self, op, guard_op, addr, + arglocs, result_loc): + faildescr = guard_op.descr + fail_index = self.cpu.get_fail_descr_number(faildescr) + self.mc.MOV(mem(ebp, FORCE_INDEX_OFS), imm(fail_index)) + descr = op.descr + assert isinstance(descr, LoopToken) + assert len(arglocs) - 2 == len(descr._x86_arglocs[0]) + self._emit_call(rel32(descr._x86_direct_bootstrap_code), arglocs, 2, + tmp=eax) + mc = self.mc._mc + mc.CMP(eax, imm(self.cpu.done_with_this_frame_int_v)) + mc.write(constlistofchars('\x74\x00')) # JE below + je_location = mc.get_relative_pos() + self._emit_call(rel32(self.assembler_helper_adr), [eax, arglocs[1]], 0, + tmp=ecx, force_mc=True, mc=mc) + mc.write(constlistofchars('\xEB\x00')) # JMP below + jmp_location = mc.get_relative_pos() + offset = jmp_location - je_location + assert 0 < offset <= 127 + mc.overwrite(je_location - 1, [chr(offset)]) + mc.MOV(eax, heap(self.fail_boxes_int.get_addr_for_num(0))) + offset = mc.get_relative_pos() - jmp_location + assert 0 < offset <= 127 + mc.overwrite(jmp_location - 1, [chr(offset)]) + if isinstance(result_loc, MODRM64): + self.mc.FSTP(result_loc) + else: + assert result_loc is eax or result_loc is None + self.mc.CMP(mem(ebp, FORCE_INDEX_OFS), imm(0)) + return self.implement_guard(addr, self.mc.JL) + def genop_discard_cond_call_gc_wb(self, op, arglocs): # use 'mc._mc' directly instead of 'mc', to avoid # bad surprizes if the code buffer is mostly full @@ -1258,7 +1350,7 @@ def not_implemented_op_guard(self, op, guard_op, failaddr, arglocs, resloc): - msg = "not implemented operation (guard): %s" % guard_op.getopname() + msg = "not implemented operation (guard): %s" % op.getopname() print msg raise NotImplementedError(msg) Modified: pypy/trunk/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/trunk/pypy/jit/backend/x86/regalloc.py Mon Jan 25 14:47:13 2010 @@ -318,7 +318,7 @@ self.assembler.regalloc_perform_discard(op, arglocs) def can_merge_with_next_guard(self, op, i, operations): - if op.opnum == rop.CALL_MAY_FORCE: + if op.opnum == rop.CALL_MAY_FORCE or op.opnum == rop.CALL_ASSEMBLER: assert operations[i + 1].opnum == rop.GUARD_NOT_FORCED return True if not op.is_comparison(): @@ -639,6 +639,20 @@ assert guard_op is not None self._consider_call(op, guard_op) + def consider_call_assembler(self, op, guard_op): + descr = op.descr + portal_calldescr = self.assembler.cpu.portal_calldescr + size = portal_calldescr.get_result_size(self.translate_support_code) + vable_index = self.assembler.cpu.index_of_virtualizable + if vable_index != -1: + self.rm._sync_var(op.args[vable_index]) + vable = self.fm.loc(op.args[vable_index], 1) + else: + vable = imm(0) + self._call(op, [imm(size), vable] + + [self.loc(arg) for arg in op.args], + guard_not_forced_op=guard_op) + def consider_cond_call_gc_wb(self, op): assert op.result is None arglocs = [self.loc(arg) for arg in op.args] @@ -977,7 +991,7 @@ name = name[len('consider_'):] num = getattr(rop, name.upper()) if (ResOperation(num, [], None).is_comparison() - or num == rop.CALL_MAY_FORCE): + or num == rop.CALL_MAY_FORCE or num == rop.CALL_ASSEMBLER): oplist_with_guard[num] = value oplist[num] = add_none_argument(value) else: Modified: pypy/trunk/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/runner.py (original) +++ pypy/trunk/pypy/jit/backend/x86/runner.py Mon Jan 25 14:47:13 2010 @@ -18,8 +18,8 @@ def __init__(self, rtyper, stats, opts=None, translate_support_code=False, gcdescr=None): - AbstractLLCPU.__init__(self, rtyper, stats, opts, translate_support_code, - gcdescr) + AbstractLLCPU.__init__(self, rtyper, stats, opts, + translate_support_code, gcdescr) def setup(self): if self.opts is not None: Modified: pypy/trunk/pypy/jit/backend/x86/test/test_recursive.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_recursive.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_recursive.py Mon Jan 25 14:47:13 2010 @@ -3,4 +3,6 @@ from pypy.jit.backend.x86.test.test_basic import Jit386Mixin class TestRecursive(Jit386Mixin, RecursiveTests): + # for the individual tests see + # ====> ../../../metainterp/test/test_recursive.py pass Modified: pypy/trunk/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_runner.py Mon Jan 25 14:47:13 2010 @@ -25,8 +25,8 @@ # for the individual tests see # ====> ../../test/runner_test.py - def setup_class(cls): - cls.cpu = CPU(rtyper=None, stats=FakeStats()) + def setup_method(self, meth): + self.cpu = CPU(rtyper=None, stats=FakeStats()) def test_execute_ptr_operation(self): cpu = self.cpu @@ -72,45 +72,41 @@ func = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)(f) addr = ctypes.cast(func, ctypes.c_void_p).value - try: - saved_addr = self.cpu.assembler.malloc_func_addr - self.cpu.assembler.malloc_func_addr = addr - ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] - - res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') - assert allocs[0] == 7 + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 7 - - # ------------------------------------------------------------ - - res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref') - assert allocs[0] == 7 + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 7 - - # ------------------------------------------------------------ - - TP = lltype.GcArray(lltype.Signed) - ofs = symbolic.get_field_token(TP, 'length', False)[0] - descr = self.cpu.arraydescrof(TP) - - res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], - 'ref', descr) - assert allocs[0] == 10*WORD + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 10 - - # ------------------------------------------------------------ - - res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], - 'ref', descr) - assert allocs[0] == 10*WORD + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 10 - - finally: - self.cpu.assembler.malloc_func_addr = saved_addr + self.cpu.assembler.make_sure_mc_exists() + self.cpu.assembler.malloc_func_addr = addr + ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] + + res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') + assert allocs[0] == 7 + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 7 + + # ------------------------------------------------------------ + + res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref') + assert allocs[0] == 7 + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 7 + + # ------------------------------------------------------------ + + TP = lltype.GcArray(lltype.Signed) + ofs = symbolic.get_field_token(TP, 'length', False)[0] + descr = self.cpu.arraydescrof(TP) + + res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], + 'ref', descr) + assert allocs[0] == 10*WORD + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 10 + + # ------------------------------------------------------------ + + res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], + 'ref', descr) + assert allocs[0] == 10*WORD + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 10 def test_stringitems(self): from pypy.rpython.lltypesystem.rstr import STR @@ -317,9 +313,9 @@ class TestX86OverflowMC(TestX86): - def setup_class(cls): - cls.cpu = CPU(rtyper=None, stats=FakeStats()) - cls.cpu.assembler.mc_size = 1024 + def setup_method(self, meth): + self.cpu = CPU(rtyper=None, stats=FakeStats()) + self.cpu.assembler.mc_size = 1024 def test_overflow_mc(self): ops = [] @@ -332,6 +328,7 @@ ops.append(ResOperation(rop.FINISH, [v], None, descr=BasicFailDescr())) looptoken = LoopToken() + self.cpu.assembler.make_sure_mc_exists() old_mc_mc = self.cpu.assembler.mc._mc self.cpu.compile_loop([base_v], ops, looptoken) assert self.cpu.assembler.mc._mc != old_mc_mc # overflowed Modified: pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py Mon Jan 25 14:47:13 2010 @@ -4,6 +4,7 @@ from pypy.jit.metainterp.jitprof import Profiler from pypy.jit.backend.x86.runner import CPU386 from pypy.jit.backend.test.support import CCompiledMixin +from pypy.jit.metainterp.policy import StopAtXPolicy class TestTranslationX86(CCompiledMixin): CPUClass = CPU386 @@ -94,3 +95,52 @@ return total * 10 res = self.meta_interp(main, [40]) assert res == main(40) + + def test_direct_assembler_call_translates(self): + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + class SomewhereElse(object): + pass + + somewhere_else = SomewhereElse() + + def change(newthing): + somewhere_else.frame.thing = newthing + + def main(codeno): + frame = Frame() + somewhere_else.frame = frame + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + elif frame.thing.val > 40: + change(Thing(13)) + nextval = 13 + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True, + policy=StopAtXPolicy(change)) + assert res == main(0) + Modified: pypy/trunk/pypy/jit/metainterp/history.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/history.py (original) +++ pypy/trunk/pypy/jit/metainterp/history.py Mon Jan 25 14:47:13 2010 @@ -805,15 +805,30 @@ class History(object): - def __init__(self, cpu): - self.cpu = cpu + def __init__(self): self.inputargs = None self.operations = [] + def record(self, opnum, argboxes, resbox, descr=None): op = ResOperation(opnum, argboxes, resbox, descr) self.operations.append(op) return op + def substitute_operation(self, position, opnum, argboxes, descr=None): + resbox = self.operations[position].result + op = ResOperation(opnum, argboxes, resbox, descr) + self.operations[position] = op + + def slice_history_at(self, position): + """ a strange function that does this: + history : operation_at_position : rest + it'll kill operation_at_position, store everything before that + in history.operations and return rest + """ + rest = self.operations[position + 1:] + del self.operations[position:] + return rest + # ____________________________________________________________ Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Mon Jan 25 14:47:13 2010 @@ -1009,8 +1009,12 @@ opnum == rop.DEBUG_MERGE_POINT): return if (opnum == rop.CALL or - opnum == rop.CALL_MAY_FORCE): - effectinfo = op.descr.get_extra_info() + opnum == rop.CALL_MAY_FORCE or + opnum == rop.CALL_ASSEMBLER): + if opnum == rop.CALL_ASSEMBLER: + effectinfo = None + else: + effectinfo = op.descr.get_extra_info() if effectinfo is not None: # XXX we can get the wrong complexity here, if the lists # XXX stored on effectinfo are large Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Mon Jan 25 14:47:13 2010 @@ -42,16 +42,10 @@ argtypes = unrolling_iterable(self.argtypes) def wrapped(self, orgpc): args = (self, ) - #if DEBUG >= DEBUG_DETAILED: - # s = '%s:%d\t%s' % (self.jitcode.name, orgpc, name) - #else: - s = '' for argspec in argtypes: if argspec == "box": box = self.load_arg() args += (box, ) - #if DEBUG >= DEBUG_DETAILED: - # s += '\t' + box.repr_rpython() elif argspec == "constbox": args += (self.load_const_arg(), ) elif argspec == "int": @@ -82,12 +76,7 @@ args += (methdescr, ) else: assert 0, "unknown argtype declaration: %r" % (argspec,) - #if DEBUG >= DEBUG_DETAILED: - # debug_print(s) val = func(*args) - #if DEBUG >= DEBUG_DETAILED: - # reprboxes = ' '.join([box.repr_rpython() for box in self.env]) - # debug_print(' \x1b[34menv=[%s]\x1b[0m' % (reprboxes,)) if val is None: val = False return val @@ -671,16 +660,40 @@ return False return self.perform_call(leave_code, varargs) - @arguments("descr", "varargs") - def opimpl_recursive_call(self, calldescr, varargs): + @arguments("orgpc", "descr", "varargs") + def opimpl_recursive_call(self, pc, calldescr, varargs): warmrunnerstate = self.metainterp.staticdata.state - if warmrunnerstate.inlining: + token = None + if not self.metainterp.is_blackholing() and warmrunnerstate.inlining: num_green_args = self.metainterp.staticdata.num_green_args portal_code = self.metainterp.staticdata.portal_code greenkey = varargs[1:num_green_args + 1] if warmrunnerstate.can_inline_callable(greenkey): return self.perform_call(portal_code, varargs[1:], greenkey) - return self.do_residual_call(varargs, descr=calldescr, exc=True) + token = warmrunnerstate.get_assembler_token(greenkey) + call_position = 0 + if token is not None: + call_position = len(self.metainterp.history.operations) + # guard value for all green args, needed to make sure + # that assembler that we call is still correct + greenargs = varargs[1:num_green_args + 1] + self.generate_guard_value_for_green_args(pc, greenargs) + res = self.do_residual_call(varargs, descr=calldescr, exc=True) + if not self.metainterp.is_blackholing() and token is not None: + # XXX fix the call position, + found = False + while True: + op = self.metainterp.history.operations[call_position] + if op.opnum == rop.CALL or op.opnum == rop.CALL_MAY_FORCE: + found = True + break + call_position += 1 + assert found + # + # this will substitute the residual call with assembler call + self.metainterp.direct_assembler_call(pc, varargs, token, + call_position) + return res @arguments("descr", "varargs") def opimpl_residual_call_noexception(self, calldescr, varargs): @@ -790,7 +803,7 @@ def opimpl_keepalive(self, box): pass # xxx? - def generate_merge_point(self, pc, varargs): + def generate_guard_value_for_green_args(self, pc, varargs): num_green_args = self.metainterp.staticdata.num_green_args for i in range(num_green_args): varargs[i] = self.implement_guard_value(pc, varargs[i]) @@ -830,7 +843,7 @@ @arguments("orgpc") def opimpl_jit_merge_point(self, pc): if not self.metainterp.is_blackholing(): - self.generate_merge_point(pc, self.env) + self.generate_guard_value_for_green_args(pc, self.env) # xxx we may disable the following line in some context later self.debug_merge_point() if self.metainterp.seen_can_enter_jit: @@ -862,9 +875,13 @@ def opimpl_teardown_exception_block(self): self.exception_target = -1 - @arguments("constbox", "jumptarget") - def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target): - assert isinstance(self.exception_box, Const) # XXX + @arguments("constbox", "jumptarget", "orgpc") + def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target, pc): + # XXX used to be: + # assert isinstance(self.exception_box, Const) # XXX + # seems this can happen that self.exception_box is not a Const, + # but I failed to write a test so far :-( + self.exception_box = self.implement_guard_value(pc, self.exception_box) cpu = self.metainterp.cpu ts = self.metainterp.cpu.ts if not ts.subclassOf(cpu, self.exception_box, vtableref): @@ -1100,6 +1117,9 @@ self._addr2name_values = [] self.__dict__.update(compile.make_done_loop_tokens()) + # store this information for fastpath of call_assembler + d = self.loop_tokens_done_with_this_frame_int[0].finishdescr + self.cpu.done_with_this_frame_int_v = self.cpu.get_fail_descr_number(d) def _freeze_(self): return True @@ -1359,7 +1379,7 @@ def create_empty_history(self): warmrunnerstate = self.staticdata.state - self.history = history.History(self.cpu) + self.history = history.History() self.staticdata.stats.set_history(self.history) def _all_constants(self, *boxes): @@ -1741,7 +1761,7 @@ self.in_recursion = -1 # always one portal around inputargs_and_holes = self.cpu.make_boxes_from_latest_values(resumedescr) if must_compile: - self.history = history.History(self.cpu) + self.history = history.History() self.history.inputargs = [box for box in inputargs_and_holes if box] self.staticdata.profiler.start_tracing() else: @@ -1953,6 +1973,23 @@ abox, ConstInt(j), itembox) assert i + 1 == len(self.virtualizable_boxes) + def gen_load_from_other_virtualizable(self, vbox): + vinfo = self.staticdata.virtualizable_info + boxes = [] + assert vinfo is not None + for i in range(vinfo.num_static_extra_boxes): + descr = vinfo.static_field_descrs[i] + boxes.append(self.execute_and_record(rop.GETFIELD_GC, descr, vbox)) + virtualizable = vinfo.unwrap_virtualizable_box(vbox) + for k in range(vinfo.num_arrays): + descr = vinfo.array_field_descrs[k] + abox = self.execute_and_record(rop.GETFIELD_GC, descr, vbox) + descr = vinfo.array_descrs[k] + for j in range(vinfo.get_array_length(virtualizable, k)): + boxes.append(self.execute_and_record(rop.GETARRAYITEM_GC, descr, + abox, ConstInt(j))) + return boxes + def replace_box(self, oldbox, newbox): for frame in self.framestack: boxes = frame.env @@ -1993,6 +2030,20 @@ max_key = key return max_key + def direct_assembler_call(self, pc, varargs, token, call_position): + """ Generate a direct call to assembler for portal entry point. + """ + assert not self.is_blackholing() # XXX + num_green_args = self.staticdata.num_green_args + args = varargs[num_green_args + 1:] + resbox = self.history.operations[call_position].result + rest = self.history.slice_history_at(call_position) + if self.staticdata.virtualizable_info is not None: + vindex = self.staticdata.virtualizable_info.index_of_virtualizable + vbox = args[vindex - num_green_args] + args += self.gen_load_from_other_virtualizable(vbox) + self.history.record(rop.CALL_ASSEMBLER, args[:], resbox, descr=token) + self.history.operations += rest class GenerateMergePoint(Exception): def __init__(self, args, target_loop_token): Modified: pypy/trunk/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/resoperation.py (original) +++ pypy/trunk/pypy/jit/metainterp/resoperation.py Mon Jan 25 14:47:13 2010 @@ -229,6 +229,7 @@ '_CANRAISE_FIRST', # ----- start of can_raise operations ----- 'CALL', + 'CALL_ASSEMBLER', 'CALL_MAY_FORCE', 'CALL_LOOPINVARIANT', 'OOSEND', # ootype operation Modified: pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py Mon Jan 25 14:47:13 2010 @@ -79,7 +79,27 @@ supports_floats=True) funcs = set([graph.func for graph in res]) assert funcs == set([f, h]) - + +def test_unroll_safe_and_inline(): + @jit.unroll_safe + def h(x): + i = 0 + while i < x: + i += 1 + return i + h._always_inline_ = True + + def g(x): + return h(x) + + rtyper = support.annotate(g, [7]) + cw = CodeWriter(rtyper) + jitpolicy = JitPolicy() + translator = rtyper.annotator.translator + res = cw.find_all_graphs(translator.graphs[0], None, jitpolicy, + supports_floats=True) + funcs = set([graph.func for graph in res]) + assert funcs == set([g, h]) def test_find_all_graphs_str_join(): def i(x, y): Modified: pypy/trunk/pypy/jit/metainterp/test/test_compile.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_compile.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_compile.py Mon Jan 25 14:47:13 2010 @@ -77,7 +77,7 @@ metainterp = FakeMetaInterp() metainterp.staticdata = staticdata metainterp.cpu = cpu - metainterp.history = History(metainterp.cpu) + metainterp.history = History() metainterp.history.operations = loop.operations[:] metainterp.history.inputargs = loop.inputargs[:] # @@ -94,7 +94,7 @@ metainterp = FakeMetaInterp() metainterp.staticdata = staticdata metainterp.cpu = cpu - metainterp.history = History(metainterp.cpu) + metainterp.history = History() metainterp.history.operations = loop.operations[:] metainterp.history.inputargs = loop.inputargs[:] # Modified: pypy/trunk/pypy/jit/metainterp/test/test_history.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_history.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_history.py Mon Jan 25 14:47:13 2010 @@ -9,3 +9,10 @@ s = lltype.cast_pointer(lltype.Ptr(S), t) const = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s)) assert const._getrepr_() == "*T" + +def test_slicing(): + h = History() + h.operations = [1, 2, 3, 4, 5] + rest = h.slice_history_at(2) + assert rest == [4, 5] + assert h.operations == [1, 2] Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Jan 25 14:47:13 2010 @@ -114,6 +114,9 @@ mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([nextdescr], [], [], forces_virtual_or_virtualizable=True)) + class LoopToken(AbstractDescr): + pass + asmdescr = LoopToken() # it can be whatever, it's not a descr though from pypy.jit.metainterp.virtualref import VirtualRefInfo class FakeWarmRunnerDesc: Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Mon Jan 25 14:47:13 2010 @@ -2451,6 +2451,16 @@ """ self.optimize_loop(ops, 'Not, Not, Not, Not', ops) + def test_call_assembler_invalidates_caches(self): + ops = ''' + [p1, i1] + setfield_gc(p1, i1, descr=valuedescr) + i3 = call_assembler(i1, descr=asmdescr) + setfield_gc(p1, i3, descr=valuedescr) + jump(p1, i3) + ''' + self.optimize_loop(ops, 'Not, Not', ops) + def test_vref_nonvirtual_nonescape(self): ops = """ [p1] Modified: pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py Mon Jan 25 14:47:13 2010 @@ -89,7 +89,7 @@ assert box.value == referencebox.value return True metainterp = pyjitpl.MetaInterp(FakeStaticData()) - metainterp.history = History(None) + metainterp.history = History() b1 = BoxInt(1) b2 = BoxInt(2) c3 = ConstInt(3) Modified: pypy/trunk/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_recursive.py Mon Jan 25 14:47:13 2010 @@ -1,5 +1,5 @@ import py -from pypy.rlib.jit import JitDriver, we_are_jitted, OPTIMIZER_SIMPLE +from pypy.rlib.jit import JitDriver, we_are_jitted, OPTIMIZER_SIMPLE, hint from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin from pypy.jit.metainterp.policy import StopAtXPolicy from pypy.rpython.annlowlevel import hlstr @@ -646,9 +646,303 @@ result += f('-c-----------l-', i+100) self.meta_interp(g, [10], backendopt=True) self.check_aborted_count(1) - self.check_history(call_may_force=1, call=0) + self.check_history(call_assembler=1, call=0) self.check_tree_loop_count(3) + + def test_directly_call_assembler(self): + driver = JitDriver(greens = ['codeno'], reds = ['i'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno): + i = 0 + while i < 10: + driver.can_enter_jit(codeno = codeno, i = i) + driver.jit_merge_point(codeno = codeno, i = i) + if codeno == 2: + portal(1) + i += 1 + + self.meta_interp(portal, [2], inline=True) + self.check_history(call_assembler=1) + + def test_directly_call_assembler_return(self): + driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno): + i = 0 + k = codeno + while i < 10: + driver.can_enter_jit(codeno = codeno, i = i, k = k) + driver.jit_merge_point(codeno = codeno, i = i, k = k) + if codeno == 2: + k = portal(1) + i += 1 + return k + + self.meta_interp(portal, [2], inline=True) + self.check_history(call_assembler=1) + + def test_directly_call_assembler_raise(self): + + class MyException(Exception): + def __init__(self, x): + self.x = x + + driver = JitDriver(greens = ['codeno'], reds = ['i'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno): + i = 0 + while i < 10: + driver.can_enter_jit(codeno = codeno, i = i) + driver.jit_merge_point(codeno = codeno, i = i) + if codeno == 2: + try: + portal(1) + except MyException, me: + i += me.x + i += 1 + if codeno == 1: + raise MyException(1) + + self.meta_interp(portal, [2], inline=True) + self.check_history(call_assembler=1) + + def test_directly_call_assembler_fail_guard(self): + driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno, k): + i = 0 + while i < 10: + driver.can_enter_jit(codeno=codeno, i=i, k=k) + driver.jit_merge_point(codeno=codeno, i=i, k=k) + if codeno == 2: + k += portal(1, k) + elif k > 40: + if i % 2: + k += 1 + else: + k += 2 + k += 1 + i += 1 + return k + + res = self.meta_interp(portal, [2, 0], inline=True) + assert res == 13542 + + def test_directly_call_assembler_virtualizable(self): + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def main(codeno): + frame = Frame() + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True) + assert res == main(0) + + def test_directly_call_assembler_virtualizable_force(self): + class Thing(object): + def __init__(self, val): + self.val = val + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + class SomewhereElse(object): + pass + + somewhere_else = SomewhereElse() + + def change(newthing): + somewhere_else.frame.thing = newthing + + def main(codeno): + frame = Frame() + somewhere_else.frame = frame + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + elif frame.thing.val > 40: + change(Thing(13)) + nextval = 13 + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True, + policy=StopAtXPolicy(change)) + assert res == main(0) + + def test_directly_call_assembler_virtualizable_with_array(self): + myjitdriver = JitDriver(greens = ['codeno'], reds = ['n', 'frame', 'x'], + virtualizables = ['frame'], + can_inline = lambda codeno : False) + + class Frame(object): + _virtualizable2_ = ['l[*]', 's'] + + def __init__(self, l, s): + self = hint(self, access_directly=True, + fresh_virtualizable=True) + self.l = l + self.s = s + + def main(codeno, n, a): + frame = Frame([a, a+1, a+2, a+3], 0) + return f(codeno, n, a, frame) + + def f(codeno, n, a, frame): + x = 0 + while n > 0: + myjitdriver.can_enter_jit(codeno=codeno, frame=frame, n=n, x=x) + myjitdriver.jit_merge_point(codeno=codeno, frame=frame, n=n, + x=x) + frame.s = hint(frame.s, promote=True) + n -= 1 + x += frame.l[frame.s] + frame.s += 1 + if codeno == 0: + subframe = Frame([n, n+1, n+2, n+3], 0) + x += f(1, 10, 1, subframe) + x += frame.l[frame.s] + x += len(frame.l) + frame.s -= 1 + return x + + res = self.meta_interp(main, [0, 10, 1], listops=True, inline=True) + assert res == main(0, 10, 1) + + def test_directly_call_assembler_virtualizable_force_blackhole(self): + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + class SomewhereElse(object): + pass + + somewhere_else = SomewhereElse() + + def change(newthing, arg): + print arg + if arg > 30: + somewhere_else.frame.thing = newthing + arg = 13 + return arg + + def main(codeno): + frame = Frame() + somewhere_else.frame = frame + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + else: + nextval = change(Thing(13), frame.thing.val) + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True, + policy=StopAtXPolicy(change)) + assert res == main(0) + + def test_assembler_call_red_args(self): + driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def residual(k): + if k > 40: + return 0 + return 1 + + def portal(codeno, k): + i = 0 + while i < 10: + driver.can_enter_jit(codeno=codeno, i=i, k=k) + driver.jit_merge_point(codeno=codeno, i=i, k=k) + if codeno == 2: + k += portal(residual(k), k) + if codeno == 0: + k += 2 + elif codeno == 1: + k += 1 + i += 1 + return k + + res = self.meta_interp(portal, [2, 0], inline=True, + policy=StopAtXPolicy(residual)) + assert res == portal(2, 0) + self.check_loops(call_assembler=2) + + # There is a test which I fail to write. + # * what happens if we call recursive_call while blackholing + # this seems to be completely corner case and not really happening + # in the wild class TestLLtype(RecursiveTests, LLJitMixin): pass Modified: pypy/trunk/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_virtualizable.py Mon Jan 25 14:47:13 2010 @@ -1193,6 +1193,8 @@ self.check_loops(getfield_gc=0, setfield_gc=0) def test_blackhole_should_not_reenter(self): + # Armin thinks this can occur and does not make interpreters slower + # so we don't check for assertionerror, to be discussed if not self.basic: py.test.skip("purely frontend test") @@ -1234,8 +1236,9 @@ f(10, True) return f(10, False) - einfo = py.test.raises(AssertionError, self.meta_interp, main, []) - assert einfo.value.args[0] == "reentering same frame via blackhole" + self.meta_interp(main, []) + #einfo = py.test.raises(AssertionError, self.meta_interp, main, []) + #assert einfo.value.args[0] == "reentering same frame via blackhole" def test_inlining(self): class Frame(object): Modified: pypy/trunk/pypy/jit/metainterp/test/test_warmspot.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_warmspot.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_warmspot.py Mon Jan 25 14:47:13 2010 @@ -4,6 +4,7 @@ from pypy.rlib.jit import JitDriver, OPTIMIZER_FULL, OPTIMIZER_SIMPLE from pypy.rlib.jit import unroll_safe from pypy.jit.backend.llgraph import runner +from pypy.jit.metainterp.history import BoxInt from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin @@ -283,3 +284,80 @@ class TestOOWarmspot(WarmspotTests, OOJitMixin): CPUClass = runner.OOtypeCPU type_system = 'ootype' + +class TestWarmspotDirect(object): + def setup_class(cls): + from pypy.jit.metainterp.typesystem import llhelper + from pypy.jit.metainterp.support import annotate + from pypy.jit.metainterp.warmspot import WarmRunnerDesc + from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE + from pypy.rpython.lltypesystem import lltype, llmemory + exc_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) + cls.exc_vtable = exc_vtable + + class FakeFailDescr(object): + def __init__(self, no): + self.no = no + + def handle_fail(self, metainterp_sd): + if self.no == 0: + raise metainterp_sd.warmrunnerdesc.DoneWithThisFrameInt(3) + if self.no == 1: + raise metainterp_sd.warmrunnerdesc.ContinueRunningNormally( + [BoxInt(0), BoxInt(1)]) + if self.no == 3: + exc = lltype.malloc(OBJECT) + exc.typeptr = exc_vtable + raise metainterp_sd.warmrunnerdesc.ExitFrameWithExceptionRef( + metainterp_sd.cpu, + lltype.cast_opaque_ptr(llmemory.GCREF, exc)) + return self.no + + class FakeCPU(object): + supports_floats = False + ts = llhelper + translate_support_code = False + + def __init__(self, *args, **kwds): + pass + + def nodescr(self, *args, **kwds): + pass + fielddescrof = nodescr + calldescrof = nodescr + sizeof = nodescr + + def get_fail_descr_from_number(self, no): + return FakeFailDescr(no) + + def execute_token(self, token): + assert token == 2 + return FakeFailDescr(1) + + driver = JitDriver(reds = ['red'], greens = ['green']) + + def f(green): + red = 0 + while red < 10: + driver.can_enter_jit(red=red, green=green) + driver.jit_merge_point(red=red, green=green) + red += 1 + return red + + rtyper = annotate(f, [0]) + translator = rtyper.annotator.translator + translator.config.translation.gc = 'hybrid' + cls.desc = WarmRunnerDesc(translator, CPUClass=FakeCPU) + + def test_call_helper(self): + from pypy.rpython.llinterp import LLException + + assert self.desc.assembler_call_helper(0, 0) == 3 + assert self.desc.assembler_call_helper(1, 0) == 10 + assert self.desc.assembler_call_helper(2, 0) == 10 + try: + self.desc.assembler_call_helper(3, 0) + except LLException, lle: + assert lle[0] == self.exc_vtable + else: + py.test.fail("DID NOT RAISE") Modified: pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py Mon Jan 25 14:47:13 2010 @@ -215,6 +215,7 @@ can_inline_ptr = None get_printable_location_ptr = llhelper(GET_LOCATION, get_location) confirm_enter_jit_ptr = None + get_jitcell_at_ptr = None state = WarmEnterState(FakeWarmRunnerDesc()) state.make_jitdriver_callbacks() res = state.get_location_str([BoxInt(5), BoxFloat(42.5)]) @@ -234,6 +235,8 @@ can_inline_ptr = None get_printable_location_ptr = None confirm_enter_jit_ptr = llhelper(ENTER_JIT, confirm_enter_jit) + get_jitcell_at_ptr = None + state = WarmEnterState(FakeWarmRunnerDesc()) state.make_jitdriver_callbacks() res = state.confirm_enter_jit(5, 42.5, 3) Modified: pypy/trunk/pypy/jit/metainterp/test/test_ztranslation.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_ztranslation.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_ztranslation.py Mon Jan 25 14:47:13 2010 @@ -7,6 +7,8 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype +py.test.skip("Broken") + class TranslationTest: CPUClass = None Modified: pypy/trunk/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/warmspot.py (original) +++ pypy/trunk/pypy/jit/metainterp/warmspot.py Mon Jan 25 14:47:13 2010 @@ -140,7 +140,7 @@ # ____________________________________________________________ -class WarmRunnerDesc: +class WarmRunnerDesc(object): def __init__(self, translator, policy=None, backendopt=True, CPUClass=None, optimizer=None, **kwds): @@ -441,7 +441,8 @@ self.PTR_JIT_ENTER_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, lltype.Void) (self.PORTAL_FUNCTYPE, self.PTR_PORTAL_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, RESTYPE) - + (_, self.PTR_ASSEMBLER_HELPER_FUNCTYPE) = self.cpu.ts.get_FuncType( + [lltype.Signed, llmemory.GCREF], RESTYPE) def rewrite_can_enter_jit(self): FUNC = self.JIT_ENTER_FUNCTYPE @@ -554,9 +555,63 @@ else: value = cast_base_ptr_to_instance(Exception, value) raise Exception, value - + + self.ll_portal_runner = ll_portal_runner # for debugging self.portal_runner_ptr = self.helper_func(self.PTR_PORTAL_FUNCTYPE, ll_portal_runner) + self.cpu.portal_calldescr = self.cpu.calldescrof( + self.PTR_PORTAL_FUNCTYPE.TO, + self.PTR_PORTAL_FUNCTYPE.TO.ARGS, + self.PTR_PORTAL_FUNCTYPE.TO.RESULT) + + vinfo = self.metainterp_sd.virtualizable_info + + def assembler_call_helper(failindex, virtualizableref): + fail_descr = self.cpu.get_fail_descr_from_number(failindex) + while True: + try: + if vinfo is not None: + virtualizable = lltype.cast_opaque_ptr( + vinfo.VTYPEPTR, virtualizableref) + vinfo.reset_vable_token(virtualizable) + loop_token = fail_descr.handle_fail(self.metainterp_sd) + fail_descr = self.cpu.execute_token(loop_token) + except self.ContinueRunningNormally, e: + args = () + for _, name, _ in portalfunc_ARGS: + v = getattr(e, name) + args = args + (v,) + return ll_portal_runner(*args) + except self.DoneWithThisFrameVoid: + assert result_kind == 'void' + return + except self.DoneWithThisFrameInt, e: + assert result_kind == 'int' + return lltype.cast_primitive(RESULT, e.result) + except self.DoneWithThisFrameRef, e: + assert result_kind == 'ref' + return ts.cast_from_ref(RESULT, e.result) + except self.DoneWithThisFrameFloat, e: + assert result_kind == 'float' + return e.result + except self.ExitFrameWithExceptionRef, e: + value = ts.cast_to_baseclass(e.value) + if not we_are_translated(): + raise LLException(ts.get_typeptr(value), value) + else: + value = cast_base_ptr_to_instance(Exception, value) + raise Exception, value + + self.assembler_call_helper = assembler_call_helper # for debugging + self.cpu.assembler_helper_ptr = self.helper_func( + self.PTR_ASSEMBLER_HELPER_FUNCTYPE, + assembler_call_helper) + # XXX a bit ugly sticking + if vinfo is not None: + self.cpu.index_of_virtualizable = (vinfo.index_of_virtualizable - + self.num_green_args) + else: + self.cpu.index_of_virtualizable = -1 # ____________________________________________________________ # Now mutate origportalgraph to end with a call to portal_runner_ptr Modified: pypy/trunk/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/warmstate.py (original) +++ pypy/trunk/pypy/jit/metainterp/warmstate.py Mon Jan 25 14:47:13 2010 @@ -212,8 +212,8 @@ if vinfo is not None: virtualizable = args[vinfo.index_of_virtualizable] virtualizable = vinfo.cast_to_vtype(virtualizable) - assert virtualizable != globaldata.blackhole_virtualizable, ( - "reentering same frame via blackhole") + if globaldata.blackhole_virtualizable == virtualizable: + return else: virtualizable = None @@ -258,7 +258,7 @@ if vinfo is not None: vinfo.reset_vable_token(virtualizable) loop_token = fail_descr.handle_fail(metainterp_sd) - + maybe_compile_and_run._dont_inline_ = True self.maybe_compile_and_run = maybe_compile_and_run return maybe_compile_and_run @@ -454,6 +454,7 @@ unwrap_greenkey = self.make_unwrap_greenkey() if can_inline_ptr is None: def can_inline_callable(*greenargs): + # XXX shouldn't it be False by default? return True else: rtyper = self.warmrunnerdesc.rtyper @@ -471,6 +472,16 @@ greenargs = unwrap_greenkey(greenkey) return can_inline(*greenargs) self.can_inline_callable = can_inline_greenkey + + get_jitcell = self.make_jitcell_getter() + def get_assembler_token(greenkey): + greenargs = unwrap_greenkey(greenkey) + cell = get_jitcell(*greenargs) + if cell.counter >= 0: + return None + return cell.entry_loop_token + self.get_assembler_token = get_assembler_token + # get_location_ptr = self.warmrunnerdesc.get_printable_location_ptr if get_location_ptr is None: From fijal at codespeak.net Mon Jan 25 14:47:52 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 14:47:52 +0100 (CET) Subject: [pypy-svn] r70830 - pypy/branch/direct-assembler-call Message-ID: <20100125134752.536AA1680B8@codespeak.net> Author: fijal Date: Mon Jan 25 14:47:51 2010 New Revision: 70830 Removed: pypy/branch/direct-assembler-call/ Log: remove merged branch From fijal at codespeak.net Mon Jan 25 14:51:41 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 14:51:41 +0100 (CET) Subject: [pypy-svn] r70831 - pypy/extradoc/planning Message-ID: <20100125135141.A69001680B8@codespeak.net> Author: fijal Date: Mon Jan 25 14:51:40 2010 New Revision: 70831 Modified: pypy/extradoc/planning/jit.txt Log: Review and kill done things Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Mon Jan 25 14:51:40 2010 @@ -35,7 +35,7 @@ - put the class into the structure to get only one promote when using an instance -- look into failing pypy-c-jit apptests, pypy-c-jit translate.py +- pypy-c-jit translate.py fails sometimes. Look into that - improve ''.join and u''.join by using stringbuilder, enable realloc for hybrid GC (on stringbuilder branch so far). @@ -75,7 +75,6 @@ wishlist: - improve on predictability: don't trace into signals ... but produce just a conditional call (or just abort the trace) -- directly call assembler for residual portal calls - the checks that look whether profiling/tracing in the Python interpreter is enabled look expensive. Do we want to do something about them? @@ -124,22 +123,7 @@ Goal: be somehow faster than CPython in real programs Benchmarks: - - Richards - - Pystone - - mako, gadfly, templess - - port some of the JS benchmarks? - - look at unladden-swallow benchmarks - - Sympy - - Simpy? - - Pyrolog - -later: - - translate.py - -- there should be a unified way to run these benchmark -- benchmarks should be run nightly -- we might need a benchmarking server - + they live at svn+ssh://codespeak.net/svn/pypy/benchmarks ootype discussion ------------------ @@ -154,6 +138,7 @@ - we use too much memory during jitting. Notably of the following types (in decreasing order of total size, for Pystone): + XXX is this still relevant? - rpy_string - GcArray of AbstractValue (unknown if fixedsize or not) - DoneWithThisFrameRef From fijal at codespeak.net Mon Jan 25 15:18:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 15:18:20 +0100 (CET) Subject: [pypy-svn] r70832 - in pypy/branch/stringbuilder2/pypy/rpython/memory: . test Message-ID: <20100125141820.64E1F1680FF@codespeak.net> Author: fijal Date: Mon Jan 25 15:18:19 2010 New Revision: 70832 Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Log: Improve gcwrapper, so we can test stringbuilder in test_gc, add a test Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py Mon Jan 25 15:18:19 2010 @@ -67,19 +67,31 @@ gctypelayout.zero_gc_pointers(result) return result - def resize_buffer(self, obj, old_size, new_size): + def resize_buffer(self, obj, oldlength, newlength): T = lltype.typeOf(obj).TO - buf = self.malloc_resizable_buffer(T, new_size) - # copy contents - arrayfld = T._arrayfld - new_arr = getattr(buf, arrayfld) - old_arr = getattr(obj, arrayfld) - for i in range(old_size): - new_arr[i] = old_arr[i] - return buf + ARRAY = getattr(T, T._arrayfld) + itemsofs = (llmemory.FieldOffset(T, T._arrayfld) + + llmemory.itemoffsetof(ARRAY, 0)) + fixedsize = llmemory.sizeof(T, 0) + itemsize = llmemory.sizeof(ARRAY.OF) + lengthofs = llmemory.FieldOffset(T, T._arrayfld) + \ + llmemory.ArrayLengthOffset(ARRAY) + result = self.gc.realloc(obj, oldlength, newlength, fixedsize, + itemsize, lengthofs, itemsofs, True) + return lltype.cast_opaque_ptr(lltype.typeOf(obj), result) - def finish_building_buffer(self, obj, size): - return obj + def finish_building_buffer(self, obj, newlength): + T = lltype.typeOf(obj).TO + ARRAY = getattr(T, T._arrayfld) + itemsofs = (llmemory.FieldOffset(T, T._arrayfld) + + llmemory.itemoffsetof(ARRAY, 0)) + fixedsize = llmemory.sizeof(T, 0) + itemsize = llmemory.sizeof(ARRAY.OF) + lengthofs = llmemory.FieldOffset(T, T._arrayfld) + \ + llmemory.ArrayLengthOffset(ARRAY) + result = self.gc.realloc(obj, 0, newlength, fixedsize, + itemsize, lengthofs, itemsofs, False) + return lltype.cast_opaque_ptr(lltype.typeOf(obj), result) def free(self, TYPE, flavor='gc'): assert flavor != 'gc' Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Mon Jan 25 15:18:19 2010 @@ -11,7 +11,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.objectmodel import compute_unique_id, keepalive_until_here from pypy.rlib import rgc - +from pypy.rlib.rstring import StringBuilder def stdout_ignore_ll_functions(msg): strmsg = str(msg) @@ -475,7 +475,7 @@ def f(): ptr = rgc.resizable_buffer_of_shape(STR, 1) ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 2) + ptr = rgc.resize_buffer(ptr, 1, 4) ptr.chars[1] = 'b' return len(hlstr(rgc.finish_building_buffer(ptr, 2))) @@ -571,6 +571,20 @@ self.interpret(fn, []) + def test_stringbuilder(self): + def fn(): + s = StringBuilder(4) + s.append("abcd") + s.append("defg") + s.append("rty") + s.append_multiple_char('y', 1000) + rgc.collect() + s.append_multiple_char('y', 1000) + res = s.build()[1000] + rgc.collect() + return ord(res) + res = self.interpret(fn, []) + assert res == ord('y') from pypy.rlib.objectmodel import UnboxedValue From fijal at codespeak.net Mon Jan 25 15:19:24 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 15:19:24 +0100 (CET) Subject: [pypy-svn] r70833 - pypy/branch/stringbuilder2/pypy/rpython Message-ID: <20100125141924.E35891680FF@codespeak.net> Author: fijal Date: Mon Jan 25 15:19:24 2010 New Revision: 70833 Modified: pypy/branch/stringbuilder2/pypy/rpython/llinterp.py Log: improve naming to what it really is Modified: pypy/branch/stringbuilder2/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/llinterp.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/llinterp.py Mon Jan 25 15:19:24 2010 @@ -724,17 +724,17 @@ except MemoryError: self.make_llexception() - def op_malloc_nonmovable(self, obj, flags): + def op_malloc_nonmovable(self, TYPE, flags): flavor = flags['flavor'] assert flavor == 'gc' zero = flags.get('zero', False) - return self.heap.malloc_nonmovable(obj, zero=zero) + return self.heap.malloc_nonmovable(TYPE, zero=zero) - def op_malloc_nonmovable_varsize(self, obj, flags, size): + def op_malloc_nonmovable_varsize(self, TYPE, flags, size): flavor = flags['flavor'] assert flavor == 'gc' zero = flags.get('zero', False) - return self.heap.malloc_nonmovable(obj, size, zero=zero) + return self.heap.malloc_nonmovable(TYPE, size, zero=zero) def op_malloc_resizable_buffer(self, obj, flags, size): return self.heap.malloc_resizable_buffer(obj, size) From fijal at codespeak.net Mon Jan 25 15:20:59 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 15:20:59 +0100 (CET) Subject: [pypy-svn] r70834 - pypy/branch/stringbuilder2/pypy/rpython/memory/gc Message-ID: <20100125142059.498A21680FF@codespeak.net> Author: fijal Date: Mon Jan 25 15:20:58 2010 New Revision: 70834 Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py Log: kill support for gen2_resizable_objects, we did not use it anyway and it was buggy. Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py Mon Jan 25 15:20:58 2010 @@ -31,7 +31,6 @@ # Object lists: # * gen2_rawmalloced_objects # * gen3_rawmalloced_objects -# * gen2_resizable_objects # * old_objects_pointing_to_young: gen2or3 objs that point to gen1 objs # * last_generation_root_objects: gen3 objs that point to gen1or2 objs # @@ -44,15 +43,11 @@ # Some invariants: # * gen3 are either GCFLAG_NO_HEAP_PTRS or in 'last_generation_root_objects' # * between collections, GCFLAG_UNVISITED set exactly for gen2_rawmalloced -# * objects in gen2_resizable_objects are part of the generation 2 but never -# explicitly listed in gen2_rawmalloced_objects. # # A malloc_varsize() of large objects returns objects that are external # but initially of generation 2. Old objects from the semispaces are # moved to external objects directly as generation 3. -# gen2_resizable_objects is for objects that are resizable - # The "age" of an object is the number of times it survived a full # collections, without counting the step that moved it out of the nursery. # When a semispace-based object would grow older than MAX_SEMISPACE_AGE, @@ -123,7 +118,6 @@ self.gen2_rawmalloced_objects = self.AddressStack() self.gen3_rawmalloced_objects = self.AddressStack() - self.gen2_resizable_objects = self.AddressStack() GenerationGC.setup(self) def set_max_heap_size(self, size): @@ -175,8 +169,7 @@ llmemory.GCREF) return self.malloc_varsize_slowpath(typeid, length) - def malloc_varsize_slowpath(self, typeid, length, force_nonmovable=False, - resizable=False): + def malloc_varsize_slowpath(self, typeid, length, force_nonmovable=False): # For objects that are too large, or when the nursery is exhausted. # In order to keep malloc_varsize_clear() as compact as possible, # we recompute what we need in this slow path instead of passing @@ -195,7 +188,7 @@ else: nonlarge_max = self.nonlarge_max if force_nonmovable or raw_malloc_usage(totalsize) > nonlarge_max: - result = self.malloc_varsize_marknsweep(totalsize, resizable) + result = self.malloc_varsize_marknsweep(totalsize) flags = self.GCFLAGS_FOR_NEW_EXTERNAL_OBJECTS | GCFLAG_UNVISITED else: result = self.malloc_varsize_collecting_nursery(totalsize) @@ -209,9 +202,6 @@ def malloc_varsize_nonmovable(self, typeid, length): return self.malloc_varsize_slowpath(typeid, length, True) - def malloc_varsize_resizable(self, typeid, length): - return self.malloc_varsize_slowpath(typeid, length, True, True) - def malloc_nonmovable(self, typeid, length, zero): # helper for testing, same as GCBase.malloc if self.is_varsize(typeid): @@ -220,39 +210,9 @@ raise NotImplementedError("Not supported") return llmemory.cast_ptr_to_adr(gcref) - def realloc(self, ptr, newlength, fixedsize, itemsize, lengthofs, grow): - size_gc_header = self.size_gc_header() - addr = llmemory.cast_ptr_to_adr(ptr) - ll_assert(self.header(addr).tid & GCFLAG_EXTERNAL, - "realloc() on a non-external object") - nonvarsize = size_gc_header + fixedsize - try: - varsize = ovfcheck(itemsize * newlength) - tot_size = ovfcheck(nonvarsize + varsize) - except OverflowError: - raise MemoryError() - oldlength = (addr + lengthofs).signed[0] - old_tot_size = size_gc_header + fixedsize + oldlength * itemsize - source_addr = addr - size_gc_header - self.gen2_resizable_objects.remove(addr) - if grow: - result = llop.raw_realloc_grow(llmemory.Address, source_addr, - old_tot_size, tot_size) - else: - result = llop.raw_realloc_shrink(llmemory.Address, source_addr, - old_tot_size, tot_size) - if not result: - self.gen2_resizable_objects.append(addr) - raise MemoryError() - if grow: - self.gen2_resizable_objects.append(result + size_gc_header) - else: - self.gen2_rawmalloced_objects.append(result + size_gc_header) - self._check_rawsize_alloced(raw_malloc_usage(tot_size) - - raw_malloc_usage(old_tot_size), - can_collect = not grow) - (result + size_gc_header + lengthofs).signed[0] = newlength - return llmemory.cast_adr_to_ptr(result + size_gc_header, llmemory.GCREF) + #def realloc(self, ...): + # here we can write a bit more sophisticated realloc, that cares + # about rawmalloced objects def can_move(self, addr): tid = self.header(addr).tid @@ -277,7 +237,7 @@ self.semispace_collect() debug_stop("gc-rawsize-collect") - def malloc_varsize_marknsweep(self, totalsize, resizable=False): + def malloc_varsize_marknsweep(self, totalsize): # In order to free the large objects from time to time, we # arbitrarily force a full collect() if none occurs when we have # allocated 'self.space_size' bytes of large objects. @@ -293,10 +253,7 @@ # need to follow suit. llmemory.raw_memclear(result, totalsize) size_gc_header = self.gcheaderbuilder.size_gc_header - if resizable: - self.gen2_resizable_objects.append(result + size_gc_header) - else: - self.gen2_rawmalloced_objects.append(result + size_gc_header) + self.gen2_rawmalloced_objects.append(result + size_gc_header) return result def allocate_external_object(self, totalsize): @@ -468,7 +425,6 @@ if self.is_collecting_gen3(): self.sweep_rawmalloced_objects(generation=3) self.sweep_rawmalloced_objects(generation=2) - self.sweep_rawmalloced_objects(generation=-2) # As we just collected, it's fine to raw_malloc'ate up to space_size # bytes again before we should force another collect. self.large_objects_collect_trigger = self.space_size @@ -499,10 +455,7 @@ gen3roots.delete() self.last_generation_root_objects = newgen3roots else: - # mostly a hack: the generation number -2 is the part of the - # generation 2 that lives in gen2_resizable_objects - ll_assert(generation == -2, "bogus 'generation'") - objects = self.gen2_resizable_objects + ll_assert(False, "bogus 'generation'") surviving_objects = self.AddressStack() # Help the flow space @@ -537,18 +490,11 @@ tid |= GCFLAG_UNVISITED surviving_objects.append(obj) self.header(obj).tid = tid - elif generation == -2: - # the object stays in generation -2 - tid |= GCFLAG_UNVISITED - surviving_objects.append(obj) - self.header(obj).tid = tid objects.delete() if generation == 2: self.gen2_rawmalloced_objects = surviving_objects elif generation == 3: self.gen3_rawmalloced_objects = surviving_objects - elif generation == -2: - self.gen2_resizable_objects = surviving_objects debug_print("| [hyb] gen", generation, "nonmoving now alive: ", alive_size, "bytes in", From fijal at codespeak.net Mon Jan 25 15:22:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 15:22:56 +0100 (CET) Subject: [pypy-svn] r70835 - in pypy/branch/stringbuilder2/pypy/rpython: lltypesystem memory/gc memory/gctransform Message-ID: <20100125142256.0B3291680FF@codespeak.net> Author: fijal Date: Mon Jan 25 15:22:55 2010 New Revision: 70835 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/boehm.py pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py Log: IN-PROGRESS. This is a first attempt, breaks tests etc. I want to check that in, so I can merge the trunk. Idea is to call realloc in framework gcs, which by default would simply do a new allocation and copy. In arena-based gcs we can be advanced and in case of shrinking simply change a length and be happy Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py Mon Jan 25 15:22:55 2010 @@ -26,7 +26,7 @@ new_allocated = ovfcheck(new_allocated + needed) except OverflowError: raise MemoryError - ll_builder.buf = rgc.resize_buffer(ll_builder.buf, ll_builder.used, + ll_builder.buf = rgc.resize_buffer(ll_builder.buf, ll_builder.allocated, new_allocated) ll_builder.allocated = new_allocated return func_with_new_name(stringbuilder_grow, name) Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py Mon Jan 25 15:22:55 2010 @@ -1,5 +1,6 @@ from pypy.rpython.lltypesystem import lltype, llmemory, llarena from pypy.rlib.debug import ll_assert +from pypy.rlib.objectmodel import keepalive_until_here from pypy.rpython.memory.gcheader import GCHeaderBuilder from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE from pypy.rpython.memory.support import get_address_stack, get_address_deque @@ -134,6 +135,29 @@ # lots of cast and reverse-cast around... return llmemory.cast_ptr_to_adr(ref) + def realloc(self, source, oldlength, newlength, fixedsize, itemsize, + lengthofs, itemsofs, grow): + # by default, realloc mallocs stuff and copies it over when growing. + # when shrinking, we only change length and be happy + source_adr = llmemory.cast_ptr_to_adr(source) + type_id = self.get_type_id(source_adr) + if not hasattr(self, 'malloc_varsize'): + malloc_varsize = self.malloc_varsize_clear + else: + malloc_varsize = self.malloc_varsize + typeid = self.get_type_id(source_adr) + if grow: + dest = malloc_varsize(typeid, newlength, fixedsize, itemsize, + lengthofs, True) + dest_adr = llmemory.cast_ptr_to_adr(dest) + llmemory.raw_memcopy(source_adr + itemsofs, dest_adr + itemsofs, + itemsize * oldlength) + keepalive_until_here(source) + else: + (source_adr + lengthofs).signed[0] = newlength + dest = source + return dest + def malloc_nonmovable(self, typeid, length=0, zero=False): return self.malloc(typeid, length, zero) Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/boehm.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/boehm.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/boehm.py Mon Jan 25 15:22:55 2010 @@ -77,7 +77,7 @@ return True def perform_realloc(self, hop, v_ptr, v_newlgt, c_const_size, c_item_size, - c_lengthofs, c_grow): + c_lengthofs, c_itemsofs, c_grow): args = [self.realloc_ptr, v_ptr, v_newlgt, c_const_size, c_item_size, c_lengthofs] return hop.genop('direct_call', args, resulttype=llmemory.Address) Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py Mon Jan 25 15:22:55 2010 @@ -373,7 +373,7 @@ self.realloc_ptr = getfn( GCClass.realloc.im_func, [s_gc, s_gcref] + - [annmodel.SomeInteger(nonneg=True)] * 4 + + [annmodel.SomeInteger(nonneg=True)] * 6 + [annmodel.SomeBool()], s_gcref) @@ -713,10 +713,11 @@ def _can_realloc(self): return True - def perform_realloc(self, hop, v_ptr, v_newsize, c_const_size, - c_itemsize, c_lengthofs, c_grow): - vlist = [self.realloc_ptr, self.c_const_gc, v_ptr, v_newsize, - c_const_size, c_itemsize, c_lengthofs, c_grow] + def perform_realloc(self, hop, v_ptr, v_oldsize, v_newsize, c_const_size, + c_itemsize, c_lengthofs, c_itemsofs, c_grow): + vlist = [self.realloc_ptr, self.c_const_gc, v_ptr, + v_oldsize, v_newsize, + c_const_size, c_itemsize, c_lengthofs, c_itemsofs, c_grow] livevars = self.push_roots(hop) v_result = hop.genop('direct_call', vlist, resulttype=llmemory.GCREF) Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py Mon Jan 25 15:22:55 2010 @@ -577,14 +577,14 @@ def gct_resize_buffer(self, hop): op = hop.spaceop if self._can_realloc(): - self._gct_resize_buffer_realloc(hop, op.args[2], True) + self._gct_resize_buffer_realloc(hop, op.args[1], op.args[2], True) else: self._gct_resize_buffer_no_realloc(hop, op.args[1]) def _can_realloc(self): return False - def _gct_resize_buffer_realloc(self, hop, v_newsize, grow=True): + def _gct_resize_buffer_realloc(self, hop, v_oldsize, v_newsize, grow=True): def intconst(c): return rmodel.inputconst(lltype.Signed, c) op = hop.spaceop flags = {'flavor':'gc', 'varsize': True} @@ -596,11 +596,13 @@ c_item_size = intconst(llmemory.sizeof(ARRAY.OF)) c_lengthofs = intconst(offset_to_length) + c_itemsofs = intconst(llmemory.itemoffsetof(TYPE, 0)) v_ptr = op.args[0] v_ptr = gen_cast(hop.llops, llmemory.GCREF, v_ptr) c_grow = rmodel.inputconst(lltype.Bool, grow) - v_raw = self.perform_realloc(hop, v_ptr, v_newsize, c_const_size, - c_item_size, c_lengthofs, c_grow) + v_raw = self.perform_realloc(hop, v_ptr, v_oldsize, v_newsize, + c_const_size, c_item_size, c_lengthofs, + c_itemsofs, c_grow) hop.cast_result(v_raw) def _gct_resize_buffer_no_realloc(self, hop, v_lgt): @@ -634,7 +636,8 @@ def gct_finish_building_buffer(self, hop): op = hop.spaceop if self._can_realloc(): - return self._gct_resize_buffer_realloc(hop, op.args[1], False) + return self._gct_resize_buffer_realloc(hop, op.args[1], + op.args[2], False) else: return self._gct_resize_buffer_no_realloc(hop, op.args[1]) From fijal at codespeak.net Mon Jan 25 15:25:54 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 15:25:54 +0100 (CET) Subject: [pypy-svn] r70836 - in pypy/branch/stringbuilder2: . ctypes_configure lib-python lib-python/modified-2.5.2/test pypy pypy/config pypy/doc pypy/doc/config pypy/doc/jit pypy/interpreter pypy/interpreter/test pypy/jit/backend pypy/jit/backend/llgraph pypy/jit/backend/llgraph/test pypy/jit/backend/llsupport pypy/jit/backend/llvm/test pypy/jit/backend/test pypy/jit/backend/x86 pypy/jit/backend/x86/test pypy/jit/metainterp pypy/jit/metainterp/test pypy/jit/tool pypy/jit/tool/test pypy/lib pypy/lib/_ctypes pypy/lib/app_test pypy/lib/app_test/ctypes_tests pypy/module/__builtin__ pypy/module/__builtin__/test pypy/module/__pypy__ pypy/module/_demo pypy/module/_demo/test pypy/module/_stackless pypy/module/exceptions pypy/module/imp pypy/module/imp/test pypy/module/oracle pypy/module/posix pypy/module/posix/test pypy/module/pypyjit pypy/module/pypyjit/test pypy/module/sys pypy/module/thread pypy/module/zipimport pypy/module/zipimport/test pypy/objspace pypy/objspace/flow pypy/objspace/std pypy/objspace/std/test pypy/objspace/test pypy/rlib pypy/rlib/test pypy/rpython pypy/rpython/lltypesystem pypy/rpython/lltypesystem/test pypy/rpython/memory/gctransform pypy/rpython/memory/gctransform/test pypy/rpython/module pypy/rpython/test pypy/rpython/tool pypy/tool pypy/tool/test pypy/translator pypy/translator/backendopt pypy/translator/backendopt/test pypy/translator/benchmark pypy/translator/benchmark/test pypy/translator/c pypy/translator/c/src pypy/translator/c/test pypy/translator/cli pypy/translator/goal pypy/translator/jvm pypy/translator/platform pypy/translator/platform/test pypy/translator/test Message-ID: <20100125142554.8E5DB1680FF@codespeak.net> Author: fijal Date: Mon Jan 25 15:25:48 2010 New Revision: 70836 Added: pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_runpy.py - copied unchanged from r70835, pypy/trunk/lib-python/modified-2.5.2/test/test_runpy.py pypy/branch/stringbuilder2/pypy/doc/config/objspace.usemodules.imp.txt - copied unchanged from r70835, pypy/trunk/pypy/doc/config/objspace.usemodules.imp.txt pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_virtualref.py - copied unchanged from r70835, pypy/trunk/pypy/jit/backend/x86/test/test_virtualref.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_virtualref.py - copied unchanged from r70835, pypy/trunk/pypy/jit/metainterp/test/test_virtualref.py pypy/branch/stringbuilder2/pypy/jit/metainterp/virtualref.py - copied unchanged from r70835, pypy/trunk/pypy/jit/metainterp/virtualref.py pypy/branch/stringbuilder2/pypy/module/_demo/test/ (props changed) - copied from r70835, pypy/trunk/pypy/module/_demo/test/ pypy/branch/stringbuilder2/pypy/module/imp/ (props changed) - copied from r70835, pypy/trunk/pypy/module/imp/ pypy/branch/stringbuilder2/pypy/module/pypyjit/test/test_pyframe.py - copied unchanged from r70835, pypy/trunk/pypy/module/pypyjit/test/test_pyframe.py pypy/branch/stringbuilder2/pypy/rlib/_jit_vref.py - copied unchanged from r70835, pypy/trunk/pypy/rlib/_jit_vref.py pypy/branch/stringbuilder2/pypy/rlib/test/test__jit_vref.py - copied unchanged from r70835, pypy/trunk/pypy/rlib/test/test__jit_vref.py pypy/branch/stringbuilder2/pypy/tool/package.py - copied unchanged from r70835, pypy/trunk/pypy/tool/package.py pypy/branch/stringbuilder2/pypy/tool/test/test_package.py - copied unchanged from r70835, pypy/trunk/pypy/tool/test/test_package.py pypy/branch/stringbuilder2/pypy/translator/c/src/debug_print.h - copied unchanged from r70835, pypy/trunk/pypy/translator/c/src/debug_print.h pypy/branch/stringbuilder2/pypy/translator/c/src/debug_traceback.h - copied unchanged from r70835, pypy/trunk/pypy/translator/c/src/debug_traceback.h Removed: pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test___all__.py pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_importhooks.py pypy/branch/stringbuilder2/pypy/lib/app_test/test_imp_extra.py pypy/branch/stringbuilder2/pypy/lib/imp.py pypy/branch/stringbuilder2/pypy/module/__builtin__/app_misc.py pypy/branch/stringbuilder2/pypy/module/__builtin__/importing.py pypy/branch/stringbuilder2/pypy/module/__builtin__/test/test_import.py pypy/branch/stringbuilder2/pypy/module/thread/importlock.py pypy/branch/stringbuilder2/pypy/translator/benchmark/test/ pypy/branch/stringbuilder2/pypy/translator/c/src/debug.h pypy/branch/stringbuilder2/pypy/translator/c/src/debuginfo.h pypy/branch/stringbuilder2/pypy/translator/c/src/trace.h Modified: pypy/branch/stringbuilder2/LICENSE pypy/branch/stringbuilder2/ctypes_configure/cbuild.py pypy/branch/stringbuilder2/lib-python/ (props changed) pypy/branch/stringbuilder2/lib-python/conftest.py pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/infinite_reload.py pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_import.py pypy/branch/stringbuilder2/pypy/ (props changed) pypy/branch/stringbuilder2/pypy/config/pypyoption.py pypy/branch/stringbuilder2/pypy/doc/coding-guide.txt pypy/branch/stringbuilder2/pypy/doc/config/objspace.std.withcelldict.txt pypy/branch/stringbuilder2/pypy/doc/confrest.py pypy/branch/stringbuilder2/pypy/doc/getting-started.txt pypy/branch/stringbuilder2/pypy/doc/jit/pyjitpl5.txt pypy/branch/stringbuilder2/pypy/interpreter/argument.py pypy/branch/stringbuilder2/pypy/interpreter/baseobjspace.py pypy/branch/stringbuilder2/pypy/interpreter/error.py pypy/branch/stringbuilder2/pypy/interpreter/executioncontext.py pypy/branch/stringbuilder2/pypy/interpreter/function.py pypy/branch/stringbuilder2/pypy/interpreter/gateway.py pypy/branch/stringbuilder2/pypy/interpreter/generator.py pypy/branch/stringbuilder2/pypy/interpreter/mixedmodule.py pypy/branch/stringbuilder2/pypy/interpreter/module.py pypy/branch/stringbuilder2/pypy/interpreter/pycode.py pypy/branch/stringbuilder2/pypy/interpreter/pyframe.py pypy/branch/stringbuilder2/pypy/interpreter/pyopcode.py pypy/branch/stringbuilder2/pypy/interpreter/pytraceback.py pypy/branch/stringbuilder2/pypy/interpreter/test/test_executioncontext.py pypy/branch/stringbuilder2/pypy/interpreter/test/test_gateway.py pypy/branch/stringbuilder2/pypy/interpreter/test/test_module.py pypy/branch/stringbuilder2/pypy/interpreter/test/test_zzpickle_and_slow.py pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/llimpl.py pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/runner.py pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/branch/stringbuilder2/pypy/jit/backend/llsupport/gc.py pypy/branch/stringbuilder2/pypy/jit/backend/llvm/test/conftest.py (props changed) pypy/branch/stringbuilder2/pypy/jit/backend/model.py pypy/branch/stringbuilder2/pypy/jit/backend/test/runner_test.py pypy/branch/stringbuilder2/pypy/jit/backend/test/support.py pypy/branch/stringbuilder2/pypy/jit/backend/test/test_random.py pypy/branch/stringbuilder2/pypy/jit/backend/x86/assembler.py pypy/branch/stringbuilder2/pypy/jit/backend/x86/regalloc.py pypy/branch/stringbuilder2/pypy/jit/backend/x86/runner.py pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_gc_integration.py (contents, props changed) pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_recursive.py pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_regalloc.py pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_runner.py pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_tlc.py pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_ztranslation.py pypy/branch/stringbuilder2/pypy/jit/metainterp/codewriter.py pypy/branch/stringbuilder2/pypy/jit/metainterp/compile.py pypy/branch/stringbuilder2/pypy/jit/metainterp/effectinfo.py pypy/branch/stringbuilder2/pypy/jit/metainterp/executor.py pypy/branch/stringbuilder2/pypy/jit/metainterp/history.py pypy/branch/stringbuilder2/pypy/jit/metainterp/jitprof.py pypy/branch/stringbuilder2/pypy/jit/metainterp/logger.py (props changed) pypy/branch/stringbuilder2/pypy/jit/metainterp/optimizeopt.py pypy/branch/stringbuilder2/pypy/jit/metainterp/optimizeutil.py pypy/branch/stringbuilder2/pypy/jit/metainterp/policy.py pypy/branch/stringbuilder2/pypy/jit/metainterp/pyjitpl.py pypy/branch/stringbuilder2/pypy/jit/metainterp/resoperation.py pypy/branch/stringbuilder2/pypy/jit/metainterp/resume.py pypy/branch/stringbuilder2/pypy/jit/metainterp/support.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_basic.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_codewriter.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_compile.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_effectinfo.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_executor.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_history.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_jitprof.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_optimizefindnode.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_optimizeopt.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_pyjitpl.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_recursive.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_resume.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_virtualizable.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmspot.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmstate.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_ztranslation.py pypy/branch/stringbuilder2/pypy/jit/metainterp/virtualizable.py pypy/branch/stringbuilder2/pypy/jit/metainterp/warmspot.py pypy/branch/stringbuilder2/pypy/jit/metainterp/warmstate.py pypy/branch/stringbuilder2/pypy/jit/tool/jitoutput.py pypy/branch/stringbuilder2/pypy/jit/tool/showstats.py pypy/branch/stringbuilder2/pypy/jit/tool/test/test_jitoutput.py pypy/branch/stringbuilder2/pypy/lib/_ctypes/array.py pypy/branch/stringbuilder2/pypy/lib/_ctypes/primitive.py pypy/branch/stringbuilder2/pypy/lib/_ctypes/structure.py pypy/branch/stringbuilder2/pypy/lib/_ctypes/union.py pypy/branch/stringbuilder2/pypy/lib/app_test/ctypes_tests/test_keepalive.py pypy/branch/stringbuilder2/pypy/lib/app_test/test_runpy.py pypy/branch/stringbuilder2/pypy/module/__builtin__/__init__.py pypy/branch/stringbuilder2/pypy/module/__builtin__/descriptor.py pypy/branch/stringbuilder2/pypy/module/__builtin__/test/test_descriptor.py pypy/branch/stringbuilder2/pypy/module/__pypy__/__init__.py pypy/branch/stringbuilder2/pypy/module/_demo/__init__.py pypy/branch/stringbuilder2/pypy/module/_stackless/interp_coroutine.py pypy/branch/stringbuilder2/pypy/module/exceptions/ (props changed) pypy/branch/stringbuilder2/pypy/module/imp/test/ (props changed) pypy/branch/stringbuilder2/pypy/module/oracle/__init__.py pypy/branch/stringbuilder2/pypy/module/oracle/interp_error.py pypy/branch/stringbuilder2/pypy/module/posix/__init__.py pypy/branch/stringbuilder2/pypy/module/posix/interp_posix.py pypy/branch/stringbuilder2/pypy/module/posix/test/test_posix2.py pypy/branch/stringbuilder2/pypy/module/pypyjit/interp_jit.py pypy/branch/stringbuilder2/pypy/module/pypyjit/test/test_pypy_c.py pypy/branch/stringbuilder2/pypy/module/sys/vm.py pypy/branch/stringbuilder2/pypy/module/thread/__init__.py pypy/branch/stringbuilder2/pypy/module/zipimport/__init__.py pypy/branch/stringbuilder2/pypy/module/zipimport/interp_zipimport.py pypy/branch/stringbuilder2/pypy/module/zipimport/test/test_zipimport.py pypy/branch/stringbuilder2/pypy/objspace/descroperation.py pypy/branch/stringbuilder2/pypy/objspace/flow/flowcontext.py pypy/branch/stringbuilder2/pypy/objspace/std/celldict.py pypy/branch/stringbuilder2/pypy/objspace/std/objspace.py pypy/branch/stringbuilder2/pypy/objspace/std/rangeobject.py pypy/branch/stringbuilder2/pypy/objspace/std/test/test_celldict.py pypy/branch/stringbuilder2/pypy/objspace/std/test/test_setobject.py (props changed) pypy/branch/stringbuilder2/pypy/objspace/std/test/test_userobject.py pypy/branch/stringbuilder2/pypy/objspace/test/test_descriptor.py pypy/branch/stringbuilder2/pypy/objspace/test/test_descroperation.py pypy/branch/stringbuilder2/pypy/rlib/debug.py pypy/branch/stringbuilder2/pypy/rlib/jit.py pypy/branch/stringbuilder2/pypy/rlib/rgc.py pypy/branch/stringbuilder2/pypy/rpython/llinterp.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll2ctypes.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/opimpl.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rclass.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rlist.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_ll2ctypes.py pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/test/test_framework.py pypy/branch/stringbuilder2/pypy/rpython/module/ll_os.py pypy/branch/stringbuilder2/pypy/rpython/rlist.py pypy/branch/stringbuilder2/pypy/rpython/rptr.py pypy/branch/stringbuilder2/pypy/rpython/rtyper.py pypy/branch/stringbuilder2/pypy/rpython/rvirtualizable2.py pypy/branch/stringbuilder2/pypy/rpython/test/test_rlist.py pypy/branch/stringbuilder2/pypy/rpython/test/test_rptr.py pypy/branch/stringbuilder2/pypy/rpython/test/test_rvirtualizable2.py pypy/branch/stringbuilder2/pypy/rpython/tool/rffi_platform.py pypy/branch/stringbuilder2/pypy/tool/gcc_cache.py pypy/branch/stringbuilder2/pypy/tool/udir.py pypy/branch/stringbuilder2/pypy/translator/backendopt/test/test_writeanalyze.py pypy/branch/stringbuilder2/pypy/translator/backendopt/writeanalyze.py pypy/branch/stringbuilder2/pypy/translator/benchmark/ (props changed) pypy/branch/stringbuilder2/pypy/translator/benchmark/bench-custom.py pypy/branch/stringbuilder2/pypy/translator/benchmark/benchmarks.py pypy/branch/stringbuilder2/pypy/translator/benchmark/jitbench.py pypy/branch/stringbuilder2/pypy/translator/benchmark/result.py pypy/branch/stringbuilder2/pypy/translator/c/funcgen.py pypy/branch/stringbuilder2/pypy/translator/c/gc.py pypy/branch/stringbuilder2/pypy/translator/c/genc.py pypy/branch/stringbuilder2/pypy/translator/c/src/g_include.h pypy/branch/stringbuilder2/pypy/translator/c/src/main.h pypy/branch/stringbuilder2/pypy/translator/c/test/test_boehm.py pypy/branch/stringbuilder2/pypy/translator/c/test/test_genc.py pypy/branch/stringbuilder2/pypy/translator/c/test/test_refcount.py (props changed) pypy/branch/stringbuilder2/pypy/translator/c/test/test_stackless.py pypy/branch/stringbuilder2/pypy/translator/c/test/test_standalone.py pypy/branch/stringbuilder2/pypy/translator/cli/opcodes.py pypy/branch/stringbuilder2/pypy/translator/driver.py pypy/branch/stringbuilder2/pypy/translator/exceptiontransform.py pypy/branch/stringbuilder2/pypy/translator/goal/app_main.py pypy/branch/stringbuilder2/pypy/translator/jvm/opcodes.py pypy/branch/stringbuilder2/pypy/translator/platform/__init__.py pypy/branch/stringbuilder2/pypy/translator/platform/darwin.py pypy/branch/stringbuilder2/pypy/translator/platform/linux.py pypy/branch/stringbuilder2/pypy/translator/platform/posix.py pypy/branch/stringbuilder2/pypy/translator/platform/test/test_darwin.py pypy/branch/stringbuilder2/pypy/translator/platform/test/test_platform.py pypy/branch/stringbuilder2/pypy/translator/test/test_exceptiontransform.py Log: merge from trunk: svn merge -r 70153:HEAD svn+ssh://codespeak.net/svn/pypy/trunk . Modified: pypy/branch/stringbuilder2/LICENSE ============================================================================== --- pypy/branch/stringbuilder2/LICENSE (original) +++ pypy/branch/stringbuilder2/LICENSE Mon Jan 25 15:25:48 2010 @@ -27,7 +27,7 @@ DEALINGS IN THE SOFTWARE. -PyPy Copyright holders 2003-2009 +PyPy Copyright holders 2003-2010 ----------------------------------- Except when otherwise stated (look for LICENSE files or information at @@ -86,6 +86,7 @@ Guenter Jantzen Dinu Gherman Georg Brandl + Benjamin Peterson Ben Young Nicolas Chauvat Jean-Paul Calderone Modified: pypy/branch/stringbuilder2/ctypes_configure/cbuild.py ============================================================================== --- pypy/branch/stringbuilder2/ctypes_configure/cbuild.py (original) +++ pypy/branch/stringbuilder2/ctypes_configure/cbuild.py Mon Jan 25 15:25:48 2010 @@ -5,8 +5,6 @@ debug = 0 -log = py.log.Producer("cbuild") - configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure') class ExternalCompilationInfo(object): @@ -327,7 +325,7 @@ def log_spawned_cmd(spawn): def spawn_and_log(cmd, *args, **kwds): if debug: - log.execute(' '.join(cmd)) + print ' '.join(cmd) return spawn(cmd, *args, **kwds) return spawn_and_log Modified: pypy/branch/stringbuilder2/lib-python/conftest.py ============================================================================== --- pypy/branch/stringbuilder2/lib-python/conftest.py (original) +++ pypy/branch/stringbuilder2/lib-python/conftest.py Mon Jan 25 15:25:48 2010 @@ -311,7 +311,7 @@ RegrTest('test_normalization.py'), RegrTest('test_ntpath.py'), RegrTest('test_opcodes.py', core=True), - RegrTest('test_openpty.py', skip="unsupported extension module"), + RegrTest('test_openpty.py'), RegrTest('test_operations.py', core=True), RegrTest('test_operator.py', core=True), RegrTest('test_optparse.py'), Modified: pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/infinite_reload.py ============================================================================== --- pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/infinite_reload.py (original) +++ pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/infinite_reload.py Mon Jan 25 15:25:48 2010 @@ -3,8 +3,5 @@ # reload()ing. This module is imported by test_import.py:test_infinite_reload # to make sure this doesn't happen any more. -print 1 import infinite_reload -print 2 reload(infinite_reload) -print 3 Modified: pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_import.py ============================================================================== --- pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_import.py (original) +++ pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_import.py Mon Jan 25 15:25:48 2010 @@ -1,4 +1,4 @@ -from test.test_support import TESTFN, TestFailed, check_impl_detail +from test.test_support import TESTFN, TestFailed import os import random @@ -56,6 +56,11 @@ os.unlink(source) try: + #--- the block below is to check that "reload" manages to import + #--- the .pyc file alone. We don't support it in PyPy in the default + #--- configuration. + return + try: reload(mod) except ImportError, err: @@ -238,5 +243,4 @@ finally: sys.path.pop(0) -if check_impl_detail(): - test_infinite_reload() +test_infinite_reload() Modified: pypy/branch/stringbuilder2/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/config/pypyoption.py (original) +++ pypy/branch/stringbuilder2/pypy/config/pypyoption.py Mon Jan 25 15:25:48 2010 @@ -16,7 +16,7 @@ default_modules = essential_modules.copy() default_modules.update(dict.fromkeys( - ["_codecs", "gc", "_weakref", "marshal", "errno", + ["_codecs", "gc", "_weakref", "marshal", "errno", "imp", "math", "_sre", "_pickle_support", "operator", "parser", "symbol", "token", "_ast", "_random", "__pypy__", "_testing"])) @@ -345,7 +345,7 @@ config.objspace.std.suggest(withprebuiltint=True) config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withprebuiltchar=True) - config.objspace.std.suggest(withsharingdict=True) + config.objspace.std.suggest(withinlineddict=True) config.objspace.std.suggest(withstrslice=True) config.objspace.std.suggest(withstrjoin=True) # xxx other options? ropes maybe? Modified: pypy/branch/stringbuilder2/pypy/doc/coding-guide.txt ============================================================================== --- pypy/branch/stringbuilder2/pypy/doc/coding-guide.txt (original) +++ pypy/branch/stringbuilder2/pypy/doc/coding-guide.txt Mon Jan 25 15:25:48 2010 @@ -160,7 +160,8 @@ An example can be found in the current implementation which is quite elegant: For the definition of all the opcodes of the Python interpreter, the module ``dis`` is imported and used to initialize our -bytecode interpreter. (See ``__initclass__`` in `pyopcode.py`_). This +bytecode interpreter. (See ``__initclass__`` in +`pypy/interpreter/pyopcode.py`_). This saves us from adding extra modules to PyPy. The import code is run at startup time, and we are allowed to use the CPython builtin import function. @@ -173,8 +174,6 @@ enables the code generator to emit efficient machine level replacements for pure integer objects, for instance. -.. _`pyopcode.py`: http://codespeak.net/svn/pypy/dist/pypy/interpreter/pyopcode.py - Restricted Python ================= Modified: pypy/branch/stringbuilder2/pypy/doc/config/objspace.std.withcelldict.txt ============================================================================== --- pypy/branch/stringbuilder2/pypy/doc/config/objspace.std.withcelldict.txt (original) +++ pypy/branch/stringbuilder2/pypy/doc/config/objspace.std.withcelldict.txt Mon Jan 25 15:25:48 2010 @@ -1,2 +1,2 @@ -Enable cell-dicts. This makes global lookups nearly as fast as the lookup of a -local. +Enable cell-dicts. This optimization is not helpful without the JIT. In the +presence of the JIT, it greatly helps looking up globals. Modified: pypy/branch/stringbuilder2/pypy/doc/confrest.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/doc/confrest.py (original) +++ pypy/branch/stringbuilder2/pypy/doc/confrest.py Mon Jan 25 15:25:48 2010 @@ -5,6 +5,17 @@ html = py.xml.html class PyPyPage(Page): + googlefragment = """ + + +""" def fill_menubar(self): self.menubar = html.div( html.a("home", @@ -31,6 +42,14 @@ def get_doclink(self, target): return relpath(self.targetpath.strpath, self.project.docpath.join(target).strpath) + + def unicode(self, doctype=True): + page = self._root.unicode() + page = page.replace("", self.googlefragment + "") + if doctype: + return self.doctype + page + else: + return page class Project(Project): Modified: pypy/branch/stringbuilder2/pypy/doc/getting-started.txt ============================================================================== --- pypy/branch/stringbuilder2/pypy/doc/getting-started.txt (original) +++ pypy/branch/stringbuilder2/pypy/doc/getting-started.txt Mon Jan 25 15:25:48 2010 @@ -35,22 +35,31 @@ Before you can play with PyPy, you will need to obtain a copy of the sources. This can be done either by `downloading them from the download page`_ or by checking them out from the -repository using subversion. We suggest using subversion as it -offers access to the most recent versions. +repository using subversion. We suggest using subversion if one +wants to access the current development. .. _`downloading them from the download page`: download.html If you choose to use subversion, you must issue the following command on your command line, DOS box, or terminal:: - svn co http://codespeak.net/svn/pypy/dist pypy-dist + svn co http://codespeak.net/svn/pypy/trunk pypy-trunk + +This will check out the subversion head and place it into a directory +named ``pypy-trunk``, and will get you the PyPy source in +``pypy-trunk/pypy`` and documentation files in ``pypy-trunk/pypy/doc``. +We try to ensure that the head is always stable, but it might +occasionally be broken. You may want to check out `our nightly tests:`_ +find a revision (5-digit number) that passed at least the +``{own}`` and ``{applevel}`` tests (corresponding to a ``+`` sign on the +line ``success``) and then check out using:: + + svn co -rXXXXX http://codespeak.net/svn/pypy/trunk pypy-trunk + +where XXXXX is the revision number. + +.. _`our nightly tests:`: http://codespeak.net:8099/summary?branch= -This will check out the most recent stable release from subversion and -place it into a directory named ``pypy-dist``, and will get you the PyPy -source in ``pypy-dist/pypy`` and documentation files in -``pypy-dist/pypy/doc``. If you would prefer to check out the "cutting edge" -version of PyPy - which may not always be stable! - then check out -from ``http://codespeak.net/svn/pypy/trunk`` intead. Where to go from here ---------------------- Modified: pypy/branch/stringbuilder2/pypy/doc/jit/pyjitpl5.txt ============================================================================== --- pypy/branch/stringbuilder2/pypy/doc/jit/pyjitpl5.txt (original) +++ pypy/branch/stringbuilder2/pypy/doc/jit/pyjitpl5.txt Mon Jan 25 15:25:48 2010 @@ -2,7 +2,7 @@ PyJitPl5 ========== -This document describes the fith generation of PyPy's JIT. +This document describes the fifth generation of PyPy's JIT. Implementation of the JIT Modified: pypy/branch/stringbuilder2/pypy/interpreter/argument.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/argument.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/argument.py Mon Jan 25 15:25:48 2010 @@ -4,7 +4,7 @@ from pypy.interpreter.error import OperationError from pypy.rlib.debug import make_sure_not_resized -from pypy.rlib.jit import purefunction, unroll_safe +from pypy.rlib import jit class Signature(object): @@ -17,7 +17,7 @@ self.varargname = varargname self.kwargname = kwargname - @purefunction + @jit.purefunction def find_argname(self, name): try: return self.argnames.index(name) @@ -101,6 +101,11 @@ make_sure_not_resized(self.arguments_w) if w_stararg is not None or w_starstararg is not None: self._combine_wrapped(w_stararg, w_starstararg) + # if we have a call where * or ** args are used at the callsite + # we shouldn't let the JIT see the argument matching + self._dont_jit = True + else: + self._dont_jit = False def __repr__(self): """ NOT_RPYTHON """ @@ -188,13 +193,28 @@ ### Parsing for function calls ### - @unroll_safe # XXX not true always, but for now def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=[], blindargs=0): """Parse args and kwargs according to the signature of a code object, or raise an ArgErr in case of failure. Return the number of arguments filled in. """ + if jit.we_are_jitted() and self._dont_jit: + return self._match_signature_jit_opaque(w_firstarg, scope_w, + signature, defaults_w, + blindargs) + return self._really_match_signature(w_firstarg, scope_w, signature, + defaults_w, blindargs) + + @jit.dont_look_inside + def _match_signature_jit_opaque(self, w_firstarg, scope_w, signature, + defaults_w, blindargs): + return self._really_match_signature(w_firstarg, scope_w, signature, + defaults_w, blindargs) + + @jit.unroll_safe + def _really_match_signature(self, w_firstarg, scope_w, signature, defaults_w=[], + blindargs=0): # # args_w = list of the normal actual parameters, wrapped # kwds_w = real dictionary {'keyword': wrapped parameter} Modified: pypy/branch/stringbuilder2/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/baseobjspace.py Mon Jan 25 15:25:48 2010 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer -from pypy.rlib.jit import we_are_jitted, dont_look_inside, unroll_safe +from pypy.rlib import jit import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] @@ -239,6 +239,9 @@ config = get_pypy_config(translating=False) self.config = config + self.builtin_modules = {} + self.reloading_modules = {} + # import extra modules for side-effects import pypy.interpreter.nestedscope # register *_DEREF bytecodes @@ -266,16 +269,22 @@ def startup(self): # To be called before using the space - # Initialize all builtin modules + # Initialize already imported builtin modules from pypy.interpreter.module import Module + w_modules = self.sys.get('modules') for w_modname in self.unpackiterable( self.sys.get('builtin_module_names')): + try: + w_mod = self.getitem(w_modules, w_modname) + except OperationError, e: + if e.match(self, self.w_KeyError): + continue + raise modname = self.str_w(w_modname) - mod = self.interpclass_w(self.getbuiltinmodule(modname)) + mod = self.interpclass_w(w_mod) if isinstance(mod, Module): - import time self.timer.start("startup " + modname) - mod.startup(self) + mod.init(self) self.timer.stop("startup " + modname) def finish(self): @@ -283,11 +292,9 @@ if w_exitfunc is not None: self.call_function(w_exitfunc) from pypy.interpreter.module import Module - for w_modname in self.unpackiterable( - self.sys.get('builtin_module_names')): - modname = self.str_w(w_modname) - mod = self.interpclass_w(self.getbuiltinmodule(modname)) - if isinstance(mod, Module): + for w_mod in self.builtin_modules.values(): + mod = self.interpclass_w(w_mod) + if isinstance(mod, Module) and mod.startup_called: mod.shutdown(self) if self.config.objspace.std.withdictmeasurement: from pypy.objspace.std.dictmultiobject import report @@ -339,14 +346,42 @@ w_name = self.wrap(name) w_mod = self.wrap(Module(self, w_name)) - w_modules = self.sys.get('modules') - self.setitem(w_modules, w_name, w_mod) + self.builtin_modules[name] = w_mod return name - def getbuiltinmodule(self, name): + def getbuiltinmodule(self, name, force_init=False): w_name = self.wrap(name) w_modules = self.sys.get('modules') - return self.getitem(w_modules, w_name) + try: + w_mod = self.getitem(w_modules, w_name) + except OperationError, e: + if not e.match(self, self.w_KeyError): + raise + else: + if not force_init: + return w_mod + + # If the module is a builtin but not yet imported, + # retrieve it and initialize it + try: + w_mod = self.builtin_modules[name] + except KeyError: + raise OperationError( + self.w_SystemError, + self.wrap("getbuiltinmodule() called " + "with non-builtin module %s" % name)) + else: + # Add the module to sys.modules + self.setitem(w_modules, w_name, w_mod) + + # And initialize it + from pypy.interpreter.module import Module + mod = self.interpclass_w(w_mod) + if isinstance(mod, Module): + self.timer.start("startup " + name) + mod.init(self) + self.timer.stop("startup " + name) + return w_mod def get_builtinmodule_to_install(self): """NOT_RPYTHON""" @@ -390,26 +425,27 @@ "NOT_RPYTHON: only for initializing the space." from pypy.module.exceptions import Module - w_name_exceptions = self.wrap('exceptions') - self.exceptions_module = Module(self, w_name_exceptions) + w_name = self.wrap('exceptions') + self.exceptions_module = Module(self, w_name) + self.builtin_modules['exceptions'] = self.wrap(self.exceptions_module) from pypy.module.sys import Module w_name = self.wrap('sys') self.sys = Module(self, w_name) - w_modules = self.sys.get('modules') - self.setitem(w_modules, w_name, self.wrap(self.sys)) + self.builtin_modules['sys'] = self.wrap(self.sys) - self.setitem(w_modules, w_name_exceptions, - self.wrap(self.exceptions_module)) + from pypy.module.imp import Module + w_name = self.wrap('imp') + self.builtin_modules['imp'] = self.wrap(Module(self, w_name)) from pypy.module.__builtin__ import Module w_name = self.wrap('__builtin__') self.builtin = Module(self, w_name) w_builtin = self.wrap(self.builtin) - self.setitem(w_modules, w_name, w_builtin) + self.builtin_modules['__builtin__'] = self.wrap(w_builtin) self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin) - bootstrap_modules = ['sys', '__builtin__', 'exceptions'] + bootstrap_modules = ['sys', 'imp', '__builtin__', 'exceptions'] installed_builtin_modules = bootstrap_modules[:] self.export_builtin_exceptions() @@ -480,12 +516,11 @@ def setup_builtin_modules(self): "NOT_RPYTHON: only for initializing the space." - from pypy.interpreter.module import Module - for w_modname in self.unpackiterable(self.sys.get('builtin_module_names')): - modname = self.unwrap(w_modname) - mod = self.getbuiltinmodule(modname) - if isinstance(mod, Module): - mod.setup_after_space_initialization() + self.getbuiltinmodule('sys') + self.getbuiltinmodule('imp') + self.getbuiltinmodule('__builtin__') + for mod in self.builtin_modules.values(): + mod.setup_after_space_initialization() def initialize(self): """NOT_RPYTHON: Abstract method that should put some minimal @@ -496,6 +531,7 @@ def leave_cache_building_mode(self, val): "hook for the flow object space" + @jit.loop_invariant def getexecutioncontext(self): "Return what we consider to be the active execution context." # Important: the annotator must not see a prebuilt ExecutionContext: @@ -700,7 +736,7 @@ """ return self.unpackiterable(w_iterable, expected_length) - @unroll_safe + @jit.unroll_safe def exception_match(self, w_exc_type, w_check_class): """Checks if the given exception type matches 'w_check_class'.""" if self.is_w(w_exc_type, w_check_class): @@ -756,8 +792,7 @@ def call_valuestack(self, w_func, nargs, frame): from pypy.interpreter.function import Function, Method, is_builtin_code - if (not we_are_jitted() and frame.is_being_profiled and - is_builtin_code(w_func)): + if frame.is_being_profiled and is_builtin_code(w_func): # XXX: this code is copied&pasted :-( from the slow path below # call_valuestack(). args = frame.make_arguments(nargs) @@ -784,7 +819,6 @@ args = frame.make_arguments(nargs) return self.call_args(w_func, args) - @dont_look_inside def call_args_and_c_profile(self, frame, w_func, args): ec = self.getexecutioncontext() ec.c_call_trace(frame, w_func) Modified: pypy/branch/stringbuilder2/pypy/interpreter/error.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/error.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/error.py Mon Jan 25 15:25:48 2010 @@ -203,8 +203,8 @@ w_instclass = space.exception_getclass(w_inst) if not space.exception_is_valid_class_w(w_instclass): instclassname = w_instclass.getname(space, '?') - msg = ("exceptions must be classes, or instances," - "or strings (deprecated) not %s" % (instclassname,)) + msg = ("exceptions must be classes, or instances, " + "or strings (deprecated), not %s" % (instclassname,)) raise OperationError(space.w_TypeError, space.wrap(msg)) if not space.is_w(w_value, space.w_None): Modified: pypy/branch/stringbuilder2/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/executioncontext.py Mon Jan 25 15:25:48 2010 @@ -3,7 +3,6 @@ from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import LONG_BIT from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib.jit import we_are_jitted from pypy.rlib import jit def app_profile_call(space, w_callable, frame, event, w_arg): @@ -15,181 +14,61 @@ """An ExecutionContext holds the state of an execution thread in the Python interpreter.""" + # XXX JIT: when tracing (but not when blackholing!), the following + # XXX fields should be known to a constant None or False: + # XXX self.w_tracefunc, self.profilefunc + # XXX frame.is_being_profiled + def __init__(self, space): self.space = space - self._init_frame_chain() + self.topframeref = jit.vref_None + self.framestackdepth = 0 # tracing: space.frame_trace_action.fire() must be called to ensure # that tracing occurs whenever self.w_tracefunc or self.is_tracing # is modified. - self.w_tracefunc = None + self.w_tracefunc = None # if not None, no JIT self.is_tracing = 0 self.compiler = space.createcompiler() - self.profilefunc = None + self.profilefunc = None # if not None, no JIT self.w_profilefuncarg = None + def gettopframe(self): + return self.topframeref() + def gettopframe_nohidden(self): - frame = self.gettopframe() - # I guess this should just use getnextframe_nohidden XXX + frame = self.topframeref() while frame and frame.hide(): - frame = frame.f_back() + frame = frame.f_backref() return frame @staticmethod def getnextframe_nohidden(frame): - frame = frame.f_back() + frame = frame.f_backref() while frame and frame.hide(): - frame = frame.f_back() + frame = frame.f_backref() return frame def enter(self, frame): if self.framestackdepth > self.space.sys.recursionlimit: raise OperationError(self.space.w_RuntimeError, self.space.wrap("maximum recursion depth exceeded")) - self._chain(frame) + self.framestackdepth += 1 + frame.f_backref = self.topframeref + self.topframeref = jit.virtual_ref(frame) def leave(self, frame): - if self.profilefunc: - self._trace(frame, 'leaveframe', self.space.w_None) + try: + if self.profilefunc: + self._trace(frame, 'leaveframe', self.space.w_None) + finally: + self.topframeref = frame.f_backref + self.framestackdepth -= 1 + jit.virtual_ref_finish(frame) - self._unchain(frame) - if self.w_tracefunc is not None and not frame.hide(): self.space.frame_trace_action.fire() # ________________________________________________________________ - # the methods below are used for chaining frames in JIT-friendly way - # part of that stuff is obscure - - @jit.unroll_safe - def gettopframe(self): - frame = self.some_frame - if frame is not None: - while frame.f_forward is not None: - frame = frame.f_forward - return frame - - def _init_frame_chain(self): - # 'some_frame' points to any frame from this thread's frame stack - # (although in general it should point to the top one). - # XXX not true: some_frame must point to a frame from which we can - # reach the top frame by following the chain of f_forward - self.some_frame = None - self.framestackdepth = 0 - - @staticmethod - def _init_chaining_attributes(frame): - """ - explanation of the f_back handling: - ----------------------------------- - - in the non-JIT case, the frames simply form a doubly linked list via the - attributes f_back_some and f_forward. - - When the JIT is used, things become more complex, as functions can be - inlined into each other. In this case a frame chain can look like this: - - +---------------+ - | real_frame | - +---------------+ - | - | f_back_some - | - | - | +--------------+ - | | virtual frame| - | +--------------+ - | ^ - | | f_forward - | +--------------+ - | | virtual frame| - | +--------------+ - | ^ - | | - v | f_forward - +---------------+ - | real_frame | - +---------------+ - | - | - v - ... - - This ensures that the virtual frames don't escape via the f_back of the - real frames. For the same reason, the executioncontext's some_frame - attribute should only point to real frames. - - All places where a frame can become accessed from applevel-code (like - sys._getframe and traceback catching) need to call force_f_back to ensure - that the intermediate virtual frames are forced to be real ones. - - """ - frame.f_back_some = None - frame.f_forward = None - frame.f_back_forced = False - - def _chain(self, frame): - self.framestackdepth += 1 - # - frame.f_back_some = self.some_frame - if self._we_are_jitted(): - curtopframe = self.gettopframe() - assert curtopframe is not None - curtopframe.f_forward = frame - else: - self.some_frame = frame - - def _unchain(self, frame): - #assert frame is self.gettopframe() --- slowish - if self.some_frame is frame: - self.some_frame = frame.f_back_some - else: - f_back = frame.f_back() - if f_back is not None: - f_back.f_forward = None - - self.framestackdepth -= 1 - - @staticmethod - def _jit_rechain_frame(ec, frame): - # this method is called after the jit has seen enter (and thus _chain) - # of a frame, but then does not actually inline it. This method thus - # needs to make sure that the state is as if the _chain method had been - # executed outside of the jit. Note that this makes it important that - # _unchain does not call we_are_jitted - frame.f_back().f_forward = None - ec.some_frame = frame - - @staticmethod - @jit.unroll_safe - def _extract_back_from_frame(frame): - back_some = frame.f_back_some - if frame.f_back_forced: - # don't check back_some.f_forward in this case - return back_some - if back_some is None: - return None - while True: - f_forward = back_some.f_forward - if f_forward is frame or f_forward is None: - return back_some - back_some = f_forward - - @staticmethod - def _force_back_of_frame(frame): - orig_frame = frame - while frame is not None and not frame.f_back_forced: - frame.f_back_some = f_back = ExecutionContext._extract_back_from_frame(frame) - frame.f_back_forced = True - # now that we force the whole chain, we also have to set the - # forward links to None - frame.f_forward = None - frame = f_back - return orig_frame.f_back_some - - _we_are_jitted = staticmethod(we_are_jitted) # indirection for testing - - # the methods above are used for chaining frames in JIT-friendly way - # ________________________________________________________________ class Subcontext(object): @@ -204,7 +83,7 @@ self.is_tracing = 0 def enter(self, ec): - ec.some_frame = self.topframe + ec.topframeref = jit.non_virtual_ref(self.topframe) ec.framestackdepth = self.framestackdepth ec.w_tracefunc = self.w_tracefunc ec.profilefunc = self.profilefunc @@ -247,29 +126,11 @@ while index > 0: index -= 1 lst[index] = f - f = f.f_back() + f = f.f_backref() assert f is None return lst # coroutine: I think this is all, folks! - - def get_builtin(self): - frame = self.gettopframe_nohidden() - if frame is not None: - return frame.builtin - else: - return self.space.builtin - - # XXX this one should probably be dropped in favor of a module - def make_standard_w_globals(self): - "Create a new empty 'globals' dictionary." - w_key = self.space.wrap("__builtins__") - w_value = self.space.wrap(self.get_builtin()) - w_globals = self.space.newdict() - space.setitem(w_globals, w_key, w_value) - return w_globals - - @jit.dont_look_inside def c_call_trace(self, frame, w_func): "Profile the call of a builtin function" if self.profilefunc is None: @@ -277,7 +138,6 @@ else: self._trace(frame, 'c_call', w_func) - @jit.dont_look_inside def c_return_trace(self, frame, w_retval): "Profile the return from a builtin function" if self.profilefunc is None: @@ -285,7 +145,6 @@ else: self._trace(frame, 'c_return', w_retval) - @jit.dont_look_inside def c_exception_trace(self, frame, w_exc): "Profile function called upon OperationError." if self.profilefunc is None: @@ -293,7 +152,6 @@ else: self._trace(frame, 'c_exception', w_exc) - @jit.dont_look_inside def call_trace(self, frame): "Trace the call of a function" if self.w_tracefunc is not None or self.profilefunc is not None: @@ -301,7 +159,6 @@ if self.profilefunc: frame.is_being_profiled = True - @jit.dont_look_inside def return_trace(self, frame, w_retval): "Trace the return from a function" if self.w_tracefunc is not None: @@ -320,7 +177,14 @@ actionflag.action_dispatcher(self, frame) # slow path bytecode_trace._always_inline_ = True - @jit.dont_look_inside + def bytecode_trace_after_exception(self, frame): + "Like bytecode_trace(), but without increasing the ticker." + actionflag = self.space.actionflag + ticker = actionflag.get() + if ticker & actionflag.interesting_bits: # fast check + actionflag.action_dispatcher(self, frame) # slow path + bytecode_trace_after_exception._always_inline_ = True + def exception_trace(self, frame, operationerr): "Trace function called upon OperationError." operationerr.record_interpreter_traceback() @@ -343,6 +207,7 @@ if self.space.is_w(w_func, self.space.w_None): self.w_tracefunc = None else: + self.force_all_frames() self.w_tracefunc = w_func self.space.frame_trace_action.fire() @@ -355,16 +220,28 @@ self.setllprofile(app_profile_call, w_func) def setllprofile(self, func, w_arg): - self.profilefunc = func if func is not None: if w_arg is None: raise ValueError("Cannot call setllprofile with real None") - frame = self.gettopframe_nohidden() - while frame: - frame.is_being_profiled = True - frame = self.getnextframe_nohidden(frame) + self.force_all_frames(is_being_profiled=True) + self.profilefunc = func self.w_profilefuncarg = w_arg + def force_all_frames(self, is_being_profiled=False): + # "Force" all frames in the sense of the jit, and optionally + # set the flag 'is_being_profiled' on them. A forced frame is + # one out of which the jit will exit: if it is running so far, + # in a piece of assembler currently running a CALL_MAY_FORCE, + # then being forced means that it will fail the following + # GUARD_NOT_FORCED operation, and so fall back to interpreted + # execution. (We get this effect simply by reading the f_back + # field of all frames, during the loop below.) + frame = self.gettopframe_nohidden() + while frame: + if is_being_profiled: + frame.is_being_profiled = True + frame = self.getnextframe_nohidden(frame) + def call_tracing(self, w_func, w_args): is_tracing = self.is_tracing self.is_tracing = 0 @@ -415,9 +292,8 @@ 'c_return', 'c_exception']: return - last_exception = None + last_exception = frame.last_exception if event == 'leaveframe': - last_exception = frame.last_exception event = 'return' assert self.is_tracing == 0 @@ -573,7 +449,7 @@ def fire_after_thread_switch(self): """Bit of a hack: fire() the action but only the next time the GIL - is released and re-acquired (i.e. after a portential thread switch). + is released and re-acquired (i.e. after a potential thread switch). Don't call this if threads are not enabled. """ from pypy.module.thread.gil import spacestate Modified: pypy/branch/stringbuilder2/pypy/interpreter/function.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/function.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/function.py Mon Jan 25 15:25:48 2010 @@ -553,6 +553,7 @@ class StaticMethod(Wrappable): """The staticmethod objects.""" + _immutable_ = True def __init__(self, w_function): self.w_function = w_function @@ -566,6 +567,7 @@ class ClassMethod(Wrappable): """The classmethod objects.""" + _immutable_ = True def __init__(self, w_function): self.w_function = w_function Modified: pypy/branch/stringbuilder2/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/gateway.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/gateway.py Mon Jan 25 15:25:48 2010 @@ -386,6 +386,15 @@ else: return typ.__name__ + '_w' + +def unwrap_spec(*spec): + """A decorator which attaches the unwrap_spec attribute.""" + def decorator(func): + func.unwrap_spec = spec + return func + return decorator + + class BuiltinCode(eval.Code): "The code object implementing a built-in (interpreter-level) hook." _immutable_ = True @@ -1075,6 +1084,11 @@ """ if not isinstance(source, str): source = str(py.code.Source(source).strip()) + while source.startswith('@py.test.mark.'): + # these decorators are known to return the same function + # object, we may ignore them + assert '\n' in source + source = source[source.find('\n') + 1:] assert source.startswith("def "), "can only transform functions" source = source[4:] p = source.find('(') Modified: pypy/branch/stringbuilder2/pypy/interpreter/generator.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/generator.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/generator.py Mon Jan 25 15:25:48 2010 @@ -2,6 +2,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import NoneNotWrapped from pypy.rlib.rarithmetic import intmask +from pypy.rlib import jit from pypy.interpreter.pyopcode import LoopBlock @@ -64,7 +65,7 @@ else: return w_result # YIELDed finally: - self.frame.f_back_some = None + self.frame.f_backref = jit.vref_None self.running = False def descr_throw(self, w_type, w_val=None, w_tb=None): Modified: pypy/branch/stringbuilder2/pypy/interpreter/mixedmodule.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/mixedmodule.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/mixedmodule.py Mon Jan 25 15:25:48 2010 @@ -13,7 +13,8 @@ applevel_name = None expose__file__attribute = True - + w_initialdict = None + def __init__(self, space, w_name): """ NOT_RPYTHON """ Module.__init__(self, space, w_name) @@ -21,6 +22,13 @@ self.__class__.buildloaders() self.loaders = self.loaders.copy() # copy from the class to the inst + def init(self, space): + """This is called each time the module is imported or reloaded + """ + if self.w_initialdict is not None: + space.call_method(self.w_dict, 'update', self.w_initialdict) + Module.init(self, space) + def get_applevel_name(cls): """ NOT_RPYTHON """ if cls.applevel_name is not None: @@ -82,11 +90,13 @@ for name in self.loaders: w_value = self.get(name) space.setitem(self.w_dict, space.new_interned_str(name), w_value) - self.lazy = False + self.lazy = False + self.w_initialdict = space.call_method(self.w_dict, 'items') return self.w_dict def _freeze_(self): self.getdict() + self.startup_called = False # hint for the annotator: Modules can hold state, so they are # not constant return False Modified: pypy/branch/stringbuilder2/pypy/interpreter/module.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/module.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/module.py Mon Jan 25 15:25:48 2010 @@ -15,22 +15,30 @@ self.w_dict = w_dict self.w_name = w_name if w_name is not None: - space.setitem(w_dict, space.new_interned_str('__name__'), w_name) + space.setitem(w_dict, space.new_interned_str('__name__'), w_name) + self.startup_called = False def setup_after_space_initialization(self): """NOT_RPYTHON: to allow built-in modules to do some more setup after the space is fully initialized.""" + def init(self, space): + """This is called each time the module is imported or reloaded + """ + if not self.startup_called: + self.startup_called = True + self.startup(space) + def startup(self, space): - """This is called at runtime before the space gets uses to allow - the module to do initialization at runtime. + """This is called at runtime on import to allow the module to + do initialization when it is imported for the first time. """ def shutdown(self, space): """This is called when the space is shut down, just after - sys.exitfunc(). + sys.exitfunc(), if the module has been imported. """ - + def getdict(self): return self.w_dict Modified: pypy/branch/stringbuilder2/pypy/interpreter/pycode.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/pycode.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/pycode.py Mon Jan 25 15:25:48 2010 @@ -27,7 +27,7 @@ # Magic numbers for the bytecode version in code objects. -# See comments in pypy/module/__builtin__/importing. +# See comments in pypy/module/imp/importing. cpython_magic, = struct.unpack("')) nofile = type(_pypy_interact)('nofile', 'foo') assert repr(nofile) == "" Modified: pypy/branch/stringbuilder2/pypy/interpreter/test/test_zzpickle_and_slow.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/test/test_zzpickle_and_slow.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/test/test_zzpickle_and_slow.py Mon Jan 25 15:25:48 2010 @@ -2,6 +2,7 @@ from pypy import conftest from pypy.conftest import gettestobjspace from pypy.interpreter import gateway +from pypy.rlib.jit import non_virtual_ref, vref_None class AppTestSlow: def setup_class(cls): @@ -30,21 +31,18 @@ from pypy.interpreter import pytraceback def hide_top_frame(space, w_frame): w_last = None - while w_frame.f_back(): - # should have been forced by traceback capturing - assert w_frame.f_back_forced + while w_frame.f_backref(): w_last = w_frame - w_frame = w_frame.f_back() + w_frame = w_frame.f_backref() assert w_last - w_saved = w_last.f_back() - w_last.f_back_some = None + w_saved = w_last.f_backref() + w_last.f_backref = vref_None return w_saved def restore_top_frame(space, w_frame, w_saved): - while w_frame.f_back(): - assert w_frame.f_back_forced - w_frame = w_frame.f_back() - w_frame.f_back_some = w_saved + while w_frame.f_backref(): + w_frame = w_frame.f_backref() + w_frame.f_backref = non_virtual_ref(w_saved) def read_exc_type(space, w_frame): if w_frame.last_exception is None: Modified: pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/llimpl.py Mon Jan 25 15:25:48 2010 @@ -125,6 +125,7 @@ 'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'), 'arraylen_gc' : (('ref',), 'int'), 'call' : (('ref', 'varargs'), 'intorptr'), + 'call_assembler' : (('ref', 'varargs'), 'intorptr'), 'call_pure' : (('ref', 'varargs'), 'intorptr'), 'cond_call_gc_wb' : (('int', 'int', 'ptr', 'varargs'), None), 'oosend' : (('varargs',), 'intorptr'), @@ -152,7 +153,9 @@ 'debug_merge_point': (('ref',), None), 'force_token' : ((), 'int'), 'call_may_force' : (('int', 'varargs'), 'intorptr'), - 'guard_not_forced': ((), None) + 'guard_not_forced': ((), None), + 'virtual_ref' : (('ref', 'int'), 'ref'), + 'virtual_ref_finish': (('ref', 'ref'), None), #'getitem' : (('void', 'ref', 'int'), 'int'), #'setitem' : (('void', 'ref', 'int', 'int'), None), #'newlist' : (('void', 'varargs'), 'ref'), @@ -314,6 +317,11 @@ assert isinstance(type, str) and len(type) == 1 op.descr = Descr(ofs, type) +def compile_add_loop_token(loop, descr): + loop = _from_opaque(loop) + op = loop.operations[-1] + op.descr = descr + def compile_add_var(loop, intvar): loop = _from_opaque(loop) op = loop.operations[-1] @@ -389,8 +397,9 @@ class Frame(object): OPHANDLERS = [None] * (rop._LAST+1) - def __init__(self, memocast): + def __init__(self, memocast, cpu): self.verbose = False + self.cpu = cpu self.memocast = memocast self.opindex = 1 self._forced = False @@ -807,12 +816,53 @@ finally: self._may_force = -1 + def op_call_assembler(self, loop_token, *args): + global _last_exception + assert not self._forced + self._may_force = self.opindex + try: + inpargs = _from_opaque(loop_token._llgraph_compiled_version).inputargs + for i, inparg in enumerate(inpargs): + TYPE = inparg.concretetype + if TYPE is lltype.Signed: + set_future_value_int(i, args[i]) + elif isinstance(TYPE, lltype.Ptr): + set_future_value_ref(i, args[i]) + elif TYPE is lltype.Float: + set_future_value_float(i, args[i]) + else: + raise Exception("Nonsense type %s" % TYPE) + + failindex = self.cpu._execute_token(loop_token) + try: + if self.cpu.index_of_virtualizable != -1: + return self.cpu.assembler_helper_ptr(failindex, + args[self.cpu.index_of_virtualizable]) + else: + return self.cpu.assembler_helper_ptr(failindex, + lltype.nullptr(llmemory.GCREF.TO)) + except LLException, lle: + assert _last_exception is None, "exception left behind" + _last_exception = lle + # fish op + op = self.loop.operations[self.opindex] + if op.result is not None: + return 0 + finally: + self._may_force = -1 + def op_guard_not_forced(self, descr): forced = self._forced self._forced = False if forced: raise GuardFailed + def op_virtual_ref(self, _, virtual, index): + return virtual + + def op_virtual_ref_finish(self, _, vref, virtual): + pass + class OOFrame(Frame): @@ -961,11 +1011,11 @@ return x -def new_frame(memocast, is_oo): +def new_frame(memocast, is_oo, cpu): if is_oo: - frame = OOFrame(memocast) + frame = OOFrame(memocast, cpu) else: - frame = Frame(memocast) + frame = Frame(memocast, cpu) return _to_opaque(frame) _future_values = [] @@ -1059,7 +1109,7 @@ else: # for tests, a random emulated ll_inst will do if Class not in _pseudo_exceptions: - ll_inst = lltype.malloc(rclass.OBJECT) + ll_inst = lltype.malloc(rclass.OBJECT, zero=True) ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True) _pseudo_exceptions[Class] = LLException(ll_inst.typeptr, ll_inst) @@ -1086,7 +1136,8 @@ assert frame._may_force >= 0 call_op = frame.loop.operations[frame._may_force] guard_op = frame.loop.operations[frame._may_force+1] - assert call_op.opnum == rop.CALL_MAY_FORCE + opnum = call_op.opnum + assert opnum == rop.CALL_MAY_FORCE or opnum == rop.CALL_ASSEMBLER frame._populate_fail_args(guard_op, skip=call_op.result) return frame.fail_index @@ -1201,7 +1252,7 @@ def do_new(size): TYPE = symbolic.Size2Type[size] - x = lltype.malloc(TYPE) + x = lltype.malloc(TYPE, zero=True) return cast_to_ptr(x) def do_new_array(arraynum, count): Modified: pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/runner.py Mon Jan 25 15:25:48 2010 @@ -74,7 +74,8 @@ class BaseCPU(model.AbstractCPU): supports_floats = True - def __init__(self, rtyper, stats=None, opts=None, translate_support_code=False, + def __init__(self, rtyper, stats=None, opts=None, + translate_support_code=False, annmixlevel=None, gcdescr=None): assert type(opts) is not bool model.AbstractCPU.__init__(self) @@ -147,6 +148,8 @@ descr = op.descr if isinstance(descr, Descr): llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo) + if isinstance(descr, history.LoopToken): + llimpl.compile_add_loop_token(c, descr) if self.is_oo and isinstance(descr, (OODescr, MethDescr)): # hack hack, not rpython c._obj.externalobj.operations[-1].descr = descr @@ -207,18 +210,22 @@ else: assert False, "unknown operation" - def execute_token(self, loop_token): - """Calls the assembler generated for the given loop. - Returns the ResOperation that failed, of type rop.FAIL. - """ + def _execute_token(self, loop_token): compiled_version = loop_token._llgraph_compiled_version - frame = llimpl.new_frame(self.memo_cast, self.is_oo) + frame = llimpl.new_frame(self.memo_cast, self.is_oo, self) # setup the frame llimpl.frame_clear(frame, compiled_version) # run the loop fail_index = llimpl.frame_execute(frame) # we hit a FAIL operation. self.latest_frame = frame + return fail_index + + def execute_token(self, loop_token): + """Calls the assembler generated for the given loop. + Returns the ResOperation that failed, of type rop.FAIL. + """ + fail_index = self._execute_token(loop_token) return self.get_fail_descr_from_number(fail_index) def set_future_value_int(self, index, intvalue): Modified: pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/test/test_llgraph.py Mon Jan 25 15:25:48 2010 @@ -7,7 +7,8 @@ TreeLoop from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.metainterp.executor import execute -from pypy.jit.backend.test.runner_test import LLtypeBackendTest +from pypy.jit.backend.test.runner_test import LLtypeBackendTest, \ + BaseAssemblerCallTests class TestLLTypeLLGraph(LLtypeBackendTest): # for individual tests see: Modified: pypy/branch/stringbuilder2/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/llsupport/gc.py Mon Jan 25 15:25:48 2010 @@ -41,7 +41,7 @@ GcLLDescription.__init__(self, gcdescr, translator) # grab a pointer to the Boehm 'malloc' function from pypy.rpython.tool import rffi_platform - compilation_info = rffi_platform.check_boehm() + compilation_info = rffi_platform.configure_boehm() # Versions 6.x of libgc needs to use GC_local_malloc(). # Versions 7.x of libgc removed this function; GC_malloc() has Modified: pypy/branch/stringbuilder2/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/model.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/model.py Mon Jan 25 15:25:48 2010 @@ -1,8 +1,12 @@ -from pypy.jit.metainterp import history +from pypy.jit.metainterp import history, compile class AbstractCPU(object): supports_floats = False + # assembler_helper_ptr - a pointer to helper to call after a direct + # assembler call + portal_calldescr = None + done_with_this_frame_int_v = -1 def __init__(self): self.fail_descr_list = [] @@ -209,6 +213,12 @@ def do_call(self, args, calldescr): raise NotImplementedError + def do_call_assembler(self, args, token): + raise NotImplementedError + + def do_call_loopinvariant(self, args, calldescr): + return self.do_call(args, calldescr) + def do_cond_call_gc_wb(self, args, calldescr): if args[0].getint() & args[1].getint(): self.do_call(args[2:], calldescr) @@ -219,10 +229,6 @@ def do_cast_ptr_to_int(self, ptrbox): raise NotImplementedError - def do_force_token(self): - # this should not be implemented at all by the backends - raise NotImplementedError - def do_call_may_force(self, args, calldescr): return self.do_call(args, calldescr) Modified: pypy/branch/stringbuilder2/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/test/runner_test.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/test/runner_test.py Mon Jan 25 15:25:48 2010 @@ -1,5 +1,5 @@ -import py, sys, random +import py, sys, random, os from pypy.jit.metainterp.history import (AbstractFailDescr, BasicFailDescr, BoxInt, Box, BoxPtr, @@ -15,6 +15,7 @@ from pypy.jit.metainterp.test.oparser import parse from pypy.rpython.annlowlevel import llhelper from pypy.rpython.llinterp import LLException +from pypy.jit.metainterp.test.oparser import parse class Runner(object): @@ -464,6 +465,30 @@ [funcbox] + args, 'float', descr=calldescr) assert abs(res.value - 4.6) < 0.0001 + + def test_call_stack_alignment(self): + # test stack alignment issues, notably for Mac OS/X. + # also test the ordering of the arguments. + + def func_ints(*ints): + s = str(ints) + '\n' + os.write(1, s) # don't remove -- crash if the stack is misaligned + return sum([(10+i)*(5+j) for i, j in enumerate(ints)]) + + for nb_args in range(0, 35): + cpu = self.cpu + TP = lltype.Signed + # + FPTR = self.Ptr(self.FuncType([TP] * nb_args, TP)) + func_ptr = llhelper(FPTR, func_ints) + FUNC = deref(FPTR) + calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT) + funcbox = self.get_funcbox(cpu, func_ptr) + args = [280-24*i for i in range(nb_args)] + res = self.execute_operation(rop.CALL, + [funcbox] + map(BoxInt, args), + 'int', descr=calldescr) + assert res.value == func_ints(*args) def test_field_basic(self): t_box, T_box = self.alloc_instance(self.T) @@ -779,6 +804,19 @@ r = self.execute_operation(rop.SAME_AS, [BoxFloat(5.5)], 'float') assert r.value == 5.5 + def test_virtual_ref(self): + # if VIRTUAL_REF reaches the backend, it should just be a SAME_AS + u_box = self.alloc_unicode(u"hello\u1234") + r = self.execute_operation(rop.VIRTUAL_REF, [u_box, ConstInt(2)], + 'ref') + assert r.value == u_box.value + + def test_virtual_ref_finish(self): + # if VIRTUAL_REF_FINISH reaches the backend, it is a no-op + self.execute_operation(rop.VIRTUAL_REF_FINISH, + [BoxInt(123), BoxInt(234)], + 'void') + def test_jump(self): # this test generates small loops where the JUMP passes many # arguments of various types, shuffling them around. @@ -1572,6 +1610,87 @@ lltype.free(x, flavor='raw') + def test_assembler_call(self): + called = [] + def assembler_helper(failindex, virtualizable): + assert self.cpu.get_latest_value_int(0) == 10 + called.append(failindex) + return 4 + 9 + self.cpu.index_of_virtualizable = -1 + self.cpu.assembler_helper_ptr = llhelper(lltype.Ptr(lltype.FuncType + ([lltype.Signed, llmemory.GCREF], lltype.Signed)), assembler_helper) + + ops = ''' + [i0, i1] + i2 = int_add(i0, i1) + finish(i2)''' + loop = parse(ops) + looptoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + ARGS = [lltype.Signed, lltype.Signed] + RES = lltype.Signed + self.cpu.portal_calldescr = self.cpu.calldescrof( + lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES) + self.cpu.set_future_value_int(0, 1) + self.cpu.set_future_value_int(1, 2) + res = self.cpu.execute_token(looptoken) + assert self.cpu.get_latest_value_int(0) == 3 + ops = ''' + [i4, i5] + i6 = int_add(i4, 1) + i3 = call_assembler(i6, i5, descr=looptoken) + guard_not_forced()[] + finish(i3) + ''' + loop = parse(ops, namespace=locals()) + othertoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + self.cpu.set_future_value_int(0, 4) + self.cpu.set_future_value_int(1, 5) + res = self.cpu.execute_token(othertoken) + assert self.cpu.get_latest_value_int(0) == 13 + assert called + + def test_assembler_call_float(self): + called = [] + def assembler_helper(failindex, virtualizable): + assert self.cpu.get_latest_value_float(0) == 1.2 + 3.2 + called.append(failindex) + return 13.5 + self.cpu.index_of_virtualizable = -1 + self.cpu.assembler_helper_ptr = llhelper(lltype.Ptr(lltype.FuncType + ([lltype.Signed, llmemory.GCREF], lltype.Float)), assembler_helper) + ARGS = [lltype.Float, lltype.Float] + RES = lltype.Float + self.cpu.portal_calldescr = self.cpu.calldescrof( + lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES) + + ops = ''' + [f0, f1] + f2 = float_add(f0, f1) + finish(f2)''' + loop = parse(ops) + looptoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + self.cpu.set_future_value_float(0, 1.2) + self.cpu.set_future_value_float(1, 2.3) + res = self.cpu.execute_token(looptoken) + assert self.cpu.get_latest_value_float(0) == 1.2 + 2.3 + ops = ''' + [f4, f5] + f3 = call_assembler(f4, f5, descr=looptoken) + guard_not_forced()[] + finish(f3) + ''' + loop = parse(ops, namespace=locals()) + othertoken = LoopToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) + self.cpu.set_future_value_float(0, 1.2) + self.cpu.set_future_value_float(1, 3.2) + res = self.cpu.execute_token(othertoken) + assert self.cpu.get_latest_value_float(0) == 13.5 + assert called + class OOtypeBackendTest(BaseBackendTest): type_system = 'ootype' @@ -1609,3 +1728,4 @@ def alloc_unicode(self, unicode): py.test.skip("implement me") + Modified: pypy/branch/stringbuilder2/pypy/jit/backend/test/support.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/test/support.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/test/support.py Mon Jan 25 15:25:48 2010 @@ -100,6 +100,9 @@ def check_aborted_count(self, *args, **kwds): pass + def check_aborted_count_at_least(self, *args, **kwds): + pass + def interp_operations(self, *args, **kwds): py.test.skip("interp_operations test skipped") @@ -117,6 +120,7 @@ def _get_TranslationContext(self): t = TranslationContext() t.config.translation.gc = 'boehm' + t.config.translation.list_comprehension_operations = True return t def _compile_and_run(self, t, entry_point, entry_point_graph, args): Modified: pypy/branch/stringbuilder2/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/test/test_random.py Mon Jan 25 15:25:48 2010 @@ -431,10 +431,11 @@ for _op in [rop.FLOAT_NEG, rop.FLOAT_ABS, - rop.FLOAT_IS_TRUE, ]: OPERATIONS.append(UnaryFloatOperation(_op)) +OPERATIONS.append(UnaryFloatOperation(rop.FLOAT_IS_TRUE, boolres=True)) + OPERATIONS.append(CastFloatToIntOperation(rop.CAST_FLOAT_TO_INT)) OPERATIONS.append(CastIntToFloatOperation(rop.CAST_INT_TO_FLOAT)) Modified: pypy/branch/stringbuilder2/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/x86/assembler.py Mon Jan 25 15:25:48 2010 @@ -2,7 +2,8 @@ import ctypes from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.history import Const, Box, BoxInt, BoxPtr, BoxFloat -from pypy.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT +from pypy.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT,\ + LoopToken from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory from pypy.rpython.lltypesystem.rclass import OBJECT from pypy.rpython.lltypesystem.lloperation import llop @@ -17,6 +18,7 @@ from pypy.jit.metainterp.resoperation import rop from pypy.jit.backend.x86.support import values_array from pypy.rlib.debug import debug_print +from pypy.rlib import rgc # our calling convention - we pass first 6 args in registers # and the rest stays on the stack @@ -27,7 +29,6 @@ else: CALL_ALIGN = 1 - def align_stack_words(words): return (words + CALL_ALIGN - 1) & ~(CALL_ALIGN-1) @@ -75,6 +76,7 @@ mc = None mc2 = None mc_size = MachineCodeBlockWrapper.MC_DEFAULT_SIZE + _float_constants = None def __init__(self, cpu, translate_support_code=False, failargs_limit=1000): @@ -85,6 +87,7 @@ self.malloc_array_func_addr = 0 self.malloc_str_func_addr = 0 self.malloc_unicode_func_addr = 0 + self.assembler_helper_adr = 0 self.fail_boxes_int = values_array(lltype.Signed, failargs_limit) self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit) self.fail_boxes_float = values_array(lltype.Float, failargs_limit) @@ -117,6 +120,14 @@ ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode() self.malloc_unicode_func_addr = rffi.cast(lltype.Signed, ll_new_unicode) + if we_are_translated(): + self.assembler_helper_adr = self.cpu.cast_ptr_to_int( + self.cpu.assembler_helper_ptr) + else: + if getattr(self.cpu, 'assembler_helper_ptr', None): + self.assembler_helper_adr = self.cpu.cast_ptr_to_int( + self.cpu.assembler_helper_ptr) + # done # we generate the loop body in 'mc' # 'mc2' is for guard recovery code @@ -153,6 +164,7 @@ """adds the following attributes to looptoken: _x86_loop_code (an integer giving an address) _x86_bootstrap_code (an integer giving an address) + _x86_direct_bootstrap_code _x86_frame_depth _x86_param_depth _x86_arglocs @@ -161,15 +173,29 @@ regalloc = RegAlloc(self, self.cpu.translate_support_code) arglocs = regalloc.prepare_loop(inputargs, operations, looptoken) looptoken._x86_arglocs = arglocs + needed_mem = len(arglocs[0]) * 16 + 16 + if needed_mem >= self.mc.bytes_free(): + self.mc.make_new_mc() looptoken._x86_bootstrap_code = self.mc.tell() adr_stackadjust = self._assemble_bootstrap_code(inputargs, arglocs) - looptoken._x86_loop_code = self.mc.tell() + curadr = self.mc.tell() + looptoken._x86_loop_code = curadr looptoken._x86_frame_depth = -1 # temporarily looptoken._x86_param_depth = -1 # temporarily frame_depth, param_depth = self._assemble(regalloc, operations) self._patch_stackadjust(adr_stackadjust, frame_depth+param_depth) looptoken._x86_frame_depth = frame_depth looptoken._x86_param_depth = param_depth + # we need to make sure here that we don't overload an mc badly. + # a safe estimate is that we need at most 16 bytes per arg + needed_mem = len(arglocs[0]) * 16 + 16 + if needed_mem >= self.mc.bytes_free(): + self.mc.make_new_mc() + looptoken._x86_direct_bootstrap_code = self.mc.tell() + self._assemble_bootstrap_direct_call(arglocs, curadr, + frame_depth+param_depth) + debug_print("Loop #", looptoken.number, "has address", + looptoken._x86_loop_code, "to", self.mc.tell()) def assemble_bridge(self, faildescr, inputargs, operations): self.make_sure_mc_exists() @@ -192,6 +218,9 @@ faildescr._x86_bridge_param_depth = param_depth # patch the jump from original guard self.patch_jump(faildescr, adr_bridge) + debug_print("Bridge out of guard", + self.cpu.get_fail_descr_number(faildescr), + "has address", adr_bridge, "to", self.mc.tell()) def patch_jump(self, faildescr, adr_new_target): adr_jump_offset = faildescr._x86_adr_jump_offset @@ -224,17 +253,17 @@ def _patch_stackadjust(self, adr_lea, reserved_depth): # patch stack adjustment LEA - # possibly align, e.g. for Mac OS X mc = codebuf.InMemoryCodeBuilder(adr_lea, adr_lea + 4) # Compute the correct offset for the instruction LEA ESP, [EBP-4*words]. # Given that [EBP] is where we saved EBP, i.e. in the last word # of our fixed frame, then the 'words' value is: words = (FRAME_FIXED_SIZE - 1) + reserved_depth - mc.write(packimm32(-WORD * words)) + # align, e.g. for Mac OS X + aligned_words = align_stack_words(words+2)-2 # 2 = EIP+EBP + mc.write(packimm32(-WORD * aligned_words)) mc.done() - def _assemble_bootstrap_code(self, inputargs, arglocs): - nonfloatlocs, floatlocs = arglocs + def _call_header(self): self.mc.PUSH(ebp) self.mc.MOV(ebp, esp) self.mc.PUSH(ebx) @@ -242,7 +271,41 @@ self.mc.PUSH(edi) # NB. the shape of the frame is hard-coded in get_basic_shape() too. # Also, make sure this is consistent with FRAME_FIXED_SIZE. - adr_stackadjust = self._patchable_stackadjust() + return self._patchable_stackadjust() + + def _assemble_bootstrap_direct_call(self, arglocs, jmpadr, stackdepth): + # XXX pushing ebx esi and edi is a bit pointless, since we store + # all regsiters anyway, for the case of guard_not_forced + # XXX this can be improved greatly. Right now it'll behave like + # a normal call + nonfloatlocs, floatlocs = arglocs + # XXX not to repeat the logic, a bit around + adr_stackadjust = self._call_header() + self._patch_stackadjust(adr_stackadjust, stackdepth) + for i in range(len(nonfloatlocs)): + loc = nonfloatlocs[i] + if isinstance(loc, REG): + self.mc.MOV(loc, mem(ebp, (2 + i) * WORD)) + loc = floatlocs[i] + if isinstance(loc, XMMREG): + self.mc.MOVSD(loc, mem64(ebp, (1 + i) * 2 * WORD)) + tmp = eax + xmmtmp = xmm0 + for i in range(len(nonfloatlocs)): + loc = nonfloatlocs[i] + if loc is not None and not isinstance(loc, REG): + self.mc.MOV(tmp, mem(ebp, (2 + i) * WORD)) + self.mc.MOV(loc, tmp) + loc = floatlocs[i] + if loc is not None and not isinstance(loc, XMMREG): + self.mc.MOVSD(xmmtmp, mem64(ebp, (1 + i) * 2 * WORD)) + self.mc.MOVSD(loc, xmmtmp) + self.mc.JMP(rel32(jmpadr)) + return adr_stackadjust + + def _assemble_bootstrap_code(self, inputargs, arglocs): + nonfloatlocs, floatlocs = arglocs + adr_stackadjust = self._call_header() tmp = X86RegisterManager.all_regs[0] xmmtmp = X86XMMRegisterManager.all_regs[0] for i in range(len(nonfloatlocs)): @@ -366,19 +429,18 @@ def genop_cmp(self, op, arglocs, result_loc): if isinstance(op.args[0], Const): self.mc.CMP(arglocs[1], arglocs[0]) - self.mc.MOV(result_loc, imm8(0)) getattr(self.mc, 'SET' + rev_cond)(lower_byte(result_loc)) else: self.mc.CMP(arglocs[0], arglocs[1]) - self.mc.MOV(result_loc, imm8(0)) getattr(self.mc, 'SET' + cond)(lower_byte(result_loc)) + self.mc.MOVZX(result_loc, lower_byte(result_loc)) return genop_cmp def _cmpop_float(cond): def genop_cmp(self, op, arglocs, result_loc): self.mc.UCOMISD(arglocs[0], arglocs[1]) - self.mc.MOV(result_loc, imm8(0)) getattr(self.mc, 'SET' + cond)(lower_byte(result_loc)) + self.mc.MOVZX(result_loc, lower_byte(result_loc)) return genop_cmp def _cmpop_guard(cond, rev_cond, false_cond, false_rev_cond): @@ -402,38 +464,47 @@ return self.implement_guard(addr, getattr(self.mc, name)) return genop_cmp_guard -## XXX redo me -## def align_stack_for_call(self, nargs): -## # xxx do something when we don't use push anymore for calls -## extra_on_stack = align_stack_words(nargs) -## for i in range(extra_on_stack-nargs): -## self.mc.PUSH(imm(0)) --- or just use a single SUB(esp, imm) -## return extra_on_stack - - def _emit_call(self, x, arglocs, start=0, tmp=eax): + def _cmpop_guard_float(cond, false_cond): + def genop_cmp_guard_float(self, op, guard_op, addr, arglocs, + result_loc): + guard_opnum = guard_op.opnum + self.mc.UCOMISD(arglocs[0], arglocs[1]) + if guard_opnum == rop.GUARD_FALSE: + name = 'J' + cond + return self.implement_guard(addr, getattr(self.mc, name)) + else: + name = 'J' + false_cond + return self.implement_guard(addr, getattr(self.mc, name)) + return genop_cmp_guard_float + + @specialize.arg(5) + def _emit_call(self, x, arglocs, start=0, tmp=eax, force_mc=False, + mc=None): + if not force_mc: + mc = self.mc p = 0 n = len(arglocs) for i in range(start, n): loc = arglocs[i] if isinstance(loc, REG): if isinstance(loc, XMMREG): - self.mc.MOVSD(mem64(esp, p), loc) + mc.MOVSD(mem64(esp, p), loc) else: - self.mc.MOV(mem(esp, p), loc) + mc.MOV(mem(esp, p), loc) p += round_up_to_4(loc.width) p = 0 for i in range(start, n): loc = arglocs[i] if not isinstance(loc, REG): if isinstance(loc, MODRM64): - self.mc.MOVSD(xmm0, loc) - self.mc.MOVSD(mem64(esp, p), xmm0) + mc.MOVSD(xmm0, loc) + mc.MOVSD(mem64(esp, p), xmm0) else: - self.mc.MOV(tmp, loc) - self.mc.MOV(mem(esp, p), tmp) + mc.MOV(tmp, loc) + mc.MOV(mem(esp, p), tmp) p += round_up_to_4(loc.width) self._regalloc.reserve_param(p//WORD) - self.mc.CALL(x) + mc.CALL(x) self.mark_gc_roots() def call(self, addr, args, res): @@ -460,11 +531,11 @@ genop_int_lt = _cmpop("L", "G") genop_int_le = _cmpop("LE", "GE") genop_int_eq = _cmpop("E", "E") - genop_oois = genop_int_eq genop_int_ne = _cmpop("NE", "NE") - genop_ooisnot = genop_int_ne genop_int_gt = _cmpop("G", "L") genop_int_ge = _cmpop("GE", "LE") + genop_oois = genop_int_eq + genop_ooisnot = genop_int_ne genop_float_lt = _cmpop_float('B') genop_float_le = _cmpop_float('BE') @@ -484,12 +555,21 @@ genop_guard_int_ne = _cmpop_guard("NE", "NE", "E", "E") genop_guard_int_gt = _cmpop_guard("G", "L", "LE", "GE") genop_guard_int_ge = _cmpop_guard("GE", "LE", "L", "G") + genop_guard_oois = genop_guard_int_eq + genop_guard_ooisnot = genop_guard_int_ne genop_guard_uint_gt = _cmpop_guard("A", "B", "BE", "AE") genop_guard_uint_lt = _cmpop_guard("B", "A", "AE", "BE") genop_guard_uint_le = _cmpop_guard("BE", "AE", "A", "B") genop_guard_uint_ge = _cmpop_guard("AE", "BE", "B", "A") + genop_guard_float_lt = _cmpop_guard_float("B", "AE") + genop_guard_float_le = _cmpop_guard_float("BE", "A") + genop_guard_float_eq = _cmpop_guard_float("E", "NE") + genop_guard_float_ne = _cmpop_guard_float("NE", "E") + genop_guard_float_gt = _cmpop_guard_float("A", "BE") + genop_guard_float_ge = _cmpop_guard_float("AE", "B") + def genop_float_neg(self, op, arglocs, resloc): # Following what gcc does: res = x ^ 0x8000000000000000 self.mc.XORPD(arglocs[0], self.loc_float_const_neg) @@ -498,6 +578,16 @@ # Following what gcc does: res = x & 0x7FFFFFFFFFFFFFFF self.mc.ANDPD(arglocs[0], self.loc_float_const_abs) + def genop_guard_float_is_true(self, op, guard_op, addr, arglocs, resloc): + guard_opnum = guard_op.opnum + loc0, loc1 = arglocs + self.mc.XORPD(loc0, loc0) + self.mc.UCOMISD(loc0, loc1) + if guard_opnum == rop.GUARD_TRUE: + return self.implement_guard(addr, self.mc.JZ) + else: + return self.implement_guard(addr, self.mc.JNZ) + def genop_float_is_true(self, op, arglocs, resloc): loc0, loc1 = arglocs self.mc.XORPD(loc0, loc0) @@ -511,9 +601,6 @@ def genop_cast_int_to_float(self, op, arglocs, resloc): self.mc.CVTSI2SD(resloc, arglocs[0]) - def genop_bool_not(self, op, arglocs, resloc): - self.mc.XOR(arglocs[0], imm8(1)) - def genop_int_lshift(self, op, arglocs, resloc): loc, loc2 = arglocs if loc2 is ecx: @@ -534,8 +621,7 @@ def genop_guard_int_is_true(self, op, guard_op, addr, arglocs, resloc): guard_opnum = guard_op.opnum - loc = arglocs[0] - self.mc.TEST(loc, loc) + self.mc.CMP(arglocs[0], imm8(0)) if guard_opnum == rop.GUARD_TRUE: return self.implement_guard(addr, self.mc.JZ) else: @@ -543,12 +629,24 @@ def genop_int_is_true(self, op, arglocs, resloc): self.mc.CMP(arglocs[0], imm8(0)) - self.mc.MOV(resloc, imm8(0)) self.mc.SETNE(lower_byte(resloc)) + self.mc.MOVZX(resloc, lower_byte(resloc)) + + def genop_guard_bool_not(self, op, guard_op, addr, arglocs, resloc): + guard_opnum = guard_op.opnum + self.mc.CMP(arglocs[0], imm8(0)) + if guard_opnum == rop.GUARD_TRUE: + return self.implement_guard(addr, self.mc.JNZ) + else: + return self.implement_guard(addr, self.mc.JZ) + + def genop_bool_not(self, op, arglocs, resloc): + self.mc.XOR(arglocs[0], imm8(1)) def genop_same_as(self, op, arglocs, resloc): self.mov(arglocs[0], resloc) genop_cast_ptr_to_int = genop_same_as + genop_virtual_ref = genop_same_as def genop_int_mod(self, op, arglocs, resloc): self.mc.CDQ() @@ -955,6 +1053,7 @@ boxes.append(box) return boxes + @rgc.no_collect def grab_frame_values(self, bytecode, frame_addr, allregisters): # no malloc allowed here!! self.fail_ebp = allregisters[16 + ebp.op] @@ -1019,6 +1118,7 @@ def setup_failure_recovery(self): + @rgc.no_collect def failure_recovery_func(registers): # 'registers' is a pointer to a structure containing the # original value of the registers, optionally the original @@ -1153,7 +1253,7 @@ tmp = ecx else: tmp = eax - + self._emit_call(x, arglocs, 2, tmp=tmp) if isinstance(resloc, MODRM64): @@ -1174,6 +1274,38 @@ self.mc.CMP(mem(ebp, FORCE_INDEX_OFS), imm(0)) return self.implement_guard(addr, self.mc.JL) + def genop_guard_call_assembler(self, op, guard_op, addr, + arglocs, result_loc): + faildescr = guard_op.descr + fail_index = self.cpu.get_fail_descr_number(faildescr) + self.mc.MOV(mem(ebp, FORCE_INDEX_OFS), imm(fail_index)) + descr = op.descr + assert isinstance(descr, LoopToken) + assert len(arglocs) - 2 == len(descr._x86_arglocs[0]) + self._emit_call(rel32(descr._x86_direct_bootstrap_code), arglocs, 2, + tmp=eax) + mc = self.mc._mc + mc.CMP(eax, imm(self.cpu.done_with_this_frame_int_v)) + mc.write(constlistofchars('\x74\x00')) # JE below + je_location = mc.get_relative_pos() + self._emit_call(rel32(self.assembler_helper_adr), [eax, arglocs[1]], 0, + tmp=ecx, force_mc=True, mc=mc) + mc.write(constlistofchars('\xEB\x00')) # JMP below + jmp_location = mc.get_relative_pos() + offset = jmp_location - je_location + assert 0 < offset <= 127 + mc.overwrite(je_location - 1, [chr(offset)]) + mc.MOV(eax, heap(self.fail_boxes_int.get_addr_for_num(0))) + offset = mc.get_relative_pos() - jmp_location + assert 0 < offset <= 127 + mc.overwrite(jmp_location - 1, [chr(offset)]) + if isinstance(result_loc, MODRM64): + self.mc.FSTP(result_loc) + else: + assert result_loc is eax or result_loc is None + self.mc.CMP(mem(ebp, FORCE_INDEX_OFS), imm(0)) + return self.implement_guard(addr, self.mc.JL) + def genop_discard_cond_call_gc_wb(self, op, arglocs): # use 'mc._mc' directly instead of 'mc', to avoid # bad surprizes if the code buffer is mostly full @@ -1218,7 +1350,7 @@ def not_implemented_op_guard(self, op, guard_op, failaddr, arglocs, resloc): - msg = "not implemented operation (guard): %s" % guard_op.getopname() + msg = "not implemented operation (guard): %s" % op.getopname() print msg raise NotImplementedError(msg) Modified: pypy/branch/stringbuilder2/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/x86/regalloc.py Mon Jan 25 15:25:48 2010 @@ -52,7 +52,28 @@ print "convert_to_imm: got a %s" % c raise AssertionError -BASE_CONSTANT_SIZE = 1000 + +class FloatConstants(object): + BASE_CONSTANT_SIZE = 1000 + + def __init__(self): + self.cur_array_free = 0 + + def _get_new_array(self): + n = self.BASE_CONSTANT_SIZE + self.cur_array = lltype.malloc(rffi.CArray(lltype.Float), n, + flavor='raw') + self.cur_array_free = n + _get_new_array._dont_inline_ = True + + def record_float(self, floatval): + if self.cur_array_free == 0: + self._get_new_array() + arr = self.cur_array + n = self.cur_array_free - 1 + arr[n] = floatval + self.cur_array_free = n + return rffi.cast(lltype.Signed, arr) + n * 8 class X86XMMRegisterManager(RegisterManager): @@ -63,29 +84,19 @@ save_around_call_regs = all_regs reg_width = 2 - def new_const_array(self): - return lltype.malloc(rffi.CArray(lltype.Float), BASE_CONSTANT_SIZE, - flavor='raw') - def __init__(self, longevity, frame_manager=None, assembler=None): RegisterManager.__init__(self, longevity, frame_manager=frame_manager, assembler=assembler) - self.constant_arrays = [self.new_const_array()] - self.constant_array_counter = 0 + if assembler is None: + self.float_constants = FloatConstants() + else: + if assembler._float_constants is None: + assembler._float_constants = FloatConstants() + self.float_constants = assembler._float_constants def convert_to_imm(self, c): - if self.constant_array_counter >= BASE_CONSTANT_SIZE: - self.constant_arrays.append(self.new_const_array()) - self.constant_array_counter = 0 - res = self.constant_array_counter - self.constant_array_counter += 1 - arr = self.constant_arrays[-1] - arr[res] = c.getfloat() - return self.get_addr_of_const_float(-1, res) - - def get_addr_of_const_float(self, num_arr, num_pos): - arr = self.constant_arrays[num_arr] - return heap64(rffi.cast(lltype.Signed, arr) + num_pos * WORD * 2) + adr = self.float_constants.record_float(c.getfloat()) + return heap64(adr) def after_call(self, v): # the result is stored in st0, but we don't have this around, @@ -307,7 +318,7 @@ self.assembler.regalloc_perform_discard(op, arglocs) def can_merge_with_next_guard(self, op, i, operations): - if op.opnum == rop.CALL_MAY_FORCE: + if op.opnum == rop.CALL_MAY_FORCE or op.opnum == rop.CALL_ASSEMBLER: assert operations[i + 1].opnum == rop.GUARD_NOT_FORCED return True if not op.is_comparison(): @@ -334,10 +345,10 @@ self.possibly_free_vars(op.args) continue if self.can_merge_with_next_guard(op, i, operations): - oplist[op.opnum](self, op, operations[i + 1]) + oplist_with_guard[op.opnum](self, op, operations[i + 1]) i += 1 else: - oplist[op.opnum](self, op, None) + oplist[op.opnum](self, op) if op.result is not None: self.possibly_free_var(op.result) self.rm._check_invariants() @@ -386,7 +397,7 @@ return self.xrm.loc(v) return self.rm.loc(v) - def _consider_guard(self, op, ignored): + def _consider_guard(self, op): loc = self.rm.make_sure_var_in_reg(op.args[0]) self.perform_guard(op, [loc], None) self.rm.possibly_free_var(op.args[0]) @@ -396,7 +407,7 @@ consider_guard_nonnull = _consider_guard consider_guard_isnull = _consider_guard - def consider_finish(self, op, ignored): + def consider_finish(self, op): locs = [self.loc(v) for v in op.args] locs_are_ref = [v.type == REF for v in op.args] fail_index = self.assembler.cpu.get_fail_descr_number(op.descr) @@ -404,10 +415,10 @@ self.exc, locs_are_ref) self.possibly_free_vars(op.args) - def consider_guard_no_exception(self, op, ignored): + def consider_guard_no_exception(self, op): self.perform_guard(op, [], None) - def consider_guard_exception(self, op, ignored): + def consider_guard_exception(self, op): loc = self.rm.make_sure_var_in_reg(op.args[0]) box = TempBox() loc1 = self.rm.force_allocate_reg(box, op.args) @@ -423,13 +434,13 @@ consider_guard_no_overflow = consider_guard_no_exception consider_guard_overflow = consider_guard_no_exception - def consider_guard_value(self, op, ignored): + def consider_guard_value(self, op): x = self.make_sure_var_in_reg(op.args[0]) y = self.loc(op.args[1]) self.perform_guard(op, [x, y], None) self.possibly_free_vars(op.args) - def consider_guard_class(self, op, ignored): + def consider_guard_class(self, op): assert isinstance(op.args[0], Box) x = self.rm.make_sure_var_in_reg(op.args[0]) y = self.loc(op.args[1]) @@ -438,15 +449,15 @@ consider_guard_nonnull_class = consider_guard_class - def _consider_binop_part(self, op, ignored): + def _consider_binop_part(self, op): x = op.args[0] argloc = self.loc(op.args[1]) loc = self.rm.force_result_in_reg(op.result, x, op.args) self.rm.possibly_free_var(op.args[1]) return loc, argloc - def _consider_binop(self, op, ignored): - loc, argloc = self._consider_binop_part(op, ignored) + def _consider_binop(self, op): + loc, argloc = self._consider_binop_part(op) self.Perform(op, [loc, argloc], loc) consider_int_add = _consider_binop @@ -460,14 +471,13 @@ consider_int_sub_ovf = _consider_binop consider_int_add_ovf = _consider_binop - def consider_int_neg(self, op, ignored): + def consider_int_neg(self, op): res = self.rm.force_result_in_reg(op.result, op.args[0]) self.Perform(op, [res], res) consider_int_invert = consider_int_neg - consider_bool_not = consider_int_neg - def consider_int_lshift(self, op, ignored): + def consider_int_lshift(self, op): if isinstance(op.args[1], Const): loc2 = self.rm.convert_to_imm(op.args[1]) else: @@ -493,11 +503,11 @@ self.rm.possibly_free_vars(op.args) self.rm.possibly_free_var(tmpvar) - def consider_int_mod(self, op, ignored): + def consider_int_mod(self, op): self._consider_int_div_or_mod(op, edx, eax) self.Perform(op, [eax, ecx], edx) - def consider_int_floordiv(self, op, ignored): + def consider_int_floordiv(self, op): self._consider_int_div_or_mod(op, eax, edx) self.Perform(op, [eax, ecx], eax) @@ -531,7 +541,7 @@ consider_oois = _consider_compop consider_ooisnot = _consider_compop - def _consider_float_op(self, op, ignored): + def _consider_float_op(self, op): loc1 = self.xrm.loc(op.args[1]) loc0 = self.xrm.force_result_in_reg(op.result, op.args[0], op.args) self.Perform(op, [loc0, loc1], loc0) @@ -542,15 +552,17 @@ consider_float_mul = _consider_float_op consider_float_truediv = _consider_float_op - def _consider_float_cmp(self, op, ignored): - assert ignored is None - # XXX so far we don't have guards here, but we want them + def _consider_float_cmp(self, op, guard_op): loc0 = self.xrm.make_sure_var_in_reg(op.args[0], op.args, imm_fine=False) loc1 = self.xrm.loc(op.args[1]) - res = self.rm.force_allocate_reg(op.result, need_lower_byte=True) - self.Perform(op, [loc0, loc1], res) - self.xrm.possibly_free_vars(op.args) + arglocs = [loc0, loc1] + self.xrm.possibly_free_vars(op.args) + if guard_op is None: + res = self.rm.force_allocate_reg(op.result, need_lower_byte=True) + self.Perform(op, arglocs, res) + else: + self.perform_with_guard(op, guard_op, arglocs, None) consider_float_lt = _consider_float_cmp consider_float_le = _consider_float_cmp @@ -559,32 +571,37 @@ consider_float_gt = _consider_float_cmp consider_float_ge = _consider_float_cmp - def consider_float_neg(self, op, ignored): + def consider_float_neg(self, op): loc0 = self.xrm.force_result_in_reg(op.result, op.args[0]) self.Perform(op, [loc0], loc0) self.xrm.possibly_free_var(op.args[0]) - def consider_float_abs(self, op, ignored): + def consider_float_abs(self, op): loc0 = self.xrm.force_result_in_reg(op.result, op.args[0]) self.Perform(op, [loc0], loc0) self.xrm.possibly_free_var(op.args[0]) - def consider_float_is_true(self, op, ignored): + def consider_float_is_true(self, op, guard_op): + # doesn't need arg to be in a register tmpbox0 = TempBox() loc0 = self.xrm.force_allocate_reg(tmpbox0) loc1 = self.xrm.loc(op.args[0]) - loc2 = self.rm.force_allocate_reg(op.result, need_lower_byte=True) - self.Perform(op, [loc0, loc1], loc2) + arglocs = [loc0, loc1] self.xrm.possibly_free_var(op.args[0]) self.xrm.possibly_free_var(tmpbox0) + if guard_op is not None: + self.perform_with_guard(op, guard_op, arglocs, None) + else: + loc2 = self.rm.force_allocate_reg(op.result, need_lower_byte=True) + self.Perform(op, arglocs, loc2) - def consider_cast_float_to_int(self, op, ignored): + def consider_cast_float_to_int(self, op): loc0 = self.xrm.make_sure_var_in_reg(op.args[0], imm_fine=False) loc1 = self.rm.force_allocate_reg(op.result) self.Perform(op, [loc0], loc1) self.xrm.possibly_free_var(op.args[0]) - def consider_cast_int_to_float(self, op, ignored): + def consider_cast_int_to_float(self, op): loc0 = self.rm.loc(op.args[0]) loc1 = self.xrm.force_allocate_reg(op.result) self.Perform(op, [loc0], loc1) @@ -614,7 +631,7 @@ self._call(op, [imm(size)] + [self.loc(arg) for arg in op.args], guard_not_forced_op=guard_not_forced_op) - def consider_call(self, op, ignored): + def consider_call(self, op): self._consider_call(op) consider_call_pure = consider_call @@ -622,7 +639,21 @@ assert guard_op is not None self._consider_call(op, guard_op) - def consider_cond_call_gc_wb(self, op, ignored): + def consider_call_assembler(self, op, guard_op): + descr = op.descr + portal_calldescr = self.assembler.cpu.portal_calldescr + size = portal_calldescr.get_result_size(self.translate_support_code) + vable_index = self.assembler.cpu.index_of_virtualizable + if vable_index != -1: + self.rm._sync_var(op.args[vable_index]) + vable = self.fm.loc(op.args[vable_index], 1) + else: + vable = imm(0) + self._call(op, [imm(size), vable] + + [self.loc(arg) for arg in op.args], + guard_not_forced_op=guard_op) + + def consider_cond_call_gc_wb(self, op): assert op.result is None arglocs = [self.loc(arg) for arg in op.args] # add eax, ecx and edx as extra "arguments" to ensure they are @@ -664,7 +695,7 @@ gc_ll_descr.get_malloc_fixedsize_slowpath_addr(), ) - def consider_new(self, op, ignored): + def consider_new(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.can_inline_malloc(op.descr): self._fastpath_malloc(op, op.descr) @@ -673,7 +704,7 @@ arglocs = [imm(x) for x in args] return self._call(op, arglocs) - def consider_new_with_vtable(self, op, ignored): + def consider_new_with_vtable(self, op): classint = op.args[0].getint() descrsize = self.assembler.cpu.class_sizes[classint] if self.assembler.cpu.gc_ll_descr.can_inline_malloc(descrsize): @@ -686,7 +717,7 @@ arglocs.append(self.loc(op.args[0])) return self._call(op, arglocs) - def consider_newstr(self, op, ignored): + def consider_newstr(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.get_funcptr_for_newstr is not None: # framework GC @@ -698,7 +729,7 @@ return self._malloc_varsize(ofs_items, ofs, 0, op.args[0], op.result) - def consider_newunicode(self, op, ignored): + def consider_newunicode(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.get_funcptr_for_newunicode is not None: # framework GC @@ -736,7 +767,7 @@ self.PerformDiscard(ResOperation(rop.SETFIELD_GC, [], None), [eax, imm(ofs_length), imm(WORD), loc]) - def consider_new_array(self, op, ignored): + def consider_new_array(self, op): gc_ll_descr = self.assembler.cpu.gc_ll_descr if gc_ll_descr.get_funcptr_for_newarray is not None: # framework GC @@ -767,7 +798,7 @@ ptr = fielddescr.is_pointer_field() return imm(ofs), imm(size), ptr - def consider_setfield_gc(self, op, ignored): + def consider_setfield_gc(self, op): ofs_loc, size_loc, ptr = self._unpack_fielddescr(op.descr) assert isinstance(size_loc, IMM32) if size_loc.value == 1: @@ -782,7 +813,7 @@ consider_setfield_raw = consider_setfield_gc - def consider_strsetitem(self, op, ignored): + def consider_strsetitem(self, op): base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args) value_loc = self.rm.make_sure_var_in_reg(op.args[2], op.args, @@ -792,7 +823,7 @@ consider_unicodesetitem = consider_strsetitem - def consider_setarrayitem_gc(self, op, ignored): + def consider_setarrayitem_gc(self, op): scale, ofs, ptr = self._unpack_arraydescr(op.descr) base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) if scale == 0: @@ -808,7 +839,7 @@ consider_setarrayitem_raw = consider_setarrayitem_gc - def consider_getfield_gc(self, op, ignored): + def consider_getfield_gc(self, op): ofs_loc, size_loc, _ = self._unpack_fielddescr(op.descr) base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) self.rm.possibly_free_vars(op.args) @@ -819,7 +850,7 @@ consider_getfield_raw_pure = consider_getfield_gc consider_getfield_gc_pure = consider_getfield_gc - def consider_getarrayitem_gc(self, op, ignored): + def consider_getarrayitem_gc(self, op): scale, ofs, _ = self._unpack_arraydescr(op.descr) base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args) @@ -829,29 +860,34 @@ consider_getarrayitem_gc_pure = consider_getarrayitem_gc - - def _consider_nullity(self, op, guard_op): - # doesn't need a register in arg + def consider_int_is_true(self, op, guard_op): + # doesn't need arg to be in a register + argloc = self.loc(op.args[0]) + self.rm.possibly_free_var(op.args[0]) if guard_op is not None: - argloc = self.rm.make_sure_var_in_reg(op.args[0]) - self.rm.possibly_free_var(op.args[0]) self.perform_with_guard(op, guard_op, [argloc], None) else: - argloc = self.loc(op.args[0]) - self.rm.possibly_free_var(op.args[0]) resloc = self.rm.force_allocate_reg(op.result, need_lower_byte=True) self.Perform(op, [argloc], resloc) - consider_int_is_true = _consider_nullity + def consider_bool_not(self, op, guard_op): + if guard_op is not None: + # doesn't need arg to be in a register + argloc = self.loc(op.args[0]) + self.rm.possibly_free_var(op.args[0]) + self.perform_with_guard(op, guard_op, [argloc], None) + else: + self.consider_int_neg(op) - def consider_same_as(self, op, ignored): + def consider_same_as(self, op): argloc = self.loc(op.args[0]) self.possibly_free_var(op.args[0]) resloc = self.force_allocate_reg(op.result) self.Perform(op, [argloc], resloc) consider_cast_ptr_to_int = consider_same_as + consider_virtual_ref = consider_same_as - def consider_strlen(self, op, ignored): + def consider_strlen(self, op): base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) self.rm.possibly_free_vars(op.args) result_loc = self.rm.force_allocate_reg(op.result) @@ -859,7 +895,7 @@ consider_unicodelen = consider_strlen - def consider_arraylen_gc(self, op, ignored): + def consider_arraylen_gc(self, op): arraydescr = op.descr assert isinstance(arraydescr, BaseArrayDescr) ofs = arraydescr.get_ofs_length(self.translate_support_code) @@ -868,7 +904,7 @@ result_loc = self.rm.force_allocate_reg(op.result) self.Perform(op, [base_loc, imm(ofs)], result_loc) - def consider_strgetitem(self, op, ignored): + def consider_strgetitem(self, op): base_loc = self.rm.make_sure_var_in_reg(op.args[0], op.args) ofs_loc = self.rm.make_sure_var_in_reg(op.args[1], op.args) self.rm.possibly_free_vars(op.args) @@ -877,7 +913,7 @@ consider_unicodegetitem = consider_strgetitem - def consider_jump(self, op, ignored): + def consider_jump(self, op): assembler = self.assembler assert self.jump_target_descr is None descr = op.descr @@ -905,9 +941,12 @@ self.possibly_free_vars(op.args) assembler.closing_jump(self.jump_target_descr) - def consider_debug_merge_point(self, op, ignored): + def consider_debug_merge_point(self, op): pass + def consider_virtual_ref_finish(self, op): + self.possibly_free_vars(op.args) + def get_mark_gc_roots(self, gcrootmap): shape = gcrootmap.get_basic_shape() for v, val in self.fm.frame_bindings.items(): @@ -926,22 +965,37 @@ assert reg is eax # ok to ignore this one return gcrootmap.compress_callshape(shape) - def consider_force_token(self, op, ignored): + def consider_force_token(self, op): loc = self.rm.force_allocate_reg(op.result) self.Perform(op, [], loc) - def not_implemented_op(self, op, ignored): + def not_implemented_op(self, op): msg = "[regalloc] Not implemented operation: %s" % op.getopname() print msg raise NotImplementedError(msg) + def not_implemented_op_with_guard(self, op, guard_op): + msg = "[regalloc] Not implemented operation with guard: %s" % ( + op.getopname(),) + print msg + raise NotImplementedError(msg) + oplist = [RegAlloc.not_implemented_op] * rop._LAST +oplist_with_guard = [RegAlloc.not_implemented_op_with_guard] * rop._LAST + +def add_none_argument(fn): + return lambda self, op: fn(self, op, None) for name, value in RegAlloc.__dict__.iteritems(): if name.startswith('consider_'): name = name[len('consider_'):] num = getattr(rop, name.upper()) - oplist[num] = value + if (ResOperation(num, [], None).is_comparison() + or num == rop.CALL_MAY_FORCE or num == rop.CALL_ASSEMBLER): + oplist_with_guard[num] = value + oplist[num] = add_none_argument(value) + else: + oplist[num] = value def get_ebp_ofs(position): # Argument is a frame position (0, 1, 2...). Modified: pypy/branch/stringbuilder2/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/x86/runner.py Mon Jan 25 15:25:48 2010 @@ -18,8 +18,8 @@ def __init__(self, rtyper, stats, opts=None, translate_support_code=False, gcdescr=None): - AbstractLLCPU.__init__(self, rtyper, stats, opts, translate_support_code, - gcdescr) + AbstractLLCPU.__init__(self, rtyper, stats, opts, + translate_support_code, gcdescr) def setup(self): if self.opts is not None: Modified: pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_gc_integration.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_gc_integration.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_gc_integration.py Mon Jan 25 15:25:48 2010 @@ -78,7 +78,7 @@ box = boxes[0] regalloc.position = 0 regalloc.consider_call(ResOperation(rop.CALL, [box], BoxInt(), - calldescr), None) + calldescr)) assert len(regalloc.assembler.movs) == 3 # mark = regalloc.get_mark_gc_roots(cpu.gc_ll_descr.gcrootmap) Modified: pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_recursive.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_recursive.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_recursive.py Mon Jan 25 15:25:48 2010 @@ -3,4 +3,6 @@ from pypy.jit.backend.x86.test.test_basic import Jit386Mixin class TestRecursive(Jit386Mixin, RecursiveTests): + # for the individual tests see + # ====> ../../../metainterp/test/test_recursive.py pass Modified: pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_regalloc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_regalloc.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_regalloc.py Mon Jan 25 15:25:48 2010 @@ -9,7 +9,7 @@ from pypy.jit.backend.llsupport.descr import GcCache from pypy.jit.backend.x86.runner import CPU from pypy.jit.backend.x86.regalloc import RegAlloc, WORD, X86RegisterManager,\ - BASE_CONSTANT_SIZE + FloatConstants from pypy.jit.metainterp.test.oparser import parse from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.annlowlevel import llhelper @@ -28,6 +28,7 @@ class MockAssembler(object): gcrefs = None + _float_constants = None def __init__(self, cpu=None, gc_ll_descr=None): self.movs = [] @@ -503,6 +504,7 @@ def test_float_overflow_const_list(self): ops = ['[f0]'] + BASE_CONSTANT_SIZE = FloatConstants.BASE_CONSTANT_SIZE for i in range(BASE_CONSTANT_SIZE * 2): ops.append('f%d = float_add(f%d, 3.5)' % (i + 1, i)) ops.append('finish(f%d)' % (BASE_CONSTANT_SIZE * 2)) Modified: pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_runner.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_runner.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_runner.py Mon Jan 25 15:25:48 2010 @@ -25,8 +25,8 @@ # for the individual tests see # ====> ../../test/runner_test.py - def setup_class(cls): - cls.cpu = CPU(rtyper=None, stats=FakeStats()) + def setup_method(self, meth): + self.cpu = CPU(rtyper=None, stats=FakeStats()) def test_execute_ptr_operation(self): cpu = self.cpu @@ -72,45 +72,41 @@ func = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)(f) addr = ctypes.cast(func, ctypes.c_void_p).value - try: - saved_addr = self.cpu.assembler.malloc_func_addr - self.cpu.assembler.malloc_func_addr = addr - ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] - - res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') - assert allocs[0] == 7 + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 7 - - # ------------------------------------------------------------ - - res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref') - assert allocs[0] == 7 + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 7 - - # ------------------------------------------------------------ - - TP = lltype.GcArray(lltype.Signed) - ofs = symbolic.get_field_token(TP, 'length', False)[0] - descr = self.cpu.arraydescrof(TP) - - res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], - 'ref', descr) - assert allocs[0] == 10*WORD + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 10 - - # ------------------------------------------------------------ - - res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], - 'ref', descr) - assert allocs[0] == 10*WORD + ofs + WORD - resbuf = self._resbuf(res) - assert resbuf[ofs/WORD] == 10 - - finally: - self.cpu.assembler.malloc_func_addr = saved_addr + self.cpu.assembler.make_sure_mc_exists() + self.cpu.assembler.malloc_func_addr = addr + ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] + + res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') + assert allocs[0] == 7 + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 7 + + # ------------------------------------------------------------ + + res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref') + assert allocs[0] == 7 + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 7 + + # ------------------------------------------------------------ + + TP = lltype.GcArray(lltype.Signed) + ofs = symbolic.get_field_token(TP, 'length', False)[0] + descr = self.cpu.arraydescrof(TP) + + res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], + 'ref', descr) + assert allocs[0] == 10*WORD + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 10 + + # ------------------------------------------------------------ + + res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], + 'ref', descr) + assert allocs[0] == 10*WORD + ofs + WORD + resbuf = self._resbuf(res) + assert resbuf[ofs/WORD] == 10 def test_stringitems(self): from pypy.rpython.lltypesystem.rstr import STR @@ -317,9 +313,9 @@ class TestX86OverflowMC(TestX86): - def setup_class(cls): - cls.cpu = CPU(rtyper=None, stats=FakeStats()) - cls.cpu.assembler.mc_size = 1024 + def setup_method(self, meth): + self.cpu = CPU(rtyper=None, stats=FakeStats()) + self.cpu.assembler.mc_size = 1024 def test_overflow_mc(self): ops = [] @@ -332,6 +328,7 @@ ops.append(ResOperation(rop.FINISH, [v], None, descr=BasicFailDescr())) looptoken = LoopToken() + self.cpu.assembler.make_sure_mc_exists() old_mc_mc = self.cpu.assembler.mc._mc self.cpu.compile_loop([base_v], ops, looptoken) assert self.cpu.assembler.mc._mc != old_mc_mc # overflowed Modified: pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_tlc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_tlc.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_tlc.py Mon Jan 25 15:25:48 2010 @@ -1,6 +1,5 @@ import py -py.test.skip("Widening to trash error") from pypy.jit.backend.x86.test.test_basic import Jit386Mixin from pypy.jit.metainterp.test.test_tlc import TLCTests from pypy.jit.tl import tlc @@ -10,6 +9,7 @@ # ====> ../../test/test_tlc.py def test_accumulator(self): + py.test.skip("investigate, maybe") path = py.path.local(tlc.__file__).dirpath('accumulator.tlc.src') code = path.read() res = self.exec_code(code, 20) @@ -18,6 +18,7 @@ assert res == 10 def test_fib(self): + py.test.skip("investigate, maybe") path = py.path.local(tlc.__file__).dirpath('fibo.tlc.src') code = path.read() res = self.exec_code(code, 7) Modified: pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_ztranslation.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_ztranslation.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/x86/test/test_ztranslation.py Mon Jan 25 15:25:48 2010 @@ -4,6 +4,7 @@ from pypy.jit.metainterp.jitprof import Profiler from pypy.jit.backend.x86.runner import CPU386 from pypy.jit.backend.test.support import CCompiledMixin +from pypy.jit.metainterp.policy import StopAtXPolicy class TestTranslationX86(CCompiledMixin): CPUClass = CPU386 @@ -94,3 +95,52 @@ return total * 10 res = self.meta_interp(main, [40]) assert res == main(40) + + def test_direct_assembler_call_translates(self): + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + class SomewhereElse(object): + pass + + somewhere_else = SomewhereElse() + + def change(newthing): + somewhere_else.frame.thing = newthing + + def main(codeno): + frame = Frame() + somewhere_else.frame = frame + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + elif frame.thing.val > 40: + change(Thing(13)) + nextval = 13 + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True, + policy=StopAtXPolicy(change)) + assert res == main(0) + Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/codewriter.py Mon Jan 25 15:25:48 2010 @@ -11,7 +11,7 @@ from pypy.tool.udir import udir from pypy.translator.simplify import get_funcobj, get_functype from pypy.translator.backendopt.canraise import RaiseAnalyzer -from pypy.translator.backendopt.writeanalyze import WriteAnalyzer +from pypy.translator.backendopt.writeanalyze import ReadWriteAnalyzer from pypy.jit.metainterp.typesystem import deref, arrayItem, fieldType from pypy.jit.metainterp.effectinfo import effectinfo_from_writeanalyze from pypy.jit.metainterp.effectinfo import VirtualizableAnalyzer @@ -86,12 +86,22 @@ if leave_graph is not None: todo.append(leave_graph) self.candidate_graphs = seen = set(todo) + + def callers(): + graph = top_graph + print graph + while graph in coming_from: + graph = coming_from[graph] + print '<-', graph + coming_from = {} + while todo: top_graph = todo.pop() for _, op in top_graph.iterblockops(): if op.opname not in ("direct_call", "indirect_call", "oosend"): continue kind = self.guess_call_kind(op, is_candidate) + # use callers() to view the calling chain in pdb if kind != "regular": continue for graph in self.graphs_from(op, is_candidate): @@ -100,6 +110,7 @@ assert is_candidate(graph) todo.append(graph) seen.add(graph) + coming_from[graph] = top_graph return self.candidate_graphs def graphs_from(self, op, is_candidate=None): @@ -185,7 +196,7 @@ self.portal_runner_ptr = portal_runner_ptr translator = self.rtyper.annotator.translator self.raise_analyzer = RaiseAnalyzer(translator) - self.write_analyzer = WriteAnalyzer(translator) + self.readwrite_analyzer = ReadWriteAnalyzer(translator) self.virtualizable_analyzer = VirtualizableAnalyzer(translator) def make_portal_bytecode(self, graph): @@ -326,7 +337,7 @@ # ok if consider_effects_of is not None: effectinfo = effectinfo_from_writeanalyze( - self.write_analyzer.analyze(consider_effects_of), + self.readwrite_analyzer.analyze(consider_effects_of), self.cpu, self.virtualizable_analyzer.analyze(consider_effects_of)) calldescr = self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), RESULT, effectinfo) @@ -417,7 +428,6 @@ """Generate a constant of the given value. Returns its index in the list self.positions[]. """ - if constvalue is _we_are_jitted: constvalue = True const = Const._new(constvalue, self.cpu) return self.get_position(const) @@ -496,9 +506,22 @@ linkfalse, linktrue = block.exits if linkfalse.llexitcase == True: linkfalse, linktrue = linktrue, linkfalse + vpos = self.var_position(block.exitswitch) + # + # constant-fold an exitswitch + cv = self.get_constant_value(vpos) + if cv is not None: + if cv.value: + link = linktrue + else: + link = linkfalse + self.emit(*self.insert_renaming(link)) + self.make_bytecode_block(link.target) + return + # self.emit("goto_if_not", tlabel(linkfalse), - self.var_position(block.exitswitch)) + vpos) self.minimize_variables(argument_only=True, exitswitch=False) truerenaming = self.insert_renaming(linktrue) falserenaming = self.insert_renaming(linkfalse) @@ -818,15 +841,21 @@ self.serialize_op_same_as(op) def serialize_op_int_is_true(self, op): - if isinstance(op.args[0], Constant): - if op.args[0].value is objectmodel.malloc_zero_filled: + vpos = self.var_position(op.args[0]) + cv = self.get_constant_value(vpos) + if cv is not None: + if cv.value is objectmodel.malloc_zero_filled: # always True for now warmrunnerdesc = self.codewriter.metainterp_sd.warmrunnerdesc if warmrunnerdesc is not None: assert warmrunnerdesc.gcdescr.malloc_zero_filled self.var_positions[op.result] = self.var_position(Constant(1)) return - self.emit('int_is_true', self.var_position(op.args[0])) + if cv.value is _we_are_jitted: + # always True + self.var_positions[op.result] = self.var_position(Constant(1)) + return + self.emit('int_is_true', vpos) self.register_var(op.result) serialize_op_uint_is_true = serialize_op_int_is_true @@ -1158,16 +1187,17 @@ self.var_position(op.args[3])) def serialize_op_jit_marker(self, op): - if op.args[0].value == 'jit_merge_point': - assert self.portal, "jit_merge_point in non-main graph!" - self.emit('jit_merge_point') - assert ([self.var_position(i) for i in op.args[2:]] == - range(0, 2*(len(op.args) - 2), 2)) - #for i in range(2, len(op.args)): - # arg = op.args[i] - # self._eventualy_builtin(arg) - elif op.args[0].value == 'can_enter_jit': - self.emit('can_enter_jit') + key = op.args[0].value + getattr(self, 'handle_jit_marker__%s' % key)(op) + + def handle_jit_marker__jit_merge_point(self, op): + assert self.portal, "jit_merge_point in non-main graph!" + self.emit('jit_merge_point') + assert ([self.var_position(i) for i in op.args[2:]] == + range(0, 2*(len(op.args) - 2), 2)) + + def handle_jit_marker__can_enter_jit(self, op): + self.emit('can_enter_jit') def serialize_op_direct_call(self, op): kind = self.codewriter.guess_call_kind(op) @@ -1205,21 +1235,26 @@ calldescr, non_void_args = self.codewriter.getcalldescr( op.args[0], args, op.result, consider_effects_of=op) pure = False + loopinvariant = False if op.opname == "direct_call": func = getattr(get_funcobj(op.args[0].value), '_callable', None) pure = getattr(func, "_pure_function_", False) + loopinvariant = getattr(func, "_jit_loop_invariant_", False) all_promoted_args = getattr(func, "_pure_function_with_all_promoted_args_", False) if pure and not all_promoted_args: effectinfo = calldescr.get_extra_info() assert (effectinfo is not None and - not effectinfo.promotes_virtualizables) + not effectinfo.forces_virtual_or_virtualizable) try: canraise = self.codewriter.raise_analyzer.can_raise(op) except lltype.DelayedPointer: canraise = True # if we need to look into the delayed ptr that is # the portal, then it's certainly going to raise - if pure: + if loopinvariant: + self.emit("residual_call_loopinvariant") + assert not non_void_args, "arguments not supported for loop-invariant function!" + elif pure: # XXX check what to do about exceptions (also MemoryError?) self.emit('residual_call_pure') elif canraise: @@ -1279,6 +1314,9 @@ return self._do_builtin_call(op, oopspec_name, args) def _do_builtin_call(self, op, oopspec_name, args): + if oopspec_name.startswith('virtual_ref'): + self.handle_virtual_ref_call(op, oopspec_name, args) + return argtypes = [v.concretetype for v in args] resulttype = op.result.concretetype c_func, TP = support.builtin_func_for_spec(self.codewriter.rtyper, @@ -1299,6 +1337,15 @@ self.emit_varargs([c_func] + non_void_args) self.register_var(op.result) + def handle_virtual_ref_call(self, op, oopspec_name, args): + self.emit(oopspec_name) # 'virtual_ref' or 'virtual_ref_finish' + self.emit(self.var_position(args[0])) + self.register_var(op.result) + # + vrefinfo = self.codewriter.metainterp_sd.virtualref_info + self.codewriter.register_known_gctype(vrefinfo.jit_virtual_ref_vtable, + vrefinfo.JIT_VIRTUAL_REF) + def _array_of_voids(self, ARRAY): if isinstance(ARRAY, ootype.Array): return ARRAY.ITEM == ootype.Void @@ -1557,12 +1604,15 @@ log.WARNING("found debug_assert in %r; should have be removed" % (self.graph,)) - def serialize_op_promote_virtualizable(self, op): + def serialize_op_jit_force_virtualizable(self, op): vinfo = self.codewriter.metainterp_sd.virtualizable_info assert vinfo is not None assert vinfo.is_vtypeptr(op.args[0].concretetype) self.vable_flags[op.args[0]] = op.args[2].value + def serialize_op_jit_force_virtual(self, op): + self._do_builtin_call(op, 'jit_force_virtual', op.args) + serialize_op_oostring = handle_builtin_call serialize_op_oounicode = handle_builtin_call serialize_op_gc_identityhash = handle_builtin_call @@ -1596,6 +1646,14 @@ raise VirtualizableArrayField(self.graph) raise + def get_constant_value(self, vpos): + """Reverse of var_position(). Returns either None or a Constant.""" + if vpos & 1: + value = self.constants[vpos // 2].value + return Constant(value) + else: + return None + def emit(self, *stuff): self.assembler.extend(stuff) Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/compile.py Mon Jan 25 15:25:48 2010 @@ -54,9 +54,11 @@ for box in loop.inputargs: assert isinstance(box, Box) if start > 0: - loop.operations = history.operations[start:] + ops = history.operations[start:] else: - loop.operations = history.operations + ops = history.operations + # make a copy, because optimize_loop can mutate the ops and descrs + loop.operations = [op.clone() for op in ops] metainterp_sd = metainterp.staticdata loop_token = make_loop_token(len(loop.inputargs)) loop.token = loop_token @@ -203,10 +205,18 @@ class ResumeDescr(AbstractFailDescr): def __init__(self, original_greenkey): self.original_greenkey = original_greenkey + def _clone_if_mutable(self): + raise NotImplementedError class ResumeGuardDescr(ResumeDescr): counter = 0 - # this class also gets attributes stored by resume.py code + # this class also gets the following attributes stored by resume.py code + rd_snapshot = None + rd_frame_info_list = None + rd_numb = None + rd_consts = None + rd_virtuals = None + rd_pendingfields = None def __init__(self, metainterp_sd, original_greenkey): ResumeDescr.__init__(self, original_greenkey) @@ -231,29 +241,67 @@ new_loop.operations) + def _clone_if_mutable(self): + res = self.__class__(self.metainterp_sd, self.original_greenkey) + # XXX a bit ugly to have to list them all here + res.rd_snapshot = self.rd_snapshot + res.rd_frame_info_list = self.rd_frame_info_list + res.rd_numb = self.rd_numb + res.rd_consts = self.rd_consts + res.rd_virtuals = self.rd_virtuals + res.rd_pendingfields = self.rd_pendingfields + return res + class ResumeGuardForcedDescr(ResumeGuardDescr): def handle_fail(self, metainterp_sd): from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) token = metainterp_sd.cpu.get_latest_force_token() - data = self.fetch_data(token) - if data is None: - data = [] - metainterp._already_allocated_resume_virtuals = data + all_virtuals = self.fetch_data(token) + if all_virtuals is None: + all_virtuals = [] + metainterp._already_allocated_resume_virtuals = all_virtuals self.counter = -2 # never compile return metainterp.handle_guard_failure(self) - def force_virtualizable(self, vinfo, virtualizable, force_token): + @staticmethod + def force_now(cpu, token): + # Called during a residual call from the assembler, if the code + # actually needs to force one of the virtualrefs or the virtualizable. + # Implemented by forcing *all* virtualrefs and the virtualizable. + faildescr = cpu.force(token) + assert isinstance(faildescr, ResumeGuardForcedDescr) + faildescr.handle_async_forcing(token) + + def handle_async_forcing(self, force_token): from pypy.jit.metainterp.pyjitpl import MetaInterp from pypy.jit.metainterp.resume import force_from_resumedata - metainterp = MetaInterp(self.metainterp_sd) + # To handle the forcing itself, we create a temporary MetaInterp + # as a convenience to move the various data to its proper place. + metainterp_sd = self.metainterp_sd + metainterp = MetaInterp(metainterp_sd) metainterp.history = None # blackholing - liveboxes = metainterp.cpu.make_boxes_from_latest_values(self) - virtualizable_boxes, data = force_from_resumedata(metainterp, - liveboxes, self) - vinfo.write_boxes(virtualizable, virtualizable_boxes) - self.save_data(force_token, data) + liveboxes = metainterp_sd.cpu.make_boxes_from_latest_values(self) + # + expect_virtualizable = metainterp_sd.virtualizable_info is not None + forced_data = force_from_resumedata(metainterp, liveboxes, self, + expect_virtualizable) + virtualizable_boxes, virtualref_boxes, all_virtuals = forced_data + # + # Handle virtualref_boxes: mark each JIT_VIRTUAL_REF as forced + vrefinfo = metainterp_sd.virtualref_info + for i in range(0, len(virtualref_boxes), 2): + virtualbox = virtualref_boxes[i] + vrefbox = virtualref_boxes[i+1] + vrefinfo.forced_single_vref(vrefbox.getref_base(), + virtualbox.getref_base()) + # Handle virtualizable_boxes: store them on the real virtualizable now + if expect_virtualizable: + metainterp_sd.virtualizable_info.forced_vable(virtualizable_boxes) + # Handle all_virtuals: keep them for later blackholing from the + # future failure of the GUARD_NOT_FORCED + self.save_data(force_token, all_virtuals) def save_data(self, key, value): globaldata = self.metainterp_sd.globaldata @@ -309,13 +357,16 @@ # it does not work -- i.e. none of the existing old_loop_tokens match. new_loop = create_empty_loop(metainterp) new_loop.inputargs = metainterp.history.inputargs - new_loop.operations = metainterp.history.operations + # clone ops, as optimize_bridge can mutate the ops + new_loop.operations = [op.clone() for op in metainterp.history.operations] metainterp_sd = metainterp.staticdata try: target_loop_token = metainterp_sd.state.optimize_bridge(metainterp_sd, old_loop_tokens, new_loop) except InvalidLoop: + # XXX I am fairly convinced that optimize_bridge cannot actually raise + # InvalidLoop return None # Did it work? if target_loop_token is not None: Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/effectinfo.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/effectinfo.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/effectinfo.py Mon Jan 25 15:25:48 2010 @@ -7,44 +7,62 @@ class EffectInfo(object): _cache = {} - def __new__(cls, write_descrs_fields, write_descrs_arrays, - promotes_virtualizables=False): - key = (frozenset(write_descrs_fields), frozenset(write_descrs_arrays), - promotes_virtualizables) + def __new__(cls, readonly_descrs_fields, + write_descrs_fields, write_descrs_arrays, + forces_virtual_or_virtualizable=False): + key = (frozenset(readonly_descrs_fields), + frozenset(write_descrs_fields), + frozenset(write_descrs_arrays), + forces_virtual_or_virtualizable) if key in cls._cache: return cls._cache[key] result = object.__new__(cls) + result.readonly_descrs_fields = readonly_descrs_fields result.write_descrs_fields = write_descrs_fields result.write_descrs_arrays = write_descrs_arrays - result.promotes_virtualizables = promotes_virtualizables + result.forces_virtual_or_virtualizable= forces_virtual_or_virtualizable cls._cache[key] = result return result -def effectinfo_from_writeanalyze(effects, cpu, promotes_virtualizables=False): +def effectinfo_from_writeanalyze(effects, cpu, + forces_virtual_or_virtualizable=False): from pypy.translator.backendopt.writeanalyze import top_set if effects is top_set: return None + readonly_descrs_fields = [] + # readonly_descrs_arrays = [] --- not enabled for now write_descrs_fields = [] write_descrs_arrays = [] + + def add_struct(descrs_fields, (_, T, fieldname)): + T = deref(T) + if consider_struct(T, fieldname): + descr = cpu.fielddescrof(T, fieldname) + descrs_fields.append(descr) + + def add_array(descrs_arrays, (_, T)): + ARRAY = deref(T) + if consider_array(ARRAY): + descr = cpu.arraydescrof(ARRAY) + descrs_arrays.append(descr) + for tup in effects: if tup[0] == "struct": - _, T, fieldname = tup - T = deref(T) - if not consider_struct(T, fieldname): - continue - descr = cpu.fielddescrof(T, fieldname) - write_descrs_fields.append(descr) + add_struct(write_descrs_fields, tup) + elif tup[0] == "readstruct": + tupw = ("struct",) + tup[1:] + if tupw not in effects: + add_struct(readonly_descrs_fields, tup) elif tup[0] == "array": - _, T = tup - ARRAY = deref(T) - if not consider_array(ARRAY): - continue - descr = cpu.arraydescrof(ARRAY) - write_descrs_arrays.append(descr) + add_array(write_descrs_arrays, tup) + elif tup[0] == "readarray": + pass else: assert 0 - return EffectInfo(write_descrs_fields, write_descrs_arrays, - promotes_virtualizables) + return EffectInfo(readonly_descrs_fields, + write_descrs_fields, + write_descrs_arrays, + forces_virtual_or_virtualizable) def consider_struct(TYPE, fieldname): if fieldType(TYPE, fieldname) is lltype.Void: @@ -73,4 +91,5 @@ class VirtualizableAnalyzer(BoolGraphAnalyzer): def analyze_simple_operation(self, op): - return op.opname == 'promote_virtualizable' + return op.opname in ('jit_force_virtualizable', + 'jit_force_virtual') Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/executor.py Mon Jan 25 15:25:48 2010 @@ -6,7 +6,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.rarithmetic import ovfcheck, r_uint, intmask -from pypy.jit.metainterp.history import BoxInt, ConstInt, check_descr +from pypy.jit.metainterp.history import BoxInt, BoxPtr, ConstInt, check_descr from pypy.jit.metainterp.history import INT, REF, ConstFloat from pypy.jit.metainterp import resoperation from pypy.jit.metainterp.resoperation import rop @@ -220,6 +220,15 @@ # ____________________________________________________________ +def do_force_token(cpu): + raise NotImplementedError + +def do_virtual_ref(cpu, box1, box2): + raise NotImplementedError + +def do_virtual_ref_finish(cpu, box1, box2): + raise NotImplementedError + def do_debug_merge_point(cpu, box1): from pypy.jit.metainterp.warmspot import get_stats loc = box1._get_str() Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/history.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/history.py Mon Jan 25 15:25:48 2010 @@ -122,6 +122,9 @@ def repr_of_descr(self): return '%r' % (self,) + def _clone_if_mutable(self): + return self + class AbstractFailDescr(AbstractDescr): index = -1 @@ -802,15 +805,30 @@ class History(object): - def __init__(self, cpu): - self.cpu = cpu + def __init__(self): self.inputargs = None self.operations = [] + def record(self, opnum, argboxes, resbox, descr=None): op = ResOperation(opnum, argboxes, resbox, descr) self.operations.append(op) return op + def substitute_operation(self, position, opnum, argboxes, descr=None): + resbox = self.operations[position].result + op = ResOperation(opnum, argboxes, resbox, descr) + self.operations[position] = op + + def slice_history_at(self, position): + """ a strange function that does this: + history : operation_at_position : rest + it'll kill operation_at_position, store everything before that + in history.operations and return rest + """ + rest = self.operations[position + 1:] + del self.operations[position:] + return rest + # ____________________________________________________________ @@ -926,10 +944,6 @@ loops.append(loop) display_loops(loops, errmsg, extraloops) - -class CrashInJIT(Exception): - pass - # ---------------------------------------------------------------- class Options: Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/jitprof.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/jitprof.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/jitprof.py Mon Jan 25 15:25:48 2010 @@ -20,6 +20,7 @@ OPT_FORCINGS ABORT_TOO_LONG ABORT_BRIDGE +ABORT_ESCAPE NVIRTUALS NVHOLES NVREUSED @@ -176,8 +177,9 @@ self._print_intline("opt ops", cnt[OPT_OPS]) self._print_intline("opt guards", cnt[OPT_GUARDS]) self._print_intline("forcings", cnt[OPT_FORCINGS]) - self._print_intline("trace too long", cnt[ABORT_TOO_LONG]) - self._print_intline("bridge abort", cnt[ABORT_BRIDGE]) + self._print_intline("abort: trace too long", cnt[ABORT_TOO_LONG]) + self._print_intline("abort: compiling", cnt[ABORT_BRIDGE]) + self._print_intline("abort: vable escape", cnt[ABORT_ESCAPE]) self._print_intline("nvirtuals", cnt[NVIRTUALS]) self._print_intline("nvholes", cnt[NVHOLES]) self._print_intline("nvreused", cnt[NVREUSED]) Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/optimizeopt.py Mon Jan 25 15:25:48 2010 @@ -11,7 +11,7 @@ from pypy.jit.metainterp.specnode import VirtualStructSpecNode from pypy.jit.metainterp.optimizeutil import _findall, sort_descrs from pypy.jit.metainterp.optimizeutil import descrlist_dict -from pypy.jit.metainterp.optimizeutil import InvalidLoop +from pypy.jit.metainterp.optimizeutil import InvalidLoop, args_dict from pypy.jit.metainterp import resume, compile from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.rlib.objectmodel import we_are_translated @@ -161,18 +161,18 @@ return self.box def make_virtual_info(self, modifier, fieldnums): - vinfo = self._cached_vinfo - if vinfo is not None and resume.tagged_list_eq( - vinfo.fieldnums, fieldnums): + vinfo = self._cached_vinfo + if vinfo is not None and vinfo.equals(fieldnums): return vinfo vinfo = self._make_virtual(modifier) - vinfo.fieldnums = fieldnums + vinfo.set_content(fieldnums) self._cached_vinfo = vinfo return vinfo def _make_virtual(self, modifier): raise NotImplementedError("abstract base") + def get_fielddescrlist_cache(cpu): if not hasattr(cpu, '_optimizeopt_fielddescrlist_cache'): result = descrlist_dict() @@ -207,6 +207,8 @@ iteritems = list(iteritems) iteritems.sort(key = lambda (x,y): x.sort_key()) for ofs, value in iteritems: + if value.is_null(): + continue subbox = value.force_box() op = ResOperation(rop.SETFIELD_GC, [box, subbox], None, descr=ofs) @@ -234,7 +236,6 @@ def get_args_for_fail(self, modifier): if self.box is None and not modifier.already_seen_virtual(self.keybox): - # modifier.already_seen_virtual() # checks for recursion: it is False unless # we have already seen the very same keybox lst = self._get_field_descr_list() @@ -294,6 +295,8 @@ for index in range(len(self._items)): subvalue = self._items[index] if subvalue is not self.constvalue: + if subvalue.is_null(): + continue subbox = subvalue.force_box() op = ResOperation(rop.SETARRAYITEM_GC, [box, ConstInt(index), subbox], None, @@ -302,11 +305,9 @@ def get_args_for_fail(self, modifier): if self.box is None and not modifier.already_seen_virtual(self.keybox): - # modifier.already_seen_virtual() # checks for recursion: it is False unless # we have already seen the very same keybox itemboxes = [] - const = self.optimizer.new_const_item(self.arraydescr) for itemvalue in self._items: itemboxes.append(itemvalue.get_key_box()) modifier.register_virtual_fields(self.keybox, itemboxes) @@ -387,6 +388,8 @@ self.resumedata_memo = resume.ResumeDataLoopMemo(metainterp_sd) self.heap_op_optimizer = HeapOpOptimizer(self) self.bool_boxes = {} + self.loop_invariant_results = {} + self.pure_operations = args_dict() def forget_numberings(self, virtualbox): self.metainterp_sd.profiler.count(jitprof.OPT_FORCINGS) @@ -513,17 +516,16 @@ # accumulate counters self.resumedata_memo.update_counters(self.metainterp_sd.profiler) - def emit_operation(self, op, must_clone=True): + def emit_operation(self, op): self.heap_op_optimizer.emitting_operation(op) + self._emit_operation(op) + + def _emit_operation(self, op): for i in range(len(op.args)): arg = op.args[i] if arg in self.values: box = self.values[arg].force_box() - if box is not arg: - if must_clone: - op = op.clone() - must_clone = False - op.args[i] = box + op.args[i] = box self.metainterp_sd.profiler.count(jitprof.OPT_OPS) if op.is_guard(): self.metainterp_sd.profiler.count(jitprof.OPT_GUARDS) @@ -535,10 +537,11 @@ self.newoperations.append(op) def store_final_boxes_in_guard(self, op): + pendingfields = self.heap_op_optimizer.force_lazy_setfields_for_guard() descr = op.descr assert isinstance(descr, compile.ResumeGuardDescr) modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo) - newboxes = modifier.finish(self.values) + newboxes = modifier.finish(self.values, pendingfields) if len(newboxes) > self.metainterp_sd.options.failargs_limit: # XXX be careful here raise compile.GiveUp descr.store_final_boxes(op, newboxes) @@ -569,6 +572,23 @@ resbox = execute_nonspec(self.cpu, op.opnum, argboxes, op.descr) self.make_constant(op.result, resbox.constbox()) return + + if op.descr is None: + # did we do the exact same operation already? + args = op.args[:] + for i in range(len(args)): + arg = args[i] + if arg in self.values: + args[i] = self.values[arg].get_key_box() + args.append(ConstInt(op.opnum)) + oldop = self.pure_operations.get(args, None) + if oldop is not None: + assert oldop.opnum == op.opnum + self.make_equal_to(op.result, self.getvalue(oldop.result)) + return + else: + self.pure_operations[args] = op + # otherwise, the operation remains self.emit_operation(op) @@ -582,9 +602,8 @@ for i in range(len(specnodes)): value = self.getvalue(op.args[i]) specnodes[i].teardown_virtual_node(self, value, exitargs) - op2 = op.clone() - op2.args = exitargs[:] - self.emit_operation(op2, must_clone=False) + op.args = exitargs[:] + self.emit_operation(op) def optimize_guard(self, op, constbox, emit_operation=True): value = self.getvalue(op.args[0]) @@ -699,7 +718,7 @@ elif value.is_null(): self.make_constant_int(op.result, not expect_nonnull) else: - self.emit_operation(op) + self.optimize_default(op) def optimize_INT_IS_TRUE(self, op): self._optimize_nullness(op, op.args[0], True) @@ -736,6 +755,49 @@ def optimize_OOIS(self, op): self._optimize_oois_ooisnot(op, False) + def optimize_VIRTUAL_REF(self, op): + indexbox = op.args[1] + # + # get some constants + vrefinfo = self.metainterp_sd.virtualref_info + c_cls = vrefinfo.jit_virtual_ref_const_class + descr_virtual_token = vrefinfo.descr_virtual_token + descr_virtualref_index = vrefinfo.descr_virtualref_index + # + # Replace the VIRTUAL_REF operation with a virtual structure of type + # 'jit_virtual_ref'. The jit_virtual_ref structure may be forced soon, + # but the point is that doing so does not force the original structure. + op = ResOperation(rop.NEW_WITH_VTABLE, [c_cls], op.result) + vrefvalue = self.make_virtual(c_cls, op.result, op) + tokenbox = BoxInt() + self.emit_operation(ResOperation(rop.FORCE_TOKEN, [], tokenbox)) + vrefvalue.setfield(descr_virtual_token, self.getvalue(tokenbox)) + vrefvalue.setfield(descr_virtualref_index, self.getvalue(indexbox)) + + def optimize_VIRTUAL_REF_FINISH(self, op): + # Set the 'forced' field of the virtual_ref. + # In good cases, this is all virtual, so has no effect. + # Otherwise, this forces the real object -- but only now, as + # opposed to much earlier. This is important because the object is + # typically a PyPy PyFrame, and now is the end of its execution, so + # forcing it now does not have catastrophic effects. + vrefinfo = self.metainterp_sd.virtualref_info + # - set 'forced' to point to the real object + op1 = ResOperation(rop.SETFIELD_GC, op.args, None, + descr = vrefinfo.descr_forced) + self.optimize_SETFIELD_GC(op1) + # - set 'virtual_token' to TOKEN_NONE + args = [op.args[0], ConstInt(0)] + op1 = ResOperation(rop.SETFIELD_GC, args, None, + descr = vrefinfo.descr_virtual_token) + self.optimize_SETFIELD_GC(op1) + # Note that in some cases the virtual in op.args[1] has been forced + # already. This is fine. In that case, and *if* a residual + # CALL_MAY_FORCE suddenly turns out to access it, then it will + # trigger a ResumeGuardForcedDescr.handle_async_forcing() which + # will work too (but just be a little pointless, as the structure + # was already forced). + def optimize_GETFIELD_GC(self, op): value = self.getvalue(op.args[0]) if value.is_virtual(): @@ -753,11 +815,11 @@ def optimize_SETFIELD_GC(self, op): value = self.getvalue(op.args[0]) + fieldvalue = self.getvalue(op.args[1]) if value.is_virtual(): - value.setfield(op.descr, self.getvalue(op.args[1])) + value.setfield(op.descr, fieldvalue) else: value.ensure_nonnull() - fieldvalue = self.getvalue(op.args[1]) self.heap_op_optimizer.optimize_SETFIELD_GC(op, value, fieldvalue) def optimize_NEW_WITH_VTABLE(self, op): @@ -826,6 +888,23 @@ def optimize_DEBUG_MERGE_POINT(self, op): self.emit_operation(op) + def optimize_CALL_LOOPINVARIANT(self, op): + funcvalue = self.getvalue(op.args[0]) + if not funcvalue.is_constant(): + self.optimize_default(op) + return + resvalue = self.loop_invariant_results.get(op.args[0].getint(), None) + if resvalue is not None: + self.make_equal_to(op.result, resvalue) + return + # change the op to be a normal call, from the backend's point of view + # there is no reason to have a separate operation for this + op.opnum = rop.CALL + self.optimize_default(op) + resvalue = self.getvalue(op.result) + self.loop_invariant_results[op.args[0].getint()] = resvalue + + optimize_ops = _findall(Optimizer, 'optimize_') @@ -839,11 +918,13 @@ class HeapOpOptimizer(object): def __init__(self, optimizer): self.optimizer = optimizer - # cached OptValues for each field descr + # cached fields: {descr: {OptValue_instance: OptValue_fieldvalue}} self.cached_fields = {} - - # cached OptValues for each field descr + # cached array items: {descr: CachedArrayItems} self.cached_arrayitems = {} + # lazily written setfields (at most one per descr): {descr: op} + self.lazy_setfields = {} + self.lazy_setfields_descrs = [] # keys (at least) of previous dict def clean_caches(self): self.cached_fields.clear() @@ -851,15 +932,23 @@ def cache_field_value(self, descr, value, fieldvalue, write=False): if write: + # when seeing a setfield, we have to clear the cache for the same + # field on any other structure, just in case they are aliasing + # each other d = self.cached_fields[descr] = {} else: d = self.cached_fields.setdefault(descr, {}) d[value] = fieldvalue def read_cached_field(self, descr, value): + # XXX self.cached_fields and self.lazy_setfields should probably + # be merged somehow d = self.cached_fields.get(descr, None) if d is None: - return None + op = self.lazy_setfields.get(descr, None) + if op is None: + return None + return self.optimizer.getvalue(op.args[1]) return d.get(value, None) def cache_arrayitem_value(self, descr, value, indexvalue, fieldvalue, write=False): @@ -908,8 +997,6 @@ return None def emitting_operation(self, op): - if op.is_always_pure(): - return if op.has_no_side_effect(): return if op.is_ovf(): @@ -921,10 +1008,20 @@ opnum == rop.SETARRAYITEM_GC or opnum == rop.DEBUG_MERGE_POINT): return - if opnum == rop.CALL: - effectinfo = op.descr.get_extra_info() + if (opnum == rop.CALL or + opnum == rop.CALL_MAY_FORCE or + opnum == rop.CALL_ASSEMBLER): + if opnum == rop.CALL_ASSEMBLER: + effectinfo = None + else: + effectinfo = op.descr.get_extra_info() if effectinfo is not None: + # XXX we can get the wrong complexity here, if the lists + # XXX stored on effectinfo are large + for fielddescr in effectinfo.readonly_descrs_fields: + self.force_lazy_setfield(fielddescr) for fielddescr in effectinfo.write_descrs_fields: + self.force_lazy_setfield(fielddescr) try: del self.cached_fields[fielddescr] except KeyError: @@ -935,9 +1032,73 @@ except KeyError: pass return + self.force_all_lazy_setfields() + elif op.is_final() or (not we_are_translated() and + op.opnum < 0): # escape() operations + self.force_all_lazy_setfields() self.clean_caches() + def force_lazy_setfield(self, descr, before_guard=False): + try: + op = self.lazy_setfields[descr] + except KeyError: + return + del self.lazy_setfields[descr] + self.optimizer._emit_operation(op) + # + # hackish: reverse the order of the last two operations if it makes + # sense to avoid a situation like "int_eq/setfield_gc/guard_true", + # which the backend (at least the x86 backend) does not handle well. + newoperations = self.optimizer.newoperations + if before_guard and len(newoperations) >= 2: + lastop = newoperations[-1] + prevop = newoperations[-2] + # - is_comparison() for cases like "int_eq/setfield_gc/guard_true" + # - CALL_MAY_FORCE: "call_may_force/setfield_gc/guard_not_forced" + if ((prevop.is_comparison() or prevop.opnum == rop.CALL_MAY_FORCE) + and prevop.result not in lastop.args): + newoperations[-2] = lastop + newoperations[-1] = prevop + + def force_all_lazy_setfields(self): + if len(self.lazy_setfields_descrs) > 0: + for descr in self.lazy_setfields_descrs: + self.force_lazy_setfield(descr) + del self.lazy_setfields_descrs[:] + + def force_lazy_setfields_for_guard(self): + pendingfields = [] + for descr in self.lazy_setfields_descrs: + try: + op = self.lazy_setfields[descr] + except KeyError: + continue + # the only really interesting case that we need to handle in the + # guards' resume data is that of a virtual object that is stored + # into a field of a non-virtual object. + value = self.optimizer.getvalue(op.args[0]) + assert not value.is_virtual() # it must be a non-virtual + fieldvalue = self.optimizer.getvalue(op.args[1]) + if fieldvalue.is_virtual(): + # this is the case that we leave to resume.py + pendingfields.append((descr, value.box, + fieldvalue.get_key_box())) + else: + self.force_lazy_setfield(descr, before_guard=True) + return pendingfields + + def force_lazy_setfield_if_necessary(self, op, value, write=False): + try: + op1 = self.lazy_setfields[op.descr] + except KeyError: + if write: + self.lazy_setfields_descrs.append(op.descr) + else: + if self.optimizer.getvalue(op1.args[0]) is not value: + self.force_lazy_setfield(op.descr) + def optimize_GETFIELD_GC(self, op, value): + self.force_lazy_setfield_if_necessary(op, value) # check if the field was read from another getfield_gc just before # or has been written to recently fieldvalue = self.read_cached_field(op.descr, value) @@ -952,7 +1113,8 @@ self.cache_field_value(op.descr, value, fieldvalue) def optimize_SETFIELD_GC(self, op, value, fieldvalue): - self.optimizer.emit_operation(op) + self.force_lazy_setfield_if_necessary(op, value, write=True) + self.lazy_setfields[op.descr] = op # remember the result of future reads of the field self.cache_field_value(op.descr, value, fieldvalue, write=True) Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/optimizeutil.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/optimizeutil.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/optimizeutil.py Mon Jan 25 15:25:48 2010 @@ -1,7 +1,7 @@ from pypy.rlib.objectmodel import r_dict, compute_identity_hash from pypy.rlib.rarithmetic import intmask from pypy.rlib.unroll import unrolling_iterable -from pypy.jit.metainterp import resoperation +from pypy.jit.metainterp import resoperation, history class InvalidLoop(Exception): """Raised when the optimize*.py detect that the loop that @@ -59,3 +59,35 @@ def descrlist_dict(): return r_dict(descrlist_eq, descrlist_hash) +# ____________________________________________________________ + +def args_eq(args1, args2): + if len(args1) != len(args2): + return False + for i in range(len(args1)): + arg1 = args1[i] + arg2 = args2[i] + if isinstance(arg1, history.Const): + if arg1.__class__ is not arg2.__class__: + return False + if not arg1.same_constant(arg2): + return False + else: + if not arg1 is arg2: + return False + return True + +def args_hash(args): + res = 0x345678 + for arg in args: + if isinstance(arg, history.Const): + y = arg._get_hash_() + else: + y = compute_identity_hash(arg) + res = intmask((1000003 * res) ^ y) + return res + +def args_dict(): + return r_dict(args_eq, args_hash) + + Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/policy.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/policy.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/policy.py Mon Jan 25 15:25:48 2010 @@ -49,8 +49,6 @@ def look_inside_graph(self, graph): from pypy.translator.backendopt.support import find_backedges contains_loop = bool(find_backedges(graph)) - unsupported = contains_unsupported_variable_type(graph, - self.supports_floats) try: func = graph.func except AttributeError: @@ -61,7 +59,8 @@ contains_loop = contains_loop and not getattr( func, '_jit_unroll_safe_', False) - res = see_function and not unsupported + res = see_function and not contains_unsupported_variable_type(graph, + self.supports_floats) if res and contains_loop: self.unsafe_loopy_graphs.add(graph) return res and not contains_loop Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/pyjitpl.py Mon Jan 25 15:25:48 2010 @@ -11,7 +11,7 @@ from pypy.jit.metainterp import codewriter, executor from pypy.jit.metainterp.logger import Logger from pypy.jit.metainterp.jitprof import BLACKHOLED_OPS, EmptyProfiler -from pypy.jit.metainterp.jitprof import GUARDS, RECORDED_OPS +from pypy.jit.metainterp.jitprof import GUARDS, RECORDED_OPS, ABORT_ESCAPE from pypy.jit.metainterp.jitprof import ABORT_TOO_LONG, ABORT_BRIDGE from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import specialize @@ -42,16 +42,10 @@ argtypes = unrolling_iterable(self.argtypes) def wrapped(self, orgpc): args = (self, ) - #if DEBUG >= DEBUG_DETAILED: - # s = '%s:%d\t%s' % (self.jitcode.name, orgpc, name) - #else: - s = '' for argspec in argtypes: if argspec == "box": box = self.load_arg() args += (box, ) - #if DEBUG >= DEBUG_DETAILED: - # s += '\t' + box.repr_rpython() elif argspec == "constbox": args += (self.load_const_arg(), ) elif argspec == "int": @@ -82,12 +76,7 @@ args += (methdescr, ) else: assert 0, "unknown argtype declaration: %r" % (argspec,) - #if DEBUG >= DEBUG_DETAILED: - # debug_print(s) val = func(*args) - #if DEBUG >= DEBUG_DETAILED: - # reprboxes = ' '.join([box.repr_rpython() for box in self.env]) - # debug_print(' \x1b[34menv=[%s]\x1b[0m' % (reprboxes,)) if val is None: val = False return val @@ -654,6 +643,10 @@ def opimpl_residual_call(self, calldescr, varargs): return self.do_residual_call(varargs, descr=calldescr, exc=True) + @arguments("descr", "varargs") + def opimpl_residual_call_loopinvariant(self, calldescr, varargs): + return self.execute_varargs(rop.CALL_LOOPINVARIANT, varargs, calldescr, exc=True) + @arguments("varargs") def opimpl_recursion_leave_prep(self, varargs): warmrunnerstate = self.metainterp.staticdata.state @@ -667,16 +660,40 @@ return False return self.perform_call(leave_code, varargs) - @arguments("descr", "varargs") - def opimpl_recursive_call(self, calldescr, varargs): + @arguments("orgpc", "descr", "varargs") + def opimpl_recursive_call(self, pc, calldescr, varargs): warmrunnerstate = self.metainterp.staticdata.state - if warmrunnerstate.inlining: + token = None + if not self.metainterp.is_blackholing() and warmrunnerstate.inlining: num_green_args = self.metainterp.staticdata.num_green_args portal_code = self.metainterp.staticdata.portal_code greenkey = varargs[1:num_green_args + 1] if warmrunnerstate.can_inline_callable(greenkey): return self.perform_call(portal_code, varargs[1:], greenkey) - return self.do_residual_call(varargs, descr=calldescr, exc=True) + token = warmrunnerstate.get_assembler_token(greenkey) + call_position = 0 + if token is not None: + call_position = len(self.metainterp.history.operations) + # guard value for all green args, needed to make sure + # that assembler that we call is still correct + greenargs = varargs[1:num_green_args + 1] + self.generate_guard_value_for_green_args(pc, greenargs) + res = self.do_residual_call(varargs, descr=calldescr, exc=True) + if not self.metainterp.is_blackholing() and token is not None: + # XXX fix the call position, + found = False + while True: + op = self.metainterp.history.operations[call_position] + if op.opnum == rop.CALL or op.opnum == rop.CALL_MAY_FORCE: + found = True + break + call_position += 1 + assert found + # + # this will substitute the residual call with assembler call + self.metainterp.direct_assembler_call(pc, varargs, token, + call_position) + return res @arguments("descr", "varargs") def opimpl_residual_call_noexception(self, calldescr, varargs): @@ -786,7 +803,7 @@ def opimpl_keepalive(self, box): pass # xxx? - def generate_merge_point(self, pc, varargs): + def generate_guard_value_for_green_args(self, pc, varargs): num_green_args = self.metainterp.staticdata.num_green_args for i in range(num_green_args): varargs[i] = self.implement_guard_value(pc, varargs[i]) @@ -826,7 +843,7 @@ @arguments("orgpc") def opimpl_jit_merge_point(self, pc): if not self.metainterp.is_blackholing(): - self.generate_merge_point(pc, self.env) + self.generate_guard_value_for_green_args(pc, self.env) # xxx we may disable the following line in some context later self.debug_merge_point() if self.metainterp.seen_can_enter_jit: @@ -834,8 +851,7 @@ try: self.metainterp.reached_can_enter_jit(self.env) except GiveUp: - self.metainterp.staticdata.profiler.count(ABORT_BRIDGE) - self.metainterp.switch_to_blackhole() + self.metainterp.switch_to_blackhole(ABORT_BRIDGE) if self.metainterp.is_blackholing(): self.blackhole_reached_merge_point(self.env) return True @@ -846,6 +862,7 @@ greenkey = self.env[:num_green_args] sd = self.metainterp.staticdata loc = sd.state.get_location_str(greenkey) + debug_print(loc) constloc = self.metainterp.cpu.ts.conststr(loc) self.metainterp.history.record(rop.DEBUG_MERGE_POINT, [constloc], None) @@ -858,9 +875,13 @@ def opimpl_teardown_exception_block(self): self.exception_target = -1 - @arguments("constbox", "jumptarget") - def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target): - assert isinstance(self.exception_box, Const) # XXX + @arguments("constbox", "jumptarget", "orgpc") + def opimpl_goto_if_exception_mismatch(self, vtableref, next_exc_target, pc): + # XXX used to be: + # assert isinstance(self.exception_box, Const) # XXX + # seems this can happen that self.exception_box is not a Const, + # but I failed to write a test so far :-( + self.exception_box = self.implement_guard_value(pc, self.exception_box) cpu = self.metainterp.cpu ts = self.metainterp.cpu.ts if not ts.subclassOf(cpu, self.exception_box, vtableref): @@ -886,6 +907,55 @@ return self.metainterp.finishframe_exception(self.exception_box, self.exc_value_box) + @arguments("box") + def opimpl_virtual_ref(self, box): + # Details on the content of metainterp.virtualref_boxes: + # + # * it's a list whose items go two by two, containing first the + # virtual box (e.g. the PyFrame) and then the vref box (e.g. + # the 'virtual_ref(frame)'). + # + # * if we detect that the virtual box escapes during tracing + # already (by generating a CALl_MAY_FORCE that marks the flags + # in the vref), then we replace the vref in the list with + # ConstPtr(NULL). + # + metainterp = self.metainterp + if metainterp.is_blackholing(): + resbox = box # good enough when blackholing + else: + vrefinfo = metainterp.staticdata.virtualref_info + obj = box.getref_base() + vref = vrefinfo.virtual_ref_during_tracing(obj) + resbox = history.BoxPtr(vref) + cindex = history.ConstInt(len(metainterp.virtualref_boxes) // 2) + metainterp.history.record(rop.VIRTUAL_REF, [box, cindex], resbox) + # Note: we allocate a JIT_VIRTUAL_REF here + # (in virtual_ref_during_tracing()), in order to detect when + # the virtual escapes during tracing already. We record it as a + # VIRTUAL_REF operation, although the backend sees this operation + # as a no-op. The point is that the backend should not really see + # it in practice, as optimizeopt.py should either kill it or + # replace it with a NEW_WITH_VTABLE followed by SETFIELD_GCs. + metainterp.virtualref_boxes.append(box) + metainterp.virtualref_boxes.append(resbox) + self.make_result_box(resbox) + + @arguments("box") + def opimpl_virtual_ref_finish(self, box): + # virtual_ref_finish() assumes that we have a stack-like, last-in + # first-out order. + metainterp = self.metainterp + vrefbox = metainterp.virtualref_boxes.pop() + lastbox = metainterp.virtualref_boxes.pop() + assert box.getref_base() == lastbox.getref_base() + if not metainterp.is_blackholing(): + vrefinfo = metainterp.staticdata.virtualref_info + vref = vrefbox.getref_base() + if vrefinfo.is_virtual_ref(vref): + metainterp.history.record(rop.VIRTUAL_REF_FINISH, + [vrefbox, lastbox], None) + # ------------------------------ def setup_call(self, argboxes): @@ -947,7 +1017,7 @@ if metainterp.staticdata.virtualizable_info is not None: virtualizable_boxes = metainterp.virtualizable_boxes resume.capture_resumedata(metainterp.framestack, virtualizable_boxes, - resumedescr) + metainterp.virtualref_boxes, resumedescr) self.metainterp.staticdata.profiler.count_ops(opnum, GUARDS) # count metainterp.attach_debug_info(guard_op) @@ -988,13 +1058,13 @@ def do_residual_call(self, argboxes, descr, exc): effectinfo = descr.get_extra_info() - if effectinfo is None or effectinfo.promotes_virtualizables: + if effectinfo is None or effectinfo.forces_virtual_or_virtualizable: # residual calls require attention to keep virtualizables in-sync - self.metainterp.vable_before_residual_call() + self.metainterp.vable_and_vrefs_before_residual_call() # xxx do something about code duplication resbox = self.metainterp.execute_and_record_varargs( rop.CALL_MAY_FORCE, argboxes, descr=descr) - self.metainterp.vable_after_residual_call() + self.metainterp.vable_and_vrefs_after_residual_call() if resbox is not None: self.make_result_box(resbox) self.generate_guard(self.pc, rop.GUARD_NOT_FORCED, None, []) @@ -1047,6 +1117,9 @@ self._addr2name_values = [] self.__dict__.update(compile.make_done_loop_tokens()) + # store this information for fastpath of call_assembler + d = self.loop_tokens_done_with_this_frame_int[0].finishdescr + self.cpu.done_with_this_frame_int_v = self.cpu.get_fail_descr_number(d) def _freeze_(self): return True @@ -1234,8 +1307,7 @@ try: self.compile_done_with_this_frame(resultbox) except GiveUp: - self.staticdata.profiler.count(ABORT_BRIDGE) - self.switch_to_blackhole() + self.switch_to_blackhole(ABORT_BRIDGE) sd = self.staticdata if sd.result_type == 'void': assert resultbox is None @@ -1272,8 +1344,7 @@ try: self.compile_exit_frame_with_exception(excvaluebox) except GiveUp: - self.staticdata.profiler.count(ABORT_BRIDGE) - self.switch_to_blackhole() + self.switch_to_blackhole(ABORT_BRIDGE) raise self.staticdata.ExitFrameWithExceptionRef(self.cpu, excvaluebox.getref_base()) def check_recursion_invariant(self): @@ -1308,7 +1379,7 @@ def create_empty_history(self): warmrunnerstate = self.staticdata.state - self.history = history.History(self.cpu) + self.history = history.History() self.staticdata.stats.set_history(self.history) def _all_constants(self, *boxes): @@ -1391,7 +1462,8 @@ op.pc = self.framestack[-1].pc op.name = self.framestack[-1].jitcode.name - def switch_to_blackhole(self): + def switch_to_blackhole(self, reason): + self.staticdata.profiler.count(reason) debug_print('~~~ ABORTING TRACING') debug_stop('jit-tracing') debug_start('jit-blackhole') @@ -1399,15 +1471,15 @@ self.staticdata.stats.aborted() self.staticdata.profiler.end_tracing() self.staticdata.profiler.start_blackhole() + switch_to_blackhole._dont_inline_ = True def switch_to_blackhole_if_trace_too_long(self): if not self.is_blackholing(): warmrunnerstate = self.staticdata.state if len(self.history.operations) > warmrunnerstate.trace_limit: - self.staticdata.profiler.count(ABORT_TOO_LONG) self.greenkey_of_huge_function = self.find_biggest_function() self.portal_trace_positions = None - self.switch_to_blackhole() + self.switch_to_blackhole(ABORT_TOO_LONG) def _interpret(self): # Execute the frames forward until we raise a DoneWithThisFrame, @@ -1531,6 +1603,7 @@ len(self.virtualizable_boxes)-1, duplicates) live_arg_boxes += self.virtualizable_boxes[:-1] + assert len(self.virtualref_boxes) == 0, "missing virtual_ref_finish()?" # Called whenever we reach the 'can_enter_jit' hint. # First, attempt to make a bridge: # - if self.resumekey is a ResumeGuardDescr, it starts from a guard @@ -1560,17 +1633,9 @@ # we cannot reconstruct the beginning of the proper loop raise GiveUp - oldops = self.history.operations[:] # raises in case it works -- which is the common case self.compile(original_boxes, live_arg_boxes, start) - # creation of the loop was cancelled! Patch - # history.operations so that it contains again - # exactly its old list of operations... - # xxx maybe we could patch history.operations with - # Nones after calling self.compile() instead of - # before... xxx maybe we should just raise GiveUp - del self.history.operations[:] - self.history.operations.extend(oldops) + # creation of the loop was cancelled! # Otherwise, no loop found so far, so continue tracing. start = len(self.history.operations) @@ -1608,6 +1673,7 @@ greenkey, start) if loop_token is not None: # raise if it *worked* correctly raise GenerateMergePoint(live_arg_boxes, loop_token) + self.history.operations.pop() # remove the JUMP def compile_bridge(self, live_arg_boxes): num_green_args = self.staticdata.num_green_args @@ -1686,6 +1752,7 @@ f = self.newframe(self.staticdata.portal_code) f.pc = 0 f.env = original_boxes[:] + self.virtualref_boxes = [] self.initialize_virtualizable(original_boxes) return original_boxes @@ -1694,7 +1761,7 @@ self.in_recursion = -1 # always one portal around inputargs_and_holes = self.cpu.make_boxes_from_latest_values(resumedescr) if must_compile: - self.history = history.History(self.cpu) + self.history = history.History() self.history.inputargs = [box for box in inputargs_and_holes if box] self.staticdata.profiler.start_tracing() else: @@ -1723,9 +1790,18 @@ virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box) vinfo.clear_vable_token(virtualizable) - def vable_before_residual_call(self): + def vable_and_vrefs_before_residual_call(self): if self.is_blackholing(): return + # + vrefinfo = self.staticdata.virtualref_info + for i in range(1, len(self.virtualref_boxes), 2): + vrefbox = self.virtualref_boxes[i] + vref = vrefbox.getref_base() + vrefinfo.tracing_before_residual_call(vref) + # the FORCE_TOKEN is already set at runtime in each vref when + # it is created, by optimizeopt.py. + # vinfo = self.staticdata.virtualizable_info if vinfo is not None: virtualizable_box = self.virtualizable_boxes[-1] @@ -1738,23 +1814,50 @@ force_token_box], None, descr=vinfo.vable_token_descr) - def vable_after_residual_call(self): + def vable_and_vrefs_after_residual_call(self): if self.is_blackholing(): - vable_escapes = True + escapes = True else: - vable_escapes = False + escapes = False + # + vrefinfo = self.staticdata.virtualref_info + for i in range(0, len(self.virtualref_boxes), 2): + virtualbox = self.virtualref_boxes[i] + vrefbox = self.virtualref_boxes[i+1] + vref = vrefbox.getref_base() + if vrefinfo.tracing_after_residual_call(vref): + # this vref was really a virtual_ref, but it escaped + # during this CALL_MAY_FORCE. Mark this fact by + # generating a VIRTUAL_REF_FINISH on it and replacing + # it by ConstPtr(NULL). + self.stop_tracking_virtualref(i) + # vinfo = self.staticdata.virtualizable_info if vinfo is not None: virtualizable_box = self.virtualizable_boxes[-1] virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box) if vinfo.tracing_after_residual_call(virtualizable): - # We just did the residual call, and it shows that the - # virtualizable escapes. - self.switch_to_blackhole() - vable_escapes = True - if vable_escapes: + # the virtualizable escaped during CALL_MAY_FORCE. + escapes = True + # + if escapes: + self.switch_to_blackhole(ABORT_ESCAPE) + # + if escapes: self.load_fields_from_virtualizable() + def stop_tracking_virtualref(self, i): + virtualbox = self.virtualref_boxes[i] + vrefbox = self.virtualref_boxes[i+1] + # record VIRTUAL_REF_FINISH just before the current CALL_MAY_FORCE + call_may_force_op = self.history.operations.pop() + assert call_may_force_op.opnum == rop.CALL_MAY_FORCE + self.history.record(rop.VIRTUAL_REF_FINISH, + [vrefbox, virtualbox], None) + self.history.operations.append(call_may_force_op) + # mark by replacing it with ConstPtr(NULL) + self.virtualref_boxes[i+1] = self.cpu.ts.CONST_NULL + def handle_exception(self): etype = self.cpu.get_exception() evalue = self.cpu.get_exc_value() @@ -1787,7 +1890,20 @@ vinfo = self.staticdata.virtualizable_info self.framestack = [] expect_virtualizable = vinfo is not None - virtualizable_boxes = resume.rebuild_from_resumedata(self, newboxes, resumedescr, expect_virtualizable) + virtualizable_boxes, virtualref_boxes = resume.rebuild_from_resumedata( + self, newboxes, resumedescr, expect_virtualizable) + # + # virtual refs: make the vrefs point to the freshly allocated virtuals + self.virtualref_boxes = virtualref_boxes + vrefinfo = self.staticdata.virtualref_info + for i in range(0, len(virtualref_boxes), 2): + virtualbox = virtualref_boxes[i] + vrefbox = virtualref_boxes[i+1] + vrefinfo.continue_tracing(vrefbox.getref_base(), + virtualbox.getref_base()) + # + # virtualizable: synchronize the real virtualizable and the local + # boxes, in whichever direction is appropriate if expect_virtualizable: self.virtualizable_boxes = virtualizable_boxes if self._already_allocated_resume_virtuals is not None: @@ -1796,12 +1912,19 @@ self.load_fields_from_virtualizable() return # just jumped away from assembler (case 4 in the comment in - # virtualizable.py) into tracing (case 2); check that vable_rti - # is and stays NULL. + # virtualizable.py) into tracing (case 2); check that vable_token + # is and stays 0. Note the call to reset_vable_token() in + # warmstate.py. virtualizable_box = self.virtualizable_boxes[-1] virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box) assert not virtualizable.vable_token - self.synchronize_virtualizable() + if self._already_allocated_resume_virtuals is not None: + # resuming from a ResumeGuardForcedDescr: load the new values + # currently stored on the virtualizable fields + self.load_fields_from_virtualizable() + else: + # normal case: fill the virtualizable with the local boxes + self.synchronize_virtualizable() def check_synchronized_virtualizable(self): if not we_are_translated(): @@ -1850,12 +1973,33 @@ abox, ConstInt(j), itembox) assert i + 1 == len(self.virtualizable_boxes) + def gen_load_from_other_virtualizable(self, vbox): + vinfo = self.staticdata.virtualizable_info + boxes = [] + assert vinfo is not None + for i in range(vinfo.num_static_extra_boxes): + descr = vinfo.static_field_descrs[i] + boxes.append(self.execute_and_record(rop.GETFIELD_GC, descr, vbox)) + virtualizable = vinfo.unwrap_virtualizable_box(vbox) + for k in range(vinfo.num_arrays): + descr = vinfo.array_field_descrs[k] + abox = self.execute_and_record(rop.GETFIELD_GC, descr, vbox) + descr = vinfo.array_descrs[k] + for j in range(vinfo.get_array_length(virtualizable, k)): + boxes.append(self.execute_and_record(rop.GETARRAYITEM_GC, descr, + abox, ConstInt(j))) + return boxes + def replace_box(self, oldbox, newbox): for frame in self.framestack: boxes = frame.env for i in range(len(boxes)): if boxes[i] is oldbox: boxes[i] = newbox + boxes = self.virtualref_boxes + for i in range(len(boxes)): + if boxes[i] is oldbox: + boxes[i] = newbox if self.staticdata.virtualizable_info is not None: boxes = self.virtualizable_boxes for i in range(len(boxes)): @@ -1886,6 +2030,20 @@ max_key = key return max_key + def direct_assembler_call(self, pc, varargs, token, call_position): + """ Generate a direct call to assembler for portal entry point. + """ + assert not self.is_blackholing() # XXX + num_green_args = self.staticdata.num_green_args + args = varargs[num_green_args + 1:] + resbox = self.history.operations[call_position].result + rest = self.history.slice_history_at(call_position) + if self.staticdata.virtualizable_info is not None: + vindex = self.staticdata.virtualizable_info.index_of_virtualizable + vbox = args[vindex - num_green_args] + args += self.gen_load_from_other_virtualizable(vbox) + self.history.record(rop.CALL_ASSEMBLER, args[:], resbox, descr=token) + self.history.operations += rest class GenerateMergePoint(Exception): def __init__(self, args, target_loop_token): Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/resoperation.py Mon Jan 25 15:25:48 2010 @@ -31,7 +31,11 @@ self.descr = descr def clone(self): - op = ResOperation(self.opnum, self.args, self.result, self.descr) + descr = self.descr + if descr is not None: + descr = descr._clone_if_mutable() + op = ResOperation(self.opnum, self.args, self.result, descr) + op.fail_args = self.fail_args if not we_are_translated(): op.name = self.name op.pc = self.pc @@ -90,7 +94,7 @@ return rop._OVF_FIRST <= self.opnum <= rop._OVF_LAST def is_comparison(self): - return rop._COMPARISON_FIRST <= self.opnum <= rop._COMPARISON_LAST + return self.is_always_pure() and self.returns_bool_result() def is_final(self): return rop._FINAL_FIRST <= self.opnum <= rop._FINAL_LAST @@ -155,7 +159,6 @@ 'CAST_FLOAT_TO_INT/1', 'CAST_INT_TO_FLOAT/1', # - '_COMPARISON_FIRST', 'INT_LT/2b', 'INT_LE/2b', 'INT_EQ/2b', @@ -166,8 +169,7 @@ 'UINT_LE/2b', 'UINT_GT/2b', 'UINT_GE/2b', - '_COMPARISON_LAST', - 'FLOAT_LT/2b', # maybe these ones should be comparisons too + 'FLOAT_LT/2b', 'FLOAT_LE/2b', 'FLOAT_EQ/2b', 'FLOAT_NE/2b', @@ -205,6 +207,8 @@ 'NEW/0d', 'NEW_WITH_VTABLE/1', 'NEW_ARRAY/1d', + 'FORCE_TOKEN/0', + 'VIRTUAL_REF/2', '_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations ----- 'SETARRAYITEM_GC/3d', @@ -221,11 +225,13 @@ 'COND_CALL_GC_MALLOC', # [a, b, if_(a<=b)_result, if_(a>b)_call, args...] # => result (for mallocs) 'DEBUG_MERGE_POINT/1', # debugging only - 'FORCE_TOKEN/0', + 'VIRTUAL_REF_FINISH/2', '_CANRAISE_FIRST', # ----- start of can_raise operations ----- 'CALL', + 'CALL_ASSEMBLER', 'CALL_MAY_FORCE', + 'CALL_LOOPINVARIANT', 'OOSEND', # ootype operation '_CANRAISE_LAST', # ----- end of can_raise operations ----- Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/resume.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/resume.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/resume.py Mon Jan 25 15:25:48 2010 @@ -21,15 +21,10 @@ self.boxes = boxes class FrameInfo(object): - __slots__ = ('prev', 'jitcode', 'pc', 'exception_target', 'level') + __slots__ = ('prev', 'jitcode', 'pc', 'exception_target') def __init__(self, prev, frame): self.prev = prev - if prev is None: - level = 1 - else: - level = prev.level + 1 - self.level = level self.jitcode = frame.jitcode self.pc = frame.pc self.exception_target = frame.exception_target @@ -47,7 +42,8 @@ back.parent_resumedata_snapshot, back.env[:]) -def capture_resumedata(framestack, virtualizable_boxes, storage): +def capture_resumedata(framestack, virtualizable_boxes, virtualref_boxes, + storage): n = len(framestack)-1 top = framestack[n] _ensure_parent_resumedata(framestack, n) @@ -55,6 +51,7 @@ top) storage.rd_frame_info_list = frame_info_list snapshot = Snapshot(top.parent_resumedata_snapshot, top.env[:]) + snapshot = Snapshot(snapshot, virtualref_boxes[:]) # xxx for now if virtualizable_boxes is not None: snapshot = Snapshot(snapshot, virtualizable_boxes[:]) # xxx for now storage.rd_snapshot = snapshot @@ -98,8 +95,8 @@ TAGBOX = 2 TAGVIRTUAL = 3 -UNASSIGNED = tag(-2 ** 12 - 1, TAGBOX) -UNASSIGNEDVIRTUAL = tag(-2 ** 12 - 1, TAGVIRTUAL) +UNASSIGNED = tag(-1<<13, TAGBOX) +UNASSIGNEDVIRTUAL = tag(-1<<13, TAGVIRTUAL) NULLREF = tag(-1, TAGCONST) @@ -200,6 +197,7 @@ return len(self.cached_boxes) def assign_number_to_box(self, box, boxes): + # returns a negative number if box in self.cached_boxes: num = self.cached_boxes[box] boxes[-num-1] = box @@ -213,6 +211,7 @@ return len(self.cached_virtuals) def assign_number_to_virtual(self, box): + # returns a negative number if box in self.cached_virtuals: num = self.cached_virtuals[box] else: @@ -235,8 +234,6 @@ def __init__(self, storage, memo): self.storage = storage self.memo = memo - #self.virtuals = [] - #self.vfieldboxes = [] def make_virtual(self, known_class, fielddescrs): return VirtualInfo(known_class, fielddescrs) @@ -257,8 +254,6 @@ if (isinstance(box, Box) and box not in self.liveboxes_from_env and box not in self.liveboxes): self.liveboxes[box] = UNASSIGNED - return True - return False def _register_boxes(self, boxes): for box in boxes: @@ -273,9 +268,11 @@ _, tagbits = untag(tagged) return tagbits == TAGVIRTUAL - def finish(self, values): + def finish(self, values, pending_setfields=[]): # compute the numbering storage = self.storage + # make sure that nobody attached resume data to this guard yet + assert storage.rd_numb is None numb, liveboxes_from_env, v = self.memo.number(values, storage.rd_snapshot) self.liveboxes_from_env = liveboxes_from_env @@ -296,16 +293,29 @@ value = values[box] value.get_args_for_fail(self) + for _, box, fieldbox in pending_setfields: + self.register_box(box) + self.register_box(fieldbox) + value = values[fieldbox] + value.get_args_for_fail(self) + self._number_virtuals(liveboxes, values, v) + self._add_pending_fields(pending_setfields) storage.rd_consts = self.memo.consts dump_storage(storage, liveboxes) return liveboxes[:] def _number_virtuals(self, liveboxes, values, num_env_virtuals): + # !! 'liveboxes' is a list that is extend()ed in-place !! memo = self.memo new_liveboxes = [None] * memo.num_cached_boxes() count = 0 + # So far, self.liveboxes should contain 'tagged' values that are + # either UNASSIGNED, UNASSIGNEDVIRTUAL, or a *non-negative* value + # with the TAGVIRTUAL. The following loop removes the UNASSIGNED + # and UNASSIGNEDVIRTUAL entries, and replaces them with real + # negative values. for box, tagged in self.liveboxes.iteritems(): i, tagbits = untag(tagged) if tagbits == TAGBOX: @@ -320,6 +330,8 @@ assert box not in self.liveboxes_from_env index = memo.assign_number_to_virtual(box) self.liveboxes[box] = tag(index, TAGVIRTUAL) + else: + assert i >= 0 new_liveboxes.reverse() liveboxes.extend(new_liveboxes) nholes = len(new_liveboxes) - count @@ -356,6 +368,16 @@ return True return False + def _add_pending_fields(self, pending_setfields): + rd_pendingfields = None + if pending_setfields: + rd_pendingfields = [] + for descr, box, fieldbox in pending_setfields: + num = self._gettagged(box) + fieldnum = self._gettagged(fieldbox) + rd_pendingfields.append((descr, num, fieldnum)) + self.storage.rd_pendingfields = rd_pendingfields + def _gettagged(self, box): if isinstance(box, Const): return self.memo.getconst(box) @@ -364,11 +386,16 @@ return self.liveboxes_from_env[box] return self.liveboxes[box] + class AbstractVirtualInfo(object): def allocate(self, metainterp): raise NotImplementedError def setfields(self, metainterp, box, fn_decode_box): raise NotImplementedError + def equals(self, fieldnums): + return tagged_list_eq(self.fieldnums, fieldnums) + def set_content(self, fieldnums): + self.fieldnums = fieldnums class AbstractVirtualStructInfo(AbstractVirtualInfo): @@ -439,11 +466,13 @@ debug_print("\t\t", str(untag(i))) -def rebuild_from_resumedata(metainterp, newboxes, storage, expects_virtualizables): +def rebuild_from_resumedata(metainterp, newboxes, storage, + expects_virtualizables): resumereader = ResumeDataReader(storage, newboxes, metainterp) virtualizable_boxes = None if expects_virtualizables: virtualizable_boxes = resumereader.consume_boxes() + virtualref_boxes = resumereader.consume_boxes() frameinfo = storage.rd_frame_info_list while True: env = resumereader.consume_boxes() @@ -453,11 +482,16 @@ if frameinfo is None: break metainterp.framestack.reverse() - return virtualizable_boxes + return virtualizable_boxes, virtualref_boxes -def force_from_resumedata(metainterp, newboxes, storage): +def force_from_resumedata(metainterp, newboxes, storage, + expects_virtualizables): resumereader = ResumeDataReader(storage, newboxes, metainterp) - return resumereader.consume_boxes(), resumereader.virtuals + virtualizable_boxes = None + if expects_virtualizables: + virtualizable_boxes = resumereader.consume_boxes() + virtualref_boxes = resumereader.consume_boxes() + return virtualizable_boxes, virtualref_boxes, resumereader.virtuals class ResumeDataReader(object): @@ -469,6 +503,7 @@ self.liveboxes = liveboxes self.cpu = metainterp.cpu self._prepare_virtuals(metainterp, storage.rd_virtuals) + self._prepare_pendingfields(metainterp, storage.rd_pendingfields) def _prepare_virtuals(self, metainterp, virtuals): if virtuals: @@ -487,6 +522,16 @@ vinfo.setfields(metainterp, self.virtuals[i], self._decode_box) + def _prepare_pendingfields(self, metainterp, pendingfields): + if pendingfields: + if metainterp._already_allocated_resume_virtuals is not None: + return + for descr, num, fieldnum in pendingfields: + box = self._decode_box(num) + fieldbox = self._decode_box(fieldnum) + metainterp.execute_and_record(rop.SETFIELD_GC, + descr, box, fieldbox) + def consume_boxes(self): numb = self.cur_numb assert numb is not None Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/support.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/support.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/support.py Mon Jan 25 15:25:48 2010 @@ -3,6 +3,7 @@ from pypy.rpython import rlist from pypy.rpython.lltypesystem import rstr as ll_rstr, rdict as ll_rdict from pypy.rpython.lltypesystem import rlist as lltypesystem_rlist +from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.ootypesystem import rdict as oo_rdict from pypy.rpython.llinterp import LLInterpreter from pypy.rpython.extregistry import ExtRegistryEntry @@ -136,6 +137,9 @@ def _ll_1_gc_identityhash(x): return lltype.identityhash(x) +def _ll_1_jit_force_virtual(inst): + return llop.jit_force_virtual(lltype.typeOf(inst), inst) + class LLtypeHelpers: Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_basic.py Mon Jan 25 15:25:48 2010 @@ -1,7 +1,7 @@ import py import sys from pypy.rlib.jit import JitDriver, we_are_jitted, hint, dont_look_inside -from pypy.rlib.jit import OPTIMIZER_FULL, OPTIMIZER_SIMPLE +from pypy.rlib.jit import OPTIMIZER_FULL, OPTIMIZER_SIMPLE, loop_invariant from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats from pypy.jit.backend.llgraph import runner from pypy.jit.metainterp import support, codewriter, pyjitpl, history @@ -52,6 +52,8 @@ assert get_stats().exec_jumps <= maxcount def check_aborted_count(self, count): assert get_stats().aborted_count == count + def check_aborted_count_at_least(self, count): + assert get_stats().aborted_count >= count def meta_interp(self, *args, **kwds): kwds['CPUClass'] = self.CPUClass @@ -84,6 +86,10 @@ metainterp, rtyper = _get_bare_metainterp(f, args, self.CPUClass, self.type_system, **kwds) + metainterp.staticdata.state = FakeWarmRunnerState() + metainterp.staticdata.state.cpu = metainterp.staticdata.cpu + if hasattr(self, 'finish_metainterp_for_interp_operations'): + self.finish_metainterp_for_interp_operations(metainterp) portal_graph = rtyper.annotator.translator.graphs[0] cw = codewriter.CodeWriter(rtyper) @@ -95,7 +101,6 @@ cw.finish_making_bytecodes() metainterp.staticdata.portal_code = maingraph metainterp.staticdata._class_sizes = cw.class_sizes - metainterp.staticdata.state = FakeWarmRunnerState() metainterp.staticdata.DoneWithThisFrameInt = DoneWithThisFrame metainterp.staticdata.DoneWithThisFrameRef = DoneWithThisFrameRef metainterp.staticdata.DoneWithThisFrameFloat = DoneWithThisFrame @@ -380,6 +385,26 @@ res = self.meta_interp(f, [55]) assert res == -1 + def test_confirm_enter_jit(self): + def confirm_enter_jit(x, y): + return x <= 5 + myjitdriver = JitDriver(greens = ['x'], reds = ['y'], + confirm_enter_jit = confirm_enter_jit) + def f(x, y): + while y >= 0: + myjitdriver.can_enter_jit(x=x, y=y) + myjitdriver.jit_merge_point(x=x, y=y) + y -= x + return y + # + res = self.meta_interp(f, [10, 84]) + assert res == -6 + self.check_loop_count(0) + # + res = self.meta_interp(f, [3, 19]) + assert res == -2 + self.check_loop_count(1) + def test_format(self): def f(n): return len("<%d>" % n) @@ -1196,6 +1221,69 @@ res = self.meta_interp(f, [21]) assert res == 42 self.check_loops(guard_nonnull=1, guard_isnull=1) + + def test_loop_invariant(self): + myjitdriver = JitDriver(greens = [], reds = ['x', 'res']) + class A(object): + pass + a = A() + a.current_a = A() + a.current_a.x = 1 + @loop_invariant + def f(): + return a.current_a + + def g(x): + res = 0 + while x > 0: + myjitdriver.can_enter_jit(x=x, res=res) + myjitdriver.jit_merge_point(x=x, res=res) + res += f().x + res += f().x + res += f().x + x -= 1 + a.current_a = A() + a.current_a.x = 2 + return res + res = self.meta_interp(g, [21]) + assert res == 3 * 21 + self.check_loops(call=1) + + def test_bug_optimizeopt_mutates_ops(self): + myjitdriver = JitDriver(greens = [], reds = ['x', 'res', 'a', 'const']) + class A(object): + pass + class B(A): + pass + + glob = A() + glob.a = None + def f(x): + res = 0 + a = A() + a.x = 0 + glob.a = A() + const = 2 + while x > 0: + myjitdriver.can_enter_jit(x=x, res=res, a=a, const=const) + myjitdriver.jit_merge_point(x=x, res=res, a=a, const=const) + if type(glob.a) is B: + res += 1 + if a is None: + a = A() + a.x = x + glob.a = B() + const = 2 + else: + const = hint(const, promote=True) + x -= const + res += a.x + a = None + glob.a = A() + const = 1 + return res + res = self.meta_interp(f, [21]) + assert res == f(21) class TestOOtype(BasicTests, OOJitMixin): Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_codewriter.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_codewriter.py Mon Jan 25 15:25:48 2010 @@ -2,6 +2,7 @@ from pypy.rlib import jit from pypy.jit.metainterp import support, typesystem from pypy.jit.metainterp.policy import JitPolicy +from pypy.jit.metainterp.history import ConstInt from pypy.jit.metainterp.codewriter import CodeWriter from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin from pypy.translator.translator import graphof @@ -78,7 +79,27 @@ supports_floats=True) funcs = set([graph.func for graph in res]) assert funcs == set([f, h]) - + +def test_unroll_safe_and_inline(): + @jit.unroll_safe + def h(x): + i = 0 + while i < x: + i += 1 + return i + h._always_inline_ = True + + def g(x): + return h(x) + + rtyper = support.annotate(g, [7]) + cw = CodeWriter(rtyper) + jitpolicy = JitPolicy() + translator = rtyper.annotator.translator + res = cw.find_all_graphs(translator.graphs[0], None, jitpolicy, + supports_floats=True) + funcs = set([graph.func for graph in res]) + assert funcs == set([g, h]) def test_find_all_graphs_str_join(): def i(x, y): @@ -101,6 +122,8 @@ def make_graphs(self, func, values, type_system='lltype'): class FakeMetaInterpSd: virtualizable_info = None + class options: + listops = True def find_opcode(self, name): default = len(self.opname_to_index) return self.opname_to_index.setdefault(name, default) @@ -283,7 +306,7 @@ assert calldescrs[0][4] is not None assert not calldescrs[0][4].write_descrs_fields assert not calldescrs[0][4].write_descrs_arrays - assert not calldescrs[0][4].promotes_virtualizables + assert not calldescrs[0][4].forces_virtual_or_virtualizable def test_oosend_look_inside_only_one(self): class A: @@ -394,7 +417,7 @@ assert cw.list_of_addr2name[0][1].endswith('.A1') assert cw.list_of_addr2name[1][1] == 'A1.g' - def test_promote_virtualizable_effectinfo(self): + def test_jit_force_virtualizable_effectinfo(self): class Frame(object): _virtualizable2_ = ['x'] @@ -430,9 +453,64 @@ effectinfo_g1 = calldescrs[1][4] effectinfo_g2 = calldescrs[2][4] effectinfo_h = calldescrs[3][4] - assert effectinfo_g1.promotes_virtualizables - assert effectinfo_g2.promotes_virtualizables - assert not effectinfo_h.promotes_virtualizables + assert effectinfo_g1.forces_virtual_or_virtualizable + assert effectinfo_g2.forces_virtual_or_virtualizable + assert not effectinfo_h.forces_virtual_or_virtualizable + + def make_vrefinfo(self): + from pypy.jit.metainterp.virtualref import VirtualRefInfo + class FakeWarmRunnerDesc: + cpu = self.metainterp_sd.cpu + self.metainterp_sd.virtualref_info = VirtualRefInfo(FakeWarmRunnerDesc) + + def test_vref_simple(self): + class X: + pass + def f(): + return jit.virtual_ref(X()) + graphs = self.make_graphs(f, []) + assert graphs[0].func is f + assert graphs[1].func is jit.virtual_ref + self.make_vrefinfo() + cw = CodeWriter(self.rtyper) + cw.candidate_graphs = [graphs[0]] + cw._start(self.metainterp_sd, None) + jitcode = cw.make_one_bytecode((graphs[0], None), False) + assert 'virtual_ref' in jitcode._source + + def test_vref_forced(self): + class X: + pass + def f(): + vref = jit.virtual_ref(X()) + return vref() + graphs = self.make_graphs(f, []) + assert graphs[0].func is f + assert graphs[1].func is jit.virtual_ref + self.make_vrefinfo() + cw = CodeWriter(self.rtyper) + cw.candidate_graphs = [graphs[0]] + cw._start(self.metainterp_sd, None) + jitcode = cw.make_one_bytecode((graphs[0], None), False) + assert 'virtual_ref' in jitcode._source + # the call vref() becomes a residual call to a helper that contains + # itself a copy of the call. + assert 'residual_call' in jitcode._source + + def test_we_are_jitted(self): + def f(): + if jit.we_are_jitted(): + return 55 + else: + return 66 + graphs = self.make_graphs(f, []) + cw = CodeWriter(self.rtyper) + cw.candidate_graphs = [graphs[0]] + cw._start(self.metainterp_sd, None) + jitcode = cw.make_one_bytecode((graphs[0], None), False) + assert 'goto_if_not' not in jitcode._source + assert ConstInt(55) in jitcode.constants + assert ConstInt(66) not in jitcode.constants class ImmutableFieldsTests: Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_compile.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_compile.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_compile.py Mon Jan 25 15:25:48 2010 @@ -77,7 +77,7 @@ metainterp = FakeMetaInterp() metainterp.staticdata = staticdata metainterp.cpu = cpu - metainterp.history = History(metainterp.cpu) + metainterp.history = History() metainterp.history.operations = loop.operations[:] metainterp.history.inputargs = loop.inputargs[:] # @@ -94,7 +94,7 @@ metainterp = FakeMetaInterp() metainterp.staticdata = staticdata metainterp.cpu = cpu - metainterp.history = History(metainterp.cpu) + metainterp.history = History() metainterp.history.operations = loop.operations[:] metainterp.history.inputargs = loop.inputargs[:] # Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_effectinfo.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_effectinfo.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_effectinfo.py Mon Jan 25 15:25:48 2010 @@ -3,32 +3,77 @@ from pypy.rpython.ootypesystem import ootype from pypy.jit.metainterp.effectinfo import effectinfo_from_writeanalyze +class FakeCPU: + def fielddescrof(self, T, fieldname): + return ('fielddescr', T, fieldname) + def arraydescrof(self, A): + return ('arraydescr', A) + +def test_include_read_field(): + S = lltype.GcStruct("S", ("a", lltype.Signed)) + effects = frozenset([("readstruct", lltype.Ptr(S), "a")]) + effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU()) + assert list(effectinfo.readonly_descrs_fields) == [('fielddescr', S, "a")] + assert not effectinfo.write_descrs_fields + assert not effectinfo.write_descrs_arrays + +def test_include_write_field(): + S = lltype.GcStruct("S", ("a", lltype.Signed)) + effects = frozenset([("struct", lltype.Ptr(S), "a")]) + effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU()) + assert list(effectinfo.write_descrs_fields) == [('fielddescr', S, "a")] + assert not effectinfo.readonly_descrs_fields + assert not effectinfo.write_descrs_arrays + +def test_include_write_array(): + A = lltype.GcArray(lltype.Signed) + effects = frozenset([("array", lltype.Ptr(A))]) + effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU()) + assert not effectinfo.readonly_descrs_fields + assert not effectinfo.write_descrs_fields + assert list(effectinfo.write_descrs_arrays) == [('arraydescr', A)] + +def test_dont_include_read_and_write_field(): + S = lltype.GcStruct("S", ("a", lltype.Signed)) + effects = frozenset([("readstruct", lltype.Ptr(S), "a"), + ("struct", lltype.Ptr(S), "a")]) + effectinfo = effectinfo_from_writeanalyze(effects, FakeCPU()) + assert not effectinfo.readonly_descrs_fields + assert list(effectinfo.write_descrs_fields) == [('fielddescr', S, "a")] + assert not effectinfo.write_descrs_arrays + + def test_filter_out_typeptr(): effects = frozenset([("struct", lltype.Ptr(OBJECT), "typeptr")]) effectinfo = effectinfo_from_writeanalyze(effects, None) + assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_fields assert not effectinfo.write_descrs_arrays def test_filter_out_array_of_void(): effects = frozenset([("array", lltype.Ptr(lltype.GcArray(lltype.Void)))]) effectinfo = effectinfo_from_writeanalyze(effects, None) + assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_fields assert not effectinfo.write_descrs_arrays def test_filter_out_struct_with_void(): effects = frozenset([("struct", lltype.Ptr(lltype.GcStruct("x", ("a", lltype.Void))), "a")]) effectinfo = effectinfo_from_writeanalyze(effects, None) + assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_fields assert not effectinfo.write_descrs_arrays def test_filter_out_ooarray_of_void(): effects = frozenset([("array", ootype.Array(ootype.Void))]) effectinfo = effectinfo_from_writeanalyze(effects, None) + assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_fields assert not effectinfo.write_descrs_arrays def test_filter_out_instance_with_void(): effects = frozenset([("struct", ootype.Instance("x", ootype.ROOT, {"a": ootype.Void}), "a")]) effectinfo = effectinfo_from_writeanalyze(effects, None) + assert not effectinfo.readonly_descrs_fields assert not effectinfo.write_descrs_fields assert not effectinfo.write_descrs_arrays Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_executor.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_executor.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_executor.py Mon Jan 25 15:25:48 2010 @@ -273,4 +273,4 @@ elif rettype == 'int': assert box.getint() == retvalue else: - assert retvalue is None + assert 0, "rettype is %r" % (rettype,) Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_history.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_history.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_history.py Mon Jan 25 15:25:48 2010 @@ -9,3 +9,10 @@ s = lltype.cast_pointer(lltype.Ptr(S), t) const = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s)) assert const._getrepr_() == "*T" + +def test_slicing(): + h = History() + h.operations = [1, 2, 3, 4, 5] + rest = h.slice_history_at(2) + assert rest == [4, 5] + assert h.operations == [1, 2] Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_jitprof.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_jitprof.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_jitprof.py Mon Jan 25 15:25:48 2010 @@ -64,7 +64,7 @@ assert profiler.events == expected assert profiler.times == [2, 1, 1, 1] assert profiler.counters == [1, 1, 1, 1, 4, 3, 1, 1, 7, 1, 0, 0, 0, - 0, 0, 0] + 0, 0, 0, 0] def test_simple_loop_with_call(self): @dont_look_inside Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_optimizefindnode.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_optimizefindnode.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_optimizefindnode.py Mon Jan 25 15:25:48 2010 @@ -1,6 +1,6 @@ import py, random -from pypy.rpython.lltypesystem import lltype, llmemory +from pypy.rpython.lltypesystem import lltype, llmemory, rclass from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE @@ -38,12 +38,13 @@ type_system = 'lltype' def get_class_of_box(self, box): - from pypy.rpython.lltypesystem import rclass return box.getref(rclass.OBJECTPTR).typeptr node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) + node_vtable.name = rclass.alloc_array_name('node') node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable) node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True) + node_vtable2.name = rclass.alloc_array_name('node2') node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2) cpu = runner.LLtypeCPU(None) @@ -67,6 +68,12 @@ nextdescr = cpu.fielddescrof(NODE, 'next') otherdescr = cpu.fielddescrof(NODE2, 'other') + NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT), + ('ref', lltype.Ptr(OBJECT))) + nodeobj = lltype.malloc(NODEOBJ) + nodeobjvalue = lltype.cast_opaque_ptr(llmemory.GCREF, nodeobj) + refdescr = cpu.fielddescrof(NODEOBJ, 'ref') + arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed)) floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float)) @@ -95,13 +102,40 @@ onedescr = cpu.fielddescrof(U, 'one') FUNC = lltype.FuncType([lltype.Signed], lltype.Signed) - nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([], [])) - writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([adescr], [])) - writearraydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, EffectInfo([adescr], [arraydescr])) - - cpu.class_sizes = {cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE), - cpu.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2), - cpu.cast_adr_to_int(u_vtable_adr): cpu.sizeof(U)} + plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT) + nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo([], [], [])) + writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo([], [adescr], [])) + writearraydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo([], [adescr], [arraydescr])) + readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo([adescr], [], [])) + mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, + EffectInfo([nextdescr], [], [], + forces_virtual_or_virtualizable=True)) + class LoopToken(AbstractDescr): + pass + asmdescr = LoopToken() # it can be whatever, it's not a descr though + + from pypy.jit.metainterp.virtualref import VirtualRefInfo + class FakeWarmRunnerDesc: + pass + FakeWarmRunnerDesc.cpu = cpu + vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc) + virtualtokendescr = vrefinfo.descr_virtual_token + virtualrefindexdescr = vrefinfo.descr_virtualref_index + virtualforceddescr = vrefinfo.descr_forced + jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable + jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable) + + cpu.class_sizes = { + cpu.cast_adr_to_int(node_vtable_adr): cpu.sizeof(NODE), + cpu.cast_adr_to_int(node_vtable_adr2): cpu.sizeof(NODE2), + cpu.cast_adr_to_int(u_vtable_adr): cpu.sizeof(U), + cpu.cast_adr_to_int(jvr_vtable_adr): cpu.sizeof( + vrefinfo.JIT_VIRTUAL_REF), + } namespace = locals() class OOtypeMixin(object): Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_optimizeopt.py Mon Jan 25 15:25:48 2010 @@ -87,7 +87,10 @@ def test_reuse_vinfo(): class FakeVInfo(object): - pass + def set_content(self, fieldnums): + self.fieldnums = fieldnums + def equals(self, fieldnums): + return self.fieldnums == fieldnums class FakeVirtualValue(optimizeopt.AbstractVirtualValue): def _make_virtual(self, *args): return FakeVInfo() @@ -204,8 +207,9 @@ class Storage(compile.ResumeGuardDescr): "for tests." - def __init__(self): - pass + def __init__(self, metainterp_sd=None, original_greenkey=None): + self.metainterp_sd = metainterp_sd + self.original_greenkey = original_greenkey def store_final_boxes(self, op, boxes): op.fail_args = boxes def __eq__(self, other): @@ -246,7 +250,10 @@ loop.token.specnodes = self.unpack_specnodes(spectext) # self.loop = loop - optimize_loop_1(FakeMetaInterpStaticData(self.cpu), loop) + metainterp_sd = FakeMetaInterpStaticData(self.cpu) + if hasattr(self, 'vrefinfo'): + metainterp_sd.virtualref_info = self.vrefinfo + optimize_loop_1(metainterp_sd, loop) # expected = self.parse(optops) self.assert_equal(loop, expected) @@ -606,10 +613,10 @@ p3sub = getfield_gc(p3, descr=nextdescr) i3 = getfield_gc(p3sub, descr=valuedescr) escape(i3) + p1 = new_with_vtable(ConstClass(node_vtable)) p2sub = new_with_vtable(ConstClass(node_vtable2)) setfield_gc(p2sub, i1, descr=valuedescr) setfield_gc(p2, p2sub, descr=nextdescr) - p1 = new_with_vtable(ConstClass(node_vtable)) jump(i1, p1, p2) """ # The same as test_p123_simple, but in the end the "old" p2 contains @@ -642,6 +649,32 @@ # ---------- + def test_call_loopinvariant(self): + ops = """ + [i1] + i2 = call_loopinvariant(1, i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + i3 = call_loopinvariant(1, i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + i4 = call_loopinvariant(1, i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + jump(i1) + """ + expected = """ + [i1] + i2 = call(1, i1, descr=nonwritedescr) + guard_no_exception() [] + guard_value(i2, 1) [] + jump(i1) + """ + self.optimize_loop(ops, 'Not', expected) + + + # ---------- + def test_virtual_1(self): ops = """ [i, p0] @@ -919,6 +952,26 @@ """ self.optimize_loop(ops, 'Not', expected) + def test_nonvirtual_dont_write_null_fields_on_force(self): + ops = """ + [i] + p1 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1, i, descr=valuedescr) + i1 = getfield_gc(p1, descr=valuedescr) + setfield_gc(p1, 0, descr=valuedescr) + escape(p1) + i2 = getfield_gc(p1, descr=valuedescr) + jump(i2) + """ + expected = """ + [i] + p1 = new_with_vtable(ConstClass(node_vtable)) + escape(p1) + i2 = getfield_gc(p1, descr=valuedescr) + jump(i2) + """ + self.optimize_loop(ops, 'Not', expected) + def test_getfield_gc_pure_1(self): ops = """ [i] @@ -1019,6 +1072,24 @@ """ self.optimize_loop(ops, 'Not, Not', expected) + def test_nonvirtual_array_dont_write_null_fields_on_force(self): + ops = """ + [i1] + p1 = new_array(5, descr=arraydescr) + setarrayitem_gc(p1, 0, i1, descr=arraydescr) + setarrayitem_gc(p1, 1, 0, descr=arraydescr) + escape(p1) + jump(i1) + """ + expected = """ + [i1] + p1 = new_array(5, descr=arraydescr) + setarrayitem_gc(p1, 0, i1, descr=arraydescr) + escape(p1) + jump(i1) + """ + self.optimize_loop(ops, 'Not', expected) + def test_varray_2(self): ops = """ [i0, p1] @@ -1293,6 +1364,204 @@ """ self.optimize_loop(ops, 'Not, Not', ops) + def test_duplicate_setfield_1(self): + ops = """ + [p1, i1, i2] + setfield_gc(p1, i1, descr=valuedescr) + setfield_gc(p1, i2, descr=valuedescr) + jump(p1, i1, i2) + """ + expected = """ + [p1, i1, i2] + setfield_gc(p1, i2, descr=valuedescr) + jump(p1, i1, i2) + """ + self.optimize_loop(ops, 'Not, Not, Not', expected) + + def test_duplicate_setfield_2(self): + ops = """ + [p1, i1, i3] + setfield_gc(p1, i1, descr=valuedescr) + i2 = getfield_gc(p1, descr=valuedescr) + setfield_gc(p1, i3, descr=valuedescr) + escape(i2) + jump(p1, i1, i3) + """ + expected = """ + [p1, i1, i3] + setfield_gc(p1, i3, descr=valuedescr) + escape(i1) + jump(p1, i1, i3) + """ + self.optimize_loop(ops, 'Not, Not, Not', expected) + + def test_duplicate_setfield_3(self): + ops = """ + [p1, p2, i1, i3] + setfield_gc(p1, i1, descr=valuedescr) + i2 = getfield_gc(p2, descr=valuedescr) + setfield_gc(p1, i3, descr=valuedescr) + escape(i2) + jump(p1, p2, i1, i3) + """ + # potential aliasing of p1 and p2 means that we cannot kill the + # the setfield_gc + self.optimize_loop(ops, 'Not, Not, Not, Not', ops) + + def test_duplicate_setfield_4(self): + ops = """ + [p1, i1, i2, p3] + setfield_gc(p1, i1, descr=valuedescr) + # + # some operations on which the above setfield_gc cannot have effect + i3 = getarrayitem_gc_pure(p3, 1, descr=arraydescr) + i4 = getarrayitem_gc(p3, i3, descr=arraydescr) + i5 = int_add(i3, i4) + setarrayitem_gc(p3, 0, i5, descr=arraydescr) + setfield_gc(p1, i4, descr=nextdescr) + # + setfield_gc(p1, i2, descr=valuedescr) + jump(p1, i1, i2, p3) + """ + expected = """ + [p1, i1, i2, p3] + # + i3 = getarrayitem_gc_pure(p3, 1, descr=arraydescr) + i4 = getarrayitem_gc(p3, i3, descr=arraydescr) + i5 = int_add(i3, i4) + setarrayitem_gc(p3, 0, i5, descr=arraydescr) + # + setfield_gc(p1, i2, descr=valuedescr) + setfield_gc(p1, i4, descr=nextdescr) + jump(p1, i1, i2, p3) + """ + self.optimize_loop(ops, 'Not, Not, Not, Not', expected) + + def test_duplicate_setfield_5(self): + ops = """ + [p0, i1] + p1 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1, i1, descr=valuedescr) + setfield_gc(p0, p1, descr=nextdescr) + setfield_raw(i1, i1, descr=valuedescr) # random op with side-effects + p2 = getfield_gc(p0, descr=nextdescr) + i2 = getfield_gc(p2, descr=valuedescr) + setfield_gc(p0, NULL, descr=nextdescr) + escape(i2) + jump(p0, i1) + """ + expected = """ + [p0, i1] + setfield_raw(i1, i1, descr=valuedescr) + setfield_gc(p0, NULL, descr=nextdescr) + escape(i1) + jump(p0, i1) + """ + self.optimize_loop(ops, 'Not, Not', expected) + + def test_duplicate_setfield_sideeffects_1(self): + ops = """ + [p1, i1, i2] + setfield_gc(p1, i1, descr=valuedescr) + escape() + setfield_gc(p1, i2, descr=valuedescr) + jump(p1, i1, i2) + """ + self.optimize_loop(ops, 'Not, Not, Not', ops) + + def test_duplicate_setfield_residual_guard_1(self): + ops = """ + [p1, i1, i2, i3] + setfield_gc(p1, i1, descr=valuedescr) + guard_true(i3) [] + i4 = int_neg(i2) + setfield_gc(p1, i2, descr=valuedescr) + jump(p1, i1, i2, i4) + """ + self.optimize_loop(ops, 'Not, Not, Not, Not', ops) + + def test_duplicate_setfield_residual_guard_2(self): + # the difference with the previous test is that the field value is + # a virtual, which we try hard to keep virtual + ops = """ + [p1, i2, i3] + p2 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1, p2, descr=nextdescr) + guard_true(i3) [] + i4 = int_neg(i2) + setfield_gc(p1, NULL, descr=nextdescr) + jump(p1, i2, i4) + """ + expected = """ + [p1, i2, i3] + guard_true(i3) [p1] + i4 = int_neg(i2) + setfield_gc(p1, NULL, descr=nextdescr) + jump(p1, i2, i4) + """ + self.optimize_loop(ops, 'Not, Not, Not', expected) + + def test_duplicate_setfield_residual_guard_3(self): + ops = """ + [p1, i2, i3] + p2 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p2, i2, descr=valuedescr) + setfield_gc(p1, p2, descr=nextdescr) + guard_true(i3) [] + i4 = int_neg(i2) + setfield_gc(p1, NULL, descr=nextdescr) + jump(p1, i2, i4) + """ + expected = """ + [p1, i2, i3] + guard_true(i3) [p1, i2] + i4 = int_neg(i2) + setfield_gc(p1, NULL, descr=nextdescr) + jump(p1, i2, i4) + """ + self.optimize_loop(ops, 'Not, Not, Not', expected) + + def test_duplicate_setfield_residual_guard_4(self): + # test that the setfield_gc does not end up between int_eq and + # the following guard_true + ops = """ + [p1, i1, i2, i3] + setfield_gc(p1, i1, descr=valuedescr) + i5 = int_eq(i3, 5) + guard_true(i5) [] + i4 = int_neg(i2) + setfield_gc(p1, i2, descr=valuedescr) + jump(p1, i1, i2, i4) + """ + self.optimize_loop(ops, 'Not, Not, Not, Not', ops) + + def test_duplicate_setfield_aliasing(self): + # a case where aliasing issues (and not enough cleverness) mean + # that we fail to remove any setfield_gc + ops = """ + [p1, p2, i1, i2, i3] + setfield_gc(p1, i1, descr=valuedescr) + setfield_gc(p2, i2, descr=valuedescr) + setfield_gc(p1, i3, descr=valuedescr) + jump(p1, p2, i1, i2, i3) + """ + self.optimize_loop(ops, 'Not, Not, Not, Not, Not', ops) + + def test_duplicate_setfield_guard_value_const(self): + ops = """ + [p1, i1, i2] + guard_value(p1, ConstPtr(myptr)) [] + setfield_gc(p1, i1, descr=valuedescr) + setfield_gc(ConstPtr(myptr), i2, descr=valuedescr) + jump(p1, i1, i2) + """ + expected = """ + [i1, i2] + setfield_gc(ConstPtr(myptr), i2, descr=valuedescr) + jump(i1, i2) + """ + self.optimize_loop(ops, 'Constant(myptr), Not, Not', expected) + def test_duplicate_getarrayitem_1(self): ops = """ [p1] @@ -1592,6 +1861,36 @@ """ self.optimize_loop(ops, "Not", expected) + def test_remove_duplicate_pure_op(self): + ops = """ + [p1, p2] + i1 = oois(p1, p2) + i2 = oois(p1, p2) + i3 = int_add(i1, 1) + i3b = int_is_true(i3) + guard_true(i3b) [] + i4 = int_add(i2, 1) + i4b = int_is_true(i4) + guard_true(i4b) [] + escape(i3) + escape(i4) + guard_true(i1) [] + guard_true(i2) [] + jump(p1, p2) + """ + expected = """ + [p1, p2] + i1 = oois(p1, p2) + i3 = int_add(i1, 1) + i3b = int_is_true(i3) + guard_true(i3b) [] + escape(i3) + escape(i3) + guard_true(i1) [] + jump(p1, p2) + """ + self.optimize_loop(ops, "Not, Not", expected) + # ---------- def make_fail_descr(self): @@ -1634,6 +1933,14 @@ tag = ('virtual', self.namespace[match.group(2)]) virtuals[pvar] = (tag, None, fieldstext) # + r2 = re.compile(r"([\w\d()]+)[.](\w+)\s*=\s*([\w\d()]+)") + pendingfields = [] + for match in r2.finditer(text): + pvar = match.group(1) + pfieldname = match.group(2) + pfieldvar = match.group(3) + pendingfields.append((pvar, pfieldname, pfieldvar)) + # def _variables_equal(box, varname, strict): if varname not in virtuals: if strict: @@ -1655,11 +1962,21 @@ else: virtuals[varname] = tag, box, fieldstext # - basetext = text[:ends[0]] + basetext = text.splitlines()[0] varnames = [s.strip() for s in basetext.split(',')] + if varnames == ['']: + varnames = [] assert len(boxes) == len(varnames) for box, varname in zip(boxes, varnames): _variables_equal(box, varname, strict=True) + for pvar, pfieldname, pfieldvar in pendingfields: + box = oparse.getvar(pvar) + fielddescr = self.namespace[pfieldname.strip()] + fieldbox = executor.execute(self.cpu, + rop.GETFIELD_GC, + fielddescr, + box) + _variables_equal(fieldbox, pfieldvar, strict=True) # for match in parts: pvar = match.group(1) @@ -1918,6 +2235,57 @@ where p7v is a node_vtable, valuedescr=iv ''') + def test_expand_fail_lazy_setfield_1(self): + self.make_fail_descr() + ops = """ + [p1, i2, i3] + p2 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p2, i2, descr=valuedescr) + setfield_gc(p1, p2, descr=nextdescr) + guard_true(i3, descr=fdescr) [] + i4 = int_neg(i2) + setfield_gc(p1, NULL, descr=nextdescr) + jump(p1, i2, i4) + """ + expected = """ + [p1, i2, i3] + guard_true(i3, descr=fdescr) [p1, i2] + i4 = int_neg(i2) + setfield_gc(p1, NULL, descr=nextdescr) + jump(p1, i2, i4) + """ + self.optimize_loop(ops, 'Not, Not, Not', expected) + self.loop.inputargs[0].value = self.nodebox.value + self.check_expanded_fail_descr(''' + p1.nextdescr = p2 + where p2 is a node_vtable, valuedescr=i2 + ''') + + def test_expand_fail_lazy_setfield_2(self): + self.make_fail_descr() + ops = """ + [i2, i3] + p2 = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p2, i2, descr=valuedescr) + setfield_gc(ConstPtr(myptr), p2, descr=nextdescr) + guard_true(i3, descr=fdescr) [] + i4 = int_neg(i2) + setfield_gc(ConstPtr(myptr), NULL, descr=nextdescr) + jump(i2, i4) + """ + expected = """ + [i2, i3] + guard_true(i3, descr=fdescr) [i2] + i4 = int_neg(i2) + setfield_gc(ConstPtr(myptr), NULL, descr=nextdescr) + jump(i2, i4) + """ + self.optimize_loop(ops, 'Not, Not', expected) + self.check_expanded_fail_descr(''' + ConstPtr(myptr).nextdescr = p2 + where p2 is a node_vtable, valuedescr=i2 + ''') + class TestLLtype(BaseTestOptimizeOpt, LLtypeMixin): @@ -2031,6 +2399,233 @@ """ self.optimize_loop(ops, 'Not, Not, Not', expected) + def test_residual_call_invalidates_some_read_caches_1(self): + ops = """ + [p1, i1, p2, i2] + setfield_gc(p1, i1, descr=valuedescr) + setfield_gc(p2, i2, descr=adescr) + i3 = call(i1, descr=readadescr) + setfield_gc(p1, i3, descr=valuedescr) + setfield_gc(p2, i3, descr=adescr) + jump(p1, i1, p2, i2) + """ + expected = """ + [p1, i1, p2, i2] + setfield_gc(p2, i2, descr=adescr) + i3 = call(i1, descr=readadescr) + setfield_gc(p1, i3, descr=valuedescr) + setfield_gc(p2, i3, descr=adescr) + jump(p1, i1, p2, i2) + """ + self.optimize_loop(ops, 'Not, Not, Not, Not', expected) + + def test_residual_call_invalidates_some_read_caches_2(self): + ops = """ + [p1, i1, p2, i2] + setfield_gc(p1, i1, descr=valuedescr) + setfield_gc(p2, i2, descr=adescr) + i3 = call(i1, descr=writeadescr) + setfield_gc(p1, i3, descr=valuedescr) + setfield_gc(p2, i3, descr=adescr) + jump(p1, i1, p2, i2) + """ + expected = """ + [p1, i1, p2, i2] + setfield_gc(p2, i2, descr=adescr) + i3 = call(i1, descr=writeadescr) + setfield_gc(p1, i3, descr=valuedescr) + setfield_gc(p2, i3, descr=adescr) + jump(p1, i1, p2, i2) + """ + self.optimize_loop(ops, 'Not, Not, Not, Not', expected) + + def test_residual_call_invalidates_some_read_caches_3(self): + ops = """ + [p1, i1, p2, i2] + setfield_gc(p1, i1, descr=valuedescr) + setfield_gc(p2, i2, descr=adescr) + i3 = call(i1, descr=plaincalldescr) + setfield_gc(p1, i3, descr=valuedescr) + setfield_gc(p2, i3, descr=adescr) + jump(p1, i1, p2, i2) + """ + self.optimize_loop(ops, 'Not, Not, Not, Not', ops) + + def test_call_assembler_invalidates_caches(self): + ops = ''' + [p1, i1] + setfield_gc(p1, i1, descr=valuedescr) + i3 = call_assembler(i1, descr=asmdescr) + setfield_gc(p1, i3, descr=valuedescr) + jump(p1, i3) + ''' + self.optimize_loop(ops, 'Not, Not', ops) + + def test_vref_nonvirtual_nonescape(self): + ops = """ + [p1] + p2 = virtual_ref(p1, 5) + virtual_ref_finish(p2, p1) + jump(p1) + """ + expected = """ + [p1] + i0 = force_token() + jump(p1) + """ + self.optimize_loop(ops, 'Not', expected) + + def test_vref_nonvirtual_escape(self): + ops = """ + [p1] + p2 = virtual_ref(p1, 5) + escape(p2) + virtual_ref_finish(p2, p1) + jump(p1) + """ + expected = """ + [p1] + i0 = force_token() + p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable)) + setfield_gc(p2, i0, descr=virtualtokendescr) + setfield_gc(p2, 5, descr=virtualrefindexdescr) + escape(p2) + setfield_gc(p2, p1, descr=virtualforceddescr) + setfield_gc(p2, 0, descr=virtualtokendescr) + jump(p1) + """ + # XXX we should optimize a bit more the case of a nonvirtual. + # in theory it is enough to just do 'p2 = p1'. + self.optimize_loop(ops, 'Not', expected) + + def test_vref_virtual_1(self): + ops = """ + [p0, i1] + # + p1 = new_with_vtable(ConstClass(node_vtable)) + p1b = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1b, 252, descr=valuedescr) + setfield_gc(p1, p1b, descr=nextdescr) + # + p2 = virtual_ref(p1, 3) + setfield_gc(p0, p2, descr=nextdescr) + call_may_force(i1, descr=mayforcevirtdescr) + guard_not_forced() [i1] + virtual_ref_finish(p2, p1) + setfield_gc(p0, NULL, descr=nextdescr) + jump(p0, i1) + """ + expected = """ + [p0, i1] + i3 = force_token() + # + p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable)) + setfield_gc(p2, i3, descr=virtualtokendescr) + setfield_gc(p2, 3, descr=virtualrefindexdescr) + setfield_gc(p0, p2, descr=nextdescr) + # + call_may_force(i1, descr=mayforcevirtdescr) + guard_not_forced() [i1] + setfield_gc(p0, NULL, descr=nextdescr) + # + p1 = new_with_vtable(ConstClass(node_vtable)) + p1b = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1b, 252, descr=valuedescr) + setfield_gc(p1, p1b, descr=nextdescr) + setfield_gc(p2, p1, descr=virtualforceddescr) + setfield_gc(p2, 0, descr=virtualtokendescr) + # + jump(p0, i1) + """ + self.optimize_loop(ops, 'Not, Not', expected) + + def test_vref_virtual_2(self): + self.make_fail_descr() + ops = """ + [p0, i1] + # + p1 = new_with_vtable(ConstClass(node_vtable)) + p1b = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1b, i1, descr=valuedescr) + setfield_gc(p1, p1b, descr=nextdescr) + # + p2 = virtual_ref(p1, 2) + setfield_gc(p0, p2, descr=nextdescr) + call_may_force(i1, descr=mayforcevirtdescr) + guard_not_forced(descr=fdescr) [p2, p1] + virtual_ref_finish(p2, p1) + setfield_gc(p0, NULL, descr=nextdescr) + jump(p0, i1) + """ + expected = """ + [p0, i1] + i3 = force_token() + # + p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable)) + setfield_gc(p2, i3, descr=virtualtokendescr) + setfield_gc(p2, 2, descr=virtualrefindexdescr) + setfield_gc(p0, p2, descr=nextdescr) + # + call_may_force(i1, descr=mayforcevirtdescr) + guard_not_forced(descr=fdescr) [p2, i1] + setfield_gc(p0, NULL, descr=nextdescr) + # + p1 = new_with_vtable(ConstClass(node_vtable)) + p1b = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1b, i1, descr=valuedescr) + setfield_gc(p1, p1b, descr=nextdescr) + setfield_gc(p2, p1, descr=virtualforceddescr) + setfield_gc(p2, 0, descr=virtualtokendescr) + # + jump(p0, i1) + """ + # the point of this test is that 'i1' should show up in the fail_args + # of 'guard_not_forced', because it was stored in the virtual 'p1b'. + self.optimize_loop(ops, 'Not, Not', expected) + self.check_expanded_fail_descr('''p2, p1 + where p1 is a node_vtable, nextdescr=p1b + where p1b is a node_vtable, valuedescr=i1 + ''') + + def test_vref_virtual_and_lazy_setfield(self): + self.make_fail_descr() + ops = """ + [p0, i1] + # + p1 = new_with_vtable(ConstClass(node_vtable)) + p1b = new_with_vtable(ConstClass(node_vtable)) + setfield_gc(p1b, i1, descr=valuedescr) + setfield_gc(p1, p1b, descr=nextdescr) + # + p2 = virtual_ref(p1, 2) + setfield_gc(p0, p2, descr=refdescr) + call(i1, descr=nonwritedescr) + guard_no_exception(descr=fdescr) [p2, p1] + virtual_ref_finish(p2, p1) + setfield_gc(p0, NULL, descr=refdescr) + jump(p0, i1) + """ + expected = """ + [p0, i1] + i3 = force_token() + call(i1, descr=nonwritedescr) + guard_no_exception(descr=fdescr) [i3, i1, p0] + setfield_gc(p0, NULL, descr=refdescr) + jump(p0, i1) + """ + self.optimize_loop(ops, 'Not, Not', expected) + # the fail_args contain [i3, i1, p0]: + # - i3 is from the virtual expansion of p2 + # - i1 is from the virtual expansion of p1 + # - p0 is from the extra pendingfields + self.loop.inputargs[0].value = self.nodeobjvalue + self.check_expanded_fail_descr('''p2, p1 + p0.refdescr = p2 + where p2 is a jit_virtual_ref_vtable, virtualtokendescr=i3, virtualrefindexdescr=2 + where p1 is a node_vtable, nextdescr=p1b + where p1b is a node_vtable, valuedescr=i1 + ''') + class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin): Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_pyjitpl.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_pyjitpl.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_pyjitpl.py Mon Jan 25 15:25:48 2010 @@ -33,7 +33,8 @@ def test_simple_opimpl_exist(): rop = resoperation.rop for opnum, opname in resoperation.opname.items(): - if opnum in (rop.SAME_AS, rop.CALL_PURE, rop.OOSEND_PURE): + if opnum in (rop.SAME_AS, rop.CALL_PURE, rop.OOSEND_PURE, + rop.FORCE_TOKEN): continue if rop._NOSIDEEFFECT_FIRST <= opnum <= rop._NOSIDEEFFECT_LAST: assert hasattr(pyjitpl.MIFrame, 'opimpl_' + opname.lower()), opname @@ -88,7 +89,7 @@ assert box.value == referencebox.value return True metainterp = pyjitpl.MetaInterp(FakeStaticData()) - metainterp.history = History(None) + metainterp.history = History() b1 = BoxInt(1) b2 = BoxInt(2) c3 = ConstInt(3) Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_recursive.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_recursive.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_recursive.py Mon Jan 25 15:25:48 2010 @@ -1,5 +1,5 @@ import py -from pypy.rlib.jit import JitDriver, we_are_jitted, OPTIMIZER_SIMPLE +from pypy.rlib.jit import JitDriver, we_are_jitted, OPTIMIZER_SIMPLE, hint from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin from pypy.jit.metainterp.policy import StopAtXPolicy from pypy.rpython.annlowlevel import hlstr @@ -646,9 +646,303 @@ result += f('-c-----------l-', i+100) self.meta_interp(g, [10], backendopt=True) self.check_aborted_count(1) - self.check_history(call_may_force=1, call=0) + self.check_history(call_assembler=1, call=0) self.check_tree_loop_count(3) + + def test_directly_call_assembler(self): + driver = JitDriver(greens = ['codeno'], reds = ['i'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno): + i = 0 + while i < 10: + driver.can_enter_jit(codeno = codeno, i = i) + driver.jit_merge_point(codeno = codeno, i = i) + if codeno == 2: + portal(1) + i += 1 + + self.meta_interp(portal, [2], inline=True) + self.check_history(call_assembler=1) + + def test_directly_call_assembler_return(self): + driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno): + i = 0 + k = codeno + while i < 10: + driver.can_enter_jit(codeno = codeno, i = i, k = k) + driver.jit_merge_point(codeno = codeno, i = i, k = k) + if codeno == 2: + k = portal(1) + i += 1 + return k + + self.meta_interp(portal, [2], inline=True) + self.check_history(call_assembler=1) + + def test_directly_call_assembler_raise(self): + + class MyException(Exception): + def __init__(self, x): + self.x = x + + driver = JitDriver(greens = ['codeno'], reds = ['i'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno): + i = 0 + while i < 10: + driver.can_enter_jit(codeno = codeno, i = i) + driver.jit_merge_point(codeno = codeno, i = i) + if codeno == 2: + try: + portal(1) + except MyException, me: + i += me.x + i += 1 + if codeno == 1: + raise MyException(1) + + self.meta_interp(portal, [2], inline=True) + self.check_history(call_assembler=1) + + def test_directly_call_assembler_fail_guard(self): + driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def portal(codeno, k): + i = 0 + while i < 10: + driver.can_enter_jit(codeno=codeno, i=i, k=k) + driver.jit_merge_point(codeno=codeno, i=i, k=k) + if codeno == 2: + k += portal(1, k) + elif k > 40: + if i % 2: + k += 1 + else: + k += 2 + k += 1 + i += 1 + return k + + res = self.meta_interp(portal, [2, 0], inline=True) + assert res == 13542 + + def test_directly_call_assembler_virtualizable(self): + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def main(codeno): + frame = Frame() + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True) + assert res == main(0) + + def test_directly_call_assembler_virtualizable_force(self): + class Thing(object): + def __init__(self, val): + self.val = val + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + class SomewhereElse(object): + pass + + somewhere_else = SomewhereElse() + + def change(newthing): + somewhere_else.frame.thing = newthing + + def main(codeno): + frame = Frame() + somewhere_else.frame = frame + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + elif frame.thing.val > 40: + change(Thing(13)) + nextval = 13 + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True, + policy=StopAtXPolicy(change)) + assert res == main(0) + + def test_directly_call_assembler_virtualizable_with_array(self): + myjitdriver = JitDriver(greens = ['codeno'], reds = ['n', 'frame', 'x'], + virtualizables = ['frame'], + can_inline = lambda codeno : False) + + class Frame(object): + _virtualizable2_ = ['l[*]', 's'] + + def __init__(self, l, s): + self = hint(self, access_directly=True, + fresh_virtualizable=True) + self.l = l + self.s = s + + def main(codeno, n, a): + frame = Frame([a, a+1, a+2, a+3], 0) + return f(codeno, n, a, frame) + + def f(codeno, n, a, frame): + x = 0 + while n > 0: + myjitdriver.can_enter_jit(codeno=codeno, frame=frame, n=n, x=x) + myjitdriver.jit_merge_point(codeno=codeno, frame=frame, n=n, + x=x) + frame.s = hint(frame.s, promote=True) + n -= 1 + x += frame.l[frame.s] + frame.s += 1 + if codeno == 0: + subframe = Frame([n, n+1, n+2, n+3], 0) + x += f(1, 10, 1, subframe) + x += frame.l[frame.s] + x += len(frame.l) + frame.s -= 1 + return x + + res = self.meta_interp(main, [0, 10, 1], listops=True, inline=True) + assert res == main(0, 10, 1) + + def test_directly_call_assembler_virtualizable_force_blackhole(self): + class Thing(object): + def __init__(self, val): + self.val = val + + class Frame(object): + _virtualizable2_ = ['thing'] + + driver = JitDriver(greens = ['codeno'], reds = ['frame', 'i'], + virtualizables = ['frame'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + class SomewhereElse(object): + pass + + somewhere_else = SomewhereElse() + + def change(newthing, arg): + print arg + if arg > 30: + somewhere_else.frame.thing = newthing + arg = 13 + return arg + + def main(codeno): + frame = Frame() + somewhere_else.frame = frame + frame.thing = Thing(0) + portal(codeno, frame) + return frame.thing.val + + def portal(codeno, frame): + i = 0 + while i < 10: + driver.can_enter_jit(frame=frame, codeno=codeno, i=i) + driver.jit_merge_point(frame=frame, codeno=codeno, i=i) + nextval = frame.thing.val + if codeno == 0: + subframe = Frame() + subframe.thing = Thing(nextval) + nextval = portal(1, subframe) + else: + nextval = change(Thing(13), frame.thing.val) + frame.thing = Thing(nextval + 1) + i += 1 + return frame.thing.val + + res = self.meta_interp(main, [0], inline=True, + policy=StopAtXPolicy(change)) + assert res == main(0) + + def test_assembler_call_red_args(self): + driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'], + get_printable_location = lambda codeno : str(codeno), + can_inline = lambda codeno : False) + + def residual(k): + if k > 40: + return 0 + return 1 + + def portal(codeno, k): + i = 0 + while i < 10: + driver.can_enter_jit(codeno=codeno, i=i, k=k) + driver.jit_merge_point(codeno=codeno, i=i, k=k) + if codeno == 2: + k += portal(residual(k), k) + if codeno == 0: + k += 2 + elif codeno == 1: + k += 1 + i += 1 + return k + + res = self.meta_interp(portal, [2, 0], inline=True, + policy=StopAtXPolicy(residual)) + assert res == portal(2, 0) + self.check_loops(call_assembler=2) + + # There is a test which I fail to write. + # * what happens if we call recursive_call while blackholing + # this seems to be completely corner case and not really happening + # in the wild class TestLLtype(RecursiveTests, LLJitMixin): pass Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_resume.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_resume.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_resume.py Mon Jan 25 15:25:48 2010 @@ -12,6 +12,8 @@ rd_frame_info_list = None rd_numb = None rd_consts = [] + rd_virtuals = None + rd_pendingfields = None def test_tag(): assert tag(3, 1) == rffi.r_short(3<<2|1) @@ -40,6 +42,12 @@ assert not tagged_list_eq([tag(1, TAGBOX)], [tag(-2, TAGBOX)]) assert not tagged_list_eq([tag(1, TAGBOX), tag(-2, TAGBOX)], [tag(1, TAGBOX)]) +def test_vinfo(): + v1 = AbstractVirtualInfo() + v1.set_content([1, 2, 4]) + assert v1.equals([1, 2, 4]) + assert not v1.equals([1, 2, 6]) + class MyMetaInterp: _already_allocated_resume_virtuals = None @@ -80,7 +88,6 @@ tag(0, TAGBOX), tag(1, TAGBOX)]) storage.rd_numb = numb - storage.rd_virtuals = None b1s, b2s, b3s = [BoxInt(), BoxPtr(), BoxInt()] assert b1s != b3s @@ -103,7 +110,6 @@ tag(0, TAGBOX), tag(1, TAGBOX)]) storage.rd_numb = numb - storage.rd_virtuals = None b1s, b2s, b3s = [BoxInt(), BoxPtr(), BoxInt()] assert b1s != b3s reader = ResumeDataReader(storage, [b1s, b2s, b3s], MyMetaInterp()) @@ -125,6 +131,7 @@ rd_virtuals = [FakeVinfo(), None] rd_numb = [] rd_consts = [] + rd_pendingfields = None class FakeMetainterp(object): _already_allocated_resume_virtuals = None cpu = None @@ -175,7 +182,6 @@ assert fi.jitcode is jitcode assert fi.pc == 1 assert fi.exception_target == 2 - assert fi.level == 1 jitcode1 = "JITCODE1" frame1 = FakeFrame(jitcode, 3, 4) @@ -184,7 +190,6 @@ assert fi1.jitcode is jitcode assert fi1.pc == 3 assert fi1.exception_target == 4 - assert fi1.level == 2 def test_Numbering_create(): l = [1, 2] @@ -203,29 +208,32 @@ fs = [FakeFrame("code0", 0, -1, b1, c1, b2)] storage = Storage() - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) assert fs[0].parent_resumedata_snapshot is None assert fs[0].parent_resumedata_frame_info_list is None assert storage.rd_frame_info_list.prev is None assert storage.rd_frame_info_list.jitcode == 'code0' - assert storage.rd_snapshot.prev is None - assert storage.rd_snapshot.boxes == fs[0].env - assert storage.rd_snapshot.boxes is not fs[0].env + assert storage.rd_snapshot.boxes == [] # for virtualrefs + snapshot = storage.rd_snapshot.prev + assert snapshot.prev is None + assert snapshot.boxes == fs[0].env + assert snapshot.boxes is not fs[0].env storage = Storage() fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) frame_info_list = storage.rd_frame_info_list assert frame_info_list.prev is fs[2].parent_resumedata_frame_info_list assert frame_info_list.jitcode == 'code2' assert frame_info_list.pc == 9 - snapshot = storage.rd_snapshot + assert storage.rd_snapshot.boxes == [] # for virtualrefs + snapshot = storage.rd_snapshot.prev assert snapshot.prev is fs[2].parent_resumedata_snapshot assert snapshot.boxes == fs[2].env assert snapshot.boxes is not fs[2].env @@ -249,8 +257,9 @@ fs[2].env = [b2, b3] fs[2].pc = 15 vbs = [b1, b2] - capture_resumedata(fs, vbs, storage) - + vrs = [b3] + capture_resumedata(fs, vbs, vrs, storage) + frame_info_list = storage.rd_frame_info_list assert frame_info_list.prev is fs[2].parent_resumedata_frame_info_list assert frame_info_list.jitcode == 'code2' @@ -261,6 +270,10 @@ assert snapshot.boxes is not vbs snapshot = snapshot.prev + assert snapshot.boxes == vrs + assert snapshot.boxes is not vrs + + snapshot = snapshot.prev assert snapshot.prev is fs[2].parent_resumedata_snapshot assert snapshot.boxes == fs[2].env @@ -278,7 +291,7 @@ fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(storage, memo) liveboxes = modifier.finish({}) @@ -289,7 +302,7 @@ result = rebuild_from_resumedata(metainterp, newboxes, storage, False) - assert result is None + assert result == (None, []) fs2 = [FakeFrame("code0", 0, -1, b1t, c1, b2t), FakeFrame("code1", 3, 7, b3t, c2, b1t), FakeFrame("code2", 9, -1, c3, b2t)] @@ -302,7 +315,7 @@ fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] - capture_resumedata(fs, [b4], storage) + capture_resumedata(fs, [b4], [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(storage, memo) liveboxes = modifier.finish({}) @@ -313,7 +326,7 @@ result = rebuild_from_resumedata(metainterp, newboxes, storage, True) - assert result == [b4t] + assert result == ([b4t], []) fs2 = [FakeFrame("code0", 0, -1, b1t, c1, b2t), FakeFrame("code1", 3, 7, b3t, c2, b1t), FakeFrame("code2", 9, -1, c3, b2t)] @@ -326,10 +339,10 @@ fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) storage2 = Storage() fs = fs[:-1] + [FakeFrame("code2", 10, -1, c3, b2, b4)] - capture_resumedata(fs, None, storage2) + capture_resumedata(fs, None, [], storage2) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(storage, memo) @@ -345,7 +358,7 @@ result = rebuild_from_resumedata(metainterp, newboxes, storage, False) - assert result is None + assert result == (None, []) fs2 = [FakeFrame("code0", 0, -1, b1t, c1, b2t), FakeFrame("code1", 3, 7, b3t, c2, b1t), FakeFrame("code2", 9, -1, c3, b2t)] @@ -356,7 +369,7 @@ metainterp.framestack = [] result = rebuild_from_resumedata(metainterp, newboxes, storage2, False) - assert result is None + assert result == (None, []) fs2 = fs2[:-1] + [FakeFrame("code2", 10, -1, c3, b2t, b4t)] assert metainterp.framestack == fs2 @@ -384,10 +397,10 @@ fs = [FakeFrame("code0", 0, -1, b1, c1, b2), FakeFrame("code1", 3, 7, b3, c2, b1), FakeFrame("code2", 9, -1, c3, b2)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) storage2 = Storage() fs = fs[:-1] + [FakeFrame("code2", 10, -1, c3, b2, b4)] - capture_resumedata(fs, None, storage2) + capture_resumedata(fs, None, [], storage2) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) values = {b2: virtual_value(b2, b5, c4)} @@ -443,7 +456,7 @@ LLtypeMixin.nodebox.constbox()] storage = Storage() fs = [FakeFrame("code0", 0, -1, c1, b2, b3)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) values = {b2: virtual_value(b2, b5, c4)} @@ -455,7 +468,7 @@ storage2 = Storage() fs = [FakeFrame("code0", 0, -1, b1, b4, b2)] - capture_resumedata(fs, None, storage2) + capture_resumedata(fs, None, [], storage2) values[b4] = virtual_value(b4, b6, c4) modifier = ResumeDataVirtualAdder(storage2, memo) liveboxes = modifier.finish(values) @@ -468,7 +481,7 @@ b1, b2, b3 = [BoxPtr(), BoxPtr(), BoxInt()] storage = Storage() fs = [FakeFrame("code0", 0, -1, b1, b2)] - capture_resumedata(fs, None, storage) + capture_resumedata(fs, None, [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) v1 = virtual_value(b1, b3, None) @@ -962,6 +975,46 @@ assert ptr.a == 111 assert ptr.b == lltype.nullptr(LLtypeMixin.NODE) + +def test_virtual_adder_pending_fields(): + b2s, b4s = [BoxPtr(), BoxPtr()] + storage = Storage() + memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) + modifier = ResumeDataVirtualAdder(storage, memo) + modifier.liveboxes_from_env = {} + modifier.liveboxes = {} + modifier.vfieldboxes = {} + + v2 = OptValue(b2s) + v4 = OptValue(b4s) + modifier.register_box(b2s) + modifier.register_box(b4s) + + values = {b4s: v4, b2s: v2} + liveboxes = [] + modifier._number_virtuals(liveboxes, values, 0) + assert liveboxes == [b2s, b4s] + modifier._add_pending_fields([(LLtypeMixin.nextdescr, b2s, b4s)]) + storage.rd_consts = memo.consts[:] + storage.rd_numb = None + # resume + demo55.next = lltype.nullptr(LLtypeMixin.NODE) + b2t = BoxPtr(demo55o) + b4t = BoxPtr(demo66o) + newboxes = _resume_remap(liveboxes, [b2s, b4s], b2t, b4t) + + metainterp = MyMetaInterp() + reader = ResumeDataReader(storage, newboxes, metainterp) + assert reader.virtuals is None + trace = metainterp.trace + b2set = (rop.SETFIELD_GC, [b2t, b4t], None, LLtypeMixin.nextdescr) + expected = [b2set] + + for x, y in zip(expected, trace): + assert x == y + assert demo55.next == demo66 + + def test_invalidation_needed(): class options: failargs_limit = 10 Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_virtualizable.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_virtualizable.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_virtualizable.py Mon Jan 25 15:25:48 2010 @@ -28,7 +28,7 @@ hop.inputconst(lltype.Void, hop.args_v[1].value), hop.inputconst(lltype.Void, {})] hop.exception_cannot_occur() - return hop.genop('promote_virtualizable', + return hop.genop('jit_force_virtualizable', args_v, resulttype=lltype.Void) debug_print = lloperation.llop.debug_print @@ -907,6 +907,39 @@ res = self.meta_interp(f, [123], policy=StopAtXPolicy(g)) assert res == f(123) + def test_bridge_forces(self): + jitdriver = JitDriver(greens = [], reds = ['frame'], + virtualizables = ['frame']) + + class Frame(object): + _virtualizable2_ = ['x', 'y'] + class SomewhereElse: + pass + somewhere_else = SomewhereElse() + + def g(): + n = somewhere_else.top_frame.y + 700 + debug_print(lltype.Void, '-+-+-+-+- external write:', n) + somewhere_else.top_frame.y = n + + def f(n): + frame = Frame() + frame.x = n + frame.y = 10 + somewhere_else.counter = 0 + somewhere_else.top_frame = frame + while frame.x > 0: + jitdriver.can_enter_jit(frame=frame) + jitdriver.jit_merge_point(frame=frame) + if frame.y > 17: + g() + frame.x -= 5 + frame.y += 1 + return frame.y + + res = self.meta_interp(f, [123], policy=StopAtXPolicy(g)) + assert res == f(123) + def test_promote_index_in_virtualizable_list(self): jitdriver = JitDriver(greens = [], reds = ['frame', 'n'], virtualizables = ['frame']) @@ -980,9 +1013,11 @@ for block, op in graph.iterblockops() if op.opname == 'direct_call'] - assert direct_calls(f_graph) == ['__init__', 'force_if_necessary', 'll_portal_runner'] - assert direct_calls(portal_graph) == ['force_if_necessary', 'maybe_enter_jit'] - + assert direct_calls(f_graph) == ['__init__', + 'force_virtualizable_if_necessary', + 'll_portal_runner'] + assert direct_calls(portal_graph)==['force_virtualizable_if_necessary', + 'maybe_enter_jit'] assert direct_calls(init_graph) == [] def test_virtual_child_frame(self): @@ -1158,8 +1193,9 @@ self.check_loops(getfield_gc=0, setfield_gc=0) def test_blackhole_should_not_reenter(self): - from pypy.jit.backend.test.support import BaseCompiledMixin - if isinstance(self, BaseCompiledMixin): + # Armin thinks this can occur and does not make interpreters slower + # so we don't check for assertionerror, to be discussed + if not self.basic: py.test.skip("purely frontend test") myjitdriver = JitDriver(greens = [], reds = ['frame', 'fail'], @@ -1200,8 +1236,9 @@ f(10, True) return f(10, False) - einfo = py.test.raises(AssertionError, self.meta_interp, main, []) - assert einfo.value.args[0] == "reentering same frame via blackhole" + self.meta_interp(main, []) + #einfo = py.test.raises(AssertionError, self.meta_interp, main, []) + #assert einfo.value.args[0] == "reentering same frame via blackhole" def test_inlining(self): class Frame(object): Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmspot.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmspot.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmspot.py Mon Jan 25 15:25:48 2010 @@ -4,6 +4,7 @@ from pypy.rlib.jit import JitDriver, OPTIMIZER_FULL, OPTIMIZER_SIMPLE from pypy.rlib.jit import unroll_safe from pypy.jit.backend.llgraph import runner +from pypy.jit.metainterp.history import BoxInt from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin @@ -283,3 +284,80 @@ class TestOOWarmspot(WarmspotTests, OOJitMixin): CPUClass = runner.OOtypeCPU type_system = 'ootype' + +class TestWarmspotDirect(object): + def setup_class(cls): + from pypy.jit.metainterp.typesystem import llhelper + from pypy.jit.metainterp.support import annotate + from pypy.jit.metainterp.warmspot import WarmRunnerDesc + from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE + from pypy.rpython.lltypesystem import lltype, llmemory + exc_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) + cls.exc_vtable = exc_vtable + + class FakeFailDescr(object): + def __init__(self, no): + self.no = no + + def handle_fail(self, metainterp_sd): + if self.no == 0: + raise metainterp_sd.warmrunnerdesc.DoneWithThisFrameInt(3) + if self.no == 1: + raise metainterp_sd.warmrunnerdesc.ContinueRunningNormally( + [BoxInt(0), BoxInt(1)]) + if self.no == 3: + exc = lltype.malloc(OBJECT) + exc.typeptr = exc_vtable + raise metainterp_sd.warmrunnerdesc.ExitFrameWithExceptionRef( + metainterp_sd.cpu, + lltype.cast_opaque_ptr(llmemory.GCREF, exc)) + return self.no + + class FakeCPU(object): + supports_floats = False + ts = llhelper + translate_support_code = False + + def __init__(self, *args, **kwds): + pass + + def nodescr(self, *args, **kwds): + pass + fielddescrof = nodescr + calldescrof = nodescr + sizeof = nodescr + + def get_fail_descr_from_number(self, no): + return FakeFailDescr(no) + + def execute_token(self, token): + assert token == 2 + return FakeFailDescr(1) + + driver = JitDriver(reds = ['red'], greens = ['green']) + + def f(green): + red = 0 + while red < 10: + driver.can_enter_jit(red=red, green=green) + driver.jit_merge_point(red=red, green=green) + red += 1 + return red + + rtyper = annotate(f, [0]) + translator = rtyper.annotator.translator + translator.config.translation.gc = 'hybrid' + cls.desc = WarmRunnerDesc(translator, CPUClass=FakeCPU) + + def test_call_helper(self): + from pypy.rpython.llinterp import LLException + + assert self.desc.assembler_call_helper(0, 0) == 3 + assert self.desc.assembler_call_helper(1, 0) == 10 + assert self.desc.assembler_call_helper(2, 0) == 10 + try: + self.desc.assembler_call_helper(3, 0) + except LLException, lle: + assert lle[0] == self.exc_vtable + else: + py.test.fail("DID NOT RAISE") Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmstate.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmstate.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmstate.py Mon Jan 25 15:25:48 2010 @@ -165,6 +165,7 @@ class FakeWarmRunnerDesc: can_inline_ptr = None get_printable_location_ptr = None + confirm_enter_jit_ptr = None green_args_spec = [lltype.Signed, lltype.Float] class FakeCell: dont_trace_here = False @@ -192,6 +193,7 @@ green_args_spec = [lltype.Signed, lltype.Float] can_inline_ptr = llhelper(CAN_INLINE, can_inline) get_printable_location_ptr = None + confirm_enter_jit_ptr = None state = WarmEnterState(FakeWarmRunnerDesc()) def jit_getter(*args): return FakeCell() @@ -212,7 +214,30 @@ green_args_spec = [lltype.Signed, lltype.Float] can_inline_ptr = None get_printable_location_ptr = llhelper(GET_LOCATION, get_location) + confirm_enter_jit_ptr = None + get_jitcell_at_ptr = None state = WarmEnterState(FakeWarmRunnerDesc()) state.make_jitdriver_callbacks() res = state.get_location_str([BoxInt(5), BoxFloat(42.5)]) assert res == "hi there" + +def test_make_jitdriver_callbacks_4(): + def confirm_enter_jit(x, y, z): + assert x == 5 + assert y == 42.5 + assert z == 3 + return True + ENTER_JIT = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Float, + lltype.Signed], lltype.Bool)) + class FakeWarmRunnerDesc: + rtyper = None + green_args_spec = [lltype.Signed, lltype.Float] + can_inline_ptr = None + get_printable_location_ptr = None + confirm_enter_jit_ptr = llhelper(ENTER_JIT, confirm_enter_jit) + get_jitcell_at_ptr = None + + state = WarmEnterState(FakeWarmRunnerDesc()) + state.make_jitdriver_callbacks() + res = state.confirm_enter_jit(5, 42.5, 3) + assert res is True Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_ztranslation.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_ztranslation.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_ztranslation.py Mon Jan 25 15:25:48 2010 @@ -7,6 +7,8 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype +py.test.skip("Broken") + class TranslationTest: CPUClass = None Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/virtualizable.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/virtualizable.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/virtualizable.py Mon Jan 25 15:25:48 2010 @@ -11,8 +11,8 @@ class VirtualizableInfo: - token_none = 0 - token_tracing = -1 + TOKEN_NONE = 0 + TOKEN_TRACING_RESCALL = -1 def __init__(self, warmrunnerdesc): self.warmrunnerdesc = warmrunnerdesc @@ -153,16 +153,17 @@ def finish(self): # - def force_if_necessary(virtualizable): + def force_virtualizable_if_necessary(virtualizable): if virtualizable.vable_token: self.force_now(virtualizable) - force_if_necessary._always_inline_ = True + force_virtualizable_if_necessary._always_inline_ = True # all_graphs = self.warmrunnerdesc.translator.graphs ts = self.warmrunnerdesc.cpu.ts (_, FUNCPTR) = ts.get_FuncType([self.VTYPEPTR], lltype.Void) - funcptr = self.warmrunnerdesc.helper_func(FUNCPTR, force_if_necessary) - rvirtualizable2.replace_promote_virtualizable_with_call( + funcptr = self.warmrunnerdesc.helper_func( + FUNCPTR, force_virtualizable_if_necessary) + rvirtualizable2.replace_force_virtualizable_with_call( all_graphs, self.VTYPEPTR, funcptr) def unwrap_virtualizable_box(self, virtualizable_box): @@ -176,7 +177,7 @@ return rvirtualizable2.match_virtualizable_type(TYPE, self.VTYPEPTR) def reset_vable_token(self, virtualizable): - virtualizable.vable_token = self.token_none + virtualizable.vable_token = self.TOKEN_NONE def clear_vable_token(self, virtualizable): if virtualizable.vable_token: @@ -185,14 +186,14 @@ def tracing_before_residual_call(self, virtualizable): assert not virtualizable.vable_token - virtualizable.vable_token = self.token_tracing + virtualizable.vable_token = self.TOKEN_TRACING_RESCALL def tracing_after_residual_call(self, virtualizable): if virtualizable.vable_token: # not modified by the residual call; assert that it is still - # set to 'tracing_vable_rti' and clear it. - assert virtualizable.vable_token == self.token_tracing - virtualizable.vable_token = self.token_none + # set to TOKEN_TRACING_RESCALL and clear it. + assert virtualizable.vable_token == self.TOKEN_TRACING_RESCALL + virtualizable.vable_token = self.TOKEN_NONE return False else: # marker "modified during residual call" set. @@ -200,32 +201,36 @@ def force_now(self, virtualizable): token = virtualizable.vable_token - virtualizable.vable_token = self.token_none - if token == self.token_tracing: + if token == self.TOKEN_TRACING_RESCALL: # The values in the virtualizable are always correct during - # tracing. We only need to reset vable_token to token_none + # tracing. We only need to reset vable_token to TOKEN_NONE # as a marker for the tracing, to tell it that this # virtualizable escapes. - pass + virtualizable.vable_token = self.TOKEN_NONE else: from pypy.jit.metainterp.compile import ResumeGuardForcedDescr - faildescr = self.cpu.force(token) - assert isinstance(faildescr, ResumeGuardForcedDescr) - faildescr.force_virtualizable(self, virtualizable, token) + ResumeGuardForcedDescr.force_now(self.cpu, token) + assert virtualizable.vable_token == self.TOKEN_NONE force_now._dont_inline_ = True + def forced_vable(self, virtualizable_boxes): + virtualizable_box = virtualizable_boxes[-1] + virtualizable = self.unwrap_virtualizable_box(virtualizable_box) + self.write_boxes(virtualizable, virtualizable_boxes) + virtualizable.vable_token = self.TOKEN_NONE + # ____________________________________________________________ # # The 'vable_token' field of a virtualizable is either 0, -1, or points # into the CPU stack to a particular field in the current frame. It is: # -# 1. 0 (token_none) if not in the JIT at all, except as described below. +# 1. 0 (TOKEN_NONE) if not in the JIT at all, except as described below. # # 2. equal to 0 when tracing is in progress; except: # -# 3. equal to -1 (token_tracing) during tracing when we do a residual call, -# calling random unknown other parts of the interpreter; it is -# reset to 0 as soon as something occurs to the virtualizable. +# 3. equal to -1 (TOKEN_TRACING_RESCALL) during tracing when we do a +# residual call, calling random unknown other parts of the interpreter; +# it is reset to 0 as soon as something occurs to the virtualizable. # # 4. when running the machine code with a virtualizable, it is set # to the address in the CPU stack by the FORCE_TOKEN operation. Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/warmspot.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/warmspot.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/warmspot.py Mon Jan 25 15:25:48 2010 @@ -1,4 +1,4 @@ -import sys +import sys, py from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr from pypy.rpython.ootypesystem import ootype from pypy.rpython.annlowlevel import llhelper, MixLevelHelperAnnotator,\ @@ -11,7 +11,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.rarithmetic import r_uint, intmask -from pypy.rlib.debug import debug_print +from pypy.rlib.debug import debug_print, fatalerror from pypy.rpython.lltypesystem.lloperation import llop from pypy.translator.simplify import get_funcobj, get_functype from pypy.translator.unsimplify import call_final_function @@ -140,7 +140,7 @@ # ____________________________________________________________ -class WarmRunnerDesc: +class WarmRunnerDesc(object): def __init__(self, translator, policy=None, backendopt=True, CPUClass=None, optimizer=None, **kwds): @@ -162,9 +162,13 @@ self.build_meta_interp(CPUClass, **kwds) self.make_args_specification() + # + from pypy.jit.metainterp.virtualref import VirtualRefInfo + self.metainterp_sd.virtualref_info = VirtualRefInfo(self) if self.jitdriver.virtualizables: from pypy.jit.metainterp.virtualizable import VirtualizableInfo self.metainterp_sd.virtualizable_info = VirtualizableInfo(self) + # self.make_exception_classes() self.make_driverhook_graphs() self.make_enter_function() @@ -177,6 +181,7 @@ ) self.rewrite_can_enter_jit() self.rewrite_set_param() + self.rewrite_force_virtual() self.add_profiler_finish() self.metainterp_sd.finish_setup(optimizer=optimizer) @@ -339,9 +344,7 @@ if sys.stdout == sys.__stdout__: import pdb; pdb.post_mortem(sys.exc_info()[2]) raise - debug_print('~~~ Crash in JIT!') - debug_print('~~~ %s' % (e,)) - raise history.CrashInJIT("crash in JIT") + fatalerror('~~~ Crash in JIT! %s' % (e,), traceback=True) crash_in_jit._dont_inline_ = True if self.translator.rtyper.type_system.name == 'lltypesystem': @@ -397,9 +400,13 @@ annhelper, self.jitdriver.can_inline, annmodel.s_Bool) self.get_printable_location_ptr = self._make_hook_graph( annhelper, self.jitdriver.get_printable_location, s_Str) + self.confirm_enter_jit_ptr = self._make_hook_graph( + annhelper, self.jitdriver.confirm_enter_jit, annmodel.s_Bool, + onlygreens=False) annhelper.finish() - def _make_hook_graph(self, annhelper, func, s_result, s_first_arg=None): + def _make_hook_graph(self, annhelper, func, s_result, s_first_arg=None, + onlygreens=True): if func is None: return None # @@ -407,7 +414,9 @@ if s_first_arg is not None: extra_args_s.append(s_first_arg) # - args_s = self.portal_args_s[:len(self.green_args_spec)] + args_s = self.portal_args_s + if onlygreens: + args_s = args_s[:len(self.green_args_spec)] graph = annhelper.getgraph(func, extra_args_s + args_s, s_result) funcptr = annhelper.graph2delayed(graph) return funcptr @@ -432,7 +441,8 @@ self.PTR_JIT_ENTER_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, lltype.Void) (self.PORTAL_FUNCTYPE, self.PTR_PORTAL_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, RESTYPE) - + (_, self.PTR_ASSEMBLER_HELPER_FUNCTYPE) = self.cpu.ts.get_FuncType( + [lltype.Signed, llmemory.GCREF], RESTYPE) def rewrite_can_enter_jit(self): FUNC = self.JIT_ENTER_FUNCTYPE @@ -545,9 +555,63 @@ else: value = cast_base_ptr_to_instance(Exception, value) raise Exception, value - + + self.ll_portal_runner = ll_portal_runner # for debugging self.portal_runner_ptr = self.helper_func(self.PTR_PORTAL_FUNCTYPE, ll_portal_runner) + self.cpu.portal_calldescr = self.cpu.calldescrof( + self.PTR_PORTAL_FUNCTYPE.TO, + self.PTR_PORTAL_FUNCTYPE.TO.ARGS, + self.PTR_PORTAL_FUNCTYPE.TO.RESULT) + + vinfo = self.metainterp_sd.virtualizable_info + + def assembler_call_helper(failindex, virtualizableref): + fail_descr = self.cpu.get_fail_descr_from_number(failindex) + while True: + try: + if vinfo is not None: + virtualizable = lltype.cast_opaque_ptr( + vinfo.VTYPEPTR, virtualizableref) + vinfo.reset_vable_token(virtualizable) + loop_token = fail_descr.handle_fail(self.metainterp_sd) + fail_descr = self.cpu.execute_token(loop_token) + except self.ContinueRunningNormally, e: + args = () + for _, name, _ in portalfunc_ARGS: + v = getattr(e, name) + args = args + (v,) + return ll_portal_runner(*args) + except self.DoneWithThisFrameVoid: + assert result_kind == 'void' + return + except self.DoneWithThisFrameInt, e: + assert result_kind == 'int' + return lltype.cast_primitive(RESULT, e.result) + except self.DoneWithThisFrameRef, e: + assert result_kind == 'ref' + return ts.cast_from_ref(RESULT, e.result) + except self.DoneWithThisFrameFloat, e: + assert result_kind == 'float' + return e.result + except self.ExitFrameWithExceptionRef, e: + value = ts.cast_to_baseclass(e.value) + if not we_are_translated(): + raise LLException(ts.get_typeptr(value), value) + else: + value = cast_base_ptr_to_instance(Exception, value) + raise Exception, value + + self.assembler_call_helper = assembler_call_helper # for debugging + self.cpu.assembler_helper_ptr = self.helper_func( + self.PTR_ASSEMBLER_HELPER_FUNCTYPE, + assembler_call_helper) + # XXX a bit ugly sticking + if vinfo is not None: + self.cpu.index_of_virtualizable = (vinfo.index_of_virtualizable - + self.num_green_args) + else: + self.cpu.index_of_virtualizable = -1 # ____________________________________________________________ # Now mutate origportalgraph to end with a call to portal_runner_ptr @@ -599,6 +663,13 @@ op.opname = 'direct_call' op.args[:3] = [closures[funcname]] + def rewrite_force_virtual(self): + if self.cpu.ts.name != 'lltype': + py.test.skip("rewrite_force_virtual: port it to ootype") + all_graphs = self.translator.graphs + vrefinfo = self.metainterp_sd.virtualref_info + vrefinfo.replace_force_virtual_with_call(all_graphs) + def decode_hp_hint_args(op): # Returns (list-of-green-vars, list-of-red-vars) without Voids. Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/warmstate.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/warmstate.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/warmstate.py Mon Jan 25 15:25:48 2010 @@ -196,6 +196,7 @@ get_jitcell = self.make_jitcell_getter() set_future_values = self.make_set_future_values() self.make_jitdriver_callbacks() + confirm_enter_jit = self.confirm_enter_jit def maybe_compile_and_run(*args): """Entry point to the JIT. Called at the point with the @@ -211,8 +212,8 @@ if vinfo is not None: virtualizable = args[vinfo.index_of_virtualizable] virtualizable = vinfo.cast_to_vtype(virtualizable) - assert virtualizable != globaldata.blackhole_virtualizable, ( - "reentering same frame via blackhole") + if globaldata.blackhole_virtualizable == virtualizable: + return else: virtualizable = None @@ -227,6 +228,9 @@ cell.counter = n return # bound reached; start tracing + if not confirm_enter_jit(*args): + cell.counter = 0 + return from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) try: @@ -237,6 +241,8 @@ self.disable_noninlinable_function(metainterp) raise else: + if not confirm_enter_jit(*args): + return # machine code was already compiled for these greenargs # get the assembler and fill in the boxes set_future_values(*args[num_green_args:]) @@ -252,7 +258,7 @@ if vinfo is not None: vinfo.reset_vable_token(virtualizable) loop_token = fail_descr.handle_fail(metainterp_sd) - + maybe_compile_and_run._dont_inline_ = True self.maybe_compile_and_run = maybe_compile_and_run return maybe_compile_and_run @@ -448,6 +454,7 @@ unwrap_greenkey = self.make_unwrap_greenkey() if can_inline_ptr is None: def can_inline_callable(*greenargs): + # XXX shouldn't it be False by default? return True else: rtyper = self.warmrunnerdesc.rtyper @@ -465,7 +472,16 @@ greenargs = unwrap_greenkey(greenkey) return can_inline(*greenargs) self.can_inline_callable = can_inline_greenkey - + + get_jitcell = self.make_jitcell_getter() + def get_assembler_token(greenkey): + greenargs = unwrap_greenkey(greenkey) + cell = get_jitcell(*greenargs) + if cell.counter >= 0: + return None + return cell.entry_loop_token + self.get_assembler_token = get_assembler_token + # get_location_ptr = self.warmrunnerdesc.get_printable_location_ptr if get_location_ptr is None: @@ -483,3 +499,16 @@ res = hlstr(res) return res self.get_location_str = get_location_str + # + confirm_enter_jit_ptr = self.warmrunnerdesc.confirm_enter_jit_ptr + if confirm_enter_jit_ptr is None: + def confirm_enter_jit(*args): + return True + else: + rtyper = self.warmrunnerdesc.rtyper + # + def confirm_enter_jit(*args): + fn = support.maybe_on_top_of_llinterp(rtyper, + confirm_enter_jit_ptr) + return fn(*args) + self.confirm_enter_jit = confirm_enter_jit Modified: pypy/branch/stringbuilder2/pypy/jit/tool/jitoutput.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/tool/jitoutput.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/tool/jitoutput.py Mon Jan 25 15:25:48 2010 @@ -26,8 +26,12 @@ (('opt_ops',), '^opt ops:\s+(\d+)$'), (('opt_guards',), '^opt guards:\s+(\d+)$'), (('forcings',), '^forcings:\s+(\d+)$'), - (('trace_too_long',), '^trace too long:\s+(\d+)$'), - (('bridge_abort',), '^bridge abort:\s+(\d+)$'), + (('abort.trace_too_long',), '^abort: trace too long:\s+(\d+)$'), + (('abort.compiling',), '^abort: compiling:\s+(\d+)$'), + (('abort.vable_escape',), '^abort: vable escape:\s+(\d+)$'), + (('nvirtuals',), '^nvirtuals:\s+(\d+)$'), + (('nvholes',), '^nvholes:\s+(\d+)$'), + (('nvreused',), '^nvreused:\s+(\d+)$'), ] class Ops(object): @@ -35,6 +39,11 @@ calls = 0 pure_calls = 0 +class Aborts(object): + trace_too_long = 0 + compiling = 0 + vable_escape = 0 + class OutputInfo(object): tracing_no = 0 tracing_time = 0.0 @@ -45,13 +54,16 @@ guards = 0 opt_ops = 0 opt_guards = 0 - trace_too_long = 0 - bridge_abort = 0 + forcings = 0 + nvirtuals = 0 + nvholes = 0 + nvreused = 0 def __init__(self): self.ops = Ops() self.recorded_ops = Ops() self.blackholed_ops = Ops() + self.abort = Aborts() def parse_prof(output): lines = output.splitlines() Modified: pypy/branch/stringbuilder2/pypy/jit/tool/showstats.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/tool/showstats.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/tool/showstats.py Mon Jan 25 15:25:48 2010 @@ -1,4 +1,6 @@ #!/usr/bin/env python +from __future__ import division + import autopath import sys, py from pypy.tool import logparser @@ -9,7 +11,7 @@ def main(argv): log = logparser.parse_log_file(argv[0]) parts = logparser.extract_category(log, "jit-log-opt-") - for oplist in parts: + for i, oplist in enumerate(parts): loop = parse(oplist, no_namespace=True) num_ops = 0 num_dmp = 0 @@ -21,7 +23,7 @@ num_ops += 1 if op.is_guard(): num_guards += 1 - print "Loop, length: %d, opcodes: %d, guards: %d" % (num_ops, num_dmp, num_guards) + print "Loop #%d, length: %d, opcodes: %d, guards: %d, %f" % (i, num_ops, num_dmp, num_guards, num_ops/num_dmp) if __name__ == '__main__': main(sys.argv[1:]) Modified: pypy/branch/stringbuilder2/pypy/jit/tool/test/test_jitoutput.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/tool/test/test_jitoutput.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/tool/test/test_jitoutput.py Mon Jan 25 15:25:48 2010 @@ -46,8 +46,6 @@ assert info.opt_ops == 6 assert info.opt_guards == 1 assert info.forcings == 0 - assert info.trace_too_long == 0 - assert info.bridge_abort == 0 DATA = '''Tracing: 1 0.006992 Backend: 1 0.000525 @@ -66,8 +64,12 @@ opt ops: 6 opt guards: 1 forcings: 1 -trace too long: 2 -bridge abort: 3 +abort: trace too long: 10 +abort: compiling: 11 +abort: vable escape: 12 +nvirtuals: 13 +nvholes: 14 +nvreused: 15 ''' def test_parse(): @@ -90,5 +92,9 @@ assert info.opt_ops == 6 assert info.opt_guards == 1 assert info.forcings == 1 - assert info.trace_too_long == 2 - assert info.bridge_abort == 3 + assert info.abort.trace_too_long == 10 + assert info.abort.compiling == 11 + assert info.abort.vable_escape == 12 + assert info.nvirtuals == 13 + assert info.nvholes == 14 + assert info.nvreused == 15 Modified: pypy/branch/stringbuilder2/pypy/lib/_ctypes/array.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/lib/_ctypes/array.py (original) +++ pypy/branch/stringbuilder2/pypy/lib/_ctypes/array.py Mon Jan 25 15:25:48 2010 @@ -90,7 +90,7 @@ def _CData_retval(self, resbuffer): raise NotImplementedError - def _CData_value(self, value): + def from_param(self, value): # array accepts very strange parameters as part of structure # or function argument... from ctypes import c_char, c_wchar @@ -104,7 +104,7 @@ if len(value) > self._length_: raise RuntimeError("Invalid length") value = self(*value) - return _CDataMeta._CData_value(self, value) + return _CDataMeta.from_param(self, value) def array_get_slice_params(self, index): if index.step is not None: Modified: pypy/branch/stringbuilder2/pypy/lib/_ctypes/primitive.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/lib/_ctypes/primitive.py (original) +++ pypy/branch/stringbuilder2/pypy/lib/_ctypes/primitive.py Mon Jan 25 15:25:48 2010 @@ -290,6 +290,8 @@ self.value = value def _ensure_objects(self): + if self._type_ in 'zZ': + return self._objects return None def _getvalue(self): Modified: pypy/branch/stringbuilder2/pypy/lib/_ctypes/structure.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/lib/_ctypes/structure.py (original) +++ pypy/branch/stringbuilder2/pypy/lib/_ctypes/structure.py Mon Jan 25 15:25:48 2010 @@ -130,10 +130,10 @@ def _alignmentofinstances(self): return self._ffistruct.alignment - def _CData_value(self, value): + def from_param(self, value): if isinstance(value, tuple): value = self(*value) - return _CDataMeta._CData_value(self, value) + return _CDataMeta.from_param(self, value) def _CData_output(self, resarray, base=None, index=-1): res = self.__new__(self) @@ -183,10 +183,11 @@ fieldtype = self._fieldtypes[name].ctype except KeyError: return _CData.__setattr__(self, name, value) - if ensure_objects(value) is not None: + cobj = fieldtype.from_param(value) + if ensure_objects(cobj) is not None: key = keepalive_key(getattr(self.__class__, name).num) - store_reference(self, key, value._objects) - arg = fieldtype._CData_value(value) + store_reference(self, key, cobj._objects) + arg = cobj._get_buffer_value() if fieldtype._fficompositesize is not None: from ctypes import memmove dest = self._buffer.fieldaddress(name) Modified: pypy/branch/stringbuilder2/pypy/lib/_ctypes/union.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/lib/_ctypes/union.py (original) +++ pypy/branch/stringbuilder2/pypy/lib/_ctypes/union.py Mon Jan 25 15:25:48 2010 @@ -99,10 +99,11 @@ fieldtype = self._fieldtypes[name].ctype except KeyError: raise AttributeError(name) - if ensure_objects(value) is not None: + cobj = fieldtype.from_param(value) + if ensure_objects(cobj) is not None: key = keepalive_key(getattr(self.__class__, name).num) - store_reference(self, key, value._objects) - arg = fieldtype._CData_value(value) + store_reference(self, key, cobj._objects) + arg = cobj._get_buffer_value() if fieldtype._fficompositesize is not None: from ctypes import memmove dest = self._buffer.buffer Modified: pypy/branch/stringbuilder2/pypy/lib/app_test/ctypes_tests/test_keepalive.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/lib/app_test/ctypes_tests/test_keepalive.py (original) +++ pypy/branch/stringbuilder2/pypy/lib/app_test/ctypes_tests/test_keepalive.py Mon Jan 25 15:25:48 2010 @@ -205,3 +205,50 @@ s.r = r # obscure assert s._objects == {'1': {}, '0:1': {'1': stuff}} + + def test_c_char_p(self): + n = 2 + xs = "hello" * n + x = c_char_p(xs) + del xs + import gc; gc.collect() + print 'x =', repr(x) + assert x.value == 'hellohello' + assert x._objects.keys() == ['0'] + # + class datum(Structure): + _fields_ = [ + ('dptr', c_char_p), + ('dsize', c_int), + ] + class union(Union): + _fields_ = [ + ('dptr', c_char_p), + ('dsize', c_int), + ] + for wrap in [False, True]: + n = 2 + xs = "hello" * n + if wrap: + xs = c_char_p(xs) + dat = datum() + dat.dptr = xs + dat.dsize = 15 + del xs + import gc; gc.collect() + print 'dat.dptr =', repr(dat.dptr) + print 'dat._objects =', repr(dat._objects) + assert dat.dptr == "hellohello" + assert dat._objects.keys() == ['0'] + + xs = "hello" * n + if wrap: + xs = c_char_p(xs) + dat = union() + dat.dptr = xs + del xs + import gc; gc.collect() + print 'dat.dptr =', repr(dat.dptr) + print 'dat._objects =', repr(dat._objects) + assert dat.dptr == "hellohello" + assert dat._objects.keys() == ['0'] Modified: pypy/branch/stringbuilder2/pypy/lib/app_test/test_runpy.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/lib/app_test/test_runpy.py (original) +++ pypy/branch/stringbuilder2/pypy/lib/app_test/test_runpy.py Mon Jan 25 15:25:48 2010 @@ -102,7 +102,7 @@ if verbose: print " Next level in:", sub_dir pkg_fname = os.path.join(sub_dir, init_fname) pkg_file = open(pkg_fname, "w") - pkg_file.write("__path__ = ['%s']\n" % sub_dir) + pkg_file.write("__path__ = [%r]\n" % sub_dir) pkg_file.close() if verbose: print " Created:", pkg_fname mod_fname = os.path.join(sub_dir, test_fname) @@ -137,6 +137,12 @@ d1 = run_module(mod_name) # Read from source __import__(mod_name) os.remove(mod_fname) + + #--- the block below is to check that "imp.find_module" + #--- manages to import the .pyc file alone. We don't + #--- support it in PyPy in the default configuration. + return + if verbose: print "Running from compiled:", mod_name d2 = run_module(mod_name) # Read from bytecode finally: Modified: pypy/branch/stringbuilder2/pypy/module/__builtin__/__init__.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/__builtin__/__init__.py (original) +++ pypy/branch/stringbuilder2/pypy/module/__builtin__/__init__.py Mon Jan 25 15:25:48 2010 @@ -1,6 +1,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter import module from pypy.interpreter.mixedmodule import MixedModule +import pypy.module.imp.importing # put builtins here that should be optimized somehow @@ -35,9 +36,6 @@ 'vars' : 'app_inspect.vars', 'dir' : 'app_inspect.dir', - '_find_module' : 'app_misc.find_module', - 'reload' : 'app_misc.reload', - '__filestub' : 'app_file_stub.file', } @@ -88,7 +86,8 @@ 'compile' : 'compiling.compile', 'eval' : 'compiling.eval', - '__import__' : 'importing.importhook', + '__import__' : 'pypy.module.imp.importing.importhook', + 'reload' : 'pypy.module.imp.importing.reload', 'range' : 'functional.range_int', 'xrange' : 'functional.W_XRange', @@ -152,16 +151,3 @@ space.exception_is_valid_obj_as_class_w = ab.exception_is_valid_obj_as_class_w.__get__(space) space.exception_getclass = ab.exception_getclass.__get__(space) space.exception_issubclass_w = ab.exception_issubclass_w.__get__(space) - - def startup(self, space): - # install zipimport hook if --withmod-zipimport is used - if space.config.objspace.usemodules.zipimport: - w_import = space.builtin.get('__import__') - w_zipimport = space.call(w_import, space.newlist( - [space.wrap('zipimport')])) - w_sys = space.getbuiltinmodule('sys') - w_path_hooks = space.getattr(w_sys, space.wrap('path_hooks')) - w_append = space.getattr(w_path_hooks, space.wrap('append')) - w_zipimporter = space.getattr(w_zipimport, - space.wrap('zipimporter')) - space.call(w_append, space.newlist([w_zipimporter])) Modified: pypy/branch/stringbuilder2/pypy/module/__builtin__/descriptor.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/__builtin__/descriptor.py (original) +++ pypy/branch/stringbuilder2/pypy/module/__builtin__/descriptor.py Mon Jan 25 15:25:48 2010 @@ -4,7 +4,7 @@ Arguments from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError -from pypy.objspace.descroperation import object_getattribute +from pypy.objspace.descroperation import object_getattribute, object_setattr from pypy.interpreter.function import StaticMethod, ClassMethod from pypy.interpreter.typedef import GetSetProperty, descr_get_dict, \ descr_set_dict, interp_attrproperty_w @@ -153,8 +153,11 @@ # XXX kill me? This is mostly to make tests happy, raising # a TypeError instead of an AttributeError and using "readonly" # instead of "read-only" in the error message :-/ - raise OperationError(space.w_TypeError, space.wrap( - "Trying to set readonly attribute %s on property" % (attr,))) + if attr in ["__doc__", "fget", "fset", "fdel"]: + raise OperationError(space.w_TypeError, space.wrap( + "Trying to set readonly attribute %s on property" % (attr,))) + return space.call_function(object_setattr(space), + space.wrap(self), space.wrap(attr), w_value) setattr.unwrap_spec = ['self', ObjSpace, str, W_Root] W_Property.typedef = TypeDef( Modified: pypy/branch/stringbuilder2/pypy/module/__builtin__/test/test_descriptor.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/__builtin__/test/test_descriptor.py (original) +++ pypy/branch/stringbuilder2/pypy/module/__builtin__/test/test_descriptor.py Mon Jan 25 15:25:48 2010 @@ -301,3 +301,13 @@ pass else: raise Exception, "expected ZeroDivisionError from bad property" + + def test_property_subclass(self): + class P(property): + pass + + p = P() + p.name = 0 + assert p.name == 0 + + Modified: pypy/branch/stringbuilder2/pypy/module/__pypy__/__init__.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/__pypy__/__init__.py (original) +++ pypy/branch/stringbuilder2/pypy/module/__pypy__/__init__.py Mon Jan 25 15:25:48 2010 @@ -1,7 +1,7 @@ # Package initialisation from pypy.interpreter.mixedmodule import MixedModule -from pypy.module.__builtin__.importing import get_pyc_magic +from pypy.module.imp.importing import get_pyc_magic class Module(MixedModule): appleveldefs = { Modified: pypy/branch/stringbuilder2/pypy/module/_demo/__init__.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/_demo/__init__.py (original) +++ pypy/branch/stringbuilder2/pypy/module/_demo/__init__.py Mon Jan 25 15:25:48 2010 @@ -12,3 +12,13 @@ appleveldefs = { 'DemoError' : 'app_demo.DemoError', } + + # Used in tests + demo_events = [] + def setup_after_space_initialization(self): + Module.demo_events.append('setup') + def startup(self, space): + Module.demo_events.append('startup') + def shutdown(self, space): + Module.demo_events.append('shutdown') + Modified: pypy/branch/stringbuilder2/pypy/module/_stackless/interp_coroutine.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/_stackless/interp_coroutine.py (original) +++ pypy/branch/stringbuilder2/pypy/module/_stackless/interp_coroutine.py Mon Jan 25 15:25:48 2010 @@ -275,11 +275,10 @@ return space.newtuple([]) items = [None] * index f = self.subctx.topframe - f.force_f_back() while index > 0: index -= 1 items[index] = space.wrap(f) - f = f.f_back() + f = f.f_backref() assert f is None return space.newtuple(items) Modified: pypy/branch/stringbuilder2/pypy/module/oracle/__init__.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/oracle/__init__.py (original) +++ pypy/branch/stringbuilder2/pypy/module/oracle/__init__.py Mon Jan 25 15:25:48 2010 @@ -39,6 +39,7 @@ def startup(self, space): from pypy.module.oracle.interp_error import get state = get(space) + state.startup(space) (state.w_DecimalType, state.w_DateTimeType, state.w_DateType, state.w_TimedeltaType, ) = space.fixedview(space.appexec([], """(): Modified: pypy/branch/stringbuilder2/pypy/module/oracle/interp_error.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/oracle/interp_error.py (original) +++ pypy/branch/stringbuilder2/pypy/module/oracle/interp_error.py Mon Jan 25 15:25:48 2010 @@ -4,32 +4,47 @@ from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError + from pypy.module.oracle import roci, config +from pypy.rlib.unroll import unrolling_iterable + +exported_names = unrolling_iterable(""" + DatabaseError OperationalError InterfaceError ProgrammingError + NotSupportedError IntegrityError InternalError DataError + Variable Connection""".split()) class State: # XXX move to another file + def __init__(self, space): - w_module = space.getbuiltinmodule('cx_Oracle') - def get(name): - return space.getattr(w_module, space.wrap(name)) + "NOT_RPYTHON" + self.variableTypeByPythonType = {} + self.w_DecimalType = None + self.w_DateTimeType = None + self.w_DateType = None + self.w_TimedeltaType = None - self.w_DatabaseError = get('DatabaseError') - self.w_OperationalError = get('OperationalError') - self.w_InterfaceError = get('InterfaceError') - self.w_ProgrammingError = get('ProgrammingError') - self.w_NotSupportedError = get('NotSupportedError') - self.w_IntegrityError = get('IntegrityError') - self.w_InternalError = get('InternalError') - self.w_DataError = get('DataError') - self.w_Variable = get('Variable') - self.w_Connection = get('Connection') + for name in exported_names: + setattr(self, 'w_' + name, None) + + def startup(self, space): + w_module = space.getbuiltinmodule('cx_Oracle') + for name in exported_names: + setattr(self, 'w_' + name, space.getattr(w_module, space.wrap(name))) from pypy.module.oracle.interp_variable import all_variable_types - self.variableTypeByPythonType = {} for varType in all_variable_types: w_type = space.gettypeobject(varType.typedef) self.variableTypeByPythonType[w_type] = varType + (self.w_DecimalType, + self.w_DateTimeType, self.w_DateType, self.w_TimedeltaType, + ) = space.fixedview(space.appexec([], """(): + import decimal, datetime + return (decimal.Decimal, + datetime.datetime, datetime.date, datetime.timedelta) + """)) + def get(space): return space.fromcache(State) Modified: pypy/branch/stringbuilder2/pypy/module/posix/__init__.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/posix/__init__.py (original) +++ pypy/branch/stringbuilder2/pypy/module/posix/__init__.py Mon Jan 25 15:25:48 2010 @@ -93,6 +93,8 @@ interpleveldefs['readlink'] = 'interp_posix.readlink' if hasattr(os, 'fork'): interpleveldefs['fork'] = 'interp_posix.fork' + if hasattr(os, 'openpty'): + interpleveldefs['openpty'] = 'interp_posix.openpty' if hasattr(os, 'waitpid'): interpleveldefs['waitpid'] = 'interp_posix.waitpid' if hasattr(os, 'execv'): Modified: pypy/branch/stringbuilder2/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/posix/interp_posix.py (original) +++ pypy/branch/stringbuilder2/pypy/module/posix/interp_posix.py Mon Jan 25 15:25:48 2010 @@ -507,6 +507,14 @@ raise wrap_oserror(space, e) return space.wrap(pid) +def openpty(space): + "Open a pseudo-terminal, returning open fd's for both master and slave end." + try: + master_fd, slave_fd = os.openpty() + except OSError, e: + raise wrap_oserror(space, e) + return space.newtuple([space.wrap(master_fd), space.wrap(slave_fd)]) + def waitpid(space, pid, options): """ waitpid(pid, options) -> (pid, status) Modified: pypy/branch/stringbuilder2/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/posix/test/test_posix2.py (original) +++ pypy/branch/stringbuilder2/pypy/module/posix/test/test_posix2.py Mon Jan 25 15:25:48 2010 @@ -245,6 +245,21 @@ assert os.WEXITSTATUS(status1) == 4 pass # <- please, inspect.getsource(), don't crash + + if hasattr(__import__(os.name), "openpty"): + def test_openpty(self): + os = self.posix + master_fd, slave_fd = self.posix.openpty() + try: + assert isinstance(master_fd, int) + assert isinstance(slave_fd, int) + os.write(slave_fd, 'x') + assert os.read(master_fd, 1) == 'x' + finally: + os.close(master_fd) + os.close(slave_fd) + + if hasattr(__import__(os.name), "execv"): def test_execv(self): os = self.posix @@ -312,7 +327,7 @@ fh.close() from time import time, sleep t0 = time() - sleep(1) + sleep(1.1) os.utime(path, None) assert os.stat(path).st_atime > t0 os.utime(path, (int(t0), int(t0))) Modified: pypy/branch/stringbuilder2/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/stringbuilder2/pypy/module/pypyjit/interp_jit.py Mon Jan 25 15:25:48 2010 @@ -21,7 +21,7 @@ PyFrame._virtualizable2_ = ['last_instr', 'pycode', 'valuestackdepth', 'valuestack_w[*]', - 'fastlocals_w[*]', 'f_forward', + 'fastlocals_w[*]', 'last_exception', ] @@ -35,18 +35,17 @@ name = opcode_method_names[ord(bytecode.co_code[next_instr])] return '%s #%d %s' % (bytecode.get_repr(), next_instr, name) -def leave(next_instr, pycode, frame, ec): - from pypy.interpreter.executioncontext import ExecutionContext - # can't use a method here, since this function is seen later than the main - # annotation XXX no longer true, could be fixed - ExecutionContext._jit_rechain_frame(ec, frame) - def get_jitcell_at(next_instr, bytecode): return bytecode.jit_cells.get(next_instr, None) def set_jitcell_at(newcell, next_instr, bytecode): bytecode.jit_cells[next_instr] = newcell +def confirm_enter_jit(next_instr, bytecode, frame, ec): + return (frame.w_f_trace is None and + ec.profilefunc is None and + ec.w_tracefunc is None) + class PyPyJitDriver(JitDriver): reds = ['frame', 'ec'] @@ -63,9 +62,9 @@ pypyjitdriver = PyPyJitDriver(can_inline = can_inline, get_printable_location = get_printable_location, - leave = leave, get_jitcell_at = get_jitcell_at, - set_jitcell_at = set_jitcell_at) + set_jitcell_at = set_jitcell_at, + confirm_enter_jit = confirm_enter_jit) class __extend__(PyFrame): Modified: pypy/branch/stringbuilder2/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/branch/stringbuilder2/pypy/module/pypyjit/test/test_pypy_c.py Mon Jan 25 15:25:48 2010 @@ -89,8 +89,12 @@ print >> f, source # some support code... print >> f, py.code.Source(""" - import sys, pypyjit - pypyjit.set_param(threshold=3) + import sys + try: # make the file runnable by CPython + import pypyjit + pypyjit.set_param(threshold=3) + except ImportError: + pass def check(args, expected): print >> sys.stderr, 'trying:', args @@ -113,8 +117,8 @@ assert result assert result.splitlines()[-1].strip() == 'OK :-)' self.parse_loops(logfilepath) + self.print_loops() if self.total_ops > expected_max_ops: - self.print_loops() assert 0, "too many operations: got %d, expected maximum %d" % ( self.total_ops, expected_max_ops) @@ -172,7 +176,7 @@ x = x + (i&j) i = i + 1 return x - ''', 194, + ''', 220, ([2117], 1083876708)) def test_factorial(self): @@ -183,7 +187,7 @@ r *= n n -= 1 return r - ''', 26, + ''', 28, ([5], 120), ([20], 2432902008176640000L)) @@ -205,30 +209,43 @@ def main(): return richards.main(iterations = 1) - ''' % (sys.path,), 7000, + ''' % (sys.path,), 7200, ([], 42)) def test_simple_call(self): self.run_source(''' + OFFSET = 0 def f(i): - return i + 1 + return i + 1 + OFFSET def main(n): i = 0 - while i < n: + while i < n+OFFSET: i = f(f(i)) return i - ''', 76, + ''', 96, ([20], 20), ([31], 32)) ops = self.get_by_bytecode("LOAD_GLOBAL") - assert len(ops) == 2 - assert ops[0].get_opnames() == ["getfield_gc", "getarrayitem_gc", + assert len(ops) == 5 + assert ops[0].get_opnames() == ["getfield_gc", "guard_value", + "getfield_gc", "guard_isnull", "getfield_gc", "guard_nonnull_class"] - assert not ops[1] # second LOAD_GLOBAL folded away + # the second getfield on the same globals is quicker + assert ops[1].get_opnames() == ["getfield_gc", "guard_nonnull_class"] + assert not ops[2] # second LOAD_GLOBAL of the same name folded away + # LOAD_GLOBAL of the same name but in different function partially + # folded away + # XXX could be improved + assert ops[3].get_opnames() == ["guard_value", + "getfield_gc", "guard_isnull"] + assert not ops[4] ops = self.get_by_bytecode("CALL_FUNCTION") assert len(ops) == 2 - for bytecode in ops: - assert not bytecode.get_opnames("call") + for i, bytecode in enumerate(ops): + if i == 0: + assert "call(getexecutioncontext)" in str(bytecode) + else: + assert not bytecode.get_opnames("call") assert not bytecode.get_opnames("new") assert len(bytecode.get_opnames("guard")) <= 10 @@ -258,8 +275,11 @@ ops = self.get_by_bytecode("CALL_METHOD") assert len(ops) == 2 - for bytecode in ops: - assert not bytecode.get_opnames("call") + for i, bytecode in enumerate(ops): + if i == 0: + assert "call(getexecutioncontext)" in str(bytecode) + else: + assert not bytecode.get_opnames("call") assert not bytecode.get_opnames("new") assert len(bytecode.get_opnames("guard")) <= 9 assert len(ops[1]) < len(ops[0]) @@ -270,6 +290,35 @@ "guard_nonnull_class"] assert not ops[1] # second LOAD_ATTR folded away + def test_static_classmethod_call(self): + self.run_source(''' + class A(object): + @classmethod + def f(cls, i): + return i + (cls is A) + 1 + + @staticmethod + def g(i): + return i - 1 + + def main(n): + i = 0 + a = A() + while i < n: + x = a.f(i) + i = a.g(x) + return i + ''', 105, + ([20], 20), + ([31], 31)) + ops = self.get_by_bytecode("LOOKUP_METHOD") + assert len(ops) == 2 + assert not ops[0].get_opnames("call") + assert not ops[0].get_opnames("new") + assert len(ops[0].get_opnames("guard")) <= 7 + assert len(ops[0].get_opnames("getfield")) < 6 + assert not ops[1] # second LOOKUP_METHOD folded away + def test_default_and_kw(self): self.run_source(''' def f(i, j=1): @@ -279,17 +328,45 @@ while i < n: i = f(f(i), j=1) return i - ''', 98, + ''', 100, ([20], 20), ([31], 32)) ops = self.get_by_bytecode("CALL_FUNCTION") assert len(ops) == 2 - for bytecode in ops: - assert not bytecode.get_opnames("call") + for i, bytecode in enumerate(ops): + if i == 0: + assert "call(getexecutioncontext)" in str(bytecode) + else: + assert not bytecode.get_opnames("call") assert not bytecode.get_opnames("new") assert len(ops[0].get_opnames("guard")) <= 14 assert len(ops[1].get_opnames("guard")) <= 3 + def test_kwargs(self): + self.run_source(''' + d = {} + + def g(**args): + return len(args) + + def main(x): + s = 0 + d = {} + for i in range(x): + s += g(**d) + d[str(i)] = i + if i % 100 == 99: + d = {} + return s + ''', 100000, ([100], 4950), + ([1000], 49500), + ([10000], 495000), + ([100000], 4950000)) + assert len(self.loops) == 2 + op, = self.get_by_bytecode("CALL_FUNCTION_KW") + # XXX a bit too many guards, but better than before + assert len(op.get_opnames("guard")) <= 10 + def test_virtual_instance(self): self.run_source(''' class A(object): @@ -303,7 +380,7 @@ a.x = 2 i = i + a.x return i - ''', 63, + ''', 67, ([20], 20), ([31], 32)) @@ -334,7 +411,7 @@ while i < n: i = i + a.x return i - ''', 39, + ''', 41, ([20], 20), ([31], 32)) @@ -375,15 +452,40 @@ i += 1 l.append(i) return i, len(l) - ''', 37, + ''', 39, ([20], (20, 18)), ([31], (31, 29))) bytecode, = self.get_by_bytecode("CALL_METHOD") assert len(bytecode.get_opnames("new_with_vtable")) == 1 # the forcing of the int assert len(bytecode.get_opnames("call")) == 1 # the call to append - assert len(bytecode.get_opnames("guard")) == 1 # guard_no_exception after the call + assert len(bytecode.get_opnames("guard")) == 2 # guard for profiling disabledness + guard_no_exception after the call + def test_range_iter(self): + self.run_source(''' + def g(n): + return range(n) + + def main(n): + s = 0 + for i in range(n): + s += g(n)[i] + return s + ''', 143, ([1000], 1000 * 999 / 2)) + bytecode, = self.get_by_bytecode("BINARY_SUBSCR") + assert bytecode.get_opnames("guard") == [ + "guard_isnull", # check that the range list is not forced + "guard_false", # check that the index is >= 0 + "guard_false", # check that the index is lower than the current length + ] + bytecode, _ = self.get_by_bytecode("FOR_ITER") # second bytecode is the end of the loop + assert bytecode.get_opnames("guard") == [ + "guard_class", # check the class of the iterator + "guard_nonnull", # check that the iterator is not finished + "guard_isnull", # check that the range list is not forced + "guard_false", # check that the index is lower than the current length + ] + def test_exception_inside_loop_1(self): py.test.skip("exceptions: in-progress") self.run_source(''' @@ -445,7 +547,27 @@ def setup_class(cls): if option.pypy_c is None: py.test.skip("pass --pypy!") + if not has_info(option.pypy_c, 'translation.jit'): + py.test.skip("must give a pypy-c with the jit enabled") cls.tmpdir = udir.join('pypy-jit') cls.tmpdir.ensure(dir=1) cls.counter = 0 cls.pypy_c = option.pypy_c + +def has_info(pypy_c, option): + g = os.popen('"%s" --info' % pypy_c, 'r') + lines = g.readlines() + g.close() + if not lines: + raise ValueError("cannot execute %r" % pypy_c) + for line in lines: + line = line.strip() + if line.startswith(option + ':'): + line = line[len(option)+1:].strip() + if line == 'True': + return True + elif line == 'False': + return False + else: + return line + raise ValueError(option + ' not found in ' + pypy_c) Modified: pypy/branch/stringbuilder2/pypy/module/sys/vm.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/sys/vm.py (original) +++ pypy/branch/stringbuilder2/pypy/module/sys/vm.py Mon Jan 25 15:25:48 2010 @@ -31,7 +31,6 @@ space.wrap("frame index must not be negative")) ec = space.getexecutioncontext() f = ec.gettopframe_nohidden() - f.force_f_back() while True: if f is None: raise OperationError(space.w_ValueError, Modified: pypy/branch/stringbuilder2/pypy/module/thread/__init__.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/thread/__init__.py (original) +++ pypy/branch/stringbuilder2/pypy/module/thread/__init__.py Mon Jan 25 15:25:48 2010 @@ -18,11 +18,6 @@ 'allocate': 'os_lock.allocate_lock', # obsolete synonym 'LockType': 'os_lock.getlocktype(space)', '_local': 'os_local.getlocaltype(space)', - - # custom interface for the 'imp' module - '_importlock_held': 'importlock.held', - '_importlock_acquire': 'importlock.acquire', - '_importlock_release': 'importlock.release', } def __init__(self, space, *args): Modified: pypy/branch/stringbuilder2/pypy/module/zipimport/__init__.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/zipimport/__init__.py (original) +++ pypy/branch/stringbuilder2/pypy/module/zipimport/__init__.py Mon Jan 25 15:25:48 2010 @@ -14,4 +14,12 @@ appleveldefs = { 'ZipImportError' : 'app_zipimport.ZipImportError', } - + + def setup_after_space_initialization(self): + """NOT_RPYTHON""" + space = self.space + # install zipimport hook + w_path_hooks = space.sys.get('path_hooks') + from pypy.module.zipimport.interp_zipimport import W_ZipImporter + w_zipimporter = space.gettypefor(W_ZipImporter) + space.call_method(w_path_hooks, 'append', w_zipimporter) Modified: pypy/branch/stringbuilder2/pypy/module/zipimport/interp_zipimport.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/zipimport/interp_zipimport.py (original) +++ pypy/branch/stringbuilder2/pypy/module/zipimport/interp_zipimport.py Mon Jan 25 15:25:48 2010 @@ -5,7 +5,7 @@ from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.module import Module -from pypy.module.__builtin__ import importing +from pypy.module.imp import importing from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.rzipfile import RZipFile, BadZipfile import os @@ -149,9 +149,9 @@ real_name = self.name + os.path.sep + self.corr_zname(filename) space.setattr(w_mod, w('__loader__'), space.wrap(self)) importing._prepare_module(space, w_mod, real_name, pkgpath) - result = importing.load_source_module(space, w(modname), w_mod, - filename, buf, write_pyc=False) - return result + code_w = importing.parse_source_module(space, filename, buf) + importing.exec_code_module(space, w_mod, code_w) + return w_mod def _parse_mtime(self, space, filename): w = space.wrap Modified: pypy/branch/stringbuilder2/pypy/module/zipimport/test/test_zipimport.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/zipimport/test/test_zipimport.py (original) +++ pypy/branch/stringbuilder2/pypy/module/zipimport/test/test_zipimport.py Mon Jan 25 15:25:48 2010 @@ -4,7 +4,7 @@ import py import time import struct -from pypy.module.__builtin__.importing import get_pyc_magic, _w_long +from pypy.module.imp.importing import get_pyc_magic, _w_long from StringIO import StringIO from pypy.tool.udir import udir @@ -255,6 +255,11 @@ l = [i for i in zipimport._zip_directory_cache] assert len(l) + def test_path_hooks(self): + import sys + import zipimport + assert sys.path_hooks.count(zipimport.zipimporter) == 1 + class AppTestZipimportDeflated(AppTestZipimport): compression = ZIP_DEFLATED Modified: pypy/branch/stringbuilder2/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/descroperation.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/descroperation.py Mon Jan 25 15:25:48 2010 @@ -35,7 +35,13 @@ w_descr = space.lookup(w_obj, name) if w_descr is not None: if space.is_data_descr(w_descr): - return space.get(w_descr, w_obj) + # Only override if __get__ is defined, too, for compatibility + # with CPython. + w_get = space.lookup(w_descr, "__get__") + if w_get is not None: + w_type = space.type(w_obj) + return space.get_and_call_function(w_get, w_descr, w_obj, + w_type) w_value = w_obj.getdictvalue_attr_is_in_class(space, name) else: w_value = w_obj.getdictvalue(space, name) @@ -505,30 +511,42 @@ slice_max = Temp()[:] del Temp +def old_slice_range_getlength(space, w_obj): + # NB. the language ref is inconsistent with the new-style class + # behavior when w_obj doesn't implement __len__(), so we just + # follow cpython. Also note that CPython slots make it easier + # to check for object implementing it or not. We just catch errors + # so this behavior is slightly different + try: + return space.len(w_obj) + except OperationError, e: + if not ((e.match(space, space.w_AttributeError) or + e.match(space, space.w_TypeError))): + raise + return None + def old_slice_range(space, w_obj, w_start, w_stop): """Only for backward compatibility for __getslice__()&co methods.""" + w_length = None if space.is_w(w_start, space.w_None): w_start = space.wrap(0) else: - w_start = space.wrap(space.getindex_w(w_start, None)) - if space.is_true(space.lt(w_start, space.wrap(0))): - try: - w_start = space.add(w_start, space.len(w_obj)) - except OperationError, e: - if not ((e.match(space, space.w_AttributeError) or - e.match(space, space.w_TypeError))): - raise - # NB. the language ref is inconsistent with the new-style class - # behavior when w_obj doesn't implement __len__(), so we just - # follow cpython. Also note that CPython slots make it easier - # to check for object implementing it or not. We just catch errors - # so this behavior is slightly different + start = space.getindex_w(w_start, None) + w_start = space.wrap(start) + if start < 0: + w_length = old_slice_range_getlength(space, w_obj) + if w_length is not None: + w_start = space.add(w_start, w_length) if space.is_w(w_stop, space.w_None): w_stop = space.wrap(slice_max) else: - w_stop = space.wrap(space.getindex_w(w_stop, None)) - if space.is_true(space.lt(w_stop, space.wrap(0))): - w_stop = space.add(w_stop, space.len(w_obj)) + stop = space.getindex_w(w_stop, None) + w_stop = space.wrap(stop) + if stop < 0: + if w_length is None: + w_length = old_slice_range_getlength(space, w_obj) + if w_length is not None: + w_stop = space.add(w_stop, w_length) return w_start, w_stop # regular methods def helpers Modified: pypy/branch/stringbuilder2/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/flow/flowcontext.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/flow/flowcontext.py Mon Jan 25 15:25:48 2010 @@ -5,6 +5,7 @@ from pypy.interpreter.argument import ArgumentsForTranslation from pypy.objspace.flow.model import * from pypy.objspace.flow.framestate import FrameState +from pypy.rlib import jit class OperationThatShouldNotBePropagatedError(OperationError): @@ -260,8 +261,8 @@ except StopFlowing: continue # restarting a dead SpamBlock try: - old_frame = self.some_frame - self.some_frame = frame + old_frameref = self.topframeref + self.topframeref = jit.non_virtual_ref(frame) self.crnt_frame = frame try: w_result = frame.dispatch(frame.pycode, @@ -269,7 +270,7 @@ self) finally: self.crnt_frame = None - self.some_frame = old_frame + self.topframeref = old_frameref except OperationThatShouldNotBePropagatedError, e: raise Exception( @@ -384,6 +385,9 @@ operr = OperationError(operr.w_type, operr.w_value) return operr + def exception_trace(self, frame, operationerr): + pass # overridden for performance only + # hack for unrolling iterables, don't use this def replace_in_stack(self, oldvalue, newvalue): w_new = Constant(newvalue) Modified: pypy/branch/stringbuilder2/pypy/objspace/std/celldict.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/celldict.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/celldict.py Mon Jan 25 15:25:48 2010 @@ -1,4 +1,8 @@ -from pypy.interpreter.pycode import CO_CONTAINSGLOBALS +""" A very simple cell dict implementation. The dictionary maps keys to cell. +This ensures that the function (dict, key) -> cell is pure. By itself, this +optimization is not helping at all, but in conjunction with the JIT it can +speed up global lookups a lot.""" + from pypy.objspace.std.dictmultiobject import IteratorImplementation from pypy.objspace.std.dictmultiobject import W_DictMultiObject, _is_sane_hash from pypy.rlib import jit @@ -19,31 +23,22 @@ def __init__(self, space): self.space = space self.content = {} - self.unshadowed_builtins = {} - def getcell(self, key, make_new=True): + def getcell(self, key, makenew): + if makenew or jit.we_are_jitted(): + # when we are jitting, we always go through the pure function + # below, to ensure that we have no residual dict lookup + return self._getcell_makenew(key) + return self.content.get(key, None) + + @jit.purefunction_promote + def _getcell_makenew(self, key): res = self.content.get(key, None) if res is not None: return res - if not make_new: - return None result = self.content[key] = ModuleCell() return result - def add_unshadowed_builtin(self, name, builtin_impl): - assert isinstance(builtin_impl, ModuleDictImplementation) - self.unshadowed_builtins[name] = builtin_impl - - def invalidate_unshadowed_builtin(self, name): - impl = self.unshadowed_builtins[name] - try: - cell = impl.content[name] - except KeyError: - pass - else: - w_value = cell.invalidate() - cell = impl.content[name] = ModuleCell(w_value) - def impl_setitem(self, w_key, w_value): space = self.space if space.is_w(space.type(w_key), space.w_str): @@ -52,11 +47,7 @@ self._as_rdict().setitem(w_key, w_value) def impl_setitem_str(self, name, w_value, shadows_type=True): - self.getcell(name).w_value = w_value - - if name in self.unshadowed_builtins: - self.invalidate_unshadowed_builtin(name) - del self.unshadowed_builtins[name] + self.getcell(name, True).w_value = w_value def impl_delitem(self, w_key): space = self.space @@ -64,17 +55,25 @@ if space.is_w(w_key_type, space.w_str): key = space.str_w(w_key) cell = self.getcell(key, False) - if cell is None: + if cell is None or cell.w_value is None: raise KeyError + # note that we don't remove the cell from self.content, to make + # sure that a key that was found at any point in the dict, still + # maps to the same cell later (even if this cell no longer + # represents a key) cell.invalidate() - del self.content[key] elif _is_sane_hash(space, w_key_type): raise KeyError else: self._as_rdict().delitem(w_key) def impl_length(self): - return len(self.content) + # inefficient, but do we care? + res = 0 + for cell in self.content.itervalues(): + if cell.w_value is not None: + res += 1 + return res def impl_getitem(self, w_lookup): space = self.space @@ -91,6 +90,7 @@ res = self.getcell(lookup, False) if res is None: return None + # note that even if the res.w_value is None, the next line is fine return res.w_value def impl_iter(self): @@ -98,39 +98,34 @@ def impl_keys(self): space = self.space - return [space.wrap(key) for key in self.content.iterkeys()] + return [space.wrap(key) for key, cell in self.content.iteritems() + if cell.w_value is not None] def impl_values(self): - return [cell.w_value for cell in self.content.itervalues()] + return [cell.w_value for cell in self.content.itervalues() + if cell.w_value is not None] def impl_items(self): space = self.space return [space.newtuple([space.wrap(key), cell.w_value]) - for (key, cell) in self.content.iteritems()] + for (key, cell) in self.content.iteritems() + if cell.w_value is not None] def impl_clear(self): - # inefficient, but who cares for k, cell in self.content.iteritems(): cell.invalidate() - for k in self.unshadowed_builtins: - self.invalidate_unshadowed_builtin(k) - self.content.clear() - self.unshadowed_builtins.clear() - def _as_rdict(self): r_dict_content = self.initialize_as_rdict() for k, cell in self.content.iteritems(): - r_dict_content[self.space.wrap(k)] = cell.w_value + if cell.w_value is not None: + r_dict_content[self.space.wrap(k)] = cell.w_value cell.invalidate() - for k in self.unshadowed_builtins: - self.invalidate_unshadowed_builtin(k) self._clear_fields() return self def _clear_fields(self): self.content = None - self.unshadowed_builtins = None class ModuleDictIteratorImplementation(IteratorImplementation): def __init__(self, space, dictimplementation): @@ -138,99 +133,8 @@ self.iterator = dictimplementation.content.iteritems() def next_entry(self): - # note that this 'for' loop only runs once, at most for key, cell in self.iterator: - return (self.space.wrap(key), cell.w_value) + if cell.w_value is not None: + return (self.space.wrap(key), cell.w_value) else: return None, None - - -class State(object): - def __init__(self, space): - self.space = space - self.invalidcell = ModuleCell() - self.always_invalid_cache = [] - self.neverused_dictcontent = {} - -class GlobalCacheHolder(object): - def __init__(self, space): - self.cache = None - state = space.fromcache(State) - self.dictcontent = state.neverused_dictcontent - - def getcache(self, space, code, w_globals): - if type(w_globals) is ModuleDictImplementation: - content = w_globals.content - else: - content = None - if self.dictcontent is content: - return self.cache - return self.getcache_slow(space, code, w_globals, content) - getcache._always_inline_ = True - - def getcache_slow(self, space, code, w_globals, content): - state = space.fromcache(State) - if content is None: - cache = state.always_invalid_cache - if len(code.co_names_w) > len(cache): - cache = [state.invalidcell] * len(code.co_names_w) - state.always_invalid_cache = cache - else: - cache = [state.invalidcell] * len(code.co_names_w) - self.cache = cache - self.dictcontent = content - return cache - getcache_slow._dont_inline_ = True - -def init_code(code): - if code.co_flags & CO_CONTAINSGLOBALS: - code.globalcacheholder = GlobalCacheHolder(code.space) - else: - code.globalcacheholder = None - - -def get_global_cache(space, code, w_globals): - from pypy.interpreter.pycode import PyCode - assert isinstance(code, PyCode) - holder = code.globalcacheholder - if holder is not None: - return holder.getcache(space, code, w_globals) - return None - -def getimplementation(w_dict): - if type(w_dict) is ModuleDictImplementation and w_dict.r_dict_content is None: - return w_dict - else: - return None - -def LOAD_GLOBAL(f, nameindex, *ignored): - cell = f.cache_for_globals[nameindex] - w_value = cell.w_value - if w_value is None: - # slow path - w_value = load_global_fill_cache(f, nameindex) - f.pushvalue(w_value) -LOAD_GLOBAL._always_inline_ = True - -def find_cell_from_dict(implementation, name): - if implementation is not None: - return implementation.getcell(name, False) - return None - - at jit.dont_look_inside -def load_global_fill_cache(f, nameindex): - name = f.space.str_w(f.getname_w(nameindex)) - implementation = getimplementation(f.w_globals) - if implementation is not None: - cell = implementation.getcell(name, False) - if cell is None: - builtin_impl = getimplementation(f.get_builtin().getdict()) - cell = find_cell_from_dict(builtin_impl, name) - if cell is not None: - implementation.add_unshadowed_builtin(name, builtin_impl) - - if cell is not None: - f.cache_for_globals[nameindex] = cell - return cell.w_value - return f._load_global(f.getname_u(nameindex)) -load_global_fill_cache._dont_inline_ = True Modified: pypy/branch/stringbuilder2/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/objspace.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/objspace.py Mon Jan 25 15:25:48 2010 @@ -71,16 +71,8 @@ # Import all the object types and implementations self.model = StdTypeModel(self.config) - from pypy.objspace.std.celldict import get_global_cache class StdObjSpaceFrame(pyframe.PyFrame): - if self.config.objspace.std.withcelldict: - def __init__(self, space, code, w_globals, closure): - pyframe.PyFrame.__init__(self, space, code, w_globals, closure) - self.cache_for_globals = get_global_cache(space, code, w_globals) - - from pypy.objspace.std.celldict import LOAD_GLOBAL - if self.config.objspace.std.optimized_int_add: if self.config.objspace.std.withsmallint: def BINARY_ADD(f, oparg, *ignored): @@ -662,15 +654,23 @@ w_value = w_obj.getdictvalue_attr_is_in_class(self, name) if w_value is not None: return w_value - try: - return self.get(w_descr, w_obj) - except OperationError, e: - if not e.match(self, self.w_AttributeError): - raise - else: + w_get = self.lookup(w_descr, "__get__") + if w_get is not None: + # __get__ is allowed to raise an AttributeError to trigger use + # of __getattr__. + try: + return self.get_and_call_function(w_get, w_descr, w_obj, + w_type) + except OperationError, e: + if not e.match(self, self.w_AttributeError): + raise + if e is None: w_value = w_obj.getdictvalue(self, name) if w_value is not None: return w_value + # No value in __dict__. Fallback to the descriptor if we have it. + if w_descr is not None: + return w_descr w_descr = self.lookup(w_obj, '__getattr__') if w_descr is not None: Modified: pypy/branch/stringbuilder2/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/rangeobject.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/rangeobject.py Mon Jan 25 15:25:48 2010 @@ -56,7 +56,9 @@ def getitem(w_self, i): if i < 0: i += w_self.length - if i >= w_self.length or i < 0: + if i < 0: + raise IndexError + elif i >= w_self.length: raise IndexError return w_self.start + i * w_self.step @@ -194,24 +196,24 @@ if w_rangelist is None: raise OperationError(space.w_StopIteration, space.w_None) assert isinstance(w_rangelist, W_RangeListObject) + index = w_rangeiter.index if w_rangelist.w_list is not None: try: w_item = space.getitem(w_rangelist.w_list, - wrapint(space, w_rangeiter.index)) + wrapint(space, index)) except OperationError, e: w_rangeiter.w_seq = None if not e.match(space, space.w_IndexError): raise raise OperationError(space.w_StopIteration, space.w_None) else: - try: - w_item = wrapint( - space, - w_rangelist.getitem(w_rangeiter.index)) - except IndexError: + if index >= w_rangelist.length: w_rangeiter.w_seq = None raise OperationError(space.w_StopIteration, space.w_None) - w_rangeiter.index += 1 + w_item = wrapint( + space, + w_rangelist.getitem_unchecked(index)) + w_rangeiter.index = index + 1 return w_item # XXX __length_hint__() Modified: pypy/branch/stringbuilder2/pypy/objspace/std/test/test_celldict.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/test/test_celldict.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/test/test_celldict.py Mon Jan 25 15:25:48 2010 @@ -1,262 +1,31 @@ import py from pypy.conftest import gettestobjspace, option -from pypy.objspace.std.celldict import get_global_cache, ModuleCell, ModuleDictImplementation +from pypy.objspace.std.celldict import ModuleCell, ModuleDictImplementation +from pypy.objspace.std.test.test_dictmultiobject import FakeSpace from pypy.interpreter import gateway -# this file tests mostly the effects of caching global lookup. The dict -# implementation itself is tested in test_dictmultiobject.py - - -class AppTestCellDict(object): - def setup_class(cls): - if option.runappdirect: - py.test.skip("not appdirect tests") - cls.space = gettestobjspace(**{"objspace.std.withcelldict": True}) - cls.w_impl_used = cls.space.appexec([], """(): - import __pypy__ - def impl_used(obj): - assert "ModuleDictImplementation" in __pypy__.internal_repr(obj) - return impl_used - """) - def is_in_cache(space, w_code, w_globals, w_name): - name = space.str_w(w_name) - cache = get_global_cache(space, w_code, w_globals) - index = [space.str_w(w_n) for w_n in w_code.co_names_w].index(name) - return space.wrap(cache[index].w_value is not None) - is_in_cache = gateway.interp2app(is_in_cache) - cls.w_is_in_cache = cls.space.wrap(is_in_cache) - stored_builtins = [] - def rescue_builtins(space): - w_dict = space.builtin.getdict() - content = {} - for key, cell in w_dict.content.iteritems(): - newcell = ModuleCell() - newcell.w_value = cell.w_value - content[key] = newcell - stored_builtins.append(content) - rescue_builtins = gateway.interp2app(rescue_builtins) - cls.w_rescue_builtins = cls.space.wrap(rescue_builtins) - def restore_builtins(space): - w_dict = space.builtin.getdict() - assert isinstance(w_dict, ModuleDictImplementation) - w_dict.content = stored_builtins.pop() - w_dict.fallback = None - restore_builtins = gateway.interp2app(restore_builtins) - cls.w_restore_builtins = cls.space.wrap(restore_builtins) - - def test_same_code_in_different_modules(self): - import sys - mod1 = type(sys)("abc") - self.impl_used(mod1.__dict__) - glob1 = mod1.__dict__ - mod2 = type(sys)("abc") - self.impl_used(mod2.__dict__) - glob2 = mod2.__dict__ - def f(): - return x + 1 - code = f.func_code - f1 = type(f)(code, glob1) - mod1.x = 1 - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - mod1.x = 2 - assert f1() == 3 - assert self.is_in_cache(code, glob1, "x") - assert f1() == 3 - assert self.is_in_cache(code, glob1, "x") - f2 = type(f)(code, glob2) - mod2.x = 5 - assert not self.is_in_cache(code, glob2, "x") - assert f2() == 6 - assert self.is_in_cache(code, glob2, "x") - assert f2() == 6 - assert self.is_in_cache(code, glob2, "x") - mod2.x = 7 - assert f2() == 8 - assert self.is_in_cache(code, glob2, "x") - assert f2() == 8 - assert self.is_in_cache(code, glob2, "x") - - def test_override_builtins(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - glob1 = mod1.__dict__ - self.impl_used(mod1.__dict__) - def f(): - return len(x) - code = f.func_code - f1 = type(f)(f.func_code, glob1) - mod1.x = [] - assert not self.is_in_cache(code, glob1, "len") - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 0 - assert self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - assert f1() == 0 - mod1.x.append(1) - assert f1() == 1 - assert self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - mod1.len = lambda x: 15 - assert not self.is_in_cache(code, glob1, "len") - mod1.x.append(1) - assert f1() == 15 - assert self.is_in_cache(code, glob1, "len") - assert f1() == 15 - assert self.is_in_cache(code, glob1, "len") - del mod1.len - mod1.x.append(1) - assert not self.is_in_cache(code, glob1, "len") - assert f1() == 3 - assert self.is_in_cache(code, glob1, "len") - assert f1() == 3 - assert self.is_in_cache(code, glob1, "len") - orig_len = __builtins__.len - try: - __builtins__.len = lambda x: 12 - mod1.x.append(1) - assert self.is_in_cache(code, glob1, "len") - assert f1() == 12 - assert self.is_in_cache(code, glob1, "len") - assert f1() == 12 - assert self.is_in_cache(code, glob1, "len") - finally: - __builtins__.len = orig_len - - def test_override_builtins2(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - glob1 = mod1.__dict__ - self.impl_used(mod1.__dict__) - def f(): - return l(x) - code = f.func_code - f1 = type(f)(f.func_code, glob1) - mod1.x = [] - __builtin__.l = len - try: - assert not self.is_in_cache(code, glob1, "l") - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 0 - assert self.is_in_cache(code, glob1, "l") - assert self.is_in_cache(code, glob1, "x") - assert f1() == 0 - mod1.x.append(1) - assert f1() == 1 - assert self.is_in_cache(code, glob1, "l") - assert self.is_in_cache(code, glob1, "x") - del __builtin__.l - mod1.l = len - mod1.x.append(1) - assert not self.is_in_cache(code, glob1, "l") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "l") - assert self.is_in_cache(code, glob1, "x") - finally: - if hasattr(__builtins__, "l"): - del __builtins__.l - - def test_generator(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - glob1 = mod1.__dict__ - self.impl_used(mod1.__dict__) - def f(): - yield 1 - yield x - yield len(x) - code = f.func_code - f1 = type(f)(f.func_code, glob1) - mod1.x = [] - gen = f1() - assert not self.is_in_cache(code, glob1, "len") - assert not self.is_in_cache(code, glob1, "x") - v = gen.next() - assert v == 1 - assert not self.is_in_cache(code, glob1, "len") - assert not self.is_in_cache(code, glob1, "x") - v = gen.next() - assert v is mod1.x - assert not self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - v = gen.next() - assert v == 0 - assert self.is_in_cache(code, glob1, "len") - assert self.is_in_cache(code, glob1, "x") - - def test_degenerate_to_rdict(self): - import sys - mod1 = type(sys)("abc") - self.impl_used(mod1.__dict__) - glob1 = mod1.__dict__ - def f(): - return x + 1 - code = f.func_code - f1 = type(f)(code, glob1) - mod1.x = 1 - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - glob1[1] = 2 - assert not self.is_in_cache(code, glob1, "x") - assert f1() == 2 - assert not self.is_in_cache(code, glob1, "x") - - def test_degenerate_builtin_to_rdict(self): - import sys, __builtin__ - mod1 = type(sys)("abc") - self.impl_used(mod1.__dict__) - glob1 = mod1.__dict__ - def f(): - return len(x) - code = f.func_code - f1 = type(f)(code, glob1) - mod1.x = [1, 2] - assert not self.is_in_cache(code, glob1, "x") - assert not self.is_in_cache(code, glob1, "len") - assert f1() == 2 - assert self.is_in_cache(code, glob1, "x") - assert self.is_in_cache(code, glob1, "len") - self.rescue_builtins() - try: - __builtin__.__dict__[1] = 2 - assert not self.is_in_cache(code, glob1, "len") - assert f1() == 2 - assert not self.is_in_cache(code, glob1, "len") - finally: - self.restore_builtins() - - def test_mapping_as_locals(self): - import sys - if sys.version_info < (2,5) or not hasattr(sys, 'pypy_objspaceclass'): - skip("need CPython 2.5 or PyPy for non-dictionaries in exec statements") - class M(object): - def __getitem__(self, key): - return key - def __setitem__(self, key, value): - self.result[key] = value - m = M() - m.result = {} - exec "x=m" in {}, m - assert m.result == {'x': 'm'} - exec "y=n" in m # NOTE: this doesn't work in CPython 2.4 - assert m.result == {'x': 'm', 'y': 'n'} - - def test_subclass_of_dict_as_locals(self): - import sys - if sys.version_info < (2,5) or not hasattr(sys, 'pypy_objspaceclass'): - skip("need CPython 2.5 or PyPy for non-dictionaries in exec statements") - class M(dict): - def __getitem__(self, key): - return key - def __setitem__(self, key, value): - dict.__setitem__(self, key, value) - m = M() - exec "x=m" in {}, m - assert m == {'x': 'm'} - exec "y=n" in m # NOTE: this doesn't work in CPython 2.4 - assert m == {'x': 'm', 'y': 'n'} +space = FakeSpace() +class TestCellDict(object): + def test_basic_property(self): + d = ModuleDictImplementation(space) + d.setitem("a", 1) + assert d.getcell("a", False) is d.getcell("a", False) + acell = d.getcell("a", False) + d.setitem("b", 2) + assert d.getcell("b", False) is d.getcell("b", False) + assert d.getcell("c", True) is d.getcell("c", True) + + assert d.getitem("a") == 1 + assert d.getitem("b") == 2 + + d.delitem("a") + py.test.raises(KeyError, d.delitem, "a") + assert d.getitem("a") is None + assert d.getcell("a", False) is acell + assert d.length() == 1 + + d.clear() + assert d.getitem("a") is None + assert d.getcell("a", False) is acell + assert d.length() == 0 Modified: pypy/branch/stringbuilder2/pypy/objspace/std/test/test_userobject.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/test/test_userobject.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/test/test_userobject.py Mon Jan 25 15:25:48 2010 @@ -1,5 +1,6 @@ import py from pypy.interpreter import gateway +from pypy.objspace.test import test_descriptor class AppTestUserObject: @@ -297,3 +298,10 @@ class AppTestWithGetAttributeShortcut(AppTestUserObject): OPTIONS = {"objspace.std.getattributeshortcut": True} + +class AppTestDescriptorWithGetAttributeShortcut( + test_descriptor.AppTest_Descriptor): + # for the individual tests see + # ====> ../../test/test_descriptor.py + + OPTIONS = {"objspace.std.getattributeshortcut": True} Modified: pypy/branch/stringbuilder2/pypy/objspace/test/test_descriptor.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/test/test_descriptor.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/test/test_descriptor.py Mon Jan 25 15:25:48 2010 @@ -1,6 +1,13 @@ +import py +from pypy.conftest import gettestobjspace class AppTest_Descriptor: + OPTIONS = {} + + def setup_class(cls): + cls.space = gettestobjspace(**cls.OPTIONS) + def test_non_data_descr(self): class X(object): def f(self): @@ -12,6 +19,49 @@ del x.f assert x.f() == 42 + def test_set_without_get(self): + class Descr(object): + + def __init__(self, name): + self.name = name + + def __set__(self, obj, value): + obj.__dict__[self.name] = value + descr = Descr("a") + + class X(object): + a = descr + + x = X() + assert x.a is descr + x.a = 42 + assert x.a == 42 + + def test_failing_get(self): + # when __get__() raises AttributeError, + # __getattr__ is called... + class X(object): + def get_v(self): + raise AttributeError + v = property(get_v) + + def __getattr__(self, name): + if name == 'v': + return 42 + x = X() + assert x.v == 42 + + # ... but the __dict__ is not searched + class Y(object): + def get_w(self): + raise AttributeError + def set_w(self, value): + raise AttributeError + w = property(get_w, set_w) + y = Y() + y.__dict__['w'] = 42 + raises(AttributeError, getattr, y, 'w') + def test_member(self): class X(object): def __init__(self): Modified: pypy/branch/stringbuilder2/pypy/objspace/test/test_descroperation.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/test/test_descroperation.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/test/test_descroperation.py Mon Jan 25 15:25:48 2010 @@ -174,6 +174,29 @@ (0, slice_max), ] + def test_getslice_nolength(self): + class Sq(object): + def __getslice__(self, start, stop): + return (start, stop) + def __getitem__(self, key): + return "booh" + + sq = Sq() + + assert sq[1:3] == (1,3) + slice_min, slice_max = sq[:] + assert slice_min == 0 + assert slice_max >= 2**31-1 + assert sq[1:] == (1, slice_max) + assert sq[:3] == (0, 3) + assert sq[:] == (0, slice_max) + # negative indices, but no __len__ + assert sq[-1:3] == (-1, 3) + assert sq[1:-3] == (1, -3) + assert sq[-1:-3] == (-1, -3) + # extended slice syntax always uses __getitem__() + assert sq[::] == "booh" + def test_ipow(self): x = 2 x **= 5 Modified: pypy/branch/stringbuilder2/pypy/rlib/debug.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rlib/debug.py (original) +++ pypy/branch/stringbuilder2/pypy/rlib/debug.py Mon Jan 25 15:25:48 2010 @@ -19,6 +19,14 @@ hop.exception_cannot_occur() hop.genop('debug_assert', vlist) +def fatalerror(msg, traceback=False): + from pypy.rpython.lltypesystem import lltype + from pypy.rpython.lltypesystem.lloperation import llop + if traceback: + llop.debug_print_traceback(lltype.Void) + llop.debug_fatalerror(lltype.Void, msg) +fatalerror._dont_inline_ = True + class DebugLog(list): def debug_print(self, *args): Modified: pypy/branch/stringbuilder2/pypy/rlib/jit.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rlib/jit.py (original) +++ pypy/branch/stringbuilder2/pypy/rlib/jit.py Mon Jan 25 15:25:48 2010 @@ -2,6 +2,7 @@ import sys from pypy.rpython.extregistry import ExtRegistryEntry from pypy.rlib.objectmodel import CDefinedIntSymbolic +from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.unroll import unrolling_iterable def purefunction(func): @@ -19,6 +20,12 @@ func._jit_unroll_safe_ = True return func +def loop_invariant(func): + dont_look_inside(func) + func._jit_loop_invariant_ = True + return func + + def purefunction_promote(func): import inspect purefunction(func) @@ -80,8 +87,9 @@ def we_are_jitted(): + """ Considered as true during tracing and blackholing, + so its consquences are reflected into jitted code """ return False -# timeshifts to True _we_are_jitted = CDefinedIntSymbolic('0 /* we are not jitted here */', default=0) @@ -98,6 +106,85 @@ hop.exception_cannot_occur() return hop.inputconst(lltype.Signed, _we_are_jitted) + +##def force_virtualizable(virtualizable): +## pass + +##class Entry(ExtRegistryEntry): +## _about_ = force_virtualizable + +## def compute_result_annotation(self): +## from pypy.annotation import model as annmodel +## return annmodel.s_None + +## def specialize_call(self, hop): +## [vinst] = hop.inputargs(hop.args_r[0]) +## cname = inputconst(lltype.Void, None) +## cflags = inputconst(lltype.Void, {}) +## hop.exception_cannot_occur() +## return hop.genop('jit_force_virtualizable', [vinst, cname, cflags], +## resulttype=lltype.Void) + +# ____________________________________________________________ +# VRefs + +def virtual_ref(x): + + """Creates a 'vref' object that contains a reference to 'x'. Calls + to virtual_ref/virtual_ref_finish must be properly nested. The idea + is that the object 'x' is supposed to be JITted as a virtual between + the calls to virtual_ref and virtual_ref_finish, but the 'vref' + object can escape at any point in time. If at runtime it is + dereferenced (by the call syntax 'vref()'), it returns 'x', which is + then forced.""" + return DirectJitVRef(x) +virtual_ref.oopspec = 'virtual_ref(x)' + +def virtual_ref_finish(x): + """See docstring in virtual_ref(x). Note that virtual_ref_finish + takes as argument the real object, not the vref.""" + keepalive_until_here(x) # otherwise the whole function call is removed +virtual_ref_finish.oopspec = 'virtual_ref_finish(x)' + +def non_virtual_ref(x): + """Creates a 'vref' that just returns x when called; nothing more special. + Used for None or for frames outside JIT scope.""" + return DirectVRef(x) + +# ---------- implementation-specific ---------- + +class DirectVRef(object): + def __init__(self, x): + self._x = x + def __call__(self): + return self._x + +class DirectJitVRef(DirectVRef): + def __init__(self, x): + assert x is not None, "virtual_ref(None) is not allowed" + DirectVRef.__init__(self, x) + +class Entry(ExtRegistryEntry): + _about_ = (non_virtual_ref, DirectJitVRef) + + def compute_result_annotation(self, s_obj): + from pypy.rlib import _jit_vref + return _jit_vref.SomeVRef(s_obj) + + def specialize_call(self, hop): + return hop.r_result.specialize_call(hop) + +class Entry(ExtRegistryEntry): + _type_ = DirectVRef + + def compute_annotation(self): + from pypy.rlib import _jit_vref + assert isinstance(self.instance, DirectVRef) + s_obj = self.bookkeeper.immutablevalue(self.instance()) + return _jit_vref.SomeVRef(s_obj) + +vref_None = non_virtual_ref(None) + # ____________________________________________________________ # User interface for the hotpath JIT policy @@ -135,7 +222,8 @@ def __init__(self, greens=None, reds=None, virtualizables=None, get_jitcell_at=None, set_jitcell_at=None, can_inline=None, get_printable_location=None, - leave=None): + confirm_enter_jit=None, + leave=None): # XXX 'leave' is deprecated if greens is not None: self.greens = greens if reds is not None: @@ -152,6 +240,7 @@ self.set_jitcell_at = set_jitcell_at self.get_printable_location = get_printable_location self.can_inline = can_inline + self.confirm_enter_jit = confirm_enter_jit self.leave = leave def _freeze_(self): Modified: pypy/branch/stringbuilder2/pypy/rlib/rgc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rlib/rgc.py (original) +++ pypy/branch/stringbuilder2/pypy/rlib/rgc.py Mon Jan 25 15:25:48 2010 @@ -1,5 +1,7 @@ import gc from pypy.rpython.extregistry import ExtRegistryEntry +from pypy.rlib.objectmodel import we_are_translated + # ____________________________________________________________ # General GC features @@ -334,7 +336,12 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rlib.objectmodel import keepalive_until_here - assert source != dest + # supports non-overlapping copies only + if not we_are_translated(): + if source == dest: + assert (source_start + length <= dest_start or + dest_start + length <= source_start) + TP = lltype.typeOf(source).TO assert TP == lltype.typeOf(dest).TO if isinstance(TP.OF, lltype.Ptr) and TP.OF.TO._gckind == 'gc': @@ -357,3 +364,9 @@ keepalive_until_here(source) keepalive_until_here(dest) ll_arraycopy._annspecialcase_ = 'specialize:ll' +ll_arraycopy._jit_look_inside_ = False + +def no_collect(func): + func._dont_inline_ = True + func._gc_no_collect_ = True + return func Modified: pypy/branch/stringbuilder2/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/llinterp.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/llinterp.py Mon Jan 25 15:25:48 2010 @@ -543,10 +543,22 @@ def op_debug_llinterpcall(self, pythonfunction, *args_ll): return pythonfunction(*args_ll) - def op_jit_marker(self, *args): - pass + def op_debug_start_traceback(self, *args): + pass # xxx write debugging code here? + + def op_debug_reraise_traceback(self, *args): + pass # xxx write debugging code here? + + def op_debug_record_traceback(self, *args): + pass # xxx write debugging code here? - def op_promote_virtualizable(self, *args): + def op_debug_print_traceback(self, *args): + pass # xxx write debugging code here? + + def op_debug_catch_exception(self, *args): + pass # xxx write debugging code here? + + def op_jit_marker(self, *args): pass def op_get_exception_addr(self, *args): Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll2ctypes.py Mon Jan 25 15:25:48 2010 @@ -21,8 +21,7 @@ from pypy.rlib.rarithmetic import r_uint, r_singlefloat, intmask from pypy.annotation import model as annmodel from pypy.rpython.llinterp import LLInterpreter, LLException -from pypy.rpython.lltypesystem.rclass import OBJECT -from pypy.rpython.annlowlevel import base_ptr_lltype +from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE from pypy.rpython import raddress from pypy.translator.platform import platform @@ -31,7 +30,6 @@ _ctypes_cache = {} _eci_cache = {} -_parent_cache = {} def _setup_ctypes_cache(): from pypy.rpython.lltypesystem import rffi @@ -255,7 +253,6 @@ convert_struct(field_value, csubstruct) subcontainer = getattr(container, field_name) substorage = subcontainer._storage - update_parent_cache(substorage, subcontainer) elif field_name == STRUCT._arrayfld: # inlined var-sized part csubarray = getattr(cstruct, field_name) convert_array(field_value, csubarray) @@ -314,7 +311,6 @@ struct_storage = getattr(ctypes_storage, field_name) struct_use_ctypes_storage(struct_container, struct_storage) struct_container._setparentstructure(container, field_name) - update_parent_cache(ctypes_storage, struct_container) elif isinstance(FIELDTYPE, lltype.Array): assert FIELDTYPE._hints.get('nolength', False) == False arraycontainer = _array_of_known_length(FIELDTYPE) @@ -500,25 +496,6 @@ _callback2obj = {} _callback_exc_info = None -# this is just another hack that passes around references to applevel types -# disguised as base_ptr_lltype -class Dummy(object): - pass - -_opaque_cache = {Dummy():0} -_opaque_list = [Dummy()] - -def new_opaque_object(llobj): - try: - return _opaque_cache[llobj] - except KeyError: - assert len(_opaque_cache) == len(_opaque_list) - ctypes_type = get_ctypes_type(base_ptr_lltype()) - val = ctypes.cast(len(_opaque_cache), ctypes_type) - _opaque_list.append(llobj) - _opaque_cache[llobj] = val - return val - def get_rtyper(): llinterp = LLInterpreter.current_interpreter if llinterp is not None: @@ -542,8 +519,6 @@ return ctypes.c_void_p(0) return get_ctypes_type(T)() - if T is base_ptr_lltype(): - return new_opaque_object(llobj) if T == llmemory.GCREF: if isinstance(llobj._obj, _llgcopaque): return ctypes.c_void_p(llobj._obj.intval) @@ -655,8 +630,6 @@ raise NotImplementedError(T) container._ctypes_storage_was_allocated() storage = container._storage - if lltype.parentlink(container)[0] is not None: - update_parent_cache(storage, container) p = ctypes.pointer(storage) if index: p = ctypes.cast(p, ctypes.c_void_p) @@ -694,29 +667,37 @@ if isinstance(T, lltype.Ptr): if not cobj: # NULL pointer return lltype.nullptr(T.TO) - if T is base_ptr_lltype(): - return _opaque_list[ctypes.cast(cobj, ctypes.c_void_p).value] if isinstance(T.TO, lltype.Struct): + REAL_TYPE = T.TO if T.TO._arrayfld is not None: carray = getattr(cobj.contents, T.TO._arrayfld) container = lltype._struct(T.TO, carray.length) else: # special treatment of 'OBJECT' subclasses - if get_rtyper() and lltype._castdepth(T.TO, OBJECT) > 0: - ctypes_object = get_ctypes_type(lltype.Ptr(OBJECT)) - as_obj = ctypes2lltype(lltype.Ptr(OBJECT), - ctypes.cast(cobj, ctypes_object)) - TObj = get_rtyper().get_type_for_typeptr(as_obj.typeptr) - if TObj != T.TO: - ctypes_instance = get_ctypes_type(lltype.Ptr(TObj)) - return lltype.cast_pointer(T, - ctypes2lltype(lltype.Ptr(TObj), - ctypes.cast(cobj, ctypes_instance))) - container = lltype._struct(T.TO) + if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT) >= 0: + # figure out the real type of the object + containerheader = lltype._struct(OBJECT) + cobjheader = ctypes.cast(cobj, + get_ctypes_type(lltype.Ptr(OBJECT))) + struct_use_ctypes_storage(containerheader, + cobjheader.contents) + REAL_TYPE = get_rtyper().get_type_for_typeptr( + containerheader.typeptr) + REAL_T = lltype.Ptr(REAL_TYPE) + cobj = ctypes.cast(cobj, get_ctypes_type(REAL_T)) + container = lltype._struct(REAL_TYPE) struct_use_ctypes_storage(container, cobj.contents) - addr = ctypes.addressof(cobj.contents) - if addr in _parent_cache: - setparentstructure(container, _parent_cache[addr]) + if REAL_TYPE != T.TO: + p = container._as_ptr() + container = lltype.cast_pointer(T, p)._as_obj() + # special treatment of 'OBJECT_VTABLE' subclasses + if get_rtyper() and lltype._castdepth(REAL_TYPE, + OBJECT_VTABLE) >= 0: + # figure out the real object that this vtable points to, + # and just return that + p = get_rtyper().get_real_typeptr_for_typeptr( + container._as_ptr()) + container = lltype.cast_pointer(T, p)._as_obj() elif isinstance(T.TO, lltype.Array): if T.TO._hints.get('nolength', False): container = _array_of_unknown_length(T.TO) @@ -1163,46 +1144,6 @@ return hop.genop('cast_adr_to_int', [adr], resulttype = lltype.Signed) -# ------------------------------------------------------------ - -def parentchain(container): - current = container - links = [] - while True: - link = lltype.parentlink(current) - if link[0] is None: - try: - addr = ctypes.addressof(container._storage) - actual = _parent_cache[addr] - if len(links) < len(actual): - return actual - except KeyError: - pass - return links - links.append(link) - current = link[0] - -def update_parent_cache(storage, container): - chain = parentchain(container) - addr = ctypes.addressof(storage) - try: - current = _parent_cache[addr] - if len(chain) > len(current): - _parent_cache[addr] = chain - except KeyError: - _parent_cache[addr] = chain - -def setparentstructure(container, chain): - TP = lltype.typeOf(container) - current = container - for i, elem in enumerate(chain): - if lltype.typeOf(elem[0]) == TP: - chain = chain[i + 1:] - break - for elem in chain: - current._setparentstructure(*elem) - current = elem[0] - # ____________________________________________________________ # errno Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py Mon Jan 25 15:25:48 2010 @@ -427,7 +427,8 @@ # __________ used by the JIT ________ 'jit_marker': LLOp(), - 'promote_virtualizable':LLOp(canrun=True), + 'jit_force_virtualizable':LLOp(canrun=True), + 'jit_force_virtual': LLOp(canrun=True), 'get_exception_addr': LLOp(), 'get_exc_value_addr': LLOp(), 'do_malloc_fixedsize_clear': LLOp(canunwindgc=True), @@ -535,6 +536,11 @@ 'debug_fatalerror': LLOp(), 'debug_llinterpcall': LLOp(), # Python func call 'res=arg[0](*arg[1:])' # in backends, abort() or whatever is fine + 'debug_start_traceback': LLOp(), + 'debug_record_traceback': LLOp(), + 'debug_catch_exception': LLOp(), + 'debug_reraise_traceback': LLOp(), + 'debug_print_traceback': LLOp(), # __________ instrumentation _________ 'instrument_count': LLOp(), Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/opimpl.py Mon Jan 25 15:25:48 2010 @@ -444,8 +444,11 @@ def op_gc_stack_bottom(): pass # marker for trackgcroot.py -def op_promote_virtualizable(object, fieldname, flags): - pass # XXX should do something +def op_jit_force_virtualizable(*args): + pass + +def op_jit_force_virtual(x): + return x def op_get_group_member(TYPE, grpptr, memberoffset): from pypy.rpython.lltypesystem import llgroup Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rclass.py Mon Jan 25 15:25:48 2010 @@ -86,6 +86,13 @@ vtable = vtable.super return vtable +def alloc_array_name(name): + p = malloc(Array(Char), len(name)+1, immortal=True) + for i in range(len(name)): + p[i] = name[i] + p[len(name)] = '\x00' + return p + class ClassRepr(AbstractClassRepr): def __init__(self, rtyper, classdef): @@ -192,10 +199,7 @@ name = 'object' else: name = rsubcls.classdef.shortname - vtable.name = malloc(Array(Char), len(name)+1, immortal=True) - for i in range(len(name)): - vtable.name[i] = name[i] - vtable.name[len(name)] = '\x00' + vtable.name = alloc_array_name(name) if hasattr(rsubcls.classdef, 'my_instantiate_graph'): graph = rsubcls.classdef.my_instantiate_graph vtable.instantiate = self.rtyper.getcallable(graph) @@ -379,7 +383,7 @@ ll_runtime_type_info, OBJECT, destrptr) vtable = self.rclass.getvtable() - self.rtyper.type_for_typeptr[vtable._obj] = self.lowleveltype.TO + self.rtyper.set_type_for_typeptr(vtable, self.lowleveltype.TO) self.rtyper.lltype2vtable[self.lowleveltype.TO] = vtable def common_repr(self): # -> object or nongcobject reprs @@ -689,3 +693,23 @@ break raise AttributeError("%s has no field %s" % (lltype.typeOf(widest), name)) + +def declare_type_for_typeptr(vtable, TYPE): + """Hack for custom low-level-only 'subclasses' of OBJECT: + call this somewhere annotated, in order to declare that it is + of the given TYPE and has got the corresponding vtable.""" + +class Entry(ExtRegistryEntry): + _about_ = declare_type_for_typeptr + def compute_result_annotation(self, s_vtable, s_TYPE): + assert s_vtable.is_constant() + assert s_TYPE.is_constant() + return annmodel.s_None + def specialize_call(self, hop): + vtable = hop.args_v[0].value + TYPE = hop.args_v[1].value + assert lltype.typeOf(vtable) == CLASSTYPE + assert isinstance(TYPE, GcStruct) + assert lltype._castdepth(TYPE, OBJECT) > 0 + hop.rtyper.set_type_for_typeptr(vtable, TYPE) + return hop.inputconst(lltype.Void, None) Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rlist.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rlist.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rlist.py Mon Jan 25 15:25:48 2010 @@ -368,8 +368,7 @@ else: LIST = typeOf(l).TO newitems = malloc(LIST.items.TO, n) - for i in range(n): - newitems[i] = olditems[i] + rgc.ll_arraycopy(olditems, newitems, 0, 0, n) return newitems ll_list2fixed.oopspec = 'list.list2fixed(l)' Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_ll2ctypes.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Mon Jan 25 15:25:48 2010 @@ -928,34 +928,6 @@ assert op.args[1].value == pypy.rpython.lltypesystem.rstr.LLHelpers assert op.args[3].value == -2 - def test_pass_around_t_object(self): - from pypy.rpython.annlowlevel import base_ptr_lltype - T = base_ptr_lltype() - - class X(object): - _TYPE = T - x = 10 - - def callback(x): - return x.x - - c_source = py.code.Source(""" - long eating_callback(void *arg, long(*call)(void*)) - { - return call(arg); - } - """) - - eci = ExternalCompilationInfo(separate_module_sources=[c_source], - export_symbols=['eating_callback']) - - args = [T, rffi.CCallback([T], rffi.LONG)] - eating_callback = rffi.llexternal('eating_callback', args, rffi.LONG, - compilation_info=eci) - - res = eating_callback(X(), callback) - assert res == 10 - def test_recursive_struct_more(self): NODE = lltype.ForwardReference() NODE.become(lltype.Struct('NODE', ('value', lltype.Signed), @@ -1134,7 +1106,104 @@ #import pdb; pdb.set_trace() assert adr1_2 == adr1 assert adr1 == adr1_2 - + + def test_object_subclass(self): + from pypy.rpython.lltypesystem import rclass + from pypy.rpython.annlowlevel import cast_instance_to_base_ptr + from pypy.rpython.annlowlevel import cast_base_ptr_to_instance + class S: + pass + def f(n): + s = S() + s.x = n + ls = cast_instance_to_base_ptr(s) + as_num = rffi.cast(lltype.Signed, ls) + # --- around this point, only 'as_num' is passed + t = rffi.cast(rclass.OBJECTPTR, as_num) + u = cast_base_ptr_to_instance(S, t) + return u.x + res = interpret(f, [123]) + assert res == 123 + + def test_object_subclass_2(self): + from pypy.rpython.lltypesystem import rclass + SCLASS = lltype.GcStruct('SCLASS', + ('parent', rclass.OBJECT), + ('n', lltype.Signed)) + sclass_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True, + immortal=True) + sclass_vtable.name = rclass.alloc_array_name('SClass') + def f(n): + rclass.declare_type_for_typeptr(sclass_vtable, SCLASS) + s = lltype.malloc(SCLASS) + s.parent.typeptr = sclass_vtable + s.n = n + as_num = rffi.cast(lltype.Signed, s) + # --- around this point, only 'as_num' is passed + t = rffi.cast(lltype.Ptr(SCLASS), as_num) + return t.n + res = interpret(f, [123]) + assert res == 123 + + def test_object_subclass_3(self): + from pypy.rpython.lltypesystem import rclass + from pypy.rpython.annlowlevel import cast_instance_to_base_ptr + from pypy.rpython.annlowlevel import cast_base_ptr_to_instance + class S: + pass + def f(n): + s = S() + s.x = n + ls = cast_instance_to_base_ptr(s) + as_num = rffi.cast(lltype.Signed, ls) + # --- around this point, only 'as_num' is passed + r = rffi.cast(llmemory.GCREF, as_num) + t = lltype.cast_opaque_ptr(rclass.OBJECTPTR, r) + u = cast_base_ptr_to_instance(S, t) + return u.x + res = interpret(f, [123]) + assert res == 123 + + def test_object_subclass_4(self): + from pypy.rpython.lltypesystem import rclass + SCLASS = lltype.GcStruct('SCLASS', + ('parent', rclass.OBJECT), + ('n', lltype.Signed)) + sclass_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True, + immortal=True) + sclass_vtable.name = rclass.alloc_array_name('SClass') + def f(n): + rclass.declare_type_for_typeptr(sclass_vtable, SCLASS) + s = lltype.malloc(SCLASS) + s.parent.typeptr = sclass_vtable + s.n = n + as_num = rffi.cast(lltype.Signed, s) + # --- around this point, only 'as_num' is passed + r = rffi.cast(llmemory.GCREF, as_num) + t = lltype.cast_opaque_ptr(lltype.Ptr(SCLASS), r) + return t.n + res = interpret(f, [123]) + assert res == 123 + + def test_object_subclass_5(self): + from pypy.rpython.lltypesystem import rclass + from pypy.rpython.annlowlevel import cast_instance_to_base_ptr + from pypy.rpython.annlowlevel import cast_base_ptr_to_instance + class S: + x = 5 # entry in the vtable + class T(S): + x = 6 + def f(): + s = T() + ls = cast_instance_to_base_ptr(s) + as_num = rffi.cast(lltype.Signed, ls) + # --- around this point, only 'as_num' is passed + t = rffi.cast(rclass.OBJECTPTR, as_num) + u = cast_base_ptr_to_instance(S, t) + return u.x + res = interpret(f, []) + assert res == 6 + class TestPlatform(object): def test_lib_on_libpaths(self): from pypy.translator.platform import platform Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py Mon Jan 25 15:25:48 2010 @@ -567,6 +567,12 @@ f.close() def transform_graph(self, graph): + func = getattr(graph, 'func', None) + if func and getattr(func, '_gc_no_collect_', False): + if self.collect_analyzer.analyze_direct_call(graph): + raise Exception("no_collect function can trigger collection: %s" + % func.__name__) + if self.write_barrier_ptr: self.clean_sets = ( find_clean_setarrayitems(self.collect_analyzer, graph).union( Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/test/test_framework.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/test/test_framework.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/test/test_framework.py Mon Jan 25 15:25:48 2010 @@ -1,5 +1,6 @@ from pypy.objspace.flow.model import Constant, SpaceOperation from pypy.annotation.model import SomeInteger +from pypy.annotation.listdef import s_list_of_strings from pypy.rpython.memory.gc.marksweep import MarkSweepGC from pypy.rpython.memory.gctransform.test.test_transform import rtype, \ rtype_and_transform @@ -34,7 +35,6 @@ from pypy.rpython.llinterp import LLInterpreter from pypy.translator.c.genc import CStandaloneBuilder from pypy.translator.c import gc - from pypy.annotation.listdef import s_list_of_strings t = rtype(entrypoint, [s_list_of_strings]) cbuild = CStandaloneBuilder(t, entrypoint, t.config, @@ -113,6 +113,50 @@ gg = graphof(t, g) assert CollectAnalyzer(t).analyze_direct_call(gg) +def test_no_collect(): + from pypy.rlib import rgc + from pypy.translator.c.genc import CStandaloneBuilder + from pypy.translator.c import gc + + @rgc.no_collect + def g(): + return 1 + + assert g._dont_inline_ + assert g._gc_no_collect_ + + def entrypoint(argv): + return g() + 2 + + t = rtype(entrypoint, [s_list_of_strings]) + cbuild = CStandaloneBuilder(t, entrypoint, t.config, + gcpolicy=FrameworkGcPolicy2) + db = cbuild.generate_graphs_for_llinterp() + +def test_no_collect_detection(): + from pypy.rlib import rgc + from pypy.translator.c.genc import CStandaloneBuilder + from pypy.translator.c import gc + + class A(object): + def __init__(self, x): + self.x = x + + @rgc.no_collect + def g(): + return A(1).x + + assert g._dont_inline_ + assert g._gc_no_collect_ + + def entrypoint(argv): + return g() + 2 + + t = rtype(entrypoint, [s_list_of_strings]) + cbuild = CStandaloneBuilder(t, entrypoint, t.config, + gcpolicy=FrameworkGcPolicy2) + f = py.test.raises(Exception, cbuild.generate_graphs_for_llinterp) + assert str(f.value) == 'no_collect function can trigger collection: g' class WriteBarrierTransformer(FrameworkGCTransformer): clean_sets = {} Modified: pypy/branch/stringbuilder2/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/module/ll_os.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/module/ll_os.py Mon Jan 25 15:25:48 2010 @@ -1400,6 +1400,30 @@ return extdef([], int, llimpl=fork_llimpl, export_name="ll_os.ll_os_fork") + @registering_if(os, 'openpty') + def register_os_openpty(self): + os_openpty = self.llexternal( + 'openpty', + [rffi.INTP, rffi.INTP, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP], + rffi.INT, + compilation_info=ExternalCompilationInfo(libraries=['util'])) + def openpty_llimpl(): + master_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + slave_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + result = os_openpty(master_p, slave_p, None, None, None) + master_fd = master_p[0] + slave_fd = slave_p[0] + lltype.free(master_p, flavor='raw') + lltype.free(slave_p, flavor='raw') + if result == -1: + raise OSError(rposix.get_errno(), "os_openpty failed") + return (rffi.cast(lltype.Signed, master_fd), + rffi.cast(lltype.Signed, slave_fd)) + + return extdef([], (int, int), "ll_os.ll_os_openpty", + llimpl=openpty_llimpl) + + @registering(os._exit) def register_os__exit(self): os__exit = self.llexternal('_exit', [rffi.INT], lltype.Void) Modified: pypy/branch/stringbuilder2/pypy/rpython/rlist.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/rlist.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/rlist.py Mon Jan 25 15:25:48 2010 @@ -11,6 +11,7 @@ from pypy.rlib.debug import ll_assert from pypy.rlib.rarithmetic import ovfcheck, widen from pypy.rpython.annlowlevel import ADTInterface +from pypy.rlib import rgc ADTIFixedList = ADTInterface(None, { 'll_newlist': (['SELF', Signed ], 'self'), @@ -525,13 +526,24 @@ return LIST.ITEM +def ll_arraycopy(source, dest, source_start, dest_start, length): + SRCTYPE = typeOf(source) + if isinstance(SRCTYPE, Ptr): + # lltype + rgc.ll_arraycopy(source.ll_items(), dest.ll_items(), + source_start, dest_start, length) + else: + # ootype -- XXX improve the case of array->array copy? + i = 0 + while i < length: + item = source.ll_getitem_fast(source_start + i) + dest.ll_setitem_fast(dest_start + i, item) + i += 1 + def ll_copy(RESLIST, l): length = l.ll_length() new_lst = RESLIST.ll_newlist(length) - i = 0 - while i < length: - new_lst.ll_setitem_fast(i, l.ll_getitem_fast(i)) - i += 1 + ll_arraycopy(l, new_lst, 0, 0, length) return new_lst def ll_len(l): @@ -574,15 +586,8 @@ except OverflowError: raise MemoryError l = RESLIST.ll_newlist(newlength) - j = 0 - while j < len1: - l.ll_setitem_fast(j, l1.ll_getitem_fast(j)) - j += 1 - i = 0 - while i < len2: - l.ll_setitem_fast(j, l2.ll_getitem_fast(i)) - i += 1 - j += 1 + ll_arraycopy(l1, l, 0, 0, len1) + ll_arraycopy(l2, l, 0, len1, len2) return l def ll_insert_nonneg(l, index, newitem): @@ -769,12 +774,7 @@ except OverflowError: raise MemoryError l1._ll_resize_ge(newlength) - i = 0 - j = len1 - while i < len2: - l1.ll_setitem_fast(j, l2.ll_getitem_fast(i)) - i += 1 - j += 1 + ll_arraycopy(l2, l1, 0, len1, len2) ll_extend.oopspec = 'list.extend(l1, l2)' def ll_extend_with_str(lst, s, getstrlen, getstritem): @@ -867,12 +867,7 @@ ll_assert(start <= len1, "list slice start larger than list length") newlength = len1 - start l = RESLIST.ll_newlist(newlength) - j = 0 - i = start - while i < len1: - l.ll_setitem_fast(j, l1.ll_getitem_fast(i)) - i += 1 - j += 1 + ll_arraycopy(l1, l, start, 0, newlength) return l ll_listslice_startonly._annenforceargs_ = (None, None, int) @@ -885,22 +880,14 @@ stop = length newlength = stop - start l = RESLIST.ll_newlist(newlength) - j = 0 - i = start - while i < stop: - l.ll_setitem_fast(j, l1.ll_getitem_fast(i)) - i += 1 - j += 1 + ll_arraycopy(l1, l, start, 0, newlength) return l def ll_listslice_minusone(RESLIST, l1): newlength = l1.ll_length() - 1 ll_assert(newlength >= 0, "empty list is sliced with [:-1]") l = RESLIST.ll_newlist(newlength) - j = 0 - while j < newlength: - l.ll_setitem_fast(j, l1.ll_getitem_fast(j)) - j += 1 + ll_arraycopy(l1, l, 0, 0, newlength) return l def ll_listdelslice_startonly(l, start): @@ -945,13 +932,8 @@ ll_assert(start <= l1.ll_length(), "l[start:x] = l with start > len(l)") ll_assert(count == stop - start, "setslice cannot resize lists in RPython") - # XXX but it should be easy enough to support, soon - j = start - i = 0 - while i < count: - l1.ll_setitem_fast(j, l2.ll_getitem_fast(i)) - i += 1 - j += 1 + # XXX ...but it would be easy enough to support if really needed + ll_arraycopy(l2, l1, 0, start, count) ll_listsetslice.oopspec = 'list.setslice(l1, start, stop, l2)' # ____________________________________________________________ Modified: pypy/branch/stringbuilder2/pypy/rpython/rptr.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/rptr.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/rptr.py Mon Jan 25 15:25:48 2010 @@ -39,6 +39,14 @@ attr = hop.args_s[1].const if isinstance(hop.s_result, annmodel.SomeLLADTMeth): return hop.inputarg(hop.r_result, arg=0) + try: + self.lowleveltype._example()._lookup_adtmeth(attr) + except AttributeError: + pass + else: + assert hop.s_result.is_constant() + return hop.inputconst(hop.r_result, hop.s_result.const) + assert attr in self.lowleveltype.TO._flds # check that the field exists FIELD_TYPE = getattr(self.lowleveltype.TO, attr) if isinstance(FIELD_TYPE, lltype.ContainerType): if (attr, FIELD_TYPE) == self.lowleveltype.TO._first_struct(): Modified: pypy/branch/stringbuilder2/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/rtyper.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/rtyper.py Mon Jan 25 15:25:48 2010 @@ -133,15 +133,33 @@ return result def get_type_for_typeptr(self, typeptr): + search = typeptr._obj try: - return self.type_for_typeptr[typeptr._obj] + return self.type_for_typeptr[search] except KeyError: - # rehash the dictionary + # rehash the dictionary, and perform a linear scan + # for the case of ll2ctypes typeptr + found = None type_for_typeptr = {} for key, value in self.type_for_typeptr.items(): type_for_typeptr[key] = value + if key == search: + found = value self.type_for_typeptr = type_for_typeptr - return self.type_for_typeptr[typeptr._obj] + if found is None: + raise KeyError(search) + return found + + def set_type_for_typeptr(self, typeptr, TYPE): + self.type_for_typeptr[typeptr._obj] = TYPE + + def get_real_typeptr_for_typeptr(self, typeptr): + # perform a linear scan for the case of ll2ctypes typeptr + search = typeptr._obj + for key, value in self.type_for_typeptr.items(): + if key == search: + return key._as_ptr() + raise KeyError(search) def makekey(self, s_obj): return pair(self.type_system, s_obj).rtyper_makekey(self) Modified: pypy/branch/stringbuilder2/pypy/rpython/rvirtualizable2.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/rvirtualizable2.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/rvirtualizable2.py Mon Jan 25 15:25:48 2010 @@ -52,10 +52,10 @@ #if not flags.get('access_directly'): if cname.value in self.my_redirected_fields: cflags = inputconst(lltype.Void, flags) - llops.genop('promote_virtualizable', [vinst, cname, cflags]) + llops.genop('jit_force_virtualizable', [vinst, cname, cflags]) -def replace_promote_virtualizable_with_call(graphs, VTYPEPTR, funcptr): +def replace_force_virtualizable_with_call(graphs, VTYPEPTR, funcptr): # funcptr should be an ll or oo function pointer with a VTYPEPTR argument c_funcptr = inputconst(lltype.typeOf(funcptr), funcptr) count = 0 @@ -65,7 +65,7 @@ continue newoplist = [] for i, op in enumerate(block.operations): - if (op.opname == 'promote_virtualizable' and + if (op.opname == 'jit_force_virtualizable' and match_virtualizable_type(op.args[0].concretetype, VTYPEPTR)): if op.args[-1].value.get('access_directly', False): @@ -75,7 +75,7 @@ count += 1 newoplist.append(op) block.operations = newoplist - log("replaced %d 'promote_virtualizable' with %r" % (count, funcptr)) + log("replaced %d 'jit_force_virtualizable' with %r" % (count, funcptr)) def match_virtualizable_type(TYPE, VTYPEPTR): if isinstance(TYPE, ootype.Instance): Modified: pypy/branch/stringbuilder2/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/test/test_rlist.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/test/test_rlist.py Mon Jan 25 15:25:48 2010 @@ -410,13 +410,18 @@ assert res.item2 == 9 def test_bltn_list(self): - def dummyfn(): - l1 = [42] - l2 = list(l1) - l2[0] = 0 - return l1[0] - res = self.interpret(dummyfn, ()) - assert res == 42 + # test for ll_copy() + for resize1 in [False, True]: + for resize2 in [False, True]: + def dummyfn(): + l1 = [42] + if resize1: l1.append(43) + l2 = list(l1) + if resize2: l2.append(44) + l2[0] = 0 + return l1[0] + res = self.interpret(dummyfn, ()) + assert res == 42 def test_is_true(self): def is_true(lst): Modified: pypy/branch/stringbuilder2/pypy/rpython/test/test_rptr.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/test/test_rptr.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/test/test_rptr.py Mon Jan 25 15:25:48 2010 @@ -337,3 +337,13 @@ return f([1]) s, t = ll_rtype(lltest, []) assert s.is_constant() == False + +def test_staticadtmeths(): + ll_func = staticAdtMethod(lambda x: x + 42) + S = GcStruct('S', adtmeths={'ll_func': ll_func}) + def f(): + return malloc(S).ll_func(5) + s, t = ll_rtype(f, []) + graphf = t.graphs[0] + for op in graphf.startblock.operations: + assert op.opname != 'getfield' Modified: pypy/branch/stringbuilder2/pypy/rpython/test/test_rvirtualizable2.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/test/test_rvirtualizable2.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/test/test_rvirtualizable2.py Mon Jan 25 15:25:48 2010 @@ -1,7 +1,7 @@ import py from pypy.rpython.lltypesystem import lltype from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin -from pypy.rpython.rvirtualizable2 import replace_promote_virtualizable_with_call +from pypy.rpython.rvirtualizable2 import replace_force_virtualizable_with_call from pypy.rlib.jit import hint from pypy.objspace.flow.model import summary from pypy.rpython.llinterp import LLInterpreter @@ -33,15 +33,15 @@ def __init__(self, v0): self.v0 = v0 -def get_promote_virtualizable_flags(graph): +def get_force_virtualizable_flags(graph): res = [] for block, op in graph.iterblockops(): - if op.opname == 'promote_virtualizable': + if op.opname == 'jit_force_virtualizable': res.append(op.args[-1].value) return res class BaseTest(BaseRtypingTest): - def test_generate_promote_virtualizable(self): + def test_generate_force_virtualizable(self): def fn(n): vinst = V(n) return vinst.v @@ -51,11 +51,11 @@ op_getfield = block.operations[-1] assert op_getfield.opname in ('getfield', 'oogetfield') v_inst = op_getfield.args[0] - assert op_promote.opname == 'promote_virtualizable' + assert op_promote.opname == 'jit_force_virtualizable' assert op_promote.args[0] is v_inst assert op_promote.args[-1].value == {} - def test_generate_promote_virtualizable_subclass(self): + def test_generate_force_virtualizable_subclass(self): def fn(n): V(n) # to attach v to V vinst = SubclassV(n) @@ -66,11 +66,11 @@ op_getfield = block.operations[-1] assert op_getfield.opname in ('getfield', 'oogetfield') v_inst = op_getfield.args[0] - assert op_promote.opname == 'promote_virtualizable' + assert op_promote.opname == 'jit_force_virtualizable' assert op_promote.args[0] is v_inst assert op_promote.args[-1].value == {} - def test_no_promote_virtualizable_for_other_fields(self): + def test_no_force_virtualizable_for_other_fields(self): def fn(n): vinst = V(n) return vinst.w @@ -81,7 +81,7 @@ assert op_getfield.opname in ('getfield', 'oogetfield') assert op_call.opname == 'direct_call' # to V.__init__ - def test_generate_promote_virtualizable_array(self): + def test_generate_force_virtualizable_array(self): def fn(n): vinst = VArray([n, n+1]) return vinst.lst[1] @@ -93,7 +93,7 @@ assert op_getarrayitem.opname == 'direct_call' # to ll_getitem_xxx assert op_getfield.opname in ('getfield', 'oogetfield') v_inst = op_getfield.args[0] - assert op_promote.opname == 'promote_virtualizable' + assert op_promote.opname == 'jit_force_virtualizable' assert op_promote.args[0] is v_inst assert op_promote.args[-1].value == {} @@ -130,13 +130,13 @@ TYPE = self.gettype(w_inst) assert 'virtualizable2_accessor' not in TYPE._hints - def replace_promote_virtualizable(self, rtyper, graphs): + def replace_force_virtualizable(self, rtyper, graphs): from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator graph = graphs[0] for block, op in graph.iterblockops(): - if op.opname == 'promote_virtualizable': + if op.opname == 'jit_force_virtualizable': v_inst_ll_type = op.args[0].concretetype break @@ -150,11 +150,10 @@ s_vinst = annmodel.SomeOOInstance(v_inst_ll_type) funcptr = annhelper.delayedfunction(mycall, [s_vinst], annmodel.s_None) annhelper.finish() - replace_promote_virtualizable_with_call(graphs, v_inst_ll_type, - funcptr) + replace_force_virtualizable_with_call(graphs, v_inst_ll_type, funcptr) return funcptr - def test_replace_promote_virtualizable_with_call(self): + def test_replace_force_virtualizable_with_call(self): def fn(n): vinst = V(n) return vinst.v @@ -162,7 +161,7 @@ block = graph.startblock op_getfield = block.operations[-1] assert op_getfield.opname in ('getfield', 'oogetfield') - funcptr = self.replace_promote_virtualizable(rtyper, [graph]) + funcptr = self.replace_force_virtualizable(rtyper, [graph]) if getattr(conftest.option, 'view', False): graph.show() op_promote = block.operations[-2] @@ -190,9 +189,9 @@ g_graph = t._graphof(g) expected = [{'access_directly': True}] * 3 - assert get_promote_virtualizable_flags(g_graph) == expected + assert get_force_virtualizable_flags(g_graph) == expected - self.replace_promote_virtualizable(typer, [g_graph]) + self.replace_force_virtualizable(typer, [g_graph]) assert summary(g_graph) == {self.GETFIELD: 2, self.SETFIELD: 1, 'int_add': 1} res = self.interpret(f, [23]) @@ -213,7 +212,7 @@ f_graph = t._graphof(f) g_graph = t._graphof(g) - self.replace_promote_virtualizable(typer, [f_graph, g_graph]) + self.replace_force_virtualizable(typer, [f_graph, g_graph]) t.checkgraphs() res = self.interpret(f, [23]) @@ -236,12 +235,12 @@ g_graphs.sort() assert g_graphs[0][0] is None - assert get_promote_virtualizable_flags(g_graphs[0][1]) == [{}] + assert get_force_virtualizable_flags(g_graphs[0][1]) == [{}] expected = [{'access_directly': True}] - assert get_promote_virtualizable_flags(g_graphs[1][1]) == expected + assert get_force_virtualizable_flags(g_graphs[1][1]) == expected - self.replace_promote_virtualizable(typer, [g_graphs[0][1], - g_graphs[1][1]]) + self.replace_force_virtualizable(typer, [g_graphs[0][1], + g_graphs[1][1]]) assert summary(g_graphs[0][1]) == {'direct_call': 1, self.GETFIELD: 1} assert summary(g_graphs[1][1]) == {self.GETFIELD: 1} @@ -276,8 +275,9 @@ assert summary(g_graphs[1][1]) == {self.SETFIELD: 1} h_graph = t._graphof(h) - assert summary(h_graph) == {'promote_virtualizable': 1, self.GETFIELD: 1} - assert get_promote_virtualizable_flags(h_graph) == [{}] + assert summary(h_graph) == {'jit_force_virtualizable': 1, + self.GETFIELD: 1} + assert get_force_virtualizable_flags(h_graph) == [{}] res = self.interpret(f, [23]) assert res == 23 @@ -303,7 +303,7 @@ t, typer, graph = self.gengraph(f, [int]) g_graph = t._graphof(A.g.im_func) - self.replace_promote_virtualizable(typer, [g_graph]) + self.replace_force_virtualizable(typer, [g_graph]) assert summary(g_graph) == {self.GETFIELD: 1, 'int_mul': 1} Modified: pypy/branch/stringbuilder2/pypy/rpython/tool/rffi_platform.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/tool/rffi_platform.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/tool/rffi_platform.py Mon Jan 25 15:25:48 2010 @@ -644,7 +644,7 @@ else: raise CompilationError("Library %s is not installed" % (name,)) -def check_boehm(platform=None): +def configure_boehm(platform=None): if platform is None: from pypy.translator.platform import platform if sys.platform == 'win32': @@ -658,13 +658,10 @@ includes=includes, libraries=['gc'], ) - try: - return configure_external_library( - 'gc', eci, - [dict(prefix='gc-', include_dir='include', library_dir=library_dir)], - symbol='GC_init') - except CompilationError: - return None + return configure_external_library( + 'gc', eci, + [dict(prefix='gc-', include_dir='include', library_dir=library_dir)], + symbol='GC_init') if __name__ == '__main__': doc = """Example: Modified: pypy/branch/stringbuilder2/pypy/tool/gcc_cache.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/tool/gcc_cache.py (original) +++ pypy/branch/stringbuilder2/pypy/tool/gcc_cache.py Mon Jan 25 15:25:48 2010 @@ -10,7 +10,7 @@ def cache_file_path(c_files, eci, cachename): cache_dir = cache_dir_root.join(cachename).ensure(dir=1) filecontents = [c_file.read() for c_file in c_files] - key = repr((filecontents, eci)) + key = repr((filecontents, eci, platform.key())) hash = md5(key).hexdigest() return cache_dir.join(hash) Modified: pypy/branch/stringbuilder2/pypy/tool/udir.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/tool/udir.py (original) +++ pypy/branch/stringbuilder2/pypy/tool/udir.py Mon Jan 25 15:25:48 2010 @@ -18,7 +18,7 @@ # import autopath -import os +import os, sys import py from py.path import local @@ -30,6 +30,8 @@ else: return basename.split('/')[-2] +PYPY_KEEP = int(os.environ.get('PYPY_USESSION_KEEP', '3')) + def make_udir(dir=None, basename=None): if dir is not None: dir = local(dir) @@ -37,6 +39,8 @@ try: p = py.path.local(__file__).dirpath() basename = svn_info(py.path.svnwc(p).info().url) + if isinstance(basename, unicode): + basename = basename.encode(sys.getdefaultencoding()) except: basename = '' if not basename.startswith('-'): @@ -45,7 +49,7 @@ basename = basename + '-' return local.make_numbered_dir(rootdir = dir, prefix = 'usession' + basename, - keep = 3) + keep = PYPY_KEEP) udir = make_udir(dir = os.environ.get('PYPY_USESSION_DIR'), basename = os.environ.get('PYPY_USESSION_BASENAME')) Modified: pypy/branch/stringbuilder2/pypy/translator/backendopt/test/test_writeanalyze.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/backendopt/test/test_writeanalyze.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/backendopt/test/test_writeanalyze.py Mon Jan 25 15:25:48 2010 @@ -4,14 +4,15 @@ from pypy.translator.translator import TranslationContext, graphof from pypy.translator.simplify import get_funcobj from pypy.translator.backendopt.writeanalyze import WriteAnalyzer, top_set +from pypy.translator.backendopt.writeanalyze import ReadWriteAnalyzer from pypy.translator.backendopt.all import backend_optimizations from pypy.conftest import option -class BaseTestCanRaise(object): +class BaseTest(object): type_system = None - + Analyzer = WriteAnalyzer def translate(self, func, sig): t = TranslationContext() @@ -19,7 +20,10 @@ t.buildrtyper(type_system=self.type_system).specialize() if option.view: t.view() - return t, WriteAnalyzer(t) + return t, self.Analyzer(t) + + +class BaseTestWriteAnalyze(BaseTest): def test_writes_simple(self): def g(x): @@ -146,7 +150,7 @@ assert not result -class TestLLtype(BaseTestCanRaise): +class TestLLtype(BaseTestWriteAnalyze): type_system = 'lltype' def test_list(self): @@ -205,7 +209,7 @@ assert name.endswith("foobar") -class TestOOtype(BaseTestCanRaise): +class TestOOtype(BaseTestWriteAnalyze): type_system = 'ootype' def test_array(self): @@ -240,3 +244,88 @@ result = wa.analyze(ggraph.startblock.operations[0]) assert result is top_set + + +class TestLLtypeReadWriteAnalyze(BaseTest): + Analyzer = ReadWriteAnalyzer + type_system = 'lltype' + + def test_read_simple(self): + def g(x): + return True + + def f(x): + return g(x - 1) + t, wa = self.translate(f, [int]) + fgraph = graphof(t, f) + result = wa.analyze(fgraph.startblock.operations[0]) + assert not result + + def test_read_really(self): + class A(object): + def __init__(self, y): + self.y = y + def f(self): + self.x = 1 + return self.y + def h(flag): + obj = A(flag) + return obj.f() + + t, wa = self.translate(h, [int]) + hgraph = graphof(t, h) + op_call_f = hgraph.startblock.operations[-1] + + # check that we fished the expected ops + assert op_call_f.opname == "direct_call" + assert get_funcobj(op_call_f.args[0].value)._name == 'A.f' + + result = wa.analyze(op_call_f) + assert len(result) == 2 + result = list(result) + result.sort() + [(struct1, T1, name1), (struct2, T2, name2)] = result + assert struct1 == "readstruct" + assert name1.endswith("y") + assert struct2 == "struct" + assert name2.endswith("x") + assert T1 == T2 + + def test_contains(self): + def g(x, y, z): + l = [x] + return f(l, y, z) + def f(x, y, z): + return y in x + + t, wa = self.translate(g, [int, int, int]) + ggraph = graphof(t, g) + assert ggraph.startblock.operations[-1].opname == 'direct_call' + + result = wa.analyze(ggraph.startblock.operations[-1]) + ARRAYPTR = list(result)[0][1] + assert list(result) == [("readarray", ARRAYPTR)] + assert isinstance(ARRAYPTR.TO, lltype.GcArray) + + def test_adt_method(self): + def ll_callme(n): + return n + ll_callme = lltype.staticAdtMethod(ll_callme) + S = lltype.GcStruct('S', ('x', lltype.Signed), + adtmeths = {'yep': True, + 'callme': ll_callme}) + def g(x, y, z): + p = lltype.malloc(S) + p.x = x + if p.yep: + z *= p.callme(y) + return z + def f(x, y, z): + return g(x, y, z) + + t, wa = self.translate(f, [int, int, int]) + fgraph = graphof(t, f) + assert fgraph.startblock.operations[-1].opname == 'direct_call' + + result = wa.analyze(fgraph.startblock.operations[-1]) + assert list(result) == [("struct", lltype.Ptr(S), "x")] Modified: pypy/branch/stringbuilder2/pypy/translator/backendopt/writeanalyze.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/backendopt/writeanalyze.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/backendopt/writeanalyze.py Mon Jan 25 15:25:48 2010 @@ -45,3 +45,15 @@ elif methname in ('ll_getitem_fast', 'll_length'): return self.bottom_result() return graphanalyze.GraphAnalyzer.analyze_external_method(self, op, TYPE, meth) + + +class ReadWriteAnalyzer(WriteAnalyzer): + + def analyze_simple_operation(self, op): + if op.opname == "getfield": + return frozenset([ + ("readstruct", op.args[0].concretetype, op.args[1].value)]) + elif op.opname == "getarrayitem": + return frozenset([ + ("readarray", op.args[0].concretetype)]) + return WriteAnalyzer.analyze_simple_operation(self, op) Modified: pypy/branch/stringbuilder2/pypy/translator/benchmark/bench-custom.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/benchmark/bench-custom.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/benchmark/bench-custom.py Mon Jan 25 15:25:48 2010 @@ -34,7 +34,7 @@ benchmarks.append(b) exes = get_executables(args) - pythons = 'python2.5 python2.4 python2.3'.split() + pythons = 'python2.6 python2.5 python2.4'.split() full_pythons = [] for python in pythons: full_python = py.path.local.sysfind(python) @@ -44,6 +44,7 @@ sys.stdout.flush() refs = {} + final_error_count = 0 if not options.nocpython: exes = full_pythons + exes @@ -52,7 +53,10 @@ if i is not None: for exe in exes: for b in benchmarks: - benchmark_result.result(exe, allowcreate=True).run_benchmark(b, verbose=options.verbose) + br = benchmark_result.result(exe, allowcreate=True) + result = br.run_benchmark(b, verbose=options.verbose) + if not result: + final_error_count += 1 if options.relto: relto = options.relto @@ -83,6 +87,10 @@ print row print + if final_error_count: + raise SystemExit("%d benchmark run(s) failed (see -FAILED- above)" + % final_error_count) + if __name__ == '__main__': from optparse import OptionParser parser = OptionParser() Modified: pypy/branch/stringbuilder2/pypy/translator/benchmark/benchmarks.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/benchmark/benchmarks.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/benchmark/benchmarks.py Mon Jan 25 15:25:48 2010 @@ -1,15 +1,16 @@ import os, sys, time, pickle, re, py +import yaml class BenchmarkFailed(Exception): pass PYSTONE_CMD = 'from test import pystone;pystone.main(%s)' PYSTONE_PATTERN = 'This machine benchmarks at' -PYSTONE_ASCENDING_GOOD = True RICHARDS_CMD = 'from richards import *;main(iterations=%d)' RICHARDS_PATTERN = 'Average time per iteration:' -RICHARDS_ASCENDING_GOOD = False + +TIME_FMT = 'max mem used: %Mk\nelapsed time: %e\nsystem time: %S\nuser time: %U\nCPU use: %P' def get_result(txt, pattern): for line in txt.split('\n'): @@ -36,60 +37,40 @@ return Benchmark(self._basename, self._run, self.asc_good, self.units, self.check, self.sizefactor * n) def run(self, exe): - global latest_output - latest_output = '' try: - result = self._run(exe, self.sizefactor) + result, latest_output = self._run(exe, self.sizefactor) + self.latest_output = latest_output except BenchmarkFailed, e: result = '-FAILED-' - self.latest_output = latest_output return result -def external_dependency(dirname, svnurl, revision): - """Check out (if necessary) a given fixed revision of a svn url.""" - dirpath = py.path.local(__file__).dirpath().join(dirname) - revtag = dirpath.join('-svn-rev-') - if dirpath.check(): - if not revtag.check() or int(revtag.read()) != revision: - print >> sys.stderr, ("Out-of-date benchmark checkout!" - " I won't update it automatically.") - print >> sys.stderr, ("To continue, move away or remove the " - "%r directory." % (dirname,)) - sys.exit(1) - return True - CMD = "svn co -r%d %s@%d %s" % (revision, svnurl, revision, dirpath) - print >> sys.stderr, CMD - err = os.system(CMD) - if err != 0: - print >> sys.stderr, "* checkout failed, skipping this benchmark" - return False - revtag.write(str(revision)) +def external_dependency(dirname, svnurl, revision=None): + directory = py.path.local(__file__).dirpath().join(dirname) + wc = py.path.svnwc(directory) + wc.checkout(svnurl, rev=revision) return True def run_cmd(cmd): - global latest_output - #print "running", cmd pipe = os.popen(cmd + ' 2>&1') r = pipe.read() status = pipe.close() - latest_output = r if status: raise BenchmarkFailed(status) return r -def run_pystone(executable='/usr/local/bin/python', sizefactor=1): +def run_pystone(executable, sizefactor=1): from pypy.tool import autopath distdir = py.path.local(autopath.pypydir).dirpath() pystone = py.path.local(autopath.libpythondir).join('test', 'pystone.py') txt = run_cmd('"%s" "%s" %d' % (executable, pystone, 50000 * sizefactor)) - return get_result(txt, PYSTONE_PATTERN) + return get_result(txt, PYSTONE_PATTERN), txt -def run_richards(executable='/usr/local/bin/python', sizefactor=1): +def run_richards(executable, sizefactor=1): richards = py.path.local(__file__).dirpath().dirpath().join('goal').join('richards.py') txt = run_cmd('"%s" %s %d' % (executable, richards, 5 * sizefactor)) - return get_result(txt, RICHARDS_PATTERN) + return get_result(txt, RICHARDS_PATTERN), txt -def run_translate(executable='/usr/local/bin/python'): +def run_translate(executable): translate = py.path.local(__file__).dirpath().dirpath().join('goal').join('translate.py') target = py.path.local(__file__).dirpath().dirpath().join('goal').join('targetrpystonedalone.py') argstr = '%s %s --batch --backendopt --no-compile %s > /dev/null 2> /dev/null' @@ -100,39 +81,7 @@ raise BenchmarkFailed(status) return r -def run_docutils(executable='/usr/local/bin/python'): - docutilssvnpath = 'docutils' # subdir of the local dir - translatetxt = py.path.local(__file__).dirpath().dirpath().dirpath().join('doc').join('translation.txt') - command = """import sys -sys.modules['unicodedata'] = sys # docutils need 'import unicodedata' to work, but no more... -sys.path[0:0] = ['%s', '%s/extras'] -from docutils.core import publish_cmdline -publish_cmdline(writer_name='html') -"""%(docutilssvnpath, docutilssvnpath) - T = time.time() - pid = os.fork() - if not pid: - davenull = os.open('/dev/null', os.O_RDWR) - os.dup2(davenull, 0) - os.dup2(davenull, 1) - os.dup2(davenull, 2) - status = os.spawnv(os.P_WAIT, executable, [executable, '-c', command, str(translatetxt)]) - os._exit(status) - else: - status = os.waitpid(pid, 0)[1] - r = time.time() - T - if status: - raise BenchmarkFailed(status) - return r - -def check_docutils(): - return False # useless benchmark - I've seen 15% of difference - # between two successive runs on the same machine! - #return external_dependency('docutils', - # 'svn://svn.berlios.de/docutils/trunk/docutils', - # 4821) - -def run_templess(executable='/usr/local/bin/python', sizefactor=1): +def run_templess(executable, sizefactor=1): """ run some script in the templess package templess is some simple templating language, to check out use @@ -149,7 +98,7 @@ for line in txt.split('\n'): if '.' in line: try: - return float(line) / sizefactor + return float(line) / sizefactor, txt except ValueError: pass else: @@ -160,7 +109,7 @@ 'http://johnnydebris.net/templess/trunk', 100) -def run_gadfly(executable='/usr/local/bin/python', sizefactor=1): +def run_gadfly(executable, sizefactor=1): """ run some tests in the gadfly pure Python database """ here = py.path.local(__file__).dirpath() gadfly = here.join('gadfly') @@ -168,14 +117,14 @@ command = 'PYTHONPATH="%s" "%s" "%s" %d' % (gadfly, executable, testscript, sizefactor) txt = run_cmd(command) - return get_result(txt, 'Total running time:') / sizefactor + return get_result(txt, 'Total running time:') / sizefactor, txt def check_gadfly(): return external_dependency('gadfly', 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/gadflyZip', 70117) -def run_mako(executable='/usr/local/bin/python', sizefactor=1): +def run_mako(executable, sizefactor=1): """ run some tests in the mako templating system """ here = py.path.local(__file__).dirpath() mako = here.join('mako') @@ -184,29 +133,64 @@ executable, testscript, 2000 * sizefactor) txt = run_cmd(command) - return get_result(txt, 'Mako:') + return get_result(txt, 'Mako:'), txt def check_mako(): return external_dependency('mako', 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/mako', - 70118) + 70118) def check_translate(): return False # XXX what should we do about the dependency on ctypes? -BENCHMARKS = [Benchmark('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'), - Benchmark('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''), - Benchmark('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms', check_translate), - Benchmark('docutils', run_docutils, RICHARDS_ASCENDING_GOOD, - 's', check_docutils), - Benchmark('templess', run_templess, RICHARDS_ASCENDING_GOOD, +class LanguageShootoutBenchmark(Benchmark): + def __init__(self, name, sizefactor=1, test=False): + self.test = test + self.basename = name + Benchmark.__init__(self, name, self.runner, False, 'ms', + self.check, sizefactor) + + def __mul__(self, i): + return LanguageShootoutBenchmark(self.name, self.sizefactor * i, + self.test) + + def runner(self, executable, sizefactor=1): + shootout = py.path.local(__file__).dirpath().join( + 'shootout_benchmarks') + argsfile = shootout.join('tests.yml') + if self.test: + kind = 'test' + else: + kind = 'run' + args = yaml.load(argsfile.read())[self.basename][kind]['args'] + progname = str(shootout.join(self.basename)) + '.py' + cmd = 'time -f "%s" %s %s %s %d' % (TIME_FMT, executable, progname, + " ".join(args), sizefactor) + txt = run_cmd(cmd) + return get_result(txt, 'elapsed time:'), txt + + def check(self): + return external_dependency('shootout_benchmarks', + 'http://codespeak.net/svn/pypy/benchmarks/shootout') + +BENCHMARKS = [Benchmark('richards', run_richards, False, 'ms'), + Benchmark('pystone', run_pystone, True, ''), + Benchmark('translate', run_translate, False, 'ms', + check_translate), + Benchmark('templess', run_templess, False, 's', check_templess), - Benchmark('gadfly2', run_gadfly, RICHARDS_ASCENDING_GOOD, + Benchmark('gadfly2', run_gadfly, False, 's', check_gadfly), - Benchmark('mako', run_mako, RICHARDS_ASCENDING_GOOD, + Benchmark('mako', run_mako, False, 's', check_mako), ] +SHOOTOUT_NAMES = ['binary-trees', 'fannkuch', 'fasta', 'float', + 'meteor-contest', 'nbody', 'spectral-norm'] + +#for name in SHOOTOUT_NAMES: +# BENCHMARKS.append(LanguageShootoutBenchmark(name)) + BENCHMARKS_BY_NAME = {} for _b in BENCHMARKS: BENCHMARKS_BY_NAME[_b.name] = _b Modified: pypy/branch/stringbuilder2/pypy/translator/benchmark/jitbench.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/benchmark/jitbench.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/benchmark/jitbench.py Mon Jan 25 15:25:48 2010 @@ -4,7 +4,7 @@ parser = OptionParser() parser.add_option( '--size-factor-list', dest='sizefactorlist', - default='1,2,5,1,2,5,1,2,5', + default='1,2,5,20,1,2,5,20,1,2,5,20', ) options, args = parser.parse_args(sys.argv[1:]) args = args or [sys.executable] @@ -13,9 +13,18 @@ os.chdir(os.path.dirname(sys.argv[0]) or '.') +errors = [] + for sizefactor in sizefactors: for executable in executables: sys.argv[1:] = [executable, '--pickle=jitbench.benchmark_result', '-v', '--no-cpython', '--size-factor=%d' % sizefactor] - execfile('bench-custom.py') + try: + execfile('bench-custom.py') + except SystemExit, e: + errors.append('%s:*%s: %s' % (executable, sizefactor, e)) + +if errors: + print '\n'.join(errors) + sys.exit(1) Modified: pypy/branch/stringbuilder2/pypy/translator/benchmark/result.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/benchmark/result.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/benchmark/result.py Mon Jan 25 15:25:48 2010 @@ -88,7 +88,7 @@ def run_benchmark(self, benchmark, verbose=False): self.asc_goods[benchmark.name] = benchmark.asc_good if self.run_counts.get(benchmark.name, 0) > self.max_results: - return + return -1 print 'running', benchmark.name, 'for', self.exe_name, if verbose and self.pypy_rev > 0: print '[rev %d]' % self.pypy_rev, @@ -97,12 +97,15 @@ print new_result if verbose: print '{' - for line in benchmark.latest_output.splitlines(False): + lines = benchmark.latest_output.splitlines(False) + for line in lines[:80]: print '\t' + line + if len(lines) > 80: + print '\t....' print '}' self.run_counts[benchmark.name] = self.run_counts.get(benchmark.name, 0) + 1 if new_result == '-FAILED-': - return + return 0 self.benchmarks.setdefault(benchmark.name, []).append(new_result) if benchmark.name in self.best_benchmarks: old_result = self.best_benchmarks[benchmark.name] @@ -111,6 +114,7 @@ else: new_result = min(new_result, old_result) self.best_benchmarks[benchmark.name] = new_result + return 1 def getstat(self, *args): # oh for supplied-p! Modified: pypy/branch/stringbuilder2/pypy/translator/c/funcgen.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/funcgen.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/funcgen.py Mon Jan 25 15:25:48 2010 @@ -793,8 +793,12 @@ def OP_JIT_MARKER(self, op): return '/* JIT_MARKER %s */' % op - def OP_PROMOTE_VIRTUALIZABLE(self, op): - return '/* PROMOTE_VIRTUALIZABLE %s */' % op + def OP_JIT_FORCE_VIRTUALIZABLE(self, op): + return '/* JIT_FORCE_VIRTUALIZABLE %s */' % op + + def OP_JIT_FORCE_VIRTUAL(self, op): + return '%s = %s; /* JIT_FORCE_VIRTUAL */' % (self.expr(op.result), + self.expr(op.args[0])) def OP_GET_GROUP_MEMBER(self, op): typename = self.db.gettype(op.result.concretetype) @@ -813,5 +817,26 @@ self.expr(op.args[1]), self.expr(op.args[2])) + def getdebugfunctionname(self): + name = self.functionname + if not name: + return "?" + if name.startswith('pypy_g_'): + name = name[7:] + return name + + def OP_DEBUG_RECORD_TRACEBACK(self, op): + #if self.functionname is None, we print "?" as the argument */ + return 'PYPY_DEBUG_RECORD_TRACEBACK("%s");' % ( + self.getdebugfunctionname(),) + + def OP_DEBUG_CATCH_EXCEPTION(self, op): + gottype = self.expr(op.args[0]) + exprs = [] + for c_limited_type in op.args[1:]: + exprs.append('%s == %s' % (gottype, self.expr(c_limited_type))) + return 'PYPY_DEBUG_CATCH_EXCEPTION("%s", %s, %s);' % ( + self.getdebugfunctionname(), gottype, ' || '.join(exprs)) + assert not USESLOTS or '__dict__' not in dir(FunctionCodeGenerator) Modified: pypy/branch/stringbuilder2/pypy/translator/c/gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/gc.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/gc.py Mon Jan 25 15:25:48 2010 @@ -215,8 +215,8 @@ def compilation_info(self): eci = BasicGcPolicy.compilation_info(self) - from pypy.rpython.tool.rffi_platform import check_boehm - eci = eci.merge(check_boehm()) + from pypy.rpython.tool.rffi_platform import configure_boehm + eci = eci.merge(configure_boehm()) pre_include_bits = [] if sys.platform == "linux2": @@ -253,6 +253,9 @@ nbytes = funcgen.expr(op.args[0]) return 'GC_set_max_heap_size(%s);' % (nbytes,) + def GC_KEEPALIVE(self, funcgen, v): + return 'pypy_asm_keepalive(%s);' % funcgen.expr(v) + class BoehmGcRuntimeTypeInfo_OpaqueNode(ContainerNode): nodekind = 'boehm rtti' globalcontainer = True Modified: pypy/branch/stringbuilder2/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/genc.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/genc.py Mon Jan 25 15:25:48 2010 @@ -430,12 +430,16 @@ bk = self.translator.annotator.bookkeeper return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph()) - def cmdexec(self, args='', env=None, err=False): + def cmdexec(self, args='', env=None, err=False, expect_crash=False): assert self._compiled res = self.translator.platform.execute(self.executable_name, args, env=env) if res.returncode != 0: + if expect_crash: + return res.out, res.err raise Exception("Returned %d" % (res.returncode,)) + if expect_crash: + raise Exception("Program did not crash!") if err: return res.out, res.err return res.out @@ -711,6 +715,7 @@ print >> fc, '/*** Implementations ***/' print >> fc print >> fc, '#define PYPY_NOT_MAIN_FILE' + print >> fc, '#define PYPY_FILE_NAME "%s"' % name print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' @@ -783,6 +788,7 @@ print >> f, '/***********************************************************/' print >> f, '/*** Implementations ***/' print >> f + print >> f, '#define PYPY_FILE_NAME "%s"' % os.path.basename(f.name) for line in preimplementationlines: print >> f, line print >> f, '#include "src/g_include.h"' Modified: pypy/branch/stringbuilder2/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/src/g_include.h (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/src/g_include.h Mon Jan 25 15:25:48 2010 @@ -17,11 +17,7 @@ #include "src/mem.h" #include "src/exception.h" #include "src/support.h" -#ifndef AVR -#include "src/trace.h" -#else - #define PY_LONG_LONG long long -#endif +#define PY_LONG_LONG long long #ifndef PYPY_STANDALONE # include "src/pyobj.h" @@ -51,7 +47,8 @@ /*** modules ***/ #ifdef HAVE_RTYPER /* only if we have an RTyper */ # include "src/rtyper.h" -# include "src/debug.h" +# include "src/debug_print.h" +# include "src/debug_traceback.h" #ifndef AVR # include "src/ll_os.h" # include "src/ll_strtod.h" Modified: pypy/branch/stringbuilder2/pypy/translator/c/src/main.h ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/src/main.h (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/src/main.h Mon Jan 25 15:25:48 2010 @@ -36,12 +36,8 @@ exitcode = STANDALONE_ENTRY_POINT(list); if (RPyExceptionOccurred()) { - /* fish for the exception type, at least */ -#ifndef AVR - fprintf(stderr, "Fatal RPython error: %s\n", - RPyFetchExceptionType()->ov_name->items); -#endif - abort(); + /* print the RPython traceback */ + pypy_debug_catch_fatal_exception(); } return exitcode; Modified: pypy/branch/stringbuilder2/pypy/translator/c/test/test_boehm.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/test/test_boehm.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/test/test_boehm.py Mon Jan 25 15:25:48 2010 @@ -3,12 +3,16 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.memory.test import snippet -from pypy.rpython.tool.rffi_platform import check_boehm from pypy.translator.c.genc import CExtModuleBuilder +from pypy.rlib.objectmodel import keepalive_until_here from pypy import conftest def setup_module(mod): - if not check_boehm(): + from pypy.rpython.tool.rffi_platform import configure_boehm + from pypy.translator.platform import CompilationError + try: + configure_boehm() + except CompilationError: py.test.skip("Boehm GC not present") class AbstractGCTestClass(object): @@ -287,6 +291,7 @@ assert a.index == i & ~1 else: count_free += 1 + keepalive_until_here(keepalive) return count_free c_fn = self.getcompiled(fn, [int]) res = c_fn(7000) Modified: pypy/branch/stringbuilder2/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/test/test_genc.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/test/test_genc.py Mon Jan 25 15:25:48 2010 @@ -334,6 +334,7 @@ f = compile(prob_with_pyobj, [object]) from sys import getrefcount as g obj = None + import gc; gc.collect() before = g(obj) f(obj) after = g(obj) Modified: pypy/branch/stringbuilder2/pypy/translator/c/test/test_stackless.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/test/test_stackless.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/test/test_stackless.py Mon Jan 25 15:25:48 2010 @@ -20,8 +20,11 @@ import py py.test.skip("stackless + refcounting doesn't work any more for now") elif cls.gcpolicy == "boehm": - from pypy.rpython.tool.rffi_platform import check_boehm - if not check_boehm(): + from pypy.rpython.tool.rffi_platform import configure_boehm + from pypy.translator.platform import CompilationError + try: + configure_boehm() + except CompilationError: py.test.skip("Boehm GC not present") def wrap_stackless_function(self, fn): Modified: pypy/branch/stringbuilder2/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/test/test_standalone.py Mon Jan 25 15:25:48 2010 @@ -10,6 +10,7 @@ from pypy.annotation.listdef import s_list_of_strings from pypy.tool.udir import udir from pypy.tool.autopath import pypydir +from pypy.conftest import option class StandaloneTests(object): @@ -21,8 +22,10 @@ t.buildrtyper().specialize() cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() + cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() + if option.view: + t.view() return t, cbuilder @@ -377,6 +380,186 @@ assert not err assert path.check(file=0) + def test_fatal_error(self): + def g(x): + if x == 1: + raise ValueError + else: + raise KeyError + def entry_point(argv): + if len(argv) < 3: + g(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: ValueError' + assert len(lines) >= 4 + l0, l1, l2 = lines[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) + # + out2, err2 = cbuilder.cmdexec("x", expect_crash=True) + assert out2.strip() == '' + lines2 = err2.strip().splitlines() + assert lines2[-1] == 'Fatal RPython error: KeyError' + l0, l1, l2 = lines2[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) + assert lines2[-2] != lines[-2] # different line number + assert lines2[-3] == lines[-3] # same line number + + def test_fatal_error_finally_1(self): + # a simple case of try:finally: + def g(x): + if x == 1: + raise KeyError + def h(x): + try: + g(x) + finally: + os.write(1, 'done.\n') + def entry_point(argv): + if len(argv) < 3: + h(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == 'done.' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: KeyError' + assert len(lines) >= 5 + l0, l1, l2, l3 = lines[-5:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in h', l2) + assert re.match(r' File "\w+.c", line \d+, in g', l3) + + def test_fatal_error_finally_2(self): + # a try:finally: in which we raise and catch another exception + def raiseme(x): + if x == 1: + raise ValueError + def raise_and_catch(x): + try: + raiseme(x) + except ValueError: + pass + def g(x): + if x == 1: + raise KeyError + def h(x): + try: + g(x) + finally: + raise_and_catch(x) + os.write(1, 'done.\n') + def entry_point(argv): + if len(argv) < 3: + h(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == 'done.' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: KeyError' + assert len(lines) >= 5 + l0, l1, l2, l3 = lines[-5:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in h', l2) + assert re.match(r' File "\w+.c", line \d+, in g', l3) + + def test_fatal_error_finally_3(self): + py.test.skip("not implemented: " + "a try:finally: in which we raise the *same* exception") + + def test_fatal_error_finally_4(self): + # a try:finally: in which we raise (and don't catch) an exception + def raiseme(x): + if x == 1: + raise ValueError + def g(x): + if x == 1: + raise KeyError + def h(x): + try: + g(x) + finally: + raiseme(x) + os.write(1, 'done.\n') + def entry_point(argv): + if len(argv) < 3: + h(len(argv)) + return 0 + t, cbuilder = self.compile(entry_point) + # + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: ValueError' + assert len(lines) >= 5 + l0, l1, l2, l3 = lines[-5:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) + assert re.match(r' File "\w+.c", line \d+, in h', l2) + assert re.match(r' File "\w+.c", line \d+, in raiseme', l3) + + def test_assertion_error(self): + def g(x): + assert x != 1 + def f(argv): + try: + g(len(argv)) + finally: + print 'done' + def entry_point(argv): + f(argv) + return 0 + t, cbuilder = self.compile(entry_point) + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'Fatal RPython error: AssertionError' + assert len(lines) >= 4 + l0, l1, l2 = lines[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in f', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) + # The traceback stops at f() because it's the first function that + # captures the AssertionError, which makes the program abort. + + def test_ll_assert_error(self): + py.test.skip("implement later, maybe: tracebacks even with ll_assert") + def g(x): + ll_assert(x != 1, "foobar") + def f(argv): + try: + g(len(argv)) + finally: + print 'done' + def entry_point(argv): + f(argv) + return 0 + t, cbuilder = self.compile(entry_point) + out, err = cbuilder.cmdexec("", expect_crash=True) + assert out.strip() == '' + lines = err.strip().splitlines() + assert lines[-1] == 'PyPy assertion failed: foobar' + assert len(lines) >= 4 + l0, l1, l2 = lines[-4:-1] + assert l0 == 'RPython traceback:' + assert re.match(r' File "\w+.c", line \d+, in f', l1) + assert re.match(r' File "\w+.c", line \d+, in g', l2) + # The traceback stops at f() because it's the first function that + # captures the AssertionError, which makes the program abort. + class TestMaemo(TestStandalone): def setup_class(cls): @@ -407,7 +590,7 @@ t.buildrtyper().specialize() # cbuilder = CStandaloneBuilder(t, entry_point, t.config) - cbuilder.generate_source() + cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() # return t, cbuilder Modified: pypy/branch/stringbuilder2/pypy/translator/cli/opcodes.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/cli/opcodes.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/cli/opcodes.py Mon Jan 25 15:25:48 2010 @@ -77,6 +77,11 @@ 'gc_set_max_heap_size': Ignore, 'resume_point': Ignore, 'debug_assert': Ignore, + 'debug_start_traceback': Ignore, + 'debug_record_traceback': Ignore, + 'debug_catch_exception': Ignore, + 'debug_reraise_traceback': Ignore, + 'debug_print_traceback': Ignore, 'debug_print': [DebugPrint], 'debug_start': [PushAllArgs, 'call void [pypylib]pypy.runtime.DebugPrint::DEBUG_START(string)'], 'debug_stop': [PushAllArgs, 'call void [pypylib]pypy.runtime.DebugPrint::DEBUG_STOP(string)'], @@ -84,7 +89,8 @@ 'debug_fatalerror': [PushAllArgs, 'call void [pypylib]pypy.runtime.Debug::DEBUG_FATALERROR(string)'], 'keepalive': Ignore, 'jit_marker': Ignore, - 'promote_virtualizable': Ignore, + 'jit_force_virtualizable': Ignore, + 'jit_force_virtual': DoNothing, } # __________ numeric operations __________ Modified: pypy/branch/stringbuilder2/pypy/translator/driver.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/driver.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/driver.py Mon Jan 25 15:25:48 2010 @@ -428,10 +428,13 @@ def possibly_check_for_boehm(self): if self.config.translation.gc == "boehm": - from pypy.rpython.tool.rffi_platform import check_boehm - if not check_boehm(self.translator.platform): + from pypy.rpython.tool.rffi_platform import configure_boehm + from pypy.translator.platform import CompilationError + try: + configure_boehm(self.translator.platform) + except CompilationError, e: i = 'Boehm GC not installed. Try e.g. "translate.py --gc=hybrid"' - raise Exception(i) + raise Exception(str(e) + '\n' + i) def task_database_c(self): translator = self.translator Modified: pypy/branch/stringbuilder2/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/exceptiontransform.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/exceptiontransform.py Mon Jan 25 15:25:48 2010 @@ -3,11 +3,10 @@ from pypy.translator.unsimplify import insert_empty_block, split_block from pypy.translator.backendopt import canraise, inline, support, removenoops from pypy.objspace.flow.model import Block, Constant, Variable, Link, \ - c_last_exception, SpaceOperation, checkgraph, FunctionGraph + c_last_exception, SpaceOperation, checkgraph, FunctionGraph, mkentrymap from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem import lloperation -from pypy.rpython.lltypesystem.llmemory import NULL from pypy.rpython import rtyper from pypy.rpython import rclass from pypy.rpython.rmodel import inputconst @@ -16,6 +15,7 @@ from pypy.rlib.debug import ll_assert from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator +from pypy.tool.sourcetools import func_with_new_name PrimitiveErrorValue = {lltype.Signed: -1, lltype.Unsigned: r_uint(-1), @@ -26,7 +26,7 @@ lltype.Char: chr(255), lltype.UniChar: unichr(0xFFFF), # XXX is this always right? lltype.Bool: True, - llmemory.Address: NULL, + llmemory.Address: llmemory.NULL, lltype.Void: None} for TYPE in rffi.NUMBER_TYPES: @@ -45,6 +45,9 @@ def error_constant(T): return Constant(error_value(T), T) +def constant_value(llvalue): + return Constant(llvalue, lltype.typeOf(llvalue)) + class BaseExceptionTransformer(object): def __init__(self, translator): @@ -64,6 +67,10 @@ (n_i_error_ll_exc_type, n_i_error_ll_exc) = self.get_builtin_exception(NotImplementedError) + self.c_assertion_error_ll_exc_type = constant_value( + assertion_error_ll_exc_type) + self.c_n_i_error_ll_exc_type = constant_value(n_i_error_ll_exc_type) + def rpyexc_occured(): exc_type = exc_data.exc_type return bool(exc_type) @@ -80,10 +87,14 @@ def rpyexc_raise(etype, evalue): # assert(!RPyExceptionOccurred()); - ll_assert(etype != assertion_error_ll_exc_type, "AssertionError!") - ll_assert(etype != n_i_error_ll_exc_type, "NotImplementedError!") exc_data.exc_type = etype exc_data.exc_value = evalue + lloperation.llop.debug_start_traceback(lltype.Void, etype) + + def rpyexc_reraise(etype, evalue): + exc_data.exc_type = etype + exc_data.exc_value = evalue + lloperation.llop.debug_reraise_traceback(lltype.Void, etype) def rpyexc_fetch_exception(): evalue = rpyexc_fetch_value() @@ -92,7 +103,8 @@ def rpyexc_restore_exception(evalue): if evalue: - rpyexc_raise(rclass.ll_inst_type(evalue), evalue) + exc_data.exc_type = rclass.ll_inst_type(evalue) + exc_data.exc_value = evalue def rpyexc_raise_runtime_error(): rpyexc_raise(runtime_error_ll_exc_type, runtime_error_ll_exc) @@ -119,14 +131,21 @@ self.rpyexc_raise_ptr = self.build_func( "RPyRaiseException", - rpyexc_raise, + self.noinline(rpyexc_raise), + [self.lltype_of_exception_type, self.lltype_of_exception_value], + lltype.Void, + jitcallkind='rpyexc_raise') # for the JIT + + self.rpyexc_reraise_ptr = self.build_func( + "RPyReRaiseException", + rpyexc_reraise, [self.lltype_of_exception_type, self.lltype_of_exception_value], lltype.Void, jitcallkind='rpyexc_raise') # for the JIT self.rpyexc_raise_runtime_error_ptr = self.build_func( "RPyRaiseRuntimeError", - rpyexc_raise_runtime_error, + self.noinline(rpyexc_raise_runtime_error), [], lltype.Void) self.rpyexc_fetch_exception_ptr = self.build_func( @@ -136,7 +155,7 @@ self.rpyexc_restore_exception_ptr = self.build_func( "RPyRestoreException", - rpyexc_restore_exception, + self.noinline(rpyexc_restore_exception), [self.lltype_of_exception_value], lltype.Void) self.build_extra_funcs() @@ -144,6 +163,11 @@ self.mixlevelannotator.finish() self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping() + def noinline(self, fn): + fn = func_with_new_name(fn, fn.__name__) + fn._dont_inline_ = True + return fn + def build_func(self, name, fn, inputtypes, rettype, **kwds): l2a = annmodel.lltype_to_annotation graph = self.mixlevelannotator.getgraph(fn, map(l2a, inputtypes), l2a(rettype)) @@ -184,13 +208,18 @@ # collect the blocks before changing them n_need_exc_matching_blocks = 0 n_gen_exc_checks = 0 + # + entrymap = mkentrymap(graph) + if graph.exceptblock in entrymap: + for link in entrymap[graph.exceptblock]: + self.transform_jump_to_except_block(graph, entrymap, link) + # for block in list(graph.iterblocks()): self.replace_stack_unwind(block) self.replace_fetch_restore_operations(block) need_exc_matching, gen_exc_checks = self.transform_block(graph, block) n_need_exc_matching_blocks += need_exc_matching n_gen_exc_checks += gen_exc_checks - self.transform_except_block(graph, graph.exceptblock) cleanup_graph(graph) removenoops.remove_superfluous_keep_alive(graph) return n_need_exc_matching_blocks, n_gen_exc_checks @@ -268,18 +297,54 @@ self.insert_matching(lastblock, graph) return need_exc_matching, n_gen_exc_checks - def transform_except_block(self, graph, block): - # attach an except block -- let's hope that nobody uses it - graph.exceptblock = Block([Variable('etype'), # exception class - Variable('evalue')]) # exception value - graph.exceptblock.operations = () - graph.exceptblock.closeblock() - + def comes_from_last_exception(self, entrymap, link): + seen = {} + pending = [(link, link.args[1])] + while pending: + link, v = pending.pop() + if (link, v) in seen: + continue + seen[link, v] = True + if link.last_exc_value is not None and v is link.last_exc_value: + return True + block = link.prevblock + if block is None: + continue + for op in block.operations[::-1]: + if v is op.result: + if op.opname == 'cast_pointer': + v = op.args[0] + else: + break + for link in entrymap.get(block, ()): + for v1, v2 in zip(link.args, block.inputargs): + if v2 is v: + pending.append((link, v1)) + return False + + def transform_jump_to_except_block(self, graph, entrymap, link): + reraise = self.comes_from_last_exception(entrymap, link) result = Variable() result.concretetype = lltype.Void - block.operations = [SpaceOperation( - "direct_call", [self.rpyexc_raise_ptr] + block.inputargs, result)] - l = Link([error_constant(graph.returnblock.inputargs[0].concretetype)], graph.returnblock) + block = Block([copyvar(None, v) + for v in graph.exceptblock.inputargs]) + if reraise: + block.operations = [ + SpaceOperation("direct_call", + [self.rpyexc_reraise_ptr] + block.inputargs, + result), + ] + else: + block.operations = [ + SpaceOperation("direct_call", + [self.rpyexc_raise_ptr] + block.inputargs, + result), + SpaceOperation('debug_record_traceback', [], + varoftype(lltype.Void)), + ] + link.target = block + RETTYPE = graph.returnblock.inputargs[0].concretetype + l = Link([error_constant(RETTYPE)], graph.returnblock) block.recloseblock(l) def insert_matching(self, block, graph): @@ -328,6 +393,11 @@ llops = rtyper.LowLevelOpList(None) var_value = self.gen_getfield('exc_value', llops) var_type = self.gen_getfield('exc_type' , llops) + # + c_check1 = self.c_assertion_error_ll_exc_type + c_check2 = self.c_n_i_error_ll_exc_type + llops.genop('debug_catch_exception', [var_type, c_check1, c_check2]) + # self.gen_setfield('exc_value', self.c_null_evalue, llops) self.gen_setfield('exc_type', self.c_null_etype, llops) excblock.operations[:] = llops @@ -361,7 +431,12 @@ block.exitswitch = var_no_exc #exception occurred case + b = Block([]) + b.operations = [SpaceOperation('debug_record_traceback', [], + varoftype(lltype.Void))] l = Link([error_constant(returnblock.inputargs[0].concretetype)], returnblock) + b.closeblock(l) + l = Link([], b) l.exitcase = l.llexitcase = False #non-exception case Modified: pypy/branch/stringbuilder2/pypy/translator/goal/app_main.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/goal/app_main.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/goal/app_main.py Mon Jan 25 15:25:48 2010 @@ -228,7 +228,7 @@ newpath.insert(0, '') # remove duplicates _seen = {} - sys.path = [] + del sys.path[:] for dir in newpath: if dir not in _seen: sys.path.append(dir) Modified: pypy/branch/stringbuilder2/pypy/translator/jvm/opcodes.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/jvm/opcodes.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/jvm/opcodes.py Mon Jan 25 15:25:48 2010 @@ -97,9 +97,15 @@ 'gc_set_max_heap_size': Ignore, 'resume_point': Ignore, 'jit_marker': Ignore, - 'promote_virtualizable': Ignore, + 'jit_force_virtualizable': Ignore, + 'jit_force_virtual': DoNothing, 'debug_assert': [], # TODO: implement? + 'debug_start_traceback': Ignore, + 'debug_record_traceback': Ignore, + 'debug_catch_exception': Ignore, + 'debug_reraise_traceback': Ignore, + 'debug_print_traceback': Ignore, # __________ numeric operations __________ Modified: pypy/branch/stringbuilder2/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/platform/__init__.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/platform/__init__.py Mon Jan 25 15:25:48 2010 @@ -52,6 +52,8 @@ name = "abstract platform" c_environ = None + relevant_environ = [] + so_prefixes = [''] def __init__(self, cc): @@ -98,6 +100,12 @@ return (self.__class__ is other.__class__ and self.__dict__ == other.__dict__) + def key(self): + bits = [self.__class__.__name__, 'cc=%s' % self.cc] + for varname in self.relevant_environ: + bits.append('%s=%s' % (varname, os.environ.get(varname))) + return ' '.join(bits) + # some helpers which seem to be cross-platform enough def _execute_c_compiler(self, cc, args, outname): @@ -171,8 +179,15 @@ else: host_factory = Linux64 elif sys.platform == 'darwin': - from pypy.translator.platform.darwin import Darwin - host_factory = Darwin + from pypy.translator.platform.darwin import Darwin_i386, Darwin_x86_64 + import platform + if platform.machine() == 'i386': + if sys.maxint <= 2147483647: + host_factory = Darwin_i386 + else: + host_factory = Darwin_x86_64 + else: + host_factory = Darwin elif sys.platform == 'freebsd7': from pypy.translator.platform.freebsd7 import Freebsd7, Freebsd7_64 import platform Modified: pypy/branch/stringbuilder2/pypy/translator/platform/darwin.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/platform/darwin.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/platform/darwin.py Mon Jan 25 15:25:48 2010 @@ -4,7 +4,7 @@ class Darwin(posix.BasePosix): name = "darwin" - + link_flags = ['-mmacosx-version-min=10.4'] cflags = ['-O3', '-fomit-frame-pointer', '-mmacosx-version-min=10.4'] standalone_only = ['-mdynamic-no-pic'] @@ -44,3 +44,13 @@ include_dirs = self._includedirs(eci.include_dirs) return (args + frameworks + include_dirs) +class Darwin_i386(Darwin): + name = "darwin_i386" + link_flags = ['-arch', 'i386', '-mmacosx-version-min=10.4'] + cflags = ['-arch', 'i386', '-O3', '-fomit-frame-pointer', '-mmacosx-version-min=10.4'] + +class Darwin_x86_64(Darwin): + name = "darwin_x86_64" + link_flags = ['-arch', 'x86_64', '-mmacosx-version-min=10.4'] + cflags = ['-arch', 'x86_64', '-O3', '-fomit-frame-pointer', '-mmacosx-version-min=10.4'] + Modified: pypy/branch/stringbuilder2/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/platform/linux.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/platform/linux.py Mon Jan 25 15:25:48 2010 @@ -11,7 +11,7 @@ link_flags = ['-pthread', '-lrt'] cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] standalone_only = [] - shared_only = [] + shared_only = ['-fPIC'] so_ext = 'so' so_prefixes = ['lib', ''] Modified: pypy/branch/stringbuilder2/pypy/translator/platform/posix.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/platform/posix.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/platform/posix.py Mon Jan 25 15:25:48 2010 @@ -10,6 +10,8 @@ exe_ext = '' make_cmd = 'make' + relevant_environ=['CPATH', 'LIBRARY_PATH', 'C_INCLUDE_PATH'] + def __init__(self, cc=None): if cc is None: cc = 'gcc' Modified: pypy/branch/stringbuilder2/pypy/translator/platform/test/test_darwin.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/platform/test/test_darwin.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/platform/test/test_darwin.py Mon Jan 25 15:25:48 2010 @@ -2,17 +2,25 @@ """ File containing darwin platform tests """ -import py, sys +import py, sys, platform if sys.platform != 'darwin': py.test.skip("Darwin only") from pypy.tool.udir import udir -from pypy.translator.platform.darwin import Darwin +from pypy.translator.platform.darwin import Darwin_i386, Darwin_x86_64 from pypy.translator.platform.test.test_platform import TestPlatform as BasicTest from pypy.translator.tool.cbuild import ExternalCompilationInfo +if platform.machine() == 'i386': + if sys.maxint <= 2147483647: + host_factory = Darwin_i386 + else: + host_factory = Darwin_x86_64 +else: + host_factory = Darwin + class TestDarwin(BasicTest): - platform = Darwin() + platform = host_factory() def test_frameworks(self): objcfile = udir.join('test_simple.m') @@ -39,3 +47,81 @@ res = self.platform.execute(executable) self.check_res(res) + def test_64_32_results(self): + if platform.machine() != 'i386': + py.test.skip("i386 only") + plat32 = Darwin_i386() + plat64 = Darwin_x86_64() + cfile = udir.join('test_int_size.c') + cfile.write(r''' + #include + #include + + int main() { + printf("%d\n", INT_MAX < LONG_MAX); + return 0; + } + ''') + eci = ExternalCompilationInfo() + executable = plat32.compile([cfile], eci) + res = plat32.execute(executable) + self.check_res(res, '0\n') + if host_factory == Darwin_x86_64: + executable = plat64.compile([cfile], eci) + res = plat64.execute(executable) + self.check_res(res, '1\n') + + def test_longsize(self): + if platform.machine() != 'i386': + py.test.skip("i386 only") + cfile = udir.join('test_int_size.c') + cfile.write(r''' + #include + #include + + int main() { + printf("%ld\n", LONG_MAX); + return 0; + } + ''') + eci = ExternalCompilationInfo() + executable = self.platform.compile([cfile], eci) + res = self.platform.execute(executable) + self.check_res(res, str(sys.maxint) + '\n') + + def test_32bit_makefile(self): + if platform.machine() != 'i386': + py.test.skip("i386 only") + plat32 = Darwin_i386() + plat64 = Darwin_x86_64() + eci = ExternalCompilationInfo() + cfile_content =r''' + #include + #include + + int main() { + printf("%d\n", INT_MAX < LONG_MAX); + return 0; + } + ''' + + tmpdir = udir.join('32_makefile' + self.__class__.__name__).ensure(dir=1) + cfile = tmpdir.join('test_int_size.c') + cfile.write(cfile_content) + mk = plat32.gen_makefile([cfile], ExternalCompilationInfo(), + path=tmpdir) + mk.write() + plat32.execute_makefile(mk) + res = plat32.execute(tmpdir.join('test_int_size')) + self.check_res(res, '0\n') + if host_factory == Darwin_x86_64: + tmpdir = udir.join('64_makefile' + self.__class__.__name__).ensure(dir=1) + cfile = tmpdir.join('test_int_size.c') + cfile.write(cfile_content) + mk = plat64.gen_makefile([cfile], ExternalCompilationInfo(), + path=tmpdir) + mk.write() + plat64.execute_makefile(mk) + res = plat64.execute(tmpdir.join('test_int_size')) + self.check_res(res, '1\n') + Modified: pypy/branch/stringbuilder2/pypy/translator/platform/test/test_platform.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/platform/test/test_platform.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/platform/test/test_platform.py Mon Jan 25 15:25:48 2010 @@ -115,6 +115,16 @@ finally: del os.environ['_SOME_VARIABLE_2'] + def test_key(self): + class XPlatform(Platform): + relevant_environ = ['CPATH'] + + def __init__(self): + self.cc = 'xcc' + x = XPlatform() + res = x.key() + assert res.startswith('XPlatform cc=xcc CPATH=') + def test_equality(): class X(Platform): def __init__(self): Modified: pypy/branch/stringbuilder2/pypy/translator/test/test_exceptiontransform.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/test/test_exceptiontransform.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/test/test_exceptiontransform.py Mon Jan 25 15:25:48 2010 @@ -95,7 +95,7 @@ return 3 + x return 4 + x t, g = self.transform_func(foo, [int]) - assert len(list(g.iterblocks())) == 9 + assert len(list(g.iterblocks())) == 10 f = self.compile(foo, [int]) result = interpret(foo, [6]) assert result == 2 @@ -126,7 +126,7 @@ return 1 + x return 4 + x t, g = self.transform_func(foo, [int]) - assert len(list(g.iterblocks())) == 5 + assert len(list(g.iterblocks())) == 6 f = self.compile(foo, [int]) result = interpret(foo, [6]) assert result == 2 @@ -175,6 +175,34 @@ etrafo.create_exception_handling(g) assert etrafo.raise_analyzer.analyze_direct_call(g) + def test_reraise_is_not_raise(self): + def one(x): + if x == 1: + raise ValueError() + elif x == 2: + raise TypeError() + return x - 5 + def foo(x): + try: + return one(x) + except ValueError: + return -42 + t, g = self.transform_func(foo, [int]) + for block in g.iterblocks(): + for op in block.operations: + # the operation 'debug_record_traceback' should only show up + # in a normal raise, not in a reraise + assert op.opname != 'debug_record_traceback' + f = self.compile(foo, [int]) + result = interpret(foo, [7]) + assert result == 2 + result = f(7) + assert result == 2 + result = interpret(foo, [1]) + assert result == -42 + result = f(1) + assert result == -42 + class TestLLType(BaseTestExceptionTransform): type_system = 'lltype' From fijal at codespeak.net Mon Jan 25 15:59:10 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 15:59:10 +0100 (CET) Subject: [pypy-svn] r70837 - pypy/extradoc/planning Message-ID: <20100125145910.588A249843E@codespeak.net> Author: fijal Date: Mon Jan 25 15:59:09 2010 New Revision: 70837 Modified: pypy/extradoc/planning/jit.txt Log: Re-add a point which I'm unsure about Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Mon Jan 25 15:59:09 2010 @@ -36,6 +36,7 @@ instance - pypy-c-jit translate.py fails sometimes. Look into that + [Check if there are no failing applevel tests also] - improve ''.join and u''.join by using stringbuilder, enable realloc for hybrid GC (on stringbuilder branch so far). From arigo at codespeak.net Mon Jan 25 16:28:49 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 16:28:49 +0100 (CET) Subject: [pypy-svn] r70838 - in pypy/branch/lazy-operr-format/pypy: interpreter interpreter/test module/__builtin__ module/_codecs module/_file module/_rawffi module/_socket module/_stackless module/bz2 module/clr module/imp module/pypyjit module/rctime module/select module/sys module/thread module/zipimport objspace objspace/flow objspace/std tool tool/test translator translator/goal Message-ID: <20100125152849.98BBE318139@codespeak.net> Author: arigo Date: Mon Jan 25 16:28:47 2010 New Revision: 70838 Modified: pypy/branch/lazy-operr-format/pypy/interpreter/argument.py pypy/branch/lazy-operr-format/pypy/interpreter/baseobjspace.py pypy/branch/lazy-operr-format/pypy/interpreter/error.py pypy/branch/lazy-operr-format/pypy/interpreter/function.py pypy/branch/lazy-operr-format/pypy/interpreter/pycompiler.py pypy/branch/lazy-operr-format/pypy/interpreter/pyframe.py pypy/branch/lazy-operr-format/pypy/interpreter/pyopcode.py pypy/branch/lazy-operr-format/pypy/interpreter/test/test_argument.py pypy/branch/lazy-operr-format/pypy/interpreter/test/test_compiler.py pypy/branch/lazy-operr-format/pypy/interpreter/typedef.py pypy/branch/lazy-operr-format/pypy/module/__builtin__/descriptor.py pypy/branch/lazy-operr-format/pypy/module/__builtin__/interp_classobj.py pypy/branch/lazy-operr-format/pypy/module/_codecs/interp_codecs.py pypy/branch/lazy-operr-format/pypy/module/_file/interp_file.py pypy/branch/lazy-operr-format/pypy/module/_rawffi/interp_rawffi.py pypy/branch/lazy-operr-format/pypy/module/_rawffi/structure.py pypy/branch/lazy-operr-format/pypy/module/_socket/interp_func.py pypy/branch/lazy-operr-format/pypy/module/_stackless/interp_coroutine.py pypy/branch/lazy-operr-format/pypy/module/_stackless/interp_greenlet.py pypy/branch/lazy-operr-format/pypy/module/bz2/interp_bz2.py pypy/branch/lazy-operr-format/pypy/module/clr/interp_clr.py pypy/branch/lazy-operr-format/pypy/module/imp/importing.py pypy/branch/lazy-operr-format/pypy/module/imp/interp_imp.py pypy/branch/lazy-operr-format/pypy/module/pypyjit/interp_jit.py pypy/branch/lazy-operr-format/pypy/module/rctime/interp_time.py pypy/branch/lazy-operr-format/pypy/module/select/interp_select.py pypy/branch/lazy-operr-format/pypy/module/sys/__init__.py pypy/branch/lazy-operr-format/pypy/module/sys/vm.py pypy/branch/lazy-operr-format/pypy/module/thread/os_thread.py pypy/branch/lazy-operr-format/pypy/module/zipimport/interp_zipimport.py pypy/branch/lazy-operr-format/pypy/objspace/descroperation.py pypy/branch/lazy-operr-format/pypy/objspace/flow/flowcontext.py pypy/branch/lazy-operr-format/pypy/objspace/flow/framestate.py pypy/branch/lazy-operr-format/pypy/objspace/std/dictmultiobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/listobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/objecttype.py pypy/branch/lazy-operr-format/pypy/objspace/std/objspace.py pypy/branch/lazy-operr-format/pypy/objspace/std/ropeobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/ropeunicodeobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/stdtypedef.py pypy/branch/lazy-operr-format/pypy/objspace/std/stringobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/transparent.py pypy/branch/lazy-operr-format/pypy/objspace/std/typeobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/typetype.py pypy/branch/lazy-operr-format/pypy/objspace/std/unicodeobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/unicodetype.py pypy/branch/lazy-operr-format/pypy/tool/test/test_pytestsupport.py pypy/branch/lazy-operr-format/pypy/tool/traceop.py pypy/branch/lazy-operr-format/pypy/translator/geninterplevel.py pypy/branch/lazy-operr-format/pypy/translator/goal/sharedpypy.py pypy/branch/lazy-operr-format/pypy/translator/goal/targetpreimportedpypy.py pypy/branch/lazy-operr-format/pypy/translator/goal/targetpypystandalone.py Log: Finish the conversion of OperationErrors into operationerrfmt. Modified: pypy/branch/lazy-operr-format/pypy/interpreter/argument.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/argument.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/argument.py Mon Jan 25 16:28:47 2010 @@ -2,7 +2,7 @@ Arguments objects. """ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rlib.debug import make_sure_not_resized from pypy.rlib import jit @@ -160,10 +160,10 @@ raise OperationError(space.w_TypeError, space.wrap("keywords must be strings")) if self.keywords and key in self.keywords: - raise OperationError(self.space.w_TypeError, - self.space.wrap("got multiple values " - "for keyword argument " - "'%s'" % key)) + raise operationerrfmt(self.space.w_TypeError, + "got multiple values " + "for keyword argument " + "'%s'", key) keywords[i] = key keywords_w[i] = space.getitem(w_starstararg, w_key) i += 1 Modified: pypy/branch/lazy-operr-format/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/baseobjspace.py Mon Jan 25 16:28:47 2010 @@ -1,6 +1,6 @@ from pypy.interpreter.executioncontext import ExecutionContext, ActionFlag from pypy.interpreter.executioncontext import UserDelAction, FrameTraceAction -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.argument import Arguments from pypy.interpreter.pycompiler import CPythonCompiler, PythonAstCompiler from pypy.interpreter.miscutils import ThreadLocals @@ -54,9 +54,9 @@ def setdict(self, space, w_dict): typename = space.type(self).getname(space, '?') - raise OperationError(space.w_TypeError, - space.wrap("attribute '__dict__' of %s objects " - "is not writable" % typename)) + raise operationerrfmt(space.w_TypeError, + "attribute '__dict__' of %s objects " + "is not writable", typename) # to be used directly only by space.type implementations def getclass(self, space): @@ -112,9 +112,9 @@ classname = '?' else: classname = wrappable_class_name(RequiredClass) - msg = "'%s' object expected, got '%s' instead" % ( + msg = "'%s' object expected, got '%s' instead" + raise operationerrfmt(space.w_TypeError, msg, classname, self.getclass(space).getname(space, '?')) - raise OperationError(space.w_TypeError, space.wrap(msg)) # used by _weakref implemenation @@ -123,8 +123,8 @@ def setweakref(self, space, weakreflifeline): typename = space.type(self).getname(space, '?') - raise OperationError(space.w_TypeError, space.wrap( - "cannot create weak reference to '%s' object" % typename)) + raise operationerrfmt(space.w_TypeError, + "cannot create weak reference to '%s' object", typename) def clear_all_weakrefs(self): """Call this at the beginning of interp-level __del__() methods @@ -366,10 +366,10 @@ try: w_mod = self.builtin_modules[name] except KeyError: - raise OperationError( + raise operationerrfmt( self.w_SystemError, - self.wrap("getbuiltinmodule() called " - "with non-builtin module %s" % name)) + "getbuiltinmodule() called " + "with non-builtin module %s", name) else: # Add the module to sys.modules self.setitem(w_modules, w_name, w_mod) @@ -693,10 +693,10 @@ return None obj = self.interpclass_w(w_obj) if not isinstance(obj, RequiredClass): # or obj is None - msg = "'%s' object expected, got '%s' instead" % ( + msg = "'%s' object expected, got '%s' instead" + raise operationerrfmt(self.w_TypeError, msg, wrappable_class_name(RequiredClass), w_obj.getclass(self).getname(self, '?')) - raise OperationError(self.w_TypeError, self.wrap(msg)) return obj interp_w._annspecialcase_ = 'specialize:arg(1)' @@ -998,9 +998,9 @@ except OperationError, err: if objdescr is None or not err.match(self, self.w_TypeError): raise - msg = "%s must be an integer, not %s" % ( + msg = "%s must be an integer, not %s" + raise operationerrfmt(self.w_TypeError, msg, objdescr, self.type(w_obj).getname(self, '?')) - raise OperationError(self.w_TypeError, self.wrap(msg)) try: index = self.int_w(w_index) except OperationError, err: @@ -1013,10 +1013,10 @@ else: return sys.maxint else: - raise OperationError( - w_exception, self.wrap( + raise operationerrfmt( + w_exception, "cannot fit '%s' into an index-sized " - "integer" % self.type(w_obj).getname(self, '?'))) + "integer", self.type(w_obj).getname(self, '?')) else: return index Modified: pypy/branch/lazy-operr-format/pypy/interpreter/error.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/error.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/error.py Mon Jan 25 16:28:47 2010 @@ -208,8 +208,8 @@ if not space.exception_is_valid_class_w(w_instclass): instclassname = w_instclass.getname(space, '?') msg = ("exceptions must be classes, or instances, " - "or strings (deprecated), not %s" % (instclassname,)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + "or strings (deprecated), not %s") + raise operationerrfmt(space.w_TypeError, msg, instclassname) if not space.is_w(w_value, space.w_None): raise OperationError(space.w_TypeError, @@ -366,16 +366,3 @@ space.wrap(msg)) return OperationError(exc, w_error) wrap_oserror._annspecialcase_ = 'specialize:arg(2)' - -### installing the excepthook for OperationErrors -##def operr_excepthook(exctype, value, traceback): -## if issubclass(exctype, OperationError): -## value.debug_excs.append((exctype, value, traceback)) -## value.print_detailed_traceback() -## else: -## old_excepthook(exctype, value, traceback) -## from pypy.tool import tb_server -## tb_server.publish_exc((exctype, value, traceback)) - -##old_excepthook = sys.excepthook -##sys.excepthook = operr_excepthook Modified: pypy/branch/lazy-operr-format/pypy/interpreter/function.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/function.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/function.py Mon Jan 25 16:28:47 2010 @@ -7,7 +7,7 @@ """ from pypy.rlib.unroll import unrolling_iterable -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments @@ -388,7 +388,9 @@ if self.closure: closure_len = len(self.closure) if isinstance(code, PyCode) and closure_len != len(code.co_freevars): - raise OperationError(space.w_ValueError, space.wrap("%s() requires a code object with %s free vars, not %s " % (self.name, closure_len, len(code.co_freevars)))) + raise operationerrfmt(space.w_ValueError, + "%s() requires a code object with %d free vars, not %d", + self.name, closure_len, len(code.co_freevars)) self.code = code def fget_func_closure(space, self): @@ -458,9 +460,9 @@ instname += " " instdescr = "%sinstance" %instname msg = ("unbound method %s() must be called with %s" - "instance as first argument (got %s instead)") % (myname, clsdescr, instdescr) - raise OperationError(space.w_TypeError, - space.wrap(msg)) + "instance as first argument (got %s instead)") + raise operationerrfmt(space.w_TypeError, msg, + myname, clsdescr, instdescr) return space.call_args(self.w_function, args) def descr_method_get(self, w_obj, w_cls=None): @@ -580,8 +582,8 @@ def descr_classmethod__new__(space, w_type, w_function): if not space.is_true(space.callable(w_function)): typename = space.type(w_function).getname(space, '?') - raise OperationError(space.w_TypeError, space.wrap( - "'%s' object is not callable" % typename)) + raise operationerrfmt(space.w_TypeError, + "'%s' object is not callable", typename) return space.wrap(ClassMethod(w_function)) class FunctionWithFixedCode(Function): Modified: pypy/branch/lazy-operr-format/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/pycompiler.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/pycompiler.py Mon Jan 25 16:28:47 2010 @@ -70,7 +70,7 @@ if not err2.match(space, space.w_SyntaxError): raise - if space.eq_w(err1.w_value, err2.w_value): + if space.eq_w(err1.get_w_value(space), err2.get_w_value(space)): raise # twice the same error, re-raise return None # two different errors, expect more Modified: pypy/branch/lazy-operr-format/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/pyframe.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/pyframe.py Mon Jan 25 16:28:47 2010 @@ -4,7 +4,7 @@ from pypy.tool.pairtype import extendabletype from pypy.interpreter import eval, baseobjspace, pycode from pypy.interpreter.argument import Arguments -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter import pytraceback import opcode @@ -303,7 +303,7 @@ w_exc_value = space.w_None w_tb = space.w_None else: - w_exc_value = self.last_exception.w_value + w_exc_value = self.last_exception.get_w_value(space) w_tb = w(self.last_exception.application_traceback) tup_state = [ @@ -455,8 +455,8 @@ space.wrap("f_lineno can only be set by a trace function.")) if new_lineno < self.pycode.co_firstlineno: - raise OperationError(space.w_ValueError, - space.wrap("line %d comes before the current code." % new_lineno)) + raise operationerrfmt(space.w_ValueError, + "line %d comes before the current code.", new_lineno) code = self.pycode.co_code addr = 0 line = self.pycode.co_firstlineno @@ -472,8 +472,8 @@ break if new_lasti == -1: - raise OperationError(space.w_ValueError, - space.wrap("line %d comes after the current code." % new_lineno)) + raise operationerrfmt(space.w_ValueError, + "line %d comes after the current code.", new_lineno) # Don't jump to a line with an except in it. if ord(code[new_lasti]) in (DUP_TOP, POP_TOP): @@ -519,9 +519,9 @@ assert len(blockstack) == 0 if new_lasti_setup_addr != f_lasti_setup_addr: - raise OperationError(space.w_ValueError, - space.wrap("can't jump into or out of a 'finally' block %d -> %d" % - (f_lasti_setup_addr, new_lasti_setup_addr))) + raise operationerrfmt(space.w_ValueError, + "can't jump into or out of a 'finally' block %d -> %d", + f_lasti_setup_addr, new_lasti_setup_addr) if new_lasti < self.last_instr: min_addr = new_lasti @@ -612,7 +612,7 @@ while f is not None and f.last_exception is None: f = f.f_backref() if f is not None: - return f.last_exception.w_value + return f.last_exception.get_w_value(space) return space.w_None def fget_f_exc_traceback(space, self): Modified: pypy/branch/lazy-operr-format/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/pyopcode.py Mon Jan 25 16:28:47 2010 @@ -5,7 +5,7 @@ """ import sys -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import UnpackValueError, Wrappable from pypy.interpreter import gateway, function, eval from pypy.interpreter import pyframe, pytraceback @@ -323,8 +323,8 @@ def _load_fast_failed(f, varindex): varname = f.getlocalvarname(varindex) - message = "local variable '%s' referenced before assignment" % varname - raise OperationError(f.space.w_UnboundLocalError, f.space.wrap(message)) + message = "local variable '%s' referenced before assignment" + raise operationerrfmt(f.space.w_UnboundLocalError, message, varname) _load_fast_failed._dont_inline_ = True def LOAD_CONST(f, constindex, *ignored): @@ -627,8 +627,9 @@ # catch KeyErrors and turn them into NameErrors if not e.match(f.space, f.space.w_KeyError): raise - message = "name '%s' is not defined" % f.space.str_w(w_varname) - raise OperationError(f.space.w_NameError, f.space.wrap(message)) + message = "name '%s' is not defined" + raise operationerrfmt(f.space.w_NameError, message, + f.space.str_w(w_varname)) def UNPACK_SEQUENCE(f, itemcount, *ignored): w_iterable = f.popvalue() @@ -680,9 +681,8 @@ _load_global._always_inline_ = True def _load_global_failed(f, varname): - message = "global name '%s' is not defined" % varname - raise OperationError(f.space.w_NameError, - f.space.wrap(message)) + message = "global name '%s' is not defined" + raise operationerrfmt(f.space.w_NameError, message, varname) _load_global_failed._dont_inline_ = True def LOAD_GLOBAL(f, nameindex, *ignored): @@ -692,8 +692,8 @@ def DELETE_FAST(f, varindex, *ignored): if f.fastlocals_w[varindex] is None: varname = f.getlocalvarname(varindex) - message = "local variable '%s' referenced before assignment" % varname - raise OperationError(f.space.w_UnboundLocalError, f.space.wrap(message)) + message = "local variable '%s' referenced before assignment" + raise operationerrfmt(f.space.w_UnboundLocalError, message, varname) f.fastlocals_w[varindex] = None @@ -809,8 +809,9 @@ except OperationError, e: if not e.match(f.space, f.space.w_AttributeError): raise - raise OperationError(f.space.w_ImportError, - f.space.wrap("cannot import name '%s'" % f.space.str_w(w_name) )) + raise operationerrfmt(f.space.w_ImportError, + "cannot import name '%s'", + f.space.str_w(w_name)) f.pushvalue(w_obj) def JUMP_FORWARD(f, jumpby, next_instr, *ignored): @@ -875,7 +876,7 @@ operr = unroller.operr w_result = f.space.call_function(w_exitfunc, operr.w_type, - operr.w_value, + operr.get_w_value(f.space), operr.application_traceback) if f.space.is_true(w_result): # __exit__() returned True -> Swallow the exception. @@ -1098,7 +1099,7 @@ raise RaiseWithExplicitTraceback(self.operr) def state_unpack_variables(self, space): - return [self.operr.w_type, self.operr.w_value] + return [self.operr.w_type, self.operr.get_w_value(space)] def state_pack_variables(space, w_type, w_value): return SApplicationException(OperationError(w_type, w_value)) state_pack_variables = staticmethod(state_pack_variables) @@ -1209,7 +1210,7 @@ # instead of the traceback, we store the unroller object, # wrapped. frame.pushvalue(frame.space.wrap(unroller)) - frame.pushvalue(operationerr.w_value) + frame.pushvalue(operationerr.get_w_value(frame.space)) frame.pushvalue(operationerr.w_type) frame.last_exception = operationerr return self.handlerposition # jump to the handler Modified: pypy/branch/lazy-operr-format/pypy/interpreter/test/test_argument.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/test/test_argument.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/test/test_argument.py Mon Jan 25 16:28:47 2010 @@ -292,11 +292,11 @@ excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"], [1], w_starstararg={None: 1}) assert excinfo.value.w_type is TypeError - assert excinfo.value.w_value is not None + assert excinfo.value._w_value is not None excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"], [1], w_starstararg={valuedummy: 1}) assert excinfo.value.w_type is ValueError - assert excinfo.value.w_value is None + assert excinfo.value._w_value is None def test_blindargs(self): @@ -374,7 +374,7 @@ excinfo = py.test.raises(OperationError, args.parse_obj, "obj", "foo", Signature(["a", "b"], None, None)) assert excinfo.value.w_type is TypeError - assert excinfo.value.w_value == "msg foo" + assert excinfo.value._w_value == "msg foo" def test_args_parsing_into_scope(self): @@ -429,7 +429,7 @@ "obj", [None, None], "foo", Signature(["a", "b"], None, None)) assert excinfo.value.w_type is TypeError - assert excinfo.value.w_value == "msg foo" + assert excinfo.value._w_value == "msg foo" def test_topacked_frompacked(self): space = DummySpace() Modified: pypy/branch/lazy-operr-format/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/test/test_compiler.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/test/test_compiler.py Mon Jan 25 16:28:47 2010 @@ -634,7 +634,7 @@ ex = e.value space = self.space assert ex.match(space, space.w_SyntaxError) - assert 'hello_world' in space.str_w(space.str(ex.w_value)) + assert 'hello_world' in space.str_w(space.str(ex.get_w_value(space))) class TestPyCCompiler(BaseTestCompiler): Modified: pypy/branch/lazy-operr-format/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/typedef.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/typedef.py Mon Jan 25 16:28:47 2010 @@ -53,7 +53,7 @@ def descr__hash__unhashable(space, w_obj): typename = space.type(w_obj).getname(space, '?') raise operationerrfmt(space.w_TypeError, - "%s objects are unhashable", typename) + "'%s' objects are unhashable", typename) no_hash_descr = interp2app(descr__hash__unhashable) @@ -482,12 +482,12 @@ def typecheck(self, space, w_obj): if not space.is_true(space.isinstance(w_obj, self.w_cls)): - raise OperationError(space.w_TypeError, - space.wrap("descriptor '%s' for '%s'" - " objects doesn't apply to '%s' object" % - (self.name, - self.w_cls.name, - space.type(w_obj).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "descriptor '%s' for '%s'" + " objects doesn't apply to '%s' object", + self.name, + self.w_cls.name, + space.type(w_obj).getname(space, '?')) def descr_member_get(space, member, w_obj, w_w_cls=None): """member.__get__(obj[, type]) -> value @@ -554,9 +554,9 @@ w_dict = w_obj.getdict() if w_dict is None: typename = space.type(w_obj).getname(space, '?') - raise OperationError(space.w_TypeError, - space.wrap("descriptor '__dict__' doesn't apply to" - " '%s' objects" % typename)) + raise operationerrfmt(space.w_TypeError, + "descriptor '__dict__' doesn't apply to" + " '%s' objects", typename) return w_dict def descr_set_dict(space, w_obj, w_dict): Modified: pypy/branch/lazy-operr-format/pypy/module/__builtin__/descriptor.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/__builtin__/descriptor.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/__builtin__/descriptor.py Mon Jan 25 16:28:47 2010 @@ -3,7 +3,7 @@ from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments from pypy.interpreter.gateway import interp2app -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.descroperation import object_getattribute, object_setattr from pypy.interpreter.function import StaticMethod, ClassMethod from pypy.interpreter.typedef import GetSetProperty, descr_get_dict, \ @@ -154,8 +154,8 @@ # a TypeError instead of an AttributeError and using "readonly" # instead of "read-only" in the error message :-/ if attr in ["__doc__", "fget", "fset", "fdel"]: - raise OperationError(space.w_TypeError, space.wrap( - "Trying to set readonly attribute %s on property" % (attr,))) + raise operationerrfmt(space.w_TypeError, + "Trying to set readonly attribute %s on property", attr) return space.call_function(object_setattr(space), space.wrap(self), space.wrap(attr), w_value) setattr.unwrap_spec = ['self', ObjSpace, str, W_Root] Modified: pypy/branch/lazy-operr-format/pypy/module/__builtin__/interp_classobj.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/__builtin__/interp_classobj.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/__builtin__/interp_classobj.py Mon Jan 25 16:28:47 2010 @@ -1,5 +1,5 @@ import new -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped, applevel from pypy.interpreter.gateway import interp2app, ObjSpace from pypy.interpreter.typedef import TypeDef, make_weakref_descr @@ -11,10 +11,9 @@ def raise_type_err(space, argument, expected, w_obj): type_name = space.type(w_obj).getname(space, '?') - w_error = space.wrap("argument %s must be %s, not %s" % ( - argument, expected, type_name)) - raise OperationError(space.w_TypeError, - w_error) + raise operationerrfmt(space.w_TypeError, + "argument %s must be %s, not %s", + argument, expected, type_name) def unwrap_attr(space, w_attr): try: @@ -22,7 +21,8 @@ except OperationError, e: if not e.match(space, space.w_TypeError): raise - return "" + return "?" # any string different from "__dict__" & co. is fine + # XXX it's not clear that we have to catch the TypeError... def descr_classobj_new(space, w_subtype, w_name, w_bases, w_dict): if not space.is_true(space.isinstance(w_bases, space.w_tuple)): @@ -120,10 +120,10 @@ return space.newtuple(self.bases_w) w_value = self.lookup(space, w_attr) if w_value is None: - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("class %s has no attribute %s" % ( - self.name, space.str_w(space.str(w_attr))))) + "class %s has no attribute '%s'", + self.name, name) w_descr_get = space.lookup(w_value, '__get__') if w_descr_get is None: @@ -152,18 +152,18 @@ def descr_delattr(self, space, w_attr): name = unwrap_attr(space, w_attr) if name in ("__dict__", "__name__", "__bases__"): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("cannot delete attribute %s" % (name,))) + "cannot delete attribute '%s'", name) try: space.delitem(self.w_dict, w_attr) except OperationError, e: if not e.match(space, space.w_KeyError): raise - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("class %s has no attribute %s" % ( - self.name, space.str_w(space.str(w_attr))))) + "class %s has no attribute '%s'", + self.name, name) def descr_call(self, space, __args__): if self.lookup(space, space.wrap('__del__')) is not None: @@ -336,10 +336,10 @@ w_value = self.w_class.lookup(space, w_name) if w_value is None: if exc: - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("%s instance has no attribute %s" % ( - self.w_class.name, space.str_w(w_name)))) + "%s instance has no attribute '%s'", + self.w_class.name, space.str_w(w_name)) else: return None w_descr_get = space.lookup(w_value, '__get__') @@ -401,10 +401,10 @@ space.call_function(w_meth, w_name) else: if not self.deldictvalue(space, w_name): - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("%s instance has no attribute %s" % ( - self.w_class.name, space.str_w(space.str(w_name))))) + "%s instance has no attribute '%s'", + self.w_class.name, name) def descr_repr(self, space): w_meth = self.getattr(space, space.wrap('__repr__'), False) Modified: pypy/branch/lazy-operr-format/pypy/module/_codecs/interp_codecs.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/_codecs/interp_codecs.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/_codecs/interp_codecs.py Mon Jan 25 16:28:47 2010 @@ -1,4 +1,4 @@ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, NoneNotWrapped from pypy.interpreter.baseobjspace import W_Root @@ -30,20 +30,19 @@ w_res = space.call_function(w_errorhandler, w_exc) if (not space.is_true(space.isinstance(w_res, space.w_tuple)) or space.int_w(space.len(w_res)) != 2): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("encoding error handler must return " - "(unicode, int) tuple, not %s" % ( - space.str_w(space.repr(w_res))))) + "encoding error handler must return " + "(unicode, int) tuple, not %s", + space.str_w(space.repr(w_res))) w_replace, w_newpos = space.fixedview(w_res, 2) newpos = space.int_w(w_newpos) if (newpos < 0): newpos = len(input) + newpos if newpos < 0 or newpos > len(input): - raise OperationError( + raise operationerrfmt( space.w_IndexError, - space.wrap("position %d from error handler " - "out of bounds" % newpos)) + "position %d from error handler out of bounds", newpos) if decode: replace = space.unicode_w(w_replace) return replace, newpos @@ -103,9 +102,9 @@ else: state.codec_search_cache[normalized_encoding] = w_result return w_result - raise OperationError( + raise operationerrfmt( space.w_LookupError, - space.wrap("unknown encoding: %s" % encoding)) + "unknown encoding: %s", encoding) lookup_codec.unwrap_spec = [ObjSpace, str] @@ -120,9 +119,9 @@ try: w_err_handler = state.codec_error_registry[errors] except KeyError: - raise OperationError( + raise operationerrfmt( space.w_LookupError, - space.wrap("unknown error handler name %s" % errors)) + "unknown error handler name %s", errors) return w_err_handler lookup_error.unwrap_spec = [ObjSpace, str] Modified: pypy/branch/lazy-operr-format/pypy/module/_file/interp_file.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/_file/interp_file.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/_file/interp_file.py Mon Jan 25 16:28:47 2010 @@ -4,7 +4,7 @@ from pypy.rlib.rarithmetic import r_longlong from pypy.module._file.interp_stream import W_AbstractStream from pypy.module._file.interp_stream import StreamErrors, wrap_streamerror -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, make_weakref_descr @@ -52,8 +52,8 @@ if (not mode or mode[0] not in ['r', 'w', 'a', 'U'] or ('U' in mode and ('w' in mode or 'a' in mode))): space = self.space - raise OperationError(space.w_ValueError, - space.wrap('invalid mode : "%s"' % mode)) + raise operationerrfmt(space.w_ValueError, + "invalid mode: '%s'", mode) def getstream(self): """Return self.stream or raise an app-level ValueError if missing Modified: pypy/branch/lazy-operr-format/pypy/module/_rawffi/interp_rawffi.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/_rawffi/interp_rawffi.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/_rawffi/interp_rawffi.py Mon Jan 25 16:28:47 2010 @@ -1,7 +1,7 @@ import sys from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments -from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.interpreter.gateway import interp2app, NoneNotWrapped from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -85,15 +85,15 @@ try: return UNPACKED_TYPECODES[key] except KeyError: - raise OperationError(space.w_ValueError, space.wrap( - "Unknown type letter %s" % (key,))) + raise operationerrfmt(space.w_ValueError, + "Unknown type letter %s", key) def _get_type_(space, key): try: return TYPEMAP[key] except KeyError: - raise OperationError(space.w_ValueError, space.wrap( - "Unknown type letter %s" % (key,))) + raise operationerrfmt(space.w_ValueError, + "Unknown type letter %s", key) def unpack_to_ffi_type(space, w_shape, shape=False): resshape = None @@ -174,8 +174,8 @@ ptr = self.cdll.getrawpointer(name, ffi_argtypes, ffi_restype, flags) except KeyError: - raise OperationError(space.w_AttributeError, space.wrap( - "No symbol %s found in library %s" % (name, self.name))) + raise operationerrfmt(space.w_AttributeError, + "No symbol %s found in library %s", name, self.name) elif (_MS_WINDOWS and space.is_true(space.isinstance(w_name, space.w_int))): @@ -184,8 +184,8 @@ ptr = self.cdll.getrawpointer_byordinal(ordinal, ffi_argtypes, ffi_restype, flags) except KeyError: - raise OperationError(space.w_AttributeError, space.wrap( - "No symbol %d found in library %s" % (ordinal, self.name))) + raise operationerrfmt(space.w_AttributeError, + "No symbol %d found in library %s", ordinal, self.name) else: raise OperationError(space.w_TypeError, space.wrap( "function name must be string or integer")) @@ -200,8 +200,8 @@ address_as_uint = rffi.cast(lltype.Unsigned, self.cdll.getaddressindll(name)) except KeyError: - raise OperationError(space.w_ValueError, - space.wrap("Cannot find symbol %s" % (name,))) + raise operationerrfmt(space.w_ValueError, + "Cannot find symbol %s", name) return space.wrap(address_as_uint) getaddressindll.unwrap_spec = ['self', ObjSpace, str] @@ -391,9 +391,9 @@ from pypy.module._rawffi.structure import W_StructureInstance argnum = len(args_w) if argnum != len(self.argletters): - msg = "Wrong number of arguments: expected %d, got %d" % ( - len(self.argletters), argnum) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "Wrong number of arguments: expected %d, got %d" + raise operationerrfmt(space.w_TypeError, msg, + len(self.argletters), argnum) args_ll = [] for i in range(argnum): argletter = self.argletters[i] @@ -405,23 +405,24 @@ arg.shape.alignment != xalignment): msg = ("Argument %d should be a structure of size %d and " "alignment %d, " - "got instead size %d and alignment %d" % - (i+1, xsize, xalignment, - arg.shape.size, arg.shape.alignment)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + "got instead size %d and alignment %d") + raise operationerrfmt(space.w_TypeError, msg, i+1, + xsize, xalignment, arg.shape.size, + arg.shape.alignment) else: arg = space.interp_w(W_ArrayInstance, w_arg) if arg.length != 1: msg = ("Argument %d should be an array of length 1, " - "got length %d" % (i+1, arg.length)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + "got length %d") + raise operationerrfmt(space.w_TypeError, msg, + i+1, arg.length) letter = arg.shape.itemtp[0] if letter != argletter: if not (argletter in TYPEMAP_PTR_LETTERS and letter in TYPEMAP_PTR_LETTERS): - msg = "Argument %d should be typecode %s, got %s" % ( - i+1, argletter, letter) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "Argument %d should be typecode %s, got %s" + raise operationerrfmt(space.w_TypeError, msg, + i+1, argletter, letter) args_ll.append(arg.ll_buffer) # XXX we could avoid the intermediate list args_ll @@ -463,8 +464,8 @@ try: return space.wrap(intmask(getattr(TYPEMAP[tp_letter], name))) except KeyError: - raise OperationError(space.w_ValueError, space.wrap( - "Unknown type specification %s" % tp_letter)) + raise operationerrfmt(space.w_ValueError, + "Unknown type specification %s", tp_letter) accessor.unwrap_spec = [ObjSpace, str] return func_with_new_name(accessor, func_name) Modified: pypy/branch/lazy-operr-format/pypy/module/_rawffi/structure.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/_rawffi/structure.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/_rawffi/structure.py Mon Jan 25 16:28:47 2010 @@ -9,7 +9,7 @@ from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.rpython.lltypesystem import lltype, rffi -from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.module._rawffi.interp_rawffi import segfault_exception from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance from pypy.module._rawffi.interp_rawffi import wrap_value, unwrap_value @@ -53,8 +53,8 @@ for i in range(len(fields)): name, tp = fields[i] if name in name_to_index: - raise OperationError(space.w_ValueError, space.wrap( - "duplicate field name %s" % (name, ))) + raise operationerrfmt(space.w_ValueError, + "duplicate field name %s", name) name_to_index[name] = i size, alignment, pos = size_alignment_pos(fields) else: # opaque case @@ -76,8 +76,8 @@ try: return self.name_to_index[attr] except KeyError: - raise OperationError(space.w_AttributeError, space.wrap( - "C Structure has no attribute %s" % attr)) + raise operationerrfmt(space.w_AttributeError, + "C Structure has no attribute %s", attr) def descr_call(self, space, autofree=False): return space.wrap(self.allocate(space, 1, autofree)) Modified: pypy/branch/lazy-operr-format/pypy/module/_socket/interp_func.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/_socket/interp_func.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/_socket/interp_func.py Mon Jan 25 16:28:47 2010 @@ -2,7 +2,7 @@ from pypy.module._socket.interp_socket import converted_error, W_RSocket from pypy.rlib import rsocket from pypy.rlib.rsocket import SocketError -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt def gethostname(space): """gethostname() -> string @@ -170,9 +170,9 @@ elif space.is_true(space.isinstance(w_x, space.w_long)): x = space.uint_w(w_x) else: - raise OperationError(space.w_TypeError, - space.wrap("expected int/long, %s found" % - (space.type(w_x).getname(space, "?")))) + raise operationerrfmt(space.w_TypeError, + "expected int/long, %s found", + space.type(w_x).getname(space, "?")) return space.wrap(rsocket.ntohl(x)) ntohl.unwrap_spec = [ObjSpace, W_Root] @@ -195,9 +195,9 @@ elif space.is_true(space.isinstance(w_x, space.w_long)): x = space.uint_w(w_x) else: - raise OperationError(space.w_TypeError, - space.wrap("expected int/long, %s found" % - (space.type(w_x).getname(space, "?")))) + raise operationerrfmt(space.w_TypeError, + "expected int/long, %s found", + space.type(w_x).getname(space, "?")) return space.wrap(rsocket.htonl(x)) htonl.unwrap_spec = [ObjSpace, W_Root] @@ -249,7 +249,7 @@ ip = rsocket.inet_ntop(family, packed) except SocketError, e: raise converted_error(space, e) - except ValueError, e: + except ValueError, e: # XXX the message is lost in RPython raise OperationError(space.w_ValueError, space.wrap(str(e))) return space.wrap(ip) Modified: pypy/branch/lazy-operr-format/pypy/module/_stackless/interp_coroutine.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/_stackless/interp_coroutine.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/_stackless/interp_coroutine.py Mon Jan 25 16:28:47 2010 @@ -20,7 +20,7 @@ from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.function import StaticMethod from pypy.module._stackless.stackless_flags import StacklessFlags @@ -35,10 +35,10 @@ self.space = space self.costate = costate if not space.is_true(space.callable(w_obj)): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.mod(space.wrap('object %r is not callable'), - space.newtuple([w_obj]))) + "'%s' object is not callable", + space.type(w_obj).getname(space, '?')) self.w_func = w_obj self.args = args @@ -99,7 +99,7 @@ space = self.space if isinstance(operror, OperationError): w_exctype = operror.w_type - w_excvalue = operror.w_value + w_excvalue = operror.get_w_value(space) w_exctraceback = operror.application_traceback w_excinfo = space.newtuple([w_exctype, w_excvalue, w_exctraceback]) else: Modified: pypy/branch/lazy-operr-format/pypy/module/_stackless/interp_greenlet.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/_stackless/interp_greenlet.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/_stackless/interp_greenlet.py Mon Jan 25 16:28:47 2010 @@ -28,7 +28,7 @@ except OperationError, operror: if not operror.match(space, greenlet.costate.w_GreenletExit): raise - w_result = operror.w_value + w_result = operror.get_w_value(space) finally: greenlet.active = False greenlet.costate.args_w = [w_result] @@ -127,7 +127,7 @@ operror.application_traceback = tb # Dead greenlet: turn GreenletExit into a regular return if self.isdead() and operror.match(space, self.costate.w_GreenletExit): - args_w = [operror.w_value] + args_w = [operror.get_w_value(space)] else: syncstate.push_exception(operror) args_w = None Modified: pypy/branch/lazy-operr-format/pypy/module/bz2/interp_bz2.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/bz2/interp_bz2.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/bz2/interp_bz2.py Mon Jan 25 16:28:47 2010 @@ -1,7 +1,7 @@ from pypy.rpython.tool import rffi_platform as platform from pypy.rpython.lltypesystem import rffi from pypy.rpython.lltypesystem import lltype -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty @@ -193,8 +193,8 @@ def check_mode_ok(self, mode): if (not mode or mode[0] not in ['r', 'w', 'a', 'U']): space = self.space - raise OperationError(space.w_ValueError, - space.wrap('invalid mode : "%s"' % mode)) + raise operationerrfmt(space.w_ValueError, + "invalid mode: '%s'", mode) def direct_bz2__init__(self, w_name, mode='r', buffering=-1, compresslevel=9): Modified: pypy/branch/lazy-operr-format/pypy/module/clr/interp_clr.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/clr/interp_clr.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/clr/interp_clr.py Mon Jan 25 16:28:47 2010 @@ -1,7 +1,7 @@ import os.path from pypy.module.clr import assemblyname from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app, ApplevelClass from pypy.interpreter.typedef import TypeDef from pypy.rpython.ootypesystem import ootype @@ -17,11 +17,11 @@ try: method = b_type.GetMethod(name, b_paramtypes) except AmbiguousMatchException: - msg = 'Multiple overloads for %s could match' % name - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = 'Multiple overloads for %s could match' + raise operationerrfmt(space.w_TypeError, msg, name) if method is None: - msg = 'No overloads for %s could match' % name - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = 'No overloads for %s could match' + raise operationerrfmt(space.w_TypeError, msg, name) return method def get_constructor(space, b_type, b_paramtypes): @@ -301,7 +301,8 @@ assembly_qualified_name = '%s, %s' % (fullname, assemblyname) b_type = System.Type.GetType(assembly_qualified_name) if b_type is None: - raise OperationError(space.w_ImportError, space.wrap("Cannot load .NET type: %s" % fullname)) + raise operationerrfmt(space.w_ImportError, + "Cannot load .NET type: %s", fullname) # this is where we locate the interfaces inherited by the class # set the flag hasIEnumerable if IEnumerable interface has been by the class Modified: pypy/branch/lazy-operr-format/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/imp/importing.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/imp/importing.py Mon Jan 25 16:28:47 2010 @@ -6,7 +6,7 @@ from pypy.interpreter.module import Module from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root, ObjSpace from pypy.interpreter.eval import Code from pypy.rlib import streamio @@ -382,8 +382,8 @@ return None else: # ImportError - msg = "No module named %s" % modulename - raise OperationError(space.w_ImportError, w(msg)) + msg = "No module named %s" + raise operationerrfmt(space.w_ImportError, msg, modulename) def reload(space, w_module): """Reload the module. @@ -396,9 +396,9 @@ w_modulename = space.getattr(w_module, space.wrap("__name__")) modulename = space.str_w(w_modulename) if not space.is_w(check_sys_modules(space, w_modulename), w_module): - raise OperationError( + raise operationerrfmt( space.w_ImportError, - space.wrap("reload(): module %s not in sys.modules" % (modulename,))) + "reload(): module %s not in sys.modules", modulename) try: w_mod = space.reloading_modules[modulename] @@ -416,10 +416,10 @@ if parent_name: w_parent = check_sys_modules(space, space.wrap(parent_name)) if w_parent is None: - raise OperationError( + raise operationerrfmt( space.w_ImportError, - space.wrap("reload(): parent %s not in sys.modules" % ( - parent_name,))) + "reload(): parent %s not in sys.modules", + parent_name) w_path = space.getattr(w_parent, space.wrap("__path__")) else: w_path = None @@ -429,8 +429,8 @@ if not find_info: # ImportError - msg = "No module named %s" % modulename - raise OperationError(space.w_ImportError, space.wrap(msg)) + msg = "No module named %s" + raise operationerrfmt(space.w_ImportError, msg, modulename) try: try: @@ -677,8 +677,8 @@ w_code = space.call_method(w_marshal, 'loads', space.wrap(strbuf)) pycode = space.interpclass_w(w_code) if pycode is None or not isinstance(pycode, Code): - raise OperationError(space.w_ImportError, space.wrap( - "Non-code object in %s" % cpathname)) + raise operationerrfmt(space.w_ImportError, + "Non-code object in %s", cpathname) return pycode def load_compiled_module(space, w_modulename, w_mod, cpathname, magic, @@ -689,8 +689,8 @@ """ w = space.wrap if magic != get_pyc_magic(space): - raise OperationError(space.w_ImportError, w( - "Bad magic number in %s" % cpathname)) + raise operationerrfmt(space.w_ImportError, + "Bad magic number in %s", cpathname) #print "loading pyc file:", cpathname code_w = read_compiled_module(space, cpathname, source) exec_code_module(space, w_mod, code_w) Modified: pypy/branch/lazy-operr-format/pypy/module/imp/interp_imp.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/imp/interp_imp.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/imp/interp_imp.py Mon Jan 25 16:28:47 2010 @@ -1,7 +1,7 @@ from pypy.module.imp import importing from pypy.module._file.interp_file import W_File from pypy.rlib import streamio -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.module import Module from pypy.interpreter.gateway import NoneNotWrapped import struct @@ -38,9 +38,9 @@ find_info = importing.find_module( space, name, w_name, name, w_path, use_loader=False) if not find_info: - raise OperationError( + raise operationerrfmt( space.w_ImportError, - space.wrap("No module named %s" % (name,))) + "No module named %s", name) w_filename = space.wrap(find_info.filename) stream = find_info.stream Modified: pypy/branch/lazy-operr-format/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/pypyjit/interp_jit.py Mon Jan 25 16:28:47 2010 @@ -8,7 +8,7 @@ from pypy.rlib.rarithmetic import r_uint, intmask from pypy.rlib.jit import JitDriver, hint, we_are_jitted import pypy.interpreter.pyopcode # for side-effects -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, Arguments from pypy.interpreter.eval import Frame from pypy.interpreter.pycode import PyCode, CO_CONTAINSLOOP @@ -116,9 +116,8 @@ # XXXXXXXXX args_w, kwds_w = args.unpack() if len(args_w) > 1: - msg = ("set_param() takes at most 1 non-keyword argument, %d given" - % len(args_w)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "set_param() takes at most 1 non-keyword argument, %d given" + raise operationerrfmt(space.w_TypeError, msg, len(args_w)) if len(args_w) == 1: text = space.str_w(args_w[0]) try: @@ -131,7 +130,7 @@ try: pypyjitdriver.set_param(key, intval) except ValueError: - raise OperationError(space.w_TypeError, - space.wrap("no JIT parameter '%s'" % (key,))) + raise operationerrfmt(space.w_TypeError, + "no JIT parameter '%s'", key) set_param.unwrap_spec = [ObjSpace, Arguments] Modified: pypy/branch/lazy-operr-format/pypy/module/rctime/interp_time.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/rctime/interp_time.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/rctime/interp_time.py Mon Jan 25 16:28:47 2010 @@ -1,6 +1,6 @@ from pypy.rpython.tool import rffi_platform as platform from pypy.rpython.lltypesystem import rffi -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root, ObjSpace from pypy.rpython.lltypesystem import lltype from pypy.rlib.rarithmetic import ovfcheck_float_to_int @@ -224,9 +224,9 @@ tup_w = space.fixedview(w_tup) if len(tup_w) != 9: - raise OperationError(space.w_TypeError, - space.wrap("argument must be sequence of " - "length 9, not %d" % len(tup_w))) + raise operationerrfmt(space.w_TypeError, + "argument must be sequence of " + "length 9, not %d", len(tup_w)) y = space.int_w(tup_w[0]) tm_mon = space.int_w(tup_w[1]) Modified: pypy/branch/lazy-operr-format/pypy/module/select/interp_select.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/select/interp_select.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/select/interp_select.py Mon Jan 25 16:28:47 2010 @@ -2,7 +2,7 @@ from pypy.interpreter.typedef import TypeDef from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import W_Root, ObjSpace, interp2app -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rlib import rpoll defaultevents = rpoll.POLLIN | rpoll.POLLOUT | rpoll.POLLPRI @@ -28,8 +28,8 @@ fd = space.int_w(w_fd) if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file descriptor cannot be a negative integer (%d)"%fd)) + raise operationerrfmt(space.w_ValueError, + "file descriptor cannot be a negative integer (%d)", fd) return fd class Poll(Wrappable): @@ -47,7 +47,7 @@ del self.fddict[fd] except KeyError: raise OperationError(space.w_KeyError, - space.wrap(fd)) + space.wrap(fd)) # XXX should this maybe be w_fd? unregister.unwrap_spec = ['self', ObjSpace, W_Root] def poll(self, space, w_timeout=None): Modified: pypy/branch/lazy-operr-format/pypy/module/sys/__init__.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/sys/__init__.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/sys/__init__.py Mon Jan 25 16:28:47 2010 @@ -116,7 +116,7 @@ if operror is None: return space.w_None else: - return operror.w_value + return operror.get_w_value(space) elif attr == 'exc_traceback': operror = space.getexecutioncontext().sys_exc_info() if operror is None: Modified: pypy/branch/lazy-operr-format/pypy/module/sys/vm.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/sys/vm.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/sys/vm.py Mon Jan 25 16:28:47 2010 @@ -90,7 +90,7 @@ if operror is None: return space.newtuple([space.w_None,space.w_None,space.w_None]) else: - return space.newtuple([operror.w_type, operror.w_value, + return space.newtuple([operror.w_type, operror.get_w_value(space), space.wrap(operror.application_traceback)]) def exc_clear(space): Modified: pypy/branch/lazy-operr-format/pypy/module/thread/os_thread.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/thread/os_thread.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/thread/os_thread.py Mon Jan 25 16:28:47 2010 @@ -4,7 +4,7 @@ from pypy.module.thread import ll_thread as thread from pypy.module.thread.error import wrap_thread_error -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments from pypy.rlib.objectmodel import free_non_gc_object @@ -198,8 +198,8 @@ old_size = thread.get_stacksize() error = thread.set_stacksize(size) if error == -1: - raise OperationError(space.w_ValueError, - space.wrap("size not valid: %d bytes" % size)) + raise operationerrfmt(space.w_ValueError, + "size not valid: %d bytes", size) if error == -2: raise wrap_thread_error(space, "setting stack size not supported") return space.wrap(old_size) Modified: pypy/branch/lazy-operr-format/pypy/module/zipimport/interp_zipimport.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/module/zipimport/interp_zipimport.py (original) +++ pypy/branch/lazy-operr-format/pypy/module/zipimport/interp_zipimport.py Mon Jan 25 16:28:47 2010 @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments -from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.module import Module @@ -257,7 +257,7 @@ w_mods = space.sys.get('modules') space.call_method(w_mods, 'pop', w(fullname), space.w_None) if last_exc: - raise OperationError(self.w_ZipImportError, last_exc.w_value) + raise OperationError(self.w_ZipImportError, last_exc.get_w_value(space)) # should never happen I think return space.w_None load_module.unwrap_spec = ['self', ObjSpace, str] @@ -288,8 +288,8 @@ w_code = space.builtin.call('compile', w_source, w(filename + ext), w('exec')) return w_code - raise OperationError(self.w_ZipImportError, space.wrap( - "Cannot find source or code for %s in %s" % (filename, self.name))) + raise operationerrfmt(self.w_ZipImportError, + "Cannot find source or code for %s in %s", filename, self.name) get_code.unwrap_spec = ['self', ObjSpace, str] def get_source(self, space, fullname): @@ -304,8 +304,8 @@ found = True if found: return space.w_None - raise OperationError(self.w_ZipImportError, space.wrap( - "Cannot find source for %s in %s" % (filename, self.name))) + raise operationerrfmt(self.w_ZipImportError, + "Cannot find source for %s in %s", filename, self.name) get_source.unwrap_spec = ['self', ObjSpace, str] def is_package(self, space, fullname): @@ -313,8 +313,8 @@ for _, is_package, ext in ENUMERATE_EXTS: if self.have_modulefile(space, filename + ext): return space.wrap(is_package) - raise OperationError(self.w_ZipImportError, space.wrap( - "Cannot find module %s in %s" % (filename, self.name))) + raise operationerrfmt(self.w_ZipImportError, + "Cannot find module %s in %s", filename, self.name) is_package.unwrap_spec = ['self', ObjSpace, str] def getarchive(space, self): @@ -335,28 +335,28 @@ try: s = os.stat(filename) except OSError: - raise OperationError(w_ZipImportError, space.wrap( - "Cannot find name %s" % (filename,))) + raise operationerrfmt(w_ZipImportError, + "Cannot find name %s", filename) if not stat.S_ISDIR(s.st_mode): ok = True break if not ok: - raise OperationError(w_ZipImportError, space.wrap( - "Did not find %s to be a valid zippath" % (name,))) + raise operationerrfmt(w_ZipImportError, + "Did not find %s to be a valid zippath", name) try: w_result = zip_cache.get(filename) if w_result is None: - raise OperationError(w_ZipImportError, space.wrap( + raise operationerrfmt(w_ZipImportError, "Cannot import %s from zipfile, recursion detected or" - "already tried and failed" % (name,))) + "already tried and failed", name) return w_result except KeyError: zip_cache.cache[filename] = None try: zip_file = RZipFile(filename, 'r') except (BadZipfile, OSError): - raise OperationError(w_ZipImportError, space.wrap( - "%s seems not to be a zipfile" % (filename,))) + raise operationerrfmt(w_ZipImportError, + "%s seems not to be a zipfile", filename) zip_file.close() prefix = name[len(filename):] if prefix.startswith(os.sep): Modified: pypy/branch/lazy-operr-format/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/descroperation.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/descroperation.py Mon Jan 25 16:28:47 2010 @@ -1,5 +1,5 @@ import operator -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.function import Function, Method, FunctionWithFixedCode from pypy.interpreter.argument import Arguments @@ -24,10 +24,13 @@ w_type = space.type(w_obj) typename = w_type.getname(space, '?') if w_descr is None: - msg = "'%s' object has no attribute '%s'" % (typename, name) + raise operationerrfmt(space.w_AttributeError, + "'%s' object has no attribute '%s'", + typename, name) else: - msg = "'%s' object attribute '%s' is read-only" % (typename, name) - raise OperationError(space.w_AttributeError, space.wrap(msg)) + raise operationerrfmt(space.w_AttributeError, + "'%s' object attribute '%s' is read-only", + typename, name) class Object: def descr__getattribute__(space, w_obj, w_name): @@ -120,10 +123,10 @@ return w_obj.call_args(args) w_descr = space.lookup(w_obj, '__call__') if w_descr is None: - raise OperationError( - space.w_TypeError, - space.mod(space.wrap('object %r is not callable'), - space.newtuple([w_obj]))) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not callable", + typename) return space.get_and_call_args(w_descr, w_obj, args) def get(space, w_descr, w_obj, w_type=None): @@ -137,15 +140,19 @@ def set(space, w_descr, w_obj, w_val): w_set = space.lookup(w_descr, '__set__') if w_set is None: - raise OperationError(space.w_TypeError, - space.wrap("object is not a descriptor with set")) + typename = space.type(w_descr).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not a descriptor with set", + typename) return space.get_and_call_function(w_set, w_descr, w_obj, w_val) def delete(space, w_descr, w_obj): w_delete = space.lookup(w_descr, '__delete__') if w_delete is None: - raise OperationError(space.w_TypeError, - space.wrap("object is not a descriptor with delete")) + typename = space.type(w_descr).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not a descriptor with delete", + typename) return space.get_and_call_function(w_delete, w_descr, w_obj) def getattr(space, w_obj, w_name): @@ -169,15 +176,19 @@ def setattr(space, w_obj, w_name, w_val): w_descr = space.lookup(w_obj, '__setattr__') if w_descr is None: - raise OperationError(space.w_AttributeError, - space.wrap("object is readonly")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_AttributeError, + "'%s' object is readonly", + typename) return space.get_and_call_function(w_descr, w_obj, w_name, w_val) def delattr(space, w_obj, w_name): w_descr = space.lookup(w_obj, '__delattr__') if w_descr is None: - raise OperationError(space.w_AttributeError, - space.wrap("object does not support attribute removal")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_AttributeError, + "'%s' object does not support attribute removal", + typename) return space.get_and_call_function(w_descr, w_obj, w_name) def is_true(space, w_obj): @@ -215,37 +226,47 @@ if w_descr is None: w_descr = space.lookup(w_obj, '__getitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("iteration over non-sequence")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not iterable", + typename) return space.newseqiter(w_obj) return space.get_and_call_function(w_descr, w_obj) def next(space, w_obj): w_descr = space.lookup(w_obj, 'next') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("iterator has no next() method")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not an iterator", + typename) return space.get_and_call_function(w_descr, w_obj) def getitem(space, w_obj, w_key): w_descr = space.lookup(w_obj, '__getitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("cannot get items from object")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not subscriptable", + typename) return space.get_and_call_function(w_descr, w_obj, w_key) def setitem(space, w_obj, w_key, w_val): w_descr = space.lookup(w_obj, '__setitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("cannot set items on object")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object does not support item assignment", + typename) return space.get_and_call_function(w_descr, w_obj, w_key, w_val) def delitem(space, w_obj, w_key): w_descr = space.lookup(w_obj, '__delitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("cannot delete items from object")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object does not support item deletion", + typename) return space.get_and_call_function(w_descr, w_obj, w_key) def getslice(space, w_obj, w_start, w_stop): @@ -553,6 +574,7 @@ def _make_binop_impl(symbol, specialnames): left, right = specialnames + errormsg = "unsupported operand type(s) for %s: '%%s' and '%%s'" % symbol def binop_impl(space, w_obj1, w_obj2): w_typ1 = space.type(w_obj1) @@ -592,8 +614,10 @@ w_res = _invoke_binop(space, w_right_impl, w_obj2, w_obj1) if w_res is not None: return w_res - raise OperationError(space.w_TypeError, - space.wrap("unsupported operand type(s) for %s" % symbol)) + typename1 = w_typ1.getname(space, '?') + typename2 = w_typ2.getname(space, '?') + raise operationerrfmt(space.w_TypeError, errormsg, + typename1, typename2) return func_with_new_name(binop_impl, "binop_%s_impl"%left.strip('_')) @@ -649,11 +673,12 @@ def _make_unaryop_impl(symbol, specialnames): specialname, = specialnames + errormsg = "unsupported operand type for unary %s: '%%s'" % symbol def unaryop_impl(space, w_obj): w_impl = space.lookup(w_obj, specialname) if w_impl is None: - raise OperationError(space.w_TypeError, - space.wrap("operand does not support unary %s" % symbol)) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, errormsg, typename) return space.get_and_call_function(w_impl, w_obj) return func_with_new_name(unaryop_impl, 'unaryop_%s_impl'%specialname.strip('_')) @@ -674,16 +699,17 @@ def %(targetname)s(space, w_obj): w_impl = space.lookup(w_obj, %(specialname)r) if w_impl is None: - raise OperationError(space.w_TypeError, - space.wrap("operand does not support unary %(targetname)s")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for %(targetname)s(): '%%s'", + typename) w_result = space.get_and_call_function(w_impl, w_obj) if %(checker)s: return w_result - typename = space.str_w(space.getattr(space.type(w_result), - space.wrap('__name__'))) - msg = '%(specialname)s returned non-%(targetname)s (type %%s)' %% (typename,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + typename = space.type(w_result).getname(space, '?') + msg = "%(specialname)s returned non-%(targetname)s (type '%%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) assert not hasattr(DescrOperation, %(targetname)r) DescrOperation.%(targetname)s = %(targetname)s del %(targetname)s @@ -700,8 +726,10 @@ def %(targetname)s(space, w_obj): w_impl = space.lookup(w_obj, %(specialname)r) if w_impl is None: - raise OperationError(space.w_TypeError, - space.wrap("operand does not support unary %(targetname)s")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for %(targetname)s(): '%%s'", + typename) w_result = space.get_and_call_function(w_impl, w_obj) if space.is_true(space.isinstance(w_result, space.w_str)): @@ -711,10 +739,9 @@ except OperationError, e: if not e.match(space, space.w_TypeError): raise - typename = space.str_w(space.getattr(space.type(w_result), - space.wrap('__name__'))) - msg = '%(specialname)s returned non-%(targetname)s (type %%s)' %% (typename,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + typename = space.type(w_result).getname(space, '?') + msg = "%(specialname)s returned non-%(targetname)s (type '%%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) else: # re-wrap the result as a real string return space.wrap(result) Modified: pypy/branch/lazy-operr-format/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/flow/flowcontext.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/flow/flowcontext.py Mon Jan 25 16:28:47 2010 @@ -290,7 +290,7 @@ self.recorder.crnt_block.closeblock(link) except OperationError, e: - #print "OE", e.w_type, e.w_value + #print "OE", e.w_type, e.get_w_value(self.space) if (self.space.do_imports_immediately and e.w_type is self.space.w_ImportError): raise ImportError('import statement always raises %s' % ( Modified: pypy/branch/lazy-operr-format/pypy/objspace/flow/framestate.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/flow/framestate.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/flow/framestate.py Mon Jan 25 16:28:47 2010 @@ -16,7 +16,7 @@ data.append(Constant(None)) else: data.append(state.last_exception.w_type) - data.append(state.last_exception.w_value) + data.append(state.last_exception.get_w_value(state.space)) recursively_flatten(state.space, data) self.mergeable = data self.nonmergeable = ( Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/dictmultiobject.py Mon Jan 25 16:28:47 2010 @@ -1,6 +1,8 @@ -import py -from pypy.objspace.std.objspace import * +import py, sys +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.argument import Signature from pypy.module.__builtin__.__init__ import BUILTIN_TO_INDEX, OPTIMIZED_BUILTINS @@ -796,7 +798,9 @@ defaults = space.listview(w_defaults) len_defaults = len(defaults) if len_defaults > 1: - raise OperationError(space.w_TypeError, space.wrap("pop expected at most 2 arguments, got %d" % (1 + len_defaults, ))) + raise operationerrfmt(space.w_TypeError, + "pop expected at most 2 arguments, got %d", + 1 + len_defaults) w_item = w_dict.getitem(w_key) if w_item is None: if len_defaults > 0: Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/listobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/listobject.py Mon Jan 25 16:28:47 2010 @@ -1,4 +1,6 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice @@ -282,9 +284,9 @@ else: assert delta==0 elif len2 != slicelength: # No resize for extended slices - raise OperationError(space.w_ValueError, space.wrap("attempt to " - "assign sequence of size %d to extended slice of size %d" % - (len2,slicelength))) + raise operationerrfmt(space.w_ValueError, "attempt to " + "assign sequence of size %d to extended slice of size %d", + len2, slicelength) if sequence2 is items: if step > 0: Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/objecttype.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/objecttype.py Mon Jan 25 16:28:47 2010 @@ -1,4 +1,4 @@ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.descroperation import Object from pypy.interpreter import gateway from pypy.interpreter.typedef import default_identity_hash @@ -31,9 +31,9 @@ def descr_set___class__(space, w_obj, w_newcls): from pypy.objspace.std.typeobject import W_TypeObject if not isinstance(w_newcls, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap("__class__ must be set to new-style class, not '%s' object" % - space.type(w_newcls).getname(space, '?'))) + raise operationerrfmt(space.w_TypeError, + "__class__ must be set to new-style class, not '%s' object", + space.type(w_newcls).getname(space, '?')) if not w_newcls.is_heaptype(): raise OperationError(space.w_TypeError, space.wrap("__class__ assignment: only for heap types")) @@ -43,9 +43,9 @@ if w_oldcls.get_full_instance_layout() == w_newcls.get_full_instance_layout(): w_obj.setclass(space, w_newcls) else: - raise OperationError(space.w_TypeError, - space.wrap("__class__ assignment: '%s' object layout differs from '%s'" % - (w_oldcls.getname(space, '?'), w_newcls.getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "__class__ assignment: '%s' object layout differs from '%s'", + w_oldcls.getname(space, '?'), w_newcls.getname(space, '?')) def descr__new__(space, w_type, __args__): Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/objspace.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/objspace.py Mon Jan 25 16:28:47 2010 @@ -1,6 +1,6 @@ from pypy.objspace.std.register_all import register_all from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, UnpackValueError -from pypy.interpreter.error import OperationError, debug_print +from pypy.interpreter.error import OperationError, operationerrfmt, debug_print from pypy.interpreter.typedef import get_unique_interplevel_subclass from pypy.interpreter import pyframe from pypy.interpreter import function @@ -143,9 +143,9 @@ ## print "CALL_LIKELY_BUILTIN fast" if w_value is None: varname = OPTIMIZED_BUILTINS[num] - message = "global name '%s' is not defined" % varname - raise OperationError(f.space.w_NameError, - f.space.wrap(message)) + message = "global name '%s' is not defined" + raise operationerrfmt(f.space.w_NameError, + message, varname) nargs = oparg & 0xff w_function = w_value try: @@ -559,9 +559,9 @@ assert isinstance(instance, cls) instance.user_setup(self, w_subtype) else: - raise OperationError(self.w_TypeError, - self.wrap("%s.__new__(%s): only for the type %s" % ( - w_type.name, w_subtype.getname(self, '?'), w_type.name))) + raise operationerrfmt(self.w_TypeError, + "%s.__new__(%s): only for the type %s", + w_type.name, w_subtype.getname(self, '?'), w_type.name) return instance allocate_instance._annspecialcase_ = "specialize:arg(1)" Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/ropeobject.py Mon Jan 25 16:28:47 2010 @@ -1,4 +1,6 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.rlib.objectmodel import we_are_translated from pypy.objspace.std.inttype import wrapint @@ -281,10 +283,10 @@ if space.is_true(space.isinstance(w_s, space.w_unicode)): w_u = space.call_function(space.w_unicode, w_self) return space.call_method(w_u, "join", space.newlist(list_w)) - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("sequence item %d: expected string, %s " - "found" % (i, space.type(w_s).name))) + "sequence item %d: expected string, %s " + "found", i, space.type(w_s).getname(space, "?")) assert isinstance(w_s, W_RopeObject) node = w_s._node l.append(node) @@ -689,9 +691,8 @@ if ival < 0: ival += slen if ival < 0 or ival >= slen: - exc = space.call_function(space.w_IndexError, - space.wrap("string index out of range")) - raise OperationError(space.w_IndexError, exc) + raise OperationError(space.w_IndexError, + space.wrap("string index out of range")) return wrapchar(space, node.getchar(ival)) def getitem__Rope_Slice(space, w_str, w_slice): @@ -756,10 +757,10 @@ def ord__Rope(space, w_str): node = w_str._node if node.length() != 1: - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("ord() expected a character, but string " - "of length %d found"% (w_str._node.length(),))) + "ord() expected a character, but string " + "of length %d found", node.length()) return space.wrap(node.getint(0)) def getnewargs__Rope(space, w_str): Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/ropeunicodeobject.py Mon Jan 25 16:28:47 2010 @@ -1,4 +1,6 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import _normalize_index @@ -24,11 +26,10 @@ encoding = getdefaultencoding(space) w_retval = decode_string(space, w_str, encoding, "strict") if not space.is_true(space.isinstance(w_retval, space.w_unicode)): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap( - "decoder did not return an unicode object (type=%s)" % - space.type(w_retval).getname(space, '?'))) + "decoder did not return an unicode object (type '%s')", + space.type(w_retval).getname(space, '?')) assert isinstance(w_retval, W_RopeUnicodeObject) return w_retval @@ -143,7 +144,7 @@ w_start = space.wrap(i) w_end = space.wrap(i+1) w_reason = space.wrap('invalid decimal Unicode string') - raise OperationError(space.w_UnicodeEncodeError,space.newtuple ([w_encoding, w_unistr, w_start, w_end, w_reason])) + raise OperationError(space.w_UnicodeEncodeError, space.newtuple([w_encoding, w_unistr, w_start, w_end, w_reason])) return ''.join(result) # string-to-unicode delegation @@ -252,9 +253,8 @@ elif space.is_true(space.isinstance(w_item, space.w_str)): item = unicode_from_string(space, w_item)._node else: - w_msg = space.mod(space.wrap('sequence item %d: expected string or Unicode'), - space.wrap(i)) - raise OperationError(space.w_TypeError, w_msg) + msg = 'sequence item %d: expected string or Unicode' + raise operationerrfmt(space.w_TypeError, msg, i) values_list.append(item) try: return W_RopeUnicodeObject(rope.join(w_self._node, values_list)) Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/stdtypedef.py Mon Jan 25 16:28:47 2010 @@ -1,5 +1,5 @@ from pypy.interpreter import gateway, baseobjspace, argument -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member from pypy.interpreter.typedef import descr_get_dict, descr_set_dict from pypy.interpreter.typedef import no_hash_descr, descr_del_dict @@ -141,16 +141,27 @@ prefix = typedef.name +'_mth'+prefix return prefix, list_of_typeorders -def typeerrormsg(space, operatorsymbol, args_w): - type_names = [ space.type(w_arg).getname(space, '?') for w_arg in args_w ] - if len(args_w) > 1: +def _gettypeerrormsg(nbargs): + if nbargs > 1: plural = 's' else: plural = '' - msg = "unsupported operand type%s for %s (%s)" % ( - plural, operatorsymbol, - ', '.join(type_names)) - return space.wrap(msg) + return "unsupported operand type%s for %%s: %s" % ( + plural, ', '.join(["'%s'"] * nbargs)) +_gettypeerrormsg._annspecialcase_ = 'specialize:memo' + +def _gettypenames(space, *args_w): + if args_w: + typename = space.type(args_w[-1]).getname(space, '?') + return _gettypenames(space, *args_w[:-1]) + (typename,) + return () +_gettypenames._always_inline_ = True + +def gettypeerror(space, operatorsymbol, *args_w): + msg = _gettypeerrormsg(len(args_w)) + type_names = _gettypenames(space, *args_w) + return operationerrfmt(space.w_TypeError, msg, + operatorsymbol, *type_names) def make_perform_trampoline(prefix, exprargs, expr, miniglobals, multimethod, selfindex=0, allow_NotImplemented_results=False): @@ -172,7 +183,7 @@ wrapper_arglist += multimethod.extras.get('extra_args', ()) miniglobals.update({ 'OperationError': OperationError, - 'typeerrormsg': typeerrormsg}) + 'gettypeerror': gettypeerror}) app_defaults = multimethod.extras.get('defaults', ()) i = len(argnames) - len(app_defaults) @@ -209,7 +220,7 @@ return %s except FailedToImplement, e: if e.w_type is not None: - raise OperationError(e.w_type, e.w_value) + raise OperationError(e.w_type, e.get_w_value(space)) else: return space.w_NotImplemented """ % (prefix, wrapper_sig, renaming, expr) @@ -221,10 +232,9 @@ w_res = %s except FailedToImplement, e: if e.w_type is not None: - raise OperationError(e.w_type, e.w_value) + raise OperationError(e.w_type, e.get_w_value(space)) else: - raise OperationError(space.w_TypeError, - typeerrormsg(space, %r, [%s])) + raise gettypeerror(space, %r, %s) if w_res is None: w_res = space.w_None return w_res Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/stringobject.py Mon Jan 25 16:28:47 2010 @@ -1,6 +1,6 @@ -# -*- coding: latin-1 -*- - -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.rlib.rarithmetic import ovfcheck from pypy.rlib.objectmodel import we_are_translated, compute_hash @@ -365,11 +365,10 @@ w_list = space.newlist(list_w) w_u = space.call_function(space.w_unicode, w_self) return space.call_method(w_u, "join", w_list) - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("sequence item %d: expected string, %s " - "found" % (i, - space.type(w_s).getname(space, '?')))) + "sequence item %d: expected string, %s " + "found", i, space.type(w_s).getname(space, '?')) l[i] = space.str_w(w_s) return space.wrap(self.join(l)) else: @@ -816,9 +815,8 @@ if ival < 0: ival += slen if ival < 0 or ival >= slen: - exc = space.call_function(space.w_IndexError, - space.wrap("string index out of range")) - raise OperationError(space.w_IndexError, exc) + raise OperationError(space.w_IndexError, + space.wrap("string index out of range")) return wrapchar(space, str[ival]) def getitem__String_Slice(space, w_str, w_slice): @@ -857,9 +855,10 @@ try: buflen = ovfcheck(mul * input_len) except OverflowError: - raise OperationError( + raise operationerrfmt( space.w_OverflowError, - space.wrap("repeated string is too long: %d %d" % (input_len, mul))) + "repeated string is too long: %d times %d characters", + mul, input_len) # XXX maybe only do this when input has a big length return joined(space, [input] * mul) @@ -889,10 +888,10 @@ def ord__String(space, w_str): u_str = w_str._value if len(u_str) != 1: - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("ord() expected a character, but string " - "of length %d found"%(len(w_str._value),))) + "ord() expected a character, but string " + "of length %d found", len(u_str)) return space.wrap(ord(u_str)) def getnewargs__String(space, w_str): Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/transparent.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/transparent.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/transparent.py Mon Jan 25 16:28:47 2010 @@ -4,7 +4,7 @@ from pypy.interpreter import gateway from pypy.interpreter.function import Function -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.proxyobject import * from pypy.objspace.std.typeobject import W_TypeObject from pypy.rlib.objectmodel import r_dict @@ -52,8 +52,9 @@ for k, v in type_cache.cache: if w_lookup == k: return v(space, w_type, w_controller) - raise OperationError(space.w_TypeError, space.wrap("Object type %s could not "\ - "be wrapped (YET)" % w_type.getname(space, "?"))) + raise operationerrfmt(space.w_TypeError, + "'%s' object could not be wrapped (YET)", + w_type.getname(space, "?")) def register_proxyable(space, cls): tpdef = cls.typedef Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/typeobject.py Mon Jan 25 16:28:47 2010 @@ -1,6 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import weakref_descr from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member from pypy.objspace.std.objecttype import object_typedef @@ -283,17 +284,17 @@ def check_user_subclass(w_self, w_subtype): space = w_self.space if not isinstance(w_subtype, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap("X is not a type object (%s)" % ( - space.type(w_subtype).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "X is not a type object ('%s')", + space.type(w_subtype).getname(space, '?')) if not space.is_true(space.issubtype(w_subtype, w_self)): - raise OperationError(space.w_TypeError, - space.wrap("%s.__new__(%s): %s is not a subtype of %s" % ( - w_self.name, w_subtype.name, w_subtype.name, w_self.name))) + raise operationerrfmt(space.w_TypeError, + "%s.__new__(%s): %s is not a subtype of %s", + w_self.name, w_subtype.name, w_subtype.name, w_self.name) if w_self.instancetypedef is not w_subtype.instancetypedef: - raise OperationError(space.w_TypeError, - space.wrap("%s.__new__(%s) is not safe, use %s.__new__()" % ( - w_self.name, w_subtype.name, w_subtype.name))) + raise operationerrfmt(space.w_TypeError, + "%s.__new__(%s) is not safe, use %s.__new__()", + w_self.name, w_subtype.name, w_subtype.name) return w_subtype def _freeze_(w_self): @@ -444,10 +445,10 @@ space.wrap("a new-style class can't have " "only classic bases")) if not w_bestbase.instancetypedef.acceptable_as_base_class: - raise OperationError(space.w_TypeError, - space.wrap("type '%s' is not an " - "acceptable base class" % - w_bestbase.instancetypedef.name)) + raise operationerrfmt(space.w_TypeError, + "type '%s' is not an " + "acceptable base class", + w_bestbase.instancetypedef.name) # check that all other bases' layouts are superclasses of the bestbase w_bestlayout = w_bestbase.w_same_layout_as or w_bestbase @@ -703,8 +704,9 @@ return space.get(w_value, space.w_None, w_type) if w_descr is not None: return space.get(w_descr,w_type) - msg = "type object '%s' has no attribute '%s'" %(w_type.name, name) - raise OperationError(space.w_AttributeError, space.wrap(msg)) + raise operationerrfmt(space.w_AttributeError, + "type object '%s' has no attribute '%s'", + w_type.name, name) def setattr__Type_ANY_ANY(space, w_type, w_name, w_value): # Note. This is exactly the same thing as descroperation.descr__setattr__, @@ -719,8 +721,8 @@ if (space.config.objspace.std.immutable_builtintypes and not w_type.is_heaptype()): - msg = "can't set attributes on type object '%s'" %(w_type.name,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "can't set attributes on type object '%s'" + raise operationerrfmt(space.w_TypeError, msg, w_type.name) if name == "__del__" and name not in w_type.dict_w: msg = "a __del__ method added to an existing type will not be called" space.warn(msg, space.w_RuntimeWarning) @@ -738,8 +740,8 @@ return if (space.config.objspace.std.immutable_builtintypes and not w_type.is_heaptype()): - msg = "can't delete attributes on type object '%s'" %(w_type.name,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "can't delete attributes on type object '%s'" + raise operationerrfmt(space.w_TypeError, msg, w_type.name) try: del w_type.dict_w[name] except KeyError: @@ -806,8 +808,9 @@ candidate = orderlists[-1][0] if candidate in orderlists[-1][1:]: # explicit error message for this specific case - raise OperationError(space.w_TypeError, - space.wrap("duplicate base class " + candidate.getname(space,"?"))) + raise operationerrfmt(space.w_TypeError, + "duplicate base class '%s'", + candidate.getname(space,"?")) while candidate not in cycle: cycle.append(candidate) nextblockinglist = mro_blockinglist(candidate, orderlists) Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/typetype.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/typetype.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/typetype.py Mon Jan 25 16:28:47 2010 @@ -1,4 +1,4 @@ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import weakref_descr @@ -51,18 +51,19 @@ def _precheck_for_new(space, w_type): from pypy.objspace.std.typeobject import W_TypeObject if not isinstance(w_type, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap("X is not a type object (%s)" % - (space.type(w_type).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "X is not a type object (%s)", + space.type(w_type).getname(space, '?')) return w_type # ____________________________________________________________ -def _check(space, w_type, msg=None): +def _check(space, w_type, w_msg=None): from pypy.objspace.std.typeobject import W_TypeObject if not isinstance(w_type, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap(msg or "descriptor is for 'type'")) + if w_msg is None: + w_msg = space.wrap("descriptor is for 'type'") + raise OperationError(space.w_TypeError, w_msg) return w_type @@ -73,9 +74,8 @@ def descr_set__name__(space, w_type, w_value): w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise OperationError(space.w_TypeError, - space.wrap("can't set %s.__name__" % - w_type.name)) + raise operationerrfmt(space.w_TypeError, + "can't set %s.__name__", w_type.name) w_type.name = space.str_w(w_value) def descr_get__mro__(space, w_type): @@ -84,7 +84,7 @@ def descr_mro(space, w_type): """Return a type's method resolution order.""" - w_type = _check(space, w_type,"expected type") + w_type = _check(space, w_type, space.wrap("expected type")) return space.newlist(w_type.compute_default_mro()) def descr_get__bases__(space, w_type): @@ -106,21 +106,18 @@ from pypy.objspace.std.typeobject import get_parent_layout w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise OperationError(space.w_TypeError, - space.wrap("can't set %s.__bases__" % - (w_type.name,))) + raise operationerrfmt(space.w_TypeError, + "can't set %s.__bases__", w_type.name) if not space.is_true(space.isinstance(w_value, space.w_tuple)): - raise OperationError(space.w_TypeError, - space.wrap("can only assign tuple" - " to %s.__bases__, not %s"% - (w_type.name, - space.type(w_value).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "can only assign tuple to %s.__bases__, not %s", + w_type.name, + space.type(w_value).getname(space, '?')) newbases_w = space.fixedview(w_value) if len(newbases_w) == 0: - raise OperationError(space.w_TypeError, - space.wrap("can only assign non-empty tuple" - " to %s.__bases__, not ()"% - (w_type.name,))) + raise operationerrfmt(space.w_TypeError, + "can only assign non-empty tuple to %s.__bases__, not ()", + w_type.name) for w_newbase in newbases_w: if isinstance(w_newbase, W_TypeObject): @@ -135,11 +132,11 @@ newlayout = w_newbestbase.get_full_instance_layout() if oldlayout != newlayout: - raise OperationError(space.w_TypeError, - space.wrap("__bases__ assignment: '%s' object layout" - " differs from '%s'" % - (w_newbestbase.getname(space, '?'), - w_oldbestbase.getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "__bases__ assignment: '%s' object layout" + " differs from '%s'", + w_newbestbase.getname(space, '?'), + w_oldbestbase.getname(space, '?')) # invalidate the version_tag of all the current subclasses w_type.mutated() @@ -191,9 +188,9 @@ def descr_set__module(space, w_type, w_value): w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise OperationError(space.w_TypeError, - space.wrap("can't set %s.__module__" % - w_type.name)) + raise operationerrfmt(space.w_TypeError, + "can't set %s.__module__", + w_type.name) w_type.mutated() w_type.dict_w['__module__'] = w_value Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/unicodeobject.py Mon Jan 25 16:28:47 2010 @@ -1,5 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.stringobject import W_StringObject, make_rsplit_with_delim from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.noneobject import W_NoneObject @@ -42,8 +44,9 @@ # Helper for converting int/long def unicode_to_decimal_w(space, w_unistr): if not isinstance(w_unistr, W_UnicodeObject): - raise OperationError(space.w_TypeError, - space.wrap("expected unicode")) + raise operationerrfmt(space.w_TypeError, + "expected unicode, got '%s'", + space.type(w_unistr).getname(space, '?')) unistr = w_unistr._value result = ['\0'] * len(unistr) digits = [ '0', '1', '2', '3', '4', @@ -63,7 +66,7 @@ w_start = space.wrap(i) w_end = space.wrap(i+1) w_reason = space.wrap('invalid decimal Unicode string') - raise OperationError(space.w_UnicodeEncodeError,space.newtuple ([w_encoding, w_unistr, w_start, w_end, w_reason])) + raise OperationError(space.w_UnicodeEncodeError, space.newtuple([w_encoding, w_unistr, w_start, w_end, w_reason])) return ''.join(result) # string-to-unicode delegation @@ -80,11 +83,11 @@ except OperationError, e: if e.match(space, space.w_UnicodeDecodeError): if inverse: - word = "unequal" + msg = "Unicode unequal comparison failed to convert both " \ + "arguments to Unicode - interpreting them as being unequal" else : - word = "equal" - msg = "Unicode %s comparison failed to convert both arguments\ - to Unicode - interpreting them as being unequal" % word + msg = "Unicode equal comparison failed to convert both " \ + "arguments to Unicode - interpreting them as being unequal" space.warn(msg, space.w_UnicodeWarning) return space.newbool(inverse) raise @@ -127,7 +130,9 @@ def ord__Unicode(space, w_uni): if len(w_uni._value) != 1: - raise OperationError(space.w_TypeError, space.wrap('ord() expected a character')) + raise operationerrfmt(space.w_TypeError, + "ord() expected a character, got a unicode of length %d", + len(w_uni._value)) return space.wrap(ord(w_uni._value[0])) def getnewargs__Unicode(space, w_uni): @@ -192,9 +197,8 @@ elif space.is_true(space.isinstance(item, space.w_str)): item = space.unicode_w(item) else: - w_msg = space.mod(space.wrap('sequence item %d: expected string or Unicode'), - space.wrap(i)) - raise OperationError(space.w_TypeError, w_msg) + raise operationerrfmt(space.w_TypeError, + "sequence item %d: expected string or Unicode", i) values_list[i] = item return W_UnicodeObject(w_self._value.join(values_list)) Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/unicodetype.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/unicodetype.py Mon Jan 25 16:28:47 2010 @@ -2,7 +2,7 @@ from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all from pypy.objspace.std.basestringtype import basestring_typedef -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from sys import maxint @@ -181,11 +181,9 @@ w_restuple = space.call_function(w_encoder, w_object, w_errors) w_retval = space.getitem(w_restuple, space.wrap(0)) if not space.is_true(space.isinstance(w_retval, space.w_str)): - raise OperationError( - space.w_TypeError, - space.wrap( - "encoder did not return an string object (type=%s)" % - space.type(w_retval).getname(space, '?'))) + raise operationerrfmt(space.w_TypeError, + "encoder did not return an string object (type '%s')", + space.type(w_retval).getname(space, '?')) return w_retval def decode_object(space, w_obj, encoding, errors): @@ -204,11 +202,9 @@ def unicode_from_encoded_object(space, w_obj, encoding, errors): w_retval = decode_object(space, w_obj, encoding, errors) if not space.is_true(space.isinstance(w_retval, space.w_unicode)): - raise OperationError( - space.w_TypeError, - space.wrap( - "decoder did not return an unicode object (type=%s)" % - space.type(w_retval).getname(space, '?'))) + raise operationerrfmt(space.w_TypeError, + "decoder did not return an unicode object (type '%s')", + space.type(w_retval).getname(space, '?')) return w_retval def unicode_from_object(space, w_obj): Modified: pypy/branch/lazy-operr-format/pypy/tool/test/test_pytestsupport.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/tool/test/test_pytestsupport.py (original) +++ pypy/branch/lazy-operr-format/pypy/tool/test/test_pytestsupport.py Mon Jan 25 16:28:47 2010 @@ -41,7 +41,7 @@ f.call_args(Arguments(None, [])) except OperationError, e: assert e.match(space, space.w_AssertionError) - assert space.unwrap(space.str(e.w_value)) == 'assert 42 == 43' + assert space.unwrap(space.str(e.get_w_value(space))) == 'assert 42 == 43' else: assert False, "got no exception!" Modified: pypy/branch/lazy-operr-format/pypy/tool/traceop.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/tool/traceop.py (original) +++ pypy/branch/lazy-operr-format/pypy/tool/traceop.py Mon Jan 25 16:28:47 2010 @@ -273,7 +273,7 @@ # Special case - operation error if isinstance(obj, OperationError): return "OpError(%s, %s)" % (repr_value(space, obj.w_type), - repr_value(space, obj.w_value)) + repr_value(space, obj.get_w_value(space))) # Try object repr try: Modified: pypy/branch/lazy-operr-format/pypy/translator/geninterplevel.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/translator/geninterplevel.py (original) +++ pypy/branch/lazy-operr-format/pypy/translator/geninterplevel.py Mon Jan 25 16:28:47 2010 @@ -1366,7 +1366,7 @@ q = "elif" for op in self.gen_link(link, localscope, blocknum, block, { link.last_exception: 'e.w_type', - link.last_exc_value: 'e.w_value'}): + link.last_exc_value: 'e.get_w_value(space)'}): yield " %s" % op yield " else:raise # unhandled case, should not happen" else: Modified: pypy/branch/lazy-operr-format/pypy/translator/goal/sharedpypy.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/translator/goal/sharedpypy.py (original) +++ pypy/branch/lazy-operr-format/pypy/translator/goal/sharedpypy.py Mon Jan 25 16:28:47 2010 @@ -39,7 +39,7 @@ except OperationError, e: print "OperationError:" print " operror-type: " + e.w_type.getname(space, '?') - print " operror-value: " + space.str_w(space.str(e.w_value)) + print " operror-value: " + space.str_w(space.str(e.get_w_value(space))) return 1 return 0 Modified: pypy/branch/lazy-operr-format/pypy/translator/goal/targetpreimportedpypy.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/translator/goal/targetpreimportedpypy.py (original) +++ pypy/branch/lazy-operr-format/pypy/translator/goal/targetpreimportedpypy.py Mon Jan 25 16:28:47 2010 @@ -74,7 +74,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 finally: try: @@ -84,7 +84,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 space.timer.stop("Entrypoint") space.timer.dump() Modified: pypy/branch/lazy-operr-format/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/branch/lazy-operr-format/pypy/translator/goal/targetpypystandalone.py Mon Jan 25 16:28:47 2010 @@ -62,7 +62,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 finally: try: @@ -72,7 +72,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 space.timer.stop("Entrypoint") space.timer.dump() From arigo at codespeak.net Mon Jan 25 16:47:19 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 16:47:19 +0100 (CET) Subject: [pypy-svn] r70839 - pypy/branch/lazy-operr-format/pypy/interpreter Message-ID: <20100125154719.C2DC5318139@codespeak.net> Author: arigo Date: Mon Jan 25 16:47:18 2010 New Revision: 70839 Modified: pypy/branch/lazy-operr-format/pypy/interpreter/error.py Log: Transation fixes. Modified: pypy/branch/lazy-operr-format/pypy/interpreter/error.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/error.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/error.py Mon Jan 25 16:47:18 2010 @@ -16,16 +16,19 @@ PyTraceback objects making the application-level traceback. """ - __slots__ = ('w_type', '_w_value', 'application_traceback', - 'debug_excs') + _w_value = None + application_traceback = None def __init__(self, w_type, w_value, tb=None): - if w_type is None: + if not we_are_translated() and w_type is None: from pypy.tool.error import FlowingError raise FlowingError(w_value) - self.w_type = w_type + self.setup(w_type) self._w_value = w_value self.application_traceback = tb + + def setup(self, w_type): + self.w_type = w_type if not we_are_translated(): self.debug_excs = [] @@ -285,11 +288,14 @@ # class OpErrFmt(OperationError): def __init__(self, w_type, strings, *args): - OperationError.__init__(self, w_type, None) + self.setup(w_type) assert len(args) == len(strings) - 1 self.xstrings = strings for i, attr in entries: setattr(self, attr, args[i]) + if not we_are_translated() and w_type is None: + from pypy.tool.error import FlowingError + raise FlowingError(self._compute_value()) def _compute_value(self): lst = [None] * (len(formats) + len(formats) + 1) for i, attr in entries: From fijal at codespeak.net Mon Jan 25 16:49:23 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 16:49:23 +0100 (CET) Subject: [pypy-svn] r70840 - in pypy/branch/stringbuilder2/pypy: rlib rpython rpython/lltypesystem rpython/memory rpython/memory/gc rpython/memory/gctransform rpython/memory/test Message-ID: <20100125154923.1DAD4318139@codespeak.net> Author: fijal Date: Mon Jan 25 16:49:22 2010 New Revision: 70840 Modified: pypy/branch/stringbuilder2/pypy/rlib/rgc.py pypy/branch/stringbuilder2/pypy/rpython/llinterp.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Log: IN-PROGRESS Check in what I have in my wc, so we can pair Modified: pypy/branch/stringbuilder2/pypy/rlib/rgc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rlib/rgc.py (original) +++ pypy/branch/stringbuilder2/pypy/rlib/rgc.py Mon Jan 25 16:49:22 2010 @@ -308,7 +308,7 @@ return hop.genop('resize_buffer', vlist, resulttype=hop.r_result.lowleveltype) -def finish_building_buffer(ptr, final_size): +def finish_building_buffer(ptr, old_size, final_size): """ Finish building resizable buffer returned by resizable_buffer_of_shape """ return ptr @@ -316,20 +316,24 @@ class FinishBuildingBufferEntry(ExtRegistryEntry): _about_ = finish_building_buffer - def compute_result_annotation(self, s_arr, s_final_size): + def compute_result_annotation(self, s_arr, s_old_size, s_final_size): from pypy.annotation.model import SomePtr, s_ImpossibleValue,\ SomeInteger assert isinstance(s_arr, SomePtr) + assert isinstance(s_old_size, SomeInteger) assert isinstance(s_final_size, SomeInteger) return s_arr def specialize_call(self, hop): from pypy.rpython.lltypesystem import lltype vlist = [hop.inputarg(hop.args_r[0], 0), - hop.inputarg(hop.args_r[1], 1)] - hop.exception_cannot_occur() - return hop.genop('finish_building_buffer', vlist, - resulttype=hop.r_result.lowleveltype) + hop.inputarg(hop.args_r[1], 1), + hop.inputarg(hop.args_r[2], 2)] + hop.exception_is_here() + res = hop.genop('finish_building_buffer', vlist, + resulttype=hop.r_result.lowleveltype) + hop.genop('keepalive', [hop.args_v[0]]) + return res def ll_arraycopy(source, dest, source_start, dest_start, length): from pypy.rpython.lltypesystem.lloperation import llop Modified: pypy/branch/stringbuilder2/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/llinterp.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/llinterp.py Mon Jan 25 16:49:22 2010 @@ -754,8 +754,8 @@ def op_resize_buffer(self, obj, old_size, new_size): return self.heap.resize_buffer(obj, old_size, new_size) - def op_finish_building_buffer(self, obj, size): - return self.heap.finish_building_buffer(obj, size) + def op_finish_building_buffer(self, obj, oldsize, size): + return self.heap.finish_building_buffer(obj, oldsize, size) def op_free(self, obj, flavor): assert isinstance(flavor, str) Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py Mon Jan 25 16:49:22 2010 @@ -99,7 +99,8 @@ @staticmethod def ll_build(ll_builder): final_size = ll_builder.used - return rgc.finish_building_buffer(ll_builder.buf, final_size) + return rgc.finish_building_buffer(ll_builder.buf, ll_builder.allocated, + final_size) class StringBuilderRepr(BaseStringBuilderRepr): lowleveltype = lltype.Ptr(STRINGBUILDER) Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py Mon Jan 25 16:49:22 2010 @@ -135,29 +135,6 @@ # lots of cast and reverse-cast around... return llmemory.cast_ptr_to_adr(ref) - def realloc(self, source, oldlength, newlength, fixedsize, itemsize, - lengthofs, itemsofs, grow): - # by default, realloc mallocs stuff and copies it over when growing. - # when shrinking, we only change length and be happy - source_adr = llmemory.cast_ptr_to_adr(source) - type_id = self.get_type_id(source_adr) - if not hasattr(self, 'malloc_varsize'): - malloc_varsize = self.malloc_varsize_clear - else: - malloc_varsize = self.malloc_varsize - typeid = self.get_type_id(source_adr) - if grow: - dest = malloc_varsize(typeid, newlength, fixedsize, itemsize, - lengthofs, True) - dest_adr = llmemory.cast_ptr_to_adr(dest) - llmemory.raw_memcopy(source_adr + itemsofs, dest_adr + itemsofs, - itemsize * oldlength) - keepalive_until_here(source) - else: - (source_adr + lengthofs).signed[0] = newlength - dest = source - return dest - def malloc_nonmovable(self, typeid, length=0, zero=False): return self.malloc(typeid, length, zero) Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py Mon Jan 25 16:49:22 2010 @@ -576,36 +576,31 @@ def gct_resize_buffer(self, hop): op = hop.spaceop - if self._can_realloc(): - self._gct_resize_buffer_realloc(hop, op.args[1], op.args[2], True) - else: - self._gct_resize_buffer_no_realloc(hop, op.args[1]) - - def _can_realloc(self): - return False + # if we want to support a general realloc, support goes here + self._malloc_and_copy(hop, op.args[1], op.args[2]) - def _gct_resize_buffer_realloc(self, hop, v_oldsize, v_newsize, grow=True): - def intconst(c): return rmodel.inputconst(lltype.Signed, c) - op = hop.spaceop - flags = {'flavor':'gc', 'varsize': True} - TYPE = op.args[0].concretetype.TO - ARRAY = TYPE._flds[TYPE._arrayfld] - offset_to_length = llmemory.FieldOffset(TYPE, TYPE._arrayfld) + \ - llmemory.ArrayLengthOffset(ARRAY) - c_const_size = intconst(llmemory.sizeof(TYPE, 0)) - c_item_size = intconst(llmemory.sizeof(ARRAY.OF)) - - c_lengthofs = intconst(offset_to_length) - c_itemsofs = intconst(llmemory.itemoffsetof(TYPE, 0)) - v_ptr = op.args[0] - v_ptr = gen_cast(hop.llops, llmemory.GCREF, v_ptr) - c_grow = rmodel.inputconst(lltype.Bool, grow) - v_raw = self.perform_realloc(hop, v_ptr, v_oldsize, v_newsize, - c_const_size, c_item_size, c_lengthofs, - c_itemsofs, c_grow) - hop.cast_result(v_raw) + # def _malloc_and_copy(self, hop, v_oldsize, v_newsize, grow=True): + # def intconst(c): return rmodel.inputconst(lltype.Signed, c) + # op = hop.spaceop + # flags = {'flavor':'gc', 'varsize': True} + # TYPE = op.args[0].concretetype.TO + # ARRAY = TYPE._flds[TYPE._arrayfld] + # offset_to_length = llmemory.FieldOffset(TYPE, TYPE._arrayfld) + \ + # llmemory.ArrayLengthOffset(ARRAY) + # c_const_size = intconst(llmemory.sizeof(TYPE, 0)) + # c_item_size = intconst(llmemory.sizeof(ARRAY.OF)) + + # c_lengthofs = intconst(offset_to_length) + # c_itemsofs = intconst(llmemory.itemoffsetof(TYPE, 0)) + # v_ptr = op.args[0] + # v_ptr = gen_cast(hop.llops, llmemory.GCREF, v_ptr) + # c_grow = rmodel.inputconst(lltype.Bool, grow) + # v_raw = self.perform_realloc(hop, v_ptr, v_oldsize, v_newsize, + # c_const_size, c_item_size, c_lengthofs, + # c_itemsofs, c_grow) + # hop.cast_result(v_raw) - def _gct_resize_buffer_no_realloc(self, hop, v_lgt): + def _malloc_and_copy(self, hop, v_lgt): op = hop.spaceop meth = self.gct_fv_gc_malloc_varsize flags = {'flavor':'gc', 'varsize': True, 'keep_current_args': True} @@ -634,6 +629,7 @@ hop.genop('raw_memcopy', vlist) def gct_finish_building_buffer(self, hop): + xxx op = hop.spaceop if self._can_realloc(): return self._gct_resize_buffer_realloc(hop, op.args[1], Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py Mon Jan 25 16:49:22 2010 @@ -4,7 +4,6 @@ from pypy.rpython.memory import gctypelayout from pypy.objspace.flow.model import Constant - class GCManagedHeap(object): def __init__(self, llinterp, flowgraphs, gc_class, GC_PARAMS={}): @@ -70,28 +69,22 @@ def resize_buffer(self, obj, oldlength, newlength): T = lltype.typeOf(obj).TO ARRAY = getattr(T, T._arrayfld) + addr = llmemory.cast_ptr_to_adr(obj) + newaddr = self.gc.malloc(self.gc.get_type_id(addr), newlength, True) + addr = llmemory.cast_ptr_to_adr(obj) itemsofs = (llmemory.FieldOffset(T, T._arrayfld) + llmemory.itemoffsetof(ARRAY, 0)) - fixedsize = llmemory.sizeof(T, 0) - itemsize = llmemory.sizeof(ARRAY.OF) - lengthofs = llmemory.FieldOffset(T, T._arrayfld) + \ - llmemory.ArrayLengthOffset(ARRAY) - result = self.gc.realloc(obj, oldlength, newlength, fixedsize, - itemsize, lengthofs, itemsofs, True) - return lltype.cast_opaque_ptr(lltype.typeOf(obj), result) - - def finish_building_buffer(self, obj, newlength): - T = lltype.typeOf(obj).TO - ARRAY = getattr(T, T._arrayfld) - itemsofs = (llmemory.FieldOffset(T, T._arrayfld) + - llmemory.itemoffsetof(ARRAY, 0)) - fixedsize = llmemory.sizeof(T, 0) itemsize = llmemory.sizeof(ARRAY.OF) - lengthofs = llmemory.FieldOffset(T, T._arrayfld) + \ - llmemory.ArrayLengthOffset(ARRAY) - result = self.gc.realloc(obj, 0, newlength, fixedsize, - itemsize, lengthofs, itemsofs, False) - return lltype.cast_opaque_ptr(lltype.typeOf(obj), result) + tocopy = min(newlength, oldlength) + llmemory.raw_memcopy(addr + itemsofs, newaddr + itemsofs, + tocopy * itemsize) + return llmemory.cast_adr_to_ptr(newaddr, lltype.Ptr(T)) + + def finish_building_buffer(self, obj, oldlength, newlength): + if hasattr(self.gc, 'realloc_shrink'): + xxx + else: + return self.resize_buffer(obj, oldlength, newlength) def free(self, TYPE, flavor='gc'): assert flavor != 'gc' Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Mon Jan 25 16:49:22 2010 @@ -571,20 +571,20 @@ self.interpret(fn, []) - def test_stringbuilder(self): - def fn(): - s = StringBuilder(4) - s.append("abcd") - s.append("defg") - s.append("rty") - s.append_multiple_char('y', 1000) - rgc.collect() - s.append_multiple_char('y', 1000) - res = s.build()[1000] - rgc.collect() - return ord(res) - res = self.interpret(fn, []) - assert res == ord('y') + # def test_stringbuilder(self): + # def fn(): + # s = StringBuilder(4) + # s.append("abcd") + # s.append("defg") + # s.append("rty") + # s.append_multiple_char('y', 1000) + # rgc.collect() + # s.append_multiple_char('y', 1000) + # res = s.build()[1000] + # rgc.collect() + # return ord(res) + # res = self.interpret(fn, []) + # assert res == ord('y') from pypy.rlib.objectmodel import UnboxedValue From fijal at codespeak.net Mon Jan 25 16:51:31 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 25 Jan 2010 16:51:31 +0100 (CET) Subject: [pypy-svn] r70841 - pypy/branch/stringbuilder2/pypy/rpython/memory/test Message-ID: <20100125155131.BF52D318139@codespeak.net> Author: fijal Date: Mon Jan 25 16:51:31 2010 New Revision: 70841 Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Log: uncomment a test Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Mon Jan 25 16:51:31 2010 @@ -571,20 +571,20 @@ self.interpret(fn, []) - # def test_stringbuilder(self): - # def fn(): - # s = StringBuilder(4) - # s.append("abcd") - # s.append("defg") - # s.append("rty") - # s.append_multiple_char('y', 1000) - # rgc.collect() - # s.append_multiple_char('y', 1000) - # res = s.build()[1000] - # rgc.collect() - # return ord(res) - # res = self.interpret(fn, []) - # assert res == ord('y') + def test_stringbuilder(self): + def fn(): + s = StringBuilder(4) + s.append("abcd") + s.append("defg") + s.append("rty") + s.append_multiple_char('y', 1000) + rgc.collect() + s.append_multiple_char('y', 1000) + res = s.build()[1000] + rgc.collect() + return ord(res) + res = self.interpret(fn, []) + assert res == ord('y') from pypy.rlib.objectmodel import UnboxedValue From arigo at codespeak.net Mon Jan 25 18:20:32 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 18:20:32 +0100 (CET) Subject: [pypy-svn] r70842 - in pypy/branch/stringbuilder2/pypy: rlib rlib/test rpython/lltypesystem Message-ID: <20100125172032.4D1E41680C1@codespeak.net> Author: arigo Date: Mon Jan 25 18:20:31 2010 New Revision: 70842 Modified: pypy/branch/stringbuilder2/pypy/rlib/rgc.py pypy/branch/stringbuilder2/pypy/rlib/test/test_rgc.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/opimpl.py Log: (fijal, arigo) Kill the resize_buffer() interface from rlib.rgc. Add another, simpler interface: ll_shrink_array(). To be used to simplify the implementation of rbuilder.py. Modified: pypy/branch/stringbuilder2/pypy/rlib/rgc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rlib/rgc.py (original) +++ pypy/branch/stringbuilder2/pypy/rlib/rgc.py Mon Jan 25 18:20:31 2010 @@ -242,99 +242,6 @@ hop.exception_cannot_occur() return hop.genop(opname, vlist, resulttype = hop.r_result.lowleveltype) -def resizable_buffer_of_shape(T, init_size): - """ Pre-allocates structure of type T (varsized) with possibility - to reallocate it further by resize_buffer. - """ - from pypy.rpython.lltypesystem import lltype - return lltype.malloc(T, init_size) - -class ResizableBufferOfShapeEntry(ExtRegistryEntry): - _about_ = resizable_buffer_of_shape - - def compute_result_annotation(self, s_T, s_init_size): - from pypy.annotation import model as annmodel - from pypy.rpython.lltypesystem import rffi, lltype - assert s_T.is_constant() - assert isinstance(s_init_size, annmodel.SomeInteger) - T = s_T.const - # limit ourselves to structs and to a fact that var-sized element - # does not contain pointers. - assert isinstance(T, lltype.Struct) - assert isinstance(getattr(T, T._arrayfld).OF, lltype.Primitive) - return annmodel.SomePtr(lltype.Ptr(T)) - - def specialize_call(self, hop): - from pypy.rpython.lltypesystem import lltype - flags = {'flavor': 'gc'} - vlist = [hop.inputarg(lltype.Void, 0), - hop.inputconst(lltype.Void, flags), - hop.inputarg(lltype.Signed, 1)] - hop.exception_is_here() - return hop.genop('malloc_resizable_buffer', vlist, - resulttype=hop.r_result.lowleveltype) - -def resize_buffer(ptr, old_size, new_size): - """ Resize raw buffer returned by resizable_buffer_of_shape to new size - """ - from pypy.rpython.lltypesystem import lltype - T = lltype.typeOf(ptr).TO - arrayfld = T._arrayfld - arr = getattr(ptr, arrayfld) - # we don't have any realloc on top of cpython - new_ptr = lltype.malloc(T, new_size) - new_ar = getattr(new_ptr, arrayfld) - for i in range(old_size): - new_ar[i] = arr[i] - return new_ptr - -class ResizeBufferEntry(ExtRegistryEntry): - _about_ = resize_buffer - - def compute_result_annotation(self, s_ptr, s_old_size, s_new_size): - from pypy.annotation import model as annmodel - from pypy.rpython.lltypesystem import rffi - assert isinstance(s_ptr, annmodel.SomePtr) - assert isinstance(s_new_size, annmodel.SomeInteger) - assert isinstance(s_old_size, annmodel.SomeInteger) - return s_ptr - - def specialize_call(self, hop): - from pypy.rpython.lltypesystem import lltype - vlist = [hop.inputarg(hop.args_r[0], 0), - hop.inputarg(lltype.Signed, 1), - hop.inputarg(lltype.Signed, 2)] - hop.exception_is_here() - return hop.genop('resize_buffer', vlist, - resulttype=hop.r_result.lowleveltype) - -def finish_building_buffer(ptr, old_size, final_size): - """ Finish building resizable buffer returned by resizable_buffer_of_shape - """ - return ptr - -class FinishBuildingBufferEntry(ExtRegistryEntry): - _about_ = finish_building_buffer - - def compute_result_annotation(self, s_arr, s_old_size, s_final_size): - from pypy.annotation.model import SomePtr, s_ImpossibleValue,\ - SomeInteger - assert isinstance(s_arr, SomePtr) - assert isinstance(s_old_size, SomeInteger) - assert isinstance(s_final_size, SomeInteger) - return s_arr - - def specialize_call(self, hop): - from pypy.rpython.lltypesystem import lltype - vlist = [hop.inputarg(hop.args_r[0], 0), - hop.inputarg(hop.args_r[1], 1), - hop.inputarg(hop.args_r[2], 2)] - hop.exception_is_here() - res = hop.genop('finish_building_buffer', vlist, - resulttype=hop.r_result.lowleveltype) - hop.genop('keepalive', [hop.args_v[0]]) - return res - def ll_arraycopy(source, dest, source_start, dest_start, length): from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.lltypesystem import lltype, llmemory @@ -370,6 +277,36 @@ ll_arraycopy._annspecialcase_ = 'specialize:ll' ll_arraycopy._jit_look_inside_ = False +def ll_shrink_array(p, smallerlength): + from pypy.rpython.lltypesystem.lloperation import llop + from pypy.rpython.lltypesystem import lltype, llmemory + from pypy.rlib.objectmodel import keepalive_until_here + + if llop.shrink_array(lltype.Bool, p, smallerlength): + return p # done by the GC + # XXX we assume for now that the type of p is GcStruct containing a + # variable array, with no further pointers anywhere + + TP = lltype.typeOf(p).TO + newp = lltype.malloc(TP, smallerlength) + + source_addr = llmemory.cast_ptr_to_adr(p) + dest_addr = llmemory.cast_ptr_to_adr(newp) + staticsize = llmemory.offsetof(TP, TP._arrayfld) + llmemory.raw_memcopy(source_addr, dest_addr, staticsize) + + ARRAY = getattr(TP, TP._arrayfld) + source_addr += staticsize + llmemory.itemoffsetof(ARRAY, 0) + dest_addr += staticsize + llmemory.itemoffsetof(ARRAY, 0) + llmemory.raw_memcopy(source_addr, dest_addr, + llmemory.sizeof(ARRAY.OF) * smallerlength) + + keepalive_until_here(p) + keepalive_until_here(newp) + return newp +ll_shrink_array._annspecialcase_ = 'specialize:ll' + + def no_collect(func): func._dont_inline_ = True func._gc_no_collect_ = True Modified: pypy/branch/stringbuilder2/pypy/rlib/test/test_rgc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rlib/test/test_rgc.py (original) +++ pypy/branch/stringbuilder2/pypy/rlib/test/test_rgc.py Mon Jan 25 18:20:31 2010 @@ -56,19 +56,6 @@ assert res == True -def test_resizable_buffer(): - from pypy.rpython.lltypesystem.rstr import STR - from pypy.rpython.annlowlevel import hlstr - - def f(): - ptr = rgc.resizable_buffer_of_shape(STR, 1) - ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 2) - ptr.chars[1] = 'b' - return hlstr(rgc.finish_building_buffer(ptr, 2)) - - assert f() == 'ab' - def test_ll_arraycopy_1(): TYPE = lltype.GcArray(lltype.Signed) a1 = lltype.malloc(TYPE, 10) @@ -126,3 +113,21 @@ assert a2[i] == a1[i+2] else: assert a2[i] == org2[i] + +def test_ll_shrink_array_1(): + py.test.skip("implement ll_shrink_array for GcStructs or GcArrays that " + "don't have the shape of STR or UNICODE") + +def test_ll_shrink_array_2(): + S = lltype.GcStruct('S', ('x', lltype.Signed), + ('vars', lltype.Array(lltype.Signed))) + s1 = lltype.malloc(S, 5) + s1.x = 1234 + for i in range(5): + s1.vars[i] = 50 + i + s2 = rgc.ll_shrink_array(s1, 3) + assert lltype.typeOf(s2) == lltype.Ptr(S) + assert s2.x == 1234 + assert len(s2.vars) == 3 + for i in range(3): + assert s2.vars[i] == 50 + i Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py Mon Jan 25 18:20:31 2010 @@ -354,9 +354,7 @@ 'malloc_varsize': LLOp(canraise=(MemoryError,), canunwindgc=True), 'malloc_nonmovable': LLOp(canraise=(MemoryError,), canunwindgc=True), 'malloc_nonmovable_varsize':LLOp(canraise=(MemoryError,),canunwindgc=True), - 'malloc_resizable_buffer': LLOp(canraise=(MemoryError,),canunwindgc=True), - 'resize_buffer': LLOp(canraise=(MemoryError,), canunwindgc=True), - 'finish_building_buffer' : LLOp(canraise=(MemoryError,), canunwindgc=True), + 'shrink_array': LLOp(canrun=True), 'zero_gc_pointers_inside': LLOp(), 'free': LLOp(), 'getfield': LLOp(sideeffects=False, canrun=True), Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/opimpl.py Mon Jan 25 18:20:31 2010 @@ -500,6 +500,9 @@ def op_gc_assume_young_pointers(addr): pass +def op_shrink_array(array, smallersize): + return False + # ____________________________________________________________ def get_op_impl(opname): From arigo at codespeak.net Mon Jan 25 18:23:13 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 18:23:13 +0100 (CET) Subject: [pypy-svn] r70843 - in pypy/branch/stringbuilder2/pypy/rpython: lltypesystem test Message-ID: <20100125172313.D35901680F6@codespeak.net> Author: arigo Date: Mon Jan 25 18:23:13 2010 New Revision: 70843 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py pypy/branch/stringbuilder2/pypy/rpython/test/test_rbuilder.py Log: (fijal, arigo) Use the new interface provided by rlib.rgc. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py Mon Jan 25 18:23:13 2010 @@ -1,6 +1,6 @@ from pypy.rpython.rbuilder import AbstractStringBuilderRepr -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, rstr from pypy.rpython.lltypesystem.rstr import STR, UNICODE, char_repr,\ string_repr, unichar_repr, unicode_repr from pypy.rpython.annlowlevel import llstr @@ -9,9 +9,12 @@ from pypy.rpython.lltypesystem.lltype import staticAdtMethod from pypy.tool.sourcetools import func_with_new_name +# Think about heuristics below, maybe we can come up with something +# better or at least compare it with list heuristics + GROW_FAST_UNTIL = 100*1024*1024 # 100 MB -def new_grow_func(name): +def new_grow_func(name, mallocfn, copycontentsfn): def stringbuilder_grow(ll_builder, needed): allocated = ll_builder.allocated #if allocated < GROW_FAST_UNTIL: @@ -20,31 +23,31 @@ extra_size = allocated >> 2 try: new_allocated = ovfcheck(allocated + extra_size) - except OverflowError: - raise MemoryError - try: new_allocated = ovfcheck(new_allocated + needed) except OverflowError: raise MemoryError - ll_builder.buf = rgc.resize_buffer(ll_builder.buf, ll_builder.allocated, - new_allocated) + newbuf = mallocfn(new_allocated) + copycontentsfn(ll_builder.buf, newbuf, 0, 0, ll_builder.allocated) + ll_builder.buf = newbuf ll_builder.allocated = new_allocated return func_with_new_name(stringbuilder_grow, name) -stringbuilder_grow = new_grow_func('stringbuilder_grow') -unicodebuilder_grow = new_grow_func('unicodebuilder_grow') +stringbuilder_grow = new_grow_func('stringbuilder_grow', rstr.mallocstr, + rstr.copy_string_contents) +unicodebuilder_grow = new_grow_func('unicodebuilder_grow', rstr.mallocunicode, + rstr.copy_unicode_contents) STRINGBUILDER = lltype.GcStruct('stringbuilder', - ('allocated', lltype.Signed), - ('used', lltype.Signed), - ('buf', lltype.Ptr(STR)), - adtmeths={'grow':staticAdtMethod(stringbuilder_grow)}) + ('allocated', lltype.Signed), + ('used', lltype.Signed), + ('buf', lltype.Ptr(STR)), + adtmeths={'grow':staticAdtMethod(stringbuilder_grow)}) UNICODEBUILDER = lltype.GcStruct('unicodebuilder', ('allocated', lltype.Signed), ('used', lltype.Signed), ('buf', lltype.Ptr(UNICODE)), - adtmeths={'grow':staticAdtMethod(unicodebuilder_grow)}) + adtmeths={'grow':staticAdtMethod(unicodebuilder_grow)}) MAX = 16*1024*1024 @@ -56,7 +59,7 @@ ll_builder = lltype.malloc(cls.lowleveltype.TO) ll_builder.allocated = init_size ll_builder.used = 0 - ll_builder.buf = rgc.resizable_buffer_of_shape(cls.basetp, init_size) + ll_builder.buf = lltype.malloc(cls.basetp, init_size) return ll_builder @staticmethod @@ -99,8 +102,7 @@ @staticmethod def ll_build(ll_builder): final_size = ll_builder.used - return rgc.finish_building_buffer(ll_builder.buf, ll_builder.allocated, - final_size) + return rgc.ll_shrink_array(ll_builder.buf, final_size) class StringBuilderRepr(BaseStringBuilderRepr): lowleveltype = lltype.Ptr(STRINGBUILDER) Modified: pypy/branch/stringbuilder2/pypy/rpython/test/test_rbuilder.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/test/test_rbuilder.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/test/test_rbuilder.py Mon Jan 25 18:23:13 2010 @@ -1,7 +1,21 @@ from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin +from pypy.rpython.lltypesystem.rbuilder import * +from pypy.rpython.annlowlevel import llstr, hlstr from pypy.rlib.rstring import StringBuilder, UnicodeBuilder + +class TestStringBuilderDirect(object): + def test_simple(self): + sb = StringBuilderRepr.ll_new(3) + StringBuilderRepr.ll_append_char(sb, 'x') + StringBuilderRepr.ll_append(sb, llstr("abc")) + StringBuilderRepr.ll_append_slice(sb, llstr("foobar"), 2, 5) + StringBuilderRepr.ll_append_multiple_char(sb, 'y', 3) + s = StringBuilderRepr.ll_build(sb) + assert hlstr(s) == "xabcobayyy" + + class BaseTestStringBuilder(BaseRtypingTest): def test_simple(self): def func(): @@ -37,7 +51,6 @@ assert res == 'aabcabcdefbuuuu' assert isinstance(res, unicode) - class TestLLtype(BaseTestStringBuilder, LLRtypeMixin): pass From arigo at codespeak.net Mon Jan 25 18:36:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 18:36:55 +0100 (CET) Subject: [pypy-svn] r70844 - pypy/branch/lazy-operr-format/pypy/objspace/std Message-ID: <20100125173655.65E351680F6@codespeak.net> Author: arigo Date: Mon Jan 25 18:36:54 2010 New Revision: 70844 Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/listobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/ropeobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/ropeunicodeobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/stringobject.py pypy/branch/lazy-operr-format/pypy/objspace/std/unicodeobject.py Log: Add a missing import here and there. Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/listobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/listobject.py Mon Jan 25 18:36:54 2010 @@ -1,5 +1,6 @@ from pypy.objspace.std.objspace import register_all, W_Object from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.listtype import get_list_index Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/ropeobject.py Mon Jan 25 18:36:54 2010 @@ -1,5 +1,6 @@ from pypy.objspace.std.objspace import register_all, W_Object from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.rlib.objectmodel import we_are_translated Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/ropeunicodeobject.py Mon Jan 25 18:36:54 2010 @@ -1,5 +1,6 @@ from pypy.objspace.std.objspace import register_all, W_Object from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.objspace.std.stringobject import W_StringObject Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/stringobject.py Mon Jan 25 18:36:54 2010 @@ -1,5 +1,6 @@ from pypy.objspace.std.objspace import register_all, W_Object from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.rlib.rarithmetic import ovfcheck Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/unicodeobject.py Mon Jan 25 18:36:54 2010 @@ -1,5 +1,6 @@ from pypy.objspace.std.objspace import register_all, W_Object from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter import gateway from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.stringobject import W_StringObject, make_rsplit_with_delim From arigo at codespeak.net Mon Jan 25 18:45:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 18:45:11 +0100 (CET) Subject: [pypy-svn] r70845 - pypy/branch/lazy-operr-format/pypy/interpreter Message-ID: <20100125174511.C9C111680F6@codespeak.net> Author: arigo Date: Mon Jan 25 18:45:11 2010 New Revision: 70845 Modified: pypy/branch/lazy-operr-format/pypy/interpreter/error.py Log: Improve the non-RPython str of OperationErrors. Modified: pypy/branch/lazy-operr-format/pypy/interpreter/error.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/interpreter/error.py (original) +++ pypy/branch/lazy-operr-format/pypy/interpreter/error.py Mon Jan 25 18:45:11 2010 @@ -51,7 +51,10 @@ def __str__(self): "NOT_RPYTHON: Convenience for tracebacks." - return '[%s: %s]' % (self.w_type, self._w_value) + s = self._w_value + if self.__class__ is not OperationError and s is None: + s = self._compute_value() + return '[%s: %s]' % (self.w_type, s) def errorstr(self, space): "The exception class and value, as a string." From arigo at codespeak.net Mon Jan 25 18:51:18 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 18:51:18 +0100 (CET) Subject: [pypy-svn] r70846 - in pypy/branch/lazy-operr-format/pypy/objspace: . test Message-ID: <20100125175118.890361680F4@codespeak.net> Author: arigo Date: Mon Jan 25 18:51:17 2010 New Revision: 70846 Modified: pypy/branch/lazy-operr-format/pypy/objspace/descroperation.py pypy/branch/lazy-operr-format/pypy/objspace/test/test_descroperation.py Log: Test and fix. Modified: pypy/branch/lazy-operr-format/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/descroperation.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/descroperation.py Mon Jan 25 18:51:17 2010 @@ -574,7 +574,8 @@ def _make_binop_impl(symbol, specialnames): left, right = specialnames - errormsg = "unsupported operand type(s) for %s: '%%s' and '%%s'" % symbol + errormsg = "unsupported operand type(s) for %s: '%%s' and '%%s'" % ( + symbol.replace('%', '%%'),) def binop_impl(space, w_obj1, w_obj2): w_typ1 = space.type(w_obj1) Modified: pypy/branch/lazy-operr-format/pypy/objspace/test/test_descroperation.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/test/test_descroperation.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/test/test_descroperation.py Mon Jan 25 18:51:17 2010 @@ -371,5 +371,14 @@ A() < B() assert l == [B, A, A, B] + def test_mod_failure(self): + try: + [] % 3 + except TypeError, e: + assert '%' in str(e) + else: + assert False, "did not raise" + + class AppTestWithBuiltinShortcut(AppTest_Descroperation): OPTIONS = {'objspace.std.builtinshortcut': True} From arigo at codespeak.net Mon Jan 25 18:52:49 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 18:52:49 +0100 (CET) Subject: [pypy-svn] r70847 - pypy/branch/stringbuilder2/pypy/rpython Message-ID: <20100125175249.777461680F8@codespeak.net> Author: arigo Date: Mon Jan 25 18:52:49 2010 New Revision: 70847 Modified: pypy/branch/stringbuilder2/pypy/rpython/llinterp.py Log: (fijal) Kill these operations from there as well. Modified: pypy/branch/stringbuilder2/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/llinterp.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/llinterp.py Mon Jan 25 18:52:49 2010 @@ -748,15 +748,6 @@ zero = flags.get('zero', False) return self.heap.malloc_nonmovable(TYPE, size, zero=zero) - def op_malloc_resizable_buffer(self, obj, flags, size): - return self.heap.malloc_resizable_buffer(obj, size) - - def op_resize_buffer(self, obj, old_size, new_size): - return self.heap.resize_buffer(obj, old_size, new_size) - - def op_finish_building_buffer(self, obj, oldsize, size): - return self.heap.finish_building_buffer(obj, oldsize, size) - def op_free(self, obj, flavor): assert isinstance(flavor, str) if flavor == 'raw' and self.llinterpreter.malloc_check: From arigo at codespeak.net Mon Jan 25 19:07:25 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 19:07:25 +0100 (CET) Subject: [pypy-svn] r70848 - pypy/branch/lazy-operr-format/pypy/objspace/std Message-ID: <20100125180725.771641680C1@codespeak.net> Author: arigo Date: Mon Jan 25 19:07:25 2010 New Revision: 70848 Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/multimethod.py Log: Add a get_w_value() method there too. Avoids the trouble of finding where we replaced 'e.w_value' with 'e.get_w_value()' but should not have :-) Modified: pypy/branch/lazy-operr-format/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/branch/lazy-operr-format/pypy/objspace/std/multimethod.py (original) +++ pypy/branch/lazy-operr-format/pypy/objspace/std/multimethod.py Mon Jan 25 19:07:25 2010 @@ -29,6 +29,10 @@ self.w_type = w_type self.w_value = w_value + def get_w_value(self, space): + # convenience: same semantics as with OperationError + return self.w_value + def __str__(self): return '' % (self.w_type, self.w_value) From arigo at codespeak.net Mon Jan 25 19:08:46 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 19:08:46 +0100 (CET) Subject: [pypy-svn] r70849 - in pypy/branch/stringbuilder2/pypy/rpython: . lltypesystem memory memory/test Message-ID: <20100125180846.A91451680C1@codespeak.net> Author: arigo Date: Mon Jan 25 19:08:46 2010 New Revision: 70849 Modified: pypy/branch/stringbuilder2/pypy/rpython/llinterp.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llheap.py pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Log: Support 'shrink_array' in the llinterp and in gcwrapper (not linked to the real gc yet). Modified: pypy/branch/stringbuilder2/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/llinterp.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/llinterp.py Mon Jan 25 19:08:46 2010 @@ -754,6 +754,9 @@ self.llinterpreter.remember_free(obj) self.heap.free(obj, flavor=flavor) + def op_shrink_array(self, obj, smallersize): + return self.heap.shrink_array(obj, smallersize) + def op_zero_gc_pointers_inside(self, obj): raise NotImplementedError("zero_gc_pointers_inside") Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llheap.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llheap.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llheap.py Mon Jan 25 19:08:46 2010 @@ -20,20 +20,9 @@ malloc_nonmovable = malloc -def malloc_resizable_buffer(TP, size): - return malloc(TP, size) +def shrink_array(p, smallersize): + return False -def resize_buffer(buf, old_size, new_size): - ll_str = malloc(typeOf(buf).TO, new_size) - for i in range(old_size): - ll_str.chars[i] = buf.chars[i] - return ll_str - -def finish_building_buffer(buf, final_size): - ll_str = malloc(typeOf(buf).TO, final_size) - for i in range(final_size): - ll_str.chars[i] = buf.chars[i] - return ll_str def thread_prepare(): pass Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py Mon Jan 25 19:08:46 2010 @@ -58,33 +58,8 @@ gctypelayout.zero_gc_pointers(result) return result - def malloc_resizable_buffer(self, TYPE, n): - typeid = self.get_type_id(TYPE) - addr = self.gc.malloc(typeid, n) - result = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(TYPE)) - if not self.gc.malloc_zero_filled: - gctypelayout.zero_gc_pointers(result) - return result - - def resize_buffer(self, obj, oldlength, newlength): - T = lltype.typeOf(obj).TO - ARRAY = getattr(T, T._arrayfld) - addr = llmemory.cast_ptr_to_adr(obj) - newaddr = self.gc.malloc(self.gc.get_type_id(addr), newlength, True) - addr = llmemory.cast_ptr_to_adr(obj) - itemsofs = (llmemory.FieldOffset(T, T._arrayfld) + - llmemory.itemoffsetof(ARRAY, 0)) - itemsize = llmemory.sizeof(ARRAY.OF) - tocopy = min(newlength, oldlength) - llmemory.raw_memcopy(addr + itemsofs, newaddr + itemsofs, - tocopy * itemsize) - return llmemory.cast_adr_to_ptr(newaddr, lltype.Ptr(T)) - - def finish_building_buffer(self, obj, oldlength, newlength): - if hasattr(self.gc, 'realloc_shrink'): - xxx - else: - return self.resize_buffer(obj, oldlength, newlength) + def shrink_array(self, p, smallersize): + return False def free(self, TYPE, flavor='gc'): assert flavor != 'gc' Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Mon Jan 25 19:08:46 2010 @@ -468,18 +468,22 @@ assert self.interpret(func, []) == int(self.GC_CANNOT_MALLOC_NONMOVABLE) - def test_resizable_buffer(self): + def test_shrink_array(self): from pypy.rpython.lltypesystem.rstr import STR - from pypy.rpython.annlowlevel import hlstr def f(): - ptr = rgc.resizable_buffer_of_shape(STR, 1) - ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 4) - ptr.chars[1] = 'b' - return len(hlstr(rgc.finish_building_buffer(ptr, 2))) + ptr = lltype.malloc(STR, 3) + ptr.hash = 0x62 + ptr.chars[0] = 'A' + ptr.chars[1] = 'B' + ptr.chars[2] = 'C' + ptr = rgc.ll_shrink_array(ptr, 2) + return ( ord(ptr.chars[0]) + + (ord(ptr.chars[1]) << 8) + + (len(ptr.chars) << 16) + + (ptr.hash << 24)) - assert self.interpret(f, []) == 2 + assert self.interpret(f, []) == 0x62024241 def test_tagged_simple(self): from pypy.rlib.objectmodel import UnboxedValue From arigo at codespeak.net Mon Jan 25 19:21:00 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 19:21:00 +0100 (CET) Subject: [pypy-svn] r70850 - in pypy/branch/stringbuilder2/pypy/rpython: lltypesystem memory/test Message-ID: <20100125182100.3463D1680F8@codespeak.net> Author: arigo Date: Mon Jan 25 19:20:59 2010 New Revision: 70850 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_transformed_gc.py Log: Test and fix for test_transformed_gc. Still not actually linked to the GC. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py Mon Jan 25 19:20:59 2010 @@ -102,6 +102,7 @@ @staticmethod def ll_build(ll_builder): final_size = ll_builder.used + assert final_size >= 0 return rgc.ll_shrink_array(ll_builder.buf, final_size) class StringBuilderRepr(BaseStringBuilderRepr): Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_transformed_gc.py Mon Jan 25 19:20:59 2010 @@ -631,22 +631,25 @@ run = self.runner("malloc_nonmovable_fixsize") assert run([]) == int(self.GC_CANNOT_MALLOC_NONMOVABLE) - def define_resizable_buffer(cls): + def define_shrink_array(cls): from pypy.rpython.lltypesystem.rstr import STR - from pypy.rpython.annlowlevel import hlstr def f(): - ptr = rgc.resizable_buffer_of_shape(STR, 2) - ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 200) - ptr.chars[1] = 'b' - return hlstr(rgc.finish_building_buffer(ptr, 2)) == "ab" - + ptr = lltype.malloc(STR, 3) + ptr.hash = 0x62 + ptr.chars[0] = 'A' + ptr.chars[1] = 'B' + ptr.chars[2] = 'C' + ptr = rgc.ll_shrink_array(ptr, 2) + return ( ord(ptr.chars[0]) + + (ord(ptr.chars[1]) << 8) + + (len(ptr.chars) << 16) + + (ptr.hash << 24)) return f - def test_resizable_buffer(self): - run = self.runner("resizable_buffer") - assert run([]) == 1 + def test_shrink_array(self): + run = self.runner("shrink_array") + assert run([]) == 0x62024241 def define_string_builder_over_allocation(cls): import gc From arigo at codespeak.net Mon Jan 25 19:54:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 19:54:09 +0100 (CET) Subject: [pypy-svn] r70851 - in pypy/branch/stringbuilder2/pypy/rpython: lltypesystem memory memory/gc memory/gc/test memory/gctransform Message-ID: <20100125185409.17FBA168101@codespeak.net> Author: arigo Date: Mon Jan 25 19:54:08 2010 New Revision: 70851 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lltype.py pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py pypy/branch/stringbuilder2/pypy/rpython/memory/gc/test/test_direct.py pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py Log: Shrink the arrays in-place, if they are living in the main gc space. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lltype.py Mon Jan 25 19:54:08 2010 @@ -1528,6 +1528,9 @@ def getlength(self): return len(self.items) + def shrinklength(self, newlength): + del self.items[newlength:] + def getbounds(self): stop = len(self.items) return 0, stop @@ -1658,7 +1661,9 @@ def setitem(self, index, value): assert index == 0 if value != self.array.getlength(): - raise Exception("can't change the length of an array") + if value > self.array.getlength(): + raise Exception("can't grow an array in-place") + self.array.shrinklength(value) def _makeptr(array, solid=False): try: Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py Mon Jan 25 19:54:08 2010 @@ -210,10 +210,6 @@ raise NotImplementedError("Not supported") return llmemory.cast_ptr_to_adr(gcref) - #def realloc(self, ...): - # here we can write a bit more sophisticated realloc, that cares - # about rawmalloced objects - def can_move(self, addr): tid = self.header(addr).tid return not (tid & GCFLAG_EXTERNAL) Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py Mon Jan 25 19:54:08 2010 @@ -119,6 +119,15 @@ self.free = result + llarena.round_up_for_allocation(totalsize) return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF) + def shrink_array(self, addr, smallersize): + if self._is_in_the_space(addr): + typeid = self.get_type_id(addr) + offset_to_length = self.varsize_offset_to_length(typeid) + (addr + offset_to_length).signed[0] = smallersize + return True + else: + return False + def obtain_free_space(self, needed): # a bit of tweaking to maximize the performance and minimize the # amount of code in an inlined version of malloc_fixedsize_clear() @@ -572,6 +581,9 @@ def _is_external(self, obj): return (self.header(obj).tid & GCFLAG_EXTERNAL) != 0 + def _is_in_the_space(self, obj): + return self.tospace <= obj < self.free + def debug_check_object(self, obj): """Check the invariants about 'obj' that should be true between collections.""" Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/test/test_direct.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/test/test_direct.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/test/test_direct.py Mon Jan 25 19:54:08 2010 @@ -268,6 +268,22 @@ class TestSemiSpaceGC(DirectGCTest): from pypy.rpython.memory.gc.semispace import SemiSpaceGC as GCClass + def test_shrink_array(self): + S1 = lltype.GcStruct('S1', ('h', lltype.Char), + ('v', lltype.Array(lltype.Char))) + p1 = self.malloc(S1, 2) + p1.h = '?' + for i in range(2): + p1.v[i] = chr(50 + i) + addr = llmemory.cast_ptr_to_adr(p1) + ok = self.gc.shrink_array(addr, 1) + assert ok + assert p1.h == '?' + assert len(p1.v) == 1 + for i in range(1): + assert p1.v[i] == chr(50 + i) + + class TestGenerationGC(TestSemiSpaceGC): from pypy.rpython.memory.gc.generation import GenerationGC as GCClass @@ -358,7 +374,7 @@ gc.collect(9) assert calls == [('semispace_collect', True)] - calls = [] + calls = [] class TestMarkCompactGC(DirectGCTest): Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py Mon Jan 25 19:54:08 2010 @@ -563,80 +563,6 @@ def gct_malloc_nonmovable_varsize(self, *args, **kwds): return self.gct_malloc_varsize(*args, **kwds) - def gct_malloc_resizable_buffer(self, hop): - flags = hop.spaceop.args[1].value - flags['varsize'] = True - flags['nonmovable'] = True - flags['resizable'] = True - flavor = flags['flavor'] - assert flavor != 'cpy', "cannot malloc CPython objects directly" - meth = getattr(self, 'gct_fv_%s_malloc_varsize' % flavor, None) - assert meth, "%s has no support for malloc_varsize with flavor %r" % (self, flavor) - return self.varsize_malloc_helper(hop, flags, meth, []) - - def gct_resize_buffer(self, hop): - op = hop.spaceop - # if we want to support a general realloc, support goes here - self._malloc_and_copy(hop, op.args[1], op.args[2]) - - # def _malloc_and_copy(self, hop, v_oldsize, v_newsize, grow=True): - # def intconst(c): return rmodel.inputconst(lltype.Signed, c) - # op = hop.spaceop - # flags = {'flavor':'gc', 'varsize': True} - # TYPE = op.args[0].concretetype.TO - # ARRAY = TYPE._flds[TYPE._arrayfld] - # offset_to_length = llmemory.FieldOffset(TYPE, TYPE._arrayfld) + \ - # llmemory.ArrayLengthOffset(ARRAY) - # c_const_size = intconst(llmemory.sizeof(TYPE, 0)) - # c_item_size = intconst(llmemory.sizeof(ARRAY.OF)) - - # c_lengthofs = intconst(offset_to_length) - # c_itemsofs = intconst(llmemory.itemoffsetof(TYPE, 0)) - # v_ptr = op.args[0] - # v_ptr = gen_cast(hop.llops, llmemory.GCREF, v_ptr) - # c_grow = rmodel.inputconst(lltype.Bool, grow) - # v_raw = self.perform_realloc(hop, v_ptr, v_oldsize, v_newsize, - # c_const_size, c_item_size, c_lengthofs, - # c_itemsofs, c_grow) - # hop.cast_result(v_raw) - - def _malloc_and_copy(self, hop, v_lgt): - op = hop.spaceop - meth = self.gct_fv_gc_malloc_varsize - flags = {'flavor':'gc', 'varsize': True, 'keep_current_args': True} - self.varsize_malloc_helper(hop, flags, meth, []) - # fish resvar - v_newbuf = hop.llops[-1].result - v_src = op.args[0] - TYPE = v_src.concretetype.TO - c_fldname = rmodel.inputconst(lltype.Void, TYPE._arrayfld) - v_adrsrc = hop.genop('cast_ptr_to_adr', [v_src], - resulttype=llmemory.Address) - v_adrnewbuf = hop.genop('cast_ptr_to_adr', [v_newbuf], - resulttype=llmemory.Address) - ofs = (llmemory.offsetof(TYPE, TYPE._arrayfld) + - llmemory.itemoffsetof(getattr(TYPE, TYPE._arrayfld), 0)) - v_ofs = rmodel.inputconst(lltype.Signed, ofs) - v_adrsrc = hop.genop('adr_add', [v_adrsrc, v_ofs], - resulttype=llmemory.Address) - v_adrnewbuf = hop.genop('adr_add', [v_adrnewbuf, v_ofs], - resulttype=llmemory.Address) - size = llmemory.sizeof(getattr(TYPE, TYPE._arrayfld).OF) - c_size = rmodel.inputconst(lltype.Signed, size) - v_lgtsym = hop.genop('int_mul', [c_size, v_lgt], - resulttype=lltype.Signed) - vlist = [v_adrsrc, v_adrnewbuf, v_lgtsym] - hop.genop('raw_memcopy', vlist) - - def gct_finish_building_buffer(self, hop): - xxx - op = hop.spaceop - if self._can_realloc(): - return self._gct_resize_buffer_realloc(hop, op.args[1], - op.args[2], False) - else: - return self._gct_resize_buffer_no_realloc(hop, op.args[1]) - def varsize_malloc_helper(self, hop, flags, meth, extraargs): def intconst(c): return rmodel.inputconst(lltype.Signed, c) op = hop.spaceop @@ -697,3 +623,6 @@ def gct_gc_can_move(self, hop): return hop.cast_result(rmodel.inputconst(lltype.Bool, False)) + + def gct_shrink_array(self, hop): + return hop.cast_result(rmodel.inputconst(lltype.Bool, False)) Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gcwrapper.py Mon Jan 25 19:54:08 2010 @@ -59,6 +59,9 @@ return result def shrink_array(self, p, smallersize): + if hasattr(self.gc, 'shrink_array'): + addr = llmemory.cast_ptr_to_adr(p) + return self.gc.shrink_array(addr, smallersize) return False def free(self, TYPE, flavor='gc'): From arigo at codespeak.net Mon Jan 25 20:01:16 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 20:01:16 +0100 (CET) Subject: [pypy-svn] r70852 - pypy/branch/stringbuilder2/pypy/rpython/memory/test Message-ID: <20100125190116.A260D1680FF@codespeak.net> Author: arigo Date: Mon Jan 25 20:01:15 2010 New Revision: 70852 Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Log: Improve the test: checks that shrink_array() did his job for exactly the correct GC classes. Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Mon Jan 25 20:01:15 2010 @@ -24,6 +24,7 @@ GC_PARAMS = {} GC_CAN_MOVE = False GC_CANNOT_MALLOC_NONMOVABLE = False + GC_CAN_SHRINK_ARRAY = False def setup_class(cls): cls._saved_logstate = py.log._getstate() @@ -470,6 +471,7 @@ def test_shrink_array(self): from pypy.rpython.lltypesystem.rstr import STR + GC_CAN_SHRINK_ARRAY = self.GC_CAN_SHRINK_ARRAY def f(): ptr = lltype.malloc(STR, 3) @@ -477,11 +479,12 @@ ptr.chars[0] = 'A' ptr.chars[1] = 'B' ptr.chars[2] = 'C' - ptr = rgc.ll_shrink_array(ptr, 2) - return ( ord(ptr.chars[0]) + - (ord(ptr.chars[1]) << 8) + - (len(ptr.chars) << 16) + - (ptr.hash << 24)) + ptr2 = rgc.ll_shrink_array(ptr, 2) + assert (ptr == ptr2) == GC_CAN_SHRINK_ARRAY + return ( ord(ptr2.chars[0]) + + (ord(ptr2.chars[1]) << 8) + + (len(ptr2.chars) << 16) + + (ptr2.hash << 24)) assert self.interpret(f, []) == 0x62024241 @@ -617,6 +620,7 @@ from pypy.rpython.memory.gc.semispace import SemiSpaceGC as GCClass GC_CAN_MOVE = True GC_CANNOT_MALLOC_NONMOVABLE = True + GC_CAN_SHRINK_ARRAY = True class TestGrowingSemiSpaceGC(TestSemiSpaceGC): GC_PARAMS = {'space_size': 64} From arigo at codespeak.net Mon Jan 25 20:15:00 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 20:15:00 +0100 (CET) Subject: [pypy-svn] r70853 - pypy/branch/stringbuilder2/pypy/rpython/memory/gc Message-ID: <20100125191500.031661680FB@codespeak.net> Author: arigo Date: Mon Jan 25 20:15:00 2010 New Revision: 70853 Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py Log: Fix (shown by test_transformed_gc). Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/hybrid.py Mon Jan 25 20:15:00 2010 @@ -452,6 +452,7 @@ self.last_generation_root_objects = newgen3roots else: ll_assert(False, "bogus 'generation'") + return surviving_objects = self.AddressStack() # Help the flow space From arigo at codespeak.net Mon Jan 25 20:15:24 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 20:15:24 +0100 (CET) Subject: [pypy-svn] r70854 - in pypy/branch/stringbuilder2/pypy/rpython/memory: gctransform test Message-ID: <20100125191524.B47411680FB@codespeak.net> Author: arigo Date: Mon Jan 25 20:15:24 2010 New Revision: 70854 Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_transformed_gc.py Log: Finish the integration of shrink_array. Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py Mon Jan 25 20:15:24 2010 @@ -276,6 +276,14 @@ [s_gc, annmodel.SomeAddress()], annmodel.SomeBool()) + if hasattr(GCClass, 'shrink_array'): + self.shrink_array_ptr = getfn( + GCClass.shrink_array.im_func, + [s_gc, annmodel.SomeAddress(), + annmodel.SomeInteger(nonneg=True)], annmodel.s_Bool) + else: + self.shrink_array_ptr = None + if hasattr(GCClass, 'assume_young_pointers'): # xxx should really be a noop for gcs without generations self.assume_young_pointers_ptr = getfn( @@ -358,16 +366,16 @@ else: self.malloc_varsize_nonmovable_ptr = None - if getattr(GCClass, 'malloc_varsize_resizable', False): - malloc_resizable = func_with_new_name( - GCClass.malloc_varsize_resizable.im_func, - "malloc_varsize_resizable") - self.malloc_varsize_resizable_ptr = getfn( - malloc_resizable, - [s_gc, s_typeid16, - annmodel.SomeInteger(nonneg=True)], s_gcref) - else: - self.malloc_varsize_resizable_ptr = None +## if getattr(GCClass, 'malloc_varsize_resizable', False): +## malloc_resizable = func_with_new_name( +## GCClass.malloc_varsize_resizable.im_func, +## "malloc_varsize_resizable") +## self.malloc_varsize_resizable_ptr = getfn( +## malloc_resizable, +## [s_gc, s_typeid16, +## annmodel.SomeInteger(nonneg=True)], s_gcref) +## else: +## self.malloc_varsize_resizable_ptr = None if getattr(GCClass, 'realloc', False): self.realloc_ptr = getfn( @@ -627,11 +635,11 @@ info_varsize.ofstolength) c_varitemsize = rmodel.inputconst(lltype.Signed, info_varsize.varitemsize) - if flags.get('resizable') and self.malloc_varsize_resizable_ptr: - assert c_can_collect.value - malloc_ptr = self.malloc_varsize_resizable_ptr - args = [self.c_const_gc, c_type_id, v_length] - elif flags.get('nonmovable') and self.malloc_varsize_nonmovable_ptr: +## if flags.get('resizable') and self.malloc_varsize_resizable_ptr: +## assert c_can_collect.value +## malloc_ptr = self.malloc_varsize_resizable_ptr +## args = [self.c_const_gc, c_type_id, v_length] + if flags.get('nonmovable') and self.malloc_varsize_nonmovable_ptr: # we don't have tests for such cases, let's fail # explicitely assert c_can_collect.value @@ -673,6 +681,17 @@ hop.genop("direct_call", [self.can_move_ptr, self.c_const_gc, v_addr], resultvar=op.result) + def gct_shrink_array(self, hop): + if self.shrink_array_ptr is None: + return GCTransformer.gct_shrink_array(self, hop) + op = hop.spaceop + v_addr = hop.genop('cast_ptr_to_adr', + [op.args[0]], resulttype=llmemory.Address) + v_length = op.args[1] + hop.genop("direct_call", [self.shrink_array_ptr, self.c_const_gc, + v_addr, v_length], + resultvar=op.result) + def gct_gc_assume_young_pointers(self, hop): op = hop.spaceop v_addr = op.args[0] Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_transformed_gc.py Mon Jan 25 20:15:24 2010 @@ -162,6 +162,7 @@ return run class GenericGCTests(GCTest): + GC_CAN_SHRINK_ARRAY = False def heap_usage(self, statistics): try: @@ -637,19 +638,24 @@ def f(): ptr = lltype.malloc(STR, 3) ptr.hash = 0x62 - ptr.chars[0] = 'A' + ptr.chars[0] = '0' ptr.chars[1] = 'B' ptr.chars[2] = 'C' - ptr = rgc.ll_shrink_array(ptr, 2) - return ( ord(ptr.chars[0]) + - (ord(ptr.chars[1]) << 8) + - (len(ptr.chars) << 16) + - (ptr.hash << 24)) + ptr2 = rgc.ll_shrink_array(ptr, 2) + return ((ptr == ptr2) + + ord(ptr2.chars[0]) + + (ord(ptr2.chars[1]) << 8) + + (len(ptr2.chars) << 16) + + (ptr2.hash << 24)) return f def test_shrink_array(self): run = self.runner("shrink_array") - assert run([]) == 0x62024241 + if self.GC_CAN_SHRINK_ARRAY: + expected = 0x62024231 + else: + expected = 0x62024230 + assert run([]) == expected def define_string_builder_over_allocation(cls): import gc @@ -1120,6 +1126,7 @@ class TestSemiSpaceGC(GenericMovingGCTests): gcname = "semispace" + GC_CAN_SHRINK_ARRAY = True class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): @@ -1141,6 +1148,7 @@ class TestGenerationGC(GenericMovingGCTests): gcname = "generation" + GC_CAN_SHRINK_ARRAY = True class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): From arigo at codespeak.net Mon Jan 25 22:25:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 22:25:27 +0100 (CET) Subject: [pypy-svn] r70855 - pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/output Message-ID: <20100125212527.1565A168101@codespeak.net> Author: arigo Date: Mon Jan 25 22:25:26 2010 New Revision: 70855 Modified: pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/output/test_extcall Log: Update the error message. Modified: pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/output/test_extcall ============================================================================== --- pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/output/test_extcall (original) +++ pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/output/test_extcall Mon Jan 25 22:25:26 2010 @@ -25,9 +25,9 @@ got multiple values for keyword argument 'b' keywords must be strings h() got an unexpected keyword argument 'e' -iteration over non-sequence -iteration over non-sequence -iteration over non-sequence +'function' object is not iterable +'function' object is not iterable +'function' object is not iterable argument after ** must be a dictionary argument after ** must be a dictionary argument after ** must be a dictionary From arigo at codespeak.net Mon Jan 25 22:29:39 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 22:29:39 +0100 (CET) Subject: [pypy-svn] r70856 - pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test Message-ID: <20100125212939.1E4A7168101@codespeak.net> Author: arigo Date: Mon Jan 25 22:29:38 2010 New Revision: 70856 Modified: pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/test_genexps.py Log: Fix the error message. Modified: pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/test_genexps.py ============================================================================== --- pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/test_genexps.py (original) +++ pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/test_genexps.py Mon Jan 25 22:29:38 2010 @@ -109,7 +109,7 @@ Traceback (most recent call last): File "", line 1, in -toplevel- (i for i in 6) - TypeError: iteration over non-sequence + TypeError: 'int' object is not iterable Verify late binding for the outermost if-expression From arigo at codespeak.net Mon Jan 25 22:30:42 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 25 Jan 2010 22:30:42 +0100 (CET) Subject: [pypy-svn] r70857 - pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test Message-ID: <20100125213042.5D8751680F8@codespeak.net> Author: arigo Date: Mon Jan 25 22:30:41 2010 New Revision: 70857 Modified: pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/test_unpack.py Log: Fix the error message, 3rd test. Modified: pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/test_unpack.py ============================================================================== --- pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/test_unpack.py (original) +++ pypy/branch/lazy-operr-format/lib-python/modified-2.5.2/test/test_unpack.py Mon Jan 25 22:30:41 2010 @@ -55,7 +55,7 @@ >>> a, b, c = 7 Traceback (most recent call last): ... - TypeError: iteration over non-sequence + TypeError: 'int' object is not iterable Unpacking tuple of wrong size From fijal at codespeak.net Tue Jan 26 06:31:28 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 26 Jan 2010 06:31:28 +0100 (CET) Subject: [pypy-svn] r70858 - in pypy/branch/stringbuilder2/pypy/rpython/lltypesystem: . test Message-ID: <20100126053128.AF41B49843E@codespeak.net> Author: fijal Date: Tue Jan 26 06:31:27 2010 New Revision: 70858 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py Log: Add object shrinking capability to llarena Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py Tue Jan 26 06:31:27 2010 @@ -103,6 +103,11 @@ Arena.object_arena_location[container] = self, offset Arena.old_object_arena_location[container] = self, offset + def shrink_obj(self, offset, newsize): + assert offset in self.objectptrs + assert newsize < self.objectsizes[offset] + self.objectsizes[offset] = newsize + class fakearenaaddress(llmemory.fakeaddress): def __init__(self, arena, offset): @@ -306,6 +311,13 @@ % (addr.offset,)) addr.arena.allocate_object(addr.offset, size) +def arena_shrink_obj(addr, newsize): + """ Mark object as shorter than it was + """ + addr = _getfakearenaaddress(addr) + bytes = llmemory.raw_malloc_usage(newsize) + addr.arena.shrink_obj(addr.offset, bytes) + def round_up_for_allocation(size, minsize=0): """Round up the size in order to preserve alignment of objects following an object. For arenas containing heterogenous objects. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py Tue Jan 26 06:31:27 2010 @@ -5,6 +5,7 @@ from pypy.rpython.lltypesystem.llarena import arena_reserve, arena_free from pypy.rpython.lltypesystem.llarena import round_up_for_allocation from pypy.rpython.lltypesystem.llarena import ArenaError, arena_new_view +from pypy.rpython.lltypesystem.llarena import arena_shrink_obj def test_arena(): S = lltype.Struct('S', ('x',lltype.Signed)) @@ -268,3 +269,13 @@ fn = compile(test_look_inside_object, []) res = fn() assert res == 42 + +def test_shrink_obj(): + S = lltype.Struct('S', ('x', lltype.Signed), + ('a', lltype.Array(lltype.Signed))) + myarenasize = 200 + a = arena_malloc(myarenasize, False) + arena_reserve(a, llmemory.sizeof(S, 10)) + arena_shrink_obj(a, llmemory.sizeof(S, 5)) + arena_reset(a + llmemory.sizeof(S, 5), llmemory.sizeof(S, 10), True) + arena_reserve(a + llmemory.sizeof(S, 5), llmemory.sizeof(S, 10)) From fijal at codespeak.net Tue Jan 26 06:36:59 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 26 Jan 2010 06:36:59 +0100 (CET) Subject: [pypy-svn] r70859 - in pypy/branch/stringbuilder2/pypy/rpython: lltypesystem test Message-ID: <20100126053659.AC81849843E@codespeak.net> Author: fijal Date: Tue Jan 26 06:36:59 2010 New Revision: 70859 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py pypy/branch/stringbuilder2/pypy/rpython/test/test_rbuilder.py Log: Don't even try to shrink in case we have allocated exactly enough. Also fix comparison so in case we allocate exactly the correct amount, we're happy Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py Tue Jan 26 06:36:59 2010 @@ -67,7 +67,7 @@ used = ll_builder.used lgt = len(ll_str.chars) needed = lgt + used - if needed >= ll_builder.allocated: + if needed > ll_builder.allocated: ll_builder.grow(ll_builder, lgt) ll_str.copy_contents(ll_str, ll_builder.buf, 0, used, lgt) ll_builder.used = needed @@ -83,7 +83,7 @@ def ll_append_slice(ll_builder, ll_str, start, end): needed = end - start used = ll_builder.used - if needed + used >= ll_builder.allocated: + if needed + used > ll_builder.allocated: ll_builder.grow(ll_builder, needed) assert needed >= 0 ll_str.copy_contents(ll_str, ll_builder.buf, start, used, needed) @@ -92,7 +92,7 @@ @staticmethod def ll_append_multiple_char(ll_builder, char, times): used = ll_builder.used - if times + used >= ll_builder.allocated: + if times + used > ll_builder.allocated: ll_builder.grow(ll_builder, times) for i in range(times): ll_builder.buf.chars[used] = char @@ -103,6 +103,8 @@ def ll_build(ll_builder): final_size = ll_builder.used assert final_size >= 0 + if final_size == ll_builder.allocated: + return ll_builder.buf return rgc.ll_shrink_array(ll_builder.buf, final_size) class StringBuilderRepr(BaseStringBuilderRepr): Modified: pypy/branch/stringbuilder2/pypy/rpython/test/test_rbuilder.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/test/test_rbuilder.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/test/test_rbuilder.py Tue Jan 26 06:36:59 2010 @@ -15,6 +15,10 @@ s = StringBuilderRepr.ll_build(sb) assert hlstr(s) == "xabcobayyy" + def test_nooveralloc(self): + sb = StringBuilderRepr.ll_new(3) + StringBuilderRepr.ll_append(sb, llstr("abc")) + assert StringBuilderRepr.ll_build(sb) == sb.buf class BaseTestStringBuilder(BaseRtypingTest): def test_simple(self): From dan at codespeak.net Tue Jan 26 08:37:01 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Tue, 26 Jan 2010 08:37:01 +0100 (CET) Subject: [pypy-svn] r70860 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test Message-ID: <20100126073701.CAAF81680B8@codespeak.net> Author: dan Date: Tue Jan 26 08:37:01 2010 New Revision: 70860 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: Added tests, and some Meh implementation code... Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Tue Jan 26 08:37:01 2010 @@ -59,7 +59,7 @@ self.dtype = dtype make_sure_not_resized(self.storage) - def create_math_operation(f): + def create_client_math_operation(f): def scalar_operation(result, source, w_x): space = result.space x = coerce(space, w_x) @@ -80,18 +80,29 @@ self.storage[i] = f(source.storage[i], self.coerce(w_x)) #TODO: probably shouldn't coerce i += 1 return result + return scalar_operation, fixedview_operation + + client_mul_scalar, client_mul_fixedview = create_client_math_operation(mul) + client_div_scalar, client_div_fixedview = create_client_math_operation(div) + client_add_scalar, client_add_fixedview = create_client_math_operation(add) + client_sub_scalar, client_sub_fixedview = create_client_math_operation(sub) + def create_math_operation(f): + scalar_operation_name = '_'.join(['client', f.__name__, 'scalar']) + fixedview_operation_name = '_'.join(['client', f.__name__, 'fixedview']) def math_operation(self, w_x): space = self.space if space.type(w_x) in (space.w_list, space.w_tuple): raise OperationError(space.w_NotImplementedError, - space.wrap("Haven't implemented array * iterable yet!")) + space.wrap("Haven't implemented array %s iterable yet!" % f.__name__)) + result_t = result_mapping(space, (self.dtype, space.w_None)) else: result_t = result_mapping(space, (space.type(w_x), self.dtype)) - result = sdresult(space, result_t)(space, self.len(), self.dtype) - scalar_operation(result, self, w_x) - w_result = space.wrap(result) + result = sdresult(space, result_t)(space, self.len(), self.dtype) + getattr(result, scalar_operation_name)(self, w_x) + + w_result = space.wrap(result) return w_result math_operation.unwrap_spec = ['self', W_Root] return math_operation Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Tue Jan 26 08:37:01 2010 @@ -1,7 +1,7 @@ from pypy.conftest import gettestobjspace -class AppTestNumpy(object): +class AppTestSDArray(object): def setup_class(cls): cls.space = gettestobjspace(usemodules=('micronumpy',)) cls.w_compare = cls.space.appexec([], @@ -12,36 +12,65 @@ assert type(x) == type(y) return True return compare""") - cls.w_array_type_test = cls.space.appexec([cls.w_compare], - """(compare): - def array_type_test(data_type): - from numpy import array + cls.w_length = cls.space.appexec([], """(): return 16""") + cls.w_value = cls.space.appexec([], """(): return 3.0""") + + def test_type_array(self): + compare = self.compare + from numpy import array + for data_type in (int, float): data = [data_type(x) for x in xrange(4)] ar = array(data) - assert compare(ar, data) - return array_type_test - """) - cls.w_array_scalar_op_test = cls.space.appexec([cls.w_compare], - """(compare): - def array_scalar_op_test(self, data_type, f, value, length): - compare = self.compare - from numpy import array - data = [data_type(x) for x in range(length)] - ar = array(data) - assert compare(f(ar, value), [f(x, value) for x in data]) - return array_scalar_op_test - """) - - def test_int_array(self): self.array_type_test(int) - def test_float_array(self): self.array_type_test(float) def test_sdarray_operators(self): from operator import mul, div, add, sub - self.array_scalar_op_test(self, float, mul, 2.0, 16) - self.array_scalar_op_test(self, float, div, 2.0, 16) - self.array_scalar_op_test(self, float, add, 2.0, 16) - self.array_scalar_op_test(self, float, sub, 2.0, 16) + #FIXME: overkill... + for data_type in (int, float): + for operator in (mul, div, add, sub): + for value in xrange(1, 16): + compare = self.compare + from numpy import array + data = [data_type(x) for x in range(self.length)] + ar = array(data) + assert compare(operator(ar, value), [operator(x, value) for x in data]) + + def test_operator_result_types(self): + from operator import mul, div, add, sub + from numpy import array + types = { + (int, int): int, + (int, float): float, + (float, int): float, + (float, float): float + } + + for operand_types, result_type in types.iteritems(): + for operator in (mul, div, add, sub): + a_type, b_type = operand_types + a = array(xrange(1, self.length + 1), dtype=a_type) + b = array(xrange(1, self.length + 1), dtype=b_type) + + c = operator(a, b) + assert c.dtype == result_type + + d = operator(b, a) + assert d.dtype == result_type + + e = operator(a, b_type(self.value)) + assert e.dtype == result_type + + f = operator(a_type(self.value), b) + assert f.dtype == result_type + + def test_iter(self): + from numpy import array + for iterable_type in (list, tuple): + for data_type in (int, float): + data = iterable_type([data_type(x) for x in xrange(self.length)]) + ar = array(data, dtype=data_type) + ar_data = iterable_type([x for x in ar]) + assert ar_data == data def test_iterable_construction(self): compare = self.compare @@ -52,8 +81,9 @@ def test_zeroes(self): from numpy import zeros - ar = zeros(3, dtype=int) - assert ar[0] == 0 + for data_type in (int, float): + ar = zeros(3, dtype=int) + assert ar[0] == data_type(0.0) def test_setitem_getitem(self): from numpy import zeros From arigo at codespeak.net Tue Jan 26 09:15:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 09:15:55 +0100 (CET) Subject: [pypy-svn] r70861 - pypy/branch/stringbuilder2/pypy/rlib Message-ID: <20100126081555.AC0C61680B8@codespeak.net> Author: arigo Date: Tue Jan 26 09:15:55 2010 New Revision: 70861 Modified: pypy/branch/stringbuilder2/pypy/rlib/rgc.py Log: Fix for a bug that is hard to test: using raw_memcopy in that way would also overwrite the header of the new object with a copy of the header of the one. This might make a few GC flags wrong. This problem only occurs after translation to C, though. Modified: pypy/branch/stringbuilder2/pypy/rlib/rgc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rlib/rgc.py (original) +++ pypy/branch/stringbuilder2/pypy/rlib/rgc.py Tue Jan 26 09:15:55 2010 @@ -285,19 +285,21 @@ if llop.shrink_array(lltype.Bool, p, smallerlength): return p # done by the GC # XXX we assume for now that the type of p is GcStruct containing a - # variable array, with no further pointers anywhere + # variable array, with no further pointers anywhere, and exactly one + # field in the fixed part -- like STR and UNICODE. TP = lltype.typeOf(p).TO newp = lltype.malloc(TP, smallerlength) - - source_addr = llmemory.cast_ptr_to_adr(p) - dest_addr = llmemory.cast_ptr_to_adr(newp) - staticsize = llmemory.offsetof(TP, TP._arrayfld) - llmemory.raw_memcopy(source_addr, dest_addr, staticsize) + + assert len(TP._names) == 2 + field = getattr(p, TP._names[0]) + setattr(newp, TP._names[0], field) ARRAY = getattr(TP, TP._arrayfld) - source_addr += staticsize + llmemory.itemoffsetof(ARRAY, 0) - dest_addr += staticsize + llmemory.itemoffsetof(ARRAY, 0) + offset = (llmemory.offsetof(TP, TP._arrayfld) + + llmemory.itemoffsetof(ARRAY, 0)) + source_addr = llmemory.cast_ptr_to_adr(p) + offset + dest_addr = llmemory.cast_ptr_to_adr(newp) + offset llmemory.raw_memcopy(source_addr, dest_addr, llmemory.sizeof(ARRAY.OF) * smallerlength) From arigo at codespeak.net Tue Jan 26 09:24:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 09:24:53 +0100 (CET) Subject: [pypy-svn] r70862 - pypy/branch/stringbuilder2/pypy/rlib Message-ID: <20100126082453.753F71680F3@codespeak.net> Author: arigo Date: Tue Jan 26 09:24:52 2010 New Revision: 70862 Modified: pypy/branch/stringbuilder2/pypy/rlib/rgc.py Log: This hint is probably needed. Modified: pypy/branch/stringbuilder2/pypy/rlib/rgc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rlib/rgc.py (original) +++ pypy/branch/stringbuilder2/pypy/rlib/rgc.py Tue Jan 26 09:24:52 2010 @@ -307,6 +307,7 @@ keepalive_until_here(newp) return newp ll_shrink_array._annspecialcase_ = 'specialize:ll' +ll_shrink_array._jit_look_inside_ = False def no_collect(func): From arigo at codespeak.net Tue Jan 26 09:33:45 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 09:33:45 +0100 (CET) Subject: [pypy-svn] r70863 - in pypy/trunk: lib-python/modified-2.5.2/test lib-python/modified-2.5.2/test/output py/plugin pypy/interpreter pypy/interpreter/test pypy/module/__builtin__ pypy/module/_codecs pypy/module/_file pypy/module/_rawffi pypy/module/_socket pypy/module/_stackless pypy/module/bz2 pypy/module/clr pypy/module/imp pypy/module/pypyjit pypy/module/rctime pypy/module/select pypy/module/sys pypy/module/thread pypy/module/zipimport pypy/objspace pypy/objspace/flow pypy/objspace/std pypy/objspace/test pypy/tool pypy/tool/test pypy/translator pypy/translator/goal Message-ID: <20100126083345.40FF71680B8@codespeak.net> Author: arigo Date: Tue Jan 26 09:33:42 2010 New Revision: 70863 Added: pypy/trunk/pypy/interpreter/test/test_error.py - copied unchanged from r70862, pypy/branch/lazy-operr-format/pypy/interpreter/test/test_error.py Modified: pypy/trunk/lib-python/modified-2.5.2/test/output/test_extcall pypy/trunk/lib-python/modified-2.5.2/test/test_genexps.py pypy/trunk/lib-python/modified-2.5.2/test/test_unpack.py pypy/trunk/py/plugin/pytest_terminal.py pypy/trunk/pypy/interpreter/argument.py pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/interpreter/error.py pypy/trunk/pypy/interpreter/executioncontext.py pypy/trunk/pypy/interpreter/function.py pypy/trunk/pypy/interpreter/main.py pypy/trunk/pypy/interpreter/pycompiler.py pypy/trunk/pypy/interpreter/pyframe.py pypy/trunk/pypy/interpreter/pyopcode.py pypy/trunk/pypy/interpreter/test/test_argument.py pypy/trunk/pypy/interpreter/test/test_compiler.py pypy/trunk/pypy/interpreter/typedef.py pypy/trunk/pypy/module/__builtin__/descriptor.py pypy/trunk/pypy/module/__builtin__/interp_classobj.py pypy/trunk/pypy/module/_codecs/interp_codecs.py pypy/trunk/pypy/module/_file/interp_file.py pypy/trunk/pypy/module/_rawffi/interp_rawffi.py pypy/trunk/pypy/module/_rawffi/structure.py pypy/trunk/pypy/module/_socket/interp_func.py pypy/trunk/pypy/module/_stackless/interp_coroutine.py pypy/trunk/pypy/module/_stackless/interp_greenlet.py pypy/trunk/pypy/module/bz2/interp_bz2.py pypy/trunk/pypy/module/clr/interp_clr.py pypy/trunk/pypy/module/imp/importing.py pypy/trunk/pypy/module/imp/interp_imp.py pypy/trunk/pypy/module/pypyjit/interp_jit.py pypy/trunk/pypy/module/rctime/interp_time.py pypy/trunk/pypy/module/select/interp_select.py pypy/trunk/pypy/module/sys/__init__.py pypy/trunk/pypy/module/sys/vm.py pypy/trunk/pypy/module/thread/os_thread.py pypy/trunk/pypy/module/zipimport/interp_zipimport.py pypy/trunk/pypy/objspace/descroperation.py pypy/trunk/pypy/objspace/flow/flowcontext.py pypy/trunk/pypy/objspace/flow/framestate.py pypy/trunk/pypy/objspace/std/dictmultiobject.py pypy/trunk/pypy/objspace/std/listobject.py pypy/trunk/pypy/objspace/std/multimethod.py pypy/trunk/pypy/objspace/std/objecttype.py pypy/trunk/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/std/ropeobject.py pypy/trunk/pypy/objspace/std/ropeunicodeobject.py pypy/trunk/pypy/objspace/std/stdtypedef.py pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/transparent.py pypy/trunk/pypy/objspace/std/typeobject.py pypy/trunk/pypy/objspace/std/typetype.py pypy/trunk/pypy/objspace/std/unicodeobject.py pypy/trunk/pypy/objspace/std/unicodetype.py pypy/trunk/pypy/objspace/test/test_descroperation.py pypy/trunk/pypy/tool/test/test_pytestsupport.py pypy/trunk/pypy/tool/traceop.py pypy/trunk/pypy/translator/geninterplevel.py pypy/trunk/pypy/translator/goal/sharedpypy.py pypy/trunk/pypy/translator/goal/targetpreimportedpypy.py pypy/trunk/pypy/translator/goal/targetpypystandalone.py Log: (cfbolz, arigo) Merge the branch/lazy-operr-format, replacing most raise OperationError(space.w_XxxError, space.wrap("foo %s" % x)) with raise operationerrfmt(space.w_XxxError, "foo %s", x) which is both a bit shorter and quite faster to run in the common case where the exception is swallowed without being ever printed: the string formatting is then never done. Modified: pypy/trunk/lib-python/modified-2.5.2/test/output/test_extcall ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/output/test_extcall (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/output/test_extcall Tue Jan 26 09:33:42 2010 @@ -25,9 +25,9 @@ got multiple values for keyword argument 'b' keywords must be strings h() got an unexpected keyword argument 'e' -iteration over non-sequence -iteration over non-sequence -iteration over non-sequence +'function' object is not iterable +'function' object is not iterable +'function' object is not iterable argument after ** must be a dictionary argument after ** must be a dictionary argument after ** must be a dictionary Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_genexps.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_genexps.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_genexps.py Tue Jan 26 09:33:42 2010 @@ -109,7 +109,7 @@ Traceback (most recent call last): File "", line 1, in -toplevel- (i for i in 6) - TypeError: iteration over non-sequence + TypeError: 'int' object is not iterable Verify late binding for the outermost if-expression Modified: pypy/trunk/lib-python/modified-2.5.2/test/test_unpack.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/test/test_unpack.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/test/test_unpack.py Tue Jan 26 09:33:42 2010 @@ -55,7 +55,7 @@ >>> a, b, c = 7 Traceback (most recent call last): ... - TypeError: iteration over non-sequence + TypeError: 'int' object is not iterable Unpacking tuple of wrong size Modified: pypy/trunk/py/plugin/pytest_terminal.py ============================================================================== --- pypy/trunk/py/plugin/pytest_terminal.py (original) +++ pypy/trunk/py/plugin/pytest_terminal.py Tue Jan 26 09:33:42 2010 @@ -276,8 +276,8 @@ if len(repr_plugin)+26 > fullwidth: repr_plugin = repr_plugin[:(fullwidth-30)] + '...' self.write_line(" %-20s: %s" %(name, repr_plugin)) - for i, testarg in enumerate(self.config.args): - self.write_line("test object %d: %s" %(i+1, testarg)) + #for i, testarg in enumerate(self.config.args): + # self.write_line("test object %d: %s" %(i+1, testarg)) def pytest_sessionfinish(self, exitstatus, __multicall__): __multicall__.execute() Modified: pypy/trunk/pypy/interpreter/argument.py ============================================================================== --- pypy/trunk/pypy/interpreter/argument.py (original) +++ pypy/trunk/pypy/interpreter/argument.py Tue Jan 26 09:33:42 2010 @@ -2,7 +2,7 @@ Arguments objects. """ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rlib.debug import make_sure_not_resized from pypy.rlib import jit @@ -160,10 +160,10 @@ raise OperationError(space.w_TypeError, space.wrap("keywords must be strings")) if self.keywords and key in self.keywords: - raise OperationError(self.space.w_TypeError, - self.space.wrap("got multiple values " - "for keyword argument " - "'%s'" % key)) + raise operationerrfmt(self.space.w_TypeError, + "got multiple values " + "for keyword argument " + "'%s'", key) keywords[i] = key keywords_w[i] = space.getitem(w_starstararg, w_key) i += 1 Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Tue Jan 26 09:33:42 2010 @@ -1,6 +1,6 @@ from pypy.interpreter.executioncontext import ExecutionContext, ActionFlag from pypy.interpreter.executioncontext import UserDelAction, FrameTraceAction -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.argument import Arguments from pypy.interpreter.pycompiler import CPythonCompiler, PythonAstCompiler from pypy.interpreter.miscutils import ThreadLocals @@ -54,9 +54,9 @@ def setdict(self, space, w_dict): typename = space.type(self).getname(space, '?') - raise OperationError(space.w_TypeError, - space.wrap("attribute '__dict__' of %s objects " - "is not writable" % typename)) + raise operationerrfmt(space.w_TypeError, + "attribute '__dict__' of %s objects " + "is not writable", typename) # to be used directly only by space.type implementations def getclass(self, space): @@ -112,9 +112,9 @@ classname = '?' else: classname = wrappable_class_name(RequiredClass) - msg = "'%s' object expected, got '%s' instead" % ( + msg = "'%s' object expected, got '%s' instead" + raise operationerrfmt(space.w_TypeError, msg, classname, self.getclass(space).getname(space, '?')) - raise OperationError(space.w_TypeError, space.wrap(msg)) # used by _weakref implemenation @@ -123,8 +123,8 @@ def setweakref(self, space, weakreflifeline): typename = space.type(self).getname(space, '?') - raise OperationError(space.w_TypeError, space.wrap( - "cannot create weak reference to '%s' object" % typename)) + raise operationerrfmt(space.w_TypeError, + "cannot create weak reference to '%s' object", typename) def clear_all_weakrefs(self): """Call this at the beginning of interp-level __del__() methods @@ -366,10 +366,10 @@ try: w_mod = self.builtin_modules[name] except KeyError: - raise OperationError( + raise operationerrfmt( self.w_SystemError, - self.wrap("getbuiltinmodule() called " - "with non-builtin module %s" % name)) + "getbuiltinmodule() called " + "with non-builtin module %s", name) else: # Add the module to sys.modules self.setitem(w_modules, w_name, w_mod) @@ -693,10 +693,10 @@ return None obj = self.interpclass_w(w_obj) if not isinstance(obj, RequiredClass): # or obj is None - msg = "'%s' object expected, got '%s' instead" % ( + msg = "'%s' object expected, got '%s' instead" + raise operationerrfmt(self.w_TypeError, msg, wrappable_class_name(RequiredClass), w_obj.getclass(self).getname(self, '?')) - raise OperationError(self.w_TypeError, self.wrap(msg)) return obj interp_w._annspecialcase_ = 'specialize:arg(1)' @@ -825,7 +825,8 @@ try: w_res = self.call_args(w_func, args) except OperationError, e: - ec.c_exception_trace(frame, e.w_value) + w_value = e.get_w_value(self) + ec.c_exception_trace(frame, w_value) raise ec.c_return_trace(frame, w_func) return w_res @@ -997,9 +998,9 @@ except OperationError, err: if objdescr is None or not err.match(self, self.w_TypeError): raise - msg = "%s must be an integer, not %s" % ( + msg = "%s must be an integer, not %s" + raise operationerrfmt(self.w_TypeError, msg, objdescr, self.type(w_obj).getname(self, '?')) - raise OperationError(self.w_TypeError, self.wrap(msg)) try: index = self.int_w(w_index) except OperationError, err: @@ -1012,10 +1013,10 @@ else: return sys.maxint else: - raise OperationError( - w_exception, self.wrap( + raise operationerrfmt( + w_exception, "cannot fit '%s' into an index-sized " - "integer" % self.type(w_obj).getname(self, '?'))) + "integer", self.type(w_obj).getname(self, '?')) else: return index Modified: pypy/trunk/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/pypy/interpreter/error.py (original) +++ pypy/trunk/pypy/interpreter/error.py Tue Jan 26 09:33:42 2010 @@ -16,20 +16,26 @@ PyTraceback objects making the application-level traceback. """ + _w_value = None + application_traceback = None + def __init__(self, w_type, w_value, tb=None): - if w_type is None: + if not we_are_translated() and w_type is None: from pypy.tool.error import FlowingError raise FlowingError(w_value) - self.w_type = w_type - self.w_value = w_value + self.setup(w_type) + self._w_value = w_value self.application_traceback = tb + + def setup(self, w_type): + self.w_type = w_type if not we_are_translated(): self.debug_excs = [] def clear(self, space): # for sys.exc_clear() self.w_type = space.w_None - self.w_value = space.w_None + self._w_value = space.w_None self.application_traceback = None if not we_are_translated(): del self.debug_excs[:] @@ -45,14 +51,18 @@ def __str__(self): "NOT_RPYTHON: Convenience for tracebacks." - return '[%s: %s]' % (self.w_type, self.w_value) + s = self._w_value + if self.__class__ is not OperationError and s is None: + s = self._compute_value() + return '[%s: %s]' % (self.w_type, s) def errorstr(self, space): "The exception class and value, as a string." + w_value = self.get_w_value(space) if space is None: # this part NOT_RPYTHON exc_typename = str(self.w_type) - exc_value = str(self.w_value) + exc_value = str(w_value) else: w = space.wrap if space.is_w(space.type(self.w_type), space.w_str): @@ -60,11 +70,11 @@ else: exc_typename = space.str_w( space.getattr(self.w_type, w('__name__'))) - if space.is_w(self.w_value, space.w_None): + if space.is_w(w_value, space.w_None): exc_value = "" else: try: - exc_value = space.str_w(space.str(self.w_value)) + exc_value = space.str_w(space.str(w_value)) except OperationError: # oups, cannot __str__ the exception object exc_value = "" @@ -165,7 +175,7 @@ # (inst, None) (inst.__class__, inst) no # w_type = self.w_type - w_value = self.w_value + w_value = self.get_w_value(space) if space.full_exceptions: while space.is_true(space.isinstance(w_type, space.w_tuple)): w_type = space.getitem(w_type, space.wrap(0)) @@ -204,8 +214,8 @@ if not space.exception_is_valid_class_w(w_instclass): instclassname = w_instclass.getname(space, '?') msg = ("exceptions must be classes, or instances, " - "or strings (deprecated), not %s" % (instclassname,)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + "or strings (deprecated), not %s") + raise operationerrfmt(space.w_TypeError, msg, instclassname) if not space.is_w(w_value, space.w_None): raise OperationError(space.w_TypeError, @@ -214,8 +224,8 @@ w_value = w_inst w_type = w_instclass - self.w_type = w_type - self.w_value = w_value + self.w_type = w_type + self._w_value = w_value def write_unraisable(self, space, where, w_object=None): if w_object is None: @@ -232,6 +242,94 @@ except OperationError: pass # ignored + def get_w_value(self, space): + w_value = self._w_value + if w_value is None: + value = self._compute_value() + self._w_value = w_value = space.wrap(value) + return w_value + + def _compute_value(self): + raise NotImplementedError + +# ____________________________________________________________ +# optimization only: avoid the slowest operation -- the string +# formatting with '%' -- in the common case were we don't +# actually need the message. Only supports %s and %d. + +_fmtcache = {} +_fmtcache2 = {} + +def decompose_valuefmt(valuefmt): + """Returns a tuple of string parts extracted from valuefmt, + and a tuple of format characters.""" + formats = [] + parts = valuefmt.split('%') + i = 1 + while i < len(parts): + if parts[i].startswith('s') or parts[i].startswith('d'): + formats.append(parts[i][0]) + parts[i] = parts[i][1:] + i += 1 + elif parts[i] == '': # support for '%%' + parts[i-1] += '%' + parts[i+1] + del parts[i:i+2] + else: + raise ValueError("invalid format string (only %s or %d supported)") + assert len(formats) > 0, "unsupported: no % command found" + return tuple(parts), tuple(formats) + +def get_operrcls2(valuefmt): + strings, formats = decompose_valuefmt(valuefmt) + assert len(strings) == len(formats) + 1 + try: + OpErrFmt = _fmtcache2[formats] + except KeyError: + from pypy.rlib.unroll import unrolling_iterable + attrs = ['x%d' % i for i in range(len(formats))] + entries = unrolling_iterable(enumerate(attrs)) + # + class OpErrFmt(OperationError): + def __init__(self, w_type, strings, *args): + self.setup(w_type) + assert len(args) == len(strings) - 1 + self.xstrings = strings + for i, attr in entries: + setattr(self, attr, args[i]) + if not we_are_translated() and w_type is None: + from pypy.tool.error import FlowingError + raise FlowingError(self._compute_value()) + def _compute_value(self): + lst = [None] * (len(formats) + len(formats) + 1) + for i, attr in entries: + string = self.xstrings[i] + value = getattr(self, attr) + lst[i+i] = string + lst[i+i+1] = str(value) + lst[-1] = self.xstrings[-1] + return ''.join(lst) + # + _fmtcache2[formats] = OpErrFmt + return OpErrFmt, strings + +def get_operationerr_class(valuefmt): + try: + result = _fmtcache[valuefmt] + except KeyError: + result = _fmtcache[valuefmt] = get_operrcls2(valuefmt) + return result +get_operationerr_class._annspecialcase_ = 'specialize:memo' + +def operationerrfmt(w_type, valuefmt, *args): + """Equivalent to OperationError(w_type, space.wrap(valuefmt % args)). + More efficient in the (common) case where the value is not actually + needed.""" + OpErrFmt, strings = get_operationerr_class(valuefmt) + return OpErrFmt(w_type, strings, *args) +operationerrfmt._annspecialcase_ = 'specialize:arg(1)' + +# ____________________________________________________________ + # Utilities from pypy.tool.ansi_print import ansi_print @@ -277,16 +375,3 @@ space.wrap(msg)) return OperationError(exc, w_error) wrap_oserror._annspecialcase_ = 'specialize:arg(2)' - -### installing the excepthook for OperationErrors -##def operr_excepthook(exctype, value, traceback): -## if issubclass(exctype, OperationError): -## value.debug_excs.append((exctype, value, traceback)) -## value.print_detailed_traceback() -## else: -## old_excepthook(exctype, value, traceback) -## from pypy.tool import tb_server -## tb_server.publish_exc((exctype, value, traceback)) - -##old_excepthook = sys.excepthook -##sys.excepthook = operr_excepthook Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Tue Jan 26 09:33:42 2010 @@ -265,7 +265,8 @@ if w_callback is not None and event != "leaveframe": if operr is not None: - w_arg = space.newtuple([operr.w_type, operr.w_value, + w_value = operr.get_w_value(space) + w_arg = space.newtuple([operr.w_type, w_value, space.wrap(operr.application_traceback)]) frame.fast2locals() Modified: pypy/trunk/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/pypy/interpreter/function.py (original) +++ pypy/trunk/pypy/interpreter/function.py Tue Jan 26 09:33:42 2010 @@ -7,7 +7,7 @@ """ from pypy.rlib.unroll import unrolling_iterable -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments @@ -388,7 +388,9 @@ if self.closure: closure_len = len(self.closure) if isinstance(code, PyCode) and closure_len != len(code.co_freevars): - raise OperationError(space.w_ValueError, space.wrap("%s() requires a code object with %s free vars, not %s " % (self.name, closure_len, len(code.co_freevars)))) + raise operationerrfmt(space.w_ValueError, + "%s() requires a code object with %d free vars, not %d", + self.name, closure_len, len(code.co_freevars)) self.code = code def fget_func_closure(space, self): @@ -458,9 +460,9 @@ instname += " " instdescr = "%sinstance" %instname msg = ("unbound method %s() must be called with %s" - "instance as first argument (got %s instead)") % (myname, clsdescr, instdescr) - raise OperationError(space.w_TypeError, - space.wrap(msg)) + "instance as first argument (got %s instead)") + raise operationerrfmt(space.w_TypeError, msg, + myname, clsdescr, instdescr) return space.call_args(self.w_function, args) def descr_method_get(self, w_obj, w_cls=None): @@ -580,8 +582,8 @@ def descr_classmethod__new__(space, w_type, w_function): if not space.is_true(space.callable(w_function)): typename = space.type(w_function).getname(space, '?') - raise OperationError(space.w_TypeError, space.wrap( - "'%s' object is not callable" % typename)) + raise operationerrfmt(space.w_TypeError, + "'%s' object is not callable", typename) return space.wrap(ClassMethod(w_function)) class FunctionWithFixedCode(Function): Modified: pypy/trunk/pypy/interpreter/main.py ============================================================================== --- pypy/trunk/pypy/interpreter/main.py (original) +++ pypy/trunk/pypy/interpreter/main.py Tue Jan 26 09:33:42 2010 @@ -117,7 +117,7 @@ except OperationError, operationerr: operationerr.normalize_exception(space) w_type = operationerr.w_type - w_value = operationerr.w_value + w_value = operationerr.get_w_value(space) w_traceback = space.wrap(operationerr.application_traceback) # for debugging convenience we also insert the exception into @@ -128,7 +128,7 @@ try: # exit if we catch a w_SystemExit if operationerr.match(space, space.w_SystemExit): - w_exitcode = space.getattr(operationerr.w_value, + w_exitcode = space.getattr(w_value, space.wrap('code')) if space.is_w(w_exitcode, space.w_None): exitcode = 0 Modified: pypy/trunk/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/trunk/pypy/interpreter/pycompiler.py (original) +++ pypy/trunk/pypy/interpreter/pycompiler.py Tue Jan 26 09:33:42 2010 @@ -70,7 +70,7 @@ if not err2.match(space, space.w_SyntaxError): raise - if space.eq_w(err1.w_value, err2.w_value): + if space.eq_w(err1.get_w_value(space), err2.get_w_value(space)): raise # twice the same error, re-raise return None # two different errors, expect more Modified: pypy/trunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/pypy/interpreter/pyframe.py Tue Jan 26 09:33:42 2010 @@ -4,7 +4,7 @@ from pypy.tool.pairtype import extendabletype from pypy.interpreter import eval, baseobjspace, pycode from pypy.interpreter.argument import Arguments -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter import pytraceback import opcode @@ -303,7 +303,7 @@ w_exc_value = space.w_None w_tb = space.w_None else: - w_exc_value = self.last_exception.w_value + w_exc_value = self.last_exception.get_w_value(space) w_tb = w(self.last_exception.application_traceback) tup_state = [ @@ -455,8 +455,8 @@ space.wrap("f_lineno can only be set by a trace function.")) if new_lineno < self.pycode.co_firstlineno: - raise OperationError(space.w_ValueError, - space.wrap("line %d comes before the current code." % new_lineno)) + raise operationerrfmt(space.w_ValueError, + "line %d comes before the current code.", new_lineno) code = self.pycode.co_code addr = 0 line = self.pycode.co_firstlineno @@ -472,8 +472,8 @@ break if new_lasti == -1: - raise OperationError(space.w_ValueError, - space.wrap("line %d comes after the current code." % new_lineno)) + raise operationerrfmt(space.w_ValueError, + "line %d comes after the current code.", new_lineno) # Don't jump to a line with an except in it. if ord(code[new_lasti]) in (DUP_TOP, POP_TOP): @@ -519,9 +519,9 @@ assert len(blockstack) == 0 if new_lasti_setup_addr != f_lasti_setup_addr: - raise OperationError(space.w_ValueError, - space.wrap("can't jump into or out of a 'finally' block %d -> %d" % - (f_lasti_setup_addr, new_lasti_setup_addr))) + raise operationerrfmt(space.w_ValueError, + "can't jump into or out of a 'finally' block %d -> %d", + f_lasti_setup_addr, new_lasti_setup_addr) if new_lasti < self.last_instr: min_addr = new_lasti @@ -612,7 +612,7 @@ while f is not None and f.last_exception is None: f = f.f_backref() if f is not None: - return f.last_exception.w_value + return f.last_exception.get_w_value(space) return space.w_None def fget_f_exc_traceback(space, self): Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Tue Jan 26 09:33:42 2010 @@ -5,7 +5,7 @@ """ import sys -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import UnpackValueError, Wrappable from pypy.interpreter import gateway, function, eval from pypy.interpreter import pyframe, pytraceback @@ -323,8 +323,8 @@ def _load_fast_failed(f, varindex): varname = f.getlocalvarname(varindex) - message = "local variable '%s' referenced before assignment" % varname - raise OperationError(f.space.w_UnboundLocalError, f.space.wrap(message)) + message = "local variable '%s' referenced before assignment" + raise operationerrfmt(f.space.w_UnboundLocalError, message, varname) _load_fast_failed._dont_inline_ = True def LOAD_CONST(f, constindex, *ignored): @@ -627,8 +627,9 @@ # catch KeyErrors and turn them into NameErrors if not e.match(f.space, f.space.w_KeyError): raise - message = "name '%s' is not defined" % f.space.str_w(w_varname) - raise OperationError(f.space.w_NameError, f.space.wrap(message)) + message = "name '%s' is not defined" + raise operationerrfmt(f.space.w_NameError, message, + f.space.str_w(w_varname)) def UNPACK_SEQUENCE(f, itemcount, *ignored): w_iterable = f.popvalue() @@ -680,9 +681,8 @@ _load_global._always_inline_ = True def _load_global_failed(f, varname): - message = "global name '%s' is not defined" % varname - raise OperationError(f.space.w_NameError, - f.space.wrap(message)) + message = "global name '%s' is not defined" + raise operationerrfmt(f.space.w_NameError, message, varname) _load_global_failed._dont_inline_ = True def LOAD_GLOBAL(f, nameindex, *ignored): @@ -692,8 +692,8 @@ def DELETE_FAST(f, varindex, *ignored): if f.fastlocals_w[varindex] is None: varname = f.getlocalvarname(varindex) - message = "local variable '%s' referenced before assignment" % varname - raise OperationError(f.space.w_UnboundLocalError, f.space.wrap(message)) + message = "local variable '%s' referenced before assignment" + raise operationerrfmt(f.space.w_UnboundLocalError, message, varname) f.fastlocals_w[varindex] = None @@ -809,8 +809,9 @@ except OperationError, e: if not e.match(f.space, f.space.w_AttributeError): raise - raise OperationError(f.space.w_ImportError, - f.space.wrap("cannot import name '%s'" % f.space.str_w(w_name) )) + raise operationerrfmt(f.space.w_ImportError, + "cannot import name '%s'", + f.space.str_w(w_name)) f.pushvalue(w_obj) def JUMP_FORWARD(f, jumpby, next_instr, *ignored): @@ -875,7 +876,7 @@ operr = unroller.operr w_result = f.space.call_function(w_exitfunc, operr.w_type, - operr.w_value, + operr.get_w_value(f.space), operr.application_traceback) if f.space.is_true(w_result): # __exit__() returned True -> Swallow the exception. @@ -1098,7 +1099,7 @@ raise RaiseWithExplicitTraceback(self.operr) def state_unpack_variables(self, space): - return [self.operr.w_type, self.operr.w_value] + return [self.operr.w_type, self.operr.get_w_value(space)] def state_pack_variables(space, w_type, w_value): return SApplicationException(OperationError(w_type, w_value)) state_pack_variables = staticmethod(state_pack_variables) @@ -1209,7 +1210,7 @@ # instead of the traceback, we store the unroller object, # wrapped. frame.pushvalue(frame.space.wrap(unroller)) - frame.pushvalue(operationerr.w_value) + frame.pushvalue(operationerr.get_w_value(frame.space)) frame.pushvalue(operationerr.w_type) frame.last_exception = operationerr return self.handlerposition # jump to the handler Modified: pypy/trunk/pypy/interpreter/test/test_argument.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_argument.py (original) +++ pypy/trunk/pypy/interpreter/test/test_argument.py Tue Jan 26 09:33:42 2010 @@ -292,11 +292,11 @@ excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"], [1], w_starstararg={None: 1}) assert excinfo.value.w_type is TypeError - assert excinfo.value.w_value is not None + assert excinfo.value._w_value is not None excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"], [1], w_starstararg={valuedummy: 1}) assert excinfo.value.w_type is ValueError - assert excinfo.value.w_value is None + assert excinfo.value._w_value is None def test_blindargs(self): @@ -374,7 +374,7 @@ excinfo = py.test.raises(OperationError, args.parse_obj, "obj", "foo", Signature(["a", "b"], None, None)) assert excinfo.value.w_type is TypeError - assert excinfo.value.w_value == "msg foo" + assert excinfo.value._w_value == "msg foo" def test_args_parsing_into_scope(self): @@ -429,7 +429,7 @@ "obj", [None, None], "foo", Signature(["a", "b"], None, None)) assert excinfo.value.w_type is TypeError - assert excinfo.value.w_value == "msg foo" + assert excinfo.value._w_value == "msg foo" def test_topacked_frompacked(self): space = DummySpace() Modified: pypy/trunk/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_compiler.py (original) +++ pypy/trunk/pypy/interpreter/test/test_compiler.py Tue Jan 26 09:33:42 2010 @@ -634,7 +634,7 @@ ex = e.value space = self.space assert ex.match(space, space.w_SyntaxError) - assert 'hello_world' in space.str_w(space.str(ex.w_value)) + assert 'hello_world' in space.str_w(space.str(ex.get_w_value(space))) class TestPyCCompiler(BaseTestCompiler): Modified: pypy/trunk/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/pypy/interpreter/typedef.py (original) +++ pypy/trunk/pypy/interpreter/typedef.py Tue Jan 26 09:33:42 2010 @@ -7,7 +7,7 @@ from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, W_Root, ObjSpace, \ DescrMismatch -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.tool.sourcetools import compile2, func_with_new_name from pypy.rlib.objectmodel import instantiate, compute_identity_hash from pypy.rlib.jit import hint @@ -52,8 +52,8 @@ def descr__hash__unhashable(space, w_obj): typename = space.type(w_obj).getname(space, '?') - msg = "%s objects are unhashable" % (typename,) - raise OperationError(space.w_TypeError,space.wrap(msg)) + raise operationerrfmt(space.w_TypeError, + "'%s' objects are unhashable", typename) no_hash_descr = interp2app(descr__hash__unhashable) @@ -482,12 +482,12 @@ def typecheck(self, space, w_obj): if not space.is_true(space.isinstance(w_obj, self.w_cls)): - raise OperationError(space.w_TypeError, - space.wrap("descriptor '%s' for '%s'" - " objects doesn't apply to '%s' object" % - (self.name, - self.w_cls.name, - space.type(w_obj).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "descriptor '%s' for '%s'" + " objects doesn't apply to '%s' object", + self.name, + self.w_cls.name, + space.type(w_obj).getname(space, '?')) def descr_member_get(space, member, w_obj, w_w_cls=None): """member.__get__(obj[, type]) -> value @@ -554,9 +554,9 @@ w_dict = w_obj.getdict() if w_dict is None: typename = space.type(w_obj).getname(space, '?') - raise OperationError(space.w_TypeError, - space.wrap("descriptor '__dict__' doesn't apply to" - " '%s' objects" % typename)) + raise operationerrfmt(space.w_TypeError, + "descriptor '__dict__' doesn't apply to" + " '%s' objects", typename) return w_dict def descr_set_dict(space, w_obj, w_dict): Modified: pypy/trunk/pypy/module/__builtin__/descriptor.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/descriptor.py (original) +++ pypy/trunk/pypy/module/__builtin__/descriptor.py Tue Jan 26 09:33:42 2010 @@ -3,7 +3,7 @@ from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments from pypy.interpreter.gateway import interp2app -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.descroperation import object_getattribute, object_setattr from pypy.interpreter.function import StaticMethod, ClassMethod from pypy.interpreter.typedef import GetSetProperty, descr_get_dict, \ @@ -154,8 +154,8 @@ # a TypeError instead of an AttributeError and using "readonly" # instead of "read-only" in the error message :-/ if attr in ["__doc__", "fget", "fset", "fdel"]: - raise OperationError(space.w_TypeError, space.wrap( - "Trying to set readonly attribute %s on property" % (attr,))) + raise operationerrfmt(space.w_TypeError, + "Trying to set readonly attribute %s on property", attr) return space.call_function(object_setattr(space), space.wrap(self), space.wrap(attr), w_value) setattr.unwrap_spec = ['self', ObjSpace, str, W_Root] Modified: pypy/trunk/pypy/module/__builtin__/interp_classobj.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/interp_classobj.py (original) +++ pypy/trunk/pypy/module/__builtin__/interp_classobj.py Tue Jan 26 09:33:42 2010 @@ -1,5 +1,5 @@ import new -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped, applevel from pypy.interpreter.gateway import interp2app, ObjSpace from pypy.interpreter.typedef import TypeDef, make_weakref_descr @@ -11,10 +11,9 @@ def raise_type_err(space, argument, expected, w_obj): type_name = space.type(w_obj).getname(space, '?') - w_error = space.wrap("argument %s must be %s, not %s" % ( - argument, expected, type_name)) - raise OperationError(space.w_TypeError, - w_error) + raise operationerrfmt(space.w_TypeError, + "argument %s must be %s, not %s", + argument, expected, type_name) def unwrap_attr(space, w_attr): try: @@ -22,7 +21,8 @@ except OperationError, e: if not e.match(space, space.w_TypeError): raise - return "" + return "?" # any string different from "__dict__" & co. is fine + # XXX it's not clear that we have to catch the TypeError... def descr_classobj_new(space, w_subtype, w_name, w_bases, w_dict): if not space.is_true(space.isinstance(w_bases, space.w_tuple)): @@ -120,10 +120,10 @@ return space.newtuple(self.bases_w) w_value = self.lookup(space, w_attr) if w_value is None: - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("class %s has no attribute %s" % ( - self.name, space.str_w(space.str(w_attr))))) + "class %s has no attribute '%s'", + self.name, name) w_descr_get = space.lookup(w_value, '__get__') if w_descr_get is None: @@ -152,18 +152,18 @@ def descr_delattr(self, space, w_attr): name = unwrap_attr(space, w_attr) if name in ("__dict__", "__name__", "__bases__"): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("cannot delete attribute %s" % (name,))) + "cannot delete attribute '%s'", name) try: space.delitem(self.w_dict, w_attr) except OperationError, e: if not e.match(space, space.w_KeyError): raise - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("class %s has no attribute %s" % ( - self.name, space.str_w(space.str(w_attr))))) + "class %s has no attribute '%s'", + self.name, name) def descr_call(self, space, __args__): if self.lookup(space, space.wrap('__del__')) is not None: @@ -336,10 +336,10 @@ w_value = self.w_class.lookup(space, w_name) if w_value is None: if exc: - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("%s instance has no attribute %s" % ( - self.w_class.name, space.str_w(w_name)))) + "%s instance has no attribute '%s'", + self.w_class.name, space.str_w(w_name)) else: return None w_descr_get = space.lookup(w_value, '__get__') @@ -401,10 +401,10 @@ space.call_function(w_meth, w_name) else: if not self.deldictvalue(space, w_name): - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("%s instance has no attribute %s" % ( - self.w_class.name, space.str_w(space.str(w_name))))) + "%s instance has no attribute '%s'", + self.w_class.name, name) def descr_repr(self, space): w_meth = self.getattr(space, space.wrap('__repr__'), False) Modified: pypy/trunk/pypy/module/_codecs/interp_codecs.py ============================================================================== --- pypy/trunk/pypy/module/_codecs/interp_codecs.py (original) +++ pypy/trunk/pypy/module/_codecs/interp_codecs.py Tue Jan 26 09:33:42 2010 @@ -1,4 +1,4 @@ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, NoneNotWrapped from pypy.interpreter.baseobjspace import W_Root @@ -30,20 +30,19 @@ w_res = space.call_function(w_errorhandler, w_exc) if (not space.is_true(space.isinstance(w_res, space.w_tuple)) or space.int_w(space.len(w_res)) != 2): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("encoding error handler must return " - "(unicode, int) tuple, not %s" % ( - space.str_w(space.repr(w_res))))) + "encoding error handler must return " + "(unicode, int) tuple, not %s", + space.str_w(space.repr(w_res))) w_replace, w_newpos = space.fixedview(w_res, 2) newpos = space.int_w(w_newpos) if (newpos < 0): newpos = len(input) + newpos if newpos < 0 or newpos > len(input): - raise OperationError( + raise operationerrfmt( space.w_IndexError, - space.wrap("position %d from error handler " - "out of bounds" % newpos)) + "position %d from error handler out of bounds", newpos) if decode: replace = space.unicode_w(w_replace) return replace, newpos @@ -103,9 +102,9 @@ else: state.codec_search_cache[normalized_encoding] = w_result return w_result - raise OperationError( + raise operationerrfmt( space.w_LookupError, - space.wrap("unknown encoding: %s" % encoding)) + "unknown encoding: %s", encoding) lookup_codec.unwrap_spec = [ObjSpace, str] @@ -120,9 +119,9 @@ try: w_err_handler = state.codec_error_registry[errors] except KeyError: - raise OperationError( + raise operationerrfmt( space.w_LookupError, - space.wrap("unknown error handler name %s" % errors)) + "unknown error handler name %s", errors) return w_err_handler lookup_error.unwrap_spec = [ObjSpace, str] Modified: pypy/trunk/pypy/module/_file/interp_file.py ============================================================================== --- pypy/trunk/pypy/module/_file/interp_file.py (original) +++ pypy/trunk/pypy/module/_file/interp_file.py Tue Jan 26 09:33:42 2010 @@ -4,7 +4,7 @@ from pypy.rlib.rarithmetic import r_longlong from pypy.module._file.interp_stream import W_AbstractStream from pypy.module._file.interp_stream import StreamErrors, wrap_streamerror -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, make_weakref_descr @@ -52,8 +52,8 @@ if (not mode or mode[0] not in ['r', 'w', 'a', 'U'] or ('U' in mode and ('w' in mode or 'a' in mode))): space = self.space - raise OperationError(space.w_ValueError, - space.wrap('invalid mode : "%s"' % mode)) + raise operationerrfmt(space.w_ValueError, + "invalid mode: '%s'", mode) def getstream(self): """Return self.stream or raise an app-level ValueError if missing Modified: pypy/trunk/pypy/module/_rawffi/interp_rawffi.py ============================================================================== --- pypy/trunk/pypy/module/_rawffi/interp_rawffi.py (original) +++ pypy/trunk/pypy/module/_rawffi/interp_rawffi.py Tue Jan 26 09:33:42 2010 @@ -1,7 +1,7 @@ import sys from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments -from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.interpreter.gateway import interp2app, NoneNotWrapped from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -85,15 +85,15 @@ try: return UNPACKED_TYPECODES[key] except KeyError: - raise OperationError(space.w_ValueError, space.wrap( - "Unknown type letter %s" % (key,))) + raise operationerrfmt(space.w_ValueError, + "Unknown type letter %s", key) def _get_type_(space, key): try: return TYPEMAP[key] except KeyError: - raise OperationError(space.w_ValueError, space.wrap( - "Unknown type letter %s" % (key,))) + raise operationerrfmt(space.w_ValueError, + "Unknown type letter %s", key) def unpack_to_ffi_type(space, w_shape, shape=False): resshape = None @@ -174,8 +174,8 @@ ptr = self.cdll.getrawpointer(name, ffi_argtypes, ffi_restype, flags) except KeyError: - raise OperationError(space.w_AttributeError, space.wrap( - "No symbol %s found in library %s" % (name, self.name))) + raise operationerrfmt(space.w_AttributeError, + "No symbol %s found in library %s", name, self.name) elif (_MS_WINDOWS and space.is_true(space.isinstance(w_name, space.w_int))): @@ -184,8 +184,8 @@ ptr = self.cdll.getrawpointer_byordinal(ordinal, ffi_argtypes, ffi_restype, flags) except KeyError: - raise OperationError(space.w_AttributeError, space.wrap( - "No symbol %d found in library %s" % (ordinal, self.name))) + raise operationerrfmt(space.w_AttributeError, + "No symbol %d found in library %s", ordinal, self.name) else: raise OperationError(space.w_TypeError, space.wrap( "function name must be string or integer")) @@ -200,8 +200,8 @@ address_as_uint = rffi.cast(lltype.Unsigned, self.cdll.getaddressindll(name)) except KeyError: - raise OperationError(space.w_ValueError, - space.wrap("Cannot find symbol %s" % (name,))) + raise operationerrfmt(space.w_ValueError, + "Cannot find symbol %s", name) return space.wrap(address_as_uint) getaddressindll.unwrap_spec = ['self', ObjSpace, str] @@ -391,9 +391,9 @@ from pypy.module._rawffi.structure import W_StructureInstance argnum = len(args_w) if argnum != len(self.argletters): - msg = "Wrong number of arguments: expected %d, got %d" % ( - len(self.argletters), argnum) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "Wrong number of arguments: expected %d, got %d" + raise operationerrfmt(space.w_TypeError, msg, + len(self.argletters), argnum) args_ll = [] for i in range(argnum): argletter = self.argletters[i] @@ -405,23 +405,24 @@ arg.shape.alignment != xalignment): msg = ("Argument %d should be a structure of size %d and " "alignment %d, " - "got instead size %d and alignment %d" % - (i+1, xsize, xalignment, - arg.shape.size, arg.shape.alignment)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + "got instead size %d and alignment %d") + raise operationerrfmt(space.w_TypeError, msg, i+1, + xsize, xalignment, arg.shape.size, + arg.shape.alignment) else: arg = space.interp_w(W_ArrayInstance, w_arg) if arg.length != 1: msg = ("Argument %d should be an array of length 1, " - "got length %d" % (i+1, arg.length)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + "got length %d") + raise operationerrfmt(space.w_TypeError, msg, + i+1, arg.length) letter = arg.shape.itemtp[0] if letter != argletter: if not (argletter in TYPEMAP_PTR_LETTERS and letter in TYPEMAP_PTR_LETTERS): - msg = "Argument %d should be typecode %s, got %s" % ( - i+1, argletter, letter) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "Argument %d should be typecode %s, got %s" + raise operationerrfmt(space.w_TypeError, msg, + i+1, argletter, letter) args_ll.append(arg.ll_buffer) # XXX we could avoid the intermediate list args_ll @@ -463,8 +464,8 @@ try: return space.wrap(intmask(getattr(TYPEMAP[tp_letter], name))) except KeyError: - raise OperationError(space.w_ValueError, space.wrap( - "Unknown type specification %s" % tp_letter)) + raise operationerrfmt(space.w_ValueError, + "Unknown type specification %s", tp_letter) accessor.unwrap_spec = [ObjSpace, str] return func_with_new_name(accessor, func_name) Modified: pypy/trunk/pypy/module/_rawffi/structure.py ============================================================================== --- pypy/trunk/pypy/module/_rawffi/structure.py (original) +++ pypy/trunk/pypy/module/_rawffi/structure.py Tue Jan 26 09:33:42 2010 @@ -9,7 +9,7 @@ from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.rpython.lltypesystem import lltype, rffi -from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.module._rawffi.interp_rawffi import segfault_exception from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance from pypy.module._rawffi.interp_rawffi import wrap_value, unwrap_value @@ -53,8 +53,8 @@ for i in range(len(fields)): name, tp = fields[i] if name in name_to_index: - raise OperationError(space.w_ValueError, space.wrap( - "duplicate field name %s" % (name, ))) + raise operationerrfmt(space.w_ValueError, + "duplicate field name %s", name) name_to_index[name] = i size, alignment, pos = size_alignment_pos(fields) else: # opaque case @@ -76,8 +76,8 @@ try: return self.name_to_index[attr] except KeyError: - raise OperationError(space.w_AttributeError, space.wrap( - "C Structure has no attribute %s" % attr)) + raise operationerrfmt(space.w_AttributeError, + "C Structure has no attribute %s", attr) def descr_call(self, space, autofree=False): return space.wrap(self.allocate(space, 1, autofree)) Modified: pypy/trunk/pypy/module/_socket/interp_func.py ============================================================================== --- pypy/trunk/pypy/module/_socket/interp_func.py (original) +++ pypy/trunk/pypy/module/_socket/interp_func.py Tue Jan 26 09:33:42 2010 @@ -2,7 +2,7 @@ from pypy.module._socket.interp_socket import converted_error, W_RSocket from pypy.rlib import rsocket from pypy.rlib.rsocket import SocketError -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt def gethostname(space): """gethostname() -> string @@ -170,9 +170,9 @@ elif space.is_true(space.isinstance(w_x, space.w_long)): x = space.uint_w(w_x) else: - raise OperationError(space.w_TypeError, - space.wrap("expected int/long, %s found" % - (space.type(w_x).getname(space, "?")))) + raise operationerrfmt(space.w_TypeError, + "expected int/long, %s found", + space.type(w_x).getname(space, "?")) return space.wrap(rsocket.ntohl(x)) ntohl.unwrap_spec = [ObjSpace, W_Root] @@ -195,9 +195,9 @@ elif space.is_true(space.isinstance(w_x, space.w_long)): x = space.uint_w(w_x) else: - raise OperationError(space.w_TypeError, - space.wrap("expected int/long, %s found" % - (space.type(w_x).getname(space, "?")))) + raise operationerrfmt(space.w_TypeError, + "expected int/long, %s found", + space.type(w_x).getname(space, "?")) return space.wrap(rsocket.htonl(x)) htonl.unwrap_spec = [ObjSpace, W_Root] @@ -249,7 +249,7 @@ ip = rsocket.inet_ntop(family, packed) except SocketError, e: raise converted_error(space, e) - except ValueError, e: + except ValueError, e: # XXX the message is lost in RPython raise OperationError(space.w_ValueError, space.wrap(str(e))) return space.wrap(ip) Modified: pypy/trunk/pypy/module/_stackless/interp_coroutine.py ============================================================================== --- pypy/trunk/pypy/module/_stackless/interp_coroutine.py (original) +++ pypy/trunk/pypy/module/_stackless/interp_coroutine.py Tue Jan 26 09:33:42 2010 @@ -20,7 +20,7 @@ from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.function import StaticMethod from pypy.module._stackless.stackless_flags import StacklessFlags @@ -35,10 +35,10 @@ self.space = space self.costate = costate if not space.is_true(space.callable(w_obj)): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.mod(space.wrap('object %r is not callable'), - space.newtuple([w_obj]))) + "'%s' object is not callable", + space.type(w_obj).getname(space, '?')) self.w_func = w_obj self.args = args @@ -99,7 +99,7 @@ space = self.space if isinstance(operror, OperationError): w_exctype = operror.w_type - w_excvalue = operror.w_value + w_excvalue = operror.get_w_value(space) w_exctraceback = operror.application_traceback w_excinfo = space.newtuple([w_exctype, w_excvalue, w_exctraceback]) else: Modified: pypy/trunk/pypy/module/_stackless/interp_greenlet.py ============================================================================== --- pypy/trunk/pypy/module/_stackless/interp_greenlet.py (original) +++ pypy/trunk/pypy/module/_stackless/interp_greenlet.py Tue Jan 26 09:33:42 2010 @@ -28,7 +28,7 @@ except OperationError, operror: if not operror.match(space, greenlet.costate.w_GreenletExit): raise - w_result = operror.w_value + w_result = operror.get_w_value(space) finally: greenlet.active = False greenlet.costate.args_w = [w_result] @@ -127,7 +127,7 @@ operror.application_traceback = tb # Dead greenlet: turn GreenletExit into a regular return if self.isdead() and operror.match(space, self.costate.w_GreenletExit): - args_w = [operror.w_value] + args_w = [operror.get_w_value(space)] else: syncstate.push_exception(operror) args_w = None Modified: pypy/trunk/pypy/module/bz2/interp_bz2.py ============================================================================== --- pypy/trunk/pypy/module/bz2/interp_bz2.py (original) +++ pypy/trunk/pypy/module/bz2/interp_bz2.py Tue Jan 26 09:33:42 2010 @@ -1,7 +1,7 @@ from pypy.rpython.tool import rffi_platform as platform from pypy.rpython.lltypesystem import rffi from pypy.rpython.lltypesystem import lltype -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty @@ -193,8 +193,8 @@ def check_mode_ok(self, mode): if (not mode or mode[0] not in ['r', 'w', 'a', 'U']): space = self.space - raise OperationError(space.w_ValueError, - space.wrap('invalid mode : "%s"' % mode)) + raise operationerrfmt(space.w_ValueError, + "invalid mode: '%s'", mode) def direct_bz2__init__(self, w_name, mode='r', buffering=-1, compresslevel=9): Modified: pypy/trunk/pypy/module/clr/interp_clr.py ============================================================================== --- pypy/trunk/pypy/module/clr/interp_clr.py (original) +++ pypy/trunk/pypy/module/clr/interp_clr.py Tue Jan 26 09:33:42 2010 @@ -1,7 +1,7 @@ import os.path from pypy.module.clr import assemblyname from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app, ApplevelClass from pypy.interpreter.typedef import TypeDef from pypy.rpython.ootypesystem import ootype @@ -17,11 +17,11 @@ try: method = b_type.GetMethod(name, b_paramtypes) except AmbiguousMatchException: - msg = 'Multiple overloads for %s could match' % name - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = 'Multiple overloads for %s could match' + raise operationerrfmt(space.w_TypeError, msg, name) if method is None: - msg = 'No overloads for %s could match' % name - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = 'No overloads for %s could match' + raise operationerrfmt(space.w_TypeError, msg, name) return method def get_constructor(space, b_type, b_paramtypes): @@ -301,7 +301,8 @@ assembly_qualified_name = '%s, %s' % (fullname, assemblyname) b_type = System.Type.GetType(assembly_qualified_name) if b_type is None: - raise OperationError(space.w_ImportError, space.wrap("Cannot load .NET type: %s" % fullname)) + raise operationerrfmt(space.w_ImportError, + "Cannot load .NET type: %s", fullname) # this is where we locate the interfaces inherited by the class # set the flag hasIEnumerable if IEnumerable interface has been by the class Modified: pypy/trunk/pypy/module/imp/importing.py ============================================================================== --- pypy/trunk/pypy/module/imp/importing.py (original) +++ pypy/trunk/pypy/module/imp/importing.py Tue Jan 26 09:33:42 2010 @@ -6,7 +6,7 @@ from pypy.interpreter.module import Module from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root, ObjSpace from pypy.interpreter.eval import Code from pypy.rlib import streamio @@ -382,8 +382,8 @@ return None else: # ImportError - msg = "No module named %s" % modulename - raise OperationError(space.w_ImportError, w(msg)) + msg = "No module named %s" + raise operationerrfmt(space.w_ImportError, msg, modulename) def reload(space, w_module): """Reload the module. @@ -396,9 +396,9 @@ w_modulename = space.getattr(w_module, space.wrap("__name__")) modulename = space.str_w(w_modulename) if not space.is_w(check_sys_modules(space, w_modulename), w_module): - raise OperationError( + raise operationerrfmt( space.w_ImportError, - space.wrap("reload(): module %s not in sys.modules" % (modulename,))) + "reload(): module %s not in sys.modules", modulename) try: w_mod = space.reloading_modules[modulename] @@ -416,10 +416,10 @@ if parent_name: w_parent = check_sys_modules(space, space.wrap(parent_name)) if w_parent is None: - raise OperationError( + raise operationerrfmt( space.w_ImportError, - space.wrap("reload(): parent %s not in sys.modules" % ( - parent_name,))) + "reload(): parent %s not in sys.modules", + parent_name) w_path = space.getattr(w_parent, space.wrap("__path__")) else: w_path = None @@ -429,8 +429,8 @@ if not find_info: # ImportError - msg = "No module named %s" % modulename - raise OperationError(space.w_ImportError, space.wrap(msg)) + msg = "No module named %s" + raise operationerrfmt(space.w_ImportError, msg, modulename) try: try: @@ -677,8 +677,8 @@ w_code = space.call_method(w_marshal, 'loads', space.wrap(strbuf)) pycode = space.interpclass_w(w_code) if pycode is None or not isinstance(pycode, Code): - raise OperationError(space.w_ImportError, space.wrap( - "Non-code object in %s" % cpathname)) + raise operationerrfmt(space.w_ImportError, + "Non-code object in %s", cpathname) return pycode def load_compiled_module(space, w_modulename, w_mod, cpathname, magic, @@ -689,8 +689,8 @@ """ w = space.wrap if magic != get_pyc_magic(space): - raise OperationError(space.w_ImportError, w( - "Bad magic number in %s" % cpathname)) + raise operationerrfmt(space.w_ImportError, + "Bad magic number in %s", cpathname) #print "loading pyc file:", cpathname code_w = read_compiled_module(space, cpathname, source) exec_code_module(space, w_mod, code_w) Modified: pypy/trunk/pypy/module/imp/interp_imp.py ============================================================================== --- pypy/trunk/pypy/module/imp/interp_imp.py (original) +++ pypy/trunk/pypy/module/imp/interp_imp.py Tue Jan 26 09:33:42 2010 @@ -1,7 +1,7 @@ from pypy.module.imp import importing from pypy.module._file.interp_file import W_File from pypy.rlib import streamio -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.module import Module from pypy.interpreter.gateway import NoneNotWrapped import struct @@ -38,9 +38,9 @@ find_info = importing.find_module( space, name, w_name, name, w_path, use_loader=False) if not find_info: - raise OperationError( + raise operationerrfmt( space.w_ImportError, - space.wrap("No module named %s" % (name,))) + "No module named %s", name) w_filename = space.wrap(find_info.filename) stream = find_info.stream Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/trunk/pypy/module/pypyjit/interp_jit.py Tue Jan 26 09:33:42 2010 @@ -8,7 +8,7 @@ from pypy.rlib.rarithmetic import r_uint, intmask from pypy.rlib.jit import JitDriver, hint, we_are_jitted import pypy.interpreter.pyopcode # for side-effects -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, Arguments from pypy.interpreter.eval import Frame from pypy.interpreter.pycode import PyCode, CO_CONTAINSLOOP @@ -116,9 +116,8 @@ # XXXXXXXXX args_w, kwds_w = args.unpack() if len(args_w) > 1: - msg = ("set_param() takes at most 1 non-keyword argument, %d given" - % len(args_w)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "set_param() takes at most 1 non-keyword argument, %d given" + raise operationerrfmt(space.w_TypeError, msg, len(args_w)) if len(args_w) == 1: text = space.str_w(args_w[0]) try: @@ -131,7 +130,7 @@ try: pypyjitdriver.set_param(key, intval) except ValueError: - raise OperationError(space.w_TypeError, - space.wrap("no JIT parameter '%s'" % (key,))) + raise operationerrfmt(space.w_TypeError, + "no JIT parameter '%s'", key) set_param.unwrap_spec = [ObjSpace, Arguments] Modified: pypy/trunk/pypy/module/rctime/interp_time.py ============================================================================== --- pypy/trunk/pypy/module/rctime/interp_time.py (original) +++ pypy/trunk/pypy/module/rctime/interp_time.py Tue Jan 26 09:33:42 2010 @@ -1,6 +1,6 @@ from pypy.rpython.tool import rffi_platform as platform from pypy.rpython.lltypesystem import rffi -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root, ObjSpace from pypy.rpython.lltypesystem import lltype from pypy.rlib.rarithmetic import ovfcheck_float_to_int @@ -224,9 +224,9 @@ tup_w = space.fixedview(w_tup) if len(tup_w) != 9: - raise OperationError(space.w_TypeError, - space.wrap("argument must be sequence of " - "length 9, not %d" % len(tup_w))) + raise operationerrfmt(space.w_TypeError, + "argument must be sequence of " + "length 9, not %d", len(tup_w)) y = space.int_w(tup_w[0]) tm_mon = space.int_w(tup_w[1]) Modified: pypy/trunk/pypy/module/select/interp_select.py ============================================================================== --- pypy/trunk/pypy/module/select/interp_select.py (original) +++ pypy/trunk/pypy/module/select/interp_select.py Tue Jan 26 09:33:42 2010 @@ -2,7 +2,7 @@ from pypy.interpreter.typedef import TypeDef from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import W_Root, ObjSpace, interp2app -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rlib import rpoll defaultevents = rpoll.POLLIN | rpoll.POLLOUT | rpoll.POLLPRI @@ -28,8 +28,8 @@ fd = space.int_w(w_fd) if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file descriptor cannot be a negative integer (%d)"%fd)) + raise operationerrfmt(space.w_ValueError, + "file descriptor cannot be a negative integer (%d)", fd) return fd class Poll(Wrappable): @@ -47,7 +47,7 @@ del self.fddict[fd] except KeyError: raise OperationError(space.w_KeyError, - space.wrap(fd)) + space.wrap(fd)) # XXX should this maybe be w_fd? unregister.unwrap_spec = ['self', ObjSpace, W_Root] def poll(self, space, w_timeout=None): Modified: pypy/trunk/pypy/module/sys/__init__.py ============================================================================== --- pypy/trunk/pypy/module/sys/__init__.py (original) +++ pypy/trunk/pypy/module/sys/__init__.py Tue Jan 26 09:33:42 2010 @@ -116,7 +116,7 @@ if operror is None: return space.w_None else: - return operror.w_value + return operror.get_w_value(space) elif attr == 'exc_traceback': operror = space.getexecutioncontext().sys_exc_info() if operror is None: Modified: pypy/trunk/pypy/module/sys/vm.py ============================================================================== --- pypy/trunk/pypy/module/sys/vm.py (original) +++ pypy/trunk/pypy/module/sys/vm.py Tue Jan 26 09:33:42 2010 @@ -90,7 +90,7 @@ if operror is None: return space.newtuple([space.w_None,space.w_None,space.w_None]) else: - return space.newtuple([operror.w_type, operror.w_value, + return space.newtuple([operror.w_type, operror.get_w_value(space), space.wrap(operror.application_traceback)]) def exc_clear(space): Modified: pypy/trunk/pypy/module/thread/os_thread.py ============================================================================== --- pypy/trunk/pypy/module/thread/os_thread.py (original) +++ pypy/trunk/pypy/module/thread/os_thread.py Tue Jan 26 09:33:42 2010 @@ -4,7 +4,7 @@ from pypy.module.thread import ll_thread as thread from pypy.module.thread.error import wrap_thread_error -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments from pypy.rlib.objectmodel import free_non_gc_object @@ -198,8 +198,8 @@ old_size = thread.get_stacksize() error = thread.set_stacksize(size) if error == -1: - raise OperationError(space.w_ValueError, - space.wrap("size not valid: %d bytes" % size)) + raise operationerrfmt(space.w_ValueError, + "size not valid: %d bytes", size) if error == -2: raise wrap_thread_error(space, "setting stack size not supported") return space.wrap(old_size) Modified: pypy/trunk/pypy/module/zipimport/interp_zipimport.py ============================================================================== --- pypy/trunk/pypy/module/zipimport/interp_zipimport.py (original) +++ pypy/trunk/pypy/module/zipimport/interp_zipimport.py Tue Jan 26 09:33:42 2010 @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments -from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.module import Module @@ -257,7 +257,7 @@ w_mods = space.sys.get('modules') space.call_method(w_mods, 'pop', w(fullname), space.w_None) if last_exc: - raise OperationError(self.w_ZipImportError, last_exc.w_value) + raise OperationError(self.w_ZipImportError, last_exc.get_w_value(space)) # should never happen I think return space.w_None load_module.unwrap_spec = ['self', ObjSpace, str] @@ -288,8 +288,8 @@ w_code = space.builtin.call('compile', w_source, w(filename + ext), w('exec')) return w_code - raise OperationError(self.w_ZipImportError, space.wrap( - "Cannot find source or code for %s in %s" % (filename, self.name))) + raise operationerrfmt(self.w_ZipImportError, + "Cannot find source or code for %s in %s", filename, self.name) get_code.unwrap_spec = ['self', ObjSpace, str] def get_source(self, space, fullname): @@ -304,8 +304,8 @@ found = True if found: return space.w_None - raise OperationError(self.w_ZipImportError, space.wrap( - "Cannot find source for %s in %s" % (filename, self.name))) + raise operationerrfmt(self.w_ZipImportError, + "Cannot find source for %s in %s", filename, self.name) get_source.unwrap_spec = ['self', ObjSpace, str] def is_package(self, space, fullname): @@ -313,8 +313,8 @@ for _, is_package, ext in ENUMERATE_EXTS: if self.have_modulefile(space, filename + ext): return space.wrap(is_package) - raise OperationError(self.w_ZipImportError, space.wrap( - "Cannot find module %s in %s" % (filename, self.name))) + raise operationerrfmt(self.w_ZipImportError, + "Cannot find module %s in %s", filename, self.name) is_package.unwrap_spec = ['self', ObjSpace, str] def getarchive(space, self): @@ -335,28 +335,28 @@ try: s = os.stat(filename) except OSError: - raise OperationError(w_ZipImportError, space.wrap( - "Cannot find name %s" % (filename,))) + raise operationerrfmt(w_ZipImportError, + "Cannot find name %s", filename) if not stat.S_ISDIR(s.st_mode): ok = True break if not ok: - raise OperationError(w_ZipImportError, space.wrap( - "Did not find %s to be a valid zippath" % (name,))) + raise operationerrfmt(w_ZipImportError, + "Did not find %s to be a valid zippath", name) try: w_result = zip_cache.get(filename) if w_result is None: - raise OperationError(w_ZipImportError, space.wrap( + raise operationerrfmt(w_ZipImportError, "Cannot import %s from zipfile, recursion detected or" - "already tried and failed" % (name,))) + "already tried and failed", name) return w_result except KeyError: zip_cache.cache[filename] = None try: zip_file = RZipFile(filename, 'r') except (BadZipfile, OSError): - raise OperationError(w_ZipImportError, space.wrap( - "%s seems not to be a zipfile" % (filename,))) + raise operationerrfmt(w_ZipImportError, + "%s seems not to be a zipfile", filename) zip_file.close() prefix = name[len(filename):] if prefix.startswith(os.sep): Modified: pypy/trunk/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/pypy/objspace/descroperation.py (original) +++ pypy/trunk/pypy/objspace/descroperation.py Tue Jan 26 09:33:42 2010 @@ -1,5 +1,5 @@ import operator -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.function import Function, Method, FunctionWithFixedCode from pypy.interpreter.argument import Arguments @@ -24,10 +24,13 @@ w_type = space.type(w_obj) typename = w_type.getname(space, '?') if w_descr is None: - msg = "'%s' object has no attribute '%s'" % (typename, name) + raise operationerrfmt(space.w_AttributeError, + "'%s' object has no attribute '%s'", + typename, name) else: - msg = "'%s' object attribute '%s' is read-only" % (typename, name) - raise OperationError(space.w_AttributeError, space.wrap(msg)) + raise operationerrfmt(space.w_AttributeError, + "'%s' object attribute '%s' is read-only", + typename, name) class Object: def descr__getattribute__(space, w_obj, w_name): @@ -120,10 +123,10 @@ return w_obj.call_args(args) w_descr = space.lookup(w_obj, '__call__') if w_descr is None: - raise OperationError( - space.w_TypeError, - space.mod(space.wrap('object %r is not callable'), - space.newtuple([w_obj]))) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not callable", + typename) return space.get_and_call_args(w_descr, w_obj, args) def get(space, w_descr, w_obj, w_type=None): @@ -137,15 +140,19 @@ def set(space, w_descr, w_obj, w_val): w_set = space.lookup(w_descr, '__set__') if w_set is None: - raise OperationError(space.w_TypeError, - space.wrap("object is not a descriptor with set")) + typename = space.type(w_descr).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not a descriptor with set", + typename) return space.get_and_call_function(w_set, w_descr, w_obj, w_val) def delete(space, w_descr, w_obj): w_delete = space.lookup(w_descr, '__delete__') if w_delete is None: - raise OperationError(space.w_TypeError, - space.wrap("object is not a descriptor with delete")) + typename = space.type(w_descr).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not a descriptor with delete", + typename) return space.get_and_call_function(w_delete, w_descr, w_obj) def getattr(space, w_obj, w_name): @@ -169,15 +176,19 @@ def setattr(space, w_obj, w_name, w_val): w_descr = space.lookup(w_obj, '__setattr__') if w_descr is None: - raise OperationError(space.w_AttributeError, - space.wrap("object is readonly")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_AttributeError, + "'%s' object is readonly", + typename) return space.get_and_call_function(w_descr, w_obj, w_name, w_val) def delattr(space, w_obj, w_name): w_descr = space.lookup(w_obj, '__delattr__') if w_descr is None: - raise OperationError(space.w_AttributeError, - space.wrap("object does not support attribute removal")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_AttributeError, + "'%s' object does not support attribute removal", + typename) return space.get_and_call_function(w_descr, w_obj, w_name) def is_true(space, w_obj): @@ -215,37 +226,47 @@ if w_descr is None: w_descr = space.lookup(w_obj, '__getitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("iteration over non-sequence")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not iterable", + typename) return space.newseqiter(w_obj) return space.get_and_call_function(w_descr, w_obj) def next(space, w_obj): w_descr = space.lookup(w_obj, 'next') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("iterator has no next() method")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not an iterator", + typename) return space.get_and_call_function(w_descr, w_obj) def getitem(space, w_obj, w_key): w_descr = space.lookup(w_obj, '__getitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("cannot get items from object")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not subscriptable", + typename) return space.get_and_call_function(w_descr, w_obj, w_key) def setitem(space, w_obj, w_key, w_val): w_descr = space.lookup(w_obj, '__setitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("cannot set items on object")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object does not support item assignment", + typename) return space.get_and_call_function(w_descr, w_obj, w_key, w_val) def delitem(space, w_obj, w_key): w_descr = space.lookup(w_obj, '__delitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("cannot delete items from object")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object does not support item deletion", + typename) return space.get_and_call_function(w_descr, w_obj, w_key) def getslice(space, w_obj, w_start, w_stop): @@ -553,6 +574,8 @@ def _make_binop_impl(symbol, specialnames): left, right = specialnames + errormsg = "unsupported operand type(s) for %s: '%%s' and '%%s'" % ( + symbol.replace('%', '%%'),) def binop_impl(space, w_obj1, w_obj2): w_typ1 = space.type(w_obj1) @@ -592,8 +615,10 @@ w_res = _invoke_binop(space, w_right_impl, w_obj2, w_obj1) if w_res is not None: return w_res - raise OperationError(space.w_TypeError, - space.wrap("unsupported operand type(s) for %s" % symbol)) + typename1 = w_typ1.getname(space, '?') + typename2 = w_typ2.getname(space, '?') + raise operationerrfmt(space.w_TypeError, errormsg, + typename1, typename2) return func_with_new_name(binop_impl, "binop_%s_impl"%left.strip('_')) @@ -649,11 +674,12 @@ def _make_unaryop_impl(symbol, specialnames): specialname, = specialnames + errormsg = "unsupported operand type for unary %s: '%%s'" % symbol def unaryop_impl(space, w_obj): w_impl = space.lookup(w_obj, specialname) if w_impl is None: - raise OperationError(space.w_TypeError, - space.wrap("operand does not support unary %s" % symbol)) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, errormsg, typename) return space.get_and_call_function(w_impl, w_obj) return func_with_new_name(unaryop_impl, 'unaryop_%s_impl'%specialname.strip('_')) @@ -674,16 +700,17 @@ def %(targetname)s(space, w_obj): w_impl = space.lookup(w_obj, %(specialname)r) if w_impl is None: - raise OperationError(space.w_TypeError, - space.wrap("operand does not support unary %(targetname)s")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for %(targetname)s(): '%%s'", + typename) w_result = space.get_and_call_function(w_impl, w_obj) if %(checker)s: return w_result - typename = space.str_w(space.getattr(space.type(w_result), - space.wrap('__name__'))) - msg = '%(specialname)s returned non-%(targetname)s (type %%s)' %% (typename,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + typename = space.type(w_result).getname(space, '?') + msg = "%(specialname)s returned non-%(targetname)s (type '%%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) assert not hasattr(DescrOperation, %(targetname)r) DescrOperation.%(targetname)s = %(targetname)s del %(targetname)s @@ -700,8 +727,10 @@ def %(targetname)s(space, w_obj): w_impl = space.lookup(w_obj, %(specialname)r) if w_impl is None: - raise OperationError(space.w_TypeError, - space.wrap("operand does not support unary %(targetname)s")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for %(targetname)s(): '%%s'", + typename) w_result = space.get_and_call_function(w_impl, w_obj) if space.is_true(space.isinstance(w_result, space.w_str)): @@ -711,10 +740,9 @@ except OperationError, e: if not e.match(space, space.w_TypeError): raise - typename = space.str_w(space.getattr(space.type(w_result), - space.wrap('__name__'))) - msg = '%(specialname)s returned non-%(targetname)s (type %%s)' %% (typename,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + typename = space.type(w_result).getname(space, '?') + msg = "%(specialname)s returned non-%(targetname)s (type '%%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) else: # re-wrap the result as a real string return space.wrap(result) Modified: pypy/trunk/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/flowcontext.py (original) +++ pypy/trunk/pypy/objspace/flow/flowcontext.py Tue Jan 26 09:33:42 2010 @@ -276,7 +276,7 @@ raise Exception( 'found an operation that always raises %s: %s' % ( self.space.unwrap(e.w_type).__name__, - self.space.unwrap(e.w_value))) + self.space.unwrap(e.get_w_value(self.space)))) except ImplicitOperationError, e: if isinstance(e.w_type, Constant): @@ -290,12 +290,13 @@ self.recorder.crnt_block.closeblock(link) except OperationError, e: - #print "OE", e.w_type, e.w_value + #print "OE", e.w_type, e.get_w_value(self.space) if (self.space.do_imports_immediately and e.w_type is self.space.w_ImportError): raise ImportError('import statement always raises %s' % ( e,)) - link = self.make_link([e.w_type, e.w_value], self.graph.exceptblock) + w_value = e.get_w_value(self.space) + link = self.make_link([e.w_type, w_value], self.graph.exceptblock) self.recorder.crnt_block.closeblock(link) except StopFlowing: @@ -382,7 +383,8 @@ operr = ExecutionContext.sys_exc_info(self) if isinstance(operr, ImplicitOperationError): # re-raising an implicit operation makes it an explicit one - operr = OperationError(operr.w_type, operr.w_value) + w_value = operr.get_w_value(self.space) + operr = OperationError(operr.w_type, w_value) return operr def exception_trace(self, frame, operationerr): Modified: pypy/trunk/pypy/objspace/flow/framestate.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/framestate.py (original) +++ pypy/trunk/pypy/objspace/flow/framestate.py Tue Jan 26 09:33:42 2010 @@ -16,7 +16,7 @@ data.append(Constant(None)) else: data.append(state.last_exception.w_type) - data.append(state.last_exception.w_value) + data.append(state.last_exception.get_w_value(state.space)) recursively_flatten(state.space, data) self.mergeable = data self.nonmergeable = ( Modified: pypy/trunk/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/trunk/pypy/objspace/std/dictmultiobject.py Tue Jan 26 09:33:42 2010 @@ -1,6 +1,8 @@ -import py -from pypy.objspace.std.objspace import * +import py, sys +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.argument import Signature from pypy.module.__builtin__.__init__ import BUILTIN_TO_INDEX, OPTIMIZED_BUILTINS @@ -796,7 +798,9 @@ defaults = space.listview(w_defaults) len_defaults = len(defaults) if len_defaults > 1: - raise OperationError(space.w_TypeError, space.wrap("pop expected at most 2 arguments, got %d" % (1 + len_defaults, ))) + raise operationerrfmt(space.w_TypeError, + "pop expected at most 2 arguments, got %d", + 1 + len_defaults) w_item = w_dict.getitem(w_key) if w_item is None: if len_defaults > 0: Modified: pypy/trunk/pypy/objspace/std/listobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/listobject.py (original) +++ pypy/trunk/pypy/objspace/std/listobject.py Tue Jan 26 09:33:42 2010 @@ -1,4 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice @@ -282,9 +285,9 @@ else: assert delta==0 elif len2 != slicelength: # No resize for extended slices - raise OperationError(space.w_ValueError, space.wrap("attempt to " - "assign sequence of size %d to extended slice of size %d" % - (len2,slicelength))) + raise operationerrfmt(space.w_ValueError, "attempt to " + "assign sequence of size %d to extended slice of size %d", + len2, slicelength) if sequence2 is items: if step > 0: Modified: pypy/trunk/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/trunk/pypy/objspace/std/multimethod.py (original) +++ pypy/trunk/pypy/objspace/std/multimethod.py Tue Jan 26 09:33:42 2010 @@ -29,6 +29,10 @@ self.w_type = w_type self.w_value = w_value + def get_w_value(self, space): + # convenience: same semantics as with OperationError + return self.w_value + def __str__(self): return '' % (self.w_type, self.w_value) Modified: pypy/trunk/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/pypy/objspace/std/objecttype.py Tue Jan 26 09:33:42 2010 @@ -1,4 +1,4 @@ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.descroperation import Object from pypy.interpreter import gateway from pypy.interpreter.typedef import default_identity_hash @@ -31,9 +31,9 @@ def descr_set___class__(space, w_obj, w_newcls): from pypy.objspace.std.typeobject import W_TypeObject if not isinstance(w_newcls, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap("__class__ must be set to new-style class, not '%s' object" % - space.type(w_newcls).getname(space, '?'))) + raise operationerrfmt(space.w_TypeError, + "__class__ must be set to new-style class, not '%s' object", + space.type(w_newcls).getname(space, '?')) if not w_newcls.is_heaptype(): raise OperationError(space.w_TypeError, space.wrap("__class__ assignment: only for heap types")) @@ -43,9 +43,9 @@ if w_oldcls.get_full_instance_layout() == w_newcls.get_full_instance_layout(): w_obj.setclass(space, w_newcls) else: - raise OperationError(space.w_TypeError, - space.wrap("__class__ assignment: '%s' object layout differs from '%s'" % - (w_oldcls.getname(space, '?'), w_newcls.getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "__class__ assignment: '%s' object layout differs from '%s'", + w_oldcls.getname(space, '?'), w_newcls.getname(space, '?')) def descr__new__(space, w_type, __args__): Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Tue Jan 26 09:33:42 2010 @@ -1,6 +1,6 @@ from pypy.objspace.std.register_all import register_all from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, UnpackValueError -from pypy.interpreter.error import OperationError, debug_print +from pypy.interpreter.error import OperationError, operationerrfmt, debug_print from pypy.interpreter.typedef import get_unique_interplevel_subclass from pypy.interpreter import pyframe from pypy.interpreter import function @@ -143,9 +143,9 @@ ## print "CALL_LIKELY_BUILTIN fast" if w_value is None: varname = OPTIMIZED_BUILTINS[num] - message = "global name '%s' is not defined" % varname - raise OperationError(f.space.w_NameError, - f.space.wrap(message)) + message = "global name '%s' is not defined" + raise operationerrfmt(f.space.w_NameError, + message, varname) nargs = oparg & 0xff w_function = w_value try: @@ -559,9 +559,9 @@ assert isinstance(instance, cls) instance.user_setup(self, w_subtype) else: - raise OperationError(self.w_TypeError, - self.wrap("%s.__new__(%s): only for the type %s" % ( - w_type.name, w_subtype.getname(self, '?'), w_type.name))) + raise operationerrfmt(self.w_TypeError, + "%s.__new__(%s): only for the type %s", + w_type.name, w_subtype.getname(self, '?'), w_type.name) return instance allocate_instance._annspecialcase_ = "specialize:arg(1)" Modified: pypy/trunk/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeobject.py Tue Jan 26 09:33:42 2010 @@ -1,4 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.rlib.objectmodel import we_are_translated from pypy.objspace.std.inttype import wrapint @@ -281,10 +284,10 @@ if space.is_true(space.isinstance(w_s, space.w_unicode)): w_u = space.call_function(space.w_unicode, w_self) return space.call_method(w_u, "join", space.newlist(list_w)) - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("sequence item %d: expected string, %s " - "found" % (i, space.type(w_s).name))) + "sequence item %d: expected string, %s " + "found", i, space.type(w_s).getname(space, "?")) assert isinstance(w_s, W_RopeObject) node = w_s._node l.append(node) @@ -689,9 +692,8 @@ if ival < 0: ival += slen if ival < 0 or ival >= slen: - exc = space.call_function(space.w_IndexError, - space.wrap("string index out of range")) - raise OperationError(space.w_IndexError, exc) + raise OperationError(space.w_IndexError, + space.wrap("string index out of range")) return wrapchar(space, node.getchar(ival)) def getitem__Rope_Slice(space, w_str, w_slice): @@ -756,10 +758,10 @@ def ord__Rope(space, w_str): node = w_str._node if node.length() != 1: - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("ord() expected a character, but string " - "of length %d found"% (w_str._node.length(),))) + "ord() expected a character, but string " + "of length %d found", node.length()) return space.wrap(node.getint(0)) def getnewargs__Rope(space, w_str): Modified: pypy/trunk/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeunicodeobject.py Tue Jan 26 09:33:42 2010 @@ -1,4 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import _normalize_index @@ -24,11 +27,10 @@ encoding = getdefaultencoding(space) w_retval = decode_string(space, w_str, encoding, "strict") if not space.is_true(space.isinstance(w_retval, space.w_unicode)): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap( - "decoder did not return an unicode object (type=%s)" % - space.type(w_retval).getname(space, '?'))) + "decoder did not return an unicode object (type '%s')", + space.type(w_retval).getname(space, '?')) assert isinstance(w_retval, W_RopeUnicodeObject) return w_retval @@ -143,7 +145,7 @@ w_start = space.wrap(i) w_end = space.wrap(i+1) w_reason = space.wrap('invalid decimal Unicode string') - raise OperationError(space.w_UnicodeEncodeError,space.newtuple ([w_encoding, w_unistr, w_start, w_end, w_reason])) + raise OperationError(space.w_UnicodeEncodeError, space.newtuple([w_encoding, w_unistr, w_start, w_end, w_reason])) return ''.join(result) # string-to-unicode delegation @@ -252,9 +254,8 @@ elif space.is_true(space.isinstance(w_item, space.w_str)): item = unicode_from_string(space, w_item)._node else: - w_msg = space.mod(space.wrap('sequence item %d: expected string or Unicode'), - space.wrap(i)) - raise OperationError(space.w_TypeError, w_msg) + msg = 'sequence item %d: expected string or Unicode' + raise operationerrfmt(space.w_TypeError, msg, i) values_list.append(item) try: return W_RopeUnicodeObject(rope.join(w_self._node, values_list)) Modified: pypy/trunk/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stdtypedef.py (original) +++ pypy/trunk/pypy/objspace/std/stdtypedef.py Tue Jan 26 09:33:42 2010 @@ -1,5 +1,5 @@ from pypy.interpreter import gateway, baseobjspace, argument -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member from pypy.interpreter.typedef import descr_get_dict, descr_set_dict from pypy.interpreter.typedef import no_hash_descr, descr_del_dict @@ -141,16 +141,27 @@ prefix = typedef.name +'_mth'+prefix return prefix, list_of_typeorders -def typeerrormsg(space, operatorsymbol, args_w): - type_names = [ space.type(w_arg).getname(space, '?') for w_arg in args_w ] - if len(args_w) > 1: +def _gettypeerrormsg(nbargs): + if nbargs > 1: plural = 's' else: plural = '' - msg = "unsupported operand type%s for %s (%s)" % ( - plural, operatorsymbol, - ', '.join(type_names)) - return space.wrap(msg) + return "unsupported operand type%s for %%s: %s" % ( + plural, ', '.join(["'%s'"] * nbargs)) +_gettypeerrormsg._annspecialcase_ = 'specialize:memo' + +def _gettypenames(space, *args_w): + if args_w: + typename = space.type(args_w[-1]).getname(space, '?') + return _gettypenames(space, *args_w[:-1]) + (typename,) + return () +_gettypenames._always_inline_ = True + +def gettypeerror(space, operatorsymbol, *args_w): + msg = _gettypeerrormsg(len(args_w)) + type_names = _gettypenames(space, *args_w) + return operationerrfmt(space.w_TypeError, msg, + operatorsymbol, *type_names) def make_perform_trampoline(prefix, exprargs, expr, miniglobals, multimethod, selfindex=0, allow_NotImplemented_results=False): @@ -172,7 +183,7 @@ wrapper_arglist += multimethod.extras.get('extra_args', ()) miniglobals.update({ 'OperationError': OperationError, - 'typeerrormsg': typeerrormsg}) + 'gettypeerror': gettypeerror}) app_defaults = multimethod.extras.get('defaults', ()) i = len(argnames) - len(app_defaults) @@ -209,7 +220,7 @@ return %s except FailedToImplement, e: if e.w_type is not None: - raise OperationError(e.w_type, e.w_value) + raise OperationError(e.w_type, e.get_w_value(space)) else: return space.w_NotImplemented """ % (prefix, wrapper_sig, renaming, expr) @@ -221,10 +232,9 @@ w_res = %s except FailedToImplement, e: if e.w_type is not None: - raise OperationError(e.w_type, e.w_value) + raise OperationError(e.w_type, e.get_w_value(space)) else: - raise OperationError(space.w_TypeError, - typeerrormsg(space, %r, [%s])) + raise gettypeerror(space, %r, %s) if w_res is None: w_res = space.w_None return w_res Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Tue Jan 26 09:33:42 2010 @@ -1,6 +1,7 @@ -# -*- coding: latin-1 -*- - -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.rlib.rarithmetic import ovfcheck from pypy.rlib.objectmodel import we_are_translated, compute_hash @@ -365,11 +366,10 @@ w_list = space.newlist(list_w) w_u = space.call_function(space.w_unicode, w_self) return space.call_method(w_u, "join", w_list) - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("sequence item %d: expected string, %s " - "found" % (i, - space.type(w_s).getname(space, '?')))) + "sequence item %d: expected string, %s " + "found", i, space.type(w_s).getname(space, '?')) l[i] = space.str_w(w_s) return space.wrap(self.join(l)) else: @@ -816,9 +816,8 @@ if ival < 0: ival += slen if ival < 0 or ival >= slen: - exc = space.call_function(space.w_IndexError, - space.wrap("string index out of range")) - raise OperationError(space.w_IndexError, exc) + raise OperationError(space.w_IndexError, + space.wrap("string index out of range")) return wrapchar(space, str[ival]) def getitem__String_Slice(space, w_str, w_slice): @@ -857,9 +856,10 @@ try: buflen = ovfcheck(mul * input_len) except OverflowError: - raise OperationError( + raise operationerrfmt( space.w_OverflowError, - space.wrap("repeated string is too long: %d %d" % (input_len, mul))) + "repeated string is too long: %d times %d characters", + mul, input_len) # XXX maybe only do this when input has a big length return joined(space, [input] * mul) @@ -889,10 +889,10 @@ def ord__String(space, w_str): u_str = w_str._value if len(u_str) != 1: - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("ord() expected a character, but string " - "of length %d found"%(len(w_str._value),))) + "ord() expected a character, but string " + "of length %d found", len(u_str)) return space.wrap(ord(u_str)) def getnewargs__String(space, w_str): Modified: pypy/trunk/pypy/objspace/std/transparent.py ============================================================================== --- pypy/trunk/pypy/objspace/std/transparent.py (original) +++ pypy/trunk/pypy/objspace/std/transparent.py Tue Jan 26 09:33:42 2010 @@ -4,7 +4,7 @@ from pypy.interpreter import gateway from pypy.interpreter.function import Function -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.proxyobject import * from pypy.objspace.std.typeobject import W_TypeObject from pypy.rlib.objectmodel import r_dict @@ -52,8 +52,9 @@ for k, v in type_cache.cache: if w_lookup == k: return v(space, w_type, w_controller) - raise OperationError(space.w_TypeError, space.wrap("Object type %s could not "\ - "be wrapped (YET)" % w_type.getname(space, "?"))) + raise operationerrfmt(space.w_TypeError, + "'%s' object could not be wrapped (YET)", + w_type.getname(space, "?")) def register_proxyable(space, cls): tpdef = cls.typedef Modified: pypy/trunk/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/typeobject.py Tue Jan 26 09:33:42 2010 @@ -1,6 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import weakref_descr from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member from pypy.objspace.std.objecttype import object_typedef @@ -283,17 +284,17 @@ def check_user_subclass(w_self, w_subtype): space = w_self.space if not isinstance(w_subtype, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap("X is not a type object (%s)" % ( - space.type(w_subtype).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "X is not a type object ('%s')", + space.type(w_subtype).getname(space, '?')) if not space.is_true(space.issubtype(w_subtype, w_self)): - raise OperationError(space.w_TypeError, - space.wrap("%s.__new__(%s): %s is not a subtype of %s" % ( - w_self.name, w_subtype.name, w_subtype.name, w_self.name))) + raise operationerrfmt(space.w_TypeError, + "%s.__new__(%s): %s is not a subtype of %s", + w_self.name, w_subtype.name, w_subtype.name, w_self.name) if w_self.instancetypedef is not w_subtype.instancetypedef: - raise OperationError(space.w_TypeError, - space.wrap("%s.__new__(%s) is not safe, use %s.__new__()" % ( - w_self.name, w_subtype.name, w_subtype.name))) + raise operationerrfmt(space.w_TypeError, + "%s.__new__(%s) is not safe, use %s.__new__()", + w_self.name, w_subtype.name, w_subtype.name) return w_subtype def _freeze_(w_self): @@ -444,10 +445,10 @@ space.wrap("a new-style class can't have " "only classic bases")) if not w_bestbase.instancetypedef.acceptable_as_base_class: - raise OperationError(space.w_TypeError, - space.wrap("type '%s' is not an " - "acceptable base class" % - w_bestbase.instancetypedef.name)) + raise operationerrfmt(space.w_TypeError, + "type '%s' is not an " + "acceptable base class", + w_bestbase.instancetypedef.name) # check that all other bases' layouts are superclasses of the bestbase w_bestlayout = w_bestbase.w_same_layout_as or w_bestbase @@ -703,8 +704,9 @@ return space.get(w_value, space.w_None, w_type) if w_descr is not None: return space.get(w_descr,w_type) - msg = "type object '%s' has no attribute '%s'" %(w_type.name, name) - raise OperationError(space.w_AttributeError, space.wrap(msg)) + raise operationerrfmt(space.w_AttributeError, + "type object '%s' has no attribute '%s'", + w_type.name, name) def setattr__Type_ANY_ANY(space, w_type, w_name, w_value): # Note. This is exactly the same thing as descroperation.descr__setattr__, @@ -719,8 +721,8 @@ if (space.config.objspace.std.immutable_builtintypes and not w_type.is_heaptype()): - msg = "can't set attributes on type object '%s'" %(w_type.name,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "can't set attributes on type object '%s'" + raise operationerrfmt(space.w_TypeError, msg, w_type.name) if name == "__del__" and name not in w_type.dict_w: msg = "a __del__ method added to an existing type will not be called" space.warn(msg, space.w_RuntimeWarning) @@ -738,8 +740,8 @@ return if (space.config.objspace.std.immutable_builtintypes and not w_type.is_heaptype()): - msg = "can't delete attributes on type object '%s'" %(w_type.name,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "can't delete attributes on type object '%s'" + raise operationerrfmt(space.w_TypeError, msg, w_type.name) try: del w_type.dict_w[name] except KeyError: @@ -806,8 +808,9 @@ candidate = orderlists[-1][0] if candidate in orderlists[-1][1:]: # explicit error message for this specific case - raise OperationError(space.w_TypeError, - space.wrap("duplicate base class " + candidate.getname(space,"?"))) + raise operationerrfmt(space.w_TypeError, + "duplicate base class '%s'", + candidate.getname(space,"?")) while candidate not in cycle: cycle.append(candidate) nextblockinglist = mro_blockinglist(candidate, orderlists) Modified: pypy/trunk/pypy/objspace/std/typetype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typetype.py (original) +++ pypy/trunk/pypy/objspace/std/typetype.py Tue Jan 26 09:33:42 2010 @@ -1,4 +1,4 @@ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import weakref_descr @@ -51,18 +51,19 @@ def _precheck_for_new(space, w_type): from pypy.objspace.std.typeobject import W_TypeObject if not isinstance(w_type, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap("X is not a type object (%s)" % - (space.type(w_type).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "X is not a type object (%s)", + space.type(w_type).getname(space, '?')) return w_type # ____________________________________________________________ -def _check(space, w_type, msg=None): +def _check(space, w_type, w_msg=None): from pypy.objspace.std.typeobject import W_TypeObject if not isinstance(w_type, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap(msg or "descriptor is for 'type'")) + if w_msg is None: + w_msg = space.wrap("descriptor is for 'type'") + raise OperationError(space.w_TypeError, w_msg) return w_type @@ -73,9 +74,8 @@ def descr_set__name__(space, w_type, w_value): w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise OperationError(space.w_TypeError, - space.wrap("can't set %s.__name__" % - w_type.name)) + raise operationerrfmt(space.w_TypeError, + "can't set %s.__name__", w_type.name) w_type.name = space.str_w(w_value) def descr_get__mro__(space, w_type): @@ -84,7 +84,7 @@ def descr_mro(space, w_type): """Return a type's method resolution order.""" - w_type = _check(space, w_type,"expected type") + w_type = _check(space, w_type, space.wrap("expected type")) return space.newlist(w_type.compute_default_mro()) def descr_get__bases__(space, w_type): @@ -106,21 +106,18 @@ from pypy.objspace.std.typeobject import get_parent_layout w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise OperationError(space.w_TypeError, - space.wrap("can't set %s.__bases__" % - (w_type.name,))) + raise operationerrfmt(space.w_TypeError, + "can't set %s.__bases__", w_type.name) if not space.is_true(space.isinstance(w_value, space.w_tuple)): - raise OperationError(space.w_TypeError, - space.wrap("can only assign tuple" - " to %s.__bases__, not %s"% - (w_type.name, - space.type(w_value).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "can only assign tuple to %s.__bases__, not %s", + w_type.name, + space.type(w_value).getname(space, '?')) newbases_w = space.fixedview(w_value) if len(newbases_w) == 0: - raise OperationError(space.w_TypeError, - space.wrap("can only assign non-empty tuple" - " to %s.__bases__, not ()"% - (w_type.name,))) + raise operationerrfmt(space.w_TypeError, + "can only assign non-empty tuple to %s.__bases__, not ()", + w_type.name) for w_newbase in newbases_w: if isinstance(w_newbase, W_TypeObject): @@ -135,11 +132,11 @@ newlayout = w_newbestbase.get_full_instance_layout() if oldlayout != newlayout: - raise OperationError(space.w_TypeError, - space.wrap("__bases__ assignment: '%s' object layout" - " differs from '%s'" % - (w_newbestbase.getname(space, '?'), - w_oldbestbase.getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "__bases__ assignment: '%s' object layout" + " differs from '%s'", + w_newbestbase.getname(space, '?'), + w_oldbestbase.getname(space, '?')) # invalidate the version_tag of all the current subclasses w_type.mutated() @@ -191,9 +188,9 @@ def descr_set__module(space, w_type, w_value): w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise OperationError(space.w_TypeError, - space.wrap("can't set %s.__module__" % - w_type.name)) + raise operationerrfmt(space.w_TypeError, + "can't set %s.__module__", + w_type.name) w_type.mutated() w_type.dict_w['__module__'] = w_value Modified: pypy/trunk/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/unicodeobject.py Tue Jan 26 09:33:42 2010 @@ -1,5 +1,8 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.stringobject import W_StringObject, make_rsplit_with_delim from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.noneobject import W_NoneObject @@ -42,8 +45,9 @@ # Helper for converting int/long def unicode_to_decimal_w(space, w_unistr): if not isinstance(w_unistr, W_UnicodeObject): - raise OperationError(space.w_TypeError, - space.wrap("expected unicode")) + raise operationerrfmt(space.w_TypeError, + "expected unicode, got '%s'", + space.type(w_unistr).getname(space, '?')) unistr = w_unistr._value result = ['\0'] * len(unistr) digits = [ '0', '1', '2', '3', '4', @@ -63,7 +67,7 @@ w_start = space.wrap(i) w_end = space.wrap(i+1) w_reason = space.wrap('invalid decimal Unicode string') - raise OperationError(space.w_UnicodeEncodeError,space.newtuple ([w_encoding, w_unistr, w_start, w_end, w_reason])) + raise OperationError(space.w_UnicodeEncodeError, space.newtuple([w_encoding, w_unistr, w_start, w_end, w_reason])) return ''.join(result) # string-to-unicode delegation @@ -80,11 +84,11 @@ except OperationError, e: if e.match(space, space.w_UnicodeDecodeError): if inverse: - word = "unequal" + msg = "Unicode unequal comparison failed to convert both " \ + "arguments to Unicode - interpreting them as being unequal" else : - word = "equal" - msg = "Unicode %s comparison failed to convert both arguments\ - to Unicode - interpreting them as being unequal" % word + msg = "Unicode equal comparison failed to convert both " \ + "arguments to Unicode - interpreting them as being unequal" space.warn(msg, space.w_UnicodeWarning) return space.newbool(inverse) raise @@ -127,7 +131,9 @@ def ord__Unicode(space, w_uni): if len(w_uni._value) != 1: - raise OperationError(space.w_TypeError, space.wrap('ord() expected a character')) + raise operationerrfmt(space.w_TypeError, + "ord() expected a character, got a unicode of length %d", + len(w_uni._value)) return space.wrap(ord(w_uni._value[0])) def getnewargs__Unicode(space, w_uni): @@ -192,9 +198,8 @@ elif space.is_true(space.isinstance(item, space.w_str)): item = space.unicode_w(item) else: - w_msg = space.mod(space.wrap('sequence item %d: expected string or Unicode'), - space.wrap(i)) - raise OperationError(space.w_TypeError, w_msg) + raise operationerrfmt(space.w_TypeError, + "sequence item %d: expected string or Unicode", i) values_list[i] = item return W_UnicodeObject(w_self._value.join(values_list)) Modified: pypy/trunk/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodetype.py (original) +++ pypy/trunk/pypy/objspace/std/unicodetype.py Tue Jan 26 09:33:42 2010 @@ -2,7 +2,7 @@ from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all from pypy.objspace.std.basestringtype import basestring_typedef -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from sys import maxint @@ -181,11 +181,9 @@ w_restuple = space.call_function(w_encoder, w_object, w_errors) w_retval = space.getitem(w_restuple, space.wrap(0)) if not space.is_true(space.isinstance(w_retval, space.w_str)): - raise OperationError( - space.w_TypeError, - space.wrap( - "encoder did not return an string object (type=%s)" % - space.type(w_retval).getname(space, '?'))) + raise operationerrfmt(space.w_TypeError, + "encoder did not return an string object (type '%s')", + space.type(w_retval).getname(space, '?')) return w_retval def decode_object(space, w_obj, encoding, errors): @@ -204,11 +202,9 @@ def unicode_from_encoded_object(space, w_obj, encoding, errors): w_retval = decode_object(space, w_obj, encoding, errors) if not space.is_true(space.isinstance(w_retval, space.w_unicode)): - raise OperationError( - space.w_TypeError, - space.wrap( - "decoder did not return an unicode object (type=%s)" % - space.type(w_retval).getname(space, '?'))) + raise operationerrfmt(space.w_TypeError, + "decoder did not return an unicode object (type '%s')", + space.type(w_retval).getname(space, '?')) return w_retval def unicode_from_object(space, w_obj): Modified: pypy/trunk/pypy/objspace/test/test_descroperation.py ============================================================================== --- pypy/trunk/pypy/objspace/test/test_descroperation.py (original) +++ pypy/trunk/pypy/objspace/test/test_descroperation.py Tue Jan 26 09:33:42 2010 @@ -371,5 +371,14 @@ A() < B() assert l == [B, A, A, B] + def test_mod_failure(self): + try: + [] % 3 + except TypeError, e: + assert '%' in str(e) + else: + assert False, "did not raise" + + class AppTestWithBuiltinShortcut(AppTest_Descroperation): OPTIONS = {'objspace.std.builtinshortcut': True} Modified: pypy/trunk/pypy/tool/test/test_pytestsupport.py ============================================================================== --- pypy/trunk/pypy/tool/test/test_pytestsupport.py (original) +++ pypy/trunk/pypy/tool/test/test_pytestsupport.py Tue Jan 26 09:33:42 2010 @@ -41,7 +41,7 @@ f.call_args(Arguments(None, [])) except OperationError, e: assert e.match(space, space.w_AssertionError) - assert space.unwrap(space.str(e.w_value)) == 'assert 42 == 43' + assert space.unwrap(space.str(e.get_w_value(space))) == 'assert 42 == 43' else: assert False, "got no exception!" Modified: pypy/trunk/pypy/tool/traceop.py ============================================================================== --- pypy/trunk/pypy/tool/traceop.py (original) +++ pypy/trunk/pypy/tool/traceop.py Tue Jan 26 09:33:42 2010 @@ -273,7 +273,7 @@ # Special case - operation error if isinstance(obj, OperationError): return "OpError(%s, %s)" % (repr_value(space, obj.w_type), - repr_value(space, obj.w_value)) + repr_value(space, obj.get_w_value(space))) # Try object repr try: Modified: pypy/trunk/pypy/translator/geninterplevel.py ============================================================================== --- pypy/trunk/pypy/translator/geninterplevel.py (original) +++ pypy/trunk/pypy/translator/geninterplevel.py Tue Jan 26 09:33:42 2010 @@ -1366,7 +1366,7 @@ q = "elif" for op in self.gen_link(link, localscope, blocknum, block, { link.last_exception: 'e.w_type', - link.last_exc_value: 'e.w_value'}): + link.last_exc_value: 'e.get_w_value(space)'}): yield " %s" % op yield " else:raise # unhandled case, should not happen" else: Modified: pypy/trunk/pypy/translator/goal/sharedpypy.py ============================================================================== --- pypy/trunk/pypy/translator/goal/sharedpypy.py (original) +++ pypy/trunk/pypy/translator/goal/sharedpypy.py Tue Jan 26 09:33:42 2010 @@ -39,7 +39,7 @@ except OperationError, e: print "OperationError:" print " operror-type: " + e.w_type.getname(space, '?') - print " operror-value: " + space.str_w(space.str(e.w_value)) + print " operror-value: " + space.str_w(space.str(e.get_w_value(space))) return 1 return 0 Modified: pypy/trunk/pypy/translator/goal/targetpreimportedpypy.py ============================================================================== --- pypy/trunk/pypy/translator/goal/targetpreimportedpypy.py (original) +++ pypy/trunk/pypy/translator/goal/targetpreimportedpypy.py Tue Jan 26 09:33:42 2010 @@ -74,7 +74,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 finally: try: @@ -84,7 +84,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 space.timer.stop("Entrypoint") space.timer.dump() Modified: pypy/trunk/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/trunk/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/trunk/pypy/translator/goal/targetpypystandalone.py Tue Jan 26 09:33:42 2010 @@ -62,7 +62,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 finally: try: @@ -72,7 +72,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 space.timer.stop("Entrypoint") space.timer.dump() From arigo at codespeak.net Tue Jan 26 09:34:04 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 09:34:04 +0100 (CET) Subject: [pypy-svn] r70864 - pypy/branch/lazy-operr-format Message-ID: <20100126083404.4DDB61680B8@codespeak.net> Author: arigo Date: Tue Jan 26 09:34:03 2010 New Revision: 70864 Removed: pypy/branch/lazy-operr-format/ Log: Remove merged branch. From fijal at codespeak.net Tue Jan 26 09:55:52 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 26 Jan 2010 09:55:52 +0100 (CET) Subject: [pypy-svn] r70865 - in pypy/branch/stringbuilder2/pypy/rpython/lltypesystem: . test Message-ID: <20100126085552.041FA1680F3@codespeak.net> Author: fijal Date: Tue Jan 26 09:55:52 2010 New Revision: 70865 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py Log: Revert 70858, it seems something else is needed Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py Tue Jan 26 09:55:52 2010 @@ -103,11 +103,6 @@ Arena.object_arena_location[container] = self, offset Arena.old_object_arena_location[container] = self, offset - def shrink_obj(self, offset, newsize): - assert offset in self.objectptrs - assert newsize < self.objectsizes[offset] - self.objectsizes[offset] = newsize - class fakearenaaddress(llmemory.fakeaddress): def __init__(self, arena, offset): @@ -311,13 +306,6 @@ % (addr.offset,)) addr.arena.allocate_object(addr.offset, size) -def arena_shrink_obj(addr, newsize): - """ Mark object as shorter than it was - """ - addr = _getfakearenaaddress(addr) - bytes = llmemory.raw_malloc_usage(newsize) - addr.arena.shrink_obj(addr.offset, bytes) - def round_up_for_allocation(size, minsize=0): """Round up the size in order to preserve alignment of objects following an object. For arenas containing heterogenous objects. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py Tue Jan 26 09:55:52 2010 @@ -5,7 +5,6 @@ from pypy.rpython.lltypesystem.llarena import arena_reserve, arena_free from pypy.rpython.lltypesystem.llarena import round_up_for_allocation from pypy.rpython.lltypesystem.llarena import ArenaError, arena_new_view -from pypy.rpython.lltypesystem.llarena import arena_shrink_obj def test_arena(): S = lltype.Struct('S', ('x',lltype.Signed)) @@ -269,13 +268,3 @@ fn = compile(test_look_inside_object, []) res = fn() assert res == 42 - -def test_shrink_obj(): - S = lltype.Struct('S', ('x', lltype.Signed), - ('a', lltype.Array(lltype.Signed))) - myarenasize = 200 - a = arena_malloc(myarenasize, False) - arena_reserve(a, llmemory.sizeof(S, 10)) - arena_shrink_obj(a, llmemory.sizeof(S, 5)) - arena_reset(a + llmemory.sizeof(S, 5), llmemory.sizeof(S, 10), True) - arena_reserve(a + llmemory.sizeof(S, 5), llmemory.sizeof(S, 10)) From arigo at codespeak.net Tue Jan 26 10:04:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 10:04:03 +0100 (CET) Subject: [pypy-svn] r70866 - pypy/branch/stringbuilder2/pypy/rpython/memory/test Message-ID: <20100126090403.7E0691680F1@codespeak.net> Author: arigo Date: Tue Jan 26 10:04:03 2010 New Revision: 70866 Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Log: Improve the test until it fails in the same way as test_stringbuilder. Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Tue Jan 26 10:04:03 2010 @@ -473,20 +473,22 @@ from pypy.rpython.lltypesystem.rstr import STR GC_CAN_SHRINK_ARRAY = self.GC_CAN_SHRINK_ARRAY - def f(): - ptr = lltype.malloc(STR, 3) + def f(n, m): + ptr = lltype.malloc(STR, n) ptr.hash = 0x62 ptr.chars[0] = 'A' ptr.chars[1] = 'B' ptr.chars[2] = 'C' ptr2 = rgc.ll_shrink_array(ptr, 2) assert (ptr == ptr2) == GC_CAN_SHRINK_ARRAY + rgc.collect() return ( ord(ptr2.chars[0]) + (ord(ptr2.chars[1]) << 8) + (len(ptr2.chars) << 16) + (ptr2.hash << 24)) - assert self.interpret(f, []) == 0x62024241 + assert self.interpret(f, [3, 0]) == 0x62024241 + assert self.interpret(f, [12, 0]) == 0x62024241 def test_tagged_simple(self): from pypy.rlib.objectmodel import UnboxedValue From arigo at codespeak.net Tue Jan 26 10:17:25 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 10:17:25 +0100 (CET) Subject: [pypy-svn] r70867 - in pypy/branch/stringbuilder2/pypy/rpython/lltypesystem: . test Message-ID: <20100126091725.F3F2C1680F3@codespeak.net> Author: arigo Date: Tue Jan 26 10:17:24 2010 New Revision: 70867 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py Log: Re-checkin r70865, with the correct test. Fails probably for a shallow reason. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py Tue Jan 26 10:17:24 2010 @@ -103,6 +103,11 @@ Arena.object_arena_location[container] = self, offset Arena.old_object_arena_location[container] = self, offset + def shrink_obj(self, offset, newsize): + assert offset in self.objectptrs + assert newsize < self.objectsizes[offset] + self.objectsizes[offset] = newsize + class fakearenaaddress(llmemory.fakeaddress): def __init__(self, arena, offset): @@ -306,6 +311,13 @@ % (addr.offset,)) addr.arena.allocate_object(addr.offset, size) +def arena_shrink_obj(addr, newsize): + """ Mark object as shorter than it was + """ + addr = _getfakearenaaddress(addr) + bytes = llmemory.raw_malloc_usage(newsize) + addr.arena.shrink_obj(addr.offset, bytes) + def round_up_for_allocation(size, minsize=0): """Round up the size in order to preserve alignment of objects following an object. For arenas containing heterogenous objects. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py Tue Jan 26 10:17:24 2010 @@ -5,6 +5,7 @@ from pypy.rpython.lltypesystem.llarena import arena_reserve, arena_free from pypy.rpython.lltypesystem.llarena import round_up_for_allocation from pypy.rpython.lltypesystem.llarena import ArenaError, arena_new_view +from pypy.rpython.lltypesystem.llarena import arena_shrink_obj def test_arena(): S = lltype.Struct('S', ('x',lltype.Signed)) @@ -268,3 +269,13 @@ fn = compile(test_look_inside_object, []) res = fn() assert res == 42 + +def test_shrink_obj(): + S = lltype.Struct('S', ('x', lltype.Signed), + ('a', lltype.Array(lltype.Signed))) + myarenasize = 200 + a = arena_malloc(myarenasize, False) + arena_reserve(a, llmemory.sizeof(S, 10)) + arena_shrink_obj(a, llmemory.sizeof(S, 5)) + arena_reserve(a + llmemory.sizeof(S, 5), llmemory.sizeof(S, 10)) + arena_reset(a, llmemory.sizeof(S, 5), False) From arigo at codespeak.net Tue Jan 26 10:20:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 10:20:55 +0100 (CET) Subject: [pypy-svn] r70868 - pypy/branch/stringbuilder2/pypy/rpython/lltypesystem Message-ID: <20100126092055.CBCCC1680F3@codespeak.net> Author: arigo Date: Tue Jan 26 10:20:55 2010 New Revision: 70868 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py Log: Fix: forgot to update the 'usagemap'. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py Tue Jan 26 10:20:55 2010 @@ -105,8 +105,12 @@ def shrink_obj(self, offset, newsize): assert offset in self.objectptrs - assert newsize < self.objectsizes[offset] + oldsize = self.objectsizes[offset] + assert newsize <= oldsize self.objectsizes[offset] = newsize + for i in range(offset + newsize, offset + oldsize): + assert self.usagemap[i] == 'x' + self.usagemap[i] = '#' class fakearenaaddress(llmemory.fakeaddress): From arigo at codespeak.net Tue Jan 26 10:23:56 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 10:23:56 +0100 (CET) Subject: [pypy-svn] r70870 - pypy/branch/stringbuilder2/pypy/rpython/lltypesystem Message-ID: <20100126092356.B8CE31680B8@codespeak.net> Author: arigo Date: Tue Jan 26 10:23:56 2010 New Revision: 70870 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py Log: Implement arena_shrink_obj as a no-op after translation. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py Tue Jan 26 10:23:56 2010 @@ -476,6 +476,14 @@ llfakeimpl=arena_reserve, sandboxsafe=True) +def llimpl_arena_shrink_obj(addr, newsize): + pass +register_external(arena_shrink_obj, [llmemory.Address, int], None, + 'll_arena.arena_shrink_obj', + llimpl=llimpl_arena_shrink_obj, + llfakeimpl=arena_shrink_obj, + sandboxsafe=True) + llimpl_round_up_for_allocation = rffi.llexternal('ROUND_UP_FOR_ALLOCATION', [lltype.Signed, lltype.Signed], lltype.Signed, From arigo at codespeak.net Tue Jan 26 11:23:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 11:23:53 +0100 (CET) Subject: [pypy-svn] r70871 - in pypy/branch/stringbuilder2/pypy/rpython: lltypesystem lltypesystem/test memory/gc memory/test Message-ID: <20100126102353.9F0A816807B@codespeak.net> Author: arigo Date: Tue Jan 26 11:23:53 2010 New Revision: 70871 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Log: Fuh. Fix test_shrink_array. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llarena.py Tue Jan 26 11:23:53 2010 @@ -104,11 +104,17 @@ Arena.old_object_arena_location[container] = self, offset def shrink_obj(self, offset, newsize): - assert offset in self.objectptrs - oldsize = self.objectsizes[offset] - assert newsize <= oldsize - self.objectsizes[offset] = newsize - for i in range(offset + newsize, offset + oldsize): + oldbytes = self.objectsizes[offset] + newbytes = llmemory.raw_malloc_usage(newsize) + assert newbytes <= oldbytes + # fix self.objectsizes + for i in range(newbytes): + adr = offset + i + if adr in self.objectsizes: + assert self.objectsizes[adr] == oldbytes - i + self.objectsizes[adr] = newbytes - i + # fix self.usagemap + for i in range(offset + newbytes, offset + oldbytes): assert self.usagemap[i] == 'x' self.usagemap[i] = '#' @@ -319,8 +325,7 @@ """ Mark object as shorter than it was """ addr = _getfakearenaaddress(addr) - bytes = llmemory.raw_malloc_usage(newsize) - addr.arena.shrink_obj(addr.offset, bytes) + addr.arena.shrink_obj(addr.offset, newsize) def round_up_for_allocation(size, minsize=0): """Round up the size in order to preserve alignment of objects Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llarena.py Tue Jan 26 11:23:53 2010 @@ -271,11 +271,14 @@ assert res == 42 def test_shrink_obj(): - S = lltype.Struct('S', ('x', lltype.Signed), - ('a', lltype.Array(lltype.Signed))) + from pypy.rpython.memory.gcheader import GCHeaderBuilder + HDR = lltype.Struct('HDR', ('h', lltype.Signed)) + gcheaderbuilder = GCHeaderBuilder(HDR) + size_gc_header = gcheaderbuilder.size_gc_header + S = lltype.GcStruct('S', ('x', lltype.Signed), + ('a', lltype.Array(lltype.Signed))) myarenasize = 200 a = arena_malloc(myarenasize, False) - arena_reserve(a, llmemory.sizeof(S, 10)) - arena_shrink_obj(a, llmemory.sizeof(S, 5)) - arena_reserve(a + llmemory.sizeof(S, 5), llmemory.sizeof(S, 10)) - arena_reset(a, llmemory.sizeof(S, 5), False) + arena_reserve(a, size_gc_header + llmemory.sizeof(S, 10)) + arena_shrink_obj(a, size_gc_header + llmemory.sizeof(S, 5)) + arena_reset(a, size_gc_header + llmemory.sizeof(S, 5), False) Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/semispace.py Tue Jan 26 11:23:53 2010 @@ -119,11 +119,17 @@ self.free = result + llarena.round_up_for_allocation(totalsize) return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF) - def shrink_array(self, addr, smallersize): - if self._is_in_the_space(addr): + def shrink_array(self, addr, smallerlength): + size_gc_header = self.gcheaderbuilder.size_gc_header + if self._is_in_the_space(addr - size_gc_header): typeid = self.get_type_id(addr) + totalsmallersize = ( + size_gc_header + self.fixed_size(typeid) + + self.varsize_item_sizes(typeid) * smallerlength) + llarena.arena_shrink_obj(addr - size_gc_header, totalsmallersize) + # offset_to_length = self.varsize_offset_to_length(typeid) - (addr + offset_to_length).signed[0] = smallersize + (addr + offset_to_length).signed[0] = smallerlength return True else: return False Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/test/test_gc.py Tue Jan 26 11:23:53 2010 @@ -488,7 +488,11 @@ (ptr2.hash << 24)) assert self.interpret(f, [3, 0]) == 0x62024241 - assert self.interpret(f, [12, 0]) == 0x62024241 + # don't test with larger numbers of top of the Hybrid GC, because + # the default settings make it a too-large varsized object that + # gets allocated outside the semispace + if not isinstance(self, TestHybridGC): + assert self.interpret(f, [12, 0]) == 0x62024241 def test_tagged_simple(self): from pypy.rlib.objectmodel import UnboxedValue From fijal at codespeak.net Tue Jan 26 11:37:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 26 Jan 2010 11:37:20 +0100 (CET) Subject: [pypy-svn] r70872 - pypy/branch/stringbuilder2/pypy/rpython/lltypesystem Message-ID: <20100126103720.39CAE1680C1@codespeak.net> Author: fijal Date: Tue Jan 26 11:37:19 2010 New Revision: 70872 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll_str.py Log: Preallocate temp buffer. Not thread-safe, to be measured Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll_str.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll_str.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll_str.py Tue Jan 26 11:37:19 2010 @@ -4,13 +4,15 @@ CHAR_ARRAY = GcArray(Char) +# It's more efficient, but not thread safe! +temp = malloc(CHAR_ARRAY, 25) + def ll_int_str(repr, i): return ll_int2dec(i) ll_int_str._pure_function_ = True def ll_int2dec(i): from pypy.rpython.lltypesystem.rstr import mallocstr - temp = malloc(CHAR_ARRAY, 20) len = 0 sign = 0 if i < 0: @@ -47,7 +49,6 @@ def ll_int2hex(i, addPrefix): from pypy.rpython.lltypesystem.rstr import mallocstr - temp = malloc(CHAR_ARRAY, 20) len = 0 sign = 0 if i < 0: @@ -89,7 +90,6 @@ result.hash = 0 result.chars[0] = '0' return result - temp = malloc(CHAR_ARRAY, 25) len = 0 sign = 0 if i < 0: From fijal at codespeak.net Tue Jan 26 12:07:07 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 26 Jan 2010 12:07:07 +0100 (CET) Subject: [pypy-svn] r70873 - pypy/branch/stringbuilder2/pypy/rpython/lltypesystem Message-ID: <20100126110707.BB29216807A@codespeak.net> Author: fijal Date: Tue Jan 26 12:07:07 2010 New Revision: 70873 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll_str.py Log: Revert 70872. It requires separate thinking & branch Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll_str.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll_str.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/ll_str.py Tue Jan 26 12:07:07 2010 @@ -4,15 +4,13 @@ CHAR_ARRAY = GcArray(Char) -# It's more efficient, but not thread safe! -temp = malloc(CHAR_ARRAY, 25) - def ll_int_str(repr, i): return ll_int2dec(i) ll_int_str._pure_function_ = True def ll_int2dec(i): from pypy.rpython.lltypesystem.rstr import mallocstr + temp = malloc(CHAR_ARRAY, 20) len = 0 sign = 0 if i < 0: @@ -49,6 +47,7 @@ def ll_int2hex(i, addPrefix): from pypy.rpython.lltypesystem.rstr import mallocstr + temp = malloc(CHAR_ARRAY, 20) len = 0 sign = 0 if i < 0: @@ -90,6 +89,7 @@ result.hash = 0 result.chars[0] = '0' return result + temp = malloc(CHAR_ARRAY, 25) len = 0 sign = 0 if i < 0: From arigo at codespeak.net Tue Jan 26 12:46:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 12:46:53 +0100 (CET) Subject: [pypy-svn] r70874 - pypy/extradoc/planning Message-ID: <20100126114653.86EDE16807A@codespeak.net> Author: arigo Date: Tue Jan 26 12:46:53 2010 New Revision: 70874 Modified: pypy/extradoc/planning/jit.txt Log: This has been done. Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Tue Jan 26 12:46:53 2010 @@ -149,28 +149,3 @@ - ResOperation - ResumeGuardDescr - ConstInt - - -Plan for killing the hacks in executioncontext.py -------------------------------------------------- - -1. Finish support for virtualizables. We need a way to ask, - typically from a recursive residual call, for the structure - in some parent JITted context. So the virtualizable and - all virtuals need a way to be forced. The idea is to reuse - as much as possible the backend logic of guard failure and - the corresponding frontend logic to rebuild virtuals, but - called in this case indirectly, in the middle of running a - residual call. - -2. Reverting to the old logic without "f_forward", we need to - make "f_back" and "topframe" pointers that can reference - virtuals. Probably implemented by having them point to a - stub object that contains the stack position and the index - of the virtual in the list of virtuals. If we need to - access its content, we force it as above. For this to work, - we must make sure that no reference to such a stub can live - longer than the residual call -- either we are sure that it - dies, or we have forced it. - -Open question: how can this be done on CLI? From arigo at codespeak.net Tue Jan 26 12:52:41 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 12:52:41 +0100 (CET) Subject: [pypy-svn] r70875 - pypy/trunk/py/plugin Message-ID: <20100126115241.8FBE616807A@codespeak.net> Author: arigo Date: Tue Jan 26 12:52:41 2010 New Revision: 70875 Modified: pypy/trunk/py/plugin/pytest_terminal.py Log: Revert checkin by mistake. Modified: pypy/trunk/py/plugin/pytest_terminal.py ============================================================================== --- pypy/trunk/py/plugin/pytest_terminal.py (original) +++ pypy/trunk/py/plugin/pytest_terminal.py Tue Jan 26 12:52:41 2010 @@ -276,8 +276,8 @@ if len(repr_plugin)+26 > fullwidth: repr_plugin = repr_plugin[:(fullwidth-30)] + '...' self.write_line(" %-20s: %s" %(name, repr_plugin)) - #for i, testarg in enumerate(self.config.args): - # self.write_line("test object %d: %s" %(i+1, testarg)) + for i, testarg in enumerate(self.config.args): + self.write_line("test object %d: %s" %(i+1, testarg)) def pytest_sessionfinish(self, exitstatus, __multicall__): __multicall__.execute() From arigo at codespeak.net Tue Jan 26 13:11:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 13:11:53 +0100 (CET) Subject: [pypy-svn] r70876 - pypy/branch/stringbuilder2/pypy/translator/c/test Message-ID: <20100126121153.5079A318139@codespeak.net> Author: arigo Date: Tue Jan 26 13:11:52 2010 New Revision: 70876 Modified: pypy/branch/stringbuilder2/pypy/translator/c/test/test_boehm.py pypy/branch/stringbuilder2/pypy/translator/c/test/test_newgc.py Log: Fix these tests to check for rgc.ll_shrink_array(). Modified: pypy/branch/stringbuilder2/pypy/translator/c/test/test_boehm.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/test/test_boehm.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/test/test_boehm.py Tue Jan 26 13:11:52 2010 @@ -411,20 +411,25 @@ run = self.getcompiled(func) assert run() == 0 - def test_resizable_buffer(self): + def test_shrink_array(self): from pypy.rpython.lltypesystem.rstr import STR - from pypy.rpython.annlowlevel import hlstr from pypy.rlib import rgc def f(): - ptr = rgc.resizable_buffer_of_shape(STR, 2) - ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 200) - ptr.chars[1] = 'b' - return hlstr(rgc.finish_building_buffer(ptr, 2)) == "ab" + ptr = lltype.malloc(STR, 3) + ptr.hash = 0x62 + ptr.chars[0] = '0' + ptr.chars[1] = 'B' + ptr.chars[2] = 'C' + ptr2 = rgc.ll_shrink_array(ptr, 2) + return ((ptr == ptr2) + + ord(ptr2.chars[0]) + + (ord(ptr2.chars[1]) << 8) + + (len(ptr2.chars) << 16) + + (ptr2.hash << 24)) run = self.getcompiled(f) - assert run() == True + assert run() == 0x62024230 def test_assume_young_pointers_nop(self): S = lltype.GcStruct('S', ('x', lltype.Signed)) Modified: pypy/branch/stringbuilder2/pypy/translator/c/test/test_newgc.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/test/test_newgc.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/test/test_newgc.py Tue Jan 26 13:11:52 2010 @@ -20,6 +20,7 @@ taggedpointers = False GC_CAN_MOVE = False GC_CANNOT_MALLOC_NONMOVABLE = False + GC_CAN_SHRINK_ARRAY = False _isolated_func = None @@ -697,19 +698,28 @@ def define_resizable_buffer(cls): from pypy.rpython.lltypesystem.rstr import STR - from pypy.rpython.annlowlevel import hlstr def f(): - ptr = rgc.resizable_buffer_of_shape(STR, 2) - ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 200) - ptr.chars[1] = 'b' - return hlstr(rgc.finish_building_buffer(ptr, 2)) == "ab" - + ptr = lltype.malloc(STR, 3) + ptr.hash = 0x62 + ptr.chars[0] = '0' + ptr.chars[1] = 'B' + ptr.chars[2] = 'C' + ptr2 = rgc.ll_shrink_array(ptr, 2) + return ((ptr == ptr2) + + ord(ptr2.chars[0]) + + (ord(ptr2.chars[1]) << 8) + + (len(ptr2.chars) << 16) + + (ptr2.hash << 24)) return f def test_resizable_buffer(self): - assert self.run('resizable_buffer') + res = self.run('resizable_buffer') + if self.GC_CAN_SHRINK_ARRAY: + expected = 0x62024231 + else: + expected = 0x62024230 + assert res == expected def define_hash_preservation(cls): from pypy.rlib.objectmodel import compute_hash @@ -882,6 +892,7 @@ should_be_moving = True GC_CAN_MOVE = True GC_CANNOT_MALLOC_NONMOVABLE = True + GC_CAN_SHRINK_ARRAY = True # for snippets large_tests_ok = True @@ -1029,6 +1040,7 @@ class TestMarkCompactGC(TestSemiSpaceGC): gcpolicy = "markcompact" should_be_moving = True + GC_CAN_SHRINK_ARRAY = False def setup_class(cls): py.test.skip("Disabled for now") From arigo at codespeak.net Tue Jan 26 13:40:35 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 13:40:35 +0100 (CET) Subject: [pypy-svn] r70877 - pypy/branch/unroll-safe-if-const-arg Message-ID: <20100126124035.9276216807B@codespeak.net> Author: arigo Date: Tue Jan 26 13:40:34 2010 New Revision: 70877 Added: pypy/branch/unroll-safe-if-const-arg/ - copied from r70876, pypy/trunk/ Log: Create a branch to implement rlib.jit.unroll_safe_if_const_arg(). From arigo at codespeak.net Tue Jan 26 14:19:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 14:19:15 +0100 (CET) Subject: [pypy-svn] r70878 - in pypy/branch/unroll-safe-if-const-arg/pypy: jit/metainterp jit/metainterp/test rlib Message-ID: <20100126131915.885D016807B@codespeak.net> Author: arigo Date: Tue Jan 26 14:19:14 2010 New Revision: 70878 Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_codewriter.py pypy/branch/unroll-safe-if-const-arg/pypy/rlib/jit.py Log: Write the decorator, unroll_safe_if_const_arg(argpos). Support it in codewriter.py. Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py Tue Jan 26 14:19:14 2010 @@ -162,15 +162,22 @@ if getattr(funcobj, 'graph', None) is None: return 'residual' targetgraph = funcobj.graph - if (hasattr(targetgraph, 'func') and - hasattr(targetgraph.func, 'oopspec')): - return 'builtin' + if hasattr(targetgraph, 'func'): + if hasattr(targetgraph.func, 'oopspec'): + return 'builtin' + if hasattr(targetgraph.func, '_jit_unroll_safe_if_const_arg_'): + return 'unrollsafeif' elif op.opname == 'oosend': SELFTYPE, methname, opargs = support.decompose_oosend(op) if SELFTYPE.oopspec_name is not None: return 'builtin' - if self.graphs_from(op, is_candidate) is None: + graphs = self.graphs_from(op, is_candidate) + if graphs is None: return 'residual' + for graph in graphs: + if hasattr(graph, 'func'): + assert not hasattr(graph.func, 'oopspec') + assert not hasattr(graph.func, '_unroll_safe_if_const_arg_') return 'regular' def is_candidate(self, graph): @@ -1211,7 +1218,7 @@ kind = self.codewriter.guess_call_kind(op) return getattr(self, 'handle_%s_oosend' % kind)(op) - def handle_regular_call(self, op, oosend_methdescr=None): + def handle_regular_call(self, op, oosend_methdescr=None, if_const_arg=None): self.minimize_variables() [targetgraph] = self.codewriter.graphs_from(op) jitbox = self.codewriter.get_jitcode(targetgraph, self.graph, @@ -1220,12 +1227,29 @@ args = op.args else: args = op.args[1:] - self.emit('call') + if if_const_arg is None: + self.emit('call') + else: + self.emit('call_if_const_arg') + self.emit(if_const_arg) self.emit(self.get_position(jitbox)) self.emit_varargs([x for x in args if x.concretetype is not lltype.Void]) self.register_var(op.result) + def handle_unrollsafeif_call(self, op): + [targetgraph] = self.codewriter.graphs_from(op) + argpos = targetgraph.func._jit_unroll_safe_if_const_arg_ + assert isinstance(argpos, int) + # fix argpos to not count the None arguments + argpos2 = 0 + args = op.args[1:] + for v in args[:argpos]: + if v.concretetype is not lltype.Void: + argpos2 += 1 + assert args[argpos].concretetype is not lltype.Void + self.handle_regular_call(op, if_const_arg=argpos2) + def handle_residual_call(self, op, skip_last=False): self.minimize_variables() if skip_last: Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_codewriter.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_codewriter.py Tue Jan 26 14:19:14 2010 @@ -512,6 +512,25 @@ assert ConstInt(55) in jitcode.constants assert ConstInt(66) not in jitcode.constants + def test_unroll_safe_if_const_arg(self): + @jit.unroll_safe_if_const_arg(2) + def g(x, z, y): + while y > 0: + x += 2 + y -= 1 + return x + def f(x, z, y): + return g(x, z, y) + graphs = self.make_graphs(f, [3, None, 5]) + cw = CodeWriter(self.rtyper) + cw.candidate_graphs = graphs + cw._start(self.metainterp_sd, None) + jitcode = cw.make_one_bytecode((graphs[0], None), False) + assert 'call' not in jitcode._source + assert 'call_if_const_arg' in jitcode._source + index = jitcode._source.index('call_if_const_arg') + assert jitcode._source[index+1] == 1 # argpos without Nones + class ImmutableFieldsTests: Modified: pypy/branch/unroll-safe-if-const-arg/pypy/rlib/jit.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/rlib/jit.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/rlib/jit.py Tue Jan 26 14:19:14 2010 @@ -20,6 +20,13 @@ func._jit_unroll_safe_ = True return func +def unroll_safe_if_const_arg(argpos): + assert isinstance(argpos, int) + def _decorate(func): + func._jit_unroll_safe_if_const_arg_ = argpos + return func + return _decorate + def loop_invariant(func): dont_look_inside(func) func._jit_loop_invariant_ = True From arigo at codespeak.net Tue Jan 26 14:57:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 14:57:57 +0100 (CET) Subject: [pypy-svn] r70879 - in pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp: . test Message-ID: <20100126135757.405DF16807B@codespeak.net> Author: arigo Date: Tue Jan 26 14:57:56 2010 New Revision: 70879 Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/policy.py pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/pyjitpl.py pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_send.py Log: (fijal, cfbolz looking, arigo) Implement call_if_not_const in pyjitpl. Should be all. Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/codewriter.py Tue Jan 26 14:57:56 2010 @@ -102,7 +102,7 @@ continue kind = self.guess_call_kind(op, is_candidate) # use callers() to view the calling chain in pdb - if kind != "regular": + if kind != "regular" and kind != "unrollsafeif": continue for graph in self.graphs_from(op, is_candidate): if graph in seen: @@ -1230,6 +1230,7 @@ if if_const_arg is None: self.emit('call') else: + assert jitbox.calldescr is not None self.emit('call_if_const_arg') self.emit(if_const_arg) self.emit(self.get_position(jitbox)) Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/policy.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/policy.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/policy.py Tue Jan 26 14:57:56 2010 @@ -56,8 +56,9 @@ else: see_function = (self.look_inside_function(func) and not self._reject_function(func)) - contains_loop = contains_loop and not getattr( - func, '_jit_unroll_safe_', False) + contains_loop = (contains_loop + and not getattr(func, '_jit_unroll_safe_', False) + and not hasattr(func, '_jit_unroll_safe_if_const_arg_')) res = see_function and not contains_unsupported_variable_type(graph, self.supports_floats) Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/pyjitpl.py Tue Jan 26 14:57:56 2010 @@ -647,6 +647,15 @@ def opimpl_residual_call_loopinvariant(self, calldescr, varargs): return self.execute_varargs(rop.CALL_LOOPINVARIANT, varargs, calldescr, exc=True) + @arguments("int", "bytecode", "varargs") + def opimpl_call_if_const_arg(self, if_const_arg, callee, varargs): + if isinstance(varargs[if_const_arg], Const): + return self.perform_call(callee, varargs) + else: + assert callee.cfnptr is not None + return self.do_residual_call([callee.cfnptr] + varargs, + descr=callee.calldescr, exc=True) + @arguments("varargs") def opimpl_recursion_leave_prep(self, varargs): warmrunnerstate = self.metainterp.staticdata.state Modified: pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_send.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_send.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/jit/metainterp/test/test_send.py Tue Jan 26 14:57:56 2010 @@ -1,5 +1,6 @@ import py from pypy.rlib.jit import JitDriver, hint, purefunction +from pypy.rlib import jit from pypy.jit.metainterp.policy import StopAtXPolicy from pypy.rpython.ootypesystem import ootype from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin @@ -607,6 +608,29 @@ res = self.meta_interp(fn, [20], policy=StopAtXPolicy(extern)) assert res == 21 + def test_unroll_safe_if_const_arg(self): + myjitdriver = JitDriver(greens=['g'], reds = ['i', 'x']) + @jit.unroll_safe_if_const_arg(1) + def do_stuff(x, y): + while y > 0: + x += 2 + y -= 1 + return x + def fn(g, i): + x = 0 + while i > 0: + myjitdriver.can_enter_jit(g=g, i=i, x=x) + myjitdriver.jit_merge_point(g=g, i=i, x=x) + x = do_stuff(x, g) # unroll_safe + x = do_stuff(x, i) # not unroll_safe + i -= 1 + return x + res = self.meta_interp(fn, [10, 20]) + assert res == fn(10, 20) + # xxx we could get a call instead of a call_may_force, + # given enough efforts, but it seems not very useful in + # practice + self.check_loops(int_add=10, call_may_force=1) class TestOOtype(SendTests, OOJitMixin): pass From arigo at codespeak.net Tue Jan 26 15:11:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 15:11:26 +0100 (CET) Subject: [pypy-svn] r70880 - pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std Message-ID: <20100126141126.255A616807B@codespeak.net> Author: arigo Date: Tue Jan 26 15:11:25 2010 New Revision: 70880 Modified: pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/tupleobject.py Log: Add the jit.unroll_safe_if_const_arg decorator to "x in (tuple)" and to string formatting. Unsure if it's really a good idea in general in string formatting, we will try. Modified: pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py Tue Jan 26 15:11:25 2010 @@ -6,6 +6,7 @@ from pypy.interpreter.error import OperationError from pypy.tool.sourcetools import func_with_new_name from pypy.rlib.rstring import StringBuilder, UnicodeBuilder +from pypy.rlib import jit class BaseStringFormatter(object): def __init__(self, space, values_w, w_valuedict): @@ -142,10 +143,6 @@ class StringFormatter(BaseStringFormatter): - def __init__(self, space, fmt, values_w, w_valuedict): - BaseStringFormatter.__init__(self, space, values_w, w_valuedict) - self.fmt = fmt # either a string or a unicode - def peekchr(self): # return the 'current' character try: @@ -258,8 +255,10 @@ c = self.peekchr() return result - def format(self): - lgt = len(self.fmt) + 4 * len(self.values_w) + 10 + @jit.unroll_safe_if_const_arg(1) + def format(self, fmt): + self.fmt = fmt # either a string or a unicode + lgt = len(fmt) + 4 * len(self.values_w) + 10 if do_unicode: result = UnicodeBuilder(lgt) else: @@ -267,13 +266,9 @@ self.result = result while True: # fast path: consume as many characters as possible - fmt = self.fmt - i = i0 = self.fmtpos - while i < len(fmt): - if fmt[i] == '%': - break - i += 1 - else: + i0 = self.fmtpos + i = fmt.find('%', i0) + if i < 0: result.append_slice(fmt, i0, len(fmt)) break # end of 'fmt' string result.append_slice(fmt, i0, i) @@ -479,9 +474,9 @@ "Entry point" if not do_unicode: fmt = space.str_w(w_fmt) - formatter = StringFormatter(space, fmt, values_w, w_valuedict) + formatter = StringFormatter(space, values_w, w_valuedict) try: - result = formatter.format() + result = formatter.format(fmt) except NeedUnicodeFormattingError: # fall through to the unicode case fmt = unicode(fmt) @@ -489,8 +484,8 @@ return space.wrap(result) else: fmt = space.unicode_w(w_fmt) - formatter = UnicodeFormatter(space, fmt, values_w, w_valuedict) - result = formatter.format() + formatter = UnicodeFormatter(space, values_w, w_valuedict) + result = formatter.format(fmt) return space.wrap(result) def mod_format(space, w_format, w_values, do_unicode=False): Modified: pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/tupleobject.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/tupleobject.py Tue Jan 26 15:11:25 2010 @@ -4,6 +4,7 @@ from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.interpreter import gateway from pypy.rlib.debug import make_sure_not_resized +from pypy.rlib import jit class W_TupleObject(W_Object): from pypy.objspace.std.tupletype import tuple_typedef as typedef @@ -59,6 +60,7 @@ start, stop = normalize_simple_slice(space, length, w_start, w_stop) return W_TupleObject(w_tuple.wrappeditems[start:stop]) + at jit.unroll_safe_if_const_arg(1) def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): From fijal at codespeak.net Tue Jan 26 15:14:46 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 26 Jan 2010 15:14:46 +0100 (CET) Subject: [pypy-svn] r70881 - pypy/trunk/pypy/jit/metainterp/test Message-ID: <20100126141446.7FF311680B8@codespeak.net> Author: fijal Date: Tue Jan 26 15:14:45 2010 New Revision: 70881 Modified: pypy/trunk/pypy/jit/metainterp/test/test_warmspot.py Log: Fix a test Modified: pypy/trunk/pypy/jit/metainterp/test/test_warmspot.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_warmspot.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_warmspot.py Tue Jan 26 15:14:45 2010 @@ -317,6 +317,9 @@ supports_floats = False ts = llhelper translate_support_code = False + + def get_fail_descr_number(self, d): + return -1 def __init__(self, *args, **kwds): pass From fijal at codespeak.net Tue Jan 26 15:16:23 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 26 Jan 2010 15:16:23 +0100 (CET) Subject: [pypy-svn] r70882 - pypy/trunk/pypy/jit/backend/llgraph/test Message-ID: <20100126141623.2C8A31680B8@codespeak.net> Author: fijal Date: Tue Jan 26 15:16:22 2010 New Revision: 70882 Modified: pypy/trunk/pypy/jit/backend/llgraph/test/test_llgraph.py Log: Not sure what it was, but kill exploding & useless import Modified: pypy/trunk/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/trunk/pypy/jit/backend/llgraph/test/test_llgraph.py Tue Jan 26 15:16:22 2010 @@ -7,8 +7,7 @@ TreeLoop from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.metainterp.executor import execute -from pypy.jit.backend.test.runner_test import LLtypeBackendTest, \ - BaseAssemblerCallTests +from pypy.jit.backend.test.runner_test import LLtypeBackendTest class TestLLTypeLLGraph(LLtypeBackendTest): # for individual tests see: From arigo at codespeak.net Tue Jan 26 15:17:39 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 15:17:39 +0100 (CET) Subject: [pypy-svn] r70883 - pypy/branch/stringbuilder2/pypy/rpython/lltypesystem Message-ID: <20100126141739.419BA1680B8@codespeak.net> Author: arigo Date: Tue Jan 26 15:17:38 2010 New Revision: 70883 Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py Log: Fix for test_rbuilder: always use mallocstr/mallocunicode. Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/rbuilder.py Tue Jan 26 15:17:38 2010 @@ -59,7 +59,7 @@ ll_builder = lltype.malloc(cls.lowleveltype.TO) ll_builder.allocated = init_size ll_builder.used = 0 - ll_builder.buf = lltype.malloc(cls.basetp, init_size) + ll_builder.buf = cls.mallocfn(init_size) return ll_builder @staticmethod @@ -110,12 +110,14 @@ class StringBuilderRepr(BaseStringBuilderRepr): lowleveltype = lltype.Ptr(STRINGBUILDER) basetp = STR + mallocfn = staticmethod(rstr.mallocstr) string_repr = string_repr char_repr = char_repr class UnicodeBuilderRepr(BaseStringBuilderRepr): lowleveltype = lltype.Ptr(UNICODEBUILDER) basetp = UNICODE + mallocfn = staticmethod(rstr.mallocunicode) string_repr = unicode_repr char_repr = unichar_repr From arigo at codespeak.net Tue Jan 26 15:23:29 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 15:23:29 +0100 (CET) Subject: [pypy-svn] r70884 - in pypy/branch/stringbuilder2: lib-python/modified-2.5.2/test lib-python/modified-2.5.2/test/output pypy/interpreter pypy/interpreter/test pypy/jit/backend/llgraph/test pypy/jit/metainterp/test pypy/module/__builtin__ pypy/module/_codecs pypy/module/_file pypy/module/_rawffi pypy/module/_socket pypy/module/_stackless pypy/module/bz2 pypy/module/clr pypy/module/imp pypy/module/pypyjit pypy/module/rctime pypy/module/select pypy/module/sys pypy/module/thread pypy/module/zipimport pypy/objspace pypy/objspace/flow pypy/objspace/std pypy/objspace/test pypy/tool pypy/tool/test pypy/translator pypy/translator/goal Message-ID: <20100126142329.383611680A3@codespeak.net> Author: arigo Date: Tue Jan 26 15:23:26 2010 New Revision: 70884 Added: pypy/branch/stringbuilder2/pypy/interpreter/test/test_error.py - copied unchanged from r70883, pypy/trunk/pypy/interpreter/test/test_error.py Modified: pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/output/test_extcall pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_genexps.py pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_unpack.py pypy/branch/stringbuilder2/pypy/interpreter/argument.py pypy/branch/stringbuilder2/pypy/interpreter/baseobjspace.py pypy/branch/stringbuilder2/pypy/interpreter/error.py pypy/branch/stringbuilder2/pypy/interpreter/executioncontext.py pypy/branch/stringbuilder2/pypy/interpreter/function.py pypy/branch/stringbuilder2/pypy/interpreter/main.py pypy/branch/stringbuilder2/pypy/interpreter/pycompiler.py pypy/branch/stringbuilder2/pypy/interpreter/pyframe.py pypy/branch/stringbuilder2/pypy/interpreter/pyopcode.py pypy/branch/stringbuilder2/pypy/interpreter/test/test_argument.py pypy/branch/stringbuilder2/pypy/interpreter/test/test_compiler.py pypy/branch/stringbuilder2/pypy/interpreter/typedef.py pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/test/test_llgraph.py pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmspot.py pypy/branch/stringbuilder2/pypy/module/__builtin__/descriptor.py pypy/branch/stringbuilder2/pypy/module/__builtin__/interp_classobj.py pypy/branch/stringbuilder2/pypy/module/_codecs/interp_codecs.py pypy/branch/stringbuilder2/pypy/module/_file/interp_file.py pypy/branch/stringbuilder2/pypy/module/_rawffi/interp_rawffi.py pypy/branch/stringbuilder2/pypy/module/_rawffi/structure.py pypy/branch/stringbuilder2/pypy/module/_socket/interp_func.py pypy/branch/stringbuilder2/pypy/module/_stackless/interp_coroutine.py pypy/branch/stringbuilder2/pypy/module/_stackless/interp_greenlet.py pypy/branch/stringbuilder2/pypy/module/bz2/interp_bz2.py pypy/branch/stringbuilder2/pypy/module/clr/interp_clr.py pypy/branch/stringbuilder2/pypy/module/imp/importing.py pypy/branch/stringbuilder2/pypy/module/imp/interp_imp.py pypy/branch/stringbuilder2/pypy/module/pypyjit/interp_jit.py pypy/branch/stringbuilder2/pypy/module/rctime/interp_time.py pypy/branch/stringbuilder2/pypy/module/select/interp_select.py pypy/branch/stringbuilder2/pypy/module/sys/__init__.py pypy/branch/stringbuilder2/pypy/module/sys/vm.py pypy/branch/stringbuilder2/pypy/module/thread/os_thread.py pypy/branch/stringbuilder2/pypy/module/zipimport/interp_zipimport.py pypy/branch/stringbuilder2/pypy/objspace/descroperation.py pypy/branch/stringbuilder2/pypy/objspace/flow/flowcontext.py pypy/branch/stringbuilder2/pypy/objspace/flow/framestate.py pypy/branch/stringbuilder2/pypy/objspace/std/dictmultiobject.py pypy/branch/stringbuilder2/pypy/objspace/std/listobject.py pypy/branch/stringbuilder2/pypy/objspace/std/multimethod.py pypy/branch/stringbuilder2/pypy/objspace/std/objecttype.py pypy/branch/stringbuilder2/pypy/objspace/std/objspace.py pypy/branch/stringbuilder2/pypy/objspace/std/ropeobject.py pypy/branch/stringbuilder2/pypy/objspace/std/ropeunicodeobject.py pypy/branch/stringbuilder2/pypy/objspace/std/stdtypedef.py pypy/branch/stringbuilder2/pypy/objspace/std/stringobject.py pypy/branch/stringbuilder2/pypy/objspace/std/transparent.py pypy/branch/stringbuilder2/pypy/objspace/std/typeobject.py pypy/branch/stringbuilder2/pypy/objspace/std/typetype.py pypy/branch/stringbuilder2/pypy/objspace/std/unicodeobject.py pypy/branch/stringbuilder2/pypy/objspace/std/unicodetype.py pypy/branch/stringbuilder2/pypy/objspace/test/test_descroperation.py pypy/branch/stringbuilder2/pypy/tool/test/test_pytestsupport.py pypy/branch/stringbuilder2/pypy/tool/traceop.py pypy/branch/stringbuilder2/pypy/translator/geninterplevel.py pypy/branch/stringbuilder2/pypy/translator/goal/sharedpypy.py pypy/branch/stringbuilder2/pypy/translator/goal/targetpreimportedpypy.py pypy/branch/stringbuilder2/pypy/translator/goal/targetpypystandalone.py Log: Merge trunk again: svn merge -r70836:HEAD svn+ssh://codespeak.net/svn/pypy/trunk . Modified: pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/output/test_extcall ============================================================================== --- pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/output/test_extcall (original) +++ pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/output/test_extcall Tue Jan 26 15:23:26 2010 @@ -25,9 +25,9 @@ got multiple values for keyword argument 'b' keywords must be strings h() got an unexpected keyword argument 'e' -iteration over non-sequence -iteration over non-sequence -iteration over non-sequence +'function' object is not iterable +'function' object is not iterable +'function' object is not iterable argument after ** must be a dictionary argument after ** must be a dictionary argument after ** must be a dictionary Modified: pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_genexps.py ============================================================================== --- pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_genexps.py (original) +++ pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_genexps.py Tue Jan 26 15:23:26 2010 @@ -109,7 +109,7 @@ Traceback (most recent call last): File "", line 1, in -toplevel- (i for i in 6) - TypeError: iteration over non-sequence + TypeError: 'int' object is not iterable Verify late binding for the outermost if-expression Modified: pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_unpack.py ============================================================================== --- pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_unpack.py (original) +++ pypy/branch/stringbuilder2/lib-python/modified-2.5.2/test/test_unpack.py Tue Jan 26 15:23:26 2010 @@ -55,7 +55,7 @@ >>> a, b, c = 7 Traceback (most recent call last): ... - TypeError: iteration over non-sequence + TypeError: 'int' object is not iterable Unpacking tuple of wrong size Modified: pypy/branch/stringbuilder2/pypy/interpreter/argument.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/argument.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/argument.py Tue Jan 26 15:23:26 2010 @@ -2,7 +2,7 @@ Arguments objects. """ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rlib.debug import make_sure_not_resized from pypy.rlib import jit @@ -160,10 +160,10 @@ raise OperationError(space.w_TypeError, space.wrap("keywords must be strings")) if self.keywords and key in self.keywords: - raise OperationError(self.space.w_TypeError, - self.space.wrap("got multiple values " - "for keyword argument " - "'%s'" % key)) + raise operationerrfmt(self.space.w_TypeError, + "got multiple values " + "for keyword argument " + "'%s'", key) keywords[i] = key keywords_w[i] = space.getitem(w_starstararg, w_key) i += 1 Modified: pypy/branch/stringbuilder2/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/baseobjspace.py Tue Jan 26 15:23:26 2010 @@ -1,6 +1,6 @@ from pypy.interpreter.executioncontext import ExecutionContext, ActionFlag from pypy.interpreter.executioncontext import UserDelAction, FrameTraceAction -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.argument import Arguments from pypy.interpreter.pycompiler import CPythonCompiler, PythonAstCompiler from pypy.interpreter.miscutils import ThreadLocals @@ -54,9 +54,9 @@ def setdict(self, space, w_dict): typename = space.type(self).getname(space, '?') - raise OperationError(space.w_TypeError, - space.wrap("attribute '__dict__' of %s objects " - "is not writable" % typename)) + raise operationerrfmt(space.w_TypeError, + "attribute '__dict__' of %s objects " + "is not writable", typename) # to be used directly only by space.type implementations def getclass(self, space): @@ -112,9 +112,9 @@ classname = '?' else: classname = wrappable_class_name(RequiredClass) - msg = "'%s' object expected, got '%s' instead" % ( + msg = "'%s' object expected, got '%s' instead" + raise operationerrfmt(space.w_TypeError, msg, classname, self.getclass(space).getname(space, '?')) - raise OperationError(space.w_TypeError, space.wrap(msg)) # used by _weakref implemenation @@ -123,8 +123,8 @@ def setweakref(self, space, weakreflifeline): typename = space.type(self).getname(space, '?') - raise OperationError(space.w_TypeError, space.wrap( - "cannot create weak reference to '%s' object" % typename)) + raise operationerrfmt(space.w_TypeError, + "cannot create weak reference to '%s' object", typename) def clear_all_weakrefs(self): """Call this at the beginning of interp-level __del__() methods @@ -366,10 +366,10 @@ try: w_mod = self.builtin_modules[name] except KeyError: - raise OperationError( + raise operationerrfmt( self.w_SystemError, - self.wrap("getbuiltinmodule() called " - "with non-builtin module %s" % name)) + "getbuiltinmodule() called " + "with non-builtin module %s", name) else: # Add the module to sys.modules self.setitem(w_modules, w_name, w_mod) @@ -693,10 +693,10 @@ return None obj = self.interpclass_w(w_obj) if not isinstance(obj, RequiredClass): # or obj is None - msg = "'%s' object expected, got '%s' instead" % ( + msg = "'%s' object expected, got '%s' instead" + raise operationerrfmt(self.w_TypeError, msg, wrappable_class_name(RequiredClass), w_obj.getclass(self).getname(self, '?')) - raise OperationError(self.w_TypeError, self.wrap(msg)) return obj interp_w._annspecialcase_ = 'specialize:arg(1)' @@ -825,7 +825,8 @@ try: w_res = self.call_args(w_func, args) except OperationError, e: - ec.c_exception_trace(frame, e.w_value) + w_value = e.get_w_value(self) + ec.c_exception_trace(frame, w_value) raise ec.c_return_trace(frame, w_func) return w_res @@ -997,9 +998,9 @@ except OperationError, err: if objdescr is None or not err.match(self, self.w_TypeError): raise - msg = "%s must be an integer, not %s" % ( + msg = "%s must be an integer, not %s" + raise operationerrfmt(self.w_TypeError, msg, objdescr, self.type(w_obj).getname(self, '?')) - raise OperationError(self.w_TypeError, self.wrap(msg)) try: index = self.int_w(w_index) except OperationError, err: @@ -1012,10 +1013,10 @@ else: return sys.maxint else: - raise OperationError( - w_exception, self.wrap( + raise operationerrfmt( + w_exception, "cannot fit '%s' into an index-sized " - "integer" % self.type(w_obj).getname(self, '?'))) + "integer", self.type(w_obj).getname(self, '?')) else: return index Modified: pypy/branch/stringbuilder2/pypy/interpreter/error.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/error.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/error.py Tue Jan 26 15:23:26 2010 @@ -16,20 +16,26 @@ PyTraceback objects making the application-level traceback. """ + _w_value = None + application_traceback = None + def __init__(self, w_type, w_value, tb=None): - if w_type is None: + if not we_are_translated() and w_type is None: from pypy.tool.error import FlowingError raise FlowingError(w_value) - self.w_type = w_type - self.w_value = w_value + self.setup(w_type) + self._w_value = w_value self.application_traceback = tb + + def setup(self, w_type): + self.w_type = w_type if not we_are_translated(): self.debug_excs = [] def clear(self, space): # for sys.exc_clear() self.w_type = space.w_None - self.w_value = space.w_None + self._w_value = space.w_None self.application_traceback = None if not we_are_translated(): del self.debug_excs[:] @@ -45,14 +51,18 @@ def __str__(self): "NOT_RPYTHON: Convenience for tracebacks." - return '[%s: %s]' % (self.w_type, self.w_value) + s = self._w_value + if self.__class__ is not OperationError and s is None: + s = self._compute_value() + return '[%s: %s]' % (self.w_type, s) def errorstr(self, space): "The exception class and value, as a string." + w_value = self.get_w_value(space) if space is None: # this part NOT_RPYTHON exc_typename = str(self.w_type) - exc_value = str(self.w_value) + exc_value = str(w_value) else: w = space.wrap if space.is_w(space.type(self.w_type), space.w_str): @@ -60,11 +70,11 @@ else: exc_typename = space.str_w( space.getattr(self.w_type, w('__name__'))) - if space.is_w(self.w_value, space.w_None): + if space.is_w(w_value, space.w_None): exc_value = "" else: try: - exc_value = space.str_w(space.str(self.w_value)) + exc_value = space.str_w(space.str(w_value)) except OperationError: # oups, cannot __str__ the exception object exc_value = "" @@ -165,7 +175,7 @@ # (inst, None) (inst.__class__, inst) no # w_type = self.w_type - w_value = self.w_value + w_value = self.get_w_value(space) if space.full_exceptions: while space.is_true(space.isinstance(w_type, space.w_tuple)): w_type = space.getitem(w_type, space.wrap(0)) @@ -204,8 +214,8 @@ if not space.exception_is_valid_class_w(w_instclass): instclassname = w_instclass.getname(space, '?') msg = ("exceptions must be classes, or instances, " - "or strings (deprecated), not %s" % (instclassname,)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + "or strings (deprecated), not %s") + raise operationerrfmt(space.w_TypeError, msg, instclassname) if not space.is_w(w_value, space.w_None): raise OperationError(space.w_TypeError, @@ -214,8 +224,8 @@ w_value = w_inst w_type = w_instclass - self.w_type = w_type - self.w_value = w_value + self.w_type = w_type + self._w_value = w_value def write_unraisable(self, space, where, w_object=None): if w_object is None: @@ -232,6 +242,94 @@ except OperationError: pass # ignored + def get_w_value(self, space): + w_value = self._w_value + if w_value is None: + value = self._compute_value() + self._w_value = w_value = space.wrap(value) + return w_value + + def _compute_value(self): + raise NotImplementedError + +# ____________________________________________________________ +# optimization only: avoid the slowest operation -- the string +# formatting with '%' -- in the common case were we don't +# actually need the message. Only supports %s and %d. + +_fmtcache = {} +_fmtcache2 = {} + +def decompose_valuefmt(valuefmt): + """Returns a tuple of string parts extracted from valuefmt, + and a tuple of format characters.""" + formats = [] + parts = valuefmt.split('%') + i = 1 + while i < len(parts): + if parts[i].startswith('s') or parts[i].startswith('d'): + formats.append(parts[i][0]) + parts[i] = parts[i][1:] + i += 1 + elif parts[i] == '': # support for '%%' + parts[i-1] += '%' + parts[i+1] + del parts[i:i+2] + else: + raise ValueError("invalid format string (only %s or %d supported)") + assert len(formats) > 0, "unsupported: no % command found" + return tuple(parts), tuple(formats) + +def get_operrcls2(valuefmt): + strings, formats = decompose_valuefmt(valuefmt) + assert len(strings) == len(formats) + 1 + try: + OpErrFmt = _fmtcache2[formats] + except KeyError: + from pypy.rlib.unroll import unrolling_iterable + attrs = ['x%d' % i for i in range(len(formats))] + entries = unrolling_iterable(enumerate(attrs)) + # + class OpErrFmt(OperationError): + def __init__(self, w_type, strings, *args): + self.setup(w_type) + assert len(args) == len(strings) - 1 + self.xstrings = strings + for i, attr in entries: + setattr(self, attr, args[i]) + if not we_are_translated() and w_type is None: + from pypy.tool.error import FlowingError + raise FlowingError(self._compute_value()) + def _compute_value(self): + lst = [None] * (len(formats) + len(formats) + 1) + for i, attr in entries: + string = self.xstrings[i] + value = getattr(self, attr) + lst[i+i] = string + lst[i+i+1] = str(value) + lst[-1] = self.xstrings[-1] + return ''.join(lst) + # + _fmtcache2[formats] = OpErrFmt + return OpErrFmt, strings + +def get_operationerr_class(valuefmt): + try: + result = _fmtcache[valuefmt] + except KeyError: + result = _fmtcache[valuefmt] = get_operrcls2(valuefmt) + return result +get_operationerr_class._annspecialcase_ = 'specialize:memo' + +def operationerrfmt(w_type, valuefmt, *args): + """Equivalent to OperationError(w_type, space.wrap(valuefmt % args)). + More efficient in the (common) case where the value is not actually + needed.""" + OpErrFmt, strings = get_operationerr_class(valuefmt) + return OpErrFmt(w_type, strings, *args) +operationerrfmt._annspecialcase_ = 'specialize:arg(1)' + +# ____________________________________________________________ + # Utilities from pypy.tool.ansi_print import ansi_print @@ -277,16 +375,3 @@ space.wrap(msg)) return OperationError(exc, w_error) wrap_oserror._annspecialcase_ = 'specialize:arg(2)' - -### installing the excepthook for OperationErrors -##def operr_excepthook(exctype, value, traceback): -## if issubclass(exctype, OperationError): -## value.debug_excs.append((exctype, value, traceback)) -## value.print_detailed_traceback() -## else: -## old_excepthook(exctype, value, traceback) -## from pypy.tool import tb_server -## tb_server.publish_exc((exctype, value, traceback)) - -##old_excepthook = sys.excepthook -##sys.excepthook = operr_excepthook Modified: pypy/branch/stringbuilder2/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/executioncontext.py Tue Jan 26 15:23:26 2010 @@ -265,7 +265,8 @@ if w_callback is not None and event != "leaveframe": if operr is not None: - w_arg = space.newtuple([operr.w_type, operr.w_value, + w_value = operr.get_w_value(space) + w_arg = space.newtuple([operr.w_type, w_value, space.wrap(operr.application_traceback)]) frame.fast2locals() Modified: pypy/branch/stringbuilder2/pypy/interpreter/function.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/function.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/function.py Tue Jan 26 15:23:26 2010 @@ -7,7 +7,7 @@ """ from pypy.rlib.unroll import unrolling_iterable -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.eval import Code from pypy.interpreter.argument import Arguments @@ -388,7 +388,9 @@ if self.closure: closure_len = len(self.closure) if isinstance(code, PyCode) and closure_len != len(code.co_freevars): - raise OperationError(space.w_ValueError, space.wrap("%s() requires a code object with %s free vars, not %s " % (self.name, closure_len, len(code.co_freevars)))) + raise operationerrfmt(space.w_ValueError, + "%s() requires a code object with %d free vars, not %d", + self.name, closure_len, len(code.co_freevars)) self.code = code def fget_func_closure(space, self): @@ -458,9 +460,9 @@ instname += " " instdescr = "%sinstance" %instname msg = ("unbound method %s() must be called with %s" - "instance as first argument (got %s instead)") % (myname, clsdescr, instdescr) - raise OperationError(space.w_TypeError, - space.wrap(msg)) + "instance as first argument (got %s instead)") + raise operationerrfmt(space.w_TypeError, msg, + myname, clsdescr, instdescr) return space.call_args(self.w_function, args) def descr_method_get(self, w_obj, w_cls=None): @@ -580,8 +582,8 @@ def descr_classmethod__new__(space, w_type, w_function): if not space.is_true(space.callable(w_function)): typename = space.type(w_function).getname(space, '?') - raise OperationError(space.w_TypeError, space.wrap( - "'%s' object is not callable" % typename)) + raise operationerrfmt(space.w_TypeError, + "'%s' object is not callable", typename) return space.wrap(ClassMethod(w_function)) class FunctionWithFixedCode(Function): Modified: pypy/branch/stringbuilder2/pypy/interpreter/main.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/main.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/main.py Tue Jan 26 15:23:26 2010 @@ -117,7 +117,7 @@ except OperationError, operationerr: operationerr.normalize_exception(space) w_type = operationerr.w_type - w_value = operationerr.w_value + w_value = operationerr.get_w_value(space) w_traceback = space.wrap(operationerr.application_traceback) # for debugging convenience we also insert the exception into @@ -128,7 +128,7 @@ try: # exit if we catch a w_SystemExit if operationerr.match(space, space.w_SystemExit): - w_exitcode = space.getattr(operationerr.w_value, + w_exitcode = space.getattr(w_value, space.wrap('code')) if space.is_w(w_exitcode, space.w_None): exitcode = 0 Modified: pypy/branch/stringbuilder2/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/pycompiler.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/pycompiler.py Tue Jan 26 15:23:26 2010 @@ -70,7 +70,7 @@ if not err2.match(space, space.w_SyntaxError): raise - if space.eq_w(err1.w_value, err2.w_value): + if space.eq_w(err1.get_w_value(space), err2.get_w_value(space)): raise # twice the same error, re-raise return None # two different errors, expect more Modified: pypy/branch/stringbuilder2/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/pyframe.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/pyframe.py Tue Jan 26 15:23:26 2010 @@ -4,7 +4,7 @@ from pypy.tool.pairtype import extendabletype from pypy.interpreter import eval, baseobjspace, pycode from pypy.interpreter.argument import Arguments -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter import pytraceback import opcode @@ -303,7 +303,7 @@ w_exc_value = space.w_None w_tb = space.w_None else: - w_exc_value = self.last_exception.w_value + w_exc_value = self.last_exception.get_w_value(space) w_tb = w(self.last_exception.application_traceback) tup_state = [ @@ -455,8 +455,8 @@ space.wrap("f_lineno can only be set by a trace function.")) if new_lineno < self.pycode.co_firstlineno: - raise OperationError(space.w_ValueError, - space.wrap("line %d comes before the current code." % new_lineno)) + raise operationerrfmt(space.w_ValueError, + "line %d comes before the current code.", new_lineno) code = self.pycode.co_code addr = 0 line = self.pycode.co_firstlineno @@ -472,8 +472,8 @@ break if new_lasti == -1: - raise OperationError(space.w_ValueError, - space.wrap("line %d comes after the current code." % new_lineno)) + raise operationerrfmt(space.w_ValueError, + "line %d comes after the current code.", new_lineno) # Don't jump to a line with an except in it. if ord(code[new_lasti]) in (DUP_TOP, POP_TOP): @@ -519,9 +519,9 @@ assert len(blockstack) == 0 if new_lasti_setup_addr != f_lasti_setup_addr: - raise OperationError(space.w_ValueError, - space.wrap("can't jump into or out of a 'finally' block %d -> %d" % - (f_lasti_setup_addr, new_lasti_setup_addr))) + raise operationerrfmt(space.w_ValueError, + "can't jump into or out of a 'finally' block %d -> %d", + f_lasti_setup_addr, new_lasti_setup_addr) if new_lasti < self.last_instr: min_addr = new_lasti @@ -612,7 +612,7 @@ while f is not None and f.last_exception is None: f = f.f_backref() if f is not None: - return f.last_exception.w_value + return f.last_exception.get_w_value(space) return space.w_None def fget_f_exc_traceback(space, self): Modified: pypy/branch/stringbuilder2/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/pyopcode.py Tue Jan 26 15:23:26 2010 @@ -5,7 +5,7 @@ """ import sys -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import UnpackValueError, Wrappable from pypy.interpreter import gateway, function, eval from pypy.interpreter import pyframe, pytraceback @@ -323,8 +323,8 @@ def _load_fast_failed(f, varindex): varname = f.getlocalvarname(varindex) - message = "local variable '%s' referenced before assignment" % varname - raise OperationError(f.space.w_UnboundLocalError, f.space.wrap(message)) + message = "local variable '%s' referenced before assignment" + raise operationerrfmt(f.space.w_UnboundLocalError, message, varname) _load_fast_failed._dont_inline_ = True def LOAD_CONST(f, constindex, *ignored): @@ -627,8 +627,9 @@ # catch KeyErrors and turn them into NameErrors if not e.match(f.space, f.space.w_KeyError): raise - message = "name '%s' is not defined" % f.space.str_w(w_varname) - raise OperationError(f.space.w_NameError, f.space.wrap(message)) + message = "name '%s' is not defined" + raise operationerrfmt(f.space.w_NameError, message, + f.space.str_w(w_varname)) def UNPACK_SEQUENCE(f, itemcount, *ignored): w_iterable = f.popvalue() @@ -680,9 +681,8 @@ _load_global._always_inline_ = True def _load_global_failed(f, varname): - message = "global name '%s' is not defined" % varname - raise OperationError(f.space.w_NameError, - f.space.wrap(message)) + message = "global name '%s' is not defined" + raise operationerrfmt(f.space.w_NameError, message, varname) _load_global_failed._dont_inline_ = True def LOAD_GLOBAL(f, nameindex, *ignored): @@ -692,8 +692,8 @@ def DELETE_FAST(f, varindex, *ignored): if f.fastlocals_w[varindex] is None: varname = f.getlocalvarname(varindex) - message = "local variable '%s' referenced before assignment" % varname - raise OperationError(f.space.w_UnboundLocalError, f.space.wrap(message)) + message = "local variable '%s' referenced before assignment" + raise operationerrfmt(f.space.w_UnboundLocalError, message, varname) f.fastlocals_w[varindex] = None @@ -809,8 +809,9 @@ except OperationError, e: if not e.match(f.space, f.space.w_AttributeError): raise - raise OperationError(f.space.w_ImportError, - f.space.wrap("cannot import name '%s'" % f.space.str_w(w_name) )) + raise operationerrfmt(f.space.w_ImportError, + "cannot import name '%s'", + f.space.str_w(w_name)) f.pushvalue(w_obj) def JUMP_FORWARD(f, jumpby, next_instr, *ignored): @@ -875,7 +876,7 @@ operr = unroller.operr w_result = f.space.call_function(w_exitfunc, operr.w_type, - operr.w_value, + operr.get_w_value(f.space), operr.application_traceback) if f.space.is_true(w_result): # __exit__() returned True -> Swallow the exception. @@ -1098,7 +1099,7 @@ raise RaiseWithExplicitTraceback(self.operr) def state_unpack_variables(self, space): - return [self.operr.w_type, self.operr.w_value] + return [self.operr.w_type, self.operr.get_w_value(space)] def state_pack_variables(space, w_type, w_value): return SApplicationException(OperationError(w_type, w_value)) state_pack_variables = staticmethod(state_pack_variables) @@ -1209,7 +1210,7 @@ # instead of the traceback, we store the unroller object, # wrapped. frame.pushvalue(frame.space.wrap(unroller)) - frame.pushvalue(operationerr.w_value) + frame.pushvalue(operationerr.get_w_value(frame.space)) frame.pushvalue(operationerr.w_type) frame.last_exception = operationerr return self.handlerposition # jump to the handler Modified: pypy/branch/stringbuilder2/pypy/interpreter/test/test_argument.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/test/test_argument.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/test/test_argument.py Tue Jan 26 15:23:26 2010 @@ -292,11 +292,11 @@ excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"], [1], w_starstararg={None: 1}) assert excinfo.value.w_type is TypeError - assert excinfo.value.w_value is not None + assert excinfo.value._w_value is not None excinfo = py.test.raises(OperationError, Arguments, space, [], ["a"], [1], w_starstararg={valuedummy: 1}) assert excinfo.value.w_type is ValueError - assert excinfo.value.w_value is None + assert excinfo.value._w_value is None def test_blindargs(self): @@ -374,7 +374,7 @@ excinfo = py.test.raises(OperationError, args.parse_obj, "obj", "foo", Signature(["a", "b"], None, None)) assert excinfo.value.w_type is TypeError - assert excinfo.value.w_value == "msg foo" + assert excinfo.value._w_value == "msg foo" def test_args_parsing_into_scope(self): @@ -429,7 +429,7 @@ "obj", [None, None], "foo", Signature(["a", "b"], None, None)) assert excinfo.value.w_type is TypeError - assert excinfo.value.w_value == "msg foo" + assert excinfo.value._w_value == "msg foo" def test_topacked_frompacked(self): space = DummySpace() Modified: pypy/branch/stringbuilder2/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/test/test_compiler.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/test/test_compiler.py Tue Jan 26 15:23:26 2010 @@ -634,7 +634,7 @@ ex = e.value space = self.space assert ex.match(space, space.w_SyntaxError) - assert 'hello_world' in space.str_w(space.str(ex.w_value)) + assert 'hello_world' in space.str_w(space.str(ex.get_w_value(space))) class TestPyCCompiler(BaseTestCompiler): Modified: pypy/branch/stringbuilder2/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/interpreter/typedef.py (original) +++ pypy/branch/stringbuilder2/pypy/interpreter/typedef.py Tue Jan 26 15:23:26 2010 @@ -7,7 +7,7 @@ from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, W_Root, ObjSpace, \ DescrMismatch -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.tool.sourcetools import compile2, func_with_new_name from pypy.rlib.objectmodel import instantiate, compute_identity_hash from pypy.rlib.jit import hint @@ -52,8 +52,8 @@ def descr__hash__unhashable(space, w_obj): typename = space.type(w_obj).getname(space, '?') - msg = "%s objects are unhashable" % (typename,) - raise OperationError(space.w_TypeError,space.wrap(msg)) + raise operationerrfmt(space.w_TypeError, + "'%s' objects are unhashable", typename) no_hash_descr = interp2app(descr__hash__unhashable) @@ -482,12 +482,12 @@ def typecheck(self, space, w_obj): if not space.is_true(space.isinstance(w_obj, self.w_cls)): - raise OperationError(space.w_TypeError, - space.wrap("descriptor '%s' for '%s'" - " objects doesn't apply to '%s' object" % - (self.name, - self.w_cls.name, - space.type(w_obj).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "descriptor '%s' for '%s'" + " objects doesn't apply to '%s' object", + self.name, + self.w_cls.name, + space.type(w_obj).getname(space, '?')) def descr_member_get(space, member, w_obj, w_w_cls=None): """member.__get__(obj[, type]) -> value @@ -554,9 +554,9 @@ w_dict = w_obj.getdict() if w_dict is None: typename = space.type(w_obj).getname(space, '?') - raise OperationError(space.w_TypeError, - space.wrap("descriptor '__dict__' doesn't apply to" - " '%s' objects" % typename)) + raise operationerrfmt(space.w_TypeError, + "descriptor '__dict__' doesn't apply to" + " '%s' objects", typename) return w_dict def descr_set_dict(space, w_obj, w_dict): Modified: pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/test/test_llgraph.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/test/test_llgraph.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/backend/llgraph/test/test_llgraph.py Tue Jan 26 15:23:26 2010 @@ -7,8 +7,7 @@ TreeLoop from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.metainterp.executor import execute -from pypy.jit.backend.test.runner_test import LLtypeBackendTest, \ - BaseAssemblerCallTests +from pypy.jit.backend.test.runner_test import LLtypeBackendTest class TestLLTypeLLGraph(LLtypeBackendTest): # for individual tests see: Modified: pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmspot.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmspot.py (original) +++ pypy/branch/stringbuilder2/pypy/jit/metainterp/test/test_warmspot.py Tue Jan 26 15:23:26 2010 @@ -317,6 +317,9 @@ supports_floats = False ts = llhelper translate_support_code = False + + def get_fail_descr_number(self, d): + return -1 def __init__(self, *args, **kwds): pass Modified: pypy/branch/stringbuilder2/pypy/module/__builtin__/descriptor.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/__builtin__/descriptor.py (original) +++ pypy/branch/stringbuilder2/pypy/module/__builtin__/descriptor.py Tue Jan 26 15:23:26 2010 @@ -3,7 +3,7 @@ from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments from pypy.interpreter.gateway import interp2app -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.descroperation import object_getattribute, object_setattr from pypy.interpreter.function import StaticMethod, ClassMethod from pypy.interpreter.typedef import GetSetProperty, descr_get_dict, \ @@ -154,8 +154,8 @@ # a TypeError instead of an AttributeError and using "readonly" # instead of "read-only" in the error message :-/ if attr in ["__doc__", "fget", "fset", "fdel"]: - raise OperationError(space.w_TypeError, space.wrap( - "Trying to set readonly attribute %s on property" % (attr,))) + raise operationerrfmt(space.w_TypeError, + "Trying to set readonly attribute %s on property", attr) return space.call_function(object_setattr(space), space.wrap(self), space.wrap(attr), w_value) setattr.unwrap_spec = ['self', ObjSpace, str, W_Root] Modified: pypy/branch/stringbuilder2/pypy/module/__builtin__/interp_classobj.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/__builtin__/interp_classobj.py (original) +++ pypy/branch/stringbuilder2/pypy/module/__builtin__/interp_classobj.py Tue Jan 26 15:23:26 2010 @@ -1,5 +1,5 @@ import new -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped, applevel from pypy.interpreter.gateway import interp2app, ObjSpace from pypy.interpreter.typedef import TypeDef, make_weakref_descr @@ -11,10 +11,9 @@ def raise_type_err(space, argument, expected, w_obj): type_name = space.type(w_obj).getname(space, '?') - w_error = space.wrap("argument %s must be %s, not %s" % ( - argument, expected, type_name)) - raise OperationError(space.w_TypeError, - w_error) + raise operationerrfmt(space.w_TypeError, + "argument %s must be %s, not %s", + argument, expected, type_name) def unwrap_attr(space, w_attr): try: @@ -22,7 +21,8 @@ except OperationError, e: if not e.match(space, space.w_TypeError): raise - return "" + return "?" # any string different from "__dict__" & co. is fine + # XXX it's not clear that we have to catch the TypeError... def descr_classobj_new(space, w_subtype, w_name, w_bases, w_dict): if not space.is_true(space.isinstance(w_bases, space.w_tuple)): @@ -120,10 +120,10 @@ return space.newtuple(self.bases_w) w_value = self.lookup(space, w_attr) if w_value is None: - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("class %s has no attribute %s" % ( - self.name, space.str_w(space.str(w_attr))))) + "class %s has no attribute '%s'", + self.name, name) w_descr_get = space.lookup(w_value, '__get__') if w_descr_get is None: @@ -152,18 +152,18 @@ def descr_delattr(self, space, w_attr): name = unwrap_attr(space, w_attr) if name in ("__dict__", "__name__", "__bases__"): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("cannot delete attribute %s" % (name,))) + "cannot delete attribute '%s'", name) try: space.delitem(self.w_dict, w_attr) except OperationError, e: if not e.match(space, space.w_KeyError): raise - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("class %s has no attribute %s" % ( - self.name, space.str_w(space.str(w_attr))))) + "class %s has no attribute '%s'", + self.name, name) def descr_call(self, space, __args__): if self.lookup(space, space.wrap('__del__')) is not None: @@ -336,10 +336,10 @@ w_value = self.w_class.lookup(space, w_name) if w_value is None: if exc: - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("%s instance has no attribute %s" % ( - self.w_class.name, space.str_w(w_name)))) + "%s instance has no attribute '%s'", + self.w_class.name, space.str_w(w_name)) else: return None w_descr_get = space.lookup(w_value, '__get__') @@ -401,10 +401,10 @@ space.call_function(w_meth, w_name) else: if not self.deldictvalue(space, w_name): - raise OperationError( + raise operationerrfmt( space.w_AttributeError, - space.wrap("%s instance has no attribute %s" % ( - self.w_class.name, space.str_w(space.str(w_name))))) + "%s instance has no attribute '%s'", + self.w_class.name, name) def descr_repr(self, space): w_meth = self.getattr(space, space.wrap('__repr__'), False) Modified: pypy/branch/stringbuilder2/pypy/module/_codecs/interp_codecs.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/_codecs/interp_codecs.py (original) +++ pypy/branch/stringbuilder2/pypy/module/_codecs/interp_codecs.py Tue Jan 26 15:23:26 2010 @@ -1,4 +1,4 @@ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, NoneNotWrapped from pypy.interpreter.baseobjspace import W_Root @@ -30,20 +30,19 @@ w_res = space.call_function(w_errorhandler, w_exc) if (not space.is_true(space.isinstance(w_res, space.w_tuple)) or space.int_w(space.len(w_res)) != 2): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("encoding error handler must return " - "(unicode, int) tuple, not %s" % ( - space.str_w(space.repr(w_res))))) + "encoding error handler must return " + "(unicode, int) tuple, not %s", + space.str_w(space.repr(w_res))) w_replace, w_newpos = space.fixedview(w_res, 2) newpos = space.int_w(w_newpos) if (newpos < 0): newpos = len(input) + newpos if newpos < 0 or newpos > len(input): - raise OperationError( + raise operationerrfmt( space.w_IndexError, - space.wrap("position %d from error handler " - "out of bounds" % newpos)) + "position %d from error handler out of bounds", newpos) if decode: replace = space.unicode_w(w_replace) return replace, newpos @@ -103,9 +102,9 @@ else: state.codec_search_cache[normalized_encoding] = w_result return w_result - raise OperationError( + raise operationerrfmt( space.w_LookupError, - space.wrap("unknown encoding: %s" % encoding)) + "unknown encoding: %s", encoding) lookup_codec.unwrap_spec = [ObjSpace, str] @@ -120,9 +119,9 @@ try: w_err_handler = state.codec_error_registry[errors] except KeyError: - raise OperationError( + raise operationerrfmt( space.w_LookupError, - space.wrap("unknown error handler name %s" % errors)) + "unknown error handler name %s", errors) return w_err_handler lookup_error.unwrap_spec = [ObjSpace, str] Modified: pypy/branch/stringbuilder2/pypy/module/_file/interp_file.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/_file/interp_file.py (original) +++ pypy/branch/stringbuilder2/pypy/module/_file/interp_file.py Tue Jan 26 15:23:26 2010 @@ -4,7 +4,7 @@ from pypy.rlib.rarithmetic import r_longlong from pypy.module._file.interp_stream import W_AbstractStream from pypy.module._file.interp_stream import StreamErrors, wrap_streamerror -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, make_weakref_descr @@ -52,8 +52,8 @@ if (not mode or mode[0] not in ['r', 'w', 'a', 'U'] or ('U' in mode and ('w' in mode or 'a' in mode))): space = self.space - raise OperationError(space.w_ValueError, - space.wrap('invalid mode : "%s"' % mode)) + raise operationerrfmt(space.w_ValueError, + "invalid mode: '%s'", mode) def getstream(self): """Return self.stream or raise an app-level ValueError if missing Modified: pypy/branch/stringbuilder2/pypy/module/_rawffi/interp_rawffi.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/_rawffi/interp_rawffi.py (original) +++ pypy/branch/stringbuilder2/pypy/module/_rawffi/interp_rawffi.py Tue Jan 26 15:23:26 2010 @@ -1,7 +1,7 @@ import sys from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments -from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.interpreter.gateway import interp2app, NoneNotWrapped from pypy.interpreter.typedef import TypeDef, GetSetProperty @@ -85,15 +85,15 @@ try: return UNPACKED_TYPECODES[key] except KeyError: - raise OperationError(space.w_ValueError, space.wrap( - "Unknown type letter %s" % (key,))) + raise operationerrfmt(space.w_ValueError, + "Unknown type letter %s", key) def _get_type_(space, key): try: return TYPEMAP[key] except KeyError: - raise OperationError(space.w_ValueError, space.wrap( - "Unknown type letter %s" % (key,))) + raise operationerrfmt(space.w_ValueError, + "Unknown type letter %s", key) def unpack_to_ffi_type(space, w_shape, shape=False): resshape = None @@ -174,8 +174,8 @@ ptr = self.cdll.getrawpointer(name, ffi_argtypes, ffi_restype, flags) except KeyError: - raise OperationError(space.w_AttributeError, space.wrap( - "No symbol %s found in library %s" % (name, self.name))) + raise operationerrfmt(space.w_AttributeError, + "No symbol %s found in library %s", name, self.name) elif (_MS_WINDOWS and space.is_true(space.isinstance(w_name, space.w_int))): @@ -184,8 +184,8 @@ ptr = self.cdll.getrawpointer_byordinal(ordinal, ffi_argtypes, ffi_restype, flags) except KeyError: - raise OperationError(space.w_AttributeError, space.wrap( - "No symbol %d found in library %s" % (ordinal, self.name))) + raise operationerrfmt(space.w_AttributeError, + "No symbol %d found in library %s", ordinal, self.name) else: raise OperationError(space.w_TypeError, space.wrap( "function name must be string or integer")) @@ -200,8 +200,8 @@ address_as_uint = rffi.cast(lltype.Unsigned, self.cdll.getaddressindll(name)) except KeyError: - raise OperationError(space.w_ValueError, - space.wrap("Cannot find symbol %s" % (name,))) + raise operationerrfmt(space.w_ValueError, + "Cannot find symbol %s", name) return space.wrap(address_as_uint) getaddressindll.unwrap_spec = ['self', ObjSpace, str] @@ -391,9 +391,9 @@ from pypy.module._rawffi.structure import W_StructureInstance argnum = len(args_w) if argnum != len(self.argletters): - msg = "Wrong number of arguments: expected %d, got %d" % ( - len(self.argletters), argnum) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "Wrong number of arguments: expected %d, got %d" + raise operationerrfmt(space.w_TypeError, msg, + len(self.argletters), argnum) args_ll = [] for i in range(argnum): argletter = self.argletters[i] @@ -405,23 +405,24 @@ arg.shape.alignment != xalignment): msg = ("Argument %d should be a structure of size %d and " "alignment %d, " - "got instead size %d and alignment %d" % - (i+1, xsize, xalignment, - arg.shape.size, arg.shape.alignment)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + "got instead size %d and alignment %d") + raise operationerrfmt(space.w_TypeError, msg, i+1, + xsize, xalignment, arg.shape.size, + arg.shape.alignment) else: arg = space.interp_w(W_ArrayInstance, w_arg) if arg.length != 1: msg = ("Argument %d should be an array of length 1, " - "got length %d" % (i+1, arg.length)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + "got length %d") + raise operationerrfmt(space.w_TypeError, msg, + i+1, arg.length) letter = arg.shape.itemtp[0] if letter != argletter: if not (argletter in TYPEMAP_PTR_LETTERS and letter in TYPEMAP_PTR_LETTERS): - msg = "Argument %d should be typecode %s, got %s" % ( - i+1, argletter, letter) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "Argument %d should be typecode %s, got %s" + raise operationerrfmt(space.w_TypeError, msg, + i+1, argletter, letter) args_ll.append(arg.ll_buffer) # XXX we could avoid the intermediate list args_ll @@ -463,8 +464,8 @@ try: return space.wrap(intmask(getattr(TYPEMAP[tp_letter], name))) except KeyError: - raise OperationError(space.w_ValueError, space.wrap( - "Unknown type specification %s" % tp_letter)) + raise operationerrfmt(space.w_ValueError, + "Unknown type specification %s", tp_letter) accessor.unwrap_spec = [ObjSpace, str] return func_with_new_name(accessor, func_name) Modified: pypy/branch/stringbuilder2/pypy/module/_rawffi/structure.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/_rawffi/structure.py (original) +++ pypy/branch/stringbuilder2/pypy/module/_rawffi/structure.py Tue Jan 26 15:23:26 2010 @@ -9,7 +9,7 @@ from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.rpython.lltypesystem import lltype, rffi -from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.module._rawffi.interp_rawffi import segfault_exception from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance from pypy.module._rawffi.interp_rawffi import wrap_value, unwrap_value @@ -53,8 +53,8 @@ for i in range(len(fields)): name, tp = fields[i] if name in name_to_index: - raise OperationError(space.w_ValueError, space.wrap( - "duplicate field name %s" % (name, ))) + raise operationerrfmt(space.w_ValueError, + "duplicate field name %s", name) name_to_index[name] = i size, alignment, pos = size_alignment_pos(fields) else: # opaque case @@ -76,8 +76,8 @@ try: return self.name_to_index[attr] except KeyError: - raise OperationError(space.w_AttributeError, space.wrap( - "C Structure has no attribute %s" % attr)) + raise operationerrfmt(space.w_AttributeError, + "C Structure has no attribute %s", attr) def descr_call(self, space, autofree=False): return space.wrap(self.allocate(space, 1, autofree)) Modified: pypy/branch/stringbuilder2/pypy/module/_socket/interp_func.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/_socket/interp_func.py (original) +++ pypy/branch/stringbuilder2/pypy/module/_socket/interp_func.py Tue Jan 26 15:23:26 2010 @@ -2,7 +2,7 @@ from pypy.module._socket.interp_socket import converted_error, W_RSocket from pypy.rlib import rsocket from pypy.rlib.rsocket import SocketError -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt def gethostname(space): """gethostname() -> string @@ -170,9 +170,9 @@ elif space.is_true(space.isinstance(w_x, space.w_long)): x = space.uint_w(w_x) else: - raise OperationError(space.w_TypeError, - space.wrap("expected int/long, %s found" % - (space.type(w_x).getname(space, "?")))) + raise operationerrfmt(space.w_TypeError, + "expected int/long, %s found", + space.type(w_x).getname(space, "?")) return space.wrap(rsocket.ntohl(x)) ntohl.unwrap_spec = [ObjSpace, W_Root] @@ -195,9 +195,9 @@ elif space.is_true(space.isinstance(w_x, space.w_long)): x = space.uint_w(w_x) else: - raise OperationError(space.w_TypeError, - space.wrap("expected int/long, %s found" % - (space.type(w_x).getname(space, "?")))) + raise operationerrfmt(space.w_TypeError, + "expected int/long, %s found", + space.type(w_x).getname(space, "?")) return space.wrap(rsocket.htonl(x)) htonl.unwrap_spec = [ObjSpace, W_Root] @@ -249,7 +249,7 @@ ip = rsocket.inet_ntop(family, packed) except SocketError, e: raise converted_error(space, e) - except ValueError, e: + except ValueError, e: # XXX the message is lost in RPython raise OperationError(space.w_ValueError, space.wrap(str(e))) return space.wrap(ip) Modified: pypy/branch/stringbuilder2/pypy/module/_stackless/interp_coroutine.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/_stackless/interp_coroutine.py (original) +++ pypy/branch/stringbuilder2/pypy/module/_stackless/interp_coroutine.py Tue Jan 26 15:23:26 2010 @@ -20,7 +20,7 @@ from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.function import StaticMethod from pypy.module._stackless.stackless_flags import StacklessFlags @@ -35,10 +35,10 @@ self.space = space self.costate = costate if not space.is_true(space.callable(w_obj)): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.mod(space.wrap('object %r is not callable'), - space.newtuple([w_obj]))) + "'%s' object is not callable", + space.type(w_obj).getname(space, '?')) self.w_func = w_obj self.args = args @@ -99,7 +99,7 @@ space = self.space if isinstance(operror, OperationError): w_exctype = operror.w_type - w_excvalue = operror.w_value + w_excvalue = operror.get_w_value(space) w_exctraceback = operror.application_traceback w_excinfo = space.newtuple([w_exctype, w_excvalue, w_exctraceback]) else: Modified: pypy/branch/stringbuilder2/pypy/module/_stackless/interp_greenlet.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/_stackless/interp_greenlet.py (original) +++ pypy/branch/stringbuilder2/pypy/module/_stackless/interp_greenlet.py Tue Jan 26 15:23:26 2010 @@ -28,7 +28,7 @@ except OperationError, operror: if not operror.match(space, greenlet.costate.w_GreenletExit): raise - w_result = operror.w_value + w_result = operror.get_w_value(space) finally: greenlet.active = False greenlet.costate.args_w = [w_result] @@ -127,7 +127,7 @@ operror.application_traceback = tb # Dead greenlet: turn GreenletExit into a regular return if self.isdead() and operror.match(space, self.costate.w_GreenletExit): - args_w = [operror.w_value] + args_w = [operror.get_w_value(space)] else: syncstate.push_exception(operror) args_w = None Modified: pypy/branch/stringbuilder2/pypy/module/bz2/interp_bz2.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/bz2/interp_bz2.py (original) +++ pypy/branch/stringbuilder2/pypy/module/bz2/interp_bz2.py Tue Jan 26 15:23:26 2010 @@ -1,7 +1,7 @@ from pypy.rpython.tool import rffi_platform as platform from pypy.rpython.lltypesystem import rffi from pypy.rpython.lltypesystem import lltype -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty @@ -193,8 +193,8 @@ def check_mode_ok(self, mode): if (not mode or mode[0] not in ['r', 'w', 'a', 'U']): space = self.space - raise OperationError(space.w_ValueError, - space.wrap('invalid mode : "%s"' % mode)) + raise operationerrfmt(space.w_ValueError, + "invalid mode: '%s'", mode) def direct_bz2__init__(self, w_name, mode='r', buffering=-1, compresslevel=9): Modified: pypy/branch/stringbuilder2/pypy/module/clr/interp_clr.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/clr/interp_clr.py (original) +++ pypy/branch/stringbuilder2/pypy/module/clr/interp_clr.py Tue Jan 26 15:23:26 2010 @@ -1,7 +1,7 @@ import os.path from pypy.module.clr import assemblyname from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app, ApplevelClass from pypy.interpreter.typedef import TypeDef from pypy.rpython.ootypesystem import ootype @@ -17,11 +17,11 @@ try: method = b_type.GetMethod(name, b_paramtypes) except AmbiguousMatchException: - msg = 'Multiple overloads for %s could match' % name - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = 'Multiple overloads for %s could match' + raise operationerrfmt(space.w_TypeError, msg, name) if method is None: - msg = 'No overloads for %s could match' % name - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = 'No overloads for %s could match' + raise operationerrfmt(space.w_TypeError, msg, name) return method def get_constructor(space, b_type, b_paramtypes): @@ -301,7 +301,8 @@ assembly_qualified_name = '%s, %s' % (fullname, assemblyname) b_type = System.Type.GetType(assembly_qualified_name) if b_type is None: - raise OperationError(space.w_ImportError, space.wrap("Cannot load .NET type: %s" % fullname)) + raise operationerrfmt(space.w_ImportError, + "Cannot load .NET type: %s", fullname) # this is where we locate the interfaces inherited by the class # set the flag hasIEnumerable if IEnumerable interface has been by the class Modified: pypy/branch/stringbuilder2/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/imp/importing.py (original) +++ pypy/branch/stringbuilder2/pypy/module/imp/importing.py Tue Jan 26 15:23:26 2010 @@ -6,7 +6,7 @@ from pypy.interpreter.module import Module from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root, ObjSpace from pypy.interpreter.eval import Code from pypy.rlib import streamio @@ -382,8 +382,8 @@ return None else: # ImportError - msg = "No module named %s" % modulename - raise OperationError(space.w_ImportError, w(msg)) + msg = "No module named %s" + raise operationerrfmt(space.w_ImportError, msg, modulename) def reload(space, w_module): """Reload the module. @@ -396,9 +396,9 @@ w_modulename = space.getattr(w_module, space.wrap("__name__")) modulename = space.str_w(w_modulename) if not space.is_w(check_sys_modules(space, w_modulename), w_module): - raise OperationError( + raise operationerrfmt( space.w_ImportError, - space.wrap("reload(): module %s not in sys.modules" % (modulename,))) + "reload(): module %s not in sys.modules", modulename) try: w_mod = space.reloading_modules[modulename] @@ -416,10 +416,10 @@ if parent_name: w_parent = check_sys_modules(space, space.wrap(parent_name)) if w_parent is None: - raise OperationError( + raise operationerrfmt( space.w_ImportError, - space.wrap("reload(): parent %s not in sys.modules" % ( - parent_name,))) + "reload(): parent %s not in sys.modules", + parent_name) w_path = space.getattr(w_parent, space.wrap("__path__")) else: w_path = None @@ -429,8 +429,8 @@ if not find_info: # ImportError - msg = "No module named %s" % modulename - raise OperationError(space.w_ImportError, space.wrap(msg)) + msg = "No module named %s" + raise operationerrfmt(space.w_ImportError, msg, modulename) try: try: @@ -677,8 +677,8 @@ w_code = space.call_method(w_marshal, 'loads', space.wrap(strbuf)) pycode = space.interpclass_w(w_code) if pycode is None or not isinstance(pycode, Code): - raise OperationError(space.w_ImportError, space.wrap( - "Non-code object in %s" % cpathname)) + raise operationerrfmt(space.w_ImportError, + "Non-code object in %s", cpathname) return pycode def load_compiled_module(space, w_modulename, w_mod, cpathname, magic, @@ -689,8 +689,8 @@ """ w = space.wrap if magic != get_pyc_magic(space): - raise OperationError(space.w_ImportError, w( - "Bad magic number in %s" % cpathname)) + raise operationerrfmt(space.w_ImportError, + "Bad magic number in %s", cpathname) #print "loading pyc file:", cpathname code_w = read_compiled_module(space, cpathname, source) exec_code_module(space, w_mod, code_w) Modified: pypy/branch/stringbuilder2/pypy/module/imp/interp_imp.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/imp/interp_imp.py (original) +++ pypy/branch/stringbuilder2/pypy/module/imp/interp_imp.py Tue Jan 26 15:23:26 2010 @@ -1,7 +1,7 @@ from pypy.module.imp import importing from pypy.module._file.interp_file import W_File from pypy.rlib import streamio -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.module import Module from pypy.interpreter.gateway import NoneNotWrapped import struct @@ -38,9 +38,9 @@ find_info = importing.find_module( space, name, w_name, name, w_path, use_loader=False) if not find_info: - raise OperationError( + raise operationerrfmt( space.w_ImportError, - space.wrap("No module named %s" % (name,))) + "No module named %s", name) w_filename = space.wrap(find_info.filename) stream = find_info.stream Modified: pypy/branch/stringbuilder2/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/stringbuilder2/pypy/module/pypyjit/interp_jit.py Tue Jan 26 15:23:26 2010 @@ -8,7 +8,7 @@ from pypy.rlib.rarithmetic import r_uint, intmask from pypy.rlib.jit import JitDriver, hint, we_are_jitted import pypy.interpreter.pyopcode # for side-effects -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import ObjSpace, Arguments from pypy.interpreter.eval import Frame from pypy.interpreter.pycode import PyCode, CO_CONTAINSLOOP @@ -116,9 +116,8 @@ # XXXXXXXXX args_w, kwds_w = args.unpack() if len(args_w) > 1: - msg = ("set_param() takes at most 1 non-keyword argument, %d given" - % len(args_w)) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "set_param() takes at most 1 non-keyword argument, %d given" + raise operationerrfmt(space.w_TypeError, msg, len(args_w)) if len(args_w) == 1: text = space.str_w(args_w[0]) try: @@ -131,7 +130,7 @@ try: pypyjitdriver.set_param(key, intval) except ValueError: - raise OperationError(space.w_TypeError, - space.wrap("no JIT parameter '%s'" % (key,))) + raise operationerrfmt(space.w_TypeError, + "no JIT parameter '%s'", key) set_param.unwrap_spec = [ObjSpace, Arguments] Modified: pypy/branch/stringbuilder2/pypy/module/rctime/interp_time.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/rctime/interp_time.py (original) +++ pypy/branch/stringbuilder2/pypy/module/rctime/interp_time.py Tue Jan 26 15:23:26 2010 @@ -1,6 +1,6 @@ from pypy.rpython.tool import rffi_platform as platform from pypy.rpython.lltypesystem import rffi -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root, ObjSpace from pypy.rpython.lltypesystem import lltype from pypy.rlib.rarithmetic import ovfcheck_float_to_int @@ -224,9 +224,9 @@ tup_w = space.fixedview(w_tup) if len(tup_w) != 9: - raise OperationError(space.w_TypeError, - space.wrap("argument must be sequence of " - "length 9, not %d" % len(tup_w))) + raise operationerrfmt(space.w_TypeError, + "argument must be sequence of " + "length 9, not %d", len(tup_w)) y = space.int_w(tup_w[0]) tm_mon = space.int_w(tup_w[1]) Modified: pypy/branch/stringbuilder2/pypy/module/select/interp_select.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/select/interp_select.py (original) +++ pypy/branch/stringbuilder2/pypy/module/select/interp_select.py Tue Jan 26 15:23:26 2010 @@ -2,7 +2,7 @@ from pypy.interpreter.typedef import TypeDef from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.gateway import W_Root, ObjSpace, interp2app -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.rlib import rpoll defaultevents = rpoll.POLLIN | rpoll.POLLOUT | rpoll.POLLPRI @@ -28,8 +28,8 @@ fd = space.int_w(w_fd) if fd < 0: - raise OperationError(space.w_ValueError, - space.wrap("file descriptor cannot be a negative integer (%d)"%fd)) + raise operationerrfmt(space.w_ValueError, + "file descriptor cannot be a negative integer (%d)", fd) return fd class Poll(Wrappable): @@ -47,7 +47,7 @@ del self.fddict[fd] except KeyError: raise OperationError(space.w_KeyError, - space.wrap(fd)) + space.wrap(fd)) # XXX should this maybe be w_fd? unregister.unwrap_spec = ['self', ObjSpace, W_Root] def poll(self, space, w_timeout=None): Modified: pypy/branch/stringbuilder2/pypy/module/sys/__init__.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/sys/__init__.py (original) +++ pypy/branch/stringbuilder2/pypy/module/sys/__init__.py Tue Jan 26 15:23:26 2010 @@ -116,7 +116,7 @@ if operror is None: return space.w_None else: - return operror.w_value + return operror.get_w_value(space) elif attr == 'exc_traceback': operror = space.getexecutioncontext().sys_exc_info() if operror is None: Modified: pypy/branch/stringbuilder2/pypy/module/sys/vm.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/sys/vm.py (original) +++ pypy/branch/stringbuilder2/pypy/module/sys/vm.py Tue Jan 26 15:23:26 2010 @@ -90,7 +90,7 @@ if operror is None: return space.newtuple([space.w_None,space.w_None,space.w_None]) else: - return space.newtuple([operror.w_type, operror.w_value, + return space.newtuple([operror.w_type, operror.get_w_value(space), space.wrap(operror.application_traceback)]) def exc_clear(space): Modified: pypy/branch/stringbuilder2/pypy/module/thread/os_thread.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/thread/os_thread.py (original) +++ pypy/branch/stringbuilder2/pypy/module/thread/os_thread.py Tue Jan 26 15:23:26 2010 @@ -4,7 +4,7 @@ from pypy.module.thread import ll_thread as thread from pypy.module.thread.error import wrap_thread_error -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments from pypy.rlib.objectmodel import free_non_gc_object @@ -198,8 +198,8 @@ old_size = thread.get_stacksize() error = thread.set_stacksize(size) if error == -1: - raise OperationError(space.w_ValueError, - space.wrap("size not valid: %d bytes" % size)) + raise operationerrfmt(space.w_ValueError, + "size not valid: %d bytes", size) if error == -2: raise wrap_thread_error(space, "setting stack size not supported") return space.wrap(old_size) Modified: pypy/branch/stringbuilder2/pypy/module/zipimport/interp_zipimport.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/module/zipimport/interp_zipimport.py (original) +++ pypy/branch/stringbuilder2/pypy/module/zipimport/interp_zipimport.py Tue Jan 26 15:23:26 2010 @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments -from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.module import Module @@ -257,7 +257,7 @@ w_mods = space.sys.get('modules') space.call_method(w_mods, 'pop', w(fullname), space.w_None) if last_exc: - raise OperationError(self.w_ZipImportError, last_exc.w_value) + raise OperationError(self.w_ZipImportError, last_exc.get_w_value(space)) # should never happen I think return space.w_None load_module.unwrap_spec = ['self', ObjSpace, str] @@ -288,8 +288,8 @@ w_code = space.builtin.call('compile', w_source, w(filename + ext), w('exec')) return w_code - raise OperationError(self.w_ZipImportError, space.wrap( - "Cannot find source or code for %s in %s" % (filename, self.name))) + raise operationerrfmt(self.w_ZipImportError, + "Cannot find source or code for %s in %s", filename, self.name) get_code.unwrap_spec = ['self', ObjSpace, str] def get_source(self, space, fullname): @@ -304,8 +304,8 @@ found = True if found: return space.w_None - raise OperationError(self.w_ZipImportError, space.wrap( - "Cannot find source for %s in %s" % (filename, self.name))) + raise operationerrfmt(self.w_ZipImportError, + "Cannot find source for %s in %s", filename, self.name) get_source.unwrap_spec = ['self', ObjSpace, str] def is_package(self, space, fullname): @@ -313,8 +313,8 @@ for _, is_package, ext in ENUMERATE_EXTS: if self.have_modulefile(space, filename + ext): return space.wrap(is_package) - raise OperationError(self.w_ZipImportError, space.wrap( - "Cannot find module %s in %s" % (filename, self.name))) + raise operationerrfmt(self.w_ZipImportError, + "Cannot find module %s in %s", filename, self.name) is_package.unwrap_spec = ['self', ObjSpace, str] def getarchive(space, self): @@ -335,28 +335,28 @@ try: s = os.stat(filename) except OSError: - raise OperationError(w_ZipImportError, space.wrap( - "Cannot find name %s" % (filename,))) + raise operationerrfmt(w_ZipImportError, + "Cannot find name %s", filename) if not stat.S_ISDIR(s.st_mode): ok = True break if not ok: - raise OperationError(w_ZipImportError, space.wrap( - "Did not find %s to be a valid zippath" % (name,))) + raise operationerrfmt(w_ZipImportError, + "Did not find %s to be a valid zippath", name) try: w_result = zip_cache.get(filename) if w_result is None: - raise OperationError(w_ZipImportError, space.wrap( + raise operationerrfmt(w_ZipImportError, "Cannot import %s from zipfile, recursion detected or" - "already tried and failed" % (name,))) + "already tried and failed", name) return w_result except KeyError: zip_cache.cache[filename] = None try: zip_file = RZipFile(filename, 'r') except (BadZipfile, OSError): - raise OperationError(w_ZipImportError, space.wrap( - "%s seems not to be a zipfile" % (filename,))) + raise operationerrfmt(w_ZipImportError, + "%s seems not to be a zipfile", filename) zip_file.close() prefix = name[len(filename):] if prefix.startswith(os.sep): Modified: pypy/branch/stringbuilder2/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/descroperation.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/descroperation.py Tue Jan 26 15:23:26 2010 @@ -1,5 +1,5 @@ import operator -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.function import Function, Method, FunctionWithFixedCode from pypy.interpreter.argument import Arguments @@ -24,10 +24,13 @@ w_type = space.type(w_obj) typename = w_type.getname(space, '?') if w_descr is None: - msg = "'%s' object has no attribute '%s'" % (typename, name) + raise operationerrfmt(space.w_AttributeError, + "'%s' object has no attribute '%s'", + typename, name) else: - msg = "'%s' object attribute '%s' is read-only" % (typename, name) - raise OperationError(space.w_AttributeError, space.wrap(msg)) + raise operationerrfmt(space.w_AttributeError, + "'%s' object attribute '%s' is read-only", + typename, name) class Object: def descr__getattribute__(space, w_obj, w_name): @@ -120,10 +123,10 @@ return w_obj.call_args(args) w_descr = space.lookup(w_obj, '__call__') if w_descr is None: - raise OperationError( - space.w_TypeError, - space.mod(space.wrap('object %r is not callable'), - space.newtuple([w_obj]))) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not callable", + typename) return space.get_and_call_args(w_descr, w_obj, args) def get(space, w_descr, w_obj, w_type=None): @@ -137,15 +140,19 @@ def set(space, w_descr, w_obj, w_val): w_set = space.lookup(w_descr, '__set__') if w_set is None: - raise OperationError(space.w_TypeError, - space.wrap("object is not a descriptor with set")) + typename = space.type(w_descr).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not a descriptor with set", + typename) return space.get_and_call_function(w_set, w_descr, w_obj, w_val) def delete(space, w_descr, w_obj): w_delete = space.lookup(w_descr, '__delete__') if w_delete is None: - raise OperationError(space.w_TypeError, - space.wrap("object is not a descriptor with delete")) + typename = space.type(w_descr).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not a descriptor with delete", + typename) return space.get_and_call_function(w_delete, w_descr, w_obj) def getattr(space, w_obj, w_name): @@ -169,15 +176,19 @@ def setattr(space, w_obj, w_name, w_val): w_descr = space.lookup(w_obj, '__setattr__') if w_descr is None: - raise OperationError(space.w_AttributeError, - space.wrap("object is readonly")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_AttributeError, + "'%s' object is readonly", + typename) return space.get_and_call_function(w_descr, w_obj, w_name, w_val) def delattr(space, w_obj, w_name): w_descr = space.lookup(w_obj, '__delattr__') if w_descr is None: - raise OperationError(space.w_AttributeError, - space.wrap("object does not support attribute removal")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_AttributeError, + "'%s' object does not support attribute removal", + typename) return space.get_and_call_function(w_descr, w_obj, w_name) def is_true(space, w_obj): @@ -215,37 +226,47 @@ if w_descr is None: w_descr = space.lookup(w_obj, '__getitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("iteration over non-sequence")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not iterable", + typename) return space.newseqiter(w_obj) return space.get_and_call_function(w_descr, w_obj) def next(space, w_obj): w_descr = space.lookup(w_obj, 'next') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("iterator has no next() method")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not an iterator", + typename) return space.get_and_call_function(w_descr, w_obj) def getitem(space, w_obj, w_key): w_descr = space.lookup(w_obj, '__getitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("cannot get items from object")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object is not subscriptable", + typename) return space.get_and_call_function(w_descr, w_obj, w_key) def setitem(space, w_obj, w_key, w_val): w_descr = space.lookup(w_obj, '__setitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("cannot set items on object")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object does not support item assignment", + typename) return space.get_and_call_function(w_descr, w_obj, w_key, w_val) def delitem(space, w_obj, w_key): w_descr = space.lookup(w_obj, '__delitem__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("cannot delete items from object")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "'%s' object does not support item deletion", + typename) return space.get_and_call_function(w_descr, w_obj, w_key) def getslice(space, w_obj, w_start, w_stop): @@ -553,6 +574,8 @@ def _make_binop_impl(symbol, specialnames): left, right = specialnames + errormsg = "unsupported operand type(s) for %s: '%%s' and '%%s'" % ( + symbol.replace('%', '%%'),) def binop_impl(space, w_obj1, w_obj2): w_typ1 = space.type(w_obj1) @@ -592,8 +615,10 @@ w_res = _invoke_binop(space, w_right_impl, w_obj2, w_obj1) if w_res is not None: return w_res - raise OperationError(space.w_TypeError, - space.wrap("unsupported operand type(s) for %s" % symbol)) + typename1 = w_typ1.getname(space, '?') + typename2 = w_typ2.getname(space, '?') + raise operationerrfmt(space.w_TypeError, errormsg, + typename1, typename2) return func_with_new_name(binop_impl, "binop_%s_impl"%left.strip('_')) @@ -649,11 +674,12 @@ def _make_unaryop_impl(symbol, specialnames): specialname, = specialnames + errormsg = "unsupported operand type for unary %s: '%%s'" % symbol def unaryop_impl(space, w_obj): w_impl = space.lookup(w_obj, specialname) if w_impl is None: - raise OperationError(space.w_TypeError, - space.wrap("operand does not support unary %s" % symbol)) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, errormsg, typename) return space.get_and_call_function(w_impl, w_obj) return func_with_new_name(unaryop_impl, 'unaryop_%s_impl'%specialname.strip('_')) @@ -674,16 +700,17 @@ def %(targetname)s(space, w_obj): w_impl = space.lookup(w_obj, %(specialname)r) if w_impl is None: - raise OperationError(space.w_TypeError, - space.wrap("operand does not support unary %(targetname)s")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for %(targetname)s(): '%%s'", + typename) w_result = space.get_and_call_function(w_impl, w_obj) if %(checker)s: return w_result - typename = space.str_w(space.getattr(space.type(w_result), - space.wrap('__name__'))) - msg = '%(specialname)s returned non-%(targetname)s (type %%s)' %% (typename,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + typename = space.type(w_result).getname(space, '?') + msg = "%(specialname)s returned non-%(targetname)s (type '%%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) assert not hasattr(DescrOperation, %(targetname)r) DescrOperation.%(targetname)s = %(targetname)s del %(targetname)s @@ -700,8 +727,10 @@ def %(targetname)s(space, w_obj): w_impl = space.lookup(w_obj, %(specialname)r) if w_impl is None: - raise OperationError(space.w_TypeError, - space.wrap("operand does not support unary %(targetname)s")) + typename = space.type(w_obj).getname(space, '?') + raise operationerrfmt(space.w_TypeError, + "unsupported operand type for %(targetname)s(): '%%s'", + typename) w_result = space.get_and_call_function(w_impl, w_obj) if space.is_true(space.isinstance(w_result, space.w_str)): @@ -711,10 +740,9 @@ except OperationError, e: if not e.match(space, space.w_TypeError): raise - typename = space.str_w(space.getattr(space.type(w_result), - space.wrap('__name__'))) - msg = '%(specialname)s returned non-%(targetname)s (type %%s)' %% (typename,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + typename = space.type(w_result).getname(space, '?') + msg = "%(specialname)s returned non-%(targetname)s (type '%%s')" + raise operationerrfmt(space.w_TypeError, msg, typename) else: # re-wrap the result as a real string return space.wrap(result) Modified: pypy/branch/stringbuilder2/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/flow/flowcontext.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/flow/flowcontext.py Tue Jan 26 15:23:26 2010 @@ -276,7 +276,7 @@ raise Exception( 'found an operation that always raises %s: %s' % ( self.space.unwrap(e.w_type).__name__, - self.space.unwrap(e.w_value))) + self.space.unwrap(e.get_w_value(self.space)))) except ImplicitOperationError, e: if isinstance(e.w_type, Constant): @@ -290,12 +290,13 @@ self.recorder.crnt_block.closeblock(link) except OperationError, e: - #print "OE", e.w_type, e.w_value + #print "OE", e.w_type, e.get_w_value(self.space) if (self.space.do_imports_immediately and e.w_type is self.space.w_ImportError): raise ImportError('import statement always raises %s' % ( e,)) - link = self.make_link([e.w_type, e.w_value], self.graph.exceptblock) + w_value = e.get_w_value(self.space) + link = self.make_link([e.w_type, w_value], self.graph.exceptblock) self.recorder.crnt_block.closeblock(link) except StopFlowing: @@ -382,7 +383,8 @@ operr = ExecutionContext.sys_exc_info(self) if isinstance(operr, ImplicitOperationError): # re-raising an implicit operation makes it an explicit one - operr = OperationError(operr.w_type, operr.w_value) + w_value = operr.get_w_value(self.space) + operr = OperationError(operr.w_type, w_value) return operr def exception_trace(self, frame, operationerr): Modified: pypy/branch/stringbuilder2/pypy/objspace/flow/framestate.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/flow/framestate.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/flow/framestate.py Tue Jan 26 15:23:26 2010 @@ -16,7 +16,7 @@ data.append(Constant(None)) else: data.append(state.last_exception.w_type) - data.append(state.last_exception.w_value) + data.append(state.last_exception.get_w_value(state.space)) recursively_flatten(state.space, data) self.mergeable = data self.nonmergeable = ( Modified: pypy/branch/stringbuilder2/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/dictmultiobject.py Tue Jan 26 15:23:26 2010 @@ -1,6 +1,8 @@ -import py -from pypy.objspace.std.objspace import * +import py, sys +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.argument import Signature from pypy.module.__builtin__.__init__ import BUILTIN_TO_INDEX, OPTIMIZED_BUILTINS @@ -796,7 +798,9 @@ defaults = space.listview(w_defaults) len_defaults = len(defaults) if len_defaults > 1: - raise OperationError(space.w_TypeError, space.wrap("pop expected at most 2 arguments, got %d" % (1 + len_defaults, ))) + raise operationerrfmt(space.w_TypeError, + "pop expected at most 2 arguments, got %d", + 1 + len_defaults) w_item = w_dict.getitem(w_key) if w_item is None: if len_defaults > 0: Modified: pypy/branch/stringbuilder2/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/listobject.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/listobject.py Tue Jan 26 15:23:26 2010 @@ -1,4 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.listtype import get_list_index from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice @@ -282,9 +285,9 @@ else: assert delta==0 elif len2 != slicelength: # No resize for extended slices - raise OperationError(space.w_ValueError, space.wrap("attempt to " - "assign sequence of size %d to extended slice of size %d" % - (len2,slicelength))) + raise operationerrfmt(space.w_ValueError, "attempt to " + "assign sequence of size %d to extended slice of size %d", + len2, slicelength) if sequence2 is items: if step > 0: Modified: pypy/branch/stringbuilder2/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/multimethod.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/multimethod.py Tue Jan 26 15:23:26 2010 @@ -29,6 +29,10 @@ self.w_type = w_type self.w_value = w_value + def get_w_value(self, space): + # convenience: same semantics as with OperationError + return self.w_value + def __str__(self): return '' % (self.w_type, self.w_value) Modified: pypy/branch/stringbuilder2/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/objecttype.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/objecttype.py Tue Jan 26 15:23:26 2010 @@ -1,4 +1,4 @@ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.descroperation import Object from pypy.interpreter import gateway from pypy.interpreter.typedef import default_identity_hash @@ -31,9 +31,9 @@ def descr_set___class__(space, w_obj, w_newcls): from pypy.objspace.std.typeobject import W_TypeObject if not isinstance(w_newcls, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap("__class__ must be set to new-style class, not '%s' object" % - space.type(w_newcls).getname(space, '?'))) + raise operationerrfmt(space.w_TypeError, + "__class__ must be set to new-style class, not '%s' object", + space.type(w_newcls).getname(space, '?')) if not w_newcls.is_heaptype(): raise OperationError(space.w_TypeError, space.wrap("__class__ assignment: only for heap types")) @@ -43,9 +43,9 @@ if w_oldcls.get_full_instance_layout() == w_newcls.get_full_instance_layout(): w_obj.setclass(space, w_newcls) else: - raise OperationError(space.w_TypeError, - space.wrap("__class__ assignment: '%s' object layout differs from '%s'" % - (w_oldcls.getname(space, '?'), w_newcls.getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "__class__ assignment: '%s' object layout differs from '%s'", + w_oldcls.getname(space, '?'), w_newcls.getname(space, '?')) def descr__new__(space, w_type, __args__): Modified: pypy/branch/stringbuilder2/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/objspace.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/objspace.py Tue Jan 26 15:23:26 2010 @@ -1,6 +1,6 @@ from pypy.objspace.std.register_all import register_all from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, UnpackValueError -from pypy.interpreter.error import OperationError, debug_print +from pypy.interpreter.error import OperationError, operationerrfmt, debug_print from pypy.interpreter.typedef import get_unique_interplevel_subclass from pypy.interpreter import pyframe from pypy.interpreter import function @@ -143,9 +143,9 @@ ## print "CALL_LIKELY_BUILTIN fast" if w_value is None: varname = OPTIMIZED_BUILTINS[num] - message = "global name '%s' is not defined" % varname - raise OperationError(f.space.w_NameError, - f.space.wrap(message)) + message = "global name '%s' is not defined" + raise operationerrfmt(f.space.w_NameError, + message, varname) nargs = oparg & 0xff w_function = w_value try: @@ -559,9 +559,9 @@ assert isinstance(instance, cls) instance.user_setup(self, w_subtype) else: - raise OperationError(self.w_TypeError, - self.wrap("%s.__new__(%s): only for the type %s" % ( - w_type.name, w_subtype.getname(self, '?'), w_type.name))) + raise operationerrfmt(self.w_TypeError, + "%s.__new__(%s): only for the type %s", + w_type.name, w_subtype.getname(self, '?'), w_type.name) return instance allocate_instance._annspecialcase_ = "specialize:arg(1)" Modified: pypy/branch/stringbuilder2/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/ropeobject.py Tue Jan 26 15:23:26 2010 @@ -1,4 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.rlib.objectmodel import we_are_translated from pypy.objspace.std.inttype import wrapint @@ -281,10 +284,10 @@ if space.is_true(space.isinstance(w_s, space.w_unicode)): w_u = space.call_function(space.w_unicode, w_self) return space.call_method(w_u, "join", space.newlist(list_w)) - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("sequence item %d: expected string, %s " - "found" % (i, space.type(w_s).name))) + "sequence item %d: expected string, %s " + "found", i, space.type(w_s).getname(space, "?")) assert isinstance(w_s, W_RopeObject) node = w_s._node l.append(node) @@ -689,9 +692,8 @@ if ival < 0: ival += slen if ival < 0 or ival >= slen: - exc = space.call_function(space.w_IndexError, - space.wrap("string index out of range")) - raise OperationError(space.w_IndexError, exc) + raise OperationError(space.w_IndexError, + space.wrap("string index out of range")) return wrapchar(space, node.getchar(ival)) def getitem__Rope_Slice(space, w_str, w_slice): @@ -756,10 +758,10 @@ def ord__Rope(space, w_str): node = w_str._node if node.length() != 1: - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("ord() expected a character, but string " - "of length %d found"% (w_str._node.length(),))) + "ord() expected a character, but string " + "of length %d found", node.length()) return space.wrap(node.getint(0)) def getnewargs__Rope(space, w_str): Modified: pypy/branch/stringbuilder2/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/ropeunicodeobject.py Tue Jan 26 15:23:26 2010 @@ -1,4 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import _normalize_index @@ -24,11 +27,10 @@ encoding = getdefaultencoding(space) w_retval = decode_string(space, w_str, encoding, "strict") if not space.is_true(space.isinstance(w_retval, space.w_unicode)): - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap( - "decoder did not return an unicode object (type=%s)" % - space.type(w_retval).getname(space, '?'))) + "decoder did not return an unicode object (type '%s')", + space.type(w_retval).getname(space, '?')) assert isinstance(w_retval, W_RopeUnicodeObject) return w_retval @@ -143,7 +145,7 @@ w_start = space.wrap(i) w_end = space.wrap(i+1) w_reason = space.wrap('invalid decimal Unicode string') - raise OperationError(space.w_UnicodeEncodeError,space.newtuple ([w_encoding, w_unistr, w_start, w_end, w_reason])) + raise OperationError(space.w_UnicodeEncodeError, space.newtuple([w_encoding, w_unistr, w_start, w_end, w_reason])) return ''.join(result) # string-to-unicode delegation @@ -252,9 +254,8 @@ elif space.is_true(space.isinstance(w_item, space.w_str)): item = unicode_from_string(space, w_item)._node else: - w_msg = space.mod(space.wrap('sequence item %d: expected string or Unicode'), - space.wrap(i)) - raise OperationError(space.w_TypeError, w_msg) + msg = 'sequence item %d: expected string or Unicode' + raise operationerrfmt(space.w_TypeError, msg, i) values_list.append(item) try: return W_RopeUnicodeObject(rope.join(w_self._node, values_list)) Modified: pypy/branch/stringbuilder2/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/stdtypedef.py Tue Jan 26 15:23:26 2010 @@ -1,5 +1,5 @@ from pypy.interpreter import gateway, baseobjspace, argument -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member from pypy.interpreter.typedef import descr_get_dict, descr_set_dict from pypy.interpreter.typedef import no_hash_descr, descr_del_dict @@ -141,16 +141,27 @@ prefix = typedef.name +'_mth'+prefix return prefix, list_of_typeorders -def typeerrormsg(space, operatorsymbol, args_w): - type_names = [ space.type(w_arg).getname(space, '?') for w_arg in args_w ] - if len(args_w) > 1: +def _gettypeerrormsg(nbargs): + if nbargs > 1: plural = 's' else: plural = '' - msg = "unsupported operand type%s for %s (%s)" % ( - plural, operatorsymbol, - ', '.join(type_names)) - return space.wrap(msg) + return "unsupported operand type%s for %%s: %s" % ( + plural, ', '.join(["'%s'"] * nbargs)) +_gettypeerrormsg._annspecialcase_ = 'specialize:memo' + +def _gettypenames(space, *args_w): + if args_w: + typename = space.type(args_w[-1]).getname(space, '?') + return _gettypenames(space, *args_w[:-1]) + (typename,) + return () +_gettypenames._always_inline_ = True + +def gettypeerror(space, operatorsymbol, *args_w): + msg = _gettypeerrormsg(len(args_w)) + type_names = _gettypenames(space, *args_w) + return operationerrfmt(space.w_TypeError, msg, + operatorsymbol, *type_names) def make_perform_trampoline(prefix, exprargs, expr, miniglobals, multimethod, selfindex=0, allow_NotImplemented_results=False): @@ -172,7 +183,7 @@ wrapper_arglist += multimethod.extras.get('extra_args', ()) miniglobals.update({ 'OperationError': OperationError, - 'typeerrormsg': typeerrormsg}) + 'gettypeerror': gettypeerror}) app_defaults = multimethod.extras.get('defaults', ()) i = len(argnames) - len(app_defaults) @@ -209,7 +220,7 @@ return %s except FailedToImplement, e: if e.w_type is not None: - raise OperationError(e.w_type, e.w_value) + raise OperationError(e.w_type, e.get_w_value(space)) else: return space.w_NotImplemented """ % (prefix, wrapper_sig, renaming, expr) @@ -221,10 +232,9 @@ w_res = %s except FailedToImplement, e: if e.w_type is not None: - raise OperationError(e.w_type, e.w_value) + raise OperationError(e.w_type, e.get_w_value(space)) else: - raise OperationError(space.w_TypeError, - typeerrormsg(space, %r, [%s])) + raise gettypeerror(space, %r, %s) if w_res is None: w_res = space.w_None return w_res Modified: pypy/branch/stringbuilder2/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/stringobject.py Tue Jan 26 15:23:26 2010 @@ -1,6 +1,7 @@ -# -*- coding: latin-1 -*- - -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.rlib.rarithmetic import ovfcheck from pypy.rlib.objectmodel import we_are_translated, compute_hash @@ -365,11 +366,10 @@ w_list = space.newlist(list_w) w_u = space.call_function(space.w_unicode, w_self) return space.call_method(w_u, "join", w_list) - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("sequence item %d: expected string, %s " - "found" % (i, - space.type(w_s).getname(space, '?')))) + "sequence item %d: expected string, %s " + "found", i, space.type(w_s).getname(space, '?')) l[i] = space.str_w(w_s) return space.wrap(self.join(l)) else: @@ -816,9 +816,8 @@ if ival < 0: ival += slen if ival < 0 or ival >= slen: - exc = space.call_function(space.w_IndexError, - space.wrap("string index out of range")) - raise OperationError(space.w_IndexError, exc) + raise OperationError(space.w_IndexError, + space.wrap("string index out of range")) return wrapchar(space, str[ival]) def getitem__String_Slice(space, w_str, w_slice): @@ -857,9 +856,10 @@ try: buflen = ovfcheck(mul * input_len) except OverflowError: - raise OperationError( + raise operationerrfmt( space.w_OverflowError, - space.wrap("repeated string is too long: %d %d" % (input_len, mul))) + "repeated string is too long: %d times %d characters", + mul, input_len) # XXX maybe only do this when input has a big length return joined(space, [input] * mul) @@ -889,10 +889,10 @@ def ord__String(space, w_str): u_str = w_str._value if len(u_str) != 1: - raise OperationError( + raise operationerrfmt( space.w_TypeError, - space.wrap("ord() expected a character, but string " - "of length %d found"%(len(w_str._value),))) + "ord() expected a character, but string " + "of length %d found", len(u_str)) return space.wrap(ord(u_str)) def getnewargs__String(space, w_str): Modified: pypy/branch/stringbuilder2/pypy/objspace/std/transparent.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/transparent.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/transparent.py Tue Jan 26 15:23:26 2010 @@ -4,7 +4,7 @@ from pypy.interpreter import gateway from pypy.interpreter.function import Function -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.proxyobject import * from pypy.objspace.std.typeobject import W_TypeObject from pypy.rlib.objectmodel import r_dict @@ -52,8 +52,9 @@ for k, v in type_cache.cache: if w_lookup == k: return v(space, w_type, w_controller) - raise OperationError(space.w_TypeError, space.wrap("Object type %s could not "\ - "be wrapped (YET)" % w_type.getname(space, "?"))) + raise operationerrfmt(space.w_TypeError, + "'%s' object could not be wrapped (YET)", + w_type.getname(space, "?")) def register_proxyable(space, cls): tpdef = cls.typedef Modified: pypy/branch/stringbuilder2/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/typeobject.py Tue Jan 26 15:23:26 2010 @@ -1,6 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import weakref_descr from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member from pypy.objspace.std.objecttype import object_typedef @@ -283,17 +284,17 @@ def check_user_subclass(w_self, w_subtype): space = w_self.space if not isinstance(w_subtype, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap("X is not a type object (%s)" % ( - space.type(w_subtype).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "X is not a type object ('%s')", + space.type(w_subtype).getname(space, '?')) if not space.is_true(space.issubtype(w_subtype, w_self)): - raise OperationError(space.w_TypeError, - space.wrap("%s.__new__(%s): %s is not a subtype of %s" % ( - w_self.name, w_subtype.name, w_subtype.name, w_self.name))) + raise operationerrfmt(space.w_TypeError, + "%s.__new__(%s): %s is not a subtype of %s", + w_self.name, w_subtype.name, w_subtype.name, w_self.name) if w_self.instancetypedef is not w_subtype.instancetypedef: - raise OperationError(space.w_TypeError, - space.wrap("%s.__new__(%s) is not safe, use %s.__new__()" % ( - w_self.name, w_subtype.name, w_subtype.name))) + raise operationerrfmt(space.w_TypeError, + "%s.__new__(%s) is not safe, use %s.__new__()", + w_self.name, w_subtype.name, w_subtype.name) return w_subtype def _freeze_(w_self): @@ -444,10 +445,10 @@ space.wrap("a new-style class can't have " "only classic bases")) if not w_bestbase.instancetypedef.acceptable_as_base_class: - raise OperationError(space.w_TypeError, - space.wrap("type '%s' is not an " - "acceptable base class" % - w_bestbase.instancetypedef.name)) + raise operationerrfmt(space.w_TypeError, + "type '%s' is not an " + "acceptable base class", + w_bestbase.instancetypedef.name) # check that all other bases' layouts are superclasses of the bestbase w_bestlayout = w_bestbase.w_same_layout_as or w_bestbase @@ -703,8 +704,9 @@ return space.get(w_value, space.w_None, w_type) if w_descr is not None: return space.get(w_descr,w_type) - msg = "type object '%s' has no attribute '%s'" %(w_type.name, name) - raise OperationError(space.w_AttributeError, space.wrap(msg)) + raise operationerrfmt(space.w_AttributeError, + "type object '%s' has no attribute '%s'", + w_type.name, name) def setattr__Type_ANY_ANY(space, w_type, w_name, w_value): # Note. This is exactly the same thing as descroperation.descr__setattr__, @@ -719,8 +721,8 @@ if (space.config.objspace.std.immutable_builtintypes and not w_type.is_heaptype()): - msg = "can't set attributes on type object '%s'" %(w_type.name,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "can't set attributes on type object '%s'" + raise operationerrfmt(space.w_TypeError, msg, w_type.name) if name == "__del__" and name not in w_type.dict_w: msg = "a __del__ method added to an existing type will not be called" space.warn(msg, space.w_RuntimeWarning) @@ -738,8 +740,8 @@ return if (space.config.objspace.std.immutable_builtintypes and not w_type.is_heaptype()): - msg = "can't delete attributes on type object '%s'" %(w_type.name,) - raise OperationError(space.w_TypeError, space.wrap(msg)) + msg = "can't delete attributes on type object '%s'" + raise operationerrfmt(space.w_TypeError, msg, w_type.name) try: del w_type.dict_w[name] except KeyError: @@ -806,8 +808,9 @@ candidate = orderlists[-1][0] if candidate in orderlists[-1][1:]: # explicit error message for this specific case - raise OperationError(space.w_TypeError, - space.wrap("duplicate base class " + candidate.getname(space,"?"))) + raise operationerrfmt(space.w_TypeError, + "duplicate base class '%s'", + candidate.getname(space,"?")) while candidate not in cycle: cycle.append(candidate) nextblockinglist = mro_blockinglist(candidate, orderlists) Modified: pypy/branch/stringbuilder2/pypy/objspace/std/typetype.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/typetype.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/typetype.py Tue Jan 26 15:23:26 2010 @@ -1,4 +1,4 @@ -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import weakref_descr @@ -51,18 +51,19 @@ def _precheck_for_new(space, w_type): from pypy.objspace.std.typeobject import W_TypeObject if not isinstance(w_type, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap("X is not a type object (%s)" % - (space.type(w_type).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "X is not a type object (%s)", + space.type(w_type).getname(space, '?')) return w_type # ____________________________________________________________ -def _check(space, w_type, msg=None): +def _check(space, w_type, w_msg=None): from pypy.objspace.std.typeobject import W_TypeObject if not isinstance(w_type, W_TypeObject): - raise OperationError(space.w_TypeError, - space.wrap(msg or "descriptor is for 'type'")) + if w_msg is None: + w_msg = space.wrap("descriptor is for 'type'") + raise OperationError(space.w_TypeError, w_msg) return w_type @@ -73,9 +74,8 @@ def descr_set__name__(space, w_type, w_value): w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise OperationError(space.w_TypeError, - space.wrap("can't set %s.__name__" % - w_type.name)) + raise operationerrfmt(space.w_TypeError, + "can't set %s.__name__", w_type.name) w_type.name = space.str_w(w_value) def descr_get__mro__(space, w_type): @@ -84,7 +84,7 @@ def descr_mro(space, w_type): """Return a type's method resolution order.""" - w_type = _check(space, w_type,"expected type") + w_type = _check(space, w_type, space.wrap("expected type")) return space.newlist(w_type.compute_default_mro()) def descr_get__bases__(space, w_type): @@ -106,21 +106,18 @@ from pypy.objspace.std.typeobject import get_parent_layout w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise OperationError(space.w_TypeError, - space.wrap("can't set %s.__bases__" % - (w_type.name,))) + raise operationerrfmt(space.w_TypeError, + "can't set %s.__bases__", w_type.name) if not space.is_true(space.isinstance(w_value, space.w_tuple)): - raise OperationError(space.w_TypeError, - space.wrap("can only assign tuple" - " to %s.__bases__, not %s"% - (w_type.name, - space.type(w_value).getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "can only assign tuple to %s.__bases__, not %s", + w_type.name, + space.type(w_value).getname(space, '?')) newbases_w = space.fixedview(w_value) if len(newbases_w) == 0: - raise OperationError(space.w_TypeError, - space.wrap("can only assign non-empty tuple" - " to %s.__bases__, not ()"% - (w_type.name,))) + raise operationerrfmt(space.w_TypeError, + "can only assign non-empty tuple to %s.__bases__, not ()", + w_type.name) for w_newbase in newbases_w: if isinstance(w_newbase, W_TypeObject): @@ -135,11 +132,11 @@ newlayout = w_newbestbase.get_full_instance_layout() if oldlayout != newlayout: - raise OperationError(space.w_TypeError, - space.wrap("__bases__ assignment: '%s' object layout" - " differs from '%s'" % - (w_newbestbase.getname(space, '?'), - w_oldbestbase.getname(space, '?')))) + raise operationerrfmt(space.w_TypeError, + "__bases__ assignment: '%s' object layout" + " differs from '%s'", + w_newbestbase.getname(space, '?'), + w_oldbestbase.getname(space, '?')) # invalidate the version_tag of all the current subclasses w_type.mutated() @@ -191,9 +188,9 @@ def descr_set__module(space, w_type, w_value): w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise OperationError(space.w_TypeError, - space.wrap("can't set %s.__module__" % - w_type.name)) + raise operationerrfmt(space.w_TypeError, + "can't set %s.__module__", + w_type.name) w_type.mutated() w_type.dict_w['__module__'] = w_value Modified: pypy/branch/stringbuilder2/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/unicodeobject.py Tue Jan 26 15:23:26 2010 @@ -1,5 +1,8 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.stringobject import W_StringObject, make_rsplit_with_delim from pypy.objspace.std.ropeobject import W_RopeObject from pypy.objspace.std.noneobject import W_NoneObject @@ -42,8 +45,9 @@ # Helper for converting int/long def unicode_to_decimal_w(space, w_unistr): if not isinstance(w_unistr, W_UnicodeObject): - raise OperationError(space.w_TypeError, - space.wrap("expected unicode")) + raise operationerrfmt(space.w_TypeError, + "expected unicode, got '%s'", + space.type(w_unistr).getname(space, '?')) unistr = w_unistr._value result = ['\0'] * len(unistr) digits = [ '0', '1', '2', '3', '4', @@ -63,7 +67,7 @@ w_start = space.wrap(i) w_end = space.wrap(i+1) w_reason = space.wrap('invalid decimal Unicode string') - raise OperationError(space.w_UnicodeEncodeError,space.newtuple ([w_encoding, w_unistr, w_start, w_end, w_reason])) + raise OperationError(space.w_UnicodeEncodeError, space.newtuple([w_encoding, w_unistr, w_start, w_end, w_reason])) return ''.join(result) # string-to-unicode delegation @@ -80,11 +84,11 @@ except OperationError, e: if e.match(space, space.w_UnicodeDecodeError): if inverse: - word = "unequal" + msg = "Unicode unequal comparison failed to convert both " \ + "arguments to Unicode - interpreting them as being unequal" else : - word = "equal" - msg = "Unicode %s comparison failed to convert both arguments\ - to Unicode - interpreting them as being unequal" % word + msg = "Unicode equal comparison failed to convert both " \ + "arguments to Unicode - interpreting them as being unequal" space.warn(msg, space.w_UnicodeWarning) return space.newbool(inverse) raise @@ -127,7 +131,9 @@ def ord__Unicode(space, w_uni): if len(w_uni._value) != 1: - raise OperationError(space.w_TypeError, space.wrap('ord() expected a character')) + raise operationerrfmt(space.w_TypeError, + "ord() expected a character, got a unicode of length %d", + len(w_uni._value)) return space.wrap(ord(w_uni._value[0])) def getnewargs__Unicode(space, w_uni): @@ -192,9 +198,8 @@ elif space.is_true(space.isinstance(item, space.w_str)): item = space.unicode_w(item) else: - w_msg = space.mod(space.wrap('sequence item %d: expected string or Unicode'), - space.wrap(i)) - raise OperationError(space.w_TypeError, w_msg) + raise operationerrfmt(space.w_TypeError, + "sequence item %d: expected string or Unicode", i) values_list[i] = item return W_UnicodeObject(w_self._value.join(values_list)) Modified: pypy/branch/stringbuilder2/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/std/unicodetype.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/std/unicodetype.py Tue Jan 26 15:23:26 2010 @@ -2,7 +2,7 @@ from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all from pypy.objspace.std.basestringtype import basestring_typedef -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from sys import maxint @@ -181,11 +181,9 @@ w_restuple = space.call_function(w_encoder, w_object, w_errors) w_retval = space.getitem(w_restuple, space.wrap(0)) if not space.is_true(space.isinstance(w_retval, space.w_str)): - raise OperationError( - space.w_TypeError, - space.wrap( - "encoder did not return an string object (type=%s)" % - space.type(w_retval).getname(space, '?'))) + raise operationerrfmt(space.w_TypeError, + "encoder did not return an string object (type '%s')", + space.type(w_retval).getname(space, '?')) return w_retval def decode_object(space, w_obj, encoding, errors): @@ -204,11 +202,9 @@ def unicode_from_encoded_object(space, w_obj, encoding, errors): w_retval = decode_object(space, w_obj, encoding, errors) if not space.is_true(space.isinstance(w_retval, space.w_unicode)): - raise OperationError( - space.w_TypeError, - space.wrap( - "decoder did not return an unicode object (type=%s)" % - space.type(w_retval).getname(space, '?'))) + raise operationerrfmt(space.w_TypeError, + "decoder did not return an unicode object (type '%s')", + space.type(w_retval).getname(space, '?')) return w_retval def unicode_from_object(space, w_obj): Modified: pypy/branch/stringbuilder2/pypy/objspace/test/test_descroperation.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/objspace/test/test_descroperation.py (original) +++ pypy/branch/stringbuilder2/pypy/objspace/test/test_descroperation.py Tue Jan 26 15:23:26 2010 @@ -371,5 +371,14 @@ A() < B() assert l == [B, A, A, B] + def test_mod_failure(self): + try: + [] % 3 + except TypeError, e: + assert '%' in str(e) + else: + assert False, "did not raise" + + class AppTestWithBuiltinShortcut(AppTest_Descroperation): OPTIONS = {'objspace.std.builtinshortcut': True} Modified: pypy/branch/stringbuilder2/pypy/tool/test/test_pytestsupport.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/tool/test/test_pytestsupport.py (original) +++ pypy/branch/stringbuilder2/pypy/tool/test/test_pytestsupport.py Tue Jan 26 15:23:26 2010 @@ -41,7 +41,7 @@ f.call_args(Arguments(None, [])) except OperationError, e: assert e.match(space, space.w_AssertionError) - assert space.unwrap(space.str(e.w_value)) == 'assert 42 == 43' + assert space.unwrap(space.str(e.get_w_value(space))) == 'assert 42 == 43' else: assert False, "got no exception!" Modified: pypy/branch/stringbuilder2/pypy/tool/traceop.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/tool/traceop.py (original) +++ pypy/branch/stringbuilder2/pypy/tool/traceop.py Tue Jan 26 15:23:26 2010 @@ -273,7 +273,7 @@ # Special case - operation error if isinstance(obj, OperationError): return "OpError(%s, %s)" % (repr_value(space, obj.w_type), - repr_value(space, obj.w_value)) + repr_value(space, obj.get_w_value(space))) # Try object repr try: Modified: pypy/branch/stringbuilder2/pypy/translator/geninterplevel.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/geninterplevel.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/geninterplevel.py Tue Jan 26 15:23:26 2010 @@ -1366,7 +1366,7 @@ q = "elif" for op in self.gen_link(link, localscope, blocknum, block, { link.last_exception: 'e.w_type', - link.last_exc_value: 'e.w_value'}): + link.last_exc_value: 'e.get_w_value(space)'}): yield " %s" % op yield " else:raise # unhandled case, should not happen" else: Modified: pypy/branch/stringbuilder2/pypy/translator/goal/sharedpypy.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/goal/sharedpypy.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/goal/sharedpypy.py Tue Jan 26 15:23:26 2010 @@ -39,7 +39,7 @@ except OperationError, e: print "OperationError:" print " operror-type: " + e.w_type.getname(space, '?') - print " operror-value: " + space.str_w(space.str(e.w_value)) + print " operror-value: " + space.str_w(space.str(e.get_w_value(space))) return 1 return 0 Modified: pypy/branch/stringbuilder2/pypy/translator/goal/targetpreimportedpypy.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/goal/targetpreimportedpypy.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/goal/targetpreimportedpypy.py Tue Jan 26 15:23:26 2010 @@ -74,7 +74,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 finally: try: @@ -84,7 +84,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 space.timer.stop("Entrypoint") space.timer.dump() Modified: pypy/branch/stringbuilder2/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/branch/stringbuilder2/pypy/translator/goal/targetpypystandalone.py Tue Jan 26 15:23:26 2010 @@ -62,7 +62,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 finally: try: @@ -72,7 +72,7 @@ except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space, '?')) - debug(" operror-value: " + space.str_w(space.str(e.w_value))) + debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return 1 space.timer.stop("Entrypoint") space.timer.dump() From cfbolz at codespeak.net Tue Jan 26 15:49:14 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 26 Jan 2010 15:49:14 +0100 (CET) Subject: [pypy-svn] r70886 - pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std Message-ID: <20100126144914.1412116807B@codespeak.net> Author: cfbolz Date: Tue Jan 26 15:49:14 2010 New Revision: 70886 Modified: pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py Log: two more unroll-safe needed Modified: pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py Tue Jan 26 15:49:14 2010 @@ -212,6 +212,7 @@ return w_value + @jit.unroll_safe def peel_flags(self): self.f_ljust = False self.f_sign = False @@ -234,6 +235,7 @@ break self.forward() + @jit.unroll_safe def peel_num(self): space = self.space c = self.peekchr() From arigo at codespeak.net Tue Jan 26 15:53:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 15:53:31 +0100 (CET) Subject: [pypy-svn] r70887 - pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform Message-ID: <20100126145331.C639816807B@codespeak.net> Author: arigo Date: Tue Jan 26 15:53:31 2010 New Revision: 70887 Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/boehm.py pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py Log: Kill old unused code. Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/boehm.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/boehm.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/boehm.py Tue Jan 26 15:53:31 2010 @@ -22,19 +22,12 @@ mh = mallocHelpers() mh.allocate = lambda size: llop.boehm_malloc(llmemory.Address, size) - c_realloc = rffi.llexternal('GC_REALLOC', [rffi.VOIDP, rffi.INT], - rffi.VOIDP, sandboxsafe=True) - def _realloc(ptr, size): - return llmemory.cast_ptr_to_adr(c_realloc(rffi.cast(rffi.VOIDP, ptr), size)) - mh.realloc = _realloc ll_malloc_fixedsize = mh._ll_malloc_fixedsize # XXX, do we need/want an atomic version of this function? ll_malloc_varsize_no_length = mh.ll_malloc_varsize_no_length ll_malloc_varsize = mh.ll_malloc_varsize - ll_realloc = mh.ll_realloc - HDRPTR = lltype.Ptr(self.HDR) def ll_identityhash(addr): @@ -58,9 +51,6 @@ inline=False) self.weakref_deref_ptr = self.inittime_helper( ll_weakref_deref, [llmemory.WeakRefPtr], llmemory.Address) - self.realloc_ptr = self.inittime_helper( - ll_realloc, [llmemory.Address] + [lltype.Signed] * 4, - llmemory.Address) self.identityhash_ptr = self.inittime_helper( ll_identityhash, [llmemory.Address], lltype.Signed, inline=False) @@ -73,15 +63,6 @@ def pop_alive_nopyobj(self, var, llops): pass - def _can_realloc(self): - return True - - def perform_realloc(self, hop, v_ptr, v_newlgt, c_const_size, c_item_size, - c_lengthofs, c_itemsofs, c_grow): - args = [self.realloc_ptr, v_ptr, v_newlgt, c_const_size, - c_item_size, c_lengthofs] - return hop.genop('direct_call', args, resulttype=llmemory.Address) - def gct_fv_gc_malloc(self, hop, flags, TYPE, c_size): # XXX same behavior for zero=True: in theory that's wrong if TYPE._is_atomic(): Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/framework.py Tue Jan 26 15:53:31 2010 @@ -366,25 +366,6 @@ else: self.malloc_varsize_nonmovable_ptr = None -## if getattr(GCClass, 'malloc_varsize_resizable', False): -## malloc_resizable = func_with_new_name( -## GCClass.malloc_varsize_resizable.im_func, -## "malloc_varsize_resizable") -## self.malloc_varsize_resizable_ptr = getfn( -## malloc_resizable, -## [s_gc, s_typeid16, -## annmodel.SomeInteger(nonneg=True)], s_gcref) -## else: -## self.malloc_varsize_resizable_ptr = None - - if getattr(GCClass, 'realloc', False): - self.realloc_ptr = getfn( - GCClass.realloc.im_func, - [s_gc, s_gcref] + - [annmodel.SomeInteger(nonneg=True)] * 6 + - [annmodel.SomeBool()], - s_gcref) - self.identityhash_ptr = getfn(GCClass.identityhash.im_func, [s_gc, s_gcref], annmodel.SomeInteger(), @@ -635,10 +616,6 @@ info_varsize.ofstolength) c_varitemsize = rmodel.inputconst(lltype.Signed, info_varsize.varitemsize) -## if flags.get('resizable') and self.malloc_varsize_resizable_ptr: -## assert c_can_collect.value -## malloc_ptr = self.malloc_varsize_resizable_ptr -## args = [self.c_const_gc, c_type_id, v_length] if flags.get('nonmovable') and self.malloc_varsize_nonmovable_ptr: # we don't have tests for such cases, let's fail # explicitely @@ -735,20 +712,6 @@ resulttype=llmemory.Address) hop.genop('adr_add', [v_gc_adr, c_ofs], resultvar=op.result) - def _can_realloc(self): - return True - - def perform_realloc(self, hop, v_ptr, v_oldsize, v_newsize, c_const_size, - c_itemsize, c_lengthofs, c_itemsofs, c_grow): - vlist = [self.realloc_ptr, self.c_const_gc, v_ptr, - v_oldsize, v_newsize, - c_const_size, c_itemsize, c_lengthofs, c_itemsofs, c_grow] - livevars = self.push_roots(hop) - v_result = hop.genop('direct_call', vlist, - resulttype=llmemory.GCREF) - self.pop_roots(hop, livevars) - return v_result - def gct_gc_x_swap_pool(self, hop): op = hop.spaceop [v_malloced] = op.args Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gctransform/transform.py Tue Jan 26 15:53:31 2010 @@ -482,15 +482,6 @@ return result mh.ll_malloc_varsize_no_length_zero = _ll_malloc_varsize_no_length_zero - def ll_realloc(ptr, length, constsize, itemsize, lengthoffset): - size = constsize + length * itemsize - result = mh.realloc(ptr, size) - if not result: - raise MemoryError() - (result + lengthoffset).signed[0] = length - return result - mh.ll_realloc = ll_realloc - return mh class GCTransformer(BaseGCTransformer): From arigo at codespeak.net Tue Jan 26 15:56:38 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 15:56:38 +0100 (CET) Subject: [pypy-svn] r70888 - in pypy/branch/stringbuilder2/pypy: rpython rpython/lltypesystem rpython/lltypesystem/test translator/c/src Message-ID: <20100126145638.735E5168079@codespeak.net> Author: arigo Date: Tue Jan 26 15:56:37 2010 New Revision: 70888 Modified: pypy/branch/stringbuilder2/pypy/rpython/llinterp.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llmemory.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llmemory.py pypy/branch/stringbuilder2/pypy/translator/c/src/mem.h Log: Kill 'raw_realloc_{shrink,grow}', which are old apparently-unused lloperations. Modified: pypy/branch/stringbuilder2/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/llinterp.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/llinterp.py Tue Jan 26 15:56:37 2010 @@ -964,14 +964,6 @@ assert lltype.typeOf(size) == lltype.Signed return llmemory.raw_malloc(size) - def op_raw_realloc_grow(self, addr, old_size, size): - assert lltype.typeOf(size) == lltype.Signed - return llmemory.raw_realloc_grow(addr, old_size, size) - - def op_raw_realloc_shrink(self, addr, old_size, size): - assert lltype.typeOf(size) == lltype.Signed - return llmemory.raw_realloc_shrink(addr, old_size, size) - op_boehm_malloc = op_boehm_malloc_atomic = op_raw_malloc def op_boehm_register_finalizer(self, p, finalizer): Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llmemory.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llmemory.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/llmemory.py Tue Jan 26 15:56:37 2010 @@ -716,18 +716,6 @@ raise NotImplementedError(size) return size._raw_malloc([], zero=False) -def raw_realloc_grow(addr, old_size, size): - new_area = size._raw_malloc([], zero=False) - raw_memcopy(addr, new_area, old_size) - raw_free(addr) - return new_area - -def raw_realloc_shrink(addr, old_size, size): - new_area = size._raw_malloc([], zero=False) - raw_memcopy(addr, new_area, size) - raw_free(addr) - return new_area - def raw_free(adr): # try to free the whole object if 'adr' is the address of the header from pypy.rpython.memory.gcheader import GCHeaderBuilder Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/lloperation.py Tue Jan 26 15:56:37 2010 @@ -389,8 +389,6 @@ 'boehm_register_finalizer': LLOp(), 'boehm_disappearing_link': LLOp(), 'raw_malloc': LLOp(), - 'raw_realloc_grow': LLOp(), - 'raw_realloc_shrink': LLOp(), 'raw_malloc_usage': LLOp(sideeffects=False), 'raw_free': LLOp(), 'raw_memclear': LLOp(), Modified: pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llmemory.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llmemory.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/lltypesystem/test/test_llmemory.py Tue Jan 26 15:56:37 2010 @@ -624,31 +624,3 @@ # the following line crashes if the array is dead ptr1 = cast_adr_to_ptr(adr, lltype.Ptr(lltype.FixedSizeArray(Address, 1))) ptr1[0] = NULL - -def test_realloc(): - A = lltype.Array(lltype.Float) - adr = raw_malloc(sizeof(A, 10)) - ptr = cast_adr_to_ptr(adr, lltype.Ptr(A)) - for i in range(10): - ptr[i] = float(i) - adr2 = raw_realloc_shrink(adr, sizeof(A, 10), sizeof(A, 5)) - ptr2 = cast_adr_to_ptr(adr2, lltype.Ptr(A)) - assert len(ptr2) == 5 - assert ptr2[3] == 3.0 - assert ptr2[1] == 1.0 - -def test_realloc_struct(): - S = lltype.Struct('x', ('one', lltype.Signed), - ('a', lltype.Array(lltype.Float))) - adr = raw_malloc(sizeof(S, 5)) - ptr = cast_adr_to_ptr(adr, lltype.Ptr(S)) - for i in range(5): - ptr.a[i] = float(i) - ptr.one = 3 - adr2 = raw_realloc_grow(adr, sizeof(S, 5), sizeof(S, 10)) - ptr2 = cast_adr_to_ptr(adr2, lltype.Ptr(S)) - assert len(ptr2.a) == 10 - assert ptr2.a[3] == 3.0 - assert ptr2.a[0] == 0.0 - assert ptr2.one == 3 - Modified: pypy/branch/stringbuilder2/pypy/translator/c/src/mem.h ============================================================================== --- pypy/branch/stringbuilder2/pypy/translator/c/src/mem.h (original) +++ pypy/branch/stringbuilder2/pypy/translator/c/src/mem.h Tue Jan 26 15:56:37 2010 @@ -101,10 +101,6 @@ #define OP_RAW_MALLOC_USAGE(size, r) r = size -#define OP_RAW_REALLOC_SHRINK(p, old_size, size, r) r = PyObject_Realloc((void*)p, size) - -#define OP_RAW_REALLOC_GROW(p, old_size, size, r) r = PyObject_Realloc((void*)p, size) - #ifdef MS_WINDOWS #define alloca _alloca #endif From cfbolz at codespeak.net Tue Jan 26 16:26:22 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 26 Jan 2010 16:26:22 +0100 (CET) Subject: [pypy-svn] r70889 - pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std Message-ID: <20100126152622.CB77C16807B@codespeak.net> Author: cfbolz Date: Tue Jan 26 16:26:21 2010 New Revision: 70889 Modified: pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py Log: this is on the silly side, but it helps the jit Modified: pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/objspace/std/formatting.py Tue Jan 26 16:26:21 2010 @@ -22,13 +22,12 @@ def nextinputvalue(self): # return the next value in the tuple of input arguments - try: - w_result = self.values_w[self.values_pos] - except IndexError: + if self.values_pos >= len(self.values_w): space = self.space raise OperationError(space.w_TypeError, space.wrap( 'not enough arguments for format string')) else: + w_result = self.values_w[self.values_pos] self.values_pos += 1 return w_result From cfbolz at codespeak.net Tue Jan 26 16:36:21 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 26 Jan 2010 16:36:21 +0100 (CET) Subject: [pypy-svn] r70890 - pypy/branch/unroll-safe-if-const-arg/pypy/rpython/lltypesystem Message-ID: <20100126153621.C2C2416807B@codespeak.net> Author: cfbolz Date: Tue Jan 26 16:36:20 2010 New Revision: 70890 Modified: pypy/branch/unroll-safe-if-const-arg/pypy/rpython/lltypesystem/rstr.py Log: mark character finding as pure. at some point we should do that systematically about string functions. Modified: pypy/branch/unroll-safe-if-const-arg/pypy/rpython/lltypesystem/rstr.py ============================================================================== --- pypy/branch/unroll-safe-if-const-arg/pypy/rpython/lltypesystem/rstr.py (original) +++ pypy/branch/unroll-safe-if-const-arg/pypy/rpython/lltypesystem/rstr.py Tue Jan 26 16:36:20 2010 @@ -450,6 +450,7 @@ return True + @purefunction def ll_find_char(s, ch, start, end): i = start if end > len(s.chars): @@ -460,6 +461,7 @@ i += 1 return -1 + @purefunction def ll_rfind_char(s, ch, start, end): if end > len(s.chars): end = len(s.chars) From arigo at codespeak.net Tue Jan 26 16:39:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 16:39:57 +0100 (CET) Subject: [pypy-svn] r70891 - pypy/trunk/pypy/jit/metainterp/test Message-ID: <20100126153957.8B19516807B@codespeak.net> Author: arigo Date: Tue Jan 26 16:39:57 2010 New Revision: 70891 Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py Log: A failing test. Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_basic.py Tue Jan 26 16:39:57 2010 @@ -1284,7 +1284,24 @@ return res res = self.meta_interp(f, [21]) assert res == f(21) - + + def test_getitem_indexerror(self): + py.test.skip("failing test!") + lst = [10, 4, 9, 16] + def f(n): + try: + return lst[n] + except IndexError: + return -2 + res = self.interp_operations(f, [2]) + assert res == 9 + res = self.interp_operations(f, [4]) + assert res == -2 + res = self.interp_operations(f, [-4]) + assert res == 10 + res = self.interp_operations(f, [-5]) + assert res == -2 + class TestOOtype(BasicTests, OOJitMixin): From arigo at codespeak.net Tue Jan 26 17:01:37 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 17:01:37 +0100 (CET) Subject: [pypy-svn] r70892 - in pypy/trunk/pypy: jit/metainterp jit/metainterp/test rpython Message-ID: <20100126160137.C4B4316807B@codespeak.net> Author: arigo Date: Tue Jan 26 17:01:36 2010 New Revision: 70892 Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py pypy/trunk/pypy/jit/metainterp/test/test_basic.py pypy/trunk/pypy/rpython/rlist.py Log: Fix test_getitem_indexerror. Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/codewriter.py Tue Jan 26 17:01:36 2010 @@ -1326,7 +1326,7 @@ if self.handle_list_call(op, oopspec_name, args, TP): return if oopspec_name.endswith('_foldable'): - opname = 'residual_call_pure' # XXX not for possibly-raising calls + opname = 'residual_call_pure' # should not raise, either else: opname = 'residual_call' Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_basic.py Tue Jan 26 17:01:36 2010 @@ -1286,7 +1286,6 @@ assert res == f(21) def test_getitem_indexerror(self): - py.test.skip("failing test!") lst = [10, 4, 9, 16] def f(n): try: Modified: pypy/trunk/pypy/rpython/rlist.py ============================================================================== --- pypy/trunk/pypy/rpython/rlist.py (original) +++ pypy/trunk/pypy/rpython/rlist.py Tue Jan 26 17:01:36 2010 @@ -247,12 +247,14 @@ spec = dum_nocheck v_func = hop.inputconst(Void, spec) v_lst, v_index = hop.inputargs(r_lst, Signed) - if hop.args_s[0].listdef.listitem.mutated: + if hop.args_s[0].listdef.listitem.mutated or checkidx: if hop.args_s[1].nonneg: llfn = ll_getitem_nonneg else: llfn = ll_getitem else: + # this is the 'foldable' version, which is not used when + # we check for IndexError if hop.args_s[1].nonneg: llfn = ll_getitem_foldable_nonneg else: From arigo at codespeak.net Tue Jan 26 17:36:48 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 17:36:48 +0100 (CET) Subject: [pypy-svn] r70894 - pypy/branch/stringbuilder2/pypy/rpython/memory/gc Message-ID: <20100126163648.8E60F16807B@codespeak.net> Author: arigo Date: Tue Jan 26 17:36:48 2010 New Revision: 70894 Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py Log: Remove unneeded import. Modified: pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py (original) +++ pypy/branch/stringbuilder2/pypy/rpython/memory/gc/base.py Tue Jan 26 17:36:48 2010 @@ -1,6 +1,5 @@ from pypy.rpython.lltypesystem import lltype, llmemory, llarena from pypy.rlib.debug import ll_assert -from pypy.rlib.objectmodel import keepalive_until_here from pypy.rpython.memory.gcheader import GCHeaderBuilder from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE from pypy.rpython.memory.support import get_address_stack, get_address_deque From arigo at codespeak.net Tue Jan 26 17:44:41 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 17:44:41 +0100 (CET) Subject: [pypy-svn] r70895 - in pypy/trunk/pypy: rlib rlib/test rpython rpython/lltypesystem rpython/lltypesystem/test rpython/memory rpython/memory/gc rpython/memory/gc/test rpython/memory/gctransform rpython/memory/test rpython/test translator/c/src translator/c/test Message-ID: <20100126164441.7ED1D16807B@codespeak.net> Author: arigo Date: Tue Jan 26 17:44:40 2010 New Revision: 70895 Modified: pypy/trunk/pypy/rlib/rgc.py pypy/trunk/pypy/rlib/test/test_rgc.py pypy/trunk/pypy/rpython/llinterp.py pypy/trunk/pypy/rpython/lltypesystem/llarena.py pypy/trunk/pypy/rpython/lltypesystem/llheap.py pypy/trunk/pypy/rpython/lltypesystem/llmemory.py pypy/trunk/pypy/rpython/lltypesystem/lloperation.py pypy/trunk/pypy/rpython/lltypesystem/lltype.py pypy/trunk/pypy/rpython/lltypesystem/opimpl.py pypy/trunk/pypy/rpython/lltypesystem/rbuilder.py pypy/trunk/pypy/rpython/lltypesystem/test/test_llarena.py pypy/trunk/pypy/rpython/lltypesystem/test/test_llmemory.py pypy/trunk/pypy/rpython/memory/gc/base.py pypy/trunk/pypy/rpython/memory/gc/hybrid.py pypy/trunk/pypy/rpython/memory/gc/semispace.py pypy/trunk/pypy/rpython/memory/gc/test/test_direct.py pypy/trunk/pypy/rpython/memory/gctransform/boehm.py pypy/trunk/pypy/rpython/memory/gctransform/framework.py pypy/trunk/pypy/rpython/memory/gctransform/transform.py pypy/trunk/pypy/rpython/memory/gcwrapper.py pypy/trunk/pypy/rpython/memory/test/test_gc.py pypy/trunk/pypy/rpython/memory/test/test_transformed_gc.py pypy/trunk/pypy/rpython/test/test_rbuilder.py pypy/trunk/pypy/translator/c/src/mem.h pypy/trunk/pypy/translator/c/test/test_boehm.py pypy/trunk/pypy/translator/c/test/test_newgc.py Log: (arigo, fijal) Merge branch/stringbuilder2: Simplifies a lot the implementation of stringbuilder, getting rid of various realloc_* and resizable_buffer_* operations. Replaces it with just one operation: 'shrink_array'. Modified: pypy/trunk/pypy/rlib/rgc.py ============================================================================== --- pypy/trunk/pypy/rlib/rgc.py (original) +++ pypy/trunk/pypy/rlib/rgc.py Tue Jan 26 17:44:40 2010 @@ -242,95 +242,6 @@ hop.exception_cannot_occur() return hop.genop(opname, vlist, resulttype = hop.r_result.lowleveltype) -def resizable_buffer_of_shape(T, init_size): - """ Pre-allocates structure of type T (varsized) with possibility - to reallocate it further by resize_buffer. - """ - from pypy.rpython.lltypesystem import lltype - return lltype.malloc(T, init_size) - -class ResizableBufferOfShapeEntry(ExtRegistryEntry): - _about_ = resizable_buffer_of_shape - - def compute_result_annotation(self, s_T, s_init_size): - from pypy.annotation import model as annmodel - from pypy.rpython.lltypesystem import rffi, lltype - assert s_T.is_constant() - assert isinstance(s_init_size, annmodel.SomeInteger) - T = s_T.const - # limit ourselves to structs and to a fact that var-sized element - # does not contain pointers. - assert isinstance(T, lltype.Struct) - assert isinstance(getattr(T, T._arrayfld).OF, lltype.Primitive) - return annmodel.SomePtr(lltype.Ptr(T)) - - def specialize_call(self, hop): - from pypy.rpython.lltypesystem import lltype - flags = {'flavor': 'gc'} - vlist = [hop.inputarg(lltype.Void, 0), - hop.inputconst(lltype.Void, flags), - hop.inputarg(lltype.Signed, 1)] - hop.exception_is_here() - return hop.genop('malloc_resizable_buffer', vlist, - resulttype=hop.r_result.lowleveltype) - -def resize_buffer(ptr, old_size, new_size): - """ Resize raw buffer returned by resizable_buffer_of_shape to new size - """ - from pypy.rpython.lltypesystem import lltype - T = lltype.typeOf(ptr).TO - arrayfld = T._arrayfld - arr = getattr(ptr, arrayfld) - # we don't have any realloc on top of cpython - new_ptr = lltype.malloc(T, new_size) - new_ar = getattr(new_ptr, arrayfld) - for i in range(old_size): - new_ar[i] = arr[i] - return new_ptr - -class ResizeBufferEntry(ExtRegistryEntry): - _about_ = resize_buffer - - def compute_result_annotation(self, s_ptr, s_old_size, s_new_size): - from pypy.annotation import model as annmodel - from pypy.rpython.lltypesystem import rffi - assert isinstance(s_ptr, annmodel.SomePtr) - assert isinstance(s_new_size, annmodel.SomeInteger) - assert isinstance(s_old_size, annmodel.SomeInteger) - return s_ptr - - def specialize_call(self, hop): - from pypy.rpython.lltypesystem import lltype - vlist = [hop.inputarg(hop.args_r[0], 0), - hop.inputarg(lltype.Signed, 1), - hop.inputarg(lltype.Signed, 2)] - hop.exception_is_here() - return hop.genop('resize_buffer', vlist, - resulttype=hop.r_result.lowleveltype) - -def finish_building_buffer(ptr, final_size): - """ Finish building resizable buffer returned by resizable_buffer_of_shape - """ - return ptr - -class FinishBuildingBufferEntry(ExtRegistryEntry): - _about_ = finish_building_buffer - - def compute_result_annotation(self, s_arr, s_final_size): - from pypy.annotation.model import SomePtr, s_ImpossibleValue,\ - SomeInteger - assert isinstance(s_arr, SomePtr) - assert isinstance(s_final_size, SomeInteger) - return s_arr - - def specialize_call(self, hop): - from pypy.rpython.lltypesystem import lltype - vlist = [hop.inputarg(hop.args_r[0], 0), - hop.inputarg(hop.args_r[1], 1)] - hop.exception_cannot_occur() - return hop.genop('finish_building_buffer', vlist, - resulttype=hop.r_result.lowleveltype) - def ll_arraycopy(source, dest, source_start, dest_start, length): from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.lltypesystem import lltype, llmemory @@ -366,6 +277,39 @@ ll_arraycopy._annspecialcase_ = 'specialize:ll' ll_arraycopy._jit_look_inside_ = False +def ll_shrink_array(p, smallerlength): + from pypy.rpython.lltypesystem.lloperation import llop + from pypy.rpython.lltypesystem import lltype, llmemory + from pypy.rlib.objectmodel import keepalive_until_here + + if llop.shrink_array(lltype.Bool, p, smallerlength): + return p # done by the GC + # XXX we assume for now that the type of p is GcStruct containing a + # variable array, with no further pointers anywhere, and exactly one + # field in the fixed part -- like STR and UNICODE. + + TP = lltype.typeOf(p).TO + newp = lltype.malloc(TP, smallerlength) + + assert len(TP._names) == 2 + field = getattr(p, TP._names[0]) + setattr(newp, TP._names[0], field) + + ARRAY = getattr(TP, TP._arrayfld) + offset = (llmemory.offsetof(TP, TP._arrayfld) + + llmemory.itemoffsetof(ARRAY, 0)) + source_addr = llmemory.cast_ptr_to_adr(p) + offset + dest_addr = llmemory.cast_ptr_to_adr(newp) + offset + llmemory.raw_memcopy(source_addr, dest_addr, + llmemory.sizeof(ARRAY.OF) * smallerlength) + + keepalive_until_here(p) + keepalive_until_here(newp) + return newp +ll_shrink_array._annspecialcase_ = 'specialize:ll' +ll_shrink_array._jit_look_inside_ = False + + def no_collect(func): func._dont_inline_ = True func._gc_no_collect_ = True Modified: pypy/trunk/pypy/rlib/test/test_rgc.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rgc.py (original) +++ pypy/trunk/pypy/rlib/test/test_rgc.py Tue Jan 26 17:44:40 2010 @@ -56,19 +56,6 @@ assert res == True -def test_resizable_buffer(): - from pypy.rpython.lltypesystem.rstr import STR - from pypy.rpython.annlowlevel import hlstr - - def f(): - ptr = rgc.resizable_buffer_of_shape(STR, 1) - ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 2) - ptr.chars[1] = 'b' - return hlstr(rgc.finish_building_buffer(ptr, 2)) - - assert f() == 'ab' - def test_ll_arraycopy_1(): TYPE = lltype.GcArray(lltype.Signed) a1 = lltype.malloc(TYPE, 10) @@ -126,3 +113,21 @@ assert a2[i] == a1[i+2] else: assert a2[i] == org2[i] + +def test_ll_shrink_array_1(): + py.test.skip("implement ll_shrink_array for GcStructs or GcArrays that " + "don't have the shape of STR or UNICODE") + +def test_ll_shrink_array_2(): + S = lltype.GcStruct('S', ('x', lltype.Signed), + ('vars', lltype.Array(lltype.Signed))) + s1 = lltype.malloc(S, 5) + s1.x = 1234 + for i in range(5): + s1.vars[i] = 50 + i + s2 = rgc.ll_shrink_array(s1, 3) + assert lltype.typeOf(s2) == lltype.Ptr(S) + assert s2.x == 1234 + assert len(s2.vars) == 3 + for i in range(3): + assert s2.vars[i] == 50 + i Modified: pypy/trunk/pypy/rpython/llinterp.py ============================================================================== --- pypy/trunk/pypy/rpython/llinterp.py (original) +++ pypy/trunk/pypy/rpython/llinterp.py Tue Jan 26 17:44:40 2010 @@ -736,26 +736,17 @@ except MemoryError: self.make_llexception() - def op_malloc_nonmovable(self, obj, flags): + def op_malloc_nonmovable(self, TYPE, flags): flavor = flags['flavor'] assert flavor == 'gc' zero = flags.get('zero', False) - return self.heap.malloc_nonmovable(obj, zero=zero) + return self.heap.malloc_nonmovable(TYPE, zero=zero) - def op_malloc_nonmovable_varsize(self, obj, flags, size): + def op_malloc_nonmovable_varsize(self, TYPE, flags, size): flavor = flags['flavor'] assert flavor == 'gc' zero = flags.get('zero', False) - return self.heap.malloc_nonmovable(obj, size, zero=zero) - - def op_malloc_resizable_buffer(self, obj, flags, size): - return self.heap.malloc_resizable_buffer(obj, size) - - def op_resize_buffer(self, obj, old_size, new_size): - return self.heap.resize_buffer(obj, old_size, new_size) - - def op_finish_building_buffer(self, obj, size): - return self.heap.finish_building_buffer(obj, size) + return self.heap.malloc_nonmovable(TYPE, size, zero=zero) def op_free(self, obj, flavor): assert isinstance(flavor, str) @@ -763,6 +754,9 @@ self.llinterpreter.remember_free(obj) self.heap.free(obj, flavor=flavor) + def op_shrink_array(self, obj, smallersize): + return self.heap.shrink_array(obj, smallersize) + def op_zero_gc_pointers_inside(self, obj): raise NotImplementedError("zero_gc_pointers_inside") @@ -970,14 +964,6 @@ assert lltype.typeOf(size) == lltype.Signed return llmemory.raw_malloc(size) - def op_raw_realloc_grow(self, addr, old_size, size): - assert lltype.typeOf(size) == lltype.Signed - return llmemory.raw_realloc_grow(addr, old_size, size) - - def op_raw_realloc_shrink(self, addr, old_size, size): - assert lltype.typeOf(size) == lltype.Signed - return llmemory.raw_realloc_shrink(addr, old_size, size) - op_boehm_malloc = op_boehm_malloc_atomic = op_raw_malloc def op_boehm_register_finalizer(self, p, finalizer): Modified: pypy/trunk/pypy/rpython/lltypesystem/llarena.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/llarena.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/llarena.py Tue Jan 26 17:44:40 2010 @@ -103,6 +103,21 @@ Arena.object_arena_location[container] = self, offset Arena.old_object_arena_location[container] = self, offset + def shrink_obj(self, offset, newsize): + oldbytes = self.objectsizes[offset] + newbytes = llmemory.raw_malloc_usage(newsize) + assert newbytes <= oldbytes + # fix self.objectsizes + for i in range(newbytes): + adr = offset + i + if adr in self.objectsizes: + assert self.objectsizes[adr] == oldbytes - i + self.objectsizes[adr] = newbytes - i + # fix self.usagemap + for i in range(offset + newbytes, offset + oldbytes): + assert self.usagemap[i] == 'x' + self.usagemap[i] = '#' + class fakearenaaddress(llmemory.fakeaddress): def __init__(self, arena, offset): @@ -306,6 +321,12 @@ % (addr.offset,)) addr.arena.allocate_object(addr.offset, size) +def arena_shrink_obj(addr, newsize): + """ Mark object as shorter than it was + """ + addr = _getfakearenaaddress(addr) + addr.arena.shrink_obj(addr.offset, newsize) + def round_up_for_allocation(size, minsize=0): """Round up the size in order to preserve alignment of objects following an object. For arenas containing heterogenous objects. @@ -460,6 +481,14 @@ llfakeimpl=arena_reserve, sandboxsafe=True) +def llimpl_arena_shrink_obj(addr, newsize): + pass +register_external(arena_shrink_obj, [llmemory.Address, int], None, + 'll_arena.arena_shrink_obj', + llimpl=llimpl_arena_shrink_obj, + llfakeimpl=arena_shrink_obj, + sandboxsafe=True) + llimpl_round_up_for_allocation = rffi.llexternal('ROUND_UP_FOR_ALLOCATION', [lltype.Signed, lltype.Signed], lltype.Signed, Modified: pypy/trunk/pypy/rpython/lltypesystem/llheap.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/llheap.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/llheap.py Tue Jan 26 17:44:40 2010 @@ -20,20 +20,9 @@ malloc_nonmovable = malloc -def malloc_resizable_buffer(TP, size): - return malloc(TP, size) +def shrink_array(p, smallersize): + return False -def resize_buffer(buf, old_size, new_size): - ll_str = malloc(typeOf(buf).TO, new_size) - for i in range(old_size): - ll_str.chars[i] = buf.chars[i] - return ll_str - -def finish_building_buffer(buf, final_size): - ll_str = malloc(typeOf(buf).TO, final_size) - for i in range(final_size): - ll_str.chars[i] = buf.chars[i] - return ll_str def thread_prepare(): pass Modified: pypy/trunk/pypy/rpython/lltypesystem/llmemory.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/llmemory.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/llmemory.py Tue Jan 26 17:44:40 2010 @@ -716,18 +716,6 @@ raise NotImplementedError(size) return size._raw_malloc([], zero=False) -def raw_realloc_grow(addr, old_size, size): - new_area = size._raw_malloc([], zero=False) - raw_memcopy(addr, new_area, old_size) - raw_free(addr) - return new_area - -def raw_realloc_shrink(addr, old_size, size): - new_area = size._raw_malloc([], zero=False) - raw_memcopy(addr, new_area, size) - raw_free(addr) - return new_area - def raw_free(adr): # try to free the whole object if 'adr' is the address of the header from pypy.rpython.memory.gcheader import GCHeaderBuilder Modified: pypy/trunk/pypy/rpython/lltypesystem/lloperation.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/lloperation.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/lloperation.py Tue Jan 26 17:44:40 2010 @@ -354,9 +354,7 @@ 'malloc_varsize': LLOp(canraise=(MemoryError,), canunwindgc=True), 'malloc_nonmovable': LLOp(canraise=(MemoryError,), canunwindgc=True), 'malloc_nonmovable_varsize':LLOp(canraise=(MemoryError,),canunwindgc=True), - 'malloc_resizable_buffer': LLOp(canraise=(MemoryError,),canunwindgc=True), - 'resize_buffer': LLOp(canraise=(MemoryError,), canunwindgc=True), - 'finish_building_buffer' : LLOp(canraise=(MemoryError,), canunwindgc=True), + 'shrink_array': LLOp(canrun=True), 'zero_gc_pointers_inside': LLOp(), 'free': LLOp(), 'getfield': LLOp(sideeffects=False, canrun=True), @@ -391,8 +389,6 @@ 'boehm_register_finalizer': LLOp(), 'boehm_disappearing_link': LLOp(), 'raw_malloc': LLOp(), - 'raw_realloc_grow': LLOp(), - 'raw_realloc_shrink': LLOp(), 'raw_malloc_usage': LLOp(sideeffects=False), 'raw_free': LLOp(), 'raw_memclear': LLOp(), Modified: pypy/trunk/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/lltype.py Tue Jan 26 17:44:40 2010 @@ -1528,6 +1528,9 @@ def getlength(self): return len(self.items) + def shrinklength(self, newlength): + del self.items[newlength:] + def getbounds(self): stop = len(self.items) return 0, stop @@ -1658,7 +1661,9 @@ def setitem(self, index, value): assert index == 0 if value != self.array.getlength(): - raise Exception("can't change the length of an array") + if value > self.array.getlength(): + raise Exception("can't grow an array in-place") + self.array.shrinklength(value) def _makeptr(array, solid=False): try: Modified: pypy/trunk/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/opimpl.py Tue Jan 26 17:44:40 2010 @@ -500,6 +500,9 @@ def op_gc_assume_young_pointers(addr): pass +def op_shrink_array(array, smallersize): + return False + # ____________________________________________________________ def get_op_impl(opname): Modified: pypy/trunk/pypy/rpython/lltypesystem/rbuilder.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rbuilder.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rbuilder.py Tue Jan 26 17:44:40 2010 @@ -1,6 +1,6 @@ from pypy.rpython.rbuilder import AbstractStringBuilderRepr -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, rstr from pypy.rpython.lltypesystem.rstr import STR, UNICODE, char_repr,\ string_repr, unichar_repr, unicode_repr from pypy.rpython.annlowlevel import llstr @@ -9,42 +9,45 @@ from pypy.rpython.lltypesystem.lltype import staticAdtMethod from pypy.tool.sourcetools import func_with_new_name +# Think about heuristics below, maybe we can come up with something +# better or at least compare it with list heuristics + GROW_FAST_UNTIL = 100*1024*1024 # 100 MB -def new_grow_func(name): +def new_grow_func(name, mallocfn, copycontentsfn): def stringbuilder_grow(ll_builder, needed): allocated = ll_builder.allocated - if allocated < GROW_FAST_UNTIL: - new_allocated = allocated << 1 - else: - extra_size = allocated >> 2 - try: - new_allocated = ovfcheck(allocated + extra_size) - except OverflowError: - raise MemoryError + #if allocated < GROW_FAST_UNTIL: + # new_allocated = allocated << 1 + #else: + extra_size = allocated >> 2 try: + new_allocated = ovfcheck(allocated + extra_size) new_allocated = ovfcheck(new_allocated + needed) except OverflowError: raise MemoryError - ll_builder.buf = rgc.resize_buffer(ll_builder.buf, ll_builder.used, - new_allocated) + newbuf = mallocfn(new_allocated) + copycontentsfn(ll_builder.buf, newbuf, 0, 0, ll_builder.allocated) + ll_builder.buf = newbuf ll_builder.allocated = new_allocated return func_with_new_name(stringbuilder_grow, name) -stringbuilder_grow = new_grow_func('stringbuilder_grow') -unicodebuilder_grow = new_grow_func('unicodebuilder_grow') +stringbuilder_grow = new_grow_func('stringbuilder_grow', rstr.mallocstr, + rstr.copy_string_contents) +unicodebuilder_grow = new_grow_func('unicodebuilder_grow', rstr.mallocunicode, + rstr.copy_unicode_contents) STRINGBUILDER = lltype.GcStruct('stringbuilder', - ('allocated', lltype.Signed), - ('used', lltype.Signed), - ('buf', lltype.Ptr(STR)), - adtmeths={'grow':staticAdtMethod(stringbuilder_grow)}) + ('allocated', lltype.Signed), + ('used', lltype.Signed), + ('buf', lltype.Ptr(STR)), + adtmeths={'grow':staticAdtMethod(stringbuilder_grow)}) UNICODEBUILDER = lltype.GcStruct('unicodebuilder', ('allocated', lltype.Signed), ('used', lltype.Signed), ('buf', lltype.Ptr(UNICODE)), - adtmeths={'grow':staticAdtMethod(unicodebuilder_grow)}) + adtmeths={'grow':staticAdtMethod(unicodebuilder_grow)}) MAX = 16*1024*1024 @@ -56,7 +59,7 @@ ll_builder = lltype.malloc(cls.lowleveltype.TO) ll_builder.allocated = init_size ll_builder.used = 0 - ll_builder.buf = rgc.resizable_buffer_of_shape(cls.basetp, init_size) + ll_builder.buf = cls.mallocfn(init_size) return ll_builder @staticmethod @@ -64,7 +67,7 @@ used = ll_builder.used lgt = len(ll_str.chars) needed = lgt + used - if needed >= ll_builder.allocated: + if needed > ll_builder.allocated: ll_builder.grow(ll_builder, lgt) ll_str.copy_contents(ll_str, ll_builder.buf, 0, used, lgt) ll_builder.used = needed @@ -80,7 +83,7 @@ def ll_append_slice(ll_builder, ll_str, start, end): needed = end - start used = ll_builder.used - if needed + used >= ll_builder.allocated: + if needed + used > ll_builder.allocated: ll_builder.grow(ll_builder, needed) assert needed >= 0 ll_str.copy_contents(ll_str, ll_builder.buf, start, used, needed) @@ -89,7 +92,7 @@ @staticmethod def ll_append_multiple_char(ll_builder, char, times): used = ll_builder.used - if times + used >= ll_builder.allocated: + if times + used > ll_builder.allocated: ll_builder.grow(ll_builder, times) for i in range(times): ll_builder.buf.chars[used] = char @@ -99,17 +102,22 @@ @staticmethod def ll_build(ll_builder): final_size = ll_builder.used - return rgc.finish_building_buffer(ll_builder.buf, final_size) + assert final_size >= 0 + if final_size == ll_builder.allocated: + return ll_builder.buf + return rgc.ll_shrink_array(ll_builder.buf, final_size) class StringBuilderRepr(BaseStringBuilderRepr): lowleveltype = lltype.Ptr(STRINGBUILDER) basetp = STR + mallocfn = staticmethod(rstr.mallocstr) string_repr = string_repr char_repr = char_repr class UnicodeBuilderRepr(BaseStringBuilderRepr): lowleveltype = lltype.Ptr(UNICODEBUILDER) basetp = UNICODE + mallocfn = staticmethod(rstr.mallocunicode) string_repr = unicode_repr char_repr = unichar_repr Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_llarena.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/test/test_llarena.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/test/test_llarena.py Tue Jan 26 17:44:40 2010 @@ -5,6 +5,7 @@ from pypy.rpython.lltypesystem.llarena import arena_reserve, arena_free from pypy.rpython.lltypesystem.llarena import round_up_for_allocation from pypy.rpython.lltypesystem.llarena import ArenaError, arena_new_view +from pypy.rpython.lltypesystem.llarena import arena_shrink_obj def test_arena(): S = lltype.Struct('S', ('x',lltype.Signed)) @@ -268,3 +269,16 @@ fn = compile(test_look_inside_object, []) res = fn() assert res == 42 + +def test_shrink_obj(): + from pypy.rpython.memory.gcheader import GCHeaderBuilder + HDR = lltype.Struct('HDR', ('h', lltype.Signed)) + gcheaderbuilder = GCHeaderBuilder(HDR) + size_gc_header = gcheaderbuilder.size_gc_header + S = lltype.GcStruct('S', ('x', lltype.Signed), + ('a', lltype.Array(lltype.Signed))) + myarenasize = 200 + a = arena_malloc(myarenasize, False) + arena_reserve(a, size_gc_header + llmemory.sizeof(S, 10)) + arena_shrink_obj(a, size_gc_header + llmemory.sizeof(S, 5)) + arena_reset(a, size_gc_header + llmemory.sizeof(S, 5), False) Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_llmemory.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/test/test_llmemory.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/test/test_llmemory.py Tue Jan 26 17:44:40 2010 @@ -624,31 +624,3 @@ # the following line crashes if the array is dead ptr1 = cast_adr_to_ptr(adr, lltype.Ptr(lltype.FixedSizeArray(Address, 1))) ptr1[0] = NULL - -def test_realloc(): - A = lltype.Array(lltype.Float) - adr = raw_malloc(sizeof(A, 10)) - ptr = cast_adr_to_ptr(adr, lltype.Ptr(A)) - for i in range(10): - ptr[i] = float(i) - adr2 = raw_realloc_shrink(adr, sizeof(A, 10), sizeof(A, 5)) - ptr2 = cast_adr_to_ptr(adr2, lltype.Ptr(A)) - assert len(ptr2) == 5 - assert ptr2[3] == 3.0 - assert ptr2[1] == 1.0 - -def test_realloc_struct(): - S = lltype.Struct('x', ('one', lltype.Signed), - ('a', lltype.Array(lltype.Float))) - adr = raw_malloc(sizeof(S, 5)) - ptr = cast_adr_to_ptr(adr, lltype.Ptr(S)) - for i in range(5): - ptr.a[i] = float(i) - ptr.one = 3 - adr2 = raw_realloc_grow(adr, sizeof(S, 5), sizeof(S, 10)) - ptr2 = cast_adr_to_ptr(adr2, lltype.Ptr(S)) - assert len(ptr2.a) == 10 - assert ptr2.a[3] == 3.0 - assert ptr2.a[0] == 0.0 - assert ptr2.one == 3 - Modified: pypy/trunk/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gc/base.py (original) +++ pypy/trunk/pypy/rpython/memory/gc/base.py Tue Jan 26 17:44:40 2010 @@ -17,7 +17,6 @@ needs_write_barrier = False malloc_zero_filled = False prebuilt_gc_objects_are_static_roots = True - can_realloc = False object_minimal_size = 0 def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE): Modified: pypy/trunk/pypy/rpython/memory/gc/hybrid.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gc/hybrid.py (original) +++ pypy/trunk/pypy/rpython/memory/gc/hybrid.py Tue Jan 26 17:44:40 2010 @@ -31,7 +31,6 @@ # Object lists: # * gen2_rawmalloced_objects # * gen3_rawmalloced_objects -# * gen2_resizable_objects # * old_objects_pointing_to_young: gen2or3 objs that point to gen1 objs # * last_generation_root_objects: gen3 objs that point to gen1or2 objs # @@ -44,15 +43,11 @@ # Some invariants: # * gen3 are either GCFLAG_NO_HEAP_PTRS or in 'last_generation_root_objects' # * between collections, GCFLAG_UNVISITED set exactly for gen2_rawmalloced -# * objects in gen2_resizable_objects are part of the generation 2 but never -# explicitly listed in gen2_rawmalloced_objects. # # A malloc_varsize() of large objects returns objects that are external # but initially of generation 2. Old objects from the semispaces are # moved to external objects directly as generation 3. -# gen2_resizable_objects is for objects that are resizable - # The "age" of an object is the number of times it survived a full # collections, without counting the step that moved it out of the nursery. # When a semispace-based object would grow older than MAX_SEMISPACE_AGE, @@ -82,7 +77,6 @@ """ first_unused_gcflag = _gcflag_next_bit prebuilt_gc_objects_are_static_roots = True - can_realloc = False # the following values override the default arguments of __init__ when # translating to a real backend. @@ -124,7 +118,6 @@ self.gen2_rawmalloced_objects = self.AddressStack() self.gen3_rawmalloced_objects = self.AddressStack() - self.gen2_resizable_objects = self.AddressStack() GenerationGC.setup(self) def set_max_heap_size(self, size): @@ -176,8 +169,7 @@ llmemory.GCREF) return self.malloc_varsize_slowpath(typeid, length) - def malloc_varsize_slowpath(self, typeid, length, force_nonmovable=False, - resizable=False): + def malloc_varsize_slowpath(self, typeid, length, force_nonmovable=False): # For objects that are too large, or when the nursery is exhausted. # In order to keep malloc_varsize_clear() as compact as possible, # we recompute what we need in this slow path instead of passing @@ -196,7 +188,7 @@ else: nonlarge_max = self.nonlarge_max if force_nonmovable or raw_malloc_usage(totalsize) > nonlarge_max: - result = self.malloc_varsize_marknsweep(totalsize, resizable) + result = self.malloc_varsize_marknsweep(totalsize) flags = self.GCFLAGS_FOR_NEW_EXTERNAL_OBJECTS | GCFLAG_UNVISITED else: result = self.malloc_varsize_collecting_nursery(totalsize) @@ -210,9 +202,6 @@ def malloc_varsize_nonmovable(self, typeid, length): return self.malloc_varsize_slowpath(typeid, length, True) - def malloc_varsize_resizable(self, typeid, length): - return self.malloc_varsize_slowpath(typeid, length, True, True) - def malloc_nonmovable(self, typeid, length, zero): # helper for testing, same as GCBase.malloc if self.is_varsize(typeid): @@ -221,40 +210,6 @@ raise NotImplementedError("Not supported") return llmemory.cast_ptr_to_adr(gcref) - def realloc(self, ptr, newlength, fixedsize, itemsize, lengthofs, grow): - size_gc_header = self.size_gc_header() - addr = llmemory.cast_ptr_to_adr(ptr) - ll_assert(self.header(addr).tid & GCFLAG_EXTERNAL, - "realloc() on a non-external object") - nonvarsize = size_gc_header + fixedsize - try: - varsize = ovfcheck(itemsize * newlength) - tot_size = ovfcheck(nonvarsize + varsize) - except OverflowError: - raise MemoryError() - oldlength = (addr + lengthofs).signed[0] - old_tot_size = size_gc_header + fixedsize + oldlength * itemsize - source_addr = addr - size_gc_header - self.gen2_resizable_objects.remove(addr) - if grow: - result = llop.raw_realloc_grow(llmemory.Address, source_addr, - old_tot_size, tot_size) - else: - result = llop.raw_realloc_shrink(llmemory.Address, source_addr, - old_tot_size, tot_size) - if not result: - self.gen2_resizable_objects.append(addr) - raise MemoryError() - if grow: - self.gen2_resizable_objects.append(result + size_gc_header) - else: - self.gen2_rawmalloced_objects.append(result + size_gc_header) - self._check_rawsize_alloced(raw_malloc_usage(tot_size) - - raw_malloc_usage(old_tot_size), - can_collect = not grow) - (result + size_gc_header + lengthofs).signed[0] = newlength - return llmemory.cast_adr_to_ptr(result + size_gc_header, llmemory.GCREF) - def can_move(self, addr): tid = self.header(addr).tid return not (tid & GCFLAG_EXTERNAL) @@ -278,7 +233,7 @@ self.semispace_collect() debug_stop("gc-rawsize-collect") - def malloc_varsize_marknsweep(self, totalsize, resizable=False): + def malloc_varsize_marknsweep(self, totalsize): # In order to free the large objects from time to time, we # arbitrarily force a full collect() if none occurs when we have # allocated 'self.space_size' bytes of large objects. @@ -294,10 +249,7 @@ # need to follow suit. llmemory.raw_memclear(result, totalsize) size_gc_header = self.gcheaderbuilder.size_gc_header - if resizable: - self.gen2_resizable_objects.append(result + size_gc_header) - else: - self.gen2_rawmalloced_objects.append(result + size_gc_header) + self.gen2_rawmalloced_objects.append(result + size_gc_header) return result def allocate_external_object(self, totalsize): @@ -469,7 +421,6 @@ if self.is_collecting_gen3(): self.sweep_rawmalloced_objects(generation=3) self.sweep_rawmalloced_objects(generation=2) - self.sweep_rawmalloced_objects(generation=-2) # As we just collected, it's fine to raw_malloc'ate up to space_size # bytes again before we should force another collect. self.large_objects_collect_trigger = self.space_size @@ -500,10 +451,8 @@ gen3roots.delete() self.last_generation_root_objects = newgen3roots else: - # mostly a hack: the generation number -2 is the part of the - # generation 2 that lives in gen2_resizable_objects - ll_assert(generation == -2, "bogus 'generation'") - objects = self.gen2_resizable_objects + ll_assert(False, "bogus 'generation'") + return surviving_objects = self.AddressStack() # Help the flow space @@ -538,18 +487,11 @@ tid |= GCFLAG_UNVISITED surviving_objects.append(obj) self.header(obj).tid = tid - elif generation == -2: - # the object stays in generation -2 - tid |= GCFLAG_UNVISITED - surviving_objects.append(obj) - self.header(obj).tid = tid objects.delete() if generation == 2: self.gen2_rawmalloced_objects = surviving_objects elif generation == 3: self.gen3_rawmalloced_objects = surviving_objects - elif generation == -2: - self.gen2_resizable_objects = surviving_objects debug_print("| [hyb] gen", generation, "nonmoving now alive: ", alive_size, "bytes in", Modified: pypy/trunk/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/trunk/pypy/rpython/memory/gc/semispace.py Tue Jan 26 17:44:40 2010 @@ -119,6 +119,21 @@ self.free = result + llarena.round_up_for_allocation(totalsize) return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF) + def shrink_array(self, addr, smallerlength): + size_gc_header = self.gcheaderbuilder.size_gc_header + if self._is_in_the_space(addr - size_gc_header): + typeid = self.get_type_id(addr) + totalsmallersize = ( + size_gc_header + self.fixed_size(typeid) + + self.varsize_item_sizes(typeid) * smallerlength) + llarena.arena_shrink_obj(addr - size_gc_header, totalsmallersize) + # + offset_to_length = self.varsize_offset_to_length(typeid) + (addr + offset_to_length).signed[0] = smallerlength + return True + else: + return False + def obtain_free_space(self, needed): # a bit of tweaking to maximize the performance and minimize the # amount of code in an inlined version of malloc_fixedsize_clear() @@ -572,6 +587,9 @@ def _is_external(self, obj): return (self.header(obj).tid & GCFLAG_EXTERNAL) != 0 + def _is_in_the_space(self, obj): + return self.tospace <= obj < self.free + def debug_check_object(self, obj): """Check the invariants about 'obj' that should be true between collections.""" Modified: pypy/trunk/pypy/rpython/memory/gc/test/test_direct.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gc/test/test_direct.py (original) +++ pypy/trunk/pypy/rpython/memory/gc/test/test_direct.py Tue Jan 26 17:44:40 2010 @@ -268,6 +268,22 @@ class TestSemiSpaceGC(DirectGCTest): from pypy.rpython.memory.gc.semispace import SemiSpaceGC as GCClass + def test_shrink_array(self): + S1 = lltype.GcStruct('S1', ('h', lltype.Char), + ('v', lltype.Array(lltype.Char))) + p1 = self.malloc(S1, 2) + p1.h = '?' + for i in range(2): + p1.v[i] = chr(50 + i) + addr = llmemory.cast_ptr_to_adr(p1) + ok = self.gc.shrink_array(addr, 1) + assert ok + assert p1.h == '?' + assert len(p1.v) == 1 + for i in range(1): + assert p1.v[i] == chr(50 + i) + + class TestGenerationGC(TestSemiSpaceGC): from pypy.rpython.memory.gc.generation import GenerationGC as GCClass @@ -358,7 +374,7 @@ gc.collect(9) assert calls == [('semispace_collect', True)] - calls = [] + calls = [] class TestMarkCompactGC(DirectGCTest): Modified: pypy/trunk/pypy/rpython/memory/gctransform/boehm.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gctransform/boehm.py (original) +++ pypy/trunk/pypy/rpython/memory/gctransform/boehm.py Tue Jan 26 17:44:40 2010 @@ -22,19 +22,12 @@ mh = mallocHelpers() mh.allocate = lambda size: llop.boehm_malloc(llmemory.Address, size) - c_realloc = rffi.llexternal('GC_REALLOC', [rffi.VOIDP, rffi.INT], - rffi.VOIDP, sandboxsafe=True) - def _realloc(ptr, size): - return llmemory.cast_ptr_to_adr(c_realloc(rffi.cast(rffi.VOIDP, ptr), size)) - mh.realloc = _realloc ll_malloc_fixedsize = mh._ll_malloc_fixedsize # XXX, do we need/want an atomic version of this function? ll_malloc_varsize_no_length = mh.ll_malloc_varsize_no_length ll_malloc_varsize = mh.ll_malloc_varsize - ll_realloc = mh.ll_realloc - HDRPTR = lltype.Ptr(self.HDR) def ll_identityhash(addr): @@ -58,9 +51,6 @@ inline=False) self.weakref_deref_ptr = self.inittime_helper( ll_weakref_deref, [llmemory.WeakRefPtr], llmemory.Address) - self.realloc_ptr = self.inittime_helper( - ll_realloc, [llmemory.Address] + [lltype.Signed] * 4, - llmemory.Address) self.identityhash_ptr = self.inittime_helper( ll_identityhash, [llmemory.Address], lltype.Signed, inline=False) @@ -73,15 +63,6 @@ def pop_alive_nopyobj(self, var, llops): pass - def _can_realloc(self): - return True - - def perform_realloc(self, hop, v_ptr, v_newlgt, c_const_size, c_item_size, - c_lengthofs, c_grow): - args = [self.realloc_ptr, v_ptr, v_newlgt, c_const_size, - c_item_size, c_lengthofs] - return hop.genop('direct_call', args, resulttype=llmemory.Address) - def gct_fv_gc_malloc(self, hop, flags, TYPE, c_size): # XXX same behavior for zero=True: in theory that's wrong if TYPE._is_atomic(): Modified: pypy/trunk/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/trunk/pypy/rpython/memory/gctransform/framework.py Tue Jan 26 17:44:40 2010 @@ -276,6 +276,14 @@ [s_gc, annmodel.SomeAddress()], annmodel.SomeBool()) + if hasattr(GCClass, 'shrink_array'): + self.shrink_array_ptr = getfn( + GCClass.shrink_array.im_func, + [s_gc, annmodel.SomeAddress(), + annmodel.SomeInteger(nonneg=True)], annmodel.s_Bool) + else: + self.shrink_array_ptr = None + if hasattr(GCClass, 'assume_young_pointers'): # xxx should really be a noop for gcs without generations self.assume_young_pointers_ptr = getfn( @@ -358,25 +366,6 @@ else: self.malloc_varsize_nonmovable_ptr = None - if getattr(GCClass, 'malloc_varsize_resizable', False): - malloc_resizable = func_with_new_name( - GCClass.malloc_varsize_resizable.im_func, - "malloc_varsize_resizable") - self.malloc_varsize_resizable_ptr = getfn( - malloc_resizable, - [s_gc, s_typeid16, - annmodel.SomeInteger(nonneg=True)], s_gcref) - else: - self.malloc_varsize_resizable_ptr = None - - if getattr(GCClass, 'realloc', False): - self.realloc_ptr = getfn( - GCClass.realloc.im_func, - [s_gc, s_gcref] + - [annmodel.SomeInteger(nonneg=True)] * 4 + - [annmodel.SomeBool()], - s_gcref) - self.identityhash_ptr = getfn(GCClass.identityhash.im_func, [s_gc, s_gcref], annmodel.SomeInteger(), @@ -627,11 +616,7 @@ info_varsize.ofstolength) c_varitemsize = rmodel.inputconst(lltype.Signed, info_varsize.varitemsize) - if flags.get('resizable') and self.malloc_varsize_resizable_ptr: - assert c_can_collect.value - malloc_ptr = self.malloc_varsize_resizable_ptr - args = [self.c_const_gc, c_type_id, v_length] - elif flags.get('nonmovable') and self.malloc_varsize_nonmovable_ptr: + if flags.get('nonmovable') and self.malloc_varsize_nonmovable_ptr: # we don't have tests for such cases, let's fail # explicitely assert c_can_collect.value @@ -673,6 +658,17 @@ hop.genop("direct_call", [self.can_move_ptr, self.c_const_gc, v_addr], resultvar=op.result) + def gct_shrink_array(self, hop): + if self.shrink_array_ptr is None: + return GCTransformer.gct_shrink_array(self, hop) + op = hop.spaceop + v_addr = hop.genop('cast_ptr_to_adr', + [op.args[0]], resulttype=llmemory.Address) + v_length = op.args[1] + hop.genop("direct_call", [self.shrink_array_ptr, self.c_const_gc, + v_addr, v_length], + resultvar=op.result) + def gct_gc_assume_young_pointers(self, hop): op = hop.spaceop v_addr = op.args[0] @@ -716,19 +712,6 @@ resulttype=llmemory.Address) hop.genop('adr_add', [v_gc_adr, c_ofs], resultvar=op.result) - def _can_realloc(self): - return self.gcdata.gc.can_realloc - - def perform_realloc(self, hop, v_ptr, v_newsize, c_const_size, - c_itemsize, c_lengthofs, c_grow): - vlist = [self.realloc_ptr, self.c_const_gc, v_ptr, v_newsize, - c_const_size, c_itemsize, c_lengthofs, c_grow] - livevars = self.push_roots(hop) - v_result = hop.genop('direct_call', vlist, - resulttype=llmemory.GCREF) - self.pop_roots(hop, livevars) - return v_result - def gct_gc_x_swap_pool(self, hop): op = hop.spaceop [v_malloced] = op.args Modified: pypy/trunk/pypy/rpython/memory/gctransform/transform.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gctransform/transform.py (original) +++ pypy/trunk/pypy/rpython/memory/gctransform/transform.py Tue Jan 26 17:44:40 2010 @@ -482,15 +482,6 @@ return result mh.ll_malloc_varsize_no_length_zero = _ll_malloc_varsize_no_length_zero - def ll_realloc(ptr, length, constsize, itemsize, lengthoffset): - size = constsize + length * itemsize - result = mh.realloc(ptr, size) - if not result: - raise MemoryError() - (result + lengthoffset).signed[0] = length - return result - mh.ll_realloc = ll_realloc - return mh class GCTransformer(BaseGCTransformer): @@ -563,81 +554,6 @@ def gct_malloc_nonmovable_varsize(self, *args, **kwds): return self.gct_malloc_varsize(*args, **kwds) - def gct_malloc_resizable_buffer(self, hop): - flags = hop.spaceop.args[1].value - flags['varsize'] = True - flags['nonmovable'] = True - flags['resizable'] = True - flavor = flags['flavor'] - assert flavor != 'cpy', "cannot malloc CPython objects directly" - meth = getattr(self, 'gct_fv_%s_malloc_varsize' % flavor, None) - assert meth, "%s has no support for malloc_varsize with flavor %r" % (self, flavor) - return self.varsize_malloc_helper(hop, flags, meth, []) - - def gct_resize_buffer(self, hop): - op = hop.spaceop - if self._can_realloc(): - self._gct_resize_buffer_realloc(hop, op.args[2], True) - else: - self._gct_resize_buffer_no_realloc(hop, op.args[1]) - - def _can_realloc(self): - return False - - def _gct_resize_buffer_realloc(self, hop, v_newsize, grow=True): - def intconst(c): return rmodel.inputconst(lltype.Signed, c) - op = hop.spaceop - flags = {'flavor':'gc', 'varsize': True} - TYPE = op.args[0].concretetype.TO - ARRAY = TYPE._flds[TYPE._arrayfld] - offset_to_length = llmemory.FieldOffset(TYPE, TYPE._arrayfld) + \ - llmemory.ArrayLengthOffset(ARRAY) - c_const_size = intconst(llmemory.sizeof(TYPE, 0)) - c_item_size = intconst(llmemory.sizeof(ARRAY.OF)) - - c_lengthofs = intconst(offset_to_length) - v_ptr = op.args[0] - v_ptr = gen_cast(hop.llops, llmemory.GCREF, v_ptr) - c_grow = rmodel.inputconst(lltype.Bool, grow) - v_raw = self.perform_realloc(hop, v_ptr, v_newsize, c_const_size, - c_item_size, c_lengthofs, c_grow) - hop.cast_result(v_raw) - - def _gct_resize_buffer_no_realloc(self, hop, v_lgt): - op = hop.spaceop - meth = self.gct_fv_gc_malloc_varsize - flags = {'flavor':'gc', 'varsize': True, 'keep_current_args': True} - self.varsize_malloc_helper(hop, flags, meth, []) - # fish resvar - v_newbuf = hop.llops[-1].result - v_src = op.args[0] - TYPE = v_src.concretetype.TO - c_fldname = rmodel.inputconst(lltype.Void, TYPE._arrayfld) - v_adrsrc = hop.genop('cast_ptr_to_adr', [v_src], - resulttype=llmemory.Address) - v_adrnewbuf = hop.genop('cast_ptr_to_adr', [v_newbuf], - resulttype=llmemory.Address) - ofs = (llmemory.offsetof(TYPE, TYPE._arrayfld) + - llmemory.itemoffsetof(getattr(TYPE, TYPE._arrayfld), 0)) - v_ofs = rmodel.inputconst(lltype.Signed, ofs) - v_adrsrc = hop.genop('adr_add', [v_adrsrc, v_ofs], - resulttype=llmemory.Address) - v_adrnewbuf = hop.genop('adr_add', [v_adrnewbuf, v_ofs], - resulttype=llmemory.Address) - size = llmemory.sizeof(getattr(TYPE, TYPE._arrayfld).OF) - c_size = rmodel.inputconst(lltype.Signed, size) - v_lgtsym = hop.genop('int_mul', [c_size, v_lgt], - resulttype=lltype.Signed) - vlist = [v_adrsrc, v_adrnewbuf, v_lgtsym] - hop.genop('raw_memcopy', vlist) - - def gct_finish_building_buffer(self, hop): - op = hop.spaceop - if self._can_realloc(): - return self._gct_resize_buffer_realloc(hop, op.args[1], False) - else: - return self._gct_resize_buffer_no_realloc(hop, op.args[1]) - def varsize_malloc_helper(self, hop, flags, meth, extraargs): def intconst(c): return rmodel.inputconst(lltype.Signed, c) op = hop.spaceop @@ -698,3 +614,6 @@ def gct_gc_can_move(self, hop): return hop.cast_result(rmodel.inputconst(lltype.Bool, False)) + + def gct_shrink_array(self, hop): + return hop.cast_result(rmodel.inputconst(lltype.Bool, False)) Modified: pypy/trunk/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/trunk/pypy/rpython/memory/gcwrapper.py Tue Jan 26 17:44:40 2010 @@ -4,7 +4,6 @@ from pypy.rpython.memory import gctypelayout from pypy.objspace.flow.model import Constant - class GCManagedHeap(object): def __init__(self, llinterp, flowgraphs, gc_class, GC_PARAMS={}): @@ -59,27 +58,11 @@ gctypelayout.zero_gc_pointers(result) return result - def malloc_resizable_buffer(self, TYPE, n): - typeid = self.get_type_id(TYPE) - addr = self.gc.malloc(typeid, n) - result = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(TYPE)) - if not self.gc.malloc_zero_filled: - gctypelayout.zero_gc_pointers(result) - return result - - def resize_buffer(self, obj, old_size, new_size): - T = lltype.typeOf(obj).TO - buf = self.malloc_resizable_buffer(T, new_size) - # copy contents - arrayfld = T._arrayfld - new_arr = getattr(buf, arrayfld) - old_arr = getattr(obj, arrayfld) - for i in range(old_size): - new_arr[i] = old_arr[i] - return buf - - def finish_building_buffer(self, obj, size): - return obj + def shrink_array(self, p, smallersize): + if hasattr(self.gc, 'shrink_array'): + addr = llmemory.cast_ptr_to_adr(p) + return self.gc.shrink_array(addr, smallersize) + return False def free(self, TYPE, flavor='gc'): assert flavor != 'gc' Modified: pypy/trunk/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/trunk/pypy/rpython/memory/test/test_gc.py Tue Jan 26 17:44:40 2010 @@ -11,7 +11,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.objectmodel import compute_unique_id, keepalive_until_here from pypy.rlib import rgc - +from pypy.rlib.rstring import StringBuilder def stdout_ignore_ll_functions(msg): strmsg = str(msg) @@ -24,6 +24,7 @@ GC_PARAMS = {} GC_CAN_MOVE = False GC_CANNOT_MALLOC_NONMOVABLE = False + GC_CAN_SHRINK_ARRAY = False def setup_class(cls): cls._saved_logstate = py.log._getstate() @@ -468,18 +469,30 @@ assert self.interpret(func, []) == int(self.GC_CANNOT_MALLOC_NONMOVABLE) - def test_resizable_buffer(self): + def test_shrink_array(self): from pypy.rpython.lltypesystem.rstr import STR - from pypy.rpython.annlowlevel import hlstr - - def f(): - ptr = rgc.resizable_buffer_of_shape(STR, 1) - ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 2) - ptr.chars[1] = 'b' - return len(hlstr(rgc.finish_building_buffer(ptr, 2))) + GC_CAN_SHRINK_ARRAY = self.GC_CAN_SHRINK_ARRAY - assert self.interpret(f, []) == 2 + def f(n, m): + ptr = lltype.malloc(STR, n) + ptr.hash = 0x62 + ptr.chars[0] = 'A' + ptr.chars[1] = 'B' + ptr.chars[2] = 'C' + ptr2 = rgc.ll_shrink_array(ptr, 2) + assert (ptr == ptr2) == GC_CAN_SHRINK_ARRAY + rgc.collect() + return ( ord(ptr2.chars[0]) + + (ord(ptr2.chars[1]) << 8) + + (len(ptr2.chars) << 16) + + (ptr2.hash << 24)) + + assert self.interpret(f, [3, 0]) == 0x62024241 + # don't test with larger numbers of top of the Hybrid GC, because + # the default settings make it a too-large varsized object that + # gets allocated outside the semispace + if not isinstance(self, TestHybridGC): + assert self.interpret(f, [12, 0]) == 0x62024241 def test_tagged_simple(self): from pypy.rlib.objectmodel import UnboxedValue @@ -571,6 +584,20 @@ self.interpret(fn, []) + def test_stringbuilder(self): + def fn(): + s = StringBuilder(4) + s.append("abcd") + s.append("defg") + s.append("rty") + s.append_multiple_char('y', 1000) + rgc.collect() + s.append_multiple_char('y', 1000) + res = s.build()[1000] + rgc.collect() + return ord(res) + res = self.interpret(fn, []) + assert res == ord('y') from pypy.rlib.objectmodel import UnboxedValue @@ -599,6 +626,7 @@ from pypy.rpython.memory.gc.semispace import SemiSpaceGC as GCClass GC_CAN_MOVE = True GC_CANNOT_MALLOC_NONMOVABLE = True + GC_CAN_SHRINK_ARRAY = True class TestGrowingSemiSpaceGC(TestSemiSpaceGC): GC_PARAMS = {'space_size': 64} Modified: pypy/trunk/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/trunk/pypy/rpython/memory/test/test_transformed_gc.py Tue Jan 26 17:44:40 2010 @@ -162,6 +162,7 @@ return run class GenericGCTests(GCTest): + GC_CAN_SHRINK_ARRAY = False def heap_usage(self, statistics): try: @@ -631,22 +632,30 @@ run = self.runner("malloc_nonmovable_fixsize") assert run([]) == int(self.GC_CANNOT_MALLOC_NONMOVABLE) - def define_resizable_buffer(cls): + def define_shrink_array(cls): from pypy.rpython.lltypesystem.rstr import STR - from pypy.rpython.annlowlevel import hlstr def f(): - ptr = rgc.resizable_buffer_of_shape(STR, 2) - ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 200) - ptr.chars[1] = 'b' - return hlstr(rgc.finish_building_buffer(ptr, 2)) == "ab" - + ptr = lltype.malloc(STR, 3) + ptr.hash = 0x62 + ptr.chars[0] = '0' + ptr.chars[1] = 'B' + ptr.chars[2] = 'C' + ptr2 = rgc.ll_shrink_array(ptr, 2) + return ((ptr == ptr2) + + ord(ptr2.chars[0]) + + (ord(ptr2.chars[1]) << 8) + + (len(ptr2.chars) << 16) + + (ptr2.hash << 24)) return f - def test_resizable_buffer(self): - run = self.runner("resizable_buffer") - assert run([]) == 1 + def test_shrink_array(self): + run = self.runner("shrink_array") + if self.GC_CAN_SHRINK_ARRAY: + expected = 0x62024231 + else: + expected = 0x62024230 + assert run([]) == expected def define_string_builder_over_allocation(cls): import gc @@ -1117,6 +1126,7 @@ class TestSemiSpaceGC(GenericMovingGCTests): gcname = "semispace" + GC_CAN_SHRINK_ARRAY = True class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): @@ -1138,6 +1148,7 @@ class TestGenerationGC(GenericMovingGCTests): gcname = "generation" + GC_CAN_SHRINK_ARRAY = True class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): Modified: pypy/trunk/pypy/rpython/test/test_rbuilder.py ============================================================================== --- pypy/trunk/pypy/rpython/test/test_rbuilder.py (original) +++ pypy/trunk/pypy/rpython/test/test_rbuilder.py Tue Jan 26 17:44:40 2010 @@ -1,7 +1,25 @@ from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin +from pypy.rpython.lltypesystem.rbuilder import * +from pypy.rpython.annlowlevel import llstr, hlstr from pypy.rlib.rstring import StringBuilder, UnicodeBuilder + +class TestStringBuilderDirect(object): + def test_simple(self): + sb = StringBuilderRepr.ll_new(3) + StringBuilderRepr.ll_append_char(sb, 'x') + StringBuilderRepr.ll_append(sb, llstr("abc")) + StringBuilderRepr.ll_append_slice(sb, llstr("foobar"), 2, 5) + StringBuilderRepr.ll_append_multiple_char(sb, 'y', 3) + s = StringBuilderRepr.ll_build(sb) + assert hlstr(s) == "xabcobayyy" + + def test_nooveralloc(self): + sb = StringBuilderRepr.ll_new(3) + StringBuilderRepr.ll_append(sb, llstr("abc")) + assert StringBuilderRepr.ll_build(sb) == sb.buf + class BaseTestStringBuilder(BaseRtypingTest): def test_simple(self): def func(): @@ -37,7 +55,6 @@ assert res == 'aabcabcdefbuuuu' assert isinstance(res, unicode) - class TestLLtype(BaseTestStringBuilder, LLRtypeMixin): pass Modified: pypy/trunk/pypy/translator/c/src/mem.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/mem.h (original) +++ pypy/trunk/pypy/translator/c/src/mem.h Tue Jan 26 17:44:40 2010 @@ -101,10 +101,6 @@ #define OP_RAW_MALLOC_USAGE(size, r) r = size -#define OP_RAW_REALLOC_SHRINK(p, old_size, size, r) r = PyObject_Realloc((void*)p, size) - -#define OP_RAW_REALLOC_GROW(p, old_size, size, r) r = PyObject_Realloc((void*)p, size) - #ifdef MS_WINDOWS #define alloca _alloca #endif Modified: pypy/trunk/pypy/translator/c/test/test_boehm.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_boehm.py (original) +++ pypy/trunk/pypy/translator/c/test/test_boehm.py Tue Jan 26 17:44:40 2010 @@ -411,20 +411,25 @@ run = self.getcompiled(func) assert run() == 0 - def test_resizable_buffer(self): + def test_shrink_array(self): from pypy.rpython.lltypesystem.rstr import STR - from pypy.rpython.annlowlevel import hlstr from pypy.rlib import rgc def f(): - ptr = rgc.resizable_buffer_of_shape(STR, 2) - ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 200) - ptr.chars[1] = 'b' - return hlstr(rgc.finish_building_buffer(ptr, 2)) == "ab" + ptr = lltype.malloc(STR, 3) + ptr.hash = 0x62 + ptr.chars[0] = '0' + ptr.chars[1] = 'B' + ptr.chars[2] = 'C' + ptr2 = rgc.ll_shrink_array(ptr, 2) + return ((ptr == ptr2) + + ord(ptr2.chars[0]) + + (ord(ptr2.chars[1]) << 8) + + (len(ptr2.chars) << 16) + + (ptr2.hash << 24)) run = self.getcompiled(f) - assert run() == True + assert run() == 0x62024230 def test_assume_young_pointers_nop(self): S = lltype.GcStruct('S', ('x', lltype.Signed)) Modified: pypy/trunk/pypy/translator/c/test/test_newgc.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_newgc.py (original) +++ pypy/trunk/pypy/translator/c/test/test_newgc.py Tue Jan 26 17:44:40 2010 @@ -20,6 +20,7 @@ taggedpointers = False GC_CAN_MOVE = False GC_CANNOT_MALLOC_NONMOVABLE = False + GC_CAN_SHRINK_ARRAY = False _isolated_func = None @@ -697,19 +698,28 @@ def define_resizable_buffer(cls): from pypy.rpython.lltypesystem.rstr import STR - from pypy.rpython.annlowlevel import hlstr def f(): - ptr = rgc.resizable_buffer_of_shape(STR, 2) - ptr.chars[0] = 'a' - ptr = rgc.resize_buffer(ptr, 1, 200) - ptr.chars[1] = 'b' - return hlstr(rgc.finish_building_buffer(ptr, 2)) == "ab" - + ptr = lltype.malloc(STR, 3) + ptr.hash = 0x62 + ptr.chars[0] = '0' + ptr.chars[1] = 'B' + ptr.chars[2] = 'C' + ptr2 = rgc.ll_shrink_array(ptr, 2) + return ((ptr == ptr2) + + ord(ptr2.chars[0]) + + (ord(ptr2.chars[1]) << 8) + + (len(ptr2.chars) << 16) + + (ptr2.hash << 24)) return f def test_resizable_buffer(self): - assert self.run('resizable_buffer') + res = self.run('resizable_buffer') + if self.GC_CAN_SHRINK_ARRAY: + expected = 0x62024231 + else: + expected = 0x62024230 + assert res == expected def define_hash_preservation(cls): from pypy.rlib.objectmodel import compute_hash @@ -882,6 +892,7 @@ should_be_moving = True GC_CAN_MOVE = True GC_CANNOT_MALLOC_NONMOVABLE = True + GC_CAN_SHRINK_ARRAY = True # for snippets large_tests_ok = True @@ -1029,6 +1040,7 @@ class TestMarkCompactGC(TestSemiSpaceGC): gcpolicy = "markcompact" should_be_moving = True + GC_CAN_SHRINK_ARRAY = False def setup_class(cls): py.test.skip("Disabled for now") From arigo at codespeak.net Tue Jan 26 18:29:41 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 18:29:41 +0100 (CET) Subject: [pypy-svn] r70896 - pypy/trunk/pypy/interpreter Message-ID: <20100126172941.24CD216807B@codespeak.net> Author: arigo Date: Tue Jan 26 18:29:40 2010 New Revision: 70896 Modified: pypy/trunk/pypy/interpreter/pyframe.py Log: I think that these promote are pointless by now. Modified: pypy/trunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/pypy/interpreter/pyframe.py Tue Jan 26 18:29:40 2010 @@ -167,14 +167,14 @@ def pushvalue(self, w_object): depth = self.valuestackdepth self.valuestack_w[depth] = w_object - self.valuestackdepth = hint(depth + 1, promote=True) + self.valuestackdepth = depth + 1 def popvalue(self): depth = self.valuestackdepth - 1 assert depth >= 0, "pop from empty value stack" w_object = self.valuestack_w[depth] self.valuestack_w[depth] = None - self.valuestackdepth = hint(depth, promote=True) + self.valuestackdepth = depth return w_object From arigo at codespeak.net Tue Jan 26 18:41:22 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 26 Jan 2010 18:41:22 +0100 (CET) Subject: [pypy-svn] r70897 - pypy/trunk/pypy/translator Message-ID: <20100126174122.F23A916807B@codespeak.net> Author: arigo Date: Tue Jan 26 18:41:22 2010 New Revision: 70897 Modified: pypy/trunk/pypy/translator/geninterplevel.py Log: Bump the version number, which should have been done when merging the lazy-operr-format branch. Modified: pypy/trunk/pypy/translator/geninterplevel.py ============================================================================== --- pypy/trunk/pypy/translator/geninterplevel.py (original) +++ pypy/trunk/pypy/translator/geninterplevel.py Tue Jan 26 18:41:22 2010 @@ -71,7 +71,7 @@ log = py.log.Producer("geninterp") py.log.setconsumer("geninterp", ansi_log) -GI_VERSION = '1.2.6' # bump this for substantial changes +GI_VERSION = '1.2.7' # bump this for substantial changes # ____________________________________________________________ try: From cfbolz at codespeak.net Tue Jan 26 18:45:49 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 26 Jan 2010 18:45:49 +0100 (CET) Subject: [pypy-svn] r70898 - in pypy/trunk/pypy: interpreter module/__builtin__/test objspace/std Message-ID: <20100126174549.3749D49843E@codespeak.net> Author: cfbolz Date: Tue Jan 26 18:45:48 2010 New Revision: 70898 Modified: pypy/trunk/pypy/interpreter/pyframe.py pypy/trunk/pypy/module/__builtin__/test/test_classobj.py pypy/trunk/pypy/objspace/std/dictmultiobject.py pypy/trunk/pypy/objspace/std/objspace.py Log: Improve slightly on old-style classes (and on the execution time of all class bodies): make the __dict__ of an old-style class a str-dict. Modified: pypy/trunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/pypy/interpreter/pyframe.py Tue Jan 26 18:45:48 2010 @@ -110,7 +110,7 @@ if flags & pycode.CO_OPTIMIZED: return if flags & pycode.CO_NEWLOCALS: - self.w_locals = self.space.newdict() + self.w_locals = self.space.newdict(strdict=True) else: assert self.w_globals is not None self.w_locals = self.w_globals Modified: pypy/trunk/pypy/module/__builtin__/test/test_classobj.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/test/test_classobj.py (original) +++ pypy/trunk/pypy/module/__builtin__/test/test_classobj.py Tue Jan 26 18:45:48 2010 @@ -773,9 +773,9 @@ if option.runappdirect: py.test.skip("can only be run on py.py") def is_sharing(space, w_inst): - from pypy.objspace.std.sharingdict import SharedDictImplementation, W_DictMultiObject + from pypy.objspace.std.sharingdict import SharedDictImplementation w_d = w_inst.getdict() - return space.wrap(isinstance(w_d, SharedDictImplementation)) + return space.wrap(isinstance(w_d, SharedDictImplementation) and w_d.r_dict_content is None) cls.w_is_sharing = cls.space.wrap(gateway.interp2app(is_sharing)) @@ -786,3 +786,22 @@ A1, A2, A3 = A(), A(), A() assert self.is_sharing(A3) assert self.is_sharing(A2) + assert self.is_sharing(A1) + +class AppTestOldStyleStrDict(object): + def setup_class(cls): + cls.space = gettestobjspace() + if option.runappdirect: + py.test.skip("can only be run on py.py") + def is_strdict(space, w_class): + from pypy.objspace.std.dictmultiobject import StrDictImplementation + w_d = w_class.getdict() + return space.wrap(isinstance(w_d, StrDictImplementation) and w_d.r_dict_content is None) + + cls.w_is_strdict = cls.space.wrap(gateway.interp2app(is_strdict)) + + def test_strdict(self): + class A: + a = 1 + b = 2 + assert self.is_strdict(A) Modified: pypy/trunk/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/trunk/pypy/objspace/std/dictmultiobject.py Tue Jan 26 18:45:48 2010 @@ -32,7 +32,7 @@ @staticmethod def allocate_and_init_instance(space, w_type=None, module=False, instance=False, classofinstance=None, - from_strdict_shared=None): + from_strdict_shared=None, strdict=False): if from_strdict_shared is not None: assert w_type is None assert not module and not instance and classofinstance is None @@ -57,7 +57,7 @@ classofinstance is not None): assert w_type is None return ShadowDetectingDictImplementation(space, classofinstance) - elif instance: + elif instance or strdict: assert w_type is None return StrDictImplementation(space) else: Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Tue Jan 26 18:45:48 2010 @@ -506,12 +506,13 @@ return W_ListObject(list_w) def newdict(self, module=False, instance=False, classofinstance=None, - from_strdict_shared=None): + from_strdict_shared=None, strdict=False): from pypy.objspace.std.dictmultiobject import W_DictMultiObject return W_DictMultiObject.allocate_and_init_instance( self, module=module, instance=instance, classofinstance=classofinstance, - from_strdict_shared=from_strdict_shared) + from_strdict_shared=from_strdict_shared, + strdict=strdict) def newslice(self, w_start, w_end, w_step): return W_SliceObject(w_start, w_end, w_step) From cfbolz at codespeak.net Tue Jan 26 19:00:26 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 26 Jan 2010 19:00:26 +0100 (CET) Subject: [pypy-svn] r70899 - pypy/trunk/pypy/module/__builtin__ Message-ID: <20100126180026.B4C5949843E@codespeak.net> Author: cfbolz Date: Tue Jan 26 19:00:25 2010 New Revision: 70899 Modified: pypy/trunk/pypy/module/__builtin__/interp_classobj.py Log: Be a bit on the paranoid side and make sure that the bases_w list of an old-style class is not resizable. Modified: pypy/trunk/pypy/module/__builtin__/interp_classobj.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/interp_classobj.py (original) +++ pypy/trunk/pypy/module/__builtin__/interp_classobj.py Tue Jan 26 19:00:25 2010 @@ -7,6 +7,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.rlib.rarithmetic import r_uint, intmask from pypy.rlib.objectmodel import compute_identity_hash +from pypy.rlib.debug import make_sure_not_resized def raise_type_err(space, argument, expected, w_obj): @@ -51,6 +52,7 @@ class W_ClassObject(Wrappable): def __init__(self, space, w_name, bases, w_dict): self.name = space.str_w(w_name) + make_sure_not_resized(bases) self.bases_w = bases self.w_dict = w_dict From fijal at codespeak.net Tue Jan 26 19:44:36 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 26 Jan 2010 19:44:36 +0100 (CET) Subject: [pypy-svn] r70900 - in pypy/trunk/pypy/module/gc: . test Message-ID: <20100126184436.EEC3A168079@codespeak.net> Author: fijal Date: Tue Jan 26 19:44:36 2010 New Revision: 70900 Modified: pypy/trunk/pypy/module/gc/__init__.py pypy/trunk/pypy/module/gc/test/test_gc.py Log: disable this feature. Due to a combination of imports, it break late importing of gc module (imports it during annotation) Modified: pypy/trunk/pypy/module/gc/__init__.py ============================================================================== --- pypy/trunk/pypy/module/gc/__init__.py (original) +++ pypy/trunk/pypy/module/gc/__init__.py Tue Jan 26 19:44:36 2010 @@ -12,7 +12,7 @@ 'disable_finalizers': 'interp_gc.disable_finalizers', 'estimate_heap_size': 'interp_gc.estimate_heap_size', 'garbage' : 'space.newlist([])', - 'dump_heap_stats': 'interp_gc.dump_heap_stats', + #'dump_heap_stats': 'interp_gc.dump_heap_stats', } def __init__(self, space, w_name): Modified: pypy/trunk/pypy/module/gc/test/test_gc.py ============================================================================== --- pypy/trunk/pypy/module/gc/test/test_gc.py (original) +++ pypy/trunk/pypy/module/gc/test/test_gc.py Tue Jan 26 19:44:36 2010 @@ -77,6 +77,8 @@ class AppTestGcDumpHeap(object): def setup_class(cls): + import py + py.test.skip("Disabled") from pypy.tool.udir import udir from pypy.rlib import rgc class X(object): From fijal at codespeak.net Tue Jan 26 23:03:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 26 Jan 2010 23:03:56 +0100 (CET) Subject: [pypy-svn] r70901 - pypy/extradoc/planning Message-ID: <20100126220356.B4B1616804F@codespeak.net> Author: fijal Date: Tue Jan 26 23:03:54 2010 New Revision: 70901 Added: pypy/extradoc/planning/gcplan.txt (contents, props changed) Log: Add a plan Added: pypy/extradoc/planning/gcplan.txt ============================================================================== --- (empty file) +++ pypy/extradoc/planning/gcplan.txt Tue Jan 26 23:03:54 2010 @@ -0,0 +1,54 @@ + +The problem: +============ + +given such algorithm: + +l = [] +for i in range(N): + l.append(i) + +the resulting time spent in the GC would be O(N^2). +The reason for this is the following: + +During each C iterations, depending on size of nursery (hence +C is a constant), we're going to collect the nursery. This requires +O(C) copying (so far so good), but we're also going to look inside +l (which is old from some point on, hence it's an old obj pointing to +new objects) and iteratate over all it's elements. That requires O(N) +operations, so in total we got O(N^2) operations. + +Solution: +========= + +We use a card marking algorithm. This requires certain changes to +how our gcs work and how they're tested. For now I'll concentrate +on generation gc, completely ignoring hybrid (which has it's own +quadratic problem marked by an XXX anyway). Let's suppose we have +a semispace allocated in a contigous way such as: + +------------------------------------------------------------ +[obj 0][obj 1][array 0xxxxxxxxxxx][obj 2][array 1xxxxxxxxxx] +------------------------------------------------------------ + +Now we make cards, each of certain size, say PAGE. + +------------------------------------------------------------ +[obj 0][obj 1][array 0xxxxxxxxxxx][obj 2][array 1xxxxxxxxxx] +------------------------------------------------------------ +^ ^ ^ ^ + +At some place, we store a bitmap corresponding to cards, one bit per +card. For a write barrier we simply mark a corresponding bit +(can be done based on pointer arithmetics). We also store, in a list +somewhere, an object which is the first one on a card (or overlaps from +the left). For the example above, list would contain: [obj 0][array 0] +[array 0][array 1]. + +When we collect the nursery, we look in the bitmap for marked pages. +For each marked page, we start looking at the first object. We can do +simple arithmetics in case of objects on borders. After the end, we cleanup +the whole bitmap. Lists are updated when copied to new semispace. + +This of course assume lack of hybrid GC. + From arigo at codespeak.net Wed Jan 27 10:10:13 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 27 Jan 2010 10:10:13 +0100 (CET) Subject: [pypy-svn] r70903 - pypy/trunk/pypy/translator/c/test Message-ID: <20100127091013.D5F131680B8@codespeak.net> Author: arigo Date: Wed Jan 27 10:10:12 2010 New Revision: 70903 Modified: pypy/trunk/pypy/translator/c/test/test_lladdresses.py Log: Skip a test on Mac OS/X. It causes a later crash, and I think that Boehm is in cause. Modified: pypy/trunk/pypy/translator/c/test/test_lladdresses.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_lladdresses.py (original) +++ pypy/trunk/pypy/translator/c/test/test_lladdresses.py Wed Jan 27 10:10:12 2010 @@ -1,4 +1,4 @@ -import py +import py, sys from pypy.rpython.lltypesystem.llmemory import * from pypy.annotation.model import SomeAddress, SomeChar from pypy.translator.c.test.test_genc import compile @@ -154,6 +154,8 @@ assert fn(1) == 2 def test_gcref(): + if sys.platform == 'darwin': + py.test.skip("'boehm' may crash") S = lltype.GcStruct("S", ("x", lltype.Signed)) s = lltype.malloc(S) s.x = 123 From arigo at codespeak.net Wed Jan 27 11:02:36 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 27 Jan 2010 11:02:36 +0100 (CET) Subject: [pypy-svn] r70905 - pypy/trunk/pypy/jit/metainterp/test Message-ID: <20100127100236.6809616807B@codespeak.net> Author: arigo Date: Wed Jan 27 11:02:36 2010 New Revision: 70905 Modified: pypy/trunk/pypy/jit/metainterp/test/test_resume.py Log: Fix for dictionary order. Modified: pypy/trunk/pypy/jit/metainterp/test/test_resume.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_resume.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_resume.py Wed Jan 27 11:02:36 2010 @@ -993,7 +993,7 @@ values = {b4s: v4, b2s: v2} liveboxes = [] modifier._number_virtuals(liveboxes, values, 0) - assert liveboxes == [b2s, b4s] + assert liveboxes == [b2s, b4s] or liveboxes == [b4s, b2s] modifier._add_pending_fields([(LLtypeMixin.nextdescr, b2s, b4s)]) storage.rd_consts = memo.consts[:] storage.rd_numb = None @@ -1012,6 +1012,7 @@ for x, y in zip(expected, trace): assert x == y + assert len(expected) == len(trace) assert demo55.next == demo66 From arigo at codespeak.net Wed Jan 27 11:43:08 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 27 Jan 2010 11:43:08 +0100 (CET) Subject: [pypy-svn] r70906 - pypy/branch/gc-huge-list Message-ID: <20100127104308.1EB04168025@codespeak.net> Author: arigo Date: Wed Jan 27 11:43:07 2010 New Revision: 70906 Added: pypy/branch/gc-huge-list/ - copied from r70905, pypy/trunk/ Log: (fijal, arigo, cfbolz looking) A branch in which to implement card marking to avoid O(n^2) complexity when creating large lists of small objects. From cfbolz at codespeak.net Wed Jan 27 11:43:53 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 27 Jan 2010 11:43:53 +0100 (CET) Subject: [pypy-svn] r70907 - in pypy/trunk/pypy/jit/metainterp: . test Message-ID: <20100127104353.324B3168025@codespeak.net> Author: cfbolz Date: Wed Jan 27 11:43:52 2010 New Revision: 70907 Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Log: Also remove duplicate pure ops that have a descr, e.g. arraylen_gc. Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Wed Jan 27 11:43:52 2010 @@ -573,21 +573,20 @@ self.make_constant(op.result, resbox.constbox()) return - if op.descr is None: - # did we do the exact same operation already? - args = op.args[:] - for i in range(len(args)): - arg = args[i] - if arg in self.values: - args[i] = self.values[arg].get_key_box() - args.append(ConstInt(op.opnum)) - oldop = self.pure_operations.get(args, None) - if oldop is not None: - assert oldop.opnum == op.opnum - self.make_equal_to(op.result, self.getvalue(oldop.result)) - return - else: - self.pure_operations[args] = op + # did we do the exact same operation already? + args = op.args[:] + for i in range(len(args)): + arg = args[i] + if arg in self.values: + args[i] = self.values[arg].get_key_box() + args.append(ConstInt(op.opnum)) + oldop = self.pure_operations.get(args, None) + if oldop is not None and oldop.descr is op.descr: + assert oldop.opnum == op.opnum + self.make_equal_to(op.result, self.getvalue(oldop.result)) + return + else: + self.pure_operations[args] = op # otherwise, the operation remains self.emit_operation(op) Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Wed Jan 27 11:43:52 2010 @@ -1891,6 +1891,26 @@ """ self.optimize_loop(ops, "Not, Not", expected) + def test_remove_duplicate_pure_op_with_descr(self): + ops = """ + [p1] + i0 = arraylen_gc(p1, descr=arraydescr) + i1 = int_gt(i0, 0) + guard_true(i1) [] + i2 = arraylen_gc(p1, descr=arraydescr) + i3 = int_gt(i0, 0) + guard_true(i3) [] + jump(p1) + """ + expected = """ + [p1] + i0 = arraylen_gc(p1, descr=arraydescr) + i1 = int_gt(i0, 0) + guard_true(i1) [] + jump(p1) + """ + self.optimize_loop(ops, 'Not', expected) + # ---------- def make_fail_descr(self): From cfbolz at codespeak.net Wed Jan 27 12:01:10 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 27 Jan 2010 12:01:10 +0100 (CET) Subject: [pypy-svn] r70909 - in pypy/trunk/pypy/jit/metainterp: . test Message-ID: <20100127110110.ED0E0168048@codespeak.net> Author: cfbolz Date: Wed Jan 27 12:01:10 2010 New Revision: 70909 Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Log: A tiny optimization on "oois": oois(X, X) returns True. This turns up a few times when using old-style classes (something to do with coercion or so). Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Wed Jan 27 12:01:10 2010 @@ -737,6 +737,8 @@ self._optimize_nullness(op, op.args[0], expect_isnot) elif value0.is_null(): self._optimize_nullness(op, op.args[1], expect_isnot) + elif value0 is value1: + self.make_constant_int(op.result, not expect_isnot) else: cls0 = value0.get_constant_class(self.cpu) if cls0 is not None: Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Wed Jan 27 12:01:10 2010 @@ -1861,6 +1861,24 @@ """ self.optimize_loop(ops, "Not", expected) + def test_oois_of_itself(self): + ops = """ + [p0] + p1 = getfield_gc(p0, descr=nextdescr) + p2 = getfield_gc(p0, descr=nextdescr) + i1 = oois(p1, p2) + guard_true(i1) [] + i2 = ooisnot(p1, p2) + guard_false(i2) [] + jump(p0) + """ + expected = """ + [p0] + p1 = getfield_gc(p0, descr=nextdescr) + jump(p0) + """ + self.optimize_loop(ops, 'Not', expected) + def test_remove_duplicate_pure_op(self): ops = """ [p1, p2] From cfbolz at codespeak.net Wed Jan 27 12:02:26 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 27 Jan 2010 12:02:26 +0100 (CET) Subject: [pypy-svn] r70910 - pypy/trunk/pypy/interpreter Message-ID: <20100127110226.805D4168048@codespeak.net> Author: cfbolz Date: Wed Jan 27 12:02:26 2010 New Revision: 70910 Modified: pypy/trunk/pypy/interpreter/pyopcode.py Log: remove an unused variable Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Wed Jan 27 12:02:26 2010 @@ -897,7 +897,6 @@ if n_keywords: keywords = [None] * n_keywords keywords_w = [None] * n_keywords - dic_w = {} while True: n_keywords -= 1 if n_keywords < 0: From pedronis at codespeak.net Wed Jan 27 12:39:11 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 27 Jan 2010 12:39:11 +0100 (CET) Subject: [pypy-svn] r70911 - pypy/extradoc/talk/jan10 Message-ID: <20100127113911.2F6D6168032@codespeak.net> Author: pedronis Date: Wed Jan 27 12:39:10 2010 New Revision: 70911 Added: pypy/extradoc/talk/jan10/ - copied from r70884, pypy/extradoc/talk/jitdec09/ pypy/extradoc/talk/jan10/benchs.pdf (contents, props changed) Removed: pypy/extradoc/talk/jan10/result.png Modified: pypy/extradoc/talk/jan10/talk.html pypy/extradoc/talk/jan10/talk.txt Log: various pypy technology aspects talk Added: pypy/extradoc/talk/jan10/benchs.pdf ============================================================================== Binary file. No diff available. Modified: pypy/extradoc/talk/jan10/talk.html ============================================================================== --- pypy/extradoc/talk/jitdec09/talk.html (original) +++ pypy/extradoc/talk/jan10/talk.html Wed Jan 27 12:39:10 2010 @@ -5,9 +5,9 @@ -A generated JIT compiler for Python +PyPy Technologies - +