Files
bun.sh/src/bun.js/bindings/JSFFIFunction.cpp
Jarred Sumner 7485c7c7cb feat: Windows + CMake Build System (#4410)
* Prepare for windows event loop

* More progress

* Update libuv.zig

* wip

* Make compiling each dependency a shell script

* Bump mimalloc

* Add the build scripts

* Update settings.json

* Fix a bunch of compiler warnings

* Remove more warnings

* more warnings

* cmake works

* Update JSSQLStatement.h

* put it in the zig file

* Fix usockets warnings

* Fixup

* Fix one of the compiler errors

* chunk

* draw the rest of the owl

* theres more

* Rename Process -> BunProcess

Works around a Windows issue

* Add musl polyfill for memmem on Windows

* More

* 12 mb

* Fix getenvZ

* fix variosu issues

* Add fast-ish path for bun install on Windows

* Update windows.zig

* Update windows.zig

* Fix build issue

* it works

* hmmm

* Rename file

* Fixups

* Update wtf-bindings.cpp

* Update src/bun.js/bindings/headers-handwritten.h

Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com>

* further!

* more

* Update .gitignore

* hm

* quite a lot of fixes

* Update CMakeLists.txt

* zig fmt

* Many more things are starting to work.

* reb

* regenaret

* Update JSSink.h

* fixup

* fetch works

* Bun.serve() and much of the event loop works now

* Make require() work

* bun install progress

* more things work

* use less std.os

* Fixes

* small fixes

* Bump

* Bummp

* Undo that change

* We have to bump the version of Debian because libarchive has a higher minimum requirement

* ok

* some clenaup

* windows

* Update bun.zig

* fixup

* avoid duplicate symbols

* avoid undefined symbols

* bump

* Remove issue template for install

It's not used, and use the bug issue instead.

* Add types for cp and cpSync

* Add types for watchFile and unwatchFile

* Add bun-types to 'bun fmt' script

* Update nodejs compat docs cp/cpSync/watchFile/unwatchFile (#4525)

* feat(fetch) rejectUnauthorized and checkServerIdentity (#4514)

* enable root certs on fetch

* rebase

* fix lookup

* some fixes and improvements

* fmt

* more fixes

* more fixes

* check detached onHandshake

* fix promise case

* fix cert non-Native

* add fetch tls tests

* more one test

* churn

* Update feature_flags.zig

* Update response.zig

* Revert "avoid undefined symbols"

This reverts commit ca835b726f.

* Revert "avoid duplicate symbols"

This reverts commit 4ac6ca8700.

* Update feature_flags.zig

* Set permissions

* more

* Update mimalloc

* Fix sqlite test failures

* Fix some test failures

* Make sure we remove libusockets is removed

* hm

* [dave]: fix webcrypto crash

* bump

* Update index.ts

* windows zig compiles

* cmake on mac works

* progress

* yay

* bun run build

* fix

* ok

* oops

* asdfasfdafdsafda

* fghjkl

* git ignore

* wow

* Process -> BunProcess

* hmm

* blah

* finalize merge

* now it only has linker errors on mac

* sdfadsf

* g

* getting farther

* sxdcvbnmk,

* adfhjskfjdhkas

* a

* fgh

* update build dot zig

* asdfg

* theoretical -DCANARY flag we can use

* asdf

* cool

* okay

* colorterm

* New build workflow

* Fix script

* Use sudo

* More sudo

* Tweak dependencies

* Another sudo attempt

* Tweak script

* 16.0 -> 16

* Tweak script

* Tweak script

* Tweak script

* Tweak script

* Tweak script

* bun install

* ssh into github actions

* add more to ssh

* Fix postinstal

* Skip llvm

* New dockerfile

* Build

* More changes to Dockerfile

* chaos chaos chaos

* okay

* a

* more cmake nonsense

* add unified sources code (does not work)

* stuff

* prepare for CI builds

* ok

* yay

* yeah

* make this more stable simply by trying again if it fails, 5 times, then lose. it fixes the stability issue i was running into L O L

* messing with ci

* x

* a

* clean dependencies before build

* oops

* this is not going to work but its closer

* not gonna work either

* a

* a

* did i do it

* a

* a

* work around weird fs+Bun.build issues

* properly pass debug flag correctly

* idk im sorry

* lose

* maybe

* run the tests please

* a

* fix zlib script

* a

* hi

* prevent stupid ci issue

* i totally didnt leave in a syntax error on cmakelists

* a

* lol

* relax

* 😭

* a

* SO SILLY

* 😡 one line mistake

* one character diff

* fix linking symbols missing

* work on dependency scripts

* does this work now?

* fix mac build

* a

* bump!

* woops

* add macos baseline build

* .

* fix sqlite and also enable $assert/$debug support in builtin functions

* okay

* oops

* zig upgrade lol

* Merge

* Fix spawn test issue

* Set a timeout

* yeah

* etc

* mi

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com>
Co-authored-by: Ashcon Partovi <ashcon@partovi.net>
Co-authored-by: Birk Skyum <74932975+birkskyum@users.noreply.github.com>
Co-authored-by: dave caruso <me@paperdave.net>
2023-10-27 01:51:56 -07:00

401 lines
16 KiB
C++

/*
* Copyright (C) 2015-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "root.h"
#include "JSFFIFunction.h"
#include <JavaScriptCore/JSCJSValueInlines.h>
#include <JavaScriptCore/VM.h>
#include "ZigGlobalObject.h"
#include <JavaScriptCore/DOMJITAbstractHeap.h>
#include "DOMJITIDLConvert.h"
#include "DOMJITIDLType.h"
#include "DOMJITIDLTypeFilter.h"
#include "DOMJITHelpers.h"
class FFICallbackFunctionWrapper {
WTF_MAKE_FAST_ALLOCATED;
public:
JSC::Strong<JSC::JSFunction> m_function;
JSC::Strong<Zig::GlobalObject> globalObject;
~FFICallbackFunctionWrapper() = default;
FFICallbackFunctionWrapper(JSC::JSFunction* function, Zig::GlobalObject* globalObject)
: m_function(globalObject->vm(), function)
, globalObject(globalObject->vm(), globalObject)
{
}
};
extern "C" void FFICallbackFunctionWrapper_destroy(FFICallbackFunctionWrapper* wrapper)
{
delete wrapper;
}
extern "C" FFICallbackFunctionWrapper* Bun__createFFICallbackFunction(
Zig::GlobalObject* globalObject,
JSC::EncodedJSValue callbackFn)
{
auto* vm = &globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(*vm);
auto* callbackFunction = jsCast<JSC::JSFunction*>(JSC::JSValue::decode(callbackFn));
auto* wrapper = new FFICallbackFunctionWrapper(callbackFunction, globalObject);
return wrapper;
}
extern "C" Zig::JSFFIFunction* Bun__CreateFFIFunctionWithData(Zig::GlobalObject* globalObject, const ZigString* symbolName, unsigned argCount, Zig::FFIFunction functionPointer, bool strong, void* data)
{
JSC::VM& vm = globalObject->vm();
Zig::JSFFIFunction* function = Zig::JSFFIFunction::create(vm, globalObject, argCount, symbolName != nullptr ? Zig::toStringCopy(*symbolName) : String(), functionPointer, JSC::NoIntrinsic);
if (strong)
globalObject->trackFFIFunction(function);
function->dataPtr = data;
return function;
}
extern "C" JSC::EncodedJSValue Bun__CreateFFIFunctionWithDataValue(Zig::GlobalObject* globalObject, const ZigString* symbolName, unsigned argCount, Zig::FFIFunction functionPointer, bool strong, void* data)
{
return JSC::JSValue::encode(Bun__CreateFFIFunctionWithData(globalObject, symbolName, argCount, functionPointer, strong, data));
}
extern "C" Zig::JSFFIFunction* Bun__CreateFFIFunction(Zig::GlobalObject* globalObject, const ZigString* symbolName, unsigned argCount, Zig::FFIFunction functionPointer, bool strong)
{
return Bun__CreateFFIFunctionWithData(globalObject, symbolName, argCount, functionPointer, strong, nullptr);
}
extern "C" void* Bun__FFIFunction_getDataPtr(JSC::EncodedJSValue jsValue)
{
Zig::JSFFIFunction* function = jsDynamicCast<Zig::JSFFIFunction*>(JSC::JSValue::decode(jsValue));
if (!function)
return nullptr;
return function->dataPtr;
}
extern "C" void Bun__FFIFunction_setDataPtr(JSC::EncodedJSValue jsValue, void* ptr)
{
Zig::JSFFIFunction* function = jsDynamicCast<Zig::JSFFIFunction*>(JSC::JSValue::decode(jsValue));
if (!function)
return;
function->dataPtr = ptr;
}
extern "C" void Bun__untrackFFIFunction(Zig::GlobalObject* globalObject, JSC::EncodedJSValue function)
{
globalObject->untrackFFIFunction(JSC::jsCast<JSC::JSFunction*>(JSC::JSValue::decode(function)));
}
extern "C" JSC::EncodedJSValue Bun__CreateFFIFunctionValue(Zig::GlobalObject* globalObject, const ZigString* symbolName, unsigned argCount, Zig::FFIFunction functionPointer, bool strong, bool addPtrField)
{
auto* function = Bun__CreateFFIFunction(globalObject, symbolName, argCount, functionPointer, strong);
if (addPtrField) {
auto& vm = globalObject->vm();
// We should only expose the "ptr" field when it's a JSCallback for bun:ffi.
// Not for internal usages of this function type.
// We should also consider a separate JSFunction type for our usage to not have this branch in the first place...
function->putDirect(vm, JSC::Identifier::fromString(vm, String(MAKE_STATIC_STRING_IMPL("ptr"))), JSC::jsNumber(bitwise_cast<double>(functionPointer)), JSC::PropertyAttribute::ReadOnly | 0);
}
return JSC::JSValue::encode(function);
}
namespace Zig {
using namespace JSC;
const ClassInfo JSFFIFunction::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFFIFunction) };
JSFFIFunction::JSFFIFunction(VM& vm, NativeExecutable* executable, JSGlobalObject* globalObject, Structure* structure, FFIFunction&& function)
: Base(vm, executable, globalObject, structure)
, m_function(WTFMove(function))
{
// used in NAPI
dataPtr = nullptr;
}
template<typename Visitor>
void JSFFIFunction::visitChildrenImpl(JSCell* cell, Visitor& visitor)
{
JSFFIFunction* thisObject = jsCast<JSFFIFunction*>(cell);
ASSERT_GC_OBJECT_INHERITS(thisObject, info());
Base::visitChildren(thisObject, visitor);
}
DEFINE_VISIT_CHILDREN(JSFFIFunction);
void JSFFIFunction::finishCreation(VM& vm, NativeExecutable* executable, unsigned length, const String& name)
{
Base::finishCreation(vm, executable, length, name);
ASSERT(inherits(info()));
}
JSFFIFunction* JSFFIFunction::create(VM& vm, Zig::GlobalObject* globalObject, unsigned length, const String& name, FFIFunction FFIFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
{
NativeExecutable* executable = vm.getHostFunction(FFIFunction, ImplementationVisibility::Public, intrinsic, FFIFunction, nullptr, name);
Structure* structure = globalObject->FFIFunctionStructure();
JSFFIFunction* function = new (NotNull, allocateCell<JSFFIFunction>(vm)) JSFFIFunction(vm, executable, globalObject, structure, WTFMove(FFIFunction));
function->finishCreation(vm, executable, length, name);
return function;
}
} // namespace JSC
extern "C" JSC::EncodedJSValue
FFI_Callback_call(FFICallbackFunctionWrapper& wrapper, size_t argCount, JSC::EncodedJSValue* args)
{
auto* function = wrapper.m_function.get();
auto* globalObject = wrapper.globalObject.get();
auto& vm = globalObject->vm();
JSC::MarkedArgumentBuffer arguments;
for (size_t i = 0; i < argCount; ++i)
arguments.appendWithCrashOnOverflow(JSC::JSValue::decode(args[i]));
WTF::NakedPtr<JSC::Exception> exception;
auto result = JSC::call(globalObject, function, JSC::getCallData(function), JSC::jsUndefined(), arguments, exception);
if (UNLIKELY(exception)) {
auto scope = DECLARE_THROW_SCOPE(vm);
scope.throwException(globalObject, exception);
return JSC::JSValue::encode(JSC::jsNull());
}
return JSC::JSValue::encode(result);
}
extern "C" void
FFI_Callback_threadsafe_call(FFICallbackFunctionWrapper& wrapper, size_t argCount, JSC::EncodedJSValue* args)
{
auto* globalObject = wrapper.globalObject.get();
WTF::Vector<JSC::EncodedJSValue, 8> argsVec;
for (size_t i = 0; i < argCount; ++i)
argsVec.append(args[i]);
WebCore::ScriptExecutionContext::postTaskTo(globalObject->scriptExecutionContext()->identifier(), [argsVec = WTFMove(argsVec), wrapper](WebCore::ScriptExecutionContext& ctx) mutable {
auto* globalObject = JSC::jsCast<Zig::GlobalObject*>(ctx.jsGlobalObject());
auto& vm = globalObject->vm();
JSC::MarkedArgumentBuffer arguments;
auto* function = wrapper.m_function.get();
for (size_t i = 0; i < argsVec.size(); ++i)
arguments.appendWithCrashOnOverflow(JSC::JSValue::decode(argsVec[i]));
WTF::NakedPtr<JSC::Exception> exception;
JSC::call(globalObject, function, JSC::getCallData(function), JSC::jsUndefined(), arguments, exception);
if (UNLIKELY(exception)) {
auto scope = DECLARE_THROW_SCOPE(vm);
scope.throwException(globalObject, exception);
return;
}
});
}
extern "C" JSC::EncodedJSValue
FFI_Callback_call_0(FFICallbackFunctionWrapper& wrapper, size_t argCount, JSC::EncodedJSValue* args)
{
auto* function = wrapper.m_function.get();
auto* globalObject = wrapper.globalObject.get();
auto& vm = globalObject->vm();
JSC::MarkedArgumentBuffer arguments;
WTF::NakedPtr<JSC::Exception> exception;
auto result = JSC::call(globalObject, function, JSC::getCallData(function), JSC::jsUndefined(), arguments, exception);
if (UNLIKELY(exception)) {
auto scope = DECLARE_THROW_SCOPE(vm);
scope.throwException(globalObject, exception);
return JSC::JSValue::encode(JSC::jsNull());
}
return JSC::JSValue::encode(result);
}
extern "C" JSC::EncodedJSValue
FFI_Callback_call_1(FFICallbackFunctionWrapper& wrapper, size_t argCount, JSC::EncodedJSValue* args)
{
auto* function = wrapper.m_function.get();
auto* globalObject = wrapper.globalObject.get();
auto& vm = globalObject->vm();
JSC::MarkedArgumentBuffer arguments;
arguments.append(JSC::JSValue::decode(args[0]));
WTF::NakedPtr<JSC::Exception> exception;
auto result = JSC::call(globalObject, function, JSC::getCallData(function), JSC::jsUndefined(), arguments, exception);
if (UNLIKELY(exception)) {
auto scope = DECLARE_THROW_SCOPE(vm);
scope.throwException(globalObject, exception);
return JSC::JSValue::encode(JSC::jsNull());
}
return JSC::JSValue::encode(result);
}
extern "C" JSC::EncodedJSValue
FFI_Callback_call_2(FFICallbackFunctionWrapper& wrapper, size_t argCount, JSC::EncodedJSValue* args)
{
auto* function = wrapper.m_function.get();
auto* globalObject = wrapper.globalObject.get();
auto& vm = globalObject->vm();
JSC::MarkedArgumentBuffer arguments;
arguments.append(JSC::JSValue::decode(args[0]));
arguments.append(JSC::JSValue::decode(args[1]));
WTF::NakedPtr<JSC::Exception> exception;
auto result = JSC::call(globalObject, function, JSC::getCallData(function), JSC::jsUndefined(), arguments, exception);
if (UNLIKELY(exception)) {
auto scope = DECLARE_THROW_SCOPE(vm);
scope.throwException(globalObject, exception);
return JSC::JSValue::encode(JSC::jsNull());
}
return JSC::JSValue::encode(result);
}
extern "C" JSC::EncodedJSValue FFI_Callback_call_3(FFICallbackFunctionWrapper& wrapper, size_t argCount, JSC::EncodedJSValue* args)
{
auto* function = wrapper.m_function.get();
auto* globalObject = wrapper.globalObject.get();
auto& vm = globalObject->vm();
JSC::MarkedArgumentBuffer arguments;
arguments.append(JSC::JSValue::decode(args[0]));
arguments.append(JSC::JSValue::decode(args[1]));
arguments.append(JSC::JSValue::decode(args[2]));
WTF::NakedPtr<JSC::Exception> exception;
auto result = JSC::call(globalObject, function, JSC::getCallData(function), JSC::jsUndefined(), arguments, exception);
if (UNLIKELY(exception)) {
auto scope = DECLARE_THROW_SCOPE(vm);
scope.throwException(globalObject, exception);
return JSC::JSValue::encode(JSC::jsNull());
}
return JSC::JSValue::encode(result);
}
extern "C" JSC::EncodedJSValue FFI_Callback_call_4(FFICallbackFunctionWrapper& wrapper, size_t argCount, JSC::EncodedJSValue* args)
{
auto* function = wrapper.m_function.get();
auto* globalObject = wrapper.globalObject.get();
auto& vm = globalObject->vm();
JSC::MarkedArgumentBuffer arguments;
arguments.append(JSC::JSValue::decode(args[0]));
arguments.append(JSC::JSValue::decode(args[1]));
arguments.append(JSC::JSValue::decode(args[2]));
arguments.append(JSC::JSValue::decode(args[3]));
WTF::NakedPtr<JSC::Exception> exception;
auto result = JSC::call(globalObject, function, JSC::getCallData(function), JSC::jsUndefined(), arguments, exception);
if (UNLIKELY(exception)) {
auto scope = DECLARE_THROW_SCOPE(vm);
scope.throwException(globalObject, exception);
return JSC::JSValue::encode(JSC::jsNull());
}
return JSC::JSValue::encode(result);
}
extern "C" JSC::EncodedJSValue FFI_Callback_call_5(FFICallbackFunctionWrapper& wrapper, size_t argCount, JSC::EncodedJSValue* args)
{
auto* function = wrapper.m_function.get();
auto* globalObject = wrapper.globalObject.get();
auto& vm = globalObject->vm();
JSC::MarkedArgumentBuffer arguments;
arguments.append(JSC::JSValue::decode(args[0]));
arguments.append(JSC::JSValue::decode(args[1]));
arguments.append(JSC::JSValue::decode(args[2]));
arguments.append(JSC::JSValue::decode(args[3]));
arguments.append(JSC::JSValue::decode(args[4]));
WTF::NakedPtr<JSC::Exception> exception;
auto result = JSC::call(globalObject, function, JSC::getCallData(function), JSC::jsUndefined(), arguments, exception);
if (UNLIKELY(exception)) {
auto scope = DECLARE_THROW_SCOPE(vm);
scope.throwException(globalObject, exception);
return JSC::JSValue::encode(JSC::jsNull());
}
return JSC::JSValue::encode(result);
}
extern "C" JSC::EncodedJSValue
FFI_Callback_call_6(FFICallbackFunctionWrapper& wrapper, size_t argCount, JSC::EncodedJSValue* args)
{
auto* function = wrapper.m_function.get();
auto* globalObject = wrapper.globalObject.get();
auto& vm = globalObject->vm();
JSC::MarkedArgumentBuffer arguments;
arguments.append(JSC::JSValue::decode(args[0]));
arguments.append(JSC::JSValue::decode(args[1]));
arguments.append(JSC::JSValue::decode(args[2]));
arguments.append(JSC::JSValue::decode(args[3]));
arguments.append(JSC::JSValue::decode(args[4]));
arguments.append(JSC::JSValue::decode(args[5]));
WTF::NakedPtr<JSC::Exception> exception;
auto result = JSC::call(globalObject, function, JSC::getCallData(function), JSC::jsUndefined(), arguments, exception);
if (UNLIKELY(exception)) {
auto scope = DECLARE_THROW_SCOPE(vm);
scope.throwException(globalObject, exception);
return JSC::JSValue::encode(JSC::jsNull());
}
return JSC::JSValue::encode(result);
}
extern "C" JSC::EncodedJSValue
FFI_Callback_call_7(FFICallbackFunctionWrapper& wrapper, size_t argCount, JSC::EncodedJSValue* args)
{
auto* function = wrapper.m_function.get();
auto* globalObject = wrapper.globalObject.get();
auto& vm = globalObject->vm();
JSC::MarkedArgumentBuffer arguments;
arguments.append(JSC::JSValue::decode(args[0]));
arguments.append(JSC::JSValue::decode(args[1]));
arguments.append(JSC::JSValue::decode(args[2]));
arguments.append(JSC::JSValue::decode(args[3]));
arguments.append(JSC::JSValue::decode(args[4]));
arguments.append(JSC::JSValue::decode(args[5]));
arguments.append(JSC::JSValue::decode(args[6]));
WTF::NakedPtr<JSC::Exception> exception;
auto result = JSC::call(globalObject, function, JSC::getCallData(function), JSC::jsUndefined(), arguments, exception);
if (UNLIKELY(exception)) {
auto scope = DECLARE_THROW_SCOPE(vm);
scope.throwException(globalObject, exception);
return JSC::JSValue::encode(JSC::jsNull());
}
return JSC::JSValue::encode(result);
}