From 60387d58e5d92ebcca36751904f81f85e3a4c437 Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Sun, 4 Mar 2012 18:13:20 -0500 Subject: [PATCH] trying to implement js-function and js-async-function --- .../runtime-src/baselib-primitives.js | 2 +- js/js-impl.js | 62 ++++++++++++++++++- js/main.rkt | 3 + js/racket-impl.rkt | 6 ++ 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/js-assembler/runtime-src/baselib-primitives.js b/js-assembler/runtime-src/baselib-primitives.js index 3728ce7..2da9a9a 100644 --- a/js-assembler/runtime-src/baselib-primitives.js +++ b/js-assembler/runtime-src/baselib-primitives.js @@ -365,7 +365,7 @@ if (M.a === 1) { inputPort = checkInputPort(M, 'read-byte', 0); } - plt.runtime.PAUSE(function(restart) { + return plt.runtime.PAUSE(function(restart) { inputPort.callWhenReady(M, function() { restart(function(MACHINE) { plt.runtime.finalizeClosureCall(MACHINE, diff --git a/js/js-impl.js b/js/js-impl.js index ebab1c9..e97fcc8 100644 --- a/js/js-impl.js +++ b/js/js-impl.js @@ -11,6 +11,8 @@ var makeCheckArgumentType = plt.baselib.check.makeCheckArgumentType; var checkSymbolOrString = plt.baselib.check.checkSymbolOrString; var checkString = plt.baselib.check.checkString; + var checkJSFunction = makeCheckArgumentType(function(x) { return typeof(x) === 'function'; }, + "js function"); var checkAny = makeCheckArgumentType(function(x) { return true; }, "any"); @@ -90,7 +92,7 @@ 1, function(MACHINE) { var elt = MACHINE.e[MACHINE.e.length - 1]; - var obj = eval(String(elt)); + var obj = eval('(' + String(elt) + ')'); return obj; }); @@ -156,6 +158,64 @@ }); + // Lift JavaScript functions to Whalesong functions. + EXPORTS['js-function'] = + makePrimitiveProcedure( + 'js-function', + 1, + function(MACHINE) { + var f = checkJSFunction(MACHINE, 'js function', 0); + return makePrimitiveProcedure( + 'lifted js function', + plt.baselib.arity.makeArityAtLeast(0), + function(MACHINE) { + var args = [], i; + for (i = 0; i < MACHINE.a ; i = i+1) { + args.push(MACHINE.e[MACHINE.e.length - 1 - i]); + } + return f.call(null, args); + }); + }); + + EXPORTS['js-async-function'] = + makePrimitiveProcedure( + 'js-async-function', + 1, + function(MACHINE) { + var f = checkJSFunction(MACHINE, 'js function', 0); + return makeClosure( + 'lifted asynchronous js function', + plt.baselib.arity.makeArityAtLeast(0), + function(MACHINE) { + var args = [], i; + for (i = 0; i < MACHINE.a ; i = i+1) { + args.push(MACHINE.e[MACHINE.e.length - 1 - i]); + } + return plt.runtime.PAUSE( + function(restart) { + var onFail = function(e) { + restart(function(MACHINE) { + plt.baselib.exceptions.raiseFailure( + MACHINE, + plt.baselib.format.format( + "~a", + [((e && e.message) ? e.message : "unknown error")])); + + }); + }; + var onSuccess = function(v) { + restart(function(MACHINE) { + plt.runtime.finalizeClosureCall(MACHINE, v); + }); + } + args.unshift(onFail); + args.unshift(onSuccess); + return f.call(null, args); + }); + }); + }); + + EXPORTS['window'] = window; diff --git a/js/main.rkt b/js/main.rkt index 2326d3c..58e4d57 100644 --- a/js/main.rkt +++ b/js/main.rkt @@ -7,6 +7,9 @@ body call-method $ + + js-function + js-async-function window diff --git a/js/racket-impl.rkt b/js/racket-impl.rkt index f0021a4..e12a3ac 100644 --- a/js/racket-impl.rkt +++ b/js/racket-impl.rkt @@ -99,3 +99,9 @@ (define (load-script url) (error 'load-script "Not available outside JavaScript context.")) + +(define (js-function f) + (error 'js-function "Not available outside JavaScript context.")) + +(define (js-async-function f) + (error 'js-async-function "Not available outside JavaScript context.")) \ No newline at end of file