LCOV - code coverage report
Current view: top level - test/cctest/wasm - test-streaming-compilation.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 330 339 97.3 %
Date: 2019-04-18 Functions: 90 100 90.0 %

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

Generated by: LCOV version 1.10