Kernel-Methods.st 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. Smalltalk current createPackage: 'Kernel-Methods' properties: #{}!
  2. Object subclass: #BlockClosure
  3. instanceVariableNames: ''
  4. package: 'Kernel-Methods'!
  5. !BlockClosure commentStamp!
  6. A BlockClosure is a lexical closure.
  7. The JavaScript representation is a function.
  8. A BlockClosure is evaluated with the `#value*` methods in the 'evaluating' protocol.!
  9. !BlockClosure methodsFor: 'accessing'!
  10. compiledSource
  11. <return self.toString()>
  12. !
  13. numArgs
  14. <return self.length>
  15. ! !
  16. !BlockClosure methodsFor: 'controlling'!
  17. whileFalse
  18. "inlined in the Compiler"
  19. self whileFalse: []
  20. !
  21. whileFalse: aBlock
  22. "inlined in the Compiler"
  23. <while(!!self()) {aBlock()}>
  24. !
  25. whileTrue
  26. "inlined in the Compiler"
  27. self whileTrue: []
  28. !
  29. whileTrue: aBlock
  30. "inlined in the Compiler"
  31. <while(self()) {aBlock()}>
  32. ! !
  33. !BlockClosure methodsFor: 'converting'!
  34. asCompiledMethod: aString
  35. <return smalltalk.method({selector:aString, fn:self});>
  36. ! !
  37. !BlockClosure methodsFor: 'error handling'!
  38. on: anErrorClass do: aBlock
  39. "All exceptions thrown in the Smalltalk stack are cought.
  40. Convert all JS exceptions to JavaScriptException instances."
  41. ^self try: self catch: [ :error | | smalltalkError |
  42. smalltalkError := Smalltalk current asSmalltalkException: error.
  43. (smalltalkError isKindOf: anErrorClass)
  44. ifTrue: [ aBlock value: smalltalkError ]
  45. ifFalse: [ smalltalkError signal ] ]
  46. ! !
  47. !BlockClosure methodsFor: 'evaluating'!
  48. applyTo: anObject arguments: aCollection
  49. <return self.apply(anObject, aCollection)>
  50. !
  51. ensure: aBlock
  52. <try{return self()}finally{aBlock._value()}>
  53. !
  54. new
  55. "Use the receiver as a JS constructor.
  56. *Do not* use this method to instanciate Smalltalk objects!!"
  57. <return new self()>
  58. !
  59. newValue: anObject
  60. "Use the receiver as a JS constructor.
  61. *Do not* use this method to instanciate Smalltalk objects!!"
  62. <return new self(anObject)>
  63. !
  64. newValue: anObject value: anObject2
  65. "Use the receiver as a JS constructor.
  66. *Do not* use this method to instanciate Smalltalk objects!!"
  67. <return new self(anObject, anObject2)>
  68. !
  69. newValue: anObject value: anObject2 value: anObject3
  70. "Use the receiver as a JS constructor.
  71. *Do not* use this method to instanciate Smalltalk objects!!"
  72. <return new self(anObject, anObject2,anObject3)>
  73. !
  74. timeToRun
  75. "Answer the number of milliseconds taken to execute this block."
  76. ^ Date millisecondsToRun: self
  77. !
  78. value
  79. "inlined in the Compiler"
  80. <return self();>
  81. !
  82. value: anArg
  83. "inlined in the Compiler"
  84. <return self(anArg);>
  85. !
  86. value: firstArg value: secondArg
  87. "inlined in the Compiler"
  88. <return self(firstArg, secondArg);>
  89. !
  90. value: firstArg value: secondArg value: thirdArg
  91. "inlined in the Compiler"
  92. <return self(firstArg, secondArg, thirdArg);>
  93. !
  94. valueWithPossibleArguments: aCollection
  95. <return self.apply(null, aCollection);>
  96. ! !
  97. !BlockClosure methodsFor: 'timeout/interval'!
  98. fork
  99. ForkPool default fork: self
  100. !
  101. valueWithInterval: aNumber
  102. <
  103. var interval = setInterval(self, aNumber);
  104. return smalltalk.Timeout._on_(interval);
  105. >
  106. !
  107. valueWithTimeout: aNumber
  108. <
  109. var timeout = setTimeout(self, aNumber);
  110. return smalltalk.Timeout._on_(timeout);
  111. >
  112. ! !
  113. Object subclass: #CompiledMethod
  114. instanceVariableNames: ''
  115. package: 'Kernel-Methods'!
  116. !CompiledMethod commentStamp!
  117. CompiledMethod hold the source and compiled code of a class method.
  118. You can get a CompiledMethod using `Behavior>>methodAt:`
  119. String methodAt: 'lines'
  120. and read the source code
  121. (String methodAt: 'lines') source
  122. See referenced classes:
  123. (String methodAt: 'lines') referencedClasses
  124. or messages sent from this method:
  125. (String methodAt: 'lines') messageSends!
  126. !CompiledMethod methodsFor: 'accessing'!
  127. arguments
  128. <return self.args || []>
  129. !
  130. category
  131. ^(self basicAt: 'category') ifNil: ['']
  132. !
  133. category: aString
  134. | oldCategory |
  135. oldCategory := self category.
  136. self basicAt: 'category' put: aString.
  137. self methodClass ifNotNil: [
  138. self methodClass organization addElement: aString.
  139. (self methodClass methods
  140. select: [ :each | each category = oldCategory ])
  141. ifEmpty: [ self methodClass organization removeElement: oldCategory ] ]
  142. !
  143. fn
  144. ^self basicAt: 'fn'
  145. !
  146. fn: aBlock
  147. self basicAt: 'fn' put: aBlock
  148. !
  149. messageSends
  150. ^self basicAt: 'messageSends'
  151. !
  152. methodClass
  153. ^self basicAt: 'methodClass'
  154. !
  155. protocol
  156. ^ self category
  157. !
  158. referencedClasses
  159. ^self basicAt: 'referencedClasses'
  160. !
  161. selector
  162. ^self basicAt: 'selector'
  163. !
  164. selector: aString
  165. self basicAt: 'selector' put: aString
  166. !
  167. source
  168. ^(self basicAt: 'source') ifNil: ['']
  169. !
  170. source: aString
  171. self basicAt: 'source' put: aString
  172. ! !
  173. Object subclass: #ForkPool
  174. instanceVariableNames: 'poolSize maxPoolSize queue worker'
  175. package: 'Kernel-Methods'!
  176. !ForkPool commentStamp!
  177. A ForkPool is responsible for handling forked blocks.
  178. The pool size sets the maximum concurrent forked blocks.
  179. The default instance is accessed with `ForkPool default`!
  180. !ForkPool methodsFor: 'accessing'!
  181. maxPoolSize
  182. ^ maxPoolSize ifNil: [ self defaultMaxPoolSize ]
  183. !
  184. maxPoolSize: anInteger
  185. maxPoolSize := anInteger
  186. ! !
  187. !ForkPool methodsFor: 'actions'!
  188. fork: aBlock
  189. poolSize < self maxPoolSize ifTrue: [ self addWorker ].
  190. queue back: aBlock
  191. ! !
  192. !ForkPool methodsFor: 'defaults'!
  193. defaultMaxPoolSize
  194. ^ self class defaultMaxPoolSize
  195. ! !
  196. !ForkPool methodsFor: 'initialization'!
  197. initialize
  198. super initialize.
  199. poolSize := 0.
  200. queue := Queue new.
  201. worker := self makeWorker
  202. !
  203. makeWorker
  204. | sentinel |
  205. sentinel := Object new.
  206. ^[ | block |
  207. poolSize := poolSize - 1.
  208. block := queue frontIfAbsent: [ sentinel ].
  209. block == sentinel ifFalse: [
  210. [ block value ] ensure: [ self addWorker ]]]
  211. ! !
  212. !ForkPool methodsFor: 'private'!
  213. addWorker
  214. worker valueWithTimeout: 0.
  215. poolSize := poolSize + 1
  216. ! !
  217. ForkPool class instanceVariableNames: 'default'!
  218. !ForkPool class methodsFor: 'accessing'!
  219. default
  220. ^default ifNil: [ default := self new ]
  221. !
  222. defaultMaxPoolSize
  223. ^100
  224. !
  225. resetDefault
  226. default := nil
  227. ! !
  228. Object subclass: #Message
  229. instanceVariableNames: 'selector arguments'
  230. package: 'Kernel-Methods'!
  231. !Message commentStamp!
  232. Generally, the system does not use instances of Message for efficiency reasons.
  233. However, when a message is not understood by its receiver, the interpreter will make up an instance of it in order to capture the information involved in an actual message transmission.
  234. This instance is sent it as an argument with the message `doesNotUnderstand:` to the receiver.
  235. See boot.js, `messageNotUnderstood` and its counterpart `Object>>doesNotUnderstand:`!
  236. !Message methodsFor: 'accessing'!
  237. arguments
  238. ^arguments
  239. !
  240. arguments: anArray
  241. arguments := anArray
  242. !
  243. selector
  244. ^selector
  245. !
  246. selector: aString
  247. selector := aString
  248. ! !
  249. !Message methodsFor: 'printing'!
  250. printString
  251. ^ String streamContents: [:aStream|
  252. aStream
  253. nextPutAll: super printString;
  254. nextPutAll: '(';
  255. nextPutAll: selector;
  256. nextPutAll: ')' ]
  257. !
  258. sendTo: anObject
  259. ^ anObject perform: self selector withArguments: self arguments
  260. ! !
  261. !Message class methodsFor: 'instance creation'!
  262. selector: aString arguments: anArray
  263. ^self new
  264. selector: aString;
  265. arguments: anArray;
  266. yourself
  267. ! !
  268. Object subclass: #MethodContext
  269. instanceVariableNames: ''
  270. package: 'Kernel-Methods'!
  271. !MethodContext commentStamp!
  272. MethodContext holds all the dynamic state associated with the execution of either a method activation resulting from a message send. That is used to build the call stack while debugging.
  273. MethodContext instances are JavaScript `SmalltalkMethodContext` objects defined in boot.js!
  274. !MethodContext methodsFor: 'accessing'!
  275. home
  276. <return self.methodContext || self.homeContext>
  277. !
  278. locals
  279. <return self.locals>
  280. !
  281. method
  282. ^self methodContext receiver class lookupSelector: self methodContext selector
  283. !
  284. methodContext
  285. self isBlockContext ifFalse: [ ^ self ].
  286. ^ self home
  287. !
  288. outerContext
  289. <return self.homeContext>
  290. !
  291. pc
  292. <return self.pc>
  293. !
  294. printString
  295. ^super printString, '(', self asString, ')'
  296. !
  297. receiver
  298. <return self.receiver>
  299. !
  300. selector
  301. <
  302. if(self.selector) {
  303. return smalltalk.convertSelector(self.selector);
  304. } else {
  305. return nil;
  306. }
  307. >
  308. !
  309. temps
  310. self deprecatedAPI.
  311. ^ self locals
  312. ! !
  313. !MethodContext methodsFor: 'converting'!
  314. asString
  315. ^self isBlockContext
  316. ifTrue: [ 'a block (in ', self methodContext receiver class printString, ')' ]
  317. ifFalse: [ self receiver class printString, ' >> ', self selector ]
  318. ! !
  319. !MethodContext methodsFor: 'testing'!
  320. isBlockContext
  321. "Block context do not have selectors."
  322. ^ self selector isNil
  323. ! !
  324. Object subclass: #NativeFunction
  325. instanceVariableNames: ''
  326. package: 'Kernel-Methods'!
  327. !NativeFunction commentStamp!
  328. NativeFunction is a wrapper around native functions, such as `WebSocket`.
  329. For 'normal' functions (whose constructor is the JavaScript `Function` object), use `BlockClosure`.
  330. See the class-side `instance creation` methods.
  331. Created instances will most probably be instance of `JSObjectProxy`.
  332. Usage example:
  333. | ws |
  334. ws := NativeFunction constructor: 'WebSocket' value: 'ws://localhost'.
  335. ws at: 'onopen' put: [ ws send: 'hey there from Amber' ]!
  336. !NativeFunction class methodsFor: 'instance creation'!
  337. constructor: aString
  338. <
  339. var native=eval(aString);
  340. return new native();
  341. >
  342. !
  343. constructor: aString value:anObject
  344. <
  345. var native=eval(aString);
  346. return new native(anObject);
  347. >
  348. !
  349. constructor: aString value:anObject value: anObject2
  350. <
  351. var native=eval(aString);
  352. return new native(anObject,anObject2);
  353. >
  354. !
  355. constructor: aString value:anObject value: anObject2 value:anObject3
  356. <
  357. var native=eval(aString);
  358. return new native(anObject,anObject2, anObject3);
  359. >
  360. ! !
  361. !NativeFunction class methodsFor: 'testing'!
  362. exists: aString
  363. <
  364. if(aString in window) {
  365. return true
  366. } else {
  367. return false
  368. }
  369. >
  370. ! !