< prev index next >

src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java

Print this page




 131     @SuppressWarnings("unused")
 132     private static PropertyMap $nasgenmap$;
 133 
 134     private NativeObject() {
 135         // don't create me!
 136         throw new UnsupportedOperationException();
 137     }
 138 
 139     private static ECMAException notAnObject(final Object obj) {
 140         return typeError("not.an.object", ScriptRuntime.safeToString(obj));
 141     }
 142 
 143     /**
 144      * Nashorn extension: setIndexedPropertiesToExternalArrayData
 145      *
 146      * @param self self reference
 147      * @param obj object whose index properties are backed by buffer
 148      * @param buf external buffer - should be a nio ByteBuffer
 149      * @return the 'obj' object
 150      */
 151     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 152     public static ScriptObject setIndexedPropertiesToExternalArrayData(final Object self, final Object obj, final Object buf) {
 153         Global.checkObject(obj);
 154         final ScriptObject sobj = (ScriptObject)obj;
 155         if (buf instanceof ByteBuffer) {
 156             sobj.setArray(ArrayData.allocate((ByteBuffer)buf));
 157         } else {
 158             throw typeError("not.a.bytebuffer", "setIndexedPropertiesToExternalArrayData's buf argument");
 159         }
 160         return sobj;
 161     }
 162 
 163 
 164     /**
 165      * ECMA 15.2.3.2 Object.getPrototypeOf ( O )
 166      *
 167      * @param  self self reference
 168      * @param  obj object to get prototype from
 169      * @return the prototype of an object
 170      */
 171     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 172     public static Object getPrototypeOf(final Object self, final Object obj) {
 173         if (obj instanceof ScriptObject) {
 174             return ((ScriptObject)obj).getProto();
 175         } else if (obj instanceof ScriptObjectMirror) {
 176             return ((ScriptObjectMirror)obj).getProto();
 177         } else {
 178             final JSType type = JSType.of(obj);
 179             if (type == JSType.OBJECT) {
 180                 // host (Java) objects have null __proto__
 181                 return null;
 182             }
 183 
 184             // must be some JS primitive
 185             throw notAnObject(obj);
 186         }
 187     }
 188 
 189     /**
 190      * Nashorn extension: Object.setPrototypeOf ( O, proto )
 191      * Also found in ES6 draft specification.
 192      *
 193      * @param  self self reference
 194      * @param  obj object to set prototype for
 195      * @param  proto prototype object to be used
 196      * @return object whose prototype is set
 197      */
 198     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 199     public static Object setPrototypeOf(final Object self, final Object obj, final Object proto) {
 200         if (obj instanceof ScriptObject) {
 201             ((ScriptObject)obj).setPrototypeOf(proto);
 202             return obj;
 203         } else if (obj instanceof ScriptObjectMirror) {
 204             ((ScriptObjectMirror)obj).setProto(proto);
 205             return obj;
 206         }
 207 
 208         throw notAnObject(obj);
 209     }
 210 
 211     /**
 212      * ECMA 15.2.3.3 Object.getOwnPropertyDescriptor ( O, P )
 213      *
 214      * @param self  self reference
 215      * @param obj   object from which to get property descriptor for {@code ToString(prop)}
 216      * @param prop  property descriptor
 217      * @return property descriptor
 218      */
 219     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 220     public static Object getOwnPropertyDescriptor(final Object self, final Object obj, final Object prop) {
 221         if (obj instanceof ScriptObject) {
 222             final String       key  = JSType.toString(prop);
 223             final ScriptObject sobj = (ScriptObject)obj;
 224 
 225             return sobj.getOwnPropertyDescriptor(key);
 226         } else if (obj instanceof ScriptObjectMirror) {
 227             final String       key  = JSType.toString(prop);
 228             final ScriptObjectMirror sobjMirror = (ScriptObjectMirror)obj;
 229 
 230             return sobjMirror.getOwnPropertyDescriptor(key);
 231         } else {
 232             throw notAnObject(obj);
 233         }
 234     }
 235 
 236     /**
 237      * ECMA 15.2.3.4 Object.getOwnPropertyNames ( O )
 238      *
 239      * @param self self reference
 240      * @param obj  object to query for property names
 241      * @return array of property names
 242      */
 243     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 244     public static ScriptObject getOwnPropertyNames(final Object self, final Object obj) {
 245         if (obj instanceof ScriptObject) {
 246             return new NativeArray(((ScriptObject)obj).getOwnKeys(true));
 247         } else if (obj instanceof ScriptObjectMirror) {
 248             return new NativeArray(((ScriptObjectMirror)obj).getOwnKeys(true));
 249         } else {
 250             throw notAnObject(obj);
 251         }
 252     }
 253 
 254     /**
 255      * ECMA 2 19.1.2.8 Object.getOwnPropertySymbols ( O )
 256      *
 257      * @param self self reference
 258      * @param obj  object to query for property names
 259      * @return array of property names
 260      */
 261     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 262     public static ScriptObject getOwnPropertySymbols(final Object self, final Object obj) {
 263         if (obj instanceof ScriptObject) {
 264             return new NativeArray(((ScriptObject)obj).getOwnSymbols(true));
 265         } else {
 266             // TODO: we don't support this on ScriptObjectMirror objects yet
 267             throw notAnObject(obj);
 268         }
 269     }
 270 
 271     /**
 272      * ECMA 15.2.3.5 Object.create ( O [, Properties] )
 273      *
 274      * @param self  self reference
 275      * @param proto prototype object
 276      * @param props properties to define
 277      * @return object created
 278      */
 279     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 280     public static ScriptObject create(final Object self, final Object proto, final Object props) {
 281         if (proto != null) {
 282             Global.checkObject(proto);
 283         }
 284 
 285         // FIXME: should we create a proper object with correct number of
 286         // properties?
 287         final ScriptObject newObj = Global.newEmptyInstance();
 288         newObj.setProto((ScriptObject)proto);
 289         if (props != UNDEFINED) {
 290             NativeObject.defineProperties(self, newObj, props);
 291         }
 292 
 293         return newObj;
 294     }
 295 
 296     /**
 297      * ECMA 15.2.3.6 Object.defineProperty ( O, P, Attributes )
 298      *
 299      * @param self self reference
 300      * @param obj  object in which to define a property
 301      * @param prop property to define
 302      * @param attr attributes for property descriptor
 303      * @return object
 304      */
 305     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 306     public static ScriptObject defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
 307         final ScriptObject sobj = Global.checkObject(obj);
 308         sobj.defineOwnProperty(JSType.toPropertyKey(prop), attr, true);
 309         return sobj;
 310     }
 311 
 312     /**
 313      * ECMA 5.2.3.7 Object.defineProperties ( O, Properties )
 314      *
 315      * @param self  self reference
 316      * @param obj   object in which to define properties
 317      * @param props properties
 318      * @return object
 319      */
 320     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 321     public static ScriptObject defineProperties(final Object self, final Object obj, final Object props) {
 322         final ScriptObject sobj     = Global.checkObject(obj);
 323         final Object       propsObj = Global.toObject(props);
 324 
 325         if (propsObj instanceof ScriptObject) {
 326             final Object[] keys = ((ScriptObject)propsObj).getOwnKeys(false);
 327             for (final Object key : keys) {
 328                 final String prop = JSType.toString(key);
 329                 sobj.defineOwnProperty(prop, ((ScriptObject)propsObj).get(prop), true);
 330             }
 331         }
 332         return sobj;
 333     }
 334 
 335     /**
 336      * ECMA 15.2.3.8 Object.seal ( O )
 337      *
 338      * @param self self reference
 339      * @param obj  object to seal
 340      * @return sealed object
 341      */
 342     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 343     public static Object seal(final Object self, final Object obj) {
 344         if (obj instanceof ScriptObject) {
 345             return ((ScriptObject)obj).seal();
 346         } else if (obj instanceof ScriptObjectMirror) {
 347             return ((ScriptObjectMirror)obj).seal();
 348         } else {
 349             throw notAnObject(obj);
 350         }
 351     }
 352 
 353 
 354     /**
 355      * ECMA 15.2.3.9 Object.freeze ( O )
 356      *
 357      * @param self self reference
 358      * @param obj object to freeze
 359      * @return frozen object
 360      */
 361     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 362     public static Object freeze(final Object self, final Object obj) {
 363         if (obj instanceof ScriptObject) {
 364             return ((ScriptObject)obj).freeze();
 365         } else if (obj instanceof ScriptObjectMirror) {
 366             return ((ScriptObjectMirror)obj).freeze();
 367         } else {
 368             throw notAnObject(obj);
 369         }
 370     }
 371 
 372     /**
 373      * ECMA 15.2.3.10 Object.preventExtensions ( O )
 374      *
 375      * @param self self reference
 376      * @param obj  object, for which to set the internal extensible property to false
 377      * @return object
 378      */
 379     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 380     public static Object preventExtensions(final Object self, final Object obj) {
 381         if (obj instanceof ScriptObject) {
 382             return ((ScriptObject)obj).preventExtensions();
 383         } else if (obj instanceof ScriptObjectMirror) {
 384             return ((ScriptObjectMirror)obj).preventExtensions();
 385         } else {
 386             throw notAnObject(obj);
 387         }
 388     }
 389 
 390     /**
 391      * ECMA 15.2.3.11 Object.isSealed ( O )
 392      *
 393      * @param self self reference
 394      * @param obj check whether an object is sealed
 395      * @return true if sealed, false otherwise
 396      */
 397     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 398     public static boolean isSealed(final Object self, final Object obj) {
 399         if (obj instanceof ScriptObject) {
 400             return ((ScriptObject)obj).isSealed();
 401         } else if (obj instanceof ScriptObjectMirror) {
 402             return ((ScriptObjectMirror)obj).isSealed();
 403         } else {
 404             throw notAnObject(obj);
 405         }
 406     }
 407 
 408     /**
 409      * ECMA 15.2.3.12 Object.isFrozen ( O )
 410      *
 411      * @param self self reference
 412      * @param obj check whether an object
 413      * @return true if object is frozen, false otherwise
 414      */
 415     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 416     public static boolean isFrozen(final Object self, final Object obj) {
 417         if (obj instanceof ScriptObject) {
 418             return ((ScriptObject)obj).isFrozen();
 419         } else if (obj instanceof ScriptObjectMirror) {
 420             return ((ScriptObjectMirror)obj).isFrozen();
 421         } else {
 422             throw notAnObject(obj);
 423         }
 424     }
 425 
 426     /**
 427      * ECMA 15.2.3.13 Object.isExtensible ( O )
 428      *
 429      * @param self self reference
 430      * @param obj check whether an object is extensible
 431      * @return true if object is extensible, false otherwise
 432      */
 433     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 434     public static boolean isExtensible(final Object self, final Object obj) {
 435         if (obj instanceof ScriptObject) {
 436             return ((ScriptObject)obj).isExtensible();
 437         } else if (obj instanceof ScriptObjectMirror) {
 438             return ((ScriptObjectMirror)obj).isExtensible();
 439         } else {
 440             throw notAnObject(obj);
 441         }
 442     }
 443 
 444     /**
 445      * ECMA 15.2.3.14 Object.keys ( O )
 446      *
 447      * @param self self reference
 448      * @param obj  object from which to extract keys
 449      * @return array of keys in object
 450      */
 451     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 452     public static ScriptObject keys(final Object self, final Object obj) {
 453         if (obj instanceof ScriptObject) {
 454             final ScriptObject sobj = (ScriptObject)obj;
 455             return new NativeArray(sobj.getOwnKeys(false));
 456         } else if (obj instanceof ScriptObjectMirror) {
 457             final ScriptObjectMirror sobjMirror = (ScriptObjectMirror)obj;
 458             return new NativeArray(sobjMirror.getOwnKeys(false));
 459         } else {
 460             throw notAnObject(obj);
 461         }
 462     }
 463 
 464     /**
 465      * ECMA 15.2.2.1 , 15.2.1.1 new Object([value]) and Object([value])
 466      *
 467      * Constructor
 468      *
 469      * @param newObj is the new object instantiated with the new operator
 470      * @param self   self reference
 471      * @param value  value of object to be instantiated
 472      * @return the new NativeObject
 473      */
 474     @Constructor
 475     public static Object construct(final boolean newObj, final Object self, final Object value) {
 476         final JSType type = JSType.ofNoFunction(value);
 477 
 478         // Object(null), Object(undefined), Object() are same as "new Object()"
 479 
 480         if (newObj || type == JSType.NULL || type == JSType.UNDEFINED) {
 481             switch (type) {
 482             case BOOLEAN:
 483             case NUMBER:
 484             case STRING:
 485             case SYMBOL:
 486                 return Global.toObject(value);
 487             case OBJECT:
 488                 return value;
 489             case NULL:
 490             case UNDEFINED:
 491                 // fall through..
 492             default:
 493                 break;
 494             }
 495 
 496             return Global.newEmptyInstance();
 497         }
 498 
 499         return Global.toObject(value);
 500     }
 501 
 502     /**
 503      * ECMA 15.2.4.2 Object.prototype.toString ( )
 504      *
 505      * @param self self reference
 506      * @return ToString of object
 507      */
 508     @Function(attributes = Attribute.NOT_ENUMERABLE)

 509     public static String toString(final Object self) {
 510         return ScriptRuntime.builtinObjectToString(self);
 511     }
 512 
 513     /**
 514      * ECMA 15.2.4.3 Object.prototype.toLocaleString ( )
 515      *
 516      * @param self self reference
 517      * @return localized ToString
 518      */
 519     @Function(attributes = Attribute.NOT_ENUMERABLE)
 520     public static Object toLocaleString(final Object self) {
 521         final Object obj = JSType.toScriptObject(self);
 522         if (obj instanceof ScriptObject) {
 523             final InvokeByName toStringInvoker = getTO_STRING();
 524             final ScriptObject sobj = (ScriptObject)obj;
 525             try {
 526                 final Object toString = toStringInvoker.getGetter().invokeExact(sobj);
 527 
 528                 if (Bootstrap.isCallable(toString)) {


 541     }
 542 
 543     /**
 544      * ECMA 15.2.4.4 Object.prototype.valueOf ( )
 545      *
 546      * @param self self reference
 547      * @return value of object
 548      */
 549     @Function(attributes = Attribute.NOT_ENUMERABLE)
 550     public static Object valueOf(final Object self) {
 551         return Global.toObject(self);
 552     }
 553 
 554     /**
 555      * ECMA 15.2.4.5 Object.prototype.hasOwnProperty (V)
 556      *
 557      * @param self self reference
 558      * @param v property to check for
 559      * @return true if property exists in object
 560      */
 561     @Function(attributes = Attribute.NOT_ENUMERABLE)

 562     public static boolean hasOwnProperty(final Object self, final Object v) {
 563         // Convert ScriptObjects to primitive with String.class hint
 564         // but no need to convert other primitives to string.
 565         final Object key = JSType.toPrimitive(v, String.class);
 566         final Object obj = Global.toObject(self);
 567 
 568         return obj instanceof ScriptObject && ((ScriptObject)obj).hasOwnProperty(key);
 569     }
 570 
 571     /**
 572      * ECMA 15.2.4.6 Object.prototype.isPrototypeOf (V)
 573      *
 574      * @param self self reference
 575      * @param v v prototype object to check against
 576      * @return true if object is prototype of v
 577      */
 578     @Function(attributes = Attribute.NOT_ENUMERABLE)

 579     public static boolean isPrototypeOf(final Object self, final Object v) {
 580         if (!(v instanceof ScriptObject)) {
 581             return false;
 582         }
 583 
 584         final Object obj   = Global.toObject(self);
 585         ScriptObject proto = (ScriptObject)v;
 586 
 587         do {
 588             proto = proto.getProto();
 589             if (proto == obj) {
 590                 return true;
 591             }
 592         } while (proto != null);
 593 
 594         return false;
 595     }
 596 
 597     /**
 598      * ECMA 15.2.4.7 Object.prototype.propertyIsEnumerable (V)
 599      *
 600      * @param self self reference
 601      * @param v property to check if enumerable
 602      * @return true if property is enumerable
 603      */
 604     @Function(attributes = Attribute.NOT_ENUMERABLE)

 605     public static boolean propertyIsEnumerable(final Object self, final Object v) {
 606         final String str = JSType.toString(v);
 607         final Object obj = Global.toObject(self);
 608 
 609         if (obj instanceof ScriptObject) {
 610             final jdk.nashorn.internal.runtime.Property property = ((ScriptObject)obj).getMap().findProperty(str);
 611             return property != null && property.isEnumerable();
 612         }
 613 
 614         return false;
 615     }
 616 
 617     /**
 618      * Nashorn extension: Object.bindProperties
 619      *
 620      * Binds the source object's properties to the target object. Binding
 621      * properties allows two-way read/write for the properties of the source object.
 622      *
 623      * Example:
 624      * <pre>


 659      *
 660      * Limitations of property binding:
 661      * <ul>
 662      * <li> Only enumerable, immediate (not proto inherited) properties of the source object are bound.
 663      * <li> If the target object already contains a property called "foo", the source's "foo" is skipped (not bound).
 664      * <li> Properties added to the source object after binding to the target are not bound.
 665      * <li> Property configuration changes on the source object (or on the target) is not propagated.
 666      * <li> Delete of property on the target (or the source) is not propagated -
 667      * only the property value is set to 'undefined' if the property happens to be a data property.
 668      * </ul>
 669      * <p>
 670      * It is recommended that the bound properties be treated as non-configurable
 671      * properties to avoid surprises.
 672      * </p>
 673      *
 674      * @param self self reference
 675      * @param target the target object to which the source object's properties are bound
 676      * @param source the source object whose properties are bound to the target
 677      * @return the target object after property binding
 678      */
 679     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)

 680     public static Object bindProperties(final Object self, final Object target, final Object source) {
 681         // target object has to be a ScriptObject
 682         final ScriptObject targetObj = Global.checkObject(target);
 683         // check null or undefined source object
 684         Global.checkObjectCoercible(source);
 685 
 686         if (source instanceof ScriptObject) {
 687             final ScriptObject sourceObj  = (ScriptObject)source;
 688 
 689             final PropertyMap  sourceMap  = sourceObj.getMap();
 690             final Property[]   properties = sourceMap.getProperties();
 691             //replace the map and blow up everything to objects to work with dual fields :-(
 692 
 693             // filter non-enumerable properties
 694             final ArrayList<Property> propList = new ArrayList<>();
 695             for (final Property prop : properties) {
 696                 if (prop.isEnumerable()) {
 697                     final Object value = sourceObj.get(prop.getKey());
 698                     prop.setType(Object.class);
 699                     prop.setValue(sourceObj, sourceObj, value, false);




 131     @SuppressWarnings("unused")
 132     private static PropertyMap $nasgenmap$;
 133 
 134     private NativeObject() {
 135         // don't create me!
 136         throw new UnsupportedOperationException();
 137     }
 138 
 139     private static ECMAException notAnObject(final Object obj) {
 140         return typeError("not.an.object", ScriptRuntime.safeToString(obj));
 141     }
 142 
 143     /**
 144      * Nashorn extension: setIndexedPropertiesToExternalArrayData
 145      *
 146      * @param self self reference
 147      * @param obj object whose index properties are backed by buffer
 148      * @param buf external buffer - should be a nio ByteBuffer
 149      * @return the 'obj' object
 150      */
 151     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 152         documentation = "sets ByteBuffer to hold indexed data (nashorn extension)")
 153     public static ScriptObject setIndexedPropertiesToExternalArrayData(final Object self, final Object obj, final Object buf) {
 154         Global.checkObject(obj);
 155         final ScriptObject sobj = (ScriptObject)obj;
 156         if (buf instanceof ByteBuffer) {
 157             sobj.setArray(ArrayData.allocate((ByteBuffer)buf));
 158         } else {
 159             throw typeError("not.a.bytebuffer", "setIndexedPropertiesToExternalArrayData's buf argument");
 160         }
 161         return sobj;
 162     }
 163 
 164 
 165     /**
 166      * ECMA 15.2.3.2 Object.getPrototypeOf ( O )
 167      *
 168      * @param  self self reference
 169      * @param  obj object to get prototype from
 170      * @return the prototype of an object
 171      */
 172     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 173         documentation = "returns the prototype of the specified object")
 174     public static Object getPrototypeOf(final Object self, final Object obj) {
 175         if (obj instanceof ScriptObject) {
 176             return ((ScriptObject)obj).getProto();
 177         } else if (obj instanceof ScriptObjectMirror) {
 178             return ((ScriptObjectMirror)obj).getProto();
 179         } else {
 180             final JSType type = JSType.of(obj);
 181             if (type == JSType.OBJECT) {
 182                 // host (Java) objects have null __proto__
 183                 return null;
 184             }
 185 
 186             // must be some JS primitive
 187             throw notAnObject(obj);
 188         }
 189     }
 190 
 191     /**
 192      * Nashorn extension: Object.setPrototypeOf ( O, proto )
 193      * Also found in ES6 draft specification.
 194      *
 195      * @param  self self reference
 196      * @param  obj object to set prototype for
 197      * @param  proto prototype object to be used
 198      * @return object whose prototype is set
 199      */
 200     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 201         documentation = "sets the prototype of the given object (ES6)")
 202     public static Object setPrototypeOf(final Object self, final Object obj, final Object proto) {
 203         if (obj instanceof ScriptObject) {
 204             ((ScriptObject)obj).setPrototypeOf(proto);
 205             return obj;
 206         } else if (obj instanceof ScriptObjectMirror) {
 207             ((ScriptObjectMirror)obj).setProto(proto);
 208             return obj;
 209         }
 210 
 211         throw notAnObject(obj);
 212     }
 213 
 214     /**
 215      * ECMA 15.2.3.3 Object.getOwnPropertyDescriptor ( O, P )
 216      *
 217      * @param self  self reference
 218      * @param obj   object from which to get property descriptor for {@code ToString(prop)}
 219      * @param prop  property descriptor
 220      * @return property descriptor
 221      */
 222     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 223         documentation = "returns a property descriptor for an own property (not inherited property)")
 224     public static Object getOwnPropertyDescriptor(final Object self, final Object obj, final Object prop) {
 225         if (obj instanceof ScriptObject) {
 226             final String       key  = JSType.toString(prop);
 227             final ScriptObject sobj = (ScriptObject)obj;
 228 
 229             return sobj.getOwnPropertyDescriptor(key);
 230         } else if (obj instanceof ScriptObjectMirror) {
 231             final String       key  = JSType.toString(prop);
 232             final ScriptObjectMirror sobjMirror = (ScriptObjectMirror)obj;
 233 
 234             return sobjMirror.getOwnPropertyDescriptor(key);
 235         } else {
 236             throw notAnObject(obj);
 237         }
 238     }
 239 
 240     /**
 241      * ECMA 15.2.3.4 Object.getOwnPropertyNames ( O )
 242      *
 243      * @param self self reference
 244      * @param obj  object to query for property names
 245      * @return array of property names
 246      */
 247     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 248         documentation = "returns an array of all properties (enumerable or not) found directly on the given object")
 249     public static ScriptObject getOwnPropertyNames(final Object self, final Object obj) {
 250         if (obj instanceof ScriptObject) {
 251             return new NativeArray(((ScriptObject)obj).getOwnKeys(true));
 252         } else if (obj instanceof ScriptObjectMirror) {
 253             return new NativeArray(((ScriptObjectMirror)obj).getOwnKeys(true));
 254         } else {
 255             throw notAnObject(obj);
 256         }
 257     }
 258 
 259     /**
 260      * ECMA 2 19.1.2.8 Object.getOwnPropertySymbols ( O )
 261      *
 262      * @param self self reference
 263      * @param obj  object to query for property names
 264      * @return array of property names
 265      */
 266     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 267         documentation = "returns an array of all symbol properties found directly on the given object (ES6)")
 268     public static ScriptObject getOwnPropertySymbols(final Object self, final Object obj) {
 269         if (obj instanceof ScriptObject) {
 270             return new NativeArray(((ScriptObject)obj).getOwnSymbols(true));
 271         } else {
 272             // TODO: we don't support this on ScriptObjectMirror objects yet
 273             throw notAnObject(obj);
 274         }
 275     }
 276 
 277     /**
 278      * ECMA 15.2.3.5 Object.create ( O [, Properties] )
 279      *
 280      * @param self  self reference
 281      * @param proto prototype object
 282      * @param props properties to define
 283      * @return object created
 284      */
 285     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 286         documentation = "creates a new object with the specified prototype object and properties")
 287     public static ScriptObject create(final Object self, final Object proto, final Object props) {
 288         if (proto != null) {
 289             Global.checkObject(proto);
 290         }
 291 
 292         // FIXME: should we create a proper object with correct number of
 293         // properties?
 294         final ScriptObject newObj = Global.newEmptyInstance();
 295         newObj.setProto((ScriptObject)proto);
 296         if (props != UNDEFINED) {
 297             NativeObject.defineProperties(self, newObj, props);
 298         }
 299 
 300         return newObj;
 301     }
 302 
 303     /**
 304      * ECMA 15.2.3.6 Object.defineProperty ( O, P, Attributes )
 305      *
 306      * @param self self reference
 307      * @param obj  object in which to define a property
 308      * @param prop property to define
 309      * @param attr attributes for property descriptor
 310      * @return object
 311      */
 312     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 313         documentation = "adds an own property and/or update the attributes of an existing own property of an object")
 314     public static ScriptObject defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
 315         final ScriptObject sobj = Global.checkObject(obj);
 316         sobj.defineOwnProperty(JSType.toPropertyKey(prop), attr, true);
 317         return sobj;
 318     }
 319 
 320     /**
 321      * ECMA 5.2.3.7 Object.defineProperties ( O, Properties )
 322      *
 323      * @param self  self reference
 324      * @param obj   object in which to define properties
 325      * @param props properties
 326      * @return object
 327      */
 328     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 329         documentation = "defines new or modifies existing properties directly on the given object")
 330     public static ScriptObject defineProperties(final Object self, final Object obj, final Object props) {
 331         final ScriptObject sobj     = Global.checkObject(obj);
 332         final Object       propsObj = Global.toObject(props);
 333 
 334         if (propsObj instanceof ScriptObject) {
 335             final Object[] keys = ((ScriptObject)propsObj).getOwnKeys(false);
 336             for (final Object key : keys) {
 337                 final String prop = JSType.toString(key);
 338                 sobj.defineOwnProperty(prop, ((ScriptObject)propsObj).get(prop), true);
 339             }
 340         }
 341         return sobj;
 342     }
 343 
 344     /**
 345      * ECMA 15.2.3.8 Object.seal ( O )
 346      *
 347      * @param self self reference
 348      * @param obj  object to seal
 349      * @return sealed object
 350      */
 351     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 352         documentation = "prevents new properties from being added to the given object and marks existing properties as non-configurable")
 353     public static Object seal(final Object self, final Object obj) {
 354         if (obj instanceof ScriptObject) {
 355             return ((ScriptObject)obj).seal();
 356         } else if (obj instanceof ScriptObjectMirror) {
 357             return ((ScriptObjectMirror)obj).seal();
 358         } else {
 359             throw notAnObject(obj);
 360         }
 361     }
 362 
 363 
 364     /**
 365      * ECMA 15.2.3.9 Object.freeze ( O )
 366      *
 367      * @param self self reference
 368      * @param obj object to freeze
 369      * @return frozen object
 370      */
 371     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 372         documentation = "prevents new properties from being added to the given object and prevents existing properties from being removed or re-configured")
 373     public static Object freeze(final Object self, final Object obj) {
 374         if (obj instanceof ScriptObject) {
 375             return ((ScriptObject)obj).freeze();
 376         } else if (obj instanceof ScriptObjectMirror) {
 377             return ((ScriptObjectMirror)obj).freeze();
 378         } else {
 379             throw notAnObject(obj);
 380         }
 381     }
 382 
 383     /**
 384      * ECMA 15.2.3.10 Object.preventExtensions ( O )
 385      *
 386      * @param self self reference
 387      * @param obj  object, for which to set the internal extensible property to false
 388      * @return object
 389      */
 390     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 391         documentation = "prevents new properties from ever being added to the given object")
 392     public static Object preventExtensions(final Object self, final Object obj) {
 393         if (obj instanceof ScriptObject) {
 394             return ((ScriptObject)obj).preventExtensions();
 395         } else if (obj instanceof ScriptObjectMirror) {
 396             return ((ScriptObjectMirror)obj).preventExtensions();
 397         } else {
 398             throw notAnObject(obj);
 399         }
 400     }
 401 
 402     /**
 403      * ECMA 15.2.3.11 Object.isSealed ( O )
 404      *
 405      * @param self self reference
 406      * @param obj check whether an object is sealed
 407      * @return true if sealed, false otherwise
 408      */
 409     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 410         documentation = "tells if an object is sealed or not")
 411     public static boolean isSealed(final Object self, final Object obj) {
 412         if (obj instanceof ScriptObject) {
 413             return ((ScriptObject)obj).isSealed();
 414         } else if (obj instanceof ScriptObjectMirror) {
 415             return ((ScriptObjectMirror)obj).isSealed();
 416         } else {
 417             throw notAnObject(obj);
 418         }
 419     }
 420 
 421     /**
 422      * ECMA 15.2.3.12 Object.isFrozen ( O )
 423      *
 424      * @param self self reference
 425      * @param obj check whether an object
 426      * @return true if object is frozen, false otherwise
 427      */
 428     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 429         documentation = "tells if an object is fronzen or not")
 430     public static boolean isFrozen(final Object self, final Object obj) {
 431         if (obj instanceof ScriptObject) {
 432             return ((ScriptObject)obj).isFrozen();
 433         } else if (obj instanceof ScriptObjectMirror) {
 434             return ((ScriptObjectMirror)obj).isFrozen();
 435         } else {
 436             throw notAnObject(obj);
 437         }
 438     }
 439 
 440     /**
 441      * ECMA 15.2.3.13 Object.isExtensible ( O )
 442      *
 443      * @param self self reference
 444      * @param obj check whether an object is extensible
 445      * @return true if object is extensible, false otherwise
 446      */
 447     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 448         documentation = "tells if an object is extensible or not")
 449     public static boolean isExtensible(final Object self, final Object obj) {
 450         if (obj instanceof ScriptObject) {
 451             return ((ScriptObject)obj).isExtensible();
 452         } else if (obj instanceof ScriptObjectMirror) {
 453             return ((ScriptObjectMirror)obj).isExtensible();
 454         } else {
 455             throw notAnObject(obj);
 456         }
 457     }
 458 
 459     /**
 460      * ECMA 15.2.3.14 Object.keys ( O )
 461      *
 462      * @param self self reference
 463      * @param obj  object from which to extract keys
 464      * @return array of keys in object
 465      */
 466     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 467         documentation = "returns an array of the given object's own enumerable properties")
 468     public static ScriptObject keys(final Object self, final Object obj) {
 469         if (obj instanceof ScriptObject) {
 470             final ScriptObject sobj = (ScriptObject)obj;
 471             return new NativeArray(sobj.getOwnKeys(false));
 472         } else if (obj instanceof ScriptObjectMirror) {
 473             final ScriptObjectMirror sobjMirror = (ScriptObjectMirror)obj;
 474             return new NativeArray(sobjMirror.getOwnKeys(false));
 475         } else {
 476             throw notAnObject(obj);
 477         }
 478     }
 479 
 480     /**
 481      * ECMA 15.2.2.1 , 15.2.1.1 new Object([value]) and Object([value])
 482      *
 483      * Constructor
 484      *
 485      * @param newObj is the new object instantiated with the new operator
 486      * @param self   self reference
 487      * @param value  value of object to be instantiated
 488      * @return the new NativeObject
 489      */
 490     @Constructor(documentation = "creates a new script object or converts given value as a script object")
 491     public static Object construct(final boolean newObj, final Object self, final Object value) {
 492         final JSType type = JSType.ofNoFunction(value);
 493 
 494         // Object(null), Object(undefined), Object() are same as "new Object()"
 495 
 496         if (newObj || type == JSType.NULL || type == JSType.UNDEFINED) {
 497             switch (type) {
 498             case BOOLEAN:
 499             case NUMBER:
 500             case STRING:
 501             case SYMBOL:
 502                 return Global.toObject(value);
 503             case OBJECT:
 504                 return value;
 505             case NULL:
 506             case UNDEFINED:
 507                 // fall through..
 508             default:
 509                 break;
 510             }
 511 
 512             return Global.newEmptyInstance();
 513         }
 514 
 515         return Global.toObject(value);
 516     }
 517 
 518     /**
 519      * ECMA 15.2.4.2 Object.prototype.toString ( )
 520      *
 521      * @param self self reference
 522      * @return ToString of object
 523      */
 524     @Function(attributes = Attribute.NOT_ENUMERABLE,
 525         documentation = "returns a string representing of this object")
 526     public static String toString(final Object self) {
 527         return ScriptRuntime.builtinObjectToString(self);
 528     }
 529 
 530     /**
 531      * ECMA 15.2.4.3 Object.prototype.toLocaleString ( )
 532      *
 533      * @param self self reference
 534      * @return localized ToString
 535      */
 536     @Function(attributes = Attribute.NOT_ENUMERABLE)
 537     public static Object toLocaleString(final Object self) {
 538         final Object obj = JSType.toScriptObject(self);
 539         if (obj instanceof ScriptObject) {
 540             final InvokeByName toStringInvoker = getTO_STRING();
 541             final ScriptObject sobj = (ScriptObject)obj;
 542             try {
 543                 final Object toString = toStringInvoker.getGetter().invokeExact(sobj);
 544 
 545                 if (Bootstrap.isCallable(toString)) {


 558     }
 559 
 560     /**
 561      * ECMA 15.2.4.4 Object.prototype.valueOf ( )
 562      *
 563      * @param self self reference
 564      * @return value of object
 565      */
 566     @Function(attributes = Attribute.NOT_ENUMERABLE)
 567     public static Object valueOf(final Object self) {
 568         return Global.toObject(self);
 569     }
 570 
 571     /**
 572      * ECMA 15.2.4.5 Object.prototype.hasOwnProperty (V)
 573      *
 574      * @param self self reference
 575      * @param v property to check for
 576      * @return true if property exists in object
 577      */
 578     @Function(attributes = Attribute.NOT_ENUMERABLE,
 579         documentation = "tells whether this object has the specified property or not")
 580     public static boolean hasOwnProperty(final Object self, final Object v) {
 581         // Convert ScriptObjects to primitive with String.class hint
 582         // but no need to convert other primitives to string.
 583         final Object key = JSType.toPrimitive(v, String.class);
 584         final Object obj = Global.toObject(self);
 585 
 586         return obj instanceof ScriptObject && ((ScriptObject)obj).hasOwnProperty(key);
 587     }
 588 
 589     /**
 590      * ECMA 15.2.4.6 Object.prototype.isPrototypeOf (V)
 591      *
 592      * @param self self reference
 593      * @param v v prototype object to check against
 594      * @return true if object is prototype of v
 595      */
 596     @Function(attributes = Attribute.NOT_ENUMERABLE,
 597         documentation = "tests for this object in another object's prototype chain")
 598     public static boolean isPrototypeOf(final Object self, final Object v) {
 599         if (!(v instanceof ScriptObject)) {
 600             return false;
 601         }
 602 
 603         final Object obj   = Global.toObject(self);
 604         ScriptObject proto = (ScriptObject)v;
 605 
 606         do {
 607             proto = proto.getProto();
 608             if (proto == obj) {
 609                 return true;
 610             }
 611         } while (proto != null);
 612 
 613         return false;
 614     }
 615 
 616     /**
 617      * ECMA 15.2.4.7 Object.prototype.propertyIsEnumerable (V)
 618      *
 619      * @param self self reference
 620      * @param v property to check if enumerable
 621      * @return true if property is enumerable
 622      */
 623     @Function(attributes = Attribute.NOT_ENUMERABLE,
 624         documentation = "tells whether the given property is enumerable or not")
 625     public static boolean propertyIsEnumerable(final Object self, final Object v) {
 626         final String str = JSType.toString(v);
 627         final Object obj = Global.toObject(self);
 628 
 629         if (obj instanceof ScriptObject) {
 630             final jdk.nashorn.internal.runtime.Property property = ((ScriptObject)obj).getMap().findProperty(str);
 631             return property != null && property.isEnumerable();
 632         }
 633 
 634         return false;
 635     }
 636 
 637     /**
 638      * Nashorn extension: Object.bindProperties
 639      *
 640      * Binds the source object's properties to the target object. Binding
 641      * properties allows two-way read/write for the properties of the source object.
 642      *
 643      * Example:
 644      * <pre>


 679      *
 680      * Limitations of property binding:
 681      * <ul>
 682      * <li> Only enumerable, immediate (not proto inherited) properties of the source object are bound.
 683      * <li> If the target object already contains a property called "foo", the source's "foo" is skipped (not bound).
 684      * <li> Properties added to the source object after binding to the target are not bound.
 685      * <li> Property configuration changes on the source object (or on the target) is not propagated.
 686      * <li> Delete of property on the target (or the source) is not propagated -
 687      * only the property value is set to 'undefined' if the property happens to be a data property.
 688      * </ul>
 689      * <p>
 690      * It is recommended that the bound properties be treated as non-configurable
 691      * properties to avoid surprises.
 692      * </p>
 693      *
 694      * @param self self reference
 695      * @param target the target object to which the source object's properties are bound
 696      * @param source the source object whose properties are bound to the target
 697      * @return the target object after property binding
 698      */
 699     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR,
 700         documentation = "binds the source object's properties to the target object (nashorn extension)")
 701     public static Object bindProperties(final Object self, final Object target, final Object source) {
 702         // target object has to be a ScriptObject
 703         final ScriptObject targetObj = Global.checkObject(target);
 704         // check null or undefined source object
 705         Global.checkObjectCoercible(source);
 706 
 707         if (source instanceof ScriptObject) {
 708             final ScriptObject sourceObj  = (ScriptObject)source;
 709 
 710             final PropertyMap  sourceMap  = sourceObj.getMap();
 711             final Property[]   properties = sourceMap.getProperties();
 712             //replace the map and blow up everything to objects to work with dual fields :-(
 713 
 714             // filter non-enumerable properties
 715             final ArrayList<Property> propList = new ArrayList<>();
 716             for (final Property prop : properties) {
 717                 if (prop.isEnumerable()) {
 718                     final Object value = sourceObj.get(prop.getKey());
 719                     prop.setType(Object.class);
 720                     prop.setValue(sourceObj, sourceObj, value, false);


< prev index next >