Diff for /parser3/src/main/execute.C between versions 1.415 and 1.423

version 1.415, 2023/10/06 20:02:50 version 1.423, 2024/10/02 21:24:41
Line 19 Line 19
 #include "pa_vtable.h"  #include "pa_vtable.h"
 #include "pa_vfile.h"  #include "pa_vfile.h"
 #include "pa_vimage.h"  #include "pa_vimage.h"
   #include "pa_varray.h"
 #include "pa_wwrapper.h"  #include "pa_wwrapper.h"
   
 volatile const char * IDENT_EXECUTE_C="$Id$" IDENT_PA_OPCODE_H IDENT_PA_OPERATION_H IDENT_PA_VCODE_FRAME_H IDENT_PA_WWRAPPER_H;  volatile const char * IDENT_EXECUTE_C="$Id$" IDENT_PA_OPCODE_H IDENT_PA_OPERATION_H IDENT_PA_VCODE_FRAME_H IDENT_PA_WWRAPPER_H;
Line 34  const char *opcode_name[]={ Line 35  const char *opcode_name[]={
         // actions          // actions
         "WITH_ROOT",    "WITH_SELF",    "WITH_READ",    "WITH_WRITE",          "WITH_ROOT",    "WITH_SELF",    "WITH_READ",    "WITH_WRITE",
         "VALUE__GET_CLASS", "VALUE__GET_BASE_CLASS",          "VALUE__GET_CLASS", "VALUE__GET_BASE_CLASS",
         "CONSTRUCT_VALUE", "CONSTRUCT_EXPR", "CURLY_CODE__CONSTRUCT",          "CONSTRUCT_VALUE", "CONSTRUCT_EXPR", "CURLY_CODE__CONSTRUCT", "CONSTRUCT_ARRAY",
         "WRITE_VALUE",  "WRITE_EXPR_RESULT",  "STRING__WRITE",          "WRITE_VALUE",  "WRITE_EXPR_RESULT",  "STRING__WRITE",
 #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT  #ifdef OPTIMIZE_BYTECODE_GET_ELEMENT
         "VALUE__GET_ELEMENT_OR_OPERATOR",          "VALUE__GET_ELEMENT_OR_OPERATOR",
Line 128  void debug_printf(SAPI_Info& sapi_info, Line 129  void debug_printf(SAPI_Info& sapi_info,
 }  }
   
 void debug_dump(SAPI_Info& sapi_info, int level, ArrayOperation& ops) {  void debug_dump(SAPI_Info& sapi_info, int level, ArrayOperation& ops) {
         Array_iterator<Operation> i(ops);          for(Array_iterator<Operation> i(ops); i;) {
         while(i.has_next()) {  
                 OP::OPCODE opcode=i.next().code;                  OP::OPCODE opcode=i.next().code;
   
 #if defined(OPTIMIZE_BYTECODE_GET_OBJECT_ELEMENT) || defined(OPTIMIZE_BYTECODE_GET_OBJECT_VAR_ELEMENT)  #if defined(OPTIMIZE_BYTECODE_GET_OBJECT_ELEMENT) || defined(OPTIMIZE_BYTECODE_GET_OBJECT_VAR_ELEMENT)
Line 220  void debug_dump(SAPI_Info& sapi_info, in Line 220  void debug_dump(SAPI_Info& sapi_info, in
                 case OP::OP_NESTED_CODE:                  case OP::OP_NESTED_CODE:
                 case OP::OP_OBJECT_POOL:                  case OP::OP_OBJECT_POOL:
                 case OP::OP_STRING_POOL:                  case OP::OP_STRING_POOL:
                   case OP::OP_CONSTRUCT_ARRAY:
                 case OP::OP_CALL:                  case OP::OP_CALL:
                 case OP::OP_CALL__WRITE:                  case OP::OP_CALL__WRITE:
                         if(ArrayOperation* local_ops=i.next().ops)                          if(ArrayOperation* local_ops=i.next().ops)
Line 245  void debug_dump(SAPI_Info& sapi_info, in Line 246  void debug_dump(SAPI_Info& sapi_info, in
 // Request  // Request
   
 void Request::execute(ArrayOperation& ops) {  void Request::execute(ArrayOperation& ops) {
         register Stack<StackItem>& stack=this->stack; // helps a lot on MSVC: 'esi'          Stack<StackItem>& stack=this->stack; // helps a lot on MSVC: 'esi'
   
         const String* debug_name=0;  Operation::Origin debug_origin={0, 0, 0};          const String* debug_name=0;  Operation::Origin debug_origin={0, 0, 0};
         try{          try{
Line 254  void Request::execute(ArrayOperation& op Line 255  void Request::execute(ArrayOperation& op
         debug_dump(sapi_info, 0, ops);          debug_dump(sapi_info, 0, ops);
         debug_printf(sapi_info, "execution-------------------------\n");          debug_printf(sapi_info, "execution-------------------------\n");
 #endif  #endif
         for(Array_iterator<Operation> i(ops); i.has_next(); ) {          for(Array_iterator<Operation> i(ops); i; ) {
                 OP::OPCODE opcode=i.next().code;                  OP::OPCODE opcode=i.next().code;
   
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
Line 442  void Request::execute(ArrayOperation& op Line 443  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(const VJunction* vjunction=ncontext.put_element(name, &value))
                                                 throw Exception(PARSER_RUNTIME, 0, "property value can not be code, use [] or () brackets");                                                  throw Exception(PARSER_RUNTIME, 0, "property value cannot be code, use [] or () brackets");
   
                                 break;                                  break;
                         }                          }
   
                   case OP::OP_CONSTRUCT_ARRAY:
                           {
                                   ArrayOperation* local_ops=i.next().ops;
   
                                   DEBUG_PRINT_OPS(local_ops)
                                   DEBUG_PRINT_STR("->\n")
   
                                   size_t first = stack.top_index();
                                   execute(*local_ops);
                                   Value *value=new VArray(stack.top_index()-first, (Value**)stack.ptr(first));
                                   stack.set_top_index(first);
   
   #ifdef OPTIMIZE_BYTECODE_CONSTRUCT
                                   const String& name=stack.pop().string();  debug_name=&name;
                                   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);
   
                                   DEBUG_PRINT_STR("<-returned")
                                   goto check_skip;
                           }
   
                 case OP::OP_NESTED_CODE:                  case OP::OP_NESTED_CODE:
                         {                          {
                                 ArrayOperation& local_ops=*i.next().ops;                                  ArrayOperation& local_ops=*i.next().ops;
Line 759  void Request::execute(ArrayOperation& op Line 786  void Request::execute(ArrayOperation& op
   
                                 Junction* junction=value.get_junction();                                  Junction* junction=value.get_junction();
                                 if(!junction) {                                  if(!junction) {
                                         if(value.is("void"))                                          if(dynamic_cast<VVoid*>(&value))
                                                 throw Exception(PARSER_RUNTIME, 0, "undefined method");                                                  throw Exception(PARSER_RUNTIME, 0, "undefined method");
                                         else                                          else
                                                 throw Exception(PARSER_RUNTIME, 0, "is '%s', not a method or junction, can not call it", value.type());                                                  throw Exception(PARSER_RUNTIME, 0, "is '%s', not a method or junction, cannot call it", value.type());
                                 }                                  }
   
                                 Value *result;                                  Value *result;
Line 790  void Request::execute(ArrayOperation& op Line 817  void Request::execute(ArrayOperation& op
   
                                 Junction* junction=value.get_junction();                                  Junction* junction=value.get_junction();
                                 if(!junction) {                                  if(!junction) {
                                         if(value.is("void"))                                          if(dynamic_cast<VVoid*>(&value))
                                                 throw Exception(PARSER_RUNTIME, 0, "undefined method");                                                  throw Exception(PARSER_RUNTIME, 0, "undefined method");
                                         else                                          else
                                                 throw Exception(PARSER_RUNTIME, 0, "is '%s', not a method or junction, can not call it", value.type());                                                  throw Exception(PARSER_RUNTIME, 0, "is '%s', not a method or junction, cannot call it", value.type());
                                 }                                  }
   
                                 const Method& method=*junction->method;                                  const Method& method=*junction->method;
Line 933  void Request::execute(ArrayOperation& op Line 960  void Request::execute(ArrayOperation& op
                 // expression ops: binary                  // expression ops: binary
                 case OP::OP_SUB:                  case OP::OP_SUB:
                         {                          {
                                 Value& b=stack.pop().value();  Value& a=stack.pop().value();                                  volatile double b_double=stack.pop().value().as_double();
                                   volatile double a_double=stack.pop().value().as_double();
                                 double a_double=a.as_double();  
                                 double b_double=b.as_double();  
   
                                 Value& value=*new VDouble(a_double - b_double);                                  Value& value=*new VDouble(a_double - b_double);
                                 stack.push(value);                                  stack.push(value);
Line 944  void Request::execute(ArrayOperation& op Line 969  void Request::execute(ArrayOperation& op
                         }                          }
                 case OP::OP_ADD:                  case OP::OP_ADD:
                         {                          {
                                 Value& b=stack.pop().value();  Value& a=stack.pop().value();                                  volatile double b_double=stack.pop().value().as_double();
                                   volatile double a_double=stack.pop().value().as_double();
                                 double a_double=a.as_double();  
                                 double b_double=b.as_double();  
   
                                 Value& value=*new VDouble(a_double + b_double);                                  Value& value=*new VDouble(a_double + b_double);
                                 stack.push(value);                                  stack.push(value);
Line 955  void Request::execute(ArrayOperation& op Line 978  void Request::execute(ArrayOperation& op
                         }                          }
                 case OP::OP_MUL:                  case OP::OP_MUL:
                         {                          {
                                 Value& b=stack.pop().value();  Value& a=stack.pop().value();                                  volatile double b_double=stack.pop().value().as_double();
                                   volatile double a_double=stack.pop().value().as_double();
                                 double a_double=a.as_double();  
                                 double b_double=b.as_double();  
   
                                 Value& value=*new VDouble(a_double * b_double);                                  Value& value=*new VDouble(a_double * b_double);
                                 stack.push(value);                                  stack.push(value);
Line 966  void Request::execute(ArrayOperation& op Line 987  void Request::execute(ArrayOperation& op
                         }                          }
                 case OP::OP_DIV:                  case OP::OP_DIV:
                         {                          {
                                 Value& b=stack.pop().value();  Value& a=stack.pop().value();                                  volatile double b_double=stack.pop().value().as_double();
                                   volatile double a_double=stack.pop().value().as_double();
                                 double a_double=a.as_double();  
                                 double b_double=b.as_double();  
   
                                 if(b_double == 0) {                                  if(b_double == 0) {
                                         //const String* problem_source=b.as_string();                                          //const String* problem_source=b.as_string();
Line 982  void Request::execute(ArrayOperation& op Line 1001  void Request::execute(ArrayOperation& op
                         }                          }
                 case OP::OP_MOD:                  case OP::OP_MOD:
                         {                          {
                                 Value& b=stack.pop().value();  Value& a=stack.pop().value();                                  volatile double b_double=stack.pop().value().as_double();
                                   volatile double a_double=stack.pop().value().as_double();
                                 double a_double=a.as_double();  
                                 double b_double=b.as_double();  
   
                                 if(b_double == 0) {                                  if(b_double == 0) {
                                         //const String* problem_source=b.as_string();                                          //const String* problem_source=b.as_string();
Line 998  void Request::execute(ArrayOperation& op Line 1015  void Request::execute(ArrayOperation& op
                         }                          }
                 case OP::OP_INTDIV:                  case OP::OP_INTDIV:
                         {                          {
                                 Value& b=stack.pop().value();  Value& a=stack.pop().value();                                  int b_int=stack.pop().value().as_int();
                                   int a_int=stack.pop().value().as_int();
                                 int a_int=a.as_int();  
                                 int b_int=b.as_int();  
   
                                 if(b_int == 0) {                                  if(b_int == 0) {
                                         //const String* problem_source=b.as_string();                                          //const String* problem_source=b.as_string();
Line 1236  Value& Request::construct(VStateless_cla Line 1251  Value& Request::construct(VStateless_cla
                         throw Exception(PARSER_RUNTIME, method.name,                          throw Exception(PARSER_RUNTIME, method.name,
                                 "is not a constructor, system class '%s' can be constructed only implicitly", called_class.type());                                  "is not a constructor, system class '%s' can be constructed only implicitly", called_class.type());
         } else          } else
                 throw Exception(PARSER_RUNTIME, method.name, "method of '%s' is static and can not be used as constructor", called_class.type());                  throw Exception(PARSER_RUNTIME, method.name, "method of '%s' is static and cannot be used as constructor", called_class.type());
 }  }
   
 Value& Request::get_element(Value& ncontext, const String& name) {  Value& Request::get_element(Value& ncontext, const String& name) {
Line 1288  Value& Request::process_getter(Junction& Line 1303  Value& Request::process_getter(Junction&
         if(junction.auto_name){          if(junction.auto_name){
                 // default getter                  // default getter
                 if(param_count>1)                  if(param_count>1)
                         throw Exception(PARSER_RUNTIME, 0, "default getter method can't have more then 1 parameter (has %d parameters)", param_count);                          throw Exception(PARSER_RUNTIME, 0, "default getter method can't have more than 1 parameter (has %d parameters)", param_count);
   
                 Value *param;                  Value *param;
                 METHOD_FRAME_ACTION(*junction.method, method_frame/*caller*/, junction.self, {                  METHOD_FRAME_ACTION(*junction.method, method_frame/*caller*/, junction.self, {
Line 1345  Value& Request::process(Value& input_val Line 1360  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 1354  Value& Request::process(Value& input_val Line 1369  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 1366  Value& Request::process(Value& input_val Line 1381  Value& Request::process(Value& input_val
                         return result;                          return result;
                 }                  }
   
                 // it is then method-junction, do not explode it                  // then it is a method-junction, do not explode it
                 // just return it as we do for usual objects                  // just return it as we do for usual objects
         }                 }       
   
Line 1397  void Request::process_write(Value& input Line 1412  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 1408  void Request::process_write(Value& input Line 1423  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 1417  void Request::process_write(Value& input Line 1432  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());
                         }                          }
Line 1427  void Request::process_write(Value& input Line 1442  void Request::process_write(Value& input
                         return;                          return;
                 }                  }
   
                 // it is then method-junction, do not explode it                  // then it is a method-junction, do not explode it
                 // just return it as we do for usual objects                  // just return it as we do for usual objects
         }          }
   
Line 1476  bool Request::execute_method_if_exists(V Line 1491  bool Request::execute_method_if_exists(V
         return false;          return false;
 }  }
   
   bool Request::execute_auto_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, {
                           Value* two_params[2];
   
                           if (optional_param && method->params_count>1) {
                                   two_params[0] = optional_param;
                                   two_params[1] = new VString(*new String(aclass.type()));
                                   frame.store_params(two_params, 2);
                           } else 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){  const String* Request::get_method_filespec(const Method* method){
         Operation::Origin origin=get_method_origin(method);          Operation::Origin origin=get_method_origin(method);
         return origin.file_no ? get_used_filespec(origin.file_no) : NULL;          return origin.file_no ? get_used_filespec(origin.file_no) : NULL;
Line 1486  const Operation::Origin Request::get_met Line 1523  const Operation::Origin Request::get_met
   
         if(ArrayOperation* code=method->parser_code)          if(ArrayOperation* code=method->parser_code)
                 if(code){                  if(code){
                         Array_iterator<Operation> i(*code);                          for(Array_iterator<Operation> i(*code); i; ){
                         while( i.has_next() ){  
                                 switch( i.next().code ){                                  switch( i.next().code ){
                                         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:

Removed from v.1.415  
changed lines
  Added in v.1.423


E-mail: