diff --git a/spec/ruby/core/exception/arguments_spec.rb b/spec/ruby/core/exception/arguments_spec.rb
index 47c4339e2d..b9f3a3f27b 100644
--- a/spec/ruby/core/exception/arguments_spec.rb
+++ b/spec/ruby/core/exception/arguments_spec.rb
@@ -1,6 +1,14 @@
 require File.expand_path('../../../spec_helper', __FILE__)
 
 describe "ArgumentError" do
+  class ArgumentErrorDummyClass
+    def foo(a,b,c:)
+    end
+
+    def foo_kw(a:)
+    end
+  end
+
   it "is a subclass of StandardError" do
     StandardError.should be_ancestor_of(ArgumentError)
   end
@@ -8,4 +16,32 @@
   it "gives its own class name as message if it has no message" do
     ArgumentError.new.message.should == "ArgumentError"
   end
+
+  describe "arity error" do
+    it "includes receiver and method name when raised by application code" do
+      exc = begin
+        ArgumentErrorDummyClass.new.foo(3)
+      rescue => exc
+        exc
+      end
+
+      exc.instance_variable_get('@receiver').should_not be_nil
+      exc.instance_variable_get('@receiver').should.class === ArgumentErrorDummyClass
+      exc.instance_variable_get('@method_name').should == 'foo'
+    end
+  end
+
+  describe "kw error" do
+    it "includes receiver and method name when raised by application code" do
+      exc = begin
+        ArgumentErrorDummyClass.new.foo_kw()
+      rescue => exc
+        exc
+      end
+
+      exc.instance_variable_get('@receiver').should_not be_nil
+      exc.instance_variable_get('@receiver').should.class === ArgumentErrorDummyClass
+      exc.instance_variable_get('@method_name').should == 'foo'
+    end
+  end
 end
diff --git a/vm_args.c b/vm_args.c
index 997b0b2f48..5ec9f85076 100644
--- a/vm_args.c
+++ b/vm_args.c
@@ -9,8 +9,8 @@
 **********************************************************************/
 
 NORETURN(static void raise_argument_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const VALUE exc));
-NORETURN(static void argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc));
-NORETURN(static void argument_kw_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const char *error, const VALUE keys));
+NORETURN(static void argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_calling_info *calling, const int miss_argc, const int min_argc, const int max_argc));
+NORETURN(static void argument_kw_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_calling_info *calling, const char *error, const VALUE keys));
 VALUE rb_keyword_error_new(const char *error, VALUE keys); /* class.c */
 static VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv,
 			    enum method_missing_reason call_status);
@@ -394,7 +394,8 @@ args_setup_kw_parameters_lookup(const ID key, VALUE *ptr, const VALUE *const pas
 
 static void
 args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *const iseq,
-			 VALUE *const passed_values, const int passed_keyword_len, const VALUE *const passed_keywords,
+			 struct rb_calling_info *calling, VALUE *const passed_values,
+			 const int passed_keyword_len, const VALUE *const passed_keywords,
 			 VALUE *const locals)
 {
     const ID *acceptable_keywords = iseq->body->param.keyword->table;
@@ -417,7 +418,7 @@ args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *cons
 	}
     }
 
-    if (missing) argument_kw_error(ec, iseq, "missing", missing);
+    if (missing) argument_kw_error(ec, iseq, calling, "missing", missing);
 
     for (di=0; i<key_num; i++, di++) {
 	if (args_setup_kw_parameters_lookup(acceptable_keywords[i], &locals[i], passed_keywords, passed_values, passed_keyword_len)) {
@@ -458,7 +459,7 @@ args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *cons
     else {
 	if (found != passed_keyword_len) {
 	    VALUE keys = make_unknown_kw_hash(passed_keywords, passed_keyword_len, passed_values);
-	    argument_kw_error(ec, iseq, "unknown", keys);
+	    argument_kw_error(ec, iseq, calling, "unknown", keys);
 	}
     }
 
@@ -593,7 +594,7 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
 		args_extend(args, min_argc);
 	    }
 	    else {
-		argument_arity_error(ec, iseq, given_argc, min_argc, max_argc);
+		argument_arity_error(ec, iseq, calling, given_argc, min_argc, max_argc);
 	    }
 	}
     }
@@ -615,7 +616,7 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
 	    given_argc = max_argc;
 	}
 	else {
-	    argument_arity_error(ec, iseq, given_argc, min_argc, max_argc);
+	    argument_arity_error(ec, iseq, calling, given_argc, min_argc, max_argc);
 	}
     }
 
@@ -641,7 +642,7 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
 
 	if (args->kw_argv != NULL) {
 	    const struct rb_call_info_kw_arg *kw_arg = args->kw_arg;
-	    args_setup_kw_parameters(ec, iseq, args->kw_argv, kw_arg->keyword_len, kw_arg->keywords, klocals);
+	    args_setup_kw_parameters(ec, iseq, calling, args->kw_argv, kw_arg->keyword_len, kw_arg->keywords, klocals);
 	}
 	else if (!NIL_P(keyword_hash)) {
 	    int kw_len = rb_long2int(RHASH_SIZE(keyword_hash));
@@ -652,18 +653,18 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
 	    arg.argc = 0;
 	    rb_hash_foreach(keyword_hash, fill_keys_values, (VALUE)&arg);
 	    VM_ASSERT(arg.argc == kw_len);
-	    args_setup_kw_parameters(ec, iseq, arg.vals, kw_len, arg.keys, klocals);
+	    args_setup_kw_parameters(ec, iseq, calling, arg.vals, kw_len, arg.keys, klocals);
 	}
 	else {
 	    VM_ASSERT(args_argc(args) == 0);
-	    args_setup_kw_parameters(ec, iseq, NULL, 0, NULL, klocals);
+	    args_setup_kw_parameters(ec, iseq, calling, NULL, 0, NULL, klocals);
 	}
     }
     else if (iseq->body->param.flags.has_kwrest) {
 	args_setup_kw_rest_parameter(keyword_hash, locals + iseq->body->param.keyword->rest_start);
     }
     else if (!NIL_P(keyword_hash) && RHASH_SIZE(keyword_hash) > 0) {
-	argument_kw_error(ec, iseq, "unknown", rb_hash_keys(keyword_hash));
+	argument_kw_error(ec, iseq, calling, "unknown", rb_hash_keys(keyword_hash));
     }
 
     if (iseq->body->param.flags.has_block) {
@@ -714,7 +715,9 @@ raise_argument_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const VA
 }
 
 static void
-argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc)
+argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq,
+		     struct rb_calling_info *calling,
+		     const int miss_argc, const int min_argc, const int max_argc)
 {
     VALUE exc = rb_arity_error_new(miss_argc, min_argc, max_argc);
     if (iseq->body->param.flags.has_kw) {
@@ -735,13 +738,21 @@ argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const in
 	    RSTRING_PTR(mesg)[RSTRING_LEN(mesg)-1] = ')';
 	}
     }
+
+    rb_iv_set(exc, "@receiver", calling->recv);
+    rb_iv_set(exc, "@method_name", rb_iseq_method_name(iseq));
     raise_argument_error(ec, iseq, exc);
 }
 
 static void
-argument_kw_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const char *error, const VALUE keys)
+argument_kw_error(rb_execution_context_t *ec, const rb_iseq_t *iseq,
+		  struct rb_calling_info *calling, const char *error,
+		  const VALUE keys)
 {
-    raise_argument_error(ec, iseq, rb_keyword_error_new(error, keys));
+    VALUE exc = rb_keyword_error_new(error, keys);
+    rb_iv_set(exc, "@receiver", calling->recv);
+    rb_iv_set(exc, "@method_name", rb_iseq_method_name(iseq));
+    raise_argument_error(ec, iseq, exc);
 }
 
 static inline void
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 9a2f3cb2d9..d569d03fb1 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1608,7 +1608,7 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
 	CALLER_SETUP_ARG(cfp, calling, ci); /* splat arg */
 
 	if (calling->argc != iseq->body->param.lead_num) {
-	    argument_arity_error(ec, iseq, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
+	    argument_arity_error(ec, iseq, calling, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
 	}
 
 	CI_SET_FASTPATH(cc, vm_call_iseq_setup_func(ci, param_size, local_size),
@@ -2593,7 +2593,7 @@ vm_callee_setup_block_arg(rb_execution_context_t *ec, struct rb_calling_info *ca
 		}
 	    }
 	    else {
-		argument_arity_error(ec, iseq, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
+		argument_arity_error(ec, iseq, calling, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
 	    }
 	}
 
