Kernel-Methods.st 20 KB

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