JSPP: Morphing C++ into Javascript


Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

JSPP: Morphing C++ into Javascript

  1. 1. JSPP: Morphing C++ into Javascript Christopher Chedeau Didier Verna EPITA Research and Development Laboratory EPITA Research and Development Laboratory christopher.chedeau@lrde.epita.fr didier.verna@lrde.epita.frAbstract The source code and some examples can be found at the project’sIn a time where the differences between static and dynamic lan- Github Repository1 .guages are starting to fade away, this paper brings one more ele- In section 2, we describe the implementation of Javascript’s dy-ment to the “convergence” picture by showing that thanks to the namic type system and object notation (a.k.a. JSON[3]). Section 3novelties from the recent C++0x standard, it is relatively easy to on page 3 provides an explanation on how to use the C++0x lambdaimplement a Javascript layer on top of C++. By that, we not only functions to emulate Javascript functions and object constructors.mean to implement the language features, but also to preserve as Section 4 on page 4 addresses the support for Javascript objectmuch of its original notation as possible. In doing so, we provide properties (most notably prototypal inheritance and contents traver-the programmer with a means to freely incorporate highly dynamic sal). Finally section 5 on page 6 discusses some other aspects of theJavascript-like code into a regular C++ program. language along with their implementation.1. Introduction 2. Data Types and JSONThe relations between static and dynamic language communities In this section, we describe the implementation of Javascript’sare notoriously tense. People from both camps often have difficul- dynamic type system and object notation.ties communicating with each other and tend to become emotionalwhen it comes to such concerns as expressiveness, safety or per- Listing 1. JSON vs PHP object creationformance. However, and perhaps due (at least partially) to the con- 1 // PHPstantly increasing popularity of modern dynamic languages such 2 $obj = array (as Ruby, Python, PHP or Javascript, those seemingly irreconcilable 3 ”number” => 42,worlds are starting to converge. For example, while C# recently 4 ”array” => array(1, 2, ”three”)provided support for dynamic types, Racket[1], a descendant from 5 );Scheme, allows you to freely mix static typing with an otherwise 6dynamically typed program. 7 // JSON C++0x[2], the new standard for the C++ language, incorporates 8 var obj = {many concepts well known in the functional or dynamic worlds, 9 number: 42,such as “lambda (anonymous) functions”, “range-based iterators” 10 array: [1, 2, ”three”](an extended iteration facility) and “initializer lists” (an extended 11 };object initialization facility). To bring one more element to this general trend towards con-vergence, this article relates the surprising discovery that given this 2.1 Primitive Typesnew C++ standard, it is relatively easy to implement Javascript in Javascript has few primitive types:C++. The idea is to make all the features of Javascript availablein C++ while preserving the original Javascript syntax as much as Boolean : true or falsepossible. Ultimately, we would like to be able to simply copy and Number : double precision floating-point valuespaste Javascript code in a C++ source file and compile it as-is. A first prototypical implementation of a syntax-preserving String : unicode-encoded character sequencesJavascript engine in C++ has been developed. The project is called undefined : special type with only one eponymous valueJSPP. JSPP currently implements all the core features of Javascriptin about 600 lines of code. Being only a prototype however, JSPP is The value undefined is the default value for (undeclared) vari-not currently optimized and does not provided the Javascript stan- ables.dard libraries. however, but are missing optimization and all the The following code demonstrates how to declare and assign astandard library implementation. JSPP is an open-source project. variable in Javascript: var foo = 1; JSPP values are implemented as instances of a single Value class.Permission to make digital or hard copies of all or part of this work for personal or This class emulates the usual boxing technique of dynamic lan-classroom use is granted without fee provided that copies are not made or distributed guages, and notably stores a type flag for each value. The abovefor profit or commercial advantage and that copies bear this notice and the full citation assignment essentially translates into the following C++ code:on the first page. To copy otherwise, to republish, to post on servers or to redistributeto lists, requires prior specific permission and/or a fee. Value foo = Integer (1);DLS 2011 October 24, 2011, Portland, Oregon, USACopyright c 2011 ACM . . . $10.00 1 http://github.com/vjeux/jspp
  2. 2. Listing 2. Original JSON Listing 3. JSPP JSON 1 var undefined, 1 var undefined, 2 string = ”DLS”, 2 string = ”DLS”, 3 number = 4.2; 3 number = 4.2; 4 4 5 var json = { 5 var obj = { 6 ”number”: 42, 6 [”number”] = 42, 7 ”string”: ”vjeux”, 7 [”string”] = ”vjeux”, 8 ”array”: [1, 2, ”three”], 8 [”array”] = {1, 2, ”three”}, 9 910 ”nested”: { 10 [”nested”] = {11 ”first”: 1, 11 [”first”] = 1,12 ”second”: 2 12 [”second”] = 213 } 13 }14 }; 14 };In JSPP, var is simply typedef’ed to Value, so as to preserve possible notation to transform a const char* into an instance ofthe original Javascript notation. The Value class constructor is a class is the following:overloaded to handle all basics C++ types such as const char*, _["key"]int, double etc. The argument-less version of the constructor isoverloaded to create an undefined value. The choice of this notation is motivated by the fact that it is rem- iniscent of the Javascript object property access syntax, and hence rather easy to remember:2.2 Composite Types obj["string"]In Javascript, everything that is not of a primitive type is an object.All Javascript objects are actually just associative arrays (or dictio- In order to implement this notation, we create a singleton classnaries) in which the keys are strings. Keys are often referred to as named Underscore equipped with an eponymous instance. Thisthe object’s “properties”. class overloads both the bracket [] and equal = operators so as to All values of a primitive type may have an object counter- create a KeyValue object, that is, an object holding both a propertypart. This allows them to have properties and specific “methods”. name (the key), and its associated value.Javascript automatically boxes primitive values when used in an Initializing an object contents can now be done in two ways: ei-object context[4]. In such a situation, the objects in question are ther by providing KeyValue objects, or only Value objects. Whenpassed by reference instead of by value[5]. In the current imple- a KeyValue object is encountered, the pair is inserted directly intomentation of JSPP, primitive values are always boxed. the object’s internal map. When a Value object is encountered, it A Javascript array is an object the keys of which are the base is regarded as an array element. As a consequence, the key is the10 string representation of the elements positions. The first element string representation of the object’s current length property, whichhas the key "0", the second has the key "1" and so on. Additionally, is automatically increased by one after the insertion.arrays have a special length property which is updated automati- 2.3 Caveatscally when new elements (with a numerical key) are added. As mentioned before, Javascript introduces a purely syntactic From a syntactical point of view, the notation provided by JSPPnotation for objects and arrays called JSON[3] (Javascript Object is heavier than the original Javascript one. The key part, notably,Notation). JSON introduces two distinct syntactic forms for cre- is more verbose, and equal signs are wider than colons. On theating regular objects and arrays, as opposed to PHP for instance, other hand, a slight improvement over JSON is that keys can inwhich requires the use of a uniform constructor call (see listing 1 fact be any expression leading to instantiating the Underscoreon the preceding page). class, whereas in Javascript, keys can only be literal strings. This Implementing this notation (or something close), turns out to be allows for dynamic computation of keys, something not possible inthe biggest challenge for JSPP. The result is depicted in listings 2 Javascript.and 3. Eventhough Javascript exhibits two different syntactic forms Unfortunately, using initializer lists introduces some corner-for variadic object and array initialization, we need a single C++0x cases. For instance, constructing an object using an empty initial-feature, called “initializer lists”[6], to implement both. ization list does not call the constructor with an empty initializer list As far as the array notation is concerned, the implementation is but without any argument instead. This means that {} is equivalentstraightforward, although one drawback is that Javascript’s square to undefined instead of an empty object.brackets [] needs to be replaced with C++’s curly braces {}. See For technical reasons not explained here, nested objects withline 8 on the corresponding listings. only one property, such as: The object notation, on the other hand, requires more trickery. {_["nested"]= {_["prop"]=1}}Javascript uses colons (:) to separate keys from their correspond-ing values. Our problem is that the colon is not an overloadable will produce a conflict between constructors. One solution to thisoperator in C++. Consequently, we choose to use the equal sign (=) problem is to explicitly cast the nested value using underscore asinstead. See for instance line 6 on the corresponding listings. a function: (val). Since Javascript object properties (keys) are strings, we use the Javascript allows both double quotes " and single quotes ’ fortype const char* in JSPP. However, values of that type are not string literals (they are completely equivalent notations). JSPP onlyclass instances, and hence cannot be operator-overloaded (some- supports double quotes " because single quotes are used to denotething required for property initialization, as explained below). One characters in C++.
  3. 3. Listing 4. Javascript functions Listing 5. JSPP functions 1 function forEach (array, func) { 1 var forEach = function (var array, var func) { 2 for (var i = 0; i < array.length; ++i) { 2 for (var i = 0; i < array[”length”]; ++i) { 3 func(i, array[i]); 3 func(i, array[i]); 4 } 4 } 5 5 return undefined; 6 }; 6 }; 7 7 8 forEach([’DLS’, 2011, ’Portland’], 8 forEach({”DLS”, 2011, ”Portland”}, 9 function (key, value) { 9 function (var key, var value) {10 console.log(key, ’−’, value); 10 cout << key << ”−” << value;11 11 return undefined;12 }); 12 });13 1314 // 0 − DLS 14 // 0 − DLS15 // 1 − 2011 15 // 1 − 201116 // 2 − Portland 16 // 2 − Portland In Javascript, multiple libraries can provide the same global than a simple offset addition. For efficiency reasons, propertiesvariable (for example $), possibly overriding a previously existing with a numerical key are stored in an actual dense array in someone. In C++ the same situation would lead to a name clash instead. implementations[10].Indeed, one cannot redeclare the same variable name twice. A None of these optimizations are currently implemented in JSPP,technique frequently used in Javascript is to insert such a global although we hope to be able to provide them in the future.variable as a property of the global object (window in the browser).When a variable is not found in any scope, Javascript will search for 3. Functionsit inside the global object. However, in C++ we cannot reproducethe same mechanism. A way to deal with this issue is to make an Javascript functions are first-class objects, as per Christopherexplicit local binding of the global variable, in the user code, for Stratchey’s definition. The language supports passing functionsinstance: as arguments to other functions, returning them as the values from other functions, and assigning them to variables etc. Listings 4var $ = global[’$’]; and 5 show how functions are defined and used in both Javascript and JSPP.Another possibility would be to use the C preprocessor (#define The new feature of C++0x called “lambda functions”[11] is aand #ifndef). convenient tool to implement Javascript function support in JSPP. In both Javascript and C++, it is possible to declare variables One very early difficulty, however, is that the syntax is radicallyin the middle of a function’s body. However, Javascript has a fea- different. In Javascript, a function definition looks like this:ture called “hoisting” which automatically removes variable dec-larations from a function’s body and puts them back at the top of function (arguments) { body }the function. As a result, the same code in Javascript and JSPP will On the other hand, a C++ lambda function definition is written ashave different semantics. Today, hoisting has a tendency to be re- follows:garded as a misfeature[7]. Doing hoisting in C++ can be done onlymanually and conversely, a hoisting-less behavior in Javascript is [capture] (arguments) constness -> returnTypepossible by manually adding new scopes every time a variable is { body }declared. In order to implement Javascript functions in JSPP, we define Finally, Javascript automatically creates a global variable if you a macro called function which operates the transformation de-assign a value to a previously undeclared variable (that is, without picted in listing 6:using the var keyword). This behavior is not possible in C++,although in Javascript, it is an important source of errors and is also Listing 6. The function macro transformationconsidered as a language misfeature. Therefore, it is not critical that 1 function (var n) { body }JSPP does not provide it. 2 // is transformed into 3 [=] (var This, var arguments, var n) mutable −> Value2.4 Optimization 4 { body }Javascript features an automatic memory management system.JSPP, on the other hand, uses a simple reference counting scheme We now explain how this transformation works.to handle garbage collection. Modern Javascript implementations use boxed objects ex- 3.1 Closurescept for immediate types (such as integers). For example, V8 Argument capture in C++ lambda functions may be done either(the Javascript engine that powers Google Chrome) uses tagged by reference or by value. Doing it by reference corresponds topointers[8] and JaegerMonkey (the one from Mozilla Firefox) does the semantics of Javascript, but this is problematic for us becauseNaN boxing[9]. In our current implementation of JSPP, objects are as soon as the initial variable reaches the end of its scope, it isalways boxed. destroyed and any subsequent attempt to dereference it leads to a Array access through a hash table is costly: keys are num- segmentation fault.bers that need to be converted into their string representation be- Consequently, we actually have no choice but to use a by-valuefore the hash table can be accessed. This process is a lot slower capture mode, denoted as [=]. This means that a new object is
  4. 4. Listing 7. Javascript closures Listing 8. JSPP closures 1 var container = function (data) { 1 var container = function (var data) { 2 var secret = data; 2 var secret = data; 3 3 4 return { 4 return { 5 set: function (x) { secret = x; }, 5 [”set”] = function (var x) { secret |= x; return undefined; }, 6 get: function () { return secret; } 6 [”get”] = function () { return secret; } 7 }; 7 }; 8 }; 8 }; 9 910 var a = container (”secret−a”); 10 var a = container (”secret−a”);11 var b = container (”secret−b”); 11 var b = container (”secret−b”);12 1213 a.set (”override−a”); 13 a[”set”] (”override−a”);14 1415 console.log (a.get ()); // override−a 15 cout << a[”get”] (); // override−a16 console.log (b.get ()); // secret−b 16 cout << b[”get”] (); // secret−bcreated for each lambda capturing the original variable. Since our able in the expanded lambda function’s prototype in order to makeobjects are manipulated by reference, assigning a new value to it available to the programmer.an object will only update the local reference. In order to cope Also, when a function call does not match the intended num-with this problem, we introduce a new assignment operator |= the ber of arguments, Javascript ignores the spurious ones or fills thepurpose of which is to update all the copies (see line 5 in listing 8). missing ones with the undefined value. Remember that functions, as any other JSPP objects, are stored3.2 Special argument This in the Value class. All function arguments are of type Value asWithin a function’s body, Javascript provides an implicit variable well as a function’s return value. Therefore, we can distinguish thecalled this, similar to the eponymous variable in C++. Our imple- different function types based only on their arity.mentation of the function macro (listing 6 on the previous page) In order to implement this distinction, the Value class issilently inserts such a variable in the expanded lambda function’s equipped with a specific typed slot, a constructor overload[13]prototype in order to make it available to the programmer. Note and a parenthesis () operator for each arity. This imposes anthat in order to avoid conflicts with the original this of C++, the implementation-dependent limit for the number of arguments tointernals of JSPP use This (with a capital T). However, an internal functions in JSPP.JSPP macro ensures that user-level code may continue to use thistransparently. 3.4 Mutable lambda functions Contrary to C++ where this is statically scoped however, By default, C++ lambda functions are assumed to be const. AsJavascript’s this is being set dynamically in one of four possi- this is in contradiction with the semantics of Javascript, we mustble ways[12]: specify our lambda functions to be mutable instead (listing 6 onFunction call foo(...). Upon a standard function call, this is the preceding page). set to undefined for a strict variant of ECMAScript 5, or the global object otherwise. 3.5 CaveatsMethod call obj.foo(...). Upon a function call resulting from In regular C++ as well as in the recent lambda functions facility, an object property access, this is set to be that object (obj). every variable needs to be explicitly typed by prepending the typeConstructor new foo(...). Upon a function call used as a con- information before its name. As a consequence, the current imple- structor, this is set to a new, empty object. See section 4.2 on mentation of JSPP requires that the programmer adds an explicit the facing page for more details. var type specifier in front of every function argument (compare for instance line 1 of listings 9 and 10 on the next page).Explicit foo.call(this, ...). Finally, the special functions In Javascript, every function’s body ends implicitly with call and apply allow to explicitly set the value of this. return undefined; Listings 9 and 10 on the next page demonstrate that all fourways of setting this are implemented in JSPP. Each JSPP vari- In JSPP, however, the programmer is required to add such a lineable holding a function has a hidden "this" property. When the manually in any function that does not otherwise return anythingfunction is called, the current value of the property is given to the useful.function as its first argument (listing 6 on the preceding page). Finally, Javascript has two ways of defining functions: named and anonymous. JSPP only supports the anonymous functions as3.3 Special argument arguments lambda functions are anonymous in C++. In practice the namedIn addition to providing the special variable this, Javascript also notation is only used for debugging purposes. We may providedoes some extra processing related to the morphology of function some syntactic sugar to give names to JSPP functions in the future.calls and their arguments. Within a function’s body, Javascript provides another implicitvariable called arguments, holding an array of all arguments actu- 4. Object Propertiesally passed to the function. Our implementation of the function After the tour of Javascript functions, we now address the moremacro (listing 6 on the previous page) silently inserts such a vari- general issue of object property management.
  5. 5. Listing 9. Javascript’s this variable Listing 10. JSPP’s this variable 1 function f (x, y) { 1 var f = function (var x, var y) { 2 console.log (”this:”, this); 2 cout << ”this: ” << this; 3 this.x = x; 3 this[”x”] = x; 4 this.y = y; 4 this[”y”] = y; 5 5 return undefined; 6 }; 6 }; 7 7 8 // New creates a new, empty object 8 // New creates a new, empty object 9 var a = new f (1, 2); // this: [object] 9 var a = new (f) (1, 2); // this: [function 40d0]10 var b = new f (3, 4); // this: [object] 10 var b = new (f) (3, 4); // this: [function 48e0]11 1112 // Unbound call 12 // Unbound call13 var c = f (5, 6); // this: undefined 13 var c = f (5, 6); // this: undefined14 1415 // Bound call 15 // Bound call16 var obj = [42]; 16 var obj = { 42 };17 obj.f = f; 17 obj[”f”] = f;18 var d = obj.f (1, 2); // this: [42] 18 var d = obj[”f”] (1, 2); // this: [42]19 1920 // Explicit call 20 // Explicit call21 var e = f.call(obj, 1, 2); // this: [42] 21 var e = f[”call”] (obj, 1, 2); // this: [42]4.1 Prototypal inheritance In order to emulate the functionality of a constructor which ini-Javascript features a class-less, prototype-based object model [14]. tializes the attributes of a new instance, Javascript uses a function.When accessing the properties of an object, Javascript performs an This constructor function contains a property named prototypeupwards traversal of the prototype chain until it finds a property which links back to an object storing the methods and attributes.with the requested name. A sample Javascript implementation of The new operator takes that function followed by a list ofthis process can be found in listing 11. We use proto to repre- arguments as arguments. It first creates an object representingsent the link to the prototype element. This is a non-standard nota- the instance of the class, with the proto property set to thetion which is however supported by both SpiderMonkey (Mozilla prototype function. Then, it calls this function with the providedFirefox) and V8 (Google Chrome). list of arguments and with the variable this bound to the instance being created. Finally it returns the object. A sample implementa- tion of this process is depicted in listing 12. Since the new keyword Listing 11. Javascript property access implementation is reserved in C++, JSPP uses a function named New (note the cap- 1 function getProperty (obj, prop) { ital N) internally. However, an internal JSPP macro ensures that 2 if (obj.hasOwnProperty (prop)) user-level code may continue to use new transparently. 3 return obj[prop]; 4 5 else if (obj. proto !== null) Listing 12. Javascript implementation of the new operator 6 return getProperty (obj. proto , prop); 1 function New (f) { 7 2 var obj = { proto : f.prototype }; 8 else 3 return function () { 9 return undefined; 4 f.apply (obj, arguments);10 } 5 return obj; 6 }; A property assignment, however, does not involve any lookup. 7 }Properties are always set directly in the corresponding object. Re- 8member that in JSPP, property access in both directions (read or 9 function Point (x, y) { this.x = x; this.y = y; }write) is accomplished by the bracket [] operator. In order to com- 10 Point.prototype = {ply with the semantics of Javascript, this operator needs to perform 11 print: function () { console.log (this.x, this.y); }a proper property lookup, with the unfortunate consequence that 12 };the lookup in question is done for nothing in the case of a write ac- 13 var p = New (Point) (10, 20);cess. Indeed, the operator itself cannot distinguish between a read 14 p.print (); // 10 20of a write access. Javascript’s new operator is not very intuitive and there is4.2 The new operator no standard way to access the prototype ( proto ) of an ob-Javascript has been designed to look like traditional object-oriented ject. Douglas Crockford[7] has designed a small function calledprogramming languages such as Java and C++. In those languages, Object.Create (listing 13 on the following page) which cre-the new operator creates an instance of a class. Javascript wants to ates a new object from the specified prototype. Both new andprovide a similar construction, although it is a class-less language. Object.create are implemented in JSPP (the latter is shownAs a consequence, the functionality of new in Javascript is slightly in listing 14 on the next page). Finally, an example of prototypaldifferent. inheritance is provided in listings 15 and 16 on the following page.
  6. 6. Listing 13. Javascript’s Object.create function Listing 14. JSPP’s Object.create function 1 Object.create (parent) { 1 Object[”create”] = function (var parent) { 2 function F () {}; 2 var F = function () { return undefined; }; 3 F.prototype = parent; 3 F[”prototype”] = parent; 4 return new F (); 4 return new (F) (); 5 }; 5 }; Listing 15. Prototypal inheritance in Javascript Listing 16. Prototypal inheritance in JSPP 1 var Point = { 1 var Point = { 2 x: 0, y: 0, 2 [”x”] = 0, [”y”] = 0, 3 print: function () { 3 [”print”] = function () { 4 console.log (this.x, this.y); 4 cout << this.x << ” ” << this.y; 5 } 5 return undefined; } 6 }; 6 }; 7 7 8 var origin = Object.create (Point); 8 var origin = Object[”create”] (Point); 9 910 var p1 = Object.create (Point); 10 var p1 = Object[”create”] (Point);11 p1.x = 10; 11 p1[”x”] = 10;12 p1.y = 20; 12 p1[”y”] = 20;13 1314 var p2 = Object.create (Point); 14 var p2 = Object[”create”] (Point);15 p2.x = 5; 15 p2[”x”] = 5;16 1617 origin.print (); // 0 0 17 origin[”print”] (); // 0 018 p1.print (); // 10 20 18 p1[”print”] (); // 10 2019 p2.print (); // 5 0 19 p2[”print”] (); // 5 04.3 Iteration around the constructor. It is also impossible to implement calls toJavascript’s for-in construction allows to iterate over the keys of the new operator without any argument. Those deficiencies are il-an object. More precisely, iteration occurs over all the keys of the lustrated in listing 19.object itself and all the keys from its prototype chain. Properties The ECMAScript standard defines two forms for the for-inthat have the (internal) Enumerable property set to false are not construction:enumerable. C++0x provides a new iteration facility called “range • for ( var variable in Expression )iteration”[15]. The syntax is as follows: • for ( LHS in Expression )for (type element : container) The C++0x range iteration facility does not allow for the secondJSPP provides a simple defining in to expand to a colon. This lets form however. The left-hand side expression is always a variableus use range iterators directly, as shown in listings 17 and 18 on the identifier[16].next page. Javascript provides some additional operators on objects (in,4.4 Caveats delete, typeof and instanceof). The keyword in has two different meanings (iteration and belonging) but we cannot ex-Our C++ implementation of property access has the same expres- press both with the same keyword. As a workaround, we usesive power as in Javascript, although it currently lacks some syntac- the keyword of in the latter case (of has been chosen to matchtic sugar. On the other hand, our syntax for iteration is completely CoffeeScript[17]). Finally, JSPP currently provides delete andidentical to that of Javascript. typeof as regular functions instead of operators. In Javascript, the bracket notation obj["prop"] is strictlyequivalent to the dot notation obj.prop. Unfortunately, the dotnotation cannot be reproduced in JSPP, which makes property ac- 5. Miscellaneouscess more cumbersome to both type and read. In this last section, we tackle various other aspects of JSPP in comparison with their respective Javascript equivalent. Listing 19. Syntactic overhead of JSPP’s new operator 1 new Point (1, 2); // Javascript 5.1 Code Organization 2 new (Point) (1, 2); // JSPP 3 C++ does not have the notion of a “top-level”. Imperative code 4 new Point; // Javascript cannot occur everywhere. It must be contained within a function’s 5 new (Point) (); // JSPP body. In order to emulate the existence of a top-level, we wrap all JSPP code inside the main function and a try-catch to handleThe new operator in JSPP suffers from a syntactic overhead. Be- errors. This part of the code is implemented in two header files,cause C++ does not provide any overloadable operator with a Javascript start.h and Javascript end.h, that the pro-higher precedence than a function call, parenthesis are required grammer is supposed to use. C++ specific includes should be added
  7. 7. Listing 17. Javascript for-in example Listing 18. JSPP for-in example 1 var object = { 1 var object = { 2 ”a”: 1, 2 [”a”] = 1, 3 ”b”: 2, 3 [”b”] = 2, 4 ”c”: 3 4 [”c”] = 3 5 }; 5 }; 6 6 7 for (var i in object) { 7 for (var i in object) { 8 console.log (i, object[i]); 8 cout << i << ” − ” << object[i]; 9 } 9 }10 1011 // a − 1 11 // a − 112 // b − 2 12 // b − 213 // c − 3 13 // c − 3before Javascript start.h. On the other hand, JSPP specific argument and always returns undefined. As their use is limited inincludes should be added after it, as demonstrated in listing 20. practice, JSPP currently does not provide any equivalent. Compiling a JSPP program is very easy. One simply needs tocompile the source file using g++ (GNU Compiler Collection for 5.5 ExceptionsC++) in C++0x mode: The Javascript exception mechanism is directly borrowed fromg++ -std=gnu++0x jspp_file.cpp C++, therefore we can use it directly, as shown in listings 21 and 22 on the following page, with some precautions. Most notably, weAt the time of this writing, g++ version 4.6 is the only compiler to make sure to cast the thrown argument into an instance of Value.support enough of the C++0x standard to be able to compile JSPP. In order to do that, a macro defines throw to translate into throw =. The equal = operator for underscore transforms the argument Listing 20. JSPP program skeleton into an instance of Value. In a similar vein, the argument to catch 1 // C++ Includes in C++ needs to be typed. A simple macro works around this in 2 JSPP by providing the type annotation automatically. 3 #include ”../src/js start.h” A further extension of JSPP will be to implement a way to dis- 4 play the stack trace in order to improve the programmer’s debug- 5 // JSPP Includes ging experience. 6 7 // JSPP Code 5.6 Automatic semi-column ; insertion 8 Like C++, Javascript uses semi-columns ; as statement delimiters. 9 #include ”../src/js end.h” In order to make the language friendly to new developers, there is a heuristic to insert semi-columns automatically during the parsing5.2 Control Structures phase in Javascript [18]. It is impossible to implement this in JSPP without modifying the C++ compiler. Therefore, JSPP does notAlthough C++ and Javascript have similar control structures (if, support automatic semi-column insertion.for, while, do-while, switch etc.), some differences remain.The C++ switch statement only works with integers whereas 5.7 Properties importationJavascript allows any data type. The break and continue instruc- The with instruction of Javascript is a relatively unknown con-tions in Javascript accept a label name as an argument. This allows struct that imports all the properties of an object as local vari-to exit from more than one loop at a time. ables. Mozilla recommends against using it and ECMAScript 55.3 Comments strict mode goes even as far as forbidding its use altogether. As there is no simple way to emulate this in C++, JSPP does not sup-Javascript and C++ share the same comment notation. Both single- port it.line // and multi-line /* */ comments are available in JSSP. 5.8 The eval function5.4 Operators Although eval is often considered as bad practice in user-levelJavascript has many operators in common with C++. All of them code, it plays an essential role in dynamic languages (read-eval-can be overloaded to match the Javascript behavior. Javascript also print loop implementation, reflexivity, dynamic code creation andhas some specific operators without any C++ counterpart. The execution etc.). Unfortunately, this is not possible to implement indifficulty here is that it is impossible to implement them in terms C++ as the code is compiled once and for all. The lack of an evalof a preprocessor macro, as macros can only define new identifiers function is probably the biggest downside of JSPP.(for instance, it is impossible to define a === macro). As a consequence, strict comparison operators (=== and !==)are defined with two macros named is and isnt (this is in fact 6. Conclusionalong the lines of what CoffeeScript[17] does). Another macro In this paper, we have demonstrated that in a time where the dif-transforms a is b into a * == b. With the appropriate oper- ferences between static and dynamic languages are starting to fadeator overloading, this behaves in compliance with Javascript. away, the novelties from the recent C++0x standard, makes it is Javascript provides two special operators for right unsigned relatively easy to implement a Javascript layer on top of C++, pro-bitwise shift (>>> and >>>=) and a void operator that gobbles its viding not only the features of the language, but also much of its
  8. 8. Listing 21. Javascript exceptions Listing 22. JSPP exceptions 1 var problematic = function () { throw ”Exception!”; }; 1 var problematic = function () { throw ”Exception!”; }; 2 2 3 try { 3 try { 4 problematic (); 4 problematic (); 5 } catch (e) { 5 } catch (e) { 6 console.log (”Error:”, e); 6 cout << ”Error: ” << e; 7 } 7 } 8 8 9 // Error: Exception! 9 // Error: Exception!original notation. The key elements of C++0x in this context are the most recent striking examples in this matter. Finally, just likelambda functions, range-based iteration and initializer lists, a set of Clojure helps bringing more people from Java to Lisp, it is possiblefeatures directly inspired from dynamic or functional languages. that JSPP will help bring more people from C++ to Javascript. A prototype implementation of such a Javascript layer, calledJSPP, has been presented. More precisely, we have shed some Referenceslight on the exact amount of the original JSON syntax we areable to reproduce, how Javascript functions are supported, how [1] Matthias Felleisen. Racket. http://racket-lang.org/.Javascript’s prototypal inheritance scheme can be emulated and [2] Bjarne Stroustrup. C++0x - the next iso c++ standard. http://www2.we have also outlined some other various aspects of the language research.att.com/~bs/C++0xFAQ.html.support. [3] Douglas Crockford. JSON: Javascript object notation. http://www. In terms of features, the major drawback of our current imple- json.org/.mentation is the lack of an eval function. In terms of syntax, we [4] Angus Croll. The secret life of javascript primitives.are quite close to the original Javascript notation and it is not dif- http://javascriptweblog.wordpress.com/2010/09/27/ficult to translate code back and forth between the two languages. the-secret-life-of-javascript-primitives/.An exhaustive list of the variations between JSPP and Javascript is [5] Jonathan Snook. Javascript: Passing by value or by reference. http:given in appendix A on the next page. //snook.ca/archives/javascript/javascript_pass. It is worth mentioning that the implementation of JSPP mostly [6] Bjarne Stroustrup and Gabriel Dos Reis. N1919: C++0x initial-uses regular C++ features and as such, does not heavily rely on izer list. http://www.open-std.org/jtc1/sc22/wg21/docs/fragile “hacks”. For instance, the use of preprocessor macros is papers/2005/n1919.pdf.very limited (see listing 23) and only serves to fill syntactic gaps. [7] Douglas Crockford. JavaScript: The Good Parts. O’Reilly Media,As a consequence, both the JSPP code and potential run-time error Inc., 2008.messages are completely readable. [8] Mads Ager. Google i/o 2009 - v8: High performance javascript engine. http://www.google.com/events/io/2009/sessions/ V8BuildingHighPerfJavascriptEngine.html. Listing 23. JSPP macros 1 #define catch(e) catch(var e) [9] Andy Wingo. Value representation in javascript implemen- 2 #define throw throw = tations. http://wingolog.org/archives/2011/05/18/ value-representation-in-javascript-implementations. 3 #define in : 4 #define function(...) [=] (var This, var arguments [10] V8 issue: Wrong order in object properties iteration. http://code. 5 ## VA ARGS ) mutable −> Value google.com/p/v8/issues/detail?id=164. 6 #define is ∗ == [11] Jeremiah Willcock, Jaakko J¨ rvi, Doug Gregor, Bjarne Stroustrup, a 7 #define isnt ∗ != and Andrew Lumsdaine. N1968: C++0x lambda expressions and 8 #define of ∗ < closures. http://www.open-std.org/jtc1/sc22/wg21/docs/ papers/2006/n1968.pdf. 9 #define this This10 #define new New [12] Ivo Wetzel and Zhang Yi Jiang. Javascript garden: How this works. http://javascriptgarden.info/#function.this. The current implementation of JSPP is only a prototype. Core [13] Anthony Williams. C++0x: Overloading on lambda arity. http:concepts such as object iteration and operators are only partially //stackoverflow.com/q/4170201/#4196447.implemented, and the standard Javascript library is not yet avail- [14] Henry Lieberman. Using prototypical objects to implement sharedable. Nothing has been done yet with respect to performance, even- behavior in object-oriented systems. In Conference proceedings onthough we are already aware of many optimization techniques that Object-oriented programming systems, languages and applications,we can use. Finally, further development aspects are foreseen in OOPLSA ’86, pages 214–223, New York, NY, USA, 1986. ACM.order to improve interoperability between JSPP and regular C++ [15] Douglas Gregor and Beman Dawes. N2930: C++0x range-basedcode. for loop. http://www.open-std.org/JTC1/SC22/WG21/docs/ Although the project started mostly as an accidental curiosity, papers/2009/n2930.html.we think that it has some serious potential applications. For one, [16] Angus Croll. Exploring javascript for-in loops. http:JSPP gives the C++ programmer a means to freely incorporate //javascriptweblog.wordpress.com/2011/01/04/highly dynamic Javascript-like code into a regular C++ program, exploring-javascript-for-in-loops/.hereby increasing the multi-paradigm level of the application. This [17] Jeremy Ashkenas. Coffeescript. http://www.coffeescript.is in compliance with a general trend towards offering as many org/.paradigms as possible within the same language (especially both [18] Inimino. Javascript semicolon insertion. http://inimino.org/static and dynamic aspects), something that the Lisp family of ~inimino/blog/javascript_semicolons.languages has been doing for a long time, Racket being one of
  9. 9. A. Exhaustive comparison listVariations Missing Features • Different syntax for Array and Object initialization • No eval • Only boxed version of primitive types • No dot notation for object property access • C++ primitive types must sometimes be explicitly casted • No automatic semi-column insertion into Value • The empty object notation {} is undefined • No variable hoisting: • Implementation dependant limit for number of arguments Control structures are blocks • No named functions Cannot redeclare variables in the same scope • String literal with simple quote ’ • No automatic global without var • No short regex notation /.../ • Function arguments must be preceded by var • No >>>, >>>=, void • No implicit return undefined; • No with • return; is not valid • new requires parenthesis around the constructor function • Use |= instead of = to modify a closure reference • in, === and !== renamed in of, is and isnt • typeof, delete are functions instead of operators • No break form with a label • switch construction with integers only