summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--functions.h2
-rw-r--r--functions.m35
2 files changed, 37 insertions, 0 deletions
diff --git a/functions.h b/functions.h
index 7be8eee..e635220 100644
--- a/functions.h
+++ b/functions.h
@@ -74,3 +74,5 @@ ffi_type *MLKFFITypeWithObjectiveCType (const char *typestring);
ffi_type *MLKFFITypeWithLispValue (id value);
void MLKSetForeignValueWithLispValue (void *destination, id value, MLKForeignType type);
id MLKLispValueWithForeignValue (void *source, MLKForeignType type);
+
+id MLKInterpretedFunctionTrampoline (void *target, ...);
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;
+}