| 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 |