示例#1
0
	void entry::print(std::ostream& os, int indent) const
	{
		LIBED2K_ASSERT(indent >= 0);
		for (int i = 0; i < indent; ++i) os << " ";
		switch (m_type)
		{
		case int_t:
			os << integer() << "\n";
			break;
		case string_t:
			{
				bool binary_string = false;
				for (std::string::const_iterator i = string().begin(); i != string().end(); ++i)
				{
					if (!is_print(static_cast<unsigned char>(*i)))
					{
						binary_string = true;
						break;
					}
				}
				if (binary_string) os << to_hex(string()) << "\n";
				else os << string() << "\n";
			} break;
		case list_t:
			{
				os << "list\n";
				for (list_type::const_iterator i = list().begin(); i != list().end(); ++i)
				{
					i->print(os, indent+1);
				}
			} break;
		case dictionary_t:
			{
				os << "dictionary\n";
				for (dictionary_type::const_iterator i = dict().begin(); i != dict().end(); ++i)
				{
					bool binary_string = false;
					for (std::string::const_iterator k = i->first.begin(); k != i->first.end(); ++k)
					{
						if (!is_print(static_cast<unsigned char>(*k)))
						{
							binary_string = true;
							break;
						}
					}
					for (int j = 0; j < indent+1; ++j) os << " ";
					os << "[";
					if (binary_string) os << to_hex(i->first);
					else os << i->first;
					os << "]";

					if (i->second.type() != entry::string_t
						&& i->second.type() != entry::int_t)
						os << "\n";
					else os << " ";
					i->second.print(os, indent+2);
				}
			} break;
		default:
			os << "<uninitialized>\n";
		}
	}
示例#2
0
	entry* entry::find_key(char const* key)
	{
		dictionary_type::iterator i = dict().find(key);
		if (i == dict().end()) return 0;
		return &i->second;
	}
示例#3
0
	entry const* entry::find_key(std::string const& key) const
	{
		dictionary_type::const_iterator i = dict().find(key);
		if (i == dict().end()) return 0;
		return &i->second;
	}
DEF_TEST(PDFPrimitives, reporter) {
    SkAutoTUnref<SkPDFInt> int42(new SkPDFInt(42));
    SimpleCheckObjectOutput(reporter, int42.get(), "42");

    SkAutoTUnref<SkPDFScalar> realHalf(new SkPDFScalar(SK_ScalarHalf));
    SimpleCheckObjectOutput(reporter, realHalf.get(), "0.5");

#if defined(SK_SCALAR_IS_FLOAT)
    SkAutoTUnref<SkPDFScalar> bigScalar(new SkPDFScalar(110999.75f));
#if !defined(SK_ALLOW_LARGE_PDF_SCALARS)
    SimpleCheckObjectOutput(reporter, bigScalar.get(), "111000");
#else
    SimpleCheckObjectOutput(reporter, bigScalar.get(), "110999.75");

    SkAutoTUnref<SkPDFScalar> biggerScalar(new SkPDFScalar(50000000.1));
    SimpleCheckObjectOutput(reporter, biggerScalar.get(), "50000000");

    SkAutoTUnref<SkPDFScalar> smallestScalar(new SkPDFScalar(1.0/65536));
    SimpleCheckObjectOutput(reporter, smallestScalar.get(), "0.00001526");
#endif
#endif

    SkAutoTUnref<SkPDFString> stringSimple(
        new SkPDFString("test ) string ( foo"));
    SimpleCheckObjectOutput(reporter, stringSimple.get(),
                            "(test \\) string \\( foo)");
    SkAutoTUnref<SkPDFString> stringComplex(
        new SkPDFString("\ttest ) string ( foo"));
    SimpleCheckObjectOutput(reporter, stringComplex.get(),
                            "<0974657374202920737472696E67202820666F6F>");

    SkAutoTUnref<SkPDFName> name(new SkPDFName("Test name\twith#tab"));
    const char expectedResult[] = "/Test#20name#09with#23tab";
    CheckObjectOutput(reporter, name.get(), expectedResult,
                      strlen(expectedResult), false, false);

    SkAutoTUnref<SkPDFName> escapedName(new SkPDFName("A#/%()<>[]{}B"));
    const char escapedNameExpected[] = "/A#23#2F#25#28#29#3C#3E#5B#5D#7B#7DB";
    CheckObjectOutput(reporter, escapedName.get(), escapedNameExpected,
                      strlen(escapedNameExpected), false, false);

    // Test that we correctly handle characters with the high-bit set.
    const unsigned char highBitCString[] = {0xDE, 0xAD, 'b', 'e', 0xEF, 0};
    SkAutoTUnref<SkPDFName> highBitName(
        new SkPDFName((const char*)highBitCString));
    const char highBitExpectedResult[] = "/#DE#ADbe#EF";
    CheckObjectOutput(reporter, highBitName.get(), highBitExpectedResult,
                      strlen(highBitExpectedResult), false, false);

    SkAutoTUnref<SkPDFArray> array(new SkPDFArray);
    SimpleCheckObjectOutput(reporter, array.get(), "[]");
    array->append(int42.get());
    SimpleCheckObjectOutput(reporter, array.get(), "[42]");
    array->append(realHalf.get());
    SimpleCheckObjectOutput(reporter, array.get(), "[42 0.5]");
    SkAutoTUnref<SkPDFInt> int0(new SkPDFInt(0));
    array->append(int0.get());
    SimpleCheckObjectOutput(reporter, array.get(), "[42 0.5 0]");
    SkAutoTUnref<SkPDFInt> int1(new SkPDFInt(1));
    array->setAt(0, int1.get());
    SimpleCheckObjectOutput(reporter, array.get(), "[1 0.5 0]");

    SkAutoTUnref<SkPDFDict> dict(new SkPDFDict);
    SimpleCheckObjectOutput(reporter, dict.get(), "<<>>");
    SkAutoTUnref<SkPDFName> n1(new SkPDFName("n1"));
    dict->insert(n1.get(), int42.get());
    SimpleCheckObjectOutput(reporter, dict.get(), "<</n1 42\n>>");
    SkAutoTUnref<SkPDFName> n2(new SkPDFName("n2"));
    SkAutoTUnref<SkPDFName> n3(new SkPDFName("n3"));
    dict->insert(n2.get(), realHalf.get());
    dict->insert(n3.get(), array.get());
    SimpleCheckObjectOutput(reporter, dict.get(),
                            "<</n1 42\n/n2 0.5\n/n3 [1 0.5 0]\n>>");

    TestPDFStream(reporter);

    TestCatalog(reporter);

    TestObjectRef(reporter);

    TestSubstitute(reporter);

    test_issue1083();

    TestImages(reporter);
}
std::tuple<std::vector<std::string>, array_type, array_type>
gen_features(
    const std::vector<std::string> & i_colnames,
    const array_type & i_train_data,
    const array_type & i_test_data)
{
    typedef std::valarray<real_type> varray_type;

    /*
     * generate feature vector across all groups for a single attribute column
     */
    auto gen_attribute = [&i_colnames](GroupBy & gb, const array_type & arr, const std::string & colname) -> varray_type
    {
        const std::size_t cix = colidx(i_colnames, colname);
        varray_type vec(NAN, gb.size());

        std::size_t vix{0};
        for (auto group = gb.yield(); group.size() != 0; group = gb.yield())
        {
            const varray_type row = arr[arr.row(group.front())];
            vec[vix++] = row[cix];
        }

        gb.rewind();

        return vec;
    };

    auto gen_attributes = [&i_colnames, &gen_attribute](GroupBy & gb, const array_type & arr, const std::vector<std::string> & att_names) -> array_type
    {
        const varray_type att1 = gen_attribute(gb, arr, att_names.front());
        array_type result({att1.size(), 1}, att1);

        for (auto it = std::next(att_names.cbegin()); it != att_names.cend(); ++it)
        {
            const varray_type att = gen_attribute(gb, arr, *it);
            result = num::add_column(result, att);
        }
        return result;
    };


    const std::vector<std::string> att_names{"PRODUCT_CLASS_ID1", "BRAND", "PRODUCT_SALES_UNIT", "PRODUCT_UNIT_OF_MEASURE"};

    ////////////////////////////////////////////////////////////////////////////

    GroupBy gb_train(i_train_data);

    array_type train_data = gen_attributes(gb_train, i_train_data, att_names);

    std::vector<std::string> colnames;
    std::copy(att_names.cbegin(), att_names.cend(), std::back_inserter(colnames));

    ////////////////////////////////////////////////////////////////////////////

    GroupBy gb_test(i_test_data);

    array_type test_data = gen_attributes(gb_test, i_test_data, att_names);

    ////////////////////////////////////////////////////////////////////////////

    auto gen_distribution = [&i_colnames](GroupBy & gb, const array_type & arr, const std::string & colname, const int dict_sz, const int offset) -> array_type
    {
        const std::size_t cix = colidx(i_colnames, colname);

        array_type result({gb.size(), dict_sz}, 0.);

        std::size_t gbix{0};
        for (auto group = gb.yield(); group.size() != 0; group = gb.yield())
        {
            varray_type dict(0., dict_sz);

            for (const auto rix : group)
            {
                const int item = arr[arr.row(rix)][cix] - offset;
                assert(0 <= item && item < dict_sz);

                ++dict[item];
            }

            dict /= dict.sum();
            result[result.row(gbix++)] = dict;
        }

        gb.rewind();

        return result;
    };

    const std::tuple<std::string, int, int> dist_db[] =
        {
            std::make_tuple("PRICE_METHOD", 5, 1),
            std::make_tuple("ORDER_SOURCE", 2, 0),
            std::make_tuple("CUSTOMER_ACCOUNT_TYPE", 2, 0),
            std::make_tuple("CUSTOMER_MANAGED_LEVEL", 2, 0),
            std::make_tuple("CUSTOMER_TYPE2", 3, 0),
            std::make_tuple("CUSTOMER_TYPE1", 3, 1),
        };

    for (const auto & descriptor : dist_db)
    {
        const auto dist = gen_distribution(gb_train, i_train_data,
            std::get<0>(descriptor),
            std::get<1>(descriptor),
            std::get<2>(descriptor));
        train_data = num::add_columns(train_data, dist);
    }

    for (const auto & descriptor : dist_db)
    {
        const auto dist = gen_distribution(gb_test, i_test_data,
            std::get<0>(descriptor),
            std::get<1>(descriptor),
            std::get<2>(descriptor));
        test_data = num::add_columns(test_data, dist);
    }

    for (const auto & descriptor : dist_db)
    {
        for (int ix{0}; ix < std::get<1>(descriptor); ++ix)
        {
            colnames.push_back(std::get<0>(descriptor) + '_' + std::to_string(ix + 1));
        }
    }

    ////////////////////////////////////////////////////////////////////////////

    auto min_max_std = [&i_colnames](GroupBy & gb, const array_type & arr) -> array_type
    {
        const std::size_t pcost1_cix = colidx(i_colnames, "PRODUCT_COST1");
        const std::size_t boxes_cix = colidx(i_colnames, "TOTAL_BOXES_SOLD");
        const std::size_t price_cix = colidx(i_colnames, "PRODUCT_PRICE");
        const std::size_t gross_cix = colidx(i_colnames, "GROSS_SALES");
        const std::size_t unit_cix = colidx(i_colnames, "PRODUCT_UNIT_OF_MEASURE");

        constexpr std::size_t NFEAT = 3 + 3 + 4;

        array_type result({gb.size(), NFEAT}, 0.);

        std::size_t gbix{0};
        for (auto group = gb.yield(); group.size() != 0; group = gb.yield())
        {
            varray_type row(0., NFEAT);
            std::size_t rix{0};

            const std::valarray<std::size_t> indirect(group.data(), group.size());

            const varray_type boxes_sold = arr[arr.column(boxes_cix)][indirect];
            const varray_type signed_pcost = arr[arr.column(pcost1_cix)][indirect];
            const varray_type pcost1 = std::abs(signed_pcost);
            const varray_type pcost1_per_item = pcost1 / boxes_sold;
            const real_type pcost1_mean = num::mean(pcost1_per_item);
            const real_type pcost1_std = num::std(pcost1_per_item);

            row[rix++] = pcost1_per_item.min() / pcost1_mean;
            row[rix++] = pcost1_per_item.max() / pcost1_mean;
            row[rix++] = pcost1_std / pcost1_mean;

            const varray_type signed_price = arr[arr.column(price_cix)][indirect];
            const varray_type price = std::abs(signed_price);
            const real_type price_mean = num::mean(price);
            const real_type price_std = num::std(price);

            row[rix++] = price.min() / price_mean;
            row[rix++] = price.max() / price_mean;
            row[rix++] = price_std / price_mean;

            const varray_type signed_gross_sales = arr[arr.column(gross_cix)][indirect];
            const varray_type commision = arr[arr.row(group.front())][unit_cix] < 2 ?
                (varray_type)(price / pcost1_per_item) :
                (varray_type)(std::abs(signed_gross_sales) / pcost1);
            const real_type commision_mean = num::mean(commision);
            const real_type commision_std = num::std(commision);

            row[rix++] = commision_mean;
            row[rix++] = commision.min() / commision_mean;
            row[rix++] = commision.max() / commision_mean;
            row[rix++] = commision_std / commision_mean;

            result[result.row(gbix)] = row;
        }

        gb.rewind();

        return result;
    };

    {
        const auto stat = min_max_std(gb_train, i_train_data);
        train_data = num::add_columns(train_data, stat);
    }
    {
        const auto stat = min_max_std(gb_test, i_test_data);
        test_data = num::add_columns(test_data, stat);
    }

    const std::string stat_colnames[] = {
        "PCOST1_REL_MIN", "PCOST1_REL_MAX", "PCOST1_REL_STD",
        "PRICE_REL_MIN", "PRICE_REL_MAX", "PRICE_REL_STD",
        "COMMN_MEAN", "COMMN_REL_MIN", "COMMN_REL_MAX", "COMMN_REL_STD"};
    colnames.insert(colnames.end(), std::begin(stat_colnames), std::end(stat_colnames));

    ////////////////////////////////////////////////////////////////////////////


    const varray_type special_part = gen_attribute(gb_train, i_train_data, "SPECIAL_PART");
    colnames.push_back("SPECIAL_PART");
    train_data = num::add_column(train_data, special_part);

    return std::make_tuple(colnames, train_data, test_data);
}
示例#6
0
	void entry::sort()
	{
		dict().sort(sortpred);
	}
void Foam::scalarTransportPOD::calcOrthoBase() const
{
    if (orthoBasePtr_)
    {
        FatalErrorIn
        (
            "scalarTransportPOD::calcOrthoBase()"
        )   << "Orthogonal base already calculated"
            << abort(FatalError);
    }

    // Create ortho-normal base
    scalar accuracy = readScalar(dict().lookup("accuracy"));

    // Get times list
    Time& runTime = const_cast<Time&>(mesh().time());

    // Remember time index to restore it after the scan
    label origTimeIndex = runTime.timeIndex();

    instantList Times = runTime.times();

    // Create a list of snapshots
    PtrList<volScalarField> fields(Times.size());

    label nSnapshots = 0;

    forAll (Times, i)
    {
        if (Times[i].value() < SMALL || Times[i] == runTime.constant())
        {
            Info << "Skipping time " << Times[i] << endl;

            continue;
        }

        runTime.setTime(Times[i], i);

        Info<< "Time = " << runTime.timeName() << endl;

        IOobject phiHeader
        (
            phiName_,
            runTime.timeName(),
            mesh(),
            IOobject::MUST_READ
        );

        if (phiHeader.headerOk())
        {
            Info<< "    Reading " << phiName_ << endl;

            fields.set(nSnapshots, new volScalarField(phiHeader, mesh()));

            // Rename the field
            fields[nSnapshots].rename(phiName_ + name(i));
            nSnapshots++;
        }
        else
        {
            Info<< "    No " << phiName_ << endl;
        }
    }

    // Reset time index to initial state
    runTime.setTime(Times[origTimeIndex], origTimeIndex);

    // Resize snapshots
    if (nSnapshots < 2)
    {
        FatalErrorIn
        (
            "scalarTransportPOD::calcOrthoBase()"
        )   << "Insufficient number of snapshots: " << nSnapshots
            << abort(FatalError);
    }

    Info << "Number of snapshots: " << nSnapshots << endl;

    fields.setSize(nSnapshots);

    // Create ortho-normal base for transported variable
    orthoBasePtr_ = new scalarPODOrthoNormalBase(fields, accuracy);
}
示例#8
0
TodoView::TodoView(CalObject *cal, QWidget *parent, const char *name)
    : KTabListBox(parent, name, 5)
{
  calendar = cal;
  // set up filter for events
  lbox.installEventFilter(this);
  // set up the widget to have 4 columns (one hidden), and
  // only a vertical scrollbar
  clearTableFlags(Tbl_hScrollBar);
  clearTableFlags(Tbl_autoHScrollBar);
  // BL: autoscrollbar in not working...
  setTableFlags(Tbl_hScrollBar);
  setAutoUpdate(TRUE);
  adjustColumns();
  // insert pictures for use to show a checked/not checked todo
  dict().insert("CHECKED", new QPixmap(Icon("checkedbox.xpm")));
  dict().insert("EMPTY", new QPixmap(Icon("emptybox.xpm")));
  dict().insert("CHECKEDMASK", new QPixmap(Icon("checkedbox-mask.xpm")));
  dict().insert("EMPTYMASK", new QPixmap(Icon("emptybox-mask.xpm")));

  // this is the thing that lets you edit the todo text.
  editor = new QLineEdit(this);
  editor->hide();
  connect(editor, SIGNAL(returnPressed()),
	  this, SLOT(updateSummary()));
  connect(editor, SIGNAL(returnPressed()),
	  editor, SLOT(hide()));
  connect(editor, SIGNAL(textChanged(const char *)),
	  this, SLOT(changeSummary(const char *)));
  
  connect(this, SIGNAL(selected(int, int)),
    	  this, SLOT(updateItem(int, int)));
  connect(this, SIGNAL(highlighted(int, int)),
	  this, SLOT(hiliteAction(int, int)));

  priList = new QListBox(this);
  priList->hide();
  priList->insertItem("1");
  priList->insertItem("2");
  priList->insertItem("3");
  priList->insertItem("4");
  priList->insertItem("5");
  priList->setFixedHeight(priList->itemHeight()*5+5);
  priList->setFixedWidth(priList->maxItemWidth()+5);
  connect(priList, SIGNAL(highlighted(int)),
	  priList, SLOT(hide()));
  connect(priList, SIGNAL(highlighted(int)),
	  this, SLOT(changePriority(int)));

  QPixmap pixmap;
  rmbMenu1 = new QPopupMenu;
  pixmap = Icon("checkedbox.xpm");
  rmbMenu1->insertItem(pixmap, i18n("New Todo"), this,
		       SLOT(newTodo()));
  pixmap = Icon("delete.xpm");
  rmbMenu1->insertItem(pixmap, i18n("Purge Completed "), this,
		       SLOT(purgeCompleted()));

  rmbMenu2 = new QPopupMenu;
  pixmap = Icon("checkedbox.xpm");
  rmbMenu2->insertItem(pixmap, i18n("New Todo"), this,
		     SLOT (newTodo()));
  rmbMenu2->insertItem(i18n("Edit Todo"), this,
		     SLOT (editTodo()));
  pixmap = Icon("delete.xpm");
  rmbMenu2->insertItem(pixmap, i18n("Delete Todo"), this,
		     SLOT (deleteTodo()));
  rmbMenu2->insertItem(i18n("Purge Completed "), this,
		       SLOT(purgeCompleted()));


  editingFlag = FALSE;
  connect(this, SIGNAL(headerClicked(int)), this, SLOT(headerAction(int)));
  updateConfig();
  prevRow = updatingRow = -1;
}
示例#9
0
KService::List KServiceType::offers(const QString &_servicetype)
{
    QDict< KService > dict(53);
    KService::List lst;

    // Services associated directly with this servicetype (the normal case)
    KServiceType::Ptr serv = KServiceTypeFactory::self()->findServiceTypeByName(_servicetype);
    if(serv)
        addUnique(lst, dict, KServiceFactory::self()->offers(serv->offset()), false);
    else
        kdWarning(7009) << "KServiceType::offers : servicetype " << _servicetype << " not found" << endl;

    // Find services associated with any mimetype parents. e.g. text/x-java -> text/plain
    KMimeType::Ptr mime = dynamic_cast< KMimeType * >(static_cast< KServiceType * >(serv));
    bool isAMimeType = (mime != 0);
    if(mime)
    {
        while(true)
        {
            QString parent = mime->parentMimeType();
            if(parent.isEmpty())
                break;
            mime = dynamic_cast< KMimeType * >(KServiceTypeFactory::self()->findServiceTypeByName(parent));
            if(!mime)
                break;

            addUnique(lst, dict, KServiceFactory::self()->offers(mime->offset()), false);
        }
    }
    serv = mime = 0;

    // QValueListIterator<KService::Ptr> it = lst.begin();
    // for( ; it != lst.end(); ++it )
    //    kdDebug() << (*it).data() << " " << (*it)->name() << endl;

    // Support for all/* is deactivated by KServiceTypeProfile::configurationMode()
    // (and makes no sense when querying for an "all" servicetype itself
    // nor for non-mimetypes service types)
    if(!KServiceTypeProfile::configurationMode() && isAMimeType && _servicetype.left(4) != "all/")
    {
        // Support for services associated with "all"
        KServiceType *servAll = KServiceTypeFactory::self()->findServiceTypeByName("all/all");
        if(servAll)
        {
            addUnique(lst, dict, KServiceFactory::self()->offers(servAll->offset()), true);
        }
        else
            kdWarning(7009) << "KServiceType::offers : servicetype all/all not found" << endl;
        delete servAll;

        // Support for services associated with "allfiles"
        if(_servicetype != "inode/directory" && _servicetype != "inode/directory-locked")
        {
            KServiceType *servAllFiles = KServiceTypeFactory::self()->findServiceTypeByName("all/allfiles");
            if(servAllFiles)
            {
                addUnique(lst, dict, KServiceFactory::self()->offers(servAllFiles->offset()), true);
            }
            else
                kdWarning(7009) << "KServiceType::offers : servicetype all/allfiles not found" << endl;
            delete servAllFiles;
        }
    }

    return lst;
}
示例#10
0
void
ModelManager::set_synapse_defaults_( index model_id,
  const DictionaryDatum& params )
{
  params->clear_access_flags();
  assert_valid_syn_id( model_id );

  BadProperty* tmp_exception = NULL;
#ifdef _OPENMP
#pragma omp parallel
  {
    index t = kernel().vp_manager.get_thread_id();
#else // clang-format off
  for ( index t = 0; t < kernel().vp_manager.get_num_threads(); ++t )
  {
#endif // clang-format on
#pragma omp critical
    {
      try
      {
        prototypes_[ t ][ model_id ]->set_status( params );
      }
      catch ( BadProperty& e )
      {
        if ( tmp_exception == NULL )
        {
          tmp_exception = new BadProperty(
            String::compose( "Setting status of prototype '%1': %2",
              prototypes_[ t ][ model_id ]->get_name(),
              e.message() ) );
        }
      }
    }
  }

  if ( tmp_exception != NULL )
  {
    BadProperty e = *tmp_exception;
    delete tmp_exception;
    throw e;
  }

  ALL_ENTRIES_ACCESSED( *params,
    "ModelManager::set_synapse_defaults_",
    "Unread dictionary entries: " );
}

// TODO: replace int with index and return value -1 with invalid_index, also
// change all pertaining code
int
ModelManager::get_model_id( const Name name ) const
{
  const Name model_name( name );
  for ( int i = 0; i < ( int ) models_.size(); ++i )
  {
    assert( models_[ i ] != NULL );
    if ( model_name == models_[ i ]->get_name() )
      return i;
  }
  return -1;
}


DictionaryDatum
ModelManager::get_connector_defaults( synindex syn_id ) const
{
  assert_valid_syn_id( syn_id );

  DictionaryDatum dict( new Dictionary() );

  for ( thread t = 0;
        t < static_cast< thread >( kernel().vp_manager.get_num_threads() );
        ++t )
    prototypes_[ t ][ syn_id ]->get_status(
      dict ); // each call adds to num_connections

  ( *dict )[ "num_connections" ] =
    kernel().connection_manager.get_num_connections( syn_id );

  return dict;
}
Foam::lduSolverPerformance Foam::PCG::solve
(
    scalarField& x,
    const scalarField& b,
    const direction cmpt
) const
{
    // --- Setup class containing solver performance data
    lduSolverPerformance solverPerf
    (
        lduMatrix::preconditioner::getName(dict()) + typeName,
        fieldName()
    );

    register label nCells = x.size();

    scalar* __restrict__ xPtr = x.begin();

    scalarField pA(nCells);
    scalar* __restrict__ pAPtr = pA.begin();

    scalarField wA(nCells);
    scalar* __restrict__ wAPtr = wA.begin();

    // Calculate A.x
    matrix_.Amul(wA, x, coupleBouCoeffs_, interfaces_, cmpt);

    // Calculate initial residual field
    scalarField rA(b - wA);
    scalar* __restrict__ rAPtr = rA.begin();

    // Calculate normalisation factor
    scalar normFactor = this->normFactor(x, b, wA, pA, cmpt);

    if (lduMatrix::debug >= 2)
    {
        Info<< "   Normalisation factor = " << normFactor << endl;
    }

    // Calculate normalised residual norm
    solverPerf.initialResidual() = gSumMag(rA)/normFactor;
    solverPerf.finalResidual() = solverPerf.initialResidual();

    // Check convergence, solve if not converged
    if (!stop(solverPerf))
    {
        scalar wArA = matrix_.great_;
        scalar wArAold = wArA;

        // Select and construct the preconditioner
        autoPtr<lduPreconditioner> preconPtr;

        preconPtr =
            lduPreconditioner::New
            (
                matrix_,
                coupleBouCoeffs_,
                coupleIntCoeffs_,
                interfaces_,
                dict()
            );

        // Solver iteration
        do
        {
            // Store previous wArA
            wArAold = wArA;

            // Precondition residual
            preconPtr->precondition(wA, rA, cmpt);

            // Update search directions:
            wArA = gSumProd(wA, rA);

            if (solverPerf.nIterations() == 0)
            {
                for (register label cell=0; cell<nCells; cell++)
                {
                    pAPtr[cell] = wAPtr[cell];
                }
            }
            else
            {
                scalar beta = wArA/wArAold;

                for (register label cell=0; cell<nCells; cell++)
                {
                    pAPtr[cell] = wAPtr[cell] + beta*pAPtr[cell];
                }
            }


            // Update preconditioned residual
            matrix_.Amul(wA, pA, coupleBouCoeffs_, interfaces_, cmpt);

            scalar wApA = gSumProd(wA, pA);


            // Test for singularity
            if (solverPerf.checkSingularity(mag(wApA)/normFactor)) break;


            // Update solution and residual:

            scalar alpha = wArA/wApA;

            for (register label cell=0; cell<nCells; cell++)
            {
                xPtr[cell] += alpha*pAPtr[cell];
                rAPtr[cell] -= alpha*wAPtr[cell];
            }

            solverPerf.finalResidual() = gSumMag(rA)/normFactor;
            solverPerf.nIterations()++;
        } while (!stop(solverPerf));
    }

    return solverPerf;
}
示例#12
0
Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError& r_err, CallState *p_state) {


	if (!_code_ptr) {

		return Variant();
	}

	r_err.error=Variant::CallError::CALL_OK;

	Variant self;
	Variant retvalue;
	Variant *stack = NULL;
	Variant **call_args;
	int defarg=0;

#ifdef DEBUG_ENABLED

	//GDScriptLanguage::get_singleton()->calls++;

#endif

	uint32_t alloca_size=0;
	GDScript *_class;
	int ip=0;
	int line=_initial_line;



	if (p_state) {
		//use existing (supplied) state (yielded)
		stack=(Variant*)p_state->stack.ptr();
		call_args=(Variant**)&p_state->stack[sizeof(Variant)*p_state->stack_size];
		line=p_state->line;
		ip=p_state->ip;
		alloca_size=p_state->stack.size();
		_class=p_state->_class;
		p_instance=p_state->instance;
		defarg=p_state->defarg;
		self=p_state->self;
		//stack[p_state->result_pos]=p_state->result; //assign stack with result

	} else {

		if (p_argcount!=_argument_count) {

			if (p_argcount>_argument_count) {

				r_err.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
				r_err.argument=_argument_count;


				return Variant();
			} else if (p_argcount < _argument_count - _default_arg_count) {

				r_err.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
				r_err.argument=_argument_count - _default_arg_count;
				return Variant();
			} else {

				defarg=_argument_count-p_argcount;
			}
		}

		alloca_size = sizeof(Variant*)*_call_size + sizeof(Variant)*_stack_size;

		if (alloca_size) {

			uint8_t *aptr = (uint8_t*)alloca(alloca_size);

			if (_stack_size) {

				stack=(Variant*)aptr;
				for(int i=0;i<p_argcount;i++)
					memnew_placement(&stack[i],Variant(*p_args[i]));
				for(int i=p_argcount;i<_stack_size;i++)
					memnew_placement(&stack[i],Variant);
			} else {
				stack=NULL;
			}

			if (_call_size) {

				call_args = (Variant**)&aptr[sizeof(Variant)*_stack_size];
			} else {

				call_args=NULL;
			}


		} else {
			stack=NULL;
			call_args=NULL;
		}

		if (p_instance) {
			if (p_instance->base_ref && static_cast<Reference*>(p_instance->owner)->is_referenced()) {

				self=REF(static_cast<Reference*>(p_instance->owner));
			} else {
				self=p_instance->owner;
			}
			_class=p_instance->script.ptr();
		} else {
			_class=_script;
		}
	}

	String err_text;

#ifdef DEBUG_ENABLED

	if (ScriptDebugger::get_singleton())
		GDScriptLanguage::get_singleton()->enter_function(p_instance,this,stack,&ip,&line);

#define CHECK_SPACE(m_space)\
	ERR_BREAK((ip+m_space)>_code_size)

#define GET_VARIANT_PTR(m_v,m_code_ofs) \
	Variant *m_v; \
	m_v = _get_variant(_code_ptr[ip+m_code_ofs],p_instance,_class,self,stack,err_text);\
	if (!m_v)\
	break;


#else
#define CHECK_SPACE(m_space)
#define GET_VARIANT_PTR(m_v,m_code_ofs) \
	Variant *m_v; \
	m_v = _get_variant(_code_ptr[ip+m_code_ofs],p_instance,_class,self,stack,err_text);

#endif


#ifdef DEBUG_ENABLED

	uint64_t function_start_time;
	uint64_t function_call_time;

	if (GDScriptLanguage::get_singleton()->profiling) {
		function_start_time=OS::get_singleton()->get_ticks_usec();
		function_call_time=0;
		profile.call_count++;
		profile.frame_call_count++;
	}
#endif
	bool exit_ok=false;

	while(ip<_code_size) {


		int last_opcode=_code_ptr[ip];
		switch(_code_ptr[ip]) {

			case OPCODE_OPERATOR: {

				CHECK_SPACE(5);

				bool valid;
				Variant::Operator op = (Variant::Operator)_code_ptr[ip+1];
				ERR_BREAK(op>=Variant::OP_MAX);

				GET_VARIANT_PTR(a,2);
				GET_VARIANT_PTR(b,3);
				GET_VARIANT_PTR(dst,4);

#ifdef DEBUG_ENABLED
				Variant ret;
				Variant::evaluate(op,*a,*b,ret,valid);
#else
				Variant::evaluate(op,*a,*b,*dst,valid);
#endif

				if (!valid) {
#ifdef DEBUG_ENABLED

					if (ret.get_type()==Variant::STRING) {
						//return a string when invalid with the error
						err_text=ret;
						err_text += " in operator '"+Variant::get_operator_name(op)+"'.";
					} else {
						err_text="Invalid operands '"+Variant::get_type_name(a->get_type())+"' and '"+Variant::get_type_name(b->get_type())+"' in operator '"+Variant::get_operator_name(op)+"'.";
					}
#endif
					break;

				}
#ifdef DEBUG_ENABLED
				*dst=ret;
#endif

				ip+=5;

			} continue;
			case OPCODE_EXTENDS_TEST: {

				CHECK_SPACE(4);

				GET_VARIANT_PTR(a,1);
				GET_VARIANT_PTR(b,2);
				GET_VARIANT_PTR(dst,3);

#ifdef DEBUG_ENABLED

				if (a->get_type()!=Variant::OBJECT || a->operator Object*()==NULL) {

					err_text="Left operand of 'extends' is not an instance of anything.";
					break;

				}
				if (b->get_type()!=Variant::OBJECT || b->operator Object*()==NULL) {

					err_text="Right operand of 'extends' is not a class.";
					break;

				}
#endif


				Object *obj_A = *a;
				Object *obj_B = *b;


				GDScript *scr_B = obj_B->cast_to<GDScript>();

				bool extends_ok=false;

				if (scr_B) {
					//if B is a script, the only valid condition is that A has an instance which inherits from the script
					//in other situation, this shoul return false.

					if (obj_A->get_script_instance() && obj_A->get_script_instance()->get_language()==GDScriptLanguage::get_singleton()) {

						GDScript *cmp = static_cast<GDScript*>(obj_A->get_script_instance()->get_script().ptr());
						//bool found=false;
						while(cmp) {

							if (cmp==scr_B) {
								//inherits from script, all ok
								extends_ok=true;
								break;

							}

							cmp=cmp->_base;
						}

					}


				} else {

					GDNativeClass *nc= obj_B->cast_to<GDNativeClass>();

					if (!nc) {

						err_text="Right operand of 'extends' is not a class (type: '"+obj_B->get_type()+"').";
						break;
					}

					extends_ok=ObjectTypeDB::is_type(obj_A->get_type_name(),nc->get_name());
				}

				*dst=extends_ok;
				ip+=4;

			} continue;
			case OPCODE_SET: {

				CHECK_SPACE(3);

				GET_VARIANT_PTR(dst,1);
				GET_VARIANT_PTR(index,2);
				GET_VARIANT_PTR(value,3);

				bool valid;
				dst->set(*index,*value,&valid);

				if (!valid) {
					String v = index->operator String();
					if (v!="") {
						v="'"+v+"'";
					} else {
						v="of type '"+_get_var_type(index)+"'";
					}
					err_text="Invalid set index "+v+" (on base: '"+_get_var_type(dst)+"').";
					break;
				}

				ip+=4;
			} continue;
			case OPCODE_GET: {

				CHECK_SPACE(3);

				GET_VARIANT_PTR(src,1);
				GET_VARIANT_PTR(index,2);
				GET_VARIANT_PTR(dst,3);

				bool valid;
#ifdef DEBUG_ENABLED
				//allow better error message in cases where src and dst are the same stack position
				Variant ret = src->get(*index,&valid);
#else
				*dst = src->get(*index,&valid);

#endif
				if (!valid) {
					String v = index->operator String();
					if (v!="") {
						v="'"+v+"'";
					} else {
						v="of type '"+_get_var_type(index)+"'";
					}
					err_text="Invalid get index "+v+" (on base: '"+_get_var_type(src)+"').";
					break;
				}
#ifdef DEBUG_ENABLED
				*dst=ret;
#endif
				ip+=4;
			} continue;
			case OPCODE_SET_NAMED: {

				CHECK_SPACE(3);

				GET_VARIANT_PTR(dst,1);
				GET_VARIANT_PTR(value,3);

				int indexname = _code_ptr[ip+2];

				ERR_BREAK(indexname<0 || indexname>=_global_names_count);
				const StringName *index = &_global_names_ptr[indexname];

				bool valid;
				dst->set_named(*index,*value,&valid);

				if (!valid) {
					String err_type;
					err_text="Invalid set index '"+String(*index)+"' (on base: '"+_get_var_type(dst)+"').";
					break;
				}

				ip+=4;
			} continue;
			case OPCODE_GET_NAMED: {


				CHECK_SPACE(3);

				GET_VARIANT_PTR(src,1);
				GET_VARIANT_PTR(dst,3);

				int indexname = _code_ptr[ip+2];

				ERR_BREAK(indexname<0 || indexname>=_global_names_count);
				const StringName *index = &_global_names_ptr[indexname];

				bool valid;
#ifdef DEBUG_ENABLED
				//allow better error message in cases where src and dst are the same stack position
				Variant ret = src->get_named(*index,&valid);

#else
				*dst = src->get_named(*index,&valid);
#endif

				if (!valid) {
					if (src->has_method(*index)) {
						err_text="Invalid get index '"+index->operator String()+"' (on base: '"+_get_var_type(src)+"'). Did you mean '."+index->operator String()+"()' ?";
					} else {
						err_text="Invalid get index '"+index->operator String()+"' (on base: '"+_get_var_type(src)+"').";
					}
					break;
				}
#ifdef DEBUG_ENABLED
				*dst=ret;
#endif
				ip+=4;
			} continue;
			case OPCODE_ASSIGN: {

				CHECK_SPACE(3);
				GET_VARIANT_PTR(dst,1);
				GET_VARIANT_PTR(src,2);

				*dst = *src;

				ip+=3;

			} continue;
			case OPCODE_ASSIGN_TRUE: {

				CHECK_SPACE(2);
				GET_VARIANT_PTR(dst,1);

				*dst = true;

				ip+=2;
			} continue;
			case OPCODE_ASSIGN_FALSE: {

				CHECK_SPACE(2);
				GET_VARIANT_PTR(dst,1);

				*dst = false;

				ip+=2;
			} continue;
			case OPCODE_CONSTRUCT: {

				CHECK_SPACE(2);
				Variant::Type t=Variant::Type(_code_ptr[ip+1]);
				int argc=_code_ptr[ip+2];
				CHECK_SPACE(argc+2);
				Variant **argptrs = call_args;
				for(int i=0;i<argc;i++) {
					GET_VARIANT_PTR(v,3+i);
					argptrs[i]=v;
				}

				GET_VARIANT_PTR(dst,3+argc);
				Variant::CallError err;
				*dst = Variant::construct(t,(const Variant**)argptrs,argc,err);

				if (err.error!=Variant::CallError::CALL_OK) {

					err_text=_get_call_error(err,"'"+Variant::get_type_name(t)+"' constructor",(const Variant**)argptrs);
					break;
				}

				ip+=4+argc;
				//construct a basic type
			} continue;
			case OPCODE_CONSTRUCT_ARRAY: {

				CHECK_SPACE(1);
				int argc=_code_ptr[ip+1];
				Array array(true); //arrays are always shared
				array.resize(argc);
				CHECK_SPACE(argc+2);

				for(int i=0;i<argc;i++) {
					GET_VARIANT_PTR(v,2+i);
					array[i]=*v;

				}

				GET_VARIANT_PTR(dst,2+argc);

				*dst=array;

				ip+=3+argc;

			} continue;
			case OPCODE_CONSTRUCT_DICTIONARY: {

				CHECK_SPACE(1);
				int argc=_code_ptr[ip+1];
				Dictionary dict(true); //arrays are always shared

				CHECK_SPACE(argc*2+2);

				for(int i=0;i<argc;i++) {

					GET_VARIANT_PTR(k,2+i*2+0);
					GET_VARIANT_PTR(v,2+i*2+1);
					dict[*k]=*v;

				}

				GET_VARIANT_PTR(dst,2+argc*2);

				*dst=dict;

				ip+=3+argc*2;

			} continue;
			case OPCODE_CALL_RETURN:
			case OPCODE_CALL: {


				CHECK_SPACE(4);
				bool call_ret = _code_ptr[ip]==OPCODE_CALL_RETURN;

				int argc=_code_ptr[ip+1];
				GET_VARIANT_PTR(base,2);
				int nameg=_code_ptr[ip+3];

				ERR_BREAK(nameg<0 || nameg>=_global_names_count);
				const StringName *methodname = &_global_names_ptr[nameg];

				ERR_BREAK(argc<0);
				ip+=4;
				CHECK_SPACE(argc+1);
				Variant **argptrs = call_args;

				for(int i=0;i<argc;i++) {
					GET_VARIANT_PTR(v,i);
					argptrs[i]=v;
				}

#ifdef DEBUG_ENABLED
				uint64_t call_time;

				if (GDScriptLanguage::get_singleton()->profiling) {
					call_time=OS::get_singleton()->get_ticks_usec();
				}

#endif
				Variant::CallError err;
				if (call_ret) {

					GET_VARIANT_PTR(ret,argc);
					base->call_ptr(*methodname,(const Variant**)argptrs,argc,ret,err);
				} else {

					base->call_ptr(*methodname,(const Variant**)argptrs,argc,NULL,err);
				}
#ifdef DEBUG_ENABLED
				if (GDScriptLanguage::get_singleton()->profiling) {
					function_call_time+=OS::get_singleton()->get_ticks_usec() - call_time;
				}
#endif

				if (err.error!=Variant::CallError::CALL_OK) {


					String methodstr = *methodname;
					String basestr = _get_var_type(base);

					if (methodstr=="call") {
						if (argc>=1) {
							methodstr=String(*argptrs[0])+" (via call)";
							if (err.error==Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
								err.argument-=1;
							}
						}
					} if (methodstr=="free") {

						if (err.error==Variant::CallError::CALL_ERROR_INVALID_METHOD) {

							if (base->is_ref()) {
								err_text="Attempted to free a reference.";
								break;
							} else if (base->get_type()==Variant::OBJECT) {

								err_text="Attempted to free a locked object (calling or emitting).";
								break;
							}
						}
					}
					err_text=_get_call_error(err,"function '"+methodstr+"' in base '"+basestr+"'",(const Variant**)argptrs);
					break;
				}

				//_call_func(NULL,base,*methodname,ip,argc,p_instance,stack);
				ip+=argc+1;

			} continue;
			case OPCODE_CALL_BUILT_IN: {

				CHECK_SPACE(4);

				GDFunctions::Function func = GDFunctions::Function(_code_ptr[ip+1]);
				int argc=_code_ptr[ip+2];
				ERR_BREAK(argc<0);

				ip+=3;
				CHECK_SPACE(argc+1);
				Variant **argptrs = call_args;

				for(int i=0;i<argc;i++) {
					GET_VARIANT_PTR(v,i);
					argptrs[i]=v;
				}

				GET_VARIANT_PTR(dst,argc);

				Variant::CallError err;

				GDFunctions::call(func,(const Variant**)argptrs,argc,*dst,err);

				if (err.error!=Variant::CallError::CALL_OK) {


					String methodstr = GDFunctions::get_func_name(func);
					if (dst->get_type()==Variant::STRING) {
						//call provided error string
						err_text="Error calling built-in function '"+methodstr+"': "+String(*dst);
					} else {
						err_text=_get_call_error(err,"built-in function '"+methodstr+"'",(const Variant**)argptrs);
					}
					break;
				}
				ip+=argc+1;

			} continue;
			case OPCODE_CALL_SELF: {


			} break;
			case OPCODE_CALL_SELF_BASE: {

				CHECK_SPACE(2);
				int self_fun = _code_ptr[ip+1];
#ifdef DEBUG_ENABLED

				if (self_fun<0 || self_fun>=_global_names_count) {

					err_text="compiler bug, function name not found";
					break;
				}
#endif
				const StringName *methodname = &_global_names_ptr[self_fun];

				int argc=_code_ptr[ip+2];

				CHECK_SPACE(2+argc+1);

				Variant **argptrs = call_args;

				for(int i=0;i<argc;i++) {
					GET_VARIANT_PTR(v,i+3);
					argptrs[i]=v;
				}

				GET_VARIANT_PTR(dst,argc+3);

				const GDScript *gds = _script;


				const Map<StringName,GDFunction*>::Element *E=NULL;
				while (gds->base.ptr()) {
					gds=gds->base.ptr();
					E=gds->member_functions.find(*methodname);
					if (E)
						break;
				}

				Variant::CallError err;

				if (E) {

					*dst=E->get()->call(p_instance,(const Variant**)argptrs,argc,err);
				} else if (gds->native.ptr()) {

					if (*methodname!=GDScriptLanguage::get_singleton()->strings._init) {

						MethodBind *mb = ObjectTypeDB::get_method(gds->native->get_name(),*methodname);
						if (!mb) {
							err.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
						} else {
							*dst=mb->call(p_instance->owner,(const Variant**)argptrs,argc,err);
						}
					} else {
						err.error=Variant::CallError::CALL_OK;
					}
				} else {

					if (*methodname!=GDScriptLanguage::get_singleton()->strings._init) {
						err.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
					} else {
						err.error=Variant::CallError::CALL_OK;
					}
				}


				if (err.error!=Variant::CallError::CALL_OK) {


					String methodstr = *methodname;
					err_text=_get_call_error(err,"function '"+methodstr+"'",(const Variant**)argptrs);

					break;
				}

				ip+=4+argc;

			} continue;
			case OPCODE_YIELD:
			case OPCODE_YIELD_SIGNAL: {

				int ipofs=1;
				if (_code_ptr[ip]==OPCODE_YIELD_SIGNAL) {
					CHECK_SPACE(4);
					ipofs+=2;
				} else {
					CHECK_SPACE(2);

				}

				Ref<GDFunctionState> gdfs = memnew( GDFunctionState );
				gdfs->function=this;

				gdfs->state.stack.resize(alloca_size);
				//copy variant stack
				for(int i=0;i<_stack_size;i++) {
					memnew_placement(&gdfs->state.stack[sizeof(Variant)*i],Variant(stack[i]));
				}
				gdfs->state.stack_size=_stack_size;
				gdfs->state.self=self;
				gdfs->state.alloca_size=alloca_size;
				gdfs->state._class=_class;
				gdfs->state.ip=ip+ipofs;
				gdfs->state.line=line;
				gdfs->state.instance_id=(p_instance && p_instance->get_owner())?p_instance->get_owner()->get_instance_ID():0;
				gdfs->state.script_id=_class->get_instance_ID();
				//gdfs->state.result_pos=ip+ipofs-1;
				gdfs->state.defarg=defarg;
				gdfs->state.instance=p_instance;
				gdfs->function=this;

				retvalue=gdfs;

				if (_code_ptr[ip]==OPCODE_YIELD_SIGNAL) {
					GET_VARIANT_PTR(argobj,1);
					GET_VARIANT_PTR(argname,2);
					//do the oneshot connect

					if (argobj->get_type()!=Variant::OBJECT) {
						err_text="First argument of yield() not of type object.";
						break;
					}
					if (argname->get_type()!=Variant::STRING) {
						err_text="Second argument of yield() not a string (for signal name).";
						break;
					}
					Object *obj=argobj->operator Object *();
					String signal = argname->operator String();
#ifdef DEBUG_ENABLED

					if (!obj) {
						err_text="First argument of yield() is null.";
						break;
					}
					if (ScriptDebugger::get_singleton()) {
						if (!ObjectDB::instance_validate(obj)) {
							err_text="First argument of yield() is a previously freed instance.";
							break;
						}
					}
					if (signal.length()==0) {

						err_text="Second argument of yield() is an empty string (for signal name).";
						break;
					}

#endif
					Error err = obj->connect(signal,gdfs.ptr(),"_signal_callback",varray(gdfs),Object::CONNECT_ONESHOT);
					if (err!=OK) {
						err_text="Error connecting to signal: "+signal+" during yield().";
						break;
					}


				}

				exit_ok=true;

			} break;
			case OPCODE_YIELD_RESUME: {

				CHECK_SPACE(2);
				if (!p_state) {
					err_text=("Invalid Resume (bug?)");
					break;
				}
				GET_VARIANT_PTR(result,1);
				*result=p_state->result;
				ip+=2;

			} continue;
			case OPCODE_JUMP: {

				CHECK_SPACE(2);
				int to = _code_ptr[ip+1];

				ERR_BREAK(to<0 || to>_code_size);
				ip=to;

			} continue;
			case OPCODE_JUMP_IF: {

				CHECK_SPACE(3);

				GET_VARIANT_PTR(test,1);

				bool valid;
				bool result = test->booleanize(valid);
#ifdef DEBUG_ENABLED
				if (!valid) {

					err_text="cannot evaluate conditional expression of type: "+Variant::get_type_name(test->get_type());
					break;
				}
#endif
				if (result) {
					int to = _code_ptr[ip+2];
					ERR_BREAK(to<0 || to>_code_size);
					ip=to;
					continue;
				}
				ip+=3;
			} continue;
			case OPCODE_JUMP_IF_NOT: {

				CHECK_SPACE(3);

				GET_VARIANT_PTR(test,1);

				bool valid;
				bool result = test->booleanize(valid);
#ifdef DEBUG_ENABLED
				if (!valid) {

					err_text="cannot evaluate conditional expression of type: "+Variant::get_type_name(test->get_type());
					break;
				}
#endif
				if (!result) {
					int to = _code_ptr[ip+2];
					ERR_BREAK(to<0 || to>_code_size);
					ip=to;
					continue;
				}
				ip+=3;
			} continue;
			case OPCODE_JUMP_TO_DEF_ARGUMENT: {

				CHECK_SPACE(2);
				ip=_default_arg_ptr[defarg];

			} continue;
			case OPCODE_RETURN: {

				CHECK_SPACE(2);
				GET_VARIANT_PTR(r,1);
				retvalue=*r;
				exit_ok=true;

			} break;
			case OPCODE_ITERATE_BEGIN: {

				CHECK_SPACE(8); //space for this an regular iterate

				GET_VARIANT_PTR(counter,1);
				GET_VARIANT_PTR(container,2);

				bool valid;
				if (!container->iter_init(*counter,valid)) {
					if (!valid) {
						err_text="Unable to iterate on object of type  "+Variant::get_type_name(container->get_type())+"'.";
						break;
					}
					int jumpto=_code_ptr[ip+3];
					ERR_BREAK(jumpto<0 || jumpto>_code_size);
					ip=jumpto;
					continue;
				}
				GET_VARIANT_PTR(iterator,4);


				*iterator=container->iter_get(*counter,valid);
				if (!valid) {
					err_text="Unable to obtain iterator object of type  "+Variant::get_type_name(container->get_type())+"'.";
					break;
				}


				ip+=5; //skip regular iterate which is always next

			} continue;
			case OPCODE_ITERATE: {

				CHECK_SPACE(4);

				GET_VARIANT_PTR(counter,1);
				GET_VARIANT_PTR(container,2);

				bool valid;
				if (!container->iter_next(*counter,valid)) {
					if (!valid) {
						err_text="Unable to iterate on object of type  "+Variant::get_type_name(container->get_type())+"' (type changed since first iteration?).";
						break;
					}
					int jumpto=_code_ptr[ip+3];
					ERR_BREAK(jumpto<0 || jumpto>_code_size);
					ip=jumpto;
					continue;
				}
				GET_VARIANT_PTR(iterator,4);

				*iterator=container->iter_get(*counter,valid);
				if (!valid) {
					err_text="Unable to obtain iterator object of type  "+Variant::get_type_name(container->get_type())+"' (but was obtained on first iteration?).";
					break;
				}

				ip+=5; //loop again
			} continue;
			case OPCODE_ASSERT: {
				CHECK_SPACE(2);
				GET_VARIANT_PTR(test,1);

#ifdef DEBUG_ENABLED
				bool valid;
				bool result = test->booleanize(valid);


				if (!valid) {

					err_text="cannot evaluate conditional expression of type: "+Variant::get_type_name(test->get_type());
					break;
				}


				if (!result) {

					err_text="Assertion failed.";
					break;
				}

#endif

				ip+=2;
			} continue;
			case OPCODE_BREAKPOINT: {
#ifdef DEBUG_ENABLED
				if (ScriptDebugger::get_singleton()) {
					GDScriptLanguage::get_singleton()->debug_break("Breakpoint Statement",true);
				}
#endif
				ip+=1;
			} continue;
			case OPCODE_LINE: {
				CHECK_SPACE(2);

				line=_code_ptr[ip+1];
				ip+=2;

				if (ScriptDebugger::get_singleton()) {
					// line
					bool do_break=false;

					if (ScriptDebugger::get_singleton()->get_lines_left()>0) {

						if (ScriptDebugger::get_singleton()->get_depth()<=0)
							ScriptDebugger::get_singleton()->set_lines_left( ScriptDebugger::get_singleton()->get_lines_left() -1 );
						if (ScriptDebugger::get_singleton()->get_lines_left()<=0)
							do_break=true;
					}

					if (ScriptDebugger::get_singleton()->is_breakpoint(line,source))
						do_break=true;

					if (do_break) {
						GDScriptLanguage::get_singleton()->debug_break("Breakpoint",true);
					}

					ScriptDebugger::get_singleton()->line_poll();

				}
			} continue;
			case OPCODE_END: {

				exit_ok=true;
				break;

			} break;
			default: {

				err_text="Illegal opcode "+itos(_code_ptr[ip])+" at address "+itos(ip);
			} break;

		}

		if (exit_ok)
			break;
		//error
		// function, file, line, error, explanation
		String err_file;
		if (p_instance)
			err_file=p_instance->script->path;
		else if (_class)
			err_file=_class->path;
		if (err_file=="")
			err_file="<built-in>";
		String err_func = name;
		if (p_instance && p_instance->script->name!="")
			err_func=p_instance->script->name+"."+err_func;
		int err_line=line;
		if (err_text=="") {
			err_text="Internal Script Error! - opcode #"+itos(last_opcode)+" (report please).";
		}

		if (!GDScriptLanguage::get_singleton()->debug_break(err_text,false)) {
			// debugger break did not happen

			_err_print_error(err_func.utf8().get_data(),err_file.utf8().get_data(),err_line,err_text.utf8().get_data(),ERR_HANDLER_SCRIPT);
		}


		break;
	}

#ifdef DEBUG_ENABLED
	if (GDScriptLanguage::get_singleton()->profiling) {
		uint64_t time_taken = OS::get_singleton()->get_ticks_usec() - function_start_time;
		profile.total_time+=time_taken;
		profile.self_time+=time_taken-function_call_time;
		profile.frame_total_time+=time_taken;
		profile.frame_self_time+=time_taken-function_call_time;
		GDScriptLanguage::get_singleton()->script_frame_time+=time_taken-function_call_time;

	}

#endif
	if (ScriptDebugger::get_singleton())
		GDScriptLanguage::get_singleton()->exit_function();


	if (_stack_size) {
		//free stack
		for(int i=0;i<_stack_size;i++)
			stack[i].~Variant();
	}

	return retvalue;

}