Kernel-Methods.st 9.8 KB

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