Comments (9)
The behavior of JMP*
is not changed. I think the comments should be modified.
from neo-vm.
Yes behavior of JMP*
is the same. 👍
from neo-vm.
JMP 0000
is an infinite loop.
from neo-vm.
When I wrote that, it made sense to me 🤔 sorry about that 😝
In fact code has changed recently, so it's even clearer now perhaps (although logic should be the same... let's check).
This is an infinite loop code:
public static void Main()
{
while(true);
}
The generated NVM is: 00c56b620000
, which means:
00 PUSH0 #An empty array of bytes is pushed onto the stack
c5 NEWARRAY #
6b TOALTSTACK # Puts the input onto the top of the alt stack. Removes it from the main stack.
62 JMP 0000 # 0
So, here's the instruction counter i.
^00c56b620000
i=0: PUSH0
00^c56b620000
i=1: NEWARRAY
00c5^6b620000
i=2: TOALTSTACK
00c56b^620000
i=3: JMP
Now, at this point, for JMP, it must read 2 bytes more (n=0x0000):
00c56b620000^
Offset value n
is zero (and i=5). So, if it jumped i+n=5+0=5, it would be at the same place, and read the next instruction (after the while
).
So, instead, it must jump to i+n-3=5+0-3=2
(the same state before reading the JMP). What happened now is that instruction has already been processed in this "new" format, so jump can go directly to i+n (but i
is probably still 2 at this point). It is just important to know that the jump reference is related to the start position of JMP instruction, not the end.
There are some test cases here, you can take a look just to make sure everything is fine (if we don't have one specific like this, we can make one to be sure it is fine ;) )
Source: https://neocompiler.io
from neo-vm.
@igormcoelho ,
Thanks for detail explanation which mirror the description of the opcode JMP
. However I am not sure that the current code does what you said. Try to debug the following code:
public void Test()
{
ExecutionEngine e = new ExecutionEngine(null, new Crypto());
e.LoadScript("00c56b620000".FromHexString());
e.Execute();
}
As you can see the instruction pointer is set again to 3 forever because fvalue=true
and n=0
.
In my opinion either we should change the code to reflect the description of the opcodes or viceversa:
The current code mirror this description in my opinion:
/// Reads a 2-byte value n and a jump is performed to relative position n.
/// </summary>
JMP = 0x62,
/// <summary>
/// A boolean value b is taken from main stack and reads a 2-byte value n, if b is True then a jump is performed to relative position n. If b is False advance the instruction pointer of 3
/// </summary>
JMPIF = 0x63,
/// <summary>
/// A boolean value b is taken from main stack and reads a 2-byte value n, if b is False then a jump is performed to relative position n. If b is True advance the instruction pointer of 3.
/// </summary>
JMPIFNOT = 0x64,
So the current logic is not the same as the old logic.
from neo-vm.
Sorry @dauTT , I don't have a C# debugger.. hahaha so I only have my eyes for these things :P
Anyway, if value is 3 on instruction counter, 3 represents the beggining of JMP opcode. So, a next jump to position 3 would keep it in the same position, right?
I agree, we need to update the description, specially now that we don't have an explicit subtraction (we had that before).
from neo-vm.
The old logic seems to me more corret than the current one: 😄
https://github.com/neo-project/neo-vm/blob/v2.4.0/src/neo-vm/ExecutionEngine.cs
case OpCode.JMP:
case OpCode.JMPIF:
case OpCode.JMPIFNOT:
{
int offset = context.OpReader.ReadInt16();
offset = context.InstructionPointer + offset - 3;
if (offset < 0 || offset > context.Script.Length)
{
State |= VMState.FAULT;
return;
}
bool fValue = true;
if (opcode > OpCode.JMP)
{
CheckStackSize(false, -1);
fValue = context.EvaluationStack.Pop().GetBoolean();
if (opcode == OpCode.JMPIFNOT)
fValue = !fValue;
}
if (fValue)
context.InstructionPointer = offset;
break;
}
and I think we would need to roll back to the old logic to maintain backward compatibility.
from neo-vm.
No man... no rolling back, that's why we have tests now 😆
Are you sure there's no test here to verify a similar case?
Let's try a simple if-else
structure and see if the correct value is returned on stack.
from neo-vm.
Good. So, how can we explain it better on comment? :)
from neo-vm.
Related Issues (20)
- Shallow-copy problem for OrderedDictionary.CopyTo in case of Array & Map type HOT 6
- Add 'utf8Size' opcode HOT 4
- Script checks are incomplete
- Can I integrate this vm in to my custom projects? HOT 1
- Efficient way to pass Map type to contract method? OpCode.PACKMAP? HOT 1
- Adapt code documentation of UNPACK opcode
- ReferenceCounter can become negative HOT 18
- Is this `MEMCPY` expected to push nothing to the stack?
- ScriptBuilder should have an emitPush overload that takes a ReadOnlySpan<byte>
- How to customize an interface in interoperation service layer HOT 3
- Presssure test on v3.3.0 cause execution failed HOT 1
- v3.3.0 need more than 30 hours for syncing mainnet even it's just about 1.7million blocks HOT 2
- What is the purpose of the second assert of this test? HOT 1
- Instruction pointer reading PUSHDATA4 operand size as *signed* int32 HOT 1
- Missing push in APPEND?
- EmitPush(bool) should convert stackitem to right type
- Buffer to Integer conversion inconsistency HOT 1
- Override GetString for Buffer/ByteString ? HOT 4
- Set Operation in a Get Function HOT 2
- Add Equatable for StackItem
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from neo-vm.