[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