|  | // Copyright 2019 the V8 project authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "test/wasm-api-tests/wasm-api-test.h" | 
|  |  | 
|  | namespace v8 { | 
|  | namespace internal { | 
|  | namespace wasm { | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | int g_instances_finalized = 0; | 
|  | int g_functions_finalized = 0; | 
|  | int g_foreigns_finalized = 0; | 
|  | int g_modules_finalized = 0; | 
|  |  | 
|  | void FinalizeInstance(void* data) { | 
|  | int iteration = static_cast<int>(reinterpret_cast<intptr_t>(data)); | 
|  | g_instances_finalized += iteration; | 
|  | } | 
|  |  | 
|  | void FinalizeFunction(void* data) { | 
|  | int iteration = static_cast<int>(reinterpret_cast<intptr_t>(data)); | 
|  | g_functions_finalized += iteration; | 
|  | } | 
|  |  | 
|  | void FinalizeForeign(void* data) { | 
|  | int iteration = static_cast<int>(reinterpret_cast<intptr_t>(data)); | 
|  | g_foreigns_finalized += iteration; | 
|  | } | 
|  |  | 
|  | void FinalizeModule(void* data) { | 
|  | g_modules_finalized += static_cast<int>(reinterpret_cast<intptr_t>(data)); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | TEST_F(WasmCapiTest, InstanceFinalization) { | 
|  | // Add a dummy function: f(x) { return x; } | 
|  | byte code[] = {WASM_RETURN1(WASM_GET_LOCAL(0))}; | 
|  | AddExportedFunction(CStrVector("f"), code, sizeof(code), wasm_i_i_sig()); | 
|  | Compile(); | 
|  | g_instances_finalized = 0; | 
|  | g_functions_finalized = 0; | 
|  | g_foreigns_finalized = 0; | 
|  | g_modules_finalized = 0; | 
|  | module()->set_host_info(reinterpret_cast<void*>(42), &FinalizeModule); | 
|  | static const int kIterations = 10; | 
|  | for (int iteration = 0; iteration < kIterations; iteration++) { | 
|  | void* finalizer_data = reinterpret_cast<void*>(iteration); | 
|  | own<Instance*> instance = Instance::make(store(), module(), nullptr); | 
|  | EXPECT_NE(nullptr, instance.get()); | 
|  | instance->set_host_info(finalizer_data, &FinalizeInstance); | 
|  |  | 
|  | own<Func*> func = instance->exports()[0]->func()->copy(); | 
|  | ASSERT_NE(func, nullptr); | 
|  | func->set_host_info(finalizer_data, &FinalizeFunction); | 
|  |  | 
|  | own<Foreign*> foreign = Foreign::make(store()); | 
|  | foreign->set_host_info(finalizer_data, &FinalizeForeign); | 
|  | } | 
|  | Shutdown(); | 
|  | // Verify that (1) all finalizers were called, and (2) they passed the | 
|  | // correct host data: the loop above sets {i} as data, and the finalizer | 
|  | // callbacks add them all up, so the expected value is | 
|  | // sum([0, 1, ..., kIterations - 1]), which per Gauss's formula is: | 
|  | static const int kExpected = (kIterations * (kIterations - 1)) / 2; | 
|  | EXPECT_EQ(g_instances_finalized, kExpected); | 
|  | EXPECT_EQ(g_functions_finalized, kExpected); | 
|  | EXPECT_EQ(g_foreigns_finalized, kExpected); | 
|  | EXPECT_EQ(g_modules_finalized, 42); | 
|  | } | 
|  |  | 
|  | }  // namespace wasm | 
|  | }  // namespace internal | 
|  | }  // namespace v8 |