Kernel-Methods.st 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. Smalltalk createPackage: 'Kernel-Methods'!
  2. Object subclass: #BlockClosure
  3. instanceVariableNames: '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. instanceVariableNames: '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. SystemAnnouncer current announce: (MethodMoved new
  200. method: self;
  201. oldProtocol: oldProtocol;
  202. yourself).
  203. self methodClass ifNotNil: [ :methodClass |
  204. methodClass organization addElement: aString.
  205. methodClass removeProtocolIfEmpty: oldProtocol ]
  206. !
  207. referencedClasses
  208. ^ referencedClasses
  209. !
  210. selector
  211. ^ selector
  212. !
  213. selector: aString
  214. selector := aString
  215. !
  216. source
  217. ^ source ifNil: [ '' ]
  218. !
  219. source: aString
  220. source := aString
  221. ! !
  222. !CompiledMethod methodsFor: 'browsing'!
  223. browse
  224. Finder findMethod: self
  225. ! !
  226. !CompiledMethod methodsFor: 'defaults'!
  227. defaultProtocol
  228. ^ 'as yet unclassified'
  229. ! !
  230. !CompiledMethod methodsFor: 'evaluating'!
  231. sendTo: anObject arguments: aCollection
  232. ^ self fn applyTo: anObject arguments: aCollection
  233. ! !
  234. !CompiledMethod methodsFor: 'testing'!
  235. isCompiledMethod
  236. ^ true
  237. !
  238. isOverridden
  239. self methodClass allSubclassesDo: [ :each |
  240. (each includesSelector: selector)
  241. ifTrue: [ ^ true ] ].
  242. ^ false
  243. !
  244. isOverride
  245. | superclass |
  246. superclass := self methodClass superclass.
  247. superclass ifNil: [ ^ false ].
  248. ^ (self methodClass superclass lookupSelector: self selector) notNil
  249. ! !
  250. Object subclass: #ForkPool
  251. instanceVariableNames: 'poolSize maxPoolSize queue worker'
  252. package: 'Kernel-Methods'!
  253. !ForkPool commentStamp!
  254. I am responsible for handling forked blocks.
  255. The pool size sets the maximum concurrent forked blocks.
  256. ## API
  257. The default instance is accessed with `#default`.
  258. The maximum concurrent forked blocks can be set with `#maxPoolSize:`.
  259. Forking is done via `BlockClosure >> #fork`!
  260. !ForkPool methodsFor: 'accessing'!
  261. maxPoolSize
  262. ^ maxPoolSize ifNil: [ self defaultMaxPoolSize ]
  263. !
  264. maxPoolSize: anInteger
  265. maxPoolSize := anInteger
  266. ! !
  267. !ForkPool methodsFor: 'actions'!
  268. fork: aBlock
  269. poolSize < self maxPoolSize ifTrue: [ self addWorker ].
  270. queue nextPut: aBlock
  271. ! !
  272. !ForkPool methodsFor: 'defaults'!
  273. defaultMaxPoolSize
  274. ^ self class defaultMaxPoolSize
  275. ! !
  276. !ForkPool methodsFor: 'initialization'!
  277. initialize
  278. super initialize.
  279. poolSize := 0.
  280. queue := Queue new.
  281. worker := self makeWorker
  282. !
  283. makeWorker
  284. | sentinel |
  285. sentinel := Object new.
  286. ^ [ | block |
  287. poolSize := poolSize - 1.
  288. block := queue nextIfAbsent: [ sentinel ].
  289. block == sentinel ifFalse: [
  290. [ block value ] ensure: [ self addWorker ] ]]
  291. ! !
  292. !ForkPool methodsFor: 'private'!
  293. addWorker
  294. worker valueWithTimeout: 0.
  295. poolSize := poolSize + 1
  296. ! !
  297. ForkPool class instanceVariableNames: 'default'!
  298. !ForkPool class methodsFor: 'accessing'!
  299. default
  300. ^ default ifNil: [ default := self new ]
  301. !
  302. defaultMaxPoolSize
  303. ^ 100
  304. !
  305. resetDefault
  306. default := nil
  307. ! !
  308. Object subclass: #Message
  309. instanceVariableNames: 'selector arguments'
  310. package: 'Kernel-Methods'!
  311. !Message commentStamp!
  312. In general, the system does not use instances of me for efficiency reasons.
  313. 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.
  314. This instance is sent it as an argument with the message `#doesNotUnderstand:` to the receiver.
  315. See boot.js, `messageNotUnderstood` and its counterpart `Object >> #doesNotUnderstand:`
  316. ## API
  317. Besides accessing methods, `#sendTo:` provides a convenient way to send a message to an object.!
  318. !Message methodsFor: 'accessing'!
  319. arguments
  320. ^ arguments
  321. !
  322. arguments: anArray
  323. arguments := anArray
  324. !
  325. selector
  326. ^ selector
  327. !
  328. selector: aString
  329. selector := aString
  330. ! !
  331. !Message methodsFor: 'actions'!
  332. sendTo: anObject
  333. ^ anObject perform: self selector withArguments: self arguments
  334. ! !
  335. !Message methodsFor: 'printing'!
  336. printOn: aStream
  337. super printOn: aStream.
  338. aStream
  339. nextPutAll: '(';
  340. nextPutAll: self selector;
  341. nextPutAll: ')'
  342. ! !
  343. !Message class methodsFor: 'dnu handling'!
  344. selector: aString arguments: anArray notUnderstoodBy: anObject
  345. "Creates the message and passes it to #doesNotUnderstand:.
  346. Used by kernel to handle MNU."
  347. ^ anObject doesNotUnderstand:
  348. (self selector: aString arguments: anArray)
  349. ! !
  350. !Message class methodsFor: 'instance creation'!
  351. selector: aString arguments: anArray
  352. ^ self new
  353. selector: aString;
  354. arguments: anArray;
  355. yourself
  356. ! !
  357. Object subclass: #MessageSend
  358. instanceVariableNames: 'receiver message'
  359. package: 'Kernel-Methods'!
  360. !MessageSend commentStamp!
  361. I encapsulate message sends to objects. Arguments can be either predefined or supplied when the message send is performed.
  362. ## API
  363. Use `#value` to perform a message send with its predefined arguments and `#value:*` if additonal arguments have to supplied.!
  364. !MessageSend methodsFor: 'accessing'!
  365. arguments
  366. ^ message arguments
  367. !
  368. arguments: aCollection
  369. message arguments: aCollection
  370. !
  371. receiver
  372. ^ receiver
  373. !
  374. receiver: anObject
  375. receiver := anObject
  376. !
  377. selector
  378. ^ message selector
  379. !
  380. selector: aString
  381. message selector: aString
  382. ! !
  383. !MessageSend methodsFor: 'evaluating'!
  384. value
  385. ^ message sendTo: self receiver
  386. !
  387. value: anObject
  388. ^ message
  389. arguments: { anObject };
  390. sendTo: self receiver
  391. !
  392. value: firstArgument value: secondArgument
  393. ^ message
  394. arguments: { firstArgument. secondArgument };
  395. sendTo: self receiver
  396. !
  397. value: firstArgument value: secondArgument value: thirdArgument
  398. ^ message
  399. arguments: { firstArgument. secondArgument. thirdArgument };
  400. sendTo: self receiver
  401. !
  402. valueWithPossibleArguments: aCollection
  403. self arguments: aCollection.
  404. ^ self value
  405. ! !
  406. !MessageSend methodsFor: 'initialization'!
  407. initialize
  408. super initialize.
  409. message := Message new
  410. ! !
  411. !MessageSend methodsFor: 'printing'!
  412. printOn: aStream
  413. super printOn: aStream.
  414. aStream
  415. nextPutAll: '(';
  416. nextPutAll: self receiver;
  417. nextPutAll: ' >> ';
  418. nextPutAll: self selector;
  419. nextPutAll: ')'
  420. ! !
  421. Object subclass: #MethodContext
  422. instanceVariableNames: 'receiver evaluatedSelector homeContext index locals outerContext selector sendIdx supercall'
  423. package: 'Kernel-Methods'!
  424. !MethodContext commentStamp!
  425. 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.
  426. My instances are JavaScript `SmalltalkMethodContext` objects defined in `boot.js`.!
  427. !MethodContext methodsFor: 'accessing'!
  428. basicReceiver
  429. ^ receiver
  430. !
  431. evaluatedSelector
  432. ^ evaluatedSelector
  433. !
  434. home
  435. ^ homeContext
  436. !
  437. index
  438. ^ index ifNil: [ 0 ]
  439. !
  440. locals
  441. ^ locals
  442. !
  443. outerContext
  444. ^ outerContext ifNil: [ self home ]
  445. !
  446. selector
  447. ^ selector ifNotNil: [ Smalltalk core js2st: selector ]
  448. !
  449. sendIndexes
  450. ^ sendIdx
  451. !
  452. stubHere
  453. homeContext := JSObjectProxy undefined
  454. !
  455. supercall
  456. ^ supercall = true
  457. ! !
  458. !MethodContext methodsFor: 'error handling'!
  459. stubToAtMost: anInteger
  460. | context |
  461. context := self.
  462. anInteger timesRepeat: [ context := context ifNotNil: [ context home ] ].
  463. context ifNotNil: [ context stubHere ]
  464. ! !
  465. Object subclass: #NativeFunction
  466. instanceVariableNames: ''
  467. package: 'Kernel-Methods'!
  468. !NativeFunction commentStamp!
  469. I am a wrapper around native functions, such as `WebSocket`.
  470. For 'normal' functions (whose constructor is the JavaScript `Function` object), use `BlockClosure`.
  471. ## API
  472. See the class-side `instance creation` methods for instance creation.
  473. Created instances will most probably be instance of `JSObjectProxy`.
  474. ## Usage example:
  475. | ws |
  476. ws := NativeFunction constructor: 'WebSocket' value: 'ws://localhost'.
  477. ws at: 'onopen' put: [ ws send: 'hey there from Amber' ]!
  478. !NativeFunction class methodsFor: 'function calling'!
  479. functionNamed: aString
  480. <inlineJS: '
  481. var nativeFunc=$globals.Platform._globals[aString];
  482. return nativeFunc();
  483. '>
  484. !
  485. functionNamed: aString value: anObject
  486. <inlineJS: '
  487. var nativeFunc=$globals.Platform._globals()[aString];
  488. return nativeFunc(anObject);
  489. '>
  490. !
  491. functionNamed: aString value: anObject value: anObject2
  492. <inlineJS: '
  493. var nativeFunc=$globals.Platform._globals()[aString];
  494. return nativeFunc(anObject,anObject2);
  495. '>
  496. !
  497. functionNamed: aString value: anObject value: anObject2 value: anObject3
  498. <inlineJS: '
  499. var nativeFunc=$globals.Platform._globals()[aString];
  500. return nativeFunc(anObject,anObject2, anObject3);
  501. '>
  502. !
  503. functionNamed: aString valueWithArgs: args
  504. <inlineJS: '
  505. var nativeFunc=$globals.Platform._globals()[aString];
  506. return Function.prototype.apply.call(nativeFunc, null, args);
  507. '>
  508. !
  509. functionOf: nativeFunc
  510. <inlineJS: '
  511. return nativeFunc();
  512. '>
  513. !
  514. functionOf: nativeFunc value: anObject
  515. <inlineJS: '
  516. return nativeFunc(anObject);
  517. '>
  518. !
  519. functionOf: nativeFunc value: anObject value: anObject2
  520. <inlineJS: '
  521. return nativeFunc(anObject,anObject2);
  522. '>
  523. !
  524. functionOf: nativeFunc value: anObject value: anObject2 value: anObject3
  525. <inlineJS: '
  526. return nativeFunc(anObject,anObject2, anObject3);
  527. '>
  528. !
  529. functionOf: nativeFunc valueWithArgs: args
  530. <inlineJS: '
  531. return Function.prototype.apply.call(nativeFunc, null, args);
  532. '>
  533. ! !
  534. !NativeFunction class methodsFor: 'instance creation'!
  535. constructorNamed: aString
  536. <inlineJS: '
  537. var nativeFunc=$globals.Platform._globals()[aString];
  538. return new nativeFunc();
  539. '>
  540. !
  541. constructorNamed: aString value: anObject
  542. <inlineJS: '
  543. var nativeFunc=$globals.Platform._globals()[aString];
  544. return new nativeFunc(anObject);
  545. '>
  546. !
  547. constructorNamed: aString value: anObject value: anObject2
  548. <inlineJS: '
  549. var nativeFunc=$globals.Platform._globals[aString];
  550. return new nativeFunc(anObject,anObject2);
  551. '>
  552. !
  553. constructorNamed: aString value: anObject value: anObject2 value: anObject3
  554. <inlineJS: '
  555. var nativeFunc=$globals.Platform._globals[aString];
  556. return new nativeFunc(anObject,anObject2, anObject3);
  557. '>
  558. !
  559. constructorOf: nativeFunc
  560. <inlineJS: '
  561. return new nativeFunc();
  562. '>
  563. !
  564. constructorOf: nativeFunc value: anObject
  565. <inlineJS: '
  566. return new nativeFunc(anObject);
  567. '>
  568. !
  569. constructorOf: nativeFunc value: anObject value: anObject2
  570. <inlineJS: '
  571. return new nativeFunc(anObject,anObject2);
  572. '>
  573. !
  574. constructorOf: nativeFunc value: anObject value: anObject2 value: anObject3
  575. <inlineJS: '
  576. return new nativeFunc(anObject,anObject2, anObject3);
  577. '>
  578. ! !
  579. !NativeFunction class methodsFor: 'method calling'!
  580. methodOf: nativeFunc this: thisObject
  581. <inlineJS: '
  582. return Function.prototype.call.call(nativeFunc, thisObject);
  583. '>
  584. !
  585. methodOf: nativeFunc this: thisObject value: anObject
  586. <inlineJS: '
  587. return Function.prototype.call.call(nativeFunc, thisObject, anObject);
  588. '>
  589. !
  590. methodOf: nativeFunc this: thisObject value: anObject value: anObject2
  591. <inlineJS: '
  592. return Function.prototype.call.call(nativeFunc, thisObject,anObject,anObject2);
  593. '>
  594. !
  595. methodOf: nativeFunc this: thisObject value: anObject value: anObject2 value: anObject3
  596. <inlineJS: '
  597. return Function.prototype.call.call(nativeFunc, thisObject,anObject,anObject2, anObject3);
  598. '>
  599. !
  600. methodOf: nativeFunc this: thisObject valueWithArgs: args
  601. <inlineJS: '
  602. return Function.prototype.apply.call(nativeFunc, thisObject, args);
  603. '>
  604. ! !
  605. !NativeFunction class methodsFor: 'testing'!
  606. exists: aString
  607. ^ Platform includesGlobal: aString
  608. !
  609. isNativeFunction: anObject
  610. <inlineJS: 'return typeof anObject === "function"'>
  611. ! !
  612. Trait named: #TMethodContext
  613. package: 'Kernel-Methods'!
  614. !TMethodContext methodsFor: 'accessing'!
  615. basicReceiver
  616. self subclassResponsibility
  617. !
  618. findContextSuchThat: testBlock
  619. "Search self and my sender chain for first one that satisfies `testBlock`.
  620. Answer `nil` if none satisfy"
  621. | context |
  622. context := self.
  623. [ context isNil] whileFalse: [
  624. (testBlock value: context)
  625. ifTrue: [ ^ context ].
  626. context := context outerContext ].
  627. ^ nil
  628. !
  629. home
  630. self subclassResponsibility
  631. !
  632. index
  633. self subclassResponsibility
  634. !
  635. locals
  636. self subclassResponsibility
  637. !
  638. method
  639. | method lookupClass receiverClass supercall |
  640. self methodContext ifNil: [ ^ nil ].
  641. receiverClass := self methodContext receiver class.
  642. method := receiverClass lookupSelector: self methodContext selector.
  643. supercall := self outerContext
  644. ifNil: [ false ]
  645. ifNotNil: [ :outer | outer supercall ].
  646. ^ supercall
  647. ifFalse: [ method ]
  648. ifTrue: [ method methodClass superclass lookupSelector: self methodContext selector ]
  649. !
  650. methodContext
  651. self isBlockContext ifFalse: [ ^ self ].
  652. ^ self outerContext ifNotNil: [ :outer |
  653. outer methodContext ]
  654. !
  655. outerContext
  656. self subclassResponsibility
  657. !
  658. receiver
  659. ^ (self isBlockContext and: [ self outerContext notNil ])
  660. ifTrue: [ self outerContext receiver ]
  661. ifFalse: [ self basicReceiver ]
  662. !
  663. selector
  664. self subclassResponsibility
  665. !
  666. sendIndexes
  667. self subclassResponsibility
  668. !
  669. supercall
  670. self subclassResponsibility
  671. ! !
  672. !TMethodContext methodsFor: 'converting'!
  673. asString
  674. ^ self isBlockContext
  675. ifTrue: [ 'a block (in ', self methodContext asString, ')' ]
  676. ifFalse: [
  677. | methodClass |
  678. methodClass := self method methodClass.
  679. methodClass = self receiver class
  680. ifTrue: [ self receiver class name, ' >> ', self selector ]
  681. ifFalse: [ self receiver class name, '(', methodClass name, ') >> ', self selector ] ]
  682. ! !
  683. !TMethodContext methodsFor: 'printing'!
  684. printOn: aStream
  685. super printOn: aStream.
  686. aStream
  687. nextPutAll: '(';
  688. nextPutAll: self asString;
  689. nextPutAll: ')'
  690. ! !
  691. !TMethodContext methodsFor: 'testing'!
  692. isBlockContext
  693. "Block context do not have selectors."
  694. ^ self selector isNil
  695. ! !
  696. Object subclass: #Timeout
  697. instanceVariableNames: 'rawTimeout'
  698. package: 'Kernel-Methods'!
  699. !Timeout commentStamp!
  700. I am wrapping the returns from `set{Timeout,Interval}`.
  701. ## Motivation
  702. Number suffices in browsers, but node.js returns an object.!
  703. !Timeout methodsFor: 'accessing'!
  704. rawTimeout: anObject
  705. rawTimeout := anObject
  706. ! !
  707. !Timeout methodsFor: 'timeout/interval'!
  708. clearInterval
  709. <inlineJS: '
  710. var interval = $self.rawTimeout;
  711. clearInterval(interval);
  712. '>
  713. !
  714. clearTimeout
  715. <inlineJS: '
  716. var timeout = $self.rawTimeout;
  717. clearTimeout(timeout);
  718. '>
  719. ! !
  720. !Timeout class methodsFor: 'instance creation'!
  721. on: anObject
  722. ^ self new rawTimeout: anObject; yourself
  723. ! !
  724. MethodContext setTraitComposition: {TMethodContext} asTraitComposition!
  725. ! !