Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

D1: Fixed accessing parameters in contracts.

This reverts the changes from commit f7e5245 and implements the
proper fix – in D1, contracts are treated as normal nested functions.

GitHub: Fix #138.
  • Loading branch information...
commit 07888f95e49932c99cdbf8434643466bf9768bf1 1 parent ece5176
@klickverbot klickverbot authored
Showing with 17 additions and 9 deletions.
  1. +11 −8 gen/tocall.cpp
  2. +6 −1 gen/toir.cpp
View
19 gen/tocall.cpp
@@ -410,18 +410,21 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
// then comes a context argument...
if(thiscall || delegatecall || nestedcall)
{
- if (dfnval && (dfnval->func->ident == Id::ensure ||
- dfnval->func->ident == Id::require))
- {
+#if DMDV2
+ if (dfnval && (dfnval->func->ident == Id::ensure || dfnval->func->ident == Id::require)) {
// ... which can be the this "context" argument for a contract
- // invocation (we do not generate a full nested context struct for
- // these)
+ // invocation (in D2, we do not generate a full nested contexts
+ // for __require/__ensure as the needed parameters are passed
+ // explicitly, while in D1, the normal nested function handling
+ // mechanisms are used)
LLValue* thisarg = DtoBitCast(DtoLoad(gIR->func()->thisArg), getVoidPtrType());
++argiter;
args.push_back(thisarg);
}
- else if (thiscall && dfnval && dfnval->vthis)
- {
+ else
+#endif
+ if (thiscall && dfnval && dfnval->vthis)
+ {
// ... or a normal 'this' argument
LLValue* thisarg = DtoBitCast(dfnval->vthis, *argiter);
++argiter;
@@ -445,7 +448,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
}
else if (nestedcall)
{
- /// ... or a nested function context arg
+ // ... or a nested function context arg
if (dfnval) {
LLValue* contextptr = DtoNestedContext(loc, dfnval->func);
contextptr = DtoBitCast(contextptr, getVoidPtrType());
View
7 gen/toir.cpp
@@ -1562,11 +1562,16 @@ DValue* ThisExp::toElem(IRState* p)
LLValue* v;
Dsymbol* vdparent = vd->toParent2();
Identifier *ident = p->func()->decl->ident;
+#if DMDV2
+ // In D1, contracts are treated as normal nested methods, 'this' is
+ // just passed in the context struct along with any used parameters.
if (ident == Id::ensure || ident == Id::require) {
Logger::println("contract this exp");
v = p->func()->nestArg;
v = DtoBitCast(v, DtoType(type)->getPointerTo());
- } else if (vdparent != p->func()->decl) {
+ } else
+#endif
+ if (vdparent != p->func()->decl) {
Logger::println("nested this exp");
#if STRUCTTHISREF
return DtoNestedVariable(loc, type, vd, type->ty == Tstruct);

0 comments on commit 07888f9

Please sign in to comment.
Something went wrong with that request. Please try again.