All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sandius.rembulan.compiler.gen.asm.helpers.ASMUtils Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2016 Miroslav Janíček
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.sandius.rembulan.compiler.gen.asm.helpers;

import net.sandius.rembulan.util.Check;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.TypeInsnNode;

import java.util.Arrays;

import static org.objectweb.asm.Opcodes.*;

public abstract class ASMUtils {

	private ASMUtils() {
		// not to be instantiated
	}

	public static Type arrayTypeFor(Class clazz) {
		return arrayTypeFor(clazz, 1);
	}

	public static Type arrayTypeFor(Class clazz, int dimensions) {
		Check.notNull(clazz);
		if (dimensions < 1) {
			throw new IllegalArgumentException("dimensions must be at least 1");
		}

		String prefix = "[";
		for (int i = 1; i < dimensions; i++) prefix = prefix + "[";

		return Type.getType(prefix + Type.getType(clazz).getDescriptor());
	}

	public static Type typeForClassName(String className) {
		Check.notNull(className);
		return Type.getType("L" + className.replace(".", "/") + ";");
	}

	public static Type[] fillTypes(Type t, int n) {
		Type[] result = new Type[n];
		Arrays.fill(result, t);
		return result;
	}

	public static FrameNode frameSame() {
		return new FrameNode(F_SAME, 0, null, 0, null);
	}

	public static FrameNode frameSame1(Class clazz) {
		return new FrameNode(F_SAME1, 0, null, 1, new Object[] { Type.getInternalName(clazz) });
	}

	public static AbstractInsnNode checkCast(Class clazz) {
		return new TypeInsnNode(CHECKCAST, Type.getInternalName(clazz));
	}

	public static AbstractInsnNode loadInt(int i) {
		switch (i) {
			case -1: return new InsnNode(ICONST_M1);
			case 0:  return new InsnNode(ICONST_0);
			case 1:  return new InsnNode(ICONST_1);
			case 2:  return new InsnNode(ICONST_2);
			case 3:  return new InsnNode(ICONST_3);
			case 4:  return new InsnNode(ICONST_4);
			case 5:  return new InsnNode(ICONST_5);
			default: {
				if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) return new IntInsnNode(BIPUSH, i);
				else if (i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) return new IntInsnNode(SIPUSH, i);
				else return new LdcInsnNode(i);
			}
		}
	}

	public static AbstractInsnNode loadLong(long l) {
		if (l == 0L) return new InsnNode(LCONST_0);
		else if (l == 1L) return new InsnNode(LCONST_1);
		else return new LdcInsnNode(l);
	}

	public static AbstractInsnNode loadDouble(double d) {
		// We want to distinguish -0.0 from 0.0, but -0.0 == 0.0;
		// luckily, Double.equals() distinguishes these two cases.
		if (Double.valueOf(d).equals(0.0)) return new InsnNode(DCONST_0);
		else if (d == 1.0) return new InsnNode(DCONST_1);
		else return new LdcInsnNode(d);
	}

	public static MethodInsnNode ctor(Type of, Type... args) {
		return new MethodInsnNode(
				INVOKESPECIAL,
				of.getInternalName(),
				"",
				Type.getMethodDescriptor(
						Type.VOID_TYPE,
						args),
				false);
	}

	public static MethodInsnNode ctor(Class clazz, Class... args) {
		Type[] argTypes = new Type[args.length];
		for (int i = 0; i < args.length; i++) {
			argTypes[i] = Type.getType(args[i]);
		}
		return ctor(Type.getType(clazz), argTypes);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy