 Chromium Code Reviews
 Chromium Code Reviews Issue 2431223005:
  Implement DefineOwnProperty for TypedArrays  (Closed)
    
  
    Issue 2431223005:
  Implement DefineOwnProperty for TypedArrays  (Closed) 
  | OLD | NEW | 
|---|---|
| 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/objects.h" | 5 #include "src/objects.h" | 
| 6 | 6 | 
| 7 #include <cmath> | 7 #include <cmath> | 
| 8 #include <iomanip> | 8 #include <iomanip> | 
| 9 #include <memory> | 9 #include <memory> | 
| 10 #include <sstream> | 10 #include <sstream> | 
| (...skipping 6524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6535 PropertyDescriptor* desc, | 6535 PropertyDescriptor* desc, | 
| 6536 ShouldThrow should_throw) { | 6536 ShouldThrow should_throw) { | 
| 6537 if (object->IsJSArray()) { | 6537 if (object->IsJSArray()) { | 
| 6538 return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object), | 6538 return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object), | 
| 6539 key, desc, should_throw); | 6539 key, desc, should_throw); | 
| 6540 } | 6540 } | 
| 6541 if (object->IsJSProxy()) { | 6541 if (object->IsJSProxy()) { | 
| 6542 return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object), | 6542 return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object), | 
| 6543 key, desc, should_throw); | 6543 key, desc, should_throw); | 
| 6544 } | 6544 } | 
| 6545 if (object->IsJSTypedArray()) { | |
| 6546 return JSTypedArray::DefineOwnProperty( | |
| 6547 isolate, Handle<JSTypedArray>::cast(object), key, desc, should_throw); | |
| 6548 } | |
| 6545 // TODO(neis): Special case for JSModuleNamespace? | 6549 // TODO(neis): Special case for JSModuleNamespace? | 
| 6546 | 6550 | 
| 6547 // OrdinaryDefineOwnProperty, by virtue of calling | 6551 // OrdinaryDefineOwnProperty, by virtue of calling | 
| 6548 // DefineOwnPropertyIgnoreAttributes, can handle arguments (ES6 9.4.4.2) | 6552 // DefineOwnPropertyIgnoreAttributes, can handle arguments (ES6 9.4.4.2) | 
| 6549 // and IntegerIndexedExotics (ES6 9.4.5.3), with one exception: | |
| 6550 // TODO(jkummerow): Setting an indexed accessor on a typed array should throw. | |
| 6551 return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key, | 6553 return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key, | 
| 6552 desc, should_throw); | 6554 desc, should_throw); | 
| 6553 } | 6555 } | 
| 6554 | 6556 | 
| 6555 | 6557 | 
| 6556 // static | 6558 // static | 
| 6557 Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate, | 6559 Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(Isolate* isolate, | 
| 6558 Handle<JSObject> object, | 6560 Handle<JSObject> object, | 
| 6559 Handle<Object> key, | 6561 Handle<Object> key, | 
| 6560 PropertyDescriptor* desc, | 6562 PropertyDescriptor* desc, | 
| (...skipping 10866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 17427 } | 17429 } | 
| 17428 while (holes < limit) { | 17430 while (holes < limit) { | 
| 17429 elements->set_the_hole(holes); | 17431 elements->set_the_hole(holes); | 
| 17430 holes++; | 17432 holes++; | 
| 17431 } | 17433 } | 
| 17432 } | 17434 } | 
| 17433 | 17435 | 
| 17434 return isolate->factory()->NewNumberFromUint(result); | 17436 return isolate->factory()->NewNumberFromUint(result); | 
| 17435 } | 17437 } | 
| 17436 | 17438 | 
| 17439 static Handle<Object> CanonicalNumericIndexString(Isolate* isolate, | |
| 17440 Handle<Object> s) { | |
| 17441 DCHECK(s->IsString()); | |
| 17442 Handle<Object> index = String::ToNumber(Handle<String>::cast(s)); | |
| 17443 if (index->IsMinusZero()) return index; | |
| 17444 // Avoid treating strings like "2E1" and "20" as the same key | |
| 17445 if (!Object::ToString(isolate, index).ToHandleChecked()->SameValue(*s)) | |
| 17446 return isolate->factory()->undefined_value(); | |
| 17447 return index; | |
| 17448 } | |
| 17449 | |
| 17450 // ES6 9.4.5.3 | |
| 17451 // static | |
| 17452 Maybe<bool> JSTypedArray::DefineOwnProperty(Isolate* isolate, | |
| 17453 Handle<JSTypedArray> o, | |
| 17454 Handle<Object> key, | |
| 17455 PropertyDescriptor* desc, | |
| 17456 ShouldThrow should_throw) { | |
| 17457 // 1. Assert: IsPropertyKey(P) is true. | |
| 17458 DCHECK(key->IsName() || key->IsNumber()); | |
| 17459 // 2. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot. | |
| 17460 // 3. If Type(P) is String, then | |
| 17461 // ToPropertyKey returns Smi's too | |
| 17462 if (key->IsString() || key->IsSmi()) { | |
| 17463 // 3a. Let numericIndex be ! CanonicalNumericIndexString(P) | |
| 17464 Handle<Object> numeric_index = | |
| 17465 key->IsSmi() ? key : CanonicalNumericIndexString( | |
| 17466 isolate, Handle<String>::cast(key)); | |
| 17467 // 3b. If numericIndex is not undefined, then | |
| 17468 if (!numeric_index->IsUndefined(isolate)) { | |
| 17469 // 3b i. If IsInteger(numericIndex) is false, return false. | |
| 17470 // 3b ii. If numericIndex = -0, return false. | |
| 17471 // 3b iii. If numericIndex < 0, return false. | |
| 17472 double index_dbl = numeric_index->Number(); | |
| 
Henrique Ferreiro
2016/11/15 13:07:55
This was uncovered when fixing test262 expectation
 | |
| 17473 // FIXME: the standard allows up to 2^53 elements | |
| 17474 if (!IsUint32Double(index_dbl)) | |
| 17475 RETURN_FAILURE(isolate, should_throw, | |
| 17476 NewTypeError(MessageTemplate::kInvalidTypedArrayIndex)); | |
| 17477 uint32_t index = DoubleToUint32(index_dbl); | |
| 17478 // 3b iv. Let length be O.[[ArrayLength]]. | |
| 17479 int length = o->length()->Number(); | |
| 17480 // 3b v. If numericIndex ≥ length, return false. | |
| 17481 if (index >= length) | |
| 17482 RETURN_FAILURE(isolate, should_throw, | |
| 17483 NewTypeError(MessageTemplate::kInvalidTypedArrayIndex)); | |
| 17484 // 3b vi. If IsAccessorDescriptor(Desc) is true, return false. | |
| 17485 if (PropertyDescriptor::IsAccessorDescriptor(desc)) | |
| 17486 RETURN_FAILURE(isolate, should_throw, | |
| 17487 NewTypeError(MessageTemplate::kRedefineDisallowed, key)); | |
| 17488 // 3b vii. If Desc has a [[Configurable]] field and if | |
| 17489 // Desc.[[Configurable]] is true, return false. | |
| 17490 // 3b viii. If Desc has an [[Enumerable]] field and if Desc.[[Enumerable]] | |
| 17491 // is false, return false. | |
| 17492 // 3b ix. If Desc has a [[Writable]] field and if Desc.[[Writable]] is | |
| 17493 // false, return false. | |
| 17494 if ((desc->has_configurable() && desc->configurable()) || | |
| 17495 (desc->has_enumerable() && !desc->enumerable()) || | |
| 17496 (desc->has_writable() && !desc->writable())) | |
| 17497 RETURN_FAILURE(isolate, should_throw, | |
| 17498 NewTypeError(MessageTemplate::kRedefineDisallowed, key)); | |
| 17499 // 3b x. If Desc has a [[Value]] field, then | |
| 17500 // 3b x 1. Let value be Desc.[[Value]]. | |
| 17501 // 3b x 2. Return ? IntegerIndexedElementSet(O, numericIndex, value). | |
| 17502 if (desc->has_value()) { | |
| 17503 if (!desc->has_configurable()) desc->set_configurable(false); | |
| 17504 if (!desc->has_enumerable()) desc->set_enumerable(true); | |
| 17505 if (!desc->has_writable()) desc->set_writable(true); | |
| 17506 Handle<Object> value = desc->value(); | |
| 17507 RETURN_ON_EXCEPTION_VALUE(isolate, | |
| 17508 SetOwnElementIgnoreAttributes( | |
| 17509 o, index, value, desc->ToAttributes()), | |
| 17510 Nothing<bool>()); | |
| 17511 } | |
| 17512 // 3b xi. Return true. | |
| 17513 return Just(true); | |
| 17514 } | |
| 17515 } | |
| 17516 // 4. Return ! OrdinaryDefineOwnProperty(O, P, Desc). | |
| 17517 return OrdinaryDefineOwnProperty(isolate, o, key, desc, should_throw); | |
| 17518 } | |
| 17519 | |
| 17437 | 17520 | 
| 17438 ExternalArrayType JSTypedArray::type() { | 17521 ExternalArrayType JSTypedArray::type() { | 
| 17439 switch (elements()->map()->instance_type()) { | 17522 switch (elements()->map()->instance_type()) { | 
| 17440 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ | 17523 #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \ | 
| 17441 case FIXED_##TYPE##_ARRAY_TYPE: \ | 17524 case FIXED_##TYPE##_ARRAY_TYPE: \ | 
| 17442 return kExternal##Type##Array; | 17525 return kExternal##Type##Array; | 
| 17443 | 17526 | 
| 17444 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) | 17527 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE) | 
| 17445 #undef INSTANCE_TYPE_TO_ARRAY_TYPE | 17528 #undef INSTANCE_TYPE_TO_ARRAY_TYPE | 
| 17446 | 17529 | 
| (...skipping 2766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 20213 ns, Accessors::ModuleNamespaceEntryInfo(isolate, name, attr)) | 20296 ns, Accessors::ModuleNamespaceEntryInfo(isolate, name, attr)) | 
| 20214 .Check(); | 20297 .Check(); | 
| 20215 } | 20298 } | 
| 20216 JSObject::PreventExtensions(ns, THROW_ON_ERROR).ToChecked(); | 20299 JSObject::PreventExtensions(ns, THROW_ON_ERROR).ToChecked(); | 
| 20217 | 20300 | 
| 20218 return ns; | 20301 return ns; | 
| 20219 } | 20302 } | 
| 20220 | 20303 | 
| 20221 } // namespace internal | 20304 } // namespace internal | 
| 20222 } // namespace v8 | 20305 } // namespace v8 | 
| OLD | NEW |