From f04f127680fff6f1a04e26f776d1f7d0ec87ece8 Mon Sep 17 00:00:00 2001 From: Bojidar Marinov Date: Tue, 9 Apr 2019 22:21:20 +0300 Subject: [PATCH] Fix `as` operator generating opcode 38 errors Closes #27489 Fixup of 466a76ac2c7c6634ed1d78fde4ac011e2e70b710 Additionally, update `GDScriptCompiler` test to use Ref and to include `as` expressions. --- main/tests/test_gdscript.cpp | 24 +++++++++++++++++++----- modules/gdscript/gdscript_compiler.cpp | 23 ++++++++++++++++++----- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/main/tests/test_gdscript.cpp b/main/tests/test_gdscript.cpp index 8c60b792003..87bd6400018 100644 --- a/main/tests/test_gdscript.cpp +++ b/main/tests/test_gdscript.cpp @@ -288,6 +288,11 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) { } } + } break; + case GDScriptParser::Node::TYPE_CAST: { + const GDScriptParser::CastNode *cast_node = static_cast(p_expr); + txt = _parser_expr(cast_node->source_node) + " as " + cast_node->cast_type.to_string(); + } break; case GDScriptParser::Node::TYPE_NEWLINE: { @@ -668,6 +673,17 @@ static void _disassemble_class(const Ref &p_class, const Vector gds; + gds.instance(); GDScriptCompiler gdc; - err = gdc.compile(&parser, script); + err = gdc.compile(&parser, gds.ptr()); if (err) { print_line("Compile Error:\n" + itos(gdc.get_error_line()) + ":" + itos(gdc.get_error_column()) + ":" + gdc.get_error()); - memdelete(script); return NULL; } - Ref gds = Ref(script); - Ref current = gds; while (current.is_valid()) { diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index ae67521749a..f7be0ce37c3 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -480,16 +480,16 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: switch (cast_type.kind) { case GDScriptDataType::BUILTIN: { codegen.opcodes.push_back(GDScriptFunction::OPCODE_CAST_TO_BUILTIN); - codegen.opcodes.push_back(cn->cast_type.builtin_type); + codegen.opcodes.push_back(cast_type.builtin_type); } break; case GDScriptDataType::NATIVE: { int class_idx; - if (GDScriptLanguage::get_singleton()->get_global_map().has(cn->cast_type.native_type)) { + if (GDScriptLanguage::get_singleton()->get_global_map().has(cast_type.native_type)) { - class_idx = GDScriptLanguage::get_singleton()->get_global_map()[cn->cast_type.native_type]; + class_idx = GDScriptLanguage::get_singleton()->get_global_map()[cast_type.native_type]; class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root) } else { - _set_error("Invalid native class type '" + String(cn->cast_type.native_type) + "'.", cn); + _set_error("Invalid native class type '" + String(cast_type.native_type) + "'.", cn); return -1; } codegen.opcodes.push_back(GDScriptFunction::OPCODE_CAST_TO_NATIVE); // perform operator @@ -498,7 +498,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: case GDScriptDataType::SCRIPT: case GDScriptDataType::GDSCRIPT: { - Variant script = cn->cast_type.script_type; + Variant script = cast_type.script_type; int idx = codegen.get_constant_pos(script); idx |= GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS; //make it a local constant (faster access) @@ -1863,6 +1863,19 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar p_script->base = base; p_script->_base = base.ptr(); p_script->member_indices = base->member_indices; + + if (p_class->base_type.kind == GDScriptParser::DataType::CLASS) { + if (!parsed_classes.has(p_script->_base)) { + if (parsing_classes.has(p_script->_base)) { + _set_error("Cyclic class reference for '" + String(p_class->name) + "'.", p_class); + return ERR_PARSE_ERROR; + } + Error err = _parse_class_level(p_script->_base, p_class->base_type.class_type, p_keep_state); + if (err) { + return err; + } + } + } } break; default: { _set_error("Parser bug: invalid inheritance.", p_class);