forked from rubinius/rubinius
-
Notifications
You must be signed in to change notification settings - Fork 0
/
class.cpp
109 lines (83 loc) · 3.83 KB
/
class.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "builtin/class.hpp"
#include "builtin/module.hpp"
#include "builtin/symbol.hpp"
#include "helpers.hpp"
#include "capi/capi.hpp"
#include "capi/ruby.h"
using namespace rubinius;
using namespace rubinius::capi;
extern "C" {
VALUE rb_class_new_instance(int arg_count, VALUE* args, VALUE class_handle) {
return rb_funcall2(class_handle, rb_intern("new"), arg_count, args);
}
VALUE rb_class_of(VALUE object_handle) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();
Class* class_object = env->get_object(object_handle)->class_object(env->state());
return env->get_handle(class_object);
}
// MUST return the immediate object in the class field, not the real class!
VALUE CLASS_OF(VALUE object_handle) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();
Class* class_object = env->get_object(object_handle)->lookup_begin(env->state());
return env->get_handle(class_object);
}
VALUE rb_class_name(VALUE class_handle) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();
Class* class_object = c_as<Class>(env->get_object(class_handle));
return env->get_handle(class_object->name()->to_str(env->state()));
}
char* rb_class2name(VALUE class_handle) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();
Class* class_object = c_as<Class>(env->get_object(class_handle));
return ::strdup(class_object->name()->c_str(env->state()));
}
VALUE rb_path2class(const char* name) {
return rb_funcall(rb_mKernel, rb_intern("const_lookup"), 1, rb_str_new2(name));
}
VALUE rb_cv_get(VALUE module_handle, const char* name) {
return rb_cvar_get(module_handle, rb_intern(name));
}
VALUE rb_cv_set(VALUE module_handle, const char* name, VALUE value) {
return rb_cvar_set(module_handle, rb_intern(name), value, 0);
}
VALUE rb_cvar_defined(VALUE module_handle, ID name) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();
return rb_funcall(module_handle, rb_intern("class_variable_defined?"),
1,
env->get_handle(prefixed_by("@@", name)));
}
VALUE rb_cvar_get(VALUE module_handle, ID name) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();
return rb_funcall(module_handle, rb_intern("class_variable_set"),
1,
env->get_handle(prefixed_by("@@", name)));
}
VALUE rb_cvar_set(VALUE module_handle, ID name, VALUE value, int unused) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();
return rb_funcall(module_handle, rb_intern("class_variable_set"),
2,
env->get_handle(prefixed_by("@@", name)),
value);
}
VALUE rb_define_class(const char* name, VALUE superclass_handle) {
return rb_define_class_under(rb_cObject, name, superclass_handle);
}
/** @note Shares code with rb_define_module_under, change there too. --rue */
VALUE rb_define_class_under(VALUE outer, const char* name, VALUE super) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();
Module* module = c_as<Module>(env->get_object(outer));
Class* superclass = c_as<Class>(env->get_object(super ? super : rb_cObject));
Symbol* constant = env->state()->symbol(name);
bool created = false;
VALUE klass = env->get_handle(rubinius::Helpers::open_class(env->state(),
env->current_call_frame(), module, superclass, constant, &created));
if(super) rb_funcall(super, rb_intern("inherited"), 1, klass);
return klass;
}
/** @todo Should this be a global handle? Surely not.. --rue */
VALUE rb_singleton_class(VALUE object_handle) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();
Class* metaclass = env->get_object(object_handle)->metaclass(env->state());
return env->get_handle(metaclass);
}
}