[Vm-dev] VM Maker: VMMakerJS-bf.16.mcz
commits at source.squeak.org
commits at source.squeak.org
Thu Nov 13 23:27:31 UTC 2014
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: '))'].!
More information about the Vm-dev
mailing list