例如我可以做这样的事情吗
pythonCode = "print 'hello world'"
pyc = generate_bytecode(pythonCode)
Run Code Online (Sandbox Code Playgroud)
其中 pyc 将包含 pythonCode 的字节码?
编辑:我的目标本质上是准确获取将写入文件中的 .pyc 的内容到变量中。幻数、时间戳、十六进制版本的代码等等
我已经用 Java 创建了一个原型 VM(因为它是我最熟悉的语言),并且我尝试以字节码格式存储指令。我想知道如何在字节码中存储值,因为byte只能是 0 到 255。
举个例子:
push 4752
Run Code Online (Sandbox Code Playgroud)
Push 的操作码值为 0。但是我如何存储 4752?它不适合单个字节。我可以将值存储在 4 个字节中,因此允许它们是 32 位整数,但随后我必须决定是加载操作码(1 个字节)还是一个值(4 个字节)。目前,我将程序作为整数数组传递,VM 循环遍历该数组并执行操作码。如果操作码需要一个值,它会从数组中获取该值,然后增加程序计数器以跳过该值,以便它不会被执行。
我试图弄清楚像 JVM 这样的虚拟机是如何做到这一点的,但我无法找到答案。
所以我有一些类已插入“虚拟方法调用”;即具有空主体的专用类中的静态方法。
这个想法是获取在方法调用之前推送到堆栈的参数,将它们存储在局部变量中,然后用实际实现替换方法调用。
为了看看当地人是如何处理的,我运行
A.java
package asmvisit;
public class A {
long y;
public long doSomething(int x, A a){
if(a == null){
this.y = (long)x;
return -1L;
}
else{
long old = y;
this.y += (long)x;
return old;
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过文本编辑器(代码在帖子底部)。
正如您在输出中看到的(也在帖子的底部),局部变量
LOCALVARIABLE old J L4 L6 3
LOCALVARIABLE this Lasmvisit/A; L0 L6 0
LOCALVARIABLE x I L0 L6 1
LOCALVARIABLE a Lasmvisit/A; L0 L6 2
Run Code Online (Sandbox Code Playgroud)
在方法的最后被访问。
从技术上讲,我们将被允许更早地访问它们,但我明白为什么在任意位置插入局部变量可能会搞乱编号 - 以及程序。
因此,在我看来,添加更多局部变量的唯一安全方法是对每个方法运行两次:
visitMaxs,使用计数器来跟踪新局部变量最终将拥有的索引。有没有更简单的替代方案,不需要两次通过?
文本化器
package asmvisit; …Run Code Online (Sandbox Code Playgroud) 目前,我参与了一个大型遗留项目,其中包含许多巨大的类和生成的代码。我希望找到所有字节码长度大于 8000 字节的方法(因为 OOTB java 不会优化它)。
我找到了这样的手动方式:How much bytes of bytecode has a certain method in Java? ,但是我的目标是自动扫描许多文件。
我尝试使用 jboss-javassist,但据我所知,获取字节码长度仅在类级别可用。
我相信这是一个经常被问到的问题,但我一直无法找到或找到答案
编译/执行 python 时,__pycache__会创建一个目录,其中主要包含字节码,以便下次使用该模块中的代码时节省时间。
请注意,这可以被抑制
我的问题是为什么__pycache__在设计语言时要隐藏该目录?
(例如.__pycache__在 UNIX 系统上)
这是可能且可行的,因为 git 程序对文件夹执行此操作.git,我相信该文件夹也隐藏在 Windows 计算机上
如https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-2.html#jvms-2.11.1 所述,将操作数类型编码为操作码是有代价的:
鉴于 Java 虚拟机的一字节操作码大小,将类型编码为操作码会给指令集的设计带来压力。如果每个类型化指令都支持 Java 虚拟机的所有运行时数据类型,那么指令数量将超过一个字节所能表示的数量。
因此,似乎应该只对需要操作数类型信息或启用优化的指令执行此操作。例如,需要区分iadd和fadd,因为整数和浮点数的加法实现方式不同。而且我不知道为什么有不同的指令从数组(分别为和)加载 aboolean和 an ,但我至少可以想象一些性能原因。intbaloadiaload
但是,为什么将int( istore) 和float( fstore)存储到局部变量中有不同的指令?它们不应该以完全相同的方式实施吗?
这个答案/sf/answers/184670041/说字节码验证器需要输入指令。但这真的有必要吗?在一个方法中,所有数据都从方法的参数(类型已知)和类字段(类型也已知)流向其他类字段和返回值。因此,由于输入和输出的类型是已知的,我们不能为指令重建任何缺失的类型吗?事实上,这不是字节码验证器所做的,因为它必须检查类型,即它必须知道需要哪些类型?
简而言之:如果我们将istore和组合fstore成一条指令会破坏什么?性能或便携性会受到影响吗?字节码验证会停止工作吗?
def foo():
while <condition>:
do something
def bar():
for i in range(5):
do something
Run Code Online (Sandbox Code Playgroud)
假设我在一个文件名中定义了两个函数test.py。python 有没有办法编写具有以下行为的函数?
import test
def uses_while(fn: Callable) -> bool:
(what goes here?)
>>> uses_while(test.foo)
True
>>> uses_while(test.bar)
False
Run Code Online (Sandbox Code Playgroud)
我本质上需要以编程方式检查函数是否使用 while 循环,而不需要手动检查代码。我想过使用 pdb.getsourcelines() ,但是如果里面有注释或字符串中包含“while”一词,那么这不起作用。有任何想法吗?
我尝试新建一个内部静态类,但我发现字节码出现 jvm 指令ACONST_NULLbwteen NEW,DUP并且INVOKE_SPECIAL,但我知道一个类 new 是
package com.hoho.api;
/**
* @author linuxea
*/
public class Main {
private static class InnerMain {
// no field
}
public static void main(String[] args) {
InnerMain innerMain = new InnerMain();
}
}
Run Code Online (Sandbox Code Playgroud)
// class version 52.0 (52)
// access flags 0x21
public class com/hoho/api/Main {
// compiled from: Main.java
// access flags 0xA
private static INNERCLASS com/hoho/api/Main$InnerMain com/hoho/api/Main InnerMain
// access flags 0x1008 …Run Code Online (Sandbox Code Playgroud) 我希望我的 python GUI 应用程序可以在所有三个操作系统上运行,而无需在每个平台上重新编译。由 pyinstaller(由或类似实用程序)平台创建的 python 可执行文件是否像 Java 的字节码一样独立?Java 的字节码使用 JRE 在 Windows、Mac 和 Linux 上运行。
我编译了以下方法:
public static final boolean equalTo(final int x, final int y) {
return x == y;
}
Run Code Online (Sandbox Code Playgroud)
可以javap看到为其生成了以下字节码:
public static final boolean equalTo(int, int);
descriptor: (II)Z
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
Code:
stack=2, locals=2, args_size=2
0: iload_0
1: iload_1
2: if_icmpne 9
5: iconst_1
6: goto 10
9: iconst_0
10: ireturn
LineNumberTable:
line 72: 0
StackMapTable: number_of_entries = 2
frame_type = 9 /* same */
frame_type = 64 /* same_locals_1_stack_item */
stack = [ int ]
Run Code Online (Sandbox Code Playgroud)
我编写了 …
bytecode ×10
java ×5
python ×4
jvm ×3
jvm-bytecode ×3
built-in ×1
pyinstaller ×1
python-3.x ×1
unit-testing ×1