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

Side by Side Diff: lib/runtime/dart_runtime.js

Issue 1099333002: canonicalize const (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 8 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
« no previous file with comments | « lib/runtime/dart/typed_data.js ('k') | lib/src/codegen/js_codegen.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 var dart, _js_helper; 5 var dart, _js_helper;
6 (function (dart) { 6 (function (dart) {
7 'use strict'; 7 'use strict';
8 8
9 let defineProperty = Object.defineProperty; 9 let defineProperty = Object.defineProperty;
10 let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; 10 let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
11 let getOwnPropertyNames = Object.getOwnPropertyNames; 11 let getOwnPropertyNames = Object.getOwnPropertyNames;
12 let getOwnPropertySymbols = Object.getOwnPropertySymbols; 12 let getOwnPropertySymbols = Object.getOwnPropertySymbols;
13 13
14 function getOwnNamesAndSymbols(obj) {
15 return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj));
16 }
17
14 // Adapted from Angular.js 18 // Adapted from Angular.js
15 let FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; 19 let FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
16 let FN_ARG_SPLIT = /,/; 20 let FN_ARG_SPLIT = /,/;
17 let FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; 21 let FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
18 let STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; 22 let STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
19 23
20 function formalParameterList(fn) { 24 function formalParameterList(fn) {
21 let fnText,argDecl; 25 let fnText,argDecl;
22 let args=[]; 26 let args=[];
23 fnText = fn.toString().replace(STRIP_COMMENTS, ''); 27 fnText = fn.toString().replace(STRIP_COMMENTS, '');
24 argDecl = fnText.match(FN_ARGS); 28 argDecl = fnText.match(FN_ARGS);
25 29
26 let r = argDecl[1].split(FN_ARG_SPLIT); 30 let r = argDecl[1].split(FN_ARG_SPLIT);
27 for(let a in r) { 31 for (let arg of r) {
28 let arg = r[a];
29 arg.replace(FN_ARG, function(all, underscore, name){ 32 arg.replace(FN_ARG, function(all, underscore, name){
30 args.push(name); 33 args.push(name);
31 }); 34 });
32 } 35 }
33 return args; 36 return args;
34 } 37 }
35 38
36 function dload(obj, field) { 39 function dload(obj, field) {
37 if (!(field in obj)) { 40 if (!(field in obj)) {
38 throw new core.NoSuchMethodError(obj, field); 41 throw new core.NoSuchMethodError(obj, field);
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 } 320 }
318 321
319 // TODO(jmesserly): this isn't currently used, but it could be if we want 322 // TODO(jmesserly): this isn't currently used, but it could be if we want
320 // `obj is NonGroundType<T,S>` to be rejected at runtime instead of compile 323 // `obj is NonGroundType<T,S>` to be rejected at runtime instead of compile
321 // time. 324 // time.
322 function isGroundType(type) { 325 function isGroundType(type) {
323 // TODO(vsm): Cache this if we start using it at runtime. 326 // TODO(vsm): Cache this if we start using it at runtime.
324 327
325 if (type instanceof AbstractFunctionType) { 328 if (type instanceof AbstractFunctionType) {
326 if (!_isTop(type.returnType, false)) return false; 329 if (!_isTop(type.returnType, false)) return false;
327 for (var i = 0; i < type.args.length; ++i) { 330 for (let i = 0; i < type.args.length; ++i) {
328 if (!_isBottom(type.args[i], true)) return false; 331 if (!_isBottom(type.args[i], true)) return false;
329 } 332 }
330 for (var i = 0; i < type.optionals.length; ++i) { 333 for (let i = 0; i < type.optionals.length; ++i) {
331 if (!_isBottom(type.optionals[i], true)) return false; 334 if (!_isBottom(type.optionals[i], true)) return false;
332 } 335 }
333 var names = Object.getOwnPropertyNames(type.named); 336 var names = getOwnPropertyNames(type.named);
334 for (var i = 0; i < names.length; ++i) { 337 for (let i = 0; i < names.length; ++i) {
335 if (!_isBottom(type.named[names[i]], true)) return false; 338 if (!_isBottom(type.named[names[i]], true)) return false;
336 } 339 }
337 return true; 340 return true;
338 } 341 }
339 342
340 let typeArgs = safeGetOwnProperty(type, dart.typeArguments); 343 let typeArgs = safeGetOwnProperty(type, dart.typeArguments);
341 if (!typeArgs) return true; 344 if (!typeArgs) return true;
342 for (let t of typeArgs) { 345 for (let t of typeArgs) {
343 if (t != core.Object && t != dart.dynamic) return false; 346 if (t != core.Object && t != dart.dynamic) return false;
344 } 347 }
(...skipping 30 matching lines...) Expand all
375 378
376 class AbstractFunctionType { 379 class AbstractFunctionType {
377 constructor() { 380 constructor() {
378 this._stringValue = null; 381 this._stringValue = null;
379 } 382 }
380 383
381 get name() { 384 get name() {
382 if (this._stringValue) return this._stringValue; 385 if (this._stringValue) return this._stringValue;
383 386
384 var buffer = '('; 387 var buffer = '(';
385 for (var i = 0; i < this.args.length; ++i) { 388 for (let i = 0; i < this.args.length; ++i) {
386 if (i > 0) { 389 if (i > 0) {
387 buffer += ', '; 390 buffer += ', ';
388 } 391 }
389 buffer += _typeName(this.args[i]); 392 buffer += _typeName(this.args[i]);
390 } 393 }
391 if (this.optionals.length > 0) { 394 if (this.optionals.length > 0) {
392 if (this.args.length > 0) buffer += ', '; 395 if (this.args.length > 0) buffer += ', ';
393 buffer += '['; 396 buffer += '[';
394 for (var i = 0; i < this.optionals.length; ++i) { 397 for (let i = 0; i < this.optionals.length; ++i) {
395 if (i > 0) { 398 if (i > 0) {
396 buffer += ', '; 399 buffer += ', ';
397 } 400 }
398 buffer += _typeName(this.optionals[i]); 401 buffer += _typeName(this.optionals[i]);
399 } 402 }
400 buffer += ']'; 403 buffer += ']';
401 } else if (this.named.length > 0) { 404 } else if (this.named.length > 0) {
402 if (this.args.length > 0) buffer += ', '; 405 if (this.args.length > 0) buffer += ', ';
403 buffer += '{'; 406 buffer += '{';
404 let names = Object.getOwnPropertyNames(this.named).sort(); 407 let names = getOwnPropertyNames(this.named).sort();
405 for (var i = 0; i < names.length; ++i) { 408 for (let i = 0; i < names.length; ++i) {
406 if (i > 0) { 409 if (i > 0) {
407 buffer += ', '; 410 buffer += ', ';
408 } 411 }
409 buffer += names[i] + ': ' + _typeName(this.named[names[i]]); 412 buffer += names[i] + ': ' + _typeName(this.named[names[i]]);
410 } 413 }
411 buffer += '}'; 414 buffer += '}';
412 } 415 }
413 416
414 buffer += ') -> ' + _typeName(this.returnType); 417 buffer += ') -> ' + _typeName(this.returnType);
415 this._stringValue = buffer; 418 this._stringValue = buffer;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 } 519 }
517 } 520 }
518 521
519 let args1 = ft1.args; 522 let args1 = ft1.args;
520 let args2 = ft2.args; 523 let args2 = ft2.args;
521 524
522 if (args1.length > args2.length) { 525 if (args1.length > args2.length) {
523 return false; 526 return false;
524 } 527 }
525 528
526 for (var i = 0; i < args1.length; ++i) { 529 for (let i = 0; i < args1.length; ++i) {
527 if (!isSubtype_(args2[i], args1[i], true)) { 530 if (!isSubtype_(args2[i], args1[i], true)) {
528 return false; 531 return false;
529 } 532 }
530 } 533 }
531 534
532 let optionals1 = ft1.optionals; 535 let optionals1 = ft1.optionals;
533 let optionals2 = ft2.optionals; 536 let optionals2 = ft2.optionals;
534 537
535 if (args1.length + optionals1.length < args2.length + optionals2.length) { 538 if (args1.length + optionals1.length < args2.length + optionals2.length) {
536 return false; 539 return false;
537 } 540 }
538 541
539 var j = 0; 542 var j = 0;
540 for (var i = args1.length; i < args2.length; ++i, ++j) { 543 for (let i = args1.length; i < args2.length; ++i, ++j) {
541 if (!isSubtype_(args2[i], optionals1[j], true)) { 544 if (!isSubtype_(args2[i], optionals1[j], true)) {
542 return false; 545 return false;
543 } 546 }
544 } 547 }
545 548
546 for (var i = 0; i < optionals2.length; ++i, ++j) { 549 for (let i = 0; i < optionals2.length; ++i, ++j) {
547 if (!isSubtype_(optionals2[i], optionals1[j], true)) { 550 if (!isSubtype_(optionals2[i], optionals1[j], true)) {
548 return false; 551 return false;
549 } 552 }
550 } 553 }
551 554
552 let named1 = ft1.named; 555 let named1 = ft1.named;
553 let named2 = ft2.named; 556 let named2 = ft2.named;
554 557
555 let names = Object.getOwnPropertyNames(named2); 558 let names = getOwnPropertyNames(named2);
556 for (var i = 0; i < names.length; ++i) { 559 for (let i = 0; i < names.length; ++i) {
557 let name = names[i]; 560 let name = names[i];
558 let n1 = named1[name] 561 let n1 = named1[name];
559 let n2 = named2[name]; 562 let n2 = named2[name];
560 if (n1 === void 0) { 563 if (n1 === void 0) {
561 return false; 564 return false;
562 } 565 }
563 if (!isSubtype_(n2, n1, true)) { 566 if (!isSubtype_(n2, n1, true)) {
564 return false; 567 return false;
565 } 568 }
566 } 569 }
567 570
568 return true; 571 return true;
(...skipping 23 matching lines...) Expand all
592 lazySetter(value); 595 lazySetter(value);
593 return value; 596 return value;
594 } 597 }
595 desc.get = lazyGetter; 598 desc.get = lazyGetter;
596 desc.configurable = true; 599 desc.configurable = true;
597 if (writable) desc.set = lazySetter; 600 if (writable) desc.set = lazySetter;
598 defineProperty(to, name, desc); 601 defineProperty(to, name, desc);
599 } 602 }
600 603
601 function defineLazy(to, from) { 604 function defineLazy(to, from) {
602 let names = getOwnPropertyNames(from); 605 for (let name of getOwnNamesAndSymbols(from)) {
603 for (let i = 0; i < names.length; i++) {
604 let name = names[i];
605 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); 606 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name));
606 } 607 }
607 } 608 }
608 // TODO(jmesserly): these are identical, but this makes it easier to grep for. 609 // TODO(jmesserly): these are identical, but this makes it easier to grep for.
609 dart.defineLazyClass = defineLazy; 610 dart.defineLazyClass = defineLazy;
610 dart.defineLazyProperties = defineLazy; 611 dart.defineLazyProperties = defineLazy;
611 dart.defineLazyClassGeneric = defineLazyProperty; 612 dart.defineLazyClassGeneric = defineLazyProperty;
612 613
613 /** 614 /**
614 * Copy properties from source to destination object. 615 * Copy properties from source to destination object.
615 * This operation is commonly called `mixin` in JS. 616 * This operation is commonly called `mixin` in JS.
616 */ 617 */
617 function copyProperties(to, from) { 618 function copyProperties(to, from) {
618 function copyPropertiesHelper(names) { 619 for (let name of getOwnNamesAndSymbols(from)) {
619 for (let i = 0; i < names.length; i++) { 620 defineProperty(to, name, getOwnPropertyDescriptor(from, name));
620 let name = names[i];
621 defineProperty(to, name, getOwnPropertyDescriptor(from, name));
622 }
623 } 621 }
624 copyPropertiesHelper(getOwnPropertyNames(from));
625 copyPropertiesHelper(getOwnPropertySymbols(from));
626 return to; 622 return to;
627 } 623 }
628 dart.copyProperties = copyProperties; 624 dart.copyProperties = copyProperties;
629 625
630 /** 626 /**
631 * This is called whenever a derived class needs to introduce a new field, 627 * This is called whenever a derived class needs to introduce a new field,
632 * shadowing a field or getter/setter pair on its parent. 628 * shadowing a field or getter/setter pair on its parent.
633 * 629 *
634 * This is important because otherwise, trying to read or write the field 630 * This is important because otherwise, trying to read or write the field
635 * would end up calling the getter or setter, and one of those might not even 631 * would end up calling the getter or setter, and one of those might not even
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 // TODO(jmesserly): this could be faster 705 // TODO(jmesserly): this could be faster
710 function map(values) { 706 function map(values) {
711 let map = new collection.LinkedHashMap(); 707 let map = new collection.LinkedHashMap();
712 if (Array.isArray(values)) { 708 if (Array.isArray(values)) {
713 for (let i = 0, end = values.length - 1; i < end; i += 2) { 709 for (let i = 0, end = values.length - 1; i < end; i += 2) {
714 let key = values[i]; 710 let key = values[i];
715 let value = values[i + 1]; 711 let value = values[i + 1];
716 map.set(key, value); 712 map.set(key, value);
717 } 713 }
718 } else if (typeof values === 'object') { 714 } else if (typeof values === 'object') {
719 for (let key of Object.getOwnPropertyNames(values)) { 715 for (let key of getOwnPropertyNames(values)) {
720 map.set(key, values[key]); 716 map.set(key, values[key]);
721 } 717 }
722 } 718 }
723 return map; 719 return map;
724 } 720 }
725 dart.map = map; 721 dart.map = map;
726 722
727 function assert(condition) { 723 function assert(condition) {
728 // TODO(jmesserly): throw assertion error. 724 // TODO(jmesserly): throw assertion error.
729 if (!condition) throw 'assertion failed'; 725 if (!condition) throw 'assertion failed';
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 } 785 }
790 map.set(arg, value); 786 map.set(arg, value);
791 } 787 }
792 } 788 }
793 return value; 789 return value;
794 } 790 }
795 return makeGenericType; 791 return makeGenericType;
796 } 792 }
797 dart.generic = generic; 793 dart.generic = generic;
798 794
795 let _value = Symbol('_value');
796 /**
797 * Looks up a sequence of [keys] in [map], recursively, and
798 * returns the result. If the value is not found, [valueFn] will be called to
799 * add it. For example:
800 *
801 * var map = new Map();
802 * putIfAbsent(map, [1, 2, 'hi ', 'there '], () => 'world');
803 *
804 * ... will create a Map with a structure like:
805 *
806 * { 1: { 2: { 'hi ': { 'there ': 'world' } } } }
807 */
808 function multiKeyPutIfAbsent(map, keys, valueFn) {
809 for (let k of keys) {
810 let value = map.get(k);
811 if (!value) {
812 // TODO(jmesserly): most of these maps are very small (e.g. 1 item),
813 // so it may be worth optimizing for that.
814 map.set(k, value = new Map());
815 }
816 map = value;
817 }
818 if (map.has(_value)) return map.get(_value);
819 let value = valueFn();
820 map.set(_value, value);
821 return value;
822 }
823
824 /** The global constant table. */
825 let constants = new Map();
826
827 /**
828 * Canonicalize a constant object.
829 *
830 * Preconditions:
831 * - `obj` is an objects or array, not a primitive.
832 * - nested values of the object are themselves already canonicalized.
833 */
834 function constant(obj) {
835 let objectKey = [getRuntimeType(obj)];
836 // There's no guarantee in JS that names/symbols are returned in the same
837 // order. We could probably get the same order if we're judicious about
838 // initializing them, but easier to not depend on that.
839 for (let name of getOwnNamesAndSymbols(obj)) {
840 // TODO(jmesserly): we can make this faster if needed.
841 objectKey.push(name);
842 objectKey.push(obj[name]);
843 }
844 return multiKeyPutIfAbsent(constants, objectKey, () => obj);
845 }
846 dart.const = constant;
847
799 /** Sets the runtime type of `obj` to be `type` */ 848 /** Sets the runtime type of `obj` to be `type` */
800 function setType(obj, type) { 849 function setType(obj, type) {
801 obj[runtimeType] = type; 850 obj[runtimeType] = type;
802 } 851 }
803 dart.setType = setType; 852 dart.setType = setType;
804 853
805 // TODO(jmesserly): right now this is a sentinel. It should be a type object 854 // TODO(jmesserly): right now this is a sentinel. It should be a type object
806 // of some sort, assuming we keep around `dynamic` at runtime. 855 // of some sort, assuming we keep around `dynamic` at runtime.
807 dart.dynamic = { toString() { return 'dynamic'; } }; 856 dart.dynamic = { toString() { return 'dynamic'; } };
808 dart.void = { toString() { return 'void'; } }; 857 dart.void = { toString() { return 'void'; } };
809 dart.bottom = { toString() { return 'bottom'; } }; 858 dart.bottom = { toString() { return 'bottom'; } };
810 859
811 dart.global = window || global; 860 dart.global = window || global;
812 dart.JsSymbol = Symbol; 861 dart.JsSymbol = Symbol;
813 862
814 // TODO(jmesserly): hack to bootstrap the SDK 863 // TODO(jmesserly): hack to bootstrap the SDK
815 _js_helper = _js_helper || {}; 864 _js_helper = _js_helper || {};
816 _js_helper.checkNum = notNull; 865 _js_helper.checkNum = notNull;
817 866
818 })(dart || (dart = {})); 867 })(dart || (dart = {}));
OLDNEW
« no previous file with comments | « lib/runtime/dart/typed_data.js ('k') | lib/src/codegen/js_codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698