| 724 | } |
| 725 | |
| 726 | vector<SimNode *> SimulateVisitor::simulateExprMakeVariant(const ExprMakeVariant *mkv) { |
| 727 | gc_guard gc_scope; |
| 728 | vector<SimNode *> simlist; |
| 729 | int index = 0; |
| 730 | int stride = mkv->makeType->getStride(); |
| 731 | // init with 0 it its 'default' initialization |
| 732 | if ( stride && mkv->variants.empty() ) { |
| 733 | int bytes = stride; |
| 734 | SimNode * init0; |
| 735 | if ( mkv->useCMRES ) { |
| 736 | if ( bytes==0 ) { |
| 737 | init0 = nullptr; |
| 738 | } else if ( bytes <= 32 ) { |
| 739 | init0 = context.code->makeNodeUnrollNZ<SimNode_InitLocalCMResN>(bytes, mkv->at, mkv->extraOffset); |
| 740 | } else { |
| 741 | init0 = context.code->makeNode<SimNode_InitLocalCMRes>(mkv->at, mkv->extraOffset, bytes); |
| 742 | } |
| 743 | } else if ( mkv->useStackRef ) { |
| 744 | init0 = context.code->makeNode<SimNode_InitLocalRef>(mkv->at, mkv->stackTop, mkv->extraOffset, bytes); |
| 745 | } else { |
| 746 | init0 = context.code->makeNode<SimNode_InitLocal>(mkv->at, mkv->stackTop + mkv->extraOffset, bytes); |
| 747 | } |
| 748 | if (init0) simlist.push_back(init0); |
| 749 | } |
| 750 | // now fields |
| 751 | for ( const auto & decl : mkv->variants ) { |
| 752 | auto fieldVariant = mkv->makeType->findArgumentIndex(decl->name); |
| 753 | DAS_ASSERT(fieldVariant!=-1 && "should have failed in type infer otherwise"); |
| 754 | // lets set variant index |
| 755 | uint32_t voffset = mkv->extraOffset + index*stride; |
| 756 | auto vconst = new ExprConstInt(mkv->at, int32_t(fieldVariant)); |
| 757 | vconst->type = new TypeDecl(Type::tInt); |
| 758 | setE(vconst, context.code->makeNode<SimNode_ConstValue>(vconst->at, vconst->value)); |
| 759 | SimNode * svi; |
| 760 | if ( mkv->useCMRES ) { |
| 761 | svi = sv_makeLocalCMResCopy(mkv->at, voffset, vconst); |
| 762 | } else if (mkv->useStackRef) { |
| 763 | svi = sv_makeLocalRefCopy(mkv->at, mkv->stackTop, voffset, vconst); |
| 764 | } else { |
| 765 | svi = sv_makeLocalCopy(mkv->at, mkv->stackTop+voffset, vconst); |
| 766 | } |
| 767 | simlist.push_back(svi); |
| 768 | // field itself |
| 769 | auto fieldOffset = mkv->makeType->getVariantFieldOffset(fieldVariant); |
| 770 | uint32_t offset = voffset + fieldOffset; |
| 771 | SimNode * cpy = nullptr; |
| 772 | if ( decl->value->rtti_isMakeLocal() ) { |
| 773 | // so what happens here, is we ask it for the generated commands and append it to this list only |
| 774 | auto mkl = static_cast<ExprMakeLocal*>(decl->value); |
| 775 | auto lsim = sv_simulateLocal(mkl); |
| 776 | simlist.insert(simlist.end(), lsim.begin(), lsim.end()); |
| 777 | } else if ( mkv->useCMRES ) { |
| 778 | if ( decl->moveSemantics ){ |
| 779 | cpy = sv_makeLocalCMResMove(mkv->at, offset, decl->value); |
| 780 | } else { |
| 781 | cpy = sv_makeLocalCMResCopy(mkv->at, offset, decl->value); |
| 782 | } |
| 783 | } else if ( mkv->useStackRef ) { |
nothing calls this directly
no test coverage detected