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

Side by Side Diff: src/objects.cc

Issue 9428026: Cleaned up setting of accessors. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4344 matching lines...) Expand 10 before | Expand all | Expand 10 after
4355 for (Object* current = this; 4355 for (Object* current = this;
4356 current != heap->null_value() && current->IsJSObject(); 4356 current != heap->null_value() && current->IsJSObject();
4357 current = JSObject::cast(current)->GetPrototype()) { 4357 current = JSObject::cast(current)->GetPrototype()) {
4358 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); 4358 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
4359 if (result->IsFound() && result->type() == CALLBACKS) return; 4359 if (result->IsFound() && result->type() == CALLBACKS) return;
4360 } 4360 }
4361 result->NotFound(); 4361 result->NotFound();
4362 } 4362 }
4363 4363
4364 4364
4365 // Search for a getter or setter in an elements dictionary and update its 4365 // Try to update an accessor in an elements dictionary. Return true if the
4366 // attributes. Returns either undefined if the element is non-deletable, or the 4366 // update succeeded, and false otherwise.
4367 // getter/setter pair if there is an existing one, or the hole value if the 4367 static bool UpdateGetterSetterInDictionary(
4368 // element does not exist or is a normal non-getter/setter data element.
4369 static Object* UpdateGetterSetterInDictionary(
4370 SeededNumberDictionary* dictionary, 4368 SeededNumberDictionary* dictionary,
4371 uint32_t index, 4369 uint32_t index,
4372 PropertyAttributes attributes, 4370 bool is_getter,
4373 Heap* heap) { 4371 Object* fun,
4372 PropertyAttributes attributes) {
4374 int entry = dictionary->FindEntry(index); 4373 int entry = dictionary->FindEntry(index);
4375 if (entry != SeededNumberDictionary::kNotFound) { 4374 if (entry != SeededNumberDictionary::kNotFound) {
4376 Object* result = dictionary->ValueAt(entry); 4375 Object* result = dictionary->ValueAt(entry);
4377 PropertyDetails details = dictionary->DetailsAt(entry); 4376 PropertyDetails details = dictionary->DetailsAt(entry);
4378 // TODO(mstarzinger): We should check for details.IsDontDelete() here once 4377 // TODO(mstarzinger): We should check for details.IsDontDelete() here once
4379 // we only call into the runtime once to set both getter and setter. 4378 // we only call into the runtime once to set both getter and setter.
4380 if (details.type() == CALLBACKS && result->IsAccessorPair()) { 4379 if (details.type() == CALLBACKS && result->IsAccessorPair()) {
4381 if (details.attributes() != attributes) { 4380 if (details.attributes() != attributes) {
4382 dictionary->DetailsAtPut(entry, 4381 dictionary->DetailsAtPut(entry,
4383 PropertyDetails(attributes, CALLBACKS, index)); 4382 PropertyDetails(attributes, CALLBACKS, index));
4384 } 4383 }
4385 return result; 4384 AccessorPair::cast(result)->set(is_getter, fun);
4385 return true;
4386 } 4386 }
4387 } 4387 }
4388 return heap->the_hole_value(); 4388 return false;
4389 } 4389 }
4390 4390
4391 4391
4392 MaybeObject* JSObject::DefineGetterSetter(String* name, 4392 MaybeObject* JSObject::DefineElementAccessor(uint32_t index,
4393 PropertyAttributes attributes) { 4393 bool is_getter,
4394 Heap* heap = GetHeap(); 4394 Object* fun,
4395 // Make sure that the top context does not change when doing callbacks or 4395 PropertyAttributes attributes) {
4396 // interceptor calls. 4396 switch (GetElementsKind()) {
4397 AssertNoContextChange ncc; 4397 case FAST_SMI_ONLY_ELEMENTS:
4398 4398 case FAST_ELEMENTS:
4399 // Try to flatten before operating on the string. 4399 case FAST_DOUBLE_ELEMENTS:
4400 name->TryFlatten(); 4400 break;
4401 4401 case EXTERNAL_PIXEL_ELEMENTS:
4402 if (!CanSetCallback(name)) { 4402 case EXTERNAL_BYTE_ELEMENTS:
4403 return heap->undefined_value(); 4403 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4404 case EXTERNAL_SHORT_ELEMENTS:
4405 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
4406 case EXTERNAL_INT_ELEMENTS:
4407 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
4408 case EXTERNAL_FLOAT_ELEMENTS:
4409 case EXTERNAL_DOUBLE_ELEMENTS:
4410 // Ignore getters and setters on pixel and external array elements.
4411 return GetHeap()->undefined_value();
4412 case DICTIONARY_ELEMENTS:
4413 if (UpdateGetterSetterInDictionary(element_dictionary(),
4414 index,
4415 is_getter,
4416 fun,
4417 attributes)) {
4418 return GetHeap()->undefined_value();
Michael Starzinger 2012/02/22 10:24:38 I prefer having the result of GetHeap() in a local
Sven Panne 2012/02/22 10:52:18 I don't think that one possible additional memory
fschneider 2012/02/24 10:33:17 I don't buy the conciseness argument. heap->undefi
Sven Panne 2012/02/24 11:47:17 It's not about shorter lines, it's all about havin
Michael Starzinger 2012/02/24 12:44:09 Knowing that "heap" refers to the one and only hea
4419 }
4420 break;
4421 case NON_STRICT_ARGUMENTS_ELEMENTS: {
4422 // Ascertain whether we have read-only properties or an existing
4423 // getter/setter pair in an arguments elements dictionary backing
4424 // store.
4425 FixedArray* parameter_map = FixedArray::cast(elements());
4426 uint32_t length = parameter_map->length();
4427 Object* probe =
4428 index < (length - 2) ? parameter_map->get(index + 2) : NULL;
4429 if (probe == NULL || probe->IsTheHole()) {
4430 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
4431 if (arguments->IsDictionary()) {
4432 SeededNumberDictionary* dictionary =
4433 SeededNumberDictionary::cast(arguments);
4434 if (UpdateGetterSetterInDictionary(dictionary,
4435 index,
4436 is_getter,
4437 fun,
4438 attributes)) {
4439 return GetHeap()->undefined_value();
4440 }
4441 }
4442 }
4443 break;
4444 }
4404 } 4445 }
4405 4446
4406 uint32_t index = 0; 4447 AccessorPair* accessors;
4407 bool is_element = name->AsArrayIndex(&index); 4448 { MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair();
4449 if (!maybe_accessors->To(&accessors)) return maybe_accessors;
4450 }
4451 accessors->set(is_getter, fun);
4408 4452
4409 if (is_element) { 4453 { MaybeObject* maybe_ok = SetElementCallback(index, accessors, attributes);
Sven Panne 2012/02/24 11:47:17 I'll apply the same simplification here...
4410 switch (GetElementsKind()) { 4454 if (maybe_ok->IsFailure()) return maybe_ok;
4411 case FAST_SMI_ONLY_ELEMENTS: 4455 }
4412 case FAST_ELEMENTS: 4456 return GetHeap()->undefined_value();
4413 case FAST_DOUBLE_ELEMENTS: 4457 }
4414 break; 4458
4415 case EXTERNAL_PIXEL_ELEMENTS: 4459
4416 case EXTERNAL_BYTE_ELEMENTS: 4460 MaybeObject* JSObject::DefinePropertyAccessor(String* name,
4417 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4461 bool is_getter,
4418 case EXTERNAL_SHORT_ELEMENTS: 4462 Object* fun,
4419 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4463 PropertyAttributes attributes) {
4420 case EXTERNAL_INT_ELEMENTS: 4464 // Lookup the name.
4421 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4465 LookupResult result(GetHeap()->isolate());
4422 case EXTERNAL_FLOAT_ELEMENTS: 4466 LocalLookupRealNamedProperty(name, &result);
4423 case EXTERNAL_DOUBLE_ELEMENTS: 4467 if (result.IsFound()) {
4424 // Ignore getters and setters on pixel and external array 4468 // TODO(mstarzinger): We should check for result.IsDontDelete() here once
4425 // elements. 4469 // we only call into the runtime once to set both getter and setter.
4426 return heap->undefined_value(); 4470 if (result.type() == CALLBACKS) {
4427 case DICTIONARY_ELEMENTS: { 4471 Object* obj = result.GetCallbackObject();
4428 Object* probe = UpdateGetterSetterInDictionary(element_dictionary(), 4472 // Need to preserve old getters/setters.
4429 index, 4473 if (obj->IsAccessorPair()) {
4430 attributes, 4474 AccessorPair::cast(obj)->set(is_getter, fun);
4431 heap); 4475 // Use set to update attributes.
4432 if (!probe->IsTheHole()) return probe; 4476 { MaybeObject* maybe_ok = SetPropertyCallback(name, obj, attributes);
4433 // Otherwise allow to override it. 4477 if (maybe_ok->IsFailure()) return maybe_ok;
4434 break;
4435 }
4436 case NON_STRICT_ARGUMENTS_ELEMENTS: {
4437 // Ascertain whether we have read-only properties or an existing
4438 // getter/setter pair in an arguments elements dictionary backing
4439 // store.
4440 FixedArray* parameter_map = FixedArray::cast(elements());
4441 uint32_t length = parameter_map->length();
4442 Object* probe =
4443 index < (length - 2) ? parameter_map->get(index + 2) : NULL;
4444 if (probe == NULL || probe->IsTheHole()) {
4445 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
4446 if (arguments->IsDictionary()) {
4447 SeededNumberDictionary* dictionary =
4448 SeededNumberDictionary::cast(arguments);
4449 probe = UpdateGetterSetterInDictionary(dictionary,
4450 index,
4451 attributes,
4452 heap);
4453 if (!probe->IsTheHole()) return probe;
4454 }
4455 } 4478 }
4456 break; 4479 return GetHeap()->undefined_value();
fschneider 2012/02/24 10:33:17 return SetPropertyCallback(name, obj, attributes);
Sven Panne 2012/02/24 11:47:17 See remark below.
4457 }
4458 }
4459 } else {
4460 // Lookup the name.
4461 LookupResult result(heap->isolate());
4462 LocalLookupRealNamedProperty(name, &result);
4463 if (result.IsFound()) {
4464 // TODO(mstarzinger): We should check for result.IsDontDelete() here once
4465 // we only call into the runtime once to set both getter and setter.
4466 if (result.type() == CALLBACKS) {
4467 Object* obj = result.GetCallbackObject();
4468 // Need to preserve old getters/setters.
4469 if (obj->IsAccessorPair()) {
4470 // Use set to update attributes.
4471 return SetPropertyCallback(name, obj, attributes);
4472 }
4473 } 4480 }
4474 } 4481 }
4475 } 4482 }
4476 4483
4477 AccessorPair* accessors; 4484 AccessorPair* accessors;
4478 { MaybeObject* maybe_accessors = heap->AllocateAccessorPair(); 4485 { MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair();
4479 if (!maybe_accessors->To<AccessorPair>(&accessors)) return maybe_accessors; 4486 if (!maybe_accessors->To(&accessors)) return maybe_accessors;
4480 } 4487 }
4488 accessors->set(is_getter, fun);
4481 4489
4482 if (is_element) { 4490 { MaybeObject* maybe_ok = SetPropertyCallback(name, accessors, attributes);
4483 return SetElementCallback(index, accessors, attributes); 4491 if (maybe_ok->IsFailure()) return maybe_ok;
4484 } else {
4485 return SetPropertyCallback(name, accessors, attributes);
4486 } 4492 }
4493 return GetHeap()->undefined_value();
fschneider 2012/02/24 10:33:17 return SetPropertyCallback(name, accessors, attrib
Sven Panne 2012/02/24 11:47:17 Good point, I'll submit a separate CL for this min
4487 } 4494 }
4488 4495
4489 4496
4490 bool JSObject::CanSetCallback(String* name) { 4497 bool JSObject::CanSetCallback(String* name) {
4491 ASSERT(!IsAccessCheckNeeded() || 4498 ASSERT(!IsAccessCheckNeeded() ||
4492 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); 4499 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET));
4493 4500
4494 // Check if there is an API defined callback object which prohibits 4501 // Check if there is an API defined callback object which prohibits
4495 // callback overwriting in this object or it's prototype chain. 4502 // callback overwriting in this object or it's prototype chain.
4496 // This mechanism is needed for instance in a browser setting, where 4503 // This mechanism is needed for instance in a browser setting, where
(...skipping 13 matching lines...) Expand all
4510 return true; 4517 return true;
4511 } 4518 }
4512 4519
4513 4520
4514 MaybeObject* JSObject::SetElementCallback(uint32_t index, 4521 MaybeObject* JSObject::SetElementCallback(uint32_t index,
4515 Object* structure, 4522 Object* structure,
4516 PropertyAttributes attributes) { 4523 PropertyAttributes attributes) {
4517 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); 4524 PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
4518 4525
4519 // Normalize elements to make this operation simple. 4526 // Normalize elements to make this operation simple.
4520 SeededNumberDictionary* dictionary = NULL; 4527 SeededNumberDictionary* dictionary;
4521 { Object* result; 4528 { MaybeObject* maybe_dictionary = NormalizeElements();
4522 MaybeObject* maybe = NormalizeElements(); 4529 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
4523 if (!maybe->ToObject(&result)) return maybe;
4524 dictionary = SeededNumberDictionary::cast(result);
4525 } 4530 }
4526 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 4531 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
4527 4532
4528 // Update the dictionary with the new CALLBACKS property. 4533 // Update the dictionary with the new CALLBACKS property.
4529 { Object* result; 4534 { MaybeObject* maybe_dictionary = dictionary->Set(index, structure, details);
4530 MaybeObject* maybe = dictionary->Set(index, structure, details); 4535 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
4531 if (!maybe->ToObject(&result)) return maybe;
4532 dictionary = SeededNumberDictionary::cast(result);
4533 } 4536 }
4534 4537
4535 dictionary->set_requires_slow_elements(); 4538 dictionary->set_requires_slow_elements();
4536 // Update the dictionary backing store on the object. 4539 // Update the dictionary backing store on the object.
4537 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { 4540 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) {
4538 // Also delete any parameter alias. 4541 // Also delete any parameter alias.
4539 // 4542 //
4540 // TODO(kmillikin): when deleting the last parameter alias we could 4543 // TODO(kmillikin): when deleting the last parameter alias we could
4541 // switch to a direct backing store without the parameter map. This 4544 // switch to a direct backing store without the parameter map. This
4542 // would allow GC of the context. 4545 // would allow GC of the context.
4543 FixedArray* parameter_map = FixedArray::cast(elements()); 4546 FixedArray* parameter_map = FixedArray::cast(elements());
4544 uint32_t length = parameter_map->length(); 4547 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) {
4545 if (index < length - 2) {
4546 parameter_map->set(index + 2, GetHeap()->the_hole_value()); 4548 parameter_map->set(index + 2, GetHeap()->the_hole_value());
4547 } 4549 }
4548 parameter_map->set(1, dictionary); 4550 parameter_map->set(1, dictionary);
4549 } else { 4551 } else {
4550 set_elements(dictionary); 4552 set_elements(dictionary);
4551 } 4553 }
4552 4554
4553 return structure; 4555 return GetHeap()->undefined_value();
4554 } 4556 }
4555 4557
4556 4558
4557 MaybeObject* JSObject::SetPropertyCallback(String* name, 4559 MaybeObject* JSObject::SetPropertyCallback(String* name,
4558 Object* structure, 4560 Object* structure,
4559 PropertyAttributes attributes) { 4561 PropertyAttributes attributes) {
4560 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); 4562 PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
4561 4563
4562 bool convert_back_to_fast = HasFastProperties() && 4564 bool convert_back_to_fast = HasFastProperties() &&
4563 (map()->instance_descriptors()->number_of_descriptors() 4565 (map()->instance_descriptors()->number_of_descriptors()
4564 < DescriptorArray::kMaxNumberOfDescriptors); 4566 < DescriptorArray::kMaxNumberOfDescriptors);
4565 4567
4566 // Normalize object to make this operation simple. 4568 // Normalize object to make this operation simple.
4567 Object* ok;
4568 { MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 4569 { MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
4569 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 4570 if (maybe_ok->IsFailure()) return maybe_ok;
4570 } 4571 }
4571 4572
4572 // For the global object allocate a new map to invalidate the global inline 4573 // For the global object allocate a new map to invalidate the global inline
4573 // caches which have a global property cell reference directly in the code. 4574 // caches which have a global property cell reference directly in the code.
4574 if (IsGlobalObject()) { 4575 if (IsGlobalObject()) {
4575 Object* new_map; 4576 Map* new_map;
4576 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); 4577 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
4577 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 4578 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
4578 } 4579 }
4579 set_map(Map::cast(new_map)); 4580 set_map(new_map);
4580 // When running crankshaft, changing the map is not enough. We 4581 // When running crankshaft, changing the map is not enough. We
4581 // need to deoptimize all functions that rely on this global 4582 // need to deoptimize all functions that rely on this global
4582 // object. 4583 // object.
4583 Deoptimizer::DeoptimizeGlobalObject(this); 4584 Deoptimizer::DeoptimizeGlobalObject(this);
4584 } 4585 }
4585 4586
4586 // Update the dictionary with the new CALLBACKS property. 4587 // Update the dictionary with the new CALLBACKS property.
4587 Object* result; 4588 { MaybeObject* maybe_ok = SetNormalizedProperty(name, structure, details);
4588 { MaybeObject* maybe_result = SetNormalizedProperty(name, structure, details); 4589 if (maybe_ok->IsFailure()) return maybe_ok;
4589 if (!maybe_result->ToObject(&result)) return maybe_result;
4590 } 4590 }
4591 4591
4592 if (convert_back_to_fast) { 4592 if (convert_back_to_fast) {
4593 { MaybeObject* maybe_ok = TransformToFastProperties(0); 4593 MaybeObject* maybe_ok = TransformToFastProperties(0);
4594 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 4594 if (maybe_ok->IsFailure()) return maybe_ok;
4595 }
4596 } 4595 }
4597 return result; 4596 return GetHeap()->undefined_value();
4598 } 4597 }
4599 4598
4600 MaybeObject* JSObject::DefineAccessor(String* name, 4599 MaybeObject* JSObject::DefineAccessor(String* name,
4601 bool is_getter, 4600 bool is_getter,
4602 Object* fun, 4601 Object* fun,
4603 PropertyAttributes attributes) { 4602 PropertyAttributes attributes) {
4604 ASSERT(fun->IsSpecFunction() || fun->IsUndefined()); 4603 ASSERT(fun->IsSpecFunction() || fun->IsUndefined());
4605 Isolate* isolate = GetIsolate(); 4604 Isolate* isolate = GetIsolate();
4606 // Check access rights if needed. 4605 // Check access rights if needed.
4607 if (IsAccessCheckNeeded() && 4606 if (IsAccessCheckNeeded() &&
4608 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { 4607 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
4609 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 4608 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
4610 return isolate->heap()->undefined_value(); 4609 return isolate->heap()->undefined_value();
4611 } 4610 }
4612 4611
4613 if (IsJSGlobalProxy()) { 4612 if (IsJSGlobalProxy()) {
4614 Object* proto = GetPrototype(); 4613 Object* proto = GetPrototype();
4615 if (proto->IsNull()) return this; 4614 if (proto->IsNull()) return this;
4616 ASSERT(proto->IsJSGlobalObject()); 4615 ASSERT(proto->IsJSGlobalObject());
4617 return JSObject::cast(proto)->DefineAccessor(name, is_getter, 4616 return JSObject::cast(proto)->DefineAccessor(name, is_getter,
4618 fun, attributes); 4617 fun, attributes);
4619 } 4618 }
4620 4619
4621 Object* accessors; 4620 // Make sure that the top context does not change when doing callbacks or
4622 { MaybeObject* maybe_accessors = DefineGetterSetter(name, attributes); 4621 // interceptor calls.
4623 if (!maybe_accessors->To<Object>(&accessors)) return maybe_accessors; 4622 AssertNoContextChange ncc;
4624 } 4623
4625 if (accessors->IsUndefined()) return accessors; 4624 // Try to flatten before operating on the string.
4626 if (is_getter) { 4625 name->TryFlatten();
4627 AccessorPair::cast(accessors)->set_getter(fun); 4626
4628 } else { 4627 if (!CanSetCallback(name)) return isolate->heap()->undefined_value();
4629 AccessorPair::cast(accessors)->set_setter(fun); 4628
4630 } 4629 uint32_t index = 0;
4631 return this; 4630 return name->AsArrayIndex(&index) ?
4631 DefineElementAccessor(index, is_getter, fun, attributes) :
4632 DefinePropertyAccessor(name, is_getter, fun, attributes);
4632 } 4633 }
4633 4634
4634 4635
4635 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { 4636 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) {
4636 Isolate* isolate = GetIsolate(); 4637 Isolate* isolate = GetIsolate();
4637 String* name = String::cast(info->name()); 4638 String* name = String::cast(info->name());
4638 // Check access rights if needed. 4639 // Check access rights if needed.
4639 if (IsAccessCheckNeeded() && 4640 if (IsAccessCheckNeeded() &&
4640 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { 4641 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
4641 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 4642 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4684 // Ignore getters and setters on pixel and external array 4685 // Ignore getters and setters on pixel and external array
4685 // elements. 4686 // elements.
4686 return isolate->heap()->undefined_value(); 4687 return isolate->heap()->undefined_value();
4687 case DICTIONARY_ELEMENTS: 4688 case DICTIONARY_ELEMENTS:
4688 break; 4689 break;
4689 case NON_STRICT_ARGUMENTS_ELEMENTS: 4690 case NON_STRICT_ARGUMENTS_ELEMENTS:
4690 UNIMPLEMENTED(); 4691 UNIMPLEMENTED();
4691 break; 4692 break;
4692 } 4693 }
4693 4694
4694 Object* ok;
4695 { MaybeObject* maybe_ok = 4695 { MaybeObject* maybe_ok =
4696 SetElementCallback(index, info, info->property_attributes()); 4696 SetElementCallback(index, info, info->property_attributes());
4697 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 4697 if (maybe_ok->IsFailure()) return maybe_ok;
4698 } 4698 }
4699 } else { 4699 } else {
4700 // Lookup the name. 4700 // Lookup the name.
4701 LookupResult result(isolate); 4701 LookupResult result(isolate);
4702 LocalLookup(name, &result); 4702 LocalLookup(name, &result);
4703 // ES5 forbids turning a property into an accessor if it's not 4703 // ES5 forbids turning a property into an accessor if it's not
4704 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). 4704 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
4705 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) { 4705 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) {
4706 return isolate->heap()->undefined_value(); 4706 return isolate->heap()->undefined_value();
4707 } 4707 }
4708 Object* ok;
4709 { MaybeObject* maybe_ok = 4708 { MaybeObject* maybe_ok =
4710 SetPropertyCallback(name, info, info->property_attributes()); 4709 SetPropertyCallback(name, info, info->property_attributes());
4711 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 4710 if (maybe_ok->IsFailure()) return maybe_ok;
4712 } 4711 }
4713 } 4712 }
4714 4713
4715 return this; 4714 return this;
4716 } 4715 }
4717 4716
4718 4717
4719 Object* JSObject::LookupAccessor(String* name, bool is_getter) { 4718 Object* JSObject::LookupAccessor(String* name, bool is_getter) {
4720 Heap* heap = GetHeap(); 4719 Heap* heap = GetHeap();
4721 4720
(...skipping 7943 matching lines...) Expand 10 before | Expand all | Expand 10 after
12665 } else { 12664 } else {
12666 int offset = current_offset - inobject_props; 12665 int offset = current_offset - inobject_props;
12667 FixedArray::cast(fields)->set(offset, value); 12666 FixedArray::cast(fields)->set(offset, value);
12668 } 12667 }
12669 FieldDescriptor d(String::cast(key), 12668 FieldDescriptor d(String::cast(key),
12670 current_offset++, 12669 current_offset++,
12671 details.attributes(), 12670 details.attributes(),
12672 details.index()); 12671 details.index());
12673 descriptors->Set(next_descriptor++, &d, witness); 12672 descriptors->Set(next_descriptor++, &d, witness);
12674 } else if (type == CALLBACKS) { 12673 } else if (type == CALLBACKS) {
12674 if (value->IsAccessorPair()) {
12675 MaybeObject* maybe_copy =
12676 AccessorPair::cast(value)->CopyWithoutTransitions();
12677 if (!maybe_copy->To(&value)) return maybe_copy;
12678 }
12675 CallbacksDescriptor d(String::cast(key), 12679 CallbacksDescriptor d(String::cast(key),
12676 value, 12680 value,
12677 details.attributes(), 12681 details.attributes(),
12678 details.index()); 12682 details.index());
12679 descriptors->Set(next_descriptor++, &d, witness); 12683 descriptors->Set(next_descriptor++, &d, witness);
12680 } else { 12684 } else {
12681 UNREACHABLE(); 12685 UNREACHABLE();
12682 } 12686 }
12683 } 12687 }
12684 } 12688 }
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
13075 if (break_point_objects()->IsUndefined()) return 0; 13079 if (break_point_objects()->IsUndefined()) return 0;
13076 // Single break point. 13080 // Single break point.
13077 if (!break_point_objects()->IsFixedArray()) return 1; 13081 if (!break_point_objects()->IsFixedArray()) return 1;
13078 // Multiple break points. 13082 // Multiple break points.
13079 return FixedArray::cast(break_point_objects())->length(); 13083 return FixedArray::cast(break_point_objects())->length();
13080 } 13084 }
13081 #endif // ENABLE_DEBUGGER_SUPPORT 13085 #endif // ENABLE_DEBUGGER_SUPPORT
13082 13086
13083 13087
13084 } } // namespace v8::internal 13088 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698