@@ -1105,6 +1105,13 @@ struct InfoCollector
11051105 addChildParentLink (curr->ref , curr);
11061106 addChildParentLink (curr->value , curr);
11071107 }
1108+ void visitArrayLoad (ArrayLoad* curr) {
1109+ if (!isRelevant (curr->ref )) {
1110+ addRoot (curr);
1111+ return ;
1112+ }
1113+ addChildParentLink (curr->ref , curr);
1114+ }
11081115 void visitArrayStore (ArrayStore* curr) {
11091116 if (curr->ref ->type == Type::unreachable) {
11101117 return ;
@@ -1755,6 +1762,7 @@ void TNHOracle::scan(Function* func,
17551762 }
17561763 void visitArrayGet (ArrayGet* curr) { notePossibleTrap (curr->ref ); }
17571764 void visitArraySet (ArraySet* curr) { notePossibleTrap (curr->ref ); }
1765+ void visitArrayLoad (ArrayLoad* curr) { notePossibleTrap (curr->ref ); }
17581766 void visitArrayStore (ArrayStore* curr) { notePossibleTrap (curr->ref ); }
17591767 void visitArrayLen (ArrayLen* curr) { notePossibleTrap (curr->ref ); }
17601768 void visitArrayCopy (ArrayCopy* curr) {
@@ -2865,6 +2873,9 @@ void Flower::flowAfterUpdate(LocationIndex locationIndex) {
28652873 } else if (auto * set = parent->dynCast <ArraySet>()) {
28662874 assert (set->ref == child || set->value == child);
28672875 writeToData (set->ref , set->value , 0 );
2876+ } else if (auto * load = parent->dynCast <ArrayLoad>()) {
2877+ assert (load->ref == child);
2878+ readFromData (load->ref ->type , 0 , contents, load);
28682879 } else if (auto * store = parent->dynCast <ArrayStore>()) {
28692880 assert (store->ref == child || store->value == child);
28702881 // TODO: model the stored value, and handle different but equal values in
@@ -3108,15 +3119,25 @@ void Flower::filterPackedDataReads(PossibleContents& contents,
31083119 auto signed_ = false ;
31093120 Expression* ref;
31103121 Index index;
3122+ unsigned bytes = 0 ;
3123+ Type resultType = Type::none;
31113124 if (auto * get = expr->dynCast <StructGet>()) {
31123125 signed_ = get->signed_ ;
31133126 ref = get->ref ;
31143127 index = get->index ;
3128+ resultType = get->type ;
31153129 } else if (auto * get = expr->dynCast <ArrayGet>()) {
31163130 signed_ = get->signed_ ;
31173131 ref = get->ref ;
31183132 // Arrays are treated as having a single field.
31193133 index = 0 ;
3134+ resultType = get->type ;
3135+ } else if (auto * load = expr->dynCast <ArrayLoad>()) {
3136+ signed_ = load->signed_ ;
3137+ ref = load->ref ;
3138+ index = 0 ;
3139+ bytes = load->bytes ;
3140+ resultType = load->type ;
31203141 } else {
31213142 WASM_UNREACHABLE (" bad packed read" );
31223143 }
@@ -3135,13 +3156,21 @@ void Flower::filterPackedDataReads(PossibleContents& contents,
31353156 assert (ref->type .isRef ());
31363157 auto field = GCTypeUtils::getField (ref->type .getHeapType (), index);
31373158 assert (field);
3138- if (!field->isPacked ()) {
3139- return ;
3159+ if (!bytes) {
3160+ if (!field->isPacked ()) {
3161+ return ;
3162+ }
3163+ bytes = field->getByteSize ();
31403164 }
31413165
31423166 if (contents.isLiteral ()) {
31433167 // This is a constant. We can sign-extend it and use that value.
3144- auto shifts = Literal (int32_t (32 - field->getByteSize () * 8 ));
3168+ unsigned bits = resultType.getByteSize () == 8 ? 64 : 32 ;
3169+ if (bits <= bytes * 8 ) {
3170+ // No need to sign-extend for full size.
3171+ return ;
3172+ }
3173+ auto shifts = Literal (int32_t (bits - bytes * 8 ));
31453174 auto lit = contents.getLiteral ();
31463175 lit = lit.shl (shifts);
31473176 lit = lit.shrS (shifts);
0 commit comments