mirror of
https://github.com/oven-sh/bun
synced 2026-02-19 23:31:45 +00:00
final steps to getting dd-trace to work (#10568)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// clang-format off
|
||||
#pragma once
|
||||
|
||||
#include "CommonJSModuleRecord.h"
|
||||
@@ -6,6 +7,7 @@
|
||||
#include "isBuiltinModule.h"
|
||||
#include <JavaScriptCore/JSBoundFunction.h>
|
||||
#include <JavaScriptCore/ObjectConstructor.h>
|
||||
#include "PathInlines.h"
|
||||
|
||||
using namespace Zig;
|
||||
using namespace JSC;
|
||||
@@ -92,9 +94,11 @@ static constexpr ASCIILiteral builtinModuleNames[] = {
|
||||
"zlib"_s,
|
||||
};
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleModuleConstructor,
|
||||
(JSC::JSGlobalObject * globalObject,
|
||||
JSC::CallFrame *callFrame)) {
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionDebugNoop, (JSC::JSGlobalObject * globalObject, JSC::CallFrame *callFrame)) {
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleModuleConstructor, (JSC::JSGlobalObject * globalObject, JSC::CallFrame *callFrame)) {
|
||||
// In node, this is supposed to be the actual CommonJSModule constructor.
|
||||
// We are cutting a huge corner by not doing all that work.
|
||||
// This code is only to support babel.
|
||||
@@ -126,20 +130,21 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleModuleConstructor,
|
||||
auto *out = Bun::JSCommonJSModule::create(vm, structure, idString, jsNull(),
|
||||
dirname, SourceCode());
|
||||
|
||||
if (!parentValue.isUndefined())
|
||||
out->putDirect(vm, JSC::Identifier::fromString(vm, "parent"_s), parentValue,
|
||||
0);
|
||||
if (!parentValue.isUndefined()) {
|
||||
out->putDirect(vm, JSC::Identifier::fromString(vm, "parent"_s), parentValue, 0);
|
||||
}
|
||||
|
||||
out->putDirect(
|
||||
vm,
|
||||
JSC::Identifier::fromString(vm, "exports"_s),
|
||||
JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 0),
|
||||
0
|
||||
);
|
||||
|
||||
out->putDirect(vm, JSC::Identifier::fromString(vm, "exports"_s),
|
||||
JSC::constructEmptyObject(globalObject,
|
||||
globalObject->objectPrototype(), 0),
|
||||
0);
|
||||
return JSValue::encode(out);
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionIsBuiltinModule,
|
||||
(JSC::JSGlobalObject * globalObject,
|
||||
JSC::CallFrame *callFrame)) {
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionIsBuiltinModule, (JSC::JSGlobalObject * globalObject, JSC::CallFrame *callFrame)) {
|
||||
JSC::VM &vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
JSValue moduleName = callFrame->argument(0);
|
||||
@@ -163,10 +168,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionWrap, (JSC::JSGlobalObject * globalObject,
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
JSString *prefix = jsString(
|
||||
vm,
|
||||
String(
|
||||
"(function (exports, require, module, __filename, __dirname) { "_s));
|
||||
JSString *prefix = jsString(vm, String( "(function (exports, require, module, __filename, __dirname) { "_s));
|
||||
JSString *suffix = jsString(vm, String("\n});"_s));
|
||||
|
||||
return JSValue::encode(jsString(globalObject, prefix, code, suffix));
|
||||
@@ -191,7 +193,6 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleCreateRequire,
|
||||
throwTypeError(globalObject, scope,
|
||||
makeString("createRequire() was given an invalid URL '"_s,
|
||||
url.string(), "'"_s));
|
||||
;
|
||||
RELEASE_AND_RETURN(scope, JSValue::encode({}));
|
||||
}
|
||||
if (!url.protocolIsFile()) {
|
||||
@@ -207,16 +208,12 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleCreateRequire,
|
||||
scope, JSValue::encode(Bun::JSCommonJSModule::createBoundRequireFunction(
|
||||
vm, globalObject, val)));
|
||||
}
|
||||
extern "C" JSC::EncodedJSValue Resolver__nodeModulePathsForJS(JSGlobalObject *,
|
||||
CallFrame *);
|
||||
extern "C" JSC::EncodedJSValue Resolver__nodeModulePathsForJS(JSGlobalObject *, CallFrame *);
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionFindSourceMap,
|
||||
(JSGlobalObject * globalObject,
|
||||
CallFrame *callFrame)) {
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionFindSourceMap, (JSGlobalObject * globalObject, CallFrame *callFrame)) {
|
||||
auto &vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
throwException(globalObject, scope,
|
||||
createError(globalObject, "Not implemented"_s));
|
||||
throwException(globalObject, scope, createError(globalObject, "module.SourceMap is not yet implemented in Bun"_s));
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
@@ -226,8 +223,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionSyncBuiltinExports,
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionSourceMap, (JSGlobalObject * globalObject,
|
||||
CallFrame *callFrame)) {
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionSourceMap, (JSGlobalObject * globalObject, CallFrame *callFrame)) {
|
||||
auto &vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
throwException(globalObject, scope,
|
||||
@@ -235,9 +231,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionSourceMap, (JSGlobalObject * globalObject,
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName,
|
||||
(JSC::JSGlobalObject * globalObject,
|
||||
JSC::CallFrame *callFrame)) {
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName, (JSC::JSGlobalObject * globalObject, JSC::CallFrame *callFrame)) {
|
||||
JSC::VM &vm = globalObject->vm();
|
||||
|
||||
switch (callFrame->argumentCount()) {
|
||||
@@ -246,7 +240,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName,
|
||||
// not "requires" because "require" could be confusing
|
||||
JSC::throwTypeError(
|
||||
globalObject, scope,
|
||||
"Module._resolveFileName needs 2+ arguments (a string)"_s);
|
||||
"Module._resolveFilename needs 2+ arguments (a string)"_s);
|
||||
scope.release();
|
||||
return JSC::JSValue::encode(JSC::JSValue{});
|
||||
}
|
||||
@@ -257,7 +251,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName,
|
||||
if (moduleName.isUndefinedOrNull()) {
|
||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
JSC::throwTypeError(globalObject, scope,
|
||||
"Module._resolveFileName expects a string"_s);
|
||||
"Module._resolveFilename expects a string"_s);
|
||||
scope.release();
|
||||
return JSC::JSValue::encode(JSC::JSValue{});
|
||||
}
|
||||
@@ -271,17 +265,14 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName,
|
||||
// weird thing.
|
||||
(fromValue.isObject()) {
|
||||
|
||||
if (auto idValue = fromValue.getObject()->getIfPropertyExists(
|
||||
globalObject, Identifier::fromString(vm, "filename"_s))) {
|
||||
if (auto idValue = fromValue.getObject()->getIfPropertyExists(globalObject, Identifier::fromString(vm, "filename"_s))) {
|
||||
if (idValue.isString()) {
|
||||
fromValue = idValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto result =
|
||||
Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName),
|
||||
JSValue::encode(fromValue), false);
|
||||
auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), JSValue::encode(fromValue), false);
|
||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
|
||||
if (!JSC::JSValue::decode(result).isString()) {
|
||||
@@ -332,6 +323,118 @@ JSC_DEFINE_CUSTOM_SETTER(set_resolveFilename,
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" bool ModuleLoader__isBuiltin(const char* data, size_t len);
|
||||
|
||||
struct Parent {
|
||||
JSArray* paths;
|
||||
JSString* filename;
|
||||
};
|
||||
|
||||
Parent getParent(VM&vm, JSGlobalObject* global, JSValue maybe_parent) {
|
||||
Parent value { nullptr, nullptr };
|
||||
if (!maybe_parent.isCell()) {
|
||||
return value;
|
||||
}
|
||||
if (!maybe_parent.isObject()) {
|
||||
return value;
|
||||
}
|
||||
auto parent = maybe_parent.getObject();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
JSValue paths = parent->get(global, Identifier::fromString(vm, "paths"_s));
|
||||
RETURN_IF_EXCEPTION(scope, value);
|
||||
if (paths.isCell()) {
|
||||
value.paths = jsDynamicCast<JSArray*>(paths);
|
||||
}
|
||||
|
||||
JSValue filename = parent->get(global, Identifier::fromString(vm, "filename"_s));
|
||||
RETURN_IF_EXCEPTION(scope, value);
|
||||
if (filename.isString()) {
|
||||
value.filename = filename.toString(global);
|
||||
}
|
||||
RELEASE_AND_RETURN(scope, value);
|
||||
}
|
||||
|
||||
// https://github.com/nodejs/node/blob/40ef9d541ed79470977f90eb445c291b95ab75a0/lib/internal/modules/cjs/loader.js#L895
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveLookupPaths, (JSC::JSGlobalObject * globalObject, JSC::CallFrame *callFrame)) {
|
||||
auto &vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
String request = callFrame->argument(0).toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
auto utf8 = request.utf8();
|
||||
if(ModuleLoader__isBuiltin(utf8.data(), utf8.length())) {
|
||||
return JSC::JSValue::encode(JSC::jsNull());
|
||||
}
|
||||
|
||||
auto parent = getParent(vm, globalObject, callFrame->argument(1));
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
// Check for node modules paths.
|
||||
if (
|
||||
request.characterAt(0) != '.' ||
|
||||
(request.length() > 1 &&
|
||||
request.characterAt(1) != '.' &&
|
||||
request.characterAt(1) != '/' &&
|
||||
#if OS(WINDOWS)
|
||||
request.characterAt(1) != '\\'
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
)
|
||||
) {
|
||||
auto array = JSC::constructArray(globalObject, (ArrayAllocationProfile*)nullptr, nullptr, 0);
|
||||
if (parent.paths) {
|
||||
auto len = parent.paths->length();
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
auto path = parent.paths->getIndex(globalObject, i);
|
||||
array->push(globalObject, path);
|
||||
}
|
||||
}
|
||||
return JSValue::encode(array);
|
||||
}
|
||||
|
||||
JSString* dirname = nullptr;
|
||||
if (parent.filename) {
|
||||
String str = parent.filename->value(globalObject);
|
||||
if (str.endsWith(PLATFORM_SEP_s)) {
|
||||
str = str.substring(0, str.length() - 1);
|
||||
} else if (str.contains(PLATFORM_SEP)) {
|
||||
str = str.substring(0, str.reverseFind(PLATFORM_SEP));
|
||||
}
|
||||
dirname = jsString(vm, str);
|
||||
} else {
|
||||
dirname = jsString(vm, String("."_s));
|
||||
}
|
||||
|
||||
JSValue values[] = { dirname };
|
||||
auto array = JSC::constructArray(
|
||||
globalObject,
|
||||
(ArrayAllocationProfile*)nullptr,
|
||||
values,
|
||||
1
|
||||
);
|
||||
RELEASE_AND_RETURN(scope, JSValue::encode(array));
|
||||
}
|
||||
|
||||
extern "C" JSC::EncodedJSValue NodeModuleModule__findPath(JSGlobalObject*, BunString, JSArray*);
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionFindPath, (JSGlobalObject * globalObject, JSC::CallFrame *callFrame)) {
|
||||
JSC::VM &vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
JSValue request_value = callFrame->argument(0);
|
||||
JSValue paths_value = callFrame->argument(1);
|
||||
|
||||
String request = request_value.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
BunString request_bun_str = Bun::toString(request);
|
||||
|
||||
JSArray* paths = paths_value.isCell() ? jsDynamicCast<JSArray*>(paths_value) : nullptr;
|
||||
|
||||
return NodeModuleModule__findPath(globalObject, request_bun_str, paths);
|
||||
}
|
||||
|
||||
// These two setters are only used if you directly hit
|
||||
// `Module.prototype.require` or `module.require`. When accessing the cjs
|
||||
// require argument, this is a bound version of `require`, which calls into the
|
||||
@@ -370,9 +473,7 @@ namespace Zig {
|
||||
DEFINE_NATIVE_MODULE(NodeModule) {
|
||||
// the default object here is a function, so we cant use the
|
||||
// INIT_NATIVE_MODULE helper
|
||||
|
||||
Zig::GlobalObject *globalObject =
|
||||
reinterpret_cast<Zig::GlobalObject *>(lexicalGlobalObject);
|
||||
Zig::GlobalObject *globalObject = reinterpret_cast<Zig::GlobalObject *>(lexicalGlobalObject);
|
||||
JSC::VM &vm = globalObject->vm();
|
||||
JSC::JSObject *defaultObject = JSC::JSFunction::create(
|
||||
vm, globalObject, 0, "Module"_s, jsFunctionNodeModuleModuleConstructor,
|
||||
@@ -399,58 +500,54 @@ DEFINE_NATIVE_MODULE(NodeModule) {
|
||||
put(Identifier::fromString(vm, "Module"_s), defaultObject);
|
||||
|
||||
// Module._extensions === require.extensions
|
||||
put(Identifier::fromString(vm, "_extensions"_s),
|
||||
globalObject->requireFunctionUnbound()->get(
|
||||
globalObject, Identifier::fromString(vm, "extensions"_s)));
|
||||
put(
|
||||
Identifier::fromString(vm, "_extensions"_s),
|
||||
globalObject->requireFunctionUnbound()->get( globalObject, Identifier::fromString(vm, "extensions"_s))
|
||||
);
|
||||
|
||||
defaultObject->putDirectCustomAccessor(
|
||||
vm, JSC::Identifier::fromString(vm, "_resolveFilename"_s),
|
||||
JSC::CustomGetterSetter::create(vm, get_resolveFilename,
|
||||
set_resolveFilename),
|
||||
JSC::PropertyAttribute::CustomAccessor | 0);
|
||||
putNativeFn(Identifier::fromString(vm, "__resolveFilename"_s),
|
||||
jsFunctionResolveFileName);
|
||||
vm,
|
||||
JSC::Identifier::fromString(vm, "_resolveFilename"_s),
|
||||
JSC::CustomGetterSetter::create(vm, get_resolveFilename, set_resolveFilename),
|
||||
JSC::PropertyAttribute::CustomAccessor | 0
|
||||
);
|
||||
|
||||
putNativeFn(Identifier::fromString(vm, "createRequire"_s),
|
||||
jsFunctionNodeModuleCreateRequire);
|
||||
putNativeFn(Identifier::fromString(vm, "paths"_s),
|
||||
Resolver__nodeModulePathsForJS);
|
||||
putNativeFn(Identifier::fromString(vm, "findSourceMap"_s),
|
||||
jsFunctionFindSourceMap);
|
||||
putNativeFn(Identifier::fromString(vm, "syncBuiltinExports"_s),
|
||||
jsFunctionSyncBuiltinExports);
|
||||
putNativeFn(Identifier::fromString(vm, "__resolveFilename"_s), jsFunctionResolveFileName);
|
||||
putNativeFn(Identifier::fromString(vm, "_resolveLookupPaths"_s), jsFunctionResolveLookupPaths);
|
||||
|
||||
putNativeFn(Identifier::fromString(vm, "createRequire"_s), jsFunctionNodeModuleCreateRequire);
|
||||
putNativeFn(Identifier::fromString(vm, "paths"_s), Resolver__nodeModulePathsForJS);
|
||||
putNativeFn(Identifier::fromString(vm, "findSourceMap"_s), jsFunctionFindSourceMap);
|
||||
putNativeFn(Identifier::fromString(vm, "syncBuiltinExports"_s), jsFunctionSyncBuiltinExports);
|
||||
putNativeFn(Identifier::fromString(vm, "SourceMap"_s), jsFunctionSourceMap);
|
||||
putNativeFn(Identifier::fromString(vm, "isBuiltin"_s),
|
||||
jsFunctionIsBuiltinModule);
|
||||
putNativeFn(Identifier::fromString(vm, "_nodeModulePaths"_s),
|
||||
Resolver__nodeModulePathsForJS);
|
||||
putNativeFn(Identifier::fromString(vm, "isBuiltin"_s), jsFunctionIsBuiltinModule);
|
||||
putNativeFn(Identifier::fromString(vm, "_nodeModulePaths"_s), Resolver__nodeModulePathsForJS);
|
||||
putNativeFn(Identifier::fromString(vm, "wrap"_s), jsFunctionWrap);
|
||||
|
||||
put(Identifier::fromString(vm, "_cache"_s),
|
||||
jsCast<Zig::GlobalObject *>(globalObject)->lazyRequireCacheObject());
|
||||
put(Identifier::fromString(vm, "_cache"_s), jsCast<Zig::GlobalObject *>(globalObject)->lazyRequireCacheObject());
|
||||
put(Identifier::fromString(vm, "globalPaths"_s), constructEmptyArray(globalObject, nullptr, 0));
|
||||
|
||||
put(Identifier::fromString(vm, "globalPaths"_s),
|
||||
constructEmptyArray(globalObject, nullptr, 0));
|
||||
|
||||
auto prototype =
|
||||
constructEmptyObject(globalObject, globalObject->objectPrototype(), 1);
|
||||
auto prototype = constructEmptyObject(globalObject, globalObject->objectPrototype(), 1);
|
||||
prototype->putDirectCustomAccessor(
|
||||
vm, JSC::Identifier::fromString(vm, "require"_s),
|
||||
JSC::CustomGetterSetter::create(vm, getterRequireFunction,
|
||||
setterRequireFunction),
|
||||
0);
|
||||
vm, JSC::Identifier::fromString(vm, "require"_s),
|
||||
JSC::CustomGetterSetter::create(
|
||||
vm,
|
||||
getterRequireFunction,
|
||||
setterRequireFunction
|
||||
),
|
||||
0
|
||||
);
|
||||
|
||||
defaultObject->putDirect(vm, vm.propertyNames->prototype, prototype);
|
||||
|
||||
JSC::JSArray *builtinModules = JSC::JSArray::create(
|
||||
vm,
|
||||
globalObject->arrayStructureForIndexingTypeDuringAllocation(
|
||||
ArrayWithContiguous),
|
||||
countof(builtinModuleNames));
|
||||
vm,
|
||||
globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous),
|
||||
countof(builtinModuleNames)
|
||||
);
|
||||
|
||||
for (unsigned i = 0; i < countof(builtinModuleNames); ++i) {
|
||||
builtinModules->putDirectIndex(
|
||||
globalObject, i, JSC::jsString(vm, String(builtinModuleNames[i])));
|
||||
builtinModules->putDirectIndex(globalObject, i, JSC::jsString(vm, String(builtinModuleNames[i])));
|
||||
}
|
||||
|
||||
put(JSC::Identifier::fromString(vm, "builtinModules"_s), builtinModules);
|
||||
|
||||
Reference in New Issue
Block a user