[dart2wasm] Make slow path call StackTrace.current on null errors
For throwing normal exceptions we already outlined obtaining the current stack. We can do this for null check errors as well. Change-Id: Ie0505bfd99ff9c6738040c47b07e542439ee74a5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/419161 Reviewed-by: Ömer Ağacan <omersa@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
committed by
Commit Queue
parent
90aecc4fe8
commit
b8d25b791a
@@ -274,6 +274,15 @@ class AsyncStateMachineCodeGenerator extends StateMachineCodeGenerator {
|
||||
b.return_();
|
||||
}
|
||||
|
||||
void callCompleteErrorWithCurrentStack() {
|
||||
b.local_get(_suspendStateLocal);
|
||||
b.struct_get(
|
||||
asyncSuspendStateInfo.struct, FieldIndex.asyncSuspendStateCompleter);
|
||||
b.local_get(exceptionLocal);
|
||||
call(translator.completerCompleteErrorWithCurrentStack.reference);
|
||||
b.return_();
|
||||
}
|
||||
|
||||
// Handle Dart exceptions.
|
||||
b.catch_legacy(translator.getExceptionTag(b.module));
|
||||
b.local_set(stackTraceLocal);
|
||||
@@ -289,10 +298,7 @@ class AsyncStateMachineCodeGenerator extends StateMachineCodeGenerator {
|
||||
|
||||
// JS exceptions won't have a Dart stack trace, so we attach the current
|
||||
// Dart stack trace.
|
||||
call(translator.stackTraceCurrent.reference);
|
||||
b.local_set(stackTraceLocal);
|
||||
|
||||
callCompleteError();
|
||||
callCompleteErrorWithCurrentStack();
|
||||
|
||||
b.end(); // try
|
||||
|
||||
|
||||
@@ -2651,8 +2651,7 @@ abstract class AstCodeGenerator
|
||||
// We lower a null check to a br_on_non_null, throwing a [TypeError] in
|
||||
// the null case.
|
||||
b.br_on_non_null(nullCheckBlock);
|
||||
call(translator.stackTraceCurrent.reference);
|
||||
call(translator.throwNullCheckError.reference);
|
||||
call(translator.throwNullCheckErrorWithCurrentStack.reference);
|
||||
b.unreachable();
|
||||
b.end();
|
||||
return nonNullOperandType;
|
||||
|
||||
@@ -147,6 +147,9 @@ mixin KernelNodes {
|
||||
index.getField("dart:async", "_Completer", "future");
|
||||
late final Procedure completerComplete =
|
||||
index.getProcedure("dart:async", "_AsyncCompleter", "complete");
|
||||
late final Procedure completerCompleteErrorWithCurrentStack =
|
||||
index.getProcedure(
|
||||
"dart:async", "_AsyncCompleter", "_completeErrorWithCurrentStack");
|
||||
late final Procedure completerCompleteError =
|
||||
index.getProcedure("dart:async", "_Completer", "completeError");
|
||||
late final Procedure awaitHelper =
|
||||
@@ -290,8 +293,8 @@ mixin KernelNodes {
|
||||
"_throwUnimplementedExternalMemberError");
|
||||
late final Procedure stackTraceCurrent =
|
||||
index.getProcedure("dart:core", "StackTrace", "get:current");
|
||||
late final Procedure throwNullCheckError =
|
||||
index.getProcedure("dart:core", "_TypeError", "_throwNullCheckError");
|
||||
late final Procedure throwNullCheckErrorWithCurrentStack = index.getProcedure(
|
||||
"dart:core", "_TypeError", "_throwNullCheckErrorWithCurrentStack");
|
||||
late final Procedure throwAsCheckError =
|
||||
index.getProcedure("dart:core", "_TypeError", "_throwAsCheckError");
|
||||
late final Procedure throwInterfaceTypeAsCheckError1 = index
|
||||
|
||||
@@ -84,6 +84,15 @@ _AsyncSuspendState _newAsyncSuspendState(
|
||||
@pragma("wasm:entry-point")
|
||||
_AsyncCompleter<T> _makeAsyncCompleter<T>() => _AsyncCompleter<T>();
|
||||
|
||||
@patch
|
||||
@pragma("wasm:entry-point")
|
||||
class _AsyncCompleter<T> extends _Completer<T> {
|
||||
@pragma("wasm:entry-point")
|
||||
void _completeErrorWithCurrentStack(Object error) {
|
||||
completeError(error, StackTrace.current);
|
||||
}
|
||||
}
|
||||
|
||||
@pragma("wasm:entry-point")
|
||||
void _awaitHelper(_AsyncSuspendState suspendState, Object? operand) {
|
||||
if (operand is! Future) {
|
||||
|
||||
@@ -73,7 +73,9 @@ class _TypeError extends _Error implements TypeError {
|
||||
}
|
||||
|
||||
@pragma("wasm:entry-point")
|
||||
static Never _throwNullCheckError(StackTrace stackTrace) {
|
||||
@pragma("wasm:never-inline")
|
||||
static Never _throwNullCheckErrorWithCurrentStack() {
|
||||
final stackTrace = StackTrace.current;
|
||||
final typeError = _TypeError.fromMessageAndStackTrace(
|
||||
"Null check operator used on a null value",
|
||||
stackTrace,
|
||||
|
||||
Reference in New Issue
Block a user