Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 65b9bd1

Browse files
committedAug 30, 2015
Fixed guarding references when calling methods from the VM.
1 parent e12ce1a commit 65b9bd1

16 files changed

+252
-173
lines changed
 

‎vm/builtin/array.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "dispatch.hpp"
44
#include "object_utils.hpp"
55
#include "object_memory.hpp"
6+
#include "on_stack.hpp"
67

78
#include "builtin/array.hpp"
89
#include "builtin/class.hpp"
@@ -150,12 +151,11 @@ namespace rubinius {
150151
Exception::type_error(state, "to_ary should return an Array", call_frame);
151152
return 0;
152153
}
153-
154-
// NOTE: On >= 1.9, if res is nil just fall through and return [value]
155154
}
156155

157156
Array* ary = Array::create(state, 1);
158157
ary->set(state, 0, value);
158+
159159
return ary;
160160
}
161161

‎vm/builtin/autoload.cpp

+14-12
Original file line numberDiff line numberDiff line change
@@ -14,45 +14,47 @@ namespace rubinius {
1414
return state->memory()->new_object<Autoload>(state, G(autoload));
1515
}
1616

17-
Object* Autoload::resolve(STATE, CallFrame* call_frame, Module* under, bool honor_require) {
17+
Object* Autoload::resolve(STATE, CallFrame* call_frame,
18+
Module* under, bool honor_require)
19+
{
1820
Autoload* self = this;
19-
OnStack<1> os(state, self);
20-
Object* res = send(state, call_frame, state->symbol("resolve"));
21+
OnStack<2> os(state, self, under);
2122

23+
Object* res = send(state, call_frame, state->symbol("resolve"));
2224
if(!res) return NULL;
2325

2426
if(CBOOL(res) || !honor_require) {
2527
ConstantMissingReason reason = vNonExistent;
26-
Object* constant = Helpers::const_get_under(state, under, self->name(), &reason, self, true);
28+
Object* constant = Helpers::const_get_under(
29+
state, under, self->name(), &reason, self, true);
2730

2831
if(!constant) return NULL;
32+
if(reason == vFound) return constant;
2933

30-
if(reason == vFound) {
31-
return constant;
32-
}
3334
return Helpers::const_missing_under(state, under, self->name(), call_frame);
3435
}
36+
3537
return cNil;
3638
}
3739

3840
Object* Autoload::resolve(STATE, CallFrame* call_frame, bool honor_require) {
3941
Autoload* self = this;
4042
OnStack<1> os(state, self);
41-
Object* res = send(state, call_frame, state->symbol("resolve"));
4243

44+
Object* res = send(state, call_frame, state->symbol("resolve"));
4345
if(!res) return NULL;
4446

4547
if(CBOOL(res) || !honor_require) {
4648
ConstantMissingReason reason = vNonExistent;
47-
Object* constant = Helpers::const_get(state, call_frame, self->name(), &reason, self, true);
49+
Object* constant = Helpers::const_get(
50+
state, call_frame, self->name(), &reason, self, true);
4851

4952
if(!constant) return NULL;
53+
if(reason == vFound) return constant;
5054

51-
if(reason == vFound) {
52-
return constant;
53-
}
5455
return Helpers::const_missing(state, self->name(), call_frame);
5556
}
57+
5658
return cNil;
5759
}
5860
}

‎vm/builtin/block_environment.cpp

+20-5
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,15 @@ namespace rubinius {
220220

221221
if(!(ary = try_as<Array>(obj))) {
222222
if(CBOOL(obj->respond_to(state, G(sym_to_ary), cFalse))) {
223-
if(!(obj = obj->send(state, call_frame, G(sym_to_ary)))) {
224-
return false;
223+
{
224+
/* The references in args are not visible to the GC and
225+
* there's not a simple mechanism to manage that now.
226+
*/
227+
ObjectMemory::GCInhibit inhibitor(state);
228+
229+
if(!(obj = obj->send(state, call_frame, G(sym_to_ary)))) {
230+
return false;
231+
}
225232
}
226233

227234
if(!(ary = try_as<Array>(obj)) && !obj->nil_p()) {
@@ -264,15 +271,23 @@ namespace rubinius {
264271
if(mcode->keywords && N > M) {
265272
Object* obj = args.get_argument(args.total() - 1);
266273

267-
OnStack<1> os(state, obj);
268274
Object* arguments[2];
269275

270276
arguments[0] = obj;
271277
arguments[1] = RBOOL(O > 0 || RP);
272278
Arguments args(G(sym_keyword_object), G(runtime), 2, arguments);
273-
Dispatch dis(G(sym_keyword_object));
279+
Dispatch dispatch(G(sym_keyword_object));
280+
281+
Object* kw_result;
274282

275-
Object* kw_result = dis.send(state, call_frame, args);
283+
{
284+
/* The references in args are not visible to the GC and
285+
* there's not a simple mechanism to manage that now.
286+
*/
287+
ObjectMemory::GCInhibit inhibitor(state);
288+
289+
kw_result = dispatch.send(state, call_frame, args);
290+
}
276291

277292
if(kw_result) {
278293
if(Array* ary = try_as<Array>(kw_result)) {

‎vm/builtin/call_site.cpp

+63-50
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,29 @@ namespace rubinius {
3838
return Integer::from(state, ip_);
3939
}
4040

41-
Object* CallSite::empty_cache_custom(STATE, CallSite* call_site, CallFrame* call_frame,
42-
Arguments& args)
41+
Object* CallSite::empty_cache_custom(STATE, CallSite* call_site,
42+
CallFrame* call_frame, Arguments& args)
4343
{
4444
Object* const recv = args.recv();
4545

46-
Array* ary = Array::create(state, args.total() + 2);
46+
Array* ary = Array::create(state, args.total() + 2);
4747
ary->set(state, 0, recv);
4848
ary->set(state, 1, call_site->name_);
4949

5050
for(size_t i = 0; i < args.total(); i++) {
5151
ary->set(state, i + 2, args.get_argument(i));
5252
}
5353

54-
Object* ret = G(rubinius)->send(state, call_frame, state->symbol("bind_call"), ary);
54+
Object* ret;
55+
56+
{
57+
/* The references in args are not visible to the GC and
58+
* there's not a simple mechanism to manage that now.
59+
*/
60+
ObjectMemory::GCInhibit inhibitor(state);
61+
62+
ret = G(rubinius)->send(state, call_frame, state->symbol("bind_call"), ary);
63+
}
5564

5665
if(CallUnit* cu = try_as<CallUnit>(ret)) {
5766
CallCustomCache* cache = CallCustomCache::create(state, call_site, cu);
@@ -63,28 +72,28 @@ namespace rubinius {
6372
}
6473
}
6574

66-
Object* CallSite::empty_cache(STATE, CallSite* call_site, CallFrame* call_frame,
67-
Arguments& args)
75+
Object* CallSite::empty_cache(STATE, CallSite* call_site,
76+
CallFrame* call_frame, Arguments& args)
6877
{
6978
Object* const recv = args.recv();
7079
Class* const recv_class = recv->direct_class(state);
7180

7281
LookupData lookup(call_frame->self(), recv->lookup_begin(state), G(sym_public));
73-
Dispatch dis(call_site->name());
82+
Dispatch dispatch(call_site->name());
7483

75-
if(!dis.resolve(state, call_site->name(), lookup)) {
84+
if(!dispatch.resolve(state, call_site->name(), lookup)) {
7685
if(!lookup_method_missing(state, call_frame, args,
77-
dis, call_frame->self(), recv->lookup_begin(state))) {
86+
dispatch, call_frame->self(), recv->lookup_begin(state))) {
7887
return NULL;
7988
}
8089
}
8190

8291
state->vm()->metrics().machine.methods_invoked++;
8392

84-
call_site->update(state, recv_class, dis);
93+
call_site->update(state, recv_class, dispatch);
8594

86-
Executable* meth = dis.method;
87-
Module* mod = dis.module;
95+
Executable* meth = dispatch.method;
96+
Module* mod = dispatch.module;
8897

8998
if(meth->custom_call_site_p()) {
9099
CallSiteInformation info(call_site->executable(), call_site->ip());
@@ -104,21 +113,21 @@ namespace rubinius {
104113
Class* const recv_class = recv->direct_class(state);
105114

106115
LookupData lookup(call_frame->self(), recv->lookup_begin(state), G(sym_private));
107-
Dispatch dis(call_site->name());
116+
Dispatch dispatch(call_site->name());
108117

109-
if(!dis.resolve(state, dis.name, lookup)) {
118+
if(!dispatch.resolve(state, dispatch.name, lookup)) {
110119
if(!lookup_method_missing(state, call_frame, args,
111-
dis, call_frame->self(), recv->lookup_begin(state))) {
120+
dispatch, call_frame->self(), recv->lookup_begin(state))) {
112121
return NULL;
113122
}
114123
}
115124

116125
state->vm()->metrics().machine.methods_invoked++;
117126

118-
call_site->update(state, recv_class, dis);
127+
call_site->update(state, recv_class, dispatch);
119128

120-
Executable* meth = dis.method;
121-
Module* mod = dis.module;
129+
Executable* meth = dispatch.method;
130+
Module* mod = dispatch.module;
122131

123132
if(meth->custom_call_site_p()) {
124133
CallSiteInformation info(call_site->executable(), call_site->ip());
@@ -139,22 +148,22 @@ namespace rubinius {
139148
Class* const recv_class = recv->direct_class(state);
140149

141150
LookupData lookup(call_frame->self(), recv->lookup_begin(state), G(sym_private));
142-
Dispatch dis(call_site->name());
151+
Dispatch dispatch(call_site->name());
143152

144-
if(!dis.resolve(state, call_site->name(), lookup)) {
145-
dis.method_missing = eVCall;
153+
if(!dispatch.resolve(state, call_site->name(), lookup)) {
154+
dispatch.method_missing = eVCall;
146155
if(!lookup_method_missing(state, call_frame, args,
147-
dis, call_frame->self(), recv->lookup_begin(state))) {
156+
dispatch, call_frame->self(), recv->lookup_begin(state))) {
148157
return NULL;
149158
}
150159
}
151160

152161
state->vm()->metrics().machine.methods_invoked++;
153162

154-
call_site->update(state, recv_class, dis);
163+
call_site->update(state, recv_class, dispatch);
155164

156-
Executable* meth = dis.method;
157-
Module* mod = dis.module;
165+
Executable* meth = dispatch.method;
166+
Module* mod = dispatch.module;
158167

159168
if(meth->custom_call_site_p()) {
160169
CallSiteInformation info(call_site->executable(), call_site->ip());
@@ -181,14 +190,15 @@ namespace rubinius {
181190
Module* const start = call_frame->module()->superclass();
182191

183192
LookupData lookup(call_frame->self(), start, G(sym_private));
184-
Dispatch dis(call_site->name());
193+
Dispatch dispatch(call_site->name());
185194

186-
if(start->nil_p() || !dis.resolve(state, call_site->name(), lookup)) {
195+
if(start->nil_p() || !dispatch.resolve(state, call_site->name(), lookup)) {
187196

188-
LookupData missing_lookup(call_frame->self(), recv->lookup_begin(state), G(sym_private));
189-
Dispatch missing_dis(G(sym_method_missing));
197+
LookupData missing_lookup(call_frame->self(),
198+
recv->lookup_begin(state), G(sym_private));
199+
Dispatch missing_dispatch(G(sym_method_missing));
190200

191-
if(!missing_dis.resolve(state, G(sym_method_missing), missing_lookup)) {
201+
if(!missing_dispatch.resolve(state, G(sym_method_missing), missing_lookup)) {
192202
std::ostringstream msg;
193203
msg << "no method_missing for ";
194204
msg << recv_class->to_string(state);
@@ -199,19 +209,19 @@ namespace rubinius {
199209
}
200210

201211
args.unshift(state, call_site->name());
202-
dis.method = missing_dis.method;
203-
dis.module = missing_dis.module;
204-
dis.method_missing = eSuper;
205-
state->vm()->set_method_missing_reason(dis.method_missing);
212+
dispatch.method = missing_dispatch.method;
213+
dispatch.module = missing_dispatch.module;
214+
dispatch.method_missing = eSuper;
215+
state->vm()->set_method_missing_reason(dispatch.method_missing);
206216
state->vm()->global_cache()->add_seen(state, call_site->name());
207217
}
208218

209219
state->vm()->metrics().machine.methods_invoked++;
210220

211-
call_site->update(state, recv_class, dis);
221+
call_site->update(state, recv_class, dispatch);
212222

213-
Executable* meth = dis.method;
214-
Module* mod = dis.module;
223+
Executable* meth = dispatch.method;
224+
Module* mod = dispatch.module;
215225

216226
if(meth->custom_call_site_p()) {
217227
CallSiteInformation info(call_site->executable(), call_site->ip());
@@ -245,34 +255,37 @@ namespace rubinius {
245255
}
246256

247257
LookupData lookup(call_frame->self(), recv->lookup_begin(state), G(sym_public));
248-
Dispatch dis(name_);
258+
Dispatch dispatch(name_);
249259

250-
if(dis.resolve(state, name_, lookup)) {
251-
update(state, recv_class, dis);
252-
return dis.method->serial()->to_native() == serial;
260+
if(dispatch.resolve(state, name_, lookup)) {
261+
update(state, recv_class, dispatch);
262+
return dispatch.method->serial()->to_native() == serial;
253263
}
254264
return false;
255265
}
256266

257-
bool CallSite::lookup_method_missing(STATE, CallFrame* call_frame, Arguments& args, Dispatch& dis, Object* self, Module* begin) {
267+
bool CallSite::lookup_method_missing(STATE, CallFrame* call_frame,
268+
Arguments& args, Dispatch& dispatch, Object* self, Module* begin)
269+
{
258270
LookupData missing_lookup(self, begin, G(sym_private));
259-
Dispatch missing_dis(G(sym_method_missing));
271+
Dispatch missing_dispatch(G(sym_method_missing));
260272

261-
if(!missing_dis.resolve(state, G(sym_method_missing), missing_lookup)) {
273+
if(!missing_dispatch.resolve(state, G(sym_method_missing), missing_lookup)) {
262274
std::ostringstream msg;
263275
msg << "no method_missing for ";
264276
msg << begin->to_string(state);
265-
msg << "#" << dis.name->to_string(state);
277+
msg << "#" << dispatch.name->to_string(state);
266278

267279
Exception::internal_error(state, call_frame, msg.str().c_str());
268280
return false;
269281
}
270282

271-
args.unshift(state, dis.name);
272-
dis.method = missing_dis.method;
273-
dis.module = missing_dis.module;
274-
state->vm()->set_method_missing_reason(dis.method_missing);
275-
state->vm()->global_cache()->add_seen(state, dis.name);
283+
args.unshift(state, dispatch.name);
284+
dispatch.method = missing_dispatch.method;
285+
dispatch.module = missing_dispatch.module;
286+
state->vm()->set_method_missing_reason(dispatch.method_missing);
287+
state->vm()->global_cache()->add_seen(state, dispatch.name);
288+
276289
return true;
277290
}
278291

‎vm/builtin/executable.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@ namespace rubinius {
4949
return execute(state, call_frame, this, mod, args);
5050
}
5151

52-
Object* Executable::default_executor(STATE, CallFrame* call_frame, Executable* exec, Module* mod,
53-
Arguments& args) {
52+
Object* Executable::default_executor(STATE, CallFrame* call_frame,
53+
Executable* exec, Module* mod, Arguments& args)
54+
{
5455
args.unshift2(state, args.recv(), args.name());
5556
args.set_recv(exec);
5657

57-
Dispatch dis(G(sym_call));
58-
return dis.send(state, call_frame, args);
58+
Dispatch dispatch(G(sym_call));
59+
60+
return dispatch.send(state, call_frame, args);
5961
}
6062

6163
void Executable::add_inliner(STATE, ObjectMemory* om, CompiledCode* code) {

0 commit comments

Comments
 (0)
Please sign in to comment.