LCOV - code coverage report
Current view: top level - test/cctest/wasm - test-streaming-compilation.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 385 394 97.7 %
Date: 2019-01-20 Functions: 90 99 90.9 %

          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

Generated by: LCOV version 1.10