git ssb

0+

wanderer🌟 / js-primea-hypervisor



Commit fe80685fa3f7f75e6bcb2fb0e4278298822b4a3e

Merge pull request #39 from ewasm/endian-cleanup

Endian cleanup
wanderer authored on 8/25/2016, 2:12:37 AM
GitHub committed on 8/25/2016, 2:12:37 AM
Parent: aa7f348ee71a97e479efcc2d058b302bcf683a0d
Parent: a2d4372bc21bc705e7d5c559b431d90588315e10

Files changed

address.jschanged
block.jschanged
debugInterface.jschanged
environment.jschanged
index.jschanged
interface.jschanged
tests/interface/address.wastchanged
tests/interface/balance.wastchanged
tests/interface/caller.wastchanged
tests/interface/coinbase.wastchanged
tests/interface/origin.wastchanged
transaction.jschanged
u256.jschanged
address.jsView
@@ -1,41 +1,38 @@
1-const ethUtil = require('ethereumjs-util')
1+const BN = require('bn.js')
2+const U256 = require('./u256.js')
23
3-module.exports = class Address {
4+module.exports = class Address extends U256 {
45 constructor (value) {
5- // Special case: duplicate
6- if (value instanceof Address) {
7- this._value = new Buffer(value._value)
8- return
6+ super(value)
7+ if (this._value.byteLength() > 20) {
8+ throw new Error('Invalid address length: ' + this._value.byteLength() + ' for ' + value)
99 }
10+ }
1011
11- if (value instanceof Uint8Array) {
12- this._value = new Buffer(value)
13- } else if (typeof value !== 'string') {
14- throw new Error('Invalid input to address')
15- } else if (!ethUtil.isHexPrefixed(value)) {
16- throw new Error('Invalid address format')
17- } else {
18- this._value = new Buffer(ethUtil.stripHexPrefix(value), 'hex')
19- }
12+ // This assumes Uint8Array in LSB (WASM code)
13+ static fromMemory (value) {
14+ return new Address(new BN(value, 16, 'le'))
15+ }
2016
21- if (this._value.length !== 20) {
22- throw new Error('Invalid address length')
23- }
17+ // This assumes Uint8Array in LSB (WASM code)
18+ toMemory () {
19+ return this._value.toBuffer('le', 20)
2420 }
2521
2622 toBuffer () {
27- return this._value
23+ return super.toBuffer(20)
2824 }
2925
26+ // Needs to be displayed as a hex always
3027 toString () {
31- return '0x' + this._value.toString('hex')
28+ return '0x' + this._value.toString('hex', 40)
3229 }
3330
3431 isZero () {
35- return this._value.equals(ethUtil.zeros(20))
32+ return this._value.isZero()
3633 }
3734
3835 equals (address) {
39- return this._value.toString('hex') === address.toBuffer().toString('hex')
36+ return this.toString() === address.toString()
4037 }
4138 }
block.jsView
@@ -25,7 +25,7 @@
2525 return ethUtil.bufferToInt(this.header.timestamp)
2626 }
2727
2828 get coinbase () {
29- return new Address(this.header.coinbase)
29+ return new Address('0x' + this.header.coinbase.toString('hex'))
3030 }
3131 }
debugInterface.jsView
@@ -34,15 +34,15 @@
3434 }
3535 console.error(`op: ${opcode.name} gas: ${this.environment.gasLeft}`)
3636 console.log('-------------stack--------------')
3737 for (let i = sp; i >= 0; i -= 32) {
38- console.log(`${(sp - i) / 32} ${this.getMemoryBuffer(i).toString('hex')}`)
38+ console.log(`${(sp - i) / 32} ${this.getMemoryBuffer(i).reverse().toString('hex')}`)
3939 }
4040 return sp
4141 }.bind(this)
4242 }
4343 }
4444
4545 getMemoryBuffer (offset) {
46- return new Buffer(this.module.exports.memory.slice(offset, offset + 32)).reverse()
46+ return new Buffer(this.module.exports.memory.slice(offset, offset + 32))
4747 }
4848 }
environment.jsView
@@ -37,9 +37,8 @@
3737 account.set('nonce', trie.nonce || new U256(0))
3838 account.set('balance', trie.balance || new U256(0))
3939 account.set('code', trie.code || new Uint8Array())
4040 account.set('storage', trie.storage || new Map())
41-
4241 this.state.set(address.toString(), account)
4342 }
4443
4544 getBalance (address) {
index.jsView
@@ -17,11 +17,9 @@
1717
1818 // The Kernel Stores all of its state in the Environment. The Interface is used
1919 // to by the VM to retrive infromation from the Environment.
2020 const Environment = require('./environment.js')
21-
2221 const DebugInterface = require('./debugInterface.js')
23-
2422 const Address = require('./address.js')
2523 const U256 = require('./u256.js')
2624 const Utils = require('./utils.js')
2725 const Transaction = require('./transaction.js')
interface.jsView
@@ -86,9 +86,9 @@
8686 */
8787 getAddress (offset) {
8888 this.takeGas(2)
8989
90- this.setMemory(offset, constants.ADDRESS_SIZE_BYTES, this.environment.address.toBuffer())
90+ this.setMemory(offset, constants.ADDRESS_SIZE_BYTES, this.environment.address.toMemory())
9191 }
9292
9393 /**
9494 * Gets balance of the given account and loads it into memory at the given
@@ -98,12 +98,12 @@
9898 */
9999 getBalance (addressOffset, offset) {
100100 this.takeGas(20)
101101
102- const address = new Address(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
102+ const address = Address.fromMemory(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
103103 // call the parent contract and ask for the balance of one of its child contracts
104104 const balance = this.environment.getBalance(address)
105- this.setMemory(offset, constants.BALANCE_SIZE_BYTES, balance.toBuffer(constants.BALANCE_SIZE_BYTES))
105+ this.setMemory(offset, constants.BALANCE_SIZE_BYTES, balance.toMemory(constants.BALANCE_SIZE_BYTES))
106106 }
107107
108108 /**
109109 * Gets the execution's origination address and loads it into memory at the
@@ -113,9 +113,9 @@
113113 */
114114 getTxOrigin (offset) {
115115 this.takeGas(2)
116116
117- this.setMemory(offset, constants.ADDRESS_SIZE_BYTES, this.environment.origin.toBuffer())
117+ this.setMemory(offset, constants.ADDRESS_SIZE_BYTES, this.environment.origin.toMemory())
118118 }
119119
120120 /**
121121 * Gets caller address and loads it into memory at the given offset. This is
@@ -124,9 +124,9 @@
124124 */
125125 getCaller (offset) {
126126 this.takeGas(2)
127127
128- this.setMemory(offset, constants.ADDRESS_SIZE_BYTES, this.environment.caller.toBuffer())
128+ this.setMemory(offset, constants.ADDRESS_SIZE_BYTES, this.environment.caller.toMemory())
129129 }
130130
131131 /**
132132 * Gets the deposited value by the instruction/transaction responsible for
@@ -135,9 +135,9 @@
135135 */
136136 getCallValue (offset) {
137137 this.takeGas(2)
138138
139- this.setMemory(offset, constants.BALANCE_SIZE_BYTES, this.environment.callValue.toBuffer(constants.BALANCE_SIZE_BYTES))
139+ this.setMemory(offset, constants.BALANCE_SIZE_BYTES, this.environment.callValue.toMemory(constants.BALANCE_SIZE_BYTES))
140140 }
141141
142142 /**
143143 * Get size of input data in current environment. This pertains to the input
@@ -168,9 +168,8 @@
168168 * Copys the input data in current environment to memory. This pertains to
169169 * the input data passed with the message call instruction or transaction.
170170 * @param {integer} offset the offset in memory to load into
171171 * @param {integer} dataOffset the offset in the input data
172- * @param {integer} length the length of data to copy
173172 */
174173 callDataCopy256 (offset, dataOffset) {
175174 this.takeGas(3)
176175 const callData = this.environment.callData.slice(dataOffset, dataOffset + 32)
@@ -207,9 +206,9 @@
207206 */
208207 getExternalCodeSize (addressOffset) {
209208 this.takeGas(20)
210209
211- const address = new Address(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
210+ const address = Address.fromMemory(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
212211 const code = this.environment.getCode(address)
213212 return code.length
214213 }
215214
@@ -222,9 +221,9 @@
222221 */
223222 externalCodeCopy (addressOffset, resultOffset, codeOffset, length) {
224223 this.takeGas(20 + ((length / 32) * 3))
225224
226- const address = new Address(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
225+ const address = Address.fromMemory(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
227226 let code = this.environment.getCode(address)
228227 code = new Uint8Array(code, codeOffset, length)
229228 this.setMemory(resultOffset, length, code)
230229 }
@@ -254,9 +253,9 @@
254253 hash = new U256(0)
255254 } else {
256255 hash = new U256(this.environment.getBlockHash(number))
257256 }
258- this.setMemory(offset, 32, hash.toBuffer())
257+ this.setMemory(offset, 32, hash.toMemory())
259258 }
260259
261260 /**
262261 * Gets the block’s beneficiary address and loads into memory.
@@ -264,9 +263,9 @@
264263 */
265264 getBlockCoinbase (offset) {
266265 this.takeGas(2)
267266
268- this.setMemory(offset, constants.ADDRESS_SIZE_BYTES, this.environment.block.coinbase.toBuffer())
267+ this.setMemory(offset, constants.ADDRESS_SIZE_BYTES, this.environment.block.coinbase.toMemory())
269268 }
270269
271270 /**
272271 * Get the block’s timestamp.
@@ -294,9 +293,9 @@
294293 */
295294 getBlockDifficulty (offset) {
296295 this.takeGas(2)
297296
298- this.setMemory(offset, 32, this.environment.block.difficulty.toBuffer())
297+ this.setMemory(offset, 32, this.environment.block.difficulty.toMemory())
299298 }
300299
301300 /**
302301 * Get the block’s gas limit.
@@ -333,9 +332,9 @@
333332 */
334333 create (valueOffset, dataOffset, length) {
335334 this.takeGas(32000)
336335
337- const value = new U256(this.getMemory(valueOffset, constants.BALANCE_SIZE_BYTES))
336+ const value = U256.fromMemory(this.getMemory(valueOffset, constants.BALANCE_SIZE_BYTES))
338337 const data = this.getMemory(dataOffset, length)
339338 const result = this.environment.create(value, data)
340339 return result
341340 }
@@ -355,10 +354,10 @@
355354 // FIXME: count properly
356355 this.takeGas(40)
357356
358357 // Load the params from mem
359- const address = new Address(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
360- const value = new U256(this.getMemory(valueOffset, constants.BALANCE_SIZE_BYTES))
358+ const address = Address.fromMemory(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
359+ const value = U256.fromMemory(this.getMemory(valueOffset, constants.BALANCE_SIZE_BYTES))
361360 const data = this.getMemory(dataOffset, dataLength)
362361 // Run the call
363362 const [result, errorCode] = this.environment.call(gas, address, value, data)
364363 this.setMemory(resultOffset, resultLength, result)
@@ -380,10 +379,10 @@
380379 // FIXME: count properly
381380 this.takeGas(40)
382381
383382 // Load the params from mem
384- const address = new Address(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
385- const value = new U256(this.getMemory(valueOffset, constants.BALANCE_SIZE_BYTES))
383+ const address = Address.fromMemory(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
384+ const value = U256.fromMemory(this.getMemory(valueOffset, constants.BALANCE_SIZE_BYTES))
386385 const data = this.getMemory(dataOffset, dataLength)
387386 // Run the call
388387 const [result, errorCode] = this.environment.callCode(gas, address, value, data)
389388 this.setMemory(resultOffset, resultLength, result)
@@ -406,9 +405,9 @@
406405 // FIXME: count properly
407406 this.takeGas(40)
408407
409408 const data = this.getMemory(dataOffset, dataLength)
410- const address = new Address(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
409+ const address = Address.fromMemory(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
411410 const [result, errorCode] = this.environment.callDelegate(gas, address, data)
412411 this.setMemory(resultOffset, resultLength, result)
413412 return errorCode
414413 }
@@ -469,9 +468,9 @@
469468 * balance to an address path
470469 * @param {integer} offset the offset to load the address from
471470 */
472471 selfDestruct (addressOffset) {
473- this.environment.suicideAddress = new Address(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
472+ this.environment.suicideAddress = Address.fromMemory(this.getMemory(addressOffset, constants.ADDRESS_SIZE_BYTES))
474473 this.environment.gasRefund += 24000
475474 }
476475
477476 getMemory (offset, length) {
tests/interface/address.wastView
@@ -8,9 +8,9 @@
88 (func
99 (block
1010 ;; loads the address into memory
1111 (call_import $address (i32.const 0))
12- (if (i64.eq (i64.load (i32.const 0)) (i64.const 0x72a1048901c1485d)) ;; big enden
12+ (if (i64.eq (i64.load (i32.const 0)) (i64.const 0xbd9c6f4a2d06c47b))
1313 (return)
1414 )
1515 (unreachable)
1616 )
tests/interface/balance.wastView
@@ -1,7 +1,7 @@
11 ;; address of 5d48c1018904a172886829bbbd9c6f4a2d06c47b has a balance of 0x056bc75e2d63100000 (100 ETH)
22 (module
3- (memory 1 (segment 0 "\5d\48\c1\01\89\04\a1\72\88\68\29\bb\bd\9c\6f\4a\2d\06\c4\7b"))
3+ (memory 1 (segment 0 "\7b\c4\06\2d\4a\6f\9c\bd\bb\29\68\88\72\a1\04\89\01\c1\48\5d"))
44 (import $balance "ethereum" "getBalance" (param i32 i32))
55 (export "a" memory)
66 (export "test" 0)
77 (func
tests/interface/caller.wastView
@@ -8,9 +8,9 @@
88 (func
99 (block
1010 ;; loads the caller into memory
1111 (call_import $caller (i32.const 0))
12- (if (i64.eq (i64.load (i32.const 0)) (i64.const 0x72a1048901c1485d))
12+ (if (i64.eq (i64.load (i32.const 0)) (i64.const 0xbd9c6f4a2d06c47b))
1313 (return)
1414 )
1515 (unreachable)
1616 )
tests/interface/coinbase.wastView
@@ -8,9 +8,9 @@
88 (func
99 (block
1010 ;; loads the coinbase into memory
1111 (call_import $coinbase (i32.const 0))
12- (if (i64.eq (i64.load (i32.const 0)) (i64.const 0x72a1048901c1485d)) ;; big endian
12+ (if (i64.eq (i64.load (i32.const 0)) (i64.const 0xbd9c6f4a2d06c47b))
1313 (return)
1414 )
1515 (unreachable)
1616 )
tests/interface/origin.wastView
@@ -8,9 +8,9 @@
88 (func
99 (block
1010 ;; loads the address into memory
1111 (call_import $origin (i32.const 0))
12- (if (i64.eq (i64.load (i32.const 0)) (i64.const 0x72a1048901c1485d))
12+ (if (i64.eq (i64.load (i32.const 0)) (i64.const 0xbd9c6f4a2d06c47b))
1313 (return)
1414 )
1515 (unreachable)
1616 )
transaction.jsView
@@ -36,16 +36,16 @@
3636 return Uint8Array.from(this._tx.data)
3737 }
3838
3939 get from () {
40- return new Address(this._tx.getSenderAddress())
40+ return new Address('0x' + this._tx.getSenderAddress().toString('hex'))
4141 }
4242
4343 get to () {
4444 if (this._tx.to.length === 0) {
4545 return new Address('0x0000000000000000000000000000000000000000')
4646 }
47- return new Address(this._tx.to)
47+ return new Address('0x' + this._tx.to.toString('hex'))
4848 }
4949
5050 get isSend () {
5151 }
u256.jsView
@@ -1,19 +1,27 @@
11 const BN = require('bn.js')
22 const ethUtil = require('ethereumjs-util')
33
4-module.exports = class U256 {
4+const U256 = module.exports = class U256 {
55 constructor (value) {
6- // This is the case when data is copied from WASM
7- if (value instanceof Uint8Array) {
8- this._value = new BN(value, 16, 'le')
9- } else if ((typeof value === 'string') && ethUtil.isHexPrefixed(value)) {
6+ // bn.js still doesn't support hex prefixes...
7+ if ((typeof value === 'string') && ethUtil.isHexPrefixed(value)) {
108 this._value = new BN(ethUtil.stripHexPrefix(value), 16)
119 } else {
1210 this._value = new BN(value, 10)
1311 }
1412 }
1513
14+ // This assumes Uint8Array in LSB (WASM code)
15+ static fromMemory (value) {
16+ return new U256(new BN(value, 16, 'le'))
17+ }
18+
19+ // This assumes Uint8Array in LSB (WASM code)
20+ toMemory (width) {
21+ return this._value.toBuffer('le', width || 32)
22+ }
23+
1624 toString (radix = 10) {
1725 if (radix === 16) {
1826 return '0x' + this._value.toString(16)
1927 }
@@ -23,9 +31,9 @@
2331 toBuffer (width) {
2432 if (width <= 0 || width > 32) {
2533 throw new Error('Invalid U256 width')
2634 }
27- return this._value.toBuffer('le', width || 32)
35+ return this._value.toBuffer('be', width || 32)
2836 }
2937
3038 sub (u256) {
3139 return new U256(this._value.sub(u256._value))

Built with git-ssb-web