1091 /**
1092 * Set the __proto__ of an object with checks.
1093 * @param newProto Prototype to set.
1094 */
1095 public final void setProtoCheck(final Object newProto) {
1096 if (newProto == null || newProto instanceof ScriptObject) {
1097 setProto((ScriptObject)newProto);
1098 } else {
1099 final ScriptObject global = Context.getGlobalTrusted();
1100 final Object newProtoObject = JSType.toScriptObject(global, newProto);
1101
1102 if (newProtoObject instanceof ScriptObject) {
1103 setProto((ScriptObject)newProtoObject);
1104 } else {
1105 throw typeError(global, "cant.set.proto.to.non.object", ScriptRuntime.safeToString(this), ScriptRuntime.safeToString(newProto));
1106 }
1107 }
1108 }
1109
1110 /**
1111 * return a List of own keys associated with the object.
1112 * @param all True if to include non-enumerable keys.
1113 * @return Array of keys.
1114 */
1115 public String[] getOwnKeys(final boolean all) {
1116 final List<Object> keys = new ArrayList<>();
1117 final PropertyMap selfMap = this.getMap();
1118
1119 final ArrayData array = getArray();
1120 final long length = array.length();
1121
1122 for (long i = 0; i < length; i = array.nextIndex(i)) {
1123 if (array.has((int)i)) {
1124 keys.add(JSType.toString(i));
1125 }
1126 }
1127
1128 for (final Property property : selfMap.getProperties()) {
1129 if (all || property.isEnumerable()) {
1130 keys.add(property.getKey());
1131 }
1192 *
1193 * ECMA 8.12.8 [[DefaultValue]](hint)
1194 *
1195 * @param typeHint the preferred type hint
1196 * @return the default value
1197 */
1198 public Object getDefaultValue(final Class<?> typeHint) {
1199 // We delegate to GlobalObject, as the implementation uses dynamic call sites to invoke object's "toString" and
1200 // "valueOf" methods, and in order to avoid those call sites from becoming megamorphic when multiple contexts
1201 // are being executed in a long-running program, we move the code and their associated dynamic call sites
1202 // (Global.TO_STRING and Global.VALUE_OF) into per-context code.
1203 return ((GlobalObject)Context.getGlobalTrusted()).getDefaultValue(this, typeHint);
1204 }
1205
1206 /**
1207 * Checking whether a script object is an instance of another. Used
1208 * in {@link ScriptFunction} for hasInstance implementation, walks
1209 * the proto chain
1210 *
1211 * @param instance instace to check
1212 * @return true if instance of instance
1213 */
1214 public boolean isInstance(final ScriptObject instance) {
1215 return false;
1216 }
1217
1218 /**
1219 * Flag this ScriptObject as non extensible
1220 *
1221 * @return the object after being made non extensible
1222 */
1223 public ScriptObject preventExtensions() {
1224 PropertyMap oldMap = getMap();
1225
1226 while (true) {
1227 final PropertyMap newMap = getMap().preventExtensions();
1228
1229 if (!compareAndSetMap(oldMap, newMap)) {
1230 oldMap = getMap();
1231 } else {
1232 return this;
1365 * ECMA 15.2.39 - freeze implementation. Freeze this ScriptObject
1366 * @return the frozen ScriptObject
1367 */
1368 public ScriptObject freeze() {
1369 PropertyMap oldMap = getMap();
1370
1371 while (true) {
1372 final PropertyMap newMap = getMap().freeze();
1373
1374 if (!compareAndSetMap(oldMap, newMap)) {
1375 oldMap = getMap();
1376 } else {
1377 setArray(ArrayData.freeze(getArray()));
1378 return this;
1379 }
1380 }
1381 }
1382
1383 /**
1384 * Check whether this ScriptObject is frozen
1385 * @return true if frozed
1386 */
1387 public boolean isFrozen() {
1388 return getMap().isFrozen();
1389 }
1390
1391
1392 /**
1393 * Flag this ScriptObject as scope
1394 */
1395 public final void setIsScope() {
1396 if (Context.DEBUG) {
1397 scopeCount++;
1398 }
1399 flags |= IS_SCOPE;
1400 }
1401
1402 /**
1403 * Check whether this ScriptObject is scope
1404 * @return true if scope
1405 */
|
1091 /**
1092 * Set the __proto__ of an object with checks.
1093 * @param newProto Prototype to set.
1094 */
1095 public final void setProtoCheck(final Object newProto) {
1096 if (newProto == null || newProto instanceof ScriptObject) {
1097 setProto((ScriptObject)newProto);
1098 } else {
1099 final ScriptObject global = Context.getGlobalTrusted();
1100 final Object newProtoObject = JSType.toScriptObject(global, newProto);
1101
1102 if (newProtoObject instanceof ScriptObject) {
1103 setProto((ScriptObject)newProtoObject);
1104 } else {
1105 throw typeError(global, "cant.set.proto.to.non.object", ScriptRuntime.safeToString(this), ScriptRuntime.safeToString(newProto));
1106 }
1107 }
1108 }
1109
1110 /**
1111 * return an array of own property keys associated with the object.
1112 *
1113 * @param all True if to include non-enumerable keys.
1114 * @return Array of keys.
1115 */
1116 public String[] getOwnKeys(final boolean all) {
1117 final List<Object> keys = new ArrayList<>();
1118 final PropertyMap selfMap = this.getMap();
1119
1120 final ArrayData array = getArray();
1121 final long length = array.length();
1122
1123 for (long i = 0; i < length; i = array.nextIndex(i)) {
1124 if (array.has((int)i)) {
1125 keys.add(JSType.toString(i));
1126 }
1127 }
1128
1129 for (final Property property : selfMap.getProperties()) {
1130 if (all || property.isEnumerable()) {
1131 keys.add(property.getKey());
1132 }
1193 *
1194 * ECMA 8.12.8 [[DefaultValue]](hint)
1195 *
1196 * @param typeHint the preferred type hint
1197 * @return the default value
1198 */
1199 public Object getDefaultValue(final Class<?> typeHint) {
1200 // We delegate to GlobalObject, as the implementation uses dynamic call sites to invoke object's "toString" and
1201 // "valueOf" methods, and in order to avoid those call sites from becoming megamorphic when multiple contexts
1202 // are being executed in a long-running program, we move the code and their associated dynamic call sites
1203 // (Global.TO_STRING and Global.VALUE_OF) into per-context code.
1204 return ((GlobalObject)Context.getGlobalTrusted()).getDefaultValue(this, typeHint);
1205 }
1206
1207 /**
1208 * Checking whether a script object is an instance of another. Used
1209 * in {@link ScriptFunction} for hasInstance implementation, walks
1210 * the proto chain
1211 *
1212 * @param instance instace to check
1213 * @return true if 'instance' is an instance of this object
1214 */
1215 public boolean isInstance(final ScriptObject instance) {
1216 return false;
1217 }
1218
1219 /**
1220 * Flag this ScriptObject as non extensible
1221 *
1222 * @return the object after being made non extensible
1223 */
1224 public ScriptObject preventExtensions() {
1225 PropertyMap oldMap = getMap();
1226
1227 while (true) {
1228 final PropertyMap newMap = getMap().preventExtensions();
1229
1230 if (!compareAndSetMap(oldMap, newMap)) {
1231 oldMap = getMap();
1232 } else {
1233 return this;
1366 * ECMA 15.2.39 - freeze implementation. Freeze this ScriptObject
1367 * @return the frozen ScriptObject
1368 */
1369 public ScriptObject freeze() {
1370 PropertyMap oldMap = getMap();
1371
1372 while (true) {
1373 final PropertyMap newMap = getMap().freeze();
1374
1375 if (!compareAndSetMap(oldMap, newMap)) {
1376 oldMap = getMap();
1377 } else {
1378 setArray(ArrayData.freeze(getArray()));
1379 return this;
1380 }
1381 }
1382 }
1383
1384 /**
1385 * Check whether this ScriptObject is frozen
1386 * @return true if frozen
1387 */
1388 public boolean isFrozen() {
1389 return getMap().isFrozen();
1390 }
1391
1392
1393 /**
1394 * Flag this ScriptObject as scope
1395 */
1396 public final void setIsScope() {
1397 if (Context.DEBUG) {
1398 scopeCount++;
1399 }
1400 flags |= IS_SCOPE;
1401 }
1402
1403 /**
1404 * Check whether this ScriptObject is scope
1405 * @return true if scope
1406 */
|