Kernel-Methods.st 10 KB

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