comparison gen/nested.cpp @ 1213:9430d4959ab4

Fix a bug in nested context code that occured when calling a function nested in the outermost scope with a context frame from a function using a more nested context frame.
author Frits van Bommel <fvbommel wxs.nl>
date Mon, 13 Apr 2009 12:19:18 +0200
parents df2227fdc860
children 033f18ec1371
comparison
equal deleted inserted replaced
1212:df2227fdc860 1213:9430d4959ab4
48 /*//////////////////////////////////////////////////////////////////////////////////////// 48 /*////////////////////////////////////////////////////////////////////////////////////////
49 // NESTED VARIABLE HELPERS 49 // NESTED VARIABLE HELPERS
50 ////////////////////////////////////////////////////////////////////////////////////////*/ 50 ////////////////////////////////////////////////////////////////////////////////////////*/
51 51
52 static FuncDeclaration* getParentFunc(Dsymbol* sym) { 52 static FuncDeclaration* getParentFunc(Dsymbol* sym) {
53 if (!sym)
54 return NULL;
53 Dsymbol* parent = sym->parent; 55 Dsymbol* parent = sym->parent;
54 assert(parent); 56 assert(parent);
55 while (parent && !parent->isFuncDeclaration()) 57 while (parent && !parent->isFuncDeclaration())
56 parent = parent->parent; 58 parent = parent->parent;
57 59
176 { 178 {
177 Logger::println("DtoNestedContext for %s", sym->toPrettyChars()); 179 Logger::println("DtoNestedContext for %s", sym->toPrettyChars());
178 LOG_SCOPE; 180 LOG_SCOPE;
179 181
180 IrFunction* irfunc = gIR->func(); 182 IrFunction* irfunc = gIR->func();
181 183 bool fromParent = true;
184
185 LLValue* val;
182 // if this func has its own vars that are accessed by nested funcs 186 // if this func has its own vars that are accessed by nested funcs
183 // use its own context 187 // use its own context
184 if (irfunc->nestedVar) 188 if (irfunc->nestedVar) {
185 return irfunc->nestedVar; 189 val = irfunc->nestedVar;
190 fromParent = false;
191 }
186 // otherwise, it may have gotten a context from the caller 192 // otherwise, it may have gotten a context from the caller
187 else if (irfunc->nestArg) 193 else if (irfunc->nestArg)
188 return irfunc->nestArg; 194 val = irfunc->nestArg;
189 // or just have a this argument 195 // or just have a this argument
190 else if (irfunc->thisArg) 196 else if (irfunc->thisArg)
191 { 197 {
192 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration(); 198 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
193 if (!cd || !cd->vthis) 199 if (!cd || !cd->vthis)
194 return getNullPtr(getVoidPtrType()); 200 return getNullPtr(getVoidPtrType());
195 LLValue* val = DtoLoad(irfunc->thisArg); 201 val = DtoLoad(irfunc->thisArg);
196 return DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis")); 202 val = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
197 } 203 }
198 else 204 else
199 { 205 {
200 return getNullPtr(getVoidPtrType()); 206 return getNullPtr(getVoidPtrType());
201 } 207 }
208 if (nestedCtx == NCHybrid) {
209 // If sym is a nested function, and its parent elided the context list but the
210 // context we got didn't, we need to index to the first frame.
211 if (FuncDeclaration* fd = getParentFunc(sym->isFuncDeclaration())) {
212 Logger::println("For nested function, parent is %s", fd->toChars());
213 FuncDeclaration* ctxfd = irfunc->decl;
214 Logger::println("Current function is %s", ctxfd->toChars());
215 if (fromParent) {
216 ctxfd = getParentFunc(ctxfd);
217 assert(ctxfd && "Context from outer function, but no outer function?");
218 }
219 Logger::println("Context is from %s", ctxfd->toChars());
220 if (fd->ir.irFunc->elidedCtxList && !ctxfd->ir.irFunc->elidedCtxList) {
221 Logger::println("Adjusting to remove context frame list", ctxfd->toChars());
222 val = DtoBitCast(val, LLPointerType::getUnqual(ctxfd->ir.irFunc->framesType));
223 val = DtoGEPi(val, 0, 0);
224 val = DtoAlignedLoad(val, (std::string(".frame.") + fd->toChars()).c_str());
225 }
226 }
227 }
228 Logger::cout() << "result = " << *val << '\n';
229 Logger::cout() << "of type " << *val->getType() << '\n';
230 return val;
202 } 231 }
203 232
204 void DtoCreateNestedContext(FuncDeclaration* fd) { 233 void DtoCreateNestedContext(FuncDeclaration* fd) {
205 Logger::println("DtoCreateNestedContext for %s", fd->toChars()); 234 Logger::println("DtoCreateNestedContext for %s", fd->toChars());
206 LOG_SCOPE 235 LOG_SCOPE