summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-09-01 23:58:53 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-09-01 23:58:53 +0200
commitb6b6fb9e55e46a631deb99a47a705af648da6e31 (patch)
tree2cc5c5ea9a99e1d82004c9ca119db6f7fd30fa4e
parentd2f326bbc766af34a2d1e5f0be4252eab41b2cac (diff)
LLVM compiler: Handle closure variables.
-rw-r--r--MLKLLVMCompiler.mm27
1 files changed, 24 insertions, 3 deletions
diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm
index 75e444b..071146a 100644
--- a/MLKLLVMCompiler.mm
+++ b/MLKLLVMCompiler.mm
@@ -668,12 +668,33 @@ static Constant
builder.SetInsertPoint (outerBlock);
- Value *closure_data = ConstantPointerNull::get (PointerTy);
+ NSArray *freeVariables = [[self freeVariables] allObjects];
+ Value *closure_data = builder.CreateMalloc (PointerTy,
+ ConstantInt::get(Type::Int32Ty,
+ (uint32_t)[freeVariables count],
+ false));
+ int closure_data_size = 0;
+ unsigned int i;
+ for (i = 0; i < [freeVariables count]; i++)
+ {
+ // FIXME: We assume heap allocation for all closure variables.
+ MLKSymbol *symbol = [freeVariables objectAtIndex:i];
+ if (![_context variableIsGlobal:symbol])
+ {
+ Value *binding = [_context bindingValueForSymbol:symbol];
+ Value *closure_value_ptr = builder.CreateGEP (closure_data,
+ ConstantInt::get(Type::Int32Ty,
+ closure_data_size,
+ false));
+ builder.CreateStore (binding, closure_value_ptr);
+ closure_data_size++;
+ }
+ }
argv[0] = function;
argv[1] = closure_data;
- argv.push_back (builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty,
- 0,
+ argv.push_back (builder.CreateIntToPtr (ConstantInt::get(Type::Int32Ty,
+ closure_data_size,
false),
PointerTy));
Value *mlkcompiledclosure = [_compiler