@@ -297,90 +297,6 @@ struct PyModuleDef pythonmonkey =
297297
298298PyObject *SpiderMonkeyError = NULL ;
299299
300- // Implement the `setTimeout` global function
301- // https://developer.mozilla.org/en-US/docs/Web/API/setTimeout
302- // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout
303- static bool setTimeout (JSContext *cx, unsigned argc, JS::Value *vp) {
304- JS::CallArgs args = JS::CallArgsFromVp (argc, vp);
305-
306- // Ensure the first parameter is a function
307- // We don't support passing a `code` string to `setTimeout` (yet)
308- JS::HandleValue jobArgVal = args.get (0 );
309- bool jobArgIsFunction = jobArgVal.isObject () && js::IsFunctionObject (&jobArgVal.toObject ());
310- if (!jobArgIsFunction) {
311- JS_ReportErrorNumberASCII (cx, nullptr , nullptr , JSErrNum::JSMSG_NOT_FUNCTION, " The first parameter to setTimeout()" );
312- return false ;
313- }
314-
315- // Get the function to be executed
316- // FIXME (Tom Tang): memory leak, not free-ed
317- JS::RootedObject *thisv = new JS::RootedObject (cx, JS::GetNonCCWObjectGlobal (&args.callee ())); // HTML spec requires `thisArg` to be the global object
318- JS::RootedValue *jobArg = new JS::RootedValue (cx, jobArgVal);
319- // `setTimeout` allows passing additional arguments to the callback, as spec-ed
320- if (args.length () > 2 ) { // having additional arguments
321- // Wrap the job function into a bound function with the given additional arguments
322- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
323- JS::RootedVector<JS::Value> bindArgs (cx);
324- (void )bindArgs.append (JS::ObjectValue (**thisv)); /* * @todo XXXwg handle return value */
325- for (size_t j = 2 ; j < args.length (); j++) {
326- (void )bindArgs.append (args[j]); /* * @todo XXXwg handle return value */
327- }
328- JS::RootedObject jobArgObj = JS::RootedObject (cx, &jobArgVal.toObject ());
329- JS_CallFunctionName (cx, jobArgObj, " bind" , JS::HandleValueArray (bindArgs), jobArg); // jobArg = jobArg.bind(thisv, ...bindArgs)
330- }
331- // Convert to a Python function
332- PyObject *job = pyTypeFactory (cx, thisv, jobArg)->getPyObject ();
333-
334- // Get the delay time
335- // JS `setTimeout` takes milliseconds, but Python takes seconds
336- double delayMs = 0 ; // use value of 0 if the delay parameter is omitted
337- if (args.hasDefined (1 )) { JS::ToNumber (cx, args[1 ], &delayMs); } // implicitly do type coercion to a `number`
338- if (delayMs < 0 ) { delayMs = 0 ; } // as spec-ed
339- double delaySeconds = delayMs / 1000 ; // convert ms to s
340-
341- // Schedule job to the running Python event-loop
342- PyEventLoop loop = PyEventLoop::getRunningLoop ();
343- if (!loop.initialized ()) return false ;
344- PyEventLoop::AsyncHandle handle = loop.enqueueWithDelay (job, delaySeconds);
345-
346- // Return the `timeoutID` to use in `clearTimeout`
347- args.rval ().setDouble ((double )PyEventLoop::AsyncHandle::getUniqueId (std::move (handle)));
348-
349- return true ;
350- }
351-
352- // Implement the `clearTimeout` global function
353- // https://developer.mozilla.org/en-US/docs/Web/API/clearTimeout
354- // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-cleartimeout
355- static bool clearTimeout (JSContext *cx, unsigned argc, JS::Value *vp) {
356- using AsyncHandle = PyEventLoop::AsyncHandle;
357- JS::CallArgs args = JS::CallArgsFromVp (argc, vp);
358- JS::HandleValue timeoutIdArg = args.get (0 );
359-
360- args.rval ().setUndefined ();
361-
362- // silently does nothing when an invalid timeoutID is passed in
363- if (!timeoutIdArg.isInt32 ()) {
364- return true ;
365- }
366-
367- // Retrieve the AsyncHandle by `timeoutID`
368- int32_t timeoutID = timeoutIdArg.toInt32 ();
369- AsyncHandle *handle = AsyncHandle::fromId ((uint32_t )timeoutID);
370- if (!handle) return true ; // does nothing on invalid timeoutID
371-
372- // Cancel this job on Python event-loop
373- handle->cancel ();
374-
375- return true ;
376- }
377-
378- static JSFunctionSpec jsGlobalFunctions[] = {
379- JS_FN (" setTimeout" , setTimeout, /* nargs */ 2 , 0 ),
380- JS_FN (" clearTimeout" , clearTimeout, 1 , 0 ),
381- JS_FS_END
382- };
383-
384300PyMODINIT_FUNC PyInit_pythonmonkey (void )
385301{
386302 PyDateTime_IMPORT;
@@ -425,11 +341,6 @@ PyMODINIT_FUNC PyInit_pythonmonkey(void)
425341
426342 autoRealm = new JSAutoRealm (GLOBAL_CX, *global);
427343
428- if (!JS_DefineFunctions (GLOBAL_CX, *global, jsGlobalFunctions)) {
429- PyErr_SetString (SpiderMonkeyError, " Spidermonkey could not define global functions." );
430- return NULL ;
431- }
432-
433344 JS_SetGCCallback (GLOBAL_CX, handleSharedPythonMonkeyMemory, NULL );
434345
435346 // XXX: SpiderMonkey bug???
0 commit comments