11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.objects; 27 28 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; 29 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 30 31 import jdk.nashorn.internal.objects.annotations.Attribute; 32 import jdk.nashorn.internal.objects.annotations.Constructor; 33 import jdk.nashorn.internal.objects.annotations.Function; 34 import jdk.nashorn.internal.objects.annotations.ScriptClass; 35 import jdk.nashorn.internal.objects.annotations.Where; 36 import jdk.nashorn.internal.runtime.JSType; 37 import jdk.nashorn.internal.runtime.ScriptFunction; 38 import jdk.nashorn.internal.runtime.ScriptObject; 39 import jdk.nashorn.internal.runtime.ScriptRuntime; 40 import jdk.nashorn.internal.runtime.linker.InvokeByName; 41 42 /** 43 * ECMA 15.2 Object objects 44 * 45 * JavaScript Object constructor/prototype. Note: instances of this class are 46 * never created. This class is not even a subclass of ScriptObject. But, we use 47 * this class to generate prototype and constructor for "Object". 48 * 49 */ 50 @ScriptClass("Object") 51 public final class NativeObject { 52 private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class); 53 54 private NativeObject() { 55 } 56 57 /** 58 * ECMA 15.2.3.2 Object.getPrototypeOf ( O ) 59 * 60 * @param self self reference 61 * @param obj object to get prototype from 62 * @return the prototype of an object 63 */ 64 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 65 public static Object getPrototypeOf(final Object self, final Object obj) { 66 Global.checkObject(obj); 67 68 return ((ScriptObject)obj).getProto(); 69 } 70 71 /** 72 * ECMA 15.2.3.3 Object.getOwnPropertyDescriptor ( O, P ) 73 * 74 * @param self self reference 75 * @param obj object from which to get property descriptor for {@code ToString(prop)} 76 * @param prop property descriptor 77 * @return property descriptor 78 */ 79 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 80 public static Object getOwnPropertyDescriptor(final Object self, final Object obj, final Object prop) { 81 Global.checkObject(obj); 82 83 final String key = JSType.toString(prop); 84 final ScriptObject sobj = (ScriptObject)obj; 85 86 return sobj.getOwnPropertyDescriptor(key); 87 } 88 89 /** 90 * ECMA 15.2.3.4 Object.getOwnPropertyNames ( O ) 91 * 92 * @param self self reference 93 * @param obj object to query for property names 94 * @return array of property names 95 */ 96 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 97 public static Object getOwnPropertyNames(final Object self, final Object obj) { 98 Global.checkObject(obj); 99 100 return new NativeArray(((ScriptObject)obj).getOwnKeys(true)); 101 } 102 103 /** 104 * ECMA 15.2.3.5 Object.create ( O [, Properties] ) 105 * 106 * @param self self reference 107 * @param proto prototype object 108 * @param props properties to define 109 * @return object created 110 */ 111 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 112 public static Object create(final Object self, final Object proto, final Object props) { 113 if (proto != null) { 114 Global.checkObject(proto); 115 } 116 117 // FIXME: should we create a proper object with correct number of 118 // properties? 119 final ScriptObject newObj = Global.newEmptyInstance(); 120 newObj.setProtoCheck(proto); 158 159 if (propsObj instanceof ScriptObject) { 160 final Object[] keys = ((ScriptObject)propsObj).getOwnKeys(false); 161 for (final Object key : keys) { 162 final String prop = JSType.toString(key); 163 sobj.defineOwnProperty(prop, ((ScriptObject)propsObj).get(prop), true); 164 } 165 } 166 return sobj; 167 } 168 169 /** 170 * ECMA 15.2.3.8 Object.seal ( O ) 171 * 172 * @param self self reference 173 * @param obj object to seal 174 * @return sealed object 175 */ 176 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 177 public static Object seal(final Object self, final Object obj) { 178 Global.checkObject(obj); 179 return ((ScriptObject)obj).seal(); 180 } 181 182 183 /** 184 * ECMA 15.2.3.9 Object.freeze ( O ) 185 * 186 * @param self self reference 187 * @param obj object to freeze 188 * @return frozen object 189 */ 190 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 191 public static Object freeze(final Object self, final Object obj) { 192 Global.checkObject(obj); 193 return ((ScriptObject)obj).freeze(); 194 } 195 196 /** 197 * ECMA 15.2.3.10 Object.preventExtensions ( O ) 198 * 199 * @param self self reference 200 * @param obj object, for which to set the internal extensible property to false 201 * @return object 202 */ 203 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 204 public static Object preventExtensions(final Object self, final Object obj) { 205 Global.checkObject(obj); 206 return ((ScriptObject)obj).preventExtensions(); 207 } 208 209 /** 210 * ECMA 15.2.3.11 Object.isSealed ( O ) 211 * 212 * @param self self reference 213 * @param obj check whether an object is sealed 214 * @return true if sealed, false otherwise 215 */ 216 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 217 public static Object isSealed(final Object self, final Object obj) { 218 Global.checkObject(obj); 219 return ((ScriptObject)obj).isSealed(); 220 } 221 222 /** 223 * ECMA 15.2.3.12 Object.isFrozen ( O ) 224 * 225 * @param self self reference 226 * @param obj check whether an object 227 * @return true if object is frozen, false otherwise 228 */ 229 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 230 public static Object isFrozen(final Object self, final Object obj) { 231 Global.checkObject(obj); 232 return ((ScriptObject)obj).isFrozen(); 233 } 234 235 /** 236 * ECMA 15.2.3.13 Object.isExtensible ( O ) 237 * 238 * @param self self reference 239 * @param obj check whether an object is extensible 240 * @return true if object is extensible, false otherwise 241 */ 242 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 243 public static Object isExtensible(final Object self, final Object obj) { 244 Global.checkObject(obj); 245 return ((ScriptObject)obj).isExtensible(); 246 } 247 248 /** 249 * ECMA 15.2.3.14 Object.keys ( O ) 250 * 251 * @param self self reference 252 * @param obj object from which to extract keys 253 * @return array of keys in object 254 */ 255 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 256 public static Object keys(final Object self, final Object obj) { 257 Global.checkObject(obj); 258 final ScriptObject sobj = (ScriptObject)obj; 259 return new NativeArray(sobj.getOwnKeys(false)); 260 } 261 262 /** 263 * ECMA 15.2.2.1 , 15.2.1.1 new Object([value]) and Object([value]) 264 * 265 * Constructor 266 * 267 * @param newObj is the new object instantiated with the new operator 268 * @param self self reference 269 * @param value value of object to be instantiated 270 * @return the new NativeObject 271 */ 272 @Constructor 273 public static Object construct(final boolean newObj, final Object self, final Object value) { 274 final JSType type = JSType.of(value); 275 276 // Object(null), Object(undefined), Object() are same as "new Object()" 277 278 if (newObj || (type == JSType.NULL || type == JSType.UNDEFINED)) { 279 switch (type) { | 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.objects; 27 28 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; 29 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 30 31 import jdk.nashorn.api.scripting.ScriptObjectMirror; 32 import jdk.nashorn.internal.objects.annotations.Attribute; 33 import jdk.nashorn.internal.objects.annotations.Constructor; 34 import jdk.nashorn.internal.objects.annotations.Function; 35 import jdk.nashorn.internal.objects.annotations.ScriptClass; 36 import jdk.nashorn.internal.objects.annotations.Where; 37 import jdk.nashorn.internal.runtime.ECMAException; 38 import jdk.nashorn.internal.runtime.JSType; 39 import jdk.nashorn.internal.runtime.ScriptFunction; 40 import jdk.nashorn.internal.runtime.ScriptObject; 41 import jdk.nashorn.internal.runtime.ScriptRuntime; 42 import jdk.nashorn.internal.runtime.linker.InvokeByName; 43 44 /** 45 * ECMA 15.2 Object objects 46 * 47 * JavaScript Object constructor/prototype. Note: instances of this class are 48 * never created. This class is not even a subclass of ScriptObject. But, we use 49 * this class to generate prototype and constructor for "Object". 50 * 51 */ 52 @ScriptClass("Object") 53 public final class NativeObject { 54 private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class); 55 56 private NativeObject() { 57 } 58 59 private static ECMAException notAnObject(final Object obj) { 60 return typeError("not.an.object", ScriptRuntime.safeToString(obj)); 61 } 62 63 /** 64 * ECMA 15.2.3.2 Object.getPrototypeOf ( O ) 65 * 66 * @param self self reference 67 * @param obj object to get prototype from 68 * @return the prototype of an object 69 */ 70 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 71 public static Object getPrototypeOf(final Object self, final Object obj) { 72 if (obj instanceof ScriptObject) { 73 return ((ScriptObject)obj).getProto(); 74 } else if (obj instanceof ScriptObjectMirror) { 75 return ((ScriptObjectMirror)obj).getProto(); 76 } else { 77 throw notAnObject(obj); 78 } 79 } 80 81 /** 82 * ECMA 15.2.3.3 Object.getOwnPropertyDescriptor ( O, P ) 83 * 84 * @param self self reference 85 * @param obj object from which to get property descriptor for {@code ToString(prop)} 86 * @param prop property descriptor 87 * @return property descriptor 88 */ 89 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 90 public static Object getOwnPropertyDescriptor(final Object self, final Object obj, final Object prop) { 91 if (obj instanceof ScriptObject) { 92 final String key = JSType.toString(prop); 93 final ScriptObject sobj = (ScriptObject)obj; 94 95 return sobj.getOwnPropertyDescriptor(key); 96 } else if (obj instanceof ScriptObjectMirror) { 97 final String key = JSType.toString(prop); 98 final ScriptObjectMirror sobjMirror = (ScriptObjectMirror)obj; 99 100 return sobjMirror.getOwnPropertyDescriptor(key); 101 } else { 102 throw notAnObject(obj); 103 } 104 } 105 106 /** 107 * ECMA 15.2.3.4 Object.getOwnPropertyNames ( O ) 108 * 109 * @param self self reference 110 * @param obj object to query for property names 111 * @return array of property names 112 */ 113 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 114 public static Object getOwnPropertyNames(final Object self, final Object obj) { 115 if (obj instanceof ScriptObject) { 116 return new NativeArray(((ScriptObject)obj).getOwnKeys(true)); 117 } else if (obj instanceof ScriptObjectMirror) { 118 return new NativeArray(((ScriptObjectMirror)obj).getOwnKeys(true)); 119 } else { 120 throw notAnObject(obj); 121 } 122 } 123 124 /** 125 * ECMA 15.2.3.5 Object.create ( O [, Properties] ) 126 * 127 * @param self self reference 128 * @param proto prototype object 129 * @param props properties to define 130 * @return object created 131 */ 132 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 133 public static Object create(final Object self, final Object proto, final Object props) { 134 if (proto != null) { 135 Global.checkObject(proto); 136 } 137 138 // FIXME: should we create a proper object with correct number of 139 // properties? 140 final ScriptObject newObj = Global.newEmptyInstance(); 141 newObj.setProtoCheck(proto); 179 180 if (propsObj instanceof ScriptObject) { 181 final Object[] keys = ((ScriptObject)propsObj).getOwnKeys(false); 182 for (final Object key : keys) { 183 final String prop = JSType.toString(key); 184 sobj.defineOwnProperty(prop, ((ScriptObject)propsObj).get(prop), true); 185 } 186 } 187 return sobj; 188 } 189 190 /** 191 * ECMA 15.2.3.8 Object.seal ( O ) 192 * 193 * @param self self reference 194 * @param obj object to seal 195 * @return sealed object 196 */ 197 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 198 public static Object seal(final Object self, final Object obj) { 199 if (obj instanceof ScriptObject) { 200 return ((ScriptObject)obj).seal(); 201 } else if (obj instanceof ScriptObjectMirror) { 202 return ((ScriptObjectMirror)obj).seal(); 203 } else { 204 throw notAnObject(obj); 205 } 206 } 207 208 209 /** 210 * ECMA 15.2.3.9 Object.freeze ( O ) 211 * 212 * @param self self reference 213 * @param obj object to freeze 214 * @return frozen object 215 */ 216 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 217 public static Object freeze(final Object self, final Object obj) { 218 if (obj instanceof ScriptObject) { 219 return ((ScriptObject)obj).freeze(); 220 } else if (obj instanceof ScriptObjectMirror) { 221 return ((ScriptObjectMirror)obj).freeze(); 222 } else { 223 throw notAnObject(obj); 224 } 225 } 226 227 /** 228 * ECMA 15.2.3.10 Object.preventExtensions ( O ) 229 * 230 * @param self self reference 231 * @param obj object, for which to set the internal extensible property to false 232 * @return object 233 */ 234 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 235 public static Object preventExtensions(final Object self, final Object obj) { 236 if (obj instanceof ScriptObject) { 237 return ((ScriptObject)obj).preventExtensions(); 238 } else if (obj instanceof ScriptObjectMirror) { 239 return ((ScriptObjectMirror)obj).preventExtensions(); 240 } else { 241 throw notAnObject(obj); 242 } 243 } 244 245 /** 246 * ECMA 15.2.3.11 Object.isSealed ( O ) 247 * 248 * @param self self reference 249 * @param obj check whether an object is sealed 250 * @return true if sealed, false otherwise 251 */ 252 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 253 public static Object isSealed(final Object self, final Object obj) { 254 if (obj instanceof ScriptObject) { 255 return ((ScriptObject)obj).isSealed(); 256 } else if (obj instanceof ScriptObjectMirror) { 257 return ((ScriptObjectMirror)obj).isSealed(); 258 } else { 259 throw notAnObject(obj); 260 } 261 } 262 263 /** 264 * ECMA 15.2.3.12 Object.isFrozen ( O ) 265 * 266 * @param self self reference 267 * @param obj check whether an object 268 * @return true if object is frozen, false otherwise 269 */ 270 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 271 public static Object isFrozen(final Object self, final Object obj) { 272 if (obj instanceof ScriptObject) { 273 return ((ScriptObject)obj).isFrozen(); 274 } else if (obj instanceof ScriptObjectMirror) { 275 return ((ScriptObjectMirror)obj).isFrozen(); 276 } else { 277 throw notAnObject(obj); 278 } 279 } 280 281 /** 282 * ECMA 15.2.3.13 Object.isExtensible ( O ) 283 * 284 * @param self self reference 285 * @param obj check whether an object is extensible 286 * @return true if object is extensible, false otherwise 287 */ 288 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 289 public static Object isExtensible(final Object self, final Object obj) { 290 if (obj instanceof ScriptObject) { 291 return ((ScriptObject)obj).isExtensible(); 292 } else if (obj instanceof ScriptObjectMirror) { 293 return ((ScriptObjectMirror)obj).isExtensible(); 294 } else { 295 throw notAnObject(obj); 296 } 297 } 298 299 /** 300 * ECMA 15.2.3.14 Object.keys ( O ) 301 * 302 * @param self self reference 303 * @param obj object from which to extract keys 304 * @return array of keys in object 305 */ 306 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 307 public static Object keys(final Object self, final Object obj) { 308 if (obj instanceof ScriptObject) { 309 final ScriptObject sobj = (ScriptObject)obj; 310 return new NativeArray(sobj.getOwnKeys(false)); 311 } else if (obj instanceof ScriptObjectMirror) { 312 final ScriptObjectMirror sobjMirror = (ScriptObjectMirror)obj; 313 return new NativeArray(sobjMirror.getOwnKeys(false)); 314 } else { 315 throw notAnObject(obj); 316 } 317 } 318 319 /** 320 * ECMA 15.2.2.1 , 15.2.1.1 new Object([value]) and Object([value]) 321 * 322 * Constructor 323 * 324 * @param newObj is the new object instantiated with the new operator 325 * @param self self reference 326 * @param value value of object to be instantiated 327 * @return the new NativeObject 328 */ 329 @Constructor 330 public static Object construct(final boolean newObj, final Object self, final Object value) { 331 final JSType type = JSType.of(value); 332 333 // Object(null), Object(undefined), Object() are same as "new Object()" 334 335 if (newObj || (type == JSType.NULL || type == JSType.UNDEFINED)) { 336 switch (type) { |