Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 class NativeGenerator { | 7 class NativeGenerator { |
| 8 | 8 |
| 9 static bool needsIsolateAffinityTagInitialization(JavaScriptBackend backend) { | 9 static bool needsIsolateAffinityTagInitialization(JavaScriptBackend backend) { |
| 10 return backend.needToInitializeIsolateAffinityTag; | 10 return backend.needToInitializeIsolateAffinityTag; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 'convertToFastObject': convertToFastObject, | 66 'convertToFastObject': convertToFastObject, |
| 67 'getIsolateTag': getIsolateTagAccess, | 67 'getIsolateTag': getIsolateTagAccess, |
| 68 'isolateTag': isolateTagAccess, | 68 'isolateTag': isolateTagAccess, |
| 69 'dispatchPropertyName': dispatchPropertyNameAccess}); | 69 'dispatchPropertyName': dispatchPropertyNameAccess}); |
| 70 } | 70 } |
| 71 | 71 |
| 72 static String generateIsolateTagRoot() { | 72 static String generateIsolateTagRoot() { |
| 73 // TODO(sra): MD5 of contributing source code or URIs? | 73 // TODO(sra): MD5 of contributing source code or URIs? |
| 74 return 'ZxYxX'; | 74 return 'ZxYxX'; |
| 75 } | 75 } |
| 76 | |
| 77 /// Encodes the collected native information so that it can be treated by | |
| 78 /// the native info-handler below. | |
| 79 /// | |
| 80 /// The encoded information has the form: | |
| 81 /// | |
| 82 // "%": "leafTag1|leafTag2|...;nonleafTag1|...;Class1|Class2|...", | |
| 83 // | |
| 84 // If there is no data following a semicolon, the semicolon can be omitted. | |
| 85 jsAst.Expression encodeNativeInfo(Class cls) { | |
|
floitsch
2015/07/06 13:08:17
copy/paste except that it returns the encoded resu
herhut
2015/07/06 13:16:54
Why is this not static like the others? NativeGene
floitsch
2015/07/06 16:04:53
Done.
| |
| 86 List<String> leafTags = cls.nativeLeafTags; | |
| 87 List<String> nonLeafTags = cls.nativeNonLeafTags; | |
| 88 List<Class> extensions = cls.nativeExtensions; | |
| 89 | |
| 90 String formatTags(Iterable<String> tags) { | |
| 91 if (tags == null) return ''; | |
| 92 return (tags.toList() | |
| 93 ..sort()).join('|'); | |
| 94 } | |
| 95 | |
| 96 String leafStr = formatTags(leafTags); | |
| 97 String nonLeafStr = formatTags(nonLeafTags); | |
| 98 | |
| 99 StringBuffer sb = new StringBuffer(leafStr); | |
| 100 if (nonLeafStr != '') { | |
| 101 sb | |
| 102 ..write(';') | |
| 103 ..write(nonLeafStr); | |
| 104 } | |
| 105 | |
| 106 String encoding = sb.toString(); | |
| 107 | |
| 108 if (cls.isNative || encoding != '' || extensions != null) { | |
| 109 List<jsAst.Literal> parts = <jsAst.Literal>[js.stringPart(encoding)]; | |
| 110 if (extensions != null) { | |
| 111 parts | |
| 112 ..add(js.stringPart(';')) | |
| 113 ..addAll( | |
| 114 js.joinLiterals(extensions.map((Class cls) => cls.name), | |
| 115 js.stringPart('|'))); | |
| 116 } | |
| 117 return jsAst.concatenateStrings(parts, addQuotes: true); | |
| 118 } | |
| 119 return null; | |
| 120 } | |
| 121 | |
| 122 /// Returns a JavaScript template that fills the embedded globals referenced | |
| 123 /// by [interceptorsByTagAccess] and [leafTagsAccess]. | |
| 124 /// | |
| 125 /// This code must be invoked for every class that has a native info before | |
| 126 /// the program starts. | |
| 127 /// | |
| 128 /// The [infoAccess] parameter must evaluate to an expression that contains | |
| 129 /// the info (as a JavaScript string). | |
| 130 /// | |
| 131 /// The [constructorAccess] parameter must evaluate to an expression that | |
| 132 /// contains the constructor of the class. The constructor's prototype must | |
| 133 /// be set up. | |
| 134 /// | |
| 135 /// The [subclassReadGenerator] function must evaluate to a JS expression | |
| 136 /// that returns a reference to the constructor (with evaluated prototype) | |
| 137 /// of the given JS expression. | |
| 138 /// | |
| 139 /// The [interceptorsByTagAccess] must point to the embedded global | |
| 140 /// [embeddedNames.INTERCEPTORS_BY_TAG] and must be initialized with an empty | |
| 141 /// JS Object (used as a map). | |
| 142 /// | |
| 143 /// Similarly, the [leafTagsAccess] must point to the embedded global | |
| 144 /// [embeddedNames.LEAF_TAGS] and must be initialized with an empty JS Object | |
| 145 /// (used as a map). | |
| 146 /// | |
| 147 /// Both variables are passed in (instead of creating the access here) to | |
| 148 /// make sure the caller is aware of these globals. | |
| 149 jsAst.Statement buildNativeInfoHandler( | |
|
floitsch
2015/07/06 13:08:18
verbatim copy/paste.
herhut
2015/07/06 13:16:54
Same here...
floitsch
2015/07/06 16:04:53
Done.
| |
| 150 jsAst.Expression infoAccess, | |
| 151 jsAst.Expression constructorAccess, | |
| 152 jsAst.Expression subclassReadGenerator(jsAst.Expression subclass), | |
| 153 jsAst.Expression interceptorsByTagAccess, | |
| 154 jsAst.Expression leafTagsAccess) { | |
| 155 jsAst.Expression subclassRead = | |
| 156 subclassReadGenerator(js('subclasses[i]', [])); | |
|
herhut
2015/07/06 13:16:53
indentation...
floitsch
2015/07/06 16:04:53
Done.
| |
| 157 return js.statement(''' | |
| 158 // The native info looks like this: | |
| 159 // | |
| 160 // HtmlElement: { | |
| 161 // "%": "HTMLDivElement|HTMLAnchorElement;HTMLElement;FancyButton" | |
| 162 // | |
| 163 // The first two semicolon-separated parts contain dispatch tags, the | |
| 164 // third contains the JavaScript names for classes. | |
| 165 // | |
| 166 // The tags indicate that JavaScript objects with the dispatch tags | |
| 167 // (usually constructor names) HTMLDivElement, HTMLAnchorElement and | |
| 168 // HTMLElement all map to the Dart native class named HtmlElement. | |
| 169 // The first set is for effective leaf nodes in the hierarchy, the | |
| 170 // second set is non-leaf nodes. | |
| 171 // | |
| 172 // The third part contains the JavaScript names of Dart classes that | |
| 173 // extend the native class. Here, FancyButton extends HtmlElement, so | |
| 174 // the runtime needs to know that window.HTMLElement.prototype is the | |
| 175 // prototype that needs to be extended in creating the custom element. | |
| 176 // | |
| 177 // The information is used to build tables referenced by | |
| 178 // getNativeInterceptor and custom element support. | |
| 179 { | |
| 180 var nativeSpec = #info.split(";"); | |
| 181 if (nativeSpec[0]) { | |
| 182 var tags = nativeSpec[0].split("|"); | |
| 183 for (var i = 0; i < tags.length; i++) { | |
| 184 #interceptorsByTagAccess[tags[i]] = #constructor; | |
| 185 #leafTagsAccess[tags[i]] = true; | |
| 186 } | |
| 187 } | |
| 188 if (nativeSpec[1]) { | |
| 189 tags = nativeSpec[1].split("|"); | |
| 190 if (#allowNativesSubclassing) { | |
| 191 if (nativeSpec[2]) { | |
| 192 var subclasses = nativeSpec[2].split("|"); | |
| 193 for (var i = 0; i < subclasses.length; i++) { | |
| 194 var subclass = #subclassRead; | |
| 195 subclass.#nativeSuperclassTagName = tags[0]; | |
| 196 } | |
| 197 } | |
| 198 for (i = 0; i < tags.length; i++) { | |
| 199 #interceptorsByTagAccess[tags[i]] = #constructor; | |
| 200 #leafTagsAccess[tags[i]] = false; | |
| 201 } | |
| 202 } | |
| 203 } | |
| 204 } | |
| 205 ''', {'info': infoAccess, | |
| 206 'constructor': constructorAccess, | |
| 207 'subclassRead': subclassRead, | |
| 208 'interceptorsByTagAccess': interceptorsByTagAccess, | |
| 209 'leafTagsAccess': leafTagsAccess, | |
| 210 'nativeSuperclassTagName': embeddedNames.NATIVE_SUPERCLASS_TAG_NAME, | |
| 211 'allowNativesSubclassing': true}); | |
| 212 } | |
| 76 } | 213 } |
| OLD | NEW |