8006028: Integrate Joni regexp engine with Nashorn

Reviewed-by: lagergren, attila
This commit is contained in:
Hannes Wallnöfer 2013-02-22 17:00:22 +01:00
parent 1c711a064a
commit 1867421e9b
91 changed files with 17781 additions and 1 deletions
nashorn
THIRD_PARTY_README
docs
src/jdk/nashorn/internal/runtime/regexp

@ -98,3 +98,26 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--- end of LICENSE ---
%% This notice is provided with respect to Joni library which is included
with the Nashorn technology.
--- begin of LICENSE ---
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--- end of LICENSE ---

@ -338,6 +338,15 @@ instead redirect this to a file, specify the path to the file using
this system property.
SYSTEM_PROPERTY: nashorn.regexp.impl=[jdk|joni]
This property defines the regular expression engine to be used by
Nashorn. The default implementation is "jdk" which is based on the
JDK's java.util.regex package. Set this property to "joni" to install
an implementation based on Joni, the regular expression engine used by
the JRuby project.
===============
2. The loggers.
===============

@ -0,0 +1,185 @@
/*
* 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.runtime.regexp;
import jdk.nashorn.internal.runtime.ParserException;
import jdk.nashorn.internal.runtime.regexp.joni.Matcher;
import jdk.nashorn.internal.runtime.regexp.joni.Option;
import jdk.nashorn.internal.runtime.regexp.joni.Regex;
import jdk.nashorn.internal.runtime.regexp.joni.Region;
import jdk.nashorn.internal.runtime.regexp.joni.Syntax;
import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
* Regular expression implementation based on the Joni engine from the JRuby project.
*/
public class JoniRegExp extends RegExp {
/** Compiled Joni Regex */
private Regex regex;
/** Matcher */
private RegExpMatcher matcher;
/**
* Construct a Regular expression from the given {@code pattern} and {@code flags} strings.
*
* @param pattern RegExp pattern string
* @param flags RegExp flag string
* @throws ParserException if flags is invalid or pattern string has syntax error.
*/
public JoniRegExp(final String pattern, final String flags) throws ParserException {
super(pattern, flags);
int option = Option.SINGLELINE;
if (this.isIgnoreCase()) {
option |= Option.IGNORECASE;
}
if (this.isMultiline()) {
option &= ~Option.SINGLELINE;
option |= Option.NEGATE_SINGLELINE;
}
try {
RegExpScanner parsed;
try {
parsed = RegExpScanner.scan(pattern);
} catch (final PatternSyntaxException e) {
// refine the exception with a better syntax error, if this
// passes, just rethrow what we have
Pattern.compile(pattern, 0);
throw e;
}
if (parsed != null) {
char[] javaPattern = parsed.getJavaPattern().toCharArray();
this.regex = new Regex(javaPattern, 0, javaPattern.length, option, Syntax.JAVASCRIPT);
this.groupsInNegativeLookahead = parsed.getGroupsInNegativeLookahead();
}
} catch (final PatternSyntaxException e2) {
throwParserException("syntax", e2.getMessage());
} catch (JOniException e2) {
throwParserException("syntax", e2.getMessage());
}
}
@Override
public RegExpMatcher match(final String input) {
if (regex == null) {
return null;
}
RegExpMatcher matcher = this.matcher;
if (matcher == null || input != matcher.getInput()) {
matcher = new JoniMatcher(input);
this.matcher = matcher;
}
return matcher;
}
/**
* RegExp Factory class for Joni regexp engine.
*/
public static class Factory extends RegExpFactory {
@Override
protected RegExp compile(final String pattern, final String flags) throws ParserException {
return new JoniRegExp(pattern, flags);
}
@Override
protected String replaceToken(final String str) {
return str.equals("[^]") ? "[\\s\\S]" : str;
}
}
class JoniMatcher implements RegExpMatcher {
final String input;
final Matcher matcher;
JoniMatcher(final String input) {
this.input = input;
this.matcher = regex.matcher(input.toCharArray());
}
@Override
public boolean search(final int start) {
return matcher.search(start, input.length(), Option.NONE) > -1;
}
@Override
public String getInput() {
return input;
}
@Override
public int start() {
return matcher.getBegin();
}
@Override
public int start(final int group) {
return group == 0 ? start() : matcher.getRegion().beg[group];
}
@Override
public int end() {
return matcher.getEnd();
}
@Override
public int end(final int group) {
return group == 0 ? end() : matcher.getRegion().end[group];
}
@Override
public String group() {
return input.substring(matcher.getBegin(), matcher.getEnd());
}
@Override
public String group(final int group) {
if (group == 0) {
return group();
}
final Region region = matcher.getRegion();
return input.substring(region.beg[group], region.end[group]);
}
@Override
public int groupCount() {
final Region region = matcher.getRegion();
return region == null ? 0 : region.numRegs - 1;
}
}
}

@ -27,14 +27,34 @@ package jdk.nashorn.internal.runtime.regexp;
import jdk.nashorn.internal.parser.Lexer;
import jdk.nashorn.internal.runtime.ParserException;
import jdk.nashorn.internal.runtime.options.Options;
/**
* Factory class for regular expressions. This class creates instances of {@link DefaultRegExp}.
* An alternative factory can be installed using the {@code nashorn.regexp.impl} system property.
*/
public class RegExpFactory {
private final static RegExpFactory instance = new RegExpFactory();
private final static RegExpFactory instance;
private final static String JDK = "jdk";
private final static String JONI = "joni";
static {
final String impl = Options.getStringProperty("nashorn.regexp.impl", JDK);
switch (impl) {
case JONI:
instance = new JoniRegExp.Factory();
break;
case JDK:
instance = new RegExpFactory();
break;
default:
instance = null;
throw new InternalError("Unsupported RegExp factory: " + impl);
}
}
/**
* Creates a Regular expression from the given {@code pattern} and {@code flags} strings.

File diff suppressed because it is too large Load Diff

@ -0,0 +1,91 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
final class ApplyCaseFold {
// i_apply_case_fold
public void apply(int from, int[]to, int length, Object o) {
ApplyCaseFoldArg arg = (ApplyCaseFoldArg)o;
ScanEnvironment env = arg.env;
CClassNode cc = arg.cc;
BitSet bs = cc.bs;
if (length == 1) {
boolean inCC = cc.isCodeInCC(from);
if (Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS) {
if ((inCC && !cc.isNot()) || (!inCC && cc.isNot())) {
if (to[0] >= BitSet.SINGLE_BYTE_SIZE) {
cc.addCodeRange(env, to[0], to[0]);
} else {
/* /(?i:[^A-C])/.match("a") ==> fail. */
bs.set(to[0]);
}
}
} else {
if (inCC) {
if (to[0] >= BitSet.SINGLE_BYTE_SIZE) {
if (cc.isNot()) cc.clearNotFlag();
cc.addCodeRange(env, to[0], to[0]);
} else {
if (cc.isNot()) {
bs.clear(to[0]);
} else {
bs.set(to[0]);
}
}
}
} // CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
} else {
if (cc.isCodeInCC(from) && (!Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS || !cc.isNot())) {
StringNode node = null;
for (int i=0; i<length; i++) {
if (i == 0) {
node = new StringNode();
/* char-class expanded multi-char only
compare with string folded at match time. */
node.setAmbig();
}
node.catCode(to[i]);
}
ConsAltNode alt = ConsAltNode.newAltNode(node, null);
if (arg.tail == null) {
arg.altRoot = alt;
} else {
arg.tail.setCdr(alt);
}
arg.tail = alt;
}
}
}
static final ApplyCaseFold INSTANCE = new ApplyCaseFold();
}

@ -0,0 +1,35 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
public final class ApplyCaseFoldArg {
final ScanEnvironment env;
final CClassNode cc;
ConsAltNode altRoot;
ConsAltNode tail;
public ApplyCaseFoldArg(ScanEnvironment env, CClassNode cc) {
this.env = env;
this.cc = cc;
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,109 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
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.CTypeNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
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.QuantifierNode;
final class AsmCompiler extends AsmCompilerSupport {
public AsmCompiler(Analyser analyser) {
super(analyser);
}
@Override
protected void prepare() {
REG_NUM++;
prepareMachine();
prepareMachineInit();
prepareMachineMatch();
prepareFactory();
prepareFactoryInit();
}
@Override
protected void finish() {
setupFactoryInit();
setupMachineInit();
setupMachineMatch();
setupClasses();
}
@Override
protected void compileAltNode(ConsAltNode node) {
}
@Override
protected void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
String template = installTemplate(chars, p, strLength);
}
@Override
protected void compileCClassNode(CClassNode node) {
if (node.bs != null) {
String bitsetName = installBitSet(node.bs.bits);
}
}
@Override
protected void compileCTypeNode(CTypeNode node) {
}
@Override
protected void compileAnyCharNode() {
}
@Override
protected void compileBackrefNode(BackRefNode node) {
}
@Override
protected void compileCallNode(CallNode node) {
}
@Override
protected void compileCECQuantifierNode(QuantifierNode node) {
}
@Override
protected void compileNonCECQuantifierNode(QuantifierNode node) {
}
@Override
protected void compileOptionNode(EncloseNode node) {
}
@Override
protected void compileEncloseNode(EncloseNode node) {
}
@Override
protected void compileAnchorNode(AnchorNode node) {
}
}

@ -0,0 +1,267 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import java.io.FileOutputStream;
import java.io.IOException;
import jdk.nashorn.internal.runtime.regexp.joni.constants.AsmConstants;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConstants {
protected ClassWriter factory; // matcher allocator, also bit set, code rage and string template container
protected MethodVisitor factoryInit;// factory constructor
protected String factoryName;
protected ClassWriter machine; // matcher
protected MethodVisitor machineInit;// matcher constructor
protected MethodVisitor match; // actual matcher implementation (the matchAt method)
protected String machineName;
// we will? try to manage visitMaxs ourselves for efficiency
protected int maxStack = 1;
protected int maxVars = LAST_INDEX;
// for field generation
protected int bitsets, ranges, templates;
// simple class name postfix scheme for now
static int REG_NUM = 0;
// dummy class loader for now
private static final class DummyClassLoader extends ClassLoader {
public Class<?> defineClass(String name, byte[] bytes) {
return super.defineClass(name, bytes, 0, bytes.length);
}
};
private static final DummyClassLoader loader = new DummyClassLoader();
AsmCompilerSupport(Analyser analyser) {
super(analyser);
}
protected final void prepareFactory() {
factory = new ClassWriter(ClassWriter.COMPUTE_MAXS);
factoryName = "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory" + REG_NUM;
factory.visit(V1_4, ACC_PUBLIC + ACC_FINAL, factoryName, null, "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory", null);
MethodVisitor create = factory.visitMethod(ACC_SYNTHETIC, "create", "(Lorg/joni/Regex;[BII)Lorg/joni/Matcher;", null, null);
create.visitTypeInsn(NEW, machineName);
create.visitInsn(DUP); // instance
create.visitVarInsn(ALOAD, 1); // Regex
create.visitVarInsn(ALOAD, 2); // bytes[]
create.visitVarInsn(ILOAD, 3); // p
create.visitVarInsn(ILOAD, 4); // end
create.visitMethodInsn(INVOKESPECIAL, machineName, "<init>", "(Lorg/joni/Regex;[BII)V");
create.visitInsn(ARETURN);
create.visitMaxs(0, 0);
//create.visitMaxs(6, 5);
create.visitEnd();
}
protected final void prepareFactoryInit() {
factoryInit = factory.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
factoryInit.visitVarInsn(ALOAD, 0);
factoryInit.visitMethodInsn(INVOKESPECIAL, "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory", "<init>", "()V");
}
protected final void setupFactoryInit() {
factoryInit.visitInsn(RETURN);
factoryInit.visitMaxs(0, 0);
//init.visitMaxs(1, 1);
factoryInit.visitEnd();
}
protected final void prepareMachine() {
machine = new ClassWriter(ClassWriter.COMPUTE_MAXS);
machineName = "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine" + REG_NUM;
}
protected final void prepareMachineInit() {
machine.visit(V1_4, ACC_PUBLIC + ACC_FINAL, machineName, null, "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine", null);
machineInit = machine.visitMethod(ACC_PROTECTED, "<init>", "(Lorg/joni/Regex;[BII)V", null, null);
machineInit.visitVarInsn(ALOAD, THIS); // this
machineInit.visitVarInsn(ALOAD, 1); // Regex
machineInit.visitVarInsn(ALOAD, 2); // bytes[]
machineInit.visitVarInsn(ILOAD, 3); // p
machineInit.visitVarInsn(ILOAD, 4); // end
machineInit.visitMethodInsn(INVOKESPECIAL, "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine", "<init>", "(Lorg/joni/Regex;[BII)V");
}
protected final void setupMachineInit() {
if (bitsets + ranges + templates > 0) { // ok, some of these are in use, we'd like to cache the factory
machine.visitField(ACC_PRIVATE + ACC_FINAL, "factory", "L" + factoryName + ";", null, null);
machineInit.visitVarInsn(ALOAD, THIS); // this
machineInit.visitVarInsn(ALOAD, 1); // this, Regex
machineInit.visitFieldInsn(GETFIELD, "jdk/nashorn/internal/runtime/regexp/joni/Regex", "factory", "Lorg/joni/MatcherFactory;"); // this, factory
machineInit.visitTypeInsn(CHECKCAST, factoryName);
machineInit.visitFieldInsn(PUTFIELD, machineName, "factory", "L" + factoryName + ";"); // []
}
machineInit.visitInsn(RETURN);
machineInit.visitMaxs(0, 0);
//init.visitMaxs(5, 5);
machineInit.visitEnd();
}
protected final void prepareMachineMatch() {
match = machine.visitMethod(ACC_SYNTHETIC, "matchAt", "(III)I", null, null);
move(S, SSTART); // s = sstart
load("bytes", "[B"); //
astore(BYTES); // byte[]bytes = this.bytes
}
protected final void setupMachineMatch() {
match.visitInsn(ICONST_M1);
match.visitInsn(IRETURN);
match.visitMaxs(maxStack, maxVars);
match.visitEnd();
}
protected final void setupClasses() {
byte[]factoryCode = factory.toByteArray();
byte[]machineCode = machine.toByteArray();
if (Config.DEBUG_ASM) {
try {
FileOutputStream fos;
fos = new FileOutputStream(factoryName.substring(factoryName.lastIndexOf('/') + 1) + ".class");
fos.write(factoryCode);
fos.close();
fos = new FileOutputStream(machineName.substring(machineName.lastIndexOf('/') + 1) + ".class");
fos.write(machineCode);
fos.close();
} catch (IOException ioe) {
ioe.printStackTrace(Config.err);
}
}
loader.defineClass(machineName.replace('/', '.'), machineCode);
Class<?> cls = loader.defineClass(factoryName.replace('/', '.'), factoryCode);
try {
regex.factory = (MatcherFactory)cls.newInstance();
} catch(Exception e) {
e.printStackTrace(Config.err);
}
}
protected final void aload(int var) {
match.visitVarInsn(ALOAD, var);
}
protected final void astore(int var) {
match.visitVarInsn(ASTORE, var);
}
protected final void loadThis() {
match.visitVarInsn(ALOAD, THIS);
}
protected final void load(int var) {
match.visitVarInsn(ILOAD, var);
}
protected final void store(int var) {
match.visitVarInsn(ISTORE, var);
}
protected final void move(int to, int from) {
load(from);
store(to);
}
protected final void load(String field, String singature) {
loadThis();
match.visitFieldInsn(GETFIELD, machineName, field, singature);
}
protected final void load(String field) {
load(field, "I");
}
protected final void store(String field, String singature) {
loadThis();
match.visitFieldInsn(PUTFIELD, machineName, field, singature);
}
protected final void store(String field) {
store(field, "I");
}
protected final String installTemplate(char[] arr, int p, int length) {
String templateName = TEMPLATE + ++templates;
installArray(templateName, arr, p, length);
return templateName;
}
protected final String installCodeRange(int[]arr) {
String coreRangeName = CODERANGE + ++ranges;
installArray(coreRangeName, arr);
return coreRangeName;
}
protected final String installBitSet(int[]arr) {
String bitsetName = BITSET + ++bitsets;
installArray(bitsetName, arr);
return bitsetName;
}
private void installArray(String name, int[]arr) {
factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[I", null, null);
factoryInit.visitVarInsn(ALOAD, THIS); // this;
loadInt(factoryInit, arr.length); // this, length
factoryInit.visitIntInsn(NEWARRAY, T_INT); // this, arr
for (int i=0;i < arr.length; i++) buildArray(i, arr[i], IASTORE);
factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[I");
}
private void installArray(String name, char[]arr, int p, int length) {
factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[B", null, null);
factoryInit.visitVarInsn(ALOAD, THIS); // this;
loadInt(factoryInit, arr.length); // this, length
factoryInit.visitIntInsn(NEWARRAY, T_BYTE); // this, arr
for (int i=p, j=0; i < p + length; i++, j++) buildArray(j, arr[i] & 0xff, BASTORE);
factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[B");
}
private void buildArray(int index, int value, int type) {
factoryInit.visitInsn(DUP); // ... arr, arr
loadInt(factoryInit, index); // ... arr, arr, index
loadInt(factoryInit, value); // ... arr, arr, index, value
factoryInit.visitInsn(type); // ... arr
}
private void loadInt(MethodVisitor mv, int value) {
if (value >= -1 && value <= 5) {
mv.visitInsn(value + ICONST_0); // ICONST_0 == 3
} else if (value >= 6 && value <= 127 || value >= -128 && value <= -2) {
mv.visitIntInsn(BIPUSH, value);
} else if (value >= 128 && value <= 32767 || value >= -32768 && value <= -129) {
mv.visitIntInsn(SIPUSH, value);
} else {
mv.visitLdcInsn(new Integer(value));
}
}
}

@ -0,0 +1,115 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public final class BitSet {
static final int BITS_PER_BYTE = 8;
public static final int SINGLE_BYTE_SIZE = (1 << BITS_PER_BYTE);
private static final int BITS_IN_ROOM = 4 * BITS_PER_BYTE;
static final int BITSET_SIZE = (SINGLE_BYTE_SIZE / BITS_IN_ROOM);
static final int ROOM_SHIFT = log2(BITS_IN_ROOM);
final int[] bits = new int[BITSET_SIZE];
private static final int BITS_TO_STRING_WRAP = 4;
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("BitSet");
for (int i=0; i<SINGLE_BYTE_SIZE; i++) {
if ((i % (SINGLE_BYTE_SIZE / BITS_TO_STRING_WRAP)) == 0) buffer.append("\n ");
buffer.append(at(i) ? "1" : "0");
}
return buffer.toString();
}
public boolean at(int pos) {
return (bits[pos >>> ROOM_SHIFT] & bit(pos)) != 0;
}
public void set(int pos) {
bits[pos >>> ROOM_SHIFT] |= bit(pos);
}
public void clear(int pos) {
bits[pos >>> ROOM_SHIFT] &= ~bit(pos);
}
public void invert(int pos) {
bits[pos >>> ROOM_SHIFT] ^= bit(pos);
}
public void clear() {
for (int i=0; i<BITSET_SIZE; i++) bits[i]=0;
}
public boolean isEmpty() {
for (int i=0; i<BITSET_SIZE; i++) {
if (bits[i] != 0) return false;
}
return true;
}
public void setRange(int from, int to) {
for (int i=from; i<=to && i < SINGLE_BYTE_SIZE; i++) set(i);
}
public void setAll() {
for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~0;
}
public void invert() {
for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~bits[i];
}
public void invertTo(BitSet to) {
for (int i=0; i<BITSET_SIZE; i++) to.bits[i] = ~bits[i];
}
public void and(BitSet other) {
for (int i=0; i<BITSET_SIZE; i++) bits[i] &= other.bits[i];
}
public void or(BitSet other) {
for (int i=0; i<BITSET_SIZE; i++) bits[i] |= other.bits[i];
}
public void copy(BitSet other) {
for (int i=0; i<BITSET_SIZE; i++) bits[i] = other.bits[i];
}
public int numOn() {
int num = 0;
for (int i=0; i<SINGLE_BYTE_SIZE; i++) {
if (at(i)) num++;
}
return num;
}
static int bit(int pos){
return 1 << (pos % SINGLE_BYTE_SIZE);
}
private static int log2(int n){
int log = 0;
while ((n >>>= 1) != 0) log++;
return log;
}
}

@ -0,0 +1,55 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
final class BitStatus {
public static final int BIT_STATUS_BITS_NUM = 4 * 8;
public static int bsClear() {
return 0;
}
public static int bsAll() {
return -1;
}
public static boolean bsAt(int stats, int n) {
return (n < BIT_STATUS_BITS_NUM ? stats & (1 << n) : (stats & 1)) != 0;
}
public static int bsOnAt(int stats, int n) {
if (n < BIT_STATUS_BITS_NUM) {
stats |= (1 << n);
} else {
stats |= 1;
}
return stats;
}
public static int bsOnAtSimple(int stats, int n) {
if (n < BIT_STATUS_BITS_NUM) stats |= (1 << n);
return stats;
}
public static int bsOnOff(int v, int f, boolean negative) {
if (negative) {
v &= ~f;
} else {
v |= f;
}
return v;
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,416 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
import jdk.nashorn.internal.runtime.regexp.joni.constants.Arguments;
import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
import jdk.nashorn.internal.runtime.regexp.joni.constants.OPSize;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
class ByteCodePrinter {
final int[]code;
final int codeLength;
final char[][] templates;
Object[]operands;
int operantCount;
WarnCallback warnings;
public ByteCodePrinter(Regex regex) {
code = regex.code;
codeLength = regex.codeLength;
operands = regex.operands;
operantCount = regex.operandLength;
templates = regex.templates;
warnings = regex.warnings;
}
public String byteCodeListToString() {
return compiledByteCodeListToString();
}
private void pString(StringBuilder sb, int len, int s) {
sb.append(":");
while (len-- > 0) sb.append(new String(new byte[]{(byte)code[s++]}));
}
private void pStringFromTemplate(StringBuilder sb, int len, byte[]tm, int idx) {
sb.append(":T:");
while (len-- > 0) sb.append(new String(new byte[]{tm[idx++]}));
}
private void pLenString(StringBuilder sb, int len, int mbLen, int s) {
int x = len * mbLen;
sb.append(":" + len + ":");
while (x-- > 0) sb.append(new String(new byte[]{(byte)code[s++]}));
}
private void pLenStringFromTemplate(StringBuilder sb, int len, int mbLen, char[] tm, int idx) {
int x = len * mbLen;
sb.append(":T:" + len + ":");
while (x-- > 0) sb.append(new String(new byte[]{(byte)tm[idx++]}));
}
public int compiledByteCodeToString(StringBuilder sb, int bp) {
int len, n, mem, addr, scn, cod;
BitSet bs;
CClassNode cc;
int tm, idx;
sb.append("[" + OPCode.OpCodeNames[code[bp]]);
int argType = OPCode.OpCodeArgTypes[code[bp]];
int ip = bp;
if (argType != Arguments.SPECIAL) {
bp++;
switch (argType) {
case Arguments.NON:
break;
case Arguments.RELADDR:
sb.append(":(" + code[bp] + ")");
bp += OPSize.RELADDR;
break;
case Arguments.ABSADDR:
sb.append(":(" + code[bp] + ")");
bp += OPSize.ABSADDR;
break;
case Arguments.LENGTH:
sb.append(":" + code[bp]);
bp += OPSize.LENGTH;
break;
case Arguments.MEMNUM:
sb.append(":" + code[bp]);
bp += OPSize.MEMNUM;
break;
case Arguments.OPTION:
sb.append(":" + code[bp]);
bp += OPSize.OPTION;
break;
case Arguments.STATE_CHECK:
sb.append(":" + code[bp]);
bp += OPSize.STATE_CHECK;
break;
}
} else {
switch (code[bp++]) {
case OPCode.EXACT1:
case OPCode.ANYCHAR_STAR_PEEK_NEXT:
case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT:
case OPCode.ANYCHAR_STAR_PEEK_NEXT_SB:
case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT_SB:
pString(sb, 1, bp++);
break;
case OPCode.EXACT2:
pString(sb, 2, bp);
bp += 2;
break;
case OPCode.EXACT3:
pString(sb, 3, bp);
bp += 3;
break;
case OPCode.EXACT4:
pString(sb, 4, bp);
bp += 4;
break;
case OPCode.EXACT5:
pString(sb, 5, bp);
bp += 5;
break;
case OPCode.EXACTN:
len = code[bp];
bp += OPSize.LENGTH;
if (Config.USE_STRING_TEMPLATES) {
tm = code[bp];
bp += OPSize.INDEX;
idx = code[bp];
bp += OPSize.INDEX;
pLenStringFromTemplate(sb, len, 1, templates[tm], idx);
} else {
pLenString(sb, len, 1, bp);
bp += len;
}
break;
case OPCode.EXACTMB2N1:
pString(sb, 2, bp);
bp += 2;
break;
case OPCode.EXACTMB2N2:
pString(sb, 4, bp);
bp += 4;
break;
case OPCode.EXACTMB2N3:
pString(sb, 6, bp);
bp += 6;
break;
case OPCode.EXACTMB2N:
len = code[bp];
bp += OPSize.LENGTH;
if (Config.USE_STRING_TEMPLATES) {
tm = code[bp];
bp += OPSize.INDEX;
idx = code[bp];
bp += OPSize.INDEX;
pLenStringFromTemplate(sb, len, 2, templates[tm], idx);
} else {
pLenString(sb, len, 2, bp);
bp += len * 2;
}
break;
case OPCode.EXACTMB3N:
len = code[bp];
bp += OPSize.LENGTH;
if (Config.USE_STRING_TEMPLATES) {
tm = code[bp];
bp += OPSize.INDEX;
idx = code[bp];
bp += OPSize.INDEX;
pLenStringFromTemplate(sb, len, 3, templates[tm], idx);
} else {
pLenString(sb, len, 3, bp);
bp += len * 3;
}
break;
case OPCode.EXACTMBN:
int mbLen = code[bp];
bp += OPSize.LENGTH;
len = code[bp];
bp += OPSize.LENGTH;
n = len * mbLen;
if (Config.USE_STRING_TEMPLATES) {
tm = code[bp];
bp += OPSize.INDEX;
idx = code[bp];
bp += OPSize.INDEX;
sb.append(":T:" + mbLen + ":" + len + ":");
while (n-- > 0) sb.append(new String(new char[]{templates[tm][idx++]}));
} else {
sb.append(":" + mbLen + ":" + len + ":");
while (n-- > 0) sb.append(new String(new byte[]{(byte)code[bp++]}));
}
break;
case OPCode.EXACT1_IC:
case OPCode.EXACT1_IC_SB:
final int MAX_CHAR_LENGTH = 6;
byte[]bytes = new byte[MAX_CHAR_LENGTH];
for (int i = 0; bp + i < code.length && i < MAX_CHAR_LENGTH; i++) bytes[i] = (byte)code[bp + i];
pString(sb, 1, bp);
bp++;
break;
case OPCode.EXACTN_IC:
case OPCode.EXACTN_IC_SB:
len = code[bp];
bp += OPSize.LENGTH;
if (Config.USE_STRING_TEMPLATES) {
tm = code[bp];
bp += OPSize.INDEX;
idx = code[bp];
bp += OPSize.INDEX;
pLenStringFromTemplate(sb, len, 1, templates[tm], idx);
} else {
pLenString(sb, len, 1, bp);
bp += len;
}
break;
case OPCode.CCLASS:
case OPCode.CCLASS_SB:
bs = new BitSet();
System.arraycopy(code, bp, bs.bits, 0, BitSet.BITSET_SIZE);
n = bs.numOn();
bp += BitSet.BITSET_SIZE;
sb.append(":" + n);
break;
case OPCode.CCLASS_NOT:
case OPCode.CCLASS_NOT_SB:
bs = new BitSet();
System.arraycopy(code, bp, bs.bits, 0, BitSet.BITSET_SIZE);
n = bs.numOn();
bp += BitSet.BITSET_SIZE;
sb.append(":" + n);
break;
case OPCode.CCLASS_MB:
case OPCode.CCLASS_MB_NOT:
len = code[bp];
bp += OPSize.LENGTH;
cod = code[bp];
//bp += OPSize.CODE_POINT;
bp += len;
sb.append(":" + cod + ":" + len);
break;
case OPCode.CCLASS_MIX:
case OPCode.CCLASS_MIX_NOT:
bs = new BitSet();
System.arraycopy(code, bp, bs.bits, 0, BitSet.BITSET_SIZE);
n = bs.numOn();
bp += BitSet.BITSET_SIZE;
len = code[bp];
bp += OPSize.LENGTH;
cod = code[bp];
//bp += OPSize.CODE_POINT;
bp += len;
sb.append(":" + n + ":" + cod + ":" + len);
break;
case OPCode.CCLASS_NODE:
cc = (CClassNode)operands[code[bp]];
bp += OPSize.POINTER;
n = cc.bs.numOn();
sb.append(":" + cc + ":" + n);
break;
case OPCode.BACKREFN_IC:
mem = code[bp];
bp += OPSize.MEMNUM;
sb.append(":" + mem);
break;
case OPCode.BACKREF_MULTI_IC:
case OPCode.BACKREF_MULTI:
sb.append(" ");
len = code[bp];
bp += OPSize.LENGTH;
for (int i=0; i<len; i++) {
mem = code[bp];
bp += OPSize.MEMNUM;
if (i > 0) sb.append(", ");
sb.append(mem);
}
break;
case OPCode.BACKREF_WITH_LEVEL: {
int option = code[bp];
bp += OPSize.OPTION;
sb.append(":" + option);
int level = code[bp];
bp += OPSize.LENGTH;
sb.append(":" + level);
sb.append(" ");
len = code[bp];
bp += OPSize.LENGTH;
for (int i=0; i<len; i++) {
mem = code[bp];
bp += OPSize.MEMNUM;
if (i > 0) sb.append(", ");
sb.append(mem);
}
break;
}
case OPCode.REPEAT:
case OPCode.REPEAT_NG:
mem = code[bp];
bp += OPSize.MEMNUM;
addr = code[bp];
bp += OPSize.RELADDR;
sb.append(":" + mem + ":" + addr);
break;
case OPCode.PUSH_OR_JUMP_EXACT1:
case OPCode.PUSH_IF_PEEK_NEXT:
addr = code[bp];
bp += OPSize.RELADDR;
sb.append(":(" + addr + ")");
pString(sb, 1, bp);
bp++;
break;
case OPCode.LOOK_BEHIND:
case OPCode.LOOK_BEHIND_SB:
len = code[bp];
bp += OPSize.LENGTH;
sb.append(":" + len);
break;
case OPCode.PUSH_LOOK_BEHIND_NOT:
addr = code[bp];
bp += OPSize.RELADDR;
len = code[bp];
bp += OPSize.LENGTH;
sb.append(":" + len + ":(" + addr + ")");
break;
case OPCode.STATE_CHECK_PUSH:
case OPCode.STATE_CHECK_PUSH_OR_JUMP:
scn = code[bp];
bp += OPSize.STATE_CHECK_NUM;
addr = code[bp];
bp += OPSize.RELADDR;
sb.append(":" + scn + ":(" + addr + ")");
break;
default:
throw new InternalException("undefined code: " + code[--bp]);
}
}
sb.append("]");
// @opcode_address(opcode_size)
if (Config.DEBUG_COMPILE_BYTE_CODE_INFO) sb.append("@" + ip + "(" + (bp - ip) + ")");
return bp;
}
private String compiledByteCodeListToString() {
StringBuilder sb = new StringBuilder();
sb.append("code length: " + codeLength + "\n");
int ncode = 0;
int bp = 0;
int end = codeLength;
while (bp < end) {
ncode++;
if (bp > 0) sb.append(ncode % 5 == 0 ? "\n" : " ");
bp = compiledByteCodeToString(sb, bp);
}
sb.append("\n");
return sb.toString();
}
}

@ -0,0 +1,74 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public class CaptureTreeNode {
int group;
int beg;
int end;
// int allocated;
int numChildren;
CaptureTreeNode[]children;
CaptureTreeNode() {
beg = Region.REGION_NOTPOS;
end = Region.REGION_NOTPOS;
group = -1;
}
static final int HISTORY_TREE_INIT_ALLOC_SIZE = 8;
void addChild(CaptureTreeNode child) {
if (children == null) {
children = new CaptureTreeNode[HISTORY_TREE_INIT_ALLOC_SIZE];
} else if (numChildren >= children.length) {
CaptureTreeNode[]tmp = new CaptureTreeNode[children.length << 1];
System.arraycopy(children, 0, tmp, 0, children.length);
children = tmp;
}
children[numChildren] = child;
numChildren++;
}
void clear() {
for (int i=0; i<numChildren; i++) {
children[i] = null; // ???
}
numChildren = 0;
beg = end = Region.REGION_NOTPOS;
group = -1;
}
CaptureTreeNode cloneTree() {
CaptureTreeNode clone = new CaptureTreeNode();
clone.beg = beg;
clone.end = end;
for (int i=0; i<numChildren; i++) {
CaptureTreeNode child = children[i].cloneTree();
clone.addChild(child);
}
return clone;
}
}

@ -0,0 +1,378 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
public final class CodeRangeBuffer {
private static final int INIT_MULTI_BYTE_RANGE_SIZE = 5;
private static final int ALL_MULTI_BYTE_RANGE = 0x7fffffff;
int[]p;
int used;
public CodeRangeBuffer(int[]ranges) {
p = ranges;
used = ranges[0] + 1;
}
public CodeRangeBuffer() {
p = new int[INIT_MULTI_BYTE_RANGE_SIZE];
writeCodePoint(0, 0);
}
public int[]getCodeRange() {
return p;
}
private CodeRangeBuffer(CodeRangeBuffer orig) {
p = new int[orig.p.length];
System.arraycopy(orig.p, 0, p, 0, p.length);
used = orig.used;
}
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("CodeRange");
buf.append("\n used: " + used);
buf.append("\n code point: " + p[0]);
buf.append("\n ranges: ");
for (int i=0; i<p[0]; i++) {
buf.append("[" + rangeNumToString(p[i * 2 + 1]) + ".." + rangeNumToString(p[i * 2 + 2]) + "]");
if (i > 0 && i % 6 == 0) buf.append("\n ");
}
return buf.toString();
}
private static String rangeNumToString(int num){
return "0x" + Integer.toString(num, 16);
}
public void expand(int low) {
int length = p.length;
do { length <<= 1; } while (length < low);
int[]tmp = new int[length];
System.arraycopy(p, 0, tmp, 0, used);
p = tmp;
}
public void ensureSize(int size) {
int length = p.length;
while (length < size ) { length <<= 1; }
if (p.length != length) {
int[]tmp = new int[length];
System.arraycopy(p, 0, tmp, 0, used);
p = tmp;
}
}
private void moveRight(int from, int to, int n) {
if (to + n > p.length) expand(to + n);
System.arraycopy(p, from, p, to, n);
if (to + n > used) used = to + n;
}
protected void moveLeft(int from, int to, int n) {
System.arraycopy(p, from, p, to, n);
}
private void moveLeftAndReduce(int from, int to) {
System.arraycopy(p, from, p, to, used - from);
used -= from - to;
}
public void writeCodePoint(int pos, int b) {
int u = pos + 1;
if (p.length < u) expand(u);
p[pos] = b;
if (used < u) used = u;
}
public CodeRangeBuffer clone() {
return new CodeRangeBuffer(this);
}
// ugly part: these methods should be made OO
// add_code_range_to_buf
public static CodeRangeBuffer addCodeRangeToBuff(CodeRangeBuffer pbuf, int from, int to) {
if (from > to) {
int n = from;
from = to;
to = n;
}
if (pbuf == null) pbuf = new CodeRangeBuffer(); // move to CClassNode
int[]p = pbuf.p;
int n = p[0];
int low = 0;
int bound = n;
while (low < bound) {
int x = (low + bound) >>> 1;
if (from > p[x * 2 + 2]) {
low = x + 1;
} else {
bound = x;
}
}
int high = low;
bound = n;
while (high < bound) {
int x = (high + bound) >>> 1;
if (to >= p[x * 2 + 1] - 1) {
high = x + 1;
} else {
bound = x;
}
}
int incN = low + 1 - high;
if (n + incN > Config.MAX_MULTI_BYTE_RANGES_NUM) throw new ValueException(ErrorMessages.ERR_TOO_MANY_MULTI_BYTE_RANGES);
if (incN != 1) {
if (from > p[low * 2 + 1]) from = p[low * 2 + 1];
if (to < p[(high - 1) * 2 + 2]) to = p[(high - 1) * 2 + 2];
}
if (incN != 0 && high < n) {
int fromPos = 1 + high * 2;
int toPos = 1 + (low + 1) * 2;
int size = (n - high) * 2;
if (incN > 0) {
pbuf.moveRight(fromPos, toPos, size);
} else {
pbuf.moveLeftAndReduce(fromPos, toPos);
}
}
int pos = 1 + low * 2;
// pbuf.ensureSize(pos + 2);
pbuf.writeCodePoint(pos, from);
pbuf.writeCodePoint(pos + 1, to);
n += incN;
pbuf.writeCodePoint(0, n);
return pbuf;
}
// add_code_range, be aware of it returning null!
public static CodeRangeBuffer addCodeRange(CodeRangeBuffer pbuf, ScanEnvironment env, int from, int to) {
if (from >to) {
if (env.syntax.allowEmptyRangeInCC()) {
return pbuf;
} else {
throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
}
}
return addCodeRangeToBuff(pbuf, from, to);
}
// SET_ALL_MULTI_BYTE_RANGE
protected static CodeRangeBuffer setAllMultiByteRange(CodeRangeBuffer pbuf) {
return addCodeRangeToBuff(pbuf, EncodingHelper.mbcodeStartPosition(), ALL_MULTI_BYTE_RANGE);
}
// ADD_ALL_MULTI_BYTE_RANGE
public static CodeRangeBuffer addAllMultiByteRange(CodeRangeBuffer pbuf) {
return setAllMultiByteRange(pbuf);
}
// not_code_range_buf
public static CodeRangeBuffer notCodeRangeBuff(CodeRangeBuffer bbuf) {
CodeRangeBuffer pbuf = null;
if (bbuf == null) return setAllMultiByteRange(pbuf);
int[]p = bbuf.p;
int n = p[0];
if (n <= 0) return setAllMultiByteRange(pbuf);
int pre = EncodingHelper.mbcodeStartPosition();
int from;
int to = 0;
for (int i=0; i<n; i++) {
from = p[i * 2 + 1];
to = p[i * 2 + 2];
if (pre <= from - 1) {
pbuf = addCodeRangeToBuff(pbuf, pre, from - 1);
}
if (to == ALL_MULTI_BYTE_RANGE) break;
pre = to + 1;
}
if (to < ALL_MULTI_BYTE_RANGE) pbuf = addCodeRangeToBuff(pbuf, to + 1, ALL_MULTI_BYTE_RANGE);
return pbuf;
}
// or_code_range_buf
public static CodeRangeBuffer orCodeRangeBuff(CodeRangeBuffer bbuf1, boolean not1,
CodeRangeBuffer bbuf2, boolean not2) {
CodeRangeBuffer pbuf = null;
if (bbuf1 == null && bbuf2 == null) {
if (not1 || not2) {
return setAllMultiByteRange(pbuf);
}
return null;
}
if (bbuf2 == null) {
CodeRangeBuffer tbuf;
boolean tnot;
// swap
tnot = not1; not1 = not2; not2 = tnot;
tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
}
if (bbuf1 == null) {
if (not1) {
return setAllMultiByteRange(pbuf);
} else {
if (!not2) {
return bbuf2.clone();
} else {
return notCodeRangeBuff(bbuf2);
}
}
}
if (not1) {
CodeRangeBuffer tbuf;
boolean tnot;
// swap
tnot = not1; not1 = not2; not2 = tnot;
tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
}
if (!not2 && !not1) { /* 1 OR 2 */
pbuf = bbuf2.clone();
} else if (!not1) { /* 1 OR (not 2) */
pbuf = notCodeRangeBuff(bbuf2);
}
int[]p1 = bbuf1.p;
int n1 = p1[0];
for (int i=0; i<n1; i++) {
int from = p1[i * 2 + 1];
int to = p1[i * 2 + 2];
pbuf = addCodeRangeToBuff(pbuf, from, to);
}
return pbuf;
}
// and_code_range1
public static CodeRangeBuffer andCodeRange1(CodeRangeBuffer pbuf, int from1, int to1, int[]data, int n) {
for (int i=0; i<n; i++) {
int from2 = data[i * 2 + 1];
int to2 = data[i * 2 + 2];
if (from2 < from1) {
if (to2 < from1) {
continue;
} else {
from1 = to2 + 1;
}
} else if (from2 <= to1) {
if (to2 < to1) {
if (from1 <= from2 - 1) {
pbuf = addCodeRangeToBuff(pbuf, from1, from2 - 1);
}
from1 = to2 + 1;
} else {
to1 = from2 - 1;
}
} else {
from1 = from2;
}
if (from1 > to1) break;
}
if (from1 <= to1) {
pbuf = addCodeRangeToBuff(pbuf, from1, to1);
}
return pbuf;
}
// and_code_range_buf
public static CodeRangeBuffer andCodeRangeBuff(CodeRangeBuffer bbuf1, boolean not1,
CodeRangeBuffer bbuf2, boolean not2) {
CodeRangeBuffer pbuf = null;
if (bbuf1 == null) {
if (not1 && bbuf2 != null) return bbuf2.clone(); /* not1 != 0 -> not2 == 0 */
return null;
} else if (bbuf2 == null) {
if (not2) return bbuf1.clone();
return null;
}
if (not1) {
CodeRangeBuffer tbuf;
boolean tnot;
// swap
tnot = not1; not1 = not2; not2 = tnot;
tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf;
}
int[]p1 = bbuf1.p;
int n1 = p1[0];
int[]p2 = bbuf2.p;
int n2 = p2[0];
if (!not2 && !not1) { /* 1 AND 2 */
for (int i=0; i<n1; i++) {
int from1 = p1[i * 2 + 1];
int to1 = p1[i * 2 + 2];
for (int j=0; j<n2; j++) {
int from2 = p2[j * 2 + 1];
int to2 = p2[j * 2 + 2];
if (from2 > to1) break;
if (to2 < from1) continue;
int from = from1 > from2 ? from1 : from2;
int to = to1 < to2 ? to1 : to2;
pbuf = addCodeRangeToBuff(pbuf, from, to);
}
}
} else if (!not1) { /* 1 AND (not 2) */
for (int i=0; i<n1; i++) {
int from1 = p1[i * 2 + 1];
int to1 = p1[i * 2 + 2];
pbuf = andCodeRange1(pbuf, from1, to1, p2, n2);
}
}
return pbuf;
}
}

@ -0,0 +1,178 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
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.CTypeNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
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.constants.NodeType;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;
abstract class Compiler implements ErrorMessages {
protected final Analyser analyser;
protected final Regex regex;
protected Compiler(Analyser analyser) {
this.analyser = analyser;
this.regex = analyser.regex;
}
final void compile() {
prepare();
compileTree(analyser.root);
finish();
}
protected abstract void prepare();
protected abstract void finish();
protected abstract void compileAltNode(ConsAltNode node);
private void compileStringRawNode(StringNode sn) {
if (sn.length() <= 0) return;
addCompileString(sn.chars, sn.p, 1 /*sb*/, sn.length(), false);
}
private void compileStringNode(StringNode node) {
StringNode sn = node;
if (sn.length() <= 0) return;
boolean ambig = sn.isAmbig();
int p, prev;
p = prev = sn.p;
int end = sn.end;
char[] chars = sn.chars;
p++;
int slen = 1;
while (p < end) {
slen++;
p++;
}
addCompileString(chars, prev, 1, slen, ambig);
}
protected abstract void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase);
protected abstract void compileCClassNode(CClassNode node);
protected abstract void compileCTypeNode(CTypeNode node);
protected abstract void compileAnyCharNode();
protected abstract void compileCallNode(CallNode node);
protected abstract void compileBackrefNode(BackRefNode node);
protected abstract void compileCECQuantifierNode(QuantifierNode node);
protected abstract void compileNonCECQuantifierNode(QuantifierNode node);
protected abstract void compileOptionNode(EncloseNode node);
protected abstract void compileEncloseNode(EncloseNode node);
protected abstract void compileAnchorNode(AnchorNode node);
protected final void compileTree(Node node) {
switch (node.getType()) {
case NodeType.LIST:
ConsAltNode lin = (ConsAltNode)node;
do {
compileTree(lin.car);
} while ((lin = lin.cdr) != null);
break;
case NodeType.ALT:
compileAltNode((ConsAltNode)node);
break;
case NodeType.STR:
StringNode sn = (StringNode)node;
if (sn.isRaw()) {
compileStringRawNode(sn);
} else {
compileStringNode(sn);
}
break;
case NodeType.CCLASS:
compileCClassNode((CClassNode)node);
break;
case NodeType.CTYPE:
compileCTypeNode((CTypeNode)node);
break;
case NodeType.CANY:
compileAnyCharNode();
break;
case NodeType.BREF:
compileBackrefNode((BackRefNode)node);
break;
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
compileCallNode((CallNode)node);
break;
} // USE_SUBEXP_CALL
break;
case NodeType.QTFR:
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
compileCECQuantifierNode((QuantifierNode)node);
} else {
compileNonCECQuantifierNode((QuantifierNode)node);
}
break;
case NodeType.ENCLOSE:
EncloseNode enode = (EncloseNode)node;
if (enode.isOption()) {
compileOptionNode(enode);
} else {
compileEncloseNode(enode);
}
break;
case NodeType.ANCHOR:
compileAnchorNode((AnchorNode)node);
break;
default:
// undefined node type
newInternalException(ERR_PARSER_BUG);
} // switch
}
protected final void compileTreeNTimes(Node node, int n) {
for (int i=0; i<n; i++) compileTree(node);
}
protected void newSyntaxException(String message) {
throw new SyntaxException(message);
}
protected void newInternalException(String message) {
throw new InternalException(message);
}
}

@ -0,0 +1,100 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import java.io.PrintStream;
public interface Config {
final int CHAR_TABLE_SIZE = 256;
/* from jcodings */
final boolean VANILLA = false;
final int INTERNAL_ENC_CASE_FOLD_MULTI_CHAR = (1<<30);
final int ENC_CASE_FOLD_MIN = INTERNAL_ENC_CASE_FOLD_MULTI_CHAR;
final int ENC_CASE_FOLD_DEFAULT = ENC_CASE_FOLD_MIN;
final boolean USE_CRNL_AS_LINE_TERMINATOR = false;
final boolean USE_NAMED_GROUP = true;
final boolean USE_SUBEXP_CALL = true;
final boolean USE_BACKREF_WITH_LEVEL = true; /* \k<name+n>, \k<name-n> */
final boolean USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT = true; /* /(?:()|())*\2/ */
final boolean USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE = true; /* /\n$/ =~ "\n" */
final boolean USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR = false;
final boolean CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS = true;
final boolean USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE = false;
final boolean USE_CAPTURE_HISTORY = false;
final boolean USE_VARIABLE_META_CHARS = true;
final boolean USE_WORD_BEGIN_END = true; /* "\<": word-begin, "\>": word-end */
final boolean USE_POSIX_API_REGION_OPTION = true; /* needed for POSIX API support */
final boolean USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE = true;
final boolean USE_COMBINATION_EXPLOSION_CHECK = false;
final int NREGION = 10;
final int MAX_BACKREF_NUM = 1000;
final int MAX_REPEAT_NUM = 100000;
final int MAX_MULTI_BYTE_RANGES_NUM = 10000;
final boolean USE_WARN = true;
// internal config
final boolean USE_PARSE_TREE_NODE_RECYCLE = true;
final boolean USE_OP_PUSH_OR_JUMP_EXACT = true;
final boolean USE_SHARED_CCLASS_TABLE = false;
final boolean USE_QTFR_PEEK_NEXT = true;
final int INIT_MATCH_STACK_SIZE = 64;
final int DEFAULT_MATCH_STACK_LIMIT_SIZE = 0; /* unlimited */
final int NUMBER_OF_POOLED_STACKS = 4;
final boolean DONT_OPTIMIZE = false;
final boolean USE_STRING_TEMPLATES = true; // use embeded string templates in Regex object as byte arrays instead of compiling them into int bytecode array
final int MAX_CAPTURE_HISTORY_GROUP = 31;
final int CHECK_STRING_THRESHOLD_LEN = 7;
final int CHECK_BUFF_MAX_SIZE = 0x4000;
final boolean NON_UNICODE_SDW = true;
final PrintStream log = System.out;
final PrintStream err = System.err;
final boolean DEBUG_ALL = false;
final boolean DEBUG = DEBUG_ALL;
final boolean DEBUG_PARSE_TREE = DEBUG_ALL;
final boolean DEBUG_PARSE_TREE_RAW = true;
final boolean DEBUG_COMPILE = DEBUG_ALL;
final boolean DEBUG_COMPILE_BYTE_CODE_INFO = DEBUG_ALL;
final boolean DEBUG_SEARCH = DEBUG_ALL;
final boolean DEBUG_MATCH = DEBUG_ALL;
final boolean DEBUG_ASM = true;
final boolean DEBUG_ASM_EXEC = true;
}

@ -0,0 +1,285 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
import java.util.Arrays;
public class EncodingHelper {
public final static char NEW_LINE = 0xa;
public final static char RETURN = 0xd;
final static char[] EMPTYCHARS = new char[0];
final static int[][] codeRanges = new int[15][];
public static int digitVal(int code) {
return code - '0';
}
public static int odigitVal(int code) {
return digitVal(code);
}
public static boolean isXDigit(int code) {
return Character.isDigit(code) || (code >= 'a' && code <= 'f') || (code >= 'A' && code <= 'F');
}
public static int xdigitVal(int code) {
if (Character.isDigit(code)) {
return code - '0';
} else if (code >= 'a' && code <= 'f') {
return code - 'a' + 10;
} else {
return code - 'A' + 10;
}
}
public static boolean isDigit(int code) {
return code >= '0' && code <= '9';
}
public static boolean isWord(int code) {
// letter, digit, or '_'
return (1 << Character.getType(code) & CharacterType.WORD_MASK) != 0;
}
public static boolean isNewLine(int code) {
return code == NEW_LINE;
}
public static boolean isNewLine(char[] chars, int p, int end) {
return p < end && chars[p] == NEW_LINE;
}
public static boolean isCrnl(char[] chars, int p, int end) {
return p + 1 < end && chars[p] == RETURN && chars[p + 1] == NEW_LINE;
}
// Encoding.prevCharHead
public static int prevCharHead(int p, int s) {
return s <= p ? -1 : s - 1;
}
/* onigenc_get_right_adjust_char_head_with_prev */
public static int rightAdjustCharHeadWithPrev(int s, IntHolder prev) {
if (prev != null) prev.value = -1; /* Sorry */
return s;
}
// Encoding.stepBack
public static int stepBack(int p, int s, int n) {
while (s != -1 && n-- > 0) {
if (s <= p) return -1;
s--;
}
return s;
}
/* onigenc_with_ascii_strncmp */
public static int strNCmp(char[] chars1, int p1, int end, char[] chars2, int p2, int n) {
while (n-- > 0) {
if (p1 >= end) return chars2[p2];
int c = chars1[p1];
int x = chars2[p2] - c;
if (x != 0) return x;
p2++;
p1++;
}
return 0;
}
public static int mbcToCode(byte[] bytes, int p, int end) {
int code = 0;
for (int i = p; i < end; i++) {
code = (code << 8) | (bytes[i] & 0xff);
}
return code;
}
public static int mbcodeStartPosition() {
return 0x80;
}
public static char[] caseFoldCodesByString(int flag, char c) {
if (Character.isUpperCase(c)) {
return new char[] {Character.toLowerCase(c)};
} else if (Character.isLowerCase(c)) {
return new char[] {Character.toUpperCase(c)};
} else {
return EMPTYCHARS;
}
}
public static void applyAllCaseFold(int flag, ApplyCaseFold fun, Object arg) {
int[] code = new int[1];
for (int c = 0; c < 0xffff; c++) {
if (Character.getType(c) == Character.LOWERCASE_LETTER) {
int upper = code[0] = Character.toUpperCase(c);
fun.apply(c, code, 1, arg);
code[0] = c;
fun.apply(upper, code, 1, arg);
}
}
}
// CodeRange.isInCodeRange
public static boolean isInCodeRange(int[]p, int code) {
int low = 0;
int n = p[0];
int high = n;
while (low < high) {
int x = (low + high) >> 1;
if (code > p[(x << 1) + 2]) {
low = x + 1;
} else {
high = x;
}
}
return low < n && code >= p[(low << 1) + 1];
}
public static int[] ctypeCodeRange(int ctype, IntHolder sbOut) {
sbOut.value = 0x100; // use bitset for codes smaller than 256
int[] range = null;
if (ctype < codeRanges.length) {
range = codeRanges[ctype];
if (range == null) {
// format: [numberOfRanges, rangeStart, rangeEnd, ...]
range = new int[16];
int rangeCount = 0;
int lastCode = -2;
for (int code = 0; code <= 0xffff; code++) {
if (isCodeCType(code, ctype)) {
if (lastCode < code -1) {
if (rangeCount * 2 + 2 >= range.length) {
range = Arrays.copyOf(range, range.length * 2);
}
range[rangeCount * 2 + 1] = code;
rangeCount++;
}
range[rangeCount * 2] = lastCode = code;
}
}
if (rangeCount * 2 + 1 < range.length) {
range = Arrays.copyOf(range, rangeCount * 2 + 1);
}
range[0] = rangeCount;
codeRanges[ctype] = range;
}
}
return range;
}
// CodeRange.isInCodeRange
public static boolean isInCodeRange(int[]p, int offset, int code) {
int low = 0;
int n = p[offset];
int high = n ;
while (low < high) {
int x = (low + high) >> 1;
if (code > p[(x << 1) + 2 + offset]) {
low = x + 1;
} else {
high = x;
}
}
return low < n && code >= p[(low << 1) + 1 + offset];
}
/**
* @see [http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt]
*/
public static boolean isCodeCType(int code, int ctype) {
int type;
switch (ctype) {
case CharacterType.NEWLINE:
return code == EncodingHelper.NEW_LINE;
case CharacterType.ALPHA:
return (1 << Character.getType(code) & CharacterType.ALPHA_MASK) != 0;
case CharacterType.BLANK:
return code == 0x09 || Character.getType(code) == Character.SPACE_SEPARATOR;
case CharacterType.CNTRL:
type = Character.getType(code);
return (1 << type & CharacterType.CNTRL_MASK) != 0 || type == Character.UNASSIGNED;
case CharacterType.DIGIT:
return EncodingHelper.isDigit(code);
case CharacterType.GRAPH:
switch (code) {
case 0x09:
case 0x0a:
case 0x0b:
case 0x0c:
case 0x0d:
return false;
default:
type = Character.getType(code);
return (1 << type & CharacterType.GRAPH_MASK) == 0 && type != Character.UNASSIGNED;
}
case CharacterType.LOWER:
return Character.isLowerCase(code);
case CharacterType.PRINT:
type = Character.getType(code);
return (1 << type & CharacterType.PRINT_MASK) == 0 && type != Character.UNASSIGNED;
case CharacterType.PUNCT:
return (1 << Character.getType(code) & CharacterType.PUNCT_MASK) != 0;
case CharacterType.SPACE:
// ECMA 7.2 and 7.3
switch (code) {
case 0x09:
case 0x0a:
case 0x0b:
case 0x0c:
case 0x0d:
return true;
default:
// true if Unicode separator or BOM
return (1 << Character.getType(code) & CharacterType.SPACE_MASK) != 0 || code == 0xfeff;
}
case CharacterType.UPPER:
return Character.isUpperCase(code);
case CharacterType.XDIGIT:
return EncodingHelper.isXDigit(code);
case CharacterType.WORD:
return (1 << Character.getType(code) & CharacterType.WORD_MASK) != 0;
case CharacterType.ALNUM:
return (1 << Character.getType(code) & CharacterType.ALNUM_MASK) != 0;
case CharacterType.ASCII:
return code < 0x80;
default:
throw new RuntimeException("illegal character type: " + ctype);
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,556 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindLongest;
import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
public abstract class Matcher extends IntHolder {
protected final Regex regex;
protected final char[] chars;
protected final int str;
protected final int end;
protected int msaStart;
protected int msaOptions;
protected final Region msaRegion;
protected int msaBestLen;
protected int msaBestS;
protected int msaBegin;
protected int msaEnd;
public Matcher(Regex regex, char[] chars) {
this(regex, chars, 0, chars.length);
}
public Matcher(Regex regex, char[] chars, int p, int end) {
this.regex = regex;
this.chars = chars;
this.str = p;
this.end = end;
this.msaRegion = regex.numMem == 0 ? null : new Region(regex.numMem + 1);
}
// main matching method
protected abstract int matchAt(int range, int sstart, int sprev);
protected abstract void stateCheckBuffInit(int strLength, int offset, int stateNum);
protected abstract void stateCheckBuffClear();
public final Region getRegion() {
return msaRegion;
}
public final Region getEagerRegion() {
return msaRegion != null ? msaRegion : new Region(msaBegin, msaEnd);
}
public final int getBegin() {
return msaBegin;
}
public final int getEnd() {
return msaEnd;
}
protected final void msaInit(int option, int start) {
msaOptions = option;
msaStart = start;
if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) msaBestLen = -1;
}
public final int match(int at, int range, int option) {
msaInit(option, at);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
int offset = at = str;
stateCheckBuffInit(end - str, offset, regex.numCombExpCheck); // move it to construction?
} // USE_COMBINATION_EXPLOSION_CHECK
int prev = EncodingHelper.prevCharHead(str, at);
if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
return matchAt(end /*range*/, at, prev);
} else {
return matchAt(range /*range*/, at, prev);
}
}
int low, high; // these are the return values
private boolean forwardSearchRange(char[] chars, int str, int end, int s, int range, IntHolder lowPrev) {
int pprev = -1;
int p = s;
if (Config.DEBUG_SEARCH) {
Config.log.println("forward_search_range: "+
"str: " + str +
", end: " + end +
", s: " + s +
", range: " + range);
}
if (regex.dMin > 0) {
p += regex.dMin;
}
retry:while (true) {
p = regex.searchAlgorithm.search(regex, chars, p, end, range);
if (p != -1 && p < range) {
if (p - regex.dMin < s) {
// retry_gate:
pprev = p;
p++;
continue retry;
}
if (regex.subAnchor != 0) {
switch (regex.subAnchor) {
case AnchorType.BEGIN_LINE:
if (p != str) {
int prev = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, p);
if (!EncodingHelper.isNewLine(chars, prev, end)) {
// goto retry_gate;
pprev = p;
p++;
continue retry;
}
}
break;
case AnchorType.END_LINE:
if (p == end) {
if (!Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
int prev = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, p);
if (prev != -1 && EncodingHelper.isNewLine(chars, prev, end)) {
// goto retry_gate;
pprev = p;
p++;
continue retry;
}
}
} else if (!EncodingHelper.isNewLine(chars, p, end) && (!Config.USE_CRNL_AS_LINE_TERMINATOR || !EncodingHelper.isCrnl(chars, p, end))) {
//if () break;
// goto retry_gate;
pprev = p;
p++;
continue retry;
}
break;
} // switch
}
if (regex.dMax == 0) {
low = p;
if (lowPrev != null) { // ??? // remove null checks
if (low > s) {
lowPrev.value = EncodingHelper.prevCharHead(s, p);
} else {
lowPrev.value = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, p);
}
}
} else {
if (regex.dMax != MinMaxLen.INFINITE_DISTANCE) {
low = p - regex.dMax;
if (low > s) {
low = EncodingHelper.rightAdjustCharHeadWithPrev(low, lowPrev);
if (lowPrev != null && lowPrev.value == -1) {
lowPrev.value = EncodingHelper.prevCharHead((pprev != -1) ? pprev : s, low);
}
} else {
if (lowPrev != null) {
lowPrev.value = EncodingHelper.prevCharHead((pprev != -1) ? pprev : str, low);
}
}
}
}
/* no needs to adjust *high, *high is used as range check only */
high = p - regex.dMin;
if (Config.DEBUG_SEARCH) {
Config.log.println("forward_search_range success: "+
"low: " + (low - str) +
", high: " + (high - str) +
", dmin: " + regex.dMin +
", dmax: " + regex.dMax);
}
return true; /* success */
}
return false; /* fail */
} //while
}
// low, high
private boolean backwardSearchRange(char[] chars, int str, int end, int s, int range, int adjrange) {
range += regex.dMin;
int p = s;
retry:while (true) {
p = regex.searchAlgorithm.searchBackward(regex, chars, range, adjrange, end, p, s, range);
if (p != -1) {
if (regex.subAnchor != 0) {
switch (regex.subAnchor) {
case AnchorType.BEGIN_LINE:
if (p != str) {
int prev = EncodingHelper.prevCharHead(str, p);
if (!EncodingHelper.isNewLine(chars, prev, end)) {
p = prev;
continue retry;
}
}
break;
case AnchorType.END_LINE:
if (p == end) {
if (!Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
int prev = EncodingHelper.prevCharHead(adjrange, p);
if (prev == -1) return false;
if (EncodingHelper.isNewLine(chars, prev, end)) {
p = prev;
continue retry;
}
}
} else if (!EncodingHelper.isNewLine(chars, p, end) && (!Config.USE_CRNL_AS_LINE_TERMINATOR || !EncodingHelper.isCrnl(chars, p, end))) {
p = EncodingHelper.prevCharHead(adjrange, p);
if (p == -1) return false;
continue retry;
}
break;
} // switch
}
/* no needs to adjust *high, *high is used as range check only */
if (regex.dMax != MinMaxLen.INFINITE_DISTANCE) {
low = p - regex.dMax;
high = p - regex.dMin;
}
if (Config.DEBUG_SEARCH) {
Config.log.println("backward_search_range: "+
"low: " + (low - str) +
", high: " + (high - str));
}
return true;
}
if (Config.DEBUG_SEARCH) Config.log.println("backward_search_range: fail.");
return false;
} // while
}
// MATCH_AND_RETURN_CHECK
private boolean matchCheck(int upperRange, int s, int prev) {
if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
//range = upperRange;
if (matchAt(upperRange, s, prev) != -1) {
if (!isFindLongest(regex.options)) return true;
}
} else {
//range = upperRange;
if (matchAt(upperRange, s, prev) != -1) return true;
}
} else {
if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
if (matchAt(end, s, prev) != -1) {
//range = upperRange;
if (!isFindLongest(regex.options)) return true;
}
} else {
//range = upperRange;
if (matchAt(end, s, prev) != -1) return true;
}
}
return false;
}
public final int search(int start, int range, int option) {
int s, prev;
int origStart = start;
int origRange = range;
if (Config.DEBUG_SEARCH) {
Config.log.println("onig_search (entry point): "+
"str: " + str +
", end: " + (end - str) +
", start: " + (start - str) +
", range " + (range - str));
}
if (start > end || start < str) return -1;
/* anchor optimize: resume search range */
if (regex.anchor != 0 && str < end) {
int minSemiEnd, maxSemiEnd;
if ((regex.anchor & AnchorType.BEGIN_POSITION) != 0) {
/* search start-position only */
// !begin_position:!
if (range > start) {
range = start + 1;
} else {
range = start;
}
} else if ((regex.anchor & AnchorType.BEGIN_BUF) != 0) {
/* search str-position only */
if (range > start) {
if (start != str) return -1; // mismatch_no_msa;
range = str + 1;
} else {
if (range <= str) {
start = str;
range = str;
} else {
return -1; // mismatch_no_msa;
}
}
} else if ((regex.anchor & AnchorType.END_BUF) != 0) {
minSemiEnd = maxSemiEnd = end;
// !end_buf:!
if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
} else if ((regex.anchor & AnchorType.SEMI_END_BUF) != 0) {
int preEnd = EncodingHelper.stepBack(str, end, 1);
maxSemiEnd = end;
if (EncodingHelper.isNewLine(chars, preEnd, end)) {
minSemiEnd = preEnd;
if (Config.USE_CRNL_AS_LINE_TERMINATOR) {
preEnd = EncodingHelper.stepBack(str, preEnd, 1);
if (preEnd != -1 && EncodingHelper.isCrnl(chars, preEnd, end)) {
minSemiEnd = preEnd;
}
}
if (minSemiEnd > str && start <= minSemiEnd) {
// !goto end_buf;!
if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
}
} else {
minSemiEnd = end;
// !goto end_buf;!
if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
}
} else if ((regex.anchor & AnchorType.ANYCHAR_STAR_ML) != 0) {
// goto !begin_position;!
if (range > start) {
range = start + 1;
} else {
range = start;
}
}
} else if (str == end) { /* empty string */
// empty address ?
if (Config.DEBUG_SEARCH) {
Config.log.println("onig_search: empty string.");
}
if (regex.thresholdLength == 0) {
s = start = str;
prev = -1;
msaInit(option, start);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) stateCheckBuffClear();
if (matchCheck(end, s, prev)) return match(s);
return mismatch();
}
return -1; // goto mismatch_no_msa;
}
if (Config.DEBUG_SEARCH) {
Config.log.println("onig_search(apply anchor): " +
"end: " + (end - str) +
", start " + (start - str) +
", range " + (range - str));
}
msaInit(option, origStart);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
int offset = Math.min(start, range) - str;
stateCheckBuffInit(end - str, offset, regex.numCombExpCheck);
}
s = start;
if (range > start) { /* forward search */
if (s > str) {
prev = EncodingHelper.prevCharHead(str, s);
} else {
prev = 0; // -1
}
if (regex.searchAlgorithm != SearchAlgorithm.NONE) {
int schRange = range;
if (regex.dMax != 0) {
if (regex.dMax == MinMaxLen.INFINITE_DISTANCE) {
schRange = end;
} else {
schRange += regex.dMax;
if (schRange > end) schRange = end;
}
}
if ((end - start) < regex.thresholdLength) return mismatch();
if (regex.dMax != MinMaxLen.INFINITE_DISTANCE) {
do {
if (!forwardSearchRange(chars, str, end, s, schRange, this)) return mismatch(); // low, high, lowPrev
if (s < low) {
s = low;
prev = value;
}
while (s <= high) {
if (matchCheck(origRange, s, prev)) return match(s); // ???
prev = s;
s++;
}
} while (s < range);
return mismatch();
} else { /* check only. */
if (!forwardSearchRange(chars, str, end, s, schRange, null)) return mismatch();
if ((regex.anchor & AnchorType.ANYCHAR_STAR) != 0) {
do {
if (matchCheck(origRange, s, prev)) return match(s);
prev = s;
s++;
} while (s < range);
return mismatch();
}
}
}
do {
if (matchCheck(origRange, s, prev)) return match(s);
prev = s;
s++;
} while (s < range);
if (s == range) { /* because empty match with /$/. */
if (matchCheck(origRange, s, prev)) return match(s);
}
} else { /* backward search */
if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
if (origStart < end) {
origStart++; // /* is upper range */
}
}
if (regex.searchAlgorithm != SearchAlgorithm.NONE) {
int adjrange;
if (range < end) {
adjrange = range;
} else {
adjrange = end;
}
if (regex.dMax != MinMaxLen.INFINITE_DISTANCE && (end - range) >= regex.thresholdLength) {
do {
int schStart = s + regex.dMax;
if (schStart > end) schStart = end;
if (!backwardSearchRange(chars, str, end, schStart, range, adjrange)) return mismatch(); // low, high
if (s > high) s = high;
while (s != -1 && s >= low) {
prev = EncodingHelper.prevCharHead(str, s);
if (matchCheck(origStart, s, prev)) return match(s);
s = prev;
}
} while (s >= range);
return mismatch();
} else { /* check only. */
if ((end - range) < regex.thresholdLength) return mismatch();
int schStart = s;
if (regex.dMax != 0) {
if (regex.dMax == MinMaxLen.INFINITE_DISTANCE) {
schStart = end;
} else {
schStart += regex.dMax;
if (schStart > end) {
schStart = end;
}
}
}
if (!backwardSearchRange(chars, str, end, schStart, range, adjrange)) return mismatch();
}
}
do {
prev = EncodingHelper.prevCharHead(str, s);
if (matchCheck(origStart, s, prev)) return match(s);
s = prev;
} while (s >= range);
}
return mismatch();
}
private boolean endBuf(int start, int range, int minSemiEnd, int maxSemiEnd) {
if ((maxSemiEnd - str) < regex.anchorDmin) return true; // mismatch_no_msa;
if (range > start) {
if ((minSemiEnd - start) > regex.anchorDmax) {
start = minSemiEnd - regex.anchorDmax;
if (start >= end) {
/* match with empty at end */
start = EncodingHelper.prevCharHead(str, end);
}
}
if ((maxSemiEnd - (range - 1)) < regex.anchorDmin) {
range = maxSemiEnd - regex.anchorDmin + 1;
}
if (start >= range) return true; // mismatch_no_msa;
} else {
if ((minSemiEnd - range) > regex.anchorDmax) {
range = minSemiEnd - regex.anchorDmax;
}
if ((maxSemiEnd - start) < regex.anchorDmin) {
start = maxSemiEnd - regex.anchorDmin;
}
if (range > start) return true; // mismatch_no_msa;
}
return false;
}
private int match(int s) {
return s - str; // sstart ???
}
private int mismatch() {
if (Config.USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE) {
if (msaBestLen >= 0) {
int s = msaBestS;
return match(s);
}
}
// falls through finish:
return -1;
}
}

@ -0,0 +1,31 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public abstract class MatcherFactory {
public abstract Matcher create(Regex regex, char[] chars, int p, int end);
static final MatcherFactory DEFAULT = new MatcherFactory() {
@Override
public Matcher create(Regex regex, char[] chars, int p, int end) {
return new ByteCodeMachine(regex, chars, p, end);
}
};
}

@ -0,0 +1,139 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
final class MinMaxLen {
int min; /* min byte length */
int max; /* max byte length */
MinMaxLen() {
}
MinMaxLen(int min, int max) {
this.min = min;
this.max = max;
}
/* 1000 / (min-max-dist + 1) */
private static final short distValues[] = {
1000, 500, 333, 250, 200, 167, 143, 125, 111, 100,
91, 83, 77, 71, 67, 63, 59, 56, 53, 50,
48, 45, 43, 42, 40, 38, 37, 36, 34, 33,
32, 31, 30, 29, 29, 28, 27, 26, 26, 25,
24, 24, 23, 23, 22, 22, 21, 21, 20, 20,
20, 19, 19, 19, 18, 18, 18, 17, 17, 17,
16, 16, 16, 16, 15, 15, 15, 15, 14, 14,
14, 14, 14, 14, 13, 13, 13, 13, 13, 13,
12, 12, 12, 12, 12, 12, 11, 11, 11, 11,
11, 11, 11, 11, 11, 10, 10, 10, 10, 10
};
int distanceValue() {
if (max == INFINITE_DISTANCE) return 0;
int d = max - min;
/* return dist_vals[d] * 16 / (mm->min + 12); */
return d < distValues.length ? distValues[d] : 1;
}
int compareDistanceValue(MinMaxLen other, int v1, int v2) {
if (v2 <= 0) return -1;
if (v1 <= 0) return 1;
v1 *= distanceValue();
v2 *= other.distanceValue();
if (v2 > v1) return 1;
if (v2 < v1) return -1;
if (other.min < min) return 1;
if (other.min > min) return -1;
return 0;
}
boolean equal(MinMaxLen other) {
return min == other.min && max == other.max;
}
void set(int min, int max) {
this.min = min;
this.max = max;
}
void clear() {
min = max = 0;
}
void copy(MinMaxLen other) {
min = other.min;
max = other.max;
}
void add(MinMaxLen other) {
min = distanceAdd(min, other.min);
max = distanceAdd(max, other.max);
}
void addLength(int len) {
min = distanceAdd(min, len);
max = distanceAdd(max, len);
}
void altMerge(MinMaxLen other) {
if (min > other.min) min = other.min;
if (max < other.max) max = other.max;
}
static final int INFINITE_DISTANCE = 0x7FFFFFFF;
static int distanceAdd(int d1, int d2) {
if (d1 == INFINITE_DISTANCE || d2 == INFINITE_DISTANCE) {
return INFINITE_DISTANCE;
} else {
if (d1 <= INFINITE_DISTANCE - d2) return d1 + d2;
else return INFINITE_DISTANCE;
}
}
static int distanceMultiply(int d, int m) {
if (m == 0) return 0;
if (d < INFINITE_DISTANCE / m) {
return d * m;
} else {
return INFINITE_DISTANCE;
}
}
static String distanceRangeToString(int a, int b) {
String s = "";
if (a == INFINITE_DISTANCE) {
s += "inf";
} else {
s += "(" + a + ")";
}
s += "-";
if (b == INFINITE_DISTANCE) {
s += "inf";
} else {
s += "(" + b + ")";
}
return s;
}
}

@ -0,0 +1,97 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public final class NameEntry {
static final int INIT_NAME_BACKREFS_ALLOC_NUM = 8;
public final char[] name;
public final int nameP;
public final int nameEnd;
int backNum;
int backRef1;
int backRefs[];
public NameEntry(char[] chars, int p, int end) {
name = chars;
nameP = p;
nameEnd = end;
}
public int[] getBackRefs() {
switch (backNum) {
case 0:
return new int[]{};
case 1:
return new int[]{backRef1};
default:
int[]result = new int[backNum];
System.arraycopy(backRefs, 0, result, 0, backNum);
return result;
}
}
private void alloc() {
backRefs = new int[INIT_NAME_BACKREFS_ALLOC_NUM];
}
private void ensureSize() {
if (backNum > backRefs.length) {
int[]tmp = new int[backRefs.length << 1];
System.arraycopy(backRefs, 0, tmp, 0, backRefs.length);
backRefs = tmp;
}
}
public void addBackref(int backRef) {
backNum++;
switch (backNum) {
case 1:
backRef1 = backRef;
break;
case 2:
alloc();
backRefs[0] = backRef1;
backRefs[1] = backRef;
break;
default:
ensureSize();
backRefs[backNum - 1] = backRef;
}
}
public String toString() {
StringBuilder buff = new StringBuilder(new String(name, nameP, nameEnd - nameP) + " ");
if (backNum == 0) {
buff.append("-");
} else if (backNum == 1){
buff.append(backRef1);
} else {
for (int i=0; i<backNum; i++){
if (i > 0) buff.append(", ");
buff.append(backRefs[i]);
}
}
return buff.toString();
}
}

@ -0,0 +1,27 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public abstract class NativeMachine extends Matcher {
protected NativeMachine(Regex regex, char[] chars, int p, int end) {
super(regex, chars, p, end);
}
}

@ -0,0 +1,125 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public final class NodeOptInfo {
final MinMaxLen length = new MinMaxLen();
final OptAnchorInfo anchor = new OptAnchorInfo();
final OptExactInfo exb = new OptExactInfo(); /* boundary */
final OptExactInfo exm = new OptExactInfo(); /* middle */
final OptExactInfo expr = new OptExactInfo(); /* prec read (?=...) */
final OptMapInfo map = new OptMapInfo(); /* boundary */
public void setBoundNode(MinMaxLen mmd) {
exb.mmd.copy(mmd);
expr.mmd.copy(mmd);
map.mmd.copy(mmd);
}
public void clear() {
length.clear();
anchor.clear();
exb.clear();
exm.clear();
expr.clear();
map.clear();
}
public void copy(NodeOptInfo other) {
length.copy(other.length);
anchor.copy(other.anchor);
exb.copy(other.exb);
exm.copy(other.exm);
expr.copy(other.expr);
map.copy(other.map);
}
public void concatLeftNode(NodeOptInfo other) {
OptAnchorInfo tanchor = new OptAnchorInfo(); // remove it somehow ?
tanchor.concat(anchor, other.anchor, length.max, other.length.max);
anchor.copy(tanchor);
if (other.exb.length > 0 && length.max == 0) {
tanchor.concat(anchor, other.exb.anchor, length.max, other.length.max);
other.exb.anchor.copy(tanchor);
}
if (other.map.value > 0 && length.max == 0) {
if (other.map.mmd.max == 0) {
other.map.anchor.leftAnchor |= anchor.leftAnchor;
}
}
boolean exbReach = exb.reachEnd;
boolean exmReach = exm.reachEnd;
if (other.length.max != 0) {
exb.reachEnd = exm.reachEnd = false;
}
if (other.exb.length > 0) {
if (exbReach) {
exb.concat(other.exb);
other.exb.clear();
} else if (exmReach) {
exm.concat(other.exb);
other.exb.clear();
}
}
exm.select(other.exb);
exm.select(other.exm);
if (expr.length > 0) {
if (other.length.max > 0) {
// TODO: make sure it is not an Oniguruma bug (casting unsigned int to int for arithmetic comparison)
int otherLengthMax = other.length.max;
if (otherLengthMax == MinMaxLen.INFINITE_DISTANCE) otherLengthMax = -1;
if (expr.length > otherLengthMax) expr.length = otherLengthMax;
if (expr.mmd.max == 0) {
exb.select(expr);
} else {
exm.select(expr);
}
}
} else if (other.expr.length > 0) {
expr.copy(other.expr);
}
map.select(other.map);
length.add(other.length);
}
public void altMerge(NodeOptInfo other, OptEnvironment env) {
anchor.altMerge(other.anchor);
exb.altMerge(other.exb, env);
exm.altMerge(other.exm, env);
expr.altMerge(other.expr, env);
map.altMerge(other.map);
length.altMerge(other.length);
}
public void setBound(MinMaxLen mmd) {
exb.mmd.copy(mmd);
expr.mmd.copy(mmd);
map.mmd.copy(mmd);
}
}

@ -0,0 +1,92 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
final class OptAnchorInfo implements AnchorType {
int leftAnchor;
int rightAnchor;
void clear() {
leftAnchor = rightAnchor = 0;
}
void copy(OptAnchorInfo other) {
leftAnchor = other.leftAnchor;
rightAnchor = other.rightAnchor;
}
void concat(OptAnchorInfo left, OptAnchorInfo right, int leftLength, int rightLength) {
leftAnchor = left.leftAnchor;
if (leftLength == 0) leftAnchor |= right.leftAnchor;
rightAnchor = right.rightAnchor;
if (rightLength == 0) rightAnchor |= left.rightAnchor;
}
boolean isSet(int anchor) {
if ((leftAnchor & anchor) != 0) return true;
return (rightAnchor & anchor) != 0;
}
void add(int anchor) {
if (isLeftAnchor(anchor)) {
leftAnchor |= anchor;
} else {
rightAnchor |= anchor;
}
}
void remove(int anchor) {
if (isLeftAnchor(anchor)) {
leftAnchor &= ~anchor;
} else {
rightAnchor &= ~anchor;
}
}
void altMerge(OptAnchorInfo other) {
leftAnchor &= other.leftAnchor;
rightAnchor &= other.rightAnchor;
}
static boolean isLeftAnchor(int anchor) { // make a mask for it ?
return !(anchor == END_BUF || anchor == SEMI_END_BUF ||
anchor == END_LINE || anchor == PREC_READ ||
anchor == PREC_READ_NOT);
}
static String anchorToString(int anchor) {
StringBuffer s = new StringBuffer("[");
if ((anchor & AnchorType.BEGIN_BUF) !=0 ) s.append("begin-buf ");
if ((anchor & AnchorType.BEGIN_LINE) !=0 ) s.append("begin-line ");
if ((anchor & AnchorType.BEGIN_POSITION) !=0 ) s.append("begin-pos ");
if ((anchor & AnchorType.END_BUF) !=0 ) s.append("end-buf ");
if ((anchor & AnchorType.SEMI_END_BUF) !=0 ) s.append("semi-end-buf ");
if ((anchor & AnchorType.END_LINE) !=0 ) s.append("end-line ");
if ((anchor & AnchorType.ANYCHAR_STAR) !=0 ) s.append("anychar-star ");
if ((anchor & AnchorType.ANYCHAR_STAR_ML) !=0 ) s.append("anychar-star-pl ");
s.append("]");
return s.toString();
}
}

@ -0,0 +1,35 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
// remove this one in future and pass mmd directly
final class OptEnvironment {
final MinMaxLen mmd = new MinMaxLen();
int options;
int caseFoldFlag;
ScanEnvironment scanEnv;
void copy(OptEnvironment other) {
mmd.copy(other.mmd);
options = other.options;
caseFoldFlag = other.caseFoldFlag;
scanEnv = other.scanEnv;
}
}

@ -0,0 +1,153 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
final class OptExactInfo {
static final int OPT_EXACT_MAXLEN = 24;
final MinMaxLen mmd = new MinMaxLen();
final OptAnchorInfo anchor = new OptAnchorInfo();
boolean reachEnd;
boolean ignoreCase;
final char chars[] = new char[OPT_EXACT_MAXLEN];
int length;
boolean isFull() {
return length >= OPT_EXACT_MAXLEN;
}
void clear() {
mmd.clear();
anchor.clear();
reachEnd = false;
ignoreCase = false;
length = 0;
}
void copy(OptExactInfo other) {
mmd.copy(other.mmd);
anchor.copy(other.anchor);
reachEnd = other.reachEnd;
ignoreCase = other.ignoreCase;
length = other.length;
System.arraycopy(other.chars, 0, chars, 0, OPT_EXACT_MAXLEN);
}
void concat(OptExactInfo other) {
if (!ignoreCase && other.ignoreCase) {
if (length >= other.length) return; /* avoid */
ignoreCase = true;
}
int p = 0; // add->s;
int end = p + other.length;
int i;
for (i = length; p < end;) {
if (i + 1 > OPT_EXACT_MAXLEN) break;
chars[i++] = other.chars[p++];
}
length = i;
reachEnd = (p == end ? other.reachEnd : false);
OptAnchorInfo tmp = new OptAnchorInfo();
tmp.concat(anchor, other.anchor, 1, 1);
if (!other.reachEnd) tmp.rightAnchor = 0;
anchor.copy(tmp);
}
// ?? raw is not used here
void concatStr(char[] lchars, int p, int end, boolean raw) {
int i;
for (i = length; p < end && i < OPT_EXACT_MAXLEN;) {
if (i + 1 > OPT_EXACT_MAXLEN) break;
chars[i++] = lchars[p++];
}
length = i;
}
void altMerge(OptExactInfo other, OptEnvironment env) {
if (other.length == 0 || length == 0) {
clear();
return;
}
if (!mmd.equal(other.mmd)) {
clear();
return;
}
int i;
for (i = 0; i < length && i < other.length; i++) {
if (chars[i] != other.chars[i]) break;
}
if (!other.reachEnd || i<other.length || i<length) reachEnd = false;
length = i;
ignoreCase |= other.ignoreCase;
anchor.altMerge(other.anchor);
if (!reachEnd) anchor.rightAnchor = 0;
}
void select(OptExactInfo alt) {
int v1 = length;
int v2 = alt.length;
if (v2 == 0) {
return;
} else if (v1 == 0) {
copy(alt);
return;
} else if (v1 <= 2 && v2 <= 2) {
/* ByteValTable[x] is big value --> low price */
v2 = OptMapInfo.positionValue(chars[0] & 0xff);
v1 = OptMapInfo.positionValue(alt.chars[0] & 0xff);
if (length > 1) v1 += 5;
if (alt.length > 1) v2 += 5;
}
if (!ignoreCase) v1 *= 2;
if (!alt.ignoreCase) v2 *= 2;
if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) copy(alt);
}
// comp_opt_exact_or_map_info
private static final int COMP_EM_BASE = 20;
int compare(OptMapInfo m) {
if (m.value <= 0) return -1;
int ve = COMP_EM_BASE * length * (ignoreCase ? 1 : 2);
int vm = COMP_EM_BASE * 5 * 2 / m.value;
return mmd.compareDistanceValue(m.mmd, ve, vm);
}
}

@ -0,0 +1,120 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
final class OptMapInfo {
final MinMaxLen mmd = new MinMaxLen(); /* info position */
final OptAnchorInfo anchor = new OptAnchorInfo();
int value; /* weighted value */
final byte map[] = new byte[Config.CHAR_TABLE_SIZE];
void clear() {
mmd.clear();
anchor.clear();
value = 0;
for (int i=0; i<map.length; i++) map[i] = 0;
}
void copy(OptMapInfo other) {
mmd.copy(other.mmd);
anchor.copy(other.anchor);
value = other.value;
//for(int i=0; i<map.length; i++) map[i] = other.map[i];
System.arraycopy(other.map, 0, map, 0, other.map.length);
}
void addChar(int c) {
int c_ = c & 0xff;
if (map[c_] == 0) {
map[c_] = 1;
value += positionValue(c_);
}
}
void addCharAmb(char[] chars, int p, int end, int caseFoldFlag) {
addChar(chars[p]);
caseFoldFlag &= ~Config.INTERNAL_ENC_CASE_FOLD_MULTI_CHAR;
char[]items = EncodingHelper.caseFoldCodesByString(caseFoldFlag, chars[p]);
for (int i=0; i<items.length; i++) {
addChar(items[i]);
}
}
// select_opt_map_info
private static final int z = 1<<15; /* 32768: something big value */
void select(OptMapInfo alt) {
if (alt.value == 0) return;
if (value == 0) {
copy(alt);
return;
}
int v1 = z / value;
int v2 = z /alt.value;
if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) copy(alt);
}
// alt_merge_opt_map_info
void altMerge(OptMapInfo other) {
/* if (! is_equal_mml(&to->mmd, &add->mmd)) return ; */
if (value == 0) return;
if (other.value == 0 || mmd.max < other.mmd.max) {
clear();
return;
}
mmd.altMerge(other.mmd);
int val = 0;
for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) {
if (other.map[i] != 0) map[i] = 1;
if (map[i] != 0) val += positionValue(i);
}
value = val;
anchor.altMerge(other.anchor);
}
static final short ByteValTable[] = {
5, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 1, 1, 10, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
12, 4, 7, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5,
5, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 5, 5, 5,
5, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 1
};
// map_position_value
static int positionValue(int i) {
if (i < ByteValTable.length) {
return ByteValTable[i];
} else {
return 4; /* Take it easy. */
}
}
}

@ -0,0 +1,122 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public class Option {
/* options */
public static final int NONE = 0;
public static final int IGNORECASE = (1<<0);
public static final int EXTEND = (1<<1);
public static final int MULTILINE = (1<<2);
public static final int SINGLELINE = (1<<3);
public static final int FIND_LONGEST = (1<<4);
public static final int FIND_NOT_EMPTY = (1<<5);
public static final int NEGATE_SINGLELINE = (1<<6);
public static final int DONT_CAPTURE_GROUP = (1<<7);
public static final int CAPTURE_GROUP = (1<<8);
/* options (search time) */
public static final int NOTBOL = (1<<9);
public static final int NOTEOL = (1<<10);
public static final int POSIX_REGION = (1<<11);
public static final int MAXBIT = (1<<12); /* limit */
public static final int DEFAULT = NONE;
public static String toString(int option) {
String options = "";
if (isIgnoreCase(option)) options += "IGNORECASE ";
if (isExtend(option)) options += "EXTEND ";
if (isMultiline(option)) options += "MULTILINE ";
if (isSingleline(option)) options += "SINGLELINE ";
if (isFindLongest(option)) options += "FIND_LONGEST ";
if (isFindNotEmpty(option)) options += "FIND_NOT_EMPTY ";
if (isNegateSingleline(option)) options += "NEGATE_SINGLELINE ";
if (isDontCaptureGroup(option)) options += "DONT_CAPTURE_GROUP ";
if (isCaptureGroup(option)) options += "CAPTURE_GROUP ";
if (isNotBol(option)) options += "NOTBOL ";
if (isNotEol(option)) options += "NOTEOL ";
if (isPosixRegion(option)) options += "POSIX_REGION ";
return options;
}
public static boolean isIgnoreCase(int option) {
return (option & IGNORECASE) != 0;
}
public static boolean isExtend(int option) {
return (option & EXTEND) != 0;
}
public static boolean isSingleline(int option) {
return (option & SINGLELINE) != 0;
}
public static boolean isMultiline(int option) {
return (option & MULTILINE) != 0;
}
public static boolean isFindLongest(int option) {
return (option & FIND_LONGEST) != 0;
}
public static boolean isFindNotEmpty(int option) {
return (option & FIND_NOT_EMPTY) != 0;
}
public static boolean isFindCondition(int option) {
return (option & (FIND_LONGEST | FIND_NOT_EMPTY)) != 0;
}
public static boolean isNegateSingleline(int option) {
return (option & NEGATE_SINGLELINE) != 0;
}
public static boolean isDontCaptureGroup(int option) {
return (option & DONT_CAPTURE_GROUP) != 0;
}
public static boolean isCaptureGroup(int option) {
return (option & CAPTURE_GROUP) != 0;
}
public static boolean isNotBol(int option) {
return (option & NOTBOL) != 0;
}
public static boolean isNotEol(int option) {
return (option & NOTEOL) != 0;
}
public static boolean isPosixRegion(int option) {
return (option & POSIX_REGION) != 0;
}
/* OP_SET_OPTION is required for these options. ??? */
// public static boolean isDynamic(int option) {
// return (option & (MULTILINE | IGNORECASE)) != 0;
// }
public static boolean isDynamic(int option) {
return false;
}
}

@ -0,0 +1,953 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAtSimple;
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.encoding.PosixBracket;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
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.CTypeNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
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;
class Parser extends Lexer {
protected final Regex regex;
protected Node root;
protected int returnCode; // return code used by parser methods (they itself return parsed nodes)
// this approach will not affect recursive calls
protected Parser(ScanEnvironment env, char[] chars, int p, int end) {
super(env, chars, p, end);
regex = env.reg;
}
// onig_parse_make_tree
protected final Node parse() {
root = parseRegexp();
regex.numMem = env.numMem;
return root;
}
private static final int POSIX_BRACKET_NAME_MIN_LEN = 4;
private static final int POSIX_BRACKET_CHECK_LIMIT_LENGTH = 20;
private static final char BRACKET_END[] = ":]".toCharArray();
private boolean parsePosixBracket(CClassNode cc) {
mark();
boolean not;
if (peekIs('^')) {
inc();
not = true;
} else {
not = false;
}
if (stop - p >= POSIX_BRACKET_NAME_MIN_LEN + 3) { // else goto not_posix_bracket
char[][] pbs = PosixBracket.PBSNamesLower;
for (int i=0; i<pbs.length; i++) {
char[] name = pbs[i];
// hash lookup here ?
if (EncodingHelper.strNCmp(chars, p, stop, name, 0, name.length) == 0) {
p += name.length;
if (EncodingHelper.strNCmp(chars, p, stop, BRACKET_END, 0, BRACKET_END.length) != 0) {
newSyntaxException(ERR_INVALID_POSIX_BRACKET_TYPE);
}
cc.addCType(PosixBracket.PBSValues[i], not, env, this);
inc();
inc();
return false;
}
}
}
// not_posix_bracket:
c = 0;
int i= 0;
while (left() && ((c=peek()) != ':') && c != ']') {
inc();
if (++i > POSIX_BRACKET_CHECK_LIMIT_LENGTH) break;
}
if (c == ':' && left()) {
inc();
if (left()) {
fetch();
if (c == ']') newSyntaxException(ERR_INVALID_POSIX_BRACKET_TYPE);
}
}
restore();
return true; /* 1: is not POSIX bracket, but no error. */
}
private CClassNode parseCharProperty() {
int ctype = fetchCharPropertyToCType();
CClassNode n = new CClassNode();
n.addCType(ctype, false, env, this);
if (token.getPropNot()) n.setNot();
return n;
}
private boolean codeExistCheck(int code, boolean ignoreEscaped) {
mark();
boolean inEsc = false;
while (left()) {
if (ignoreEscaped && inEsc) {
inEsc = false;
} else {
fetch();
if (c == code) {
restore();
return true;
}
if (c == syntax.metaCharTable.esc) inEsc = true;
}
}
restore();
return false;
}
private CClassNode parseCharClass() {
fetchTokenInCC();
final boolean neg;
if (token.type == TokenType.CHAR && token.getC() == '^' && !token.escaped) {
neg = true;
fetchTokenInCC();
} else {
neg = false;
}
if (token.type == TokenType.CC_CLOSE) {
if (!codeExistCheck(']', true)) newSyntaxException(ERR_EMPTY_CHAR_CLASS);
env.ccEscWarn("]");
token.type = TokenType.CHAR; /* allow []...] */
}
CClassNode cc = new CClassNode();
CClassNode prevCC = null;
CClassNode workCC = null;
CCStateArg arg = new CCStateArg();
boolean andStart = false;
arg.state = CCSTATE.START;
while (token.type != TokenType.CC_CLOSE) {
boolean fetched = false;
switch (token.type) {
case CHAR:
if (token.getC() > 0xff) {
arg.inType = CCVALTYPE.CODE_POINT;
} else {
arg.inType = CCVALTYPE.SB; // sb_char:
}
arg.v = token.getC();
arg.vIsRaw = false;
parseCharClassValEntry2(cc, arg); // goto val_entry2
break;
case RAW_BYTE:
if (token.base != 0) { /* tok->base != 0 : octal or hexadec. */
byte[] buf = new byte[4];
int psave = p;
int base = token.base;
buf[0] = (byte)token.getC();
int i;
for (i=1; i<4; i++) {
fetchTokenInCC();
if (token.type != TokenType.RAW_BYTE || token.base != base) {
fetched = true;
break;
}
buf[i] = (byte)token.getC();
}
if (i == 1) {
arg.v = buf[0] & 0xff;
arg.inType = CCVALTYPE.SB; // goto raw_single
} else {
arg.v = EncodingHelper.mbcToCode(buf, 0, buf.length);
arg.inType = CCVALTYPE.CODE_POINT;
}
} else {
arg.v = token.getC();
arg.inType = CCVALTYPE.SB; // raw_single:
}
arg.vIsRaw = true;
parseCharClassValEntry2(cc, arg); // goto val_entry2
break;
case CODE_POINT:
arg.v = token.getCode();
arg.vIsRaw = true;
parseCharClassValEntry(cc, arg); // val_entry:, val_entry2
break;
case POSIX_BRACKET_OPEN:
if (parsePosixBracket(cc)) { /* true: is not POSIX bracket */
env.ccEscWarn("[");
p = token.backP;
arg.v = token.getC();
arg.vIsRaw = false;
parseCharClassValEntry(cc, arg); // goto val_entry
break;
}
cc.nextStateClass(arg, env); // goto next_class
break;
case CHAR_TYPE:
cc.addCType(token.getPropCType(), token.getPropNot(), env, this);
cc.nextStateClass(arg, env); // next_class:
break;
case CHAR_PROPERTY:
int ctype = fetchCharPropertyToCType();
cc.addCType(ctype, token.getPropNot(), env, this);
cc.nextStateClass(arg, env); // goto next_class
break;
case CC_RANGE:
if (arg.state == CCSTATE.VALUE) {
fetchTokenInCC();
fetched = true;
if (token.type == TokenType.CC_CLOSE) { /* allow [x-] */
parseCharClassRangeEndVal(cc, arg); // range_end_val:, goto val_entry;
break;
} else if (token.type == TokenType.CC_AND) {
env.ccEscWarn("-");
parseCharClassRangeEndVal(cc, arg); // goto range_end_val
break;
}
arg.state = CCSTATE.RANGE;
} else if (arg.state == CCSTATE.START) {
arg.v = token.getC(); /* [-xa] is allowed */
arg.vIsRaw = false;
fetchTokenInCC();
fetched = true;
if (token.type == TokenType.CC_RANGE || andStart) env.ccEscWarn("-"); /* [--x] or [a&&-x] is warned. */
parseCharClassValEntry(cc, arg); // goto val_entry
break;
} else if (arg.state == CCSTATE.RANGE) {
env.ccEscWarn("-");
parseCharClassSbChar(cc, arg); // goto sb_char /* [!--x] is allowed */
break;
} else { /* CCS_COMPLETE */
fetchTokenInCC();
fetched = true;
if (token.type == TokenType.CC_CLOSE) { /* allow [a-b-] */
parseCharClassRangeEndVal(cc, arg); // goto range_end_val
break;
} else if (token.type == TokenType.CC_AND) {
env.ccEscWarn("-");
parseCharClassRangeEndVal(cc, arg); // goto range_end_val
break;
}
if (syntax.allowDoubleRangeOpInCC()) {
env.ccEscWarn("-");
parseCharClassSbChar(cc, arg); // goto sb_char /* [0-9-a] is allowed as [0-9\-a] */
break;
}
newSyntaxException(ERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS);
}
break;
case CC_CC_OPEN: /* [ */
CClassNode acc = parseCharClass();
cc.or(acc);
break;
case CC_AND: /* && */
if (arg.state == CCSTATE.VALUE) {
arg.v = 0; // ??? safe v ?
arg.vIsRaw = false;
cc.nextStateValue(arg, env);
}
/* initialize local variables */
andStart = true;
arg.state = CCSTATE.START;
if (prevCC != null) {
prevCC.and(cc);
} else {
prevCC = cc;
if (workCC == null) workCC = new CClassNode();
cc = workCC;
}
cc.clear();
break;
case EOT:
newSyntaxException(ERR_PREMATURE_END_OF_CHAR_CLASS);
default:
newInternalException(ERR_PARSER_BUG);
} // switch
if (!fetched) fetchTokenInCC();
} // while
if (arg.state == CCSTATE.VALUE) {
arg.v = 0; // ??? safe v ?
arg.vIsRaw = false;
cc.nextStateValue(arg, env);
}
if (prevCC != null) {
prevCC.and(cc);
cc = prevCC;
}
if (neg) {
cc.setNot();
} else {
cc.clearNot();
}
if (cc.isNot() && syntax.notNewlineInNegativeCC()) {
if (!cc.isEmpty()) {
final int NEW_LINE = 0x0a;
if (EncodingHelper.isNewLine(NEW_LINE)) {
cc.bs.set(NEW_LINE);
}
}
}
return cc;
}
private void parseCharClassSbChar(CClassNode cc, CCStateArg arg) {
arg.inType = CCVALTYPE.SB;
arg.v = token.getC();
arg.vIsRaw = false;
parseCharClassValEntry2(cc, arg); // goto val_entry2
}
private void parseCharClassRangeEndVal(CClassNode cc, CCStateArg arg) {
arg.v = '-';
arg.vIsRaw = false;
parseCharClassValEntry(cc, arg); // goto val_entry
}
private void parseCharClassValEntry(CClassNode cc, CCStateArg arg) {
arg.inType = arg.v <= 0xff ? CCVALTYPE.SB : CCVALTYPE.CODE_POINT;
parseCharClassValEntry2(cc, arg); // val_entry2:
}
private void parseCharClassValEntry2(CClassNode cc, CCStateArg arg) {
cc.nextStateValue(arg, env);
}
private Node parseEnclose(TokenType term) {
Node node = null;
if (!left()) newSyntaxException(ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS);
int option = env.option;
if (peekIs('?') && syntax.op2QMarkGroupEffect()) {
inc();
if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
boolean listCapture = false;
fetch();
switch(c) {
case ':': /* (?:...) grouping only */
fetchToken(); // group:
node = parseSubExp(term);
returnCode = 1; /* group */
return node;
case '=':
node = new AnchorNode(AnchorType.PREC_READ);
break;
case '!': /* preceding read */
node = new AnchorNode(AnchorType.PREC_READ_NOT);
break;
case '>': /* (?>...) stop backtrack */
node = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
break;
case '\'':
if (Config.USE_NAMED_GROUP) {
if (syntax.op2QMarkLtNamedGroup()) {
listCapture = false; // goto named_group1
node = parseEncloseNamedGroup2(listCapture);
break;
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
} // USE_NAMED_GROUP
break;
case '<': /* look behind (?<=...), (?<!...) */
fetch();
if (c == '=') {
node = new AnchorNode(AnchorType.LOOK_BEHIND);
} else if (c == '!') {
node = new AnchorNode(AnchorType.LOOK_BEHIND_NOT);
} else {
if (Config.USE_NAMED_GROUP) {
if (syntax.op2QMarkLtNamedGroup()) {
unfetch();
c = '<';
listCapture = false; // named_group1:
node = parseEncloseNamedGroup2(listCapture); // named_group2:
break;
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
} else { // USE_NAMED_GROUP
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
} // USE_NAMED_GROUP
}
break;
case '@':
if (syntax.op2AtMarkCaptureHistory()) {
if (Config.USE_NAMED_GROUP) {
if (syntax.op2QMarkLtNamedGroup()) {
fetch();
if (c == '<' || c == '\'') {
listCapture = true;
node = parseEncloseNamedGroup2(listCapture); // goto named_group2 /* (?@<name>...) */
}
unfetch();
}
} // USE_NAMED_GROUP
EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
int num = env.addMemEntry();
if (num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
en.regNum = num;
node = en;
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
break;
// case 'p': #ifdef USE_POSIXLINE_OPTION
case '-':
case 'i':
case 'm':
case 's':
case 'x':
boolean neg = false;
while (true) {
switch(c) {
case ':':
case ')':
break;
case '-':
neg = true;
break;
case 'x':
option = bsOnOff(option, Option.EXTEND, neg);
break;
case 'i':
option = bsOnOff(option, Option.IGNORECASE, neg);
break;
case 's':
if (syntax.op2OptionPerl()) {
option = bsOnOff(option, Option.MULTILINE, neg);
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
break;
case 'm':
if (syntax.op2OptionPerl()) {
option = bsOnOff(option, Option.SINGLELINE, !neg);
} else if (syntax.op2OptionRuby()) {
option = bsOnOff(option, Option.MULTILINE, neg);
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
break;
// case 'p': #ifdef USE_POSIXLINE_OPTION // not defined
// option = bsOnOff(option, Option.MULTILINE|Option.SINGLELINE, neg);
// break;
default:
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
} // switch
if (c == ')') {
EncloseNode en = new EncloseNode(option, 0); // node_new_option
node = en;
returnCode = 2; /* option only */
return node;
} else if (c == ':') {
int prev = env.option;
env.option = option;
fetchToken();
Node target = parseSubExp(term);
env.option = prev;
EncloseNode en = new EncloseNode(option, 0); // node_new_option
en.setTarget(target);
node = en;
returnCode = 0;
return node;
}
if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
fetch();
} // while
default:
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
} // switch
} else {
if (isDontCaptureGroup(env.option)) {
fetchToken(); // goto group
node = parseSubExp(term);
returnCode = 1; /* group */
return node;
}
EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
int num = env.addMemEntry();
en.regNum = num;
node = en;
}
fetchToken();
Node target = parseSubExp(term);
if (node.getType() == NodeType.ANCHOR) {
AnchorNode an = (AnchorNode) node;
an.setTarget(target);
} else {
EncloseNode en = (EncloseNode)node;
en.setTarget(target);
if (en.type == EncloseType.MEMORY) {
/* Don't move this to previous of parse_subexp() */
env.setMemNode(en.regNum, node);
}
}
returnCode = 0;
return node; // ??
}
private Node parseEncloseNamedGroup2(boolean listCapture) {
int nm = p;
int num = fetchName(c, false);
int nameEnd = value;
num = env.addMemEntry();
if (listCapture && num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
regex.nameAdd(chars, nm, nameEnd, num, syntax);
EncloseNode en = new EncloseNode(env.option, true); // node_new_enclose_memory
en.regNum = num;
Node node = en;
if (listCapture) env.captureHistory = bsOnAtSimple(env.captureHistory, num);
env.numNamed++;
return node;
}
private int findStrPosition(int[]s, int n, int from, int to, Ptr nextChar) {
int x;
int q;
int p = from;
int i = 0;
while (p < to) {
x = chars[p];
q = p + 1;
if (x == s[0]) {
for (i=1; i<n && q<to; i++) {
x = chars[q];
if (x != s[i]) break;
q++;
}
if (i >= n) {
if (chars[nextChar.p] != 0) nextChar.p = q; // we may need zero term semantics...
return p;
}
}
p = q;
}
return -1;
}
private Node parseExp(TokenType term) {
if (token.type == term) return StringNode.EMPTY; // goto end_of_token
Node node = null;
boolean group = false;
switch(token.type) {
case ALT:
case EOT:
return StringNode.EMPTY; // end_of_token:, node_new_empty
case SUBEXP_OPEN:
node = parseEnclose(TokenType.SUBEXP_CLOSE);
if (returnCode == 1) {
group = true;
} else if (returnCode == 2) { /* option only */
int prev = env.option;
EncloseNode en = (EncloseNode)node;
env.option = en.option;
fetchToken();
Node target = parseSubExp(term);
env.option = prev;
en.setTarget(target);
return node;
}
break;
case SUBEXP_CLOSE:
if (!syntax.allowUnmatchedCloseSubexp()) newSyntaxException(ERR_UNMATCHED_CLOSE_PARENTHESIS);
if (token.escaped) {
return parseExpTkRawByte(group); // goto tk_raw_byte
} else {
return parseExpTkByte(group); // goto tk_byte
}
case STRING:
return parseExpTkByte(group); // tk_byte:
case RAW_BYTE:
return parseExpTkRawByte(group); // tk_raw_byte:
case CODE_POINT:
char[] buf = new char[] {(char)token.getCode()};
// #ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG ... // setRaw() #else
node = new StringNode(buf, 0, 1);
break;
case QUOTE_OPEN:
int[] endOp = new int[] {syntax.metaCharTable.esc, 'E'};
int qstart = p;
Ptr nextChar = new Ptr();
int qend = findStrPosition(endOp, endOp.length, qstart, stop, nextChar);
if (qend == -1) nextChar.p = qend = stop;
node = new StringNode(chars, qstart, qend);
p = nextChar.p;
break;
case CHAR_TYPE:
switch(token.getPropCType()) {
case CharacterType.D:
case CharacterType.S:
case CharacterType.W:
if (Config.NON_UNICODE_SDW) {
CClassNode cc = new CClassNode();
cc.addCType(token.getPropCType(), false, env, this);
if (token.getPropNot()) cc.setNot();
node = cc;
}
break;
case CharacterType.WORD:
node = new CTypeNode(token.getPropCType(), token.getPropNot());
break;
case CharacterType.SPACE:
case CharacterType.DIGIT:
case CharacterType.XDIGIT:
// #ifdef USE_SHARED_CCLASS_TABLE ... #endif
CClassNode ccn = new CClassNode();
ccn.addCType(token.getPropCType(), false, env, this);
if (token.getPropNot()) ccn.setNot();
node = ccn;
break;
default:
newInternalException(ERR_PARSER_BUG);
} // inner switch
break;
case CHAR_PROPERTY:
node = parseCharProperty();
break;
case CC_CC_OPEN:
CClassNode cc = parseCharClass();
node = cc;
if (isIgnoreCase(env.option)) {
ApplyCaseFoldArg arg = new ApplyCaseFoldArg(env, cc);
EncodingHelper.applyAllCaseFold(env.caseFoldFlag, ApplyCaseFold.INSTANCE, arg);
if (arg.altRoot != null) {
node = ConsAltNode.newAltNode(node, arg.altRoot);
}
}
break;
case ANYCHAR:
node = new AnyCharNode();
break;
case ANYCHAR_ANYTIME:
node = new AnyCharNode();
QuantifierNode qn = new QuantifierNode(0, QuantifierNode.REPEAT_INFINITE, false);
qn.setTarget(node);
node = qn;
break;
case BACKREF:
int[]backRefs = token.getBackrefNum() > 1 ? token.getBackrefRefs() : new int[]{token.getBackrefRef1()};
node = new BackRefNode(token.getBackrefNum(),
backRefs,
token.getBackrefByName(),
token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL
token.getBackrefLevel(), // ...
env);
break;
case CALL:
if (Config.USE_SUBEXP_CALL) {
int gNum = token.getCallGNum();
if (gNum < 0) {
gNum = backrefRelToAbs(gNum);
if (gNum <= 0) newValueException(ERR_INVALID_BACKREF);
}
node = new CallNode(chars, token.getCallNameP(), token.getCallNameEnd(), gNum);
env.numCall++;
} // USE_SUBEXP_CALL
break;
case ANCHOR:
node = new AnchorNode(token.getAnchor()); // possible bug in oniguruma
break;
case OP_REPEAT:
case INTERVAL:
if (syntax.contextIndepRepeatOps()) {
if (syntax.contextInvalidRepeatOps()) {
newSyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED);
} else {
node = StringNode.EMPTY; // node_new_empty
}
} else {
return parseExpTkByte(group); // goto tk_byte
}
break;
default:
newInternalException(ERR_PARSER_BUG);
} //switch
//targetp = node;
fetchToken(); // re_entry:
return parseExpRepeat(node, group); // repeat:
}
private Node parseExpTkByte(boolean group) {
StringNode node = new StringNode(chars, token.backP, p); // tk_byte:
while (true) {
fetchToken();
if (token.type != TokenType.STRING) break;
if (token.backP == node.end) {
node.end = p; // non escaped character, remain shared, just increase shared range
} else {
node.cat(chars, token.backP, p); // non continuous string stream, need to COW
}
}
// targetp = node;
return parseExpRepeat(node, group); // string_end:, goto repeat
}
private Node parseExpTkRawByte(boolean group) {
// tk_raw_byte:
// important: we don't use 0xff mask here neither in the compiler
// (in the template string) so we won't have to mask target
// strings when comparing against them in the matcher
StringNode node = new StringNode((char)token.getC());
node.setRaw();
int len = 1;
while (true) {
if (len >= 1) {
if (len == 1) {
fetchToken();
node.clearRaw();
// !goto string_end;!
return parseExpRepeat(node, group);
}
}
fetchToken();
if (token.type != TokenType.RAW_BYTE) {
/* Don't use this, it is wrong for little endian encodings. */
// USE_PAD_TO_SHORT_BYTE_CHAR ...
newValueException(ERR_TOO_SHORT_MULTI_BYTE_STRING);
}
// important: we don't use 0xff mask here neither in the compiler
// (in the template string) so we won't have to mask target
// strings when comparing against them in the matcher
node.cat((char)token.getC());
len++;
} // while
}
private Node parseExpRepeat(Node target, boolean group) {
while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat:
if (target.isInvalidQuantifier()) newSyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID);
QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
token.getRepeatUpper(),
token.type == TokenType.INTERVAL);
qtfr.greedy = token.getRepeatGreedy();
int ret = qtfr.setQuantifier(target, group, env, chars, getBegin(), getEnd());
Node qn = qtfr;
if (token.getRepeatPossessive()) {
EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
en.setTarget(qn);
qn = en;
}
if (ret == 0) {
target = qn;
} else if (ret == 2) { /* split case: /abc+/ */
target = ConsAltNode.newListNode(target, null);
ConsAltNode tmp = ((ConsAltNode)target).setCdr(ConsAltNode.newListNode(qn, null));
fetchToken();
return parseExpRepeatForCar(target, tmp, group);
}
fetchToken(); // goto re_entry
}
return target;
}
private Node parseExpRepeatForCar(Node top, ConsAltNode target, boolean group) {
while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat:
if (target.car.isInvalidQuantifier()) newSyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID);
QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
token.getRepeatUpper(),
token.type == TokenType.INTERVAL);
qtfr.greedy = token.getRepeatGreedy();
int ret = qtfr.setQuantifier(target.car, group, env, chars, getBegin(), getEnd());
Node qn = qtfr;
if (token.getRepeatPossessive()) {
EncloseNode en = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
en.setTarget(qn);
qn = en;
}
if (ret == 0) {
target.setCar(qn);
} else if (ret == 2) { /* split case: /abc+/ */
assert false;
}
fetchToken(); // goto re_entry
}
return top;
}
private Node parseBranch(TokenType term) {
Node node = parseExp(term);
if (token.type == TokenType.EOT || token.type == term || token.type == TokenType.ALT) {
return node;
} else {
ConsAltNode top = ConsAltNode.newListNode(node, null);
ConsAltNode t = top;
while (token.type != TokenType.EOT && token.type != term && token.type != TokenType.ALT) {
node = parseExp(term);
if (node.getType() == NodeType.LIST) {
t.setCdr((ConsAltNode)node);
while (((ConsAltNode)node).cdr != null ) node = ((ConsAltNode)node).cdr;
t = ((ConsAltNode)node);
} else {
t.setCdr(ConsAltNode.newListNode(node, null));
t = t.cdr;
}
}
return top;
}
}
/* term_tok: TK_EOT or TK_SUBEXP_CLOSE */
private Node parseSubExp(TokenType term) {
Node node = parseBranch(term);
if (token.type == term) {
return node;
} else if (token.type == TokenType.ALT) {
ConsAltNode top = ConsAltNode.newAltNode(node, null);
ConsAltNode t = top;
while (token.type == TokenType.ALT) {
fetchToken();
node = parseBranch(term);
t.setCdr(ConsAltNode.newAltNode(node, null));
t = t.cdr;
}
if (token.type != term) parseSubExpError(term);
return top;
} else {
parseSubExpError(term);
return null; //not reached
}
}
private void parseSubExpError(TokenType term) {
if (term == TokenType.SUBEXP_CLOSE) {
newSyntaxException(ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS);
} else {
newInternalException(ERR_PARSER_BUG);
}
}
private Node parseRegexp() {
fetchToken();
return parseSubExp(TokenType.EOT);
}
}

@ -0,0 +1,413 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isCaptureGroup;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup;
import java.util.HashMap;
import java.util.Iterator;
import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
public final class Regex implements RegexState {
int[] code; /* compiled pattern */
int codeLength;
boolean stackNeeded;
Object[]operands; /* e.g. shared CClassNode */
int operandLength;
int state; /* normal, searching, compiling */ // remove
int numMem; /* used memory(...) num counted from 1 */
int numRepeat; /* OP_REPEAT/OP_REPEAT_NG id-counter */
int numNullCheck; /* OP_NULL_CHECK_START/END id counter */
int numCombExpCheck; /* combination explosion check */
int numCall; /* number of subexp call */
int captureHistory; /* (?@...) flag (1-31) */
int btMemStart; /* need backtrack flag */
int btMemEnd; /* need backtrack flag */
int stackPopLevel;
int[]repeatRangeLo;
int[]repeatRangeHi;
public WarnCallback warnings;
public MatcherFactory factory;
int options;
int userOptions;
Object userObject;
//final Syntax syntax;
final int caseFoldFlag;
HashMap<String,NameEntry> nameTable; // named entries
/* optimization info (string search, char-map and anchors) */
SearchAlgorithm searchAlgorithm; /* optimize flag */
int thresholdLength; /* search str-length for apply optimize */
int anchor; /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */
int anchorDmin; /* (SEMI_)END_BUF anchor distance */
int anchorDmax; /* (SEMI_)END_BUF anchor distance */
int subAnchor; /* start-anchor for exact or map */
char[] exact;
int exactP;
int exactEnd;
byte[] map; /* used as BM skip or char-map */
int[] intMap; /* BM skip for exact_len > 255 */
int[] intMapBackward; /* BM skip for backward search */
int dMin; /* min-distance of exact or map */
int dMax; /* max-distance of exact or map */
char[][] templates;
int templateNum;
public Regex(CharSequence cs) {
this(cs.toString());
}
public Regex(String str) {
this(str.toCharArray(), 0, str.length(), 0);
}
public Regex(char[] chars) {
this(chars, 0, chars.length, 0);
}
public Regex(char[] chars, int p, int end) {
this(chars, p, end, 0);
}
public Regex(char[] chars, int p, int end, int option) {
this(chars, p, end, option, Syntax.RUBY, WarnCallback.DEFAULT);
}
// onig_new
public Regex(char[] chars, int p, int end, int option, Syntax syntax) {
this(chars, p, end, option, Config.ENC_CASE_FOLD_DEFAULT, syntax, WarnCallback.DEFAULT);
}
public Regex(char[]chars, int p, int end, int option, WarnCallback warnings) {
this(chars, p, end, option, Syntax.RUBY, warnings);
}
// onig_new
public Regex(char[] chars, int p, int end, int option, Syntax syntax, WarnCallback warnings) {
this(chars, p, end, option, Config.ENC_CASE_FOLD_DEFAULT, syntax, warnings);
}
// onig_alloc_init
public Regex(char[] chars, int p, int end, int option, int caseFoldFlag, Syntax syntax, WarnCallback warnings) {
if ((option & (Option.DONT_CAPTURE_GROUP | Option.CAPTURE_GROUP)) ==
(Option.DONT_CAPTURE_GROUP | Option.CAPTURE_GROUP)) {
throw new ValueException(ErrorMessages.ERR_INVALID_COMBINATION_OF_OPTIONS);
}
if ((option & Option.NEGATE_SINGLELINE) != 0) {
option |= syntax.options;
option &= ~Option.SINGLELINE;
} else {
option |= syntax.options;
}
this.options = option;
this.caseFoldFlag = caseFoldFlag;
this.warnings = warnings;
new Analyser(new ScanEnvironment(this, syntax), chars, p, end).compile();
this.warnings = null;
}
public Matcher matcher(char[] chars) {
return matcher(chars, 0, chars.length);
}
public Matcher matcher(char[] chars, int p, int end) {
return factory.create(this, chars, p, end);
}
public int numberOfCaptures() {
return numMem;
}
public int numberOfCaptureHistories() {
if (Config.USE_CAPTURE_HISTORY) {
int n = 0;
for (int i=0; i<=Config.MAX_CAPTURE_HISTORY_GROUP; i++) {
if (bsAt(captureHistory, i)) n++;
}
return n;
} else {
return 0;
}
}
String nameTableToString() {
StringBuilder sb = new StringBuilder();
if (nameTable != null) {
sb.append("name table\n");
for (NameEntry ne : nameTable.values()) {
sb.append(" " + ne + "\n");
}
sb.append("\n");
}
return sb.toString();
}
NameEntry nameFind(char[] name, int nameP, int nameEnd) {
if (nameTable != null) return nameTable.get(new String(name, nameP, nameEnd - nameP));
return null;
}
void renumberNameTable(int[]map) {
if (nameTable != null) {
for (NameEntry e : nameTable.values()) {
if (e.backNum > 1) {
for (int i=0; i<e.backNum; i++) {
e.backRefs[i] = map[e.backRefs[i]];
}
} else if (e.backNum == 1) {
e.backRef1 = map[e.backRef1];
}
}
}
}
public int numberOfNames() {
return nameTable == null ? 0 : nameTable.size();
}
void nameAdd(char[] name, int nameP, int nameEnd, int backRef, Syntax syntax) {
if (nameEnd - nameP <= 0) throw new ValueException(ErrorMessages.ERR_EMPTY_GROUP_NAME);
NameEntry e = null;
if (nameTable == null) {
nameTable = new HashMap<String,NameEntry>(); // 13, oni defaults to 5
} else {
e = nameFind(name, nameP, nameEnd);
}
if (e == null) {
// dup the name here as oni does ?, what for ? (it has to manage it, we don't)
e = new NameEntry(name, nameP, nameEnd);
nameTable.put(new String(name, nameP, nameEnd - nameP), e);
} else if (e.backNum >= 1 && !syntax.allowMultiplexDefinitionName()) {
throw new ValueException(ErrorMessages.ERR_MULTIPLEX_DEFINED_NAME, new String(name, nameP, nameEnd - nameP));
}
e.addBackref(backRef);
}
NameEntry nameToGroupNumbers(char[] name, int nameP, int nameEnd) {
return nameFind(name, nameP, nameEnd);
}
public int nameToBackrefNumber(char[] name, int nameP, int nameEnd, Region region) {
NameEntry e = nameToGroupNumbers(name, nameP, nameEnd);
if (e == null) throw new ValueException(ErrorMessages.ERR_UNDEFINED_NAME_REFERENCE,
new String(name, nameP, nameEnd - nameP));
switch(e.backNum) {
case 0:
throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
case 1:
return e.backRef1;
default:
if (region != null) {
for (int i = e.backNum - 1; i >= 0; i--) {
if (region.beg[e.backRefs[i]] != Region.REGION_NOTPOS) return e.backRefs[i];
}
}
return e.backRefs[e.backNum - 1];
}
}
public Iterator<NameEntry> namedBackrefIterator() {
return nameTable.values().iterator();
}
public boolean noNameGroupIsActive(Syntax syntax) {
if (isDontCaptureGroup(options)) return false;
if (Config.USE_NAMED_GROUP) {
if (numberOfNames() > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(options)) return false;
}
return true;
}
/* set skip map for Boyer-Moor search */
void setupBMSkipMap() {
char[] chars = exact;
int p = exactP;
int end = exactEnd;
int len = end - p;
if (len < Config.CHAR_TABLE_SIZE) {
// map/skip
if (map == null) map = new byte[Config.CHAR_TABLE_SIZE];
for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) map[i] = (byte)len;
for (int i=0; i<len-1; i++) map[chars[p + i] & 0xff] = (byte)(len - 1 -i); // oxff ??
} else {
if (intMap == null) intMap = new int[Config.CHAR_TABLE_SIZE];
for (int i=0; i<len-1; i++) intMap[chars[p + i] & 0xff] = len - 1 - i; // oxff ??
}
}
void setExactInfo(OptExactInfo e) {
if (e.length == 0) return;
// shall we copy that ?
exact = e.chars;
exactP = 0;
exactEnd = e.length;
if (e.ignoreCase) {
searchAlgorithm = new SearchAlgorithm.SLOW_IC(this);
} else {
if (e.length >= 2) {
setupBMSkipMap();
searchAlgorithm = SearchAlgorithm.BM;
} else {
searchAlgorithm = SearchAlgorithm.SLOW;
}
}
dMin = e.mmd.min;
dMax = e.mmd.max;
if (dMin != MinMaxLen.INFINITE_DISTANCE) {
thresholdLength = dMin + (exactEnd - exactP);
}
}
void setOptimizeMapInfo(OptMapInfo m) {
map = m.map;
searchAlgorithm = SearchAlgorithm.MAP;
dMin = m.mmd.min;
dMax = m.mmd.max;
if (dMin != MinMaxLen.INFINITE_DISTANCE) {
thresholdLength = dMin + 1;
}
}
void setSubAnchor(OptAnchorInfo anc) {
subAnchor |= anc.leftAnchor & AnchorType.BEGIN_LINE;
subAnchor |= anc.rightAnchor & AnchorType.END_LINE;
}
void clearOptimizeInfo() {
searchAlgorithm = SearchAlgorithm.NONE;
anchor = 0;
anchorDmax = 0;
anchorDmin = 0;
subAnchor = 0;
exact = null;
exactP = exactEnd = 0;
}
public String encStringToString(byte[]bytes, int p, int end) {
StringBuilder sb = new StringBuilder("\nPATTERN: /");
while (p < end) {
sb.append(new String(new byte[]{bytes[p]}));
p++;
}
return sb.append("/").toString();
}
public String optimizeInfoToString() {
String s = "";
s += "optimize: " + searchAlgorithm.getName() + "\n";
s += " anchor: " + OptAnchorInfo.anchorToString(anchor);
if ((anchor & AnchorType.END_BUF_MASK) != 0) {
s += MinMaxLen.distanceRangeToString(anchorDmin, anchorDmax);
}
s += "\n";
if (searchAlgorithm != SearchAlgorithm.NONE) {
s += " sub anchor: " + OptAnchorInfo.anchorToString(subAnchor) + "\n";
}
s += "dmin: " + dMin + " dmax: " + dMax + "\n";
s += "threshold length: " + thresholdLength + "\n";
if (exact != null) {
s += "exact: [" + new String(exact, exactP, exactEnd - exactP) + "]: length: " + (exactEnd - exactP) + "\n";
} else if (searchAlgorithm == SearchAlgorithm.MAP) {
int n=0;
for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) if (map[i] != 0) n++;
s += "map: n = " + n + "\n";
if (n > 0) {
int c=0;
s += "[";
for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) {
if (map[i] != 0) {
if (c > 0) s += ", ";
c++;
// TODO if (enc.isPrint(i)
s += ((char)i);
}
}
s += "]\n";
}
}
return s;
}
public int getOptions() {
return options;
}
public void setUserOptions(int options) {
this.userOptions = options;
}
public int getUserOptions() {
return userOptions;
}
public void setUserObject(Object object) {
this.userObject = object;
}
public Object getUserObject() {
return userObject;
}
}

@ -0,0 +1,66 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public final class Region {
static final int REGION_NOTPOS = -1;
public final int numRegs;
public final int[]beg;
public final int[]end;
public CaptureTreeNode historyRoot;
public Region(int num) {
this.numRegs = num;
this.beg = new int[num];
this.end = new int[num];
}
public Region(int begin, int end) {
this.numRegs = 1;
this.beg = new int[]{begin};
this.end = new int[]{end};
}
public Region clone() {
Region region = new Region(numRegs);
System.arraycopy(beg, 0, region.beg, 0, beg.length);
System.arraycopy(end, 0, region.end, 0, end.length);
if (historyRoot != null) region.historyRoot = historyRoot.cloneTree();
return region;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Region: \n");
for (int i=0; i<beg.length; i++) sb.append(" " + i + ": (" + beg[i] + "-" + end[i] + ")");
return sb.toString();
}
CaptureTreeNode getCaptureTree() {
return historyRoot;
}
void clear() {
for (int i=0; i<beg.length; i++) {
beg[i] = end[i] = REGION_NOTPOS;
}
}
}

@ -0,0 +1,137 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsClear;
import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
public final class ScanEnvironment {
private static final int SCANENV_MEMNODES_SIZE = 8;
int option;
final int caseFoldFlag;
final public Syntax syntax;
int captureHistory;
int btMemStart;
int btMemEnd;
int backrefedMem;
final public Regex reg;
int numCall;
UnsetAddrList unsetAddrList; // USE_SUBEXP_CALL
public int numMem;
int numNamed; // USE_NAMED_GROUP
public Node memNodes[];
// USE_COMBINATION_EXPLOSION_CHECK
int numCombExpCheck;
int combExpMaxRegNum;
int currMaxRegNum;
boolean hasRecursion;
public ScanEnvironment(Regex regex, Syntax syntax) {
this.reg = regex;
option = regex.options;
caseFoldFlag = regex.caseFoldFlag;
this.syntax = syntax;
}
public void clear() {
captureHistory = bsClear();
btMemStart = bsClear();
btMemEnd = bsClear();
backrefedMem = bsClear();
numCall = 0;
numMem = 0;
numNamed = 0;
memNodes = null;
numCombExpCheck = 0;
combExpMaxRegNum = 0;
currMaxRegNum = 0;
hasRecursion = false;
}
public int addMemEntry() {
if (numMem++ == 0) {
memNodes = new Node[SCANENV_MEMNODES_SIZE];
} else if (numMem >= memNodes.length) {
Node[]tmp = new Node[memNodes.length << 1];
System.arraycopy(memNodes, 0, tmp, 0, memNodes.length);
memNodes = tmp;
}
return numMem;
}
public void setMemNode(int num, Node node) {
if (numMem >= num) {
memNodes[num] = node;
} else {
throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
}
}
public int convertBackslashValue(int c) {
if (syntax.opEscControlChars()) {
switch (c) {
case 'n': return '\n';
case 't': return '\t';
case 'r': return '\r';
case 'f': return '\f';
case 'a': return '\007';
case 'b': return '\010';
case 'e': return '\033';
case 'v':
if (syntax.op2EscVVtab()) return 11; // ???
break;
default:
break;
}
}
return c;
}
void ccEscWarn(String s) {
if (Config.USE_WARN) {
if (syntax.warnCCOpNotEscaped() && syntax.backSlashEscapeInCC()) {
reg.warnings.warn("character class has '" + s + "' without escape");
}
}
}
void closeBracketWithoutEscapeWarn(String s) {
if (Config.USE_WARN) {
if (syntax.warnCCOpNotEscaped()) {
reg.warnings.warn("regular expression has '" + s + "' without escape");
}
}
}
}

@ -0,0 +1,178 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
abstract class ScannerSupport extends IntHolder implements ErrorMessages {
protected final char[] chars; // pattern
protected int p; // current scanner position
protected int stop; // pattern end (mutable)
private int lastFetched; // last fetched value for unfetch support
protected int c; // current code point
private final int begin; // pattern begin position for reset() support
private final int end; // pattern end position for reset() support
protected int _p; // used by mark()/restore() to mark positions
protected ScannerSupport(char[] chars, int p, int end) {
this.chars = chars;
this.begin = p;
this.end = end;
reset();
}
protected int getBegin() {
return begin;
}
protected int getEnd() {
return end;
}
private final int INT_SIGN_BIT = 1 << 31;
protected final int scanUnsignedNumber() {
int last = c;
int num = 0; // long ???
while(left()) {
fetch();
if (Character.isDigit(c)) {
int onum = num;
num = num * 10 + EncodingHelper.digitVal(c);
if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
} else {
unfetch();
break;
}
}
c = last;
return num;
}
protected final int scanUnsignedHexadecimalNumber(int maxLength) {
int last = c;
int num = 0;
while(left() && maxLength-- != 0) {
fetch();
if (EncodingHelper.isXDigit(c)) {
int onum = num;
int val = EncodingHelper.xdigitVal(c);
num = (num << 4) + val;
if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
} else {
unfetch();
break;
}
}
c = last;
return num;
}
protected final int scanUnsignedOctalNumber(int maxLength) {
int last = c;
int num = 0;
while(left() && maxLength-- != 0) {
fetch();
if (Character.isDigit(c) && c < '8') {
int onum = num;
int val = EncodingHelper.odigitVal(c);
num = (num << 3) + val;
if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
} else {
unfetch();
break;
}
}
c = last;
return num;
}
protected final void reset() {
p = begin;
stop = end;
}
protected final void mark() {
_p = p;
}
protected final void restore() {
p = _p;
}
protected final void inc() {
lastFetched = p;
p++;
}
protected final void fetch() {
lastFetched = p;
c = chars[p++];
}
protected int fetchTo() {
lastFetched = p;
return chars[p++];
}
protected final void unfetch() {
p = lastFetched;
}
protected final int peek() {
return p < stop ? chars[p] : 0;
}
protected final boolean peekIs(int c) {
return peek() == c;
}
protected final boolean left() {
return p < stop;
}
protected void newSyntaxException(String message) {
throw new SyntaxException(message);
}
protected void newValueException(String message) {
throw new ValueException(message);
}
protected void newValueException(String message, String str) {
throw new ValueException(message, str);
}
protected void newValueException(String message, int p, int end) {
throw new ValueException(message, new String(chars, p, end - p));
}
protected void newInternalException(String message) {
throw new InternalException(message);
}
}

@ -0,0 +1,294 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public abstract class SearchAlgorithm {
public abstract String getName();
public abstract int search(Regex regex, char[] text, int textP, int textEnd, int textRange);
public abstract int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_);
public static final SearchAlgorithm NONE = new SearchAlgorithm() {
public final String getName() {
return "NONE";
}
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
return textP;
}
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
return textP;
}
};
public static final SearchAlgorithm SLOW = new SearchAlgorithm() {
public final String getName() {
return "EXACT";
}
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
char[] target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
int end = textEnd;
end -= targetEnd - targetP - 1;
if (end > textRange) end = textRange;
int s = textP;
while (s < end) {
if (text[s] == target[targetP]) {
int p = s + 1;
int t = targetP + 1;
while (t < targetEnd) {
if (target[t] != text[p++]) break;
t++;
}
if (t == targetEnd) return s;
}
s++;
}
return -1;
}
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
char[] target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
int s = textEnd;
s -= targetEnd - targetP;
if (s > textStart) {
s = textStart;
}
while (s >= textP) {
if (text[s] == target[targetP]) {
int p = s + 1;
int t = targetP + 1;
while (t < targetEnd) {
if (target[t] != text[p++]) break;
t++;
}
if (t == targetEnd) return s;
}
// s = enc.prevCharHead or s = s <= adjustText ? -1 : s - 1;
s--;
}
return -1;
}
};
public static final class SLOW_IC extends SearchAlgorithm {
private final int caseFoldFlag;
public SLOW_IC(Regex regex) {
this.caseFoldFlag = regex.caseFoldFlag;
}
public final String getName() {
return "EXACT_IC";
}
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
char[] target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
int end = textEnd;
end -= targetEnd - targetP - 1;
if (end > textRange) end = textRange;
int s = textP;
while (s < end) {
if (lowerCaseMatch(target, targetP, targetEnd, text, s, textEnd)) return s;
s++;
}
return -1;
}
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
char[] target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
int s = textEnd;
s -= targetEnd - targetP;
if (s > textStart) {
s = textStart;
}
while (s >= textP) {
if (lowerCaseMatch(target, targetP, targetEnd, text, s, textEnd)) return s;
s = EncodingHelper.prevCharHead(adjustText, s);
}
return -1;
}
private boolean lowerCaseMatch(char[] t, int tP, int tEnd,
char[] chars, int p, int end) {
while (tP < tEnd) {
if (t[tP++] != Character.toLowerCase(chars[p++])) return false;
}
return true;
}
};
public static final SearchAlgorithm BM = new SearchAlgorithm() {
public final String getName() {
return "EXACT_BM";
}
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
char[] target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
int end = textRange + (targetEnd - targetP) - 1;
if (end > textEnd) end = textEnd;
int tail = targetEnd - 1;
int s = textP + (targetEnd - targetP) - 1;
if (regex.intMap == null) {
while (s < end) {
int p = s;
int t = tail;
while (text[p] == target[t]) {
if (t == targetP) return p;
p--; t--;
}
s += regex.map[text[s] & 0xff];
}
} else { /* see int_map[] */
while (s < end) {
int p = s;
int t = tail;
while (text[p] == target[t]) {
if (t == targetP) return p;
p--; t--;
}
s += regex.intMap[text[s] & 0xff];
}
}
return -1;
}
private static final int BM_BACKWARD_SEARCH_LENGTH_THRESHOLD = 100;
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
char[] target = regex.exact;
int targetP = regex.exactP;
int targetEnd = regex.exactEnd;
if (regex.intMapBackward == null) {
if (s_ - range_ < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD) {
// goto exact_method;
return SLOW.searchBackward(regex, text, textP, adjustText, textEnd, textStart, s_, range_);
}
setBmBackwardSkip(regex, target, targetP, targetEnd);
}
int s = textEnd - (targetEnd - targetP);
if (textStart < s) {
s = textStart;
}
while (s >= textP) {
int p = s;
int t = targetP;
while (t < targetEnd && text[p] == target[t]) {
p++; t++;
}
if (t == targetEnd) return s;
s -= regex.intMapBackward[text[s] & 0xff];
}
return -1;
}
private void setBmBackwardSkip(Regex regex, char[] chars, int p, int end) {
int[] skip;
if (regex.intMapBackward == null) {
skip = new int[Config.CHAR_TABLE_SIZE];
regex.intMapBackward = skip;
} else {
skip = regex.intMapBackward;
}
int len = end - p;
for (int i=0; i<Config.CHAR_TABLE_SIZE; i++) skip[i] = len;
for (int i=len-1; i>0; i--) skip[chars[i] & 0xff] = i;
}
};
public static final SearchAlgorithm MAP = new SearchAlgorithm() {
public final String getName() {
return "MAP";
}
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
byte[] map = regex.map;
int s = textP;
while (s < textRange) {
if (text[s] > 0xff || map[text[s]] != 0) return s;
s++;
}
return -1;
}
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
byte[] map = regex.map;
int s = textStart;
if (s >= textEnd) s = textEnd - 1;
while (s >= textP) {
if (text[s] > 0xff || map[text[s]] != 0) return s;
s--;
}
return -1;
}
};
}

@ -0,0 +1,164 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
final class StackEntry {
int type;
private int E1, E2, E3, E4;
// first union member
/* byte code position */
void setStatePCode(int pcode) {
E1 = pcode;
}
int getStatePCode() {
return E1;
}
/* string position */
void setStatePStr(int pstr) {
E2 = pstr;
}
int getStatePStr() {
return E2;
}
/* previous char position of pstr */
void setStatePStrPrev(int pstrPrev) {
E3 = pstrPrev;
}
int getStatePStrPrev() {
return E3;
}
void setStateCheck(int check) {
E4 = check;
}
int getStateCheck() {
return E4;
}
// second union member
/* for OP_REPEAT_INC, OP_REPEAT_INC_NG */
void setRepeatCount(int count) {
E1 = count;
}
int getRepeatCount() {
return E1;
}
void decreaseRepeatCount() {
E1--;
}
void increaseRepeatCount() {
E1++;
}
/* byte code position (head of repeated target) */
void setRepeatPCode(int pcode) {
E2 = pcode;
}
int getRepeatPCode() {
return E2;
}
/* repeat id */
void setRepeatNum(int num) {
E3 = num;
}
int getRepeatNum() {
return E3;
}
// third union member
/* index of stack */ /*int repeat_inc struct*/
void setSi(int si) {
E1 = si;
}
int getSi() {
return E1;
}
// fourth union member
/* memory num */
void setMemNum(int num) {
E1 = num;
}
int getMemNum() {
return E1;
}
/* start/end position */
void setMemPstr(int pstr) {
E2 = pstr;
}
int getMemPStr() {
return E2;
}
/* Following information is set, if this stack type is MEM-START */
/* prev. info (for backtrack "(...)*" ) */
void setMemStart(int start) {
E3 = start;
}
int getMemStart() {
return E3;
}
/* prev. info (for backtrack "(...)*" ) */
void setMemEnd(int end) {
E4 = end;
}
int getMemEnd() {
return E4;
}
// fifth union member
/* null check id */
void setNullCheckNum(int num) {
E1 = num;
}
int getNullCheckNum() {
return E1;
}
/* start position */
void setNullCheckPStr(int pstr) {
E2 = pstr;
}
int getNullCheckPStr() {
return E2;
}
// sixth union member
/* byte code position */
void setCallFrameRetAddr(int addr) {
E1 = addr;
}
int getCallFrameRetAddr() {
return E1;
}
/* null check id */
void setCallFrameNum(int num) {
E2 = num;
}
int getCallFrameNum() {
return E2;
}
/* string position */
void setCallFramePStr(int pstr) {
E3 = pstr;
}
int getCallFramePStr() {
return E3;
}
}

@ -0,0 +1,621 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
import jdk.nashorn.internal.runtime.regexp.joni.constants.StackType;
abstract class StackMachine extends Matcher implements StackType {
protected static final int INVALID_INDEX = -1;
protected StackEntry[]stack;
protected int stk; // stkEnd
protected final int[]repeatStk;
protected final int memStartStk, memEndStk;
// CEC
protected byte[] stateCheckBuff; // move to int[] ?
int stateCheckBuffSize;
protected StackMachine(Regex regex, char[] chars, int p , int end) {
super(regex, chars, p, end);
this.stack = regex.stackNeeded ? fetchStack() : null;
int n = regex.numRepeat + (regex.numMem << 1);
this.repeatStk = n > 0 ? new int[n] : null;
memStartStk = regex.numRepeat - 1;
memEndStk = memStartStk + regex.numMem;
/* for index start from 1, mem_start_stk[1]..mem_start_stk[num_mem] */
/* for index start from 1, mem_end_stk[1]..mem_end_stk[num_mem] */
}
private static StackEntry[] allocateStack() {
StackEntry[]stack = new StackEntry[Config.INIT_MATCH_STACK_SIZE];
stack[0] = new StackEntry();
return stack;
}
private void doubleStack() {
StackEntry[] newStack = new StackEntry[stack.length << 1];
System.arraycopy(stack, 0, newStack, 0, stack.length);
stack = newStack;
}
static final ThreadLocal<WeakReference<StackEntry[]>> stacks
= new ThreadLocal<WeakReference<StackEntry[]>>() {
@Override
protected WeakReference<StackEntry[]> initialValue() {
return new WeakReference<StackEntry[]>(allocateStack());
}
};
private static StackEntry[] fetchStack() {
WeakReference<StackEntry[]> ref = stacks.get();
StackEntry[] stack = ref.get();
if (stack == null) {
ref = new WeakReference<StackEntry[]>(stack = allocateStack());
stacks.set(ref);
}
return stack;
}
protected final void init() {
if (stack != null) pushEnsured(ALT, regex.codeLength - 1); /* bottom stack */
if (repeatStk != null) {
for (int i=1; i<=regex.numMem; i++) {
repeatStk[i + memStartStk] = repeatStk[i + memEndStk] = INVALID_INDEX;
}
}
}
protected final StackEntry ensure1() {
if (stk >= stack.length) doubleStack();
StackEntry e = stack[stk];
if (e == null) stack[stk] = e = new StackEntry();
return e;
}
protected final void pushType(int type) {
ensure1().type = type;
stk++;
}
// CEC
// STATE_CHECK_POS
private int stateCheckPos(int s, int snum) {
return (s - str) * regex.numCombExpCheck + (snum - 1);
}
// STATE_CHECK_VAL
protected final boolean stateCheckVal(int s, int snum) {
if (stateCheckBuff != null) {
int x = stateCheckPos(s, snum);
return (stateCheckBuff[x / 8] & (1 << (x % 8))) != 0;
}
return false;
}
// ELSE_IF_STATE_CHECK_MARK
private void stateCheckMark() {
StackEntry e = stack[stk];
int x = stateCheckPos(e.getStatePStr(), e.getStateCheck());
stateCheckBuff[x / 8] |= (1 << (x % 8));
}
// STATE_CHECK_BUFF_INIT
private static final int STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE = 16;
protected final void stateCheckBuffInit(int strLength, int offset, int stateNum) {
if (stateNum > 0 && strLength >= Config.CHECK_STRING_THRESHOLD_LEN) {
int size = ((strLength + 1) * stateNum + 7) >>> 3;
offset = (offset * stateNum) >>> 3;
if (size > 0 && offset < size && size < Config.CHECK_BUFF_MAX_SIZE) {
if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {
stateCheckBuff = new byte[size];
} else {
// same impl, reduce...
stateCheckBuff = new byte[size];
}
Arrays.fill(stateCheckBuff, offset, (size - offset), (byte)0);
stateCheckBuffSize = size;
} else {
stateCheckBuff = null; // reduce
stateCheckBuffSize = 0;
}
} else {
stateCheckBuff = null; // reduce
stateCheckBuffSize = 0;
}
}
protected final void stateCheckBuffClear() {
stateCheckBuff = null;
stateCheckBuffSize = 0;
}
private void push(int type, int pat, int s, int prev) {
StackEntry e = ensure1();
e.type = type;
e.setStatePCode(pat);
e.setStatePStr(s);
e.setStatePStrPrev(prev);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
stk++;
}
protected final void pushEnsured(int type, int pat) {
StackEntry e = stack[stk];
e.type = type;
e.setStatePCode(pat);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
stk++;
}
protected final void pushAltWithStateCheck(int pat, int s, int sprev, int snum) {
StackEntry e = ensure1();
e.type = ALT;
e.setStatePCode(pat);
e.setStatePStr(s);
e.setStatePStrPrev(sprev);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(stateCheckBuff != null ? snum : 0);
stk++;
}
protected final void pushStateCheck(int s, int snum) {
if (stateCheckBuff != null) {
StackEntry e = ensure1();
e.type = STATE_CHECK_MARK;
e.setStatePStr(s);
e.setStateCheck(snum);
stk++;
}
}
protected final void pushAlt(int pat, int s, int prev) {
push(ALT, pat, s, prev);
}
protected final void pushPos(int s, int prev) {
push(POS, -1 /*NULL_UCHARP*/, s, prev);
}
protected final void pushPosNot(int pat, int s, int prev) {
push(POS_NOT, pat, s, prev);
}
protected final void pushStopBT() {
pushType(STOP_BT);
}
protected final void pushLookBehindNot(int pat, int s, int sprev) {
push(LOOK_BEHIND_NOT, pat, s, sprev);
}
protected final void pushRepeat(int id, int pat) {
StackEntry e = ensure1();
e.type = REPEAT;
e.setRepeatNum(id);
e.setRepeatPCode(pat);
e.setRepeatCount(0);
stk++;
}
protected final void pushRepeatInc(int sindex) {
StackEntry e = ensure1();
e.type = REPEAT_INC;
e.setSi(sindex);
stk++;
}
protected final void pushMemStart(int mnum, int s) {
StackEntry e = ensure1();
e.type = MEM_START;
e.setMemNum(mnum);
e.setMemPstr(s);
e.setMemStart(repeatStk[memStartStk + mnum]);
e.setMemEnd(repeatStk[memEndStk + mnum]);
repeatStk[memStartStk + mnum] = stk;
repeatStk[memEndStk + mnum] = INVALID_INDEX;
stk++;
}
protected final void pushMemEnd(int mnum, int s) {
StackEntry e = ensure1();
e.type = MEM_END;
e.setMemNum(mnum);
e.setMemPstr(s);
e.setMemStart(repeatStk[memStartStk + mnum]);
e.setMemEnd(repeatStk[memEndStk + mnum]);
repeatStk[memEndStk + mnum] = stk;
stk++;
}
protected final void pushMemEndMark(int mnum) {
StackEntry e = ensure1();
e.type = MEM_END_MARK;
e.setMemNum(mnum);
stk++;
}
protected final int getMemStart(int mnum) {
int level = 0;
int stkp = stk;
while (stkp > 0) {
stkp--;
StackEntry e = stack[stkp];
if ((e.type & MASK_MEM_END_OR_MARK) != 0 && e.getMemNum() == mnum) {
level++;
} else if (e.type == MEM_START && e.getMemNum() == mnum) {
if (level == 0) break;
level--;
}
}
return stkp;
}
protected final void pushNullCheckStart(int cnum, int s) {
StackEntry e = ensure1();
e.type = NULL_CHECK_START;
e.setNullCheckNum(cnum);
e.setNullCheckPStr(s);
stk++;
}
protected final void pushNullCheckEnd(int cnum) {
StackEntry e = ensure1();
e.type = NULL_CHECK_END;
e.setNullCheckNum(cnum);
stk++;
}
protected final void pushCallFrame(int pat) {
StackEntry e = ensure1();
e.type = CALL_FRAME;
e.setCallFrameRetAddr(pat);
stk++;
}
protected final void pushReturn() {
StackEntry e = ensure1();
e.type = RETURN;
stk++;
}
// stack debug routines here
// ...
protected final void popOne() {
stk--;
}
protected final StackEntry pop() {
switch (regex.stackPopLevel) {
case StackPopLevel.FREE:
return popFree();
case StackPopLevel.MEM_START:
return popMemStart();
default:
return popDefault();
}
}
private StackEntry popFree() {
while (true) {
StackEntry e = stack[--stk];
if ((e.type & MASK_POP_USED) != 0) {
return e;
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
private StackEntry popMemStart() {
while (true) {
StackEntry e = stack[--stk];
if ((e.type & MASK_POP_USED) != 0) {
return e;
} else if (e.type == MEM_START) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
private StackEntry popDefault() {
while (true) {
StackEntry e = stack[--stk];
if ((e.type & MASK_POP_USED) != 0) {
return e;
} else if (e.type == MEM_START) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
} else if (e.type == REPEAT_INC) {
//int si = stack[stk + IREPEAT_INC_SI];
//stack[si + IREPEAT_COUNT]--;
stack[e.getSi()].decreaseRepeatCount();
} else if (e.type == MEM_END) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
protected final void popTilPosNot() {
while (true) {
stk--;
StackEntry e = stack[stk];
if (e.type == POS_NOT) {
break;
} else if (e.type == MEM_START) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemStart();
} else if (e.type == REPEAT_INC) {
//int si = stack[stk + IREPEAT_INC_SI];
//stack[si + IREPEAT_COUNT]--;
stack[e.getSi()].decreaseRepeatCount();
} else if (e.type == MEM_END){
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemStart();
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
protected final void popTilLookBehindNot() {
while (true) {
stk--;
StackEntry e = stack[stk];
if (e.type == LOOK_BEHIND_NOT) {
break;
} else if (e.type == MEM_START) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
} else if (e.type == REPEAT_INC) {
//int si = stack[stk + IREPEAT_INC_SI];
//stack[si + IREPEAT_COUNT]--;
stack[e.getSi()].decreaseRepeatCount();
} else if (e.type == MEM_END) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
protected final int posEnd() {
int k = stk;
while (true) {
k--;
StackEntry e = stack[k];
if ((e.type & MASK_TO_VOID_TARGET) != 0) {
e.type = VOID;
} else if (e.type == POS) {
e.type = VOID;
break;
}
}
return k;
}
protected final void stopBtEnd() {
int k = stk;
while (true) {
k--;
StackEntry e = stack[k];
if ((e.type & MASK_TO_VOID_TARGET) != 0) {
e.type = VOID;
} else if (e.type == STOP_BT) {
e.type = VOID;
break;
}
}
}
// int for consistency with other null check routines
protected final int nullCheck(int id, int s) {
int k = stk;
while (true) {
k--;
StackEntry e = stack[k];
if (e.type == NULL_CHECK_START) {
if (e.getNullCheckNum() == id) {
return e.getNullCheckPStr() == s ? 1 : 0;
}
}
}
}
protected final int nullCheckRec(int id, int s) {
int level = 0;
int k = stk;
while (true) {
k--;
StackEntry e = stack[k];
if (e.type == NULL_CHECK_START) {
if (e.getNullCheckNum() == id) {
if (level == 0) {
return e.getNullCheckPStr() == s ? 1 : 0;
} else {
level--;
}
}
} else if (e.type == NULL_CHECK_END) {
level++;
}
}
}
protected final int nullCheckMemSt(int id, int s) {
int k = stk;
int isNull;
while (true) {
k--;
StackEntry e = stack[k];
if (e.type == NULL_CHECK_START) {
if (e.getNullCheckNum() == id) {
if (e.getNullCheckPStr() != s) {
isNull = 0;
break;
} else {
int endp;
isNull = 1;
while (k < stk) {
if (e.type == MEM_START) {
if (e.getMemEnd() == INVALID_INDEX) {
isNull = 0;
break;
}
if (bsAt(regex.btMemEnd, e.getMemNum())) {
endp = stack[e.getMemEnd()].getMemPStr();
} else {
endp = e.getMemEnd();
}
if (stack[e.getMemStart()].getMemPStr() != endp) {
isNull = 0;
break;
} else if (endp != s) {
isNull = -1; /* empty, but position changed */
}
}
k++;
e = stack[k]; // !!
}
break;
}
}
}
}
return isNull;
}
protected final int nullCheckMemStRec(int id, int s) {
int level = 0;
int k = stk;
int isNull;
while (true) {
k--;
StackEntry e = stack[k];
if (e.type == NULL_CHECK_START) {
if (e.getNullCheckNum() == id) {
if (level == 0) {
if (e.getNullCheckPStr() != s) {
isNull = 0;
break;
} else {
int endp;
isNull = 1;
while (k < stk) {
if (e.type == MEM_START) {
if (e.getMemEnd() == INVALID_INDEX) {
isNull = 0;
break;
}
if (bsAt(regex.btMemEnd, e.getMemNum())) {
endp = stack[e.getMemEnd()].getMemPStr();
} else {
endp = e.getMemEnd();
}
if (stack[e.getMemStart()].getMemPStr() != endp) {
isNull = 0;
break;
} else if (endp != s) {
isNull = -1;; /* empty, but position changed */
}
}
k++;
e = stack[k];
}
break;
}
} else {
level--;
}
}
} else if (e.type == NULL_CHECK_END) {
if (e.getNullCheckNum() == id) level++;
}
}
return isNull;
}
protected final int getRepeat(int id) {
int level = 0;
int k = stk;
while (true) {
k--;
StackEntry e = stack[k];
if (e.type == REPEAT) {
if (level == 0) {
if (e.getRepeatNum() == id) return k;
}
} else if (e.type == CALL_FRAME) {
level--;
} else if (e.type == RETURN) {
level++;
}
}
}
protected final int sreturn() {
int level = 0;
int k = stk;
while (true) {
k--;
StackEntry e = stack[k];
if (e.type == CALL_FRAME) {
if (level == 0) {
return e.getCallFrameRetAddr();
} else {
level--;
}
} else if (e.type == RETURN) {
level++;
}
}
}
}

@ -0,0 +1,628 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.MetaChar.INEFFECTIVE_META_CHAR;
import jdk.nashorn.internal.runtime.regexp.joni.constants.SyntaxProperties;
public final class Syntax implements SyntaxProperties{
private final int op;
private final int op2;
private final int behavior;
public final int options;
public final MetaCharTable metaCharTable;
public Syntax(int op, int op2, int behavior, int options, MetaCharTable metaCharTable) {
this.op = op;
this.op2 = op2;
this.behavior = behavior;
this.options = options;
this.metaCharTable = metaCharTable;
}
public static class MetaCharTable {
public final int esc;
public final int anyChar;
public final int anyTime;
public final int zeroOrOneTime;
public final int oneOrMoreTime;
public final int anyCharAnyTime;
public MetaCharTable(int esc, int anyChar, int anyTime,
int zeroOrOneTime, int oneOrMoreTime, int anyCharAnyTime) {
this.esc = esc;
this.anyChar = anyChar;
this.anyTime = anyTime;
this.zeroOrOneTime = zeroOrOneTime;
this.oneOrMoreTime = oneOrMoreTime;
this.anyCharAnyTime = anyCharAnyTime;
}
}
/**
* OP
*
*/
protected boolean isOp(int opm) {
return (op & opm) != 0;
}
public boolean opVariableMetaCharacters() {
return isOp(OP_VARIABLE_META_CHARACTERS);
}
public boolean opDotAnyChar() {
return isOp(OP_DOT_ANYCHAR);
}
public boolean opAsteriskZeroInf() {
return isOp(OP_ASTERISK_ZERO_INF);
}
public boolean opEscAsteriskZeroInf() {
return isOp(OP_ESC_ASTERISK_ZERO_INF);
}
public boolean opPlusOneInf() {
return isOp(OP_PLUS_ONE_INF);
}
public boolean opEscPlusOneInf() {
return isOp(OP_ESC_PLUS_ONE_INF);
}
public boolean opQMarkZeroOne() {
return isOp(OP_QMARK_ZERO_ONE);
}
public boolean opEscQMarkZeroOne() {
return isOp(OP_ESC_QMARK_ZERO_ONE);
}
public boolean opBraceInterval() {
return isOp(OP_BRACE_INTERVAL);
}
public boolean opEscBraceInterval() {
return isOp(OP_ESC_BRACE_INTERVAL);
}
public boolean opVBarAlt() {
return isOp(OP_VBAR_ALT);
}
public boolean opEscVBarAlt() {
return isOp(OP_ESC_VBAR_ALT);
}
public boolean opLParenSubexp() {
return isOp(OP_LPAREN_SUBEXP);
}
public boolean opEscLParenSubexp() {
return isOp(OP_ESC_LPAREN_SUBEXP);
}
public boolean opEscAZBufAnchor() {
return isOp(OP_ESC_AZ_BUF_ANCHOR);
}
public boolean opEscCapitalGBeginAnchor() {
return isOp(OP_ESC_CAPITAL_G_BEGIN_ANCHOR);
}
public boolean opDecimalBackref() {
return isOp(OP_DECIMAL_BACKREF);
}
public boolean opBracketCC() {
return isOp(OP_BRACKET_CC);
}
public boolean opEscWWord() {
return isOp(OP_ESC_W_WORD);
}
public boolean opEscLtGtWordBeginEnd() {
return isOp(OP_ESC_LTGT_WORD_BEGIN_END);
}
public boolean opEscBWordBound() {
return isOp(OP_ESC_B_WORD_BOUND);
}
public boolean opEscSWhiteSpace() {
return isOp(OP_ESC_S_WHITE_SPACE);
}
public boolean opEscDDigit() {
return isOp(OP_ESC_D_DIGIT);
}
public boolean opLineAnchor() {
return isOp(OP_LINE_ANCHOR);
}
public boolean opPosixBracket() {
return isOp(OP_POSIX_BRACKET);
}
public boolean opQMarkNonGreedy() {
return isOp(OP_QMARK_NON_GREEDY);
}
public boolean opEscControlChars() {
return isOp(OP_ESC_CONTROL_CHARS);
}
public boolean opEscCControl() {
return isOp(OP_ESC_C_CONTROL);
}
public boolean opEscOctal3() {
return isOp(OP_ESC_OCTAL3);
}
public boolean opEscXHex2() {
return isOp(OP_ESC_X_HEX2);
}
public boolean opEscXBraceHex8() {
return isOp(OP_ESC_X_BRACE_HEX8);
}
/**
* OP
*
*/
protected boolean isOp2(int opm) {
return (op2 & opm) != 0;
}
public boolean op2EscCapitalQQuote() {
return isOp2(OP2_ESC_CAPITAL_Q_QUOTE);
}
public boolean op2QMarkGroupEffect() {
return isOp2(OP2_QMARK_GROUP_EFFECT);
}
public boolean op2OptionPerl() {
return isOp2(OP2_OPTION_PERL);
}
public boolean op2OptionRuby() {
return isOp2(OP2_OPTION_RUBY);
}
public boolean op2PlusPossessiveRepeat() {
return isOp2(OP2_PLUS_POSSESSIVE_REPEAT);
}
public boolean op2PlusPossessiveInterval() {
return isOp2(OP2_PLUS_POSSESSIVE_INTERVAL);
}
public boolean op2CClassSetOp() {
return isOp2(OP2_CCLASS_SET_OP);
}
public boolean op2QMarkLtNamedGroup() {
return isOp2(OP2_QMARK_LT_NAMED_GROUP);
}
public boolean op2EscKNamedBackref() {
return isOp2(OP2_ESC_K_NAMED_BACKREF);
}
public boolean op2EscGSubexpCall() {
return isOp2(OP2_ESC_G_SUBEXP_CALL);
}
public boolean op2AtMarkCaptureHistory() {
return isOp2(OP2_ATMARK_CAPTURE_HISTORY);
}
public boolean op2EscCapitalCBarControl() {
return isOp2(OP2_ESC_CAPITAL_C_BAR_CONTROL);
}
public boolean op2EscCapitalMBarMeta() {
return isOp2(OP2_ESC_CAPITAL_M_BAR_META);
}
public boolean op2EscVVtab() {
return isOp2(OP2_ESC_V_VTAB);
}
public boolean op2EscUHex4() {
return isOp2(OP2_ESC_U_HEX4);
}
public boolean op2EscGnuBufAnchor() {
return isOp2(OP2_ESC_GNU_BUF_ANCHOR);
}
public boolean op2EscPBraceCharProperty() {
return isOp2(OP2_ESC_P_BRACE_CHAR_PROPERTY);
}
public boolean op2EscPBraceCircumflexNot() {
return isOp2(OP2_ESC_P_BRACE_CIRCUMFLEX_NOT);
}
public boolean op2EscHXDigit() {
return isOp2(OP2_ESC_H_XDIGIT);
}
public boolean op2IneffectiveEscape() {
return isOp2(OP2_INEFFECTIVE_ESCAPE);
}
/**
* BEHAVIOR
*
*/
protected boolean isBehavior(int bvm) {
return (behavior & bvm) != 0;
}
public boolean contextIndepRepeatOps() {
return isBehavior(CONTEXT_INDEP_REPEAT_OPS);
}
public boolean contextInvalidRepeatOps() {
return isBehavior(CONTEXT_INVALID_REPEAT_OPS);
}
public boolean allowUnmatchedCloseSubexp() {
return isBehavior(ALLOW_UNMATCHED_CLOSE_SUBEXP);
}
public boolean allowInvalidInterval() {
return isBehavior(ALLOW_INVALID_INTERVAL);
}
public boolean allowIntervalLowAbbrev() {
return isBehavior(ALLOW_INTERVAL_LOW_ABBREV);
}
public boolean strictCheckBackref() {
return isBehavior(STRICT_CHECK_BACKREF);
}
public boolean differentLengthAltLookBehind() {
return isBehavior(DIFFERENT_LEN_ALT_LOOK_BEHIND);
}
public boolean captureOnlyNamedGroup() {
return isBehavior(CAPTURE_ONLY_NAMED_GROUP);
}
public boolean allowMultiplexDefinitionName() {
return isBehavior(ALLOW_MULTIPLEX_DEFINITION_NAME);
}
public boolean fixedIntervalIsGreedyOnly() {
return isBehavior(FIXED_INTERVAL_IS_GREEDY_ONLY);
}
public boolean notNewlineInNegativeCC() {
return isBehavior(NOT_NEWLINE_IN_NEGATIVE_CC);
}
public boolean backSlashEscapeInCC() {
return isBehavior(BACKSLASH_ESCAPE_IN_CC);
}
public boolean allowEmptyRangeInCC() {
return isBehavior(ALLOW_EMPTY_RANGE_IN_CC);
}
public boolean allowDoubleRangeOpInCC() {
return isBehavior(ALLOW_DOUBLE_RANGE_OP_IN_CC);
}
public boolean warnCCOpNotEscaped() {
return isBehavior(WARN_CC_OP_NOT_ESCAPED);
}
public boolean warnReduntantNestedRepeat() {
return isBehavior(WARN_REDUNDANT_NESTED_REPEAT);
}
public static final Syntax RUBY = new Syntax(
(( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
OP_ESC_OCTAL3 | OP_ESC_X_HEX2 |
OP_ESC_X_BRACE_HEX8 | OP_ESC_CONTROL_CHARS |
OP_ESC_C_CONTROL )
& ~OP_ESC_LTGT_WORD_BEGIN_END ),
( OP2_QMARK_GROUP_EFFECT |
OP2_OPTION_RUBY |
OP2_QMARK_LT_NAMED_GROUP | OP2_ESC_K_NAMED_BACKREF |
OP2_ESC_G_SUBEXP_CALL |
OP2_ESC_P_BRACE_CHAR_PROPERTY |
OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
OP2_PLUS_POSSESSIVE_REPEAT |
OP2_CCLASS_SET_OP | OP2_ESC_CAPITAL_C_BAR_CONTROL |
OP2_ESC_CAPITAL_M_BAR_META | OP2_ESC_V_VTAB |
OP2_ESC_H_XDIGIT ),
( GNU_REGEX_BV |
ALLOW_INTERVAL_LOW_ABBREV |
DIFFERENT_LEN_ALT_LOOK_BEHIND |
CAPTURE_ONLY_NAMED_GROUP |
ALLOW_MULTIPLEX_DEFINITION_NAME |
FIXED_INTERVAL_IS_GREEDY_ONLY |
WARN_CC_OP_NOT_ESCAPED |
WARN_REDUNDANT_NESTED_REPEAT ),
Option.NONE,
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
public static final Syntax DEFAULT = RUBY;
public static final Syntax ASIS = new Syntax(
0,
OP2_INEFFECTIVE_ESCAPE,
0,
Option.NONE,
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
public static final Syntax PosixBasic = new Syntax(
(POSIX_COMMON_OP | OP_ESC_LPAREN_SUBEXP |
OP_ESC_BRACE_INTERVAL ),
0,
0,
( Option.SINGLELINE | Option.MULTILINE ),
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
public static final Syntax PosixExtended = new Syntax(
( POSIX_COMMON_OP | OP_LPAREN_SUBEXP |
OP_BRACE_INTERVAL |
OP_PLUS_ONE_INF | OP_QMARK_ZERO_ONE |OP_VBAR_ALT ),
0,
( CONTEXT_INDEP_ANCHORS |
CONTEXT_INDEP_REPEAT_OPS | CONTEXT_INVALID_REPEAT_OPS |
ALLOW_UNMATCHED_CLOSE_SUBEXP |
ALLOW_DOUBLE_RANGE_OP_IN_CC ),
( Option.SINGLELINE | Option.MULTILINE ),
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
public static final Syntax Emacs = new Syntax(
( OP_DOT_ANYCHAR | OP_BRACKET_CC |
OP_ESC_BRACE_INTERVAL |
OP_ESC_LPAREN_SUBEXP | OP_ESC_VBAR_ALT |
OP_ASTERISK_ZERO_INF | OP_PLUS_ONE_INF |
OP_QMARK_ZERO_ONE | OP_DECIMAL_BACKREF |
OP_LINE_ANCHOR | OP_ESC_CONTROL_CHARS ),
OP2_ESC_GNU_BUF_ANCHOR,
ALLOW_EMPTY_RANGE_IN_CC,
Option.NONE,
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
public static final Syntax Grep = new Syntax(
( OP_DOT_ANYCHAR | OP_BRACKET_CC | OP_POSIX_BRACKET |
OP_ESC_BRACE_INTERVAL | OP_ESC_LPAREN_SUBEXP |
OP_ESC_VBAR_ALT |
OP_ASTERISK_ZERO_INF | OP_ESC_PLUS_ONE_INF |
OP_ESC_QMARK_ZERO_ONE | OP_LINE_ANCHOR |
OP_ESC_W_WORD | OP_ESC_B_WORD_BOUND |
OP_ESC_LTGT_WORD_BEGIN_END | OP_DECIMAL_BACKREF ),
0,
( ALLOW_EMPTY_RANGE_IN_CC | NOT_NEWLINE_IN_NEGATIVE_CC ),
Option.NONE,
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
public static final Syntax GnuRegex = new Syntax(
GNU_REGEX_OP,
0,
GNU_REGEX_BV,
Option.NONE,
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
public static final Syntax Java = new Syntax(
(( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
OP_ESC_CONTROL_CHARS | OP_ESC_C_CONTROL |
OP_ESC_OCTAL3 | OP_ESC_X_HEX2 )
& ~OP_ESC_LTGT_WORD_BEGIN_END ),
( OP2_ESC_CAPITAL_Q_QUOTE | OP2_QMARK_GROUP_EFFECT |
OP2_OPTION_PERL | OP2_PLUS_POSSESSIVE_REPEAT |
OP2_PLUS_POSSESSIVE_INTERVAL | OP2_CCLASS_SET_OP |
OP2_ESC_V_VTAB | OP2_ESC_U_HEX4 |
OP2_ESC_P_BRACE_CHAR_PROPERTY ),
( GNU_REGEX_BV | DIFFERENT_LEN_ALT_LOOK_BEHIND ),
Option.SINGLELINE,
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
public static final Syntax Perl = new Syntax(
(( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
OP_ESC_OCTAL3 | OP_ESC_X_HEX2 |
OP_ESC_X_BRACE_HEX8 | OP_ESC_CONTROL_CHARS |
OP_ESC_C_CONTROL )
& ~OP_ESC_LTGT_WORD_BEGIN_END ),
( OP2_ESC_CAPITAL_Q_QUOTE |
OP2_QMARK_GROUP_EFFECT | OP2_OPTION_PERL |
OP2_ESC_P_BRACE_CHAR_PROPERTY |
OP2_ESC_P_BRACE_CIRCUMFLEX_NOT ),
GNU_REGEX_BV,
Option.SINGLELINE,
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
public static final Syntax PerlNG = new Syntax(
(( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
OP_ESC_OCTAL3 | OP_ESC_X_HEX2 |
OP_ESC_X_BRACE_HEX8 | OP_ESC_CONTROL_CHARS |
OP_ESC_C_CONTROL )
& ~OP_ESC_LTGT_WORD_BEGIN_END ),
( OP2_ESC_CAPITAL_Q_QUOTE |
OP2_QMARK_GROUP_EFFECT | OP2_OPTION_PERL |
OP2_ESC_P_BRACE_CHAR_PROPERTY |
OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
OP2_QMARK_LT_NAMED_GROUP |
OP2_ESC_K_NAMED_BACKREF |
OP2_ESC_G_SUBEXP_CALL ),
( GNU_REGEX_BV |
CAPTURE_ONLY_NAMED_GROUP |
ALLOW_MULTIPLEX_DEFINITION_NAME ),
Option.SINGLELINE,
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
public static final Syntax JAVASCRIPT = new Syntax(
(( GNU_REGEX_OP | OP_QMARK_NON_GREEDY |
OP_ESC_CONTROL_CHARS | OP_ESC_C_CONTROL | OP_ESC_X_HEX2)
& ~OP_ESC_LTGT_WORD_BEGIN_END ),
( OP2_QMARK_GROUP_EFFECT | OP2_CCLASS_SET_OP |
OP2_ESC_V_VTAB | OP2_ESC_U_HEX4 ),
( GNU_REGEX_BV | DIFFERENT_LEN_ALT_LOOK_BEHIND ),
Option.SINGLELINE,
new MetaCharTable(
'\\', /* esc */
INEFFECTIVE_META_CHAR, /* anychar '.' */
INEFFECTIVE_META_CHAR, /* anytime '*' */
INEFFECTIVE_META_CHAR, /* zero or one time '?' */
INEFFECTIVE_META_CHAR, /* one or more time '+' */
INEFFECTIVE_META_CHAR /* anychar anytime */
)
);
}

@ -0,0 +1,172 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.constants.TokenType;
final class Token {
TokenType type;
boolean escaped;
int base; /* is number: 8, 16 (used in [....]) */
int backP;
// union fields
private int INT1, INT2, INT3, INT4, INT5;
private int []INTA1;
// union accessors
int getC() {
return INT1;
}
void setC(int c) {
INT1 = c;
}
int getCode() {
return INT1;
}
void setCode(int code) {
INT1 = code;
}
int getAnchor() {
return INT1;
}
void setAnchor(int anchor) {
INT1 = anchor;
}
int getSubtype() {
return INT1;
}
void setSubtype(int subtype) {
INT1 = subtype;
}
// repeat union member
int getRepeatLower() {
return INT1;
}
void setRepeatLower(int lower) {
INT1 = lower;
}
int getRepeatUpper() {
return INT2;
}
void setRepeatUpper(int upper) {
INT2 = upper;
}
boolean getRepeatGreedy() {
return INT3 != 0;
}
void setRepeatGreedy(boolean greedy) {
INT3 = greedy ? 1 : 0;
}
boolean getRepeatPossessive() {
return INT4 != 0;
}
void setRepeatPossessive(boolean possessive) {
INT4 = possessive ? 1 : 0;
}
// backref union member
int getBackrefNum() {
return INT1;
}
void setBackrefNum(int num) {
INT1 = num;
}
int getBackrefRef1() {
return INT2;
}
void setBackrefRef1(int ref1) {
INT2 = ref1;
}
int[]getBackrefRefs() {
return INTA1;
}
void setBackrefRefs(int[]refs) {
INTA1 = refs;
}
boolean getBackrefByName() {
return INT3 != 0;
}
void setBackrefByName(boolean byName) {
INT3 = byName ? 1 : 0;
}
// USE_BACKREF_AT_LEVEL
boolean getBackrefExistLevel() {
return INT4 != 0;
}
void setBackrefExistLevel(boolean existLevel) {
INT4 = existLevel ? 1 : 0;
}
int getBackrefLevel() {
return INT5;
}
void setBackrefLevel(int level) {
INT5 = level;
}
// call union member
int getCallNameP() {
return INT1;
}
void setCallNameP(int nameP) {
INT1 = nameP;
}
int getCallNameEnd() {
return INT2;
}
void setCallNameEnd(int nameEnd) {
INT2 = nameEnd;
}
int getCallGNum() {
return INT3;
}
void setCallGNum(int gnum) {
INT3 = gnum;
}
// prop union member
int getPropCType() {
return INT1;
}
void setPropCType(int ctype) {
INT1 = ctype;
}
boolean getPropNot() {
return INT2 != 0;
}
void setPropNot(boolean not) {
INT2 = not ? 1 : 0;
}
}

@ -0,0 +1,69 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
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.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
public final class UnsetAddrList {
int num;
Node[]targets;
int[]offsets;
public UnsetAddrList(int size) {
targets = new Node[size];
offsets = new int[size];
}
public void add(int offset, Node node) {
if (num >= offsets.length) {
Node []ttmp = new Node[targets.length << 1];
System.arraycopy(targets, 0, ttmp, 0, num);
targets = ttmp;
int[]otmp = new int[offsets.length << 1];
System.arraycopy(offsets, 0, otmp, 0, num);
offsets = otmp;
}
targets[num] = node;
offsets[num] = offset;
num++;
}
public void fix(Regex regex) {
for (int i=0; i<num; i++) {
EncloseNode en = (EncloseNode)targets[i];
if (!en.isAddrFixed()) new InternalException(ErrorMessages.ERR_PARSER_BUG);
regex.code[offsets[i]] = en.callAddr; // is this safe ?
}
}
public String toString() {
StringBuilder value = new StringBuilder();
if (num > 0) {
for (int i=0; i<num; i++) {
value.append("offset + " + offsets[i] + " target: " + targets[i].getAddressName());
}
}
return value.toString();
}
}

@ -0,0 +1,33 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
/**
* @author <a href="mailto:ola.bini@gmail.com">Ola Bini</a>
*/
public interface WarnCallback {
WarnCallback DEFAULT = new WarnCallback() {
public void warn(String message) {
System.err.println(message);
}
};
void warn(String message);
}

@ -0,0 +1,26 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public interface Warnings {
final String INVALID_BACKREFERENCE = "invalid back reference";
final String INVALID_SUBEXP_CALL = "invalid subexp call";
final String INVALID_UNICODE_PROPERTY = "invalid Unicode Property \\<%n>";
}

@ -0,0 +1,92 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
public final class AnchorNode extends Node implements AnchorType {
public int type;
public Node target;
public int charLength;
public AnchorNode(int type) {
this.type = type;
charLength = -1;
}
@Override
public int getType() {
return ANCHOR;
}
@Override
protected void setChild(Node newChild) {
target = newChild;
}
@Override
protected Node getChild() {
return target;
}
public void setTarget(Node tgt) {
target = tgt;
tgt.parent = this;
}
@Override
public String getName() {
return "Anchor";
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
value.append("\n type: " + typeToString());
value.append("\n target: " + pad(target, level + 1));
return value.toString();
}
public String typeToString() {
StringBuilder type = new StringBuilder();
if (isType(BEGIN_BUF)) type.append("BEGIN_BUF ");
if (isType(BEGIN_LINE)) type.append("BEGIN_LINE ");
if (isType(BEGIN_POSITION)) type.append("BEGIN_POSITION ");
if (isType(END_BUF)) type.append("END_BUF ");
if (isType(SEMI_END_BUF)) type.append("SEMI_END_BUF ");
if (isType(END_LINE)) type.append("END_LINE ");
if (isType(WORD_BOUND)) type.append("WORD_BOUND ");
if (isType(NOT_WORD_BOUND)) type.append("NOT_WORD_BOUND ");
if (isType(WORD_BEGIN)) type.append("WORD_BEGIN ");
if (isType(WORD_END)) type.append("WORD_END ");
if (isType(PREC_READ)) type.append("PREC_READ ");
if (isType(PREC_READ_NOT)) type.append("PREC_READ_NOT ");
if (isType(LOOK_BEHIND)) type.append("LOOK_BEHIND ");
if (isType(LOOK_BEHIND_NOT)) type.append("LOOK_BEHIND_NOT ");
if (isType(ANYCHAR_STAR)) type.append("ANYCHAR_STAR ");
if (isType(ANYCHAR_STAR_ML)) type.append("ANYCHAR_STAR_ML ");
return type.toString();
}
private boolean isType(int type) {
return (this.type & type) != 0;
}
}

@ -0,0 +1,40 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
public final class AnyCharNode extends Node {
public AnyCharNode(){}
@Override
public int getType() {
return CANY;
}
@Override
public String getName() {
return "Any Char";
}
@Override
public String toString(int level) {
String value = "";
return value;
}
}

@ -0,0 +1,98 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
public final class BackRefNode extends StateNode {
//private static int NODE_BACKREFS_SIZE = 6;
//int state;
public int backNum;
public int back[];
public int nestLevel;
public BackRefNode(int backNum, int[]backRefs, boolean byName, ScanEnvironment env) {
this.backNum = backNum;
if (byName) setNameRef();
for (int i=0; i<backNum; i++) {
if (backRefs[i] <= env.numMem && env.memNodes[backRefs[i]] == null) {
setRecursion(); /* /...(\1).../ */
break;
}
}
back = new int[backNum];
System.arraycopy(backRefs, 0, back, 0, backNum); // shall we really dup it ???
}
// #ifdef USE_BACKREF_AT_LEVEL
public BackRefNode(int backNum, int[]backRefs, boolean byName, boolean existLevel, int nestLevel, ScanEnvironment env) {
this(backNum, backRefs, byName, env);
if (existLevel) {
//state |= NST_NEST_LEVEL;
setNestLevel();
this.nestLevel = nestLevel;
}
}
@Override
public int getType() {
return BREF;
}
@Override
public String getName() {
return "Back Ref";
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder(super.toString(level));
value.append("\n backNum: " + backNum);
String backs = "";
for (int i=0; i<back.length; i++) backs += back[i] + ", ";
value.append("\n back: " + backs);
value.append("\n nextLevel: " + nestLevel);
return value.toString();
}
public void renumber(int[]map) {
if (!isNameRef()) throw new ValueException(ErrorMessages.ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
int oldNum = backNum;
int pos = 0;
for (int i=0; i<oldNum; i++) {
int n = map[back[i]];
if (n > 0) {
back[pos] = n;
pos++;
}
}
backNum = pos;
}
}

@ -0,0 +1,545 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.*;
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.encoding.AsciiTables;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
public final class CClassNode extends Node {
private static final int FLAG_NCCLASS_NOT = 1<<0;
private static final int FLAG_NCCLASS_SHARE = 1<<1;
int flags;
public final BitSet bs = new BitSet(); // conditional creation ?
public CodeRangeBuffer mbuf; /* multi-byte info or NULL */
private int ctype; // for hashing purposes
// node_new_cclass
public CClassNode() {}
public CClassNode(int ctype, boolean not, int sbOut, int[]ranges) {
this(not, sbOut, ranges);
this.ctype = ctype;
}
public void clear() {
bs.clear();
flags = 0;
mbuf = null;
}
// node_new_cclass_by_codepoint_range, only used by shared Char Classes
public CClassNode(boolean not, int sbOut, int[]ranges) {
if (not) setNot();
// bs.clear();
if (sbOut > 0 && ranges != null) {
int n = ranges[0];
for (int i=0; i<n; i++) {
int from = ranges[i * 2 + 1];
int to = ranges[i * 2 + 2];
for (int j=from; j<=to; j++) {
if (j >= sbOut) {
setupBuffer(ranges);
return;
}
bs.set(j);
}
}
}
setupBuffer(ranges);
}
@Override
public int getType() {
return CCLASS;
}
@Override
public String getName() {
return "Character Class";
}
@Override
public boolean equals(Object other) {
if (!(other instanceof CClassNode)) return false;
CClassNode cc = (CClassNode)other;
return ctype == cc.ctype && isNot() == cc.isNot();
}
@Override
public int hashCode() {
if (Config.USE_SHARED_CCLASS_TABLE) {
int hash = 0;
hash += ctype;
if (isNot()) hash++;
return hash + (hash >> 5);
} else {
return super.hashCode();
}
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
value.append("\n flags: " + flagsToString());
value.append("\n bs: " + pad(bs, level + 1));
value.append("\n mbuf: " + pad(mbuf, level + 1));
return value.toString();
}
public String flagsToString() {
StringBuilder flags = new StringBuilder();
if (isNot()) flags.append("NOT ");
if (isShare()) flags.append("SHARE ");
return flags.toString();
}
private void setupBuffer(int[]ranges) {
if (ranges != null) {
if (ranges[0] == 0) return;
mbuf = new CodeRangeBuffer(ranges);
}
}
public boolean isEmpty() {
return mbuf == null && bs.isEmpty();
}
public void addCodeRangeToBuf(int from, int to) {
mbuf = CodeRangeBuffer.addCodeRangeToBuff(mbuf, from, to);
}
public void addCodeRange(ScanEnvironment env, int from, int to) {
mbuf = CodeRangeBuffer.addCodeRange(mbuf, env, from, to);
}
public void addAllMultiByteRange() {
mbuf = CodeRangeBuffer.addAllMultiByteRange(mbuf);
}
public void clearNotFlag() {
if (isNot()) {
bs.invert();
mbuf = CodeRangeBuffer.notCodeRangeBuff(mbuf);
clearNot();
}
}
// and_cclass
public void and(CClassNode other) {
boolean not1 = isNot();
BitSet bsr1 = bs;
CodeRangeBuffer buf1 = mbuf;
boolean not2 = other.isNot();
BitSet bsr2 = other.bs;
CodeRangeBuffer buf2 = other.mbuf;
if (not1) {
BitSet bs1 = new BitSet();
bsr1.invertTo(bs1);
bsr1 = bs1;
}
if (not2) {
BitSet bs2 = new BitSet();
bsr2.invertTo(bs2);
bsr2 = bs2;
}
bsr1.and(bsr2);
if (bsr1 != bs) {
bs.copy(bsr1);
bsr1 = bs;
}
if (not1) {
bs.invert();
}
CodeRangeBuffer pbuf = null;
if (not1 && not2) {
pbuf = CodeRangeBuffer.orCodeRangeBuff(buf1, false, buf2, false);
} else {
pbuf = CodeRangeBuffer.andCodeRangeBuff(buf1, not1, buf2, not2);
if (not1) {
pbuf = CodeRangeBuffer.notCodeRangeBuff(pbuf);
}
}
mbuf = pbuf;
}
// or_cclass
public void or(CClassNode other) {
boolean not1 = isNot();
BitSet bsr1 = bs;
CodeRangeBuffer buf1 = mbuf;
boolean not2 = other.isNot();
BitSet bsr2 = other.bs;
CodeRangeBuffer buf2 = other.mbuf;
if (not1) {
BitSet bs1 = new BitSet();
bsr1.invertTo(bs1);
bsr1 = bs1;
}
if (not2) {
BitSet bs2 = new BitSet();
bsr2.invertTo(bs2);
bsr2 = bs2;
}
bsr1.or(bsr2);
if (bsr1 != bs) {
bs.copy(bsr1);
bsr1 = bs;
}
if (not1) {
bs.invert();
}
CodeRangeBuffer pbuf = null;
if (not1 && not2) {
pbuf = CodeRangeBuffer.andCodeRangeBuff(buf1, false, buf2, false);
} else {
pbuf = CodeRangeBuffer.orCodeRangeBuff(buf1, not1, buf2, not2);
if (not1) {
pbuf = CodeRangeBuffer.notCodeRangeBuff(pbuf);
}
}
mbuf = pbuf;
}
// add_ctype_to_cc_by_range // Encoding out!
public void addCTypeByRange(int ctype, boolean not, int sbOut, int mbr[]) {
int n = mbr[0];
if (!not) {
for (int i=0; i<n; i++) {
for (int j=mbr[i * 2 + 1]; j<=mbr[i * 2 + 2]; j++) {
if (j >= sbOut) {
if (Config.VANILLA) {
if (j == mbr[i * 2 + 2]) {
i++;
} else if (j > mbr[i * 2 + 1]) {
addCodeRangeToBuf(j, mbr[i * 2 + 2]);
i++;
}
} else {
if (j >= mbr[i * 2 + 1]) {
addCodeRangeToBuf(j, mbr[i * 2 + 2]);
i++;
}
}
// !goto sb_end!, remove duplication!
for (; i<n; i++) {
addCodeRangeToBuf(mbr[2 * i + 1], mbr[2 * i + 2]);
}
return;
}
bs.set(j);
}
}
// !sb_end:!
for (int i=0; i<n; i++) {
addCodeRangeToBuf(mbr[2 * i + 1], mbr[2 * i + 2]);
}
} else {
int prev = 0;
for (int i=0; i<n; i++) {
for (int j=prev; j < mbr[2 * i + 1]; j++) {
if (j >= sbOut) {
// !goto sb_end2!, remove duplication
prev = sbOut;
for (i=0; i<n; i++) {
if (prev < mbr[2 * i + 1]) addCodeRangeToBuf(prev, mbr[i * 2 + 1] - 1);
prev = mbr[i * 2 + 2] + 1;
}
if (prev < 0x7fffffff/*!!!*/) addCodeRangeToBuf(prev, 0x7fffffff);
return;
}
bs.set(j);
}
prev = mbr[2 * i + 2] + 1;
}
for (int j=prev; j<sbOut; j++) {
bs.set(j);
}
// !sb_end2:!
prev = sbOut;
for (int i=0; i<n; i++) {
if (prev < mbr[2 * i + 1]) addCodeRangeToBuf(prev, mbr[i * 2 + 1] - 1);
prev = mbr[i * 2 + 2] + 1;
}
if (prev < 0x7fffffff/*!!!*/) addCodeRangeToBuf(prev, 0x7fffffff);
}
}
public void addCType(int ctype, boolean not, ScanEnvironment env, IntHolder sbOut) {
if (Config.NON_UNICODE_SDW) {
switch(ctype) {
case CharacterType.D:
case CharacterType.S:
case CharacterType.W:
ctype ^= CharacterType.SPECIAL_MASK;
if (env.syntax == Syntax.JAVASCRIPT && ctype == CharacterType.SPACE) {
// \s in JavaScript includes unicode characters.
break;
}
if (not) {
for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
// if (!ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
if ((AsciiTables.AsciiCtypeTable[c] & (1 << ctype)) == 0) bs.set(c);
}
addAllMultiByteRange();
} else {
for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
// if (ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
if ((AsciiTables.AsciiCtypeTable[c] & (1 << ctype)) != 0) bs.set(c);
}
}
return;
}
}
int[] ranges = EncodingHelper.ctypeCodeRange(ctype, sbOut);
if (ranges != null) {
addCTypeByRange(ctype, not, sbOut.value, ranges);
return;
}
switch(ctype) {
case CharacterType.ALPHA:
case CharacterType.BLANK:
case CharacterType.CNTRL:
case CharacterType.DIGIT:
case CharacterType.LOWER:
case CharacterType.PUNCT:
case CharacterType.SPACE:
case CharacterType.UPPER:
case CharacterType.XDIGIT:
case CharacterType.ASCII:
case CharacterType.ALNUM:
if (not) {
for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
if (!EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
}
addAllMultiByteRange();
} else {
for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
if (EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
}
}
break;
case CharacterType.GRAPH:
case CharacterType.PRINT:
if (not) {
for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
if (!EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
}
} else {
for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
if (EncodingHelper.isCodeCType(c, ctype)) bs.set(c);
}
addAllMultiByteRange();
}
break;
case CharacterType.WORD:
if (!not) {
for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
if (EncodingHelper.isWord(c)) bs.set(c);
}
addAllMultiByteRange();
} else {
for (int c=0; c<BitSet.SINGLE_BYTE_SIZE; c++) {
if (!EncodingHelper.isWord(c)) bs.set(c);
}
}
break;
default:
throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
} // switch
}
public static final class CCStateArg {
public int v;
public int vs;
public boolean vsIsRaw;
public boolean vIsRaw;
public CCVALTYPE inType;
public CCVALTYPE type;
public CCSTATE state;
}
public void nextStateClass(CCStateArg arg, ScanEnvironment env) {
if (arg.state == CCSTATE.RANGE) throw new SyntaxException(ErrorMessages.ERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE);
if (arg.state == CCSTATE.VALUE && arg.type != CCVALTYPE.CLASS) {
if (arg.type == CCVALTYPE.SB) {
bs.set(arg.vs);
} else if (arg.type == CCVALTYPE.CODE_POINT) {
addCodeRange(env, arg.vs, arg.vs);
}
}
arg.state = CCSTATE.VALUE;
arg.type = CCVALTYPE.CLASS;
}
public void nextStateValue(CCStateArg arg, ScanEnvironment env) {
switch(arg.state) {
case VALUE:
if (arg.type == CCVALTYPE.SB) {
if (arg.vs > 0xff) throw new ValueException(ErrorMessages.ERR_INVALID_CODE_POINT_VALUE);
bs.set(arg.vs);
} else if (arg.type == CCVALTYPE.CODE_POINT) {
addCodeRange(env, arg.vs, arg.vs);
}
break;
case RANGE:
if (arg.inType == arg.type) {
if (arg.inType == CCVALTYPE.SB) {
if (arg.vs > 0xff || arg.v > 0xff) throw new ValueException(ErrorMessages.ERR_INVALID_CODE_POINT_VALUE);
if (arg.vs > arg.v) {
if (env.syntax.allowEmptyRangeInCC()) {
// goto ccs_range_end
arg.state = CCSTATE.COMPLETE;
break;
} else {
throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
}
}
bs.setRange(arg.vs, arg.v);
} else {
addCodeRange(env, arg.vs, arg.v);
}
} else {
if (arg.vs > arg.v) {
if (env.syntax.allowEmptyRangeInCC()) {
// goto ccs_range_end
arg.state = CCSTATE.COMPLETE;
break;
} else {
throw new ValueException(ErrorMessages.ERR_EMPTY_RANGE_IN_CHAR_CLASS);
}
}
bs.setRange(arg.vs, arg.v < 0xff ? arg.v : 0xff);
addCodeRange(env, arg.vs, arg.v);
}
// ccs_range_end:
arg.state = CCSTATE.COMPLETE;
break;
case COMPLETE:
case START:
arg.state = CCSTATE.VALUE;
break;
default:
break;
} // switch
arg.vsIsRaw = arg.vIsRaw;
arg.vs = arg.v;
arg.type = arg.inType;
}
// onig_is_code_in_cc_len
public boolean isCodeInCCLength(int code) {
boolean found;
if (code > 0xff) {
if (mbuf == null) {
found = false;
} else {
found = EncodingHelper.isInCodeRange(mbuf.getCodeRange(), code);
}
} else {
found = bs.at(code);
}
if (isNot()) {
return !found;
} else {
return found;
}
}
// onig_is_code_in_cc
public boolean isCodeInCC(int code) {
return isCodeInCCLength(code);
}
public void setNot() {
flags |= FLAG_NCCLASS_NOT;
}
public void clearNot() {
flags &= ~FLAG_NCCLASS_NOT;
}
public boolean isNot() {
return (flags & FLAG_NCCLASS_NOT) != 0;
}
public void setShare() {
flags |= FLAG_NCCLASS_SHARE;
}
public void clearShare() {
flags &= ~FLAG_NCCLASS_SHARE;
}
public boolean isShare() {
return (flags & FLAG_NCCLASS_SHARE) != 0;
}
}

@ -0,0 +1,50 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
public final class CTypeNode extends Node {
public int ctype;
public boolean not;
public CTypeNode(int type, boolean not) {
this.ctype= type;
this.not = not;
}
@Override
public int getType() {
return CTYPE;
}
@Override
public String getName() {
return "Character Type";
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
value.append("\n ctype: " + ctype);
value.append("\n not: " + not);
return value.toString();
}
}

@ -0,0 +1,86 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import java.util.Set;
import jdk.nashorn.internal.runtime.regexp.joni.UnsetAddrList;
import jdk.nashorn.internal.runtime.regexp.joni.WarnCallback;
public final class CallNode extends StateNode {
public char[] name;
public int nameP;
public int nameEnd;
public int groupNum;
public Node target; // is it an EncloseNode always ?
public UnsetAddrList unsetAddrList;
public CallNode(char[] name, int nameP, int nameEnd, int gnum) {
this.name = name;
this.nameP = nameP;
this.nameEnd = nameEnd;
this.groupNum = gnum; /* call by number if gnum != 0 */
}
@Override
public int getType() {
return CALL;
}
@Override
protected void setChild(Node newChild) {
target = newChild;
}
@Override
protected Node getChild() {
return target;
}
public void setTarget(Node tgt) {
target = tgt;
tgt.parent = this;
}
@Override
public String getName() {
return "Call";
}
@Override
public void verifyTree(Set<Node> set, WarnCallback warnings) {
if (target == null || target.parent == this)
warnings.warn(this.getAddressName() + " doesn't point to a target or the target has been stolen");
// do not recurse here
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder(super.toString(level));
value.append("\n name: " + new String(name, nameP, nameEnd - nameP));
value.append("\n groupNum: " + groupNum);
value.append("\n target: " + pad(target.getAddressName(), level + 1));
value.append("\n unsetAddrList: " + pad(unsetAddrList, level + 1));
return value.toString();
}
}

@ -0,0 +1,152 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import java.util.Set;
import jdk.nashorn.internal.runtime.regexp.joni.WarnCallback;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
public final class ConsAltNode extends Node {
public Node car;
public ConsAltNode cdr;
private int type; // List or Alt
private ConsAltNode(Node car, ConsAltNode cdr, int type) {
this.car = car;
if (car != null) car.parent = this;
this.cdr = cdr;
if (cdr != null) cdr.parent = this;
this.type = type;
}
public static ConsAltNode newAltNode(Node left, ConsAltNode right) {
return new ConsAltNode(left, right, ALT);
}
public static ConsAltNode newListNode(Node left, ConsAltNode right) {
return new ConsAltNode(left, right, LIST);
}
public static ConsAltNode listAdd(ConsAltNode list, Node x) {
ConsAltNode n = newListNode(x, null);
if (list != null) {
while (list.cdr != null) {
list = list.cdr;
}
list.setCdr(n);
}
return n;
}
public void toListNode() {
type = LIST;
}
public void toAltNode() {
type = ALT;
}
@Override
public int getType() {
return type;
}
@Override
protected void setChild(Node newChild) {
car = newChild;
}
@Override
protected Node getChild() {
return car;
}
@Override
public void swap(Node with) {
if (cdr != null) {
cdr.parent = with;
if (with instanceof ConsAltNode) {
ConsAltNode withCan = (ConsAltNode)with;
withCan.cdr.parent = this;
ConsAltNode tmp = cdr;
cdr = withCan.cdr;
withCan.cdr = tmp;
}
}
super.swap(with);
}
@Override
public void verifyTree(Set<Node> set, WarnCallback warnings) {
if (!set.contains(this)) {
set.add(this);
if (car != null) {
if (car.parent != this) {
warnings.warn("broken list car: " + this.getAddressName() + " -> " + car.getAddressName());
}
car.verifyTree(set,warnings);
}
if (cdr != null) {
if (cdr.parent != this) {
warnings.warn("broken list cdr: " + this.getAddressName() + " -> " + cdr.getAddressName());
}
cdr.verifyTree(set,warnings);
}
}
}
public Node setCar(Node ca) {
car = ca;
ca.parent = this;
return car;
}
public ConsAltNode setCdr(ConsAltNode cd) {
cdr = cd;
cd.parent = this;
return cdr;
}
@Override
public String getName() {
switch (type) {
case ALT:
return "Alt";
case LIST:
return "List";
default:
throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
}
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
value.append("\n car: " + pad(car, level + 1));
value.append("\n cdr: " + (cdr == null ? "NULL" : cdr.toString()));
return value.toString();
}
}

@ -0,0 +1,151 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
import jdk.nashorn.internal.runtime.regexp.joni.Option;
import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
public final class EncloseNode extends StateNode implements EncloseType {
public int type; // enclose type
public int regNum;
public int option;
public Node target; /* EncloseNode : ENCLOSE_MEMORY */
public int callAddr; // AbsAddrType
public int minLength; // OnigDistance
public int maxLength; // OnigDistance
public int charLength;
public int optCount; // referenced count in optimize_node_left()
// node_new_enclose / onig_node_new_enclose
public EncloseNode(int type) {
this.type = type;
callAddr = -1;
}
// node_new_enclose_memory
public EncloseNode(int option, boolean isNamed) {
this(MEMORY);
if (isNamed) setNamedGroup();
if (Config.USE_SUBEXP_CALL) this.option = option;
}
// node_new_option
public EncloseNode(int option, int i) {
this(OPTION);
this.option = option;
}
@Override
public int getType() {
return ENCLOSE;
}
@Override
protected void setChild(Node newChild) {
target = newChild;
}
@Override
protected Node getChild() {
return target;
}
public void setTarget(Node tgt) {
target = tgt;
tgt.parent = this;
}
@Override
public String getName() {
return "Enclose";
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder(super.toString(level));
value.append("\n type: " + typeToString());
value.append("\n regNum: " + regNum);
value.append("\n option: " + Option.toString(option));
value.append("\n target: " + pad(target, level + 1));
value.append("\n callAddr: " + callAddr);
value.append("\n minLength: " + minLength);
value.append("\n maxLength: " + maxLength);
value.append("\n charLength: " + charLength);
value.append("\n optCount: " + optCount);
return value.toString();
}
public String typeToString() {
StringBuilder types = new StringBuilder();
if (isStopBacktrack()) types.append("STOP_BACKTRACK ");
if (isMemory()) types.append("MEMORY ");
if (isOption()) types.append("OPTION ");
return types.toString();
}
public void setEncloseStatus(int flag) {
state |= flag;
}
public void clearEncloseStatus(int flag) {
state &= ~flag;
}
public void clearMemory() {
type &= ~MEMORY;
}
public void setMemory() {
type |= MEMORY;
}
public boolean isMemory() {
return (type & MEMORY) != 0;
}
public void clearOption() {
type &= ~OPTION;
}
public void setOption() {
type |= OPTION;
}
public boolean isOption() {
return (type & OPTION) != 0;
}
public void clearStopBacktrack() {
type &= ~STOP_BACKTRACK;
}
public void setStopBacktrack() {
type |= STOP_BACKTRACK;
}
public boolean isStopBacktrack() {
return (type & STOP_BACKTRACK) != 0;
}
}

@ -0,0 +1,135 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import java.util.Set;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
import jdk.nashorn.internal.runtime.regexp.joni.WarnCallback;
import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
public abstract class Node implements NodeType {
public Node parent;
public abstract int getType();
public final int getType2Bit() {
return 1 << getType();
}
protected void setChild(Node tgt){} // default definition
protected Node getChild(){return null;}; // default definition
public void swap(Node with) {
Node tmp;
//if (getChild() != null) getChild().parent = with;
//if (with.getChild() != null) with.getChild().parent = this;
//tmp = getChild();
//setChild(with.getChild());
//with.setChild(tmp);
if (parent != null) parent.setChild(with);
if (with.parent != null) with.parent.setChild(this);
tmp = parent;
parent = with.parent;
with.parent = tmp;
}
// overridden by ConsAltNode and CallNode
public void verifyTree(Set<Node> set, WarnCallback warnings) {
if (!set.contains(this) && getChild() != null) {
set.add(this);
if (getChild().parent != this) {
warnings.warn("broken link to child: " + this.getAddressName() + " -> " + getChild().getAddressName());
}
getChild().verifyTree(set, warnings);
}
}
public abstract String getName();
protected abstract String toString(int level);
public String getAddressName() {
return getName() + ":0x" + Integer.toHexString(System.identityHashCode(this));
}
public final String toString() {
StringBuilder s = new StringBuilder();
s.append("<" + getAddressName() + " (" + (parent == null ? "NULL" : parent.getAddressName()) + ")>");
return s + toString(0);
}
protected static String pad(Object value, int level) {
if (value == null) return "NULL";
StringBuilder pad = new StringBuilder(" ");
for (int i=0; i<level; i++) pad.append(pad);
return value.toString().replace("\n", "\n" + pad);
}
public final boolean isInvalidQuantifier() {
if (!Config.VANILLA) return false;
ConsAltNode node;
switch(getType()) {
case ANCHOR:
return true;
case ENCLOSE:
/* allow enclosed elements */
/* return is_invalid_quantifier_target(NENCLOSE(node)->target); */
break;
case LIST:
node = (ConsAltNode)this;
do {
if (!node.car.isInvalidQuantifier()) return false;
} while ((node = node.cdr) != null);
return false;
case ALT:
node = (ConsAltNode)this;
do {
if (node.car.isInvalidQuantifier()) return true;
} while ((node = node.cdr) != null);
break;
default:
break;
}
return false;
}
public final boolean isAllowedInLookBehind() {
return (getType2Bit() & ALLOWED_IN_LB) != 0;
}
public final boolean isSimple() {
return (getType2Bit() & SIMPLE) != 0;
}
}

@ -0,0 +1,272 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
import jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce;
import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
public final class QuantifierNode extends StateNode {
public Node target;
public int lower;
public int upper;
public boolean greedy;
public int targetEmptyInfo;
public Node headExact;
public Node nextHeadExact;
public boolean isRefered; /* include called node. don't eliminate even if {0} */
// USE_COMBINATION_EXPLOSION_CHECK
public int combExpCheckNum; /* 1,2,3...: check, 0: no check */
public QuantifierNode(int lower, int upper, boolean byNumber) {
this.lower = lower;
this.upper = upper;
greedy = true;
targetEmptyInfo = TargetInfo.ISNOT_EMPTY;
if (byNumber) setByNumber();
}
@Override
public int getType() {
return QTFR;
}
@Override
protected void setChild(Node newChild) {
target = newChild;
}
@Override
protected Node getChild() {
return target;
}
public void setTarget(Node tgt) {
target = tgt;
tgt.parent = this;
}
public StringNode convertToString(int flag) {
StringNode sn = new StringNode();
sn.flag = flag;
sn.swap(this);
return sn;
}
@Override
public String getName() {
return "Quantifier";
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder(super.toString(level));
value.append("\n target: " + pad(target, level + 1));
value.append("\n lower: " + lower);
value.append("\n upper: " + upper);
value.append("\n greedy: " + greedy);
value.append("\n targetEmptyInfo: " + targetEmptyInfo);
value.append("\n headExact: " + pad(headExact, level + 1));
value.append("\n nextHeadExact: " + pad(nextHeadExact, level + 1));
value.append("\n isRefered: " + isRefered);
value.append("\n combExpCheckNum: " + combExpCheckNum);
return value.toString();
}
public boolean isAnyCharStar() {
return greedy && isRepeatInfinite(upper) && target.getType() == CANY;
}
/* ?:0, *:1, +:2, ??:3, *?:4, +?:5 */
protected int popularNum() {
if (greedy) {
if (lower == 0) {
if (upper == 1) return 0;
else if (isRepeatInfinite(upper)) return 1;
} else if (lower == 1) {
if (isRepeatInfinite(upper)) return 2;
}
} else {
if (lower == 0) {
if (upper == 1) return 3;
else if (isRepeatInfinite(upper)) return 4;
} else if (lower == 1) {
if (isRepeatInfinite(upper)) return 5;
}
}
return -1;
}
protected void set(QuantifierNode other) {
setTarget(other.target);
other.target = null;
lower = other.lower;
upper = other.upper;
greedy = other.greedy;
targetEmptyInfo = other.targetEmptyInfo;
//setHeadExact(other.headExact);
//setNextHeadExact(other.nextHeadExact);
headExact = other.headExact;
nextHeadExact = other.nextHeadExact;
isRefered = other.isRefered;
combExpCheckNum = other.combExpCheckNum;
}
public void reduceNestedQuantifier(QuantifierNode other) {
int pnum = popularNum();
int cnum = other.popularNum();
if (pnum < 0 || cnum < 0) return;
switch(Reduce.REDUCE_TABLE[cnum][pnum]) {
case DEL:
// no need to set the parent here...
// swap ?
set(other); // *pnode = *cnode; ???
break;
case A:
setTarget(other.target);
lower = 0;
upper = REPEAT_INFINITE;
greedy = true;
break;
case AQ:
setTarget(other.target);
lower = 0;
upper = REPEAT_INFINITE;
greedy = false;
break;
case QQ:
setTarget(other.target);
lower = 0;
upper = 1;
greedy = false;
break;
case P_QQ:
setTarget(other);
lower = 0;
upper = 1;
greedy = false;
other.lower = 1;
other.upper = REPEAT_INFINITE;
other.greedy = true;
return;
case PQ_Q:
setTarget(other);
lower = 0;
upper = 1;
greedy = true;
other.lower = 1;
other.upper = REPEAT_INFINITE;
other.greedy = false;
return;
case ASIS:
setTarget(other);
return;
}
// ??? remove the parent from target ???
other.target = null; // remove target from reduced quantifier
}
public int setQuantifier(Node tgt, boolean group, ScanEnvironment env, char[] chars, int p, int end) {
if (lower == 1 && upper == 1) return 1;
switch(tgt.getType()) {
case STR:
if (!group) {
StringNode sn = (StringNode)tgt;
if (sn.canBeSplit()) {
StringNode n = sn.splitLastChar();
if (n != null) {
setTarget(n);
return 2;
}
}
}
break;
case QTFR:
/* check redundant double repeat. */
/* verbose warn (?:.?)? etc... but not warn (.?)? etc... */
QuantifierNode qnt = (QuantifierNode)tgt;
int nestQNum = popularNum();
int targetQNum = qnt.popularNum();
if (Config.USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR) {
if (!isByNumber() && !qnt.isByNumber() && env.syntax.warnReduntantNestedRepeat()) {
switch(Reduce.REDUCE_TABLE[targetQNum][nestQNum]) {
case ASIS:
break;
case DEL:
env.reg.warnings.warn(new String(chars, p, end) +
" redundant nested repeat operator");
break;
default:
env.reg.warnings.warn(new String(chars, p, end) +
" nested repeat operator " + Reduce.PopularQStr[targetQNum] +
" and " + Reduce.PopularQStr[nestQNum] + " was replaced with '" +
Reduce.ReduceQStr[Reduce.REDUCE_TABLE[targetQNum][nestQNum].ordinal()] + "'");
}
}
} // USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
if (targetQNum >= 0) {
if (nestQNum >= 0) {
reduceNestedQuantifier(qnt);
return 0;
} else if (targetQNum == 1 || targetQNum == 2) { /* * or + */
/* (?:a*){n,m}, (?:a+){n,m} => (?:a*){n,n}, (?:a+){n,n} */
if (!isRepeatInfinite(upper) && upper > 1 && greedy) {
upper = lower == 0 ? 1 : lower;
}
}
}
default:
break;
}
setTarget(tgt);
return 0;
}
public static final int REPEAT_INFINITE = -1;
public static boolean isRepeatInfinite(int n) {
return n == REPEAT_INFINITE;
}
}

@ -0,0 +1,232 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeStatus;
public abstract class StateNode extends Node implements NodeStatus {
protected int state;
@Override
public String toString(int level) {
return "\n state: " + stateToString();
}
public String stateToString() {
StringBuilder states = new StringBuilder();
if (isMinFixed()) states.append("MIN_FIXED ");
if (isMaxFixed()) states.append("MAX_FIXED ");
if (isMark1()) states.append("MARK1 ");
if (isMark2()) states.append("MARK2 ");
if (isMemBackrefed()) states.append("MEM_BACKREFED ");
if (isStopBtSimpleRepeat()) states.append("STOP_BT_SIMPLE_REPEAT ");
if (isRecursion()) states.append("RECURSION ");
if (isCalled()) states.append("CALLED ");
if (isAddrFixed()) states.append("ADDR_FIXED ");
if (isNamedGroup()) states.append("NAMED_GROUP ");
if (isNameRef()) states.append("NAME_REF ");
if (isInRepeat()) states.append("IN_REPEAT ");
if (isNestLevel()) states.append("NEST_LEVEL ");
if (isByNumber()) states.append("BY_NUMBER ");
return states.toString();
}
public boolean isMinFixed() {
return (state & NST_MIN_FIXED) != 0;
}
public void setMinFixed() {
state |= NST_MIN_FIXED;
}
public void clearMinFixed() {
state &= ~NST_MIN_FIXED;
}
public boolean isMaxFixed() {
return (state & NST_MAX_FIXED) != 0;
}
public void setMaxFixed() {
state |= NST_MAX_FIXED;
}
public void clearMaxFixed() {
state &= ~NST_MAX_FIXED;
}
public boolean isCLenFixed() {
return (state & NST_CLEN_FIXED) != 0;
}
public void setCLenFixed() {
state |= NST_CLEN_FIXED;
}
public void clearCLenFixed() {
state &= ~NST_CLEN_FIXED;
}
public boolean isMark1() {
return (state & NST_MARK1) != 0;
}
public void setMark1() {
state |= NST_MARK1;
}
public void clearMark1() {
state &= ~NST_MARK1;
}
public boolean isMark2() {
return (state & NST_MARK2) != 0;
}
public void setMark2() {
state |= NST_MARK2;
}
public void clearMark2() {
state &= ~NST_MARK2;
}
public boolean isMemBackrefed() {
return (state & NST_MEM_BACKREFED) != 0;
}
public void setMemBackrefed() {
state |= NST_MEM_BACKREFED;
}
public void clearMemBackrefed() {
state &= ~NST_MEM_BACKREFED;
}
public boolean isStopBtSimpleRepeat() {
return (state & NST_STOP_BT_SIMPLE_REPEAT) != 0;
}
public void setStopBtSimpleRepeat() {
state |= NST_STOP_BT_SIMPLE_REPEAT;
}
public void clearStopBtSimpleRepeat() {
state &= ~NST_STOP_BT_SIMPLE_REPEAT;
}
public boolean isRecursion() {
return (state & NST_RECURSION) != 0;
}
public void setRecursion() {
state |= NST_RECURSION;
}
public void clearRecursion() {
state &= ~NST_RECURSION;
}
public boolean isCalled() {
return (state & NST_CALLED) != 0;
}
public void setCalled() {
state |= NST_CALLED;
}
public void clearCAlled() {
state &= ~NST_CALLED;
}
public boolean isAddrFixed() {
return (state & NST_ADDR_FIXED) != 0;
}
public void setAddrFixed() {
state |= NST_ADDR_FIXED;
}
public void clearAddrFixed() {
state &= ~NST_ADDR_FIXED;
}
public boolean isNamedGroup() {
return (state & NST_NAMED_GROUP) != 0;
}
public void setNamedGroup() {
state |= NST_NAMED_GROUP;
}
public void clearNamedGroup() {
state &= ~NST_NAMED_GROUP;
}
public boolean isNameRef() {
return (state & NST_NAME_REF) != 0;
}
public void setNameRef() {
state |= NST_NAME_REF;
}
public void clearNameRef() {
state &= ~NST_NAME_REF;
}
public boolean isInRepeat() {
return (state & NST_IN_REPEAT) != 0;
}
public void setInRepeat() {
state |= NST_IN_REPEAT;
}
public void clearInRepeat() {
state &= ~NST_IN_REPEAT;
}
public boolean isNestLevel() {
return (state & NST_NEST_LEVEL) != 0;
}
public void setNestLevel() {
state |= NST_NEST_LEVEL;
}
public void clearNestLevel() {
state &= ~NST_NEST_LEVEL;
}
public boolean isByNumber() {
return (state & NST_BY_NUMBER) != 0;
}
public void setByNumber() {
state |= NST_BY_NUMBER;
}
public void clearByNumber() {
state &= ~NST_BY_NUMBER;
}
}

@ -0,0 +1,207 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper;
import jdk.nashorn.internal.runtime.regexp.joni.constants.StringType;
public final class StringNode extends Node implements StringType {
private static final int NODE_STR_MARGIN = 16;
private static final int NODE_STR_BUF_SIZE = 24;
public static final StringNode EMPTY = new StringNode(null, Integer.MAX_VALUE, Integer.MAX_VALUE);
public char[] chars;
public int p;
public int end;
public int flag;
public StringNode() {
this.chars = new char[NODE_STR_BUF_SIZE];
}
public StringNode(char[] chars, int p, int end) {
this.chars = chars;
this.p = p;
this.end = end;
setShared();
}
public StringNode(char c) {
this();
chars[end++] = c;
}
/* Ensure there is ahead bytes available in node's buffer
* (assumes that the node is not shared)
*/
public void ensure(int ahead) {
int len = (end - p) + ahead;
if (len >= chars.length) {
char[] tmp = new char[len + NODE_STR_MARGIN];
System.arraycopy(chars, p, tmp, 0, end - p);
chars = tmp;
}
}
/* COW and/or ensure there is ahead bytes available in node's buffer
*/
private void modifyEnsure(int ahead) {
if (isShared()) {
int len = (end - p) + ahead;
char[] tmp = new char[len + NODE_STR_MARGIN];
System.arraycopy(chars, p, tmp, 0, end - p);
chars = tmp;
end = end - p;
p = 0;
clearShared();
} else {
ensure(ahead);
}
}
@Override
public int getType() {
return STR;
}
@Override
public String getName() {
return "String";
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
value.append("\n bytes: '");
for (int i=p; i<end; i++) {
if (chars[i] >= 0x20 && chars[i] < 0x7f) {
value.append(chars[i]);
} else {
value.append(String.format("[0x%04x]", chars[i]));
}
}
value.append("'");
return value.toString();
}
public int length() {
return end - p;
}
public StringNode splitLastChar() {
StringNode n = null;
if (end > p) {
int prev = EncodingHelper.prevCharHead(p, end);
if (prev != -1 && prev > p) { /* can be splitted. */
n = new StringNode(chars, prev, end);
if (isRaw()) n.setRaw();
end = prev;
}
}
return n;
}
public boolean canBeSplit() {
if (end > p) {
return 1 < (end - p);
}
return false;
}
public void set(char[] chars, int p, int end) {
this.chars = chars;
this.p = p;
this.end = end;
setShared();
}
public void cat(char[] cat, int catP, int catEnd) {
int len = catEnd - catP;
modifyEnsure(len);
System.arraycopy(cat, catP, chars, end, len);
end += len;
}
public void cat(char c) {
modifyEnsure(1);
chars[end++] = c;
}
public void catCode(int code) {
cat((char)code);
}
public void clear() {
if (chars.length > NODE_STR_BUF_SIZE) chars = new char[NODE_STR_BUF_SIZE];
flag = 0;
p = end = 0;
}
public void setRaw() {
flag |= NSTR_RAW;
}
public void clearRaw() {
flag &= ~NSTR_RAW;
}
public boolean isRaw() {
return (flag & NSTR_RAW) != 0;
}
public void setAmbig() {
flag |= NSTR_AMBIG;
}
public void clearAmbig() {
flag &= ~NSTR_AMBIG;
}
public boolean isAmbig() {
return (flag & NSTR_AMBIG) != 0;
}
public void setDontGetOptInfo() {
flag |= NSTR_DONT_GET_OPT_INFO;
}
public void clearDontGetOptInfo() {
flag &= ~NSTR_DONT_GET_OPT_INFO;
}
public boolean isDontGetOptInfo() {
return (flag & NSTR_DONT_GET_OPT_INFO) != 0;
}
public void setShared() {
flag |= NSTR_SHARED;
}
public void clearShared() {
flag &= ~NSTR_SHARED;
}
public boolean isShared() {
return (flag & NSTR_SHARED) != 0;
}
}

@ -0,0 +1,49 @@
package jdk.nashorn.internal.runtime.regexp.joni.bench;
import jdk.nashorn.internal.runtime.regexp.joni.Option;
import jdk.nashorn.internal.runtime.regexp.joni.Regex;
import jdk.nashorn.internal.runtime.regexp.joni.Syntax;
public abstract class AbstractBench {
protected void bench(String _reg, String _str, int warmup, int times) throws Exception {
char[] reg = _reg.toCharArray();
char[] str = _str.toCharArray();
Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,Syntax.DEFAULT);
System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
for(int j=0;j<warmup;j++) {
long before = System.currentTimeMillis();
for(int i = 0; i < times; i++) {
p.matcher(str, 0, str.length).search(0, str.length, Option.NONE);
}
long time = System.currentTimeMillis() - before;
System.err.println(": " + time + "ms");
}
}
protected void benchBestOf(String _reg, String _str, int warmup, int times) throws Exception {
char[] reg = _reg.toCharArray();
char[] str = _str.toCharArray();
Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,Syntax.DEFAULT);
System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
long best = Long.MAX_VALUE;
for(int j=0;j<warmup;j++) {
long before = System.currentTimeMillis();
for(int i = 0; i < times; i++) {
p.matcher(str, 0, str.length).search(0, str.length, Option.NONE);
}
long time = System.currentTimeMillis() - before;
if(time < best) {
best = time;
}
System.err.print(".");
}
System.err.println(": " + best + "ms");
}
}

@ -0,0 +1,7 @@
package jdk.nashorn.internal.runtime.regexp.joni.bench;
public class BenchGreedyBacktrack extends AbstractBench {
public static void main(String[] args) throws Exception {
new BenchGreedyBacktrack().bench(".*_p","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,1000000);
}
}

@ -0,0 +1,31 @@
package jdk.nashorn.internal.runtime.regexp.joni.bench;
public class BenchRailsRegs extends AbstractBench {
public static void main(String[] args) throws Exception {
final String[][] regexps = {{"a.*?[b-z]{2,4}aaaaaa","afdgdsgderaabxxaaaaaaaaaaaaaaaaaaaaaaaa"},
{"://","/shop/viewCategory.shtml?category=DOGS"},
{"^\\w+\\://[^/]+(/.*|$)$","/shop/viewCategory.shtml?category=DOGS"},
{"\\A/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/signonForm\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/newAccountForm\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/newAccount\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/viewCart\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/index\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/viewCategory\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A(?:::)?([A-Z]\\w*(?:::[A-Z]\\w*)*)\\z","CategoriesController"},
{"\\Ainsert","SELECT * FROM sessions WHERE (session_id = '1b341ffe23b5298676d535fcabd3d0d7') LIMIT 1"},
{"\\A\\(?\\s*(select|show)","SELECT * FROM sessions WHERE (session_id = '1b341ffe23b5298676d535fcabd3d0d7') LIMIT 1"},
{".*?\n","1b341ffe23b5298676d535fcabd3d0d7"},
{"^find_(all_by|by)_([_a-zA-Z]\\w*)$","find_by_string_id"},
{"\\.rjs$","categories/show.rhtml"},
{"^[-a-z]+://","petstore.css"},
{"^get$",""},
{"^post$",""},
{"^[^:]+","www.example.com"},
{"(=|\\?|_before_type_cast)$", "updated_on"},
{"^(.*?)=(.*?);","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/"}};
for(String[] reg : regexps) {
new BenchRailsRegs().benchBestOf(reg[0],reg[1],10,1000000);
}
}
}

@ -0,0 +1,17 @@
package jdk.nashorn.internal.runtime.regexp.joni.bench;
public class BenchSeveralRegexps extends AbstractBench {
public static void main(String[] args) throws Exception {
int BASE = 1000000;
new BenchSeveralRegexps().benchBestOf("a"," a",10,4*BASE);
new BenchSeveralRegexps().benchBestOf(".*?=","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,BASE);
new BenchSeveralRegexps().benchBestOf("^(.*?)=(.*?);","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,BASE);
new BenchSeveralRegexps().benchBestOf(".*_p","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,4*BASE);
new BenchSeveralRegexps().benchBestOf(".*=","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,4*BASE);
}
}

@ -0,0 +1,58 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface AnchorType {
final int BEGIN_BUF = (1<<0);
final int BEGIN_LINE = (1<<1);
final int BEGIN_POSITION = (1<<2);
final int END_BUF = (1<<3);
final int SEMI_END_BUF = (1<<4);
final int END_LINE = (1<<5);
final int WORD_BOUND = (1<<6);
final int NOT_WORD_BOUND = (1<<7);
final int WORD_BEGIN = (1<<8);
final int WORD_END = (1<<9);
final int PREC_READ = (1<<10);
final int PREC_READ_NOT = (1<<11);
final int LOOK_BEHIND = (1<<12);
final int LOOK_BEHIND_NOT = (1<<13);
final int ANYCHAR_STAR = (1<<14); /* ".*" optimize info */
final int ANYCHAR_STAR_ML = (1<<15); /* ".*" optimize info (multi-line) */
final int ANYCHAR_STAR_MASK = (ANYCHAR_STAR | ANYCHAR_STAR_ML);
final int END_BUF_MASK = (END_BUF | SEMI_END_BUF);
final int ALLOWED_IN_LB = ( LOOK_BEHIND |
BEGIN_LINE |
END_LINE |
BEGIN_BUF |
BEGIN_POSITION );
final int ALLOWED_IN_LB_NOT = ( LOOK_BEHIND |
LOOK_BEHIND_NOT |
BEGIN_LINE |
END_LINE |
BEGIN_BUF |
BEGIN_POSITION );
}

@ -0,0 +1,31 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface Arguments {
final int SPECIAL = -1;
final int NON = 0;
final int RELADDR = 1;
final int ABSADDR = 2;
final int LENGTH = 3;
final int MEMNUM = 4;
final int OPTION = 5;
final int STATE_CHECK = 6;
}

@ -0,0 +1,49 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface AsmConstants {
final int THIS = 0;
// argument indexes
final int RANGE = 1;
final int SSTART = 2;
final int SPREV = 3;
// local var indexes
final int S = 4; // current index
final int BYTES = 5; // string
final int LAST_INDEX = BYTES + 1;
// frequently used field names (all ints)
final String STR = "str";
final String END = "end";
final String MSA_START = "msaStart";
final String MSA_OPTONS = "msaOptions";
final String MSA_BEST_LEN = "msaBestLen";
final String MSA_BEST_S = "msaBestS";
final String MSA_BEGIN = "msaBegin";
final String MSA_END = "msaEnd";
// generated field names
final String BITSET = "bitset";
final String CODERANGE = "range";
final String TEMPLATE = "template";
}

@ -0,0 +1,27 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public enum CCSTATE {
VALUE,
RANGE,
COMPLETE,
START
}

@ -0,0 +1,26 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public enum CCVALTYPE {
SB,
CODE_POINT,
CLASS
}

@ -0,0 +1,29 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface EncloseType {
final int MEMORY = 1<<0;
final int OPTION = 1<<1;
final int STOP_BACKTRACK = 1<<2;
final int ALLOWED_IN_LB = MEMORY;
final int ALLOWED_IN_LB_NOT = 0;
}

@ -0,0 +1,31 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface MetaChar {
final int ESCAPE = 0;
final int ANYCHAR = 1;
final int ANYTIME = 2;
final int ZERO_OR_ONE_TIME = 3;
final int ONE_OR_MORE_TIME = 4;
final int ANYCHAR_ANYTIME = 5;
final int INEFFECTIVE_META_CHAR = 0;
}

@ -0,0 +1,39 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface NodeStatus {
/* status bits */
final int NST_MIN_FIXED = (1<<0);
final int NST_MAX_FIXED = (1<<1);
final int NST_CLEN_FIXED = (1<<2);
final int NST_MARK1 = (1<<3);
final int NST_MARK2 = (1<<4);
final int NST_MEM_BACKREFED = (1<<5);
final int NST_STOP_BT_SIMPLE_REPEAT= (1<<6);
final int NST_RECURSION = (1<<7);
final int NST_CALLED = (1<<8);
final int NST_ADDR_FIXED = (1<<9);
final int NST_NAMED_GROUP = (1<<10);
final int NST_NAME_REF = (1<<11);
final int NST_IN_REPEAT = (1<<12); /* STK_REPEAT is nested in stack. */
final int NST_NEST_LEVEL = (1<<13);
final int NST_BY_NUMBER = (1<<14); /* {n,m} */
}

@ -0,0 +1,66 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface NodeType {
/* node type */
final int STR = 0;
final int CCLASS = 1;
final int CTYPE = 2;
final int CANY = 3;
final int BREF = 4;
final int QTFR = 5;
final int ENCLOSE = 6;
final int ANCHOR = 7;
final int LIST = 8;
final int ALT = 9;
final int CALL = 10;
final int BIT_STR = 1 << STR;
final int BIT_CCLASS = 1 << CCLASS;
final int BIT_CTYPE = 1 << CTYPE;
final int BIT_CANY = 1 << CANY;
final int BIT_BREF = 1 << BREF;
final int BIT_QTFR = 1 << QTFR;
final int BIT_ENCLOSE = 1 << ENCLOSE;
final int BIT_ANCHOR = 1 << ANCHOR;
final int BIT_LIST = 1 << LIST;
final int BIT_ALT = 1 << ALT;
final int BIT_CALL = 1 << CALL;
/* allowed node types in look-behind */
final int ALLOWED_IN_LB = ( BIT_LIST |
BIT_ALT |
BIT_STR |
BIT_CCLASS |
BIT_CTYPE |
BIT_CANY |
BIT_ANCHOR |
BIT_ENCLOSE |
BIT_QTFR |
BIT_CALL );
final int SIMPLE = ( BIT_STR |
BIT_CCLASS |
BIT_CTYPE |
BIT_CANY |
BIT_BREF);
}

@ -0,0 +1,387 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
public interface OPCode {
final int FINISH = 0; /* matching process terminator (no more alternative) */
final int END = 1; /* pattern code terminator (success end) */
final int EXACT1 = 2; /* single byte, N = 1 */
final int EXACT2 = 3; /* single byte, N = 2 */
final int EXACT3 = 4; /* single byte, N = 3 */
final int EXACT4 = 5; /* single byte, N = 4 */
final int EXACT5 = 6; /* single byte, N = 5 */
final int EXACTN = 7; /* single byte */
final int EXACTMB2N1 = 8; /* mb-length = 2 N = 1 */
final int EXACTMB2N2 = 9; /* mb-length = 2 N = 2 */
final int EXACTMB2N3 = 10; /* mb-length = 2 N = 3 */
final int EXACTMB2N = 11; /* mb-length = 2 */
final int EXACTMB3N = 12; /* mb-length = 3 */
final int EXACTMBN = 13; /* other length */
final int EXACT1_IC = 14; /* single byte, N = 1, ignore case */
final int EXACTN_IC = 15; /* single byte, ignore case */
final int CCLASS = 16;
final int CCLASS_MB = 17;
final int CCLASS_MIX = 18;
final int CCLASS_NOT = 19;
final int CCLASS_MB_NOT = 20;
final int CCLASS_MIX_NOT = 21;
final int CCLASS_NODE = 22; /* pointer to CClassNode node */
final int ANYCHAR = 23; /* "." */
final int ANYCHAR_ML = 24; /* "." multi-line */
final int ANYCHAR_STAR = 25; /* ".*" */
final int ANYCHAR_ML_STAR = 26; /* ".*" multi-line */
final int ANYCHAR_STAR_PEEK_NEXT = 27;
final int ANYCHAR_ML_STAR_PEEK_NEXT = 28;
final int WORD = 29;
final int NOT_WORD = 30;
final int WORD_BOUND = 31;
final int NOT_WORD_BOUND = 32;
final int WORD_BEGIN = 33;
final int WORD_END = 34;
final int BEGIN_BUF = 35;
final int END_BUF = 36;
final int BEGIN_LINE = 37;
final int END_LINE = 38;
final int SEMI_END_BUF = 39;
final int BEGIN_POSITION = 40;
final int BACKREF1 = 41;
final int BACKREF2 = 42;
final int BACKREFN = 43;
final int BACKREFN_IC = 44;
final int BACKREF_MULTI = 45;
final int BACKREF_MULTI_IC = 46;
final int BACKREF_WITH_LEVEL = 47; /* \k<xxx+n>, \k<xxx-n> */
final int MEMORY_START = 48;
final int MEMORY_START_PUSH = 49; /* push back-tracker to stack */
final int MEMORY_END_PUSH = 50; /* push back-tracker to stack */
final int MEMORY_END_PUSH_REC = 51; /* push back-tracker to stack */
final int MEMORY_END = 52;
final int MEMORY_END_REC = 53; /* push marker to stack */
final int FAIL = 54; /* pop stack and move */
final int JUMP = 55;
final int PUSH = 56;
final int POP = 57;
final int PUSH_OR_JUMP_EXACT1 = 58; /* if match exact then push, else jump. */
final int PUSH_IF_PEEK_NEXT = 59; /* if match exact then push, else none. */
final int REPEAT = 60; /* {n,m} */
final int REPEAT_NG = 61; /* {n,m}? (non greedy) */
final int REPEAT_INC = 62;
final int REPEAT_INC_NG = 63; /* non greedy */
final int REPEAT_INC_SG = 64; /* search and get in stack */
final int REPEAT_INC_NG_SG = 65; /* search and get in stack (non greedy) */
final int NULL_CHECK_START = 66; /* null loop checker start */
final int NULL_CHECK_END = 67; /* null loop checker end */
final int NULL_CHECK_END_MEMST = 68; /* null loop checker end (with capture status) */
final int NULL_CHECK_END_MEMST_PUSH = 69; /* with capture status and push check-end */
final int PUSH_POS = 70; /* (?=...) start */
final int POP_POS = 71; /* (?=...) end */
final int PUSH_POS_NOT = 72; /* (?!...) start */
final int FAIL_POS = 73; /* (?!...) end */
final int PUSH_STOP_BT = 74; /* (?>...) start */
final int POP_STOP_BT = 75; /* (?>...) end */
final int LOOK_BEHIND = 76; /* (?<=...) start (no needs end opcode) */
final int PUSH_LOOK_BEHIND_NOT = 77; /* (?<!...) start */
final int FAIL_LOOK_BEHIND_NOT = 78; /* (?<!...) end */
final int CALL = 79; /* \g<name> */
final int RETURN = 80;
final int STATE_CHECK_PUSH = 81; /* combination explosion check and push */
final int STATE_CHECK_PUSH_OR_JUMP = 82; /* check ok -> push, else jump */
final int STATE_CHECK = 83; /* check only */
final int STATE_CHECK_ANYCHAR_STAR = 84;
final int STATE_CHECK_ANYCHAR_ML_STAR = 85;
/* no need: IS_DYNAMIC_OPTION() == 0 */
final int SET_OPTION_PUSH = 86; /* set option and push recover option */
final int SET_OPTION = 87; /* set option */
// single byte versions
final int ANYCHAR_SB = 88; /* "." */
final int ANYCHAR_ML_SB = 89; /* "." multi-line */
final int ANYCHAR_STAR_SB = 90; /* ".*" */
final int ANYCHAR_ML_STAR_SB = 91; /* ".*" multi-line */
final int ANYCHAR_STAR_PEEK_NEXT_SB = 92;
final int ANYCHAR_ML_STAR_PEEK_NEXT_SB = 93;
final int STATE_CHECK_ANYCHAR_STAR_SB = 94;
final int STATE_CHECK_ANYCHAR_ML_STAR_SB= 95;
final int CCLASS_SB = 96;
final int CCLASS_NOT_SB = 97;
final int WORD_SB = 98;
final int NOT_WORD_SB = 99;
final int WORD_BOUND_SB = 100;
final int NOT_WORD_BOUND_SB = 101;
final int WORD_BEGIN_SB = 102;
final int WORD_END_SB = 103;
final int LOOK_BEHIND_SB = 104;
final int EXACT1_IC_SB = 105; /* single byte, N = 1, ignore case */
final int EXACTN_IC_SB = 106; /* single byte, ignore case */
public final String OpCodeNames[] = Config.DEBUG_COMPILE ? new String[] {
"finish", /*OP_FINISH*/
"end", /*OP_END*/
"exact1", /*OP_EXACT1*/
"exact2", /*OP_EXACT2*/
"exact3", /*OP_EXACT3*/
"exact4", /*OP_EXACT4*/
"exact5", /*OP_EXACT5*/
"exactn", /*OP_EXACTN*/
"exactmb2-n1", /*OP_EXACTMB2N1*/
"exactmb2-n2", /*OP_EXACTMB2N2*/
"exactmb2-n3", /*OP_EXACTMB2N3*/
"exactmb2-n", /*OP_EXACTMB2N*/
"exactmb3n", /*OP_EXACTMB3N*/
"exactmbn", /*OP_EXACTMBN*/
"exact1-ic", /*OP_EXACT1_IC*/
"exactn-ic", /*OP_EXACTN_IC*/
"cclass", /*OP_CCLASS*/
"cclass-mb", /*OP_CCLASS_MB*/
"cclass-mix", /*OP_CCLASS_MIX*/
"cclass-not", /*OP_CCLASS_NOT*/
"cclass-mb-not", /*OP_CCLASS_MB_NOT*/
"cclass-mix-not", /*OP_CCLASS_MIX_NOT*/
"cclass-node", /*OP_CCLASS_NODE*/
"anychar", /*OP_ANYCHAR*/
"anychar-ml", /*OP_ANYCHAR_ML*/
"anychar*", /*OP_ANYCHAR_STAR*/
"anychar-ml*", /*OP_ANYCHAR_ML_STAR*/
"anychar*-peek-next", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
"anychar-ml*-peek-next", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
"word", /*OP_WORD*/
"not-word", /*OP_NOT_WORD*/
"word-bound", /*OP_WORD_BOUND*/
"not-word-bound", /*OP_NOT_WORD_BOUND*/
"word-begin", /*OP_WORD_BEGIN*/
"word-end", /*OP_WORD_END*/
"begin-buf", /*OP_BEGIN_BUF*/
"end-buf", /*OP_END_BUF*/
"begin-line", /*OP_BEGIN_LINE*/
"end-line", /*OP_END_LINE*/
"semi-end-buf", /*OP_SEMI_END_BUF*/
"begin-position", /*OP_BEGIN_POSITION*/
"backref1", /*OP_BACKREF1*/
"backref2", /*OP_BACKREF2*/
"backrefn", /*OP_BACKREFN*/
"backrefn-ic", /*OP_BACKREFN_IC*/
"backref_multi", /*OP_BACKREF_MULTI*/
"backref_multi-ic", /*OP_BACKREF_MULTI_IC*/
"backref_at_level", /*OP_BACKREF_AT_LEVEL*/
"mem-start", /*OP_MEMORY_START*/
"mem-start-push", /*OP_MEMORY_START_PUSH*/
"mem-end-push", /*OP_MEMORY_END_PUSH*/
"mem-end-push-rec", /*OP_MEMORY_END_PUSH_REC*/
"mem-end", /*OP_MEMORY_END*/
"mem-end-rec", /*OP_MEMORY_END_REC*/
"fail", /*OP_FAIL*/
"jump", /*OP_JUMP*/
"push", /*OP_PUSH*/
"pop", /*OP_POP*/
"push-or-jump-e1", /*OP_PUSH_OR_JUMP_EXACT1*/
"push-if-peek-next", /*OP_PUSH_IF_PEEK_NEXT*/
"repeat", /*OP_REPEAT*/
"repeat-ng", /*OP_REPEAT_NG*/
"repeat-inc", /*OP_REPEAT_INC*/
"repeat-inc-ng", /*OP_REPEAT_INC_NG*/
"repeat-inc-sg", /*OP_REPEAT_INC_SG*/
"repeat-inc-ng-sg", /*OP_REPEAT_INC_NG_SG*/
"null-check-start", /*OP_NULL_CHECK_START*/
"null-check-end", /*OP_NULL_CHECK_END*/
"null-check-end-memst", /*OP_NULL_CHECK_END_MEMST*/
"null-check-end-memst-push", /*OP_NULL_CHECK_END_MEMST_PUSH*/
"push-pos", /*OP_PUSH_POS*/
"pop-pos", /*OP_POP_POS*/
"push-pos-not", /*OP_PUSH_POS_NOT*/
"fail-pos", /*OP_FAIL_POS*/
"push-stop-bt", /*OP_PUSH_STOP_BT*/
"pop-stop-bt", /*OP_POP_STOP_BT*/
"look-behind", /*OP_LOOK_BEHIND*/
"push-look-behind-not", /*OP_PUSH_LOOK_BEHIND_NOT*/
"fail-look-behind-not", /*OP_FAIL_LOOK_BEHIND_NOT*/
"call", /*OP_CALL*/
"return", /*OP_RETURN*/
"state-check-push", /*OP_STATE_CHECK_PUSH*/
"state-check-push-or-jump", /*OP_STATE_CHECK_PUSH_OR_JUMP*/
"state-check", /*OP_STATE_CHECK*/
"state-check-anychar*", /*OP_STATE_CHECK_ANYCHAR_STAR*/
"state-check-anychar-ml*", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
"set-option-push", /*OP_SET_OPTION_PUSH*/
"set-option", /*OP_SET_OPTION*/
// single byte versions
"anychar-sb", /*OP_ANYCHAR*/
"anychar-ml-sb", /*OP_ANYCHAR_ML*/
"anychar*-sb", /*OP_ANYCHAR_STAR*/
"anychar-ml*-sb", /*OP_ANYCHAR_ML_STAR*/
"anychar*-peek-next-sb", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
"anychar-ml*-peek-next-sb", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
"state-check-anychar*-sb", /*OP_STATE_CHECK_ANYCHAR_STAR*/
"state-check-anychar-ml*-sb", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
"cclass-sb", /*OP_CCLASS*/
"cclass-not-sb", /*OP_CCLASS_NOT*/
"word-sb", /*OP_WORD*/
"not-word-sb", /*OP_NOT_WORD*/
"word-bound-sb", /*OP_WORD_BOUND*/
"not-word-bound-sb", /*OP_NOT_WORD_BOUND*/
"word-begin-sb", /*OP_WORD_BEGIN*/
"word-end-sb", /*OP_WORD_END*/
"look-behind-sb", /*OP_LOOK_BEHIND*/
"exact1-ic-sb", /*OP_EXACT1_IC*/
"exactn-ic-sb", /*OP_EXACTN_IC*/
} : null;
public final int OpCodeArgTypes[] = Config.DEBUG_COMPILE ? new int[] {
Arguments.NON, /*OP_FINISH*/
Arguments.NON, /*OP_END*/
Arguments.SPECIAL, /*OP_EXACT1*/
Arguments.SPECIAL, /*OP_EXACT2*/
Arguments.SPECIAL, /*OP_EXACT3*/
Arguments.SPECIAL, /*OP_EXACT4*/
Arguments.SPECIAL, /*OP_EXACT5*/
Arguments.SPECIAL, /*OP_EXACTN*/
Arguments.SPECIAL, /*OP_EXACTMB2N1*/
Arguments.SPECIAL, /*OP_EXACTMB2N2*/
Arguments.SPECIAL, /*OP_EXACTMB2N3*/
Arguments.SPECIAL, /*OP_EXACTMB2N*/
Arguments.SPECIAL, /*OP_EXACTMB3N*/
Arguments.SPECIAL, /*OP_EXACTMBN*/
Arguments.SPECIAL, /*OP_EXACT1_IC*/
Arguments.SPECIAL, /*OP_EXACTN_IC*/
Arguments.SPECIAL, /*OP_CCLASS*/
Arguments.SPECIAL, /*OP_CCLASS_MB*/
Arguments.SPECIAL, /*OP_CCLASS_MIX*/
Arguments.SPECIAL, /*OP_CCLASS_NOT*/
Arguments.SPECIAL, /*OP_CCLASS_MB_NOT*/
Arguments.SPECIAL, /*OP_CCLASS_MIX_NOT*/
Arguments.SPECIAL, /*OP_CCLASS_NODE*/
Arguments.NON, /*OP_ANYCHAR*/
Arguments.NON, /*OP_ANYCHAR_ML*/
Arguments.NON, /*OP_ANYCHAR_STAR*/
Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
Arguments.NON, /*OP_WORD*/
Arguments.NON, /*OP_NOT_WORD*/
Arguments.NON, /*OP_WORD_BOUND*/
Arguments.NON, /*OP_NOT_WORD_BOUND*/
Arguments.NON, /*OP_WORD_BEGIN*/
Arguments.NON, /*OP_WORD_END*/
Arguments.NON, /*OP_BEGIN_BUF*/
Arguments.NON, /*OP_END_BUF*/
Arguments.NON, /*OP_BEGIN_LINE*/
Arguments.NON, /*OP_END_LINE*/
Arguments.NON, /*OP_SEMI_END_BUF*/
Arguments.NON, /*OP_BEGIN_POSITION*/
Arguments.NON, /*OP_BACKREF1*/
Arguments.NON, /*OP_BACKREF2*/
Arguments.MEMNUM, /*OP_BACKREFN*/
Arguments.SPECIAL, /*OP_BACKREFN_IC*/
Arguments.SPECIAL, /*OP_BACKREF_MULTI*/
Arguments.SPECIAL, /*OP_BACKREF_MULTI_IC*/
Arguments.SPECIAL, /*OP_BACKREF_AT_LEVEL*/
Arguments.MEMNUM, /*OP_MEMORY_START*/
Arguments.MEMNUM, /*OP_MEMORY_START_PUSH*/
Arguments.MEMNUM, /*OP_MEMORY_END_PUSH*/
Arguments.MEMNUM, /*OP_MEMORY_END_PUSH_REC*/
Arguments.MEMNUM, /*OP_MEMORY_END*/
Arguments.MEMNUM, /*OP_MEMORY_END_REC*/
Arguments.NON, /*OP_FAIL*/
Arguments.RELADDR, /*OP_JUMP*/
Arguments.RELADDR, /*OP_PUSH*/
Arguments.NON, /*OP_POP*/
Arguments.SPECIAL, /*OP_PUSH_OR_JUMP_EXACT1*/
Arguments.SPECIAL, /*OP_PUSH_IF_PEEK_NEXT*/
Arguments.SPECIAL, /*OP_REPEAT*/
Arguments.SPECIAL, /*OP_REPEAT_NG*/
Arguments.MEMNUM, /*OP_REPEAT_INC*/
Arguments.MEMNUM, /*OP_REPEAT_INC_NG*/
Arguments.MEMNUM, /*OP_REPEAT_INC_SG*/
Arguments.MEMNUM, /*OP_REPEAT_INC_NG_SG*/
Arguments.MEMNUM, /*OP_NULL_CHECK_START*/
Arguments.MEMNUM, /*OP_NULL_CHECK_END*/
Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST*/
Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST_PUSH*/
Arguments.NON, /*OP_PUSH_POS*/
Arguments.NON, /*OP_POP_POS*/
Arguments.RELADDR, /*OP_PUSH_POS_NOT*/
Arguments.NON, /*OP_FAIL_POS*/
Arguments.NON, /*OP_PUSH_STOP_BT*/
Arguments.NON, /*OP_POP_STOP_BT*/
Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
Arguments.SPECIAL, /*OP_PUSH_LOOK_BEHIND_NOT*/
Arguments.NON, /*OP_FAIL_LOOK_BEHIND_NOT*/
Arguments.ABSADDR, /*OP_CALL*/
Arguments.NON, /*OP_RETURN*/
Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH*/
Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH_OR_JUMP*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
Arguments.OPTION, /*OP_SET_OPTION_PUSH*/
Arguments.OPTION, /*OP_SET_OPTION*/
// single byte versions
Arguments.NON, /*OP_ANYCHAR*/
Arguments.NON, /*OP_ANYCHAR_ML*/
Arguments.NON, /*OP_ANYCHAR_STAR*/
Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
Arguments.SPECIAL, /*OP_CCLASS*/
Arguments.SPECIAL, /*OP_CCLASS_NOT*/
Arguments.NON, /*OP_WORD*/
Arguments.NON, /*OP_NOT_WORD*/
Arguments.NON, /*OP_WORD_BOUND*/
Arguments.NON, /*OP_NOT_WORD_BOUND*/
Arguments.NON, /*OP_WORD_BEGIN*/
Arguments.NON, /*OP_WORD_END*/
Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
Arguments.SPECIAL, /*OP_EXACT1_IC*/
Arguments.SPECIAL, /*OP_EXACTN_IC*/
} : null;
}

@ -0,0 +1,76 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface OPSize {
// this might be helpful for potential byte[] migration
final int OPCODE = 1;
final int RELADDR = 1;
final int ABSADDR = 1;
final int LENGTH = 1;
final int MEMNUM = 1;
final int STATE_CHECK_NUM = 1;
final int REPEATNUM = 1;
final int OPTION = 1;
final int CODE_POINT = 1;
final int POINTER = 1;
final int INDEX = 1;
/* op-code + arg size */
final int ANYCHAR_STAR = OPCODE;
final int ANYCHAR_STAR_PEEK_NEXT = (OPCODE + 1);
final int JUMP = (OPCODE + RELADDR);
final int PUSH = (OPCODE + RELADDR);
final int POP = OPCODE;
final int PUSH_OR_JUMP_EXACT1 = (OPCODE + RELADDR + 1);
final int PUSH_IF_PEEK_NEXT = (OPCODE + RELADDR + 1);
final int REPEAT_INC = (OPCODE + MEMNUM);
final int REPEAT_INC_NG = (OPCODE + MEMNUM);
final int PUSH_POS = OPCODE;
final int PUSH_POS_NOT = (OPCODE + RELADDR);
final int POP_POS = OPCODE;
final int FAIL_POS = OPCODE;
final int SET_OPTION = (OPCODE + OPTION);
final int SET_OPTION_PUSH = (OPCODE + OPTION);
final int FAIL = OPCODE;
final int MEMORY_START = (OPCODE + MEMNUM);
final int MEMORY_START_PUSH = (OPCODE + MEMNUM);
final int MEMORY_END_PUSH = (OPCODE + MEMNUM);
final int MEMORY_END_PUSH_REC = (OPCODE + MEMNUM);
final int MEMORY_END = (OPCODE + MEMNUM);
final int MEMORY_END_REC = (OPCODE + MEMNUM);
final int PUSH_STOP_BT = OPCODE;
final int POP_STOP_BT = OPCODE;
final int NULL_CHECK_START = (OPCODE + MEMNUM);
final int NULL_CHECK_END = (OPCODE + MEMNUM);
final int LOOK_BEHIND = (OPCODE + LENGTH);
final int PUSH_LOOK_BEHIND_NOT = (OPCODE + RELADDR + LENGTH);
final int FAIL_LOOK_BEHIND_NOT = OPCODE;
final int CALL = (OPCODE + ABSADDR);
final int RETURN = OPCODE;
// #ifdef USE_COMBINATION_EXPLOSION_CHECK
final int STATE_CHECK = (OPCODE + STATE_CHECK_NUM);
final int STATE_CHECK_PUSH = (OPCODE + STATE_CHECK_NUM + RELADDR);
final int STATE_CHECK_PUSH_OR_JUMP = (OPCODE + STATE_CHECK_NUM + RELADDR);
final int STATE_CHECK_ANYCHAR_STAR = (OPCODE + STATE_CHECK_NUM);
}

@ -0,0 +1,61 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.A;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.AQ;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.ASIS;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.DEL;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.PQ_Q;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.P_QQ;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.QQ;
public interface Reduce {
enum ReduceType {
ASIS, /* as is */
DEL, /* delete parent */
A, /* to '*' */
AQ, /* to '*?' */
QQ, /* to '??' */
P_QQ, /* to '+)??' */
PQ_Q, /* to '+?)?' */
}
final ReduceType[][]REDUCE_TABLE = {
{DEL, A, A, QQ, AQ, ASIS}, /* '?' */
{DEL, DEL, DEL, P_QQ, P_QQ, DEL}, /* '*' */
{A, A, DEL, ASIS, P_QQ, DEL}, /* '+' */
{DEL, AQ, AQ, DEL, AQ, AQ}, /* '??' */
{DEL, DEL, DEL, DEL, DEL, DEL}, /* '*?' */
{ASIS, PQ_Q, DEL, AQ, AQ, DEL} /* '+?' */
};
final String PopularQStr[] = new String[] {
"?", "*", "+", "??", "*?", "+?"
};
String ReduceQStr[]= new String[] {
"", "", "*", "*?", "??", "+ and ??", "+? and ?"
};
}

@ -0,0 +1,28 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
// we dont need this ATM
public interface RegexState {
final int NORMAL = 0;
final int SEARCHING = 1;
final int COMPILING = -1;
final int MODIFY = -2;
}

@ -0,0 +1,27 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface StackPopLevel {
final int FREE = 0;
final int MEM_START = 1;
final int ALL = 2;
}

@ -0,0 +1,51 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface StackType {
/** stack **/
final int INVALID_STACK_INDEX = -1;
/* stack type */
/* used by normal-POP */
final int ALT = 0x0001;
final int LOOK_BEHIND_NOT = 0x0002;
final int POS_NOT = 0x0003;
/* handled by normal-POP */
final int MEM_START = 0x0100;
final int MEM_END = 0x8200;
final int REPEAT_INC = 0x0300;
final int STATE_CHECK_MARK = 0x1000;
/* avoided by normal-POP */
final int NULL_CHECK_START = 0x3000;
final int NULL_CHECK_END = 0x5000; /* for recursive call */
final int MEM_END_MARK = 0x8400;
final int POS = 0x0500; /* used when POP-POS */
final int STOP_BT = 0x0600; /* mark for "(?>...)" */
final int REPEAT = 0x0700;
final int CALL_FRAME = 0x0800;
final int RETURN = 0x0900;
final int VOID = 0x0a00; /* for fill a blank */
/* stack type check mask */
final int MASK_POP_USED = 0x00ff;
final int MASK_TO_VOID_TARGET = 0x10ff;
final int MASK_MEM_END_OR_MARK = 0x8000; /* MEM_END or MEM_END_MARK */
}

@ -0,0 +1,27 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface StringType {
final int NSTR_RAW = 1<<0;
final int NSTR_AMBIG = 1<<1;
final int NSTR_DONT_GET_OPT_INFO = 1<<2;
final int NSTR_SHARED = 1<<3;
}

@ -0,0 +1,124 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface SyntaxProperties {
/* syntax (operators); */
final int OP_VARIABLE_META_CHARACTERS = (1<<0);
final int OP_DOT_ANYCHAR = (1<<1); /* . */
final int OP_ASTERISK_ZERO_INF = (1<<2); /* * */
final int OP_ESC_ASTERISK_ZERO_INF = (1<<3);
final int OP_PLUS_ONE_INF = (1<<4); /* + */
final int OP_ESC_PLUS_ONE_INF = (1<<5);
final int OP_QMARK_ZERO_ONE = (1<<6); /* ? */
final int OP_ESC_QMARK_ZERO_ONE = (1<<7);
final int OP_BRACE_INTERVAL = (1<<8); /* {lower,upper} */
final int OP_ESC_BRACE_INTERVAL = (1<<9); /* \{lower,upper\} */
final int OP_VBAR_ALT = (1<<10); /* | */
final int OP_ESC_VBAR_ALT = (1<<11); /* \| */
final int OP_LPAREN_SUBEXP = (1<<12); /* (...); */
final int OP_ESC_LPAREN_SUBEXP = (1<<13); /* \(...\); */
final int OP_ESC_AZ_BUF_ANCHOR = (1<<14); /* \A, \Z, \z */
final int OP_ESC_CAPITAL_G_BEGIN_ANCHOR = (1<<15); /* \G */
final int OP_DECIMAL_BACKREF = (1<<16); /* \num */
final int OP_BRACKET_CC = (1<<17); /* [...] */
final int OP_ESC_W_WORD = (1<<18); /* \w, \W */
final int OP_ESC_LTGT_WORD_BEGIN_END = (1<<19); /* \<. \> */
final int OP_ESC_B_WORD_BOUND = (1<<20); /* \b, \B */
final int OP_ESC_S_WHITE_SPACE = (1<<21); /* \s, \S */
final int OP_ESC_D_DIGIT = (1<<22); /* \d, \D */
final int OP_LINE_ANCHOR = (1<<23); /* ^, $ */
final int OP_POSIX_BRACKET = (1<<24); /* [:xxxx:] */
final int OP_QMARK_NON_GREEDY = (1<<25); /* ??,*?,+?,{n,m}? */
final int OP_ESC_CONTROL_CHARS = (1<<26); /* \n,\r,\t,\a ... */
final int OP_ESC_C_CONTROL = (1<<27); /* \cx */
final int OP_ESC_OCTAL3 = (1<<28); /* \OOO */
final int OP_ESC_X_HEX2 = (1<<29); /* \xHH */
final int OP_ESC_X_BRACE_HEX8 = (1<<30); /* \x{7HHHHHHH} */
final int OP2_ESC_CAPITAL_Q_QUOTE = (1<<0); /* \Q...\E */
final int OP2_QMARK_GROUP_EFFECT = (1<<1); /* (?...); */
final int OP2_OPTION_PERL = (1<<2); /* (?imsx);,(?-imsx); */
final int OP2_OPTION_RUBY = (1<<3); /* (?imx);, (?-imx); */
final int OP2_PLUS_POSSESSIVE_REPEAT = (1<<4); /* ?+,*+,++ */
final int OP2_PLUS_POSSESSIVE_INTERVAL = (1<<5); /* {n,m}+ */
final int OP2_CCLASS_SET_OP = (1<<6); /* [...&&..[..]..] */
final int OP2_QMARK_LT_NAMED_GROUP = (1<<7); /* (?<name>...); */
final int OP2_ESC_K_NAMED_BACKREF = (1<<8); /* \k<name> */
final int OP2_ESC_G_SUBEXP_CALL = (1<<9); /* \g<name>, \g<n> */
final int OP2_ATMARK_CAPTURE_HISTORY = (1<<10); /* (?@..);,(?@<x>..); */
final int OP2_ESC_CAPITAL_C_BAR_CONTROL = (1<<11); /* \C-x */
final int OP2_ESC_CAPITAL_M_BAR_META = (1<<12); /* \M-x */
final int OP2_ESC_V_VTAB = (1<<13); /* \v as VTAB */
final int OP2_ESC_U_HEX4 = (1<<14); /* \\uHHHH */
final int OP2_ESC_GNU_BUF_ANCHOR = (1<<15); /* \`, \' */
final int OP2_ESC_P_BRACE_CHAR_PROPERTY = (1<<16); /* \p{...}, \P{...} */
final int OP2_ESC_P_BRACE_CIRCUMFLEX_NOT = (1<<17); /* \p{^..}, \P{^..} */
/* final int OP2_CHAR_PROPERTY_PREFIX_IS = (1<<18); */
final int OP2_ESC_H_XDIGIT = (1<<19); /* \h, \H */
final int OP2_INEFFECTIVE_ESCAPE = (1<<20); /* \ */
/* syntax (behavior); */
final int CONTEXT_INDEP_ANCHORS = (1<<31); /* not implemented */
final int CONTEXT_INDEP_REPEAT_OPS = (1<<0); /* ?, *, +, {n,m} */
final int CONTEXT_INVALID_REPEAT_OPS = (1<<1); /* error or ignore */
final int ALLOW_UNMATCHED_CLOSE_SUBEXP = (1<<2); /* ...);... */
final int ALLOW_INVALID_INTERVAL = (1<<3); /* {??? */
final int ALLOW_INTERVAL_LOW_ABBREV = (1<<4); /* {,n} => {0,n} */
final int STRICT_CHECK_BACKREF = (1<<5); /* /(\1);/,/\1();/ ..*/
final int DIFFERENT_LEN_ALT_LOOK_BEHIND = (1<<6); /* (?<=a|bc); */
final int CAPTURE_ONLY_NAMED_GROUP = (1<<7); /* see doc/RE */
final int ALLOW_MULTIPLEX_DEFINITION_NAME = (1<<8); /* (?<x>);(?<x>); */
final int FIXED_INTERVAL_IS_GREEDY_ONLY = (1<<9); /* a{n}?=(?:a{n});? */
/* syntax (behavior); in char class [...] */
final int NOT_NEWLINE_IN_NEGATIVE_CC = (1<<20); /* [^...] */
final int BACKSLASH_ESCAPE_IN_CC = (1<<21); /* [..\w..] etc.. */
final int ALLOW_EMPTY_RANGE_IN_CC = (1<<22);
final int ALLOW_DOUBLE_RANGE_OP_IN_CC = (1<<23); /* [0-9-a]=[0-9\-a] */
/* syntax (behavior); warning */
final int WARN_CC_OP_NOT_ESCAPED = (1<<24); /* [,-,] */
final int WARN_REDUNDANT_NESTED_REPEAT = (1<<25); /* (?:a*);+ */
final int POSIX_COMMON_OP =
OP_DOT_ANYCHAR | OP_POSIX_BRACKET |
OP_DECIMAL_BACKREF |
OP_BRACKET_CC | OP_ASTERISK_ZERO_INF |
OP_LINE_ANCHOR |
OP_ESC_CONTROL_CHARS;
final int GNU_REGEX_OP =
OP_DOT_ANYCHAR | OP_BRACKET_CC |
OP_POSIX_BRACKET | OP_DECIMAL_BACKREF |
OP_BRACE_INTERVAL | OP_LPAREN_SUBEXP |
OP_VBAR_ALT |
OP_ASTERISK_ZERO_INF | OP_PLUS_ONE_INF |
OP_QMARK_ZERO_ONE |
OP_ESC_AZ_BUF_ANCHOR | OP_ESC_CAPITAL_G_BEGIN_ANCHOR |
OP_ESC_W_WORD |
OP_ESC_B_WORD_BOUND | OP_ESC_LTGT_WORD_BEGIN_END |
OP_ESC_S_WHITE_SPACE | OP_ESC_D_DIGIT |
OP_LINE_ANCHOR;
final int GNU_REGEX_BV =
CONTEXT_INDEP_ANCHORS | CONTEXT_INDEP_REPEAT_OPS |
CONTEXT_INVALID_REPEAT_OPS | ALLOW_INVALID_INTERVAL |
BACKSLASH_ESCAPE_IN_CC | ALLOW_DOUBLE_RANGE_OP_IN_CC;
}

@ -0,0 +1,27 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface TargetInfo {
final int ISNOT_EMPTY = 0;
final int IS_EMPTY = 1;
final int IS_EMPTY_MEM = 2;
final int IS_EMPTY_REC = 3;
}

@ -0,0 +1,48 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public enum TokenType {
EOT, /* end of token */
RAW_BYTE,
CHAR,
STRING,
CODE_POINT,
ANYCHAR,
CHAR_TYPE,
BACKREF,
CALL,
ANCHOR,
OP_REPEAT,
INTERVAL,
ANYCHAR_ANYTIME, /* SQL '%' == .* */
ALT,
SUBEXP_OPEN,
SUBEXP_CLOSE,
CC_OPEN,
QUOTE_OPEN,
CHAR_PROPERTY, /* \p{...}, \P{...} */
/* in cc */
CC_CLOSE,
CC_RANGE,
POSIX_BRACKET_OPEN,
CC_AND, /* && */
CC_CC_OPEN /* [ */
}

@ -0,0 +1,26 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
public interface Traverse {
final int TRAVERSE_CALLBACK_AT_FIRST = 1;
final int TRAVERSE_CALLBACK_AT_LAST = 2;
final int TRAVERSE_CALLBACK_AT_BOTH = TRAVERSE_CALLBACK_AT_FIRST | TRAVERSE_CALLBACK_AT_LAST;
}

@ -0,0 +1,157 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.encoding;
public class AsciiTables {
public static final short AsciiCtypeTable[] = {
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
public static final byte ToLowerCaseTable[] = {
(byte)'\000', (byte)'\001', (byte)'\002', (byte)'\003', (byte)'\004', (byte)'\005', (byte)'\006', (byte)'\007',
(byte)'\010', (byte)'\011', (byte)'\012', (byte)'\013', (byte)'\014', (byte)'\015', (byte)'\016', (byte)'\017',
(byte)'\020', (byte)'\021', (byte)'\022', (byte)'\023', (byte)'\024', (byte)'\025', (byte)'\026', (byte)'\027',
(byte)'\030', (byte)'\031', (byte)'\032', (byte)'\033', (byte)'\034', (byte)'\035', (byte)'\036', (byte)'\037',
(byte)'\040', (byte)'\041', (byte)'\042', (byte)'\043', (byte)'\044', (byte)'\045', (byte)'\046', (byte)'\047',
(byte)'\050', (byte)'\051', (byte)'\052', (byte)'\053', (byte)'\054', (byte)'\055', (byte)'\056', (byte)'\057',
(byte)'\060', (byte)'\061', (byte)'\062', (byte)'\063', (byte)'\064', (byte)'\065', (byte)'\066', (byte)'\067',
(byte)'\070', (byte)'\071', (byte)'\072', (byte)'\073', (byte)'\074', (byte)'\075', (byte)'\076', (byte)'\077',
(byte)'\100', (byte)'\141', (byte)'\142', (byte)'\143', (byte)'\144', (byte)'\145', (byte)'\146', (byte)'\147',
(byte)'\150', (byte)'\151', (byte)'\152', (byte)'\153', (byte)'\154', (byte)'\155', (byte)'\156', (byte)'\157',
(byte)'\160', (byte)'\161', (byte)'\162', (byte)'\163', (byte)'\164', (byte)'\165', (byte)'\166', (byte)'\167',
(byte)'\170', (byte)'\171', (byte)'\172', (byte)'\133', (byte)'\134', (byte)'\135', (byte)'\136', (byte)'\137',
(byte)'\140', (byte)'\141', (byte)'\142', (byte)'\143', (byte)'\144', (byte)'\145', (byte)'\146', (byte)'\147',
(byte)'\150', (byte)'\151', (byte)'\152', (byte)'\153', (byte)'\154', (byte)'\155', (byte)'\156', (byte)'\157',
(byte)'\160', (byte)'\161', (byte)'\162', (byte)'\163', (byte)'\164', (byte)'\165', (byte)'\166', (byte)'\167',
(byte)'\170', (byte)'\171', (byte)'\172', (byte)'\173', (byte)'\174', (byte)'\175', (byte)'\176', (byte)'\177',
(byte)'\200', (byte)'\201', (byte)'\202', (byte)'\203', (byte)'\204', (byte)'\205', (byte)'\206', (byte)'\207',
(byte)'\210', (byte)'\211', (byte)'\212', (byte)'\213', (byte)'\214', (byte)'\215', (byte)'\216', (byte)'\217',
(byte)'\220', (byte)'\221', (byte)'\222', (byte)'\223', (byte)'\224', (byte)'\225', (byte)'\226', (byte)'\227',
(byte)'\230', (byte)'\231', (byte)'\232', (byte)'\233', (byte)'\234', (byte)'\235', (byte)'\236', (byte)'\237',
(byte)'\240', (byte)'\241', (byte)'\242', (byte)'\243', (byte)'\244', (byte)'\245', (byte)'\246', (byte)'\247',
(byte)'\250', (byte)'\251', (byte)'\252', (byte)'\253', (byte)'\254', (byte)'\255', (byte)'\256', (byte)'\257',
(byte)'\260', (byte)'\261', (byte)'\262', (byte)'\263', (byte)'\264', (byte)'\265', (byte)'\266', (byte)'\267',
(byte)'\270', (byte)'\271', (byte)'\272', (byte)'\273', (byte)'\274', (byte)'\275', (byte)'\276', (byte)'\277',
(byte)'\300', (byte)'\301', (byte)'\302', (byte)'\303', (byte)'\304', (byte)'\305', (byte)'\306', (byte)'\307',
(byte)'\310', (byte)'\311', (byte)'\312', (byte)'\313', (byte)'\314', (byte)'\315', (byte)'\316', (byte)'\317',
(byte)'\320', (byte)'\321', (byte)'\322', (byte)'\323', (byte)'\324', (byte)'\325', (byte)'\326', (byte)'\327',
(byte)'\330', (byte)'\331', (byte)'\332', (byte)'\333', (byte)'\334', (byte)'\335', (byte)'\336', (byte)'\337',
(byte)'\340', (byte)'\341', (byte)'\342', (byte)'\343', (byte)'\344', (byte)'\345', (byte)'\346', (byte)'\347',
(byte)'\350', (byte)'\351', (byte)'\352', (byte)'\353', (byte)'\354', (byte)'\355', (byte)'\356', (byte)'\357',
(byte)'\360', (byte)'\361', (byte)'\362', (byte)'\363', (byte)'\364', (byte)'\365', (byte)'\366', (byte)'\367',
(byte)'\370', (byte)'\371', (byte)'\372', (byte)'\373', (byte)'\374', (byte)'\375', (byte)'\376', (byte)'\377',
};
public static final byte ToUpperCaseTable[] = {
(byte)'\000', (byte)'\001', (byte)'\002', (byte)'\003', (byte)'\004', (byte)'\005', (byte)'\006', (byte)'\007',
(byte)'\010', (byte)'\011', (byte)'\012', (byte)'\013', (byte)'\014', (byte)'\015', (byte)'\016', (byte)'\017',
(byte)'\020', (byte)'\021', (byte)'\022', (byte)'\023', (byte)'\024', (byte)'\025', (byte)'\026', (byte)'\027',
(byte)'\030', (byte)'\031', (byte)'\032', (byte)'\033', (byte)'\034', (byte)'\035', (byte)'\036', (byte)'\037',
(byte)'\040', (byte)'\041', (byte)'\042', (byte)'\043', (byte)'\044', (byte)'\045', (byte)'\046', (byte)'\047',
(byte)'\050', (byte)'\051', (byte)'\052', (byte)'\053', (byte)'\054', (byte)'\055', (byte)'\056', (byte)'\057',
(byte)'\060', (byte)'\061', (byte)'\062', (byte)'\063', (byte)'\064', (byte)'\065', (byte)'\066', (byte)'\067',
(byte)'\070', (byte)'\071', (byte)'\072', (byte)'\073', (byte)'\074', (byte)'\075', (byte)'\076', (byte)'\077',
(byte)'\100', (byte)'\101', (byte)'\102', (byte)'\103', (byte)'\104', (byte)'\105', (byte)'\106', (byte)'\107',
(byte)'\110', (byte)'\111', (byte)'\112', (byte)'\113', (byte)'\114', (byte)'\115', (byte)'\116', (byte)'\117',
(byte)'\120', (byte)'\121', (byte)'\122', (byte)'\123', (byte)'\124', (byte)'\125', (byte)'\126', (byte)'\127',
(byte)'\130', (byte)'\131', (byte)'\132', (byte)'\133', (byte)'\134', (byte)'\135', (byte)'\136', (byte)'\137',
(byte)'\140', (byte)'\101', (byte)'\102', (byte)'\103', (byte)'\104', (byte)'\105', (byte)'\106', (byte)'\107',
(byte)'\110', (byte)'\111', (byte)'\112', (byte)'\113', (byte)'\114', (byte)'\115', (byte)'\116', (byte)'\117',
(byte)'\120', (byte)'\121', (byte)'\122', (byte)'\123', (byte)'\124', (byte)'\125', (byte)'\126', (byte)'\127',
(byte)'\130', (byte)'\131', (byte)'\132', (byte)'\173', (byte)'\174', (byte)'\175', (byte)'\176', (byte)'\177',
(byte)'\200', (byte)'\201', (byte)'\202', (byte)'\203', (byte)'\204', (byte)'\205', (byte)'\206', (byte)'\207',
(byte)'\210', (byte)'\211', (byte)'\212', (byte)'\213', (byte)'\214', (byte)'\215', (byte)'\216', (byte)'\217',
(byte)'\220', (byte)'\221', (byte)'\222', (byte)'\223', (byte)'\224', (byte)'\225', (byte)'\226', (byte)'\227',
(byte)'\230', (byte)'\231', (byte)'\232', (byte)'\233', (byte)'\234', (byte)'\235', (byte)'\236', (byte)'\237',
(byte)'\240', (byte)'\241', (byte)'\242', (byte)'\243', (byte)'\244', (byte)'\245', (byte)'\246', (byte)'\247',
(byte)'\250', (byte)'\251', (byte)'\252', (byte)'\253', (byte)'\254', (byte)'\255', (byte)'\256', (byte)'\257',
(byte)'\260', (byte)'\261', (byte)'\262', (byte)'\263', (byte)'\264', (byte)'\265', (byte)'\266', (byte)'\267',
(byte)'\270', (byte)'\271', (byte)'\272', (byte)'\273', (byte)'\274', (byte)'\275', (byte)'\276', (byte)'\277',
(byte)'\300', (byte)'\301', (byte)'\302', (byte)'\303', (byte)'\304', (byte)'\305', (byte)'\306', (byte)'\307',
(byte)'\310', (byte)'\311', (byte)'\312', (byte)'\313', (byte)'\314', (byte)'\315', (byte)'\316', (byte)'\317',
(byte)'\320', (byte)'\321', (byte)'\322', (byte)'\323', (byte)'\324', (byte)'\325', (byte)'\326', (byte)'\327',
(byte)'\330', (byte)'\331', (byte)'\332', (byte)'\333', (byte)'\334', (byte)'\335', (byte)'\336', (byte)'\337',
(byte)'\340', (byte)'\341', (byte)'\342', (byte)'\343', (byte)'\344', (byte)'\345', (byte)'\346', (byte)'\347',
(byte)'\350', (byte)'\351', (byte)'\352', (byte)'\353', (byte)'\354', (byte)'\355', (byte)'\356', (byte)'\357',
(byte)'\360', (byte)'\361', (byte)'\362', (byte)'\363', (byte)'\364', (byte)'\365', (byte)'\366', (byte)'\367',
(byte)'\370', (byte)'\371', (byte)'\372', (byte)'\373', (byte)'\374', (byte)'\375', (byte)'\376', (byte)'\377',
};
public static final int LowerMap[][] = {
{0x41, 0x61},
{0x42, 0x62},
{0x43, 0x63},
{0x44, 0x64},
{0x45, 0x65},
{0x46, 0x66},
{0x47, 0x67},
{0x48, 0x68},
{0x49, 0x69},
{0x4a, 0x6a},
{0x4b, 0x6b},
{0x4c, 0x6c},
{0x4d, 0x6d},
{0x4e, 0x6e},
{0x4f, 0x6f},
{0x50, 0x70},
{0x51, 0x71},
{0x52, 0x72},
{0x53, 0x73},
{0x54, 0x74},
{0x55, 0x75},
{0x56, 0x76},
{0x57, 0x77},
{0x58, 0x78},
{0x59, 0x79},
{0x5a, 0x7a}
};
}

@ -0,0 +1,79 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.encoding;
public interface CharacterType {
final int NEWLINE = 0;
final int ALPHA = 1;
final int BLANK = 2;
final int CNTRL = 3;
final int DIGIT = 4;
final int GRAPH = 5;
final int LOWER = 6;
final int PRINT = 7;
final int PUNCT = 8;
final int SPACE = 9;
final int UPPER = 10;
final int XDIGIT = 11;
final int WORD = 12;
final int ALNUM = 13; /* alpha || digit */
final int ASCII = 14;
final int SPECIAL_MASK = 256;
final int S = SPECIAL_MASK | SPACE;
final int D = SPECIAL_MASK | DIGIT;
final int W = SPECIAL_MASK | WORD;
final int LETTER_MASK = (1 << Character.UPPERCASE_LETTER)
| (1 << Character.LOWERCASE_LETTER)
| (1 << Character.TITLECASE_LETTER)
| (1 << Character.MODIFIER_LETTER)
| (1 << Character.OTHER_LETTER);
final int ALPHA_MASK = LETTER_MASK
| (1 << Character.COMBINING_SPACING_MARK)
| (1 << Character.NON_SPACING_MARK)
| (1 << Character.ENCLOSING_MARK);
final int ALNUM_MASK = ALPHA_MASK
| (1 << Character.DECIMAL_DIGIT_NUMBER);
final int WORD_MASK = ALNUM_MASK
| (1 << Character.CONNECTOR_PUNCTUATION);
final int PUNCT_MASK = (1 << Character.CONNECTOR_PUNCTUATION)
| (1 << Character.DASH_PUNCTUATION)
| (1 << Character.END_PUNCTUATION)
| (1 << Character.FINAL_QUOTE_PUNCTUATION)
| (1 << Character.INITIAL_QUOTE_PUNCTUATION)
| (1 << Character.OTHER_PUNCTUATION)
| (1 << Character.START_PUNCTUATION);
final int CNTRL_MASK = (1 << Character.CONTROL)
| (1 << Character.FORMAT)
| (1 << Character.PRIVATE_USE)
| (1 << Character.SURROGATE);
final int SPACE_MASK = (1 << Character.SPACE_SEPARATOR)
| (1 << Character.LINE_SEPARATOR) // 0x2028
| (1 << Character.PARAGRAPH_SEPARATOR); // 0x2029
final int GRAPH_MASK = SPACE_MASK
| (1 << Character.CONTROL)
| (1 << Character.SURROGATE);
final int PRINT_MASK = (1 << Character.CONTROL)
| (1 << Character.SURROGATE);
}

@ -0,0 +1,24 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.encoding;
public class IntHolder {
public int value;
}

@ -0,0 +1,35 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.encoding;
public final class ObjPtr<T> {
public ObjPtr() {
this(null);
}
public ObjPtr(T p) {
this.p = p;
}
public T p;
static final ObjPtr<Void> NULL = new ObjPtr<Void>();
}

@ -0,0 +1,77 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS".toCharArray(), WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.encoding;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
import java.util.HashMap;
public class PosixBracket {
public static final char[][] PBSNamesLower = {
"alnum".toCharArray(),
"alpha".toCharArray(),
"blank".toCharArray(),
"cntrl".toCharArray(),
"digit".toCharArray(),
"graph".toCharArray(),
"lower".toCharArray(),
"print".toCharArray(),
"punct".toCharArray(),
"space".toCharArray(),
"upper".toCharArray(),
"xdigit".toCharArray(),
"ascii".toCharArray(),
"word".toCharArray()
};
public static final int PBSValues[] = {
CharacterType.ALNUM,
CharacterType.ALPHA,
CharacterType.BLANK,
CharacterType.CNTRL,
CharacterType.DIGIT,
CharacterType.GRAPH,
CharacterType.LOWER,
CharacterType.PRINT,
CharacterType.PUNCT,
CharacterType.SPACE,
CharacterType.UPPER,
CharacterType.XDIGIT,
CharacterType.ASCII,
CharacterType.WORD,
};
public static int propertyNameToCType(String name) {
name = name.toLowerCase();
if (!PBSTableUpper.containsKey(name)) {
throw new JOniException(ErrorMessages.ERR_INVALID_CHAR_PROPERTY_NAME.replaceAll("%n", name));
}
return PBSTableUpper.get(name);
}
private static final HashMap<String,Integer> PBSTableUpper = new HashMap<String,Integer>();
static {
for (int i=0; i<PBSValues.length; i++) PBSTableUpper.put(new String(PBSNamesLower[i]), PBSValues[i]);
}
}

@ -0,0 +1,35 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.encoding;
public final class Ptr {
public Ptr() {
this(0);
}
public Ptr(int p) {
this.p = p;
}
public int p;
public static final Ptr NULL = new Ptr(0);
}

@ -0,0 +1,98 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.exception;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
public interface ErrorMessages {
final String MISMATCH = "mismatch";
final String NO_SUPPORT_CONFIG = "no support in this configuration";
/* from jcodings */
final String ERR_INVALID_CHAR_PROPERTY_NAME = "invalid character property name <%n>";
final String ERR_INVALID_CODE_POINT_VALUE = "invalid code point value";
final String ERR_TOO_BIG_WIDE_CHAR_VALUE = "too big wide-char value";
final String ERR_TOO_LONG_WIDE_CHAR_VALUE = "too long wide-char value";
/* internal error */
final String ERR_MEMORY = "fail to memory allocation";
final String ERR_MATCH_STACK_LIMIT_OVER = "match-stack limit over";
final String ERR_TYPE_BUG = "undefined type (bug)";
final String ERR_PARSER_BUG = "internal parser error (bug)";
final String ERR_STACK_BUG = "stack error (bug)";
final String ERR_UNDEFINED_BYTECODE = "undefined bytecode (bug)";
final String ERR_UNEXPECTED_BYTECODE = "unexpected bytecode (bug)";
final String ERR_DEFAULT_ENCODING_IS_NOT_SETTED = "default multibyte-encoding is not setted";
final String ERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR = "can't convert to wide-char on specified multibyte-encoding";
/* general error */
final String ERR_INVALID_ARGUMENT = "invalid argument";
/* syntax error */
final String ERR_END_PATTERN_AT_LEFT_BRACE = "end pattern at left brace";
final String ERR_END_PATTERN_AT_LEFT_BRACKET = "end pattern at left bracket";
final String ERR_EMPTY_CHAR_CLASS = "empty char-class";
final String ERR_PREMATURE_END_OF_CHAR_CLASS = "premature end of char-class";
final String ERR_END_PATTERN_AT_ESCAPE = "end pattern at escape";
final String ERR_END_PATTERN_AT_META = "end pattern at meta";
final String ERR_END_PATTERN_AT_CONTROL = "end pattern at control";
final String ERR_META_CODE_SYNTAX = "invalid meta-code syntax";
final String ERR_CONTROL_CODE_SYNTAX = "invalid control-code syntax";
final String ERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE = "char-class value at end of range";
final String ERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE = "char-class value at start of range";
final String ERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS = "unmatched range specifier in char-class";
final String ERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED = "target of repeat operator is not specified";
final String ERR_TARGET_OF_REPEAT_OPERATOR_INVALID = "target of repeat operator is invalid";
final String ERR_NESTED_REPEAT_OPERATOR = "nested repeat operator";
final String ERR_UNMATCHED_CLOSE_PARENTHESIS = "unmatched close parenthesis";
final String ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS = "end pattern with unmatched parenthesis";
final String ERR_END_PATTERN_IN_GROUP = "end pattern in group";
final String ERR_UNDEFINED_GROUP_OPTION = "undefined group option";
final String ERR_INVALID_POSIX_BRACKET_TYPE = "invalid POSIX bracket type";
final String ERR_INVALID_LOOK_BEHIND_PATTERN = "invalid pattern in look-behind";
final String ERR_INVALID_REPEAT_RANGE_PATTERN = "invalid repeat range {lower,upper}";
/* values error (syntax error) */
final String ERR_TOO_BIG_NUMBER = "too big number";
final String ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE = "too big number for repeat range";
final String ERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE = "upper is smaller than lower in repeat range";
final String ERR_EMPTY_RANGE_IN_CHAR_CLASS = "empty range in char class";
final String ERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE = "mismatch multibyte code length in char-class range";
final String ERR_TOO_MANY_MULTI_BYTE_RANGES = "too many multibyte code ranges are specified";
final String ERR_TOO_SHORT_MULTI_BYTE_STRING = "too short multibyte code string";
final String ERR_TOO_BIG_BACKREF_NUMBER = "too big backref number";
final String ERR_INVALID_BACKREF = Config.USE_NAMED_GROUP ? "invalid backref number/name" : "invalid backref number";
final String ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED = "numbered backref/call is not allowed. (use name)";
final String ERR_INVALID_WIDE_CHAR_VALUE = "invalid wide-char value";
final String ERR_EMPTY_GROUP_NAME = "group name is empty";
final String ERR_INVALID_GROUP_NAME = "invalid group name <%n>";
final String ERR_INVALID_CHAR_IN_GROUP_NAME = Config.USE_NAMED_GROUP ? "invalid char in group name <%n>" : "invalid char in group number <%n>";
final String ERR_UNDEFINED_NAME_REFERENCE = "undefined name <%n> reference";
final String ERR_UNDEFINED_GROUP_REFERENCE = "undefined group <%n> reference";
final String ERR_MULTIPLEX_DEFINED_NAME = "multiplex defined name <%n>";
final String ERR_MULTIPLEX_DEFINITION_NAME_CALL = "multiplex definition name <%n> call";
final String ERR_NEVER_ENDING_RECURSION = "never ending recursion";
final String ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY = "group number is too big for capture history";
final String ERR_NOT_SUPPORTED_ENCODING_COMBINATION = "not supported encoding combination";
final String ERR_INVALID_COMBINATION_OF_OPTIONS = "invalid combination of options";
final String ERR_OVER_THREAD_PASS_LIMIT_COUNT = "over thread pass limit count";
final String ERR_TOO_BIG_SB_CHAR_VALUE = "too big singlebyte char value";
}

@ -0,0 +1,28 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.exception;
public class InternalException extends JOniException{
private static final long serialVersionUID = -3871816465397927992L;
public InternalException(String message) {
super(message);
}
}

@ -0,0 +1,28 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.exception;
public class JOniException extends RuntimeException{
private static final long serialVersionUID = -6027192180014164667L;
public JOniException(String message) {
super(message);
}
}

@ -0,0 +1,28 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.exception;
public class SyntaxException extends JOniException{
private static final long serialVersionUID = 7862720128961874288L;
public SyntaxException(String message) {
super(message);
}
}

@ -0,0 +1,37 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.exception;
public class ValueException extends SyntaxException{
private static final long serialVersionUID = -196013852479929134L;
public ValueException(String message) {
super(message);
}
public ValueException(String message, String str) {
super(message.replaceAll("%n", str));
}
public ValueException(String message, byte[]bytes, int p, int end) {
this(message, new String(bytes, p, end - p));
}
}