From: Dmitry Volyntsev Date: Thu, 30 Jul 2020 17:47:05 +0000 (+0000) Subject: Introduced tags for NJS_DATA type. X-Git-Url: http://git.kaiwu.me/sitemap.xml?a=commitdiff_plain;h=62dc62ba52f1d0f050116c8e9cfecaa8d9b0cd5d;p=njs.git Introduced tags for NJS_DATA type. NJS_DATA is designed to contain arbitrary opaque pointers. Tags are used to distinguish different opaque pointers. --- diff --git a/src/njs.h b/src/njs.h index 88cacfb4..82a570fd 100644 --- a/src/njs.h +++ b/src/njs.h @@ -341,11 +341,9 @@ NJS_EXPORT void njs_vm_memory_error(njs_vm_t *vm); 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 --git a/src/njs_crypto.c b/src/njs_crypto.c index 9989ef10..71e2d0b8 100644 --- a/src/njs_crypto.c +++ b/src/njs_crypto.c @@ -184,7 +184,7 @@ njs_crypto_create_hash(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, 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_value_t *args, njs_uint_t nargs, 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, njs_value_t *args, njs_uint_t nargs, 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, njs_value_t *args, njs_uint_t nargs, 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, njs_value_t *args, njs_uint_t nargs, 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, njs_value_t *args, njs_uint_t nargs, 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, njs_value_t *args, njs_uint_t nargs, } } - 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_value_t *args, njs_uint_t nargs, 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, njs_value_t *args, njs_uint_t nargs, 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_value_t *args, njs_uint_t nargs, 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, njs_value_t *args, njs_uint_t nargs, 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, njs_value_t *args, njs_uint_t nargs, } } - 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 --git a/src/njs_extern.c b/src/njs_extern.c index 3df7604c..04bd5873 100644 --- a/src/njs_extern.c +++ b/src/njs_extern.c @@ -202,7 +202,7 @@ njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self, 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_value_t *value, 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_value_t *value, 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 --git a/src/njs_promise.c b/src/njs_promise.c index c1db7bcf..41704c07 100644 --- a/src/njs_promise.c +++ b/src/njs_promise.c @@ -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 *vm, njs_value_t *value, 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_promise_t *promise, njs_value_t *value) 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_promise_t *promise, njs_value_t *reason) 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, njs_value_t *value, } 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, njs_value_t *value, 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 --git a/src/njs_value.c b/src/njs_value.c index a271a770..fc2fbd49 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -371,13 +371,6 @@ njs_value_number_set(njs_value_t *value, double num) } -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 *value) } -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 --git a/src/njs_value.h b/src/njs_value.h index 609eadc4..d09b9421 100644 --- a/src/njs_value.h +++ b/src/njs_value.h @@ -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, uint32_t symbol) 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 --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 83cad21b..ff87505c 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -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()"),