内置脚本语言,实现在 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)。
各阶段
| 阶段 | 文件 | 要点 |
|---|---|---|
| Lexer | gdscript_tokenizer.h/cpp | Token 约 100 种类型(含 INDENT/DEDENT/NEWLINE);GDScriptTokenizerText 手写扫描,indent_stack/paren_stack 处理缩进敏感;另有 GDScriptTokenizerBuffer 读预编译二进制(TOKENIZER_VERSION=101) |
| Parser | gdscript_parser.h/cpp(1760/6486 行) | 递归下降,约 40 种 AST 节点(ClassNode/FunctionNode/MatchNode/LambdaNode…);DataType 带 Kind(BUILTIN/NATIVE/SCRIPT/CLASS/ENUM/VARIANT…)与 TypeSource(UNDETECTED/INFERRED/ANNOTATED_EXPLICIT…) |
| Analyzer | gdscript_analyzer.h/cpp(6732 行,最大单文件) | 静态类型检查:resolve_inheritance/interface/body/dependencies;reduce_* 系列做表达式归约与常量折叠;is_type_compatible |
| Compiler | gdscript_compiler.h/cpp | 遍历 AST,经 CodeGen(管参数/局部变量/Address)调 gdscript_byte_codegen 生成 GDScriptFunction;含 lambda 热重载替换(FunctionLambdaInfo) |
| VM | gdscript_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-modelGDScriptLanguage : ScriptLanguage(:400):单例,实现语言接口(validate/reload_all_scripts/profiling/debug 栈CallLevel链表)
编辑器集成
modules/gdscript/editor/:高亮(gdscript_highlighter)、文档生成(gdscript_docgen)、翻译解析、language_server/ 内置 LSP 实现(gdscript_language_protocol)。