@@ -928,10 +928,6 @@ class ModuleInstanceBase {
928928 }
929929
930930 void initializeMemoryContents () {
931- // no way to create a Block without an ArenaAllocator, so use a builder
932- // instead of creating it locally.
933- Builder builder (wasm);
934-
935931 Const offset;
936932 offset.value = Literal (uint32_t (0 ));
937933 offset.finalize ();
@@ -955,15 +951,16 @@ class ModuleInstanceBase {
955951 init.finalize ();
956952
957953 DataDrop drop;
958- drop.segment = segment. index ;
954+ drop.segment = i ;
959955 drop.finalize ();
960956
961- Function initializer;
962- initializer.body = builder.blockify (&init, &drop);
963-
964- FunctionScope scope (&initializer, {});
965-
966- RuntimeExpressionRunner (*this , scope).visit (&init);
957+ // we don't actually have a function, but we need one in order to visit
958+ // the memory.init and data.drop instructions.
959+ Function dummyFunc;
960+ FunctionScope dummyScope (&dummyFunc, {});
961+ RuntimeExpressionRunner runner (*this , dummyScope);
962+ runner.visit (&init);
963+ runner.visit (&drop);
967964 }
968965 }
969966
@@ -1228,14 +1225,20 @@ class ModuleInstanceBase {
12281225 trap (" memory.init of dropped segment" );
12291226 }
12301227
1231- size_t destVal (dest.value .geti32 ());
1232- size_t offsetVal (offset.value .geti32 ());
1233- size_t sizeVal (size.value .geti32 ());
1228+ Address destVal (uint32_t (dest.value .geti32 ()));
1229+ Address offsetVal (uint32_t (offset.value .geti32 ()));
1230+ Address sizeVal (uint32_t (size.value .geti32 ()));
1231+
1232+ instance.checkLoadAddress (destVal, 0 );
1233+ if (offsetVal > segment.data .size ()) {
1234+ trap (" segment offset out of bounds" );
1235+ }
1236+
12341237 for (size_t i = 0 ; i < sizeVal; ++i) {
12351238 if (offsetVal + i >= segment.data .size ()) {
12361239 trap (" out of bounds segment access in memory.init" );
12371240 }
1238- Literal addr = Literal (uint32_t (destVal + i));
1241+ Literal addr (uint32_t (destVal + i));
12391242 instance.externalInterface ->store8 (
12401243 instance.getFinalAddress (addr, 1 ),
12411244 segment.data [offsetVal + i]
@@ -1253,12 +1256,64 @@ class ModuleInstanceBase {
12531256 }
12541257 Flow visitMemoryCopy (MemoryCopy *curr) {
12551258 NOTE_ENTER (" MemoryCopy" );
1256- // TODO(tlively): implement me
1259+ Flow dest = this ->visit (curr->dest );
1260+ if (dest.breaking ()) return dest;
1261+ Flow source = this ->visit (curr->source );
1262+ if (source.breaking ()) return source;
1263+ Flow size = this ->visit (curr->size );
1264+ if (size.breaking ()) return size;
1265+ NOTE_EVAL1 (dest);
1266+ NOTE_EVAL1 (source);
1267+ NOTE_EVAL1 (size);
1268+ Address destVal (uint32_t (dest.value .geti32 ()));
1269+ Address sourceVal (uint32_t (source.value .geti32 ()));
1270+ Address sizeVal (uint32_t (size.value .geti32 ()));
1271+
1272+ instance.checkLoadAddress (destVal, 0 );
1273+ instance.checkLoadAddress (sourceVal, 0 );
1274+
1275+ size_t start = 0 ;
1276+ size_t end = sizeVal;
1277+ int step = 1 ;
1278+ // Reverse direction if source is below dest and they overlap
1279+ if (sourceVal < destVal &&
1280+ (sourceVal + sizeVal > destVal || sourceVal + sizeVal < sourceVal)) {
1281+ start = sizeVal - 1 ;
1282+ end = -1 ;
1283+ step = -1 ;
1284+ }
1285+ for (size_t i = start; i != end; i += step) {
1286+ if (i + destVal >= std::numeric_limits<uint32_t >::max ()) {
1287+ trap (" Out of bounds memory access" );
1288+ }
1289+ instance.externalInterface ->store8 (
1290+ instance.getFinalAddress (Literal (uint32_t (destVal + i)), 1 ),
1291+ instance.externalInterface ->load8s (
1292+ instance.getFinalAddress (Literal (uint32_t (sourceVal + i)), 1 )));
1293+ }
12571294 return {};
12581295 }
12591296 Flow visitMemoryFill (MemoryFill *curr) {
12601297 NOTE_ENTER (" MemoryFill" );
1261- // TODO(tlively): implement me
1298+ Flow dest = this ->visit (curr->dest );
1299+ if (dest.breaking ()) return dest;
1300+ Flow value = this ->visit (curr->value );
1301+ if (value.breaking ()) return value;
1302+ Flow size = this ->visit (curr->size );
1303+ if (size.breaking ()) return size;
1304+ NOTE_EVAL1 (dest);
1305+ NOTE_EVAL1 (value);
1306+ NOTE_EVAL1 (size);
1307+ Address destVal (uint32_t (dest.value .geti32 ()));
1308+ Address sizeVal (uint32_t (size.value .geti32 ()));
1309+
1310+ instance.checkLoadAddress (destVal, 0 );
1311+
1312+ uint8_t val (value.value .geti32 ());
1313+ for (size_t i = 0 ; i < sizeVal; ++i) {
1314+ instance.externalInterface ->store8 (
1315+ instance.getFinalAddress (Literal (uint32_t (destVal + i)), 1 ), val);
1316+ }
12621317 return {};
12631318 }
12641319
0 commit comments