summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MLKLLVMCompiler.mm55
-rw-r--r--functions.h3
-rw-r--r--functions.m28
3 files changed, 75 insertions, 11 deletions
diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm
index 81aa764..aba2bf1 100644
--- a/MLKLLVMCompiler.mm
+++ b/MLKLLVMCompiler.mm
@@ -17,6 +17,7 @@
*/
#import "MLKLLVMCompiler.h"
+#import "MLKPackage.h"
#import "globals.h"
#import "util.h"
@@ -381,23 +382,59 @@ static Constant
@implementation MLKFunctionCallForm (MLKLLVMCompilation)
-(Value *) processForLLVM
{
+ static MLKPackage *sys = [MLKPackage findPackage:@"TOILET-SYSTEM"];
+
+ BOOL special_dispatch = NO;
+ Value *functionCell;
+ Value *functionPtr;
+ Value *closureDataCell;
+ Value *closureDataPtr;
+ std::vector<Value *> args;
+
if (![_context symbolNamesFunction:_head])
{
- NSLog (@"Compiler: Don't know function %@", MLKPrintToString(_head));
- // XXX Issue a style warning.
+ if (_head && [_head homePackage] == sys)
+ {
+ special_dispatch = YES;
+ }
+ else
+ {
+ NSLog (@"Compiler: Don't know function %@", MLKPrintToString(_head));
+ // XXX Issue a style warning.
+ }
}
- Value *functionCell = builder.Insert ([_context functionCellValueForSymbol:_head]);
- Value *functionPtr = builder.CreateLoad (functionCell);
- Value *closureDataCell = builder.Insert ([_context closureDataPointerValueForSymbol:_head]);
- Value *closureDataPtr = builder.CreateLoad (closureDataCell);
+ if (!special_dispatch)
+ {
+ functionCell = builder.Insert ([_context functionCellValueForSymbol:_head]);
+ functionPtr = builder.CreateLoad (functionCell);
+ closureDataCell = builder.Insert ([_context closureDataPointerValueForSymbol:_head]);
+ closureDataPtr = builder.CreateLoad (closureDataCell);
+
+ args.push_back (closureDataPtr);
+ }
+ else
+ {
+ std::vector<const Type *> argtypes (1, PointerTy);
+ functionPtr = builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty,
+ (uint64_t)MLKDispatchRootFunction,
+ false),
+ PointerType::get (FunctionType::get (PointerTy,
+ argtypes,
+ true),
+ 0));
+ LRETAIN (_head); // FIXME: release sometime? On the other hand,
+ // these symbols will probably never be
+ // deallocated anyway.
+ args.push_back (builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty,
+ (uint64_t)_head,
+ false),
+ PointerTy));
+ }
NSEnumerator *e = [_argumentForms objectEnumerator];
MLKForm *form;
- std::vector<Value *> args;
- args.push_back (closureDataPtr);
-
while ((form = [e nextObject]))
{
args.push_back ([form processForLLVM]);
diff --git a/functions.h b/functions.h
index 8f3e70e..4ea8261 100644
--- a/functions.h
+++ b/functions.h
@@ -17,6 +17,7 @@
*/
#import "MLKInteger.h"
+#import "MLKSymbol.h"
#import <Foundation/NSString.h>
#include <stdint.h>
@@ -82,7 +83,7 @@ void MLKSetForeignValueWithLispValue (void *destination, id value, MLKForeignTyp
id MLKLispValueWithForeignValue (void *source, MLKForeignType type);
id MLKInterpretedFunctionTrampoline (void *target, ...);
-
+id MLKDispatchRootFunction (MLKSymbol *name, ...);
#ifdef __cplusplus
}
diff --git a/functions.m b/functions.m
index 7caea41..20cde07 100644
--- a/functions.m
+++ b/functions.m
@@ -25,7 +25,9 @@
#import "MLKInterpretedClosure.h"
#import "MLKPackage.h"
#import "MLKSymbol.h"
+#import "MLKRoot.h"
+#import <Foundation/NSArray.h>
#import <Foundation/NSException.h>
#import <Foundation/NSString.h>
@@ -405,7 +407,31 @@ id MLKInterpretedFunctionTrampoline (void *target, ...)
values = [closure applyToArray:arguments];
if ([values count] > 0)
- return [values objectAtIndex:0];
+ return denullify ([values objectAtIndex:0]);
+ else
+ return nil;
+}
+
+id MLKDispatchRootFunction (MLKSymbol *name, ...)
+{
+ NSArray *values;
+ NSMutableArray *arguments;
+ id arg;
+ va_list ap;
+
+ arguments = [NSMutableArray array];
+
+ va_start (ap, name);
+ while ((arg = va_arg (ap, id)) != MLKEndOfArgumentsMarker)
+ {
+ [arguments addObject:nullify(arg)];
+ }
+ va_end (ap);
+
+ values = [MLKRoot dispatch:name withArguments:arguments];
+
+ if ([values count] > 0)
+ return denullify ([values objectAtIndex:0]);
else
return nil;
}