Chromium Code Reviews| Index: src/wasm/ast-decoder.h |
| diff --git a/src/wasm/ast-decoder.h b/src/wasm/ast-decoder.h |
| index 386f6f52b2d1456f28cb01232cfcdfaf47e8eaec..8c459963bfbc01110dc0b560ae5d21300ca50aa9 100644 |
| --- a/src/wasm/ast-decoder.h |
| +++ b/src/wasm/ast-decoder.h |
| @@ -97,8 +97,7 @@ struct BreakDepthOperand { |
| Block* target; |
| int length; |
| inline BreakDepthOperand(Decoder* decoder, const byte* pc) { |
| - depth = decoder->checked_read_u8(pc, 1, "break depth"); |
| - length = 1; |
| + depth = decoder->checked_read_u32v(pc, 1, &length, "break depth"); |
| target = nullptr; |
| } |
| }; |
| @@ -107,8 +106,7 @@ struct BlockCountOperand { |
| uint32_t count; |
| int length; |
| inline BlockCountOperand(Decoder* decoder, const byte* pc) { |
| - count = decoder->checked_read_u8(pc, 1, "block count"); |
| - length = 1; |
| + count = decoder->checked_read_u32v(pc, 1, &length, "block count"); |
| } |
| }; |
| @@ -146,20 +144,47 @@ struct BranchTableOperand { |
| uint32_t table_count; |
| const byte* table; |
| int length; |
| + // Cache entry offsets, assuming we are iterating through them in order. |
| + int next_entry_index; |
| + const byte* next_entry; |
| inline BranchTableOperand(Decoder* decoder, const byte* pc) { |
|
titzer
2016/03/08 10:06:53
Maybe we can leave the branch table target as uint
binji
2016/03/08 16:30:15
:)
|
| - table_count = decoder->checked_read_u16(pc, 1, "expected #entries"); |
| - length = 2 + table_count * 2 + 2; |
| + int varint_length; |
| + table_count = |
| + decoder->checked_read_u32v(pc, 1, &varint_length, "expected #entries"); |
| + length = varint_length; |
| + uint32_t table_start = 1 + length; |
| + for (uint32_t i = 0; i < table_count; ++i) { |
| + decoder->checked_read_u32v(pc, 1 + length, &varint_length); |
| + length += varint_length; |
| + } |
| + // Default entry. |
| + decoder->checked_read_u32v(pc, 1 + length, &varint_length); |
| + length += varint_length; |
| - if (decoder->check(pc, 3, table_count * 2 + 2, |
| - "expected <table entries>")) { |
| - table = pc + 3; |
| + if (decoder->check(pc, 1, length, "expected <table entries>")) { |
| + table = pc + table_start; |
| } else { |
| table = nullptr; |
| } |
| + next_entry_index = 0; |
| + next_entry = table; |
| } |
| - inline uint16_t read_entry(Decoder* decoder, int i) { |
| + inline uint32_t read_entry(Decoder* decoder, int i) { |
| DCHECK(i >= 0 && static_cast<uint32_t>(i) <= table_count); |
| - return table ? decoder->read_u16(table + i * sizeof(uint16_t)) : 0; |
| + if (!table) return 0; |
| + if (next_entry_index > i) { |
| + // Reset to zero and iterate. |
| + next_entry_index = 0; |
| + next_entry = table; |
| + } |
| + uint32_t result; |
| + while (next_entry_index <= i) { |
|
titzer
2016/03/08 10:06:53
Linear search; that's no good. Definitely gotta go
binji
2016/03/08 16:30:15
It shouldn't actually end up being linear here. In
|
| + int varint_length; |
| + result = decoder->checked_read_u32v(next_entry, 0, &varint_length); |
| + next_entry_index++; |
| + next_entry += varint_length; |
| + } |
| + return result; |
| } |
| }; |