comparison gen/toir.cpp @ 719:7261ff0f95ff

Implemented first class delegates. closes #101
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Wed, 22 Oct 2008 21:50:08 +0200
parents 30b42a283c8e
children e177ae483f8e
comparison
equal deleted inserted replaced
718:72ee105be27b 719:7261ff0f95ff
108 return DtoNestedVariable(loc, type, vd); 108 return DtoNestedVariable(loc, type, vd);
109 } 109 }
110 // function parameter 110 // function parameter
111 else if (vd->isParameter()) { 111 else if (vd->isParameter()) {
112 Logger::println("function param"); 112 Logger::println("function param");
113 Logger::println("type: %s", vd->type->toChars());
113 FuncDeclaration* fd = vd->toParent2()->isFuncDeclaration(); 114 FuncDeclaration* fd = vd->toParent2()->isFuncDeclaration();
114 if (fd && fd != p->func()->decl) { 115 if (fd && fd != p->func()->decl) {
115 Logger::println("nested parameter"); 116 Logger::println("nested parameter");
116 return DtoNestedVariable(loc, type, vd); 117 return DtoNestedVariable(loc, type, vd);
118 }
119 else if (vd->storage_class & STClazy) {
120 Logger::println("lazy parameter");
121 assert(type->ty == Tdelegate);
122 return new DVarValue(type, vd->ir.getIrValue());
117 } 123 }
118 else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue())) { 124 else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue())) {
119 return new DVarValue(type, vd, vd->ir.getIrValue()); 125 return new DVarValue(type, vd, vd->ir.getIrValue());
120 } 126 }
121 else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue())) { 127 else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue())) {
1831 if(func->isStatic()) 1837 if(func->isStatic())
1832 error("can't take delegate of static function %s, it does not require a context ptr", func->toChars()); 1838 error("can't take delegate of static function %s, it does not require a context ptr", func->toChars());
1833 1839
1834 const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty); 1840 const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty);
1835 1841
1836 LLValue* lval = DtoAlloca(DtoType(type), "tmpdelegate"); 1842 assert(type->toBasetype()->ty == Tdelegate);
1843 const LLType* dgty = DtoType(type);
1837 1844
1838 DValue* u = e1->toElem(p); 1845 DValue* u = e1->toElem(p);
1839 LLValue* uval; 1846 LLValue* uval;
1840 if (DFuncValue* f = u->isFunc()) { 1847 if (DFuncValue* f = u->isFunc()) {
1841 assert(f->func); 1848 assert(f->func);
1857 } 1864 }
1858 1865
1859 if (Logger::enabled()) 1866 if (Logger::enabled())
1860 Logger::cout() << "context = " << *uval << '\n'; 1867 Logger::cout() << "context = " << *uval << '\n';
1861 1868
1862 LLValue* context = DtoGEPi(lval,0,0);
1863 LLValue* castcontext = DtoBitCast(uval, int8ptrty); 1869 LLValue* castcontext = DtoBitCast(uval, int8ptrty);
1864 DtoStore(castcontext, context);
1865
1866 LLValue* fptr = DtoGEPi(lval,0,1);
1867 1870
1868 Logger::println("func: '%s'", func->toPrettyChars()); 1871 Logger::println("func: '%s'", func->toPrettyChars());
1869 1872
1870 LLValue* castfptr; 1873 LLValue* castfptr;
1871 if (func->isVirtual()) 1874 if (func->isVirtual())
1878 { 1881 {
1879 DtoForceDeclareDsymbol(func); 1882 DtoForceDeclareDsymbol(func);
1880 castfptr = func->ir.irFunc->func; 1883 castfptr = func->ir.irFunc->func;
1881 } 1884 }
1882 1885
1883 castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0)); 1886 castfptr = DtoBitCast(castfptr, dgty->getContainedType(1));
1884 DtoStore(castfptr, fptr); 1887
1885 1888 return new DImValue(type, DtoAggrPair(castcontext, castfptr, ".dg"));
1886 return new DImValue(type, lval);
1887 } 1889 }
1888 1890
1889 ////////////////////////////////////////////////////////////////////////////////////////// 1891 //////////////////////////////////////////////////////////////////////////////////////////
1890 1892
1891 DValue* IdentityExp::toElem(IRState* p) 1893 DValue* IdentityExp::toElem(IRState* p)
2096 Logger::println("kind = %s\n", fd->kind()); 2098 Logger::println("kind = %s\n", fd->kind());
2097 2099
2098 DtoForceDefineDsymbol(fd); 2100 DtoForceDefineDsymbol(fd);
2099 assert(fd->ir.irFunc->func); 2101 assert(fd->ir.irFunc->func);
2100 2102
2101 LLValue *lval, *fptr;
2102 if(fd->tok == TOKdelegate) { 2103 if(fd->tok == TOKdelegate) {
2103 const LLType* dgty = DtoType(type); 2104 const LLType* dgty = DtoType(type);
2104 lval = DtoAlloca(dgty,"dgstorage"); 2105
2105
2106 LLValue* context = DtoGEPi(lval,0,0);
2107 LLValue* cval; 2106 LLValue* cval;
2108 IrFunction* irfn = p->func(); 2107 IrFunction* irfn = p->func();
2109 if (irfn->nestedVar) 2108 if (irfn->nestedVar)
2110 cval = irfn->nestedVar; 2109 cval = irfn->nestedVar;
2111 else if (irfn->nestArg) 2110 else if (irfn->nestArg)
2112 cval = irfn->nestArg; 2111 cval = irfn->nestArg;
2113 else 2112 else
2114 cval = getNullPtr(getVoidPtrType()); 2113 cval = getNullPtr(getVoidPtrType());
2115 cval = DtoBitCast(cval, context->getType()->getContainedType(0)); 2114 cval = DtoBitCast(cval, dgty->getContainedType(0));
2116 DtoStore(cval, context); 2115
2117 2116 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, dgty->getContainedType(1));
2118 fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); 2117
2119 2118 return new DImValue(type, DtoAggrPair(cval, castfptr, ".func"));
2120 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0));
2121 DtoStore(castfptr, fptr);
2122
2123 return new DVarValue(type, lval);
2124 2119
2125 } else if(fd->tok == TOKfunction) { 2120 } else if(fd->tok == TOKfunction) {
2126 return new DImValue(type, fd->ir.irFunc->func); 2121 return new DImValue(type, fd->ir.irFunc->func);
2127 } 2122 }
2128 2123