VM Maker: VMMakerJS-bf.16.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMakerJS-bf.16.mcz

commits-2
 
Bert Freudenberg uploaded a new version of VMMakerJS to project VM Maker:
http://source.squeak.org/VMMaker/VMMakerJS-bf.16.mcz

==================== Summary ====================

Name: VMMakerJS-bf.16
Author: bf
Time: 13 November 2014, 7:08:06.162 pm
UUID: aa9fd3da-7901-4c62-ae34-c166f1492d3b
Ancestors: VMMakerJS-bf.15

Balloon2D needs pointer arithmetic. Fake it.
How? If p is a 'pointer' to an Int32Array, then
        p += offset
becomes
        p = new Int32Array(p.buffer, p.byteOffset + 4 * offset)
This is actually more efficient than it looks. The Int32Array is just an object holding a buffer, and offset. Allocating this is cheap, and it's going to be GC'ed quickly. The resulting plugin is actually twice as fast as my home-grown one.

=============== Diff against VMMakerJS-bf.15 ===============

Item was changed:
  ----- Method: JSCodeGenerator class>>translateAllPluginsIn: (in category 'utilities') -----
  translateAllPluginsIn: aDirectory
  self beActiveDuring: [
  #( ADPCMCodecPlugin
+ BalloonEnginePlugin
  "BMPReadWriterPlugin -- not working yet"
  BitBltSimulation
+ "DSAPlugin --not working yet"
- DSAPlugin
  DeflatePlugin
  FFTPlugin
  FloatArrayPlugin
+ GeniePlugin "-- not working yet"
- "GeniePlugin -- not working yet"
  JPEGReaderPlugin
  KedamaPlugin
  KedamaPlugin2
  KlattSynthesizerPlugin
  LargeIntegersPlugin
  Matrix2x3Plugin
  MiscPrimitivePlugin
  ScratchPlugin
  SoundGenerationPlugin
  StarSqueakPlugin
  ) do: [:pluginName |
  self environment at: pluginName ifPresent: [:plugin |
  plugin translateInDirectory: aDirectory doInlining: false]]
  displayingProgress: 'Generating JS plugins'].!

Item was changed:
  ----- Method: JSCodeGenerator>>checkNonPointer:op: (in category 'private') -----
  checkNonPointer: node op: op
+ self ifPointerVar: node then: [:type |
+ self halt: 'cannot do ', op, ' with ', type]!
- node isVariable
- ifTrue: [(self typeOfVariable: node name) ifNotNil: [:type |
- (type includes: $*) ifTrue: [self halt: 'cannot do ', op, ' with ', type]]].!

Item was changed:
  ----- Method: JSCodeGenerator>>generateAt:on:indent: (in category 'JS translation') -----
  generateAt: msgNode on: aStream indent: level
  "Generate the JS code for this message onto the given stream."
+ | arrayNode indexNode subtractOne complex coerceTo |
- | arrayNode indexNode subtractOne complex |
  arrayNode := msgNode receiver.
+ (arrayNode isSend and: [arrayNode selector = #cCoerce:to: and: [arrayNode args first isVariable]]) ifTrue: [
+ coerceTo := (arrayNode args second value) copyWithout: $ .
+ arrayNode := arrayNode args first.
+ aStream nextPutAll: '('].
  indexNode := msgNode args first.
  subtractOne := self isOneBasedArray: arrayNode name in: currentMethod.
  (subtractOne and: [indexNode isPlusOne]) ifTrue: [
  subtractOne := false.
  indexNode := indexNode receiver. "remove + 1"
  ].
  complex := subtractOne and: [indexNode isLeafOrFunc not].
  self emitJSExpression: arrayNode on: aStream.
  aStream nextPut: $[.
  complex ifTrue: [aStream nextPut: $(].
  indexNode emitJSCodeAsExpressionOn: aStream level: level + 1 generator: self.
  complex ifTrue: [aStream nextPut: $)].
  subtractOne ifTrue: [aStream nextPutAll: ' - 1'].
+ aStream nextPut: $].
+ coerceTo ifNotNil: [
+ coerceTo = 'int*' ifFalse: [self halt].
+ aStream nextPutAll: '|0)'].
+ !
- aStream nextPut: $].!

Item was changed:
  ----- Method: JSCodeGenerator>>generateAtPut:on:indent: (in category 'JS translation') -----
  generateAtPut: msgNode on: aStream indent: level
  "Generate the JS code for this message onto the given stream."
  | putExpr incExpr |
+ (msgNode receiver isSend and: [msgNode receiver selector = #cCoerce:to:]) ifTrue: [
+ msgNode receiver args asString =  '{deltaST . ''int *''}'
+ ifTrue: [msgNode receiver: msgNode receiver args first]]. "HACK!!"
  self generateAt: msgNode on: aStream indent: level.
 
  (putExpr := msgNode args last) isPlusOne ifTrue: [
  ((incExpr := putExpr receiver) isSend and: [incExpr selector = #at: and: [
  incExpr receiver asString = msgNode receiver asString and: [
  incExpr args first asString = msgNode args first asString]]])
  ifTrue: [^aStream nextPutAll: '++'.]].
 
  aStream nextPutAll: ' = '.
  self emitJSExpression: putExpr on: aStream!

Item was changed:
  ----- Method: JSCodeGenerator>>generateBitShift:on:indent: (in category 'JS translation') -----
  generateBitShift: msgNode on: aStream indent: level
  "Generate the JS code for this message onto the given stream."
 
  | arg rcvr |
  arg := msgNode args first.
  rcvr := msgNode receiver.
  arg isConstant ifTrue: [
  "bit shift amount is a constant"
- self emitJSExpression: rcvr on: aStream.
  arg value < 0 ifTrue: [
+ "skip unneeded coercion to unsigned"
+ (rcvr isSend and: [rcvr selector = #cCoerce:to: and: [rcvr args second value = 'unsigned']])
+ ifTrue: [self emitJSExpression: rcvr args first on: aStream]
+ ifFalse: [self emitJSExpression: rcvr on: aStream].
  aStream nextPutAll: ' >>> ', arg value negated printString.
  ] ifFalse: [
+ self emitJSExpression: rcvr on: aStream.
  aStream nextPutAll: ' << ', arg value printString.
  ].
  ] ifFalse: [
  "bit shift amount is an expression"
  aStream nextPutAll: 'SHIFT('.
  self emitJSExpression: rcvr on: aStream.
  aStream nextPutAll: ', '.
  self emitJSExpression: arg on: aStream.
  aStream nextPutAll: ')'.
  ].!

Item was changed:
  ----- Method: JSCodeGenerator>>generateCCoercion:on:indent: (in category 'JS translation') -----
  generateCCoercion: msgNode on: aStream indent: level
  "Generate the JS code for this message onto the given stream."
  | expr cType |.
  expr := msgNode args first.
  cType := msgNode args second value.
  (expr isSend and: [expr receiver name = 'interpreterProxy' and: [expr selector = #firstIndexableField:]]) ifTrue: [
  cType := msgNode args second value.
  self emitJSExpression: expr args first on: aStream.
  cType = 'unsigned char *' ifTrue: [^aStream nextPutAll: '.bytes'].
  cType = 'unsigned int *' ifTrue: [^aStream nextPutAll: '.words'].
  cType = 'int *' ifTrue: [^aStream nextPutAll: '.wordsAsInt32Array()'].
  cType = 'short *' ifTrue: [^aStream nextPutAll: '.wordsAsInt16Array()'].
  cType = 'float *' ifTrue: [^aStream nextPutAll: '.wordsAsFloat32Array()'].
  cType = 'double *' ifTrue: [^aStream nextPutAll: '.wordsAsFloat64Array()'].
  self halt.
  ] ifFalse: [
+ (#('int') includes: cType) ifTrue: [
- (#('int' 'unsigned int') includes: cType) ifTrue: [
  aStream nextPutAll: '('.
  self emitJSExpression: expr on: aStream.
  ^aStream nextPutAll: '|0)'].
+ (#('unsigned int' 'unsigned' ) includes: cType) ifTrue: [
+ aStream nextPutAll: '('.
+ self emitJSExpression: expr on: aStream.
+ ^ aStream nextPutAll: '>>>0)'].
+ ((#('double' 'float') includes: cType) or: [('sqInt (*)(*)'match: cType)
+ or: [#(transformPoint:into:) includes: currentMethod selector]])
- ((#('double' 'float') includes: cType) or: ['sqInt (*)(*)'match: cType])
  ifFalse: [self halt].
  self emitJSExpression: expr on: aStream.
  ]
  !

Item was changed:
  ----- Method: JSCodeGenerator>>generateDivide:on:indent: (in category 'JS translation') -----
  generateDivide: msgNode on: aStream indent: level
  "Generate the JS code for this message onto the given stream."
 
  | rcvr arg divisor |
  rcvr := msgNode receiver.
  arg := msgNode args first.
  msgNode selector == #/ ifTrue: [
+ (#('Matrix2x3Plugin' 'ScratchPlugin' 'FloatArrayPlugin' 'KedamaPlugin' 'KedamaPlugin2' 'FFTPlugin' 'Klatt' 'B2DPlugin') includes: self pluginName) ifFalse: [self halt: msgNode].
- (#('Matrix2x3Plugin' 'ScratchPlugin' 'FloatArrayPlugin' 'KedamaPlugin' 'KedamaPlugin2' 'FFTPlugin' 'Klatt') includes: self pluginName) ifFalse: [self halt].
  self emitJSExpression: rcvr on: aStream.
  aStream nextPutAll: ' / '.
  ^self emitJSExpression: arg on: aStream].
  (arg isConstant and:
  [UseRightShiftForDivide and:
  [(divisor := arg value) isInteger and:
  [divisor isPowerOfTwo and:
  [divisor > 0 and:
  [divisor <= (1 bitShift: 31)]]]]])
  ifTrue: [
  "use signed (arithmetic) right shift instead of divide"
  self emitJSExpression: rcvr on: aStream.
  aStream nextPutAll: ' >> ', (divisor log: 2) asInteger printString.
  ] ifFalse: [
  "use float divide and coerce to integer"
  aStream nextPutAll: 'DIV('.
  self emitJSExpression: rcvr on: aStream.
  aStream nextPutAll: ', '.
  self emitJSExpression: arg on: aStream.
  aStream nextPutAll: ')'.
  ].
  !

Item was changed:
  ----- Method: JSCodeGenerator>>generateFirstIndexableField:on:indent: (in category 'JS hacks') -----
  generateFirstIndexableField: msgNode on: aStream indent: level
  | parent cType accessor |
  self oneBasedArrays: false.
  "HACK: detect cType from parent node"
  parent := thisContext sender sender sender.
  cType := parent method == (TAssignmentNode>>#emitJSCodeOn:level:generator:)
  ifTrue: [self typeOfVariable: parent receiver variable name] ifFalse: [
  parent method == (TSendNode>>#emitJSCodeAsFunctionCallOn:level:generator:)
  ifTrue: [self typeOfArgument: (parent receiver args indexOf: msgNode) in: parent receiver selector] ifFalse: [
  msgNode asString = 'interpreterProxy firstIndexableField: mapOop'
  ifTrue: ['unsigned int*'] ifFalse: [
  msgNode asString = 'interpreterProxy firstIndexableField: blockOop'
  ifTrue: ['int*'] ifFalse: [
+ parent method == (TReturnNode>>#emitJSCodeOn:level:generator:)
+ ifTrue: [currentMethod returnType] ifFalse: [
+ self halt]]]]].
- self halt]]]].
  cType ifNotNil: [
  cType := cType copyReplaceAll: ' *' with: '* '.
  accessor := (cType beginsWith: 'unsigned char*') ifTrue: ['.bytes']
  ifFalse: [(cType beginsWith: 'unsigned int*') ifTrue: ['.words']
  ifFalse: [(cType beginsWith: 'int*') ifTrue: ['.wordsAsInt32Array()']
  ifFalse: [(cType beginsWith: 'char*') ifTrue: ['.bytes']
  ifFalse: [(cType beginsWith: 'float*') ifTrue: ['.wordsAsFloat32Array()']
  ifFalse: [self halt: 'need to handle ', cType]]]]].
  accessor ifNotNil: [msgNode args first emitJSCodeOn: aStream level: level generator: self.
  ^aStream nextPutAll: accessor]].
  "generic code below, not needed ever hopefully"
  aStream nextPutAll: 'interpreterProxy.'.
  ^ msgNode emitJSCodeAsFunctionCallOn: aStream level: level generator: self!

Item was added:
+ ----- Method: JSCodeGenerator>>generateLoadPointInt:on:indent: (in category 'JS hacks') -----
+ generateLoadPointInt: msgNode on: aStream indent: level
+ aStream nextPutAll: '('.
+ self emitJSExpression: msgNode args second on: aStream.
+ aStream nextPutAll: '['.
+ self emitJSExpression: msgNode args first on: aStream.
+ aStream nextPutAll: ']|0)'.
+ !

Item was added:
+ ----- Method: JSCodeGenerator>>generateLoadPointShort:on:indent: (in category 'JS hacks') -----
+ generateLoadPointShort: msgNode on: aStream indent: level
+ msgNode args second isVariable ifFalse: [self halt].
+ msgNode args second name = 'points' ifFalse: [self halt].
+ aStream nextPutAll: '(points.int16Array || (points.int16Array = new Int16Array(points.buffer, points.byteOffset)))['.
+ msgNode args first emitJSCodeAsExpressionOn: aStream level: 0 generator: self.
+ aStream nextPutAll: ']'.
+ !

Item was added:
+ ----- Method: JSCodeGenerator>>generateMakeUnsignedFrom:on:indent: (in category 'JS hacks') -----
+ generateMakeUnsignedFrom: msgNode on: aStream indent: level
+ "Generate the JS code for this message onto the given stream."
+ | expr type coerce |
+ msgNode args size = 1 ifFalse: [self halt].
+ expr := msgNode args first.
+ (expr isSend and: [expr selector = #at:])
+ ifFalse: [^self emitJSExpression: expr on: aStream].
+ coerce := expr receiver.
+ (coerce isSend and: [coerce selector = #cCoerce:to:])
+ ifFalse: [^self emitJSExpression: expr on: aStream].
+ type := (coerce args second value) copyWithout: $ .
+ type = 'int*' ifFalse: [self halt].
+ self emitJSExpression: coerce args first on: aStream.
+ aStream nextPut: $[.
+ expr args first emitJSCodeAsExpressionOn: aStream level: 0 generator: self.
+ aStream nextPut: $].
+ !

Item was changed:
  ----- Method: JSCodeGenerator>>generatePlus:on:indent: (in category 'JS translation') -----
  generatePlus: msgNode on: aStream indent: level
  "Generate the JS code for this message onto the given stream."
  msgNode receiver isBitBltPtr ifFalse: [
- self checkNonPointer: msgNode receiver op: '+'.
  self checkNonPointer: msgNode args first op: '+'.
+ self ifPointerVar: msgNode receiver then: [:type |
+ (self generatePointerPlus: msgNode type: type on: aStream indent: level)
+ ifTrue: [^self].
+ self halt: 'cannot do + with ', type].
  self emitJSExpression: msgNode receiver on: aStream.
  aStream nextPutAll: ' + '].
  self emitJSExpression: msgNode args first on: aStream.!

Item was added:
+ ----- Method: JSCodeGenerator>>generatePointerPlus:type:on:indent: (in category 'JS translation') -----
+ generatePointerPlus: msgNode type: type on: aStream indent: level
+ "Generate the JS code for this message onto the given stream."
+ (#('B2DPlugin' 'GeniePlugin') includes: self pluginName) ifFalse: [self halt].
+ msgNode emitJSPointerArithmetic: type on: aStream level: level generator: self type: type top: true.
+ ^true
+ !

Item was added:
+ ----- Method: JSCodeGenerator>>ifPointerVar:then: (in category 'private') -----
+ ifPointerVar: node then: aBlock
+ (node isSend and: [node selector = #+]) ifTrue: [
+ ^self ifPointerVar: node receiver then: aBlock].
+ node isVariable ifTrue: [
+ (self typeOfVariable: node name) ifNotNil: [:type |
+ (type includes: $*) ifTrue: [aBlock value: type]]].
+ !

Item was changed:
  ----- Method: JSCodeGenerator>>initialize (in category 'public') -----
  initialize
  translationDict := Dictionary new.
  inlineList := Array new.
  constants := Dictionary new: 100.
  variables := OrderedCollection new: 100.
  variableDeclarations := Dictionary new: 100.
  methods := Dictionary new: 500.
  macros := Dictionary new.
+ self initializeJSTranslationDictionary.
- self initializeCTranslationDictionary.
  receiverDict := Dictionary new.
  headerFiles := OrderedCollection new.
  globalVariableUsage := Dictionary new.
  useSymbolicConstants := true.
  generateDeadCode := false.
  scopeStack := OrderedCollection new.
  logger := (ProvideAnswerNotification new tag: #logger; signal) ifNil: [Transcript].
  pools := IdentitySet new.
  abstractDeclarations := IdentitySet new.
  uncheckedAbstractMethods := OrderedCollection new.
  !

Item was removed:
- ----- Method: JSCodeGenerator>>initializeCTranslationDictionary (in category 'JS translation') -----
- initializeCTranslationDictionary
- "Initialize the dictionary mapping message names to actions for C code generation."
-
- | pairs |
- translationDict := Dictionary new: 200.
- pairs := #(
- #& #generateAnd:on:indent:
- #| #generateOr:on:indent:
- #and: #generateSequentialAnd:on:indent:
- #or: #generateSequentialOr:on:indent:
- #not #generateNot:on:indent:
-
- #+ #generatePlus:on:indent:
- #- #generateMinus:on:indent:
- #negated #generateNegated:on:indent:
- #abs #generateMath:on:indent:
- #sqrt #generateMath:on:indent:
- #sin #generateMath:on:indent:
- #cos #generateMath:on:indent:
- #tan #generateMath:on:indent:
- #atan #generateMath:on:indent:
- #exp #generateMath:on:indent:
- #log #generateMath:on:indent:
- #* #generateTimes:on:indent:
- #/ #generateDivide:on:indent:
- #// #generateDivide:on:indent:
- #\\ #generateModulo:on:indent:
- #<< #generateShiftLeft:on:indent:
- #>> #generateShiftRight:on:indent:
- #min: #generateMin:on:indent:
- #max: #generateMax:on:indent:
- #between:and: #generateBetweenAnd:on:indent:
-
- #bitAnd: #generateBitAnd:on:indent:
- #bitOr: #generateBitOr:on:indent:
- #bitXor: #generateBitXor:on:indent:
- #bitShift: #generateBitShift:on:indent:
- #signedBitShift: #generateSignedBitShift:on:indent:
- #bitInvert32 #generateBitInvert32:on:indent:
- #bitClear: #generateBitClear:on:indent:
-
- #< #generateLessThan:on:indent:
- #<= #generateLessThanOrEqual:on:indent:
- #= #generateEqual:on:indent:
- #> #generateGreaterThan:on:indent:
- #>= #generateGreaterThanOrEqual:on:indent:
- #~= #generateNotEqual:on:indent:
- #== #generateEqual:on:indent:
- #~~ #generateNotEqual:on:indent:
- #isNil #generateIsNil:on:indent:
- #notNil #generateNotNil:on:indent:
-
- #whileTrue: #generateWhileTrue:on:indent:
- #whileFalse: #generateWhileFalse:on:indent:
- #whileTrue #generateDoWhileTrue:on:indent:
- #whileFalse #generateDoWhileFalse:on:indent:
- #to:do: #generateToDo:on:indent:
- #to:by:do: #generateToByDo:on:indent:
- #repeat #generateRepeat:on:indent:
-
- #ifTrue: #generateIfTrue:on:indent:
- #ifFalse: #generateIfFalse:on:indent:
- #ifTrue:ifFalse: #generateIfTrueIfFalse:on:indent:
- #ifFalse:ifTrue: #generateIfFalseIfTrue:on:indent:
-
- #at: #generateAt:on:indent:
- #at:put: #generateAtPut:on:indent:
- #basicAt: #generateAt:on:indent:
- #basicAt:put: #generateAtPut:on:indent:
-
- #integerValueOf: #generateIntegerValueOf:on:indent:
- #integerObjectOf: #generateIntegerObjectOf:on:indent:
- #isIntegerObject: #generateIsIntegerObject:on:indent:
- #cCode: #generateInlineCCode:on:indent:
- #cCode:inSmalltalk: #generateInlineCCode:on:indent:
- #cPreprocessorDirective: #generateInlineCPreprocessorDirective:on:indent:
- #preprocessorExpression: #generateInlineCppDirective:on:indent:
- #isDefined:inSmalltalk:comment:ifTrue: #generateInlineCppIfDef:on:indent:
- #isDefined:inSmalltalk:comment:ifTrue:ifFalse: #generateInlineCppIfDefElse:on:indent:
- #isDefinedTrueExpression:inSmalltalk:comment:ifTrue:ifFalse: #generateInlineCppIfElse:on:indent:
- #cCoerce:to: #generateCCoercion:on:indent:
- #cCoerceSimple:to: #generateCCoercion:on:indent:
- #addressOf: #generateAddressOf:on:indent:
- #signedIntFromLong #generateSignedIntFromLong:on:indent:
- #signedIntToLong #generateSignedIntToLong:on:indent:
- #signedIntFromShort #generateSignedIntFromShort:on:indent:
- #signedIntToShort #generateSignedIntToShort:on:indent:
- #preIncrement #generatePreIncrement:on:indent:
- #preDecrement #generatePreDecrement:on:indent:
- #inline: #generateInlineDirective:on:indent:
- #asFloat #generateAsFloat:on:indent:
- #asInteger #generateAsInteger:on:indent:
- #asUnsignedInteger #generateAsUnsignedInteger:on:indent:
- #asSymbol #generateAsSymbol:on:indent:
- #anyMask: #generateBitAnd:on:indent:
- #raisedTo: #generateRaisedTo:on:indent:
- #touch: #generateTouch:on:indent:
- #bytesPerWord #generateBytesPerWord:on:indent:
- #baseHeaderSize #generateBaseHeaderSize:on:indent:
-
- #sharedCodeNamed:inCase: #generateSharedCodeDirective:on:indent:
-
- #perform: #generatePerform:on:indent:
- #perform:with: #generatePerform:on:indent:
- #perform:with:with: #generatePerform:on:indent:
- #perform:with:with:with: #generatePerform:on:indent:
- #perform:with:with:with:with: #generatePerform:on:indent:
- #perform:with:with:with:with:with: #generatePerform:on:indent:
-
- #shouldNotImplement #generateSmalltalkMetaError:on:indent:
- #shouldBeImplemented #generateSmalltalkMetaError:on:indent:
-
- "optimized interpreterProxy calls"
- #firstIndexableField: #generateFirstIndexableField:on:indent:
- #slotSizeOf: #generateSlotSizeOf:on:indent:
- #stSizeOf: #generateSlotSizeOf:on:indent:
- #byteSizeOfBytes: #generateByteSizeOf:on:indent:
- #byteSizeOf: #generateByteSizeOf:on:indent:
- #fetchClassOf: #generateFetchClassOf:on:indent:
- #superclassOf: #generateSuperclassOf:on:indent:
- #instanceSizeOf: #generateInstanceSizeOf:on:indent:
- #is:KindOf: #generateIsKindOf:on:indent:
- #isFloatObject: #generateIsFloatObject:on:indent:
- #cDigitCopyFrom:to:len: #generateCDigitCopy:on:indent:
- #sizeOfSTArrayFromCPrimitive: #generateSizeOfSTArrayFromCPrimitive:on:indent:
- #asciiValue #generateIdentityUnary:on:indent:
- #primitiveFail #generateInterpreterProxyCall:on:indent:
- #intAtPointer: #generateIntAtPointer:on:indent:
- #byteAtPointer: #generateByteAtPointer:on:indent:
- #oopForPointer: #generateOopForPointer:on:indent:
- #long32At: #generateLong32At:on:indent:
- #srcLongAt: #generateSrcLongAt:on:indent:
- #dstLongAt: #generateDstLongAt:on:indent:
- #dstLongAt:put: #generateDstLongAtPut:on:indent:
- ).
-
- 1 to: pairs size by: 2 do: [:i |
- translationDict at: (pairs at: i) put: (pairs at: i + 1)].
-
- pairs := #(
- #ifTrue: #generateIfTrueAsArgument:on:indent:
- #ifFalse: #generateIfFalseAsArgument:on:indent:
- #ifTrue:ifFalse: #generateIfTrueIfFalseAsArgument:on:indent:
- #ifFalse:ifTrue: #generateIfFalseIfTrueAsArgument:on:indent:
- #cCode: #generateInlineCCodeAsArgument:on:indent:
- #cCode:inSmalltalk: #generateInlineCCodeAsArgument:on:indent:
- ).
-
- asArgumentTranslationDict := Dictionary new: 8.
- 1 to: pairs size by: 2 do: [:i |
- asArgumentTranslationDict at: (pairs at: i) put: (pairs at: i + 1)].
-
- cCodeTranslationDict := Dictionary new: 8.
- pairs := #(
- 'fprintf(stderr, "\n%s: %s", moduleName, s)' 'console.log(moduleName + ": " + s)'
- 'interpreterProxy->majorVersion() == VM_PROXY_MAJOR' 'interpreterProxy.majorVersion() == VM_PROXY_MAJOR'
- 'interpreterProxy->minorVersion() >= VM_PROXY_MINOR' 'interpreterProxy.minorVersion() >= VM_PROXY_MINOR'
- 'rand()' 'Math.random()'
- '*src++' 'src[_src++]'
- '*dst++ = max' 'dst[_dst++] = max'
- 'src++' '_src++'
- '*dst++ = *src; src += 2' 'dst[_dst++] = src[_src]; _src += 2'
- 'tX' 'tX'
- 'tY' 'tY'
- ).
- 1 to: pairs size by: 2 do: [:i |
- cCodeTranslationDict at: (pairs at: i) put: (pairs at: i + 1)].
- !

Item was added:
+ ----- Method: JSCodeGenerator>>initializeJSTranslationDictionary (in category 'JS translation') -----
+ initializeJSTranslationDictionary
+ "Initialize the dictionary mapping message names to actions for JS code generation."
+
+ | pairs |
+ translationDict := Dictionary new: 200.
+ pairs := #(
+ #& #generateAnd:on:indent:
+ #| #generateOr:on:indent:
+ #and: #generateSequentialAnd:on:indent:
+ #or: #generateSequentialOr:on:indent:
+ #not #generateNot:on:indent:
+
+ #+ #generatePlus:on:indent:
+ #- #generateMinus:on:indent:
+ #negated #generateNegated:on:indent:
+ #abs #generateMath:on:indent:
+ #sqrt #generateMath:on:indent:
+ #sin #generateMath:on:indent:
+ #cos #generateMath:on:indent:
+ #tan #generateMath:on:indent:
+ #atan #generateMath:on:indent:
+ #exp #generateMath:on:indent:
+ #log #generateMath:on:indent:
+ #* #generateTimes:on:indent:
+ #/ #generateDivide:on:indent:
+ #// #generateDivide:on:indent:
+ #\\ #generateModulo:on:indent:
+ #<< #generateShiftLeft:on:indent:
+ #>> #generateShiftRight:on:indent:
+ #min: #generateMin:on:indent:
+ #max: #generateMax:on:indent:
+ #between:and: #generateBetweenAnd:on:indent:
+
+ #bitAnd: #generateBitAnd:on:indent:
+ #bitOr: #generateBitOr:on:indent:
+ #bitXor: #generateBitXor:on:indent:
+ #bitShift: #generateBitShift:on:indent:
+ #signedBitShift: #generateSignedBitShift:on:indent:
+ #bitInvert32 #generateBitInvert32:on:indent:
+ #bitClear: #generateBitClear:on:indent:
+
+ #< #generateLessThan:on:indent:
+ #<= #generateLessThanOrEqual:on:indent:
+ #= #generateEqual:on:indent:
+ #> #generateGreaterThan:on:indent:
+ #>= #generateGreaterThanOrEqual:on:indent:
+ #~= #generateNotEqual:on:indent:
+ #== #generateEqual:on:indent:
+ #~~ #generateNotEqual:on:indent:
+ #isNil #generateIsNil:on:indent:
+ #notNil #generateNotNil:on:indent:
+
+ #whileTrue: #generateWhileTrue:on:indent:
+ #whileFalse: #generateWhileFalse:on:indent:
+ #whileTrue #generateDoWhileTrue:on:indent:
+ #whileFalse #generateDoWhileFalse:on:indent:
+ #to:do: #generateToDo:on:indent:
+ #to:by:do: #generateToByDo:on:indent:
+ #repeat #generateRepeat:on:indent:
+
+ #ifTrue: #generateIfTrue:on:indent:
+ #ifFalse: #generateIfFalse:on:indent:
+ #ifTrue:ifFalse: #generateIfTrueIfFalse:on:indent:
+ #ifFalse:ifTrue: #generateIfFalseIfTrue:on:indent:
+
+ #at: #generateAt:on:indent:
+ #at:put: #generateAtPut:on:indent:
+ #basicAt: #generateAt:on:indent:
+ #basicAt:put: #generateAtPut:on:indent:
+
+ #integerValueOf: #generateIntegerValueOf:on:indent:
+ #integerObjectOf: #generateIntegerObjectOf:on:indent:
+ #isIntegerObject: #generateIsIntegerObject:on:indent:
+ #cCode: #generateInlineCCode:on:indent:
+ #cCode:inSmalltalk: #generateInlineCCode:on:indent:
+ #cPreprocessorDirective: #generateInlineCPreprocessorDirective:on:indent:
+ #preprocessorExpression: #generateInlineCppDirective:on:indent:
+ #isDefined:inSmalltalk:comment:ifTrue: #generateInlineCppIfDef:on:indent:
+ #isDefined:inSmalltalk:comment:ifTrue:ifFalse: #generateInlineCppIfDefElse:on:indent:
+ #isDefinedTrueExpression:inSmalltalk:comment:ifTrue:ifFalse: #generateInlineCppIfElse:on:indent:
+ #cCoerce:to: #generateCCoercion:on:indent:
+ #cCoerceSimple:to: #generateCCoercion:on:indent:
+ #addressOf: #generateAddressOf:on:indent:
+ #signedIntFromLong #generateSignedIntFromLong:on:indent:
+ #signedIntToLong #generateSignedIntToLong:on:indent:
+ #signedIntFromShort #generateSignedIntFromShort:on:indent:
+ #signedIntToShort #generateSignedIntToShort:on:indent:
+ #preIncrement #generatePreIncrement:on:indent:
+ #preDecrement #generatePreDecrement:on:indent:
+ #inline: #generateInlineDirective:on:indent:
+ #asFloat #generateAsFloat:on:indent:
+ #asInteger #generateAsInteger:on:indent:
+ #asUnsignedInteger #generateAsUnsignedInteger:on:indent:
+ #asSymbol #generateAsSymbol:on:indent:
+ #anyMask: #generateBitAnd:on:indent:
+ #raisedTo: #generateRaisedTo:on:indent:
+ #touch: #generateTouch:on:indent:
+ #bytesPerWord #generateBytesPerWord:on:indent:
+ #baseHeaderSize #generateBaseHeaderSize:on:indent:
+
+ #sharedCodeNamed:inCase: #generateSharedCodeDirective:on:indent:
+
+ #perform: #generatePerform:on:indent:
+ #perform:with: #generatePerform:on:indent:
+ #perform:with:with: #generatePerform:on:indent:
+ #perform:with:with:with: #generatePerform:on:indent:
+ #perform:with:with:with:with: #generatePerform:on:indent:
+ #perform:with:with:with:with:with: #generatePerform:on:indent:
+
+ #shouldNotImplement #generateSmalltalkMetaError:on:indent:
+ #shouldBeImplemented #generateSmalltalkMetaError:on:indent:
+
+ "optimized interpreterProxy calls"
+ #firstIndexableField: #generateFirstIndexableField:on:indent:
+ #slotSizeOf: #generateSlotSizeOf:on:indent:
+ #stSizeOf: #generateSlotSizeOf:on:indent:
+ #byteSizeOfBytes: #generateByteSizeOf:on:indent:
+ #byteSizeOf: #generateByteSizeOf:on:indent:
+ #fetchClassOf: #generateFetchClassOf:on:indent:
+ #superclassOf: #generateSuperclassOf:on:indent:
+ #instanceSizeOf: #generateInstanceSizeOf:on:indent:
+ #is:KindOf: #generateIsKindOf:on:indent:
+ #isFloatObject: #generateIsFloatObject:on:indent:
+ #cDigitCopyFrom:to:len: #generateCDigitCopy:on:indent:
+ #sizeOfSTArrayFromCPrimitive: #generateSizeOfSTArrayFromCPrimitive:on:indent:
+ #asciiValue #generateIdentityUnary:on:indent:
+ #primitiveFail #generateInterpreterProxyCall:on:indent:
+ #intAtPointer: #generateIntAtPointer:on:indent:
+ #byteAtPointer: #generateByteAtPointer:on:indent:
+ #oopForPointer: #generateOopForPointer:on:indent:
+ #long32At: #generateLong32At:on:indent:
+ #srcLongAt: #generateSrcLongAt:on:indent:
+ #dstLongAt: #generateDstLongAt:on:indent:
+ #dstLongAt:put: #generateDstLongAtPut:on:indent:
+ ).
+
+ 1 to: pairs size by: 2 do: [:i |
+ translationDict at: (pairs at: i) put: (pairs at: i + 1)].
+
+ pairs := #(
+ #ifTrue: #generateIfTrueAsArgument:on:indent:
+ #ifFalse: #generateIfFalseAsArgument:on:indent:
+ #ifTrue:ifFalse: #generateIfTrueIfFalseAsArgument:on:indent:
+ #ifFalse:ifTrue: #generateIfFalseIfTrueAsArgument:on:indent:
+ #cCode: #generateInlineCCodeAsArgument:on:indent:
+ #cCode:inSmalltalk: #generateInlineCCodeAsArgument:on:indent:
+ ).
+
+ asArgumentTranslationDict := Dictionary new: 8.
+ 1 to: pairs size by: 2 do: [:i |
+ asArgumentTranslationDict at: (pairs at: i) put: (pairs at: i + 1)].
+
+ cCodeTranslationDict := Dictionary new: 8.
+ pairs := #(
+ 'fprintf(stderr, "\n%s: %s", moduleName, s)' 'console.log(moduleName + ": " + s)'
+ 'interpreterProxy->majorVersion() == VM_PROXY_MAJOR' 'interpreterProxy.majorVersion() == VM_PROXY_MAJOR'
+ 'interpreterProxy->minorVersion() >= VM_PROXY_MINOR' 'interpreterProxy.minorVersion() >= VM_PROXY_MINOR'
+ 'rand()' 'Math.random()'
+ '*src++' 'src[_src++]'
+ '*dst++ = max' 'dst[_dst++] = max'
+ 'src++' '_src++'
+ '*dst++ = *src; src += 2' 'dst[_dst++] = src[_src]; _src += 2'
+ 'tX' 'tX'
+ 'tY' 'tY'
+ '((sqInt (*)(sqInt, sqInt, sqInt))copyBitsFn)(x0, x1, yValue)' 'copyBitsFn(x0, x1, yValue)'
+ '((sqInt (*)(sqInt))loadBBFn)(bbObj)' 'loadBBFn(bbObj)'
+ ).
+ 1 to: pairs size by: 2 do: [:i |
+ cCodeTranslationDict at: (pairs at: i) put: (pairs at: i + 1)].
+ !

Item was changed:
  ----- Method: JSCodeGenerator>>isPointer: (in category 'private') -----
  isPointer: node
+ self ifPointerVar: node then: [:type | ^true].
- node isVariable ifFalse: [^false].
- (self typeOfVariable: node name) ifNotNil: [:type | ^type includes: $*].
  ^false!

Item was changed:
  ----- Method: JSMethod>>emitJSCodeOn:generator: (in category 'JS code generation') -----
  emitJSCodeOn: aStream generator: aCodeGen
  "Emit JS code for this method onto the given stream. All calls to inlined methods should already have been expanded."
  aCodeGen currentMethod: self.
  aCodeGen pushScope: declarations while: [
  self emitJSCommentOn: aStream. "place method comment before function"
  self emitJSHeaderOn: aStream generator: aCodeGen.
+ (self emitJSSpecialOn:  aStream level: 1 generator: aCodeGen)
+ ifFalse: [parseTree emitJSCodeOn: aStream level: 1 generator: aCodeGen].
- parseTree emitJSCodeOn: aStream level: 1 generator: aCodeGen.
  aStream nextPutAll: '}'; cr]!

Item was added:
+ ----- Method: JSMethod>>emitJSSpecialOn:level:generator: (in category 'JS hacks') -----
+ emitJSSpecialOn: aStream level: level generator: aCodeGen
+ | expr type |
+ aCodeGen pluginName = 'B2DPlugin' ifFalse: [^false].
+ (returnType includes: $*) ifFalse: [^false].
+ parseTree statements first isReturn ifFalse: [^false].
+ expr := parseTree statements first expression.
+ expr isSend ifFalse: [^false].
+ type := returnType.
+ expr selector = #cCoerce:to: ifTrue: [
+ type = expr args second value ifFalse: [self halt].
+ expr := expr args first.
+ ].
+ expr selector = #+ ifFalse: [^false].
+ aStream tab: level; nextPutAll: 'return '.
+ expr emitJSPointerArithmetic: type on: aStream level: level generator: aCodeGen type: type top: true.
+ aStream nextPutAll: ';'; cr.
+ ^true
+ !

Item was changed:
  ----- Method: JSPluginCodeGenerator>>ignoredMethods (in category 'public') -----
  ignoredMethods
  pluginName = 'BitBltPlugin' ifTrue: [
  ^#(dstLongAt: dstLongAt:put: srcLongAt:)].
  pluginName = 'ScratchPlugin' ifTrue: [
  ^(ScratchPlugin organization listAtCategoryNamed: 'serial port'),
  (ScratchPlugin organization listAtCategoryNamed: 'os functions')].
+ pluginName = 'B2DPlugin' ifTrue: [
+ ^self translatedMethodsB2DPlugin collect: [:ea | ea key]].
  ^super ignoredMethods!

Item was added:
+ ----- Method: JSPluginCodeGenerator>>overrideJSTranslationDictionary (in category 'public') -----
+ overrideJSTranslationDictionary
+ | sel |
+ sel := (#translatedMethods, self pluginName) asSymbol.
+ (self respondsTo: sel) ifFalse: [^self].
+ (self perform: sel) associationsDo: [:assoc |
+ translationDict at: assoc key put: assoc value].
+ !

Item was changed:
  ----- Method: JSPluginCodeGenerator>>pluginName: (in category 'public') -----
  pluginName: aString
  "TPR - moved from JSCodeGenerator"
  "Set the plugin name when generating plugins."
+ pluginName := aString.
+ self overrideJSTranslationDictionary.!
- pluginName := aString.!

Item was added:
+ ----- Method: JSPluginCodeGenerator>>translatedMethodsB2DPlugin (in category 'public') -----
+ translatedMethodsB2DPlugin
+ "see senders of translatedMethods"
+ ^{
+ #makeUnsignedFrom: -> #generateMakeUnsignedFrom:on:indent:.
+ #loadPointIntAt:from: -> #generateLoadPointInt:on:indent:.
+ #loadPointShortAt:from: -> #generateLoadPointShort:on:indent:.
+ }!

Item was removed:
- ----- Method: JSSmartSyntaxPluginCodeGenerator>>initializeCTranslationDictionary (in category 'translating builtins') -----
- initializeCTranslationDictionary
- "Initialize the dictionary mapping message names to actions for C code generation."
-
- | pairs |
- super initializeCTranslationDictionary.
- pairs := #(
- #asCInt #generateAsCInt:on:indent:
- #asCUnsigned #generateAsCUnsigned:on:indent:
- #asCBoolean #generateAsCBoolean:on:indent:
- #asCDouble #generateAsCDouble:on:indent:
-
- #asSmallIntegerObj #generateAsSmallIntegerObj:on:indent:
- #asPositiveIntegerObj #generateAsPositiveIntegerObj:on:indent:
- #asBooleanObj #generateAsBooleanObj:on:indent:
- #asFloatObj #generateAsFloatObj:on:indent:
-
- #asIf:var: #generateAsIfVar:on:indent:
- #asIf:var:asValue: #generateAsIfVarAsValue:on:indent:
- #asIf:var:put: #generateAsIfVarPut:on:indent:
- #field: #generateField:on:indent:
- #field:put: #generateFieldPut:on:indent:
-
- #class #generateClass:on:indent:
-
- #stSize #generateStSize:on:indent:
- #stAt: #generateStAt:on:indent:
- #stAt:put: #generateStAtPut:on:indent:
-
- #asCharPtr #generateAsCharPtr:on:indent:
- #asIntPtr #generateAsIntPtr:on:indent:
- #cPtrAsOop #generateCPtrAsOop:on:indent:
- #next #generateNext:on:indent:
-
- #asOop: #generateAsOop:on:indent:
- #asValue: #generateAsValue:on:indent:
-
- #isFloat #generateIsFloat:on:indent:
- #isIndexable #generateIsIndexable:on:indent:
- #isIntegerOop #generateIsIntegerOop:on:indent:
- #isIntegerValue #generateIsIntegerValue:on:indent:
- #FloatOop #generateIsFloatValue:on:indent:
- #isWords #generateIsWords:on:indent:
- #isWordsOrBytes #generateIsWordsOrBytes:on:indent:
- #isPointers #generateIsPointers:on:indent:
- #isNil #generateIsNil:on:indent:
- #isMemberOf: #generateIsMemberOf:on:indent:
- #isKindOf: #generateIsKindOf:on:indent:
-
- #fromStack: #generateFromStack:on:indent:
- #clone #generateClone:on:indent
- #new #generateNew:on:indent
- #new: #generateNewSize:on:indent
- #superclass #generateSuperclass:on:indent:
- #remapOop:in: #generateRemapOopIn:on:indent:
- #debugCode: #generateDebugCode:on:indent:
- ).
-
- 1 to: pairs size by: 2 do: [:i |
- translationDict at: (pairs at: i) put: (pairs at: i + 1)].
- !

Item was added:
+ ----- Method: JSSmartSyntaxPluginCodeGenerator>>initializeJSTranslationDictionary (in category 'translating builtins') -----
+ initializeJSTranslationDictionary
+ "Initialize the dictionary mapping message names to actions for C code generation."
+
+ | pairs |
+ super initializeJSTranslationDictionary.
+ pairs := #(
+ #asCInt #generateAsCInt:on:indent:
+ #asCUnsigned #generateAsCUnsigned:on:indent:
+ #asCBoolean #generateAsCBoolean:on:indent:
+ #asCDouble #generateAsCDouble:on:indent:
+
+ #asSmallIntegerObj #generateAsSmallIntegerObj:on:indent:
+ #asPositiveIntegerObj #generateAsPositiveIntegerObj:on:indent:
+ #asBooleanObj #generateAsBooleanObj:on:indent:
+ #asFloatObj #generateAsFloatObj:on:indent:
+
+ #asIf:var: #generateAsIfVar:on:indent:
+ #asIf:var:asValue: #generateAsIfVarAsValue:on:indent:
+ #asIf:var:put: #generateAsIfVarPut:on:indent:
+ #field: #generateField:on:indent:
+ #field:put: #generateFieldPut:on:indent:
+
+ #class #generateClass:on:indent:
+
+ #stSize #generateStSize:on:indent:
+ #stAt: #generateStAt:on:indent:
+ #stAt:put: #generateStAtPut:on:indent:
+
+ #asCharPtr #generateAsCharPtr:on:indent:
+ #asIntPtr #generateAsIntPtr:on:indent:
+ #cPtrAsOop #generateCPtrAsOop:on:indent:
+ #next #generateNext:on:indent:
+
+ #asOop: #generateAsOop:on:indent:
+ #asValue: #generateAsValue:on:indent:
+
+ #isFloat #generateIsFloat:on:indent:
+ #isIndexable #generateIsIndexable:on:indent:
+ #isIntegerOop #generateIsIntegerOop:on:indent:
+ #isIntegerValue #generateIsIntegerValue:on:indent:
+ #FloatOop #generateIsFloatValue:on:indent:
+ #isWords #generateIsWords:on:indent:
+ #isWordsOrBytes #generateIsWordsOrBytes:on:indent:
+ #isPointers #generateIsPointers:on:indent:
+ #isNil #generateIsNil:on:indent:
+ #isMemberOf: #generateIsMemberOf:on:indent:
+ #isKindOf: #generateIsKindOf:on:indent:
+
+ #fromStack: #generateFromStack:on:indent:
+ #clone #generateClone:on:indent
+ #new #generateNew:on:indent
+ #new: #generateNewSize:on:indent
+ #superclass #generateSuperclass:on:indent:
+ #remapOop:in: #generateRemapOopIn:on:indent:
+ #debugCode: #generateDebugCode:on:indent:
+ ).
+
+ 1 to: pairs size by: 2 do: [:i |
+ translationDict at: (pairs at: i) put: (pairs at: i + 1)].
+ !

Item was changed:
  ----- Method: TAssignmentNode>>emitJSCodeOn:level:generator: (in category '*vmmakerjs') -----
  emitJSCodeOn: aStream level: level generator: aCodeGen
  expression isSwitch ifTrue:
  [^expression emitJSCodeOn: aStream addToEndOfCases: self level: level generator: aCodeGen].
+ (self isVariableUpdatingAssignment and: [(aCodeGen isPointer: variable) not])
- self isVariableUpdatingAssignment
  ifTrue:
  [(expression args first isConstant and: [expression args first value = 1])
  ifTrue: [aStream nextPutAll: expression selector, expression selector.
  variable emitJSCodeOn: aStream level: level generator: aCodeGen]
  ifFalse: [
  variable emitJSCodeOn: aStream level: level generator: aCodeGen.
  aStream nextPutAll: ' ', expression selector, '= '.
  expression args first emitJSCodeAsArgumentOn: aStream level: level generator: aCodeGen]]
  ifFalse:
  [ | coerceToInt |
  coerceToInt := (variable isFloatIn: aCodeGen) not and: [expression isFloatIn: aCodeGen].
  variable emitJSCodeOn: aStream level: level generator: aCodeGen.
  aStream nextPutAll: ' = '.
  expression emitJSCodeAsArgumentOn: aStream level: level generator: aCodeGen.
  coerceToInt ifTrue: [aStream nextPutAll: '|0'].]!

Item was added:
+ ----- Method: TSendNode>>emitJSPointerArithmetic:on:level:generator:type:top: (in category '*vmmakerjs') -----
+ emitJSPointerArithmetic: type on: aStream level: level generator: aGenerator type: cType top: top
+ (selector = #+) ifFalse: [self halt].
+ receiver isVariable
+ ifTrue: [ | typeAndSize |
+ typeAndSize := ({'int' -> #('Int32Array' 4). 'float' -> #('Float32Array' 4)} as: Dictionary)
+ at: ((cType copyUpTo: $*) copyWithout: $ ).
+ aStream nextPutAll: ('new {1}({2}.buffer, {2}.byteOffset + {3} * ('
+ format: {typeAndSize first. receiver name. typeAndSize second})]
+ ifFalse: [receiver emitJSPointerArithmetic: type on: aStream level: level generator: aGenerator type: cType top: false.
+ aStream nextPutAll: ' + '].
+ aGenerator emitJSExpression: arguments first on: aStream.
+ top ifTrue: [aStream nextPutAll: '))'].!