我正在考虑写自己的小语言.
我找到了一些选择,但可以随意提出更多建议.
很多语言都在使用JVM,但除非你编写一个Java-ish语言,否则stdlib给你的所有功能都会让你感到难过; 它在动态的东西上也不是很好.
Parrot似乎是开发语言的好VM,但它有一点废弃/未完成/爱好项目的味道.
OSA是Applescript的推动力,而不是一个特别知名的虚拟机,但我使用的是Mac,它提供了良好的系统集成.
CLR + Mac似乎不是一个很好的组合......
我的语言将成为面向对象的功能并发数据流语言,具有强类型和Python和Lisp语法的混合.听起来不错,嗯?
[编辑]
我现在接受了Python,但我想更多地了解OSA和Parrot.
我正在用C写一个虚拟机只是为了好玩.Lame,我知道,但幸运的是我在这么做,所以希望没有人会取笑:)
我写了一个非常快速的虚拟机,它可以读取(我自己的)ASM的行并完成任务.现在,我只有3个指令:add,jmp,end.一切都很好,实际上非常酷,能够提供线路(做类似的事情write_line(&prog[1], "jmp", regA, regB, 0);然后运行程序:
while (machine.code_pointer <= BOUNDS && DONE != true)
{
run_line(&prog[machine.cp]);
}
Run Code Online (Sandbox Code Playgroud)
我在C中使用操作码查找表(可能效率不高但很优雅),一切似乎都正常.
我的问题更多的是一个"最佳实践"问题,但我认为这是一个正确的答案.我正在使VM能够读取二进制文件(存储字节unsigned char[])并执行字节码.我的问题是:VM的工作是确保字节码格式正确,还是只是编译器的工作才能确保它吐出的二进制文件格式正确?
我只问这个,因为如果有人编辑二进制文件并搞砸了(删除它的任意部分等)会发生什么.很明显,该程序将是错误的,可能不起作用.这甚至是VM的问题吗?我确信比我聪明的人已经找到了解决这些问题的方法,我只是好奇他们是什么!
当甲骨文通过Dalvik VM起诉Google时,很明显,如果没有Oracle的许可,你就无法实现Java VM(编辑:Matthew Flaschen指出,Oracle的说法可能无效.无论如何我们目前的情况是Oracle,威胁VM实现.).这可能成为Java的开源实现(如Apache Harmony)的死亡.
我不想讨论这起诉讼的影响或合法性.但作为一名Java程序员,我想深入研究替代方案,为每个案例做好准备.当我将编译器的创建视为一个小问题时,我的主要兴趣是替代的VM实现,其用途与JVM类似.
我正在寻找的VM应该满足一些条件:
请为我添加一些建议.
在学习Smalltalk时,我看到了3个不同的VM.他们是Squeak/Pharo/Newspeak.他们之间有什么区别?
从语义上讲,Dalvik VM为每种方法都有一组新的寄存器,并且没有访问调用堆栈的指令.但就其实现而言,寄存器应以某种方式保存在方法调用上并在方法返回时恢复.Dalvik(谷歌的实施)如何做到这一点?
我找到了亚瑟惠特尼这件神奇的作品 - http://www.jsoftware.com/jwiki/Essays/Incunabulum
它汇编了一些警告
$ gcc-4.7 incuna.c -o incuna.o
incuna.c: In function 'ma':
incuna.c:8:15: warning: incompatible implicit declaration of built-in function 'malloc' [enabled by default]
incuna.c: In function 'pi':
incuna.c:26:7: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
incuna.c: In function 'nl':
incuna.c:26:24: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
incuna.c: In function 'pr':
incuna.c:28:10: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
incuna.c: In function 'ex':
incuna.c:35:36: warning: assignment …Run Code Online (Sandbox Code Playgroud) 好的,所以我对PHP VM的了解比较天真,最近我一直在想.特别是,PHP中的Web应用程序的请求生命周期是什么样的.我发现了一篇文章在这里,给出了一个很好的解释,但我觉得有有将更多的故事.
根据文章的解释,每次向服务器发出请求时都会解析并执行脚本!这对我来说似乎很疯狂!
我正在尝试通过编写一个利用许多PHP 5.3/5.4功能的小型微框架来学习PHP.因此,我开始考虑静态意味着什么以及静态类变量实际存在多长时间.我希望我的应用程序可以有一个设置阶段,它能够将其结果缓存到具有静态属性的类中.但是,如果在每个请求上解析并执行整个脚本,我就无法看到如何避免为每个请求运行应用程序初始化步骤!
我真的希望我在这里缺少一些重要的东西......任何见解都是非常令人沮丧的!
前言
这是关于提高JIT编译器中的消息发送效率.尽管提到了Smalltalk,但这个问题适用于大多数动态JIT编译语言.
问题
给定一个消息发送站点,它可以被分类为单态,多态或变形.如果发送的消息的接收者总是相同类型,则它是单态发送,如
10 timesRepeat: [Object new].
Run Code Online (Sandbox Code Playgroud)
new总是接收者的地方Object.对于这种发送,JIT发出单态内联缓存.
有时,给定的发送站点会引用一些不同的对象类型,例如:
#(1 'a string' 1.5) do: [:element | element print]
Run Code Online (Sandbox Code Playgroud)
在这种情况下,print被发送到不同类型的对象.对于这些情况,JIT通常会发出多态内联缓存.
当消息不仅仅发送到同一个地方的许多不同对象类型时,就会发生变形消息发送.其中一个最突出的例子是:
Behavior>>#new
^self basicNew initialize
Run Code Online (Sandbox Code Playgroud)
在这里,basicNew创建对象,然后进行initialize初始化.你可以这样做:
Object new
OrderedCollection new
Dictionary new
Run Code Online (Sandbox Code Playgroud)
并且它们都将执行相同的行为>> #new方法.由于初始化的实现在很多类中是不同的,因此PIC将很快填充.我对这种发送网站感兴趣,知道它们只是不经常发生(只有1%的发送是变形的).
题
对于变形发送站点有哪些可能的和特定的优化来避免进行查找?
我正在尝试基于探索Ruby的正则表达式算法中概述的回溯方法来实现正则表达式匹配器。编译后的正则表达式将转换为虚拟机命令数组;为了回溯,当前命令和输入字符串索引以及捕获组信息保留在堆栈中。
在“ 正则表达式匹配:虚拟机方法 Cox”中提供了有关如何将某些正则表达式组件编译为VM命令的更多详细信息,尽管所讨论的实现有所不同。根据这些文章,我的实现对于标准分组,字符类和重复组件非常有效。
现在,我想看看这种实现有哪些扩展和优化选项。Cox在他的文章中提供了许多有关DFA / NFA方法的有用信息,但是有关回溯方法的扩展或优化技术的信息却很少。
例如,关于他提到的反向引用
回溯在回溯实现中很简单。
并给出了DFA方法的想法。但是对我来说,尚不清楚如何通过VM方法“轻松地”完成。到达backreference命令后,您必须将来自相应组的先前匹配的字符串编译到另一组VM命令中,并以某种方式将这些命令合并到当前VM中,或者维护第二个VM并暂时将执行切换到该VM。
他还提到了通过使用超前方式在重复中可能进行的优化,但是没有详细说明如何实现。在我看来,这可以用来减少回溯堆栈上的项目数量。
tl; dr针对基于VM的回溯正则表达式实现存在哪些常规优化技术,它们如何工作?请注意,我并不是在寻找特定于某种编程语言的优化,而是在寻找这种正则表达式实现的通用技术。
编辑:如第一个链接中所述,Oniguruma库正是使用基于堆栈的回溯方法来实现正则表达式匹配器。也许有人可以解释该库所做的优化,这些优化可以推广到其他实现中。不幸的是,该库似乎未提供有关源代码的任何文档,并且该代码也缺少注释。
编辑2:在阅读有关解析表达语法(PEG)的文章时,我偶然发现了一篇关于Lua PEG实现的论文,该论文利用了类似的基于VM的方法。本文提到了一些优化选项,以减少已执行的VM命令的数量以及回溯堆栈的不必要增长。