|
@@ -520,10 +520,12 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|
case GDScriptParser::Node::CALL: {
|
|
case GDScriptParser::Node::CALL: {
|
|
const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_expression);
|
|
const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_expression);
|
|
GDScriptDataType type = _gdtype_from_datatype(call->get_datatype(), codegen.script);
|
|
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;
|
|
Vector<GDScriptCodeGenerator::Address> arguments;
|
|
for (int i = 0; i < call->arguments.size(); i++) {
|
|
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.
|
|
// Construct a built-in type.
|
|
Variant::Type vtype = GDScriptParser::get_builtin_type(static_cast<GDScriptParser::IdentifierNode *>(call->callee)->name);
|
|
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)) {
|
|
} else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && Variant::has_utility_function(call->function_name)) {
|
|
// Variant utility function.
|
|
// 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)) {
|
|
} else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptUtilityFunctions::function_exists(call->function_name)) {
|
|
// GDScript utility function.
|
|
// 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 {
|
|
} else {
|
|
// Regular function.
|
|
// Regular function.
|
|
const GDScriptParser::ExpressionNode *callee = call->callee;
|
|
const GDScriptParser::ExpressionNode *callee = call->callee;
|
|
|
|
|
|
if (call->is_super) {
|
|
if (call->is_super) {
|
|
// Super call.
|
|
// Super call.
|
|
- gen->write_super_call(return_addr, call->function_name, arguments);
|
|
|
|
|
|
+ gen->write_super_call(result, call->function_name, arguments);
|
|
} else {
|
|
} else {
|
|
if (callee->type == GDScriptParser::Node::IDENTIFIER) {
|
|
if (callee->type == GDScriptParser::Node::IDENTIFIER) {
|
|
// Self function call.
|
|
// Self function call.
|
|
@@ -563,24 +565,24 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|
|
|
|
|
if (_have_exact_arguments(method, arguments)) {
|
|
if (_have_exact_arguments(method, arguments)) {
|
|
// Exact arguments, use ptrcall.
|
|
// Exact arguments, use ptrcall.
|
|
- gen->write_call_ptrcall(return_addr, self, method, arguments);
|
|
|
|
|
|
+ gen->write_call_ptrcall(result, self, method, arguments);
|
|
} else {
|
|
} else {
|
|
// Not exact arguments, but still can use method bind call.
|
|
// 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") {
|
|
} else if ((codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") {
|
|
GDScriptCodeGenerator::Address self;
|
|
GDScriptCodeGenerator::Address self;
|
|
self.mode = GDScriptCodeGenerator::Address::CLASS;
|
|
self.mode = GDScriptCodeGenerator::Address::CLASS;
|
|
if (within_await) {
|
|
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 {
|
|
} else {
|
|
- gen->write_call(return_addr, self, call->function_name, arguments);
|
|
|
|
|
|
+ gen->write_call(result, self, call->function_name, arguments);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
if (within_await) {
|
|
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 {
|
|
} 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) {
|
|
} else if (callee->type == GDScriptParser::Node::SUBSCRIPT) {
|
|
@@ -589,18 +591,18 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|
if (subscript->is_attribute) {
|
|
if (subscript->is_attribute) {
|
|
// May be static built-in method call.
|
|
// 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) {
|
|
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") &&
|
|
} 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)) {
|
|
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.
|
|
// 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 {
|
|
} else {
|
|
GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, subscript->base);
|
|
GDScriptCodeGenerator::Address base = _parse_expression(codegen, r_error, subscript->base);
|
|
if (r_error) {
|
|
if (r_error) {
|
|
return GDScriptCodeGenerator::Address();
|
|
return GDScriptCodeGenerator::Address();
|
|
}
|
|
}
|
|
if (within_await) {
|
|
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) {
|
|
} else if (base.type.has_type && base.type.kind != GDScriptDataType::BUILTIN) {
|
|
// Native method, use faster path.
|
|
// Native method, use faster path.
|
|
StringName class_name;
|
|
StringName class_name;
|
|
@@ -613,18 +615,18 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|
MethodBind *method = ClassDB::get_method(class_name, call->function_name);
|
|
MethodBind *method = ClassDB::get_method(class_name, call->function_name);
|
|
if (_have_exact_arguments(method, arguments)) {
|
|
if (_have_exact_arguments(method, arguments)) {
|
|
// Exact arguments, use ptrcall.
|
|
// Exact arguments, use ptrcall.
|
|
- gen->write_call_ptrcall(return_addr, base, method, arguments);
|
|
|
|
|
|
+ gen->write_call_ptrcall(result, base, method, arguments);
|
|
} else {
|
|
} else {
|
|
// Not exact arguments, but still can use method bind call.
|
|
// 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 {
|
|
} 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) {
|
|
} 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 {
|
|
} 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) {
|
|
if (base.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
|
|
gen->pop_temporary();
|
|
gen->pop_temporary();
|