GDScript: Replace ptrcalls on MethodBind to validated calls
This improves the performance of typed calls to engine methods when the argument types are exact. Using validated calls delegate more of the work the core instead of doing argument unpacking in the VM. It also does not need different instructions for each return type, simplifying the code.
This commit is contained in:
parent
fba341ce44
commit
4a7d49a89a
8 changed files with 213 additions and 497 deletions
|
@ -400,7 +400,6 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() {
|
|||
}
|
||||
function->_stack_size = RESERVED_STACK + max_locals + temporaries.size();
|
||||
function->_instruction_args_size = instr_args_max;
|
||||
function->_ptrcall_args_size = ptrcall_max;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
function->operator_names = operator_names;
|
||||
|
@ -1225,75 +1224,35 @@ void GDScriptByteCodeGenerator::write_call_method_bind(const Address &p_target,
|
|||
ct.cleanup();
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_call_ptrcall(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) {
|
||||
#define CASE_TYPE(m_type) \
|
||||
case Variant::m_type: \
|
||||
append_opcode_and_argcount(GDScriptFunction::OPCODE_CALL_PTRCALL_##m_type, 2 + p_arguments.size()); \
|
||||
break
|
||||
void GDScriptByteCodeGenerator::write_call_method_bind_validated(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) {
|
||||
Variant::Type return_type = Variant::NIL;
|
||||
bool has_return = p_method->has_return();
|
||||
|
||||
bool is_ptrcall = true;
|
||||
|
||||
if (p_method->has_return()) {
|
||||
MethodInfo info;
|
||||
ClassDB::get_method_info(p_method->get_instance_class(), p_method->get_name(), &info);
|
||||
switch (info.return_val.type) {
|
||||
CASE_TYPE(BOOL);
|
||||
CASE_TYPE(INT);
|
||||
CASE_TYPE(FLOAT);
|
||||
CASE_TYPE(STRING);
|
||||
CASE_TYPE(VECTOR2);
|
||||
CASE_TYPE(VECTOR2I);
|
||||
CASE_TYPE(RECT2);
|
||||
CASE_TYPE(RECT2I);
|
||||
CASE_TYPE(VECTOR3);
|
||||
CASE_TYPE(VECTOR3I);
|
||||
CASE_TYPE(TRANSFORM2D);
|
||||
CASE_TYPE(PLANE);
|
||||
CASE_TYPE(AABB);
|
||||
CASE_TYPE(BASIS);
|
||||
CASE_TYPE(TRANSFORM3D);
|
||||
CASE_TYPE(COLOR);
|
||||
CASE_TYPE(STRING_NAME);
|
||||
CASE_TYPE(NODE_PATH);
|
||||
CASE_TYPE(RID);
|
||||
CASE_TYPE(QUATERNION);
|
||||
CASE_TYPE(OBJECT);
|
||||
CASE_TYPE(CALLABLE);
|
||||
CASE_TYPE(SIGNAL);
|
||||
CASE_TYPE(DICTIONARY);
|
||||
CASE_TYPE(ARRAY);
|
||||
CASE_TYPE(PACKED_BYTE_ARRAY);
|
||||
CASE_TYPE(PACKED_INT32_ARRAY);
|
||||
CASE_TYPE(PACKED_INT64_ARRAY);
|
||||
CASE_TYPE(PACKED_FLOAT32_ARRAY);
|
||||
CASE_TYPE(PACKED_FLOAT64_ARRAY);
|
||||
CASE_TYPE(PACKED_STRING_ARRAY);
|
||||
CASE_TYPE(PACKED_VECTOR2_ARRAY);
|
||||
CASE_TYPE(PACKED_VECTOR3_ARRAY);
|
||||
CASE_TYPE(PACKED_COLOR_ARRAY);
|
||||
default:
|
||||
append_opcode_and_argcount(p_target.mode == Address::NIL ? GDScriptFunction::OPCODE_CALL_METHOD_BIND : GDScriptFunction::OPCODE_CALL_METHOD_BIND_RET, 2 + p_arguments.size());
|
||||
is_ptrcall = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
append_opcode_and_argcount(GDScriptFunction::OPCODE_CALL_PTRCALL_NO_RETURN, 2 + p_arguments.size());
|
||||
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_METHOD_BIND_VALIDATED_RETURN : GDScriptFunction::OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN;
|
||||
append_opcode_and_argcount(code, 2 + p_arguments.size());
|
||||
|
||||
for (int i = 0; i < p_arguments.size(); i++) {
|
||||
append(p_arguments[i]);
|
||||
}
|
||||
append(p_base);
|
||||
CallTarget ct = get_call_target(p_target);
|
||||
append(ct.target);
|
||||
append(p_arguments.size());
|
||||
append(p_method);
|
||||
ct.cleanup();
|
||||
if (is_ptrcall) {
|
||||
alloc_ptrcall(p_arguments.size());
|
||||
}
|
||||
|
||||
#undef CASE_TYPE
|
||||
}
|
||||
|
||||
void GDScriptByteCodeGenerator::write_call_self(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) {
|
||||
|
|
|
@ -97,7 +97,6 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
|
|||
int max_locals = 0;
|
||||
int current_line = 0;
|
||||
int instr_args_max = 0;
|
||||
int ptrcall_max = 0;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
List<int> temp_stack;
|
||||
|
@ -346,12 +345,6 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
|
|||
return pos;
|
||||
}
|
||||
|
||||
void alloc_ptrcall(int p_params) {
|
||||
if (p_params >= ptrcall_max) {
|
||||
ptrcall_max = p_params;
|
||||
}
|
||||
}
|
||||
|
||||
CallTarget get_call_target(const Address &p_target, Variant::Type p_type = Variant::NIL);
|
||||
|
||||
int address_of(const Address &p_address) {
|
||||
|
@ -519,7 +512,7 @@ public:
|
|||
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_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) override;
|
||||
virtual void write_call_ptrcall(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_async(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
|
||||
virtual void write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
|
||||
|
|
|
@ -129,7 +129,7 @@ public:
|
|||
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_method_bind(const Address &p_target, const Address &p_base, MethodBind *p_method, const Vector<Address> &p_arguments) = 0;
|
||||
virtual void write_call_ptrcall(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_async(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
|
||||
virtual void write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
|
||||
|
|
|
@ -229,13 +229,13 @@ static bool _is_exact_type(const PropertyInfo &p_par_type, const GDScriptDataTyp
|
|||
}
|
||||
}
|
||||
|
||||
static bool _can_use_ptrcall(const MethodBind *p_method, const Vector<GDScriptCodeGenerator::Address> &p_arguments) {
|
||||
static bool _can_use_validate_call(const MethodBind *p_method, const Vector<GDScriptCodeGenerator::Address> &p_arguments) {
|
||||
if (p_method->is_vararg()) {
|
||||
// ptrcall won't work with vararg methods.
|
||||
// Validated call won't work with vararg methods.
|
||||
return false;
|
||||
}
|
||||
if (p_method->get_argument_count() != p_arguments.size()) {
|
||||
// ptrcall won't work with default arguments.
|
||||
// Validated call won't work with default arguments.
|
||||
return false;
|
||||
}
|
||||
MethodInfo info;
|
||||
|
@ -636,9 +636,9 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|||
self.mode = GDScriptCodeGenerator::Address::SELF;
|
||||
MethodBind *method = ClassDB::get_method(codegen.script->native->get_name(), call->function_name);
|
||||
|
||||
if (_can_use_ptrcall(method, arguments)) {
|
||||
// Exact arguments, use ptrcall.
|
||||
gen->write_call_ptrcall(result, self, method, arguments);
|
||||
if (_can_use_validate_call(method, arguments)) {
|
||||
// Exact arguments, use validated call.
|
||||
gen->write_call_method_bind_validated(result, self, method, arguments);
|
||||
} else {
|
||||
// Not exact arguments, but still can use method bind call.
|
||||
gen->write_call_method_bind(result, self, method, arguments);
|
||||
|
@ -686,9 +686,9 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|||
}
|
||||
if (ClassDB::class_exists(class_name) && ClassDB::has_method(class_name, call->function_name)) {
|
||||
MethodBind *method = ClassDB::get_method(class_name, call->function_name);
|
||||
if (_can_use_ptrcall(method, arguments)) {
|
||||
// Exact arguments, use ptrcall.
|
||||
gen->write_call_ptrcall(result, base, method, arguments);
|
||||
if (_can_use_validate_call(method, arguments)) {
|
||||
// Exact arguments, use validated call.
|
||||
gen->write_call_method_bind_validated(result, base, method, arguments);
|
||||
} else {
|
||||
// Not exact arguments, but still can use method bind call.
|
||||
gen->write_call_method_bind(result, base, method, arguments);
|
||||
|
@ -733,7 +733,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
|||
GDScriptCodeGenerator::Address result = codegen.add_temporary(_gdtype_from_datatype(get_node->get_datatype(), codegen.script));
|
||||
|
||||
MethodBind *get_node_method = ClassDB::get_method("Node", "get_node");
|
||||
gen->write_call_ptrcall(result, GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), get_node_method, args);
|
||||
gen->write_call_method_bind_validated(result, GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), get_node_method, args);
|
||||
|
||||
return result;
|
||||
} break;
|
||||
|
|
|
@ -670,10 +670,29 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
|||
|
||||
incr += 4 + argc;
|
||||
} break;
|
||||
case OPCODE_CALL_PTRCALL_NO_RETURN: {
|
||||
|
||||
case OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN: {
|
||||
int instr_var_args = _code_ptr[++ip];
|
||||
text += "call method-bind validated (return) ";
|
||||
MethodBind *method = _methods_ptr[_code_ptr[ip + 2 + instr_var_args]];
|
||||
int argc = _code_ptr[ip + 1 + instr_var_args];
|
||||
text += DADDR(2 + argc) + " = ";
|
||||
text += DADDR(1 + argc) + ".";
|
||||
text += method->get_name();
|
||||
text += "(";
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (i > 0)
|
||||
text += ", ";
|
||||
text += DADDR(1 + i);
|
||||
}
|
||||
text += ")";
|
||||
incr = 5 + argc;
|
||||
} break;
|
||||
|
||||
case OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN: {
|
||||
int instr_var_args = _code_ptr[++ip];
|
||||
|
||||
text += "call-ptrcall (no return) ";
|
||||
text += "call method-bind validated (no return) ";
|
||||
|
||||
MethodBind *method = _methods_ptr[_code_ptr[ip + 2 + instr_var_args]];
|
||||
|
||||
|
@ -694,65 +713,6 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
|||
incr = 5 + argc;
|
||||
} break;
|
||||
|
||||
#define DISASSEMBLE_PTRCALL(m_type) \
|
||||
case OPCODE_CALL_PTRCALL_##m_type: { \
|
||||
int instr_var_args = _code_ptr[++ip]; \
|
||||
text += "call-ptrcall (return "; \
|
||||
text += #m_type; \
|
||||
text += ") "; \
|
||||
MethodBind *method = _methods_ptr[_code_ptr[ip + 2 + instr_var_args]]; \
|
||||
int argc = _code_ptr[ip + 1 + instr_var_args]; \
|
||||
text += DADDR(2 + argc) + " = "; \
|
||||
text += DADDR(1 + argc) + "."; \
|
||||
text += method->get_name(); \
|
||||
text += "("; \
|
||||
for (int i = 0; i < argc; i++) { \
|
||||
if (i > 0) \
|
||||
text += ", "; \
|
||||
text += DADDR(1 + i); \
|
||||
} \
|
||||
text += ")"; \
|
||||
incr = 5 + argc; \
|
||||
} break
|
||||
|
||||
DISASSEMBLE_PTRCALL(BOOL);
|
||||
DISASSEMBLE_PTRCALL(INT);
|
||||
DISASSEMBLE_PTRCALL(FLOAT);
|
||||
DISASSEMBLE_PTRCALL(STRING);
|
||||
DISASSEMBLE_PTRCALL(VECTOR2);
|
||||
DISASSEMBLE_PTRCALL(VECTOR2I);
|
||||
DISASSEMBLE_PTRCALL(RECT2);
|
||||
DISASSEMBLE_PTRCALL(RECT2I);
|
||||
DISASSEMBLE_PTRCALL(VECTOR3);
|
||||
DISASSEMBLE_PTRCALL(VECTOR3I);
|
||||
DISASSEMBLE_PTRCALL(TRANSFORM2D);
|
||||
DISASSEMBLE_PTRCALL(VECTOR4);
|
||||
DISASSEMBLE_PTRCALL(VECTOR4I);
|
||||
DISASSEMBLE_PTRCALL(PLANE);
|
||||
DISASSEMBLE_PTRCALL(AABB);
|
||||
DISASSEMBLE_PTRCALL(BASIS);
|
||||
DISASSEMBLE_PTRCALL(TRANSFORM3D);
|
||||
DISASSEMBLE_PTRCALL(PROJECTION);
|
||||
DISASSEMBLE_PTRCALL(COLOR);
|
||||
DISASSEMBLE_PTRCALL(STRING_NAME);
|
||||
DISASSEMBLE_PTRCALL(NODE_PATH);
|
||||
DISASSEMBLE_PTRCALL(RID);
|
||||
DISASSEMBLE_PTRCALL(QUATERNION);
|
||||
DISASSEMBLE_PTRCALL(OBJECT);
|
||||
DISASSEMBLE_PTRCALL(CALLABLE);
|
||||
DISASSEMBLE_PTRCALL(SIGNAL);
|
||||
DISASSEMBLE_PTRCALL(DICTIONARY);
|
||||
DISASSEMBLE_PTRCALL(ARRAY);
|
||||
DISASSEMBLE_PTRCALL(PACKED_BYTE_ARRAY);
|
||||
DISASSEMBLE_PTRCALL(PACKED_INT32_ARRAY);
|
||||
DISASSEMBLE_PTRCALL(PACKED_INT64_ARRAY);
|
||||
DISASSEMBLE_PTRCALL(PACKED_FLOAT32_ARRAY);
|
||||
DISASSEMBLE_PTRCALL(PACKED_FLOAT64_ARRAY);
|
||||
DISASSEMBLE_PTRCALL(PACKED_STRING_ARRAY);
|
||||
DISASSEMBLE_PTRCALL(PACKED_VECTOR2_ARRAY);
|
||||
DISASSEMBLE_PTRCALL(PACKED_VECTOR3_ARRAY);
|
||||
DISASSEMBLE_PTRCALL(PACKED_COLOR_ARRAY);
|
||||
|
||||
case OPCODE_CALL_BUILTIN_TYPE_VALIDATED: {
|
||||
int instr_var_args = _code_ptr[++ip];
|
||||
int argc = _code_ptr[ip + 1 + instr_var_args];
|
||||
|
|
|
@ -241,45 +241,8 @@ public:
|
|||
OPCODE_CALL_METHOD_BIND_RET,
|
||||
OPCODE_CALL_BUILTIN_STATIC,
|
||||
OPCODE_CALL_NATIVE_STATIC,
|
||||
// ptrcall have one instruction per return type.
|
||||
OPCODE_CALL_PTRCALL_NO_RETURN,
|
||||
OPCODE_CALL_PTRCALL_BOOL,
|
||||
OPCODE_CALL_PTRCALL_INT,
|
||||
OPCODE_CALL_PTRCALL_FLOAT,
|
||||
OPCODE_CALL_PTRCALL_STRING,
|
||||
OPCODE_CALL_PTRCALL_VECTOR2,
|
||||
OPCODE_CALL_PTRCALL_VECTOR2I,
|
||||
OPCODE_CALL_PTRCALL_RECT2,
|
||||
OPCODE_CALL_PTRCALL_RECT2I,
|
||||
OPCODE_CALL_PTRCALL_VECTOR3,
|
||||
OPCODE_CALL_PTRCALL_VECTOR3I,
|
||||
OPCODE_CALL_PTRCALL_TRANSFORM2D,
|
||||
OPCODE_CALL_PTRCALL_VECTOR4,
|
||||
OPCODE_CALL_PTRCALL_VECTOR4I,
|
||||
OPCODE_CALL_PTRCALL_PLANE,
|
||||
OPCODE_CALL_PTRCALL_QUATERNION,
|
||||
OPCODE_CALL_PTRCALL_AABB,
|
||||
OPCODE_CALL_PTRCALL_BASIS,
|
||||
OPCODE_CALL_PTRCALL_TRANSFORM3D,
|
||||
OPCODE_CALL_PTRCALL_PROJECTION,
|
||||
OPCODE_CALL_PTRCALL_COLOR,
|
||||
OPCODE_CALL_PTRCALL_STRING_NAME,
|
||||
OPCODE_CALL_PTRCALL_NODE_PATH,
|
||||
OPCODE_CALL_PTRCALL_RID,
|
||||
OPCODE_CALL_PTRCALL_OBJECT,
|
||||
OPCODE_CALL_PTRCALL_CALLABLE,
|
||||
OPCODE_CALL_PTRCALL_SIGNAL,
|
||||
OPCODE_CALL_PTRCALL_DICTIONARY,
|
||||
OPCODE_CALL_PTRCALL_ARRAY,
|
||||
OPCODE_CALL_PTRCALL_PACKED_BYTE_ARRAY,
|
||||
OPCODE_CALL_PTRCALL_PACKED_INT32_ARRAY,
|
||||
OPCODE_CALL_PTRCALL_PACKED_INT64_ARRAY,
|
||||
OPCODE_CALL_PTRCALL_PACKED_FLOAT32_ARRAY,
|
||||
OPCODE_CALL_PTRCALL_PACKED_FLOAT64_ARRAY,
|
||||
OPCODE_CALL_PTRCALL_PACKED_STRING_ARRAY,
|
||||
OPCODE_CALL_PTRCALL_PACKED_VECTOR2_ARRAY,
|
||||
OPCODE_CALL_PTRCALL_PACKED_VECTOR3_ARRAY,
|
||||
OPCODE_CALL_PTRCALL_PACKED_COLOR_ARRAY,
|
||||
OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN,
|
||||
OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN,
|
||||
OPCODE_AWAIT,
|
||||
OPCODE_AWAIT_RESUME,
|
||||
OPCODE_CREATE_LAMBDA,
|
||||
|
@ -425,7 +388,6 @@ private:
|
|||
int _argument_count = 0;
|
||||
int _stack_size = 0;
|
||||
int _instruction_args_size = 0;
|
||||
int _ptrcall_args_size = 0;
|
||||
|
||||
SelfList<GDScriptFunction> function_list{ this };
|
||||
mutable Variant nil;
|
||||
|
|
|
@ -187,191 +187,155 @@ void (*type_init_function_table[])(Variant *) = {
|
|||
};
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define OPCODES_TABLE \
|
||||
static const void *switch_table_ops[] = { \
|
||||
&&OPCODE_OPERATOR, \
|
||||
&&OPCODE_OPERATOR_VALIDATED, \
|
||||
&&OPCODE_TYPE_TEST_BUILTIN, \
|
||||
&&OPCODE_TYPE_TEST_ARRAY, \
|
||||
&&OPCODE_TYPE_TEST_NATIVE, \
|
||||
&&OPCODE_TYPE_TEST_SCRIPT, \
|
||||
&&OPCODE_SET_KEYED, \
|
||||
&&OPCODE_SET_KEYED_VALIDATED, \
|
||||
&&OPCODE_SET_INDEXED_VALIDATED, \
|
||||
&&OPCODE_GET_KEYED, \
|
||||
&&OPCODE_GET_KEYED_VALIDATED, \
|
||||
&&OPCODE_GET_INDEXED_VALIDATED, \
|
||||
&&OPCODE_SET_NAMED, \
|
||||
&&OPCODE_SET_NAMED_VALIDATED, \
|
||||
&&OPCODE_GET_NAMED, \
|
||||
&&OPCODE_GET_NAMED_VALIDATED, \
|
||||
&&OPCODE_SET_MEMBER, \
|
||||
&&OPCODE_GET_MEMBER, \
|
||||
&&OPCODE_SET_STATIC_VARIABLE, \
|
||||
&&OPCODE_GET_STATIC_VARIABLE, \
|
||||
&&OPCODE_ASSIGN, \
|
||||
&&OPCODE_ASSIGN_TRUE, \
|
||||
&&OPCODE_ASSIGN_FALSE, \
|
||||
&&OPCODE_ASSIGN_TYPED_BUILTIN, \
|
||||
&&OPCODE_ASSIGN_TYPED_ARRAY, \
|
||||
&&OPCODE_ASSIGN_TYPED_NATIVE, \
|
||||
&&OPCODE_ASSIGN_TYPED_SCRIPT, \
|
||||
&&OPCODE_CAST_TO_BUILTIN, \
|
||||
&&OPCODE_CAST_TO_NATIVE, \
|
||||
&&OPCODE_CAST_TO_SCRIPT, \
|
||||
&&OPCODE_CONSTRUCT, \
|
||||
&&OPCODE_CONSTRUCT_VALIDATED, \
|
||||
&&OPCODE_CONSTRUCT_ARRAY, \
|
||||
&&OPCODE_CONSTRUCT_TYPED_ARRAY, \
|
||||
&&OPCODE_CONSTRUCT_DICTIONARY, \
|
||||
&&OPCODE_CALL, \
|
||||
&&OPCODE_CALL_RETURN, \
|
||||
&&OPCODE_CALL_ASYNC, \
|
||||
&&OPCODE_CALL_UTILITY, \
|
||||
&&OPCODE_CALL_UTILITY_VALIDATED, \
|
||||
&&OPCODE_CALL_GDSCRIPT_UTILITY, \
|
||||
&&OPCODE_CALL_BUILTIN_TYPE_VALIDATED, \
|
||||
&&OPCODE_CALL_SELF_BASE, \
|
||||
&&OPCODE_CALL_METHOD_BIND, \
|
||||
&&OPCODE_CALL_METHOD_BIND_RET, \
|
||||
&&OPCODE_CALL_BUILTIN_STATIC, \
|
||||
&&OPCODE_CALL_NATIVE_STATIC, \
|
||||
&&OPCODE_CALL_PTRCALL_NO_RETURN, \
|
||||
&&OPCODE_CALL_PTRCALL_BOOL, \
|
||||
&&OPCODE_CALL_PTRCALL_INT, \
|
||||
&&OPCODE_CALL_PTRCALL_FLOAT, \
|
||||
&&OPCODE_CALL_PTRCALL_STRING, \
|
||||
&&OPCODE_CALL_PTRCALL_VECTOR2, \
|
||||
&&OPCODE_CALL_PTRCALL_VECTOR2I, \
|
||||
&&OPCODE_CALL_PTRCALL_RECT2, \
|
||||
&&OPCODE_CALL_PTRCALL_RECT2I, \
|
||||
&&OPCODE_CALL_PTRCALL_VECTOR3, \
|
||||
&&OPCODE_CALL_PTRCALL_VECTOR3I, \
|
||||
&&OPCODE_CALL_PTRCALL_TRANSFORM2D, \
|
||||
&&OPCODE_CALL_PTRCALL_VECTOR4, \
|
||||
&&OPCODE_CALL_PTRCALL_VECTOR4I, \
|
||||
&&OPCODE_CALL_PTRCALL_PLANE, \
|
||||
&&OPCODE_CALL_PTRCALL_QUATERNION, \
|
||||
&&OPCODE_CALL_PTRCALL_AABB, \
|
||||
&&OPCODE_CALL_PTRCALL_BASIS, \
|
||||
&&OPCODE_CALL_PTRCALL_TRANSFORM3D, \
|
||||
&&OPCODE_CALL_PTRCALL_PROJECTION, \
|
||||
&&OPCODE_CALL_PTRCALL_COLOR, \
|
||||
&&OPCODE_CALL_PTRCALL_STRING_NAME, \
|
||||
&&OPCODE_CALL_PTRCALL_NODE_PATH, \
|
||||
&&OPCODE_CALL_PTRCALL_RID, \
|
||||
&&OPCODE_CALL_PTRCALL_OBJECT, \
|
||||
&&OPCODE_CALL_PTRCALL_CALLABLE, \
|
||||
&&OPCODE_CALL_PTRCALL_SIGNAL, \
|
||||
&&OPCODE_CALL_PTRCALL_DICTIONARY, \
|
||||
&&OPCODE_CALL_PTRCALL_ARRAY, \
|
||||
&&OPCODE_CALL_PTRCALL_PACKED_BYTE_ARRAY, \
|
||||
&&OPCODE_CALL_PTRCALL_PACKED_INT32_ARRAY, \
|
||||
&&OPCODE_CALL_PTRCALL_PACKED_INT64_ARRAY, \
|
||||
&&OPCODE_CALL_PTRCALL_PACKED_FLOAT32_ARRAY, \
|
||||
&&OPCODE_CALL_PTRCALL_PACKED_FLOAT64_ARRAY, \
|
||||
&&OPCODE_CALL_PTRCALL_PACKED_STRING_ARRAY, \
|
||||
&&OPCODE_CALL_PTRCALL_PACKED_VECTOR2_ARRAY, \
|
||||
&&OPCODE_CALL_PTRCALL_PACKED_VECTOR3_ARRAY, \
|
||||
&&OPCODE_CALL_PTRCALL_PACKED_COLOR_ARRAY, \
|
||||
&&OPCODE_AWAIT, \
|
||||
&&OPCODE_AWAIT_RESUME, \
|
||||
&&OPCODE_CREATE_LAMBDA, \
|
||||
&&OPCODE_CREATE_SELF_LAMBDA, \
|
||||
&&OPCODE_JUMP, \
|
||||
&&OPCODE_JUMP_IF, \
|
||||
&&OPCODE_JUMP_IF_NOT, \
|
||||
&&OPCODE_JUMP_TO_DEF_ARGUMENT, \
|
||||
&&OPCODE_JUMP_IF_SHARED, \
|
||||
&&OPCODE_RETURN, \
|
||||
&&OPCODE_RETURN_TYPED_BUILTIN, \
|
||||
&&OPCODE_RETURN_TYPED_ARRAY, \
|
||||
&&OPCODE_RETURN_TYPED_NATIVE, \
|
||||
&&OPCODE_RETURN_TYPED_SCRIPT, \
|
||||
&&OPCODE_ITERATE_BEGIN, \
|
||||
&&OPCODE_ITERATE_BEGIN_INT, \
|
||||
&&OPCODE_ITERATE_BEGIN_FLOAT, \
|
||||
&&OPCODE_ITERATE_BEGIN_VECTOR2, \
|
||||
&&OPCODE_ITERATE_BEGIN_VECTOR2I, \
|
||||
&&OPCODE_ITERATE_BEGIN_VECTOR3, \
|
||||
&&OPCODE_ITERATE_BEGIN_VECTOR3I, \
|
||||
&&OPCODE_ITERATE_BEGIN_STRING, \
|
||||
&&OPCODE_ITERATE_BEGIN_DICTIONARY, \
|
||||
&&OPCODE_ITERATE_BEGIN_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_BYTE_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_INT32_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_INT64_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_FLOAT32_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_FLOAT64_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_STRING_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR2_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR3_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_COLOR_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_OBJECT, \
|
||||
&&OPCODE_ITERATE, \
|
||||
&&OPCODE_ITERATE_INT, \
|
||||
&&OPCODE_ITERATE_FLOAT, \
|
||||
&&OPCODE_ITERATE_VECTOR2, \
|
||||
&&OPCODE_ITERATE_VECTOR2I, \
|
||||
&&OPCODE_ITERATE_VECTOR3, \
|
||||
&&OPCODE_ITERATE_VECTOR3I, \
|
||||
&&OPCODE_ITERATE_STRING, \
|
||||
&&OPCODE_ITERATE_DICTIONARY, \
|
||||
&&OPCODE_ITERATE_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_BYTE_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_INT32_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_INT64_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_FLOAT32_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_FLOAT64_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_STRING_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_VECTOR2_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_VECTOR3_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_COLOR_ARRAY, \
|
||||
&&OPCODE_ITERATE_OBJECT, \
|
||||
&&OPCODE_STORE_GLOBAL, \
|
||||
&&OPCODE_STORE_NAMED_GLOBAL, \
|
||||
&&OPCODE_TYPE_ADJUST_BOOL, \
|
||||
&&OPCODE_TYPE_ADJUST_INT, \
|
||||
&&OPCODE_TYPE_ADJUST_FLOAT, \
|
||||
&&OPCODE_TYPE_ADJUST_STRING, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR2, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR2I, \
|
||||
&&OPCODE_TYPE_ADJUST_RECT2, \
|
||||
&&OPCODE_TYPE_ADJUST_RECT2I, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR3, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR3I, \
|
||||
&&OPCODE_TYPE_ADJUST_TRANSFORM2D, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR4, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR4I, \
|
||||
&&OPCODE_TYPE_ADJUST_PLANE, \
|
||||
&&OPCODE_TYPE_ADJUST_QUATERNION, \
|
||||
&&OPCODE_TYPE_ADJUST_AABB, \
|
||||
&&OPCODE_TYPE_ADJUST_BASIS, \
|
||||
&&OPCODE_TYPE_ADJUST_TRANSFORM3D, \
|
||||
&&OPCODE_TYPE_ADJUST_PROJECTION, \
|
||||
&&OPCODE_TYPE_ADJUST_COLOR, \
|
||||
&&OPCODE_TYPE_ADJUST_STRING_NAME, \
|
||||
&&OPCODE_TYPE_ADJUST_NODE_PATH, \
|
||||
&&OPCODE_TYPE_ADJUST_RID, \
|
||||
&&OPCODE_TYPE_ADJUST_OBJECT, \
|
||||
&&OPCODE_TYPE_ADJUST_CALLABLE, \
|
||||
&&OPCODE_TYPE_ADJUST_SIGNAL, \
|
||||
&&OPCODE_TYPE_ADJUST_DICTIONARY, \
|
||||
&&OPCODE_TYPE_ADJUST_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_BYTE_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_INT32_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_INT64_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_FLOAT32_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_FLOAT64_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_STRING_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR2_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR3_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_COLOR_ARRAY, \
|
||||
&&OPCODE_ASSERT, \
|
||||
&&OPCODE_BREAKPOINT, \
|
||||
&&OPCODE_LINE, \
|
||||
&&OPCODE_END \
|
||||
}; \
|
||||
#define OPCODES_TABLE \
|
||||
static const void *switch_table_ops[] = { \
|
||||
&&OPCODE_OPERATOR, \
|
||||
&&OPCODE_OPERATOR_VALIDATED, \
|
||||
&&OPCODE_TYPE_TEST_BUILTIN, \
|
||||
&&OPCODE_TYPE_TEST_ARRAY, \
|
||||
&&OPCODE_TYPE_TEST_NATIVE, \
|
||||
&&OPCODE_TYPE_TEST_SCRIPT, \
|
||||
&&OPCODE_SET_KEYED, \
|
||||
&&OPCODE_SET_KEYED_VALIDATED, \
|
||||
&&OPCODE_SET_INDEXED_VALIDATED, \
|
||||
&&OPCODE_GET_KEYED, \
|
||||
&&OPCODE_GET_KEYED_VALIDATED, \
|
||||
&&OPCODE_GET_INDEXED_VALIDATED, \
|
||||
&&OPCODE_SET_NAMED, \
|
||||
&&OPCODE_SET_NAMED_VALIDATED, \
|
||||
&&OPCODE_GET_NAMED, \
|
||||
&&OPCODE_GET_NAMED_VALIDATED, \
|
||||
&&OPCODE_SET_MEMBER, \
|
||||
&&OPCODE_GET_MEMBER, \
|
||||
&&OPCODE_SET_STATIC_VARIABLE, \
|
||||
&&OPCODE_GET_STATIC_VARIABLE, \
|
||||
&&OPCODE_ASSIGN, \
|
||||
&&OPCODE_ASSIGN_TRUE, \
|
||||
&&OPCODE_ASSIGN_FALSE, \
|
||||
&&OPCODE_ASSIGN_TYPED_BUILTIN, \
|
||||
&&OPCODE_ASSIGN_TYPED_ARRAY, \
|
||||
&&OPCODE_ASSIGN_TYPED_NATIVE, \
|
||||
&&OPCODE_ASSIGN_TYPED_SCRIPT, \
|
||||
&&OPCODE_CAST_TO_BUILTIN, \
|
||||
&&OPCODE_CAST_TO_NATIVE, \
|
||||
&&OPCODE_CAST_TO_SCRIPT, \
|
||||
&&OPCODE_CONSTRUCT, \
|
||||
&&OPCODE_CONSTRUCT_VALIDATED, \
|
||||
&&OPCODE_CONSTRUCT_ARRAY, \
|
||||
&&OPCODE_CONSTRUCT_TYPED_ARRAY, \
|
||||
&&OPCODE_CONSTRUCT_DICTIONARY, \
|
||||
&&OPCODE_CALL, \
|
||||
&&OPCODE_CALL_RETURN, \
|
||||
&&OPCODE_CALL_ASYNC, \
|
||||
&&OPCODE_CALL_UTILITY, \
|
||||
&&OPCODE_CALL_UTILITY_VALIDATED, \
|
||||
&&OPCODE_CALL_GDSCRIPT_UTILITY, \
|
||||
&&OPCODE_CALL_BUILTIN_TYPE_VALIDATED, \
|
||||
&&OPCODE_CALL_SELF_BASE, \
|
||||
&&OPCODE_CALL_METHOD_BIND, \
|
||||
&&OPCODE_CALL_METHOD_BIND_RET, \
|
||||
&&OPCODE_CALL_BUILTIN_STATIC, \
|
||||
&&OPCODE_CALL_NATIVE_STATIC, \
|
||||
&&OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN, \
|
||||
&&OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN, \
|
||||
&&OPCODE_AWAIT, \
|
||||
&&OPCODE_AWAIT_RESUME, \
|
||||
&&OPCODE_CREATE_LAMBDA, \
|
||||
&&OPCODE_CREATE_SELF_LAMBDA, \
|
||||
&&OPCODE_JUMP, \
|
||||
&&OPCODE_JUMP_IF, \
|
||||
&&OPCODE_JUMP_IF_NOT, \
|
||||
&&OPCODE_JUMP_TO_DEF_ARGUMENT, \
|
||||
&&OPCODE_JUMP_IF_SHARED, \
|
||||
&&OPCODE_RETURN, \
|
||||
&&OPCODE_RETURN_TYPED_BUILTIN, \
|
||||
&&OPCODE_RETURN_TYPED_ARRAY, \
|
||||
&&OPCODE_RETURN_TYPED_NATIVE, \
|
||||
&&OPCODE_RETURN_TYPED_SCRIPT, \
|
||||
&&OPCODE_ITERATE_BEGIN, \
|
||||
&&OPCODE_ITERATE_BEGIN_INT, \
|
||||
&&OPCODE_ITERATE_BEGIN_FLOAT, \
|
||||
&&OPCODE_ITERATE_BEGIN_VECTOR2, \
|
||||
&&OPCODE_ITERATE_BEGIN_VECTOR2I, \
|
||||
&&OPCODE_ITERATE_BEGIN_VECTOR3, \
|
||||
&&OPCODE_ITERATE_BEGIN_VECTOR3I, \
|
||||
&&OPCODE_ITERATE_BEGIN_STRING, \
|
||||
&&OPCODE_ITERATE_BEGIN_DICTIONARY, \
|
||||
&&OPCODE_ITERATE_BEGIN_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_BYTE_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_INT32_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_INT64_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_FLOAT32_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_FLOAT64_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_STRING_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR2_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_VECTOR3_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_PACKED_COLOR_ARRAY, \
|
||||
&&OPCODE_ITERATE_BEGIN_OBJECT, \
|
||||
&&OPCODE_ITERATE, \
|
||||
&&OPCODE_ITERATE_INT, \
|
||||
&&OPCODE_ITERATE_FLOAT, \
|
||||
&&OPCODE_ITERATE_VECTOR2, \
|
||||
&&OPCODE_ITERATE_VECTOR2I, \
|
||||
&&OPCODE_ITERATE_VECTOR3, \
|
||||
&&OPCODE_ITERATE_VECTOR3I, \
|
||||
&&OPCODE_ITERATE_STRING, \
|
||||
&&OPCODE_ITERATE_DICTIONARY, \
|
||||
&&OPCODE_ITERATE_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_BYTE_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_INT32_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_INT64_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_FLOAT32_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_FLOAT64_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_STRING_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_VECTOR2_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_VECTOR3_ARRAY, \
|
||||
&&OPCODE_ITERATE_PACKED_COLOR_ARRAY, \
|
||||
&&OPCODE_ITERATE_OBJECT, \
|
||||
&&OPCODE_STORE_GLOBAL, \
|
||||
&&OPCODE_STORE_NAMED_GLOBAL, \
|
||||
&&OPCODE_TYPE_ADJUST_BOOL, \
|
||||
&&OPCODE_TYPE_ADJUST_INT, \
|
||||
&&OPCODE_TYPE_ADJUST_FLOAT, \
|
||||
&&OPCODE_TYPE_ADJUST_STRING, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR2, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR2I, \
|
||||
&&OPCODE_TYPE_ADJUST_RECT2, \
|
||||
&&OPCODE_TYPE_ADJUST_RECT2I, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR3, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR3I, \
|
||||
&&OPCODE_TYPE_ADJUST_TRANSFORM2D, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR4, \
|
||||
&&OPCODE_TYPE_ADJUST_VECTOR4I, \
|
||||
&&OPCODE_TYPE_ADJUST_PLANE, \
|
||||
&&OPCODE_TYPE_ADJUST_QUATERNION, \
|
||||
&&OPCODE_TYPE_ADJUST_AABB, \
|
||||
&&OPCODE_TYPE_ADJUST_BASIS, \
|
||||
&&OPCODE_TYPE_ADJUST_TRANSFORM3D, \
|
||||
&&OPCODE_TYPE_ADJUST_PROJECTION, \
|
||||
&&OPCODE_TYPE_ADJUST_COLOR, \
|
||||
&&OPCODE_TYPE_ADJUST_STRING_NAME, \
|
||||
&&OPCODE_TYPE_ADJUST_NODE_PATH, \
|
||||
&&OPCODE_TYPE_ADJUST_RID, \
|
||||
&&OPCODE_TYPE_ADJUST_OBJECT, \
|
||||
&&OPCODE_TYPE_ADJUST_CALLABLE, \
|
||||
&&OPCODE_TYPE_ADJUST_SIGNAL, \
|
||||
&&OPCODE_TYPE_ADJUST_DICTIONARY, \
|
||||
&&OPCODE_TYPE_ADJUST_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_BYTE_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_INT32_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_INT64_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_FLOAT32_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_FLOAT64_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_STRING_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR2_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_VECTOR3_ARRAY, \
|
||||
&&OPCODE_TYPE_ADJUST_PACKED_COLOR_ARRAY, \
|
||||
&&OPCODE_ASSERT, \
|
||||
&&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.");
|
||||
|
||||
#define OPCODE(m_op) \
|
||||
|
@ -489,7 +453,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
Variant retvalue;
|
||||
Variant *stack = nullptr;
|
||||
Variant **instruction_args = nullptr;
|
||||
const void **call_args_ptr = nullptr;
|
||||
int defarg = 0;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
@ -578,12 +541,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
}
|
||||
}
|
||||
|
||||
if (_ptrcall_args_size) {
|
||||
call_args_ptr = (const void **)alloca(_ptrcall_args_size * sizeof(void *));
|
||||
} else {
|
||||
call_args_ptr = nullptr;
|
||||
}
|
||||
|
||||
if (p_instance) {
|
||||
memnew_placement(&stack[ADDR_STACK_SELF], Variant(p_instance->owner));
|
||||
script = p_instance->script.ptr();
|
||||
|
@ -1954,106 +1911,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
}
|
||||
DISPATCH_OPCODE;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
#define OPCODE_CALL_PTR(m_type) \
|
||||
OPCODE(OPCODE_CALL_PTRCALL_##m_type) { \
|
||||
LOAD_INSTRUCTION_ARGS \
|
||||
CHECK_SPACE(3 + instr_arg_count); \
|
||||
ip += instr_arg_count; \
|
||||
int argc = _code_ptr[ip + 1]; \
|
||||
GD_ERR_BREAK(argc < 0); \
|
||||
GET_INSTRUCTION_ARG(base, argc); \
|
||||
GD_ERR_BREAK(_code_ptr[ip + 2] < 0 || _code_ptr[ip + 2] >= _methods_count); \
|
||||
MethodBind *method = _methods_ptr[_code_ptr[ip + 2]]; \
|
||||
bool freed = false; \
|
||||
Object *base_obj = base->get_validated_object_with_check(freed); \
|
||||
if (freed) { \
|
||||
err_text = METHOD_CALL_ON_FREED_INSTANCE_ERROR(method); \
|
||||
OPCODE_BREAK; \
|
||||
} else if (!base_obj) { \
|
||||
err_text = METHOD_CALL_ON_NULL_VALUE_ERROR(method); \
|
||||
OPCODE_BREAK; \
|
||||
} \
|
||||
const void **argptrs = call_args_ptr; \
|
||||
for (int i = 0; i < argc; i++) { \
|
||||
GET_INSTRUCTION_ARG(v, i); \
|
||||
argptrs[i] = VariantInternal::get_opaque_pointer((const Variant *)v); \
|
||||
} \
|
||||
uint64_t call_time = 0; \
|
||||
if (GDScriptLanguage::get_singleton()->profiling) { \
|
||||
call_time = OS::get_singleton()->get_ticks_usec(); \
|
||||
} \
|
||||
GET_INSTRUCTION_ARG(ret, argc + 1); \
|
||||
VariantInternal::initialize(ret, Variant::m_type); \
|
||||
void *ret_opaque = VariantInternal::OP_GET_##m_type(ret); \
|
||||
method->ptrcall(base_obj, argptrs, ret_opaque); \
|
||||
if (GDScriptLanguage::get_singleton()->profiling) { \
|
||||
function_call_time += OS::get_singleton()->get_ticks_usec() - call_time; \
|
||||
} \
|
||||
ip += 3; \
|
||||
} \
|
||||
DISPATCH_OPCODE
|
||||
#else
|
||||
#define OPCODE_CALL_PTR(m_type) \
|
||||
OPCODE(OPCODE_CALL_PTRCALL_##m_type) { \
|
||||
LOAD_INSTRUCTION_ARGS \
|
||||
CHECK_SPACE(3 + instr_arg_count); \
|
||||
ip += instr_arg_count; \
|
||||
int argc = _code_ptr[ip + 1]; \
|
||||
GET_INSTRUCTION_ARG(base, argc); \
|
||||
MethodBind *method = _methods_ptr[_code_ptr[ip + 2]]; \
|
||||
Object *base_obj = *VariantInternal::get_object(base); \
|
||||
const void **argptrs = call_args_ptr; \
|
||||
for (int i = 0; i < argc; i++) { \
|
||||
GET_INSTRUCTION_ARG(v, i); \
|
||||
argptrs[i] = VariantInternal::get_opaque_pointer((const Variant *)v); \
|
||||
} \
|
||||
GET_INSTRUCTION_ARG(ret, argc + 1); \
|
||||
VariantInternal::initialize(ret, Variant::m_type); \
|
||||
void *ret_opaque = VariantInternal::OP_GET_##m_type(ret); \
|
||||
method->ptrcall(base_obj, argptrs, ret_opaque); \
|
||||
ip += 3; \
|
||||
} \
|
||||
DISPATCH_OPCODE
|
||||
#endif
|
||||
|
||||
OPCODE_CALL_PTR(BOOL);
|
||||
OPCODE_CALL_PTR(INT);
|
||||
OPCODE_CALL_PTR(FLOAT);
|
||||
OPCODE_CALL_PTR(STRING);
|
||||
OPCODE_CALL_PTR(VECTOR2);
|
||||
OPCODE_CALL_PTR(VECTOR2I);
|
||||
OPCODE_CALL_PTR(RECT2);
|
||||
OPCODE_CALL_PTR(RECT2I);
|
||||
OPCODE_CALL_PTR(VECTOR3);
|
||||
OPCODE_CALL_PTR(VECTOR3I);
|
||||
OPCODE_CALL_PTR(TRANSFORM2D);
|
||||
OPCODE_CALL_PTR(VECTOR4);
|
||||
OPCODE_CALL_PTR(VECTOR4I);
|
||||
OPCODE_CALL_PTR(PLANE);
|
||||
OPCODE_CALL_PTR(QUATERNION);
|
||||
OPCODE_CALL_PTR(AABB);
|
||||
OPCODE_CALL_PTR(BASIS);
|
||||
OPCODE_CALL_PTR(TRANSFORM3D);
|
||||
OPCODE_CALL_PTR(PROJECTION);
|
||||
OPCODE_CALL_PTR(COLOR);
|
||||
OPCODE_CALL_PTR(STRING_NAME);
|
||||
OPCODE_CALL_PTR(NODE_PATH);
|
||||
OPCODE_CALL_PTR(RID);
|
||||
OPCODE_CALL_PTR(CALLABLE);
|
||||
OPCODE_CALL_PTR(SIGNAL);
|
||||
OPCODE_CALL_PTR(DICTIONARY);
|
||||
OPCODE_CALL_PTR(ARRAY);
|
||||
OPCODE_CALL_PTR(PACKED_BYTE_ARRAY);
|
||||
OPCODE_CALL_PTR(PACKED_INT32_ARRAY);
|
||||
OPCODE_CALL_PTR(PACKED_INT64_ARRAY);
|
||||
OPCODE_CALL_PTR(PACKED_FLOAT32_ARRAY);
|
||||
OPCODE_CALL_PTR(PACKED_FLOAT64_ARRAY);
|
||||
OPCODE_CALL_PTR(PACKED_STRING_ARRAY);
|
||||
OPCODE_CALL_PTR(PACKED_VECTOR2_ARRAY);
|
||||
OPCODE_CALL_PTR(PACKED_VECTOR3_ARRAY);
|
||||
OPCODE_CALL_PTR(PACKED_COLOR_ARRAY);
|
||||
OPCODE(OPCODE_CALL_PTRCALL_OBJECT) {
|
||||
OPCODE(OPCODE_CALL_METHOD_BIND_VALIDATED_RETURN) {
|
||||
LOAD_INSTRUCTION_ARGS
|
||||
CHECK_SPACE(3 + instr_arg_count);
|
||||
|
||||
|
@ -2066,6 +1924,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
MethodBind *method = _methods_ptr[_code_ptr[ip + 2]];
|
||||
|
||||
GET_INSTRUCTION_ARG(base, argc);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
bool freed = false;
|
||||
Object *base_obj = base->get_validated_object_with_check(freed);
|
||||
|
@ -2080,12 +1939,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
Object *base_obj = *VariantInternal::get_object(base);
|
||||
#endif
|
||||
|
||||
const void **argptrs = call_args_ptr;
|
||||
Variant **argptrs = instruction_args;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
GET_INSTRUCTION_ARG(v, i);
|
||||
argptrs[i] = VariantInternal::get_opaque_pointer((const Variant *)v);
|
||||
}
|
||||
#ifdef DEBUG_ENABLED
|
||||
uint64_t call_time = 0;
|
||||
|
||||
|
@ -2095,16 +1950,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
#endif
|
||||
|
||||
GET_INSTRUCTION_ARG(ret, argc + 1);
|
||||
VariantInternal::initialize(ret, Variant::OBJECT);
|
||||
Object **ret_opaque = VariantInternal::get_object(ret);
|
||||
method->ptrcall(base_obj, argptrs, ret_opaque);
|
||||
if (method->is_return_type_raw_object_ptr()) {
|
||||
// The Variant has to participate in the ref count since the method returns a raw Object *.
|
||||
VariantInternal::object_assign(ret, *ret_opaque);
|
||||
} else {
|
||||
// The method, in case it returns something, returns an already encapsulated object.
|
||||
VariantInternal::update_object_id(ret);
|
||||
}
|
||||
method->validated_call(base_obj, (const Variant **)argptrs, ret);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (GDScriptLanguage::get_singleton()->profiling) {
|
||||
|
@ -2114,7 +1960,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
ip += 3;
|
||||
}
|
||||
DISPATCH_OPCODE;
|
||||
OPCODE(OPCODE_CALL_PTRCALL_NO_RETURN) {
|
||||
|
||||
OPCODE(OPCODE_CALL_METHOD_BIND_VALIDATED_NO_RETURN) {
|
||||
LOAD_INSTRUCTION_ARGS
|
||||
CHECK_SPACE(3 + instr_arg_count);
|
||||
|
||||
|
@ -2140,12 +1987,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
#else
|
||||
Object *base_obj = *VariantInternal::get_object(base);
|
||||
#endif
|
||||
const void **argptrs = call_args_ptr;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
GET_INSTRUCTION_ARG(v, i);
|
||||
argptrs[i] = VariantInternal::get_opaque_pointer((const Variant *)v);
|
||||
}
|
||||
Variant **argptrs = instruction_args;
|
||||
#ifdef DEBUG_ENABLED
|
||||
uint64_t call_time = 0;
|
||||
|
||||
|
@ -2156,7 +1998,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
|
|||
|
||||
GET_INSTRUCTION_ARG(ret, argc + 1);
|
||||
VariantInternal::initialize(ret, Variant::NIL);
|
||||
method->ptrcall(base_obj, argptrs, nullptr);
|
||||
method->validated_call(base_obj, (const Variant **)argptrs, nullptr);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (GDScriptLanguage::get_singleton()->profiling) {
|
||||
|
|
|
@ -7,7 +7,7 @@ func test():
|
|||
test_builtin_call_validated(Vector2.UP, false)
|
||||
test_object_call(RefCounted.new(), false)
|
||||
test_object_call_method_bind(Resource.new(), false)
|
||||
test_object_call_ptrcall(RefCounted.new(), false)
|
||||
test_object_call_method_bind_validated(RefCounted.new(), false)
|
||||
|
||||
print("end")
|
||||
|
||||
|
@ -40,7 +40,7 @@ func test_object_call_method_bind(v: Resource, f):
|
|||
v.duplicate() # Native type method call with MethodBind.
|
||||
assert(not f) # Test unary operator reading from `nil`.
|
||||
|
||||
func test_object_call_ptrcall(v: RefCounted, f):
|
||||
func test_object_call_method_bind_validated(v: RefCounted, f):
|
||||
@warning_ignore("return_value_discarded")
|
||||
v.get_reference_count() # Native type method call with ptrcall.
|
||||
v.get_reference_count() # Native type method call with validated MethodBind.
|
||||
assert(not f) # Test unary operator reading from `nil`.
|
||||
|
|
Loading…
Reference in a new issue