summaryrefslogtreecommitdiff
path: root/functions.m
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-08-07 20:50:43 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-08-07 20:50:43 +0200
commit728d1fa3acdf0e64b397c54913fb67d25e5a6b84 (patch)
treedc88578b6cacaa26695b52add72322d6006cc99d /functions.m
parenta277a977dc9d036dba3498ee5459803da1cc2c8d (diff)
Add a trampoline by which compiled code can call interpreted functions.
Diffstat (limited to 'functions.m')
-rw-r--r--functions.m35
1 files changed, 35 insertions, 0 deletions
diff --git a/functions.m b/functions.m
index 895b70b..67b4361 100644
--- a/functions.m
+++ b/functions.m
@@ -17,10 +17,12 @@
*/
#import "functions.h"
+#import "globals.h"
#import "util.h"
#import "MLKCons.h"
#import "MLKCharacter.h"
#import "MLKInteger.h"
+#import "MLKInterpretedClosure.h"
#import "MLKPackage.h"
#import "MLKSymbol.h"
@@ -28,6 +30,7 @@
#import <Foundation/NSString.h>
#include <string.h>
+#include <stdarg.h>
#include <alloca.h>
@@ -373,3 +376,35 @@ MLKForeignType MLKForeignTypeWithObjectiveCType (const char *typestring)
MLKForeignType MLKForeignTypeWithLispValue (id value);
ffi_type *MLKFFITypeWithObjectiveCType (const char *typestring);
ffi_type *MLKFFITypeWithLispValue (id value);
+
+
+id MLKInterpretedFunctionTrampoline (void *target, ...)
+{
+ // Our first argument is the fat pointer's closure data pointer. We
+ // simply treat it as a pointer to the MLKInterpretedClosure that we
+ // want to call, because that is what we put there when setting this
+ // trampoline up with a specific MLKInterpretedClosure.
+
+ // FIXME: Implement multiple-value return, or at least set the
+ // multiple-value return flag to 0 before doing anything else.
+
+ NSArray *values;
+ NSMutableArray *arguments = [NSMutableArray array];
+ MLKInterpretedClosure *closure = target;
+ id arg;
+ va_list ap;
+
+ va_start (ap, target);
+ while ((arg = va_arg (ap, id)) != MLKEndOfArgumentsMarker)
+ {
+ [arguments addObject:arg];
+ }
+ va_end (ap);
+
+ values = [closure applyToArray:arguments];
+
+ if ([values count] > 0)
+ return [values objectAtIndex:0];
+ else
+ return nil;
+}