|
|
| version 1.422, 2024/09/28 14:37:53 | version 1.430, 2026/04/25 13:38:46 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: executor part of request class. | Parser: executor part of request class. |
| Copyright (c) 2001-2023 Art. Lebedev Studio (http://www.artlebedev.com) | Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com) |
| Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru> | Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru> |
| */ | */ |
| Line 214 void debug_dump(SAPI_Info& sapi_info, in | Line 214 void debug_dump(SAPI_Info& sapi_info, in |
| debug_printf(sapi_info, "%*s%s", level*4, "", opcode_name[opcode]); | debug_printf(sapi_info, "%*s%s", level*4, "", opcode_name[opcode]); |
| switch(opcode) { | switch(opcode) { |
| case OP::OP_CURLY_CODE__STORE_PARAM: | case OP::OP_CURLY_CODE__STORE_PARAM: |
| case OP::OP_EXPR_CODE__STORE_PARAM: | case OP::OP_EXPR_CODE__STORE_PARAM: |
| case OP::OP_CURLY_CODE__CONSTRUCT: | case OP::OP_CURLY_CODE__CONSTRUCT: |
| case OP::OP_NESTED_CODE: | case OP::OP_NESTED_CODE: |
| Line 442 void Request::execute(ArrayOperation& op | Line 442 void Request::execute(ArrayOperation& op |
| const String& name=stack.pop().string(); debug_name=&name; | const String& name=stack.pop().string(); debug_name=&name; |
| Value& ncontext=stack.pop().value(); | Value& ncontext=stack.pop().value(); |
| if(const VJunction* vjunction=ncontext.put_element(name, &value)) | if(ncontext.put_element(name, &value)) |
| throw Exception(PARSER_RUNTIME, 0, "property value cannot be code, use [] or () brackets"); | throw Exception(PARSER_RUNTIME, 0, "property value cannot be code, use [] or () brackets"); |
| break; | break; |
| Line 450 void Request::execute(ArrayOperation& op | Line 450 void Request::execute(ArrayOperation& op |
| case OP::OP_CONSTRUCT_ARRAY: | case OP::OP_CONSTRUCT_ARRAY: |
| { | { |
| debug_name=0; | |
| ArrayOperation* local_ops=i.next().ops; | ArrayOperation* local_ops=i.next().ops; |
| DEBUG_PRINT_OPS(local_ops) | DEBUG_PRINT_OPS(local_ops) |
| Line 460 void Request::execute(ArrayOperation& op | Line 462 void Request::execute(ArrayOperation& op |
| Value *value=new VArray(stack.top_index()-first, (Value**)stack.ptr(first)); | Value *value=new VArray(stack.top_index()-first, (Value**)stack.ptr(first)); |
| stack.set_top_index(first); | stack.set_top_index(first); |
| #ifdef OPTIMIZE_BYTECODE_CONSTRUCT | |
| const String& name=stack.pop().string(); debug_name=&name; | const String& name=stack.pop().string(); debug_name=&name; |
| Value& ncontext=stack.pop().value(); | Value& ncontext=stack.pop().value(); |
| #else | |
| const String& name=stack.pop().string(); debug_name=&name; | |
| Value& ncontext=stack.pop().value(); | |
| #endif | |
| put_element(ncontext, name, value); | put_element(ncontext, name, value); |
| DEBUG_PRINT_STR("<-returned") | DEBUG_PRINT_STR("<-returned") |
| Line 516 void Request::execute(ArrayOperation& op | Line 514 void Request::execute(ArrayOperation& op |
| DEBUG_PRINT_STRING(name) | DEBUG_PRINT_STRING(name) |
| if(Method* method=main_class.get_method(name)){ // looking operator of that name FIRST | if(Method* method=main_class.get_method(name)){ // looking operator of that name FIRST |
| if(!method->junction_template) method->junction_template=new VJunction(main_class, method); | stack.push(*method->get_vjunction(main_class)); |
| stack.push(*method->junction_template); | |
| break; | break; |
| } | } |
| Value& value=get_element(*rcontext, name); | Value& value=get_element(*rcontext, name); |
| Line 530 void Request::execute(ArrayOperation& op | Line 527 void Request::execute(ArrayOperation& op |
| const String& name=stack.pop().string(); debug_name=&name; | const String& name=stack.pop().string(); debug_name=&name; |
| Value& ncontext=stack.pop().value(); | Value& ncontext=stack.pop().value(); |
| if(Method* method=main_class.get_method(name)){ // looking operator of that name FIRST | if(Method* method=main_class.get_method(name)){ // looking operator of that name FIRST |
| if(!method->junction_template) method->junction_template=new VJunction(main_class, method); | stack.push(*method->get_vjunction(main_class)); |
| stack.push(*method->junction_template); | |
| break; | break; |
| } | } |
| Value& value=get_element(ncontext, name); | Value& value=get_element(ncontext, name); |
| Line 877 void Request::execute(ArrayOperation& op | Line 873 void Request::execute(ArrayOperation& op |
| DEBUG_PRINT_STRING(constructor_name) | DEBUG_PRINT_STRING(constructor_name) |
| // not get_element4call for better error reporting | |
| Junction* constructor_junction=get_element(vclass, constructor_name).get_junction(); | Junction* constructor_junction=get_element(vclass, constructor_name).get_junction(); |
| if(!constructor_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, "%s constructor not found", vclass.type()); |
| ArrayOperation* local_ops=i.next().ops; | ArrayOperation* local_ops=i.next().ops; |
| DEBUG_PRINT_OPS(local_ops) | DEBUG_PRINT_OPS(local_ops) |
| Line 1015 void Request::execute(ArrayOperation& op | Line 1012 void Request::execute(ArrayOperation& op |
| } | } |
| case OP::OP_INTDIV: | case OP::OP_INTDIV: |
| { | { |
| int b_int=stack.pop().value().as_int(); | pa_wint b_int=stack.pop().value().as_wint(); |
| int a_int=stack.pop().value().as_int(); | pa_wint a_int=stack.pop().value().as_wint(); |
| if(b_int == 0) { | if(b_int == 0) { |
| //const String* problem_source=b.as_string(); | //const String* problem_source=b.as_string(); |
| Line 1031 void Request::execute(ArrayOperation& op | Line 1028 void Request::execute(ArrayOperation& op |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=*new VInt( | Value& value=*new VInt( |
| a.as_int() << | a.as_wint() << |
| b.as_int()); | b.as_wint()); |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| Line 1040 void Request::execute(ArrayOperation& op | Line 1037 void Request::execute(ArrayOperation& op |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=*new VInt( | Value& value=*new VInt( |
| a.as_int() >> | a.as_wint() >> |
| b.as_int()); | b.as_wint()); |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| Line 1049 void Request::execute(ArrayOperation& op | Line 1046 void Request::execute(ArrayOperation& op |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=*new VInt( | Value& value=*new VInt( |
| a.as_int() & | a.as_wint() & |
| b.as_int()); | b.as_wint()); |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| Line 1058 void Request::execute(ArrayOperation& op | Line 1055 void Request::execute(ArrayOperation& op |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=*new VInt( | Value& value=*new VInt( |
| a.as_int() | | a.as_wint() | |
| b.as_int()); | b.as_wint()); |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| Line 1067 void Request::execute(ArrayOperation& op | Line 1064 void Request::execute(ArrayOperation& op |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=*new VInt( | Value& value=*new VInt( |
| a.as_int() ^ | a.as_wint() ^ |
| b.as_int()); | b.as_wint()); |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| Line 1108 void Request::execute(ArrayOperation& op | Line 1105 void Request::execute(ArrayOperation& op |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_NUM_LT: | case OP::OP_NUM_LT: |
| { | { |
| volatile double b_double=stack.pop().value().as_double(); | volatile double b_double=stack.pop().value().as_double(); |
| volatile double a_double=stack.pop().value().as_double(); | volatile double a_double=stack.pop().value().as_double(); |
| Line 1116 void Request::execute(ArrayOperation& op | Line 1113 void Request::execute(ArrayOperation& op |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_NUM_GT: | case OP::OP_NUM_GT: |
| { | { |
| volatile double b_double=stack.pop().value().as_double(); | volatile double b_double=stack.pop().value().as_double(); |
| volatile double a_double=stack.pop().value().as_double(); | volatile double a_double=stack.pop().value().as_double(); |
| Line 1124 void Request::execute(ArrayOperation& op | Line 1121 void Request::execute(ArrayOperation& op |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_NUM_LE: | case OP::OP_NUM_LE: |
| { | { |
| volatile double b_double=stack.pop().value().as_double(); | volatile double b_double=stack.pop().value().as_double(); |
| volatile double a_double=stack.pop().value().as_double(); | volatile double a_double=stack.pop().value().as_double(); |
| Line 1132 void Request::execute(ArrayOperation& op | Line 1129 void Request::execute(ArrayOperation& op |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_NUM_GE: | case OP::OP_NUM_GE: |
| { | { |
| volatile double b_double=stack.pop().value().as_double(); | volatile double b_double=stack.pop().value().as_double(); |
| volatile double a_double=stack.pop().value().as_double(); | volatile double a_double=stack.pop().value().as_double(); |
| Line 1140 void Request::execute(ArrayOperation& op | Line 1137 void Request::execute(ArrayOperation& op |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_NUM_EQ: | case OP::OP_NUM_EQ: |
| { | { |
| volatile double b_double=stack.pop().value().as_double(); | volatile double b_double=stack.pop().value().as_double(); |
| volatile double a_double=stack.pop().value().as_double(); | volatile double a_double=stack.pop().value().as_double(); |
| Line 1148 void Request::execute(ArrayOperation& op | Line 1145 void Request::execute(ArrayOperation& op |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_NUM_NE: | case OP::OP_NUM_NE: |
| { | { |
| volatile double b_double=stack.pop().value().as_double(); | volatile double b_double=stack.pop().value().as_double(); |
| volatile double a_double=stack.pop().value().as_double(); | volatile double a_double=stack.pop().value().as_double(); |
| Line 1156 void Request::execute(ArrayOperation& op | Line 1153 void Request::execute(ArrayOperation& op |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_STR_LT: | case OP::OP_STR_LT: |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=VBool::get(a.as_string() < b.as_string()); | Value& value=VBool::get(a.as_string() < b.as_string()); |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_STR_GT: | case OP::OP_STR_GT: |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=VBool::get(a.as_string() > b.as_string()); | Value& value=VBool::get(a.as_string() > b.as_string()); |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_STR_LE: | case OP::OP_STR_LE: |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=VBool::get(a.as_string() <= b.as_string()); | Value& value=VBool::get(a.as_string() <= b.as_string()); |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_STR_GE: | case OP::OP_STR_GE: |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=VBool::get(a.as_string() >= b.as_string()); | Value& value=VBool::get(a.as_string() >= b.as_string()); |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_STR_EQ: | case OP::OP_STR_EQ: |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=VBool::get(a.as_string() == b.as_string()); | Value& value=VBool::get(a.as_string() == b.as_string()); |
| stack.push(value); | stack.push(value); |
| break; | break; |
| } | } |
| case OP::OP_STR_NE: | case OP::OP_STR_NE: |
| { | { |
| Value& b=stack.pop().value(); Value& a=stack.pop().value(); | Value& b=stack.pop().value(); Value& a=stack.pop().value(); |
| Value& value=VBool::get(a.as_string() != b.as_string()); | Value& value=VBool::get(a.as_string() != b.as_string()); |
| Line 1360 Value& Request::process(Value& input_val | Line 1357 Value& Request::process(Value& input_val |
| wcontext=&local; | wcontext=&local; |
| // execute it | // execute it |
| recoursion_checked_execute(*junction->code); | recursion_checked_execute(*junction->code); |
| result=wcontext->result(); | result=wcontext->result(); |
| } else { | } else { |
| Line 1369 Value& Request::process(Value& input_val | Line 1366 Value& Request::process(Value& input_val |
| wcontext=&local; | wcontext=&local; |
| // execute it | // execute it |
| recoursion_checked_execute(*junction->code); | recursion_checked_execute(*junction->code); |
| result=wcontext->result(); | result=wcontext->result(); |
| } | } |
| Line 1412 void Request::process_write(Value& input | Line 1409 void Request::process_write(Value& input |
| #ifdef OPTIMIZE_CALL | #ifdef OPTIMIZE_CALL |
| if(wcontext==junction->wcontext){ | if(wcontext==junction->wcontext){ |
| // no wrappers for wcontext | // no wrappers for wcontext |
| recoursion_checked_execute(*junction->code); | recursion_checked_execute(*junction->code); |
| RESTORE_CONTEXT | RESTORE_CONTEXT |
| } else | } else |
| Line 1423 void Request::process_write(Value& input | Line 1420 void Request::process_write(Value& input |
| wcontext=&local; | wcontext=&local; |
| // execute it | // execute it |
| recoursion_checked_execute(*junction->code); | recursion_checked_execute(*junction->code); |
| RESTORE_CONTEXT | RESTORE_CONTEXT |
| write(local.result()); | write(local.result()); |
| } else { | } else { |
| Line 1432 void Request::process_write(Value& input | Line 1429 void Request::process_write(Value& input |
| wcontext=&local; | wcontext=&local; |
| // execute it | // execute it |
| recoursion_checked_execute(*junction->code); | recursion_checked_execute(*junction->code); |
| RESTORE_CONTEXT | RESTORE_CONTEXT |
| write(local.result()); | write(local.result()); |
| } | } |