From: Garthy D Date: 2013-02-25T16:22:08+09:00 Subject: Re: Possible mruby bug in mrb_load_string Hi all, Whoops, I mean 20130222 rather than 20120222. About 3 days ago, not one year and three days. I'm still mentally stuck in 2012 I think. ;) Cheers, Garth On 25/02/13 15:29, Garthy D wrote: > > Hi all, > > I have been having a bit of a play around with mruby (note: mruby, not > MRI Ruby), and I believe I may have found a bug in a recent (20120222) > version. > > Basically, if you call mrb_load_string with something that returns a > class, then make a call on the returned object that throws an exception, > and then call mrb_load_string with a string that makes the same kind of > return, the class in question has somehow vanished from the environment, > and the second load will fail. > > Test program and Makefile below. The test string is simply "Float", > which returns the Float class. The first time it calls it, it is okay. > The second time, "Float" no longer exists. > > Naturally, if you remove the call to 'dummyCall', the second load works > as it should. > > I have seen the problem with other classes as well, although the > specifics of what triggers the problem can vary. It is hard to make a > general statement as to the exact fault. As a general rule, if any Class > is returned from mrb_load_string, and a subsequent call on the return > generates an exception, depending on what you do, the whole Class may or > may not (seem to) be removed from the current environment. > > I was wondering if anyone familiar with mruby would be happy to skim > over my code below and let me know of any mistakes I may have made, and > possibly test out the code with their version of mruby, to see if it > works or fails for them as well. I want to make sure I haven't made a > mistake myself before I report it as a bug in mruby. I hope at least one > person here is using or has used mruby. :} > > I am using mruby as checked out on 20120222, Linux, 64-bit. > > Cheers, > Garth > > ----------------- > floatnom.c > ----------------- > > #include > #include > #include > #include > #include > > static void show_result(mrb_state *mrb, mrb_value v) > { > switch (mrb_type(v)) > { > case MRB_TT_CLASS: > fprintf(stderr, "- Type Class returned.\n"); > break; > case MRB_TT_FALSE: > fprintf(stderr, "- Type false/nil returned.\n"); > break; > default: > fprintf(stderr, "- Type %d returned.\n", mrb_type(v)); > break; > } > > if (mrb->exc) > { > struct RObject *exc = mrb->exc; > mrb->exc = 0; > mrb_value e = mrb_obj_value(exc); > mrb_value e_to_s = mrb_funcall(mrb, e, "to_s", 0); > assert(mrb->exc == 0); > if (mrb_type(e_to_s) == MRB_TT_STRING) > { > char buff[512]; > memcpy(buff, RSTRING_PTR(e_to_s), RSTRING_LEN(e_to_s)); > buff[RSTRING_LEN(e_to_s)] = '\0'; > fprintf(stderr, "- Exception was: %s\n", buff); > } > else > fprintf(stderr, "- Exception could not be identified.\n"); > assert(mrb->exc == 0); > } > else > fprintf(stderr, "- No exception.\n"); > } > > int main(int argc, char *argv[]) > { > mrb_state *mrb = mrb_open(); > > fprintf(stderr, "Loading first string:\n"); > mrb_value v1 = mrb_load_string(mrb, "Float"); > show_result(mrb, v1); > > fprintf(stderr, "Making bad call:\n"); > mrb_value v2 = mrb_funcall(mrb, v1, "dummyCall", 0); > show_result(mrb, v2); > > fprintf(stderr, "Loading same string again. Should work, but doesn't.\n"); > mrb_value v3 = mrb_load_string(mrb, "Float"); > show_result(mrb, v3); > > mrb_close(mrb); > return 0; > } > > ----------------- > Makefile > ----------------- > > floatnom: floatnom.o > gcc -o floatnom floatnom.o -L/path/to/mruby/lib -lmruby -lm > > floatnom.o: floatnom.c > gcc -Wall -o floatnom.o -I/path/to/mruby/include -c floatnom.c > > clean: > rm -f floatnom floatnom.o > > > ----------------- > Typical output > ----------------- > > (May be typos- transcribed by hand) > > Loading first string: > - Type Class returned. > - No exception. > Making bad call: > - Type false/nil returned. > - Exception was: undefined method 'dummyCall' for Float > Loading same string again. Should work, but doesn't. > - Type false/nil returned. > - Exception was: uninitialized constant Float > > > >