
org.elasticsearch.painless.ir.FunctionNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lang-painless Show documentation
Show all versions of lang-painless Show documentation
Elasticsearch module: lang-painless
The newest version!
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.painless.ir;
import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.phase.IRTreeVisitor;
import org.elasticsearch.painless.symbol.WriteScope;
import org.elasticsearch.painless.symbol.WriteScope.Variable;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
import java.util.ArrayList;
import java.util.List;
public class FunctionNode extends IRNode {
/* ---- begin tree structure ---- */
private BlockNode blockNode;
public void setBlockNode(BlockNode blockNode) {
this.blockNode = blockNode;
}
public BlockNode getBlockNode() {
return blockNode;
}
/* ---- end tree structure, begin node data ---- */
protected String name;
Class> returnType;
List> typeParameters = new ArrayList<>();
List parameterNames = new ArrayList<>();
protected boolean isStatic;
protected boolean hasVarArgs;
protected boolean isSynthetic;
protected int maxLoopCounter;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setReturnType(Class> returnType) {
this.returnType = returnType;
}
public Class> getReturnType() {
return returnType;
}
public void addTypeParameter(Class> typeParameter) {
typeParameters.add(typeParameter);
}
public List> getTypeParameters() {
return typeParameters;
}
public void addParameterName(String parameterName) {
parameterNames.add(parameterName);
}
public List getParameterNames() {
return parameterNames;
}
public void setStatic(boolean isStatic) {
this.isStatic = isStatic;
}
public boolean isStatic() {
return isStatic;
}
public void setVarArgs(boolean hasVarArgs) {
this.hasVarArgs = hasVarArgs;
}
public boolean hasVarArgs() {
return hasVarArgs;
}
public void setSynthetic(boolean isSythetic) {
this.isSynthetic = isSythetic;
}
public boolean isSynthetic() {
return isSynthetic;
}
public void setMaxLoopCounter(int maxLoopCounter) {
this.maxLoopCounter = maxLoopCounter;
}
public int getMaxLoopCounter() {
return maxLoopCounter;
}
/* ---- end node data, begin visitor ---- */
@Override
public void visit(IRTreeVisitor irTreeVisitor, Scope scope) {
irTreeVisitor.visitFunction(this, scope);
}
@Override
public void visitChildren(IRTreeVisitor irTreeVisitor, Scope scope) {
getBlockNode().visit(irTreeVisitor, scope);
}
/* ---- end visitor ---- */
public FunctionNode(Location location) {
super(location);
}
@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
int access = Opcodes.ACC_PUBLIC;
if (isStatic) {
access |= Opcodes.ACC_STATIC;
} else {
writeScope.defineInternalVariable(Object.class, "this");
}
if (hasVarArgs) {
access |= Opcodes.ACC_VARARGS;
}
if (isSynthetic) {
access |= Opcodes.ACC_SYNTHETIC;
}
Type asmReturnType = MethodWriter.getType(returnType);
Type[] asmParameterTypes = new Type[typeParameters.size()];
for (int index = 0; index < asmParameterTypes.length; ++index) {
Class> type = typeParameters.get(index);
String name = parameterNames.get(index);
writeScope.defineVariable(type, name);
asmParameterTypes[index] = MethodWriter.getType(typeParameters.get(index));
}
Method method = new Method(name, asmReturnType, asmParameterTypes);
methodWriter = classWriter.newMethodWriter(access, method);
methodWriter.visitCode();
if (maxLoopCounter > 0) {
// if there is infinite loop protection, we do this once:
// int #loop = settings.getMaxLoopCounter()
Variable loop = writeScope.defineInternalVariable(int.class, "loop");
methodWriter.push(maxLoopCounter);
methodWriter.visitVarInsn(Opcodes.ISTORE, loop.getSlot());
}
blockNode.write(classWriter, methodWriter, writeScope.newScope());
methodWriter.endMethod();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy