GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — perf_hooks: convert maxSize to IDL value in setResourceTimingBufferSize · nodejs/node@7cdf745

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • lib/internal
    • perf
      • performance.js
    • webidl.js
  • test/parallel
    • test-bootstrap-modules.js
    • test-internal-webidl-converttoint.js
    • test-performance-resourcetimingbuffersize.js
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎lib/internal/perf/performance.js‎

Copy file name to clipboardExpand all lines: lib/internal/perf/performance.js
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const timerify = require('internal/perf/timerify');
4444
const { customInspectSymbol: kInspect, kEnumerableProperty, kEmptyObject } = require('internal/util');
4545
const { inspect } = require('util');
4646
const { validateInternalField } = require('internal/validators');
47+
const { convertToInt } = require('internal/webidl');
4748

4849
const {
4950
getTimeOriginTimestamp
@@ -144,6 +145,8 @@ class Performance extends EventTarget {
144145
if (arguments.length === 0) {
145146
throw new ERR_MISSING_ARGS('maxSize');
146147
}
148+
// unsigned long
149+
maxSize = convertToInt('maxSize', maxSize, 32);
147150
return setResourceTimingBufferSize(maxSize);
148151
}
149152

Collapse file

‎lib/internal/webidl.js‎

Copy file name to clipboard
+163Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
'use strict';
2+
3+
const {
4+
MathAbs,
5+
MathMax,
6+
MathMin,
7+
MathPow,
8+
MathSign,
9+
MathTrunc,
10+
NumberIsNaN,
11+
NumberMAX_SAFE_INTEGER,
12+
NumberMIN_SAFE_INTEGER,
13+
} = primordials;
14+
15+
const {
16+
codes: {
17+
ERR_INVALID_ARG_VALUE,
18+
},
19+
} = require('internal/errors');
20+
const { kEmptyObject } = require('internal/util');
21+
22+
// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart
23+
const integerPart = MathTrunc;
24+
25+
/* eslint-disable node-core/non-ascii-character */
26+
// Round x to the nearest integer, choosing the even integer if it lies halfway
27+
// between two, and choosing +0 rather than -0.
28+
// This is different from Math.round, which rounds to the next integer in the
29+
// direction of +∞ when the fraction portion is exactly 0.5.
30+
/* eslint-enable node-core/non-ascii-character */
31+
function evenRound(x) {
32+
// Convert -0 to +0.
33+
const i = integerPart(x) + 0;
34+
const reminder = MathAbs(x % 1);
35+
const sign = MathSign(i);
36+
if (reminder === 0.5) {
37+
return i % 2 === 0 ? i : i + sign;
38+
}
39+
const r = reminder < 0.5 ? i : i + sign;
40+
// Convert -0 to +0.
41+
if (r === 0) {
42+
return 0;
43+
}
44+
return r;
45+
}
46+
47+
function pow2(exponent) {
48+
// << operates on 32 bit signed integers.
49+
if (exponent < 31) {
50+
return 1 << exponent;
51+
}
52+
if (exponent === 31) {
53+
return 0x8000_0000;
54+
}
55+
if (exponent === 32) {
56+
return 0x1_0000_0000;
57+
}
58+
return MathPow(2, exponent);
59+
}
60+
61+
// https://tc39.es/ecma262/#eqn-modulo
62+
// The notation “x modulo y” computes a value k of the same sign as y.
63+
function modulo(x, y) {
64+
const r = x % y;
65+
// Convert -0 to +0.
66+
if (r === 0) {
67+
return 0;
68+
}
69+
return r;
70+
}
71+
72+
// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
73+
function convertToInt(name, value, bitLength, options = kEmptyObject) {
74+
const { signed = false, enforceRange = false, clamp = false } = options;
75+
76+
let upperBound;
77+
let lowerBound;
78+
// 1. If bitLength is 64, then:
79+
if (bitLength === 64) {
80+
// 1.1. Let upperBound be 2^53 − 1.
81+
upperBound = NumberMAX_SAFE_INTEGER;
82+
// 1.2. If signedness is "unsigned", then let lowerBound be 0.
83+
// 1.3. Otherwise let lowerBound be −2^53 + 1.
84+
lowerBound = !signed ? 0 : NumberMIN_SAFE_INTEGER;
85+
} else if (!signed) {
86+
// 2. Otherwise, if signedness is "unsigned", then:
87+
// 2.1. Let lowerBound be 0.
88+
// 2.2. Let upperBound be 2^bitLength − 1.
89+
lowerBound = 0;
90+
upperBound = pow2(bitLength) - 1;
91+
} else {
92+
// 3. Otherwise:
93+
// 3.1. Let lowerBound be -2^(bitLength − 1).
94+
// 3.2. Let upperBound be 2^(bitLength − 1) − 1.
95+
lowerBound = -pow2(bitLength - 1);
96+
upperBound = pow2(bitLength - 1) - 1;
97+
}
98+
99+
// 4. Let x be ? ToNumber(V).
100+
let x = +value;
101+
// 5. If x is −0, then set x to +0.
102+
if (x === 0) {
103+
x = 0;
104+
}
105+
106+
// 6. If the conversion is to an IDL type associated with the [EnforceRange]
107+
// extended attribute, then:
108+
if (enforceRange) {
109+
// 6.1. If x is NaN, +∞, or −∞, then throw a TypeError.
110+
if (NumberIsNaN(x) || x === Infinity || x === -Infinity) {
111+
throw new ERR_INVALID_ARG_VALUE(name, x);
112+
}
113+
// 6.2. Set x to IntegerPart(x).
114+
x = integerPart(x);
115+
116+
// 6.3. If x < lowerBound or x > upperBound, then throw a TypeError.
117+
if (x < lowerBound || x > upperBound) {
118+
throw new ERR_INVALID_ARG_VALUE(name, x);
119+
}
120+
121+
// 6.4. Return x.
122+
return x;
123+
}
124+
125+
// 7. If x is not NaN and the conversion is to an IDL type associated with
126+
// the [Clamp] extended attribute, then:
127+
if (clamp && !NumberIsNaN(x)) {
128+
// 7.1. Set x to min(max(x, lowerBound), upperBound).
129+
x = MathMin(MathMax(x, lowerBound), upperBound);
130+
131+
// 7.2. Round x to the nearest integer, choosing the even integer if it
132+
// lies halfway between two, and choosing +0 rather than −0.
133+
x = evenRound(x);
134+
135+
// 7.3. Return x.
136+
return x;
137+
}
138+
139+
// 8. If x is NaN, +0, +∞, or −∞, then return +0.
140+
if (NumberIsNaN(x) || x === 0 || x === Infinity || x === -Infinity) {
141+
return 0;
142+
}
143+
144+
// 9. Set x to IntegerPart(x).
145+
x = integerPart(x);
146+
147+
// 10. Set x to x modulo 2^bitLength.
148+
x = modulo(x, pow2(bitLength));
149+
150+
// 11. If signedness is "signed" and x ≥ 2^(bitLength − 1), then return x −
151+
// 2^bitLength.
152+
if (signed && x >= pow2(bitLength - 1)) {
153+
return x - pow2(bitLength);
154+
}
155+
156+
// 12. Otherwise, return x.
157+
return x;
158+
}
159+
160+
module.exports = {
161+
convertToInt,
162+
evenRound,
163+
};
Collapse file

‎test/parallel/test-bootstrap-modules.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-bootstrap-modules.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ const expectedModules = new Set([
149149
'NativeModule internal/validators',
150150
'NativeModule internal/vm/module',
151151
'NativeModule internal/wasm_web_api',
152+
'NativeModule internal/webidl',
152153
'NativeModule internal/webstreams/adapters',
153154
'NativeModule internal/webstreams/compression',
154155
'NativeModule internal/webstreams/encoding',
Collapse file

‎test/parallel/test-internal-webidl-converttoint.js‎

Copy file name to clipboard
+58Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Flags: --expose-internals
2+
'use strict';
3+
4+
require('../common');
5+
const assert = require('assert');
6+
const { convertToInt, evenRound } = require('internal/webidl');
7+
8+
assert.strictEqual(evenRound(-0.5), 0);
9+
assert.strictEqual(evenRound(0.5), 0);
10+
assert.strictEqual(evenRound(-1.5), -2);
11+
assert.strictEqual(evenRound(1.5), 2);
12+
assert.strictEqual(evenRound(3.4), 3);
13+
assert.strictEqual(evenRound(4.6), 5);
14+
assert.strictEqual(evenRound(5), 5);
15+
assert.strictEqual(evenRound(6), 6);
16+
17+
// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
18+
assert.strictEqual(convertToInt('x', 0, 64), 0);
19+
assert.strictEqual(convertToInt('x', 1, 64), 1);
20+
assert.strictEqual(convertToInt('x', -0.5, 64), 0);
21+
assert.strictEqual(convertToInt('x', -0.5, 64, { signed: true }), 0);
22+
assert.strictEqual(convertToInt('x', -1.5, 64, { signed: true }), -1);
23+
24+
// EnforceRange
25+
const OutOfRangeValues = [ NaN, Infinity, -Infinity, 2 ** 53, -(2 ** 53) ];
26+
for (const value of OutOfRangeValues) {
27+
assert.throws(() => convertToInt('x', value, 64, { enforceRange: true }), {
28+
name: 'TypeError',
29+
code: 'ERR_INVALID_ARG_VALUE',
30+
});
31+
}
32+
33+
// Out of range: clamp
34+
assert.strictEqual(convertToInt('x', NaN, 64, { clamp: true }), 0);
35+
assert.strictEqual(convertToInt('x', Infinity, 64, { clamp: true }), Number.MAX_SAFE_INTEGER);
36+
assert.strictEqual(convertToInt('x', -Infinity, 64, { clamp: true }), 0);
37+
assert.strictEqual(convertToInt('x', -Infinity, 64, { signed: true, clamp: true }), Number.MIN_SAFE_INTEGER);
38+
assert.strictEqual(convertToInt('x', 0x1_0000_0000, 32, { clamp: true }), 0xFFFF_FFFF);
39+
assert.strictEqual(convertToInt('x', 0xFFFF_FFFF, 32, { clamp: true }), 0xFFFF_FFFF);
40+
assert.strictEqual(convertToInt('x', 0x8000_0000, 32, { clamp: true, signed: true }), 0x7FFF_FFFF);
41+
assert.strictEqual(convertToInt('x', 0xFFFF_FFFF, 32, { clamp: true, signed: true }), 0x7FFF_FFFF);
42+
assert.strictEqual(convertToInt('x', 0.5, 64, { clamp: true }), 0);
43+
assert.strictEqual(convertToInt('x', 1.5, 64, { clamp: true }), 2);
44+
assert.strictEqual(convertToInt('x', -0.5, 64, { clamp: true }), 0);
45+
assert.strictEqual(convertToInt('x', -0.5, 64, { signed: true, clamp: true }), 0);
46+
assert.strictEqual(convertToInt('x', -1.5, 64, { signed: true, clamp: true }), -2);
47+
48+
// Out of range, step 8.
49+
assert.strictEqual(convertToInt('x', NaN, 64), 0);
50+
assert.strictEqual(convertToInt('x', Infinity, 64), 0);
51+
assert.strictEqual(convertToInt('x', -Infinity, 64), 0);
52+
assert.strictEqual(convertToInt('x', 0x1_0000_0000, 32), 0);
53+
assert.strictEqual(convertToInt('x', 0x1_0000_0001, 32), 1);
54+
assert.strictEqual(convertToInt('x', 0xFFFF_FFFF, 32), 0xFFFF_FFFF);
55+
56+
// Out of range, step 11.
57+
assert.strictEqual(convertToInt('x', 0x8000_0000, 32, { signed: true }), -0x8000_0000);
58+
assert.strictEqual(convertToInt('x', 0xFFF_FFFF, 32, { signed: true }), 0xFFF_FFFF);
Collapse file

‎test/parallel/test-performance-resourcetimingbuffersize.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-performance-resourcetimingbuffersize.js
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ const initiatorType = '';
3030
const cacheMode = '';
3131

3232
async function main() {
33+
// Invalid buffer size values are converted to 0.
34+
const invalidValues = [ null, undefined, true, false, -1, 0.5, Infinity, NaN, '', 'foo', {}, [], () => {} ];
35+
for (const value of invalidValues) {
36+
performance.setResourceTimingBufferSize(value);
37+
performance.markResourceTiming(timingInfo, requestedUrl, initiatorType, globalThis, cacheMode);
38+
assert.strictEqual(performance.getEntriesByType('resource').length, 0);
39+
performance.clearResourceTimings();
40+
}
41+
// Wait for the buffer full event to be cleared.
42+
await waitBufferFullEvent();
43+
3344
performance.setResourceTimingBufferSize(1);
3445
performance.markResourceTiming(timingInfo, requestedUrl, initiatorType, globalThis, cacheMode);
3546
// Trigger a resourcetimingbufferfull event.

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.