随笔-341  评论-2670  文章-0  trackbacks-0
    今天终于让脚本引擎可以成功执行int main(){return 1+1;}了,总算是让冒烟测试过了。一开始没那么顺利,主要是因为昨天写了一整天代码,犯了点错误。

    举个例子,脚本里面有return语句,这个语句实际上是对应到一个jump指令去,跳到函数最后面执行一些代码然后返回。当代码生成执行到return的时候,实际上函数还没生成完,所以不知道jump到什么地方。因此我想到一个办法,我先把这些需要延迟填充的指令都记下来,当函数结束的时候一次性填充它们。于是我使用了下面的代码:
1 needToReturns.Add(&ins[ins.Count()-1]);

    这样做我就把刚刚加入的那条jump指令,也就是当前的最后一条指令的指针添加到一个列表里面去了。于是我接着处理很多代码生成的工作,也免不了往needToReturns添加很多的其他jump指令。于是到了最后填充它们的时候了,没有问题发生。代码生成结束之后,我就要把再也不需要的符号表给析构掉,这个时候VC就报告说释放一个TypeInfo的时候完蛋了。

    其实很明显,错误肯定不会出现在TypeInfo里面的,想都不用想肯定是哪里溢出了。但是自己的容器的operator[]都有溢出检查的,不可能通过a[b]=c;的方法导致内存出现错误。最后想来想去,发现问题出在上面那一行代码里。

    我们都知道,一个列表在Add的时候,他所拥有的缓冲区肯定最终都会用光,然后分配一个更大的。于是之前的&ins[x]跟之后的&ins[x]的地址肯定不一样,于是我添加到needToReturns里面的引用就变成一个野引用了。搞定一个函数之后,我一下子填充它们,也就等于往各种各样不同的野引用里面写东西。刚好之后创建的一个符号表项就是某一个野引用指向的地方,于是内容就被我破坏了,释放它的时候当然就出现问题了。

    这个故事告诉我们
1:永远不要试图获取容器中某一个项的引用。
2:就算是自己的类,有时候也会误用的。

    关于我如何执行int main(){return 1+1;},可以在Vczh Library++3.0的单元测试代码(UnitTest\UnitTest\TestScripting_BasicLanguage_CodeGeneration.cpp)里面找到。
posted on 2010-02-26 19:41 陈梓瀚(vczh) 阅读(2404) 评论(6)  编辑 收藏 引用 所属分类: VL++3.0开发纪事

评论:
# re: Vczh Library++3.0开发纪事之[使用自己写的类偶尔也会误用的][未登录] 2010-02-26 20:07 | ccsdu2009
你弄得这个脚本引擎最大优点是什么?
好的话我可以拿去作为引擎备用脚本引擎  回复  更多评论
  
# re: Vczh Library++3.0开发纪事之[使用自己写的类偶尔也会误用的] 2010-02-26 20:09 | 空明流转
@ccsdu2009
它最大的有点就是你要是用的不爽了可以用中文开喷。。。  回复  更多评论
  
# re: Vczh Library++3.0开发纪事之[使用自己写的类偶尔也会误用的] 2010-02-26 20:21 | 陈梓瀚(vczh)
@ccsdu2009
还没写完呢……目标有三

1:预定义了一票语言(本地,托管,动态等)
2:在上面开发新语言就跟喝白开水一样
3:N种语言可以被无缝编译在一起

全部做完估计要很长的时间  回复  更多评论
  
# re: Vczh Library++3.0开发纪事之[使用自己写的类偶尔也会误用的] 2010-02-26 20:23 | 陈梓瀚(vczh)
@空明流转
最大的优点是用中文喷了之后我还看得懂……  回复  更多评论
  
# re: Vczh Library++3.0开发纪事之[使用自己写的类偶尔也会误用的] 2010-02-27 21:34 | 唐风
@陈梓瀚(vczh)
陈版 .net ?
哈哈~~~~  回复  更多评论
  
# re: Vczh Library++3.0开发纪事之[使用自己写的类偶尔也会误用的] 2010-02-27 22:55 | junglevass
都是膜拜的对象。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理