ASMSupport教程4.5 在Class中生成算术运算符

Stella981
• 阅读 545

ASMSupport教程4.5 在Class中生成算术运算符

这节我们开始介绍ASMSupport如何生成算数运算符(+-\*/%),依旧先看我们需要生成的java代码:

package generated.operators;

import java.io.PrintStream; import java.util.Random;

public class ArithmeticOperatorGenerateExample { static void printInt(String s, int i) { System.out.println(s + " = " + i); }

static void printFloat(String s, float f) { System.out.println(s + " = " + f); }

public static void main(String[] args) { Random rand = new Random(); int j = rand.nextInt(100) + 1; int k = rand.nextInt(100) + 1; printInt("j", j); printInt("k", k); int i = j + k; printInt("j + k", i); i = j - k; printInt("j - k", i); i = k / j; printInt("k / j", i); i = k * j; printInt("k * j", i); i = k % j; printInt("k % j", i); j %= k; printInt("j %= k", j); float v = rand.nextFloat(); float w = rand.nextFloat(); printFloat("v", v); printFloat("w", w); float u = v + w; printFloat("v + w", u); u = v - w; printFloat("v - w", u); u = v * w; printFloat("v * w", u); u = v / w; printFloat("v / w", u); u += v; printFloat("u += v", u); u -= v; printFloat("u -= v", u); u *= v; printFloat("u *= v", u); u /= v; printFloat("u /= v", u); } }

对应的代码如下,由于代码比较多,我们将对应的java代码写在asmsupport代码之上,便于对比。

package example.operators;

import java.util.Random;

import org.objectweb.asm.Opcodes;

import jw.asmsupport.block.method.common.StaticMethodBody; import jw.asmsupport.clazz.AClass; import jw.asmsupport.clazz.AClassFactory; import jw.asmsupport.creator.ClassCreator; import jw.asmsupport.definition.value.Value; import jw.asmsupport.definition.variable.LocalVariable; import jw.asmsupport.operators.method.MethodInvoker; import jw.asmsupport.operators.numerical.arithmetic.Addition;

import example.AbstractExample;

public class ArithmeticOperatorGenerate extends AbstractExample {

/**
 * @param args
 */
public static void main(String[] args) {
    ClassCreator creator = new ClassCreator(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "generated.operators.ArithmeticOperatorGenerateExample", null, null);

    //printIn方法
    creator.createStaticMethod("printInt", new AClass[]{AClass.STRING_ACLASS, AClass.INT_ACLASS}, new String[]{"s", "i"}, null, null, 0, new StaticMethodBody(){

        @Override
        public void generateBody(LocalVariable... argus) {
            invoke(systemOut, "println", append(argus[0], Value.value(" = "), argus[1]));
            runReturn();
        }
        
    });
    
    //printIn方法
    creator.createStaticMethod("printFloat", new AClass[]{AClass.STRING_ACLASS, AClass.FLOAT_ACLASS}, new String[]{"s", "f"}, null, null, 0, new StaticMethodBody(){

        @Override
        public void generateBody(LocalVariable... argus) {
            invoke(systemOut, "println", append(argus[0], Value.value(" = "), argus[1]));
            runReturn();
        }
        
    });        
    
    creator.createStaticMethod("main", new AClass[] { AClassFactory.getProductClass(String[].class) }, new String[] { "args" }, null, null, Opcodes.ACC_PUBLIC +

            Opcodes.ACC_STATIC, new StaticMethodBody() {

                @Override
                public void generateBody(LocalVariable... argus) {
                    //Random rand = new Random();
                    LocalVariable rand = createVariable("rand", AClassFactory.getProductClass(Random.class), false, invokeConstructor(AClassFactory.getProductClass(Random.class)));
                    
                    //rand.nextInt(100) + 1
                    Addition add1 = add(invoke(rand, "nextInt", Value.value(100)), Value.value(1));
                    
                    //int j = rand.nextInt(100) + 1;
                    LocalVariable j = createVariable("j", AClass.INT_ACLASS, false, add1);
                    
                    //int k = rand.nextInt(100) + 1;
                    LocalVariable k = createVariable("k", AClass.INT_ACLASS, false, add1);
                    
                    //printInt("j", j);
                    invokeStatic(getMethodOwner(), "printInt", Value.value("j"), j);

                    //printInt("k", k);
                    invokeStatic(getMethodOwner(), "printInt", Value.value("k"), k);
                    
                    //j + k
                    Addition add2 = add(j, k);
                    //int i = j + k;
                    LocalVariable i = createVariable("i", AClass.INT_ACLASS, false, add2);
                    
                    //printInt("j + k", i);
                    invokeStatic(getMethodOwner(), "printInt", Value.value("j + k"), i);
                    
                    //i = j - k;
                    assign(i, sub(j, k));
                    
                    //printInt("j - k", i);
                    invokeStatic(getMethodOwner(), "printInt", Value.value("j - k"), i);
                    
                    //i = k / j;
                    assign(i, div(k, j));
                    
                    //printInt("k / j", i);
                    invokeStatic(getMethodOwner(), "printInt", Value.value("k / j"), i);
                    
                    //i = k * j;
                    assign(i, mul(k, j));
                    
                    //printInt("k * j", i);
                    invokeStatic(getMethodOwner(), "printInt", Value.value("k * j"), i);
                    
                    //i = k % j;
                    assign(i, mod(k, j));
                    
                    //printInt("k % j", i);
                    invokeStatic(getMethodOwner(), "printInt", Value.value("k % j"), i);
                    
                    //j %= k;
                    assign(j, mod(j, k));
                    
                    //printInt("j %= k", j);
                    invokeStatic(getMethodOwner(), "printInt", Value.value("j %= k"), j);
                    
                    
                    //rand.nextFloat()
                    MethodInvoker nextFloat = invoke(rand, "nextFloat");
                    
                    //v = rand.nextFloat();
                    LocalVariable v = createVariable("v", AClass.FLOAT_ACLASS, false, nextFloat);
                    
                    //w = rand.nextFloat();
                    LocalVariable w = createVariable("w", AClass.FLOAT_ACLASS, false, nextFloat);
                    
                    //printFloat("v", v);
                    invokeStatic(getMethodOwner(), "printFloat", Value.value("v"), v);
                    
                    //printFloat("w", w);
                    invokeStatic(getMethodOwner(), "printFloat", Value.value("w"), w);
                    
                    //u = v + w;
                    LocalVariable u = createVariable("u", AClass.FLOAT_ACLASS, false, add(v,w));
                    
                    //printFloat("v + w", u);
                    invokeStatic(getMethodOwner(), "printFloat", Value.value("v + w"), u);

                    //u = v - w;
                    assign(u, sub(v, w));
                    
                    //printFloat("v - w", u);
                    invokeStatic(getMethodOwner(), "printFloat", Value.value("v - w"), u);
                    
                    //u = v * w;
                    assign(u, mul(v, w));
                    
                    //printFloat("v * w", u);
                    invokeStatic(getMethodOwner(), "printFloat", Value.value("v * w"), u);
                    
                    //u = v / w;
                    assign(u, div(v, w));
                    
                    //printFloat("v / w", u);
                    invokeStatic(getMethodOwner(), "printFloat", Value.value("v / w"), u);
                    
                    //u += v;
                    assign(u, add(u, v));
                    
                    //printFloat("u += v", u);
                    invokeStatic(getMethodOwner(), "printFloat", Value.value("u += v"), u);
                    
                    //u -= v;
                    assign(u, sub(u, v));
                    
                    //printFloat("u -= v", u);
                    invokeStatic(getMethodOwner(), "printFloat", Value.value("u -= v"), u);
                    
                    //u *= v;
                    assign(u, mul(u, v));
                    
                    //printFloat("u *= v", u);
                    invokeStatic(getMethodOwner(), "printFloat", Value.value("u *= v"), u);
                    
                    //u /= v;
                    assign(u, div(u, v));
                    
                    //printFloat("u /= v", u);
                    invokeStatic(getMethodOwner(), "printFloat", Value.value("u /= v"), u);
                    
                    runReturn();
                }
            });
    generate(creator);
}

}

这里我们不逐行解释,只对生成算术操作的方法进行解释:

  • jw.asmsupport.block.ProgramBlock.add(Parameterized factor1, Parameterized factor2) : 生成加法操作,生成的代码是factor1+factor2,返回类型jw.asmsupport.operators.numerical.arithmetic.Addition
  • jw.asmsupport.block.ProgramBlock.sub(Parameterized factor1, Parameterized factor2) : 生成减法操作,生成的代码是factor1-factor2 , 返回类型jw.asmsupport.operators.numerical.arithmetic.Subtraction
  • jw.asmsupport.block.ProgramBlock.mul(Parameterized factor1, Parameterized factor2): 生成乘法操作,生成的代码是factor1\*factor2 , 返回类型jw.asmsupport.operators.numerical.arithmetic.Multiplication
  • jw.asmsupport.block.ProgramBlock.div(Parameterized factor1, Parameterized factor2):  生成除法操作,生成的代码是factor1/factor2 , 返回类型jw.asmsupport.operators.numerical.arithmetic.Division
  • jw.asmsupport.block.ProgramBlock.mod(Parameterized factor1, Parameterized factor2):生成取模操作,生成的代码是factor1%factor2 , 返回类型jw.asmsupport.operators.numerical.arithmetic.Modulus

这些方法的返回值都是继承自jw.asmsupport.Parameterized接口的,这个接口意味着这个类还可以被其他的操作所使用,这个很容易理解,我可以将a+b这个运算作为参数传入某个方法,比如有个方法是c(int a),我们可以这样调用:c(a+b)。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Java修道之路,问鼎巅峰,我辈代码修仙法力齐天
<center<fontcolor00FF7Fsize5face"黑体"代码尽头谁为峰,一见秃头道成空。</font<center<fontcolor00FF00size5face"黑体"编程修真路破折,一步一劫渡飞升。</font众所周知,编程修真有八大境界:1.Javase练气筑基2.数据库结丹3.web前端元婴4.Jav
Stella981 Stella981
2年前
ASMSupport教程4.7 生成关系运算符
<p在java中,关系运算符是很常用的,分别是&gt;,,&lt;,&gt;,&lt;,!这六种,我们按照惯例看看我们需要生成的代码:</p<divid"scid:9D7513F9C04C4721824A2B34F0212519:dfec0f1ca2ec4ebabc9b91c161fbfa47"class"wlWri
Wesley13 Wesley13
2年前
thinkphp3.2.3模板渲染支持三元表达式
thinkphp3.2.3模板渲染支持三元表达式{$status?'正常':'错误'}{$info'status'?$info'msg':$info'error'}注意:三元运算符中暂时不支持点语法。如下:           <divclass"modalhidefade"id'myModa
Stella981 Stella981
2年前
ASMSupport教程4.9 生成三元运算符
<p这节我们介绍如何用ASMSupport生成三元运算符(...?...:...)运算符。我们预计生成如下代码:</p<divid"scid:9D7513F9C04C4721824A2B34F0212519:935e30cc33214e0093ba9834f3a4e044"class"wlWriterEditableS
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这