Skip to content

Commit

Permalink
Add binary::FuncBindImmediate
Browse files Browse the repository at this point in the history
  • Loading branch information
binji committed Nov 2, 2020
1 parent 6439085 commit 18bbab8
Show file tree
Hide file tree
Showing 15 changed files with 102 additions and 14 deletions.
1 change: 1 addition & 0 deletions include/wasp/binary/formatters.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ WASP_DEFINE_VARIANT_NAME(binary::BrOnExnImmediate, "br_on_exn")
WASP_DEFINE_VARIANT_NAME(binary::BrTableImmediate, "br_table")
WASP_DEFINE_VARIANT_NAME(binary::CallIndirectImmediate, "call_indirect")
WASP_DEFINE_VARIANT_NAME(binary::CopyImmediate, "copy")
WASP_DEFINE_VARIANT_NAME(binary::FuncBindImmediate, "func.bind")
WASP_DEFINE_VARIANT_NAME(binary::InitImmediate, "init")
WASP_DEFINE_VARIANT_NAME(binary::LetImmediate, "let")
WASP_DEFINE_VARIANT_NAME(binary::MemArgImmediate, "mem_arg")
Expand Down
2 changes: 2 additions & 0 deletions include/wasp/binary/read.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ auto Read(SpanU8*, Context&, Tag<ExternalKind>) -> OptAt<ExternalKind>;
auto Read(SpanU8*, Context&, Tag<f32>) -> OptAt<f32>;
auto Read(SpanU8*, Context&, Tag<f64>) -> OptAt<f64>;
auto Read(SpanU8*, Context&, Tag<FieldType>) -> OptAt<FieldType>;
auto Read(SpanU8*, Context&, Tag<FuncBindImmediate>)
-> OptAt<FuncBindImmediate>;
auto Read(SpanU8*, Context&, Tag<Function>) -> OptAt<Function>;
auto Read(SpanU8*, Context&, Tag<FunctionType>) -> OptAt<FunctionType>;
auto Read(SpanU8*, Context&, Tag<Global>) -> OptAt<Global>;
Expand Down
11 changes: 11 additions & 0 deletions include/wasp/binary/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ struct CopyImmediate {
At<Index> src_index;
};

struct FuncBindImmediate {
At<Index> index;
};

struct InitImmediate {
At<Index> segment_index;
At<Index> dst_index;
Expand Down Expand Up @@ -284,6 +288,7 @@ enum class InstructionKind {
Select,
Shuffle,
SimdLane,
FuncBind,
BrOnCast,
HeapType2,
RttSub,
Expand All @@ -304,6 +309,7 @@ struct Instruction {
explicit Instruction(At<Opcode>, At<BrTableImmediate>);
explicit Instruction(At<Opcode>, At<CallIndirectImmediate>);
explicit Instruction(At<Opcode>, At<CopyImmediate>);
explicit Instruction(At<Opcode>, At<FuncBindImmediate>);
explicit Instruction(At<Opcode>, At<HeapType>);
explicit Instruction(At<Opcode>, At<HeapType2Immediate>);
explicit Instruction(At<Opcode>, At<InitImmediate>);
Expand Down Expand Up @@ -339,6 +345,7 @@ struct Instruction {
bool has_br_table_immediate() const;
bool has_call_indirect_immediate() const;
bool has_copy_immediate() const;
bool has_func_bind_immediate() const;
bool has_heap_type_immediate() const;
bool has_heap_type_2_immediate() const;
bool has_init_immediate() const;
Expand Down Expand Up @@ -374,6 +381,8 @@ struct Instruction {
auto call_indirect_immediate() const -> const At<CallIndirectImmediate>&;
auto copy_immediate() -> At<CopyImmediate>&;
auto copy_immediate() const -> const At<CopyImmediate>&;
auto func_bind_immediate() -> At<FuncBindImmediate>&;
auto func_bind_immediate() const -> const At<FuncBindImmediate>&;
auto heap_type_immediate() -> At<HeapType>&;
auto heap_type_immediate() const -> const At<HeapType>&;
auto heap_type_2_immediate() -> At<HeapType2Immediate>&;
Expand Down Expand Up @@ -415,6 +424,7 @@ struct Instruction {
At<SelectImmediate>,
At<ShuffleImmediate>,
At<SimdLaneImmediate>,
At<FuncBindImmediate>,
At<BrOnCastImmediate>,
At<HeapType2Immediate>,
At<RttSubImmediate>,
Expand Down Expand Up @@ -720,6 +730,7 @@ struct Module {
WASP_V(binary::Export, 3, kind, name, index) \
WASP_V(binary::Expression, 1, data) \
WASP_V(binary::FieldType, 2, type, mut) \
WASP_V(binary::FuncBindImmediate, 1, index) \
WASP_V(binary::Function, 1, type_index) \
WASP_V(binary::FunctionType, 2, param_types, result_types) \
WASP_V(binary::Global, 2, global_type, init) \
Expand Down
8 changes: 8 additions & 0 deletions include/wasp/binary/write.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,11 @@ WriteFixedVarInt(T value, Iterator out, size_t length = VarInt<T>::kMaxBytes) {
return out;
}

template <typename Iterator>
Iterator Write(const FuncBindImmediate& immediate, Iterator out) {
return Write(immediate.index, out);
}

template <typename Iterator>
Iterator Write(const Function& value, Iterator out) {
return Write(value.type_index, out);
Expand Down Expand Up @@ -614,6 +619,9 @@ Iterator Write(const Instruction& instr, Iterator out) {
case InstructionKind::SimdLane:
return Write(instr.simd_lane_immediate(), out);

case InstructionKind::FuncBind:
return Write(instr.func_bind_immediate(), out);

case InstructionKind::BrOnCast:
return Write(instr.br_on_cast_immediate(), out);

Expand Down
1 change: 1 addition & 0 deletions include/wasp/convert/to_binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ auto ToBinary(Context&, const At<text::BrOnExnImmediate>&) -> At<binary::BrOnExn
auto ToBinary(Context&, const At<text::BrTableImmediate>&) -> At<binary::BrTableImmediate>;
auto ToBinary(Context&, const At<text::CallIndirectImmediate>&) -> At<binary::CallIndirectImmediate>;
auto ToBinary(Context&, const At<text::CopyImmediate>&) -> At<binary::CopyImmediate>;
auto ToBinary(Context&, const At<text::FuncBindImmediate>&) -> At<binary::FuncBindImmediate>;
auto ToBinary(Context&, const At<text::HeapType2Immediate>&) -> At<binary::HeapType2Immediate>;
auto ToBinary(Context&, const At<text::InitImmediate>&) -> At<binary::InitImmediate>;
auto ToBinary(Context&, const At<text::LetImmediate>&) -> At<binary::LetImmediate>;
Expand Down
6 changes: 6 additions & 0 deletions src/binary/formatters.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,11 @@ std::ostream& operator<<(std::ostream& os,
return os << self.dst_index << " " << self.src_index;
}

std::ostream& operator<<(std::ostream& os,
const ::wasp::binary::FuncBindImmediate& self) {
return os << self.index;
}

std::ostream& operator<<(std::ostream& os,
const ::wasp::binary::RttSubImmediate& self) {
return os << self.depth << " " << self.types;
Expand Down Expand Up @@ -327,6 +332,7 @@ std::ostream& operator<<(std::ostream& os,
case InstructionKind::Select: os << " " << self.select_immediate(); break;
case InstructionKind::Shuffle: os << " " << self.shuffle_immediate(); break;
case InstructionKind::SimdLane: os << " " << self.simd_lane_immediate(); break;
case InstructionKind::FuncBind: os << " " << self.func_bind_immediate(); break;
case InstructionKind::BrOnCast: os << " " << self.br_on_cast_immediate(); break;
case InstructionKind::HeapType2: os << " " << self.heap_type_2_immediate(); break;
case InstructionKind::RttSub: os << " " << self.rtt_sub_immediate(); break;
Expand Down
15 changes: 14 additions & 1 deletion src/binary/read.cc
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,14 @@ OptAt<FieldType> Read(SpanU8* data, Context& context, Tag<FieldType>) {
return At{guard.range(data), FieldType{type, mut}};
}

OptAt<FuncBindImmediate> Read(SpanU8* data,
Context& context,
Tag<FuncBindImmediate>) {
LocationGuard guard{data};
WASP_TRY_READ(index, ReadIndex(data, context, "func index"));
return At{guard.range(data), FuncBindImmediate{index}};
}

OptAt<Function> Read(SpanU8* data, Context& context, Tag<Function>) {
ErrorsContextGuard error_guard{context.errors, *data, "function"};
LocationGuard guard{data};
Expand Down Expand Up @@ -985,7 +993,6 @@ OptAt<Instruction> Read(SpanU8* data, Context& context, Tag<Instruction>) {
case Opcode::TableSize:
case Opcode::TableFill:
case Opcode::BrOnNull:
case Opcode::FuncBind:
case Opcode::StructNewWithRtt:
case Opcode::StructNewDefaultWithRtt:
case Opcode::ArrayNewWithRtt:
Expand All @@ -999,6 +1006,12 @@ OptAt<Instruction> Read(SpanU8* data, Context& context, Tag<Instruction>) {
return At{guard.range(data), Instruction{opcode, index}};
}

// FuncBind immediate.
case Opcode::FuncBind: {
WASP_TRY_READ(immediate, Read<FuncBindImmediate>(data, context));
return At{guard.range(data), Instruction{opcode, immediate}};
}

// Index, Index immediates.
case Opcode::BrOnExn: {
WASP_TRY_READ(immediate, Read<BrOnExnImmediate>(data, context));
Expand Down
15 changes: 15 additions & 0 deletions src/binary/types.cc
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,9 @@ Instruction::Instruction(At<Opcode> opcode, At<CallIndirectImmediate> immediate)
Instruction::Instruction(At<Opcode> opcode, At<CopyImmediate> immediate)
: opcode(opcode), immediate(immediate) {}

Instruction::Instruction(At<Opcode> opcode, At<FuncBindImmediate> immediate)
: opcode{opcode}, immediate{immediate} {}

Instruction::Instruction(At<Opcode> opcode, At<HeapType> immediate)
: opcode(opcode), immediate(immediate) {}

Expand Down Expand Up @@ -415,6 +418,10 @@ bool Instruction::has_copy_immediate() const {
return holds_alternative<At<CopyImmediate>>(immediate);
}

bool Instruction::has_func_bind_immediate() const {
return holds_alternative<At<FuncBindImmediate>>(immediate);
}

bool Instruction::has_heap_type_immediate() const {
return holds_alternative<At<HeapType>>(immediate);
}
Expand Down Expand Up @@ -553,6 +560,14 @@ const At<CopyImmediate>& Instruction::copy_immediate() const {
return get<At<CopyImmediate>>(immediate);
}

At<FuncBindImmediate>& Instruction::func_bind_immediate() {
return get<At<FuncBindImmediate>>(immediate);
}

const At<FuncBindImmediate>& Instruction::func_bind_immediate() const {
return get<At<FuncBindImmediate>>(immediate);
}

At<HeapType>& Instruction::heap_type_immediate() {
return get<At<HeapType>>(immediate);
}
Expand Down
15 changes: 10 additions & 5 deletions src/convert/to_binary.cc
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,6 @@ auto ToBinary(Context& context, const At<text::ElementSegment>& value)
auto ToBinary(Context& context, const At<text::BlockImmediate>& value)
-> At<binary::BlockType> {
if (value->type.IsInlineType()) {
// TODO: This is really nasty; find a nicer way.
auto inline_type = value->type.GetInlineType();
if (!inline_type) {
return At{value.loc(), binary::BlockType{binary::VoidType{}}};
Expand Down Expand Up @@ -405,6 +404,12 @@ auto ToBinary(Context& context, const At<text::CopyImmediate>& value)
ToBinary(context, value->src, 0)}};
}

auto ToBinary(Context& context, const At<text::FuncBindImmediate>& value)
-> At<binary::FuncBindImmediate> {
return At{value.loc(),
binary::FuncBindImmediate{ToBinary(context, value->type_use)}};
}

auto ToBinary(Context& context, const At<text::HeapType2Immediate>& value)
-> At<binary::HeapType2Immediate> {
return At{value.loc(),
Expand Down Expand Up @@ -676,10 +681,10 @@ auto ToBinary(Context& context, const At<text::Instruction>& value)
value->simd_lane_immediate()}};

case text::InstructionKind::FuncBind:
return At{value.loc(),
binary::Instruction{
value->opcode,
ToBinary(context, value->func_bind_immediate()->type_use)}};
return At{
value.loc(),
binary::Instruction{value->opcode,
ToBinary(context, value->func_bind_immediate())}};

case text::InstructionKind::BrOnCast:
return At{
Expand Down
5 changes: 3 additions & 2 deletions src/valid/validate_instruction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,8 @@ bool ReturnCallRef(Context& context, Location loc) {
return AllTrue(function_type, valid);
}

bool FuncBind(Context& context, Location loc, At<Index> new_type_index) {
bool FuncBind(Context& context, Location loc, At<FuncBindImmediate> immediate) {
auto new_type_index = immediate->index;
auto [stack_type, old_function_type] = PopFunctionReference(context, loc);
if (!stack_type) {
return false;
Expand Down Expand Up @@ -1889,7 +1890,7 @@ bool Validate(Context& context, const At<Instruction>& value) {
return ReturnCallRef(context, loc);

case Opcode::FuncBind:
return FuncBind(context, loc, value->index_immediate());
return FuncBind(context, loc, value->func_bind_immediate());

case Opcode::Let:
return Let(context, loc, value->let_immediate());
Expand Down
7 changes: 7 additions & 0 deletions test/binary/formatters_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,10 @@ TEST(BinaryFormattersTest, CopyImmediate) {
EXPECT_EQ(R"(0 0)", concat(CopyImmediate{0, 0}));
}

TEST(BinaryFormattersTest, FuncBindImmediate) {
EXPECT_EQ(R"(0)", concat(FuncBindImmediate{0}));
}

TEST(BinaryFormattersTest, RttSubImmediate) {
EXPECT_EQ(R"(1 func 0)", concat(RttSubImmediate{1, {HT_Func, HT_0}}));
}
Expand Down Expand Up @@ -405,6 +409,9 @@ TEST(BinaryFormattersTest, Instruction) {
// memory.copy 1 2
EXPECT_EQ(R"(memory.copy 1 2)",
concat(Instruction{Opcode::MemoryCopy, CopyImmediate{1, 2}}));
// func.bind 2
EXPECT_EQ(R"(func.bind 2)",
concat(Instruction{Opcode::FuncBind, FuncBindImmediate{2}}));
// rtt.sub 1 func 0
EXPECT_EQ(
R"(rtt.sub 1 func 0)",
Expand Down
9 changes: 8 additions & 1 deletion test/binary/read_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,11 @@ TEST_F(BinaryReadTest, CopyImmediate_Memory_reference_types) {
"\x01\x80\x01"_su8);
}

TEST_F(BinaryReadTest, FuncBindImmediate) {
OK(Read<FuncBindImmediate>, FuncBindImmediate{At{"\x00"_su8, Index{0}}},
"\x00"_su8);
}

TEST_F(BinaryReadTest, ShuffleImmediate) {
OK(Read<ShuffleImmediate>,
ShuffleImmediate{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
Expand Down Expand Up @@ -2338,7 +2343,9 @@ TEST_F(BinaryReadTest, Instruction_function_references) {

OK(Read<I>, I{At{"\x14"_su8, O::CallRef}}, "\x14"_su8);
OK(Read<I>, I{At{"\x15"_su8, O::ReturnCallRef}}, "\x15"_su8);
OK(Read<I>, I{At{"\x16"_su8, O::FuncBind}, At{"\x00"_su8, Index{0}}},
OK(Read<I>,
I{At{"\x16"_su8, O::FuncBind},
At{"\x00"_su8, FuncBindImmediate{At{"\x00"_su8, Index{0}}}}},
"\x16\x00"_su8);
OK(Read<I>,
I{At{"\x17"_su8, O::Let},
Expand Down
6 changes: 5 additions & 1 deletion test/binary/write_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,10 @@ TEST(BinaryWriteTest, FixedVarInt_s32) {
ExpectWriteFixedVarInt<s32>("\xef\xdd\xbb\xf7\x7e"_su8, -0x11111111, 5);
}

TEST(BinaryWriteTest, FuncBindImmediate) {
ExpectWrite("\x00"_su8, FuncBindImmediate{0});
}

TEST(BinaryWriteTest, Function) {
ExpectWrite("\x01"_su8, Function{1});
}
Expand Down Expand Up @@ -707,7 +711,7 @@ TEST(BinaryWriteTest, Instruction_reference_types) {
TEST(BinaryWriteTest, Instruction_function_references) {
ExpectWrite("\x14"_su8, I{O::CallRef});
ExpectWrite("\x15"_su8, I{O::ReturnCallRef});
ExpectWrite("\x16\x00"_su8, I{O::FuncBind, Index{0}});
ExpectWrite("\x16\x00"_su8, I{O::FuncBind, FuncBindImmediate{Index{0}}});
ExpectWrite("\x17\x40\x01\x02\x7f"_su8,
I{O::Let, LetImmediate{BT_Void, {Locals{Index{2}, VT_I32}}}});
ExpectWrite("\xd3"_su8, I{O::RefAsNonNull});
Expand Down
10 changes: 8 additions & 2 deletions test/convert/to_binary_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,11 @@ TEST(ConvertToBinaryTest, CopyImmediate) {
At{loc1, text::CopyImmediate{}});
}

TEST(ConvertToBinaryTest, FuncBindImmediate) {
OK(At{loc1, binary::FuncBindImmediate{At{loc2, Index{13}}}},
At{loc1, text::FuncBindImmediate{At{loc2, text::Var{Index{13}}}, {}}});
}

TEST(ConvertToBinaryTest, HeapType2Immediate) {
OK(At{loc1,
binary::HeapType2Immediate{At{loc2, BHT_Func}, At{loc3, BHT_Func}}},
Expand Down Expand Up @@ -739,8 +744,9 @@ TEST(ConvertToBinaryTest, Instruction) {
At{loc5, text::Var{Index{14}}}}}}});

// FuncBindImmediate
OK(At{loc1,
binary::Instruction{At{loc2, Opcode::FuncBind}, At{loc4, Index{13}}}},
OK(At{loc1, binary::Instruction{At{loc2, Opcode::FuncBind},
At{loc3, binary::FuncBindImmediate{At{
loc4, Index{13}}}}}},
At{loc1, text::Instruction{
At{loc2, Opcode::FuncBind},
At{loc3, text::FuncBindImmediate{text::FunctionTypeUse{
Expand Down
5 changes: 3 additions & 2 deletions test/valid/validate_instruction_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2846,7 +2846,8 @@ TEST_F(ValidateInstructionTest, FuncBind) {
ValueType VT_RefNew = MakeValueTypeRef(new_index, Null::No);
ValueTypeList params = info.params;
params.push_back(VT_RefOld);
TestSignature(I{O::FuncBind, new_index}, params, {VT_RefNew});
TestSignature(I{O::FuncBind, FuncBindImmediate{new_index}}, params,
{VT_RefNew});
}
}

Expand Down Expand Up @@ -2879,7 +2880,7 @@ TEST_F(ValidateInstructionTest, FuncBind_TypeMismatch) {
ValueType VT_RefOld = MakeValueTypeRef(old_index, Null::No);
ValueTypeList params = info.params;
params.push_back(VT_RefOld);
FailWithTypeStack(I{O::FuncBind, new_index}, params);
FailWithTypeStack(I{O::FuncBind, FuncBindImmediate{new_index}}, params);
ClearErrors(errors);
}
}
Expand Down

0 comments on commit 18bbab8

Please sign in to comment.