diff options
-rw-r--r-- | src/bun.js/modules/NodeUtilTypesModule.h | 28 | ||||
-rw-r--r-- | test/js/node/util/test-util-types.test.js | 22 |
2 files changed, 44 insertions, 6 deletions
diff --git a/src/bun.js/modules/NodeUtilTypesModule.h b/src/bun.js/modules/NodeUtilTypesModule.h index 586743fea..de9b147a4 100644 --- a/src/bun.js/modules/NodeUtilTypesModule.h +++ b/src/bun.js/modules/NodeUtilTypesModule.h @@ -123,8 +123,28 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionIsRegExp, (JSC::JSGlobalObject * globalObject } JSC_DEFINE_HOST_FUNCTION(jsFunctionIsAsyncFunction, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe)) { - GET_FIRST_CELL - return JSValue::encode(jsBoolean(JSValue::strictEqual(globalObject, JSValue(globalObject->asyncFunctionPrototype()), cell->getObject()->getPrototype(cell->getObject(), globalObject)))); + GET_FIRST_VALUE + + auto* function = jsDynamicCast<JSFunction*>(value); + if (!function) + return JSValue::encode(jsBoolean(false)); + + auto *executable = function->jsExecutable(); + if (!executable) + return JSValue::encode(jsBoolean(false)); + + if (executable->isAsyncGenerator()) { + return JSValue::encode(jsBoolean(true)); + } + + auto& vm = globalObject->vm(); + auto proto = function->getPrototype(vm, globalObject); + if (!proto.isCell()) { + return JSValue::encode(jsBoolean(false)); + } + + auto *protoCell = proto.asCell(); + return JSValue::encode(jsBoolean(protoCell->inherits<AsyncFunctionPrototype>())); } JSC_DEFINE_HOST_FUNCTION(jsFunctionIsGeneratorFunction, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe)) { @@ -137,13 +157,13 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionIsGeneratorFunction, (JSC::JSGlobalObject * g if (!executable) return JSValue::encode(jsBoolean(false)); - return JSValue::encode(jsBoolean(executable->isGenerator())); + return JSValue::encode(jsBoolean(executable->isGenerator() || executable->isAsyncGenerator())); } JSC_DEFINE_HOST_FUNCTION(jsFunctionIsGeneratorObject, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe)) { GET_FIRST_CELL - return JSValue::encode(jsBoolean(cell->type() == JSGeneratorType)); + return JSValue::encode(jsBoolean(cell->type() == JSGeneratorType || cell->type() == JSAsyncGeneratorType)); } JSC_DEFINE_HOST_FUNCTION(jsFunctionIsPromise, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe)) { diff --git a/test/js/node/util/test-util-types.test.js b/test/js/node/util/test-util-types.test.js index a75b9eac0..cb8fa594a 100644 --- a/test/js/node/util/test-util-types.test.js +++ b/test/js/node/util/test-util-types.test.js @@ -24,9 +24,8 @@ for (const [value, _method] of [ [Object(BigInt(0)), "isBigIntObject"], [new Error(), "isNativeError"], [new RegExp()], - [async function () {}, "isAsyncFunction"], - [function* () {}, "isGeneratorFunction"], [(function* () {})(), "isGeneratorObject"], + [(async function* () {})(), "isGeneratorObject"], [Promise.resolve()], [new Map()], [new Set()], @@ -248,3 +247,22 @@ test("isBoxedPrimitive", () => { } } // */ + +test("isAsyncFunction", () => { + for (let fn of [async function asyncFn() {}, async function* asyncGeneratorFn() {}]) { + expect(types.isAsyncFunction(fn)).toBeTrue(); + } + + for (let fn of [function normal() {}, function* generatorFn() {}]) { + expect(types.isAsyncFunction(fn)).toBeFalse(); + } +}); +test("isGeneratorFunction", () => { + for (let fn of [function* generator() {}, async function* asyncGenerator() {}]) { + expect(types.isGeneratorFunction(fn)).toBeTrue(); + } + + for (let fn of [function normal() {}, async function asyncFn() {}]) { + expect(types.isGeneratorFunction(fn)).toBeFalse(); + } +}); |