perf: pass primitives directly through the context bridge, avoids copying (#24531)
This commit is contained in:
parent
36900df7d9
commit
3f54f240bd
4 changed files with 32 additions and 2 deletions
|
@ -31,7 +31,8 @@
|
||||||
"BUILDFLAG": "readonly",
|
"BUILDFLAG": "readonly",
|
||||||
"ENABLE_DESKTOP_CAPTURER": "readonly",
|
"ENABLE_DESKTOP_CAPTURER": "readonly",
|
||||||
"ENABLE_REMOTE_MODULE": "readonly",
|
"ENABLE_REMOTE_MODULE": "readonly",
|
||||||
"ENABLE_VIEWS_API": "readonly"
|
"ENABLE_VIEWS_API": "readonly",
|
||||||
|
"BigInt": "readonly"
|
||||||
},
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -146,6 +146,17 @@ v8::MaybeLocal<v8::Value> PassValueToOtherContext(
|
||||||
"deeper than 1000 are not supported.")));
|
"deeper than 1000 are not supported.")));
|
||||||
return v8::MaybeLocal<v8::Value>();
|
return v8::MaybeLocal<v8::Value>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Certain primitives always use the current contexts prototype and we can
|
||||||
|
// pass these through directly which is significantly more performant than
|
||||||
|
// copying them. This list of primitives is based on the classification of
|
||||||
|
// "primitive value" as defined in the ECMA262 spec
|
||||||
|
// https://tc39.es/ecma262/#sec-primitive-value
|
||||||
|
if (value->IsString() || value->IsNumber() || value->IsNullOrUndefined() ||
|
||||||
|
value->IsBoolean() || value->IsSymbol() || value->IsBigInt()) {
|
||||||
|
return v8::MaybeLocal<v8::Value>(value);
|
||||||
|
}
|
||||||
|
|
||||||
// Check Cache
|
// Check Cache
|
||||||
auto cached_value = object_cache->GetCachedProxiedObject(value);
|
auto cached_value = object_cache->GetCachedProxiedObject(value);
|
||||||
if (!cached_value.IsEmpty()) {
|
if (!cached_value.IsEmpty()) {
|
||||||
|
|
|
@ -313,6 +313,20 @@ describe('contextBridge', () => {
|
||||||
expect(result).to.deep.equal(['null', 'undefined']);
|
expect(result).to.deep.equal(['null', 'undefined']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should proxy symbols such that symbol equality works', async () => {
|
||||||
|
await makeBindingWindow(() => {
|
||||||
|
const mySymbol = Symbol('unique');
|
||||||
|
contextBridge.exposeInMainWorld('example', {
|
||||||
|
getSymbol: () => mySymbol,
|
||||||
|
isSymbol: (s: Symbol) => s === mySymbol
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const result = await callWithBindings((root: any) => {
|
||||||
|
return root.example.isSymbol(root.example.getSymbol());
|
||||||
|
});
|
||||||
|
expect(result).to.equal(true, 'symbols should be equal across contexts');
|
||||||
|
});
|
||||||
|
|
||||||
it('should proxy typed arrays and regexps through the serializer', async () => {
|
it('should proxy typed arrays and regexps through the serializer', async () => {
|
||||||
await makeBindingWindow(() => {
|
await makeBindingWindow(() => {
|
||||||
contextBridge.exposeInMainWorld('example', {
|
contextBridge.exposeInMainWorld('example', {
|
||||||
|
@ -479,6 +493,8 @@ describe('contextBridge', () => {
|
||||||
string: 'string',
|
string: 'string',
|
||||||
boolean: true,
|
boolean: true,
|
||||||
arr: [123, 'string', true, ['foo']],
|
arr: [123, 'string', true, ['foo']],
|
||||||
|
symbol: Symbol('foo'),
|
||||||
|
bigInt: 10n,
|
||||||
getObject: () => ({ thing: 123 }),
|
getObject: () => ({ thing: 123 }),
|
||||||
getNumber: () => 123,
|
getNumber: () => 123,
|
||||||
getString: () => 'string',
|
getString: () => 'string',
|
||||||
|
@ -511,6 +527,8 @@ describe('contextBridge', () => {
|
||||||
[example.arr[2], Boolean],
|
[example.arr[2], Boolean],
|
||||||
[example.arr[3], Array],
|
[example.arr[3], Array],
|
||||||
[example.arr[3][0], String],
|
[example.arr[3][0], String],
|
||||||
|
[example.symbol, Symbol],
|
||||||
|
[example.bigInt, BigInt],
|
||||||
[example.getNumber, Function],
|
[example.getNumber, Function],
|
||||||
[example.getNumber(), Number],
|
[example.getNumber(), Number],
|
||||||
[example.getObject(), Object],
|
[example.getObject(), Object],
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es2017",
|
"target": "es2020",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2019",
|
"es2019",
|
||||||
"dom",
|
"dom",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue