内置脚本语言,实现在 modules/gdscript/,经 ScriptLanguage 插件接口接入(ScriptServer::register_language,register_types.cpp:144)。编译管线:

源码 → Lexer(tokenizer)→ Parser(AST)→ Analyzer(类型检查)→ Compiler(字节码)→ VM 执行

入口 GDScript::reload()(gdscript.cpp:746),依次调 GDScriptParser::parse(:823)→ GDScriptAnalyzer(:838)→ GDScriptCompiler::compile(:857)。

各阶段

阶段文件要点
Lexergdscript_tokenizer.h/cppToken 约 100 种类型(含 INDENT/DEDENT/NEWLINE);GDScriptTokenizerText 手写扫描,indent_stack/paren_stack 处理缩进敏感;另有 GDScriptTokenizerBuffer 读预编译二进制(TOKENIZER_VERSION=101)
Parsergdscript_parser.h/cpp(1760/6486 行)递归下降,约 40 种 AST 节点(ClassNode/FunctionNode/MatchNode/LambdaNode…);DataType 带 Kind(BUILTIN/NATIVE/SCRIPT/CLASS/ENUM/VARIANT…)与 TypeSource(UNDETECTED/INFERRED/ANNOTATED_EXPLICIT…)
Analyzergdscript_analyzer.h/cpp(6732 行,最大单文件)静态类型检查:resolve_inheritance/interface/body/dependencies;reduce_* 系列做表达式归约与常量折叠;is_type_compatible
Compilergdscript_compiler.h/cpp遍历 AST,经 CodeGen(管参数/局部变量/Address)调 gdscript_byte_codegen 生成 GDScriptFunction;含 lambda 热重载替换(FunctionLambdaInfo)
VMgdscript_vm.cpp(4037 行)GDScriptFunction::call()(:499);computed-goto 分派(goto *switch_table_ops[...],:425-432);DEBUG 下 CHECK_SPACE 防栈溢出

字节码与运行时

GDScriptFunction(gdscript_function.h):

  • 158 条 opcode(:152-311),含大量 OPCODE_TYPE_ADJUST_*(类型特化快速路径)与 ITERATE_* 变体
  • Address 编码:24 位偏移 + 寻址模式(STACK/CONSTANT/MEMBER,:313-321)
  • 持有 Vector<int> code、constants 池、methods(MethodBind 指针)、预验证的 Validated* 函数指针数组(跳过 Variant 装箱,呼应 variant 的调用分档)
  • CallState(:462)支撑 await 协程挂起;MAX_CALL_DEPTH=2048

类结构

gdscript.h(649 行):

  • GDScript : public Script(:57):持 native(对应原生类)、base、members/constants/member_functions(StringName→GDScriptFunction*)、subclasses(内部类)
  • GDScriptInstance : ScriptInstance(:337):挂到 Object::script_instance,见 object-model
  • GDScriptLanguage : ScriptLanguage(:400):单例,实现语言接口(validate/reload_all_scripts/profiling/debug 栈 CallLevel 链表)

编辑器集成

modules/gdscript/editor/:高亮(gdscript_highlighter)、文档生成(gdscript_docgen)、翻译解析、language_server/ 内置 LSP 实现(gdscript_language_protocol)。

相关