Commit 85be3ddd authored by Kevin Modzelewski's avatar Kevin Modzelewski

More fixes. Need to support nullable in more places

parent a9b41d55
...@@ -1409,8 +1409,10 @@ public: ...@@ -1409,8 +1409,10 @@ public:
// Will this ever hit the cache? // Will this ever hit the cache?
boxed = embedRelocatablePtr(emitter.getFloatConstant(llvm_val->getValueAPF().convertToDouble()), boxed = embedRelocatablePtr(emitter.getFloatConstant(llvm_val->getValueAPF().convertToDouble()),
g.llvm_value_type_ptr); g.llvm_value_type_ptr);
emitter.setType(boxed, RefType::BORROWED);
} else { } else {
boxed = emitter.getBuilder()->CreateCall(g.funcs.boxFloat, unboxed); boxed = emitter.getBuilder()->CreateCall(g.funcs.boxFloat, unboxed);
emitter.setType(boxed, RefType::OWNED);
} }
return new ConcreteCompilerVariable(other_type, boxed); return new ConcreteCompilerVariable(other_type, boxed);
} }
......
...@@ -195,7 +195,8 @@ class IRGenState; ...@@ -195,7 +195,8 @@ class IRGenState;
class RefcountTracker { class RefcountTracker {
private: private:
struct RefcountState { struct RefcountState {
RefType reftype; RefType reftype = RefType::UNKNOWN;
bool nullable = false;
//llvm::SmallVector<llvm::Instruction*, 2> ref_consumers; //llvm::SmallVector<llvm::Instruction*, 2> ref_consumers;
}; };
...@@ -204,6 +205,7 @@ private: ...@@ -204,6 +205,7 @@ private:
public: public:
llvm::Value* setType(llvm::Value* v, RefType reftype); llvm::Value* setType(llvm::Value* v, RefType reftype);
llvm::Value* setNullable(llvm::Value* v, bool nullable = true);
void refConsumed(llvm::Value* v, llvm::Instruction*); void refConsumed(llvm::Value* v, llvm::Instruction*);
static void addRefcounts(IRGenState* state); static void addRefcounts(IRGenState* state);
}; };
......
...@@ -526,6 +526,11 @@ public: ...@@ -526,6 +526,11 @@ public:
return v; return v;
} }
llvm::Value* setNullable(llvm::Value* v, bool nullable) {
irstate->getRefcounts()->setNullable(v, nullable);
return v;
}
ConcreteCompilerVariable* getNone() { ConcreteCompilerVariable* getNone() {
llvm::Constant* none = embedRelocatablePtr(None, g.llvm_value_type_ptr, "cNone"); llvm::Constant* none = embedRelocatablePtr(None, g.llvm_value_type_ptr, "cNone");
setType(none, RefType::BORROWED); setType(none, RefType::BORROWED);
...@@ -740,9 +745,11 @@ private: ...@@ -740,9 +745,11 @@ private:
// For example, the cfg code will conservatively assume that any name-access can // For example, the cfg code will conservatively assume that any name-access can
// trigger an exception, but the irgenerator will know that definitely-defined // trigger an exception, but the irgenerator will know that definitely-defined
// local symbols will not throw. // local symbols will not throw.
emitter.getBuilder()->CreateUnreachable();
exc_type = undefVariable(); exc_type = undefVariable();
exc_value = undefVariable(); exc_value = undefVariable();
exc_tb = undefVariable(); exc_tb = undefVariable();
endBlock(DEAD);
} }
// clear this out to signal that we consumed them: // clear this out to signal that we consumed them:
...@@ -2668,23 +2675,31 @@ public: ...@@ -2668,23 +2675,31 @@ public:
} }
if (param_names.kwarg.size()) { if (param_names.kwarg.size()) {
llvm::Value* passed_dict = python_parameters[i];
emitter.setNullable(passed_dict, true);
llvm::BasicBlock* starting_block = emitter.currentBasicBlock(); llvm::BasicBlock* starting_block = emitter.currentBasicBlock();
llvm::BasicBlock* isnull_bb = emitter.createBasicBlock("isnull"); llvm::BasicBlock* isnull_bb = emitter.createBasicBlock("isnull");
llvm::BasicBlock* continue_bb = emitter.createBasicBlock("kwargs_join"); llvm::BasicBlock* continue_bb = emitter.createBasicBlock("kwargs_join");
llvm::Value* kwargs_null llvm::Value* kwargs_null
= emitter.getBuilder()->CreateICmpEQ(python_parameters[i], getNullPtr(g.llvm_value_type_ptr)); = emitter.getBuilder()->CreateICmpEQ(passed_dict, getNullPtr(g.llvm_value_type_ptr));
llvm::BranchInst* null_check = emitter.getBuilder()->CreateCondBr(kwargs_null, isnull_bb, continue_bb); llvm::BranchInst* null_check = emitter.getBuilder()->CreateCondBr(kwargs_null, isnull_bb, continue_bb);
emitter.setCurrentBasicBlock(isnull_bb); emitter.setCurrentBasicBlock(isnull_bb);
llvm::Value* created_dict = emitter.getBuilder()->CreateCall(g.funcs.createDict); llvm::Value* created_dict = emitter.getBuilder()->CreateCall(g.funcs.createDict);
emitter.getBuilder()->CreateBr(continue_bb); emitter.setType(created_dict, RefType::OWNED);
auto isnull_terminator = emitter.getBuilder()->CreateBr(continue_bb);
emitter.setCurrentBasicBlock(continue_bb); emitter.setCurrentBasicBlock(continue_bb);
llvm::PHINode* phi = emitter.getBuilder()->CreatePHI(g.llvm_value_type_ptr, 2); llvm::PHINode* phi = emitter.getBuilder()->CreatePHI(g.llvm_value_type_ptr, 2);
phi->addIncoming(python_parameters[i], starting_block); phi->addIncoming(passed_dict, starting_block);
phi->addIncoming(created_dict, isnull_bb); phi->addIncoming(created_dict, isnull_bb);
emitter.setType(phi, RefType::OWNED);
emitter.refConsumed(passed_dict, null_check);
emitter.refConsumed(created_dict, isnull_terminator);
loadArgument(internString(param_names.kwarg), arg_types[i], phi, UnwindInfo::cantUnwind()); loadArgument(internString(param_names.kwarg), arg_types[i], phi, UnwindInfo::cantUnwind());
i++; i++;
} }
......
...@@ -52,6 +52,16 @@ llvm::Value* RefcountTracker::setType(llvm::Value* v, RefType reftype) { ...@@ -52,6 +52,16 @@ llvm::Value* RefcountTracker::setType(llvm::Value* v, RefType reftype) {
return v; return v;
} }
llvm::Value* RefcountTracker::setNullable(llvm::Value* v, bool nullable) {
assert(!llvm::isa<llvm::UndefValue>(v));
auto& var = this->vars[v];
assert(var.nullable == nullable || var.nullable == false);
var.nullable = nullable;
return v;
}
void RefcountTracker::refConsumed(llvm::Value* v, llvm::Instruction* inst) { void RefcountTracker::refConsumed(llvm::Value* v, llvm::Instruction* inst) {
assert(this->vars[v].reftype != RefType::UNKNOWN); assert(this->vars[v].reftype != RefType::UNKNOWN);
...@@ -63,21 +73,23 @@ llvm::Instruction* findIncrefPt(llvm::BasicBlock* BB) { ...@@ -63,21 +73,23 @@ llvm::Instruction* findIncrefPt(llvm::BasicBlock* BB) {
ASSERT(pred_begin(BB) == pred_end(BB) || pred_end(BB) == ++pred_begin(BB), ASSERT(pred_begin(BB) == pred_end(BB) || pred_end(BB) == ++pred_begin(BB),
"We shouldn't be inserting anything at the beginning of blocks with multiple predecessors"); "We shouldn't be inserting anything at the beginning of blocks with multiple predecessors");
llvm::Instruction* incref_pt;// = BB->getFirstInsertionPt();
if (llvm::isa<llvm::LandingPadInst>(*BB->begin())) { if (llvm::isa<llvm::LandingPadInst>(*BB->begin())) {
// Don't split up the landingpad+extract+cxa_begin_catch // Don't split up the landingpad+extract+cxa_begin_catch
auto it = BB->begin(); auto it = BB->begin();
++it; ++it;
++it; ++it;
++it; ++it;
incref_pt = &*it; return &*it;
} else { } else {
incref_pt = BB->getFirstInsertionPt(); for (llvm::Instruction& I : *BB) {
if (!llvm::isa<llvm::PHINode>(I) && !llvm::isa<llvm::AllocaInst>(I))
return &I;
}
abort();
} }
return incref_pt;
} }
void addIncrefs(llvm::Value* v, int num_refs, llvm::Instruction* incref_pt) { void addIncrefs(llvm::Value* v, bool nullable, int num_refs, llvm::Instruction* incref_pt) {
if (num_refs > 1) { if (num_refs > 1) {
// Not bad but I don't think this should happen: // Not bad but I don't think this should happen:
//printf("Whoa more than one incref??\n"); //printf("Whoa more than one incref??\n");
...@@ -85,29 +97,55 @@ void addIncrefs(llvm::Value* v, int num_refs, llvm::Instruction* incref_pt) { ...@@ -85,29 +97,55 @@ void addIncrefs(llvm::Value* v, int num_refs, llvm::Instruction* incref_pt) {
} }
assert(num_refs > 0); assert(num_refs > 0);
llvm::BasicBlock* cur_block;
llvm::BasicBlock* continue_block;
llvm::BasicBlock* incref_block;
llvm::IRBuilder<true> builder(incref_pt);
if (nullable) {
cur_block = incref_pt->getParent();
continue_block = cur_block->splitBasicBlock(incref_pt);
incref_block
= llvm::BasicBlock::Create(g.context, "incref", incref_pt->getParent()->getParent(), continue_block);
assert(llvm::isa<llvm::BranchInst>(cur_block->getTerminator()));
cur_block->getTerminator()->eraseFromParent();
builder.SetInsertPoint(cur_block);
auto isnull = builder.CreateICmpEQ(v, getNullPtr(g.llvm_value_type_ptr));
builder.CreateCondBr(isnull, continue_block, incref_block);
builder.SetInsertPoint(incref_block);
}
#ifdef Py_REF_DEBUG #ifdef Py_REF_DEBUG
auto reftotal_gv = g.cur_module->getOrInsertGlobal("_Py_RefTotal", g.i64); auto reftotal_gv = g.cur_module->getOrInsertGlobal("_Py_RefTotal", g.i64);
auto reftotal = new llvm::LoadInst(reftotal_gv, "", incref_pt); auto reftotal = builder.CreateLoad(reftotal_gv);
auto new_reftotal = llvm::BinaryOperator::Create(llvm::BinaryOperator::BinaryOps::Add, reftotal, auto new_reftotal = builder.CreateAdd(reftotal, getConstantInt(num_refs, g.i64));
getConstantInt(num_refs, g.i64), "", incref_pt); builder.CreateStore(new_reftotal, reftotal_gv);
new llvm::StoreInst(new_reftotal, reftotal_gv, incref_pt);
#endif #endif
llvm::ArrayRef<llvm::Value*> idxs({ getConstantInt(0, g.i32), getConstantInt(0, g.i32) }); llvm::ArrayRef<llvm::Value*> idxs({ getConstantInt(0, g.i32), getConstantInt(0, g.i32) });
auto refcount_ptr = llvm::GetElementPtrInst::CreateInBounds(v, idxs, "", incref_pt); auto refcount_ptr = builder.CreateConstInBoundsGEP2_32(v, 0, 0);
auto refcount = new llvm::LoadInst(refcount_ptr, "", incref_pt); auto refcount = builder.CreateLoad(refcount_ptr);
auto new_refcount = llvm::BinaryOperator::Create(llvm::BinaryOperator::BinaryOps::Add, refcount, auto new_refcount = builder.CreateAdd(refcount, getConstantInt(num_refs, g.i64));
getConstantInt(num_refs, g.i64), "", incref_pt); builder.CreateStore(new_refcount, refcount_ptr);
new llvm::StoreInst(new_refcount, refcount_ptr, incref_pt);
if (nullable)
builder.CreateBr(continue_block);
} }
void addDecrefs(llvm::Value* v, int num_refs, llvm::Instruction* decref_pt) { void addDecrefs(llvm::Value* v, bool nullable, int num_refs, llvm::Instruction* decref_pt) {
if (num_refs > 1) { if (num_refs > 1) {
// Not bad but I don't think this should happen: // Not bad but I don't think this should happen:
printf("Whoa more than one decref??\n"); printf("Whoa more than one decref??\n");
raise(SIGTRAP); raise(SIGTRAP);
} }
assert(!nullable);
assert(num_refs > 0); assert(num_refs > 0);
llvm::IRBuilder<true> builder(decref_pt); llvm::IRBuilder<true> builder(decref_pt);
#ifdef Py_REF_DEBUG #ifdef Py_REF_DEBUG
...@@ -392,6 +430,7 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -392,6 +430,7 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
struct RefOp { struct RefOp {
llvm::Value* operand; llvm::Value* operand;
bool nullable;
int num_refs; int num_refs;
llvm::Instruction* insertion_pt; llvm::Instruction* insertion_pt;
}; };
...@@ -473,10 +512,10 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -473,10 +512,10 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
this_refs = it->second; this_refs = it->second;
} }
if (this_refs > min_refs) { if (this_refs > min_refs) {
state.increfs.push_back(RefOp({v, this_refs - min_refs, findIncrefPt(SBB)})); state.increfs.push_back(RefOp({v, refstate.nullable, this_refs - min_refs, findIncrefPt(SBB)}));
} else if (this_refs < min_refs) { } else if (this_refs < min_refs) {
assert(refstate.reftype == RefType::OWNED); assert(refstate.reftype == RefType::OWNED);
state.decrefs.push_back(RefOp({v, min_refs - this_refs, findIncrefPt(SBB)})); state.decrefs.push_back(RefOp({v, refstate.nullable, min_refs - this_refs, findIncrefPt(SBB)}));
} }
} }
...@@ -530,15 +569,15 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -530,15 +569,15 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
llvm::outs() << "Last use of " << *op << " is at " << I << "; adding a decref after\n"; llvm::outs() << "Last use of " << *op << " is at " << I << "; adding a decref after\n";
if (llvm::InvokeInst* invoke = llvm::dyn_cast<llvm::InvokeInst>(&I)) { if (llvm::InvokeInst* invoke = llvm::dyn_cast<llvm::InvokeInst>(&I)) {
state.decrefs.push_back(RefOp({op, 1, findIncrefPt(invoke->getNormalDest())})); state.decrefs.push_back(RefOp({op, rt->vars[op].nullable, 1, findIncrefPt(invoke->getNormalDest())}));
state.decrefs.push_back(RefOp({op, 1, findIncrefPt(invoke->getUnwindDest())})); state.decrefs.push_back(RefOp({op, rt->vars[op].nullable, 1, findIncrefPt(invoke->getUnwindDest())}));
} else { } else {
assert(&I != I.getParent()->getTerminator()); assert(&I != I.getParent()->getTerminator());
auto next = I.getNextNode(); auto next = I.getNextNode();
//while (llvm::isa<llvm::PHINode>(next)) //while (llvm::isa<llvm::PHINode>(next))
//next = next->getNextNode(); //next = next->getNextNode();
ASSERT(!llvm::isa<llvm::UnreachableInst>(next), "Can't add decrefs after this function..."); ASSERT(!llvm::isa<llvm::UnreachableInst>(next), "Can't add decrefs after this function...");
state.decrefs.push_back(RefOp({op, 1, next})); state.decrefs.push_back(RefOp({op, rt->vars[op].nullable, 1, next}));
} }
state.ending_refs[op] = 1; state.ending_refs[op] = 1;
} }
...@@ -567,9 +606,11 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -567,9 +606,11 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
if (state.ending_refs[inst] < starting_refs) { if (state.ending_refs[inst] < starting_refs) {
assert(p.second.reftype == RefType::OWNED); assert(p.second.reftype == RefType::OWNED);
state.decrefs.push_back(RefOp({inst, starting_refs - state.ending_refs[inst], insertion_pt})); state.decrefs.push_back(
RefOp({ inst, p.second.nullable, starting_refs - state.ending_refs[inst], insertion_pt }));
} else { } else {
state.increfs.push_back(RefOp({inst, state.ending_refs[inst] - starting_refs, insertion_pt})); state.increfs.push_back(
RefOp({ inst, p.second.nullable, state.ending_refs[inst] - starting_refs, insertion_pt }));
} }
} }
state.ending_refs.erase(inst); state.ending_refs.erase(inst);
...@@ -601,7 +642,7 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -601,7 +642,7 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
#endif #endif
assert(rt->vars[p.first].reftype == RefType::BORROWED); assert(rt->vars[p.first].reftype == RefType::BORROWED);
state.increfs.push_back(RefOp({p.first, p.second, findIncrefPt(&BB)})); state.increfs.push_back(RefOp({p.first, rt->vars[p.first].nullable, p.second, findIncrefPt(&BB)}));
} }
state.ending_refs.clear(); state.ending_refs.clear();
} }
...@@ -622,9 +663,9 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) { ...@@ -622,9 +663,9 @@ void RefcountTracker::addRefcounts(IRGenState* irstate) {
for (auto&& p : states) { for (auto&& p : states) {
auto&& state = p.second; auto&& state = p.second;
for (auto& op : state.increfs) for (auto& op : state.increfs)
addIncrefs(op.operand, op.num_refs, op.insertion_pt); addIncrefs(op.operand, op.nullable, op.num_refs, op.insertion_pt);
for (auto& op : state.decrefs) for (auto& op : state.decrefs)
addDecrefs(op.operand, op.num_refs, op.insertion_pt); addDecrefs(op.operand, op.nullable, op.num_refs, op.insertion_pt);
} }
if (VERBOSITY()) { if (VERBOSITY()) {
......
...@@ -3782,21 +3782,24 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3782,21 +3782,24 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
auto propagate_args = [&]() { auto propagate_args = [&]() {
if (num_output_args >= 1) if (num_output_args >= 1)
Py_INCREF(oarg1); Py_XINCREF(oarg1);
if (num_output_args >= 2) if (num_output_args >= 2)
Py_INCREF(oarg2); Py_XINCREF(oarg2);
if (num_output_args >= 3) if (num_output_args >= 3)
Py_INCREF(oarg3); Py_XINCREF(oarg3);
if (num_output_args >= 3) { if (num_output_args >= 3) {
memcpy(oargs, args, sizeof(Box*) * (num_output_args - 3)); memcpy(oargs, args, sizeof(Box*) * (num_output_args - 3));
for (int i = 0; i < num_output_args - 3; i++) { for (int i = 0; i < num_output_args - 3; i++) {
Py_INCREF(oargs[i]); Py_XINCREF(oargs[i]);
} }
} }
if (rewrite_args) { if (rewrite_args) {
if (num_output_args >= 3) { if (num_output_args >= 3) {
for (int i = 0; i < num_output_args - 3; i++) { for (int i = 0; i < num_output_args - 3; i++) {
rewrite_args->args->getAttr(i * sizeof(Box*))->setType(RefType::BORROWED)->refConsumed(); rewrite_args->args->getAttr(i * sizeof(Box*))
->setType(RefType::BORROWED)
->setNullable(true)
->refConsumed();
} }
} }
} }
...@@ -3918,7 +3921,9 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3918,7 +3921,9 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
getArg(i, oarg1, oarg2, oarg3, oargs) = incref(getArg(i, arg1, arg2, arg3, args)); getArg(i, oarg1, oarg2, oarg3, oargs) = incref(getArg(i, arg1, arg2, arg3, args));
} }
if (rewrite_args) { if (rewrite_args) {
assert(positional_to_positional < 3 && "figure this out"); for (int i = 3; i < positional_to_positional; i++) {
rewrite_args->args->getAttr((i - 3) * sizeof(Box*))->setType(RefType::BORROWED)->refConsumed();
}
} }
int varargs_to_positional = std::min((int)varargs_size, paramspec.num_args - positional_to_positional); int varargs_to_positional = std::min((int)varargs_size, paramspec.num_args - positional_to_positional);
...@@ -3939,7 +3944,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3939,7 +3944,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
RewriterVar::SmallVector unused_positional_rvars; RewriterVar::SmallVector unused_positional_rvars;
for (int i = positional_to_positional; i < argspec.num_args; i++) { for (int i = positional_to_positional; i < argspec.num_args; i++) {
assert(!rewrite_args && "check refcounting");
unused_positional.push_back(getArg(i, arg1, arg2, arg3, args)); unused_positional.push_back(getArg(i, arg1, arg2, arg3, args));
if (rewrite_args) { if (rewrite_args) {
if (i == 0) if (i == 0)
...@@ -3949,7 +3953,8 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3949,7 +3953,8 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
if (i == 2) if (i == 2)
unused_positional_rvars.push_back(rewrite_args->arg3); unused_positional_rvars.push_back(rewrite_args->arg3);
if (i >= 3) if (i >= 3)
unused_positional_rvars.push_back(rewrite_args->args->getAttr((i - 3) * sizeof(Box*))); unused_positional_rvars.push_back(
rewrite_args->args->getAttr((i - 3) * sizeof(Box*))->setType(RefType::BORROWED));
} }
} }
for (int i = varargs_to_positional; i < varargs_size; i++) { for (int i = varargs_to_positional; i < varargs_size; i++) {
...@@ -3960,7 +3965,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3960,7 +3965,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
if (paramspec.takes_varargs) { if (paramspec.takes_varargs) {
int varargs_idx = paramspec.num_args; int varargs_idx = paramspec.num_args;
if (rewrite_args) { if (rewrite_args) {
assert(0 && "check refcounting");
assert(!varargs_size); assert(!varargs_size);
assert(!argspec.has_starargs); assert(!argspec.has_starargs);
...@@ -3968,8 +3972,10 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3968,8 +3972,10 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
int varargs_size = unused_positional_rvars.size(); int varargs_size = unused_positional_rvars.size();
if (varargs_size == 0) { if (varargs_size == 0) {
varargs_val = rewrite_args->rewriter->loadConst( varargs_val
(intptr_t)EmptyTuple, varargs_idx < 3 ? Location::forArg(varargs_idx) : Location::any()); = rewrite_args->rewriter->loadConst((intptr_t)EmptyTuple,
varargs_idx < 3 ? Location::forArg(varargs_idx)
: Location::any())->setType(RefType::BORROWED);
} else { } else {
assert(varargs_size <= 6); assert(varargs_size <= 6);
void* create_ptrs[] = { void* create_ptrs[] = {
...@@ -3981,7 +3987,8 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3981,7 +3987,8 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
(void*)BoxedTuple::create5, // (void*)BoxedTuple::create5, //
(void*)BoxedTuple::create6, // (void*)BoxedTuple::create6, //
}; };
varargs_val = rewrite_args->rewriter->call(false, create_ptrs[varargs_size], unused_positional_rvars); varargs_val = rewrite_args->rewriter->call(false, create_ptrs[varargs_size], unused_positional_rvars)
->setType(RefType::OWNED);
} }
if (varargs_val) { if (varargs_val) {
...@@ -3991,8 +3998,10 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -3991,8 +3998,10 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
rewrite_args->arg2 = varargs_val; rewrite_args->arg2 = varargs_val;
if (varargs_idx == 2) if (varargs_idx == 2)
rewrite_args->arg3 = varargs_val; rewrite_args->arg3 = varargs_val;
if (varargs_idx >= 3) if (varargs_idx >= 3) {
rewrite_args->args->setAttr((varargs_idx - 3) * sizeof(Box*), varargs_val); rewrite_args->args->setAttr((varargs_idx - 3) * sizeof(Box*), varargs_val);
varargs_val->refConsumed();
}
} }
} }
...@@ -4025,7 +4034,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa ...@@ -4025,7 +4034,6 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
// If you need to access the dict, you should call get_okwargs() // If you need to access the dict, you should call get_okwargs()
BoxedDict** _okwargs = NULL; BoxedDict** _okwargs = NULL;
if (paramspec.takes_kwargs) { if (paramspec.takes_kwargs) {
assert(!rewrite_args && "check refcounting");
int kwargs_idx = paramspec.num_args + (paramspec.takes_varargs ? 1 : 0); int kwargs_idx = paramspec.num_args + (paramspec.takes_varargs ? 1 : 0);
if (rewrite_args) { if (rewrite_args) {
RewriterVar* r_kwargs = rewrite_args->rewriter->loadConst(0); RewriterVar* r_kwargs = rewrite_args->rewriter->loadConst(0);
...@@ -6714,7 +6722,6 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) { ...@@ -6714,7 +6722,6 @@ extern "C" Box* getGlobal(Box* globals, BoxedString* name) {
auto r_rtn = rewrite_args.getReturn(ReturnConvention::HAS_RETURN); auto r_rtn = rewrite_args.getReturn(ReturnConvention::HAS_RETURN);
rewriter->commitReturning(r_rtn); rewriter->commitReturning(r_rtn);
} else { } else {
assert(0 && "check refcounting");
rewrite_args.getReturn(); // just to make the asserts happy rewrite_args.getReturn(); // just to make the asserts happy
rewriter.reset(NULL); rewriter.reset(NULL);
} }
......
...@@ -1113,7 +1113,7 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo ...@@ -1113,7 +1113,7 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
class InitHelper { class InitHelper {
public: public:
static Box* call(Box* made, BoxedClass* cls, Box* args, Box* kwargs) noexcept(S == CAPI) { static Box* call(STOLEN(Box*) made, BoxedClass* cls, Box* args, Box* kwargs) noexcept(S == CAPI) {
if (!isSubclass(made->cls, cls)) if (!isSubclass(made->cls, cls))
return made; return made;
...@@ -1132,8 +1132,10 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo ...@@ -1132,8 +1132,10 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
assert(!arg3 || arg3->cls == dict_cls); assert(!arg3 || arg3->cls == dict_cls);
if (rewrite_args) { if (rewrite_args) {
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)InitHelper::call, r_made, r_ccls, rewrite_args->out_rtn
rewrite_args->arg2, rewrite_args->arg3); = rewrite_args->rewriter->call(true, (void*)InitHelper::call, r_made, r_ccls, rewrite_args->arg2,
rewrite_args->arg3)->setType(RefType::OWNED);
r_made->refConsumed();
rewrite_args->out_success = true; rewrite_args->out_success = true;
} }
return InitHelper::call(made, cls, arg2, arg3); return InitHelper::call(made, cls, arg2, arg3);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment