Diff for /parser3/src/main/execute.C between versions 1.202 and 1.209

version 1.202, 2001/11/01 16:27:20 version 1.209, 2002/01/24 17:18:48
Line 2 Line 2
         Parser: executor part of request class.          Parser: executor part of request class.
   
         Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)          Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru)
   
         $Id$          $Id$
 */  */
Line 25 Line 25
   
 //#define DEBUG_EXECUTE  //#define DEBUG_EXECUTE
   
 const uint ANTI_ENDLESS_EXECUTE_RECOURSION=200;  const uint ANTI_ENDLESS_EXECUTE_RECOURSION=500;
   
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
 char *opcode_name[]={  char *opcode_name[]={
         // literals          // literals
         "VALUE",  "CURLY_CODE__STORE_PARAM",  "EXPR_CODE__STORE_PARAM",          "VALUE",  "CURLY_CODE__STORE_PARAM",  "EXPR_CODE__STORE_PARAM",
           "NESTED_CODE",
   
         // actions          // actions
         "WITH_ROOT",    "WITH_SELF",    "WITH_READ",    "WITH_WRITE",          "WITH_ROOT",    "WITH_SELF",    "WITH_READ",    "WITH_WRITE",
Line 89  void debug_dump(Pool& pool, int level, c Line 90  void debug_dump(Pool& pool, int level, c
                 case OP_CURLY_CODE__STORE_PARAM:                   case OP_CURLY_CODE__STORE_PARAM: 
                 case OP_EXPR_CODE__STORE_PARAM:                  case OP_EXPR_CODE__STORE_PARAM:
                 case OP_CURLY_CODE__CONSTRUCT:                  case OP_CURLY_CODE__CONSTRUCT:
                   case OP_NESTED_CODE:
                         const Array *local_ops=reinterpret_cast<const Array *>(i.next());                          const Array *local_ops=reinterpret_cast<const Array *>(i.next());
                         debug_dump(pool, level+1, *local_ops);                          debug_dump(pool, level+1, *local_ops);
                 }                  }
Line 99  void debug_dump(Pool& pool, int level, c Line 101  void debug_dump(Pool& pool, int level, c
 #define PUSH(value) stack.push(value)  #define PUSH(value) stack.push(value)
 #define POP() static_cast<Value *>(stack.pop())  #define POP() static_cast<Value *>(stack.pop())
 #define POP_NAME() static_cast<Value *>(stack.pop())->as_string()  #define POP_NAME() static_cast<Value *>(stack.pop())->as_string()
   #define POP_CODE() static_cast<Array *>(stack.pop())
   
 void Request::execute(const Array& ops) {  void Request::execute(const Array& ops) {
 //      _asm int 3;  //      _asm int 3;
Line 118  void Request::execute(const Array& ops) Line 121  void Request::execute(const Array& ops)
   
                 Value *value;                  Value *value;
                 Value *a; Value *b;                  Value *a; Value *b;
                   Array *b_code;
                 switch(op.code) {                  switch(op.code) {
                 // param in next instruction                  // param in next instruction
                 case OP_VALUE:                  case OP_VALUE:
Line 237  void Request::execute(const Array& ops) Line 241  void Request::execute(const Array& ops)
                                 value->set_name(name);                                  value->set_name(name);
                                 break;                                  break;
                         }                          }
                   case OP_NESTED_CODE:
                           {
                                   Array *local_ops=static_cast<Array *>(i.next());
   #ifdef DEBUG_EXECUTE
                                   debug_printf(pool(), " (%d)\n", local_ops->size());
                                   debug_dump(pool(), 1, *local_ops);
   #endif                          
                                   PUSH(local_ops);
                                   break;
                           }
                 case OP_WRITE_VALUE:                  case OP_WRITE_VALUE:
                         {                          {
                                 value=POP();                                  value=POP();
Line 292  void Request::execute(const Array& ops) Line 306  void Request::execute(const Array& ops)
                         }                          }
                 case OP_REDUCE_EWPOOL:                  case OP_REDUCE_EWPOOL:
                         {                          {
                                 value=wcontext->result();                                  value=&wcontext->result();
                                 flang=static_cast<String::Untaint_lang>(reinterpret_cast<int>(POP()));                                  flang=static_cast<String::Untaint_lang>(reinterpret_cast<int>(POP()));
                                 wcontext=static_cast<WContext *>(POP());                                  wcontext=static_cast<WContext *>(POP());
                                 PUSH(value);                                  PUSH(value);
Line 371  void Request::execute(const Array& ops) Line 385  void Request::execute(const Array& ops)
                                                 // this is a constructor call                                                  // this is a constructor call
   
                                                 if(Value *value=called_class->create_new_value(pool())) {                                                  if(Value *value=called_class->create_new_value(pool())) {
                                                         // some stateless_object creatable derivates                                                          // some stateless_class creatable derivates
                                                         self=value;                                                          self=value;
                                                 } else {                                                  } else 
                                                         // stateful object                                                          throw Exception(0, 0,
                                                         self=NEW VObject(pool(), *called_class);                                                                  &frame->name(),
                                                 }                                                                  "is not a constructor, system class '%s' can be constructed only implicitly", 
                                                                   called_class->name().cstr());
   
                                                 frame->write(*self,                                                   frame->write(*self, 
                                                         String::UL_CLEAN  // not used, always an object, not string                                                          String::UL_CLEAN  // not used, always an object, not string
                                                 );                                                  );
Line 423  void Request::execute(const Array& ops) Line 439  void Request::execute(const Array& ops)
                                                                         frame->name(), frame->numbered_params()); // execute it                                                                          frame->name(), frame->numbered_params()); // execute it
                                                         } else { // parser code                                                          } else { // parser code
                                                                 root=frame;                                                                  root=frame;
                                                                 if(++anti_endless_execute_recoursion==ANTI_ENDLESS_EXECUTE_RECOURSION) {                                                                  { // anti_endless_execute_recoursion
                                                                         anti_endless_execute_recoursion=0; // give @exception a chance                                                                          if(++anti_endless_execute_recoursion==ANTI_ENDLESS_EXECUTE_RECOURSION) {
                                                                         throw Exception(0, 0,                                                                                  anti_endless_execute_recoursion=0; // give @exception a chance
                                                                                 &frame->name(),                                                                                  throw Exception(0, 0,
                                                                                 "endless recursion detected");                                                                                          &frame->name(),
                                                                                           "call canceled - endless recursion detected");
                                                                           }
                                                                           execute(*method.parser_code); // execute it
                                                                           anti_endless_execute_recoursion--;
                                                                 }                                                                  }
                                                                   
                                                                 execute(*method.parser_code); // execute it  
                                                                 anti_endless_execute_recoursion--;  
                                                         }                                                          }
                                                 } catch(...) {                                                  } catch(...) {
                                                         // record it to stack trace                                                          // record it to stack trace
Line 445  void Request::execute(const Array& ops) Line 462  void Request::execute(const Array& ops)
                                                                 call_type==Method::CT_STATIC?"statically":"dynamically");                                                                  call_type==Method::CT_STATIC?"statically":"dynamically");
   
                                 }                                  }
                                 value=wcontext->result();                                  value=&wcontext->result();
   
                                 wcontext=static_cast<WContext *>(POP());                                    wcontext=static_cast<WContext *>(POP());  
                                 rcontext=POP();                                    rcontext=POP();  
Line 632  void Request::execute(const Array& ops) Line 649  void Request::execute(const Array& ops)
                         }                          }
                 case OP_LOG_AND:                  case OP_LOG_AND:
                         {                          {
                                 b=POP();  a=POP();                                  b_code=POP_CODE();  a=POP();
                                 value=NEW VBool(pool(), a->as_bool() && b->as_bool());                                  bool result;
                                   if(a->as_bool()) {
                                           execute(*b_code);
                                           b=POP();
                                           result=b->as_bool();
                                   } else
                                           result=false;
                                   value=NEW VBool(pool(), result);
                                 PUSH(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_LOG_OR:                  case OP_LOG_OR:
                         {                          {
                                 b=POP();  a=POP();                                  b_code=POP_CODE();  a=POP();
                                 value=NEW VBool(pool(), a->as_bool() || b->as_bool());                                  bool result;
                                   if(a->as_bool()) 
                                           result=true;
                                   else {
                                           execute(*b_code);
                                           b=POP();
                                           result=b->as_bool();
                                   }
                                   value=NEW VBool(pool(), result);
                                 PUSH(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
Line 814  Value& Request::process(Value& value, co Line 846  Value& Request::process(Value& value, co
                 self=&junction->self;                  self=&junction->self;
                 root=junction->root;                  root=junction->root;
                 rcontext=junction->rcontext;                  rcontext=junction->rcontext;
                 execute(*junction->code);  
                   { // anti_endless_execute_recoursion
                           if(++anti_endless_execute_recoursion==ANTI_ENDLESS_EXECUTE_RECOURSION) {
                                   anti_endless_execute_recoursion=0; // give @exception a chance
                                   throw Exception(0, 0,
                                           name,
                                           "junction evaluation canceled - endless recursion detected");
                           }
                           execute(*junction->code);
                           anti_endless_execute_recoursion--;
                   }
                   
                 if(using_code_frame) {                  if(using_code_frame) {
                         // CodeFrame soul:                          // CodeFrame soul:
                         //   string writes were intercepted                          //   string writes were intercepted
                         //   returning them as the result of getting code-junction                          //   returning them as the result of getting code-junction
                         result=NEW VString(*frame->get_string());                          result=NEW VString(*frame->get_string());
                 } else                   } else 
                         result=frame->result();                          result=&frame->result();
                                   
                 wcontext=static_cast<WContext *>(POP());                    wcontext=static_cast<WContext *>(POP());  
                 rcontext=POP();                    rcontext=POP();  
Line 839  Value& Request::process(Value& value, co Line 882  Value& Request::process(Value& value, co
         return *result;          return *result;
 }  }
   
 const String *Request::execute_method(Value& aself, const Method& method,   const String *Request::execute_method(Value& aself, const Method& method,
                                                                           bool return_cstr) {                  bool return_cstr) {
         PUSH(self);            PUSH(self);  
         PUSH(root);            PUSH(root);  
         PUSH(rcontext);            PUSH(rcontext);  
Line 854  const String *Request::execute_method(Va Line 897  const String *Request::execute_method(Va
         execute(*method.parser_code);          execute(*method.parser_code);
                   
         // result          // result
         const String *result;          const String *result=return_cstr ? &wcontext->as_string() : 0;
         if(return_cstr)          
                 result=&wcontext->as_string();          wcontext=static_cast<WContext *>(POP());  
         else          rcontext=POP();  
                 result=0; // ignore result          root=POP();  
           self=static_cast<VAliased *>(POP());
           
           // return
           return result;
   }
   
   const String& Request::execute_method(VMethodFrame& amethodFrame, const Method& method) {
           PUSH(self);  
           PUSH(root);  
           PUSH(rcontext);  
           PUSH(wcontext);
           
           // initialize contexts
           root=rcontext=self=&amethodFrame;
           wcontext=&amethodFrame;
           
           // execute!     
           execute(*method.parser_code);
           
           // result
           const String& result=wcontext->as_string();
                   
         wcontext=static_cast<WContext *>(POP());            wcontext=static_cast<WContext *>(POP());  
         rcontext=POP();            rcontext=POP();  
Line 870  const String *Request::execute_method(Va Line 934  const String *Request::execute_method(Va
 }  }
   
 const String *Request::execute_virtual_method(Value& aself,   const String *Request::execute_virtual_method(Value& aself, 
                                                                                           const String& method_name,                                                                                             const String& method_name) {
                                                                                           bool return_cstr) {  
         if(Value *value=aself.get_element(method_name))          if(Value *value=aself.get_element(method_name))
                 if(Junction *junction=value->get_junction())                  if(Junction *junction=value->get_junction())
                         if(const Method *method=junction->method)                           if(const Method *method=junction->method) 
                                 return execute_method(aself, *method, return_cstr);                                  return execute_method(aself, *method, true /*return_cstr*/);
                                                   
         return 0;          return 0;
 }  }
   
 const String *Request::execute_nonvirtual_method(VStateless_class& aclass,   const String *Request::execute_nonvirtual_method(VStateless_class& aclass, 
                                                                                                  const String& method_name,                                                                                                    const String& method_name,
                                                                                                  bool return_cstr) {                                                                                                   bool return_cstr) {
         if(const Method *method=aclass.get_method(method_name))          if(const Method *method=aclass.get_method(method_name))
                 return execute_method(aclass, *method, return_cstr);                  return execute_method(aclass, *method, return_cstr);

Removed from v.1.202  
changed lines
  Added in v.1.209


E-mail: