Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/api-inl.h"
6 : #include "src/objects-inl.h"
7 : #include "src/objects/managed.h"
8 : #include "src/v8.h"
9 : #include "src/vector.h"
10 :
11 : #include "src/wasm/module-decoder.h"
12 : #include "src/wasm/streaming-decoder.h"
13 : #include "src/wasm/wasm-engine.h"
14 : #include "src/wasm/wasm-module-builder.h"
15 : #include "src/wasm/wasm-module.h"
16 : #include "src/wasm/wasm-objects-inl.h"
17 : #include "src/wasm/wasm-objects.h"
18 : #include "src/wasm/wasm-serialization.h"
19 :
20 : #include "test/cctest/cctest.h"
21 :
22 : #include "test/common/wasm/test-signatures.h"
23 : #include "test/common/wasm/wasm-macro-gen.h"
24 :
25 : namespace v8 {
26 : namespace internal {
27 : namespace wasm {
28 :
29 280 : class MockPlatform final : public TestPlatform {
30 : public:
31 280 : MockPlatform() : task_runner_(std::make_shared<MockTaskRunner>()) {
32 : // Now that it's completely constructed, make this the current platform.
33 140 : i::V8::SetPlatformForTesting(this);
34 140 : }
35 :
36 329 : std::shared_ptr<TaskRunner> GetForegroundTaskRunner(
37 : v8::Isolate* isolate) override {
38 329 : return task_runner_;
39 : }
40 :
41 0 : void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override {
42 0 : task_runner_->PostTask(std::unique_ptr<Task>(task));
43 0 : }
44 :
45 1102 : void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override {
46 2204 : task_runner_->PostTask(std::move(task));
47 1102 : }
48 :
49 0 : bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; }
50 :
51 292 : void ExecuteTasks() { task_runner_->ExecuteTasks(); }
52 :
53 : private:
54 560 : class MockTaskRunner final : public TaskRunner {
55 : public:
56 245 : void PostTask(std::unique_ptr<v8::Task> task) override {
57 : tasks_.push(std::move(task));
58 245 : }
59 :
60 16 : void PostDelayedTask(std::unique_ptr<Task> task,
61 : double delay_in_seconds) override {
62 : tasks_.push(std::move(task));
63 16 : }
64 :
65 0 : void PostIdleTask(std::unique_ptr<IdleTask> task) override {
66 0 : UNREACHABLE();
67 : }
68 :
69 0 : bool IdleTasksEnabled() override { return false; }
70 :
71 292 : void ExecuteTasks() {
72 1947 : while (!tasks_.empty()) {
73 : std::unique_ptr<Task> task = std::move(tasks_.front());
74 : tasks_.pop();
75 1363 : task->Run();
76 : }
77 292 : }
78 :
79 : private:
80 : // We do not execute tasks concurrently, so we only need one list of tasks.
81 : std::queue<std::unique_ptr<v8::Task>> tasks_;
82 : };
83 :
84 : std::shared_ptr<MockTaskRunner> task_runner_;
85 : };
86 :
87 : namespace {
88 :
89 : enum class CompilationState {
90 : kPending,
91 : kFinished,
92 : kFailed,
93 : };
94 :
95 296 : class TestResolver : public CompilationResultResolver {
96 : public:
97 : TestResolver(CompilationState* state,
98 : std::shared_ptr<NativeModule>* native_module)
99 148 : : state_(state), native_module_(native_module) {}
100 :
101 56 : void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> module) override {
102 56 : *state_ = CompilationState::kFinished;
103 56 : if (!module.is_null()) {
104 112 : *native_module_ = module->shared_native_module();
105 : }
106 56 : }
107 :
108 48 : void OnCompilationFailed(i::Handle<i::Object> error_reason) override {
109 48 : *state_ = CompilationState::kFailed;
110 48 : }
111 :
112 : private:
113 : CompilationState* state_;
114 : std::shared_ptr<NativeModule>* native_module_;
115 : };
116 :
117 296 : class StreamTester {
118 : public:
119 148 : StreamTester()
120 : : zone_(&allocator_, "StreamTester"),
121 296 : internal_scope_(CcTest::i_isolate()) {
122 148 : v8::Isolate* isolate = CcTest::isolate();
123 : i::Isolate* i_isolate = CcTest::i_isolate();
124 :
125 148 : v8::Local<v8::Context> context = isolate->GetCurrentContext();
126 :
127 740 : stream_ = i_isolate->wasm_engine()->StartStreamingCompilation(
128 : i_isolate, kAllWasmFeatures, v8::Utils::OpenHandle(*context),
129 : std::make_shared<TestResolver>(&state_, &native_module_));
130 148 : }
131 :
132 : std::shared_ptr<StreamingDecoder> stream() { return stream_; }
133 :
134 : // Compiled native module, valid after successful compile.
135 : std::shared_ptr<NativeModule> native_module() { return native_module_; }
136 :
137 : // Run all compiler tasks, both foreground and background tasks.
138 292 : void RunCompilerTasks() {
139 292 : static_cast<MockPlatform*>(i::V8::GetCurrentPlatform())->ExecuteTasks();
140 292 : }
141 :
142 : bool IsPromiseFulfilled() { return state_ == CompilationState::kFinished; }
143 :
144 : bool IsPromiseRejected() { return state_ == CompilationState::kFailed; }
145 :
146 : bool IsPromisePending() { return state_ == CompilationState::kPending; }
147 :
148 : void OnBytesReceived(const uint8_t* start, size_t length) {
149 332 : stream_->OnBytesReceived(Vector<const uint8_t>(start, length));
150 : }
151 :
152 100 : void FinishStream() { stream_->Finish(); }
153 :
154 : void SetCompiledModuleBytes(const uint8_t* start, size_t length) {
155 8 : stream_->SetCompiledModuleBytes(Vector<const uint8_t>(start, length));
156 : }
157 :
158 : Zone* zone() { return &zone_; }
159 :
160 : private:
161 : AccountingAllocator allocator_;
162 : Zone zone_;
163 : i::HandleScope internal_scope_;
164 : CompilationState state_ = CompilationState::kPending;
165 : std::shared_ptr<NativeModule> native_module_;
166 : std::shared_ptr<StreamingDecoder> stream_;
167 : };
168 : } // namespace
169 :
170 : #define STREAM_TEST(name) \
171 : void RunStream_##name(); \
172 : TEST(name) { \
173 : MockPlatform platform; \
174 : CcTest::InitializeVM(); \
175 : RunStream_##name(); \
176 : } \
177 : void RunStream_##name()
178 :
179 : // Create a valid module with 3 functions.
180 36 : ZoneBuffer GetValidModuleBytes(Zone* zone) {
181 : ZoneBuffer buffer(zone);
182 36 : TestSignatures sigs;
183 36 : WasmModuleBuilder builder(zone);
184 : {
185 36 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
186 36 : uint8_t code[] = {kExprGetLocal, 0, kExprEnd};
187 36 : f->EmitCode(code, arraysize(code));
188 : }
189 : {
190 36 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
191 36 : uint8_t code[] = {kExprGetLocal, 1, kExprEnd};
192 36 : f->EmitCode(code, arraysize(code));
193 : }
194 : {
195 36 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
196 36 : uint8_t code[] = {kExprGetLocal, 2, kExprEnd};
197 36 : f->EmitCode(code, arraysize(code));
198 : }
199 36 : builder.WriteTo(buffer);
200 36 : return buffer;
201 : }
202 :
203 : // Create the same valid module as above and serialize it to test streaming
204 : // with compiled module caching.
205 8 : ZoneBuffer GetValidCompiledModuleBytes(Zone* zone, ZoneBuffer wire_bytes) {
206 : // Use a tester to compile to a NativeModule.
207 8 : StreamTester tester;
208 8 : tester.OnBytesReceived(wire_bytes.begin(), wire_bytes.size());
209 : tester.FinishStream();
210 8 : tester.RunCompilerTasks();
211 8 : CHECK(tester.IsPromiseFulfilled());
212 : // Serialize the NativeModule.
213 : std::shared_ptr<NativeModule> native_module = tester.native_module();
214 8 : CHECK(native_module);
215 8 : i::wasm::WasmSerializer serializer(native_module.get());
216 8 : size_t size = serializer.GetSerializedNativeModuleSize();
217 8 : std::vector<byte> buffer(size);
218 8 : CHECK(serializer.SerializeNativeModule({buffer.data(), size}));
219 : ZoneBuffer result(zone, size);
220 8 : result.write(buffer.data(), size);
221 8 : return result;
222 : }
223 :
224 : // Test that all bytes arrive before doing any compilation. FinishStream is
225 : // called immediately.
226 25883 : STREAM_TEST(TestAllBytesArriveImmediatelyStreamFinishesFirst) {
227 4 : StreamTester tester;
228 4 : ZoneBuffer buffer = GetValidModuleBytes(tester.zone());
229 :
230 4 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
231 : tester.FinishStream();
232 :
233 4 : tester.RunCompilerTasks();
234 :
235 4 : CHECK(tester.IsPromiseFulfilled());
236 4 : }
237 :
238 : // Test that all bytes arrive before doing any compilation. FinishStream is
239 : // called after the compilation is done.
240 25883 : STREAM_TEST(TestAllBytesArriveAOTCompilerFinishesFirst) {
241 4 : StreamTester tester;
242 4 : ZoneBuffer buffer = GetValidModuleBytes(tester.zone());
243 :
244 4 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
245 :
246 4 : tester.RunCompilerTasks();
247 : tester.FinishStream();
248 4 : tester.RunCompilerTasks();
249 :
250 4 : CHECK(tester.IsPromiseFulfilled());
251 4 : }
252 :
253 8 : size_t GetFunctionOffset(i::Isolate* isolate, const uint8_t* buffer,
254 : size_t size, size_t index) {
255 : ModuleResult result = DecodeWasmModule(
256 : kAllWasmFeatures, buffer, buffer + size, false, ModuleOrigin::kWasmOrigin,
257 16 : isolate->counters(), isolate->allocator());
258 8 : CHECK(result.ok());
259 8 : const WasmFunction* func = &result.value()->functions[1];
260 8 : return func->code.offset();
261 : }
262 :
263 : // Test that some functions come in the beginning, some come after some
264 : // functions already got compiled.
265 25883 : STREAM_TEST(TestCutAfterOneFunctionStreamFinishesFirst) {
266 : i::Isolate* isolate = CcTest::i_isolate();
267 4 : StreamTester tester;
268 4 : ZoneBuffer buffer = GetValidModuleBytes(tester.zone());
269 :
270 4 : size_t offset = GetFunctionOffset(isolate, buffer.begin(), buffer.size(), 1);
271 : tester.OnBytesReceived(buffer.begin(), offset);
272 4 : tester.RunCompilerTasks();
273 4 : CHECK(tester.IsPromisePending());
274 4 : tester.OnBytesReceived(buffer.begin() + offset, buffer.size() - offset);
275 : tester.FinishStream();
276 4 : tester.RunCompilerTasks();
277 4 : CHECK(tester.IsPromiseFulfilled());
278 4 : }
279 :
280 : // Test that some functions come in the beginning, some come after some
281 : // functions already got compiled. Call FinishStream after the compilation is
282 : // done.
283 25883 : STREAM_TEST(TestCutAfterOneFunctionCompilerFinishesFirst) {
284 : i::Isolate* isolate = CcTest::i_isolate();
285 4 : StreamTester tester;
286 4 : ZoneBuffer buffer = GetValidModuleBytes(tester.zone());
287 :
288 4 : size_t offset = GetFunctionOffset(isolate, buffer.begin(), buffer.size(), 1);
289 : tester.OnBytesReceived(buffer.begin(), offset);
290 4 : tester.RunCompilerTasks();
291 4 : CHECK(tester.IsPromisePending());
292 4 : tester.OnBytesReceived(buffer.begin() + offset, buffer.size() - offset);
293 4 : tester.RunCompilerTasks();
294 : tester.FinishStream();
295 4 : tester.RunCompilerTasks();
296 4 : CHECK(tester.IsPromiseFulfilled());
297 4 : }
298 :
299 : // Create a module with an invalid global section.
300 12 : ZoneBuffer GetModuleWithInvalidSection(Zone* zone) {
301 : ZoneBuffer buffer(zone);
302 12 : TestSignatures sigs;
303 12 : WasmModuleBuilder builder(zone);
304 : // Add an invalid global to the module. The decoder will fail there.
305 : builder.AddGlobal(kWasmStmt, false, true,
306 12 : WasmInitExpr(WasmInitExpr::kGlobalIndex, 12));
307 : {
308 12 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
309 12 : uint8_t code[] = {kExprGetLocal, 0, kExprEnd};
310 12 : f->EmitCode(code, arraysize(code));
311 : }
312 : {
313 12 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
314 12 : uint8_t code[] = {kExprGetLocal, 1, kExprEnd};
315 12 : f->EmitCode(code, arraysize(code));
316 : }
317 : {
318 12 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
319 12 : uint8_t code[] = {kExprGetLocal, 2, kExprEnd};
320 12 : f->EmitCode(code, arraysize(code));
321 : }
322 12 : builder.WriteTo(buffer);
323 12 : return buffer;
324 : }
325 :
326 : // Test an error in a section, found by the ModuleDecoder.
327 25883 : STREAM_TEST(TestErrorInSectionStreamFinishesFirst) {
328 4 : StreamTester tester;
329 4 : ZoneBuffer buffer = GetModuleWithInvalidSection(tester.zone());
330 :
331 4 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
332 : tester.FinishStream();
333 :
334 4 : tester.RunCompilerTasks();
335 :
336 4 : CHECK(tester.IsPromiseRejected());
337 4 : }
338 :
339 25883 : STREAM_TEST(TestErrorInSectionCompilerFinishesFirst) {
340 4 : StreamTester tester;
341 4 : ZoneBuffer buffer = GetModuleWithInvalidSection(tester.zone());
342 :
343 4 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
344 4 : tester.RunCompilerTasks();
345 : tester.FinishStream();
346 4 : tester.RunCompilerTasks();
347 :
348 4 : CHECK(tester.IsPromiseRejected());
349 4 : }
350 :
351 25883 : STREAM_TEST(TestErrorInSectionWithCuts) {
352 4 : StreamTester tester;
353 4 : ZoneBuffer buffer = GetModuleWithInvalidSection(tester.zone());
354 :
355 : const uint8_t* current = buffer.begin();
356 4 : size_t remaining = buffer.end() - buffer.begin();
357 40 : while (current < buffer.end()) {
358 64 : size_t size = std::min(remaining, size_t{10});
359 : tester.OnBytesReceived(current, size);
360 32 : tester.RunCompilerTasks();
361 32 : current += 10;
362 32 : remaining -= size;
363 : }
364 : tester.FinishStream();
365 4 : tester.RunCompilerTasks();
366 :
367 4 : CHECK(tester.IsPromiseRejected());
368 4 : }
369 :
370 12 : ZoneBuffer GetModuleWithInvalidSectionSize(Zone* zone) {
371 : // We get a valid module and overwrite the size of the first section with an
372 : // invalid value.
373 12 : ZoneBuffer buffer = GetValidModuleBytes(zone);
374 : // 9 == 4 (wasm magic) + 4 (version) + 1 (section code)
375 12 : uint8_t* section_size_address = const_cast<uint8_t*>(buffer.begin()) + 9;
376 : // 0x808080800F is an invalid module size in leb encoding.
377 12 : section_size_address[0] = 0x80;
378 12 : section_size_address[1] = 0x80;
379 12 : section_size_address[2] = 0x80;
380 12 : section_size_address[3] = 0x80;
381 12 : section_size_address[4] = 0x0F;
382 12 : return buffer;
383 : }
384 :
385 25883 : STREAM_TEST(TestErrorInSectionSizeStreamFinishesFirst) {
386 4 : StreamTester tester;
387 4 : ZoneBuffer buffer = GetModuleWithInvalidSectionSize(tester.zone());
388 4 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
389 : tester.FinishStream();
390 4 : tester.RunCompilerTasks();
391 :
392 4 : CHECK(tester.IsPromiseRejected());
393 4 : }
394 :
395 25883 : STREAM_TEST(TestErrorInSectionSizeCompilerFinishesFirst) {
396 4 : StreamTester tester;
397 4 : ZoneBuffer buffer = GetModuleWithInvalidSectionSize(tester.zone());
398 4 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
399 4 : tester.RunCompilerTasks();
400 : tester.FinishStream();
401 4 : tester.RunCompilerTasks();
402 :
403 4 : CHECK(tester.IsPromiseRejected());
404 4 : }
405 :
406 25883 : STREAM_TEST(TestErrorInSectionSizeWithCuts) {
407 4 : StreamTester tester;
408 4 : ZoneBuffer buffer = GetModuleWithInvalidSectionSize(tester.zone());
409 : const uint8_t* current = buffer.begin();
410 4 : size_t remaining = buffer.end() - buffer.begin();
411 36 : while (current < buffer.end()) {
412 56 : size_t size = std::min(remaining, size_t{10});
413 : tester.OnBytesReceived(current, size);
414 28 : tester.RunCompilerTasks();
415 28 : current += 10;
416 28 : remaining -= size;
417 : }
418 4 : tester.RunCompilerTasks();
419 : tester.FinishStream();
420 4 : tester.RunCompilerTasks();
421 :
422 4 : CHECK(tester.IsPromiseRejected());
423 4 : }
424 :
425 : // Test an error in the code section, found by the ModuleDecoder. The error is a
426 : // functions count in the code section which differs from the functions count in
427 : // the function section.
428 25883 : STREAM_TEST(TestErrorInCodeSectionDetectedByModuleDecoder) {
429 4 : StreamTester tester;
430 :
431 : uint8_t code[] = {
432 : U32V_1(4), // body size
433 : U32V_1(0), // locals count
434 : kExprGetLocal, 0, kExprEnd // body
435 4 : };
436 :
437 : const uint8_t bytes[] = {
438 : WASM_MODULE_HEADER, // module header
439 : kTypeSectionCode, // section code
440 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
441 : U32V_1(1), // type count
442 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
443 : kFunctionSectionCode, // section code
444 : U32V_1(1 + 3), // section size
445 : U32V_1(3), // functions count
446 : 0, // signature index
447 : 0, // signature index
448 : 0, // signature index
449 : kCodeSectionCode, // section code
450 : U32V_1(1 + arraysize(code) * 2), // section size
451 : U32V_1(2), // !!! invalid function count !!!
452 4 : };
453 :
454 : tester.OnBytesReceived(bytes, arraysize(bytes));
455 : tester.OnBytesReceived(code, arraysize(code));
456 : tester.OnBytesReceived(code, arraysize(code));
457 : tester.FinishStream();
458 :
459 4 : tester.RunCompilerTasks();
460 :
461 4 : CHECK(tester.IsPromiseRejected());
462 4 : }
463 :
464 : // Test an error in the code section, found by the StreamingDecoder. The error
465 : // is an invalid function body size, so that there are not enough bytes in the
466 : // code section for the function body.
467 25883 : STREAM_TEST(TestErrorInCodeSectionDetectedByStreamingDecoder) {
468 4 : StreamTester tester;
469 :
470 : uint8_t code[] = {
471 : U32V_1(26), // !!! invalid body size !!!
472 : U32V_1(0), // locals count
473 : kExprGetLocal, 0, kExprEnd // body
474 4 : };
475 :
476 : const uint8_t bytes[] = {
477 : WASM_MODULE_HEADER, // module header
478 : kTypeSectionCode, // section code
479 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
480 : U32V_1(1), // type count
481 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
482 : kFunctionSectionCode, // section code
483 : U32V_1(1 + 3), // section size
484 : U32V_1(3), // functions count
485 : 0, // signature index
486 : 0, // signature index
487 : 0, // signature index
488 : kCodeSectionCode, // section code
489 : U32V_1(1 + arraysize(code) * 3), // section size
490 : U32V_1(3), // functions count
491 4 : };
492 :
493 : tester.OnBytesReceived(bytes, arraysize(bytes));
494 : tester.OnBytesReceived(code, arraysize(code));
495 : tester.OnBytesReceived(code, arraysize(code));
496 : tester.OnBytesReceived(code, arraysize(code));
497 : tester.FinishStream();
498 :
499 4 : tester.RunCompilerTasks();
500 :
501 4 : CHECK(tester.IsPromiseRejected());
502 4 : }
503 :
504 : // Test an error in the code section, found by the Compiler. The error is an
505 : // invalid return type.
506 25883 : STREAM_TEST(TestErrorInCodeSectionDetectedByCompiler) {
507 4 : StreamTester tester;
508 :
509 : uint8_t code[] = {
510 : U32V_1(4), // !!! invalid body size !!!
511 : U32V_1(0), // locals count
512 : kExprGetLocal, 0, kExprEnd // body
513 4 : };
514 :
515 : uint8_t invalid_code[] = {
516 : U32V_1(4), // !!! invalid body size !!!
517 : U32V_1(0), // locals count
518 : kExprI64Const, 0, kExprEnd // body
519 4 : };
520 :
521 : const uint8_t bytes[] = {
522 : WASM_MODULE_HEADER, // module header
523 : kTypeSectionCode, // section code
524 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
525 : U32V_1(1), // type count
526 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
527 : kFunctionSectionCode, // section code
528 : U32V_1(1 + 3), // section size
529 : U32V_1(3), // functions count
530 : 0, // signature index
531 : 0, // signature index
532 : 0, // signature index
533 : kCodeSectionCode, // section code
534 : U32V_1(1 + arraysize(code) * 2 +
535 : arraysize(invalid_code)), // section size
536 : U32V_1(3), // functions count
537 4 : };
538 :
539 : tester.OnBytesReceived(bytes, arraysize(bytes));
540 4 : tester.RunCompilerTasks();
541 : tester.OnBytesReceived(code, arraysize(code));
542 4 : tester.RunCompilerTasks();
543 : tester.OnBytesReceived(invalid_code, arraysize(invalid_code));
544 4 : tester.RunCompilerTasks();
545 : tester.OnBytesReceived(code, arraysize(code));
546 4 : tester.RunCompilerTasks();
547 : tester.FinishStream();
548 4 : tester.RunCompilerTasks();
549 :
550 4 : CHECK(tester.IsPromiseRejected());
551 4 : }
552 :
553 : // Test Abort before any bytes arrive.
554 25883 : STREAM_TEST(TestAbortImmediately) {
555 4 : StreamTester tester;
556 4 : tester.stream()->Abort();
557 4 : tester.RunCompilerTasks();
558 4 : }
559 :
560 : // Test Abort within a section.
561 25883 : STREAM_TEST(TestAbortWithinSection1) {
562 4 : StreamTester tester;
563 : const uint8_t bytes[] = {
564 : WASM_MODULE_HEADER, // module header
565 : kTypeSectionCode, // section code
566 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
567 : U32V_1(1) // type count
568 : // Type section is not yet complete.
569 4 : };
570 : tester.OnBytesReceived(bytes, arraysize(bytes));
571 4 : tester.RunCompilerTasks();
572 4 : tester.stream()->Abort();
573 4 : tester.RunCompilerTasks();
574 4 : }
575 :
576 : // Test Abort within a section.
577 25883 : STREAM_TEST(TestAbortWithinSection2) {
578 4 : StreamTester tester;
579 : const uint8_t bytes[] = {
580 : WASM_MODULE_HEADER, // module header
581 : kTypeSectionCode, // section code
582 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
583 : U32V_1(1), // type count
584 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
585 : kFunctionSectionCode, // section code
586 : U32V_1(1 + 3), // section size
587 : U32V_1(3), // functions count
588 : // Function section is not yet complete.
589 4 : };
590 : tester.OnBytesReceived(bytes, arraysize(bytes));
591 4 : tester.RunCompilerTasks();
592 4 : tester.stream()->Abort();
593 4 : tester.RunCompilerTasks();
594 4 : }
595 :
596 : // Test Abort just before the code section.
597 25883 : STREAM_TEST(TestAbortAfterSection) {
598 4 : StreamTester tester;
599 : const uint8_t bytes[] = {
600 : WASM_MODULE_HEADER, // module header
601 : kTypeSectionCode, // section code
602 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
603 : U32V_1(1), // type count
604 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
605 4 : };
606 : tester.OnBytesReceived(bytes, arraysize(bytes));
607 4 : tester.RunCompilerTasks();
608 4 : tester.stream()->Abort();
609 4 : tester.RunCompilerTasks();
610 4 : }
611 :
612 : // Test Abort after the function count in the code section. The compiler tasks
613 : // execute before the abort.
614 25883 : STREAM_TEST(TestAbortAfterFunctionsCount1) {
615 4 : StreamTester tester;
616 : const uint8_t bytes[] = {
617 : WASM_MODULE_HEADER, // module header
618 : kTypeSectionCode, // section code
619 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
620 : U32V_1(1), // type count
621 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
622 : kFunctionSectionCode, // section code
623 : U32V_1(1 + 3), // section size
624 : U32V_1(3), // functions count
625 : 0, // signature index
626 : 0, // signature index
627 : 0, // signature index
628 : kCodeSectionCode, // section code
629 : U32V_1(20), // section size
630 : U32V_1(3), // functions count
631 4 : };
632 : tester.OnBytesReceived(bytes, arraysize(bytes));
633 4 : tester.RunCompilerTasks();
634 4 : tester.stream()->Abort();
635 4 : tester.RunCompilerTasks();
636 4 : }
637 :
638 : // Test Abort after the function count in the code section. The compiler tasks
639 : // do not execute before the abort.
640 25883 : STREAM_TEST(TestAbortAfterFunctionsCount2) {
641 4 : StreamTester tester;
642 : const uint8_t bytes[] = {
643 : WASM_MODULE_HEADER, // module header
644 : kTypeSectionCode, // section code
645 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
646 : U32V_1(1), // type count
647 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
648 : kFunctionSectionCode, // section code
649 : U32V_1(1 + 3), // section size
650 : U32V_1(3), // functions count
651 : 0, // signature index
652 : 0, // signature index
653 : 0, // signature index
654 : kCodeSectionCode, // section code
655 : U32V_1(20), // section size
656 : U32V_1(3), // functions count
657 4 : };
658 : tester.OnBytesReceived(bytes, arraysize(bytes));
659 4 : tester.stream()->Abort();
660 4 : tester.RunCompilerTasks();
661 4 : }
662 :
663 : // Test Abort after some functions got compiled. The compiler tasks execute
664 : // before the abort.
665 25883 : STREAM_TEST(TestAbortAfterFunctionGotCompiled1) {
666 4 : StreamTester tester;
667 :
668 : uint8_t code[] = {
669 : U32V_1(4), // !!! invalid body size !!!
670 : U32V_1(0), // locals count
671 : kExprGetLocal, 0, kExprEnd // body
672 4 : };
673 :
674 : const uint8_t bytes[] = {
675 : WASM_MODULE_HEADER, // module header
676 : kTypeSectionCode, // section code
677 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
678 : U32V_1(1), // type count
679 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
680 : kFunctionSectionCode, // section code
681 : U32V_1(1 + 3), // section size
682 : U32V_1(3), // functions count
683 : 0, // signature index
684 : 0, // signature index
685 : 0, // signature index
686 : kCodeSectionCode, // section code
687 : U32V_1(20), // section size
688 : U32V_1(3), // functions count
689 4 : };
690 : tester.OnBytesReceived(bytes, arraysize(bytes));
691 : tester.OnBytesReceived(code, arraysize(code));
692 4 : tester.RunCompilerTasks();
693 4 : tester.stream()->Abort();
694 4 : tester.RunCompilerTasks();
695 4 : }
696 :
697 : // Test Abort after some functions got compiled. The compiler tasks execute
698 : // before the abort.
699 25883 : STREAM_TEST(TestAbortAfterFunctionGotCompiled2) {
700 4 : StreamTester tester;
701 :
702 : uint8_t code[] = {
703 : U32V_1(4), // !!! invalid body size !!!
704 : U32V_1(0), // locals count
705 : kExprGetLocal, 0, kExprEnd // body
706 4 : };
707 :
708 : const uint8_t bytes[] = {
709 : WASM_MODULE_HEADER, // module header
710 : kTypeSectionCode, // section code
711 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
712 : U32V_1(1), // type count
713 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
714 : kFunctionSectionCode, // section code
715 : U32V_1(1 + 3), // section size
716 : U32V_1(3), // functions count
717 : 0, // signature index
718 : 0, // signature index
719 : 0, // signature index
720 : kCodeSectionCode, // section code
721 : U32V_1(20), // section size
722 : U32V_1(3), // functions count
723 4 : };
724 : tester.OnBytesReceived(bytes, arraysize(bytes));
725 : tester.OnBytesReceived(code, arraysize(code));
726 4 : tester.stream()->Abort();
727 4 : tester.RunCompilerTasks();
728 4 : }
729 :
730 : // Test Abort after all functions got compiled.
731 25883 : STREAM_TEST(TestAbortAfterCodeSection1) {
732 4 : StreamTester tester;
733 :
734 : uint8_t code[] = {
735 : U32V_1(4), // body size
736 : U32V_1(0), // locals count
737 : kExprGetLocal, 0, kExprEnd // body
738 4 : };
739 :
740 : const uint8_t bytes[] = {
741 : WASM_MODULE_HEADER, // module header
742 : kTypeSectionCode, // section code
743 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
744 : U32V_1(1), // type count
745 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
746 : kFunctionSectionCode, // section code
747 : U32V_1(1 + 3), // section size
748 : U32V_1(3), // functions count
749 : 0, // signature index
750 : 0, // signature index
751 : 0, // signature index
752 : kCodeSectionCode, // section code
753 : U32V_1(1 + arraysize(code) * 3), // section size
754 : U32V_1(3), // functions count
755 4 : };
756 :
757 : tester.OnBytesReceived(bytes, arraysize(bytes));
758 : tester.OnBytesReceived(code, arraysize(code));
759 : tester.OnBytesReceived(code, arraysize(code));
760 : tester.OnBytesReceived(code, arraysize(code));
761 4 : tester.RunCompilerTasks();
762 4 : tester.stream()->Abort();
763 4 : tester.RunCompilerTasks();
764 4 : }
765 :
766 : // Test Abort after all functions got compiled.
767 25883 : STREAM_TEST(TestAbortAfterCodeSection2) {
768 4 : StreamTester tester;
769 :
770 : uint8_t code[] = {
771 : U32V_1(4), // body size
772 : U32V_1(0), // locals count
773 : kExprGetLocal, 0, kExprEnd // body
774 4 : };
775 :
776 : const uint8_t bytes[] = {
777 : WASM_MODULE_HEADER, // module header
778 : kTypeSectionCode, // section code
779 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
780 : U32V_1(1), // type count
781 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
782 : kFunctionSectionCode, // section code
783 : U32V_1(1 + 3), // section size
784 : U32V_1(3), // functions count
785 : 0, // signature index
786 : 0, // signature index
787 : 0, // signature index
788 : kCodeSectionCode, // section code
789 : U32V_1(1 + arraysize(code) * 3), // section size
790 : U32V_1(3), // functions count
791 4 : };
792 :
793 : tester.OnBytesReceived(bytes, arraysize(bytes));
794 : tester.OnBytesReceived(code, arraysize(code));
795 : tester.OnBytesReceived(code, arraysize(code));
796 : tester.OnBytesReceived(code, arraysize(code));
797 4 : tester.stream()->Abort();
798 4 : tester.RunCompilerTasks();
799 4 : }
800 :
801 25883 : STREAM_TEST(TestAbortAfterCompilationError1) {
802 4 : StreamTester tester;
803 :
804 : uint8_t code[] = {
805 : U32V_1(4), // !!! invalid body size !!!
806 : U32V_1(0), // locals count
807 : kExprGetLocal, 0, kExprEnd // body
808 4 : };
809 :
810 : uint8_t invalid_code[] = {
811 : U32V_1(4), // !!! invalid body size !!!
812 : U32V_1(0), // locals count
813 : kExprI64Const, 0, kExprEnd // body
814 4 : };
815 :
816 : const uint8_t bytes[] = {
817 : WASM_MODULE_HEADER, // module header
818 : kTypeSectionCode, // section code
819 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
820 : U32V_1(1), // type count
821 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
822 : kFunctionSectionCode, // section code
823 : U32V_1(1 + 3), // section size
824 : U32V_1(3), // functions count
825 : 0, // signature index
826 : 0, // signature index
827 : 0, // signature index
828 : kCodeSectionCode, // section code
829 : U32V_1(1 + arraysize(code) * 2 +
830 : arraysize(invalid_code)), // section size
831 : U32V_1(3), // functions count
832 4 : };
833 :
834 : tester.OnBytesReceived(bytes, arraysize(bytes));
835 : tester.OnBytesReceived(code, arraysize(code));
836 : tester.OnBytesReceived(invalid_code, arraysize(invalid_code));
837 : tester.OnBytesReceived(code, arraysize(code));
838 4 : tester.RunCompilerTasks();
839 4 : tester.stream()->Abort();
840 4 : tester.RunCompilerTasks();
841 4 : }
842 :
843 25883 : STREAM_TEST(TestAbortAfterCompilationError2) {
844 4 : StreamTester tester;
845 :
846 : uint8_t code[] = {
847 : U32V_1(4), // !!! invalid body size !!!
848 : U32V_1(0), // locals count
849 : kExprGetLocal, 0, kExprEnd // body
850 4 : };
851 :
852 : uint8_t invalid_code[] = {
853 : U32V_1(4), // !!! invalid body size !!!
854 : U32V_1(0), // locals count
855 : kExprI64Const, 0, kExprEnd // body
856 4 : };
857 :
858 : const uint8_t bytes[] = {
859 : WASM_MODULE_HEADER, // module header
860 : kTypeSectionCode, // section code
861 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
862 : U32V_1(1), // type count
863 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
864 : kFunctionSectionCode, // section code
865 : U32V_1(1 + 3), // section size
866 : U32V_1(3), // functions count
867 : 0, // signature index
868 : 0, // signature index
869 : 0, // signature index
870 : kCodeSectionCode, // section code
871 : U32V_1(1 + arraysize(code) * 2 +
872 : arraysize(invalid_code)), // section size
873 : U32V_1(3), // functions count
874 4 : };
875 :
876 : tester.OnBytesReceived(bytes, arraysize(bytes));
877 : tester.OnBytesReceived(code, arraysize(code));
878 : tester.OnBytesReceived(invalid_code, arraysize(invalid_code));
879 : tester.OnBytesReceived(code, arraysize(code));
880 4 : tester.stream()->Abort();
881 4 : tester.RunCompilerTasks();
882 4 : }
883 :
884 25883 : STREAM_TEST(TestOnlyModuleHeader) {
885 4 : StreamTester tester;
886 :
887 : const uint8_t bytes[] = {
888 : WASM_MODULE_HEADER, // module header
889 4 : };
890 :
891 : tester.OnBytesReceived(bytes, arraysize(bytes));
892 : tester.FinishStream();
893 4 : tester.RunCompilerTasks();
894 :
895 4 : CHECK(tester.IsPromiseFulfilled());
896 4 : }
897 :
898 25883 : STREAM_TEST(TestModuleWithZeroFunctions) {
899 4 : StreamTester tester;
900 :
901 : const uint8_t bytes[] = {
902 : WASM_MODULE_HEADER, // module header
903 : kTypeSectionCode, // section code
904 : U32V_1(1), // section size
905 : U32V_1(0), // type count
906 : kFunctionSectionCode, // section code
907 : U32V_1(1), // section size
908 : U32V_1(0), // functions count
909 : kCodeSectionCode, // section code
910 : U32V_1(1), // section size
911 : U32V_1(0), // functions count
912 4 : };
913 :
914 : tester.OnBytesReceived(bytes, arraysize(bytes));
915 : tester.FinishStream();
916 4 : tester.RunCompilerTasks();
917 4 : CHECK(tester.IsPromiseFulfilled());
918 4 : }
919 :
920 25883 : STREAM_TEST(TestModuleWithMultipleFunctions) {
921 4 : StreamTester tester;
922 :
923 : uint8_t code[] = {
924 : U32V_1(4), // body size
925 : U32V_1(0), // locals count
926 : kExprGetLocal, 0, kExprEnd // body
927 4 : };
928 :
929 : const uint8_t bytes[] = {
930 : WASM_MODULE_HEADER, // module header
931 : kTypeSectionCode, // section code
932 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
933 : U32V_1(1), // type count
934 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
935 : kFunctionSectionCode, // section code
936 : U32V_1(1 + 3), // section size
937 : U32V_1(3), // functions count
938 : 0, // signature index
939 : 0, // signature index
940 : 0, // signature index
941 : kCodeSectionCode, // section code
942 : U32V_1(1 + arraysize(code) * 3), // section size
943 : U32V_1(3), // functions count
944 4 : };
945 :
946 : tester.OnBytesReceived(bytes, arraysize(bytes));
947 : tester.OnBytesReceived(code, arraysize(code));
948 : tester.OnBytesReceived(code, arraysize(code));
949 4 : tester.RunCompilerTasks();
950 : tester.OnBytesReceived(code, arraysize(code));
951 : tester.FinishStream();
952 4 : tester.RunCompilerTasks();
953 4 : CHECK(tester.IsPromiseFulfilled());
954 4 : }
955 :
956 25883 : STREAM_TEST(TestModuleWithDataSection) {
957 4 : StreamTester tester;
958 :
959 : uint8_t code[] = {
960 : U32V_1(4), // body size
961 : U32V_1(0), // locals count
962 : kExprGetLocal, 0, kExprEnd // body
963 4 : };
964 :
965 : const uint8_t bytes[] = {
966 : WASM_MODULE_HEADER, // module header
967 : kTypeSectionCode, // section code
968 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
969 : U32V_1(1), // type count
970 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
971 : kFunctionSectionCode, // section code
972 : U32V_1(1 + 3), // section size
973 : U32V_1(3), // functions count
974 : 0, // signature index
975 : 0, // signature index
976 : 0, // signature index
977 : kCodeSectionCode, // section code
978 : U32V_1(1 + arraysize(code) * 3), // section size
979 : U32V_1(3), // functions count
980 4 : };
981 :
982 : const uint8_t data_section[] = {
983 : kDataSectionCode, // section code
984 : U32V_1(1), // section size
985 : U32V_1(0), // data segment count
986 4 : };
987 : tester.OnBytesReceived(bytes, arraysize(bytes));
988 : tester.OnBytesReceived(code, arraysize(code));
989 : tester.OnBytesReceived(code, arraysize(code));
990 : tester.OnBytesReceived(code, arraysize(code));
991 4 : tester.RunCompilerTasks();
992 : tester.OnBytesReceived(data_section, arraysize(data_section));
993 4 : tester.RunCompilerTasks();
994 : tester.FinishStream();
995 4 : tester.RunCompilerTasks();
996 4 : CHECK(tester.IsPromiseFulfilled());
997 4 : }
998 : // Test that all bytes arrive before doing any compilation. FinishStream is
999 : // called immediately.
1000 25883 : STREAM_TEST(TestModuleWithImportedFunction) {
1001 4 : StreamTester tester;
1002 : ZoneBuffer buffer(tester.zone());
1003 4 : TestSignatures sigs;
1004 4 : WasmModuleBuilder builder(tester.zone());
1005 4 : builder.AddImport(ArrayVector("Test"), sigs.i_iii());
1006 : {
1007 4 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
1008 4 : uint8_t code[] = {kExprGetLocal, 0, kExprEnd};
1009 4 : f->EmitCode(code, arraysize(code));
1010 : }
1011 4 : builder.WriteTo(buffer);
1012 :
1013 4 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
1014 : tester.FinishStream();
1015 :
1016 4 : tester.RunCompilerTasks();
1017 :
1018 8 : CHECK(tester.IsPromiseFulfilled());
1019 4 : }
1020 :
1021 25883 : STREAM_TEST(TestModuleWithErrorAfterDataSection) {
1022 4 : StreamTester tester;
1023 :
1024 : const uint8_t bytes[] = {
1025 : WASM_MODULE_HEADER, // module header
1026 : kTypeSectionCode, // section code
1027 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
1028 : U32V_1(1), // type count
1029 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
1030 : kFunctionSectionCode, // section code
1031 : U32V_1(1 + 1), // section size
1032 : U32V_1(1), // functions count
1033 : 0, // signature index
1034 : kCodeSectionCode, // section code
1035 : U32V_1(6), // section size
1036 : U32V_1(1), // functions count
1037 : U32V_1(4), // body size
1038 : U32V_1(0), // locals count
1039 : kExprGetLocal, // some code
1040 : 0, // some code
1041 : kExprEnd, // some code
1042 : kDataSectionCode, // section code
1043 : U32V_1(1), // section size
1044 : U32V_1(0), // data segment count
1045 : kUnknownSectionCode, // section code
1046 : U32V_1(1), // invalid section size
1047 4 : };
1048 :
1049 : tester.OnBytesReceived(bytes, arraysize(bytes));
1050 : tester.FinishStream();
1051 4 : tester.RunCompilerTasks();
1052 4 : CHECK(tester.IsPromiseRejected());
1053 4 : }
1054 :
1055 : // Test that cached bytes work.
1056 25883 : STREAM_TEST(TestDeserializationBypassesCompilation) {
1057 4 : StreamTester tester;
1058 4 : ZoneBuffer wire_bytes = GetValidModuleBytes(tester.zone());
1059 : ZoneBuffer module_bytes =
1060 4 : GetValidCompiledModuleBytes(tester.zone(), wire_bytes);
1061 4 : tester.SetCompiledModuleBytes(module_bytes.begin(), module_bytes.size());
1062 4 : tester.OnBytesReceived(wire_bytes.begin(), wire_bytes.size());
1063 : tester.FinishStream();
1064 :
1065 4 : tester.RunCompilerTasks();
1066 :
1067 4 : CHECK(tester.IsPromiseFulfilled());
1068 4 : }
1069 :
1070 : // Test that bad cached bytes don't cause compilation of wire bytes to fail.
1071 25883 : STREAM_TEST(TestDeserializationFails) {
1072 4 : StreamTester tester;
1073 4 : ZoneBuffer wire_bytes = GetValidModuleBytes(tester.zone());
1074 : ZoneBuffer module_bytes =
1075 4 : GetValidCompiledModuleBytes(tester.zone(), wire_bytes);
1076 : // corrupt header
1077 4 : byte first_byte = *module_bytes.begin();
1078 4 : module_bytes.patch_u8(0, first_byte + 1);
1079 4 : tester.SetCompiledModuleBytes(module_bytes.begin(), module_bytes.size());
1080 4 : tester.OnBytesReceived(wire_bytes.begin(), wire_bytes.size());
1081 : tester.FinishStream();
1082 :
1083 4 : tester.RunCompilerTasks();
1084 :
1085 4 : CHECK(tester.IsPromiseFulfilled());
1086 4 : }
1087 :
1088 : // Test that a non-empty function section with a missing code section fails.
1089 25883 : STREAM_TEST(TestFunctionSectionWithoutCodeSection) {
1090 4 : StreamTester tester;
1091 :
1092 : const uint8_t bytes[] = {
1093 : WASM_MODULE_HEADER, // module header
1094 : kTypeSectionCode, // section code
1095 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
1096 : U32V_1(1), // type count
1097 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
1098 : kFunctionSectionCode, // section code
1099 : U32V_1(1 + 3), // section size
1100 : U32V_1(3), // functions count
1101 : 0, // signature index
1102 : 0, // signature index
1103 : 0, // signature index
1104 4 : };
1105 :
1106 : tester.OnBytesReceived(bytes, arraysize(bytes));
1107 : tester.FinishStream();
1108 :
1109 4 : tester.RunCompilerTasks();
1110 :
1111 4 : CHECK(tester.IsPromiseRejected());
1112 4 : }
1113 :
1114 25883 : STREAM_TEST(TestSetModuleCompiledCallback) {
1115 4 : StreamTester tester;
1116 4 : bool callback_called = false;
1117 : tester.stream()->SetModuleCompiledCallback(
1118 : [&callback_called](const std::shared_ptr<NativeModule> module) {
1119 4 : callback_called = true;
1120 8 : });
1121 :
1122 : uint8_t code[] = {
1123 : U32V_1(4), // body size
1124 : U32V_1(0), // locals count
1125 : kExprGetLocal, 0, kExprEnd // body
1126 4 : };
1127 :
1128 : const uint8_t bytes[] = {
1129 : WASM_MODULE_HEADER, // module header
1130 : kTypeSectionCode, // section code
1131 : U32V_1(1 + SIZEOF_SIG_ENTRY_x_x), // section size
1132 : U32V_1(1), // type count
1133 : SIG_ENTRY_x_x(kLocalI32, kLocalI32), // signature entry
1134 : kFunctionSectionCode, // section code
1135 : U32V_1(1 + 3), // section size
1136 : U32V_1(3), // functions count
1137 : 0, // signature index
1138 : 0, // signature index
1139 : 0, // signature index
1140 : kCodeSectionCode, // section code
1141 : U32V_1(1 + arraysize(code) * 3), // section size
1142 : U32V_1(3), // functions count
1143 4 : };
1144 :
1145 : tester.OnBytesReceived(bytes, arraysize(bytes));
1146 : tester.OnBytesReceived(code, arraysize(code));
1147 : tester.OnBytesReceived(code, arraysize(code));
1148 : tester.OnBytesReceived(code, arraysize(code));
1149 : tester.FinishStream();
1150 4 : tester.RunCompilerTasks();
1151 4 : CHECK(tester.IsPromiseFulfilled());
1152 4 : CHECK(callback_called);
1153 4 : }
1154 :
1155 : #undef STREAM_TEST
1156 :
1157 : } // namespace wasm
1158 : } // namespace internal
1159 77625 : } // namespace v8
|