MCPcopy Create free account
hub / github.com/Redot-Engine/redot-engine / OPCODE

Function OPCODE

modules/gdscript/gdscript_vm.cpp:756–840  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

754
755 OPCODE_SWITCH(_code_ptr[ip]) {
756 OPCODE(OPCODE_OPERATOR) {
757 constexpr int _pointer_size = sizeof(Variant::ValidatedOperatorEvaluator) / sizeof(*_code_ptr);
758 CHECK_SPACE(7 + _pointer_size);
759
760 bool valid;
761 Variant::Operator op = (Variant::Operator)_code_ptr[ip + 4];
762 GD_ERR_BREAK(op >= Variant::OP_MAX);
763
764 GET_VARIANT_PTR(a, 0);
765 GET_VARIANT_PTR(b, 1);
766 GET_VARIANT_PTR(dst, 2);
767 // Compute signatures (types of operands) so it can be optimized when matching.
768 uint32_t op_signature = _code_ptr[ip + 5];
769 uint32_t actual_signature = (a->get_type() << 8) | (b->get_type());
770
771#ifdef DEBUG_ENABLED
772 if (op == Variant::OP_DIVIDE || op == Variant::OP_MODULE) {
773 // Don't optimize division and modulo since there's not check for division by zero with validated calls.
774 op_signature = 0xFFFF;
775 _code_ptr[ip + 5] = op_signature;
776 }
777#endif
778
779 // Check if this is the first run. If so, store the current signature for the optimized path.
780 if (unlikely(op_signature == 0)) {
781 static Mutex initializer_mutex;
782 initializer_mutex.lock();
783 Variant::Type a_type = (Variant::Type)((actual_signature >> 8) & 0xFF);
784 Variant::Type b_type = (Variant::Type)(actual_signature & 0xFF);
785
786 Variant::ValidatedOperatorEvaluator op_func = Variant::get_validated_operator_evaluator(op, a_type, b_type);
787
788 if (unlikely(!op_func)) {
789#ifdef DEBUG_ENABLED
790 err_text = "Invalid operands '" + Variant::get_type_name(a->get_type()) + "' and '" + Variant::get_type_name(b->get_type()) + "' in operator '" + Variant::get_operator_name(op) + "'.";
791#endif
792 initializer_mutex.unlock();
793 OPCODE_BREAK;
794 } else {
795 Variant::Type ret_type = Variant::get_operator_return_type(op, a_type, b_type);
796 VariantInternal::initialize(dst, ret_type);
797 op_func(a, b, dst);
798
799 // Check again in case another thread already set it.
800 if (_code_ptr[ip + 5] == 0) {
801 _code_ptr[ip + 5] = actual_signature;
802 _code_ptr[ip + 6] = static_cast<int>(ret_type);
803 Variant::ValidatedOperatorEvaluator *tmp = reinterpret_cast<Variant::ValidatedOperatorEvaluator *>(&_code_ptr[ip + 7]);
804 *tmp = op_func;
805 }
806 }
807 initializer_mutex.unlock();
808 } else if (likely(op_signature == actual_signature)) {
809 // If the signature matches, we can use the optimized path.
810 Variant::Type ret_type = static_cast<Variant::Type>(_code_ptr[ip + 6]);
811 Variant::ValidatedOperatorEvaluator op_func = *reinterpret_cast<Variant::ValidatedOperatorEvaluator *>(&_code_ptr[ip + 7]);
812
813 // Make sure the return value has the correct type.

Callers 1

gdscript_vm.cppFile · 0.85

Calls 15

initializeFunction · 0.85
_get_var_typeFunction · 0.85
vformatFunction · 0.85
_get_element_typeFunction · 0.85
_profile_count_as_nativeFunction · 0.85
get_typed_builtinMethod · 0.80
get_typed_class_nameMethod · 0.80
get_typed_scriptMethod · 0.80
get_typed_key_builtinMethod · 0.80

Tested by

no test coverage detected