on master help sign in
javascript: apply uses an extra stackframe, not good
commit66705c7a0c360c559d1a6a0a2d60c9a723d0bee1 authorraichoo <raichoo@googlemail.com> dateSat 5 Oct 2013, 00:58 (13 years ago) parentb397692
2 files changed+35−28
js/Runtime-common.js+9−8 src/IRTS/CodegenJavaScript.hs+26−20
js/Runtime-common.js+9−8
@@ -13,9 +13,8 @@ var __IDRRT__Forgot = new __IDRRT__Type('Forgot');
1313
1414
1515/** @constructor */
16−var __IDRRT__Tailcall = function(fun, args) {
17− this.fun = fun;
18− this.args = args;
16+var __IDRRT__Cont = function(k) {
17+ this.k = k;
1918};
2019
2120var __IDRRT__ffiWrap = function(fid) {
@@ -25,7 +24,9 @@ var __IDRRT__ffiWrap = function(fid) {
2524 var arg;
2625 while (res instanceof __IDRRT__Con){
2726 arg = arguments[i];
28− res = __IDRRT__tailcall(__IDR__mAPPLY0, [res, arg]);
27+ res = __IDRRT__tailcall(function(){
28+ return __IDR__mAPPLY0(res, arg);
29+ });
2930 ++i;
3031 }
3132 return res;
@@ -38,10 +39,10 @@ var __IDRRT__Con = function(tag,vars) {
3839 this.vars = vars;
3940};
4041
41−var __IDRRT__tailcall = function(fun, args) {
42− var ret = new __IDRRT__Tailcall(fun, args);
43− while (ret instanceof __IDRRT__Tailcall)
44− ret = ret.fun.apply(this, ret.args);
42+var __IDRRT__tailcall = function(k) {
43+ var ret = k();
44+ while (ret instanceof __IDRRT__Cont)
45+ ret = ret.k();
4546
4647 return ret;
4748};
src/IRTS/CodegenJavaScript.hs+26−20
@@ -163,9 +163,11 @@ compileJS (JSTernary cond true false) =
163163 f = compileJS false in
164164 "(" ++ c ++ ")?(" ++ t ++ "):(" ++ f ++ ")"
165165
166−jsTailcall :: String -> [JS] -> JS
167−jsTailcall fun args =
168− jsCall (idrRTNamespace ++ "tailcall") [JSRaw fun, JSArray args]
166+jsTailcall :: JS -> JS
167+jsTailcall call =
168+ jsCall (idrRTNamespace ++ "tailcall") [
169+ JSFunction [] (JSReturn call)
170+ ]
169171
170172jsCall :: String -> [JS] -> JS
171173jsCall fun = JSApp (JSRaw fun)
@@ -265,7 +267,7 @@ codegenJavaScript target definitions filename outputType = do
265267 writeFile filename $ intercalate "\n" $ [ header
266268 , idrRuntime
267269 , tgtRuntime
268− ] ++ functions ++ [mainLoop]
270+ ] ++ functions ++ [compileJS mainLoop]
269271
270272 setPermissions filename (emptyPermissions { readable = True
271273 , executable = target == Node
@@ -276,15 +278,20 @@ codegenJavaScript target definitions filename outputType = do
276278 def = map (first translateNamespace) definitions
277279
278280 functions :: [String]
279− functions = map (compileJS . optJS 1 . translateDeclaration) def
280−
281− mainLoop :: String
282− mainLoop = compileJS $
283− JSSeq [ JSAlloc "main" $ Just $ JSFunction [] (
284− jsTailcall mainFun []
285− )
286− , jsCall "main" []
287− ]
281+ functions = map (compileJS . translateDeclaration) def
282+
283+ mainLoop :: JS
284+ mainLoop =
285+ if target == Node
286+ then JSSeq [ loop
287+ , jsCall "main" []
288+ ]
289+ else loop
290+ where
291+ loop :: JS
292+ loop = JSAlloc "main" $ Just $ JSFunction [] (
293+ jsTailcall $ jsCall mainFun []
294+ )
288295
289296 mainFun :: String
290297 mainFun = idrNamespace ++ translateName (MN 0 "runMain")
@@ -503,15 +510,14 @@ translateExpression (SV var) =
503510
504511translateExpression (SApp tc name vars)
505512 | False <- tc =
506− jsTailcall (translateFunctionCall name) (map JSVar vars)
513+ jsTailcall $ translateFunctionCall name vars
507514 | True <- tc =
508− JSNew (idrRTNamespace ++ "Tailcall")
509− [ JSRaw $ translateFunctionCall name
510− , JSArray $ map JSVar vars
511− ]
515+ JSNew (idrRTNamespace ++ "Cont") [JSFunction [] (
516+ JSReturn $ translateFunctionCall name vars
517+ )]
512518 where
513− translateFunctionCall name =
514− translateNamespace name ++ translateName name
519+ translateFunctionCall name vars =
520+ jsCall (translateNamespace name ++ translateName name) (map JSVar vars)
515521
516522translateExpression (SOp op vars)
517523 | LNoOp <- op = JSVar (last vars)