diff options
author | Matthias Andreas Benkard <matthias@benkard.de> | 2008-08-07 20:50:43 +0200 |
---|---|---|
committer | Matthias Andreas Benkard <matthias@benkard.de> | 2008-08-07 20:50:43 +0200 |
commit | 728d1fa3acdf0e64b397c54913fb67d25e5a6b84 (patch) | |
tree | dc88578b6cacaa26695b52add72322d6006cc99d | |
parent | a277a977dc9d036dba3498ee5459803da1cc2c8d (diff) |
Add a trampoline by which compiled code can call interpreted functions.
-rw-r--r-- | functions.h | 2 | ||||
-rw-r--r-- | functions.m | 35 |
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; +} |