aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/InternalModuleRegistry.cpp
diff options
context:
space:
mode:
authorGravatar dave caruso <me@paperdave.net> 2023-08-02 16:27:36 -0700
committerGravatar GitHub <noreply@github.com> 2023-08-02 16:27:36 -0700
commitc2a77cf7ec9de9eadf938046bdf78e58561c8a6d (patch)
tree0f90f1b323061455875333c9f40592b303585973 /src/bun.js/bindings/InternalModuleRegistry.cpp
parent7656b4b17e91f15b58eeab8f45b78c416ec6a045 (diff)
downloadbun-c2a77cf7ec9de9eadf938046bdf78e58561c8a6d.tar.gz
bun-c2a77cf7ec9de9eadf938046bdf78e58561c8a6d.tar.zst
bun-c2a77cf7ec9de9eadf938046bdf78e58561c8a6d.zip
Rewrite built-in modules to use CommonJS over ESM (#3814)
* stfdsafsd sadffdsa stuff finish commonjs stuff asdf not done but work not done but work not done yet but this is how far i am remove files lol update built files uncomment everything in events lol export default stuff * afdsafsd * its not perfect but almost done * okay * cool * remove temp file * finish rebase * revert settings.json * a * ch-ch-ch-ch-changes * okay * remove this check in release for now * sxdcfghnjm, * lkjhgf * fmt * filename can be null * Update NodeModuleModule.h * weee * fmt --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js/bindings/InternalModuleRegistry.cpp')
-rw-r--r--src/bun.js/bindings/InternalModuleRegistry.cpp142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/bun.js/bindings/InternalModuleRegistry.cpp b/src/bun.js/bindings/InternalModuleRegistry.cpp
new file mode 100644
index 000000000..552e9fbfe
--- /dev/null
+++ b/src/bun.js/bindings/InternalModuleRegistry.cpp
@@ -0,0 +1,142 @@
+#include "InternalModuleRegistry.h"
+
+#include "ZigGlobalObject.h"
+#include "JavaScriptCore/BuiltinUtils.h"
+#include "JavaScriptCore/JSFunction.h"
+#include "JavaScriptCore/LazyProperty.h"
+#include "JavaScriptCore/LazyPropertyInlines.h"
+#include "JavaScriptCore/VMTrapsInlines.h"
+#include "JavaScriptCore/JSModuleLoader.h"
+
+#include "InternalModuleRegistryConstants.h"
+
+namespace Bun {
+
+// The `INTERNAL_MODULE_REGISTRY_GENERATE` macro handles inlining code to compile and run a
+// JS builtin that acts as a module. In debug mode, we use a different implementation that reads
+// from the developer's filesystem. This allows reloading code without recompiling bindings.
+
+#define INTERNAL_MODULE_REGISTRY_GENERATE_(globalObject, vm, SOURCE, moduleName) \
+ auto throwScope = DECLARE_THROW_SCOPE(vm); \
+ \
+ SourceCode source = JSC::makeSource(SOURCE, SourceOrigin(WTF::URL("builtin://" #moduleName ".js"_s)), #moduleName ".js"_s); \
+ \
+ JSFunction* func \
+ = JSFunction::create( \
+ vm, \
+ createBuiltinExecutable( \
+ vm, source, \
+ Identifier(), \
+ ImplementationVisibility::Public, \
+ ConstructorKind::None, \
+ ConstructAbility::CannotConstruct) \
+ ->link(vm, nullptr, source), \
+ static_cast<JSC::JSGlobalObject*>(globalObject)); \
+ \
+ JSC::MarkedArgumentBuffer argList; \
+ \
+ JSValue result = JSC::call( \
+ globalObject, \
+ func, \
+ JSC::getCallData(func), \
+ globalObject, JSC::MarkedArgumentBuffer()); \
+ \
+ RETURN_IF_EXCEPTION(throwScope, {}); \
+ ASSERT_INTERNAL_MODULE(result, moduleName); \
+ return result;
+
+#if BUN_DEBUG
+#include "../../src/js/out/DebugPath.h"
+#define ASSERT_INTERNAL_MODULE(result, moduleName) \
+ if (!result || !result.isCell() || !jsDynamicCast<JSObject*>(result)) { \
+ printf("Expected \"%s\" to export a JSObject. Bun is going to crash.", moduleName.utf8().data()); \
+ }
+JSValue initializeInternalModuleFromDisk(
+ JSGlobalObject* globalObject,
+ VM& vm,
+ WTF::String moduleName,
+ WTF::String fileBase,
+ WTF::String fallback)
+{
+ WTF::String file = makeString(BUN_DYNAMIC_JS_LOAD_PATH, "modules_dev/"_s, fileBase);
+ if (auto contents = WTF::FileSystemImpl::readEntireFile(file)) {
+ auto string = WTF::String::fromUTF8(contents.value());
+ INTERNAL_MODULE_REGISTRY_GENERATE_(globalObject, vm, string, moduleName);
+ } else {
+ printf("bun-debug failed to load bundled version of \"%s\" at \"%s\" (was it deleted?)\n"
+ "Please run `make js` to rebundle these builtins.\n",
+ moduleName.utf8().data(), file.utf8().data());
+ // Fallback to embedded source
+ INTERNAL_MODULE_REGISTRY_GENERATE_(globalObject, vm, fallback, moduleName);
+ }
+}
+#define INTERNAL_MODULE_REGISTRY_GENERATE(globalObject, vm, moduleId, filename, SOURCE) \
+ return initializeInternalModuleFromDisk(globalObject, vm, moduleId, filename, SOURCE)
+#else
+
+#define ASSERT_INTERNAL_MODULE(result, moduleName) \
+ { \
+ }
+#define INTERNAL_MODULE_REGISTRY_GENERATE(globalObject, vm, moduleId, filename, SOURCE) \
+ INTERNAL_MODULE_REGISTRY_GENERATE_(globalObject, vm, SOURCE, moduleId)
+#endif
+
+const ClassInfo InternalModuleRegistry::s_info = { "InternalModuleRegistry"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(InternalModuleRegistry) };
+
+InternalModuleRegistry::InternalModuleRegistry(VM& vm, Structure* structure)
+ : Base(vm, structure)
+{
+}
+
+template<typename Visitor>
+void InternalModuleRegistry::visitChildrenImpl(JSCell* cell, Visitor& visitor)
+{
+ auto* thisObject = jsCast<InternalModuleRegistry*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(thisObject, visitor);
+}
+
+DEFINE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE, InternalModuleRegistry);
+
+InternalModuleRegistry* InternalModuleRegistry::create(VM& vm, Structure* structure)
+{
+ InternalModuleRegistry* registry = new (NotNull, allocateCell<InternalModuleRegistry>(vm)) InternalModuleRegistry(vm, structure);
+ for (uint8_t i = 0; i < BUN_INTERNAL_MODULE_COUNT; i++) {
+ registry->internalField(static_cast<Field>(i))
+ .set(vm, registry, jsUndefined());
+ }
+ return registry;
+}
+
+Structure* InternalModuleRegistry::createStructure(VM& vm, JSGlobalObject* globalObject)
+{
+ return Structure::create(vm, globalObject, jsNull(), TypeInfo(InternalFieldTupleType, StructureFlags), info(), 0, 48);
+}
+
+JSValue InternalModuleRegistry::requireId(JSGlobalObject* globalObject, VM& vm, Field id)
+{
+ auto value = internalField(id).get();
+ if (!value || value.isUndefined()) {
+ value = createInternalModuleById(globalObject, vm, id);
+ internalField(id).set(vm, this, value);
+ }
+ return value;
+}
+
+#include "../../../src/js/out/InternalModuleRegistry+createInternalModuleById.h"
+
+// This is called like @getInternalField(@internalModuleRegistry, 1) ?? @createInternalModuleById(1)
+// so we want to write it to the internal field when loaded.
+JSC_DEFINE_HOST_FUNCTION(InternalModuleRegistry::jsCreateInternalModuleById, (JSGlobalObject * lexicalGlobalObject, CallFrame* callframe))
+{
+ auto id = callframe->argument(0).toUInt32(lexicalGlobalObject);
+ auto registry = static_cast<Zig::GlobalObject*>(lexicalGlobalObject)->internalModuleRegistry();
+ auto module = registry->createInternalModuleById(lexicalGlobalObject, lexicalGlobalObject->vm(), static_cast<Field>(id));
+ registry->internalField(static_cast<Field>(id)).set(lexicalGlobalObject->vm(), registry, module);
+ return JSValue::encode(module);
+}
+
+} // namespace Bun
+
+#undef INTERNAL_MODULE_REGISTRY_GENERATE_
+#undef INTERNAL_MODULE_REGISTRY_GENERATE