Diff for /parser3/src/main/execute.C between versions 1.306 and 1.313

version 1.306, 2004/07/30 10:01:14 version 1.313, 2005/08/09 08:14:51
Line 1 Line 1
 /** @file  /** @file
         Parser: executor part of request class.          Parser: executor part of request class.
   
         Copyright (c) 2001-2004 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001-2005 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)
 */  */
   
Line 186  void Request::execute(ArrayOperation& op Line 186  void Request::execute(ArrayOperation& op
                                 Value& value=stack.pop().value();                                  Value& value=stack.pop().value();
                                 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();
                                 ncontext.put_element(name, &value, false);                                  put_element(ncontext, name, value);
   
                                 break;                                  break;
                         }                          }
                 case OP_CONSTRUCT_EXPR:                  case OP_CONSTRUCT_EXPR:
Line 194  void Request::execute(ArrayOperation& op Line 195  void Request::execute(ArrayOperation& op
                                 // see OP_PREPARE_TO_EXPRESSION                                  // see OP_PREPARE_TO_EXPRESSION
                                 wcontext->set_in_expression(false);                                  wcontext->set_in_expression(false);
   
                                 Value& value=stack.pop().value();                                  Value& expr=stack.pop().value();
                                 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();
                                 ncontext.put_element(name, &value.as_expr_result(), false);                                  Value& value=expr.as_expr_result();
                                   put_element(ncontext, name, value);
                                 break;                                  break;
                         }                          }
                 case OP_CURLY_CODE__CONSTRUCT:                  case OP_CURLY_CODE__CONSTRUCT:
Line 207  void Request::execute(ArrayOperation& op Line 209  void Request::execute(ArrayOperation& op
                                 debug_printf(sapi_info, " (%d)\n", local_ops.count());                                  debug_printf(sapi_info, " (%d)\n", local_ops.count());
                                 debug_dump(sapi_info, 1, local_ops);                                  debug_dump(sapi_info, 1, local_ops);
 #endif                            #endif                          
                                 Value& value=*new VJunction(new Junction(                                   Value& value=*new VJunction(
                                         get_self(), 0,                                          get_self(), 0,
                                         method_frame,                                           method_frame, 
                                         rcontext,                                           rcontext, 
                                         wcontext,                                           wcontext, 
                                         &local_ops));                                          &local_ops);
   
                                 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();
                                 ncontext.put_element(name, &value, false);                                  if(const VJunction* vjunction=ncontext.put_element(ncontext, name, &value, false))
                                           if(vjunction!=PUT_ELEMENT_REPLACED_ELEMENT)
                                                   throw Exception("parser.runtime",
                                                           0,
                                                           "property value can not be code, use [] or () brackets");
                                           
                                 break;                                  break;
                         }                          }
                 case OP_NESTED_CODE:                  case OP_NESTED_CODE:
Line 350  void Request::execute(ArrayOperation& op Line 357  void Request::execute(ArrayOperation& op
                                 // hence, we zero junction.wcontext here, and later                                  // hence, we zero junction.wcontext here, and later
                                 // in .process we would test that field                                   // in .process we would test that field 
                                 // in decision "which wwrapper to use"                                  // in decision "which wwrapper to use"
                                 Value& value=*new VJunction(new Junction(                                  Value& value=*new VJunction(
                                         get_self(), 0,                                          get_self(), 0,
                                         method_frame,                                           method_frame, 
                                         rcontext,                                           rcontext, 
                                         opcode==OP_EXPR_CODE__STORE_PARAM?0:wcontext,                                           opcode==OP_EXPR_CODE__STORE_PARAM?0:wcontext, 
                                         &local_ops));                                          &local_ops);
                                 // store param                                  // store param
                                 // this op is executed from CALL local_ops only, so can not check method_frame_to_fill==0                                  // this op is executed from CALL local_ops only, so can not check method_frame_to_fill==0
                                 frame.store_param(value);                                  frame.store_param(value);
Line 425  void Request::execute(ArrayOperation& op Line 432  void Request::execute(ArrayOperation& op
                                 WContext *saved_wcontext=wcontext;                                  WContext *saved_wcontext=wcontext;
                                                                   
                                 VStateless_class& called_class=*frame.junction.self.get_class();                                  VStateless_class& called_class=*frame.junction.self.get_class();
                                 Value* new_self=&get_self();                                  Value* new_self;
                                 if(wcontext->get_constructing()) {                                  if(wcontext->get_constructing()) {
                                         wcontext->set_constructing(false);                                          wcontext->set_constructing(false);
                                           new_self=&get_self();
                                         if(frame.junction.method->call_type!=Method::CT_STATIC) {                                          if(frame.junction.method->call_type!=Method::CT_STATIC) {
                                                 // this is a constructor call                                                  // this is a constructor call
   
                                                 if(Value* value=called_class.create_new_value(fpool)) {                                                  HashStringValue& new_object_fields=*new HashStringValue();
                                                   if(Value* value=called_class.create_new_value(fpool, new_object_fields)) {
                                                         // some stateless_class creatable derivates                                                          // some stateless_class creatable derivates
                                                         new_self=value;                                                          new_self=value;
                                                 } else                                                   } else 
Line 472  void Request::execute(ArrayOperation& op Line 481  void Request::execute(ArrayOperation& op
                                                                 *this,                                                                   *this, 
                                                                 *frame.numbered_params()); // execute it                                                                  *frame.numbered_params()); // execute it
                                                 } else // parser code, execute it                                                  } else // parser code, execute it
                                                         recoursion_checked_execute(/*frame.name(), */*method.parser_code);                                                          recoursion_checked_execute(*method.parser_code);
                                         } else                                          } else
                                                 throw Exception("parser.runtime",                                                  throw Exception("parser.runtime",
                                                         0, //&frame.name(),                                                          0, //&frame.name(),
Line 828  Value& Request::get_element(Value& ncont Line 837  Value& Request::get_element(Value& ncont
         Value* value=0;          Value* value=0;
         if(can_call_operator) {          if(can_call_operator) {
                 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
                         value=new VJunction(new Junction(                          value=new VJunction(main_class, method);
                                 main_class, method, 0,0,0, 0));  
         }          }
         if(!value) {          if(!value) {
                 if(!wcontext->get_constructing() // not constructing                  if(!wcontext->get_constructing() // not constructing
Line 864  value_ready: Line 872  value_ready:
         return *value;          return *value;
 }  }
   
   void Request::put_element(Value& ncontext, const String& name, Value& value) {
           // put_element can return property-setting-junction
           if(const VJunction* vjunction=ncontext.put_element(ncontext, name, &value, false))
                   if(vjunction!=PUT_ELEMENT_REPLACED_ELEMENT) {
                           const Junction& junction=vjunction->junction();
                           // process it
                           ArrayString* params_names=junction.method->params_names;
                           int param_count=params_names? params_names->count(): 0;
                           if(param_count!=1)
                                   throw Exception("parser.runtime",
                                           0,
                                           "setter method must have ONE parameter (has %d parameters)", param_count);
   
                           VMethodFrame frame(junction, method_frame/*caller*/);
                           frame.store_param(value);
   
                           frame.set_self(frame.junction.self);
   
                           VMethodFrame *saved_method_frame=method_frame;
                           Value* saved_rcontext=rcontext;
                           WContext *saved_wcontext=wcontext;
   
                           rcontext=wcontext=&frame;
                           method_frame=&frame;
   
                           // prevent non-string writes for better error reporting [setters are not expected to return anything]
                           wcontext->write(*method_frame);
   
                           recoursion_checked_execute(*frame.junction.method->parser_code); // parser code, execute it
                           // we don't need it StringOrValue result=wcontext->result();
   
                           method_frame=saved_method_frame;
                           wcontext=saved_wcontext;
                           rcontext=saved_rcontext;
                   }
   }
   
 /**     @param intercept_string  /**     @param intercept_string
         - true:          - true:
                 they want result=string value,                   they want result=string value, 
Line 876  value_ready: Line 921  value_ready:
     using the fact it's either string_ or value_ result requested to speed up checkes      using the fact it's either string_ or value_ result requested to speed up checkes
 */  */
 StringOrValue Request::process(Value& input_value, bool intercept_string) {  StringOrValue Request::process(Value& input_value, bool intercept_string) {
         StringOrValue result;  
         Junction* junction=input_value.get_junction();          Junction* junction=input_value.get_junction();
         if(junction && junction->code) { // is it a code-junction?          if(junction) {
                 // process it                  if(junction->is_getter) { // is it a getter-junction?
                           // process it
   
                           VMethodFrame frame(*junction, method_frame/*caller*/);
                           if(junction->method->params_names)
                                   throw Exception("parser.runtime",
                                           0,
                                           "getter method must have no parameters");
   
                           frame.set_self(frame.junction.self);
   
                           VMethodFrame *saved_method_frame=method_frame;
                           Value* saved_rcontext=rcontext;
                           WContext *saved_wcontext=wcontext;
   
                           rcontext=wcontext=&frame;
                           method_frame=&frame;
   
                           recoursion_checked_execute(*frame.junction.method->parser_code); // parser code, execute it
                           StringOrValue result=wcontext->result();
   
                           method_frame=saved_method_frame;
                           wcontext=saved_wcontext;
                           rcontext=saved_rcontext;
   
                           return result;
                   }
   
                   if(junction->code) { // is it a code-junction?
                           // process it
                           StringOrValue result;
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
                 debug_printf(sapi_info, "ja->\n");                          debug_printf(sapi_info, "ja->\n");
 #endif  #endif
   
                 if(!junction->method_frame)                          if(!junction->method_frame)
                         throw Exception("parser.runtime",                                  throw Exception("parser.runtime",
                                 0,                                  0,
                                 "junction used outside of context");                                  "junction used outside of context");
   
                 VMethodFrame *saved_method_frame=method_frame;                            VMethodFrame *saved_method_frame=method_frame;  
                 Value* saved_rcontext=rcontext;                            Value* saved_rcontext=rcontext;  
                 WContext *saved_wcontext=wcontext;                          WContext *saved_wcontext=wcontext;
                   
                 method_frame=junction->method_frame;                          method_frame=junction->method_frame;
                 rcontext=junction->rcontext;                          rcontext=junction->rcontext;
   
                 // for expression method params                          // for expression method params
                 // wcontext is set 0                          // wcontext is set 0
                 // using the fact in decision "which wwrapper to use"                          // using the fact in decision "which wwrapper to use"
                 bool using_code_frame=intercept_string && junction->wcontext;                          bool using_code_frame=intercept_string && junction->wcontext;
                 if(using_code_frame) {                          if(using_code_frame) {
                         // almost plain wwrapper about junction wcontext,                                   // almost plain wwrapper about junction wcontext, 
                         // BUT intercepts string writes                                  // BUT intercepts string writes
                         VCodeFrame local(*junction->wcontext, junction->wcontext);                                  VCodeFrame local(*junction->wcontext, junction->wcontext);
                         wcontext=&local;                                  wcontext=&local;
   
                                   // execute it
                                   recoursion_checked_execute(*junction->code);
   
                                   // CodeFrame soul:
                                   //   string writes were intercepted
                                   //   returning them as the result of getting code-junction
                                   result.set_string(*wcontext->get_string());
                           } else {
                                   // plain wwrapper
                                   WWrapper local(0/*empty*/, wcontext);
                                   wcontext=&local;
   
                                   // execute it
                                   recoursion_checked_execute(*junction->code);
   
                                   result=wcontext->result();
                           }
   
                           wcontext=saved_wcontext;
                           rcontext=saved_rcontext;
                           method_frame=saved_method_frame;
   
                         // execute it  
                         recoursion_checked_execute(*junction->code);  
                           
                         // CodeFrame soul:  
                         //   string writes were intercepted  
                         //   returning them as the result of getting code-junction  
                         result.set_string(*wcontext->get_string());  
                 } else {  
                         // plain wwrapper  
                         WWrapper local(0/*empty*/, wcontext);  
                         wcontext=&local;  
                   
                         // execute it  
                         recoursion_checked_execute(*junction->code);  
                   
                         result=wcontext->result();  
                 }  
                   
                 wcontext=saved_wcontext;  
                 rcontext=saved_rcontext;  
                 method_frame=saved_method_frame;  
                   
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
                 debug_printf(sapi_info, "<-ja returned");                          debug_printf(sapi_info, "<-ja returned");
 #endif  #endif
         } else {                          return result;
                 result.set_value(input_value);                  }
         }  
         return result;                  // it is then method-junction, do not explode it
                   // just return it as we do for usual objects
           }       
   
           return input_value;
 }  }
   
 StringOrValue Request::execute_method(VMethodFrame& amethod_frame, const Method& method) {  StringOrValue Request::execute_method(VMethodFrame& amethod_frame, const Method& method) {
Line 966  const String* Request::execute_method(Va Line 1044  const String* Request::execute_method(Va
         Value* saved_rcontext=rcontext;            Value* saved_rcontext=rcontext;  
         WContext *saved_wcontext=wcontext;          WContext *saved_wcontext=wcontext;
                   
         Junction local_junction(aself, &method, 0,0,0, 0);          Junction local_junction(aself, &method);
         VMethodFrame local_frame(local_junction, method_frame/*caller*/);          VMethodFrame local_frame(local_junction, method_frame/*caller*/);
         if(optional_param && local_frame.can_store_param()) {          if(optional_param && local_frame.can_store_param()) {
                 local_frame.store_param(*optional_param);                  local_frame.store_param(*optional_param);

Removed from v.1.306  
changed lines
  Added in v.1.313


E-mail: