Compare commits

...

1 Commits

Author SHA1 Message Date
John-David Dalton
eaeedd1274 Make process.binding errors more specific to get better idea of which methods to support 2024-02-15 09:12:58 -08:00
4 changed files with 83 additions and 69 deletions

View File

@@ -171,7 +171,7 @@ static JSValue constructVersions(VM& vm, JSObject* processObject)
object->putDirect(vm, JSC::Identifier::fromString(vm, "usockets"_s),
JSC::JSValue(JSC::jsString(vm, makeString(Bun__versions_usockets))), 0);
object->putDirect(vm, JSC::Identifier::fromString(vm, "v8"_s), JSValue(JSC::jsString(vm, makeString("11.3.244.8-node.15"_s))), 0);
object->putDirect(vm, JSC::Identifier::fromString(vm, "v8"_s), JSValue(JSC::jsString(vm, String("11.3.244.8-node.15"_s))), 0);
#if OS(WINDOWS)
object->putDirect(vm, JSC::Identifier::fromString(vm, "uv"_s), JSValue(JSC::jsString(vm, makeString(uv_version_string()))), 0);
#else
@@ -224,19 +224,6 @@ static void dispatchExitInternal(JSC::JSGlobalObject* globalObject, Process* pro
emitter.emit(event, arguments);
}
JSC_DEFINE_CUSTOM_SETTER(Process_defaultSetter,
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
{
JSC::VM& vm = globalObject->vm();
JSC::JSObject* thisObject = JSC::jsDynamicCast<JSC::JSObject*>(JSValue::decode(thisValue));
if (value)
thisObject->putDirect(vm, propertyName, JSValue::decode(value), 0);
return true;
}
extern "C" bool Bun__resolveEmbeddedNodeFile(void*, BunString*);
JSC_DECLARE_HOST_FUNCTION(Process_functionDlopen);
@@ -1485,28 +1472,10 @@ static JSValue constructProcessReportObject(VM& vm, JSObject* processObject)
static JSValue constructProcessConfigObject(VM& vm, JSObject* processObject)
{
auto* globalObject = processObject->globalObject();
// target_defaults:
// { cflags: [],
// default_configuration: 'Release',
// defines: [],
// include_dirs: [],
// libraries: [] },
// variables:
// {
// host_arch: 'x64',
// napi_build_version: 5,
// node_install_npm: 'true',
// node_prefix: '',
// node_shared_cares: 'false',
// node_shared_http_parser: 'false',
// node_shared_libuv: 'false',
// node_shared_zlib: 'false',
// node_use_openssl: 'true',
// node_shared_openssl: 'false',
// strict_aliasing: 'true',
// target_arch: 'x64',
// v8_use_snapshot: 1
// }
// target_defaults: {},
// variables: {
// v8_enable_i18n_support: 1,
// },
// }
JSC::JSObject* config = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 2);
JSC::JSObject* variables = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 1);
@@ -1514,7 +1483,6 @@ static JSValue constructProcessConfigObject(VM& vm, JSObject* processObject)
JSC::jsNumber(1), 0);
config->putDirect(vm, JSC::Identifier::fromString(vm, "target_defaults"_s), JSC::constructEmptyObject(globalObject), 0);
config->putDirect(vm, JSC::Identifier::fromString(vm, "variables"_s), variables, 0);
return config;
}
@@ -1766,17 +1734,57 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionAssert, (JSGlobalObject * globalObject,
return JSValue::encode(jsUndefined());
}
#define PROCESS_BINDING_NOT_IMPLEMENTED_ISSUE(str, issue) \
{ \
throwScope.throwException(globalObject, createError(globalObject, String("process.binding(\"" str "\") is not implemented in Bun. Track the status & thumbs up the issue: https://github.com/oven-sh/bun/issues/" issue ""_s))); \
return JSValue::encode(JSValue {}); \
inline JSC::EncodedJSValue createProcessBindingNotImplementedProxy(
JSC::JSGlobalObject* globalObject,
JSC::VM& vm,
WTF::String handlerGetTrapCode)
{
auto* nullProtoStruct = globalObject->nullPrototypeObjectStructure();
auto&& origin = SourceOrigin(WTF::URL());
auto* target = JSC::constructEmptyObject(vm, nullProtoStruct);
auto* handler = JSC::constructEmptyObject(vm, nullProtoStruct);
SourceCode handlerGetTrapSourceCode
= JSC::makeSource(
handlerGetTrapCode,
origin,
JSC::SourceTaintedOrigin::Untainted);
JSFunction* func
= JSFunction::create(
vm,
JSC::createBuiltinExecutable(
vm,
handlerGetTrapSourceCode,
Identifier(),
ImplementationVisibility::Private,
ConstructorKind::None,
ConstructAbility::CannotConstruct,
InlineAttribute::None)
->link(vm, nullptr, handlerGetTrapSourceCode),
static_cast<JSC::JSGlobalObject*>(globalObject));
handler->putDirect(vm, Identifier::fromString(vm, "get"_s), func, 0);
return JSValue::encode(ProxyObject::create(globalObject, target, handler));
}
#define PROCESS_BINDING_NOT_IMPLEMENTED_1_ARGS(moduleName) \
{ \
auto handlerGetTrapCode = String( \
"(function (_target,propertyKey){" \
"throw new Error(`process.binding(\"" moduleName "\").${propertyKey} is not implemented in Bun. If that breaks something, please file an issue and include a reproducible code sample.`)" \
"})"_s); \
return createProcessBindingNotImplementedProxy(globalObject, vm, handlerGetTrapCode); \
}
#define PROCESS_BINDING_NOT_IMPLEMENTED(str) \
{ \
throwScope.throwException(globalObject, createError(globalObject, String("process.binding(\"" str "\") is not implemented in Bun. If that breaks something, please file an issue and include a reproducible code sample."_s))); \
return JSValue::encode(JSValue {}); \
#define PROCESS_BINDING_NOT_IMPLEMENTED_2_ARGS(moduleName, issue) \
{ \
auto handlerGetTrapCode = String( \
"(function (_target,propertyKey){" \
"throw new Error(`process.binding(\"" moduleName "\").${propertyKey} is not implemented in Bun. Track the status, thumbs up the issue, & report the binding property name: https://github.com/oven-sh/bun/issues/" issue ".`)" \
"})"_s); \
return createProcessBindingNotImplementedProxy(globalObject, vm, handlerGetTrapCode); \
}
#define GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
#define PROCESS_BINDING_NOT_IMPLEMENTED_MACRO_CHOOSER(...) \
GET_3RD_ARG(__VA_ARGS__, PROCESS_BINDING_NOT_IMPLEMENTED_2_ARGS, \
PROCESS_BINDING_NOT_IMPLEMENTED_1_ARGS)
#define PROCESS_BINDING_NOT_IMPLEMENTED(...) PROCESS_BINDING_NOT_IMPLEMENTED_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
inline JSValue processBindingUtil(Zig::GlobalObject* globalObject, JSC::VM& vm)
{
@@ -1796,34 +1804,34 @@ inline JSValue processBindingConfig(Zig::GlobalObject* globalObject, JSC::VM& vm
#else
config->putDirect(vm, Identifier::fromString(vm, "isDebugBuild"_s), jsBoolean(false), 0);
#endif
config->putDirect(vm, Identifier::fromString(vm, "hasOpenSSL"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "fipsMode"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "hasIntl"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "hasTracing"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "hasNodeOptions"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "hasInspector"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "noBrowserGlobals"_s), jsBoolean(false), 0);
config->putDirect(vm, Identifier::fromString(vm, "bits"_s), jsNumber(64), 0);
config->putDirect(vm, Identifier::fromString(vm, "fipsMode"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "hasInspector"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "hasIntl"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "hasNodeOptions"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "hasOpenSSL"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "hasTracing"_s), jsBoolean(true), 0);
config->putDirect(vm, Identifier::fromString(vm, "noBrowserGlobals"_s), jsBoolean(false), 0);
return config;
}
JSC_DEFINE_HOST_FUNCTION(Process_functionBinding, (JSGlobalObject * jsGlobalObject, CallFrame* callFrame))
JSC_DEFINE_HOST_FUNCTION(Process_functionBinding, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
auto& vm = jsGlobalObject->vm();
auto lexicalGlobalObject = jsCast<Zig::GlobalObject*>(globalObject);
auto& vm = globalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto globalObject = jsCast<Zig::GlobalObject*>(jsGlobalObject);
auto process = jsCast<Process*>(globalObject->processObject());
auto moduleName = callFrame->argument(0).toWTFString(globalObject);
auto process = jsCast<Process*>(lexicalGlobalObject->processObject());
// clang-format off
if (moduleName == "async_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("async_wrap");
if (moduleName == "buffer"_s) PROCESS_BINDING_NOT_IMPLEMENTED_ISSUE("buffer", "2020");
if (moduleName == "buffer"_s) PROCESS_BINDING_NOT_IMPLEMENTED("buffer", "2020");
if (moduleName == "cares_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("cares_wrap");
if (moduleName == "config"_s) return JSValue::encode(processBindingConfig(globalObject, vm));
if (moduleName == "constants"_s) return JSValue::encode(globalObject->processBindingConstants());
if (moduleName == "config"_s) return JSValue::encode(processBindingConfig(lexicalGlobalObject, vm));
if (moduleName == "constants"_s) return JSValue::encode(lexicalGlobalObject->processBindingConstants());
if (moduleName == "contextify"_s) PROCESS_BINDING_NOT_IMPLEMENTED("contextify");
if (moduleName == "crypto"_s) PROCESS_BINDING_NOT_IMPLEMENTED("crypto");
if (moduleName == "fs"_s) PROCESS_BINDING_NOT_IMPLEMENTED_ISSUE("fs", "3546");
if (moduleName == "fs"_s) PROCESS_BINDING_NOT_IMPLEMENTED("fs", "3546");
if (moduleName == "fs_event_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("fs_event_wrap");
if (moduleName == "http_parser"_s) PROCESS_BINDING_NOT_IMPLEMENTED("http_parser");
if (moduleName == "icu"_s) PROCESS_BINDING_NOT_IMPLEMENTED("icu");
@@ -1835,13 +1843,13 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionBinding, (JSGlobalObject * jsGlobalObje
if (moduleName == "process_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("process_wrap");
if (moduleName == "signal_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("signal_wrap");
if (moduleName == "spawn_sync"_s) PROCESS_BINDING_NOT_IMPLEMENTED("spawn_sync");
if (moduleName == "stream_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED_ISSUE("stream_wrap", "4957");
if (moduleName == "stream_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("stream_wrap", "4957");
if (moduleName == "tcp_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("tcp_wrap");
if (moduleName == "tls_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("tls_wrap");
if (moduleName == "tty_wrap"_s) return JSValue::encode(Bun::createNodeTTYWrapObject(globalObject));
if (moduleName == "udp_wrap"_s) PROCESS_BINDING_NOT_IMPLEMENTED("udp_wrap");
if (moduleName == "url"_s) PROCESS_BINDING_NOT_IMPLEMENTED("url");
if (moduleName == "util"_s) return JSValue::encode(processBindingUtil(globalObject, vm));
if (moduleName == "util"_s) return JSValue::encode(processBindingUtil(lexicalGlobalObject, vm));
if (moduleName == "uv"_s) return JSValue::encode(process->bindingUV());
if (moduleName == "v8"_s) PROCESS_BINDING_NOT_IMPLEMENTED("v8");
if (moduleName == "zlib"_s) PROCESS_BINDING_NOT_IMPLEMENTED("zlib");

View File

@@ -33,7 +33,9 @@ static void maybeAddCodeCoverage(JSC::VM& vm, const JSC::SourceCode& code)
#define INTERNAL_MODULE_REGISTRY_GENERATE_(globalObject, vm, SOURCE, moduleName, urlString) \
auto throwScope = DECLARE_THROW_SCOPE(vm); \
auto&& origin = SourceOrigin(WTF::URL(urlString)); \
SourceCode source = JSC::makeSource(SOURCE, origin, \
SourceCode source = JSC::makeSource( \
SOURCE, \
origin, \
JSC::SourceTaintedOrigin::Untainted, \
moduleName); \
maybeAddCodeCoverage(vm, source); \
@@ -41,7 +43,8 @@ static void maybeAddCodeCoverage(JSC::VM& vm, const JSC::SourceCode& code)
= JSFunction::create( \
vm, \
createBuiltinExecutable( \
vm, source, \
vm, \
source, \
Identifier(), \
ImplementationVisibility::Public, \
ConstructorKind::None, \

View File

@@ -1,4 +1,10 @@
describe("process.binding", () => {
test("process.binding() with unsupported module property access", () => {
/* @ts-ignore */
const unsupported = process.binding("buffer");
expect(() => unsupported.kMaxLength).toThrow();
});
test("process.binding('constants')", () => {
/* @ts-ignore */
const constants = process.binding("constants");
@@ -9,6 +15,7 @@ describe("process.binding", () => {
expect(constants).toHaveProperty("trace");
expect(constants).toHaveProperty("zlib");
});
test("process.binding('uv')", () => {
/* @ts-ignore */
const uv = process.binding("uv");

View File

@@ -231,10 +231,6 @@ it("process.execArgv", () => {
expect(process.execArgv instanceof Array).toBe(true);
});
it("process.binding", () => {
expect(() => process.binding("buffer")).toThrow();
});
it("process.argv in testing", () => {
expect(process.argv).toBeInstanceOf(Array);
expect(process.argv[0]).toBe(bunExe());