LCOV - code coverage report
Current view: top level - js/src/builtin - Reflect.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 20 131 15.3 %
Date: 2017-07-14 16:53:18 Functions: 2 11 18.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "builtin/Reflect.h"
       8             : 
       9             : #include "jsarray.h"
      10             : #include "jscntxt.h"
      11             : 
      12             : #include "vm/ArgumentsObject.h"
      13             : #include "vm/Stack.h"
      14             : 
      15             : #include "vm/Interpreter-inl.h"
      16             : 
      17             : using namespace js;
      18             : 
      19             : 
      20             : /*** Reflect methods *****************************************************************************/
      21             : 
      22             : /* ES6 26.1.3 Reflect.defineProperty(target, propertyKey, attributes) */
      23             : static bool
      24           0 : Reflect_defineProperty(JSContext* cx, unsigned argc, Value* vp)
      25             : {
      26           0 :     CallArgs args = CallArgsFromVp(argc, vp);
      27             : 
      28             :     // Step 1.
      29           0 :     RootedObject obj(cx, NonNullObjectArg(cx, "`target`", "Reflect.defineProperty",
      30           0 :                                           args.get(0)));
      31           0 :     if (!obj)
      32           0 :         return false;
      33             : 
      34             :     // Steps 2-3.
      35           0 :     RootedValue propertyKey(cx, args.get(1));
      36           0 :     RootedId key(cx);
      37           0 :     if (!ToPropertyKey(cx, propertyKey, &key))
      38           0 :         return false;
      39             : 
      40             :     // Steps 4-5.
      41           0 :     Rooted<PropertyDescriptor> desc(cx);
      42           0 :     if (!ToPropertyDescriptor(cx, args.get(2), true, &desc))
      43           0 :         return false;
      44             : 
      45             :     // Step 6.
      46           0 :     ObjectOpResult result;
      47           0 :     if (!DefineProperty(cx, obj, key, desc, result))
      48           0 :         return false;
      49           0 :     args.rval().setBoolean(bool(result));
      50           0 :     return true;
      51             : }
      52             : 
      53             : /* ES6 26.1.4 Reflect.deleteProperty (target, propertyKey) */
      54             : static bool
      55           0 : Reflect_deleteProperty(JSContext* cx, unsigned argc, Value* vp)
      56             : {
      57           0 :     CallArgs args = CallArgsFromVp(argc, vp);
      58             : 
      59             :     // Step 1.
      60           0 :     RootedObject target(cx, NonNullObjectArg(cx, "`target`", "Reflect.deleteProperty",
      61           0 :                                              args.get(0)));
      62           0 :     if (!target)
      63           0 :         return false;
      64             : 
      65             :     // Steps 2-3.
      66           0 :     RootedValue propertyKey(cx, args.get(1));
      67           0 :     RootedId key(cx);
      68           0 :     if (!ToPropertyKey(cx, propertyKey, &key))
      69           0 :         return false;
      70             : 
      71             :     // Step 4.
      72           0 :     ObjectOpResult result;
      73           0 :     if (!DeleteProperty(cx, target, key, result))
      74           0 :         return false;
      75           0 :     args.rval().setBoolean(bool(result));
      76           0 :     return true;
      77             : }
      78             : 
      79             : /* ES6 26.1.6 Reflect.get(target, propertyKey [, receiver]) */
      80             : static bool
      81           0 : Reflect_get(JSContext* cx, unsigned argc, Value* vp)
      82             : {
      83           0 :     CallArgs args = CallArgsFromVp(argc, vp);
      84             : 
      85             :     // Step 1.
      86           0 :     RootedObject obj(cx, NonNullObjectArg(cx, "`target`", "Reflect.get", args.get(0)));
      87           0 :     if (!obj)
      88           0 :         return false;
      89             : 
      90             :     // Steps 2-3.
      91           0 :     RootedValue propertyKey(cx, args.get(1));
      92           0 :     RootedId key(cx);
      93           0 :     if (!ToPropertyKey(cx, propertyKey, &key))
      94           0 :         return false;
      95             : 
      96             :     // Step 4.
      97           0 :     RootedValue receiver(cx, args.length() > 2 ? args[2] : args.get(0));
      98             : 
      99             :     // Step 5.
     100           0 :     return GetProperty(cx, obj, receiver, key, args.rval());
     101             : }
     102             : 
     103             : /* ES6 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey) */
     104             : static bool
     105           0 : Reflect_getOwnPropertyDescriptor(JSContext* cx, unsigned argc, Value* vp)
     106             : {
     107             :     // Step 1.
     108           0 :     CallArgs args = CallArgsFromVp(argc, vp);
     109           0 :     if (!NonNullObjectArg(cx, "`target`", "Reflect.getOwnPropertyDescriptor", args.get(0)))
     110           0 :         return false;
     111             : 
     112             :     // The other steps are identical to ES6 draft rev 32 (2015 Feb 2) 19.1.2.6
     113             :     // Object.getOwnPropertyDescriptor.
     114           0 :     return js::obj_getOwnPropertyDescriptor(cx, argc, vp);
     115             : }
     116             : 
     117             : /* ES6 26.1.8 Reflect.getPrototypeOf(target) */
     118             : bool
     119         126 : js::Reflect_getPrototypeOf(JSContext* cx, unsigned argc, Value* vp)
     120             : {
     121         126 :     CallArgs args = CallArgsFromVp(argc, vp);
     122             : 
     123             :     // Step 1.
     124         252 :     RootedObject target(cx, NonNullObjectArg(cx, "`target`", "Reflect.getPrototypeOf",
     125         252 :                                              args.get(0)));
     126         126 :     if (!target)
     127           0 :         return false;
     128             : 
     129             :     // Step 2.
     130         252 :     RootedObject proto(cx);
     131         126 :     if (!GetPrototype(cx, target, &proto))
     132           0 :         return false;
     133         126 :     args.rval().setObjectOrNull(proto);
     134         126 :     return true;
     135             : }
     136             : 
     137             : /* ES6 draft 26.1.10 Reflect.isExtensible(target) */
     138             : bool
     139           0 : js::Reflect_isExtensible(JSContext* cx, unsigned argc, Value* vp)
     140             : {
     141           0 :     CallArgs args = CallArgsFromVp(argc, vp);
     142             : 
     143             :     // Step 1.
     144           0 :     RootedObject target(cx, NonNullObjectArg(cx, "`target`", "Reflect.isExtensible", args.get(0)));
     145           0 :     if (!target)
     146           0 :         return false;
     147             : 
     148             :     // Step 2.
     149             :     bool extensible;
     150           0 :     if (!IsExtensible(cx, target, &extensible))
     151           0 :         return false;
     152           0 :     args.rval().setBoolean(extensible);
     153           0 :     return true;
     154             : }
     155             : 
     156             : /* ES6 26.1.11 Reflect.ownKeys(target) */
     157             : static bool
     158           0 : Reflect_ownKeys(JSContext* cx, unsigned argc, Value* vp)
     159             : {
     160           0 :     CallArgs args = CallArgsFromVp(argc, vp);
     161             : 
     162             :     // Step 1.
     163           0 :     if (!NonNullObjectArg(cx, "`target`", "Reflect.ownKeys", args.get(0)))
     164           0 :         return false;
     165             : 
     166             :     // Steps 2-4.
     167           0 :     return GetOwnPropertyKeys(cx, args, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS);
     168             : }
     169             : 
     170             : /* ES6 26.1.12 Reflect.preventExtensions(target) */
     171             : static bool
     172           0 : Reflect_preventExtensions(JSContext* cx, unsigned argc, Value* vp)
     173             : {
     174           0 :     CallArgs args = CallArgsFromVp(argc, vp);
     175             : 
     176             :     // Step 1.
     177           0 :     RootedObject target(cx, NonNullObjectArg(cx, "`target`", "Reflect.preventExtensions",
     178           0 :                                              args.get(0)));
     179           0 :     if (!target)
     180           0 :         return false;
     181             : 
     182             :     // Step 2.
     183           0 :     ObjectOpResult result;
     184           0 :     if (!PreventExtensions(cx, target, result))
     185           0 :         return false;
     186           0 :     args.rval().setBoolean(bool(result));
     187           0 :     return true;
     188             : }
     189             : 
     190             : /* ES6 26.1.13 Reflect.set(target, propertyKey, V [, receiver]) */
     191             : static bool
     192           0 : Reflect_set(JSContext* cx, unsigned argc, Value* vp)
     193             : {
     194           0 :     CallArgs args = CallArgsFromVp(argc, vp);
     195             : 
     196             :     // Step 1.
     197           0 :     RootedObject target(cx, NonNullObjectArg(cx, "`target`", "Reflect.set", args.get(0)));
     198           0 :     if (!target)
     199           0 :         return false;
     200             : 
     201             :     // Steps 2-3.
     202           0 :     RootedValue propertyKey(cx, args.get(1));
     203           0 :     RootedId key(cx);
     204           0 :     if (!ToPropertyKey(cx, propertyKey, &key))
     205           0 :         return false;
     206             : 
     207             :     // Step 4.
     208           0 :     RootedValue receiver(cx, args.length() > 3 ? args[3] : args.get(0));
     209             : 
     210             :     // Step 5.
     211           0 :     ObjectOpResult result;
     212           0 :     RootedValue value(cx, args.get(2));
     213           0 :     if (!SetProperty(cx, target, key, value, receiver, result))
     214           0 :         return false;
     215           0 :     args.rval().setBoolean(bool(result));
     216           0 :     return true;
     217             : }
     218             : 
     219             : /*
     220             :  * ES6 26.1.3 Reflect.setPrototypeOf(target, proto)
     221             :  *
     222             :  * The specification is not quite similar enough to Object.setPrototypeOf to
     223             :  * share code.
     224             :  */
     225             : static bool
     226           0 : Reflect_setPrototypeOf(JSContext* cx, unsigned argc, Value* vp)
     227             : {
     228           0 :     CallArgs args = CallArgsFromVp(argc, vp);
     229             : 
     230             :     // Step 1.
     231           0 :     RootedObject obj(cx, NonNullObjectArg(cx, "`target`", "Reflect.setPrototypeOf", args.get(0)));
     232           0 :     if (!obj)
     233           0 :         return false;
     234             : 
     235             :     // Step 2.
     236           0 :     if (!args.get(1).isObjectOrNull()) {
     237           0 :         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
     238             :                                   "Reflect.setPrototypeOf", "an object or null",
     239           0 :                                   InformalValueTypeName(args.get(1)));
     240           0 :         return false;
     241             :     }
     242           0 :     RootedObject proto(cx, args.get(1).toObjectOrNull());
     243             : 
     244             :     // Step 4.
     245           0 :     ObjectOpResult result;
     246           0 :     if (!SetPrototype(cx, obj, proto, result))
     247           0 :         return false;
     248           0 :     args.rval().setBoolean(bool(result));
     249           0 :     return true;
     250             : }
     251             : 
     252             : static const JSFunctionSpec methods[] = {
     253             :     JS_SELF_HOSTED_FN("apply", "Reflect_apply", 3, 0),
     254             :     JS_SELF_HOSTED_FN("construct", "Reflect_construct", 2, 0),
     255             :     JS_FN("defineProperty", Reflect_defineProperty, 3, 0),
     256             :     JS_FN("deleteProperty", Reflect_deleteProperty, 2, 0),
     257             :     JS_FN("get", Reflect_get, 2, 0),
     258             :     JS_FN("getOwnPropertyDescriptor", Reflect_getOwnPropertyDescriptor, 2, 0),
     259             :     JS_FN("getPrototypeOf", Reflect_getPrototypeOf, 1, 0),
     260             :     JS_SELF_HOSTED_FN("has", "Reflect_has", 2, 0),
     261             :     JS_FN("isExtensible", Reflect_isExtensible, 1, 0),
     262             :     JS_FN("ownKeys", Reflect_ownKeys, 1, 0),
     263             :     JS_FN("preventExtensions", Reflect_preventExtensions, 1, 0),
     264             :     JS_FN("set", Reflect_set, 3, 0),
     265             :     JS_FN("setPrototypeOf", Reflect_setPrototypeOf, 2, 0),
     266             :     JS_FS_END
     267             : };
     268             : 
     269             : 
     270             : /*** Setup **************************************************************************************/
     271             : 
     272             : JSObject*
     273           6 : js::InitReflect(JSContext* cx, HandleObject obj)
     274             : {
     275           6 :     Handle<GlobalObject*> global = obj.as<GlobalObject>();
     276          12 :     RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global));
     277           6 :     if (!proto)
     278           0 :         return nullptr;
     279             : 
     280          12 :     RootedObject reflect(cx, NewObjectWithGivenProto<PlainObject>(cx, proto, SingletonObject));
     281           6 :     if (!reflect)
     282           0 :         return nullptr;
     283           6 :     if (!JS_DefineFunctions(cx, reflect, methods))
     284           0 :         return nullptr;
     285             : 
     286          12 :     RootedValue value(cx, ObjectValue(*reflect));
     287           6 :     if (!DefineProperty(cx, obj, cx->names().Reflect, value, nullptr, nullptr, JSPROP_RESOLVING))
     288           0 :         return nullptr;
     289             : 
     290           6 :     obj->as<GlobalObject>().setConstructor(JSProto_Reflect, value);
     291             : 
     292           6 :     return reflect;
     293             : }

Generated by: LCOV version 1.13