Kernel-Methods.st 20 KB

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