예제 #1
0
QoreValue QoreValueList::takeExists(ptrdiff_t offset) {
   QoreValue* ptr = getExistingEntryPtr(offset);
   if (!ptr)
      return QoreValue();
   QoreValue rv = *ptr;
   *ptr = QoreValue();
   return rv;
}
QoreValue QoreShiftLeftEqualsOperatorNode::evalValueImpl(bool& needs_deref, ExceptionSink* xsink) const {
   int64 val = right->bigIntEval(xsink);
   if (*xsink)
      return QoreValue();

   // get ptr to current value (lvalue is locked for the scope of the LValueHelper object)
   LValueHelper v(left, xsink);
   if (!v)
      return QoreValue();
   return v.shiftLeftEqualsBigInt(val, "<<= operator>");
}
예제 #3
0
// evalImpl(): return value requires a deref(xsink) if not 0
QoreValue CallReferenceCallNode::evalValueImpl(bool& needs_deref, ExceptionSink* xsink) const {
   ReferenceHolder<AbstractQoreNode> lv(exp->eval(xsink), xsink);
   if (*xsink)
      return QoreValue();

   ResolvedCallReferenceNode* r = dynamic_cast<ResolvedCallReferenceNode*>(*lv);
   if (!r) {
      xsink->raiseException("REFERENCE-CALL-ERROR", "expression does not evaluate to a call reference (evaluated to type '%s')", lv ? lv->getTypeName() : "NOTHING"); 
      return QoreValue();
   }
   return r->execValue(args, xsink);
}
예제 #4
0
QoreValue QoreModulaOperatorNode::evalValueImpl(bool& needs_deref, ExceptionSink* xsink) const {
   int64 l = left->bigIntEval(xsink);
   if (*xsink)
      return QoreValue();
   int64 r = right->bigIntEval(xsink);
   if (*xsink)
      return QoreValue();
   if (!r) {
      xsink->raiseException("DIVISION-BY-ZERO", "modula operand cannot be zero ("QLLD" %% "QLLD" attempted)", l, r);
      return QoreValue();
   }
   return l % r;
}
예제 #5
0
QoreValue QoreValueList::minValue(ExceptionSink* xsink) const {
   if (!priv->length)
      return QoreValue();
   QoreValue rv = priv->entry[0];

   for (size_t i = 1; i < priv->length; ++i) {
      QoreValue v = priv->entry[i];
      if (QoreLogicalLessThanOperatorNode::doLessThan(v, rv, xsink))
	 rv = v;
      if (*xsink)
	 return QoreValue();
   }
   return rv.refSelf();
}
예제 #6
0
QoreValue QoreValueList::pop() {
   assert(reference_count() == 1);
   if (!priv->length)
      return QoreValue();
   QoreValue& rv = priv->entry[priv->length - 1];
   size_t pos = priv->length - 1;
   priv->entry[pos] = QoreValue();
   priv->resize(pos);

   if (rv.hasNode() && get_container_obj(rv.getInternalNode()))
      priv->incObjectCount(-1);

   return rv;
}
예제 #7
0
QoreValue VarRefNewObjectNode::evalValueImpl(bool& needs_deref, ExceptionSink* xsink) const {
   assert(typeInfo->getUniqueReturnClass());
   ReferenceHolder<QoreObject> obj(qore_class_private::execConstructor(*typeInfo->getUniqueReturnClass(), variant, args, xsink), xsink);
   if (*xsink)
      return QoreValue();

   QoreObject* rv = *obj;
   LValueHelper lv(this, xsink);
   if (!lv)
      return QoreValue();
   lv.assign(obj.release());
   if (*xsink)
      return QoreValue();
   return QoreValue(rv->refSelf());
}
QoreValue QorePreIncrementOperatorNode::evalValueImpl(bool& needs_deref, ExceptionSink* xsink) const {
   // get ptr to current value (lvalue is locked for the scope of the LValueHelper object)
   LValueHelper n(exp, xsink);
   if (!n)
      return QoreValue();
   if (n.getType() == NT_NUMBER) {
      n.preIncrementNumber("<++ (pre) operator>");
      assert(!*xsink);
   }
   else if (n.getType() == NT_FLOAT)
      return n.preIncrementFloat("<++ (pre) operator>");
   else
      return n.preIncrementBigInt("<++ (pre) operator>");

   return *xsink || !ref_rv ? QoreValue() : n.getReferencedValue();
}
예제 #9
0
// returns a RunTimeObjectMethodReference or NULL if there's an exception
QoreValue ParseObjectMethodReferenceNode::evalValueImpl(bool& needs_deref, ExceptionSink* xsink) const {
   // evaluate lvalue expression
   ReferenceHolder<AbstractQoreNode> lv(exp->eval(xsink), xsink);
   if (*xsink)
      return QoreValue();

   QoreObject* o = (*lv) && (*lv)->getType() == NT_OBJECT ? reinterpret_cast<QoreObject*>(*lv) : 0;
   if (!o) {
      xsink->raiseException("OBJECT-METHOD-REFERENCE-ERROR", "expression does not evaluate to an object");
      return QoreValue();
   }

   //printd(5, "ParseObjectMethodReferenceNode::evalImpl() this: %p o: %p %s::%s() m: %p\n", this, o, o->getClassName(), method.c_str(), m);

   const QoreClass* oc = o->getClass();

   // find the method at runtime if necessary
   if (!m) {
      // serialize method resolution at runtime
      AutoLocker al(lck);
      // check m again inside the lock (this way we avoid the lock in the common case where the method has already been resolved)
      if (!m) {
	 bool m_priv = false;
	 m = oc->findMethod(method.c_str(), m_priv);
	 if (!m) {
	    m = oc->findStaticMethod(method.c_str(), m_priv);
	    if (!m) {
	       xsink->raiseException("OBJECT-METHOD-REFERENCE-ERROR", "cannot resolve reference to %s::%s(): unknown method", o->getClassName(), method.c_str());
	       return QoreValue();
	    }
	 }
	 
	 if (m_priv && !qore_class_private::runtimeCheckPrivateClassAccess(*oc)) {
	    if (m->isPrivate())
	       xsink->raiseException("ILLEGAL-CALL-REFERENCE", "cannot create a call reference to private %s::%s() from outside the class", o->getClassName(), method.c_str());
	    else
	       xsink->raiseException("ILLEGAL-CALL-REFERENCE", "cannot create a call reference to %s::%s() because the parent class that implements the method (%s::%s()) is privately inherited", o->getClassName(), method.c_str(), m->getClass()->getName(), method.c_str());
	    
	    return QoreValue();
	 }
      }
   }

   if (oc == m->getClass() || oc == qc)
      return new RunTimeResolvedMethodReferenceNode(o, m);
   return new RunTimeObjectMethodReferenceNode(o, method.c_str());
}
예제 #10
0
QoreValue QoreValueList::maxValue(const ResolvedCallReferenceNode* fr, ExceptionSink* xsink) const {
   if (!priv->length)
      return QoreValue();
   QoreValue rv = priv->entry[0];

   for (size_t i = 1; i < priv->length; ++i) {
      QoreValue v = priv->entry[i];

      safe_qorelist_t args(do_args(v, rv), xsink);
      ValueHolder result(fr->execValue(*args, xsink), xsink);
      if (*xsink)
	 return QoreValue();
      if (result->getAsBigInt() > 0)
	 rv = v;
   }
   return rv.refSelf();
}
예제 #11
0
QoreValue QoreProgram::getGlobalVariableVal(const char* var, bool& found) const {
   const qore_ns_private* vns = 0;
   Var* v = qore_root_ns_private::runtimeFindGlobalVar(*(priv->RootNS), var, vns);
   if (!v) {
      found = false;
      return QoreValue();
   }
   found = true;   
   return v->eval();
}
QoreValue QoreAssignmentOperatorNode::evalValueImpl(bool& needs_deref, ExceptionSink* xsink) const {
   /* assign new value, this value gets referenced with the
      eval(xsink) call, so there's no need to reference it again
      for the variable assignment - however it does need to be
      copied/referenced for the return value
   */
   ValueEvalRefHolder new_value(right, xsink);
   if (*xsink)
      return QoreValue();

   // get ptr to current value (lvalue is locked for the scope of the LValueHelper object)
   LValueHelper v(left, xsink);
   if (!v)
      return QoreValue();

   // assign new value
   if (v.assign(new_value.takeReferencedValue()))
      return QoreValue();

   // reference return value if necessary
   return ref_rv ? v.getReferencedValue() : QoreValue();
}
예제 #13
0
QoreValue QoreHashMapOperatorNode::mapIterator(AbstractIteratorHelper& h, ExceptionSink* xsink) const {
   ReferenceHolder<QoreHashNode> rv(ref_rv ? new QoreHashNode : 0, xsink);

   qore_size_t i = 0;
   // set offset in thread-local data for "$#"
   while (true) {
      bool has_next = h.next(xsink);
      if (*xsink)
         return QoreValue();
      if (!has_next)
	 break;

      ImplicitElementHelper eh(i++);

      ReferenceHolder<> iv(h.getValue(xsink), xsink);
      if (*xsink)
         return QoreValue();

      // check if value can be mapped
      SingleArgvContextHelper argv_helper(*iv, xsink);

      {
	 ValueEvalRefHolder ekey(e[0], xsink);
	 if (*xsink)
	    return QoreValue();
	 
	 // we have to convert to a string in the default encoding to use a hash key
	 QoreStringValueHelper key(*ekey, QCS_DEFAULT, xsink);
	 if (*xsink)
	    return QoreValue();
	 
	 ValueEvalRefHolder val(e[1], xsink);
	 if (*xsink)
	    return QoreValue();
	 
	 if (ref_rv)
	    rv->setKeyValue(key->getBuffer(), val.getReferencedValue(), xsink);
      }
      // if there is an exception dereferencing one of the evaluted nodes above, then exit the loop
      if (*xsink)
	 return QoreValue();
   }
   
   return rv.release();
}
예제 #14
0
QoreValue QoreDotEvalOperatorNode::evalValueImpl(bool& needs_deref, ExceptionSink* xsink) const {
   ValueEvalRefHolder op(left, xsink);
   if (*xsink)
      return QoreValue();

   if (op->getType() == NT_HASH) {
      const AbstractQoreNode* ref = check_call_ref(op->getInternalNode(), m->getName());
      if (ref)
	 return reinterpret_cast<const ResolvedCallReferenceNode*>(ref)->execValue(m->getArgs(), xsink);
   }

   if (op->getType() != NT_OBJECT) {
      // FIXME: inefficient
      ReferenceHolder<> nop(op.getReferencedValue(), xsink);
      if (m->isPseudo())
	 return m->execPseudo(*nop, xsink);

      return pseudo_classes_eval(*nop, m->getName(), m->getArgs(), xsink);
   }

   QoreObject* o = const_cast<QoreObject*>(reinterpret_cast<const QoreObject*>(op->getInternalNode()));
   // FIXME: inefficient
   return m->exec(o, xsink);
}
QoreValue QoreDivideEqualsOperatorNode::evalValueImpl(bool& needs_deref, ExceptionSink* xsink) const {
   ValueEvalRefHolder res(right, xsink);
   if (*xsink)
      return QoreValue();

   // get ptr to current value (lvalue is locked for the scope of the LValueHelper object)
   LValueHelper v(left, xsink);
   if (!v)
      return QoreValue();

   // is either side a number?
   if (res->getType() == NT_NUMBER || v.getType() == NT_NUMBER) {
      // check for divide by zero
      if (res->getAsFloat() == 0.0) {
	 xsink->raiseException("DIVISION-BY-ZERO", "division by zero in arbitrary-precision numeric expression");
	 return QoreValue();
      }
      // FIXME: efficiency
      ReferenceHolder<> rh(res.getReferencedValue(), xsink);
      v.divideEqualsNumber(*rh, "</= operator>");
   }
   // is either side a float?
   else if (res->getType() == NT_FLOAT || v.getType() == NT_FLOAT) {
      double val = res->getAsFloat();
      if (val == 0.0) {
	 xsink->raiseException("DIVISION-BY-ZERO", "division by zero in floating-point expression");
	 return QoreValue();
      }
      return v.divideEqualsFloat(val, "</= operator>");
   }
   else { // do integer divide equals
      int64 val = res->getAsBigInt();
      if (!val) {
	 xsink->raiseException("DIVISION-BY-ZERO", "division by zero in integer expression");
	 return QoreValue();
      }
      // get new value if necessary
      return v.divideEqualsBigInt(val, "</= operator>");
   }

   // reference return value and return
   return ref_rv ? v.getReferencedValue() : QoreValue();
}
예제 #16
0
QoreValue QoreValueList::retrieveEntry(size_t num) {
   if (num >= priv->length)
      return QoreValue();
   return priv->entry[num];
}
예제 #17
0
QoreValue MethodCallReferenceNode::execValue(const QoreListNode* args, ExceptionSink* xsink) const {
   ProgramThreadCountContextHelper tch(xsink, pgm, true);
   if (*xsink)
      return QoreValue();
   return qore_method_private::eval(*method, runtime_get_stack_object(), args, xsink);
}
예제 #18
0
QoreValue QoreValueList::getReferencedEntry(size_t num) const {
   if (num >= priv->length)
      return QoreValue();
   return priv->entry[num].refSelf();
}
예제 #19
0
QoreValue QoreHashMapOperatorNode::evalValueImpl(bool& needs_deref, ExceptionSink* xsink) const {
   ValueEvalRefHolder arg_lst(e[2], xsink);
   if (*xsink || arg_lst->isNothing())
      return QoreValue();
   
   qore_type_t arglst_type = arg_lst->getType();
   assert(arglst_type != NT_NOTHING);
   ReferenceHolder<QoreHashNode> ret_val(ref_rv ? new QoreHashNode : 0, xsink);
   if (NT_LIST != arglst_type) { // Single value
      // check if it's an AbstractIterator object
      if (NT_OBJECT == arglst_type) {
         AbstractIteratorHelper h(xsink, "hmap operator select", 
				  const_cast<QoreObject*>(arg_lst->get<const QoreObject>()));
         if (*xsink)
	    return QoreValue();
         if (h)
            return mapIterator(h, xsink); // TODO!!
	 // passed iterator
      }

      // check if value can be mapped
      ReferenceHolder<> arg_ival(arg_lst.getReferencedValue(), xsink);
      SingleArgvContextHelper argv_helper(*arg_ival, xsink);
      ValueEvalRefHolder arg_key(e[0], xsink);
      if (*xsink)
	 return QoreValue();

      ValueEvalRefHolder arg_val(e[1], xsink);
      if (*xsink)
	 return QoreValue();

      // we have to convert to a string in the default encoding to use a hash key
      QoreStringValueHelper str_util(*arg_key, QCS_DEFAULT, xsink);
      if (*xsink)
	 return QoreValue();
      
      // Insert key-Value pair to the hash
      ret_val->setKeyValue(str_util->getBuffer(), arg_val.getReferencedValue(), xsink);
   }
   else {// List of values
      ConstListIterator li(arg_lst->get<const QoreListNode>());
      while (li.next()) {
         // set offset in thread-local data for "$#"
         ImplicitElementHelper eh(li.index()); 
         SingleArgvContextHelper argv_helper(li.getValue(), xsink);

	 {
	    ValueEvalRefHolder ekey(e[0], xsink);
	    if (*xsink)
	       return QoreValue();

	    // we have to convert to a string in the default encoding to use a hash key
	    QoreStringValueHelper key(*ekey, QCS_DEFAULT, xsink);
	    if (*xsink)
	       return QoreValue();
	    
	    ValueEvalRefHolder val(e[1], xsink);
	    if (*xsink)
	       return QoreValue();

	    if (ref_rv)
	       ret_val->setKeyValue(key->getBuffer(), val.getReferencedValue(), xsink);
	 }
	 // if there is an exception dereferencing one of the evaluted nodes above, then exit the loop
	 if (*xsink)
	    return QoreValue();
      }
   }
   if (*xsink || !ref_rv)
      return QoreValue();

   return ret_val.release();
}