--- parser3/src/main/execute.C 2009/08/01 04:58:38 1.353 +++ parser3/src/main/execute.C 2009/08/11 10:19:02 1.356 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_EXECUTE_C="$Date: 2009/08/01 04:58:38 $"; +static const char * const IDENT_EXECUTE_C="$Date: 2009/08/11 10:19:02 $"; #include "pa_opcode.h" #include "pa_array.h" @@ -422,7 +422,7 @@ void Request::execute(ArrayOperation& op const String& name=stack.pop().string(); debug_name=&name; Value& ncontext=stack.pop().value(); - if(const VJunction* vjunction=ncontext.put_element(ncontext, name, &value, false)) + if(const VJunction* vjunction=ncontext.put_element(name, &value, false)) if(vjunction!=PUT_ELEMENT_REPLACED_ELEMENT) throw Exception(PARSER_RUNTIME, 0, @@ -853,7 +853,7 @@ void Request::execute(ArrayOperation& op Value& constructor_value=get_element(*class_value, constructor_name); Junction* junction=constructor_value.get_junction(); - if(!junction || junction->self.get_class()!=class_value) + if(!junction) throw Exception(PARSER_RUNTIME, &constructor_name, "constructor must be declared in class '%s'", @@ -863,7 +863,9 @@ void Request::execute(ArrayOperation& op DEBUG_PRINT_OPS(local_ops) DEBUG_PRINT_STR("->\n") - VMethodFrame frame(*junction, method_frame); + Junction casted=Junction(*class_value, junction->method); + VMethodFrame frame(casted, method_frame); + METHOD_FRAME_ACTION(op_call(frame, true /* constructing */)); if(opcode==OP::OP_CONSTRUCT_OBJECT) stack.push(frame.result().as_value()); @@ -1213,7 +1215,7 @@ void Request::op_call(VMethodFrame& fram if(constructing) { if(junction.method->call_type!=Method::CT_STATIC) { // this is a constructor call - if(new_self=called_class.create_new_value(fpool, 0 /*creating fields only in VClass*/)) { + if(new_self=called_class.create_new_value(fpool)) { // some stateless_class creatable derivates } else throw Exception(PARSER_RUNTIME, @@ -1290,28 +1292,23 @@ void Request::op_call_write(VMethodFrame method_frame=saved_method_frame; } -/** - @bug ^superbase:method would dynamically call ^base:method if there is any -*/ Value& Request::get_element(Value& ncontext, const String& name) { if(wcontext->get_somebody_entered_some_class()) // ^class:method if(VStateless_class *called_class=ncontext.get_class()) if(VStateless_class *read_class=rcontext->get_class()) - if(read_class->derived_from(*called_class)) // current derived from called - if(Value* base=get_self().base()) { // doing DYNAMIC call - Temp_derived temp_derived(*base, 0); // temporarily prevent go-back-down virtual calls - Value *value=base->get_element(name, *base, true); // virtual-up lookup starting from parent - return *(value ? &process_to_value(*value) : VVoid::get()); - } + if(read_class->derived_from(*called_class)){ // current derived from called + Value *value=called_class->get_element(get_self(), name); + return *(value ? &process_to_value(*value) : VVoid::get()); + } - Value* value=ncontext.get_element(name, ncontext, true); + Value* value=ncontext.get_element(name); return *(value ? &process_to_value(*value) : VVoid::get()); } void Request::put_element(Value& ncontext, const String& name, Value* value) { // put_element can return property-setting-junction - if(const VJunction* vjunction=ncontext.put_element(ncontext, name, value, false)) + if(const VJunction* vjunction=ncontext.put_element(name, value, false)) if(vjunction!=PUT_ELEMENT_REPLACED_ELEMENT) { // process it VMethodFrame frame(vjunction->junction(), method_frame/*caller*/); @@ -1356,11 +1353,12 @@ StringOrValue Request::process(Value& in if(junction) { if(junction->is_getter) { // is it a getter-junction? VMethodFrame frame(*junction, method_frame/*caller*/); + Value *param; if(size_t param_count=frame.method_params_count()){ if(junction->auto_name){ // default getter if(param_count==1){ - Value *param=new VString(*junction->auto_name); + param=new VString(*junction->auto_name); frame.store_params(¶m, 1); } else throw Exception(PARSER_RUNTIME, @@ -1380,11 +1378,10 @@ StringOrValue Request::process(Value& in method_frame=&frame; recoursion_checked_execute(*frame.junction.method->parser_code); // parser code, execute it - StringOrValue result=wcontext->result(); RESTORE_CONTEXT - return result; + return frame.result(); } if(junction->code) { // is it a code-junction? @@ -1448,11 +1445,12 @@ void Request::process_write(Value& input if(junction) { if(junction->is_getter) { // is it a getter-junction? VMethodFrame frame(*junction, method_frame/*caller*/); + Value *param; if(size_t param_count=frame.method_params_count()){ if(junction->auto_name){ // default getter if(param_count==1){ - Value *param=new VString(*junction->auto_name); + param=new VString(*junction->auto_name); frame.store_params(¶m, 1); } else throw Exception(PARSER_RUNTIME, @@ -1602,7 +1600,7 @@ Request::execute_nonvirtual_method(VStat const String* Request::execute_virtual_method(Value& aself, const String& method_name) { - if(Value* value=aself.get_element(method_name, aself, false)) + if(Value* value=aself.get_element(method_name)) if(Junction* junction=value->get_junction()) if(const Method *method=junction->method) return execute_method(aself, *method, 0/*no params*/, true);