OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library js_backend.serialization; | 5 library js_backend.serialization; |
6 | 6 |
| 7 import '../common.dart'; |
7 import '../common/backend_api.dart' show BackendSerialization; | 8 import '../common/backend_api.dart' show BackendSerialization; |
8 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
9 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
10 import '../js/js.dart' as js; | 11 import '../js/js.dart' as js; |
11 import '../native/native.dart'; | 12 import '../native/native.dart'; |
12 import '../serialization/serialization.dart' | 13 import '../serialization/serialization.dart' |
13 show DeserializerPlugin, ObjectDecoder, ObjectEncoder, SerializerPlugin; | 14 show DeserializerPlugin, ObjectDecoder, ObjectEncoder, SerializerPlugin; |
14 import '../serialization/keys.dart'; | 15 import '../serialization/keys.dart'; |
15 import '../universe/side_effects.dart'; | 16 import '../universe/side_effects.dart'; |
16 import 'js_backend.dart'; | 17 import 'js_backend.dart'; |
(...skipping 14 matching lines...) Expand all Loading... |
31 final JavaScriptBackendDeserializer deserializer; | 32 final JavaScriptBackendDeserializer deserializer; |
32 | 33 |
33 JavaScriptBackendSerialization(JavaScriptBackend backend) | 34 JavaScriptBackendSerialization(JavaScriptBackend backend) |
34 : serializer = new JavaScriptBackendSerializer(backend), | 35 : serializer = new JavaScriptBackendSerializer(backend), |
35 deserializer = new JavaScriptBackendDeserializer(backend); | 36 deserializer = new JavaScriptBackendDeserializer(backend); |
36 } | 37 } |
37 | 38 |
38 const Key JS_INTEROP_NAME = const Key('jsInteropName'); | 39 const Key JS_INTEROP_NAME = const Key('jsInteropName'); |
39 const Key NATIVE_MEMBER_NAME = const Key('nativeMemberName'); | 40 const Key NATIVE_MEMBER_NAME = const Key('nativeMemberName'); |
40 const Key NATIVE_CLASS_TAG_INFO = const Key('nativeClassTagInfo'); | 41 const Key NATIVE_CLASS_TAG_INFO = const Key('nativeClassTagInfo'); |
| 42 const Key NATIVE_METHOD_BEHAVIOR = const Key('nativeMethodBehavior'); |
| 43 const Key NATIVE_FIELD_LOAD_BEHAVIOR = const Key('nativeFieldLoadBehavior'); |
| 44 const Key NATIVE_FIELD_STORE_BEHAVIOR = const Key('nativeFieldStoreBehavior'); |
41 | 45 |
42 class JavaScriptBackendSerializer implements SerializerPlugin { | 46 class JavaScriptBackendSerializer implements SerializerPlugin { |
43 final JavaScriptBackend backend; | 47 final JavaScriptBackend backend; |
44 | 48 |
45 JavaScriptBackendSerializer(this.backend); | 49 JavaScriptBackendSerializer(this.backend); |
46 | 50 |
47 @override | 51 @override |
48 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { | 52 void onElement(Element element, ObjectEncoder createEncoder(String tag)) { |
49 ObjectEncoder encoder; | 53 ObjectEncoder encoder; |
50 ObjectEncoder getEncoder() { | 54 ObjectEncoder getEncoder() { |
51 return encoder ??= createEncoder(_BACKEND_DATA_TAG); | 55 return encoder ??= createEncoder(_BACKEND_DATA_TAG); |
52 } | 56 } |
53 | 57 |
54 String jsInteropName = backend.nativeData.jsInteropNames[element]; | 58 String jsInteropName = backend.nativeData.jsInteropNames[element]; |
55 if (jsInteropName != null) { | 59 if (jsInteropName != null) { |
56 getEncoder().setString(JS_INTEROP_NAME, jsInteropName); | 60 getEncoder().setString(JS_INTEROP_NAME, jsInteropName); |
57 } | 61 } |
58 String nativeMemberName = backend.nativeData.nativeMemberName[element]; | 62 String nativeMemberName = backend.nativeData.nativeMemberName[element]; |
59 if (nativeMemberName != null) { | 63 if (nativeMemberName != null) { |
60 getEncoder().setString(NATIVE_MEMBER_NAME, nativeMemberName); | 64 getEncoder().setString(NATIVE_MEMBER_NAME, nativeMemberName); |
61 } | 65 } |
62 String nativeClassTagInfo = backend.nativeData.nativeClassTagInfo[element]; | 66 String nativeClassTagInfo = backend.nativeData.nativeClassTagInfo[element]; |
63 if (nativeClassTagInfo != null) { | 67 if (nativeClassTagInfo != null) { |
64 getEncoder().setString(NATIVE_CLASS_TAG_INFO, nativeClassTagInfo); | 68 getEncoder().setString(NATIVE_CLASS_TAG_INFO, nativeClassTagInfo); |
65 } | 69 } |
66 } | 70 NativeBehavior nativeMethodBehavior = |
67 | 71 backend.nativeData.nativeMethodBehavior[element]; |
68 /// Returns a list of the [DartType]s in [types]. | 72 if (nativeMethodBehavior != null) { |
69 static List<DartType> filterDartTypes(List types) { | 73 NativeBehaviorSerialization.serializeNativeBehavior(nativeMethodBehavior, |
70 return types.where((type) => type is DartType).toList(); | 74 getEncoder().createObject(NATIVE_METHOD_BEHAVIOR)); |
71 } | 75 } |
72 | 76 NativeBehavior nativeFieldLoadBehavior = |
73 /// Returns a list of the names of the [SpecialType]s in [types]. | 77 backend.nativeData.nativeFieldLoadBehavior[element]; |
74 static List<String> filterSpecialTypes(List types) { | 78 if (nativeFieldLoadBehavior != null) { |
75 return types | 79 NativeBehaviorSerialization.serializeNativeBehavior( |
76 .where((type) => type is SpecialType) | 80 nativeFieldLoadBehavior, |
77 .map((SpecialType type) => type.name) | 81 getEncoder().createObject(NATIVE_FIELD_LOAD_BEHAVIOR)); |
78 .toList(); | 82 } |
| 83 NativeBehavior nativeFieldStoreBehavior = |
| 84 backend.nativeData.nativeFieldStoreBehavior[element]; |
| 85 if (nativeFieldStoreBehavior != null) { |
| 86 NativeBehaviorSerialization.serializeNativeBehavior( |
| 87 nativeFieldStoreBehavior, |
| 88 getEncoder().createObject(NATIVE_FIELD_STORE_BEHAVIOR)); |
| 89 } |
79 } | 90 } |
80 | 91 |
81 @override | 92 @override |
82 void onData(NativeBehavior behavior, ObjectEncoder encoder) { | 93 void onData(NativeBehavior behavior, ObjectEncoder encoder) { |
83 encoder.setTypes( | 94 NativeBehaviorSerialization.serializeNativeBehavior(behavior, encoder); |
84 DART_TYPES_RETURNED, filterDartTypes(behavior.typesReturned)); | |
85 encoder.setStrings( | |
86 SPECIAL_TYPES_RETURNED, filterSpecialTypes(behavior.typesReturned)); | |
87 | |
88 encoder.setTypes( | |
89 DART_TYPES_INSTANTIATED, filterDartTypes(behavior.typesInstantiated)); | |
90 encoder.setStrings(SPECIAL_TYPES_INSTANTIATED, | |
91 filterSpecialTypes(behavior.typesInstantiated)); | |
92 | |
93 if (behavior.codeTemplateText != null) { | |
94 encoder.setString(CODE_TEMPLATE, behavior.codeTemplateText); | |
95 } | |
96 | |
97 encoder.setInt(SIDE_EFFECTS, behavior.sideEffects.flags); | |
98 encoder.setEnum(THROW_BEHAVIOR, behavior.throwBehavior); | |
99 encoder.setBool(IS_ALLOCATION, behavior.isAllocation); | |
100 encoder.setBool(USE_GVN, behavior.useGvn); | |
101 } | 95 } |
102 } | 96 } |
103 | 97 |
104 class JavaScriptBackendDeserializer implements DeserializerPlugin { | 98 class JavaScriptBackendDeserializer implements DeserializerPlugin { |
105 final JavaScriptBackend backend; | 99 final JavaScriptBackend backend; |
106 | 100 |
107 JavaScriptBackendDeserializer(this.backend); | 101 JavaScriptBackendDeserializer(this.backend); |
108 | 102 |
109 @override | 103 @override |
110 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { | 104 void onElement(Element element, ObjectDecoder getDecoder(String tag)) { |
111 ObjectDecoder decoder = getDecoder(_BACKEND_DATA_TAG); | 105 ObjectDecoder decoder = getDecoder(_BACKEND_DATA_TAG); |
112 if (decoder != null) { | 106 if (decoder != null) { |
113 String jsInteropName = | 107 String jsInteropName = |
114 decoder.getString(JS_INTEROP_NAME, isOptional: true); | 108 decoder.getString(JS_INTEROP_NAME, isOptional: true); |
115 if (jsInteropName != null) { | 109 if (jsInteropName != null) { |
116 backend.nativeData.jsInteropNames[element] = jsInteropName; | 110 backend.nativeData.jsInteropNames[element] = jsInteropName; |
117 } | 111 } |
118 String nativeMemberName = | 112 String nativeMemberName = |
119 decoder.getString(NATIVE_MEMBER_NAME, isOptional: true); | 113 decoder.getString(NATIVE_MEMBER_NAME, isOptional: true); |
120 if (nativeMemberName != null) { | 114 if (nativeMemberName != null) { |
121 backend.nativeData.nativeMemberName[element] = nativeMemberName; | 115 backend.nativeData.nativeMemberName[element] = nativeMemberName; |
122 } | 116 } |
123 String nativeClassTagInfo = | 117 String nativeClassTagInfo = |
124 decoder.getString(NATIVE_CLASS_TAG_INFO, isOptional: true); | 118 decoder.getString(NATIVE_CLASS_TAG_INFO, isOptional: true); |
125 if (nativeClassTagInfo != null) { | 119 if (nativeClassTagInfo != null) { |
126 backend.nativeData.nativeClassTagInfo[element] = nativeClassTagInfo; | 120 backend.nativeData.nativeClassTagInfo[element] = nativeClassTagInfo; |
127 } | 121 } |
| 122 ObjectDecoder nativeMethodBehavior = |
| 123 decoder.getObject(NATIVE_METHOD_BEHAVIOR, isOptional: true); |
| 124 if (nativeMethodBehavior != null) { |
| 125 backend.nativeData.nativeMethodBehavior[element] = |
| 126 NativeBehaviorSerialization |
| 127 .deserializeNativeBehavior(nativeMethodBehavior); |
| 128 } |
| 129 ObjectDecoder nativeFieldLoadBehavior = |
| 130 decoder.getObject(NATIVE_FIELD_LOAD_BEHAVIOR, isOptional: true); |
| 131 if (nativeFieldLoadBehavior != null) { |
| 132 backend.nativeData.nativeFieldLoadBehavior[element] = |
| 133 NativeBehaviorSerialization |
| 134 .deserializeNativeBehavior(nativeFieldLoadBehavior); |
| 135 } |
| 136 ObjectDecoder nativeFieldStoreBehavior = |
| 137 decoder.getObject(NATIVE_FIELD_STORE_BEHAVIOR, isOptional: true); |
| 138 if (nativeFieldStoreBehavior != null) { |
| 139 backend.nativeData.nativeFieldStoreBehavior[element] = |
| 140 NativeBehaviorSerialization |
| 141 .deserializeNativeBehavior(nativeFieldStoreBehavior); |
| 142 } |
128 } | 143 } |
129 } | 144 } |
130 | 145 |
131 @override | 146 @override |
132 NativeBehavior onData(ObjectDecoder decoder) { | 147 NativeBehavior onData(ObjectDecoder decoder) { |
| 148 return NativeBehaviorSerialization.deserializeNativeBehavior(decoder); |
| 149 } |
| 150 } |
| 151 |
| 152 class NativeBehaviorSerialization { |
| 153 /// Returns a list of the [DartType]s in [types]. |
| 154 static List<DartType> filterDartTypes(List types) { |
| 155 return types.where((type) => type is DartType).toList(); |
| 156 } |
| 157 |
| 158 /// Returns a list of the names of the [SpecialType]s in [types]. |
| 159 static List<String> filterSpecialTypes(List types) { |
| 160 return types |
| 161 .where((type) => type is SpecialType) |
| 162 .map((SpecialType type) => type.name) |
| 163 .toList(); |
| 164 } |
| 165 |
| 166 static void serializeNativeBehavior( |
| 167 NativeBehavior behavior, ObjectEncoder encoder) { |
| 168 encoder.setTypes( |
| 169 DART_TYPES_RETURNED, filterDartTypes(behavior.typesReturned)); |
| 170 encoder.setStrings( |
| 171 SPECIAL_TYPES_RETURNED, filterSpecialTypes(behavior.typesReturned)); |
| 172 |
| 173 encoder.setTypes( |
| 174 DART_TYPES_INSTANTIATED, filterDartTypes(behavior.typesInstantiated)); |
| 175 encoder.setStrings(SPECIAL_TYPES_INSTANTIATED, |
| 176 filterSpecialTypes(behavior.typesInstantiated)); |
| 177 |
| 178 if (behavior.codeTemplateText != null) { |
| 179 encoder.setString(CODE_TEMPLATE, behavior.codeTemplateText); |
| 180 } |
| 181 |
| 182 encoder.setInt(SIDE_EFFECTS, behavior.sideEffects.flags); |
| 183 encoder.setEnum(THROW_BEHAVIOR, behavior.throwBehavior); |
| 184 encoder.setBool(IS_ALLOCATION, behavior.isAllocation); |
| 185 encoder.setBool(USE_GVN, behavior.useGvn); |
| 186 } |
| 187 |
| 188 static NativeBehavior deserializeNativeBehavior(ObjectDecoder decoder) { |
133 SideEffects sideEffects = | 189 SideEffects sideEffects = |
134 new SideEffects.fromFlags(decoder.getInt(SIDE_EFFECTS)); | 190 new SideEffects.fromFlags(decoder.getInt(SIDE_EFFECTS)); |
135 NativeBehavior behavior = new NativeBehavior.internal(sideEffects); | 191 NativeBehavior behavior = new NativeBehavior.internal(sideEffects); |
136 | 192 |
137 behavior.typesReturned | 193 behavior.typesReturned |
138 .addAll(decoder.getTypes(DART_TYPES_RETURNED, isOptional: true)); | 194 .addAll(decoder.getTypes(DART_TYPES_RETURNED, isOptional: true)); |
139 behavior.typesReturned.addAll(decoder | 195 behavior.typesReturned.addAll(decoder |
140 .getStrings(SPECIAL_TYPES_RETURNED, isOptional: true) | 196 .getStrings(SPECIAL_TYPES_RETURNED, isOptional: true) |
141 .map(SpecialType.fromName)); | 197 .map(SpecialType.fromName)); |
142 | 198 |
143 behavior.typesInstantiated | 199 behavior.typesInstantiated |
144 .addAll(decoder.getTypes(DART_TYPES_INSTANTIATED, isOptional: true)); | 200 .addAll(decoder.getTypes(DART_TYPES_INSTANTIATED, isOptional: true)); |
145 behavior.typesInstantiated.addAll(decoder | 201 behavior.typesInstantiated.addAll(decoder |
146 .getStrings(SPECIAL_TYPES_INSTANTIATED, isOptional: true) | 202 .getStrings(SPECIAL_TYPES_INSTANTIATED, isOptional: true) |
147 .map(SpecialType.fromName)); | 203 .map(SpecialType.fromName)); |
148 | 204 |
149 behavior.codeTemplateText = | 205 behavior.codeTemplateText = |
150 decoder.getString(CODE_TEMPLATE, isOptional: true); | 206 decoder.getString(CODE_TEMPLATE, isOptional: true); |
151 if (behavior.codeTemplateText != null) { | 207 if (behavior.codeTemplateText != null) { |
152 behavior.codeTemplate = js.js.parseForeignJS(behavior.codeTemplateText); | 208 behavior.codeTemplate = js.js.parseForeignJS(behavior.codeTemplateText); |
153 } | 209 } |
154 | 210 |
155 behavior.throwBehavior = | 211 behavior.throwBehavior = |
156 decoder.getEnum(THROW_BEHAVIOR, NativeThrowBehavior.values); | 212 decoder.getEnum(THROW_BEHAVIOR, NativeThrowBehavior.values); |
157 behavior.isAllocation = decoder.getBool(IS_ALLOCATION); | 213 behavior.isAllocation = decoder.getBool(IS_ALLOCATION); |
158 behavior.useGvn = decoder.getBool(USE_GVN); | 214 behavior.useGvn = decoder.getBool(USE_GVN); |
159 return behavior; | 215 return behavior; |
160 } | 216 } |
161 } | 217 } |
OLD | NEW |