595 /** 596 * Spec. mentions use of [[DefineOwnProperty]] for indexed properties in 597 * certain places (eg. Array.prototype.map, filter). We can not use ScriptObject.set 598 * method in such cases. This is because set method uses inherited setters (if any) 599 * from any object in proto chain such as Array.prototype, Object.prototype. 600 * This method directly sets a particular element value in the current object. 601 * 602 * @param index key for property 603 * @param value value to define 604 */ 605 public final void defineOwnProperty(final int index, final Object value) { 606 assert isValidArrayIndex(index) : "invalid array index"; 607 final long longIndex = ArrayIndex.toLongIndex(index); 608 if (longIndex >= getArray().length()) { 609 // make array big enough to hold.. 610 setArray(getArray().ensure(longIndex)); 611 } 612 setArray(getArray().set(index, value, false)); 613 } 614 615 private void checkIntegerKey(final String key) { 616 final int index = getArrayIndex(key); 617 618 if (isValidArrayIndex(index)) { 619 final ArrayData data = getArray(); 620 621 if (data.has(index)) { 622 setArray(data.delete(index)); 623 } 624 } 625 } 626 627 /** 628 * Add a new property to the object. 629 * 630 * @param key property key 631 * @param propertyDesc property descriptor for property 632 */ 633 public final void addOwnProperty(final String key, final PropertyDescriptor propertyDesc) { 634 // Already checked that there is no own property with that key. 2730 @Override 2731 public Object get(final int key) { 2732 final int index = getArrayIndex(key); 2733 final ArrayData array = getArray(); 2734 2735 if (array.has(index)) { 2736 return array.getObject(index); 2737 } 2738 2739 return get(index, JSType.toString(key)); 2740 } 2741 2742 /** 2743 * Handle when an array doesn't have a slot - possibly grow and/or convert array. 2744 * 2745 * @param index key as index 2746 * @param value element value 2747 * @param strict are we in strict mode 2748 */ 2749 private void doesNotHave(final int index, final Object value, final boolean strict) { 2750 final long oldLength = getArray().length(); 2751 final long longIndex = ArrayIndex.toLongIndex(index); 2752 2753 if (getMap().containsArrayKeys()) { 2754 final String key = JSType.toString(longIndex); 2755 final FindProperty find = findProperty(key, true); 2756 2757 if (find != null) { 2758 setObject(find, strict, key, value); 2759 return; 2760 } 2761 } 2762 2763 if (longIndex >= oldLength) { 2764 if (!isExtensible()) { 2765 if (strict) { 2766 throw typeError("object.non.extensible", JSType.toString(index), ScriptRuntime.safeToString(this)); 2767 } 2768 return; 2769 } 2770 setArray(getArray().ensure(longIndex)); 2771 } 2772 2773 if (value instanceof Integer) { 2774 setArray(getArray().set(index, (int)value, strict)); 2775 } else if (value instanceof Long) { 2776 setArray(getArray().set(index, (long)value, strict)); 2777 } else if (value instanceof Double) { 2778 setArray(getArray().set(index, (double)value, strict)); 2779 } else { 2780 setArray(getArray().set(index, value, strict)); 2781 } 2782 | 595 /** 596 * Spec. mentions use of [[DefineOwnProperty]] for indexed properties in 597 * certain places (eg. Array.prototype.map, filter). We can not use ScriptObject.set 598 * method in such cases. This is because set method uses inherited setters (if any) 599 * from any object in proto chain such as Array.prototype, Object.prototype. 600 * This method directly sets a particular element value in the current object. 601 * 602 * @param index key for property 603 * @param value value to define 604 */ 605 public final void defineOwnProperty(final int index, final Object value) { 606 assert isValidArrayIndex(index) : "invalid array index"; 607 final long longIndex = ArrayIndex.toLongIndex(index); 608 if (longIndex >= getArray().length()) { 609 // make array big enough to hold.. 610 setArray(getArray().ensure(longIndex)); 611 } 612 setArray(getArray().set(index, value, false)); 613 } 614 615 /** 616 * Almost like defineOwnProperty(int,Object) but makes 'gap' elements empty 617 * 618 * @param index key for property 619 * @param value value to define 620 */ 621 public final void defineOwnPropertyNoGap(final int index, final Object value) { 622 assert isValidArrayIndex(index) : "invalid array index"; 623 final long longIndex = ArrayIndex.toLongIndex(index); 624 setValueAtArrayIndex(longIndex, index, value, false); 625 } 626 627 private void checkIntegerKey(final String key) { 628 final int index = getArrayIndex(key); 629 630 if (isValidArrayIndex(index)) { 631 final ArrayData data = getArray(); 632 633 if (data.has(index)) { 634 setArray(data.delete(index)); 635 } 636 } 637 } 638 639 /** 640 * Add a new property to the object. 641 * 642 * @param key property key 643 * @param propertyDesc property descriptor for property 644 */ 645 public final void addOwnProperty(final String key, final PropertyDescriptor propertyDesc) { 646 // Already checked that there is no own property with that key. 2742 @Override 2743 public Object get(final int key) { 2744 final int index = getArrayIndex(key); 2745 final ArrayData array = getArray(); 2746 2747 if (array.has(index)) { 2748 return array.getObject(index); 2749 } 2750 2751 return get(index, JSType.toString(key)); 2752 } 2753 2754 /** 2755 * Handle when an array doesn't have a slot - possibly grow and/or convert array. 2756 * 2757 * @param index key as index 2758 * @param value element value 2759 * @param strict are we in strict mode 2760 */ 2761 private void doesNotHave(final int index, final Object value, final boolean strict) { 2762 final long longIndex = ArrayIndex.toLongIndex(index); 2763 if (getMap().containsArrayKeys()) { 2764 final String key = JSType.toString(longIndex); 2765 final FindProperty find = findProperty(key, true); 2766 2767 if (find != null) { 2768 setObject(find, strict, key, value); 2769 return; 2770 } 2771 } 2772 2773 setValueAtArrayIndex(longIndex, index, value, strict); 2774 } 2775 2776 /** 2777 * Handle when an array doesn't have a slot - possibly grow and/or convert array. 2778 * 2779 * @param index key as index 2780 * @param value element value 2781 * @param strict are we in strict mode 2782 */ 2783 private void setValueAtArrayIndex(final long longIndex, final int index, final Object value, final boolean strict) { 2784 final long oldLength = getArray().length(); 2785 if (longIndex >= oldLength) { 2786 if (!isExtensible()) { 2787 if (strict) { 2788 throw typeError("object.non.extensible", JSType.toString(index), ScriptRuntime.safeToString(this)); 2789 } 2790 return; 2791 } 2792 setArray(getArray().ensure(longIndex)); 2793 } 2794 2795 if (value instanceof Integer) { 2796 setArray(getArray().set(index, (int)value, strict)); 2797 } else if (value instanceof Long) { 2798 setArray(getArray().set(index, (long)value, strict)); 2799 } else if (value instanceof Double) { 2800 setArray(getArray().set(index, (double)value, strict)); 2801 } else { 2802 setArray(getArray().set(index, value, strict)); 2803 } 2804 |