Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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 @@ -56,6 +56,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
Loading