summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/apply-names.cc91
-rw-r--r--src/ir.cc7
-rw-r--r--src/ir.h1
-rw-r--r--src/wat-writer.cc53
4 files changed, 123 insertions, 29 deletions
diff --git a/src/apply-names.cc b/src/apply-names.cc
index a0d55818..d464c5f9 100644
--- a/src/apply-names.cc
+++ b/src/apply-names.cc
@@ -56,17 +56,23 @@ class NameApplier : public ExprVisitor::DelegateNop {
Result OnSetGlobalExpr(SetGlobalExpr*) override;
Result OnSetLocalExpr(SetLocalExpr*) override;
Result OnTeeLocalExpr(TeeLocalExpr*) override;
+ Result BeginTryExpr(TryExpr*) override;
+ Result EndTryExpr(TryExpr*) override;
+ Result OnCatchExpr(TryExpr*, Catch*) override;
+ Result OnThrowExpr(ThrowExpr*) override;
+ Result OnRethrowExpr(RethrowExpr*) override;
private:
void PushLabel(Label* label);
void PopLabel();
Label* FindLabelByVar(Var* var);
void UseNameForVar(StringSlice* name, Var* var);
- Result UseNameForFuncTypeVar(Module* module, Var* var);
- Result UseNameForFuncVar(Module* module, Var* var);
- Result UseNameForGlobalVar(Module* module, Var* var);
- Result UseNameForTableVar(Module* module, Var* var);
- Result UseNameForMemoryVar(Module* module, Var* var);
+ Result UseNameForFuncTypeVar(Var* var);
+ Result UseNameForFuncVar(Var* var);
+ Result UseNameForGlobalVar(Var* var);
+ Result UseNameForTableVar(Var* var);
+ Result UseNameForMemoryVar(Var* var);
+ Result UseNameForExceptVar(Var* var);
Result UseNameForParamAndLocalVar(Func* func, Var* var);
Result VisitFunc(Index func_index, Func* func);
Result VisitExport(Index export_index, Export* export_);
@@ -110,6 +116,7 @@ Label* NameApplier::FindLabelByVar(Var* var) {
void NameApplier::UseNameForVar(StringSlice* name, Var* var) {
if (var->type == VarType::Name) {
assert(string_slices_are_equal(name, &var->name));
+ return;
}
if (name && name->start) {
@@ -118,46 +125,54 @@ void NameApplier::UseNameForVar(StringSlice* name, Var* var) {
}
}
-Result NameApplier::UseNameForFuncTypeVar(Module* module, Var* var) {
- FuncType* func_type = module->GetFuncType(*var);
+Result NameApplier::UseNameForFuncTypeVar(Var* var) {
+ FuncType* func_type = module_->GetFuncType(*var);
if (!func_type)
return Result::Error;
UseNameForVar(&func_type->name, var);
return Result::Ok;
}
-Result NameApplier::UseNameForFuncVar(Module* module, Var* var) {
- Func* func = module->GetFunc(*var);
+Result NameApplier::UseNameForFuncVar(Var* var) {
+ Func* func = module_->GetFunc(*var);
if (!func)
return Result::Error;
UseNameForVar(&func->name, var);
return Result::Ok;
}
-Result NameApplier::UseNameForGlobalVar(Module* module, Var* var) {
- Global* global = module->GetGlobal(*var);
+Result NameApplier::UseNameForGlobalVar(Var* var) {
+ Global* global = module_->GetGlobal(*var);
if (!global)
return Result::Error;
UseNameForVar(&global->name, var);
return Result::Ok;
}
-Result NameApplier::UseNameForTableVar(Module* module, Var* var) {
- Table* table = module->GetTable(*var);
+Result NameApplier::UseNameForTableVar(Var* var) {
+ Table* table = module_->GetTable(*var);
if (!table)
return Result::Error;
UseNameForVar(&table->name, var);
return Result::Ok;
}
-Result NameApplier::UseNameForMemoryVar(Module* module, Var* var) {
- Memory* memory = module->GetMemory(*var);
+Result NameApplier::UseNameForMemoryVar(Var* var) {
+ Memory* memory = module_->GetMemory(*var);
if (!memory)
return Result::Error;
UseNameForVar(&memory->name, var);
return Result::Ok;
}
+Result NameApplier::UseNameForExceptVar(Var* var) {
+ Exception* except = module_->GetExcept(*var);
+ if (!except)
+ return Result::Error;
+ UseNameForVar(&except->name, var);
+ return Result::Ok;
+}
+
Result NameApplier::UseNameForParamAndLocalVar(Func* func, Var* var) {
Index local_index = func->GetLocalIndex(*var);
if (local_index >= func->GetNumParamsAndLocals())
@@ -233,18 +248,46 @@ Result NameApplier::OnBrTableExpr(BrTableExpr* expr) {
return Result::Ok;
}
+Result NameApplier::BeginTryExpr(TryExpr* expr) {
+ PushLabel(&expr->block->label);
+ return Result::Ok;
+}
+
+Result NameApplier::EndTryExpr(TryExpr*) {
+ PopLabel();
+ return Result::Ok;
+}
+
+Result NameApplier::OnCatchExpr(TryExpr*, Catch* expr) {
+ if (!expr->IsCatchAll()) {
+ CHECK_RESULT(UseNameForExceptVar(&expr->var));
+ }
+ return Result::Ok;
+}
+
+Result NameApplier::OnThrowExpr(ThrowExpr* expr) {
+ CHECK_RESULT(UseNameForExceptVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnRethrowExpr(RethrowExpr* expr) {
+ Label* label = FindLabelByVar(&expr->var);
+ UseNameForVar(label, &expr->var);
+ return Result::Ok;
+}
+
Result NameApplier::OnCallExpr(CallExpr* expr) {
- CHECK_RESULT(UseNameForFuncVar(module_, &expr->var));
+ CHECK_RESULT(UseNameForFuncVar(&expr->var));
return Result::Ok;
}
Result NameApplier::OnCallIndirectExpr(CallIndirectExpr* expr) {
- CHECK_RESULT(UseNameForFuncTypeVar(module_, &expr->var));
+ CHECK_RESULT(UseNameForFuncTypeVar(&expr->var));
return Result::Ok;
}
Result NameApplier::OnGetGlobalExpr(GetGlobalExpr* expr) {
- CHECK_RESULT(UseNameForGlobalVar(module_, &expr->var));
+ CHECK_RESULT(UseNameForGlobalVar(&expr->var));
return Result::Ok;
}
@@ -264,7 +307,7 @@ Result NameApplier::EndIfExpr(IfExpr* expr) {
}
Result NameApplier::OnSetGlobalExpr(SetGlobalExpr* expr) {
- CHECK_RESULT(UseNameForGlobalVar(module_, &expr->var));
+ CHECK_RESULT(UseNameForGlobalVar(&expr->var));
return Result::Ok;
}
@@ -281,7 +324,7 @@ Result NameApplier::OnTeeLocalExpr(TeeLocalExpr* expr) {
Result NameApplier::VisitFunc(Index func_index, Func* func) {
current_func_ = func;
if (func->decl.has_func_type) {
- CHECK_RESULT(UseNameForFuncTypeVar(module_, &func->decl.type_var));
+ CHECK_RESULT(UseNameForFuncTypeVar(&func->decl.type_var));
}
MakeTypeBindingReverseMapping(func->decl.sig.param_types,
@@ -297,23 +340,23 @@ Result NameApplier::VisitFunc(Index func_index, Func* func) {
Result NameApplier::VisitExport(Index export_index, Export* export_) {
if (export_->kind == ExternalKind::Func) {
- UseNameForFuncVar(module_, &export_->var);
+ UseNameForFuncVar(&export_->var);
}
return Result::Ok;
}
Result NameApplier::VisitElemSegment(Index elem_segment_index,
ElemSegment* segment) {
- CHECK_RESULT(UseNameForTableVar(module_, &segment->table_var));
+ CHECK_RESULT(UseNameForTableVar(&segment->table_var));
for (Var& var : segment->vars) {
- CHECK_RESULT(UseNameForFuncVar(module_, &var));
+ CHECK_RESULT(UseNameForFuncVar(&var));
}
return Result::Ok;
}
Result NameApplier::VisitDataSegment(Index data_segment_index,
DataSegment* segment) {
- CHECK_RESULT(UseNameForMemoryVar(module_, &segment->memory_var));
+ CHECK_RESULT(UseNameForMemoryVar(&segment->memory_var));
return Result::Ok;
}
diff --git a/src/ir.cc b/src/ir.cc
index cc7b8f48..b47d848e 100644
--- a/src/ir.cc
+++ b/src/ir.cc
@@ -108,6 +108,13 @@ Memory* Module::GetMemory(const Var& var) {
return memories[index];
}
+Exception* Module::GetExcept(const Var& var) const {
+ Index index = GetExceptIndex(var);
+ if (index >= excepts.size())
+ return nullptr;
+ return excepts[index];
+}
+
const FuncType* Module::GetFuncType(const Var& var) const {
return const_cast<Module*>(this)->GetFuncType(var);
}
diff --git a/src/ir.h b/src/ir.h
index 058da8e9..64761c59 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -507,6 +507,7 @@ struct Module {
const Global* GetGlobal(const Var&) const;
Global* GetGlobal(const Var&);
const Export* GetExport(const StringSlice&) const;
+ Exception* GetExcept(const Var&) const;
Index GetExceptIndex(const Var&) const;
Location loc;
diff --git a/src/wat-writer.cc b/src/wat-writer.cc
index 3a0e0610..0c025777 100644
--- a/src/wat-writer.cc
+++ b/src/wat-writer.cc
@@ -133,6 +133,8 @@ class WatWriter {
void WriteFunc(const Module* module, const Func* func);
void WriteBeginGlobal(const Global* global);
void WriteGlobal(const Global* global);
+ void WriteBeginException(const Exception* except);
+ void WriteException(const Exception* except);
void WriteLimits(const Limits* limits);
void WriteTable(const Table* table);
void WriteElemSegment(const ElemSegment* segment);
@@ -570,6 +572,11 @@ void WatWriter::WriteExpr(const Expr* expr) {
WritePutsNewline(Opcode::Nop_Opcode.GetName());
break;
+ case ExprType::Rethrow:
+ WritePutsSpace(Opcode::Rethrow_Opcode.GetName());
+ WriteBrVar(&expr->As<RethrowExpr>()->var, NextChar::Newline);
+ break;
+
case ExprType::Return:
WritePutsNewline(Opcode::Return_Opcode.GetName());
break;
@@ -604,6 +611,32 @@ void WatWriter::WriteExpr(const Expr* expr) {
WriteVar(&expr->As<TeeLocalExpr>()->var, NextChar::Newline);
break;
+ case ExprType::Throw:
+ WritePutsSpace(Opcode::Throw_Opcode.GetName());
+ WriteVar(&expr->As<ThrowExpr>()->var, NextChar::Newline);
+ break;
+
+ case ExprType::TryBlock: {
+ auto try_ = expr->As<TryExpr>();
+ WriteBeginBlock(LabelType::Try, try_->block,
+ Opcode::Try_Opcode.GetName());
+ WriteExprList(try_->block->first);
+ for (const Catch* catch_ : try_->catches) {
+ Dedent();
+ if (catch_->IsCatchAll()) {
+ WritePutsNewline(Opcode::CatchAll_Opcode.GetName());
+ } else {
+ WritePutsSpace(Opcode::Catch_Opcode.GetName());
+ WriteVar(&catch_->var, NextChar::Newline);
+ }
+ Indent();
+ label_stack_.back().label_type = LabelType::Catch;
+ WriteExprList(catch_->first);
+ }
+ WriteEndBlock();
+ break;
+ }
+
case ExprType::Unary:
WritePutsNewline(expr->As<UnaryExpr>()->opcode.GetName());
break;
@@ -931,6 +964,17 @@ void WatWriter::WriteGlobal(const Global* global) {
WriteCloseNewline();
}
+void WatWriter::WriteBeginException(const Exception* except) {
+ WriteOpenSpace("except");
+ WriteName(&except->name, NextChar::Space);
+ WriteTypes(except->sig, nullptr);
+}
+
+void WatWriter::WriteException(const Exception* except) {
+ WriteBeginException(except);
+ WriteCloseNewline();
+}
+
void WatWriter::WriteLimits(const Limits* limits) {
Writef("%" PRIu64, limits->initial);
if (limits->has_max)
@@ -1003,8 +1047,8 @@ void WatWriter::WriteImport(const Import* import) {
break;
case ExternalKind::Except:
- // TODO(karlschimpf) Define
- WABT_FATAL("WriteImport(except) not implemented");
+ WriteBeginException(import->except);
+ WriteCloseSpace();
break;
}
WriteCloseNewline();
@@ -1053,8 +1097,7 @@ Result WatWriter::WriteModule(const Module* module) {
WriteImport(field->import);
break;
case ModuleFieldType::Except:
- // TODO(karlschimpf) Define
- WABT_FATAL("WriteModule(except) not implemented");
+ WriteException(field->except);
break;
case ModuleFieldType::Export:
WriteExport(field->export_);
@@ -1122,7 +1165,7 @@ void WatWriter::BuildExportMaps() {
}
case ExternalKind::Except:
- WABT_FATAL("BuildExportMaps(except) not implemented");
+ // TODO(karlschimpf): Build for inline exceptions.
break;
}
}