--- parser3/src/main/execute.C 2010/08/01 14:49:33 1.363 +++ parser3/src/main/execute.C 2010/10/09 23:17:26 1.366 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_EXECUTE_C="$Date: 2010/08/01 14:49:33 $"; +static const char * const IDENT_EXECUTE_C="$Date: 2010/10/09 23:17:26 $"; #include "pa_opcode.h" #include "pa_array.h" @@ -839,11 +839,12 @@ void Request::execute(ArrayOperation& op Value &object=construct(*class_value, *constructor_junction->method); VConstructorFrame frame(*constructor_junction->method, method_frame, object); METHOD_FRAME_ACTION(op_call(frame)); + object.enable_default_setter(); if(opcode==OP::OP_CONSTRUCT_OBJECT) - stack.push(object); + stack.push(frame.result().as_value()); else - write_pass_lang(object); + write_pass_lang(frame.result()); DEBUG_PRINT_STR("<-returned") break; @@ -1206,8 +1207,7 @@ void Request::op_call(VMethodFrame& fram SAVE_CONTEXT - rcontext=wcontext=&frame; - method_frame=&frame; + rcontext=wcontext=method_frame=&frame; Value& self=frame.self(); const Method& method=frame.method; @@ -1273,31 +1273,67 @@ void Request::put_element(Value& ncontex // put_element can return property-setting-junction if(const VJunction* vjunction=ncontext.put_element(name, value, false)) if(vjunction!=PUT_ELEMENT_REPLACED_ELEMENT) { - // process it const Junction& junction = vjunction->junction(); - VMethodFrame frame(*junction.method, method_frame /*caller*/, junction.self); + VConstructorFrame frame(*junction.method, method_frame /*caller*/, junction.self); size_t param_count=frame.method_params_count(); - if(param_count!=1) - throw Exception(PARSER_RUNTIME, - 0, - "setter method must have ONE parameter (has %d parameters)", param_count); - frame.store_params(&value, 1); + if(junction.auto_name){ + // default setter + if(param_count!=2) + throw Exception(PARSER_RUNTIME, + 0, + "default setter method must have TWO parameters (has %d parameters)", param_count); + + Value* params[2] = { new VString(*junction.auto_name), value }; + frame.store_params(params, 2); + + Temp_disable_default_setter temp(junction.self); + execute_method(frame); + } else { + // setter + if(param_count!=1) + throw Exception(PARSER_RUNTIME, + 0, + "setter method must have ONE parameter (has %d parameters)", param_count); - SAVE_CONTEXT + frame.store_params(&value, 1); + execute_method(frame); + } + } +} - rcontext=wcontext=&frame; - method_frame=&frame; +StringOrValue Request::process_getter(Junction& junction) { + VMethodFrame frame(*junction.method, method_frame/*caller*/, junction.self); + size_t param_count=frame.method_params_count(); + + if(junction.auto_name){ + // default getter + Value *param; - // prevent non-string writes for better error reporting [setters are not expected to return anything] - wcontext->write(*method_frame); + if(param_count){ + if(param_count>1) + throw Exception(PARSER_RUNTIME, + 0, + "default getter method can't have more then 1 parameter (has %d parameters)", param_count); + param=new VString(*junction.auto_name); + frame.store_params(¶m, 1); + } // no need for else frame.empty_params() - recoursion_checked_execute(*frame.method.parser_code); // parser code, execute it - // we don't need it StringOrValue result=wcontext->result(); + Temp_disable_default_getter temp(junction.self); + execute_method(frame); + } else { + // getter + if(param_count!=0) + throw Exception(PARSER_RUNTIME, + 0, + "getter method must have no parameters (has %d parameters)", param_count); + + // no need for frame.empty_params() + execute_method(frame); + } - RESTORE_CONTEXT - } + return frame.result(); } /** @param intercept_string @@ -1311,38 +1347,12 @@ void Request::put_element(Value& ncontex using the fact it's either string_ or value_ result requested to speed up checkes */ + StringOrValue Request::process(Value& input_value, bool intercept_string) { Junction* junction=input_value.get_junction(); if(junction) { if(junction->is_getter) { // is it a getter-junction? - VMethodFrame frame(*junction->method, method_frame/*caller*/, junction->self); - Value *param; - - if(size_t param_count=frame.method_params_count()){ - if(junction->auto_name){ // default getter - if(param_count==1){ - param=new VString(*junction->auto_name); - frame.store_params(¶m, 1); - } else - throw Exception(PARSER_RUNTIME, - 0, - "default getter method can't have more then 1 parameter (has %d parameters)", param_count); - } else - throw Exception(PARSER_RUNTIME, - 0, - "getter method must have no parameters (has %d parameters)", param_count); - } // no need for else frame.empty_params() - - SAVE_CONTEXT - - rcontext=wcontext=&frame; - method_frame=&frame; - - recoursion_checked_execute(*frame.method.parser_code); // parser code, execute it - - RESTORE_CONTEXT - - return frame.result(); + return process_getter(*junction); } if(junction->code) { // is it a code-junction? @@ -1405,34 +1415,7 @@ void Request::process_write(Value& input Junction* junction=input_value.get_junction(); if(junction) { if(junction->is_getter) { // is it a getter-junction? - VMethodFrame frame(*junction->method, method_frame /*caller*/, junction->self); - Value *param; - - if(size_t param_count=frame.method_params_count()){ - if(junction->auto_name){ // default getter - if(param_count==1){ - param=new VString(*junction->auto_name); - frame.store_params(¶m, 1); - } else - throw Exception(PARSER_RUNTIME, - 0, - "default getter method can't have more then 1 parameter (has %d parameters)", param_count); - } else - throw Exception(PARSER_RUNTIME, - 0, - "getter method must have no parameters (has %d parameters)", param_count); - } // no need for else frame.empty_params() - - SAVE_CONTEXT - - rcontext=wcontext=&frame; - method_frame=&frame; - - recoursion_checked_execute(*frame.method.parser_code); // parser code, execute it - - RESTORE_CONTEXT - - write_pass_lang(frame.result()); + write_pass_lang(process_getter(*junction)); return; } @@ -1494,51 +1477,37 @@ void Request::process_write(Value& input write_pass_lang(input_value); } -StringOrValue Request::execute_method(VMethodFrame& amethod_frame, const Method& method) { +void Request::execute_method(VMethodFrame& aframe) { SAVE_CONTEXT // initialize contexts - rcontext=wcontext=method_frame=&amethod_frame; + rcontext=wcontext=method_frame=&aframe; // execute! - execute(*method.parser_code); - - // result - StringOrValue result=wcontext->result(); + recoursion_checked_execute(*aframe.method.parser_code); RESTORE_CONTEXT - - // return - return result; } const String* Request::execute_method(Value& aself, const Method& method, Value* optional_param, bool do_return_string) { - SAVE_CONTEXT - VMethodFrame local_frame(method, method_frame/*caller*/, aself); + if(optional_param && local_frame.method_params_count()>0) { local_frame.store_params(&optional_param, 1); } else { local_frame.empty_params(); } - rcontext=wcontext=method_frame=&local_frame; // prevent non-string writes for better error reporting if(do_return_string) local_frame.write(local_frame); - // execute! - execute(*method.parser_code); - - // result - const String* result=do_return_string ? local_frame.get_string() : 0; + execute_method(local_frame); - RESTORE_CONTEXT - - return result; + return do_return_string ? local_frame.get_string() : 0; } Request::Execute_nonvirtual_method_result