inv() is an intrinsic
This commit is contained in:
@@ -784,16 +784,17 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
generateConstructorCall(expression, (JetSimpleNameExpression) callee);
|
generateConstructorCall(expression, (JetSimpleNameExpression) callee);
|
||||||
}
|
}
|
||||||
else if (funDescriptor instanceof FunctionDescriptor) {
|
else if (funDescriptor instanceof FunctionDescriptor) {
|
||||||
final DeclarationDescriptor functionParent = funDescriptor.getContainingDeclaration();
|
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(funDescriptor);
|
||||||
if (isNumberPrimitive(functionParent)) {
|
if (intrinsic != null) {
|
||||||
if (funDescriptor.getName().equals("inv")) {
|
List<JetExpression> args = new ArrayList<JetExpression>();
|
||||||
final StackValue value = myStack.pop(); // HACK we rely on the dot reference handler to put it on the stack
|
for (JetArgument argument : expression.getValueArguments()) {
|
||||||
final Type asmType = expressionType(expression);
|
args.add(argument.getArgumentExpression());
|
||||||
value.put(asmType, v);
|
|
||||||
generateInv(asmType);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
myStack.push(intrinsic.generate(this, v, expressionType(expression), expression, args));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final DeclarationDescriptor functionParent = funDescriptor.getContainingDeclaration();
|
||||||
if (state.getStandardLibrary().getTypeInfoFunctionGroup().getFunctionDescriptors().contains(funDescriptor.getOriginal())) {
|
if (state.getStandardLibrary().getTypeInfoFunctionGroup().getFunctionDescriptors().contains(funDescriptor.getOriginal())) {
|
||||||
generateTypeInfoCall(expression);
|
generateTypeInfoCall(expression);
|
||||||
return;
|
return;
|
||||||
@@ -1453,12 +1454,6 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateInv(Type asmType) {
|
|
||||||
v.aconst(-1);
|
|
||||||
v.xor(asmType);
|
|
||||||
myStack.push(StackValue.onStack(asmType));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitProperty(JetProperty property) {
|
public void visitProperty(JetProperty property) {
|
||||||
VariableDescriptor variableDescriptor = bindingContext.getVariableDescriptor(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 UNARY_MINUS = new UnaryMinus();
|
||||||
private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
|
private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
|
||||||
private static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
|
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>();
|
private final Map<DeclarationDescriptor, IntrinsicMethod> myMethods = new HashMap<DeclarationDescriptor, IntrinsicMethod>();
|
||||||
|
|
||||||
public IntrinsicMethods(JetStandardLibrary stdlib) {
|
public IntrinsicMethods(JetStandardLibrary 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) {
|
||||||
declareIntrinsicProperty(stdlib, "Number", method, NUMBER_CAST);
|
declareIntrinsicProperty("Number", method, NUMBER_CAST);
|
||||||
}
|
}
|
||||||
declareIntrinsicProperty(stdlib, "Array", "size", ARRAY_SIZE);
|
declareIntrinsicProperty("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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
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) {
|
private void declareIntrinsicProperty(String className, String methodName, IntrinsicMethod implementation) {
|
||||||
final ClassDescriptor descriptor = (ClassDescriptor) stdlib.getLibraryScope().getClassifier(className);
|
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();
|
final List<TypeParameterDescriptor> typeParameterDescriptors = descriptor.getTypeConstructor().getParameters();
|
||||||
List<TypeProjection> typeParameters = new ArrayList<TypeProjection>();
|
List<TypeProjection> typeParameters = new ArrayList<TypeProjection>();
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : typeParameterDescriptors) {
|
for (TypeParameterDescriptor typeParameterDescriptor : typeParameterDescriptors) {
|
||||||
typeParameters.add(new TypeProjection(JetStandardClasses.getAnyType()));
|
typeParameters.add(new TypeProjection(JetStandardClasses.getAnyType()));
|
||||||
}
|
}
|
||||||
final JetScope numberScope = descriptor.getMemberScope(typeParameters);
|
return descriptor.getMemberScope(typeParameters);
|
||||||
final VariableDescriptor variable = numberScope.getVariable(methodName);
|
|
||||||
myMethods.put(variable.getOriginal(), implementation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntrinsicMethod getIntrinsic(DeclarationDescriptor descriptor) {
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user