Kernel-Methods.st 11 KB

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