diff options
author | 2023-08-21 01:29:06 -0700 | |
---|---|---|
committer | 2023-08-21 01:29:06 -0700 | |
commit | c99a9ba33a36f16f79e38ff77423f5d301f6d2a8 (patch) | |
tree | 0ca11cdc93b665668c9c6d07da0ae865cd1f4c77 /src/bun.js/bindings/JSDOMFile.cpp | |
parent | f75b949524ac4a41e0f015cb981f356444fab331 (diff) | |
download | bun-c99a9ba33a36f16f79e38ff77423f5d301f6d2a8.tar.gz bun-c99a9ba33a36f16f79e38ff77423f5d301f6d2a8.tar.zst bun-c99a9ba33a36f16f79e38ff77423f5d301f6d2a8.zip |
Implement File
Diffstat (limited to 'src/bun.js/bindings/JSDOMFile.cpp')
-rw-r--r-- | src/bun.js/bindings/JSDOMFile.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/bun.js/bindings/JSDOMFile.cpp b/src/bun.js/bindings/JSDOMFile.cpp new file mode 100644 index 000000000..1d7770ac1 --- /dev/null +++ b/src/bun.js/bindings/JSDOMFile.cpp @@ -0,0 +1,105 @@ +#include "root.h" +#include "ZigGeneratedClasses.h" +#include "JavaScriptCore/ObjectConstructor.h" +#include "JavaScriptCore/InternalFunction.h" +#include "JavaScriptCore/FunctionPrototype.h" +#include "JSDOMFile.h" + +using namespace JSC; + +extern "C" void* JSDOMFile__construct(JSC::JSGlobalObject*, JSC::CallFrame* callframe); +extern "C" bool JSDOMFile__hasInstance(EncodedJSValue, JSC::JSGlobalObject*, EncodedJSValue); + +// TODO: make this inehrit from JSBlob instead of InternalFunction +// That will let us remove this hack for [Symbol.hasInstance] and fix the prototype chain. +class JSDOMFile : public JSC::InternalFunction { + using Base = JSC::InternalFunction; + +public: + JSDOMFile(JSC::VM& vm, JSC::Structure* structure) + : Base(vm, structure, nullptr, construct) + { + } + + DECLARE_INFO; + + static constexpr unsigned StructureFlags = (Base::StructureFlags & ~ImplementsDefaultHasInstance) | ImplementsHasInstance; + + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + return &vm.internalFunctionSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(InternalFunctionType, StructureFlags), info()); + } + + void finishCreation(JSC::VM& vm) + { + Base::finishCreation(vm, 2, "File"_s); + } + + static JSDOMFile* create(JSC::VM& vm, JSGlobalObject* globalObject) + { + auto* zigGlobal = reinterpret_cast<Zig::GlobalObject*>(globalObject); + auto* object = new (NotNull, JSC::allocateCell<JSDOMFile>(vm)) JSDOMFile(vm, createStructure(vm, globalObject, zigGlobal->functionPrototype())); + object->finishCreation(vm); + + // This is not quite right. But we'll fix it if someone files an issue about it. + object->putDirect(vm, vm.propertyNames->prototype, zigGlobal->JSBlobPrototype(), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | 0); + + return object; + } + + static bool customHasInstance(JSObject* object, JSGlobalObject* globalObject, JSValue value) + { + if (!value.isObject()) + return false; + + // Note: this breaks [Symbol.hasInstance] + // We must do this for now until we update the code generator to export classes + return JSDOMFile__hasInstance(JSValue::encode(object), globalObject, JSValue::encode(value)); + } + + static EncodedJSValue construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) + { + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + JSC::VM& vm = globalObject->vm(); + JSObject* newTarget = asObject(callFrame->newTarget()); + auto* constructor = globalObject->JSDOMFileConstructor(); + Structure* structure = globalObject->JSBlobStructure(); + if (constructor != newTarget) { + auto scope = DECLARE_THROW_SCOPE(vm); + + auto* functionGlobalObject = reinterpret_cast<Zig::GlobalObject*>( + // ShadowRealm functions belong to a different global object. + getFunctionRealm(globalObject, newTarget)); + RETURN_IF_EXCEPTION(scope, {}); + structure = InternalFunction::createSubclassStructure( + globalObject, + newTarget, + functionGlobalObject->JSBlobStructure()); + } + + void* ptr = JSDOMFile__construct(globalObject, callFrame); + + if (UNLIKELY(!ptr)) { + return JSValue::encode(JSC::jsUndefined()); + } + + return JSValue::encode( + WebCore::JSBlob::create(vm, globalObject, structure, ptr)); + } +}; + +const JSC::ClassInfo JSDOMFile::s_info = { "File"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMFile) }; + +namespace Bun { + +JSC::JSObject* createJSDOMFileConstructor(JSC::VM& vm, JSC::JSGlobalObject* globalObject) +{ + return JSDOMFile::create(vm, globalObject); +} + +}
\ No newline at end of file |