annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
1 #include "gen/nested.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
2
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
3 #include "gen/dvalue.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
4 #include "gen/irstate.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
5 #include "gen/llvmhelpers.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
6 #include "gen/logger.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
7 #include "gen/tollvm.h"
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
8
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
9 #include "llvm/Support/CommandLine.h"
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
10 namespace cl = llvm::cl;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
11
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
12 /// What the context pointer for a nested function looks like
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
13 enum NestedCtxType {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
14 /// Context is void*[] of pointers to variables.
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
15 /// Variables from higher levels are at the front.
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
16 NCArray,
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
17
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
18 /// Context is a struct containing variables belonging to the parent function.
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
19 /// If the parent function itself has a parent function, one of the members is
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
20 /// a pointer to its context. (linked-list style)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
21 // FIXME: implement
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
22 // TODO: Functions without any variables accessed by nested functions, but
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
23 // with a parent whose variables are accessed, can use the parent's
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
24 // context.
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
25 // NOTE: This is what DMD seems to do.
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
26 NCStruct,
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
27
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
28 /// Context is a list of pointers to structs. Each function with variables
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
29 /// accessed by nested functions puts them in a struct, and appends a
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
30 /// pointer to that struct to it's local copy of the list.
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
31 /// As an additional optimization, if the list has length one it's not
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
32 /// generated; the only element is used directly instead.
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
33 NCHybrid
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
34 };
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
35
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
36 static cl::opt<NestedCtxType> nestedCtx("nested-ctx",
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
37 cl::desc("How to construct a nested function's context:"),
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
38 cl::ZeroOrMore,
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
39 cl::values(
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
40 clEnumValN(NCArray, "array", "Array of pointers to variables (including multi-level)"),
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
41 //clEnumValN(NCStruct, "struct", "Struct of variables (with multi-level via linked list)"),
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
42 clEnumValN(NCHybrid, "hybrid", "List of pointers to structs of variables, one per level."),
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
43 clEnumValEnd),
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
44 cl::init(NCHybrid));
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
45
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
46
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
47 /****************************************************************************************/
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
48 /*////////////////////////////////////////////////////////////////////////////////////////
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
49 // NESTED VARIABLE HELPERS
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
50 ////////////////////////////////////////////////////////////////////////////////////////*/
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
51
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
52 static FuncDeclaration* getParentFunc(Dsymbol* sym) {
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
53 if (!sym)
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
54 return NULL;
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
55 Dsymbol* parent = sym->parent;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
56 assert(parent);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
57 while (parent && !parent->isFuncDeclaration())
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
58 parent = parent->parent;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
59
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
60 return (parent ? parent->isFuncDeclaration() : NULL);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
61 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
62
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
63 DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
64 {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
65 Logger::println("DtoNestedVariable for %s @ %s", vd->toChars(), loc.toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
66 LOG_SCOPE;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
67
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
68 ////////////////////////////////////
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
69 // Locate context value
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
70
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
71 Dsymbol* vdparent = vd->toParent2();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
72 assert(vdparent);
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
73
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
74 IrFunction* irfunc = gIR->func();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
75
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
76 // is the nested variable in this scope?
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
77 if (vdparent == irfunc->decl)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
78 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
79 LLValue* val = vd->ir.getIrValue();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
80 return new DVarValue(astype, vd, val);
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
81 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
82
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
83 // get the nested context
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
84 LLValue* ctx = 0;
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
85 if (irfunc->decl->isMember2())
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
86 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
87 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
88 LLValue* val = DtoLoad(irfunc->thisArg);
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
89 ctx = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
90 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
91 else
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
92 ctx = irfunc->nestArg;
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
93 assert(ctx);
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
94
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
95 assert(vd->ir.irLocal);
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
96
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
97 ////////////////////////////////////
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
98 // Extract variable from nested context
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
99
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
100 if (nestedCtx == NCArray) {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
101 LLValue* val = DtoBitCast(ctx, getPtrToType(getVoidPtrType()));
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
102 val = DtoGEPi1(val, vd->ir.irLocal->nestedIndex);
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
103 val = DtoAlignedLoad(val);
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
104 assert(vd->ir.irLocal->value);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
105 val = DtoBitCast(val, vd->ir.irLocal->value->getType(), vd->toChars());
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
106 return new DVarValue(astype, vd, val);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
107 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
108 else if (nestedCtx == NCHybrid) {
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
109 FuncDeclaration* parentfunc = getParentFunc(irfunc->decl);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
110 assert(parentfunc && "No parent function for nested function?");
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
111 Logger::println("Parent function: %s", parentfunc->toChars());
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
112
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
113 LLValue* val = DtoBitCast(ctx, LLPointerType::getUnqual(parentfunc->ir.irFunc->framesType));
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
114 Logger::cout() << "Context: " << *val << '\n';
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
115
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
116 if (!parentfunc->ir.irFunc->elidedCtxList) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
117 val = DtoGEPi(val, 0, vd->ir.irLocal->nestedDepth);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
118 val = DtoAlignedLoad(val, (std::string(".frame.") + vdparent->toChars()).c_str());
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
119 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
120 val = DtoGEPi(val, 0, vd->ir.irLocal->nestedIndex, vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
121 if (vd->ir.irLocal->byref)
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
122 val = DtoAlignedLoad(val);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
123 return new DVarValue(astype, vd, val);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
124 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
125 else {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
126 assert(0 && "Not implemented yet");
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
127 }
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
128 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
129
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
130 void DtoNestedInit(VarDeclaration* vd)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
131 {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
132 Logger::println("DtoNestedInit for %s", vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
133 LOG_SCOPE
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
134
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
135 IrFunction* irfunc = gIR->func()->decl->ir.irFunc;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
136 LLValue* nestedVar = irfunc->nestedVar;
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
137
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
138 if (nestedCtx == NCArray) {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
139 // alloca as usual if no value already
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
140 if (!vd->ir.irLocal->value)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
141 vd->ir.irLocal->value = DtoAlloca(DtoType(vd->type), vd->toChars());
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
142
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
143 // store the address into the nested vars array
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
144 assert(vd->ir.irLocal->nestedIndex >= 0);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
145 LLValue* gep = DtoGEPi(nestedVar, 0, vd->ir.irLocal->nestedIndex);
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
146
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
147 assert(isaPointer(vd->ir.irLocal->value));
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
148 LLValue* val = DtoBitCast(vd->ir.irLocal->value, getVoidPtrType());
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
149
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
150 DtoAlignedStore(val, gep);
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
151 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
152 else if (nestedCtx == NCHybrid) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
153 assert(vd->ir.irLocal->value && "Nested variable without storage?");
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
154 if (!vd->isParameter() && (vd->isRef() || vd->isOut())) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
155 Logger::println("Initializing non-parameter byref value");
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
156 LLValue* frame;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
157 if (!irfunc->elidedCtxList) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
158 LLValue* framep = DtoGEPi(nestedVar, 0, vd->ir.irLocal->nestedDepth);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
159
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
160 FuncDeclaration *parentfunc = getParentFunc(vd);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
161 assert(parentfunc && "No parent function for nested variable?");
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
162 frame = DtoAlignedLoad(framep, (std::string(".frame.") + parentfunc->toChars()).c_str());
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
163 } else {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
164 frame = nestedVar;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
165 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
166 LLValue* slot = DtoGEPi(frame, 0, vd->ir.irLocal->nestedIndex);
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
167 DtoAlignedStore(vd->ir.irLocal->value, slot);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
168 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
169 // Already initialized in DtoCreateNestedContext
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
170 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
171 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
172 else {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
173 assert(0 && "Not implemented yet");
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
174 }
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
175 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
176
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
177 LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
178 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
179 Logger::println("DtoNestedContext for %s", sym->toPrettyChars());
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
180 LOG_SCOPE;
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
181
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
182 IrFunction* irfunc = gIR->func();
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
183 bool fromParent = true;
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
184
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
185 LLValue* val;
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
186 // if this func has its own vars that are accessed by nested funcs
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
187 // use its own context
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
188 if (irfunc->nestedVar) {
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
189 val = irfunc->nestedVar;
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
190 fromParent = false;
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
191 }
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
192 // otherwise, it may have gotten a context from the caller
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
193 else if (irfunc->nestArg)
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
194 val = irfunc->nestArg;
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
195 // or just have a this argument
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
196 else if (irfunc->thisArg)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
197 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
198 ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
199 if (!cd || !cd->vthis)
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
200 return getNullPtr(getVoidPtrType());
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
201 val = DtoLoad(irfunc->thisArg);
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
202 val = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
203 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
204 else
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
205 {
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
206 return getNullPtr(getVoidPtrType());
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
207 }
1213
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
208 if (nestedCtx == NCHybrid) {
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
209 // If sym is a nested function, and its parent elided the context list but the
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
210 // context we got didn't, we need to index to the first frame.
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
211 if (FuncDeclaration* fd = getParentFunc(sym->isFuncDeclaration())) {
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
212 Logger::println("For nested function, parent is %s", fd->toChars());
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
213 FuncDeclaration* ctxfd = irfunc->decl;
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
214 Logger::println("Current function is %s", ctxfd->toChars());
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
215 if (fromParent) {
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
216 ctxfd = getParentFunc(ctxfd);
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
217 assert(ctxfd && "Context from outer function, but no outer function?");
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
218 }
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
219 Logger::println("Context is from %s", ctxfd->toChars());
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
220 if (fd->ir.irFunc->elidedCtxList && !ctxfd->ir.irFunc->elidedCtxList) {
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
221 Logger::println("Adjusting to remove context frame list", ctxfd->toChars());
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
222 val = DtoBitCast(val, LLPointerType::getUnqual(ctxfd->ir.irFunc->framesType));
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
223 val = DtoGEPi(val, 0, 0);
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
224 val = DtoAlignedLoad(val, (std::string(".frame.") + fd->toChars()).c_str());
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
225 }
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
226 }
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
227 }
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
228 Logger::cout() << "result = " << *val << '\n';
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
229 Logger::cout() << "of type " << *val->getType() << '\n';
9430d4959ab4 Fix a bug in nested context code that occured when calling a function nested in
Frits van Bommel <fvbommel wxs.nl>
parents: 1212
diff changeset
230 return val;
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
231 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
232
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
233 void DtoCreateNestedContext(FuncDeclaration* fd) {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
234 Logger::println("DtoCreateNestedContext for %s", fd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
235 LOG_SCOPE
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
236
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
237 if (nestedCtx == NCArray) {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
238 // construct nested variables array
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
239 if (!fd->nestedVars.empty())
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
240 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
241 Logger::println("has nested frame");
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
242 // start with adding all enclosing parent frames until a static parent is reached
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
243 int nparelems = 0;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
244 if (!fd->isStatic())
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
245 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
246 Dsymbol* par = fd->toParent2();
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
247 while (par)
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
248 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
249 if (FuncDeclaration* parfd = par->isFuncDeclaration())
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
250 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
251 nparelems += parfd->nestedVars.size();
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
252 // stop at first static
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
253 if (parfd->isStatic())
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
254 break;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
255 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
256 else if (ClassDeclaration* parcd = par->isClassDeclaration())
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
257 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
258 // nothing needed
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
259 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
260 else
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
261 {
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
262 break;
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
263 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
264
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
265 par = par->toParent2();
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
266 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
267 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
268 int nelems = fd->nestedVars.size() + nparelems;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
269
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
270 // make array type for nested vars
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
271 const LLType* nestedVarsTy = LLArrayType::get(getVoidPtrType(), nelems);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
272
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
273 // alloca it
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
274 LLValue* nestedVars = DtoAlloca(nestedVarsTy, ".nested_vars");
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
275
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
276 IrFunction* irfunction = fd->ir.irFunc;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
277
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
278 // copy parent frame into beginning
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
279 if (nparelems)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
280 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
281 LLValue* src = irfunction->nestArg;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
282 if (!src)
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
283 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
284 assert(irfunction->thisArg);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
285 assert(fd->isMember2());
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
286 LLValue* thisval = DtoLoad(irfunction->thisArg);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
287 ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
288 assert(cd);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
289 assert(cd->vthis);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
290 src = DtoLoad(DtoGEPi(thisval, 0,cd->vthis->ir.irField->index, ".vthis"));
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
291 }
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
292 DtoMemCpy(nestedVars, src, DtoConstSize_t(nparelems*PTRSIZE),
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
293 getABITypeAlign(getVoidPtrType()));
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
294 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
295
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
296 // store in IrFunction
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
297 irfunction->nestedVar = nestedVars;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
298
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
299 // go through all nested vars and assign indices
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
300 int idx = nparelems;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
301 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
302 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
303 VarDeclaration* vd = *i;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
304 if (!vd->ir.irLocal)
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
305 vd->ir.irLocal = new IrLocal(vd);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
306
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
307 if (vd->isParameter())
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
308 {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
309 Logger::println("nested param: %s", vd->toChars());
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
310 LLValue* gep = DtoGEPi(nestedVars, 0, idx);
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
311 LLValue* val = DtoBitCast(vd->ir.irLocal->value, getVoidPtrType());
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
312 DtoAlignedStore(val, gep);
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
313 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
314 else
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
315 {
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
316 Logger::println("nested var: %s", vd->toChars());
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
317 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
318
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
319 vd->ir.irLocal->nestedIndex = idx++;
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
320 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
321 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
322 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
323 else if (nestedCtx == NCHybrid) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
324 // construct nested variables array
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
325 if (!fd->nestedVars.empty())
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
326 {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
327 Logger::println("has nested frame");
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
328 // start with adding all enclosing parent frames until a static parent is reached
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
329 typedef std::vector<const LLType*> TypeVec;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
330 TypeVec frametypes;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
331 if (!fd->isStatic()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
332 Dsymbol* par = fd->toParent2();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
333 while (par) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
334 if (FuncDeclaration* parfd = par->isFuncDeclaration()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
335 // skip functions without nested parameters
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
336 if (!parfd->nestedVars.empty()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
337 const LLStructType* parft = parfd->ir.irFunc->framesType;
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
338 if (parfd->ir.irFunc->elidedCtxList) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
339 // This is the outermost function with a nested context.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
340 // Its context is not a list of frames, but just the frame itself.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
341 frametypes.push_back(LLPointerType::getUnqual(parft));
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
342 } else {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
343 // Copy the types of parent function frames.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
344 frametypes.insert(frametypes.begin(), parft->element_begin(), parft->element_end());
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
345 }
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
346 break; // That's all the info needed.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
347 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
348 } else if (ClassDeclaration* parcd = par->isClassDeclaration()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
349 // skip
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
350 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
351 break;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
352 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
353 par = par->toParent2();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
354 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
355 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
356 unsigned depth = frametypes.size();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
357
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
358 if (Logger::enabled()) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
359 Logger::println("Frame types: ");
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
360 LOG_SCOPE;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
361 for (TypeVec::iterator i=frametypes.begin(); i!=frametypes.end(); ++i)
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
362 Logger::cout() << **i << '\n';
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
363 }
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
364
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
365 // Construct a struct for the direct nested variables of this function, and update their indices to match.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
366 // TODO: optimize ordering for minimal space usage?
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
367 TypeVec types;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
368 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i)
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
369 {
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
370 VarDeclaration* vd = *i;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
371 if (!vd->ir.irLocal)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
372 vd->ir.irLocal = new IrLocal(vd);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
373
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
374 vd->ir.irLocal->nestedDepth = depth;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
375 vd->ir.irLocal->nestedIndex = types.size();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
376 if (vd->isParameter()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
377 // Parameters already have storage associated with them (to handle byref etc.),
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
378 // so handle specially for now by storing a pointer instead of a value.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
379 assert(vd->ir.irLocal->value);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
380 // FIXME: don't do this for normal parameters?
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
381 types.push_back(vd->ir.irLocal->value->getType());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
382 } else if (vd->isRef() || vd->isOut()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
383 // Foreach variables can also be by reference, for instance.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
384 types.push_back(DtoType(vd->type->pointerTo()));
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
385 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
386 types.push_back(DtoType(vd->type));
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
387 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
388 if (Logger::enabled()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
389 Logger::println("Nested var: %s", vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
390 Logger::cout() << "of type: " << *types.back() << '\n';
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
391 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
392 }
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
393
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
394 // Append current frame type to frame type list
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
395 const LLStructType* frameType = LLStructType::get(types);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
396 const LLStructType* nestedVarsTy = NULL;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
397 if (!frametypes.empty()) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
398 assert(depth > 0);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
399 frametypes.push_back(LLPointerType::getUnqual(frameType));
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
400
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
401 // make struct type for nested frame list
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
402 nestedVarsTy = LLStructType::get(frametypes);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
403 } else {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
404 assert(depth == 0);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
405 // For the outer function, just use the frame as the context
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
406 // instead of alloca'ing a single-element framelist and passing
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
407 // a pointer to that.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
408 nestedVarsTy = frameType;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
409 fd->ir.irFunc->elidedCtxList = true;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
410 }
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
411
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
412 Logger::cout() << "nestedVarsTy = " << *nestedVarsTy << '\n';
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
413
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
414 // Store type in IrFunction
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
415 IrFunction* irfunction = fd->ir.irFunc;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
416 irfunction->framesType = nestedVarsTy;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
417
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
418 LLValue* nestedVars = NULL;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
419
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
420 // Create frame for current function and append to frames list
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
421 // FIXME: For D2, this should be a gc_malloc (or similar) call, not alloca
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
422 LLValue* frame = DtoAlloca(frameType, ".frame");
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
423
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
424 // copy parent frames into beginning
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
425 if (depth != 0)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
426 {
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
427 // alloca frame list first
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
428 nestedVars = DtoAlloca(nestedVarsTy, ".frame_list");
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
429
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
430 LLValue* src = irfunction->nestArg;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
431 if (!src)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
432 {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
433 assert(irfunction->thisArg);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
434 assert(fd->isMember2());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
435 LLValue* thisval = DtoLoad(irfunction->thisArg);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
436 ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
437 assert(cd);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
438 assert(cd->vthis);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
439 Logger::println("Indexing to 'this'");
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
440 src = DtoLoad(DtoGEPi(thisval, 0, cd->vthis->ir.irField->index, ".vthis"));
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
441 }
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
442 if (depth == 1) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
443 // Just copy nestArg into framelist; the outer frame is not a list of pointers
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
444 // but a direct pointer.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
445 src = DtoBitCast(src, frametypes[0]);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
446 LLValue* gep = DtoGEPi(nestedVars, 0, 0);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
447 DtoAlignedStore(src, gep);
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
448 } else {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
449 src = DtoBitCast(src, getVoidPtrType());
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
450 LLValue* dst = DtoBitCast(nestedVars, getVoidPtrType());
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
451 DtoMemCpy(dst, src, DtoConstSize_t(depth * PTRSIZE),
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
452 getABITypeAlign(getVoidPtrType()));
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
453 }
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
454 // store current frame in list
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
455 DtoAlignedStore(frame, DtoGEPi(nestedVars, 0, depth));
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
456 } else {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
457 // Use frame as context directly
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
458 nestedVars = frame;
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
459 }
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
460
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
461 // store context in IrFunction
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
462 irfunction->nestedVar = nestedVars;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
463
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
464 // go through all nested vars and assign addresses where possible.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
465 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
466 {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
467 VarDeclaration* vd = *i;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
468
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
469 LLValue* gep = DtoGEPi(frame, 0, vd->ir.irLocal->nestedIndex, vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
470 if (vd->isParameter()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
471 Logger::println("nested param: %s", vd->toChars());
1210
3d4581761b4c Add some alignment info where LLVM might otherwise be more pessimistic.
Frits van Bommel <fvbommel wxs.nl>
parents: 1209
diff changeset
472 DtoAlignedStore(vd->ir.irLocal->value, gep);
1209
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
473 vd->ir.irLocal->byref = true;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
474 } else if (vd->isRef() || vd->isOut()) {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
475 // This slot is initialized in DtoNestedInit, to handle things like byref foreach variables
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
476 // which move around in memory.
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
477 vd->ir.irLocal->byref = true;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
478 } else {
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
479 Logger::println("nested var: %s", vd->toChars());
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
480 if (vd->ir.irLocal->value)
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
481 Logger::cout() << "Pre-existing value: " << *vd->ir.irLocal->value << '\n';
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
482 assert(!vd->ir.irLocal->value);
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
483 vd->ir.irLocal->value = gep;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
484 vd->ir.irLocal->byref = false;
8699c450a1a0 Implement -nested-ctx=hybrid
Frits van Bommel <fvbommel wxs.nl>
parents: 1208
diff changeset
485 }
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
486 }
1212
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
487 } else if (FuncDeclaration* parFunc = getParentFunc(fd)) {
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
488 // Propagate context arg properties if the context arg is passed on unmodified.
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
489 fd->ir.irFunc->framesType = parFunc->ir.irFunc->framesType;
df2227fdc860 For the outermost function needing a context frame, use the address of that
Frits van Bommel <fvbommel wxs.nl>
parents: 1210
diff changeset
490 fd->ir.irFunc->elidedCtxList = parFunc->ir.irFunc->elidedCtxList;
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
491 }
1208
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
492 }
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
493 else {
2a37f4745ddd Add an option to change the way nested variables are handled.
Frits van Bommel <fvbommel wxs.nl>
parents: 1207
diff changeset
494 assert(0 && "Not implemented yet");
1207
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
495 }
83d3b25c2213 Isolate all knowledge of what a function's nested context looks like in a
Frits van Bommel <fvbommel wxs.nl>
parents:
diff changeset
496 }