summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarrod Connolly <jarrod@nestedquotes.ca>2019-02-03 23:26:33 -0800
committerMichael Dawson <michael_dawson@ca.ibm.com>2019-02-28 17:43:37 -0500
commit13b1aafe8710f5df733fd42bed8b1e1321160505 (patch)
treebf7018fdf0eb8e6509f22faf0b163089f669ba7e
parent3f31c884ff112dd7c2a184d87e6ebbc75906ea7c (diff)
downloadandroid-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.md73
-rw-r--r--src/js_native_api.h14
-rw-r--r--src/js_native_api_types.h1
-rw-r--r--src/js_native_api_v8.cc42
-rw-r--r--test/js-native-api/test_date/binding.gyp11
-rw-r--r--test/js-native-api/test_date/test.js21
-rw-r--r--test/js-native-api/test_date/test_date.c65
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