Kernel-Methods.st 19 KB

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