Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: pkg/compiler/lib/src/js_emitter/constant_ordering.dart

Issue 1491413008: Canonical output ordering for constants. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: baseline for fix Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library dart2js.js_emitter.constant_ordering;
6
7 import '../constants/values.dart';
8
9 import '../common.dart';
10 //import '../core_types.dart';
11 import '../dart_types.dart';
12 import '../elements/elements.dart'
13 show Element,
14 Elements,
15 FieldElement;
16 import '../tree/tree.dart' show DartString;
17
18 /// A canonical but arbrary ordering of constants. The ordering is 'stable'
19 /// under perturbation of the source.
20 int deepCompareConstants(ConstantValue a, ConstantValue b) {
21 return _CompareVisitor.compareValues(a, b);
22 }
23
24 class _CompareVisitor implements ConstantValueVisitor<int, ConstantValue> {
25 const _CompareVisitor();
26
27 static int compareValues(ConstantValue a, ConstantValue b) {
28 if (identical(a, b)) return 0;
29 int r = _KindVisitor.kind(a).compareTo(_KindVisitor.kind(b));
30 if (r != 0) return r;
31 r = a.accept(const _CompareVisitor(), b);
32 return r;
33 }
34
35 static int compareNullable(int compare(a, b), a, b) {
36 if (a == null && b == null) return 0;
37 if (a == null) return -1;
38 if (b == null) return 1;
39 return compare(a, b);
40 }
41
42 static int compareLists(int compare(a, b), List a, List b) {
43 int r = a.length.compareTo(b.length);
44 if (r != 0) return r;
45 for (int i = 0; i < a.length; i++) {
46 r = compare(a[i], b[i]);
47 if (r != 0) return r;
48 }
49 return 0;
50 }
51
52 static int compareElements(Element a, Element b) {
53 int r = a.name.compareTo(b.name);
54 if (r != 0) return r;
55 return Elements.compareByPosition(a, b);
56 }
57
58 static int compareDartTypes(DartType a, DartType b) {
59 if (a == b) return 0;
60 int r = a.kind.index.compareTo(b.kind.index);
61 if (r != 0) return r;
62 r = compareNullable(compareElements, a.element, b.element);
63 if (r != 0) return r;
64
65 if (a is GenericType) {
66 GenericType aGeneric = a;
67 GenericType bGeneric = b;
68 r = compareLists(compareDartTypes,
69 aGeneric.typeArguments, bGeneric.typeArguments);
70 if (r != 0) return r;
71 }
72 throw 'unexpected compareDartTypes $a $b';
73 }
74
75 int visitFunction(FunctionConstantValue a, FunctionConstantValue b) {
76 return compareElements(a.element, b.element);
77 }
78
79 int visitNull(NullConstantValue a, NullConstantValue b) {
80 return 0;
81 }
82
83 int visitInt(IntConstantValue a, IntConstantValue b) {
84 return a.primitiveValue.compareTo(b.primitiveValue);
85 }
86
87 int visitDouble(DoubleConstantValue a, DoubleConstantValue b) {
88 return a.primitiveValue.compareTo(b.primitiveValue);
89 }
90
91 int visitBool(BoolConstantValue a, BoolConstantValue b) {
92 int aInt = a.primitiveValue ? 1 : 0;
93 int bInt = b.primitiveValue ? 1 : 0;
94 return aInt.compareTo(bInt);
95 }
96
97 int visitString(StringConstantValue a, StringConstantValue b) {
98 DartString aString = a.primitiveValue;
99 DartString bString = b.primitiveValue;
100 int r = aString.length.compareTo(bString.length);
101 if (r != 0) return r;
102 return aString.slowToString().compareTo(bString.slowToString());
103 }
104
105 int visitList(ListConstantValue a, ListConstantValue b) {
106 int r = compareLists(compareValues, a.entries, b.entries);
107 if (r != 0) return r;
108 return compareDartTypes(a.type, b.type);
109 }
110
111 int visitMap(MapConstantValue a, MapConstantValue b) {
112 int r = compareLists(compareValues, a.keys, b.keys);
113 if (r != 0) return r;
114 r = compareLists(compareValues, a.values, b.values);
115 if (r != 0) return r;
116 return compareDartTypes(a.type, b.type);
117 }
118
119 int visitConstructed(ConstructedConstantValue a, ConstructedConstantValue b) {
120 int r = compareDartTypes(a.type, b.type);
121 if (r != 0) return r;
122
123 List<FieldElement> aFields = a.fields.keys.toList()..sort(compareElements);
124 List<FieldElement> bFields = b.fields.keys.toList()..sort(compareElements);
125
126 r = compareLists(compareElements, aFields, bFields);
127 if (r != 0) return r;
128
129 return compareLists(compareValues,
130 aFields.map((field) => a.fields[field]).toList(),
131 aFields.map((field) => b.fields[field]).toList());
132 }
133
134 int visitType(TypeConstantValue a, TypeConstantValue b) {
135 int r = compareDartTypes(a.representedType, b.representedType);
136 if (r != 0) return r;
137 return compareDartTypes(a.type, b.type);
138 }
139
140 int visitInterceptor(InterceptorConstantValue a, InterceptorConstantValue b) {
141 return compareDartTypes(a.dispatchedType, b.dispatchedType);
142 }
143
144 int visitSynthetic(SyntheticConstantValue a, SyntheticConstantValue b) {
145 // [SyntheticConstantValue]s have abstract fields that are set only by
146 // convention. Lucky for us, they do not occur as top level constant, only
147 // as elements of a few constants. If this becomes a source of instability,
148 // we will need to add a total ordering on JavaScript ASTs including
149 // deferred elements.
150 SyntheticConstantKind aKind = a.kind;
151 SyntheticConstantKind bKind = b.kind;
152 int r = aKind.index - bKind.index;
153 if (r != 0) return r;
154 switch (a.kind) {
155 case SyntheticConstantKind.DUMMY_INTERCEPTOR:
156 case SyntheticConstantKind.EMPTY_VALUE:
157 // Never emitted.
158 return 0:
159
160 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
161 // An opaque deferred JS AST reference to a type in reflection data.
162 return 0;
163 case SyntheticConstantKind.NAME:
164 // An opaque deferred JS AST reference to a name.
165 return 0;
166 default:
167 // Should not happen.
168 throw 'unexpected SyntheticConstantKind $akind';
169 }
170 }
171
172 int visitDeferred(DeferredConstantValue a, DeferredConstantValue b) {
173 int r = compareValues(a.referenced, b.referenced);
174 if (r != 0) return r;
175 return compareElements(a.prefix, b.prefix);
176 }
177 }
178
179 class _KindVisitor implements ConstantValueVisitor<int, Null> {
180 const _KindVisitor();
181
182 static const int FUNCTION = 1;
183 static const int NULL = 2;
184 static const int INT = 3;
185 static const int DOUBLE = 4;
186 static const int BOOL = 5;
187 static const int STRING = 6;
188 static const int LIST = 7;
189 static const int MAP = 8;
190 static const int CONSTRUCTED = 9;
191 static const int TYPE = 10;
192 static const int INTERCEPTOR = 11;
193 static const int SYNTHETIC = 12;
194 static const int DEFERRED = 13;
195
196 static int kind(ConstantValue constant) =>
197 constant.accept(const _KindVisitor(), null);
198
199 int visitFunction(FunctionConstantValue a, _) => FUNCTION;
200 int visitNull(NullConstantValue a, _) => NULL;
201 int visitInt(IntConstantValue a, _) => INT;
202 int visitDouble(DoubleConstantValue a, _) => DOUBLE;
203 int visitBool(BoolConstantValue a, _) => BOOL;
204 int visitString(StringConstantValue a, _) => STRING;
205 int visitList(ListConstantValue a, _) => LIST;
206 int visitMap(MapConstantValue a, _) => MAP;
207 int visitConstructed(ConstructedConstantValue a, _) => CONSTRUCTED;
208 int visitType(TypeConstantValue a, _) => TYPE;
209 int visitInterceptor(InterceptorConstantValue a, _) => INTERCEPTOR;
210 int visitSynthetic(SyntheticConstantValue a, _) => SYNTHETIC;
211 int visitDeferred(DeferredConstantValue a, _) => DEFERRED;
212 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/namer.dart ('k') | pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698