-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathvariable.c
More file actions
163 lines (146 loc) · 5.86 KB
/
variable.c
File metadata and controls
163 lines (146 loc) · 5.86 KB
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "load_so.h"
VALUE rb_cObject, rb_mKernel, rb_cModule, rb_cClass, rb_cArray, rb_cString, rb_cFloat, rb_cHash, rb_cProc, rb_cData;
VALUE rb_cFixnum, rb_cBignum, rb_cTrueClass, rb_cSymbol, rb_cNilClass, rb_cFalseClass, rb_cTime, rb_cEncoding, rb_cThread;
VALUE rb_cMethod, rb_cUnboundMethod;
VALUE rb_mGC;
VALUE rb_eRuntimeError, rb_eLoadError, rb_eTypeError, rb_eArgError, rb_eNotImpError, rb_eSecurityError, rb_eNoMethodError, rb_eIndexError;
VALUE rb_eFatal, rb_eRangeError;
static VALUE (*rb_mod_const_get)(int, VALUE*, VALUE);
static VALUE (*rb_mod_const_set)(VALUE, VALUE, VALUE);
static VALUE (*rb_obj_ivar_set)(VALUE, VALUE, VALUE);
static VALUE (*rb_obj_ivar_get)(VALUE, VALUE);
static VALUE (*rb_obj_ivar_defined_p)(VALUE, VALUE);
static ID tLAST_TOKEN;
#define ID_SCOPE_MASK 0x07
#define ID_INSTANCE 0x01
#define ID_CONST 0x05
#define is_notop_id(id) ((id)>tLAST_TOKEN)
#define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
#define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
int rb_is_const_id(ID id) {
int retval = is_const_id(id);
return retval;
}
VALUE rb_const_get(VALUE klass, ID id) {
VALUE sym = ID2SYM(id);
VALUE ret = rb_mod_const_get(1, &sym, klass);
return ret;
}
static VALUE const_get_cstr(VALUE klass, const char *name) {
set_buf_string(name);
return rb_mod_const_get(1, &value_buf_string, klass);
}
void rb_const_set(VALUE klass, ID id, VALUE val) {
VALUE sym = ID2SYM(id);
rb_mod_const_set(klass, sym, val);
}
void rb_define_const(VALUE klass, const char *name, VALUE val) {
rb_mod_const_set(klass, set_buf_string(name), val);
}
VALUE rb_ivar_set(VALUE obj, ID id, VALUE val) {
VALUE ivar_table, inner_table;
if(is_instance_id(id)) {
return rb_obj_ivar_set(obj, ID2SYM(id), val);
}
/* TODO
switch (TYPE(obj)) {
case T_OBJECT:
case T_CLASS:
case T_MODULE:
rb_raise(rb_eNotImpError, "TODO: rb_ivar_set(obj_or_class_or_mod, :not_ivar_name, val) is not implemented yet.");
}
*/
ivar_table = rb_eval_string("$__loadso__ivar_table");
inner_table = rb_hash_aref(ivar_table, obj);
if(!inner_table) {
inner_table = rb_hash_new();
rb_hash_aset(ivar_table, obj, inner_table);
}
return rb_hash_aset(inner_table, ID2SYM(id), val);
}
VALUE rb_ivar_get(VALUE obj, ID id) {
VALUE ivar_table, inner_table;
if(is_instance_id(id)) {
return rb_obj_ivar_get(obj, ID2SYM(id));
}
/* TODO
switch (TYPE(obj)) {
case T_OBJECT:
case T_CLASS:
case T_MODULE:
rb_raise(rb_eNotImpError, "TODO: rb_ivar_get(obj_or_class_or_mod, :not_ivar_name, val) is not implemented yet.");
}
*/
ivar_table = rb_eval_string("$__loadso__ivar_table");
inner_table = rb_hash_aref(ivar_table, obj);
if(!inner_table) {
return Qnil;
}
return rb_hash_aref(inner_table, ID2SYM(id));
}
VALUE rb_ivar_defined(VALUE obj, ID id) {
VALUE ivar_table, inner_table;
if(is_instance_id(id)) {
return rb_obj_ivar_defined_p(obj, ID2SYM(id));
}
/* TODO
switch (TYPE(obj)) {
case T_OBJECT:
case T_CLASS:
case T_MODULE:
rb_raise(rb_eNotImpError, "TODO: rb_ivar_get(obj_or_class_or_mod, :not_ivar_name, val) is not implemented yet.");
}
*/
ivar_table = rb_eval_string("$__loadso__ivar_table");
inner_table = rb_hash_aref(ivar_table, obj);
if(inner_table) {
return rb_hash_has_key(inner_table, ID2SYM(id));
}
return Qfalse;
}
VALUE rb_path2class(const char *path) {
/* TODO: too insecure and slow. */
return rb_eval_string(path);
}
void Init_VariableCore() {
rb_mod_const_get = get_method(rb_cObject, "const_get");
rb_mGC = const_get_cstr(rb_cObject, "GC");
rb_mKernel = const_get_cstr(rb_cObject, "Kernel");
rb_cNilClass = const_get_cstr(rb_cObject, "NilClass");
rb_cTrueClass = const_get_cstr(rb_cObject, "TrueClass");
rb_cFalseClass = const_get_cstr(rb_cObject, "FalseClass");
rb_cSymbol = const_get_cstr(rb_cObject, "Symbol");
rb_cClass = const_get_cstr(rb_cObject, "Class");
rb_cModule = const_get_cstr(rb_cObject, "Module");
rb_cFixnum = const_get_cstr(rb_cObject, "Fixnum");
rb_cArray = const_get_cstr(rb_cObject, "Array");
rb_cHash = const_get_cstr(rb_cObject, "Hash");
rb_cString = const_get_cstr(rb_cObject, "String");
rb_cProc = const_get_cstr(rb_cObject, "Proc");
rb_cMethod = const_get_cstr(rb_cObject, "Method");
rb_cUnboundMethod = const_get_cstr(rb_cObject, "UnboundMethod");
rb_cThread = const_get_cstr(rb_cObject, "Thread");
rb_cFloat = const_get_cstr(rb_cObject, "Float");
rb_cBignum = const_get_cstr(rb_cObject, "Bignum");
rb_cData = const_get_cstr(rb_cObject, "Data");
rb_cTime = const_get_cstr(rb_cObject, "Time");
rb_cEncoding = const_get_cstr(rb_cObject, "Encoding");
rb_eRuntimeError = const_get_cstr(rb_cObject, "RuntimeError");
rb_eLoadError = const_get_cstr(rb_cObject, "LoadError");
rb_eTypeError = const_get_cstr(rb_cObject, "TypeError");
rb_eArgError = const_get_cstr(rb_cObject, "ArgumentError");
rb_eNotImpError = const_get_cstr(rb_cObject, "NotImplementedError");
rb_eSecurityError = const_get_cstr(rb_cObject, "SecurityError");
rb_eNoMethodError = const_get_cstr(rb_cObject, "NoMethodError");
rb_eIndexError = const_get_cstr(rb_cObject, "IndexError");
rb_eRangeError = const_get_cstr(rb_cObject, "RangeError");
}
void Init_Variable() {
/* VALUE ivar_table = */ rb_eval_string("$__loadso__ivar_table = Hash.new(false)");
rb_eFatal = rb_eval_string("ObjectSpace.each_object(Class).find{|c|c.to_s=='fatal'}");
rb_mod_const_set = get_method(rb_cObject, "const_set");
rb_obj_ivar_set = get_method(rb_cObject, "instance_variable_set");
rb_obj_ivar_get = get_method(rb_cObject, "instance_variable_get");
rb_obj_ivar_defined_p = get_method(rb_cObject, "instance_variable_defined?");
tLAST_TOKEN = rb_intern("core#set_postexe") + 10;
}