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

Convert PCRERFFI to one node per method.

parent 0d8cee6f
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;
*/
public class GrepFunctions {
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) {
// with default error message, NO_CALLER does not work
......@@ -201,8 +202,8 @@ public class GrepFunctions {
protected PCRERFFI.Result compilePerlPattern(String pattern, boolean ignoreCase) {
int cflags = ignoreCase ? PCRERFFI.CASELESS : 0;
long tables = pcreRFFINode.maketables();
PCRERFFI.Result pcre = pcreRFFINode.compile(pattern, cflags, tables);
long tables = maketablesNode.execute();
PCRERFFI.Result pcre = compileNode.execute(pattern, cflags, tables);
if (pcre.result == 0) {
// TODO output warning if pcre.errorMessage not NULL
throw RError.error(this, RError.Message.INVALID_REGEXP, pattern);
......@@ -212,6 +213,8 @@ public class GrepFunctions {
}
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,
@SuppressWarnings("unused") byte useBytes, byte invertLogical, boolean grepl) {
boolean value = RRuntime.fromLogical(valueLogical);
......@@ -241,7 +244,7 @@ public class GrepFunctions {
for (int i = 0; i < len; i++) {
String text = vector.getDataAt(i);
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;
}
}
......@@ -363,6 +366,7 @@ public class GrepFunctions {
}
protected abstract static class SubAdapter extends CommonCodeAdapter {
@Child PCRERFFI.ExecNode execNode = RFFIFactory.getRFFI().getPCRERFFI().createExecNode();
protected static void castReplacement(Casts casts) {
// with default error message, NO_CALLER does not work
......@@ -432,7 +436,7 @@ public class GrepFunctions {
// necessary
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++;
// offset == byte position
......@@ -690,6 +694,9 @@ public class GrepFunctions {
@Child SetFixedAttributeNode setCaptureLengthAttrNode = SetFixedAttributeNode.create("capture.length");
@Child SetFixedAttributeNode setCaptureNamesAttrNode = SetFixedAttributeNode.create("capture.names");
@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 {
Casts casts = new Casts(Regexp.class);
......@@ -817,13 +824,13 @@ public class GrepFunctions {
}
} else if (perl) {
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 offset = 0;
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) {
String[] captureNames = pcreRFFINode.getCaptureNames(pcre.result, 0, maxCaptureCount);
String[] captureNames = getCaptureNamesNode.execute(pcre.result, 0, maxCaptureCount);
for (int i = 0; i < captureNames.length; i++) {
if (captureNames[i] == null) {
captureNames[i] = "";
......@@ -1164,6 +1171,7 @@ public class GrepFunctions {
@RBuiltin(name = "strsplit", kind = INTERNAL, parameterNames = {"x", "split", "fixed", "perl", "useBytes"}, behavior = PURE)
public abstract static class Strsplit extends CommonCodeAdapter {
@Child PCRERFFI.ExecNode execNode = RFFIFactory.getRFFI().getPCRERFFI().createExecNode();
static {
Casts casts = new Casts(Strsplit.class);
......@@ -1185,7 +1193,7 @@ public class GrepFunctions {
// treat split = NULL as split = ""
RAbstractStringVector split = splitArg.getLength() == 0 ? RDataFactory.createStringVectorFromScalar("") : splitArg;
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;
na.enable(x);
......@@ -1194,7 +1202,7 @@ public class GrepFunctions {
splits[i] = fixed || perl ? split.getDataAt(i) : RegExp.checkPreDefinedClasses(split.getDataAt(i));
if (perl) {
if (!currentSplit.isEmpty()) {
pcreSplits[i] = pcreRFFINode.compile(currentSplit, 0, pcreTables);
pcreSplits[i] = compileNode.execute(currentSplit, 0, pcreTables);
if (pcreSplits[i].result == 0) {
// TODO output warning if pcre.errorMessage not NULL
throw RError.error(this, RError.Message.INVALID_REGEXP, currentSplit);
......@@ -1298,7 +1306,7 @@ public class GrepFunctions {
int[] ovector = new int[30];
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
// index == character position
int startOffset = ovector[0];
......
......@@ -28,19 +28,23 @@ import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.ffi.PCRERFFI;
public class JNI_PCRE implements PCRERFFI {
private static class JNI_PCRERFFINode extends PCRERFFINode {
private static class JNI_MaketablesNode extends MaketablesNode {
@Override
public long maketables() {
public long execute() {
return nativeMaketables();
}
}
private static class JNI_CompileNode extends CompileNode {
@Override
public Result compile(String pattern, int options, long tables) {
public Result execute(String pattern, int options, long tables) {
return nativeCompile(pattern, options, tables);
}
}
private static class JNI_GetCaptureCountNode extends GetCaptureCountNode {
@Override
public int getCaptureCount(long code, long extra) {
public int execute(long code, long extra) {
int res = nativeGetCaptureCount(code, extra);
if (res < 0) {
CompilerDirectives.transferToInterpreter();
......@@ -48,9 +52,11 @@ public class JNI_PCRE implements PCRERFFI {
}
return res;
}
}
private static class JNI_GetCaptureNamesNode extends GetCaptureNamesNode {
@Override
public String[] getCaptureNames(long code, long extra, int captureCount) {
public String[] execute(long code, long extra, int captureCount) {
String[] ret = new String[captureCount];
int res = nativeGetCaptureNames(code, extra, ret);
if (res < 0) {
......@@ -59,14 +65,18 @@ public class JNI_PCRE implements PCRERFFI {
}
return ret;
}
}
private static class JNI_StudyNode extends StudyNode {
@Override
public Result study(long code, int options) {
public Result execute(long code, int options) {
throw RInternalError.unimplemented("pcre_study");
}
}
private static class JNI_ExecNode extends ExecNode {
@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);
}
}
......@@ -83,7 +93,33 @@ public class JNI_PCRE implements PCRERFFI {
int options, int[] ovector, int ovectorLen);
@Override
public PCRERFFINode createPCRERFFINode() {
return new JNI_PCRERFFINode();
public MaketablesNode createMaketablesNode() {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -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