8022731: NativeArguments has wrong implementation of isMapped()

Mon, 12 Aug 2013 13:31:43 +0200

author
hannesw
date
Mon, 12 Aug 2013 13:31:43 +0200
changeset 496
03ba1cd734c0
parent 495
0bbaa0ac36ab
child 497
821b605c7046

8022731: NativeArguments has wrong implementation of isMapped()
Reviewed-by: lagergren, jlaskey

src/jdk/nashorn/internal/objects/NativeArguments.java file | annotate | diff | comparison | revisions
test/script/basic/JDK-8022731.js file | annotate | diff | comparison | revisions
test/script/basic/JDK-8022731.js.EXPECTED file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/internal/objects/NativeArguments.java	Mon Aug 12 16:52:32 2013 +0530
     1.2 +++ b/src/jdk/nashorn/internal/objects/NativeArguments.java	Mon Aug 12 13:31:43 2013 +0200
     1.3 @@ -76,36 +76,21 @@
     1.4  
     1.5      private Object length;
     1.6      private Object callee;
     1.7 -    private ArrayData namedArgs;
     1.8 -    // This is lazily initialized - only when delete is invoked at all
     1.9 +    private final int numMapped;
    1.10 +    private final int numParams;
    1.11 +
    1.12 +    // These are lazily initialized when delete is invoked on a mapped arg or an unmapped argument is set.
    1.13 +    private ArrayData unmappedArgs;
    1.14      private BitSet deleted;
    1.15  
    1.16      NativeArguments(final Object[] arguments, final Object callee, final int numParams, final ScriptObject proto, final PropertyMap map) {
    1.17          super(proto, map);
    1.18          setIsArguments();
    1.19 -
    1.20          setArray(ArrayData.allocate(arguments));
    1.21          this.length = arguments.length;
    1.22          this.callee = callee;
    1.23 -
    1.24 -        /**
    1.25 -         * Declared number of parameters may be more or less than the actual passed
    1.26 -         * runtime arguments count. We need to truncate or extend with undefined values.
    1.27 -         *
    1.28 -         * Example:
    1.29 -         *
    1.30 -         * // less declared params
    1.31 -         * (function (x) { print(arguments); })(20, 44);
    1.32 -         *
    1.33 -         * // more declared params
    1.34 -         * (function (x, y) { print(arguments); })(3);
    1.35 -         */
    1.36 -        final Object[] newValues = new Object[numParams];
    1.37 -        if (numParams > arguments.length) {
    1.38 -            Arrays.fill(newValues, UNDEFINED);
    1.39 -        }
    1.40 -        System.arraycopy(arguments, 0, newValues, 0, Math.min(newValues.length, arguments.length));
    1.41 -        this.namedArgs = ArrayData.allocate(newValues);
    1.42 +        this.numMapped = Math.min(numParams, arguments.length);
    1.43 +        this.numParams = numParams;
    1.44      }
    1.45  
    1.46      @Override
    1.47 @@ -118,7 +103,8 @@
    1.48       */
    1.49      @Override
    1.50      public Object getArgument(final int key) {
    1.51 -        return namedArgs.has(key) ? namedArgs.getObject(key) : UNDEFINED;
    1.52 +        assert key >= 0 && key < numParams : "invalid argument index";
    1.53 +        return isMapped(key) ? getArray().getObject(key) : getUnmappedArg(key);
    1.54      }
    1.55  
    1.56      /**
    1.57 @@ -126,353 +112,36 @@
    1.58       */
    1.59      @Override
    1.60      public void setArgument(final int key, final Object value) {
    1.61 -        if (namedArgs.has(key)) {
    1.62 -            namedArgs = namedArgs.set(key, value, false);
    1.63 +        assert key >= 0 && key < numParams : "invalid argument index";
    1.64 +        if (isMapped(key)) {
    1.65 +            setArray(getArray().set(key, value, false));
    1.66 +        } else {
    1.67 +            setUnmappedArg(key, value);
    1.68          }
    1.69      }
    1.70  
    1.71      @Override
    1.72 -    public int getInt(final Object key) {
    1.73 -        final int index = ArrayIndex.getArrayIndex(key);
    1.74 -        return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
    1.75 -    }
    1.76 -
    1.77 -    @Override
    1.78 -    public int getInt(final double key) {
    1.79 -        final int index = ArrayIndex.getArrayIndex(key);
    1.80 -        return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
    1.81 -    }
    1.82 -
    1.83 -    @Override
    1.84 -    public int getInt(final long key) {
    1.85 -        final int index = ArrayIndex.getArrayIndex(key);
    1.86 -        return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
    1.87 -    }
    1.88 -
    1.89 -    @Override
    1.90 -    public int getInt(final int key) {
    1.91 -        final int index = ArrayIndex.getArrayIndex(key);
    1.92 -        return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
    1.93 -    }
    1.94 -
    1.95 -    @Override
    1.96 -    public long getLong(final Object key) {
    1.97 -        final int index = ArrayIndex.getArrayIndex(key);
    1.98 -        return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
    1.99 -    }
   1.100 -
   1.101 -    @Override
   1.102 -    public long getLong(final double key) {
   1.103 -        final int index = ArrayIndex.getArrayIndex(key);
   1.104 -        return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
   1.105 -    }
   1.106 -
   1.107 -    @Override
   1.108 -    public long getLong(final long key) {
   1.109 -        final int index = ArrayIndex.getArrayIndex(key);
   1.110 -        return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
   1.111 -    }
   1.112 -
   1.113 -    @Override
   1.114 -    public long getLong(final int key) {
   1.115 -        final int index = ArrayIndex.getArrayIndex(key);
   1.116 -        return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
   1.117 -    }
   1.118 -
   1.119 -    @Override
   1.120 -    public double getDouble(final Object key) {
   1.121 -        final int index = ArrayIndex.getArrayIndex(key);
   1.122 -        return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
   1.123 -    }
   1.124 -
   1.125 -    @Override
   1.126 -    public double getDouble(final double key) {
   1.127 -        final int index = ArrayIndex.getArrayIndex(key);
   1.128 -        return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
   1.129 -    }
   1.130 -
   1.131 -    @Override
   1.132 -    public double getDouble(final long key) {
   1.133 -        final int index = ArrayIndex.getArrayIndex(key);
   1.134 -        return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
   1.135 -    }
   1.136 -
   1.137 -    @Override
   1.138 -    public double getDouble(final int key) {
   1.139 -        final int index = ArrayIndex.getArrayIndex(key);
   1.140 -        return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
   1.141 -    }
   1.142 -
   1.143 -    @Override
   1.144 -    public Object get(final Object key) {
   1.145 -        final int index = ArrayIndex.getArrayIndex(key);
   1.146 -        return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
   1.147 -    }
   1.148 -
   1.149 -    @Override
   1.150 -    public Object get(final double key) {
   1.151 -        final int index = ArrayIndex.getArrayIndex(key);
   1.152 -        return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
   1.153 -    }
   1.154 -
   1.155 -    @Override
   1.156 -    public Object get(final long key) {
   1.157 -        final int index = ArrayIndex.getArrayIndex(key);
   1.158 -        return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
   1.159 -    }
   1.160 -
   1.161 -    @Override
   1.162 -    public Object get(final int key) {
   1.163 -        final int index = ArrayIndex.getArrayIndex(key);
   1.164 -        return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
   1.165 -    }
   1.166 -
   1.167 -    @Override
   1.168 -    public void set(final Object key, final int value, final boolean strict) {
   1.169 -        final int index = ArrayIndex.getArrayIndex(key);
   1.170 -        if (isMapped(index)) {
   1.171 -            namedArgs = namedArgs.set(index, value, strict);
   1.172 -        } else {
   1.173 -            super.set(key, value, strict);
   1.174 -        }
   1.175 -    }
   1.176 -
   1.177 -    @Override
   1.178 -    public void set(final Object key, final long value, final boolean strict) {
   1.179 -        final int index = ArrayIndex.getArrayIndex(key);
   1.180 -        if (isMapped(index)) {
   1.181 -            namedArgs = namedArgs.set(index, value, strict);
   1.182 -        } else {
   1.183 -            super.set(key, value, strict);
   1.184 -        }
   1.185 -    }
   1.186 -
   1.187 -    @Override
   1.188 -    public void set(final Object key, final double value, final boolean strict) {
   1.189 -        final int index = ArrayIndex.getArrayIndex(key);
   1.190 -        if (isMapped(index)) {
   1.191 -            namedArgs = namedArgs.set(index, value, strict);
   1.192 -        } else {
   1.193 -            super.set(key, value, strict);
   1.194 -        }
   1.195 -    }
   1.196 -
   1.197 -    @Override
   1.198 -    public void set(final Object key, final Object value, final boolean strict) {
   1.199 -        final int index = ArrayIndex.getArrayIndex(key);
   1.200 -        if (isMapped(index)) {
   1.201 -            namedArgs = namedArgs.set(index, value, strict);
   1.202 -        } else {
   1.203 -            super.set(key, value, strict);
   1.204 -        }
   1.205 -    }
   1.206 -
   1.207 -    @Override
   1.208 -    public void set(final double key, final int value, final boolean strict) {
   1.209 -        final int index = ArrayIndex.getArrayIndex(key);
   1.210 -        if (isMapped(index)) {
   1.211 -            namedArgs = namedArgs.set(index, value, strict);
   1.212 -        } else {
   1.213 -            super.set(key, value, strict);
   1.214 -        }
   1.215 -    }
   1.216 -
   1.217 -    @Override
   1.218 -    public void set(final double key, final long value, final boolean strict) {
   1.219 -        final int index = ArrayIndex.getArrayIndex(key);
   1.220 -        if (isMapped(index)) {
   1.221 -            namedArgs = namedArgs.set(index, value, strict);
   1.222 -        } else {
   1.223 -            super.set(key, value, strict);
   1.224 -        }
   1.225 -    }
   1.226 -
   1.227 -    @Override
   1.228 -    public void set(final double key, final double value, final boolean strict) {
   1.229 -        final int index = ArrayIndex.getArrayIndex(key);
   1.230 -        if (isMapped(index)) {
   1.231 -            namedArgs = namedArgs.set(index, value, strict);
   1.232 -        } else {
   1.233 -            super.set(key, value, strict);
   1.234 -        }
   1.235 -    }
   1.236 -
   1.237 -    @Override
   1.238 -    public void set(final double key, final Object value, final boolean strict) {
   1.239 -        final int index = ArrayIndex.getArrayIndex(key);
   1.240 -        if (isMapped(index)) {
   1.241 -            namedArgs = namedArgs.set(index, value, strict);
   1.242 -        } else {
   1.243 -            super.set(key, value, strict);
   1.244 -        }
   1.245 -    }
   1.246 -
   1.247 -    @Override
   1.248 -    public void set(final long key, final int value, final boolean strict) {
   1.249 -        final int index = ArrayIndex.getArrayIndex(key);
   1.250 -        if (isMapped(index)) {
   1.251 -            namedArgs = namedArgs.set(index, value, strict);
   1.252 -        } else {
   1.253 -            super.set(key, value, strict);
   1.254 -        }
   1.255 -    }
   1.256 -
   1.257 -    @Override
   1.258 -    public void set(final long key, final long value, final boolean strict) {
   1.259 -        final int index = ArrayIndex.getArrayIndex(key);
   1.260 -        if (isMapped(index)) {
   1.261 -            namedArgs = namedArgs.set(index, value, strict);
   1.262 -        } else {
   1.263 -            super.set(key, value, strict);
   1.264 -        }
   1.265 -    }
   1.266 -
   1.267 -    @Override
   1.268 -    public void set(final long key, final double value, final boolean strict) {
   1.269 -        final int index = ArrayIndex.getArrayIndex(key);
   1.270 -        if (isMapped(index)) {
   1.271 -            namedArgs = namedArgs.set(index, value, strict);
   1.272 -        } else {
   1.273 -            super.set(key, value, strict);
   1.274 -        }
   1.275 -    }
   1.276 -
   1.277 -    @Override
   1.278 -    public void set(final long key, final Object value, final boolean strict) {
   1.279 -        final int index = ArrayIndex.getArrayIndex(key);
   1.280 -        if (isMapped(index)) {
   1.281 -            namedArgs = namedArgs.set(index, value, strict);
   1.282 -        } else {
   1.283 -            super.set(key, value, strict);
   1.284 -        }
   1.285 -    }
   1.286 -
   1.287 -    @Override
   1.288 -    public void set(final int key, final int value, final boolean strict) {
   1.289 -        final int index = ArrayIndex.getArrayIndex(key);
   1.290 -        if (isMapped(index)) {
   1.291 -            namedArgs = namedArgs.set(index, value, strict);
   1.292 -        } else {
   1.293 -            super.set(key, value, strict);
   1.294 -        }
   1.295 -    }
   1.296 -
   1.297 -    @Override
   1.298 -    public void set(final int key, final long value, final boolean strict) {
   1.299 -        final int index = ArrayIndex.getArrayIndex(key);
   1.300 -        if (isMapped(index)) {
   1.301 -            namedArgs = namedArgs.set(index, value, strict);
   1.302 -        } else {
   1.303 -            super.set(key, value, strict);
   1.304 -        }
   1.305 -    }
   1.306 -
   1.307 -    @Override
   1.308 -    public void set(final int key, final double value, final boolean strict) {
   1.309 -        final int index = ArrayIndex.getArrayIndex(key);
   1.310 -        if (isMapped(index)) {
   1.311 -            namedArgs = namedArgs.set(index, value, strict);
   1.312 -        } else {
   1.313 -            super.set(key, value, strict);
   1.314 -        }
   1.315 -    }
   1.316 -
   1.317 -    @Override
   1.318 -    public void set(final int key, final Object value, final boolean strict) {
   1.319 -        final int index = ArrayIndex.getArrayIndex(key);
   1.320 -        if (isMapped(index)) {
   1.321 -            namedArgs = namedArgs.set(index, value, strict);
   1.322 -        } else {
   1.323 -            super.set(key, value, strict);
   1.324 -        }
   1.325 -    }
   1.326 -
   1.327 -    @Override
   1.328 -    public boolean has(final Object key) {
   1.329 -        final int index = ArrayIndex.getArrayIndex(key);
   1.330 -        return isMapped(index) || super.has(key);
   1.331 -    }
   1.332 -
   1.333 -    @Override
   1.334 -    public boolean has(final double key) {
   1.335 -        final int index = ArrayIndex.getArrayIndex(key);
   1.336 -        return isMapped(index) || super.has(key);
   1.337 -    }
   1.338 -
   1.339 -    @Override
   1.340 -    public boolean has(final long key) {
   1.341 -        final int index = ArrayIndex.getArrayIndex(key);
   1.342 -        return isMapped(index) || super.has(key);
   1.343 -    }
   1.344 -
   1.345 -    @Override
   1.346 -    public boolean has(final int key) {
   1.347 -        final int index = ArrayIndex.getArrayIndex(key);
   1.348 -        return isMapped(index) || super.has(key);
   1.349 -    }
   1.350 -
   1.351 -    @Override
   1.352 -    public boolean hasOwnProperty(final Object key) {
   1.353 -        final int index = ArrayIndex.getArrayIndex(key);
   1.354 -        return isMapped(index) || super.hasOwnProperty(key);
   1.355 -    }
   1.356 -
   1.357 -    @Override
   1.358 -    public boolean hasOwnProperty(final int key) {
   1.359 -        final int index = ArrayIndex.getArrayIndex(key);
   1.360 -        return isMapped(index) || super.hasOwnProperty(key);
   1.361 -    }
   1.362 -
   1.363 -    @Override
   1.364 -    public boolean hasOwnProperty(final long key) {
   1.365 -        final int index = ArrayIndex.getArrayIndex(key);
   1.366 -        return isMapped(index) || super.hasOwnProperty(key);
   1.367 -    }
   1.368 -
   1.369 -    @Override
   1.370 -    public boolean hasOwnProperty(final double key) {
   1.371 -        final int index = ArrayIndex.getArrayIndex(key);
   1.372 -        return isMapped(index) || super.hasOwnProperty(key);
   1.373 -    }
   1.374 -
   1.375 -    @Override
   1.376      public boolean delete(final int key, final boolean strict) {
   1.377          final int index = ArrayIndex.getArrayIndex(key);
   1.378 -        final boolean success = super.delete(key, strict);
   1.379 -        if (success && namedArgs.has(index)) {
   1.380 -            setDeleted(index);
   1.381 -        }
   1.382 -        return success;
   1.383 +        return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
   1.384      }
   1.385  
   1.386      @Override
   1.387      public boolean delete(final long key, final boolean strict) {
   1.388          final int index = ArrayIndex.getArrayIndex(key);
   1.389 -        final boolean success = super.delete(key, strict);
   1.390 -        if (success && namedArgs.has(index)) {
   1.391 -            setDeleted(index);
   1.392 -        }
   1.393 -        return success;
   1.394 +        return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
   1.395      }
   1.396  
   1.397      @Override
   1.398      public boolean delete(final double key, final boolean strict) {
   1.399          final int index = ArrayIndex.getArrayIndex(key);
   1.400 -        final boolean success = super.delete(key, strict);
   1.401 -        if (success && namedArgs.has(index)) {
   1.402 -            setDeleted(index);
   1.403 -        }
   1.404 -        return success;
   1.405 +        return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
   1.406      }
   1.407  
   1.408      @Override
   1.409      public boolean delete(final Object key, final boolean strict) {
   1.410          final int index = ArrayIndex.getArrayIndex(key);
   1.411 -        final boolean success = super.delete(key, strict);
   1.412 -        if (success && namedArgs.has(index)) {
   1.413 -            setDeleted(index);
   1.414 -        }
   1.415 -        return success;
   1.416 +        return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
   1.417      }
   1.418  
   1.419      /**
   1.420 @@ -483,29 +152,27 @@
   1.421      public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
   1.422          final int index = ArrayIndex.getArrayIndex(key);
   1.423          if (index >= 0) {
   1.424 -            final boolean allowed = super.defineOwnProperty(key, propertyDesc, false);
   1.425 -            if (!allowed) {
   1.426 +            final boolean isMapped = isMapped(index);
   1.427 +            final Object oldValue = isMapped ? getArray().getObject(index) : null;
   1.428 +
   1.429 +            if (!super.defineOwnProperty(key, propertyDesc, false)) {
   1.430                  if (reject) {
   1.431                      throw typeError("cant.redefine.property",  key, ScriptRuntime.safeToString(this));
   1.432                  }
   1.433                  return false;
   1.434              }
   1.435  
   1.436 -            if (isMapped(index)) {
   1.437 +            if (isMapped) {
   1.438                  // When mapped argument is redefined, if new descriptor is accessor property
   1.439                  // or data-non-writable property, we have to "unmap" (unlink).
   1.440                  final PropertyDescriptor desc = toPropertyDescriptor(Global.instance(), propertyDesc);
   1.441                  if (desc.type() == PropertyDescriptor.ACCESSOR) {
   1.442 -                    setDeleted(index);
   1.443 -                } else {
   1.444 -                    // set "value" from new descriptor to named args
   1.445 -                    if (desc.has(PropertyDescriptor.VALUE)) {
   1.446 -                        namedArgs = namedArgs.set(index, desc.getValue(), false);
   1.447 -                    }
   1.448 -
   1.449 -                    if (desc.has(PropertyDescriptor.WRITABLE) && !desc.isWritable()) {
   1.450 -                        setDeleted(index);
   1.451 -                    }
   1.452 +                    setDeleted(index, oldValue);
   1.453 +                } else if (desc.has(PropertyDescriptor.WRITABLE) && !desc.isWritable()) {
   1.454 +                    // delete and set value from new descriptor if it has one, otherwise use old value
   1.455 +                    setDeleted(index, desc.has(PropertyDescriptor.VALUE) ? desc.getValue() : oldValue);
   1.456 +                } else if (desc.has(PropertyDescriptor.VALUE)) {
   1.457 +                    setArray(getArray().set(index, desc.getValue(), false));
   1.458                  }
   1.459              }
   1.460  
   1.461 @@ -519,31 +186,72 @@
   1.462  
   1.463      // We track deletions using a bit set (delete arguments[index])
   1.464      private boolean isDeleted(final int index) {
   1.465 -        return (deleted != null) ? deleted.get(index) : false;
   1.466 +        return deleted != null && deleted.get(index);
   1.467      }
   1.468  
   1.469 -    private void setDeleted(final int index) {
   1.470 +    private void setDeleted(final int index, final Object unmappedValue) {
   1.471          if (deleted == null) {
   1.472 -            deleted = new BitSet((int)namedArgs.length());
   1.473 +            deleted = new BitSet(numMapped);
   1.474          }
   1.475          deleted.set(index, true);
   1.476 +        setUnmappedArg(index, unmappedValue);
   1.477 +    }
   1.478 +
   1.479 +    private boolean deleteMapped(final int index, final boolean strict) {
   1.480 +        final Object value = getArray().getObject(index);
   1.481 +        final boolean success = super.delete(index, strict);
   1.482 +        if (success) {
   1.483 +            setDeleted(index, value);
   1.484 +        }
   1.485 +        return success;
   1.486 +    }
   1.487 +
   1.488 +    private Object getUnmappedArg(final int key) {
   1.489 +        assert key >= 0 && key < numParams;
   1.490 +        return unmappedArgs == null ? UNDEFINED : unmappedArgs.getObject(key);
   1.491 +    }
   1.492 +
   1.493 +    private void setUnmappedArg(final int key, final Object value) {
   1.494 +        assert key >= 0 && key < numParams;
   1.495 +        if (unmappedArgs == null) {
   1.496 +            /*
   1.497 +             * Declared number of parameters may be more or less than the actual passed
   1.498 +             * runtime arguments count. We need to truncate or extend with undefined values.
   1.499 +             *
   1.500 +             * Example:
   1.501 +             *
   1.502 +             * // less declared params
   1.503 +             * (function (x) { print(arguments); })(20, 44);
   1.504 +             *
   1.505 +             * // more declared params
   1.506 +             * (function (x, y) { print(arguments); })(3);
   1.507 +             */
   1.508 +            final Object[] newValues = new Object[numParams];
   1.509 +            System.arraycopy(getArray().asObjectArray(), 0, newValues, 0, numMapped);
   1.510 +            if (numMapped < numParams) {
   1.511 +                Arrays.fill(newValues, numMapped, numParams, UNDEFINED);
   1.512 +            }
   1.513 +            this.unmappedArgs = ArrayData.allocate(newValues);
   1.514 +        }
   1.515 +        // Set value of argument
   1.516 +        unmappedArgs = unmappedArgs.set(key, value, false);
   1.517      }
   1.518  
   1.519      /**
   1.520       * Are arguments[index] and corresponding named parameter linked?
   1.521       *
   1.522 -     * In non-strict mode, arguments[index] and corresponding named param
   1.523 -     * are "linked" or "mapped". Modifications are tacked b/w each other - till
   1.524 -     * (delete arguments[index]) is used. Once deleted, the corresponding arg
   1.525 -     * is no longer 'mapped'. Please note that delete can happen only through
   1.526 -     * the arguments array - named param can not be deleted. (delete is one-way).
   1.527 +     * In non-strict mode, arguments[index] and corresponding named param are "linked" or "mapped"
   1.528 +     * if the argument is provided by the caller. Modifications are tacked b/w each other - until
   1.529 +     * (delete arguments[index]) is used. Once deleted, the corresponding arg is no longer 'mapped'.
   1.530 +     * Please note that delete can happen only through the arguments array - named param can not
   1.531 +     * be deleted. (delete is one-way).
   1.532       */
   1.533      private boolean isMapped(final int index) {
   1.534 -        // in named args and not marked as "deleted"
   1.535 -        return namedArgs.has(index) && !isDeleted(index);
   1.536 +        // in mapped named args and not marked as "deleted"
   1.537 +        return index >= 0 && index < numMapped && !isDeleted(index);
   1.538      }
   1.539  
   1.540 -        /**
   1.541 +    /**
   1.542       * Factory to create correct Arguments object based on strict mode.
   1.543       *
   1.544       * @param arguments the actual arguments array passed
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/test/script/basic/JDK-8022731.js	Mon Aug 12 13:31:43 2013 +0200
     2.3 @@ -0,0 +1,93 @@
     2.4 +/*
     2.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + * 
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.
    2.11 + * 
    2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.15 + * version 2 for more details (a copy is included in the LICENSE file that
    2.16 + * accompanied this code).
    2.17 + * 
    2.18 + * You should have received a copy of the GNU General Public License version
    2.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.21 + * 
    2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.23 + * or visit www.oracle.com if you need additional information or have any
    2.24 + * questions.
    2.25 + */
    2.26 +
    2.27 +/**
    2.28 + * JDK-8022731: NativeArguments has wrong implementation of isMapped()
    2.29 + *
    2.30 + * @test
    2.31 + * @run
    2.32 + */
    2.33 +
    2.34 +Object.defineProperty(Object.prototype, "0", {value: "proto"});
    2.35 +
    2.36 +function test0(a, b) {
    2.37 +    Object.defineProperty(arguments, "1", {get: function() { return "get" }});
    2.38 +    return arguments[0];
    2.39 +}
    2.40 +
    2.41 +function test1(a, b) {
    2.42 +    Object.defineProperty(arguments, "0", {get: function() { return "get" }});
    2.43 +    return a;
    2.44 +}
    2.45 +
    2.46 +function test2(a, b) {
    2.47 +    Object.defineProperty(arguments, "0", {value: "value"});
    2.48 +    delete arguments[0];
    2.49 +    return a;
    2.50 +}
    2.51 +
    2.52 +function test3(a, b) {
    2.53 +    arguments[1] = "arg1";
    2.54 +    return b;
    2.55 +}
    2.56 +
    2.57 +function test4(a, b) {
    2.58 +    b = "b";
    2.59 +    return arguments[1];
    2.60 +}
    2.61 +
    2.62 +function test5(a, b) {
    2.63 +    Object.defineProperty(arguments, "0", {value: "value"});
    2.64 +    arguments[0] = "new";
    2.65 +    return a;
    2.66 +}
    2.67 +
    2.68 +function test6(a, b) {
    2.69 +    Object.defineProperty(arguments, "0", {value: "value"});
    2.70 +    arguments[0] = "new";
    2.71 +    delete arguments[0];
    2.72 +    return a;
    2.73 +}
    2.74 +
    2.75 +function test7(a, b) {
    2.76 +    Object.defineProperty(arguments, "0", {value: "value", writable: false});
    2.77 +    arguments[0] = "new";
    2.78 +    return a;
    2.79 +}
    2.80 +
    2.81 +print(test0());
    2.82 +print(test0("p1", "p2"));
    2.83 +print(test1());
    2.84 +print(test1("p1"));
    2.85 +print(test2());
    2.86 +print(test2("p1"));
    2.87 +print(test3());
    2.88 +print(test3(1, 2));
    2.89 +print(test4());
    2.90 +print(test4("p1", "p2"));
    2.91 +print(test5());
    2.92 +print(test5("p1"));
    2.93 +print(test6());
    2.94 +print(test6("p1"));
    2.95 +print(test7());
    2.96 +print(test7("p1"));
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/script/basic/JDK-8022731.js.EXPECTED	Mon Aug 12 13:31:43 2013 +0200
     3.3 @@ -0,0 +1,16 @@
     3.4 +proto
     3.5 +p1
     3.6 +undefined
     3.7 +p1
     3.8 +undefined
     3.9 +value
    3.10 +undefined
    3.11 +arg1
    3.12 +undefined
    3.13 +b
    3.14 +undefined
    3.15 +new
    3.16 +undefined
    3.17 +new
    3.18 +undefined
    3.19 +value

mercurial