[pure-lang-svn] SF.net SVN: pure-lang: [36] pure/trunk
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-05-03 10:28:54
|
Revision: 36 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=36&view=rev Author: agraef Date: 2008-05-03 03:29:01 -0700 (Sat, 03 May 2008) Log Message: ----------- Fixed premature garbage collection of arguments in external wrapper code. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-03 10:05:43 UTC (rev 35) +++ pure/trunk/ChangeLog 2008-05-03 10:29:01 UTC (rev 36) @@ -1,6 +1,13 @@ 2008-05-03 Albert Graef <Dr....@t-...> - * test/test4.pure: Disable tail call checks, as they may fail on + * interpreter.cc (declare_extern): Fixed a bug in the generated + wrapper code for external calls, which caused function arguments + to be garbage-collected prematurely, when they were still needed + to create the default value, in the case of external calls + returning a null expression pointer to indicate failure. Reported + by Eddie Rucker. + + * test/test4.pure: Disabled tail call checks, as they may fail on some platforms. Reported by Ryan Schmidt. * test/test1.pure: Corrected fact3 example, added test cases. Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-05-03 10:05:43 UTC (rev 35) +++ pure/trunk/interpreter.cc 2008-05-03 10:29:01 UTC (rev 36) @@ -2405,19 +2405,8 @@ } // call the function Value* u = b.CreateCall(g, unboxed.begin(), unboxed.end()); - // free temporaries and arguments + // free temporaries if (temps) b.CreateCall(module->getFunction("pure_free_cstrings")); - if (n == 1) - b.CreateCall(module->getFunction("pure_free"), args[0]); - else if (n > 0) { - vector<Value*> freeargs(n+2); - freeargs[0] = NullExprPtr; - for (size_t i = 0; i < n; i++) - freeargs[i+1] = args[i]; - freeargs[n+1] = NullExprPtr; - b.CreateCall(module->getFunction("pure_free_args"), - freeargs.begin(), freeargs.end()); - } // box the result if (type == Type::VoidTy) u = b.CreateCall(module->getFunction("pure_const"), @@ -2456,6 +2445,18 @@ u = b.CreateCall(module->getFunction("pure_pointer"), u); else assert(0 && "invalid C type"); + // free arguments (we do that here so that the arguments don't get freed + // before we know that we don't need them anymore) + if (n > 0) { + vector<Value*> freeargs(n+2); + freeargs[0] = u; + for (size_t i = 0; i < n; i++) + freeargs[i+1] = args[i]; + freeargs[n+1] = NullExprPtr; + b.CreateCall(module->getFunction("pure_free_args"), + freeargs.begin(), freeargs.end()); + b.CreateCall(module->getFunction("pure_unref"), u); + } b.CreateRet(u); // The call failed. Provide a default value. f->getBasicBlockList().push_back(failedbb); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |