VM Maker: VMMakerJS-bf.12.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.12.mcz

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

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

Name: VMMakerJS-bf.12
Author: bf
Time: 14 October 2014, 3:49:18.236 pm
UUID: a24182f0-6780-4782-a772-87ccf9030a78
Ancestors: VMMakerJS-bf.11

Fix inst vars in non-inlined prim methods (specifically, ADPCMCodecPlugin).

=============== Diff against VMMakerJS-bf.11 ===============

Item was changed:
  ----- Method: JSCodeGenerator class>>beActiveDuring: (in category 'preferences') -----
  beActiveDuring: aBlock
  | wasActive |
  wasActive := self isActive.
+ self isActive: true.
  aBlock ensure: [self isActive: wasActive].!

Item was changed:
  ----- Method: JSCodeGenerator>>addMethodsForPrimitives: (in category 'public') -----
  addMethodsForPrimitives: classAndSelectorList
+ | sel aClass source verbose meth primInstVars sharedInstVars assignedInstVars |
- | sel aClass source verbose meth |
  classAndSelectorList do:[:classAndSelector |
  aClass := Smalltalk at: (classAndSelector at: 1) ifAbsent:[nil].
  aClass ifNotNil:[
  self addAllClassVarsFor: aClass.
  "TPR - should pool vars also be added here?"
 
  "find the method in either the class or the metaclass"
  sel := classAndSelector at: 2.
  (aClass includesSelector: sel)
  ifTrue: [source := aClass sourceCodeAt: sel ifAbsent:[nil]]
  ifFalse: [source := aClass class sourceCodeAt: sel ifAbsent:[nil]].
  ].
  source ifNil:[
  Transcript cr; show: 'WARNING: Compiled primitive ', classAndSelector first, '>>', classAndSelector last, ' not present'.
  ] ifNotNil:[
  "compile the method source and convert to a suitable translation
  method "
  meth := (Compiler new
  parse: source
  in: aClass
  notifying: nil)
  asTranslationMethodOfClass: self translationMethodClass.
 
  (aClass includesSelector: sel)
  ifTrue: [meth definingClass: aClass]
  ifFalse: [meth definingClass: aClass class].
  meth primitive > 0 ifTrue:[meth preparePrimitiveName].
  "for old-style array accessing:
  meth covertToZeroBasedArrayReferences."
  meth replaceSizeMessages.
  self addMethod: meth.
  ].
  ].
  "method preparation"
  verbose := false.
  self prepareMethods.
  verbose
  ifTrue:
  [self printUnboundCallWarnings.
  self printUnboundVariableReferenceWarnings.
  Transcript cr].
 
  "code generation"
+ "self doInlining: false"
- self doInlining: false.
 
+ primInstVars := Set new. "inst vars used in primitives"
+ sharedInstVars := Set new. "inst vars used in non-primitives"
+ assignedInstVars :=  Set new. "inst vars modified in non-primitives"
  methods do:[:m|
+ m primitive > 0 ifTrue: [
+ primInstVars addAll: m freeVariableReferences.
+ ] ifFalse: [
+ sharedInstVars addAll: m freeVariableReferences.
+ assignedInstVars addAll: m variablesAssignedTo.
+ ].
+ ].
+ methods do:[:m|
  "if this method is supposed to be a primitive (rather than a helper
  routine), add assorted prolog and epilog items"
+ m primitive > 0 ifTrue: [
+ m preparePrimitivePrologueShared: sharedInstVars assigned: assignedInstVars ].
- m primitive > 0 ifTrue: [m preparePrimitivePrologue].
  "check for one-based array access"
  m oneBasedArrays ifNotNil: [self oneBasedArrays: true].
+ ].
+ "Add declarations for inst vars used in both prims and non-prims as global"
+ ((primInstVars intersection: sharedInstVars) difference: variables) do: [:var |
+ methods do:[:m|
+ m declarations at: var ifPresent: [:decl |
+ variableDeclarations at: var
+ ifPresent: [:existing |
+ decl = existing ifFalse: [self error: 'decls do not match']]
+ ifAbsent: [variableDeclarations at: var put: decl]]].
+ variables add: var].
+ "Add non-shared inst vars as local"
+ methods do:[:m|
+ m locals addAll: (m freeVariableReferences difference: sharedInstVars)].
+ !
- ].!

Item was changed:
  ----- Method: JSMethod>>freeVariableReferences (in category 'utilities') -----
  freeVariableReferences
  "Answer a collection of variables referenced this method, excluding locals, arguments, and pseudovariables."
 
  | refs |
  refs := Set new.
  parseTree nodesDo: [ :node |
  node isVariable ifTrue: [ refs add: node name asString ].
  ].
  args do: [ :var | refs remove: var asString ifAbsent: [] ].
  locals do: [ :var | refs remove: var asString ifAbsent: [] ].
+ #('self' 'nil' 'true' 'false' 'null') do: [ :var | refs remove: var ifAbsent: [] ].
- #('self' 'nil' 'true' 'false') do: [ :var | refs remove: var ifAbsent: [] ].
  ^ refs asSortedCollection!

Item was removed:
- ----- Method: JSMethod>>preparePrimitivePrologue (in category 'primitive compilation') -----
- preparePrimitivePrologue
- "Add a prolog and postlog to a primitive method. The prolog copies any instance variables referenced by this primitive method into local variables. The postlog copies values of assigned-to variables back into the instance. The names of the new locals are added to the local variables list.
-
- The declarations dictionary defines the types of any non-integer variables (locals, arguments, or instance variables). In particular, it may specify the types:
-
- int * -- an array of 32-bit values (e.g., a BitMap)
- short * -- an array of 16-bit values (e.g., a SoundBuffer)
- char * -- an array of unsigned bytes (e.g., a String)
- double -- a double precision floating point number (e.g., 3.14159)
-
- Undeclared variables are taken to be integers and will be converted from Smalltalk to C ints."
-
- "Current restrictions:
- o method must not contain message sends
- o method must not allocate objects
- o method must not manipulate raw oops
- o method cannot access class variables
- o method can only return an integer"
-
- | prolog postlog instVarsUsed varsAssignedTo instVarList primArgCount varName endsWithReturn aClass |
- selector == #setInterpreter: ifTrue:[self halt].
- aClass := definingClass.
- prolog := OrderedCollection new.
- postlog := OrderedCollection new.
- instVarsUsed := self freeVariableReferences asSet.
- varsAssignedTo := self variablesAssignedTo asSet.
- instVarList := aClass allInstVarNames.
- primArgCount := args size.
-
- "add receiver fetch and arg conversions to prolog"
- prolog addAll: self fetchRcvrExpr.
- 1 to: args size do: [:argIndex |
- varName := args at: argIndex.
- prolog addAll:
- (self argConversionExprFor: varName stackIndex: args size - argIndex)].
-
- "add success check to postlog"
- postlog addAll: self checkSuccessExpr.
-
- "add instance variable fetches to prolog and instance variable stores to postlog"
- 1 to: instVarList size do: [:varIndex |
- varName := instVarList at: varIndex.
- (instVarsUsed includes: varName) ifTrue: [
- locals add: varName.
- prolog addAll: (self instVarGetExprFor: varName offset: varIndex - 1).
- (varsAssignedTo includes: varName) ifTrue: [
- postlog addAll: (self instVarPutExprFor: varName offset: varIndex - 1)]]].
- prolog addAll: self checkSuccessExpr.
-
- locals addAllFirst: args.
- locals addFirst: 'rcvr'.
- args := args class new.
- locals asSet size = locals size
- ifFalse: [self error: 'local name conflicts with instance variable name'].
- endsWithReturn := self endsWithReturn.
- self fixUpReturns: primArgCount postlog: postlog.
-
- endsWithReturn
- ifTrue: [parseTree setStatements: prolog, parseTree statements]
- ifFalse: [
- postlog addAll: (self popArgsExpr: primArgCount).
- parseTree setStatements: prolog, parseTree statements, postlog].
- !

Item was added:
+ ----- Method: JSMethod>>preparePrimitivePrologueShared:assigned: (in category 'primitive compilation') -----
+ preparePrimitivePrologueShared: sharedInstVars assigned: assignedInstVars
+ "Add a prolog and postlog to a primitive method. The prolog copies any instance variables referenced by this primitive method into local variables. The postlog copies values of assigned-to variables back into the instance. The names of the new locals are added to the local variables list.
+
+ The declarations dictionary defines the types of any non-integer variables (locals, arguments, or instance variables). In particular, it may specify the types:
+
+ int * -- an array of 32-bit values (e.g., a BitMap)
+ short * -- an array of 16-bit values (e.g., a SoundBuffer)
+ char * -- an array of unsigned bytes (e.g., a String)
+ double -- a double precision floating point number (e.g., 3.14159)
+
+ Undeclared variables are taken to be integers and will be converted from Smalltalk to C ints."
+
+ "Current restrictions:
+ o method must not contain message sends
+ o method must not allocate objects
+ o method must not manipulate raw oops
+ o method cannot access class variables
+ o method can only return an integer"
+
+ | prolog postlog instVarsUsed varsAssignedTo instVarList primArgCount varName endsWithReturn aClass |
+ selector == #setInterpreter: ifTrue:[self halt].
+ aClass := definingClass.
+ prolog := OrderedCollection new.
+ postlog := OrderedCollection new.
+ instVarsUsed := self freeVariableReferences asSet union: sharedInstVars.
+ varsAssignedTo := self variablesAssignedTo asSet union: assignedInstVars.
+ instVarList := aClass allInstVarNames.
+ primArgCount := args size.
+
+ "add receiver fetch and arg conversions to prolog"
+ prolog addAll: self fetchRcvrExpr.
+ 1 to: args size do: [:argIndex |
+ varName := args at: argIndex.
+ prolog addAll:
+ (self argConversionExprFor: varName stackIndex: args size - argIndex)].
+
+ "add success check to postlog"
+ postlog addAll: self checkSuccessExpr.
+
+ "add instance variable fetches to prolog and instance variable stores to postlog"
+ 1 to: instVarList size do: [:varIndex |
+ varName := instVarList at: varIndex.
+ (instVarsUsed includes: varName) ifTrue: [
+ "locals add: varName. -- since we do not inline, we cannot declare these local since they migth be used by inlined methods"
+ prolog addAll: (self instVarGetExprFor: varName offset: varIndex - 1).
+ (varsAssignedTo includes: varName) ifTrue: [
+ postlog addAll: (self instVarPutExprFor: varName offset: varIndex - 1)]]].
+ prolog addAll: self checkSuccessExpr.
+
+ locals addAllFirst: args.
+ locals addFirst: 'rcvr'.
+ args := args class new.
+ locals asSet size = locals size
+ ifFalse: [self error: 'local name conflicts with instance variable name'].
+ endsWithReturn := self endsWithReturn.
+ self fixUpReturns: primArgCount postlog: postlog.
+
+ endsWithReturn
+ ifTrue: [parseTree setStatements: prolog, parseTree statements]
+ ifFalse: [
+ postlog addAll: (self popArgsExpr: primArgCount).
+ parseTree setStatements: prolog, parseTree statements, postlog].
+ !