LCOV - code coverage report
Current view: top level - src/builtins - builtins-object.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 142 145 97.9 %
Date: 2019-01-20 Functions: 43 62 69.4 %

          Line data    Source code
       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-utils-inl.h"
       6             : #include "src/builtins/builtins.h"
       7             : #include "src/code-factory.h"
       8             : #include "src/counters.h"
       9             : #include "src/keys.h"
      10             : #include "src/lookup.h"
      11             : #include "src/message-template.h"
      12             : #include "src/objects-inl.h"
      13             : #include "src/property-descriptor.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : 
      18             : // -----------------------------------------------------------------------------
      19             : // ES6 section 19.1 Object Objects
      20             : 
      21             : // ES6 section 19.1.3.4 Object.prototype.propertyIsEnumerable ( V )
      22       22908 : BUILTIN(ObjectPrototypePropertyIsEnumerable) {
      23             :   HandleScope scope(isolate);
      24             :   Handle<JSReceiver> object;
      25             :   Handle<Name> name;
      26       11459 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
      27             :       isolate, name, Object::ToName(isolate, args.atOrUndefined(isolate, 1)));
      28       11615 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
      29             :       isolate, object, Object::ToObject(isolate, args.receiver()));
      30             :   Maybe<PropertyAttributes> maybe =
      31        5551 :       JSReceiver::GetOwnPropertyAttributes(object, name);
      32        5765 :   if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
      33        5566 :   if (maybe.FromJust() == ABSENT) return ReadOnlyRoots(isolate).false_value();
      34        5108 :   return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0);
      35             : }
      36             : 
      37             : // ES6 section 19.1.2.3 Object.defineProperties
      38        2988 : BUILTIN(ObjectDefineProperties) {
      39             :   HandleScope scope(isolate);
      40             :   DCHECK_EQ(3, args.length());
      41         747 :   Handle<Object> target = args.at(1);
      42         747 :   Handle<Object> properties = args.at(2);
      43             : 
      44        1665 :   RETURN_RESULT_OR_FAILURE(
      45             :       isolate, JSReceiver::DefineProperties(isolate, target, properties));
      46             : }
      47             : 
      48             : // ES6 section 19.1.2.4 Object.defineProperty
      49      457300 : BUILTIN(ObjectDefineProperty) {
      50             :   HandleScope scope(isolate);
      51             :   DCHECK_EQ(4, args.length());
      52      114325 :   Handle<Object> target = args.at(1);
      53      114325 :   Handle<Object> key = args.at(2);
      54      114325 :   Handle<Object> attributes = args.at(3);
      55             : 
      56      228650 :   return JSReceiver::DefineProperty(isolate, target, key, attributes);
      57             : }
      58             : 
      59             : namespace {
      60             : 
      61             : template <AccessorComponent which_accessor>
      62      147927 : Object ObjectDefineAccessor(Isolate* isolate, Handle<Object> object,
      63             :                             Handle<Object> name, Handle<Object> accessor) {
      64             :   // 1. Let O be ? ToObject(this value).
      65             :   Handle<JSReceiver> receiver;
      66      295863 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
      67             :                                      Object::ToObject(isolate, object));
      68             :   // 2. If IsCallable(getter) is false, throw a TypeError exception.
      69      295836 :   if (!accessor->IsCallable()) {
      70             :     MessageTemplate message =
      71             :         which_accessor == ACCESSOR_GETTER
      72             :             ? MessageTemplate::kObjectGetterExpectingFunction
      73             :             : MessageTemplate::kObjectSetterExpectingFunction;
      74         108 :     THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(message));
      75             :   }
      76             :   // 3. Let desc be PropertyDescriptor{[[Get]]: getter, [[Enumerable]]: true,
      77             :   //                                   [[Configurable]]: true}.
      78             :   PropertyDescriptor desc;
      79             :   if (which_accessor == ACCESSOR_GETTER) {
      80             :     desc.set_get(accessor);
      81             :   } else {
      82             :     DCHECK(which_accessor == ACCESSOR_SETTER);
      83             :     desc.set_set(accessor);
      84             :   }
      85             :   desc.set_enumerable(true);
      86             :   desc.set_configurable(true);
      87             :   // 4. Let key be ? ToPropertyKey(P).
      88      295728 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
      89             :                                      Object::ToPropertyKey(isolate, name));
      90             :   // 5. Perform ? DefinePropertyOrThrow(O, key, desc).
      91             :   // To preserve legacy behavior, we ignore errors silently rather than
      92             :   // throwing an exception.
      93             :   Maybe<bool> success = JSReceiver::DefineOwnProperty(isolate, receiver, name,
      94      147864 :                                                       &desc, kThrowOnError);
      95      148045 :   MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
      96      147683 :   if (!success.FromJust()) {
      97           0 :     isolate->CountUsage(v8::Isolate::kDefineGetterOrSetterWouldThrow);
      98             :   }
      99             :   // 6. Return undefined.
     100      147683 :   return ReadOnlyRoots(isolate).undefined_value();
     101             : }
     102             : 
     103         646 : Object ObjectLookupAccessor(Isolate* isolate, Handle<Object> object,
     104             :                             Handle<Object> key, AccessorComponent component) {
     105        1292 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, object,
     106             :                                      Object::ToObject(isolate, object));
     107        1292 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
     108             :                                      Object::ToPropertyKey(isolate, key));
     109         646 :   bool success = false;
     110             :   LookupIterator it = LookupIterator::PropertyOrElement(
     111             :       isolate, object, key, &success,
     112         646 :       LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
     113             :   DCHECK(success);
     114             : 
     115         646 :   for (; it.IsFound(); it.Next()) {
     116         574 :     switch (it.state()) {
     117             :       case LookupIterator::INTERCEPTOR:
     118             :       case LookupIterator::NOT_FOUND:
     119             :       case LookupIterator::TRANSITION:
     120           0 :         UNREACHABLE();
     121             : 
     122             :       case LookupIterator::ACCESS_CHECK:
     123           5 :         if (it.HasAccess()) continue;
     124           5 :         isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
     125           5 :         RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
     126           0 :         return ReadOnlyRoots(isolate).undefined_value();
     127             : 
     128             :       case LookupIterator::JSPROXY: {
     129             :         PropertyDescriptor desc;
     130             :         Maybe<bool> found = JSProxy::GetOwnPropertyDescriptor(
     131         576 :             isolate, it.GetHolder<JSProxy>(), it.GetName(), &desc);
     132         288 :         MAYBE_RETURN(found, ReadOnlyRoots(isolate).exception());
     133         288 :         if (found.FromJust()) {
     134         243 :           if (component == ACCESSOR_GETTER && desc.has_get()) {
     135             :             return *desc.get();
     136             :           }
     137         189 :           if (component == ACCESSOR_SETTER && desc.has_set()) {
     138             :             return *desc.set();
     139             :           }
     140          54 :           return ReadOnlyRoots(isolate).undefined_value();
     141             :         }
     142             :         Handle<Object> prototype;
     143         252 :         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     144             :             isolate, prototype, JSProxy::GetPrototype(it.GetHolder<JSProxy>()));
     145         252 :         if (prototype->IsNull(isolate)) {
     146          18 :           return ReadOnlyRoots(isolate).undefined_value();
     147             :         }
     148         108 :         return ObjectLookupAccessor(isolate, prototype, key, component);
     149             :       }
     150             : 
     151             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
     152             :       case LookupIterator::DATA:
     153          72 :         return ReadOnlyRoots(isolate).undefined_value();
     154             : 
     155             :       case LookupIterator::ACCESSOR: {
     156         209 :         Handle<Object> maybe_pair = it.GetAccessors();
     157         418 :         if (maybe_pair->IsAccessorPair()) {
     158             :           return *AccessorPair::GetComponent(
     159         418 :               isolate, Handle<AccessorPair>::cast(maybe_pair), component);
     160             :         }
     161             :       }
     162             :     }
     163             :   }
     164             : 
     165          72 :   return ReadOnlyRoots(isolate).undefined_value();
     166             : }
     167             : 
     168             : }  // namespace
     169             : 
     170             : // ES6 B.2.2.2 a.k.a.
     171             : // https://tc39.github.io/ecma262/#sec-object.prototype.__defineGetter__
     172      545884 : BUILTIN(ObjectDefineGetter) {
     173             :   HandleScope scope(isolate);
     174      136471 :   Handle<Object> object = args.at(0);  // Receiver.
     175      136471 :   Handle<Object> name = args.at(1);
     176      136471 :   Handle<Object> getter = args.at(2);
     177      272942 :   return ObjectDefineAccessor<ACCESSOR_GETTER>(isolate, object, name, getter);
     178             : }
     179             : 
     180             : // ES6 B.2.2.3 a.k.a.
     181             : // https://tc39.github.io/ecma262/#sec-object.prototype.__defineSetter__
     182       45824 : BUILTIN(ObjectDefineSetter) {
     183             :   HandleScope scope(isolate);
     184       11456 :   Handle<Object> object = args.at(0);  // Receiver.
     185       11456 :   Handle<Object> name = args.at(1);
     186       11456 :   Handle<Object> setter = args.at(2);
     187       22912 :   return ObjectDefineAccessor<ACCESSOR_SETTER>(isolate, object, name, setter);
     188             : }
     189             : 
     190             : // ES6 B.2.2.4 a.k.a.
     191             : // https://tc39.github.io/ecma262/#sec-object.prototype.__lookupGetter__
     192        1124 : BUILTIN(ObjectLookupGetter) {
     193             :   HandleScope scope(isolate);
     194         281 :   Handle<Object> object = args.at(0);
     195         281 :   Handle<Object> name = args.at(1);
     196         562 :   return ObjectLookupAccessor(isolate, object, name, ACCESSOR_GETTER);
     197             : }
     198             : 
     199             : // ES6 B.2.2.5 a.k.a.
     200             : // https://tc39.github.io/ecma262/#sec-object.prototype.__lookupSetter__
     201        1028 : BUILTIN(ObjectLookupSetter) {
     202             :   HandleScope scope(isolate);
     203         257 :   Handle<Object> object = args.at(0);
     204         257 :   Handle<Object> name = args.at(1);
     205         514 :   return ObjectLookupAccessor(isolate, object, name, ACCESSOR_SETTER);
     206             : }
     207             : 
     208             : // ES6 section 19.1.2.5 Object.freeze ( O )
     209      387428 : BUILTIN(ObjectFreeze) {
     210             :   HandleScope scope(isolate);
     211             :   Handle<Object> object = args.atOrUndefined(isolate, 1);
     212      193714 :   if (object->IsJSReceiver()) {
     213       96856 :     MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object),
     214             :                                                FROZEN, kThrowOnError),
     215             :                  ReadOnlyRoots(isolate).exception());
     216             :   }
     217             :   return *object;
     218             : }
     219             : 
     220             : // ES section 19.1.2.9 Object.getPrototypeOf ( O )
     221     1338076 : BUILTIN(ObjectGetPrototypeOf) {
     222             :   HandleScope scope(isolate);
     223      334519 :   Handle<Object> object = args.atOrUndefined(isolate, 1);
     224             : 
     225             :   Handle<JSReceiver> receiver;
     226      669056 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
     227             :                                      Object::ToObject(isolate, object));
     228             : 
     229      669011 :   RETURN_RESULT_OR_FAILURE(isolate,
     230             :                            JSReceiver::GetPrototype(isolate, receiver));
     231             : }
     232             : 
     233             : // ES6 section 19.1.2.21 Object.setPrototypeOf ( O, proto )
     234      234872 : BUILTIN(ObjectSetPrototypeOf) {
     235             :   HandleScope scope(isolate);
     236             : 
     237             :   // 1. Let O be ? RequireObjectCoercible(O).
     238             :   Handle<Object> object = args.atOrUndefined(isolate, 1);
     239      117436 :   if (object->IsNullOrUndefined(isolate)) {
     240          54 :     THROW_NEW_ERROR_RETURN_FAILURE(
     241             :         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
     242             :                               isolate->factory()->NewStringFromAsciiChecked(
     243             :                                   "Object.setPrototypeOf")));
     244             :   }
     245             : 
     246             :   // 2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
     247             :   Handle<Object> proto = args.atOrUndefined(isolate, 2);
     248      234530 :   if (!proto->IsNull(isolate) && !proto->IsJSReceiver()) {
     249         954 :     THROW_NEW_ERROR_RETURN_FAILURE(
     250             :         isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto));
     251             :   }
     252             : 
     253             :   // 3. If Type(O) is not Object, return O.
     254      116446 :   if (!object->IsJSReceiver()) return *object;
     255       58187 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
     256             : 
     257             :   // 4. Let status be ? O.[[SetPrototypeOf]](proto).
     258             :   // 5. If status is false, throw a TypeError exception.
     259       58358 :   MAYBE_RETURN(JSReceiver::SetPrototype(receiver, proto, true, kThrowOnError),
     260             :                ReadOnlyRoots(isolate).exception());
     261             : 
     262             :   // 6. Return O.
     263       58016 :   return *receiver;
     264             : }
     265             : 
     266             : // ES6 section B.2.2.1.1 get Object.prototype.__proto__
     267      544276 : BUILTIN(ObjectPrototypeGetProto) {
     268             :   HandleScope scope(isolate);
     269             :   // 1. Let O be ? ToObject(this value).
     270             :   Handle<JSReceiver> receiver;
     271      272156 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     272             :       isolate, receiver, Object::ToObject(isolate, args.receiver()));
     273             : 
     274             :   // 2. Return ? O.[[GetPrototypeOf]]().
     275      272102 :   RETURN_RESULT_OR_FAILURE(isolate,
     276             :                            JSReceiver::GetPrototype(isolate, receiver));
     277             : }
     278             : 
     279             : // ES6 section B.2.2.1.2 set Object.prototype.__proto__
     280      644340 : BUILTIN(ObjectPrototypeSetProto) {
     281             :   HandleScope scope(isolate);
     282             :   // 1. Let O be ? RequireObjectCoercible(this value).
     283             :   Handle<Object> object = args.receiver();
     284      322170 :   if (object->IsNullOrUndefined(isolate)) {
     285          54 :     THROW_NEW_ERROR_RETURN_FAILURE(
     286             :         isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
     287             :                               isolate->factory()->NewStringFromAsciiChecked(
     288             :                                   "set Object.prototype.__proto__")));
     289             :   }
     290             : 
     291             :   // 2. If Type(proto) is neither Object nor Null, return undefined.
     292             :   Handle<Object> proto = args.at(1);
     293      643536 :   if (!proto->IsNull(isolate) && !proto->IsJSReceiver()) {
     294       29366 :     return ReadOnlyRoots(isolate).undefined_value();
     295             :   }
     296             : 
     297             :   // 3. If Type(O) is not Object, return undefined.
     298      263447 :   if (!object->IsJSReceiver()) return ReadOnlyRoots(isolate).undefined_value();
     299      131656 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
     300             : 
     301             :   // 4. Let status be ? O.[[SetPrototypeOf]](proto).
     302             :   // 5. If status is false, throw a TypeError exception.
     303      131752 :   MAYBE_RETURN(JSReceiver::SetPrototype(receiver, proto, true, kThrowOnError),
     304             :                ReadOnlyRoots(isolate).exception());
     305             : 
     306             :   // Return undefined.
     307      131560 :   return ReadOnlyRoots(isolate).undefined_value();
     308             : }
     309             : 
     310             : namespace {
     311             : 
     312         340 : Object GetOwnPropertyKeys(Isolate* isolate, BuiltinArguments args,
     313             :                           PropertyFilter filter) {
     314             :   HandleScope scope(isolate);
     315         340 :   Handle<Object> object = args.atOrUndefined(isolate, 1);
     316             :   Handle<JSReceiver> receiver;
     317         680 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
     318             :                                      Object::ToObject(isolate, object));
     319             :   Handle<FixedArray> keys;
     320         680 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     321             :       isolate, keys,
     322             :       KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly, filter,
     323             :                               GetKeysConversion::kConvertToString));
     324         680 :   return *isolate->factory()->NewJSArrayWithElements(keys);
     325             : }
     326             : 
     327             : }  // namespace
     328             : 
     329             : // ES6 section 19.1.2.8 Object.getOwnPropertySymbols ( O )
     330         340 : BUILTIN(ObjectGetOwnPropertySymbols) {
     331         340 :   return GetOwnPropertyKeys(isolate, args, SKIP_STRINGS);
     332             : }
     333             : 
     334             : // ES6 section 19.1.2.11 Object.isExtensible ( O )
     335        7920 : BUILTIN(ObjectIsExtensible) {
     336             :   HandleScope scope(isolate);
     337             :   Handle<Object> object = args.atOrUndefined(isolate, 1);
     338             :   Maybe<bool> result =
     339        3960 :       object->IsJSReceiver()
     340        1980 :           ? JSReceiver::IsExtensible(Handle<JSReceiver>::cast(object))
     341        3960 :           : Just(false);
     342        1980 :   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
     343        1980 :   return isolate->heap()->ToBoolean(result.FromJust());
     344             : }
     345             : 
     346             : // ES6 section 19.1.2.12 Object.isFrozen ( O )
     347        3388 : BUILTIN(ObjectIsFrozen) {
     348             :   HandleScope scope(isolate);
     349             :   Handle<Object> object = args.atOrUndefined(isolate, 1);
     350        1694 :   Maybe<bool> result = object->IsJSReceiver()
     351             :                            ? JSReceiver::TestIntegrityLevel(
     352         772 :                                  Handle<JSReceiver>::cast(object), FROZEN)
     353        1619 :                            : Just(true);
     354         856 :   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
     355         838 :   return isolate->heap()->ToBoolean(result.FromJust());
     356             : }
     357             : 
     358             : // ES6 section 19.1.2.13 Object.isSealed ( O )
     359        1680 : BUILTIN(ObjectIsSealed) {
     360             :   HandleScope scope(isolate);
     361             :   Handle<Object> object = args.atOrUndefined(isolate, 1);
     362         840 :   Maybe<bool> result = object->IsJSReceiver()
     363             :                            ? JSReceiver::TestIntegrityLevel(
     364         385 :                                  Handle<JSReceiver>::cast(object), SEALED)
     365         805 :                            : Just(true);
     366         438 :   MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
     367         402 :   return isolate->heap()->ToBoolean(result.FromJust());
     368             : }
     369             : 
     370         396 : BUILTIN(ObjectGetOwnPropertyDescriptors) {
     371             :   HandleScope scope(isolate);
     372          99 :   Handle<Object> object = args.atOrUndefined(isolate, 1);
     373             : 
     374             :   Handle<JSReceiver> receiver;
     375         225 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
     376             :                                      Object::ToObject(isolate, object));
     377             : 
     378             :   Handle<FixedArray> keys;
     379         144 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     380             :       isolate, keys, KeyAccumulator::GetKeys(
     381             :                          receiver, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
     382             :                          GetKeysConversion::kConvertToString));
     383             : 
     384             :   Handle<JSObject> descriptors =
     385          72 :       isolate->factory()->NewJSObject(isolate->object_function());
     386             : 
     387         522 :   for (int i = 0; i < keys->length(); ++i) {
     388         189 :     Handle<Name> key = Handle<Name>::cast(FixedArray::get(*keys, i, isolate));
     389             :     PropertyDescriptor descriptor;
     390             :     Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
     391         189 :         isolate, receiver, key, &descriptor);
     392         189 :     MAYBE_RETURN(did_get_descriptor, ReadOnlyRoots(isolate).exception());
     393             : 
     394         207 :     if (!did_get_descriptor.FromJust()) continue;
     395         171 :     Handle<Object> from_descriptor = descriptor.ToObject(isolate);
     396             : 
     397             :     Maybe<bool> success = JSReceiver::CreateDataProperty(
     398         171 :         isolate, descriptors, key, from_descriptor, kDontThrow);
     399         171 :     CHECK(success.FromJust());
     400             :   }
     401             : 
     402          72 :   return *descriptors;
     403             : }
     404             : 
     405             : // ES6 section 19.1.2.15 Object.preventExtensions ( O )
     406       13228 : BUILTIN(ObjectPreventExtensions) {
     407             :   HandleScope scope(isolate);
     408             :   Handle<Object> object = args.atOrUndefined(isolate, 1);
     409        6614 :   if (object->IsJSReceiver()) {
     410        3317 :     MAYBE_RETURN(JSReceiver::PreventExtensions(Handle<JSReceiver>::cast(object),
     411             :                                                kThrowOnError),
     412             :                  ReadOnlyRoots(isolate).exception());
     413             :   }
     414             :   return *object;
     415             : }
     416             : 
     417             : // ES6 section 19.1.2.17 Object.seal ( O )
     418        3068 : BUILTIN(ObjectSeal) {
     419             :   HandleScope scope(isolate);
     420             :   Handle<Object> object = args.atOrUndefined(isolate, 1);
     421        1534 :   if (object->IsJSReceiver()) {
     422         755 :     MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(object),
     423             :                                                SEALED, kThrowOnError),
     424             :                  ReadOnlyRoots(isolate).exception());
     425             :   }
     426             :   return *object;
     427             : }
     428             : 
     429             : }  // namespace internal
     430      183867 : }  // namespace v8

Generated by: LCOV version 1.10