mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
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>
This commit is contained in:
committed by
Michael Dawson
parent
3f31c884ff
commit
13b1aafe87
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
11
test/js-native-api/test_date/binding.gyp
Normal file
11
test/js-native-api/test_date/binding.gyp
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "test_date",
|
||||
"sources": [
|
||||
"../entry_point.c",
|
||||
"test_date.c"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
21
test/js-native-api/test_date/test.js
Normal file
21
test/js-native-api/test_date/test.js
Normal file
@@ -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);
|
||||
65
test/js-native-api/test_date/test_date.c
Normal file
65
test/js-native-api/test_date/test_date.c
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user