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 350 : class MockPlatform final : public TestPlatform {
30 : public:
31 350 : MockPlatform() : task_runner_(std::make_shared<MockTaskRunner>()) {
32 : // Now that it's completely constructed, make this the current platform.
33 175 : i::V8::SetPlatformForTesting(this);
34 175 : }
35 :
36 489 : std::shared_ptr<TaskRunner> GetForegroundTaskRunner(
37 : v8::Isolate* isolate) override {
38 489 : 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 1206 : void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override {
46 2412 : task_runner_->PostTask(std::move(task));
47 1206 : }
48 :
49 0 : bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; }
50 :
51 365 : void ExecuteTasks() { task_runner_->ExecuteTasks(); }
52 :
53 : private:
54 700 : class MockTaskRunner final : public TaskRunner {
55 : public:
56 454 : void PostTask(std::unique_ptr<v8::Task> task) override {
57 : tasks_.push(std::move(task));
58 454 : }
59 :
60 0 : void PostDelayedTask(std::unique_ptr<Task> task,
61 : double delay_in_seconds) override {
62 0 : UNREACHABLE();
63 : };
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 365 : void ExecuteTasks() {
72 2390 : while (!tasks_.empty()) {
73 : std::unique_ptr<Task> task = std::move(tasks_.front());
74 : tasks_.pop();
75 1660 : task->Run();
76 : }
77 365 : }
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 370 : class TestResolver : public CompilationResultResolver {
96 : public:
97 : TestResolver(CompilationState* state,
98 : std::shared_ptr<NativeModule>* native_module)
99 185 : : state_(state), native_module_(native_module) {}
100 :
101 70 : void OnCompilationSucceeded(i::Handle<i::WasmModuleObject> module) override {
102 70 : *state_ = CompilationState::kFinished;
103 70 : if (!module.is_null()) {
104 140 : *native_module_ = module->shared_native_module();
105 : }
106 70 : }
107 :
108 60 : void OnCompilationFailed(i::Handle<i::Object> error_reason) override {
109 60 : *state_ = CompilationState::kFailed;
110 60 : }
111 :
112 : private:
113 : CompilationState* state_;
114 : std::shared_ptr<NativeModule>* native_module_;
115 : };
116 :
117 370 : class StreamTester {
118 : public:
119 185 : StreamTester()
120 : : zone_(&allocator_, "StreamTester"),
121 370 : internal_scope_(CcTest::i_isolate()) {
122 185 : v8::Isolate* isolate = CcTest::isolate();
123 : i::Isolate* i_isolate = CcTest::i_isolate();
124 :
125 185 : v8::Local<v8::Context> context = isolate->GetCurrentContext();
126 :
127 925 : stream_ = i_isolate->wasm_engine()->StartStreamingCompilation(
128 : i_isolate, kAllWasmFeatures, v8::Utils::OpenHandle(*context),
129 : std::make_shared<TestResolver>(&state_, &native_module_));
130 185 : }
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 365 : void RunCompilerTasks() {
139 365 : static_cast<MockPlatform*>(i::V8::GetCurrentPlatform())->ExecuteTasks();
140 365 : }
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 415 : stream_->OnBytesReceived(Vector<const uint8_t>(start, length));
150 : }
151 :
152 125 : void FinishStream() { stream_->Finish(); }
153 :
154 : void SetCompiledModuleBytes(const uint8_t* start, size_t length) {
155 10 : 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 45 : ZoneBuffer GetValidModuleBytes(Zone* zone) {
181 : ZoneBuffer buffer(zone);
182 45 : TestSignatures sigs;
183 45 : WasmModuleBuilder builder(zone);
184 : {
185 45 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
186 45 : uint8_t code[] = {kExprGetLocal, 0, kExprEnd};
187 45 : f->EmitCode(code, arraysize(code));
188 : }
189 : {
190 45 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
191 45 : uint8_t code[] = {kExprGetLocal, 1, kExprEnd};
192 45 : f->EmitCode(code, arraysize(code));
193 : }
194 : {
195 45 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
196 45 : uint8_t code[] = {kExprGetLocal, 2, kExprEnd};
197 45 : f->EmitCode(code, arraysize(code));
198 : }
199 45 : builder.WriteTo(buffer);
200 45 : return buffer;
201 : }
202 :
203 : // Create the same valid module as above and serialize it to test streaming
204 : // with compiled module caching.
205 10 : ZoneBuffer GetValidCompiledModuleBytes(Zone* zone, ZoneBuffer wire_bytes) {
206 : // Use a tester to compile to a NativeModule.
207 10 : StreamTester tester;
208 10 : tester.OnBytesReceived(wire_bytes.begin(), wire_bytes.size());
209 : tester.FinishStream();
210 10 : tester.RunCompilerTasks();
211 10 : CHECK(tester.IsPromiseFulfilled());
212 : // Serialize the NativeModule.
213 : std::shared_ptr<NativeModule> native_module = tester.native_module();
214 10 : CHECK(native_module);
215 10 : i::wasm::WasmSerializer serializer(native_module.get());
216 10 : size_t size = serializer.GetSerializedNativeModuleSize();
217 10 : std::vector<byte> buffer(size);
218 10 : CHECK(serializer.SerializeNativeModule({buffer.data(), size}));
219 : ZoneBuffer result(zone, size);
220 10 : result.write(buffer.data(), size);
221 10 : return result;
222 : }
223 :
224 : // Test that all bytes arrive before doing any compilation. FinishStream is
225 : // called immediately.
226 28347 : STREAM_TEST(TestAllBytesArriveImmediatelyStreamFinishesFirst) {
227 5 : StreamTester tester;
228 5 : ZoneBuffer buffer = GetValidModuleBytes(tester.zone());
229 :
230 5 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
231 : tester.FinishStream();
232 :
233 5 : tester.RunCompilerTasks();
234 :
235 5 : CHECK(tester.IsPromiseFulfilled());
236 5 : }
237 :
238 : // Test that all bytes arrive before doing any compilation. FinishStream is
239 : // called after the compilation is done.
240 28347 : STREAM_TEST(TestAllBytesArriveAOTCompilerFinishesFirst) {
241 5 : StreamTester tester;
242 5 : ZoneBuffer buffer = GetValidModuleBytes(tester.zone());
243 :
244 5 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
245 :
246 5 : tester.RunCompilerTasks();
247 : tester.FinishStream();
248 5 : tester.RunCompilerTasks();
249 :
250 5 : CHECK(tester.IsPromiseFulfilled());
251 5 : }
252 :
253 10 : 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 20 : isolate->counters(), isolate->allocator());
258 10 : CHECK(result.ok());
259 10 : const WasmFunction* func = &result.value()->functions[1];
260 10 : 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 28347 : STREAM_TEST(TestCutAfterOneFunctionStreamFinishesFirst) {
266 : i::Isolate* isolate = CcTest::i_isolate();
267 5 : StreamTester tester;
268 5 : ZoneBuffer buffer = GetValidModuleBytes(tester.zone());
269 :
270 5 : size_t offset = GetFunctionOffset(isolate, buffer.begin(), buffer.size(), 1);
271 : tester.OnBytesReceived(buffer.begin(), offset);
272 5 : tester.RunCompilerTasks();
273 5 : CHECK(tester.IsPromisePending());
274 5 : tester.OnBytesReceived(buffer.begin() + offset, buffer.size() - offset);
275 : tester.FinishStream();
276 5 : tester.RunCompilerTasks();
277 5 : CHECK(tester.IsPromiseFulfilled());
278 5 : }
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 28347 : STREAM_TEST(TestCutAfterOneFunctionCompilerFinishesFirst) {
284 : i::Isolate* isolate = CcTest::i_isolate();
285 5 : StreamTester tester;
286 5 : ZoneBuffer buffer = GetValidModuleBytes(tester.zone());
287 :
288 5 : size_t offset = GetFunctionOffset(isolate, buffer.begin(), buffer.size(), 1);
289 : tester.OnBytesReceived(buffer.begin(), offset);
290 5 : tester.RunCompilerTasks();
291 5 : CHECK(tester.IsPromisePending());
292 5 : tester.OnBytesReceived(buffer.begin() + offset, buffer.size() - offset);
293 5 : tester.RunCompilerTasks();
294 : tester.FinishStream();
295 5 : tester.RunCompilerTasks();
296 5 : CHECK(tester.IsPromiseFulfilled());
297 5 : }
298 :
299 : // Create a module with an invalid global section.
300 15 : ZoneBuffer GetModuleWithInvalidSection(Zone* zone) {
301 : ZoneBuffer buffer(zone);
302 15 : TestSignatures sigs;
303 15 : WasmModuleBuilder builder(zone);
304 : // Add an invalid global to the module. The decoder will fail there.
305 : builder.AddGlobal(kWasmStmt, false, true,
306 15 : WasmInitExpr(WasmInitExpr::kGlobalIndex, 12));
307 : {
308 15 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
309 15 : uint8_t code[] = {kExprGetLocal, 0, kExprEnd};
310 15 : f->EmitCode(code, arraysize(code));
311 : }
312 : {
313 15 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
314 15 : uint8_t code[] = {kExprGetLocal, 1, kExprEnd};
315 15 : f->EmitCode(code, arraysize(code));
316 : }
317 : {
318 15 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
319 15 : uint8_t code[] = {kExprGetLocal, 2, kExprEnd};
320 15 : f->EmitCode(code, arraysize(code));
321 : }
322 15 : builder.WriteTo(buffer);
323 15 : return buffer;
324 : }
325 :
326 : // Test an error in a section, found by the ModuleDecoder.
327 28347 : STREAM_TEST(TestErrorInSectionStreamFinishesFirst) {
328 5 : StreamTester tester;
329 5 : ZoneBuffer buffer = GetModuleWithInvalidSection(tester.zone());
330 :
331 5 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
332 : tester.FinishStream();
333 :
334 5 : tester.RunCompilerTasks();
335 :
336 5 : CHECK(tester.IsPromiseRejected());
337 5 : }
338 :
339 28347 : STREAM_TEST(TestErrorInSectionCompilerFinishesFirst) {
340 5 : StreamTester tester;
341 5 : ZoneBuffer buffer = GetModuleWithInvalidSection(tester.zone());
342 :
343 5 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
344 5 : tester.RunCompilerTasks();
345 : tester.FinishStream();
346 5 : tester.RunCompilerTasks();
347 :
348 5 : CHECK(tester.IsPromiseRejected());
349 5 : }
350 :
351 28347 : STREAM_TEST(TestErrorInSectionWithCuts) {
352 5 : StreamTester tester;
353 5 : ZoneBuffer buffer = GetModuleWithInvalidSection(tester.zone());
354 :
355 : const uint8_t* current = buffer.begin();
356 5 : size_t remaining = buffer.end() - buffer.begin();
357 50 : while (current < buffer.end()) {
358 80 : size_t size = std::min(remaining, size_t{10});
359 : tester.OnBytesReceived(current, size);
360 40 : tester.RunCompilerTasks();
361 40 : current += 10;
362 40 : remaining -= size;
363 : }
364 : tester.FinishStream();
365 5 : tester.RunCompilerTasks();
366 :
367 5 : CHECK(tester.IsPromiseRejected());
368 5 : }
369 :
370 15 : ZoneBuffer GetModuleWithInvalidSectionSize(Zone* zone) {
371 : // We get a valid module and overwrite the size of the first section with an
372 : // invalid value.
373 15 : ZoneBuffer buffer = GetValidModuleBytes(zone);
374 : // 9 == 4 (wasm magic) + 4 (version) + 1 (section code)
375 15 : uint8_t* section_size_address = const_cast<uint8_t*>(buffer.begin()) + 9;
376 : // 0x808080800F is an invalid module size in leb encoding.
377 15 : section_size_address[0] = 0x80;
378 15 : section_size_address[1] = 0x80;
379 15 : section_size_address[2] = 0x80;
380 15 : section_size_address[3] = 0x80;
381 15 : section_size_address[4] = 0x0F;
382 15 : return buffer;
383 : }
384 :
385 28347 : STREAM_TEST(TestErrorInSectionSizeStreamFinishesFirst) {
386 5 : StreamTester tester;
387 5 : ZoneBuffer buffer = GetModuleWithInvalidSectionSize(tester.zone());
388 5 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
389 : tester.FinishStream();
390 5 : tester.RunCompilerTasks();
391 :
392 5 : CHECK(tester.IsPromiseRejected());
393 5 : }
394 :
395 28347 : STREAM_TEST(TestErrorInSectionSizeCompilerFinishesFirst) {
396 5 : StreamTester tester;
397 5 : ZoneBuffer buffer = GetModuleWithInvalidSectionSize(tester.zone());
398 5 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
399 5 : tester.RunCompilerTasks();
400 : tester.FinishStream();
401 5 : tester.RunCompilerTasks();
402 :
403 5 : CHECK(tester.IsPromiseRejected());
404 5 : }
405 :
406 28347 : STREAM_TEST(TestErrorInSectionSizeWithCuts) {
407 5 : StreamTester tester;
408 5 : ZoneBuffer buffer = GetModuleWithInvalidSectionSize(tester.zone());
409 : const uint8_t* current = buffer.begin();
410 5 : size_t remaining = buffer.end() - buffer.begin();
411 45 : while (current < buffer.end()) {
412 70 : size_t size = std::min(remaining, size_t{10});
413 : tester.OnBytesReceived(current, size);
414 35 : tester.RunCompilerTasks();
415 35 : current += 10;
416 35 : remaining -= size;
417 : }
418 5 : tester.RunCompilerTasks();
419 : tester.FinishStream();
420 5 : tester.RunCompilerTasks();
421 :
422 5 : CHECK(tester.IsPromiseRejected());
423 5 : }
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 28347 : STREAM_TEST(TestErrorInCodeSectionDetectedByModuleDecoder) {
429 5 : 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 5 : };
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 5 : };
453 :
454 : tester.OnBytesReceived(bytes, arraysize(bytes));
455 : tester.OnBytesReceived(code, arraysize(code));
456 : tester.OnBytesReceived(code, arraysize(code));
457 : tester.FinishStream();
458 :
459 5 : tester.RunCompilerTasks();
460 :
461 5 : CHECK(tester.IsPromiseRejected());
462 5 : }
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 28347 : STREAM_TEST(TestErrorInCodeSectionDetectedByStreamingDecoder) {
468 5 : 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 5 : };
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 5 : };
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 5 : tester.RunCompilerTasks();
500 :
501 5 : CHECK(tester.IsPromiseRejected());
502 5 : }
503 :
504 : // Test an error in the code section, found by the Compiler. The error is an
505 : // invalid return type.
506 28347 : STREAM_TEST(TestErrorInCodeSectionDetectedByCompiler) {
507 5 : 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 5 : };
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 5 : };
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 5 : };
538 :
539 : tester.OnBytesReceived(bytes, arraysize(bytes));
540 5 : tester.RunCompilerTasks();
541 : tester.OnBytesReceived(code, arraysize(code));
542 5 : tester.RunCompilerTasks();
543 : tester.OnBytesReceived(invalid_code, arraysize(invalid_code));
544 5 : tester.RunCompilerTasks();
545 : tester.OnBytesReceived(code, arraysize(code));
546 5 : tester.RunCompilerTasks();
547 : tester.FinishStream();
548 5 : tester.RunCompilerTasks();
549 :
550 5 : CHECK(tester.IsPromiseRejected());
551 5 : }
552 :
553 : // Test Abort before any bytes arrive.
554 28347 : STREAM_TEST(TestAbortImmediately) {
555 5 : StreamTester tester;
556 5 : tester.stream()->Abort();
557 5 : tester.RunCompilerTasks();
558 5 : }
559 :
560 : // Test Abort within a section.
561 28347 : STREAM_TEST(TestAbortWithinSection1) {
562 5 : 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 5 : };
570 : tester.OnBytesReceived(bytes, arraysize(bytes));
571 5 : tester.RunCompilerTasks();
572 5 : tester.stream()->Abort();
573 5 : tester.RunCompilerTasks();
574 5 : }
575 :
576 : // Test Abort within a section.
577 28347 : STREAM_TEST(TestAbortWithinSection2) {
578 5 : 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 5 : };
590 : tester.OnBytesReceived(bytes, arraysize(bytes));
591 5 : tester.RunCompilerTasks();
592 5 : tester.stream()->Abort();
593 5 : tester.RunCompilerTasks();
594 5 : }
595 :
596 : // Test Abort just before the code section.
597 28347 : STREAM_TEST(TestAbortAfterSection) {
598 5 : 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 5 : };
606 : tester.OnBytesReceived(bytes, arraysize(bytes));
607 5 : tester.RunCompilerTasks();
608 5 : tester.stream()->Abort();
609 5 : tester.RunCompilerTasks();
610 5 : }
611 :
612 : // Test Abort after the function count in the code section. The compiler tasks
613 : // execute before the abort.
614 28347 : STREAM_TEST(TestAbortAfterFunctionsCount1) {
615 5 : 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 5 : };
632 : tester.OnBytesReceived(bytes, arraysize(bytes));
633 5 : tester.RunCompilerTasks();
634 5 : tester.stream()->Abort();
635 5 : tester.RunCompilerTasks();
636 5 : }
637 :
638 : // Test Abort after the function count in the code section. The compiler tasks
639 : // do not execute before the abort.
640 28347 : STREAM_TEST(TestAbortAfterFunctionsCount2) {
641 5 : 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 5 : };
658 : tester.OnBytesReceived(bytes, arraysize(bytes));
659 5 : tester.stream()->Abort();
660 5 : tester.RunCompilerTasks();
661 5 : }
662 :
663 : // Test Abort after some functions got compiled. The compiler tasks execute
664 : // before the abort.
665 28347 : STREAM_TEST(TestAbortAfterFunctionGotCompiled1) {
666 5 : 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 5 : };
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 5 : };
690 : tester.OnBytesReceived(bytes, arraysize(bytes));
691 : tester.OnBytesReceived(code, arraysize(code));
692 5 : tester.RunCompilerTasks();
693 5 : tester.stream()->Abort();
694 5 : tester.RunCompilerTasks();
695 5 : }
696 :
697 : // Test Abort after some functions got compiled. The compiler tasks execute
698 : // before the abort.
699 28347 : STREAM_TEST(TestAbortAfterFunctionGotCompiled2) {
700 5 : 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 5 : };
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 5 : };
724 : tester.OnBytesReceived(bytes, arraysize(bytes));
725 : tester.OnBytesReceived(code, arraysize(code));
726 5 : tester.stream()->Abort();
727 5 : tester.RunCompilerTasks();
728 5 : }
729 :
730 : // Test Abort after all functions got compiled.
731 28347 : STREAM_TEST(TestAbortAfterCodeSection1) {
732 5 : 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 5 : };
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 5 : };
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 5 : tester.RunCompilerTasks();
762 5 : tester.stream()->Abort();
763 5 : tester.RunCompilerTasks();
764 5 : }
765 :
766 : // Test Abort after all functions got compiled.
767 28347 : STREAM_TEST(TestAbortAfterCodeSection2) {
768 5 : 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 5 : };
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 5 : };
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 5 : tester.stream()->Abort();
798 5 : tester.RunCompilerTasks();
799 5 : }
800 :
801 28347 : STREAM_TEST(TestAbortAfterCompilationError1) {
802 5 : 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 5 : };
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 5 : };
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 5 : };
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 5 : tester.RunCompilerTasks();
839 5 : tester.stream()->Abort();
840 5 : tester.RunCompilerTasks();
841 5 : }
842 :
843 28347 : STREAM_TEST(TestAbortAfterCompilationError2) {
844 5 : 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 5 : };
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 5 : };
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 5 : };
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 5 : tester.stream()->Abort();
881 5 : tester.RunCompilerTasks();
882 5 : }
883 :
884 28347 : STREAM_TEST(TestOnlyModuleHeader) {
885 5 : StreamTester tester;
886 :
887 : const uint8_t bytes[] = {
888 : WASM_MODULE_HEADER, // module header
889 5 : };
890 :
891 : tester.OnBytesReceived(bytes, arraysize(bytes));
892 : tester.FinishStream();
893 5 : tester.RunCompilerTasks();
894 :
895 5 : CHECK(tester.IsPromiseFulfilled());
896 5 : }
897 :
898 28347 : STREAM_TEST(TestModuleWithZeroFunctions) {
899 5 : 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 5 : };
913 :
914 : tester.OnBytesReceived(bytes, arraysize(bytes));
915 : tester.FinishStream();
916 5 : tester.RunCompilerTasks();
917 5 : CHECK(tester.IsPromiseFulfilled());
918 5 : }
919 :
920 28347 : STREAM_TEST(TestModuleWithMultipleFunctions) {
921 5 : 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 5 : };
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 5 : };
945 :
946 : tester.OnBytesReceived(bytes, arraysize(bytes));
947 : tester.OnBytesReceived(code, arraysize(code));
948 : tester.OnBytesReceived(code, arraysize(code));
949 5 : tester.RunCompilerTasks();
950 : tester.OnBytesReceived(code, arraysize(code));
951 : tester.FinishStream();
952 5 : tester.RunCompilerTasks();
953 5 : CHECK(tester.IsPromiseFulfilled());
954 5 : }
955 :
956 28347 : STREAM_TEST(TestModuleWithDataSection) {
957 5 : 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 5 : };
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 5 : };
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 5 : };
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 5 : tester.RunCompilerTasks();
992 : tester.OnBytesReceived(data_section, arraysize(data_section));
993 5 : tester.RunCompilerTasks();
994 : tester.FinishStream();
995 5 : tester.RunCompilerTasks();
996 5 : CHECK(tester.IsPromiseFulfilled());
997 5 : }
998 : // Test that all bytes arrive before doing any compilation. FinishStream is
999 : // called immediately.
1000 28347 : STREAM_TEST(TestModuleWithImportedFunction) {
1001 5 : StreamTester tester;
1002 : ZoneBuffer buffer(tester.zone());
1003 5 : TestSignatures sigs;
1004 5 : WasmModuleBuilder builder(tester.zone());
1005 5 : builder.AddImport(ArrayVector("Test"), sigs.i_iii());
1006 : {
1007 5 : WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
1008 5 : uint8_t code[] = {kExprGetLocal, 0, kExprEnd};
1009 5 : f->EmitCode(code, arraysize(code));
1010 : }
1011 5 : builder.WriteTo(buffer);
1012 :
1013 5 : tester.OnBytesReceived(buffer.begin(), buffer.end() - buffer.begin());
1014 : tester.FinishStream();
1015 :
1016 5 : tester.RunCompilerTasks();
1017 :
1018 10 : CHECK(tester.IsPromiseFulfilled());
1019 5 : }
1020 :
1021 28347 : STREAM_TEST(TestModuleWithErrorAfterDataSection) {
1022 5 : 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 5 : };
1048 :
1049 : tester.OnBytesReceived(bytes, arraysize(bytes));
1050 : tester.FinishStream();
1051 5 : tester.RunCompilerTasks();
1052 5 : CHECK(tester.IsPromiseRejected());
1053 5 : }
1054 :
1055 : // Test that cached bytes work.
1056 28347 : STREAM_TEST(TestDeserializationBypassesCompilation) {
1057 5 : StreamTester tester;
1058 5 : ZoneBuffer wire_bytes = GetValidModuleBytes(tester.zone());
1059 : ZoneBuffer module_bytes =
1060 5 : GetValidCompiledModuleBytes(tester.zone(), wire_bytes);
1061 5 : tester.SetCompiledModuleBytes(module_bytes.begin(), module_bytes.size());
1062 5 : tester.OnBytesReceived(wire_bytes.begin(), wire_bytes.size());
1063 : tester.FinishStream();
1064 :
1065 5 : tester.RunCompilerTasks();
1066 :
1067 5 : CHECK(tester.IsPromiseFulfilled());
1068 5 : }
1069 :
1070 : // Test that bad cached bytes don't cause compilation of wire bytes to fail.
1071 28347 : STREAM_TEST(TestDeserializationFails) {
1072 5 : StreamTester tester;
1073 5 : ZoneBuffer wire_bytes = GetValidModuleBytes(tester.zone());
1074 : ZoneBuffer module_bytes =
1075 5 : GetValidCompiledModuleBytes(tester.zone(), wire_bytes);
1076 : // corrupt header
1077 5 : byte first_byte = *module_bytes.begin();
1078 5 : module_bytes.patch_u8(0, first_byte + 1);
1079 5 : tester.SetCompiledModuleBytes(module_bytes.begin(), module_bytes.size());
1080 5 : tester.OnBytesReceived(wire_bytes.begin(), wire_bytes.size());
1081 : tester.FinishStream();
1082 :
1083 5 : tester.RunCompilerTasks();
1084 :
1085 5 : CHECK(tester.IsPromiseFulfilled());
1086 5 : }
1087 :
1088 : // Test that a non-empty function section with a missing code section fails.
1089 28347 : STREAM_TEST(TestFunctionSectionWithoutCodeSection) {
1090 5 : 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 5 : };
1105 :
1106 : tester.OnBytesReceived(bytes, arraysize(bytes));
1107 : tester.FinishStream();
1108 :
1109 5 : tester.RunCompilerTasks();
1110 :
1111 5 : CHECK(tester.IsPromiseRejected());
1112 5 : }
1113 :
1114 28347 : STREAM_TEST(TestSetModuleCompiledCallback) {
1115 5 : StreamTester tester;
1116 5 : bool callback_called = false;
1117 : tester.stream()->SetModuleCompiledCallback(
1118 : [&callback_called](const std::shared_ptr<NativeModule> module) {
1119 5 : callback_called = true;
1120 10 : });
1121 :
1122 : uint8_t code[] = {
1123 : U32V_1(4), // body size
1124 : U32V_1(0), // locals count
1125 : kExprGetLocal, 0, kExprEnd // body
1126 5 : };
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 5 : };
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 5 : tester.RunCompilerTasks();
1151 5 : CHECK(tester.IsPromiseFulfilled());
1152 5 : CHECK(callback_called);
1153 5 : }
1154 :
1155 : #undef STREAM_TEST
1156 :
1157 : } // namespace wasm
1158 : } // namespace internal
1159 85011 : } // namespace v8
|