mirror of
https://github.com/oven-sh/bun
synced 2026-02-06 00:48:55 +00:00
Compare commits
1 Commits
dylan/pyth
...
jarred/red
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df2738ac82 |
1
Makefile
1
Makefile
@@ -1109,6 +1109,7 @@ jsc-copy-headers:
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSTypedArrayViewPrototype.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSTypedArrayPrototypes.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSTypedArrayPrototypes.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSModuleNamespaceObject.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSModuleEnvironment.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSModuleEnvironment.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JIT.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JIT.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/StructureStubInfo.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/StructureStubInfo.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/AccessCase.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/AccessCase.h
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
#include <JavaScriptCore/JSMap.h>
|
||||
|
||||
#include <JavaScriptCore/JSMapInlines.h>
|
||||
#include <JavaScriptCore/JSModuleEnvironment.h>
|
||||
#include <JavaScriptCore/SyntheticModuleRecord.h>
|
||||
|
||||
namespace Bun {
|
||||
using namespace JSC;
|
||||
@@ -247,7 +249,6 @@ const JSC::ClassInfo JSCommonJSModule::s_info = { "Module"_s, &Base::s_info, nul
|
||||
|
||||
JSCommonJSModule* createCommonJSModuleObject(
|
||||
Zig::GlobalObject* globalObject,
|
||||
const ResolvedSource& source,
|
||||
const WTF::String& sourceURL,
|
||||
JSC::JSValue exportsObjectValue,
|
||||
JSC::JSValue requireFunctionValue)
|
||||
@@ -287,6 +288,180 @@ static bool canPerformFastEnumeration(Structure* s)
|
||||
return true;
|
||||
}
|
||||
|
||||
JSC::JSValue evaluateCommonJSModule(
|
||||
Zig::GlobalObject* globalObject,
|
||||
JSC::SyntheticModuleRecord* syntheticModuleRecord,
|
||||
EvalExecutable* executable)
|
||||
{
|
||||
auto sourceURL = syntheticModuleRecord->moduleKey().string().string();
|
||||
auto& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
auto* requireMapKey = jsString(vm, sourceURL);
|
||||
|
||||
unsigned int exportCount = syntheticModuleRecord->exportEntries().size();
|
||||
JSC::JSObject* exportsObject = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype());
|
||||
|
||||
auto index = sourceURL.reverseFind('/', sourceURL.length());
|
||||
JSString* dirname = jsEmptyString(vm);
|
||||
JSString* filename = requireMapKey;
|
||||
if (index != WTF::notFound) {
|
||||
dirname = JSC::jsSubstring(globalObject, requireMapKey, 0, index);
|
||||
}
|
||||
|
||||
globalObject->requireMap()->set(globalObject, requireMapKey, exportsObject);
|
||||
|
||||
JSC::Structure* scopeExtensionObjectStructure = globalObject->commonJSFunctionArgumentsStructure();
|
||||
JSC::JSObject* scopeExtensionObject = JSC::constructEmptyObject(
|
||||
vm,
|
||||
scopeExtensionObjectStructure);
|
||||
|
||||
auto* requireFunction = Zig::ImportMetaObject::createRequireFunction(vm, globalObject, sourceURL);
|
||||
|
||||
auto* moduleObject = createCommonJSModuleObject(globalObject,
|
||||
sourceURL,
|
||||
exportsObject,
|
||||
requireFunction);
|
||||
|
||||
scopeExtensionObject->putDirectOffset(
|
||||
vm,
|
||||
0,
|
||||
moduleObject);
|
||||
|
||||
scopeExtensionObject->putDirectOffset(
|
||||
vm,
|
||||
1,
|
||||
exportsObject);
|
||||
|
||||
scopeExtensionObject->putDirectOffset(
|
||||
vm,
|
||||
2,
|
||||
dirname);
|
||||
|
||||
scopeExtensionObject->putDirectOffset(
|
||||
vm,
|
||||
3,
|
||||
filename);
|
||||
|
||||
scopeExtensionObject->putDirectOffset(
|
||||
vm,
|
||||
4,
|
||||
requireFunction);
|
||||
|
||||
if (UNLIKELY(throwScope.exception())) {
|
||||
globalObject->requireMap()->remove(globalObject, requireMapKey);
|
||||
throwScope.release();
|
||||
return {};
|
||||
}
|
||||
|
||||
auto catchScope = DECLARE_CATCH_SCOPE(vm);
|
||||
|
||||
// Where the magic happens.
|
||||
//
|
||||
// A `with` scope is created containing { module, exports, require }.
|
||||
// We eval() the CommonJS module code
|
||||
// with that scope.
|
||||
//
|
||||
// Doing it that way saves us a roundtrip through C++ <> JS.
|
||||
//
|
||||
// Sidenote: another implementation could use
|
||||
// FunctionExecutable. It looks like there are lots of arguments
|
||||
// to pass to that and it isn't used directly much, so that
|
||||
// seems harder to do correctly.
|
||||
{
|
||||
JSWithScope* withScope = JSWithScope::create(vm, globalObject, globalObject->globalScope(), scopeExtensionObject);
|
||||
auto* globalExtension = globalObject->globalScopeExtension();
|
||||
globalObject->setGlobalScopeExtension(withScope);
|
||||
vm.interpreter.executeEval(executable, globalObject, globalObject->globalScope());
|
||||
globalObject->setGlobalScopeExtension(globalExtension);
|
||||
syntheticModuleRecord->setUserValue(vm, jsUndefined());
|
||||
}
|
||||
|
||||
if (throwScope.exception()) {
|
||||
globalObject->requireMap()->remove(globalObject, requireMapKey);
|
||||
throwScope.release();
|
||||
return {};
|
||||
}
|
||||
|
||||
JSValue result = moduleObject->exportsObject();
|
||||
|
||||
globalObject->requireMap()->set(globalObject, requireMapKey, result);
|
||||
|
||||
// The developer can do something like:
|
||||
//
|
||||
// Object.defineProperty(module, 'exports', {get: getter})
|
||||
//
|
||||
// In which case, the exports object is now a GetterSetter object.
|
||||
//
|
||||
// We can't return a GetterSetter object to ESM code, so we need to call it.
|
||||
if (!result.isEmpty() && (result.isGetterSetter() || result.isCustomGetterSetter())) {
|
||||
auto* clientData = WebCore::clientData(vm);
|
||||
|
||||
// TODO: is there a faster way to call these getters? We shouldn't need to do a full property lookup.
|
||||
//
|
||||
// we use getIfPropertyExists just incase a pathological devleoper did:
|
||||
//
|
||||
// - Object.defineProperty(module, 'exports', {get: getter})
|
||||
// - delete module.exports
|
||||
//
|
||||
result = moduleObject->getIfPropertyExists(globalObject, clientData->builtinNames().exportsPublicName());
|
||||
|
||||
if (UNLIKELY(throwScope.exception())) {
|
||||
// Unlike getters on properties of the exports object
|
||||
// When the exports object itself is a getter and it throws
|
||||
// There's not a lot we can do
|
||||
// so we surface that error
|
||||
globalObject->requireMap()->remove(globalObject, requireMapKey);
|
||||
throwScope.release();
|
||||
}
|
||||
}
|
||||
|
||||
auto* moduleEnvironment = syntheticModuleRecord->moduleEnvironment();
|
||||
|
||||
if (result && result.isObject()) {
|
||||
auto* jsExportsObject = jsCast<JSC::JSObject*>(result);
|
||||
auto defaultKeyword = vm.propertyNames->defaultKeyword;
|
||||
for (auto& exportEntry : syntheticModuleRecord->exportEntries()) {
|
||||
PropertyName exportName = exportEntry.value.localName;
|
||||
|
||||
if (exportName == defaultKeyword) {
|
||||
continue;
|
||||
} else if (exportName.isSymbol())
|
||||
continue;
|
||||
|
||||
JSValue exportValue = jsExportsObject->getIfPropertyExists(globalObject, exportName);
|
||||
if (UNLIKELY(catchScope.exception())) {
|
||||
catchScope.clearException();
|
||||
continue;
|
||||
}
|
||||
|
||||
constexpr bool shouldThrowReadOnlyError = false;
|
||||
constexpr bool ignoreReadOnlyErrors = true;
|
||||
bool putResult = false;
|
||||
symbolTablePutTouchWatchpointSet(moduleEnvironment, globalObject, exportName, exportValue, shouldThrowReadOnlyError, ignoreReadOnlyErrors, putResult);
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
constexpr bool shouldThrowReadOnlyError = false;
|
||||
constexpr bool ignoreReadOnlyErrors = true;
|
||||
bool putResult = false;
|
||||
PropertyName exportName = vm.propertyNames->defaultKeyword;
|
||||
JSValue exportValue = result;
|
||||
symbolTablePutTouchWatchpointSet(moduleEnvironment, globalObject, exportName, exportValue, shouldThrowReadOnlyError, ignoreReadOnlyErrors, putResult);
|
||||
}
|
||||
|
||||
{
|
||||
constexpr bool shouldThrowReadOnlyError = false;
|
||||
constexpr bool ignoreReadOnlyErrors = true;
|
||||
bool putResult = false;
|
||||
PropertyName exportName = Identifier::fromUid(vm.symbolRegistry().symbolForKey("module"_s));
|
||||
JSValue exportValue = moduleObject;
|
||||
symbolTablePutTouchWatchpointSet(moduleEnvironment, globalObject, exportName, exportValue, shouldThrowReadOnlyError, ignoreReadOnlyErrors, putResult);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
JSC::SourceCode createCommonJSModule(
|
||||
Zig::GlobalObject* globalObject,
|
||||
ResolvedSource source)
|
||||
@@ -299,218 +474,52 @@ JSC::SourceCode createCommonJSModule(
|
||||
[source, sourceURL](JSC::JSGlobalObject* lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4>& exportNames,
|
||||
JSC::MarkedArgumentBuffer& exportValues) -> void {
|
||||
JSC::MarkedArgumentBuffer& exportValues) -> JSValue {
|
||||
Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
auto& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
auto sourceCodeString = Zig::toString(source.source_code);
|
||||
auto* requireMapKey = jsString(vm, sourceURL);
|
||||
|
||||
JSC::JSObject* exportsObject = source.commonJSExportsLen < 64
|
||||
? JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), source.commonJSExportsLen)
|
||||
: JSC::constructEmptyObject(globalObject, globalObject->objectPrototype());
|
||||
|
||||
auto index = sourceURL.reverseFind('/', sourceURL.length());
|
||||
JSString* dirname = jsEmptyString(vm);
|
||||
JSString* filename = requireMapKey;
|
||||
if (index != WTF::notFound) {
|
||||
dirname = JSC::jsSubstring(globalObject, requireMapKey, 0, index);
|
||||
}
|
||||
|
||||
globalObject->requireMap()->set(globalObject, requireMapKey, exportsObject);
|
||||
auto& vm = globalObject->vm();
|
||||
|
||||
JSC::SourceCode inputSource(
|
||||
JSC::StringSourceProvider::create(sourceCodeString,
|
||||
JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(sourceURL)),
|
||||
sourceURL, TextPosition()));
|
||||
|
||||
JSC::Structure* scopeExtensionObjectStructure = globalObject->commonJSFunctionArgumentsStructure();
|
||||
JSC::JSObject* scopeExtensionObject = JSC::constructEmptyObject(
|
||||
vm,
|
||||
scopeExtensionObjectStructure);
|
||||
|
||||
auto* requireFunction = Zig::ImportMetaObject::createRequireFunction(vm, globalObject, sourceURL);
|
||||
|
||||
auto* moduleObject = createCommonJSModuleObject(globalObject,
|
||||
source,
|
||||
sourceURL,
|
||||
exportsObject,
|
||||
requireFunction);
|
||||
scopeExtensionObject->putDirectOffset(
|
||||
vm,
|
||||
0,
|
||||
moduleObject);
|
||||
|
||||
scopeExtensionObject->putDirectOffset(
|
||||
vm,
|
||||
1,
|
||||
exportsObject);
|
||||
|
||||
scopeExtensionObject->putDirectOffset(
|
||||
vm,
|
||||
2,
|
||||
dirname);
|
||||
|
||||
scopeExtensionObject->putDirectOffset(
|
||||
vm,
|
||||
3,
|
||||
filename);
|
||||
|
||||
scopeExtensionObject->putDirectOffset(
|
||||
vm,
|
||||
4,
|
||||
requireFunction);
|
||||
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
auto* executable = JSC::DirectEvalExecutable::create(
|
||||
globalObject, inputSource, DerivedContextType::None, NeedsClassFieldInitializer::No, PrivateBrandRequirement::None,
|
||||
false, false, EvalContextType::None, nullptr, nullptr, ECMAMode::sloppy());
|
||||
|
||||
if (UNLIKELY(!executable && !throwScope.exception())) {
|
||||
// I'm not sure if this case happens, but it's better to be safe than sorry.
|
||||
throwSyntaxError(globalObject, throwScope, "Failed to compile CommonJS module."_s);
|
||||
throwSyntaxError(globalObject, throwScope, "Failed to create CommonJS module"_s);
|
||||
}
|
||||
|
||||
if (UNLIKELY(throwScope.exception())) {
|
||||
globalObject->requireMap()->remove(globalObject, requireMapKey);
|
||||
throwScope.release();
|
||||
return;
|
||||
return jsUndefined();
|
||||
}
|
||||
|
||||
auto catchScope = DECLARE_CATCH_SCOPE(vm);
|
||||
|
||||
// Where the magic happens.
|
||||
//
|
||||
// A `with` scope is created containing { module, exports, require }.
|
||||
// We eval() the CommonJS module code
|
||||
// with that scope.
|
||||
//
|
||||
// Doing it that way saves us a roundtrip through C++ <> JS.
|
||||
//
|
||||
// Sidenote: another implementation could use
|
||||
// FunctionExecutable. It looks like there are lots of arguments
|
||||
// to pass to that and it isn't used directly much, so that
|
||||
// seems harder to do correctly.
|
||||
{
|
||||
JSWithScope* withScope = JSWithScope::create(vm, globalObject, globalObject->globalScope(), scopeExtensionObject);
|
||||
vm.interpreter.executeEval(executable, globalObject, withScope);
|
||||
|
||||
if (UNLIKELY(catchScope.exception())) {
|
||||
auto returnedException = catchScope.exception();
|
||||
catchScope.clearException();
|
||||
JSC::throwException(globalObject, throwScope, returnedException);
|
||||
}
|
||||
}
|
||||
|
||||
if (throwScope.exception()) {
|
||||
globalObject->requireMap()->remove(globalObject, requireMapKey);
|
||||
throwScope.release();
|
||||
return;
|
||||
}
|
||||
|
||||
JSValue result = moduleObject->exportsObject();
|
||||
|
||||
// The developer can do something like:
|
||||
//
|
||||
// Object.defineProperty(module, 'exports', {get: getter})
|
||||
//
|
||||
// In which case, the exports object is now a GetterSetter object.
|
||||
//
|
||||
// We can't return a GetterSetter object to ESM code, so we need to call it.
|
||||
if (!result.isEmpty() && (result.isGetterSetter() || result.isCustomGetterSetter())) {
|
||||
auto* clientData = WebCore::clientData(vm);
|
||||
|
||||
// TODO: is there a faster way to call these getters? We shouldn't need to do a full property lookup.
|
||||
//
|
||||
// we use getIfPropertyExists just incase a pathological devleoper did:
|
||||
//
|
||||
// - Object.defineProperty(module, 'exports', {get: getter})
|
||||
// - delete module.exports
|
||||
//
|
||||
result = moduleObject->getIfPropertyExists(globalObject, clientData->builtinNames().exportsPublicName());
|
||||
|
||||
if (UNLIKELY(throwScope.exception())) {
|
||||
// Unlike getters on properties of the exports object
|
||||
// When the exports object itself is a getter and it throws
|
||||
// There's not a lot we can do
|
||||
// so we surface that error
|
||||
globalObject->requireMap()->remove(globalObject, requireMapKey);
|
||||
throwScope.release();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
globalObject->requireMap()->set(globalObject, requireMapKey, result);
|
||||
size_t exportNamesLen = source.commonJSExportsLen > 0 && source.commonJSExportsLen < std::numeric_limits<uint32_t>::max() ? source.commonJSExportsLen : 0;
|
||||
exportNames.reserveCapacity(exportNamesLen + 3);
|
||||
exportValues.ensureCapacity(exportNamesLen + 3);
|
||||
|
||||
exportNames.append(vm.propertyNames->defaultKeyword);
|
||||
exportValues.append(result);
|
||||
exportValues.append(jsUndefined());
|
||||
|
||||
// This exists to tell ImportMetaObject.ts that this is a CommonJS module.
|
||||
exportNames.append(Identifier::fromUid(vm.symbolRegistry().symbolForKey("CommonJS"_s)));
|
||||
exportValues.append(jsNumber(0));
|
||||
|
||||
// This strong reference exists because otherwise it will crash when the finalizer runs.
|
||||
// This exists to tell ImportMetaObject.ts that this is a CommonJS module.
|
||||
exportNames.append(Identifier::fromUid(vm.symbolRegistry().symbolForKey("module"_s)));
|
||||
exportValues.append(moduleObject);
|
||||
exportValues.append(jsUndefined());
|
||||
|
||||
if (result.isObject()) {
|
||||
auto* exports = asObject(result);
|
||||
|
||||
auto* structure = exports->structure();
|
||||
uint32_t size = structure->inlineSize() + structure->outOfLineSize();
|
||||
exportNames.reserveCapacity(size + 3);
|
||||
exportValues.ensureCapacity(size + 3);
|
||||
|
||||
if (canPerformFastEnumeration(structure)) {
|
||||
exports->structure()->forEachProperty(vm, [&](const PropertyTableEntry& entry) -> bool {
|
||||
auto key = entry.key();
|
||||
if (key->isSymbol() || key == vm.propertyNames->defaultKeyword || entry.attributes() & PropertyAttribute::DontEnum)
|
||||
return true;
|
||||
|
||||
exportNames.append(Identifier::fromUid(vm, key));
|
||||
|
||||
JSValue value = exports->getDirect(entry.offset());
|
||||
|
||||
exportValues.append(value);
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
JSC::PropertyNameArray properties(vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude);
|
||||
exports->methodTable()->getOwnPropertyNames(exports, globalObject, properties, DontEnumPropertiesMode::Exclude);
|
||||
if (throwScope.exception()) {
|
||||
throwScope.release();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto property : properties) {
|
||||
if (UNLIKELY(property.isEmpty() || property.isNull()))
|
||||
continue;
|
||||
|
||||
// ignore constructor
|
||||
if (property == vm.propertyNames->constructor)
|
||||
continue;
|
||||
|
||||
if (property.isSymbol() || property.isPrivateName() || property == vm.propertyNames->defaultKeyword)
|
||||
continue;
|
||||
|
||||
JSC::PropertySlot slot(exports, PropertySlot::InternalMethodType::Get);
|
||||
if (!exports->getPropertySlot(globalObject, property, slot))
|
||||
continue;
|
||||
|
||||
exportNames.append(property);
|
||||
|
||||
JSValue getterResult = slot.getValue(globalObject, property);
|
||||
|
||||
// If it throws, we keep them in the exports list, but mark it as undefined
|
||||
// This is consistent with what Node.js does.
|
||||
if (catchScope.exception()) {
|
||||
catchScope.clearException();
|
||||
getterResult = jsUndefined();
|
||||
}
|
||||
|
||||
exportValues.append(getterResult);
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < exportNamesLen; i++) {
|
||||
auto str = Zig::toStringCopy(source.commonJSExports[i]);
|
||||
exportNames.append(Identifier::fromString(vm, str));
|
||||
exportValues.append(jsUndefined());
|
||||
}
|
||||
vm.heap.collectAsync();
|
||||
return executable;
|
||||
},
|
||||
SourceOrigin(WTF::URL::fileURLWithFileSystemPath(sourceURL)),
|
||||
sourceURL));
|
||||
|
||||
@@ -6,6 +6,8 @@ class GlobalObject;
|
||||
}
|
||||
namespace JSC {
|
||||
class SourceCode;
|
||||
class EvalExecutable;
|
||||
class SyntheticModuleRecord;
|
||||
}
|
||||
|
||||
namespace Bun {
|
||||
@@ -17,4 +19,9 @@ JSC::SourceCode createCommonJSModule(
|
||||
Zig::GlobalObject* globalObject,
|
||||
ResolvedSource source);
|
||||
|
||||
JSC::JSValue evaluateCommonJSModule(
|
||||
Zig::GlobalObject* globalObject,
|
||||
JSC::SyntheticModuleRecord* syntheticModuleRecord,
|
||||
EvalExecutable* executable);
|
||||
|
||||
} // namespace Bun
|
||||
|
||||
@@ -178,6 +178,7 @@ namespace JSCastingHelpers = JSC::JSCastingHelpers;
|
||||
#include "CallSitePrototype.h"
|
||||
#include "DOMWrapperWorld-class.h"
|
||||
#include "CommonJSModuleRecord.h"
|
||||
#include "JavaScriptCore/SyntheticModuleRecord.h"
|
||||
|
||||
constexpr size_t DEFAULT_ERROR_STACK_TRACE_LIMIT = 10;
|
||||
|
||||
@@ -4113,6 +4114,16 @@ JSC::JSValue GlobalObject::moduleLoaderEvaluate(JSGlobalObject* globalObject,
|
||||
return scriptFetcher;
|
||||
}
|
||||
|
||||
if (JSC::SyntheticModuleRecord* record = jsDynamicCast<JSC::SyntheticModuleRecord*>(moduleRecordValue)) {
|
||||
if (JSValue userValue = record->userValue()) {
|
||||
auto* evalExecutable = jsDynamicCast<JSC::EvalExecutable*>(userValue);
|
||||
return Bun::evaluateCommonJSModule(
|
||||
reinterpret_cast<Zig::GlobalObject*>(globalObject),
|
||||
record,
|
||||
evalExecutable);
|
||||
}
|
||||
}
|
||||
|
||||
JSC::JSValue result = moduleLoader->evaluateNonVirtual(globalObject, key, moduleRecordValue,
|
||||
scriptFetcher, sentValue, resumeMode);
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionIsCryptoKey, (JSC::JSGlobalObject * globalObj
|
||||
}
|
||||
|
||||
namespace Bun {
|
||||
void generateNodeUtilTypesSourceCode(JSC::JSGlobalObject* lexicalGlobalObject,
|
||||
JSC::JSValue generateNodeUtilTypesSourceCode(JSC::JSGlobalObject* lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4>& exportNames,
|
||||
JSC::MarkedArgumentBuffer& exportValues)
|
||||
@@ -379,5 +379,7 @@ void generateNodeUtilTypesSourceCode(JSC::JSGlobalObject* lexicalGlobalObject,
|
||||
|
||||
exportNames.append(JSC::Identifier::fromString(vm, "default"_s));
|
||||
exportValues.append(defaultObject);
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
namespace Bun {
|
||||
using namespace WebCore;
|
||||
|
||||
void generateNodeUtilTypesSourceCode(JSC::JSGlobalObject* lexicalGlobalObject,
|
||||
JSC::JSValue generateNodeUtilTypesSourceCode(JSC::JSGlobalObject* lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4>& exportNames,
|
||||
JSC::MarkedArgumentBuffer& exportValues);
|
||||
|
||||
@@ -18,10 +18,11 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNotImplemented,
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
inline void generateBufferSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) {
|
||||
inline JSValue
|
||||
generateBufferSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) {
|
||||
JSC::VM &vm = lexicalGlobalObject->vm();
|
||||
GlobalObject *globalObject =
|
||||
reinterpret_cast<GlobalObject *>(lexicalGlobalObject);
|
||||
@@ -105,6 +106,7 @@ inline void generateBufferSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
|
||||
exportNames.append(vm.propertyNames->defaultKeyword);
|
||||
exportValues.append(defaultObject);
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Zig
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
namespace Zig {
|
||||
using namespace WebCore;
|
||||
|
||||
inline void generateEventsSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) {
|
||||
inline JSValue
|
||||
generateEventsSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) {
|
||||
JSC::VM &vm = lexicalGlobalObject->vm();
|
||||
GlobalObject *globalObject =
|
||||
reinterpret_cast<GlobalObject *>(lexicalGlobalObject);
|
||||
@@ -53,6 +54,8 @@ inline void generateEventsSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
|
||||
exportNames.append(JSC::Identifier::fromString(vm, "default"_s));
|
||||
exportValues.append(eventEmitterModuleCJS);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Zig
|
||||
|
||||
@@ -116,10 +116,10 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName,
|
||||
}
|
||||
|
||||
namespace Zig {
|
||||
void generateNodeModuleModule(JSC::JSGlobalObject *globalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) {
|
||||
JSValue generateNodeModuleModule(JSC::JSGlobalObject *globalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) {
|
||||
JSC::VM &vm = globalObject->vm();
|
||||
|
||||
exportValues.append(JSFunction::create(
|
||||
@@ -185,5 +185,7 @@ void generateNodeModuleModule(JSC::JSGlobalObject *globalObject,
|
||||
builtinModules->putDirectIndex(globalObject, 6,
|
||||
JSC::jsString(vm, String("bun:sqlite"_s)));
|
||||
exportValues.append(builtinModules);
|
||||
|
||||
return {};
|
||||
}
|
||||
} // namespace Zig
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
namespace Zig {
|
||||
|
||||
// node:module
|
||||
void generateNodeModuleModule(JSC::JSGlobalObject *globalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues);
|
||||
JSValue generateNodeModuleModule(JSC::JSGlobalObject *globalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues);
|
||||
|
||||
} // namespace Zig
|
||||
@@ -9,7 +9,7 @@ generateObjectModuleSourceCode(JSC::JSGlobalObject *globalObject,
|
||||
return [object](JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) -> void {
|
||||
JSC::MarkedArgumentBuffer &exportValues) -> JSValue {
|
||||
JSC::VM &vm = lexicalGlobalObject->vm();
|
||||
GlobalObject *globalObject =
|
||||
reinterpret_cast<GlobalObject *>(lexicalGlobalObject);
|
||||
@@ -24,6 +24,8 @@ generateObjectModuleSourceCode(JSC::JSGlobalObject *globalObject,
|
||||
exportNames.append(entry);
|
||||
exportValues.append(object->get(globalObject, entry));
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
}
|
||||
} // namespace Zig
|
||||
@@ -35,10 +35,11 @@ JSC_DEFINE_CUSTOM_SETTER(jsFunctionProcessModuleCommonJSSetter,
|
||||
->putDirect(vm, propertyName, JSValue::decode(encodedValue), 0);
|
||||
}
|
||||
|
||||
inline void generateProcessSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) {
|
||||
inline JSValue
|
||||
generateProcessSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) {
|
||||
JSC::VM &vm = lexicalGlobalObject->vm();
|
||||
GlobalObject *globalObject =
|
||||
reinterpret_cast<GlobalObject *>(lexicalGlobalObject);
|
||||
@@ -71,6 +72,8 @@ inline void generateProcessSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
jsFunctionProcessModuleCommonJSSetter),
|
||||
0);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Zig
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
namespace Zig {
|
||||
|
||||
inline void
|
||||
inline JSValue
|
||||
generateStringDecoderSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
@@ -28,6 +28,7 @@ generateStringDecoderSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
|
||||
exportNames.append(vm.propertyNames->defaultKeyword);
|
||||
exportValues.append(defaultObject);
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Zig
|
||||
|
||||
@@ -31,10 +31,10 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNotImplementedYet,
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
inline void generateTTYSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) {
|
||||
inline JSValue generateTTYSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
Vector<JSC::Identifier, 4> &exportNames,
|
||||
JSC::MarkedArgumentBuffer &exportValues) {
|
||||
JSC::VM &vm = lexicalGlobalObject->vm();
|
||||
GlobalObject *globalObject =
|
||||
reinterpret_cast<GlobalObject *>(lexicalGlobalObject);
|
||||
@@ -73,6 +73,8 @@ inline void generateTTYSourceCode(JSC::JSGlobalObject *lexicalGlobalObject,
|
||||
|
||||
exportNames.append(vm.propertyNames->defaultKeyword);
|
||||
exportValues.append(tty);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Zig
|
||||
|
||||
@@ -17603,6 +17603,41 @@ fn NewParser_(
|
||||
|
||||
// rewrite `module.exports` to `exports`
|
||||
return p.newExpr(E.Identifier{ .ref = p.exports_ref }, name_loc);
|
||||
} else if (p.options.features.commonjs_at_runtime and strings.eqlComptime(name, "exports")) {
|
||||
|
||||
// Detect if we are doing
|
||||
//
|
||||
// module.exports = {
|
||||
// foo: "bar"
|
||||
// }
|
||||
//
|
||||
// Note that it cannot be any of these:
|
||||
//
|
||||
// module.exports += { };
|
||||
// delete module.exports = {};
|
||||
// module.exports()
|
||||
if (!(identifier_opts.is_call_target or identifier_opts.is_delete_target) and
|
||||
identifier_opts.assign_target == .replace and
|
||||
p.stmt_expr_value == .e_binary and
|
||||
p.stmt_expr_value.e_binary.op == .bin_assign and
|
||||
!(p.stmt_expr_value.e_binary.right.data != .e_object or
|
||||
p.stmt_expr_value.e_binary.left.data != .e_dot or
|
||||
!strings.eqlComptime(p.stmt_expr_value.e_binary.left.data.e_dot.name, "exports") or
|
||||
p.stmt_expr_value.e_binary.left.data.e_dot.target.data != .e_identifier or
|
||||
!p.stmt_expr_value.e_binary.left.data.e_dot.target.data.e_identifier.ref.eql(p.module_ref)))
|
||||
{
|
||||
const props: []const G.Property = p.stmt_expr_value.e_binary.right.data.e_object.properties.slice();
|
||||
for (props) |prop| {
|
||||
// only worry about string literals
|
||||
if (prop.key == null or
|
||||
prop.key.?.data != .e_string or prop.key.?.data.e_string.len() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_ = p.commonjs_export_names.getOrPut(p.allocator, prop.key.?.data.e_string.slice(p.allocator)) catch unreachable;
|
||||
}
|
||||
}
|
||||
} else if (p.options.bundle and strings.eqlComptime(name, "id") and identifier_opts.assign_target == .none) {
|
||||
// inline module.id
|
||||
p.ignoreUsage(p.module_ref);
|
||||
|
||||
Reference in New Issue
Block a user