320 if (!Double.isNaN(doubleLength) && JSType.isRepresentableAsLong(doubleLength)) {
321 final long len = (long) doubleLength;
322 if (len >= 0 && len <= JSType.MAX_UINT) {
323 return len;
324 }
325 }
326 if (reject) {
327 throw rangeError("inappropriate.array.length", ScriptRuntime.safeToString(length));
328 }
329 return -1;
330 }
331
332 /**
333 * ECMA 15.4.4.2 Array.prototype.toString ( )
334 *
335 * @param self self reference
336 * @return string representation of array
337 */
338 @Function(attributes = Attribute.NOT_ENUMERABLE)
339 public static Object toString(final Object self) {
340 if (self instanceof ScriptObject) {
341 final ScriptObject sobj = (ScriptObject) self;
342 try {
343 final Object join = JOIN.getGetter().invokeExact(sobj);
344 if (join instanceof ScriptFunction) {
345 return JOIN.getInvoker().invokeExact(join, sobj);
346 }
347 } catch (final RuntimeException | Error e) {
348 throw e;
349 } catch (final Throwable t) {
350 throw new RuntimeException(t);
351 }
352 }
353
354 // FIXME: should lookup Object.prototype.toString and call that?
355 return ScriptRuntime.builtinObjectToString(self);
356 }
357
358 /**
359 * ECMA 15.4.4.3 Array.prototype.toLocaleString ( )
360 *
361 * @param self self reference
556 list.add(obj); // add empty object, but not an empty array
557 }
558 } else {
559 // single element, add it
560 list.add(obj);
561 }
562 }
563
564 return new NativeArray(list.toArray());
565 }
566
567 /**
568 * ECMA 15.4.4.5 Array.prototype.join (separator)
569 *
570 * @param self self reference
571 * @param separator element separator
572 * @return string representation after join
573 */
574 @Function(attributes = Attribute.NOT_ENUMERABLE)
575 public static Object join(final Object self, final Object separator) {
576 final String sep = separator == ScriptRuntime.UNDEFINED ? "," : JSType.toString(separator);
577 final StringBuilder sb = new StringBuilder();
578 final Iterator<Object> iter = arrayLikeIterator(self, true);
579
580 while (iter.hasNext()) {
581 final Object obj = iter.next();
582
583 if (obj != null && obj != ScriptRuntime.UNDEFINED) {
584 sb.append(JSType.toString(obj));
585 }
586
587 if (iter.hasNext()) {
588 sb.append(sep);
589 }
590 }
591
592 return sb.toString();
593 }
594
595 /**
596 * ECMA 15.4.4.6 Array.prototype.pop ()
597 *
598 * @param self self reference
|
320 if (!Double.isNaN(doubleLength) && JSType.isRepresentableAsLong(doubleLength)) {
321 final long len = (long) doubleLength;
322 if (len >= 0 && len <= JSType.MAX_UINT) {
323 return len;
324 }
325 }
326 if (reject) {
327 throw rangeError("inappropriate.array.length", ScriptRuntime.safeToString(length));
328 }
329 return -1;
330 }
331
332 /**
333 * ECMA 15.4.4.2 Array.prototype.toString ( )
334 *
335 * @param self self reference
336 * @return string representation of array
337 */
338 @Function(attributes = Attribute.NOT_ENUMERABLE)
339 public static Object toString(final Object self) {
340 final Object obj = Global.toObject(self);
341 if (obj instanceof ScriptObject) {
342 final ScriptObject sobj = (ScriptObject)obj;
343 try {
344 final Object join = JOIN.getGetter().invokeExact(sobj);
345 if (join instanceof ScriptFunction) {
346 return JOIN.getInvoker().invokeExact(join, sobj);
347 }
348 } catch (final RuntimeException | Error e) {
349 throw e;
350 } catch (final Throwable t) {
351 throw new RuntimeException(t);
352 }
353 }
354
355 // FIXME: should lookup Object.prototype.toString and call that?
356 return ScriptRuntime.builtinObjectToString(self);
357 }
358
359 /**
360 * ECMA 15.4.4.3 Array.prototype.toLocaleString ( )
361 *
362 * @param self self reference
557 list.add(obj); // add empty object, but not an empty array
558 }
559 } else {
560 // single element, add it
561 list.add(obj);
562 }
563 }
564
565 return new NativeArray(list.toArray());
566 }
567
568 /**
569 * ECMA 15.4.4.5 Array.prototype.join (separator)
570 *
571 * @param self self reference
572 * @param separator element separator
573 * @return string representation after join
574 */
575 @Function(attributes = Attribute.NOT_ENUMERABLE)
576 public static Object join(final Object self, final Object separator) {
577 final StringBuilder sb = new StringBuilder();
578 final Iterator<Object> iter = arrayLikeIterator(self, true);
579 final String sep = separator == ScriptRuntime.UNDEFINED ? "," : JSType.toString(separator);
580
581 while (iter.hasNext()) {
582 final Object obj = iter.next();
583
584 if (obj != null && obj != ScriptRuntime.UNDEFINED) {
585 sb.append(JSType.toString(obj));
586 }
587
588 if (iter.hasNext()) {
589 sb.append(sep);
590 }
591 }
592
593 return sb.toString();
594 }
595
596 /**
597 * ECMA 15.4.4.6 Array.prototype.pop ()
598 *
599 * @param self self reference
|