|  | /* | 
|  | * Copyright (C) 2016 Apple Inc. All rights reserved. | 
|  | * | 
|  | * Redistribution and use in source and binary forms, with or without | 
|  | * modification, are permitted provided that the following conditions | 
|  | * are met: | 
|  | * 1. Redistributions of source code must retain the above copyright | 
|  | *    notice, this list of conditions and the following disclaimer. | 
|  | * 2. Redistributions in binary form must reproduce the above copyright | 
|  | *    notice, this list of conditions and the following disclaimer in the | 
|  | *    documentation and/or other materials provided with the distribution. | 
|  | * | 
|  | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 
|  | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
|  | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 
|  | * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR | 
|  | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 
|  | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
|  | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 
|  | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 
|  | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | */ | 
|  |  | 
|  | #pragma once | 
|  |  | 
|  | #if ENABLE(WEBASSEMBLY) | 
|  |  | 
|  | #if !ASSERT_ENABLED | 
|  | IGNORE_RETURN_TYPE_WARNINGS_BEGIN | 
|  | #endif | 
|  |  | 
|  | namespace JSC { namespace Wasm { | 
|  |  | 
|  | #define FOR_EACH_KNOWN_WASM_SECTION(macro) \ | 
|  | macro(Type,       1, "Function signature declarations") \ | 
|  | macro(Import,     2, "Import declarations") \ | 
|  | macro(Function,   3, "Function declarations") \ | 
|  | macro(Table,      4, "Indirect function table and other tables") \ | 
|  | macro(Memory,     5, "Memory attributes") \ | 
|  | macro(Global,     6, "Global declarations") \ | 
|  | macro(Export,     7, "Exports") \ | 
|  | macro(Start,      8, "Start function declaration") \ | 
|  | macro(Element,    9, "Elements section") \ | 
|  | macro(Code,      10, "Function bodies (code)") \ | 
|  | macro(Data,      11, "Data segments") \ | 
|  | macro(DataCount, 12, "Data count") \ | 
|  | macro(Exception, 13, "Exception declarations") \ | 
|  |  | 
|  | enum class Section : uint8_t { | 
|  | // It's important that Begin is less than every other section number and that Custom is greater. | 
|  | // This only works because section numbers are currently monotonically increasing. | 
|  | // Also, Begin is not a real section but is used as a marker for validating the ordering | 
|  | // of sections. | 
|  | Begin = 0, | 
|  | #define DEFINE_WASM_SECTION_ENUM(NAME, ID, DESCRIPTION) NAME = ID, | 
|  | FOR_EACH_KNOWN_WASM_SECTION(DEFINE_WASM_SECTION_ENUM) | 
|  | #undef DEFINE_WASM_SECTION_ENUM | 
|  | Custom | 
|  | }; | 
|  | static_assert(static_cast<uint8_t>(Section::Begin) < static_cast<uint8_t>(Section::Type), "Begin should come before the first known section."); | 
|  |  | 
|  | template<typename Int> | 
|  | inline bool isKnownSection(Int section) | 
|  | { | 
|  | switch (section) { | 
|  | #define VALIDATE_SECTION(NAME, ID, DESCRIPTION) case static_cast<Int>(Section::NAME): return true; | 
|  | FOR_EACH_KNOWN_WASM_SECTION(VALIDATE_SECTION) | 
|  | #undef VALIDATE_SECTION | 
|  | default: | 
|  | return false; | 
|  | } | 
|  | } | 
|  |  | 
|  | inline bool decodeSection(uint8_t sectionByte, Section& section) | 
|  | { | 
|  | section = Section::Custom; | 
|  | if (!sectionByte) | 
|  | return true; | 
|  |  | 
|  | if (!isKnownSection(sectionByte)) | 
|  | return false; | 
|  |  | 
|  | section = static_cast<Section>(sectionByte); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | inline bool validateOrder(Section previousKnown, Section next) | 
|  | { | 
|  | ASSERT(isKnownSection(previousKnown) || previousKnown == Section::Begin); | 
|  | if (previousKnown == Section::DataCount && next == Section::Code) | 
|  | return true; | 
|  | if (previousKnown == Section::Exception) | 
|  | return next >= Section::Global; | 
|  | if (next == Section::Exception) | 
|  | return previousKnown <= Section::Memory; | 
|  | return static_cast<uint8_t>(previousKnown) < static_cast<uint8_t>(next); | 
|  | } | 
|  |  | 
|  | inline const char* makeString(Section section) | 
|  | { | 
|  | switch (section) { | 
|  | case Section::Begin: | 
|  | return "Begin"; | 
|  | case Section::Custom: | 
|  | return "Custom"; | 
|  | #define STRINGIFY_SECTION_NAME(NAME, ID, DESCRIPTION) case Section::NAME: return #NAME; | 
|  | FOR_EACH_KNOWN_WASM_SECTION(STRINGIFY_SECTION_NAME) | 
|  | #undef STRINGIFY_SECTION_NAME | 
|  | } | 
|  | ASSERT_NOT_REACHED(); | 
|  | } | 
|  |  | 
|  | } } // namespace JSC::Wasm | 
|  |  | 
|  | #if !ASSERT_ENABLED | 
|  | IGNORE_RETURN_TYPE_WARNINGS_END | 
|  | #endif | 
|  |  | 
|  | #endif // ENABLE(WEBASSEMBLY) |