Diff for /parser3/src/main/execute.C between versions 1.295.2.6 and 1.296

version 1.295.2.6, 2003/01/31 16:45:26 version 1.296, 2003/04/07 12:39:32
Line 1 Line 1
 /** @file  /** @file
         Parser: executor part of request class.          Parser: executor part of request class.
   
         Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001, 2003 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 62  char *opcode_name[]={ Line 62  char *opcode_name[]={
         "IS"          "IS"
 };  };
   
 void va_debug_printf(Pool& pool, const char* fmt,va_list args) {  void va_debug_printf(Pool& pool, const char *fmt,va_list args) {
         char buf[MAX_STRING];          char buf[MAX_STRING];
         vsnprintf(buf, MAX_STRING, fmt, args);          vsnprintf(buf, MAX_STRING, fmt, args);
         SAPI::log(pool, "%s", buf);          SAPI::log(pool, "%s", buf);
 }  }
   
 void debug_printf(Pool& pool, const char* fmt, ...) {  void debug_printf(Pool& pool, const char *fmt, ...) {
     va_list args;      va_list args;
     va_start(args,fmt);      va_start(args,fmt);
     va_debug_printf(pool,fmt,args);      va_debug_printf(pool,fmt,args);
Line 76  void debug_printf(Pool& pool, const char Line 76  void debug_printf(Pool& pool, const char
 }  }
   
 void debug_dump(Pool& pool, int level, const Array& ops) {  void debug_dump(Pool& pool, int level, const Array& ops) {
         Array_iterator i(ops);          Array_iter i(ops);
         while(i.has_next()) {          while(i.has_next()) {
                 Operation op;                  Operation op;
                 op.cast=i.next();                  op.cast=i.next();
   
                 if(op.code==OP_VALUE || op.code==OP_STRING__WRITE) {                  if(op.code==OP_VALUE || op.code==OP_STRING__WRITE) {
                         Value* value=i.next().value;                          Value *value=static_cast<Value *>(i.next());
                         debug_printf(pool,                           debug_printf(pool, 
                                 "%*s%s"                                  "%*s%s"
                                 " \"%s\" %s",                                   " \"%s\" %s", 
Line 107  void debug_dump(Pool& pool, int level, c Line 107  void debug_dump(Pool& pool, int level, c
 }  }
 #endif  #endif
   
 /*#define stack.push(value) stack.push(value.get())  #define PUSH(value) stack.push(value)
 #define stack.pop().value static_cast<Value* >(stack.pop())  #define POP() static_cast<Value *>(stack.pop())
   #define POP_NAME() static_cast<Value *>(stack.pop())->as_string()
 #define stack.push(value) stack.push(value)  
 #define stack.pop().string static_cast<Value* >(stack.pop())->as_string(&pool()).get()  
 #define POP_CODE() static_cast<Array *>(stack.pop())  #define POP_CODE() static_cast<Array *>(stack.pop())
 */  
 // Request  
   
 void Request::execute(ArrayOperation& ops) {  void Request::execute(const Array& ops) {
 //      _asm int 3;  //      _asm int 3;
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
         debug_printf(pool(), "source----------------------------\n");          debug_printf(pool(), "source----------------------------\n");
         debug_dump(pool(), 0, ops);          debug_dump(pool(), 0, ops);
         debug_printf(pool(), "execution-------------------------\n");          debug_printf(pool(), "execution-------------------------\n");
 #endif  #endif
         StringPtr last_get_element_name(0);          const String *last_get_element_name=0;
   
         Array_iterator<Operation> i(ops);          Array_iter i(ops);
         while(i.has_next()) {          while(i.has_next()) {
                 if(interrupted())                  if(interrupted())
                         throw Exception("parser.interrupted",                          throw Exception("parser.interrupted",
                                 Exception::undefined_source,                                  0,
                                 "execution stopped");                                  "execution stopped");
   
                 Operation& op=i.next();                  Operation op;
                   op.cast=i.next();
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
                 debug_printf(pool(), "%d:%s", stack.top_index()+1, opcode_name[op.code]);                  debug_printf(pool(), "%d:%s", stack.top_index()+1, opcode_name[op.code]);
 #endif  #endif
   
                 ValuePtr value;                  Value *value;
                 ValuePtr a; ValuePtr b;                  Value *a; Value *b;
                 //ArrayOperationPtr b_code;                  Array *b_code;
                   
                 StringPtr name;  
                 Value* ncontext;  
   
                 ArrayOperationPtr local_ops;  
   
                 switch(op.code) {                  switch(op.code) {
                 // param in next instruction                  // param in next instruction
                 case OP_VALUE:                  case OP_VALUE:
                         {                          {
                                 value=i.next().value;                                  value=static_cast<Value *>(i.next());
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
                                 debug_printf(pool(), " \"%s\" %s", value->get_string()->cstr(), value->type());                                  debug_printf(pool(), " \"%s\" %s", value->get_string()->cstr(), value->type());
 #endif  #endif
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_GET_CLASS:                  case OP_GET_CLASS:
Line 162  void Request::execute(ArrayOperation& op Line 153  void Request::execute(ArrayOperation& op
                                 // maybe they do ^class:method[] call, remember the fact                                  // maybe they do ^class:method[] call, remember the fact
                                 wcontext->set_somebody_entered_some_class();                                  wcontext->set_somebody_entered_some_class();
   
                                 name=stack.pop().string;                                  const String& name=POP_NAME();
                                 value=classes().get(name);                                  value=static_cast<Value *>(classes().get(name));
                                 if(!value)                                   if(!value) 
                                         throw Exception("parser.runtime",                                          throw Exception("parser.runtime",
                                                 StringPtr(name),                                                  &name,
                                                 "class is undefined");                                                   "class is undefined"); 
   
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                                                   
                 // OP_WITH                  // OP_WITH
                 case OP_WITH_ROOT:                  case OP_WITH_ROOT:
                         {                          {
                                 stack.push(ValuePtr(method_frame));                                  PUSH(method_frame);
                                 break;                                  break;
                         }                          }
                 case OP_WITH_SELF:                   case OP_WITH_SELF: 
                         {                          {
                                 stack.push(ValuePtr(get_self()));                                  PUSH(get_self());
                                 break;                                  break;
                         }                          }
                 case OP_WITH_READ:                   case OP_WITH_READ: 
                         {                          {
                                 stack.push(ValuePtr(rcontext));                                  PUSH(rcontext);
                                 break;                                  break;
                         }                          }
                 case OP_WITH_WRITE:                   case OP_WITH_WRITE: 
                         {                          {
                                 if(wcontext==method_frame)                                  if(wcontext==method_frame)
                                         throw Exception("parser.runtime",                                          throw Exception("parser.runtime",
                                         Exception::undefined_source,                                                  0,
                                                 "$.name outside of $name[...]");                                                  "$.name outside of $name[...]");
   
                                 stack.push(ValuePtr(wcontext));                                  PUSH(wcontext);
                                 break;                                  break;
                         }                          }
                                                   
                 // OTHER ACTIONS BUT WITHs                  // OTHER ACTIONS BUT WITHs
                 case OP_CONSTRUCT_VALUE:                  case OP_CONSTRUCT_VALUE:
                         {                          {
                                 value=stack.pop().value;                                  value=POP();
                                 name=stack.pop().string;                                  const String& name=POP_NAME();
                                 ncontext=stack.pop().value.get();                                  Value *ncontext=POP();
                                 ncontext->put_element(name, value, false);                                  ncontext->put_element(name, value, false);
                                 break;                                  break;
                         }                          }
Line 214  void Request::execute(ArrayOperation& op Line 205  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=stack.pop().value;                                  value=POP();
                                 name=stack.pop().string;                                  const String& name=POP_NAME();
                                 ncontext=stack.pop().value.get();                                  Value *ncontext=POP();
                                 ncontext->put_element(name, value->as_expr_result(), false);                                  ncontext->put_element(name, value->as_expr_result(), false);
                                 break;                                  break;
                         }                          }
                 case OP_CURLY_CODE__CONSTRUCT:                  case OP_CURLY_CODE__CONSTRUCT:
                         {                          {
                                 local_ops=i.next().ops;                                  const Array *local_ops=reinterpret_cast<const Array *>(i.next());
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
                                 debug_printf(pool(), " (%d)\n", local_ops->count());                                  debug_printf(pool(), " (%d)\n", local_ops->size());
                                 debug_dump(pool(), 1, *local_ops);                                  debug_dump(pool(), 1, *local_ops);
 #endif                            #endif                          
                                 value=ValuePtr(new VJunction(JunctionPtr(new Junction(                                   Junction& j=*NEW Junction(pool(), 
                                         *get_self(), 0,                                          *get_self(), 0,
                                         method_frame,                                           method_frame, 
                                         rcontext,                                           rcontext, 
                                         wcontext,                                           wcontext, 
                                         local_ops))));                                          local_ops);
   
                                 name=stack.pop().string;                                  value=NEW VJunction(j);
                                 ncontext=stack.pop().value.get();                                  const String& name=POP_NAME();
                                   Value *ncontext=POP();
                                 ncontext->put_element(name, value, false);                                  ncontext->put_element(name, value, false);
                                 break;                                  break;
                         }                          }
                 case OP_NESTED_CODE:                  case OP_NESTED_CODE:
                         {                          {
                                 local_ops=i.next().ops;                                  Array *local_ops=static_cast<Array *>(i.next());
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
                                 debug_printf(pool(), " (%d)\n", local_ops->count());                                  debug_printf(pool(), " (%d)\n", local_ops->size());
                                 debug_dump(pool(), 1, *local_ops);                                  debug_dump(pool(), 1, *local_ops);
 #endif                            #endif                          
                                 stack.push(local_ops);                                  PUSH(local_ops);
                                 break;                                  break;
                         }                          }
                 case OP_WRITE_VALUE:                  case OP_WRITE_VALUE:
                         {                          {
                                 value=stack.pop().value;                                  value=POP();
                                 write_assign_lang(value, last_get_element_name);                                  write_assign_lang(*value, last_get_element_name);
                                 break;                                  break;
                         }                          }
                 case OP_WRITE_EXPR_RESULT:                  case OP_WRITE_EXPR_RESULT:
                         {                          {
                                 value=stack.pop().value;                                  value=POP();
                                 write_no_lang(*value->as_expr_result());                                  write_no_lang(*value->as_expr_result());
   
                                 // must be after write(result) and                                   // must be after write(result) and 
Line 278  void Request::execute(ArrayOperation& op Line 270  void Request::execute(ArrayOperation& op
                 case OP_GET_ELEMENT_OR_OPERATOR:                  case OP_GET_ELEMENT_OR_OPERATOR:
                         {                          {
                                 value=get_element(last_get_element_name, true);                                  value=get_element(last_get_element_name, true);
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_GET_ELEMENT:                  case OP_GET_ELEMENT:
                         {                          {
                                 value=get_element(last_get_element_name, false);                                  value=get_element(last_get_element_name, false);
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
   
Line 311  void Request::execute(ArrayOperation& op Line 303  void Request::execute(ArrayOperation& op
                                 value=&wcontext->result().as_value();                                  value=&wcontext->result().as_value();
                                 flang=saved_lang;                                  flang=saved_lang;
                                 wcontext=saved_wcontext;                                  wcontext=saved_wcontext;
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                                                   
Line 328  void Request::execute(ArrayOperation& op Line 320  void Request::execute(ArrayOperation& op
                                 // from "$a $b" part of expression taking only string value,                                  // from "$a $b" part of expression taking only string value,
                                 // ignoring any other content of wcontext                                  // ignoring any other content of wcontext
                                 const String *string=wcontext->get_string();                                  const String *string=wcontext->get_string();
                                 Value* value;                                  Value *value;
                                 if(string)                                  if(string)
                                         value=NEW VString(*string);                                          value=NEW VString(*string);
                                 else                                  else
                                         NEW VVoid(pool());                                          NEW VVoid(pool());
                                 wcontext=saved_wcontext;                                  wcontext=saved_wcontext;
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
   
                 // CALL                  // CALL
                 case OP_STORE_PARAM:                  case OP_STORE_PARAM:
                         {                          {
                                 value=stack.pop().value;                                  value=POP();
                                 VMethodFrame *frame=static_cast<VMethodFrame *>(stack.top_value());                                  VMethodFrame *frame=static_cast<VMethodFrame *>(stack.top_value());
                                 // 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 354  void Request::execute(ArrayOperation& op Line 346  void Request::execute(ArrayOperation& op
                                 const Array *local_ops=reinterpret_cast<const Array *>(i.next());                                  const Array *local_ops=reinterpret_cast<const Array *>(i.next());
                                 VMethodFrame *frame=static_cast<VMethodFrame *>(stack.top_value());                                  VMethodFrame *frame=static_cast<VMethodFrame *>(stack.top_value());
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
                                 debug_printf(pool(), " (%d)\n", local_ops->count());                                  debug_printf(pool(), " (%d)\n", local_ops->size());
                                 debug_dump(pool(), 1, *local_ops);                                  debug_dump(pool(), 1, *local_ops);
 #endif                            #endif                          
                                 // when they evaluate expression parameter,                                  // when they evaluate expression parameter,
Line 396  void Request::execute(ArrayOperation& op Line 388  void Request::execute(ArrayOperation& op
                         {                          {
                                 Array *local_ops=static_cast<Array *>(i.next());                                  Array *local_ops=static_cast<Array *>(i.next());
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
                                 debug_printf(pool(), " (%d)\n", local_ops->count());                                  debug_printf(pool(), " (%d)\n", local_ops->size());
                                 debug_dump(pool(), 1, *local_ops);                                  debug_dump(pool(), 1, *local_ops);
   
                                 debug_printf(pool(), "->\n");                                  debug_printf(pool(), "->\n");
 #endif  #endif
                                 value=stack.pop().value;                                  value=POP();
   
                                 Junction *junction=value->get_junction();                                  Junction *junction=value->get_junction();
                                 if(!junction)                                  if(!junction)
Line 424  void Request::execute(ArrayOperation& op Line 416  void Request::execute(ArrayOperation& op
   
                                 VMethodFrame frame(pool(), *last_get_element_name, *junction, method_frame/*caller*/);                                  VMethodFrame frame(pool(), *last_get_element_name, *junction, method_frame/*caller*/);
                                 if(local_ops){ // store param code goes here                                  if(local_ops){ // store param code goes here
                                         stack.push(&frame); // argument for *STORE_PARAM ops                                          PUSH(&frame); // argument for *STORE_PARAM ops
                                         execute(*local_ops);                                          execute(*local_ops);
                                         stack.pop().value;                                          POP();
                                 }                                  }
                                 frame.fill_unspecified_params();                                  frame.fill_unspecified_params();
                                 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;
                                                                   
                                 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=get_self();
                                 if(wcontext->get_constructing()) {                                  if(wcontext->get_constructing()) {
                                         wcontext->set_constructing(false);                                          wcontext->set_constructing(false);
                                         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(ValuePtr value=called_class->create_new_value()) {                                                  if(Value *value=called_class->create_new_value(pool())) {
                                                         // some stateless_class creatable derivates                                                          // some stateless_class creatable derivates
                                                         new_self=value;                                                          new_self=value;
                                                 } else                                                   } else 
Line 486  void Request::execute(ArrayOperation& op Line 478  void Request::execute(ArrayOperation& op
                                                 } catch(...) {                                                  } catch(...) {
                                                         // record it to stack trace                                                          // record it to stack trace
                                                         exception_trace.push((void *)&frame.name());                                                          exception_trace.push((void *)&frame.name());
                                                         rethrow;                                                          /*re*/throw;
                                                 }                                                  }
                                         } else                                          } else
                                                 throw Exception("parser.runtime",                                                  throw Exception("parser.runtime",
Line 509  void Request::execute(ArrayOperation& op Line 501  void Request::execute(ArrayOperation& op
                                 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);
                                 } else { // OP_CALL                                  } else { // OP_CALL
                                         stack.push(&result.as_value());                                          PUSH(&result.as_value());
                                 }                                  }
                                                                   
 #ifdef DEBUG_EXECUTE  #ifdef DEBUG_EXECUTE
Line 521  void Request::execute(ArrayOperation& op Line 513  void Request::execute(ArrayOperation& op
                 // expression ops: unary                  // expression ops: unary
                 case OP_NEG:                  case OP_NEG:
                         {                          {
                                 Value* operand=stack.pop().value;                                  Value *operand=POP();
                                 value=NEW VDouble(pool(), -operand->as_double());                                  value=NEW VDouble(pool(), -operand->as_double());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_INV:                  case OP_INV:
                         {                          {
                                 Value* operand=stack.pop().value;                                  Value *operand=POP();
                                 value=NEW VDouble(pool(), ~operand->as_int());                                  value=NEW VDouble(pool(), ~operand->as_int());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_NOT:                  case OP_NOT:
                         {                          {
                                 Value* operand=stack.pop().value;                                  Value *operand=POP();
                                 value=NEW VBool(pool(), !operand->as_bool());                                  value=NEW VBool(pool(), !operand->as_bool());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_DEF:                  case OP_DEF:
                         {                          {
                                 Value* operand=stack.pop().value;                                  Value *operand=POP();
                                 value=NEW VBool(pool(), operand->is_defined());                                  value=NEW VBool(pool(), operand->is_defined());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_IN:                  case OP_IN:
                         {                          {
                                 /// @test String::cmp                                  /// @test String::cmp
                                 Value* operand=stack.pop().value;                                  Value *operand=POP();
                                 const char* path=operand->as_string().cstr();                                  const char *path=operand->as_string().cstr();
                                 value=NEW VBool(pool(),                                   value=NEW VBool(pool(), 
                                         info.uri && strncmp(path, info.uri, strlen(path))==0);                                          info.uri && strncmp(path, info.uri, strlen(path))==0);
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_FEXISTS:                  case OP_FEXISTS:
                         {                          {
                                 Value* operand=stack.pop().value;                                  Value *operand=POP();
                                 value=NEW VBool(pool(),                                   value=NEW VBool(pool(), 
                                         file_readable(absolute(operand->as_string())));                                          file_readable(absolute(operand->as_string())));
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_DEXISTS:                  case OP_DEXISTS:
                         {                          {
                                 Value* operand=stack.pop().value;                                  Value *operand=POP();
                                 value=NEW VBool(pool(),                                   value=NEW VBool(pool(), 
                                         dir_readable(absolute(operand->as_string())));                                          dir_readable(absolute(operand->as_string())));
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
   
                 // expression ops: binary                  // expression ops: binary
                 case OP_SUB:                   case OP_SUB: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VDouble(pool(), a->as_double() - b->as_double());                                  value=NEW VDouble(pool(), a->as_double() - b->as_double());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_ADD:                   case OP_ADD: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VDouble(pool(), a->as_double() + b->as_double());                                  value=NEW VDouble(pool(), a->as_double() + b->as_double());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_MUL:                   case OP_MUL: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VDouble(pool(), a->as_double() * b->as_double());                                  value=NEW VDouble(pool(), a->as_double() * b->as_double());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_DIV:                   case OP_DIV: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
   
                                 double a_double=a->as_double();                                  double a_double=a->as_double();
                                 double b_double=b->as_double();                                  double b_double=b->as_double();
Line 611  void Request::execute(ArrayOperation& op Line 603  void Request::execute(ArrayOperation& op
                                 }                                  }
   
                                 value=NEW VDouble(pool(), a_double / b_double);                                  value=NEW VDouble(pool(), a_double / b_double);
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_MOD:                   case OP_MOD: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
   
                                 double a_double=a->as_double();                                  double a_double=a->as_double();
                                 double b_double=b->as_double();                                  double b_double=b->as_double();
Line 629  void Request::execute(ArrayOperation& op Line 621  void Request::execute(ArrayOperation& op
                                 }                                  }
   
                                 value=NEW VDouble(pool(), fmod(a_double, b_double));                                  value=NEW VDouble(pool(), fmod(a_double, b_double));
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_INTDIV:                  case OP_INTDIV:
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
   
                                 int a_int=a->as_int();                                  int a_int=a->as_int();
                                 int b_int=b->as_int();                                  int b_int=b->as_int();
Line 647  void Request::execute(ArrayOperation& op Line 639  void Request::execute(ArrayOperation& op
                                 }                                  }
   
                                 value=NEW VInt(pool(), a_int / b_int);                                  value=NEW VInt(pool(), a_int / b_int);
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_BIN_SL:                  case OP_BIN_SL:
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VInt(pool(),                                   value=NEW VInt(pool(), 
                                         a->as_int() <<                                          a->as_int() <<
                                         b->as_int());                                          b->as_int());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_BIN_SR:                  case OP_BIN_SR:
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VInt(pool(),                                   value=NEW VInt(pool(), 
                                         a->as_int() >>                                          a->as_int() >>
                                         b->as_int());                                          b->as_int());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_BIN_AND:                  case OP_BIN_AND:
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VInt(pool(),                                   value=NEW VInt(pool(), 
                                         a->as_int() &                                          a->as_int() &
                                         b->as_int());                                          b->as_int());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_BIN_OR:                  case OP_BIN_OR:
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VInt(pool(),                                   value=NEW VInt(pool(), 
                                         a->as_int() |                                          a->as_int() |
                                         b->as_int());                                          b->as_int());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_BIN_XOR:                  case OP_BIN_XOR:
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VInt(pool(),                                   value=NEW VInt(pool(), 
                                         a->as_int() ^                                          a->as_int() ^
                                         b->as_int());                                          b->as_int());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_LOG_AND:                  case OP_LOG_AND:
                         {                          {
                                 b_code=POP_CODE();  a=stack.pop().value;                                  b_code=POP_CODE();  a=POP();
                                 bool result;                                  bool result;
                                 if(a->as_bool()) {                                  if(a->as_bool()) {
                                         execute(*b_code);                                          execute(*b_code);
                                         b=stack.pop().value;                                          b=POP();
                                         result=b->as_bool();                                          result=b->as_bool();
                                 } else                                  } else
                                         result=false;                                          result=false;
                                 value=NEW VBool(pool(), result);                                  value=NEW VBool(pool(), result);
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_LOG_OR:                  case OP_LOG_OR:
                         {                          {
                                 b_code=POP_CODE();  a=stack.pop().value;                                  b_code=POP_CODE();  a=POP();
                                 bool result;                                  bool result;
                                 if(a->as_bool())                                   if(a->as_bool()) 
                                         result=true;                                          result=true;
                                 else {                                  else {
                                         execute(*b_code);                                          execute(*b_code);
                                         b=stack.pop().value;                                          b=POP();
                                         result=b->as_bool();                                          result=b->as_bool();
                                 }                                  }
                                 value=NEW VBool(pool(), result);                                  value=NEW VBool(pool(), result);
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_LOG_XOR:                  case OP_LOG_XOR:
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VBool(pool(), a->as_bool() ^ b->as_bool());                                  value=NEW VBool(pool(), a->as_bool() ^ b->as_bool());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_NUM_LT:                   case OP_NUM_LT: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 double result=a->as_double() - b->as_double();                                  volatile double a_double=a->as_double(); 
                                 value=NEW VBool(pool(), result < 0.0);                                  volatile double b_double=b->as_double();
                                 stack.push(value);                                  value=NEW VBool(pool(), a_double<b_double);
                                   PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_NUM_GT:                   case OP_NUM_GT: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 double result=a->as_double() - b->as_double();                                  volatile double a_double=a->as_double(); 
                                 value=NEW VBool(pool(), result > 0.0);                                  volatile double b_double=b->as_double();
                                 stack.push(value);                                  value=NEW VBool(pool(), a_double>b_double);
                                   PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_NUM_LE:                   case OP_NUM_LE: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 double result=a->as_double() - b->as_double();                                  volatile double a_double=a->as_double(); 
                                 value=NEW VBool(pool(), result <= 0.0);                                  volatile double b_double=b->as_double();
                                 stack.push(value);                                  value=NEW VBool(pool(), a_double<=b_double);
                                   PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_NUM_GE:                   case OP_NUM_GE: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 double result=a->as_double() - b->as_double();                                  volatile double a_double=a->as_double(); 
                                 value=NEW VBool(pool(), result >= 0.0);                                  volatile double b_double=b->as_double();
                                 stack.push(value);                                  value=NEW VBool(pool(), a_double>=b_double);
                                   PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_NUM_EQ:                   case OP_NUM_EQ: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 double result=a->as_double() - b->as_double();                                  volatile double a_double=a->as_double(); 
                                 value=NEW VBool(pool(), result == 0.0);                                  volatile double b_double=b->as_double();
                                 stack.push(value);                                  value=NEW VBool(pool(), a_double==b_double);
                                   PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_NUM_NE:                   case OP_NUM_NE: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 double result=a->as_double() - b->as_double();                                  volatile double a_double=a->as_double(); 
                                 value=NEW VBool(pool(), result != 0.0);                                  volatile double b_double=b->as_double();
                                 stack.push(value);                                  value=NEW VBool(pool(), a_double!=b_double);
                                   PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_STR_LT:                   case OP_STR_LT: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VBool(pool(), a->as_string() < b->as_string());                                  value=NEW VBool(pool(), a->as_string() < b->as_string());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_STR_GT:                   case OP_STR_GT: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VBool(pool(), a->as_string() > b->as_string());                                  value=NEW VBool(pool(), a->as_string() > b->as_string());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_STR_LE:                   case OP_STR_LE: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VBool(pool(), a->as_string() <= b->as_string());                                  value=NEW VBool(pool(), a->as_string() <= b->as_string());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_STR_GE:                   case OP_STR_GE: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VBool(pool(), a->as_string() >= b->as_string());                                  value=NEW VBool(pool(), a->as_string() >= b->as_string());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_STR_EQ:                   case OP_STR_EQ: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VBool(pool(), a->as_string() == b->as_string());                                  value=NEW VBool(pool(), a->as_string() == b->as_string());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_STR_NE:                   case OP_STR_NE: 
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VBool(pool(), a->as_string() != b->as_string());                                  value=NEW VBool(pool(), a->as_string() != b->as_string());
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
                 case OP_IS:                  case OP_IS:
                         {                          {
                                 b=stack.pop().value;  a=stack.pop().value;                                  b=POP();  a=POP();
                                 value=NEW VBool(pool(), a->is(b->as_string().cstr()));                                  value=NEW VBool(pool(), a->is(b->as_string().cstr()));
                                 stack.push(value);                                  PUSH(value);
                                 break;                                  break;
                         }                          }
   
Line 841  void Request::execute(ArrayOperation& op Line 839  void Request::execute(ArrayOperation& op
         @todo cache|prepare junctions          @todo cache|prepare junctions
         @bug ^superbase:method would dynamically call ^base:method if there is any          @bug ^superbase:method would dynamically call ^base:method if there is any
 */  */
 Value* Request::get_element(const String *& remember_name, bool can_call_operator) {  Value *Request::get_element(const String *& remember_name, bool can_call_operator) {
         String* name=stack.pop().string;  remember_name=&name;          const String& name=POP_NAME();  remember_name=&name;
         Value* ncontext=stack.pop().value;          Value *ncontext=POP();
         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
                         Junction& junction=*NEW Junction(pool(),                           Junction& junction=*NEW Junction(pool(), 
Line 858  Value* Request::get_element(const String Line 856  Value* Request::get_element(const String
                         if(VStateless_class *called_class=ncontext->get_class())                          if(VStateless_class *called_class=ncontext->get_class())
                                 if(VStateless_class *read_class=rcontext->get_class())                                  if(VStateless_class *read_class=rcontext->get_class())
                                         if(read_class->derived_from(*called_class)) // current derived from called                                          if(read_class->derived_from(*called_class)) // current derived from called
                                                 if(Value* base=get_self()->base()) { // doing DYNAMIC call                                                  if(Value *base=get_self()->base()) { // doing DYNAMIC call
                                                         Temp_derived temp_derived(*base, 0); // temporarily prevent go-back-down virtual calls                                                          Temp_derived temp_derived(*base, 0); // temporarily prevent go-back-down virtual calls
                                                         value=base->get_element(name, *base, false); // virtual-up lookup starting from parent                                                          value=base->get_element(name, *base, false); // virtual-up lookup starting from parent
                                                         goto value_ready;                                                          goto value_ready;
Line 910  StringOrValue Request::process(Value& in Line 908  StringOrValue Request::process(Value& in
                                 "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;
Line 959  StringOrValue Request::process(Value& in Line 957  StringOrValue Request::process(Value& in
   
 const String& Request::execute_method(VMethodFrame& amethod_frame, const Method& method) {  const String& Request::execute_method(VMethodFrame& amethod_frame, const Method& method) {
         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;
                   
         // initialize contexts          // initialize contexts
Line 983  void Request::execute_method(Value& asel Line 981  void Request::execute_method(Value& asel
                                                          const Method& method, VString *optional_param,                                                           const Method& method, VString *optional_param,
                                                          const String **return_string) {                                                           const String **return_string) {
         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;
                   
         Junction local_junction(pool(), aself, &method, 0,0,0,0);          Junction local_junction(pool(), aself, &method, 0,0,0,0);
Line 1013  void Request::execute_method(Value& asel Line 1011  void Request::execute_method(Value& asel
 }  }
   
 void Request::execute_nonvirtual_method(VStateless_class& aclass,   void Request::execute_nonvirtual_method(VStateless_class& aclass, 
                                                                                                  StringPtr method_name, VStringPtr optional_param,                                                                                                   const String& method_name, VString *optional_param,
                                                                                                  const String **return_string,                                                                                                   const String **return_string,
                                                                                                  const Method **return_method) {                                                                                                   const Method **return_method) {
   
Line 1027  void Request::execute_nonvirtual_method( Line 1025  void Request::execute_nonvirtual_method(
                 execute_method(aclass, *method, optional_param, return_string);                  execute_method(aclass, *method, optional_param, return_string);
 }  }
   
 StringPtr Request::execute_virtual_method(Value& aself,   const String *Request::execute_virtual_method(Value& aself, 
                                                                                           StringPtr method_name) {                                                                                            const String& method_name) {
         if(Value* value=aself.get_element(method_name, aself, false))          if(Value *value=aself.get_element(method_name, aself, false))
                 if(Junction *junction=value->get_junction())                  if(Junction *junction=value->get_junction())
                         if(const Method *method=junction->method) {                          if(const Method *method=junction->method) {
                                 const String *result;                                  const String *result;

Removed from v.1.295.2.6  
changed lines
  Added in v.1.296


E-mail: