Kernel-Methods.st 20 KB

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