inv() is an intrinsic

This commit is contained in:
Dmitry Jemerov
2011-07-13 19:41:29 +02:00
parent a1e6d16c96
commit ed241e13d3
3 changed files with 60 additions and 43 deletions
@@ -784,16 +784,17 @@ public class ExpressionCodegen extends JetVisitor {
generateConstructorCall(expression, (JetSimpleNameExpression) callee);
}
else if (funDescriptor instanceof FunctionDescriptor) {
final DeclarationDescriptor functionParent = funDescriptor.getContainingDeclaration();
if (isNumberPrimitive(functionParent)) {
if (funDescriptor.getName().equals("inv")) {
final StackValue value = myStack.pop(); // HACK we rely on the dot reference handler to put it on the stack
final Type asmType = expressionType(expression);
value.put(asmType, v);
generateInv(asmType);
return;
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 DeclarationDescriptor functionParent = funDescriptor.getContainingDeclaration();
if (state.getStandardLibrary().getTypeInfoFunctionGroup().getFunctionDescriptors().contains(funDescriptor.getOriginal())) {
generateTypeInfoCall(expression);
return;
@@ -1453,12 +1454,6 @@ public class ExpressionCodegen extends JetVisitor {
return value;
}
private void generateInv(Type asmType) {
v.aconst(-1);
v.xor(asmType);
myStack.push(StackValue.onStack(asmType));
}
@Override
public void visitProperty(JetProperty property) {
VariableDescriptor variableDescriptor = bindingContext.getVariableDescriptor(property);
@@ -16,51 +16,50 @@ public class IntrinsicMethods {
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
private static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
private static final IntrinsicMethod INV = new Inv();
private final JetStandardLibrary myStdLib;
private final Map<DeclarationDescriptor, IntrinsicMethod> myMethods = new HashMap<DeclarationDescriptor, IntrinsicMethod>();
public IntrinsicMethods(JetStandardLibrary stdlib) {
myStdLib = stdlib;
List<String> primitiveCastMethods = ImmutableList.of("dbl", "flt", "lng", "int", "chr", "sht", "byt");
for (String method : primitiveCastMethods) {
declareIntrinsicProperty(stdlib, "Number", method, NUMBER_CAST);
declareIntrinsicProperty("Number", method, NUMBER_CAST);
}
declareIntrinsicProperty(stdlib, "Array", "size", ARRAY_SIZE);
List<ClassDescriptor> primitiveNumberTypes = ImmutableList.of(
stdlib.getBoolean(),
stdlib.getByte(),
stdlib.getChar(),
stdlib.getShort(),
stdlib.getInt(),
stdlib.getFloat(),
stdlib.getLong(),
stdlib.getDouble()
);
for (ClassDescriptor primitiveNumberType : primitiveNumberTypes) {
final JetScope memberScope = primitiveNumberType.getMemberScope(Collections.<TypeProjection>emptyList());
final FunctionGroup minus = memberScope.getFunctionGroup("minus");
for (FunctionDescriptor descriptor : minus.getFunctionDescriptors()) {
if (descriptor.getValueParameters().isEmpty()) {
myMethods.put(descriptor, UNARY_MINUS);
}
}
declareIntrinsicProperty("Array", "size", ARRAY_SIZE);
List<String> primitiveNumberTypes = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
for (String primitiveNumberType : primitiveNumberTypes) {
declareIntrinsicFunction(primitiveNumberType, "minus", 0, UNARY_MINUS);
declareIntrinsicFunction(primitiveNumberType, "inv", 0, INV);
}
}
private void declareIntrinsicProperty(JetStandardLibrary stdlib, String className, String methodName, IntrinsicMethod implementation) {
final ClassDescriptor descriptor = (ClassDescriptor) stdlib.getLibraryScope().getClassifier(className);
private void declareIntrinsicProperty(String className, String methodName, IntrinsicMethod implementation) {
final JetScope numberScope = getClassMemberScope(className);
final VariableDescriptor variable = numberScope.getVariable(methodName);
myMethods.put(variable.getOriginal(), implementation);
}
private void declareIntrinsicFunction(String className, String functionName, int arity, IntrinsicMethod implementation) {
JetScope memberScope = getClassMemberScope(className);
final FunctionGroup minus = memberScope.getFunctionGroup(functionName);
for (FunctionDescriptor descriptor : minus.getFunctionDescriptors()) {
if (descriptor.getValueParameters().size() == arity) {
myMethods.put(descriptor, implementation);
}
}
}
private JetScope getClassMemberScope(String className) {
final ClassDescriptor descriptor = (ClassDescriptor) myStdLib.getLibraryScope().getClassifier(className);
final List<TypeParameterDescriptor> typeParameterDescriptors = descriptor.getTypeConstructor().getParameters();
List<TypeProjection> typeParameters = new ArrayList<TypeProjection>();
for (TypeParameterDescriptor typeParameterDescriptor : typeParameterDescriptors) {
typeParameters.add(new TypeProjection(JetStandardClasses.getAnyType()));
}
final JetScope numberScope = descriptor.getMemberScope(typeParameters);
final VariableDescriptor variable = numberScope.getVariable(methodName);
myMethods.put(variable.getOriginal(), implementation);
return descriptor.getMemberScope(typeParameters);
}
public IntrinsicMethod getIntrinsic(DeclarationDescriptor descriptor) {
@@ -0,0 +1,23 @@
package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.StackValue;
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 Inv implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
codegen.putTopOfStack(expectedType);
v.aconst(-1);
v.xor(expectedType);
return StackValue.onStack(expectedType);
}
}