forked from WebKit/WebKit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_Data.js
180 lines (168 loc) · 7.46 KB
/
test_Data.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import * as assert from '../assert.js';
import Builder from '../Builder.js';
const memSizeInPages = 1;
const pageSizeInBytes = 64 * 1024;
const memoryDescription = { initial: memSizeInPages, maximum: memSizeInPages };
const emptyMemory = { initial: 0, maximum: 2 };
// FIXME Some corner cases are ill-specified: https://github.com/WebAssembly/design/issues/897
const assertMemoryAllZero = memory => {
const buffer = new Uint8Array(memory.buffer);
for (let idx = 0; idx < buffer.length; ++idx) {
const value = buffer[idx];
assert.eq(value, 0x00);
}
};
(function DataSection() {
const builder = (new Builder())
.Type().End()
.Import().Memory("imp", "memory", memoryDescription).End()
.Data()
.Segment([0xff, 0x2a]).Offset(4).End()
.Segment([0xde, 0xad, 0xbe, 0xef]).Offset(24).End()
.Segment([0xca, 0xfe]).Offset(25).End() // Overwrite.
.Segment([]).Offset(4).End() // Empty.
.End();
const bin = builder.WebAssembly().get();
const module = new WebAssembly.Module(bin);
const memory = new WebAssembly.Memory(memoryDescription);
const instance = new WebAssembly.Instance(module, { imp: { memory: memory } });
const buffer = new Uint8Array(memory.buffer);
for (let idx = 0; idx < memSizeInPages * pageSizeInBytes; ++idx) {
const value = buffer[idx];
switch (idx) {
case 4: assert.eq(value, 0xff); break;
case 5: assert.eq(value, 0x2a); break;
case 24: assert.eq(value, 0xde); break;
case 25: assert.eq(value, 0xca); break;
case 26: assert.eq(value, 0xfe); break;
case 27: assert.eq(value, 0xef); break;
default: assert.eq(value, 0x00); break;
}
}
})();
(function DataSectionWithoutMemory() {
const builder = (new Builder())
.Type().End()
.Data()
.Segment([0xff]).Offset(0).End()
.End();
const bin = builder.WebAssembly().get();
assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 15: 0th Data segment has index 0 which exceeds the number of Memories 0`);
})();
(function EmptyDataSectionWithoutMemory() {
const builder = (new Builder())
.Type().End()
.Data()
.Segment([]).Offset(0).End()
.End();
const bin = builder.WebAssembly().get();
assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 15: 0th Data segment has index 0 which exceeds the number of Memories 0`);
})();
(function DataSectionBiggerThanMemory() {
const builder = (new Builder())
.Type().End()
.Import().Memory("imp", "memory", memoryDescription).End()
.Data()
.Segment(Array(memSizeInPages * pageSizeInBytes + 1).fill(0xff)).Offset(0).End()
.End();
const bin = builder.WebAssembly().get();
const module = new WebAssembly.Module(bin);
const memory = new WebAssembly.Memory(memoryDescription);
assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), WebAssembly.RuntimeError, `Invalid data segment initialization: segment of 65537 bytes memory of 65536 bytes, at offset 0, segment is too big (evaluating 'new WebAssembly.Instance(module, { imp: { memory: memory } })')`);
assertMemoryAllZero(memory);
})();
(function DataSectionOffTheEnd() {
const builder = (new Builder())
.Type().End()
.Import().Memory("imp", "memory", memoryDescription).End()
.Data()
.Segment([0xff]).Offset(memSizeInPages * pageSizeInBytes).End()
.End();
const bin = builder.WebAssembly().get();
const module = new WebAssembly.Module(bin);
const memory = new WebAssembly.Memory(memoryDescription);
assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), WebAssembly.RuntimeError, `Invalid data segment initialization: segment of 1 bytes memory of 65536 bytes, at offset 65536, segment writes outside of memory (evaluating 'new WebAssembly.Instance(module, { imp: { memory: memory } })')`);
assertMemoryAllZero(memory);
})();
(function DataSectionPartlyOffTheEnd() {
const builder = (new Builder())
.Type().End()
.Import().Memory("imp", "memory", memoryDescription).End()
.Data()
.Segment([0xff, 0xff]).Offset(memSizeInPages * pageSizeInBytes - 1).End()
.End();
const bin = builder.WebAssembly().get();
const module = new WebAssembly.Module(bin);
const memory = new WebAssembly.Memory(memoryDescription);
assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), WebAssembly.RuntimeError, `Invalid data segment initialization: segment of 2 bytes memory of 65536 bytes, at offset 65535, segment writes outside of memory (evaluating 'new WebAssembly.Instance(module, { imp: { memory: memory } })')`);
assertMemoryAllZero(memory);
})();
(function DataSectionEmptyOffTheEnd() {
const builder = (new Builder())
.Type().End()
.Import().Memory("imp", "memory", memoryDescription).End()
.Data()
.Segment([]).Offset(memSizeInPages * pageSizeInBytes).End()
.End();
const bin = builder.WebAssembly().get();
const module = new WebAssembly.Module(bin);
const memory = new WebAssembly.Memory(memoryDescription);
const instance = new WebAssembly.Instance(module, { imp: { memory: memory } });
assertMemoryAllZero(memory);
})();
(function DataSectionEmptyOffTheEndWithEmptyMemory() {
const builder = (new Builder())
.Type().End()
.Import().Memory("imp", "memory", emptyMemory).End()
.Data()
.Segment([]).Offset(memSizeInPages * pageSizeInBytes).End()
.End();
const bin = builder.WebAssembly().get();
const module = new WebAssembly.Module(bin);
const memory = new WebAssembly.Memory(emptyMemory);
assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), WebAssembly.RuntimeError, `Invalid data segment initialization: segment of 0 bytes memory of 0 bytes, at offset 65536, segment writes outside of memory`);
assert.eq(memory.buffer.byteLength, 0);
})();
(function DataSectionSeenByStart() {
const offset = 1024;
const builder = (new Builder())
.Type().End()
.Import()
.Memory("imp", "memory", memoryDescription)
.Function("imp", "func", { params: ["i32"] })
.End()
.Function().End()
.Start("foo").End()
.Code()
.Function("foo", { params: [] })
.I32Const(offset)
.I32Load8U(0, 0)
.Call(0) // Calls func((i8.load(offset), align=2, offset=0). This should observe 0xff as set by the data section.
.End()
.End()
.Data()
.Segment([0xff]).Offset(offset).End()
.End();
const bin = builder.WebAssembly().get();
const module = new WebAssembly.Module(bin);
const memory = new WebAssembly.Memory(memoryDescription);
let value = 0;
const setter = v => value = v;
const instance = new WebAssembly.Instance(
module,
{
imp: {
memory: memory,
func: setter
}
});
assert.eq(value, 0xff);
const buffer = new Uint8Array(memory.buffer);
for (let idx = 0; idx < memSizeInPages * pageSizeInBytes; ++idx) {
const value = buffer[idx];
if (idx == offset)
assert.eq(value, 0xff);
else
assert.eq(value, 0x00);
}
})();