Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions cl-cc-javascript.asd
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@
(:file "v8-objects/package")
(:file "package")
(:module "syntax" :serial t :components ((:file "macros") (:file "registry") (:file "lexer") (:file "lexer-string") (:file "lexer-operator") (:file "parser")))
(:module "objects" :serial t :components ((:file "runtime-values") (:file "runtime-hooks") (:file "runtime-function-hooks") (:file "runtime-generator-hooks") (:file "runtime-collections") (:file "runtime-collections-set") (:file "runtime-map") (:file "runtime-object") (:file "runtime-object-vm") (:file "runtime-object-ops") (:file "runtime-property") (:file "runtime-coercion") (:file "runtime-symbol") (:file "runtime-weak-collections") (:file "runtime-console")))
(:module "expressions" :serial t :components ((:file "parser-expr") (:file "parser-expr-literal") (:file "parser-expr-incdec") (:file "parser-expr-postfix") (:file "parser-expr-primary") (:file "parser-expr-unary") (:file "runtime-ops") (:file "runtime")))
(:module "objects" :serial t :components ((:file "runtime-values") (:file "runtime-hooks") (:file "runtime-function-hooks") (:file "runtime-generator-hooks") (:file "runtime-collections") (:file "runtime-collections-set") (:file "runtime-map") (:file "runtime-object") (:file "runtime-object-vm") (:file "runtime-object-ops") (:file "runtime-property-descriptors") (:file "runtime-property") (:file "runtime-coercion") (:file "runtime-symbol") (:file "runtime-weak-collections") (:file "runtime-console")))
(:module "expressions" :serial t :components ((:file "parser-expr") (:file "parser-expr-gdi") (:file "parser-expr-literal") (:file "parser-expr-incdec") (:file "parser-expr-postfix") (:file "parser-expr-primary") (:file "parser-expr-unary") (:file "runtime-ops") (:file "runtime")))
(:module "statements" :serial t :components ((:file "parser-stmt") (:file "parser-stmt-binding") (:file "parser-stmt-control") (:file "parser-stmt-switch") (:file "parser-stmt-dispatch") (:file "runtime-control")))
(:module "functions" :serial t :components ((:file "parser-arrow-params") (:file "parser-arrow") (:file "parser-expr-args") (:file "parser-stmt-fn") (:file "runtime-call") (:file "runtime-object-handlers")))
(:module "classes" :serial t :components ((:file "parser-class-member-syntax") (:file "parser-class-lower-classify") (:file "parser-class-lower") (:file "parser-class") (:file "runtime-class")))
(:module "v8-objects" :serial t :components ((:file "runtime-vm-objects")))
(:module "proxies" :serial t :components ((:file "runtime-builtins-object") (:file "runtime-object-hooks")))
(:module "proxies" :serial t :components ((:file "runtime-builtins-object") (:file "runtime-builtins-object-descriptors") (:file "runtime-object-hooks")))
(:module "iterators" :serial t :components ((:file "runtime-collections-iterators") (:file "runtime-collections-zip") (:file "runtime-for-of") (:file "runtime-generator") (:file "runtime-builtins-platform-atomics") (:file "runtime-object-hooks") (:file "runtime-object-generator-hooks")))
(:module "async" :serial t :components ((:file "runtime-hooks") (:file "runtime-promise") (:file "runtime-builtins-platform-abort")))
(:module "modules" :serial t :components ((:file "parser-module") (:file "parser-module-export") (:file "runtime-module")))
Expand All @@ -66,7 +66,7 @@
(:module "errors" :serial t :components ((:file "runtime-exception") (:file "runtime-builtins")))
(:module "disposables" :serial t :components ((:file "parser-stmt-flow")))

(:module "backend" :serial t :components ((:file "runtime-function-hooks") (:file "runtime-builtins-globals") (:file "runtime-builtins-platform") (:file "runtime-builtins-platform-crypto") (:file "runtime-builtins-prelude") (:file "runtime-builtins-table-specs") (:file "runtime-builtins-table") (:file "runtime-builtins-table-globals") (:file "runtime-method-resolver") (:file "runtime-method-resolver-core") (:file "runtime-method-resolver-tables") (:file "runtime-method-resolver-dispatch") (:file "runtime-bridge-provider") (:file "vm-integration")))
(:module "backend" :serial t :components ((:file "runtime-function-hooks") (:file "runtime-builtins-globals") (:file "runtime-builtins-platform") (:file "runtime-builtins-platform-crypto") (:file "runtime-gdi-environment") (:file "runtime-gdi-declarations") (:file "runtime-builtins-prelude") (:file "runtime-builtins-table-specs") (:file "runtime-builtins-table") (:file "runtime-builtins-table-globals") (:file "runtime-method-resolver") (:file "runtime-method-resolver-core") (:file "runtime-method-resolver-tables") (:file "runtime-method-resolver-dispatch") (:file "runtime-bridge-provider") (:file "vm-integration")))
)
:in-order-to ((test-op (test-op "cl-cc-javascript/test"))))

Expand Down Expand Up @@ -121,7 +121,7 @@
(:module "json" :serial t :components ( (:file "runtime-json-test") (:file "suite")))
(:module "dates" :serial t :components ((:file "runtime-date-test") (:file "runtime-temporal-test") (:file "suite")))

(:module "backend" :serial t :components ((:file "runtime-method-resolver-dispatch-test") (:file "runtime-builtins-platform-test") (:file "runtime-object-coercion-clone-test") (:file "suite")))
(:module "backend" :serial t :components ((:file "runtime-method-resolver-dispatch-test") (:file "runtime-builtins-platform-test") (:file "runtime-object-coercion-clone-test") (:file "gdi-prelude-global-properties-test") (:file "gdi-instantiation-test") (:file "gdi-instantiation-execution-test") (:file "suite")))
(:module "v8-objects" :serial t :components ((:file "runtime-vm-objects-test") (:file "suite")))
(:module "functions" :serial t :components ((:file "suite")))
(:module "classes" :serial t :components ((:file "suite")))
Expand Down
2 changes: 1 addition & 1 deletion nix/feature-dependencies.sexp
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,4 @@
:facade-packages ("cl-cc/javascript")
:domain-package "cl-cc/javascript/backend"
:infra-package nil
:depends-on ("arrays" "async" "classes" "dates" "errors" "expressions" "functions" "intl" "iterators" "json" "numbers" "objects" "proxies" "regex" "strings" "syntax")))
:depends-on ("arrays" "async" "classes" "dates" "errors" "expressions" "functions" "intl" "iterators" "json" "numbers" "objects" "proxies" "regex" "statements" "strings" "syntax")))
33 changes: 20 additions & 13 deletions src/backend/runtime-bridge-provider.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,27 @@
(in-package #:cl-cc/javascript/backend)

(defun %js-host-bridge-entries ()
"Return (symbol . function) pairs for every fbound, non-macro %JS-* function
homed in :cl-cc/javascript."
(let ((pkg (find-package :cl-cc/javascript))
"Return (symbol . function) pairs for runtime helpers owned by this frontend."
(let ((packages (remove nil
(list (find-package :cl-cc/javascript)
(find-package :cl-cc/javascript/backend))))
(entries '()))
(when pkg
(do-symbols (sym pkg)
(when (and (eq (symbol-package sym) pkg)
(fboundp sym)
(not (macro-function sym))
(not (special-operator-p sym))
(let ((name (symbol-name sym)))
(and (>= (length name) 4)
(string= "%JS-" name :end2 4))))
(push (cons sym (fdefinition sym)) entries))))
(dolist (pkg packages)
(let ((prefix (if (eq pkg (find-package :cl-cc/javascript))
"%JS-"
"%JS-GDI-"))
(prefix-length (if (eq pkg (find-package :cl-cc/javascript))
4
8)))
(do-symbols (sym pkg)
(when (and (eq (symbol-package sym) pkg)
(fboundp sym)
(not (macro-function sym))
(not (special-operator-p sym))
(let ((name (symbol-name sym)))
(and (>= (length name) prefix-length)
(string= prefix name :end2 prefix-length))))
(push (cons sym (fdefinition sym)) entries)))))
(nreverse entries)))

(register-backend-bridge-provider #'%js-host-bridge-entries)
116 changes: 98 additions & 18 deletions src/backend/runtime-builtins-prelude.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
;;;;
;;;; Load order: after runtime-builtins-table.lisp (needs *js-builtin-specs*,
;;;; %js-builtin-ref, and all the %js-make-* / *js-* symbols).

(in-package #:cl-cc/javascript/backend)

;;; -----------------------------------------------------------------------
Expand All @@ -22,7 +21,6 @@
;;; :builtin — %js-builtin-ref lookup by key string e.g. "Set"
;;;
;;; Add new globals here; js-program-forms consumes this table automatically.

(defparameter *js-prelude-global-specs*
'((:call "console" %js-make-console)
(:var "Symbol" *js-symbol-global*)
Expand All @@ -41,7 +39,7 @@
(:namespace "Promise" "Promise")
(:namespace "Iterator" "Iterator")
(:namespace "Intl" "Intl")
(:call "globalThis" %js-make-object)
(:call "globalThis" %js-gdi-global-object)
(:var "Temporal" *js-temporal-global*)
(:var "BigInt" *js-bigint-global*)
;; URI helpers
Expand Down Expand Up @@ -98,21 +96,103 @@
before every compiled JS program so standard globals are available.")

(defun %js-prelude-form (spec)
"Emit a defparameter AST node for one entry in *js-prelude-global-specs*."
"Emit a prelude AST declaration for one entry in *js-prelude-global-specs*."
(destructuring-bind (kind js-name cl-sym) spec
(make-ast-defvar
:name (js-ident-sym js-name)
:kind 'defparameter
:value (ecase kind
(:call (%js-call cl-sym))
(:var (make-ast-var :name cl-sym))
(:function (make-ast-function :name cl-sym))
(:namespace (%js-call '%js-make-namespace-object (make-ast-quote :value cl-sym)))
(:quote (make-ast-quote :value cl-sym))
(:builtin (%js-call '%js-builtin-ref (make-ast-quote :value cl-sym)))))))
(make-ast-defvar :name
(js-ident-sym js-name)
:kind
(if (equal js-name "globalThis")
(quote defvar)
(quote defparameter))
:value
(ecase kind
(:call (%js-call cl-sym))
(:var (make-ast-var :name cl-sym))
(:function (make-ast-function :name cl-sym))
(:namespace
(%js-call (quote %js-make-namespace-object) (make-ast-quote :value cl-sym)))
(:quote (make-ast-quote :value cl-sym))
(:builtin (%js-call (quote %js-builtin-ref) (make-ast-quote :value cl-sym)))))))

(defun %js-gdi-build-script-forms (source)
(multiple-value-bind (raw lexical-bindings)
(let ((cl-cc/javascript/statements:*js-gdi-mode* t)
(cl-cc/javascript/statements:*js-gdi-lower-var-declarations* nil)
(cl-cc/javascript/statements:*js-gdi-lexical-scope-depth* 0)
(cl-cc/javascript/statements:*js-gdi-collect-global-lexical-bindings* t)
(cl-cc/javascript/statements:*js-gdi-global-lexical-bindings* nil)
(cl-cc/javascript/syntax:*js-gdi-global-reference-mode* nil))
(values (parse-js-source source)
(nreverse cl-cc/javascript/statements:*js-gdi-global-lexical-bindings*)))
(let* ((var-names (%js-gdi-var-names raw))
(functions (%js-gdi-selected-functions raw))
(function-names (mapcar (function cl-cc/ast:ast-defun-name) functions))
(all-var-names (%js-gdi-unique-names (append var-names function-names)))
(forms
(let ((cl-cc/javascript/statements:*js-gdi-mode* t)
(cl-cc/javascript/statements:*js-gdi-lower-var-declarations* t)
(cl-cc/javascript/statements:*js-gdi-collect-global-lexical-bindings* nil)
(cl-cc/javascript/syntax:*js-gdi-global-reference-mode* t)
(cl-cc/javascript/syntax:*js-gdi-global-lexical-names*
(mapcar (function car) lexical-bindings))
(cl-cc/javascript/syntax:*js-gdi-global-var-names* all-var-names)
(cl-cc/javascript/syntax:*js-gdi-shadowed-names* nil))
(parse-js-source source)))
(selected-functions (%js-gdi-selected-functions forms))
(selected-names (mapcar (function cl-cc/ast:ast-defun-name) selected-functions))
(preflight
(%js-call (quote %js-gdi-prepare)
(make-ast-quote :value lexical-bindings)
(make-ast-quote :value selected-names)
(make-ast-quote :value var-names)))
(declare-vars
(mapcar
(lambda (name)
(make-ast-defvar :name name :kind (quote defvar) :value nil))
all-var-names))
(initialize-functions
(%js-call (quote %js-gdi-create-global-functions)
(make-ast-quote :value (%js-gdi-function-metadata selected-functions))))
(create-vars
(%js-call (quote %js-gdi-create-global-vars)
(make-ast-quote :value var-names)
(make-ast-quote :value selected-names)))
(body
(loop for form in forms
append (cond
((cl-cc/ast:ast-defun-p form) nil)
((and (cl-cc/ast:ast-let-p form)
(member :var (cl-cc/ast:ast-let-declarations form)))
(list (%js-gdi-lower-declaration form :var)))
((and (cl-cc/ast:ast-let-p form)
(null (cl-cc/ast:ast-let-body form))
(intersection (cl-cc/ast:ast-let-declarations form)
(quote (:let :const))
:test
(function eq)))
(list
(%js-gdi-lower-declaration form
(if (member :const
(cl-cc/ast:ast-let-declarations
form))
:const
:let))))
((cl-cc/ast:ast-defclass-p form) (%js-gdi-lower-class form))
(t (list form))))))
(append (mapcar (function %js-prelude-form) *js-prelude-global-specs*)
(list
(%js-call (quote %js-gdi-initialize-prelude-global-properties)
(make-ast-quote :value
(mapcar
(lambda (spec)
(js-ident-sym (second spec)))
*js-prelude-global-specs*)))
preflight)
declare-vars
selected-functions
(list initialize-functions create-vars)
body))))

(defun js-program-forms (source)
"Parse JS SOURCE prepending the standard-globals prelude.
Returns top-level AST forms ready for the compiler backend."
(append (mapcar #'%js-prelude-form *js-prelude-global-specs*)
(parse-js-source source)))
"Parse a JavaScript script, instantiate its global declarations, then execute its body."
(%js-gdi-build-script-forms source))
Loading
Loading