diff --git a/compiler/il-structs.rkt b/compiler/il-structs.rkt index 6921bdc..e038cbb 100644 --- a/compiler/il-structs.rkt +++ b/compiler/il-structs.rkt @@ -425,10 +425,9 @@ #:transparent) -;; Give an alternative locator to the module. Assumes the module has -;; already been installed. -(define-struct: AliasModuleName! ([from : ModuleLocator] - [to : ModuleLocator]) +;; Give an alternative locator to the module as a main module. +;; Assumes the module has already been installed. +(define-struct: AliasModuleAsMain! ([from : ModuleLocator]) #:transparent) ;; Given the module locator, do any finalizing operations, like @@ -463,7 +462,7 @@ InstallModuleEntry! MarkModuleInvoked! - AliasModuleName! + AliasModuleAsMain! FinalizeModuleInvokation! )) diff --git a/js-assembler/assemble-perform-statement.rkt b/js-assembler/assemble-perform-statement.rkt index 9334be9..5c76afd 100644 --- a/js-assembler/assemble-perform-statement.rkt +++ b/js-assembler/assemble-perform-statement.rkt @@ -21,7 +21,6 @@ (CheckToplevelBound!-pos op))] - ;; FIXME: use raiseArityMismatchError [(CheckClosureArity!? op) (format #<string (ModuleLocator-name (MarkModuleInvoked!-path op))))] - [(AliasModuleName!? op) - (format "MACHINE.modules[~s] = MACHINE.modules[~s];" - (symbol->string (ModuleLocator-name (AliasModuleName!-to op))) - (symbol->string (ModuleLocator-name (AliasModuleName!-from op))))] + [(AliasModuleAsMain!? op) + (format "MACHINE.mainModules.push(MACHINE.modules[~s]);" + (symbol->string (ModuleLocator-name (AliasModuleAsMain!-from op))))] [(FinalizeModuleInvokation!? op) (format "MACHINE.modules[~s].finalizeModuleInvokation();" diff --git a/js-assembler/assemble.rkt b/js-assembler/assemble.rkt index 5c61cc0..fdfde55 100644 --- a/js-assembler/assemble.rkt +++ b/js-assembler/assemble.rkt @@ -12,8 +12,7 @@ racket/string racket/list) -(provide assemble/write-invoke-module-as-main - assemble/write-invoke +(provide assemble/write-invoke fracture assemble-basic-block assemble-statement) @@ -25,13 +24,6 @@ -(: assemble/write-invoke-module-as-main (Symbol Output-Port -> Void)) -(define (assemble/write-invoke-module-as-main module-name op) - ;; FIXME - (void)) - - - (: assemble/write-invoke ((Listof Statement) Output-Port -> Void)) ;; Writes out the JavaScript code that represents the anonymous invocation expression. ;; What's emitted is a function expression that, when invoked, runs the diff --git a/js-assembler/mini-runtime.js b/js-assembler/mini-runtime.js index 69f9e51..cdf9d6d 100644 --- a/js-assembler/mini-runtime.js +++ b/js-assembler/mini-runtime.js @@ -65,6 +65,7 @@ this.control = []; // Arrayof (U Frame CallFrame PromptFrame) this.running = false; this.modules = {}; // String -> ModuleRecord + this.mainModules = []; // Arrayof String this.params = { // currentDisplayer: DomNode -> Void @@ -139,6 +140,10 @@ // External invokation of a module. ModuleRecord.prototype.invoke = function(MACHINE, succ, fail) { + MACHINE = MACHINE || plt.runtime.currentMachine; + succ = succ || function(){}; + fail = fail || function(){}; + var oldErrorHandler = MACHINE.params['currentErrorHandler']; var afterGoodInvoke = function(MACHINE) { MACHINE.params['currentErrorHandler'] = oldErrorHandler; @@ -1305,6 +1310,9 @@ ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + (function(scope) { scope.ready = function(f) { if (runtimeIsReady) { @@ -1328,14 +1336,44 @@ setTimeout(w, 0); }; })(this); + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + // Executes all programs that have been labeled as a main module + var invokeMains = function(machine, succ, fail) { + plt.runtime.ready(function() { + machine = machine || plt.runtime.currentMachine; + succ = succ || function() {}; + fail = fail || function() {}; + var mainModules = machine.mainModules.slice(); + var loop = function() { + if (mainModules.length > 0) { + var nextModule = mainModules.shift(); + nextModule.invoke(machine, loop, fail); + } else { + succ(); + } + }; + setTimeout(loop, 0); + }); + }; + + + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// - - // Exports - exports['Primitives'] = Primitives; + + exports['currentMachine'] = new Machine(); + exports['invokeMains'] = invokeMains; + exports['Primitives'] = Primitives; + exports['ready'] = ready; // Private: the runtime library will set this flag to true when // the library has finished loading. diff --git a/js-assembler/package.rkt b/js-assembler/package.rkt index a64993c..f88e4fb 100644 --- a/js-assembler/package.rkt +++ b/js-assembler/package.rkt @@ -12,11 +12,14 @@ (provide package package-anonymous package-standalone-xhtml - get-code - get-runtime) + get-standalone-code + write-standalone-code + get-runtime + write-runtime) + ;; Packager: produce single .js files to be included to execute a -;; program. Follows module dependencies. +;; program. @@ -84,34 +87,41 @@ ;; get-runtime: -> string (define (get-runtime) - (let* ([buffer (open-output-string)] - [packaging-configuration - (make-Configuration - ;; should-follow? - (lambda (p) #t) - ;; on - (lambda (ast stmts) - (assemble/write-invoke stmts buffer) - (fprintf buffer "(MACHINE, function() { ")) - - ;; after - (lambda (ast stmts) - (fprintf buffer " }, FAIL, PARAMS);")) - - ;; last - (lambda () - (fprintf buffer "SUCCESS();")))]) - - (display (runtime:get-runtime) buffer) - (newline buffer) - (fprintf buffer "(function(MACHINE, SUCCESS, FAIL, PARAMS) {") - (make (list only-bootstrapped-code) packaging-configuration) - (fprintf buffer "})(new plt.runtime.Machine(),\nfunction(){ plt.runtime.setReadyTrue(); },\nfunction(){},\n{});\n") + (let ([buffer (open-output-string)]) + (write-runtime buffer) (get-output-string buffer))) +;; write-runtime: output-port -> void +(define (write-runtime op) + (let ([packaging-configuration + (make-Configuration + ;; should-follow? + (lambda (p) #t) + ;; on + (lambda (ast stmts) + (assemble/write-invoke stmts op) + (fprintf op "(MACHINE, function() { ")) + + ;; after + (lambda (ast stmts) + (fprintf op " }, FAIL, PARAMS);")) + + ;; last + (lambda () + (fprintf op "SUCCESS();")))]) + + (display (runtime:get-runtime) op) + (newline op) + (fprintf op "(function(MACHINE, SUCCESS, FAIL, PARAMS) {") + (make (list only-bootstrapped-code) packaging-configuration) + (fprintf op "})(plt.runtime.currentMachine,\nfunction(){ plt.runtime.setReadyTrue(); },\nfunction(){},\n{});\n"))) + + + +;; *header* : string (define *header* #< @@ -126,6 +136,7 @@ EOF ) +;; get-code: source -> string (define (get-code source-code) (let ([buffer (open-output-string)]) (package source-code @@ -134,15 +145,33 @@ EOF (get-output-string buffer))) + +;; get-standalone-code: source -> string +(define (get-standalone-code source-code) + (let ([buffer (open-output-string)]) + (write-standalone-code source-code buffer) + (get-output-string buffer))) + + +;; write-standalone-code: source output-port -> void +(define (write-standalone-code source-code op) + (package-anonymous source-code + #:should-follow? (lambda (p) #t) + #:output-port op) + (fprintf op "()(plt.runtime.currentMachine, function() {}, function() {}, {});\n")) + + + + (define *footer* #<