summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-08-18 11:38:56 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-08-18 11:41:15 +0200
commit4447563e79bb32bbda14641733049fe544392917 (patch)
treed1d4cdd5498b988817d386a855887b403896eb6f
parent60993a5e474244a3f4f623bb81d5191f2ec50993 (diff)
LLVM compiler: Implement dynamic variable access.
-rw-r--r--MLKLLVMCompiler.mm46
-rw-r--r--MLKLexicalContext-MLKLLVMCompilation.h2
-rw-r--r--MLKLexicalContext-MLKLLVMCompilation.mm12
-rw-r--r--MLKLexicalContext.h7
-rw-r--r--MLKLexicalContext.m39
-rw-r--r--MLKLexicalEnvironment.m32
6 files changed, 115 insertions, 23 deletions
diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm
index a7efa12..e7dc660 100644
--- a/MLKLLVMCompiler.mm
+++ b/MLKLLVMCompiler.mm
@@ -132,6 +132,8 @@ static Constant
verifyFunction (*function);
fpm->run (*function);
+ //function->dump();
+
// JIT-compile.
fn = (id (*)()) execution_engine->getPointerToFunction (function);
//module->dump();
@@ -377,9 +379,26 @@ static Constant
{
Value *value;
- if ([_context variableHeapAllocationForSymbol:_form])
+ if (![_context variableIsLexical:_form])
+ {
+ Value *mlkdynamiccontext = [_compiler insertClassLookup:@"MLKCons"];
+ Value *dynctx = [_compiler insertMethodCall:@"currentContext"
+ onObject:mlkdynamiccontext];
+
+ LRETAIN (_form); // FIXME: release
+ Value *symbolV = builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty,
+ (uint64_t)_form,
+ false),
+ PointerTy);
+
+ std::vector<Value *> args (1, symbolV);
+ value = [_compiler insertMethodCall:@"valueForSymbol:"
+ onObject:dynctx
+ withArgumentVector:&args];
+ }
+ else if ([_context variableHeapAllocationForSymbol:_form])
{
- Value *binding = builder.CreateLoad ([_context bindingValueForSymbol:_form]);
+ Value *binding = builder.CreateLoad (builder.Insert ([_context bindingCellValueForSymbol:_form]));
value = [_compiler insertMethodCall:@"value" onObject:binding];
}
else
@@ -732,10 +751,29 @@ static Constant
{
variable = [var_e nextObject];
value = [valueForm processForLLVM];
+ if (![_context variableIsLexical:variable])
+ {
+ Value *mlkdynamiccontext = [_compiler insertClassLookup:@"MLKCons"];
+ Value *dynctx = [_compiler insertMethodCall:@"currentContext"
+ onObject:mlkdynamiccontext];
+
+ LRETAIN (variable); // FIXME: release
+ Value *symbolV = builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty,
+ (uint64_t)variable,
+ false),
+ PointerTy);
+
+ std::vector<Value *> args;
+ args.push_back (value);
+ args.push_back (symbolV);
+ [_compiler insertMethodCall:@"setValue:forSymbol:"
+ onObject:dynctx
+ withArgumentVector:&args];
+ }
if ([_context variableHeapAllocationForSymbol:variable])
{
- Value *binding = builder.CreateLoad ([_context
- bindingValueForSymbol:variable]);
+ Value *binding = builder.CreateLoad (builder.Insert ([_context
+ bindingCellValueForSymbol:variable]));
std::vector<Value *> args (1, value);
[_compiler insertVoidMethodCall:@"setValue:"
diff --git a/MLKLexicalContext-MLKLLVMCompilation.h b/MLKLexicalContext-MLKLLVMCompilation.h
index d42140e..d791765 100644
--- a/MLKLexicalContext-MLKLLVMCompilation.h
+++ b/MLKLexicalContext-MLKLLVMCompilation.h
@@ -37,7 +37,7 @@ using namespace llvm;
-(BOOL) variableHeapAllocationForSymbol:(id)name;
-(Instruction *) functionCellValueForSymbol:(id)name;
-(Instruction *) closureDataPointerValueForSymbol:(id)name;
--(Value *) bindingValueForSymbol:(id)name;
+-(Instruction *) bindingCellValueForSymbol:(id)name;
-(Value *) valueValueForSymbol:(id)name;
//-(void) setFunctionCellValue:(Value *)cellPtr forSymbol:(id)name;
//-(void) setClosureDataPointerValue:(Value *)pointer forSymbol:(id)name;
diff --git a/MLKLexicalContext-MLKLLVMCompilation.mm b/MLKLexicalContext-MLKLLVMCompilation.mm
index 744351a..22d211d 100644
--- a/MLKLexicalContext-MLKLLVMCompilation.mm
+++ b/MLKLexicalContext-MLKLLVMCompilation.mm
@@ -45,7 +45,11 @@ using namespace std;
id flag = [self deepPropertyForVariable:name
key:@"LLVM.heap-flag"];
- return (flag && [flag boolValue]);
+ if (flag)
+ return [flag boolValue];
+ else
+ return (![self contextForVariable:name]
+ || [self contextForVariable:name] == [MLKLexicalContext globalContext]);
}
-(Instruction *) functionCellValueForSymbol:(id)name
@@ -70,12 +74,12 @@ using namespace std;
PointerType::get(PointerType::get(Type::Int8Ty, 0), 0)));
}
--(Value *) bindingValueForSymbol:(id)name
+-(Instruction *) bindingCellValueForSymbol:(id)name
{
return (new IntToPtrInst (ConstantInt::get(Type::Int64Ty,
- (uint64_t)[self bindingForSymbol:name],
+ (uint64_t)[self bindingCellForSymbol:name],
false),
- PointerType::get(Type::Int8Ty, 0)));
+ PointerType::get(PointerType::get(Type::Int8Ty, 0), 0)));
}
-(Value *) valueValueForSymbol:(id)name
diff --git a/MLKLexicalContext.h b/MLKLexicalContext.h
index fc2abc3..e350b63 100644
--- a/MLKLexicalContext.h
+++ b/MLKLexicalContext.h
@@ -86,9 +86,8 @@
-(id) declarations;
-(void) addDeclaration:(id)declaration;
-// FIXME?
-//-(MLKLexicalEnvironment *) instantiateWithVariables:(NSDictionary *)variables
-// functions:(NSDictionary *)functions;
+-(id) contextForVariable:(MLKSymbol *)symbol;
+-(id) contextForFunction:(MLKSymbol *)symbol;
-(void) addVariable:(MLKSymbol *)symbol;
-(void) addFunction:(MLKSymbol *)symbol;
@@ -107,7 +106,7 @@
-(void *) functionCellForSymbol:(id)name;
-(void *) closureDataPointerForSymbol:(id)name;
--(id) bindingForSymbol:(id)name;
+-(id *) bindingCellForSymbol:(id)name;
-(void) dealloc;
@end
diff --git a/MLKLexicalContext.m b/MLKLexicalContext.m
index 2af717b..3f820a8 100644
--- a/MLKLexicalContext.m
+++ b/MLKLexicalContext.m
@@ -198,9 +198,29 @@ static MLKSymbol *LEXICAL;
with:_declarations]);
}
+-(id) contextForVariable:(MLKSymbol *)symbol
+{
+ if ([_variables containsObject:nullify(symbol)])
+ return self;
+ else if (_parent)
+ return [_parent contextForVariable:symbol];
+ else
+ return nil;
+}
+
+-(id) contextForFunction:(MLKSymbol *)symbol
+{
+ if ([_functions containsObject:nullify(symbol)])
+ return self;
+ else if (_parent)
+ return [_parent contextForFunction:symbol];
+ else
+ return nil;
+}
+
-(BOOL) symbolNamesFunction:(MLKSymbol *)symbol
{
- symbol = symbol ? (id)symbol : (id)[NSNull null];
+ symbol = nullify (symbol);
if ([_functions containsObject:symbol])
return YES;
else if ([_knownMacros containsObject:symbol])
@@ -211,7 +231,7 @@ static MLKSymbol *LEXICAL;
-(BOOL) symbolNamesMacro:(MLKSymbol *)symbol
{
- symbol = symbol ? (id)symbol : (id)[NSNull null];
+ symbol = nullify (symbol);
if ([_functions containsObject:symbol])
return NO;
else if ([_knownMacros containsObject:symbol])
@@ -222,7 +242,7 @@ static MLKSymbol *LEXICAL;
-(BOOL) symbolNamesSymbolMacro:(MLKSymbol *)symbol
{
- symbol = symbol ? (id)symbol : (id)[NSNull null];
+ symbol = nullify (symbol);
if ([_variables containsObject:symbol])
return NO;
else if ([_knownSymbolMacros containsObject:symbol])
@@ -401,20 +421,25 @@ static MLKSymbol *LEXICAL;
}
}
--(id) bindingForSymbol:(id)name
+-(id *) bindingCellForSymbol:(id)name
{
id prop = [self deepPropertyForVariable:name
key:@"LEXCTX.variable-binding"];
if (!prop)
{
- prop = [MLKBinding binding];
+ id *cell = malloc (sizeof(id));
+ *cell = [[MLKBinding alloc] init];
+ prop = [NSValue valueWithPointer:cell];
[self setDeepProperty:prop
forVariable:name
key:@"LEXCTX.variable-binding"];
+ return cell;
+ }
+ else
+ {
+ return [prop pointerValue];
}
-
- return prop;
}
-(void) dealloc
diff --git a/MLKLexicalEnvironment.m b/MLKLexicalEnvironment.m
index ca6b4a9..723c955 100644
--- a/MLKLexicalEnvironment.m
+++ b/MLKLexicalEnvironment.m
@@ -107,17 +107,43 @@ static MLKLexicalEnvironment *global_environment;
-(id) valueForSymbol:(MLKSymbol *)symbol
{
- return [_variables valueForSymbol:symbol];
+ if (![_variables environmentForSymbol:symbol]
+ || [_variables environmentForSymbol:symbol] == global_environment->_variables)
+ {
+ id *cell = [[MLKLexicalContext globalContext] bindingCellForSymbol:symbol];
+ return [*cell value];
+ }
+ else
+ {
+ return [_variables valueForSymbol:symbol];
+ }
}
-(void) setValue:(id)value forSymbol:(MLKSymbol *)symbol
{
- [_variables setValue:value forSymbol:symbol];
+ if (![_variables environmentForSymbol:symbol]
+ || [_variables environmentForSymbol:symbol] == global_environment->_variables)
+ {
+ id *cell = [[MLKLexicalContext globalContext] bindingCellForSymbol:symbol];
+ [*cell setValue:value forSymbol:symbol];
+ }
+ else
+ {
+ [_variables setValue:value forSymbol:symbol];
+ }
}
-(void) addValue:(id)value forSymbol:(MLKSymbol *)symbol
{
- [_variables addValue:value forSymbol:symbol];
+ if (self == global_environment)
+ {
+ id *cell = [[MLKLexicalContext globalContext] bindingCellForSymbol:symbol];
+ [*cell setValue:value forSymbol:symbol];
+ }
+ else
+ {
+ [_variables addValue:value forSymbol:symbol];
+ }
}
-(void) addBindingForSymbol:(MLKSymbol *)symbol