Revision: 1520 http://trac.macosforge.org/projects/ruby/changeset/1520 Author: vincent.isambart@gmail.com Date: 2009-05-02 21:24:14 -0700 (Sat, 02 May 2009) Log Message: ----------- now check if we have to save the local variables on all returns Modified Paths: -------------- MacRuby/branches/experimental/roxor.cpp MacRuby/branches/experimental/roxor.h Modified: MacRuby/branches/experimental/roxor.cpp =================================================================== --- MacRuby/branches/experimental/roxor.cpp 2009-05-03 04:09:05 UTC (rev 1519) +++ MacRuby/branches/experimental/roxor.cpp 2009-05-03 04:24:14 UTC (rev 1520) @@ -3140,10 +3140,11 @@ val = nilVal; } + ReturnInst::Create(val, bb); + // current_lvar_uses has 2 uses or more if it is really used // (there is always a StoreInst in which we assign it NULL) if (current_lvar_uses != NULL && current_lvar_uses->hasNUsesOrMore(2)) { - // TODO: only call the function is current_use is not NULL if (keepVarsFunc == NULL) { // void rb_vm_keep_vars(rb_vm_lvar_uses_t *uses, int lvars_size, ...); std::vector<const Type *> types; @@ -3156,7 +3157,7 @@ std::vector<Value *> params; - params.push_back(new LoadInst(current_lvar_uses, "", bb)); + params.push_back(NULL); // will be filled later params.push_back(ConstantInt::get(Type::Int32Ty, (int)lvars.size())); for (std::map<ID, Value *>::iterator iter = lvars.begin(); @@ -3169,11 +3170,23 @@ } } - CallInst::Create(keepVarsFunc, params.begin(), params.end(), "", bb); + // searches all ReturnInst in the function we just created and add before + // a call to the function to save the local variables if necessary + // (we can't do this before finishing compiling the whole function + // because we can't be sure if a block is there or not before) + for (Function::iterator block_it = f->begin(); block_it != f->end(); ++block_it) { + for (BasicBlock::iterator inst_it = block_it->begin(); inst_it != block_it->end(); ++inst_it) { + if (dyn_cast<ReturnInst>(inst_it)) { + // LoadInst needs to be inserted in a BasicBlock + // so we has to wait before putting it in params + params[0] = new LoadInst(current_lvar_uses, "", inst_it); + // TODO: only call the function is current_use is not NULL + CallInst::Create(keepVarsFunc, params.begin(), params.end(), "", inst_it); + } + } + } } - ReturnInst::Create(val, bb); - bb = old_bb; entry_bb = old_entry_bb; lvars = old_lvars; @@ -8006,7 +8019,7 @@ current = current->next; free(old_current); } - // no use still alive so nothing to do + // there's no use alive anymore so nothing to do return; use_found: Modified: MacRuby/branches/experimental/roxor.h =================================================================== --- MacRuby/branches/experimental/roxor.h 2009-05-03 04:09:05 UTC (rev 1519) +++ MacRuby/branches/experimental/roxor.h 2009-05-03 04:24:14 UTC (rev 1520) @@ -19,7 +19,7 @@ }; typedef struct rb_vm_local rb_vm_local_t; -#define VM_LVAR_USES_SIZE 128 +#define VM_LVAR_USES_SIZE 8 typedef struct rb_vm_lvar_uses { int uses_count; void *uses[VM_LVAR_USES_SIZE];