Diff for /parser3/src/main/execute.C between versions 1.241 and 1.253

version 1.241, 2002/06/12 11:40:32 version 1.253, 2002/08/14 14:18:28
Line 3 Line 3
   
         Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
   
         $Id$  
 */  */
   
   static const char* IDENT_EXECUTE_C="$Date$";
   
 #include "pa_opcode.h"  #include "pa_opcode.h"
 #include "pa_array.h"   #include "pa_array.h" 
 #include "pa_request.h"  #include "pa_request.h"
Line 231  void Request::execute(const Array& ops) Line 231  void Request::execute(const Array& ops)
                                 value=POP();                                  value=POP();
                                 const String& name=POP_NAME();                                  const String& name=POP_NAME();
                                 Value *ncontext=POP();                                  Value *ncontext=POP();
                                 ncontext->put_element(name, value);                                  ncontext->put_element(name, value, false);
                                 break;                                  break;
                         }                          }
                 case OP_CONSTRUCT_EXPR:                  case OP_CONSTRUCT_EXPR:
Line 242  void Request::execute(const Array& ops) Line 242  void Request::execute(const Array& ops)
                                 value=POP();                                  value=POP();
                                 const String& name=POP_NAME();                                  const String& name=POP_NAME();
                                 Value *ncontext=POP();                                  Value *ncontext=POP();
                                 ncontext->put_element(name, value->as_expr_result());                                  ncontext->put_element(name, value->as_expr_result(), false);
                                 break;                                  break;
                         }                          }
                 case OP_CURLY_CODE__CONSTRUCT:                  case OP_CURLY_CODE__CONSTRUCT:
Line 263  void Request::execute(const Array& ops) Line 263  void Request::execute(const Array& ops)
                                 value=NEW VJunction(j);                                  value=NEW VJunction(j);
                                 const String& name=POP_NAME();                                  const String& name=POP_NAME();
                                 Value *ncontext=POP();                                  Value *ncontext=POP();
                                 ncontext->put_element(name, value);                                  ncontext->put_element(name, value, false);
                                 break;                                  break;
                         }                          }
                 case OP_NESTED_CODE:                  case OP_NESTED_CODE:
Line 304  void Request::execute(const Array& ops) Line 304  void Request::execute(const Array& ops)
                                                   
                 case OP_GET_ELEMENT_OR_OPERATOR:                  case OP_GET_ELEMENT_OR_OPERATOR:
                         {                          {
                                 // maybe they do ^object.method[] call, remember the fact  
                                 wcontext->set_somebody_entered_some_object(true);  
   
                                 //_asm int 3;                                  //_asm int 3;
                                 value=get_element(last_get_element_name, true);                                  value=get_element(last_get_element_name, true);
                                 PUSH(value);                                  PUSH(value);
Line 314  void Request::execute(const Array& ops) Line 311  void Request::execute(const Array& ops)
                         }                          }
                 case OP_GET_ELEMENT:                  case OP_GET_ELEMENT:
                         {                          {
                                 // maybe they do ^object.method[] call, remember the fact  
                                 wcontext->set_somebody_entered_some_object(true);  
   
                                 //_asm int 3;                                  //_asm int 3;
                                 value=get_element(last_get_element_name, false);                                  value=get_element(last_get_element_name, false);
                                 PUSH(value);                                  PUSH(value);
Line 482  void Request::execute(const Array& ops) Line 476  void Request::execute(const Array& ops)
                                                 throw Exception("parser.runtime",                                                  throw Exception("parser.runtime",
                                                         &frame.name(),                                                          &frame.name(),
                                                         "method is static and can not be used as constructor");                                                          "method is static and can not be used as constructor");
                                 } else {                                  } else
                                         // this is not constructor call                                          self=&frame.junction.self;
   
                                         // not ^name.method call, name:method call; and  
                                         // is context object or class & is it my class or my parent's class and?  
                                         VStateless_class *read_class=rcontext->get_class();  
                                         if(  
                                                 !(wcontext->get_somebody_entered_some_object() &&  
                                                 !wcontext->get_somebody_entered_some_class()) &&   
                                                 read_class && read_class->is_or_derived_from(*called_class)) // yes  
                                                 self=rcontext; // dynamic call  
                                         else // no, not me or relative of mine (=total stranger)  
                                                 self=&frame.junction.self; // static call  
                                 }  
   
                                 frame.set_self(*self);                                  frame.set_self(*self);
   
Line 504  void Request::execute(const Array& ops) Line 486  void Request::execute(const Array& ops)
                                                                   
                                 rcontext=wcontext=&frame;                                  rcontext=wcontext=&frame;
                                 {                                  {
                                         // take object or class from any wrappers  
                                         // and substitute class alias to the class they are called AS  
                                         Temp_alias temp_alias(*self->get_aliased(), *frame.junction.vclass);  
   
                                         const Method& method=*frame.junction.method;                                          const Method& method=*frame.junction.method;
                                         Method::Call_type call_type=                                          Method::Call_type call_type=
                                                 called_class==self ? Method::CT_STATIC : Method::CT_DYNAMIC;                                                  called_class==self ? Method::CT_STATIC : Method::CT_DYNAMIC;
Line 545  void Request::execute(const Array& ops) Line 523  void Request::execute(const Array& ops)
                                 wcontext=static_cast<WContext *>(POP());                                    wcontext=static_cast<WContext *>(POP());  
                                 rcontext=POP();                                    rcontext=POP();  
                                 root=POP();                                    root=POP();  
                                 self=static_cast<VAliased *>(POP());                                  self=static_cast<Value *>(POP());
   
 #ifdef DEBUG_STRING_APPENDS_VS_EXPANDS  #ifdef DEBUG_STRING_APPENDS_VS_EXPANDS
                                 if(const String *s=value->get_string())                                  if(const String *s=value->get_string())
Line 554  void Request::execute(const Array& ops) Line 532  void Request::execute(const Array& ops)
   
                                 if(op.code==OP_CALL__WRITE) {                                  if(op.code==OP_CALL__WRITE) {
                                         write_assign_lang(result, last_get_element_name);                                          write_assign_lang(result, last_get_element_name);
                                         // forget the fact they've entered some ^object.method[].  
                                         // see OP_GET_ELEMENT  
                                         wcontext->set_somebody_entered_some_object(false);  
                                 } else { // OP_CALL                                  } else { // OP_CALL
                                         PUSH(&result.as_value());                                          PUSH(&result.as_value());
                                 }                                  }
Line 848  void Request::execute(const Array& ops) Line 823  void Request::execute(const Array& ops)
                         }                          }
                 case OP_IS:                  case OP_IS:
                         {                          {
                                 //_asm int 3;  
                                 b=POP();  a=POP();                                  b=POP();  a=POP();
                                 value=NEW VBool(pool(), b->as_string() == a->type());                                  value=NEW VBool(pool(), a->is(b->as_string().cstr(), false));
                                 PUSH(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
Line 868  Value *Request::get_element(const String Line 842  Value *Request::get_element(const String
         const String& name=POP_NAME();  remember_name=&name;          const String& name=POP_NAME();  remember_name=&name;
         Value *ncontext=POP();          Value *ncontext=POP();
         Value *value=0;          Value *value=0;
         if(can_call_operator)          if(can_call_operator) {
                 if(Method* method=OP.get_method(name)) { // looking operator of that name FIRST                  if(Method* method=OP.get_method(name)) { // looking operator of that name FIRST
                         // as if that method were in self and we have normal dynamic method here                          // as if that method were in self and we have normal dynamic method here
                         Junction& junction=*NEW Junction(pool(),                           Junction& junction=*NEW Junction(pool(), 
                                 *root, self->get_class(), method, 0,0,0,0);                                  *root, self->get_class(), method, 0,0,0,0);
                         value=NEW VJunction(junction);                          value=NEW VJunction(junction);
                 }                  }
           }
           if(!value) {
                   if(!wcontext->get_constructing() // not constructing
                           && wcontext->get_somebody_entered_some_class() ) // ^class:method
                           if(VStateless_class *called_class=ncontext->get_class())
                                   if(VStateless_class *read_class=rcontext->get_class())
                                           if(read_class->derived_from(*called_class)) // current derived from called
                                                   if(Value *base_object=self->base_object()) { // doing DYNAMIC call
                                                           Temp_derived(*base_object, 0); // temporarily prevent go-back-down virtual calls
                                                           value=base_object->get_element(name, base_object, false); // virtual-up lookup starting from parent
                                                           goto _void;
                                                   }
           }
         if(!value)          if(!value)
                 value=ncontext->get_element(name);                  value=ncontext->get_element(name, ncontext, false);
   
   _void:
         if(value)          if(value)
                 value=&process_to_value(*value); // process possible code-junction                  value=&process_to_value(*value); // process possible code-junction
         else          else
Line 950  StringOrValue Request::process(Value& in Line 939  StringOrValue Request::process(Value& in
                 wcontext=static_cast<WContext *>(POP());                    wcontext=static_cast<WContext *>(POP());  
                 rcontext=POP();                    rcontext=POP();  
                 root=POP();                    root=POP();  
                 self=static_cast<VAliased *>(POP());                  self=static_cast<Value *>(POP());
                                   
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
                 debug_printf(pool(), "<-ja returned");                  debug_printf(pool(), "<-ja returned");
Line 961  StringOrValue Request::process(Value& in Line 950  StringOrValue Request::process(Value& in
         return result;          return result;
 }  }
   
 void Request::execute_method(Value& aself, const Method& method,  const String& Request::execute_method(VMethodFrame& amethodFrame, const Method& method) {
                 const String **return_string) {  
         PUSH(self);            PUSH(self);  
         PUSH(root);            PUSH(root);  
         PUSH(rcontext);            PUSH(rcontext);  
         PUSH(wcontext);          PUSH(wcontext);
                   
         // initialize contexts          // initialize contexts
         root=rcontext=self=&aself;          root=rcontext=self=&amethodFrame;
         WWrapper local(pool(), &aself);          wcontext=&amethodFrame;
         wcontext=&local;   
                   
         // execute!               // execute!     
         execute(*method.parser_code);          execute(*method.parser_code);
                   
         // result          // result
         const String *result=0;          const String& result=wcontext->result().as_string();
         if(return_string) {  
                 if(Value *result_var_value=wcontext->get_element(*result_var_name))  
                         *return_string=&result_var_value->as_string();  
                 else  
                         *return_string=&wcontext->as_string();  
         }  
                   
         wcontext=static_cast<WContext *>(POP());            wcontext=static_cast<WContext *>(POP());  
         rcontext=POP();            rcontext=POP();  
         root=POP();            root=POP();  
         self=static_cast<VAliased *>(POP());          self=static_cast<Value *>(POP());
           
           // return
           return result;
 }  }
   
 const String& Request::execute_method(VMethodFrame& amethodFrame, const Method& method) {  void Request::execute_method(Value& aself, 
                                                            const Method& method, VString *optional_param,
                                                            const String **return_string) {
         PUSH(self);            PUSH(self);  
         PUSH(root);            PUSH(root);  
         PUSH(rcontext);            PUSH(rcontext);  
         PUSH(wcontext);          PUSH(wcontext);
                   
         // initialize contexts          // initialize contexts
         root=rcontext=self=&amethodFrame;          //root=rcontext=self=&aself;
         wcontext=&amethodFrame;          self=&aself;    
   //      WWrapper local(pool(), &aself);
   //      wcontext=&local; 
           Junction local_junction(pool(), *self, self->get_class(), &method, 0,0,0,0);
           VMethodFrame local_frame(pool(), method.name, local_junction);
           if(optional_param && local_frame.can_store_param()) {
                   local_frame.store_param(optional_param);
                   local_frame.fill_unspecified_params();
           }
           local_frame.set_self(*self);
           root=rcontext=wcontext=&local_frame; 
   
           // prevent non-string writes for better error reporting
           if(return_string)
                   wcontext->write(local_frame);
                   
         // execute!               // execute!     
         execute(*method.parser_code);          execute(*method.parser_code);
                   
         // result          // result
         const String& result=wcontext->result().as_string();          const String *result=0;
           if(return_string)
                   *return_string=&wcontext->result().as_string();
                   
         wcontext=static_cast<WContext *>(POP());            wcontext=static_cast<WContext *>(POP());  
         rcontext=POP();            rcontext=POP();  
         root=POP();            root=POP();  
         self=static_cast<VAliased *>(POP());          self=static_cast<Value *>(POP());
           
         // return  
         return result;  
 }  
   
 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) {  
                                 const String *result;  
                                 execute_method(aself, *method, &result);  
                                 return result;  
                         }  
                           
         return 0;  
 }  }
   
 void Request::execute_nonvirtual_method(VStateless_class& aclass,   void Request::execute_nonvirtual_method(VStateless_class& aclass, 
                                                                                                  const String& method_name,                                                                                                   const String& method_name, VString *optional_param,
                                                                                                  const String **return_string,                                                                                                   const String **return_string,
                                                                                                  const Method **return_method) {                                                                                                   const Method **return_method) {
   
         const Method *method=aclass.get_method(method_name);          const Method *method=aclass.get_method(method_name);
         if(return_string)          if(return_string)
                 *return_string=0;                  *return_string=0;
Line 1040  void Request::execute_nonvirtual_method( Line 1027  void Request::execute_nonvirtual_method(
                 *return_method=method;                  *return_method=method;
   
         if(method)          if(method)
                 execute_method(aclass, *method, return_string);                  execute_method(aclass, *method, optional_param, return_string);
   }
   
   const String *Request::execute_virtual_method(Value& aself, 
                                                                                             const String& method_name) {
           if(Value *value=aself.get_element(method_name, &aself, false))
                   if(Junction *junction=value->get_junction())
                           if(const Method *method=junction->method) {
                                   const String *result;
                                   execute_method(aself, *method, 0/*no params*/, &result);
                                   return result;
                           }
                           
           return 0;
 }  }
   

Removed from v.1.241  
changed lines
  Added in v.1.253


E-mail: