Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement wat-numeric-values proposal #28

Merged
merged 1 commit into from
Nov 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/wasp/base/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@

#include <vector>

#include "wasp/base/span.h"
#include "wasp/base/types.h"

namespace wasp {

using Buffer = std::vector<u8>;

inline auto ToBuffer(SpanU8 span) -> Buffer {
return Buffer(span.begin(), span.end());
}

} // namespace wasp

#endif // WASP_BASE_BUFFER_H_
1 change: 1 addition & 0 deletions include/wasp/base/features.inc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ WASP_V(GC, gc, "gc",
WASP_V(Memory64, memory64, "memory64", false)
WASP_V(MultiValue, multi_value, "multi-value", false)
WASP_V(MutableGlobals, mutable_globals, "mutable-globals", true )
WASP_V(NumericValues, numeric_values, "numeric-values", false)
WASP_V(ReferenceTypes, reference_types, "reference-types", false)
WASP_V(SaturatingFloatToInt, saturating_float_to_int, "saturating-float-to-int", false)
WASP_V(SignExtension, sign_extension, "sign-extension", false)
Expand Down
2 changes: 1 addition & 1 deletion include/wasp/convert/to_binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ auto ToBinaryLocalsList(Context&, const At<text::BoundValueTypeList>&) -> At<bin
auto ToBinaryCode(Context&, const At<text::Function>&) -> OptAt<binary::UnpackedCode>;

// Section 11: Data
auto ToBinary(Context&, const At<text::TextList>&) -> SpanU8;
auto ToBinary(Context&, const At<text::DataItemList>&) -> SpanU8;
auto ToBinary(Context&, const At<text::DataSegment>&) -> At<binary::DataSegment>;

// Section 12: DataCount
Expand Down
2 changes: 1 addition & 1 deletion include/wasp/convert/to_text.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ auto ToText(TextContext&, const binary::LocalsList&) -> At<text::BoundValueTypeL
auto ToText(TextContext&, const At<binary::UnpackedCode>&, At<text::Function>&) -> At<text::Function>&;

// Section 11: Data
auto ToText(TextContext&, const At<SpanU8>&) -> text::TextList;
auto ToText(TextContext&, const At<SpanU8>&) -> text::DataItemList;
auto ToText(TextContext&, const At<binary::DataSegment>&) -> At<text::DataSegment>;

// Section 12: DataCount
Expand Down
8 changes: 7 additions & 1 deletion include/wasp/text/formatters.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@ WASP_DEFINE_VARIANT_NAME(text::BoundFunctionType, "func")
WASP_DEFINE_VARIANT_NAME(text::StructType, "struct")
WASP_DEFINE_VARIANT_NAME(text::ArrayType, "array")

// Instruction.
// Token.
WASP_DEFINE_VARIANT_NAME(text::OpcodeInfo, "opcode_info")
WASP_DEFINE_VARIANT_NAME(text::LiteralInfo, "literal_info")
WASP_DEFINE_VARIANT_NAME(text::Text, "text")
WASP_DEFINE_VARIANT_NAME(text::SimdShape, "simd_shape")

// Instruction.
WASP_DEFINE_VARIANT_NAME(text::BlockImmediate, "block")
WASP_DEFINE_VARIANT_NAME(text::BrTableImmediate, "br_table")
WASP_DEFINE_VARIANT_NAME(text::BrOnCastImmediate, "br_on_cast")
Expand Down Expand Up @@ -69,6 +72,9 @@ WASP_DEFINE_VARIANT_NAME(text::EventDesc, "event")
WASP_DEFINE_VARIANT_NAME(text::ElementListWithExpressions, "expression")
WASP_DEFINE_VARIANT_NAME(text::ElementListWithVars, "var")

// DataItem.
WASP_DEFINE_VARIANT_NAME(text::NumericData, "numeric_data")

// ModuleItem.
WASP_DEFINE_VARIANT_NAME(text::DefinedType, "type")
WASP_DEFINE_VARIANT_NAME(text::Import, "import")
Expand Down
11 changes: 11 additions & 0 deletions include/wasp/text/read.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ auto ReadTable(Tokenizer&, Context&) -> OptAt<Table>;

// Section 5: Memory

template <typename T>
bool ReadIntsIntoBuffer(Tokenizer&, Context&, Buffer&);
template <typename T>
bool ReadFloatsIntoBuffer(Tokenizer&, Context&, Buffer&);

auto ReadSimdConst(Tokenizer&, Context&) -> OptAt<v128>;
bool ReadSimdConstsIntoBuffer(Tokenizer&, Context&, Buffer&);

auto ReadNumericData(Tokenizer&, Context&) -> OptAt<NumericData>;
auto ReadDataItem(Tokenizer&, Context&) -> OptAt<DataItem>;
auto ReadDataItemList(Tokenizer&, Context&) -> optional<DataItemList>;
auto ReadMemoryType(Tokenizer&, Context&) -> OptAt<MemoryType>;
auto ReadMemory(Tokenizer&, Context&) -> OptAt<Memory>;

Expand Down
8 changes: 8 additions & 0 deletions include/wasp/text/read/token-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ inline bool Token::has_text() const {
return immediate.index() == 7;
}

inline bool Token::has_simd_shape() const {
return immediate.index() == 8;
}

inline At<Opcode> Token::opcode() const {
return At{loc, get<OpcodeInfo>(immediate).opcode};
}
Expand Down Expand Up @@ -140,4 +144,8 @@ inline Text Token::text() const {
return get<Text>(immediate);
}

inline SimdShape Token::simd_shape() const {
return get<SimdShape>(immediate);
}

} // namespace wasp::text
10 changes: 8 additions & 2 deletions include/wasp/text/read/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ enum class LiteralKind { Normal, Nan, NanPayload, Infinity };
enum class Base { Decimal, Hex };
enum class HasUnderscores { No, Yes };

enum class SimdShape { I8X16, I16X8, I32X4, I64X2, F32X4, F64X2 };

struct LiteralInfo {
static LiteralInfo HexNat(HasUnderscores);
static LiteralInfo Nat(HasUnderscores);
Expand Down Expand Up @@ -69,7 +71,7 @@ struct OpcodeInfo {
};

struct Text {
void ToBuffer(Buffer& buffer) const;
void AppendToBuffer(Buffer& buffer) const;
auto ToString() const -> std::string;

string_view text;
Expand All @@ -84,7 +86,8 @@ struct Token {
HeapKind,
PackedType,
LiteralInfo,
Text>;
Text,
SimdShape>;

Token();
Token(Location, TokenType);
Expand All @@ -96,6 +99,7 @@ struct Token {
Token(Location, TokenType, LiteralInfo);
Token(Location, TokenType, Text);
Token(Location, TokenType, Immediate);
Token(Location, TokenType, SimdShape);

SpanU8 span_u8() const;
string_view as_string_view() const;
Expand All @@ -107,6 +111,7 @@ struct Token {
bool has_packed_type() const;
bool has_literal_info() const;
bool has_text() const;
bool has_simd_shape() const;

At<Opcode> opcode() const;
Features opcode_features() const;
Expand All @@ -116,6 +121,7 @@ struct Token {
At<PackedType> packed_type() const;
LiteralInfo literal_info() const;
Text text() const;
SimdShape simd_shape() const;

Location loc;
TokenType type;
Expand Down
7 changes: 1 addition & 6 deletions include/wasp/text/token_type.inc
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,11 @@ WASP_V(Else) // "else"
WASP_V(End) // "end"
WASP_V(Event) // "event"
WASP_V(Export) // "export"
WASP_V(F32X4) // "f32x4"
WASP_V(F64X2) // "f64x2"
WASP_V(Field) // "field"
WASP_V(Float) // "3.14159"
WASP_V(Func) // "func"
WASP_V(Global) // "global"
WASP_V(HeapKind) // "any", "extern", "exn", "i31", etc.
WASP_V(I16X8) // "i16x8"
WASP_V(I32X4) // "i32x4"
WASP_V(I64X2) // "i64x2"
WASP_V(I8X16) // "i8x16"
WASP_V(Id) // "$hello"
WASP_V(I31) // "i31"
WASP_V(Import) // "import"
Expand All @@ -75,6 +69,7 @@ WASP_V(Result) // "result"
WASP_V(Rpar) // ")"
WASP_V(Rtt) // "rtt"
WASP_V(Shared) // "shared"
WASP_V(SimdShape) // "i8x16", "i16x8", "f32x4", etc.
WASP_V(Start) // "start"
WASP_V(Struct) // "struct"
WASP_V(Table) // "table"
Expand Down
29 changes: 29 additions & 0 deletions include/wasp/text/types-inl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Copyright 2020 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.
//

namespace wasp::text {

template <typename T>
auto NumericData::value(Index index) const -> T {
assert(index < count());
T result;
size_t size = data_type_size();
// TODO: Handle big endian.
memcpy(&result, data.data() + index * size, size);
return result;
}

} // namespace wasp::text
73 changes: 58 additions & 15 deletions include/wasp/text/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ using BindVar = string_view;

using TextList = std::vector<At<Text>>;

void ToBuffer(const TextList&, Buffer& buffer);
void AppendToBuffer(const TextList&, Buffer& buffer);

struct FunctionType {
ValueTypeList params;
Expand Down Expand Up @@ -606,12 +606,48 @@ struct Table {

struct DataSegment;

enum class NumericDataType { I8, I16, I32, I64, F32, F64, V128 };

struct NumericData {
auto data_type_size() const -> u32;
auto byte_size() const -> u32;
auto count() const -> Index;

template <typename T>
auto value(Index) const -> T;

void AppendToBuffer(Buffer&) const;

NumericDataType type;
Buffer data;
};

struct DataItem {
bool is_text() const;
bool is_numeric_data() const;

auto text() -> Text&;
auto text() const -> const Text&;
auto numeric_data() -> NumericData&;
auto numeric_data() const -> const NumericData&;

auto byte_size() const -> u32;

void AppendToBuffer(Buffer&) const;

variant<Text, NumericData> value;
};

using DataItemList = std::vector<At<DataItem>>;

struct Memory {
// Defined memory.
explicit Memory(const MemoryDesc&, const InlineExportList&);

// Defined memory with implicit data segment.
explicit Memory(const MemoryDesc&, const InlineExportList&, const TextList&);
explicit Memory(const MemoryDesc&,
const InlineExportList&,
const DataItemList&);

// Imported memory.
explicit Memory(const MemoryDesc&,
Expand All @@ -625,7 +661,7 @@ struct Memory {
MemoryDesc desc;
OptAt<InlineImport> import;
InlineExportList exports;
optional<TextList> data;
optional<DataItemList> data;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use the empty list here to signify no items?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been trying to use optional for things like this, rather than sentinel values. It makes it nicer to do a quick "does this exist" check too (data.has_value()) -- otherwise you'd probably need a separate function.

};

// Section 6: Global
Expand Down Expand Up @@ -702,16 +738,16 @@ struct DataSegment {
explicit DataSegment(OptAt<BindVar> name,
OptAt<Var> memory,
const At<ConstantExpression>& offset,
const TextList&);
const DataItemList&);

// Passive.
explicit DataSegment(OptAt<BindVar> name, const TextList&);
explicit DataSegment(OptAt<BindVar> name, const DataItemList&);

OptAt<BindVar> name;
SegmentType type;
OptAt<Var> memory;
OptAt<ConstantExpression> offset;
TextList data;
DataItemList data;
};

// Section 12: DataCount
Expand Down Expand Up @@ -1002,15 +1038,17 @@ struct Command {

using Script = std::vector<At<Command>>;

#define WASP_TEXT_ENUMS(WASP_V) \
WASP_V(text::TokenType) \
WASP_V(text::Sign) \
WASP_V(text::LiteralKind) \
WASP_V(text::Base) \
WASP_V(text::HasUnderscores) \
WASP_V(text::ScriptModuleKind) \
WASP_V(text::AssertionKind) \
WASP_V(text::NanKind)
#define WASP_TEXT_ENUMS(WASP_V) \
WASP_V(text::TokenType) \
WASP_V(text::Sign) \
WASP_V(text::LiteralKind) \
WASP_V(text::Base) \
WASP_V(text::HasUnderscores) \
WASP_V(text::ScriptModuleKind) \
WASP_V(text::AssertionKind) \
WASP_V(text::NanKind) \
WASP_V(text::SimdShape) \
WASP_V(text::NumericDataType)

#define WASP_TEXT_STRUCTS(WASP_V) \
WASP_V(text::LiteralInfo, 4, sign, kind, base, has_underscores) \
Expand Down Expand Up @@ -1048,6 +1086,8 @@ using Script = std::vector<At<Command>>;
WASP_V(text::InlineExport, 1, name) \
WASP_V(text::Function, 5, desc, locals, instructions, import, exports) \
WASP_V(text::Table, 4, desc, import, exports, elements) \
WASP_V(text::NumericData, 2, type, data) \
WASP_V(text::DataItem, 1, value) \
WASP_V(text::Memory, 4, desc, import, exports, data) \
WASP_V(text::ConstantExpression, 1, instructions) \
WASP_V(text::Global, 4, desc, init, import, exports) \
Expand Down Expand Up @@ -1095,6 +1135,7 @@ using Script = std::vector<At<Command>>;
WASP_V(text::BoundValueTypeList) \
WASP_V(text::FieldTypeList) \
WASP_V(text::InlineExportList) \
WASP_V(text::DataItemList) \
WASP_V(text::ElementExpressionList) \
WASP_V(text::Module) \
WASP_V(text::ConstList) \
Expand All @@ -1118,4 +1159,6 @@ WASP_TEXT_CONTAINERS(WASP_ABSL_HASH_VALUE_CONTAINER)

} // namespace wasp::text

#include "wasp/text/types-inl.h"

#endif // WASP_TEXT_TYPES_H_
Loading