bool tracerPhpPartInternalFuncCallPreHook()

in agent/native/ext/tracer_PHP_part.cpp [197:260]


bool tracerPhpPartInternalFuncCallPreHook( uint32_t interceptRegistrationId, zend_execute_data* execute_data )
{
    ELASTIC_APM_LOG_TRACE_FUNCTION_ENTRY_MSG( "interceptRegistrationId: %u", interceptRegistrationId );

    ResultCode resultCode;
    zval preHookRetVal;
    ZVAL_UNDEF( &preHookRetVal );
    bool shouldCallPostHook = false;
    zval interceptRegistrationIdAsZval;
    ZVAL_UNDEF( &interceptRegistrationIdAsZval );
    zval phpPartArgs[ g_maxInterceptedCallArgsCount + 2 ];

    if (!canInvokeTracerPhpPart()) {
        if (switchTracerPhpPartStateToFailed( /* reason */ "Unexpected current tracer PHP part state", __FUNCTION__ )) {
            ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE();
        } else {
            ELASTIC_APM_SET_RESULT_CODE_TO_SUCCESS_AND_GOTO_FINALLY();
        }
    }

    // The first argument to PHP part's interceptedCallPreHook() is $interceptRegistrationId
    ZVAL_LONG( &interceptRegistrationIdAsZval, interceptRegistrationId );
    phpPartArgs[ 0 ] = interceptRegistrationIdAsZval;

    // The second argument to PHP part's interceptedCallPreHook() is $thisObj
    if ( Z_TYPE( execute_data->This ) == IS_UNDEF )
    {
        ZVAL_NULL( &phpPartArgs[ 1 ] );
    }
    else
    {
        phpPartArgs[ 1 ] = execute_data->This;
    }

    uint32_t interceptedCallArgsCount;
    getArgsFromZendExecuteData( execute_data, g_maxInterceptedCallArgsCount, &( phpPartArgs[ 2 ] ), &interceptedCallArgsCount );
    ELASTIC_APM_CALL_IF_FAILED_GOTO(
            callPhpFunctionRetZval(
                    ELASTIC_APM_STRING_LITERAL_TO_VIEW( ELASTIC_APM_PHP_PART_INTERNAL_FUNC_CALL_PRE_HOOK_FUNC )
                    , interceptedCallArgsCount + 2
                    , phpPartArgs
                    , /* out */ &preHookRetVal ) );
    ELASTIC_APM_LOG_TRACE( "Successfully finished call to PHP part. Return value type: %u", Z_TYPE_P( &preHookRetVal ) );

    if ( Z_TYPE( preHookRetVal ) != IS_FALSE && Z_TYPE( preHookRetVal ) != IS_TRUE )
    {
        ELASTIC_APM_LOG_ERROR( "Call to PHP part returned value that is not bool. Return value type: %u", Z_TYPE_P( &preHookRetVal ) );
        ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE();
    }
    shouldCallPostHook = ( Z_TYPE( preHookRetVal ) == IS_TRUE );

    resultCode = resultSuccess;

    finally:
    zval_dtor( &interceptRegistrationIdAsZval );

    ELASTIC_APM_LOG_TRACE_RESULT_CODE_FUNCTION_EXIT();
    ELASTIC_APM_UNUSED( resultCode );
    return shouldCallPostHook;

    failure:
    switchTracerPhpPartStateToFailed( /* reason */ "Failed to call tracer PHP part", __FUNCTION__ );
    goto finally;
}