You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-15 13:51:40 +00:00
Merge pull request #91192 from vnen/gdscript-validated-native-static-calls
GDScript: Perform validated calls with static methods
This commit is contained in:
@@ -1196,23 +1196,49 @@ void GDScriptByteCodeGenerator::write_call_builtin_type_static(const Address &p_
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GDScriptByteCodeGenerator::write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector<Address> &p_arguments) {
|
void GDScriptByteCodeGenerator::write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector<Address> &p_arguments) {
|
||||||
bool is_validated = false;
|
|
||||||
|
|
||||||
MethodBind *method = ClassDB::get_method(p_class, p_method);
|
MethodBind *method = ClassDB::get_method(p_class, p_method);
|
||||||
|
|
||||||
if (!is_validated) {
|
// Perform regular call.
|
||||||
// Perform regular call.
|
append_opcode_and_argcount(GDScriptFunction::OPCODE_CALL_NATIVE_STATIC, p_arguments.size() + 1);
|
||||||
append_opcode_and_argcount(GDScriptFunction::OPCODE_CALL_NATIVE_STATIC, p_arguments.size() + 1);
|
for (int i = 0; i < p_arguments.size(); i++) {
|
||||||
for (int i = 0; i < p_arguments.size(); i++) {
|
append(p_arguments[i]);
|
||||||
append(p_arguments[i]);
|
|
||||||
}
|
|
||||||
CallTarget ct = get_call_target(p_target);
|
|
||||||
append(ct.target);
|
|
||||||
append(method);
|
|
||||||
append(p_arguments.size());
|
|
||||||
ct.cleanup();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
CallTarget ct = get_call_target(p_target);
|
||||||
|
append(ct.target);
|
||||||
|
append(method);
|
||||||
|
append(p_arguments.size());
|
||||||
|
ct.cleanup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDScriptByteCodeGenerator::write_call_native_static_validated(const GDScriptCodeGenerator::Address &p_target, MethodBind *p_method, const Vector<GDScriptCodeGenerator::Address> &p_arguments) {
|
||||||
|
Variant::Type return_type = Variant::NIL;
|
||||||
|
bool has_return = p_method->has_return();
|
||||||
|
|
||||||
|
if (has_return) {
|
||||||
|
PropertyInfo return_info = p_method->get_return_info();
|
||||||
|
return_type = return_info.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
CallTarget ct = get_call_target(p_target, return_type);
|
||||||
|
|
||||||
|
if (has_return) {
|
||||||
|
Variant::Type temp_type = temporaries[ct.target.address].type;
|
||||||
|
if (temp_type != return_type) {
|
||||||
|
write_type_adjust(ct.target, return_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GDScriptFunction::Opcode code = p_method->has_return() ? GDScriptFunction::OPCODE_CALL_NATIVE_STATIC_VALIDATED_RETURN : GDScriptFunction::OPCODE_CALL_NATIVE_STATIC_VALIDATED_NO_RETURN;
|
||||||
|
append_opcode_and_argcount(code, 1 + p_arguments.size());
|
||||||
|
|
||||||
|
for (int i = 0; i < p_arguments.size(); i++) {
|
||||||
|
append(p_arguments[i]);
|
||||||
|
}
|
||||||
|
append(ct.target);
|
||||||
|
append(p_arguments.size());
|
||||||
|
append(p_method);
|
||||||
|
ct.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDScriptByteCodeGenerator::write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) {
|
void GDScriptByteCodeGenerator::write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) {
|
||||||
|
|||||||
@@ -518,6 +518,7 @@ public:
|
|||||||
virtual void write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) override;
|
virtual void write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) override;
|
||||||
virtual void write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) override;
|
virtual void write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) override;
|
||||||
virtual void write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector<Address> &p_arguments) override;
|
virtual void write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector<Address> &p_arguments) override;
|
||||||
|
virtual void write_call_native_static_validated(const Address &p_target, MethodBind *p_method, const Vector<Address> &p_arguments) override;
|
||||||
virtual void write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override;
|
virtual void write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override;
|
||||||
virtual void write_call_method_bind_validated(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override;
|
virtual void write_call_method_bind_validated(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override;
|
||||||
virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
|
virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ public:
|
|||||||
virtual void write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) = 0;
|
virtual void write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) = 0;
|
||||||
virtual void write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) = 0;
|
virtual void write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) = 0;
|
||||||
virtual void write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector<Address> &p_arguments) = 0;
|
virtual void write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector<Address> &p_arguments) = 0;
|
||||||
|
virtual void write_call_native_static_validated(const Address &p_target, MethodBind *p_method, const Vector<Address> &p_arguments) = 0;
|
||||||
virtual void write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0;
|
virtual void write_call_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0;
|
||||||
virtual void write_call_method_bind_validated(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0;
|
virtual void write_call_method_bind_validated(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0;
|
||||||
virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
|
virtual void write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
|
||||||
|
|||||||
@@ -673,7 +673,15 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|||||||
} 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(result, static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name, subscript->attribute->name, arguments);
|
StringName class_name = static_cast<GDScriptParser::IdentifierNode *>(subscript->base)->name;
|
||||||
|
MethodBind *method = ClassDB::get_method(class_name, subscript->attribute->name);
|
||||||
|
if (_can_use_validate_call(method, arguments)) {
|
||||||
|
// Exact arguments, use validated call.
|
||||||
|
gen->write_call_native_static_validated(result, method, arguments);
|
||||||
|
} else {
|
||||||
|
// Not exact arguments, use regular static call
|
||||||
|
gen->write_call_native_static(result, class_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) {
|
||||||
|
|||||||
@@ -678,6 +678,50 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
|||||||
incr += 4 + argc;
|
incr += 4 + argc;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case OPCODE_CALL_NATIVE_STATIC_VALIDATED_RETURN: {
|
||||||
|
int instr_var_args = _code_ptr[++ip];
|
||||||
|
text += "call native static method validated (return) ";
|
||||||
|
MethodBind *method = _methods_ptr[_code_ptr[ip + 2 + instr_var_args]];
|
||||||
|
int argc = _code_ptr[ip + 1 + instr_var_args];
|
||||||
|
text += DADDR(1 + argc) + " = ";
|
||||||
|
text += method->get_instance_class();
|
||||||
|
text += ".";
|
||||||
|
text += method->get_name();
|
||||||
|
text += "(";
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
if (i > 0)
|
||||||
|
text += ", ";
|
||||||
|
text += DADDR(1 + i);
|
||||||
|
}
|
||||||
|
text += ")";
|
||||||
|
incr = 4 + argc;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case OPCODE_CALL_NATIVE_STATIC_VALIDATED_NO_RETURN: {
|
||||||
|
int instr_var_args = _code_ptr[++ip];
|
||||||
|
|
||||||
|
text += "call native static method validated (no return) ";
|
||||||
|
|
||||||
|
MethodBind *method = _methods_ptr[_code_ptr[ip + 2 + instr_var_args]];
|
||||||
|
|
||||||
|
int argc = _code_ptr[ip + 1 + instr_var_args];
|
||||||
|
|
||||||
|
text += method->get_instance_class();
|
||||||
|
text += ".";
|
||||||
|
text += method->get_name();
|
||||||
|
text += "(";
|
||||||
|
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
text += ", ";
|
||||||
|
}
|
||||||
|
text += DADDR(1 + i);
|
||||||
|
}
|
||||||
|
text += ")";
|
||||||
|
|
||||||
|
incr = 4 + argc;
|
||||||
|
} break;
|
||||||
|
|
||||||
case OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN: {
|
case OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN: {
|
||||||
int instr_var_args = _code_ptr[++ip];
|
int instr_var_args = _code_ptr[++ip];
|
||||||
text += "call method-bind validated (return) ";
|
text += "call method-bind validated (return) ";
|
||||||
|
|||||||
@@ -264,6 +264,8 @@ public:
|
|||||||
OPCODE_CALL_METHOD_BIND_RET,
|
OPCODE_CALL_METHOD_BIND_RET,
|
||||||
OPCODE_CALL_BUILTIN_STATIC,
|
OPCODE_CALL_BUILTIN_STATIC,
|
||||||
OPCODE_CALL_NATIVE_STATIC,
|
OPCODE_CALL_NATIVE_STATIC,
|
||||||
|
OPCODE_CALL_NATIVE_STATIC_VALIDATED_RETURN,
|
||||||
|
OPCODE_CALL_NATIVE_STATIC_VALIDATED_NO_RETURN,
|
||||||
OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN,
|
OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN,
|
||||||
OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN,
|
OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN,
|
||||||
OPCODE_AWAIT,
|
OPCODE_AWAIT,
|
||||||
|
|||||||
@@ -211,156 +211,158 @@ void (*type_init_function_table[])(Variant *) = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#define OPCODES_TABLE \
|
#define OPCODES_TABLE \
|
||||||
static const void *switch_table_ops[] = { \
|
static const void *switch_table_ops[] = { \
|
||||||
&&OPCODE_OPERATOR, \
|
&&OPCODE_OPERATOR, \
|
||||||
&&OPCODE_OPERATOR_VALIDATED, \
|
&&OPCODE_OPERATOR_VALIDATED, \
|
||||||
&&OPCODE_TYPE_TEST_BUILTIN, \
|
&&OPCODE_TYPE_TEST_BUILTIN, \
|
||||||
&&OPCODE_TYPE_TEST_ARRAY, \
|
&&OPCODE_TYPE_TEST_ARRAY, \
|
||||||
&&OPCODE_TYPE_TEST_NATIVE, \
|
&&OPCODE_TYPE_TEST_NATIVE, \
|
||||||
&&OPCODE_TYPE_TEST_SCRIPT, \
|
&&OPCODE_TYPE_TEST_SCRIPT, \
|
||||||
&&OPCODE_SET_KEYED, \
|
&&OPCODE_SET_KEYED, \
|
||||||
&&OPCODE_SET_KEYED_VALIDATED, \
|
&&OPCODE_SET_KEYED_VALIDATED, \
|
||||||
&&OPCODE_SET_INDEXED_VALIDATED, \
|
&&OPCODE_SET_INDEXED_VALIDATED, \
|
||||||
&&OPCODE_GET_KEYED, \
|
&&OPCODE_GET_KEYED, \
|
||||||
&&OPCODE_GET_KEYED_VALIDATED, \
|
&&OPCODE_GET_KEYED_VALIDATED, \
|
||||||
&&OPCODE_GET_INDEXED_VALIDATED, \
|
&&OPCODE_GET_INDEXED_VALIDATED, \
|
||||||
&&OPCODE_SET_NAMED, \
|
&&OPCODE_SET_NAMED, \
|
||||||
&&OPCODE_SET_NAMED_VALIDATED, \
|
&&OPCODE_SET_NAMED_VALIDATED, \
|
||||||
&&OPCODE_GET_NAMED, \
|
&&OPCODE_GET_NAMED, \
|
||||||
&&OPCODE_GET_NAMED_VALIDATED, \
|
&&OPCODE_GET_NAMED_VALIDATED, \
|
||||||
&&OPCODE_SET_MEMBER, \
|
&&OPCODE_SET_MEMBER, \
|
||||||
&&OPCODE_GET_MEMBER, \
|
&&OPCODE_GET_MEMBER, \
|
||||||
&&OPCODE_SET_STATIC_VARIABLE, \
|
&&OPCODE_SET_STATIC_VARIABLE, \
|
||||||
&&OPCODE_GET_STATIC_VARIABLE, \
|
&&OPCODE_GET_STATIC_VARIABLE, \
|
||||||
&&OPCODE_ASSIGN, \
|
&&OPCODE_ASSIGN, \
|
||||||
&&OPCODE_ASSIGN_NULL, \
|
&&OPCODE_ASSIGN_NULL, \
|
||||||
&&OPCODE_ASSIGN_TRUE, \
|
&&OPCODE_ASSIGN_TRUE, \
|
||||||
&&OPCODE_ASSIGN_FALSE, \
|
&&OPCODE_ASSIGN_FALSE, \
|
||||||
&&OPCODE_ASSIGN_TYPED_BUILTIN, \
|
&&OPCODE_ASSIGN_TYPED_BUILTIN, \
|
||||||
&&OPCODE_ASSIGN_TYPED_ARRAY, \
|
&&OPCODE_ASSIGN_TYPED_ARRAY, \
|
||||||
&&OPCODE_ASSIGN_TYPED_NATIVE, \
|
&&OPCODE_ASSIGN_TYPED_NATIVE, \
|
||||||
&&OPCODE_ASSIGN_TYPED_SCRIPT, \
|
&&OPCODE_ASSIGN_TYPED_SCRIPT, \
|
||||||
&&OPCODE_CAST_TO_BUILTIN, \
|
&&OPCODE_CAST_TO_BUILTIN, \
|
||||||
&&OPCODE_CAST_TO_NATIVE, \
|
&&OPCODE_CAST_TO_NATIVE, \
|
||||||
&&OPCODE_CAST_TO_SCRIPT, \
|
&&OPCODE_CAST_TO_SCRIPT, \
|
||||||
&&OPCODE_CONSTRUCT, \
|
&&OPCODE_CONSTRUCT, \
|
||||||
&&OPCODE_CONSTRUCT_VALIDATED, \
|
&&OPCODE_CONSTRUCT_VALIDATED, \
|
||||||
&&OPCODE_CONSTRUCT_ARRAY, \
|
&&OPCODE_CONSTRUCT_ARRAY, \
|
||||||
&&OPCODE_CONSTRUCT_TYPED_ARRAY, \
|
&&OPCODE_CONSTRUCT_TYPED_ARRAY, \
|
||||||
&&OPCODE_CONSTRUCT_DICTIONARY, \
|
&&OPCODE_CONSTRUCT_DICTIONARY, \
|
||||||
&&OPCODE_CALL, \
|
&&OPCODE_CALL, \
|
||||||
&&OPCODE_CALL_RETURN, \
|
&&OPCODE_CALL_RETURN, \
|
||||||
&&OPCODE_CALL_ASYNC, \
|
&&OPCODE_CALL_ASYNC, \
|
||||||
&&OPCODE_CALL_UTILITY, \
|
&&OPCODE_CALL_UTILITY, \
|
||||||
&&OPCODE_CALL_UTILITY_VALIDATED, \
|
&&OPCODE_CALL_UTILITY_VALIDATED, \
|
||||||
&&OPCODE_CALL_GDSCRIPT_UTILITY, \
|
&&OPCODE_CALL_GDSCRIPT_UTILITY, \
|
||||||
&&OPCODE_CALL_BUILTIN_TYPE_VALIDATED, \
|
&&OPCODE_CALL_BUILTIN_TYPE_VALIDATED, \
|
||||||
&&OPCODE_CALL_SELF_BASE, \
|
&&OPCODE_CALL_SELF_BASE, \
|
||||||
&&OPCODE_CALL_METHOD_BIND, \
|
&&OPCODE_CALL_METHOD_BIND, \
|
||||||
&&OPCODE_CALL_METHOD_BIND_RET, \
|
&&OPCODE_CALL_METHOD_BIND_RET, \
|
||||||
&&OPCODE_CALL_BUILTIN_STATIC, \
|
&&OPCODE_CALL_BUILTIN_STATIC, \
|
||||||
&&OPCODE_CALL_NATIVE_STATIC, \
|
&&OPCODE_CALL_NATIVE_STATIC, \
|
||||||
&&OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN, \
|
&&OPCODE_CALL_NATIVE_STATIC_VALIDATED_RETURN, \
|
||||||
&&OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN, \
|
&&OPCODE_CALL_NATIVE_STATIC_VALIDATED_NO_RETURN, \
|
||||||
&&OPCODE_AWAIT, \
|
&&OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN, \
|
||||||
&&OPCODE_AWAIT_RESUME, \
|
&&OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN, \
|
||||||
&&OPCODE_CREATE_LAMBDA, \
|
&&OPCODE_AWAIT, \
|
||||||
&&OPCODE_CREATE_SELF_LAMBDA, \
|
&&OPCODE_AWAIT_RESUME, \
|
||||||
&&OPCODE_JUMP, \
|
&&OPCODE_CREATE_LAMBDA, \
|
||||||
&&OPCODE_JUMP_IF, \
|
&&OPCODE_CREATE_SELF_LAMBDA, \
|
||||||
&&OPCODE_JUMP_IF_NOT, \
|
&&OPCODE_JUMP, \
|
||||||
&&OPCODE_JUMP_TO_DEF_ARGUMENT, \
|
&&OPCODE_JUMP_IF, \
|
||||||
&&OPCODE_JUMP_IF_SHARED, \
|
&&OPCODE_JUMP_IF_NOT, \
|
||||||
&&OPCODE_RETURN, \
|
&&OPCODE_JUMP_TO_DEF_ARGUMENT, \
|
||||||
&&OPCODE_RETURN_TYPED_BUILTIN, \
|
&&OPCODE_JUMP_IF_SHARED, \
|
||||||
&&OPCODE_RETURN_TYPED_ARRAY, \
|
&&OPCODE_RETURN, \
|
||||||
&&OPCODE_RETURN_TYPED_NATIVE, \
|
&&OPCODE_RETURN_TYPED_BUILTIN, \
|
||||||
&&OPCODE_RETURN_TYPED_SCRIPT, \
|
&&OPCODE_RETURN_TYPED_ARRAY, \
|
||||||
&&OPCODE_ITERATE_BEGIN, \
|
&&OPCODE_RETURN_TYPED_NATIVE, \
|
||||||
&&OPCODE_ITERATE_BEGIN_INT, \
|
&&OPCODE_RETURN_TYPED_SCRIPT, \
|
||||||
&&OPCODE_ITERATE_BEGIN_FLOAT, \
|
&&OPCODE_ITERATE_BEGIN, \
|
||||||
&&OPCODE_ITERATE_BEGIN_VECTOR2, \
|
&&OPCODE_ITERATE_BEGIN_INT, \
|
||||||
&&OPCODE_ITERATE_BEGIN_VECTOR2I, \
|
&&OPCODE_ITERATE_BEGIN_FLOAT, \
|
||||||
&&OPCODE_ITERATE_BEGIN_VECTOR3, \
|
&&OPCODE_ITERATE_BEGIN_VECTOR2, \
|
||||||
&&OPCODE_ITERATE_BEGIN_VECTOR3I, \
|
&&OPCODE_ITERATE_BEGIN_VECTOR2I, \
|
||||||
&&OPCODE_ITERATE_BEGIN_STRING, \
|
&&OPCODE_ITERATE_BEGIN_VECTOR3, \
|
||||||
&&OPCODE_ITERATE_BEGIN_DICTIONARY, \
|
&&OPCODE_ITERATE_BEGIN_VECTOR3I, \
|
||||||
&&OPCODE_ITERATE_BEGIN_ARRAY, \
|
&&OPCODE_ITERATE_BEGIN_STRING, \
|
||||||
&&OPCODE_ITERATE_BEGIN_PACKED_BYTE_ARRAY, \
|
&&OPCODE_ITERATE_BEGIN_DICTIONARY, \
|
||||||
&&OPCODE_ITERATE_BEGIN_PACKED_INT32_ARRAY, \
|
&&OPCODE_ITERATE_BEGIN_ARRAY, \
|
||||||
&&OPCODE_ITERATE_BEGIN_PACKED_INT64_ARRAY, \
|
&&OPCODE_ITERATE_BEGIN_PACKED_BYTE_ARRAY, \
|
||||||
&&OPCODE_ITERATE_BEGIN_PACKED_FLOAT32_ARRAY, \
|
&&OPCODE_ITERATE_BEGIN_PACKED_INT32_ARRAY, \
|
||||||
&&OPCODE_ITERATE_BEGIN_PACKED_FLOAT64_ARRAY, \
|
&&OPCODE_ITERATE_BEGIN_PACKED_INT64_ARRAY, \
|
||||||
&&OPCODE_ITERATE_BEGIN_PACKED_STRING_ARRAY, \
|
&&OPCODE_ITERATE_BEGIN_PACKED_FLOAT32_ARRAY, \
|
||||||
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR2_ARRAY, \
|
&&OPCODE_ITERATE_BEGIN_PACKED_FLOAT64_ARRAY, \
|
||||||
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR3_ARRAY, \
|
&&OPCODE_ITERATE_BEGIN_PACKED_STRING_ARRAY, \
|
||||||
&&OPCODE_ITERATE_BEGIN_PACKED_COLOR_ARRAY, \
|
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR2_ARRAY, \
|
||||||
&&OPCODE_ITERATE_BEGIN_OBJECT, \
|
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR3_ARRAY, \
|
||||||
&&OPCODE_ITERATE, \
|
&&OPCODE_ITERATE_BEGIN_PACKED_COLOR_ARRAY, \
|
||||||
&&OPCODE_ITERATE_INT, \
|
&&OPCODE_ITERATE_BEGIN_OBJECT, \
|
||||||
&&OPCODE_ITERATE_FLOAT, \
|
&&OPCODE_ITERATE, \
|
||||||
&&OPCODE_ITERATE_VECTOR2, \
|
&&OPCODE_ITERATE_INT, \
|
||||||
&&OPCODE_ITERATE_VECTOR2I, \
|
&&OPCODE_ITERATE_FLOAT, \
|
||||||
&&OPCODE_ITERATE_VECTOR3, \
|
&&OPCODE_ITERATE_VECTOR2, \
|
||||||
&&OPCODE_ITERATE_VECTOR3I, \
|
&&OPCODE_ITERATE_VECTOR2I, \
|
||||||
&&OPCODE_ITERATE_STRING, \
|
&&OPCODE_ITERATE_VECTOR3, \
|
||||||
&&OPCODE_ITERATE_DICTIONARY, \
|
&&OPCODE_ITERATE_VECTOR3I, \
|
||||||
&&OPCODE_ITERATE_ARRAY, \
|
&&OPCODE_ITERATE_STRING, \
|
||||||
&&OPCODE_ITERATE_PACKED_BYTE_ARRAY, \
|
&&OPCODE_ITERATE_DICTIONARY, \
|
||||||
&&OPCODE_ITERATE_PACKED_INT32_ARRAY, \
|
&&OPCODE_ITERATE_ARRAY, \
|
||||||
&&OPCODE_ITERATE_PACKED_INT64_ARRAY, \
|
&&OPCODE_ITERATE_PACKED_BYTE_ARRAY, \
|
||||||
&&OPCODE_ITERATE_PACKED_FLOAT32_ARRAY, \
|
&&OPCODE_ITERATE_PACKED_INT32_ARRAY, \
|
||||||
&&OPCODE_ITERATE_PACKED_FLOAT64_ARRAY, \
|
&&OPCODE_ITERATE_PACKED_INT64_ARRAY, \
|
||||||
&&OPCODE_ITERATE_PACKED_STRING_ARRAY, \
|
&&OPCODE_ITERATE_PACKED_FLOAT32_ARRAY, \
|
||||||
&&OPCODE_ITERATE_PACKED_VECTOR2_ARRAY, \
|
&&OPCODE_ITERATE_PACKED_FLOAT64_ARRAY, \
|
||||||
&&OPCODE_ITERATE_PACKED_VECTOR3_ARRAY, \
|
&&OPCODE_ITERATE_PACKED_STRING_ARRAY, \
|
||||||
&&OPCODE_ITERATE_PACKED_COLOR_ARRAY, \
|
&&OPCODE_ITERATE_PACKED_VECTOR2_ARRAY, \
|
||||||
&&OPCODE_ITERATE_OBJECT, \
|
&&OPCODE_ITERATE_PACKED_VECTOR3_ARRAY, \
|
||||||
&&OPCODE_STORE_GLOBAL, \
|
&&OPCODE_ITERATE_PACKED_COLOR_ARRAY, \
|
||||||
&&OPCODE_STORE_NAMED_GLOBAL, \
|
&&OPCODE_ITERATE_OBJECT, \
|
||||||
&&OPCODE_TYPE_ADJUST_BOOL, \
|
&&OPCODE_STORE_GLOBAL, \
|
||||||
&&OPCODE_TYPE_ADJUST_INT, \
|
&&OPCODE_STORE_NAMED_GLOBAL, \
|
||||||
&&OPCODE_TYPE_ADJUST_FLOAT, \
|
&&OPCODE_TYPE_ADJUST_BOOL, \
|
||||||
&&OPCODE_TYPE_ADJUST_STRING, \
|
&&OPCODE_TYPE_ADJUST_INT, \
|
||||||
&&OPCODE_TYPE_ADJUST_VECTOR2, \
|
&&OPCODE_TYPE_ADJUST_FLOAT, \
|
||||||
&&OPCODE_TYPE_ADJUST_VECTOR2I, \
|
&&OPCODE_TYPE_ADJUST_STRING, \
|
||||||
&&OPCODE_TYPE_ADJUST_RECT2, \
|
&&OPCODE_TYPE_ADJUST_VECTOR2, \
|
||||||
&&OPCODE_TYPE_ADJUST_RECT2I, \
|
&&OPCODE_TYPE_ADJUST_VECTOR2I, \
|
||||||
&&OPCODE_TYPE_ADJUST_VECTOR3, \
|
&&OPCODE_TYPE_ADJUST_RECT2, \
|
||||||
&&OPCODE_TYPE_ADJUST_VECTOR3I, \
|
&&OPCODE_TYPE_ADJUST_RECT2I, \
|
||||||
&&OPCODE_TYPE_ADJUST_TRANSFORM2D, \
|
&&OPCODE_TYPE_ADJUST_VECTOR3, \
|
||||||
&&OPCODE_TYPE_ADJUST_VECTOR4, \
|
&&OPCODE_TYPE_ADJUST_VECTOR3I, \
|
||||||
&&OPCODE_TYPE_ADJUST_VECTOR4I, \
|
&&OPCODE_TYPE_ADJUST_TRANSFORM2D, \
|
||||||
&&OPCODE_TYPE_ADJUST_PLANE, \
|
&&OPCODE_TYPE_ADJUST_VECTOR4, \
|
||||||
&&OPCODE_TYPE_ADJUST_QUATERNION, \
|
&&OPCODE_TYPE_ADJUST_VECTOR4I, \
|
||||||
&&OPCODE_TYPE_ADJUST_AABB, \
|
&&OPCODE_TYPE_ADJUST_PLANE, \
|
||||||
&&OPCODE_TYPE_ADJUST_BASIS, \
|
&&OPCODE_TYPE_ADJUST_QUATERNION, \
|
||||||
&&OPCODE_TYPE_ADJUST_TRANSFORM3D, \
|
&&OPCODE_TYPE_ADJUST_AABB, \
|
||||||
&&OPCODE_TYPE_ADJUST_PROJECTION, \
|
&&OPCODE_TYPE_ADJUST_BASIS, \
|
||||||
&&OPCODE_TYPE_ADJUST_COLOR, \
|
&&OPCODE_TYPE_ADJUST_TRANSFORM3D, \
|
||||||
&&OPCODE_TYPE_ADJUST_STRING_NAME, \
|
&&OPCODE_TYPE_ADJUST_PROJECTION, \
|
||||||
&&OPCODE_TYPE_ADJUST_NODE_PATH, \
|
&&OPCODE_TYPE_ADJUST_COLOR, \
|
||||||
&&OPCODE_TYPE_ADJUST_RID, \
|
&&OPCODE_TYPE_ADJUST_STRING_NAME, \
|
||||||
&&OPCODE_TYPE_ADJUST_OBJECT, \
|
&&OPCODE_TYPE_ADJUST_NODE_PATH, \
|
||||||
&&OPCODE_TYPE_ADJUST_CALLABLE, \
|
&&OPCODE_TYPE_ADJUST_RID, \
|
||||||
&&OPCODE_TYPE_ADJUST_SIGNAL, \
|
&&OPCODE_TYPE_ADJUST_OBJECT, \
|
||||||
&&OPCODE_TYPE_ADJUST_DICTIONARY, \
|
&&OPCODE_TYPE_ADJUST_CALLABLE, \
|
||||||
&&OPCODE_TYPE_ADJUST_ARRAY, \
|
&&OPCODE_TYPE_ADJUST_SIGNAL, \
|
||||||
&&OPCODE_TYPE_ADJUST_PACKED_BYTE_ARRAY, \
|
&&OPCODE_TYPE_ADJUST_DICTIONARY, \
|
||||||
&&OPCODE_TYPE_ADJUST_PACKED_INT32_ARRAY, \
|
&&OPCODE_TYPE_ADJUST_ARRAY, \
|
||||||
&&OPCODE_TYPE_ADJUST_PACKED_INT64_ARRAY, \
|
&&OPCODE_TYPE_ADJUST_PACKED_BYTE_ARRAY, \
|
||||||
&&OPCODE_TYPE_ADJUST_PACKED_FLOAT32_ARRAY, \
|
&&OPCODE_TYPE_ADJUST_PACKED_INT32_ARRAY, \
|
||||||
&&OPCODE_TYPE_ADJUST_PACKED_FLOAT64_ARRAY, \
|
&&OPCODE_TYPE_ADJUST_PACKED_INT64_ARRAY, \
|
||||||
&&OPCODE_TYPE_ADJUST_PACKED_STRING_ARRAY, \
|
&&OPCODE_TYPE_ADJUST_PACKED_FLOAT32_ARRAY, \
|
||||||
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR2_ARRAY, \
|
&&OPCODE_TYPE_ADJUST_PACKED_FLOAT64_ARRAY, \
|
||||||
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR3_ARRAY, \
|
&&OPCODE_TYPE_ADJUST_PACKED_STRING_ARRAY, \
|
||||||
&&OPCODE_TYPE_ADJUST_PACKED_COLOR_ARRAY, \
|
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR2_ARRAY, \
|
||||||
&&OPCODE_ASSERT, \
|
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR3_ARRAY, \
|
||||||
&&OPCODE_BREAKPOINT, \
|
&&OPCODE_TYPE_ADJUST_PACKED_COLOR_ARRAY, \
|
||||||
&&OPCODE_LINE, \
|
&&OPCODE_ASSERT, \
|
||||||
&&OPCODE_END \
|
&&OPCODE_BREAKPOINT, \
|
||||||
}; \
|
&&OPCODE_LINE, \
|
||||||
|
&&OPCODE_END \
|
||||||
|
}; \
|
||||||
static_assert((sizeof(switch_table_ops) / sizeof(switch_table_ops[0]) == (OPCODE_END + 1)), "Opcodes in jump table aren't the same as opcodes in enum.");
|
static_assert((sizeof(switch_table_ops) / sizeof(switch_table_ops[0]) == (OPCODE_END + 1)), "Opcodes in jump table aren't the same as opcodes in enum.");
|
||||||
|
|
||||||
#define OPCODE(m_op) \
|
#define OPCODE(m_op) \
|
||||||
@@ -1956,6 +1958,78 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||||||
}
|
}
|
||||||
DISPATCH_OPCODE;
|
DISPATCH_OPCODE;
|
||||||
|
|
||||||
|
OPCODE(OPCODE_CALL_NATIVE_STATIC_VALIDATED_RETURN) {
|
||||||
|
LOAD_INSTRUCTION_ARGS
|
||||||
|
CHECK_SPACE(3 + instr_arg_count);
|
||||||
|
|
||||||
|
ip += instr_arg_count;
|
||||||
|
|
||||||
|
int argc = _code_ptr[ip + 1];
|
||||||
|
GD_ERR_BREAK(argc < 0);
|
||||||
|
|
||||||
|
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _methods_count);
|
||||||
|
MethodBind *method = _methods_ptr[_code_ptr[ip + 2]];
|
||||||
|
|
||||||
|
Variant **argptrs = instruction_args;
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
uint64_t call_time = 0;
|
||||||
|
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
|
||||||
|
call_time = OS::get_singleton()->get_ticks_usec();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GET_INSTRUCTION_ARG(ret, argc);
|
||||||
|
method->validated_call(nullptr, (const Variant **)argptrs, ret);
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
|
||||||
|
uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time;
|
||||||
|
_profile_native_call(t_taken, method->get_name(), method->get_instance_class());
|
||||||
|
function_call_time += t_taken;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ip += 3;
|
||||||
|
}
|
||||||
|
DISPATCH_OPCODE;
|
||||||
|
|
||||||
|
OPCODE(OPCODE_CALL_NATIVE_STATIC_VALIDATED_NO_RETURN) {
|
||||||
|
LOAD_INSTRUCTION_ARGS
|
||||||
|
CHECK_SPACE(3 + instr_arg_count);
|
||||||
|
|
||||||
|
ip += instr_arg_count;
|
||||||
|
|
||||||
|
int argc = _code_ptr[ip + 1];
|
||||||
|
GD_ERR_BREAK(argc < 0);
|
||||||
|
|
||||||
|
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _methods_count);
|
||||||
|
MethodBind *method = _methods_ptr[_code_ptr[ip + 2]];
|
||||||
|
|
||||||
|
Variant **argptrs = instruction_args;
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
uint64_t call_time = 0;
|
||||||
|
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
|
||||||
|
call_time = OS::get_singleton()->get_ticks_usec();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GET_INSTRUCTION_ARG(ret, argc);
|
||||||
|
VariantInternal::initialize(ret, Variant::NIL);
|
||||||
|
method->validated_call(nullptr, (const Variant **)argptrs, nullptr);
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (GDScriptLanguage::get_singleton()->profiling && GDScriptLanguage::get_singleton()->profile_native_calls) {
|
||||||
|
uint64_t t_taken = OS::get_singleton()->get_ticks_usec() - call_time;
|
||||||
|
_profile_native_call(t_taken, method->get_name(), method->get_instance_class());
|
||||||
|
function_call_time += t_taken;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ip += 3;
|
||||||
|
}
|
||||||
|
DISPATCH_OPCODE;
|
||||||
|
|
||||||
OPCODE(OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN) {
|
OPCODE(OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN) {
|
||||||
LOAD_INSTRUCTION_ARGS
|
LOAD_INSTRUCTION_ARGS
|
||||||
CHECK_SPACE(3 + instr_arg_count);
|
CHECK_SPACE(3 + instr_arg_count);
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
func test():
|
||||||
|
# Validated native static call with return value.
|
||||||
|
print(FileAccess.file_exists("some_file"))
|
||||||
|
|
||||||
|
# Validated native static call without return value.
|
||||||
|
Node.print_orphan_nodes()
|
||||||
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
GDTEST_OK
|
||||||
|
false
|
||||||
Reference in New Issue
Block a user