2
0

boot.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. /* ====================================================================
  2. |
  3. | Amber Smalltalk
  4. | http://amber-lang.net
  5. |
  6. ======================================================================
  7. ======================================================================
  8. |
  9. | Copyright (c) 2010-2014
  10. | Nicolas Petton <petton.nicolas@gmail.com>
  11. |
  12. | Copyright (c) 2012-2016
  13. | The Amber team https://lolg.it/org/amber/members
  14. | Amber contributors (see /CONTRIBUTORS)
  15. |
  16. | Amber is released under the MIT license
  17. |
  18. | Permission is hereby granted, free of charge, to any person obtaining
  19. | a copy of this software and associated documentation files (the
  20. | 'Software'), to deal in the Software without restriction, including
  21. | without limitation the rights to use, copy, modify, merge, publish,
  22. | distribute, sublicense, and/or sell copies of the Software, and to
  23. | permit persons to whom the Software is furnished to do so, subject to
  24. | the following conditions:
  25. |
  26. | The above copyright notice and this permission notice shall be
  27. | included in all copies or substantial portions of the Software.
  28. |
  29. | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  30. | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  31. | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  32. | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  33. | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  34. | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  35. | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  36. |
  37. ==================================================================== */
  38. //jshint eqnull:true
  39. define(['require', './brikz', './compatibility'], function (require, Brikz) {
  40. "use strict";
  41. function inherits(child, parent) {
  42. child.prototype = Object.create(parent.prototype, {
  43. constructor: {
  44. value: child,
  45. enumerable: false, configurable: true, writable: true
  46. }
  47. });
  48. return child;
  49. }
  50. function SmalltalkGlobalsBrik(brikz, st) {
  51. // jshint evil:true
  52. var jsGlobals = new Function("return this")();
  53. var globals = Object.create(jsGlobals);
  54. globals.SmalltalkSettings = {};
  55. this.globals = globals;
  56. }
  57. function RootBrik(brikz, st) {
  58. /* Smalltalk foundational objects */
  59. /* SmalltalkRoot is the hidden root of the Amber hierarchy.
  60. All objects including `Object` inherit from SmalltalkRoot */
  61. function SmalltalkRoot() {
  62. }
  63. function SmalltalkProtoObject() {
  64. }
  65. function SmalltalkObject() {
  66. }
  67. function SmalltalkNil() {
  68. }
  69. inherits(SmalltalkProtoObject, SmalltalkRoot);
  70. inherits(SmalltalkObject, SmalltalkProtoObject);
  71. inherits(SmalltalkNil, SmalltalkObject);
  72. this.Object = SmalltalkObject;
  73. this.nil = new SmalltalkNil();
  74. // Adds an `isNil` property to the `nil` object. When sending
  75. // nil objects from one environment to another, doing
  76. // `anObject == nil` (in JavaScript) does not always answer
  77. // true as the referenced nil object might come from the other
  78. // environment.
  79. Object.defineProperty(this.nil, 'isNil', {
  80. value: true,
  81. enumerable: false, configurable: false, writable: false
  82. });
  83. // Hidden root class of the system.
  84. // Effective superclass of all classes created with `nil subclass: ...`.
  85. this.nilAsClass = {fn: SmalltalkRoot};
  86. this.__init__ = function () {
  87. var globals = brikz.smalltalkGlobals.globals;
  88. var addCoupledClass = brikz.classes.addCoupledClass;
  89. st.addPackage("Kernel-Objects");
  90. addCoupledClass("ProtoObject", undefined, "Kernel-Objects", SmalltalkProtoObject);
  91. addCoupledClass("Object", globals.ProtoObject, "Kernel-Objects", SmalltalkObject);
  92. addCoupledClass("UndefinedObject", globals.Object, "Kernel-Objects", SmalltalkNil);
  93. };
  94. this.__init__.once = true;
  95. }
  96. OrganizeBrik.deps = ["augments", "root"];
  97. function OrganizeBrik(brikz, st) {
  98. var SmalltalkObject = brikz.root.Object;
  99. function SmalltalkOrganizer() {
  100. }
  101. function SmalltalkPackageOrganizer() {
  102. this.elements = [];
  103. }
  104. function SmalltalkClassOrganizer() {
  105. this.elements = [];
  106. }
  107. inherits(SmalltalkOrganizer, SmalltalkObject);
  108. inherits(SmalltalkPackageOrganizer, SmalltalkOrganizer);
  109. inherits(SmalltalkClassOrganizer, SmalltalkOrganizer);
  110. this.__init__ = function () {
  111. var globals = brikz.smalltalkGlobals.globals;
  112. var addCoupledClass = brikz.classes.addCoupledClass;
  113. st.addPackage("Kernel-Infrastructure");
  114. addCoupledClass("Organizer", globals.Object, "Kernel-Infrastructure", SmalltalkOrganizer);
  115. addCoupledClass("PackageOrganizer", globals.Organizer, "Kernel-Infrastructure", SmalltalkPackageOrganizer);
  116. addCoupledClass("ClassOrganizer", globals.Organizer, "Kernel-Infrastructure", SmalltalkClassOrganizer);
  117. };
  118. this.__init__.once = true;
  119. this.setupClassOrganization = function (klass) {
  120. klass.organization = new SmalltalkClassOrganizer();
  121. klass.organization.theClass = klass;
  122. };
  123. this.setupPackageOrganization = function (pkg) {
  124. pkg.organization = new SmalltalkPackageOrganizer();
  125. };
  126. this.addOrganizationElement = function (owner, element) {
  127. owner.organization.elements.addElement(element);
  128. };
  129. this.removeOrganizationElement = function (owner, element) {
  130. owner.organization.elements.removeElement(element);
  131. };
  132. }
  133. SelectorsBrik.deps = ["selectorConversion"];
  134. function SelectorsBrik(brikz, st) {
  135. var selectorSet = Object.create(null);
  136. var selectors = this.selectors = [];
  137. var selectorPairs = this.selectorPairs = [];
  138. this.registerSelector = function (stSelector) {
  139. if (selectorSet[stSelector]) return null;
  140. var jsSelector = st.st2js(stSelector);
  141. selectorSet[stSelector] = true;
  142. selectors.push(stSelector);
  143. var pair = {st: stSelector, js: jsSelector};
  144. selectorPairs.push(pair);
  145. return pair;
  146. };
  147. /* Answer all method selectors based on dnu handlers */
  148. st.allSelectors = function () {
  149. return selectors;
  150. };
  151. }
  152. PackagesBrik.deps = ["organize", "root"];
  153. function PackagesBrik(brikz, st) {
  154. var setupPackageOrganization = brikz.organize.setupPackageOrganization;
  155. var SmalltalkObject = brikz.root.Object;
  156. function SmalltalkPackage() {
  157. }
  158. inherits(SmalltalkPackage, SmalltalkObject);
  159. this.__init__ = function () {
  160. var globals = brikz.smalltalkGlobals.globals;
  161. var addCoupledClass = brikz.classes.addCoupledClass;
  162. st.addPackage("Kernel-Infrastructure");
  163. addCoupledClass("Package", globals.Object, "Kernel-Infrastructure", SmalltalkPackage);
  164. };
  165. this.__init__.once = true;
  166. st.packages = {};
  167. /* Smalltalk package creation. To add a Package, use smalltalk.addPackage() */
  168. function pkg(spec) {
  169. var that = new SmalltalkPackage();
  170. that.pkgName = spec.pkgName;
  171. setupPackageOrganization(that);
  172. that.properties = spec.properties || {};
  173. return that;
  174. }
  175. /* Add a package to the smalltalk.packages object, creating a new one if needed.
  176. If pkgName is null or empty we return nil, which is an allowed package for a class.
  177. If package already exists we still update the properties of it. */
  178. st.addPackage = function (pkgName, properties) {
  179. if (!pkgName) {
  180. return null;
  181. }
  182. if (!(st.packages[pkgName])) {
  183. st.packages[pkgName] = pkg({
  184. pkgName: pkgName,
  185. properties: properties
  186. });
  187. } else {
  188. if (properties) {
  189. st.packages[pkgName].properties = properties;
  190. }
  191. }
  192. return st.packages[pkgName];
  193. };
  194. }
  195. ClassesBrik.deps = ["organize", "root", "smalltalkGlobals"];
  196. function ClassesBrik(brikz, st) {
  197. var setupClassOrganization = brikz.organize.setupClassOrganization;
  198. var addOrganizationElement = brikz.organize.addOrganizationElement;
  199. var removeOrganizationElement = brikz.organize.removeOrganizationElement;
  200. var globals = brikz.smalltalkGlobals.globals;
  201. var nilAsClass = brikz.root.nilAsClass;
  202. var SmalltalkObject = brikz.root.Object;
  203. nilAsClass.klass = {fn: SmalltalkClass};
  204. function SmalltalkBehavior() {
  205. }
  206. function SmalltalkClass() {
  207. }
  208. function SmalltalkMetaclass() {
  209. }
  210. inherits(SmalltalkBehavior, SmalltalkObject);
  211. inherits(SmalltalkClass, SmalltalkBehavior);
  212. inherits(SmalltalkMetaclass, SmalltalkBehavior);
  213. SmalltalkBehavior.prototype.toString = function () {
  214. return 'Smalltalk ' + this.className;
  215. };
  216. SmalltalkMetaclass.prototype.meta = true;
  217. this.__init__ = function () {
  218. var globals = brikz.smalltalkGlobals.globals;
  219. var addCoupledClass = brikz.classes.addCoupledClass;
  220. st.addPackage("Kernel-Classes");
  221. addCoupledClass("Behavior", globals.Object, "Kernel-Classes", SmalltalkBehavior);
  222. addCoupledClass("Metaclass", globals.Behavior, "Kernel-Classes", SmalltalkMetaclass);
  223. addCoupledClass("Class", globals.Behavior, "Kernel-Classes", SmalltalkClass);
  224. // Manually bootstrap the metaclass hierarchy
  225. globals.ProtoObject.klass.superclass = nilAsClass.klass = globals.Class;
  226. addSubclass(globals.ProtoObject.klass);
  227. };
  228. this.__init__.once = true;
  229. /* Smalltalk classes */
  230. var classes = [];
  231. /* Smalltalk class creation. A class is an instance of an automatically
  232. created metaclass object. Newly created classes (not their metaclass)
  233. should be added to the smalltalk object, see smalltalk.addClass().
  234. Superclass linking is *not* handled here, see smalltalk.init() */
  235. function klass(spec) {
  236. var setSuperClass = spec.superclass;
  237. if (!spec.superclass) {
  238. spec.superclass = nilAsClass;
  239. }
  240. var meta = metaclass(spec);
  241. var that = meta.instanceClass;
  242. that.superclass = setSuperClass;
  243. that.fn = spec.fn || inherits(function () {
  244. }, spec.superclass.fn);
  245. that.subclasses = [];
  246. setupClass(that, spec);
  247. that.className = spec.className;
  248. meta.className = spec.className + ' class';
  249. meta.superclass = spec.superclass.klass;
  250. return that;
  251. }
  252. function metaclass(spec) {
  253. var that = new SmalltalkMetaclass();
  254. that.fn = inherits(function () {
  255. }, spec.superclass.klass.fn);
  256. wireKlass(that);
  257. that.instanceClass = new that.fn();
  258. setupClass(that, {});
  259. return that;
  260. }
  261. function setupClass(klass, spec) {
  262. klass.iVarNames = spec.iVarNames || [];
  263. if (spec.pkg) {
  264. klass.pkg = spec.pkg;
  265. }
  266. setupClassOrganization(klass);
  267. Object.defineProperty(klass, "methods", {
  268. value: Object.create(null),
  269. enumerable: false, configurable: true, writable: true
  270. });
  271. }
  272. function wireKlass(klass) {
  273. Object.defineProperty(klass.fn.prototype, "klass", {
  274. value: klass,
  275. enumerable: false, configurable: true, writable: true
  276. });
  277. }
  278. this.wireKlass = wireKlass;
  279. /* Add a class to the smalltalk object, creating a new one if needed.
  280. A Package is lazily created if it does not exist with given name. */
  281. st.addClass = function (className, superclass, iVarNames, pkgName) {
  282. // While subclassing nil is allowed, it might be an error, so
  283. // warn about it.
  284. if (typeof superclass == 'undefined' || superclass && superclass.isNil) {
  285. console.warn('Compiling ' + className + ' as a subclass of `nil`. A dependency might be missing.');
  286. }
  287. return rawAddClass(pkgName, className, superclass, iVarNames, null);
  288. };
  289. function rawAddClass(pkgName, className, superclass, iVarNames, fn) {
  290. var pkg = st.packages[pkgName];
  291. if (!pkg) {
  292. throw new Error("Missing package " + pkgName);
  293. }
  294. if (superclass == null || superclass.isNil) {
  295. superclass = null;
  296. }
  297. var theClass = globals.hasOwnProperty(className) && globals[className];
  298. if (theClass && theClass.superclass == superclass && !fn) {
  299. if (iVarNames) theClass.iVarNames = iVarNames;
  300. if (pkg) theClass.pkg = pkg;
  301. } else {
  302. if (theClass) {
  303. iVarNames = iVarNames || theClass.iVarNames;
  304. st.removeClass(theClass);
  305. }
  306. theClass = globals[className] = klass({
  307. className: className,
  308. superclass: superclass,
  309. pkg: pkg,
  310. iVarNames: iVarNames,
  311. fn: fn
  312. });
  313. addSubclass(theClass);
  314. }
  315. classes.addElement(theClass);
  316. addOrganizationElement(pkg, theClass);
  317. if (st._classAdded) st._classAdded(theClass);
  318. return theClass;
  319. }
  320. st.removeClass = function (klass) {
  321. removeOrganizationElement(klass.pkg, klass);
  322. classes.removeElement(klass);
  323. removeSubclass(klass);
  324. delete globals[klass.className];
  325. };
  326. function addSubclass(klass) {
  327. if (klass.superclass) {
  328. klass.superclass.subclasses.addElement(klass);
  329. }
  330. }
  331. function removeSubclass(klass) {
  332. if (klass.superclass) {
  333. klass.superclass.subclasses.removeElement(klass);
  334. }
  335. }
  336. /* Create a new class coupling with a JavaScript constructor,
  337. and add it to the global smalltalk object.*/
  338. this.addCoupledClass = function (className, superclass, pkgName, fn) {
  339. return rawAddClass(pkgName, className, superclass, null, fn);
  340. };
  341. /* Create an alias for an existing class */
  342. st.alias = function (klass, alias) {
  343. globals[alias] = klass;
  344. };
  345. /* Answer all registered Smalltalk classes */
  346. //TODO: remove the function and make smalltalk.classes an array
  347. st.classes = this.classes = function () {
  348. return classes;
  349. };
  350. function metaSubclasses(metaclass) {
  351. return metaclass.instanceClass.subclasses
  352. .filter(function (each) {
  353. return !each.meta;
  354. })
  355. .map(function (each) {
  356. return each.klass;
  357. });
  358. }
  359. st.metaSubclasses = metaSubclasses;
  360. st.traverseClassTree = function (klass, fn) {
  361. var queue = [klass];
  362. for (var i = 0; i < queue.length; ++i) {
  363. var item = queue[i];
  364. fn(item);
  365. var subclasses = item.meta ? metaSubclasses(item) : item.subclasses;
  366. queue.push.apply(queue, subclasses);
  367. }
  368. };
  369. }
  370. MethodsBrik.deps = ["organize", "selectors", "root", "selectorConversion"];
  371. function MethodsBrik(brikz, st) {
  372. var addOrganizationElement = brikz.organize.addOrganizationElement;
  373. var registerSelector = brikz.selectors.registerSelector;
  374. var SmalltalkObject = brikz.root.Object;
  375. function SmalltalkMethod() {
  376. }
  377. inherits(SmalltalkMethod, SmalltalkObject);
  378. this.__init__ = function () {
  379. var globals = brikz.smalltalkGlobals.globals;
  380. var addCoupledClass = brikz.classes.addCoupledClass;
  381. st.addPackage("Kernel-Methods");
  382. addCoupledClass("CompiledMethod", globals.Object, "Kernel-Methods", SmalltalkMethod);
  383. };
  384. this.__init__.once = true;
  385. /* Smalltalk method object. To add a method to a class,
  386. use smalltalk.addMethod() */
  387. st.method = function (spec) {
  388. var that = new SmalltalkMethod();
  389. var selector = spec.selector;
  390. that.selector = selector;
  391. that.jsSelector = st.st2js(selector);
  392. that.args = spec.args || {};
  393. that.protocol = spec.protocol;
  394. that.source = spec.source;
  395. that.messageSends = spec.messageSends || [];
  396. that.referencedClasses = spec.referencedClasses || [];
  397. that.fn = spec.fn;
  398. return that;
  399. };
  400. /* Add/remove a method to/from a class */
  401. st.addMethod = function (method, klass) {
  402. klass.methods[method.selector] = method;
  403. method.methodClass = klass;
  404. // During the bootstrap, #addCompiledMethod is not used.
  405. // Therefore we populate the organizer here too
  406. addOrganizationElement(klass, method.protocol);
  407. var newSelectors = [];
  408. function selectorInUse(stSelector) {
  409. var pair = registerSelector(stSelector);
  410. if (pair) {
  411. newSelectors.push(pair);
  412. }
  413. }
  414. selectorInUse(method.selector);
  415. method.messageSends.forEach(selectorInUse);
  416. if (st._methodAdded) st._methodAdded(method, klass);
  417. if (st._selectorsAdded) st._selectorsAdded(newSelectors);
  418. };
  419. st.removeMethod = function (method, klass) {
  420. if (klass !== method.methodClass) {
  421. throw new Error(
  422. "Refusing to remove method " +
  423. method.methodClass.className + ">>" + method.selector +
  424. " from different class " +
  425. klass.className);
  426. }
  427. delete klass.methods[method.selector];
  428. if (st._methodRemoved) st._methodRemoved(method, klass);
  429. // Do *not* delete protocols from here.
  430. // This is handled by #removeCompiledMethod
  431. };
  432. }
  433. function AugmentsBrik(brikz, st) {
  434. /* Array extensions */
  435. Array.prototype.addElement = function (el) {
  436. if (typeof el === 'undefined') {
  437. return;
  438. }
  439. if (this.indexOf(el) == -1) {
  440. this.push(el);
  441. }
  442. };
  443. Array.prototype.removeElement = function (el) {
  444. var i = this.indexOf(el);
  445. if (i !== -1) {
  446. this.splice(i, 1);
  447. }
  448. };
  449. }
  450. SmalltalkInitBrik.deps = ["globals", "classes"];
  451. function SmalltalkInitBrik(brikz, st) {
  452. var globals = brikz.smalltalkGlobals.globals;
  453. var initialized = false;
  454. var runtimeLoadedPromise = new Promise(function (resolve, reject) {
  455. require(['./kernel-runtime'], resolve, reject);
  456. });
  457. /* Smalltalk initialization. Called on page load */
  458. st.initialize = function () {
  459. return runtimeLoadedPromise.then(function (configureWithRuntime) {
  460. if (initialized) {
  461. return;
  462. }
  463. configureWithRuntime(brikz);
  464. /* Alias definitions */
  465. st.alias(globals.Array, "OrderedCollection");
  466. st.alias(globals.Date, "Time");
  467. st.classes().forEach(function (klass) {
  468. klass._initialize();
  469. });
  470. initialized = true;
  471. });
  472. };
  473. }
  474. function SelectorConversionBrik(brikz, st) {
  475. /* Convert a Smalltalk selector into a JS selector */
  476. st.st2js = function (string) {
  477. return '_' + string
  478. .replace(/:/g, '_')
  479. .replace(/[\&]/g, '_and')
  480. .replace(/[\|]/g, '_or')
  481. .replace(/[+]/g, '_plus')
  482. .replace(/-/g, '_minus')
  483. .replace(/[*]/g, '_star')
  484. .replace(/[\/]/g, '_slash')
  485. .replace(/[\\]/g, '_backslash')
  486. .replace(/[\~]/g, '_tild')
  487. .replace(/>/g, '_gt')
  488. .replace(/</g, '_lt')
  489. .replace(/=/g, '_eq')
  490. .replace(/,/g, '_comma')
  491. .replace(/[@]/g, '_at');
  492. };
  493. /* Convert a string to a valid smalltalk selector.
  494. if you modify the following functions, also change st2js
  495. accordingly */
  496. st.js2st = function (selector) {
  497. if (selector.match(/^__/)) {
  498. return binaryJsToSt(selector);
  499. } else {
  500. return keywordJsToSt(selector);
  501. }
  502. };
  503. function keywordJsToSt(selector) {
  504. return selector.replace(/^_/, '').replace(/_/g, ':');
  505. }
  506. function binaryJsToSt(selector) {
  507. return selector
  508. .replace(/^_/, '')
  509. .replace(/_and/g, '&')
  510. .replace(/_or/g, '|')
  511. .replace(/_plus/g, '+')
  512. .replace(/_minus/g, '-')
  513. .replace(/_star/g, '*')
  514. .replace(/_slash/g, '/')
  515. .replace(/_backslash/g, '\\')
  516. .replace(/_tild/g, '~')
  517. .replace(/_gt/g, '>')
  518. .replace(/_lt/g, '<')
  519. .replace(/_eq/g, '=')
  520. .replace(/_comma/g, ',')
  521. .replace(/_at/g, '@');
  522. }
  523. st.st2prop = function (stSelector) {
  524. var colonPosition = stSelector.indexOf(':');
  525. return colonPosition === -1 ? stSelector : stSelector.slice(0, colonPosition);
  526. };
  527. }
  528. /* Adds AMD and requirejs related methods to the smalltalk object */
  529. function AMDBrik(brikz, st) {
  530. st.amdRequire = require;
  531. st.defaultTransportType = st.defaultTransportType || "amd";
  532. st.defaultAmdNamespace = st.defaultAmdNamespace || "amber_core";
  533. }
  534. /* Defines asReceiver to be present at load time */
  535. /* (logically it belongs more to PrimitiveBrik) */
  536. AsReceiverBrik.deps = ["smalltalkGlobals", "root"];
  537. function AsReceiverBrik(brikz, st) {
  538. var globals = brikz.smalltalkGlobals.globals;
  539. var nil = brikz.root.nil;
  540. /**
  541. * This function is used all over the compiled amber code.
  542. * It takes any value (JavaScript or Smalltalk)
  543. * and returns a proper Amber Smalltalk receiver.
  544. *
  545. * null or undefined -> nil,
  546. * plain JS object -> wrapped JS object,
  547. * otherwise unchanged
  548. */
  549. this.asReceiver = function (o) {
  550. if (o == null) return nil;
  551. if (typeof o === "object" || typeof o === "function") {
  552. return o.klass != null ? o : globals.JSObjectProxy._on_(o);
  553. }
  554. // IMPORTANT: This optimization (return o if typeof !== "object")
  555. // assumes all primitive types are coupled with some
  556. // (detached root) Smalltalk class so they can be returned as-is,
  557. // without boxing and looking for .klass.
  558. // KEEP THE primitives-are-coupled INVARIANT!
  559. return o;
  560. };
  561. }
  562. var api = {};
  563. var brikz = new Brikz(api);
  564. /* Making smalltalk that can load */
  565. brikz.smalltalkGlobals = SmalltalkGlobalsBrik;
  566. brikz.root = RootBrik;
  567. brikz.selectors = SelectorsBrik;
  568. brikz.organize = OrganizeBrik;
  569. brikz.selectorConversion = SelectorConversionBrik;
  570. brikz.packages = PackagesBrik;
  571. brikz.classes = ClassesBrik;
  572. brikz.methods = MethodsBrik;
  573. brikz.stInit = SmalltalkInitBrik;
  574. brikz.augments = AugmentsBrik;
  575. brikz.asReceiver = AsReceiverBrik;
  576. brikz.amd = AMDBrik;
  577. brikz.rebuild();
  578. return {
  579. api: api,
  580. nil/* TODO deprecate */: brikz.root.nil,
  581. nilAsReceiver: brikz.root.nil,
  582. dnu/* TODO deprecate */: brikz.root.nilAsClass,
  583. nilAsClass: brikz.root.nilAsClass,
  584. globals: brikz.smalltalkGlobals.globals,
  585. asReceiver: brikz.asReceiver.asReceiver
  586. };
  587. });