Kernel-Methods.st 20 KB

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