Kernel-Methods.st 12 KB

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