Permalink
Browse files

supported lexical const lookup. (fixes #619, #626, #1167, #1192) (ref…

…s #1095)
  • Loading branch information...
1 parent 2099c43 commit 6b101bd0e5c95433934ca38e9ff33ae02a9ee2b3 @takaokouji takaokouji committed Apr 24, 2011
Showing with 403 additions and 118 deletions.
  1. +91 −15 compiler.cpp
  2. +9 −0 compiler.h
  3. +4 −0 dispatcher.cpp
  4. +4 −36 eval.c
  5. +6 −0 interpreter.cpp
  6. +17 −7 kernel.c
  7. +1 −14 load.c
  8. +0 −2 spec/frozen/tags/macruby/core/module/nesting_tags.txt
  9. +0 −2 spec/frozen/tags/macruby/language/constants_tags.txt
  10. +2 −2 test_vm/constant.rb
  11. +1 −1 test_vm/eval.rb
  12. +247 −35 vm.cpp
  13. +21 −4 vm.h
View
@@ -76,7 +76,8 @@ RoxorCompiler *RoxorCompiler::shared = NULL;
__save_state(NODE *, ensure_node);\
__save_state(bool, block_declaration);\
__save_state(AllocaInst *, dispatch_argv);\
- __save_state(uint64_t, outer_mask);
+ __save_state(uint64_t, outer_mask);\
+ __save_state(GlobalVariable *, outer_stack);
#define restore_compiler_state() \
__restore_state(current_line);\
@@ -111,7 +112,8 @@ RoxorCompiler *RoxorCompiler::shared = NULL;
__restore_state(ensure_node);\
__restore_state(block_declaration);\
__restore_state(dispatch_argv);\
- __restore_state(outer_mask);
+ __restore_state(outer_mask);\
+ __restore_state(outer_stack);
#define reset_compiler_state() \
bb = NULL;\
@@ -145,7 +147,8 @@ RoxorCompiler *RoxorCompiler::shared = NULL;
ensure_node = NULL;\
block_declaration = false;\
dispatch_argv = NULL;\
- outer_mask = 0;
+ outer_mask = 0;\
+ outer_stack = NULL;
RoxorCompiler::RoxorCompiler(bool _debug_mode)
{
@@ -249,6 +252,9 @@ RoxorCompiler::RoxorCompiler(bool _debug_mode)
setHasEnsureFunc = NULL;
setScopeFunc = get_function("vm_set_current_scope");
setCurrentClassFunc = NULL;
+ pushOuterFunc = NULL;
+ popOuterFunc = NULL;
+ setCurrentOuterFunc = NULL;
debugTrapFunc = NULL;
getFFStateFunc = NULL;
setFFStateFunc = NULL;
@@ -1520,7 +1526,7 @@ RoxorCompiler::compile_constant_declaration(NODE *node, Value *val)
{
int flags = 0;
- Value *args[4];
+ Value *args[5];
if (node->nd_vid > 0) {
args[0] = compile_current_class();
@@ -1535,8 +1541,9 @@ RoxorCompiler::compile_constant_declaration(NODE *node, Value *val)
args[2] = val;
args[3] = ConstantInt::get(Int8Ty,
dynamic_class && (flags & DEFINE_OUTER) ? 1 : 0);
+ args[4] = compile_outer_stack();
- CallInst::Create(setConstFunc, args, args + 4, "", bb);
+ CallInst::Create(setConstFunc, args, args + 5, "", bb);
return val;
}
@@ -1627,15 +1634,19 @@ RoxorCompiler::compile_const(ID id, Value *outer)
if (dynamic_class) {
flags |= CONST_LOOKUP_DYNAMIC_CLASS;
}
+ if (inside_eval) {
+ flags |= CONST_LOOKUP_INSIDE_EVAL;
+ }
Value *args[] = {
outer,
ConstantInt::get(Int64Ty, outer_mask),
compile_ccache(id),
compile_id(id),
- ConstantInt::get(Int32Ty, flags)
+ ConstantInt::get(Int32Ty, flags),
+ compile_outer_stack()
};
- Instruction *insn = compile_protected_call(getConstFunc, args, args + 5);
+ Instruction *insn = compile_protected_call(getConstFunc, args, args + 6);
attach_current_line_metadata(insn);
return insn;
}
@@ -1790,10 +1801,10 @@ RoxorCompiler::compile_defined_expression(NODE *node)
}
if (definedFunc == NULL) {
- // VALUE rb_vm_defined(VALUE self, int type, VALUE what, VALUE what2);
+ // VALUE rb_vm_defined(VALUE self, int type, VALUE what, VALUE what2, rb_vm_outer_t *outer_stack);
definedFunc = cast<Function>(module->getOrInsertFunction(
"rb_vm_defined",
- RubyObjTy, RubyObjTy, Int32Ty, RubyObjTy, RubyObjTy,
+ RubyObjTy, RubyObjTy, Int32Ty, RubyObjTy, RubyObjTy, PtrTy,
NULL));
}
@@ -1804,9 +1815,10 @@ RoxorCompiler::compile_defined_expression(NODE *node)
self,
ConstantInt::get(Int32Ty, type),
what1 == NULL ? nilVal : what1,
- what2 == NULL ? nilVal : what2
+ what2 == NULL ? nilVal : what2,
+ compile_outer_stack()
};
- val = compile_protected_call(definedFunc, args, args + 4);
+ val = compile_protected_call(definedFunc, args, args + 5);
}
else {
val = ConstantInt::get(RubyObjTy, (long)CFSTR("expression"));
@@ -2576,6 +2588,59 @@ RoxorCompiler::compile_set_current_class(Value *klass)
return CallInst::Create(setCurrentClassFunc, klass, "", bb);
}
+Value *
+RoxorCompiler::compile_push_outer(Value *klass)
+{
+ if (pushOuterFunc == NULL) {
+ // rb_vm_outer_t *rb_vm_push_outer(Class klass)
+ pushOuterFunc = cast<Function>(
+ module->getOrInsertFunction("rb_vm_push_outer",
+ PtrTy, RubyObjTy, NULL));
+ }
+
+ Value *val = CallInst::Create(pushOuterFunc, klass, "", bb);
+ outer_stack = new GlobalVariable(*RoxorCompiler::module, PtrTy, false,
+ GlobalValue::InternalLinkage,
+ Constant::getNullValue(PtrTy), "");
+ assert(outer_stack != NULL);
+ new StoreInst(val, outer_stack, "", bb);
+ return val;
+}
+
+Value *
+RoxorCompiler::compile_pop_outer(void)
+{
+ if (popOuterFunc == NULL) {
+ // rb_vm_outer_t *rb_vm_pop_outer(void)
+ popOuterFunc = cast<Function>(
+ module->getOrInsertFunction("rb_vm_pop_outer", PtrTy, NULL));
+ }
+
+ return CallInst::Create(popOuterFunc, "", bb);
+}
+
+Value *
+RoxorCompiler::compile_outer_stack(void)
+{
+ if (outer_stack == NULL) {
+ return compile_const_pointer(NULL);
+ }
+ return new LoadInst(outer_stack, "", bb);
+}
+
+Value *
+RoxorCompiler::compile_set_current_outer(void)
+{
+ if (setCurrentOuterFunc == NULL) {
+ // rb_vm_outer_t *rb_vm_set_current_outer(rb_vm_outer_t *outer)
+ setCurrentOuterFunc = cast<Function>(
+ module->getOrInsertFunction("rb_vm_set_current_outer",
+ PtrTy, PtrTy, NULL));
+ }
+
+ return CallInst::Create(setCurrentOuterFunc, compile_outer_stack(), "", bb);
+}
+
void
RoxorCompiler::compile_set_current_scope(Value *klass, Value *scope)
{
@@ -2886,6 +2951,8 @@ RoxorCompiler::compile_scope(NODE *node)
current_arity = arity;
}
+ compile_set_current_outer();
+
DEBUG_LEVEL_INC();
val = compile_node(node->nd_body);
DEBUG_LEVEL_DEC();
@@ -3932,12 +3999,12 @@ RoxorCompiler::compile_node0(NODE *node)
if (defineClassFunc == NULL) {
// VALUE rb_vm_define_class(ID path, VALUE outer,
// VALUE super, int flags,
- // unsigned char dynamic_class);
+ // unsigned char dynamic_class, rb_vm_outer_t *outer_stack);
defineClassFunc = cast<Function>(
module->getOrInsertFunction(
"rb_vm_define_class",
RubyObjTy, IntTy, RubyObjTy, RubyObjTy,
- Int32Ty, Int8Ty, NULL));
+ Int32Ty, Int8Ty, PtrTy, NULL));
}
int flags = 0;
@@ -3954,10 +4021,11 @@ RoxorCompiler::compile_node0(NODE *node)
ConstantInt::get(Int32Ty, flags),
ConstantInt::get(Int8Ty,
(flags & DEFINE_OUTER) && dynamic_class
- ? 1 : 0)
+ ? 1 : 0),
+ compile_outer_stack()
};
Instruction *insn = compile_protected_call(defineClassFunc,
- args, args + 5);
+ args, args + 6);
attach_current_line_metadata(insn);
classVal = insn;
}
@@ -3977,6 +4045,10 @@ RoxorCompiler::compile_node0(NODE *node)
bool old_current_block_chain = current_block_chain;
bool old_dynamic_class = dynamic_class;
+ GlobalVariable *old_outer_stack = outer_stack;
+ compile_push_outer(classVal);
+ compile_set_current_outer();
+
current_block_chain = false;
dynamic_class = false;
@@ -4016,6 +4088,10 @@ RoxorCompiler::compile_node0(NODE *node)
params.push_back(compile_const_pointer(NULL));
val = compile_protected_call(f, params);
+ compile_pop_outer();
+ outer_stack = old_outer_stack;
+ compile_set_current_outer();
+
dynamic_class = old_dynamic_class;
compile_set_current_scope(classVal, defaultScope);
View
@@ -19,6 +19,7 @@
// For const lookup.
#define CONST_LOOKUP_LEXICAL 1
#define CONST_LOOKUP_DYNAMIC_CLASS 2
+#define CONST_LOOKUP_INSIDE_EVAL 4
// For defined?
#define DEFINED_IVAR 1
@@ -148,6 +149,7 @@ class RoxorCompiler {
bool block_declaration;
AllocaInst *dispatch_argv;
long outer_mask;
+ GlobalVariable *outer_stack;
Function *writeBarrierFunc;
Function *dispatchFunc;
@@ -234,6 +236,9 @@ class RoxorCompiler {
Function *setHasEnsureFunc;
Function *setScopeFunc;
Function *setCurrentClassFunc;
+ Function *pushOuterFunc;
+ Function *popOuterFunc;
+ Function *setCurrentOuterFunc;
Function *debugTrapFunc;
Function *getFFStateFunc;
Function *setFFStateFunc;
@@ -421,6 +426,10 @@ class RoxorCompiler {
void compile_set_current_scope(Value *klass, Value *scope);
Value *compile_set_current_class(Value *klass);
+ Value *compile_push_outer(Value *klass);
+ Value *compile_pop_outer(void);
+ Value *compile_outer_stack(void);
+ Value *compile_set_current_outer(void);
Value *compile_landing_pad_header(void);
void compile_landing_pad_footer(bool pop_exception=true);
View
@@ -1295,6 +1295,9 @@ rb_vm_yield_under(VALUE klass, VALUE self, int argc, const VALUE *argv)
VALUE old_class = b->klass;
b->klass = klass;
+ rb_vm_outer_t *o = vm->push_outer((Class)klass);
+ o->pushed_by_eval = true;
+
struct Finally {
RoxorVM *vm;
rb_vm_block_t *b;
@@ -1308,6 +1311,7 @@ rb_vm_yield_under(VALUE klass, VALUE self, int argc, const VALUE *argv)
old_self = _old_self;
}
~Finally() {
+ vm->pop_outer();
b->self = old_self;
b->klass = old_class;
vm->add_current_block(b);
View
40 eval.c
@@ -229,18 +229,9 @@ ruby_run_node(void *n)
*/
static VALUE
-rb_mod_nesting(VALUE rcv, SEL sel, VALUE top, int argc, VALUE *argv)
+rb_mod_nesting(VALUE self, SEL sel)
{
- rb_scan_args(argc, argv, "00");
-
- switch (TYPE(top)) {
- case T_CLASS:
- case T_MODULE:
- return rb_vm_module_nesting(top);
-
- default:
- return rb_ary_new();
- }
+ return rb_vm_module_nesting();
}
/*
@@ -265,30 +256,7 @@ rb_mod_s_constants(VALUE mod, SEL sel, int argc, VALUE *argv)
if (argc > 0) {
return rb_mod_constants(rb_cModule, 0, argc, argv);
}
-
-#if 0 // TODO
- const NODE *cref = vm_cref();
- VALUE klass;
- VALUE cbase = 0;
- void *data = 0;
-
- while (cref) {
- klass = cref->nd_clss;
- if (!NIL_P(klass)) {
- data = rb_mod_const_at(cref->nd_clss, data);
- if (!cbase) {
- cbase = klass;
- }
- }
- cref = cref->nd_next;
- }
-
- if (cbase) {
- data = rb_mod_const_of(cbase, data);
- }
- return rb_const_list(data);
-#endif
- return Qnil;
+ return rb_vm_module_constants();
}
void
@@ -884,7 +852,7 @@ Init_eval(void)
Init_vm_eval();
Init_eval_method();
- rb_objc_define_method(*(VALUE *)rb_cModule, "nesting", rb_mod_nesting, -3);
+ rb_objc_define_method(*(VALUE *)rb_cModule, "nesting", rb_mod_nesting, 0);
rb_objc_define_method(*(VALUE *)rb_cModule, "constants", rb_mod_s_constants, -1);
VALUE cTopLevel = *(VALUE *)rb_vm_top_self();
View
@@ -120,6 +120,12 @@ RoxorInterpreter::interpret_call(CallInst *call)
return rb_singleton_class(klass);
}
+ else if (called == RoxorCompiler::shared->setCurrentOuterFunc) {
+ rb_vm_outer_t *outer_stack = value_as(call_arg(call, 0), rb_vm_outer_t *);
+
+ rb_vm_set_current_outer(outer_stack);
+ return Qnil;
+ }
oops("unrecognized call instruction:", call);
}
Oops, something went wrong.

0 comments on commit 6b101bd

Please sign in to comment.