Files
bun.sh/src/bake/BakeSourceProvider.cpp
2024-10-27 01:57:36 -07:00

128 lines
4.6 KiB
C++

// clang-format off
#include "BakeSourceProvider.h"
#include "BakeGlobalObject.h"
#include "JavaScriptCore/Completion.h"
#include "JavaScriptCore/Identifier.h"
#include "JavaScriptCore/JSCJSValue.h"
#include "JavaScriptCore/JSCast.h"
#include "JavaScriptCore/JSLock.h"
#include "JavaScriptCore/JSMap.h"
#include "JavaScriptCore/JSModuleLoader.h"
#include "JavaScriptCore/JSString.h"
#include "JavaScriptCore/JSModuleNamespaceObject.h"
namespace Bake {
extern "C" LoadServerCodeResult BakeLoadInitialServerCode(GlobalObject* global, BunString source) {
JSC::VM& vm = global->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
String string = "bake://server.js"_s;
JSC::JSString* key = JSC::jsString(vm, string);
JSC::SourceOrigin origin = JSC::SourceOrigin(WTF::URL(string));
JSC::SourceCode sourceCode = JSC::SourceCode(DevSourceProvider::create(
source.toWTFString(),
origin,
WTFMove(string),
WTF::TextPosition(),
JSC::SourceProviderSourceType::Module
));
global->moduleLoader()->provideFetch(global, key, sourceCode);
RETURN_IF_EXCEPTION(scope, {});
JSC::JSInternalPromise* internalPromise = global->moduleLoader()->loadAndEvaluateModule(global, key, JSC::jsUndefined(), JSC::jsUndefined());
RETURN_IF_EXCEPTION(scope, {});
return { internalPromise, key };
}
extern "C" JSC::JSInternalPromise* BakeLoadModuleByKey(GlobalObject* global, JSC::JSString* key) {
return global->moduleLoader()->loadAndEvaluateModule(global, key, JSC::jsUndefined(), JSC::jsUndefined());
}
extern "C" JSC::EncodedJSValue BakeLoadServerHmrPatch(GlobalObject* global, BunString source) {
JSC::VM&vm = global->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
String string = "bake://server.patch.js"_s;
JSC::SourceOrigin origin = JSC::SourceOrigin(WTF::URL(string));
JSC::SourceCode sourceCode = JSC::SourceCode(DevSourceProvider::create(
source.toWTFString(),
origin,
WTFMove(string),
WTF::TextPosition(),
JSC::SourceProviderSourceType::Program
));
JSC::JSValue result = vm.interpreter.executeProgram(sourceCode, global, global);
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode({}));
RELEASE_ASSERT(result);
return JSC::JSValue::encode(result);
}
extern "C" JSC::EncodedJSValue BakeGetModuleNamespace(
JSC::JSGlobalObject* global,
JSC::JSValue keyValue
) {
JSC::JSString* key = JSC::jsCast<JSC::JSString*>(keyValue);
JSC::VM& vm = global->vm();
JSC::JSMap* map = JSC::jsCast<JSC::JSMap*>(
global->moduleLoader()->getDirect(
vm, JSC::Identifier::fromString(global->vm(), "registry"_s)
));
JSC::JSValue entry = map->get(global, key);
ASSERT(entry.isObject()); // should have called BakeLoadServerCode and wait for that promise
JSC::JSValue module = entry.getObject()->get(global, JSC::Identifier::fromString(global->vm(), "module"_s));
ASSERT(module.isCell());
JSC::JSModuleNamespaceObject* namespaceObject = global->moduleLoader()->getModuleNamespaceObject(global, module);
ASSERT(namespaceObject);
return JSC::JSValue::encode(namespaceObject);
}
extern "C" JSC::EncodedJSValue BakeGetDefaultExportFromModule(
JSC::JSGlobalObject* global,
JSC::JSValue keyValue
) {
JSC::VM& vm = global->vm();
return JSC::JSValue::encode(jsCast<JSC::JSModuleNamespaceObject*>(JSC::JSValue::decode(BakeGetModuleNamespace(global, keyValue)))->get(global, vm.propertyNames->defaultKeyword));
}
// There were issues when trying to use JSValue.get from zig
extern "C" JSC::EncodedJSValue BakeGetOnModuleNamespace(
JSC::JSGlobalObject* global,
JSC::JSModuleNamespaceObject* moduleNamespace,
const unsigned char* key,
size_t keyLength
) {
JSC::VM& vm = global->vm();
const auto propertyString = String(StringImpl::createWithoutCopying({ key, keyLength }));
const auto identifier = JSC::Identifier::fromString(vm, propertyString);
const auto property = JSC::PropertyName(identifier);
return JSC::JSValue::encode(moduleNamespace->get(global, property));
}
extern "C" JSC::EncodedJSValue BakeRegisterProductionChunk(JSC::JSGlobalObject* global, BunString virtualPathName, BunString source) {
JSC::VM& vm = global->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
String string = virtualPathName.toWTFString();
JSC::JSString* key = JSC::jsString(vm, string);
JSC::SourceOrigin origin = JSC::SourceOrigin(WTF::URL(string));
JSC::SourceCode sourceCode = JSC::SourceCode(DevSourceProvider::create(
source.toWTFString(),
origin,
WTFMove(string),
WTF::TextPosition(),
JSC::SourceProviderSourceType::Module
));
global->moduleLoader()->provideFetch(global, key, sourceCode);
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode({}));
return JSC::JSValue::encode(key);
}
} // namespace Bake