diff options
author | Matthias Andreas Benkard <matthias@benkard.de> | 2008-08-18 11:38:56 +0200 |
---|---|---|
committer | Matthias Andreas Benkard <matthias@benkard.de> | 2008-08-18 11:41:15 +0200 |
commit | 4447563e79bb32bbda14641733049fe544392917 (patch) | |
tree | d1d4cdd5498b988817d386a855887b403896eb6f | |
parent | 60993a5e474244a3f4f623bb81d5191f2ec50993 (diff) |
LLVM compiler: Implement dynamic variable access.
-rw-r--r-- | MLKLLVMCompiler.mm | 46 | ||||
-rw-r--r-- | MLKLexicalContext-MLKLLVMCompilation.h | 2 | ||||
-rw-r--r-- | MLKLexicalContext-MLKLLVMCompilation.mm | 12 | ||||
-rw-r--r-- | MLKLexicalContext.h | 7 | ||||
-rw-r--r-- | MLKLexicalContext.m | 39 | ||||
-rw-r--r-- | MLKLexicalEnvironment.m | 32 |
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 |