aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-09-27 19:17:05 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-09-27 19:17:05 -0700
commitc692cbff21f442b6e10c5af5c1139d2e45d2e2a8 (patch)
treeb5cb83c9cf64c6858cc4b822614c0427c9afad00
parent7cd1dc2817158f9a27605ec5bac33575b9ef12f3 (diff)
downloadbun-jarred/callable.tar.gz
bun-jarred/callable.tar.zst
bun-jarred/callable.zip
`makeClassCallable`jarred/callable
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp109
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h4
2 files changed, 112 insertions, 1 deletions
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index 54fb58776..1e4b08ef8 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -1579,6 +1579,98 @@ JSC_DEFINE_CUSTOM_SETTER(noop_setter,
return true;
}
+JSC_DEFINE_HOST_FUNCTION(jsMakeClassCallableCall, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe))
+{
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto* constructor = callframe->thisValue().getObject();
+ if (!constructor || !constructor->isConstructor()) {
+ throwTypeError(globalObject, scope, "call expects a constructor"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ JSValue newTarget = callframe->argument(0);
+ JSC::ArgList args = JSC::ArgList(callframe, 1);
+ RELEASE_AND_RETURN(scope, JSValue::encode(JSC::construct(globalObject, constructor, JSC::getCallData(constructor), args, newTarget)));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsMakeClassCallableApply, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe))
+{
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto* constructor = callframe->thisValue().getObject();
+ if (!constructor || !constructor->isConstructor()) {
+ throwTypeError(globalObject, scope, "apply expects a constructor"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ JSValue newTarget = callframe->argument(0);
+
+ MarkedArgumentBuffer args;
+ JSValue argumentsObject = callframe->argument(1);
+ if (auto* array = jsDynamicCast<JSC::JSArray*>(argumentsObject)) {
+ JSValue thisValue = callframe->thisValue();
+
+ unsigned argCount = array->length();
+ for (unsigned i = 0; i < argCount; i++) {
+ JSValue value = array->getIndex(globalObject, i);
+ if (UNLIKELY(scope.exception()))
+ return JSC::JSValue::encode(JSC::JSValue {});
+ if (value.isEmpty())
+ continue;
+
+ args.append(value);
+ }
+ }
+
+ RELEASE_AND_RETURN(scope, JSValue::encode(JSC::construct(globalObject, constructor, JSC::getCallData(constructor), args, newTarget)));
+}
+
+JSC_DEFINE_HOST_FUNCTION(jsMakeClassCallable, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callframe))
+{
+ auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (callframe->argumentCount() < 1) {
+ throwTypeError(globalObject, scope, "makeClassCallable needs 1 argument"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ auto* constructor = callframe->argument(0).getObject();
+ if (!constructor || !constructor->isConstructor()) {
+ throwTypeError(globalObject, scope, "makeClassCallable needs a constructor"_s);
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ JSFunction* call = JSC::JSBoundFunction::create(vm,
+ globalObject,
+ globalObject->makeClassCallableCallUnbound(),
+ constructor,
+ ArgList(), 1, jsString(vm, String("call"_s)));
+
+ JSFunction* apply = JSC::JSBoundFunction::create(vm,
+ globalObject,
+ globalObject->makeClassCallableApplyUnbound(),
+ constructor,
+ ArgList(), 1, jsString(vm, String("apply"_s)));
+
+ constructor->putDirect(
+ vm,
+ vm.propertyNames->builtinNames().callPublicName(),
+ call,
+ JSC::PropertyAttribute::DontEnum | 0);
+ constructor->putDirect(
+ vm,
+ vm.propertyNames->builtinNames().applyPublicName(),
+ apply,
+ JSC::PropertyAttribute::DontEnum | 0);
+
+ RELEASE_AND_RETURN(scope, JSC::JSValue::encode(constructor));
+}
+
static NeverDestroyed<const String> pathToFileURLString(MAKE_STATIC_STRING_IMPL("pathToFileURL"));
static NeverDestroyed<const String> fileURLToPathString(MAKE_STATIC_STRING_IMPL("fileURLToPath"));
@@ -1701,6 +1793,10 @@ JSC_DEFINE_HOST_FUNCTION(functionLazyLoad,
return JSC::JSValue::encode(obj);
}
+ if (string == "makeClassCallable"_s) {
+ return JSC::JSValue::encode(JSC::JSFunction::create(vm, globalObject, 1, "makeClassCallable"_s, jsMakeClassCallable, ImplementationVisibility::Public, NoIntrinsic));
+ }
+
if (string == "worker_threads"_s) {
JSValue workerData = jsUndefined();
@@ -2766,6 +2862,16 @@ void GlobalObject::finishCreation(VM& vm)
init.set(fileConstructor);
});
+ m_makeClassCallableCall.initLater(
+ [](const Initializer<JSFunction>& init) {
+ init.set(JSFunction::create(init.vm, init.owner, 2, "call"_s, jsMakeClassCallableCall, ImplementationVisibility::Private));
+ });
+
+ m_makeClassCallableApply.initLater(
+ [](const Initializer<JSFunction>& init) {
+ init.set(JSFunction::create(init.vm, init.owner, 2, "apply"_s, jsMakeClassCallableApply, ImplementationVisibility::Private));
+ });
+
m_cryptoObject.initLater(
[](const Initializer<JSObject>& init) {
JSC::JSGlobalObject* globalObject = init.owner;
@@ -3813,7 +3919,8 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_JSBufferSubclassStructure.visit(visitor);
thisObject->m_cryptoObject.visit(visitor);
thisObject->m_JSDOMFileConstructor.visit(visitor);
-
+ thisObject->m_makeClassCallableCall.visit(visitor);
+ thisObject->m_makeClassCallableApply.visit(visitor);
thisObject->m_requireFunctionUnbound.visit(visitor);
thisObject->m_requireResolveFunctionUnbound.visit(visitor);
thisObject->m_importMetaObjectStructure.visit(visitor);
diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h
index e27b3bffa..37e3ec1d2 100644
--- a/src/bun.js/bindings/ZigGlobalObject.h
+++ b/src/bun.js/bindings/ZigGlobalObject.h
@@ -353,6 +353,8 @@ public:
mutable WriteBarrier<JSFunction> m_thenables[promiseFunctionsSize + 1];
mutable WriteBarrier<JSC::Unknown> m_errorConstructorPrepareStackTraceValue;
+ JSFunction* makeClassCallableCallUnbound() { return m_makeClassCallableCall.getInitializedOnMainThread(this); }
+ JSFunction* makeClassCallableApplyUnbound() { return m_makeClassCallableApply.getInitializedOnMainThread(this); }
Structure* memoryFootprintStructure()
{
@@ -508,6 +510,8 @@ public:
LazyProperty<JSGlobalObject, JSObject> m_navigatorObject;
LazyProperty<JSGlobalObject, JSObject> m_performanceObject;
LazyProperty<JSGlobalObject, JSObject> m_processObject;
+ LazyProperty<JSGlobalObject, JSFunction> m_makeClassCallableCall;
+ LazyProperty<JSGlobalObject, JSFunction> m_makeClassCallableApply;
private:
DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock);