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

Side by Side Diff: src/wasm/wasm-js.cc

Issue 2367673003: [wasm] Do a proper HasProperty() check in the memory and table setup. (Closed)
Patch Set: Added tests also to table.js 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 | « no previous file | test/mjsunit/wasm/memory.js » ('j') | 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 "src/api-natives.h" 5 #include "src/api-natives.h"
6 #include "src/api.h" 6 #include "src/api.h"
7 #include "src/asmjs/asm-js.h" 7 #include "src/asmjs/asm-js.h"
8 #include "src/asmjs/asm-typer.h" 8 #include "src/asmjs/asm-typer.h"
9 #include "src/asmjs/asm-wasm-builder.h" 9 #include "src/asmjs/asm-wasm-builder.h"
10 #include "src/assert-scope.h" 10 #include "src/assert-scope.h"
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 305 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
306 return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); 306 return_value.Set(Utils::ToLocal(instance.ToHandleChecked()));
307 } 307 }
308 308
309 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, 309 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
310 Local<Context> context, Local<v8::Object> object, 310 Local<Context> context, Local<v8::Object> object,
311 Local<String> property, int* result, int lower_bound, 311 Local<String> property, int* result, int lower_bound,
312 int upper_bound) { 312 int upper_bound) {
313 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); 313 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property);
314 v8::Local<v8::Value> value; 314 v8::Local<v8::Value> value;
315 if (maybe.ToLocal(&value) && !value->IsUndefined()) { 315 if (maybe.ToLocal(&value)) {
316 int64_t number; 316 int64_t number;
317 if (!value->IntegerValue(context).To(&number)) return false; 317 if (!value->IntegerValue(context).To(&number)) return false;
318 if (number < static_cast<int64_t>(lower_bound)) { 318 if (number < static_cast<int64_t>(lower_bound)) {
319 thrower->RangeError("Property value %" PRId64 319 thrower->RangeError("Property value %" PRId64
320 " is below the lower bound %d", 320 " is below the lower bound %d",
321 number, lower_bound); 321 number, lower_bound);
322 return false; 322 return false;
323 } 323 }
324 if (number > static_cast<int64_t>(std::numeric_limits<int>::max())) { 324 if (number > static_cast<int64_t>(upper_bound)) {
325 thrower->RangeError("Property value %" PRId64 " is out of integer range",
326 number);
327 return false;
328 }
329 int num = static_cast<int>(number);
330 if (num > upper_bound) {
331 thrower->RangeError("Property value %" PRId64 325 thrower->RangeError("Property value %" PRId64
332 " is above the upper bound %d", 326 " is above the upper bound %d",
333 number, upper_bound); 327 number, upper_bound);
334 return false; 328 return false;
335 } 329 }
336 *result = num; 330 *result = static_cast<int>(number);
337 return true; 331 return true;
338 } 332 }
339 return false; 333 return false;
340 } 334 }
341 335
342 void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { 336 void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
343 v8::Isolate* isolate = args.GetIsolate(); 337 v8::Isolate* isolate = args.GetIsolate();
344 HandleScope scope(isolate); 338 HandleScope scope(isolate);
345 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 339 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
346 "WebAssembly.Module()"); 340 "WebAssembly.Module()");
(...skipping 21 matching lines...) Expand all
368 const int max_table_size = 1 << 26; 362 const int max_table_size = 1 << 26;
369 // The descriptor's 'initial'. 363 // The descriptor's 'initial'.
370 int initial; 364 int initial;
371 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, 365 if (!GetIntegerProperty(isolate, &thrower, context, descriptor,
372 v8_str(isolate, "initial"), &initial, 0, 366 v8_str(isolate, "initial"), &initial, 0,
373 max_table_size)) { 367 max_table_size)) {
374 return; 368 return;
375 } 369 }
376 // The descriptor's 'maximum'. 370 // The descriptor's 'maximum'.
377 int maximum; 371 int maximum;
378 bool has_maximum = true; 372 Local<String> maximum_key = v8_str(isolate, "maximum");
379 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, 373 Maybe<bool> has_maximum = descriptor->Has(context, maximum_key);
380 v8_str(isolate, "maximum"), &maximum, initial, 374
381 max_table_size)) { 375 if (has_maximum.IsNothing()) {
382 if (reinterpret_cast<i::Isolate*>(isolate)->has_pending_exception() || 376 // There has been an exception, just return.
383 thrower.error()) { 377 return;
378 }
379 if (has_maximum.FromJust()) {
380 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key,
381 &maximum, initial, max_table_size)) {
384 return; 382 return;
385 } else {
386 // There was no error, the property just does not exist.
387 has_maximum = false;
388 } 383 }
389 } 384 }
390 385
391 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 386 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
392 i::Handle<i::JSFunction> table_cons( 387 i::Handle<i::JSFunction> table_cons(
393 i_isolate->native_context()->wasm_table_constructor()); 388 i_isolate->native_context()->wasm_table_constructor());
394 i::Handle<i::JSObject> table_obj = 389 i::Handle<i::JSObject> table_obj =
395 i_isolate->factory()->NewJSObject(table_cons); 390 i_isolate->factory()->NewJSObject(table_cons);
396 i::Handle<i::FixedArray> fixed_array = 391 i::Handle<i::FixedArray> fixed_array =
397 i_isolate->factory()->NewFixedArray(initial); 392 i_isolate->factory()->NewFixedArray(initial);
398 i::Object* null = i_isolate->heap()->null_value(); 393 i::Object* null = i_isolate->heap()->null_value();
399 for (int i = 0; i < initial; ++i) fixed_array->set(i, null); 394 for (int i = 0; i < initial; ++i) fixed_array->set(i, null);
400 table_obj->SetInternalField(0, *fixed_array); 395 table_obj->SetInternalField(0, *fixed_array);
401 table_obj->SetInternalField( 396 table_obj->SetInternalField(
402 1, has_maximum 397 1, has_maximum.FromJust()
403 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) 398 ? static_cast<i::Object*>(i::Smi::FromInt(maximum))
404 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); 399 : static_cast<i::Object*>(i_isolate->heap()->undefined_value()));
405 i::Handle<i::Symbol> table_sym(i_isolate->native_context()->wasm_table_sym()); 400 i::Handle<i::Symbol> table_sym(i_isolate->native_context()->wasm_table_sym());
406 i::Object::SetProperty(table_obj, table_sym, table_obj, i::STRICT).Check(); 401 i::Object::SetProperty(table_obj, table_sym, table_obj, i::STRICT).Check();
407 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 402 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
408 return_value.Set(Utils::ToLocal(table_obj)); 403 return_value.Set(Utils::ToLocal(table_obj));
409 } 404 }
410 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { 405 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
411 v8::Isolate* isolate = args.GetIsolate(); 406 v8::Isolate* isolate = args.GetIsolate();
412 HandleScope scope(isolate); 407 HandleScope scope(isolate);
413 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 408 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
414 "WebAssembly.Module()"); 409 "WebAssembly.Module()");
415 if (args.Length() < 1 || !args[0]->IsObject()) { 410 if (args.Length() < 1 || !args[0]->IsObject()) {
416 thrower.TypeError("Argument 0 must be a table descriptor"); 411 thrower.TypeError("Argument 0 must be a table descriptor");
417 return; 412 return;
418 } 413 }
419 Local<Context> context = isolate->GetCurrentContext(); 414 Local<Context> context = isolate->GetCurrentContext();
420 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); 415 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked();
421 // The descriptor's 'initial'. 416 // The descriptor's 'initial'.
422 int initial; 417 int initial;
423 GetIntegerProperty(isolate, &thrower, context, descriptor, 418 if (!GetIntegerProperty(isolate, &thrower, context, descriptor,
424 v8_str(isolate, "initial"), &initial, 0, 65536); 419 v8_str(isolate, "initial"), &initial, 0, 65536)) {
420 return;
421 }
425 // The descriptor's 'maximum'. 422 // The descriptor's 'maximum'.
426 int maximum; 423 int maximum;
427 bool has_maximum = true; 424 Local<String> maximum_key = v8_str(isolate, "maximum");
428 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, 425 Maybe<bool> has_maximum = descriptor->Has(context, maximum_key);
429 v8_str(isolate, "maximum"), &maximum, initial, 426
430 65536)) { 427 if (has_maximum.IsNothing()) {
431 if (reinterpret_cast<i::Isolate*>(isolate)->has_pending_exception() || 428 // There has been an exception, just return.
432 thrower.error()) { 429 return;
430 }
431 if (has_maximum.FromJust()) {
432 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key,
433 &maximum, initial, 65536)) {
433 return; 434 return;
434 } else {
435 // There was no error, the property just does not exist.
436 has_maximum = false;
437 } 435 }
438 } 436 }
439 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 437 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
440 i::Handle<i::JSFunction> memory_cons( 438 i::Handle<i::JSFunction> memory_cons(
441 i_isolate->native_context()->wasm_memory_constructor()); 439 i_isolate->native_context()->wasm_memory_constructor());
442 i::Handle<i::JSObject> memory_obj = 440 i::Handle<i::JSObject> memory_obj =
443 i_isolate->factory()->NewJSObject(memory_cons); 441 i_isolate->factory()->NewJSObject(memory_cons);
444 i::Handle<i::JSArrayBuffer> buffer = 442 i::Handle<i::JSArrayBuffer> buffer =
445 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); 443 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
446 size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) * 444 size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) *
447 static_cast<size_t>(initial); 445 static_cast<size_t>(initial);
448 i::JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, size); 446 i::JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, size);
449 memory_obj->SetInternalField(0, *buffer); 447 memory_obj->SetInternalField(0, *buffer);
450 memory_obj->SetInternalField( 448 memory_obj->SetInternalField(
451 1, has_maximum 449 1, has_maximum.FromJust()
452 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) 450 ? static_cast<i::Object*>(i::Smi::FromInt(maximum))
453 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); 451 : static_cast<i::Object*>(i_isolate->heap()->undefined_value()));
454 i::Handle<i::Symbol> memory_sym( 452 i::Handle<i::Symbol> memory_sym(
455 i_isolate->native_context()->wasm_memory_sym()); 453 i_isolate->native_context()->wasm_memory_sym());
456 i::Object::SetProperty(memory_obj, memory_sym, memory_obj, i::STRICT).Check(); 454 i::Object::SetProperty(memory_obj, memory_sym, memory_obj, i::STRICT).Check();
457 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 455 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
458 return_value.Set(Utils::ToLocal(memory_obj)); 456 return_value.Set(Utils::ToLocal(memory_obj));
459 } 457 }
460 void WebAssemblyTableGetLength( 458 void WebAssemblyTableGetLength(
461 const v8::FunctionCallbackInfo<v8::Value>& args) { 459 const v8::FunctionCallbackInfo<v8::Value>& args) {
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 int unused_property_fields = in_object_properties - pre_allocated; 686 int unused_property_fields = in_object_properties - pre_allocated;
689 Handle<Map> map = Map::CopyInitialMap( 687 Handle<Map> map = Map::CopyInitialMap(
690 prev_map, instance_size, in_object_properties, unused_property_fields); 688 prev_map, instance_size, in_object_properties, unused_property_fields);
691 689
692 context->set_wasm_function_map(*map); 690 context->set_wasm_function_map(*map);
693 } 691 }
694 } 692 }
695 693
696 } // namespace internal 694 } // namespace internal
697 } // namespace v8 695 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/wasm/memory.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698