Kernel-Methods.st 20 KB

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