[njs] Introduced tags for NJS_DATA type.
Dmitry Volyntsev
xeioex at nginx.com
Thu Jul 30 17:48:16 UTC 2020
details: https://hg.nginx.org/njs/rev/0fad09ddb37a
branches:
changeset: 1484:0fad09ddb37a
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Jul 30 17:47:05 2020 +0000
description:
Introduced tags for NJS_DATA type.
NJS_DATA is designed to contain arbitrary opaque pointers.
Tags are used to distinguish different opaque pointers.
diffstat:
src/njs.h | 2 -
src/njs_crypto.c | 60 ++++++++++++++++++++---------------------------
src/njs_extern.c | 11 +++-----
src/njs_promise.c | 14 +++++-----
src/njs_value.c | 14 -----------
src/njs_value.h | 25 +++++++++++++++++--
src/test/njs_unit_test.c | 4 +++
7 files changed, 63 insertions(+), 67 deletions(-)
diffs (396 lines):
diff -r cb490ee06ac2 -r 0fad09ddb37a src/njs.h
--- a/src/njs.h Wed Jul 29 17:00:23 2020 +0000
+++ b/src/njs.h Thu Jul 30 17:47:05 2020 +0000
@@ -341,11 +341,9 @@ NJS_EXPORT void njs_vm_memory_error(njs_
NJS_EXPORT void njs_value_undefined_set(njs_value_t *value);
NJS_EXPORT void njs_value_boolean_set(njs_value_t *value, int yn);
NJS_EXPORT void njs_value_number_set(njs_value_t *value, double num);
-NJS_EXPORT void njs_value_data_set(njs_value_t *value, void *data);
NJS_EXPORT uint8_t njs_value_bool(const njs_value_t *value);
NJS_EXPORT double njs_value_number(const njs_value_t *value);
-NJS_EXPORT void *njs_value_data(const njs_value_t *value);
NJS_EXPORT njs_function_t *njs_value_function(const njs_value_t *value);
NJS_EXPORT uint16_t njs_vm_prop_magic16(njs_object_prop_t *prop);
diff -r cb490ee06ac2 -r 0fad09ddb37a src/njs_crypto.c
--- a/src/njs_crypto.c Wed Jul 29 17:00:23 2020 +0000
+++ b/src/njs_crypto.c Thu Jul 30 17:47:05 2020 +0000
@@ -184,7 +184,7 @@ njs_crypto_create_hash(njs_vm_t *vm, njs
alg->init(&dgst->u);
- njs_set_data(&hash->value, dgst);
+ njs_set_data(&hash->value, dgst, NJS_DATA_TAG_CRYPTO_HASH);
njs_set_object_value(&vm->retval, hash);
return NJS_OK;
@@ -196,6 +196,7 @@ njs_hash_prototype_update(njs_vm_t *vm,
njs_index_t unused)
{
njs_str_t data;
+ njs_value_t *this;
njs_digest_t *dgst;
if (njs_slow_path(nargs < 2 || !njs_is_string(&args[1]))) {
@@ -203,19 +204,16 @@ njs_hash_prototype_update(njs_vm_t *vm,
return NJS_ERROR;
}
- if (njs_slow_path(!njs_is_object_value(&args[0]))) {
- njs_type_error(vm, "\"this\" is not an object_value");
- return NJS_ERROR;
- }
+ this = njs_argument(args, 0);
- if (njs_slow_path(!njs_is_data(njs_object_value(&args[0])))) {
- njs_type_error(vm, "value of \"this\" is not a data type");
+ if (njs_slow_path(!njs_is_object_data(this, NJS_DATA_TAG_CRYPTO_HASH))) {
+ njs_type_error(vm, "\"this\" is not a hash object");
return NJS_ERROR;
}
njs_string_get(&args[1], &data);
- dgst = njs_value_data(njs_object_value(&args[0]));
+ dgst = njs_object_data(this);
if (njs_slow_path(dgst->alg == NULL)) {
njs_error(vm, "Digest already called");
@@ -224,7 +222,7 @@ njs_hash_prototype_update(njs_vm_t *vm,
dgst->alg->update(&dgst->u, data.start, data.length);
- vm->retval = args[0];
+ vm->retval = *this;
return NJS_OK;
}
@@ -237,6 +235,7 @@ njs_hash_prototype_digest(njs_vm_t *vm,
u_char digest[32], *p;
njs_int_t ret;
njs_str_t enc_name, str;
+ njs_value_t *this;
njs_digest_t *dgst;
njs_hash_alg_t *alg;
njs_crypto_enc_t *enc;
@@ -246,13 +245,10 @@ njs_hash_prototype_digest(njs_vm_t *vm,
return NJS_ERROR;
}
- if (njs_slow_path(!njs_is_object_value(&args[0]))) {
- njs_type_error(vm, "\"this\" is not an object_value");
- return NJS_ERROR;
- }
+ this = njs_argument(args, 0);
- if (njs_slow_path(!njs_is_data(njs_object_value(&args[0])))) {
- njs_type_error(vm, "value of \"this\" is not a data type");
+ if (njs_slow_path(!njs_is_object_data(this, NJS_DATA_TAG_CRYPTO_HASH))) {
+ njs_type_error(vm, "\"this\" is not a hash object");
return NJS_ERROR;
}
@@ -267,7 +263,7 @@ njs_hash_prototype_digest(njs_vm_t *vm,
}
}
- dgst = njs_value_data(njs_object_value(&args[0]));
+ dgst = njs_object_data(this);
if (njs_slow_path(dgst->alg == NULL)) {
njs_error(vm, "Digest already called");
@@ -465,7 +461,7 @@ njs_crypto_create_hmac(njs_vm_t *vm, njs
return NJS_ERROR;
}
- njs_set_data(&hmac->value, ctx);
+ njs_set_data(&hmac->value, ctx, NJS_DATA_TAG_CRYPTO_HMAC);
njs_set_object_value(&vm->retval, hmac);
return NJS_OK;
@@ -476,27 +472,25 @@ static njs_int_t
njs_hmac_prototype_update(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- njs_str_t data;
- njs_hmac_t *ctx;
+ njs_str_t data;
+ njs_hmac_t *ctx;
+ njs_value_t *this;
if (njs_slow_path(nargs < 2 || !njs_is_string(&args[1]))) {
njs_type_error(vm, "data must be a string");
return NJS_ERROR;
}
- if (njs_slow_path(!njs_is_object_value(&args[0]))) {
- njs_type_error(vm, "\"this\" is not an object_value");
- return NJS_ERROR;
- }
+ this = njs_argument(args, 0);
- if (njs_slow_path(!njs_is_data(njs_object_value(&args[0])))) {
- njs_type_error(vm, "value of \"this\" is not a data type");
+ if (njs_slow_path(!njs_is_object_data(this, NJS_DATA_TAG_CRYPTO_HMAC))) {
+ njs_type_error(vm, "\"this\" is not a hash object");
return NJS_ERROR;
}
njs_string_get(&args[1], &data);
- ctx = njs_value_data(njs_object_value(&args[0]));
+ ctx = njs_object_data(this);
if (njs_slow_path(ctx->alg == NULL)) {
njs_error(vm, "Digest already called");
@@ -505,7 +499,7 @@ njs_hmac_prototype_update(njs_vm_t *vm,
ctx->alg->update(&ctx->u, data.start, data.length);
- vm->retval = args[0];
+ vm->retval = *this;
return NJS_OK;
}
@@ -519,6 +513,7 @@ njs_hmac_prototype_digest(njs_vm_t *vm,
njs_str_t enc_name, str;
njs_int_t ret;
njs_hmac_t *ctx;
+ njs_value_t *this;
njs_hash_alg_t *alg;
njs_crypto_enc_t *enc;
@@ -527,13 +522,10 @@ njs_hmac_prototype_digest(njs_vm_t *vm,
return NJS_ERROR;
}
- if (njs_slow_path(!njs_is_object_value(&args[0]))) {
- njs_type_error(vm, "\"this\" is not an object_value");
- return NJS_ERROR;
- }
+ this = njs_argument(args, 0);
- if (njs_slow_path(!njs_is_data(njs_object_value(&args[0])))) {
- njs_type_error(vm, "value of \"this\" is not a data type");
+ if (njs_slow_path(!njs_is_object_data(this, NJS_DATA_TAG_CRYPTO_HMAC))) {
+ njs_type_error(vm, "\"this\" is not a hash object");
return NJS_ERROR;
}
@@ -548,7 +540,7 @@ njs_hmac_prototype_digest(njs_vm_t *vm,
}
}
- ctx = njs_value_data(njs_object_value(&args[0]));
+ ctx = njs_object_data(this);
if (njs_slow_path(ctx->alg == NULL)) {
njs_error(vm, "Digest already called");
diff -r cb490ee06ac2 -r 0fad09ddb37a src/njs_extern.c
--- a/src/njs_extern.c Wed Jul 29 17:00:23 2020 +0000
+++ b/src/njs_extern.c Thu Jul 30 17:47:05 2020 +0000
@@ -202,7 +202,7 @@ njs_external_prop_handler(njs_vm_t *vm,
ov->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object;
ov->object.slots = slots;
- njs_set_data(&ov->value, external);
+ njs_set_data(&ov->value, external, NJS_DATA_TAG_EXTERNAL);
njs_set_object_value(retval, ov);
}
@@ -313,7 +313,7 @@ njs_vm_external_create(njs_vm_t *vm, njs
ov->object.slots = slots;
njs_set_object_value(value, ov);
- njs_set_data(&ov->value, external);
+ njs_set_data(&ov->value, external, NJS_DATA_TAG_EXTERNAL);
return NJS_OK;
}
@@ -322,11 +322,8 @@ njs_vm_external_create(njs_vm_t *vm, njs
njs_external_ptr_t
njs_vm_external(njs_vm_t *vm, const njs_value_t *value)
{
- if (njs_fast_path(njs_is_object_value(value))) {
- value = njs_object_value(value);
- if (njs_fast_path(njs_is_data(value))) {
- return njs_value_data(value);
- }
+ if (njs_fast_path(njs_is_object_data(value, NJS_DATA_TAG_EXTERNAL))) {
+ return njs_object_data(value);
}
return NULL;
diff -r cb490ee06ac2 -r 0fad09ddb37a src/njs_promise.c
--- a/src/njs_promise.c Wed Jul 29 17:00:23 2020 +0000
+++ b/src/njs_promise.c Thu Jul 30 17:47:05 2020 +0000
@@ -101,7 +101,7 @@ njs_promise_alloc(njs_vm_t *vm)
njs_queue_init(&data->reject_queue);
njs_set_promise(&vm->retval, promise);
- njs_value_data_set(&promise->value, data);
+ njs_set_data(&promise->value, data, 0);
return promise;
@@ -453,7 +453,7 @@ njs_promise_trigger_reactions(njs_vm_t *
function = njs_promise_create_function(vm);
function->u.native = njs_promise_reaction_job;
- njs_set_data(&arguments[0], reaction);
+ njs_set_data(&arguments[0], reaction, 0);
arguments[1] = *value;
ret = njs_promise_add_event(vm, function, arguments, 2);
@@ -472,7 +472,7 @@ njs_promise_fulfill(njs_vm_t *vm, njs_pr
njs_queue_t queue;
njs_promise_data_t *data;
- data = njs_value_data(&promise->value);
+ data = njs_data(&promise->value);
data->result = *value;
data->state = NJS_PROMISE_FULFILL;
@@ -500,7 +500,7 @@ njs_promise_reject(njs_vm_t *vm, njs_pro
njs_queue_t queue;
njs_promise_data_t *data;
- data = njs_value_data(&promise->value);
+ data = njs_data(&promise->value);
data->result = *reason;
data->state = NJS_PROMISE_REJECTED;
@@ -845,7 +845,7 @@ njs_promise_perform_then(njs_vm_t *vm, n
}
promise = njs_promise(value);
- data = njs_value_data(&promise->value);
+ data = njs_data(&promise->value);
fulfilled_reaction = njs_mp_alloc(vm->mem_pool,
sizeof(njs_promise_reaction_t));
@@ -878,12 +878,12 @@ njs_promise_perform_then(njs_vm_t *vm, n
function->u.native = njs_promise_reaction_job;
if (data->state == NJS_PROMISE_REJECTED) {
- njs_set_data(&arguments[0], rejected_reaction);
+ njs_set_data(&arguments[0], rejected_reaction, 0);
/* TODO: HostPromiseRejectionTracker */
} else {
- njs_set_data(&arguments[0], fulfilled_reaction);
+ njs_set_data(&arguments[0], fulfilled_reaction, 0);
}
arguments[1] = data->result;
diff -r cb490ee06ac2 -r 0fad09ddb37a src/njs_value.c
--- a/src/njs_value.c Wed Jul 29 17:00:23 2020 +0000
+++ b/src/njs_value.c Thu Jul 30 17:47:05 2020 +0000
@@ -371,13 +371,6 @@ njs_value_number_set(njs_value_t *value,
}
-void
-njs_value_data_set(njs_value_t *value, void *data)
-{
- njs_set_data(value, data);
-}
-
-
uint8_t
njs_value_bool(const njs_value_t *value)
{
@@ -392,13 +385,6 @@ njs_value_number(const njs_value_t *valu
}
-void *
-njs_value_data(const njs_value_t *value)
-{
- return njs_data(value);
-}
-
-
njs_function_t *
njs_value_function(const njs_value_t *value)
{
diff -r cb490ee06ac2 -r 0fad09ddb37a src/njs_value.h
--- a/src/njs_value.h Wed Jul 29 17:00:23 2020 +0000
+++ b/src/njs_value.h Thu Jul 30 17:47:05 2020 +0000
@@ -76,6 +76,15 @@ typedef enum {
} njs_value_type_t;
+typedef enum {
+ NJS_DATA_TAG_ANY = 0,
+ NJS_DATA_TAG_EXTERNAL,
+ NJS_DATA_TAG_CRYPTO_HASH,
+ NJS_DATA_TAG_CRYPTO_HMAC,
+ NJS_DATA_TAG_MAX
+} njs_data_tag_t;
+
+
typedef struct njs_string_s njs_string_t;
typedef struct njs_object_s njs_object_t;
typedef struct njs_object_value_s njs_object_value_t;
@@ -599,8 +608,8 @@ typedef struct {
((value)->type <= NJS_STRING)
-#define njs_is_data(value) \
- ((value)->type == NJS_DATA)
+#define njs_is_data(value, tag) \
+ ((value)->type == NJS_DATA && value->data.magic32 == (tag))
#define njs_is_object(value) \
@@ -616,6 +625,11 @@ typedef struct {
((value)->type == NJS_OBJECT_VALUE)
+#define njs_is_object_data(_value, tag) \
+ (((_value)->type == NJS_OBJECT_VALUE) \
+ && njs_is_data(njs_object_value(_value), tag))
+
+
#define njs_is_object_string(value) \
((value)->type == NJS_OBJECT_STRING)
@@ -748,6 +762,10 @@ typedef struct {
(&(_value)->data.u.object_value->value)
+#define njs_object_data(_value) \
+ njs_data(njs_object_value(_value))
+
+
#define njs_set_undefined(value) \
*(value) = njs_value_undefined
@@ -852,8 +870,9 @@ njs_set_symbol(njs_value_t *value, uint3
njs_inline void
-njs_set_data(njs_value_t *value, void *data)
+njs_set_data(njs_value_t *value, void *data, njs_data_tag_t tag)
{
+ value->data.magic32 = tag;
value->data.u.data = data;
value->type = NJS_DATA;
value->data.truth = 1;
diff -r cb490ee06ac2 -r 0fad09ddb37a src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Wed Jul 29 17:00:23 2020 +0000
+++ b/src/test/njs_unit_test.c Thu Jul 30 17:47:05 2020 +0000
@@ -16956,6 +16956,10 @@ static njs_unit_test_t njs_test[] =
{ njs_str("typeof require('crypto').createHmac('md5', 'a')"),
njs_str("object") },
+ { njs_str("var cr = require('crypto'); var h = cr.createHash('sha1');"
+ "h.update.call(cr.createHmac('sha1', 's'), '')"),
+ njs_str("TypeError: \"this\" is not a hash object") },
+
/* setTimeout(). */
{ njs_str("setTimeout()"),
More information about the nginx-devel
mailing list