fix: make getChildEntry recursively traverse the path#301
fix: make getChildEntry recursively traverse the path#301guybedford merged 2 commits intobytecodealliance:mainfrom whitequark:patch-2
Conversation
| do { | ||
| if (!entry || !entry.dir) throw 'not-directory'; | ||
| segmentIdx = subpath.indexOf('/'); | ||
| segmentIdx = subpath.indexOf('/', segmentIdx); |
There was a problem hiding this comment.
Drive by: this will search starting at the previous segmentIdx, but that value was an offset into subpath as it was before the later subpath = subpath.substring(segmentIdx + 1) line. Probably you don't want to have both that line and this one?
Consider running this code on longDirName/short/x - the second time through the loop it will start searching the string "short/x" at index 11 (which is past the end of the string), and so miss the / between "short" and "x".
There was a problem hiding this comment.
For posterity, here's the traverse function I eventually ended up writing, which I think is a lot more correct:
traverse(path, flags = { create: false, remove: false }) {
let entry = this;
let separatorAt = -1;
do {
if (entry instanceof File)
throw 'not-directory';
const files = entry.files;
separatorAt = path.indexOf('/');
const segment = separatorAt === -1 ? path : path.substring(0, separatorAt);
if (separatorAt === -1 && flags.remove)
delete files[segment];
else if (segment === '' || segment === '.')
/* disregard */;
else if (segment === '..')
/* hack to make scandir() work */;
else if (Object.hasOwn(files, segment))
entry = files[segment];
else if (flags.create === 'directory' || flags.create === 'file' && separatorAt !== -1)
entry = files[segment] = new Directory({});
else if (flags.create === 'file')
entry = files[segment] = new File(new Uint8Array());
else
throw 'no-entry';
path = path.substring(separatorAt + 1);
} while (separatorAt !== -1);
return entry;
}It's not quite compatible with this specific shim but I think the algorithm is sound.
There was a problem hiding this comment.
Thanks for noticing this one @bakkot, the browser implementation is considered experimental and is kinda on the verge of either deprecation or heavy refactoring depending on which way we go here. I do like the idea of refining this implementation into something more like what was discussed in #303 (comment).
For now, it's kinda still placeholder code and lots of code paths are entirely untested, a decision will be made on the deprecation / refactoring soon though so it won't be staying in this state.
For now I posted a follow-up in #309. Any review there would be very welcome. Always fun to have the opportunity to use a bodiless conditional...
This reverts commit ed6c88b.
I'm testing JCO together with YoWASP. I componentized a regular build of YoWASP Yosys using
jco new --wasi-commandandjco transpile, and am running it with this script:Without this PR, Yosys attempting to open
./inv.vopens the directory (and then crashes because it's not a file). I'm not entirely sure what the intent for thegetChildEntryfunction is, but it seems wrong as-is, and the script completes with my changes.