Commit 8f8467da authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #412 from toshok/cache_module_str_constants

Conflicts:
	src/codegen/ast_interpreter.cpp
	src/runtime/types.cpp
parents 2288d38a ff6e4f8f
...@@ -645,7 +645,11 @@ Value ASTInterpreter::visit_stmt(AST_stmt* node) { ...@@ -645,7 +645,11 @@ Value ASTInterpreter::visit_stmt(AST_stmt* node) {
case AST_TYPE::Exec: case AST_TYPE::Exec:
return visit_exec((AST_Exec*)node); return visit_exec((AST_Exec*)node);
case AST_TYPE::Expr: case AST_TYPE::Expr:
return visit_expr((AST_Expr*)node); // docstrings are str constant expression statements.
// ignore those while interpreting.
if ((((AST_Expr*)node)->value)->type != AST_TYPE::Str)
return visit_expr((AST_Expr*)node);
break;
case AST_TYPE::Pass: case AST_TYPE::Pass:
return Value(); // nothing todo return Value(); // nothing todo
case AST_TYPE::Print: case AST_TYPE::Print:
...@@ -1066,7 +1070,7 @@ Value ASTInterpreter::visit_set(AST_Set* node) { ...@@ -1066,7 +1070,7 @@ Value ASTInterpreter::visit_set(AST_Set* node) {
Value ASTInterpreter::visit_str(AST_Str* node) { Value ASTInterpreter::visit_str(AST_Str* node) {
if (node->str_type == AST_Str::STR) { if (node->str_type == AST_Str::STR) {
return boxString(node->str_data); return source_info->parent_module->getStringConstant(node->str_data);
} else if (node->str_type == AST_Str::UNICODE) { } else if (node->str_type == AST_Str::UNICODE) {
return decodeUTF8StringPtr(&node->str_data); return decodeUTF8StringPtr(&node->str_data);
} else { } else {
......
...@@ -1020,7 +1020,11 @@ private: ...@@ -1020,7 +1020,11 @@ private:
CompilerVariable* evalStr(AST_Str* node, UnwindInfo unw_info) { CompilerVariable* evalStr(AST_Str* node, UnwindInfo unw_info) {
if (node->str_type == AST_Str::STR) { if (node->str_type == AST_Str::STR) {
return makeStr(&node->str_data); llvm::Value* rtn = embedConstantPtr(
irstate->getSourceInfo()->parent_module->getStringConstant(node->str_data), g.llvm_value_type_ptr);
return new ConcreteCompilerVariable(STR, rtn, true);
} else if (node->str_type == AST_Str::UNICODE) { } else if (node->str_type == AST_Str::UNICODE) {
return makeUnicode(emitter, &node->str_data); return makeUnicode(emitter, &node->str_data);
} else { } else {
...@@ -2039,7 +2043,8 @@ private: ...@@ -2039,7 +2043,8 @@ private:
doExec(ast_cast<AST_Exec>(node), unw_info); doExec(ast_cast<AST_Exec>(node), unw_info);
break; break;
case AST_TYPE::Expr: case AST_TYPE::Expr:
doExpr(ast_cast<AST_Expr>(node), unw_info); if ((((AST_Expr*)node)->value)->type != AST_TYPE::Str)
doExpr(ast_cast<AST_Expr>(node), unw_info);
break; break;
// case AST_TYPE::If: // case AST_TYPE::If:
// doIf(ast_cast<AST_If>(node)); // doIf(ast_cast<AST_If>(node));
......
...@@ -390,6 +390,25 @@ std::string BoxedModule::name() { ...@@ -390,6 +390,25 @@ std::string BoxedModule::name() {
} }
} }
Box* BoxedModule::getStringConstant(const std::string& ast_str) {
auto idx_iter = str_const_index.find(ast_str);
if (idx_iter != str_const_index.end())
return str_constants[idx_iter->second];
Box* box = boxString(ast_str);
str_const_index[ast_str] = str_constants.size();
str_constants.push_back(box);
return box;
}
extern "C" void moduleGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
BoxedModule* d = (BoxedModule*)b;
v->visitRange((void* const*)&d->str_constants[0], (void* const*)&d->str_constants[d->str_constants.size()]);
}
// This mustn't throw; our IR generator generates calls to it without "invoke" even when there are exception handlers / // This mustn't throw; our IR generator generates calls to it without "invoke" even when there are exception handlers /
// finally-blocks in scope. // finally-blocks in scope.
// TODO: should we use C++11 `noexcept' here? // TODO: should we use C++11 `noexcept' here?
...@@ -1890,8 +1909,8 @@ void setupRuntime() { ...@@ -1890,8 +1909,8 @@ void setupRuntime() {
function_cls->simple_destructor = builtin_function_or_method_cls->simple_destructor = functionDtor; function_cls->simple_destructor = builtin_function_or_method_cls->simple_destructor = functionDtor;
module_cls = new BoxedHeapClass(object_cls, NULL, offsetof(BoxedModule, attrs), 0, sizeof(BoxedModule), false, module_cls = new BoxedHeapClass(object_cls, &moduleGCHandler, offsetof(BoxedModule, attrs), 0, sizeof(BoxedModule),
new BoxedString("module")); false, new BoxedString("module"));
member_cls member_cls
= new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedMemberDescriptor), false, new BoxedString("member")); = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedMemberDescriptor), false, new BoxedString("member"));
capifunc_cls capifunc_cls
......
...@@ -529,6 +529,11 @@ public: ...@@ -529,6 +529,11 @@ public:
BoxedModule(const std::string& name, const std::string& fn, const char* doc = NULL); BoxedModule(const std::string& name, const std::string& fn, const char* doc = NULL);
std::string name(); std::string name();
Box* getStringConstant(const std::string& ast_str);
llvm::StringMap<int> str_const_index;
std::vector<Box*> str_constants;
DEFAULT_CLASS(module_cls); DEFAULT_CLASS(module_cls);
}; };
......
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