facebook / hermes

A JavaScript engine optimized for running React Native.
https://hermesengine.dev/
MIT License
9.41k stars 596 forks source link

[Debugger] Incorrect scope variable information for variable initialized in for-loop #1355

Open Beanyy opened 2 months ago

Beanyy commented 2 months ago

Bug Description

I'm running into some issues with a CDP Debugger (vscode-js-debug) connected to Hermes. Namely, when a variable is initialized in a for-loop, like the following:

for (let i=0; i <10; i++) {
    {... some code}
}

The variables in the for-loop initializer don't get updated in the debugger. I've narrowed down the root cause to Hermes sending two copies of the variable when Runtime.getProperties is called on the local scope and two copies of the variable are returned. One for the initial value, and one for the current value:

            {"configurable":false,"enumerable":true,"name":"i","value":{"type":"number","value":2}},
            {"configurable":false,"enumerable":true,"name":"i","value":{"type":"number","value":0}},

Digging through the code I think it may be how Hermes is transforming a for block, creating two copies of the variable initialized in the initializer const/let x = init; and const/let x = temp_x;: https://github.com/facebook/hermes/blob/55ccdf198078be78ac8c562b0087f561591aa950/lib/AST/BlockScopingTransformations.cpp#L227-L245

Moving the variable initialization outside of the for-loop fixes the issue.

Do you think you guys can help with this issue? Thanks!

Hermes git revision (if applicable): 7d9baea7221a1f69828764938fb5de0737419f6b React Native version: n/a OS: Android Platform: arm64-v8a

Steps To Reproduce

  1. Single step through the following code:
    for (let i=0; i <10; i++) {
    {... some code}
    }
  2. Each time Runtime.getProperties is called on the local scope object, it will return two copies of the variable i:
            {"configurable":false,"enumerable":true,"name":"i","value":{"type":"number","value":2}},
            {"configurable":false,"enumerable":true,"name":"i","value":{"type":"number","value":0}},

The Expected Behavior

Expected behaviour is for there to just be one copy of the for loop's initializer variable to be sent in the debugger info.

tmikov commented 2 months ago

Are you using the --block-scoping CLI option? It is experimental and unsupported - we have meanwhile switched to a completely different approach for implementing block scoping.

(With that said, we can take a look if this is something easily fixable)

Beanyy commented 1 month ago

Disabling block scoping resolved the issue I was seeing. Thanks for the help! How do I enable the new implementation of block scoping?

tmikov commented 1 month ago

@Beanyy the new implementation will be in the next major version (codename Static Hermes), which we are hoping to release as a drop-in replacement of Hermes by the middle of the year.