当前位置: 首页 > news >正文

百度网站怎样做wordpress工业模板

百度网站怎样做,wordpress工业模板,北京自适应网站建设,南京网站设计公司兴田德润电话多少Label 介绍 在 ASM 中#xff0c;每一个 Label 必须对应一个 Frame#xff0c;两个 Label 可以共享一个 Frame#xff0c;可以理解为将两个 Label 合并了#xff0c;而一个 Frame 只对应一个 Label#xff0c;就是创建它的 Label。每一次定义一个方法#xff0c;即执行 …Label 介绍 在 ASM 中每一个 Label 必须对应一个 Frame两个 Label 可以共享一个 Frame可以理解为将两个 Label 合并了而一个 Frame 只对应一个 Label就是创建它的 Label。每一次定义一个方法即执行 ClassWriter#visitMethod 方法时调用 MethodWriter 构造方法都会在构造方法中创建一个 Label作为 firstBasicBlock 使用接着访问切换到这个 Label。 在 Frame 中会存在 inputLocals : 方法参数存放于此对应 LOAD 指令 inputStack 类似于一个中转 outputLocals : 各种 STORE 指令会操作这个栈 outputStack 方法的运行操作主要在这个栈中执行各种指令其实最后都是转化成了针对这个outputStack 的 pop 和 push 操作 栈的初始化 此处 MethodWriter.compute 为 COMPUTE_ALL_FRAMES inputLocals:  inputStack: final void setInputFrameFromDescriptor(final SymbolTable symbolTable,final int access,final String descriptor,final int maxLocals) {inputLocals new int[maxLocals];inputStack new int[0];int inputLocalIndex 0;if ((access Opcodes.ACC_STATIC) 0) {if ((access Constants.ACC_CONSTRUCTOR) 0) {inputLocals[inputLocalIndex] REFERENCE_KIND | symbolTable.addType(symbolTable.getClassName());} else {inputLocals[inputLocalIndex] UNINITIALIZED_THIS;}}for (Type argumentType : Type.getArgumentTypes(descriptor)) {int abstractType getAbstractTypeFromDescriptor(symbolTable, argumentType.getDescriptor(), 0);inputLocals[inputLocalIndex] abstractType;if (abstractType LONG || abstractType DOUBLE) {inputLocals[inputLocalIndex] TOP;}}while (inputLocalIndex maxLocals) {inputLocals[inputLocalIndex] TOP;}} 可以看到非 static 方法非构造方法第一个参数对应抽REFERENCE_KIND表示这个类即我们常用的 this接着遍历参数放入每个参数对应的抽象类型这点与Java虚拟机栈保持一致。上面描述的方法会在自定义字节码操作完成执行 MethodWriter#visitMax 时进行调用。 outputLocals: private void setLocal(final int localIndex, final int abstractType) {// Create and/or resize the output local variables array if necessary.if (outputLocals null) {outputLocals new int[10];}int outputLocalsLength outputLocals.length;if (localIndex outputLocalsLength) {int[] newOutputLocals new int[Math.max(localIndex 1, 2 * outputLocalsLength)];System.arraycopy(outputLocals, 0, newOutputLocals, 0, outputLocalsLength);outputLocals newOutputLocals;}// Set the local variable.outputLocals[localIndex] abstractType;} 当执行各种 STORE 指令时会进行 outputLocals 的初始化。 outputStack: private void push(final int abstractType) {// Create and/or resize the output stack array if necessary.if (outputStack null) {outputStack new int[10];}int outputStackLength outputStack.length;if (outputStackTop outputStackLength) {int[] newOutputStack new int[Math.max(outputStackTop 1, 2 * outputStackLength)];System.arraycopy(outputStack, 0, newOutputStack, 0, outputStackLength);outputStack newOutputStack;}// Pushes the abstract type on the output stack.outputStack[outputStackTop] abstractType;// Updates the maximum size reached by the output stack, if needed (note that this size is// relative to the input stack size, which is not known yet).short outputStackSize (short) (outputStackStart outputStackTop);if (outputStackSize owner.outputStackMax) {owner.outputStackMax outputStackSize;}} 当执行涉及到入栈的指令时例如获取属性 GETFIELD、加载 ALOAD、方法调用 INVOKEVIRTUAL 等指令时会进行 outputStack 的初始化。 并且从上面可以看到各种栈都是 int 型所以当遇到转化为抽象类型为 LONG 和 DOUBLE 的变量类型时在各种栈中占两位即 2 个 int8 个 字节。 模型简介 在 ASM 的栈分为 inputStack 和 outputStackoutputStack 紧接着 inputStack。还有一个参数outputStackStart通过这个参数控制 inputStack 的大小这个参数只能为 0 或 负数为负数表明用到了上一任 Label 中的变量。 参照源码中对 outputStackStart 的注释 outputStackStart输出栈相对于输入栈的起始位置。这个偏移量总是负的或为空。空偏移量意味着输出栈必须追加到输入栈上。-n偏移量意味着前n个输出栈元素必须替换前n个输入栈栈顶元素而其他元素必须追加到输入栈上。 所以当前 Label 输入栈大小 numInputStack inputStack.length outputStackStart 不同的 Label 之间通过设置 successor 这种关系可以使用前任 Label 的输入栈和输出栈。其中前任的输入栈和输出栈会作为 successor 的输入栈所以 前任的输入栈大小numInputStack 前任的输出栈大小outputStackTop successor 的输入栈大小numInputStack outputStackTop 应用 利用设置的 successor 关系操作变量 public class Generate49 implements Opcodes {public static void main(String[] args) {String generateClassName ASM$Generate49;ClassLoaderUtils.outputClass(generate(generateClassName), generateClassName);}private static byte[] generate(String generateClassName) {ClassWriter cw new ClassWriter(ClassWriter.COMPUTE_FRAMES);// declare_classcw.visit(V1_8, ACC_PUBLIC, generateClassName, null, java/lang/Object, null);// declare_fieldcw.visitField(ACC_PRIVATE, name, Ljava/lang/String;, null, null);// declare_methodMethodVisitor mv cw.visitMethod(ACC_PUBLIC, toUppercaseName, ()Ljava/lang/String;, null, null);mv.visitVarInsn(ALOAD, 0);mv.visitFieldInsn(GETFIELD, generateClassName, name, Ljava/lang/String;);mv.visitInsn(DUP);Label l1 new Label();mv.visitJumpInsn(IFNULL, l1);mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(String.class), toUpperCase, ()Ljava/lang/String;, false);mv.visitInsn(ARETURN);mv.visitLabel(l1);mv.visitInsn(ACONST_NULL);mv.visitInsn(ARETURN);mv.visitMaxs(0, 0);return cw.toByteArray();} } 上面代码中的 DUP 指令就是为了保证在执行 INVOKEVIRTUAL 指令时可以利用到前任 Label的输出在执行 visitJumpInsn 时已经发生了 Label 的切换即通过 GETFIELD 指令获取到的name 属性接着执行方法调用。 利用 STORE 操作变量 public class Generate491 implements Opcodes {public static void main(String[] args) {String generateClassName ASM$Generate491;ClassLoaderUtils.outputClass(generate(generateClassName), generateClassName);}private static byte[] generate(String generateClassName) {ClassWriter cw new ClassWriter(ClassWriter.COMPUTE_FRAMES);// declare_classcw.visit(V1_8, ACC_PUBLIC, generateClassName, null, java/lang/Object, null);// declare_fieldcw.visitField(ACC_PRIVATE, name, Ljava/lang/String;, null, null);// declare_methodMethodVisitor mv cw.visitMethod(ACC_PUBLIC, toUppercaseName, ()Ljava/lang/String;, null, null);mv.visitVarInsn(ALOAD, 0);mv.visitFieldInsn(GETFIELD, generateClassName, name, Ljava/lang/String;);mv.visitVarInsn(ASTORE, 1);Label l1 new Label();mv.visitVarInsn(ALOAD, 1);mv.visitJumpInsn(IFNULL, l1);mv.visitVarInsn(ALOAD, 1);mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(String.class), toUpperCase, ()Ljava/lang/String;, false);mv.visitInsn(ARETURN);mv.visitLabel(l1);mv.visitInsn(ACONST_NULL);mv.visitInsn(ARETURN);mv.visitMaxs(0, 0);return cw.toByteArray();} } 可以看到使用 STORE 命令后每一次操作使用到变量都需先进行 LOAD增加了代码量但又直观的反映了栈操作的过程即先入栈再出栈。 生成的代码如下 public class ASM$Generate49 {private String name;public String toUppercaseName() {String var10000 this.name;return var10000 ! null ? var10000.toUpperCase() : null;} } 可以看到即使是很简单的一个类和方法通过ASM操作起来代码量都是生成类中代码的好几倍。而为了便于使用衍生出了 CGLIB 这样的开源项目其实就是ASM的一个具体应用。 附上上述代码中的工具类ClassLoaderUtils: public class ClassLoaderUtils extends ClassLoader {public static final String CLASS_SUFFIX .class;public Class? defineClass(String name, byte[] bytes) {return super.defineClass(name, bytes,0, bytes.length);}public static void outputClass(byte[] bytes, String name) {FileOutputStream fos null;try {String pathName ClassLoaderUtils.class.getResource(/).getPath() name CLASS_SUFFIX;fos new FileOutputStream(new File(pathName));fos.write(bytes);} catch (IOException e) {e.printStackTrace();} finally {try {fos.close();} catch (IOException e) {e.printStackTrace();}}} }
http://www.zqtcl.cn/news/648229/

相关文章:

  • 网站设计 原型图html购物网站模板
  • 谷歌网站推广报价国产搜什么关键词最好看
  • 婚礼网站有哪些个人做网站需要什么条件
  • 深圳企业网站seo人才招聘网站建设
  • 谷歌下载seo是什么软件
  • 个人网站设计分析小程序在线制作平台
  • 网站开发 一般用什么语言vi视觉设计案例
  • 微信公众平台官方网官网seo优化找哪家做
  • 简约 网站模板网站目录链接怎么做
  • 国内地铁建设公司网站大连做网站外包
  • 微网站营销是什么网站图片上传代码
  • 外包公司做网站多少用vs做的网站怎么打开
  • 兴义城乡建设部网站企业服务器配置方案
  • 淘宝客网站根目录wordpress调用导航代码
  • 海外免费网站推广网站开发项目报告书
  • 大气的金融网站深圳专门做兼职的网站
  • 最新网站备案四平网站公司
  • 济宁恒德建设有限公司网站互联网营销师报名入口
  • 做灯饰的企业都会在哪些网站网站排名恢复
  • 互联网公司网站建设价格跨境支付互联互通
  • 杭州 高端网站 开发宜昌建设网站公司
  • 咋样做网站快照济南建设质量协会网站
  • 学校网站怎么建设兄弟网络(西安网站建设制作公司)
  • 长春市城乡建设局网站photoshop破解版下载免费中文版
  • 吕梁网站设计天津高端网页制作
  • 建一个网站做cpa联盟做淘客的网站都有哪几个
  • 中国建设银行网站对公业务wordpress 文章归档页面
  • 东软 网站群平台建设用个人电脑做网站服务器
  • 音乐播放网站开发pc端营销网站的关键字
  • 江门网站推广宿州官方网站建设