我正在编写一个脚本解释器,我已经设法进入工作状态。它有一个解析脚本并生成字节码的编译器,以及一个执行字节码的VM。
翻译的核心是一个巨大的循环 case
看起来像这样的语句:
case CurrentOpcode.Operation of
OP_1: DoOp1(CurrentOpcode);
OP_2: DoOp2(CurrentOpcode);
...
OP_N: DoOpN(CurrentOpcode);
end;
分析告诉我,无论出于何种原因,我的脚本执行都花费了大量时间 case
声明,这对我来说很奇怪,所以我正在寻找一种优化它的方法。显而易见的解决方案,因为所有操作函数基本上具有相同的签名,就是创建一个由操作码索引的方法指针数组。 Operation
值。但 Operation
被声明为枚举,并且能够将其声明为const数组会很好,这样如果我将来添加更多的操作码,编译器可以提醒我更新数组。
由于方法指针存储运行时状态,( Self
引用它运行的对象,)我无法创建方法指针的const数组。 (无论如何这也不是一个好主意,因为很可能我最终会同时运行多个脚本。)但方法只是语法糖。就像是:
procedure TMyObject.DoSomething(x, y: integer);
真正意思:
procedure TMyObject_DoSomething(Self: TMyObject; x, y: integer);
所以我应该能够以后一种形式声明一个函数指针类型并以那种方式分配它,然后我只需要显式传递 Self
作为我调用它时的第一个参数。但编译器并不喜欢这样。
type TOpcodeProc = procedure (Self: TScriptVM; Opcode: TOpcode);
const OPCODE: TOpcodeProc = TScriptVM.DoOp1;
[DCC Error]: E2009 Incompatible types: 'regular procedure and method pointer'
我已经尝试了不同的变体来尝试让它编译,但它们都会给出错误。有没有办法让这个编译?