GVKun编程网logo

python, compiler, interpreter, VM, bytecode

1

本篇文章给大家谈谈python,compiler,interpreter,VM,bytecode,同时本文还将给你拓展:org.eclipse.jdt.internal.compiler.Compil

本篇文章给大家谈谈python, compiler, interpreter, VM, bytecode,同时本文还将给你拓展: org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/eclipse/jdt/core/compiler/IProblem;、ASM ByteCode 方法局部变量、Bytecode VM in a nutshell、bytecode-viewer 显示乱码等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

python, compiler, interpreter, VM, bytecode

python, compiler, interpreter, VM, bytecode

python source code --(compiler)--> python bytecode --(VM or interpreter)--> execution

 

http://stackoverflow.com/questions/2998215/if-python-is-interpreted-what-are-pyc-files

(回复很精彩)

: org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/eclipse/jdt/core/compiler/IProblem;

: org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/eclipse/jdt/core/compiler/IProblem;

java.lang.NoSuchMethodError: org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/eclipse/jdt/core/compiler/IProblem;
at org.apache.jasper.compiler.JDTCompiler$2.acceptResult(JDTCompiler.java:354)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:480)
at org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:425)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:298)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:277)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:265)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:564)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:299)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
十二月 26, 2016 4:43:02 下午 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet [jsp] in context with path [/shake] threw exception [java.lang.NoSuchMethodError: org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/eclipse/jdt/core/compiler/IProblem;] with root cause
java.lang.NoSuchMethodError: org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/eclipse/jdt/core/compiler/IProblem;
at org.apache.jasper.compiler.JDTCompiler$2.acceptResult(JDTCompiler.java:354)

ASM ByteCode 方法局部变量

ASM ByteCode 方法局部变量

如何解决ASM ByteCode 方法局部变量

我正在使用 Java/ASM 并处理一个类的字节码,我想获取本地定义的变量的数据类型。

我已经写了基本的visitMethod,但是我不确定如何获取本地定义的变量的数据类型。

  1. public class CVisitor extends ClassVisitor{
  2. public CVisitor(int api,ClassVisitor classVisitor) {
  3. super(api,classVisitor);
  4. // Todo Auto-generated constructor stub
  5. }
  6. @Override
  7. public MethodVisitor visitMethod(int access,String name,String descriptor,String signature,String[] exceptions)
  8. {
  9. System.out.println(name);
  10. MethodVisitor mv = cv.visitMethod(access,name,descriptor,signature,exceptions);
  11. System.out.println("desc="+descriptor);
  12. return null;
  13. }

解决方法

AFAIR 字节码中不存在局部变量名称,因此无法实现。

Bytecode VM in a nutshell

Bytecode VM in a nutshell

高级编程语言解释器大多采用了字节码(Bytecode)的方式实现,首先把源文件编译为结构简单的虚拟机指令,也就是Bytecode,然后再使用解释器虚拟机(VM)来执行。

下面来模拟一个计算器虚拟机的构成。
计算器虚拟机的指令格式:

struct Code
{
 Byte code[4];
 Code() {}
 Code(OPCODE op, Byte va0, Byte va1, Byte va2)
 {
   code[0] = op;
   code[1] = va0;
   code[2] = va1;
   code[3] = va2;
 }
};

计算器虚拟机的命令:

enum OPCODE
{
 OP_LOAD = 0, //LOAD reg,num,0 : reg <- num
 OP_ADD, //ADD dest,src1,src2 : src1 + src2 = dest
 OP_SUB, //SUB dest,src1,src2 : src1 - src2 = dest
 OP_MUL, //MUL dest,src1,src2 : src1 * src2 = dest
 OP_DEC, //DEC dest,src1,src2 : src1 * src2 = dest
 OP_OUT, //OUT
 OP_STOP, //STOP
};

Big Switch版本的VM逻辑如下:

 switch (itr->code[0])
 {
 case OP_LOAD:
 {
   int pos = itr->code[1];
   int val = itr->code[2];
   stack[pos] = val;
   itr++;
   break;
 }
 case OP_ADD:
 {
   int dst = itr->code[1];
   int src0 = itr->code[2];
   int src1 = itr->code[3];
   stack[dst] = stack[src0] + stack[src1];
   itr++;
   break;
 }
 case OP_SUB:
 {
   int dst = itr->code[1];
   int src0 = itr->code[2];
   int src1 = itr->code[3];
   stack[dst] = stack[src0] - stack[src1];
   itr++;
   break;
 }
 case OP_MUL:
 {
   int dst = itr->code[1];
   int src0 = itr->code[2];
   int src1 = itr->code[3];
   stack[dst] = stack[src0] * stack[src1];
   itr++;
   break;
 }
 case OP_DEC:
 {
   int dst = itr->code[1];
   int src0 = itr->code[2];
   int src1 = itr->code[3];
   stack[dst] = stack[src0] / stack[src1];
   itr++;
   break;
 }
 case OP_OUT:
 {
   int dst = itr->code[1];
   printf("%.3fn", stack[dst]);
   itr++;
   break;
 }
 default:
   return;
 }

模拟一下函数指针(Function pointer)列表的实现:

typedef void (*ExecCode)(Byte arg0, Byte arg1, Byte arg2);
HashMap<int,ExecCode> dispatchMap;
….
dispatchMap.find(opcode)(op.code[1],op.code[2],op.code[3]);
….

函数调用要消耗额外的对于栈操作的时间,虽然在纯64位环境,参数数量有限且类型是特别指定的简单类型时,call可以跟jmp差不多快,但是大部分情况下BigSwitch的表现要强于函数指令列表。

还有很多早期语言使用的一种方式,叫做Threading。BigSwitch的问题在于,每一条指令的执行需要jmp许多次。

GNU GCC编译器有两个备受诟病的扩展,就是&&label和goto (void),新版的LLVM也支持这个扩展,官方称为Address of label 和 Indirect Branches。

看上去大概是这个样子:

static const void *labelAddr = &&LABEL
goto *(labelAddr);
...
LABEL:
 //do something

但是很遗憾Visual C++ 和 Intel C++编译器并不支持这个扩展,于是有机智的老外想到了使用内联汇编来模拟,使用宏来做条件编译的话可以这么干:

#ifdef _WIN32
# define STORE_LABEL(index,label) __asm lea eax, label\
 __asm mov edx,_llistd\
 __asm mov [edx][index * TYPE _llistd],eax
# define GOTO_LABEL(addr) __asm jmp addr
#else
# define STORE_LABEL(index,label) _llist[index] = &&label
# define GOTO_LABEL(addr) goto *(addr)
#endif

然后就可以愉快的实现Indirect Threading的解释器啦:

MARK_START:
 idx = itr->code[0];
 addr = _llist[idx];
 GOTO_LABEL(addr);
MARK_LOAD:
 pos = itr->code[1];
 val = itr->code[2];
 stack[pos] = val;
 itr++;
 idx = itr->code[0];
 addr = _llist[idx];
 GOTO_LABEL(addr);
MARK_ADD:
 dst = itr->code[1];
 src0 = itr->code[2];
 src1 = itr->code[3];
 stack[dst] = stack[src0] + stack[src1];
 itr++;
 idx = itr->code[0];
 addr = _llist[idx];
 GOTO_LABEL(addr);
MARK_SUB:
 …
MARK_STOP:
 return;
MARK_INIT:
 STORE_LABEL(OP_LOAD, MARK_LOAD);
 STORE_LABEL(OP_ADD, MARK_ADD);
 STORE_LABEL(OP_SUB, MARK_SUB);
 STORE_LABEL(OP_MUL, MARK_MUL);
 STORE_LABEL(OP_DEC, MARK_DEC);
 STORE_LABEL(OP_OUT, MARK_OUT);
 STORE_LABEL(OP_STOP, MARK_STOP);
 goto MARK_START;
}

看上去实在棒棒哒,不过很可惜有两个大问题:

  1. 在Windows/VC++平台上,汇编版本的Indirect Threading竟然比Big Switch还要慢,并且慢很多!
  2. 在Windows/VC++平台上,X64编译器不支持内联汇编,要么放弃64位,要么就转去用Intel C++编译器。

其实使用GCC编译的话,如果不使用-O2优化选项,直接生成代码,得到的结果仍然是BigSwitch要快一些,在优化后,Indirect Threading的版本要比BigSwitch版本快大约10%。

内联汇编版本和GCC未优化版本之所以慢,就在那一个跳转上:

VC++最终编译后的汇编指令:

jmp DWORD PTR _addr$[ebp]

GCC开启优化后的汇编指令:

jmp *%rax

有鉴于此,一些编译器选择直接使用汇编来实现Bytecode VM,比如LuaJIT。

bytecode-viewer 显示乱码

bytecode-viewer 显示乱码

如果在使用 Bytecode Viewer 查看字节码时出现乱码,可能是因为默认的字符编码设置不正确。你可以尝试通过以下方法解决这个问题:

  1. 在启动 Bytecode Viewer 之前,检查操作系统的默认字符编码设置。确保它与源代码文件的字符编码一致。常见的字符编码包括 UTF-8、GBK、GB2312 等。

  2. 如果是使用命令行或终端运行 Bytecode Viewer,可以尝试在启动命令中明确设置字符编码。例如,在 Windows 上使用命令提示符运行 Bytecode Viewer,可以执行以下命令:

 
复制代码

java -Dfile.encoding=UTF-8 -jar bytecode-viewer.jar

上述命令中的 -Dfile.encoding=UTF-8 设置了字符编码为 UTF-8。你可以根据需要修改为适合你的字符编码。

  1. 如果 Bytecode Viewer 提供了界面选项来设置字符编码,请尝试找到相应的设置,并将字符编码设置为正确的值。

如果上述方法都无法解决乱码问题,可能是 Bytecode Viewer 自身的问题导致的。你可以尝试寻找其他类似的工具或联系 Bytecode Viewer 的开发者以获取支持。

希望这些信息对你有帮助!

今天关于python, compiler, interpreter, VM, bytecode的分享就到这里,希望大家有所收获,若想了解更多关于: org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/eclipse/jdt/core/compiler/IProblem;、ASM ByteCode 方法局部变量、Bytecode VM in a nutshell、bytecode-viewer 显示乱码等相关知识,可以在本站进行查询。

本文标签: