Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implement Object#send and fix tr_send usage on method w/ variadic arg…

…uments.
  • Loading branch information...
commit c64c60b0d88475a9c8e073ea4314cfb0d12bbb47 1 parent 588445f
@macournoyer macournoyer authored
View
6 test/pending/raise_with_type.rb → test/raise_with_type.rb
@@ -10,6 +10,6 @@ def deep_in
puts "oh no boy, ur not coming here!"
# => ArgumentError: ouch!
-# => from test/raise.rb:2:in `guacamole'
-# => from test/raise.rb:6:in `deep_in'
-# => from test/raise.rb:10
+# => from test/raise_with_type.rb:2:in `guacamole'
+# => from test/raise_with_type.rb:6:in `deep_in'
+# => from test/raise_with_type.rb:10
View
10 test/send.rb
@@ -1,4 +1,6 @@
-puts :ohaie
-# => ohaie
-puts :ohaie.to_s.to_s
-# => ohaie
+puts 1.send(:to_s)
+# => 1
+
+send :puts, 2, "cheezburgers"
+# => 2
+# => cheezburgers
View
9 vm/object.c
@@ -1,5 +1,6 @@
#include "tr.h"
#include "internal.h"
+#include "call.h"
OBJ TrObject_alloc(VM, OBJ class) {
TrObject *o = TR_INIT_CORE_OBJECT(Object);
@@ -28,6 +29,13 @@ OBJ TrObject_lookup(VM, OBJ self, OBJ name) {
return method;
}
+OBJ TrObject_send(VM, OBJ self, int argc, OBJ argv[]) {
+ if (unlikely(argc == 0))
+ tr_raise(ArgumentError, "wrong number of arguments (%d for 1)", argc);
+ OBJ method = TrObject_lookup(vm, self, argv[0]);
+ return TrMethod_call(vm, method, self, argc-1, argv+1, 0, 0);
+}
+
/* TODO respect namespace */
OBJ TrObject_const_get(VM, OBJ self, OBJ name) {
UNUSED(self);
@@ -87,6 +95,7 @@ void TrObject_init(VM) {
OBJ c = TR_CORE_CLASS(Object);
tr_def(c, "class", TrObject_class, 0);
tr_def(c, "method", TrObject_method, 1);
+ tr_def(c, "send", TrObject_send, -1);
tr_def(c, "object_id", TrObject_object_id, 0);
tr_def(c, "instance_eval", TrObject_instance_eval, 1);
tr_def(c, "to_s", TrObject_inspect, 0);
View
8 vm/tr.h
@@ -132,11 +132,10 @@
#define tr_metadef(O,N,F,A) TrObject_add_singleton_method(vm, (O), tr_intern(N), TrMethod_new(vm, (TrFunc *)(F), TR_NIL, (A)))
#define tr_defclass(N,S) TrObject_const_set(vm, vm->self, tr_intern(N), TrClass_new(vm, tr_intern(N), S))
#define tr_defmodule(N) TrObject_const_set(vm, vm->self, tr_intern(N), TrModule_new(vm, tr_intern(N)))
+
#define tr_send(R,MSG,...) ({ \
- TrMethod *m = TR_CMETHOD(TrObject_method(vm, R, (MSG))); \
- if (!m) tr_raise(NoMethodError, "Method not found: %s", TR_STR_PTR(MSG)); \
- FRAME->method = m; \
- m->func(vm, R, ##__VA_ARGS__); \
+ OBJ __argv[] = { (MSG), ##__VA_ARGS__ }; \
+ TrObject_send(vm, R, sizeof(__argv)/sizeof(OBJ), __argv); \
})
#define tr_send2(R,STR,...) tr_send((R), tr_intern(STR), ##__VA_ARGS__)
@@ -344,6 +343,7 @@ OBJ TrObject_alloc(VM, OBJ class);
int TrObject_type(VM, OBJ obj);
OBJ TrObject_method(VM, OBJ self, OBJ name);
OBJ TrObject_lookup(VM, OBJ self, OBJ name);
+OBJ TrObject_send(VM, OBJ self, int argc, OBJ argv[]);
OBJ TrObject_const_set(VM, OBJ self, OBJ name, OBJ value);
OBJ TrObject_const_get(VM, OBJ self, OBJ name);
OBJ TrObject_add_singleton_method(VM, OBJ self, OBJ name, OBJ method);
Please sign in to comment.
Something went wrong with that request. Please try again.