Commit bf63439c authored by Kevin Modzelewski's avatar Kevin Modzelewski

Improve interpreter perf by caching the name lookup scope

parent 325dbfeb
...@@ -1126,11 +1126,18 @@ Value ASTInterpreter::visit_str(AST_Str* node) { ...@@ -1126,11 +1126,18 @@ Value ASTInterpreter::visit_str(AST_Str* node) {
} }
Value ASTInterpreter::visit_name(AST_Name* node) { Value ASTInterpreter::visit_name(AST_Name* node) {
if (scope_info->refersToGlobal(node->id)) switch (node->lookup_type) {
case AST_Name::UNKNOWN: {
if (scope_info->refersToGlobal(node->id)) {
node->lookup_type = AST_Name::GLOBAL;
return getGlobal(source_info->parent_module, &node->id.str()); return getGlobal(source_info->parent_module, &node->id.str());
else if (scope_info->refersToClosure(node->id)) { } else if (scope_info->refersToClosure(node->id)) {
node->lookup_type = AST_Name::CLOSURE;
return getattr(passed_closure, node->id.c_str()); return getattr(passed_closure, node->id.c_str());
} else { } else {
bool is_old_local = (source_info->ast->type == AST_TYPE::ClassDef);
node->lookup_type = is_old_local ? AST_Name::LOCAL : AST_Name::FAST_LOCAL;
SymMap::iterator it = sym_table.find(node->id); SymMap::iterator it = sym_table.find(node->id);
if (it != sym_table.end()) { if (it != sym_table.end()) {
Box* value = it->second; Box* value = it->second;
...@@ -1144,6 +1151,31 @@ Value ASTInterpreter::visit_name(AST_Name* node) { ...@@ -1144,6 +1151,31 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
assertNameDefined(0, node->id.c_str(), UnboundLocalError, true); assertNameDefined(0, node->id.c_str(), UnboundLocalError, true);
return Value(); return Value();
} }
}
case AST_Name::GLOBAL:
return getGlobal(source_info->parent_module, &node->id.str());
case AST_Name::CLOSURE:
return getattr(passed_closure, node->id.c_str());
case AST_Name::FAST_LOCAL: {
SymMap::iterator it = sym_table.find(node->id);
if (it != sym_table.end())
return it->second;
assertNameDefined(0, node->id.c_str(), UnboundLocalError, true);
return Value();
}
case AST_Name::LOCAL: {
SymMap::iterator it = sym_table.find(node->id);
if (it != sym_table.end()) {
Box* value = it->second;
return value;
}
return getGlobal(source_info->parent_module, &node->id.str());
}
default:
abort();
}
} }
......
...@@ -662,11 +662,23 @@ public: ...@@ -662,11 +662,23 @@ public:
AST_TYPE::AST_TYPE ctx_type; AST_TYPE::AST_TYPE ctx_type;
InternedString id; InternedString id;
// The resolved scope of this name. Kind of hacky to be storing it in the AST node;
// in CPython it ends up getting "cached" by being translated into one of a number of
// different bytecodes.
// We don't have a separate bytecode representation, so just store it in here for now.
enum LookupType {
UNKNOWN,
GLOBAL,
CLOSURE,
FAST_LOCAL,
LOCAL,
} lookup_type;
virtual void accept(ASTVisitor* v); virtual void accept(ASTVisitor* v);
virtual void* accept_expr(ExprVisitor* v); virtual void* accept_expr(ExprVisitor* v);
AST_Name(InternedString id, AST_TYPE::AST_TYPE ctx_type, int lineno, int col_offset = 0) AST_Name(InternedString id, AST_TYPE::AST_TYPE ctx_type, int lineno, int col_offset = 0)
: AST_expr(AST_TYPE::Name, lineno, col_offset), ctx_type(ctx_type), id(id) {} : AST_expr(AST_TYPE::Name, lineno, col_offset), ctx_type(ctx_type), id(id), lookup_type(UNKNOWN) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Name; static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Name;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment