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; |
} |
}; |