Kernel-Methods.st 20 KB

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