Permalink
Browse files

fixing and adding several missing ruby method features

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@2357 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
1 parent 9239833 commit 9590d4057aa1d7317b9220cf2a98c2c34f559aee @lrz lrz committed Aug 22, 2009
Showing with 680 additions and 408 deletions.
  1. +3 −0 array.c
  2. +26 −25 class.c
  3. +69 −14 compiler.cpp
  4. +18 −7 compiler.h
  5. +2 −0 id.c
  6. +2 −0 id.h
  7. +15 −12 include/ruby/ruby.h
  8. +5 −3 lib/yaml/rubytypes.rb
  9. +8 −8 object.c
  10. +6 −3 proc.c
  11. +1 −1 spec/frozen/language/def_spec.rb
  12. +8 −1 spec/frozen/library/date/conversions_spec.rb
  13. +0 −1 spec/frozen/tags/macruby/core/array/initialize_copy_tags.txt
  14. +0 −1 spec/frozen/tags/macruby/core/array/initialize_tags.txt
  15. +0 −1 spec/frozen/tags/macruby/core/basicobject/method_missing_tags.txt
  16. +0 −2 spec/frozen/tags/macruby/core/kernel/respond_to_tags.txt
  17. +0 −1 spec/frozen/tags/macruby/core/kernel/singleton_method_added_tags.txt
  18. +0 −1 spec/frozen/tags/macruby/core/kernel/singleton_method_removed_tags.txt
  19. +0 −1 spec/frozen/tags/macruby/core/kernel/singleton_method_undefined_tags.txt
  20. +0 −1 spec/frozen/tags/macruby/core/module/alias_method_tags.txt
  21. +0 −1 spec/frozen/tags/macruby/core/module/extended_tags.txt
  22. +0 −1 spec/frozen/tags/macruby/core/module/included_tags.txt
  23. +0 −1 spec/frozen/tags/macruby/core/module/method_added_tags.txt
  24. +0 −6 spec/frozen/tags/macruby/core/module/private_class_method_tags.txt
  25. +0 −1 spec/frozen/tags/macruby/core/module/private_instance_methods_tags.txt
  26. +0 −4 spec/frozen/tags/macruby/core/module/private_method_defined_tags.txt
  27. +0 −1 spec/frozen/tags/macruby/core/module/private_tags.txt
  28. +0 −1 spec/frozen/tags/macruby/core/module/remove_const_tags.txt
  29. +0 −1 spec/frozen/tags/macruby/core/range/initialize_tags.txt
  30. +0 −1 spec/frozen/tags/macruby/core/string/initialize_tags.txt
  31. +0 −1 spec/frozen/tags/macruby/core/struct/initialize_tags.txt
  32. +1 −2 spec/frozen/tags/macruby/language/def_tags.txt
  33. +0 −1 spec/frozen/tags/macruby/language/method_tags.txt
  34. +0 −5 spec/frozen/tags/macruby/language/private_tags.txt
  35. +0 −1 spec/frozen/tags/macruby/library/matrix/initialize_tags.txt
  36. +0 −1 spec/frozen/tags/macruby/library/net/ftp/initialize_tags.txt
  37. +0 −1 spec/frozen/tags/macruby/library/net/http/http/initialize_tags.txt
  38. +0 −1 spec/frozen/tags/macruby/library/set/initialize_copy_tags.txt
  39. +0 −1 spec/frozen/tags/macruby/library/set/initialize_tags.txt
  40. +0 −1 spec/frozen/tags/macruby/library/set/sortedset/initialize_copy_tags.txt
  41. +0 −1 spec/frozen/tags/macruby/library/set/sortedset/initialize_tags.txt
  42. +0 −1 spec/frozen/tags/macruby/library/stringio/initialize_copy_tags.txt
  43. +0 −1 spec/frozen/tags/macruby/library/stringscanner/initialize_copy_tags.txt
  44. +0 −1 spec/frozen/tags/macruby/library/stringscanner/initialize_tags.txt
  45. +384 −139 vm.cpp
  46. +73 −48 vm.h
  47. +1 −1 vm_eval.c
  48. +58 −100 vm_method.c
View
@@ -213,6 +213,9 @@ rb_equal_fast(VALUE x, VALUE y)
if (SPECIAL_CONST_P(x) && SPECIAL_CONST_P(y) && TYPE(x) == TYPE(y)) {
return Qfalse;
}
+ if (SYMBOL_P(x)) {
+ return x == y ? Qtrue : Qfalse;
+ }
return rb_equal(x, y);
}
View
51 class.c
@@ -121,8 +121,8 @@ rb_define_object_special_methods(VALUE klass)
rb_objc_define_method(*(VALUE *)klass, "__new__",
rb_class_new_instance_imp, -1);
rb_objc_define_method(klass, "dup", rb_obj_dup, 0);
- rb_objc_define_method(klass, "initialize", rb_objc_init, 0);
- rb_objc_define_method(klass, "initialize_copy", rb_obj_init_copy, 1);
+ rb_objc_define_private_method(klass, "initialize", rb_objc_init, 0);
+ rb_objc_define_private_method(klass, "initialize_copy", rb_obj_init_copy, 1);
rb_objc_install_method(*(Class *)klass, selAllocWithZone,
(IMP)rb_obj_imp_allocWithZone);
@@ -400,20 +400,20 @@ rb_make_metaclass(VALUE obj, VALUE super)
VALUE
rb_define_class_id(ID id, VALUE super)
{
- VALUE klass;
-
- if (!super) super = rb_cObject;
- klass = rb_objc_create_class(rb_id2name(id), super);
-
- return klass;
+ if (super == 0) {
+ super = rb_cObject;
+ }
+ return rb_objc_create_class(rb_id2name(id), super);
}
VALUE
rb_class_inherited(VALUE super, VALUE klass)
{
if (rb_vm_running()) {
- if (!super) super = rb_cObject;
- return rb_funcall(super, rb_intern("inherited"), 1, klass);
+ if (super == 0) {
+ super = rb_cObject;
+ }
+ return rb_vm_call(super, selInherited, 1, &klass, false);
}
return Qnil;
}
@@ -717,20 +717,21 @@ rb_mod_ancestors(VALUE mod)
static int
ins_methods_push(VALUE name, long type, VALUE ary, long visi)
{
- if (type == -1) return ST_CONTINUE;
-
- switch (visi) {
- case NOEX_PRIVATE:
- case NOEX_PROTECTED:
- case NOEX_PUBLIC:
- visi = (type == visi);
- break;
- default:
- visi = (type != NOEX_PRIVATE);
- break;
- }
- if (visi) {
- rb_ary_push(ary, name);
+ if (type != -1) {
+ bool visible;
+ switch (visi) {
+ case NOEX_PRIVATE:
+ case NOEX_PROTECTED:
+ case NOEX_PUBLIC:
+ visible = (type == visi);
+ break;
+ default:
+ visible = (type != NOEX_PRIVATE);
+ break;
+ }
+ if (visible) {
+ rb_ary_push(ary, name);
+ }
}
return ST_CONTINUE;
}
@@ -1010,7 +1011,7 @@ rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS),
void
rb_undef_method(VALUE klass, const char *name)
{
- rb_vm_undef_method((Class)klass, name, false);
+ rb_vm_undef_method((Class)klass, rb_intern(name), false);
}
#define SPECIAL_SINGLETON(x,c) do {\
View
@@ -121,6 +121,8 @@ RoxorCompiler::RoxorCompiler(void)
longjmpFunc = NULL;
setjmpFunc = NULL;
popBrokenValue = NULL;
+ setScopeFunc = NULL;
+ setCurrentClassFunc = NULL;
#if __LP64__
RubyObjTy = IntTy = Type::Int64Ty;
@@ -133,6 +135,9 @@ RoxorCompiler::RoxorCompiler(void)
twoVal = ConstantInt::get(IntTy, 2);
threeVal = ConstantInt::get(IntTy, 3);
+ defaultScope = ConstantInt::get(Type::Int32Ty, SCOPE_DEFAULT);
+ publicScope = ConstantInt::get(Type::Int32Ty, SCOPE_PUBLIC);
+
RubyObjPtrTy = PointerType::getUnqual(RubyObjTy);
RubyObjPtrPtrTy = PointerType::getUnqual(RubyObjPtrTy);
nilVal = ConstantInt::get(RubyObjTy, Qnil);
@@ -622,22 +627,23 @@ RoxorCompiler::compile_arity(rb_vm_arity_t &arity)
}
void
-RoxorCompiler::compile_prepare_method(Value *classVal, Value *sel,
- Function *new_function, rb_vm_arity_t &arity, NODE *body)
+RoxorCompiler::compile_prepare_method(Value *classVal, bool singleton,
+ Value *sel, Function *new_function, rb_vm_arity_t &arity, NODE *body)
{
if (prepareMethodFunc == NULL) {
- // void rb_vm_prepare_method(Class klass, SEL sel,
- // Function *func, rb_vm_arity_t arity, int flags)
+ // void rb_vm_prepare_method(Class klass, unsigned char singleton,
+ // SEL sel, Function *func, rb_vm_arity_t arity, int flags)
prepareMethodFunc =
cast<Function>(module->getOrInsertFunction(
"rb_vm_prepare_method",
- Type::VoidTy, RubyObjTy, PtrTy, PtrTy,
+ Type::VoidTy, RubyObjTy, Type::Int8Ty, PtrTy, PtrTy,
Type::Int64Ty, Type::Int32Ty, NULL));
}
std::vector<Value *> params;
params.push_back(classVal);
+ params.push_back(ConstantInt::get(Type::Int8Ty, singleton));
params.push_back(sel);
params.push_back(compile_const_pointer(new_function));
@@ -650,22 +656,23 @@ RoxorCompiler::compile_prepare_method(Value *classVal, Value *sel,
}
void
-RoxorAOTCompiler::compile_prepare_method(Value *classVal, Value *sel,
- Function *new_function, rb_vm_arity_t &arity, NODE *body)
+RoxorAOTCompiler::compile_prepare_method(Value *classVal, bool singleton,
+ Value *sel, Function *new_function, rb_vm_arity_t &arity, NODE *body)
{
if (prepareMethodFunc == NULL) {
- // void rb_vm_prepare_method2(Class klass, SEL sel,
- // IMP ruby_imp, rb_vm_arity_t arity, int flags)
+ // void rb_vm_prepare_method2(Class klass, unsigned char singleton,
+ // SEL sel, IMP ruby_imp, rb_vm_arity_t arity, int flags)
prepareMethodFunc =
cast<Function>(module->getOrInsertFunction(
"rb_vm_prepare_method2",
- Type::VoidTy, RubyObjTy, PtrTy, PtrTy,
+ Type::VoidTy, RubyObjTy, Type::Int8Ty, PtrTy, PtrTy,
Type::Int64Ty, Type::Int32Ty, NULL));
}
std::vector<Value *> params;
params.push_back(classVal);
+ params.push_back(ConstantInt::get(Type::Int8Ty, singleton));
params.push_back(sel);
// Make sure the function is compiled before use, this way LLVM won't use
@@ -674,6 +681,7 @@ RoxorAOTCompiler::compile_prepare_method(Value *classVal, Value *sel,
params.push_back(new BitCastInst(new_function, PtrTy, "", bb));
params.push_back(compile_arity(arity));
+
params.push_back(ConstantInt::get(Type::Int32Ty, rb_vm_node_flags(body)));
CallInst::Create(prepareMethodFunc, params.begin(),
@@ -733,7 +741,11 @@ RoxorCompiler::compile_attribute_assign(NODE *node, Value *extra_val)
params.push_back(recv);
params.push_back(compile_sel(sel));
params.push_back(compile_const_pointer(NULL));
- params.push_back(ConstantInt::get(Type::Int8Ty, 0));
+ unsigned char opt = 0;
+ if (recv == current_self) {
+ opt = DISPATCH_SELF_ATTRASGN;
+ }
+ params.push_back(ConstantInt::get(Type::Int8Ty, opt));
params.push_back(ConstantInt::get(Type::Int32Ty, argc));
for (std::vector<Value *>::iterator i = args.begin();
i != args.end();
@@ -2469,7 +2481,7 @@ RoxorCompiler::compile_optimized_dispatch_call(SEL sel, int argc,
new_params.push_back(params[1]);
new_params.push_back(compile_sel(new_sel));
new_params.push_back(params[3]);
- new_params.push_back(params[4]);
+ new_params.push_back(ConstantInt::get(Type::Int8Ty, DISPATCH_FCALL));
new_params.push_back(ConstantInt::get(Type::Int32Ty, argc - 1));
for (int i = 0; i < argc - 1; i++) {
new_params.push_back(params[7 + i]);
@@ -2727,6 +2739,40 @@ RoxorAOTCompiler::compile_global_entry(NODE *node)
return new LoadInst(gvar, "", bb);
}
+Value *
+RoxorCompiler::compile_set_current_class(Value *klass)
+{
+ if (setCurrentClassFunc == NULL) {
+ // Class rb_vm_set_current_class(Class klass)
+ setCurrentClassFunc = cast<Function>(
+ module->getOrInsertFunction("rb_vm_set_current_class",
+ RubyObjTy, RubyObjTy, NULL));
+ }
+
+ std::vector<Value *> params;
+ params.push_back(klass);
+
+ return CallInst::Create(setCurrentClassFunc, params.begin(), params.end(),
+ "", bb);
+}
+
+void
+RoxorCompiler::compile_set_current_scope(Value *klass, Value *scope)
+{
+ if (setScopeFunc == NULL) {
+ // void rb_vm_set_current_scope(VALUE mod, int scope)
+ setScopeFunc = cast<Function>(
+ module->getOrInsertFunction("rb_vm_set_current_scope",
+ Type::VoidTy, RubyObjTy, Type::Int32Ty, NULL));
+ }
+
+ std::vector<Value *> params;
+ params.push_back(klass);
+ params.push_back(scope);
+
+ CallInst::Create(setScopeFunc, params.begin(), params.end(), "", bb);
+}
+
void
RoxorCompiler::compile_ivar_slots(Value *klass,
BasicBlock::InstListType &list,
@@ -3692,8 +3738,16 @@ RoxorCompiler::compile_node(NODE *node)
current_module = nd_type(node) == NODE_MODULE;
+ compile_set_current_scope(classVal, publicScope);
+ Value *old_current_class =
+ compile_set_current_class(
+ ConstantInt::get(RubyObjTy, 0));
+
Value *val = compile_node(body->nd_body);
+ compile_set_current_class(old_current_class);
+ compile_set_current_scope(classVal, defaultScope);
+
BasicBlock::InstListType &list = bb->getInstList();
compile_ivar_slots(classVal, list, list.end());
@@ -3844,7 +3898,8 @@ RoxorCompiler::compile_node(NODE *node)
? DISPATCH_SUPER
: (nd_type(node) == NODE_VCALL)
? DISPATCH_VCALL
- : 0;
+ : (nd_type(node) == NODE_FCALL)
+ ? DISPATCH_FCALL : 0;
params.push_back(ConstantInt::get(Type::Int8Ty, call_opt));
// Arguments.
@@ -4271,7 +4326,7 @@ RoxorCompiler::compile_node(NODE *node)
rb_vm_arity_t arity = rb_vm_node_arity(body);
const SEL sel = mid_to_sel(mid, arity.real);
- compile_prepare_method(classVal, compile_sel(sel),
+ compile_prepare_method(classVal, singleton_method, compile_sel(sel),
new_function, arity, body);
return nilVal;
View
@@ -12,9 +12,11 @@
#if defined(__cplusplus)
// For the dispatcher.
-#define DISPATCH_VCALL 1
-#define DISPATCH_SUPER 2
-#define SPLAT_ARG_FOLLOWS 0xdeadbeef
+#define DISPATCH_VCALL 1 // no receiver, no argument
+#define DISPATCH_FCALL 2 // no receiver, one or more arguments
+#define DISPATCH_SUPER 3 // super call
+#define DISPATCH_SELF_ATTRASGN 4 // self attribute assignment
+#define SPLAT_ARG_FOLLOWS 0xdeadbeef
// For defined?
#define DEFINED_IVAR 1
@@ -172,6 +174,8 @@ class RoxorCompiler {
Function *longjmpFunc;
Function *setjmpFunc;
Function *popBrokenValue;
+ Function *setScopeFunc;
+ Function *setCurrentClassFunc;
Constant *zeroVal;
Constant *oneVal;
@@ -183,6 +187,8 @@ class RoxorCompiler {
Constant *undefVal;
Constant *splatArgFollowsVal;
Constant *cObject;
+ Constant *defaultScope;
+ Constant *publicScope;
const Type *RubyObjTy;
const Type *RubyObjPtrTy;
const Type *RubyObjPtrPtrTy;
@@ -222,8 +228,9 @@ class RoxorCompiler {
BasicBlock *thenBB);
void compile_single_when_argument(NODE *arg, Value *comparedToVal,
BasicBlock *thenBB);
- virtual void compile_prepare_method(Value *classVal, Value *sel,
- Function *new_function, rb_vm_arity_t &arity, NODE *body);
+ virtual void compile_prepare_method(Value *classVal, bool singleton,
+ Value *sel, Function *new_function, rb_vm_arity_t &arity,
+ NODE *body);
Value *compile_dispatch_call(std::vector<Value *> &params);
Value *compile_when_splat(Value *comparedToVal, Value *splatVal);
Value *compile_fast_op_call(SEL sel, Value *selfVal, Value *comparedToVal);
@@ -273,6 +280,9 @@ class RoxorCompiler {
virtual Value *compile_immutable_literal(VALUE val);
virtual Value *compile_global_entry(NODE *node);
+ void compile_set_current_scope(Value *klass, Value *scope);
+ Value *compile_set_current_class(Value *klass);
+
Value *compile_landing_pad_header(void);
Value *compile_landing_pad_header(const std::type_info &eh_type);
void compile_landing_pad_footer(bool pop_exception=true);
@@ -333,8 +343,9 @@ class RoxorAOTCompiler : public RoxorCompiler {
Value *compile_mcache(SEL sel, bool super);
Value *compile_ccache(ID id);
Instruction *compile_sel(SEL sel, bool add_to_bb=true);
- void compile_prepare_method(Value *classVal, Value *sel,
- Function *new_function, rb_vm_arity_t &arity, NODE *body);
+ void compile_prepare_method(Value *classVal, bool singleton,
+ Value *sel, Function *new_function, rb_vm_arity_t &arity,
+ NODE *body);
Value *compile_prepare_block_args(Function *func, int *flags);
Value *compile_nsobject(void);
Value *compile_id(ID id);
View
2 id.c
@@ -65,6 +65,7 @@ Init_id(void)
selInit = sel_registerName("init");
selInitialize = sel_registerName("initialize");
selInitialize2 = sel_registerName("initialize:");
+ selInitializeCopy = sel_registerName("initialize_copy:");
selDescription = sel_registerName("description");
selInspect = sel_registerName("inspect");
selNew = sel_registerName("new");
@@ -95,6 +96,7 @@ Init_id(void)
selSingletonMethodAdded = sel_registerName("singleton_method_added:");
selIsEqual = sel_registerName("isEqual:");
selWrite = sel_registerName("write:");
+ selInherited = sel_registerName("inherited:");
cacheEach = rb_vm_get_call_cache(selEach);
#endif
View
2 id.h
@@ -75,6 +75,7 @@ extern SEL selAllocWithZone;
extern SEL selInit;
extern SEL selInitialize;
extern SEL selInitialize2;
+extern SEL selInitializeCopy;
extern SEL selDescription;
extern SEL selInspect;
extern SEL selNew;
@@ -104,6 +105,7 @@ extern SEL selMethodAdded;
extern SEL selSingletonMethodAdded;
extern SEL selIsEqual;
extern SEL selWrite;
+extern SEL selInherited;
extern ID idIncludedModules;
extern ID idIncludedInClasses;
extern ID idAncestors;
Oops, something went wrong.

0 comments on commit 9590d40

Please sign in to comment.