summaryrefslogtreecommitdiff
path: root/src/wasm/parsing.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-03-01 20:48:30 +0000
committerGitHub <noreply@github.com>2021-03-01 12:48:30 -0800
commitd137e7f8fb5ae943b115885f256ad57bfae67f6b (patch)
treef41ea4ba34bbc7aad585a96388ac322fc27f4c95 /src/wasm/parsing.cpp
parent575aec37f3fe4793b1d16275426c6369864e1540 (diff)
downloadbinaryen-d137e7f8fb5ae943b115885f256ad57bfae67f6b.tar.gz
binaryen-d137e7f8fb5ae943b115885f256ad57bfae67f6b.tar.bz2
binaryen-d137e7f8fb5ae943b115885f256ad57bfae67f6b.zip
Refactor code out of parsing.h NFC. (#3635)
Most of it goes in a new parsing.cpp. One method was only used in the s-expression's parser, and has been moved there.
Diffstat (limited to 'src/wasm/parsing.cpp')
-rw-r--r--src/wasm/parsing.cpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/wasm/parsing.cpp b/src/wasm/parsing.cpp
new file mode 100644
index 000000000..dc0d332d9
--- /dev/null
+++ b/src/wasm/parsing.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2021 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 "parsing.h"
+#include "ir/branch-utils.h"
+
+namespace wasm {
+
+void ParseException::dump(std::ostream& o) const {
+ Colors::magenta(o);
+ o << "[";
+ Colors::red(o);
+ o << "parse exception: ";
+ Colors::green(o);
+ o << text;
+ if (line != size_t(-1)) {
+ Colors::normal(o);
+ o << " (at " << line << ":" << col << ")";
+ }
+ Colors::magenta(o);
+ o << "]";
+ Colors::normal(o);
+}
+
+void MapParseException::dump(std::ostream& o) const {
+ Colors::magenta(o);
+ o << "[";
+ Colors::red(o);
+ o << "map parse exception: ";
+ Colors::green(o);
+ o << text;
+ Colors::magenta(o);
+ o << "]";
+ Colors::normal(o);
+}
+
+// UniqueNameMapper
+
+Name UniqueNameMapper::getPrefixedName(Name prefix) {
+ if (reverseLabelMapping.find(prefix) == reverseLabelMapping.end()) {
+ return prefix;
+ }
+ // make sure to return a unique name not already on the stack
+ while (1) {
+ Name ret = Name(prefix.str + std::to_string(otherIndex++));
+ if (reverseLabelMapping.find(ret) == reverseLabelMapping.end()) {
+ return ret;
+ }
+ }
+}
+
+Name UniqueNameMapper::pushLabelName(Name sName) {
+ Name name = getPrefixedName(sName);
+ labelStack.push_back(name);
+ labelMappings[sName].push_back(name);
+ reverseLabelMapping[name] = sName;
+ return name;
+}
+
+void UniqueNameMapper::popLabelName(Name name) {
+ assert(labelStack.back() == name);
+ labelStack.pop_back();
+ labelMappings[reverseLabelMapping[name]].pop_back();
+}
+
+Name UniqueNameMapper::sourceToUnique(Name sName) {
+ // DELEGATE_CALLER_TARGET is a fake target used to denote delegating to the
+ // caller. We do not need to modify it, as it has no definitions, only uses.
+ if (sName == DELEGATE_CALLER_TARGET) {
+ return DELEGATE_CALLER_TARGET;
+ }
+ if (labelMappings.find(sName) == labelMappings.end()) {
+ throw ParseException("bad label in sourceToUnique");
+ }
+ if (labelMappings[sName].empty()) {
+ throw ParseException("use of popped label in sourceToUnique");
+ }
+ return labelMappings[sName].back();
+}
+
+Name UniqueNameMapper::uniqueToSource(Name name) {
+ if (reverseLabelMapping.find(name) == reverseLabelMapping.end()) {
+ throw ParseException("label mismatch in uniqueToSource");
+ }
+ return reverseLabelMapping[name];
+}
+
+void UniqueNameMapper::clear() {
+ labelStack.clear();
+ labelMappings.clear();
+ reverseLabelMapping.clear();
+}
+
+void UniqueNameMapper::uniquify(Expression* curr) {
+ struct Walker
+ : public ControlFlowWalker<Walker, UnifiedExpressionVisitor<Walker>> {
+ UniqueNameMapper mapper;
+
+ static void doPreVisitControlFlow(Walker* self, Expression** currp) {
+ BranchUtils::operateOnScopeNameDefs(*currp, [&](Name& name) {
+ if (name.is()) {
+ name = self->mapper.pushLabelName(name);
+ }
+ });
+ }
+
+ static void doPostVisitControlFlow(Walker* self, Expression** currp) {
+ BranchUtils::operateOnScopeNameDefs(*currp, [&](Name& name) {
+ if (name.is()) {
+ self->mapper.popLabelName(name);
+ }
+ });
+ }
+
+ void visitExpression(Expression* curr) {
+ BranchUtils::operateOnScopeNameUses(curr, [&](Name& name) {
+ if (name.is()) {
+ name = mapper.sourceToUnique(name);
+ }
+ });
+ }
+ };
+
+ Walker walker;
+ walker.walk(curr);
+}
+
+} // namespace wasm