aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/modules/_NativeModule.h
blob: b23906ad093866b7e4458fe7c7ae96f8e58e1466 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// clang-format off
#pragma once
#include "JSBuffer.h"
#include "JavaScriptCore/JSGlobalObject.h"
#include "JavaScriptCore/ObjectConstructor.h"
#include "ZigGlobalObject.h"

// These modules are implemented in native code as a function which writes ESM
// export key+value pairs. The following macros help simplify the implementation
// of these functions.

// To add a new native module
//   1. Add a new line to `BUN_FOREACH_NATIVE_MODULE`
//   2. Add a case to `module_loader.zig` that resolves the import.
//   3. Add a new file in this folder named after the module, camelcase and suffixed with Module,
//      like "NodeBufferModule.h" or "BunJSCModule.h". It should call DEFINE_NATIVE_MODULE(name).
//
//      The native module function is called to create the module object:
//      - INIT_NATIVE_MODULE(n) is called with the number of exports
//      - put(id, jsvalue) adds an export
//      - putNativeFn(id, nativefn) lets you quickly add from `JSC_DEFINE_HOST_FUNCTION`
//      - NATIVE_MODULE_FINISH() do asserts and finalize everything.
// If you decide to not use INIT_NATIVE_MODULE. make sure the first property
// given is the default export

#define BUN_FOREACH_NATIVE_MODULE(macro) \
    macro("bun"_s, BunObject) \
    macro("bun:jsc"_s, BunJSC) \
    macro("node:buffer"_s, NodeBuffer) \
    macro("node:constants"_s, NodeConstants) \
    macro("node:module"_s, NodeModule) \
    macro("node:process"_s, NodeProcess) \
    macro("node:string_decoder"_s, NodeStringDecoder) \
    macro("node:util/types"_s, NodeUtilTypes)  \
    macro("utf-8-validate"_s, UTF8Validate) \

#if ASSERT_ENABLED

// This function is a lie. It doesnt return, but rather it performs an assertion
// that what you passed to INIT_NATIVE_MODULE is indeed correct.
#define RETURN_NATIVE_MODULE()                                                 \
  ASSERT_WITH_MESSAGE(numberOfActualExportNames == passedNumberOfExportNames,  \
                      "NATIVE_MODULE_START() was given the incorrect value.");

#define __NATIVE_MODULE_ASSERT_DECL                                            \
  int numberOfActualExportNames = 0;                                           \
  int passedNumberOfExportNames = numberOfExportNames;                         \
#define __NATIVE_MODULE_ASSERT_INCR numberOfActualExportNames++;

#else

#define RETURN_NATIVE_MODULE() ;
#define __NATIVE_MODULE_ASSERT_INCR ;
#define __NATIVE_MODULE_ASSERT_DECL ;

#endif

#define DEFINE_NATIVE_MODULE(name)                                             \
  inline void generateNativeModule_##name(                                     \
      JSC::JSGlobalObject *lexicalGlobalObject, JSC::Identifier moduleKey,     \
      Vector<JSC::Identifier, 4> &exportNames,                                 \
      JSC::MarkedArgumentBuffer &exportValues)

#define INIT_NATIVE_MODULE(numberOfExportNames)                                \
  Zig::GlobalObject *globalObject =                                            \
      reinterpret_cast<Zig::GlobalObject *>(lexicalGlobalObject);              \
  JSC::VM &vm = globalObject->vm();                                            \
  JSC::JSObject *defaultObject = JSC::constructEmptyObject(                    \
      globalObject, globalObject->objectPrototype(), numberOfExportNames);     \
  __NATIVE_MODULE_ASSERT_DECL                                                  \
  auto put = [&](JSC::Identifier name, JSC::JSValue value) {                   \
    defaultObject->putDirect(vm, name, value);                                 \
    exportNames.append(name);                                                  \
    exportValues.append(value);                                                \
    __NATIVE_MODULE_ASSERT_INCR                                                \
  };                                                                           \
  auto putNativeFn = [&](JSC::Identifier name, JSC::NativeFunction ptr) {      \
    JSC::JSFunction *value = JSC::JSFunction::create(                          \
        vm, globalObject, 1, name.string(), ptr,                               \
        JSC::ImplementationVisibility::Public, JSC::NoIntrinsic, ptr);         \
    defaultObject->putDirect(vm, name, value);                                 \
    exportNames.append(name);                                                  \
    exportValues.append(value);                                                \
    __NATIVE_MODULE_ASSERT_INCR                                                \
  };                                                                           \
  exportNames.reserveCapacity(numberOfExportNames + 1);                        \
  exportValues.ensureCapacity(numberOfExportNames + 1);                        \
  exportNames.append(vm.propertyNames->defaultKeyword);                        \
  exportValues.append(defaultObject);                                          \
  while (0) {                                                                  \
  }
retro' width='13' height='13' alt='Gravatar' /> André Alves 3-0/+13 2023-08-22Deprecate drafts feature (#8099)Gravatar Bjorn Lu 7-7/+41 2023-08-21Use more permissive type for `defineCollection` schema option (#8163)Gravatar Chris Swithinbank 2-5/+7 2023-08-21feat: style scoped hash is lowercase (#8180)Gravatar Emanuele Stoppa 4-7/+48 2023-08-21RC Release candidate (#8179)Gravatar Matthew Phillips 2-1/+32 2023-08-21Set Markdoc integration version to a minor (#8177)Gravatar Matthew Phillips 1-1/+1 2023-08-21fix(@astrojs/node): handler should work with `express` (#8176)Gravatar Emanuele Stoppa 7-16/+221 2023-08-21[docs] deprecate build.split and build.excludeMiddleware in config ref (#8158)Gravatar Sarah Rainsberger 1-25/+7 2023-08-21chore: lock fileGravatar Emanuele Stoppa 1-0/+4 2023-08-21[ci] formatGravatar natemoo-re 4-9/+15 2023-08-21Stringify shouldn't throw on user object during rendering (#8127)Gravatar Nate Moore 9-46/+115 2023-08-21[ci] formatGravatar natemoo-re 1-1/+4 2023-08-21fix(dev): open to base path (#8123)Gravatar Nate Moore 2-1/+8 2023-08-21chore(gitpod): resolve potential globbing and word splitting issue (#8124)Gravatar Ben Elan 1-1/+1 2023-08-21fix(#6965): fix build stats (#8122)Gravatar Nate Moore 2-1/+8 2023-08-21only update our own history entires during back navigation through view trans...Gravatar Martin Trapp 2-3/+11 2023-08-21fix: reinsert attribute to specify direction of ViewTransition (forward / bac...Gravatar Martin Trapp 2-7/+12 2023-08-21Remove deprecated APIs (#8170)Gravatar Bjorn Lu 4-107/+5 2023-08-21Remove pre-shiki v0.14 theme names (#8169)Gravatar Bjorn Lu 6-80/+14 2023-08-21[docs] JSX framework integration READMEs (#8151)Gravatar Sarah Rainsberger 3-0/+104 2023-08-21fix(assets): Add missing type for imageConfig export (#8171)Gravatar Erika 2-1/+7 2023-08-21Deprecate simple objects from endpoints (#8132)Gravatar Bjorn Lu 20-201/+243 2023-08-18[docs] update scopedStyleStragegy default and description (#8148)Gravatar Sarah Rainsberger 1-2/+2 2023-08-18[ci] release (#8145)astro@2.10.12@astrojs/react@2.3.2@astrojs/node@5.3.5Gravatar Houston (Bot) 46-92/+98 2023-08-18Fix missing package file regression (#8149)Gravatar Matthew Phillips 2-1/+7 2023-08-18fix(node): delegate preview's not found and error handling to core/app (#8141)Gravatar Arsh 2-9/+6 2023-08-18Replace `class:list` implementation with `clsx` (#8142)Gravatar Nate Moore 12-68/+133 2023-08-18[ci] formatGravatar matthewp 1-1/+4 2023-08-18fix(data collections): normalize file paths for DataEntry.id (#8144)Gravatar Arsh 2-1/+6 2023-08-18[ci] release (beta) (#8140)astro@3.0.0-beta.4Gravatar Houston (Bot) 41-65/+72 2023-08-18[error messages] Update image errors-data.ts (#8126)Gravatar Sarah Rainsberger 1-12/+12 2023-08-18fix(polyfills): Use object shape for Stackblitz polyfill listGravatar Princesseuh 1-2/+2 2023-08-18fix: polyfill File using undici instead of node:buffer (#8139)Gravatar Erika 2-8/+9 2023-08-18[ci] release (beta) (#8073)create-astro@4.0.0-beta.1astro@3.0.0-beta.3@astrojs/vercel@4.0.0-beta.3@astrojs/telemetry@3.0.0-beta.2@astrojs/svelte@4.0.0-beta.1@astrojs/solid-js@3.0.0-beta.2@astrojs/react@3.0.0-beta.3@astrojs/mdx@1.0.0-beta.1@astrojs/cloudflare@7.0.0-beta.2Gravatar Houston (Bot) 63-117/+389 2023-08-18[ci] release (#8138)astro@2.10.11@astrojs/react@2.3.1Gravatar Houston (Bot) 44-80/+82 2023-08-18[ci] formatGravatar natemoo-re 1-1/+1 2023-08-18Fix 404 response leading to an infinite loop when there is no 404 page (#8136)Gravatar André Alves 2-1/+10 2023-08-18fix(react): add missing export (#8137)Gravatar Nate Moore 2-1/+7 2023-08-18[ci] release (#8096)create-astro@3.2.2astro@2.10.10@astrojs/vercel@3.8.2@astrojs/svelte@3.1.1@astrojs/solid-js@2.2.1@astrojs/react@2.3.0Gravatar Houston (Bot) 63-197/+186 2023-08-18changeset(next): inlineStylesheets default switch is major (#8133)Gravatar Arsh 1-1/+1 2023-08-18feat: add polyfills for stackblitz (#8130)Gravatar Erika 7-6/+86