String methods are intrinsics

This commit is contained in:
Dmitry Jemerov
2011-07-14 18:08:57 +02:00
parent fe6eed2913
commit 0518cba342
17 changed files with 139 additions and 72 deletions
@@ -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);