| 1401 | } |
| 1402 | |
| 1403 | void GDScriptByteCodeGenerator::write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) { |
| 1404 | // Try to find an appropriate constructor. |
| 1405 | bool all_have_type = true; |
| 1406 | Vector<Variant::Type> arg_types; |
| 1407 | for (int i = 0; i < p_arguments.size(); i++) { |
| 1408 | if (!HAS_BUILTIN_TYPE(p_arguments[i])) { |
| 1409 | all_have_type = false; |
| 1410 | break; |
| 1411 | } |
| 1412 | arg_types.push_back(p_arguments[i].type.builtin_type); |
| 1413 | } |
| 1414 | if (all_have_type) { |
| 1415 | int valid_constructor = -1; |
| 1416 | for (int i = 0; i < Variant::get_constructor_count(p_type); i++) { |
| 1417 | if (Variant::get_constructor_argument_count(p_type, i) != p_arguments.size()) { |
| 1418 | continue; |
| 1419 | } |
| 1420 | int types_correct = true; |
| 1421 | for (int j = 0; j < arg_types.size(); j++) { |
| 1422 | if (arg_types[j] != Variant::get_constructor_argument_type(p_type, i, j)) { |
| 1423 | types_correct = false; |
| 1424 | break; |
| 1425 | } |
| 1426 | } |
| 1427 | if (types_correct) { |
| 1428 | valid_constructor = i; |
| 1429 | break; |
| 1430 | } |
| 1431 | } |
| 1432 | if (valid_constructor >= 0) { |
| 1433 | append_opcode_and_argcount(GDScriptFunction::OPCODE_CONSTRUCT_VALIDATED, 1 + p_arguments.size()); |
| 1434 | for (int i = 0; i < p_arguments.size(); i++) { |
| 1435 | append(p_arguments[i]); |
| 1436 | } |
| 1437 | CallTarget ct = get_call_target(p_target); |
| 1438 | append(ct.target); |
| 1439 | append(p_arguments.size()); |
| 1440 | append(Variant::get_validated_constructor(p_type, valid_constructor)); |
| 1441 | ct.cleanup(); |
| 1442 | #ifdef DEBUG_ENABLED |
| 1443 | add_debug_name(constructors_names, get_constructor_pos(Variant::get_validated_constructor(p_type, valid_constructor)), Variant::get_type_name(p_type)); |
| 1444 | #endif |
| 1445 | return; |
| 1446 | } |
| 1447 | } |
| 1448 | |
| 1449 | append_opcode_and_argcount(GDScriptFunction::OPCODE_CONSTRUCT, 1 + p_arguments.size()); |
| 1450 | for (int i = 0; i < p_arguments.size(); i++) { |
| 1451 | append(p_arguments[i]); |
| 1452 | } |
| 1453 | CallTarget ct = get_call_target(p_target); |
| 1454 | append(ct.target); |
| 1455 | append(p_arguments.size()); |
| 1456 | append(p_type); |
| 1457 | ct.cleanup(); |
| 1458 | } |
| 1459 | |
| 1460 | void GDScriptByteCodeGenerator::write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) { |
no test coverage detected