Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ rstest = "0"
serde = { version = "1", features = ["derive"] }
serde_bytes = "0.11"
serde_json = "1"
slab = "0.4.10"
smallvec = "1.14"
sourcemap = "9.1.2"
static_assertions = "1"
Expand Down
312 changes: 0 additions & 312 deletions core/00_infra.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,6 @@
URIError,
} = window.__bootstrap.primordials;

let nextPromiseId = 0;
const promiseMap = new SafeMap();
const RING_SIZE = 4 * 1024;
const NO_PROMISE = null; // Alias to null is faster than plain nulls
const promiseRing = ArrayPrototypeFill(new Array(RING_SIZE), NO_PROMISE);
// TODO(bartlomieju): in the future use `v8::Private` so it's not visible
// to users. Currently missing bindings.
const promiseIdSymbol = SymbolFor("Deno.core.internalPromiseId");

let isLeakTracingEnabled = false;
let submitLeakTrace;
let eventLoopTick;
Expand Down Expand Up @@ -129,319 +120,16 @@
errorMap[className] = errorBuilder;
}

function setPromise(promiseId) {
const idx = promiseId % RING_SIZE;
// Move old promise from ring to map
const oldPromise = promiseRing[idx];
if (oldPromise !== NO_PROMISE) {
const oldPromiseId = promiseId - RING_SIZE;
MapPrototypeSet(promiseMap, oldPromiseId, oldPromise);
}

const promise = new Promise((resolve, reject) => {
promiseRing[idx] = [resolve, reject];
});
const wrappedPromise = PromisePrototypeCatch(
promise,
(res) => {
// recreate the stacktrace and strip eventLoopTick() calls from stack trace
ErrorCaptureStackTrace(res, eventLoopTick);
throw res;
},
);
wrappedPromise[promiseIdSymbol] = promiseId;
return wrappedPromise;
}

function __resolvePromise(promiseId, res, isOk) {
// Check if out of ring bounds, fallback to map
const outOfBounds = promiseId < nextPromiseId - RING_SIZE;
if (outOfBounds) {
const promise = MapPrototypeGet(promiseMap, promiseId);
if (!promise) {
throw "Missing promise in map @ " + promiseId;
}
MapPrototypeDelete(promiseMap, promiseId);
if (isOk) {
promise[0](res);
} else {
promise[1](res);
}
} else {
// Otherwise take from ring
const idx = promiseId % RING_SIZE;
const promise = promiseRing[idx];
if (!promise) {
throw "Missing promise in ring @ " + promiseId;
}
promiseRing[idx] = NO_PROMISE;
if (isOk) {
promise[0](res);
} else {
promise[1](res);
}
}
}

function hasPromise(promiseId) {
// Check if out of ring bounds, fallback to map
const outOfBounds = promiseId < nextPromiseId - RING_SIZE;
if (outOfBounds) {
return MapPrototypeHas(promiseMap, promiseId);
}
// Otherwise check it in ring
const idx = promiseId % RING_SIZE;
return promiseRing[idx] != NO_PROMISE;
}

function setUpAsyncStub(opName, originalOp, maybeProto) {
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 {
// deno-fmt-ignore
const maybeResult = originalOp.call(this, 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 {
// deno-fmt-ignore
const maybeResult = originalOp.call(this, 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;
case 2:
fn = function async_op_2(a, b) {
const id = nextPromiseId;
try {
// deno-fmt-ignore
const maybeResult = originalOp.call(this, id, a, b);
if (maybeResult !== undefined) {
return PromiseResolve(maybeResult);
}
} catch (err) {
ErrorCaptureStackTrace(err, async_op_2);
return PromiseReject(err);
}
if (isLeakTracingEnabled) {
submitLeakTrace(id);
}
nextPromiseId = (id + 1) & 0xffffffff;
return setPromise(id);
};
break;
case 3:
fn = function async_op_3(a, b, c) {
const id = nextPromiseId;
try {
// deno-fmt-ignore
const maybeResult = originalOp.call(this, id, a, b, c);
if (maybeResult !== undefined) {
return PromiseResolve(maybeResult);
}
} catch (err) {
ErrorCaptureStackTrace(err, async_op_3);
return PromiseReject(err);
}
if (isLeakTracingEnabled) {
submitLeakTrace(id);
}
nextPromiseId = (id + 1) & 0xffffffff;
return setPromise(id);
};
break;
case 4:
fn = function async_op_4(a, b, c, d) {
const id = nextPromiseId;
try {
// deno-fmt-ignore
const maybeResult = originalOp.call(this, id, a, b, c, d);
if (maybeResult !== undefined) {
return PromiseResolve(maybeResult);
}
} catch (err) {
ErrorCaptureStackTrace(err, async_op_4);
return PromiseReject(err);
}
if (isLeakTracingEnabled) {
submitLeakTrace(id);
}
nextPromiseId = (id + 1) & 0xffffffff;
return setPromise(id);
};
break;
case 5:
fn = function async_op_5(a, b, c, d, e) {
const id = nextPromiseId;
try {
// deno-fmt-ignore
const maybeResult = originalOp.call(this, id, a, b, c, d, e);
if (maybeResult !== undefined) {
return PromiseResolve(maybeResult);
}
} catch (err) {
ErrorCaptureStackTrace(err, async_op_5);
return PromiseReject(err);
}
if (isLeakTracingEnabled) {
submitLeakTrace(id);
}
nextPromiseId = (id + 1) & 0xffffffff;
return setPromise(id);
};
break;
case 6:
fn = function async_op_6(a, b, c, d, e, f) {
const id = nextPromiseId;
try {
// deno-fmt-ignore
const maybeResult = originalOp.call(this, id, a, b, c, d, e, f);
if (maybeResult !== undefined) {
return PromiseResolve(maybeResult);
}
} catch (err) {
ErrorCaptureStackTrace(err, async_op_6);
return PromiseReject(err);
}
if (isLeakTracingEnabled) {
submitLeakTrace(id);
}
nextPromiseId = (id + 1) & 0xffffffff;
return setPromise(id);
};
break;
case 7:
fn = function async_op_7(a, b, c, d, e, f, g) {
const id = nextPromiseId;
try {
// deno-fmt-ignore
const maybeResult = originalOp.call(this, id, a, b, c, d, e, f, g);
if (maybeResult !== undefined) {
return PromiseResolve(maybeResult);
}
} catch (err) {
ErrorCaptureStackTrace(err, async_op_7);
return PromiseReject(err);
}
if (isLeakTracingEnabled) {
submitLeakTrace(id);
}
nextPromiseId = (id + 1) & 0xffffffff;
return setPromise(id);
};
break;
case 8:
fn = function async_op_8(a, b, c, d, e, f, g, h) {
const id = nextPromiseId;
try {
// deno-fmt-ignore
const maybeResult = originalOp.call(this, id, a, b, c, d, e, f, g, h);
if (maybeResult !== undefined) {
return PromiseResolve(maybeResult);
}
} catch (err) {
ErrorCaptureStackTrace(err, async_op_8);
return PromiseReject(err);
}
if (isLeakTracingEnabled) {
submitLeakTrace(id);
}
nextPromiseId = (id + 1) & 0xffffffff;
return setPromise(id);
};
break;
case 9:
fn = function async_op_9(a, b, c, d, e, f, g, h, i) {
const id = nextPromiseId;
try {
// deno-fmt-ignore
const maybeResult = originalOp.call(this, id, a, b, c, d, e, f, g, h, i);
if (maybeResult !== undefined) {
return PromiseResolve(maybeResult);
}
} catch (err) {
ErrorCaptureStackTrace(err, async_op_9);
return PromiseReject(err);
}
if (isLeakTracingEnabled) {
submitLeakTrace(id);
}
nextPromiseId = (id + 1) & 0xffffffff;
return setPromise(id);
};
break;
/* END TEMPLATE */

default:
throw new Error(
`Too many arguments for async op codegen (length of ${opName} was ${
originalOp.length - 1
})`,
);
}
ObjectDefineProperty(fn, "name", {
value: opName,
configurable: false,
writable: false,
});

if (maybeProto) {
ObjectDefineProperty(fn, "prototype", {
value: maybeProto.prototype,
configurable: false,
writable: false,
});
maybeProto.prototype[opName] = fn;
}

return fn;
}

// Extra Deno.core.* exports
const core = ObjectAssign(globalThis.Deno.core, {
build,
setBuildInfo,
registerErrorBuilder,
buildCustomError,
registerErrorClass,
setUpAsyncStub,
hasPromise,
promiseIdSymbol,
});

const infra = {
__resolvePromise,
__setLeakTracingEnabled,
__isLeakTracingEnabled,
__initializeCoreMethods,
Expand Down
Loading