Skip to content

Commit

Permalink
[dart2wasm] Move StackTrace.current for as checks into shared run…
Browse files Browse the repository at this point in the history
…time code

When an implicit or explicit `as` check fails we throw a [TypeError]
exception with a stack trace. Though that stack trace doesn't really
have to have the top-frame being where the check failed, it's fine if
there's an additional frame from the runtime code that actually throws
the exception.

Doing so removes `StackTrace.current` from every `as` check and
therefore reduces size.

Change-Id: Ia34b59ebaa54b8cdcd2dc7b153a1e4e2fe1dd0e9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370340
Reviewed-by: Ömer Ağacan <[email protected]>
Commit-Queue: Martin Kustermann <[email protected]>
  • Loading branch information
mkustermann authored and Commit Queue committed Jun 10, 2024
1 parent 1e60700 commit d32e2ec
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 13 deletions.
2 changes: 2 additions & 0 deletions pkg/dart2wasm/lib/kernel_nodes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ mixin KernelNodes {
index.getTopLevelProcedure("dart:core", "_getMasqueradedRuntimeType");
late final Procedure isSubtype =
index.getTopLevelProcedure("dart:core", "_isSubtype");
late final Procedure asSubtype =
index.getTopLevelProcedure("dart:core", "_asSubtype");
late final Procedure isTypeSubtype =
index.getTopLevelProcedure("dart:core", "_isTypeSubtype");
late final Procedure verifyOptimizedTypeCheck =
Expand Down
16 changes: 5 additions & 11 deletions pkg/dart2wasm/lib/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -426,16 +426,12 @@ class Types {

w.Local operand = b.addLocal(boxedOperandType, isParameter: false);
b.local_tee(operand);
w.Label asCheckBlock = b.block();
b.local_get(operand);
emitIsTest(codeGen, testedAgainstType, operandType, location);
b.br_if(asCheckBlock);
b.local_get(operand);
makeType(codeGen, testedAgainstType);
codeGen.call(translator.stackTraceCurrent.reference);
codeGen.call(translator.throwAsCheckError.reference);
b.unreachable();
b.end();
final outputs = codeGen.call(translator.asSubtype.reference);
for (final _ in outputs) {
b.drop();
}
b.local_get(operand);
return operand.type;
}

Expand Down Expand Up @@ -594,8 +590,6 @@ class Types {
b.local_get(b.locals[0]);
translator.constants.instantiateConstant(function, b,
TypeLiteralConstant(testedAgainstType), nonNullableTypeType);
b.call(translator.functions
.getFunction(translator.stackTraceCurrent.reference));
b.call(translator.functions
.getFunction(translator.throwAsCheckError.reference));
b.unreachable();
Expand Down
4 changes: 2 additions & 2 deletions sdk/lib/_internal/wasm/lib/errors_patch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ class _TypeError extends _Error implements TypeError {
}

@pragma("wasm:entry-point")
static Never _throwAsCheckError(
Object? operand, Type? type, StackTrace stackTrace) {
static Never _throwAsCheckError(Object? operand, Type? type) {
final stackTrace = StackTrace.current;
final typeError = _TypeError.fromMessageAndStackTrace(
"Type '${operand.runtimeType}' is not a subtype of type '$type'"
" in type cast",
Expand Down
8 changes: 8 additions & 0 deletions sdk/lib/_internal/wasm/lib/type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,14 @@ bool _isTypeSubtype(_Type s, _Type t) {
return _TypeUniverse.isSubtype(s, null, t, null);
}

@pragma("wasm:entry-point")
@pragma("wasm:prefer-inline")
void _asSubtype(Object? o, _Type t) {
if (!_isSubtype(o, t)) {
_TypeError._throwAsCheckError(o, t);
}
}

@pragma("wasm:entry-point")
bool _verifyOptimizedTypeCheck(
bool result, Object? o, _Type t, String? location) {
Expand Down

0 comments on commit d32e2ec

Please sign in to comment.