[macruby-changes] [1974] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Thu Jul 2 16:05:32 PDT 2009


Revision: 1974
          http://trac.macosforge.org/projects/ruby/changeset/1974
Author:   lsansonetti at apple.com
Date:     2009-07-02 16:05:32 -0700 (Thu, 02 Jul 2009)
Log Message:
-----------
fixed a bug in the way we compile literal strings

Modified Paths:
--------------
    MacRuby/branches/experimental/compiler.cpp
    MacRuby/branches/experimental/compiler.h
    MacRuby/branches/experimental/string.c
    MacRuby/branches/experimental/test_vm/literal.rb

Modified: MacRuby/branches/experimental/compiler.cpp
===================================================================
--- MacRuby/branches/experimental/compiler.cpp	2009-07-02 19:29:09 UTC (rev 1973)
+++ MacRuby/branches/experimental/compiler.cpp	2009-07-02 23:05:32 UTC (rev 1974)
@@ -101,6 +101,8 @@
     masgnGetElemAfterSplatFunc = NULL;
     masgnGetSplatFunc = NULL;
     newStringFunc = NULL;
+    newString2Func = NULL;
+    newString3Func = NULL;
     yieldFunc = NULL;
     blockEvalFunc = NULL;
     gvarSetFunc = NULL;
@@ -401,16 +403,16 @@
 }
 
 GlobalVariable *
-RoxorCompiler::compile_const_global_string(const char *str)
+RoxorCompiler::compile_const_global_string(const char *str, const size_t str_len)
 {
-    std::string s(str);
+    assert(str_len > 0);
+
+    std::string s(str, str_len);
     std::map<std::string, GlobalVariable *>::iterator iter =
 	static_strings.find(s);
+
     GlobalVariable *gvar;
     if (iter == static_strings.end()) {
-	const size_t str_len = strlen(str);
-	assert(str_len > 0);
-
 	const ArrayType *str_type = ArrayType::get(Type::Int8Ty, str_len + 1);
 
 	std::vector<Constant *> ary_elements;
@@ -2393,6 +2395,56 @@
     return NULL;
 }
 
+Value *
+RoxorCompiler::compile_literal(VALUE val)
+{
+    if (TYPE(val) == T_STRING) {
+	// We must compile a new string creation because strings are
+	// mutable, we can't simply compile a reference to a master
+	// copy.
+	//
+	//	10.times { s = 'foo'; s << 'bar' }
+	//
+	const char *str = RSTRING_PTR(val);
+	const size_t str_len = RSTRING_LEN(val);
+	if (str_len == 0) {
+	    if (newString3Func == NULL) {	
+		newString3Func = cast<Function>(
+			module->getOrInsertFunction(
+			    "rb_str_new_empty", RubyObjTy, NULL));
+	    }
+	    return CallInst::Create(newString3Func, "", bb);
+	}
+	else {
+	    GlobalVariable *str_gvar = compile_const_global_string(str,
+		    str_len);
+
+	    std::vector<Value *> idxs;
+	    idxs.push_back(ConstantInt::get(Type::Int32Ty, 0));
+	    idxs.push_back(ConstantInt::get(Type::Int32Ty, 0));
+	    Instruction *load = GetElementPtrInst::Create(str_gvar,
+		    idxs.begin(), idxs.end(), "", bb);
+
+	    if (newString2Func == NULL) {	
+		newString2Func = cast<Function>(
+			module->getOrInsertFunction(
+			    "rb_str_new", RubyObjTy, PtrTy, Type::Int32Ty,
+			    NULL));
+	    }
+
+	    std::vector<Value *> params;
+	    params.push_back(load);
+	    params.push_back(ConstantInt::get(Type::Int32Ty, str_len));
+
+	    return compile_protected_call(newString2Func, params);
+	}
+    }
+
+    // The other types are supposedly immutables.
+    // TODO AOT compile!
+    return ConstantInt::get(RubyObjTy, (long)val); 
+}
+
 void
 RoxorCompiler::compile_ivar_slots(Value *klass,
 	BasicBlock::InstListType &list, 
@@ -3545,7 +3597,7 @@
 	case NODE_STR:
 	    {
 		assert(node->nd_lit != 0);
-		return ConstantInt::get(RubyObjTy, (long)node->nd_lit);
+		return compile_literal(node->nd_lit);
 	    }
 	    break;
 

Modified: MacRuby/branches/experimental/compiler.h
===================================================================
--- MacRuby/branches/experimental/compiler.h	2009-07-02 19:29:09 UTC (rev 1973)
+++ MacRuby/branches/experimental/compiler.h	2009-07-02 23:05:32 UTC (rev 1974)
@@ -135,6 +135,8 @@
 	Function *masgnGetElemAfterSplatFunc;
 	Function *masgnGetSplatFunc;
 	Function *newStringFunc;
+	Function *newString2Func;
+	Function *newString3Func;
 	Function *yieldFunc;
 	Function *blockEvalFunc;
 	Function *gvarSetFunc;
@@ -232,8 +234,13 @@
 	    return compile_const_pointer(sel, PtrTy, add_to_bb);
 	}
 	virtual Value *compile_id(ID id);
-	GlobalVariable *compile_const_global_string(const char *str);
+	GlobalVariable *compile_const_global_string(const char *str,
+		const size_t str_len);
+	GlobalVariable *compile_const_global_string(const char *str) {
+	    return compile_const_global_string(str, strlen(str));
+	}
 	Value *compile_arity(rb_vm_arity_t &arity);
+	Value *compile_literal(VALUE val);
 
 	void compile_landing_pad_header(void);
 	void compile_landing_pad_footer(void);

Modified: MacRuby/branches/experimental/string.c
===================================================================
--- MacRuby/branches/experimental/string.c	2009-07-02 19:29:09 UTC (rev 1973)
+++ MacRuby/branches/experimental/string.c	2009-07-02 23:05:32 UTC (rev 1974)
@@ -82,6 +82,12 @@
 }
 
 VALUE
+rb_str_new_empty(void)
+{
+    return str_alloc(0);
+}
+
+VALUE
 rb_str_new_fast(int argc, ...)
 {
     VALUE str;

Modified: MacRuby/branches/experimental/test_vm/literal.rb
===================================================================
--- MacRuby/branches/experimental/test_vm/literal.rb	2009-07-02 19:29:09 UTC (rev 1973)
+++ MacRuby/branches/experimental/test_vm/literal.rb	2009-07-02 23:05:32 UTC (rev 1974)
@@ -28,3 +28,5 @@
 assert '42', "class Symbol; def !=(o); p 42; end; end; :foo != :foo"
 
 assert "false", "p ['foo'] == [:foo]"
+
+assert '424242', "a=''; 3.times { b=''; b << '42'; a<<b }; p a.to_i"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090702/2084d27b/attachment-0001.html>


More information about the macruby-changes mailing list