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

[Merged by Bors] - Interner support in the parser #1765

Closed
wants to merge 5 commits into from

Conversation

Razican
Copy link
Member

@Razican Razican commented Dec 27, 2021

This builds on top of #1758 to try to bring #1763 to life.

Something that should probably be done here would be to convert JsString to a Sym internally. Then, further optimizations could be done adding common strings to a custom interner type (those that we know statically).

This is definitely work in progress, but I would like to have feedback on the API, and feel free to contribute.

@Razican Razican added enhancement New feature or request help wanted Extra attention is needed performance Performance related changes and issues memory PRs and Issues related to the memory management or memory footprint. ast Issue surrounding the abstract syntax tree Internal Category for changelog labels Dec 27, 2021
@Razican Razican changed the title Feature/parser interner Interner support in the parser Dec 27, 2021
@RageKnify
Copy link
Member

I went through most files (skipped test files that looked like simple refactorings). Looks good to me so far.

@Razican Razican force-pushed the feature/parser_interner branch 2 times, most recently from 786ec51 to f9e81a9 Compare January 1, 2022 11:48
@Razican
Copy link
Member Author

Razican commented Jan 1, 2022

I got this to compile, but it seems I made a mistake somewhere, because it's failing the tests.

@Razican Razican marked this pull request as ready for review January 1, 2022 18:57
@Razican
Copy link
Member Author

Razican commented Jan 1, 2022

All tests are now passing in my laptop, still Test262 results need to be checked, and of course, any performance issue. I didn't replace JsString with anything else, since the idea here was to use the interner only in the parsing phase. I added some static strings, the ones being used by us with get_or_intern_static(), but, should we add the whole list here too?

@Razican Razican changed the base branch from feature/interner to main January 2, 2022 13:09
@Razican Razican changed the base branch from main to feature/interner January 3, 2022 09:48
@Razican Razican changed the base branch from feature/interner to main January 3, 2022 09:48
@github-actions
Copy link

github-actions bot commented Jan 3, 2022

Test262 conformance changes

VM implementation

Test result main count PR count difference
Total 87,200 87,200 0
Passed 40,828 40,828 0
Ignored 19,493 19,493 0
Failed 26,879 26,879 0
Panics 0 0 0
Conformance 46.82% 46.82% 0.00%

@codecov
Copy link

codecov bot commented Jan 3, 2022

Codecov Report

Merging #1765 (eb61895) into main (80794e5) will decrease coverage by 0.20%.
The diff coverage is 61.69%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1765      +/-   ##
==========================================
- Coverage   55.72%   55.51%   -0.21%     
==========================================
  Files         201      201              
  Lines       17336    17420      +84     
==========================================
+ Hits         9660     9671      +11     
- Misses       7676     7749      +73     
Impacted Files Coverage Δ
boa/src/builtins/console/mod.rs 25.62% <0.00%> (-0.33%) ⬇️
boa/src/builtins/dataview/mod.rs 6.77% <ø> (ø)
boa/src/builtins/map/map_iterator.rs 95.12% <ø> (ø)
boa/src/builtins/set/set_iterator.rs 86.48% <ø> (ø)
boa/src/property/mod.rs 60.81% <ø> (ø)
boa/src/realm.rs 100.00% <ø> (ø)
...x/ast/node/declaration/async_generator_expr/mod.rs 28.57% <0.00%> (+7.14%) ⬆️
.../syntax/ast/node/declaration/generator_expr/mod.rs 28.57% <0.00%> (+7.14%) ⬆️
boa/src/syntax/ast/node/yield/mod.rs 30.76% <0.00%> (ø)
boa/src/syntax/parser/expression/update.rs 40.62% <0.00%> (ø)
... and 101 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 80794e5...eb61895. Read the comment docs.

@Razican
Copy link
Member Author

Razican commented Jan 6, 2022

Benchmarks

┌─────────┬──────────────────────────────────────────────┬──────────────────────┬─────────────────────┬────────────┐
│ (index) │                     name                     │   changesDuration    │   masterDuration    │ difference │
├─────────┼──────────────────────────────────────────────┼──────────────────────┼─────────────────────┼────────────┤
│    0    │      'Arithmetic operations (Compiler)'      │    '967.2±0.70ns'    │ '**929.2±1.16ns**'  │   '+4.0'   │
│    1    │     'Arithmetic operations (Execution)'      │     '2.2±0.02µs'     │  '**2.2±0.01µs**'   │   '+1.0'   │
│    2    │       'Arithmetic operations (Parser)'       │     '6.2±0.01µs'     │  '**5.8±0.01µs**'   │   '+9.0'   │
│    3    │          'Array access (Compiler)'           │   '1442.8±1.62ns'    │ '**1310.1±3.24ns**' │   '+10'    │
│    4    │          'Array access (Execution)'          │    '10.7±0.03µs'     │    '10.7±0.11µs'    │   '0.0'    │
│    5    │           'Array access (Parser)'            │    '13.4±0.01µs'     │  '**12.2±0.04µs**'  │   '+10'    │
│    6    │         'Array creation (Compiler)'          │     '2.2±0.01µs'     │ '**1956.2±9.25ns**' │   '+14'    │
│    7    │         'Array creation (Execution)'         │     '3.2±0.00ms'     │    '3.2±0.00ms'     │   '0.0'    │
│    8    │          'Array creation (Parser)'           │    '15.0±0.02µs'     │  '**13.6±0.02µs**'  │   '+10'    │
│    9    │            'Array pop (Compiler)'            │     '7.3±0.00µs'     │  '**6.5±0.04µs**'   │   '+13'    │
│   10    │           'Array pop (Execution)'            │   '1339.6±4.32µs'    │   '1333.8±3.59µs'   │   '0.0'    │
│   11    │             'Array pop (Parser)'             │    '159.7±0.15µs'    │ '**143.9±0.08µs**'  │   '+11'    │
│   12    │      'Boolean Object Access (Compiler)'      │     '2.0±0.00µs'     │ '**1595.6±2.50ns**' │   '+27'    │
│   13    │     'Boolean Object Access (Execution)'      │   '**6.8±0.02µs**'   │    '7.1±0.02µs'     │   '-3.8'   │
│   14    │       'Boolean Object Access (Parser)'       │    '16.0±0.03µs'     │  '**14.4±0.01µs**'  │   '+11'    │
│   15    │            'Clean js (Compiler)'             │     '5.5±0.02µs'     │  '**4.5±0.02µs**'   │   '+22'    │
│   16    │            'Clean js (Execution)'            │ '**1445.8±14.68µs**' │   '1466.8±8.27µs'   │  '-0.99'   │
│   17    │             'Clean js (Parser)'              │    '32.7±0.05µs'     │  '**29.3±0.05µs**'  │   '+12'    │
│   18    │                'Create Realm'                │    '339.5±3.84ns'    │ '**337.1±0.42ns**'  │   '+1.0'   │
│   19    │ 'Dynamic Object Property Access (Compiler)'  │   '1879.7±2.03ns'    │ '**1650.5±7.25ns**' │   '+14'    │
│   20    │ 'Dynamic Object Property Access (Execution)' │     '7.1±0.02µs'     │    '7.1±0.04µs'     │   '0.0'    │
│   21    │  'Dynamic Object Property Access (Parser)'   │    '12.2±0.02µs'     │  '**10.8±0.01µs**'  │   '+13'    │
│   22    │            'Fibonacci (Compiler)'            │     '2.8±0.01µs'     │  '**2.6±0.01µs**'   │   '+9.0'   │
│   23    │           'Fibonacci (Execution)'            │     '2.9±0.00ms'     │  '**2.8±0.00ms**'   │   '+3.0'   │
│   24    │             'Fibonacci (Parser)'             │    '18.4±0.02µs'     │  '**16.3±0.02µs**'  │   '+13'    │
│   25    │            'For loop (Compiler)'             │     '2.4±0.01µs'     │  '**2.1±0.01µs**'   │   '+14'    │
│   26    │            'For loop (Execution)'            │    '46.0±0.52µs'     │  '**45.6±0.22µs**'  │   '+1.0'   │
│   27    │             'For loop (Parser)'              │    '15.6±0.02µs'     │  '**14.1±0.07µs**'  │   '+11'    │
│   28    │             'Mini js (Compiler)'             │     '5.4±0.02µs'     │  '**4.4±0.02µs**'   │   '+23'    │
│   29    │            'Mini js (Execution)'             │ '**1335.0±7.98µs**'  │   '1358.3±8.80µs'   │   '-2.0'   │
│   30    │              'Mini js (Parser)'              │    '28.6±0.03µs'     │  '**25.8±0.04µs**'  │   '+11'    │
│   31    │      'Number Object Access (Compiler)'       │   '1665.3±1.15ns'    │ '**1341.2±0.76ns**' │   '+24'    │
│   32    │      'Number Object Access (Execution)'      │   '**5.4±0.01µs**'   │    '5.6±0.01µs'     │   '-3.8'   │
│   33    │       'Number Object Access (Parser)'        │    '12.5±0.02µs'     │  '**11.5±0.02µs**'  │   '+9.0'   │
│   34    │         'Object Creation (Compiler)'         │   '1476.5±1.31ns'    │ '**1336.8±4.95ns**' │   '+10'    │
│   35    │        'Object Creation (Execution)'         │     '6.4±0.03µs'     │  '**6.4±0.03µs**'   │   '+1.0'   │
│   36    │          'Object Creation (Parser)'          │    '10.5±0.01µs'     │  '**9.4±0.01µs**'   │   '+12'    │
│   37    │             'RegExp (Compiler)'              │   '1815.9±1.28ns'    │ '**1578.9±7.07ns**' │   '+15'    │
│   38    │             'RegExp (Execution)'             │  '**13.1±0.04µs**'   │    '13.2±0.05µs'    │  '-0.99'   │
│   39    │              'RegExp (Parser)'               │    '11.5±0.06µs'     │  '**10.2±0.01µs**'  │   '+14'    │
│   40    │         'RegExp Creation (Compiler)'         │   '1494.7±3.52ns'    │ '**1351.1±3.92ns**' │   '+11'    │
│   41    │        'RegExp Creation (Execution)'         │  '**10.1±0.03µs**'   │    '10.3±0.03µs'    │  '-0.99'   │
│   42    │          'RegExp Creation (Parser)'          │     '9.6±0.02µs'     │  '**8.5±0.01µs**'   │   '+13'    │
│   43    │         'RegExp Literal (Compiler)'          │   '1816.6±2.06ns'    │ '**1587.3±6.94ns**' │   '+14'    │
│   44    │         'RegExp Literal (Execution)'         │  '**13.0±0.05µs**'   │    '13.2±0.04µs'    │  '-0.99'   │
│   45    │          'RegExp Literal (Parser)'           │     '9.3±0.01µs'     │  '**8.2±0.02µs**'   │   '+13'    │
│   46    │     'RegExp Literal Creation (Compiler)'     │   '1496.6±3.19ns'    │ '**1344.1±3.48ns**' │   '+11'    │
│   47    │    'RegExp Literal Creation (Execution)'     │  '**10.1±0.03µs**'   │    '10.2±0.03µs'    │  '-0.99'   │
│   48    │      'RegExp Literal Creation (Parser)'      │     '7.2±0.06µs'     │  '**6.4±0.01µs**'   │   '+13'    │
│   49    │  'Static Object Property Access (Compiler)'  │   '1570.1±1.53ns'    │ '**1390.7±3.26ns**' │   '+13'    │
│   50    │ 'Static Object Property Access (Execution)'  │   '**6.6±0.03µs**'   │    '6.6±0.03µs'     │  '-0.99'   │
│   51    │   'Static Object Property Access (Parser)'   │    '11.2±0.02µs'     │  '**10.0±0.01µs**'  │   '+12'    │
│   52    │      'String Object Access (Compiler)'       │     '2.5±0.00µs'     │ '**1851.5±3.11ns**' │   '+33'    │
│   53    │      'String Object Access (Execution)'      │   '**8.7±0.02µs**'   │    '9.1±0.04µs'     │   '-4.8'   │
│   54    │       'String Object Access (Parser)'        │    '15.9±0.02µs'     │  '**14.2±0.01µs**'  │   '+12'    │
│   55    │        'String comparison (Compiler)'        │     '2.5±0.00µs'     │  '**2.1±0.01µs**'   │   '+21'    │
│   56    │       'String comparison (Execution)'        │     '7.7±0.02µs'     │  '**7.6±0.03µs**'   │   '+1.0'   │
│   57    │         'String comparison (Parser)'         │    '12.5±0.02µs'     │  '**11.1±0.01µs**'  │   '+13'    │
│   58    │      'String concatenation (Compiler)'       │   '1792.0±1.49ns'    │ '**1566.3±7.54ns**' │   '+14'    │
│   59    │      'String concatenation (Execution)'      │   '**6.3±0.02µs**'   │    '6.5±0.02µs'     │   '-2.0'   │
│   60    │       'String concatenation (Parser)'        │     '8.6±0.01µs'     │  '**7.6±0.01µs**'   │   '+13'    │
│   61    │           'String copy (Compiler)'           │   '1264.6±1.59ns'    │ '**1134.9±5.81ns**' │   '+11'    │
│   62    │          'String copy (Execution)'           │     '5.6±0.02µs'     │    '5.6±0.02µs'     │   '0.0'    │
│   63    │            'String copy (Parser)'            │     '6.4±0.01µs'     │  '**5.7±0.02µs**'   │   '+12'    │
│   64    │             'Symbols (Compiler)'             │    '808.1±2.08ns'    │ '**755.0±1.54ns**'  │   '+7.0'   │
│   65    │            'Symbols (Execution)'             │     '5.2±0.01µs'     │    '5.2±0.02µs'     │   '0.0'    │
│   66    │              'Symbols (Parser)'              │     '4.8±0.01µs'     │  '**4.4±0.01µs**'   │   '+10'    │
└─────────┴──────────────────────────────────────────────┴──────────────────────┴─────────────────────┴────────────┘

Copy link
Member

@raskad raskad left a comment

Choose a reason for hiding this comment

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

Finally got around to review this. Looks really nice. I only found two things.

I noticed, that there are a lot of interner.resolve(s).expect("string disappeared") calls. Do you think it would make sense to have a interner.resolve_expect(s) helper?

boa_interner/src/lib.rs Outdated Show resolved Hide resolved
boa/src/syntax/lexer/regex.rs Outdated Show resolved Hide resolved
@RageKnify
Copy link
Member

I agree with raskad, a resolve_expect() method seems worth it.

@Razican
Copy link
Member Author

Razican commented Jan 12, 2022

Makes sense, yes, especially now that we have our own interner. In any case, I still see a performance degradation, so maybe We should extend the usage in the compiler/vm and see how it goes

@raskad
Copy link
Member

raskad commented Jan 12, 2022

Makes sense, yes, especially now that we have our own interner. In any case, I still see a performance degradation, so maybe We should extend the usage in the compiler/vm and see how it goes

I actually think the benchmark table is wrong.
If you look at the logs for example you see the debug shows a performance gain:

[command]/home/runner/.cargo/bin/critcmp base changes
group                                         base                                   changes
-----                                         ----                                   -------
 Arithmetic operations (Parser)                1.09      6.2±0.01µs        ? ?/sec    1.00      5.8±0.01µs        ? ?/sec

But the table below seems to switch base and change values:

┌─────────┬──────────────────────────────────────────────┬──────────────────────┬─────────────────────┬────────────┐
│ (index) │                     name                     │   changesDuration    │   masterDuration    │ difference │
├─────────┼──────────────────────────────────────────────┼──────────────────────┼─────────────────────┼────────────┤
│    2    │       'Arithmetic operations (Parser)'       │     '6.2±0.01µs'     │  '**5.8±0.01µs**'   │   '+9.0'   │

I also ran cargo bench locally for main and this branch and it showed a performance gain for almost all benchmarks.

@raskad
Copy link
Member

raskad commented Jan 18, 2022

@Razican I rebased and implemented the fixes. Imo we can merge this into main.

@Razican
Copy link
Member Author

Razican commented Jan 19, 2022

@Razican I rebased and implemented the fixes. Imo we can merge this into main.

Did this add the RegexpFlags to the lexer? The only limitation with this is that it will not respect the input flag order when printing it out, and that it will have to re-convert it to a string when calling the RegExp constructor, but I don't know what to think about it, or its performance.

@raskad
Copy link
Member

raskad commented Jan 19, 2022

@Razican I rebased and implemented the fixes. Imo we can merge this into main.

Did this add the RegexpFlags to the lexer? The only limitation with this is that it will not respect the input flag order when printing it out, and that it will have to re-convert it to a string when calling the RegExp constructor, but I don't know what to think about it, or its performance.

I think the printing order is ok. This is the node output for example:

> /.*/gmi
/.*/gim

@Razican
Copy link
Member Author

Razican commented Jan 22, 2022

I think the printing order is ok. This is the node output for example:


> /.*/gmi

/.*/gim

Yep, that's what I meant, it doesn't preserve the original order. It's not critical, but might be something we want.

In any case, I think this is good for now. We might want to optimize this by having a specific RegexLiteral node at some point, instead of converting it back to a string.

@Razican
Copy link
Member Author

Razican commented Jan 23, 2022

Benchmarks (properly switching the base):

(index) name Main PR difference
0 Arithmetic operations (Compiler) 979.2±0.64ns 951.2±5.37ns -3.0%
1 Arithmetic operations (Execution) 2.2±0.01µs 2.2±0.01µs +0.99%
2 Arithmetic operations (Parser) 6.5±0.02µs 5.8±0.03µs -13%
3 Array access (Compiler) 1436.4±0.99ns 1306.8±3.48ns -10%
4 Array access (Execution) 10.8±0.03µs 10.8±0.03µs -1.0%
5 Array access (Parser) 13.7±0.02µs 12.2±0.01µs -12%
6 Array creation (Compiler) 2.2±0.00µs 1951.3±9.32ns -14%
7 Array creation (Execution) 3.3±0.01ms 3.4±0.01ms +2.9%
8 Array creation (Parser) 15.5±0.02µs 13.5±0.06µs -14%
9 Array pop (Compiler) 6.8±0.00µs 6.4±0.03µs -7.0%
10 Array pop (Execution) 1362.0±4.18µs 1384.6±5.04µs +2.0%
11 Array pop (Parser) 156.5±0.35µs 143.4±0.13µs -9.0%
12 Boolean Object Access (Compiler) 2.0±0.00µs 1585.1±1.77ns -28%
13 Boolean Object Access (Execution) 6.7±0.01µs 7.0±0.02µs +3.8%
14 Boolean Object Access (Parser) 16.4±0.03µs 14.4±0.03µs -13%
15 Clean js (Compiler) 5.5±0.01µs 4.6±0.02µs -20%
16 Clean js (Execution) 1487.0±13.78µs 1508.8±13.20µs +0.99%
17 Clean js (Parser) 33.6±0.03µs 29.3±0.02µs -15%
18 Create Realm 352.6±1.56ns 334.6±0.19ns -5.0%
19 Dynamic Object Property Access (Compiler) 1899.9±2.59ns 1666.1±8.36ns -14%
20 Dynamic Object Property Access (Execution) 7.1±0.02µs 7.0±0.18µs -1.0%
21 Dynamic Object Property Access (Parser) 12.1±0.02µs 10.8±0.03µs -12%
22 Fibonacci (Compiler) 2.8±0.00µs 2.6±0.01µs -10%
23 Fibonacci (Execution) 2.8±0.00ms 2.8±0.00ms -2.0%
24 Fibonacci (Parser) 19.0±0.02µs 16.4±0.05µs -16%
25 For loop (Compiler) 2.5±0.00µs 2.1±0.01µs -18%
26 For loop (Execution) 47.1±0.25µs 46.1±0.12µs -2.0%
27 For loop (Parser) 16.3±0.03µs 14.0±0.03µs -16%
28 Mini js (Compiler) 5.4±0.02µs 4.5±0.02µs -21%
29 Mini js (Execution) 1365.3±7.85µs 1387.1±10.66µs +2.0%
30 Mini js (Parser) 29.9±0.26µs 25.7±0.05µs -17%
31 Number Object Access (Compiler) 1673.4±0.90ns 1331.9±1.36ns -26%
32 Number Object Access (Execution) 5.3±0.01µs 5.7±0.02µs +5.7%
33 Number Object Access (Parser) 12.9±0.03µs 11.2±0.03µs -15%
34 Object Creation (Compiler) 1504.0±24.31ns 1344.5±5.66ns -12%
35 Object Creation (Execution) 6.4±0.03µs 6.3±0.03µs -2.0%
36 Object Creation (Parser) 10.5±0.02µs 9.4±0.04µs -12%
37 RegExp (Compiler) 1845.1±2.34ns 1584.7±6.21ns -16%
38 RegExp (Execution) 13.5±0.03µs 13.4±0.03µs -1.0%
39 RegExp (Parser) 11.6±0.01µs 10.2±0.01µs -13%
40 RegExp Creation (Compiler) 1513.8±1.27ns 1341.1±5.40ns -13%
41 RegExp Creation (Execution) 10.3±0.04µs 10.2±0.02µs -1.0%
42 RegExp Creation (Parser) 9.7±0.01µs 8.6±0.04µs -13%
43 RegExp Literal (Compiler) 1845.8±1.84ns 1584.7±6.79ns -16%
44 RegExp Literal (Execution) 13.5±0.04µs 13.5±0.03µs 0.0%
45 RegExp Literal (Parser) 9.3±0.05µs 8.2±0.04µs -13%
46 RegExp Literal Creation (Compiler) 1517.8±7.62ns 1338.7±5.35ns -13%
47 RegExp Literal Creation (Execution) 10.3±0.03µs 10.2±0.07µs -1.0%
48 RegExp Literal Creation (Parser) 7.3±0.01µs 6.4±0.01µs -13%
49 Static Object Property Access (Compiler) 1602.6±3.47ns 1401.3±3.23ns -14%
50 Static Object Property Access (Execution) 6.7±0.02µs 6.5±0.02µs -2.0%
51 Static Object Property Access (Parser) 11.3±0.02µs 10.0±0.03µs -13%
52 String Object Access (Compiler) 2.5±0.00µs 1866.6±1.18ns -33%
53 String Object Access (Execution) 8.7±0.05µs 8.9±0.03µs +2.0%
54 String Object Access (Parser) 16.3±0.77µs 14.1±0.03µs -16%
55 String comparison (Compiler) 2.6±0.02µs 2.1±0.01µs -19%
56 String comparison (Execution) 7.8±0.03µs 7.4±0.03µs -5.0%
57 String comparison (Parser) 13.2±0.02µs 11.0±0.01µs -20%
58 String concatenation (Compiler) 1803.5±0.84ns 1577.9±6.96ns -14%
59 String concatenation (Execution) 6.5±0.02µs 6.3±0.03µs -4.0%
60 String concatenation (Parser) 9.0±0.02µs 7.6±0.01µs -18%
61 String copy (Compiler) 1262.0±0.52ns 1151.0±5.58ns -10%
62 String copy (Execution) 5.6±0.03µs 5.5±0.03µs -3.0%
63 String copy (Parser) 6.6±0.01µs 5.7±0.01µs -15%
64 Symbols (Compiler) 793.4±0.40ns 752.6±1.70ns -5.0%
65 Symbols (Execution) 5.3±0.02µs 5.1±0.01µs -4.0%
66 Symbols (Parser) 4.8±0.01µs 4.4±0.01µs -8.0%

Now things are looking much, much better

@Razican Razican added this to the v0.14.0 milestone Jan 23, 2022
@raskad
Copy link
Member

raskad commented Jan 23, 2022

bors r+

bors bot pushed a commit that referenced this pull request Jan 23, 2022
This builds on top of #1758 to try to bring #1763 to life.

Something that should probably be done here would be to convert `JsString` to a `Sym` internally. Then, further optimizations could be done adding common strings to a custom interner type (those that we know statically).

This is definitely work in progress, but I would like to have feedback on the API, and feel free to contribute.

Co-authored-by: raskad <32105367+raskad@users.noreply.github.com>
@bors
Copy link

bors bot commented Jan 23, 2022

Pull request successfully merged into main.

Build succeeded:

@bors bors bot changed the title Interner support in the parser [Merged by Bors] - Interner support in the parser Jan 23, 2022
@bors bors bot closed this Jan 23, 2022
@bors bors bot deleted the feature/parser_interner branch January 23, 2022 22:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ast Issue surrounding the abstract syntax tree enhancement New feature or request help wanted Extra attention is needed Internal Category for changelog memory PRs and Issues related to the memory management or memory footprint. performance Performance related changes and issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants