This assumes that operators are called usually with the same type of
operands as the first time. So it stores the types of the first run and
if matched it uses an optimized path by calling the validated operator
function directly. Otherwise it uses the regular untyped evaluator.
With this change, if operators do use the same type they run quite
faster. OTOH, if the types mismatch it takes longer to run than they
would with the previous code.
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)+"'.";
// Make sure the return value has the correct type.
VariantInternal::initialize(dst,ret_type);
op_func(a,b,dst);
}else{
// If the signature doesn't match, we have to use the slow path.
#ifdef DEBUG_ENABLED
Variantret;
Variant::evaluate(op,*a,*b,ret,valid);
Variantret;
Variant::evaluate(op,*a,*b,ret,valid);
#else
Variant::evaluate(op,*a,*b,*dst,valid);
Variant::evaluate(op,*a,*b,*dst,valid);
#endif
#ifdef DEBUG_ENABLED
if(!valid){
if(ret.get_type()==Variant::STRING){
//return a string when invalid with the error
err_text=ret;
err_text+=" in operator '"+Variant::get_operator_name(op)+"'.";
}else{
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)+"'.";
if(!valid){
if(ret.get_type()==Variant::STRING){
//return a string when invalid with the error
err_text=ret;
err_text+=" in operator '"+Variant::get_operator_name(op)+"'.";
}else{
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)+"'.";