Fix missing error in process.nextTick and queueMicrotask

This commit is contained in:
Jarred Sumner
2022-11-07 14:13:55 -08:00
parent 370d9c2931
commit fd26d2e9fa
3 changed files with 138 additions and 44 deletions

View File

@@ -38,8 +38,8 @@ static JSC_DECLARE_CUSTOM_GETTER(Process_getPPID);
static JSC_DECLARE_HOST_FUNCTION(Process_functionCwd);
static JSC_DECLARE_HOST_FUNCTION(Process_functionNextTick);
static JSC_DEFINE_HOST_FUNCTION(Process_functionNextTick,
JSC_DECLARE_HOST_FUNCTION(Process_functionNextTick);
JSC_DEFINE_HOST_FUNCTION(Process_functionNextTick,
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
JSC::VM& vm = globalObject->vm();
@@ -58,61 +58,49 @@ static JSC_DEFINE_HOST_FUNCTION(Process_functionNextTick,
return JSC::JSValue::encode(JSC::JSValue {});
}
switch (argCount) {
Zig::GlobalObject* global = JSC::jsCast<Zig::GlobalObject*>(globalObject);
switch (callFrame->argumentCount()) {
case 1: {
// This is a JSC builtin function
globalObject->queueMicrotask(job, JSC::JSValue {}, JSC::JSValue {},
JSC::JSValue {}, JSC::JSValue {});
global->queueMicrotask(global->performMicrotaskFunction(), job, JSC::JSValue {}, JSC::JSValue {}, JSC::JSValue {});
break;
}
case 2:
case 3:
case 4:
case 5: {
JSC::JSValue argument0 = callFrame->uncheckedArgument(1);
JSC::JSValue argument1 = argCount > 2 ? callFrame->uncheckedArgument(2) : JSC::JSValue {};
JSC::JSValue argument2 = argCount > 3 ? callFrame->uncheckedArgument(3) : JSC::JSValue {};
JSC::JSValue argument3 = argCount > 4 ? callFrame->uncheckedArgument(4) : JSC::JSValue {};
globalObject->queueMicrotask(
job, argument0, argument1, argument2, argument3);
case 2: {
global->queueMicrotask(global->performMicrotaskFunction(), job, callFrame->uncheckedArgument(1), JSC::JSValue {}, JSC::JSValue {});
break;
}
case 3: {
global->queueMicrotask(global->performMicrotaskFunction(), job, callFrame->uncheckedArgument(1), callFrame->uncheckedArgument(2), JSC::JSValue {});
break;
}
case 4: {
global->queueMicrotask(global->performMicrotaskFunction(), job, callFrame->uncheckedArgument(1), callFrame->uncheckedArgument(2), callFrame->uncheckedArgument(3));
break;
}
default: {
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
JSC::throwTypeError(globalObject, scope,
"nextTick doesn't support more than 4 arguments currently"_s);
return JSC::JSValue::encode(JSC::JSValue {});
JSC::JSArray* args = JSC::constructEmptyArray(globalObject, nullptr, argCount - 1);
if (UNLIKELY(!args)) {
auto scope = DECLARE_THROW_SCOPE(vm);
throwVMError(globalObject, scope, createOutOfMemoryError(globalObject));
return JSC::JSValue::encode(JSC::JSValue {});
}
for (unsigned i = 1; i < argCount; i++) {
args->putDirectIndex(globalObject, i - 1, callFrame->uncheckedArgument(i));
}
global->queueMicrotask(
global->performMicrotaskVariadicFunction(), job, args, JSValue {}, JSC::JSValue {});
break;
}
// JSC::MarkedArgumentBuffer args;
// for (unsigned i = 1; i < callFrame->argumentCount(); i++) {
// args.append(callFrame->uncheckedArgument(i));
// }
// JSC::ArgList argsList(args);
// JSC::gcProtect(job);
// JSC::JSFunction *callback = JSC::JSNativeStdFunction::create(
// vm, globalObject, 0, String(),
// [job, &argsList](JSC::JSGlobalObject *globalObject, JSC::CallFrame *callFrame) {
// JSC::VM &vm = globalObject->vm();
// auto callData = getCallData(job);
// return JSC::JSValue::encode(JSC::call(globalObject, job, callData, job, argsList));
// });
// globalObject->queueMicrotask(JSC::createJSMicrotask(vm, JSC::JSValue(callback)));
}
return JSC::JSValue::encode(JSC::jsUndefined());
return JSC::JSValue::encode(jsUndefined());
}
static JSC_DECLARE_HOST_FUNCTION(Process_functionDlopen);
static JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
JSC_DECLARE_HOST_FUNCTION(Process_functionDlopen);
JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
(JSC::JSGlobalObject * globalObject_, JSC::CallFrame* callFrame))
{
Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(globalObject_);

View File

@@ -686,8 +686,10 @@ static JSC_DEFINE_HOST_FUNCTION(functionQueueMicrotask,
return JSC::JSValue::encode(JSC::JSValue {});
}
Zig::GlobalObject* global = JSC::jsCast<Zig::GlobalObject*>(globalObject);
// This is a JSC builtin function
globalObject->queueMicrotask(job, JSC::JSValue {}, JSC::JSValue {},
globalObject->queueMicrotask(global->performMicrotaskFunction(), job, JSC::JSValue {},
JSC::JSValue {}, JSC::JSValue {});
return JSC::JSValue::encode(JSC::jsUndefined());
@@ -2014,6 +2016,95 @@ public:
const ClassInfo BunPrimordialsObject::s_info = { "Primordials"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(BunPrimordialsObject) };
extern "C" void Bun__reportUnhandledError(JSGlobalObject*, EncodedJSValue);
JSC_DEFINE_HOST_FUNCTION(jsFunctionPerformMicrotask, (JSGlobalObject * globalObject, CallFrame* callframe))
{
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
auto job = callframe->argument(0);
if (!job || job.isUndefinedOrNull()) {
return JSValue::encode(jsUndefined());
}
auto callData = JSC::getCallData(job);
MarkedArgumentBuffer arguments;
if (UNLIKELY(callData.type == CallData::Type::None)) {
return JSValue::encode(jsUndefined());
}
JSValue result;
WTF::NakedPtr<JSC::Exception> exceptionPtr;
switch (callframe->argumentCount()) {
case 1:
JSC::call(globalObject, job, callData, jsUndefined(), arguments, exceptionPtr);
break;
case 2:
arguments.append(callframe->argument(1));
JSC::call(globalObject, job, callData, jsUndefined(), arguments, exceptionPtr);
break;
case 3:
arguments.append(callframe->argument(1));
arguments.append(callframe->argument(2));
JSC::call(globalObject, job, callData, jsUndefined(), arguments, exceptionPtr);
break;
case 4:
arguments.append(callframe->argument(1));
arguments.append(callframe->argument(2));
arguments.append(callframe->argument(3));
JSC::call(globalObject, job, callData, jsUndefined(), arguments, exceptionPtr);
break;
default:
RELEASE_ASSERT_NOT_REACHED();
}
if (auto* exception = exceptionPtr.get()) {
Bun__reportUnhandledError(globalObject, JSValue::encode(exception));
}
return JSValue::encode(jsUndefined());
}
JSC_DEFINE_HOST_FUNCTION(jsFunctionPerformMicrotaskVariadic, (JSGlobalObject * globalObject, CallFrame* callframe))
{
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
auto job = callframe->argument(0);
if (!job || job.isUndefinedOrNull()) {
return JSValue::encode(jsUndefined());
}
auto callData = JSC::getCallData(job);
MarkedArgumentBuffer arguments;
if (UNLIKELY(callData.type == CallData::Type::None)) {
return JSValue::encode(jsUndefined());
}
JSArray* array = jsCast<JSArray*>(callframe->argument(1));
for (unsigned i = 0; i < array->length(); i++) {
arguments.append(array->getIndex(globalObject, i));
}
JSValue result;
WTF::NakedPtr<JSC::Exception> exceptionPtr;
JSValue thisValue = jsUndefined();
if (callframe->argumentCount() > 2) {
thisValue = callframe->argument(2);
}
JSC::call(globalObject, job, callData, thisValue, arguments, exceptionPtr);
if (auto* exception = exceptionPtr.get()) {
Bun__reportUnhandledError(globalObject, JSValue::encode(exception));
}
return JSValue::encode(jsUndefined());
}
void GlobalObject::finishCreation(VM& vm)
{
Base::finishCreation(vm);
@@ -2025,6 +2116,16 @@ void GlobalObject::finishCreation(VM& vm)
init.set(JSModuleNamespaceObject::createStructure(init.vm, init.owner, init.owner->objectPrototype()));
});
m_performMicrotaskFunction.initLater(
[](const Initializer<JSFunction>& init) {
init.set(JSFunction::create(init.vm, init.owner, 4, "performMicrotask"_s, jsFunctionPerformMicrotask, ImplementationVisibility::Public));
});
m_performMicrotaskVariadicFunction.initLater(
[](const Initializer<JSFunction>& init) {
init.set(JSFunction::create(init.vm, init.owner, 4, "performMicrotaskVariadic"_s, jsFunctionPerformMicrotaskVariadic, ImplementationVisibility::Public));
});
m_navigatorObject.initLater(
[](const Initializer<JSObject>& init) {
int cpuCount = 0;

View File

@@ -221,6 +221,9 @@ public:
JSC::JSObject* performanceObject() { return m_performanceObject.getInitializedOnMainThread(this); }
JSC::JSObject* primordialsObject() { return m_primordialsObject.getInitializedOnMainThread(this); }
JSC::JSFunction* performMicrotaskFunction() { return m_performMicrotaskFunction.getInitializedOnMainThread(this); }
JSC::JSFunction* performMicrotaskVariadicFunction() { return m_performMicrotaskVariadicFunction.getInitializedOnMainThread(this); }
JSC::JSObject* processObject()
{
return m_processObject.getInitializedOnMainThread(this);
@@ -427,6 +430,8 @@ private:
LazyProperty<JSGlobalObject, JSObject> m_JSFileSinkControllerPrototype;
LazyProperty<JSGlobalObject, Structure> m_JSHTTPResponseController;
LazyProperty<JSGlobalObject, JSFunction> m_performMicrotaskFunction;
LazyProperty<JSGlobalObject, JSFunction> m_performMicrotaskVariadicFunction;
LazyProperty<JSGlobalObject, JSObject> m_processObject;
LazyProperty<JSGlobalObject, JSObject> m_processEnvObject;