[record_use] Support double constants
Quirks: - JS backend compiles some values to ints instead of doubles. Closes: https://github.com/dart-lang/native/issues/3221 TEST=pkg/compiler/test/record_use/record_use_test.dart TEST=pkg/dart2wasm/test/record_use_test.dart TEST=pkg/vm/test/transformations/record_use_test.dart Change-Id: Ic8c95094343d6d1fed3a37b0772269a8232bc205 Cq-Include-Trybots: luci.dart.try:dart2wasm-asserts-linux-chrome-try,dart2wasm-asserts-minified-linux-d8-try,dart2wasm-linux-chrome-try,dart2wasm-linux-d8-try,dart2wasm-linux-firefox-try,dart2wasm-linux-jscm-chrome-try,dart2wasm-linux-optimized-jsc-try,pkg-linux-debug-try,pkg-linux-release-arm64-try,pkg-linux-release-try,pkg-mac-release-arm64-try,pkg-mac-release-try,pkg-win-release-arm64-try,pkg-win-release-try,dart2js-canary-linux-try,dart2js-hostasserts-linux-d8-try,dart2js-linux-chrome-try,dart2js-linux-firefox-try,dart2js-mac-chrome-try,dart2js-mac-safari-try,dart2js-minified-csp-linux-chrome-try,dart2js-minified-linux-d8-try,dart2js-unit-linux-x64-release-try,dart2js-win-chrome-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/487860 Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
committed by
Commit Queue
parent
aa08628c36
commit
786e90791d
@@ -143,7 +143,7 @@ vars = {
|
||||
"i18n_rev": "de7e11b7cc231d8daf6e49dc12690d7339241691",
|
||||
"leak_tracker_rev": "f5620600a5ce1c44f65ddaa02001e200b096e14c", # rolled manually
|
||||
"material_color_utilities_rev": "799b6ba2f3f1c28c67cc7e0b4f18e0c7d7f3c03e",
|
||||
"native_rev": "c478dfede2b37000ea52ac57da7a48ab9e99f5af", # rolled manually while record_use is experimental
|
||||
"native_rev": "ac1144e65a4621b9f94324f307bc3437b5b74f66", # rolled manually while record_use is experimental
|
||||
"protobuf_rev": "d5639f45b8468fba684b076b9403ccd5f2290056",
|
||||
"pub_rev": "74408212b5348003381bc63f3b59274aaa23cfa3", # rolled manually
|
||||
"shelf_rev": "900731b313dabf48927a82f2124e5a996c4a3d05",
|
||||
|
||||
@@ -456,9 +456,7 @@ class RecordUseValueConverter {
|
||||
MapConstantValue() => _findMapValue(constant),
|
||||
ListConstantValue() => _findListValue(constant),
|
||||
ConstructedConstantValue() => findInstanceValue(constant),
|
||||
DoubleConstantValue() => record_use.UnsupportedConstant(
|
||||
'Double literals are not supported for recording.',
|
||||
),
|
||||
DoubleConstantValue() => record_use.DoubleConstant(constant.doubleValue),
|
||||
SetConstantValue() => record_use.UnsupportedConstant(
|
||||
'Set literals are not supported for recording.',
|
||||
),
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// ignore: experimental_member_use
|
||||
import 'package:meta/meta.dart' show RecordUse;
|
||||
|
||||
const zero = 0.0;
|
||||
const maxFinite = 1.7976931348623157e+308;
|
||||
const minusMaxFinite = -maxFinite;
|
||||
|
||||
void main() {
|
||||
// In dart2js, 0.0 is canonicalized to IntConstant(0).
|
||||
print(SomeClass.someStaticMethod(zero));
|
||||
|
||||
// In dart2js, maxFinite is canonicalized to IntConstant.
|
||||
// When running the compiler on the VM, BigInt.toInt() clamps it to
|
||||
// 9223372036854775807 (Int64.MAX).
|
||||
print(SomeClass.someStaticMethod(maxFinite));
|
||||
|
||||
// In dart2js, -maxFinite is canonicalized to IntConstant.
|
||||
// When running the compiler on the VM, BigInt.toInt() clamps it to
|
||||
// -9223372036854775808 (Int64.MIN).
|
||||
print(SomeClass.someStaticMethod(minusMaxFinite));
|
||||
}
|
||||
|
||||
class SomeClass {
|
||||
// ignore: experimental_member_use
|
||||
@RecordUse()
|
||||
static String someStaticMethod(double d) => d.toString();
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"constants": [
|
||||
{
|
||||
"type": "int",
|
||||
"value": -9223372036854775808
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"value": 9223372036854775807
|
||||
}
|
||||
],
|
||||
"definitions": [
|
||||
{
|
||||
"path": [
|
||||
{
|
||||
"kind": "class",
|
||||
"name": "SomeClass"
|
||||
},
|
||||
{
|
||||
"disambiguators": [
|
||||
"static"
|
||||
],
|
||||
"kind": "method",
|
||||
"name": "someStaticMethod"
|
||||
}
|
||||
],
|
||||
"uri": "package:record_use_js_test/double_constants_js.dart"
|
||||
}
|
||||
],
|
||||
"loading_units": [
|
||||
{
|
||||
"name": "out"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"comment": "Recorded usages of objects tagged with a `RecordUse` annotation.",
|
||||
"version": "0.4.0"
|
||||
},
|
||||
"uses": {
|
||||
"static_calls": [
|
||||
{
|
||||
"definition_index": 0,
|
||||
"uses": [
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
0
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
1
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
2
|
||||
],
|
||||
"type": "with_arguments"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -252,6 +252,10 @@ const Set<String> dart2jsNotSupported = {
|
||||
// a compile-time error for these literals when targeting the web.
|
||||
'large_integers.dart',
|
||||
|
||||
// The JS backend represents doubles that are an int value as that int value
|
||||
// and clamps large double values.
|
||||
'double_constants_js_divergent.dart',
|
||||
|
||||
// There is an extra loading unit out_2 which contains the shared stuff
|
||||
// between out_1 and out_3. Either of those loads out_2. We need a more robust
|
||||
// semanticEquality solution than mapping loading unit names. We might only be
|
||||
|
||||
@@ -236,9 +236,7 @@ Constant evaluateConstant(ast.Constant constant) => switch (constant) {
|
||||
ast.NullConstant() => NullConstant(),
|
||||
ast.BoolConstant() => BoolConstant(constant.value),
|
||||
ast.IntConstant() => IntConstant(constant.value),
|
||||
ast.DoubleConstant() => UnsupportedConstant(
|
||||
'Double literals are not supported for recording.',
|
||||
),
|
||||
ast.DoubleConstant() => DoubleConstant(constant.value),
|
||||
ast.StringConstant() => StringConstant(constant.value),
|
||||
ast.SymbolConstant() => SymbolConstant(
|
||||
constant.name,
|
||||
@@ -289,9 +287,7 @@ Constant evaluateLiteral(ast.BasicLiteral expression) => switch (expression) {
|
||||
ast.IntLiteral() => IntConstant(expression.value),
|
||||
ast.BoolLiteral() => BoolConstant(expression.value),
|
||||
ast.StringLiteral() => StringConstant(expression.value),
|
||||
ast.DoubleLiteral() => UnsupportedConstant(
|
||||
'Double literals are not supported for recording.',
|
||||
),
|
||||
ast.DoubleLiteral() => DoubleConstant(expression.value),
|
||||
ast.BasicLiteral() => _unsupported(expression.runtimeType.toString()),
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:math' as math;
|
||||
import 'package:meta/meta.dart' show RecordUse;
|
||||
|
||||
const negativeZero = -0.0;
|
||||
const minPositive = 5e-324;
|
||||
const minusMinPositive = -minPositive;
|
||||
const highPrecision = 0.12345678901234567;
|
||||
|
||||
void main() {
|
||||
print(SomeClass.someStaticMethod(1.234));
|
||||
print(SomeClass.someStaticMethod(double.infinity));
|
||||
print(SomeClass.someStaticMethod(double.negativeInfinity));
|
||||
print(SomeClass.someStaticMethod(double.nan));
|
||||
print(SomeClass.someStaticMethod(negativeZero));
|
||||
|
||||
print(SomeClass.someStaticMethod(minPositive));
|
||||
print(SomeClass.someStaticMethod(minusMinPositive));
|
||||
|
||||
print(SomeClass.someStaticMethod(highPrecision));
|
||||
print(SomeClass.someStaticMethod(math.pi));
|
||||
}
|
||||
|
||||
class SomeClass {
|
||||
@RecordUse()
|
||||
static String someStaticMethod(double d) => d.toString();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
library #lib;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "package:meta/meta.dart" as meta;
|
||||
|
||||
import "dart:math" as math;
|
||||
import "package:meta/meta.dart" show RecordUse;
|
||||
|
||||
class SomeClass extends core::Object {
|
||||
|
||||
[@vm.inferred-return-type.metadata=!]
|
||||
[@vm.unboxing-info.metadata=[!regcc]]
|
||||
@#C1
|
||||
static method someStaticMethod([@vm.inferred-arg-type.metadata=dart.core::_Double] core::double d) → core::String
|
||||
return [@vm.direct-call.metadata=dart.core::_Double.toString] [@vm.inferred-type.metadata=! (skip check)] d.{core::double::toString}(){() → core::String};
|
||||
}
|
||||
|
||||
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
|
||||
static method main() → void {
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(1.234));
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C2));
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C3));
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C4));
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C5));
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C6));
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C7));
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C8));
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C9));
|
||||
}
|
||||
constants {
|
||||
#C1 = meta::RecordUse {}
|
||||
#C2 = Infinity
|
||||
#C3 = -Infinity
|
||||
#C4 = NaN
|
||||
#C5 = -0.0
|
||||
#C6 = 5e-324
|
||||
#C7 = -5e-324
|
||||
#C8 = 0.12345678901234566
|
||||
#C9 = 3.141592653589793
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
{
|
||||
"constants": [
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "negative_infinity"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "number",
|
||||
"value": -5e-324
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "number",
|
||||
"value": -0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "number",
|
||||
"value": 5e-324
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "number",
|
||||
"value": 0.12345678901234566
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "number",
|
||||
"value": 1.234
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "number",
|
||||
"value": 3.141592653589793
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "positive_infinity"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "not_a_number"
|
||||
}
|
||||
}
|
||||
],
|
||||
"definitions": [
|
||||
{
|
||||
"path": [
|
||||
{
|
||||
"kind": "class",
|
||||
"name": "SomeClass"
|
||||
},
|
||||
{
|
||||
"disambiguators": [
|
||||
"static"
|
||||
],
|
||||
"kind": "method",
|
||||
"name": "someStaticMethod"
|
||||
}
|
||||
],
|
||||
"uri": "package:record_use_test/double_constants.dart"
|
||||
}
|
||||
],
|
||||
"loading_units": [
|
||||
{
|
||||
"name": "1"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"comment": "Recorded usages of objects tagged with a `RecordUse` annotation.",
|
||||
"version": "0.4.0"
|
||||
},
|
||||
"uses": {
|
||||
"static_calls": [
|
||||
{
|
||||
"definition_index": 0,
|
||||
"uses": [
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
0
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
1
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
2
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
3
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
4
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
5
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
6
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
7
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
8
|
||||
],
|
||||
"type": "with_arguments"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:meta/meta.dart' show RecordUse;
|
||||
|
||||
const zero = 0.0;
|
||||
const maxFinite = 1.7976931348623157e+308;
|
||||
const minusMaxFinite = -maxFinite;
|
||||
|
||||
void main() {
|
||||
print(SomeClass.someStaticMethod(zero));
|
||||
print(SomeClass.someStaticMethod(maxFinite));
|
||||
print(SomeClass.someStaticMethod(minusMaxFinite));
|
||||
}
|
||||
|
||||
class SomeClass {
|
||||
@RecordUse()
|
||||
static String someStaticMethod(double d) => d.toString();
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
library #lib;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "package:meta/meta.dart" as meta;
|
||||
|
||||
import "package:meta/meta.dart" show RecordUse;
|
||||
|
||||
class SomeClass extends core::Object {
|
||||
|
||||
[@vm.inferred-return-type.metadata=!]
|
||||
[@vm.unboxing-info.metadata=[!regcc]]
|
||||
@#C1
|
||||
static method someStaticMethod([@vm.inferred-arg-type.metadata=dart.core::_Double] core::double d) → core::String
|
||||
return [@vm.direct-call.metadata=dart.core::_Double.toString] [@vm.inferred-type.metadata=! (skip check)] d.{core::double::toString}(){() → core::String};
|
||||
}
|
||||
|
||||
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
|
||||
static method main() → void {
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C2));
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C3));
|
||||
core::print([@vm.inferred-type.metadata=!] self::SomeClass::someStaticMethod(#C4));
|
||||
}
|
||||
constants {
|
||||
#C1 = meta::RecordUse {}
|
||||
#C2 = 0.0
|
||||
#C3 = 1.7976931348623157e+308
|
||||
#C4 = -1.7976931348623157e+308
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"constants": [
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "number",
|
||||
"value": -1.7976931348623157e+308
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "number",
|
||||
"value": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "double",
|
||||
"value": {
|
||||
"type": "number",
|
||||
"value": 1.7976931348623157e+308
|
||||
}
|
||||
}
|
||||
],
|
||||
"definitions": [
|
||||
{
|
||||
"path": [
|
||||
{
|
||||
"kind": "class",
|
||||
"name": "SomeClass"
|
||||
},
|
||||
{
|
||||
"disambiguators": [
|
||||
"static"
|
||||
],
|
||||
"kind": "method",
|
||||
"name": "someStaticMethod"
|
||||
}
|
||||
],
|
||||
"uri": "package:record_use_test/double_constants_js_divergent.dart"
|
||||
}
|
||||
],
|
||||
"loading_units": [
|
||||
{
|
||||
"name": "1"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"comment": "Recorded usages of objects tagged with a `RecordUse` annotation.",
|
||||
"version": "0.4.0"
|
||||
},
|
||||
"uses": {
|
||||
"static_calls": [
|
||||
{
|
||||
"definition_index": 0,
|
||||
"uses": [
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
0
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
1
|
||||
],
|
||||
"type": "with_arguments"
|
||||
},
|
||||
{
|
||||
"loading_unit_index": 0,
|
||||
"positional": [
|
||||
2
|
||||
],
|
||||
"type": "with_arguments"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user