.. contexts: ******* Context ******* .. index:: single: contexts Daslang 环境被组织到上下文中。编译 Daslang 程序会生成 'Program' 对象,然后可以将其模拟到 'Context' 中。 `Context` 包括 * 名称和标志 * 函数代码 * 全局变量数据 * 共享全局变量数据 * 堆栈 * 动态内存堆 * 动态字符串堆 * 常量字符串堆 * 运行时调试信息 * 锁 * 其他查找基础设施 从某种意义上说, `Context`可以被视为 Daslang 虚拟机。它是负责执行代码并保持状态的对象。 它也可以被视为类的实例,当标记为 [export] 时可以访问这些方法。 函数代码、常量字符串堆、运行时调试信息和共享的全局变量在克隆的上下文之间共享。 这允许为 context 实例保留相对较小的配置文件。 可以选择在不同类型的多个上下文之间共享堆栈,以保持内存配置文件更小。 =========================== 初始化和关闭 =========================== 在其生命周期中, `Context` 会经历初始化和关闭。 上下文初始化在 `Context::runInitScript` 中实现,关闭在 `Context::runShutdownScript` 中实现。 这些函数在创建、克隆和销毁 `Context` 时自动调用。 根据用户应用程序和 `CodeOfPolicies`,它们也可能在调用 `Context::restart` 或 `Context::restartHeaps` 时被调用。 它按以下顺序初始化。 1. 所有全局变量都按照每个模块的声明顺序进行初始化。 2. 所有标记为 [init] 的函数都按照每个模块声明的顺序调用,特别排序的函数除外。 3. 所有标记为 [init] 的特别排序的函数都按照它们在拓扑排序之后出现的顺序被调用。 init 函数的拓扑排序顺序在 init 注释中指定。 * `tag` 属性指定函数将在指定传递期间出现 * `before` 属性指定函数将出现在指定通道之前 * `after` 属性指定函数将出现在指定通道之后 请考虑以下示例:: [init(before="middle")] def a { order |> push("a") } [init(tag="middle")] def b { order |> push("b") } [init(tag="middle")] def c { order |> push("c") } [init(after="middle")] def d { order |> push("d") } 函数将按 1. d 2. b 或 c, 任意顺序 3. a Context关闭时按照每个模块声明的顺序运行所有标记为 [finalize] 的函数。 ============== 宏Context ============== 对于每个包含宏的模块,将创建并初始化单独的Context。 除了常规函数之外,在初始化期间还会调用标记为 [macro] 或 [_macro] 的函数。 标记为 [macro_function] 的函数将从常规Context中排除,并且仅显示在宏Context中。 除非宏模块被标记为共享,否则编译完成后会关闭。 共享宏模块在第一次编译期间初始化,并在环境关闭期间关闭。 ======= 锁 ======= Context 包含 `recursive_mutex`,并且可以使用 `lock_context` 或 `lock_this_context` RAII 块进行专门锁定和解锁。 跨上下文调用 `invoke_in_context` 会自动锁定目标Context。 ======= 查找 ======= 全局变量和函数可以在 Daslang 和 C++ 端按名称或损坏的名称哈希进行查找。 ======================================== 内存分配和垃圾回收 ======================================== 字符串堆和常规堆的内存分配策略都在 `CodeOfPolicies` 中指定,以及选项。 要允许从上下文内部进行垃圾回收,以下选项是必需的:: options persistent_heap // 此 API 支持垃圾回收堆 options gc // 此 API 为堆栈上的变量启用垃圾回收 要从上下文内部收集垃圾:: var collect_string_heap = true var validate_after_collect = false heap_collect(collect_string_heap, validate_after_collect) 从 C++ 端执行相同的作:: context->collectHeap(dummy_line_info_ptr, collect_string_heap, validate_after_collect);