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

Side by Side Diff: pkg/compiler/lib/src/js_backend/backend.dart

Issue 1318043005: Support user generated custom native JS classes. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: ptal Created 5 years, 2 months 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
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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 js_backend; 5 part of js_backend;
6 6
7 const VERBOSE_OPTIMIZER_HINTS = false; 7 const VERBOSE_OPTIMIZER_HINTS = false;
8 8
9 class JavaScriptItemCompilationContext extends ItemCompilationContext { 9 class JavaScriptItemCompilationContext extends ItemCompilationContext {
10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>();
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 static final Uri DART_FOREIGN_HELPER = 226 static final Uri DART_FOREIGN_HELPER =
227 new Uri(scheme: 'dart', path: '_foreign_helper'); 227 new Uri(scheme: 'dart', path: '_foreign_helper');
228 static final Uri DART_JS_MIRRORS = 228 static final Uri DART_JS_MIRRORS =
229 new Uri(scheme: 'dart', path: '_js_mirrors'); 229 new Uri(scheme: 'dart', path: '_js_mirrors');
230 static final Uri DART_JS_NAMES = 230 static final Uri DART_JS_NAMES =
231 new Uri(scheme: 'dart', path: '_js_names'); 231 new Uri(scheme: 'dart', path: '_js_names');
232 static final Uri DART_EMBEDDED_NAMES = 232 static final Uri DART_EMBEDDED_NAMES =
233 new Uri(scheme: 'dart', path: '_js_embedded_names'); 233 new Uri(scheme: 'dart', path: '_js_embedded_names');
234 static final Uri DART_ISOLATE_HELPER = 234 static final Uri DART_ISOLATE_HELPER =
235 new Uri(scheme: 'dart', path: '_isolate_helper'); 235 new Uri(scheme: 'dart', path: '_isolate_helper');
236 static final Uri PACKAGE_JS =
237 new Uri(scheme: 'package', path: 'js/js.dart');
236 238
237 static const String INVOKE_ON = '_getCachedInvocation'; 239 static const String INVOKE_ON = '_getCachedInvocation';
238 static const String START_ROOT_ISOLATE = 'startRootIsolate'; 240 static const String START_ROOT_ISOLATE = 'startRootIsolate';
239 241
240 242
241 String get patchVersion => emitter.patchVersion; 243 String get patchVersion => emitter.patchVersion;
242 244
243 bool get supportsReflection => emitter.emitter.supportsReflection; 245 bool get supportsReflection => emitter.emitter.supportsReflection;
244 246
245 final Annotations annotations; 247 final Annotations annotations;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 ClassElement jsInterceptorClass; 284 ClassElement jsInterceptorClass;
283 ClassElement jsStringClass; 285 ClassElement jsStringClass;
284 ClassElement jsArrayClass; 286 ClassElement jsArrayClass;
285 ClassElement jsNumberClass; 287 ClassElement jsNumberClass;
286 ClassElement jsIntClass; 288 ClassElement jsIntClass;
287 ClassElement jsDoubleClass; 289 ClassElement jsDoubleClass;
288 ClassElement jsNullClass; 290 ClassElement jsNullClass;
289 ClassElement jsBoolClass; 291 ClassElement jsBoolClass;
290 ClassElement jsPlainJavaScriptObjectClass; 292 ClassElement jsPlainJavaScriptObjectClass;
291 ClassElement jsUnknownJavaScriptObjectClass; 293 ClassElement jsUnknownJavaScriptObjectClass;
294 ClassElement jsJavaScriptFunctionClass;
292 295
293 ClassElement jsIndexableClass; 296 ClassElement jsIndexableClass;
294 ClassElement jsMutableIndexableClass; 297 ClassElement jsMutableIndexableClass;
295 298
296 ClassElement jsMutableArrayClass; 299 ClassElement jsMutableArrayClass;
297 ClassElement jsFixedArrayClass; 300 ClassElement jsFixedArrayClass;
298 ClassElement jsExtendableArrayClass; 301 ClassElement jsExtendableArrayClass;
299 ClassElement jsUnmodifiableArrayClass; 302 ClassElement jsUnmodifiableArrayClass;
300 ClassElement jsPositiveIntClass; 303 ClassElement jsPositiveIntClass;
301 ClassElement jsUInt32Class; 304 ClassElement jsUInt32Class;
(...skipping 17 matching lines...) Expand all
319 ConstructorElement mapLiteralConstructorEmpty; 322 ConstructorElement mapLiteralConstructorEmpty;
320 Element mapLiteralUntypedMaker; 323 Element mapLiteralUntypedMaker;
321 Element mapLiteralUntypedEmptyMaker; 324 Element mapLiteralUntypedEmptyMaker;
322 325
323 ClassElement noSideEffectsClass; 326 ClassElement noSideEffectsClass;
324 ClassElement noThrowsClass; 327 ClassElement noThrowsClass;
325 ClassElement noInlineClass; 328 ClassElement noInlineClass;
326 ClassElement forceInlineClass; 329 ClassElement forceInlineClass;
327 ClassElement irRepresentationClass; 330 ClassElement irRepresentationClass;
328 331
332 ClassElement jsAnnotationClass;
333
329 Element getInterceptorMethod; 334 Element getInterceptorMethod;
330 335
331 ClassElement jsInvocationMirrorClass; 336 ClassElement jsInvocationMirrorClass;
332 337
333 /// If [true], the compiler will emit code that logs whenever a method is 338 /// If [true], the compiler will emit code that logs whenever a method is
334 /// called. When TRACE_METHOD is 'console' this will be logged 339 /// called. When TRACE_METHOD is 'console' this will be logged
335 /// directly in the JavaScript console. When TRACE_METHOD is 'post' the 340 /// directly in the JavaScript console. When TRACE_METHOD is 'post' the
336 /// information will be sent to a server via a POST request. 341 /// information will be sent to a server via a POST request.
337 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls'); 342 static const String TRACE_METHOD = const String.fromEnvironment('traceCalls');
338 static const bool TRACE_CALLS = 343 static const bool TRACE_CALLS =
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 658
654 ConstantSystem get constantSystem => constants.constantSystem; 659 ConstantSystem get constantSystem => constants.constantSystem;
655 660
656 /// Returns constant environment for the JavaScript interpretation of the 661 /// Returns constant environment for the JavaScript interpretation of the
657 /// constants. 662 /// constants.
658 JavaScriptConstantCompiler get constants { 663 JavaScriptConstantCompiler get constants {
659 return constantCompilerTask.jsConstantCompiler; 664 return constantCompilerTask.jsConstantCompiler;
660 } 665 }
661 666
662 FunctionElement resolveExternalFunction(FunctionElement element) { 667 FunctionElement resolveExternalFunction(FunctionElement element) {
663 if (isForeign(element)) return element; 668 if (isForeign(element) || element.isJsInterop) return element;
664 return patchResolverTask.measure(() { 669 return patchResolverTask.measure(() {
665 return patchResolverTask.resolveExternalFunction(element); 670 return patchResolverTask.resolveExternalFunction(element);
666 }); 671 });
667 } 672 }
668 673
669 // TODO(karlklose): Split into findHelperFunction and findHelperClass and 674 // TODO(karlklose): Split into findHelperFunction and findHelperClass and
670 // add a check that the element has the expected kind. 675 // add a check that the element has the expected kind.
671 Element findHelper(String name) => find(jsHelperLibrary, name); 676 Element findHelper(String name) => find(jsHelperLibrary, name);
672 Element findAsyncHelper(String name) => find(asyncLibrary, name); 677 Element findAsyncHelper(String name) => find(asyncLibrary, name);
673 Element findInterceptor(String name) => find(interceptorsLibrary, name); 678 Element findInterceptor(String name) => find(interceptorsLibrary, name);
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 // For map literals, the dependency between the implementation class 1037 // For map literals, the dependency between the implementation class
1033 // and [Map] is not visible, so we have to add it manually. 1038 // and [Map] is not visible, so we have to add it manually.
1034 rti.registerRtiDependency(mapLiteralClass, cls); 1039 rti.registerRtiDependency(mapLiteralClass, cls);
1035 } else if (cls == boundClosureClass) { 1040 } else if (cls == boundClosureClass) {
1036 // TODO(johnniwinther): Is this a noop? 1041 // TODO(johnniwinther): Is this a noop?
1037 enqueueClass(enqueuer, boundClosureClass, registry); 1042 enqueueClass(enqueuer, boundClosureClass, registry);
1038 } else if (Elements.isNativeOrExtendsNative(cls)) { 1043 } else if (Elements.isNativeOrExtendsNative(cls)) {
1039 enqueue(enqueuer, getNativeInterceptorMethod, registry); 1044 enqueue(enqueuer, getNativeInterceptorMethod, registry);
1040 enqueueClass(enqueuer, jsInterceptorClass, compiler.globalDependencies); 1045 enqueueClass(enqueuer, jsInterceptorClass, compiler.globalDependencies);
1041 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry); 1046 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry);
1047 enqueueClass(enqueuer, jsJavaScriptFunctionClass, registry);
1042 } else if (cls == mapLiteralClass) { 1048 } else if (cls == mapLiteralClass) {
1043 // For map literals, the dependency between the implementation class 1049 // For map literals, the dependency between the implementation class
1044 // and [Map] is not visible, so we have to add it manually. 1050 // and [Map] is not visible, so we have to add it manually.
1045 Element getFactory(String name, int arity) { 1051 Element getFactory(String name, int arity) {
1046 // The constructor is on the patch class, but dart2js unit tests don't 1052 // The constructor is on the patch class, but dart2js unit tests don't
1047 // have a patch class. 1053 // have a patch class.
1048 ClassElement implementation = cls.patch != null ? cls.patch : cls; 1054 ClassElement implementation = cls.patch != null ? cls.patch : cls;
1049 ConstructorElement ctor = implementation.lookupConstructor(name); 1055 ConstructorElement ctor = implementation.lookupConstructor(name);
1050 if (ctor == null 1056 if (ctor == null
1051 || (Name.isPrivateName(name) 1057 || (Name.isPrivateName(name)
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 addInterceptors(jsIntClass, enqueuer, registry); 1118 addInterceptors(jsIntClass, enqueuer, registry);
1113 addInterceptors(jsPositiveIntClass, enqueuer, registry); 1119 addInterceptors(jsPositiveIntClass, enqueuer, registry);
1114 addInterceptors(jsUInt32Class, enqueuer, registry); 1120 addInterceptors(jsUInt32Class, enqueuer, registry);
1115 addInterceptors(jsUInt31Class, enqueuer, registry); 1121 addInterceptors(jsUInt31Class, enqueuer, registry);
1116 addInterceptors(jsDoubleClass, enqueuer, registry); 1122 addInterceptors(jsDoubleClass, enqueuer, registry);
1117 addInterceptors(jsNumberClass, enqueuer, registry); 1123 addInterceptors(jsNumberClass, enqueuer, registry);
1118 } else if (cls == jsPlainJavaScriptObjectClass) { 1124 } else if (cls == jsPlainJavaScriptObjectClass) {
1119 addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, registry); 1125 addInterceptors(jsPlainJavaScriptObjectClass, enqueuer, registry);
1120 } else if (cls == jsUnknownJavaScriptObjectClass) { 1126 } else if (cls == jsUnknownJavaScriptObjectClass) {
1121 addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, registry); 1127 addInterceptors(jsUnknownJavaScriptObjectClass, enqueuer, registry);
1128 } else if (cls == jsJavaScriptFunctionClass) {
1129 addInterceptors(jsJavaScriptFunctionClass, enqueuer, registry);
1122 } else if (Elements.isNativeOrExtendsNative(cls)) { 1130 } else if (Elements.isNativeOrExtendsNative(cls)) {
1123 addInterceptorsForNativeClassMembers(cls, enqueuer); 1131 addInterceptorsForNativeClassMembers(cls, enqueuer);
1124 } else if (cls == jsIndexingBehaviorInterface) { 1132 } else if (cls == jsIndexingBehaviorInterface) {
1125 // These two helpers are used by the emitter and the codegen. 1133 // These two helpers are used by the emitter and the codegen.
1126 // Because we cannot enqueue elements at the time of emission, 1134 // Because we cannot enqueue elements at the time of emission,
1127 // we make sure they are always generated. 1135 // we make sure they are always generated.
1128 enqueue(enqueuer, findHelper('isJsIndexable'), registry); 1136 enqueue(enqueuer, findHelper('isJsIndexable'), registry);
1129 } 1137 }
1130 1138
1131 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer); 1139 customElementsAnalysis.registerInstantiatedClass(cls, enqueuer);
1132 } 1140 }
1133 1141
1134 void registerUseInterceptor(Enqueuer enqueuer) { 1142 void registerUseInterceptor(Enqueuer enqueuer) {
1135 assert(!enqueuer.isResolutionQueue); 1143 assert(!enqueuer.isResolutionQueue);
1136 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return; 1144 if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return;
1137 Registry registry = compiler.globalDependencies; 1145 Registry registry = compiler.globalDependencies;
1138 enqueue(enqueuer, getNativeInterceptorMethod, registry); 1146 enqueue(enqueuer, getNativeInterceptorMethod, registry);
1139 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry); 1147 enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, registry);
1148 enqueueClass(enqueuer, jsJavaScriptFunctionClass, registry);
1140 needToInitializeIsolateAffinityTag = true; 1149 needToInitializeIsolateAffinityTag = true;
1141 needToInitializeDispatchProperty = true; 1150 needToInitializeDispatchProperty = true;
1142 } 1151 }
1143 1152
1144 JavaScriptItemCompilationContext createItemCompilationContext() { 1153 JavaScriptItemCompilationContext createItemCompilationContext() {
1145 return new JavaScriptItemCompilationContext(); 1154 return new JavaScriptItemCompilationContext();
1146 } 1155 }
1147 1156
1148 void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { 1157 void enqueueHelpers(ResolutionEnqueuer world, Registry registry) {
1149 assert(interceptorsLibrary != null); 1158 assert(interceptorsLibrary != null);
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 1469
1461 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { 1470 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) {
1462 return new native.NativeResolutionEnqueuer(world, compiler); 1471 return new native.NativeResolutionEnqueuer(world, compiler);
1463 } 1472 }
1464 1473
1465 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { 1474 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) {
1466 return new native.NativeCodegenEnqueuer(world, compiler, emitter); 1475 return new native.NativeCodegenEnqueuer(world, compiler, emitter);
1467 } 1476 }
1468 1477
1469 ClassElement defaultSuperclass(ClassElement element) { 1478 ClassElement defaultSuperclass(ClassElement element) {
1479 if (element.isJsInterop) return jsPlainJavaScriptObjectClass;
sra1 2015/10/01 20:55:28 jsJavaScriptObjectClass
Jacob 2015/10/02 20:08:15 Done.
1470 // Native classes inherit from Interceptor. 1480 // Native classes inherit from Interceptor.
1471 return element.isNative ? jsInterceptorClass : compiler.objectClass; 1481 return element.isNative ? jsInterceptorClass : compiler.objectClass;
1472 } 1482 }
1473 1483
1474 /** 1484 /**
1475 * Unit test hook that returns code of an element as a String. 1485 * Unit test hook that returns code of an element as a String.
1476 * 1486 *
1477 * Invariant: [element] must be a declaration element. 1487 * Invariant: [element] must be a declaration element.
1478 */ 1488 */
1479 String assembleCode(Element element) { 1489 String assembleCode(Element element) {
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 jsUInt31Class = findClass('JSUInt31'); 2102 jsUInt31Class = findClass('JSUInt31');
2093 jsDoubleClass = findClass('JSDouble'); 2103 jsDoubleClass = findClass('JSDouble');
2094 jsNumberClass = findClass('JSNumber'); 2104 jsNumberClass = findClass('JSNumber');
2095 jsNullClass = findClass('JSNull'); 2105 jsNullClass = findClass('JSNull');
2096 jsBoolClass = findClass('JSBool'); 2106 jsBoolClass = findClass('JSBool');
2097 jsMutableArrayClass = findClass('JSMutableArray'); 2107 jsMutableArrayClass = findClass('JSMutableArray');
2098 jsFixedArrayClass = findClass('JSFixedArray'); 2108 jsFixedArrayClass = findClass('JSFixedArray');
2099 jsExtendableArrayClass = findClass('JSExtendableArray'); 2109 jsExtendableArrayClass = findClass('JSExtendableArray');
2100 jsUnmodifiableArrayClass = findClass('JSUnmodifiableArray'); 2110 jsUnmodifiableArrayClass = findClass('JSUnmodifiableArray');
2101 jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject'); 2111 jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject');
2112 jsJavaScriptFunctionClass = findClass('JavaScriptFunction');
2102 jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject'); 2113 jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject');
2103 jsIndexableClass = findClass('JSIndexable'); 2114 jsIndexableClass = findClass('JSIndexable');
2104 jsMutableIndexableClass = findClass('JSMutableIndexable'); 2115 jsMutableIndexableClass = findClass('JSMutableIndexable');
2105 } else if (uri == DART_JS_HELPER) { 2116 } else if (uri == DART_JS_HELPER) {
2106 initializeHelperClasses(); 2117 initializeHelperClasses();
2107 assertMethod = findHelper('assertHelper'); 2118 assertMethod = findHelper('assertHelper');
2108 2119
2109 typeLiteralClass = findClass('TypeImpl'); 2120 typeLiteralClass = findClass('TypeImpl');
2110 constMapLiteralClass = findClass('ConstantMap'); 2121 constMapLiteralClass = findClass('ConstantMap');
2111 typeVariableClass = findClass('TypeVariable'); 2122 typeVariableClass = findClass('TypeVariable');
(...skipping 14 matching lines...) Expand all
2126 preserveMetadataMarker = find(library, 'preserveMetadata'); 2137 preserveMetadataMarker = find(library, 'preserveMetadata');
2127 preserveUrisMarker = find(library, 'preserveUris'); 2138 preserveUrisMarker = find(library, 'preserveUris');
2128 preserveLibraryNamesMarker = find(library, 'preserveLibraryNames'); 2139 preserveLibraryNamesMarker = find(library, 'preserveLibraryNames');
2129 } else if (uri == DART_JS_NAMES) { 2140 } else if (uri == DART_JS_NAMES) {
2130 preserveNamesMarker = find(library, 'preserveNames'); 2141 preserveNamesMarker = find(library, 'preserveNames');
2131 } else if (uri == DART_EMBEDDED_NAMES) { 2142 } else if (uri == DART_EMBEDDED_NAMES) {
2132 jsGetNameEnum = find(library, 'JsGetName'); 2143 jsGetNameEnum = find(library, 'JsGetName');
2133 jsBuiltinEnum = find(library, 'JsBuiltin'); 2144 jsBuiltinEnum = find(library, 'JsBuiltin');
2134 } else if (uri == Uris.dart_html) { 2145 } else if (uri == Uris.dart_html) {
2135 htmlLibraryIsLoaded = true; 2146 htmlLibraryIsLoaded = true;
2147 } else if (uri == PACKAGE_JS) {
2148 jsAnnotationClass = find(library, 'Js');
2136 } 2149 }
2137 annotations.onLibraryScanned(library); 2150 annotations.onLibraryScanned(library);
2138 }); 2151 });
2139 } 2152 }
2140 2153
2141 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { 2154 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) {
2142 if (!loadedLibraries.containsLibrary(Uris.dart_core)) { 2155 if (!loadedLibraries.containsLibrary(Uris.dart_core)) {
2143 return new Future.value(); 2156 return new Future.value();
2144 } 2157 }
2145 2158
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after
3098 } 3111 }
3099 } 3112 }
3100 3113
3101 /// Records that [constant] is used by the element behind [registry]. 3114 /// Records that [constant] is used by the element behind [registry].
3102 class Dependency { 3115 class Dependency {
3103 final ConstantValue constant; 3116 final ConstantValue constant;
3104 final Element annotatedElement; 3117 final Element annotatedElement;
3105 3118
3106 const Dependency(this.constant, this.annotatedElement); 3119 const Dependency(this.constant, this.annotatedElement);
3107 } 3120 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698