denoland/deno_core

A question about code generating by `core/rebuild_async_stubs.js`

Hajime-san opened this issue · 2 comments

When I tried to locally implement an op function with 14 arguments in deno/ext, and the build failed due to the argument limit imposed by core/rebuild_async_stubs.js.
Looking at the contents of core/rebuild_async_stubs.js, it looks like the function is defined each time depending on the number of arguments.
Is there a reason why this can't be replaced by using rest parameters (...theArgs) as shown below?

function setUpAsyncStub(opName, originalOp) {
  const fn = function async_op(...theArgs) {
    const id = nextPromiseId;
    try {
      const maybeResult = originalOp(id, ...theArgs);
      if (maybeResult !== undefined) {
        return PromiseResolve(maybeResult);
      }
    } catch (err) {
      ErrorCaptureStackTrace(err, async_op);
      return PromiseReject(err);
    }
    if (isLeakTracingEnabled) {
      submitLeakTrace(id);
    }
    nextPromiseId = (id + 1) & 0xffffffff;
    return setPromise(id);
  };

  ObjectDefineProperty(fn, "name", {
    value: opName,
    configurable: false,
    writable: false,
  });
  return fn;
}

deno_core/core/00_infra.js

Lines 193 to 236 in 7258aa3

function setUpAsyncStub(opName, originalOp) {
let fn;
// The body of this switch statement can be generated using the script above.
switch (originalOp.length - 1) {
/* BEGIN TEMPLATE setUpAsyncStub */
/* DO NOT MODIFY: use rebuild_async_stubs.js to regenerate */
case 0:
fn = function async_op_0() {
const id = nextPromiseId;
try {
const maybeResult = originalOp(id);
if (maybeResult !== undefined) {
return PromiseResolve(maybeResult);
}
} catch (err) {
ErrorCaptureStackTrace(err, async_op_0);
return PromiseReject(err);
}
if (isLeakTracingEnabled) {
submitLeakTrace(id);
}
nextPromiseId = (id + 1) & 0xffffffff;
return setPromise(id);
};
break;
case 1:
fn = function async_op_1(a) {
const id = nextPromiseId;
try {
const maybeResult = originalOp(id, a);
if (maybeResult !== undefined) {
return PromiseResolve(maybeResult);
}
} catch (err) {
ErrorCaptureStackTrace(err, async_op_1);
return PromiseReject(err);
}
if (isLeakTracingEnabled) {
submitLeakTrace(id);
}
nextPromiseId = (id + 1) & 0xffffffff;
return setPromise(id);
};
break;

We benchmarked it and using rest argument was way slower.

As a side note: using 14 arguments might not be the best idea. Consider using and array to "group" some arguments together.

Thanks to you I have resolved my doubts!

Consider using and array to "group" some arguments together.

Good to hear. I will use it as a reference.👀