From 1cff07e3713a0cb6b0b1b4a9c54d9d89eb1cdc06 Mon Sep 17 00:00:00 2001 From: jlaskey Date: Wed, 29 May 2013 16:23:50 -0300 Subject: 8015636: Add more typed arrays code coverage tests. Reviewed-by: sundar Contributed-by: james.laskey@oracle.com --- test/script/basic/typedarrays.js | 96 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 test/script/basic/typedarrays.js diff --git a/test/script/basic/typedarrays.js b/test/script/basic/typedarrays.js new file mode 100644 index 00000000..0854bea9 --- /dev/null +++ b/test/script/basic/typedarrays.js @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * typedarray test. + * + * @test + * @run + */ + + +var typeDefinitions = [ +Int8Array, +Uint8Array, +Uint8ClampedArray, +Int16Array, +Uint16Array, +Int32Array, +Uint32Array, +Float32Array, +Float64Array, +]; + +var mem1 = new ArrayBuffer(1024); +mem1.byteLength; +mem1.slice(512); +mem1.slice(512, 748); + +var size = 128; +var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; +var arr2 = [99, 89]; +var partial = []; +var all = []; + +typeDefinitions.forEach(function(arrayDef) { + var p = arrayDef.prototype; + var sub = []; + sub.push(new arrayDef(mem1, arrayDef.BYTES_PER_ELEMENT, 3)); + sub.push(new arrayDef(size)); + sub.push(new arrayDef(arr)); + //push the instances, they will be reused to do instance based construction + partial.push({ + instances:sub, + type:arrayDef + }); + + all.concat(all, sub); + +}); + +partial.forEach(function(inst) { + // build new instances with TypeArray instance as parameter. + partial.forEach(function(other) { + other.instances.forEach(function(otherInstance) { + var ii = new inst.type(otherInstance); + all.push(ii); + }); + }) +}); + +all.forEach(function(instance) { + // cover instance props and functions + var arr = Object.getOwnPropertyNames(instance); + arr.forEach(function(p) { + var val = instance[p]; + if(!isNaN(p)){ + val[p] = 99; + } + }); + + instance.set(instance, 0); + instance.set(instance); + instance.set(arr2); + instance.subarray(5, 9); + instance.subarray(5); +}); -- cgit v1.2.3 From 003501136a748b99c8dfb15834f99f9b2a317fab Mon Sep 17 00:00:00 2001 From: sundar Date: Thu, 30 May 2013 16:49:46 +0530 Subject: 8015353: Date.parse illegal string parsing issues Reviewed-by: jlaskey, lagergren --HG-- rename : src/jdk/nashorn/internal/objects/DateParser.java => src/jdk/nashorn/internal/parser/DateParser.java --- src/jdk/nashorn/internal/objects/DateParser.java | 706 ---------------------- src/jdk/nashorn/internal/objects/NativeDate.java | 1 + src/jdk/nashorn/internal/parser/DateParser.java | 716 +++++++++++++++++++++++ test/script/basic/JDK-8015353.js | 38 ++ 4 files changed, 755 insertions(+), 706 deletions(-) delete mode 100644 src/jdk/nashorn/internal/objects/DateParser.java create mode 100644 src/jdk/nashorn/internal/parser/DateParser.java create mode 100644 test/script/basic/JDK-8015353.js diff --git a/src/jdk/nashorn/internal/objects/DateParser.java b/src/jdk/nashorn/internal/objects/DateParser.java deleted file mode 100644 index b66d3dc9..00000000 --- a/src/jdk/nashorn/internal/objects/DateParser.java +++ /dev/null @@ -1,706 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.objects; - -import static java.lang.Character.DECIMAL_DIGIT_NUMBER; -import static java.lang.Character.LOWERCASE_LETTER; -import static java.lang.Character.OTHER_PUNCTUATION; -import static java.lang.Character.SPACE_SEPARATOR; -import static java.lang.Character.UPPERCASE_LETTER; - -import java.util.HashMap; -import java.util.Locale; - -/** - * JavaScript date parser. This class first tries to parse a date string - * according to the extended ISO 8601 format specified in ES5 15.9.1.15. - * If that fails, it falls back to legacy mode in which it accepts a range - * of different formats. - * - *

This class is neither thread-safe nor reusable. Calling the - * parse() method more than once will yield undefined results.

- */ -public class DateParser { - - /** Constant for index position of parsed year value. */ - public final static int YEAR = 0; - /** Constant for index position of parsed month value. */ - public final static int MONTH = 1; - /** Constant for index position of parsed day value. */ - public final static int DAY = 2; - /** Constant for index position of parsed hour value. */ - public final static int HOUR = 3; - /** Constant for index position of parsed minute value. */ - public final static int MINUTE = 4; - /** Constant for index position of parsed second value. */ - public final static int SECOND = 5; - /** Constant for index position of parsed millisecond value. */ - public final static int MILLISECOND = 6; - /** Constant for index position of parsed time zone offset value. */ - public final static int TIMEZONE = 7; - - private enum Token { - UNKNOWN, NUMBER, SEPARATOR, PARENTHESIS, NAME, SIGN, END - } - - private final String string; - private final int length; - private final Integer[] fields; - private int pos = 0; - private Token token; - private int tokenLength; - private Name nameValue; - private int numValue; - private int currentField = YEAR; - private int yearSign = 0; - private boolean namedMonth = false; - - private final static HashMap names = new HashMap<>(); - - static { - addName("monday", Name.DAY_OF_WEEK, 0); - addName("tuesday", Name.DAY_OF_WEEK, 0); - addName("wednesday", Name.DAY_OF_WEEK, 0); - addName("thursday", Name.DAY_OF_WEEK, 0); - addName("friday", Name.DAY_OF_WEEK, 0); - addName("saturday", Name.DAY_OF_WEEK, 0); - addName("sunday", Name.DAY_OF_WEEK, 0); - addName("january", Name.MONTH_NAME, 1); - addName("february", Name.MONTH_NAME, 2); - addName("march", Name.MONTH_NAME, 3); - addName("april", Name.MONTH_NAME, 4); - addName("may", Name.MONTH_NAME, 5); - addName("june", Name.MONTH_NAME, 6); - addName("july", Name.MONTH_NAME, 7); - addName("august", Name.MONTH_NAME, 8); - addName("september", Name.MONTH_NAME, 9); - addName("october", Name.MONTH_NAME, 10); - addName("november", Name.MONTH_NAME, 11); - addName("december", Name.MONTH_NAME, 12); - addName("am", Name.AM_PM, 0); - addName("pm", Name.AM_PM, 12); - addName("z", Name.TIMEZONE_ID, 0); - addName("gmt", Name.TIMEZONE_ID, 0); - addName("ut", Name.TIMEZONE_ID, 0); - addName("utc", Name.TIMEZONE_ID, 0); - addName("est", Name.TIMEZONE_ID, -5 * 60); - addName("edt", Name.TIMEZONE_ID, -4 * 60); - addName("cst", Name.TIMEZONE_ID, -6 * 60); - addName("cdt", Name.TIMEZONE_ID, -5 * 60); - addName("mst", Name.TIMEZONE_ID, -7 * 60); - addName("mdt", Name.TIMEZONE_ID, -6 * 60); - addName("pst", Name.TIMEZONE_ID, -8 * 60); - addName("pdt", Name.TIMEZONE_ID, -7 * 60); - addName("t", Name.TIME_SEPARATOR, 0); - } - - /** - * Construct a new DateParser instance for parsing the given string. - * @param string the string to be parsed - */ - public DateParser(final String string) { - this.string = string; - this.length = string.length(); - this.fields = new Integer[TIMEZONE + 1]; - } - - /** - * Try parsing the given string as date according to the extended ISO 8601 format - * specified in ES5 15.9.1.15. Fall back to legacy mode if that fails. - * This method returns true if the string could be parsed. - * @return true if the string could be parsed as date - */ - public boolean parse() { - return parseEcmaDate() || parseLegacyDate(); - } - - /** - * Try parsing the date string according to the rules laid out in ES5 15.9.1.15. - * The date string must conform to the following format: - * - *
  [('-'|'+')yy]yyyy[-MM[-dd]][hh:mm[:ss[.sss]][Z|(+|-)hh:mm]] 
- * - *

If the string does not contain a time zone offset, the TIMEZONE field - * is set to 0 (GMT).

- * @return true if string represents a valid ES5 date string. - */ - public boolean parseEcmaDate() { - - if (token == null) { - token = next(); - } - - while (token != Token.END) { - - switch (token) { - case NUMBER: - if (currentField == YEAR && yearSign != 0) { - // 15.9.1.15.1 Extended year must have six digits - if (tokenLength != 6) { - return false; - } - numValue *= yearSign; - } else if (!checkEcmaField(currentField, numValue)) { - return false; - } - if (!skipEcmaDelimiter()) { - return false; - } - if (currentField < TIMEZONE) { - set(currentField++, numValue); - } - break; - - case NAME: - if (nameValue == null) { - return false; - } - switch (nameValue.type) { - case Name.TIME_SEPARATOR: - if (currentField == YEAR || currentField > HOUR) { - return false; - } - currentField = HOUR; - break; - case Name.TIMEZONE_ID: - if (!nameValue.key.equals("z") || !setTimezone(nameValue.value, false)) { - return false; - } - break; - default: - return false; - } - break; - - case SIGN: - if (currentField == YEAR) { - yearSign = numValue; - } else if (currentField < SECOND || !setTimezone(readTimeZoneOffset(), true)) { - // Note: Spidermonkey won't parse timezone unless time includes seconds and milliseconds - return false; - } - break; - - default: - return false; - } - token = next(); - } - - return patchResult(true); - } - - /** - * Try parsing the date using a fuzzy algorithm that can handle a variety of formats. - * - *

Numbers separated by ':' are treated as time values, optionally followed by a - * millisecond value separated by '.'. Other number values are treated as date values. - * The exact sequence of day, month, and year values to apply is determined heuristically.

- * - *

English month names and selected time zone names as well as AM/PM markers are recognized - * and handled properly. Additionally, numeric time zone offsets such as (+|-)hh:mm or - * (+|-)hhmm are recognized. If the string does not contain a time zone offset - * the TIMEZONEfield is left undefined, meaning the local time zone should be applied.

- * - *

English weekday names are recognized but ignored. All text in parentheses is ignored as well. - * All other text causes parsing to fail.

- * - * @return true if the string could be parsed - */ - public boolean parseLegacyDate() { - - if (yearSign != 0 || currentField > DAY) { - // we don't support signed years in legacy mode - return false; - } - if (token == null) { - token = next(); - } - - while (token != Token.END) { - - switch (token) { - case NUMBER: - if (skip(':')) { - // A number followed by ':' is parsed as time - if (!setTimeField(numValue)) { - return false; - } - // consume remaining time tokens - do { - token = next(); - if (token != Token.NUMBER || !setTimeField(numValue)) { - return false; - } - } while (skip(isSet(SECOND) ? '.' : ':')); - - } else { - // Parse as date token - if (!setDateField(numValue)) { - return false; - } - skip('-'); - } - break; - - case NAME: - if (nameValue == null) { - return false; - } - switch (nameValue.type) { - case Name.AM_PM: - if (!setAmPm(nameValue.value)) { - return false; - } - break; - case Name.MONTH_NAME: - if (!setMonth(nameValue.value)) { - return false; - } - break; - case Name.TIMEZONE_ID: - if (!setTimezone(nameValue.value, false)) { - return false; - } - break; - case Name.TIME_SEPARATOR: - return false; - default: - break; - } - if (nameValue.type != Name.TIMEZONE_ID) { - skip('-'); - } - break; - - case SIGN: - if (!setTimezone(readTimeZoneOffset(), true)) { - return false; - } - break; - - case PARENTHESIS: - if (!skipParentheses()) { - return false; - } - break; - - case SEPARATOR: - break; - - default: - return false; - } - token = next(); - } - - return patchResult(false); - } - - /** - * Get the parsed date and time fields as an array of Integers. - * - *

If parsing was successful, all fields are guaranteed to be set except for the - * TIMEZONE field which may be null, meaning that local time zone - * offset should be applied.

- * - * @return the parsed date fields - */ - public Integer[] getDateFields() { - return fields; - } - - private boolean isSet(final int field) { - return fields[field] != null; - } - - private Integer get(final int field) { - return fields[field]; - } - - private void set(final int field, final int value) { - fields[field] = value; - } - - private int peek() { - return pos < length ? string.charAt(pos) : -1; - } - - private boolean skip(final char c) { - if (pos < length && string.charAt(pos) == c) { - token = null; - pos++; - return true; - } - return false; - } - - private Token next() { - if (pos >= length) { - tokenLength = 0; - return Token.END; - } - - final char c = string.charAt(pos); - - if (c > 0x80) { - tokenLength = 1; - pos++; - return Token.UNKNOWN; // We only deal with ASCII here - } - - final int type = Character.getType(c); - switch (type) { - case DECIMAL_DIGIT_NUMBER: - numValue = readNumber(6); - return Token.NUMBER; - case SPACE_SEPARATOR : - case OTHER_PUNCTUATION: - tokenLength = 1; - pos++; - return Token.SEPARATOR; - case UPPERCASE_LETTER: - case LOWERCASE_LETTER: - nameValue = readName(); - return Token.NAME; - default: - tokenLength = 1; - pos++; - switch (c) { - case '(': - return Token.PARENTHESIS; - case '-': - case '+': - numValue = c == '-' ? -1 : 1; - return Token.SIGN; - default: - return Token.UNKNOWN; - } - } - } - - private static boolean checkLegacyField(final int field, final int value) { - switch (field) { - case HOUR: - return isHour(value); - case MINUTE: - case SECOND: - return isMinuteOrSecond(value); - case MILLISECOND: - return isMillisecond(value); - default: - // skip validation on other legacy fields as we don't know what's what - return true; - } - } - - private boolean checkEcmaField(final int field, final int value) { - switch (field) { - case YEAR: - return tokenLength == 4; - case MONTH: - return tokenLength == 2 && isMonth(value); - case DAY: - return tokenLength == 2 && isDay(value); - case HOUR: - return tokenLength == 2 && isHour(value); - case MINUTE: - case SECOND: - return tokenLength == 2 && isMinuteOrSecond(value); - case MILLISECOND: - // we allow millisecond to be less than 3 digits - return tokenLength < 4 && isMillisecond(value); - default: - return true; - } - } - - private boolean skipEcmaDelimiter() { - switch (currentField) { - case YEAR: - case MONTH: - return skip('-') || peek() == 'T' || peek() == -1; - case DAY: - return peek() == 'T' || peek() == -1; - case HOUR: - case MINUTE: - return skip(':') || endOfTime(); - case SECOND: - return skip('.') || endOfTime(); - default: - return true; - } - } - - private boolean endOfTime() { - final int c = peek(); - return c == -1 || c == 'Z' || c == '-' || c == '+' || c == ' '; - } - - private static boolean isAsciiLetter(final char ch) { - return ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z'); - } - - private static boolean isAsciiDigit(final char ch) { - return '0' <= ch && ch <= '9'; - } - - private int readNumber(final int maxDigits) { - final int start = pos; - int n = 0; - final int max = Math.min(length, pos + maxDigits); - while (pos < max && isAsciiDigit(string.charAt(pos))) { - n = n * 10 + string.charAt(pos++) - '0'; - } - tokenLength = pos - start; - return n; - } - - private Name readName() { - final int start = pos; - final int limit = Math.min(pos + 3, length); - - // first read up to the key length - while (pos < limit && isAsciiLetter(string.charAt(pos))) { - pos++; - } - final String key = string.substring(start, pos).toLowerCase(Locale.ENGLISH); - final Name name = names.get(key); - // then advance to end of name - while (pos < length && isAsciiLetter(string.charAt(pos))) { - pos++; - } - - tokenLength = pos - start; - // make sure we have the full name or a prefix - if (name != null && name.matches(string, start, tokenLength)) { - return name; - } - return null; - } - - private int readTimeZoneOffset() { - final int sign = string.charAt(pos - 1) == '+' ? 1 : -1; - int offset = readNumber(2); - skip(':'); - offset = offset * 60 + readNumber(2); - return sign * offset; - } - - private boolean skipParentheses() { - int parenCount = 1; - while (pos < length && parenCount != 0) { - final char c = string.charAt(pos++); - if (c == '(') { - parenCount++; - } else if (c == ')') { - parenCount--; - } - } - return true; - } - - private static int getDefaultValue(final int field) { - switch (field) { - case MONTH: - case DAY: - return 1; - default: - return 0; - } - } - - private static boolean isDay(final int n) { - return 1 <= n && n <= 31; - } - - private static boolean isMonth(final int n) { - return 1 <= n && n <= 12; - } - - private static boolean isHour(final int n) { - return 0 <= n && n <= 24; - } - - private static boolean isMinuteOrSecond(final int n) { - return 0 <= n && n < 60; - } - - private static boolean isMillisecond(final int n) { - return 0<= n && n < 1000; - } - - private boolean setMonth(final int m) { - if (!isSet(MONTH)) { - namedMonth = true; - set(MONTH, m); - return true; - } - return false; - } - - private boolean setDateField(final int n) { - for (int field = YEAR; field != HOUR; field++) { - if (!isSet(field)) { - // no validation on legacy date fields - set(field, n); - return true; - } - } - return false; - } - - private boolean setTimeField(final int n) { - for (int field = HOUR; field != TIMEZONE; field++) { - if (!isSet(field)) { - if (checkLegacyField(field, n)) { - set(field, n); - return true; - } - return false; - } - } - return false; - } - - private boolean setTimezone(final int offset, final boolean asNumericOffset) { - if (!isSet(TIMEZONE) || (asNumericOffset && get(TIMEZONE) == 0)) { - set(TIMEZONE, offset); - return true; - } - return false; - } - - private boolean setAmPm(final int offset) { - if (!isSet(HOUR)) { - return false; - } - final int hour = get(HOUR); - if (hour >= 0 && hour <= 12) { - set(HOUR, hour + offset); - } - return true; - } - - private boolean patchResult(final boolean strict) { - // sanity checks - make sure we have something - if (!isSet(YEAR) && !isSet(HOUR)) { - return false; - } - if (isSet(HOUR) && !isSet(MINUTE)) { - return false; - } - // fill in default values for unset fields except timezone - for (int field = YEAR; field <= TIMEZONE; field++) { - if (get(field) == null) { - if (field == TIMEZONE && !strict) { - // We only use UTC as default timezone for dates parsed complying with - // the format specified in ES5 15.9.1.15. Otherwise the slot is left empty - // and local timezone is used. - continue; - } - final int value = getDefaultValue(field); - set(field, value); - } - } - - if (!strict) { - // swap year, month, and day if it looks like the right thing to do - if (isDay(get(YEAR))) { - final int d = get(YEAR); - set(YEAR, get(DAY)); - if (namedMonth) { - // d-m-y - set(DAY, d); - } else { - // m-d-y - final int d2 = get(MONTH); - set(MONTH, d); - set(DAY, d2); - } - } - // sanity checks now that we know what's what - if (!isMonth(get(MONTH)) || !isDay(get(DAY))) { - return false; - } - - // add 1900 or 2000 to year if it's between 0 and 100 - final int year = get(YEAR); - if (year >= 0 && year < 100) { - set(YEAR, year >= 50 ? 1900 + year : 2000 + year); - } - } else { - // 24 hour value is only allowed if all other time values are zero - if (get(HOUR) == 24 && - (get(MINUTE) != 0 || get(SECOND) != 0 || get(MILLISECOND) != 0)) { - return false; - } - } - - // set month to 0-based - set(MONTH, get(MONTH) - 1); - return true; - } - - private static void addName(final String str, final int type, final int value) { - final Name name = new Name(str, type, value); - names.put(name.key, name); - } - - private static class Name { - final String name; - final String key; - final int value; - final int type; - - final static int DAY_OF_WEEK = -1; - final static int MONTH_NAME = 0; - final static int AM_PM = 1; - final static int TIMEZONE_ID = 2; - final static int TIME_SEPARATOR = 3; - - Name(final String name, final int type, final int value) { - assert name != null; - assert name.equals(name.toLowerCase(Locale.ENGLISH)); - - this.name = name; - // use first three characters as lookup key - this.key = name.substring(0, Math.min(3, name.length())); - this.type = type; - this.value = value; - } - - public boolean matches(final String str, final int offset, final int len) { - return name.regionMatches(true, 0, str, offset, len); - } - - @Override - public String toString() { - return name; - } - } - -} diff --git a/src/jdk/nashorn/internal/objects/NativeDate.java b/src/jdk/nashorn/internal/objects/NativeDate.java index fa2c9d17..ef01d74b 100644 --- a/src/jdk/nashorn/internal/objects/NativeDate.java +++ b/src/jdk/nashorn/internal/objects/NativeDate.java @@ -39,6 +39,7 @@ import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.objects.annotations.SpecializedConstructor; import jdk.nashorn.internal.objects.annotations.Where; +import jdk.nashorn.internal.parser.DateParser; import jdk.nashorn.internal.runtime.ConsString; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptEnvironment; diff --git a/src/jdk/nashorn/internal/parser/DateParser.java b/src/jdk/nashorn/internal/parser/DateParser.java new file mode 100644 index 00000000..34832bb1 --- /dev/null +++ b/src/jdk/nashorn/internal/parser/DateParser.java @@ -0,0 +1,716 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.parser; + +import static java.lang.Character.DECIMAL_DIGIT_NUMBER; +import static java.lang.Character.LOWERCASE_LETTER; +import static java.lang.Character.OTHER_PUNCTUATION; +import static java.lang.Character.SPACE_SEPARATOR; +import static java.lang.Character.UPPERCASE_LETTER; + +import java.util.HashMap; +import java.util.Locale; + +/** + * JavaScript date parser. This class first tries to parse a date string + * according to the extended ISO 8601 format specified in ES5 15.9.1.15. + * If that fails, it falls back to legacy mode in which it accepts a range + * of different formats. + * + *

This class is neither thread-safe nor reusable. Calling the + * parse() method more than once will yield undefined results.

+ */ +public class DateParser { + + /** Constant for index position of parsed year value. */ + public final static int YEAR = 0; + /** Constant for index position of parsed month value. */ + public final static int MONTH = 1; + /** Constant for index position of parsed day value. */ + public final static int DAY = 2; + /** Constant for index position of parsed hour value. */ + public final static int HOUR = 3; + /** Constant for index position of parsed minute value. */ + public final static int MINUTE = 4; + /** Constant for index position of parsed second value. */ + public final static int SECOND = 5; + /** Constant for index position of parsed millisecond value. */ + public final static int MILLISECOND = 6; + /** Constant for index position of parsed time zone offset value. */ + public final static int TIMEZONE = 7; + + private enum Token { + UNKNOWN, NUMBER, SEPARATOR, PARENTHESIS, NAME, SIGN, END + } + + private final String string; + private final int length; + private final Integer[] fields; + private int pos = 0; + private Token token; + private int tokenLength; + private Name nameValue; + private int numValue; + private int currentField = YEAR; + private int yearSign = 0; + private boolean namedMonth = false; + + private final static HashMap names = new HashMap<>(); + + static { + addName("monday", Name.DAY_OF_WEEK, 0); + addName("tuesday", Name.DAY_OF_WEEK, 0); + addName("wednesday", Name.DAY_OF_WEEK, 0); + addName("thursday", Name.DAY_OF_WEEK, 0); + addName("friday", Name.DAY_OF_WEEK, 0); + addName("saturday", Name.DAY_OF_WEEK, 0); + addName("sunday", Name.DAY_OF_WEEK, 0); + addName("january", Name.MONTH_NAME, 1); + addName("february", Name.MONTH_NAME, 2); + addName("march", Name.MONTH_NAME, 3); + addName("april", Name.MONTH_NAME, 4); + addName("may", Name.MONTH_NAME, 5); + addName("june", Name.MONTH_NAME, 6); + addName("july", Name.MONTH_NAME, 7); + addName("august", Name.MONTH_NAME, 8); + addName("september", Name.MONTH_NAME, 9); + addName("october", Name.MONTH_NAME, 10); + addName("november", Name.MONTH_NAME, 11); + addName("december", Name.MONTH_NAME, 12); + addName("am", Name.AM_PM, 0); + addName("pm", Name.AM_PM, 12); + addName("z", Name.TIMEZONE_ID, 0); + addName("gmt", Name.TIMEZONE_ID, 0); + addName("ut", Name.TIMEZONE_ID, 0); + addName("utc", Name.TIMEZONE_ID, 0); + addName("est", Name.TIMEZONE_ID, -5 * 60); + addName("edt", Name.TIMEZONE_ID, -4 * 60); + addName("cst", Name.TIMEZONE_ID, -6 * 60); + addName("cdt", Name.TIMEZONE_ID, -5 * 60); + addName("mst", Name.TIMEZONE_ID, -7 * 60); + addName("mdt", Name.TIMEZONE_ID, -6 * 60); + addName("pst", Name.TIMEZONE_ID, -8 * 60); + addName("pdt", Name.TIMEZONE_ID, -7 * 60); + addName("t", Name.TIME_SEPARATOR, 0); + } + + /** + * Construct a new DateParser instance for parsing the given string. + * @param string the string to be parsed + */ + public DateParser(final String string) { + this.string = string; + this.length = string.length(); + this.fields = new Integer[TIMEZONE + 1]; + } + + /** + * Try parsing the given string as date according to the extended ISO 8601 format + * specified in ES5 15.9.1.15. Fall back to legacy mode if that fails. + * This method returns true if the string could be parsed. + * @return true if the string could be parsed as date + */ + public boolean parse() { + return parseEcmaDate() || parseLegacyDate(); + } + + /** + * Try parsing the date string according to the rules laid out in ES5 15.9.1.15. + * The date string must conform to the following format: + * + *
  [('-'|'+')yy]yyyy[-MM[-dd]][hh:mm[:ss[.sss]][Z|(+|-)hh:mm]] 
+ * + *

If the string does not contain a time zone offset, the TIMEZONE field + * is set to 0 (GMT).

+ * @return true if string represents a valid ES5 date string. + */ + public boolean parseEcmaDate() { + + if (token == null) { + token = next(); + } + + while (token != Token.END) { + + switch (token) { + case NUMBER: + if (currentField == YEAR && yearSign != 0) { + // 15.9.1.15.1 Extended year must have six digits + if (tokenLength != 6) { + return false; + } + numValue *= yearSign; + } else if (!checkEcmaField(currentField, numValue)) { + return false; + } + if (!skipEcmaDelimiter()) { + return false; + } + if (currentField < TIMEZONE) { + set(currentField++, numValue); + } + break; + + case NAME: + if (nameValue == null) { + return false; + } + switch (nameValue.type) { + case Name.TIME_SEPARATOR: + if (currentField == YEAR || currentField > HOUR) { + return false; + } + currentField = HOUR; + break; + case Name.TIMEZONE_ID: + if (!nameValue.key.equals("z") || !setTimezone(nameValue.value, false)) { + return false; + } + break; + default: + return false; + } + break; + + case SIGN: + if (peek() == -1) { + // END after sign - wrong! + return false; + } + + if (currentField == YEAR) { + yearSign = numValue; + } else if (currentField < SECOND || !setTimezone(readTimeZoneOffset(), true)) { + // Note: Spidermonkey won't parse timezone unless time includes seconds and milliseconds + return false; + } + break; + + default: + return false; + } + token = next(); + } + + return patchResult(true); + } + + /** + * Try parsing the date using a fuzzy algorithm that can handle a variety of formats. + * + *

Numbers separated by ':' are treated as time values, optionally followed by a + * millisecond value separated by '.'. Other number values are treated as date values. + * The exact sequence of day, month, and year values to apply is determined heuristically.

+ * + *

English month names and selected time zone names as well as AM/PM markers are recognized + * and handled properly. Additionally, numeric time zone offsets such as (+|-)hh:mm or + * (+|-)hhmm are recognized. If the string does not contain a time zone offset + * the TIMEZONEfield is left undefined, meaning the local time zone should be applied.

+ * + *

English weekday names are recognized but ignored. All text in parentheses is ignored as well. + * All other text causes parsing to fail.

+ * + * @return true if the string could be parsed + */ + public boolean parseLegacyDate() { + + if (yearSign != 0 || currentField > DAY) { + // we don't support signed years in legacy mode + return false; + } + if (token == null) { + token = next(); + } + + while (token != Token.END) { + + switch (token) { + case NUMBER: + if (skip(':')) { + // A number followed by ':' is parsed as time + if (!setTimeField(numValue)) { + return false; + } + // consume remaining time tokens + do { + token = next(); + if (token != Token.NUMBER || !setTimeField(numValue)) { + return false; + } + } while (skip(isSet(SECOND) ? '.' : ':')); + + } else { + // Parse as date token + if (!setDateField(numValue)) { + return false; + } + skip('-'); + } + break; + + case NAME: + if (nameValue == null) { + return false; + } + switch (nameValue.type) { + case Name.AM_PM: + if (!setAmPm(nameValue.value)) { + return false; + } + break; + case Name.MONTH_NAME: + if (!setMonth(nameValue.value)) { + return false; + } + break; + case Name.TIMEZONE_ID: + if (!setTimezone(nameValue.value, false)) { + return false; + } + break; + case Name.TIME_SEPARATOR: + return false; + default: + break; + } + if (nameValue.type != Name.TIMEZONE_ID) { + skip('-'); + } + break; + + case SIGN: + if (peek() == -1) { + // END after sign - wrong! + return false; + } + + if (!setTimezone(readTimeZoneOffset(), true)) { + return false; + } + break; + + case PARENTHESIS: + if (!skipParentheses()) { + return false; + } + break; + + case SEPARATOR: + break; + + default: + return false; + } + token = next(); + } + + return patchResult(false); + } + + /** + * Get the parsed date and time fields as an array of Integers. + * + *

If parsing was successful, all fields are guaranteed to be set except for the + * TIMEZONE field which may be null, meaning that local time zone + * offset should be applied.

+ * + * @return the parsed date fields + */ + public Integer[] getDateFields() { + return fields; + } + + private boolean isSet(final int field) { + return fields[field] != null; + } + + private Integer get(final int field) { + return fields[field]; + } + + private void set(final int field, final int value) { + fields[field] = value; + } + + private int peek() { + return pos < length ? string.charAt(pos) : -1; + } + + private boolean skip(final char c) { + if (pos < length && string.charAt(pos) == c) { + token = null; + pos++; + return true; + } + return false; + } + + private Token next() { + if (pos >= length) { + tokenLength = 0; + return Token.END; + } + + final char c = string.charAt(pos); + + if (c > 0x80) { + tokenLength = 1; + pos++; + return Token.UNKNOWN; // We only deal with ASCII here + } + + final int type = Character.getType(c); + switch (type) { + case DECIMAL_DIGIT_NUMBER: + numValue = readNumber(6); + return Token.NUMBER; + case SPACE_SEPARATOR : + case OTHER_PUNCTUATION: + tokenLength = 1; + pos++; + return Token.SEPARATOR; + case UPPERCASE_LETTER: + case LOWERCASE_LETTER: + nameValue = readName(); + return Token.NAME; + default: + tokenLength = 1; + pos++; + switch (c) { + case '(': + return Token.PARENTHESIS; + case '-': + case '+': + numValue = c == '-' ? -1 : 1; + return Token.SIGN; + default: + return Token.UNKNOWN; + } + } + } + + private static boolean checkLegacyField(final int field, final int value) { + switch (field) { + case HOUR: + return isHour(value); + case MINUTE: + case SECOND: + return isMinuteOrSecond(value); + case MILLISECOND: + return isMillisecond(value); + default: + // skip validation on other legacy fields as we don't know what's what + return true; + } + } + + private boolean checkEcmaField(final int field, final int value) { + switch (field) { + case YEAR: + return tokenLength == 4; + case MONTH: + return tokenLength == 2 && isMonth(value); + case DAY: + return tokenLength == 2 && isDay(value); + case HOUR: + return tokenLength == 2 && isHour(value); + case MINUTE: + case SECOND: + return tokenLength == 2 && isMinuteOrSecond(value); + case MILLISECOND: + // we allow millisecond to be less than 3 digits + return tokenLength < 4 && isMillisecond(value); + default: + return true; + } + } + + private boolean skipEcmaDelimiter() { + switch (currentField) { + case YEAR: + case MONTH: + return skip('-') || peek() == 'T' || peek() == -1; + case DAY: + return peek() == 'T' || peek() == -1; + case HOUR: + case MINUTE: + return skip(':') || endOfTime(); + case SECOND: + return skip('.') || endOfTime(); + default: + return true; + } + } + + private boolean endOfTime() { + final int c = peek(); + return c == -1 || c == 'Z' || c == '-' || c == '+' || c == ' '; + } + + private static boolean isAsciiLetter(final char ch) { + return ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z'); + } + + private static boolean isAsciiDigit(final char ch) { + return '0' <= ch && ch <= '9'; + } + + private int readNumber(final int maxDigits) { + final int start = pos; + int n = 0; + final int max = Math.min(length, pos + maxDigits); + while (pos < max && isAsciiDigit(string.charAt(pos))) { + n = n * 10 + string.charAt(pos++) - '0'; + } + tokenLength = pos - start; + return n; + } + + private Name readName() { + final int start = pos; + final int limit = Math.min(pos + 3, length); + + // first read up to the key length + while (pos < limit && isAsciiLetter(string.charAt(pos))) { + pos++; + } + final String key = string.substring(start, pos).toLowerCase(Locale.ENGLISH); + final Name name = names.get(key); + // then advance to end of name + while (pos < length && isAsciiLetter(string.charAt(pos))) { + pos++; + } + + tokenLength = pos - start; + // make sure we have the full name or a prefix + if (name != null && name.matches(string, start, tokenLength)) { + return name; + } + return null; + } + + private int readTimeZoneOffset() { + final int sign = string.charAt(pos - 1) == '+' ? 1 : -1; + int offset = readNumber(2); + skip(':'); + offset = offset * 60 + readNumber(2); + return sign * offset; + } + + private boolean skipParentheses() { + int parenCount = 1; + while (pos < length && parenCount != 0) { + final char c = string.charAt(pos++); + if (c == '(') { + parenCount++; + } else if (c == ')') { + parenCount--; + } + } + return true; + } + + private static int getDefaultValue(final int field) { + switch (field) { + case MONTH: + case DAY: + return 1; + default: + return 0; + } + } + + private static boolean isDay(final int n) { + return 1 <= n && n <= 31; + } + + private static boolean isMonth(final int n) { + return 1 <= n && n <= 12; + } + + private static boolean isHour(final int n) { + return 0 <= n && n <= 24; + } + + private static boolean isMinuteOrSecond(final int n) { + return 0 <= n && n < 60; + } + + private static boolean isMillisecond(final int n) { + return 0<= n && n < 1000; + } + + private boolean setMonth(final int m) { + if (!isSet(MONTH)) { + namedMonth = true; + set(MONTH, m); + return true; + } + return false; + } + + private boolean setDateField(final int n) { + for (int field = YEAR; field != HOUR; field++) { + if (!isSet(field)) { + // no validation on legacy date fields + set(field, n); + return true; + } + } + return false; + } + + private boolean setTimeField(final int n) { + for (int field = HOUR; field != TIMEZONE; field++) { + if (!isSet(field)) { + if (checkLegacyField(field, n)) { + set(field, n); + return true; + } + return false; + } + } + return false; + } + + private boolean setTimezone(final int offset, final boolean asNumericOffset) { + if (!isSet(TIMEZONE) || (asNumericOffset && get(TIMEZONE) == 0)) { + set(TIMEZONE, offset); + return true; + } + return false; + } + + private boolean setAmPm(final int offset) { + if (!isSet(HOUR)) { + return false; + } + final int hour = get(HOUR); + if (hour >= 0 && hour <= 12) { + set(HOUR, hour + offset); + } + return true; + } + + private boolean patchResult(final boolean strict) { + // sanity checks - make sure we have something + if (!isSet(YEAR) && !isSet(HOUR)) { + return false; + } + if (isSet(HOUR) && !isSet(MINUTE)) { + return false; + } + // fill in default values for unset fields except timezone + for (int field = YEAR; field <= TIMEZONE; field++) { + if (get(field) == null) { + if (field == TIMEZONE && !strict) { + // We only use UTC as default timezone for dates parsed complying with + // the format specified in ES5 15.9.1.15. Otherwise the slot is left empty + // and local timezone is used. + continue; + } + final int value = getDefaultValue(field); + set(field, value); + } + } + + if (!strict) { + // swap year, month, and day if it looks like the right thing to do + if (isDay(get(YEAR))) { + final int d = get(YEAR); + set(YEAR, get(DAY)); + if (namedMonth) { + // d-m-y + set(DAY, d); + } else { + // m-d-y + final int d2 = get(MONTH); + set(MONTH, d); + set(DAY, d2); + } + } + // sanity checks now that we know what's what + if (!isMonth(get(MONTH)) || !isDay(get(DAY))) { + return false; + } + + // add 1900 or 2000 to year if it's between 0 and 100 + final int year = get(YEAR); + if (year >= 0 && year < 100) { + set(YEAR, year >= 50 ? 1900 + year : 2000 + year); + } + } else { + // 24 hour value is only allowed if all other time values are zero + if (get(HOUR) == 24 && + (get(MINUTE) != 0 || get(SECOND) != 0 || get(MILLISECOND) != 0)) { + return false; + } + } + + // set month to 0-based + set(MONTH, get(MONTH) - 1); + return true; + } + + private static void addName(final String str, final int type, final int value) { + final Name name = new Name(str, type, value); + names.put(name.key, name); + } + + private static class Name { + final String name; + final String key; + final int value; + final int type; + + final static int DAY_OF_WEEK = -1; + final static int MONTH_NAME = 0; + final static int AM_PM = 1; + final static int TIMEZONE_ID = 2; + final static int TIME_SEPARATOR = 3; + + Name(final String name, final int type, final int value) { + assert name != null; + assert name.equals(name.toLowerCase(Locale.ENGLISH)); + + this.name = name; + // use first three characters as lookup key + this.key = name.substring(0, Math.min(3, name.length())); + this.type = type; + this.value = value; + } + + public boolean matches(final String str, final int offset, final int len) { + return name.regionMatches(true, 0, str, offset, len); + } + + @Override + public String toString() { + return name; + } + } + +} diff --git a/test/script/basic/JDK-8015353.js b/test/script/basic/JDK-8015353.js new file mode 100644 index 00000000..a9baa469 --- /dev/null +++ b/test/script/basic/JDK-8015353.js @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8015353: Date.parse illegal string parsing issues + * + * @test + * @run + */ + +function checkDate(str) { + if (! isNaN(Date.parse(str))) { + fail(str + " is parsed as legal Date"); + } +} + +checkDate("2012-01-10T00:00:00.000-"); +checkDate("2012-01-01T00:00+"); -- cgit v1.2.3 From c4864e6708cfac48a25fa4122e9b75178f7aa3bf Mon Sep 17 00:00:00 2001 From: attila Date: Fri, 31 May 2013 12:56:56 +0200 Subject: 8015693: reduce NodeLiteralNode to NullLiteralNode Reviewed-by: jlaskey, lagergren --- src/jdk/nashorn/internal/ir/LiteralNode.java | 62 ++++------------------------ 1 file changed, 9 insertions(+), 53 deletions(-) diff --git a/src/jdk/nashorn/internal/ir/LiteralNode.java b/src/jdk/nashorn/internal/ir/LiteralNode.java index 7a59c5fe..c34f9d94 100644 --- a/src/jdk/nashorn/internal/ir/LiteralNode.java +++ b/src/jdk/nashorn/internal/ir/LiteralNode.java @@ -28,7 +28,6 @@ package jdk.nashorn.internal.ir; import java.util.Arrays; import java.util.Collections; import java.util.List; - import jdk.nashorn.internal.codegen.CompileUnit; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; @@ -242,8 +241,8 @@ public abstract class LiteralNode extends Node implements PropertyKey { * * @return the new literal node */ - public static LiteralNode newInstance(final long token, final int finish) { - return new NodeLiteralNode(token, finish); + public static LiteralNode newInstance(final long token, final int finish) { + return new NullLiteralNode(token, finish); } /** @@ -253,8 +252,8 @@ public abstract class LiteralNode extends Node implements PropertyKey { * * @return the new literal node */ - public static LiteralNode newInstance(final Node parent) { - return new NodeLiteralNode(parent.getToken(), parent.getFinish()); + public static LiteralNode newInstance(final Node parent) { + return new NullLiteralNode(parent.getToken(), parent.getFinish()); } @Immutable @@ -496,33 +495,15 @@ public abstract class LiteralNode extends Node implements PropertyKey { return new LexerTokenLiteralNode(parent.getToken(), parent.getFinish(), value); } - private static final class NodeLiteralNode extends LiteralNode { - - private NodeLiteralNode(final long token, final int finish) { - this(token, finish, null); - } - - private NodeLiteralNode(final long token, final int finish, final Node value) { - super(Token.recast(token, TokenType.OBJECT), finish, value); - } - - private NodeLiteralNode(final LiteralNode literalNode) { - super(literalNode); - } + private static final class NullLiteralNode extends LiteralNode { - private NodeLiteralNode(final LiteralNode literalNode, final Node value) { - super(literalNode, value); + private NullLiteralNode(final long token, final int finish) { + super(Token.recast(token, TokenType.OBJECT), finish, null); } @Override public Node accept(final NodeVisitor visitor) { if (visitor.enterLiteralNode(this)) { - if (value != null) { - final Node newValue = value.accept(visitor); - if(value != newValue) { - return visitor.leaveLiteralNode(new NodeLiteralNode(this, newValue)); - } - } return visitor.leaveLiteralNode(this); } @@ -531,38 +512,13 @@ public abstract class LiteralNode extends Node implements PropertyKey { @Override public Type getType() { - return value == null ? Type.OBJECT : super.getType(); + return Type.OBJECT; } @Override public Type getWidestOperationType() { - return value == null ? Type.OBJECT : value.getWidestOperationType(); + return Type.OBJECT; } - - } - /** - * Create a new node literal for an arbitrary node - * - * @param token token - * @param finish finish - * @param value the literal value node - * - * @return the new literal node - */ - public static LiteralNode newInstance(final long token, final int finish, final Node value) { - return new NodeLiteralNode(token, finish, value); - } - - /** - * Create a new node literal based on a parent node (source, token, finish) - * - * @param parent parent node - * @param value node value - * - * @return the new literal node - */ - public static LiteralNode newInstance(final Node parent, final Node value) { - return new NodeLiteralNode(parent.getToken(), parent.getFinish(), value); } /** -- cgit v1.2.3 From 8017ff909039ad956fd21fc811ecde4d8d2fe165 Mon Sep 17 00:00:00 2001 From: attila Date: Fri, 31 May 2013 12:57:25 +0200 Subject: 8015684: FieldObjectCreator.putField ignores getValueType Reviewed-by: jlaskey, lagergren --- src/jdk/nashorn/internal/codegen/CodeGenerator.java | 13 +------------ src/jdk/nashorn/internal/codegen/FieldObjectCreator.java | 16 ---------------- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 21b61cd8..c2917073 100644 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -60,7 +60,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.TreeMap; - import jdk.nashorn.internal.codegen.ClassEmitter.Flag; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.codegen.RuntimeCallSite.SpecializedRuntimeNode; @@ -80,11 +79,11 @@ import jdk.nashorn.internal.ir.EmptyNode; import jdk.nashorn.internal.ir.ExecuteNode; import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.IdentNode; import jdk.nashorn.internal.ir.IfNode; import jdk.nashorn.internal.ir.IndexNode; +import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.LexicalContextNode; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; @@ -941,11 +940,6 @@ final class CodeGenerator extends NodeOperatorVisitor foc = new FieldObjectCreator(this, nameList, newSymbols, values, true, hasArguments) { - @Override - protected Type getValueType(final Symbol value) { - return value.getSymbolType(); - } - @Override protected void loadValue(final Symbol value) { method.load(value); @@ -1356,11 +1350,6 @@ final class CodeGenerator extends NodeOperatorVisitor(this, keys, symbols, values) { - @Override - protected Type getValueType(final Node node) { - return node.getType(); - } - @Override protected void loadValue(final Node node) { load(node); diff --git a/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java b/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java index 57b8b384..16ad2709 100644 --- a/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java +++ b/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java @@ -144,15 +144,6 @@ public abstract class FieldObjectCreator extends ObjectCreator { */ protected abstract void loadValue(T value); - /** - * Determine the type of a value. Defined by anonymous subclasses in code gen. - * - * @param value Value to inspect. - * - * @return Value type. - */ - protected abstract Type getValueType(T value); - /** * Store a value in a field of the generated class object. * @@ -165,13 +156,6 @@ public abstract class FieldObjectCreator extends ObjectCreator { method.dup(); loadValue(value); - - final Type valueType = getValueType(value); - // for example when we have a with scope - if (valueType.isObject() || valueType.isBoolean()) { - method.convert(OBJECT); - } - method.convert(OBJECT); method.putField(getClassName(), ObjectClassGenerator.getFieldName(fieldIndex, Type.OBJECT), typeDescriptor(Object.class)); } -- cgit v1.2.3 From ca02c5778d929864e2d9cc24140f449c9b91f563 Mon Sep 17 00:00:00 2001 From: attila Date: Fri, 31 May 2013 12:57:44 +0200 Subject: 8015674: CodeGenerator.initSymbols mutates a list Reviewed-by: jlaskey, lagergren --- .../nashorn/internal/codegen/CodeGenerator.java | 23 +++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/src/jdk/nashorn/internal/codegen/CodeGenerator.java index c2917073..34837bfa 100644 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -456,17 +456,18 @@ final class CodeGenerator extends NodeOperatorVisitor symbols, final Type type) { - if (symbols.isEmpty()) { - return; - } - - method.loadUndefined(type); - while (!symbols.isEmpty()) { - final Symbol symbol = symbols.removeFirst(); - if (!symbols.isEmpty()) { - method.dup(); - } - method.store(symbol); + final Iterator it = symbols.iterator(); + if(it.hasNext()) { + method.loadUndefined(type); + boolean hasNext; + do { + final Symbol symbol = it.next(); + hasNext = it.hasNext(); + if(hasNext) { + method.dup(); + } + method.store(symbol); + } while(hasNext); } } -- cgit v1.2.3 From dda5bf4f2363efcd962b7063207b852bca1245e7 Mon Sep 17 00:00:00 2001 From: attila Date: Fri, 31 May 2013 12:58:02 +0200 Subject: 8015673: Type for :e symbol is wrong Reviewed-by: jlaskey, lagergren --- src/jdk/nashorn/internal/codegen/Attr.java | 7 +++---- src/jdk/nashorn/internal/codegen/CompilerConstants.java | 5 +++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/jdk/nashorn/internal/codegen/Attr.java b/src/jdk/nashorn/internal/codegen/Attr.java index cf3e6946..d0b5a00a 100644 --- a/src/jdk/nashorn/internal/codegen/Attr.java +++ b/src/jdk/nashorn/internal/codegen/Attr.java @@ -84,13 +84,12 @@ import jdk.nashorn.internal.ir.TryNode; import jdk.nashorn.internal.ir.UnaryNode; import jdk.nashorn.internal.ir.VarNode; import jdk.nashorn.internal.ir.WithNode; -import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; +import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Debug; import jdk.nashorn.internal.runtime.DebugLogger; -import jdk.nashorn.internal.runtime.ECMAException; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; @@ -1323,7 +1322,7 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveForNode(final ForNode forNode) { if (forNode.isForIn()) { - forNode.setIterator(newInternal(lc.getCurrentFunction().uniqueName(ITERATOR_PREFIX.symbolName()), Type.OBJECT)); //NASHORN-73 + forNode.setIterator(newInternal(lc.getCurrentFunction().uniqueName(ITERATOR_PREFIX.symbolName()), Type.typeFor(ITERATOR_PREFIX.type()))); //NASHORN-73 /* * Iterators return objects, so we need to widen the scope of the * init variable if it, for example, has been assigned double type @@ -1500,7 +1499,7 @@ final class Attr extends NodeOperatorVisitor { } private Symbol exceptionSymbol() { - return newInternal(lc.getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(ECMAException.class)); + return newInternal(lc.getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(EXCEPTION_PREFIX.type())); } /** diff --git a/src/jdk/nashorn/internal/codegen/CompilerConstants.java b/src/jdk/nashorn/internal/codegen/CompilerConstants.java index d9c68ad8..3deff98c 100644 --- a/src/jdk/nashorn/internal/codegen/CompilerConstants.java +++ b/src/jdk/nashorn/internal/codegen/CompilerConstants.java @@ -29,6 +29,7 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.util.Iterator; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; @@ -105,13 +106,13 @@ public enum CompilerConstants { ARGUMENTS("arguments", Object.class, 2), /** prefix for iterators for for (x in ...) */ - ITERATOR_PREFIX(":i"), + ITERATOR_PREFIX(":i", Iterator.class), /** prefix for tag variable used for switch evaluation */ SWITCH_TAG_PREFIX(":s"), /** prefix for all exceptions */ - EXCEPTION_PREFIX(":e"), + EXCEPTION_PREFIX(":e", Throwable.class), /** prefix for quick slots generated in Store */ QUICK_PREFIX(":q"), -- cgit v1.2.3 From 040b9a81b0e06272391ab92a809ebd027fbfa0f3 Mon Sep 17 00:00:00 2001 From: sundar Date: Fri, 31 May 2013 17:39:12 +0530 Subject: 8012164: Error.stack needs trimming Reviewed-by: lagergren, jlaskey --- src/jdk/nashorn/internal/objects/NativeError.java | 9 ++++- test/script/basic/JDK-8012164.js | 46 +++++++++++++++++++++++ test/script/basic/JDK-8012164.js.EXPECTED | 3 ++ test/script/basic/NASHORN-108.js.EXPECTED | 4 +- test/script/basic/NASHORN-109.js.EXPECTED | 2 +- test/script/basic/errorstack.js.EXPECTED | 2 +- 6 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 test/script/basic/JDK-8012164.js create mode 100644 test/script/basic/JDK-8012164.js.EXPECTED diff --git a/src/jdk/nashorn/internal/objects/NativeError.java b/src/jdk/nashorn/internal/objects/NativeError.java index 433f9317..5473c8ef 100644 --- a/src/jdk/nashorn/internal/objects/NativeError.java +++ b/src/jdk/nashorn/internal/objects/NativeError.java @@ -32,6 +32,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.List; +import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; @@ -248,7 +249,13 @@ public final class NativeError extends ScriptObject { final List filtered = new ArrayList<>(); for (final StackTraceElement st : frames) { if (ECMAErrors.isScriptFrame(st)) { - filtered.add(st); + final String className = "<" + st.getFileName() + ">"; + String methodName = st.getMethodName(); + if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) { + methodName = ""; + } + filtered.add(new StackTraceElement(className, methodName, + st.getFileName(), st.getLineNumber())); } } res = filtered.toArray(); diff --git a/test/script/basic/JDK-8012164.js b/test/script/basic/JDK-8012164.js new file mode 100644 index 00000000..9134d143 --- /dev/null +++ b/test/script/basic/JDK-8012164.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/** + * JDK-8012164: Error.stack needs trimming + * + * @test + * @run + */ + +function func() { + error(); +} + +function error() { + try { + throw new Error('foo'); + } catch (e) { + for (i in e.stack) { + print(e.stack[i]); + } + } +} + +func(); diff --git a/test/script/basic/JDK-8012164.js.EXPECTED b/test/script/basic/JDK-8012164.js.EXPECTED new file mode 100644 index 00000000..e70edea3 --- /dev/null +++ b/test/script/basic/JDK-8012164.js.EXPECTED @@ -0,0 +1,3 @@ +.error(test/script/basic/JDK-8012164.js:38) +.func(test/script/basic/JDK-8012164.js:33) +.(test/script/basic/JDK-8012164.js:46) diff --git a/test/script/basic/NASHORN-108.js.EXPECTED b/test/script/basic/NASHORN-108.js.EXPECTED index 59e90f64..066c8ff2 100644 --- a/test/script/basic/NASHORN-108.js.EXPECTED +++ b/test/script/basic/NASHORN-108.js.EXPECTED @@ -1,3 +1,3 @@ -runScript 33 -runScript 32 + 33 + 32 done diff --git a/test/script/basic/NASHORN-109.js.EXPECTED b/test/script/basic/NASHORN-109.js.EXPECTED index fca137e2..9de7b322 100644 --- a/test/script/basic/NASHORN-109.js.EXPECTED +++ b/test/script/basic/NASHORN-109.js.EXPECTED @@ -1,2 +1,2 @@ -runScript 33 + 33 done diff --git a/test/script/basic/errorstack.js.EXPECTED b/test/script/basic/errorstack.js.EXPECTED index bb85d4e4..8ddae4df 100644 --- a/test/script/basic/errorstack.js.EXPECTED +++ b/test/script/basic/errorstack.js.EXPECTED @@ -1,4 +1,4 @@ func3 : 40 func2 : 36 func1 : 32 -runScript : 44 + : 44 -- cgit v1.2.3 From 1e0d0cbd5eeffc235ccd77b0080476aebeae8b03 Mon Sep 17 00:00:00 2001 From: jlaskey Date: Fri, 31 May 2013 13:04:55 -0300 Subject: 8015727: Thread safe print function Reviewed-by: sundar Contributed-by: james.laskey@oracle.com --- src/jdk/nashorn/internal/objects/Global.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/jdk/nashorn/internal/objects/Global.java b/src/jdk/nashorn/internal/objects/Global.java index e079248b..cdd0085f 100644 --- a/src/jdk/nashorn/internal/objects/Global.java +++ b/src/jdk/nashorn/internal/objects/Global.java @@ -1628,20 +1628,21 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { @SuppressWarnings("resource") private static Object printImpl(final boolean newLine, final Object... objects) { final PrintWriter out = Global.getEnv().getOut(); + final StringBuilder sb = new StringBuilder(); - boolean first = true; for (final Object object : objects) { - if (first) { - first = false; - } else { - out.print(' '); + if (sb.length() != 0) { + sb.append(' '); } - out.print(JSType.toString(object)); + sb.append(JSType.toString(object)); } + // Print all at once to ensure thread friendly result. if (newLine) { - out.println(); + out.println(sb.toString()); + } else { + out.print(sb.toString()); } out.flush(); -- cgit v1.2.3 From a0db141f18ba5d9319f9666507510965df8654b7 Mon Sep 17 00:00:00 2001 From: sundar Date: Mon, 3 Jun 2013 15:58:14 +0530 Subject: 8015345: Function("}),print('test'),({") should throw SyntaxError Reviewed-by: lagergren, hannesw, jlaskey --- .../nashorn/internal/objects/NativeFunction.java | 39 +++++- src/jdk/nashorn/internal/parser/Parser.java | 141 +++++++++++++++++---- test/script/basic/JDK-8015345.js | 64 ++++++++++ test/script/basic/JDK-8015345.js.EXPECTED | 15 +++ test/script/basic/funcconstructor.js.EXPECTED | 2 +- 5 files changed, 232 insertions(+), 29 deletions(-) create mode 100644 test/script/basic/JDK-8015345.js create mode 100644 test/script/basic/JDK-8015345.js.EXPECTED diff --git a/src/jdk/nashorn/internal/objects/NativeFunction.java b/src/jdk/nashorn/internal/objects/NativeFunction.java index 13c1bc15..528b120a 100644 --- a/src/jdk/nashorn/internal/objects/NativeFunction.java +++ b/src/jdk/nashorn/internal/objects/NativeFunction.java @@ -33,10 +33,14 @@ import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.ScriptClass; +import jdk.nashorn.internal.parser.Parser; +import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.JSType; +import jdk.nashorn.internal.runtime.ParserException; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.runtime.Source; /** * ECMA 15.3 Function Objects @@ -187,16 +191,25 @@ public final class NativeFunction { sb.append("(function ("); if (args.length > 0) { + final StringBuilder paramListBuf = new StringBuilder(); for (int i = 0; i < args.length - 1; i++) { - sb.append(JSType.toString(args[i])); + paramListBuf.append(JSType.toString(args[i])); if (i < args.length - 2) { - sb.append(","); + paramListBuf.append(","); } } + + final String paramList = paramListBuf.toString(); + if (! paramList.isEmpty()) { + checkFunctionParameters(paramList); + sb.append(paramList); + } } sb.append(") {\n"); if (args.length > 0) { - sb.append(JSType.toString(args[args.length - 1])); + final String funcBody = JSType.toString(args[args.length - 1]); + checkFunctionBody(funcBody); + sb.append(funcBody); sb.append('\n'); } sb.append("})"); @@ -205,4 +218,24 @@ public final class NativeFunction { return Global.directEval(global, sb.toString(), global, "", Global.isStrict()); } + + private static void checkFunctionParameters(final String params) { + final Source src = new Source("", params); + final Parser parser = new Parser(Global.getEnv(), src, new Context.ThrowErrorManager()); + try { + parser.parseFormalParameterList(); + } catch (final ParserException pe) { + pe.throwAsEcmaException(); + } + } + + private static void checkFunctionBody(final String funcBody) { + final Source src = new Source("", funcBody); + final Parser parser = new Parser(Global.getEnv(), src, new Context.ThrowErrorManager()); + try { + parser.parseFunctionBody(); + } catch (final ParserException pe) { + pe.throwAsEcmaException(); + } + } } diff --git a/src/jdk/nashorn/internal/parser/Parser.java b/src/jdk/nashorn/internal/parser/Parser.java index 03f65b86..e4dcf1b7 100644 --- a/src/jdk/nashorn/internal/parser/Parser.java +++ b/src/jdk/nashorn/internal/parser/Parser.java @@ -192,36 +192,110 @@ public class Parser extends AbstractParser { // Begin parse. return program(scriptName); } catch (final Exception e) { - // Extract message from exception. The message will be in error - // message format. - String message = e.getMessage(); - - // If empty message. - if (message == null) { - message = e.toString(); - } + handleParseException(e); - // Issue message. - if (e instanceof ParserException) { - errors.error((ParserException)e); + return null; + } finally { + final String end = this + " end '" + scriptName + "'"; + if (Timing.isEnabled()) { + Timing.accumulateTime(toString(), System.currentTimeMillis() - t0); + LOG.info(end, "' in ", (System.currentTimeMillis() - t0), " ms"); } else { - errors.error(message); + LOG.info(end); } + } + } - if (env._dump_on_error) { - e.printStackTrace(env.getErr()); - } + /** + * Parse and return the list of function parameter list. A comma + * separated list of function parameter identifiers is expected to be parsed. + * Errors will be thrown and the error manager will contain information + * if parsing should fail. This method is used to check if parameter Strings + * passed to "Function" constructor is a valid or not. + * + * @return the list of IdentNodes representing the formal parameter list + */ + public List parseFormalParameterList() { + try { + stream = new TokenStream(); + lexer = new Lexer(source, stream, scripting && !env._no_syntax_extensions); + + // Set up first token (skips opening EOL.) + k = -1; + next(); + return formalParameterList(TokenType.EOF); + } catch (final Exception e) { + handleParseException(e); return null; - } finally { - final String end = this + " end '" + scriptName + "'"; - if (Timing.isEnabled()) { - Timing.accumulateTime(toString(), System.currentTimeMillis() - t0); - LOG.info(end, "' in ", (System.currentTimeMillis() - t0), " ms"); - } else { - LOG.info(end); - } - } + } + } + + /** + * Execute parse and return the resulting function node. + * Errors will be thrown and the error manager will contain information + * if parsing should fail. This method is used to check if code String + * passed to "Function" constructor is a valid function body or not. + * + * @return function node resulting from successful parse + */ + public FunctionNode parseFunctionBody() { + try { + stream = new TokenStream(); + lexer = new Lexer(source, stream, scripting && !env._no_syntax_extensions); + + // Set up first token (skips opening EOL.) + k = -1; + next(); + + // Make a fake token for the function. + final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength()); + // Set up the function to append elements. + + FunctionNode function = newFunctionNode( + functionToken, + new IdentNode(functionToken, Token.descPosition(functionToken), RUN_SCRIPT.symbolName()), + new ArrayList(), + FunctionNode.Kind.NORMAL); + + functionDeclarations = new ArrayList<>(); + sourceElements(); + addFunctionDeclarations(function); + functionDeclarations = null; + + expect(EOF); + + function.setFinish(source.getLength() - 1); + + function = restoreFunctionNode(function, token); //commit code + function = function.setBody(lc, function.getBody().setNeedsScope(lc)); + return function; + } catch (final Exception e) { + handleParseException(e); + return null; + } + } + + private void handleParseException(final Exception e) { + // Extract message from exception. The message will be in error + // message format. + String message = e.getMessage(); + + // If empty message. + if (message == null) { + message = e.toString(); + } + + // Issue message. + if (e instanceof ParserException) { + errors.error((ParserException)e); + } else { + errors.error(message); + } + + if (env._dump_on_error) { + e.printStackTrace(env.getErr()); + } } /** @@ -2424,12 +2498,29 @@ loop: * @return List of parameter nodes. */ private List formalParameterList() { + return formalParameterList(RPAREN); + } + + /** + * Same as the other method of the same name - except that the end + * token type expected is passed as argument to this method. + * + * FormalParameterList : + * Identifier + * FormalParameterList , Identifier + * + * See 13 + * + * Parse function parameter list. + * @return List of parameter nodes. + */ + private List formalParameterList(final TokenType endType) { // Prepare to gather parameters. final List parameters = new ArrayList<>(); // Track commas. boolean first = true; - while (type != RPAREN) { + while (type != endType) { // Comma prior to every argument except the first. if (!first) { expect(COMMARIGHT); diff --git a/test/script/basic/JDK-8015345.js b/test/script/basic/JDK-8015345.js new file mode 100644 index 00000000..3f551d9e --- /dev/null +++ b/test/script/basic/JDK-8015345.js @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8015345: Function("}),print('test'),({") should throw SyntaxError + * + * @test + * @run + */ + +function checkFunction(code) { + try { + Function(code); + fail("should have thrown SyntaxError for :" + code); + } catch (e) { + if (! (e instanceof SyntaxError)) { + fail("SyntaxError expected, but got " + e); + } + print(e); + } +} + +// invalid body +checkFunction("}),print('test'),({"); + +// invalid param list +checkFunction("x**y", "print('x')"); + +// invalid param identifier +checkFunction("in", "print('hello')"); +//checkFunction("<>", "print('hello')") + +// invalid param list and body +checkFunction("x--y", ")"); + +// check few valid cases as well +var f = Function("x", "return x*x"); +print(f(10)) + +f = Function("x", "y", "return x+y"); +print(f(33, 22)); + +f = Function("x,y", "return x/y"); +print(f(24, 2)); diff --git a/test/script/basic/JDK-8015345.js.EXPECTED b/test/script/basic/JDK-8015345.js.EXPECTED new file mode 100644 index 00000000..9408699b --- /dev/null +++ b/test/script/basic/JDK-8015345.js.EXPECTED @@ -0,0 +1,15 @@ +SyntaxError: :1:0 Expected eof but found } +}),print('test'),({ +^ +SyntaxError: :1:2 Expected an operand but found * +x**y + ^ +SyntaxError: :1:0 Expected an operand but found in +in +^ +SyntaxError: :1:3 Expected ; but found y +x--y + ^ +100 +55 +12 diff --git a/test/script/basic/funcconstructor.js.EXPECTED b/test/script/basic/funcconstructor.js.EXPECTED index cf537d5a..cd7b16dd 100644 --- a/test/script/basic/funcconstructor.js.EXPECTED +++ b/test/script/basic/funcconstructor.js.EXPECTED @@ -4,7 +4,7 @@ function (x) { print('anon func'); return x*x; } syntax error? true -SyntaxError: :2:13 Missing close quote +SyntaxError: :1:13 Missing close quote print('hello) ^ done -- cgit v1.2.3 From 6d498c84911ed2edef2e655d6d472623121645fe Mon Sep 17 00:00:00 2001 From: jlaskey Date: Mon, 3 Jun 2013 08:34:29 -0300 Subject: 8015741: Need a global.load function that starts with a new global scope. Reviewed-by: sundar, lagergren Contributed-by: james.laskey@oracle.com --- src/jdk/nashorn/internal/objects/Global.java | 31 ++++++++++++--- src/jdk/nashorn/internal/runtime/Context.java | 22 +++++++++++ test/script/basic/JDK-8015741.js | 57 +++++++++++++++++++++++++++ test/script/basic/JDK-8015741.js.EXPECTED | 12 ++++++ 4 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 test/script/basic/JDK-8015741.js create mode 100644 test/script/basic/JDK-8015741.js.EXPECTED diff --git a/src/jdk/nashorn/internal/objects/Global.java b/src/jdk/nashorn/internal/objects/Global.java index cdd0085f..04daa8b5 100644 --- a/src/jdk/nashorn/internal/objects/Global.java +++ b/src/jdk/nashorn/internal/objects/Global.java @@ -119,6 +119,10 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { @Property(attributes = Attribute.NOT_ENUMERABLE) public Object load; + /** Nashorn extension: global.loadWithNewGlobal */ + @Property(attributes = Attribute.NOT_ENUMERABLE) + public Object loadWithNewGlobal; + /** Nashorn extension: global.exit */ @Property(attributes = Attribute.NOT_ENUMERABLE) public Object exit; @@ -364,11 +368,12 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // Used to store the last RegExp result to support deprecated RegExp constructor properties private RegExpResult lastRegExpResult; - private static final MethodHandle EVAL = findOwnMH("eval", Object.class, Object.class, Object.class); - private static final MethodHandle PRINT = findOwnMH("print", Object.class, Object.class, Object[].class); - private static final MethodHandle PRINTLN = findOwnMH("println", Object.class, Object.class, Object[].class); - private static final MethodHandle LOAD = findOwnMH("load", Object.class, Object.class, Object.class); - private static final MethodHandle EXIT = findOwnMH("exit", Object.class, Object.class, Object.class); + private static final MethodHandle EVAL = findOwnMH("eval", Object.class, Object.class, Object.class); + private static final MethodHandle PRINT = findOwnMH("print", Object.class, Object.class, Object[].class); + private static final MethodHandle PRINTLN = findOwnMH("println", Object.class, Object.class, Object[].class); + private static final MethodHandle LOAD = findOwnMH("load", Object.class, Object.class, Object.class); + private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH("loadWithNewGlobal", Object.class, Object.class, Object.class); + private static final MethodHandle EXIT = findOwnMH("exit", Object.class, Object.class, Object.class); private final Context context; @@ -742,6 +747,21 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { return global.context.load(scope, source); } + /** + * Global loadWithNewGlobal implementation - Nashorn extension + * + * @param self scope + * @param source source to load + * + * @return result of load (undefined) + * + * @throws IOException if source could not be read + */ + public static Object loadWithNewGlobal(final Object self, final Object source) throws IOException { + final Global global = Global.instance(); + return global.context.loadWithNewGlobal(source); + } + /** * Global exit and quit implementation - Nashorn extension: perform a {@code System.exit} call from the script * @@ -1387,6 +1407,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { this.unescape = ScriptFunctionImpl.makeFunction("unescape", GlobalFunctions.UNESCAPE); this.print = ScriptFunctionImpl.makeFunction("print", env._print_no_newline ? PRINT : PRINTLN); this.load = ScriptFunctionImpl.makeFunction("load", LOAD); + this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOADWITHNEWGLOBAL); this.exit = ScriptFunctionImpl.makeFunction("exit", EXIT); this.quit = ScriptFunctionImpl.makeFunction("quit", EXIT); diff --git a/src/jdk/nashorn/internal/runtime/Context.java b/src/jdk/nashorn/internal/runtime/Context.java index 338a8264..392d6f43 100644 --- a/src/jdk/nashorn/internal/runtime/Context.java +++ b/src/jdk/nashorn/internal/runtime/Context.java @@ -490,6 +490,28 @@ public final class Context { throw typeError("cant.load.script", ScriptRuntime.safeToString(from)); } + /** + * Implementation of {@code loadWithNewGlobal} Nashorn extension. Load a script file from a source + * expression, after creating a new global scope. + * + * @param from source expression for script + * + * @return return value for load call (undefined) + * + * @throws IOException if source cannot be found or loaded + */ + public Object loadWithNewGlobal(final Object from) throws IOException { + final ScriptObject oldGlobal = getGlobalTrusted(); + final ScriptObject newGlobal = createGlobal(); + setGlobalTrusted(newGlobal); + + try { + return load(newGlobal, from); + } finally { + setGlobalTrusted(oldGlobal); + } + } + /** * Load or get a structure class. Structure class names are based on the number of parameter fields * and {@link AccessorProperty} fields in them. Structure classes are used to represent ScriptObjects diff --git a/test/script/basic/JDK-8015741.js b/test/script/basic/JDK-8015741.js new file mode 100644 index 00000000..fdecee26 --- /dev/null +++ b/test/script/basic/JDK-8015741.js @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8015741 : Need a global.load function that starts with a new global scope. + * + * @test + * @run + */ + +var Thread = java.lang.Thread; + +myGlobal = "#0"; +var script1 = {name: "script 1", script: 'myGlobal = "#1"; print(myGlobal);'}; +var script2 = {name: "script 2", script: 'myGlobal = "#2"; print(myGlobal);'}; +var script3 = {name: "script 3", script: 'myGlobal = "#3"; print(myGlobal);'}; +var script4 = {name: "script 4", script: 'myGlobal = "#4"; print(myGlobal);'}; + +print(myGlobal); +load(script1); +print(myGlobal); + +print(myGlobal); +var thread1 = new Thread(function() { load(script2); }); +thread1.start(); +thread1.join(); +print(myGlobal); + +print(myGlobal); +loadWithNewGlobal(script3); +print(myGlobal); + +print(myGlobal); +var thread2 = new Thread(function() { loadWithNewGlobal(script4); }); +thread2.start(); +thread2.join(); +print(myGlobal); diff --git a/test/script/basic/JDK-8015741.js.EXPECTED b/test/script/basic/JDK-8015741.js.EXPECTED new file mode 100644 index 00000000..46bb1143 --- /dev/null +++ b/test/script/basic/JDK-8015741.js.EXPECTED @@ -0,0 +1,12 @@ +#0 +#1 +#1 +#1 +#2 +#2 +#2 +#3 +#2 +#2 +#4 +#2 -- cgit v1.2.3 From 7c16af5bb0d787b363b65ae36d699d4f6db74fcd Mon Sep 17 00:00:00 2001 From: jlaskey Date: Mon, 3 Jun 2013 11:16:33 -0300 Subject: 8015796: Race condition in RuntimeCallsites Reviewed-by: lagergren, attila Contributed-by: james.laskey@oracle.com --- src/jdk/nashorn/internal/codegen/RuntimeCallSite.java | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java b/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java index 1731da8e..5bbec962 100644 --- a/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java +++ b/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java @@ -59,12 +59,10 @@ import jdk.nashorn.internal.lookup.MethodHandleFactory; public final class RuntimeCallSite extends MutableCallSite { static final Call BOOTSTRAP = staticCallNoLookup(Bootstrap.class, "runtimeBootstrap", CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); - private static final MethodHandle NEXT = findOwnMH("next", MethodHandle.class); + private static final MethodHandle NEXT = findOwnMH("next", MethodHandle.class, String.class); private final RuntimeNode.Request request; - private String name; - /** * A specialized runtime node, i.e. on where we know at least one more specific type than object */ @@ -203,7 +201,6 @@ public final class RuntimeCallSite extends MutableCallSite { */ public RuntimeCallSite(final MethodType type, final String name) { super(type); - this.name = name; this.request = Request.valueOf(name.substring(0, name.indexOf(SpecializedRuntimeNode.REQUEST_SEPARATOR))); setTarget(makeMethod(name)); } @@ -292,7 +289,7 @@ public final class RuntimeCallSite extends MutableCallSite { mh = MH.explicitCastArguments(mh, type()); } - final MethodHandle fallback = MH.foldArguments(MethodHandles.exactInvoker(type()), MH.bindTo(NEXT, this)); + final MethodHandle fallback = MH.foldArguments(MethodHandles.exactInvoker(type()), MH.insertArguments(NEXT, 0, this, requestName)); MethodHandle guard; if (type().parameterType(0).isPrimitive()) { @@ -338,18 +335,12 @@ public final class RuntimeCallSite extends MutableCallSite { * * @return next wider specialization method for this RuntimeCallSite */ - public MethodHandle next() { - this.name = nextName(name); - final MethodHandle next = makeMethod(name); + public MethodHandle next(final String name) { + final MethodHandle next = makeMethod(nextName(name)); setTarget(next); return next; } - @Override - public String toString() { - return super.toString() + " " + name; - } - /** Method cache */ private static final Map METHODS; -- cgit v1.2.3 From a826ebf6dfd92641d8778e47946d3196e81dcdd4 Mon Sep 17 00:00:00 2001 From: jlaskey Date: Mon, 3 Jun 2013 12:57:53 -0300 Subject: 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged Reviewed-by: sundar Contributed-by: james.laskey@oracle.com --- src/jdk/nashorn/internal/runtime/Context.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/jdk/nashorn/internal/runtime/Context.java b/src/jdk/nashorn/internal/runtime/Context.java index 392d6f43..e75bb1b5 100644 --- a/src/jdk/nashorn/internal/runtime/Context.java +++ b/src/jdk/nashorn/internal/runtime/Context.java @@ -500,9 +500,21 @@ public final class Context { * * @throws IOException if source cannot be found or loaded */ - public Object loadWithNewGlobal(final Object from) throws IOException { + public Object loadWithNewGlobal(final Object from) throws IOException, RuntimeException { final ScriptObject oldGlobal = getGlobalTrusted(); - final ScriptObject newGlobal = createGlobal(); + final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public ScriptObject run() { + try { + return createGlobal(); + } catch (final RuntimeException e) { + if (Context.DEBUG) { + e.printStackTrace(); + } + throw e; + } + } + }); setGlobalTrusted(newGlobal); try { -- cgit v1.2.3 From 032ced2737ef6f1f4fbdad999174391d93c3ed5a Mon Sep 17 00:00:00 2001 From: sundar Date: Tue, 4 Jun 2013 17:33:14 +0530 Subject: 8015855: test/script/basic/JDK-8012164.js fails on Windows Reviewed-by: hannesw, lagergren, jlaskey --- test/script/basic/JDK-8012164.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/script/basic/JDK-8012164.js b/test/script/basic/JDK-8012164.js index 9134d143..6416cfad 100644 --- a/test/script/basic/JDK-8012164.js +++ b/test/script/basic/JDK-8012164.js @@ -38,9 +38,18 @@ function error() { throw new Error('foo'); } catch (e) { for (i in e.stack) { - print(e.stack[i]); + printFrame(e.stack[i]); } } } func(); + +// See JDK-8015855: test/script/basic/JDK-8012164.js fails on Windows +// Replace '\' to '/' in class and file names of StackFrameElement objects +function printFrame(stack) { + var fileName = stack.fileName.replace(/\\/g, '/'); + var className = stack.className.replace(/\\/g, '/'); + print(className + '.' + stack.methodName + '(' + + fileName + ':' + stack.lineNumber + ')'); +} -- cgit v1.2.3 From 0ea5d1fa77bac04905b4e7695f78eb4f4b648b70 Mon Sep 17 00:00:00 2001 From: sundar Date: Tue, 4 Jun 2013 22:31:48 +0530 Subject: 8015830: Javascript mapping of ScriptEngine bindings does not expose keys Reviewed-by: jlaskey, lagergren --- .../nashorn/api/scripting/ScriptObjectMirror.java | 23 +++++++-- src/jdk/nashorn/internal/runtime/ScriptObject.java | 11 +++++ .../nashorn/internal/runtime/ScriptRuntime.java | 13 +++++ test/script/basic/JDK-8015830.js | 56 ++++++++++++++++++++++ test/script/basic/JDK-8015830.js.EXPECTED | 4 ++ 5 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 test/script/basic/JDK-8015830.js create mode 100644 test/script/basic/JDK-8015830.js.EXPECTED diff --git a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java index e53903d3..59ac5fec 100644 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java @@ -31,7 +31,7 @@ import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -48,7 +48,7 @@ import jdk.nashorn.internal.runtime.ScriptRuntime; * access ScriptObject via the javax.script.Bindings interface or * netscape.javascript.JSObject interface. */ -final class ScriptObjectMirror extends JSObject implements Bindings { +public final class ScriptObjectMirror extends JSObject implements Bindings { private final ScriptObject sobj; private final ScriptObject global; @@ -217,7 +217,7 @@ final class ScriptObjectMirror extends JSObject implements Bindings { return inGlobal(new Callable>>() { @Override public Set> call() { final Iterator iter = sobj.propertyIterator(); - final Set> entries = new HashSet<>(); + final Set> entries = new LinkedHashSet<>(); while (iter.hasNext()) { final String key = iter.next(); @@ -253,7 +253,7 @@ final class ScriptObjectMirror extends JSObject implements Bindings { return inGlobal(new Callable>() { @Override public Set call() { final Iterator iter = sobj.propertyIterator(); - final Set keySet = new HashSet<>(); + final Set keySet = new LinkedHashSet<>(); while (iter.hasNext()) { keySet.add(iter.next()); @@ -302,6 +302,21 @@ final class ScriptObjectMirror extends JSObject implements Bindings { }); } + /** + * Delete a property from this object. + * + * @param key the property to be deleted + * + * @return if the delete was successful or not + */ + public boolean delete(final Object key) { + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.delete(unwrap(key, global)); + } + }); + } + @Override public int size() { return inGlobal(new Callable() { diff --git a/src/jdk/nashorn/internal/runtime/ScriptObject.java b/src/jdk/nashorn/internal/runtime/ScriptObject.java index cf89c545..331687ad 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -1511,6 +1511,17 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return oldValue; } + /** + * Delete a property from the ScriptObject. + * (to help ScriptObjectMirror implementation) + * + * @param key the key of the property + * @return if the delete was successful or not + */ + public boolean delete(final Object key) { + return delete(key, getContext()._strict); + } + /** * Return the size of the ScriptObject - i.e. the number of properties * it contains diff --git a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java index 25dccb7b..d5ab68b2 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java @@ -40,6 +40,7 @@ import java.util.Locale; import java.util.NoSuchElementException; import java.util.Objects; import jdk.internal.dynalink.beans.StaticClass; +import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.ir.debug.JSONWriter; import jdk.nashorn.internal.parser.Lexer; @@ -240,6 +241,10 @@ public final class ScriptRuntime { }; } + if (obj instanceof ScriptObjectMirror) { + return ((ScriptObjectMirror)obj).keySet().iterator(); + } + return Collections.emptyIterator(); } @@ -280,6 +285,10 @@ public final class ScriptRuntime { }; } + if (obj instanceof ScriptObjectMirror) { + return ((ScriptObjectMirror)obj).values().iterator(); + } + if (obj instanceof Iterable) { return ((Iterable)obj).iterator(); } @@ -591,6 +600,10 @@ public final class ScriptRuntime { throw typeError("cant.delete.property", safeToString(property), "null"); } + if (obj instanceof ScriptObjectMirror) { + return ((ScriptObjectMirror)obj).delete(property); + } + if (JSType.isPrimitive(obj)) { return ((ScriptObject) JSType.toScriptObject(obj)).delete(property, Boolean.TRUE.equals(strict)); } diff --git a/test/script/basic/JDK-8015830.js b/test/script/basic/JDK-8015830.js new file mode 100644 index 00000000..314a73a4 --- /dev/null +++ b/test/script/basic/JDK-8015830.js @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8015830: Javascript mapping of ScriptEngine bindings does not expose keys + * + * @test + * @run + */ + +var m = new javax.script.ScriptEngineManager(); +var engine = m.getEngineByName("nashorn"); + +engine.eval("x = 100; doit = function () { }"); + +var global = engine.getBindings(javax.script.ScriptContext.ENGINE_SCOPE); + +for(k in global){ + print(k + " = " + global[k]); +} + +for each (k in global) { + print(k); +} + +for(k in global) { + delete global[k]; +} + +for(k in global){ + print(k + " = " + global[k]); +} + +for each(k in global) { + print(k); +} diff --git a/test/script/basic/JDK-8015830.js.EXPECTED b/test/script/basic/JDK-8015830.js.EXPECTED new file mode 100644 index 00000000..8f98a224 --- /dev/null +++ b/test/script/basic/JDK-8015830.js.EXPECTED @@ -0,0 +1,4 @@ +x = 100 +doit = function () { } +100 +function () { } -- cgit v1.2.3 From ea026886cee53efd49d76283b82aac6e042929a1 Mon Sep 17 00:00:00 2001 From: sundar Date: Wed, 5 Jun 2013 12:08:49 +0530 Subject: 8015945: loadWithNewGlobal return value has to be properly wrapped Reviewed-by: lagergren, hannesw --- .../nashorn/api/scripting/ScriptObjectMirror.java | 53 ++++++++++++++++----- src/jdk/nashorn/internal/runtime/Context.java | 3 +- test/script/basic/JDK-8015945.js | 55 ++++++++++++++++++++++ test/script/basic/JDK-8015945.js.EXPECTED | 7 +++ 4 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 test/script/basic/JDK-8015945.js create mode 100644 test/script/basic/JDK-8015945.js.EXPECTED diff --git a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java index 59ac5fec..7428a8f6 100644 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java @@ -342,20 +342,28 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } - // package-privates below this. - ScriptObject getScriptObject() { - return sobj; - } - static Object translateUndefined(Object obj) { - return (obj == ScriptRuntime.UNDEFINED)? null : obj; - } + // These are public only so that Context can access these. - static Object wrap(final Object obj, final ScriptObject homeGlobal) { + /** + * Make a script object mirror on given object if needed. + * + * @param obj object to be wrapped + * @param homeGlobal global to which this object belongs + * @return wrapped object + */ + public static Object wrap(final Object obj, final ScriptObject homeGlobal) { return (obj instanceof ScriptObject) ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj; } - static Object unwrap(final Object obj, final ScriptObject homeGlobal) { + /** + * Unwrap a script object mirror if needed. + * + * @param obj object to be unwrapped + * @param homeGlobal global to which this object belongs + * @return unwrapped object + */ + public static Object unwrap(final Object obj, final ScriptObject homeGlobal) { if (obj instanceof ScriptObjectMirror) { final ScriptObjectMirror mirror = (ScriptObjectMirror)obj; return (mirror.global == homeGlobal)? mirror.sobj : obj; @@ -364,7 +372,14 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { return obj; } - static Object[] wrapArray(final Object[] args, final ScriptObject homeGlobal) { + /** + * Wrap an array of object to script object mirrors if needed. + * + * @param args array to be unwrapped + * @param homeGlobal global to which this object belongs + * @return wrapped array + */ + public static Object[] wrapArray(final Object[] args, final ScriptObject homeGlobal) { if (args == null || args.length == 0) { return args; } @@ -378,7 +393,14 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { return newArgs; } - static Object[] unwrapArray(final Object[] args, final ScriptObject homeGlobal) { + /** + * Unwrap an array of script object mirrors if needed. + * + * @param args array to be unwrapped + * @param homeGlobal global to which this object belongs + * @return unwrapped array + */ + public static Object[] unwrapArray(final Object[] args, final ScriptObject homeGlobal) { if (args == null || args.length == 0) { return args; } @@ -391,4 +413,13 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { } return newArgs; } + + // package-privates below this. + ScriptObject getScriptObject() { + return sobj; + } + + static Object translateUndefined(Object obj) { + return (obj == ScriptRuntime.UNDEFINED)? null : obj; + } } diff --git a/src/jdk/nashorn/internal/runtime/Context.java b/src/jdk/nashorn/internal/runtime/Context.java index e75bb1b5..6126e1a3 100644 --- a/src/jdk/nashorn/internal/runtime/Context.java +++ b/src/jdk/nashorn/internal/runtime/Context.java @@ -48,6 +48,7 @@ import java.security.PrivilegedAction; import java.security.ProtectionDomain; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; +import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.codegen.Compiler; import jdk.nashorn.internal.codegen.ObjectClassGenerator; import jdk.nashorn.internal.ir.FunctionNode; @@ -518,7 +519,7 @@ public final class Context { setGlobalTrusted(newGlobal); try { - return load(newGlobal, from); + return ScriptObjectMirror.wrap(load(newGlobal, from), newGlobal); } finally { setGlobalTrusted(oldGlobal); } diff --git a/test/script/basic/JDK-8015945.js b/test/script/basic/JDK-8015945.js new file mode 100644 index 00000000..5b9962e5 --- /dev/null +++ b/test/script/basic/JDK-8015945.js @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8015945: loadWithNewGlobal return value has to be properly wrapped + * + * @test + * @option -scripting + * @run + */ + +var global = loadWithNewGlobal({ name: "", + script: < T pop(final T node) { T expected = node; diff --git a/src/jdk/nashorn/internal/ir/ObjectNode.java b/src/jdk/nashorn/internal/ir/ObjectNode.java index 8529a1fe..31c07812 100644 --- a/src/jdk/nashorn/internal/ir/ObjectNode.java +++ b/src/jdk/nashorn/internal/ir/ObjectNode.java @@ -27,7 +27,6 @@ package jdk.nashorn.internal.ir; import java.util.Collections; import java.util.List; - import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -38,7 +37,7 @@ import jdk.nashorn.internal.ir.visitor.NodeVisitor; public final class ObjectNode extends Node { /** Literal elements. */ - private final List elements; + private final List elements; /** * Constructor @@ -47,12 +46,12 @@ public final class ObjectNode extends Node { * @param finish finish * @param elements the elements used to initialize this ObjectNode */ - public ObjectNode(final long token, final int finish, final List elements) { + public ObjectNode(final long token, final int finish, final List elements) { super(token, finish); this.elements = elements; } - private ObjectNode(final ObjectNode objectNode, final List elements) { + private ObjectNode(final ObjectNode objectNode, final List elements) { super(objectNode); this.elements = elements; } @@ -60,7 +59,7 @@ public final class ObjectNode extends Node { @Override public Node accept(final NodeVisitor visitor) { if (visitor.enterObjectNode(this)) { - return visitor.leaveObjectNode(setElements(Node.accept(visitor, Node.class, elements))); + return visitor.leaveObjectNode(setElements(Node.accept(visitor, PropertyNode.class, elements))); } return this; @@ -92,11 +91,11 @@ public final class ObjectNode extends Node { * Get the elements of this literal node * @return a list of elements */ - public List getElements() { + public List getElements() { return Collections.unmodifiableList(elements); } - private ObjectNode setElements(final List elements) { + private ObjectNode setElements(final List elements) { if (this.elements == elements) { return this; } diff --git a/src/jdk/nashorn/internal/parser/JSONParser.java b/src/jdk/nashorn/internal/parser/JSONParser.java index d4985ea3..aa9234ef 100644 --- a/src/jdk/nashorn/internal/parser/JSONParser.java +++ b/src/jdk/nashorn/internal/parser/JSONParser.java @@ -282,7 +282,7 @@ loop: next(); // Prepare to accumulate elements. - final List elements = new ArrayList<>(); + final List elements = new ArrayList<>(); // Create a block for the object literal. loop: @@ -298,7 +298,7 @@ loop: default: // Get and add the next property. - final Node property = propertyAssignment(); + final PropertyNode property = propertyAssignment(); elements.add(property); // Comma between property assigments is mandatory in JSON. @@ -317,7 +317,7 @@ loop: * Parse a property assignment from the token stream * @return the property assignment as a Node */ - private Node propertyAssignment() { + private PropertyNode propertyAssignment() { // Capture firstToken. final long propertyToken = token; LiteralNode name = null; diff --git a/src/jdk/nashorn/internal/parser/Parser.java b/src/jdk/nashorn/internal/parser/Parser.java index e4dcf1b7..ee90b8d9 100644 --- a/src/jdk/nashorn/internal/parser/Parser.java +++ b/src/jdk/nashorn/internal/parser/Parser.java @@ -59,7 +59,6 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; - import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.codegen.Namespace; import jdk.nashorn.internal.ir.AccessNode; @@ -2028,7 +2027,7 @@ loop: } } - return new ObjectNode(objectToken, finish, new ArrayList(map.values())); + return new ObjectNode(objectToken, finish, new ArrayList<>(map.values())); } /** diff --git a/src/jdk/nashorn/internal/runtime/JSONFunctions.java b/src/jdk/nashorn/internal/runtime/JSONFunctions.java index ed4d8653..c296a87a 100644 --- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java +++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java @@ -25,9 +25,11 @@ package jdk.nashorn.internal.runtime; +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow; +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; + import java.lang.invoke.MethodHandle; import java.util.Iterator; -import java.util.List; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.ObjectNode; @@ -36,8 +38,6 @@ import jdk.nashorn.internal.ir.UnaryNode; import jdk.nashorn.internal.parser.JSONParser; import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.runtime.linker.Bootstrap; -import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow; -import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; /** * Utilities used by "JSON" object implementation. @@ -171,10 +171,8 @@ public final class JSONFunctions { final ObjectNode objNode = (ObjectNode) node; final ScriptObject object = ((GlobalObject)global).newObject(); final boolean strict = global.isStrictContext(); - final List elements = objNode.getElements(); - for (final Node elem : elements) { - final PropertyNode pNode = (PropertyNode) elem; + for (final PropertyNode pNode: objNode.getElements()) { final Node valueNode = pNode.getValue(); final String name = pNode.getKeyName(); -- cgit v1.2.3 From 9cba1bff26d2d8cb67664079e94ddfcb2deebbbf Mon Sep 17 00:00:00 2001 From: attila Date: Wed, 5 Jun 2013 12:17:10 +0200 Subject: 8015961: Several small code-gardening fixes Reviewed-by: lagergren, sundar --- src/jdk/nashorn/internal/codegen/Lower.java | 15 +++++++-------- src/jdk/nashorn/internal/codegen/RuntimeCallSite.java | 5 +++-- src/jdk/nashorn/internal/ir/FunctionNode.java | 3 +-- .../internal/objects/GenericPropertyDescriptor.java | 4 ++-- src/jdk/nashorn/internal/objects/NativeMath.java | 1 - src/jdk/nashorn/internal/runtime/Context.java | 2 +- src/jdk/nashorn/internal/runtime/ListAdapter.java | 9 +++++---- src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java | 4 ++-- 8 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/jdk/nashorn/internal/codegen/Lower.java b/src/jdk/nashorn/internal/codegen/Lower.java index 2747560a..013564c2 100644 --- a/src/jdk/nashorn/internal/codegen/Lower.java +++ b/src/jdk/nashorn/internal/codegen/Lower.java @@ -32,7 +32,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.THIS; import java.util.ArrayList; import java.util.Arrays; import java.util.List; - import jdk.nashorn.internal.ir.BaseNode; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; @@ -258,7 +257,7 @@ final class Lower extends NodeOperatorVisitor { return throwNode; } - private static Node ensureUniqueNamesIn(final LexicalContext lc, final Node node) { + private static Node ensureUniqueNamesIn(final Node node) { return node.accept(new NodeVisitor(new LexicalContext()) { @Override public Node leaveFunctionNode(final FunctionNode functionNode) { @@ -273,10 +272,10 @@ final class Lower extends NodeOperatorVisitor { }); } - private static List copyFinally(final LexicalContext lc, final Block finallyBody) { + private static List copyFinally(final Block finallyBody) { final List newStatements = new ArrayList<>(); for (final Statement statement : finallyBody.getStatements()) { - newStatements.add((Statement)ensureUniqueNamesIn(lc, statement)); + newStatements.add((Statement)ensureUniqueNamesIn(statement)); if (statement.hasTerminalFlags()) { return newStatements; } @@ -340,7 +339,7 @@ final class Lower extends NodeOperatorVisitor { @Override public Node leaveThrowNode(final ThrowNode throwNode) { if (rethrows.contains(throwNode)) { - final List newStatements = copyFinally(lc, finallyBody); + final List newStatements = copyFinally(finallyBody); if (!isTerminal(newStatements)) { newStatements.add(throwNode); } @@ -374,7 +373,7 @@ final class Lower extends NodeOperatorVisitor { resultNode = null; } - newStatements.addAll(copyFinally(lc, finallyBody)); + newStatements.addAll(copyFinally(finallyBody)); if (!isTerminal(newStatements)) { newStatements.add(expr == null ? returnNode : returnNode.setExpression(resultNode)); } @@ -384,7 +383,7 @@ final class Lower extends NodeOperatorVisitor { private Node copy(final Statement endpoint, final Node targetNode) { if (!insideTry.contains(targetNode)) { - final List newStatements = copyFinally(lc, finallyBody); + final List newStatements = copyFinally(finallyBody); if (!isTerminal(newStatements)) { newStatements.add(endpoint); } @@ -550,7 +549,7 @@ final class Lower extends NodeOperatorVisitor { final FunctionNode currentFunction = lc.getCurrentFunction(); return callNode.setEvalArgs( new CallNode.EvalArgs( - ensureUniqueNamesIn(lc, args.get(0)).accept(this), + ensureUniqueNamesIn(args.get(0)).accept(this), compilerConstant(THIS), evalLocation(callee), currentFunction.isStrict())); diff --git a/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java b/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java index 5bbec962..c9f3836b 100644 --- a/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java +++ b/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java @@ -41,10 +41,10 @@ import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.RuntimeNode.Request; -import jdk.nashorn.internal.runtime.ScriptRuntime; -import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.lookup.Lookup; import jdk.nashorn.internal.lookup.MethodHandleFactory; +import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.runtime.linker.Bootstrap; /** * Optimistic call site that assumes its Object arguments to be of a boxed type. @@ -333,6 +333,7 @@ public final class RuntimeCallSite extends MutableCallSite { * * Do not call directly * + * @param name current name (with type) of runtime call at the call site * @return next wider specialization method for this RuntimeCallSite */ public MethodHandle next(final String name) { diff --git a/src/jdk/nashorn/internal/ir/FunctionNode.java b/src/jdk/nashorn/internal/ir/FunctionNode.java index 4c5eebb0..3640db30 100644 --- a/src/jdk/nashorn/internal/ir/FunctionNode.java +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java @@ -30,7 +30,6 @@ import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; - import jdk.nashorn.internal.codegen.CompileUnit; import jdk.nashorn.internal.codegen.Compiler; import jdk.nashorn.internal.codegen.CompilerConstants; @@ -385,7 +384,7 @@ public final class FunctionNode extends LexicalContextNode implements Flags newState = EnumSet.copyOf(this.compilationState); diff --git a/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java b/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java index f76f7f19..31afc307 100644 --- a/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java +++ b/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java @@ -150,11 +150,11 @@ public final class GenericPropertyDescriptor extends ScriptObject implements Pro if (this == obj) { return true; } - if (!(obj instanceof AccessorPropertyDescriptor)) { + if (!(obj instanceof GenericPropertyDescriptor)) { return false; } - final AccessorPropertyDescriptor other = (AccessorPropertyDescriptor)obj; + final GenericPropertyDescriptor other = (GenericPropertyDescriptor)obj; return ScriptRuntime.sameValue(configurable, other.configurable) && ScriptRuntime.sameValue(enumerable, other.enumerable); } diff --git a/src/jdk/nashorn/internal/objects/NativeMath.java b/src/jdk/nashorn/internal/objects/NativeMath.java index 50a2d864..9b1f226e 100644 --- a/src/jdk/nashorn/internal/objects/NativeMath.java +++ b/src/jdk/nashorn/internal/objects/NativeMath.java @@ -31,7 +31,6 @@ import jdk.nashorn.internal.objects.annotations.Property; import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.objects.annotations.SpecializedFunction; import jdk.nashorn.internal.objects.annotations.Where; -import jdk.nashorn.internal.runtime.GlobalFunctions; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptObject; diff --git a/src/jdk/nashorn/internal/runtime/Context.java b/src/jdk/nashorn/internal/runtime/Context.java index 6126e1a3..d0e3b020 100644 --- a/src/jdk/nashorn/internal/runtime/Context.java +++ b/src/jdk/nashorn/internal/runtime/Context.java @@ -501,7 +501,7 @@ public final class Context { * * @throws IOException if source cannot be found or loaded */ - public Object loadWithNewGlobal(final Object from) throws IOException, RuntimeException { + public Object loadWithNewGlobal(final Object from) throws IOException { final ScriptObject oldGlobal = getGlobalTrusted(); final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction() { @Override diff --git a/src/jdk/nashorn/internal/runtime/ListAdapter.java b/src/jdk/nashorn/internal/runtime/ListAdapter.java index cc99cd12..428cb555 100644 --- a/src/jdk/nashorn/internal/runtime/ListAdapter.java +++ b/src/jdk/nashorn/internal/runtime/ListAdapter.java @@ -15,10 +15,11 @@ import jdk.nashorn.internal.runtime.linker.InvokeByName; * as dequeues, it's still slightly more efficient to be able to translate dequeue operations into pushes, pops, shifts, * and unshifts, than to blindly translate all list's add/remove operations into splices. Also, it is conceivable that a * custom script object that implements an Array-like API can have a background data representation that is optimized - * for dequeue-like access. Note that with ECMAScript arrays, {@code push} and {@pop} operate at the end of the array, - * while in Java {@code Deque} they operate on the front of the queue and as such the Java dequeue {@link #push(Object)} - * and {@link #pop()} operations will translate to {@code unshift} and {@code shift} script operations respectively, - * while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and {@code pop}. + * for dequeue-like access. Note that with ECMAScript arrays, {@code push} and {@code pop} operate at the end of the + * array, while in Java {@code Deque} they operate on the front of the queue and as such the Java dequeue + * {@link #push(Object)} and {@link #pop()} operations will translate to {@code unshift} and {@code shift} script + * operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and + * {@code pop}. */ public class ListAdapter extends AbstractList implements RandomAccess, Deque { // These add to the back and front of the list diff --git a/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java b/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java index 749b1d41..03c99a3c 100644 --- a/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java +++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java @@ -23,23 +23,23 @@ import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnOff; import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup; import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase; -import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType; import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.AnyCharNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode; +import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode.CCStateArg; import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.Node; import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode; import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode; -import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode.CCStateArg; import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType; import jdk.nashorn.internal.runtime.regexp.joni.constants.CCSTATE; import jdk.nashorn.internal.runtime.regexp.joni.constants.CCVALTYPE; import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType; import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType; import jdk.nashorn.internal.runtime.regexp.joni.constants.TokenType; +import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType; class Parser extends Lexer { -- cgit v1.2.3 From d5db868407e3bf511aff712eeebcf4a0ec188903 Mon Sep 17 00:00:00 2001 From: hannesw Date: Wed, 5 Jun 2013 12:44:24 +0200 Subject: 8015350: Array.prototype.reduceRight issue with large length and index Reviewed-by: attila, sundar, lagergren --- src/jdk/nashorn/internal/objects/NativeArray.java | 22 +++++----- .../internal/runtime/arrays/ArrayIterator.java | 6 +-- .../internal/runtime/arrays/ArrayLikeIterator.java | 8 ++-- .../runtime/arrays/EmptyArrayLikeIterator.java | 2 +- .../internal/runtime/arrays/IteratorAction.java | 4 +- .../internal/runtime/arrays/MapIterator.java | 4 +- .../runtime/arrays/ReverseArrayIterator.java | 4 +- .../runtime/arrays/ReverseMapIterator.java | 4 +- test/script/basic/JDK-8015350.js | 51 ++++++++++++++++++++++ test/script/basic/JDK-8015350.js.EXPECTED | 4 ++ 10 files changed, 82 insertions(+), 27 deletions(-) create mode 100644 test/script/basic/JDK-8015350.js create mode 100644 test/script/basic/JDK-8015350.js.EXPECTED diff --git a/src/jdk/nashorn/internal/objects/NativeArray.java b/src/jdk/nashorn/internal/objects/NativeArray.java index 6f9fbcec..9736376b 100644 --- a/src/jdk/nashorn/internal/objects/NativeArray.java +++ b/src/jdk/nashorn/internal/objects/NativeArray.java @@ -75,7 +75,7 @@ public final class NativeArray extends ScriptObject { private static final MethodHandle FILTER_CALLBACK_INVOKER = createIteratorCallbackInvoker(boolean.class); private static final MethodHandle REDUCE_CALLBACK_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class, - Object.class, Undefined.class, Object.class, Object.class, int.class, Object.class); + Object.class, Undefined.class, Object.class, Object.class, long.class, Object.class); private static final MethodHandle CALL_CMP = Bootstrap.createDynamicInvoker("dyn:call", double.class, ScriptFunction.class, Object.class, Object.class, Object.class); @@ -1086,7 +1086,7 @@ public final class NativeArray extends ScriptObject { private static boolean applyEvery(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction(Global.toObject(self), callbackfn, thisArg, true) { @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { return (result = (boolean)EVERY_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)); } }.apply(); @@ -1104,7 +1104,7 @@ public final class NativeArray extends ScriptObject { public static Object some(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction(Global.toObject(self), callbackfn, thisArg, false) { @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { return !(result = (boolean)SOME_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)); } }.apply(); @@ -1122,7 +1122,7 @@ public final class NativeArray extends ScriptObject { public static Object forEach(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction(Global.toObject(self), callbackfn, thisArg, ScriptRuntime.UNDEFINED) { @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { FOREACH_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self); return true; } @@ -1141,9 +1141,9 @@ public final class NativeArray extends ScriptObject { public static Object map(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction(Global.toObject(self), callbackfn, thisArg, null) { @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { final Object r = MAP_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self); - result.defineOwnProperty(index, r); + result.defineOwnProperty((int)index, r); return true; } @@ -1167,12 +1167,12 @@ public final class NativeArray extends ScriptObject { @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object filter(final Object self, final Object callbackfn, final Object thisArg) { return new IteratorAction(Global.toObject(self), callbackfn, thisArg, new NativeArray()) { - private int to = 0; + private long to = 0; @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { if ((boolean)FILTER_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)) { - result.defineOwnProperty(to++, val); + result.defineOwnProperty((int)(to++), val); } return true; } @@ -1200,7 +1200,7 @@ public final class NativeArray extends ScriptObject { //if initial value is ScriptRuntime.UNDEFINED - step forward once. return new IteratorAction(Global.toObject(self), callbackfn, ScriptRuntime.UNDEFINED, initialValue, iter) { @Override - protected boolean forEach(final Object val, final int i) throws Throwable { + protected boolean forEach(final Object val, final long i) throws Throwable { // TODO: why can't I declare the second arg as Undefined.class? result = REDUCE_CALLBACK_INVOKER.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self); return true; @@ -1258,7 +1258,7 @@ public final class NativeArray extends ScriptObject { private static MethodHandle createIteratorCallbackInvoker(final Class rtype) { return Bootstrap.createDynamicInvoker("dyn:call", rtype, Object.class, Object.class, Object.class, - int.class, Object.class); + long.class, Object.class); } } diff --git a/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java b/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java index 3b9905a2..e250c748 100644 --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java @@ -36,7 +36,7 @@ public class ArrayIterator extends ArrayLikeIterator { protected final ScriptObject array; /** length of array */ - protected final int length; + protected final long length; /** * Constructor @@ -46,7 +46,7 @@ public class ArrayIterator extends ArrayLikeIterator { protected ArrayIterator(final ScriptObject array, final boolean includeUndefined) { super(includeUndefined); this.array = array; - this.length = (int) array.getArray().length(); + this.length = array.getArray().length(); } /** @@ -63,7 +63,7 @@ public class ArrayIterator extends ArrayLikeIterator { } @Override - public int getLength() { + public long getLength() { return length; } diff --git a/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java b/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java index 5061683a..48505f44 100644 --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java @@ -38,7 +38,7 @@ import jdk.nashorn.internal.runtime.ScriptObject; abstract public class ArrayLikeIterator implements Iterator { /** current element index in iteration */ - protected int index; + protected long index; /** should undefined elements be included in the iteration? */ protected final boolean includeUndefined; @@ -65,7 +65,7 @@ abstract public class ArrayLikeIterator implements Iterator { * Go the the next valid element index of the iterator * @return next index */ - protected int bumpIndex() { + protected long bumpIndex() { return index++; } @@ -73,7 +73,7 @@ abstract public class ArrayLikeIterator implements Iterator { * Return the next valid element index of the iterator * @return next index */ - public int nextIndex() { + public long nextIndex() { return index; } @@ -86,7 +86,7 @@ abstract public class ArrayLikeIterator implements Iterator { * Get the length of the iteration * @return length */ - public abstract int getLength(); + public abstract long getLength(); /** * ArrayLikeIterator factory diff --git a/src/jdk/nashorn/internal/runtime/arrays/EmptyArrayLikeIterator.java b/src/jdk/nashorn/internal/runtime/arrays/EmptyArrayLikeIterator.java index 5264283a..e94f8cf3 100644 --- a/src/jdk/nashorn/internal/runtime/arrays/EmptyArrayLikeIterator.java +++ b/src/jdk/nashorn/internal/runtime/arrays/EmptyArrayLikeIterator.java @@ -47,7 +47,7 @@ final class EmptyArrayLikeIterator extends ArrayLikeIterator { } @Override - public int getLength() { + public long getLength() { return 0; } } diff --git a/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java b/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java index 9fb4eed8..7568f41b 100644 --- a/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java +++ b/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java @@ -49,7 +49,7 @@ public abstract class IteratorAction { protected T result; /** Current array index of iterator */ - protected int index; + protected long index; /** Iterator object */ private final ArrayLikeIterator iter; @@ -134,6 +134,6 @@ public abstract class IteratorAction { * * @throws Throwable if invocation throws an exception/error */ - protected abstract boolean forEach(final Object val, final int i) throws Throwable; + protected abstract boolean forEach(final Object val, final long i) throws Throwable; } diff --git a/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java b/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java index fdf9d3a4..f8b40cfe 100644 --- a/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java +++ b/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java @@ -49,8 +49,8 @@ class MapIterator extends ArrayLikeIterator { } @Override - public int getLength() { - return (int) length; + public long getLength() { + return length; } @Override diff --git a/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java b/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java index 72a47a93..f9ba0ff0 100644 --- a/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java +++ b/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java @@ -39,7 +39,7 @@ public final class ReverseArrayIterator extends ArrayIterator { */ public ReverseArrayIterator(final ScriptObject array, final boolean includeUndefined) { super(array, includeUndefined); - this.index = (int) (array.getArray().length() - 1); + this.index = array.getArray().length() - 1; } @Override @@ -53,7 +53,7 @@ public final class ReverseArrayIterator extends ArrayIterator { } @Override - protected int bumpIndex() { + protected long bumpIndex() { return index--; } } diff --git a/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java b/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java index 760ac720..0822b5a4 100644 --- a/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java +++ b/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java @@ -35,7 +35,7 @@ final class ReverseMapIterator extends MapIterator { ReverseMapIterator(final ScriptObject obj, final boolean includeUndefined) { super(obj, includeUndefined); - this.index = JSType.toInt32(obj.getLength()) - 1; + this.index = JSType.toUint32(obj.getLength()) - 1; } @Override @@ -49,7 +49,7 @@ final class ReverseMapIterator extends MapIterator { } @Override - protected int bumpIndex() { + protected long bumpIndex() { return index--; } } diff --git a/test/script/basic/JDK-8015350.js b/test/script/basic/JDK-8015350.js new file mode 100644 index 00000000..c8202969 --- /dev/null +++ b/test/script/basic/JDK-8015350.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8015350: Array.prototype.reduceRight issue with large length and index + * + * @test + * @run + */ + +function reduce(obj) { + try { + Array.prototype.reduceRight.call(obj, function(acc, v, i, o){ + print(v + i); + throw "stop"; + }, 0); + } catch (error) { + print(error); + } +} + +// array-like object +reduce({ + length:0xffffffff, + 0xfffffffe: "index: " +}); + +// actual sparse array +var array = []; +array[0xfffffffe] = "index: "; +reduce(array); diff --git a/test/script/basic/JDK-8015350.js.EXPECTED b/test/script/basic/JDK-8015350.js.EXPECTED new file mode 100644 index 00000000..e8bda2c4 --- /dev/null +++ b/test/script/basic/JDK-8015350.js.EXPECTED @@ -0,0 +1,4 @@ +index: 4294967294 +stop +index: 4294967294 +stop -- cgit v1.2.3 From 251f423ce2f894fc82e5fc8f857eaaec28adddda Mon Sep 17 00:00:00 2001 From: jlaskey Date: Wed, 5 Jun 2013 10:32:50 -0300 Subject: 8015911: $EXEC does not handle large outputs Reviewed-by: sundar, attila Contributed-by: james.laskey@oracle.com --- .../internal/runtime/ScriptingFunctions.java | 77 +++++++++++++++------- 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java index 1d046ca9..ee1639d0 100644 --- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java @@ -32,9 +32,8 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.io.BufferedReader; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; -import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.util.Map; @@ -165,36 +164,61 @@ public final class ScriptingFunctions { // Start the process. final Process process = processBuilder.start(); + final IOException exception[] = new IOException[2]; + + // Collect output. + final StringBuilder outBuffer = new StringBuilder(); + Thread outThread = new Thread(new Runnable() { + @Override + public void run() { + char buffer[] = new char[1024]; + try (final InputStreamReader inputStream = new InputStreamReader(process.getInputStream())) { + for (int length; (length = inputStream.read(buffer, 0, buffer.length)) != -1; ) { + outBuffer.append(buffer, 0, length); + } + } catch (IOException ex) { + exception[0] = ex; + } + } + }, "$EXEC output"); + + // Collect errors. + final StringBuilder errBuffer = new StringBuilder(); + Thread errThread = new Thread(new Runnable() { + @Override + public void run() { + char buffer[] = new char[1024]; + try (final InputStreamReader inputStream = new InputStreamReader(process.getErrorStream())) { + for (int length; (length = inputStream.read(buffer, 0, buffer.length)) != -1; ) { + outBuffer.append(buffer, 0, length); + } + } catch (IOException ex) { + exception[1] = ex; + } + } + }, "$EXEC error"); + + // Start gathering output. + outThread.start(); + errThread.start(); // If input is present, pass on to process. - try (OutputStream outputStream = process.getOutputStream()) { + try (OutputStreamWriter outputStream = new OutputStreamWriter(process.getOutputStream())) { if (input != UNDEFINED) { - outputStream.write(JSType.toString(input).getBytes()); + String in = JSType.toString(input); + outputStream.write(in, 0, in.length()); } + } catch (IOException ex) { + // Process was not expecting input. May be normal state of affairs. } // Wait for the process to complete. final int exit = process.waitFor(); + outThread.join(); + errThread.join(); - // Collect output. - String out; - try (InputStream inputStream = process.getInputStream()) { - final StringBuilder outBuffer = new StringBuilder(); - for (int ch; (ch = inputStream.read()) != -1; ) { - outBuffer.append((char)ch); - } - out = outBuffer.toString(); - } - - // Collect errors. - String err; - try (InputStream errorStream = process.getErrorStream()) { - final StringBuilder errBuffer = new StringBuilder(); - for (int ch; (ch = errorStream.read()) != -1; ) { - errBuffer.append((char)ch); - } - err = errBuffer.toString(); - } + final String out = outBuffer.toString(); + final String err = errBuffer.toString(); // Set globals for secondary results. final boolean isStrict = global.isStrictContext(); @@ -202,6 +226,13 @@ public final class ScriptingFunctions { global.set(ERR_NAME, err, isStrict); global.set(EXIT_NAME, exit, isStrict); + // Propagate exception if present. + for (int i = 0; i < exception.length; i++) { + if (exception[i] != null) { + throw exception[i]; + } + } + // Return the result from stdout. return out; } -- cgit v1.2.3 From b5afc32e9596ee8409a810fdc7b09916265ba491 Mon Sep 17 00:00:00 2001 From: jlaskey Date: Wed, 5 Jun 2013 12:41:09 -0300 Subject: 8015910: Nashorn JavaFX includes are out of sync with JavaFX repo Reviewed-by: sundar Contributed-by: james.laskey@oracle.com --- .../internal/runtime/resources/fx/controls.js | 26 +++++------ .../internal/runtime/resources/fx/graphics.js | 54 +++++++++++----------- .../nashorn/internal/runtime/resources/fx/swt.js | 2 +- .../nashorn/internal/runtime/resources/fx/web.js | 4 +- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/controls.js b/src/jdk/nashorn/internal/runtime/resources/fx/controls.js index f550107d..6a2a89c4 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/controls.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/controls.js @@ -70,7 +70,7 @@ CheckBoxTableCellBuilder = Java.type("javafx.scene.control.cel CheckBoxTreeCell = Java.type("javafx.scene.control.cell.CheckBoxTreeCell"); CheckBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeCellBuilder"); CheckBoxTreeTableCell = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCell"); -CheckBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCellBuilder"); +//CheckBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCellBuilder"); ChoiceBoxListCell = Java.type("javafx.scene.control.cell.ChoiceBoxListCell"); ChoiceBoxListCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxListCellBuilder"); ChoiceBoxTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTableCell"); @@ -78,7 +78,7 @@ ChoiceBoxTableCellBuilder = Java.type("javafx.scene.control.cel ChoiceBoxTreeCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCell"); ChoiceBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCellBuilder"); ChoiceBoxTreeTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCell"); -ChoiceBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCellBuilder"); +//ChoiceBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCellBuilder"); ComboBoxListCell = Java.type("javafx.scene.control.cell.ComboBoxListCell"); ComboBoxListCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxListCellBuilder"); ComboBoxTableCell = Java.type("javafx.scene.control.cell.ComboBoxTableCell"); @@ -86,7 +86,7 @@ ComboBoxTableCellBuilder = Java.type("javafx.scene.control.cel ComboBoxTreeCell = Java.type("javafx.scene.control.cell.ComboBoxTreeCell"); ComboBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeCellBuilder"); ComboBoxTreeTableCell = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCell"); -ComboBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCellBuilder"); +//ComboBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCellBuilder"); MapValueFactory = Java.type("javafx.scene.control.cell.MapValueFactory"); ProgressBarTableCell = Java.type("javafx.scene.control.cell.ProgressBarTableCell"); ProgressBarTreeTableCell = Java.type("javafx.scene.control.cell.ProgressBarTreeTableCell"); @@ -99,9 +99,9 @@ TextFieldTableCellBuilder = Java.type("javafx.scene.control.cel TextFieldTreeCell = Java.type("javafx.scene.control.cell.TextFieldTreeCell"); TextFieldTreeCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeCellBuilder"); TextFieldTreeTableCell = Java.type("javafx.scene.control.cell.TextFieldTreeTableCell"); -TextFieldTreeTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeTableCellBuilder"); +//TextFieldTreeTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeTableCellBuilder"); TreeItemPropertyValueFactory = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactory"); -TreeItemPropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactoryBuilder"); +//TreeItemPropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactoryBuilder"); CellBuilder = Java.type("javafx.scene.control.CellBuilder"); CheckBox = Java.type("javafx.scene.control.CheckBox"); CheckBoxBuilder = Java.type("javafx.scene.control.CheckBoxBuilder"); @@ -167,7 +167,7 @@ RadioButtonBuilder = Java.type("javafx.scene.control.Rad RadioMenuItem = Java.type("javafx.scene.control.RadioMenuItem"); RadioMenuItemBuilder = Java.type("javafx.scene.control.RadioMenuItemBuilder"); ResizeFeaturesBase = Java.type("javafx.scene.control.ResizeFeaturesBase"); -ResizeFeaturesBaseBuilder = Java.type("javafx.scene.control.ResizeFeaturesBaseBuilder"); +//ResizeFeaturesBaseBuilder = Java.type("javafx.scene.control.ResizeFeaturesBaseBuilder"); ScrollBar = Java.type("javafx.scene.control.ScrollBar"); ScrollBarBuilder = Java.type("javafx.scene.control.ScrollBarBuilder"); ScrollPane = Java.type("javafx.scene.control.ScrollPane"); @@ -183,7 +183,7 @@ SeparatorMenuItemBuilder = Java.type("javafx.scene.control.Sep SingleSelectionModel = Java.type("javafx.scene.control.SingleSelectionModel"); Skin = Java.type("javafx.scene.control.Skin"); SkinBase = Java.type("javafx.scene.control.SkinBase"); -SkinBaseBuilder = Java.type("javafx.scene.control.SkinBaseBuilder"); +//SkinBaseBuilder = Java.type("javafx.scene.control.SkinBaseBuilder"); Skinnable = Java.type("javafx.scene.control.Skinnable"); Slider = Java.type("javafx.scene.control.Slider"); SliderBuilder = Java.type("javafx.scene.control.SliderBuilder"); @@ -202,7 +202,7 @@ TableColumn$CellDataFeatures = Java.type("javafx.scene.control.Tab TableColumn$CellEditEvent = Java.type("javafx.scene.control.TableColumn$CellEditEvent"); TableColumn$SortType = Java.type("javafx.scene.control.TableColumn$SortType"); TableColumnBase = Java.type("javafx.scene.control.TableColumnBase"); -TableColumnBaseBuilder = Java.type("javafx.scene.control.TableColumnBaseBuilder"); +//TableColumnBaseBuilder = Java.type("javafx.scene.control.TableColumnBaseBuilder"); TableColumnBuilder = Java.type("javafx.scene.control.TableColumnBuilder"); TableFocusModel = Java.type("javafx.scene.control.TableFocusModel"); TablePosition = Java.type("javafx.scene.control.TablePosition"); @@ -210,7 +210,7 @@ TablePositionBase = Java.type("javafx.scene.control.Tab TableRow = Java.type("javafx.scene.control.TableRow"); TableRowBuilder = Java.type("javafx.scene.control.TableRowBuilder"); TableSelectionModel = Java.type("javafx.scene.control.TableSelectionModel"); -TableSelectionModelBuilder = Java.type("javafx.scene.control.TableSelectionModelBuilder"); +//TableSelectionModelBuilder = Java.type("javafx.scene.control.TableSelectionModelBuilder"); TableView = Java.type("javafx.scene.control.TableView"); TableView$ResizeFeatures = Java.type("javafx.scene.control.TableView$ResizeFeatures"); TableView$TableViewFocusModel = Java.type("javafx.scene.control.TableView$TableViewFocusModel"); @@ -244,21 +244,21 @@ TreeItem$TreeModificationEvent = Java.type("javafx.scene.control.Tre TreeItemBuilder = Java.type("javafx.scene.control.TreeItemBuilder"); TreeSortMode = Java.type("javafx.scene.control.TreeSortMode"); TreeTableCell = Java.type("javafx.scene.control.TreeTableCell"); -TreeTableCellBuilder = Java.type("javafx.scene.control.TreeTableCellBuilder"); +//TreeTableCellBuilder = Java.type("javafx.scene.control.TreeTableCellBuilder"); TreeTableColumn = Java.type("javafx.scene.control.TreeTableColumn"); TreeTableColumn$CellDataFeatures = Java.type("javafx.scene.control.TreeTableColumn$CellDataFeatures"); TreeTableColumn$CellEditEvent = Java.type("javafx.scene.control.TreeTableColumn$CellEditEvent"); TreeTableColumn$SortType = Java.type("javafx.scene.control.TreeTableColumn$SortType"); -TreeTableColumnBuilder = Java.type("javafx.scene.control.TreeTableColumnBuilder"); +//TreeTableColumnBuilder = Java.type("javafx.scene.control.TreeTableColumnBuilder"); TreeTablePosition = Java.type("javafx.scene.control.TreeTablePosition"); TreeTableRow = Java.type("javafx.scene.control.TreeTableRow"); -TreeTableRowBuilder = Java.type("javafx.scene.control.TreeTableRowBuilder"); +//TreeTableRowBuilder = Java.type("javafx.scene.control.TreeTableRowBuilder"); TreeTableView = Java.type("javafx.scene.control.TreeTableView"); TreeTableView$EditEvent = Java.type("javafx.scene.control.TreeTableView$EditEvent"); TreeTableView$ResizeFeatures = Java.type("javafx.scene.control.TreeTableView$ResizeFeatures"); TreeTableView$TreeTableViewFocusModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewFocusModel"); TreeTableView$TreeTableViewSelectionModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewSelectionModel"); -TreeTableViewBuilder = Java.type("javafx.scene.control.TreeTableViewBuilder"); +//TreeTableViewBuilder = Java.type("javafx.scene.control.TreeTableViewBuilder"); TreeView = Java.type("javafx.scene.control.TreeView"); TreeView$EditEvent = Java.type("javafx.scene.control.TreeView$EditEvent"); TreeViewBuilder = Java.type("javafx.scene.control.TreeViewBuilder"); diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js b/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js index 9da00bd2..72f55cd1 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js @@ -134,10 +134,10 @@ PrintQuality = Java.type("javafx.print.PrintQuality"); PrintResolution = Java.type("javafx.print.PrintResolution"); PrintSides = Java.type("javafx.print.PrintSides"); AmbientLight = Java.type("javafx.scene.AmbientLight"); -AmbientLightBuilder = Java.type("javafx.scene.AmbientLightBuilder"); +//AmbientLightBuilder = Java.type("javafx.scene.AmbientLightBuilder"); CacheHint = Java.type("javafx.scene.CacheHint"); Camera = Java.type("javafx.scene.Camera"); -CameraBuilder = Java.type("javafx.scene.CameraBuilder"); +//CameraBuilder = Java.type("javafx.scene.CameraBuilder"); Canvas = Java.type("javafx.scene.canvas.Canvas"); CanvasBuilder = Java.type("javafx.scene.canvas.CanvasBuilder"); GraphicsContext = Java.type("javafx.scene.canvas.GraphicsContext"); @@ -209,12 +209,12 @@ Dragboard = Java.type("javafx.scene.input.Dragboard DragEvent = Java.type("javafx.scene.input.DragEvent"); GestureEvent = Java.type("javafx.scene.input.GestureEvent"); InputEvent = Java.type("javafx.scene.input.InputEvent"); -InputEventBuilder = Java.type("javafx.scene.input.InputEventBuilder"); +//InputEventBuilder = Java.type("javafx.scene.input.InputEventBuilder"); InputMethodEvent = Java.type("javafx.scene.input.InputMethodEvent"); InputMethodHighlight = Java.type("javafx.scene.input.InputMethodHighlight"); InputMethodRequests = Java.type("javafx.scene.input.InputMethodRequests"); InputMethodTextRun = Java.type("javafx.scene.input.InputMethodTextRun"); -InputMethodTextRunBuilder = Java.type("javafx.scene.input.InputMethodTextRunBuilder"); +//InputMethodTextRunBuilder = Java.type("javafx.scene.input.InputMethodTextRunBuilder"); KeyCharacterCombination = Java.type("javafx.scene.input.KeyCharacterCombination"); KeyCharacterCombinationBuilder = Java.type("javafx.scene.input.KeyCharacterCombinationBuilder"); KeyCode = Java.type("javafx.scene.input.KeyCode"); @@ -238,35 +238,35 @@ SwipeEvent = Java.type("javafx.scene.input.SwipeEven TouchEvent = Java.type("javafx.scene.input.TouchEvent"); TouchPoint = Java.type("javafx.scene.input.TouchPoint"); TouchPoint$State = Java.type("javafx.scene.input.TouchPoint$State"); -TouchPointBuilder = Java.type("javafx.scene.input.TouchPointBuilder"); +//TouchPointBuilder = Java.type("javafx.scene.input.TouchPointBuilder"); TransferMode = Java.type("javafx.scene.input.TransferMode"); ZoomEvent = Java.type("javafx.scene.input.ZoomEvent"); AnchorPane = Java.type("javafx.scene.layout.AnchorPane"); AnchorPaneBuilder = Java.type("javafx.scene.layout.AnchorPaneBuilder"); Background = Java.type("javafx.scene.layout.Background"); -BackgroundBuilder = Java.type("javafx.scene.layout.BackgroundBuilder"); +//BackgroundBuilder = Java.type("javafx.scene.layout.BackgroundBuilder"); BackgroundFill = Java.type("javafx.scene.layout.BackgroundFill"); -BackgroundFillBuilder = Java.type("javafx.scene.layout.BackgroundFillBuilder"); +//BackgroundFillBuilder = Java.type("javafx.scene.layout.BackgroundFillBuilder"); BackgroundImage = Java.type("javafx.scene.layout.BackgroundImage"); -BackgroundImageBuilder = Java.type("javafx.scene.layout.BackgroundImageBuilder"); +//BackgroundImageBuilder = Java.type("javafx.scene.layout.BackgroundImageBuilder"); BackgroundPosition = Java.type("javafx.scene.layout.BackgroundPosition"); -BackgroundPositionBuilder = Java.type("javafx.scene.layout.BackgroundPositionBuilder"); +//BackgroundPositionBuilder = Java.type("javafx.scene.layout.BackgroundPositionBuilder"); BackgroundRepeat = Java.type("javafx.scene.layout.BackgroundRepeat"); BackgroundSize = Java.type("javafx.scene.layout.BackgroundSize"); -BackgroundSizeBuilder = Java.type("javafx.scene.layout.BackgroundSizeBuilder"); +//BackgroundSizeBuilder = Java.type("javafx.scene.layout.BackgroundSizeBuilder"); Border = Java.type("javafx.scene.layout.Border"); -BorderBuilder = Java.type("javafx.scene.layout.BorderBuilder"); +//BorderBuilder = Java.type("javafx.scene.layout.BorderBuilder"); BorderImage = Java.type("javafx.scene.layout.BorderImage"); -BorderImageBuilder = Java.type("javafx.scene.layout.BorderImageBuilder"); +//BorderImageBuilder = Java.type("javafx.scene.layout.BorderImageBuilder"); BorderPane = Java.type("javafx.scene.layout.BorderPane"); BorderPaneBuilder = Java.type("javafx.scene.layout.BorderPaneBuilder"); BorderRepeat = Java.type("javafx.scene.layout.BorderRepeat"); BorderStroke = Java.type("javafx.scene.layout.BorderStroke"); -BorderStrokeBuilder = Java.type("javafx.scene.layout.BorderStrokeBuilder"); +//BorderStrokeBuilder = Java.type("javafx.scene.layout.BorderStrokeBuilder"); BorderStrokeStyle = Java.type("javafx.scene.layout.BorderStrokeStyle"); -BorderStrokeStyleBuilder = Java.type("javafx.scene.layout.BorderStrokeStyleBuilder"); +//BorderStrokeStyleBuilder = Java.type("javafx.scene.layout.BorderStrokeStyleBuilder"); BorderWidths = Java.type("javafx.scene.layout.BorderWidths"); -BorderWidthsBuilder = Java.type("javafx.scene.layout.BorderWidthsBuilder"); +//BorderWidthsBuilder = Java.type("javafx.scene.layout.BorderWidthsBuilder"); ColumnConstraints = Java.type("javafx.scene.layout.ColumnConstraints"); ColumnConstraintsBuilder = Java.type("javafx.scene.layout.ColumnConstraintsBuilder"); ConstraintsBase = Java.type("javafx.scene.layout.ConstraintsBase"); @@ -291,7 +291,7 @@ TilePaneBuilder = Java.type("javafx.scene.layout.TilePane VBox = Java.type("javafx.scene.layout.VBox"); VBoxBuilder = Java.type("javafx.scene.layout.VBoxBuilder"); LightBase = Java.type("javafx.scene.LightBase"); -LightBaseBuilder = Java.type("javafx.scene.LightBaseBuilder"); +//LightBaseBuilder = Java.type("javafx.scene.LightBaseBuilder"); Node = Java.type("javafx.scene.Node"); NodeBuilder = Java.type("javafx.scene.NodeBuilder"); Color = Java.type("javafx.scene.paint.Color"); @@ -304,19 +304,19 @@ LinearGradientBuilder = Java.type("javafx.scene.paint.LinearGra Material = Java.type("javafx.scene.paint.Material"); Paint = Java.type("javafx.scene.paint.Paint"); PhongMaterial = Java.type("javafx.scene.paint.PhongMaterial"); -PhongMaterialBuilder = Java.type("javafx.scene.paint.PhongMaterialBuilder"); +//PhongMaterialBuilder = Java.type("javafx.scene.paint.PhongMaterialBuilder"); RadialGradient = Java.type("javafx.scene.paint.RadialGradient"); RadialGradientBuilder = Java.type("javafx.scene.paint.RadialGradientBuilder"); Stop = Java.type("javafx.scene.paint.Stop"); StopBuilder = Java.type("javafx.scene.paint.StopBuilder"); ParallelCamera = Java.type("javafx.scene.ParallelCamera"); -ParallelCameraBuilder = Java.type("javafx.scene.ParallelCameraBuilder"); +//ParallelCameraBuilder = Java.type("javafx.scene.ParallelCameraBuilder"); Parent = Java.type("javafx.scene.Parent"); ParentBuilder = Java.type("javafx.scene.ParentBuilder"); PerspectiveCamera = Java.type("javafx.scene.PerspectiveCamera"); PerspectiveCameraBuilder = Java.type("javafx.scene.PerspectiveCameraBuilder"); PointLight = Java.type("javafx.scene.PointLight"); -PointLightBuilder = Java.type("javafx.scene.PointLightBuilder"); +//PointLightBuilder = Java.type("javafx.scene.PointLightBuilder"); //Scene = Java.type("javafx.scene.Scene"); SceneBuilder = Java.type("javafx.scene.SceneBuilder"); Arc = Java.type("javafx.scene.shape.Arc"); @@ -325,7 +325,7 @@ ArcTo = Java.type("javafx.scene.shape.ArcTo"); ArcToBuilder = Java.type("javafx.scene.shape.ArcToBuilder"); ArcType = Java.type("javafx.scene.shape.ArcType"); Box = Java.type("javafx.scene.shape.Box"); -BoxBuilder = Java.type("javafx.scene.shape.BoxBuilder"); +//BoxBuilder = Java.type("javafx.scene.shape.BoxBuilder"); Circle = Java.type("javafx.scene.shape.Circle"); CircleBuilder = Java.type("javafx.scene.shape.CircleBuilder"); ClosePath = Java.type("javafx.scene.shape.ClosePath"); @@ -336,7 +336,7 @@ CubicCurveTo = Java.type("javafx.scene.shape.CubicCurv CubicCurveToBuilder = Java.type("javafx.scene.shape.CubicCurveToBuilder"); CullFace = Java.type("javafx.scene.shape.CullFace"); Cylinder = Java.type("javafx.scene.shape.Cylinder"); -CylinderBuilder = Java.type("javafx.scene.shape.CylinderBuilder"); +//CylinderBuilder = Java.type("javafx.scene.shape.CylinderBuilder"); DrawMode = Java.type("javafx.scene.shape.DrawMode"); Ellipse = Java.type("javafx.scene.shape.Ellipse"); EllipseBuilder = Java.type("javafx.scene.shape.EllipseBuilder"); @@ -349,7 +349,7 @@ LineTo = Java.type("javafx.scene.shape.LineTo"); LineToBuilder = Java.type("javafx.scene.shape.LineToBuilder"); Mesh = Java.type("javafx.scene.shape.Mesh"); MeshView = Java.type("javafx.scene.shape.MeshView"); -MeshViewBuilder = Java.type("javafx.scene.shape.MeshViewBuilder"); +//MeshViewBuilder = Java.type("javafx.scene.shape.MeshViewBuilder"); MoveTo = Java.type("javafx.scene.shape.MoveTo"); MoveToBuilder = Java.type("javafx.scene.shape.MoveToBuilder"); Path = Java.type("javafx.scene.shape.Path"); @@ -368,10 +368,10 @@ Rectangle = Java.type("javafx.scene.shape.Rectangle RectangleBuilder = Java.type("javafx.scene.shape.RectangleBuilder"); Shape = Java.type("javafx.scene.shape.Shape"); Shape3D = Java.type("javafx.scene.shape.Shape3D"); -Shape3DBuilder = Java.type("javafx.scene.shape.Shape3DBuilder"); +//Shape3DBuilder = Java.type("javafx.scene.shape.Shape3DBuilder"); ShapeBuilder = Java.type("javafx.scene.shape.ShapeBuilder"); Sphere = Java.type("javafx.scene.shape.Sphere"); -SphereBuilder = Java.type("javafx.scene.shape.SphereBuilder"); +//SphereBuilder = Java.type("javafx.scene.shape.SphereBuilder"); StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap"); StrokeLineJoin = Java.type("javafx.scene.shape.StrokeLineJoin"); StrokeType = Java.type("javafx.scene.shape.StrokeType"); @@ -384,7 +384,7 @@ SnapshotParameters = Java.type("javafx.scene.SnapshotParamet SnapshotParametersBuilder = Java.type("javafx.scene.SnapshotParametersBuilder"); SnapshotResult = Java.type("javafx.scene.SnapshotResult"); SubScene = Java.type("javafx.scene.SubScene"); -SubSceneBuilder = Java.type("javafx.scene.SubSceneBuilder"); +//SubSceneBuilder = Java.type("javafx.scene.SubSceneBuilder"); Font = Java.type("javafx.scene.text.Font"); FontBuilder = Java.type("javafx.scene.text.FontBuilder"); FontPosture = Java.type("javafx.scene.text.FontPosture"); @@ -395,7 +395,7 @@ TextAlignment = Java.type("javafx.scene.text.TextAlignm TextBoundsType = Java.type("javafx.scene.text.TextBoundsType"); TextBuilder = Java.type("javafx.scene.text.TextBuilder"); TextFlow = Java.type("javafx.scene.text.TextFlow"); -TextFlowBuilder = Java.type("javafx.scene.text.TextFlowBuilder"); +//TextFlowBuilder = Java.type("javafx.scene.text.TextFlowBuilder"); Affine = Java.type("javafx.scene.transform.Affine"); AffineBuilder = Java.type("javafx.scene.transform.AffineBuilder"); MatrixType = Java.type("javafx.scene.transform.MatrixType"); @@ -407,7 +407,7 @@ ScaleBuilder = Java.type("javafx.scene.transform.Scale Shear = Java.type("javafx.scene.transform.Shear"); ShearBuilder = Java.type("javafx.scene.transform.ShearBuilder"); Transform = Java.type("javafx.scene.transform.Transform"); -TransformBuilder = Java.type("javafx.scene.transform.TransformBuilder"); +//TransformBuilder = Java.type("javafx.scene.transform.TransformBuilder"); TransformChangedEvent = Java.type("javafx.scene.transform.TransformChangedEvent"); Translate = Java.type("javafx.scene.transform.Translate"); TranslateBuilder = Java.type("javafx.scene.transform.TranslateBuilder"); diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/swt.js b/src/jdk/nashorn/internal/runtime/resources/fx/swt.js index 526be750..82197c71 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/swt.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/swt.js @@ -24,6 +24,6 @@ */ CustomTransfer = Java.type("javafx.embed.swt.CustomTransfer"); -CustomTransferBuilder = Java.type("javafx.embed.swt.CustomTransferBuilder"); +//CustomTransferBuilder = Java.type("javafx.embed.swt.CustomTransferBuilder"); FXCanvas = Java.type("javafx.embed.swt.FXCanvas"); SWTFXUtils = Java.type("javafx.embed.swt.SWTFXUtils"); diff --git a/src/jdk/nashorn/internal/runtime/resources/fx/web.js b/src/jdk/nashorn/internal/runtime/resources/fx/web.js index d9099345..606c3c31 100644 --- a/src/jdk/nashorn/internal/runtime/resources/fx/web.js +++ b/src/jdk/nashorn/internal/runtime/resources/fx/web.js @@ -24,10 +24,10 @@ */ HTMLEditor = Java.type("javafx.scene.web.HTMLEditor"); -HTMLEditorBuilder = Java.type("javafx.scene.web.HTMLEditorBuilder"); +//HTMLEditorBuilder = Java.type("javafx.scene.web.HTMLEditorBuilder"); PopupFeatures = Java.type("javafx.scene.web.PopupFeatures"); PromptData = Java.type("javafx.scene.web.PromptData"); -PromptDataBuilder = Java.type("javafx.scene.web.PromptDataBuilder"); +//PromptDataBuilder = Java.type("javafx.scene.web.PromptDataBuilder"); WebEngine = Java.type("javafx.scene.web.WebEngine"); WebEngineBuilder = Java.type("javafx.scene.web.WebEngineBuilder"); WebEvent = Java.type("javafx.scene.web.WebEvent"); -- cgit v1.2.3