<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[2017] MacRuby/branches/experimental</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.macosforge.org/projects/ruby/changeset/2017">2017</a></dd>
<dt>Author</dt> <dd>lsansonetti@apple.com</dd>
<dt>Date</dt> <dd>2009-07-11 20:36:07 -0700 (Sat, 11 Jul 2009)</dd>
</dl>

<h3>Log Message</h3>
<pre>AOT compiler: now supporting objc stubs and super dispatch</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#MacRubybranchesexperimentalcompilercpp">MacRuby/branches/experimental/compiler.cpp</a></li>
<li><a href="#MacRubybranchesexperimentalcompilerh">MacRuby/branches/experimental/compiler.h</a></li>
<li><a href="#MacRubybranchesexperimentalvmcpp">MacRuby/branches/experimental/vm.cpp</a></li>
<li><a href="#MacRubybranchesexperimentalvmh">MacRuby/branches/experimental/vm.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="MacRubybranchesexperimentalcompilercpp"></a>
<div class="modfile"><h4>Modified: MacRuby/branches/experimental/compiler.cpp (2016 => 2017)</h4>
<pre class="diff"><span>
<span class="info">--- MacRuby/branches/experimental/compiler.cpp        2009-07-11 09:36:55 UTC (rev 2016)
+++ MacRuby/branches/experimental/compiler.cpp        2009-07-12 03:36:07 UTC (rev 2017)
</span><span class="lines">@@ -453,27 +453,27 @@
</span><span class="cx"> Value *
</span><span class="cx"> RoxorAOTCompiler::compile_mcache(SEL sel, bool super)
</span><span class="cx"> {
</span><del>-    GlobalVariable *gvar;
</del><span class="cx">     if (super) {
</span><del>-        abort(); // TODO
</del><ins>+        char buf[100];
+        snprintf(buf, sizeof buf, &quot;__super__:%s&quot;, sel_getName(sel));
+        sel = sel_registerName(buf);
</ins><span class="cx">     }
</span><ins>+
+    GlobalVariable *gvar;
+    std::map&lt;SEL, GlobalVariable *&gt;::iterator iter = mcaches.find(sel);
+    if (iter == mcaches.end()) {
+        gvar = new GlobalVariable(
+                PtrTy,
+                false,
+                GlobalValue::InternalLinkage,
+                Constant::getNullValue(PtrTy),
+                &quot;&quot;,
+                RoxorCompiler::module);
+        assert(gvar != NULL);
+        mcaches[sel] = gvar;
+    }
</ins><span class="cx">     else {
</span><del>-        std::map&lt;SEL, GlobalVariable *&gt;::iterator iter =
-            mcaches.find(sel);
-        if (iter == mcaches.end()) {
-            gvar = new GlobalVariable(
-                    PtrTy,
-                    false,
-                    GlobalValue::InternalLinkage,
-                    Constant::getNullValue(PtrTy),
-                    &quot;&quot;,
-                    RoxorCompiler::module);
-            assert(gvar != NULL);
-            mcaches[sel] = gvar;
-        }
-        else {
-            gvar = iter-&gt;second;
-        }
</del><ins>+        gvar = iter-&gt;second;
</ins><span class="cx">     }
</span><span class="cx">     return new LoadInst(gvar, &quot;&quot;, bb);
</span><span class="cx"> }
</span><span class="lines">@@ -532,18 +532,27 @@
</span><span class="cx">         : new LoadInst(gvar, &quot;&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline Value *
+RoxorCompiler::compile_arity(rb_vm_arity_t &amp;arity)
+{
+    uint64_t v;
+    assert(sizeof(uint64_t) == sizeof(rb_vm_arity_t));
+    memcpy(&amp;v, &amp;arity, sizeof(rb_vm_arity_t));
+    return ConstantInt::get(Type::Int64Ty, v);
+}
+
</ins><span class="cx"> void
</span><span class="cx"> RoxorCompiler::compile_prepare_method(Value *classVal, Value *sel,
</span><span class="cx">         Function *new_function, rb_vm_arity_t &amp;arity, NODE *body)
</span><span class="cx"> {
</span><span class="cx">     if (prepareMethodFunc == NULL) {
</span><span class="cx">         // void rb_vm_prepare_method(Class klass, SEL sel,
</span><del>-        //                             Function *f, NODE *node);
</del><ins>+        //        Function *func, rb_vm_arity_t arity, int flags)
</ins><span class="cx">         prepareMethodFunc = 
</span><span class="cx">             cast&lt;Function&gt;(module-&gt;getOrInsertFunction(
</span><span class="cx">                         &quot;rb_vm_prepare_method&quot;,
</span><span class="cx">                         Type::VoidTy, RubyObjTy, PtrTy, PtrTy,
</span><del>-                        PtrTy, NULL));
</del><ins>+                        Type::Int64Ty, Type::Int32Ty, NULL));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     std::vector&lt;Value *&gt; params;
</span><span class="lines">@@ -553,28 +562,20 @@
</span><span class="cx"> 
</span><span class="cx">     params.push_back(compile_const_pointer(new_function));
</span><span class="cx">     rb_objc_retain((void *)body);
</span><del>-    params.push_back(compile_const_pointer(body));
</del><ins>+    params.push_back(compile_arity(arity));
+    params.push_back(ConstantInt::get(Type::Int32Ty, rb_vm_node_flags(body)));
</ins><span class="cx"> 
</span><span class="cx">     CallInst::Create(prepareMethodFunc, params.begin(),
</span><span class="cx">             params.end(), &quot;&quot;, bb);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline Value *
-RoxorCompiler::compile_arity(rb_vm_arity_t &amp;arity)
-{
-    uint64_t v;
-    assert(sizeof(uint64_t) == sizeof(rb_vm_arity_t));
-    memcpy(&amp;v, &amp;arity, sizeof(rb_vm_arity_t));
-    return ConstantInt::get(Type::Int64Ty, v);
-}
-
</del><span class="cx"> void
</span><span class="cx"> RoxorAOTCompiler::compile_prepare_method(Value *classVal, Value *sel,
</span><span class="cx">         Function *new_function, rb_vm_arity_t &amp;arity, NODE *body)
</span><span class="cx"> {
</span><span class="cx">     if (prepareMethodFunc == NULL) {
</span><del>-        // void rb_vm_prepare_method2(Class klass, SEl sel, IMP imp,
-        //                              rb_vm_arity_t arity, int flags);
</del><ins>+        // void rb_vm_prepare_method2(Class klass, SEL sel,
+        //        IMP ruby_imp, rb_vm_arity_t arity, int flags)
</ins><span class="cx">         prepareMethodFunc = 
</span><span class="cx">             cast&lt;Function&gt;(module-&gt;getOrInsertFunction(
</span><span class="cx">                         &quot;rb_vm_prepare_method2&quot;,
</span><span class="lines">@@ -5995,8 +5996,11 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Function *
</span><del>-RoxorCompiler::compile_objc_stub(Function *ruby_func, const char *types)
</del><ins>+RoxorCompiler::compile_objc_stub(Function *ruby_func, IMP ruby_imp,
+        const rb_vm_arity_t &amp;arity, const char *types)
</ins><span class="cx"> {
</span><ins>+    assert(ruby_func != NULL || ruby_imp != NULL);
+
</ins><span class="cx">     char buf[100];
</span><span class="cx">     const char *p = types;
</span><span class="cx">     std::vector&lt;const Type *&gt; f_types;
</span><span class="lines">@@ -6026,7 +6030,7 @@
</span><span class="cx">     // Arguments.
</span><span class="cx">     std::vector&lt;std::string&gt; arg_types;
</span><span class="cx">     std::vector&lt;unsigned int&gt; byval_args;
</span><del>-    for (unsigned int i = 0; i &lt; ruby_func-&gt;arg_size() - 2; i++) {
</del><ins>+    for (int i = 0; i &lt; arity.real; i++) {
</ins><span class="cx">         p = GetFirstType(p, buf, sizeof buf);
</span><span class="cx">         const Type *t = convert_type(buf);
</span><span class="cx">         if (GET_CORE()-&gt;is_large_struct_type(t)) {
</span><span class="lines">@@ -6064,20 +6068,37 @@
</span><span class="cx">     params.push_back(arg++); // sel
</span><span class="cx"> 
</span><span class="cx">     // Convert every incoming argument into Ruby type.
</span><del>-    for (unsigned int i = 0; i &lt; ruby_func-&gt;arg_size() - 2; i++) {
</del><ins>+    for (int i = 0; i &lt; arity.real; i++) {
</ins><span class="cx">         Value *a = arg++;
</span><span class="cx">         if (std::find(byval_args.begin(), byval_args.end(), i + 3 + sret_i)
</span><del>-            != byval_args.end()) {
-             a = new LoadInst(a, &quot;&quot;, bb);
</del><ins>+                != byval_args.end()) {
+            a = new LoadInst(a, &quot;&quot;, bb);
</ins><span class="cx">         }
</span><span class="cx">         Value *ruby_arg = compile_conversion_to_ruby(arg_types[i].c_str(),
</span><span class="cx">                 f_types[i + 2 + sret_i], a);
</span><span class="cx">         params.push_back(ruby_arg);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // Create the Ruby implementation type (unless it's already provided).
+    Value *imp;
+    if (ruby_func == NULL) {
+        std::vector&lt;const Type *&gt; ruby_func_types;
+        ruby_func_types.push_back(RubyObjTy);
+        ruby_func_types.push_back(PtrTy);
+        for (int i = 0; i &lt; arity.real; i++) {
+            ruby_func_types.push_back(RubyObjTy);
+        }
+        FunctionType *ft = FunctionType::get(RubyObjTy, ruby_func_types, false);
+        imp = new BitCastInst(compile_const_pointer((void *)ruby_imp),
+                PointerType::getUnqual(ft), &quot;&quot;, bb);
+    }
+    else {
+        imp = ruby_func;
+    }
+
</ins><span class="cx">     // Call the Ruby implementation.
</span><del>-    Value *ret_val = CallInst::Create(ruby_func, params.begin(),
-            params.end(), &quot;&quot;, bb);
</del><ins>+    Value *ret_val = CallInst::Create(imp, params.begin(), params.end(),
+            &quot;&quot;, bb);
</ins><span class="cx"> 
</span><span class="cx">     // Convert the return value into Objective-C type (if any).
</span><span class="cx">     if (f_ret_type != Type::VoidTy) {
</span></span></pre></div>
<a id="MacRubybranchesexperimentalcompilerh"></a>
<div class="modfile"><h4>Modified: MacRuby/branches/experimental/compiler.h (2016 => 2017)</h4>
<pre class="diff"><span>
<span class="info">--- MacRuby/branches/experimental/compiler.h        2009-07-11 09:36:55 UTC (rev 2016)
+++ MacRuby/branches/experimental/compiler.h        2009-07-12 03:36:07 UTC (rev 2017)
</span><span class="lines">@@ -49,7 +49,8 @@
</span><span class="cx">         Function *compile_ffi_function(void *stub, void *imp, int argc);
</span><span class="cx">         Function *compile_to_rval_convertor(const char *type);
</span><span class="cx">         Function *compile_to_ocval_convertor(const char *type);
</span><del>-        Function *compile_objc_stub(Function *ruby_func, const char *types);
</del><ins>+        Function *compile_objc_stub(Function *ruby_func, IMP ruby_imp,
+                const rb_vm_arity_t &amp;arity, const char *types);
</ins><span class="cx">         Function *compile_block_caller(rb_vm_block_t *block);
</span><span class="cx"> 
</span><span class="cx">         const Type *convert_type(const char *type);
</span></span></pre></div>
<a id="MacRubybranchesexperimentalvmcpp"></a>
<div class="modfile"><h4>Modified: MacRuby/branches/experimental/vm.cpp (2016 => 2017)</h4>
<pre class="diff"><span>
<span class="info">--- MacRuby/branches/experimental/vm.cpp        2009-07-11 09:36:55 UTC (rev 2016)
+++ MacRuby/branches/experimental/vm.cpp        2009-07-12 03:36:07 UTC (rev 2017)
</span><span class="lines">@@ -1269,32 +1269,30 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> rb_vm_method_node_t *
</span><del>-RoxorCore::resolve_method(Class klass, SEL sel, Function *func, NODE *node,
-        IMP imp, Method m)
</del><ins>+RoxorCore::resolve_method(Class klass, SEL sel, Function *func,
+        const rb_vm_arity_t &amp;arity, int flags, IMP imp, Method m)
</ins><span class="cx"> {
</span><del>-    const int oc_arity = rb_vm_node_arity(node).real + 3;
</del><ins>+    if (imp == NULL) {
+        assert(func != NULL);
+        imp = compile(func);
+    }
</ins><span class="cx"> 
</span><ins>+    const int oc_arity = arity.real + 3;
</ins><span class="cx">     char types[100];
</span><span class="cx">     resolve_method_type(types, sizeof types, klass, m, sel, oc_arity);
</span><span class="cx"> 
</span><del>-    std::map&lt;Function *, IMP&gt;::iterator iter = objc_to_ruby_stubs.find(func);
</del><ins>+    std::map&lt;IMP, IMP&gt;::iterator iter = objc_to_ruby_stubs.find(imp);
</ins><span class="cx">     IMP objc_imp;
</span><span class="cx">     if (iter == objc_to_ruby_stubs.end()) {
</span><span class="cx">         Function *objc_func = RoxorCompiler::shared-&gt;compile_objc_stub(func,
</span><del>-                types);
</del><ins>+                imp, arity, types);
</ins><span class="cx">         objc_imp = compile(objc_func);
</span><del>-        objc_to_ruby_stubs[func] = objc_imp;
</del><ins>+        objc_to_ruby_stubs[imp] = objc_imp;
</ins><span class="cx">     }
</span><span class="cx">     else {
</span><span class="cx">         objc_imp = iter-&gt;second;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (imp == NULL) {
-        imp = compile(func);
-    }
-
-    const rb_vm_arity_t arity = rb_vm_node_arity(node);
-    const int flags = rb_vm_node_flags(node);
</del><span class="cx">     return add_method(klass, sel, objc_imp, imp, arity, flags, types);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1312,7 +1310,8 @@
</span><span class="cx"> 
</span><span class="cx">         if (k != NULL) {
</span><span class="cx">             rb_vm_method_source_t *m = iter-&gt;second;
</span><del>-            resolve_method(iter-&gt;first, sel, m-&gt;func, m-&gt;node, NULL, NULL);
</del><ins>+            resolve_method(iter-&gt;first, sel, m-&gt;func, m-&gt;arity, m-&gt;flags,
+                    NULL, NULL);
</ins><span class="cx">             map-&gt;erase(iter++);
</span><span class="cx">             free(m);
</span><span class="cx">             did_something = true;
</span><span class="lines">@@ -1367,15 +1366,15 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void
</span><del>-RoxorCore::prepare_method(Class klass, SEL sel, Function *func, NODE *node)
</del><ins>+RoxorCore::prepare_method(Class klass, SEL sel, Function *func,
+        const rb_vm_arity_t &amp;arity, int flags)
</ins><span class="cx"> {
</span><span class="cx"> #if ROXOR_VM_DEBUG
</span><del>-    printf(&quot;preparing %c[%s %s] with LLVM func %p node %p\n&quot;,
</del><ins>+    printf(&quot;preparing %c[%s %s] with LLVM func %p\n&quot;,
</ins><span class="cx">             class_isMetaClass(klass) ? '+' : '-',
</span><span class="cx">             class_getName(klass),
</span><span class="cx">             sel_getName(sel),
</span><del>-            func,
-            node);
</del><ins>+            func);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     std::map&lt;Class, rb_vm_method_source_t *&gt; *map =
</span><span class="lines">@@ -1394,12 +1393,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m-&gt;func = func;
</span><del>-    m-&gt;node = node;
</del><ins>+    m-&gt;arity = arity;
+    m-&gt;flags = flags;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-extern &quot;C&quot;
-void
-rb_vm_prepare_method(Class klass, SEL sel, Function *func, NODE *node)
</del><ins>+static void
+prepare_method(Class klass, SEL sel, void *data,
+        const rb_vm_arity_t &amp;arity, int flags, bool precompiled)
</ins><span class="cx"> {
</span><span class="cx">     Class k = GET_VM()-&gt;get_current_class();
</span><span class="cx">     if (k != NULL) {
</span><span class="lines">@@ -1410,7 +1410,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    const rb_vm_arity_t arity = rb_vm_node_arity(node);
</del><span class="cx">     const char *sel_name = sel_getName(sel);
</span><span class="cx">     const bool genuine_selector = sel_name[strlen(sel_name) - 1] == ':';
</span><span class="cx">     bool redefined = false;
</span><span class="lines">@@ -1421,16 +1420,23 @@
</span><span class="cx"> prepare_method:
</span><span class="cx"> 
</span><span class="cx">     m = class_getInstanceMethod(klass, sel);
</span><del>-    if (m != NULL) {
-        // The method already exists - we need to JIT it.
-        if (imp == NULL) {
-            imp = GET_CORE()-&gt;compile(func);
-        }
-        GET_CORE()-&gt;resolve_method(klass, sel, func, node, imp, m);
</del><ins>+    if (precompiled) {
+        imp = (IMP)data;
+        GET_CORE()-&gt;resolve_method(klass, sel, NULL, arity, flags, imp, m);
</ins><span class="cx">     }
</span><span class="cx">     else {
</span><del>-        // Let's keep the method and JIT it later on demand.
-        GET_CORE()-&gt;prepare_method(klass, sel, func, node);
</del><ins>+        Function *func = (Function *)data;
+        if (m != NULL) {
+            // The method already exists - we need to JIT it.
+            if (imp == NULL) {
+                imp = GET_CORE()-&gt;compile(func);
+            }
+            GET_CORE()-&gt;resolve_method(klass, sel, func, arity, flags, imp, m);
+        }
+        else {
+            // Let's keep the method and JIT it later on demand.
+            GET_CORE()-&gt;prepare_method(klass, sel, func, arity, flags);
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (!redefined) {
</span><span class="lines">@@ -1460,24 +1466,32 @@
</span><span class="cx">             int i, count = RARRAY_LEN(included_in_classes);
</span><span class="cx">             for (i = 0; i &lt; count; i++) {
</span><span class="cx">                 VALUE mod = RARRAY_AT(included_in_classes, i);
</span><del>-                rb_vm_prepare_method((Class)mod, orig_sel, func, node);
</del><ins>+                prepare_method((Class)mod, orig_sel, data, arity, flags,
+                        precompiled);
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void __rb_vm_define_method(Class klass, SEL sel, IMP objc_imp,
-        IMP ruby_imp, const rb_vm_arity_t &amp;arity, int flags, bool direct);
</del><ins>+extern &quot;C&quot;
+void
+rb_vm_prepare_method(Class klass, SEL sel, Function *func,
+        const rb_vm_arity_t arity, int flags)
+{
+    prepare_method(klass, sel, (void *)func, arity, flags, false);
+}
</ins><span class="cx"> 
</span><span class="cx"> extern &quot;C&quot;
</span><span class="cx"> void
</span><del>-rb_vm_prepare_method2(Class klass, SEL sel, IMP imp, rb_vm_arity_t arity,
-                      int flags)
</del><ins>+rb_vm_prepare_method2(Class klass, SEL sel, IMP ruby_imp,
+        const rb_vm_arity_t arity, int flags)
</ins><span class="cx"> {
</span><del>-    // TODO: create objc_imp
-    __rb_vm_define_method(klass, sel, imp, imp, arity, flags, false);
</del><ins>+    prepare_method(klass, sel, (void *)ruby_imp, arity, flags, true);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void __rb_vm_define_method(Class klass, SEL sel, IMP objc_imp,
+        IMP ruby_imp, const rb_vm_arity_t &amp;arity, int flags, bool direct);
+
</ins><span class="cx"> #define VISI(x) ((x)&amp;NOEX_MASK)
</span><span class="cx"> #define VISI_CHECK(x,f) (VISI(x) == (f))
</span><span class="cx"> 
</span><span class="lines">@@ -1567,6 +1581,7 @@
</span><span class="cx">     GET_CORE()-&gt;get_methods(ary, (Class)mod, include_objc_methods, filter);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if 0
</ins><span class="cx"> extern &quot;C&quot;
</span><span class="cx"> GenericValue
</span><span class="cx"> lle_X_rb_vm_prepare_method(const FunctionType *FT,
</span><span class="lines">@@ -1584,6 +1599,7 @@
</span><span class="cx">     GV.IntVal = 0;
</span><span class="cx">     return GV;
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx"> extern &quot;C&quot;
</span><span class="cx"> void
</span><span class="lines">@@ -1663,7 +1679,8 @@
</span><span class="cx">             rb_vm_method_source_t *m = (rb_vm_method_source_t *)
</span><span class="cx">                 malloc(sizeof(rb_vm_method_source_t));
</span><span class="cx">             m-&gt;func = iter2-&gt;second-&gt;func;
</span><del>-            m-&gt;node = iter2-&gt;second-&gt;node;
</del><ins>+            m-&gt;arity = iter2-&gt;second-&gt;arity;
+            m-&gt;flags = iter2-&gt;second-&gt;flags;
</ins><span class="cx">             dict-&gt;insert(std::make_pair(to_class, m));
</span><span class="cx">             sels_to_add.push_back(sel);
</span><span class="cx">         }
</span><span class="lines">@@ -1733,22 +1750,14 @@
</span><span class="cx">     if (read) {
</span><span class="cx">         Function *f = RoxorCompiler::shared-&gt;compile_read_attr(iname);
</span><span class="cx">         SEL sel = sel_registerName(name);
</span><del>-        NODE *node = NEW_CFUNC(NULL, 0);
-        NODE *body = NEW_FBODY(NEW_METHOD(node, klass, noex), 0);
-        rb_objc_retain(body);
-
-        rb_vm_prepare_method(klass, sel, f, body);
</del><ins>+        rb_vm_prepare_method(klass, sel, f, rb_vm_arity(0), NODE_FBODY);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (write) {
</span><span class="cx">         Function *f = RoxorCompiler::shared-&gt;compile_write_attr(iname);
</span><span class="cx">         snprintf(buf, sizeof buf, &quot;%s=:&quot;, name);
</span><span class="cx">         SEL sel = sel_registerName(buf);
</span><del>-        NODE *node = NEW_CFUNC(NULL, 1);
-        NODE *body = NEW_FBODY(NEW_METHOD(node, klass, noex), 0);
-        rb_objc_retain(body);
-
-        rb_vm_prepare_method(klass, sel, f, body);
</del><ins>+        rb_vm_prepare_method(klass, sel, f, rb_vm_arity(1), NODE_FBODY);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="MacRubybranchesexperimentalvmh"></a>
<div class="modfile"><h4>Modified: MacRuby/branches/experimental/vm.h (2016 => 2017)</h4>
<pre class="diff"><span>
<span class="info">--- MacRuby/branches/experimental/vm.h        2009-07-11 09:36:55 UTC (rev 2016)
+++ MacRuby/branches/experimental/vm.h        2009-07-12 03:36:07 UTC (rev 2017)
</span><span class="lines">@@ -438,7 +438,8 @@
</span><span class="cx"> 
</span><span class="cx"> typedef struct {
</span><span class="cx">     Function *func;
</span><del>-    NODE *node;
</del><ins>+    rb_vm_arity_t arity;
+    int flags;
</ins><span class="cx"> } rb_vm_method_source_t;
</span><span class="cx"> 
</span><span class="cx"> typedef VALUE rb_vm_objc_stub_t(IMP imp, id self, SEL sel, int argc,
</span><span class="lines">@@ -538,7 +539,7 @@
</span><span class="cx">         // Maps to cache compiled stubs for a given Objective-C runtime type.
</span><span class="cx">         std::map&lt;std::string, void *&gt; c_stubs, objc_stubs,
</span><span class="cx">             to_rval_convertors, to_ocval_convertors;
</span><del>-        std::map&lt;Function *, IMP&gt; objc_to_ruby_stubs;
</del><ins>+        std::map&lt;IMP, IMP&gt; objc_to_ruby_stubs;
</ins><span class="cx"> 
</span><span class="cx">         // Caches for the lazy JIT.
</span><span class="cx">         std::map&lt;SEL, std::map&lt;Class, rb_vm_method_source_t *&gt; *&gt;
</span><span class="lines">@@ -643,12 +644,14 @@
</span><span class="cx">         struct mcache *method_cache_get(SEL sel, bool super);
</span><span class="cx">         rb_vm_method_node_t *method_node_get(IMP imp);
</span><span class="cx"> 
</span><del>-        void prepare_method(Class klass, SEL sel, Function *func, NODE *node);
</del><ins>+        void prepare_method(Class klass, SEL sel, Function *func,
+                const rb_vm_arity_t &amp;arity, int flag);
</ins><span class="cx">         rb_vm_method_node_t *add_method(Class klass, SEL sel, IMP imp,
</span><span class="cx">                 IMP ruby_imp, const rb_vm_arity_t &amp;arity, int flags,
</span><span class="cx">                 const char *types);
</span><span class="cx">         rb_vm_method_node_t *resolve_method(Class klass, SEL sel,
</span><del>-                Function *func, NODE *node, IMP imp, Method m);
</del><ins>+                Function *func, const rb_vm_arity_t &amp;arity, int flags,
+                IMP imp, Method m);
</ins><span class="cx">         bool resolve_methods(std::map&lt;Class, rb_vm_method_source_t *&gt; *map,
</span><span class="cx">                 Class klass, SEL sel);
</span><span class="cx">         void copy_methods(Class from_class, Class to_class);
</span></span></pre>
</div>
</div>

</body>
</html>