Memory management
 

fbc尝试尽可能避免内存赋值,因为它们通常很慢。在list.bas中实现的链表包含一个内置内存池,所以每个列表都是汇集的。内存池预赋值大块,然后可以快速发出许多小节点。这些列表用于简单的事情,例如链接到可执行文件的库列表,也可以用于较重的东西,如AST节点。内存池应该加快速度(不知道如果这是经过验证的)。

在许多地方,编译器只是使用全局/静态变量,例如固定长度的字符串,以避免内存赋值。令牌是一个很好的例子:lex.bas将输入的字符解析成令牌,并将令牌文本存储在静态缓冲区中。令牌文本,可以是:变量名,字符串文字等。所有令牌都存储在这里,所以预处理器可以正确地记录宏。现在考虑到解析器必须处理的巨大的令牌数量:例如,FB当前的Windows头文件导致约100k个令牌。动态赋值每个令牌的缓冲区将很快变得无效。

当然,令牌长度受限于使用静态缓冲区,但是fbc的默认值为1024字节应该足够让所有人使用。类似的长度限制适用于编译器中的许多事情,因为使用固定长度的缓冲区。在大多数情况下,编译器中的缓冲区不会用于其全部潜力,即他们比他们需要的要大。

所有这些并不意味着编译器根本不使用动态内存赋值。在赋值比使用列表/池更容易的情况下,速度并不重要。FB的内置字符串类型也在许多地方使用。只要字符串被赋值,它们是非常有效的。在预处理器中扩展宏参数字符串使用基于字符串的strReplace(),它很快(足够)。除此之外,与字符串基本相同的动态字符串在预处理器中都可以从宏记录到宏扩展。

内存不足的情况/赋值失败并没有得到认真的处理。在调用allocate()的某些地方有NULL检查,但这些检查是无意义的,因为fbc的其余部分不检查NULL。NULL有时用于指示错误,例如某些astNew *()函数。此外,编译器不会释放()一切,而是让操作系统进行清理。