diff options
author | Matthias Benkard <mulk@minimulk.mst-plus> | 2008-09-29 11:34:39 +0200 |
---|---|---|
committer | Matthias Benkard <mulk@minimulk.mst-plus> | 2008-09-29 11:34:39 +0200 |
commit | a91c396ba85243465acb7a073c58b3e3f8136587 (patch) | |
tree | 311140a50958603fad0875146f0c7a87b9e09daa | |
parent | 6efa469caf0146fb6aedb48619c4353d4c624ec4 (diff) |
SETQ (LLVM): Create new dynamic bindings on demand.
-rw-r--r-- | MLKLLVMCompiler.mm | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index ba77ae6..8602ddd 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -927,17 +927,54 @@ static Constant onObject:mlkdynamiccontext]; LRETAIN (variable); // FIXME: release +#ifdef __OBJC_GC__ + // FIXME: proper memory management + if (variable && MLKInstanceP (variable)) + [[NSGarbageCollector defaultCollector] disableCollectorForPointer:variable]; +#endif + Value *symbolV = builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, (uint64_t)variable, false), PointerTy); std::vector<Value *> args; - args.push_back (value); args.push_back (symbolV); - [_compiler insertMethodCall:@"setValue:forSymbol:" - onObject:dynctx - withArgumentVector:&args]; + Value *binding = [_compiler insertMethodCall:@"bindingForSymbol:" + onObject:dynctx + withArgumentVector:&args]; + + // Test whether the binding is non-null. If so, set its value, else create a new one. + + Function *function = builder.GetInsertBlock()->getParent(); + BasicBlock *setBlock = BasicBlock::Create ("setq_set_existing_dynamic_binding", function); + BasicBlock *makeNewBlock = BasicBlock::Create ("setq_make_new_dynamic_binding"); + BasicBlock *joinBlock = BasicBlock::Create ("setq_join"); + + Value *test = builder.CreateICmpNE (binding, ConstantPointerNull::get (PointerTy)); + //Value *value = builder.CreateAlloca (PointerTy, NULL, "if_result"); + builder.CreateCondBr (test, setBlock, makeNewBlock); + + builder.SetInsertPoint (setBlock); + args[0] = value; + [_compiler insertMethodCall:@"setValue:" + onObject:binding + withArgumentVector:&args]; + builder.CreateBr (joinBlock); + + builder.SetInsertPoint (makeNewBlock); + function->getBasicBlockList().push_back (makeNewBlock); + Value *globalctx = [_compiler insertMethodCall:@"globalContext" + onObject:mlkdynamiccontext]; + args[0] = value; + args.push_back (symbolV); + [_compiler insertMethodCall:@"addValue:forSymbol:" + onObject:globalctx + withArgumentVector:&args]; + builder.CreateBr (joinBlock); + + builder.SetInsertPoint (joinBlock); + function->getBasicBlockList().push_back (joinBlock); } else if ([_context variableIsGlobal:variable]) { |