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"; } }
entry* entry::find_key(char const* key) { dictionary_type::iterator i = dict().find(key); if (i == dict().end()) return 0; return &i->second; }
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); }
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); }
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; }
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; }
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; }
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; }