1
0

Kernel-Methods.st 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  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. <return self.toString()>
  21. !
  22. numArgs
  23. <return self.length>
  24. !
  25. receiver
  26. ^ nil
  27. ! !
  28. !BlockClosure methodsFor: 'controlling'!
  29. whileFalse
  30. self whileFalse: []
  31. !
  32. whileFalse: aBlock
  33. <while(!!$core.assert(self._value())) {aBlock._value()}>
  34. !
  35. whileTrue
  36. self whileTrue: []
  37. !
  38. whileTrue: aBlock
  39. <while($core.assert(self._value())) {aBlock._value()}>
  40. ! !
  41. !BlockClosure methodsFor: 'converting'!
  42. asCompiledMethod: aString
  43. <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. <
  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. <
  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. <return self.apply(anObject, aCollection)>
  82. !
  83. ensure: aBlock
  84. <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. <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. <
  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. <return self();>
  114. !
  115. value: anArg
  116. <return self(anArg);>
  117. !
  118. value: firstArg value: secondArg
  119. <return self(firstArg, secondArg);>
  120. !
  121. value: firstArg value: secondArg value: thirdArg
  122. <return self(firstArg, secondArg, thirdArg);>
  123. !
  124. valueWithPossibleArguments: aCollection
  125. <return self.apply(null, aCollection);>
  126. ! !
  127. !BlockClosure methodsFor: 'timeout/interval'!
  128. fork
  129. ForkPool default fork: self
  130. !
  131. valueWithInterval: aNumber
  132. <
  133. var interval = setInterval(self, aNumber);
  134. return $globals.Timeout._on_(interval);
  135. >
  136. !
  137. valueWithTimeout: aNumber
  138. <
  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. <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. <return self.receiver>
  415. !
  416. evaluatedSelector
  417. <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. <return self.homeContext>
  432. !
  433. index
  434. <return self.index || 0>
  435. !
  436. locals
  437. <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. <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. <
  466. if(self.selector) {
  467. return $core.js2st(self.selector);
  468. } else {
  469. return nil;
  470. }
  471. >
  472. !
  473. sendIndexAt: aSelector
  474. <return self.sendIdx[aSelector] || 0>
  475. !
  476. sendIndexes
  477. <return self.sendIdx>
  478. !
  479. supercall
  480. <return self.supercall == true>
  481. ! !
  482. !MethodContext methodsFor: 'converting'!
  483. asString
  484. ^ self isBlockContext
  485. ifTrue: [ 'a block (in ', self methodContext asString, ')' ]
  486. ifFalse: [
  487. | methodClass |
  488. methodClass := self method methodClass.
  489. methodClass = self receiver class
  490. ifTrue: [ self receiver class name, ' >> ', self selector ]
  491. ifFalse: [ self receiver class name, '(', methodClass name, ') >> ', self selector ] ]
  492. ! !
  493. !MethodContext methodsFor: 'printing'!
  494. printOn: aStream
  495. super printOn: aStream.
  496. aStream
  497. nextPutAll: '(';
  498. nextPutAll: self asString;
  499. nextPutAll: ')'
  500. ! !
  501. !MethodContext methodsFor: 'testing'!
  502. isBlockContext
  503. "Block context do not have selectors."
  504. ^ self selector isNil
  505. ! !
  506. Object subclass: #NativeFunction
  507. instanceVariableNames: ''
  508. package: 'Kernel-Methods'!
  509. !NativeFunction commentStamp!
  510. I am a wrapper around native functions, such as `WebSocket`.
  511. For 'normal' functions (whose constructor is the JavaScript `Function` object), use `BlockClosure`.
  512. ## API
  513. See the class-side `instance creation` methods for instance creation.
  514. Created instances will most probably be instance of `JSObjectProxy`.
  515. ## Usage example:
  516. | ws |
  517. ws := NativeFunction constructor: 'WebSocket' value: 'ws://localhost'.
  518. ws at: 'onopen' put: [ ws send: 'hey there from Amber' ]!
  519. !NativeFunction class methodsFor: 'function calling'!
  520. functionNamed: aString
  521. <
  522. var nativeFunc=(new Function('return this'))()[aString];
  523. return nativeFunc();
  524. >
  525. !
  526. functionNamed: aString value: anObject
  527. <
  528. var nativeFunc=(new Function('return this'))()[aString];
  529. return nativeFunc(anObject);
  530. >
  531. !
  532. functionNamed: aString value: anObject value: anObject2
  533. <
  534. var nativeFunc=(new Function('return this'))()[aString];
  535. return nativeFunc(anObject,anObject2);
  536. >
  537. !
  538. functionNamed: aString value: anObject value: anObject2 value: anObject3
  539. <
  540. var nativeFunc=(new Function('return this'))()[aString];
  541. return nativeFunc(anObject,anObject2, anObject3);
  542. >
  543. !
  544. functionNamed: aString valueWithArgs: args
  545. <
  546. var nativeFunc=(new Function('return this'))()[aString];
  547. return Function.prototype.apply.call(nativeFunc, null, args);
  548. >
  549. !
  550. functionOf: nativeFunc
  551. <
  552. return nativeFunc();
  553. >
  554. !
  555. functionOf: nativeFunc value: anObject
  556. <
  557. return nativeFunc(anObject);
  558. >
  559. !
  560. functionOf: nativeFunc value: anObject value: anObject2
  561. <
  562. return nativeFunc(anObject,anObject2);
  563. >
  564. !
  565. functionOf: nativeFunc value: anObject value: anObject2 value: anObject3
  566. <
  567. return nativeFunc(anObject,anObject2, anObject3);
  568. >
  569. !
  570. functionOf: nativeFunc valueWithArgs: args
  571. <
  572. return Function.prototype.apply.call(nativeFunc, null, args);
  573. >
  574. ! !
  575. !NativeFunction class methodsFor: 'instance creation'!
  576. constructor: aString
  577. <
  578. self._deprecatedAPI_("Use constructorNamed:");
  579. var nativeFunc=eval(aString);
  580. return new nativeFunc();
  581. >
  582. !
  583. constructor: aString value:anObject
  584. <
  585. self._deprecatedAPI_("Use constructorNamed:value:");
  586. var nativeFunc=eval(aString);
  587. return new nativeFunc(anObject);
  588. >
  589. !
  590. constructor: aString value:anObject value: anObject2
  591. <
  592. self._deprecatedAPI_("Use constructorNamed:value:value:");
  593. var nativeFunc=eval(aString);
  594. return new nativeFunc(anObject,anObject2);
  595. >
  596. !
  597. constructor: aString value:anObject value: anObject2 value:anObject3
  598. <
  599. self._deprecatedAPI_("Use constructorNamed:value:value:value");
  600. var nativeFunc=eval(aString);
  601. return new nativeFunc(anObject,anObject2, anObject3);
  602. >
  603. !
  604. constructorNamed: aString
  605. <
  606. var nativeFunc=(new Function('return this'))()[aString];
  607. return new nativeFunc();
  608. >
  609. !
  610. constructorNamed: aString value: anObject
  611. <
  612. var nativeFunc=(new Function('return this'))()[aString];
  613. return new nativeFunc(anObject);
  614. >
  615. !
  616. constructorNamed: aString value: anObject value: anObject2
  617. <
  618. var nativeFunc=(new Function('return this'))()[aString];
  619. return new nativeFunc(anObject,anObject2);
  620. >
  621. !
  622. constructorNamed: aString value: anObject value: anObject2 value: anObject3
  623. <
  624. var nativeFunc=(new Function('return this'))()[aString];
  625. return new nativeFunc(anObject,anObject2, anObject3);
  626. >
  627. !
  628. constructorOf: nativeFunc
  629. <
  630. return new nativeFunc();
  631. >
  632. !
  633. constructorOf: nativeFunc value: anObject
  634. <
  635. return new nativeFunc(anObject);
  636. >
  637. !
  638. constructorOf: nativeFunc value: anObject value: anObject2
  639. <
  640. return new nativeFunc(anObject,anObject2);
  641. >
  642. !
  643. constructorOf: nativeFunc value: anObject value: anObject2 value: anObject3
  644. <
  645. return new nativeFunc(anObject,anObject2, anObject3);
  646. >
  647. ! !
  648. !NativeFunction class methodsFor: 'method calling'!
  649. methodOf: nativeFunc this: thisObject
  650. <
  651. return Function.prototype.call.call(nativeFunc, thisObject);
  652. >
  653. !
  654. methodOf: nativeFunc this: thisObject value: anObject
  655. <
  656. return Function.prototype.call.call(nativeFunc, thisObject, anObject);
  657. >
  658. !
  659. methodOf: nativeFunc this: thisObject value: anObject value: anObject2
  660. <
  661. return Function.prototype.call.call(nativeFunc, thisObject,anObject,anObject2);
  662. >
  663. !
  664. methodOf: nativeFunc this: thisObject value: anObject value: anObject2 value: anObject3
  665. <
  666. return Function.prototype.call.call(nativeFunc, thisObject,anObject,anObject2, anObject3);
  667. >
  668. !
  669. methodOf: nativeFunc this: thisObject valueWithArgs: args
  670. <
  671. return Function.prototype.apply.call(nativeFunc, thisObject, args);
  672. >
  673. ! !
  674. !NativeFunction class methodsFor: 'testing'!
  675. exists: aString
  676. ^ Smalltalk existsJsGlobal: aString
  677. ! !
  678. Object subclass: #Timeout
  679. instanceVariableNames: 'rawTimeout'
  680. package: 'Kernel-Methods'!
  681. !Timeout commentStamp!
  682. I am wrapping the returns from `set{Timeout,Interval}`.
  683. ## Motivation
  684. Number suffices in browsers, but node.js returns an object.!
  685. !Timeout methodsFor: 'accessing'!
  686. rawTimeout: anObject
  687. rawTimeout := anObject
  688. ! !
  689. !Timeout methodsFor: 'timeout/interval'!
  690. clearInterval
  691. <
  692. var interval = self["@rawTimeout"];
  693. clearInterval(interval);
  694. >
  695. !
  696. clearTimeout
  697. <
  698. var timeout = self["@rawTimeout"];
  699. clearTimeout(timeout);
  700. >
  701. ! !
  702. !Timeout class methodsFor: 'instance creation'!
  703. on: anObject
  704. ^ self new rawTimeout: anObject; yourself
  705. ! !