Skip to content

Commit

Permalink
fixing and adding several missing ruby method features
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@2357 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information
lrz committed Aug 22, 2009
1 parent 9239833 commit 9590d40
Show file tree
Hide file tree
Showing 48 changed files with 680 additions and 408 deletions.
3 changes: 3 additions & 0 deletions array.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ rb_equal_fast(VALUE x, VALUE y)
if (SPECIAL_CONST_P(x) && SPECIAL_CONST_P(y) && TYPE(x) == TYPE(y)) { if (SPECIAL_CONST_P(x) && SPECIAL_CONST_P(y) && TYPE(x) == TYPE(y)) {
return Qfalse; return Qfalse;
} }
if (SYMBOL_P(x)) {
return x == y ? Qtrue : Qfalse;
}
return rb_equal(x, y); return rb_equal(x, y);
} }


Expand Down
51 changes: 26 additions & 25 deletions class.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ rb_define_object_special_methods(VALUE klass)
rb_objc_define_method(*(VALUE *)klass, "__new__", rb_objc_define_method(*(VALUE *)klass, "__new__",
rb_class_new_instance_imp, -1); rb_class_new_instance_imp, -1);
rb_objc_define_method(klass, "dup", rb_obj_dup, 0); rb_objc_define_method(klass, "dup", rb_obj_dup, 0);
rb_objc_define_method(klass, "initialize", rb_objc_init, 0); rb_objc_define_private_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_copy", rb_obj_init_copy, 1);


rb_objc_install_method(*(Class *)klass, selAllocWithZone, rb_objc_install_method(*(Class *)klass, selAllocWithZone,
(IMP)rb_obj_imp_allocWithZone); (IMP)rb_obj_imp_allocWithZone);
Expand Down Expand Up @@ -400,20 +400,20 @@ rb_make_metaclass(VALUE obj, VALUE super)
VALUE VALUE
rb_define_class_id(ID id, VALUE super) rb_define_class_id(ID id, VALUE super)
{ {
VALUE klass; if (super == 0) {

super = rb_cObject;
if (!super) super = rb_cObject; }
klass = rb_objc_create_class(rb_id2name(id), super); return rb_objc_create_class(rb_id2name(id), super);

return klass;
} }


VALUE VALUE
rb_class_inherited(VALUE super, VALUE klass) rb_class_inherited(VALUE super, VALUE klass)
{ {
if (rb_vm_running()) { if (rb_vm_running()) {
if (!super) super = rb_cObject; if (super == 0) {
return rb_funcall(super, rb_intern("inherited"), 1, klass); super = rb_cObject;
}
return rb_vm_call(super, selInherited, 1, &klass, false);
} }
return Qnil; return Qnil;
} }
Expand Down Expand Up @@ -717,20 +717,21 @@ rb_mod_ancestors(VALUE mod)
static int static int
ins_methods_push(VALUE name, long type, VALUE ary, long visi) ins_methods_push(VALUE name, long type, VALUE ary, long visi)
{ {
if (type == -1) return ST_CONTINUE; if (type != -1) {

bool visible;
switch (visi) { switch (visi) {
case NOEX_PRIVATE: case NOEX_PRIVATE:
case NOEX_PROTECTED: case NOEX_PROTECTED:
case NOEX_PUBLIC: case NOEX_PUBLIC:
visi = (type == visi); visible = (type == visi);
break; break;
default: default:
visi = (type != NOEX_PRIVATE); visible = (type != NOEX_PRIVATE);
break; break;
} }
if (visi) { if (visible) {
rb_ary_push(ary, name); rb_ary_push(ary, name);
}
} }
return ST_CONTINUE; return ST_CONTINUE;
} }
Expand Down Expand Up @@ -1010,7 +1011,7 @@ rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS),
void void
rb_undef_method(VALUE klass, const char *name) 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 {\ #define SPECIAL_SINGLETON(x,c) do {\
Expand Down
83 changes: 69 additions & 14 deletions compiler.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ RoxorCompiler::RoxorCompiler(void)
longjmpFunc = NULL; longjmpFunc = NULL;
setjmpFunc = NULL; setjmpFunc = NULL;
popBrokenValue = NULL; popBrokenValue = NULL;
setScopeFunc = NULL;
setCurrentClassFunc = NULL;


#if __LP64__ #if __LP64__
RubyObjTy = IntTy = Type::Int64Ty; RubyObjTy = IntTy = Type::Int64Ty;
Expand All @@ -133,6 +135,9 @@ RoxorCompiler::RoxorCompiler(void)
twoVal = ConstantInt::get(IntTy, 2); twoVal = ConstantInt::get(IntTy, 2);
threeVal = ConstantInt::get(IntTy, 3); threeVal = ConstantInt::get(IntTy, 3);


defaultScope = ConstantInt::get(Type::Int32Ty, SCOPE_DEFAULT);
publicScope = ConstantInt::get(Type::Int32Ty, SCOPE_PUBLIC);

RubyObjPtrTy = PointerType::getUnqual(RubyObjTy); RubyObjPtrTy = PointerType::getUnqual(RubyObjTy);
RubyObjPtrPtrTy = PointerType::getUnqual(RubyObjPtrTy); RubyObjPtrPtrTy = PointerType::getUnqual(RubyObjPtrTy);
nilVal = ConstantInt::get(RubyObjTy, Qnil); nilVal = ConstantInt::get(RubyObjTy, Qnil);
Expand Down Expand Up @@ -622,22 +627,23 @@ RoxorCompiler::compile_arity(rb_vm_arity_t &arity)
} }


void void
RoxorCompiler::compile_prepare_method(Value *classVal, Value *sel, RoxorCompiler::compile_prepare_method(Value *classVal, bool singleton,
Function *new_function, rb_vm_arity_t &arity, NODE *body) Value *sel, Function *new_function, rb_vm_arity_t &arity, NODE *body)
{ {
if (prepareMethodFunc == NULL) { if (prepareMethodFunc == NULL) {
// void rb_vm_prepare_method(Class klass, SEL sel, // void rb_vm_prepare_method(Class klass, unsigned char singleton,
// Function *func, rb_vm_arity_t arity, int flags) // SEL sel, Function *func, rb_vm_arity_t arity, int flags)
prepareMethodFunc = prepareMethodFunc =
cast<Function>(module->getOrInsertFunction( cast<Function>(module->getOrInsertFunction(
"rb_vm_prepare_method", "rb_vm_prepare_method",
Type::VoidTy, RubyObjTy, PtrTy, PtrTy, Type::VoidTy, RubyObjTy, Type::Int8Ty, PtrTy, PtrTy,
Type::Int64Ty, Type::Int32Ty, NULL)); Type::Int64Ty, Type::Int32Ty, NULL));
} }


std::vector<Value *> params; std::vector<Value *> params;


params.push_back(classVal); params.push_back(classVal);
params.push_back(ConstantInt::get(Type::Int8Ty, singleton));
params.push_back(sel); params.push_back(sel);


params.push_back(compile_const_pointer(new_function)); params.push_back(compile_const_pointer(new_function));
Expand All @@ -650,22 +656,23 @@ RoxorCompiler::compile_prepare_method(Value *classVal, Value *sel,
} }


void void
RoxorAOTCompiler::compile_prepare_method(Value *classVal, Value *sel, RoxorAOTCompiler::compile_prepare_method(Value *classVal, bool singleton,
Function *new_function, rb_vm_arity_t &arity, NODE *body) Value *sel, Function *new_function, rb_vm_arity_t &arity, NODE *body)
{ {
if (prepareMethodFunc == NULL) { if (prepareMethodFunc == NULL) {
// void rb_vm_prepare_method2(Class klass, SEL sel, // void rb_vm_prepare_method2(Class klass, unsigned char singleton,
// IMP ruby_imp, rb_vm_arity_t arity, int flags) // SEL sel, IMP ruby_imp, rb_vm_arity_t arity, int flags)
prepareMethodFunc = prepareMethodFunc =
cast<Function>(module->getOrInsertFunction( cast<Function>(module->getOrInsertFunction(
"rb_vm_prepare_method2", "rb_vm_prepare_method2",
Type::VoidTy, RubyObjTy, PtrTy, PtrTy, Type::VoidTy, RubyObjTy, Type::Int8Ty, PtrTy, PtrTy,
Type::Int64Ty, Type::Int32Ty, NULL)); Type::Int64Ty, Type::Int32Ty, NULL));
} }


std::vector<Value *> params; std::vector<Value *> params;


params.push_back(classVal); params.push_back(classVal);
params.push_back(ConstantInt::get(Type::Int8Ty, singleton));
params.push_back(sel); params.push_back(sel);


// Make sure the function is compiled before use, this way LLVM won't use // Make sure the function is compiled before use, this way LLVM won't use
Expand All @@ -674,6 +681,7 @@ RoxorAOTCompiler::compile_prepare_method(Value *classVal, Value *sel,
params.push_back(new BitCastInst(new_function, PtrTy, "", bb)); params.push_back(new BitCastInst(new_function, PtrTy, "", bb));


params.push_back(compile_arity(arity)); params.push_back(compile_arity(arity));

params.push_back(ConstantInt::get(Type::Int32Ty, rb_vm_node_flags(body))); params.push_back(ConstantInt::get(Type::Int32Ty, rb_vm_node_flags(body)));


CallInst::Create(prepareMethodFunc, params.begin(), CallInst::Create(prepareMethodFunc, params.begin(),
Expand Down Expand Up @@ -733,7 +741,11 @@ RoxorCompiler::compile_attribute_assign(NODE *node, Value *extra_val)
params.push_back(recv); params.push_back(recv);
params.push_back(compile_sel(sel)); params.push_back(compile_sel(sel));
params.push_back(compile_const_pointer(NULL)); 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)); params.push_back(ConstantInt::get(Type::Int32Ty, argc));
for (std::vector<Value *>::iterator i = args.begin(); for (std::vector<Value *>::iterator i = args.begin();
i != args.end(); i != args.end();
Expand Down Expand Up @@ -2469,7 +2481,7 @@ RoxorCompiler::compile_optimized_dispatch_call(SEL sel, int argc,
new_params.push_back(params[1]); new_params.push_back(params[1]);
new_params.push_back(compile_sel(new_sel)); new_params.push_back(compile_sel(new_sel));
new_params.push_back(params[3]); 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)); new_params.push_back(ConstantInt::get(Type::Int32Ty, argc - 1));
for (int i = 0; i < argc - 1; i++) { for (int i = 0; i < argc - 1; i++) {
new_params.push_back(params[7 + i]); new_params.push_back(params[7 + i]);
Expand Down Expand Up @@ -2727,6 +2739,40 @@ RoxorAOTCompiler::compile_global_entry(NODE *node)
return new LoadInst(gvar, "", bb); 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 void
RoxorCompiler::compile_ivar_slots(Value *klass, RoxorCompiler::compile_ivar_slots(Value *klass,
BasicBlock::InstListType &list, BasicBlock::InstListType &list,
Expand Down Expand Up @@ -3692,8 +3738,16 @@ RoxorCompiler::compile_node(NODE *node)


current_module = nd_type(node) == NODE_MODULE; 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); 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(); BasicBlock::InstListType &list = bb->getInstList();
compile_ivar_slots(classVal, list, list.end()); compile_ivar_slots(classVal, list, list.end());


Expand Down Expand Up @@ -3844,7 +3898,8 @@ RoxorCompiler::compile_node(NODE *node)
? DISPATCH_SUPER ? DISPATCH_SUPER
: (nd_type(node) == NODE_VCALL) : (nd_type(node) == NODE_VCALL)
? DISPATCH_VCALL ? DISPATCH_VCALL
: 0; : (nd_type(node) == NODE_FCALL)
? DISPATCH_FCALL : 0;
params.push_back(ConstantInt::get(Type::Int8Ty, call_opt)); params.push_back(ConstantInt::get(Type::Int8Ty, call_opt));


// Arguments. // Arguments.
Expand Down Expand Up @@ -4271,7 +4326,7 @@ RoxorCompiler::compile_node(NODE *node)
rb_vm_arity_t arity = rb_vm_node_arity(body); rb_vm_arity_t arity = rb_vm_node_arity(body);
const SEL sel = mid_to_sel(mid, arity.real); 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); new_function, arity, body);


return nilVal; return nilVal;
Expand Down
25 changes: 18 additions & 7 deletions compiler.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
#if defined(__cplusplus) #if defined(__cplusplus)


// For the dispatcher. // For the dispatcher.
#define DISPATCH_VCALL 1 #define DISPATCH_VCALL 1 // no receiver, no argument
#define DISPATCH_SUPER 2 #define DISPATCH_FCALL 2 // no receiver, one or more arguments
#define SPLAT_ARG_FOLLOWS 0xdeadbeef #define DISPATCH_SUPER 3 // super call
#define DISPATCH_SELF_ATTRASGN 4 // self attribute assignment
#define SPLAT_ARG_FOLLOWS 0xdeadbeef


// For defined? // For defined?
#define DEFINED_IVAR 1 #define DEFINED_IVAR 1
Expand Down Expand Up @@ -172,6 +174,8 @@ class RoxorCompiler {
Function *longjmpFunc; Function *longjmpFunc;
Function *setjmpFunc; Function *setjmpFunc;
Function *popBrokenValue; Function *popBrokenValue;
Function *setScopeFunc;
Function *setCurrentClassFunc;


Constant *zeroVal; Constant *zeroVal;
Constant *oneVal; Constant *oneVal;
Expand All @@ -183,6 +187,8 @@ class RoxorCompiler {
Constant *undefVal; Constant *undefVal;
Constant *splatArgFollowsVal; Constant *splatArgFollowsVal;
Constant *cObject; Constant *cObject;
Constant *defaultScope;
Constant *publicScope;
const Type *RubyObjTy; const Type *RubyObjTy;
const Type *RubyObjPtrTy; const Type *RubyObjPtrTy;
const Type *RubyObjPtrPtrTy; const Type *RubyObjPtrPtrTy;
Expand Down Expand Up @@ -222,8 +228,9 @@ class RoxorCompiler {
BasicBlock *thenBB); BasicBlock *thenBB);
void compile_single_when_argument(NODE *arg, Value *comparedToVal, void compile_single_when_argument(NODE *arg, Value *comparedToVal,
BasicBlock *thenBB); BasicBlock *thenBB);
virtual void compile_prepare_method(Value *classVal, Value *sel, virtual void compile_prepare_method(Value *classVal, bool singleton,
Function *new_function, rb_vm_arity_t &arity, NODE *body); Value *sel, Function *new_function, rb_vm_arity_t &arity,
NODE *body);
Value *compile_dispatch_call(std::vector<Value *> &params); Value *compile_dispatch_call(std::vector<Value *> &params);
Value *compile_when_splat(Value *comparedToVal, Value *splatVal); Value *compile_when_splat(Value *comparedToVal, Value *splatVal);
Value *compile_fast_op_call(SEL sel, Value *selfVal, Value *comparedToVal); Value *compile_fast_op_call(SEL sel, Value *selfVal, Value *comparedToVal);
Expand Down Expand Up @@ -273,6 +280,9 @@ class RoxorCompiler {
virtual Value *compile_immutable_literal(VALUE val); virtual Value *compile_immutable_literal(VALUE val);
virtual Value *compile_global_entry(NODE *node); 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(void);
Value *compile_landing_pad_header(const std::type_info &eh_type); Value *compile_landing_pad_header(const std::type_info &eh_type);
void compile_landing_pad_footer(bool pop_exception=true); void compile_landing_pad_footer(bool pop_exception=true);
Expand Down Expand Up @@ -333,8 +343,9 @@ class RoxorAOTCompiler : public RoxorCompiler {
Value *compile_mcache(SEL sel, bool super); Value *compile_mcache(SEL sel, bool super);
Value *compile_ccache(ID id); Value *compile_ccache(ID id);
Instruction *compile_sel(SEL sel, bool add_to_bb=true); Instruction *compile_sel(SEL sel, bool add_to_bb=true);
void compile_prepare_method(Value *classVal, Value *sel, void compile_prepare_method(Value *classVal, bool singleton,
Function *new_function, rb_vm_arity_t &arity, NODE *body); Value *sel, Function *new_function, rb_vm_arity_t &arity,
NODE *body);
Value *compile_prepare_block_args(Function *func, int *flags); Value *compile_prepare_block_args(Function *func, int *flags);
Value *compile_nsobject(void); Value *compile_nsobject(void);
Value *compile_id(ID id); Value *compile_id(ID id);
Expand Down
2 changes: 2 additions & 0 deletions id.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Init_id(void)
selInit = sel_registerName("init"); selInit = sel_registerName("init");
selInitialize = sel_registerName("initialize"); selInitialize = sel_registerName("initialize");
selInitialize2 = sel_registerName("initialize:"); selInitialize2 = sel_registerName("initialize:");
selInitializeCopy = sel_registerName("initialize_copy:");
selDescription = sel_registerName("description"); selDescription = sel_registerName("description");
selInspect = sel_registerName("inspect"); selInspect = sel_registerName("inspect");
selNew = sel_registerName("new"); selNew = sel_registerName("new");
Expand Down Expand Up @@ -95,6 +96,7 @@ Init_id(void)
selSingletonMethodAdded = sel_registerName("singleton_method_added:"); selSingletonMethodAdded = sel_registerName("singleton_method_added:");
selIsEqual = sel_registerName("isEqual:"); selIsEqual = sel_registerName("isEqual:");
selWrite = sel_registerName("write:"); selWrite = sel_registerName("write:");
selInherited = sel_registerName("inherited:");


cacheEach = rb_vm_get_call_cache(selEach); cacheEach = rb_vm_get_call_cache(selEach);
#endif #endif
Expand Down
2 changes: 2 additions & 0 deletions id.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ extern SEL selAllocWithZone;
extern SEL selInit; extern SEL selInit;
extern SEL selInitialize; extern SEL selInitialize;
extern SEL selInitialize2; extern SEL selInitialize2;
extern SEL selInitializeCopy;
extern SEL selDescription; extern SEL selDescription;
extern SEL selInspect; extern SEL selInspect;
extern SEL selNew; extern SEL selNew;
Expand Down Expand Up @@ -104,6 +105,7 @@ extern SEL selMethodAdded;
extern SEL selSingletonMethodAdded; extern SEL selSingletonMethodAdded;
extern SEL selIsEqual; extern SEL selIsEqual;
extern SEL selWrite; extern SEL selWrite;
extern SEL selInherited;
extern ID idIncludedModules; extern ID idIncludedModules;
extern ID idIncludedInClasses; extern ID idIncludedInClasses;
extern ID idAncestors; extern ID idAncestors;
Expand Down
Loading

0 comments on commit 9590d40

Please sign in to comment.