importfunctoolsimportmathimportstructfrompypy.interpreter.errorimportOperationErrorfrompypy.module.micronumpyimportinterp_boxesfrompypy.objspace.std.floatobjectimportfloat2stringfrompypy.rlibimportrfloat,libffi,clibffifrompypy.rlib.objectmodelimportspecialize,we_are_translatedfrompypy.rlib.rarithmeticimportwiden,byteswapfrompypy.rpython.lltypesystemimportlltype,rffifrompypy.rlib.rstruct.runpackimportrunpackfrompypy.tool.sourcetoolsimportfunc_with_new_namefrompypy.rlibimportjitVOID_STORAGE=lltype.Array(lltype.Char,hints={'nolength':True,'render_as_void':True})defsimple_unary_op(func):specialize.argtype(1)(func)@functools.wraps(func)defdispatcher(self,v):returnself.box(func(self,self.for_computation(self.unbox(v))))returndispatcherdefraw_unary_op(func):specialize.argtype(1)(func)@functools.wraps(func)defdispatcher(self,v):returnfunc(self,self.for_computation(self.unbox(v)))returndispatcherdefsimple_binary_op(func):specialize.argtype(1,2)(func)@functools.wraps(func)defdispatcher(self,v1,v2):returnself.box(func(self,self.for_computation(self.unbox(v1)),self.for_computation(self.unbox(v2)),))returndispatcherdefraw_binary_op(func):specialize.argtype(1,2)(func)@functools.wraps(func)defdispatcher(self,v1,v2):returnfunc(self,self.for_computation(self.unbox(v1)),self.for_computation(self.unbox(v2)))returndispatcherclassBaseType(object):def_unimplemented_ufunc(self,*args):raiseNotImplementedErrordefmalloc(self,size):# XXX find out why test_zjit explodes with tracking of allocationsreturnlltype.malloc(VOID_STORAGE,size,zero=True,flavor="raw",track_allocation=False,add_memory_pressure=True)def__repr__(self):returnself.__class__.__name__classPrimitive(object):_mixin_=Truedefget_element_size(self):returnrffi.sizeof(self.T)@specialize.argtype(1)defbox(self,value):returnself.BoxType(rffi.cast(self.T,value))defunbox(self,box):assertisinstance(box,self.BoxType)returnbox.valuedefcoerce(self,space,dtype,w_item):ifisinstance(w_item,self.BoxType):returnw_itemreturnself.coerce_subtype(space,space.gettypefor(self.BoxType),w_item)defcoerce_subtype(self,space,w_subtype,w_item):# XXX: uglyw_obj=space.allocate_instance(self.BoxType,w_subtype)assertisinstance(w_obj,self.BoxType)w_obj.__init__(self._coerce(space,w_item).value)returnw_objdefto_builtin_type(self,space,box):returnspace.wrap(self.for_computation(self.unbox(box)))def_coerce(self,space,w_item):raiseNotImplementedErrordefdefault_fromstring(self,space):raiseNotImplementedErrordef_read(self,storage,width,i,offset):ifwe_are_translated():returnlibffi.array_getitem(clibffi.cast_type_to_ffitype(self.T),width,storage,i,offset)else:returnlibffi.array_getitem_T(self.T,width,storage,i,offset)defread(self,arr,width,i,offset):returnself.box(self._read(arr.storage,width,i,offset))defread_bool(self,arr,width,i,offset):returnbool(self.for_computation(self._read(arr.storage,width,i,offset)))def_write(self,storage,width,i,offset,value):ifwe_are_translated():libffi.array_setitem(clibffi.cast_type_to_ffitype(self.T),width,storage,i,offset,value)else:libffi.array_setitem_T(self.T,width,storage,i,offset,value)defstore(self,arr,width,i,offset,box):self._write(arr.storage,width,i,offset,self.unbox(box))deffill(self,storage,width,box,start,stop,offset):value=self.unbox(box)foriinxrange(start,stop,width):self._write(storage,1,i,offset,value)defrunpack_str(self,s):returnself.box(runpack(self.format_code,s))defpack_str(self,box):returnstruct.pack(self.format_code,self.unbox(box))@simple_binary_opdefadd(self,v1,v2):returnv1+v2@simple_binary_opdefsub(self,v1,v2):returnv1-v2@simple_binary_opdefmul(self,v1,v2):returnv1*v2@simple_unary_opdefpos(self,v):return+v@simple_unary_opdefneg(self,v):return-v@simple_unary_opdefabs(self,v):returnabs(v)@raw_unary_opdefisnan(self,v):returnFalse@raw_unary_opdefisinf(self,v):returnFalse@raw_binary_opdefeq(self,v1,v2):returnv1==v2@raw_binary_opdefne(self,v1,v2):returnv1!=v2@raw_binary_opdeflt(self,v1,v2):returnv1<v2@raw_binary_opdefle(self,v1,v2):returnv1<=v2@raw_binary_opdefgt(self,v1,v2):returnv1>v2@raw_binary_opdefge(self,v1,v2):returnv1>=v2@raw_binary_opdeflogical_and(self,v1,v2):returnbool(v1)andbool(v2)@raw_binary_opdeflogical_or(self,v1,v2):returnbool(v1)orbool(v2)@raw_unary_opdeflogical_not(self,v):returnnotbool(v)@raw_binary_opdeflogical_xor(self,v1,v2):returnbool(v1)^bool(v2)defbool(self,v):returnbool(self.for_computation(self.unbox(v)))@simple_binary_opdefmax(self,v1,v2):returnmax(v1,v2)@simple_binary_opdefmin(self,v1,v2):returnmin(v1,v2)classNonNativePrimitive(Primitive):_mixin_=Truedef_read(self,storage,width,i,offset):returnbyteswap(Primitive._read(self,storage,width,i,offset))def_write(self,storage,width,i,offset,value):Primitive._write(self,storage,width,i,offset,byteswap(value))defpack_str(self,box):returnstruct.pack(self.format_code,byteswap(self.unbox(box)))classBool(BaseType,Primitive):T=lltype.BoolBoxType=interp_boxes.W_BoolBoxformat_code="?"True=BoxType(True)False=BoxType(False)@specialize.argtype(1)defbox(self,value):box=Primitive.box(self,value)ifbox.value:returnself.Trueelse:returnself.Falsedefcoerce_subtype(self,space,w_subtype,w_item):# Doesn't return subclasses so it can return the constants.returnself._coerce(space,w_item)def_coerce(self,space,w_item):returnself.box(space.is_true(w_item))defto_builtin_type(self,space,w_item):returnspace.wrap(self.unbox(w_item))defstr_format(self,box):return"True"ifself.unbox(box)else"False"deffor_computation(self,v):returnint(v)defdefault_fromstring(self,space):returnself.box(False)@simple_binary_opdefbitwise_and(self,v1,v2):returnv1&v2@simple_binary_opdefbitwise_or(self,v1,v2):returnv1|v2@simple_binary_opdefbitwise_xor(self,v1,v2):returnv1^v2@simple_unary_opdefinvert(self,v):return~vNonNativeBool=BoolclassInteger(Primitive):_mixin_=Truedef_base_coerce(self,space,w_item):returnself.box(space.int_w(space.call_function(space.w_int,w_item)))def_coerce(self,space,w_item):returnself._base_coerce(space,w_item)defstr_format(self,box):returnstr(self.for_computation(self.unbox(box)))deffor_computation(self,v):returnwiden(v)defdefault_fromstring(self,space):returnself.box(0)@simple_binary_opdefdiv(self,v1,v2):ifv2==0:return0returnv1/v2@simple_binary_opdefmod(self,v1,v2):returnv1%v2@simple_binary_opdefpow(self,v1,v2):res=1whilev2>0:ifv2&1:res*=v1v2>>=1ifv2==0:breakv1*=v1returnres@simple_binary_opdeflshift(self,v1,v2):returnv1<<v2@simple_binary_opdefrshift(self,v1,v2):returnv1>>v2@simple_unary_opdefsign(self,v):ifv>0:return1elifv<0:return-1else:assertv==0return0@simple_binary_opdefbitwise_and(self,v1,v2):returnv1&v2@simple_binary_opdefbitwise_or(self,v1,v2):returnv1|v2@simple_binary_opdefbitwise_xor(self,v1,v2):returnv1^v2@simple_unary_opdefinvert(self,v):return~vclassNonNativeInteger(NonNativePrimitive,Integer):_mixin_=TrueclassInt8(BaseType,Integer):T=rffi.SIGNEDCHARBoxType=interp_boxes.W_Int8Boxformat_code="b"NonNativeInt8=Int8classUInt8(BaseType,Integer):T=rffi.UCHARBoxType=interp_boxes.W_UInt8Boxformat_code="B"NonNativeUInt8=UInt8classInt16(BaseType,Integer):T=rffi.SHORTBoxType=interp_boxes.W_Int16Boxformat_code="h"classNonNativeInt16(BaseType,NonNativeInteger):T=rffi.SHORTBoxType=interp_boxes.W_Int16Boxformat_code="h"classUInt16(BaseType,Integer):T=rffi.USHORTBoxType=interp_boxes.W_UInt16Boxformat_code="H"classNonNativeUInt16(BaseType,NonNativeInteger):T=rffi.USHORTBoxType=interp_boxes.W_UInt16Boxformat_code="H"classInt32(BaseType,Integer):T=rffi.INTBoxType=interp_boxes.W_Int32Boxformat_code="i"classNonNativeInt32(BaseType,NonNativeInteger):T=rffi.INTBoxType=interp_boxes.W_Int32Boxformat_code="i"classUInt32(BaseType,Integer):T=rffi.UINTBoxType=interp_boxes.W_UInt32Boxformat_code="I"classNonNativeUInt32(BaseType,NonNativeInteger):T=rffi.UINTBoxType=interp_boxes.W_UInt32Boxformat_code="I"classLong(BaseType,Integer):T=rffi.LONGBoxType=interp_boxes.W_LongBoxformat_code="l"classNonNativeLong(BaseType,NonNativeInteger):T=rffi.LONGBoxType=interp_boxes.W_LongBoxformat_code="l"classULong(BaseType,Integer):T=rffi.ULONGBoxType=interp_boxes.W_ULongBoxformat_code="L"classNonNativeULong(BaseType,NonNativeInteger):T=rffi.ULONGBoxType=interp_boxes.W_ULongBoxformat_code="L"classInt64(BaseType,Integer):T=rffi.LONGLONGBoxType=interp_boxes.W_Int64Boxformat_code="q"classNonNativeInt64(BaseType,NonNativeInteger):T=rffi.LONGLONGBoxType=interp_boxes.W_Int64Boxformat_code="q"def_uint64_coerce(self,space,w_item):try:returnself._base_coerce(space,w_item)exceptOperationError,e:ifnote.match(space,space.w_OverflowError):raisebigint=space.bigint_w(w_item)try:value=bigint.toulonglong()exceptOverflowError:raiseOperationError(space.w_OverflowError,space.w_None)returnself.box(value)classUInt64(BaseType,Integer):T=rffi.ULONGLONGBoxType=interp_boxes.W_UInt64Boxformat_code="Q"_coerce=func_with_new_name(_uint64_coerce,'_coerce')classNonNativeUInt64(BaseType,NonNativeInteger):T=rffi.ULONGLONGBoxType=interp_boxes.W_UInt64Boxformat_code="Q"_coerce=func_with_new_name(_uint64_coerce,'_coerce')classFloat(Primitive):_mixin_=Truedef_coerce(self,space,w_item):returnself.box(space.float_w(space.call_function(space.w_float,w_item)))defstr_format(self,box):returnfloat2string(self.for_computation(self.unbox(box)),"g",rfloat.DTSF_STR_PRECISION)deffor_computation(self,v):returnfloat(v)defdefault_fromstring(self,space):returnself.box(-1.0)@simple_binary_opdefdiv(self,v1,v2):try:returnv1/v2exceptZeroDivisionError:ifv1==v2==0.0:returnrfloat.NANreturnrfloat.copysign(rfloat.INFINITY,v1*v2)@simple_binary_opdefmod(self,v1,v2):returnmath.fmod(v1,v2)@simple_binary_opdefpow(self,v1,v2):returnmath.pow(v1,v2)@simple_binary_opdefcopysign(self,v1,v2):returnmath.copysign(v1,v2)@simple_unary_opdefsign(self,v):ifv==0.0:return0.0returnrfloat.copysign(1.0,v)@simple_unary_opdeffabs(self,v):returnmath.fabs(v)@simple_unary_opdefreciprocal(self,v):ifv==0.0:returnrfloat.copysign(rfloat.INFINITY,v)return1.0/v@simple_unary_opdeffloor(self,v):returnmath.floor(v)@simple_unary_opdefceil(self,v):returnmath.ceil(v)@simple_unary_opdefexp(self,v):try:returnmath.exp(v)exceptOverflowError:returnrfloat.INFINITY@simple_unary_opdefsin(self,v):returnmath.sin(v)@simple_unary_opdefcos(self,v):returnmath.cos(v)@simple_unary_opdeftan(self,v):returnmath.tan(v)@simple_unary_opdefarcsin(self,v):ifnot-1.0<=v<=1.0:returnrfloat.NANreturnmath.asin(v)@simple_unary_opdefarccos(self,v):ifnot-1.0<=v<=1.0:returnrfloat.NANreturnmath.acos(v)@simple_unary_opdefarctan(self,v):returnmath.atan(v)@simple_unary_opdefarcsinh(self,v):returnmath.asinh(v)@simple_unary_opdefarctanh(self,v):ifv==1.0orv==-1.0:returnmath.copysign(rfloat.INFINITY,v)ifnot-1.0<v<1.0:returnrfloat.NANreturnmath.atanh(v)@simple_unary_opdefsqrt(self,v):try:returnmath.sqrt(v)exceptValueError:returnrfloat.NAN@raw_unary_opdefisnan(self,v):returnrfloat.isnan(v)@raw_unary_opdefisinf(self,v):returnrfloat.isinf(v)classNonNativeFloat(NonNativePrimitive,Float):_mixin_=TrueclassFloat32(BaseType,Float):T=rffi.FLOATBoxType=interp_boxes.W_Float32Boxformat_code="f"classNonNativeFloat32(BaseType,NonNativeFloat):T=rffi.FLOATBoxType=interp_boxes.W_Float32Boxformat_code="f"classFloat64(BaseType,Float):T=rffi.DOUBLEBoxType=interp_boxes.W_Float64Boxformat_code="d"classNonNativeFloat64(BaseType,NonNativeFloat):T=rffi.DOUBLEBoxType=interp_boxes.W_Float64Boxformat_code="d"classCompositeType(BaseType):def__init__(self,offsets_and_fields,size):self.offsets_and_fields=offsets_and_fieldsself.size=sizedefget_element_size(self):returnself.sizeclassBaseStringType(object):_mixin_=Truedef__init__(self,size=0):self.size=sizedefget_element_size(self):returnself.size*rffi.sizeof(self.T)defarray(self,size):returntype(self)(size)classStringType(BaseType,BaseStringType):T=lltype.CharclassVoidType(BaseType,BaseStringType):T=lltype.CharNonNativeVoidType=VoidTypeNonNativeStringType=StringTypeclassUnicodeType(BaseType,BaseStringType):T=lltype.UniCharNonNativeUnicodeType=UnicodeTypeclassRecordType(CompositeType):T=lltype.Chardefread(self,arr,width,i,offset):returninterp_boxes.W_VoidBox(arr,i)@jit.unroll_safedefcoerce(self,space,dtype,w_item):frompypy.module.micronumpy.interp_numarrayimportW_NDimArrayifisinstance(w_item,interp_boxes.W_VoidBox):returnw_item# we treat every sequence as sequence, no special support# for arraysifnotspace.issequence_w(w_item):raiseOperationError(space.w_TypeError,space.wrap("expected sequence"))iflen(self.offsets_and_fields)!=space.int_w(space.len(w_item)):raiseOperationError(space.w_ValueError,space.wrap("wrong length"))items_w=space.fixedview(w_item)# XXX optimize it out one day, but for now we just allocate an# arrayarr=W_NDimArray([1],dtype)foriinrange(len(items_w)):subdtype=dtype.fields[dtype.fieldnames[i]][1]ofs,itemtype=self.offsets_and_fields[i]w_item=items_w[i]w_box=itemtype.coerce(space,subdtype,w_item)itemtype.store(arr,1,0,ofs,w_box)returninterp_boxes.W_VoidBox(arr,0)@jit.unroll_safedefstore(self,arr,_,i,ofs,box):assertisinstance(box,interp_boxes.W_VoidBox)forkinrange(self.get_element_size()):arr.storage[k+i]=box.arr.storage[k+box.ofs]@jit.unroll_safedefstr_format(self,box):assertisinstance(box,interp_boxes.W_VoidBox)pieces=["("]first=Trueforofs,tpinself.offsets_and_fields:iffirst:first=Falseelse:pieces.append(", ")pieces.append(tp.str_format(tp.read(box.arr,1,box.ofs,ofs)))pieces.append(")")return"".join(pieces)fortpin[Int32,Int64]:iftp.T==lltype.Signed:IntP=tpbreakfortpin[UInt32,UInt64]:iftp.T==lltype.Unsigned:UIntP=tpbreakdeltpdef_setup():# compute alignmentfortpinglobals().values():ifisinstance(tp,type)andhasattr(tp,'T'):tp.alignment=clibffi.cast_type_to_ffitype(tp.T).c_alignment_setup()del_setup