| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright 2016 the V8 project authors. All rights reserved. | 
 |    2 // Use of this source code is governed by a BSD-style license that can be | 
 |    3 // found in the LICENSE file. | 
 |    4  | 
 |    5 #include "src/builtins/builtins.h" | 
 |    6 #include "src/builtins/builtins-utils.h" | 
 |    7  | 
 |    8 #include "src/code-factory.h" | 
 |    9 #include "src/property-descriptor.h" | 
 |   10  | 
 |   11 namespace v8 { | 
 |   12 namespace internal { | 
 |   13  | 
 |   14 // ----------------------------------------------------------------------------- | 
 |   15 // ES6 section 19.1 Object Objects | 
 |   16  | 
 |   17 void Builtins::Generate_ObjectHasOwnProperty(CodeStubAssembler* assembler) { | 
 |   18   typedef compiler::Node Node; | 
 |   19   typedef CodeStubAssembler::Label Label; | 
 |   20   typedef CodeStubAssembler::Variable Variable; | 
 |   21  | 
 |   22   Node* object = assembler->Parameter(0); | 
 |   23   Node* key = assembler->Parameter(1); | 
 |   24   Node* context = assembler->Parameter(4); | 
 |   25  | 
 |   26   Label call_runtime(assembler), return_true(assembler), | 
 |   27       return_false(assembler); | 
 |   28  | 
 |   29   // Smi receivers do not have own properties. | 
 |   30   Label if_objectisnotsmi(assembler); | 
 |   31   assembler->Branch(assembler->WordIsSmi(object), &return_false, | 
 |   32                     &if_objectisnotsmi); | 
 |   33   assembler->Bind(&if_objectisnotsmi); | 
 |   34  | 
 |   35   Node* map = assembler->LoadMap(object); | 
 |   36   Node* instance_type = assembler->LoadMapInstanceType(map); | 
 |   37  | 
 |   38   Variable var_index(assembler, MachineRepresentation::kWord32); | 
 |   39  | 
 |   40   Label keyisindex(assembler), if_iskeyunique(assembler); | 
 |   41   assembler->TryToName(key, &keyisindex, &var_index, &if_iskeyunique, | 
 |   42                        &call_runtime); | 
 |   43  | 
 |   44   assembler->Bind(&if_iskeyunique); | 
 |   45   assembler->TryHasOwnProperty(object, map, instance_type, key, &return_true, | 
 |   46                                &return_false, &call_runtime); | 
 |   47  | 
 |   48   assembler->Bind(&keyisindex); | 
 |   49   assembler->TryLookupElement(object, map, instance_type, var_index.value(), | 
 |   50                               &return_true, &return_false, &call_runtime); | 
 |   51  | 
 |   52   assembler->Bind(&return_true); | 
 |   53   assembler->Return(assembler->BooleanConstant(true)); | 
 |   54  | 
 |   55   assembler->Bind(&return_false); | 
 |   56   assembler->Return(assembler->BooleanConstant(false)); | 
 |   57  | 
 |   58   assembler->Bind(&call_runtime); | 
 |   59   assembler->Return(assembler->CallRuntime(Runtime::kObjectHasOwnProperty, | 
 |   60                                            context, object, key)); | 
 |   61 } | 
 |   62  | 
 |   63 namespace { | 
 |   64  | 
 |   65 MUST_USE_RESULT Maybe<bool> FastAssign(Handle<JSReceiver> to, | 
 |   66                                        Handle<Object> next_source) { | 
 |   67   // Non-empty strings are the only non-JSReceivers that need to be handled | 
 |   68   // explicitly by Object.assign. | 
 |   69   if (!next_source->IsJSReceiver()) { | 
 |   70     return Just(!next_source->IsString() || | 
 |   71                 String::cast(*next_source)->length() == 0); | 
 |   72   } | 
 |   73  | 
 |   74   // If the target is deprecated, the object will be updated on first store. If | 
 |   75   // the source for that store equals the target, this will invalidate the | 
 |   76   // cached representation of the source. Preventively upgrade the target. | 
 |   77   // Do this on each iteration since any property load could cause deprecation. | 
 |   78   if (to->map()->is_deprecated()) { | 
 |   79     JSObject::MigrateInstance(Handle<JSObject>::cast(to)); | 
 |   80   } | 
 |   81  | 
 |   82   Isolate* isolate = to->GetIsolate(); | 
 |   83   Handle<Map> map(JSReceiver::cast(*next_source)->map(), isolate); | 
 |   84  | 
 |   85   if (!map->IsJSObjectMap()) return Just(false); | 
 |   86   if (!map->OnlyHasSimpleProperties()) return Just(false); | 
 |   87  | 
 |   88   Handle<JSObject> from = Handle<JSObject>::cast(next_source); | 
 |   89   if (from->elements() != isolate->heap()->empty_fixed_array()) { | 
 |   90     return Just(false); | 
 |   91   } | 
 |   92  | 
 |   93   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate); | 
 |   94   int length = map->NumberOfOwnDescriptors(); | 
 |   95  | 
 |   96   bool stable = true; | 
 |   97  | 
 |   98   for (int i = 0; i < length; i++) { | 
 |   99     Handle<Name> next_key(descriptors->GetKey(i), isolate); | 
 |  100     Handle<Object> prop_value; | 
 |  101     // Directly decode from the descriptor array if |from| did not change shape. | 
 |  102     if (stable) { | 
 |  103       PropertyDetails details = descriptors->GetDetails(i); | 
 |  104       if (!details.IsEnumerable()) continue; | 
 |  105       if (details.kind() == kData) { | 
 |  106         if (details.location() == kDescriptor) { | 
 |  107           prop_value = handle(descriptors->GetValue(i), isolate); | 
 |  108         } else { | 
 |  109           Representation representation = details.representation(); | 
 |  110           FieldIndex index = FieldIndex::ForDescriptor(*map, i); | 
 |  111           prop_value = JSObject::FastPropertyAt(from, representation, index); | 
 |  112         } | 
 |  113       } else { | 
 |  114         ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 
 |  115             isolate, prop_value, JSReceiver::GetProperty(from, next_key), | 
 |  116             Nothing<bool>()); | 
 |  117         stable = from->map() == *map; | 
 |  118       } | 
 |  119     } else { | 
 |  120       // If the map did change, do a slower lookup. We are still guaranteed that | 
 |  121       // the object has a simple shape, and that the key is a name. | 
 |  122       LookupIterator it(from, next_key, from, | 
 |  123                         LookupIterator::OWN_SKIP_INTERCEPTOR); | 
 |  124       if (!it.IsFound()) continue; | 
 |  125       DCHECK(it.state() == LookupIterator::DATA || | 
 |  126              it.state() == LookupIterator::ACCESSOR); | 
 |  127       if (!it.IsEnumerable()) continue; | 
 |  128       ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 
 |  129           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>()); | 
 |  130     } | 
 |  131     LookupIterator it(to, next_key, to); | 
 |  132     bool call_to_js = it.IsFound() && it.state() != LookupIterator::DATA; | 
 |  133     Maybe<bool> result = Object::SetProperty( | 
 |  134         &it, prop_value, STRICT, Object::CERTAINLY_NOT_STORE_FROM_KEYED); | 
 |  135     if (result.IsNothing()) return result; | 
 |  136     if (stable && call_to_js) stable = from->map() == *map; | 
 |  137   } | 
 |  138  | 
 |  139   return Just(true); | 
 |  140 } | 
 |  141  | 
 |  142 }  // namespace | 
 |  143  | 
 |  144 // ES6 19.1.2.1 Object.assign | 
 |  145 BUILTIN(ObjectAssign) { | 
 |  146   HandleScope scope(isolate); | 
 |  147   Handle<Object> target = args.atOrUndefined(isolate, 1); | 
 |  148  | 
 |  149   // 1. Let to be ? ToObject(target). | 
 |  150   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target, | 
 |  151                                      Object::ToObject(isolate, target)); | 
 |  152   Handle<JSReceiver> to = Handle<JSReceiver>::cast(target); | 
 |  153   // 2. If only one argument was passed, return to. | 
 |  154   if (args.length() == 2) return *to; | 
 |  155   // 3. Let sources be the List of argument values starting with the | 
 |  156   //    second argument. | 
 |  157   // 4. For each element nextSource of sources, in ascending index order, | 
 |  158   for (int i = 2; i < args.length(); ++i) { | 
 |  159     Handle<Object> next_source = args.at<Object>(i); | 
 |  160     Maybe<bool> fast_assign = FastAssign(to, next_source); | 
 |  161     if (fast_assign.IsNothing()) return isolate->heap()->exception(); | 
 |  162     if (fast_assign.FromJust()) continue; | 
 |  163     // 4a. If nextSource is undefined or null, let keys be an empty List. | 
 |  164     // 4b. Else, | 
 |  165     // 4b i. Let from be ToObject(nextSource). | 
 |  166     // Only non-empty strings and JSReceivers have enumerable properties. | 
 |  167     Handle<JSReceiver> from = | 
 |  168         Object::ToObject(isolate, next_source).ToHandleChecked(); | 
 |  169     // 4b ii. Let keys be ? from.[[OwnPropertyKeys]](). | 
 |  170     Handle<FixedArray> keys; | 
 |  171     ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
 |  172         isolate, keys, KeyAccumulator::GetKeys( | 
 |  173                            from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES, | 
 |  174                            GetKeysConversion::kKeepNumbers)); | 
 |  175     // 4c. Repeat for each element nextKey of keys in List order, | 
 |  176     for (int j = 0; j < keys->length(); ++j) { | 
 |  177       Handle<Object> next_key(keys->get(j), isolate); | 
 |  178       // 4c i. Let desc be ? from.[[GetOwnProperty]](nextKey). | 
 |  179       PropertyDescriptor desc; | 
 |  180       Maybe<bool> found = | 
 |  181           JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc); | 
 |  182       if (found.IsNothing()) return isolate->heap()->exception(); | 
 |  183       // 4c ii. If desc is not undefined and desc.[[Enumerable]] is true, then | 
 |  184       if (found.FromJust() && desc.enumerable()) { | 
 |  185         // 4c ii 1. Let propValue be ? Get(from, nextKey). | 
 |  186         Handle<Object> prop_value; | 
 |  187         ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
 |  188             isolate, prop_value, | 
 |  189             Runtime::GetObjectProperty(isolate, from, next_key)); | 
 |  190         // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true). | 
 |  191         Handle<Object> status; | 
 |  192         ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
 |  193             isolate, status, Runtime::SetObjectProperty(isolate, to, next_key, | 
 |  194                                                         prop_value, STRICT)); | 
 |  195       } | 
 |  196     } | 
 |  197   } | 
 |  198   // 5. Return to. | 
 |  199   return *to; | 
 |  200 } | 
 |  201  | 
 |  202 // ES6 section 19.1.3.4 Object.prototype.propertyIsEnumerable ( V ) | 
 |  203 BUILTIN(ObjectPrototypePropertyIsEnumerable) { | 
 |  204   HandleScope scope(isolate); | 
 |  205   Handle<JSReceiver> object; | 
 |  206   Handle<Name> name; | 
 |  207   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
 |  208       isolate, name, Object::ToName(isolate, args.atOrUndefined(isolate, 1))); | 
 |  209   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
 |  210       isolate, object, JSReceiver::ToObject(isolate, args.receiver())); | 
 |  211   Maybe<PropertyAttributes> maybe = | 
 |  212       JSReceiver::GetOwnPropertyAttributes(object, name); | 
 |  213   if (!maybe.IsJust()) return isolate->heap()->exception(); | 
 |  214   if (maybe.FromJust() == ABSENT) return isolate->heap()->false_value(); | 
 |  215   return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0); | 
 |  216 } | 
 |  217  | 
 |  218 namespace {  // anonymous namespace for ObjectProtoToString() | 
 |  219  | 
 |  220 void IsString(CodeStubAssembler* assembler, compiler::Node* object, | 
 |  221               CodeStubAssembler::Label* if_string, | 
 |  222               CodeStubAssembler::Label* if_notstring) { | 
 |  223   typedef compiler::Node Node; | 
 |  224   typedef CodeStubAssembler::Label Label; | 
 |  225  | 
 |  226   Label if_notsmi(assembler); | 
 |  227   assembler->Branch(assembler->WordIsSmi(object), if_notstring, &if_notsmi); | 
 |  228  | 
 |  229   assembler->Bind(&if_notsmi); | 
 |  230   { | 
 |  231     Node* instance_type = assembler->LoadInstanceType(object); | 
 |  232  | 
 |  233     assembler->Branch( | 
 |  234         assembler->Int32LessThan( | 
 |  235             instance_type, assembler->Int32Constant(FIRST_NONSTRING_TYPE)), | 
 |  236         if_string, if_notstring); | 
 |  237   } | 
 |  238 } | 
 |  239  | 
 |  240 void ReturnToStringFormat(CodeStubAssembler* assembler, compiler::Node* context, | 
 |  241                           compiler::Node* string) { | 
 |  242   typedef compiler::Node Node; | 
 |  243  | 
 |  244   Node* lhs = assembler->HeapConstant( | 
 |  245       assembler->factory()->NewStringFromStaticChars("[object ")); | 
 |  246   Node* rhs = assembler->HeapConstant( | 
 |  247       assembler->factory()->NewStringFromStaticChars("]")); | 
 |  248  | 
 |  249   Callable callable = CodeFactory::StringAdd( | 
 |  250       assembler->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); | 
 |  251  | 
 |  252   assembler->Return(assembler->CallStub( | 
 |  253       callable, context, assembler->CallStub(callable, context, lhs, string), | 
 |  254       rhs)); | 
 |  255 } | 
 |  256  | 
 |  257 void ReturnIfPrimitive(CodeStubAssembler* assembler, | 
 |  258                        compiler::Node* instance_type, | 
 |  259                        CodeStubAssembler::Label* return_string, | 
 |  260                        CodeStubAssembler::Label* return_boolean, | 
 |  261                        CodeStubAssembler::Label* return_number) { | 
 |  262   assembler->GotoIf( | 
 |  263       assembler->Int32LessThan(instance_type, | 
 |  264                                assembler->Int32Constant(FIRST_NONSTRING_TYPE)), | 
 |  265       return_string); | 
 |  266  | 
 |  267   assembler->GotoIf(assembler->Word32Equal( | 
 |  268                         instance_type, assembler->Int32Constant(ODDBALL_TYPE)), | 
 |  269                     return_boolean); | 
 |  270  | 
 |  271   assembler->GotoIf( | 
 |  272       assembler->Word32Equal(instance_type, | 
 |  273                              assembler->Int32Constant(HEAP_NUMBER_TYPE)), | 
 |  274       return_number); | 
 |  275 } | 
 |  276  | 
 |  277 }  // namespace | 
 |  278  | 
 |  279 // ES6 section 19.1.3.6 Object.prototype.toString | 
 |  280 void Builtins::Generate_ObjectProtoToString(CodeStubAssembler* assembler) { | 
 |  281   typedef compiler::Node Node; | 
 |  282   typedef CodeStubAssembler::Label Label; | 
 |  283   typedef CodeStubAssembler::Variable Variable; | 
 |  284  | 
 |  285   Label return_undefined(assembler, Label::kDeferred), | 
 |  286       return_null(assembler, Label::kDeferred), | 
 |  287       return_arguments(assembler, Label::kDeferred), return_array(assembler), | 
 |  288       return_api(assembler, Label::kDeferred), return_object(assembler), | 
 |  289       return_regexp(assembler), return_function(assembler), | 
 |  290       return_error(assembler), return_date(assembler), return_string(assembler), | 
 |  291       return_boolean(assembler), return_jsvalue(assembler), | 
 |  292       return_jsproxy(assembler, Label::kDeferred), return_number(assembler); | 
 |  293  | 
 |  294   Label if_isproxy(assembler, Label::kDeferred); | 
 |  295  | 
 |  296   Label checkstringtag(assembler); | 
 |  297   Label if_tostringtag(assembler), if_notostringtag(assembler); | 
 |  298  | 
 |  299   Node* receiver = assembler->Parameter(0); | 
 |  300   Node* context = assembler->Parameter(3); | 
 |  301  | 
 |  302   assembler->GotoIf( | 
 |  303       assembler->Word32Equal(receiver, assembler->UndefinedConstant()), | 
 |  304       &return_undefined); | 
 |  305  | 
 |  306   assembler->GotoIf(assembler->Word32Equal(receiver, assembler->NullConstant()), | 
 |  307                     &return_null); | 
 |  308  | 
 |  309   assembler->GotoIf(assembler->WordIsSmi(receiver), &return_number); | 
 |  310  | 
 |  311   Node* receiver_instance_type = assembler->LoadInstanceType(receiver); | 
 |  312   ReturnIfPrimitive(assembler, receiver_instance_type, &return_string, | 
 |  313                     &return_boolean, &return_number); | 
 |  314  | 
 |  315   // for proxies, check IsArray before getting @@toStringTag | 
 |  316   Variable var_proxy_is_array(assembler, MachineRepresentation::kTagged); | 
 |  317   var_proxy_is_array.Bind(assembler->BooleanConstant(false)); | 
 |  318  | 
 |  319   assembler->Branch( | 
 |  320       assembler->Word32Equal(receiver_instance_type, | 
 |  321                              assembler->Int32Constant(JS_PROXY_TYPE)), | 
 |  322       &if_isproxy, &checkstringtag); | 
 |  323  | 
 |  324   assembler->Bind(&if_isproxy); | 
 |  325   { | 
 |  326     // This can throw | 
 |  327     var_proxy_is_array.Bind( | 
 |  328         assembler->CallRuntime(Runtime::kArrayIsArray, context, receiver)); | 
 |  329     assembler->Goto(&checkstringtag); | 
 |  330   } | 
 |  331  | 
 |  332   assembler->Bind(&checkstringtag); | 
 |  333   { | 
 |  334     Node* to_string_tag_symbol = assembler->HeapConstant( | 
 |  335         assembler->isolate()->factory()->to_string_tag_symbol()); | 
 |  336  | 
 |  337     GetPropertyStub stub(assembler->isolate()); | 
 |  338     Callable get_property = | 
 |  339         Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); | 
 |  340     Node* to_string_tag_value = assembler->CallStub( | 
 |  341         get_property, context, receiver, to_string_tag_symbol); | 
 |  342  | 
 |  343     IsString(assembler, to_string_tag_value, &if_tostringtag, | 
 |  344              &if_notostringtag); | 
 |  345  | 
 |  346     assembler->Bind(&if_tostringtag); | 
 |  347     ReturnToStringFormat(assembler, context, to_string_tag_value); | 
 |  348   } | 
 |  349   assembler->Bind(&if_notostringtag); | 
 |  350   { | 
 |  351     size_t const kNumCases = 11; | 
 |  352     Label* case_labels[kNumCases]; | 
 |  353     int32_t case_values[kNumCases]; | 
 |  354     case_labels[0] = &return_api; | 
 |  355     case_values[0] = JS_API_OBJECT_TYPE; | 
 |  356     case_labels[1] = &return_api; | 
 |  357     case_values[1] = JS_SPECIAL_API_OBJECT_TYPE; | 
 |  358     case_labels[2] = &return_arguments; | 
 |  359     case_values[2] = JS_ARGUMENTS_TYPE; | 
 |  360     case_labels[3] = &return_array; | 
 |  361     case_values[3] = JS_ARRAY_TYPE; | 
 |  362     case_labels[4] = &return_function; | 
 |  363     case_values[4] = JS_BOUND_FUNCTION_TYPE; | 
 |  364     case_labels[5] = &return_function; | 
 |  365     case_values[5] = JS_FUNCTION_TYPE; | 
 |  366     case_labels[6] = &return_error; | 
 |  367     case_values[6] = JS_ERROR_TYPE; | 
 |  368     case_labels[7] = &return_date; | 
 |  369     case_values[7] = JS_DATE_TYPE; | 
 |  370     case_labels[8] = &return_regexp; | 
 |  371     case_values[8] = JS_REGEXP_TYPE; | 
 |  372     case_labels[9] = &return_jsvalue; | 
 |  373     case_values[9] = JS_VALUE_TYPE; | 
 |  374     case_labels[10] = &return_jsproxy; | 
 |  375     case_values[10] = JS_PROXY_TYPE; | 
 |  376  | 
 |  377     assembler->Switch(receiver_instance_type, &return_object, case_values, | 
 |  378                       case_labels, arraysize(case_values)); | 
 |  379  | 
 |  380     assembler->Bind(&return_undefined); | 
 |  381     assembler->Return(assembler->HeapConstant( | 
 |  382         assembler->isolate()->factory()->undefined_to_string())); | 
 |  383  | 
 |  384     assembler->Bind(&return_null); | 
 |  385     assembler->Return(assembler->HeapConstant( | 
 |  386         assembler->isolate()->factory()->null_to_string())); | 
 |  387  | 
 |  388     assembler->Bind(&return_number); | 
 |  389     assembler->Return(assembler->HeapConstant( | 
 |  390         assembler->isolate()->factory()->number_to_string())); | 
 |  391  | 
 |  392     assembler->Bind(&return_string); | 
 |  393     assembler->Return(assembler->HeapConstant( | 
 |  394         assembler->isolate()->factory()->string_to_string())); | 
 |  395  | 
 |  396     assembler->Bind(&return_boolean); | 
 |  397     assembler->Return(assembler->HeapConstant( | 
 |  398         assembler->isolate()->factory()->boolean_to_string())); | 
 |  399  | 
 |  400     assembler->Bind(&return_arguments); | 
 |  401     assembler->Return(assembler->HeapConstant( | 
 |  402         assembler->isolate()->factory()->arguments_to_string())); | 
 |  403  | 
 |  404     assembler->Bind(&return_array); | 
 |  405     assembler->Return(assembler->HeapConstant( | 
 |  406         assembler->isolate()->factory()->array_to_string())); | 
 |  407  | 
 |  408     assembler->Bind(&return_function); | 
 |  409     assembler->Return(assembler->HeapConstant( | 
 |  410         assembler->isolate()->factory()->function_to_string())); | 
 |  411  | 
 |  412     assembler->Bind(&return_error); | 
 |  413     assembler->Return(assembler->HeapConstant( | 
 |  414         assembler->isolate()->factory()->error_to_string())); | 
 |  415  | 
 |  416     assembler->Bind(&return_date); | 
 |  417     assembler->Return(assembler->HeapConstant( | 
 |  418         assembler->isolate()->factory()->date_to_string())); | 
 |  419  | 
 |  420     assembler->Bind(&return_regexp); | 
 |  421     assembler->Return(assembler->HeapConstant( | 
 |  422         assembler->isolate()->factory()->regexp_to_string())); | 
 |  423  | 
 |  424     assembler->Bind(&return_api); | 
 |  425     { | 
 |  426       Node* class_name = | 
 |  427           assembler->CallRuntime(Runtime::kClassOf, context, receiver); | 
 |  428       ReturnToStringFormat(assembler, context, class_name); | 
 |  429     } | 
 |  430  | 
 |  431     assembler->Bind(&return_jsvalue); | 
 |  432     { | 
 |  433       Node* value = assembler->LoadJSValueValue(receiver); | 
 |  434       assembler->GotoIf(assembler->WordIsSmi(value), &return_number); | 
 |  435  | 
 |  436       ReturnIfPrimitive(assembler, assembler->LoadInstanceType(value), | 
 |  437                         &return_string, &return_boolean, &return_number); | 
 |  438       assembler->Goto(&return_object); | 
 |  439     } | 
 |  440  | 
 |  441     assembler->Bind(&return_jsproxy); | 
 |  442     { | 
 |  443       assembler->GotoIf(assembler->WordEqual(var_proxy_is_array.value(), | 
 |  444                                              assembler->BooleanConstant(true)), | 
 |  445                         &return_array); | 
 |  446  | 
 |  447       Node* map = assembler->LoadMap(receiver); | 
 |  448  | 
 |  449       // Return object if the proxy {receiver} is not callable. | 
 |  450       assembler->Branch( | 
 |  451           assembler->Word32Equal( | 
 |  452               assembler->Word32And( | 
 |  453                   assembler->LoadMapBitField(map), | 
 |  454                   assembler->Int32Constant(1 << Map::kIsCallable)), | 
 |  455               assembler->Int32Constant(0)), | 
 |  456           &return_object, &return_function); | 
 |  457     } | 
 |  458  | 
 |  459     // Default | 
 |  460     assembler->Bind(&return_object); | 
 |  461     assembler->Return(assembler->HeapConstant( | 
 |  462         assembler->isolate()->factory()->object_to_string())); | 
 |  463   } | 
 |  464 } | 
 |  465  | 
 |  466 // ES6 section 19.1.2.2 Object.create ( O [ , Properties ] ) | 
 |  467 // TODO(verwaest): Support the common cases with precached map directly in | 
 |  468 // an Object.create stub. | 
 |  469 BUILTIN(ObjectCreate) { | 
 |  470   HandleScope scope(isolate); | 
 |  471   Handle<Object> prototype = args.atOrUndefined(isolate, 1); | 
 |  472   if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) { | 
 |  473     THROW_NEW_ERROR_RETURN_FAILURE( | 
 |  474         isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype)); | 
 |  475   } | 
 |  476  | 
 |  477   // Generate the map with the specified {prototype} based on the Object | 
 |  478   // function's initial map from the current native context. | 
 |  479   // TODO(bmeurer): Use a dedicated cache for Object.create; think about | 
 |  480   // slack tracking for Object.create. | 
 |  481   Handle<Map> map(isolate->native_context()->object_function()->initial_map(), | 
 |  482                   isolate); | 
 |  483   if (map->prototype() != *prototype) { | 
 |  484     if (prototype->IsNull(isolate)) { | 
 |  485       map = isolate->object_with_null_prototype_map(); | 
 |  486     } else if (prototype->IsJSObject()) { | 
 |  487       Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype); | 
 |  488       if (!js_prototype->map()->is_prototype_map()) { | 
 |  489         JSObject::OptimizeAsPrototype(js_prototype, FAST_PROTOTYPE); | 
 |  490       } | 
 |  491       Handle<PrototypeInfo> info = | 
 |  492           Map::GetOrCreatePrototypeInfo(js_prototype, isolate); | 
 |  493       // TODO(verwaest): Use inobject slack tracking for this map. | 
 |  494       if (info->HasObjectCreateMap()) { | 
 |  495         map = handle(info->ObjectCreateMap(), isolate); | 
 |  496       } else { | 
 |  497         map = Map::CopyInitialMap(map); | 
 |  498         Map::SetPrototype(map, prototype, FAST_PROTOTYPE); | 
 |  499         PrototypeInfo::SetObjectCreateMap(info, map); | 
 |  500       } | 
 |  501     } else { | 
 |  502       map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE); | 
 |  503     } | 
 |  504   } | 
 |  505  | 
 |  506   // Actually allocate the object. | 
 |  507   Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(map); | 
 |  508  | 
 |  509   // Define the properties if properties was specified and is not undefined. | 
 |  510   Handle<Object> properties = args.atOrUndefined(isolate, 2); | 
 |  511   if (!properties->IsUndefined(isolate)) { | 
 |  512     RETURN_FAILURE_ON_EXCEPTION( | 
 |  513         isolate, JSReceiver::DefineProperties(isolate, object, properties)); | 
 |  514   } | 
 |  515  | 
 |  516   return *object; | 
 |  517 } | 
 |  518  | 
 |  519 // ES6 section 19.1.2.3 Object.defineProperties | 
 |  520 BUILTIN(ObjectDefineProperties) { | 
 |  521   HandleScope scope(isolate); | 
 |  522   DCHECK_EQ(3, args.length()); | 
 |  523   Handle<Object> target = args.at<Object>(1); | 
 |  524   Handle<Object> properties = args.at<Object>(2); | 
 |  525  | 
 |  526   RETURN_RESULT_OR_FAILURE( | 
 |  527       isolate, JSReceiver::DefineProperties(isolate, target, properties)); | 
 |  528 } | 
 |  529  | 
 |  530 // ES6 section 19.1.2.4 Object.defineProperty | 
 |  531 BUILTIN(ObjectDefineProperty) { | 
 |  532   HandleScope scope(isolate); | 
 |  533   DCHECK_EQ(4, args.length()); | 
 |  534   Handle<Object> target = args.at<Object>(1); | 
 |  535   Handle<Object> key = args.at<Object>(2); | 
 |  536   Handle<Object> attributes = args.at<Object>(3); | 
 |  537  | 
 |  538   return JSReceiver::DefineProperty(isolate, target, key, attributes); | 
 |  539 } | 
 |  540  | 
 |  541 namespace { | 
 |  542  | 
 |  543 template <AccessorComponent which_accessor> | 
 |  544 Object* ObjectDefineAccessor(Isolate* isolate, Handle<Object> object, | 
 |  545                              Handle<Object> name, Handle<Object> accessor) { | 
 |  546   // 1. Let O be ? ToObject(this value). | 
 |  547   Handle<JSReceiver> receiver; | 
 |  548   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 
 |  549                                      Object::ConvertReceiver(isolate, object)); | 
 |  550   // 2. If IsCallable(getter) is false, throw a TypeError exception. | 
 |  551   if (!accessor->IsCallable()) { | 
 |  552     MessageTemplate::Template message = | 
 |  553         which_accessor == ACCESSOR_GETTER | 
 |  554             ? MessageTemplate::kObjectGetterExpectingFunction | 
 |  555             : MessageTemplate::kObjectSetterExpectingFunction; | 
 |  556     THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(message)); | 
 |  557   } | 
 |  558   // 3. Let desc be PropertyDescriptor{[[Get]]: getter, [[Enumerable]]: true, | 
 |  559   //                                   [[Configurable]]: true}. | 
 |  560   PropertyDescriptor desc; | 
 |  561   if (which_accessor == ACCESSOR_GETTER) { | 
 |  562     desc.set_get(accessor); | 
 |  563   } else { | 
 |  564     DCHECK(which_accessor == ACCESSOR_SETTER); | 
 |  565     desc.set_set(accessor); | 
 |  566   } | 
 |  567   desc.set_enumerable(true); | 
 |  568   desc.set_configurable(true); | 
 |  569   // 4. Let key be ? ToPropertyKey(P). | 
 |  570   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, | 
 |  571                                      Object::ToPropertyKey(isolate, name)); | 
 |  572   // 5. Perform ? DefinePropertyOrThrow(O, key, desc). | 
 |  573   // To preserve legacy behavior, we ignore errors silently rather than | 
 |  574   // throwing an exception. | 
 |  575   Maybe<bool> success = JSReceiver::DefineOwnProperty( | 
 |  576       isolate, receiver, name, &desc, Object::DONT_THROW); | 
 |  577   MAYBE_RETURN(success, isolate->heap()->exception()); | 
 |  578   if (!success.FromJust()) { | 
 |  579     isolate->CountUsage(v8::Isolate::kDefineGetterOrSetterWouldThrow); | 
 |  580   } | 
 |  581   // 6. Return undefined. | 
 |  582   return isolate->heap()->undefined_value(); | 
 |  583 } | 
 |  584  | 
 |  585 Object* ObjectLookupAccessor(Isolate* isolate, Handle<Object> object, | 
 |  586                              Handle<Object> key, AccessorComponent component) { | 
 |  587   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, object, | 
 |  588                                      Object::ConvertReceiver(isolate, object)); | 
 |  589   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, | 
 |  590                                      Object::ToPropertyKey(isolate, key)); | 
 |  591   bool success = false; | 
 |  592   LookupIterator it = LookupIterator::PropertyOrElement( | 
 |  593       isolate, object, key, &success, | 
 |  594       LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); | 
 |  595   DCHECK(success); | 
 |  596  | 
 |  597   for (; it.IsFound(); it.Next()) { | 
 |  598     switch (it.state()) { | 
 |  599       case LookupIterator::INTERCEPTOR: | 
 |  600       case LookupIterator::NOT_FOUND: | 
 |  601       case LookupIterator::TRANSITION: | 
 |  602         UNREACHABLE(); | 
 |  603  | 
 |  604       case LookupIterator::ACCESS_CHECK: | 
 |  605         if (it.HasAccess()) continue; | 
 |  606         isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>()); | 
 |  607         RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 
 |  608         return isolate->heap()->undefined_value(); | 
 |  609  | 
 |  610       case LookupIterator::JSPROXY: | 
 |  611         return isolate->heap()->undefined_value(); | 
 |  612  | 
 |  613       case LookupIterator::INTEGER_INDEXED_EXOTIC: | 
 |  614         return isolate->heap()->undefined_value(); | 
 |  615       case LookupIterator::DATA: | 
 |  616         continue; | 
 |  617       case LookupIterator::ACCESSOR: { | 
 |  618         Handle<Object> maybe_pair = it.GetAccessors(); | 
 |  619         if (maybe_pair->IsAccessorPair()) { | 
 |  620           return *AccessorPair::GetComponent( | 
 |  621               Handle<AccessorPair>::cast(maybe_pair), component); | 
 |  622         } | 
 |  623       } | 
 |  624     } | 
 |  625   } | 
 |  626  | 
 |  627   return isolate->heap()->undefined_value(); | 
 |  628 } | 
 |  629  | 
 |  630 }  // namespace | 
 |  631  | 
 |  632 // ES6 B.2.2.2 a.k.a. | 
 |  633 // https://tc39.github.io/ecma262/#sec-object.prototype.__defineGetter__ | 
 |  634 BUILTIN(ObjectDefineGetter) { | 
 |  635   HandleScope scope(isolate); | 
 |  636   Handle<Object> object = args.at<Object>(0);  // Receiver. | 
 |  637   Handle<Object> name = args.at<Object>(1); | 
 |  638   Handle<Object> getter = args.at<Object>(2); | 
 |  639   return ObjectDefineAccessor<ACCESSOR_GETTER>(isolate, object, name, getter); | 
 |  640 } | 
 |  641  | 
 |  642 // ES6 B.2.2.3 a.k.a. | 
 |  643 // https://tc39.github.io/ecma262/#sec-object.prototype.__defineSetter__ | 
 |  644 BUILTIN(ObjectDefineSetter) { | 
 |  645   HandleScope scope(isolate); | 
 |  646   Handle<Object> object = args.at<Object>(0);  // Receiver. | 
 |  647   Handle<Object> name = args.at<Object>(1); | 
 |  648   Handle<Object> setter = args.at<Object>(2); | 
 |  649   return ObjectDefineAccessor<ACCESSOR_SETTER>(isolate, object, name, setter); | 
 |  650 } | 
 |  651  | 
 |  652 // ES6 B.2.2.4 a.k.a. | 
 |  653 // https://tc39.github.io/ecma262/#sec-object.prototype.__lookupGetter__ | 
 |  654 BUILTIN(ObjectLookupGetter) { | 
 |  655   HandleScope scope(isolate); | 
 |  656   Handle<Object> object = args.at<Object>(0); | 
 |  657   Handle<Object> name = args.at<Object>(1); | 
 |  658   return ObjectLookupAccessor(isolate, object, name, ACCESSOR_GETTER); | 
 |  659 } | 
 |  660  | 
 |  661 // ES6 B.2.2.5 a.k.a. | 
 |  662 // https://tc39.github.io/ecma262/#sec-object.prototype.__lookupSetter__ | 
 |  663 BUILTIN(ObjectLookupSetter) { | 
 |  664   HandleScope scope(isolate); | 
 |  665   Handle<Object> object = args.at<Object>(0); | 
 |  666   Handle<Object> name = args.at<Object>(1); | 
 |  667   return ObjectLookupAccessor(isolate, object, name, ACCESSOR_SETTER); | 
 |  668 } | 
 |  669  | 
 |  670 // ES6 section 19.1.2.5 Object.freeze ( O ) | 
 |  671 BUILTIN(ObjectFreeze) { | 
 |  672   HandleScope scope(isolate); | 
 |  673   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  674   if (object->IsJSReceiver()) { | 
 |  675     MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object), | 
 |  676                                                FROZEN, Object::THROW_ON_ERROR), | 
 |  677                  isolate->heap()->exception()); | 
 |  678   } | 
 |  679   return *object; | 
 |  680 } | 
 |  681  | 
 |  682 // ES section 19.1.2.9 Object.getPrototypeOf ( O ) | 
 |  683 BUILTIN(ObjectGetPrototypeOf) { | 
 |  684   HandleScope scope(isolate); | 
 |  685   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  686  | 
 |  687   Handle<JSReceiver> receiver; | 
 |  688   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 
 |  689                                      Object::ToObject(isolate, object)); | 
 |  690  | 
 |  691   RETURN_RESULT_OR_FAILURE(isolate, | 
 |  692                            JSReceiver::GetPrototype(isolate, receiver)); | 
 |  693 } | 
 |  694  | 
 |  695 // ES6 section 19.1.2.6 Object.getOwnPropertyDescriptor ( O, P ) | 
 |  696 BUILTIN(ObjectGetOwnPropertyDescriptor) { | 
 |  697   HandleScope scope(isolate); | 
 |  698   // 1. Let obj be ? ToObject(O). | 
 |  699   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  700   Handle<JSReceiver> receiver; | 
 |  701   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 
 |  702                                      Object::ToObject(isolate, object)); | 
 |  703   // 2. Let key be ? ToPropertyKey(P). | 
 |  704   Handle<Object> property = args.atOrUndefined(isolate, 2); | 
 |  705   Handle<Name> key; | 
 |  706   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key, | 
 |  707                                      Object::ToName(isolate, property)); | 
 |  708   // 3. Let desc be ? obj.[[GetOwnProperty]](key). | 
 |  709   PropertyDescriptor desc; | 
 |  710   Maybe<bool> found = | 
 |  711       JSReceiver::GetOwnPropertyDescriptor(isolate, receiver, key, &desc); | 
 |  712   MAYBE_RETURN(found, isolate->heap()->exception()); | 
 |  713   // 4. Return FromPropertyDescriptor(desc). | 
 |  714   if (!found.FromJust()) return isolate->heap()->undefined_value(); | 
 |  715   return *desc.ToObject(isolate); | 
 |  716 } | 
 |  717  | 
 |  718 namespace { | 
 |  719  | 
 |  720 Object* GetOwnPropertyKeys(Isolate* isolate, BuiltinArguments args, | 
 |  721                            PropertyFilter filter) { | 
 |  722   HandleScope scope(isolate); | 
 |  723   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  724   Handle<JSReceiver> receiver; | 
 |  725   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 
 |  726                                      Object::ToObject(isolate, object)); | 
 |  727   Handle<FixedArray> keys; | 
 |  728   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
 |  729       isolate, keys, | 
 |  730       KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly, filter, | 
 |  731                               GetKeysConversion::kConvertToString)); | 
 |  732   return *isolate->factory()->NewJSArrayWithElements(keys); | 
 |  733 } | 
 |  734  | 
 |  735 }  // namespace | 
 |  736  | 
 |  737 // ES6 section 19.1.2.7 Object.getOwnPropertyNames ( O ) | 
 |  738 BUILTIN(ObjectGetOwnPropertyNames) { | 
 |  739   return GetOwnPropertyKeys(isolate, args, SKIP_SYMBOLS); | 
 |  740 } | 
 |  741  | 
 |  742 // ES6 section 19.1.2.8 Object.getOwnPropertySymbols ( O ) | 
 |  743 BUILTIN(ObjectGetOwnPropertySymbols) { | 
 |  744   return GetOwnPropertyKeys(isolate, args, SKIP_STRINGS); | 
 |  745 } | 
 |  746  | 
 |  747 // ES#sec-object.is Object.is ( value1, value2 ) | 
 |  748 BUILTIN(ObjectIs) { | 
 |  749   SealHandleScope shs(isolate); | 
 |  750   DCHECK_EQ(3, args.length()); | 
 |  751   Handle<Object> value1 = args.at<Object>(1); | 
 |  752   Handle<Object> value2 = args.at<Object>(2); | 
 |  753   return isolate->heap()->ToBoolean(value1->SameValue(*value2)); | 
 |  754 } | 
 |  755  | 
 |  756 // ES6 section 19.1.2.11 Object.isExtensible ( O ) | 
 |  757 BUILTIN(ObjectIsExtensible) { | 
 |  758   HandleScope scope(isolate); | 
 |  759   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  760   Maybe<bool> result = | 
 |  761       object->IsJSReceiver() | 
 |  762           ? JSReceiver::IsExtensible(Handle<JSReceiver>::cast(object)) | 
 |  763           : Just(false); | 
 |  764   MAYBE_RETURN(result, isolate->heap()->exception()); | 
 |  765   return isolate->heap()->ToBoolean(result.FromJust()); | 
 |  766 } | 
 |  767  | 
 |  768 // ES6 section 19.1.2.12 Object.isFrozen ( O ) | 
 |  769 BUILTIN(ObjectIsFrozen) { | 
 |  770   HandleScope scope(isolate); | 
 |  771   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  772   Maybe<bool> result = object->IsJSReceiver() | 
 |  773                            ? JSReceiver::TestIntegrityLevel( | 
 |  774                                  Handle<JSReceiver>::cast(object), FROZEN) | 
 |  775                            : Just(true); | 
 |  776   MAYBE_RETURN(result, isolate->heap()->exception()); | 
 |  777   return isolate->heap()->ToBoolean(result.FromJust()); | 
 |  778 } | 
 |  779  | 
 |  780 // ES6 section 19.1.2.13 Object.isSealed ( O ) | 
 |  781 BUILTIN(ObjectIsSealed) { | 
 |  782   HandleScope scope(isolate); | 
 |  783   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  784   Maybe<bool> result = object->IsJSReceiver() | 
 |  785                            ? JSReceiver::TestIntegrityLevel( | 
 |  786                                  Handle<JSReceiver>::cast(object), SEALED) | 
 |  787                            : Just(true); | 
 |  788   MAYBE_RETURN(result, isolate->heap()->exception()); | 
 |  789   return isolate->heap()->ToBoolean(result.FromJust()); | 
 |  790 } | 
 |  791  | 
 |  792 // ES6 section 19.1.2.14 Object.keys ( O ) | 
 |  793 BUILTIN(ObjectKeys) { | 
 |  794   HandleScope scope(isolate); | 
 |  795   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  796   Handle<JSReceiver> receiver; | 
 |  797   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 
 |  798                                      Object::ToObject(isolate, object)); | 
 |  799  | 
 |  800   Handle<FixedArray> keys; | 
 |  801   int enum_length = receiver->map()->EnumLength(); | 
 |  802   if (enum_length != kInvalidEnumCacheSentinel && | 
 |  803       JSObject::cast(*receiver)->elements() == | 
 |  804           isolate->heap()->empty_fixed_array()) { | 
 |  805     DCHECK(receiver->IsJSObject()); | 
 |  806     DCHECK(!JSObject::cast(*receiver)->HasNamedInterceptor()); | 
 |  807     DCHECK(!JSObject::cast(*receiver)->IsAccessCheckNeeded()); | 
 |  808     DCHECK(!receiver->map()->has_hidden_prototype()); | 
 |  809     DCHECK(JSObject::cast(*receiver)->HasFastProperties()); | 
 |  810     if (enum_length == 0) { | 
 |  811       keys = isolate->factory()->empty_fixed_array(); | 
 |  812     } else { | 
 |  813       Handle<FixedArray> cache( | 
 |  814           receiver->map()->instance_descriptors()->GetEnumCache()); | 
 |  815       keys = isolate->factory()->CopyFixedArrayUpTo(cache, enum_length); | 
 |  816     } | 
 |  817   } else { | 
 |  818     ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
 |  819         isolate, keys, | 
 |  820         KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly, | 
 |  821                                 ENUMERABLE_STRINGS, | 
 |  822                                 GetKeysConversion::kConvertToString)); | 
 |  823   } | 
 |  824   return *isolate->factory()->NewJSArrayWithElements(keys, FAST_ELEMENTS); | 
 |  825 } | 
 |  826  | 
 |  827 BUILTIN(ObjectValues) { | 
 |  828   HandleScope scope(isolate); | 
 |  829   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  830   Handle<JSReceiver> receiver; | 
 |  831   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 
 |  832                                      Object::ToObject(isolate, object)); | 
 |  833   Handle<FixedArray> values; | 
 |  834   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
 |  835       isolate, values, JSReceiver::GetOwnValues(receiver, ENUMERABLE_STRINGS)); | 
 |  836   return *isolate->factory()->NewJSArrayWithElements(values); | 
 |  837 } | 
 |  838  | 
 |  839 BUILTIN(ObjectEntries) { | 
 |  840   HandleScope scope(isolate); | 
 |  841   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  842   Handle<JSReceiver> receiver; | 
 |  843   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 
 |  844                                      Object::ToObject(isolate, object)); | 
 |  845   Handle<FixedArray> entries; | 
 |  846   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
 |  847       isolate, entries, | 
 |  848       JSReceiver::GetOwnEntries(receiver, ENUMERABLE_STRINGS)); | 
 |  849   return *isolate->factory()->NewJSArrayWithElements(entries); | 
 |  850 } | 
 |  851  | 
 |  852 BUILTIN(ObjectGetOwnPropertyDescriptors) { | 
 |  853   HandleScope scope(isolate); | 
 |  854   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  855  | 
 |  856   Handle<JSReceiver> receiver; | 
 |  857   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 
 |  858                                      Object::ToObject(isolate, object)); | 
 |  859  | 
 |  860   Handle<FixedArray> keys; | 
 |  861   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
 |  862       isolate, keys, KeyAccumulator::GetKeys( | 
 |  863                          receiver, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES, | 
 |  864                          GetKeysConversion::kConvertToString)); | 
 |  865  | 
 |  866   Handle<JSObject> descriptors = | 
 |  867       isolate->factory()->NewJSObject(isolate->object_function()); | 
 |  868  | 
 |  869   for (int i = 0; i < keys->length(); ++i) { | 
 |  870     Handle<Name> key = Handle<Name>::cast(FixedArray::get(*keys, i, isolate)); | 
 |  871     PropertyDescriptor descriptor; | 
 |  872     Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor( | 
 |  873         isolate, receiver, key, &descriptor); | 
 |  874     MAYBE_RETURN(did_get_descriptor, isolate->heap()->exception()); | 
 |  875  | 
 |  876     if (!did_get_descriptor.FromJust()) continue; | 
 |  877     Handle<Object> from_descriptor = descriptor.ToObject(isolate); | 
 |  878  | 
 |  879     LookupIterator it = LookupIterator::PropertyOrElement( | 
 |  880         isolate, descriptors, key, descriptors, LookupIterator::OWN); | 
 |  881     Maybe<bool> success = JSReceiver::CreateDataProperty(&it, from_descriptor, | 
 |  882                                                          Object::DONT_THROW); | 
 |  883     CHECK(success.FromJust()); | 
 |  884   } | 
 |  885  | 
 |  886   return *descriptors; | 
 |  887 } | 
 |  888  | 
 |  889 // ES6 section 19.1.2.15 Object.preventExtensions ( O ) | 
 |  890 BUILTIN(ObjectPreventExtensions) { | 
 |  891   HandleScope scope(isolate); | 
 |  892   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  893   if (object->IsJSReceiver()) { | 
 |  894     MAYBE_RETURN(JSReceiver::PreventExtensions(Handle<JSReceiver>::cast(object), | 
 |  895                                                Object::THROW_ON_ERROR), | 
 |  896                  isolate->heap()->exception()); | 
 |  897   } | 
 |  898   return *object; | 
 |  899 } | 
 |  900  | 
 |  901 // ES6 section 19.1.2.17 Object.seal ( O ) | 
 |  902 BUILTIN(ObjectSeal) { | 
 |  903   HandleScope scope(isolate); | 
 |  904   Handle<Object> object = args.atOrUndefined(isolate, 1); | 
 |  905   if (object->IsJSReceiver()) { | 
 |  906     MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object), | 
 |  907                                                SEALED, Object::THROW_ON_ERROR), | 
 |  908                  isolate->heap()->exception()); | 
 |  909   } | 
 |  910   return *object; | 
 |  911 } | 
 |  912  | 
 |  913 }  // namespace internal | 
 |  914 }  // namespace v8 | 
| OLD | NEW |