diff options
author | Jarrod Connolly <jarrod@nestedquotes.ca> | 2019-02-03 23:26:33 -0800 |
---|---|---|
committer | Michael Dawson <michael_dawson@ca.ibm.com> | 2019-02-28 17:43:37 -0500 |
commit | 13b1aafe8710f5df733fd42bed8b1e1321160505 (patch) | |
tree | bf7018fdf0eb8e6509f22faf0b163089f669ba7e | |
parent | 3f31c884ff112dd7c2a184d87e6ebbc75906ea7c (diff) | |
download | android-node-v8-13b1aafe8710f5df733fd42bed8b1e1321160505.tar.gz android-node-v8-13b1aafe8710f5df733fd42bed8b1e1321160505.tar.bz2 android-node-v8-13b1aafe8710f5df733fd42bed8b1e1321160505.zip |
n-api: implement date object
Implements `napi_create_date()` as well as `napi_is_date()` to
allow working with JavaScript Date objects.
PR-URL: https://github.com/nodejs/node/pull/25917
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
-rw-r--r-- | doc/api/n-api.md | 73 | ||||
-rw-r--r-- | src/js_native_api.h | 14 | ||||
-rw-r--r-- | src/js_native_api_types.h | 1 | ||||
-rw-r--r-- | src/js_native_api_v8.cc | 42 | ||||
-rw-r--r-- | test/js-native-api/test_date/binding.gyp | 11 | ||||
-rw-r--r-- | test/js-native-api/test_date/test.js | 21 | ||||
-rw-r--r-- | test/js-native-api/test_date/test_date.c | 65 |
7 files changed, 227 insertions, 0 deletions
diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 2b061167f6..503046a529 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -243,6 +243,7 @@ typedef enum { napi_queue_full, napi_closing, napi_bigint_expected, + napi_date_expected, } napi_status; ``` If additional information is required upon an API returning a failed status, @@ -1527,6 +1528,31 @@ This API allocates a `node::Buffer` object and initializes it with data copied from the passed-in buffer. While this is still a fully-supported data structure, in most cases using a `TypedArray` will suffice. +#### napi_create_date +<!-- YAML +added: REPLACEME +napiVersion: 4 +--> + +> Stability: 1 - Experimental + +```C +napi_status napi_create_date(napi_env env, + double time, + napi_value* result); +``` + +- `[in] env`: The environment that the API is invoked under. +- `[in] time`: ECMAScript time value in milliseconds since 01 January, 1970 UTC. +- `[out] result`: A `napi_value` representing a JavaScript `Date`. + +Returns `napi_ok` if the API succeeded. + +This API allocates a JavaScript `Date` object. + +JavaScript `Date` objects are described in +[Section 20.3][] of the ECMAScript Language Specification. + #### napi_create_external <!-- YAML added: v8.0.0 @@ -2147,6 +2173,31 @@ Returns `napi_ok` if the API succeeded. This API returns various properties of a `DataView`. +#### napi_get_date_value +<!-- YAML +added: REPLACEME +napiVersion: 4 +--> + +> Stability: 1 - Experimental + +```C +napi_status napi_get_date_value(napi_env env, + napi_value value, + double* result) +``` + +- `[in] env`: The environment that the API is invoked under. +- `[in] value`: `napi_value` representing a JavaScript `Date`. +- `[out] result`: Time value as a `double` represented as milliseconds +since midnight at the beginning of 01 January, 1970 UTC. + +Returns `napi_ok` if the API succeeded. If a non-date `napi_value` is passed +in it returns `napi_date_expected`. + +This API returns the C double primitive of time value for the given JavaScript +`Date`. + #### napi_get_value_bool <!-- YAML added: v8.0.0 @@ -2731,6 +2782,27 @@ Returns `napi_ok` if the API succeeded. This API checks if the `Object` passed in is a buffer. +### napi_is_date +<!-- YAML +added: REPLACEME +napiVersion: 4 +--> + +> Stability: 1 - Experimental + +```C +napi_status napi_is_date(napi_env env, napi_value value, bool* result) +``` + +- `[in] env`: The environment that the API is invoked under. +- `[in] value`: The JavaScript value to check. +- `[out] result`: Whether the given `napi_value` represents a JavaScript `Date` +object. + +Returns `napi_ok` if the API succeeded. + +This API checks if the `Object` passed in is a date. + ### napi_is_error <!-- YAML added: v8.0.0 @@ -4712,6 +4784,7 @@ This API may only be called from the main thread. [Object Lifetime Management]: #n_api_object_lifetime_management [Object Wrap]: #n_api_object_wrap [Section 12.5.5]: https://tc39.github.io/ecma262/#sec-typeof-operator +[Section 20.3]: https://tc39.github.io/ecma262/#sec-date-objects [Section 22.1]: https://tc39.github.io/ecma262/#sec-array-objects [Section 22.2]: https://tc39.github.io/ecma262/#sec-typedarray-objects [Section 24.1]: https://tc39.github.io/ecma262/#sec-arraybuffer-objects diff --git a/src/js_native_api.h b/src/js_native_api.h index 9d0fa811cf..b19113b1f1 100644 --- a/src/js_native_api.h +++ b/src/js_native_api.h @@ -449,6 +449,20 @@ NAPI_EXTERN napi_status napi_adjust_external_memory(napi_env env, #ifdef NAPI_EXPERIMENTAL +// Dates +NAPI_EXTERN napi_status napi_create_date(napi_env env, + double time, + napi_value* result); + +NAPI_EXTERN napi_status napi_is_date(napi_env env, + napi_value value, + bool* is_date); + +NAPI_EXTERN napi_status napi_get_date_value(napi_env env, + napi_value value, + double* result); + +// BigInt NAPI_EXTERN napi_status napi_create_bigint_int64(napi_env env, int64_t value, napi_value* result); diff --git a/src/js_native_api_types.h b/src/js_native_api_types.h index a473995799..1f46729fc6 100644 --- a/src/js_native_api_types.h +++ b/src/js_native_api_types.h @@ -76,6 +76,7 @@ typedef enum { napi_queue_full, napi_closing, napi_bigint_expected, + napi_date_expected, } napi_status; typedef napi_value (*napi_callback)(napi_env env, diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index fd3ed2af6a..022ce104eb 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -2887,6 +2887,48 @@ napi_status napi_is_promise(napi_env env, return napi_clear_last_error(env); } +napi_status napi_create_date(napi_env env, + double time, + napi_value* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, result); + + v8::MaybeLocal<v8::Value> maybe_date = v8::Date::New(env->context(), time); + CHECK_MAYBE_EMPTY(env, maybe_date, napi_generic_failure); + + *result = v8impl::JsValueFromV8LocalValue(maybe_date.ToLocalChecked()); + + return GET_RETURN_STATUS(env); +} + +napi_status napi_is_date(napi_env env, + napi_value value, + bool* is_date) { + CHECK_ENV(env); + CHECK_ARG(env, value); + CHECK_ARG(env, is_date); + + *is_date = v8impl::V8LocalValueFromJsValue(value)->IsDate(); + + return napi_clear_last_error(env); +} + +napi_status napi_get_date_value(napi_env env, + napi_value value, + double* result) { + NAPI_PREAMBLE(env); + CHECK_ARG(env, value); + CHECK_ARG(env, result); + + v8::Local<v8::Value> val = v8impl::V8LocalValueFromJsValue(value); + RETURN_STATUS_IF_FALSE(env, val->IsDate(), napi_date_expected); + + v8::Local<v8::Date> date = val.As<v8::Date>(); + *result = date->ValueOf(); + + return GET_RETURN_STATUS(env); +} + napi_status napi_run_script(napi_env env, napi_value script, napi_value* result) { diff --git a/test/js-native-api/test_date/binding.gyp b/test/js-native-api/test_date/binding.gyp new file mode 100644 index 0000000000..a65a4e1387 --- /dev/null +++ b/test/js-native-api/test_date/binding.gyp @@ -0,0 +1,11 @@ +{ + "targets": [ + { + "target_name": "test_date", + "sources": [ + "../entry_point.c", + "test_date.c" + ] + } + ] +} diff --git a/test/js-native-api/test_date/test.js b/test/js-native-api/test_date/test.js new file mode 100644 index 0000000000..e504208520 --- /dev/null +++ b/test/js-native-api/test_date/test.js @@ -0,0 +1,21 @@ +'use strict'; + +const common = require('../../common'); + +// This tests the date-related n-api calls + +const assert = require('assert'); +const test_date = require(`./build/${common.buildType}/test_date`); + +const dateTypeTestDate = test_date.createDate(1549183351); +assert.strictEqual(test_date.isDate(dateTypeTestDate), true); + +assert.strictEqual(test_date.isDate(new Date(1549183351)), true); + +assert.strictEqual(test_date.isDate(2.4), false); +assert.strictEqual(test_date.isDate('not a date'), false); +assert.strictEqual(test_date.isDate(undefined), false); +assert.strictEqual(test_date.isDate(null), false); +assert.strictEqual(test_date.isDate({}), false); + +assert.strictEqual(test_date.getDateValue(new Date(1549183351)), 1549183351); diff --git a/test/js-native-api/test_date/test_date.c b/test/js-native-api/test_date/test_date.c new file mode 100644 index 0000000000..13de450079 --- /dev/null +++ b/test/js-native-api/test_date/test_date.c @@ -0,0 +1,65 @@ +#define NAPI_EXPERIMENTAL + +#include <js_native_api.h> +#include "../common.h" + +static napi_value createDate(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1]; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); + + NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments"); + + napi_valuetype valuetype0; + NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0)); + + NAPI_ASSERT(env, valuetype0 == napi_number, + "Wrong type of arguments. Expects a number as first argument."); + + double time; + NAPI_CALL(env, napi_get_value_double(env, args[0], &time)); + + napi_value date; + NAPI_CALL(env, napi_create_date(env, time, &date)); + + return date; +} + +static napi_value isDate(napi_env env, napi_callback_info info) { + napi_value date, result; + size_t argc = 1; + bool is_date; + + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &date, NULL, NULL)); + NAPI_CALL(env, napi_is_date(env, date, &is_date)); + NAPI_CALL(env, napi_get_boolean(env, is_date, &result)); + + return result; +} + +static napi_value getDateValue(napi_env env, napi_callback_info info) { + napi_value date, result; + size_t argc = 1; + double value; + + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &date, NULL, NULL)); + NAPI_CALL(env, napi_get_date_value(env, date, &value)); + NAPI_CALL(env, napi_create_double(env, value, &result)); + + return result; +} + +EXTERN_C_START +napi_value Init(napi_env env, napi_value exports) { + napi_property_descriptor descriptors[] = { + DECLARE_NAPI_PROPERTY("createDate", createDate), + DECLARE_NAPI_PROPERTY("isDate", isDate), + DECLARE_NAPI_PROPERTY("getDateValue", getDateValue), + }; + + NAPI_CALL(env, napi_define_properties( + env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors)); + + return exports; +} +EXTERN_C_END |