def closeblock2(block, exitswitch): block = _from_opaque(block) exitswitch = _from_opaque(exitswitch) assert isinstance(exitswitch, flowmodel.Variable) block.exitswitch = exitswitch false_link = flowmodel.Link([], None) false_link.exitcase = False false_link.llexitcase = False true_link = flowmodel.Link([], None) true_link.exitcase = True true_link.llexitcase = True block.closeblock(false_link, true_link) return pseudotuple(_to_opaque(false_link), _to_opaque(true_link))
def test_nclc_nongc_not_passed_on(): # +--- inputargs: pointer_to_gc # | v0 <- op_getsubstruct pointer_to_gc 'b' # +--- exitargs: pointer_to_gc (i.e. the pointer to non-gc doesn't leave the block) llops = LowLevelOpList() ptr_a = varoftype(lltype.Ptr(GcA)) v_res = llops.genop("getsubstruct", [ptr_a, model.Constant('b', lltype.Void)], resulttype=lltype.Ptr(NonGcB)) block = model.Block([ptr_a]) block.operations.extend(llops) block.closeblock(model.Link([ptr_a], None)) assert not needs_conservative_livevar_calculation(block)
def add_default(block): block = _from_opaque(block) assert isinstance(block.exitswitch, flowmodel.Variable) default_link = flowmodel.Link([], None) default_link.exitcase = 'default' default_link.llexitcase = None if block.exits and block.exits[-1].exitcase == 'default': raise ValueError else: exits = block.exits + (default_link, ) block.recloseblock(*exits) return _to_opaque(default_link)
def test_nclc_should_be_true(): # this is testing a block like: # +--- inputargs: pointer_to_gc # | v0 <- op_getsubstruct pointer_to_gc 'b' # +--- exitargs: v0 (i.e. pointer to non-gc) llops = LowLevelOpList() ptr_a = varoftype(lltype.Ptr(GcA)) v_res = llops.genop("getsubstruct", [ptr_a, model.Constant('b', lltype.Void)], resulttype=lltype.Ptr(NonGcB)) block = model.Block([ptr_a]) block.operations.extend(llops) block.closeblock(model.Link([v_res], None)) assert needs_conservative_livevar_calculation(block)
def casting_link(source, sourcevars, target): assert len(sourcevars) == len(target.inputargs) linkargs = [] for v, target_v in zip(sourcevars, target.inputargs): if v.concretetype == target_v.concretetype: linkargs.append(v) else: erasedv = flowmodel.Variable() erasedv.concretetype = target_v.concretetype source.operations.append( flowmodel.SpaceOperation('cast_pointer', [v], erasedv)) linkargs.append(erasedv) source.closeblock(flowmodel.Link(linkargs, target))
def test_sbwk_should_insert_keepalives(): # this is testing something like: # v0 <- op_producing_non_gc # v1 <- op_using_v0 <- split here llops = LowLevelOpList() ptr_a = varoftype(lltype.Ptr(GcA)) v_res = llops.genop("getfield", [ptr_a, model.Constant('b', lltype.Void)], resulttype=lltype.Ptr(NonGcB)) llops.genop("direct_call", [model.Constant(None, lltype.Void), v_res], resulttype=lltype.Void) block = model.Block([ptr_a]) block.operations.extend(llops) block.closeblock(model.Link([], None)) link = split_block_with_keepalive(block, 1) assert 'keepalive' in [op.opname for op in link.target.operations]
def test_nclc_ignore_functype(): # +--- inputargs: pointer_to_gc # | v0 <- op_getfield pointer_to_gc 'c' # +--- exitargs: v0 (i.e. a pointer to function) # pointers to functions are 'not gc' but functions are also # immortal so you don't need to muck around inserting keepalives # so *they* don't die! llops = LowLevelOpList() ptr_a = varoftype(lltype.Ptr(GcA)) v_res = llops.genop("getfield", [ptr_a, model.Constant('c', lltype.Void)], resulttype=GcA.c) block = model.Block([ptr_a]) block.operations.extend(llops) block.closeblock(model.Link([v_res], None)) assert not needs_conservative_livevar_calculation(block)
def add_case(block, exitcase): block = _from_opaque(block) exitcase = _from_opaque(exitcase) assert isinstance(exitcase, flowmodel.Constant) assert isinstance(block.exitswitch, flowmodel.Variable) case_link = flowmodel.Link([], None) exitvalue = exitcase.value if isinstance(lltype.typeOf(exitvalue), lltype.Ptr): # XXX hack! exitvalue = lltype.cast_ptr_to_int(exitvalue) case_link.exitcase = exitvalue case_link.llexitcase = exitvalue if block.exits and block.exits[-1].exitcase == 'default': exits = block.exits[:-1] + (case_link, ) + block.exits[-1:] else: exits = block.exits + (case_link, ) block.recloseblock(*exits) return _to_opaque(case_link)
def closeblock1(block): block = _from_opaque(block) link = flowmodel.Link([], None) block.closeblock(link) return _to_opaque(link)