eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'JavaScriptCompiler':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: JavaScriptCompiler


Inheritance:

   Object
   |
   +--Scanner
      |
      +--JavaScriptScanner
         |
         +--JavaScriptParser
            |
            +--JavaScriptCompiler
               |
               +--JavaScriptCompilerWithBreakpointSupport

Package:
stx:libjavascript
Category:
Languages-JavaScript-Compiling & Parsing
Version:
rev: 1.69 date: 2023/08/08 11:12:24
user: cg
file: JavaScriptCompiler.st directory: libjavascript
module: stx stc-classLibrary: libjavascript

Description:


JavaScriptCompiler has a lot of stuff copied from ByteCodeCompiler.
This is a very BAD SMELL!

copyright

COPYRIGHT (c) 2005 by eXept Software AG All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the inclusion of the above copyright notice. This software may not be provided or otherwise made available to, or used by, any other person. No title to or ownership of the software is hereby transferred.

Class protocol:

compiling methods
o  compile: aString forClass: aClass inCategory: cat

o  compile: aString forClass: aClass inCategory: cat notifying: requestor
compile a source-string for a method in classToCompileFor.
errors are forwarded to requestor.
The method will get cat as category.
Returns the new method, #Error or nil.

o  compile: aString forClass: aClass inCategory: cat notifying: requestor install: install

o  compile: aString forClass: aClass inCategory: cat notifying: requestor install: install skipIfSame: skipIfSame silent: silent
compile a source-string for a method in aClass.
errors are forwarded to requestor.
The method will get cat as category.
if install is true, the method is installed in the class.
if skipIfSame, the method is not installed if there is no change
(used when filing in).
if silent is true, no warnings are output.
Returns the new method, #Error or nil.

o  compile: aString forClass: aClass inCategory: cat notifying: requestor install: install skipIfSame: skipIfSame silent: silent foldConstants: fold
not needed...

o  compile: aString in: aClass notifying: requestor ifFail: failBlock

o  evaluate: aString notifying: requestor compile: doCompile
used to install new classes

o  newCodeSet

instance creation
o  new
Pretty ugly hack. A caller to compiler may provide a set of breakpoints

private
o  selectorFor: jsName numArgs: nargs
self selectorFor:'foo' numArgs:0 -> #foo
self selectorFor:'foo' numArgs:1 -> #foo:
self selectorFor:'foo' numArgs:2 -> #'foo:_:'
self selectorFor:'foo' numArgs:3 -> #'foo:_:_:'
self selectorFor:'foo' numArgs:4 -> #'foo:_:_:_:'
self selectorFor:'foo' numArgs:5 -> #'foo:_:_:_:_:'


Instance protocol:

accessing
o  methodClass: something

code generation
o  absJumpFromJump: code
given a jump-symbolic code, return corresponding absolute jump

o  addLiteral: anObject
add a literal to the literalArray - watch for and eliminate
duplicates. return the index of the literal in the Array

o  addReloc: symIndex
remember to relocate offset at symIndex later ...

o  appendByte: aByte
append a byte to the code-Array, checking for byte-range (debug-only)

o  appendByteCodeFor: codeSymbol
append the byteCode for an instructionSymbol to the code-Array

o  appendEmptyByte
append an empty byte to the code-Array

o  appendSignedByte: aByte
append a signedbyte (as in jump-offsets) to the code-Array,
check range and report an error if invalid

o  appendSignedWord: aWord
append a signed word to the code-Array,
check range and report an error if invalid

o  appendWord: aWord
append an unsigned word (low-high) to the code-Array,
checking for word-range (debug-only)

o  byteCodeFor: aSymbol
given a symbolic instruction, return the corresponding bytecode.
as a side-effect, leave number of bytes pushed/popped by this instr.
in stackDelta, and, if the instruction needs extra arguments, leave
this info in extra. Also lineno is set to true, if this code has line
information and extraLiteral is set if any hidden send is performed by it.

o  code

o  codeLineNumber: nr on: codeStream
generate lineNumber information

o  contextMustBeReturnable

o  correctedSource

o  createMethod
fixup CheapBlocks method-field in literal array,

o  genByteCodeFrom: symbolicCodeArray
convert symbolicCode into bytecodes

o  genSymbolicCode
traverse the parse-tree producing symbolicCode - return the codeArray

o  generateVariables: varCollection on: codeStream
generate code to set it up.

o  isBuiltInSelector: sel forReceiver: receiver

o  maxStackDepth

o  methodClass

o  numberOfMethodArgs

o  numberOfMethodVars

o  relocateWith: symbolicCodeArray relocInfo: relocInfo
helper for genByteCodeFrom - relocate code using relocInfo.
if relocation fails badly (due to long relative jumps) patch
symbolicCode to use absolute jumps instead and return false
(genByteCodeFrom will then try again). Otherwise return true.
Also, on the fly, jumps to jumps and jumps to return are handled.

o  specialGlobalCodeFor: aSymbol

o  specialSendCodeFor: sel
return the codeExtension for sends,
which can be performed by specialSend opCode

compiling
o  compile: aString forClass: aClass inCategory: cat
compile from source code

o  compile: aString forClass: aClass inCategory: cat notifying: requestorArg install: install skipIfSame: skipIfSame silent: silent foldConstants: fold
compile from source code

o  compile: sourceCodeString forClass: aClass inCategory: cat notifying: aRequestor install: install skipIfSame: skipIfSame silent: silent foldConstants: fold ifFail: failBlock
compile from source code

o  compileTree: tree source: sourceString forClass: aClass inCategory: cat notifying: requestor install: install skipIfSame: skipIfSame silent: silent foldConstants: fold
compile from a parsetree

o  compileTree: tree source: sourceString forClass: aClass inCategory: cat notifying: requestor install: install skipIfSame: skipIfSame silent: silent foldConstants: fold ifFail: failBlock
compile from a parsetree

initialization
o  reset
needed between functions, when reading multiple functions

loops
o  loopDescription

o  newLoopDescription

o  newLoopDescriptionForBlock

o  newSwitchDescription

o  popLoopDescription

o  pushLoopDescription: aDescription

parsing
o  compileFunctionDefinitions
because the first token ('function') has already been read,


Private classes:

    LoopDescription
    LoopDescriptionForBlock
    SwitchDescription

Examples:


    |f|

    f := JavaScriptCompiler
        compile:'max(a, b) {
                    if (a > b) return a;
                    return b;
                 }'
        forClass:nil
        inCategory:nil
        notifying:nil.
    f valueWithReceiver:nil arguments:#(10 20).
    |f|

    f := JavaScriptCompiler
        compile:'max(a, b) {
                    if (a > b) ;
                    else return b;
                    return a;
                 }'
        forClass:nil
        inCategory:nil
        notifying:nil.
    f valueWithReceiver:nil arguments:#(10 20).
    |f|

    f := JavaScriptCompiler
        compile:'max(a, b) {
                    if (a > b) return a;
                    else return b;
                 }'
        forClass:nil
        inCategory:nil
        notifying:nil.
    f valueWithReceiver:nil arguments:#(20 10).
    |f|

    f := JavaScriptCompiler
        compile:('test(arg) {
                    var n;

                    n = arg;
                    while (n > 0) {
                        n--;
                        Transcript.showCR(#hello#);
                    }
                 }' replaceAll:$# with:Character doubleQuote)
        forClass:nil
        inCategory:nil
        notifying:nil.
    f valueWithReceiver:nil arguments:#(5).
    |f|

    f := JavaScriptCompiler
        compile:('test(arg) {
                    var n;

                    n = 1;
                    while (n <= arg) {
                        n++;
                        Transcript.showCR(#hello#);
                    }
                 }' replaceAll:$# with:Character doubleQuote)
        forClass:nil
        inCategory:nil
        notifying:nil.
    f valueWithReceiver:nil arguments:#(5).
    |f|

    f := JavaScriptCompiler
        compile:'test(arg) {
                    var n;

                    n = 1;
                    while (n <= arg) {
                        Transcript.showCR(n++);
                    }
                 }'
        forClass:nil
        inCategory:nil
        notifying:nil.
    f valueWithReceiver:nil arguments:#(5).
    |f|

    f := JavaScriptCompiler
        compile:'test(arg) {
                    var n;

                    n = 1;
                    while (n++ <= arg) {
                        Transcript.showCR(n);
                    }
                 }'
        forClass:nil
        inCategory:nil
        notifying:nil.
    f valueWithReceiver:nil arguments:#(5).
    |f|

    f := JavaScriptCompiler
        compile:'foo() {
                    Transcript.showCR(''start'');
                    try {
                        Error.raise();
                    } catch(Error) {
                        Transcript.showCR(''caught error'');
                    };
                    Transcript.showCR(''end'');
                 }'
        forClass:nil
        inCategory:nil
        notifying:nil.
    f valueWithReceiver:nil arguments:#().


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Tue, 03 Dec 2024 17:58:27 GMT