summaryrefslogtreecommitdiff
path: root/src/parser/context-decls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/context-decls.cpp')
-rw-r--r--src/parser/context-decls.cpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/parser/context-decls.cpp b/src/parser/context-decls.cpp
new file mode 100644
index 000000000..f668c67ae
--- /dev/null
+++ b/src/parser/context-decls.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2023 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "contexts.h"
+
+namespace wasm::WATParser {
+
+namespace {
+
+void applyImportNames(Importable& item, ImportNames* names) {
+ if (names) {
+ item.module = names->mod;
+ item.base = names->nm;
+ }
+}
+
+Result<> addExports(ParseInput& in,
+ Module& wasm,
+ const Named* item,
+ const std::vector<Name>& exports,
+ ExternalKind kind) {
+ for (auto name : exports) {
+ if (wasm.getExportOrNull(name)) {
+ // TODO: Fix error location
+ return in.err("repeated export name");
+ }
+ wasm.addExport(Builder(wasm).makeExport(name, item->name, kind));
+ }
+ return Ok{};
+}
+
+} // anonymous namespace
+
+Result<Function*>
+ParseDeclsCtx::addFuncDecl(Index pos, Name name, ImportNames* importNames) {
+ auto f = std::make_unique<Function>();
+ if (name.is()) {
+ if (wasm.getFunctionOrNull(name)) {
+ // TDOO: if the existing function is not explicitly named, fix its name
+ // and continue.
+ return in.err(pos, "repeated function name");
+ }
+ f->setExplicitName(name);
+ } else {
+ name = (importNames ? "fimport$" : "") + std::to_string(funcCounter++);
+ name = Names::getValidFunctionName(wasm, name);
+ f->name = name;
+ }
+ applyImportNames(*f, importNames);
+ return wasm.addFunction(std::move(f));
+}
+
+Result<> ParseDeclsCtx::addFunc(Name name,
+ const std::vector<Name>& exports,
+ ImportNames* import,
+ TypeUseT type,
+ std::optional<LocalsT>,
+ std::optional<InstrsT>,
+ Index pos) {
+ if (import && hasNonImport) {
+ return in.err(pos, "import after non-import");
+ }
+ auto f = addFuncDecl(pos, name, import);
+ CHECK_ERR(f);
+ CHECK_ERR(addExports(in, wasm, *f, exports, ExternalKind::Function));
+ funcDefs.push_back({name, pos, Index(funcDefs.size())});
+ return Ok{};
+}
+
+Result<Memory*> ParseDeclsCtx::addMemoryDecl(Index pos,
+ Name name,
+ ImportNames* importNames,
+ MemType type) {
+ auto m = std::make_unique<Memory>();
+ m->indexType = type.type;
+ m->initial = type.limits.initial;
+ m->max = type.limits.max;
+ m->shared = type.shared;
+ if (name) {
+ // TODO: if the existing memory is not explicitly named, fix its name
+ // and continue.
+ if (wasm.getMemoryOrNull(name)) {
+ return in.err(pos, "repeated memory name");
+ }
+ m->setExplicitName(name);
+ } else {
+ name = (importNames ? "mimport$" : "") + std::to_string(memoryCounter++);
+ name = Names::getValidMemoryName(wasm, name);
+ m->name = name;
+ }
+ applyImportNames(*m, importNames);
+ return wasm.addMemory(std::move(m));
+}
+
+Result<> ParseDeclsCtx::addMemory(Name name,
+ const std::vector<Name>& exports,
+ ImportNames* import,
+ MemType type,
+ Index pos) {
+ if (import && hasNonImport) {
+ return in.err(pos, "import after non-import");
+ }
+ auto m = addMemoryDecl(pos, name, import, type);
+ CHECK_ERR(m);
+ CHECK_ERR(addExports(in, wasm, *m, exports, ExternalKind::Memory));
+ memoryDefs.push_back({name, pos, Index(memoryDefs.size())});
+ return Ok{};
+}
+
+Result<> ParseDeclsCtx::addImplicitData(DataStringT&& data) {
+ auto& mem = *wasm.memories.back();
+ auto d = std::make_unique<DataSegment>();
+ d->memory = mem.name;
+ d->isPassive = false;
+ d->offset = Builder(wasm).makeConstPtr(0, mem.indexType);
+ d->data = std::move(data);
+ d->name = Names::getValidDataSegmentName(wasm, "implicit-data");
+ wasm.addDataSegment(std::move(d));
+ return Ok{};
+}
+
+Result<Global*>
+ParseDeclsCtx::addGlobalDecl(Index pos, Name name, ImportNames* importNames) {
+ auto g = std::make_unique<Global>();
+ if (name) {
+ if (wasm.getGlobalOrNull(name)) {
+ // TODO: if the existing global is not explicitly named, fix its name
+ // and continue.
+ return in.err(pos, "repeated global name");
+ }
+ g->setExplicitName(name);
+ } else {
+ name = (importNames ? "gimport$" : "") + std::to_string(globalCounter++);
+ name = Names::getValidGlobalName(wasm, name);
+ g->name = name;
+ }
+ applyImportNames(*g, importNames);
+ return wasm.addGlobal(std::move(g));
+}
+
+Result<> ParseDeclsCtx::addGlobal(Name name,
+ const std::vector<Name>& exports,
+ ImportNames* import,
+ GlobalTypeT,
+ std::optional<ExprT>,
+ Index pos) {
+ if (import && hasNonImport) {
+ return in.err(pos, "import after non-import");
+ }
+ auto g = addGlobalDecl(pos, name, import);
+ CHECK_ERR(g);
+ CHECK_ERR(addExports(in, wasm, *g, exports, ExternalKind::Global));
+ globalDefs.push_back({name, pos, Index(globalDefs.size())});
+ return Ok{};
+}
+
+Result<> ParseDeclsCtx::addData(Name name,
+ MemoryIdxT*,
+ std::optional<ExprT>,
+ std::vector<char>&& data,
+ Index pos) {
+ auto d = std::make_unique<DataSegment>();
+ if (name) {
+ if (wasm.getDataSegmentOrNull(name)) {
+ // TODO: if the existing segment is not explicitly named, fix its name
+ // and continue.
+ return in.err(pos, "repeated data segment name");
+ }
+ d->setExplicitName(name);
+ } else {
+ name = std::to_string(dataCounter++);
+ name = Names::getValidDataSegmentName(wasm, name);
+ d->name = name;
+ }
+ d->data = std::move(data);
+ dataDefs.push_back({name, pos, Index(wasm.dataSegments.size())});
+ wasm.addDataSegment(std::move(d));
+ return Ok{};
+}
+
+} // namespace wasm::WATParser