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