summaryrefslogtreecommitdiff
path: root/modules/gdscript/gdscript_compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/gdscript_compiler.cpp')
-rw-r--r--modules/gdscript/gdscript_compiler.cpp50
1 files changed, 26 insertions, 24 deletions
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 2d36692c3c..77c6690d20 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -213,7 +213,7 @@ static bool _have_exact_arguments(const MethodBind *p_method, const Vector<GDScr
}
GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &codegen, Error &r_error, const GDScriptParser::ExpressionNode *p_expression, bool p_root, bool p_initializer, const GDScriptCodeGenerator::Address &p_index_addr) {
- if (p_expression->is_constant) {
+ if (p_expression->is_constant && !p_expression->get_datatype().is_meta_type) {
return codegen.add_constant(p_expression->reduced_value);
}
@@ -520,10 +520,12 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
case GDScriptParser::Node::CALL: {
const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_expression);
GDScriptDataType type = _gdtype_from_datatype(call->get_datatype(), codegen.script);
- GDScriptCodeGenerator::Address result = codegen.add_temporary(type);
- GDScriptCodeGenerator::Address nil = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::NIL);
-
- GDScriptCodeGenerator::Address return_addr = p_root ? nil : result;
+ GDScriptCodeGenerator::Address result;
+ if (p_root) {
+ result = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::NIL);
+ } else {
+ result = codegen.add_temporary(type);
+ }
Vector<GDScriptCodeGenerator::Address> arguments;
for (int i = 0; i < call->arguments.size(); i++) {
@@ -538,20 +540,20 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
// Construct a built-in type.
Variant::Type vtype = GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name);
- gen->write_construct(return_addr, vtype, arguments);
+ gen->write_construct(result, vtype, arguments);
} else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && Variant::has_utility_function(call->function_name)) {
// Variant utility function.
- gen->write_call_utility(return_addr, call->function_name, arguments);
+ gen->write_call_utility(result, call->function_name, arguments);
} else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptUtilityFunctions::function_exists(call->function_name)) {
// GDScript utility function.
- gen->write_call_gdscript_utility(return_addr, GDScriptUtilityFunctions::get_function(call->function_name), arguments);
+ gen->write_call_gdscript_utility(result, GDScriptUtilityFunctions::get_function(call->function_name), arguments);
} else {
// Regular function.
const GDScriptParser::ExpressionNode *callee = call->callee;
if (call->is_super) {
// Super call.
- gen->write_super_call(return_addr, call->function_name, arguments);
+ gen->write_super_call(result, call->function_name, arguments);
} else {
if (callee->type == GDScriptParser::Node::IDENTIFIER) {
// Self function call.
@@ -563,24 +565,24 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
if (_have_exact_arguments(method, arguments)) {
// Exact arguments, use ptrcall.
- gen->write_call_ptrcall(return_addr, self, method, arguments);
+ gen->write_call_ptrcall(result, self, method, arguments);
} else {
// Not exact arguments, but still can use method bind call.
- gen->write_call_method_bind(return_addr, self, method, arguments);
+ gen->write_call_method_bind(result, self, method, arguments);
}
} else if ((codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") {
GDScriptCodeGenerator::Address self;
self.mode = GDScriptCodeGenerator::Address::CLASS;
if (within_await) {
- gen->write_call_async(return_addr, self, call->function_name, arguments);
+ gen->write_call_async(result, self, call->function_name, arguments);
} else {
- gen->write_call(return_addr, self, call->function_name, arguments);
+ gen->write_call(result, self, call->function_name, arguments);
}
} else {
if (within_await) {
- gen->write_call_self_async(return_addr, call->function_name, arguments);
+ gen->write_call_self_async(result, call->function_name, arguments);
} else {
- gen->write_call_self(return_addr, call->function_name, arguments);
+ gen->write_call_self(result, call->function_name, arguments);
}
}
} else if (callee->type == GDScriptParser::Node::SUBSCRIPT) {
@@ -589,18 +591,18 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
if (subscript->is_attribute) {
// May be static built-in method call.
if (!call->is_super && subscript->base->type == GDScriptParser::Node::IDENTIFIER && GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name) < Variant::VARIANT_MAX) {
- gen->write_call_builtin_type_static(return_addr, GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name), subscript->attribute->name, arguments);
+ gen->write_call_builtin_type_static(result, GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name), subscript->attribute->name, arguments);
} else if (!call->is_super && subscript->base->type == GDScriptParser::Node::IDENTIFIER && call->function_name != SNAME("new") &&
ClassDB::class_exists(static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name) && !Engine::get_singleton()->has_singleton(static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name)) {
// It's a static native method call.
- gen->write_call_native_static(return_addr, static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name, subscript->attribute->name, arguments);
+ gen->write_call_native_static(result, static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name, subscript->attribute->name, arguments);
} else {
GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, subscript->base);
if (r_error) {
return GDScriptCodeGenerator::Address();
}
if (within_await) {
- gen->write_call_async(return_addr, base, call->function_name, arguments);
+ gen->write_call_async(result, base, call->function_name, arguments);
} else if (base.type.has_type && base.type.kind != GDScriptDataType::BUILTIN) {
// Native method, use faster path.
StringName class_name;
@@ -613,18 +615,18 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
MethodBind *method = ClassDB::get_method(class_name, call->function_name);
if (_have_exact_arguments(method, arguments)) {
// Exact arguments, use ptrcall.
- gen->write_call_ptrcall(return_addr, base, method, arguments);
+ gen->write_call_ptrcall(result, base, method, arguments);
} else {
// Not exact arguments, but still can use method bind call.
- gen->write_call_method_bind(return_addr, base, method, arguments);
+ gen->write_call_method_bind(result, base, method, arguments);
}
} else {
- gen->write_call(return_addr, base, call->function_name, arguments);
+ gen->write_call(result, base, call->function_name, arguments);
}
} else if (base.type.has_type && base.type.kind == GDScriptDataType::BUILTIN) {
- gen->write_call_builtin_type(return_addr, base, base.type.builtin_type, call->function_name, arguments);
+ gen->write_call_builtin_type(result, base, base.type.builtin_type, call->function_name, arguments);
} else {
- gen->write_call(return_addr, base, call->function_name, arguments);
+ gen->write_call(result, base, call->function_name, arguments);
}
if (base.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
gen->pop_temporary();
@@ -2114,7 +2116,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
}
}
- codegen.generator->write_assign_default_parameter(dst_addr, src_addr);
+ codegen.generator->write_assign_default_parameter(dst_addr, src_addr, parameter->use_conversion_assign);
if (src_addr.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
codegen.generator->pop_temporary();
}