Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugger improvements 4 #1018

Closed
wants to merge 52 commits into from
Closed

Conversation

Jither
Copy link
Contributor

@Jither Jither commented Dec 5, 2021

As discussed, and referenced in #1016

Minor compared to previous debugger-improvements PR's, but a relatively important step for Chrome devtools protocol and/or Debug Adapter Protocol (VSCode).

Summary of changes

bold areas = breaking changes (breaking for debugger implementations, that is)

  • Event (Parsed) on engine for notification of when scripts have been through Esprima. This avoids the need for double parsing, because debugger implementations are likely to need the AST too (for e.g. determining proper locations for breakpoints).
  • Closer to Chromium devtools scopes: Splitting global scope into Global (Object Environment Record) and Script (Declarative Environment Record).
  • Debug scopes now hold a reference to the BindingObject for OER's - this eases inspection a lot in devtools, and probably (not checked yet) in Debug Adapter Protocol (VSCode) - because the BindingObject can simply be serialized for the protocol, rather than copying every single property to a new object and serializing that.
  • Breakpoints:
    • Only allows a single breakpoint at a given location (source/line/column) - hence, API is now "Set" instead of "Add".
    • Requires the breakpoint to be set at exactly the correct line/column (this allows faster matching, column breakpoints, and more).
    • Additional BreakPoint tests
    • Breakpoint class unsealed - it's useful for a debugger to be able to add additional data to the class. As such, the data important to the Jint side (other than condition - source, line, column) has moved into a sealed BreakLocation class.
  • Fixed tests broken by addition of Script scope and new breakpoint semantics.
  • Fixed inspection of uninitialized block scoped bindings (const/let)

Breakpoints still need work on the API (and probably implementation) side.

BindingObject property on Global and With scopes (mainly for devtools for now, but may be useful for VSCode DebugAdapter)
Only allows a single breakpoint at a given location (source/line/column) - hence, API is now "Set" instead of "Add".
Requires the breakpoint to be set at *exactly* the correct line/column (this allows faster matching, column breakpoints, and more).
Fixed tests broken by addition of Script scope and new breakpoint semantics.
Breakpoints still need work on the API (and probably implementation) side.
Additional BreakPoint tests
/// BreakLocation is a combination of an Esprima position (line and column) and a source (path or identifier of script).
/// Like Esprima, first column is 0 and first line is 1.
/// </summary>
public sealed record BreakLocation
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, if you want really make the code short, this should also work:

public sealed record BreakLocation(string Source, int Line, int Column)
{
    public BreakLocation(int line, int column) : this(null, line, column)
    {
    }

    public BreakLocation(string source, Esprima.Position position) : this(source, position.Line, position.Column)
    {
    }
}

These are of course personal preferences and not important for this PR, I've just really liked the expressiveness they have 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan (yet) of positional records, when the properties aren't self-evidently positional (emphasized here by the multiple constructors). But that's also just philosophy. May change it anyway. 😉

public sealed class BreakPoint
// BreakPoint is not sealed. It's useful to be able to add additional properties on a derived BreakPoint class (e.g. a breakpoint ID
// or breakpoint type) but still let it be managed by Jint's breakpoint collection.
public class BreakPoint
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

record could also work here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the same reason as above, not sure record adds something to BreakPoint - value equality, yes, but not entirely sure if value equality is even appropriate for a breakpoint. 🙂 (But that's just my impaired brain speaking)


namespace Jint
{
public class SourceParsedEventArgs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be sealed if not an extension point, maybe even a record 😉

Copy link
Contributor Author

@Jither Jither Dec 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sealed, absolutely. But philosophy-wise, here I'm quite sure record doesn't add much, though - can't remember ever needing to compare two eventargs. 🙂 (and since some EventArgs may oftentimes need to be mutable, I'll generalize/take a stance (for now) and say no EventArgs should be records, even when they're immutable 😉).

Jither and others added 15 commits December 9, 2021 09:44
Co-authored-by: Sébastien Ros <sebastienros@gmail.com>
Co-authored-by: lph <philipp.luethi@sva-ag.ch>
Co-authored-by: Marko Lahma <marko.lahma@gmail.com>
Co-authored-by: Sébastien Ros <sebastienros@gmail.com>
Issues:
* function-valued properties should be excluded entirely from JSON, not serialized as objects
* proxies to functions are not handled correctly

Changes:
* Remove extraneous early exit case (JsonSerializer line 175) which diverges from the algorithm in the spec (https://tc39.es/ecma262/#sec-serializejsonproperty). This appears to correct the serialization of function-valued properties, but unmasks another issue where ProxyInstance is mistakenly treated as callable even when target is not
* Change "value is ICallbable" test to "value.IsCallable" so that serialization of ProxyInstance is handled correctly (according to the spec proxies are callable only if the target is callable - https://tc39.es/ecma262/#sec-proxycreate)
* Add test to verify serialization of function-valued properties
Co-authored-by: Jonathan Resnick <jonathan.resnick@synaptivemedical.com>
lahma and others added 23 commits January 14, 2022 12:24
* fix dictionary missing key property access
* fix destructuring with function arg in strict mode
* fix passing functions to cs side
* fix Array.sort crashing script in debug mode
* fix indexer property being enumerated
* script functions should resolve to same reference
* fix construct crashing without context
BindingObject property on Global and With scopes (mainly for devtools for now, but may be useful for VSCode DebugAdapter)
Only allows a single breakpoint at a given location (source/line/column) - hence, API is now "Set" instead of "Add".
Requires the breakpoint to be set at *exactly* the correct line/column (this allows faster matching, column breakpoints, and more).
Fixed tests broken by addition of Script scope and new breakpoint semantics.
Breakpoints still need work on the API (and probably implementation) side.
Additional BreakPoint tests
@Jither
Copy link
Contributor Author

Jither commented Mar 3, 2022

Hmmm... Judging from that list of commits, I clearly messed up when fetching the upstream. I'll probably manually rebase the changes onto the latest dev, when they're done - since so far, they don't interfere at all with the rest of the engine.

Jither added 2 commits March 6, 2022 19:12
Test case for failing breakpoint conditions (currently they, and other evaluations during paused state) reset the call stack (and probably other things).
Documentation of SourceParsedEventArgs
Renamed DebugHandler OnBreak event to clarify that it only handles debugger statements.
Added PauseType (Break/Step/DebuggerStatement) to DebugInformation to allow debuggers to distinguish between breaks and debugger statements.
@Jither
Copy link
Contributor Author

Jither commented Mar 7, 2022

Messed up history - will open a new clean slate, based on latest main

@Jither Jither closed this Mar 7, 2022
@Jither Jither deleted the debugger-improvements-4 branch March 7, 2022 20:18
@Jither Jither mentioned this pull request Mar 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants