我想破解Python解释器并尝试创建一个小型DSL.是否有任何模块我可以做这样的理论代码(类似于LINQ表达式树)?
expression_tree = Function(
Print(
String('Hello world!')
)
)
compile_to_bytecode(expression_tree)
Run Code Online (Sandbox Code Playgroud)
或者只是更容易生成Python源代码?使用C或SWIG或Cython可以使这更容易吗?
在我的Java项目中,我想以编程方式找出使用给定API中的哪些类.有没有一个好方法呢?通过源代码解析或字节码解析可能吗?因为反射不会有任何用处,我担心.
为了简单起见:import com.mycompany.api.*;我的项目中没有任何通配符import(),没有完全限定的字段或变量定义(private com.mycompany.api.MyThingy thingy;),也没有任何Class.forName(...)构造.鉴于这些限制,我认为它可以归结为解析import语句.有没有一种首选的方法来做到这一点?
我正在研究一种基于Scala的脚本语言(内部DSL),它允许用户在Scala脚本文件中定义多个数据转换函数.由于这些功能的应用可能需要几个小时,我想将结果缓存在数据库中.允许用户更改转换函数的定义以及添加新函数.但是,然后用户使用略微修改的脚本重新启动应用程序,我只想执行已更改或添加的那些功能.问题是如何检测这些变化?为简单起见,我们假设用户只能调整脚本文件,以便可以假定对此脚本中未定义的内容的任何引用都不会更改.
在这种情况下,检测此类用户定义函数的更改的最佳实践是什么?
到现在为止我虽然:
然而,这三种方法都存在缺陷.
有人有这些"解决方案"的经验或者可以建议我更好吗?
我已经开始乱用我正在研究的编译器项目的ASM API.但是,我发现文档对很多地方的新手来说并不清楚,我认为有一个很好的例子,可以生成一个只打印"Hello,World!"的类.这将是一个很好的例子.
目前,我可以使用main()(使用ClassWriter,ClassVisitor和MethodVisitor类)生成一个类,但我似乎无法弄清楚如何生成main的主体.任何人都可以给我一个在ASM中生成类文件的示例:
Python文件被编译为字节码(*.pyc).
使用Cython,您可以将它们编译为机器代码(在Linux中为*.so).
如果您使用同一文件夹中的两个文件,则在同一名称下它们之间的优先级是什么?
是否有自动方法来确保使用*.so文件而不是*.pyc文件?或者您必须在代码中明确地执行此操作(重命名等)?
可以说,类中有一些import语句.为该类生成字节代码时,这些import语句会发生什么.
如果在运行时忽略import语句,那么在运行时如何解析对该类方法的依赖性.
我试图在反编译后对一些Java .class文件进行反混淆处理,而且我遇到了代码的一部分,它以一种我认为不能使用标签的方式使用标签.我不知道这是否是反编译器误解标签的错误,或者代码是否故意以这种方式混淆.换句话说,可以在Java字节码中以这种方式使用标签吗?
请注意,标签出现在相关的break语句之后,而不是之前.它几乎似乎是使用它们作为goto,而不是用于退出循环的标签.根本没有循环,所以我对它们应该如何在这里使用感到困惑.
这里发生了什么?我在评论中标记了3个标签(###)
if (i != 96)
{
if ((i ^ 0xFFFFFFFF) != -98)
{
if (i == 98)
break label417; // ### Here are the three breaks... The relevant labels appear later in the code
if (i != 99)
break label540;
if (!bool)
break label461;
}
}
else
{
if (localwb == this.localWB5)
{
if (this.localWB4 != null) {
this.localWB4.a((byte)-92, this);
if (!bool);
}
else
{
this.localWB6.a((byte)-9, this);
}
return true;
}
if (localwb == this.localWB4)
{
this.localWB6.a((byte)-59, …Run Code Online (Sandbox Code Playgroud) 我目前正在编写一个创建Java字节代码并编写方法调用的应用程序.到目前为止,编写此字节代码的模块没有关于调用方法调用的实例的实际类型的信息,但它确实知道为其定义特定方法的类型.例如:
class Foo {
public void foo() { }
}
class Bar extends Foo {
public void bar() { }
}
Run Code Online (Sandbox Code Playgroud)
当前版本的引擎将执行
INVOKEVIRTUAL Foo.foo
Run Code Online (Sandbox Code Playgroud)
甚至在类型的对象上,Bar因为它知道在foo中定义了Foo.这在JVM中是合法的(当然),但Java编译器会将其转换为
INVOKEVIRTUAL Bar.foo
Run Code Online (Sandbox Code Playgroud)
当它是"正常"的Java源代码时.我目前想知道JVM是否实际使用了显式子类型的信息,或者在加载类时是否忽略/优化了它.我想知道,因为验证程序正在计算实际的类型,并且不会让我编写非法的方法调用,我想知道为什么运行时在它已经可用时不会使用这些信息.我特别想知道当超类型是interfaces(INVOKEINTERFACE)时它是否会对性能产生影响,如果JVM无法确定实际类型,则无法使用虚方法表.
我当然可以扩展我的模块,但我需要提供额外的信息,这会使我的代码膨胀,如果它没有效果我不想做.所以我问:类型会影响性能还是JVM会处理这种明确的解决方案?
我正在尝试理解java字节码.我从简单的例子开始:
public class Test
{
public static void main(String args[])
{
System.out.println(2 + 1);
}
}
Run Code Online (Sandbox Code Playgroud)
我编译了这个类:
javac Test.java
Run Code Online (Sandbox Code Playgroud)
然后我尝试javap在.class上像这样:
javap -c Test
Run Code Online (Sandbox Code Playgroud)
这给了我这个:
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: iconst_1
4: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
7: return
}
Run Code Online (Sandbox Code Playgroud)
除了这一行,我能够理解它:
public static void main(java.lang.String[]);
. . .
3: iconst_1
. . …Run Code Online (Sandbox Code Playgroud)