Javascript interpreter engine written in Java6898786
Abstract
A method and apparatus for interpreting and executing a program may include accessing a program in memory, parsing the program, generating an intermediate representation equivalent of the program, and executing the intermediate representation by accessing the program's library of host objects through an interface to the library. The program may be a JavaScript program embedded in HTML documents in a browser. The Web browser is programmed to intercept the JavaScript code and pass execution control over the program to the interpreter engine developed in Java. The parsing component of the engine validates the JavaScript instructions. The validated instructions are converted by the code generator component of the engine into an intermediate representation equivalent in Java code. The interpreter engine accesses the program's library of host objects through an interface to the library and executes the intermediate representation to produce the desired results as programmed in the original JavaScript source program.
Claims
1. A method, comprising:
a first process detecting one or more script language instructions in a markup language document, wherein the first process is implemented in a platform-independent programming language;
generating an intermediate representation of the one or more script language instructions, wherein the intermediate representation of the one or more script language instructions is different from the script language; and
interpreting and executing each of one or more instructions of the intermediate representation, wherein said interpreting and executing accesses one or more program objects to implement the one or more instructions of the intermediate representation;
wherein said interpreting and executing produces results in accordance with the original one or more script language instructions.
2. The method as recited in claim 1, wherein the first process is a Web browser, the method further comprising:
the Web browser passing execution to an interpreter engine after said detecting the one or more script language instructions in the markup language document;
wherein said generating, said interpreting and executing, and said accessing one or more program objects are performed by the interpreter engine.
3. The method as recited in claim 1, wherein the one or more instructions of the intermediate representation are stored in a stack data structure, and wherein said interpreting and executing is performed by a stack-machine interpreter engine that pops the one or more instructions off the stack data structure during said interpreting and executing.
4. The method as recited in claim 1, wherein said generating an intermediate representation of the one or more script language instructions comprises validating that the one or more script language instructions conform to script language syntax.
5. The method as recited in claim 1, wherein said generating an intermediate representation of the one or more script language instructions comprises modifying a first of the one or more program objects.
6. The method as recited in claim 5, wherein said modifying the first program object comprises adding at least one of methods and fields to the first program object.
7. The method as recited in claim 5, wherein said modifying the first program object comprises deleting at least one of methods and fields from the first program object.
8. The method as recited in claim 1, wherein the one or more program objects are accessed from one or more object libraries.
9. The method as recited in claim 1, wherein the script language is JavaScript.
10. The method as recited in claim 1, wherein the markup language is Hypertext Markup Language (HTML).
11. The method as recited in claim 1, wherein each of the one or more instructions of the intermediate representation is represented as one or more Java objects each referencing one of the one or more program objects accessed in implementing the one or more instructions of the intermediate representation.
12. The method as recited in claim 11, wherein each of the one or more Java objects of the intermediate representation represents one of an operator and an operand of the particular instruction of the intermediate representation.
13. The method as recited in claim 1, wherein the one or more program objects are Java objects.
14. The method as recited in claim 1, wherein the platform-independent programming language is the Java programming language.
15. The method as recited in claim 1, wherein the first process is a Java-based Web browser executing within a Java Virtual Machine.
16. A method, comprising:
a Web browser implemented in a platform-independent programming language examining a current tag of a markup language document marking the beginning of a portion of the markup language document;
if said examining determines the current tag of the markup language document identifies the portion of the markup language document as comprising script language instructions, passing execution to an interpreter engine implemented in the platform-independent programming language; and
if said examining determines the current tag of the markup language document does not identify the portion of the markup language document as comprising script language instructions, the Web browser executing the portion of the markup language document identified by the current tag;
wherein the interpreter engine is configured to perform the script language instructions to produce results in response to said passing execution.
17. The method as recited in claim 16, wherein the interpreter engine executing the script language instructions comprises:
generating an intermediate representation of the script language instructions; and
interpreting and executing each of one or more instructions of the intermediate representation, wherein said interpreting and executing accesses one or more program objects from one or more object libraries to implement the one or more instructions of the intermediate representation;
wherein said interpreting and executing produces results in accordance with the original script language instructions.
18. The method as recited in claim 17, wherein each of the one or more instructions of the intermediate representation is represented as one or more Java objects each referencing one of the one or more program objects accessed in performing the one or more instructions of the intermediate representation.
19. The method as recited in claim 17, wherein the one or more program objects are Java objects.
20. The method as recited in claim 16, wherein the script language is JavaScript.
21. The method as recited in claim 16, wherein the markup language is Hypertext Markup Language (HTML).
22. The method as recited in claim 16, wherein the platform-independent programming language is the Java programming language.
23. The method as recited in claim 16, wherein the Web browser and the interpreter engine are executing within a Java Virtual Machine.
24. A device, comprising:
a processor;
a memory coupled to said processor and operable to store program instructions in a platform-independent programming language, wherein the program instructions are executable by the processor to:
detect one or more script language instructions in a markup language document;
generate an intermediate representation of the one or more script language instructions, wherein the intermediate representation of the one or more script language instructions is different from the script language; and
interpret and execute each of one or more instructions of the intermediate representation to produce results in accordance with the original one or more script language instructions;
wherein, in said interpreting and executing, the program instructions are further executable by the processor to access one or more program objects to implement the one or more instructions of the intermediate representation.
25. The device as recited in claim 24, wherein the program instructions implement a Web browser and an interpreter engine, wherein the Web browser is executable by the processor to perform said detecting one or more script language instructions, and wherein the Web browser is further executable by the processor to pass execution to the interpreter engine after said detecting, and wherein the interpreter engine is executable by the processor to perform said generating, said interpreting and executing, and said accessing one or more program objects.
26. The device as recited in claim 25 wherein the program instructions further implement a Java Virtual Machine executable by the processor within the device, and wherein the Web browser is a Java-based Web browser executable within the Java Virtual Machine.
27. The device as recited in claim 24, wherein, in said generating an intermediate representation of the one or more script language instructions, the program instructions are further executable by the processor to modify a first of the one or more program objects.
28. The device as recited in claim 27, wherein, in said modifying a first of the one or more program objects, the program instructions are further executable by the processor to add at least one of methods and fields to the first program object.
29. The device as recited in claim 27, wherein, in said modifying a first of the one or more program objects, the program instructions are further executable by the processor to delete at least one of methods and fields from the first program object.
30. A The device as recited in claim 24, wherein, in said generating an intermediate representation of the one or more script language instructions, the program instructions are further executable by the processor to validate that the one or more script language instructions conform to script language syntax.
31. The device as recited in claim 24, wherein the one or more program objects are accessed from one or more object libraries.
32. The device as recited in claim 31, wherein the memory is further operable to store the one or more object libraries.
33. The device as recited in claim 24, wherein the script language is JavaScript.
34. The device as recited in claim 24, wherein the markup language is Hypertext Markup Language (HTML).
35. The device as recited in claim 24, wherein each of the one or more instructions of the intermediate representation is represented as one or more Java objects each referencing one of the one or more program objects accessed in implementing the one or more instructions of the intermediate representation.
36. The device as recited in claim 24, wherein the one or more program objects are Java programming language objects.
37. The device as recited in claim 24, wherein the platform-independent programming language is the Java programming language.
38. A device, comprising:
a processor;
a memory coupled to said processor and operable to store program instructions in a platform-independent programming language, wherein the program instructions implement a Web browser and an interpreter engine;
wherein the Web browser is executable by the processor to:
process a markup language document comprising a script comprising one or more script language instructions;
detect the script in the markup language document; and
provide the script to the interpreter engine;
wherein the interpreter engine is executable by the processor to execute the script to produce results of the script.
39. The device as recited in claim 38, wherein the platform-independent programming language is Java, wherein the program instructions further implement a Java Virtual Machine executable by the processor within the device, and wherein the Web browser and the interpreter engine are executable within the Java Virtual Machine.
40. The device as recited in claim 38, wherein, in said executing the script, the interpreter engine is further executable by the processor to:
generate an intermediate representation of the script; and
execute the intermediate representation to produce results in accordance with the original script.
41. The device as recited in claim 40, wherein, in said executing the intermediate representation, the interpreter engine is further executable by the processor to interpret and execute each of one or more instructions of the intermediate representation.
42. The device as recited in claim 40, wherein, in said executing the intermediate representation, the interpreter engine is further executable by the processor to access one or more program objects from one or more object libraries to implement one or more instructions of the intermediate representation.
43. The device as recited in claim 38, wherein each of the one or more instructions of the intermediate representation is represented as one or more Java objects each referencing one of the one or more program objects accessed in implementing the one or more instructions of the intermediate representation.
44. The device as recited in claim 38, wherein the script language is JavaScript.
45. The device as recited in claim 38, wherein, in said detecting the script, the Web browser is further executable by the processor to detect a markup language tag identifying the start of the script.
46. A system, comprising:
a device;
a Java Virtual Machine executable within the device;
an interpreter engine executable within the device; and
a Web browser executable within the Java Virtual Machine to:
detect one or more script language instructions in a markup language document; and
pass execution to the interpreter engine in response to said detecting;
wherein the interpreter engine is executable within the device to:
generate an intermediate representation of the detected one or more script language instructions; and
interpret and execute each of one or more instructions of the intermediate representation to produce results in accordance with the original one or more script language instructions;
wherein, in said interpreting and executing, the interpreter engine is further executable within the device to access one or more program objects to implement the one or more instructions of the intermediate representation.
47. The system as recited in claim 46, wherein, in said generating an intermediate representation of the one or more script language instructions, the interpreter engine is further executable to modify a first of the one or more program objects.
48. The system as recited in claim 46, wherein the one or more program objects are accessed from one or more object libraries.
49. The system as recited in claim 46, wherein the script language is JavaScript.
50. The system as recited in claim 46, wherein each of the one or more instructions of the intermediate representation is represented as one or more Java objects each referencing one of the one or more program objects accessed in implementing the one or more instructions of the intermediate representation.
51. The system as recited in claim 46, wherein the one or more program objects are Java programming language objects.
52. A carrier medium comprising program instructions, wherein the program instructions are computer-executable to implement:
a first process detecting one or more script language instructions in a markup language document, wherein the first process is implemented in a platform-independent programming language;
generating an intermediate representation of the one or more script language instructions, wherein the intermediate representation of the one or more script language instructions is different from the script language; and
interpreting and executing each of one or more instructions of the intermediate representation, wherein said interpreting and executing accesses one or more program objects to implement the one or more instructions of the intermediate representation;
wherein said interpreting and executing produces results in accordance with the original one or more script language instructions.
53. The carrier medium as recited in claim 52, wherein the first process is a web browser, wherein the program instructions are further computer-executable to implement:
the Web browser passing execution to an interpreter engine after said detecting the one or more script language instructions in the markup language document;
wherein said generating, said interpreting and executing, and said accessing one or more program objects are performed by the interpreter engine.
54. The carrier medium as recited in claim 52, wherein, in said generating an intermediate representation of the one or more script language instructions, the program instructions are further computer-executable to implement modifying a first of the one or more program objects.
55. The carrier medium as recited in claim 52, wherein the script language is JavaScript.
56. The carrier medium as recited in claim 52, wherein the one or more program objects are Java programming language objects, and wherein each of the one or more instructions of the intermediate representation is represented as one or more Java objects each referencing one of the one or more program objects accessed in implementing the one or more instructions of the intermediate representation.
57. The carrier medium as recited in claim 52, wherein the first process is a Java-based Web browser executing within a Java Virtual Machine.
Description
BACKGROUND OF THE INVENTION
1. Field of the Invention
This invention relates to a method and apparatus for interpreting and executing JavaScript programs, such as JavaScript programs embedded in hypertext markup language ("HTML") documents. More particularly, embodiments of the present invention relate to a method and apparatus for a JavaScript interpreter written in Java. Specifically, a JavaScript interpreter may intercept JavaScript source code within HTML documents, parse and convert the JavaScript source code to a proprietary intermediate form represented by objects written in Java. The JavaScript interpreter may interface with JavaScript library objects to execute the intermediate representation equivalent of the original JavaScript source code.
2. Description of the Related Art
JavaScript is a Web scripting language developed by Netscape Communications Corporation. JavaScript was one of the first Web scripting languages and it remains one of the most popular today. (Please note that JAVA and JAVASCRIPT used herein are registered trademarks of Sun Microsystems. Inc.) JavaScript may be directly included in HTML documents. HTML is a language used to create Web documents. Referring now to FIG. 1, the JavaScript source code is typically embedded in HTML documents 110, by using a script tag, such as "<SCRIPT LANGUAGE=JavaScript>". A Web browser 120, such as Netscape Navigator, executes HTML documents containing JavaScript source code. Unlike compiled languages, JavaScript is an interpreted language. This means the Web browser executes each line of JavaScript as it comes to it. The ability to interpret and execute JavaScript source code has been provided in popular Web browsers, such as Netscape Navigator and Microsoft Internet Explorer. JavaScript programs run within a Web browser or other JavaScript-enabled applications to produce the desired results 130. The JavaScript language is regularly updated by Netscape. The most recent version of JavaScript is version 1.3.
Typical prior art Web browsers that support JavaScript are programmed in native code complied for a particular computer platform. However, it may be desirable to support JavaScript in a Web browser programmed in a platform-independent language such as Java. A Java-based Web browser may run on any computing platform under a Java Virtual Machine for the particular platform. However, Java-based programs typically execute more and may have a larger memory footprint that natively coded programs. Thus, adding JavaScript support to a Java-based browser may exacerbate speed and memory drawbacks. It may be desirable to overcome these drawbacks for a Java-based browser with JavaScript support, especially for use in embedded devices such as personal digital assistants (PDAs), wireless communication devices, such as cellular telephones, and other small consumer devices where computer processing speed and memory resources are at a premium. The present invention may provide a method and apparatus for interpreting and executing JavaScript source code embedded in HTML documents. The interpreter of the present invention may be written using the Java programming language. The present invention uses a smaller memory footprint than the prior art in interpreting and executing JavaScript programs. Furthermore, the architecture of the present invention may enable faster execution of JavaScript programs and enable the use of independent implementations of the interpreter, the Web browser and the JavaScript object library.
SUMMARY OF THE INVENTION
A method and apparatus for interpreting and executing a program is disclosed. Specifically, a method and apparatus is disclosed for accessing a program in memory, parsing the program, generating an intermediate representation equivalent of the program, and executing the intermediate representation by accessing the program's library of host objects through an interface to the library.
In the preferred embodiment of the present invention, the program to be interpreted and executed is a JavaScript program embedded in HTML documents in an Internet Web browser. The Web browser is programmed to intercept the JavaScript code and pass execution control over the program to the interpreter engine developed using the Java programming language. The parsing component of the engine validates the JavaScript instructions. The validated instructions are converted by the code generator component of the engine into an intermediate representation equivalent in Java code. The interpreter engine accesses the program's library of host objects through an interface to the library and executes the intermediate representation to produce the desired results as programmed in the original JavaScript source program. The present invention further contemplates information media that conveys software for implementing the method disclosed herein.
BRIEF DESCRIPTION OF THE DRAWINGS
FIG. 1 is a flow diagram of a typical method of interpreting JavaScript programs;
FIG. 2 is a flow diagram illustrating one embodiment of interception of JavaScript code in HTML for execution by a Java-based JavaScript interpreter;
FIG. 3 is a flow diagram illustrating an embodiment of various components for interpreting JavaScript programs;
FIG. 4 illustrates a method according to one embodiment for converting JavaScript code to an equivalent intermediate representation; and
FIG. 5 illustrates the hierarchy of the JavaScript runtime objects and its relationship to the hierarchy of library objects, according to one embodiment.
While the invention is described herein by way of example for several embodiments and illustrative drawings, those skilled in the art will recognize that the invention is not limited to the embodiments or drawings described. It should be understood, that the drawings and detailed description thereto are not intended to limit the invention to the particular form disclosed, but on the contrary, the intention is to cover all modifications, equivalents and alternatives falling within the spirit and scope of the present invention as defined by the appended claims.
DETAILED DESCRIPTION OF EMBODIMENTS OF THE INVENTION
A preferred embodiment of the present invention may be developed using the Java programming language as provided in the Java Development Kit (JDK), version 1.1.7 from Sun Microsystems.
Referring now to FIG. 2, in one embodiment, a JavaScript source program may be embedded in HTML 210. The HTML may be processed by a Web browser 220, such as Netscape Navigator or Microsoft Internet Explorer. A JavaScript tag in the HTML may be used to identify the beginning of the JavaScript code section within the HTML. Upon encountering a JavaScript tag 230, the Web browser may pass execution control to an interpreter engine 250. The interpreter engine 250 may interpret the JavaScript code 210, execute it, and present the results to the user 260. Non-JavaScript code in the HTML may be executed by the Web browser 240.
The interpreter engine 250 is further illustrated in FIG. 3, according to one embodiment. Once the Web browser has identified an input stream of JavaScript source code 310 in the HTML document, the Web browser may pass processing control to a parser component 320 of the interpreter engine. The parser 320 may examine the syntax of the incoming Javascript source code 310 to produce a validated listing of JavaScript code 330 before the code is translated by the interpreter. The parsed JavaScript code 330 may then be processed by a representation generator component 340 of the interpreter engine. The representation generator component 540 takes as input the validated JavaScript code 330 and produces an intermediate representation using a proprietary Java code equivalent 350 of the JavaScript code 310. The intermediate Java code representation 350 may then be interpreted by an interpreter component 360. The interpreter component 360 may use a library interface 370 to communicate with a JavaScript host objects library 380 to execute the intermediate representation 350 and produce desired results 390 as programmed in the original JavaScript source program 310.
As one of ordinary skill in the art will appreciate, there are various methods by which a Web browser may be enabled to recognize the parser component 320 as the appropriate subroutine to which the Web browser passes control upon encountering the JavaScript tag 230. One method is by placing "hooks" into the Web browser which instruct the browser to call certain entry point methods of the parser component 320 when a JavaScript tag is encountered in the HTML code. The general method of placing such "hooks" in a Web browser by using the JDK Reflection API is well known to those of ordinary skill in the art. Other well-known methods of instructing one program to invoke another may be applied to instruct a Web browser to invoke the parser component 320. These methods include use of the "OnAction" keyword and "Form" tag.
In the preferred embodiment of the present invention, the parser component 320 may be written using Java CC, a publicly available utility published by Metamata. Using the Java CC utility, the parser component 320 may be written to accept the syntax (grammar) of the input language to be parsed, i.e., the Javascript syntax. This enables the parser component 320 to parse the input steam of JavaScript source code 310 to ensure that the correct syntax is followed. The parser component 320 produces a validated listing of JavaScript code 330. The parser 320 may create Java objects based on what is parsed from the input stream of the JavaScript source code 310. The Java objects, which may contain field names and methods, may be stored using a technique such as hash tables. The use of hash tables may facilitate fast access of field names and methods during the entire process of interpreting and executing the JavaScript source code 310.
As stated above, a Java CC source file may define the JavaScript grammar in one embodiment. The following illustrates the creation of Java CC source file definitions and three related parser methods as used in the preferred embodiment of the present invention:
PARSER_BEGIN(JvScParser) class JvScParser { static JvScCodeGenerator codeGen; . . . boolean parseScript (int lineOffset) throws ParseException { lineNumber = lineOffset; if (Script ( ) ) { if (codeGen.lastPut ( ) == JvScOperator.OP_STMTEND) codeGen.unput () ; codeGen.put (JvScOperator.OP_EOF) ; return true; } return false; } . . . } . . . | < #LETTER: [ "A"-"Z", "a"-"z", "$" ] > | #DIGIT: [ "0"-"9" ] > | <IDENTIFIER: <LETTER> (<LETTER> | <DIGIT> ) * > . . . boolean Script ( ) : { } { ( <SEMICOLON> ) * Statement ( ) ( <SEMICOLON> ) * ( Statement ( ) ( <SEMICOLON> ) * ) * <EOF> { return true; } | <EOF> { return false; } } /* This is a handler for the JavaScript statement. It delegates code-generating duties to other handlers depending on the current statement type. */ void Statement ( ) : { boolean nonEmpty; } { nonEmpty = StatementBody ( ) { if (nonEmpty) codeGen.put (JvScOperator.OP_STMTEND) ; } | Block (null, false) | SwitchStatement ( ) | WhileStatement ( ) | ForStatement ( ) | DoStatement ( ) | IfStatement ( ) | FunctionDefinition ( )
{ codeGen.put (JvScOperator.OP_STMTEND); } | GlobalVarDef ( ) ) . . . /* When a string of characters satisfying the pattern determined by <IDENTIFIER> (see above) has been encountered, it is used to create the JavaScript engine internal representation of identifiers, JvScName. ‘token.image’ is where the string is stored by the parser. */ JvScName Name ( ) : { } { <IDENTIFIER> { return new JvScName (token.image); } }
Once the parser 320 has parsed the input stream of the JavaScript program 310, the parsed JavaScript code 330 may be translated into an intermediate representation Java code 350 by the representation generator component 340. The intermediate format of the preferred embodiment may be an arbitrary scheme that is similar to Java byte code. As one skilled in the art will appreciate, the intermediate format may be any scheme that adequately represents the input JavaScript code 310 for execution by a JavaScript interpreter. The representation or intermediate format 350 of the preferred embodiment is particularly suitable for execution by a stack-machine implemented interpreter written in Java. However, as one skilled in the art will readily appreciate, it is not required that the intermediate format 350 be designed such that it may be executed by stack-machine implemented interpreter. Depending on the representation scheme used, alternatively designed interpreters may be used without departing from the present invention.
As stated above, the representation of the input JavaScript program 310 may be accomplished using many different schemes. The preferred embodiment of the present invention demonstrates one representation scheme using Java classes and objects.
Referring now to FIG. 4, a representation scheme example according to a preferred embodiment is illustrated. The input JavaScript source code sample 410 is "Echo ("2+3:"+(2+));." The Javascript code 410 performs the simple function of adding two numbers and displaying the result. Box 420 shows a representation of the JavaScript code 410 as it is accomplished in the preferred embodiment. More particularly, box 430 lists logical commands representing the JavaScript code 410, and box 440 lists Java objects and classes which correspond to the logical representations 430. Box 450 illustrates the foregoing with Java program code. The representation generator 340 may use a stack data structure to store the intermediate representation 350 as Java objects. For example, the JavaScript function "Echo" is represented with two pushes on the stack data structure. First, the logical command "call" is pushed on the stack to indicate the presence of a function or method. Second, the name of the function "echo" is pushed on the stack. The Java object "call" is an instance of the Java class JvScFunctionalCall. Similarly, the Java object "echo" is an instance of the Java class JvScName, used for storing host objects. The names of host objects may be names of methods or functions which are called to perform specific functions. And similarly, Java classes, such as JvScOperator, JvScString and JvScNumber may be created to hold Java objects, such as the operator "add," the string "2+3" and the integer "2" respectively. The parameters and commands in the intermediate representation may be Java objects.
Referring now to FIG. 5, box 510 illustrates a hierarchy of the JavaScript runtime objects and its relationship to a hierarchy of library objects 580. The class JvScAtom 520 may generally consist of a JvScOperator class 530 and the JvScDatum class 540. The JvScOperator class 530 may contain objects such as "MUL," "ADD," "CALL", "GETFIELD" and "RETURN." The JvScDatum class 540 includes JvScName 550 (e.g., name of a method or function), JvScNumber 560 (e.g., the integer "2" used in an ADD operation) and JvScObject 570 (which is inserted in the stack data structure discussed above). As stated above, the representation generator 340 may use a stack data structure to store the intermediate representation 350 as Java objects.
The stack used in the representation scheme of the preferred embodiment may be an array of Java objects. Each element of this array (stack) may be either a command or a parameter. Each element may derive from an abstract Java class with very generic functionality and may contain data pertaining to the operator or data type it represents, sufficient for a stack machine interpreter to perform actions equivalent to those specified in the original JavaScript program 310. The Java class to which an object in the array (stack) belongs, may determine whether the particular object is a command or a parameter. As one of ordinary skill in the art will appreciate, there are numerous methods of representing in memory the operators and the operands of a compiled program. In the preferred embodiment of the present invention, the logical representation 430 uses the well-known Polish notation scheme.
The intermediate representation 350 may have several advantages, such as a small memory footprint. Furthermore, the representation scheme of the preferred embodiment may enable faster execution of the JavaScript code 310 by the interpreter component 360.
The following illustrates the representation generator component 340 of the preferred embodiment and an associated representation scheme suitable for execution by a stack-machine implemented interpreter:
void ForStatement ( ) : {} { <FOR> <LPAREN> ForRemainder ( ) } void ForRemainder ( ) : { JvScScope scope = new JvScScope ( ) ; JvScName n = null; } { LOOKAHEAD ( Name ( ) <IN> ) n = Name( ) <IN> { scope.addLocal (n.name) ; } ForInRemainder (scope, n) | LOOKAHEAD ( <VAR> Name ( ) <IN> ) <VAR> n = Name ( ) <IN> { scope.addLocal (n.name) ; } ForInRemainder (scope, n) | [ ForInitList(scope) ] <SEMICOLON> TraditionalForRemainder(scope) } void ForInitList (JvScScope scope) : {} { { /*codeGen.put (scope) ; */ scope = insideFunction; } ( Expression( ) { codeGen.put(JvScOperator.OP_STMTEND); } (LOOKAHEAD(2) <COMMA> Expression( ) { codeGen.put (JvScOperator.OP STMTEND); } ) * ( <COMMA> LocalVarStatement (scope) )? | LocalVarStatement(scope) ) } . . . JvScAtom Literal( ) : { JvScArray a = null; } { <INTEGER> { long num = 0; boolean tryDec = false; if (token.image.charAt(0) == ‘0’ && token.image.length( ) > 1) { if(Character.toUpperCase ( token.image.charAt (1)) == ‘X’) num = Long.parseLong ( token.image.substring(2), 16) ; else if(qualifyOctal (token.image)) {
num = Long.parseLong ( token.image.substring (1) , 8) ; } else { tryDec = true; token.image = token.image.substring(1) ; } } else tryDec = true; if (tryDec) { try { num = Long.parseLong (token.image) ; } catch (NumberFormatException e) { // Most probably the number was too long return new JvScBigNumber(token.image); } } return new CacheNumber (num); } | <FLOAT> { return new CacheNumber ( (Double.valueOf (token.image)). DoubleValue ( ) ); } | <STRING> { return new CacheString ( token.image.substring (1, token.image.length ( ) -1)); } | <TRUE> { return JvScAtom.JvScTrue; } | <FALSE> { return JvScAtom.JvScFalse; } | <NULL> { return JvScAtom.JvScNull; } | <UNDEFIED>
{ return JvScAtom.JvScUndefined; } } . . . JvScOperator AssignOperator ( ) : {} { <ASSIGN> {return JvScOperator.OP_SET; } | <PLUS_ASSIGN> {return JvScOperator.OP_ADD_SET; } | <MINUS_ASSIGN> {return JvScOperator.OP_SUB_SET; } | <MUL_ASSIGN> {return JvScOperator.OP_MUL_SET; } | <DIV_ASSIGN> {return JvScOperator.OP_DIV_SET; } | <AND_ASSIGN> {return JvScOperator.OP_AND_SET; } | <OR_ASSIGN> {return JvScOperator.OP_OR_SET; } | <XOR_ASSIGN> {return JvScOperator.OP_XOR_SET; } | <MOD_ASSIGN> {return JvScOperator.OP_MOD_SET; } | <LSHIFT_ASSIGN> {return JvScOperator.OP_LSH_SET; } | <LSHIFT_ASSIGN> {return JvScOperator.OP_RSH_SET; } | <RUSHIFT_ASSIGN> {return JvScOperator.OP_USH_SET; } } . . . public class JvScAtom implements Cloneable { /* ECMAScript compatibility constants to be used by tbe typeof operator. */ static final String typeofUndefined = "undefined"; static final String typeofObject = "object"; static final String typeofNull = typeofObject; static final String typeofBoolean = "boolean"; static final String typeofFunction = "function"; static final String typeofNumber = "number"; static public final JvScAtom JvScTrue = new JvScObject( ); static public final JvScAtom JvScFalse = new JvScObject( ); static public final JvScAtom JvScUndefined = new JvScObject( ); static public final JvScAtom JvScNull = new JvScObject( ); static public final JvScNumber JvScNaN = new JvSCNumber(DOuble.NaN); static public final JvScAtom JvScLineNumber = new JvScAtom( ); public String typeOf( ) { if (this == JvScNull) return typeofNull; else if (this == JvScUndefined) return typeofUndefined; else if (this == JvScTrue || this == JvScFalse) return typeofBoolean; else if (this == JvScObject.NaN || this == JvScobject.Infinity) return typeofNumber;
return typeofObject; } . . . public class JvScNumber extends JvScAtom { static final String NAN_STRING ="NaN"; static final int MAX_RADIX = 36; static final String TYPEOF_NUMBER = "number"; static final String MAX_VALUE_STRING = "1.7976931348623157e308"; static final JvScNumber RADIX_10 = new JvScNumber(10); static final JvScNumber JvScZero = new JvScNumber(0); static final JvScNumber JvScOne = new JvScNumber(1); boolean integer; double value; public JvScNumber(int value) { this.value = value; integer = true; public JvScNumber(long value) { this.value = value; integer = true; public JvScNumber(float value) { this.value = value; integer = Math.floor(value) == value; } public JvScNumber(double value) { this.value = value; integer = Math.floor(value) == value; } public JvScNumber(double value, boolean integer) { this.value = value; this.integer = integer; } public JvScNumber(Number value) { this(value.doubleValue( )); } final public boolean isInteger( ) { return integer; } final public void set(int value) { this.value = value; integer = true; } final public void set(long value) { this.value = value; integer = true; } final public void set(float value) { this.value = value; integer = false; } final public double get( ) { return value; } final public int intValue( ) { return (int)value; } final public long longValue( ) { return (long)value; } final public float floatValue( ) { return (float)value; } public double doubleValue( ) { return value; } public JvScAtom toNumber( ) { return this; } public JvScAtom toBoolean( ) { return value == 0.0 || Double.isNaN(value)? JvScFalse : JvScTrue; } public JvScAtom isFinite( ) { return isFiniteboolean( )? JvScTrue : JvScFalse; }
public JvScAtom isNaN( ) { return Double.isNaN(value)? JvScTrue : JvScFalse; } boolean isNaNboolean( ) { return Double.isNaN(value); } boolean isFiniteboolean( ) { return !Double.isNaN(value) && value < Float.MAX_VALUE && value > -Float.MAX_VALUE; } static String trimSpaces(String str) { inti =0; for ( ; i < str.length( ) && (Character.isWhitespace(str.charAt(i)) || str.charAt(i) == ‘\u000b’); 1++); return i > 0? (i >= str.length( )? "" : str.substring(i)) : str; } static long parseInt(String inStr, int radix) { int i = 0 ; String numstr = trimSpaces(inStr); if(numstr.charAt (i) == ‘-’ || numstr.charAt (i) == ‘+’ || Character.digit(numstr.charAt(i), radix) >= 0) { for ( ++i; i < numstr.length( ) && Character.digit(numstr.charAt(i), radix) >= 0; i++); } return i < numstr.length( )? Long.parseLong(nurnstr.substring(0,i), radix) : Long.parseLong(numstr, radix); } static double parseFloat(String numstr) { int i = 0 ;
boolean dot = false; if(numstr.charAt(i) == ‘-’ || numstr.charAt(i) == ‘+’ || Character.digit(numstr.charAt(i), 10) >= 0) { for( ++i; i < numstr.length( ) && (Character.digit(numstr.charAt(i), 10) >= 0 || numstr.charAt(i) == ‘.’ && (dot = !dot)); i++); } return Double.valueOf( i <numstr.length( )? numstr.substring(O,i) : numstr). doubleValue( ); } public Object toJavaType( ) { if (integer) return new Long((long)value); else return new Double(value); } public final String toString(JvScAtom radix) throws JavaScriptRuntimeException { double r = radix.doubleValue( ); if(Double.isNaN(value) || this == JvScNaN) return NAN_STRING; if ((int)r != 10) { if(Double.isNaN(r) || r <= 0 || r > MAX_RADIX) throw new JavaScriptRuntimeException ( "Illegal radix: " + radix); return Long.toString(longValue( ), (int)r); } return value >= Float.MAX_VALUE? MAX_VALUE_STRING: (integer? ""+longValue( ): ""+(float)value); } public String toString( ) {
try { return toString(RADIX_10); } catch(JavaScriptRuntimeException e) { } return NAN_STRING; } public String typeOf( ) { return TYPEOF_NUMBER; } } . . . public class JvScObject extends JvScAtom { static final String CLS_ARRAY = "Array"; static finai String CLS_OBJECT = "Object"; static final String CLS_NUMBER = "Number"; static final String CLS_STRING = "String"; static final String CLS_FUNCTION = "Function"; static final String FLD_PROTOTYPE = "prototype"; static final String FLD_CONSTRUCTOR = "constructor"; static final String FLD_PROTO__= "_proto_"; static final Stiing FLD_LENGTH = "length"; static final String FLD_TOSTRING = "toString"; static final Class[ ] voidClsList = new Class[0]; public static JvScAtom proto— = new JvScObject( ); public static JvScAtom NaN = JvScAtom.JvScNaN; public static JvScAtom Infinity = new JvScObject( ); private static Class STRING_CLASS = "".getClass( ); private static Class JVSCOBJECT_CLASS = proto_.getClass( ); static Class varParam[ ]; static { varParam = new Class[1]; varParam[0] = (new JvScAtom[0]).getClass( ); } static Hashtable methods = new Hashtable( ); static Hashtable constructors = new Hashtable( ); static Hashtable staticInstances = new Hashtable( ); // static Hashtable prototype = new Hashtable( ); protected Hashtable properties; static private String objectPrefix = "[object"; private static String toStringClassName(JvScObject object) { String clsName = null; /* * This function is completely meaningless * if not for ECMA, wouldn't ever be written. */ if(object instanceof JvScPrototype)
clsName = className(((JvScPrototype)object).getTargetClass( )); else if(object instanceof JvScNativeFunction) clsName = CLS_FUNCTION; else { /* Object m = object.properties.get(FLDTOSTRING); if (m != null && m instanceof JvScNativeFunction && ((JvScNativeFunction)m). className.compareTo(CLS_OBJECT) == 0) { } else try { if(object.getClass( ).getDeclaredMethod(FLD_TOSTRING, voidClsList) != null) return object.toString( ); } catch(NoSuchMethodException e) { } */ clsName = className(object.getClass( )); } return objectPrefix + clsName +"]"; } static final String className(Class cls) { String name = cls.getName( ); return name.substring(name.lastIndexOf(".") + 1); } Public static JvScAtom fromJavaType(Object o) { if(o instanceof java.lang.String) return new JvScString((java.lang.String)o); else if(o instanceof java.lang.Number) return new JvScNumber((java.lang.Number)o); return new JavaObject(o); } static final JvScObject castToJvScObject(Object object) { return (JvScObject)(object instanceof JvScObject? object: new JavaObject(object));
} static JvScObject newInstance(Class cls, JvScAtom[ ] mem, imt p1, int n) throws JavaScriptRuntimeException { return newInstance(cls, mem, p1, n, false); } static JvScObject newInstance(Class cls, JvScAtom[ ] mem, int p1, int n, boolean javaClass) throws JavaScriptRuntimeException { Constructor constructor[ ]; JvScObject re = null; if(n <= 0) { try { re = castToJvScObject(cls.newInstance( )); } catch(Exception e) { throw new JavaScriptRuntimeException( "EXCEPTION trying to invoke constructor of " + cls + ":"+e); } } else { int i = 0; if((constructor=(Constructor[ ])constructors.get(cls)) == null) constructors.put(cls, constructor = cls.getConstructors( )); for( i = 0; i < constructor.length && constructor[i] .getParameterTypes( ).length != n; i++); if(i >= constructor.length) { Constructor cnstr; /* * Try to find this(JvScAtom[ ] varp) */ try { cnstr = cls.getConstructor(varParam); }
catch(Exception e) { throw new JavaScriptRuntimeException( "There is no constructor of class ‘" + className(cls) +"\’ accepting " + n +" parameter(s) "); } re = newInstance(cnstr, mem, p1, n); } else if (javaClass) { try { return newJavaInstance( constructor[i], mem, p1, n); } catch(Exception e) { throw new JavaScriptRuntimeException( "Exception caught trying instantiate ‘" + cls + "\’ "); } } else try { JvScAtom[ ] param = new JvScAtom[n]; System.arraycopy(mem, p1, param, 0, n); re = (JvScObject)constructor[i].newInstance(param); } catch(Exception e) { throw new JavaScriptRuntimeException( "EXCEPTION trying to invoke constructor of" |