Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: test/cctest/wasm/test-run-wasm-module.cc

Issue 2420373002: [wasm] Test deserialized module still has bytes, + negative test (Closed)
Patch Set: [wasm] Test deserialized module still has bytes, + negative test Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/api.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <string.h> 6 #include <string.h>
7 7
8 #include "src/snapshot/code-serializer.h" 8 #include "src/snapshot/code-serializer.h"
9 #include "src/version.h" 9 #include "src/version.h"
10 #include "src/wasm/module-decoder.h" 10 #include "src/wasm/module-decoder.h"
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 f1->EmitCode(code1, sizeof(code1)); 166 f1->EmitCode(code1, sizeof(code1));
167 WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v()); 167 WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v());
168 ExportAsMain(f2); 168 ExportAsMain(f2);
169 byte code2[] = {WASM_SET_GLOBAL(global1, WASM_I32V_1(56)), 169 byte code2[] = {WASM_SET_GLOBAL(global1, WASM_I32V_1(56)),
170 WASM_SET_GLOBAL(global2, WASM_I32V_1(41)), 170 WASM_SET_GLOBAL(global2, WASM_I32V_1(41)),
171 WASM_RETURN1(WASM_CALL_FUNCTION0(f1->func_index()))}; 171 WASM_RETURN1(WASM_CALL_FUNCTION0(f1->func_index()))};
172 f2->EmitCode(code2, sizeof(code2)); 172 f2->EmitCode(code2, sizeof(code2));
173 TestModule(&zone, builder, 97); 173 TestModule(&zone, builder, 97);
174 } 174 }
175 175
176 TEST(Run_WasmModule_Serialization) { 176 // Approximate gtest TEST_F style, in case we adopt gtest.
177 static const char* kFunctionName = "increment"; 177 class WasmSerializationTest {
178 v8::internal::AccountingAllocator allocator; 178 public:
179 Zone zone(&allocator, ZONE_NAME); 179 WasmSerializationTest() : zone_(&allocator_, ZONE_NAME) {
180 180 // Don't call here if we move to gtest.
181 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); 181 SetUp();
182 TestSignatures sigs;
183
184 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
185 byte code[] = {WASM_GET_LOCAL(0), kExprI32Const, 1, kExprI32Add};
186 f->EmitCode(code, sizeof(code));
187 f->ExportAs(CStrVector(kFunctionName));
188
189 ZoneBuffer buffer(&zone);
190 builder->WriteTo(buffer);
191
192 Isolate* isolate = CcTest::InitIsolateOnce();
193 ErrorThrower thrower(isolate, "");
194 uint8_t* bytes = nullptr;
195 size_t bytes_size = 0;
196 v8::WasmCompiledModule::SerializedModule data;
197 {
198 HandleScope scope(isolate);
199 testing::SetupIsolateForWasmModule(isolate);
200
201 ModuleResult decoding_result = DecodeWasmModule(
202 isolate, &zone, buffer.begin(), buffer.end(), false, kWasmOrigin);
203 std::unique_ptr<const WasmModule> module(decoding_result.val);
204 CHECK(!decoding_result.failed());
205
206 MaybeHandle<WasmCompiledModule> compiled_module =
207 module->CompileFunctions(isolate, &thrower);
208 CHECK(!compiled_module.is_null());
209 Handle<JSObject> module_obj = CreateCompiledModuleObject(
210 isolate, compiled_module.ToHandleChecked(), ModuleOrigin::kWasmOrigin);
211 v8::Local<v8::Object> v8_module_obj = v8::Utils::ToLocal(module_obj);
212 CHECK(v8_module_obj->IsWebAssemblyCompiledModule());
213
214 v8::Local<v8::WasmCompiledModule> v8_compiled_module =
215 v8_module_obj.As<v8::WasmCompiledModule>();
216 v8::Local<v8::String> uncompiled_bytes =
217 v8_compiled_module->GetWasmWireBytes();
218 bytes_size = static_cast<size_t>(uncompiled_bytes->Length());
219 bytes = zone.NewArray<uint8_t>(uncompiled_bytes->Length());
220 uncompiled_bytes->WriteOneByte(bytes);
221 data = v8_compiled_module->Serialize();
222 } 182 }
223 183
224 v8::WasmCompiledModule::CallerOwnedBuffer wire_bytes = { 184 void ClearSerializedData() {
225 const_cast<const uint8_t*>(bytes), bytes_size}; 185 serialized_bytes_.first = nullptr;
186 serialized_bytes_.second = 0;
187 }
226 188
227 v8::WasmCompiledModule::CallerOwnedBuffer serialized_bytes = { 189 void InvalidateVersion() {
228 data.first.get(), data.second}; 190 uint32_t* buffer = reinterpret_cast<uint32_t*>(
229 v8::Isolate::CreateParams create_params; 191 const_cast<uint8_t*>(serialized_bytes_.first));
230 create_params.array_buffer_allocator = 192 buffer[SerializedCodeData::kVersionHashOffset] = Version::Hash() + 1;
231 CcTest::InitIsolateOnce()->array_buffer_allocator(); 193 }
232 194
233 for (int i = 0; i < 3; ++i) { 195 void InvalidateWireBytes() {
234 v8::Isolate* v8_isolate = v8::Isolate::New(create_params); 196 memset(const_cast<uint8_t*>(wire_bytes_.first), '\0',
235 if (i == 1) { 197 wire_bytes_.second / 2);
236 // Invalidate the header by providing a mismatched version 198 }
237 uint32_t* buffer = reinterpret_cast<uint32_t*>( 199
238 const_cast<uint8_t*>(serialized_bytes.first)); 200 v8::MaybeLocal<v8::WasmCompiledModule> Deserialize() {
239 buffer[SerializedCodeData::kVersionHashOffset] = Version::Hash() + 1; 201 ErrorThrower thrower(current_isolate(), "");
202 v8::MaybeLocal<v8::WasmCompiledModule> deserialized =
203 v8::WasmCompiledModule::DeserializeOrCompile(
204 current_isolate_v8(), serialized_bytes(), wire_bytes());
205 return deserialized;
206 }
207
208 void DeserializeAndRun() {
209 ErrorThrower thrower(current_isolate(), "");
210 v8::Local<v8::WasmCompiledModule> deserialized_module;
211 CHECK(Deserialize().ToLocal(&deserialized_module));
212 Handle<JSObject> module_object =
213 Handle<JSObject>::cast(v8::Utils::OpenHandle(*deserialized_module));
214 {
215 DisallowHeapAllocation assume_no_gc;
216 Handle<WasmCompiledModule> compiled_part(
217 WasmCompiledModule::cast(module_object->GetInternalField(0)),
218 current_isolate());
219 CHECK_EQ(memcmp(compiled_part->module_bytes()->GetCharsAddress(),
220 wire_bytes().first, wire_bytes().second),
221 0);
222 }
223 Handle<JSObject> instance =
224 WasmModule::Instantiate(current_isolate(), &thrower, module_object,
225 Handle<JSReceiver>::null(),
226 Handle<JSArrayBuffer>::null())
227 .ToHandleChecked();
228 Handle<Object> params[1] = {
229 Handle<Object>(Smi::FromInt(41), current_isolate())};
230 int32_t result = testing::CallWasmFunctionForTesting(
231 current_isolate(), instance, &thrower, kFunctionName, 1, params,
232 ModuleOrigin::kWasmOrigin);
233 CHECK(result == 42);
234 }
235
236 Isolate* current_isolate() {
237 return reinterpret_cast<Isolate*>(current_isolate_v8_);
238 }
239
240 ~WasmSerializationTest() {
241 // Don't call from here if we move to gtest
242 TearDown();
243 }
244
245 private:
246 static const char* kFunctionName;
247
248 Zone* zone() { return &zone_; }
249 const v8::WasmCompiledModule::CallerOwnedBuffer& wire_bytes() const {
250 return wire_bytes_;
251 }
252
253 const v8::WasmCompiledModule::CallerOwnedBuffer& serialized_bytes() const {
254 return serialized_bytes_;
255 }
256
257 v8::Isolate* current_isolate_v8() { return current_isolate_v8_; }
258
259 void SetUp() {
260 WasmModuleBuilder* builder = new (zone()) WasmModuleBuilder(zone());
261 TestSignatures sigs;
262
263 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
264 byte code[] = {WASM_GET_LOCAL(0), kExprI32Const, 1, kExprI32Add};
265 f->EmitCode(code, sizeof(code));
266 f->ExportAs(CStrVector(kFunctionName));
267
268 ZoneBuffer buffer(&zone_);
269 builder->WriteTo(buffer);
270
271 Isolate* serialization_isolate = CcTest::InitIsolateOnce();
272 ErrorThrower thrower(serialization_isolate, "");
273 uint8_t* bytes = nullptr;
274 size_t bytes_size = 0;
275 {
276 HandleScope scope(serialization_isolate);
277 testing::SetupIsolateForWasmModule(serialization_isolate);
278
279 ModuleResult decoding_result =
280 DecodeWasmModule(serialization_isolate, zone(), buffer.begin(),
281 buffer.end(), false, kWasmOrigin);
282 std::unique_ptr<const WasmModule> module(decoding_result.val);
283 CHECK(!decoding_result.failed());
284
285 MaybeHandle<WasmCompiledModule> compiled_module =
286 module->CompileFunctions(serialization_isolate, &thrower);
287 CHECK(!compiled_module.is_null());
288 Handle<JSObject> module_obj = CreateCompiledModuleObject(
289 serialization_isolate, compiled_module.ToHandleChecked(),
290 ModuleOrigin::kWasmOrigin);
291 v8::Local<v8::Object> v8_module_obj = v8::Utils::ToLocal(module_obj);
292 CHECK(v8_module_obj->IsWebAssemblyCompiledModule());
293
294 v8::Local<v8::WasmCompiledModule> v8_compiled_module =
295 v8_module_obj.As<v8::WasmCompiledModule>();
296 v8::Local<v8::String> uncompiled_bytes =
297 v8_compiled_module->GetWasmWireBytes();
298 bytes_size = static_cast<size_t>(uncompiled_bytes->Length());
299 bytes = zone()->NewArray<uint8_t>(uncompiled_bytes->Length());
300 uncompiled_bytes->WriteOneByte(bytes);
301 // keep alive data_ until the end
302 data_ = v8_compiled_module->Serialize();
240 } 303 }
241 304
242 if (i == 2) { 305 wire_bytes_ = {const_cast<const uint8_t*>(bytes), bytes_size};
243 // Provide no serialized data to force recompilation. 306
244 serialized_bytes.first = nullptr; 307 serialized_bytes_ = {data_.first.get(), data_.second};
245 serialized_bytes.second = 0; 308
246 } 309 v8::Isolate::CreateParams create_params;
247 { 310 create_params.array_buffer_allocator =
248 v8::Isolate::Scope isolate_scope(v8_isolate); 311 serialization_isolate->array_buffer_allocator();
249 v8::HandleScope new_scope(v8_isolate); 312
250 v8::Local<v8::Context> new_ctx = v8::Context::New(v8_isolate); 313 current_isolate_v8_ = v8::Isolate::New(create_params);
251 new_ctx->Enter(); 314 v8::HandleScope new_scope(current_isolate_v8());
252 isolate = reinterpret_cast<Isolate*>(v8_isolate); 315 v8::Local<v8::Context> deserialization_context =
253 testing::SetupIsolateForWasmModule(isolate); 316 v8::Context::New(current_isolate_v8());
254 v8::MaybeLocal<v8::WasmCompiledModule> deserialized = 317 deserialization_context->Enter();
255 v8::WasmCompiledModule::DeserializeOrCompile( 318 testing::SetupIsolateForWasmModule(current_isolate());
256 v8_isolate, serialized_bytes, wire_bytes);
257 v8::Local<v8::WasmCompiledModule> compiled_module;
258 CHECK(deserialized.ToLocal(&compiled_module));
259 Handle<JSObject> module_object =
260 Handle<JSObject>::cast(v8::Utils::OpenHandle(*compiled_module));
261 Handle<JSObject> instance =
262 WasmModule::Instantiate(isolate, &thrower, module_object,
263 Handle<JSReceiver>::null(),
264 Handle<JSArrayBuffer>::null())
265 .ToHandleChecked();
266 Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(41), isolate)};
267 int32_t result = testing::CallWasmFunctionForTesting(
268 isolate, instance, &thrower, kFunctionName, 1, params,
269 ModuleOrigin::kWasmOrigin);
270 CHECK(result == 42);
271 new_ctx->Exit();
272 }
273 v8_isolate->Dispose();
274 } 319 }
320
321 void TearDown() {
322 current_isolate_v8()->Dispose();
323 current_isolate_v8_ = nullptr;
324 }
325
326 v8::internal::AccountingAllocator allocator_;
327 Zone zone_;
328 v8::WasmCompiledModule::SerializedModule data_;
329 v8::WasmCompiledModule::CallerOwnedBuffer wire_bytes_;
330 v8::WasmCompiledModule::CallerOwnedBuffer serialized_bytes_;
331 v8::Isolate* current_isolate_v8_;
332 };
333
334 const char* WasmSerializationTest::kFunctionName = "increment";
335
336 TEST(DeserializeValidModule) {
337 WasmSerializationTest test;
338 HandleScope scope(test.current_isolate());
339 test.DeserializeAndRun();
340 }
341
342 TEST(DeserializeMismatchingVersion) {
343 WasmSerializationTest test;
344 HandleScope scope(test.current_isolate());
345 test.InvalidateVersion();
346 test.DeserializeAndRun();
347 }
348
349 TEST(DeserializeNoSerializedData) {
350 WasmSerializationTest test;
351 HandleScope scope(test.current_isolate());
352 test.ClearSerializedData();
353 test.DeserializeAndRun();
354 }
355
356 TEST(DeserializeWireBytesAndSerializedDataInvalid) {
357 WasmSerializationTest test;
358 HandleScope scope(test.current_isolate());
359 test.InvalidateVersion();
360 test.InvalidateWireBytes();
361 test.Deserialize();
275 } 362 }
276 363
277 TEST(MemorySize) { 364 TEST(MemorySize) {
278 // Initial memory size is 16, see wasm-module-builder.cc 365 // Initial memory size is 16, see wasm-module-builder.cc
279 static const int kExpectedValue = 16; 366 static const int kExpectedValue = 16;
280 TestSignatures sigs; 367 TestSignatures sigs;
281 v8::internal::AccountingAllocator allocator; 368 v8::internal::AccountingAllocator allocator;
282 Zone zone(&allocator, ZONE_NAME); 369 Zone zone(&allocator, ZONE_NAME);
283 370
284 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); 371 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 706
620 TEST(Run_WasmModule_Global_f32) { 707 TEST(Run_WasmModule_Global_f32) {
621 RunWasmModuleGlobalInitTest<float>(kAstF32, -983.9f); 708 RunWasmModuleGlobalInitTest<float>(kAstF32, -983.9f);
622 RunWasmModuleGlobalInitTest<float>(kAstF32, 1122.99f); 709 RunWasmModuleGlobalInitTest<float>(kAstF32, 1122.99f);
623 } 710 }
624 711
625 TEST(Run_WasmModule_Global_f64) { 712 TEST(Run_WasmModule_Global_f64) {
626 RunWasmModuleGlobalInitTest<double>(kAstF64, -833.9); 713 RunWasmModuleGlobalInitTest<double>(kAstF64, -833.9);
627 RunWasmModuleGlobalInitTest<double>(kAstF64, 86374.25); 714 RunWasmModuleGlobalInitTest<double>(kAstF64, 86374.25);
628 } 715 }
OLDNEW
« no previous file with comments | « src/api.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698