inv() is an intrinsic
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user