v8/test/debugger/debug/debug-break-class-fields.js

146 lines
4.9 KiB
JavaScript
Raw Normal View History

// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-public-fields --harmony-static-fields --allow-natives-syntax
Debug = debug.Debug
Debug.setListener(function() {});
class Y {
x = 1;
y = 2;
z = 3;
}
var initializer = %GetInitializerFunction(Y);
var b1, b2, b3;
// class Y {
// x = [B0]1;
// y = [B1]2;
// z = [B2]3;
// }
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
b1 = Debug.setBreakPoint(initializer, 1, 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") > 0);
Debug.clearBreakPoint(b1);
assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") === -1);
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
b2 = Debug.setBreakPoint(initializer, 2, 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B0]2;") > 0);
Debug.clearBreakPoint(b2);
assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B0]2;") === -1);
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
b3 = Debug.setBreakPoint(initializer, 3, 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B0]3") > 0);
Debug.clearBreakPoint(b3);
assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B0]3") === -1);
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
b1 = Debug.setBreakPoint(initializer, 1, 0);
b2 = Debug.setBreakPoint(initializer, 2, 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") > 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B1]2;") > 0);
Debug.clearBreakPoint(b1);
assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") === -1);
Debug.clearBreakPoint(b2);
assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B1]2;") === -1);
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
b1 = Debug.setBreakPoint(initializer, 1, 0);
b3 = Debug.setBreakPoint(initializer, 3, 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") > 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B1]3") > 0);
Debug.clearBreakPoint(b1);
assertTrue(Debug.showBreakPoints(initializer).indexOf("x = [B0]1;") === -1);
Debug.clearBreakPoint(b3);
assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B1]3") === -1);
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
b2 = Debug.setBreakPoint(initializer, 2, 0);
b3 = Debug.setBreakPoint(initializer, 3, 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B0]2;") > 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B1]3") > 0);
Debug.clearBreakPoint(b2);
assertTrue(Debug.showBreakPoints(initializer).indexOf("y = [B0]2;") === -1);
Debug.clearBreakPoint(b3);
assertTrue(Debug.showBreakPoints(initializer).indexOf("z = [B1]3") === -1);
// The computed properties are evaluated during class construction,
// not as part of the initializer function. As a consequence of which,
// they aren't breakable here in the initializer function, but
// instead, are part of the enclosing function.
function foo() {}
var bar = 'bar';
class X {
[foo()] = 1;
baz = foo();
}
// class X {
// [foo()] = 1;
// baz = [B0]foo();
// }
initializer = %GetInitializerFunction(X);
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
b1 = Debug.setBreakPoint(initializer, 1, 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf('[foo()] = 1;') > 0);
Debug.clearBreakPoint(b1);
Reland "[class] implement reparsing of class instance member initializers" This is a reland of 91f08378bc7fe486f92dc81e9a8f9ec78c1d3c21 When the class scope does not need a context, the deserialized outer scope of the initializer scope would not be the class scope, and we should not and do not need to use it to fix up the allocation information of the context-allocated variables. The original patch did not consider this case and resulted in a regression when we tried to reparse the initializer function to look for destructuring assignment errors. This fixes the regression by not deserializing the class scope that's going to be reparsed, and using the positions of the scopes to tell whether the scope info matches the reparsed scope and can be used to fix up the allocation info. Original change's description: > [class] implement reparsing of class instance member initializers > > Previously, since the source code for the synthetic class instance > member initializer function was recorded as the span from the first > initializer to the last initializer, there was no way to reparse the > class and recompile the initializer function. It was working for > most use cases because the code for the initializer function was > generated eagarly and it was usually alive as long as the class was > alive, so the initializer wouldn't normally be lazily parsed. This > didn't work, however, when the class was snapshotted with > v8::SnapshotCreator::FunctionCodeHandling::kClear, > becuase then we needed to recompile the initializer when the class > was instantiated. This patch implements the reparsing so that > these classes can work with FunctionCodeHandling::kClear. > > This patch refactors ParserBase::ParseClassLiteral() so that we can > reuse it for both parsing the class body normally and reparsing it > to collect initializers. When reparsing the synthetic initializer > function, we rewind the scanner to the beginning of the class, and > parse the class body to collect the initializers. During the > reparsing, field initializers are parsed with the full parser while > methods of the class are pre-parsed. > > A few notable changes: > > - Extended the source range of the initializer function to cover the > entire class so that we can rewind the scanner to parse the class > body to collect initializers (previously, it starts from the first > field initializer and ends at the last initializer). This resulted > some expectation changes in the debugger tests, though the > initializers remain debuggable. > - A temporary ClassScope is created during reparsing. After the class > is reparsed, we use the information from the ScopeInfo to update > the allocated indices of the variables in the ClassScope. > > Bug: v8:10704 > Change-Id: Ifb6431a1447d8844f2a548283d59158742fe9027 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2988830 > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Commit-Queue: Joyee Cheung <joyee@igalia.com> > Cr-Commit-Position: refs/heads/main@{#78299} Bug: chromium:1278086, chromium:1278085, v8:10704 Change-Id: Iea4f1f6dc398846cbe322adc16f6fffd6d2dfdf3 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3325912 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Cr-Commit-Position: refs/heads/main@{#78745}
2022-01-24 15:35:34 +00:00
b1 = Debug.setBreakPoint(initializer, 2, 0);
assertTrue(Debug.showBreakPoints(initializer).indexOf('baz = [B0]foo()') > 0);
Debug.clearBreakPoint(b1);
function t() {
class X {
[foo()] = 1;
[bar] = 2;
baz = foo();
}
}
// class X {
// [[B0]foo()] = 1;
// [[B1]bar] = 2;
// baz = foo();
// }
b1 = Debug.setBreakPoint(t, 2, 0);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B0]foo()] = 1;') > 0);
Debug.clearBreakPoint(b1);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B0]foo()] = 1;') === -1);
b2 = Debug.setBreakPoint(t, 3, 0);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B0]bar] = 2;') > 0);
Debug.clearBreakPoint(b2);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B0]bar] = [B0]2;') === -1);
b3 = Debug.setBreakPoint(t, 4, 0);
assertTrue(Debug.showBreakPoints(t).indexOf('baz = foo()') > 0);
Debug.clearBreakPoint(b3);
b1 = Debug.setBreakPoint(t, 2, 0);
b2 = Debug.setBreakPoint(t, 3, 0);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B0]foo()] = 1;') > 0);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B1]bar] = 2;') > 0);
Debug.clearBreakPoint(b1);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B0]foo()] = 1;') === -1);
Debug.clearBreakPoint(b2);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B1]bar] = 2;') === -1);
b1 = Debug.setBreakPoint(t, 2, 0);
b3 = Debug.setBreakPoint(initializer, 4, 0);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B0]foo()] = 1;') > 0);
assertTrue(Debug.showBreakPoints(t).indexOf('baz = foo()') > 0);
Debug.clearBreakPoint(b1);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B0]foo()] = 1;') === -1);
Debug.clearBreakPoint(b3);
b2 = Debug.setBreakPoint(t, 3, 0);
b3 = Debug.setBreakPoint(t, 4, 0);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B0]bar] = 2;') > 0);
assertTrue(Debug.showBreakPoints(t).indexOf('baz = foo()') > 0);
Debug.clearBreakPoint(b2);
assertTrue(Debug.showBreakPoints(t).indexOf('[[B0]bar] = 2;') === -1);
Debug.clearBreakPoint(b3);