mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
implement Module.prototype._compile (#5840)
This commit is contained in:
@@ -346,6 +346,63 @@ static JSValue createChildren(VM& vm, JSObject* object)
|
||||
return constructEmptyArray(object->globalObject(), nullptr, 0);
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(functionCommonJSModuleRecord_compile, (JSGlobalObject * globalObject, CallFrame* callframe))
|
||||
{
|
||||
auto* moduleObject = jsDynamicCast<JSCommonJSModule*>(callframe->thisValue());
|
||||
if (!moduleObject) {
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
auto& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
String sourceString = callframe->argument(0).toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, JSValue::encode({}));
|
||||
|
||||
String filenameString = callframe->argument(1).toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, JSValue::encode({}));
|
||||
|
||||
String wrappedString = makeString(
|
||||
"(function(module,exports,require,__dirname,__filename){"_s,
|
||||
sourceString,
|
||||
"\n}).call($_BunCommonJSModule_$.module.exports, $_BunCommonJSModule_$.module, $_BunCommonJSModule_$.module.exports, ($_BunCommonJSModule_$.module.require = $_BunCommonJSModule_$.module.require.bind($_BunCommonJSModule_$.module), $_BunCommonJSModule_$.module.require.path = $_BunCommonJSModule_$.module.id, $_BunCommonJSModule_$.module.require.resolve = $_BunCommonJSModule_$.module.require.resolve.bind($_BunCommonJSModule_$.module.id), $_BunCommonJSModule_$.module.require), $_BunCommonJSModule_$.__dirname, $_BunCommonJSModule_$.__filename);"_s);
|
||||
|
||||
SourceCode sourceCode = makeSource(
|
||||
WTFMove(wrappedString),
|
||||
SourceOrigin(URL::fileURLWithFileSystemPath(filenameString)),
|
||||
JSC::SourceTaintedOrigin::Untainted,
|
||||
filenameString,
|
||||
WTF::TextPosition(),
|
||||
JSC::SourceProviderSourceType::Program);
|
||||
JSSourceCode* jsSourceCode = JSSourceCode::create(vm, WTFMove(sourceCode));
|
||||
moduleObject->sourceCode.set(vm, moduleObject, jsSourceCode);
|
||||
|
||||
auto index = filenameString.reverseFind('/', filenameString.length());
|
||||
String dirnameString;
|
||||
if (index != WTF::notFound) {
|
||||
dirnameString = filenameString.substring(0, index);
|
||||
} else {
|
||||
dirnameString = "/"_s;
|
||||
}
|
||||
|
||||
WTF::NakedPtr<JSC::Exception> exception;
|
||||
evaluateCommonJSModuleOnce(
|
||||
vm,
|
||||
jsCast<Zig::GlobalObject*>(globalObject),
|
||||
moduleObject,
|
||||
jsString(vm, dirnameString),
|
||||
jsString(vm, filenameString),
|
||||
exception);
|
||||
|
||||
if (exception) {
|
||||
throwException(globalObject, throwScope, exception.get());
|
||||
exception.clear();
|
||||
return JSValue::encode({});
|
||||
}
|
||||
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
static const struct HashTableValue JSCommonJSModulePrototypeTableValues[] = {
|
||||
{ "children"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createChildren } },
|
||||
{ "filename"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterFilename, setterFilename } },
|
||||
@@ -354,6 +411,7 @@ static const struct HashTableValue JSCommonJSModulePrototypeTableValues[] = {
|
||||
{ "parent"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createParent } },
|
||||
{ "path"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterPath, setterPath } },
|
||||
{ "paths"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterPaths, setterPaths } },
|
||||
{ "_compile"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionCommonJSModuleRecord_compile, 2 } },
|
||||
};
|
||||
|
||||
class JSCommonJSModulePrototype final : public JSC::JSNonFinalObject {
|
||||
|
||||
@@ -346,6 +346,7 @@ public:
|
||||
mutable WriteBarrier<JSFunction> m_nodeModuleOverriddenResolveFilename;
|
||||
|
||||
mutable WriteBarrier<Unknown> m_nextTickQueue;
|
||||
// Value of $_BunCommonJSModule_$
|
||||
mutable WriteBarrier<Unknown> m_BunCommonJSModuleValue;
|
||||
|
||||
// mutable WriteBarrier<Unknown> m_JSBunDebuggerValue;
|
||||
|
||||
@@ -2143,7 +2143,7 @@ pub const ModuleLoader = struct {
|
||||
const path = Fs.Path.init(specifier);
|
||||
|
||||
const loader = if (loader_ != ._none)
|
||||
options.Loader.fromString(@tagName(loader_)).?
|
||||
options.Loader.fromAPI(loader_)
|
||||
else
|
||||
jsc_vm.bundler.options.loaders.get(path.name.ext) orelse brk: {
|
||||
if (strings.eqlLong(specifier, jsc_vm.main, true)) {
|
||||
@@ -2162,7 +2162,7 @@ pub const ModuleLoader = struct {
|
||||
referrer_slice.slice(),
|
||||
specifier_ptr.*,
|
||||
path,
|
||||
options.Loader.fromString(@tagName(loader)).?,
|
||||
loader,
|
||||
&log,
|
||||
&virtual_source,
|
||||
ret,
|
||||
|
||||
@@ -70,3 +70,20 @@ test("Overwriting _resolveFilename", () => {
|
||||
expect(stdout.toString().trim().endsWith("--pass--")).toBe(true);
|
||||
expect(exitCode).toBe(0);
|
||||
});
|
||||
|
||||
test("Module.prototype._compile", () => {
|
||||
const module = new Module("module id goes here");
|
||||
const starting_exports = module.exports;
|
||||
const r = module._compile(
|
||||
"module.exports = { module, exports, require, __filename, __dirname }",
|
||||
"/file/path/goes/here.js",
|
||||
);
|
||||
expect(r).toBe(undefined);
|
||||
expect(module.exports).not.toBe(starting_exports);
|
||||
const { module: m, exports: e, require: req, __filename: fn, __dirname: dn } = module.exports;
|
||||
expect(m).toBe(module);
|
||||
expect(e).toBe(starting_exports);
|
||||
expect(req).toBe(module.require);
|
||||
expect(fn).toBe("/file/path/goes/here.js");
|
||||
expect(dn).toBe("/file/path/goes");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user