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; ...@@ -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