src/jdk/nashorn/internal/runtime/ScriptObject.java

changeset 379
682889823712
parent 350
3d947baa33cc
child 380
80c66d3fd872
equal deleted inserted replaced
378:39e17373d8df 379:682889823712
775 * @return new property 775 * @return new property
776 */ 776 */
777 public final Property modifyOwnProperty(final Property oldProperty, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) { 777 public final Property modifyOwnProperty(final Property oldProperty, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
778 Property newProperty; 778 Property newProperty;
779 if (oldProperty instanceof UserAccessorProperty) { 779 if (oldProperty instanceof UserAccessorProperty) {
780 // re-use the slots of the old user accessor property.
781 final UserAccessorProperty uc = (UserAccessorProperty) oldProperty; 780 final UserAccessorProperty uc = (UserAccessorProperty) oldProperty;
782 781 final int getterSlot = uc.getGetterSlot();
783 int getterSlot = uc.getGetterSlot(); 782 final int setterSlot = uc.getSetterSlot();
784 // clear the old getter and set the new getter
785 setSpill(getterSlot, getter); 783 setSpill(getterSlot, getter);
786 // if getter function is null, flag the slot to be negative (less by 1)
787 if (getter == null) {
788 getterSlot = -getterSlot - 1;
789 }
790
791 int setterSlot = uc.getSetterSlot();
792 // clear the old setter and set the new setter
793 setSpill(setterSlot, setter); 784 setSpill(setterSlot, setter);
794 // if setter function is null, flag the slot to be negative (less by 1) 785
795 if (setter == null) { 786 // if just flipping getter and setter with new functions, no need to change property or map
796 setterSlot = -setterSlot - 1; 787 if (uc.flags == propertyFlags) {
788 return oldProperty;
797 } 789 }
798 790
799 newProperty = new UserAccessorProperty(oldProperty.getKey(), propertyFlags, getterSlot, setterSlot); 791 newProperty = new UserAccessorProperty(oldProperty.getKey(), propertyFlags, getterSlot, setterSlot);
800 // if just flipping getter and setter with new functions, no need to change property or map
801 if (oldProperty.equals(newProperty)) {
802 return oldProperty;
803 }
804 } else { 792 } else {
805 // erase old property value and create new user accessor property 793 // erase old property value and create new user accessor property
806 erasePropertyValue(oldProperty); 794 erasePropertyValue(oldProperty);
807 newProperty = newUserAccessors(oldProperty.getKey(), propertyFlags, getter, setter); 795 newProperty = newUserAccessors(oldProperty.getKey(), propertyFlags, getter, setter);
808 } 796 }
860 * @param getter {@link UserAccessorProperty} defined getter, or null if none 848 * @param getter {@link UserAccessorProperty} defined getter, or null if none
861 * @param setter {@link UserAccessorProperty} defined setter, or null if none 849 * @param setter {@link UserAccessorProperty} defined setter, or null if none
862 */ 850 */
863 public final void setUserAccessors(final String key, final ScriptFunction getter, final ScriptFunction setter) { 851 public final void setUserAccessors(final String key, final ScriptFunction getter, final ScriptFunction setter) {
864 final Property oldProperty = getMap().findProperty(key); 852 final Property oldProperty = getMap().findProperty(key);
865 if (oldProperty != null) { 853 if (oldProperty instanceof UserAccessorProperty) {
866 final UserAccessorProperty newProperty = newUserAccessors(oldProperty.getKey(), oldProperty.getFlags(), getter, setter); 854 final UserAccessorProperty ua = (UserAccessorProperty)oldProperty;
867 modifyOwnProperty(oldProperty, newProperty); 855 setSpill(ua.getGetterSlot(), getter);
856 setSpill(ua.getSetterSlot(), setter);
868 } else { 857 } else {
869 final UserAccessorProperty newProperty = newUserAccessors(key, 0, getter, setter); 858 addOwnProperty(newUserAccessors(key, oldProperty != null ? oldProperty.getFlags() : 0, getter, setter));
870 addOwnProperty(newProperty);
871 } 859 }
872 } 860 }
873 861
874 private static int getIntValue(final FindProperty find) { 862 private static int getIntValue(final FindProperty find) {
875 final MethodHandle getter = find.getGetter(int.class); 863 final MethodHandle getter = find.getGetter(int.class);
1710 NashornCallSiteDescriptor.isFastScope(desc) && !property.canChangeType() ? null : guard); 1698 NashornCallSiteDescriptor.isFastScope(desc) && !property.canChangeType() ? null : guard);
1711 } 1699 }
1712 1700
1713 final ScriptObject prototype = find.getOwner(); 1701 final ScriptObject prototype = find.getOwner();
1714 1702
1715 if (!property.hasGetterFunction()) { 1703 if (!property.hasGetterFunction(prototype)) {
1716 methodHandle = bindTo(methodHandle, prototype); 1704 methodHandle = bindTo(methodHandle, prototype);
1717 } 1705 }
1718 return new GuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(proto, name), guard); 1706 return new GuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(proto, name), guard);
1719 } 1707 }
1720 1708
3142 3130
3143 /* 3131 /*
3144 * Make a new UserAccessorProperty property. getter and setter functions are stored in 3132 * Make a new UserAccessorProperty property. getter and setter functions are stored in
3145 * this ScriptObject and slot values are used in property object. 3133 * this ScriptObject and slot values are used in property object.
3146 */ 3134 */
3147 private UserAccessorProperty newUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) { 3135 protected final UserAccessorProperty newUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
3148 int oldSpillLength = getMap().getSpillLength(); 3136 final UserAccessorProperty property = getMap().newUserAccessors(key, propertyFlags);
3149 3137 setSpill(property.getGetterSlot(), getter);
3150 int getterSlot = oldSpillLength++; 3138 setSpill(property.getSetterSlot(), setter);
3151 setSpill(getterSlot, getter); 3139
3152 // if getter function is null, flag the slot to be negative (less by 1) 3140 return property;
3153 if (getter == null) { 3141 }
3154 getterSlot = -getterSlot - 1; 3142
3155 } 3143 protected final void setSpill(final int slot, final Object value) {
3156 3144 if (spill == null) {
3157 int setterSlot = oldSpillLength++; 3145 // create new spill.
3158 3146 spill = new Object[Math.max(slot + 1, SPILL_RATE)];
3159 setSpill(setterSlot, setter); 3147 } else if (slot >= spill.length) {
3160 // if setter function is null, flag the slot to be negative (less by 1) 3148 // grow spill as needed
3161 if (setter == null) { 3149 final Object[] newSpill = new Object[slot + 1];
3162 setterSlot = -setterSlot - 1; 3150 System.arraycopy(spill, 0, newSpill, 0, spill.length);
3163 } 3151 spill = newSpill;
3164 3152 }
3165 return new UserAccessorProperty(key, propertyFlags, getterSlot, setterSlot); 3153
3166 } 3154 spill[slot] = value;
3167 3155 }
3168 private void setSpill(final int slot, final Object value) { 3156
3169 if (slot >= 0) { 3157 protected Object getSpill(final int slot) {
3170 final int index = slot; 3158 return spill != null && slot < spill.length ? spill[slot] : null;
3171 if (spill == null) {
3172 // create new spill.
3173 spill = new Object[Math.max(index + 1, SPILL_RATE)];
3174 } else if (index >= spill.length) {
3175 // grow spill as needed
3176 final Object[] newSpill = new Object[index + 1];
3177 System.arraycopy(spill, 0, newSpill, 0, spill.length);
3178 spill = newSpill;
3179 }
3180
3181 spill[index] = value;
3182 }
3183 }
3184
3185 // user accessors are either stored in spill array slots
3186 // get the accessor value using slot number. Note that slot is spill array index.
3187 Object getSpill(final int slot) {
3188 final int index = slot;
3189 return (index < 0 || (index >= spill.length)) ? null : spill[index];
3190 } 3159 }
3191 3160
3192 private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { 3161 private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
3193 final Class<?> own = ScriptObject.class; 3162 final Class<?> own = ScriptObject.class;
3194 final MethodType mt = MH.type(rtype, types); 3163 final MethodType mt = MH.type(rtype, types);

mercurial