Kernel-Methods.st 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  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: 'dnu handling'!
  336. selector: aString arguments: anArray notUnderstoodBy: anObject
  337. "Creates the message and passes it to #doesNotUnderstand:.
  338. Used by kernel to handle MNU."
  339. ^ anObject doesNotUnderstand:
  340. (self selector: aString arguments: anArray)
  341. ! !
  342. !Message class methodsFor: 'instance creation'!
  343. selector: aString arguments: anArray
  344. ^ self new
  345. selector: aString;
  346. arguments: anArray;
  347. yourself
  348. ! !
  349. Object subclass: #MessageSend
  350. instanceVariableNames: 'receiver message'
  351. package: 'Kernel-Methods'!
  352. !MessageSend commentStamp!
  353. I encapsulate message sends to objects. Arguments can be either predefined or supplied when the message send is performed.
  354. ## API
  355. Use `#value` to perform a message send with its predefined arguments and `#value:*` if additonal arguments have to supplied.!
  356. !MessageSend methodsFor: 'accessing'!
  357. arguments
  358. ^ message arguments
  359. !
  360. arguments: aCollection
  361. message arguments: aCollection
  362. !
  363. receiver
  364. ^ receiver
  365. !
  366. receiver: anObject
  367. receiver := anObject
  368. !
  369. selector
  370. ^ message selector
  371. !
  372. selector: aString
  373. message selector: aString
  374. ! !
  375. !MessageSend methodsFor: 'evaluating'!
  376. value
  377. ^ message sendTo: self receiver
  378. !
  379. value: anObject
  380. ^ message
  381. arguments: { anObject };
  382. sendTo: self receiver
  383. !
  384. value: firstArgument value: secondArgument
  385. ^ message
  386. arguments: { firstArgument. secondArgument };
  387. sendTo: self receiver
  388. !
  389. value: firstArgument value: secondArgument value: thirdArgument
  390. ^ message
  391. arguments: { firstArgument. secondArgument. thirdArgument };
  392. sendTo: self receiver
  393. !
  394. valueWithPossibleArguments: aCollection
  395. self arguments: aCollection.
  396. ^ self value
  397. ! !
  398. !MessageSend methodsFor: 'initialization'!
  399. initialize
  400. super initialize.
  401. message := Message new
  402. ! !
  403. !MessageSend methodsFor: 'printing'!
  404. printOn: aStream
  405. super printOn: aStream.
  406. aStream
  407. nextPutAll: '(';
  408. nextPutAll: self receiver;
  409. nextPutAll: ' >> ';
  410. nextPutAll: self selector;
  411. nextPutAll: ')'
  412. ! !
  413. Object subclass: #MethodContext
  414. instanceVariableNames: ''
  415. package: 'Kernel-Methods'!
  416. !MethodContext commentStamp!
  417. 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.
  418. My instances are JavaScript `SmalltalkMethodContext` objects defined in `boot.js`.!
  419. !MethodContext methodsFor: 'accessing'!
  420. basicReceiver
  421. <inlineJS: 'return self.receiver'>
  422. !
  423. evaluatedSelector
  424. <inlineJS: 'return self.evaluatedSelector'>
  425. !
  426. findContextSuchThat: testBlock
  427. "Search self and my sender chain for first one that satisfies `testBlock`.
  428. Answer `nil` if none satisfy"
  429. | context |
  430. context := self.
  431. [ context isNil] whileFalse: [
  432. (testBlock value: context)
  433. ifTrue: [ ^ context ].
  434. context := context outerContext ].
  435. ^ nil
  436. !
  437. home
  438. <inlineJS: 'return self.homeContext'>
  439. !
  440. index
  441. <inlineJS: 'return self.index || 0'>
  442. !
  443. locals
  444. <inlineJS: 'return self.locals || {}'>
  445. !
  446. method
  447. | method lookupClass receiverClass supercall |
  448. self methodContext ifNil: [ ^ nil ].
  449. receiverClass := self methodContext receiver class.
  450. method := receiverClass lookupSelector: self methodContext selector.
  451. supercall := self outerContext
  452. ifNil: [ false ]
  453. ifNotNil: [ :outer | outer supercall ].
  454. ^ supercall
  455. ifFalse: [ method ]
  456. ifTrue: [ method methodClass superclass lookupSelector: self methodContext selector ]
  457. !
  458. methodContext
  459. self isBlockContext ifFalse: [ ^ self ].
  460. ^ self outerContext ifNotNil: [ :outer |
  461. outer methodContext ]
  462. !
  463. outerContext
  464. <inlineJS: 'return self.outerContext || self.homeContext'>
  465. !
  466. receiver
  467. ^ (self isBlockContext and: [ self outerContext notNil ])
  468. ifTrue: [ self outerContext receiver ]
  469. ifFalse: [ self basicReceiver ]
  470. !
  471. selector
  472. <inlineJS: '
  473. if(self.selector) {
  474. return $core.js2st(self.selector);
  475. } else {
  476. return nil;
  477. }
  478. '>
  479. !
  480. sendIndexAt: aSelector
  481. <inlineJS: 'return self.sendIdx[aSelector] || 0'>
  482. !
  483. sendIndexes
  484. <inlineJS: 'return self.sendIdx'>
  485. !
  486. stubHere
  487. <inlineJS: 'self.homeContext = undefined'>
  488. !
  489. supercall
  490. <inlineJS: 'return self.supercall == true'>
  491. ! !
  492. !MethodContext methodsFor: 'converting'!
  493. asString
  494. ^ self isBlockContext
  495. ifTrue: [ 'a block (in ', self methodContext asString, ')' ]
  496. ifFalse: [
  497. | methodClass |
  498. methodClass := self method methodClass.
  499. methodClass = self receiver class
  500. ifTrue: [ self receiver class name, ' >> ', self selector ]
  501. ifFalse: [ self receiver class name, '(', methodClass name, ') >> ', self selector ] ]
  502. ! !
  503. !MethodContext methodsFor: 'error handling'!
  504. stubToAtMost: anInteger
  505. | context |
  506. context := self.
  507. anInteger timesRepeat: [ context := context ifNotNil: [ context home ] ].
  508. context ifNotNil: [ context stubHere ]
  509. ! !
  510. !MethodContext methodsFor: 'printing'!
  511. printOn: aStream
  512. super printOn: aStream.
  513. aStream
  514. nextPutAll: '(';
  515. nextPutAll: self asString;
  516. nextPutAll: ')'
  517. ! !
  518. !MethodContext methodsFor: 'testing'!
  519. isBlockContext
  520. "Block context do not have selectors."
  521. ^ self selector isNil
  522. ! !
  523. Object subclass: #NativeFunction
  524. instanceVariableNames: ''
  525. package: 'Kernel-Methods'!
  526. !NativeFunction commentStamp!
  527. I am a wrapper around native functions, such as `WebSocket`.
  528. For 'normal' functions (whose constructor is the JavaScript `Function` object), use `BlockClosure`.
  529. ## API
  530. See the class-side `instance creation` methods for instance creation.
  531. Created instances will most probably be instance of `JSObjectProxy`.
  532. ## Usage example:
  533. | ws |
  534. ws := NativeFunction constructor: 'WebSocket' value: 'ws://localhost'.
  535. ws at: 'onopen' put: [ ws send: 'hey there from Amber' ]!
  536. !NativeFunction class methodsFor: 'function calling'!
  537. functionNamed: aString
  538. <inlineJS: '
  539. var nativeFunc=(new Function(''return this''))()[aString];
  540. return nativeFunc();
  541. '>
  542. !
  543. functionNamed: aString value: anObject
  544. <inlineJS: '
  545. var nativeFunc=(new Function(''return this''))()[aString];
  546. return nativeFunc(anObject);
  547. '>
  548. !
  549. functionNamed: aString value: anObject value: anObject2
  550. <inlineJS: '
  551. var nativeFunc=(new Function(''return this''))()[aString];
  552. return nativeFunc(anObject,anObject2);
  553. '>
  554. !
  555. functionNamed: aString value: anObject value: anObject2 value: anObject3
  556. <inlineJS: '
  557. var nativeFunc=(new Function(''return this''))()[aString];
  558. return nativeFunc(anObject,anObject2, anObject3);
  559. '>
  560. !
  561. functionNamed: aString valueWithArgs: args
  562. <inlineJS: '
  563. var nativeFunc=(new Function(''return this''))()[aString];
  564. return Function.prototype.apply.call(nativeFunc, null, args);
  565. '>
  566. !
  567. functionOf: nativeFunc
  568. <inlineJS: '
  569. return nativeFunc();
  570. '>
  571. !
  572. functionOf: nativeFunc value: anObject
  573. <inlineJS: '
  574. return nativeFunc(anObject);
  575. '>
  576. !
  577. functionOf: nativeFunc value: anObject value: anObject2
  578. <inlineJS: '
  579. return nativeFunc(anObject,anObject2);
  580. '>
  581. !
  582. functionOf: nativeFunc value: anObject value: anObject2 value: anObject3
  583. <inlineJS: '
  584. return nativeFunc(anObject,anObject2, anObject3);
  585. '>
  586. !
  587. functionOf: nativeFunc valueWithArgs: args
  588. <inlineJS: '
  589. return Function.prototype.apply.call(nativeFunc, null, args);
  590. '>
  591. ! !
  592. !NativeFunction class methodsFor: 'instance creation'!
  593. constructorNamed: aString
  594. <inlineJS: '
  595. var nativeFunc=(new Function(''return this''))()[aString];
  596. return new nativeFunc();
  597. '>
  598. !
  599. constructorNamed: aString value: anObject
  600. <inlineJS: '
  601. var nativeFunc=(new Function(''return this''))()[aString];
  602. return new nativeFunc(anObject);
  603. '>
  604. !
  605. constructorNamed: aString value: anObject value: anObject2
  606. <inlineJS: '
  607. var nativeFunc=(new Function(''return this''))()[aString];
  608. return new nativeFunc(anObject,anObject2);
  609. '>
  610. !
  611. constructorNamed: aString value: anObject value: anObject2 value: anObject3
  612. <inlineJS: '
  613. var nativeFunc=(new Function(''return this''))()[aString];
  614. return new nativeFunc(anObject,anObject2, anObject3);
  615. '>
  616. !
  617. constructorOf: nativeFunc
  618. <inlineJS: '
  619. return new nativeFunc();
  620. '>
  621. !
  622. constructorOf: nativeFunc value: anObject
  623. <inlineJS: '
  624. return new nativeFunc(anObject);
  625. '>
  626. !
  627. constructorOf: nativeFunc value: anObject value: anObject2
  628. <inlineJS: '
  629. return new nativeFunc(anObject,anObject2);
  630. '>
  631. !
  632. constructorOf: nativeFunc value: anObject value: anObject2 value: anObject3
  633. <inlineJS: '
  634. return new nativeFunc(anObject,anObject2, anObject3);
  635. '>
  636. ! !
  637. !NativeFunction class methodsFor: 'method calling'!
  638. methodOf: nativeFunc this: thisObject
  639. <inlineJS: '
  640. return Function.prototype.call.call(nativeFunc, thisObject);
  641. '>
  642. !
  643. methodOf: nativeFunc this: thisObject value: anObject
  644. <inlineJS: '
  645. return Function.prototype.call.call(nativeFunc, thisObject, anObject);
  646. '>
  647. !
  648. methodOf: nativeFunc this: thisObject value: anObject value: anObject2
  649. <inlineJS: '
  650. return Function.prototype.call.call(nativeFunc, thisObject,anObject,anObject2);
  651. '>
  652. !
  653. methodOf: nativeFunc this: thisObject value: anObject value: anObject2 value: anObject3
  654. <inlineJS: '
  655. return Function.prototype.call.call(nativeFunc, thisObject,anObject,anObject2, anObject3);
  656. '>
  657. !
  658. methodOf: nativeFunc this: thisObject valueWithArgs: args
  659. <inlineJS: '
  660. return Function.prototype.apply.call(nativeFunc, thisObject, args);
  661. '>
  662. ! !
  663. !NativeFunction class methodsFor: 'testing'!
  664. exists: aString
  665. ^ Smalltalk existsJsGlobal: aString
  666. !
  667. isNativeFunction: anObject
  668. <inlineJS: 'return typeof anObject === "function"'>
  669. ! !
  670. Object subclass: #Timeout
  671. instanceVariableNames: 'rawTimeout'
  672. package: 'Kernel-Methods'!
  673. !Timeout commentStamp!
  674. I am wrapping the returns from `set{Timeout,Interval}`.
  675. ## Motivation
  676. Number suffices in browsers, but node.js returns an object.!
  677. !Timeout methodsFor: 'accessing'!
  678. rawTimeout: anObject
  679. rawTimeout := anObject
  680. ! !
  681. !Timeout methodsFor: 'timeout/interval'!
  682. clearInterval
  683. <inlineJS: '
  684. var interval = $self["@rawTimeout"];
  685. clearInterval(interval);
  686. '>
  687. !
  688. clearTimeout
  689. <inlineJS: '
  690. var timeout = $self["@rawTimeout"];
  691. clearTimeout(timeout);
  692. '>
  693. ! !
  694. !Timeout class methodsFor: 'instance creation'!
  695. on: anObject
  696. ^ self new rawTimeout: anObject; yourself
  697. ! !