Kernel-Methods.st 19 KB

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