Revision history for JE 0.020 23 December, 2007 Additions/changes: • The Date object has been added, though it is far from com- plete. Only the Date object itself (which does not yet parse strings) and the prototype’s getTime, getYear and toGMTString methods have been added. • The escape and unescape functions have been added. • String.prototype.substr has been added. • JE::String now has a value16 method that returns the inter- nal UTF-16 version of the string. • JE::String also has now a ‘class’ method, that returns ‘String.’ This is intended primarily for internal use. • If JE::Object::Function->new is called with no_proto => 1, the resulting function will now die when called as a con- structor. This fixes an inconsistency with the spec. for all such built-in functions. • A string passed to JE::Object’s prop method’s autoload parameter is now evaluated in the package that called prop. Fixed bugs: • parseInt has now been fixed to match the spec. It used to return a string, unless the return value was 0. It also used to behave unpredictably when the radix was out of range, instead of simply returning NaN. It used always to return a positive number for radices other than 2, 8, 10 and 16. And it used not to allow capital letters in numbers. • parseFloat used to produce 0 when fed a number preceded by \v or non-ASCII whitespace. It would emit warnings, too. This has been fixed. • isNaN and isFinite have now been fixed, so they return a boo- lean, rather than a string. • String.prototype.lastIndexOf now works. • The length property of functions is now a number, not a string. • parseInt, isNan, isFinite, decodeURI, decodeURIComponent, encodeURI and encodeURIComponent used to die when called with no args. • isFinite’s logic was flawed and probably would have failed on Windows and OpenBSD. (I still don’t know whether it works, or whether it even failed before; it just has a far greater chance of being portable now.) • decodeURI and decodeURIComponent used to die when passed an encoded UTF-8 sequence for a character outside the BMP. • decodeURI(Component) used to die when the input contained an unpaired surrogate. • decodeURI(Component) used not to die when fed encoded utf8 characters > 0x10ffff. • decodeURI(Component) used simply to return undefined (instead of throwing an error) if the URI contained mal- formed UTF-8 escape sequences. • decodeURI(Component) used to die if a UTF-8 escape sequence resulted in a surrogate, contrary to the spec. • encodeURI used to encode any strings contained in $, and would produce “Use of uninitialized value” warnings if that var were undef, or return undefined if that variable caused a regexp syntax error when it was interpolated. • encodeURI used erroneously to encode $ and , • encodeURI and encodeURIComponent used to throw TypeErrors, rather than URIErrors, when stumbling across unpaired surrogates. • encodeURI(Component) used to use lc hex digits instead of uc. • Many methods and functions throughout the code could die when passed data containing a surrogate. This is fixed by ‘no warnings 'utf8'’, believe it or not. • isPrototypeOf used always to return false. • Object.length and Function.length used to be strings, but are now numbers. They also used to be enumerable, but are no longer so. • hasOwnProperty and propertyIsEnumerable used to emit warn- ings and behave incorrectly when called with no arguments. • hasOwnProperty used to semi-autovivify the property, such that propertyIsEnumerable would find it, as would for-in, but the ‘in’ op would not. • JE::LValue->can no longer dies instead of returning false when called as a class method. • The Function constructor now propagates syntax errors, instead of creating functions that do nothing. • JE’s parse and compile methods used to die when there was a regexp syntax error within a regexp literal or an invalid regexp modifier. 0.019 23 November, 2007 One bug fix: Methods and subroutines passed to bind_class that are expected to return something were sometimes called in list context. Now they are always called in sca- lar context. 0.018 5 November, 2007 - bind_class now binds hash- or array-like classes. - For methods, properties, and primitivisation, bind_class supports type-casting/filters (specify method names as 'foo:String', where 'String' is a JS function to feed the result of foo through). - Properties registered with bind_class can now be inherited by subclasses that are also registered with bind_class, as long as 'isa =>' is given a class name (not a proto- type object). - If you don't specify 'to_primitive' et al. when you call bind_class, JE will now check to see whether the object has string/number/boolean overloading, and will use that. If it doesn't, it continues to do the default JS thing (use the valueOf and toString methods). 0.017 9 September, 2007 Another alpha release, featuring just bug fixes: - Fixed a bug with the length property of strings being a Perl scalar instead of a JE::Number. - Fixed a bug that was causing line numbers in parse error messages to be counted from 1 even when another starting line number was given. -'continue' and 'break' statements now no longer clobber the return value of the previous statement, so eval('do{3; continue} while(0)') now returns 3, in accord- ance with the spec. - In a variable initialiser such as var a = b, the value is now correctly extracted from b and put inside a. Before, a reference to b would be put in a, such that 'var a=non_existent_var; do_something_with(a)' would throw an error on the second statement, not the first. - Fixed a problem with 'continue OUTER' statements in nested loops calling the loop condition on the inner loop first. E.g., in the following snippet: var x = 0, y = 0 OUTER: while(++x < 2) while(++y < 2) continue; The 'continue' would make '++y < 2' get evaluated, and then '++x < 2'; whereas only the latter should be evaluated. This problem was affecting do, while and for(;;) loops. - for(;;) loops now work when there is nothing before the first semicolon. - RegExp.prototype.exec now actually works (not fully tested) instead of always dying. - switch(non_existent_var) now dies as it should. - In a try-catch-finally statement, return, break and contin- ue statements and errors within the catch block no longer prevent the final block from running. 0.016 22 July, 2007 New feature: - Added support for filenames and line numbers in error messages. Bug fix: - Added a workaround for a perl 5.8.x bug (#24254) that was causing errors thrown from expressions within argument lists to trigger an "Attempt to free unreferenced sca- lar" warning. 0.015 10 June, 2007 - JS properties can now be bound to Perl subroutines that store/fetch the value (see JE::Types). - Class bindings now support binding of properties, as well as methods. - The constructor_name argument to bind_class is gone, since it was confusing. - bind_class now will understand 'package' to be the same as 'name' if only the latter is provided. - bind_class now creates a constructor whether or not the 'constructor' argument is passed. If it is not, the construc- tor that it makes will throw an error when invoked. - JE::Scope's get_var method has been renamed to find_var, since the name 'get_var' has the wrong implications. 0.014 30 May, 2007 Features and API changes: - Binding of Perl classes to JE with the new bind_class method - JE::Parser's delete_statement method now takes mul- tiple args. Bug fixes: - JS's eval function now uses the same parser if called from code that was parsed with a custom parser. - JE::Object's prop({...}) method used to infer 'dontenum => 0' even if the property already existed. Now it leaves the enumerability of existing properties alone if 'dontenum' is not specified explicitly. - Fixed a problem with bus errors resulting from 'autoload' handlers executing JS code when called from a tie handler - The & ^ | operators now work correctly when the second oper- and is outside the signed 32-bit range. 0.013 20 May, 2007 Features and API changes: - JavaScript properties can now be autoloaded. - &JE::Scope::var has been renamed to &JE::Scope::get_var, since it was too easily confused with JavaScript's 'var' keyword, which does something different. - Started work on parser customisation Bug fixes: - '==' and '!=' were not correctly determining which type of comparison to do when the two operands were of dif- ferent types. - throw now requires an expression, as it always should have done. 0.012 13 May, 2007 Yes, another alpha release. - JE::Object::Array's array dereference handler now returns a tied array. - JE::Object::Array's 'value' method now returns a copy of the object's internal array, instead of the array itself. - Functions created with new_function are now enumerable, just like 'alert', et al. in web browsers. Bug fixes: - Fixed the JE::Object's tie handlers so that autovivification now works, and delete behaves the way it usually does in Perl. - When $obj->prop({ ... }) creates a new property and dontenum is not given, the property is now enumerable. - Corrected Array.prototype.unshift so that it resets the array's length. - JE::Object::Function's 'apply' method now upgrades the argu- ments to the function if the function is written in Perl (version 0.011 only half-fixed the problem) 0.011 10 May, 2007 Oh no! Another alpha release! - JE::Object::Function's 'apply' method now upgrades the argu- ments to the function - JE::Object's %{} overloading now returns a tied hash that can be used to modify the object (untested and still a bit buggy). 0.010 9 May, 2007 Added three features: - &{} overloading for JE::Object::Function - numeric overloading for JE::Object - 'exists' method for JE::Object and JE::Object::Array One bug fix: - JE::Object::Array's is_enum now correctly returns false for the length property 0.009 8 May, 2007 Yet another alpha release. Here are the usual lists: New features/API changes: - Added numeric overloading to JE::Null. - Added compile as an alias for parse. - Added the 'exists' and 'class' methods to JE::Number Fixes: - JE::LValue's overloading was very buggy with anything other than simple conversion. I've fixed it and written a test script. - Corrected the bitshift operators such that numbers > 31 for the right operand now have % 32 applied, and are no longer simply treated as 31. - Corrected JE::Null->to_boolean so it returns a JE::Boolean, not a JE::String. - Stopped surrogate escape sequences in string literals from producing warnings. - Corrected JE::Number's stringification overloading to match the stringification in JavaScript (for NaN and Infinity) - A JE::Number that has a value of NaN now boolifies in Perl as false, as in JavaScript. - Fixed the constructors for the various subclasses of Error, so that they no longer throw TypeErrors when called ('new TypeError' would actually cause the whole script to die) - Corrected 'instanceof' so it throws an error if its right operand is an object but not a function - Corrected the 'prototype' properties of the various sub- classes of Error such that they now actually inherit from Error.prototype instead of directly from Object.prototype. - Fixed the << operator so it now works correctly on 64-bit machines 0.008 22 April, 2007 New features and API changes in this release: - Added JE::LValue's can method - new_function has been moved from JE to JE::Object, to make it more versatile - new_method has been written as a method of JE::Object - Changed the interface of JE::Code's 'execute' method, so that the third arg has three possible values for indicating the type of code, and is no longer a boolean - Changed the delete method of JS values to support a second arg (see JE::Types) - Renamed the 'props' method to 'keys' - Renamed JE::compile to JE::parse - Added the 'exists' and 'class' methods to JE::Boolean - Added numification overloading to JE::Boolean Bug fixes: - Fixed the ~ operator so it works on 64-bit platforms - Changed most calls to 'UNIVERSAL::isa($thing, UNIVERSAL)' to 'defined Scalar::Util::blessed $thing', since the former also works with strings containing package names (and does not necessarily tell whether something is blessed). This bug was causing strange errors. - Fixed a bug that was making errors thrown by JS functions called from within JavaScript cause lots of warnings and a nonsensical ReferenceError. - String.prototype.substring now works instead of always dying. - function and var declarations now work in else blocks and labelled statements - continue