def self.create_validator_procedure_fast4(mod, original_method, method_sig,
def self.create_validator_procedure_fast4(mod, original_method, method_sig,
arg0_type, arg1_type, arg2_type, arg3_type)
mod.send(:define_method, method_sig.method_name) do |arg0, arg1, arg2, arg3, &blk|
# This block is called for every `sig`. It's critical to keep it fast and
# reduce number of allocations that happen here.
# This method is a manually sped-up version of more general code in `validate_call`
T::Profile.typecheck_sample_attempts -= 1
should_sample = T::Profile.typecheck_sample_attempts == 0
if should_sample
T::Profile.typecheck_sample_attempts = T::Profile::SAMPLE_RATE
T::Profile.typecheck_samples += 1
t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
end
if method_sig.bind
message = method_sig.bind.error_message_for_obj(self)
if message
CallValidation.report_error(
method_sig,
message,
'Bind',
nil,
method_sig.bind,
self
)
end
end
unless arg0.is_a?(arg0_type)
CallValidation.report_error(
method_sig,
method_sig.arg_types[0][1].error_message_for_obj(arg0),
'Parameter',
method_sig.arg_types[0][0],
arg0_type,
arg0,
caller_offset: -1
)
end
unless arg1.is_a?(arg1_type)
CallValidation.report_error(
method_sig,
method_sig.arg_types[1][1].error_message_for_obj(arg1),
'Parameter',
method_sig.arg_types[1][0],
arg1_type,
arg1,
caller_offset: -1
)
end
unless arg2.is_a?(arg2_type)
CallValidation.report_error(
method_sig,
method_sig.arg_types[2][1].error_message_for_obj(arg2),
'Parameter',
method_sig.arg_types[2][0],
arg2_type,
arg2,
caller_offset: -1
)
end
unless arg3.is_a?(arg3_type)
CallValidation.report_error(
method_sig,
method_sig.arg_types[3][1].error_message_for_obj(arg3),
'Parameter',
method_sig.arg_types[3][0],
arg3_type,
arg3,
caller_offset: -1
)
end
if should_sample
T::Profile.typecheck_duration += (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t1)
end
# The following line breaks are intentional to show nice pry message
# PRY note:
# this code is sig validation code.
# Please issue `finish` to step out of it
original_method.bind(self).call(arg0, arg1, arg2, arg3, &blk)
T::Private::Types::Void::VOID
end
end