blob: 5883b5d4e6d8fc031d541e787956026583f26f61 [file] [log] [blame]
/*
* Copyright (C) Igor Sysoev
* Copyright (C) NGINX, Inc.
*/
#ifndef _NJS_VM_H_INCLUDED_
#define _NJS_VM_H_INCLUDED_
#define NJS_MAX_STACK_SIZE (256 * 1024)
/*
* NJS_PROPERTY_QUERY_GET must be less to NJS_PROPERTY_QUERY_SET
* and NJS_PROPERTY_QUERY_DELETE.
*/
#define NJS_PROPERTY_QUERY_GET 0
#define NJS_PROPERTY_QUERY_SET 1
#define NJS_PROPERTY_QUERY_DELETE 2
typedef struct njs_frame_s njs_frame_t;
typedef struct njs_native_frame_s njs_native_frame_t;
typedef struct njs_parser_s njs_parser_t;
typedef struct njs_parser_scope_s njs_parser_scope_t;
typedef struct njs_parser_node_s njs_parser_node_t;
typedef struct njs_generator_s njs_generator_t;
typedef enum {
NJS_SCOPE_GLOBAL = 0,
NJS_SCOPE_FUNCTION,
NJS_SCOPE_BLOCK
} njs_scope_t;
typedef enum {
NJS_OBJ_TYPE_OBJECT = 0,
NJS_OBJ_TYPE_ARRAY,
NJS_OBJ_TYPE_BOOLEAN,
NJS_OBJ_TYPE_NUMBER,
NJS_OBJ_TYPE_SYMBOL,
NJS_OBJ_TYPE_STRING,
NJS_OBJ_TYPE_FUNCTION,
NJS_OBJ_TYPE_REGEXP,
NJS_OBJ_TYPE_DATE,
NJS_OBJ_TYPE_PROMISE,
NJS_OBJ_TYPE_ARRAY_BUFFER,
NJS_OBJ_TYPE_DATA_VIEW,
NJS_OBJ_TYPE_TEXT_DECODER,
NJS_OBJ_TYPE_TEXT_ENCODER,
NJS_OBJ_TYPE_BUFFER,
#define NJS_OBJ_TYPE_HIDDEN_MIN (NJS_OBJ_TYPE_ITERATOR)
NJS_OBJ_TYPE_ITERATOR,
NJS_OBJ_TYPE_ARRAY_ITERATOR,
NJS_OBJ_TYPE_FS_DIRENT,
NJS_OBJ_TYPE_CRYPTO_HASH,
NJS_OBJ_TYPE_CRYPTO_HMAC,
NJS_OBJ_TYPE_TYPED_ARRAY,
#define NJS_OBJ_TYPE_HIDDEN_MAX (NJS_OBJ_TYPE_TYPED_ARRAY + 1)
#define NJS_OBJ_TYPE_NORMAL_MAX (NJS_OBJ_TYPE_HIDDEN_MAX)
#define NJS_OBJ_TYPE_TYPED_ARRAY_MIN (NJS_OBJ_TYPE_UINT8_ARRAY)
#define njs_typed_array_index(type) (type - NJS_OBJ_TYPE_TYPED_ARRAY_MIN)
NJS_OBJ_TYPE_UINT8_ARRAY,
NJS_OBJ_TYPE_UINT8_CLAMPED_ARRAY,
NJS_OBJ_TYPE_INT8_ARRAY,
NJS_OBJ_TYPE_UINT16_ARRAY,
NJS_OBJ_TYPE_INT16_ARRAY,
NJS_OBJ_TYPE_UINT32_ARRAY,
NJS_OBJ_TYPE_INT32_ARRAY,
NJS_OBJ_TYPE_FLOAT32_ARRAY,
NJS_OBJ_TYPE_FLOAT64_ARRAY,
#define NJS_OBJ_TYPE_TYPED_ARRAY_MAX (NJS_OBJ_TYPE_FLOAT64_ARRAY + 1)
#define NJS_OBJ_TYPE_TYPED_ARRAY_SIZE (NJS_OBJ_TYPE_TYPED_ARRAY_MAX \
- NJS_OBJ_TYPE_TYPED_ARRAY_MIN)
NJS_OBJ_TYPE_ERROR,
NJS_OBJ_TYPE_EVAL_ERROR,
NJS_OBJ_TYPE_INTERNAL_ERROR,
NJS_OBJ_TYPE_RANGE_ERROR,
NJS_OBJ_TYPE_REF_ERROR,
NJS_OBJ_TYPE_SYNTAX_ERROR,
NJS_OBJ_TYPE_TYPE_ERROR,
NJS_OBJ_TYPE_URI_ERROR,
NJS_OBJ_TYPE_MEMORY_ERROR,
NJS_OBJ_TYPE_MAX,
} njs_object_type_t;
#define njs_primitive_prototype_index(type) \
(NJS_OBJ_TYPE_BOOLEAN + ((type) - NJS_BOOLEAN))
#define njs_prototype_type(index) \
(index + NJS_OBJECT)
enum njs_object_e {
NJS_OBJECT_THIS = 0,
NJS_OBJECT_NJS,
NJS_OBJECT_PROCESS,
NJS_OBJECT_MATH,
NJS_OBJECT_JSON,
#ifdef NJS_TEST262
NJS_OBJECT_262,
#endif
NJS_OBJECT_MAX
};
enum njs_hook_e {
NJS_HOOK_EXIT = 0,
NJS_HOOK_MAX
};
typedef enum {
NJS_LEVEL_LOCAL = 0,
NJS_LEVEL_CLOSURE,
NJS_LEVEL_GLOBAL,
NJS_LEVEL_STATIC,
NJS_LEVEL_TEMP,
NJS_LEVEL_MAX
} njs_level_type_t;
struct njs_vm_s {
/* njs_vm_t must be aligned to njs_value_t due to scratch value. */
njs_value_t retval;
njs_arr_t *paths;
njs_arr_t *protos;
njs_arr_t *scope_absolute;
njs_value_t **levels[NJS_LEVEL_MAX];
size_t global_items;
njs_external_ptr_t external;
njs_native_frame_t *top_frame;
njs_frame_t *active_frame;
njs_rbtree_t *variables_hash;
njs_lvlhsh_t values_hash;
njs_arr_t *modules;
njs_lvlhsh_t modules_hash;
uint32_t event_id;
njs_lvlhsh_t events_hash;
njs_queue_t posted_events;
njs_queue_t promise_events;
njs_vm_opt_t options;
/*
* The prototypes and constructors arrays must be together because
* they are copied from njs_vm_shared_t by single memcpy()
* in njs_builtin_objects_clone().
*/
njs_object_prototype_t prototypes[NJS_OBJ_TYPE_MAX];
njs_function_t constructors[NJS_OBJ_TYPE_MAX];
njs_function_t *hooks[NJS_HOOK_MAX];
njs_mp_t *mem_pool;
u_char *start;
size_t stack_size;
njs_vm_shared_t *shared;
njs_regex_context_t *regex_context;
njs_regex_match_data_t *single_match_data;
njs_array_t *promise_reason;
njs_parser_scope_t *global_scope;
/*
* MemoryError is statically allocated immutable Error object
* with the InternalError prototype.
*/
njs_object_t memory_error_object;
njs_object_t string_object;
njs_object_t global_object;
njs_value_t global_value;
njs_arr_t *codes; /* of njs_vm_code_t */
njs_arr_t *functions_name_cache;
njs_trace_t trace;
njs_random_t random;
uint64_t symbol_generator;
};
typedef struct {
uint32_t offset;
uint32_t line;
} njs_vm_line_num_t;
typedef struct {
u_char *start;
u_char *end;
njs_str_t file;
njs_str_t name;
njs_arr_t *lines; /* of njs_vm_line_num_t */
} njs_vm_code_t;
struct njs_vm_shared_s {
njs_lvlhsh_t keywords_hash;
njs_lvlhsh_t values_hash;
njs_lvlhsh_t array_instance_hash;
njs_lvlhsh_t string_instance_hash;
njs_lvlhsh_t function_instance_hash;
njs_lvlhsh_t arrow_instance_hash;
njs_lvlhsh_t arguments_object_instance_hash;
njs_lvlhsh_t regexp_instance_hash;
njs_lvlhsh_t modules_hash;
njs_lvlhsh_t env_hash;
njs_object_t string_object;
njs_object_t objects[NJS_OBJECT_MAX];
njs_exotic_slots_t global_slots;
/*
* The prototypes and constructors arrays must be togther because they are
* copied to njs_vm_t by single memcpy() in njs_builtin_objects_clone().
*/
njs_object_prototype_t prototypes[NJS_OBJ_TYPE_MAX];
njs_function_t constructors[NJS_OBJ_TYPE_MAX];
njs_regexp_pattern_t *empty_regexp_pattern;
};
void njs_vm_scopes_restore(njs_vm_t *vm, njs_native_frame_t *frame,
njs_native_frame_t *previous);
njs_int_t njs_builtin_objects_create(njs_vm_t *vm);
njs_int_t njs_builtin_objects_clone(njs_vm_t *vm, njs_value_t *global);
njs_int_t njs_builtin_match_native_function(njs_vm_t *vm,
njs_function_t *function, njs_str_t *name);
njs_arr_t *njs_vm_completions(njs_vm_t *vm, njs_str_t *expression);
void *njs_lvlhsh_alloc(void *data, size_t size);
void njs_lvlhsh_free(void *data, void *p, size_t size);
extern const njs_str_t njs_entry_main;
extern const njs_str_t njs_entry_module;
extern const njs_str_t njs_entry_native;
extern const njs_str_t njs_entry_unknown;
extern const njs_str_t njs_entry_anonymous;
extern const njs_lvlhsh_proto_t njs_object_hash_proto;
#endif /* _NJS_VM_H_INCLUDED_ */