|
|
@ -14,29 +14,39 @@ class RefType { |
|
|
|
* |
|
|
|
* |
|
|
|
* @param {Int} stackDepth - position of the type in the stack |
|
|
|
* @param {Int} stackDepth - position of the type in the stack |
|
|
|
* @param {Array} stack - stack |
|
|
|
* @param {Array} stack - stack |
|
|
|
* @return {String} - memory |
|
|
|
* @param {String} - memory |
|
|
|
* @return {Object} - storage |
|
|
|
* @param {Object} - storage |
|
|
|
|
|
|
|
* @return {Object} decoded value |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
decodeFromStack (stackDepth, stack, memory, storage) { |
|
|
|
decodeFromStack (stackDepth, stack, memory, storage) { |
|
|
|
if (stack.length - 1 < stackDepth) { |
|
|
|
if (stack.length - 1 < stackDepth) { |
|
|
|
return { error: '<decoding failed - stack underflow ' + stackDepth + '>' } |
|
|
|
return { error: '<decoding failed - stack underflow ' + stackDepth + '>' } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!storage) { |
|
|
|
|
|
|
|
storage = {} // TODO this is a fallback, should manage properly locals store in storage
|
|
|
|
|
|
|
|
} |
|
|
|
var offset = stack[stack.length - 1 - stackDepth] |
|
|
|
var offset = stack[stack.length - 1 - stackDepth] |
|
|
|
offset = parseInt(offset, 16) |
|
|
|
offset = parseInt(offset, 16) |
|
|
|
return decodeInternal(this, offset, memory, storage) |
|
|
|
if (this.storageStore()) { |
|
|
|
|
|
|
|
return this.decodeFromStorage({ offset: 0, slot: offset }, storage) |
|
|
|
|
|
|
|
} else if (this.memoryStore()) { |
|
|
|
|
|
|
|
return this.decodeFromMemoryInternal(offset, memory) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return { error: '<decoding failed - no decoder for ' + this.location + '>' } |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* decode the type with the @arg offset location from the memory or storage |
|
|
|
* decode the type from the memory |
|
|
|
* |
|
|
|
* |
|
|
|
* @param {Int} offset - position of the type in the memory |
|
|
|
* @param {Int} offset - position of the ref of the type in memory |
|
|
|
* @return {String} - memory |
|
|
|
* @param {String} memory - memory |
|
|
|
* @return {Object} - storage |
|
|
|
* @return {Object} decoded value |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
decode (offset, memory, storage) { |
|
|
|
decodeFromMemory (offset, memory) { |
|
|
|
offset = memory.substr(2 * offset, 64) |
|
|
|
offset = memory.substr(2 * offset, 64) |
|
|
|
offset = parseInt(offset, 16) |
|
|
|
offset = parseInt(offset, 16) |
|
|
|
return decodeInternal(this, offset, memory, storage) |
|
|
|
return this.decodeFromMemoryInternal(offset, memory) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -56,20 +66,6 @@ class RefType { |
|
|
|
memoryStore () { |
|
|
|
memoryStore () { |
|
|
|
return this.location.indexOf('memory') === 0 |
|
|
|
return this.location.indexOf('memory') === 0 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function decodeInternal (self, offset, memory, storage) { |
|
|
|
|
|
|
|
if (!storage) { |
|
|
|
|
|
|
|
storage = {} // TODO this is a fallback, should manage properly locals store in storage
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (self.storageStore()) { |
|
|
|
|
|
|
|
return self.decodeFromStorage({ offset: 0, slot: offset }, storage) |
|
|
|
|
|
|
|
} else if (self.memoryStore()) { |
|
|
|
|
|
|
|
return self.decodeFromMemory(offset, memory) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return { error: '<decoding failed - no decoder for ' + self.location + '>' } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
module.exports = RefType |
|
|
|
module.exports = RefType |
|
|
|