--- parser3/src/main/execute.C 2017/01/13 13:50:28 1.403 +++ parser3/src/main/execute.C 2020/10/27 22:12:40 1.409 @@ -1,7 +1,7 @@ /** @file Parser: executor part of request class. - Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com) + Copyright (c) 2001-2017 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ @@ -21,7 +21,7 @@ #include "pa_vimage.h" #include "pa_wwrapper.h" -volatile const char * IDENT_EXECUTE_C="$Id: execute.C,v 1.403 2017/01/13 13:50:28 moko Exp $" IDENT_PA_OPCODE_H IDENT_PA_OPERATION_H IDENT_PA_VCODE_FRAME_H IDENT_PA_WWRAPPER_H; +volatile const char * IDENT_EXECUTE_C="$Id: execute.C,v 1.409 2020/10/27 22:12:40 moko Exp $" IDENT_PA_OPCODE_H IDENT_PA_OPERATION_H IDENT_PA_VCODE_FRAME_H IDENT_PA_WWRAPPER_H; //#define DEBUG_EXECUTE @@ -450,7 +450,6 @@ 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(name, &value)) - if(vjunction!=PUT_ELEMENT_REPLACED_ELEMENT) throw Exception(PARSER_RUNTIME, 0, "property value can not be code, use [] or () brackets"); break; @@ -672,6 +671,8 @@ void Request::execute(ArrayOperation& op case OP::OP_OBJECT_POOL: { + debug_name=0; + ArrayOperation& local_ops=*i.next().ops; WContext *saved_wcontext=wcontext; @@ -1250,34 +1251,33 @@ Value& Request::get_element4call(Value& 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(name, value)) - if(vjunction!=PUT_ELEMENT_REPLACED_ELEMENT) { - const Junction& junction = vjunction->junction(); - int param_count=junction.method->params_count; - - 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 }; - - CONSTRUCTOR_FRAME_ACTION(*junction.method, method_frame /*caller*/, junction.self, { - frame.store_params(params, 2); - Temp_disable_default_setter temp(junction.self); - call(frame); - }); - } else { - // setter - if(param_count!=1) - throw Exception(PARSER_RUNTIME, 0, "setter method must have ONE parameter (has %d parameters)", param_count); - - CONSTRUCTOR_FRAME_ACTION(*junction.method, method_frame /*caller*/, junction.self, { - frame.store_params(&value, 1); - call(frame); - }); - } + if(const VJunction* vjunction=ncontext.put_element(name, value)) { + const Junction& junction = vjunction->junction(); + int param_count=junction.method->params_count; + + 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 }; + + CONSTRUCTOR_FRAME_ACTION(*junction.method, method_frame /*caller*/, junction.self, { + frame.store_params(params, 2); + Temp_disable_default_setter temp(junction.self); + call(frame); + }); + } else { + // setter + if(param_count!=1) + throw Exception(PARSER_RUNTIME, 0, "setter method must have ONE parameter (has %d parameters)", param_count); + + CONSTRUCTOR_FRAME_ACTION(*junction.method, method_frame /*caller*/, junction.self, { + frame.store_params(&value, 1); + call(frame); + }); } + } } Value& Request::process_getter(Junction& junction) { @@ -1432,47 +1432,54 @@ void Request::process_write(Value& input write(input_value); } -const String* Request::execute_method(Value& aself, const Method& method, Value* optional_param, bool do_return_string) { - METHOD_FRAME_ACTION(method, method_frame/*caller*/, aself, { +const String* Request::execute_method(VStateless_class& aclass, const String& method_name, Value* optional_param) { + if(const Method *method=aclass.get_method(method_name)){ + METHOD_FRAME_ACTION(*method, method_frame/*caller*/, aclass, { - if(optional_param && method.params_count>0) { - frame.store_params(&optional_param, 1); - } else { - frame.empty_params(); - } + if(optional_param && method->params_count>0) { + frame.store_params(&optional_param, 1); + } else { + frame.empty_params(); + } - // prevent non-string writes for better error reporting - if(do_return_string) + // prevent non-string writes for better error reporting frame.write(frame); + + call(frame); - call(frame); - - return do_return_string ? frame.get_string() : 0; - }); + return &frame.result().as_string(); + }); + } + return 0; } -Request::Execute_nonvirtual_method_result -Request::execute_nonvirtual_method(VStateless_class& aclass, const String& method_name, VString* optional_param, bool do_return_string) { - Execute_nonvirtual_method_result result; - result.method=aclass.get_method(method_name); - if(result.method) - result.string=execute_method(aclass, *result.method, optional_param, do_return_string); - return result; -} +bool Request::execute_method_if_exists(VStateless_class& aclass, const String& method_name, Value* optional_param) { + if(const Method *method=aclass.get_method(method_name)){ + METHOD_FRAME_ACTION(*method, method_frame/*caller*/, aclass, { -const String* Request::execute_virtual_method(Value& aself, const String& method_name) { - 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); - - return 0; + if(optional_param && method->params_count>0) { + frame.store_params(&optional_param, 1); + } else { + frame.empty_params(); + } + + call(frame); + }); + return true; + } + return false; } const String* Request::get_method_filespec(const Method* method){ + Operation::Origin origin=get_method_origin(method); + return origin.file_no ? get_used_filespec(origin.file_no) : NULL; +} + +const Operation::Origin Request::get_method_origin(const Method* method){ + Operation::Origin origin={0, 0, 0}; + if(ArrayOperation* code=method->parser_code) if(code){ - Operation::Origin origin={0, 0, 0}; Array_iterator i(*code); while( i.has_next() ){ switch( i.next().code ){ @@ -1539,9 +1546,9 @@ const String* Request::get_method_filesp default: break; } if(origin.file_no) - return get_used_filespec(origin.file_no); + return origin; } } - return 0; + return origin; }