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",
 | 
			
		||||
    "ENABLE_DESKTOP_CAPTURER": "readonly",
 | 
			
		||||
    "ENABLE_REMOTE_MODULE": "readonly",
 | 
			
		||||
    "ENABLE_VIEWS_API": "readonly"
 | 
			
		||||
    "ENABLE_VIEWS_API": "readonly",
 | 
			
		||||
    "BigInt": "readonly"
 | 
			
		||||
  },
 | 
			
		||||
  "overrides": [
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -146,6 +146,17 @@ v8::MaybeLocal<v8::Value> PassValueToOtherContext(
 | 
			
		|||
                        "deeper than 1000 are not supported.")));
 | 
			
		||||
    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
 | 
			
		||||
  auto cached_value = object_cache->GetCachedProxiedObject(value);
 | 
			
		||||
  if (!cached_value.IsEmpty()) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -313,6 +313,20 @@ describe('contextBridge', () => {
 | 
			
		|||
        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 () => {
 | 
			
		||||
        await makeBindingWindow(() => {
 | 
			
		||||
          contextBridge.exposeInMainWorld('example', {
 | 
			
		||||
| 
						 | 
				
			
			@ -479,6 +493,8 @@ describe('contextBridge', () => {
 | 
			
		|||
            string: 'string',
 | 
			
		||||
            boolean: true,
 | 
			
		||||
            arr: [123, 'string', true, ['foo']],
 | 
			
		||||
            symbol: Symbol('foo'),
 | 
			
		||||
            bigInt: 10n,
 | 
			
		||||
            getObject: () => ({ thing: 123 }),
 | 
			
		||||
            getNumber: () => 123,
 | 
			
		||||
            getString: () => 'string',
 | 
			
		||||
| 
						 | 
				
			
			@ -511,6 +527,8 @@ describe('contextBridge', () => {
 | 
			
		|||
            [example.arr[2], Boolean],
 | 
			
		||||
            [example.arr[3], Array],
 | 
			
		||||
            [example.arr[3][0], String],
 | 
			
		||||
            [example.symbol, Symbol],
 | 
			
		||||
            [example.bigInt, BigInt],
 | 
			
		||||
            [example.getNumber, Function],
 | 
			
		||||
            [example.getNumber(), Number],
 | 
			
		||||
            [example.getObject(), Object],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "module": "commonjs",
 | 
			
		||||
    "target": "es2017",
 | 
			
		||||
    "target": "es2020",
 | 
			
		||||
    "lib": [
 | 
			
		||||
      "es2019",
 | 
			
		||||
      "dom",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue