diff options
Diffstat (limited to 'src')
58 files changed, 1251 insertions, 1244 deletions
diff --git a/src/abi/js.h b/src/abi/js.h index 60531803d..735f71af7 100644 --- a/src/abi/js.h +++ b/src/abi/js.h @@ -37,8 +37,6 @@ inline std::string getLegalizationPass(LegalizationLevel level) { namespace wasm2js { -using IString = cashew::IString; - extern IString SCRATCH_LOAD_I32; extern IString SCRATCH_STORE_I32; extern IString SCRATCH_LOAD_F32; diff --git a/src/asmjs/shared-constants.cpp b/src/asmjs/shared-constants.cpp index 6cb350f9f..57b9c4f87 100644 --- a/src/asmjs/shared-constants.cpp +++ b/src/asmjs/shared-constants.cpp @@ -18,8 +18,6 @@ namespace wasm { -using IString = cashew::IString; - IString TOPMOST("topmost"); IString INT8ARRAY("Int8Array"); IString INT16ARRAY("Int16Array"); diff --git a/src/asmjs/shared-constants.h b/src/asmjs/shared-constants.h index 753b34c5d..e199b1361 100644 --- a/src/asmjs/shared-constants.h +++ b/src/asmjs/shared-constants.h @@ -17,12 +17,10 @@ #ifndef wasm_asmjs_shared_constants_h #define wasm_asmjs_shared_constants_h -#include "emscripten-optimizer/istring.h" +#include "support/istring.h" namespace wasm { -using IString = cashew::IString; - extern IString TOPMOST; extern IString INT8ARRAY; extern IString INT16ARRAY; diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index f2908920c..dccc52131 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -100,7 +100,7 @@ BinaryenLiteral toBinaryenLiteral(Literal x) { } } if (heapType.isSignature()) { - ret.func = x.getFunc().c_str(); + ret.func = x.getFunc().str.data(); return ret; } assert(x.isData()); @@ -1892,7 +1892,7 @@ BinaryenExpressionRef BinaryenExpressionCopy(BinaryenExpressionRef expr, const char* BinaryenBlockGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<Block>()); - return static_cast<Block*>(expression)->name.c_str(); + return static_cast<Block*>(expression)->name.str.data(); } void BinaryenBlockSetName(BinaryenExpressionRef expr, const char* name) { auto* expression = (Expression*)expr; @@ -1987,7 +1987,7 @@ void BinaryenIfSetIfFalse(BinaryenExpressionRef expr, const char* BinaryenLoopGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<Loop>()); - return static_cast<Loop*>(expression)->name.c_str(); + return static_cast<Loop*>(expression)->name.str.data(); } void BinaryenLoopSetName(BinaryenExpressionRef expr, const char* name) { auto* expression = (Expression*)expr; @@ -2011,7 +2011,7 @@ void BinaryenLoopSetBody(BinaryenExpressionRef expr, const char* BinaryenBreakGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<Break>()); - return static_cast<Break*>(expression)->name.c_str(); + return static_cast<Break*>(expression)->name.str.data(); } void BinaryenBreakSetName(BinaryenExpressionRef expr, const char* name) { auto* expression = (Expression*)expr; @@ -2054,7 +2054,7 @@ const char* BinaryenSwitchGetNameAt(BinaryenExpressionRef expr, auto* expression = (Expression*)expr; assert(expression->is<Switch>()); assert(index < static_cast<Switch*>(expression)->targets.size()); - return static_cast<Switch*>(expression)->targets[index].c_str(); + return static_cast<Switch*>(expression)->targets[index].str.data(); } void BinaryenSwitchSetNameAt(BinaryenExpressionRef expr, BinaryenIndex index, @@ -2087,12 +2087,12 @@ const char* BinaryenSwitchRemoveNameAt(BinaryenExpressionRef expr, BinaryenIndex index) { auto* expression = (Expression*)expr; assert(expression->is<Switch>()); - return static_cast<Switch*>(expression)->targets.removeAt(index).c_str(); + return static_cast<Switch*>(expression)->targets.removeAt(index).str.data(); } const char* BinaryenSwitchGetDefaultName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<Switch>()); - return static_cast<Switch*>(expression)->default_.c_str(); + return static_cast<Switch*>(expression)->default_.str.data(); } void BinaryenSwitchSetDefaultName(BinaryenExpressionRef expr, const char* name) { @@ -2129,7 +2129,7 @@ void BinaryenSwitchSetValue(BinaryenExpressionRef expr, const char* BinaryenCallGetTarget(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<Call>()); - return static_cast<Call*>(expression)->target.c_str(); + return static_cast<Call*>(expression)->target.str.data(); } void BinaryenCallSetTarget(BinaryenExpressionRef expr, const char* target) { auto* expression = (Expression*)expr; @@ -2210,7 +2210,7 @@ void BinaryenCallIndirectSetTarget(BinaryenExpressionRef expr, const char* BinaryenCallIndirectGetTable(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<CallIndirect>()); - return static_cast<CallIndirect*>(expression)->table.c_str(); + return static_cast<CallIndirect*>(expression)->table.str.data(); } void BinaryenCallIndirectSetTable(BinaryenExpressionRef expr, const char* table) { @@ -2350,7 +2350,7 @@ void BinaryenLocalSetSetValue(BinaryenExpressionRef expr, const char* BinaryenGlobalGetGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<GlobalGet>()); - return static_cast<GlobalGet*>(expression)->name.c_str(); + return static_cast<GlobalGet*>(expression)->name.str.data(); } void BinaryenGlobalGetSetName(BinaryenExpressionRef expr, const char* name) { auto* expression = (Expression*)expr; @@ -2362,7 +2362,7 @@ void BinaryenGlobalGetSetName(BinaryenExpressionRef expr, const char* name) { const char* BinaryenGlobalSetGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<GlobalSet>()); - return static_cast<GlobalSet*>(expression)->name.c_str(); + return static_cast<GlobalSet*>(expression)->name.str.data(); } void BinaryenGlobalSetSetName(BinaryenExpressionRef expr, const char* name) { auto* expression = (Expression*)expr; @@ -2386,7 +2386,7 @@ void BinaryenGlobalSetSetValue(BinaryenExpressionRef expr, const char* BinaryenTableGetGetTable(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<TableGet>()); - return static_cast<TableGet*>(expression)->table.c_str(); + return static_cast<TableGet*>(expression)->table.str.data(); } void BinaryenTableGetSetTable(BinaryenExpressionRef expr, const char* table) { auto* expression = (Expression*)expr; @@ -2410,7 +2410,7 @@ void BinaryenTableGetSetIndex(BinaryenExpressionRef expr, const char* BinaryenTableSetGetTable(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<TableSet>()); - return static_cast<TableSet*>(expression)->table.c_str(); + return static_cast<TableSet*>(expression)->table.str.data(); } void BinaryenTableSetSetTable(BinaryenExpressionRef expr, const char* table) { auto* expression = (Expression*)expr; @@ -2446,7 +2446,7 @@ void BinaryenTableSetSetValue(BinaryenExpressionRef expr, const char* BinaryenTableSizeGetTable(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<TableSize>()); - return static_cast<TableSize*>(expression)->table.c_str(); + return static_cast<TableSize*>(expression)->table.str.data(); } void BinaryenTableSizeSetTable(BinaryenExpressionRef expr, const char* table) { auto* expression = (Expression*)expr; @@ -2458,7 +2458,7 @@ void BinaryenTableSizeSetTable(BinaryenExpressionRef expr, const char* table) { const char* BinaryenTableGrowGetTable(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<TableGrow>()); - return static_cast<TableGrow*>(expression)->table.c_str(); + return static_cast<TableGrow*>(expression)->table.str.data(); } void BinaryenTableGrowSetTable(BinaryenExpressionRef expr, const char* table) { auto* expression = (Expression*)expr; @@ -3547,7 +3547,7 @@ void BinaryenRefAsSetValue(BinaryenExpressionRef expr, const char* BinaryenRefFuncGetFunc(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<RefFunc>()); - return static_cast<RefFunc*>(expression)->func.c_str(); + return static_cast<RefFunc*>(expression)->func.str.data(); } void BinaryenRefFuncSetFunc(BinaryenExpressionRef expr, const char* funcName) { auto* expression = (Expression*)expr; @@ -3581,7 +3581,7 @@ void BinaryenRefEqSetRight(BinaryenExpressionRef expr, const char* BinaryenTryGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<Try>()); - return static_cast<Try*>(expression)->name.c_str(); + return static_cast<Try*>(expression)->name.str.data(); } void BinaryenTrySetName(BinaryenExpressionRef expr, const char* name) { auto* expression = (Expression*)expr; @@ -3615,7 +3615,7 @@ const char* BinaryenTryGetCatchTagAt(BinaryenExpressionRef expr, auto* expression = (Expression*)expr; assert(expression->is<Try>()); assert(index < static_cast<Try*>(expression)->catchTags.size()); - return static_cast<Try*>(expression)->catchTags[index].c_str(); + return static_cast<Try*>(expression)->catchTags[index].str.data(); } void BinaryenTrySetCatchTagAt(BinaryenExpressionRef expr, BinaryenIndex index, @@ -3648,7 +3648,7 @@ const char* BinaryenTryRemoveCatchTagAt(BinaryenExpressionRef expr, BinaryenIndex index) { auto* expression = (Expression*)expr; assert(expression->is<Try>()); - return static_cast<Try*>(expression)->catchTags.removeAt(index).c_str(); + return static_cast<Try*>(expression)->catchTags.removeAt(index).str.data(); } BinaryenExpressionRef BinaryenTryGetCatchBodyAt(BinaryenExpressionRef expr, BinaryenIndex index) { @@ -3699,7 +3699,7 @@ bool BinaryenTryHasCatchAll(BinaryenExpressionRef expr) { const char* BinaryenTryGetDelegateTarget(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<Try>()); - return static_cast<Try*>(expression)->delegateTarget.c_str(); + return static_cast<Try*>(expression)->delegateTarget.str.data(); } void BinaryenTrySetDelegateTarget(BinaryenExpressionRef expr, const char* delegateTarget) { @@ -3716,7 +3716,7 @@ bool BinaryenTryIsDelegate(BinaryenExpressionRef expr) { const char* BinaryenThrowGetTag(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<Throw>()); - return static_cast<Throw*>(expression)->tag.c_str(); + return static_cast<Throw*>(expression)->tag.str.data(); } void BinaryenThrowSetTag(BinaryenExpressionRef expr, const char* tagName) { auto* expression = (Expression*)expr; @@ -3773,7 +3773,7 @@ BinaryenExpressionRef BinaryenThrowRemoveOperandAt(BinaryenExpressionRef expr, const char* BinaryenRethrowGetTarget(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<Rethrow>()); - return static_cast<Rethrow*>(expression)->target.c_str(); + return static_cast<Rethrow*>(expression)->target.str.data(); } void BinaryenRethrowSetTarget(BinaryenExpressionRef expr, const char* target) { auto* expression = (Expression*)expr; @@ -4020,7 +4020,7 @@ void BinaryenBrOnSetOp(BinaryenExpressionRef expr, BinaryenOp op) { const char* BinaryenBrOnGetName(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<BrOn>()); - return static_cast<BrOn*>(expression)->name.c_str(); + return static_cast<BrOn*>(expression)->name.str.data(); } void BinaryenBrOnSetName(BinaryenExpressionRef expr, const char* nameStr) { auto* expression = (Expression*)expr; @@ -4453,7 +4453,7 @@ void BinaryenStringNewSetEnd(BinaryenExpressionRef expr, const char* BinaryenStringConstGetString(BinaryenExpressionRef expr) { auto* expression = (Expression*)expr; assert(expression->is<StringConst>()); - return static_cast<StringConst*>(expression)->string.c_str(); + return static_cast<StringConst*>(expression)->string.str.data(); } void BinaryenStringConstSetString(BinaryenExpressionRef expr, const char* stringStr) { @@ -5171,7 +5171,7 @@ const char* BinaryenElementSegmentGetData(BinaryenElementSegmentRef elem, if (data[dataId]->is<RefNull>()) { return NULL; } else if (auto* get = data[dataId]->dynCast<RefFunc>()) { - return get->func.c_str(); + return get->func.str.data(); } else { Fatal() << "invalid expression in segment data."; } @@ -5265,7 +5265,7 @@ BinaryenIndex BinaryenMemoryGetInitial(BinaryenModuleRef module, const char* name) { // Maintaining compatibility for instructions with a single memory if (name == nullptr && module->memories.size() == 1) { - name = module->memories[0]->name.c_str(); + name = module->memories[0]->name.str.data(); } auto* memory = ((Module*)module)->getMemoryOrNull(name); if (memory == nullptr) { @@ -5276,7 +5276,7 @@ BinaryenIndex BinaryenMemoryGetInitial(BinaryenModuleRef module, bool BinaryenMemoryHasMax(BinaryenModuleRef module, const char* name) { // Maintaining compatibility for instructions with a single memory if (name == nullptr && module->memories.size() == 1) { - name = module->memories[0]->name.c_str(); + name = module->memories[0]->name.str.data(); } auto* memory = ((Module*)module)->getMemoryOrNull(name); if (memory == nullptr) { @@ -5287,7 +5287,7 @@ bool BinaryenMemoryHasMax(BinaryenModuleRef module, const char* name) { BinaryenIndex BinaryenMemoryGetMax(BinaryenModuleRef module, const char* name) { // Maintaining compatibility for instructions with a single memory if (name == nullptr && module->memories.size() == 1) { - name = module->memories[0]->name.c_str(); + name = module->memories[0]->name.str.data(); } auto* memory = ((Module*)module)->getMemoryOrNull(name); if (memory == nullptr) { @@ -5299,14 +5299,14 @@ const char* BinaryenMemoryImportGetModule(BinaryenModuleRef module, const char* name) { // Maintaining compatibility for instructions with a single memory if (name == nullptr && module->memories.size() == 1) { - name = module->memories[0]->name.c_str(); + name = module->memories[0]->name.str.data(); } auto* memory = ((Module*)module)->getMemoryOrNull(name); if (memory == nullptr) { Fatal() << "invalid memory '" << name << "'."; } if (memory->imported()) { - return memory->module.c_str(); + return memory->module.str.data(); } else { return ""; } @@ -5315,14 +5315,14 @@ const char* BinaryenMemoryImportGetBase(BinaryenModuleRef module, const char* name) { // Maintaining compatibility for instructions with a single memory if (name == nullptr && module->memories.size() == 1) { - name = module->memories[0]->name.c_str(); + name = module->memories[0]->name.str.data(); } auto* memory = ((Module*)module)->getMemoryOrNull(name); if (memory == nullptr) { Fatal() << "invalid memory '" << name << "'."; } if (memory->imported()) { - return memory->base.c_str(); + return memory->base.str.data(); } else { return ""; } @@ -5330,7 +5330,7 @@ const char* BinaryenMemoryImportGetBase(BinaryenModuleRef module, bool BinaryenMemoryIsShared(BinaryenModuleRef module, const char* name) { // Maintaining compatibility for instructions with a single memory if (name == nullptr && module->memories.size() == 1) { - name = module->memories[0]->name.c_str(); + name = module->memories[0]->name.str.data(); } auto* memory = ((Module*)module)->getMemoryOrNull(name); if (memory == nullptr) { @@ -5341,7 +5341,7 @@ bool BinaryenMemoryIsShared(BinaryenModuleRef module, const char* name) { bool BinaryenMemoryIs64(BinaryenModuleRef module, const char* name) { // Maintaining compatibility for instructions with a single memory if (name == nullptr && module->memories.size() == 1) { - name = module->memories[0]->name.c_str(); + name = module->memories[0]->name.str.data(); } auto* memory = ((Module*)module)->getMemoryOrNull(name); if (memory == nullptr) { @@ -5491,7 +5491,7 @@ const char* BinaryenGetPassArgument(const char* key) { return nullptr; } // internalize the string so it remains valid while the module is - return Name(it->second).c_str(); + return Name(it->second).str.data(); } void BinaryenSetPassArgument(const char* key, const char* value) { @@ -5726,7 +5726,7 @@ const char* BinaryenModuleGetDebugInfoFileName(BinaryenModuleRef module, // TODO: add BinaryenFunctionGetType const char* BinaryenFunctionGetName(BinaryenFunctionRef func) { - return ((Function*)func)->name.c_str(); + return ((Function*)func)->name.str.data(); } BinaryenType BinaryenFunctionGetParams(BinaryenFunctionRef func) { return ((Function*)func)->getParams().getID(); @@ -5752,7 +5752,7 @@ bool BinaryenFunctionHasLocalName(BinaryenFunctionRef func, } const char* BinaryenFunctionGetLocalName(BinaryenFunctionRef func, BinaryenIndex index) { - return ((Function*)func)->getLocalName(index).str; + return ((Function*)func)->getLocalName(index).str.data(); } void BinaryenFunctionSetLocalName(BinaryenFunctionRef func, BinaryenIndex index, @@ -5802,7 +5802,7 @@ void BinaryenFunctionSetDebugLocation(BinaryenFunctionRef func, // const char* BinaryenTableGetName(BinaryenTableRef table) { - return ((Table*)table)->name.c_str(); + return ((Table*)table)->name.str.data(); } void BinaryenTableSetName(BinaryenTableRef table, const char* name) { ((Table*)table)->name = name; @@ -5827,14 +5827,14 @@ void BinaryenTableSetMax(BinaryenTableRef table, BinaryenIndex max) { // =========== ElementSegment operations =========== // const char* BinaryenElementSegmentGetName(BinaryenElementSegmentRef elem) { - return ((ElementSegment*)elem)->name.c_str(); + return ((ElementSegment*)elem)->name.str.data(); } void BinaryenElementSegmentSetName(BinaryenElementSegmentRef elem, const char* name) { ((ElementSegment*)elem)->name = name; } const char* BinaryenElementSegmentGetTable(BinaryenElementSegmentRef elem) { - return ((ElementSegment*)elem)->table.c_str(); + return ((ElementSegment*)elem)->table.str.data(); } void BinaryenElementSegmentSetTable(BinaryenElementSegmentRef elem, const char* table) { @@ -5849,7 +5849,7 @@ bool BinaryenElementSegmentIsPassive(BinaryenElementSegmentRef elem) { // const char* BinaryenGlobalGetName(BinaryenGlobalRef global) { - return ((Global*)global)->name.c_str(); + return ((Global*)global)->name.str.data(); } BinaryenType BinaryenGlobalGetType(BinaryenGlobalRef global) { return ((Global*)global)->type.getID(); @@ -5866,7 +5866,7 @@ BinaryenExpressionRef BinaryenGlobalGetInitExpr(BinaryenGlobalRef global) { // const char* BinaryenTagGetName(BinaryenTagRef tag) { - return ((Tag*)tag)->name.c_str(); + return ((Tag*)tag)->name.str.data(); } BinaryenType BinaryenTagGetParams(BinaryenTagRef tag) { return ((Tag*)tag)->sig.params.getID(); @@ -5883,7 +5883,7 @@ BinaryenType BinaryenTagGetResults(BinaryenTagRef tag) { const char* BinaryenFunctionImportGetModule(BinaryenFunctionRef import) { auto* func = (Function*)import; if (func->imported()) { - return func->module.c_str(); + return func->module.str.data(); } else { return ""; } @@ -5891,7 +5891,7 @@ const char* BinaryenFunctionImportGetModule(BinaryenFunctionRef import) { const char* BinaryenTableImportGetModule(BinaryenTableRef import) { auto* table = (Table*)import; if (table->imported()) { - return table->module.c_str(); + return table->module.str.data(); } else { return ""; } @@ -5899,7 +5899,7 @@ const char* BinaryenTableImportGetModule(BinaryenTableRef import) { const char* BinaryenGlobalImportGetModule(BinaryenGlobalRef import) { auto* global = (Global*)import; if (global->imported()) { - return global->module.c_str(); + return global->module.str.data(); } else { return ""; } @@ -5907,7 +5907,7 @@ const char* BinaryenGlobalImportGetModule(BinaryenGlobalRef import) { const char* BinaryenTagImportGetModule(BinaryenTagRef import) { auto* tag = (Tag*)import; if (tag->imported()) { - return tag->module.c_str(); + return tag->module.str.data(); } else { return ""; } @@ -5915,7 +5915,7 @@ const char* BinaryenTagImportGetModule(BinaryenTagRef import) { const char* BinaryenFunctionImportGetBase(BinaryenFunctionRef import) { auto* func = (Function*)import; if (func->imported()) { - return func->base.c_str(); + return func->base.str.data(); } else { return ""; } @@ -5923,7 +5923,7 @@ const char* BinaryenFunctionImportGetBase(BinaryenFunctionRef import) { const char* BinaryenTableImportGetBase(BinaryenTableRef import) { auto* table = (Table*)import; if (table->imported()) { - return table->base.c_str(); + return table->base.str.data(); } else { return ""; } @@ -5931,7 +5931,7 @@ const char* BinaryenTableImportGetBase(BinaryenTableRef import) { const char* BinaryenGlobalImportGetBase(BinaryenGlobalRef import) { auto* global = (Global*)import; if (global->imported()) { - return global->base.c_str(); + return global->base.str.data(); } else { return ""; } @@ -5939,7 +5939,7 @@ const char* BinaryenGlobalImportGetBase(BinaryenGlobalRef import) { const char* BinaryenTagImportGetBase(BinaryenTagRef import) { auto* tag = (Tag*)import; if (tag->imported()) { - return tag->base.c_str(); + return tag->base.str.data(); } else { return ""; } @@ -5953,10 +5953,10 @@ BinaryenExternalKind BinaryenExportGetKind(BinaryenExportRef export_) { return BinaryenExternalKind(((Export*)export_)->kind); } const char* BinaryenExportGetName(BinaryenExportRef export_) { - return ((Export*)export_)->name.c_str(); + return ((Export*)export_)->name.str.data(); } const char* BinaryenExportGetValue(BinaryenExportRef export_) { - return ((Export*)export_)->value.c_str(); + return ((Export*)export_)->value.str.data(); } // diff --git a/src/emscripten-optimizer/istring.h b/src/emscripten-optimizer/istring.h deleted file mode 100644 index 69df761fd..000000000 --- a/src/emscripten-optimizer/istring.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2015 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. - */ - -// Interned String type, 100% interned on creation. Comparisons are always just -// a pointer comparison - -#ifndef wasm_istring_h -#define wasm_istring_h - -#include <set> -#include <unordered_map> -#include <unordered_set> - -#include <assert.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "support/threads.h" -#include "support/utilities.h" - -namespace cashew { - -struct IString { - const char* str = nullptr; - - static size_t - hash_c(const char* str) { // see http://www.cse.yorku.ca/~oz/hash.html - unsigned int hash = 5381; - int c; - while ((c = *str++)) { - hash = ((hash << 5) + hash) ^ c; - } - return (size_t)hash; - } - - class CStringHash { - public: - size_t operator()(const char* str) const { return IString::hash_c(str); } - }; - class CStringEqual { - public: - bool operator()(const char* x, const char* y) const { - return strcmp(x, y) == 0; - } - }; - - IString() = default; - // if reuse=true, then input is assumed to remain alive; not copied - IString(const char* s, bool reuse = true) { - assert(s); - set(s, reuse); - } - - void set(const char* s, bool reuse = true) { - typedef std::unordered_set<const char*, CStringHash, CStringEqual> - StringSet; - // one global store of strings per thread, we must not access this - // in parallel - thread_local static StringSet strings; - - auto existing = strings.find(s); - - if (existing == strings.end()) { - // if the string isn't already known, we must use a single global - // storage location, guarded by a mutex, so each string is allocated - // exactly once - static std::mutex mutex; - std::unique_lock<std::mutex> lock(mutex); - // a single global set contains the actual strings, so we allocate each - // one exactly once. - static StringSet globalStrings; - auto globalExisting = globalStrings.find(s); - if (globalExisting == globalStrings.end()) { - if (!reuse) { - static std::vector<std::unique_ptr<std::string>> allocated; - allocated.emplace_back(wasm::make_unique<std::string>(s)); - s = allocated.back()->c_str(); // we'll never modify it, so this is ok - } - // insert into global set - globalStrings.insert(s); - } else { - s = *globalExisting; - } - // add the string to our thread-local set - strings.insert(s); - } else { - s = *existing; - } - - str = s; - } - - void set(const IString& s) { str = s.str; } - - void clear() { str = nullptr; } - - bool operator==(const IString& other) const { - // assert((str == other.str) == !strcmp(str, other.str)); - return str == other.str; // fast! - } - bool operator!=(const IString& other) const { - // assert((str == other.str) == !strcmp(str, other.str)); - return str != other.str; // fast! - } - bool operator<(const IString& other) const { - return strcmp(str ? str : "", other.str ? other.str : "") < 0; - } - - char operator[](int x) const { return str[x]; } - - bool operator!() const { // no string, or empty string - return !str || str[0] == 0; - } - - const char* c_str() const { return str; } - bool equals(const char* other) const { return !strcmp(str, other); } - - bool is() const { return str != nullptr; } - bool isNull() const { return str == nullptr; } - - const char* stripPrefix(const char* prefix) const { - const char* ptr = str; - while (true) { - if (*prefix == 0) { - return ptr; - } - if (*ptr == 0) { - return nullptr; - } - if (*ptr++ != *prefix++) { - return nullptr; - } - } - } - - bool startsWith(const char* prefix) const { - return stripPrefix(prefix) != nullptr; - } - bool startsWith(const IString& prefix) const { - return startsWith(prefix.str); - } - - size_t size() const { return str ? strlen(str) : 0; } -}; - -} // namespace cashew - -// Utilities for creating hashmaps/sets over IStrings - -namespace std { - -template<> struct hash<cashew::IString> { - size_t operator()(const cashew::IString& str) const { - return std::hash<size_t>{}(size_t(str.str)); - } -}; - -template<> struct equal_to<cashew::IString> { - bool operator()(const cashew::IString& x, const cashew::IString& y) const { - return x == y; - } -}; - -} // namespace std - -namespace cashew { - -// IStringSet - -class IStringSet : public std::unordered_set<IString> { - std::vector<char> data; - -public: - IStringSet() = default; - IStringSet(const char* init) { // comma-delimited list - int size = strlen(init) + 1; - data.resize(size); - char* curr = &data[0]; - strncpy(curr, init, size); - while (1) { - char* end = strchr(curr, ' '); - if (end) { - *end = 0; - } - insert(curr); - if (!end) { - break; - } - curr = end + 1; - } - } - - bool has(const IString& str) { return count(str) > 0; } -}; - -class IOrderedStringSet : public std::set<IString> { -public: - bool has(const IString& str) { return count(str) > 0; } -}; - -} // namespace cashew - -#endif // wasm_istring_h diff --git a/src/emscripten-optimizer/optimizer-shared.cpp b/src/emscripten-optimizer/optimizer-shared.cpp index 8208f6f47..9ca66441a 100644 --- a/src/emscripten-optimizer/optimizer-shared.cpp +++ b/src/emscripten-optimizer/optimizer-shared.cpp @@ -19,8 +19,6 @@ #include "optimizer.h" #include "support/safe_integer.h" -using namespace cashew; - IString JS_FLOAT_ZERO; IString SIMD_INT8X16_CHECK("SIMD_Int8x16_check"); diff --git a/src/emscripten-optimizer/optimizer.h b/src/emscripten-optimizer/optimizer.h index 132ff6fb8..9e5c7afe8 100644 --- a/src/emscripten-optimizer/optimizer.h +++ b/src/emscripten-optimizer/optimizer.h @@ -20,6 +20,7 @@ #include "simple_ast.h" using namespace cashew; +using IString = wasm::IString; extern IString JS_FLOAT_ZERO; diff --git a/src/emscripten-optimizer/parser.cpp b/src/emscripten-optimizer/parser.cpp index 016966299..533043232 100644 --- a/src/emscripten-optimizer/parser.cpp +++ b/src/emscripten-optimizer/parser.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include <unordered_map> + #include "parser.h" namespace cashew { diff --git a/src/emscripten-optimizer/parser.h b/src/emscripten-optimizer/parser.h index c4d596058..8c3f36427 100644 --- a/src/emscripten-optimizer/parser.h +++ b/src/emscripten-optimizer/parser.h @@ -30,11 +30,46 @@ #include <limits> #include <vector> -#include "istring.h" +#include "support/istring.h" #include "support/safe_integer.h" namespace cashew { +using IString = wasm::IString; + +// IStringSet + +class IStringSet : public std::unordered_set<IString> { + std::vector<char> data; + +public: + IStringSet() = default; + IStringSet(const char* init) { // comma-delimited list + int size = strlen(init) + 1; + data.resize(size); + char* curr = &data[0]; + strncpy(curr, init, size); + while (1) { + char* end = strchr(curr, ' '); + if (end) { + *end = 0; + } + insert(curr); + if (!end) { + break; + } + curr = end + 1; + } + } + + bool has(const IString& str) { return count(str) > 0; } +}; + +class IOrderedStringSet : public std::set<IString> { +public: + bool has(const IString& str) { return count(str) > 0; } +}; + // common strings extern IString TOPLEVEL; @@ -233,11 +268,11 @@ template<class NodeRef, class Builder> class Parser { src++; } if (*src == 0) { - str.set(start); + str = IString(start); } else { char temp = *src; *src = 0; - str.set(start, false); + str = IString(start, false); *src = temp; } type = keywords.has(str) ? KEYWORD : IDENT; @@ -333,11 +368,11 @@ template<class NodeRef, class Builder> class Parser { default: abort(); } - size = strlen(str.str); + size = str.size(); #ifndef NDEBUG char temp = start[size]; start[size] = 0; - assert(strcmp(str.str, start) == 0); + assert(str.str == start); start[size] = temp; #endif type = OPERATOR; @@ -346,13 +381,13 @@ template<class NodeRef, class Builder> class Parser { type = SEPARATOR; char temp = src[1]; src[1] = 0; - str.set(src, false); + str = IString(src, false); src[1] = temp; src++; } else if (*src == '"' || *src == '\'') { char* end = strchr(src + 1, *src); *end = 0; - str.set(src + 1); + str = IString(src + 1); src = end + 1; type = STRING; } else { diff --git a/src/emscripten-optimizer/simple_ast.cpp b/src/emscripten-optimizer/simple_ast.cpp index 6afa0a66e..086d504ba 100644 --- a/src/emscripten-optimizer/simple_ast.cpp +++ b/src/emscripten-optimizer/simple_ast.cpp @@ -24,13 +24,11 @@ Ref& Ref::operator[](unsigned x) { return (*get())[x]; } Ref& Ref::operator[](IString x) { return (*get())[x]; } -bool Ref::operator==(const char* str) { - return get()->isString() && !strcmp(get()->str.str, str); +bool Ref::operator==(std::string_view str) { + return get()->isString() && get()->str == str; } -bool Ref::operator!=(const char* str) { - return get()->isString() ? !!strcmp(get()->str.str, str) : true; -} +bool Ref::operator!=(std::string_view str) { return !(*this == str); } bool Ref::operator==(const IString& str) { return get()->isString() && get()->str == str; @@ -81,8 +79,8 @@ void Value::stringify(std::ostream& os, bool pretty) { } switch (type) { case String: { - if (str.str) { - os << '"' << str.str << '"'; + if (str) { + os << '"' << str << '"'; } else { os << "\"(null)\""; } @@ -147,7 +145,7 @@ void Value::stringify(std::ostream& os, bool pretty) { } } indentify(); - os << '"' << i.first.c_str() << "\": "; + os << '"' << i.first << "\": "; i.second->stringify(os, pretty); } if (pretty) { diff --git a/src/emscripten-optimizer/simple_ast.h b/src/emscripten-optimizer/simple_ast.h index 64db04d79..60399d6d2 100644 --- a/src/emscripten-optimizer/simple_ast.h +++ b/src/emscripten-optimizer/simple_ast.h @@ -63,8 +63,9 @@ struct Ref { Ref& operator[](IString x); // special conveniences - bool operator==(const char* str); // comparison to string, which is by value - bool operator!=(const char* str); + bool + operator==(std::string_view str); // comparison to string, which is by value + bool operator!=(std::string_view str); bool operator==(const IString& str); bool operator!=(const IString& str); // prevent Ref == number, which is potentially ambiguous; use ->getNumber() == @@ -163,13 +164,13 @@ struct Value { Value& setString(const char* s) { free(); type = String; - str.set(s); + str = IString(s); return *this; } Value& setString(const IString& s) { free(); type = String; - str.set(s); + str = s; return *this; } Value& setNumber(double n) { @@ -233,7 +234,7 @@ struct Value { const char* getCString() { assert(isString()); - return str.str; + return str.str.data(); } IString& getIString() { assert(isString()); @@ -817,7 +818,7 @@ struct JSPrinter { break; } default: { - errv("cannot yet print %s\n", type.str); + errv("cannot yet print %s\n", type.str.data()); abort(); } } @@ -908,7 +909,7 @@ struct JSPrinter { void printAssignName(Ref node) { auto* assign = node->asAssignName(); - emit(assign->target().c_str()); + emit(assign->target().str.data()); space(); emit('='); space(); @@ -1472,10 +1473,10 @@ struct JSPrinter { needQuote = true; str = args[i][0][1]->getCString(); } else if (args[i][0][0] == GETTER) { - getterSetter = GETTER.c_str(); + getterSetter = GETTER.str.data(); str = args[i][0][1]->getCString(); } else if (args[i][0][0] == SETTER) { - getterSetter = SETTER.c_str(); + getterSetter = SETTER.str.data(); str = args[i][0][1]->getCString(); setterParam = args[i][0][2]->getCString(); } else { diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 4803f60b5..f2e1fee9a 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -4,28 +4,31 @@ #ifdef INSTRUCTION_PARSER #undef INSTRUCTION_PARSER -char op[33] = {'\0'}; -strncpy(op, s[0]->c_str(), 32); +using namespace std::string_view_literals; +auto str = s[0]->str().str; +char buf[33] = {}; +memcpy(buf, str.data(), str.size()); +std::string_view op = {buf, str.size()}; switch (op[0]) { case 'a': { switch (op[1]) { case 'r': { switch (op[6]) { case 'c': - if (strcmp(op, "array.copy") == 0) { return makeArrayCopy(s); } + if (op == "array.copy"sv) { return makeArrayCopy(s); } goto parse_error; case 'g': { switch (op[9]) { case '\0': - if (strcmp(op, "array.get") == 0) { return makeArrayGet(s); } + if (op == "array.get"sv) { return makeArrayGet(s); } goto parse_error; case '_': { switch (op[10]) { case 's': - if (strcmp(op, "array.get_s") == 0) { return makeArrayGet(s, true); } + if (op == "array.get_s"sv) { return makeArrayGet(s, true); } goto parse_error; case 'u': - if (strcmp(op, "array.get_u") == 0) { return makeArrayGet(s, false); } + if (op == "array.get_u"sv) { return makeArrayGet(s, false); } goto parse_error; default: goto parse_error; } @@ -34,30 +37,30 @@ switch (op[0]) { } } case 'i': - if (strcmp(op, "array.init_static") == 0) { return makeArrayInitStatic(s); } + if (op == "array.init_static"sv) { return makeArrayInitStatic(s); } goto parse_error; case 'l': - if (strcmp(op, "array.len") == 0) { return makeArrayLen(s); } + if (op == "array.len"sv) { return makeArrayLen(s); } goto parse_error; case 'n': { switch (op[9]) { case '\0': - if (strcmp(op, "array.new") == 0) { return makeArrayNewStatic(s, false); } + if (op == "array.new"sv) { return makeArrayNewStatic(s, false); } goto parse_error; case '_': - if (strcmp(op, "array.new_default") == 0) { return makeArrayNewStatic(s, true); } + if (op == "array.new_default"sv) { return makeArrayNewStatic(s, true); } goto parse_error; default: goto parse_error; } } case 's': - if (strcmp(op, "array.set") == 0) { return makeArraySet(s); } + if (op == "array.set"sv) { return makeArraySet(s); } goto parse_error; default: goto parse_error; } } case 't': - if (strcmp(op, "atomic.fence") == 0) { return makeAtomicFence(s); } + if (op == "atomic.fence"sv) { return makeAtomicFence(s); } goto parse_error; default: goto parse_error; } @@ -65,37 +68,37 @@ switch (op[0]) { case 'b': { switch (op[1]) { case 'l': - if (strcmp(op, "block") == 0) { return makeBlock(s); } + if (op == "block"sv) { return makeBlock(s); } goto parse_error; case 'r': { switch (op[2]) { case '\0': - if (strcmp(op, "br") == 0) { return makeBreak(s); } + if (op == "br"sv) { return makeBreak(s); } goto parse_error; case '_': { switch (op[3]) { case 'i': - if (strcmp(op, "br_if") == 0) { return makeBreak(s); } + if (op == "br_if"sv) { return makeBreak(s); } goto parse_error; case 'o': { switch (op[6]) { case 'c': { switch (op[10]) { case '\0': - if (strcmp(op, "br_on_cast") == 0) { return makeBrOn(s, BrOnCast); } + if (op == "br_on_cast"sv) { return makeBrOn(s, BrOnCast); } goto parse_error; case '_': { switch (op[11]) { case 'f': - if (strcmp(op, "br_on_cast_fail") == 0) { return makeBrOn(s, BrOnCastFail); } + if (op == "br_on_cast_fail"sv) { return makeBrOn(s, BrOnCastFail); } goto parse_error; case 's': { switch (op[17]) { case '\0': - if (strcmp(op, "br_on_cast_static") == 0) { return makeBrOnStatic(s, BrOnCast); } + if (op == "br_on_cast_static"sv) { return makeBrOnStatic(s, BrOnCast); } goto parse_error; case '_': - if (strcmp(op, "br_on_cast_static_fail") == 0) { return makeBrOnStatic(s, BrOnCastFail); } + if (op == "br_on_cast_static_fail"sv) { return makeBrOnStatic(s, BrOnCastFail); } goto parse_error; default: goto parse_error; } @@ -107,35 +110,35 @@ switch (op[0]) { } } case 'd': - if (strcmp(op, "br_on_data") == 0) { return makeBrOn(s, BrOnData); } + if (op == "br_on_data"sv) { return makeBrOn(s, BrOnData); } goto parse_error; case 'f': - if (strcmp(op, "br_on_func") == 0) { return makeBrOn(s, BrOnFunc); } + if (op == "br_on_func"sv) { return makeBrOn(s, BrOnFunc); } goto parse_error; case 'i': - if (strcmp(op, "br_on_i31") == 0) { return makeBrOn(s, BrOnI31); } + if (op == "br_on_i31"sv) { return makeBrOn(s, BrOnI31); } goto parse_error; case 'n': { switch (op[7]) { case 'o': { switch (op[10]) { case 'd': - if (strcmp(op, "br_on_non_data") == 0) { return makeBrOn(s, BrOnNonData); } + if (op == "br_on_non_data"sv) { return makeBrOn(s, BrOnNonData); } goto parse_error; case 'f': - if (strcmp(op, "br_on_non_func") == 0) { return makeBrOn(s, BrOnNonFunc); } + if (op == "br_on_non_func"sv) { return makeBrOn(s, BrOnNonFunc); } goto parse_error; case 'i': - if (strcmp(op, "br_on_non_i31") == 0) { return makeBrOn(s, BrOnNonI31); } + if (op == "br_on_non_i31"sv) { return makeBrOn(s, BrOnNonI31); } goto parse_error; case 'n': - if (strcmp(op, "br_on_non_null") == 0) { return makeBrOn(s, BrOnNonNull); } + if (op == "br_on_non_null"sv) { return makeBrOn(s, BrOnNonNull); } goto parse_error; default: goto parse_error; } } case 'u': - if (strcmp(op, "br_on_null") == 0) { return makeBrOn(s, BrOnNull); } + if (op == "br_on_null"sv) { return makeBrOn(s, BrOnNull); } goto parse_error; default: goto parse_error; } @@ -144,7 +147,7 @@ switch (op[0]) { } } case 't': - if (strcmp(op, "br_table") == 0) { return makeBreakTable(s); } + if (op == "br_table"sv) { return makeBreakTable(s); } goto parse_error; default: goto parse_error; } @@ -158,15 +161,15 @@ switch (op[0]) { case 'c': { switch (op[4]) { case '\0': - if (strcmp(op, "call") == 0) { return makeCall(s, /*isReturn=*/false); } + if (op == "call"sv) { return makeCall(s, /*isReturn=*/false); } goto parse_error; case '_': { switch (op[5]) { case 'i': - if (strcmp(op, "call_indirect") == 0) { return makeCallIndirect(s, /*isReturn=*/false); } + if (op == "call_indirect"sv) { return makeCallIndirect(s, /*isReturn=*/false); } goto parse_error; case 'r': - if (strcmp(op, "call_ref") == 0) { return makeCallRef(s, /*isReturn=*/false); } + if (op == "call_ref"sv) { return makeCallRef(s, /*isReturn=*/false); } goto parse_error; default: goto parse_error; } @@ -177,10 +180,10 @@ switch (op[0]) { case 'd': { switch (op[1]) { case 'a': - if (strcmp(op, "data.drop") == 0) { return makeDataDrop(s); } + if (op == "data.drop"sv) { return makeDataDrop(s); } goto parse_error; case 'r': - if (strcmp(op, "drop") == 0) { return makeDrop(s); } + if (op == "drop"sv) { return makeDrop(s); } goto parse_error; default: goto parse_error; } @@ -188,15 +191,15 @@ switch (op[0]) { case 'e': { switch (op[1]) { case 'l': - if (strcmp(op, "else") == 0) { return makeThenOrElse(s); } + if (op == "else"sv) { return makeThenOrElse(s); } goto parse_error; case 'x': { switch (op[7]) { case 'e': - if (strcmp(op, "extern.externalize") == 0) { return makeRefAs(s, ExternExternalize); } + if (op == "extern.externalize"sv) { return makeRefAs(s, ExternExternalize); } goto parse_error; case 'i': - if (strcmp(op, "extern.internalize") == 0) { return makeRefAs(s, ExternInternalize); } + if (op == "extern.internalize"sv) { return makeRefAs(s, ExternInternalize); } goto parse_error; default: goto parse_error; } @@ -213,10 +216,10 @@ switch (op[0]) { case 'a': { switch (op[5]) { case 'b': - if (strcmp(op, "f32.abs") == 0) { return makeUnary(s, UnaryOp::AbsFloat32); } + if (op == "f32.abs"sv) { return makeUnary(s, UnaryOp::AbsFloat32); } goto parse_error; case 'd': - if (strcmp(op, "f32.add") == 0) { return makeBinary(s, BinaryOp::AddFloat32); } + if (op == "f32.add"sv) { return makeBinary(s, BinaryOp::AddFloat32); } goto parse_error; default: goto parse_error; } @@ -224,24 +227,24 @@ switch (op[0]) { case 'c': { switch (op[5]) { case 'e': - if (strcmp(op, "f32.ceil") == 0) { return makeUnary(s, UnaryOp::CeilFloat32); } + if (op == "f32.ceil"sv) { return makeUnary(s, UnaryOp::CeilFloat32); } goto parse_error; case 'o': { switch (op[6]) { case 'n': { switch (op[7]) { case 's': - if (strcmp(op, "f32.const") == 0) { return makeConst(s, Type::f32); } + if (op == "f32.const"sv) { return makeConst(s, Type::f32); } goto parse_error; case 'v': { switch (op[13]) { case '3': { switch (op[16]) { case 's': - if (strcmp(op, "f32.convert_i32_s") == 0) { return makeUnary(s, UnaryOp::ConvertSInt32ToFloat32); } + if (op == "f32.convert_i32_s"sv) { return makeUnary(s, UnaryOp::ConvertSInt32ToFloat32); } goto parse_error; case 'u': - if (strcmp(op, "f32.convert_i32_u") == 0) { return makeUnary(s, UnaryOp::ConvertUInt32ToFloat32); } + if (op == "f32.convert_i32_u"sv) { return makeUnary(s, UnaryOp::ConvertUInt32ToFloat32); } goto parse_error; default: goto parse_error; } @@ -249,10 +252,10 @@ switch (op[0]) { case '6': { switch (op[16]) { case 's': - if (strcmp(op, "f32.convert_i64_s") == 0) { return makeUnary(s, UnaryOp::ConvertSInt64ToFloat32); } + if (op == "f32.convert_i64_s"sv) { return makeUnary(s, UnaryOp::ConvertSInt64ToFloat32); } goto parse_error; case 'u': - if (strcmp(op, "f32.convert_i64_u") == 0) { return makeUnary(s, UnaryOp::ConvertUInt64ToFloat32); } + if (op == "f32.convert_i64_u"sv) { return makeUnary(s, UnaryOp::ConvertUInt64ToFloat32); } goto parse_error; default: goto parse_error; } @@ -264,7 +267,7 @@ switch (op[0]) { } } case 'p': - if (strcmp(op, "f32.copysign") == 0) { return makeBinary(s, BinaryOp::CopySignFloat32); } + if (op == "f32.copysign"sv) { return makeBinary(s, BinaryOp::CopySignFloat32); } goto parse_error; default: goto parse_error; } @@ -275,27 +278,27 @@ switch (op[0]) { case 'd': { switch (op[5]) { case 'e': - if (strcmp(op, "f32.demote_f64") == 0) { return makeUnary(s, UnaryOp::DemoteFloat64); } + if (op == "f32.demote_f64"sv) { return makeUnary(s, UnaryOp::DemoteFloat64); } goto parse_error; case 'i': - if (strcmp(op, "f32.div") == 0) { return makeBinary(s, BinaryOp::DivFloat32); } + if (op == "f32.div"sv) { return makeBinary(s, BinaryOp::DivFloat32); } goto parse_error; default: goto parse_error; } } case 'e': - if (strcmp(op, "f32.eq") == 0) { return makeBinary(s, BinaryOp::EqFloat32); } + if (op == "f32.eq"sv) { return makeBinary(s, BinaryOp::EqFloat32); } goto parse_error; case 'f': - if (strcmp(op, "f32.floor") == 0) { return makeUnary(s, UnaryOp::FloorFloat32); } + if (op == "f32.floor"sv) { return makeUnary(s, UnaryOp::FloorFloat32); } goto parse_error; case 'g': { switch (op[5]) { case 'e': - if (strcmp(op, "f32.ge") == 0) { return makeBinary(s, BinaryOp::GeFloat32); } + if (op == "f32.ge"sv) { return makeBinary(s, BinaryOp::GeFloat32); } goto parse_error; case 't': - if (strcmp(op, "f32.gt") == 0) { return makeBinary(s, BinaryOp::GtFloat32); } + if (op == "f32.gt"sv) { return makeBinary(s, BinaryOp::GtFloat32); } goto parse_error; default: goto parse_error; } @@ -303,13 +306,13 @@ switch (op[0]) { case 'l': { switch (op[5]) { case 'e': - if (strcmp(op, "f32.le") == 0) { return makeBinary(s, BinaryOp::LeFloat32); } + if (op == "f32.le"sv) { return makeBinary(s, BinaryOp::LeFloat32); } goto parse_error; case 'o': - if (strcmp(op, "f32.load") == 0) { return makeLoad(s, Type::f32, /*isAtomic=*/false); } + if (op == "f32.load"sv) { return makeLoad(s, Type::f32, /*isAtomic=*/false); } goto parse_error; case 't': - if (strcmp(op, "f32.lt") == 0) { return makeBinary(s, BinaryOp::LtFloat32); } + if (op == "f32.lt"sv) { return makeBinary(s, BinaryOp::LtFloat32); } goto parse_error; default: goto parse_error; } @@ -317,13 +320,13 @@ switch (op[0]) { case 'm': { switch (op[5]) { case 'a': - if (strcmp(op, "f32.max") == 0) { return makeBinary(s, BinaryOp::MaxFloat32); } + if (op == "f32.max"sv) { return makeBinary(s, BinaryOp::MaxFloat32); } goto parse_error; case 'i': - if (strcmp(op, "f32.min") == 0) { return makeBinary(s, BinaryOp::MinFloat32); } + if (op == "f32.min"sv) { return makeBinary(s, BinaryOp::MinFloat32); } goto parse_error; case 'u': - if (strcmp(op, "f32.mul") == 0) { return makeBinary(s, BinaryOp::MulFloat32); } + if (op == "f32.mul"sv) { return makeBinary(s, BinaryOp::MulFloat32); } goto parse_error; default: goto parse_error; } @@ -331,36 +334,36 @@ switch (op[0]) { case 'n': { switch (op[6]) { case '\0': - if (strcmp(op, "f32.ne") == 0) { return makeBinary(s, BinaryOp::NeFloat32); } + if (op == "f32.ne"sv) { return makeBinary(s, BinaryOp::NeFloat32); } goto parse_error; case 'a': - if (strcmp(op, "f32.nearest") == 0) { return makeUnary(s, UnaryOp::NearestFloat32); } + if (op == "f32.nearest"sv) { return makeUnary(s, UnaryOp::NearestFloat32); } goto parse_error; case 'g': - if (strcmp(op, "f32.neg") == 0) { return makeUnary(s, UnaryOp::NegFloat32); } + if (op == "f32.neg"sv) { return makeUnary(s, UnaryOp::NegFloat32); } goto parse_error; default: goto parse_error; } } case 'r': - if (strcmp(op, "f32.reinterpret_i32") == 0) { return makeUnary(s, UnaryOp::ReinterpretInt32); } + if (op == "f32.reinterpret_i32"sv) { return makeUnary(s, UnaryOp::ReinterpretInt32); } goto parse_error; case 's': { switch (op[5]) { case 'q': - if (strcmp(op, "f32.sqrt") == 0) { return makeUnary(s, UnaryOp::SqrtFloat32); } + if (op == "f32.sqrt"sv) { return makeUnary(s, UnaryOp::SqrtFloat32); } goto parse_error; case 't': - if (strcmp(op, "f32.store") == 0) { return makeStore(s, Type::f32, /*isAtomic=*/false); } + if (op == "f32.store"sv) { return makeStore(s, Type::f32, /*isAtomic=*/false); } goto parse_error; case 'u': - if (strcmp(op, "f32.sub") == 0) { return makeBinary(s, BinaryOp::SubFloat32); } + if (op == "f32.sub"sv) { return makeBinary(s, BinaryOp::SubFloat32); } goto parse_error; default: goto parse_error; } } case 't': - if (strcmp(op, "f32.trunc") == 0) { return makeUnary(s, UnaryOp::TruncFloat32); } + if (op == "f32.trunc"sv) { return makeUnary(s, UnaryOp::TruncFloat32); } goto parse_error; default: goto parse_error; } @@ -370,10 +373,10 @@ switch (op[0]) { case 'a': { switch (op[7]) { case 'b': - if (strcmp(op, "f32x4.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecF32x4); } + if (op == "f32x4.abs"sv) { return makeUnary(s, UnaryOp::AbsVecF32x4); } goto parse_error; case 'd': - if (strcmp(op, "f32x4.add") == 0) { return makeBinary(s, BinaryOp::AddVecF32x4); } + if (op == "f32x4.add"sv) { return makeBinary(s, BinaryOp::AddVecF32x4); } goto parse_error; default: goto parse_error; } @@ -381,15 +384,15 @@ switch (op[0]) { case 'c': { switch (op[7]) { case 'e': - if (strcmp(op, "f32x4.ceil") == 0) { return makeUnary(s, UnaryOp::CeilVecF32x4); } + if (op == "f32x4.ceil"sv) { return makeUnary(s, UnaryOp::CeilVecF32x4); } goto parse_error; case 'o': { switch (op[20]) { case 's': - if (strcmp(op, "f32x4.convert_i32x4_s") == 0) { return makeUnary(s, UnaryOp::ConvertSVecI32x4ToVecF32x4); } + if (op == "f32x4.convert_i32x4_s"sv) { return makeUnary(s, UnaryOp::ConvertSVecI32x4ToVecF32x4); } goto parse_error; case 'u': - if (strcmp(op, "f32x4.convert_i32x4_u") == 0) { return makeUnary(s, UnaryOp::ConvertUVecI32x4ToVecF32x4); } + if (op == "f32x4.convert_i32x4_u"sv) { return makeUnary(s, UnaryOp::ConvertUVecI32x4ToVecF32x4); } goto parse_error; default: goto parse_error; } @@ -400,10 +403,10 @@ switch (op[0]) { case 'd': { switch (op[7]) { case 'e': - if (strcmp(op, "f32x4.demote_f64x2_zero") == 0) { return makeUnary(s, UnaryOp::DemoteZeroVecF64x2ToVecF32x4); } + if (op == "f32x4.demote_f64x2_zero"sv) { return makeUnary(s, UnaryOp::DemoteZeroVecF64x2ToVecF32x4); } goto parse_error; case 'i': - if (strcmp(op, "f32x4.div") == 0) { return makeBinary(s, BinaryOp::DivVecF32x4); } + if (op == "f32x4.div"sv) { return makeBinary(s, BinaryOp::DivVecF32x4); } goto parse_error; default: goto parse_error; } @@ -411,24 +414,24 @@ switch (op[0]) { case 'e': { switch (op[7]) { case 'q': - if (strcmp(op, "f32x4.eq") == 0) { return makeBinary(s, BinaryOp::EqVecF32x4); } + if (op == "f32x4.eq"sv) { return makeBinary(s, BinaryOp::EqVecF32x4); } goto parse_error; case 'x': - if (strcmp(op, "f32x4.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecF32x4, 4); } + if (op == "f32x4.extract_lane"sv) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecF32x4, 4); } goto parse_error; default: goto parse_error; } } case 'f': - if (strcmp(op, "f32x4.floor") == 0) { return makeUnary(s, UnaryOp::FloorVecF32x4); } + if (op == "f32x4.floor"sv) { return makeUnary(s, UnaryOp::FloorVecF32x4); } goto parse_error; case 'g': { switch (op[7]) { case 'e': - if (strcmp(op, "f32x4.ge") == 0) { return makeBinary(s, BinaryOp::GeVecF32x4); } + if (op == "f32x4.ge"sv) { return makeBinary(s, BinaryOp::GeVecF32x4); } goto parse_error; case 't': - if (strcmp(op, "f32x4.gt") == 0) { return makeBinary(s, BinaryOp::GtVecF32x4); } + if (op == "f32x4.gt"sv) { return makeBinary(s, BinaryOp::GtVecF32x4); } goto parse_error; default: goto parse_error; } @@ -436,10 +439,10 @@ switch (op[0]) { case 'l': { switch (op[7]) { case 'e': - if (strcmp(op, "f32x4.le") == 0) { return makeBinary(s, BinaryOp::LeVecF32x4); } + if (op == "f32x4.le"sv) { return makeBinary(s, BinaryOp::LeVecF32x4); } goto parse_error; case 't': - if (strcmp(op, "f32x4.lt") == 0) { return makeBinary(s, BinaryOp::LtVecF32x4); } + if (op == "f32x4.lt"sv) { return makeBinary(s, BinaryOp::LtVecF32x4); } goto parse_error; default: goto parse_error; } @@ -447,13 +450,13 @@ switch (op[0]) { case 'm': { switch (op[7]) { case 'a': - if (strcmp(op, "f32x4.max") == 0) { return makeBinary(s, BinaryOp::MaxVecF32x4); } + if (op == "f32x4.max"sv) { return makeBinary(s, BinaryOp::MaxVecF32x4); } goto parse_error; case 'i': - if (strcmp(op, "f32x4.min") == 0) { return makeBinary(s, BinaryOp::MinVecF32x4); } + if (op == "f32x4.min"sv) { return makeBinary(s, BinaryOp::MinVecF32x4); } goto parse_error; case 'u': - if (strcmp(op, "f32x4.mul") == 0) { return makeBinary(s, BinaryOp::MulVecF32x4); } + if (op == "f32x4.mul"sv) { return makeBinary(s, BinaryOp::MulVecF32x4); } goto parse_error; default: goto parse_error; } @@ -461,13 +464,13 @@ switch (op[0]) { case 'n': { switch (op[8]) { case '\0': - if (strcmp(op, "f32x4.ne") == 0) { return makeBinary(s, BinaryOp::NeVecF32x4); } + if (op == "f32x4.ne"sv) { return makeBinary(s, BinaryOp::NeVecF32x4); } goto parse_error; case 'a': - if (strcmp(op, "f32x4.nearest") == 0) { return makeUnary(s, UnaryOp::NearestVecF32x4); } + if (op == "f32x4.nearest"sv) { return makeUnary(s, UnaryOp::NearestVecF32x4); } goto parse_error; case 'g': - if (strcmp(op, "f32x4.neg") == 0) { return makeUnary(s, UnaryOp::NegVecF32x4); } + if (op == "f32x4.neg"sv) { return makeUnary(s, UnaryOp::NegVecF32x4); } goto parse_error; default: goto parse_error; } @@ -475,10 +478,10 @@ switch (op[0]) { case 'p': { switch (op[8]) { case 'a': - if (strcmp(op, "f32x4.pmax") == 0) { return makeBinary(s, BinaryOp::PMaxVecF32x4); } + if (op == "f32x4.pmax"sv) { return makeBinary(s, BinaryOp::PMaxVecF32x4); } goto parse_error; case 'i': - if (strcmp(op, "f32x4.pmin") == 0) { return makeBinary(s, BinaryOp::PMinVecF32x4); } + if (op == "f32x4.pmin"sv) { return makeBinary(s, BinaryOp::PMinVecF32x4); } goto parse_error; default: goto parse_error; } @@ -490,10 +493,10 @@ switch (op[0]) { case 'f': { switch (op[16]) { case 'a': - if (strcmp(op, "f32x4.relaxed_fma") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::RelaxedFmaVecF32x4); } + if (op == "f32x4.relaxed_fma"sv) { return makeSIMDTernary(s, SIMDTernaryOp::RelaxedFmaVecF32x4); } goto parse_error; case 's': - if (strcmp(op, "f32x4.relaxed_fms") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::RelaxedFmsVecF32x4); } + if (op == "f32x4.relaxed_fms"sv) { return makeSIMDTernary(s, SIMDTernaryOp::RelaxedFmsVecF32x4); } goto parse_error; default: goto parse_error; } @@ -501,10 +504,10 @@ switch (op[0]) { case 'm': { switch (op[15]) { case 'a': - if (strcmp(op, "f32x4.relaxed_max") == 0) { return makeBinary(s, BinaryOp::RelaxedMaxVecF32x4); } + if (op == "f32x4.relaxed_max"sv) { return makeBinary(s, BinaryOp::RelaxedMaxVecF32x4); } goto parse_error; case 'i': - if (strcmp(op, "f32x4.relaxed_min") == 0) { return makeBinary(s, BinaryOp::RelaxedMinVecF32x4); } + if (op == "f32x4.relaxed_min"sv) { return makeBinary(s, BinaryOp::RelaxedMinVecF32x4); } goto parse_error; default: goto parse_error; } @@ -513,7 +516,7 @@ switch (op[0]) { } } case 'p': - if (strcmp(op, "f32x4.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecF32x4, 4); } + if (op == "f32x4.replace_lane"sv) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecF32x4, 4); } goto parse_error; default: goto parse_error; } @@ -521,19 +524,19 @@ switch (op[0]) { case 's': { switch (op[7]) { case 'p': - if (strcmp(op, "f32x4.splat") == 0) { return makeUnary(s, UnaryOp::SplatVecF32x4); } + if (op == "f32x4.splat"sv) { return makeUnary(s, UnaryOp::SplatVecF32x4); } goto parse_error; case 'q': - if (strcmp(op, "f32x4.sqrt") == 0) { return makeUnary(s, UnaryOp::SqrtVecF32x4); } + if (op == "f32x4.sqrt"sv) { return makeUnary(s, UnaryOp::SqrtVecF32x4); } goto parse_error; case 'u': - if (strcmp(op, "f32x4.sub") == 0) { return makeBinary(s, BinaryOp::SubVecF32x4); } + if (op == "f32x4.sub"sv) { return makeBinary(s, BinaryOp::SubVecF32x4); } goto parse_error; default: goto parse_error; } } case 't': - if (strcmp(op, "f32x4.trunc") == 0) { return makeUnary(s, UnaryOp::TruncVecF32x4); } + if (op == "f32x4.trunc"sv) { return makeUnary(s, UnaryOp::TruncVecF32x4); } goto parse_error; default: goto parse_error; } @@ -548,10 +551,10 @@ switch (op[0]) { case 'a': { switch (op[5]) { case 'b': - if (strcmp(op, "f64.abs") == 0) { return makeUnary(s, UnaryOp::AbsFloat64); } + if (op == "f64.abs"sv) { return makeUnary(s, UnaryOp::AbsFloat64); } goto parse_error; case 'd': - if (strcmp(op, "f64.add") == 0) { return makeBinary(s, BinaryOp::AddFloat64); } + if (op == "f64.add"sv) { return makeBinary(s, BinaryOp::AddFloat64); } goto parse_error; default: goto parse_error; } @@ -559,24 +562,24 @@ switch (op[0]) { case 'c': { switch (op[5]) { case 'e': - if (strcmp(op, "f64.ceil") == 0) { return makeUnary(s, UnaryOp::CeilFloat64); } + if (op == "f64.ceil"sv) { return makeUnary(s, UnaryOp::CeilFloat64); } goto parse_error; case 'o': { switch (op[6]) { case 'n': { switch (op[7]) { case 's': - if (strcmp(op, "f64.const") == 0) { return makeConst(s, Type::f64); } + if (op == "f64.const"sv) { return makeConst(s, Type::f64); } goto parse_error; case 'v': { switch (op[13]) { case '3': { switch (op[16]) { case 's': - if (strcmp(op, "f64.convert_i32_s") == 0) { return makeUnary(s, UnaryOp::ConvertSInt32ToFloat64); } + if (op == "f64.convert_i32_s"sv) { return makeUnary(s, UnaryOp::ConvertSInt32ToFloat64); } goto parse_error; case 'u': - if (strcmp(op, "f64.convert_i32_u") == 0) { return makeUnary(s, UnaryOp::ConvertUInt32ToFloat64); } + if (op == "f64.convert_i32_u"sv) { return makeUnary(s, UnaryOp::ConvertUInt32ToFloat64); } goto parse_error; default: goto parse_error; } @@ -584,10 +587,10 @@ switch (op[0]) { case '6': { switch (op[16]) { case 's': - if (strcmp(op, "f64.convert_i64_s") == 0) { return makeUnary(s, UnaryOp::ConvertSInt64ToFloat64); } + if (op == "f64.convert_i64_s"sv) { return makeUnary(s, UnaryOp::ConvertSInt64ToFloat64); } goto parse_error; case 'u': - if (strcmp(op, "f64.convert_i64_u") == 0) { return makeUnary(s, UnaryOp::ConvertUInt64ToFloat64); } + if (op == "f64.convert_i64_u"sv) { return makeUnary(s, UnaryOp::ConvertUInt64ToFloat64); } goto parse_error; default: goto parse_error; } @@ -599,7 +602,7 @@ switch (op[0]) { } } case 'p': - if (strcmp(op, "f64.copysign") == 0) { return makeBinary(s, BinaryOp::CopySignFloat64); } + if (op == "f64.copysign"sv) { return makeBinary(s, BinaryOp::CopySignFloat64); } goto parse_error; default: goto parse_error; } @@ -608,21 +611,21 @@ switch (op[0]) { } } case 'd': - if (strcmp(op, "f64.div") == 0) { return makeBinary(s, BinaryOp::DivFloat64); } + if (op == "f64.div"sv) { return makeBinary(s, BinaryOp::DivFloat64); } goto parse_error; case 'e': - if (strcmp(op, "f64.eq") == 0) { return makeBinary(s, BinaryOp::EqFloat64); } + if (op == "f64.eq"sv) { return makeBinary(s, BinaryOp::EqFloat64); } goto parse_error; case 'f': - if (strcmp(op, "f64.floor") == 0) { return makeUnary(s, UnaryOp::FloorFloat64); } + if (op == "f64.floor"sv) { return makeUnary(s, UnaryOp::FloorFloat64); } goto parse_error; case 'g': { switch (op[5]) { case 'e': - if (strcmp(op, "f64.ge") == 0) { return makeBinary(s, BinaryOp::GeFloat64); } + if (op == "f64.ge"sv) { return makeBinary(s, BinaryOp::GeFloat64); } goto parse_error; case 't': - if (strcmp(op, "f64.gt") == 0) { return makeBinary(s, BinaryOp::GtFloat64); } + if (op == "f64.gt"sv) { return makeBinary(s, BinaryOp::GtFloat64); } goto parse_error; default: goto parse_error; } @@ -630,13 +633,13 @@ switch (op[0]) { case 'l': { switch (op[5]) { case 'e': - if (strcmp(op, "f64.le") == 0) { return makeBinary(s, BinaryOp::LeFloat64); } + if (op == "f64.le"sv) { return makeBinary(s, BinaryOp::LeFloat64); } goto parse_error; case 'o': - if (strcmp(op, "f64.load") == 0) { return makeLoad(s, Type::f64, /*isAtomic=*/false); } + if (op == "f64.load"sv) { return makeLoad(s, Type::f64, /*isAtomic=*/false); } goto parse_error; case 't': - if (strcmp(op, "f64.lt") == 0) { return makeBinary(s, BinaryOp::LtFloat64); } + if (op == "f64.lt"sv) { return makeBinary(s, BinaryOp::LtFloat64); } goto parse_error; default: goto parse_error; } @@ -644,13 +647,13 @@ switch (op[0]) { case 'm': { switch (op[5]) { case 'a': - if (strcmp(op, "f64.max") == 0) { return makeBinary(s, BinaryOp::MaxFloat64); } + if (op == "f64.max"sv) { return makeBinary(s, BinaryOp::MaxFloat64); } goto parse_error; case 'i': - if (strcmp(op, "f64.min") == 0) { return makeBinary(s, BinaryOp::MinFloat64); } + if (op == "f64.min"sv) { return makeBinary(s, BinaryOp::MinFloat64); } goto parse_error; case 'u': - if (strcmp(op, "f64.mul") == 0) { return makeBinary(s, BinaryOp::MulFloat64); } + if (op == "f64.mul"sv) { return makeBinary(s, BinaryOp::MulFloat64); } goto parse_error; default: goto parse_error; } @@ -658,39 +661,39 @@ switch (op[0]) { case 'n': { switch (op[6]) { case '\0': - if (strcmp(op, "f64.ne") == 0) { return makeBinary(s, BinaryOp::NeFloat64); } + if (op == "f64.ne"sv) { return makeBinary(s, BinaryOp::NeFloat64); } goto parse_error; case 'a': - if (strcmp(op, "f64.nearest") == 0) { return makeUnary(s, UnaryOp::NearestFloat64); } + if (op == "f64.nearest"sv) { return makeUnary(s, UnaryOp::NearestFloat64); } goto parse_error; case 'g': - if (strcmp(op, "f64.neg") == 0) { return makeUnary(s, UnaryOp::NegFloat64); } + if (op == "f64.neg"sv) { return makeUnary(s, UnaryOp::NegFloat64); } goto parse_error; default: goto parse_error; } } case 'p': - if (strcmp(op, "f64.promote_f32") == 0) { return makeUnary(s, UnaryOp::PromoteFloat32); } + if (op == "f64.promote_f32"sv) { return makeUnary(s, UnaryOp::PromoteFloat32); } goto parse_error; case 'r': - if (strcmp(op, "f64.reinterpret_i64") == 0) { return makeUnary(s, UnaryOp::ReinterpretInt64); } + if (op == "f64.reinterpret_i64"sv) { return makeUnary(s, UnaryOp::ReinterpretInt64); } goto parse_error; case 's': { switch (op[5]) { case 'q': - if (strcmp(op, "f64.sqrt") == 0) { return makeUnary(s, UnaryOp::SqrtFloat64); } + if (op == "f64.sqrt"sv) { return makeUnary(s, UnaryOp::SqrtFloat64); } goto parse_error; case 't': - if (strcmp(op, "f64.store") == 0) { return makeStore(s, Type::f64, /*isAtomic=*/false); } + if (op == "f64.store"sv) { return makeStore(s, Type::f64, /*isAtomic=*/false); } goto parse_error; case 'u': - if (strcmp(op, "f64.sub") == 0) { return makeBinary(s, BinaryOp::SubFloat64); } + if (op == "f64.sub"sv) { return makeBinary(s, BinaryOp::SubFloat64); } goto parse_error; default: goto parse_error; } } case 't': - if (strcmp(op, "f64.trunc") == 0) { return makeUnary(s, UnaryOp::TruncFloat64); } + if (op == "f64.trunc"sv) { return makeUnary(s, UnaryOp::TruncFloat64); } goto parse_error; default: goto parse_error; } @@ -700,10 +703,10 @@ switch (op[0]) { case 'a': { switch (op[7]) { case 'b': - if (strcmp(op, "f64x2.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecF64x2); } + if (op == "f64x2.abs"sv) { return makeUnary(s, UnaryOp::AbsVecF64x2); } goto parse_error; case 'd': - if (strcmp(op, "f64x2.add") == 0) { return makeBinary(s, BinaryOp::AddVecF64x2); } + if (op == "f64x2.add"sv) { return makeBinary(s, BinaryOp::AddVecF64x2); } goto parse_error; default: goto parse_error; } @@ -711,15 +714,15 @@ switch (op[0]) { case 'c': { switch (op[7]) { case 'e': - if (strcmp(op, "f64x2.ceil") == 0) { return makeUnary(s, UnaryOp::CeilVecF64x2); } + if (op == "f64x2.ceil"sv) { return makeUnary(s, UnaryOp::CeilVecF64x2); } goto parse_error; case 'o': { switch (op[24]) { case 's': - if (strcmp(op, "f64x2.convert_low_i32x4_s") == 0) { return makeUnary(s, UnaryOp::ConvertLowSVecI32x4ToVecF64x2); } + if (op == "f64x2.convert_low_i32x4_s"sv) { return makeUnary(s, UnaryOp::ConvertLowSVecI32x4ToVecF64x2); } goto parse_error; case 'u': - if (strcmp(op, "f64x2.convert_low_i32x4_u") == 0) { return makeUnary(s, UnaryOp::ConvertLowUVecI32x4ToVecF64x2); } + if (op == "f64x2.convert_low_i32x4_u"sv) { return makeUnary(s, UnaryOp::ConvertLowUVecI32x4ToVecF64x2); } goto parse_error; default: goto parse_error; } @@ -728,29 +731,29 @@ switch (op[0]) { } } case 'd': - if (strcmp(op, "f64x2.div") == 0) { return makeBinary(s, BinaryOp::DivVecF64x2); } + if (op == "f64x2.div"sv) { return makeBinary(s, BinaryOp::DivVecF64x2); } goto parse_error; case 'e': { switch (op[7]) { case 'q': - if (strcmp(op, "f64x2.eq") == 0) { return makeBinary(s, BinaryOp::EqVecF64x2); } + if (op == "f64x2.eq"sv) { return makeBinary(s, BinaryOp::EqVecF64x2); } goto parse_error; case 'x': - if (strcmp(op, "f64x2.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecF64x2, 2); } + if (op == "f64x2.extract_lane"sv) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecF64x2, 2); } goto parse_error; default: goto parse_error; } } case 'f': - if (strcmp(op, "f64x2.floor") == 0) { return makeUnary(s, UnaryOp::FloorVecF64x2); } + if (op == "f64x2.floor"sv) { return makeUnary(s, UnaryOp::FloorVecF64x2); } goto parse_error; case 'g': { switch (op[7]) { case 'e': - if (strcmp(op, "f64x2.ge") == 0) { return makeBinary(s, BinaryOp::GeVecF64x2); } + if (op == "f64x2.ge"sv) { return makeBinary(s, BinaryOp::GeVecF64x2); } goto parse_error; case 't': - if (strcmp(op, "f64x2.gt") == 0) { return makeBinary(s, BinaryOp::GtVecF64x2); } + if (op == "f64x2.gt"sv) { return makeBinary(s, BinaryOp::GtVecF64x2); } goto parse_error; default: goto parse_error; } @@ -758,10 +761,10 @@ switch (op[0]) { case 'l': { switch (op[7]) { case 'e': - if (strcmp(op, "f64x2.le") == 0) { return makeBinary(s, BinaryOp::LeVecF64x2); } + if (op == "f64x2.le"sv) { return makeBinary(s, BinaryOp::LeVecF64x2); } goto parse_error; case 't': - if (strcmp(op, "f64x2.lt") == 0) { return makeBinary(s, BinaryOp::LtVecF64x2); } + if (op == "f64x2.lt"sv) { return makeBinary(s, BinaryOp::LtVecF64x2); } goto parse_error; default: goto parse_error; } @@ -769,13 +772,13 @@ switch (op[0]) { case 'm': { switch (op[7]) { case 'a': - if (strcmp(op, "f64x2.max") == 0) { return makeBinary(s, BinaryOp::MaxVecF64x2); } + if (op == "f64x2.max"sv) { return makeBinary(s, BinaryOp::MaxVecF64x2); } goto parse_error; case 'i': - if (strcmp(op, "f64x2.min") == 0) { return makeBinary(s, BinaryOp::MinVecF64x2); } + if (op == "f64x2.min"sv) { return makeBinary(s, BinaryOp::MinVecF64x2); } goto parse_error; case 'u': - if (strcmp(op, "f64x2.mul") == 0) { return makeBinary(s, BinaryOp::MulVecF64x2); } + if (op == "f64x2.mul"sv) { return makeBinary(s, BinaryOp::MulVecF64x2); } goto parse_error; default: goto parse_error; } @@ -783,13 +786,13 @@ switch (op[0]) { case 'n': { switch (op[8]) { case '\0': - if (strcmp(op, "f64x2.ne") == 0) { return makeBinary(s, BinaryOp::NeVecF64x2); } + if (op == "f64x2.ne"sv) { return makeBinary(s, BinaryOp::NeVecF64x2); } goto parse_error; case 'a': - if (strcmp(op, "f64x2.nearest") == 0) { return makeUnary(s, UnaryOp::NearestVecF64x2); } + if (op == "f64x2.nearest"sv) { return makeUnary(s, UnaryOp::NearestVecF64x2); } goto parse_error; case 'g': - if (strcmp(op, "f64x2.neg") == 0) { return makeUnary(s, UnaryOp::NegVecF64x2); } + if (op == "f64x2.neg"sv) { return makeUnary(s, UnaryOp::NegVecF64x2); } goto parse_error; default: goto parse_error; } @@ -799,16 +802,16 @@ switch (op[0]) { case 'm': { switch (op[8]) { case 'a': - if (strcmp(op, "f64x2.pmax") == 0) { return makeBinary(s, BinaryOp::PMaxVecF64x2); } + if (op == "f64x2.pmax"sv) { return makeBinary(s, BinaryOp::PMaxVecF64x2); } goto parse_error; case 'i': - if (strcmp(op, "f64x2.pmin") == 0) { return makeBinary(s, BinaryOp::PMinVecF64x2); } + if (op == "f64x2.pmin"sv) { return makeBinary(s, BinaryOp::PMinVecF64x2); } goto parse_error; default: goto parse_error; } } case 'r': - if (strcmp(op, "f64x2.promote_low_f32x4") == 0) { return makeUnary(s, UnaryOp::PromoteLowVecF32x4ToVecF64x2); } + if (op == "f64x2.promote_low_f32x4"sv) { return makeUnary(s, UnaryOp::PromoteLowVecF32x4ToVecF64x2); } goto parse_error; default: goto parse_error; } @@ -820,10 +823,10 @@ switch (op[0]) { case 'f': { switch (op[16]) { case 'a': - if (strcmp(op, "f64x2.relaxed_fma") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::RelaxedFmaVecF64x2); } + if (op == "f64x2.relaxed_fma"sv) { return makeSIMDTernary(s, SIMDTernaryOp::RelaxedFmaVecF64x2); } goto parse_error; case 's': - if (strcmp(op, "f64x2.relaxed_fms") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::RelaxedFmsVecF64x2); } + if (op == "f64x2.relaxed_fms"sv) { return makeSIMDTernary(s, SIMDTernaryOp::RelaxedFmsVecF64x2); } goto parse_error; default: goto parse_error; } @@ -831,10 +834,10 @@ switch (op[0]) { case 'm': { switch (op[15]) { case 'a': - if (strcmp(op, "f64x2.relaxed_max") == 0) { return makeBinary(s, BinaryOp::RelaxedMaxVecF64x2); } + if (op == "f64x2.relaxed_max"sv) { return makeBinary(s, BinaryOp::RelaxedMaxVecF64x2); } goto parse_error; case 'i': - if (strcmp(op, "f64x2.relaxed_min") == 0) { return makeBinary(s, BinaryOp::RelaxedMinVecF64x2); } + if (op == "f64x2.relaxed_min"sv) { return makeBinary(s, BinaryOp::RelaxedMinVecF64x2); } goto parse_error; default: goto parse_error; } @@ -843,7 +846,7 @@ switch (op[0]) { } } case 'p': - if (strcmp(op, "f64x2.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecF64x2, 2); } + if (op == "f64x2.replace_lane"sv) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecF64x2, 2); } goto parse_error; default: goto parse_error; } @@ -851,19 +854,19 @@ switch (op[0]) { case 's': { switch (op[7]) { case 'p': - if (strcmp(op, "f64x2.splat") == 0) { return makeUnary(s, UnaryOp::SplatVecF64x2); } + if (op == "f64x2.splat"sv) { return makeUnary(s, UnaryOp::SplatVecF64x2); } goto parse_error; case 'q': - if (strcmp(op, "f64x2.sqrt") == 0) { return makeUnary(s, UnaryOp::SqrtVecF64x2); } + if (op == "f64x2.sqrt"sv) { return makeUnary(s, UnaryOp::SqrtVecF64x2); } goto parse_error; case 'u': - if (strcmp(op, "f64x2.sub") == 0) { return makeBinary(s, BinaryOp::SubVecF64x2); } + if (op == "f64x2.sub"sv) { return makeBinary(s, BinaryOp::SubVecF64x2); } goto parse_error; default: goto parse_error; } } case 't': - if (strcmp(op, "f64x2.trunc") == 0) { return makeUnary(s, UnaryOp::TruncVecF64x2); } + if (op == "f64x2.trunc"sv) { return makeUnary(s, UnaryOp::TruncVecF64x2); } goto parse_error; default: goto parse_error; } @@ -877,10 +880,10 @@ switch (op[0]) { case 'g': { switch (op[7]) { case 'g': - if (strcmp(op, "global.get") == 0) { return makeGlobalGet(s); } + if (op == "global.get"sv) { return makeGlobalGet(s); } goto parse_error; case 's': - if (strcmp(op, "global.set") == 0) { return makeGlobalSet(s); } + if (op == "global.set"sv) { return makeGlobalSet(s); } goto parse_error; default: goto parse_error; } @@ -892,20 +895,20 @@ switch (op[0]) { case 'a': { switch (op[7]) { case 'b': - if (strcmp(op, "i16x8.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecI16x8); } + if (op == "i16x8.abs"sv) { return makeUnary(s, UnaryOp::AbsVecI16x8); } goto parse_error; case 'd': { switch (op[9]) { case '\0': - if (strcmp(op, "i16x8.add") == 0) { return makeBinary(s, BinaryOp::AddVecI16x8); } + if (op == "i16x8.add"sv) { return makeBinary(s, BinaryOp::AddVecI16x8); } goto parse_error; case '_': { switch (op[14]) { case 's': - if (strcmp(op, "i16x8.add_sat_s") == 0) { return makeBinary(s, BinaryOp::AddSatSVecI16x8); } + if (op == "i16x8.add_sat_s"sv) { return makeBinary(s, BinaryOp::AddSatSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.add_sat_u") == 0) { return makeBinary(s, BinaryOp::AddSatUVecI16x8); } + if (op == "i16x8.add_sat_u"sv) { return makeBinary(s, BinaryOp::AddSatUVecI16x8); } goto parse_error; default: goto parse_error; } @@ -914,34 +917,34 @@ switch (op[0]) { } } case 'l': - if (strcmp(op, "i16x8.all_true") == 0) { return makeUnary(s, UnaryOp::AllTrueVecI16x8); } + if (op == "i16x8.all_true"sv) { return makeUnary(s, UnaryOp::AllTrueVecI16x8); } goto parse_error; case 'v': - if (strcmp(op, "i16x8.avgr_u") == 0) { return makeBinary(s, BinaryOp::AvgrUVecI16x8); } + if (op == "i16x8.avgr_u"sv) { return makeBinary(s, BinaryOp::AvgrUVecI16x8); } goto parse_error; default: goto parse_error; } } case 'b': - if (strcmp(op, "i16x8.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI16x8); } + if (op == "i16x8.bitmask"sv) { return makeUnary(s, UnaryOp::BitmaskVecI16x8); } goto parse_error; case 'd': - if (strcmp(op, "i16x8.dot_i8x16_i7x16_s") == 0) { return makeBinary(s, BinaryOp::DotI8x16I7x16SToVecI16x8); } + if (op == "i16x8.dot_i8x16_i7x16_s"sv) { return makeBinary(s, BinaryOp::DotI8x16I7x16SToVecI16x8); } goto parse_error; case 'e': { switch (op[7]) { case 'q': - if (strcmp(op, "i16x8.eq") == 0) { return makeBinary(s, BinaryOp::EqVecI16x8); } + if (op == "i16x8.eq"sv) { return makeBinary(s, BinaryOp::EqVecI16x8); } goto parse_error; case 'x': { switch (op[9]) { case 'a': { switch (op[28]) { case 's': - if (strcmp(op, "i16x8.extadd_pairwise_i8x16_s") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseSVecI8x16ToI16x8); } + if (op == "i16x8.extadd_pairwise_i8x16_s"sv) { return makeUnary(s, UnaryOp::ExtAddPairwiseSVecI8x16ToI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.extadd_pairwise_i8x16_u") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseUVecI8x16ToI16x8); } + if (op == "i16x8.extadd_pairwise_i8x16_u"sv) { return makeUnary(s, UnaryOp::ExtAddPairwiseUVecI8x16ToI16x8); } goto parse_error; default: goto parse_error; } @@ -951,10 +954,10 @@ switch (op[0]) { case 'h': { switch (op[24]) { case 's': - if (strcmp(op, "i16x8.extend_high_i8x16_s") == 0) { return makeUnary(s, UnaryOp::ExtendHighSVecI8x16ToVecI16x8); } + if (op == "i16x8.extend_high_i8x16_s"sv) { return makeUnary(s, UnaryOp::ExtendHighSVecI8x16ToVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.extend_high_i8x16_u") == 0) { return makeUnary(s, UnaryOp::ExtendHighUVecI8x16ToVecI16x8); } + if (op == "i16x8.extend_high_i8x16_u"sv) { return makeUnary(s, UnaryOp::ExtendHighUVecI8x16ToVecI16x8); } goto parse_error; default: goto parse_error; } @@ -962,10 +965,10 @@ switch (op[0]) { case 'l': { switch (op[23]) { case 's': - if (strcmp(op, "i16x8.extend_low_i8x16_s") == 0) { return makeUnary(s, UnaryOp::ExtendLowSVecI8x16ToVecI16x8); } + if (op == "i16x8.extend_low_i8x16_s"sv) { return makeUnary(s, UnaryOp::ExtendLowSVecI8x16ToVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.extend_low_i8x16_u") == 0) { return makeUnary(s, UnaryOp::ExtendLowUVecI8x16ToVecI16x8); } + if (op == "i16x8.extend_low_i8x16_u"sv) { return makeUnary(s, UnaryOp::ExtendLowUVecI8x16ToVecI16x8); } goto parse_error; default: goto parse_error; } @@ -978,10 +981,10 @@ switch (op[0]) { case 'h': { switch (op[24]) { case 's': - if (strcmp(op, "i16x8.extmul_high_i8x16_s") == 0) { return makeBinary(s, BinaryOp::ExtMulHighSVecI16x8); } + if (op == "i16x8.extmul_high_i8x16_s"sv) { return makeBinary(s, BinaryOp::ExtMulHighSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.extmul_high_i8x16_u") == 0) { return makeBinary(s, BinaryOp::ExtMulHighUVecI16x8); } + if (op == "i16x8.extmul_high_i8x16_u"sv) { return makeBinary(s, BinaryOp::ExtMulHighUVecI16x8); } goto parse_error; default: goto parse_error; } @@ -989,10 +992,10 @@ switch (op[0]) { case 'l': { switch (op[23]) { case 's': - if (strcmp(op, "i16x8.extmul_low_i8x16_s") == 0) { return makeBinary(s, BinaryOp::ExtMulLowSVecI16x8); } + if (op == "i16x8.extmul_low_i8x16_s"sv) { return makeBinary(s, BinaryOp::ExtMulLowSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.extmul_low_i8x16_u") == 0) { return makeBinary(s, BinaryOp::ExtMulLowUVecI16x8); } + if (op == "i16x8.extmul_low_i8x16_u"sv) { return makeBinary(s, BinaryOp::ExtMulLowUVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1003,10 +1006,10 @@ switch (op[0]) { case 'r': { switch (op[19]) { case 's': - if (strcmp(op, "i16x8.extract_lane_s") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneSVecI16x8, 8); } + if (op == "i16x8.extract_lane_s"sv) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneSVecI16x8, 8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.extract_lane_u") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneUVecI16x8, 8); } + if (op == "i16x8.extract_lane_u"sv) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneUVecI16x8, 8); } goto parse_error; default: goto parse_error; } @@ -1022,10 +1025,10 @@ switch (op[0]) { case 'e': { switch (op[9]) { case 's': - if (strcmp(op, "i16x8.ge_s") == 0) { return makeBinary(s, BinaryOp::GeSVecI16x8); } + if (op == "i16x8.ge_s"sv) { return makeBinary(s, BinaryOp::GeSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.ge_u") == 0) { return makeBinary(s, BinaryOp::GeUVecI16x8); } + if (op == "i16x8.ge_u"sv) { return makeBinary(s, BinaryOp::GeUVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1033,10 +1036,10 @@ switch (op[0]) { case 't': { switch (op[9]) { case 's': - if (strcmp(op, "i16x8.gt_s") == 0) { return makeBinary(s, BinaryOp::GtSVecI16x8); } + if (op == "i16x8.gt_s"sv) { return makeBinary(s, BinaryOp::GtSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.gt_u") == 0) { return makeBinary(s, BinaryOp::GtUVecI16x8); } + if (op == "i16x8.gt_u"sv) { return makeBinary(s, BinaryOp::GtUVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1047,15 +1050,15 @@ switch (op[0]) { case 'l': { switch (op[7]) { case 'a': - if (strcmp(op, "i16x8.laneselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::LaneselectI16x8); } + if (op == "i16x8.laneselect"sv) { return makeSIMDTernary(s, SIMDTernaryOp::LaneselectI16x8); } goto parse_error; case 'e': { switch (op[9]) { case 's': - if (strcmp(op, "i16x8.le_s") == 0) { return makeBinary(s, BinaryOp::LeSVecI16x8); } + if (op == "i16x8.le_s"sv) { return makeBinary(s, BinaryOp::LeSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.le_u") == 0) { return makeBinary(s, BinaryOp::LeUVecI16x8); } + if (op == "i16x8.le_u"sv) { return makeBinary(s, BinaryOp::LeUVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1063,10 +1066,10 @@ switch (op[0]) { case 't': { switch (op[9]) { case 's': - if (strcmp(op, "i16x8.lt_s") == 0) { return makeBinary(s, BinaryOp::LtSVecI16x8); } + if (op == "i16x8.lt_s"sv) { return makeBinary(s, BinaryOp::LtSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.lt_u") == 0) { return makeBinary(s, BinaryOp::LtUVecI16x8); } + if (op == "i16x8.lt_u"sv) { return makeBinary(s, BinaryOp::LtUVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1079,10 +1082,10 @@ switch (op[0]) { case 'a': { switch (op[10]) { case 's': - if (strcmp(op, "i16x8.max_s") == 0) { return makeBinary(s, BinaryOp::MaxSVecI16x8); } + if (op == "i16x8.max_s"sv) { return makeBinary(s, BinaryOp::MaxSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.max_u") == 0) { return makeBinary(s, BinaryOp::MaxUVecI16x8); } + if (op == "i16x8.max_u"sv) { return makeBinary(s, BinaryOp::MaxUVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1090,16 +1093,16 @@ switch (op[0]) { case 'i': { switch (op[10]) { case 's': - if (strcmp(op, "i16x8.min_s") == 0) { return makeBinary(s, BinaryOp::MinSVecI16x8); } + if (op == "i16x8.min_s"sv) { return makeBinary(s, BinaryOp::MinSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.min_u") == 0) { return makeBinary(s, BinaryOp::MinUVecI16x8); } + if (op == "i16x8.min_u"sv) { return makeBinary(s, BinaryOp::MinUVecI16x8); } goto parse_error; default: goto parse_error; } } case 'u': - if (strcmp(op, "i16x8.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI16x8); } + if (op == "i16x8.mul"sv) { return makeBinary(s, BinaryOp::MulVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1109,10 +1112,10 @@ switch (op[0]) { case 'a': { switch (op[19]) { case 's': - if (strcmp(op, "i16x8.narrow_i32x4_s") == 0) { return makeBinary(s, BinaryOp::NarrowSVecI32x4ToVecI16x8); } + if (op == "i16x8.narrow_i32x4_s"sv) { return makeBinary(s, BinaryOp::NarrowSVecI32x4ToVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.narrow_i32x4_u") == 0) { return makeBinary(s, BinaryOp::NarrowUVecI32x4ToVecI16x8); } + if (op == "i16x8.narrow_i32x4_u"sv) { return makeBinary(s, BinaryOp::NarrowUVecI32x4ToVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1120,10 +1123,10 @@ switch (op[0]) { case 'e': { switch (op[8]) { case '\0': - if (strcmp(op, "i16x8.ne") == 0) { return makeBinary(s, BinaryOp::NeVecI16x8); } + if (op == "i16x8.ne"sv) { return makeBinary(s, BinaryOp::NeVecI16x8); } goto parse_error; case 'g': - if (strcmp(op, "i16x8.neg") == 0) { return makeUnary(s, UnaryOp::NegVecI16x8); } + if (op == "i16x8.neg"sv) { return makeUnary(s, UnaryOp::NegVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1132,15 +1135,15 @@ switch (op[0]) { } } case 'q': - if (strcmp(op, "i16x8.q15mulr_sat_s") == 0) { return makeBinary(s, BinaryOp::Q15MulrSatSVecI16x8); } + if (op == "i16x8.q15mulr_sat_s"sv) { return makeBinary(s, BinaryOp::Q15MulrSatSVecI16x8); } goto parse_error; case 'r': { switch (op[8]) { case 'l': - if (strcmp(op, "i16x8.relaxed_q15mulr_s") == 0) { return makeBinary(s, BinaryOp::RelaxedQ15MulrSVecI16x8); } + if (op == "i16x8.relaxed_q15mulr_s"sv) { return makeBinary(s, BinaryOp::RelaxedQ15MulrSVecI16x8); } goto parse_error; case 'p': - if (strcmp(op, "i16x8.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI16x8, 8); } + if (op == "i16x8.replace_lane"sv) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI16x8, 8); } goto parse_error; default: goto parse_error; } @@ -1150,15 +1153,15 @@ switch (op[0]) { case 'h': { switch (op[8]) { case 'l': - if (strcmp(op, "i16x8.shl") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShlVecI16x8); } + if (op == "i16x8.shl"sv) { return makeSIMDShift(s, SIMDShiftOp::ShlVecI16x8); } goto parse_error; case 'r': { switch (op[10]) { case 's': - if (strcmp(op, "i16x8.shr_s") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShrSVecI16x8); } + if (op == "i16x8.shr_s"sv) { return makeSIMDShift(s, SIMDShiftOp::ShrSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.shr_u") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShrUVecI16x8); } + if (op == "i16x8.shr_u"sv) { return makeSIMDShift(s, SIMDShiftOp::ShrUVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1167,20 +1170,20 @@ switch (op[0]) { } } case 'p': - if (strcmp(op, "i16x8.splat") == 0) { return makeUnary(s, UnaryOp::SplatVecI16x8); } + if (op == "i16x8.splat"sv) { return makeUnary(s, UnaryOp::SplatVecI16x8); } goto parse_error; case 'u': { switch (op[9]) { case '\0': - if (strcmp(op, "i16x8.sub") == 0) { return makeBinary(s, BinaryOp::SubVecI16x8); } + if (op == "i16x8.sub"sv) { return makeBinary(s, BinaryOp::SubVecI16x8); } goto parse_error; case '_': { switch (op[14]) { case 's': - if (strcmp(op, "i16x8.sub_sat_s") == 0) { return makeBinary(s, BinaryOp::SubSatSVecI16x8); } + if (op == "i16x8.sub_sat_s"sv) { return makeBinary(s, BinaryOp::SubSatSVecI16x8); } goto parse_error; case 'u': - if (strcmp(op, "i16x8.sub_sat_u") == 0) { return makeBinary(s, BinaryOp::SubSatUVecI16x8); } + if (op == "i16x8.sub_sat_u"sv) { return makeBinary(s, BinaryOp::SubSatUVecI16x8); } goto parse_error; default: goto parse_error; } @@ -1201,16 +1204,16 @@ switch (op[0]) { case 'g': { switch (op[8]) { case 's': - if (strcmp(op, "i31.get_s") == 0) { return makeI31Get(s, true); } + if (op == "i31.get_s"sv) { return makeI31Get(s, true); } goto parse_error; case 'u': - if (strcmp(op, "i31.get_u") == 0) { return makeI31Get(s, false); } + if (op == "i31.get_u"sv) { return makeI31Get(s, false); } goto parse_error; default: goto parse_error; } } case 'n': - if (strcmp(op, "i31.new") == 0) { return makeI31New(s); } + if (op == "i31.new"sv) { return makeI31New(s); } goto parse_error; default: goto parse_error; } @@ -1222,23 +1225,23 @@ switch (op[0]) { case 'a': { switch (op[5]) { case 'd': - if (strcmp(op, "i32.add") == 0) { return makeBinary(s, BinaryOp::AddInt32); } + if (op == "i32.add"sv) { return makeBinary(s, BinaryOp::AddInt32); } goto parse_error; case 'n': - if (strcmp(op, "i32.and") == 0) { return makeBinary(s, BinaryOp::AndInt32); } + if (op == "i32.and"sv) { return makeBinary(s, BinaryOp::AndInt32); } goto parse_error; case 't': { switch (op[11]) { case 'l': { switch (op[15]) { case '\0': - if (strcmp(op, "i32.atomic.load") == 0) { return makeLoad(s, Type::i32, /*isAtomic=*/true); } + if (op == "i32.atomic.load"sv) { return makeLoad(s, Type::i32, /*isAtomic=*/true); } goto parse_error; case '1': - if (strcmp(op, "i32.atomic.load16_u") == 0) { return makeLoad(s, Type::i32, /*isAtomic=*/true); } + if (op == "i32.atomic.load16_u"sv) { return makeLoad(s, Type::i32, /*isAtomic=*/true); } goto parse_error; case '8': - if (strcmp(op, "i32.atomic.load8_u") == 0) { return makeLoad(s, Type::i32, /*isAtomic=*/true); } + if (op == "i32.atomic.load8_u"sv) { return makeLoad(s, Type::i32, /*isAtomic=*/true); } goto parse_error; default: goto parse_error; } @@ -1250,30 +1253,30 @@ switch (op[0]) { case 'a': { switch (op[16]) { case 'd': - if (strcmp(op, "i32.atomic.rmw.add") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw.add"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'n': - if (strcmp(op, "i32.atomic.rmw.and") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw.and"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; default: goto parse_error; } } case 'c': - if (strcmp(op, "i32.atomic.rmw.cmpxchg") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw.cmpxchg"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'o': - if (strcmp(op, "i32.atomic.rmw.or") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw.or"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 's': - if (strcmp(op, "i32.atomic.rmw.sub") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw.sub"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'x': { switch (op[16]) { case 'c': - if (strcmp(op, "i32.atomic.rmw.xchg") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw.xchg"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'o': - if (strcmp(op, "i32.atomic.rmw.xor") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw.xor"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; default: goto parse_error; } @@ -1286,30 +1289,30 @@ switch (op[0]) { case 'a': { switch (op[18]) { case 'd': - if (strcmp(op, "i32.atomic.rmw16.add_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw16.add_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'n': - if (strcmp(op, "i32.atomic.rmw16.and_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw16.and_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; default: goto parse_error; } } case 'c': - if (strcmp(op, "i32.atomic.rmw16.cmpxchg_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw16.cmpxchg_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'o': - if (strcmp(op, "i32.atomic.rmw16.or_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw16.or_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 's': - if (strcmp(op, "i32.atomic.rmw16.sub_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw16.sub_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'x': { switch (op[18]) { case 'c': - if (strcmp(op, "i32.atomic.rmw16.xchg_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw16.xchg_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'o': - if (strcmp(op, "i32.atomic.rmw16.xor_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw16.xor_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; default: goto parse_error; } @@ -1322,30 +1325,30 @@ switch (op[0]) { case 'a': { switch (op[17]) { case 'd': - if (strcmp(op, "i32.atomic.rmw8.add_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw8.add_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'n': - if (strcmp(op, "i32.atomic.rmw8.and_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw8.and_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; default: goto parse_error; } } case 'c': - if (strcmp(op, "i32.atomic.rmw8.cmpxchg_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw8.cmpxchg_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'o': - if (strcmp(op, "i32.atomic.rmw8.or_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw8.or_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 's': - if (strcmp(op, "i32.atomic.rmw8.sub_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw8.sub_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'x': { switch (op[17]) { case 'c': - if (strcmp(op, "i32.atomic.rmw8.xchg_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw8.xchg_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; case 'o': - if (strcmp(op, "i32.atomic.rmw8.xor_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } + if (op == "i32.atomic.rmw8.xor_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i32); } goto parse_error; default: goto parse_error; } @@ -1359,13 +1362,13 @@ switch (op[0]) { case 's': { switch (op[16]) { case '\0': - if (strcmp(op, "i32.atomic.store") == 0) { return makeStore(s, Type::i32, /*isAtomic=*/true); } + if (op == "i32.atomic.store"sv) { return makeStore(s, Type::i32, /*isAtomic=*/true); } goto parse_error; case '1': - if (strcmp(op, "i32.atomic.store16") == 0) { return makeStore(s, Type::i32, /*isAtomic=*/true); } + if (op == "i32.atomic.store16"sv) { return makeStore(s, Type::i32, /*isAtomic=*/true); } goto parse_error; case '8': - if (strcmp(op, "i32.atomic.store8") == 0) { return makeStore(s, Type::i32, /*isAtomic=*/true); } + if (op == "i32.atomic.store8"sv) { return makeStore(s, Type::i32, /*isAtomic=*/true); } goto parse_error; default: goto parse_error; } @@ -1379,13 +1382,13 @@ switch (op[0]) { case 'c': { switch (op[5]) { case 'l': - if (strcmp(op, "i32.clz") == 0) { return makeUnary(s, UnaryOp::ClzInt32); } + if (op == "i32.clz"sv) { return makeUnary(s, UnaryOp::ClzInt32); } goto parse_error; case 'o': - if (strcmp(op, "i32.const") == 0) { return makeConst(s, Type::i32); } + if (op == "i32.const"sv) { return makeConst(s, Type::i32); } goto parse_error; case 't': - if (strcmp(op, "i32.ctz") == 0) { return makeUnary(s, UnaryOp::CtzInt32); } + if (op == "i32.ctz"sv) { return makeUnary(s, UnaryOp::CtzInt32); } goto parse_error; default: goto parse_error; } @@ -1393,10 +1396,10 @@ switch (op[0]) { case 'd': { switch (op[8]) { case 's': - if (strcmp(op, "i32.div_s") == 0) { return makeBinary(s, BinaryOp::DivSInt32); } + if (op == "i32.div_s"sv) { return makeBinary(s, BinaryOp::DivSInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.div_u") == 0) { return makeBinary(s, BinaryOp::DivUInt32); } + if (op == "i32.div_u"sv) { return makeBinary(s, BinaryOp::DivUInt32); } goto parse_error; default: goto parse_error; } @@ -1406,10 +1409,10 @@ switch (op[0]) { case 'q': { switch (op[6]) { case '\0': - if (strcmp(op, "i32.eq") == 0) { return makeBinary(s, BinaryOp::EqInt32); } + if (op == "i32.eq"sv) { return makeBinary(s, BinaryOp::EqInt32); } goto parse_error; case 'z': - if (strcmp(op, "i32.eqz") == 0) { return makeUnary(s, UnaryOp::EqZInt32); } + if (op == "i32.eqz"sv) { return makeUnary(s, UnaryOp::EqZInt32); } goto parse_error; default: goto parse_error; } @@ -1417,10 +1420,10 @@ switch (op[0]) { case 'x': { switch (op[10]) { case '1': - if (strcmp(op, "i32.extend16_s") == 0) { return makeUnary(s, UnaryOp::ExtendS16Int32); } + if (op == "i32.extend16_s"sv) { return makeUnary(s, UnaryOp::ExtendS16Int32); } goto parse_error; case '8': - if (strcmp(op, "i32.extend8_s") == 0) { return makeUnary(s, UnaryOp::ExtendS8Int32); } + if (op == "i32.extend8_s"sv) { return makeUnary(s, UnaryOp::ExtendS8Int32); } goto parse_error; default: goto parse_error; } @@ -1433,10 +1436,10 @@ switch (op[0]) { case 'e': { switch (op[7]) { case 's': - if (strcmp(op, "i32.ge_s") == 0) { return makeBinary(s, BinaryOp::GeSInt32); } + if (op == "i32.ge_s"sv) { return makeBinary(s, BinaryOp::GeSInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.ge_u") == 0) { return makeBinary(s, BinaryOp::GeUInt32); } + if (op == "i32.ge_u"sv) { return makeBinary(s, BinaryOp::GeUInt32); } goto parse_error; default: goto parse_error; } @@ -1444,10 +1447,10 @@ switch (op[0]) { case 't': { switch (op[7]) { case 's': - if (strcmp(op, "i32.gt_s") == 0) { return makeBinary(s, BinaryOp::GtSInt32); } + if (op == "i32.gt_s"sv) { return makeBinary(s, BinaryOp::GtSInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.gt_u") == 0) { return makeBinary(s, BinaryOp::GtUInt32); } + if (op == "i32.gt_u"sv) { return makeBinary(s, BinaryOp::GtUInt32); } goto parse_error; default: goto parse_error; } @@ -1460,10 +1463,10 @@ switch (op[0]) { case 'e': { switch (op[7]) { case 's': - if (strcmp(op, "i32.le_s") == 0) { return makeBinary(s, BinaryOp::LeSInt32); } + if (op == "i32.le_s"sv) { return makeBinary(s, BinaryOp::LeSInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.le_u") == 0) { return makeBinary(s, BinaryOp::LeUInt32); } + if (op == "i32.le_u"sv) { return makeBinary(s, BinaryOp::LeUInt32); } goto parse_error; default: goto parse_error; } @@ -1471,15 +1474,15 @@ switch (op[0]) { case 'o': { switch (op[8]) { case '\0': - if (strcmp(op, "i32.load") == 0) { return makeLoad(s, Type::i32, /*isAtomic=*/false); } + if (op == "i32.load"sv) { return makeLoad(s, Type::i32, /*isAtomic=*/false); } goto parse_error; case '1': { switch (op[11]) { case 's': - if (strcmp(op, "i32.load16_s") == 0) { return makeLoad(s, Type::i32, /*isAtomic=*/false); } + if (op == "i32.load16_s"sv) { return makeLoad(s, Type::i32, /*isAtomic=*/false); } goto parse_error; case 'u': - if (strcmp(op, "i32.load16_u") == 0) { return makeLoad(s, Type::i32, /*isAtomic=*/false); } + if (op == "i32.load16_u"sv) { return makeLoad(s, Type::i32, /*isAtomic=*/false); } goto parse_error; default: goto parse_error; } @@ -1487,10 +1490,10 @@ switch (op[0]) { case '8': { switch (op[10]) { case 's': - if (strcmp(op, "i32.load8_s") == 0) { return makeLoad(s, Type::i32, /*isAtomic=*/false); } + if (op == "i32.load8_s"sv) { return makeLoad(s, Type::i32, /*isAtomic=*/false); } goto parse_error; case 'u': - if (strcmp(op, "i32.load8_u") == 0) { return makeLoad(s, Type::i32, /*isAtomic=*/false); } + if (op == "i32.load8_u"sv) { return makeLoad(s, Type::i32, /*isAtomic=*/false); } goto parse_error; default: goto parse_error; } @@ -1501,10 +1504,10 @@ switch (op[0]) { case 't': { switch (op[7]) { case 's': - if (strcmp(op, "i32.lt_s") == 0) { return makeBinary(s, BinaryOp::LtSInt32); } + if (op == "i32.lt_s"sv) { return makeBinary(s, BinaryOp::LtSInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.lt_u") == 0) { return makeBinary(s, BinaryOp::LtUInt32); } + if (op == "i32.lt_u"sv) { return makeBinary(s, BinaryOp::LtUInt32); } goto parse_error; default: goto parse_error; } @@ -1513,31 +1516,31 @@ switch (op[0]) { } } case 'm': - if (strcmp(op, "i32.mul") == 0) { return makeBinary(s, BinaryOp::MulInt32); } + if (op == "i32.mul"sv) { return makeBinary(s, BinaryOp::MulInt32); } goto parse_error; case 'n': - if (strcmp(op, "i32.ne") == 0) { return makeBinary(s, BinaryOp::NeInt32); } + if (op == "i32.ne"sv) { return makeBinary(s, BinaryOp::NeInt32); } goto parse_error; case 'o': - if (strcmp(op, "i32.or") == 0) { return makeBinary(s, BinaryOp::OrInt32); } + if (op == "i32.or"sv) { return makeBinary(s, BinaryOp::OrInt32); } goto parse_error; case 'p': - if (strcmp(op, "i32.popcnt") == 0) { return makeUnary(s, UnaryOp::PopcntInt32); } + if (op == "i32.popcnt"sv) { return makeUnary(s, UnaryOp::PopcntInt32); } goto parse_error; case 'r': { switch (op[5]) { case 'e': { switch (op[6]) { case 'i': - if (strcmp(op, "i32.reinterpret_f32") == 0) { return makeUnary(s, UnaryOp::ReinterpretFloat32); } + if (op == "i32.reinterpret_f32"sv) { return makeUnary(s, UnaryOp::ReinterpretFloat32); } goto parse_error; case 'm': { switch (op[8]) { case 's': - if (strcmp(op, "i32.rem_s") == 0) { return makeBinary(s, BinaryOp::RemSInt32); } + if (op == "i32.rem_s"sv) { return makeBinary(s, BinaryOp::RemSInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.rem_u") == 0) { return makeBinary(s, BinaryOp::RemUInt32); } + if (op == "i32.rem_u"sv) { return makeBinary(s, BinaryOp::RemUInt32); } goto parse_error; default: goto parse_error; } @@ -1548,10 +1551,10 @@ switch (op[0]) { case 'o': { switch (op[7]) { case 'l': - if (strcmp(op, "i32.rotl") == 0) { return makeBinary(s, BinaryOp::RotLInt32); } + if (op == "i32.rotl"sv) { return makeBinary(s, BinaryOp::RotLInt32); } goto parse_error; case 'r': - if (strcmp(op, "i32.rotr") == 0) { return makeBinary(s, BinaryOp::RotRInt32); } + if (op == "i32.rotr"sv) { return makeBinary(s, BinaryOp::RotRInt32); } goto parse_error; default: goto parse_error; } @@ -1564,15 +1567,15 @@ switch (op[0]) { case 'h': { switch (op[6]) { case 'l': - if (strcmp(op, "i32.shl") == 0) { return makeBinary(s, BinaryOp::ShlInt32); } + if (op == "i32.shl"sv) { return makeBinary(s, BinaryOp::ShlInt32); } goto parse_error; case 'r': { switch (op[8]) { case 's': - if (strcmp(op, "i32.shr_s") == 0) { return makeBinary(s, BinaryOp::ShrSInt32); } + if (op == "i32.shr_s"sv) { return makeBinary(s, BinaryOp::ShrSInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.shr_u") == 0) { return makeBinary(s, BinaryOp::ShrUInt32); } + if (op == "i32.shr_u"sv) { return makeBinary(s, BinaryOp::ShrUInt32); } goto parse_error; default: goto parse_error; } @@ -1583,19 +1586,19 @@ switch (op[0]) { case 't': { switch (op[9]) { case '\0': - if (strcmp(op, "i32.store") == 0) { return makeStore(s, Type::i32, /*isAtomic=*/false); } + if (op == "i32.store"sv) { return makeStore(s, Type::i32, /*isAtomic=*/false); } goto parse_error; case '1': - if (strcmp(op, "i32.store16") == 0) { return makeStore(s, Type::i32, /*isAtomic=*/false); } + if (op == "i32.store16"sv) { return makeStore(s, Type::i32, /*isAtomic=*/false); } goto parse_error; case '8': - if (strcmp(op, "i32.store8") == 0) { return makeStore(s, Type::i32, /*isAtomic=*/false); } + if (op == "i32.store8"sv) { return makeStore(s, Type::i32, /*isAtomic=*/false); } goto parse_error; default: goto parse_error; } } case 'u': - if (strcmp(op, "i32.sub") == 0) { return makeBinary(s, BinaryOp::SubInt32); } + if (op == "i32.sub"sv) { return makeBinary(s, BinaryOp::SubInt32); } goto parse_error; default: goto parse_error; } @@ -1607,10 +1610,10 @@ switch (op[0]) { case '3': { switch (op[14]) { case 's': - if (strcmp(op, "i32.trunc_f32_s") == 0) { return makeUnary(s, UnaryOp::TruncSFloat32ToInt32); } + if (op == "i32.trunc_f32_s"sv) { return makeUnary(s, UnaryOp::TruncSFloat32ToInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.trunc_f32_u") == 0) { return makeUnary(s, UnaryOp::TruncUFloat32ToInt32); } + if (op == "i32.trunc_f32_u"sv) { return makeUnary(s, UnaryOp::TruncUFloat32ToInt32); } goto parse_error; default: goto parse_error; } @@ -1618,10 +1621,10 @@ switch (op[0]) { case '6': { switch (op[14]) { case 's': - if (strcmp(op, "i32.trunc_f64_s") == 0) { return makeUnary(s, UnaryOp::TruncSFloat64ToInt32); } + if (op == "i32.trunc_f64_s"sv) { return makeUnary(s, UnaryOp::TruncSFloat64ToInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.trunc_f64_u") == 0) { return makeUnary(s, UnaryOp::TruncUFloat64ToInt32); } + if (op == "i32.trunc_f64_u"sv) { return makeUnary(s, UnaryOp::TruncUFloat64ToInt32); } goto parse_error; default: goto parse_error; } @@ -1634,10 +1637,10 @@ switch (op[0]) { case '3': { switch (op[18]) { case 's': - if (strcmp(op, "i32.trunc_sat_f32_s") == 0) { return makeUnary(s, UnaryOp::TruncSatSFloat32ToInt32); } + if (op == "i32.trunc_sat_f32_s"sv) { return makeUnary(s, UnaryOp::TruncSatSFloat32ToInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.trunc_sat_f32_u") == 0) { return makeUnary(s, UnaryOp::TruncSatUFloat32ToInt32); } + if (op == "i32.trunc_sat_f32_u"sv) { return makeUnary(s, UnaryOp::TruncSatUFloat32ToInt32); } goto parse_error; default: goto parse_error; } @@ -1645,10 +1648,10 @@ switch (op[0]) { case '6': { switch (op[18]) { case 's': - if (strcmp(op, "i32.trunc_sat_f64_s") == 0) { return makeUnary(s, UnaryOp::TruncSatSFloat64ToInt32); } + if (op == "i32.trunc_sat_f64_s"sv) { return makeUnary(s, UnaryOp::TruncSatSFloat64ToInt32); } goto parse_error; case 'u': - if (strcmp(op, "i32.trunc_sat_f64_u") == 0) { return makeUnary(s, UnaryOp::TruncSatUFloat64ToInt32); } + if (op == "i32.trunc_sat_f64_u"sv) { return makeUnary(s, UnaryOp::TruncSatUFloat64ToInt32); } goto parse_error; default: goto parse_error; } @@ -1660,10 +1663,10 @@ switch (op[0]) { } } case 'w': - if (strcmp(op, "i32.wrap_i64") == 0) { return makeUnary(s, UnaryOp::WrapInt64); } + if (op == "i32.wrap_i64"sv) { return makeUnary(s, UnaryOp::WrapInt64); } goto parse_error; case 'x': - if (strcmp(op, "i32.xor") == 0) { return makeBinary(s, BinaryOp::XorInt32); } + if (op == "i32.xor"sv) { return makeBinary(s, BinaryOp::XorInt32); } goto parse_error; default: goto parse_error; } @@ -1673,27 +1676,27 @@ switch (op[0]) { case 'a': { switch (op[7]) { case 'b': - if (strcmp(op, "i32x4.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecI32x4); } + if (op == "i32x4.abs"sv) { return makeUnary(s, UnaryOp::AbsVecI32x4); } goto parse_error; case 'd': - if (strcmp(op, "i32x4.add") == 0) { return makeBinary(s, BinaryOp::AddVecI32x4); } + if (op == "i32x4.add"sv) { return makeBinary(s, BinaryOp::AddVecI32x4); } goto parse_error; case 'l': - if (strcmp(op, "i32x4.all_true") == 0) { return makeUnary(s, UnaryOp::AllTrueVecI32x4); } + if (op == "i32x4.all_true"sv) { return makeUnary(s, UnaryOp::AllTrueVecI32x4); } goto parse_error; default: goto parse_error; } } case 'b': - if (strcmp(op, "i32x4.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI32x4); } + if (op == "i32x4.bitmask"sv) { return makeUnary(s, UnaryOp::BitmaskVecI32x4); } goto parse_error; case 'd': { switch (op[11]) { case '1': - if (strcmp(op, "i32x4.dot_i16x8_s") == 0) { return makeBinary(s, BinaryOp::DotSVecI16x8ToVecI32x4); } + if (op == "i32x4.dot_i16x8_s"sv) { return makeBinary(s, BinaryOp::DotSVecI16x8ToVecI32x4); } goto parse_error; case '8': - if (strcmp(op, "i32x4.dot_i8x16_i7x16_add_s") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::DotI8x16I7x16AddSToVecI32x4); } + if (op == "i32x4.dot_i8x16_i7x16_add_s"sv) { return makeSIMDTernary(s, SIMDTernaryOp::DotI8x16I7x16AddSToVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1701,17 +1704,17 @@ switch (op[0]) { case 'e': { switch (op[7]) { case 'q': - if (strcmp(op, "i32x4.eq") == 0) { return makeBinary(s, BinaryOp::EqVecI32x4); } + if (op == "i32x4.eq"sv) { return makeBinary(s, BinaryOp::EqVecI32x4); } goto parse_error; case 'x': { switch (op[9]) { case 'a': { switch (op[28]) { case 's': - if (strcmp(op, "i32x4.extadd_pairwise_i16x8_s") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseSVecI16x8ToI32x4); } + if (op == "i32x4.extadd_pairwise_i16x8_s"sv) { return makeUnary(s, UnaryOp::ExtAddPairwiseSVecI16x8ToI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.extadd_pairwise_i16x8_u") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseUVecI16x8ToI32x4); } + if (op == "i32x4.extadd_pairwise_i16x8_u"sv) { return makeUnary(s, UnaryOp::ExtAddPairwiseUVecI16x8ToI32x4); } goto parse_error; default: goto parse_error; } @@ -1721,10 +1724,10 @@ switch (op[0]) { case 'h': { switch (op[24]) { case 's': - if (strcmp(op, "i32x4.extend_high_i16x8_s") == 0) { return makeUnary(s, UnaryOp::ExtendHighSVecI16x8ToVecI32x4); } + if (op == "i32x4.extend_high_i16x8_s"sv) { return makeUnary(s, UnaryOp::ExtendHighSVecI16x8ToVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.extend_high_i16x8_u") == 0) { return makeUnary(s, UnaryOp::ExtendHighUVecI16x8ToVecI32x4); } + if (op == "i32x4.extend_high_i16x8_u"sv) { return makeUnary(s, UnaryOp::ExtendHighUVecI16x8ToVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1732,10 +1735,10 @@ switch (op[0]) { case 'l': { switch (op[23]) { case 's': - if (strcmp(op, "i32x4.extend_low_i16x8_s") == 0) { return makeUnary(s, UnaryOp::ExtendLowSVecI16x8ToVecI32x4); } + if (op == "i32x4.extend_low_i16x8_s"sv) { return makeUnary(s, UnaryOp::ExtendLowSVecI16x8ToVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.extend_low_i16x8_u") == 0) { return makeUnary(s, UnaryOp::ExtendLowUVecI16x8ToVecI32x4); } + if (op == "i32x4.extend_low_i16x8_u"sv) { return makeUnary(s, UnaryOp::ExtendLowUVecI16x8ToVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1748,10 +1751,10 @@ switch (op[0]) { case 'h': { switch (op[24]) { case 's': - if (strcmp(op, "i32x4.extmul_high_i16x8_s") == 0) { return makeBinary(s, BinaryOp::ExtMulHighSVecI32x4); } + if (op == "i32x4.extmul_high_i16x8_s"sv) { return makeBinary(s, BinaryOp::ExtMulHighSVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.extmul_high_i16x8_u") == 0) { return makeBinary(s, BinaryOp::ExtMulHighUVecI32x4); } + if (op == "i32x4.extmul_high_i16x8_u"sv) { return makeBinary(s, BinaryOp::ExtMulHighUVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1759,10 +1762,10 @@ switch (op[0]) { case 'l': { switch (op[23]) { case 's': - if (strcmp(op, "i32x4.extmul_low_i16x8_s") == 0) { return makeBinary(s, BinaryOp::ExtMulLowSVecI32x4); } + if (op == "i32x4.extmul_low_i16x8_s"sv) { return makeBinary(s, BinaryOp::ExtMulLowSVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.extmul_low_i16x8_u") == 0) { return makeBinary(s, BinaryOp::ExtMulLowUVecI32x4); } + if (op == "i32x4.extmul_low_i16x8_u"sv) { return makeBinary(s, BinaryOp::ExtMulLowUVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1771,7 +1774,7 @@ switch (op[0]) { } } case 'r': - if (strcmp(op, "i32x4.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI32x4, 4); } + if (op == "i32x4.extract_lane"sv) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI32x4, 4); } goto parse_error; default: goto parse_error; } @@ -1784,10 +1787,10 @@ switch (op[0]) { case 'e': { switch (op[9]) { case 's': - if (strcmp(op, "i32x4.ge_s") == 0) { return makeBinary(s, BinaryOp::GeSVecI32x4); } + if (op == "i32x4.ge_s"sv) { return makeBinary(s, BinaryOp::GeSVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.ge_u") == 0) { return makeBinary(s, BinaryOp::GeUVecI32x4); } + if (op == "i32x4.ge_u"sv) { return makeBinary(s, BinaryOp::GeUVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1795,10 +1798,10 @@ switch (op[0]) { case 't': { switch (op[9]) { case 's': - if (strcmp(op, "i32x4.gt_s") == 0) { return makeBinary(s, BinaryOp::GtSVecI32x4); } + if (op == "i32x4.gt_s"sv) { return makeBinary(s, BinaryOp::GtSVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.gt_u") == 0) { return makeBinary(s, BinaryOp::GtUVecI32x4); } + if (op == "i32x4.gt_u"sv) { return makeBinary(s, BinaryOp::GtUVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1809,15 +1812,15 @@ switch (op[0]) { case 'l': { switch (op[7]) { case 'a': - if (strcmp(op, "i32x4.laneselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::LaneselectI32x4); } + if (op == "i32x4.laneselect"sv) { return makeSIMDTernary(s, SIMDTernaryOp::LaneselectI32x4); } goto parse_error; case 'e': { switch (op[9]) { case 's': - if (strcmp(op, "i32x4.le_s") == 0) { return makeBinary(s, BinaryOp::LeSVecI32x4); } + if (op == "i32x4.le_s"sv) { return makeBinary(s, BinaryOp::LeSVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.le_u") == 0) { return makeBinary(s, BinaryOp::LeUVecI32x4); } + if (op == "i32x4.le_u"sv) { return makeBinary(s, BinaryOp::LeUVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1825,10 +1828,10 @@ switch (op[0]) { case 't': { switch (op[9]) { case 's': - if (strcmp(op, "i32x4.lt_s") == 0) { return makeBinary(s, BinaryOp::LtSVecI32x4); } + if (op == "i32x4.lt_s"sv) { return makeBinary(s, BinaryOp::LtSVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.lt_u") == 0) { return makeBinary(s, BinaryOp::LtUVecI32x4); } + if (op == "i32x4.lt_u"sv) { return makeBinary(s, BinaryOp::LtUVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1841,10 +1844,10 @@ switch (op[0]) { case 'a': { switch (op[10]) { case 's': - if (strcmp(op, "i32x4.max_s") == 0) { return makeBinary(s, BinaryOp::MaxSVecI32x4); } + if (op == "i32x4.max_s"sv) { return makeBinary(s, BinaryOp::MaxSVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.max_u") == 0) { return makeBinary(s, BinaryOp::MaxUVecI32x4); } + if (op == "i32x4.max_u"sv) { return makeBinary(s, BinaryOp::MaxUVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1852,16 +1855,16 @@ switch (op[0]) { case 'i': { switch (op[10]) { case 's': - if (strcmp(op, "i32x4.min_s") == 0) { return makeBinary(s, BinaryOp::MinSVecI32x4); } + if (op == "i32x4.min_s"sv) { return makeBinary(s, BinaryOp::MinSVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.min_u") == 0) { return makeBinary(s, BinaryOp::MinUVecI32x4); } + if (op == "i32x4.min_u"sv) { return makeBinary(s, BinaryOp::MinUVecI32x4); } goto parse_error; default: goto parse_error; } } case 'u': - if (strcmp(op, "i32x4.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI32x4); } + if (op == "i32x4.mul"sv) { return makeBinary(s, BinaryOp::MulVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1869,10 +1872,10 @@ switch (op[0]) { case 'n': { switch (op[8]) { case '\0': - if (strcmp(op, "i32x4.ne") == 0) { return makeBinary(s, BinaryOp::NeVecI32x4); } + if (op == "i32x4.ne"sv) { return makeBinary(s, BinaryOp::NeVecI32x4); } goto parse_error; case 'g': - if (strcmp(op, "i32x4.neg") == 0) { return makeUnary(s, UnaryOp::NegVecI32x4); } + if (op == "i32x4.neg"sv) { return makeUnary(s, UnaryOp::NegVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1884,10 +1887,10 @@ switch (op[0]) { case '3': { switch (op[26]) { case 's': - if (strcmp(op, "i32x4.relaxed_trunc_f32x4_s") == 0) { return makeUnary(s, UnaryOp::RelaxedTruncSVecF32x4ToVecI32x4); } + if (op == "i32x4.relaxed_trunc_f32x4_s"sv) { return makeUnary(s, UnaryOp::RelaxedTruncSVecF32x4ToVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.relaxed_trunc_f32x4_u") == 0) { return makeUnary(s, UnaryOp::RelaxedTruncUVecF32x4ToVecI32x4); } + if (op == "i32x4.relaxed_trunc_f32x4_u"sv) { return makeUnary(s, UnaryOp::RelaxedTruncUVecF32x4ToVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1895,10 +1898,10 @@ switch (op[0]) { case '6': { switch (op[26]) { case 's': - if (strcmp(op, "i32x4.relaxed_trunc_f64x2_s_zero") == 0) { return makeUnary(s, UnaryOp::RelaxedTruncZeroSVecF64x2ToVecI32x4); } + if (op == "i32x4.relaxed_trunc_f64x2_s_zero"sv) { return makeUnary(s, UnaryOp::RelaxedTruncZeroSVecF64x2ToVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.relaxed_trunc_f64x2_u_zero") == 0) { return makeUnary(s, UnaryOp::RelaxedTruncZeroUVecF64x2ToVecI32x4); } + if (op == "i32x4.relaxed_trunc_f64x2_u_zero"sv) { return makeUnary(s, UnaryOp::RelaxedTruncZeroUVecF64x2ToVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1907,7 +1910,7 @@ switch (op[0]) { } } case 'p': - if (strcmp(op, "i32x4.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI32x4, 4); } + if (op == "i32x4.replace_lane"sv) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI32x4, 4); } goto parse_error; default: goto parse_error; } @@ -1917,15 +1920,15 @@ switch (op[0]) { case 'h': { switch (op[8]) { case 'l': - if (strcmp(op, "i32x4.shl") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShlVecI32x4); } + if (op == "i32x4.shl"sv) { return makeSIMDShift(s, SIMDShiftOp::ShlVecI32x4); } goto parse_error; case 'r': { switch (op[10]) { case 's': - if (strcmp(op, "i32x4.shr_s") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShrSVecI32x4); } + if (op == "i32x4.shr_s"sv) { return makeSIMDShift(s, SIMDShiftOp::ShrSVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.shr_u") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShrUVecI32x4); } + if (op == "i32x4.shr_u"sv) { return makeSIMDShift(s, SIMDShiftOp::ShrUVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1934,10 +1937,10 @@ switch (op[0]) { } } case 'p': - if (strcmp(op, "i32x4.splat") == 0) { return makeUnary(s, UnaryOp::SplatVecI32x4); } + if (op == "i32x4.splat"sv) { return makeUnary(s, UnaryOp::SplatVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.sub") == 0) { return makeBinary(s, BinaryOp::SubVecI32x4); } + if (op == "i32x4.sub"sv) { return makeBinary(s, BinaryOp::SubVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1947,10 +1950,10 @@ switch (op[0]) { case '3': { switch (op[22]) { case 's': - if (strcmp(op, "i32x4.trunc_sat_f32x4_s") == 0) { return makeUnary(s, UnaryOp::TruncSatSVecF32x4ToVecI32x4); } + if (op == "i32x4.trunc_sat_f32x4_s"sv) { return makeUnary(s, UnaryOp::TruncSatSVecF32x4ToVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.trunc_sat_f32x4_u") == 0) { return makeUnary(s, UnaryOp::TruncSatUVecF32x4ToVecI32x4); } + if (op == "i32x4.trunc_sat_f32x4_u"sv) { return makeUnary(s, UnaryOp::TruncSatUVecF32x4ToVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1958,10 +1961,10 @@ switch (op[0]) { case '6': { switch (op[22]) { case 's': - if (strcmp(op, "i32x4.trunc_sat_f64x2_s_zero") == 0) { return makeUnary(s, UnaryOp::TruncSatZeroSVecF64x2ToVecI32x4); } + if (op == "i32x4.trunc_sat_f64x2_s_zero"sv) { return makeUnary(s, UnaryOp::TruncSatZeroSVecF64x2ToVecI32x4); } goto parse_error; case 'u': - if (strcmp(op, "i32x4.trunc_sat_f64x2_u_zero") == 0) { return makeUnary(s, UnaryOp::TruncSatZeroUVecF64x2ToVecI32x4); } + if (op == "i32x4.trunc_sat_f64x2_u_zero"sv) { return makeUnary(s, UnaryOp::TruncSatZeroUVecF64x2ToVecI32x4); } goto parse_error; default: goto parse_error; } @@ -1985,26 +1988,26 @@ switch (op[0]) { case 'a': { switch (op[5]) { case 'd': - if (strcmp(op, "i64.add") == 0) { return makeBinary(s, BinaryOp::AddInt64); } + if (op == "i64.add"sv) { return makeBinary(s, BinaryOp::AddInt64); } goto parse_error; case 'n': - if (strcmp(op, "i64.and") == 0) { return makeBinary(s, BinaryOp::AndInt64); } + if (op == "i64.and"sv) { return makeBinary(s, BinaryOp::AndInt64); } goto parse_error; case 't': { switch (op[11]) { case 'l': { switch (op[15]) { case '\0': - if (strcmp(op, "i64.atomic.load") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/true); } + if (op == "i64.atomic.load"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/true); } goto parse_error; case '1': - if (strcmp(op, "i64.atomic.load16_u") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/true); } + if (op == "i64.atomic.load16_u"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/true); } goto parse_error; case '3': - if (strcmp(op, "i64.atomic.load32_u") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/true); } + if (op == "i64.atomic.load32_u"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/true); } goto parse_error; case '8': - if (strcmp(op, "i64.atomic.load8_u") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/true); } + if (op == "i64.atomic.load8_u"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/true); } goto parse_error; default: goto parse_error; } @@ -2016,30 +2019,30 @@ switch (op[0]) { case 'a': { switch (op[16]) { case 'd': - if (strcmp(op, "i64.atomic.rmw.add") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw.add"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'n': - if (strcmp(op, "i64.atomic.rmw.and") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw.and"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; default: goto parse_error; } } case 'c': - if (strcmp(op, "i64.atomic.rmw.cmpxchg") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw.cmpxchg"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'o': - if (strcmp(op, "i64.atomic.rmw.or") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw.or"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 's': - if (strcmp(op, "i64.atomic.rmw.sub") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw.sub"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'x': { switch (op[16]) { case 'c': - if (strcmp(op, "i64.atomic.rmw.xchg") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw.xchg"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'o': - if (strcmp(op, "i64.atomic.rmw.xor") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw.xor"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; default: goto parse_error; } @@ -2052,30 +2055,30 @@ switch (op[0]) { case 'a': { switch (op[18]) { case 'd': - if (strcmp(op, "i64.atomic.rmw16.add_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw16.add_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'n': - if (strcmp(op, "i64.atomic.rmw16.and_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw16.and_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; default: goto parse_error; } } case 'c': - if (strcmp(op, "i64.atomic.rmw16.cmpxchg_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw16.cmpxchg_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'o': - if (strcmp(op, "i64.atomic.rmw16.or_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw16.or_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 's': - if (strcmp(op, "i64.atomic.rmw16.sub_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw16.sub_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'x': { switch (op[18]) { case 'c': - if (strcmp(op, "i64.atomic.rmw16.xchg_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw16.xchg_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'o': - if (strcmp(op, "i64.atomic.rmw16.xor_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw16.xor_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; default: goto parse_error; } @@ -2088,30 +2091,30 @@ switch (op[0]) { case 'a': { switch (op[18]) { case 'd': - if (strcmp(op, "i64.atomic.rmw32.add_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw32.add_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'n': - if (strcmp(op, "i64.atomic.rmw32.and_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw32.and_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; default: goto parse_error; } } case 'c': - if (strcmp(op, "i64.atomic.rmw32.cmpxchg_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw32.cmpxchg_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'o': - if (strcmp(op, "i64.atomic.rmw32.or_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw32.or_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 's': - if (strcmp(op, "i64.atomic.rmw32.sub_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw32.sub_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'x': { switch (op[18]) { case 'c': - if (strcmp(op, "i64.atomic.rmw32.xchg_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw32.xchg_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'o': - if (strcmp(op, "i64.atomic.rmw32.xor_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw32.xor_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; default: goto parse_error; } @@ -2124,30 +2127,30 @@ switch (op[0]) { case 'a': { switch (op[17]) { case 'd': - if (strcmp(op, "i64.atomic.rmw8.add_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw8.add_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'n': - if (strcmp(op, "i64.atomic.rmw8.and_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw8.and_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; default: goto parse_error; } } case 'c': - if (strcmp(op, "i64.atomic.rmw8.cmpxchg_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw8.cmpxchg_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'o': - if (strcmp(op, "i64.atomic.rmw8.or_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw8.or_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 's': - if (strcmp(op, "i64.atomic.rmw8.sub_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw8.sub_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'x': { switch (op[17]) { case 'c': - if (strcmp(op, "i64.atomic.rmw8.xchg_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw8.xchg_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; case 'o': - if (strcmp(op, "i64.atomic.rmw8.xor_u") == 0) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } + if (op == "i64.atomic.rmw8.xor_u"sv) { return makeAtomicRMWOrCmpxchg(s, Type::i64); } goto parse_error; default: goto parse_error; } @@ -2161,16 +2164,16 @@ switch (op[0]) { case 's': { switch (op[16]) { case '\0': - if (strcmp(op, "i64.atomic.store") == 0) { return makeStore(s, Type::i64, /*isAtomic=*/true); } + if (op == "i64.atomic.store"sv) { return makeStore(s, Type::i64, /*isAtomic=*/true); } goto parse_error; case '1': - if (strcmp(op, "i64.atomic.store16") == 0) { return makeStore(s, Type::i64, /*isAtomic=*/true); } + if (op == "i64.atomic.store16"sv) { return makeStore(s, Type::i64, /*isAtomic=*/true); } goto parse_error; case '3': - if (strcmp(op, "i64.atomic.store32") == 0) { return makeStore(s, Type::i64, /*isAtomic=*/true); } + if (op == "i64.atomic.store32"sv) { return makeStore(s, Type::i64, /*isAtomic=*/true); } goto parse_error; case '8': - if (strcmp(op, "i64.atomic.store8") == 0) { return makeStore(s, Type::i64, /*isAtomic=*/true); } + if (op == "i64.atomic.store8"sv) { return makeStore(s, Type::i64, /*isAtomic=*/true); } goto parse_error; default: goto parse_error; } @@ -2184,13 +2187,13 @@ switch (op[0]) { case 'c': { switch (op[5]) { case 'l': - if (strcmp(op, "i64.clz") == 0) { return makeUnary(s, UnaryOp::ClzInt64); } + if (op == "i64.clz"sv) { return makeUnary(s, UnaryOp::ClzInt64); } goto parse_error; case 'o': - if (strcmp(op, "i64.const") == 0) { return makeConst(s, Type::i64); } + if (op == "i64.const"sv) { return makeConst(s, Type::i64); } goto parse_error; case 't': - if (strcmp(op, "i64.ctz") == 0) { return makeUnary(s, UnaryOp::CtzInt64); } + if (op == "i64.ctz"sv) { return makeUnary(s, UnaryOp::CtzInt64); } goto parse_error; default: goto parse_error; } @@ -2198,10 +2201,10 @@ switch (op[0]) { case 'd': { switch (op[8]) { case 's': - if (strcmp(op, "i64.div_s") == 0) { return makeBinary(s, BinaryOp::DivSInt64); } + if (op == "i64.div_s"sv) { return makeBinary(s, BinaryOp::DivSInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.div_u") == 0) { return makeBinary(s, BinaryOp::DivUInt64); } + if (op == "i64.div_u"sv) { return makeBinary(s, BinaryOp::DivUInt64); } goto parse_error; default: goto parse_error; } @@ -2211,10 +2214,10 @@ switch (op[0]) { case 'q': { switch (op[6]) { case '\0': - if (strcmp(op, "i64.eq") == 0) { return makeBinary(s, BinaryOp::EqInt64); } + if (op == "i64.eq"sv) { return makeBinary(s, BinaryOp::EqInt64); } goto parse_error; case 'z': - if (strcmp(op, "i64.eqz") == 0) { return makeUnary(s, UnaryOp::EqZInt64); } + if (op == "i64.eqz"sv) { return makeUnary(s, UnaryOp::EqZInt64); } goto parse_error; default: goto parse_error; } @@ -2222,21 +2225,21 @@ switch (op[0]) { case 'x': { switch (op[10]) { case '1': - if (strcmp(op, "i64.extend16_s") == 0) { return makeUnary(s, UnaryOp::ExtendS16Int64); } + if (op == "i64.extend16_s"sv) { return makeUnary(s, UnaryOp::ExtendS16Int64); } goto parse_error; case '3': - if (strcmp(op, "i64.extend32_s") == 0) { return makeUnary(s, UnaryOp::ExtendS32Int64); } + if (op == "i64.extend32_s"sv) { return makeUnary(s, UnaryOp::ExtendS32Int64); } goto parse_error; case '8': - if (strcmp(op, "i64.extend8_s") == 0) { return makeUnary(s, UnaryOp::ExtendS8Int64); } + if (op == "i64.extend8_s"sv) { return makeUnary(s, UnaryOp::ExtendS8Int64); } goto parse_error; case '_': { switch (op[15]) { case 's': - if (strcmp(op, "i64.extend_i32_s") == 0) { return makeUnary(s, UnaryOp::ExtendSInt32); } + if (op == "i64.extend_i32_s"sv) { return makeUnary(s, UnaryOp::ExtendSInt32); } goto parse_error; case 'u': - if (strcmp(op, "i64.extend_i32_u") == 0) { return makeUnary(s, UnaryOp::ExtendUInt32); } + if (op == "i64.extend_i32_u"sv) { return makeUnary(s, UnaryOp::ExtendUInt32); } goto parse_error; default: goto parse_error; } @@ -2252,10 +2255,10 @@ switch (op[0]) { case 'e': { switch (op[7]) { case 's': - if (strcmp(op, "i64.ge_s") == 0) { return makeBinary(s, BinaryOp::GeSInt64); } + if (op == "i64.ge_s"sv) { return makeBinary(s, BinaryOp::GeSInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.ge_u") == 0) { return makeBinary(s, BinaryOp::GeUInt64); } + if (op == "i64.ge_u"sv) { return makeBinary(s, BinaryOp::GeUInt64); } goto parse_error; default: goto parse_error; } @@ -2263,10 +2266,10 @@ switch (op[0]) { case 't': { switch (op[7]) { case 's': - if (strcmp(op, "i64.gt_s") == 0) { return makeBinary(s, BinaryOp::GtSInt64); } + if (op == "i64.gt_s"sv) { return makeBinary(s, BinaryOp::GtSInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.gt_u") == 0) { return makeBinary(s, BinaryOp::GtUInt64); } + if (op == "i64.gt_u"sv) { return makeBinary(s, BinaryOp::GtUInt64); } goto parse_error; default: goto parse_error; } @@ -2279,10 +2282,10 @@ switch (op[0]) { case 'e': { switch (op[7]) { case 's': - if (strcmp(op, "i64.le_s") == 0) { return makeBinary(s, BinaryOp::LeSInt64); } + if (op == "i64.le_s"sv) { return makeBinary(s, BinaryOp::LeSInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.le_u") == 0) { return makeBinary(s, BinaryOp::LeUInt64); } + if (op == "i64.le_u"sv) { return makeBinary(s, BinaryOp::LeUInt64); } goto parse_error; default: goto parse_error; } @@ -2290,15 +2293,15 @@ switch (op[0]) { case 'o': { switch (op[8]) { case '\0': - if (strcmp(op, "i64.load") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.load"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } goto parse_error; case '1': { switch (op[11]) { case 's': - if (strcmp(op, "i64.load16_s") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.load16_s"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } goto parse_error; case 'u': - if (strcmp(op, "i64.load16_u") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.load16_u"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } goto parse_error; default: goto parse_error; } @@ -2306,10 +2309,10 @@ switch (op[0]) { case '3': { switch (op[11]) { case 's': - if (strcmp(op, "i64.load32_s") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.load32_s"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } goto parse_error; case 'u': - if (strcmp(op, "i64.load32_u") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.load32_u"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } goto parse_error; default: goto parse_error; } @@ -2317,10 +2320,10 @@ switch (op[0]) { case '8': { switch (op[10]) { case 's': - if (strcmp(op, "i64.load8_s") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.load8_s"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } goto parse_error; case 'u': - if (strcmp(op, "i64.load8_u") == 0) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.load8_u"sv) { return makeLoad(s, Type::i64, /*isAtomic=*/false); } goto parse_error; default: goto parse_error; } @@ -2331,10 +2334,10 @@ switch (op[0]) { case 't': { switch (op[7]) { case 's': - if (strcmp(op, "i64.lt_s") == 0) { return makeBinary(s, BinaryOp::LtSInt64); } + if (op == "i64.lt_s"sv) { return makeBinary(s, BinaryOp::LtSInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.lt_u") == 0) { return makeBinary(s, BinaryOp::LtUInt64); } + if (op == "i64.lt_u"sv) { return makeBinary(s, BinaryOp::LtUInt64); } goto parse_error; default: goto parse_error; } @@ -2343,31 +2346,31 @@ switch (op[0]) { } } case 'm': - if (strcmp(op, "i64.mul") == 0) { return makeBinary(s, BinaryOp::MulInt64); } + if (op == "i64.mul"sv) { return makeBinary(s, BinaryOp::MulInt64); } goto parse_error; case 'n': - if (strcmp(op, "i64.ne") == 0) { return makeBinary(s, BinaryOp::NeInt64); } + if (op == "i64.ne"sv) { return makeBinary(s, BinaryOp::NeInt64); } goto parse_error; case 'o': - if (strcmp(op, "i64.or") == 0) { return makeBinary(s, BinaryOp::OrInt64); } + if (op == "i64.or"sv) { return makeBinary(s, BinaryOp::OrInt64); } goto parse_error; case 'p': - if (strcmp(op, "i64.popcnt") == 0) { return makeUnary(s, UnaryOp::PopcntInt64); } + if (op == "i64.popcnt"sv) { return makeUnary(s, UnaryOp::PopcntInt64); } goto parse_error; case 'r': { switch (op[5]) { case 'e': { switch (op[6]) { case 'i': - if (strcmp(op, "i64.reinterpret_f64") == 0) { return makeUnary(s, UnaryOp::ReinterpretFloat64); } + if (op == "i64.reinterpret_f64"sv) { return makeUnary(s, UnaryOp::ReinterpretFloat64); } goto parse_error; case 'm': { switch (op[8]) { case 's': - if (strcmp(op, "i64.rem_s") == 0) { return makeBinary(s, BinaryOp::RemSInt64); } + if (op == "i64.rem_s"sv) { return makeBinary(s, BinaryOp::RemSInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.rem_u") == 0) { return makeBinary(s, BinaryOp::RemUInt64); } + if (op == "i64.rem_u"sv) { return makeBinary(s, BinaryOp::RemUInt64); } goto parse_error; default: goto parse_error; } @@ -2378,10 +2381,10 @@ switch (op[0]) { case 'o': { switch (op[7]) { case 'l': - if (strcmp(op, "i64.rotl") == 0) { return makeBinary(s, BinaryOp::RotLInt64); } + if (op == "i64.rotl"sv) { return makeBinary(s, BinaryOp::RotLInt64); } goto parse_error; case 'r': - if (strcmp(op, "i64.rotr") == 0) { return makeBinary(s, BinaryOp::RotRInt64); } + if (op == "i64.rotr"sv) { return makeBinary(s, BinaryOp::RotRInt64); } goto parse_error; default: goto parse_error; } @@ -2394,15 +2397,15 @@ switch (op[0]) { case 'h': { switch (op[6]) { case 'l': - if (strcmp(op, "i64.shl") == 0) { return makeBinary(s, BinaryOp::ShlInt64); } + if (op == "i64.shl"sv) { return makeBinary(s, BinaryOp::ShlInt64); } goto parse_error; case 'r': { switch (op[8]) { case 's': - if (strcmp(op, "i64.shr_s") == 0) { return makeBinary(s, BinaryOp::ShrSInt64); } + if (op == "i64.shr_s"sv) { return makeBinary(s, BinaryOp::ShrSInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.shr_u") == 0) { return makeBinary(s, BinaryOp::ShrUInt64); } + if (op == "i64.shr_u"sv) { return makeBinary(s, BinaryOp::ShrUInt64); } goto parse_error; default: goto parse_error; } @@ -2413,22 +2416,22 @@ switch (op[0]) { case 't': { switch (op[9]) { case '\0': - if (strcmp(op, "i64.store") == 0) { return makeStore(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.store"sv) { return makeStore(s, Type::i64, /*isAtomic=*/false); } goto parse_error; case '1': - if (strcmp(op, "i64.store16") == 0) { return makeStore(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.store16"sv) { return makeStore(s, Type::i64, /*isAtomic=*/false); } goto parse_error; case '3': - if (strcmp(op, "i64.store32") == 0) { return makeStore(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.store32"sv) { return makeStore(s, Type::i64, /*isAtomic=*/false); } goto parse_error; case '8': - if (strcmp(op, "i64.store8") == 0) { return makeStore(s, Type::i64, /*isAtomic=*/false); } + if (op == "i64.store8"sv) { return makeStore(s, Type::i64, /*isAtomic=*/false); } goto parse_error; default: goto parse_error; } } case 'u': - if (strcmp(op, "i64.sub") == 0) { return makeBinary(s, BinaryOp::SubInt64); } + if (op == "i64.sub"sv) { return makeBinary(s, BinaryOp::SubInt64); } goto parse_error; default: goto parse_error; } @@ -2440,10 +2443,10 @@ switch (op[0]) { case '3': { switch (op[14]) { case 's': - if (strcmp(op, "i64.trunc_f32_s") == 0) { return makeUnary(s, UnaryOp::TruncSFloat32ToInt64); } + if (op == "i64.trunc_f32_s"sv) { return makeUnary(s, UnaryOp::TruncSFloat32ToInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.trunc_f32_u") == 0) { return makeUnary(s, UnaryOp::TruncUFloat32ToInt64); } + if (op == "i64.trunc_f32_u"sv) { return makeUnary(s, UnaryOp::TruncUFloat32ToInt64); } goto parse_error; default: goto parse_error; } @@ -2451,10 +2454,10 @@ switch (op[0]) { case '6': { switch (op[14]) { case 's': - if (strcmp(op, "i64.trunc_f64_s") == 0) { return makeUnary(s, UnaryOp::TruncSFloat64ToInt64); } + if (op == "i64.trunc_f64_s"sv) { return makeUnary(s, UnaryOp::TruncSFloat64ToInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.trunc_f64_u") == 0) { return makeUnary(s, UnaryOp::TruncUFloat64ToInt64); } + if (op == "i64.trunc_f64_u"sv) { return makeUnary(s, UnaryOp::TruncUFloat64ToInt64); } goto parse_error; default: goto parse_error; } @@ -2467,10 +2470,10 @@ switch (op[0]) { case '3': { switch (op[18]) { case 's': - if (strcmp(op, "i64.trunc_sat_f32_s") == 0) { return makeUnary(s, UnaryOp::TruncSatSFloat32ToInt64); } + if (op == "i64.trunc_sat_f32_s"sv) { return makeUnary(s, UnaryOp::TruncSatSFloat32ToInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.trunc_sat_f32_u") == 0) { return makeUnary(s, UnaryOp::TruncSatUFloat32ToInt64); } + if (op == "i64.trunc_sat_f32_u"sv) { return makeUnary(s, UnaryOp::TruncSatUFloat32ToInt64); } goto parse_error; default: goto parse_error; } @@ -2478,10 +2481,10 @@ switch (op[0]) { case '6': { switch (op[18]) { case 's': - if (strcmp(op, "i64.trunc_sat_f64_s") == 0) { return makeUnary(s, UnaryOp::TruncSatSFloat64ToInt64); } + if (op == "i64.trunc_sat_f64_s"sv) { return makeUnary(s, UnaryOp::TruncSatSFloat64ToInt64); } goto parse_error; case 'u': - if (strcmp(op, "i64.trunc_sat_f64_u") == 0) { return makeUnary(s, UnaryOp::TruncSatUFloat64ToInt64); } + if (op == "i64.trunc_sat_f64_u"sv) { return makeUnary(s, UnaryOp::TruncSatUFloat64ToInt64); } goto parse_error; default: goto parse_error; } @@ -2493,7 +2496,7 @@ switch (op[0]) { } } case 'x': - if (strcmp(op, "i64.xor") == 0) { return makeBinary(s, BinaryOp::XorInt64); } + if (op == "i64.xor"sv) { return makeBinary(s, BinaryOp::XorInt64); } goto parse_error; default: goto parse_error; } @@ -2503,24 +2506,24 @@ switch (op[0]) { case 'a': { switch (op[7]) { case 'b': - if (strcmp(op, "i64x2.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecI64x2); } + if (op == "i64x2.abs"sv) { return makeUnary(s, UnaryOp::AbsVecI64x2); } goto parse_error; case 'd': - if (strcmp(op, "i64x2.add") == 0) { return makeBinary(s, BinaryOp::AddVecI64x2); } + if (op == "i64x2.add"sv) { return makeBinary(s, BinaryOp::AddVecI64x2); } goto parse_error; case 'l': - if (strcmp(op, "i64x2.all_true") == 0) { return makeUnary(s, UnaryOp::AllTrueVecI64x2); } + if (op == "i64x2.all_true"sv) { return makeUnary(s, UnaryOp::AllTrueVecI64x2); } goto parse_error; default: goto parse_error; } } case 'b': - if (strcmp(op, "i64x2.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI64x2); } + if (op == "i64x2.bitmask"sv) { return makeUnary(s, UnaryOp::BitmaskVecI64x2); } goto parse_error; case 'e': { switch (op[7]) { case 'q': - if (strcmp(op, "i64x2.eq") == 0) { return makeBinary(s, BinaryOp::EqVecI64x2); } + if (op == "i64x2.eq"sv) { return makeBinary(s, BinaryOp::EqVecI64x2); } goto parse_error; case 'x': { switch (op[9]) { @@ -2529,10 +2532,10 @@ switch (op[0]) { case 'h': { switch (op[24]) { case 's': - if (strcmp(op, "i64x2.extend_high_i32x4_s") == 0) { return makeUnary(s, UnaryOp::ExtendHighSVecI32x4ToVecI64x2); } + if (op == "i64x2.extend_high_i32x4_s"sv) { return makeUnary(s, UnaryOp::ExtendHighSVecI32x4ToVecI64x2); } goto parse_error; case 'u': - if (strcmp(op, "i64x2.extend_high_i32x4_u") == 0) { return makeUnary(s, UnaryOp::ExtendHighUVecI32x4ToVecI64x2); } + if (op == "i64x2.extend_high_i32x4_u"sv) { return makeUnary(s, UnaryOp::ExtendHighUVecI32x4ToVecI64x2); } goto parse_error; default: goto parse_error; } @@ -2540,10 +2543,10 @@ switch (op[0]) { case 'l': { switch (op[23]) { case 's': - if (strcmp(op, "i64x2.extend_low_i32x4_s") == 0) { return makeUnary(s, UnaryOp::ExtendLowSVecI32x4ToVecI64x2); } + if (op == "i64x2.extend_low_i32x4_s"sv) { return makeUnary(s, UnaryOp::ExtendLowSVecI32x4ToVecI64x2); } goto parse_error; case 'u': - if (strcmp(op, "i64x2.extend_low_i32x4_u") == 0) { return makeUnary(s, UnaryOp::ExtendLowUVecI32x4ToVecI64x2); } + if (op == "i64x2.extend_low_i32x4_u"sv) { return makeUnary(s, UnaryOp::ExtendLowUVecI32x4ToVecI64x2); } goto parse_error; default: goto parse_error; } @@ -2556,10 +2559,10 @@ switch (op[0]) { case 'h': { switch (op[24]) { case 's': - if (strcmp(op, "i64x2.extmul_high_i32x4_s") == 0) { return makeBinary(s, BinaryOp::ExtMulHighSVecI64x2); } + if (op == "i64x2.extmul_high_i32x4_s"sv) { return makeBinary(s, BinaryOp::ExtMulHighSVecI64x2); } goto parse_error; case 'u': - if (strcmp(op, "i64x2.extmul_high_i32x4_u") == 0) { return makeBinary(s, BinaryOp::ExtMulHighUVecI64x2); } + if (op == "i64x2.extmul_high_i32x4_u"sv) { return makeBinary(s, BinaryOp::ExtMulHighUVecI64x2); } goto parse_error; default: goto parse_error; } @@ -2567,10 +2570,10 @@ switch (op[0]) { case 'l': { switch (op[23]) { case 's': - if (strcmp(op, "i64x2.extmul_low_i32x4_s") == 0) { return makeBinary(s, BinaryOp::ExtMulLowSVecI64x2); } + if (op == "i64x2.extmul_low_i32x4_s"sv) { return makeBinary(s, BinaryOp::ExtMulLowSVecI64x2); } goto parse_error; case 'u': - if (strcmp(op, "i64x2.extmul_low_i32x4_u") == 0) { return makeBinary(s, BinaryOp::ExtMulLowUVecI64x2); } + if (op == "i64x2.extmul_low_i32x4_u"sv) { return makeBinary(s, BinaryOp::ExtMulLowUVecI64x2); } goto parse_error; default: goto parse_error; } @@ -2579,7 +2582,7 @@ switch (op[0]) { } } case 'r': - if (strcmp(op, "i64x2.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI64x2, 2); } + if (op == "i64x2.extract_lane"sv) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI64x2, 2); } goto parse_error; default: goto parse_error; } @@ -2590,10 +2593,10 @@ switch (op[0]) { case 'g': { switch (op[7]) { case 'e': - if (strcmp(op, "i64x2.ge_s") == 0) { return makeBinary(s, BinaryOp::GeSVecI64x2); } + if (op == "i64x2.ge_s"sv) { return makeBinary(s, BinaryOp::GeSVecI64x2); } goto parse_error; case 't': - if (strcmp(op, "i64x2.gt_s") == 0) { return makeBinary(s, BinaryOp::GtSVecI64x2); } + if (op == "i64x2.gt_s"sv) { return makeBinary(s, BinaryOp::GtSVecI64x2); } goto parse_error; default: goto parse_error; } @@ -2601,48 +2604,48 @@ switch (op[0]) { case 'l': { switch (op[7]) { case 'a': - if (strcmp(op, "i64x2.laneselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::LaneselectI64x2); } + if (op == "i64x2.laneselect"sv) { return makeSIMDTernary(s, SIMDTernaryOp::LaneselectI64x2); } goto parse_error; case 'e': - if (strcmp(op, "i64x2.le_s") == 0) { return makeBinary(s, BinaryOp::LeSVecI64x2); } + if (op == "i64x2.le_s"sv) { return makeBinary(s, BinaryOp::LeSVecI64x2); } goto parse_error; case 't': - if (strcmp(op, "i64x2.lt_s") == 0) { return makeBinary(s, BinaryOp::LtSVecI64x2); } + if (op == "i64x2.lt_s"sv) { return makeBinary(s, BinaryOp::LtSVecI64x2); } goto parse_error; default: goto parse_error; } } case 'm': - if (strcmp(op, "i64x2.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI64x2); } + if (op == "i64x2.mul"sv) { return makeBinary(s, BinaryOp::MulVecI64x2); } goto parse_error; case 'n': { switch (op[8]) { case '\0': - if (strcmp(op, "i64x2.ne") == 0) { return makeBinary(s, BinaryOp::NeVecI64x2); } + if (op == "i64x2.ne"sv) { return makeBinary(s, BinaryOp::NeVecI64x2); } goto parse_error; case 'g': - if (strcmp(op, "i64x2.neg") == 0) { return makeUnary(s, UnaryOp::NegVecI64x2); } + if (op == "i64x2.neg"sv) { return makeUnary(s, UnaryOp::NegVecI64x2); } goto parse_error; default: goto parse_error; } } case 'r': - if (strcmp(op, "i64x2.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI64x2, 2); } + if (op == "i64x2.replace_lane"sv) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI64x2, 2); } goto parse_error; case 's': { switch (op[7]) { case 'h': { switch (op[8]) { case 'l': - if (strcmp(op, "i64x2.shl") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShlVecI64x2); } + if (op == "i64x2.shl"sv) { return makeSIMDShift(s, SIMDShiftOp::ShlVecI64x2); } goto parse_error; case 'r': { switch (op[10]) { case 's': - if (strcmp(op, "i64x2.shr_s") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShrSVecI64x2); } + if (op == "i64x2.shr_s"sv) { return makeSIMDShift(s, SIMDShiftOp::ShrSVecI64x2); } goto parse_error; case 'u': - if (strcmp(op, "i64x2.shr_u") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShrUVecI64x2); } + if (op == "i64x2.shr_u"sv) { return makeSIMDShift(s, SIMDShiftOp::ShrUVecI64x2); } goto parse_error; default: goto parse_error; } @@ -2651,10 +2654,10 @@ switch (op[0]) { } } case 'p': - if (strcmp(op, "i64x2.splat") == 0) { return makeUnary(s, UnaryOp::SplatVecI64x2); } + if (op == "i64x2.splat"sv) { return makeUnary(s, UnaryOp::SplatVecI64x2); } goto parse_error; case 'u': - if (strcmp(op, "i64x2.sub") == 0) { return makeBinary(s, BinaryOp::SubVecI64x2); } + if (op == "i64x2.sub"sv) { return makeBinary(s, BinaryOp::SubVecI64x2); } goto parse_error; default: goto parse_error; } @@ -2670,20 +2673,20 @@ switch (op[0]) { case 'a': { switch (op[7]) { case 'b': - if (strcmp(op, "i8x16.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecI8x16); } + if (op == "i8x16.abs"sv) { return makeUnary(s, UnaryOp::AbsVecI8x16); } goto parse_error; case 'd': { switch (op[9]) { case '\0': - if (strcmp(op, "i8x16.add") == 0) { return makeBinary(s, BinaryOp::AddVecI8x16); } + if (op == "i8x16.add"sv) { return makeBinary(s, BinaryOp::AddVecI8x16); } goto parse_error; case '_': { switch (op[14]) { case 's': - if (strcmp(op, "i8x16.add_sat_s") == 0) { return makeBinary(s, BinaryOp::AddSatSVecI8x16); } + if (op == "i8x16.add_sat_s"sv) { return makeBinary(s, BinaryOp::AddSatSVecI8x16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.add_sat_u") == 0) { return makeBinary(s, BinaryOp::AddSatUVecI8x16); } + if (op == "i8x16.add_sat_u"sv) { return makeBinary(s, BinaryOp::AddSatUVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2692,29 +2695,29 @@ switch (op[0]) { } } case 'l': - if (strcmp(op, "i8x16.all_true") == 0) { return makeUnary(s, UnaryOp::AllTrueVecI8x16); } + if (op == "i8x16.all_true"sv) { return makeUnary(s, UnaryOp::AllTrueVecI8x16); } goto parse_error; case 'v': - if (strcmp(op, "i8x16.avgr_u") == 0) { return makeBinary(s, BinaryOp::AvgrUVecI8x16); } + if (op == "i8x16.avgr_u"sv) { return makeBinary(s, BinaryOp::AvgrUVecI8x16); } goto parse_error; default: goto parse_error; } } case 'b': - if (strcmp(op, "i8x16.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI8x16); } + if (op == "i8x16.bitmask"sv) { return makeUnary(s, UnaryOp::BitmaskVecI8x16); } goto parse_error; case 'e': { switch (op[7]) { case 'q': - if (strcmp(op, "i8x16.eq") == 0) { return makeBinary(s, BinaryOp::EqVecI8x16); } + if (op == "i8x16.eq"sv) { return makeBinary(s, BinaryOp::EqVecI8x16); } goto parse_error; case 'x': { switch (op[19]) { case 's': - if (strcmp(op, "i8x16.extract_lane_s") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneSVecI8x16, 16); } + if (op == "i8x16.extract_lane_s"sv) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneSVecI8x16, 16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.extract_lane_u") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneUVecI8x16, 16); } + if (op == "i8x16.extract_lane_u"sv) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneUVecI8x16, 16); } goto parse_error; default: goto parse_error; } @@ -2727,10 +2730,10 @@ switch (op[0]) { case 'e': { switch (op[9]) { case 's': - if (strcmp(op, "i8x16.ge_s") == 0) { return makeBinary(s, BinaryOp::GeSVecI8x16); } + if (op == "i8x16.ge_s"sv) { return makeBinary(s, BinaryOp::GeSVecI8x16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.ge_u") == 0) { return makeBinary(s, BinaryOp::GeUVecI8x16); } + if (op == "i8x16.ge_u"sv) { return makeBinary(s, BinaryOp::GeUVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2738,10 +2741,10 @@ switch (op[0]) { case 't': { switch (op[9]) { case 's': - if (strcmp(op, "i8x16.gt_s") == 0) { return makeBinary(s, BinaryOp::GtSVecI8x16); } + if (op == "i8x16.gt_s"sv) { return makeBinary(s, BinaryOp::GtSVecI8x16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.gt_u") == 0) { return makeBinary(s, BinaryOp::GtUVecI8x16); } + if (op == "i8x16.gt_u"sv) { return makeBinary(s, BinaryOp::GtUVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2752,15 +2755,15 @@ switch (op[0]) { case 'l': { switch (op[7]) { case 'a': - if (strcmp(op, "i8x16.laneselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::LaneselectI8x16); } + if (op == "i8x16.laneselect"sv) { return makeSIMDTernary(s, SIMDTernaryOp::LaneselectI8x16); } goto parse_error; case 'e': { switch (op[9]) { case 's': - if (strcmp(op, "i8x16.le_s") == 0) { return makeBinary(s, BinaryOp::LeSVecI8x16); } + if (op == "i8x16.le_s"sv) { return makeBinary(s, BinaryOp::LeSVecI8x16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.le_u") == 0) { return makeBinary(s, BinaryOp::LeUVecI8x16); } + if (op == "i8x16.le_u"sv) { return makeBinary(s, BinaryOp::LeUVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2768,10 +2771,10 @@ switch (op[0]) { case 't': { switch (op[9]) { case 's': - if (strcmp(op, "i8x16.lt_s") == 0) { return makeBinary(s, BinaryOp::LtSVecI8x16); } + if (op == "i8x16.lt_s"sv) { return makeBinary(s, BinaryOp::LtSVecI8x16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.lt_u") == 0) { return makeBinary(s, BinaryOp::LtUVecI8x16); } + if (op == "i8x16.lt_u"sv) { return makeBinary(s, BinaryOp::LtUVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2784,10 +2787,10 @@ switch (op[0]) { case 'a': { switch (op[10]) { case 's': - if (strcmp(op, "i8x16.max_s") == 0) { return makeBinary(s, BinaryOp::MaxSVecI8x16); } + if (op == "i8x16.max_s"sv) { return makeBinary(s, BinaryOp::MaxSVecI8x16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.max_u") == 0) { return makeBinary(s, BinaryOp::MaxUVecI8x16); } + if (op == "i8x16.max_u"sv) { return makeBinary(s, BinaryOp::MaxUVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2795,10 +2798,10 @@ switch (op[0]) { case 'i': { switch (op[10]) { case 's': - if (strcmp(op, "i8x16.min_s") == 0) { return makeBinary(s, BinaryOp::MinSVecI8x16); } + if (op == "i8x16.min_s"sv) { return makeBinary(s, BinaryOp::MinSVecI8x16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.min_u") == 0) { return makeBinary(s, BinaryOp::MinUVecI8x16); } + if (op == "i8x16.min_u"sv) { return makeBinary(s, BinaryOp::MinUVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2811,10 +2814,10 @@ switch (op[0]) { case 'a': { switch (op[19]) { case 's': - if (strcmp(op, "i8x16.narrow_i16x8_s") == 0) { return makeBinary(s, BinaryOp::NarrowSVecI16x8ToVecI8x16); } + if (op == "i8x16.narrow_i16x8_s"sv) { return makeBinary(s, BinaryOp::NarrowSVecI16x8ToVecI8x16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.narrow_i16x8_u") == 0) { return makeBinary(s, BinaryOp::NarrowUVecI16x8ToVecI8x16); } + if (op == "i8x16.narrow_i16x8_u"sv) { return makeBinary(s, BinaryOp::NarrowUVecI16x8ToVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2822,10 +2825,10 @@ switch (op[0]) { case 'e': { switch (op[8]) { case '\0': - if (strcmp(op, "i8x16.ne") == 0) { return makeBinary(s, BinaryOp::NeVecI8x16); } + if (op == "i8x16.ne"sv) { return makeBinary(s, BinaryOp::NeVecI8x16); } goto parse_error; case 'g': - if (strcmp(op, "i8x16.neg") == 0) { return makeUnary(s, UnaryOp::NegVecI8x16); } + if (op == "i8x16.neg"sv) { return makeUnary(s, UnaryOp::NegVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2834,15 +2837,15 @@ switch (op[0]) { } } case 'p': - if (strcmp(op, "i8x16.popcnt") == 0) { return makeUnary(s, UnaryOp::PopcntVecI8x16); } + if (op == "i8x16.popcnt"sv) { return makeUnary(s, UnaryOp::PopcntVecI8x16); } goto parse_error; case 'r': { switch (op[8]) { case 'l': - if (strcmp(op, "i8x16.relaxed_swizzle") == 0) { return makeBinary(s, BinaryOp::RelaxedSwizzleVecI8x16); } + if (op == "i8x16.relaxed_swizzle"sv) { return makeBinary(s, BinaryOp::RelaxedSwizzleVecI8x16); } goto parse_error; case 'p': - if (strcmp(op, "i8x16.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI8x16, 16); } + if (op == "i8x16.replace_lane"sv) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI8x16, 16); } goto parse_error; default: goto parse_error; } @@ -2852,40 +2855,40 @@ switch (op[0]) { case 'h': { switch (op[8]) { case 'l': - if (strcmp(op, "i8x16.shl") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShlVecI8x16); } + if (op == "i8x16.shl"sv) { return makeSIMDShift(s, SIMDShiftOp::ShlVecI8x16); } goto parse_error; case 'r': { switch (op[10]) { case 's': - if (strcmp(op, "i8x16.shr_s") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShrSVecI8x16); } + if (op == "i8x16.shr_s"sv) { return makeSIMDShift(s, SIMDShiftOp::ShrSVecI8x16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.shr_u") == 0) { return makeSIMDShift(s, SIMDShiftOp::ShrUVecI8x16); } + if (op == "i8x16.shr_u"sv) { return makeSIMDShift(s, SIMDShiftOp::ShrUVecI8x16); } goto parse_error; default: goto parse_error; } } case 'u': - if (strcmp(op, "i8x16.shuffle") == 0) { return makeSIMDShuffle(s); } + if (op == "i8x16.shuffle"sv) { return makeSIMDShuffle(s); } goto parse_error; default: goto parse_error; } } case 'p': - if (strcmp(op, "i8x16.splat") == 0) { return makeUnary(s, UnaryOp::SplatVecI8x16); } + if (op == "i8x16.splat"sv) { return makeUnary(s, UnaryOp::SplatVecI8x16); } goto parse_error; case 'u': { switch (op[9]) { case '\0': - if (strcmp(op, "i8x16.sub") == 0) { return makeBinary(s, BinaryOp::SubVecI8x16); } + if (op == "i8x16.sub"sv) { return makeBinary(s, BinaryOp::SubVecI8x16); } goto parse_error; case '_': { switch (op[14]) { case 's': - if (strcmp(op, "i8x16.sub_sat_s") == 0) { return makeBinary(s, BinaryOp::SubSatSVecI8x16); } + if (op == "i8x16.sub_sat_s"sv) { return makeBinary(s, BinaryOp::SubSatSVecI8x16); } goto parse_error; case 'u': - if (strcmp(op, "i8x16.sub_sat_u") == 0) { return makeBinary(s, BinaryOp::SubSatUVecI8x16); } + if (op == "i8x16.sub_sat_u"sv) { return makeBinary(s, BinaryOp::SubSatUVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2894,7 +2897,7 @@ switch (op[0]) { } } case 'w': - if (strcmp(op, "i8x16.swizzle") == 0) { return makeBinary(s, BinaryOp::SwizzleVecI8x16); } + if (op == "i8x16.swizzle"sv) { return makeBinary(s, BinaryOp::SwizzleVecI8x16); } goto parse_error; default: goto parse_error; } @@ -2903,7 +2906,7 @@ switch (op[0]) { } } case 'f': - if (strcmp(op, "if") == 0) { return makeIf(s); } + if (op == "if"sv) { return makeIf(s); } goto parse_error; default: goto parse_error; } @@ -2913,19 +2916,19 @@ switch (op[0]) { case 'c': { switch (op[6]) { case 'g': - if (strcmp(op, "local.get") == 0) { return makeLocalGet(s); } + if (op == "local.get"sv) { return makeLocalGet(s); } goto parse_error; case 's': - if (strcmp(op, "local.set") == 0) { return makeLocalSet(s); } + if (op == "local.set"sv) { return makeLocalSet(s); } goto parse_error; case 't': - if (strcmp(op, "local.tee") == 0) { return makeLocalTee(s); } + if (op == "local.tee"sv) { return makeLocalTee(s); } goto parse_error; default: goto parse_error; } } case 'o': - if (strcmp(op, "loop") == 0) { return makeLoop(s); } + if (op == "loop"sv) { return makeLoop(s); } goto parse_error; default: goto parse_error; } @@ -2935,15 +2938,15 @@ switch (op[0]) { case 'a': { switch (op[14]) { case 'n': - if (strcmp(op, "memory.atomic.notify") == 0) { return makeAtomicNotify(s); } + if (op == "memory.atomic.notify"sv) { return makeAtomicNotify(s); } goto parse_error; case 'w': { switch (op[18]) { case '3': - if (strcmp(op, "memory.atomic.wait32") == 0) { return makeAtomicWait(s, Type::i32); } + if (op == "memory.atomic.wait32"sv) { return makeAtomicWait(s, Type::i32); } goto parse_error; case '6': - if (strcmp(op, "memory.atomic.wait64") == 0) { return makeAtomicWait(s, Type::i64); } + if (op == "memory.atomic.wait64"sv) { return makeAtomicWait(s, Type::i64); } goto parse_error; default: goto parse_error; } @@ -2952,28 +2955,28 @@ switch (op[0]) { } } case 'c': - if (strcmp(op, "memory.copy") == 0) { return makeMemoryCopy(s); } + if (op == "memory.copy"sv) { return makeMemoryCopy(s); } goto parse_error; case 'f': - if (strcmp(op, "memory.fill") == 0) { return makeMemoryFill(s); } + if (op == "memory.fill"sv) { return makeMemoryFill(s); } goto parse_error; case 'g': - if (strcmp(op, "memory.grow") == 0) { return makeMemoryGrow(s); } + if (op == "memory.grow"sv) { return makeMemoryGrow(s); } goto parse_error; case 'i': - if (strcmp(op, "memory.init") == 0) { return makeMemoryInit(s); } + if (op == "memory.init"sv) { return makeMemoryInit(s); } goto parse_error; case 's': - if (strcmp(op, "memory.size") == 0) { return makeMemorySize(s); } + if (op == "memory.size"sv) { return makeMemorySize(s); } goto parse_error; default: goto parse_error; } } case 'n': - if (strcmp(op, "nop") == 0) { return makeNop(); } + if (op == "nop"sv) { return makeNop(); } goto parse_error; case 'p': - if (strcmp(op, "pop") == 0) { return makePop(s); } + if (op == "pop"sv) { return makePop(s); } goto parse_error; case 'r': { switch (op[2]) { @@ -2982,16 +2985,16 @@ switch (op[0]) { case 'a': { switch (op[7]) { case 'd': - if (strcmp(op, "ref.as_data") == 0) { return makeRefAs(s, RefAsData); } + if (op == "ref.as_data"sv) { return makeRefAs(s, RefAsData); } goto parse_error; case 'f': - if (strcmp(op, "ref.as_func") == 0) { return makeRefAs(s, RefAsFunc); } + if (op == "ref.as_func"sv) { return makeRefAs(s, RefAsFunc); } goto parse_error; case 'i': - if (strcmp(op, "ref.as_i31") == 0) { return makeRefAs(s, RefAsI31); } + if (op == "ref.as_i31"sv) { return makeRefAs(s, RefAsI31); } goto parse_error; case 'n': - if (strcmp(op, "ref.as_non_null") == 0) { return makeRefAs(s, RefAsNonNull); } + if (op == "ref.as_non_null"sv) { return makeRefAs(s, RefAsNonNull); } goto parse_error; default: goto parse_error; } @@ -2999,42 +3002,42 @@ switch (op[0]) { case 'c': { switch (op[9]) { case 'n': - if (strcmp(op, "ref.cast_nop_static") == 0) { return makeRefCastNopStatic(s); } + if (op == "ref.cast_nop_static"sv) { return makeRefCastNopStatic(s); } goto parse_error; case 's': - if (strcmp(op, "ref.cast_static") == 0) { return makeRefCastStatic(s); } + if (op == "ref.cast_static"sv) { return makeRefCastStatic(s); } goto parse_error; default: goto parse_error; } } case 'e': - if (strcmp(op, "ref.eq") == 0) { return makeRefEq(s); } + if (op == "ref.eq"sv) { return makeRefEq(s); } goto parse_error; case 'f': - if (strcmp(op, "ref.func") == 0) { return makeRefFunc(s); } + if (op == "ref.func"sv) { return makeRefFunc(s); } goto parse_error; case 'i': { switch (op[7]) { case 'd': - if (strcmp(op, "ref.is_data") == 0) { return makeRefIs(s, RefIsData); } + if (op == "ref.is_data"sv) { return makeRefIs(s, RefIsData); } goto parse_error; case 'f': - if (strcmp(op, "ref.is_func") == 0) { return makeRefIs(s, RefIsFunc); } + if (op == "ref.is_func"sv) { return makeRefIs(s, RefIsFunc); } goto parse_error; case 'i': - if (strcmp(op, "ref.is_i31") == 0) { return makeRefIs(s, RefIsI31); } + if (op == "ref.is_i31"sv) { return makeRefIs(s, RefIsI31); } goto parse_error; case 'n': - if (strcmp(op, "ref.is_null") == 0) { return makeRefIs(s, RefIsNull); } + if (op == "ref.is_null"sv) { return makeRefIs(s, RefIsNull); } goto parse_error; default: goto parse_error; } } case 'n': - if (strcmp(op, "ref.null") == 0) { return makeRefNull(s); } + if (op == "ref.null"sv) { return makeRefNull(s); } goto parse_error; case 't': - if (strcmp(op, "ref.test_static") == 0) { return makeRefTestStatic(s); } + if (op == "ref.test_static"sv) { return makeRefTestStatic(s); } goto parse_error; default: goto parse_error; } @@ -3042,25 +3045,25 @@ switch (op[0]) { case 't': { switch (op[3]) { case 'h': - if (strcmp(op, "rethrow") == 0) { return makeRethrow(s); } + if (op == "rethrow"sv) { return makeRethrow(s); } goto parse_error; case 'u': { switch (op[6]) { case '\0': - if (strcmp(op, "return") == 0) { return makeReturn(s); } + if (op == "return"sv) { return makeReturn(s); } goto parse_error; case '_': { switch (op[11]) { case '\0': - if (strcmp(op, "return_call") == 0) { return makeCall(s, /*isReturn=*/true); } + if (op == "return_call"sv) { return makeCall(s, /*isReturn=*/true); } goto parse_error; case '_': { switch (op[12]) { case 'i': - if (strcmp(op, "return_call_indirect") == 0) { return makeCallIndirect(s, /*isReturn=*/true); } + if (op == "return_call_indirect"sv) { return makeCallIndirect(s, /*isReturn=*/true); } goto parse_error; case 'r': - if (strcmp(op, "return_call_ref") == 0) { return makeCallRef(s, /*isReturn=*/true); } + if (op == "return_call_ref"sv) { return makeCallRef(s, /*isReturn=*/true); } goto parse_error; default: goto parse_error; } @@ -3080,7 +3083,7 @@ switch (op[0]) { case 's': { switch (op[1]) { case 'e': - if (strcmp(op, "select") == 0) { return makeSelect(s); } + if (op == "select"sv) { return makeSelect(s); } goto parse_error; case 't': { switch (op[3]) { @@ -3091,15 +3094,15 @@ switch (op[0]) { case 'a': { switch (op[10]) { case 'i': - if (strcmp(op, "string.as_iter") == 0) { return makeStringAs(s, StringAsIter); } + if (op == "string.as_iter"sv) { return makeStringAs(s, StringAsIter); } goto parse_error; case 'w': { switch (op[13]) { case '1': - if (strcmp(op, "string.as_wtf16") == 0) { return makeStringAs(s, StringAsWTF16); } + if (op == "string.as_wtf16"sv) { return makeStringAs(s, StringAsWTF16); } goto parse_error; case '8': - if (strcmp(op, "string.as_wtf8") == 0) { return makeStringAs(s, StringAsWTF8); } + if (op == "string.as_wtf8"sv) { return makeStringAs(s, StringAsWTF8); } goto parse_error; default: goto parse_error; } @@ -3110,10 +3113,10 @@ switch (op[0]) { case 'c': { switch (op[10]) { case 'c': - if (strcmp(op, "string.concat") == 0) { return makeStringConcat(s); } + if (op == "string.concat"sv) { return makeStringConcat(s); } goto parse_error; case 's': - if (strcmp(op, "string.const") == 0) { return makeStringConst(s); } + if (op == "string.const"sv) { return makeStringConst(s); } goto parse_error; default: goto parse_error; } @@ -3125,10 +3128,10 @@ switch (op[0]) { case '1': { switch (op[19]) { case '\0': - if (strcmp(op, "string.encode_wtf16") == 0) { return makeStringEncode(s, StringEncodeWTF16); } + if (op == "string.encode_wtf16"sv) { return makeStringEncode(s, StringEncodeWTF16); } goto parse_error; case '_': - if (strcmp(op, "string.encode_wtf16_array") == 0) { return makeStringEncode(s, StringEncodeWTF16Array); } + if (op == "string.encode_wtf16_array"sv) { return makeStringEncode(s, StringEncodeWTF16Array); } goto parse_error; default: goto parse_error; } @@ -3136,10 +3139,10 @@ switch (op[0]) { case '8': { switch (op[18]) { case '\0': - if (strcmp(op, "string.encode_wtf8") == 0) { return makeStringEncode(s, StringEncodeWTF8); } + if (op == "string.encode_wtf8"sv) { return makeStringEncode(s, StringEncodeWTF8); } goto parse_error; case '_': - if (strcmp(op, "string.encode_wtf8_array") == 0) { return makeStringEncode(s, StringEncodeWTF8Array); } + if (op == "string.encode_wtf8_array"sv) { return makeStringEncode(s, StringEncodeWTF8Array); } goto parse_error; default: goto parse_error; } @@ -3148,21 +3151,21 @@ switch (op[0]) { } } case 'q': - if (strcmp(op, "string.eq") == 0) { return makeStringEq(s); } + if (op == "string.eq"sv) { return makeStringEq(s); } goto parse_error; default: goto parse_error; } } case 'i': - if (strcmp(op, "string.is_usv_sequence") == 0) { return makeStringMeasure(s, StringMeasureIsUSV); } + if (op == "string.is_usv_sequence"sv) { return makeStringMeasure(s, StringMeasureIsUSV); } goto parse_error; case 'm': { switch (op[18]) { case '1': - if (strcmp(op, "string.measure_wtf16") == 0) { return makeStringMeasure(s, StringMeasureWTF16); } + if (op == "string.measure_wtf16"sv) { return makeStringMeasure(s, StringMeasureWTF16); } goto parse_error; case '8': - if (strcmp(op, "string.measure_wtf8") == 0) { return makeStringMeasure(s, StringMeasureWTF8); } + if (op == "string.measure_wtf8"sv) { return makeStringMeasure(s, StringMeasureWTF8); } goto parse_error; default: goto parse_error; } @@ -3172,10 +3175,10 @@ switch (op[0]) { case '1': { switch (op[16]) { case '\0': - if (strcmp(op, "string.new_wtf16") == 0) { return makeStringNew(s, StringNewWTF16); } + if (op == "string.new_wtf16"sv) { return makeStringNew(s, StringNewWTF16); } goto parse_error; case '_': - if (strcmp(op, "string.new_wtf16_array") == 0) { return makeStringNew(s, StringNewWTF16Array); } + if (op == "string.new_wtf16_array"sv) { return makeStringNew(s, StringNewWTF16Array); } goto parse_error; default: goto parse_error; } @@ -3183,10 +3186,10 @@ switch (op[0]) { case '8': { switch (op[15]) { case '\0': - if (strcmp(op, "string.new_wtf8") == 0) { return makeStringNew(s, StringNewWTF8); } + if (op == "string.new_wtf8"sv) { return makeStringNew(s, StringNewWTF8); } goto parse_error; case '_': - if (strcmp(op, "string.new_wtf8_array") == 0) { return makeStringNew(s, StringNewWTF8Array); } + if (op == "string.new_wtf8_array"sv) { return makeStringNew(s, StringNewWTF8Array); } goto parse_error; default: goto parse_error; } @@ -3202,16 +3205,16 @@ switch (op[0]) { case 'i': { switch (op[16]) { case 'a': - if (strcmp(op, "stringview_iter.advance") == 0) { return makeStringIterMove(s, StringIterMoveAdvance); } + if (op == "stringview_iter.advance"sv) { return makeStringIterMove(s, StringIterMoveAdvance); } goto parse_error; case 'n': - if (strcmp(op, "stringview_iter.next") == 0) { return makeStringIterNext(s); } + if (op == "stringview_iter.next"sv) { return makeStringIterNext(s); } goto parse_error; case 'r': - if (strcmp(op, "stringview_iter.rewind") == 0) { return makeStringIterMove(s, StringIterMoveRewind); } + if (op == "stringview_iter.rewind"sv) { return makeStringIterMove(s, StringIterMoveRewind); } goto parse_error; case 's': - if (strcmp(op, "stringview_iter.slice") == 0) { return makeStringSliceIter(s); } + if (op == "stringview_iter.slice"sv) { return makeStringSliceIter(s); } goto parse_error; default: goto parse_error; } @@ -3221,13 +3224,13 @@ switch (op[0]) { case '1': { switch (op[17]) { case 'g': - if (strcmp(op, "stringview_wtf16.get_codeunit") == 0) { return makeStringWTF16Get(s); } + if (op == "stringview_wtf16.get_codeunit"sv) { return makeStringWTF16Get(s); } goto parse_error; case 'l': - if (strcmp(op, "stringview_wtf16.length") == 0) { return makeStringMeasure(s, StringMeasureWTF16View); } + if (op == "stringview_wtf16.length"sv) { return makeStringMeasure(s, StringMeasureWTF16View); } goto parse_error; case 's': - if (strcmp(op, "stringview_wtf16.slice") == 0) { return makeStringSliceWTF(s, StringSliceWTF16); } + if (op == "stringview_wtf16.slice"sv) { return makeStringSliceWTF(s, StringSliceWTF16); } goto parse_error; default: goto parse_error; } @@ -3235,10 +3238,10 @@ switch (op[0]) { case '8': { switch (op[16]) { case 'a': - if (strcmp(op, "stringview_wtf8.advance") == 0) { return makeStringWTF8Advance(s); } + if (op == "stringview_wtf8.advance"sv) { return makeStringWTF8Advance(s); } goto parse_error; case 's': - if (strcmp(op, "stringview_wtf8.slice") == 0) { return makeStringSliceWTF(s, StringSliceWTF8); } + if (op == "stringview_wtf8.slice"sv) { return makeStringSliceWTF(s, StringSliceWTF8); } goto parse_error; default: goto parse_error; } @@ -3257,15 +3260,15 @@ switch (op[0]) { case 'g': { switch (op[10]) { case '\0': - if (strcmp(op, "struct.get") == 0) { return makeStructGet(s); } + if (op == "struct.get"sv) { return makeStructGet(s); } goto parse_error; case '_': { switch (op[11]) { case 's': - if (strcmp(op, "struct.get_s") == 0) { return makeStructGet(s, true); } + if (op == "struct.get_s"sv) { return makeStructGet(s, true); } goto parse_error; case 'u': - if (strcmp(op, "struct.get_u") == 0) { return makeStructGet(s, false); } + if (op == "struct.get_u"sv) { return makeStructGet(s, false); } goto parse_error; default: goto parse_error; } @@ -3276,16 +3279,16 @@ switch (op[0]) { case 'n': { switch (op[10]) { case '\0': - if (strcmp(op, "struct.new") == 0) { return makeStructNewStatic(s, false); } + if (op == "struct.new"sv) { return makeStructNewStatic(s, false); } goto parse_error; case '_': - if (strcmp(op, "struct.new_default") == 0) { return makeStructNewStatic(s, true); } + if (op == "struct.new_default"sv) { return makeStructNewStatic(s, true); } goto parse_error; default: goto parse_error; } } case 's': - if (strcmp(op, "struct.set") == 0) { return makeStructSet(s); } + if (op == "struct.set"sv) { return makeStructSet(s); } goto parse_error; default: goto parse_error; } @@ -3303,10 +3306,10 @@ switch (op[0]) { case 'g': { switch (op[7]) { case 'e': - if (strcmp(op, "table.get") == 0) { return makeTableGet(s); } + if (op == "table.get"sv) { return makeTableGet(s); } goto parse_error; case 'r': - if (strcmp(op, "table.grow") == 0) { return makeTableGrow(s); } + if (op == "table.grow"sv) { return makeTableGrow(s); } goto parse_error; default: goto parse_error; } @@ -3314,10 +3317,10 @@ switch (op[0]) { case 's': { switch (op[7]) { case 'e': - if (strcmp(op, "table.set") == 0) { return makeTableSet(s); } + if (op == "table.set"sv) { return makeTableSet(s); } goto parse_error; case 'i': - if (strcmp(op, "table.size") == 0) { return makeTableSize(s); } + if (op == "table.size"sv) { return makeTableSize(s); } goto parse_error; default: goto parse_error; } @@ -3328,24 +3331,24 @@ switch (op[0]) { case 'h': { switch (op[2]) { case 'e': - if (strcmp(op, "then") == 0) { return makeThenOrElse(s); } + if (op == "then"sv) { return makeThenOrElse(s); } goto parse_error; case 'r': - if (strcmp(op, "throw") == 0) { return makeThrow(s); } + if (op == "throw"sv) { return makeThrow(s); } goto parse_error; default: goto parse_error; } } case 'r': - if (strcmp(op, "try") == 0) { return makeTry(s); } + if (op == "try"sv) { return makeTry(s); } goto parse_error; case 'u': { switch (op[6]) { case 'e': - if (strcmp(op, "tuple.extract") == 0) { return makeTupleExtract(s); } + if (op == "tuple.extract"sv) { return makeTupleExtract(s); } goto parse_error; case 'm': - if (strcmp(op, "tuple.make") == 0) { return makeTupleMake(s); } + if (op == "tuple.make"sv) { return makeTupleMake(s); } goto parse_error; default: goto parse_error; } @@ -3354,7 +3357,7 @@ switch (op[0]) { } } case 'u': - if (strcmp(op, "unreachable") == 0) { return makeUnreachable(); } + if (op == "unreachable"sv) { return makeUnreachable(); } goto parse_error; case 'v': { switch (op[5]) { @@ -3363,40 +3366,40 @@ switch (op[0]) { case 'd': { switch (op[8]) { case '\0': - if (strcmp(op, "v128.and") == 0) { return makeBinary(s, BinaryOp::AndVec128); } + if (op == "v128.and"sv) { return makeBinary(s, BinaryOp::AndVec128); } goto parse_error; case 'n': - if (strcmp(op, "v128.andnot") == 0) { return makeBinary(s, BinaryOp::AndNotVec128); } + if (op == "v128.andnot"sv) { return makeBinary(s, BinaryOp::AndNotVec128); } goto parse_error; default: goto parse_error; } } case 'y': - if (strcmp(op, "v128.any_true") == 0) { return makeUnary(s, UnaryOp::AnyTrueVec128); } + if (op == "v128.any_true"sv) { return makeUnary(s, UnaryOp::AnyTrueVec128); } goto parse_error; default: goto parse_error; } } case 'b': - if (strcmp(op, "v128.bitselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::Bitselect); } + if (op == "v128.bitselect"sv) { return makeSIMDTernary(s, SIMDTernaryOp::Bitselect); } goto parse_error; case 'c': - if (strcmp(op, "v128.const") == 0) { return makeConst(s, Type::v128); } + if (op == "v128.const"sv) { return makeConst(s, Type::v128); } goto parse_error; case 'l': { switch (op[9]) { case '\0': - if (strcmp(op, "v128.load") == 0) { return makeLoad(s, Type::v128, /*isAtomic=*/false); } + if (op == "v128.load"sv) { return makeLoad(s, Type::v128, /*isAtomic=*/false); } goto parse_error; case '1': { switch (op[11]) { case '_': { switch (op[12]) { case 'l': - if (strcmp(op, "v128.load16_lane") == 0) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Load16LaneVec128); } + if (op == "v128.load16_lane"sv) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Load16LaneVec128); } goto parse_error; case 's': - if (strcmp(op, "v128.load16_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load16SplatVec128); } + if (op == "v128.load16_splat"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load16SplatVec128); } goto parse_error; default: goto parse_error; } @@ -3404,10 +3407,10 @@ switch (op[0]) { case 'x': { switch (op[14]) { case 's': - if (strcmp(op, "v128.load16x4_s") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load16x4SVec128); } + if (op == "v128.load16x4_s"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load16x4SVec128); } goto parse_error; case 'u': - if (strcmp(op, "v128.load16x4_u") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load16x4UVec128); } + if (op == "v128.load16x4_u"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load16x4UVec128); } goto parse_error; default: goto parse_error; } @@ -3420,13 +3423,13 @@ switch (op[0]) { case '_': { switch (op[12]) { case 'l': - if (strcmp(op, "v128.load32_lane") == 0) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Load32LaneVec128); } + if (op == "v128.load32_lane"sv) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Load32LaneVec128); } goto parse_error; case 's': - if (strcmp(op, "v128.load32_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load32SplatVec128); } + if (op == "v128.load32_splat"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load32SplatVec128); } goto parse_error; case 'z': - if (strcmp(op, "v128.load32_zero") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load32ZeroVec128); } + if (op == "v128.load32_zero"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load32ZeroVec128); } goto parse_error; default: goto parse_error; } @@ -3434,10 +3437,10 @@ switch (op[0]) { case 'x': { switch (op[14]) { case 's': - if (strcmp(op, "v128.load32x2_s") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load32x2SVec128); } + if (op == "v128.load32x2_s"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load32x2SVec128); } goto parse_error; case 'u': - if (strcmp(op, "v128.load32x2_u") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load32x2UVec128); } + if (op == "v128.load32x2_u"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load32x2UVec128); } goto parse_error; default: goto parse_error; } @@ -3448,13 +3451,13 @@ switch (op[0]) { case '6': { switch (op[12]) { case 'l': - if (strcmp(op, "v128.load64_lane") == 0) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Load64LaneVec128); } + if (op == "v128.load64_lane"sv) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Load64LaneVec128); } goto parse_error; case 's': - if (strcmp(op, "v128.load64_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load64SplatVec128); } + if (op == "v128.load64_splat"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load64SplatVec128); } goto parse_error; case 'z': - if (strcmp(op, "v128.load64_zero") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load64ZeroVec128); } + if (op == "v128.load64_zero"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load64ZeroVec128); } goto parse_error; default: goto parse_error; } @@ -3464,10 +3467,10 @@ switch (op[0]) { case '_': { switch (op[11]) { case 'l': - if (strcmp(op, "v128.load8_lane") == 0) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Load8LaneVec128); } + if (op == "v128.load8_lane"sv) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Load8LaneVec128); } goto parse_error; case 's': - if (strcmp(op, "v128.load8_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load8SplatVec128); } + if (op == "v128.load8_splat"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load8SplatVec128); } goto parse_error; default: goto parse_error; } @@ -3475,10 +3478,10 @@ switch (op[0]) { case 'x': { switch (op[13]) { case 's': - if (strcmp(op, "v128.load8x8_s") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load8x8SVec128); } + if (op == "v128.load8x8_s"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load8x8SVec128); } goto parse_error; case 'u': - if (strcmp(op, "v128.load8x8_u") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load8x8UVec128); } + if (op == "v128.load8x8_u"sv) { return makeSIMDLoad(s, SIMDLoadOp::Load8x8UVec128); } goto parse_error; default: goto parse_error; } @@ -3490,33 +3493,33 @@ switch (op[0]) { } } case 'n': - if (strcmp(op, "v128.not") == 0) { return makeUnary(s, UnaryOp::NotVec128); } + if (op == "v128.not"sv) { return makeUnary(s, UnaryOp::NotVec128); } goto parse_error; case 'o': - if (strcmp(op, "v128.or") == 0) { return makeBinary(s, BinaryOp::OrVec128); } + if (op == "v128.or"sv) { return makeBinary(s, BinaryOp::OrVec128); } goto parse_error; case 's': { switch (op[10]) { case '\0': - if (strcmp(op, "v128.store") == 0) { return makeStore(s, Type::v128, /*isAtomic=*/false); } + if (op == "v128.store"sv) { return makeStore(s, Type::v128, /*isAtomic=*/false); } goto parse_error; case '1': - if (strcmp(op, "v128.store16_lane") == 0) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Store16LaneVec128); } + if (op == "v128.store16_lane"sv) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Store16LaneVec128); } goto parse_error; case '3': - if (strcmp(op, "v128.store32_lane") == 0) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Store32LaneVec128); } + if (op == "v128.store32_lane"sv) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Store32LaneVec128); } goto parse_error; case '6': - if (strcmp(op, "v128.store64_lane") == 0) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Store64LaneVec128); } + if (op == "v128.store64_lane"sv) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Store64LaneVec128); } goto parse_error; case '8': - if (strcmp(op, "v128.store8_lane") == 0) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Store8LaneVec128); } + if (op == "v128.store8_lane"sv) { return makeSIMDLoadStoreLane(s, SIMDLoadStoreLaneOp::Store8LaneVec128); } goto parse_error; default: goto parse_error; } } case 'x': - if (strcmp(op, "v128.xor") == 0) { return makeBinary(s, BinaryOp::XorVec128); } + if (op == "v128.xor"sv) { return makeBinary(s, BinaryOp::XorVec128); } goto parse_error; default: goto parse_error; } diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp index acd446acc..924040e12 100644 --- a/src/ir/ExpressionAnalyzer.cpp +++ b/src/ir/ExpressionAnalyzer.cpp @@ -364,7 +364,7 @@ struct Hasher { rehash(digest, 2); rehash(digest, internalNames[curr]); } - void visitNonScopeName(Name curr) { rehash(digest, uint64_t(curr.str)); } + void visitNonScopeName(Name curr) { rehash(digest, curr); } void visitType(Type curr) { rehash(digest, curr.getID()); } void visitHeapType(HeapType curr) { rehash(digest, curr.getID()); } void visitAddress(Address curr) { rehash(digest, curr.addr); } diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index 8294e1575..a350f0e33 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -353,7 +353,7 @@ void ModuleSplitter::exportImportFunction(Name funcName) { } while (primary.getExportOrNull(exportName) != nullptr); } else { exportName = Names::getValidExportName( - primary, config.newExportPrefix + funcName.c_str()); + primary, config.newExportPrefix + funcName.toString()); } primary.addExport( Builder::makeExport(exportName, funcName, ExternalKind::Function)); @@ -492,8 +492,7 @@ void ModuleSplitter::setupTablePatching() { placeholder->module = config.placeholderNamespace; placeholder->base = std::to_string(index); placeholder->name = Names::getValidFunctionName( - primary, - std::string("placeholder_") + std::string(placeholder->base.c_str())); + primary, std::string("placeholder_") + placeholder->base.toString()); placeholder->hasExplicitName = false; placeholder->type = secondaryFunc->type; elem = placeholder->name; diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp index e5886a348..94ad5859e 100644 --- a/src/passes/Asyncify.cpp +++ b/src/passes/Asyncify.cpp @@ -444,9 +444,9 @@ public: // internal escaped names for later comparisons for (auto& name : list) { auto escaped = WasmBinaryBuilder::escape(name); - unescaped[escaped.str] = name; + unescaped[escaped.toString()] = name; if (name.find('*') != std::string::npos) { - patterns.insert(escaped.str); + patterns.insert(escaped.toString()); } else { auto* func = module.getFunctionOrNull(escaped); if (!func) { @@ -469,7 +469,7 @@ public: return true; } else { for (auto& pattern : patterns) { - if (String::wildcardMatch(pattern, funcName.str)) { + if (String::wildcardMatch(pattern, funcName.toString())) { patternsMatched.insert(pattern); return true; } @@ -1502,7 +1502,7 @@ private: } // anonymous namespace static std::string getFullImportName(Name module, Name base) { - return std::string(module.str) + '.' + base.str; + return std::string(module.str) + '.' + base.toString(); } struct Asyncify : public Pass { diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp index 80818907f..3255208fe 100644 --- a/src/passes/FuncCastEmulation.cpp +++ b/src/passes/FuncCastEmulation.cpp @@ -177,7 +177,7 @@ struct FuncCastEmulation : public Pass { private: // Creates a thunk for a function, casting args and return value as needed. Name makeThunk(Name name, Module* module, Index numParams) { - Name thunk = std::string("byn$fpcast-emu$") + name.str; + Name thunk = std::string("byn$fpcast-emu$") + name.toString(); if (module->getFunctionOrNull(thunk)) { Fatal() << "FuncCastEmulation::makeThunk seems a thunk name already in " "use. Was the pass already run on this code?"; diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp index 313070e9a..aee65c22a 100644 --- a/src/passes/I64ToI32Lowering.cpp +++ b/src/passes/I64ToI32Lowering.cpp @@ -22,13 +22,13 @@ // #include "abi/js.h" -#include "emscripten-optimizer/istring.h" #include "ir/flat.h" #include "ir/iteration.h" #include "ir/memory-utils.h" #include "ir/module-utils.h" #include "ir/names.h" #include "pass.h" +#include "support/istring.h" #include "support/name.h" #include "wasm-builder.h" #include "wasm.h" @@ -36,7 +36,7 @@ namespace wasm { -static Name makeHighName(Name n) { return std::string(n.c_str()) + "$hi"; } +static Name makeHighName(Name n) { return n.toString() + "$hi"; } struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { struct TempVar { @@ -263,7 +263,8 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { // If this was to an import, we need to call the legal version. This assumes // that legalize-js-interface has been run before. if (fixedCall && getModule()->getFunction(fixedCall->target)->imported()) { - fixedCall->target = std::string("legalfunc$") + fixedCall->target.str; + fixedCall->target = + std::string("legalfunc$") + fixedCall->target.toString(); return; } } diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index f325f70c6..90cf3f5da 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -324,7 +324,7 @@ static Expression* doInlining(Module* module, Type retType = module->getFunction(call->target)->getResults(); Builder builder(*module); auto* block = builder.makeBlock(); - block->name = Name(std::string("__inlined_func$") + from->name.str); + block->name = Name(std::string("__inlined_func$") + from->name.toString()); // In the unlikely event that the function already has a branch target with // this name, fix that up, as otherwise we can get unexpected capture of our // branches, that is, we could end up with this: @@ -767,7 +767,8 @@ private: return ModuleUtils::copyFunction( func, *module, - Names::getValidFunctionName(*module, prefix + '$' + func->name.str)); + Names::getValidFunctionName(*module, + prefix + '$' + func->name.toString())); } // Get the i-th item in a sequence of initial items in an expression. That is, diff --git a/src/passes/JSPI.cpp b/src/passes/JSPI.cpp index fe24d60f7..48f6207ed 100644 --- a/src/passes/JSPI.cpp +++ b/src/passes/JSPI.cpp @@ -88,7 +88,7 @@ struct JSPI : public Pass { private: Name makeWrapperForExport(Function* func, Module* module, Name suspender) { Name wrapperName = Names::getValidFunctionName( - *module, std::string("export$") + func->name.str); + *module, std::string("export$") + func->name.toString()); Builder builder(*module); @@ -137,7 +137,7 @@ private: Builder builder(*module); auto wrapperIm = make_unique<Function>(); wrapperIm->name = Names::getValidFunctionName( - *module, std::string("import$") + im->name.str); + *module, std::string("import$") + im->name.toString()); wrapperIm->module = im->module; wrapperIm->base = im->base; auto stub = make_unique<Function>(); diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp index bbef5109d..f5dbbcf62 100644 --- a/src/passes/LegalizeJSInterface.cpp +++ b/src/passes/LegalizeJSInterface.cpp @@ -90,7 +90,7 @@ struct LegalizeJSInterface : public Pass { // are only called from JS. if (!func->imported() && !isDynCall(ex->name)) { Builder builder(*module); - Name newName = std::string("orig$") + ex->name.str; + Name newName = std::string("orig$") + ex->name.toString(); newExports.push_back(builder.makeExport( newName, func->name, ExternalKind::Function)); } @@ -239,7 +239,7 @@ private: // JS calls the export, so it must call a legal stub that calls the actual // wasm function Name makeLegalStub(Function* func, Module* module) { - Name legalName(std::string("legalstub$") + func->name.str); + Name legalName(std::string("legalstub$") + func->name.toString()); // a method may be exported multiple times if (module->getFunctionOrNull(legalName)) { @@ -292,11 +292,11 @@ private: Name makeLegalStubForCalledImport(Function* im, Module* module) { Builder builder(*module); auto legalIm = make_unique<Function>(); - legalIm->name = Name(std::string("legalimport$") + im->name.str); + legalIm->name = Name(std::string("legalimport$") + im->name.toString()); legalIm->module = im->module; legalIm->base = im->base; auto stub = make_unique<Function>(); - stub->name = Name(std::string("legalfunc$") + im->name.str); + stub->name = Name(std::string("legalfunc$") + im->name.toString()); stub->type = im->type; auto* call = module->allocator.alloc<Call>(); diff --git a/src/passes/MemoryPacking.cpp b/src/passes/MemoryPacking.cpp index 98b9c1df7..ed348ef57 100644 --- a/src/passes/MemoryPacking.cpp +++ b/src/passes/MemoryPacking.cpp @@ -569,8 +569,7 @@ void MemoryPacking::createSplitSegments( name = segment->name; hasExplicitName = segment->hasExplicitName; } else { - name = std::string(segment->name.c_str()) + "." + - std::to_string(segmentCount); + name = segment->name.toString() + "." + std::to_string(segmentCount); } segmentCount++; } diff --git a/src/passes/MergeSimilarFunctions.cpp b/src/passes/MergeSimilarFunctions.cpp index e5e50423a..8e039566a 100644 --- a/src/passes/MergeSimilarFunctions.cpp +++ b/src/passes/MergeSimilarFunctions.cpp @@ -526,8 +526,9 @@ bool EquivalentClass::hasMergeBenefit(Module* module, Function* EquivalentClass::createShared(Module* module, const std::vector<ParamInfo>& params) { - Name fnName = Names::getValidFunctionName( - *module, std::string("byn$mgfn-shared$") + primaryFunction->name.str); + Name fnName = Names::getValidFunctionName(*module, + std::string("byn$mgfn-shared$") + + primaryFunction->name.toString()); Builder builder(*module); std::vector<Type> sigParams; Index extraParamBase = primaryFunction->getNumParams(); diff --git a/src/passes/Metrics.cpp b/src/passes/Metrics.cpp index 480273da9..35b4241b2 100644 --- a/src/passes/Metrics.cpp +++ b/src/passes/Metrics.cpp @@ -104,7 +104,7 @@ struct Metrics counts["[vars]"] = func->getNumVars(); counts["[binary-bytes]"] = writer.tableOfContents.functionBodies[binaryIndex++].size; - printCounts(std::string("func: ") + func->name.str); + printCounts(std::string("func: ") + func->name.toString()); }); // print for each export how much code size is due to it, i.e., // how much the module could shrink without it. @@ -134,8 +134,8 @@ struct Metrics counts.clear(); counts["[removable-bytes-without-it]"] = baseline - sizeAfterGlobalCleanup(&test); - printCounts(std::string("export: ") + exp->name.str + " (" + - exp->value.str + ')'); + printCounts(std::string("export: ") + exp->name.toString() + " (" + + exp->value.toString() + ')'); } // check how much size depends on the start method if (!module->start.isNull()) { @@ -145,7 +145,7 @@ struct Metrics counts.clear(); counts["[removable-bytes-without-it]"] = baseline - sizeAfterGlobalCleanup(&test); - printCounts(std::string("start: ") + module->start.str); + printCounts(std::string("start: ") + module->start.toString()); } // can't compare detailed info between passes yet lastCounts.clear(); diff --git a/src/passes/Poppify.cpp b/src/passes/Poppify.cpp index 582753c4b..e47b13568 100644 --- a/src/passes/Poppify.cpp +++ b/src/passes/Poppify.cpp @@ -87,8 +87,8 @@ namespace { // Generate names for the elements of tuple globals Name getGlobalElem(Module* module, Name global, Index i) { - return Names::getValidGlobalName( - *module, std::string(global.c_str()) + '$' + std::to_string(i)); + return Names::getValidGlobalName(*module, + global.toString() + '$' + std::to_string(i)); } struct Poppifier : BinaryenIRWriter<Poppifier> { diff --git a/src/passes/PostEmscripten.cpp b/src/passes/PostEmscripten.cpp index c936337f3..86b7b8bc3 100644 --- a/src/passes/PostEmscripten.cpp +++ b/src/passes/PostEmscripten.cpp @@ -184,8 +184,6 @@ static void removeData(Module& wasm, << startAddress << ") and " << end_sym << " (" << endAddress << ")"; } -using IString = cashew::IString; - IString EM_JS_PREFIX("__em_js__"); IString EM_JS_DEPS_PREFIX("__em_lib_deps_"); @@ -193,10 +191,10 @@ struct EmJsWalker : public PostWalker<EmJsWalker> { std::vector<Export> toRemove; void visitExport(Export* curr) { - if (curr->name.startsWith(EM_JS_PREFIX.str)) { + if (curr->name.startsWith(EM_JS_PREFIX)) { toRemove.push_back(*curr); } - if (curr->name.startsWith(EM_JS_DEPS_PREFIX.str)) { + if (curr->name.startsWith(EM_JS_DEPS_PREFIX)) { toRemove.push_back(*curr); } } diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 7ebad3322..ddd8f9cc1 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -50,8 +50,13 @@ bool isFullForced() { } std::ostream& printName(Name name, std::ostream& o) { - // we need to quote names if they have tricky chars - if (!name.str || !strpbrk(name.str, "()")) { + assert(name && "Cannot print an empty name"); + // We need to quote names if they have tricky chars. + // TODO: This is not spec-compliant since the spec does not support quoted + // identifiers and has a limited set of valid idchars. We need a more robust + // escaping scheme here. Reusing `printEscapedString` is not sufficient, + // either. + if (name.str.find_first_of("()") == std::string_view::npos) { o << '$' << name.str; } else { o << "\"$" << name.str << '"'; @@ -383,11 +388,9 @@ void processFieldName(Module* wasm, HeapType type, Index index, T func) { func(Name()); } -std::ostream& -printEscapedString(std::ostream& os, const char* data, size_t len) { +std::ostream& printEscapedString(std::ostream& os, std::string_view str) { os << '"'; - for (size_t i = 0; i < len; i++) { - unsigned char c = data[i]; + for (unsigned char c : str) { switch (c) { case '\t': os << "\\t"; @@ -2303,7 +2306,7 @@ struct PrintExpressionContents } void visitStringConst(StringConst* curr) { printMedium(o, "string.const "); - printEscapedString(o, curr->string.c_str(), curr->string.size()); + printEscapedString(o, curr->string.str); } void visitStringMeasure(StringMeasure* curr) { switch (curr->op) { @@ -2926,7 +2929,8 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { void visitExport(Export* curr) { o << '('; printMedium(o, "export "); - printText(o, curr->name.str) << " ("; + // TODO: Escape the string properly. + printText(o, curr->name.str.data()) << " ("; switch (curr->kind) { case ExternalKind::Function: o << "func"; @@ -2951,8 +2955,9 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { } void emitImportHeader(Importable* curr) { printMedium(o, "import "); - printText(o, curr->module.str) << ' '; - printText(o, curr->base.str) << ' '; + // TODO: Escape the strings properly and use std::string_view. + printText(o, curr->module.str.data()) << ' '; + printText(o, curr->base.str.data()) << ' '; } void visitGlobal(Global* curr) { if (curr->imported()) { @@ -3233,7 +3238,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> { visit(curr->offset); o << ' '; } - printEscapedString(o, curr->data.data(), curr->data.size()); + printEscapedString(o, {curr->data.data(), curr->data.size()}); o << ')' << maybeNewLine; } void printDylinkSection(const std::unique_ptr<DylinkSection>& dylinkSection) { diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp index c77bff9af..0cafd9d9d 100644 --- a/src/passes/RemoveUnusedModuleElements.cpp +++ b/src/passes/RemoveUnusedModuleElements.cpp @@ -246,7 +246,7 @@ struct RemoveUnusedModuleElements : public Pass { auto startFunction = module->getFunction(module->start); // Can be skipped if the start function is empty. if (!startFunction->imported() && startFunction->body->is<Nop>()) { - module->start.clear(); + module->start = Name{}; } else { roots.emplace_back(ModuleElementKind::Function, module->start); } diff --git a/src/passes/ReorderFunctions.cpp b/src/passes/ReorderFunctions.cpp index b6c7a4984..6c8c55075 100644 --- a/src/passes/ReorderFunctions.cpp +++ b/src/passes/ReorderFunctions.cpp @@ -86,7 +86,7 @@ struct ReorderFunctions : public Pass { [&counts](const std::unique_ptr<Function>& a, const std::unique_ptr<Function>& b) -> bool { if (counts[a->name] == counts[b->name]) { - return strcmp(a->name.str, b->name.str) > 0; + return a->name > b->name; } return counts[a->name] > counts[b->name]; }); diff --git a/src/passes/SetGlobals.cpp b/src/passes/SetGlobals.cpp index 58a82a50b..3bcbb3d31 100644 --- a/src/passes/SetGlobals.cpp +++ b/src/passes/SetGlobals.cpp @@ -34,7 +34,7 @@ struct SetGlobals : public Pass { "SetGlobals usage: wasm-opt --pass-arg=set-globals@x=y,z=w"); // The input is a set of X=Y pairs separated by commas. - String::Split pairs(input.str, ","); + String::Split pairs(input.toString(), ","); for (auto& pair : pairs) { String::Split nameAndValue(pair, "="); auto name = nameAndValue[0]; diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 4036b8f47..197a59f41 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -638,7 +638,7 @@ static void dumpWast(Name name, Module* wasm) { // TODO: use _getpid() on windows, elsewhere? fullName += std::to_string(getpid()) + '-'; #endif - fullName += numstr + "-" + name.str; + fullName += numstr + "-" + name.toString(); Colors::setEnabled(false); ModuleWriter writer; writer.writeText(*wasm, fullName + ".wast"); diff --git a/src/support/CMakeLists.txt b/src/support/CMakeLists.txt index 0d9350305..a02c1f447 100644 --- a/src/support/CMakeLists.txt +++ b/src/support/CMakeLists.txt @@ -6,6 +6,7 @@ set(support_SOURCES command-line.cpp debug.cpp file.cpp + istring.cpp path.cpp safe_integer.cpp threads.cpp diff --git a/src/support/istring.cpp b/src/support/istring.cpp new file mode 100644 index 000000000..8a3319b5e --- /dev/null +++ b/src/support/istring.cpp @@ -0,0 +1,88 @@ +/* + * Copyright 2022 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 "istring.h" + +namespace wasm { + +std::string_view IString::interned(std::string_view s, bool reuse) { + // We need a set of string_views that can be modified in-place to minimize + // the number of lookups we do. Since set elements cannot normally be + // modified, wrap the string_views in a container that provides mutability + // even through a const reference. + struct MutStringView { + mutable std::string_view str; + MutStringView(std::string_view str) : str(str) {} + }; + struct MutStringViewHash { + size_t operator()(const MutStringView& mut) const { + return std::hash<std::string_view>{}(mut.str); + } + }; + struct MutStringViewEqual { + bool operator()(const MutStringView& a, const MutStringView& b) const { + return a.str == b.str; + } + }; + using StringSet = + std::unordered_set<MutStringView, MutStringViewHash, MutStringViewEqual>; + + // The authoritative global set of interned string views. + static StringSet globalStrings; + + // The global backing store for interned strings that do not otherwise have + // stable addresses. + static std::vector<std::vector<char>> allocated; + + // Guards access to `globalStrings` and `allocated`. + static std::mutex mutex; + + // A thread-local cache of strings to reduce contention. + thread_local static StringSet localStrings; + + auto [localIt, localInserted] = localStrings.insert(s); + if (!localInserted) { + // We already had a local copy of this string. + return localIt->str; + } + + // No copy yet in the local cache. Check the global cache. + std::unique_lock<std::mutex> lock(mutex); + auto [globalIt, globalInserted] = globalStrings.insert(s); + if (!globalInserted) { + // We already had a global copy of this string. Cache it locally. + localIt->str = globalIt->str; + return localIt->str; + } + + if (!reuse) { + // We have a new string, but it doesn't have a stable address. Create a copy + // of the data at a stable address we can use. Make sure it is null + // terminated so legacy uses that get a C string still work. + allocated.emplace_back(); + auto& data = allocated.back(); + data.reserve(s.size() + 1); + data.insert(data.end(), s.begin(), s.end()); + data.push_back('\0'); + s = std::string_view(allocated.back().data(), s.size()); + } + + // Intern our new string. + localIt->str = globalIt->str = s; + return s; +} + +} // namespace wasm diff --git a/src/support/istring.h b/src/support/istring.h new file mode 100644 index 000000000..14f991c30 --- /dev/null +++ b/src/support/istring.h @@ -0,0 +1,110 @@ +/* + * Copyright 2022 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. + */ + +// Interned String type, 100% interned on creation. Comparisons are always just +// a pointer comparison + +#ifndef wasm_support_istring_h +#define wasm_support_istring_h + +#include <set> +#include <string_view> +#include <unordered_set> + +#include <assert.h> + +#include "threads.h" +#include "utilities.h" + +namespace wasm { + +struct IString { +private: + static std::string_view interned(std::string_view s, bool reuse = true); + +public: + const std::string_view str; + + IString() = default; + + // TODO: This is a wildly unsafe default inherited from the previous + // implementation. Change it? + IString(std::string_view str, bool reuse = true) + : str(interned(str, reuse)) {} + + // But other C strings generally do need to be copied. + IString(const char* str) : str(interned(str, false)) {} + IString(const std::string& str) : str(interned(str, false)) {} + + IString(const IString& other) = default; + + IString& operator=(const IString& other) { + return *(new (this) IString(other)); + } + + bool operator==(const IString& other) const { + // Fast! No need to compare contents due to interning + return str.data() == other.str.data(); + } + bool operator!=(const IString& other) const { return !(*this == other); } + bool operator<(const IString& other) const { return str < other.str; } + bool operator<=(const IString& other) const { return str <= other.str; } + bool operator>(const IString& other) const { return str > other.str; } + bool operator>=(const IString& other) const { return str >= other.str; } + + char operator[](int x) const { return str[x]; } + + operator bool() const { return str.data() != nullptr; } + + // TODO: deprecate? + bool is() const { return bool(*this); } + bool isNull() const { return !bool(*this); } + + std::string toString() const { return {str.data(), str.size()}; } + + bool equals(std::string_view other) const { return str == other; } + + bool startsWith(std::string_view prefix) const { + // TODO: Use C++20 `starts_with`. + return str.substr(0, prefix.size()) == prefix; + } + bool startsWith(IString str) const { return startsWith(str.str); } + + // Disambiguate for string literals. + template<int N> bool startsWith(const char (&str)[N]) { + return startsWith(std::string_view(str)); + } + + size_t size() const { return str.size(); } +}; + +} // namespace wasm + +namespace std { + +template<> struct hash<wasm::IString> { + size_t operator()(const wasm::IString& str) const { + return std::hash<size_t>{}(uintptr_t(str.str.data())); + } +}; + +inline std::ostream& operator<<(std::ostream& os, const wasm::IString& str) { + return os << str.str; +} + +} // namespace std + +#endif // wasm_support_istring_h diff --git a/src/support/json.h b/src/support/json.h index a145e1f6b..269b6c0e9 100644 --- a/src/support/json.h +++ b/src/support/json.h @@ -37,12 +37,12 @@ #include <unordered_set> #include <vector> -#include "emscripten-optimizer/istring.h" +#include "support/istring.h" #include "support/safe_integer.h" namespace json { -using IString = cashew::IString; +using IString = wasm::IString; // Main value type struct Value { @@ -112,13 +112,13 @@ struct Value { Value& setString(const char* s) { free(); type = String; - str.set(s); + str = s; return *this; } Value& setString(const IString& s) { free(); type = String; - str.set(s); + str = s; return *this; } Value& setNumber(double n) { @@ -173,7 +173,7 @@ struct Value { const char* getCString() { assert(isString()); - return str.str; + return str.str.data(); } IString& getIString() { assert(isString()); diff --git a/src/support/name.h b/src/support/name.h index 615740e09..a22461d5d 100644 --- a/src/support/name.h +++ b/src/support/name.h @@ -17,9 +17,7 @@ #ifndef wasm_support_name_h #define wasm_support_name_h -#include <string> - -#include "emscripten-optimizer/istring.h" +#include "support/istring.h" namespace wasm { @@ -33,14 +31,19 @@ namespace wasm { // TODO: as an optimization, IString values < some threshold could be considered // numerical indices directly. -struct Name : public cashew::IString { - Name() : cashew::IString() {} - Name(const char* str) : cashew::IString(str, false) {} - Name(cashew::IString str) : cashew::IString(str) {} - Name(const std::string& str) : cashew::IString(str.c_str(), false) {} +struct Name : public IString { + Name() : IString() {} + Name(std::string_view str) : IString(str, false) {} + Name(const char* str) : IString(str, false) {} + Name(IString str) : IString(str) {} + Name(const std::string& str) : IString(str) {} + + // String literals do not need to be copied. Note: Not safe to construct from + // temporary char arrays! Take their address first. + template<size_t N> Name(const char (&str)[N]) : IString(str) {} friend std::ostream& operator<<(std::ostream& o, Name name) { - if (name.str) { + if (name) { return o << name.str; } else { return o << "(null Name)"; @@ -48,11 +51,12 @@ struct Name : public cashew::IString { } static Name fromInt(size_t i) { - return cashew::IString(std::to_string(i).c_str(), false); + return IString(std::to_string(i).c_str(), false); } - bool hasSubstring(cashew::IString substring) { - return strstr(c_str(), substring.c_str()) != nullptr; + bool hasSubstring(IString substring) { + // TODO: Use C++23 `contains`. + return str.find(substring.str) != std::string_view::npos; } }; @@ -60,7 +64,7 @@ struct Name : public cashew::IString { namespace std { -template<> struct hash<wasm::Name> : hash<cashew::IString> {}; +template<> struct hash<wasm::Name> : hash<wasm::IString> {}; } // namespace std diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 09df9ac31..8023ab4da 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -889,7 +889,7 @@ void TranslateToFuzzReader::dropToLog(Function* func) { } void TranslateToFuzzReader::addInvocations(Function* func) { - Name name = func->name.str + std::string("_invoker"); + Name name = func->name.toString() + std::string("_invoker"); if (wasm.getFunctionOrNull(name) || wasm.getExportOrNull(name)) { return; } diff --git a/src/tools/js-wrapper.h b/src/tools/js-wrapper.h index b93948e74..85bc3d7ba 100644 --- a/src/tools/js-wrapper.h +++ b/src/tools/js-wrapper.h @@ -94,15 +94,15 @@ inline std::string generateJSWrapper(Module& wasm) { ret += "if (instance.exports.hangLimitInitializer) " "instance.exports.hangLimitInitializer();\n"; ret += "try {\n"; - ret += std::string(" console.log('[fuzz-exec] calling ") + exp->name.str + - "');\n"; + ret += std::string(" console.log('[fuzz-exec] calling ") + + exp->name.toString() + "');\n"; if (func->getResults() != Type::none) { ret += std::string(" console.log('[fuzz-exec] note result: ") + - exp->name.str + " => ' + literal("; + exp->name.toString() + " => ' + literal("; } else { ret += " "; } - ret += std::string("instance.exports.") + exp->name.str + "("; + ret += std::string("instance.exports.") + exp->name.toString() + "("; bool first = true; for (auto param : func->getParams()) { // zeros in arguments TODO more? diff --git a/src/tools/spec-wrapper.h b/src/tools/spec-wrapper.h index 366e8d4fc..95ead4739 100644 --- a/src/tools/spec-wrapper.h +++ b/src/tools/spec-wrapper.h @@ -32,7 +32,7 @@ inline std::string generateSpecWrapper(Module& wasm) { continue; // something exported other than a function } ret += std::string("(invoke \"hangLimitInitializer\") (invoke \"") + - exp->name.str + "\" "; + exp->name.toString() + "\" "; for (const auto& param : func->getParams()) { // zeros in arguments TODO more? TODO_SINGLE_COMPOUND(param); diff --git a/src/tools/wasm-as.cpp b/src/tools/wasm-as.cpp index 382692273..cc4f6fda2 100644 --- a/src/tools/wasm-as.cpp +++ b/src/tools/wasm-as.cpp @@ -27,7 +27,6 @@ #include "tool-options.h" #include "tool-utils.h" -using namespace cashew; using namespace wasm; int main(int argc, const char* argv[]) { diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 45cc63c37..40abe2f76 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -67,7 +67,8 @@ public: auto* global = wasm.getGlobal(curr->name); if (global->imported()) { throw FailToEvalException(std::string("read from imported global ") + - global->module.str + "." + global->base.str); + global->module.toString() + "." + + global->base.toString()); } return ModuleRunnerBase<EvallingModuleRunner>::visitGlobalGet(curr); @@ -184,13 +185,14 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { auto* globalExport = inst->wasm.getExportOrNull(global->base); if (!globalExport) { throw FailToEvalException(std::string("importGlobals: ") + - global->module.str + "." + - global->base.str); + global->module.toString() + "." + + global->base.toString()); } globals[global->name] = inst->globals[globalExport->value]; } else { throw FailToEvalException(std::string("importGlobals: ") + - global->module.str + "." + global->base.str); + global->module.toString() + "." + + global->base.toString()); } }); } @@ -255,8 +257,8 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { extra = RECOMMENDATION "consider --ignore-external-input"; } throw FailToEvalException(std::string("call import: ") + - import->module.str + "." + import->base.str + - extra); + import->module.toString() + "." + + import->base.toString() + extra); } // We assume the table is not modified FIXME @@ -318,13 +320,14 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { auto* func = wasm->getFunction(targetFunc); if (func->type != sig) { throw FailToEvalException(std::string("callTable signature mismatch: ") + - targetFunc.str); + targetFunc.toString()); } if (!func->imported()) { return instance.callFunctionInternal(targetFunc, arguments); } else { throw FailToEvalException( - std::string("callTable on imported function: ") + targetFunc.str); + std::string("callTable on imported function: ") + + targetFunc.toString()); } } diff --git a/src/tools/wasm-dis.cpp b/src/tools/wasm-dis.cpp index b4003b2c8..e8ca71528 100644 --- a/src/tools/wasm-dis.cpp +++ b/src/tools/wasm-dis.cpp @@ -24,7 +24,6 @@ #include "tool-options.h" -using namespace cashew; using namespace wasm; int main(int argc, const char* argv[]) { diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp index 99d03cec0..0f63e8112 100644 --- a/src/tools/wasm-emscripten-finalize.cpp +++ b/src/tools/wasm-emscripten-finalize.cpp @@ -34,7 +34,6 @@ #define DEBUG_TYPE "emscripten" -using namespace cashew; using namespace wasm; int main(int argc, const char* argv[]) { diff --git a/src/tools/wasm-metadce.cpp b/src/tools/wasm-metadce.cpp index 5699b40f2..8a0170f0f 100644 --- a/src/tools/wasm-metadce.cpp +++ b/src/tools/wasm-metadce.cpp @@ -115,19 +115,19 @@ struct MetaDCEGraph { // does not alter parent state, just adds to things pointed by it, // independently (each thread will add for one function, etc.) ModuleUtils::iterDefinedFunctions(wasm, [&](Function* func) { - auto dceName = getName("func", func->name.str); + auto dceName = getName("func", func->name.toString()); DCENodeToFunction[dceName] = func->name; functionToDCENode[func->name] = dceName; nodes[dceName] = DCENode(dceName); }); ModuleUtils::iterDefinedGlobals(wasm, [&](Global* global) { - auto dceName = getName("global", global->name.str); + auto dceName = getName("global", global->name.toString()); DCENodeToGlobal[dceName] = global->name; globalToDCENode[global->name] = dceName; nodes[dceName] = DCENode(dceName); }); ModuleUtils::iterDefinedTags(wasm, [&](Tag* tag) { - auto dceName = getName("tag", tag->name.str); + auto dceName = getName("tag", tag->name.toString()); DCENodeToTag[dceName] = tag->name; tagToDCENode[tag->name] = dceName; nodes[dceName] = DCENode(dceName); @@ -137,27 +137,27 @@ struct MetaDCEGraph { ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) { auto id = getImportId(import->module, import->base); if (importIdToDCENode.find(id) == importIdToDCENode.end()) { - auto dceName = getName("importId", import->name.str); + auto dceName = getName("importId", import->name.toString()); importIdToDCENode[id] = dceName; } }); ModuleUtils::iterImportedGlobals(wasm, [&](Global* import) { auto id = getImportId(import->module, import->base); if (importIdToDCENode.find(id) == importIdToDCENode.end()) { - auto dceName = getName("importId", import->name.str); + auto dceName = getName("importId", import->name.toString()); importIdToDCENode[id] = dceName; } }); ModuleUtils::iterImportedTags(wasm, [&](Tag* import) { auto id = getImportId(import->module, import->base); if (importIdToDCENode.find(id) == importIdToDCENode.end()) { - auto dceName = getName("importId", import->name.str); + auto dceName = getName("importId", import->name.toString()); importIdToDCENode[id] = dceName; } }); for (auto& exp : wasm.exports) { if (exportToDCENode.find(exp->name) == exportToDCENode.end()) { - auto dceName = getName("export", exp->name.str); + auto dceName = getName("export", exp->name.toString()); DCENodeToExport[dceName] = exp->name; exportToDCENode[exp->name] = dceName; nodes[dceName] = DCENode(dceName); @@ -368,7 +368,7 @@ public: std::set<std::string> unused; for (auto& [name, _] : nodes) { if (reached.find(name) == reached.end()) { - unused.insert(name.str); + unused.insert(name.toString()); } } for (auto& name : unused) { diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp index 557e8a770..eec1e0874 100644 --- a/src/tools/wasm-reduce.cpp +++ b/src/tools/wasm-reduce.cpp @@ -488,7 +488,7 @@ struct Reducer std::string getLocation() { if (getFunction()) { - return getFunction()->name.str; + return getFunction()->name.toString(); } return "(non-function context)"; } diff --git a/src/tools/wasm-shell.cpp b/src/tools/wasm-shell.cpp index 4b20e922b..61b35e6db 100644 --- a/src/tools/wasm-shell.cpp +++ b/src/tools/wasm-shell.cpp @@ -31,7 +31,6 @@ #include "wasm-s-parser.h" #include "wasm-validator.h" -using namespace cashew; using namespace wasm; Name ASSERT_RETURN("assert_return"); @@ -162,7 +161,7 @@ protected: instances[name] = instances[lastModule]; Colors::green(std::cerr); - std::cerr << "REGISTER MODULE INSTANCE AS \"" << name.c_str() + std::cerr << "REGISTER MODULE INSTANCE AS \"" << name.str << "\" [line: " << s.line << "]\n"; Colors::normal(std::cerr); } @@ -190,7 +189,7 @@ protected: return instance->getExport(base); } - Fatal() << "Invalid operation " << s[0]->c_str(); + Fatal() << "Invalid operation " << s[0]->toString(); } void parseAssertTrap(Element& s) { diff --git a/src/tools/wasm-split/instrumenter.cpp b/src/tools/wasm-split/instrumenter.cpp index 86a52688e..22940a5f2 100644 --- a/src/tools/wasm-split/instrumenter.cpp +++ b/src/tools/wasm-split/instrumenter.cpp @@ -47,8 +47,8 @@ void Instrumenter::addGlobals(size_t numFuncs) { counterGlobal = Names::getValidGlobalName(*wasm, "monotonic_counter"); functionGlobals.reserve(numFuncs); ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) { - functionGlobals.push_back(Names::getValidGlobalName( - *wasm, std::string(func->name.c_str()) + "_timestamp")); + functionGlobals.push_back( + Names::getValidGlobalName(*wasm, func->name.toString() + "_timestamp")); }); // Create and add new globals diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp index 49a15e934..aa21ec2cb 100644 --- a/src/tools/wasm-split/wasm-split.cpp +++ b/src/tools/wasm-split/wasm-split.cpp @@ -452,7 +452,8 @@ void printReadableProfile(const WasmSplitOptions& options) { auto printFnSet = [&](auto funcs, std::string prefix) { for (auto it = funcs.begin(); it != funcs.end(); ++it) { std::cout << prefix << " " - << (options.unescape ? unescape(it->c_str()) : it->c_str()) + << (options.unescape ? unescape(it->toString()) + : it->toString()) << std::endl; } }; diff --git a/src/tools/wasm2c-wrapper.h b/src/tools/wasm2c-wrapper.h index ae32ec744..f44fc5ca0 100644 --- a/src/tools/wasm2c-wrapper.h +++ b/src/tools/wasm2c-wrapper.h @@ -30,9 +30,7 @@ namespace wasm { inline std::string wasm2cMangle(Name name, Signature sig) { const char escapePrefix = 'Z'; std::string mangled = "Z_"; - const char* original = name.str; - unsigned char c; - while ((c = *original++)) { + for (unsigned char c : name.str) { if ((isalnum(c) && c != escapePrefix) || c == '_') { // This character is ok to emit as it is. mangled += c; @@ -168,14 +166,14 @@ int main(int argc, char** argv) { auto* func = wasm.getFunction(exp->value); ret += std::string(" puts(\"[fuzz-exec] calling ") + - exp->name.str + "\");\n"; + exp->name.toString() + "\");\n"; auto result = func->getResults(); // Emit the call itself. ret += " "; if (result != Type::none) { - ret += std::string("printf(\"[fuzz-exec] note result: ") + exp->name.str + - " => "; + ret += std::string("printf(\"[fuzz-exec] note result: ") + + exp->name.toString() + " => "; TODO_SINGLE_COMPOUND(result); switch (result.getBasic()) { case Type::i32: diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp index 7cecb5f6d..a6430fe12 100644 --- a/src/tools/wasm2js.cpp +++ b/src/tools/wasm2js.cpp @@ -834,7 +834,7 @@ void AssertionEmitter::emit() { )"; Builder wasmBuilder(sexpBuilder.getModule()); - Name asmModule = std::string("ret") + ASM_FUNC.str; + Name asmModule = std::string("ret") + ASM_FUNC.toString(); // Track the last built module. Module wasm; for (size_t i = 0; i < root.size(); ++i) { @@ -843,11 +843,11 @@ void AssertionEmitter::emit() { e[0]->str() == Name("module")) { ModuleUtils::clearModule(wasm); std::stringstream funcNameS; - funcNameS << ASM_FUNC.c_str() << i; + funcNameS << ASM_FUNC << i; std::stringstream moduleNameS; - moduleNameS << "ret" << ASM_FUNC.c_str() << i; - Name funcName(funcNameS.str().c_str()); - asmModule = Name(moduleNameS.str().c_str()); + moduleNameS << "ret" << ASM_FUNC << i; + Name funcName(funcNameS.str()); + asmModule = Name(moduleNameS.str()); options.applyFeatures(wasm); SExpressionWasmBuilder builder(wasm, e, options.profile); emitWasm(wasm, out, flags, options.passOptions, funcName); @@ -857,13 +857,13 @@ void AssertionEmitter::emit() { std::cerr << "skipping " << e << std::endl; continue; } - Name testFuncName(IString(("check" + std::to_string(i)).c_str(), false)); + Name testFuncName("check" + std::to_string(i)); bool isInvoke = (e[0]->str() == Name("invoke")); bool isReturn = (e[0]->str() == Name("assert_return")); bool isReturnNan = (e[0]->str() == Name("assert_return_nan")); if (isInvoke) { emitInvokeFunc(wasmBuilder, wasm, e, testFuncName, asmModule); - out << testFuncName.str << "();\n"; + out << testFuncName << "();\n"; continue; } // Otherwise, this is some form of assertion. @@ -875,7 +875,7 @@ void AssertionEmitter::emit() { emitAssertTrapFunc(wasmBuilder, wasm, e, testFuncName, asmModule); } - out << "if (!" << testFuncName.str << "()) throw 'assertion failed: " << e + out << "if (!" << testFuncName << "()) throw 'assertion failed: " << e << "';\n"; } } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index ca21662e6..bbcfeda53 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1341,8 +1341,8 @@ public: void writeExtraDebugLocation(Expression* curr, Function* func, size_t id); // helpers - void writeInlineString(const char* name); - void writeEscapedName(const char* name); + void writeInlineString(std::string_view name); + void writeEscapedName(std::string_view name); void writeInlineBuffer(const char* data, size_t size); void writeData(const char* data, size_t size); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 10b84a82f..8f7418719 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -44,8 +44,6 @@ struct WasmException { }; std::ostream& operator<<(std::ostream& o, const WasmException& exn); -using namespace cashew; - // Utilities extern Name WASM, RETURN_FLOW, NONCONSTANT_FLOW; @@ -82,7 +80,7 @@ public: void clearIf(Name target) { if (breakTo == target) { - breakTo.clear(); + breakTo = Name{}; } } @@ -2513,7 +2511,7 @@ public: std::string printFunctionStack() { std::string ret = "/== (binaryen interpreter stack trace)\n"; for (int i = int(functionStack.size()) - 1; i >= 0; i--) { - ret += std::string("|: ") + functionStack[i].str + "\n"; + ret += std::string("|: ") + functionStack[i].toString() + "\n"; } ret += std::string("\\==\n"); return ret; @@ -3505,7 +3503,7 @@ public: // the delegation, don't handle it and just rethrow. if (scope->currDelegateTarget.is()) { if (scope->currDelegateTarget == curr->name) { - scope->currDelegateTarget.clear(); + scope->currDelegateTarget = Name{}; } else { throw; } diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index a7baaa54b..74f0e05e2 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -29,8 +29,6 @@ namespace wasm { -using IString = cashew::IString; - class SourceLocation { public: IString filename; @@ -75,7 +73,7 @@ public: // string methods IString str() const; - const char* c_str() const; + std::string toString() const; Element* setString(IString str__, bool dollared__, bool quoted__); Element* setMetadata(size_t line_, size_t col_, SourceLocation* startLoc_); @@ -168,6 +166,8 @@ private: UniqueNameMapper nameMapper; + int parseIndex(Element& s); + Name getFunctionName(Element& s); Name getTableName(Element& s); Name getMemoryName(Element& s); @@ -186,13 +186,15 @@ private: Type stringToType(IString str, bool allowError = false, bool prefix = false) { return stringToType(str.str, allowError, prefix); } - Type - stringToType(const char* str, bool allowError = false, bool prefix = false); + Type stringToType(std::string_view str, + bool allowError = false, + bool prefix = false); HeapType stringToHeapType(IString str, bool prefix = false) { return stringToHeapType(str.str, prefix); } - HeapType stringToHeapType(const char* str, bool prefix = false); + HeapType stringToHeapType(std::string_view str, bool prefix = false); Type elementToType(Element& s); + // TODO: Use std::string_view for this and similar functions. Type stringToLaneType(const char* str); bool isType(IString str) { return stringToType(str, true) != Type::none; } HeapType getFunctionType(Name name, Element& s); @@ -330,7 +332,8 @@ private: std::vector<NameType>& namedParams); size_t parseTypeUse(Element& s, size_t startPos, HeapType& functionType); - void stringToBinary(const char* input, size_t size, std::vector<char>& data); + void + stringToBinary(Element& s, std::string_view str, std::vector<char>& data); void parseMemory(Element& s, bool preParseImport = false); void parseData(Element& s); void parseInnerData(Element& s, Index i, std::unique_ptr<DataSegment>& seg); diff --git a/src/wasm-type.h b/src/wasm-type.h index dbdbe3d31..36c2cbede 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -21,6 +21,7 @@ #include <optional> #include <ostream> #include <string> +#include <unordered_map> #include <variant> #include <vector> diff --git a/src/wasm.h b/src/wasm.h index 65f70cef9..d20fe8bd5 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -30,6 +30,7 @@ #include <map> #include <ostream> #include <string> +#include <unordered_map> #include <vector> #include "literal.h" diff --git a/src/wasm/parsing.cpp b/src/wasm/parsing.cpp index dc0d332d9..46ec39865 100644 --- a/src/wasm/parsing.cpp +++ b/src/wasm/parsing.cpp @@ -55,7 +55,7 @@ Name UniqueNameMapper::getPrefixedName(Name prefix) { } // make sure to return a unique name not already on the stack while (1) { - Name ret = Name(prefix.str + std::to_string(otherIndex++)); + Name ret = prefix.toString() + std::to_string(otherIndex++); if (reverseLabelMapping.find(ret) == reverseLabelMapping.end()) { return ret; } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index f2698bd79..b9b8558bb 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1263,7 +1263,7 @@ void WasmBinaryWriter::writeLegacyDylinkSection() { o << U32LEB(wasm->dylinkSection->tableAlignment); o << U32LEB(wasm->dylinkSection->neededDynlibs.size()); for (auto& neededDynlib : wasm->dylinkSection->neededDynlibs) { - writeInlineString(neededDynlib.c_str()); + writeInlineString(neededDynlib.str); } finishSection(start); } @@ -1294,7 +1294,7 @@ void WasmBinaryWriter::writeDylinkSection() { startSubsection(BinaryConsts::UserSections::Subsection::DylinkNeeded); o << U32LEB(wasm->dylinkSection->neededDynlibs.size()); for (auto& neededDynlib : wasm->dylinkSection->neededDynlibs) { - writeInlineString(neededDynlib.c_str()); + writeInlineString(neededDynlib.str); } finishSubsection(substart); } @@ -1350,10 +1350,9 @@ void WasmBinaryWriter::writeData(const char* data, size_t size) { } } -void WasmBinaryWriter::writeInlineString(const char* name) { - int32_t size = strlen(name); - o << U32LEB(size); - writeData(name, size); +void WasmBinaryWriter::writeInlineString(std::string_view name) { + o << U32LEB(name.size()); + writeData(name.data(), name.size()); } static bool isHexDigit(char ch) { @@ -1365,19 +1364,17 @@ static int decodeHexNibble(char ch) { return ch <= '9' ? ch & 15 : (ch & 15) + 9; } -void WasmBinaryWriter::writeEscapedName(const char* name) { - assert(name); - if (!strpbrk(name, "\\")) { +void WasmBinaryWriter::writeEscapedName(std::string_view name) { + if (name.find('\\') == std::string_view::npos) { writeInlineString(name); return; } // decode escaped by escapeName (see below) function names std::string unescaped; - int32_t size = strlen(name); - for (int32_t i = 0; i < size;) { + for (size_t i = 0; i < name.size();) { char ch = name[i++]; // support only `\xx` escapes; ignore invalid or unsupported escapes - if (ch != '\\' || i + 1 >= size || !isHexDigit(name[i]) || + if (ch != '\\' || i + 1 >= name.size() || !isHexDigit(name[i]) || !isHexDigit(name[i + 1])) { unescaped.push_back(ch); continue; @@ -1386,7 +1383,7 @@ void WasmBinaryWriter::writeEscapedName(const char* name) { char((decodeHexNibble(name[i]) << 4) | decodeHexNibble(name[i + 1]))); i += 2; } - writeInlineString(unescaped.c_str()); + writeInlineString({unescaped.data(), unescaped.size()}); } void WasmBinaryWriter::writeInlineBuffer(const char* data, size_t size) { @@ -2357,8 +2354,8 @@ void WasmBinaryBuilder::readImports() { functionTypes.push_back(getTypeByIndex(index)); auto type = getTypeByIndex(index); if (!type.isSignature()) { - throwError(std::string("Imported function ") + module.str + '.' + - base.str + + throwError(std::string("Imported function ") + module.toString() + + '.' + base.toString() + "'s type must be a signature. Given: " + type.toString()); } auto curr = builder.makeFunction(name, type, {}); @@ -3268,24 +3265,25 @@ static char formatNibble(int nibble) { Name WasmBinaryBuilder::escape(Name name) { bool allIdChars = true; - for (const char* p = name.str; allIdChars && *p; p++) { - allIdChars = isIdChar(*p); + for (char c : name.str) { + if (!(allIdChars = isIdChar(c))) { + break; + } } if (allIdChars) { return name; } // encode name, if at least one non-idchar (per WebAssembly spec) was found std::string escaped; - for (const char* p = name.str; *p; p++) { - char ch = *p; - if (isIdChar(ch)) { - escaped.push_back(ch); + for (char c : name.str) { + if (isIdChar(c)) { + escaped.push_back(c); continue; } // replace non-idchar with `\xx` escape escaped.push_back('\\'); - escaped.push_back(formatNibble(ch >> 4)); - escaped.push_back(formatNibble(ch & 15)); + escaped.push_back(formatNibble(c >> 4)); + escaped.push_back(formatNibble(c & 15)); } return escaped; } @@ -6839,7 +6837,7 @@ void WasmBinaryBuilder::visitRethrow(Rethrow* curr) { // This special target is valid only for delegates if (curr->target == DELEGATE_CALLER_TARGET) { throwError(std::string("rethrow target cannot use internal name ") + - DELEGATE_CALLER_TARGET.str); + DELEGATE_CALLER_TARGET.toString()); } curr->finalize(); } diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 172ef15b6..64d7a21a2 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -54,7 +54,9 @@ static Name STRUCT("struct"), FIELD("field"), ARRAY("array"), ARRAY_SUBTYPE("array_subtype"), EXTENDS("extends"), REC("rec"), I8("i8"), I16("i16"), DECLARE("declare"), ITEM("item"), OFFSET("offset"); -static Address getAddress(const Element* s) { return atoll(s->c_str()); } +static Address getAddress(const Element* s) { + return std::stoll(s->toString()); +} static void checkAddress(Address a, const char* errorText, const Element* errorElem) { @@ -95,11 +97,11 @@ IString Element::str() const { return str_; } -const char* Element::c_str() const { +std::string Element::toString() const { if (!isStr()) { throw ParseException("expected string", line, col); } - return str_.str; + return str_.toString(); } Element* Element::setString(IString str__, bool dollared__, bool quoted__) { @@ -356,11 +358,8 @@ SExpressionWasmBuilder::SExpressionWasmBuilder(Module& wasm, if (i < module.size() && module[i]->isStr()) { // these s-expressions contain a binary module, actually std::vector<char> data; - while (i < module.size()) { - auto str = module[i++]->c_str(); - if (auto size = strlen(str)) { - stringToBinary(str, size, data); - } + for (; i < module.size(); ++i) { + stringToBinary(*module[i], module[i]->str().str, data); } // TODO: support applying features here WasmBinaryBuilder binaryBuilder(wasm, FeatureSet::MVP, data); @@ -474,12 +473,20 @@ void SExpressionWasmBuilder::parseModuleElement(Element& curr) { throw ParseException("unknown module element", curr.line, curr.col); } +int SExpressionWasmBuilder::parseIndex(Element& s) { + try { + return std::stoi(s.toString()); + } catch (...) { + throw ParseException("expected integer", s.line, s.col); + } +} + Name SExpressionWasmBuilder::getFunctionName(Element& s) { if (s.dollared()) { return s.str(); } else { // index - size_t offset = atoi(s.str().c_str()); + size_t offset = parseIndex(s); if (offset >= functionNames.size()) { throw ParseException( "unknown function in getFunctionName", s.line, s.col); @@ -493,7 +500,7 @@ Name SExpressionWasmBuilder::getTableName(Element& s) { return s.str(); } else { // index - size_t offset = atoi(s.str().c_str()); + size_t offset = parseIndex(s); if (offset >= tableNames.size()) { throw ParseException("unknown table in getTableName", s.line, s.col); } @@ -521,7 +528,7 @@ Name SExpressionWasmBuilder::getMemoryName(Element& s) { return s.str(); } else { // index - size_t offset = atoi(s.str().c_str()); + size_t offset = parseIndex(s); return getMemoryNameAtIdx(offset); } } @@ -531,7 +538,7 @@ Name SExpressionWasmBuilder::getGlobalName(Element& s) { return s.str(); } else { // index - size_t offset = atoi(s.str().c_str()); + size_t offset = parseIndex(s); if (offset >= globalNames.size()) { throw ParseException("unknown global in getGlobalName", s.line, s.col); } @@ -544,7 +551,7 @@ Name SExpressionWasmBuilder::getTagName(Element& s) { return s.str(); } else { // index - size_t offset = atoi(s.str().c_str()); + size_t offset = parseIndex(s); if (offset >= tagNames.size()) { throw ParseException("unknown tag in getTagName", s.line, s.col); } @@ -738,7 +745,7 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { size_t numTypes = 0; forEachType([&](Element& elem, size_t) { if (elem[1]->dollared()) { - std::string name = elem[1]->c_str(); + std::string name = elem[1]->toString(); if (!typeIndices.insert({name, numTypes}).second) { throw ParseException("duplicate function type", elem.line, elem.col); } @@ -769,23 +776,23 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { auto nullable = elem[1]->isStr() && *elem[1] == NULL_ ? Nullable : NonNullable; auto& referent = nullable ? *elem[2] : *elem[1]; - const char* name = referent.c_str(); + auto name = referent.toString(); if (referent.dollared()) { return builder.getTempRefType(builder[typeIndices[name]], nullable); } else if (String::isNumber(name)) { - size_t index = atoi(name); + size_t index = parseIndex(referent); if (index >= numTypes) { throw ParseException("invalid type index", elem.line, elem.col); } return builder.getTempRefType(builder[index], nullable); } else { - return Type(stringToHeapType(name), nullable); + return Type(stringToHeapType(referent.str()), nullable); } }; auto parseValType = [&](Element& elem) { if (elem.isStr()) { - return stringToType(elem.c_str()); + return stringToType(elem.str()); } else if (*elem[0] == REF) { return parseRefType(elem); } else { @@ -921,7 +928,7 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { super = extends[1]; } if (super) { - auto it = typeIndices.find(super->c_str()); + auto it = typeIndices.find(super->toString()); if (it == typeIndices.end()) { throw ParseException("unknown supertype", super->line, super->col); } @@ -1139,135 +1146,124 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) { nameMapper.clear(); } -Type SExpressionWasmBuilder::stringToType(const char* str, +Type SExpressionWasmBuilder::stringToType(std::string_view str, bool allowError, bool prefix) { - if (str[0] == 'i') { - if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0)) { - return Type::i32; - } - if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0)) { - return Type::i64; - } - } - if (str[0] == 'f') { - if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0)) { - return Type::f32; + if (str.size() >= 3) { + if (str[0] == 'i') { + if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0)) { + return Type::i32; + } + if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0)) { + return Type::i64; + } } - if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0)) { - return Type::f64; + if (str[0] == 'f') { + if (str[1] == '3' && str[2] == '2' && (prefix || str[3] == 0)) { + return Type::f32; + } + if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0)) { + return Type::f64; + } } } - if (str[0] == 'v') { - if (str[1] == '1' && str[2] == '2' && str[3] == '8' && - (prefix || str[4] == 0)) { - return Type::v128; + if (str.size() >= 4) { + if (str[0] == 'v') { + if (str[1] == '1' && str[2] == '2' && str[3] == '8' && + (prefix || str[4] == 0)) { + return Type::v128; + } } } - if (strncmp(str, "funcref", 7) == 0 && (prefix || str[7] == 0)) { + if (str.substr(0, 7) == "funcref" && (prefix || str.size() == 7)) { return Type(HeapType::func, Nullable); } - if (strncmp(str, "externref", 9) == 0 && (prefix || str[9] == 0)) { + if (str.substr(0, 9) == "externref" && (prefix || str.size() == 9)) { return Type(HeapType::ext, Nullable); } - if (strncmp(str, "anyref", 6) == 0 && (prefix || str[6] == 0)) { + if (str.substr(0, 6) == "anyref" && (prefix || str.size() == 6)) { return Type(HeapType::any, Nullable); } - if (strncmp(str, "eqref", 5) == 0 && (prefix || str[5] == 0)) { + if (str.substr(0, 5) == "eqref" && (prefix || str.size() == 5)) { return Type(HeapType::eq, Nullable); } - if (strncmp(str, "i31ref", 6) == 0 && (prefix || str[6] == 0)) { + if (str.substr(0, 6) == "i31ref" && (prefix || str.size() == 6)) { return Type(HeapType::i31, Nullable); } - if (strncmp(str, "dataref", 7) == 0 && (prefix || str[7] == 0)) { + if (str.substr(0, 7) == "dataref" && (prefix || str.size() == 7)) { return Type(HeapType::data, Nullable); } - if (strncmp(str, "stringref", 9) == 0 && (prefix || str[9] == 0)) { + if (str.substr(0, 9) == "stringref" && (prefix || str.size() == 9)) { return Type(HeapType::string, Nullable); } - if (strncmp(str, "stringview_wtf8", 15) == 0 && (prefix || str[15] == 0)) { + if (str.substr(0, 15) == "stringview_wtf8" && (prefix || str.size() == 15)) { return Type(HeapType::stringview_wtf8, Nullable); } - if (strncmp(str, "stringview_wtf16", 16) == 0 && (prefix || str[16] == 0)) { + if (str.substr(0, 16) == "stringview_wtf16" && (prefix || str.size() == 16)) { return Type(HeapType::stringview_wtf16, Nullable); } - if (strncmp(str, "stringview_iter", 15) == 0 && (prefix || str[15] == 0)) { + if (str.substr(0, 15) == "stringview_iter" && (prefix || str.size() == 15)) { return Type(HeapType::stringview_iter, Nullable); } - if (strncmp(str, "nullref", 7) == 0 && (prefix || str[7] == 0)) { + if (str.substr(0, 7) == "nullref" && (prefix || str.size() == 7)) { return Type(HeapType::none, Nullable); } - if (strncmp(str, "nullexternref", 13) == 0 && (prefix || str[13] == 0)) { + if (str.substr(0, 13) == "nullexternref" && (prefix || str.size() == 13)) { return Type(HeapType::noext, Nullable); } - if (strncmp(str, "nullfuncref", 11) == 0 && (prefix || str[11] == 0)) { + if (str.substr(0, 11) == "nullfuncref" && (prefix || str.size() == 11)) { return Type(HeapType::nofunc, Nullable); } if (allowError) { return Type::none; } - throw ParseException(std::string("invalid wasm type: ") + str); + throw ParseException(std::string("invalid wasm type: ") + + std::string(str.data(), str.size())); } -HeapType SExpressionWasmBuilder::stringToHeapType(const char* str, +HeapType SExpressionWasmBuilder::stringToHeapType(std::string_view str, bool prefix) { - if (str[0] == 'f') { - if (str[1] == 'u' && str[2] == 'n' && str[3] == 'c' && - (prefix || str[4] == 0)) { - return HeapType::func; - } + if (str.substr(0, 4) == "func" && (prefix || str.size() == 4)) { + return HeapType::func; } - if (str[0] == 'e') { - if (str[1] == 'q' && (prefix || str[2] == 0)) { - return HeapType::eq; - } - if (str[1] == 'x' && str[2] == 't' && str[3] == 'e' && str[4] == 'r' && - str[5] == 'n' && (prefix || str[6] == 0)) { - return HeapType::ext; - } + if (str.substr(0, 2) == "eq" && (prefix || str.size() == 2)) { + return HeapType::eq; } - if (str[0] == 'a') { - if (str[1] == 'n' && str[2] == 'y' && (prefix || str[3] == 0)) { - return HeapType::any; - } + if (str.substr(0, 6) == "extern" && (prefix || str.size() == 6)) { + return HeapType::ext; } - if (str[0] == 'i') { - if (str[1] == '3' && str[2] == '1' && (prefix || str[3] == 0)) { - return HeapType::i31; - } + if (str.substr(0, 3) == "any" && (prefix || str.size() == 3)) { + return HeapType::any; } - if (str[0] == 'd') { - if (str[1] == 'a' && str[2] == 't' && str[3] == 'a' && - (prefix || str[4] == 0)) { - return HeapType::data; - } + if (str.substr(0, 3) == "i31" && (prefix || str.size() == 3)) { + return HeapType::i31; } - if (str[0] == 's') { - if (strncmp(str, "string", 6) == 0 && (prefix || str[6] == 0)) { - return HeapType::string; - } - if (strncmp(str, "stringview_wtf8", 15) == 0 && (prefix || str[15] == 0)) { - return HeapType::stringview_wtf8; - } - if (strncmp(str, "stringview_wtf16", 16) == 0 && (prefix || str[16] == 0)) { - return HeapType::stringview_wtf16; - } - if (strncmp(str, "stringview_iter", 15) == 0 && (prefix || str[15] == 0)) { - return HeapType::stringview_iter; - } + if (str.substr(0, 4) == "data" && (prefix || str.size() == 4)) { + return HeapType::data; } - if (str[0] == 'n') { - if (strncmp(str, "none", 4) == 0 && (prefix || str[4] == 0)) { - return HeapType::none; - } - if (strncmp(str, "noextern", 8) == 0 && (prefix || str[8] == 0)) { - return HeapType::noext; - } - if (strncmp(str, "nofunc", 6) == 0 && (prefix || str[6] == 0)) { - return HeapType::nofunc; - } + if (str.substr(0, 6) == "string" && (prefix || str.size() == 6)) { + return HeapType::string; + } + if (str.substr(0, 15) == "stringview_wtf8" && (prefix || str.size() == 15)) { + return HeapType::stringview_wtf8; + } + if (str.substr(0, 16) == "stringview_wtf16" && (prefix || str.size() == 16)) { + return HeapType::stringview_wtf16; } - throw ParseException(std::string("invalid wasm heap type: ") + str); + if (str.substr(0, 15) == "stringview_iter" && (prefix || str.size() == 15)) { + return HeapType::stringview_iter; + } + if (str.substr(0, 4) == "none" && (prefix || str.size() == 4)) { + return HeapType::none; + } + if (str.substr(0, 8) == "noextern" && (prefix || str.size() == 8)) { + return HeapType::noext; + } + if (str.substr(0, 6) == "nofunc" && (prefix || str.size() == 6)) { + return HeapType::nofunc; + } + throw ParseException(std::string("invalid wasm heap type: ") + + std::string(str.data(), str.size())); } Type SExpressionWasmBuilder::elementToType(Element& s) { @@ -1345,7 +1341,7 @@ SExpressionWasmBuilder::getDebugLocation(const SourceLocation& loc) { auto iter = debugInfoFileIndices.find(file); if (iter == debugInfoFileIndices.end()) { Index index = debugInfoFileNames.size(); - debugInfoFileNames.push_back(file.c_str()); + debugInfoFileNames.push_back(file.toString()); debugInfoFileIndices[file] = index; } uint32_t fileIndex = debugInfoFileIndices[file]; @@ -1457,7 +1453,7 @@ Index SExpressionWasmBuilder::getLocalIndex(Element& s) { return currFunction->getLocalIndex(ret); } // this is a numeric index - Index ret = atoi(s.c_str()); + Index ret = parseIndex(s); if (ret >= currFunction->getNumLocals()) { throw ParseException("bad local index", s.line, s.col); } @@ -1620,7 +1616,7 @@ Expression* SExpressionWasmBuilder::makeThenOrElse(Element& s) { } static Expression* parseConst(IString s, Type type, MixedArena& allocator) { - const char* str = s.str; + const char* str = s.str.data(); auto ret = allocator.alloc<Const>(); ret->type = type; if (type.isFloat()) { @@ -1635,7 +1631,6 @@ static Expression* parseConst(IString s, Type type, MixedArena& allocator) { default: return nullptr; } - // std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; return ret; } if (s == NEG_INFINITY) { @@ -1649,7 +1644,6 @@ static Expression* parseConst(IString s, Type type, MixedArena& allocator) { default: return nullptr; } - // std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; return ret; } if (s == _NAN) { @@ -1663,7 +1657,6 @@ static Expression* parseConst(IString s, Type type, MixedArena& allocator) { default: return nullptr; } - // std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; return ret; } bool negative = str[0] == '-'; @@ -1813,7 +1806,6 @@ static Expression* parseConst(IString s, Type type, MixedArena& allocator) { if (ret->value.type != type) { throw ParseException("parsed type does not match expected type"); } - // std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; return ret; } @@ -1842,7 +1834,7 @@ Expression* SExpressionWasmBuilder::makeConst(Element& s, Type type) { } auto ret = allocator.alloc<Const>(); - Type lane_t = stringToLaneType(s[1]->str().str); + Type lane_t = stringToLaneType(s[1]->str().str.data()); size_t lanes = s.size() - 2; switch (lanes) { case 2: { @@ -1918,7 +1910,7 @@ static size_t parseMemAttributes(size_t i, align = fallbackAlign; // Parse "align=X" and "offset=X" arguments, bailing out on anything else. while (!s[i]->isList()) { - const char* str = s[i]->c_str(); + const char* str = s[i]->str().str.data(); if (strncmp(str, "align", 5) != 0 && strncmp(str, "offset", 6) != 0) { return i; } @@ -1957,7 +1949,7 @@ static size_t parseMemAttributes(size_t i, } static const char* findMemExtra(const Element& s, size_t skip, bool isAtomic) { - auto* str = s.c_str(); + auto* str = s.str().str.data(); auto size = strlen(str); auto* ret = strchr(str, '.'); if (!ret) { @@ -1977,8 +1969,8 @@ bool SExpressionWasmBuilder::hasMemoryIdx(Element& s, Index defaultSize, Index i) { if (s.size() > defaultSize && !s[i]->isList() && - strncmp(s[i]->c_str(), "align", 5) != 0 && - strncmp(s[i]->c_str(), "offset", 6) != 0) { + strncmp(s[i]->str().str.data(), "align", 5) != 0 && + strncmp(s[i]->str().str.data(), "offset", 6) != 0) { return true; } return false; @@ -2190,7 +2182,7 @@ Expression* SExpressionWasmBuilder::makeAtomicFence(Element& s) { } static uint8_t parseLaneIndex(const Element* s, size_t lanes) { - const char* str = s->c_str(); + const char* str = s->str().str.data(); char* end; auto n = static_cast<unsigned long long>(strtoll(str, &end, 10)); if (end == str || *end != '\0') { @@ -2360,7 +2352,7 @@ Expression* SExpressionWasmBuilder::makeMemoryInit(Element& s) { memory = getMemoryNameAtIdx(0); } ret->memory = memory; - ret->segment = atoi(s[i++]->str().c_str()); + ret->segment = parseIndex(*s[i++]); ret->dest = parseExpression(s[i++]); ret->offset = parseExpression(s[i++]); ret->size = parseExpression(s[i]); @@ -2370,7 +2362,7 @@ Expression* SExpressionWasmBuilder::makeMemoryInit(Element& s) { Expression* SExpressionWasmBuilder::makeDataDrop(Element& s) { auto ret = allocator.alloc<DataDrop>(); - ret->segment = atoi(s[1]->str().c_str()); + ret->segment = parseIndex(*s[1]); ret->finalize(); return ret; } @@ -2552,7 +2544,7 @@ Name SExpressionWasmBuilder::getLabel(Element& s, LabelType labelType) { // offset, break to nth outside label uint64_t offset; try { - offset = std::stoll(s.c_str(), nullptr, 0); + offset = std::stoll(s.toString(), nullptr, 0); } catch (std::invalid_argument&) { throw ParseException("invalid break offset", s.line, s.col); } catch (std::out_of_range&) { @@ -2836,7 +2828,7 @@ Expression* SExpressionWasmBuilder::makeTupleMake(Element& s) { Expression* SExpressionWasmBuilder::makeTupleExtract(Element& s) { auto ret = allocator.alloc<TupleExtract>(); - ret->index = atoi(s[1]->str().c_str()); + ret->index = parseIndex(*s[1]); ret->tuple = parseExpression(s[2]); if (ret->tuple->type != Type::unreachable && ret->index >= ret->tuple->type.size()) { @@ -2943,7 +2935,7 @@ Expression* SExpressionWasmBuilder::makeStructNewStatic(Element& s, Index SExpressionWasmBuilder::getStructIndex(Element& type, Element& field) { if (field.dollared()) { auto name = field.str(); - auto index = typeIndices[type.str().str]; + auto index = typeIndices[type.toString()]; auto struct_ = types[index].getStruct(); auto& fields = struct_.fields; const auto& names = fieldNames[index]; @@ -2956,7 +2948,7 @@ Index SExpressionWasmBuilder::getStructIndex(Element& type, Element& field) { throw ParseException("bad struct field name", field.line, field.col); } // this is a numeric index - return atoi(field.c_str()); + return parseIndex(field); } Expression* SExpressionWasmBuilder::makeStructGet(Element& s, bool signed_) { @@ -3055,12 +3047,12 @@ Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) { size_t i = 1; Expression* length = nullptr; if (op == StringNewWTF8) { - const char* str = s[i++]->c_str(); - if (strncmp(str, "utf8", 4) == 0) { + std::string_view str = s[i++]->str().str; + if (str == "utf8") { op = StringNewUTF8; - } else if (strncmp(str, "wtf8", 4) == 0) { + } else if (str == "wtf8") { op = StringNewWTF8; - } else if (strncmp(str, "replace", 7) == 0) { + } else if (str == "replace") { op = StringNewReplace; } else { throw ParseException("bad string.new op", s.line, s.col); @@ -3071,12 +3063,12 @@ Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) { length = parseExpression(s[i + 1]); return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length); } else if (op == StringNewWTF8Array) { - const char* str = s[i++]->c_str(); - if (strncmp(str, "utf8", 4) == 0) { + std::string_view str = s[i++]->str().str; + if (str == "utf8") { op = StringNewUTF8Array; - } else if (strncmp(str, "wtf8", 4) == 0) { + } else if (str == "wtf8") { op = StringNewWTF8Array; - } else if (strncmp(str, "replace", 7) == 0) { + } else if (str == "replace") { op = StringNewReplaceArray; } else { throw ParseException("bad string.new op", s.line, s.col); @@ -3094,16 +3086,9 @@ Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) { } Expression* SExpressionWasmBuilder::makeStringConst(Element& s) { - Name rawStr = s[1]->str(); - size_t len = rawStr.size(); std::vector<char> data; - stringToBinary(rawStr.c_str(), len, data); - data.push_back('\0'); - Name str = data.empty() ? "" : &data[0]; - if (str.size() != data.size() - 1) { - throw ParseException( - "zero bytes not yet supported in string constants", s.line, s.col); - } + stringToBinary(*s[1], s[1]->str().str, data); + Name str = std::string_view(data.data(), data.size()); return Builder(wasm).makeStringConst(str); } @@ -3111,10 +3096,10 @@ Expression* SExpressionWasmBuilder::makeStringMeasure(Element& s, StringMeasureOp op) { size_t i = 1; if (op == StringMeasureWTF8) { - const char* str = s[i++]->c_str(); - if (strncmp(str, "utf8", 4) == 0) { + std::string_view str = s[i++]->str().str; + if (str == "utf8") { op = StringMeasureUTF8; - } else if (strncmp(str, "wtf8", 4) == 0) { + } else if (str == "wtf8") { op = StringMeasureWTF8; } else { throw ParseException("bad string.measure op", s.line, s.col); @@ -3128,19 +3113,19 @@ Expression* SExpressionWasmBuilder::makeStringEncode(Element& s, size_t i = 1; Expression* start = nullptr; if (op == StringEncodeWTF8) { - const char* str = s[i++]->c_str(); - if (strncmp(str, "utf8", 4) == 0) { + std::string_view str = s[i++]->str().str; + if (str == "utf8") { op = StringEncodeUTF8; - } else if (strncmp(str, "wtf8", 4) == 0) { + } else if (str == "wtf8") { op = StringEncodeWTF8; } else { throw ParseException("bad string.new op", s.line, s.col); } } else if (op == StringEncodeWTF8Array) { - const char* str = s[i++]->c_str(); - if (strncmp(str, "utf8", 4) == 0) { + std::string_view str = s[i++]->str().str; + if (str == "utf8") { op = StringEncodeUTF8Array; - } else if (strncmp(str, "wtf8", 4) == 0) { + } else if (str == "wtf8") { op = StringEncodeWTF8Array; } else { throw ParseException("bad string.new op", s.line, s.col); @@ -3201,17 +3186,18 @@ Expression* SExpressionWasmBuilder::makeStringSliceIter(Element& s) { // converts an s-expression string representing binary data into an output // sequence of raw bytes this appends to data, which may already contain // content. -void SExpressionWasmBuilder::stringToBinary(const char* input, - size_t size, +void SExpressionWasmBuilder::stringToBinary(Element& s, + std::string_view str, std::vector<char>& data) { auto originalSize = data.size(); - data.resize(originalSize + size); + data.resize(originalSize + str.size()); char* write = data.data() + originalSize; - while (1) { - if (input[0] == 0) { - break; - } + const char* end = str.data() + str.size(); + for (const char* input = str.data(); input < end;) { if (input[0] == '\\') { + if (input + 1 >= end) { + throw ParseException("Unterminated escape sequence", s.line, s.col); + } if (input[1] == 't') { *write++ = '\t'; input += 2; @@ -3237,6 +3223,9 @@ void SExpressionWasmBuilder::stringToBinary(const char* input, input += 2; continue; } else { + if (input + 2 >= end) { + throw ParseException("Unterminated escape sequence", s.line, s.col); + } *write++ = (char)(unhex(input[1]) * 16 + unhex(input[2])); input += 3; continue; @@ -3361,7 +3350,7 @@ void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) { checkAddress(offsetValue, "excessive memory offset", offsetElem); } } - const char* input = curr[j]->c_str(); + std::string_view input = curr[j]->str().str; auto* offset = allocator.alloc<Const>(); if (memory->is64()) { offset->type = Type::i64; @@ -3370,9 +3359,9 @@ void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) { offset->type = Type::i32; offset->value = Literal(int32_t(offsetValue)); } - if (auto size = strlen(input)) { + if (input.size()) { std::vector<char> data; - stringToBinary(input, size, data); + stringToBinary(*curr[j], input, data); auto segment = Builder::makeDataSegment(Name::fromInt(dataCounter++), memory->name, false, @@ -3437,10 +3426,8 @@ void SExpressionWasmBuilder::parseInnerData(Element& s, std::unique_ptr<DataSegment>& seg) { std::vector<char> data; while (i < s.size()) { - const char* input = s[i++]->c_str(); - if (auto size = strlen(input)) { - stringToBinary(input, size, data); - } + std::string_view input = s[i++]->str().str; + stringToBinary(s, input, data); } seg->data.resize(data.size()); std::copy_n(data.data(), data.size(), seg->data.begin()); @@ -3736,12 +3723,12 @@ void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) { bool hasExplicitLimit = false; - if (s[i]->isStr() && String::isNumber(s[i]->c_str())) { - table->initial = atoi(s[i++]->c_str()); + if (s[i]->isStr() && String::isNumber(s[i]->toString())) { + table->initial = parseIndex(*s[i++]); hasExplicitLimit = true; } - if (s[i]->isStr() && String::isNumber(s[i]->c_str())) { - table->max = atoi(s[i++]->c_str()); + if (s[i]->isStr() && String::isNumber(s[i]->toString())) { + table->max = parseIndex(*s[i++]); } table->type = elementToType(*s[i++]); @@ -3905,7 +3892,7 @@ HeapType SExpressionWasmBuilder::parseHeapType(Element& s) { if (s.isStr()) { // It's a string. if (s.dollared()) { - auto it = typeIndices.find(s.str().str); + auto it = typeIndices.find(s.toString()); if (it == typeIndices.end()) { throw ParseException("unknown dollared function type", s.line, s.col); } @@ -3913,15 +3900,15 @@ HeapType SExpressionWasmBuilder::parseHeapType(Element& s) { } else { // It may be a numerical index, or it may be a built-in type name like // "i31". - auto* str = s.str().c_str(); + auto str = s.toString(); if (String::isNumber(str)) { - size_t offset = atoi(str); + size_t offset = parseIndex(s); if (offset >= types.size()) { throw ParseException("unknown indexed function type", s.line, s.col); } return types[offset]; } - return stringToHeapType(str, /* prefix = */ false); + return stringToHeapType(s.str(), /* prefix = */ false); } } throw ParseException("invalid heap type", s.line, s.col); diff --git a/src/wasm2js.h b/src/wasm2js.h index ceae32eb9..2ae22de09 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -230,7 +230,7 @@ public: // First up check our cached of mangled names to avoid doing extra work // below auto& map = wasmNameToMangledName[(int)scope]; - auto it = map.find(name.c_str()); + auto it = map.find(name.str.data()); if (it != map.end()) { return it->second; } @@ -249,7 +249,7 @@ public: IString ret; for (int i = 0;; i++) { std::ostringstream out; - out << name.c_str(); + out << name; if (i > 0) { out << "_" << i; } @@ -276,7 +276,7 @@ public: } // We found a good name, use it. scopeMangledNames.insert(ret); - map[name.c_str()] = ret; + map[name.str.data()] = ret; return ret; } } @@ -586,7 +586,7 @@ void Wasm2JSBuilder::addBasics(Ref ast, Module* wasm) { } static bool needsQuoting(Name name) { - auto mangled = asmangle(name.str); + auto mangled = asmangle(name.toString()); return mangled != name.str; } @@ -717,7 +717,7 @@ void Wasm2JSBuilder::addTable(Ref ast, Module* wasm) { } else if (auto* get = offset->dynCast<GlobalGet>()) { index = ValueBuilder::makeBinary( ValueBuilder::makeName( - stringToIString(asmangle(get->name.str))), + stringToIString(asmangle(get->name.toString()))), PLUS, ValueBuilder::makeNum(i)); } else { @@ -807,7 +807,7 @@ void Wasm2JSBuilder::addExports(Ref ast, Module* wasm) { // setter { std::ostringstream buffer; - buffer << '_' << identName.c_str(); + buffer << '_' << identName; auto setterParam = stringToIString(buffer.str()); auto block = ValueBuilder::makeBlock(); @@ -2615,8 +2615,8 @@ void Wasm2JSGlue::emitPreES6() { } baseModuleMap[base] = module; if (seenModules.count(module) == 0) { - out << "import * as " << asmangle(module.str) << " from '" << module.str - << "';\n"; + out << "import * as " << asmangle(module.toString()) << " from '" + << module << "';\n"; seenModules.insert(module); } }; @@ -2678,8 +2678,8 @@ void Wasm2JSGlue::emitPostES6() { if (seenModules.count(import->module) > 0) { return; } - out << " \"" << import->module << "\": " << asmangle(import->module.str) - << ",\n"; + out << " \"" << import->module + << "\": " << asmangle(import->module.toString()) << ",\n"; seenModules.insert(import->module); }); @@ -2690,7 +2690,7 @@ void Wasm2JSGlue::emitPostES6() { return; } out << " \"" << import->module << "\": {\n"; - out << " " << asmangle(import->base.str) << ": { buffer : mem" + out << " " << asmangle(import->base.toString()) << ": { buffer : mem" << moduleName.str << " }\n"; out << " },\n"; }); @@ -2704,8 +2704,8 @@ void Wasm2JSGlue::emitPostES6() { if (seenModules.count(import->module) > 0) { return; } - out << " \"" << import->module << "\": " << asmangle(import->module.str) - << ",\n"; + out << " \"" << import->module + << "\": " << asmangle(import->module.toString()) << ",\n"; seenModules.insert(import->module); }); @@ -2729,15 +2729,15 @@ void Wasm2JSGlue::emitPostES6() { continue; } std::ostringstream export_name; - for (auto* ptr = exp->name.str; *ptr; ptr++) { - if (*ptr == '-') { + for (char c : exp->name.str) { + if (c == '-') { export_name << '_'; } else { - export_name << *ptr; + export_name << c; } } - out << "export var " << asmangle(exp->name.str) << " = ret" - << moduleName.str << "." << asmangle(exp->name.str) << ";\n"; + out << "export var " << asmangle(exp->name.toString()) << " = ret" + << moduleName << "." << asmangle(exp->name.toString()) << ";\n"; } } @@ -2816,8 +2816,8 @@ void Wasm2JSGlue::emitMemory() { if (auto* get = segment.offset->dynCast<GlobalGet>()) { auto internalName = get->name; auto importedGlobal = wasm.getGlobal(internalName); - return std::string("imports['") + importedGlobal->module.str + "']['" + - importedGlobal->base.str + "']"; + return std::string("imports['") + importedGlobal->module.toString() + + "']['" + importedGlobal->base.toString() + "']"; } Fatal() << "non-constant offsets aren't supported yet\n"; }; |