@@ -144,14 +144,12 @@ module.exports = class EEI {
144
144
}
145
145
146
146
/**
147
- * Loads bytes from memory and returns them as a buffer. If an error occurs
148
- * a string is instead returned. The function also subtracts the amount of
149
- * gas need for memory expansion.
147
+ * Loads bytes from memory and returns them as a buffer. The function
148
+ * also subtracts the amount of gas need for memory expansion.
150
149
* @method memLoad
151
- * @param {Object } runState
152
150
* @param {BN } offset where to start reading from
153
151
* @param {BN } length how far to read
154
- * @returns {Buffer|String }
152
+ * @returns {Buffer }
155
153
*/
156
154
memLoad ( offset , length ) {
157
155
// check to see if we have enougth gas for the mem read
@@ -166,58 +164,19 @@ module.exports = class EEI {
166
164
offset = offset . toNumber ( )
167
165
length = length . toNumber ( )
168
166
169
- var loaded = this . _runState . memory . slice ( offset , offset + length )
170
- // fill the remaining lenth with zeros
171
- for ( var i = loaded . length ; i < length ; i ++ ) {
172
- loaded [ i ] = 0
173
- }
174
- return Buffer . from ( loaded )
175
- }
176
-
177
- /**
178
- * Subtracts the amount needed for memory usage from `runState.gasLeft`
179
- * @method subMemUsage
180
- * @param {Object } runState
181
- * @param {BN } offset
182
- * @param {BN } length
183
- * @returns {String }
184
- */
185
- subMemUsage ( offset , length ) {
186
- // YP (225): access with zero length will not extend the memory
187
- if ( length . isZero ( ) ) return
188
-
189
- const newMemoryWordCount = offset . add ( length ) . divCeil ( new BN ( 32 ) )
190
- if ( newMemoryWordCount . lte ( this . _runState . memoryWordCount ) ) return
191
-
192
- const words = newMemoryWordCount
193
- const fee = new BN ( this . _runState . _common . param ( 'gasPrices' , 'memory' ) )
194
- const quadCoeff = new BN ( this . _runState . _common . param ( 'gasPrices' , 'quadCoeffDiv' ) )
195
- // words * 3 + words ^2 / 512
196
- const cost = words . mul ( fee ) . add ( words . mul ( words ) . div ( quadCoeff ) )
197
-
198
- if ( cost . gt ( this . _runState . highestMemCost ) ) {
199
- this . useGas ( cost . sub ( this . _runState . highestMemCost ) )
200
- this . _runState . highestMemCost = cost
201
- }
202
-
203
- this . _runState . memoryWordCount = newMemoryWordCount
204
- }
205
-
206
- trap ( err ) {
207
- throw new VmError ( err )
167
+ return this . _runState . memory . read ( offset , length )
208
168
}
209
169
210
170
/**
211
- * Stores bytes to memory. If an error occurs a string is instead returned.
212
- * The function also subtracts the amount of gas need for memory expansion.
171
+ * Stores bytes to memory. The function also subtracts the amount
172
+ * of gas need for memory expansion.
213
173
* @method memStore
214
- * @param {Object } runState
215
174
* @param {BN } offset where to start reading from
216
175
* @param {Buffer } val
217
176
* @param {BN } valOffset
218
177
* @param {BN } length how far to read
219
178
* @param {Boolean } skipSubMem
220
- * @returns {Buffer|String }
179
+ * @returns {Buffer }
221
180
*/
222
181
memStore ( offset , val , valOffset , length , skipSubMem ) {
223
182
if ( skipSubMem !== false ) {
@@ -246,23 +205,47 @@ module.exports = class EEI {
246
205
safeLen = val . length
247
206
}
248
207
249
- let i = 0
250
- if ( safeLen > 0 ) {
251
- safeLen = safeLen > length ? length : safeLen
252
- for ( ; i < safeLen ; i ++ ) {
253
- this . _runState . memory [ offset + i ] = val [ valOffset + i ]
254
- }
208
+ safeLen = safeLen > length ? length : safeLen
209
+ val = val . slice ( valOffset )
210
+ // Pad the remaining length with zeros
211
+ if ( val . length > 0 && safeLen < length ) {
212
+ val = val . fill ( 0 , safeLen , length )
255
213
}
256
214
257
- /*
258
- pad the remaining length with zeros IF AND ONLY IF a value was stored
259
- (even if value offset > value length, strange spec...)
260
- */
261
- if ( val . length > 0 && i < length ) {
262
- for ( ; i < length ; i ++ ) {
263
- this . _runState . memory [ offset + i ] = 0
264
- }
215
+ this . _runState . memory . write ( offset , safeLen , val . slice ( valOffset ) )
216
+ }
217
+
218
+ /**
219
+ * Subtracts the amount needed for memory usage from `runState.gasLeft`
220
+ * @method subMemUsage
221
+ * @param {Object } runState
222
+ * @param {BN } offset
223
+ * @param {BN } length
224
+ * @returns {String }
225
+ */
226
+ subMemUsage ( offset , length ) {
227
+ // YP (225): access with zero length will not extend the memory
228
+ if ( length . isZero ( ) ) return
229
+
230
+ const newMemoryWordCount = offset . add ( length ) . divCeil ( new BN ( 32 ) )
231
+ if ( newMemoryWordCount . lte ( this . _runState . memoryWordCount ) ) return
232
+
233
+ const words = newMemoryWordCount
234
+ const fee = new BN ( this . _runState . _common . param ( 'gasPrices' , 'memory' ) )
235
+ const quadCoeff = new BN ( this . _runState . _common . param ( 'gasPrices' , 'quadCoeffDiv' ) )
236
+ // words * 3 + words ^2 / 512
237
+ const cost = words . mul ( fee ) . add ( words . mul ( words ) . div ( quadCoeff ) )
238
+
239
+ if ( cost . gt ( this . _runState . highestMemCost ) ) {
240
+ this . useGas ( cost . sub ( this . _runState . highestMemCost ) )
241
+ this . _runState . highestMemCost = cost
265
242
}
243
+
244
+ this . _runState . memoryWordCount = newMemoryWordCount
245
+ }
246
+
247
+ trap ( err ) {
248
+ throw new VmError ( err )
266
249
}
267
250
268
251
// checks if a jump is valid given a destination
0 commit comments