Kernel-Methods.st 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. Smalltalk createPackage: 'Kernel-Methods'!
  2. Object subclass: #BlockClosure
  3. slots: {#prototype. #length}
  4. package: 'Kernel-Methods'!
  5. !BlockClosure commentStamp!
  6. I represent a lexical closure.
  7. I am is directly mapped to JavaScript Function.
  8. ## API
  9. 1. Evaluation
  10. My instances get evaluated with the `#value*` methods in the 'evaluating' protocol.
  11. Example: ` [ :x | x + 1 ] value: 3 "Answers 4" `
  12. 2. Control structures
  13. Blocks are used (together with `Boolean`) for control structures (methods in the `controlling` protocol).
  14. Example: `aBlock whileTrue: [ ... ]`
  15. 3. Error handling
  16. I provide the `#on:do:` method for handling exceptions.
  17. Example: ` aBlock on: MessageNotUnderstood do: [ :ex | ... ] `!
  18. !BlockClosure methodsFor: 'accessing'!
  19. compiledSource
  20. <inlineJS: 'return self.toString()'>
  21. !
  22. numArgs
  23. ^ length
  24. !
  25. prototype
  26. ^ prototype
  27. !
  28. receiver
  29. ^ nil
  30. ! !
  31. !BlockClosure methodsFor: 'controlling'!
  32. whileFalse
  33. self whileFalse: []
  34. !
  35. whileFalse: aBlock
  36. <inlineJS: 'while(!!$core.assert($self._value())) {aBlock._value()}'>
  37. !
  38. whileTrue
  39. self whileTrue: []
  40. !
  41. whileTrue: aBlock
  42. <inlineJS: 'while($core.assert($self._value())) {aBlock._value()}'>
  43. ! !
  44. !BlockClosure methodsFor: 'converting'!
  45. asCompiledMethod: aString
  46. <inlineJS: 'return $core.method({selector:aString, fn:self});'>
  47. !
  48. currySelf
  49. "Transforms [ :selfarg :x :y | stcode ] block
  50. which represents JS function (selfarg, x, y, ...) {jscode}
  51. into function (x, y, ...) {jscode} that takes selfarg from 'this'.
  52. IOW, it is usable as JS method and first arg takes the receiver."
  53. <inlineJS: '
  54. return function () {
  55. var args = [ this ];
  56. args.push.apply(args, arguments);
  57. return self.apply(null, args);
  58. }
  59. '>
  60. !
  61. provided
  62. "Returns JS proxy that allows to access 'static API', as in
  63. require provided resolve: ...
  64. or
  65. XMLHttpRequest provided DONE"
  66. ^ JSObjectProxy on: self
  67. ! !
  68. !BlockClosure methodsFor: 'error handling'!
  69. on: anErrorClass do: aBlock
  70. "All exceptions thrown in the Smalltalk stack are cought.
  71. Convert all JS exceptions to JavaScriptException instances."
  72. ^ self tryCatch: [ :error | | smalltalkError |
  73. smalltalkError := Smalltalk asSmalltalkException: error.
  74. (smalltalkError isKindOf: anErrorClass)
  75. ifTrue: [ aBlock value: smalltalkError ]
  76. ifFalse: [ smalltalkError pass ] ]
  77. !
  78. tryCatch: aBlock
  79. <inlineJS: '
  80. try {
  81. return $self._value();
  82. } catch(error) {
  83. // pass non-local returns undetected
  84. if (Array.isArray(error) && error.length === 1) throw error;
  85. return aBlock._value_(error);
  86. }
  87. '>
  88. ! !
  89. !BlockClosure methodsFor: 'evaluating'!
  90. applyTo: anObject arguments: aCollection
  91. <inlineJS: 'return self.apply(anObject, aCollection)'>
  92. !
  93. ensure: aBlock
  94. <inlineJS: 'try{return $self._value()}finally{aBlock._value()}'>
  95. !
  96. new
  97. "Use the receiver as a JS constructor.
  98. *Do not* use this method to instanciate Smalltalk objects!!"
  99. <inlineJS: 'return new self()'>
  100. !
  101. newValue: anObject
  102. ^ self newWithValues: { anObject }
  103. !
  104. newValue: anObject value: anObject2
  105. ^ self newWithValues: { anObject. anObject2 }.
  106. !
  107. newValue: anObject value: anObject2 value: anObject3
  108. ^ self newWithValues: { anObject. anObject2. anObject3 }.
  109. !
  110. newWithValues: aCollection
  111. "Simulates JS new operator by combination of Object.create and .apply"
  112. <inlineJS: '
  113. var object = Object.create(self.prototype);
  114. var result = self.apply(object, aCollection);
  115. return typeof result === "object" ? result : object;
  116. '>
  117. !
  118. timeToRun
  119. "Answer the number of milliseconds taken to execute this block."
  120. ^ Date millisecondsToRun: self
  121. !
  122. value
  123. <inlineJS: 'return self();'>
  124. !
  125. value: anArg
  126. <inlineJS: 'return self(anArg);'>
  127. !
  128. value: firstArg value: secondArg
  129. <inlineJS: 'return self(firstArg, secondArg);'>
  130. !
  131. value: firstArg value: secondArg value: thirdArg
  132. <inlineJS: 'return self(firstArg, secondArg, thirdArg);'>
  133. !
  134. valueWithPossibleArguments: aCollection
  135. <inlineJS: 'return self.apply(null, aCollection);'>
  136. ! !
  137. !BlockClosure methodsFor: 'timeout/interval'!
  138. fork
  139. ForkPool default fork: self
  140. !
  141. valueWithInterval: aNumber
  142. <inlineJS: '
  143. var interval = setInterval(self, aNumber);
  144. return $globals.Timeout._on_(interval);
  145. '>
  146. !
  147. valueWithTimeout: aNumber
  148. <inlineJS: '
  149. var timeout = setTimeout(self, aNumber);
  150. return $globals.Timeout._on_(timeout);
  151. '>
  152. ! !
  153. Object subclass: #CompiledMethod
  154. slots: {#args. #fn. #messageSends. #owner. #protocol. #referencedClasses. #selector. #source}
  155. package: 'Kernel-Methods'!
  156. !CompiledMethod commentStamp!
  157. I represent a class method of the system. I hold the source and compiled code of a class method.
  158. ## API
  159. My instances can be accessed using `Behavior >> #methodAt:`
  160. Object methodAt: 'asString'
  161. Source code access:
  162. (String methodAt: 'lines') source
  163. Referenced classes:
  164. (String methodAt: 'lines') referencedClasses
  165. Messages sent from an instance:
  166. (String methodAt: 'lines') messageSends!
  167. !CompiledMethod methodsFor: 'accessing'!
  168. arguments
  169. ^ args ifNil: [ #() ]
  170. !
  171. category
  172. ^ self protocol
  173. !
  174. fn
  175. ^ fn
  176. !
  177. fn: aBlock
  178. fn := aBlock
  179. !
  180. messageSends
  181. ^ messageSends
  182. !
  183. methodClass
  184. ^ owner
  185. !
  186. package
  187. "Answer the package the receiver belongs to:
  188. - if it is an extension method, answer the corresponding package
  189. - else answer the `methodClass` package"
  190. ^ self methodClass ifNotNil: [ :class | class packageOfProtocol: self protocol ]
  191. !
  192. protocol
  193. ^ protocol ifNil: [ self defaultProtocol ]
  194. !
  195. protocol: aString
  196. | oldProtocol |
  197. oldProtocol := self protocol.
  198. protocol := aString.
  199. oldProtocol ifNotNil: [
  200. SystemAnnouncer current announce: (MethodMoved new
  201. method: self;
  202. oldProtocol: oldProtocol;
  203. yourself) ].
  204. self methodClass ifNotNil: [ :methodClass |
  205. methodClass organization addElement: aString.
  206. methodClass removeProtocolIfEmpty: oldProtocol ]
  207. !
  208. referencedClasses
  209. ^ referencedClasses
  210. !
  211. selector
  212. ^ selector
  213. !
  214. selector: aString
  215. selector := aString
  216. !
  217. source
  218. ^ source ifNil: [ '' ]
  219. !
  220. source: aString
  221. source := aString
  222. ! !
  223. !CompiledMethod methodsFor: 'browsing'!
  224. browse
  225. Finder findMethod: self
  226. ! !
  227. !CompiledMethod methodsFor: 'defaults'!
  228. defaultProtocol
  229. ^ 'as yet unclassified'
  230. ! !
  231. !CompiledMethod methodsFor: 'evaluating'!
  232. sendTo: anObject arguments: aCollection
  233. ^ self fn applyTo: anObject arguments: aCollection
  234. ! !
  235. !CompiledMethod methodsFor: 'testing'!
  236. isCompiledMethod
  237. ^ true
  238. !
  239. isOverridden
  240. self methodClass allSubclassesDo: [ :each |
  241. (each includesSelector: selector)
  242. ifTrue: [ ^ true ] ].
  243. ^ false
  244. !
  245. isOverride
  246. | superclass |
  247. superclass := self methodClass superclass.
  248. superclass ifNil: [ ^ false ].
  249. ^ (self methodClass superclass lookupSelector: self selector) notNil
  250. ! !
  251. Object subclass: #ForkPool
  252. slots: {#poolSize. #maxPoolSize. #queue. #worker}
  253. package: 'Kernel-Methods'!
  254. !ForkPool commentStamp!
  255. I am responsible for handling forked blocks.
  256. The pool size sets the maximum concurrent forked blocks.
  257. ## API
  258. The default instance is accessed with `#default`.
  259. The maximum concurrent forked blocks can be set with `#maxPoolSize:`.
  260. Forking is done via `BlockClosure >> #fork`!
  261. !ForkPool methodsFor: 'accessing'!
  262. maxPoolSize
  263. ^ maxPoolSize ifNil: [ self defaultMaxPoolSize ]
  264. !
  265. maxPoolSize: anInteger
  266. maxPoolSize := anInteger
  267. ! !
  268. !ForkPool methodsFor: 'actions'!
  269. fork: aBlock
  270. poolSize < self maxPoolSize ifTrue: [ self addWorker ].
  271. queue nextPut: aBlock
  272. ! !
  273. !ForkPool methodsFor: 'defaults'!
  274. defaultMaxPoolSize
  275. ^ self class defaultMaxPoolSize
  276. ! !
  277. !ForkPool methodsFor: 'initialization'!
  278. initialize
  279. super initialize.
  280. poolSize := 0.
  281. queue := Queue new.
  282. worker := self makeWorker
  283. !
  284. makeWorker
  285. | sentinel |
  286. sentinel := Object new.
  287. ^ [ | block |
  288. poolSize := poolSize - 1.
  289. block := queue nextIfAbsent: [ sentinel ].
  290. block == sentinel ifFalse: [
  291. [ block value ] ensure: [ self addWorker ] ]]
  292. ! !
  293. !ForkPool methodsFor: 'private'!
  294. addWorker
  295. worker valueWithTimeout: 0.
  296. poolSize := poolSize + 1
  297. ! !
  298. ForkPool class slots: {#default}!
  299. !ForkPool class methodsFor: 'accessing'!
  300. default
  301. ^ default ifNil: [ default := self new ]
  302. !
  303. defaultMaxPoolSize
  304. ^ 100
  305. !
  306. resetDefault
  307. default := nil
  308. ! !
  309. Object subclass: #Message
  310. slots: {#selector. #arguments}
  311. package: 'Kernel-Methods'!
  312. !Message commentStamp!
  313. In general, the system does not use instances of me for efficiency reasons.
  314. 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.
  315. This instance is sent it as an argument with the message `#doesNotUnderstand:` to the receiver.
  316. See boot.js, `messageNotUnderstood` and its counterpart `Object >> #doesNotUnderstand:`
  317. ## API
  318. Besides accessing methods, `#sendTo:` provides a convenient way to send a message to an object.!
  319. !Message methodsFor: 'accessing'!
  320. arguments
  321. ^ arguments
  322. !
  323. arguments: anArray
  324. arguments := anArray
  325. !
  326. selector
  327. ^ selector
  328. !
  329. selector: aString
  330. selector := aString
  331. ! !
  332. !Message methodsFor: 'actions'!
  333. sendTo: anObject
  334. ^ anObject perform: self selector withArguments: self arguments
  335. ! !
  336. !Message methodsFor: 'printing'!
  337. printOn: aStream
  338. super printOn: aStream.
  339. aStream
  340. nextPutAll: '(';
  341. nextPutAll: self selector;
  342. nextPutAll: ')'
  343. ! !
  344. !Message class methodsFor: 'dnu handling'!
  345. selector: aString arguments: anArray notUnderstoodBy: anObject
  346. "Creates the message and passes it to #doesNotUnderstand:.
  347. Used by kernel to handle MNU."
  348. ^ anObject doesNotUnderstand:
  349. (self selector: aString arguments: anArray)
  350. ! !
  351. !Message class methodsFor: 'instance creation'!
  352. selector: aString arguments: anArray
  353. ^ self new
  354. selector: aString;
  355. arguments: anArray;
  356. yourself
  357. ! !
  358. Object subclass: #MessageSend
  359. slots: {#receiver. #message}
  360. package: 'Kernel-Methods'!
  361. !MessageSend commentStamp!
  362. I encapsulate message sends to objects. Arguments can be either predefined or supplied when the message send is performed.
  363. ## API
  364. Use `#value` to perform a message send with its predefined arguments and `#value:*` if additonal arguments have to supplied.!
  365. !MessageSend methodsFor: 'accessing'!
  366. arguments
  367. ^ message arguments
  368. !
  369. arguments: aCollection
  370. message arguments: aCollection
  371. !
  372. receiver
  373. ^ receiver
  374. !
  375. receiver: anObject
  376. receiver := anObject
  377. !
  378. selector
  379. ^ message selector
  380. !
  381. selector: aString
  382. message selector: aString
  383. ! !
  384. !MessageSend methodsFor: 'evaluating'!
  385. value
  386. ^ message sendTo: self receiver
  387. !
  388. value: anObject
  389. ^ message
  390. arguments: { anObject };
  391. sendTo: self receiver
  392. !
  393. value: firstArgument value: secondArgument
  394. ^ message
  395. arguments: { firstArgument. secondArgument };
  396. sendTo: self receiver
  397. !
  398. value: firstArgument value: secondArgument value: thirdArgument
  399. ^ message
  400. arguments: { firstArgument. secondArgument. thirdArgument };
  401. sendTo: self receiver
  402. !
  403. valueWithPossibleArguments: aCollection
  404. self arguments: aCollection.
  405. ^ self value
  406. ! !
  407. !MessageSend methodsFor: 'initialization'!
  408. initialize
  409. super initialize.
  410. message := Message new
  411. ! !
  412. !MessageSend methodsFor: 'printing'!
  413. printOn: aStream
  414. super printOn: aStream.
  415. aStream
  416. nextPutAll: '(';
  417. nextPutAll: self receiver;
  418. nextPutAll: ' >> ';
  419. nextPutAll: self selector;
  420. nextPutAll: ')'
  421. ! !
  422. Object subclass: #MethodContext
  423. slots: {#receiver. #evaluatedSelector. #homeContext. #index. #locals. #outerContext. #selector. #sendIdx. #supercall}
  424. package: 'Kernel-Methods'!
  425. !MethodContext commentStamp!
  426. I hold all the dynamic state associated with the execution of either a method activation resulting from a message send. I am used to build the call stack while debugging.
  427. My instances are JavaScript `SmalltalkMethodContext` objects defined in `boot.js`.!
  428. !MethodContext methodsFor: 'accessing'!
  429. basicReceiver
  430. ^ receiver
  431. !
  432. evaluatedSelector
  433. ^ evaluatedSelector
  434. !
  435. home
  436. ^ homeContext
  437. !
  438. index
  439. ^ index ifNil: [ 0 ]
  440. !
  441. locals
  442. ^ locals
  443. !
  444. outerContext
  445. ^ outerContext ifNil: [ self home ]
  446. !
  447. selector
  448. ^ selector ifNotNil: [ Smalltalk core js2st: selector ]
  449. !
  450. sendIndexes
  451. ^ sendIdx
  452. !
  453. stubHere
  454. homeContext := JSObjectProxy undefined
  455. !
  456. supercall
  457. ^ supercall = true
  458. ! !
  459. !MethodContext methodsFor: 'error handling'!
  460. stubToAtMost: anInteger
  461. | context |
  462. context := self.
  463. anInteger timesRepeat: [ context := context ifNotNil: [ context home ] ].
  464. context ifNotNil: [ context stubHere ]
  465. ! !
  466. Object subclass: #NativeFunction
  467. slots: {}
  468. package: 'Kernel-Methods'!
  469. !NativeFunction commentStamp!
  470. I am a wrapper around native functions, such as `WebSocket`.
  471. For 'normal' functions (whose constructor is the JavaScript `Function` object), use `BlockClosure`.
  472. ## API
  473. See the class-side `instance creation` methods for instance creation.
  474. Created instances will most probably be instance of `JSObjectProxy`.
  475. ## Usage example:
  476. | ws |
  477. ws := NativeFunction constructor: 'WebSocket' value: 'ws://localhost'.
  478. ws at: 'onopen' put: [ ws send: 'hey there from Amber' ]!
  479. !NativeFunction class methodsFor: 'function calling'!
  480. functionNamed: aString
  481. <inlineJS: '
  482. var nativeFunc=$globals.Platform._globals[aString];
  483. return nativeFunc();
  484. '>
  485. !
  486. functionNamed: aString value: anObject
  487. <inlineJS: '
  488. var nativeFunc=$globals.Platform._globals()[aString];
  489. return nativeFunc(anObject);
  490. '>
  491. !
  492. functionNamed: aString value: anObject value: anObject2
  493. <inlineJS: '
  494. var nativeFunc=$globals.Platform._globals()[aString];
  495. return nativeFunc(anObject,anObject2);
  496. '>
  497. !
  498. functionNamed: aString value: anObject value: anObject2 value: anObject3
  499. <inlineJS: '
  500. var nativeFunc=$globals.Platform._globals()[aString];
  501. return nativeFunc(anObject,anObject2, anObject3);
  502. '>
  503. !
  504. functionNamed: aString valueWithArgs: args
  505. <inlineJS: '
  506. var nativeFunc=$globals.Platform._globals()[aString];
  507. return Function.prototype.apply.call(nativeFunc, null, args);
  508. '>
  509. !
  510. functionOf: nativeFunc
  511. <inlineJS: '
  512. return nativeFunc();
  513. '>
  514. !
  515. functionOf: nativeFunc value: anObject
  516. <inlineJS: '
  517. return nativeFunc(anObject);
  518. '>
  519. !
  520. functionOf: nativeFunc value: anObject value: anObject2
  521. <inlineJS: '
  522. return nativeFunc(anObject,anObject2);
  523. '>
  524. !
  525. functionOf: nativeFunc value: anObject value: anObject2 value: anObject3
  526. <inlineJS: '
  527. return nativeFunc(anObject,anObject2, anObject3);
  528. '>
  529. !
  530. functionOf: nativeFunc valueWithArgs: args
  531. <inlineJS: '
  532. return Function.prototype.apply.call(nativeFunc, null, args);
  533. '>
  534. ! !
  535. !NativeFunction class methodsFor: 'instance creation'!
  536. constructorNamed: aString
  537. <inlineJS: '
  538. var nativeFunc=$globals.Platform._globals()[aString];
  539. return new nativeFunc();
  540. '>
  541. !
  542. constructorNamed: aString value: anObject
  543. <inlineJS: '
  544. var nativeFunc=$globals.Platform._globals()[aString];
  545. return new nativeFunc(anObject);
  546. '>
  547. !
  548. constructorNamed: aString value: anObject value: anObject2
  549. <inlineJS: '
  550. var nativeFunc=$globals.Platform._globals[aString];
  551. return new nativeFunc(anObject,anObject2);
  552. '>
  553. !
  554. constructorNamed: aString value: anObject value: anObject2 value: anObject3
  555. <inlineJS: '
  556. var nativeFunc=$globals.Platform._globals[aString];
  557. return new nativeFunc(anObject,anObject2, anObject3);
  558. '>
  559. !
  560. constructorOf: nativeFunc
  561. <inlineJS: '
  562. return new nativeFunc();
  563. '>
  564. !
  565. constructorOf: nativeFunc value: anObject
  566. <inlineJS: '
  567. return new nativeFunc(anObject);
  568. '>
  569. !
  570. constructorOf: nativeFunc value: anObject value: anObject2
  571. <inlineJS: '
  572. return new nativeFunc(anObject,anObject2);
  573. '>
  574. !
  575. constructorOf: nativeFunc value: anObject value: anObject2 value: anObject3
  576. <inlineJS: '
  577. return new nativeFunc(anObject,anObject2, anObject3);
  578. '>
  579. ! !
  580. !NativeFunction class methodsFor: 'method calling'!
  581. methodOf: nativeFunc this: thisObject
  582. <inlineJS: '
  583. return Function.prototype.call.call(nativeFunc, thisObject);
  584. '>
  585. !
  586. methodOf: nativeFunc this: thisObject value: anObject
  587. <inlineJS: '
  588. return Function.prototype.call.call(nativeFunc, thisObject, anObject);
  589. '>
  590. !
  591. methodOf: nativeFunc this: thisObject value: anObject value: anObject2
  592. <inlineJS: '
  593. return Function.prototype.call.call(nativeFunc, thisObject,anObject,anObject2);
  594. '>
  595. !
  596. methodOf: nativeFunc this: thisObject value: anObject value: anObject2 value: anObject3
  597. <inlineJS: '
  598. return Function.prototype.call.call(nativeFunc, thisObject,anObject,anObject2, anObject3);
  599. '>
  600. !
  601. methodOf: nativeFunc this: thisObject valueWithArgs: args
  602. <inlineJS: '
  603. return Function.prototype.apply.call(nativeFunc, thisObject, args);
  604. '>
  605. ! !
  606. !NativeFunction class methodsFor: 'testing'!
  607. exists: aString
  608. ^ Platform includesGlobal: aString
  609. !
  610. isNativeFunction: anObject
  611. <inlineJS: 'return typeof anObject === "function"'>
  612. ! !
  613. Trait named: #TMethodContext
  614. package: 'Kernel-Methods'!
  615. !TMethodContext methodsFor: 'accessing'!
  616. basicReceiver
  617. self subclassResponsibility
  618. !
  619. findContextSuchThat: testBlock
  620. "Search self and my sender chain for first one that satisfies `testBlock`.
  621. Answer `nil` if none satisfy"
  622. | context |
  623. context := self.
  624. [ context isNil] whileFalse: [
  625. (testBlock value: context)
  626. ifTrue: [ ^ context ].
  627. context := context outerContext ].
  628. ^ nil
  629. !
  630. home
  631. self subclassResponsibility
  632. !
  633. index
  634. self subclassResponsibility
  635. !
  636. locals
  637. self subclassResponsibility
  638. !
  639. method
  640. | method lookupClass receiverClass supercall |
  641. self methodContext ifNil: [ ^ nil ].
  642. receiverClass := self methodContext receiver class.
  643. method := receiverClass lookupSelector: self methodContext selector.
  644. supercall := self outerContext
  645. ifNil: [ false ]
  646. ifNotNil: [ :outer | outer supercall ].
  647. ^ supercall
  648. ifFalse: [ method ]
  649. ifTrue: [ method methodClass superclass lookupSelector: self methodContext selector ]
  650. !
  651. methodContext
  652. self isBlockContext ifFalse: [ ^ self ].
  653. ^ self outerContext ifNotNil: [ :outer |
  654. outer methodContext ]
  655. !
  656. outerContext
  657. self subclassResponsibility
  658. !
  659. receiver
  660. ^ (self isBlockContext and: [ self outerContext notNil ])
  661. ifTrue: [ self outerContext receiver ]
  662. ifFalse: [ self basicReceiver ]
  663. !
  664. selector
  665. self subclassResponsibility
  666. !
  667. sendIndexes
  668. self subclassResponsibility
  669. !
  670. supercall
  671. self subclassResponsibility
  672. ! !
  673. !TMethodContext methodsFor: 'converting'!
  674. asString
  675. ^ self isBlockContext
  676. ifTrue: [ 'a block (in ', self methodContext asString, ')' ]
  677. ifFalse: [
  678. | methodClass |
  679. methodClass := self method methodClass.
  680. methodClass = self receiver class
  681. ifTrue: [ self receiver class name, ' >> ', self selector ]
  682. ifFalse: [ self receiver class name, '(', methodClass name, ') >> ', self selector ] ]
  683. ! !
  684. !TMethodContext methodsFor: 'printing'!
  685. printOn: aStream
  686. super printOn: aStream.
  687. aStream
  688. nextPutAll: '(';
  689. nextPutAll: self asString;
  690. nextPutAll: ')'
  691. ! !
  692. !TMethodContext methodsFor: 'testing'!
  693. isBlockContext
  694. "Block context do not have selectors."
  695. ^ self selector isNil
  696. ! !
  697. Object subclass: #Timeout
  698. slots: {#rawTimeout}
  699. package: 'Kernel-Methods'!
  700. !Timeout commentStamp!
  701. I am wrapping the returns from `set{Timeout,Interval}`.
  702. ## Motivation
  703. Number suffices in browsers, but node.js returns an object.!
  704. !Timeout methodsFor: 'accessing'!
  705. rawTimeout: anObject
  706. rawTimeout := anObject
  707. ! !
  708. !Timeout methodsFor: 'timeout/interval'!
  709. clearInterval
  710. <inlineJS: '
  711. var interval = $self.rawTimeout;
  712. clearInterval(interval);
  713. '>
  714. !
  715. clearTimeout
  716. <inlineJS: '
  717. var timeout = $self.rawTimeout;
  718. clearTimeout(timeout);
  719. '>
  720. ! !
  721. !Timeout class methodsFor: 'instance creation'!
  722. on: anObject
  723. ^ self new rawTimeout: anObject; yourself
  724. ! !
  725. MethodContext setTraitComposition: {TMethodContext} asTraitComposition!
  726. ! !