
1 var container = function (data) {
2 var secret = data;
3
4 return {
5 set: function (x) { secret = x; },
6 get: function () { return secret; }
7 };
8 };
9
10 var a = container (”secret−a”);
11 var b = container (”secret−b”);
12
13 a.set (”override−a”);
14
15 console.log (a.get ()); // override−a
16 console.log (b.get ()); // secret−b
Listing 5: JavaScript closures
1 var container = function (var data) {
2 var secret = data;
3
4 return {
5 [”set”] = function (var x) { secret |= x; return undefined; },
6 [”get”] = function () { return secret; }
7 };
8 };
9
10 var a = container (”secret−a”);
11 var b = container (”secret−b”);
12
13 a[”set”] (”override−a”);
14
15 cout << a[”get”] (); // override−a
16 cout << b[”get”] (); // secret−b
Listing 6: JSPP closures
1 function (var n) { body }
2 // is transformed into
3 [=] (var This, var arguments, var n) mutable −> Value
4 { body }
Listing 7: The function macro transformation
We now explain how this transformation works.
3.1 Closures
Argument capture in C++ lambda functions may be done
either by reference or by value. Doing it by reference corre-
sponds to the semantics of JavaScript, but this is problem-
atic for us because as soon as the initial variable reaches the
end of its scope, it is destroyed and any subsequent attempt
to dereference it leads to a segmentation fault.
Consequently, we actually have no choice but to use a
by-value capture mode, denoted as [=]. This means that a
new object is created for each lambda capturing the original
variable. Since our objects are manipulated by reference,
assigning a new value to an object will only update the local
reference. In order to cope with this problem, we introduce
a new assignment operator |= the purpose of which is to
update all the copies (see line 5 in listing 6).
3.2 Special argument This
Within a function’s body, JavaScript provides an implicit
variable called this, similar to the eponymous variable in
C++. Our implementation of the function macro (list-
ing 7) silently inserts such a variable in the expanded lambda
function’s prototype in order to make it available to the pro-
grammer. Note that in order to avoid conflicts with the orig-
inal this of C++, the internals of JSPP use This (with a
capital T). However, an internal JSPP macro ensures that
user-level code may continue to use this transparently.
Contrary to C++ where this is statically scoped however,
JavaScript’s this is being set dynamically in one of four
possible ways[15]:
Function call foo(...). Upon a standard function call,
this is set to undefined for a strict variant of EC-
MAScript 5, or the global object otherwise.
Method call obj.foo(...). Upon a function call result-
ing from an object property access, this is set to be
that object (obj).
Constructor new foo(...). Upon a function call used as
a constructor, this is set to a new, empty object. See
section 4.2 on the next page for more details.
Explicit foo.call(this, ...). Finally, the special func-
tions call and apply allow to explicitly set the value
of this.
Listings 8 and 9 on the facing page demonstrate that all
four ways of setting this are implemented in JSPP. Each
JSPP variable holding a function has a hidden "this" prop-
erty. When the function is called, the current value of the
property is given to the function as its first argument (list-
ing 7).
3.3 Special argument arguments
In addition to providing the special variable this, JavaScript
also does some extra processing related to the morphology
of function calls and their arguments.
Within a function’s body, JavaScript provides another im-
plicit variable called arguments, holding an array of all argu-
ments actually passed to the function. Our implementation
of the function macro (listing 7) silently inserts such a vari-
able in the expanded lambda function’s prototype in order
to make it available to the programmer.
Also, when a function call does not match the intended
number of arguments, JavaScript ignores the spurious ones
or fills the missing ones with the undefined value.
Remember that functions, as any other JSPP objects, are
stored in the Value class. All function arguments are of type
Value as well as a function’s return value. Therefore, we can
distinguish the different function types based only on their
arity.
In order to implement this distinction, the Value class
is equipped with a specific typed slot, a constructor over-
load[17] and a parenthesis () operator for each arity. This
imposes an implementation-dependent limit for the number
of arguments to functions in JSPP.
3.4 Mutable lambda functions
By default, C++ lambda functions are assumed to be
const. As this is in contradiction with the semantics of
EPITA / LRDE Technical Report #201201-TR 4