String methods are intrinsics
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yole
|
||||||
|
*/
|
||||||
|
public interface Callable {
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
*/
|
*/
|
||||||
public class CallableMethod {
|
public class CallableMethod implements Callable {
|
||||||
private String owner;
|
private String owner;
|
||||||
private final Method signature;
|
private final Method signature;
|
||||||
private final int invokeOpcode;
|
private final int invokeOpcode;
|
||||||
|
|||||||
@@ -102,6 +102,10 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
this.intrinsics = state.getIntrinsics();
|
this.intrinsics = state.getIntrinsics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JetTypeMapper getTypeMapper() {
|
||||||
|
return state.getTypeMapper();
|
||||||
|
}
|
||||||
|
|
||||||
public void addTypeParameter(TypeParameterDescriptor typeParameter, StackValue expression) {
|
public void addTypeParameter(TypeParameterDescriptor typeParameter, StackValue expression) {
|
||||||
typeParameterExpressions.put(typeParameter, expression);
|
typeParameterExpressions.put(typeParameter, expression);
|
||||||
}
|
}
|
||||||
@@ -618,7 +622,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
|
|
||||||
Label label = new Label();
|
Label label = new Label();
|
||||||
v.visitLabel(label);
|
v.visitLabel(label);
|
||||||
v.visitLineNumber(lineNumber+1, label); // 1-based
|
v.visitLineNumber(lineNumber + 1, label); // 1-based
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -653,7 +657,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(descriptor);
|
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(descriptor);
|
||||||
if (intrinsic != null) {
|
if (intrinsic != null) {
|
||||||
final Type expectedType = expressionType(expression);
|
final Type expectedType = expressionType(expression);
|
||||||
myStack.push(intrinsic.generate(this, v, expectedType, expression, Collections.<JetExpression>emptyList()));
|
myStack.push(intrinsic.generate(this, v, expectedType, expression, Collections.<JetExpression>emptyList(), false));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,33 +792,10 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
generateConstructorCall(expression, (JetSimpleNameExpression) callee);
|
generateConstructorCall(expression, (JetSimpleNameExpression) callee);
|
||||||
}
|
}
|
||||||
else if (funDescriptor instanceof FunctionDescriptor) {
|
else if (funDescriptor instanceof FunctionDescriptor) {
|
||||||
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(funDescriptor);
|
|
||||||
if (intrinsic != null) {
|
|
||||||
List<JetExpression> args = new ArrayList<JetExpression>();
|
|
||||||
for (JetArgument argument : expression.getValueArguments()) {
|
|
||||||
args.add(argument.getArgumentExpression());
|
|
||||||
}
|
|
||||||
myStack.push(intrinsic.generate(this, v, expressionType(expression), expression, args));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final FunctionDescriptor fd = (FunctionDescriptor) funDescriptor;
|
final FunctionDescriptor fd = (FunctionDescriptor) funDescriptor;
|
||||||
PsiElement declarationPsiElement = resolveCalleeToDeclaration(funDescriptor);
|
final StackValue stackValue = invokeFunction(expression, fd, false);
|
||||||
|
if (stackValue != null) {
|
||||||
CallableMethod callableMethod;
|
myStack.push(stackValue);
|
||||||
if (declarationPsiElement instanceof PsiMethod || declarationPsiElement instanceof JetNamedFunction) {
|
|
||||||
callableMethod = typeMapper.mapToCallableMethod((PsiNamedElement) declarationPsiElement);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callableMethod = ClosureCodegen.asCallableMethod(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
invokeMethodWithArguments(callableMethod, expression);
|
|
||||||
final Type callReturnType = callableMethod.getSignature().getReturnType();
|
|
||||||
if (callReturnType != Type.VOID_TYPE) {
|
|
||||||
final Type retType = typeMapper.mapType(fd.getReturnType());
|
|
||||||
StackValue.onStack(callReturnType).upcast(retType, v);
|
|
||||||
myStack.push(StackValue.onStack(retType));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -822,25 +803,50 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PsiElement resolveCalleeToDeclaration(DeclarationDescriptor funDescriptor) {
|
private StackValue invokeFunction(JetCallExpression expression, FunctionDescriptor fd, boolean haveReceiver) {
|
||||||
PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(funDescriptor);
|
Callable callableMethod = resolveToCallable(fd);
|
||||||
if (declarationPsiElement == null && isClass(funDescriptor.getContainingDeclaration(), "String")) {
|
return invokeCallable(fd, callableMethod, expression, haveReceiver);
|
||||||
final Project project = state.getProject();
|
}
|
||||||
PsiClass jlString = JavaPsiFacade.getInstance(project).findClass("java.lang.String",
|
|
||||||
ProjectScope.getAllScope(project));
|
@Nullable
|
||||||
// TODO better overload mapping
|
private StackValue invokeCallable(FunctionDescriptor fd, Callable callable, JetCallExpression expression, boolean haveReceiver) {
|
||||||
final PsiMethod[] methods = jlString.findMethodsByName(funDescriptor.getName(), false);
|
if (callable instanceof CallableMethod) {
|
||||||
final int arity = ((FunctionDescriptor) funDescriptor).getValueParameters().size();
|
final CallableMethod callableMethod = (CallableMethod) callable;
|
||||||
for (PsiMethod method : methods) {
|
invokeMethodWithArguments(callableMethod, expression, haveReceiver);
|
||||||
if (method.getParameterList().getParametersCount() == arity) {
|
|
||||||
declarationPsiElement = method;
|
final Type callReturnType = callableMethod.getSignature().getReturnType();
|
||||||
}
|
if (callReturnType != Type.VOID_TYPE) {
|
||||||
|
final Type retType = typeMapper.mapType(fd.getReturnType());
|
||||||
|
StackValue.onStack(callReturnType).upcast(retType, v);
|
||||||
|
return StackValue.onStack(retType);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
if (declarationPsiElement == null) {
|
else {
|
||||||
throw new UnsupportedOperationException("couldn't find declaration for " + funDescriptor);
|
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
|
||||||
|
List<JetExpression> args = new ArrayList<JetExpression>();
|
||||||
|
for (JetArgument argument : expression.getValueArguments()) {
|
||||||
|
args.add(argument.getArgumentExpression());
|
||||||
|
}
|
||||||
|
return intrinsic.generate(this, v, expressionType(expression), expression, args, haveReceiver);
|
||||||
}
|
}
|
||||||
return declarationPsiElement;
|
}
|
||||||
|
|
||||||
|
private Callable resolveToCallable(FunctionDescriptor fd) {
|
||||||
|
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(fd);
|
||||||
|
if (intrinsic != null) {
|
||||||
|
return intrinsic;
|
||||||
|
}
|
||||||
|
PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(fd);
|
||||||
|
|
||||||
|
CallableMethod callableMethod;
|
||||||
|
if (declarationPsiElement instanceof PsiMethod || declarationPsiElement instanceof JetNamedFunction) {
|
||||||
|
callableMethod = typeMapper.mapToCallableMethod((PsiNamedElement) declarationPsiElement);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callableMethod = ClosureCodegen.asCallableMethod(fd);
|
||||||
|
}
|
||||||
|
return callableMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeclarationDescriptor resolveCalleeDescriptor(JetCallExpression call) {
|
private DeclarationDescriptor resolveCalleeDescriptor(JetCallExpression call) {
|
||||||
@@ -859,7 +865,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
invokeMethodWithArguments(callableMethod, expression, false);
|
invokeMethodWithArguments(callableMethod, expression, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invokeMethodWithArguments(CallableMethod callableMethod, JetCall expression, final boolean haveReceiver) {
|
public void invokeMethodWithArguments(CallableMethod callableMethod, JetCall expression, final boolean haveReceiver) {
|
||||||
final Type calleeType = callableMethod.getGenerateCalleeType();
|
final Type calleeType = callableMethod.getGenerateCalleeType();
|
||||||
if (calleeType != null && expression instanceof JetCallExpression) {
|
if (calleeType != null && expression instanceof JetCallExpression) {
|
||||||
gen(((JetCallExpression) expression).getCalleeExpression(), calleeType);
|
gen(((JetCallExpression) expression).getCalleeExpression(), calleeType);
|
||||||
@@ -1091,7 +1097,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(op);
|
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(op);
|
||||||
if (intrinsic != null) {
|
if (intrinsic != null) {
|
||||||
myStack.push(intrinsic.generate(this, v, expressionType(expression), expression,
|
myStack.push(intrinsic.generate(this, v, expressionType(expression), expression,
|
||||||
Arrays.asList(expression.getLeft(), expression.getRight())));
|
Arrays.asList(expression.getLeft(), expression.getRight()), false));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1358,7 +1364,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(op);
|
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(op);
|
||||||
final JetExpression operand = unaryExpression.getBaseExpression();
|
final JetExpression operand = unaryExpression.getBaseExpression();
|
||||||
if (intrinsic != null) {
|
if (intrinsic != null) {
|
||||||
myStack.push(intrinsic.generate(this, v, asmType, unaryExpression, Collections.singletonList(operand)));
|
myStack.push(intrinsic.generate(this, v, asmType, unaryExpression, Collections.singletonList(operand), false));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (isNumberPrimitive(asmType) && (op.getName().equals("inc") || op.getName().equals("dec"))) {
|
else if (isNumberPrimitive(asmType) && (op.getName().equals("inc") || op.getName().equals("dec"))) {
|
||||||
@@ -1863,13 +1869,10 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
if (call instanceof JetCallExpression) {
|
if (call instanceof JetCallExpression) {
|
||||||
v.load(subjectLocal, subjectType);
|
v.load(subjectLocal, subjectType);
|
||||||
final DeclarationDescriptor declarationDescriptor = resolveCalleeDescriptor((JetCallExpression) call);
|
final DeclarationDescriptor declarationDescriptor = resolveCalleeDescriptor((JetCallExpression) call);
|
||||||
final PsiElement declaration = resolveCalleeToDeclaration(declarationDescriptor);
|
if (!(declarationDescriptor instanceof FunctionDescriptor)) {
|
||||||
final CallableMethod callableMethod = typeMapper.mapToCallableMethod((PsiNamedElement) declaration);
|
throw new UnsupportedOperationException("expected function descriptor in when condition with call, found " + declarationDescriptor);
|
||||||
if (callableMethod.getSignature().getReturnType() != Type.BOOLEAN_TYPE) {
|
|
||||||
throw new UnsupportedOperationException("calls in pattern matching must return boolean");
|
|
||||||
}
|
}
|
||||||
invokeMethodWithArguments(callableMethod, (JetCallExpression) call, true);
|
conditionValue = invokeFunction((JetCallExpression) call, (FunctionDescriptor) declarationDescriptor, true);
|
||||||
conditionValue = StackValue.onStack(Type.BOOLEAN_TYPE);
|
|
||||||
}
|
}
|
||||||
else if (call instanceof JetSimpleNameExpression) {
|
else if (call instanceof JetSimpleNameExpression) {
|
||||||
final DeclarationDescriptor descriptor = bindingContext.resolveReferenceExpression((JetSimpleNameExpression) call);
|
final DeclarationDescriptor descriptor = bindingContext.resolveReferenceExpression((JetSimpleNameExpression) call);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class GenerationState {
|
|||||||
this.project = project;
|
this.project = project;
|
||||||
this.standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
this.standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
||||||
this.factory = new ClassFileFactory(project, text, this);
|
this.factory = new ClassFileFactory(project, text, this);
|
||||||
this.intrinsics = new IntrinsicMethods(standardLibrary);
|
this.intrinsics = new IntrinsicMethods(project, standardLibrary);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassFileFactory getFactory() {
|
public ClassFileFactory getFactory() {
|
||||||
|
|||||||
@@ -404,7 +404,7 @@ public class JetTypeMapper {
|
|||||||
return mapToCallableMethod((PsiMethod) declaration);
|
return mapToCallableMethod((PsiMethod) declaration);
|
||||||
}
|
}
|
||||||
if (!(declaration instanceof JetNamedFunction)) {
|
if (!(declaration instanceof JetNamedFunction)) {
|
||||||
throw new UnsupportedOperationException("unknown declaration type");
|
throw new UnsupportedOperationException("unknown declaration type " + declaration);
|
||||||
}
|
}
|
||||||
JetNamedFunction f = (JetNamedFunction) declaration;
|
JetNamedFunction f = (JetNamedFunction) declaration;
|
||||||
final FunctionDescriptor functionDescriptor = bindingContext.getFunctionDescriptor(f);
|
final FunctionDescriptor functionDescriptor = bindingContext.getFunctionDescriptor(f);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class ArraySize implements IntrinsicMethod {
|
public class ArraySize implements IntrinsicMethod {
|
||||||
@Override
|
@Override
|
||||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
|
||||||
codegen.ensureReceiverOnStack(element, null);
|
codegen.ensureReceiverOnStack(element, null);
|
||||||
v.arraylength();
|
v.arraylength();
|
||||||
return StackValue.onStack(Type.INT_TYPE);
|
return StackValue.onStack(Type.INT_TYPE);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class BinaryOp implements IntrinsicMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
|
||||||
codegen.gen(arguments.get(0), expectedType);
|
codegen.gen(arguments.get(0), expectedType);
|
||||||
codegen.gen(arguments.get(1), expectedType);
|
codegen.gen(arguments.get(1), expectedType);
|
||||||
v.visitInsn(expectedType.getOpcode(opcode));
|
v.visitInsn(expectedType.getOpcode(opcode));
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class Concat implements IntrinsicMethod {
|
public class Concat implements IntrinsicMethod {
|
||||||
@Override
|
@Override
|
||||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
|
||||||
codegen.generateStringBuilderConstructor();
|
codegen.generateStringBuilderConstructor();
|
||||||
codegen.invokeAppend(arguments.get(0));
|
codegen.invokeAppend(arguments.get(0));
|
||||||
codegen.invokeAppend(arguments.get(1));
|
codegen.invokeAppend(arguments.get(1));
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.codegen.intrinsics;
|
package org.jetbrains.jet.codegen.intrinsics;
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.jet.codegen.Callable;
|
||||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||||
import org.jetbrains.jet.codegen.StackValue;
|
import org.jetbrains.jet.codegen.StackValue;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
@@ -12,6 +13,6 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
*/
|
*/
|
||||||
public interface IntrinsicMethod {
|
public interface IntrinsicMethod extends Callable {
|
||||||
StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments);
|
StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
package org.jetbrains.jet.codegen.intrinsics;
|
package org.jetbrains.jet.codegen.intrinsics;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.psi.JavaPsiFacade;
|
||||||
|
import com.intellij.psi.PsiClass;
|
||||||
|
import com.intellij.psi.PsiMethod;
|
||||||
|
import com.intellij.psi.search.ProjectScope;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
@@ -8,10 +13,7 @@ import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
|||||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
@@ -25,10 +27,12 @@ public class IntrinsicMethods {
|
|||||||
|
|
||||||
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
|
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
|
||||||
|
|
||||||
|
private final Project myProject;
|
||||||
private final JetStandardLibrary myStdLib;
|
private final JetStandardLibrary myStdLib;
|
||||||
private final Map<DeclarationDescriptor, IntrinsicMethod> myMethods = new HashMap<DeclarationDescriptor, IntrinsicMethod>();
|
private final Map<DeclarationDescriptor, IntrinsicMethod> myMethods = new HashMap<DeclarationDescriptor, IntrinsicMethod>();
|
||||||
|
|
||||||
public IntrinsicMethods(JetStandardLibrary stdlib) {
|
public IntrinsicMethods(Project project, JetStandardLibrary stdlib) {
|
||||||
|
myProject = project;
|
||||||
myStdLib = stdlib;
|
myStdLib = stdlib;
|
||||||
List<String> primitiveCastMethods = ImmutableList.of("dbl", "flt", "lng", "int", "chr", "sht", "byt");
|
List<String> primitiveCastMethods = ImmutableList.of("dbl", "flt", "lng", "int", "chr", "sht", "byt");
|
||||||
for (String method : primitiveCastMethods) {
|
for (String method : primitiveCastMethods) {
|
||||||
@@ -60,6 +64,26 @@ public class IntrinsicMethods {
|
|||||||
declareIntrinsicFunction("Boolean", "not", 0, new Not());
|
declareIntrinsicFunction("Boolean", "not", 0, new Not());
|
||||||
|
|
||||||
declareIntrinsicFunction("String", "plus", 1, new Concat());
|
declareIntrinsicFunction("String", "plus", 1, new Concat());
|
||||||
|
|
||||||
|
declareIntrinsicStringMethods();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void declareIntrinsicStringMethods() {
|
||||||
|
final ClassDescriptor stringClass = myStdLib.getString();
|
||||||
|
final Collection<DeclarationDescriptor> stringMembers = stringClass.getMemberScope(Collections.<TypeProjection>emptyList()).getAllDescriptors();
|
||||||
|
final PsiClass stringPsiClass = JavaPsiFacade.getInstance(myProject).findClass("java.lang.String",
|
||||||
|
ProjectScope.getLibrariesScope(myProject));
|
||||||
|
for (DeclarationDescriptor stringMember : stringMembers) {
|
||||||
|
if (stringMember instanceof FunctionDescriptor) {
|
||||||
|
final FunctionDescriptor stringMethod = (FunctionDescriptor) stringMember;
|
||||||
|
final PsiMethod[] methods = stringPsiClass.findMethodsByName(stringMember.getName(), false);
|
||||||
|
for (PsiMethod method : methods) {
|
||||||
|
if (method.getParameterList().getParametersCount() == stringMethod.getValueParameters().size()) {
|
||||||
|
myMethods.put(stringMethod, new PsiMethodCall(method));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void declareBinaryOp(String methodName, int opcode) {
|
private void declareBinaryOp(String methodName, int opcode) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class Inv implements IntrinsicMethod {
|
public class Inv implements IntrinsicMethod {
|
||||||
@Override
|
@Override
|
||||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
|
||||||
codegen.putTopOfStack(expectedType);
|
codegen.putTopOfStack(expectedType);
|
||||||
v.aconst(-1);
|
v.aconst(-1);
|
||||||
v.xor(expectedType);
|
v.xor(expectedType);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class Not implements IntrinsicMethod {
|
public class Not implements IntrinsicMethod {
|
||||||
@Override
|
@Override
|
||||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
|
||||||
final StackValue stackValue = codegen.generateIntermediateValue(arguments.get(0));
|
final StackValue stackValue = codegen.generateIntermediateValue(arguments.get(0));
|
||||||
return StackValue.not(stackValue);
|
return StackValue.not(stackValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class NumberCast implements IntrinsicMethod {
|
public class NumberCast implements IntrinsicMethod {
|
||||||
@Override
|
@Override
|
||||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
|
||||||
codegen.putTopOfStack(expectedType);
|
codegen.putTopOfStack(expectedType);
|
||||||
return StackValue.onStack(expectedType);
|
return StackValue.onStack(expectedType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.jetbrains.jet.codegen.intrinsics;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.PsiMethod;
|
||||||
|
import org.jetbrains.jet.codegen.CallableMethod;
|
||||||
|
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||||
|
import org.jetbrains.jet.codegen.StackValue;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yole
|
||||||
|
*/
|
||||||
|
public class PsiMethodCall implements IntrinsicMethod {
|
||||||
|
private final PsiMethod myMethod;
|
||||||
|
|
||||||
|
public PsiMethodCall(PsiMethod method) {
|
||||||
|
myMethod = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element,
|
||||||
|
List<JetExpression> arguments, boolean haveReceiver) {
|
||||||
|
final CallableMethod callableMethod = codegen.getTypeMapper().mapToCallableMethod(myMethod);
|
||||||
|
codegen.invokeMethodWithArguments(callableMethod, (JetCallExpression) element, haveReceiver);
|
||||||
|
return StackValue.onStack(callableMethod.getSignature().getReturnType());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class TypeInfo implements IntrinsicMethod {
|
public class TypeInfo implements IntrinsicMethod {
|
||||||
@Override
|
@Override
|
||||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
|
||||||
final List<JetTypeProjection> typeArguments = ((JetCallExpression) element).getTypeArguments();
|
final List<JetTypeProjection> typeArguments = ((JetCallExpression) element).getTypeArguments();
|
||||||
if (typeArguments.size() != 1) {
|
if (typeArguments.size() != 1) {
|
||||||
throw new UnsupportedOperationException("one type argument expected");
|
throw new UnsupportedOperationException("one type argument expected");
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class UnaryMinus implements IntrinsicMethod {
|
public class UnaryMinus implements IntrinsicMethod {
|
||||||
@Override
|
@Override
|
||||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
|
||||||
codegen.gen(arguments.get(0), expectedType);
|
codegen.gen(arguments.get(0), expectedType);
|
||||||
v.neg(expectedType);
|
v.neg(expectedType);
|
||||||
return StackValue.onStack(expectedType);
|
return StackValue.onStack(expectedType);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class ValueTypeInfo implements IntrinsicMethod {
|
public class ValueTypeInfo implements IntrinsicMethod {
|
||||||
@Override
|
@Override
|
||||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
|
||||||
codegen.gen(arguments.get(0), JetTypeMapper.TYPE_JET_OBJECT);
|
codegen.gen(arguments.get(0), JetTypeMapper.TYPE_JET_OBJECT);
|
||||||
v.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
v.invokeinterface("jet/JetObject", "getTypeInfo", "()Ljet/typeinfo/TypeInfo;");
|
||||||
return StackValue.onStack(JetTypeMapper.TYPE_TYPEINFO);
|
return StackValue.onStack(JetTypeMapper.TYPE_TYPEINFO);
|
||||||
|
|||||||
Reference in New Issue
Block a user