Mercurial > projects > ldc
changeset 532:0beebf923322
merge
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Thu, 21 Aug 2008 15:35:39 +0200 |
parents | f775ea9d09d3 (current diff) d30c40f1128d (diff) |
children | 2fe2d4518618 7e2867ed70d9 |
files | |
diffstat | 6 files changed, 99 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/dmd/mars.c Thu Aug 21 15:35:24 2008 +0200 +++ b/dmd/mars.c Thu Aug 21 15:35:39 2008 +0200 @@ -265,7 +265,7 @@ global.params.argv0 = argv[0]; #endif global.params.link = 1; - global.params.useAssert = 0; + global.params.useAssert = 1; global.params.useInvariants = 1; global.params.useIn = 1; global.params.useOut = 1;
--- a/gen/runtime.cpp Thu Aug 21 15:35:24 2008 +0200 +++ b/gen/runtime.cpp Thu Aug 21 15:35:39 2008 +0200 @@ -883,4 +883,17 @@ const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } + + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////// + + // void _d_invariant(Object o) + { + std::string fname("_d_invariant"); + std::vector<const LLType*> types; + types.push_back(objectTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } }
--- a/gen/tocall.cpp Thu Aug 21 15:35:24 2008 +0200 +++ b/gen/tocall.cpp Thu Aug 21 15:35:39 2008 +0200 @@ -113,8 +113,11 @@ int begin = tf->parameters->dim; Logger::println("num non vararg params = %d", begin); + // get n args in arguments list + size_t n_arguments = arguments ? arguments->dim : 0; + // build struct with argument types (non variadic args) - for (int i=begin; i<arguments->dim; i++) + for (int i=begin; i<n_arguments; i++) { Expression* argexp = (Expression*)arguments->data[i]; vtypes.push_back(DtoType(argexp->type)); @@ -127,7 +130,7 @@ LLValue* mem = DtoAlloca(vtype,"_argptr_storage"); // store arguments in the struct - for (int i=begin,k=0; i<arguments->dim; i++,k++) + for (int i=begin,k=0; i<n_arguments; i++,k++) { Expression* argexp = (Expression*)arguments->data[i]; if (global.params.llvmAnnotate) @@ -147,7 +150,7 @@ Logger::cout() << "_arguments storage: " << *typeinfomem << '\n'; std::vector<LLConstant*> vtypeinfos; - for (int i=begin,k=0; i<arguments->dim; i++,k++) + for (int i=begin,k=0; i<n_arguments; i++,k++) { Expression* argexp = (Expression*)arguments->data[i]; vtypeinfos.push_back(DtoTypeInfoOf(argexp->type)); @@ -219,6 +222,9 @@ const LLFunctionType* callableTy = DtoExtractFunctionType(callable->getType()); assert(callableTy); + // get n arguments + size_t n_arguments = arguments ? arguments->dim : 0; + // get llvm argument iterator, for types LLFunctionType::param_iterator argbegin = callableTy->param_begin(); LLFunctionType::param_iterator argiter = argbegin; @@ -280,8 +286,7 @@ // variadic instrinsics need some custom casts if (va_intrinsic) { - size_t n = arguments->dim; - for (int i=0; i<n; i++) + for (int i=0; i<n_arguments; i++) { Expression* exp = (Expression*)arguments->data[i]; DValue* expelem = exp->toElem(gIR); @@ -302,7 +307,7 @@ else { Logger::println("doing normal arguments"); - for (int i=0; i<arguments->dim; i++) { + for (int i=0; i<n_arguments; i++) { int j = argiter-argbegin; Argument* fnarg = Argument::getNth(tf->parameters, i); DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
--- a/gen/toir.cpp Thu Aug 21 15:35:24 2008 +0200 +++ b/gen/toir.cpp Thu Aug 21 15:35:39 2008 +0200 @@ -1569,30 +1569,56 @@ Logger::print("AssertExp::toElem: %s\n", toChars()); LOG_SCOPE; + if(!global.params.useAssert) + return NULL; + // condition DValue* cond = e1->toElem(p); - - // create basic blocks - llvm::BasicBlock* oldend = p->scopeend(); - llvm::BasicBlock* assertbb = llvm::BasicBlock::Create("assert", p->topfunc(), oldend); - llvm::BasicBlock* endbb = llvm::BasicBlock::Create("noassert", p->topfunc(), oldend); - - // test condition - LLValue* condval = DtoBoolean(loc, cond); - - // branch - llvm::BranchInst::Create(endbb, assertbb, condval, p->scopebb()); - - // call assert runtime functions - p->scope() = IRScope(assertbb,endbb); - DtoAssert(&loc, msg ? msg->toElem(p) : NULL); - - // assert inserts unreachable terminator -// if (!gIR->scopereturned()) -// llvm::BranchInst::Create(endbb, p->scopebb()); - - // rewrite the scope - p->scope() = IRScope(endbb,oldend); + Type* condty = e1->type->toBasetype(); + + InvariantDeclaration* invdecl; + + // class invariants + if( + global.params.useInvariants && + condty->ty == Tclass && + !((TypeClass*)condty)->sym->isInterfaceDeclaration()) + { + Logger::print("calling class invariant"); + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_invariant"); + LLValue* arg = DtoBitCast(cond->getRVal(), fn->getFunctionType()->getParamType(0)); + gIR->CreateCallOrInvoke(fn, arg); + } + // struct invariants + else if( + global.params.useInvariants && + condty->ty == Tpointer && condty->next->ty == Tstruct && + (invdecl = ((TypeStruct*)condty->next)->sym->inv) != NULL) + { + Logger::print("calling struct invariant"); + DFuncValue invfunc(invdecl, invdecl->ir.irFunc->func, cond->getRVal()); + DtoCallFunction(loc, NULL, &invfunc, NULL); + } + else + { + // create basic blocks + llvm::BasicBlock* oldend = p->scopeend(); + llvm::BasicBlock* assertbb = llvm::BasicBlock::Create("assert", p->topfunc(), oldend); + llvm::BasicBlock* endbb = llvm::BasicBlock::Create("noassert", p->topfunc(), oldend); + + // test condition + LLValue* condval = DtoBoolean(loc, cond); + + // branch + llvm::BranchInst::Create(endbb, assertbb, condval, p->scopebb()); + + // call assert runtime functions + p->scope() = IRScope(assertbb,endbb); + DtoAssert(&loc, msg ? msg->toElem(p) : NULL); + + // rewrite the scope + p->scope() = IRScope(endbb,oldend); + } // no meaningful return value return NULL;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtime/internal/invariant.d Thu Aug 21 15:35:39 2008 +0200 @@ -0,0 +1,25 @@ + +/* + * Placed into the Public Domain + * written by Walter Bright + * www.digitalmars.com + */ + +extern(C) void _d_invariant(Object o) +{ ClassInfo c; + + //printf("__d_invariant(%p)\n", o); + + // BUG: needs to be filename/line of caller, not library routine + assert(o !is null); // just do null check, not invariant check + + c = o.classinfo; + do + { + if (c.classInvariant) + { + (*c.classInvariant)(o); + } + c = c.base; + } while (c); +}