Skip to content
Snippets Groups Projects
Commit 1121a686 authored by Mick Jordan's avatar Mick Jordan
Browse files

[GR-2527] Convert PCRERFFI to one node per method.

parents 1c4fdf04 acdc6ed7
No related branches found
No related tags found
No related merge requests found
...@@ -63,7 +63,8 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; ...@@ -63,7 +63,8 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck;
*/ */
public class GrepFunctions { public class GrepFunctions {
public abstract static class CommonCodeAdapter extends RBuiltinNode { public abstract static class CommonCodeAdapter extends RBuiltinNode {
@Child protected PCRERFFI.PCRERFFINode pcreRFFINode = RFFIFactory.getRFFI().getPCRERFFI().createPCRERFFINode(); @Child protected PCRERFFI.MaketablesNode maketablesNode = RFFIFactory.getRFFI().getPCRERFFI().createMaketablesNode();
@Child protected PCRERFFI.CompileNode compileNode = RFFIFactory.getRFFI().getPCRERFFI().createCompileNode();
protected static void castPattern(Casts casts) { protected static void castPattern(Casts casts) {
// with default error message, NO_CALLER does not work // with default error message, NO_CALLER does not work
...@@ -201,8 +202,8 @@ public class GrepFunctions { ...@@ -201,8 +202,8 @@ public class GrepFunctions {
protected PCRERFFI.Result compilePerlPattern(String pattern, boolean ignoreCase) { protected PCRERFFI.Result compilePerlPattern(String pattern, boolean ignoreCase) {
int cflags = ignoreCase ? PCRERFFI.CASELESS : 0; int cflags = ignoreCase ? PCRERFFI.CASELESS : 0;
long tables = pcreRFFINode.maketables(); long tables = maketablesNode.execute();
PCRERFFI.Result pcre = pcreRFFINode.compile(pattern, cflags, tables); PCRERFFI.Result pcre = compileNode.execute(pattern, cflags, tables);
if (pcre.result == 0) { if (pcre.result == 0) {
// TODO output warning if pcre.errorMessage not NULL // TODO output warning if pcre.errorMessage not NULL
throw RError.error(this, RError.Message.INVALID_REGEXP, pattern); throw RError.error(this, RError.Message.INVALID_REGEXP, pattern);
...@@ -212,6 +213,8 @@ public class GrepFunctions { ...@@ -212,6 +213,8 @@ public class GrepFunctions {
} }
private abstract static class GrepAdapter extends CommonCodeAdapter { private abstract static class GrepAdapter extends CommonCodeAdapter {
@Child PCRERFFI.ExecNode execNode = RFFIFactory.getRFFI().getPCRERFFI().createExecNode();
protected Object doGrep(RAbstractStringVector patternArgVec, RAbstractStringVector vector, byte ignoreCaseLogical, byte valueLogical, byte perlLogical, byte fixedLogical, protected Object doGrep(RAbstractStringVector patternArgVec, RAbstractStringVector vector, byte ignoreCaseLogical, byte valueLogical, byte perlLogical, byte fixedLogical,
@SuppressWarnings("unused") byte useBytes, byte invertLogical, boolean grepl) { @SuppressWarnings("unused") byte useBytes, byte invertLogical, boolean grepl) {
boolean value = RRuntime.fromLogical(valueLogical); boolean value = RRuntime.fromLogical(valueLogical);
...@@ -241,7 +244,7 @@ public class GrepFunctions { ...@@ -241,7 +244,7 @@ public class GrepFunctions {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
String text = vector.getDataAt(i); String text = vector.getDataAt(i);
if (!RRuntime.isNA(text)) { if (!RRuntime.isNA(text)) {
if (pcreRFFINode.exec(pcre.result, 0, text, 0, 0, ovector) >= 0) { if (execNode.execute(pcre.result, 0, text, 0, 0, ovector) >= 0) {
matches[i] = true; matches[i] = true;
} }
} }
...@@ -363,6 +366,7 @@ public class GrepFunctions { ...@@ -363,6 +366,7 @@ public class GrepFunctions {
} }
protected abstract static class SubAdapter extends CommonCodeAdapter { protected abstract static class SubAdapter extends CommonCodeAdapter {
@Child PCRERFFI.ExecNode execNode = RFFIFactory.getRFFI().getPCRERFFI().createExecNode();
protected static void castReplacement(Casts casts) { protected static void castReplacement(Casts casts) {
// with default error message, NO_CALLER does not work // with default error message, NO_CALLER does not work
...@@ -432,7 +436,7 @@ public class GrepFunctions { ...@@ -432,7 +436,7 @@ public class GrepFunctions {
// necessary // necessary
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
while (pcreRFFINode.exec(pcre.result, 0, input, lastEndOffset, eflag, ovector) >= 0) { while (execNode.execute(pcre.result, 0, input, lastEndOffset, eflag, ovector) >= 0) {
nmatch++; nmatch++;
// offset == byte position // offset == byte position
...@@ -690,6 +694,9 @@ public class GrepFunctions { ...@@ -690,6 +694,9 @@ public class GrepFunctions {
@Child SetFixedAttributeNode setCaptureLengthAttrNode = SetFixedAttributeNode.create("capture.length"); @Child SetFixedAttributeNode setCaptureLengthAttrNode = SetFixedAttributeNode.create("capture.length");
@Child SetFixedAttributeNode setCaptureNamesAttrNode = SetFixedAttributeNode.create("capture.names"); @Child SetFixedAttributeNode setCaptureNamesAttrNode = SetFixedAttributeNode.create("capture.names");
@Child SetFixedAttributeNode setDimNamesAttrNode = SetFixedAttributeNode.createDimNames(); @Child SetFixedAttributeNode setDimNamesAttrNode = SetFixedAttributeNode.createDimNames();
@Child PCRERFFI.ExecNode execNode = RFFIFactory.getRFFI().getPCRERFFI().createExecNode();
@Child PCRERFFI.GetCaptureNamesNode getCaptureNamesNode = RFFIFactory.getRFFI().getPCRERFFI().createGetCaptureNamesNode();
@Child PCRERFFI.GetCaptureCountNode getCaptureCountNode = RFFIFactory.getRFFI().getPCRERFFI().createGetCaptureCountNode();
static { static {
Casts casts = new Casts(Regexp.class); Casts casts = new Casts(Regexp.class);
...@@ -817,13 +824,13 @@ public class GrepFunctions { ...@@ -817,13 +824,13 @@ public class GrepFunctions {
} }
} else if (perl) { } else if (perl) {
PCRERFFI.Result pcre = compilePerlPattern(pattern, ignoreCase); PCRERFFI.Result pcre = compilePerlPattern(pattern, ignoreCase);
int maxCaptureCount = pcreRFFINode.getCaptureCount(pcre.result, 0); int maxCaptureCount = getCaptureCountNode.execute(pcre.result, 0);
int[] ovector = new int[(maxCaptureCount + 1) * 3]; int[] ovector = new int[(maxCaptureCount + 1) * 3];
int offset = 0; int offset = 0;
while (true) { while (true) {
int captureCount = pcreRFFINode.exec(pcre.result, 0, text, offset, 0, ovector); int captureCount = execNode.execute(pcre.result, 0, text, offset, 0, ovector);
if (captureCount >= 0) { if (captureCount >= 0) {
String[] captureNames = pcreRFFINode.getCaptureNames(pcre.result, 0, maxCaptureCount); String[] captureNames = getCaptureNamesNode.execute(pcre.result, 0, maxCaptureCount);
for (int i = 0; i < captureNames.length; i++) { for (int i = 0; i < captureNames.length; i++) {
if (captureNames[i] == null) { if (captureNames[i] == null) {
captureNames[i] = ""; captureNames[i] = "";
...@@ -1164,6 +1171,7 @@ public class GrepFunctions { ...@@ -1164,6 +1171,7 @@ public class GrepFunctions {
@RBuiltin(name = "strsplit", kind = INTERNAL, parameterNames = {"x", "split", "fixed", "perl", "useBytes"}, behavior = PURE) @RBuiltin(name = "strsplit", kind = INTERNAL, parameterNames = {"x", "split", "fixed", "perl", "useBytes"}, behavior = PURE)
public abstract static class Strsplit extends CommonCodeAdapter { public abstract static class Strsplit extends CommonCodeAdapter {
@Child PCRERFFI.ExecNode execNode = RFFIFactory.getRFFI().getPCRERFFI().createExecNode();
static { static {
Casts casts = new Casts(Strsplit.class); Casts casts = new Casts(Strsplit.class);
...@@ -1185,7 +1193,7 @@ public class GrepFunctions { ...@@ -1185,7 +1193,7 @@ public class GrepFunctions {
// treat split = NULL as split = "" // treat split = NULL as split = ""
RAbstractStringVector split = splitArg.getLength() == 0 ? RDataFactory.createStringVectorFromScalar("") : splitArg; RAbstractStringVector split = splitArg.getLength() == 0 ? RDataFactory.createStringVectorFromScalar("") : splitArg;
String[] splits = new String[split.getLength()]; String[] splits = new String[split.getLength()];
long pcreTables = perl ? pcreRFFINode.maketables() : 0; long pcreTables = perl ? maketablesNode.execute() : 0;
PCRERFFI.Result[] pcreSplits = perl ? new PCRERFFI.Result[splits.length] : null; PCRERFFI.Result[] pcreSplits = perl ? new PCRERFFI.Result[splits.length] : null;
na.enable(x); na.enable(x);
...@@ -1194,7 +1202,7 @@ public class GrepFunctions { ...@@ -1194,7 +1202,7 @@ public class GrepFunctions {
splits[i] = fixed || perl ? split.getDataAt(i) : RegExp.checkPreDefinedClasses(split.getDataAt(i)); splits[i] = fixed || perl ? split.getDataAt(i) : RegExp.checkPreDefinedClasses(split.getDataAt(i));
if (perl) { if (perl) {
if (!currentSplit.isEmpty()) { if (!currentSplit.isEmpty()) {
pcreSplits[i] = pcreRFFINode.compile(currentSplit, 0, pcreTables); pcreSplits[i] = compileNode.execute(currentSplit, 0, pcreTables);
if (pcreSplits[i].result == 0) { if (pcreSplits[i].result == 0) {
// TODO output warning if pcre.errorMessage not NULL // TODO output warning if pcre.errorMessage not NULL
throw RError.error(this, RError.Message.INVALID_REGEXP, currentSplit); throw RError.error(this, RError.Message.INVALID_REGEXP, currentSplit);
...@@ -1298,7 +1306,7 @@ public class GrepFunctions { ...@@ -1298,7 +1306,7 @@ public class GrepFunctions {
int[] ovector = new int[30]; int[] ovector = new int[30];
int[] fromByteMapping = getFromByteMapping(data); // non-null if it's necessary int[] fromByteMapping = getFromByteMapping(data); // non-null if it's necessary
while (pcreRFFINode.exec(pcre.result, 0, data, lastEndOffset, 0, ovector) >= 0) { while (execNode.execute(pcre.result, 0, data, lastEndOffset, 0, ovector) >= 0) {
// offset == byte position // offset == byte position
// index == character position // index == character position
int startOffset = ovector[0]; int startOffset = ovector[0];
......
...@@ -28,19 +28,23 @@ import com.oracle.truffle.r.runtime.RInternalError; ...@@ -28,19 +28,23 @@ import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.ffi.PCRERFFI; import com.oracle.truffle.r.runtime.ffi.PCRERFFI;
public class JNI_PCRE implements PCRERFFI { public class JNI_PCRE implements PCRERFFI {
private static class JNI_PCRERFFINode extends PCRERFFINode { private static class JNI_MaketablesNode extends MaketablesNode {
@Override @Override
public long maketables() { public long execute() {
return nativeMaketables(); return nativeMaketables();
} }
}
private static class JNI_CompileNode extends CompileNode {
@Override @Override
public Result compile(String pattern, int options, long tables) { public Result execute(String pattern, int options, long tables) {
return nativeCompile(pattern, options, tables); return nativeCompile(pattern, options, tables);
} }
}
private static class JNI_GetCaptureCountNode extends GetCaptureCountNode {
@Override @Override
public int getCaptureCount(long code, long extra) { public int execute(long code, long extra) {
int res = nativeGetCaptureCount(code, extra); int res = nativeGetCaptureCount(code, extra);
if (res < 0) { if (res < 0) {
CompilerDirectives.transferToInterpreter(); CompilerDirectives.transferToInterpreter();
...@@ -48,9 +52,11 @@ public class JNI_PCRE implements PCRERFFI { ...@@ -48,9 +52,11 @@ public class JNI_PCRE implements PCRERFFI {
} }
return res; return res;
} }
}
private static class JNI_GetCaptureNamesNode extends GetCaptureNamesNode {
@Override @Override
public String[] getCaptureNames(long code, long extra, int captureCount) { public String[] execute(long code, long extra, int captureCount) {
String[] ret = new String[captureCount]; String[] ret = new String[captureCount];
int res = nativeGetCaptureNames(code, extra, ret); int res = nativeGetCaptureNames(code, extra, ret);
if (res < 0) { if (res < 0) {
...@@ -59,14 +65,18 @@ public class JNI_PCRE implements PCRERFFI { ...@@ -59,14 +65,18 @@ public class JNI_PCRE implements PCRERFFI {
} }
return ret; return ret;
} }
}
private static class JNI_StudyNode extends StudyNode {
@Override @Override
public Result study(long code, int options) { public Result execute(long code, int options) {
throw RInternalError.unimplemented("pcre_study"); throw RInternalError.unimplemented("pcre_study");
} }
}
private static class JNI_ExecNode extends ExecNode {
@Override @Override
public int exec(long code, long extra, String subject, int offset, int options, int[] ovector) { public int execute(long code, long extra, String subject, int offset, int options, int[] ovector) {
return nativeExec(code, extra, subject, offset, options, ovector, ovector.length); return nativeExec(code, extra, subject, offset, options, ovector, ovector.length);
} }
} }
...@@ -83,7 +93,33 @@ public class JNI_PCRE implements PCRERFFI { ...@@ -83,7 +93,33 @@ public class JNI_PCRE implements PCRERFFI {
int options, int[] ovector, int ovectorLen); int options, int[] ovector, int ovectorLen);
@Override @Override
public PCRERFFINode createPCRERFFINode() { public MaketablesNode createMaketablesNode() {
return new JNI_PCRERFFINode(); return new JNI_MaketablesNode();
}
@Override
public CompileNode createCompileNode() {
return new JNI_CompileNode();
}
@Override
public GetCaptureCountNode createGetCaptureCountNode() {
return new JNI_GetCaptureCountNode();
} }
@Override
public GetCaptureNamesNode createGetCaptureNamesNode() {
return new JNI_GetCaptureNamesNode();
}
@Override
public StudyNode createStudyNode() {
return new JNI_StudyNode();
}
@Override
public ExecNode createExecNode() {
return new JNI_ExecNode();
}
} }
/* /*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -49,21 +49,67 @@ public interface PCRERFFI { ...@@ -49,21 +49,67 @@ public interface PCRERFFI {
} }
} }
abstract class PCRERFFINode extends Node { abstract class MaketablesNode extends Node {
public abstract long maketables(); public abstract long execute();
public abstract Result compile(String pattern, int options, long tables); public static MaketablesNode create() {
return RFFIFactory.getRFFI().getPCRERFFI().createMaketablesNode();
}
}
abstract class CompileNode extends Node {
public abstract Result execute(String pattern, int options, long tables);
public static CompileNode create() {
return RFFIFactory.getRFFI().getPCRERFFI().createCompileNode();
}
}
abstract class GetCaptureCountNode extends Node {
public abstract int execute(long code, long extra);
public static GetCaptureCountNode create() {
return RFFIFactory.getRFFI().getPCRERFFI().createGetCaptureCountNode();
}
}
public abstract int getCaptureCount(long code, long extra); abstract class GetCaptureNamesNode extends Node {
public abstract String[] execute(long code, long extra, int captureCount);
public abstract String[] getCaptureNames(long code, long extra, int captureCount); public static GetCaptureNamesNode create() {
return RFFIFactory.getRFFI().getPCRERFFI().createGetCaptureNamesNode();
}
}
abstract class StudyNode extends Node {
public abstract Result execute(long code, int options);
public static StudyNode create() {
return RFFIFactory.getRFFI().getPCRERFFI().createStudyNode();
}
}
public abstract Result study(long code, int options); abstract class ExecNode extends Node {
public abstract int execute(long code, long extra, String subject, int offset, int options, int[] ovector);
public abstract int exec(long code, long extra, String subject, int offset, int options, int[] ovector); public static ExecNode create() {
return RFFIFactory.getRFFI().getPCRERFFI().createExecNode();
}
} }
PCRERFFINode createPCRERFFINode(); MaketablesNode createMaketablesNode();
CompileNode createCompileNode();
GetCaptureCountNode createGetCaptureCountNode();
GetCaptureNamesNode createGetCaptureNamesNode();
StudyNode createStudyNode();
ExecNode createExecNode();
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment