package com.oracle.truffle.js.nodes.access;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrumentation.Tag;
import com.oracle.truffle.js.nodes.JavaScriptNode;
import com.oracle.truffle.js.nodes.instrumentation.JSTags;
import com.oracle.truffle.js.nodes.instrumentation.JSTags.LiteralTag;
import com.oracle.truffle.js.nodes.intl.CreateRegExpNode;
import com.oracle.truffle.js.runtime.JSContext;
import com.oracle.truffle.js.runtime.RegexCompilerInterface;
import com.oracle.truffle.js.runtime.util.TRegexUtil;
import com.oracle.truffle.js.runtime.util.TRegexUtil.CompileRegexNode;
import java.util.Set;
public class RegExpLiteralNode extends JavaScriptNode {
private final JSContext context;
private final String pattern;
private final String flags;
@CompilationFinal private Object regex;
@Child private CreateRegExpNode createRegExpNode;
@Child private TRegexUtil.CompileRegexNode compileRegExpNode;
@Override
public boolean hasTag(Class<? extends Tag> tag) {
if (tag == LiteralTag.class) {
return true;
} else {
return super.hasTag(tag);
}
}
@Override
public Object getNodeObject() {
return JSTags.createNodeObjectDescriptor(LiteralTag.TYPE, LiteralTag.Type.RegExpLiteral.name());
}
RegExpLiteralNode(JSContext context, String pattern, String flags) {
this.context = context;
this.pattern = pattern;
this.flags = flags;
}
public static RegExpLiteralNode create(JSContext context, String pattern, String flags) {
return new RegExpLiteralNode(context, pattern, flags);
}
@Override
public Object execute(VirtualFrame frame) {
if (regex == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
regex = RegexCompilerInterface.compile(pattern, flags, context, getCompileRegExpNode());
}
return getCreateRegExpNode().createRegExp(regex);
}
private CompileRegexNode getCompileRegExpNode() {
if (compileRegExpNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
compileRegExpNode = insert(TRegexUtil.CompileRegexNode.create());
}
return compileRegExpNode;
}
private CreateRegExpNode getCreateRegExpNode() {
if (createRegExpNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
createRegExpNode = insert(CreateRegExpNode.create(context));
}
return createRegExpNode;
}
@Override
protected JavaScriptNode copyUninitialized(Set<Class<? extends Tag>> materializedTags) {
return create(context, pattern, flags);
}
}