def newgraph(gv_FUNCTYPE, name): FUNCTYPE = _from_opaque(gv_FUNCTYPE).value # 'name' is just a way to track things name = from_opaque_string(name) inputargs = [] erasedinputargs = [] for ARG in FUNCTYPE.ARGS: v = flowmodel.Variable() v.concretetype = ARG inputargs.append(v) v = flowmodel.Variable() v.concretetype = lltype.erasedType(ARG) erasedinputargs.append(v) startblock = flowmodel.Block(inputargs) # insert an exploding operation here which is removed by # builder.end() to ensure that builder.end() is actually called. startblock.operations.append( flowmodel.SpaceOperation("debug_assert", [ flowmodel.Constant(False, lltype.Bool), flowmodel.Constant("you didn't call builder.end()?", lltype.Void) ], varoftype(lltype.Void))) return_var = flowmodel.Variable() return_var.concretetype = FUNCTYPE.RESULT graph = flowmodel.FunctionGraph(name, startblock, return_var) v1 = flowmodel.Variable() v1.concretetype = lltype.erasedType(FUNCTYPE.RESULT) graph.prereturnblock = flowmodel.Block([v1]) casting_link(graph.prereturnblock, [v1], graph.returnblock) substartblock = flowmodel.Block(erasedinputargs) casting_link(graph.startblock, inputargs, substartblock) fptr = lltype.functionptr(FUNCTYPE, name, graph=graph) return genconst(fptr)
def newgraph(gv_FUNCTYPE, name): FUNCTYPE = from_opaque_object(gv_FUNCTYPE).value # 'name' is just a way to track things if not isinstance(name, str): name = LLSupport.from_rstr(name) inputargs = [] erasedinputargs = [] for ARG in FUNCTYPE.ARGS: v = flowmodel.Variable() v.concretetype = ARG inputargs.append(v) v = flowmodel.Variable() v.concretetype = lltype.erasedType(ARG) erasedinputargs.append(v) startblock = flowmodel.Block(inputargs) # insert an exploding operation here which is removed by # builder.end() to ensure that builder.end() is actually called. startblock.operations.append( flowmodel.SpaceOperation("debug_assert", [flowmodel.Constant(False, lltype.Bool), flowmodel.Constant("you didn't call builder.end()?", lltype.Void)], varoftype(lltype.Void))) return_var = flowmodel.Variable() return_var.concretetype = FUNCTYPE.RESULT graph = flowmodel.FunctionGraph(name, startblock, return_var) v1 = flowmodel.Variable() v1.concretetype = lltype.erasedType(FUNCTYPE.RESULT) graph.prereturnblock = flowmodel.Block([v1]) casting_link(graph.prereturnblock, [v1], graph.returnblock) substartblock = flowmodel.Block(erasedinputargs) casting_link(graph.startblock, inputargs, substartblock) fptr = lltype.functionptr(FUNCTYPE, name, graph=graph) return genconst(fptr)
def erasedvar(v, block): T = lltype.erasedType(v.concretetype) if T != v.concretetype: v2 = flowmodel.Variable() v2.concretetype = T op = flowmodel.SpaceOperation("cast_pointer", [v], v2) block.operations.append(op) return v2 return v
def geninputarg(block, gv_CONCRETE_TYPE): block = _from_opaque(block) assert not block.operations, "block already contains operations" assert block.exits == [], "block already closed" CONCRETE_TYPE = _from_opaque(gv_CONCRETE_TYPE).value v = flowmodel.Variable() v.concretetype = lltype.erasedType(CONCRETE_TYPE) block.inputargs.append(v) return _to_opaque(v)
def geninputarg(block, gv_CONCRETE_TYPE): block = from_opaque_object(block) assert not block.operations, "block already contains operations" assert block.exits == [], "block already closed" CONCRETE_TYPE = from_opaque_object(gv_CONCRETE_TYPE).value v = flowmodel.Variable() v.concretetype = lltype.erasedType(CONCRETE_TYPE) block.inputargs.append(v) return to_opaque_object(v)
def genconst(llvalue): T = lltype.typeOf(llvalue) T1 = lltype.erasedType(T) if T1 != T: llvalue = lltype.cast_pointer(T1, llvalue) v = flowmodel.Constant(llvalue) v.concretetype = T1 if v.concretetype == lltype.Void: # XXX genconst should not really be used for Void constants assert not isinstance(llvalue, str) and not isinstance(llvalue, lltype.LowLevelType) return to_opaque_object(v)
def genconst(llvalue): T = lltype.typeOf(llvalue) T1 = lltype.erasedType(T) if T1 != T: llvalue = lltype.cast_pointer(T1, llvalue) v = flowmodel.Constant(llvalue) v.concretetype = T1 if v.concretetype == lltype.Void: # XXX genconst should not really be used for Void constants assert not isinstance(llvalue, str) and not isinstance( llvalue, lltype.LowLevelType) return _to_opaque(v)
def cast(block, gv_TYPE, gv_var): TYPE = from_opaque_object(gv_TYPE).value v = from_opaque_object(gv_var) if TYPE != v.concretetype: if TYPE is llmemory.GCREF or v.concretetype is llmemory.GCREF: lltype.cast_opaque_ptr(TYPE, v.concretetype._defl()) # sanity check opname = 'cast_opaque_ptr' else: assert v.concretetype == lltype.erasedType(TYPE) opname = 'cast_pointer' block = from_opaque_object(block) v2 = flowmodel.Variable() v2.concretetype = TYPE op = flowmodel.SpaceOperation(opname, [v], v2) block.operations.append(op) v = v2 return to_opaque_object(v)
def cast(block, gv_TYPE, gv_var): TYPE = _from_opaque(gv_TYPE).value v = _from_opaque(gv_var) if TYPE != v.concretetype: if TYPE is llmemory.GCREF or v.concretetype is llmemory.GCREF: lltype.cast_opaque_ptr(TYPE, v.concretetype._defl()) # sanity check opname = 'cast_opaque_ptr' else: assert v.concretetype == lltype.erasedType(TYPE) opname = 'cast_pointer' block = _from_opaque(block) v2 = flowmodel.Variable() v2.concretetype = TYPE op = flowmodel.SpaceOperation(opname, [v], v2) block.operations.append(op) v = v2 return _to_opaque(v)
def erasedType(T): return lltype.erasedType(T)
def genzeroconst(gv_TYPE): TYPE = _from_opaque(gv_TYPE).value TYPE = lltype.erasedType(TYPE) c = flowmodel.Constant(TYPE._defl()) c.concretetype = TYPE return _to_opaque(c)
def genzeroconst(gv_TYPE): TYPE = from_opaque_object(gv_TYPE).value TYPE = lltype.erasedType(TYPE) c = flowmodel.Constant(TYPE._defl()) c.concretetype = TYPE return to_opaque_object(c)