Skip to content
Browse files

add implementation of MRI rb_call_super() method (note: untested)

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@4844 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
1 parent 25a8c49 commit fa6ceeb5bb844a8b2849220028507915601720f6 Laurent Sansonetti committed Oct 28, 2010
Showing with 46 additions and 2 deletions.
  1. +14 −1 compiler.cpp
  2. +1 −0 compiler.h
  3. +24 −0 dispatcher.cpp
  4. +2 −0 vm.cpp
  5. +5 −1 vm.h
View
15 compiler.cpp
@@ -270,6 +270,7 @@ RoxorCompiler::RoxorCompiler(bool _debug_mode)
rvalToSelFunc = get_function("vm_rval_to_sel");
rvalToCharPtrFunc = get_function("vm_rval_to_charptr");
initBlockFunc = get_function("vm_init_c_block");
+ setCurrentMRIMethodContext = NULL;
VoidTy = Type::getVoidTy(context);
Int1Ty = Type::getInt1Ty(context);
@@ -6569,7 +6570,19 @@ RoxorCompiler::compile_mri_stub(void *imp, const int arity)
bb = BasicBlock::Create(context, "EntryBlock", f);
Function::arg_iterator arg = f->arg_begin();
Value *rcv = arg++;
- arg++; // skip SEL
+ Value *sel = arg++;
+
+ // Register the receiver and selector to the VM (for rb_call_super()).
+ if (setCurrentMRIMethodContext == NULL) {
+ // void rb_vm_prepare_method(Class klass, unsigned char dynamic_class,
+ // SEL sel, Function *func, rb_vm_arity_t arity, int flags)
+ setCurrentMRIMethodContext =
+ cast<Function>(module->getOrInsertFunction(
+ "rb_vm_set_current_mri_method_context",
+ VoidTy, RubyObjTy, Int8Ty, NULL));
+ }
+ Value *args[2] = { rcv, sel };
+ CallInst::Create(setCurrentMRIMethodContext, args, args + 2, "", bb);
// Prepare function types for the MRI implementation and arguments.
std::vector<const Type *> imp_types;
View
1 compiler.h
@@ -259,6 +259,7 @@ class RoxorCompiler {
Function *rvalToSelFunc;
Function *rvalToCharPtrFunc;
Function *initBlockFunc;
+ Function *setCurrentMRIMethodContext;
Constant *zeroVal;
Constant *oneVal;
View
24 dispatcher.cpp
@@ -1586,4 +1586,28 @@ rb_vm_respond_to2(VALUE obj, VALUE klass, SEL sel, bool priv,
bool check_override)
{
return respond_to(obj, klass, sel, priv, check_override);
+}
+
+// Note: rb_call_super() MUST always be called from methods registered using
+// the MRI API (such as rb_define_method() & friends). It must NEVER be used
+// internally inside MacRuby core.
+extern "C"
+VALUE
+rb_call_super(int argc, const VALUE *argv)
+{
+ RoxorVM *vm = GET_VM();
+ VALUE self = vm->get_current_mri_method_self();
+ SEL sel = vm->get_current_mri_method_sel();
+ assert(self != 0 && sel != 0);
+
+ return rb_vm_call_super(self, sel, argc, argv);
+}
+
+extern "C"
+void
+rb_vm_set_current_mri_method_context(VALUE self, SEL sel)
+{
+ RoxorVM *vm = GET_VM();
+ vm->set_current_mri_method_self(self);
+ vm->set_current_mri_method_sel(sel);
}
View
2 vm.cpp
@@ -401,6 +401,8 @@ RoxorVM::RoxorVM(void)
special_exc = NULL;
current_super_class = NULL;
current_super_sel = 0;
+ current_mri_method_self = Qnil;
+ current_mri_method_sel = 0;
mcache = (struct mcache *)calloc(VM_MCACHE_SIZE, sizeof(struct mcache));
assert(mcache != NULL);
View
6 vm.h
@@ -1033,7 +1033,9 @@ class RoxorVM {
bool has_ensure;
int return_from_block;
Class current_super_class;
- SEL current_super_sel;
+ SEL current_super_sel;
+ VALUE current_mri_method_self;
+ SEL current_mri_method_sel;
RoxorSpecialException *special_exc;
@@ -1061,6 +1063,8 @@ class RoxorVM {
ACCESSOR(current_super_class, Class);
ACCESSOR(current_super_sel, SEL);
READER(mcache, struct mcache *);
+ ACCESSOR(current_mri_method_self, VALUE);
+ ACCESSOR(current_mri_method_sel, SEL);
std::string debug_blocks(void);

0 comments on commit fa6ceeb

Please sign in to comment.
Something went wrong with that request. Please try again.