def getMethod(self, name, paramList, returnType): if isinstance(returnType, vartypes.Type): returnType = returnType.builder if returnType is None: # Only user types will not have builders at this point. # External classes never return user types. # If they could, it would be some sort of circular inter-program dependancy. return None if not isinstance(returnType, System.Type): returnType = ExternalType.getNineType(returnType).builder args = util.toTypedArray(System.Type, [util.getNetType(t) for t in paramList]) assert None not in args, paramList # IronPython hack: Querying MulticastDelegate for its Invoke method segfaults Mono for some reason. # -- andy 2 Feb 2014 if self.builder == System.MulticastDelegate and name == 'Invoke': return None methodInfo = self.builder.GetMethod(name, args) if methodInfo is None: return None if System.Object.ReferenceEquals(methodInfo.ReturnType, returnType): return ExternalMethod(self, methodInfo) else: return None
def getMethod(self, name, paramList, returnType): if isinstance(returnType, vartypes.Type): returnType = returnType.builder if returnType is None: # Only user types will not have builders at this point. # External classes never return user types. # If they could, it would be some sort of circular inter-program dependancy. # Thus, if the returnType has no builder, there cannot possibly be a match. return None if not isinstance(returnType, System.Type): returnType = ExternalType.getNineType(returnType).builder args = util.toTypedArray(System.Type, [util.getNetType(t) for t in paramList]) assert None not in args, paramList methodInfo = self.builder.GetMethod(name, args) if methodInfo is None: return None if System.Object.ReferenceEquals(methodInfo.ReturnType, returnType): return ExternalMethod(self, methodInfo) else: return None
def emitType(self, gen): # Redundant calls to emitType have no effect. if self.builder is not None: return log.write('emit', 'emitType class ', self, self.name) from CLR import System flags = gen.TypeAttributes.Public if self.flags.abstract: flags |= gen.TypeAttributes.Abstract if self.flags.sealed: flags |= gen.TypeAttributes.Sealed # Be sure everybody gets their builders built. self.baseClass.emitType(gen) for iface in self.baseInterfaces: iface.emitType(gen) ifaces = util.toTypedArray(System.Type, [iface.builder for iface in self.baseInterfaces]) assert self.baseClass is not None, self assert self.baseClass.builder is not None, self.baseClass assert None not in ifaces, self.baseInterfaces self.builder = gen.module.DefineType(self.name, flags, self.baseClass.builder, ifaces)
def emitDeclaration(self, gen): if self.builder is not None: return flags = gen.MethodAttributes.Public | gen.MethodAttributes.Abstract | gen.MethodAttributes.Virtual paramTypes = util.toTypedArray(System.Type, [param.type.builder for param in self.params]) self.builder = gen.typeBuilder.DefineMethod(self.name, flags, self.returnType.builder, paramTypes)
def emitType(self, gen): if self.builder is not None: return log.write('emit', 'emitType iface ', self, self.name) flags = gen.TypeAttributes.Interface | gen.TypeAttributes.Abstract | gen.TypeAttributes.Public ifaces = util.toTypedArray(System.Type, [iface.builder for iface in self.bases]) self.builder = gen.module.DefineType(self.name, flags, None, ifaces)
def emitLoad(self, gen): from CLR import System argTypes = util.toTypedArray(System.Type, (System.String, System.String)) concatMethod = vartypes.StringType.builder.GetMethod("Concat", argTypes) assert concatMethod is not None, self self.lhs.emitLoad(gen) self.rhs.emitLoad(gen) gen.ilGen.Emit(gen.opCodes.Call, concatMethod)
def emitLoadAddress(self, gen): getArgs = [System.Int32] * len(self.indicies) getArgs = util.toTypedArray(System.Type, getArgs) getm = self.identifier.variable.type.builder.GetMethod('Address', getArgs) self.identifier.emitLoad(gen) for i, index in enumerate(self.indicies): index.emitLoad(gen) gen.ilGen.Emit(gen.opCodes.Call, getm)
def emitLoad(self, gen): arrayType = self.identifier.getType() getArgs = [System.Int32] * len(self.indicies) getArgs = util.toTypedArray(System.Type, getArgs) getm = arrayType.builder.GetMethod('Get', getArgs) self.identifier.emitLoad(gen) for i, index in enumerate(self.indicies): index.emitLoad(gen) gen.ilGen.Emit(gen.opCodes.Call, getm)
def emitAssign(self, rhs, gen): arrayType = self.identifier.getType() setArgs = [System.Int32]*len(self.indicies) setArgs.append(arrayType.arrayType.builder) setArgs = util.toTypedArray(System.Type, setArgs) setm = arrayType.builder.GetMethod('Set', setArgs) self.identifier.emitLoad(gen) for index in self.indicies: index.emitLoad(gen) rhs.emitLoad(gen) gen.ilGen.Emit(gen.opCodes.Call, setm)
def emitLoad(self, gen): for s in self.size: s.emitLoad(gen) if len(self.size) == 1: gen.ilGen.Emit(gen.opCodes.Newarr, self.elementType.builder) else: from CLR import System from ast import vartypes argTypes = (vartypes.IntType.builder,) * len(self.size) argTypes = util.toTypedArray(System.Type, argTypes) ctor = self.arrayType.builder.GetConstructor(argTypes) assert ctor is not None, (self.arrayType, self.arrayType.builder.FullName) gen.ilGen.Emit(gen.opCodes.Newobj, ctor)
def emitLoadAddress(self, gen): """Umm, dunno if this applies to strings will we ever want the address of a character in a string? FIXME: Making this work allows assigning specific character slots in a string to a variable... maybe this should be disallowed? """ raise error.CodeError("Cannot variablize a character in a string") #TODO: Create an emulation of this method's purpose for string assignment # will probably just end up a call to emitAssign getArgs = [System.Int32] * len(self.indicies) getArgs = util.toTypedArray(System.Type, getArgs) getm = self.identifier.variable.type.builder.GetMethod('Address', getArgs) self.identifier.emitLoad(gen) for i, index in enumerate(self.indicies): index.emitLoad(gen) gen.ilGen.Emit(gen.opCodes.Call, getm)
def getCtor(self, params): '''Returns a constructor that recieves the given set of parameters. params is a list that contains the types that the returned constructor recieves. (types, not Parameter instances!) ''' paramTypes = util.toTypedArray(System.Type, [util.getNetType(param.getType()) for param in params] ) ctorInfo = self.builder.GetConstructor(paramTypes) if ctorInfo is None: return None else: return ExternalConstructor(ctorInfo, self)