--- parser3/src/main/execute.C 2020/10/27 10:10:08 1.407 +++ parser3/src/main/execute.C 2023/10/06 20:02:50 1.415 @@ -1,8 +1,8 @@ /** @file Parser: executor part of request class. - Copyright (c) 2001-2017 Art. Lebedev Studio (http://www.artlebedev.com) - Author: Alexandr Petrosian (http://paf.design.ru) + Copyright (c) 2001-2023 Art. Lebedev Studio (http://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ #include "pa_opcode.h" @@ -21,7 +21,7 @@ #include "pa_vimage.h" #include "pa_wwrapper.h" -volatile const char * IDENT_EXECUTE_C="$Id: execute.C,v 1.407 2020/10/27 10:10:08 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.415 2023/10/06 20:02:50 moko Exp $" IDENT_PA_OPCODE_H IDENT_PA_OPERATION_H IDENT_PA_VCODE_FRAME_H IDENT_PA_WWRAPPER_H; //#define DEBUG_EXECUTE @@ -280,11 +280,7 @@ void Request::execute(ArrayOperation& op DEBUG_PRINT_STRING(name) - VStateless_class* vclass=get_class(name); - if(!vclass) - throw Exception(PARSER_RUNTIME, &name, "class is undefined"); - - stack.push(*vclass); + stack.push(get_class_ref(name)); break; } @@ -297,11 +293,7 @@ void Request::execute(ArrayOperation& op DEBUG_PRINT_STRING(name) - VStateless_class* vclass=get_class(name); - if(!vclass) - throw Exception(PARSER_RUNTIME, &name, "class is undefined"); - - stack.push(*new VBaseClassWrapper(*vclass, get_self())); + stack.push(*new VBaseClassWrapper(get_class_ref(name), get_self())); break; } @@ -850,9 +842,7 @@ void Request::execute(ArrayOperation& op DEBUG_PRINT_STRING(class_name) - VStateless_class* vclass=get_class(class_name); - if(!vclass) - throw Exception(PARSER_RUNTIME, &class_name, "class is undefined"); + VStateless_class& vclass=get_class_ref(class_name); debug_origin=i.next().origin; Value& vconstructor_name=*i.next().value; @@ -860,9 +850,9 @@ void Request::execute(ArrayOperation& op DEBUG_PRINT_STRING(constructor_name) - Junction* constructor_junction=get_element(*vclass, constructor_name).get_junction(); + Junction* constructor_junction=get_element(vclass, constructor_name).get_junction(); if(!constructor_junction) - throw Exception(PARSER_RUNTIME, &constructor_name, "constructor must be declared in class '%s'", vclass->type()); + throw Exception(PARSER_RUNTIME, &constructor_name, "constructor must be declared in class '%s'", vclass.type()); ArrayOperation* local_ops=i.next().ops; DEBUG_PRINT_OPS(local_ops) @@ -870,7 +860,7 @@ void Request::execute(ArrayOperation& op Value *result; { - Value& object=construct(*vclass, *constructor_junction->method); + Value& object=construct(vclass, *constructor_junction->method); CONSTRUCTOR_FRAME_ACTION(*constructor_junction->method, method_frame, object, { METHOD_PARAMS_ACTION(call(frame)); object.enable_default_setter(); @@ -928,41 +918,53 @@ void Request::execute(ArrayOperation& op case OP::OP_FEXISTS: { Value& a=stack.pop().value(); - Value& value=VBool::get(file_exist(absolute(a.as_string()))); + Value& value=VBool::get(file_exist(full_disk_path(a.as_string()))); stack.push(value); break; } case OP::OP_DEXISTS: { Value& a=stack.pop().value(); - Value& value=VBool::get(dir_exists(absolute(a.as_string()))); + Value& value=VBool::get(dir_exists(full_disk_path(a.as_string()))); stack.push(value); break; } // expression ops: binary - case OP::OP_SUB: + case OP::OP_SUB: { Value& b=stack.pop().value(); Value& a=stack.pop().value(); - Value& value=*new VDouble(a.as_double() - b.as_double()); + + double a_double=a.as_double(); + double b_double=b.as_double(); + + Value& value=*new VDouble(a_double - b_double); stack.push(value); break; } - case OP::OP_ADD: + case OP::OP_ADD: { Value& b=stack.pop().value(); Value& a=stack.pop().value(); - Value& value=*new VDouble(a.as_double() + b.as_double()); + + double a_double=a.as_double(); + double b_double=b.as_double(); + + Value& value=*new VDouble(a_double + b_double); stack.push(value); break; } - case OP::OP_MUL: + case OP::OP_MUL: { Value& b=stack.pop().value(); Value& a=stack.pop().value(); - Value& value=*new VDouble(a.as_double() * b.as_double()); + + double a_double=a.as_double(); + double b_double=b.as_double(); + + Value& value=*new VDouble(a_double * b_double); stack.push(value); break; } - case OP::OP_DIV: + case OP::OP_DIV: { Value& b=stack.pop().value(); Value& a=stack.pop().value(); @@ -978,7 +980,7 @@ void Request::execute(ArrayOperation& op stack.push(value); break; } - case OP::OP_MOD: + case OP::OP_MOD: { Value& b=stack.pop().value(); Value& a=stack.pop().value(); @@ -1432,41 +1434,46 @@ 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; - }); + Value &result=frame.result(); + if(const String* sresult=result.get_string()){ + return sresult; + } + result.bark("is '%s', it has no string representation", &method_name); + }); + } + 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){