diff options
author | Matthias Andreas Benkard <matthias@benkard.de> | 2008-10-01 19:40:42 +0200 |
---|---|---|
committer | Matthias Andreas Benkard <matthias@benkard.de> | 2008-10-01 19:40:42 +0200 |
commit | afaaec406bc86bf52ef976634b458dbc7e01fdc9 (patch) | |
tree | ce715c4b8fb6cbe95c4e2e80fc85af6706acfb44 /MLKLLVMCompiler.mm | |
parent | fd7702e9b009d2984328b2519db946f82ad834e9 (diff) | |
parent | a0dae1a2756c0f9a84c3a258f3a4a05e63afc1c6 (diff) |
Merge mulk_benkard@ssh.phx.nearlyfreespeech.net:/home/htdocs/code/mulklisp
Diffstat (limited to 'MLKLLVMCompiler.mm')
-rw-r--r-- | MLKLLVMCompiler.mm | 385 |
1 files changed, 294 insertions, 91 deletions
diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index cdb6360..84fc6af 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#import "MLKCompiledClosure.h" #import "MLKDynamicContext.h" #import "MLKLLVMCompiler.h" #import "MLKPackage.h" @@ -37,6 +38,7 @@ #include <llvm/CallingConv.h> #include <llvm/DerivedTypes.h> #include <llvm/ExecutionEngine/ExecutionEngine.h> +#include <llvm/ExecutionEngine/GenericValue.h> #include <llvm/Instructions.h> //#include <llvm/Interpreter.h> #include <llvm/Module.h> @@ -53,7 +55,14 @@ #include <deque> #include <vector> +#include <stddef.h> +#ifdef MACOSX +#include <objc/runtime.h> +#include <objc/objc-api.h> +#endif + using namespace llvm; +using namespace std; static ExecutionEngine *execution_engine; @@ -64,7 +73,7 @@ static IRBuilder builder; static IRBuilder<true, ConstantFolder> builder; #endif static FunctionPassManager *fpm; -static PointerType *PointerTy, *PointerPointerTy; +static PointerType *VoidPointerTy, *PointerPointerTy; static ModuleProvider *module_provider; @@ -109,8 +118,8 @@ static Constant //execution_engine = ExecutionEngine::create (module_provider, true); execution_engine = ExecutionEngine::create (module_provider, false); - PointerTy = PointerType::get(Type::Int8Ty, 0); - PointerPointerTy = PointerType::get(PointerTy, 0); + VoidPointerTy = PointerType::get(Type::Int8Ty, 0); + PointerPointerTy = PointerType::get(VoidPointerTy, 0); fpm = new FunctionPassManager (module_provider); fpm->add (new TargetData (*execution_engine->getTargetData())); @@ -140,8 +149,8 @@ static Constant Value *v = NULL; BasicBlock *block; - std::vector<const Type*> noargs (0, Type::VoidTy); - FunctionType *function_type = FunctionType::get (PointerTy, + vector<const Type*> noargs (0, Type::VoidTy); + FunctionType *function_type = FunctionType::get (VoidPointerTy, noargs, false); Function *function = Function::Create (function_type, @@ -174,10 +183,13 @@ static Constant #if 1 // JIT-compile. - fn = (id (*)()) execution_engine->getPointerToFunction (function); + vector<GenericValue> nogenericargs; + lambdaForm = (id)execution_engine->runFunction (function, nogenericargs).PointerVal; + //fn = (id (*)()) execution_engine->getPointerToFunction (function); // Execute. - lambdaForm = fn(); - execution_engine->freeMachineCodeForFunction (function); + //lambdaForm = fn(); + // FIXME: Free machine code when appropriate. (I.e. now? But this crashes after a LOAD.) + //execution_engine->freeMachineCodeForFunction (function); #else Interpreter *i = Interpreter::create (module_provider); lambdaForm = i->runFunction (function)->PointerVal; @@ -252,8 +264,8 @@ static Constant #else "sel_get_uid", #endif - PointerTy, - PointerTy, + VoidPointerTy, + VoidPointerTy, NULL); Constant *nameptr = createGlobalStringPtr ([name UTF8String]); @@ -262,7 +274,7 @@ static Constant +(Value *) insertMethodCall:(NSString *)messageName onObject:(Value *)object - withArgumentVector:(std::vector<Value*> *)argv + withArgumentVector:(vector<Value*> *)argv { return [self insertMethodCall:messageName onObject:object @@ -272,7 +284,7 @@ static Constant +(Value *) insertVoidMethodCall:(NSString *)messageName onObject:(Value *)object - withArgumentVector:(std::vector<Value*> *)argv + withArgumentVector:(vector<Value*> *)argv { return [self insertMethodCall:messageName onObject:object @@ -283,23 +295,23 @@ static Constant +(Value *) insertMethodCall:(NSString *)messageName onObject:(Value *)object - withArgumentVector:(std::vector<Value*> *)argv + withArgumentVector:(vector<Value*> *)argv name:(NSString *)name { return [self insertMethodCall:messageName onObject:object withArgumentVector:argv name:@"" - returnType:PointerTy]; + returnType:VoidPointerTy]; } +(Value *) insertMethodCall:(NSString *)messageName onObject:(Value *)object - withArgumentVector:(std::vector<Value*> *)argv + withArgumentVector:(vector<Value*> *)argv name:(NSString *)name returnType:(const Type *)returnType { - std::vector <const Type *> argtypes (2, PointerTy); + vector <const Type *> argtypes (2, VoidPointerTy); FunctionType *ftype = FunctionType::get (returnType, argtypes, true); Value *sel = [self insertSelectorLookup:messageName]; @@ -308,7 +320,7 @@ static Constant Constant *function = module->getOrInsertFunction ("objc_msgSend", ftype); #else - std::vector <const Type *> lookup_argtypes (2, PointerTy); + vector <const Type *> lookup_argtypes (2, VoidPointerTy); FunctionType *lookup_ftype = FunctionType::get (PointerType::get (ftype, 0), lookup_argtypes, false); @@ -319,14 +331,14 @@ static Constant #endif // XXX The following doesn't work. Why? - // std::deque <Value *> argd (*argv); + // deque <Value *> argd (*argv); // argd.push_front (sel); // argd.push_front (object); - std::vector <Value *> argd; + vector <Value *> argd; argd.push_back (object); argd.push_back (sel); - std::vector<Value *>::iterator e; + vector<Value *>::iterator e; for (e = argv->begin(); e != argv->end(); e++) argd.push_back (*e); @@ -337,7 +349,7 @@ static Constant onObject:(Value *)object withName:(NSString *)name { - std::vector<Value*> argv; + vector<Value*> argv; return [self insertMethodCall:messageName onObject:object withArgumentVector:&argv @@ -361,8 +373,8 @@ static Constant #else "objc_get_class", #endif - PointerTy, - PointerTy, + VoidPointerTy, + VoidPointerTy, NULL); const char *cname = [className UTF8String]; @@ -377,7 +389,7 @@ static Constant Constant *function = module->getOrInsertFunction ("puts", Type::Int32Ty, - PointerTy, + VoidPointerTy, NULL); builder.CreateCall (function, createGlobalStringPtr ([message UTF8String])); @@ -388,13 +400,13 @@ static Constant Constant *function = module->getOrInsertFunction ("printf", Type::Int32Ty, - PointerTy, - PointerTy, + VoidPointerTy, + VoidPointerTy, NULL); builder.CreateCall2 (function, createGlobalStringPtr ("%p\n"), - builder.CreateBitCast (pointerValue, PointerTy)); + builder.CreateBitCast (pointerValue, VoidPointerTy)); } @end @@ -432,7 +444,7 @@ static Constant { NSEnumerator *e = [_bodyForms objectEnumerator]; MLKForm *form; - Value *value = ConstantPointerNull::get (PointerTy); + Value *value = ConstantPointerNull::get (VoidPointerTy); while ((form = [e nextObject])) { @@ -469,7 +481,7 @@ static Constant builder.CreateUnreachable (); - return NULL; + return ConstantPointerNull::get (VoidPointerTy);; } @end @@ -485,7 +497,7 @@ static Constant if (![_context variableIsLexical:_form]) { //[_compiler insertTrace:@"Dynamic."]; - Value *mlkdynamiccontext = [_compiler insertClassLookup:@"MLKCons"]; + Value *mlkdynamiccontext = [_compiler insertClassLookup:@"MLKDynamicContext"]; Value *dynctx = [_compiler insertMethodCall:@"currentContext" onObject:mlkdynamiccontext]; @@ -493,9 +505,9 @@ static Constant Value *symbolV = builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, (uint64_t)_form, false), - PointerTy); + VoidPointerTy); - std::vector<Value *> args (1, symbolV); + vector<Value *> args (1, symbolV); value = [_compiler insertMethodCall:@"valueForSymbol:" onObject:dynctx withArgumentVector:&args]; @@ -525,11 +537,9 @@ static Constant @implementation MLKFunctionCallForm (MLKLLVMCompilation) -(Value *) reallyProcessForLLVM { - Value *functionCell; Value *functionPtr; - Value *closureDataCell; Value *closureDataPtr; - std::vector<Value *> args; + vector<Value *> args; if (![_context symbolNamesFunction:_head]) { @@ -537,10 +547,46 @@ static Constant // XXX Issue a style warning. } - functionCell = builder.Insert ([_context functionCellValueForSymbol:_head]); - functionPtr = builder.CreateLoad (functionCell); - closureDataCell = builder.Insert ([_context closureDataPointerValueForSymbol:_head]); - closureDataPtr = builder.CreateLoad (closureDataCell); + if ([_context functionIsGlobal:_head]) + { + Value *functionCell; + Value *closureDataCell; + + functionCell = builder.Insert ([_context functionCellValueForSymbol:_head]); + functionPtr = builder.CreateLoad (functionCell); + closureDataCell = builder.Insert ([_context closureDataPointerValueForSymbol:_head]); + closureDataPtr = builder.CreateLoad (closureDataCell); + } + else + { + Value *binding = [_context functionBindingValueForSymbol:_head]; + // It's important for closure to be an i8* because we need to calculate + // the GEP offset in terms of bytes. + Value *closure = builder.CreateBitCast ([_compiler insertMethodCall:@"value" onObject:binding], VoidPointerTy); + +#if defined(OBJC_API_VERSION) && OBJC_API_VERSION >= 2 + ptrdiff_t code_offset = ivar_getOffset (class_getInstanceVariable ([MLKCompiledClosure class], "m_code")); + ptrdiff_t data_offset = ivar_getOffset (class_getInstanceVariable ([MLKCompiledClosure class], "m_data")); +#else + ptrdiff_t code_offset = offsetof (MLKCompiledClosure, m_code); + ptrdiff_t data_offset = offsetof (MLKCompiledClosure, m_data); +#endif + Constant *code_offset_value = ConstantInt::get (Type::Int32Ty, code_offset, false); + Constant *data_offset_value = ConstantInt::get (Type::Int32Ty, data_offset, false); + Value *codeptr = builder.CreateGEP (closure, code_offset_value); + Value *dataptr = builder.CreateGEP (closure, data_offset_value); + codeptr = builder.CreateBitCast (codeptr, PointerPointerTy, "closure_code_ptr"); + dataptr = builder.CreateBitCast (codeptr, PointerPointerTy, "closure_data_ptr"); + Value *code = builder.CreateLoad (codeptr, "closure_code"); + Value *data = builder.CreateLoad (dataptr, "closure_data"); + + std::vector<const Type *> types (1, PointerPointerTy); + functionPtr = builder.CreateBitCast (code, PointerType::get(FunctionType::get(VoidPointerTy, + types, + true), + 0)); + closureDataPtr = builder.CreateBitCast (data, PointerPointerTy); + } //[_compiler insertTrace:[NSString stringWithFormat:@"Call: %@", MLKPrintToString(_head)]]; //[_compiler insertPointerTrace:functionPtr]; @@ -557,11 +603,11 @@ static Constant //GlobalVariable *endmarker = module->getGlobalVariable ("MLKEndOfArgumentsMarker", false); //endmarker->setConstant (true); - //GlobalVariable *endmarker = new GlobalVariable (PointerTy, true, GlobalValue::ExternalWeakLinkage); + //GlobalVariable *endmarker = new GlobalVariable (VoidPointerTy, true, GlobalValue::ExternalWeakLinkage); Value *endmarker = builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, (uint64_t)MLKEndOfArgumentsMarker, false), - PointerTy); + VoidPointerTy); args.push_back (endmarker); // If the pointer output here is different from the one above, @@ -589,15 +635,24 @@ static Constant @end -@implementation MLKSimpleLambdaForm (MLKLLVMCompilation) --(Value *) reallyProcessForLLVM +static void +build_simple_function_definition (MLKBodyForm *processed_form, + id _lambdaListName, + Function*& function, + Value*& closure_data, + intptr_t& closure_data_size) { - std::vector <const Type *> argtypes (1, PointerPointerTy); - FunctionType *ftype = FunctionType::get (PointerTy, argtypes, true); - Function *function = Function::Create (ftype, - Function::InternalLinkage, - "a_lisp_closure_body", - module); + NSArray *_bodyForms = [processed_form bodyForms]; + MLKLexicalContext *_bodyContext = [processed_form bodyContext]; + MLKLexicalContext *_context = [processed_form context]; + id _compiler = [MLKLLVMCompiler class]; + + vector <const Type *> argtypes (1, PointerPointerTy); + FunctionType *ftype = FunctionType::get (VoidPointerTy, argtypes, true); + function = Function::Create (ftype, + Function::InternalLinkage, + "a_lisp_closure_body", + module); Function::arg_iterator args = function->arg_begin(); Value *closure_data_arg = args++; @@ -614,12 +669,12 @@ static Constant // ***** HANDLE CLOSURE VARIABLES ***** builder.SetInsertPoint (outerBlock); - NSArray *freeVariables = [[self freeVariables] allObjects]; - Value *closure_data = builder.CreateAlloca (PointerTy, - ConstantInt::get(Type::Int32Ty, - (uint32_t)[freeVariables count], - false)); - int closure_data_size = 0; + NSArray *freeVariables = [[processed_form freeVariables] allObjects]; + closure_data = builder.CreateAlloca (VoidPointerTy, + ConstantInt::get(Type::Int32Ty, + (uint32_t)[freeVariables count], + false)); + closure_data_size = 0; unsigned int i; for (i = 0; i < [freeVariables count]; i++) { @@ -656,43 +711,43 @@ static Constant false), PointerType::get(Type::Int8Ty, 0)); - Value *ap = builder.CreateAlloca (PointerTy, NULL, "ap"); - Value *ap2 = builder.CreateBitCast (ap, PointerTy); + Value *ap = builder.CreateAlloca (VoidPointerTy, NULL, "ap"); + Value *ap2 = builder.CreateBitCast (ap, VoidPointerTy); builder.CreateCall (module->getOrInsertFunction ("llvm.va_start", Type::VoidTy, - PointerTy, + VoidPointerTy, NULL), ap2); Value *mlkcons = [_compiler insertClassLookup:@"MLKCons"]; // FIXME: Heap-allocate if appropriate. - Value *lambdaList = builder.CreateAlloca (PointerTy, NULL, "lambda_list"); - Value *lambdaListTail = builder.CreateAlloca (PointerTy, NULL, "lambda_list_tail"); + Value *lambdaList = builder.CreateAlloca (VoidPointerTy, NULL, "lambda_list"); + Value *lambdaListTail = builder.CreateAlloca (VoidPointerTy, NULL, "lambda_list_tail"); - builder.CreateStore (ConstantPointerNull::get (PointerTy), lambdaList); - builder.CreateStore (ConstantPointerNull::get (PointerTy), lambdaListTail); + builder.CreateStore (ConstantPointerNull::get (VoidPointerTy), lambdaList); + builder.CreateStore (ConstantPointerNull::get (VoidPointerTy), lambdaListTail); builder.CreateBr (loopInitBlock); builder.SetInsertPoint (loopInitBlock); function->getBasicBlockList().push_back (loopInitBlock); - Value *arg = builder.CreateVAArg (ap, PointerTy, "arg"); + Value *arg = builder.CreateVAArg (ap, VoidPointerTy, "arg"); Value *cond = builder.CreateICmpEQ (arg, endmarker); builder.CreateCondBr (cond, joinBlock, loopBlock); builder.SetInsertPoint (loopBlock); function->getBasicBlockList().push_back (loopBlock); builder.CreateCondBr (builder.CreateICmpEQ (builder.CreateLoad (lambdaList), - ConstantPointerNull::get (PointerTy)), + ConstantPointerNull::get (VoidPointerTy)), lambdaListNewBlock, lambdaListUpdateBlock); builder.SetInsertPoint (lambdaListNewBlock); function->getBasicBlockList().push_back (lambdaListNewBlock); - std::vector <Value *> argv (1, arg); - argv.push_back (ConstantPointerNull::get (PointerTy)); + vector <Value *> argv (1, arg); + argv.push_back (ConstantPointerNull::get (VoidPointerTy)); Value *newLambdaList = [_compiler insertMethodCall:@"cons:with:" onObject:mlkcons withArgumentVector:&argv]; @@ -706,7 +761,7 @@ static Constant Value *newCons = [_compiler insertMethodCall:@"cons:with:" onObject:mlkcons withArgumentVector:&argv]; - std::vector <Value *> setcdr_argv (1, newCons); + vector <Value *> setcdr_argv (1, newCons); [_compiler insertVoidMethodCall:@"setCdr:" onObject:builder.CreateLoad(lambdaListTail) withArgumentVector:&setcdr_argv]; @@ -718,7 +773,7 @@ static Constant builder.CreateCall (module->getOrInsertFunction ("llvm.va_end", Type::VoidTy, - PointerTy, + VoidPointerTy, NULL), ap2); @@ -726,7 +781,7 @@ static Constant { Value *mlkbinding = [_compiler insertClassLookup:@"MLKBinding"]; Value *currentLambdaList = builder.CreateLoad (lambdaList); - std::vector<Value *> args (1, currentLambdaList); + vector<Value *> args (1, currentLambdaList); Value *lambdaBinding = [_compiler insertMethodCall:@"bindingWithValue:" onObject:mlkbinding withArgumentVector:&args]; @@ -743,7 +798,7 @@ static Constant if ([_bodyForms count] == 0) { //NSLog (@"%LAMBDA: No body."); - value = ConstantPointerNull::get (PointerTy); + value = ConstantPointerNull::get (VoidPointerTy); } while ((form = [e nextObject])) @@ -769,13 +824,25 @@ static Constant //NSLog (@"Function built."); builder.SetInsertPoint (outerBlock); +} - argv[0] = function; - argv[1] = builder.CreateBitCast (closure_data, PointerTy); + +@implementation MLKSimpleLambdaForm (MLKLLVMCompilation) +-(Value *) reallyProcessForLLVM +{ + intptr_t closure_data_size; + Function *function; + Value *closure_data; + + build_simple_function_definition (self, _lambdaListName, function, closure_data, closure_data_size); + + vector<Value *> argv; + argv.push_back (function); + argv.push_back (builder.CreateBitCast (closure_data, VoidPointerTy)); argv.push_back (builder.CreateIntToPtr (ConstantInt::get(Type::Int32Ty, closure_data_size, false), - PointerTy)); + VoidPointerTy)); Value *mlkcompiledclosure = [_compiler insertClassLookup:@"MLKCompiledClosure"]; Value *closure = @@ -792,7 +859,7 @@ static Constant -(Value *) reallyProcessForLLVM { NSEnumerator *e = [_variableBindingForms objectEnumerator]; - Value *value = ConstantPointerNull::get (PointerTy); + Value *value = ConstantPointerNull::get (VoidPointerTy); MLKForm *form; MLKVariableBindingForm *binding_form; @@ -803,7 +870,7 @@ static Constant if ([_bodyContext variableHeapAllocationForSymbol:[binding_form name]]) { Value *mlkbinding = [_compiler insertClassLookup:@"MLKBinding"]; - std::vector<Value *> args (1, binding_value); + vector<Value *> args (1, binding_value); Value *binding = [_compiler insertMethodCall:@"bindingWithValue:" onObject:mlkbinding withArgumentVector:&args]; @@ -812,7 +879,7 @@ static Constant } else { - Value *binding_variable = builder.CreateAlloca (PointerTy, + Value *binding_variable = builder.CreateAlloca (VoidPointerTy, NULL, [(MLKPrintToString([binding_form name])) UTF8String]); @@ -834,6 +901,58 @@ static Constant @end +@implementation MLKSimpleFletForm (MLKLLVMCompilation) +-(Value *) reallyProcessForLLVM +{ + NSEnumerator *e = [_functionBindingForms objectEnumerator]; + Value *value = ConstantPointerNull::get (VoidPointerTy); + MLKForm *form; + MLKSimpleFunctionBindingForm *binding_form; + + while ((binding_form = [e nextObject])) + { + intptr_t closure_data_size; + Function *function; + Value *closure_data; + + build_simple_function_definition (binding_form, [binding_form lambdaListName], function, closure_data, closure_data_size); + + vector<Value *> argv; + argv.push_back (function); + argv.push_back (builder.CreateBitCast (closure_data, VoidPointerTy)); + argv.push_back (builder.CreateIntToPtr (ConstantInt::get(Type::Int32Ty, + closure_data_size, + false), + VoidPointerTy)); + Value *mlkcompiledclosure = [_compiler + insertClassLookup:@"MLKCompiledClosure"]; + Value *closure = + [_compiler insertMethodCall:@"closureWithCode:data:length:" + onObject:mlkcompiledclosure + withArgumentVector:&argv]; + + Value *binding_value = closure; + + Value *mlkbinding = [_compiler insertClassLookup:@"MLKBinding"]; + vector<Value *> args (1, binding_value); + Value *binding = [_compiler insertMethodCall:@"bindingWithValue:" + onObject:mlkbinding + withArgumentVector:&args]; + [_bodyContext setFunctionBindingValue:binding + forSymbol:[binding_form name]]; + } + + e = [_bodyForms objectEnumerator]; + while ((form = [e nextObject])) + { + value = [form processForLLVM]; + } + + return value; +} +@end + + @implementation MLKQuoteForm (MLKLLVMCompilation) -(Value *) reallyProcessForLLVM { @@ -850,7 +969,7 @@ static Constant return builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, (uint64_t)_quotedData, false), - PointerTy); + VoidPointerTy); } @end @@ -871,7 +990,7 @@ static Constant return builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, (uint64_t)_form, false), - PointerTy); + VoidPointerTy); } @end @@ -885,8 +1004,8 @@ static Constant BasicBlock *joinBlock = BasicBlock::Create ("if_join"); Value *test = builder.CreateICmpNE ([_conditionForm processForLLVM], - ConstantPointerNull::get (PointerTy)); - Value *value = builder.CreateAlloca (PointerTy, NULL, "if_result"); + ConstantPointerNull::get (VoidPointerTy)); + Value *value = builder.CreateAlloca (VoidPointerTy, NULL, "if_result"); builder.CreateCondBr (test, thenBlock, elseBlock); builder.SetInsertPoint (thenBlock); @@ -911,7 +1030,7 @@ static Constant { NSEnumerator *var_e, *value_e; MLKForm *valueForm; - Value *value = ConstantPointerNull::get (PointerTy); + Value *value = ConstantPointerNull::get (VoidPointerTy); id variable; var_e = [_variables objectEnumerator]; @@ -922,27 +1041,64 @@ static Constant value = [valueForm processForLLVM]; if (![_context variableIsLexical:variable]) { - Value *mlkdynamiccontext = [_compiler insertClassLookup:@"MLKCons"]; + Value *mlkdynamiccontext = [_compiler insertClassLookup:@"MLKDynamicContext"]; Value *dynctx = [_compiler insertMethodCall:@"currentContext" 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); + VoidPointerTy); - std::vector<Value *> args; - args.push_back (value); + vector<Value *> args; 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 (VoidPointerTy)); + //Value *value = builder.CreateAlloca (VoidPointerTy, 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]) { Value *binding = builder.Insert ([_context globalBindingValueForSymbol:variable]); - std::vector<Value *> args (1, value); + vector<Value *> args (1, value); [_compiler insertVoidMethodCall:@"setValue:" onObject:binding @@ -951,7 +1107,7 @@ static Constant else if ([_context variableHeapAllocationForSymbol:variable]) { Value *binding = [_context bindingValueForSymbol:variable]; - std::vector<Value *> args (1, value); + vector<Value *> args (1, value); [_compiler insertVoidMethodCall:@"setValue:" onObject:binding @@ -981,6 +1137,53 @@ static Constant return builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, (uint64_t)package, false), - PointerTy); + VoidPointerTy); } @end + + +@implementation MLKSimpleFunctionForm (MLKLLVMCompilation) +-(Value *) reallyProcessForLLVM +{ + if ([_context functionIsGlobal:_functionName]) + { + Value *mlklexicalenvironment = [_compiler insertClassLookup:@"MLKLexicalEnvironment"]; + Value *env = [_compiler insertMethodCall:@"globalEnvironment" + onObject:mlklexicalenvironment]; + + LRETAIN (_functionName); // FIXME: release +#ifdef __OBJC_GC__ + // FIXME: proper memory management + if (_functionName && MLKInstanceP (_functionName)) + [[NSGarbageCollector defaultCollector] disableCollectorForPointer:_functionName]; +#endif + + Value *symbolV = builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, + (uint64_t)_functionName, + false), + VoidPointerTy); + + vector<Value *> args; + args.push_back (symbolV); + Value *fun = [_compiler insertMethodCall:@"functionForSymbol:" + onObject:env + withArgumentVector:&args]; + return fun; + } + else + { + Value *binding = [_context functionBindingValueForSymbol:_functionName]; + Value *closure = builder.CreateBitCast ([_compiler insertMethodCall:@"value" onObject:binding], VoidPointerTy); + + return closure; + } +} +@end + + +@implementation MLKLambdaFunctionForm (MLKLLVMCompilation) +-(Value *) reallyProcessForLLVM +{ + return [_lambdaForm processForLLVM]; +} +@end
\ No newline at end of file |