Kernel-Methods.st 20 KB

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