2011-12-14 * ./tomrec.xhtml & ./tomrec_web.js: forbade the use of `arguments` within a function to be unrolled. The error appears automatically in the interactive area after one pressed the "eliminate tail calls" button. * Implementation: the call `tt.check_tree_no_arguments( top_ftree );` in ./tool.tailopt.unroll.js * Unit test: ./test.unit.tailopt.no_arguments.js * Rationale: // http://wiki.ecmascript.org/doku.php?id=strawman:proper_tail_calls // " Since ES5/strict and ES-Harmony // " // " * poisons .caller and .arguments, // " * prohibits .caller from revealing a strict function, // " * poisons arguments.callee and arguments.caller, and // " * does not join arguments with parameters // " // " all calls in possible tail position MAY safely be implemented as PTC by our gc semantics safety rule. 2011-12-13 * ./tomrec.xhtml & ./tomrec_web.js: the interactive area now reports syntax error and tailopt errors after one pressed the "eliminate tail calls" button. 2011-12-09 * Moved to Python 2.7 * ./tool.tailopt.unroll.js - Added an error detection when trying to tail-optimize "impure" code, i.e. code that mixes tail calls and non-tail calls. This should help people to get a clearer idea of what tail calls are. * Example of impure code: function no_tail_sum(pair) { return _sum( 0, pair ); // <<<<< tail call (OK) function _sum( acc, x ) { if (typeof x === 'object' && 2 === x.length) { acc = _sum( acc, x[0] ); // <<<<< non-tail call on the function `_sum` that `tailopt` is trying to unwrap -> meaningless result acc = _sum( acc, x[1] ); // <<<<< non-tail call on the function `_sum` that `tailopt` is trying to unwrap -> meaningless result return acc; } return acc + x; } } no_tail_sum([[1,2],[3,[[4,5],6]]]) // >>> 21 * For more "impure" examples, see the unit test: ./test.unit.tool.tailopt.not_a_tailcall.js * Implementation details: look for: checkthrow_all_calls_removed in ./tool.tailopt.unroll.js // Throws an Error if (1) the code `ret` has a syntax error or // (2) not all calls have been removed. // // (2) makes sure all calls to dependencies have been removed, // i.e. makes sure that the original code does NOT contain any // non-tail call to a function it *also* tail calls. // // Test added after receiving feedback from Nikita Vasilev on // 2011-12-09 * Added a safety to test.unit.js to make sure all tests are properly run. * Details: look for: auto_test_arr.sort(); 2011-08-19 * Fixed bug concerning the translation of variable names in a specific "homonyms" case. * Added unit test for it. * Details: The bug was that this: function homonyms (a, b) { return sub(a, b); function sub(a, b) { return { a : a, b : b }; } } was mistakenly tail-optimized into this: function homonyms(a,b) { var undef,a,b,sub,a0,b0; a0=a; b0=b; _L_sub_: while(true) { return {a0:a0,b0:b0}; // <<< Bug: The object keys should have been `a` and `b`. return; } } Added the "homonyms" unit test case in ./test.unit.tailopt_str.js, then fixed the bug in `ttu.mapper_gen` in ./tool.tailopt.unroll.js Now the above example is correctly tail-optimized into this: function homonyms(a,b) { var undef,a,b,sub,a0,b0; a0=a; b0=b; _L_sub_: while(true) { return {a:a0,b:b0}; // <<< Fixed: The object keys are correct: `a` and `b`. return; } } ... 2010-11-06 * narcissus.jsparse.js: added the string constant narcissus.jsparse.MISSING_FUNCTION_IDENTIFIER 2010-06-17 * narcissus.jsdef.js: dropped the eval in the const generation to be able to pass narcissus.jsdef.js through a build system. 2010-04-21 * narcissus.jsparse.js: added from.req() safety to make sure narcissus.jsdef.js is fully interpreted first. The code should still work without from.js . 2010-04-20 * narcissus.jsparse.js: removed "callable RegExp object" SpiderMonkey extension, replacing: } else if ((match = opRegExp(input))) { with: } else if ((match = opRegExp.exec(input))) { 2010-04-14 * jscheck_web.js: added Opera workaround for textarea editing. * narcissus.jsparse.js: removed Array.splice SpiderMonkey extension. This line: var a = operands.splice(operands.length - arity); was replaced with: var a = operands.splice(operands.length - arity, arity); 2010-04-01 * narcissus.jsparse.js and narcissus.jsdef.js: fixed small details (extra comma, missing var) so that both now pass JSCheck without warning. 2010-03-31 * narcissus.jsparse.js: Added detection of empty child expressions cases, such as [ 'a', , 'b', 'c' ] // Always use push to add operands to an expression, to update start and end. Np.push = function (kid) { >>> The next two lines were inserted if (!kid) throw this.tokenizer.newSyntaxError('Empty child expression!'); <<< End of insertion if (kid.start < this.start) this.start = kid.start; if (this.end < kid.end) this.end = kid.end; return Array.prototype.push.call(this, kid); } 2010-03-04 * jsdef.js & jsparse.js: Fixed unreliable order bug "for (var a in opTypeNames)" introducing opTypeNamesArr. Now opRegExpSrc works in Rhino 1.6 as well. * jsdef.js & jsparse.js: In keywords, removed __proto__ spidermonkey extension, replaced it with hasOwnProperty. Now keywords(id) works in Rhino 1.6 as well. 2010-02-19 * Wrote a.html & a.js test case * Got Narcissus to work on Firefox by replacing the three __defineProperty__ / __defineGetter__ in jsparse.js * Fixed comment detection issue in line 140 of jsparse.js, replacing: if (!(match = /^\/(?:\*(?:.|\n)*?\*\/|\/.*)/(input))) with: if (!(match = /^\/(?:\*(?:[\S\s])*?\*\/|\/.*)/(input))) * First successful run of the test case a.html 2010-02-19 * With FF 3.5.8 added a truth test with out.toSource