def resolve_type(context, op): """ Resolve types for ops: - map flypy type to low-level representation type - represent stack-allocated values through pointers """ if isinstance(op, (FuncArg, Const, Op, Undef)): if op.type.is_void: return op if op not in context: raise errors.CompileError("Type for %s was lost" % (op,)) # Retrieve type type = context[op] # Remove dummy method lookups (TODO: methods as first-class citizens) if type.__class__.__name__ == 'Method': return op # TODO: Remove this # Generate low-level representation type if isinstance(type, set): assert not isinstance(type, set) ltype = compiler.representation_type(type) if isinstance(op, Const): const = op.const # Represent dummy constant structs with at least one field for LLVM if isinstance(const, Struct) and not const.values: const = Struct(['dummy'], [Const(0, ptypes.Int32)]) # Also represent stack-allocated values through pointers if ltype.is_pointer and not isinstance(const, Pointer): const = Pointer(const, ltype) op = Const(const, ltype) elif isinstance(op, Undef): op = Undef(ltype) else: op.type = ltype return op
def resolve_type(context, op): """ Resolve types for ops: - map flypy type to low-level representation type - represent stack-allocated values through pointers """ if isinstance(op, (FuncArg, Const, Op, Undef)): if op.type.is_void: return op if op not in context: raise errors.CompileError("Type for %s was lost" % (op, )) # Retrieve type type = context[op] # Remove dummy method lookups (TODO: methods as first-class citizens) if type.__class__.__name__ == 'Method': return op # TODO: Remove this # Generate low-level representation type if isinstance(type, set): assert not isinstance(type, set) ltype = compiler.representation_type(type) if isinstance(op, Const): const = op.const # Represent dummy constant structs with at least one field for LLVM if isinstance(const, Struct) and not const.values: const = Struct(['dummy'], [Const(0, ptypes.Int32)]) # Also represent stack-allocated values through pointers if ltype.is_pointer and not isinstance(const, Pointer): const = Pointer(const, ltype) op = Const(const, ltype) elif isinstance(op, Undef): op = Undef(ltype) else: op.type = ltype return op
def impl(py_func, argtypes): # TODO: do this better from flypy.compiler import representation_type ll_argtypes = [representation_type(x) for x in argtypes] argnames = list(string.ascii_letters[:len(argtypes)]) # Determine return type if restype_func: result_type = restype_func(argtypes) else: result_type = restype or ll_argtypes[0] type = ptypes.Function(result_type, tuple(ll_argtypes), False) func = ir.Function(name, argnames, type) func.new_block("entry") b = ir.Builder(func) b.position_at_beginning(func.startblock) implementation(b, argtypes, *func.args) return func
def lltyping(func, env): """Annotate the function with the low-level representation types""" if not env['flypy.state.opaque']: context = env['flypy.typing.context'] resolve = partial(resolve_type, context) for arg in func.args: resolve(arg) for op in func.ops: if op.opcode == 'exc_catch': continue op.replace(resolve(op)) op.set_args(nestedmap(resolve, op.args)) restype = env['flypy.typing.restype'] if conversion.byref(restype): ll_restype = ptypes.Void else: ll_restype = compiler.representation_type(restype) func.type = ptypes.Function(ll_restype, [arg.type for arg in func.args], False)
def _getitem_type(argtypes): base = argtypes[0].parameters[0] return representation_type(base)