File Explorer

/proc/self/root/var/runtime/node_modules/@aws-sdk/node_modules/aws-crt/source

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

module.c54.1 KB · 1621 lines
/** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ #include "auth.h"#include "checksums.h"#include "crypto.h"#include "event_stream.h"#include "http_connection.h"#include "http_connection_manager.h"#include "http_headers.h"#include "http_message.h"#include "http_stream.h"#include "io.h"#include "logger.h"#include "mqtt5_client.h"#include "mqtt_client.h"#include "mqtt_client_connection.h"#include "mqtt_request_response.h" #include <aws/cal/cal.h> #include <aws/common/clock.h>#include <aws/common/environment.h>#include <aws/common/logging.h>#include <aws/common/mutex.h>#include <aws/common/ref_count.h>#include <aws/common/rw_lock.h>#include <aws/common/system_info.h> #include <aws/event-stream/event_stream.h> #include <aws/io/event_loop.h>#include <aws/io/tls_channel_handler.h> #include <aws/http/http.h> #include <aws/auth/auth.h> #include <uv.h> /* * This is a multi-line comment to ensure that the static assert does not collide with the static asserts in * aws/common/macro.h. * */AWS_STATIC_ASSERT(NAPI_VERSION >= 4); #define AWS_DEFINE_ERROR_INFO_CRT_NODEJS(CODE, STR) AWS_DEFINE_ERROR_INFO(CODE, STR, "aws-crt-nodejs") /* TODO: * Hardcoded enum value for `napi_no_external_buffers_allowed`. * The enum `napi_no_external_buffers_allowed` is introduced in node21 and backport * to node 14.21.2, 16.19.0, 18.13.0. * Use `napi_no_external_buffers_allowed` for external buffer related changes after bump to node 21 */#define NAPI_NO_EXTERNAL_BUFFER_ENUM_VALUE 22 static bool s_tsfn_enabled = false;static struct aws_rw_lock s_tsfn_lock; /* clang-format off */static struct aws_error_info s_errors[] = {    AWS_DEFINE_ERROR_INFO_CRT_NODEJS(        AWS_CRT_NODEJS_ERROR_THREADSAFE_FUNCTION_NULL_NAPI_ENV,        "There was an attempt to execute a thread-safe napi function binding with a null napi environment.  This is usually due to the function binding being released by a shutdown/cleanup process while the execution is waiting in the queue."),    AWS_DEFINE_ERROR_INFO_CRT_NODEJS(        AWS_CRT_NODEJS_ERROR_NAPI_FAILURE,        "A N-API API call failed"),    AWS_DEFINE_ERROR_INFO_CRT_NODEJS(        AWS_CRT_NODEJS_ERROR_EVENT_STREAM_USER_CLOSE,        "User invoked close on an eventstream connection."),};/* clang-format on */ static struct aws_error_info_list s_error_list = {    .error_list = s_errors,    .count = sizeof(s_errors) / sizeof(struct aws_error_info),}; static struct aws_log_subject_info s_log_subject_infos[] = {    DEFINE_LOG_SUBJECT_INFO(AWS_LS_NODEJS_CRT_GENERAL, "node", "General Node/N-API events"),}; static struct aws_log_subject_info_list s_log_subject_list = {    .subject_list = s_log_subject_infos,    .count = AWS_ARRAY_SIZE(s_log_subject_infos),}; static uv_loop_t *s_node_uv_loop = NULL;static struct aws_event_loop *s_node_uv_event_loop = NULL;static struct aws_event_loop_group *s_node_uv_elg = NULL;static struct aws_host_resolver *s_default_host_resolver = NULL;static struct aws_client_bootstrap *s_default_client_bootstrap = NULL; int aws_napi_attach_object_property_boolean(napi_value object, napi_env env, const char *key_name, bool value) {    if (key_name == NULL) {        return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);    }     napi_value napi_boolean = NULL;     AWS_NAPI_CALL(env, napi_get_boolean(env, value, &napi_boolean), {        return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);    });    AWS_NAPI_CALL(env, napi_set_named_property(env, object, key_name, napi_boolean), {        return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);    });     return AWS_OP_SUCCESS;} int aws_napi_attach_object_property_optional_boolean(    napi_value object,    napi_env env,    const char *key_name,    const bool *value) {    if (value == NULL) {        return AWS_OP_SUCCESS;    }     return aws_napi_attach_object_property_boolean(object, env, key_name, *value);} /* * IEEE fp double analysis says 2 ^ 53 is the maximum sequential value we could support, but the napi docs for * napi_create_int64() say (2 ^ 53 - 1) so we'll use their more conservative bound. */#define MAX_ALLOWED_UINT64_T_TO_DOUBLE ((((uint64_t)1) << 53) - 1) int aws_napi_attach_object_property_u64(napi_value object, napi_env env, const char *key_name, uint64_t value) {    if (key_name == NULL) {        return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);    }     if (value > MAX_ALLOWED_UINT64_T_TO_DOUBLE) {        return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);    }     napi_value napi_i64 = NULL;     AWS_NAPI_CALL(env, napi_create_int64(env, (int64_t)value, &napi_i64), {        return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);    });    AWS_NAPI_CALL(env, napi_set_named_property(env, object, key_name, napi_i64), {        return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);    });     return AWS_OP_SUCCESS;} int aws_napi_attach_object_property_optional_u64(    napi_value object,    napi_env env,    const char *key_name,    const uint64_t *value) {    if (value == NULL) {        return AWS_OP_SUCCESS;    }     return aws_napi_attach_object_property_u64(object, env, key_name, *value);} int aws_napi_attach_object_property_u32(napi_value object, napi_env env, const char *key_name, uint32_t value) {    if (key_name == NULL) {        return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);    }     napi_value napi_u32 = NULL;     AWS_NAPI_CALL(        env, napi_create_uint32(env, value, &napi_u32), { return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE); });    AWS_NAPI_CALL(env, napi_set_named_property(env, object, key_name, napi_u32), {        return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);    });     return AWS_OP_SUCCESS;} int aws_napi_attach_object_property_optional_u32(    napi_value object,    napi_env env,    const char *key_name,    const uint32_t *value) {    if (value == NULL) {        return AWS_OP_SUCCESS;    }     return aws_napi_attach_object_property_u32(object, env, key_name, *value);} int aws_napi_attach_object_property_i32(napi_value object, napi_env env, const char *key_name, int32_t value) {    if (key_name == NULL) {        return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);    }     napi_value napi_i32 = NULL;     AWS_NAPI_CALL(        env, napi_create_int32(env, value, &napi_i32), { return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE); });    AWS_NAPI_CALL(env, napi_set_named_property(env, object, key_name, napi_i32), {        return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);    });     return AWS_OP_SUCCESS;} int aws_napi_attach_object_property_u16(napi_value object, napi_env env, const char *key_name, uint16_t value) {    return aws_napi_attach_object_property_u32(object, env, key_name, (uint32_t)value);} int aws_napi_attach_object_property_optional_u16(    napi_value object,    napi_env env,    const char *key_name,    const uint16_t *value) {    if (value == NULL) {        return AWS_OP_SUCCESS;    }     return aws_napi_attach_object_property_u16(object, env, key_name, *value);} int aws_napi_attach_object_property_string(    napi_value object,    napi_env env,    const char *key_name,    struct aws_byte_cursor value) {     if (key_name == NULL) {        return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);    }     napi_value napi_string = NULL;     AWS_NAPI_CALL(env, napi_create_string_utf8(env, (const char *)(value.ptr), value.len, &napi_string), {        return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);    });    AWS_NAPI_CALL(env, napi_set_named_property(env, object, key_name, napi_string), {        return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);    });     return AWS_OP_SUCCESS;} int aws_napi_attach_object_property_optional_string(    napi_value object,    napi_env env,    const char *key_name,    const struct aws_byte_cursor *value) {    if (value == NULL) {        return AWS_OP_SUCCESS;    }     return aws_napi_attach_object_property_string(object, env, key_name, *value);} static void s_finalize_external_binary_byte_buf(napi_env env, void *finalize_data, void *finalize_hint) {    (void)env;    (void)finalize_data;     struct aws_byte_buf *buffer = finalize_hint;    if (buffer == NULL) {        return;    }     struct aws_allocator *allocator = buffer->allocator;    aws_byte_buf_clean_up(buffer);    aws_mem_release(allocator, buffer);} int aws_napi_attach_object_property_binary_as_finalizable_external(    napi_value object,    napi_env env,    const char *key_name,    struct aws_byte_buf *data_buffer) {     if (key_name == NULL) {        return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);    }     napi_value napi_binary = NULL;     AWS_NAPI_ENSURE(        env,        aws_napi_create_external_arraybuffer(            env,            data_buffer->buffer,            data_buffer->len,            s_finalize_external_binary_byte_buf,            data_buffer,            &napi_binary));     AWS_NAPI_CALL(env, napi_set_named_property(env, object, key_name, napi_binary), {        return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);    });     return AWS_OP_SUCCESS;} enum aws_napi_get_named_property_result aws_napi_get_named_property(    napi_env env,    napi_value object,    const char *name,    napi_valuetype type,    napi_value *result) {     if (name == NULL) {        return AWS_NGNPR_NO_VALUE;    }     bool has_property = false;    if (napi_has_named_property(env, object, name, &has_property) || !has_property) {        return AWS_NGNPR_NO_VALUE;    }     napi_value property = NULL;    if (napi_get_named_property(env, object, name, &property)) {        return AWS_NGNPR_NO_VALUE;    }     if (type != napi_undefined) {        napi_valuetype property_type = napi_undefined;        if (napi_typeof(env, property, &property_type)) {            return AWS_NGNPR_INVALID_VALUE;        }         if (property_type != type) {            return AWS_NGNPR_INVALID_VALUE;        }    }     *result = property;    return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_as_uint16(    napi_env env,    napi_value object,    const char *name,    uint16_t *result) {     napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, napi_number, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     int64_t int_value = 0;    AWS_NAPI_CALL(env, napi_get_value_int64(env, node_result, &int_value), { return AWS_NGNPR_INVALID_VALUE; });     if (int_value < 0 || int_value > UINT16_MAX) {        return AWS_NGNPR_INVALID_VALUE;    }     *result = (uint16_t)int_value;    return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_as_uint32(    napi_env env,    napi_value object,    const char *name,    uint32_t *result) {     napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, napi_number, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     int64_t int_value = 0;    AWS_NAPI_CALL(env, napi_get_value_int64(env, node_result, &int_value), { return AWS_NGNPR_INVALID_VALUE; });     if (int_value < 0 || int_value > UINT32_MAX) {        return AWS_NGNPR_INVALID_VALUE;    }     *result = (uint32_t)int_value;    return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_as_uint64(    napi_env env,    napi_value object,    const char *name,    uint64_t *result) {     napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, napi_number, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     int64_t int_value = 0;    AWS_NAPI_CALL(env, napi_get_value_int64(env, node_result, &int_value), { return AWS_NGNPR_INVALID_VALUE; });     if (int_value < 0) {        return AWS_NGNPR_INVALID_VALUE;    }     *result = (uint64_t)int_value;    return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_as_uint8(    napi_env env,    napi_value object,    const char *name,    uint8_t *result) {     napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, napi_number, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     int64_t int_value = 0;    AWS_NAPI_CALL(env, napi_get_value_int64(env, node_result, &int_value), { return AWS_NGNPR_INVALID_VALUE; });     if (int_value < 0 || int_value > UINT8_MAX) {        return AWS_NGNPR_INVALID_VALUE;    }     *result = (uint8_t)int_value;    return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_as_int8(    napi_env env,    napi_value object,    const char *name,    int8_t *result) {     napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, napi_number, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     int64_t int_value = 0;    AWS_NAPI_CALL(env, napi_get_value_int64(env, node_result, &int_value), { return AWS_NGNPR_INVALID_VALUE; });     if (int_value < INT8_MIN || int_value > INT8_MAX) {        return AWS_NGNPR_INVALID_VALUE;    }     *result = (int8_t)int_value;    return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_as_int16(    napi_env env,    napi_value object,    const char *name,    int16_t *result) {     napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, napi_number, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     int64_t int_value = 0;    AWS_NAPI_CALL(env, napi_get_value_int64(env, node_result, &int_value), { return AWS_NGNPR_INVALID_VALUE; });     if (int_value < INT16_MIN || int_value > INT16_MAX) {        return AWS_NGNPR_INVALID_VALUE;    }     *result = (int16_t)int_value;    return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_as_int32(    napi_env env,    napi_value object,    const char *name,    int32_t *result) {     napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, napi_number, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     int64_t int_value = 0;    AWS_NAPI_CALL(env, napi_get_value_int64(env, node_result, &int_value), { return AWS_NGNPR_INVALID_VALUE; });     if (int_value < INT32_MIN || int_value > INT32_MAX) {        return AWS_NGNPR_INVALID_VALUE;    }     *result = (int32_t)int_value;    return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_as_int64(    napi_env env,    napi_value object,    const char *name,    int64_t *result) {     napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, napi_number, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     AWS_NAPI_CALL(env, napi_get_value_int64(env, node_result, result), { return AWS_NGNPR_INVALID_VALUE; });     return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_as_boolean(    napi_env env,    napi_value object,    const char *name,    bool *result) {    napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, napi_boolean, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     AWS_NAPI_CALL(env, napi_get_value_bool(env, node_result, result), { return AWS_NGNPR_INVALID_VALUE; });     return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_boolean_as_uint8(    napi_env env,    napi_value object,    const char *name,    uint8_t *result) {    napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, napi_boolean, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     bool bool_result = false;    AWS_NAPI_CALL(env, napi_get_value_bool(env, node_result, &bool_result), { return AWS_NGNPR_INVALID_VALUE; });     *result = bool_result ? 1 : 0;     return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_as_bytebuf(    napi_env env,    napi_value object,    const char *name,    napi_valuetype type,    struct aws_byte_buf *result) {     napi_value node_result;    enum aws_napi_get_named_property_result get_property_result =        aws_napi_get_named_property(env, object, name, type, &node_result);    if (get_property_result != AWS_NGNPR_VALID_VALUE) {        return get_property_result;    }     AWS_NAPI_CALL(env, aws_byte_buf_init_from_napi(result, env, node_result), { return AWS_NGNPR_INVALID_VALUE; });     return AWS_NGNPR_VALID_VALUE;} enum aws_napi_get_named_property_result aws_napi_get_named_property_buffer_length(    napi_env env,    napi_value object,    const char *name,    napi_valuetype type,    size_t *length_out) {     struct aws_byte_buf buffer;    AWS_ZERO_STRUCT(buffer);     enum aws_napi_get_named_property_result result =        aws_napi_get_named_property_as_bytebuf(env, object, name, type, &buffer);    if (result == AWS_NGNPR_VALID_VALUE) {        *length_out = buffer.len;    }     aws_byte_buf_clean_up(&buffer);     return result;} static int s_typed_array_element_type_to_byte_length(napi_typedarray_type type, size_t *element_length) {    switch (type) {        case napi_int8_array:        case napi_uint8_array:        case napi_uint8_clamped_array:            *element_length = 1;            return AWS_OP_SUCCESS;         case napi_int16_array:        case napi_uint16_array:            *element_length = 2;            return AWS_OP_SUCCESS;         case napi_int32_array:        case napi_uint32_array:        case napi_float32_array:            *element_length = 4;            return AWS_OP_SUCCESS;         case napi_float64_array:        case 9:  /*napi_bigint64_array */        case 10: /*napi_biguint64_array*/            *element_length = 8;            return AWS_OP_SUCCESS;    }     return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);} napi_status aws_byte_buf_init_from_napi(struct aws_byte_buf *buf, napi_env env, napi_value node_str) {     AWS_ASSERT(buf);     napi_valuetype type = napi_undefined;    AWS_NAPI_CALL(env, napi_typeof(env, node_str, &type), { return status; });     if (type == napi_string) {         size_t length = 0;        AWS_NAPI_CALL(env, napi_get_value_string_utf8(env, node_str, NULL, 0, &length), { return status; });         /* Node requires that the null terminator be written */        if (aws_byte_buf_init(buf, aws_napi_get_allocator(), length + 1)) {            return napi_generic_failure;        }         AWS_NAPI_CALL(env, napi_get_value_string_utf8(env, node_str, (char *)buf->buffer, buf->capacity, &buf->len), {            return status;        });        AWS_ASSERT(length == buf->len);        return napi_ok;     } else if (type == napi_object) {         bool is_expected = false;         /* Try ArrayBuffer */        AWS_NAPI_CALL(env, napi_is_arraybuffer(env, node_str, &is_expected), { return status; });        if (is_expected) {            napi_status status = napi_get_arraybuffer_info(env, node_str, (void **)&buf->buffer, &buf->len);            buf->capacity = buf->len;            return status;        }         /* Try DataView */        AWS_NAPI_CALL(env, napi_is_dataview(env, node_str, &is_expected), { return status; });        if (is_expected) {            napi_status status = napi_get_dataview_info(env, node_str, &buf->len, (void **)&buf->buffer, NULL, NULL);            buf->capacity = buf->len;            return status;        }         /* Try TypedArray */        AWS_NAPI_CALL(env, napi_is_typedarray(env, node_str, &is_expected), { return status; });        if (is_expected) {            napi_typedarray_type array_type = napi_uint8_array;            size_t length = 0;            AWS_NAPI_CALL(                env, napi_get_typedarray_info(env, node_str, &array_type, &length, (void **)&buf->buffer, NULL, NULL), {                    return status;                });             size_t element_size = 0;            if (s_typed_array_element_type_to_byte_length(array_type, &element_size)) {                return napi_invalid_arg;            }             buf->len = length * element_size;            buf->capacity = buf->len;             return napi_ok;        }    }     return napi_invalid_arg;} int aws_napi_value_get_storage_length(napi_env env, napi_value value, size_t *storage_length) {     napi_valuetype type = napi_undefined;    AWS_NAPI_CALL(env, napi_typeof(env, value, &type), { return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE); });     if (type == napi_string) {        AWS_NAPI_CALL(env, napi_get_value_string_utf8(env, value, NULL, 0, storage_length), {            return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);        });         return AWS_OP_SUCCESS;    } else if (type == napi_object) {        /* Try ArrayBuffer */        bool is_array_buffer = false;        AWS_NAPI_CALL(env, napi_is_arraybuffer(env, value, &is_array_buffer), {            return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);        });        if (is_array_buffer) {            void *buffer = NULL;            AWS_NAPI_CALL(env, napi_get_arraybuffer_info(env, value, &buffer, storage_length), {                return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);            });             return AWS_OP_SUCCESS;        }         /* Try DataView */        bool is_data_view = false;        AWS_NAPI_CALL(env, napi_is_dataview(env, value, &is_data_view), {            return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);        });        if (is_data_view) {            AWS_NAPI_CALL(env, napi_get_dataview_info(env, value, storage_length, NULL, NULL, NULL), {                return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);            });             return AWS_OP_SUCCESS;        }         /* Try TypedArray */        bool is_typed_array = false;        AWS_NAPI_CALL(env, napi_is_typedarray(env, value, &is_typed_array), {            return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);        });        if (is_typed_array) {            napi_typedarray_type array_type = napi_uint8_array;            size_t length = 0;            AWS_NAPI_CALL(env, napi_get_typedarray_info(env, value, &array_type, &length, NULL, NULL, NULL), {                return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);            });             size_t element_size = 0;            if (s_typed_array_element_type_to_byte_length(array_type, &element_size)) {                return napi_invalid_arg;            }             *storage_length = length * element_size;             return AWS_OP_SUCCESS;        }    }     return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);} int aws_napi_value_bytebuf_append(    napi_env env,    napi_value value,    struct aws_byte_buf *output_buffer,    struct aws_byte_cursor *bytes_written_cursor) {     AWS_ZERO_STRUCT(*bytes_written_cursor);     napi_valuetype type = napi_undefined;    AWS_NAPI_CALL(env, napi_typeof(env, value, &type), { return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); });     size_t open_bytes = output_buffer->capacity - output_buffer->len;    uint8_t *open_space = output_buffer->buffer + output_buffer->len;     if (type == napi_string) {        size_t bytes_written = 0;        AWS_NAPI_CALL(env, napi_get_value_string_utf8(env, value, (char *)open_space, open_bytes, &bytes_written), {            return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);        });         /* technically, we might have been truncated, but there's no way to tell */        bytes_written_cursor->ptr = open_space;        bytes_written_cursor->len = bytes_written;        output_buffer->len += bytes_written;         return AWS_OP_SUCCESS;    } else if (type == napi_object) {        /* Try ArrayBuffer */        bool is_array_buffer = false;        AWS_NAPI_CALL(env, napi_is_arraybuffer(env, value, &is_array_buffer), {            return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);        });        if (is_array_buffer) {            void *buffer = NULL;            size_t buffer_length = 0;            AWS_NAPI_CALL(env, napi_get_arraybuffer_info(env, value, &buffer, &buffer_length), {                return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);            });             bytes_written_cursor->ptr = buffer;            bytes_written_cursor->len = buffer_length;             return aws_byte_buf_append_and_update(output_buffer, bytes_written_cursor);        }         /* Try DataView */        bool is_data_view = false;        AWS_NAPI_CALL(env, napi_is_dataview(env, value, &is_data_view), {            return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);        });        if (is_data_view) {            void *buffer = NULL;            size_t buffer_length = 0;            AWS_NAPI_CALL(env, napi_get_dataview_info(env, value, &buffer_length, &buffer, NULL, NULL), {                return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);            });             bytes_written_cursor->ptr = buffer;            bytes_written_cursor->len = buffer_length;             return aws_byte_buf_append_and_update(output_buffer, bytes_written_cursor);        }         bool is_typed_array = false;        AWS_NAPI_CALL(env, napi_is_typedarray(env, value, &is_typed_array), {            return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);        });        if (is_typed_array) {            napi_typedarray_type array_type = napi_uint8_array;            size_t length = 0;            uint8_t *buffer = NULL;            AWS_NAPI_CALL(                env, napi_get_typedarray_info(env, value, &array_type, &length, (void **)&buffer, NULL, NULL), {                    return aws_raise_error(AWS_CRT_NODEJS_ERROR_NAPI_FAILURE);                });             size_t element_size = 0;            if (s_typed_array_element_type_to_byte_length(array_type, &element_size)) {                return napi_invalid_arg;            }             bytes_written_cursor->ptr = buffer;            bytes_written_cursor->len = element_size * length;             return aws_byte_buf_append_and_update(output_buffer, bytes_written_cursor);        }    }     return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);} struct aws_string *aws_string_new_from_napi(napi_env env, napi_value node_str) {     struct aws_byte_buf temp_buf;    if (aws_byte_buf_init_from_napi(&temp_buf, env, node_str)) {        return NULL;    }     struct aws_string *string = aws_string_new_from_array(aws_napi_get_allocator(), temp_buf.buffer, temp_buf.len);    aws_byte_buf_clean_up(&temp_buf);    return string;} napi_status aws_napi_create_dataview_from_byte_cursor(    napi_env env,    const struct aws_byte_cursor *cur,    napi_value *result) {     void *data = NULL;    napi_value arraybuffer;    AWS_NAPI_CALL(env, napi_create_arraybuffer(env, cur->len, &data, &arraybuffer), { return status; });     struct aws_byte_buf arraybuffer_buf = aws_byte_buf_from_empty_array(data, cur->len);    struct aws_byte_cursor input = *cur;    if (!aws_byte_buf_write_from_whole_cursor(&arraybuffer_buf, input)) {        return napi_generic_failure;    }     AWS_NAPI_CALL(env, napi_create_dataview(env, cur->len, arraybuffer, 0, result), { return status; });     return napi_ok;} bool aws_napi_is_null_or_undefined(napi_env env, napi_value value) {     napi_valuetype type = napi_undefined;    if (napi_ok != napi_typeof(env, value, &type)) {        return true;    }     return type == napi_null || type == napi_undefined;} int aws_napi_get_property_array_size(    napi_env env,    napi_value object,    const char *property_name,    size_t *array_size_out) {    napi_value napi_array = NULL;    enum aws_napi_get_named_property_result get_result =        aws_napi_get_named_property(env, object, property_name, napi_object, &napi_array);    if (get_result == AWS_NGNPR_NO_VALUE) {        *array_size_out = 0;        return AWS_OP_SUCCESS;    } else if (get_result == AWS_NGNPR_INVALID_VALUE) {        return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);    }     uint32_t array_size = 0;    AWS_NAPI_CALL(env, napi_get_array_length(env, napi_array, &array_size), {        return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);    });     *array_size_out = (size_t)array_size;     return AWS_OP_SUCCESS;} void s_aws_enable_threadsafe_function(void) {    aws_rw_lock_wlock(&s_tsfn_lock);    s_tsfn_enabled = true;    aws_rw_lock_wunlock(&s_tsfn_lock);} void s_aws_disable_threadsafe_function(void) {    aws_rw_lock_wlock(&s_tsfn_lock);    s_tsfn_enabled = false;    aws_rw_lock_wunlock(&s_tsfn_lock);} napi_value aws_napi_disable_threadsafe_function(napi_env env, napi_callback_info info) {    (void)info;    if (env == NULL) {        aws_raise_error(AWS_CRT_NODEJS_ERROR_THREADSAFE_FUNCTION_NULL_NAPI_ENV);        return NULL;    }    s_aws_disable_threadsafe_function();    return NULL;} void aws_napi_throw_last_error(napi_env env) {    const int error_code = aws_last_error();    napi_throw_error(env, aws_error_str(error_code), aws_error_debug_str(error_code));} void aws_napi_throw_last_error_with_context(napi_env env, const char *context) {    const int error_code = aws_last_error();     char full_msg[1024];    snprintf(        full_msg,        AWS_ARRAY_SIZE(full_msg),        "%s : (%s - %s)",        context,        aws_error_str(error_code),        aws_error_debug_str(error_code));    napi_throw_error(env, aws_error_str(error_code), full_msg);} struct uv_loop_s *aws_napi_get_node_uv_loop(void) {    return s_node_uv_loop;} struct aws_event_loop *aws_napi_get_node_event_loop(void) {    return s_node_uv_event_loop;} struct aws_event_loop_group *aws_napi_get_node_elg(void) {    return s_node_uv_elg;} struct aws_client_bootstrap *aws_napi_get_default_client_bootstrap(void) {    return s_default_client_bootstrap;} /* The napi_status enum has grown, and is not bound by N-API versioning */#if defined(__clang__) || defined(__GNUC__)#    pragma GCC diagnostic push#    pragma GCC diagnostic ignored "-Wswitch"#endif const char *aws_napi_status_to_str(napi_status status) {    const char *reason = "UNKNOWN";    switch (status) {        case napi_ok:            reason = "OK";            break;        case napi_invalid_arg:            reason = "napi_invalid_arg: an invalid argument was supplied";            break;        case napi_object_expected:            reason = "napi_object_expected";            break;        case napi_string_expected:            reason = "napi_name_expected";            break;        case napi_name_expected:            reason = "napi_name_expected";            break;        case napi_function_expected:            reason = "napi_function_expected";            break;        case napi_number_expected:            reason = "napi_number_expected";            break;        case napi_boolean_expected:            reason = "napi_boolean_expected";            break;        case napi_array_expected:            reason = "napi_array_expected";            break;        case napi_generic_failure:            reason = "napi_generic_failure";            break;        case napi_pending_exception:            reason = "napi_pending_exception";            break;        case napi_cancelled:            reason = "napi_cancelled";            break;        case napi_escape_called_twice:            reason = "napi_escape_called_twice";            break;        case napi_handle_scope_mismatch:            reason = "napi_handle_scope_mismatch";            break;        case napi_callback_scope_mismatch:            reason = "napi_callback_scope_mismatch";            break;        case napi_queue_full:            reason = "napi_queue_full";            break;        case napi_closing:            reason = "napi_closing";            break;        case napi_bigint_expected:            reason = "napi_bigint_expected";            break;        case NAPI_NO_EXTERNAL_BUFFER_ENUM_VALUE:            reason = "napi_no_external_buffers_allowed";            break;    }    return reason;} #if defined(__clang__) || defined(__GNUC__)#    pragma GCC diagnostic pop#endif static void s_handle_failed_callback(napi_env env, napi_value function, napi_status reason) {    /* Figure out if there's an exception pending, if so, no callbacks will ever succeed again until it's cleared */    bool pending_exception = reason == napi_pending_exception;    AWS_NAPI_ENSURE(env, napi_is_exception_pending(env, &pending_exception));    /* if there's no pending exception, but failure occurred, log what we can find and get out */    if (!pending_exception) {        const napi_extended_error_info *node_error_info = NULL;        AWS_NAPI_ENSURE(env, napi_get_last_error_info(env, &node_error_info));        AWS_NAPI_LOGF_ERROR(            "Extended error info: engine_error_code=%u error_code=%s error_message=%s",            node_error_info->engine_error_code,            aws_napi_status_to_str(node_error_info->error_code),            node_error_info->error_message);        return;    }    /* get the current exception and report it, and clear it so that execution can continue */    napi_value node_exception = NULL;    AWS_NAPI_ENSURE(env, napi_get_and_clear_last_exception(env, &node_exception));     /* figure out what the exception is */    bool is_error = false;    AWS_NAPI_ENSURE(env, napi_is_error(env, node_exception, &is_error));     /*     * Convert the function to a string. If it's a lambda, this will produce the source of the lambda, if     * it's a class function or free function, it will produce the name     */    napi_value node_function_str = NULL;    AWS_NAPI_ENSURE(env, napi_coerce_to_string(env, function, &node_function_str));    struct aws_string *function_str = aws_string_new_from_napi(env, node_function_str);    if (function_str) {        AWS_NAPI_LOGF_ERROR("Calling %s", aws_string_c_str(function_str));    }     /* If it's an Error, extract info from it and log it */    if (is_error) {        /* get the Error.message field */        napi_value node_message = NULL;        AWS_NAPI_ENSURE(env, napi_get_named_property(env, node_exception, "message", &node_message));         /* extract and log the message */        struct aws_string *message = aws_string_new_from_napi(env, node_message);        if (message) {            AWS_NAPI_LOGF_ERROR("Error: %s", aws_string_bytes(message));            aws_string_destroy(message);        } else {            AWS_NAPI_LOGF_ERROR("aws_string_new_from_napi(exception.message) failed");            return;        }         /* get the Error.stack field */        napi_value node_stack = NULL;        AWS_NAPI_ENSURE(env, napi_get_named_property(env, node_exception, "stack", &node_stack));         /* extract and log the stack trace */        struct aws_string *stacktrace = aws_string_new_from_napi(env, node_stack);        if (stacktrace) {            AWS_NAPI_LOGF_ERROR("Stack:\n%s", aws_string_bytes(stacktrace));            aws_string_destroy(stacktrace);        } else {            AWS_NAPI_LOGF_ERROR("aws_string_new_from_napi(exception.stack) failed");            return;        }         /* the Error has been reported and cleared, that's all we can do */        return;    }     /* The last thing thrown was some other sort of object/primitive, so convert it to a string and log it */    napi_value node_error_str = NULL;    AWS_NAPI_ENSURE(env, napi_coerce_to_string(env, node_exception, &node_error_str));     struct aws_string *error_str = aws_string_new_from_napi(env, node_error_str);    if (error_str) {        AWS_NAPI_LOGF_ERROR("Error: %s", aws_string_bytes(error_str));    } else {        AWS_NAPI_LOGF_ERROR("aws_string_new_from_napi(ToString(exception)) failed");        return;    }} napi_status aws_napi_create_external_arraybuffer(    napi_env env,    void *external_data,    size_t byte_length,    napi_finalize finalize_cb,    void *finalize_hint,    napi_value *result) {     napi_status external_buffer_status =        napi_create_external_arraybuffer(env, external_data, byte_length, finalize_cb, finalize_hint, result);     if (external_buffer_status == NAPI_NO_EXTERNAL_BUFFER_ENUM_VALUE) {         // The external buffer is disabled, manually copy the external_data into Node        void *napi_buf_data = NULL;        napi_status create_arraybuffer_status = napi_create_arraybuffer(env, byte_length, &napi_buf_data, result);         if (create_arraybuffer_status != napi_ok) {            AWS_NAPI_LOGF_ERROR(                "napi_create_arraybuffer (in aws_napi_create_external_arraybuffer) failed with : %s",                aws_napi_status_to_str(create_arraybuffer_status));            return create_arraybuffer_status;        }         memcpy(napi_buf_data, external_data, byte_length);         // As the data has been copied into the Node, invoke the finalize callback to make sure the        // data is released.        finalize_cb(env, finalize_hint, finalize_hint);    }     return napi_ok;} napi_status aws_napi_dispatch_threadsafe_function(    napi_env env,    napi_threadsafe_function tsfn,    napi_value this_ptr,    napi_value function,    size_t argc,    napi_value *argv) {     aws_rw_lock_rlock(&s_tsfn_lock);    napi_status result = napi_ok;    if (s_tsfn_enabled) {        napi_status call_status = napi_ok;        if (!this_ptr) {            AWS_NAPI_ENSURE(env, napi_get_undefined(env, &this_ptr));        }        AWS_NAPI_CALL(env, napi_call_function(env, this_ptr, function, argc, argv, NULL), {            call_status = status;            s_handle_failed_callback(env, function, status);        });        /* main thread can exit now */        napi_unref_threadsafe_function(env, tsfn);        /* Must always decrement the ref count, or the function will be pinned */        napi_status release_status = napi_release_threadsafe_function(tsfn, napi_tsfn_release);        result = (call_status != napi_ok) ? call_status : release_status;    }    aws_rw_lock_runlock(&s_tsfn_lock);    return result;} napi_status aws_napi_create_threadsafe_function(    napi_env env,    napi_value function,    const char *name,    napi_threadsafe_function_call_js call_js,    void *context,    napi_threadsafe_function *result) {     napi_value resource_name = NULL;    AWS_NAPI_ENSURE(env, napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &resource_name));     return napi_create_threadsafe_function(        env,        function,        NULL /*async_resource*/,        resource_name,        0 /*max_queue_size - 0 means no limit*/,        1 /*initial_thread_count*/,        NULL /*thread_finalize_data*/,        NULL /*thread_finalize_cb*/,        context,        call_js,        result);} napi_status aws_napi_release_threadsafe_function(    napi_threadsafe_function function,    napi_threadsafe_function_release_mode mode) {    napi_status result = napi_ok;    aws_rw_lock_rlock(&s_tsfn_lock);    if (s_tsfn_enabled && function) {        result = napi_release_threadsafe_function(function, mode);    }    aws_rw_lock_runlock(&s_tsfn_lock);    return result;} napi_status aws_napi_acquire_threadsafe_function(napi_threadsafe_function function) {    napi_status result = napi_ok;    aws_rw_lock_rlock(&s_tsfn_lock);    if (s_tsfn_enabled && function) {        result = napi_acquire_threadsafe_function(function);    }    aws_rw_lock_runlock(&s_tsfn_lock);    return result;} napi_status aws_napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function function) {    napi_status result = napi_ok;    aws_rw_lock_rlock(&s_tsfn_lock);    if (s_tsfn_enabled && function) {        result = napi_unref_threadsafe_function(env, function);    }    aws_rw_lock_runlock(&s_tsfn_lock);    return result;} napi_status aws_napi_queue_threadsafe_function(napi_threadsafe_function function, void *user_data) {    napi_status result = napi_ok;    aws_rw_lock_rlock(&s_tsfn_lock);    if (s_tsfn_enabled && function) {        /* increase the ref count, gets decreased when the call completes */        AWS_NAPI_ENSURE(NULL, napi_acquire_threadsafe_function(function));        result = napi_call_threadsafe_function(function, user_data, napi_tsfn_nonblocking);    }    aws_rw_lock_runlock(&s_tsfn_lock);    return result;} AWS_STATIC_STRING_FROM_LITERAL(s_mem_tracing_env_var, "AWS_CRT_MEMORY_TRACING");static struct aws_allocator *s_allocator = NULL;struct aws_allocator *aws_napi_get_allocator(void) {    if (AWS_UNLIKELY(s_allocator == NULL)) {        struct aws_string *value = NULL;        if (aws_get_environment_value(aws_default_allocator(), s_mem_tracing_env_var, &value) || value == NULL) {            return s_allocator = aws_default_allocator();        }         int level = atoi(aws_string_c_str(value));        if (level < AWS_MEMTRACE_NONE || level > AWS_MEMTRACE_STACKS) {            /* this can't go through logging, because it happens before logging is set up */            fprintf(                stderr,                "AWS_CRT_MEMORY_TRACING is set to invalid value: %s, must be 0 (none), 1 (bytes), or 2 (stacks)",                aws_string_bytes(value));            level = AWS_MEMTRACE_NONE;        }        s_allocator = aws_mem_tracer_new(aws_default_allocator(), NULL, level, 16);    }    return s_allocator;} napi_value aws_napi_native_memory(napi_env env, napi_callback_info info) {    (void)info;    napi_value node_allocated = NULL;    size_t allocated = 0;    if (aws_napi_get_allocator() != aws_default_allocator()) {        allocated = aws_mem_tracer_bytes(aws_napi_get_allocator());    }    AWS_NAPI_CALL(env, napi_create_int64(env, allocated, &node_allocated), { return NULL; });    return node_allocated;} napi_value aws_napi_native_memory_dump(napi_env env, napi_callback_info info) {    (void)info;    (void)env;    if (aws_napi_get_allocator() != aws_default_allocator()) {        aws_mem_tracer_dump(aws_napi_get_allocator());    }    return NULL;} #if defined(_WIN32)#    include <windows.h>static LONG WINAPI s_print_stack_trace(struct _EXCEPTION_POINTERS *exception_pointers) {    aws_backtrace_print(stderr, exception_pointers);    return EXCEPTION_EXECUTE_HANDLER;}#elif defined(AWS_HAVE_EXECINFO)#    include <signal.h>static void s_print_stack_trace(int sig, siginfo_t *sig_info, void *user_data) {    (void)sig;    (void)sig_info;    (void)user_data;    aws_backtrace_print(stderr, sig_info);    exit(-1);}#endif static void s_install_crash_handler(void) {#if defined(_WIN32)    SetUnhandledExceptionFilter(s_print_stack_trace);#elif defined(AWS_HAVE_EXECINFO)    struct sigaction sa;    memset(&sa, 0, sizeof(struct sigaction));    sigemptyset(&sa.sa_mask);     sa.sa_flags = SA_NODEFER;    sa.sa_sigaction = s_print_stack_trace;     sigaction(SIGSEGV, &sa, NULL);    sigaction(SIGABRT, &sa, NULL);    sigaction(SIGILL, &sa, NULL);    sigaction(SIGBUS, &sa, NULL);#endif} static void s_uninstall_crash_handler(void) {#if defined(_WIN32)    SetUnhandledExceptionFilter(NULL);#elif defined(AWS_HAVE_EXECINFO)    sigaction(SIGSEGV, NULL, NULL);    sigaction(SIGABRT, NULL, NULL);    sigaction(SIGILL, NULL, NULL);    sigaction(SIGBUS, NULL, NULL);#endif} static struct aws_mutex s_module_lock = AWS_MUTEX_INIT;static uint32_t s_module_initialize_count = 0; static void s_napi_context_finalize(napi_env env, void *user_data, void *finalize_hint) {    (void)env;    (void)finalize_hint;     aws_mutex_lock(&s_module_lock);    AWS_FATAL_ASSERT(s_module_initialize_count > 0);    --s_module_initialize_count;     if (s_module_initialize_count == 0) {         aws_client_bootstrap_release(s_default_client_bootstrap);        s_default_client_bootstrap = NULL;         aws_host_resolver_release(s_default_host_resolver);        s_default_host_resolver = NULL;         aws_event_loop_group_release(s_node_uv_elg);        s_node_uv_elg = NULL;         aws_thread_join_all_managed();         aws_unregister_log_subject_info_list(&s_log_subject_list);        aws_unregister_error_info(&s_error_list);        aws_event_stream_library_clean_up();        aws_auth_library_clean_up();        aws_mqtt_library_clean_up();         s_uninstall_crash_handler();        // clean up threadsafe function lock        aws_rw_lock_clean_up(&s_tsfn_lock);    }     struct aws_napi_context *ctx = user_data;    aws_napi_logger_destroy(ctx->logger);    struct aws_allocator *ctx_allocator = ctx->allocator;    aws_mem_release(ctx->allocator, ctx);     if (s_module_initialize_count == 0) {        if (ctx_allocator != aws_default_allocator()) {            if (s_allocator == ctx_allocator) {                s_allocator = NULL;            }            aws_mem_tracer_destroy(ctx_allocator);        }    }    aws_mutex_unlock(&s_module_lock);} static struct aws_napi_context *s_napi_context_new(struct aws_allocator *allocator, napi_env env, napi_value exports) {    struct aws_napi_context *ctx = aws_mem_calloc(allocator, 1, sizeof(struct aws_napi_context));    AWS_FATAL_ASSERT(ctx && "Failed to initialize napi context");    ctx->allocator = allocator;     /* bind the context to exports, thus binding its lifetime to that object */    AWS_NAPI_ENSURE(env, napi_wrap(env, exports, ctx, s_napi_context_finalize, NULL, NULL));     ctx->logger = aws_napi_logger_new(allocator, env);     return ctx;} /** Helper for creating and registering a function */static bool s_create_and_register_function(    napi_env env,    napi_value exports,    napi_callback fn,    const char *fn_name,    size_t fn_name_len) {     napi_value napi_fn;    AWS_NAPI_CALL(env, napi_create_function(env, fn_name, fn_name_len, fn, NULL, &napi_fn), {        napi_throw_error(env, NULL, "Unable to wrap native function");        return false;    });     AWS_NAPI_CALL(env, napi_set_named_property(env, exports, fn_name, napi_fn), {        napi_throw_error(env, NULL, "Unable to populate exports");        return false;    });     return true;} #if defined(__clang__) || defined(__GNUC__)/* Suppress compiler warnings about NAPI_MODULE_INIT(). * See: https://github.com/nodejs/node/pull/49103 */#    pragma GCC diagnostic ignored "-Wstrict-prototypes"#endif /* napi_value */ NAPI_MODULE_INIT() /* (napi_env env, napi_value exports) */ {     aws_mutex_lock(&s_module_lock);     struct aws_allocator *allocator = aws_napi_get_allocator();     if (s_module_initialize_count == 0) {        aws_rw_lock_init(&s_tsfn_lock);        s_aws_enable_threadsafe_function();         s_install_crash_handler();         aws_mqtt_library_init(allocator);        aws_auth_library_init(allocator);        aws_event_stream_library_init(allocator);        aws_register_error_info(&s_error_list);        aws_register_log_subject_info_list(&s_log_subject_list);         /* Initialize the event loop group */        /*         * We don't currently support multi-init of the module, but we should.         * Things that would need to be solved:         *    (1) global objects (event loop group, logger, allocator, more)         *    (2) multi-init/multi-cleanup of aws-c-*         *    (3) allocator cross-talk/lifetimes         */        AWS_FATAL_ASSERT(s_node_uv_elg == NULL);        s_node_uv_elg = aws_event_loop_group_new_default(allocator, 1, NULL);        AWS_FATAL_ASSERT(s_node_uv_elg != NULL);         /*         * Default host resolver and client bootstrap to use if none specific at the javascript level.  In most         * cases the user doesn't even need to know about these, so let's let them leave it out completely.         */        AWS_FATAL_ASSERT(s_default_host_resolver == NULL);         struct aws_host_resolver_default_options resolver_options = {            .max_entries = 64,            .el_group = s_node_uv_elg,        };        s_default_host_resolver = aws_host_resolver_new_default(allocator, &resolver_options);        AWS_FATAL_ASSERT(s_default_host_resolver != NULL);         AWS_FATAL_ASSERT(s_default_client_bootstrap == NULL);         struct aws_client_bootstrap_options bootstrap_options = {            .event_loop_group = s_node_uv_elg,            .host_resolver = s_default_host_resolver,        };         s_default_client_bootstrap = aws_client_bootstrap_new(allocator, &bootstrap_options);         AWS_FATAL_ASSERT(s_default_client_bootstrap != NULL);    }     ++s_module_initialize_count;     aws_mutex_unlock(&s_module_lock);     /* context is bound to exports, will be cleaned up by finalizer */    s_napi_context_new(allocator, env, exports);     napi_value null;    napi_get_null(env, &null); #define CREATE_AND_REGISTER_FN(fn)                                                                                     \    if (!s_create_and_register_function(env, exports, aws_napi_##fn, #fn, sizeof(#fn))) {                              \        return null;                                                                                                   \    }     /* Common */    CREATE_AND_REGISTER_FN(native_memory)    CREATE_AND_REGISTER_FN(native_memory_dump)    CREATE_AND_REGISTER_FN(error_code_to_string)    CREATE_AND_REGISTER_FN(error_code_to_name)    CREATE_AND_REGISTER_FN(disable_threadsafe_function)     /* IO */    CREATE_AND_REGISTER_FN(io_logging_enable)    CREATE_AND_REGISTER_FN(is_alpn_available)    CREATE_AND_REGISTER_FN(io_client_bootstrap_new)    CREATE_AND_REGISTER_FN(io_tls_cipher_preference_is_supported)    CREATE_AND_REGISTER_FN(io_tls_ctx_new)    CREATE_AND_REGISTER_FN(io_tls_connection_options_new);    CREATE_AND_REGISTER_FN(io_socket_options_new)    CREATE_AND_REGISTER_FN(io_input_stream_new)    CREATE_AND_REGISTER_FN(io_input_stream_append)    CREATE_AND_REGISTER_FN(io_pkcs11_lib_new)    CREATE_AND_REGISTER_FN(io_pkcs11_lib_close)     /* MQTT Request Response */    CREATE_AND_REGISTER_FN(mqtt_request_response_client_new_from_5)    CREATE_AND_REGISTER_FN(mqtt_request_response_client_new_from_311)    CREATE_AND_REGISTER_FN(mqtt_request_response_client_close)    CREATE_AND_REGISTER_FN(mqtt_request_response_client_submit_request)    CREATE_AND_REGISTER_FN(mqtt_streaming_operation_new)    CREATE_AND_REGISTER_FN(mqtt_streaming_operation_open)    CREATE_AND_REGISTER_FN(mqtt_streaming_operation_close)     /* MQTT5 Client */    CREATE_AND_REGISTER_FN(mqtt5_client_new)    CREATE_AND_REGISTER_FN(mqtt5_client_start)    CREATE_AND_REGISTER_FN(mqtt5_client_stop)    CREATE_AND_REGISTER_FN(mqtt5_client_subscribe)    CREATE_AND_REGISTER_FN(mqtt5_client_unsubscribe)    CREATE_AND_REGISTER_FN(mqtt5_client_publish)    CREATE_AND_REGISTER_FN(mqtt5_client_get_queue_statistics)    CREATE_AND_REGISTER_FN(mqtt5_client_invoke_publish_acknowledgement)    CREATE_AND_REGISTER_FN(mqtt5_client_close)     /* MQTT Client */    CREATE_AND_REGISTER_FN(mqtt_client_new)     /* MQTT Client Connection */    CREATE_AND_REGISTER_FN(mqtt_client_connection_new)    CREATE_AND_REGISTER_FN(mqtt_client_connection_connect)    CREATE_AND_REGISTER_FN(mqtt_client_connection_reconnect)    CREATE_AND_REGISTER_FN(mqtt_client_connection_publish)    CREATE_AND_REGISTER_FN(mqtt_client_connection_subscribe)    CREATE_AND_REGISTER_FN(mqtt_client_connection_on_message)    CREATE_AND_REGISTER_FN(mqtt_client_connection_on_closed)    CREATE_AND_REGISTER_FN(mqtt_client_connection_unsubscribe)    CREATE_AND_REGISTER_FN(mqtt_client_connection_disconnect)    CREATE_AND_REGISTER_FN(mqtt_client_connection_close)    CREATE_AND_REGISTER_FN(mqtt_client_connection_get_queue_statistics)     /* Crypto */    CREATE_AND_REGISTER_FN(hash_md5_new)    CREATE_AND_REGISTER_FN(hash_sha1_new)    CREATE_AND_REGISTER_FN(hash_sha256_new)    CREATE_AND_REGISTER_FN(hash_update)    CREATE_AND_REGISTER_FN(hash_digest)    CREATE_AND_REGISTER_FN(hash_md5_compute)    CREATE_AND_REGISTER_FN(hash_sha1_compute)    CREATE_AND_REGISTER_FN(hash_sha256_compute)    CREATE_AND_REGISTER_FN(hmac_sha256_new)    CREATE_AND_REGISTER_FN(hmac_update)    CREATE_AND_REGISTER_FN(hmac_digest)    CREATE_AND_REGISTER_FN(hmac_sha256_compute)     /* Checksums */    CREATE_AND_REGISTER_FN(checksums_crc32)    CREATE_AND_REGISTER_FN(checksums_crc32c)    CREATE_AND_REGISTER_FN(checksums_crc64nvme)     /* HTTP */    CREATE_AND_REGISTER_FN(http_proxy_options_new)    CREATE_AND_REGISTER_FN(http_connection_new)    CREATE_AND_REGISTER_FN(http_connection_close)    CREATE_AND_REGISTER_FN(http_stream_new)    CREATE_AND_REGISTER_FN(http_stream_activate)    CREATE_AND_REGISTER_FN(http_stream_close)    CREATE_AND_REGISTER_FN(http_connection_manager_new)    CREATE_AND_REGISTER_FN(http_connection_manager_close)    CREATE_AND_REGISTER_FN(http_connection_manager_acquire)    CREATE_AND_REGISTER_FN(http_connection_manager_release)     /* Event stream */    CREATE_AND_REGISTER_FN(event_stream_client_connection_new)    CREATE_AND_REGISTER_FN(event_stream_client_connection_connect)    CREATE_AND_REGISTER_FN(event_stream_client_connection_close)    CREATE_AND_REGISTER_FN(event_stream_client_connection_close_internal)    CREATE_AND_REGISTER_FN(event_stream_client_connection_send_protocol_message)    CREATE_AND_REGISTER_FN(event_stream_client_stream_new)    CREATE_AND_REGISTER_FN(event_stream_client_stream_close)    CREATE_AND_REGISTER_FN(event_stream_client_stream_activate)    CREATE_AND_REGISTER_FN(event_stream_client_stream_send_message) #undef CREATE_AND_REGISTER_FN     AWS_NAPI_ENSURE(env, aws_napi_http_headers_bind(env, exports));    AWS_NAPI_ENSURE(env, aws_napi_http_message_bind(env, exports));    AWS_NAPI_ENSURE(env, aws_napi_auth_bind(env, exports));     return exports;}