summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MLKLLVMCompiler.mm68
-rw-r--r--MLKLexicalContext-MLKLLVMCompilation.h1
-rw-r--r--MLKLexicalContext-MLKLLVMCompilation.mm9
-rw-r--r--MLKLexicalContext.h5
-rw-r--r--MLKLexicalContext.m26
5 files changed, 109 insertions, 0 deletions
diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm
index 137598e..64b2423 100644
--- a/MLKLLVMCompiler.mm
+++ b/MLKLLVMCompiler.mm
@@ -1026,3 +1026,71 @@ static Constant
VoidPointerTy);
}
@end
+
+
+@implementation MLKSimpleFunctionForm (MLKLLVMCompilation)
+-(Value *) reallyProcessForLLVM
+{
+ // For global functions, this is easy. For local functions, we need to create
+ // a new MLKCompiledClosure object.
+ 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 *functionCell, *functionPtr;
+ Value *closureDataCell, *closureDataPtr;
+ Value *closureDataLengthCell, *closureDataLength;
+
+ functionCell = builder.Insert ([_context functionCellValueForSymbol:_head]);
+ functionPtr = builder.CreateLoad (functionCell);
+ closureDataCell = builder.Insert ([_context closureDataPointerValueForSymbol:_head]);
+ closureDataPtr = builder.CreateLoad (closureDataCell);
+ closureDataLengthCell = builder.Insert ([_context closureDataLengthValueForSymbol:_head]);
+ closureDataLength = builder.CreateLoad (closureDataLengthCell);
+
+ vector<Value *> argv;
+ argv.push_back (builder.CreateBitCast (functionPtr, VoidPointerTy));
+ argv.push_back (builder.CreateBitCast (closureDataPtr, VoidPointerTy));
+ argv.push_back (builder.CreateBitCast (closureDataLength, VoidPointerTy));
+ Value *mlkcompiledclosure = [_compiler
+ insertClassLookup:@"MLKCompiledClosure"];
+ Value *closure =
+ [_compiler insertMethodCall:@"closureWithCode:data:length:"
+ onObject:mlkcompiledclosure
+ withArgumentVector:&argv];
+
+ return closure;
+ }
+}
+@end
+
+
+@implementation MLKLambdaFunctionForm (MLKLLVMCompilation)
+-(Value *) reallyProcessForLLVM
+{
+ return [_lambdaForm processForLLVM];
+}
+@end
diff --git a/MLKLexicalContext-MLKLLVMCompilation.h b/MLKLexicalContext-MLKLLVMCompilation.h
index 3effb63..bbbe3fb 100644
--- a/MLKLexicalContext-MLKLLVMCompilation.h
+++ b/MLKLexicalContext-MLKLLVMCompilation.h
@@ -39,6 +39,7 @@ extern id MLKDummyUseLLVMLexicalContext;
-(BOOL) variableHeapAllocationForSymbol:(id)name;
-(Instruction *) functionCellValueForSymbol:(id)name;
-(Instruction *) closureDataPointerValueForSymbol:(id)name;
+-(Instruction *) closureDataLengthValueForSymbol:(id)name;
-(Value *) bindingValueForSymbol:(id)name;
-(void) locallySetBindingValue:(Value *)value forSymbol:(id)name;
-(void) setBindingValue:(Value *)value forSymbol:(id)name;
diff --git a/MLKLexicalContext-MLKLLVMCompilation.mm b/MLKLexicalContext-MLKLLVMCompilation.mm
index 37f03f5..2d525a5 100644
--- a/MLKLexicalContext-MLKLLVMCompilation.mm
+++ b/MLKLexicalContext-MLKLLVMCompilation.mm
@@ -75,6 +75,15 @@ id MLKDummyUseLLVMLexicalContext = nil;
PointerType::get(PointerType::get(PointerType::get(Type::Int8Ty, 0), 0), 0)));
}
+-(Instruction *) closureDataLengthValueForSymbol:(id)name
+{
+ // The length cell isn't really a void** but an intptr_t*.
+ return (new IntToPtrInst (ConstantInt::get(Type::Int64Ty,
+ (uint64_t)[self closureDataLengthForSymbol:name],
+ false),
+ PointerType::get(PointerType::get(Type::Int8Ty, 0), 0)));
+}
+
-(Instruction *) globalBindingValueForSymbol:(id)name
{
return (new IntToPtrInst (ConstantInt::get(Type::Int64Ty,
diff --git a/MLKLexicalContext.h b/MLKLexicalContext.h
index f8b7a14..0e51f2c 100644
--- a/MLKLexicalContext.h
+++ b/MLKLexicalContext.h
@@ -22,6 +22,9 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSSet.h>
+#include <stdint.h>
+
+
@class MLKEnvironment, MLKLexicalEnvironment, MLKSymbol, NSSet,
NSMutableDictionary, NSString, MLKCons;
@@ -95,6 +98,7 @@
-(BOOL) variableIsLexical:(MLKSymbol *)symbol;
-(BOOL) variableIsGlobal:(id)name;
-(BOOL) functionIsInline:(MLKSymbol *)symbol;
+-(BOOL) functionIsGlobal:(id)name;
-(id) propertyForVariable:(id)name key:(id)key;
-(void) setDeepProperty:(id)object
@@ -111,6 +115,7 @@
-(void *) functionCellForSymbol:(id)name;
-(void *) closureDataPointerForSymbol:(id)name;
+-(intptr_t *) closureDataLengthForSymbol:(id)name;
-(id) bindingForSymbol:(id)name;
-(void) dealloc;
diff --git a/MLKLexicalContext.m b/MLKLexicalContext.m
index acb5b4e..0afc66b 100644
--- a/MLKLexicalContext.m
+++ b/MLKLexicalContext.m
@@ -297,6 +297,12 @@ static MLKLexicalContext *global_context;
|| [self contextForVariable:name] == [MLKLexicalContext globalContext]);
}
+-(BOOL) functionIsGlobal:(id)name
+{
+ return (![self contextForFunction:name]
+ || [self contextForFunction:name] == [MLKLexicalContext globalContext]);
+}
+
-(BOOL) functionIsInline:(MLKSymbol *)symbol
{
if ([_functions containsObject:symbol])
@@ -455,6 +461,26 @@ static MLKLexicalContext *global_context;
}
}
+-(intptr_t *) closureDataLengthForSymbol:(id)name
+{
+ id prop = [self propertyForFunction:name
+ key:@"LEXCTX.closure-data-length"];
+
+ if (!prop)
+ {
+ intptr_t *cell = malloc (sizeof(intptr_t));
+ prop = [NSValue valueWithPointer:cell];
+ [self setDeepProperty:prop
+ forFunction:name
+ key:@"LEXCTX.closure-data-length"];
+ return cell;
+ }
+ else
+ {
+ return (intptr_t*)[prop pointerValue];
+ }
+}
+
-(id) bindingForSymbol:(id)name
{
id prop = [self propertyForVariable:name