MCPcopy Create free account
hub / github.com/GaijinEntertainment/daScript / simulateExprMakeStruct

Method simulateExprMakeStruct

src/ast/ast_simulate.cpp:853–1038  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

851 }
852
853 vector<SimNode *> SimulateVisitor::simulateExprMakeStruct(const ExprMakeStruct *mks) {
854 gc_guard gc_scope;
855 vector<SimNode *> simlist;
856 // init with 0
857 int total = int(mks->structs.size());
858 int stride = mks->makeType->getStride();
859 // note: if its an empty tuple init, like [[tuple<int;float>]] and its embedded - we need to zero it out
860 bool emptyEmbeddedTuple = ( mks->makeType->baseType==Type::tTuple && total==0);
861 bool partialyInitStruct = !mks->doesNotNeedInit && !mks->initAllFields;
862 if ( (emptyEmbeddedTuple || partialyInitStruct) && stride ) {
863 int bytes = das::max(total,1) * stride;
864 SimNode * init0;
865 if ( mks->useCMRES ) {
866 if ( bytes==0 ) {
867 init0 = nullptr;
868 } else if ( bytes <= 32 ) {
869 init0 = context.code->makeNodeUnrollNZ<SimNode_InitLocalCMResN>(bytes, mks->at, mks->extraOffset);
870 } else {
871 init0 = context.code->makeNode<SimNode_InitLocalCMRes>(mks->at, mks->extraOffset, bytes);
872 }
873 } else if ( mks->useStackRef ) {
874 init0 = context.code->makeNode<SimNode_InitLocalRef>(mks->at, mks->stackTop, mks->extraOffset, bytes);
875 } else {
876 init0 = context.code->makeNode<SimNode_InitLocal>(mks->at, mks->stackTop + mks->extraOffset, bytes);
877 }
878 if (init0) simlist.push_back(init0);
879 }
880 if ( mks->makeType->baseType == Type::tStructure ) {
881 for ( int index=0; index != total; ++index ) {
882 if ( mks->constructor ) {
883 uint32_t offset = mks->extraOffset + index*stride;
884 SimNode_CallBase * pCall = (SimNode_CallBase *) context.code->makeNodeUnrollAny<SimNode_CallAndCopyOrMove>(0, mks->at);
885 DAS_ASSERT(mks->constructor->index!=-1 && "should have failed in type infer otherwise");
886 pCall->fnPtr = context.getFunction(mks->constructor->index);
887 if ( mks->useCMRES ) {
888 pCall->cmresEval = context.code->makeNode<SimNode_GetCMResOfs>(mks->at, offset);
889 } else if ( mks->useStackRef ) {
890 pCall->cmresEval = context.code->makeNode<SimNode_GetLocalRefOff>(mks->at, mks->stackTop, offset);
891 } else {
892 pCall->cmresEval = context.code->makeNode<SimNode_GetLocal>(mks->at, mks->stackTop + offset);
893 }
894 simlist.push_back(pCall);
895 }
896 auto & fields = mks->structs[index];
897 for ( const auto & decl : *fields ) {
898 auto field = mks->makeType->structType->findField(decl->name);
899 DAS_ASSERT(field && "should have failed in type infer otherwise");
900 uint32_t offset = mks->extraOffset + index*stride + field->offset;
901 SimNode * cpy;
902 if ( decl->value->rtti_isMakeLocal() ) {
903 // so what happens here, is we ask it for the generated commands and append it to this list only
904 auto mkl = static_cast<ExprMakeLocal*>(decl->value);
905 auto lsim = sv_simulateLocal(mkl);
906 simlist.insert(simlist.end(), lsim.begin(), lsim.end());
907 continue;
908 } else if ( mks->useCMRES ) {
909 if ( decl->moveSemantics ){
910 cpy = sv_makeLocalCMResMove(mks->at, offset, decl->value);

Callers

nothing calls this directly

Calls 14

simulateExpressionFunction · 0.85
getStrideMethod · 0.80
isRefMethod · 0.80
getR2VTypeMethod · 0.80
sizeMethod · 0.45
push_backMethod · 0.45
findFieldMethod · 0.45
insertMethod · 0.45
endMethod · 0.45
beginMethod · 0.45
errorMethod · 0.45
makeFieldTypeMethod · 0.45

Tested by

no test coverage detected