<!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>[1970] 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/1970">1970</a></dd>
<dt>Author</dt> <dd>lsansonetti@apple.com</dd>
<dt>Date</dt> <dd>2009-07-01 22:14:36 -0700 (Wed, 01 Jul 2009)</dd>
</dl>

<h3>Log Message</h3>
<pre>AOT compiler: ivar slots support</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>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="MacRubybranchesexperimentalcompilercpp"></a>
<div class="modfile"><h4>Modified: MacRuby/branches/experimental/compiler.cpp (1969 => 1970)</h4>
<pre class="diff"><span>
<span class="info">--- MacRuby/branches/experimental/compiler.cpp        2009-07-02 01:31:22 UTC (rev 1969)
+++ MacRuby/branches/experimental/compiler.cpp        2009-07-02 05:14:36 UTC (rev 1970)
</span><span class="lines">@@ -136,6 +136,7 @@
</span><span class="cx">     cObject = ConstantInt::get(RubyObjTy, (long)rb_cObject);
</span><span class="cx">     PtrTy = PointerType::getUnqual(Type::Int8Ty);
</span><span class="cx">     PtrPtrTy = PointerType::getUnqual(PtrTy);
</span><ins>+    Int32PtrTy = PointerType::getUnqual(Type::Int32Ty);
</ins><span class="cx"> 
</span><span class="cx"> #if ROXOR_COMPILER_DEBUG
</span><span class="cx">     level = 0;
</span><span class="lines">@@ -933,23 +934,72 @@
</span><span class="cx">             &quot;&quot;, bb);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Instruction *
+RoxorCompiler::gen_slot_cache(ID id)
+{
+    int *slot = (int *)malloc(sizeof(int));
+    *slot = -1;
+    return compile_const_pointer(slot, Int32PtrTy, false);
+}
+
+Instruction *
+RoxorAOTCompiler::gen_slot_cache(ID id)
+{
+    GlobalVariable *gvar = new GlobalVariable(
+            Int32PtrTy,
+            false,
+            GlobalValue::InternalLinkage,
+            Constant::getNullValue(Int32PtrTy),
+            rb_id2name(id),
+            RoxorCompiler::module);
+
+    ivar_slots.push_back(gvar);
+
+    return new LoadInst(gvar, &quot;&quot;);
+}
+
+Instruction *
+RoxorCompiler::compile_slot_cache(ID id)
+{
+    if (inside_eval || current_block || !current_instance_method
+        || current_module) {
+        return compile_const_pointer(NULL, Int32PtrTy);
+    }
+
+    std::map&lt;ID, Instruction *&gt;::iterator iter = ivar_slots_cache.find(id);
+    Instruction *slot;
+    if (iter == ivar_slots_cache.end()) {
+#if ROXOR_COMPILER_DEBUG
+        printf(&quot;allocating a new slot for ivar %s\n&quot;, rb_id2name(id));
+#endif
+        slot = gen_slot_cache(id);
+        ivar_slots_cache[id] = slot;
+    }
+    else {
+        slot = iter-&gt;second;
+    }
+
+    Instruction *insn = slot-&gt;clone();
+    BasicBlock::InstListType &amp;list = bb-&gt;getInstList();
+    list.insert(list.end(), insn);
+    return insn;
+}
+
</ins><span class="cx"> Value *
</span><span class="cx"> RoxorCompiler::compile_ivar_read(ID vid)
</span><span class="cx"> {
</span><span class="cx">     if (getIvarFunc == NULL) {
</span><del>-        // VALUE rb_vm_ivar_get(VALUE obj, ID name, void *slot_cache);
</del><ins>+        // VALUE rb_vm_ivar_get(VALUE obj, ID name, int *slot_cache);
</ins><span class="cx">         getIvarFunc = cast&lt;Function&gt;(module-&gt;getOrInsertFunction(&quot;rb_vm_ivar_get&quot;,
</span><del>-                    RubyObjTy, RubyObjTy, IntTy, PtrTy, NULL)); 
</del><ins>+                    RubyObjTy, RubyObjTy, IntTy, Int32PtrTy, NULL)); 
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     std::vector&lt;Value *&gt; params;
</span><span class="cx"> 
</span><span class="cx">     params.push_back(current_self);
</span><span class="cx">     params.push_back(compile_id(vid));
</span><ins>+    params.push_back(compile_slot_cache(vid));
</ins><span class="cx"> 
</span><del>-    int *slot_cache = get_slot_cache(vid);
-    params.push_back(compile_const_pointer(slot_cache));
-
</del><span class="cx">     return CallInst::Create(getIvarFunc, params.begin(), params.end(), &quot;&quot;, bb);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -960,7 +1010,7 @@
</span><span class="cx">         // void rb_vm_ivar_set(VALUE obj, ID name, VALUE val, int *slot_cache);
</span><span class="cx">         setIvarFunc = 
</span><span class="cx">             cast&lt;Function&gt;(module-&gt;getOrInsertFunction(&quot;rb_vm_ivar_set&quot;,
</span><del>-                        Type::VoidTy, RubyObjTy, IntTy, RubyObjTy, PtrTy,
</del><ins>+                        Type::VoidTy, RubyObjTy, IntTy, RubyObjTy, Int32PtrTy,
</ins><span class="cx">                         NULL)); 
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -969,10 +1019,8 @@
</span><span class="cx">     params.push_back(current_self);
</span><span class="cx">     params.push_back(compile_id(vid));
</span><span class="cx">     params.push_back(val);
</span><ins>+    params.push_back(compile_slot_cache(vid));
</ins><span class="cx"> 
</span><del>-    int *slot_cache = get_slot_cache(vid);
-    params.push_back(compile_const_pointer(slot_cache));
-
</del><span class="cx">     CallInst::Create(setIvarFunc, params.begin(), params.end(), &quot;&quot;, bb);
</span><span class="cx"> 
</span><span class="cx">     return val;
</span><span class="lines">@@ -2347,27 +2395,41 @@
</span><span class="cx"> 
</span><span class="cx"> void
</span><span class="cx"> RoxorCompiler::compile_ivar_slots(Value *klass,
</span><del>-                                  BasicBlock::InstListType &amp;list, 
-                                  BasicBlock::InstListType::iterator list_iter)
</del><ins>+        BasicBlock::InstListType &amp;list, 
+        BasicBlock::InstListType::iterator list_iter)
</ins><span class="cx"> {
</span><span class="cx">     if (ivar_slots_cache.size() &gt; 0) {
</span><span class="cx">         if (prepareIvarSlotFunc == NULL) {
</span><del>-            // void rb_vm_prepare_class_ivar_slot(VALUE klass, ID name, int *slot_cache);
</del><ins>+            // void rb_vm_prepare_class_ivar_slot(VALUE klass, ID name,
+            //                 int *slot_cache);
</ins><span class="cx">             prepareIvarSlotFunc = cast&lt;Function&gt;(
</span><del>-                    module-&gt;getOrInsertFunction(&quot;rb_vm_prepare_class_ivar_slot&quot;, 
-                        Type::VoidTy, RubyObjTy, IntTy, PtrTy, NULL));
</del><ins>+                    module-&gt;getOrInsertFunction(
+                        &quot;rb_vm_prepare_class_ivar_slot&quot;, 
+                        Type::VoidTy, RubyObjTy, IntTy, Int32PtrTy, NULL));
</ins><span class="cx">         }
</span><del>-        for (std::map&lt;ID, int *&gt;::iterator iter = ivar_slots_cache.begin();
-                iter != ivar_slots_cache.end();
-                ++iter) {
</del><ins>+        for (std::map&lt;ID, Instruction *&gt;::iterator iter
+                = ivar_slots_cache.begin();
+             iter != ivar_slots_cache.end();
+             ++iter) {
</ins><span class="cx"> 
</span><ins>+            ID ivar_name = iter-&gt;first;
+            Instruction *ivar_slot = iter-&gt;second;
</ins><span class="cx">             std::vector&lt;Value *&gt; params;
</span><ins>+
</ins><span class="cx">             params.push_back(klass);
</span><del>-            params.push_back(compile_id(iter-&gt;first));
-            Instruction *ptr = compile_const_pointer(iter-&gt;second, false);
-            list.insert(list_iter, ptr);
-            params.push_back(ptr);
</del><span class="cx"> 
</span><ins>+            Value *id_val = compile_id(ivar_name);
+            if (Instruction::classof(id_val)) {
+                Instruction *insn = cast&lt;Instruction&gt;(id_val);
+                insn-&gt;removeFromParent();
+                list.insert(list_iter, insn);
+            }
+            params.push_back(id_val);
+
+            Instruction *insn = ivar_slot-&gt;clone();
+            list.insert(list_iter, insn);
+            params.push_back(insn);
+
</ins><span class="cx">             CallInst *call = CallInst::Create(prepareIvarSlotFunc, 
</span><span class="cx">                     params.begin(), params.end(), &quot;&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -2509,7 +2571,6 @@
</span><span class="cx"> 
</span><span class="cx">                     if (has_vars_to_save) {
</span><span class="cx">                         current_var_uses = new AllocaInst(PtrTy, &quot;&quot;, bb);
</span><del>-                        //current_var_uses = new MallocInst(PtrTy, &quot;&quot;, bb);
</del><span class="cx">                         new StoreInst(compile_const_pointer(NULL), current_var_uses, bb);
</span><span class="cx">                     }
</span><span class="cx"> 
</span><span class="lines">@@ -2597,8 +2658,8 @@
</span><span class="cx">                              ++inst_it) {
</span><span class="cx">                             if (dyn_cast&lt;ReturnInst&gt;(inst_it)) {
</span><span class="cx">                                 if (params.empty()) {
</span><del>-                                    params.push_back(new LoadInst(current_var_uses, &quot;&quot;, inst_it));
-                                    params.push_back(NULL); // filled right after.
</del><ins>+                                    params.push_back(NULL);
+                                    params.push_back(NULL);
</ins><span class="cx">                                     int vars_count = 0;
</span><span class="cx">                                     for (std::map&lt;ID, Value *&gt;::iterator iter = lvars.begin();
</span><span class="cx">                                             iter != lvars.end(); ++iter) {
</span><span class="lines">@@ -2617,6 +2678,8 @@
</span><span class="cx">                                     params[1] = ConstantInt::get(Type::Int32Ty, vars_count);
</span><span class="cx">                                 }
</span><span class="cx"> 
</span><ins>+                                params[0] = new LoadInst(current_var_uses, &quot;&quot;, inst_it);
+
</ins><span class="cx">                                 // TODO: only call the function if current_use is not NULL
</span><span class="cx">                                 CallInst::Create(keepVarsFunc, params.begin(), params.end(), &quot;&quot;,
</span><span class="cx">                                         inst_it);
</span><span class="lines">@@ -3206,7 +3269,8 @@
</span><span class="cx"> 
</span><span class="cx">                         bool old_current_module = current_module;
</span><span class="cx"> 
</span><del>-                        std::map&lt;ID, int *&gt; old_ivar_slots_cache = ivar_slots_cache;
</del><ins>+                        std::map&lt;ID, Instruction *&gt; old_ivar_slots_cache
+                            = ivar_slots_cache;
</ins><span class="cx">                         ivar_slots_cache.clear();
</span><span class="cx"> 
</span><span class="cx">                         new StoreInst(classVal, current_opened_class, bb);
</span><span class="lines">@@ -4337,10 +4401,15 @@
</span><span class="cx"> Function *
</span><span class="cx"> RoxorAOTCompiler::compile_main_function(NODE *node)
</span><span class="cx"> {
</span><del>-    Function *function = RoxorCompiler::compile_main_function(node);
</del><ins>+    current_instance_method = true;
</ins><span class="cx"> 
</span><ins>+    Value *val = compile_node(node);
+    assert(Function::classof(val));
+    Function *function = cast&lt;Function&gt;(val);
+
</ins><span class="cx">     BasicBlock::InstListType &amp;list = 
</span><span class="cx">         function-&gt;getEntryBlock().getInstList();
</span><ins>+    bb = &amp;function-&gt;getEntryBlock();
</ins><span class="cx"> 
</span><span class="cx">     // Compile method caches.
</span><span class="cx"> 
</span><span class="lines">@@ -4501,6 +4570,48 @@
</span><span class="cx">         list.insert(list.begin(), load);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // Compile ivar slots.
+
+    if (!ivar_slots_cache.empty()) {
+        GlobalVariable *toplevel = compile_const_global_string(&quot;TopLevel&quot;);
+
+        std::vector&lt;Value *&gt; idxs;
+        idxs.push_back(ConstantInt::get(Type::Int32Ty, 0));
+        idxs.push_back(ConstantInt::get(Type::Int32Ty, 0));
+        Instruction *load = GetElementPtrInst::Create(toplevel,
+                idxs.begin(), idxs.end(), &quot;&quot;);
+
+        std::vector&lt;Value *&gt; params;
+        params.push_back(load);
+
+        Instruction *call = CallInst::Create(objcGetClassFunc, params.begin(),
+                params.end(), &quot;&quot;);
+
+        compile_ivar_slots(call, list, list.begin());
+        ivar_slots_cache.clear();
+
+        list.insert(list.begin(), call);
+        list.insert(list.begin(), load);
+    }
+
+    for (std::vector&lt;GlobalVariable *&gt;::iterator i = ivar_slots.begin();
+         i != ivar_slots.end();
+         ++i) {
+
+        GlobalVariable *gvar = *i;
+
+        Instruction *call = new MallocInst(Type::Int32Ty, &quot;&quot;);
+        Instruction *assign1 =
+            new StoreInst(ConstantInt::get(Type::Int32Ty, -1), call, &quot;&quot;);
+        Instruction *assign2 = new StoreInst(call, gvar, &quot;&quot;);
+
+        list.insert(list.begin(), assign2);
+        list.insert(list.begin(), assign1);
+        list.insert(list.begin(), call);
+    }
+
+    bb = NULL;
+
</ins><span class="cx">     return function;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="MacRubybranchesexperimentalcompilerh"></a>
<div class="modfile"><h4>Modified: MacRuby/branches/experimental/compiler.h (1969 => 1970)</h4>
<pre class="diff"><span>
<span class="info">--- MacRuby/branches/experimental/compiler.h        2009-07-02 01:31:22 UTC (rev 1969)
+++ MacRuby/branches/experimental/compiler.h        2009-07-02 05:14:36 UTC (rev 1970)
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx"> 
</span><span class="cx">         std::map&lt;ID, Value *&gt; lvars;
</span><span class="cx">         std::vector&lt;ID&gt; dvars;
</span><del>-        std::map&lt;ID, int *&gt; ivar_slots_cache;
</del><ins>+        std::map&lt;ID, Instruction *&gt; ivar_slots_cache;
</ins><span class="cx">         std::map&lt;std::string, GlobalVariable *&gt; static_strings;
</span><span class="cx"> 
</span><span class="cx"> #if ROXOR_COMPILER_DEBUG
</span><span class="lines">@@ -165,23 +165,25 @@
</span><span class="cx">         const Type *PtrTy;
</span><span class="cx">         const Type *PtrPtrTy;
</span><span class="cx">         const Type *IntTy;
</span><ins>+        const Type *Int32PtrTy;
</ins><span class="cx"> 
</span><span class="cx">         void compile_node_error(const char *msg, NODE *node);
</span><span class="cx"> 
</span><span class="cx">         virtual Instruction *
</span><del>-        compile_const_pointer(void *ptr, bool insert_to_bb=true) {
</del><ins>+        compile_const_pointer(void *ptr, const Type *type=NULL,
+                bool insert_to_bb=true) {
</ins><span class="cx">             Value *ptrint = ConstantInt::get(IntTy, (long)ptr);
</span><ins>+            if (type == NULL) {
+                type = PtrTy;
+            }
</ins><span class="cx">             return insert_to_bb
</span><del>-                ? new IntToPtrInst(ptrint, PtrTy, &quot;&quot;, bb)
-                : new IntToPtrInst(ptrint, PtrTy, &quot;&quot;);
</del><ins>+                ? new IntToPtrInst(ptrint, type, &quot;&quot;, bb)
+                : new IntToPtrInst(ptrint, type, &quot;&quot;);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         Instruction *
</span><span class="cx">         compile_const_pointer_to_pointer(void *ptr, bool insert_to_bb=true) {
</span><del>-            Value *ptrint = ConstantInt::get(IntTy, (long)ptr);
-            return insert_to_bb
-                ? new IntToPtrInst(ptrint, PtrPtrTy, &quot;&quot;, bb)
-                : new IntToPtrInst(ptrint, PtrPtrTy, &quot;&quot;);
</del><ins>+            return compile_const_pointer(ptr, PtrPtrTy, insert_to_bb);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         Value *compile_protected_call(Function *func,
</span><span class="lines">@@ -227,7 +229,7 @@
</span><span class="cx">         virtual Value *compile_mcache(SEL sel, bool super);
</span><span class="cx">         virtual Value *compile_ccache(ID id);
</span><span class="cx">         virtual Instruction *compile_sel(SEL sel, bool add_to_bb=true) {
</span><del>-            return compile_const_pointer(sel, add_to_bb);
</del><ins>+            return compile_const_pointer(sel, PtrTy, add_to_bb);
</ins><span class="cx">         }
</span><span class="cx">         virtual Value *compile_id(ID id);
</span><span class="cx">         GlobalVariable *compile_const_global_string(const char *str);
</span><span class="lines">@@ -255,24 +257,8 @@
</span><span class="cx">         Value *compile_conversion_to_ruby(const char *type,
</span><span class="cx">                                           const Type *llvm_type, Value *val);
</span><span class="cx"> 
</span><del>-        int *get_slot_cache(ID id) {
-            if (inside_eval || current_block || !current_instance_method
-                || current_module) {
-                return NULL;
-            }
-            std::map&lt;ID, int *&gt;::iterator iter = ivar_slots_cache.find(id);
-            if (iter == ivar_slots_cache.end()) {
-#if ROXOR_COMPILER_DEBUG
-                printf(&quot;allocating a new slot for ivar %s\n&quot;, rb_id2name(id));
-#endif
-                int *slot = (int *)malloc(sizeof(int));
-                *slot = -1;
-                ivar_slots_cache[id] = slot;
-                return slot;
-            }
-            return iter-&gt;second;
-        }
-
</del><ins>+        Instruction *compile_slot_cache(ID id);
+        virtual Instruction *gen_slot_cache(ID id);
</ins><span class="cx">         ICmpInst *is_value_a_fixnum(Value *val);
</span><span class="cx">         void compile_ivar_slots(Value *klass, BasicBlock::InstListType &amp;list, 
</span><span class="cx">                                 BasicBlock::InstListType::iterator iter);
</span><span class="lines">@@ -296,6 +282,7 @@
</span><span class="cx">         std::map&lt;ID, GlobalVariable *&gt; ccaches;
</span><span class="cx">         std::map&lt;SEL, GlobalVariable *&gt; sels;
</span><span class="cx">         std::map&lt;ID, GlobalVariable *&gt; ids;
</span><ins>+        std::vector&lt;GlobalVariable *&gt; ivar_slots;
</ins><span class="cx">         GlobalVariable *cObject_gvar;
</span><span class="cx"> 
</span><span class="cx">         Value *compile_mcache(SEL sel, bool super);
</span><span class="lines">@@ -307,10 +294,14 @@
</span><span class="cx">         Value *compile_nsobject(void);
</span><span class="cx">         Value *compile_id(ID id);
</span><span class="cx"> 
</span><ins>+        Instruction *gen_slot_cache(ID id);
+
</ins><span class="cx">         Instruction *
</span><del>-        compile_const_pointer(void *ptr, bool insert_to_bb=true) {
</del><ins>+        compile_const_pointer(void *ptr, const Type *type=NULL,
+                bool insert_to_bb=true) {
</ins><span class="cx">             if (ptr == NULL) {
</span><del>-                return RoxorCompiler::compile_const_pointer(ptr, insert_to_bb);
</del><ins>+                return RoxorCompiler::compile_const_pointer(ptr, type,
+                        insert_to_bb);
</ins><span class="cx">             }
</span><span class="cx">             printf(&quot;compile_const_pointer() called with a non-NULL pointer &quot; \
</span><span class="cx">                    &quot;on the AOT compiler - leaving the ship!\n&quot;);
</span></span></pre>
</div>
</div>

</body>
</html>