| 2701 | } |
| 2702 | |
| 2703 | Error GDScriptCompiler::_prepare_compilation(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { |
| 2704 | if (parsed_classes.has(p_script)) { |
| 2705 | return OK; |
| 2706 | } |
| 2707 | |
| 2708 | if (parsing_classes.has(p_script)) { |
| 2709 | String class_name = p_class->identifier ? String(p_class->identifier->name) : p_class->fqcn; |
| 2710 | _set_error(vformat(R"(Cyclic class reference for "%s".)", class_name), p_class); |
| 2711 | return ERR_PARSE_ERROR; |
| 2712 | } |
| 2713 | |
| 2714 | parsing_classes.insert(p_script); |
| 2715 | |
| 2716 | p_script->clearing = true; |
| 2717 | |
| 2718 | p_script->cancel_pending_functions(true); |
| 2719 | |
| 2720 | p_script->native = Ref<GDScriptNativeClass>(); |
| 2721 | p_script->base = Ref<GDScript>(); |
| 2722 | p_script->_base = nullptr; |
| 2723 | p_script->members.clear(); |
| 2724 | |
| 2725 | // This makes possible to clear script constants and member_functions without heap-use-after-free errors. |
| 2726 | HashMap<StringName, Variant> constants; |
| 2727 | for (const KeyValue<StringName, Variant> &E : p_script->constants) { |
| 2728 | constants.insert(E.key, E.value); |
| 2729 | } |
| 2730 | p_script->constants.clear(); |
| 2731 | constants.clear(); |
| 2732 | HashMap<StringName, GDScriptFunction *> member_functions; |
| 2733 | for (const KeyValue<StringName, GDScriptFunction *> &E : p_script->member_functions) { |
| 2734 | member_functions.insert(E.key, E.value); |
| 2735 | } |
| 2736 | p_script->member_functions.clear(); |
| 2737 | for (const KeyValue<StringName, GDScriptFunction *> &E : member_functions) { |
| 2738 | memdelete(E.value); |
| 2739 | } |
| 2740 | member_functions.clear(); |
| 2741 | |
| 2742 | p_script->static_variables.clear(); |
| 2743 | |
| 2744 | if (p_script->implicit_initializer) { |
| 2745 | memdelete(p_script->implicit_initializer); |
| 2746 | } |
| 2747 | if (p_script->implicit_ready) { |
| 2748 | memdelete(p_script->implicit_ready); |
| 2749 | } |
| 2750 | if (p_script->static_initializer) { |
| 2751 | memdelete(p_script->static_initializer); |
| 2752 | } |
| 2753 | |
| 2754 | p_script->member_functions.clear(); |
| 2755 | p_script->member_indices.clear(); |
| 2756 | p_script->static_variables_indices.clear(); |
| 2757 | p_script->static_variables.clear(); |
| 2758 | p_script->_signals.clear(); |
| 2759 | p_script->initializer = nullptr; |
| 2760 | p_script->implicit_initializer = nullptr; |
nothing calls this directly
no test coverage detected