1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/property-descriptor.h" 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/bootstrapper.h" 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/factory.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/lookup.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/objects-inl.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 { 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal { 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Helper function for ToPropertyDescriptor. Comments describe steps for 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// "enumerable", other properties are handled the same way. 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Returns false if an exception was thrown. 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool GetPropertyIfPresent(Handle<Object> obj, Handle<String> name, 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object>* value) { 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LookupIterator it(obj, name); 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 4. Let hasEnumerable be HasProperty(Obj, "enumerable"). 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Maybe<bool> has_property = JSReceiver::HasProperty(&it); 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 5. ReturnIfAbrupt(hasEnumerable). 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_property.IsNothing()) return false; 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 6. If hasEnumerable is true, then 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_property.FromJust() == true) { 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 6a. Let enum be ToBoolean(Get(Obj, "enumerable")). 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 6b. ReturnIfAbrupt(enum). 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!JSObject::GetProperty(&it).ToHandle(value)) return false; 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Helper function for ToPropertyDescriptor. Handles the case of "simple" 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// objects: nothing on the prototype chain, just own fast data properties. 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Must not have observable side effects, because the slow path will restart 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// the entire conversion! 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool ToPropertyDescriptorFastPath(Isolate* isolate, Handle<Object> obj, 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyDescriptor* desc) { 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!obj->IsJSObject()) return false; 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Map* map = Handle<JSObject>::cast(obj)->map(); 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->instance_type() != JS_OBJECT_TYPE) return false; 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->is_access_check_needed()) return false; 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->prototype() != *isolate->initial_object_prototype()) return false; 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // During bootstrapping, the object_function_prototype_map hasn't been 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // set up yet. 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (isolate->bootstrapper()->IsActive()) return false; 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (JSObject::cast(map->prototype())->map() != 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->native_context()->object_function_prototype_map()) { 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(jkummerow): support dictionary properties? 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->is_dictionary_map()) return false; 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<DescriptorArray> descs = 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<DescriptorArray>(map->instance_descriptors()); 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyDetails details = descs->GetDetails(i); 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Name* key = descs->GetKey(i); 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value; 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (details.type()) { 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case DATA: 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = JSObject::FastPropertyAt(Handle<JSObject>::cast(obj), 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch details.representation(), 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FieldIndex::ForDescriptor(map, i)); 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case DATA_CONSTANT: 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = handle(descs->GetConstant(i), isolate); 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ACCESSOR: 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ACCESSOR_CONSTANT: 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Bail out to slow path. 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Heap* heap = isolate->heap(); 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (key == heap->enumerable_string()) { 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_enumerable(value->BooleanValue()); 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (key == heap->configurable_string()) { 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_configurable(value->BooleanValue()); 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (key == heap->value_string()) { 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_value(value); 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (key == heap->writable_string()) { 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_writable(value->BooleanValue()); 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (key == heap->get_string()) { 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Bail out to slow path to throw an exception if necessary. 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!value->IsCallable()) return false; 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_get(value); 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (key == heap->set_string()) { 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Bail out to slow path to throw an exception if necessary. 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!value->IsCallable()) return false; 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_set(value); 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((desc->has_get() || desc->has_set()) && 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (desc->has_value() || desc->has_writable())) { 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Bail out to slow path to throw an exception. 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void CreateDataProperty(Isolate* isolate, Handle<JSObject> object, 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> name, Handle<Object> value) { 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Maybe<bool> result = JSObject::CreateDataProperty(&it, value); 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(result.IsJust() && result.FromJust()); 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ES6 6.2.4.4 "FromPropertyDescriptor" 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<Object> PropertyDescriptor::ToObject(Isolate* isolate) { 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!(PropertyDescriptor::IsAccessorDescriptor(this) && 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyDescriptor::IsDataDescriptor(this))); 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Factory* factory = isolate->factory(); 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> result = factory->NewJSObject(isolate->object_function()); 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_value()) { 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CreateDataProperty(isolate, result, factory->value_string(), value()); 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_writable()) { 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CreateDataProperty(isolate, result, factory->writable_string(), 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch factory->ToBoolean(writable())); 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_get()) { 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CreateDataProperty(isolate, result, factory->get_string(), get()); 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_set()) { 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CreateDataProperty(isolate, result, factory->set_string(), set()); 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_enumerable()) { 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CreateDataProperty(isolate, result, factory->enumerable_string(), 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch factory->ToBoolean(enumerable())); 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (has_configurable()) { 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CreateDataProperty(isolate, result, factory->configurable_string(), 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch factory->ToBoolean(configurable())); 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ES6 6.2.4.5 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Returns false in case of exception. 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool PropertyDescriptor::ToPropertyDescriptor(Isolate* isolate, 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> obj, 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyDescriptor* desc) { 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 1. ReturnIfAbrupt(Obj). 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 2. If Type(Obj) is not Object, throw a TypeError exception. 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!obj->IsJSReceiver()) { 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->Throw(*isolate->factory()->NewTypeError( 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MessageTemplate::kPropertyDescObject, obj)); 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 3. Let desc be a new Property Descriptor that initially has no fields. 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(desc->is_empty()); 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (ToPropertyDescriptorFastPath(isolate, obj, desc)) { 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // enumerable? 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> enumerable; 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 4 through 6b. 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!GetPropertyIfPresent(obj, isolate->factory()->enumerable_string(), 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch &enumerable)) { 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 6c. Set the [[Enumerable]] field of desc to enum. 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!enumerable.is_null()) { 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_enumerable(enumerable->BooleanValue()); 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // configurable? 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> configurable; 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 7 through 9b. 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!GetPropertyIfPresent(obj, isolate->factory()->configurable_string(), 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch &configurable)) { 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 9c. Set the [[Configurable]] field of desc to conf. 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!configurable.is_null()) { 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_configurable(configurable->BooleanValue()); 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // value? 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value; 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 10 through 12b. 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!GetPropertyIfPresent(obj, isolate->factory()->value_string(), &value)) { 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 12c. Set the [[Value]] field of desc to value. 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!value.is_null()) desc->set_value(value); 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // writable? 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> writable; 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 13 through 15b. 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!GetPropertyIfPresent(obj, isolate->factory()->writable_string(), 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch &writable)) { 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 15c. Set the [[Writable]] field of desc to writable. 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!writable.is_null()) desc->set_writable(writable->BooleanValue()); 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // getter? 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> getter; 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 16 through 18b. 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!GetPropertyIfPresent(obj, isolate->factory()->get_string(), &getter)) { 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!getter.is_null()) { 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 18c. If IsCallable(getter) is false and getter is not undefined, 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // throw a TypeError exception. 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!getter->IsCallable() && !getter->IsUndefined()) { 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->Throw(*isolate->factory()->NewTypeError( 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MessageTemplate::kObjectGetterCallable, getter)); 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 18d. Set the [[Get]] field of desc to getter. 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_get(getter); 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // setter? 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> setter; 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 19 through 21b. 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!GetPropertyIfPresent(obj, isolate->factory()->set_string(), &setter)) { 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!setter.is_null()) { 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 21c. If IsCallable(setter) is false and setter is not undefined, 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // throw a TypeError exception. 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!setter->IsCallable() && !setter->IsUndefined()) { 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->Throw(*isolate->factory()->NewTypeError( 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MessageTemplate::kObjectSetterCallable, setter)); 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 21d. Set the [[Set]] field of desc to setter. 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_set(setter); 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 22. If either desc.[[Get]] or desc.[[Set]] is present, then 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 22a. If either desc.[[Value]] or desc.[[Writable]] is present, 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // throw a TypeError exception. 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((desc->has_get() || desc->has_set()) && 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (desc->has_value() || desc->has_writable())) { 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->Throw(*isolate->factory()->NewTypeError( 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MessageTemplate::kValueAndAccessor, obj)); 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 23. Return desc. 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ES6 6.2.4.6 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid PropertyDescriptor::CompletePropertyDescriptor(Isolate* isolate, 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyDescriptor* desc) { 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 1. ReturnIfAbrupt(Desc). 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 2. Assert: Desc is a Property Descriptor. 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 3. Let like be Record{ 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // [[Value]]: undefined, [[Writable]]: false, 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // [[Get]]: undefined, [[Set]]: undefined, 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // [[Enumerable]]: false, [[Configurable]]: false}. 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 4. If either IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // then: 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!IsAccessorDescriptor(desc)) { 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 4a. If Desc does not have a [[Value]] field, set Desc.[[Value]] to 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // like.[[Value]]. 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!desc->has_value()) { 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_value(isolate->factory()->undefined_value()); 273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 4b. If Desc does not have a [[Writable]] field, set Desc.[[Writable]] 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to like.[[Writable]]. 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!desc->has_writable()) desc->set_writable(false); 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 5. Else, 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 5a. If Desc does not have a [[Get]] field, set Desc.[[Get]] to 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // like.[[Get]]. 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!desc->has_get()) { 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_get(isolate->factory()->undefined_value()); 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 5b. If Desc does not have a [[Set]] field, set Desc.[[Set]] to 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // like.[[Set]]. 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!desc->has_set()) { 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->set_set(isolate->factory()->undefined_value()); 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 6. If Desc does not have an [[Enumerable]] field, set 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Desc.[[Enumerable]] to like.[[Enumerable]]. 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!desc->has_enumerable()) desc->set_enumerable(false); 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 7. If Desc does not have a [[Configurable]] field, set 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Desc.[[Configurable]] to like.[[Configurable]]. 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!desc->has_configurable()) desc->set_configurable(false); 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 8. Return Desc. 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 301