Kernel-Methods.st 20 KB

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