# File lib/sass/script/funcall.rb, line 92
      def _perform(environment)
        args = @args.map {|a| a.perform(environment)}
        splat = @splat.perform(environment) if @splat
        if fn = environment.function(@name)
          keywords = Sass::Util.map_hash(@keywords) {|k, v| [k, v.perform(environment)]}
          return perform_sass_fn(fn, args, keywords, splat)
        end

        ruby_name = @name.tr('-', '_')
        args = construct_ruby_args(ruby_name, args, splat, environment)

        unless Functions.callable?(ruby_name)
          opts(to_literal(args))
        else
          opts(Functions::EvaluationContext.new(environment.options).send(ruby_name, *args))
        end
      rescue ArgumentError => e
        message = e.message

        # If this is a legitimate Ruby-raised argument error, re-raise it.
        # Otherwise, it's an error in the user's stylesheet, so wrap it.
        if Sass::Util.rbx?
          # Rubinius has a different error report string than vanilla Ruby. It
          # also doesn't put the actual method for which the argument error was
          # thrown in the backtrace, nor does it include `send`, so we look for
          # `_perform`.
          if e.message =~ /^method '([^']+)': given (\d+), expected (\d+)/
            error_name, given, expected = $1, $2, $3
            raise e if error_name != ruby_name || e.backtrace[0] !~ /:in `_perform'$/
            message = "wrong number of arguments (#{given} for #{expected})"
          end
        elsif Sass::Util.jruby?
          if Sass::Util.jruby1_6?
            should_maybe_raise = e.message =~ /^wrong number of arguments \((\d+) for (\d+)\)/ &&
              # The one case where JRuby does include the Ruby name of the function
              # is manually-thrown ArgumentErrors, which are indistinguishable from
              # legitimate ArgumentErrors. We treat both of these as
              # Sass::SyntaxErrors even though it can hide Ruby errors.
              e.backtrace[0] !~ /:in `(block in )?#{ruby_name}'$/
          else
            should_maybe_raise = e.message =~ /^wrong number of arguments calling `[^`]+` \((\d+) for (\d+)\)/
            given, expected = $1, $2
          end

          if should_maybe_raise
            # JRuby 1.7 includes __send__ before send and _perform.
            trace = e.backtrace.dup
            raise e if !Sass::Util.jruby1_6? && trace.shift !~ /:in `__send__'$/

            # JRuby (as of 1.7.2) doesn't put the actual method
            # for which the argument error was thrown in the backtrace, so we
            # detect whether our send threw an argument error.
            if !(trace[0] =~ /:in `send'$/ && trace[1] =~ /:in `_perform'$/)
              raise e
            elsif !Sass::Util.jruby1_6?
              # JRuby 1.7 doesn't use standard formatting for its ArgumentErrors.
              message = "wrong number of arguments (#{given} for #{expected})"
            end
          end
        elsif e.message =~ /^wrong number of arguments \(\d+ for \d+\)/ &&
            e.backtrace[0] !~ /:in `(block in )?#{ruby_name}'$/
          raise e
        end
        raise Sass::SyntaxError.new("#{message} for `#{name}'")
      end