mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
wip response object c++ class thingy
This commit is contained in:
@@ -64,6 +64,7 @@ src/bun.js/bindings/InternalModuleRegistry.cpp
|
||||
src/bun.js/bindings/IPC.cpp
|
||||
src/bun.js/bindings/isBuiltinModule.cpp
|
||||
src/bun.js/bindings/JS2Native.cpp
|
||||
src/bun.js/bindings/JSBakeResponse.cpp
|
||||
src/bun.js/bindings/JSBigIntBinding.cpp
|
||||
src/bun.js/bindings/JSBuffer.cpp
|
||||
src/bun.js/bindings/JSBufferEncodingType.cpp
|
||||
|
||||
376
src/bun.js/bindings/JSBakeResponse.cpp
Normal file
376
src/bun.js/bindings/JSBakeResponse.cpp
Normal file
@@ -0,0 +1,376 @@
|
||||
#include "root.h"
|
||||
#include "headers.h"
|
||||
|
||||
#include <JavaScriptCore/JSCell.h>
|
||||
#include <JavaScriptCore/Structure.h>
|
||||
#include <JavaScriptCore/JSObject.h>
|
||||
#include <JavaScriptCore/InternalFunction.h>
|
||||
#include <JavaScriptCore/ObjectConstructor.h>
|
||||
#include <JavaScriptCore/Symbol.h>
|
||||
#include <JavaScriptCore/SymbolTable.h>
|
||||
#include <JavaScriptCore/JSCInlines.h>
|
||||
#include <JavaScriptCore/FunctionPrototype.h>
|
||||
#include <JavaScriptCore/LazyClassStructure.h>
|
||||
#include "JSBakeResponse.h"
|
||||
#include "ZigGlobalObject.h"
|
||||
#include "ZigGeneratedClasses.h"
|
||||
|
||||
#if !OS(WINDOWS)
|
||||
#define JSC_CALLCONV "C"
|
||||
#else
|
||||
#define JSC_CALLCONV "C" SYSV_ABI
|
||||
#endif
|
||||
|
||||
namespace Bun {
|
||||
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsBakeResponseConstructorRender);
|
||||
static JSC_DECLARE_HOST_FUNCTION(jsBakeResponseConstructorRedirect);
|
||||
|
||||
static JSC_DECLARE_CUSTOM_GETTER(jsBakeResponsePrototypeGetSymbolFor);
|
||||
static JSC_DECLARE_CUSTOM_GETTER(jsBakeResponsePrototypeGetType);
|
||||
static JSC_DECLARE_CUSTOM_GETTER(jsBakeResponsePrototypeGetKey);
|
||||
static JSC_DECLARE_CUSTOM_GETTER(jsBakeResponsePrototypeGetProps);
|
||||
static JSC_DECLARE_CUSTOM_GETTER(jsBakeResponsePrototypeGetStore);
|
||||
static JSC_DECLARE_CUSTOM_GETTER(jsBakeResponsePrototypeGetOwner);
|
||||
static JSC_DECLARE_CUSTOM_GETTER(jsBakeResponsePrototypeGetDebugInfo);
|
||||
static JSC_DECLARE_CUSTOM_GETTER(jsBakeResponsePrototypeGetDebugStack);
|
||||
static JSC_DECLARE_CUSTOM_GETTER(jsBakeResponsePrototypeGetDebugTask);
|
||||
|
||||
extern JSC_CALLCONV void* JSC_HOST_CALL_ATTRIBUTES ResponseClass__constructForSSR(JSC::JSGlobalObject*, JSC::CallFrame*, JSC::EncodedJSValue);
|
||||
extern "C" SYSV_ABI JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES ResponseClass__constructError(JSC::JSGlobalObject*, JSC::CallFrame*) SYSV_ABI;
|
||||
extern "C" SYSV_ABI JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES ResponseClass__constructJSON(JSC::JSGlobalObject*, JSC::CallFrame*) SYSV_ABI;
|
||||
extern JSC_CALLCONV size_t Response__estimatedSize(void* ptr);
|
||||
|
||||
static const HashTableValue JSBakeResponseConstructorTableValues[] = {
|
||||
{ "error"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ResponseClass__constructError, 0 } },
|
||||
{ "json"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, ResponseClass__constructJSON, 0 } },
|
||||
|
||||
{ "render"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBakeResponseConstructorRender, 1 } },
|
||||
{ "redirect"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBakeResponseConstructorRedirect, 1 } },
|
||||
|
||||
};
|
||||
|
||||
static const HashTableValue JSBakeResponsePrototypeTableValues[] = {
|
||||
{ "$$typeof"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBakeResponsePrototypeGetSymbolFor, nullptr } },
|
||||
{ "type"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBakeResponsePrototypeGetType, nullptr } },
|
||||
{ "key"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBakeResponsePrototypeGetKey, nullptr } },
|
||||
{ "props"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBakeResponsePrototypeGetProps, nullptr } },
|
||||
{ "_store"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBakeResponsePrototypeGetStore, nullptr } },
|
||||
{ "_owner"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBakeResponsePrototypeGetOwner, nullptr } },
|
||||
{ "_debugInfo"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBakeResponsePrototypeGetDebugInfo, nullptr } },
|
||||
{ "_debugStack"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBakeResponsePrototypeGetDebugStack, nullptr } },
|
||||
{ "_debugTask"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsBakeResponsePrototypeGetDebugTask, nullptr } }
|
||||
};
|
||||
|
||||
JSBakeResponse* JSBakeResponse::create(JSC::VM& vm, JSC::Structure* structure, void* ctx)
|
||||
{
|
||||
JSBakeResponse* ptr = new (NotNull, JSC::allocateCell<JSBakeResponse>(vm)) JSBakeResponse(vm, structure, ctx);
|
||||
ptr->finishCreation(vm);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
JSC::Structure* JSBakeResponse::createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
|
||||
{
|
||||
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(static_cast<JSC::JSType>(0b11101110), StructureFlags), info());
|
||||
}
|
||||
|
||||
JSC::GCClient::IsoSubspace* JSBakeResponse::subspaceForImpl(JSC::VM& vm)
|
||||
{
|
||||
return WebCore::subspaceForImpl<JSBakeResponse, WebCore::UseCustomHeapCellType::No>(
|
||||
vm,
|
||||
[](auto& spaces) { return spaces.m_clientSubspaceForBakeResponse.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceForBakeResponse = std::forward<decltype(space)>(space); },
|
||||
[](auto& spaces) { return spaces.m_subspaceForBakeResponse.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_subspaceForBakeResponse = std::forward<decltype(space)>(space); });
|
||||
}
|
||||
|
||||
JSBakeResponse::JSBakeResponse(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr)
|
||||
: Base(vm, structure, sinkPtr)
|
||||
{
|
||||
}
|
||||
|
||||
void JSBakeResponse::finishCreation(JSC::VM& vm)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
void JSBakeResponse::visitChildrenImpl(JSCell* cell, Visitor& visitor)
|
||||
{
|
||||
JSBakeResponse* thisObject = jsCast<JSBakeResponse*>(cell);
|
||||
Base::visitChildren(thisObject, visitor);
|
||||
}
|
||||
|
||||
DEFINE_VISIT_CHILDREN(JSBakeResponse);
|
||||
|
||||
class JSBakeResponsePrototype final : public JSNonFinalObject {
|
||||
public:
|
||||
using Base = JSNonFinalObject;
|
||||
|
||||
static JSBakeResponsePrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
|
||||
{
|
||||
auto* ptr = new (NotNull, JSC::allocateCell<JSBakeResponsePrototype>(vm)) JSBakeResponsePrototype(vm, structure);
|
||||
ptr->finishCreation(vm, globalObject);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
|
||||
{
|
||||
auto* structure = Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), NonArray);
|
||||
structure->setMayBePrototype(true);
|
||||
return structure;
|
||||
}
|
||||
|
||||
DECLARE_INFO;
|
||||
|
||||
template<typename CellType, JSC::SubspaceAccess>
|
||||
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
|
||||
{
|
||||
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSBakeResponsePrototype, Base);
|
||||
return &vm.plainObjectSpace();
|
||||
}
|
||||
|
||||
private:
|
||||
JSBakeResponsePrototype(JSC::VM& vm, JSC::Structure* structure)
|
||||
: Base(vm, structure)
|
||||
{
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
reifyStaticProperties(vm, JSBakeResponse::info(), JSBakeResponsePrototypeTableValues, *this);
|
||||
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
|
||||
}
|
||||
};
|
||||
|
||||
JSC_DECLARE_HOST_FUNCTION(callBakeResponse);
|
||||
JSC_DECLARE_HOST_FUNCTION(constructBakeResponse);
|
||||
|
||||
class JSBakeResponseConstructor final : public JSC::InternalFunction {
|
||||
public:
|
||||
using Base = JSC::InternalFunction;
|
||||
static constexpr unsigned StructureFlags = Base::StructureFlags;
|
||||
|
||||
static JSBakeResponseConstructor* create(JSC::VM& vm, JSC::Structure* structure, JSC::JSObject* prototype)
|
||||
{
|
||||
JSBakeResponseConstructor* constructor = new (NotNull, JSC::allocateCell<JSBakeResponseConstructor>(vm)) JSBakeResponseConstructor(vm, structure);
|
||||
constructor->finishCreation(vm, prototype);
|
||||
return constructor;
|
||||
}
|
||||
|
||||
// DECLARE_INFO;
|
||||
DECLARE_EXPORT_INFO;
|
||||
|
||||
// Must be defined for each specialization class.
|
||||
static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
|
||||
{
|
||||
Zig::GlobalObject* globalObject = defaultGlobalObject(lexicalGlobalObject);
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
JSObject* newTarget = asObject(callFrame->newTarget());
|
||||
auto* constructor = globalObject->JSResponseConstructor();
|
||||
Structure* structure = globalObject->JSBakeResponseStructure();
|
||||
if (constructor != newTarget) [[unlikely]] {
|
||||
auto* functionGlobalObject = defaultGlobalObject(
|
||||
// ShadowRealm functions belong to a different global object.
|
||||
getFunctionRealm(globalObject, newTarget));
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
structure = InternalFunction::createSubclassStructure(globalObject, newTarget, functionGlobalObject->JSBakeResponseStructure());
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
}
|
||||
|
||||
JSBakeResponse* instance = JSBakeResponse::create(vm, structure, nullptr);
|
||||
|
||||
void* ptr = ResponseClass__constructForSSR(globalObject, callFrame, JSValue::encode(instance));
|
||||
if (scope.exception()) [[unlikely]] {
|
||||
ASSERT_WITH_MESSAGE(!ptr, "Memory leak detected: new SSRResponse() allocated memory without checking for exceptions.");
|
||||
return JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
instance->m_ctx = ptr;
|
||||
|
||||
auto size = Response__estimatedSize(ptr);
|
||||
vm.heap.reportExtraMemoryAllocated(instance, size);
|
||||
|
||||
auto value = JSValue::encode(instance);
|
||||
RELEASE_AND_RETURN(scope, value);
|
||||
}
|
||||
|
||||
static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES call(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
|
||||
{
|
||||
Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
Structure* structure = globalObject->JSBakeResponseStructure();
|
||||
JSBakeResponse* instance = JSBakeResponse::create(vm, structure, nullptr);
|
||||
|
||||
void* ptr = ResponseClass__constructForSSR(globalObject, callFrame, JSValue::encode(instance));
|
||||
if (scope.exception()) [[unlikely]] {
|
||||
ASSERT_WITH_MESSAGE(!ptr, "Memory leak detected: new SSRResponse() allocated memory without checking for exceptions.");
|
||||
return JSValue::encode(JSC::jsUndefined());
|
||||
}
|
||||
|
||||
instance->m_ctx = ptr;
|
||||
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
auto size = Response__estimatedSize(ptr);
|
||||
vm.heap.reportExtraMemoryAllocated(instance, size);
|
||||
|
||||
RELEASE_AND_RETURN(scope, JSValue::encode(instance));
|
||||
}
|
||||
|
||||
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(JSC::InternalFunctionType, StructureFlags), info());
|
||||
}
|
||||
|
||||
private:
|
||||
JSBakeResponseConstructor(JSC::VM& vm, JSC::Structure* structure)
|
||||
: Base(vm, structure, JSBakeResponseConstructor::call, JSBakeResponseConstructor::construct)
|
||||
{
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM& vm, JSC::JSObject* prototype)
|
||||
{
|
||||
Base::finishCreation(vm, 0, "SSRResponse"_s);
|
||||
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly);
|
||||
reifyStaticProperties(vm, info(), JSBakeResponseConstructorTableValues, *this);
|
||||
}
|
||||
};
|
||||
|
||||
const JSC::ClassInfo JSBakeResponsePrototype::s_info = { "SSRResponse"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBakeResponsePrototype) };
|
||||
const JSC::ClassInfo JSBakeResponse::s_info = { "SSRResponse"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBakeResponse) };
|
||||
const JSC::ClassInfo JSBakeResponseConstructor::s_info = { "SSRResponse"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBakeResponseConstructor) };
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsBakeResponsePrototypeGetSymbolFor, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSBakeResponse* response = jsDynamicCast<JSBakeResponse*>(JSValue::decode(thisValue));
|
||||
if (!response)
|
||||
return JSValue::encode(jsUndefined());
|
||||
|
||||
auto& vm = globalObject->vm();
|
||||
auto symbolKey = "react.transitional.element"_s;
|
||||
return JSValue::encode(JSC::Symbol::create(vm, vm.symbolRegistry().symbolForKey(symbolKey)));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsBakeResponsePrototypeGetType, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSBakeResponse* response = jsDynamicCast<JSBakeResponse*>(JSValue::decode(thisValue));
|
||||
if (!response)
|
||||
return JSValue::encode(jsUndefined());
|
||||
|
||||
printf("m_ctx: %p\n", response->m_ctx);
|
||||
|
||||
// auto& type = response->type();
|
||||
// auto typeValue = type.get();
|
||||
// return JSValue::encode(typeValue);
|
||||
String wtfstring = "Hello"_s;
|
||||
auto* jsstring = JSC::jsString(globalObject->vm(), wtfstring);
|
||||
return JSValue::encode(jsstring);
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsBakeResponsePrototypeGetKey, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
return JSValue::encode(jsNull());
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsBakeResponsePrototypeGetProps, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSBakeResponse* response = jsDynamicCast<JSBakeResponse*>(JSValue::decode(thisValue));
|
||||
if (!response)
|
||||
return JSValue::encode(jsUndefined());
|
||||
|
||||
return JSValue::encode(JSC::constructEmptyObject(globalObject));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsBakeResponsePrototypeGetStore, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSBakeResponse* response = jsDynamicCast<JSBakeResponse*>(JSValue::decode(thisValue));
|
||||
if (!response)
|
||||
return JSValue::encode(jsUndefined());
|
||||
|
||||
auto& vm = globalObject->vm();
|
||||
JSObject* storeObject = JSC::constructEmptyObject(globalObject);
|
||||
auto validatedIdent = JSC::Identifier::fromString(vm, "validated"_s);
|
||||
storeObject->putDirect(vm, validatedIdent, jsNumber(0), 0);
|
||||
return JSValue::encode(storeObject);
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsBakeResponsePrototypeGetOwner, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
return JSValue::encode(jsNull());
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsBakeResponsePrototypeGetDebugInfo, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
return JSValue::encode(jsNull());
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsBakeResponsePrototypeGetDebugStack, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
return JSValue::encode(jsNull());
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsBakeResponsePrototypeGetDebugTask, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
return JSValue::encode(jsNull());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsBakeResponseConstructorRender, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsBakeResponseConstructorRedirect, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(callBakeResponse, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
throwScope.throwException(globalObject, createTypeError(globalObject, "BakeResponse constructor cannot be called as a function"_s));
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(constructBakeResponse, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
auto* zigGlobalObject = defaultGlobalObject(globalObject);
|
||||
|
||||
auto* structure = createJSBakeResponseStructure(vm, zigGlobalObject);
|
||||
|
||||
return JSValue::encode(JSBakeResponse::create(vm, structure, nullptr));
|
||||
}
|
||||
|
||||
void setupJSBakeResponseClassStructure(JSC::LazyClassStructure::Initializer& init)
|
||||
{
|
||||
auto* zigGlobal = reinterpret_cast<Zig::GlobalObject*>(init.global);
|
||||
auto* prototypeStructure = JSBakeResponsePrototype::createStructure(init.vm, init.global, zigGlobal->JSResponsePrototype());
|
||||
auto* prototype = JSBakeResponsePrototype::create(init.vm, init.global, prototypeStructure);
|
||||
|
||||
auto* constructorStructure = JSBakeResponseConstructor::createStructure(init.vm, init.global, init.global->functionPrototype());
|
||||
auto* constructor = JSBakeResponseConstructor::create(init.vm, constructorStructure, prototype);
|
||||
|
||||
auto* structure = JSBakeResponse::createStructure(init.vm, init.global, prototype);
|
||||
init.setPrototype(prototype);
|
||||
init.setStructure(structure);
|
||||
init.setConstructor(constructor);
|
||||
}
|
||||
|
||||
Structure* createJSBakeResponseStructure(JSC::VM& vm, Zig::GlobalObject* globalObject)
|
||||
{
|
||||
return globalObject->JSBakeResponseStructure();
|
||||
}
|
||||
|
||||
} // namespace Bun
|
||||
45
src/bun.js/bindings/JSBakeResponse.h
Normal file
45
src/bun.js/bindings/JSBakeResponse.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include "JSCookieMap.h"
|
||||
#include "root.h"
|
||||
#include "ZigGeneratedClasses.h"
|
||||
|
||||
namespace Bun {
|
||||
using namespace JSC;
|
||||
using namespace WebCore;
|
||||
|
||||
class JSBakeResponse : public JSResponse {
|
||||
public:
|
||||
using Base = JSResponse;
|
||||
|
||||
static JSBakeResponse* create(JSC::VM& vm, JSC::Structure* structure, void* ctx);
|
||||
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype);
|
||||
|
||||
// JSC::Strong<JSC::Unknown>& type() { return m_type; }
|
||||
|
||||
template<typename, JSC::SubspaceAccess mode>
|
||||
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
|
||||
{
|
||||
if (mode == JSC::SubspaceAccess::Concurrently) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return subspaceForImpl(vm);
|
||||
}
|
||||
|
||||
static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
|
||||
|
||||
DECLARE_VISIT_CHILDREN;
|
||||
DECLARE_INFO;
|
||||
|
||||
private:
|
||||
JSBakeResponse(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr);
|
||||
void finishCreation(JSC::VM& vm);
|
||||
|
||||
// JSC::Strong<JSC::Unknown> m_type;
|
||||
};
|
||||
|
||||
JSC::Structure* createJSBakeResponseStructure(JSC::VM&, Zig::GlobalObject*);
|
||||
void setupJSBakeResponseClassStructure(JSC::LazyClassStructure::Initializer& init);
|
||||
|
||||
} // namespace Bun
|
||||
@@ -164,6 +164,7 @@
|
||||
#include "JSPerformanceResourceTiming.h"
|
||||
#include "JSPerformanceTiming.h"
|
||||
#include "JSX509Certificate.h"
|
||||
#include "JSBakeResponse.h"
|
||||
#include "JSSign.h"
|
||||
#include "JSVerify.h"
|
||||
#include "JSHmac.h"
|
||||
@@ -3365,6 +3366,11 @@ void GlobalObject::finishCreation(VM& vm)
|
||||
init.setConstructor(constructor);
|
||||
});
|
||||
|
||||
m_JSBakeResponseClassStructure.initLater(
|
||||
[](LazyClassStructure::Initializer& init) {
|
||||
Bun::setupJSBakeResponseClassStructure(init);
|
||||
});
|
||||
|
||||
m_JSNetworkSinkClassStructure.initLater(
|
||||
[](LazyClassStructure::Initializer& init) {
|
||||
auto* prototype = createJSSinkPrototype(init.vm, init.global, WebCore::SinkID::NetworkSink);
|
||||
|
||||
@@ -234,6 +234,10 @@ public:
|
||||
JSC::JSValue HTTPSResponseSinkPrototype() const { return m_JSHTTPSResponseSinkClassStructure.prototypeInitializedOnMainThread(this); }
|
||||
JSC::JSValue JSReadableHTTPSResponseSinkControllerPrototype() const { return m_JSHTTPSResponseControllerPrototype.getInitializedOnMainThread(this); }
|
||||
|
||||
JSC::Structure* JSBakeResponseStructure() const { return m_JSBakeResponseClassStructure.getInitializedOnMainThread(this); }
|
||||
JSC::JSObject* JSBakeResponseConstructor() { return m_JSBakeResponseClassStructure.constructorInitializedOnMainThread(this); }
|
||||
JSC::JSValue JSBakeResponsePrototype() const { return m_JSBakeResponseClassStructure.prototypeInitializedOnMainThread(this); }
|
||||
|
||||
JSC::Structure* NetworkSinkStructure() const { return m_JSNetworkSinkClassStructure.getInitializedOnMainThread(this); }
|
||||
JSC::JSObject* NetworkSink() { return m_JSNetworkSinkClassStructure.constructorInitializedOnMainThread(this); }
|
||||
JSC::JSValue NetworkSinkPrototype() const { return m_JSNetworkSinkClassStructure.prototypeInitializedOnMainThread(this); }
|
||||
@@ -527,6 +531,7 @@ public:
|
||||
V(private, LazyClassStructure, m_JSFileSinkClassStructure) \
|
||||
V(private, LazyClassStructure, m_JSHTTPResponseSinkClassStructure) \
|
||||
V(private, LazyClassStructure, m_JSHTTPSResponseSinkClassStructure) \
|
||||
V(public, LazyClassStructure, m_JSBakeResponseClassStructure) \
|
||||
V(private, LazyClassStructure, m_JSNetworkSinkClassStructure) \
|
||||
\
|
||||
V(private, LazyClassStructure, m_JSStringDecoderClassStructure) \
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
ResolveError GlobalObject::m_JSResolveMessage ClassStructure
|
||||
ResolveMessage GlobalObject::m_JSResolveMessage ClassStructure
|
||||
Response GlobalObject::m_JSResponse ClassStructure
|
||||
SSRResponse GlobalObject::m_JSBakeResponseClassStructure ClassStructure
|
||||
TextDecoder GlobalObject::m_JSTextDecoder ClassStructure
|
||||
|
||||
AbortController AbortControllerConstructorCallback PropertyCallback
|
||||
|
||||
@@ -947,6 +947,7 @@ public:
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSPrivateKeyObject;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServerRouteList;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBunRequest;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBakeResponse;
|
||||
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSConnectionsList;
|
||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSHTTPParser;
|
||||
|
||||
@@ -942,6 +942,7 @@ public:
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForJSHash;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForServerRouteList;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForBunRequest;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForBakeResponse;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForJSDiffieHellman;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForJSDiffieHellmanGroup;
|
||||
std::unique_ptr<IsoSubspace> m_subspaceForJSECDH;
|
||||
|
||||
@@ -30,8 +30,6 @@ redirected: bool = false,
|
||||
/// In the server we use a flag response_protected to protect/unprotect the response
|
||||
ref_count: u32 = 1,
|
||||
|
||||
is_jsx: bool = false,
|
||||
|
||||
// We must report a consistent value for this
|
||||
reported_estimated_size: usize = 0,
|
||||
|
||||
@@ -626,9 +624,30 @@ pub fn constructError(
|
||||
}
|
||||
|
||||
pub fn constructor(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame, this_value: jsc.JSValue) bun.JSError!*Response {
|
||||
return constructorImpl(globalThis, callframe, this_value, false);
|
||||
}
|
||||
|
||||
pub fn ResponseClass__constructForSSR(globalObject: *jsc.JSGlobalObject, callFrame: *jsc.CallFrame, thisValue: jsc.JSValue) callconv(jsc.conv) ?*anyopaque {
|
||||
return @as(*Response, Response.constructor(globalObject, callFrame, thisValue) catch |err| switch (err) {
|
||||
error.JSError => return null,
|
||||
error.OutOfMemory => {
|
||||
globalObject.throwOutOfMemory() catch {};
|
||||
return null;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
comptime {
|
||||
@export(&ResponseClass__constructForSSR, .{ .name = "ResponseClass__constructForSSR" });
|
||||
}
|
||||
|
||||
pub fn constructorForSSR(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame, this_value: jsc.JSValue) bun.JSError!*Response {
|
||||
return constructorImpl(globalThis, callframe, this_value);
|
||||
}
|
||||
|
||||
pub fn constructorImpl(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame, this_value: jsc.JSValue, bake_ssr_response_enabled: bool) bun.JSError!*Response {
|
||||
var arguments = callframe.argumentsAsArray(2);
|
||||
|
||||
var is_jsx = false;
|
||||
if (!arguments[0].isUndefinedOrNull() and arguments[0].isObject()) {
|
||||
if (arguments[0].as(Blob)) |blob| {
|
||||
if (blob.isS3()) {
|
||||
@@ -664,21 +683,21 @@ pub fn constructor(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame, t
|
||||
|
||||
// Special case for bake: allow `return new Response(<jsx> ... </jsx>, { ... }`
|
||||
// inside of a react component
|
||||
if (globalThis.allowJSXInResponseConstructor()) {
|
||||
const arg = arguments[0];
|
||||
// Check if it's a JSX element (object with $$typeof)
|
||||
if (try arg.isJSXElement(globalThis)) {
|
||||
const vm = globalThis.bunVM();
|
||||
if (vm.dev_server_async_local_storage.get()) |async_local_storage| {
|
||||
try assertStreamingDisabled(globalThis, async_local_storage, "new Response(<jsx />, { ... })");
|
||||
}
|
||||
if (bake_ssr_response_enabled and globalThis.allowJSXInResponseConstructor()) {
|
||||
_ = this_value;
|
||||
// const arg = arguments[0];
|
||||
// // Check if it's a JSX element (object with $$typeof)
|
||||
// if (try arg.isJSXElement(globalThis)) {
|
||||
// const vm = globalThis.bunVM();
|
||||
// if (vm.dev_server_async_local_storage.get()) |async_local_storage| {
|
||||
// try assertStreamingDisabled(globalThis, async_local_storage, "new Response(<jsx />, { ... })");
|
||||
// }
|
||||
|
||||
// Pass the response options (arguments[1]) to transformToReactElement
|
||||
// so it can store them for later use when the component is rendered
|
||||
const responseOptions = if (arguments[1].isObject()) arguments[1] else .js_undefined;
|
||||
try JSValue.transformToReactElementWithOptions(this_value, arg, responseOptions, globalThis);
|
||||
is_jsx = true;
|
||||
}
|
||||
// // Pass the response options (arguments[1]) to transformToReactElement
|
||||
// // so it can store them for later use when the component is rendered
|
||||
// const responseOptions = if (arguments[1].isObject()) arguments[1] else .js_undefined;
|
||||
// try JSValue.transformToReactElementWithOptions(this_value, arg, responseOptions, globalThis);
|
||||
// }
|
||||
}
|
||||
}
|
||||
var init: Init = (brk: {
|
||||
@@ -719,7 +738,6 @@ pub fn constructor(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame, t
|
||||
var response = bun.new(Response, Response{
|
||||
.body = body,
|
||||
.init = init,
|
||||
.is_jsx = is_jsx,
|
||||
});
|
||||
|
||||
if (response.body.value == .Blob and
|
||||
|
||||
@@ -69,6 +69,7 @@ export default [
|
||||
name: "Response",
|
||||
construct: true,
|
||||
finalize: true,
|
||||
final: false,
|
||||
JSType: "0b11101110",
|
||||
configurable: false,
|
||||
estimatedSize: true,
|
||||
|
||||
Reference in New Issue
Block a user