mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-13 06:20:02 -04:00
fix scrammaps
This commit is contained in:
parent
e8ff38b2e5
commit
f15cf568c1
4 changed files with 103 additions and 78 deletions
|
@ -5,11 +5,11 @@ function rewriteFunction(ctx: ProxyCtx, client: ScramjetClient) {
|
||||||
const stringifiedFunction = ctx.call().toString();
|
const stringifiedFunction = ctx.call().toString();
|
||||||
|
|
||||||
const content = rewriteJs(
|
const content = rewriteJs(
|
||||||
`return ${stringifiedFunction}`,
|
stringifiedFunction,
|
||||||
"(function proxy)",
|
"(function proxy)",
|
||||||
client.meta
|
client.meta
|
||||||
);
|
);
|
||||||
ctx.return(ctx.fn(content)());
|
ctx.return(ctx.fn(`return ${content}`)());
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function (client: ScramjetClient, _self: Self) {
|
export default function (client: ScramjetClient, _self: Self) {
|
||||||
|
|
|
@ -6,27 +6,28 @@ enum RewriteType {
|
||||||
Replace = 1,
|
Replace = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Rewrite =
|
type Rewrite = {
|
||||||
|
start: number;
|
||||||
|
} & (
|
||||||
| {
|
| {
|
||||||
type: RewriteType.Insert;
|
type: RewriteType.Insert;
|
||||||
// offset before this rewrite
|
|
||||||
offset: number;
|
|
||||||
// start of insertion
|
|
||||||
start: number;
|
|
||||||
// size of insertion
|
|
||||||
size: number;
|
size: number;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: RewriteType.Replace;
|
type: RewriteType.Replace;
|
||||||
// offset before this rewrite
|
|
||||||
offset: number;
|
|
||||||
// start of replacement
|
|
||||||
start: number;
|
|
||||||
// end of replacement
|
|
||||||
end: number;
|
end: number;
|
||||||
// old string
|
|
||||||
str: string;
|
str: string;
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
function getEnd(rewrite: Rewrite): number {
|
||||||
|
if (rewrite.type === RewriteType.Insert) {
|
||||||
|
return rewrite.start + rewrite.size;
|
||||||
|
} else if (rewrite.type === RewriteType.Replace) {
|
||||||
|
return rewrite.end;
|
||||||
|
}
|
||||||
|
throw "unreachable";
|
||||||
|
}
|
||||||
|
|
||||||
const sourcemaps: Record<string, Rewrite[]> = {};
|
const sourcemaps: Record<string, Rewrite[]> = {};
|
||||||
|
|
||||||
|
@ -35,40 +36,43 @@ export const enabled = (client: ScramjetClient) =>
|
||||||
|
|
||||||
export default function (client: ScramjetClient, self: Self) {
|
export default function (client: ScramjetClient, self: Self) {
|
||||||
// every script will push a sourcemap
|
// every script will push a sourcemap
|
||||||
Object.defineProperty(self, $scramjet.config.globals.pushsourcemapfn, {
|
Object.defineProperty(
|
||||||
|
self,
|
||||||
|
globalThis.$scramjet.config.globals.pushsourcemapfn,
|
||||||
|
{
|
||||||
value: (buf: Array<number>, tag: string) => {
|
value: (buf: Array<number>, tag: string) => {
|
||||||
const sourcemap = Uint8Array.from(buf);
|
const sourcemap = Uint8Array.from(buf);
|
||||||
const view = new DataView(sourcemap.buffer);
|
const view = new DataView(sourcemap.buffer);
|
||||||
const decoder = new TextDecoder("utf-8");
|
const decoder = new TextDecoder("utf-8");
|
||||||
|
|
||||||
const rewrites = [];
|
const rewrites: Rewrite[] = [];
|
||||||
|
|
||||||
const rewritelen = view.getUint32(0, true);
|
const rewritelen = view.getUint32(0, true);
|
||||||
let cursor = 0;
|
let cursor = 4;
|
||||||
for (let i = 0; i < rewritelen; i++) {
|
for (let i = 0; i < rewritelen; i++) {
|
||||||
const type = view.getUint8(cursor) as RewriteType;
|
const type = view.getUint8(cursor) as RewriteType;
|
||||||
cursor += 1;
|
cursor += 1;
|
||||||
|
|
||||||
if (type == RewriteType.Insert) {
|
if (type == RewriteType.Insert) {
|
||||||
const offset = view.getUint32(cursor, true);
|
|
||||||
cursor += 4;
|
|
||||||
const start = view.getUint32(cursor, true);
|
const start = view.getUint32(cursor, true);
|
||||||
cursor += 4;
|
cursor += 4;
|
||||||
const size = view.getUint32(cursor, true);
|
const size = view.getUint32(cursor, true);
|
||||||
cursor += 4;
|
cursor += 4;
|
||||||
|
|
||||||
rewrites.push({ type, offset, start, size });
|
rewrites.push({ type, start, size });
|
||||||
} else if (type == RewriteType.Replace) {
|
} else if (type == RewriteType.Replace) {
|
||||||
const offset = view.getUint32(cursor, true);
|
|
||||||
cursor += 4;
|
|
||||||
const start = view.getUint32(cursor, true);
|
const start = view.getUint32(cursor, true);
|
||||||
cursor += 4;
|
cursor += 4;
|
||||||
const end = view.getUint32(cursor, true);
|
const end = view.getUint32(cursor, true);
|
||||||
cursor += 4;
|
cursor += 4;
|
||||||
|
const len = view.getUint32(cursor, true);
|
||||||
|
cursor += 4;
|
||||||
|
|
||||||
const str = decoder.decode(sourcemap.subarray(start, end));
|
const str = decoder.decode(
|
||||||
|
sourcemap.subarray(cursor, cursor + len)
|
||||||
|
);
|
||||||
|
|
||||||
rewrites.push({ type, offset, start, end, str });
|
rewrites.push({ type, start, end, str });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +81,8 @@ export default function (client: ScramjetClient, self: Self) {
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
writable: false,
|
writable: false,
|
||||||
configurable: false,
|
configurable: false,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const scramtag_ident = "/*scramtag ";
|
const scramtag_ident = "/*scramtag ";
|
||||||
|
|
||||||
|
@ -86,7 +91,6 @@ export default function (client: ScramjetClient, self: Self) {
|
||||||
client.Proxy("Function.prototype.toString", {
|
client.Proxy("Function.prototype.toString", {
|
||||||
apply(ctx) {
|
apply(ctx) {
|
||||||
let stringified: string = ctx.fn.call(ctx.this);
|
let stringified: string = ctx.fn.call(ctx.this);
|
||||||
let newString = "";
|
|
||||||
|
|
||||||
// every function rewritten will have a scramtag comment
|
// every function rewritten will have a scramtag comment
|
||||||
// it will look like this:
|
// it will look like this:
|
||||||
|
@ -106,39 +110,50 @@ export default function (client: ScramjetClient, self: Self) {
|
||||||
|
|
||||||
// subtracting that from the index of the scramtag gives us the starting index of the function relative to the entire file
|
// subtracting that from the index of the scramtag gives us the starting index of the function relative to the entire file
|
||||||
const absindex = abstagindex - scramtagstart;
|
const absindex = abstagindex - scramtagstart;
|
||||||
|
const endindex = absindex + stringified.length;
|
||||||
|
|
||||||
const scramtagend = stringified.indexOf("*/", scramtagstart);
|
const scramtagend = stringified.indexOf("*/", scramtagstart);
|
||||||
const tag = stringified.substring(firstspace + 1, scramtagend);
|
const tag = stringified.substring(firstspace + 1, scramtagend);
|
||||||
|
|
||||||
// delete all scramtags inside the function (and nested ones!!)
|
const rewrites = sourcemaps[tag];
|
||||||
stringified = stringified.replace(/\/\*scramtag.*?\*\//g, "");
|
|
||||||
|
|
||||||
const maps = sourcemaps[tag];
|
if (!rewrites) {
|
||||||
|
console.warn("failed to get rewrites for tag", tag);
|
||||||
|
return ctx.return(stringified);
|
||||||
|
}
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
let offset = 0;
|
// skip all rewrites in the file before the fn
|
||||||
|
while (i < rewrites.length) {
|
||||||
let j = 0;
|
if (rewrites[i].start < absindex) i++;
|
||||||
while (j < maps.length) {
|
else break;
|
||||||
/* TODO
|
|
||||||
const [str, start, end] = maps[j];
|
|
||||||
if (start < absindex) {
|
|
||||||
j++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (start - absindex + offset > stringified.length) break;
|
|
||||||
|
|
||||||
// ooh i should really document this before i forget how it works
|
|
||||||
newString += stringified.slice(i, start - absindex + offset);
|
|
||||||
newString += str;
|
|
||||||
offset += end - start - str.length;
|
|
||||||
i = start - absindex + offset + str.length;
|
|
||||||
|
|
||||||
j++;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newString += stringified.slice(i);
|
let end = i;
|
||||||
|
while (end < rewrites.length) {
|
||||||
|
if (getEnd(rewrites[end]) < endindex) end++;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnrewrites = rewrites.slice(i, end);
|
||||||
|
|
||||||
|
let newString = "";
|
||||||
|
let lastpos = absindex;
|
||||||
|
|
||||||
|
for (const rewrite of fnrewrites) {
|
||||||
|
newString += stringified.slice(lastpos, rewrite.start);
|
||||||
|
|
||||||
|
if (rewrite.type === RewriteType.Insert) {
|
||||||
|
lastpos = rewrite.start + rewrite.size;
|
||||||
|
} else if (rewrite.type === RewriteType.Replace) {
|
||||||
|
newString += rewrite.str;
|
||||||
|
lastpos = rewrite.end;
|
||||||
|
} else {
|
||||||
|
throw "unreachable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newString += stringified.slice(lastpos);
|
||||||
|
|
||||||
return ctx.return(newString);
|
return ctx.return(newString);
|
||||||
},
|
},
|
||||||
|
|
|
@ -62,7 +62,14 @@ function rewriteJsWrapper(
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
const after = performance.now();
|
const after = performance.now();
|
||||||
const { js, errors, duration } = out;
|
const { js, map, scramtag, errors, duration } = out;
|
||||||
|
|
||||||
|
if ((flagEnabled("sourcemaps", meta.base), !globalThis.clients)) {
|
||||||
|
globalThis[globalThis.$scramjet.config.globals.pushsourcemapfn](
|
||||||
|
Array.from(map),
|
||||||
|
scramtag
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (flagEnabled("rewriterLogs", meta.base)) {
|
if (flagEnabled("rewriterLogs", meta.base)) {
|
||||||
for (const error of errors) {
|
for (const error of errors) {
|
||||||
|
|
|
@ -6,6 +6,9 @@ const scramjet = new ScramjetController({
|
||||||
shared: "/scram/scramjet.shared.js",
|
shared: "/scram/scramjet.shared.js",
|
||||||
sync: "/scram/scramjet.sync.js",
|
sync: "/scram/scramjet.sync.js",
|
||||||
},
|
},
|
||||||
|
flags: {
|
||||||
|
sourcemaps: true,
|
||||||
|
},
|
||||||
siteFlags: {
|
siteFlags: {
|
||||||
"https://worker-playground.glitch.me/.*": {
|
"https://worker-playground.glitch.me/.*": {
|
||||||
serviceworkers: true,
|
serviceworkers: true,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue