@@ -312,56 +312,6 @@ class Driver {
312312 }
313313 }
314314
315- runCode ( string ) {
316- if ( ! isInBrowser ) {
317- const scripts = string ;
318- let globalObject ;
319- let realm ;
320- if ( isD8 ) {
321- realm = Realm . createAllowCrossRealmAccess ( ) ;
322- globalObject = Realm . global ( realm ) ;
323- globalObject . loadString = function ( s ) {
324- return Realm . eval ( realm , s ) ;
325- } ;
326- globalObject . readFile = read ;
327- } else if ( isSpiderMonkey ) {
328- globalObject = newGlobal ( ) ;
329- globalObject . loadString = globalObject . evaluate ;
330- globalObject . readFile = globalObject . readRelativeToScript ;
331- } else
332- globalObject = runString ( "" ) ;
333-
334- globalObject . console = {
335- log : globalObject . print ,
336- warn : ( e ) => { print ( "Warn: " + e ) ; } ,
337- error : ( e ) => { print ( "Error: " + e ) ; } ,
338- debug : ( e ) => { print ( "Debug: " + e ) ; } ,
339- } ;
340-
341- globalObject . self = globalObject ;
342- globalObject . top = {
343- currentResolve,
344- currentReject
345- } ;
346-
347- globalObject . performance ??= performance ;
348- for ( const script of scripts )
349- globalObject . loadString ( script ) ;
350-
351- return isD8 ? realm : globalObject ;
352- }
353-
354- const magic = document . getElementById ( "magic" ) ;
355- magic . contentDocument . body . textContent = "" ;
356- magic . contentDocument . body . innerHTML = "<iframe id=\"magicframe\" frameborder=\"0\">" ;
357-
358- const magicFrame = magic . contentDocument . getElementById ( "magicframe" ) ;
359- magicFrame . contentDocument . open ( ) ;
360- magicFrame . contentDocument . write ( `<!DOCTYPE html><head><title>benchmark payload</title></head><body>\n${ string } </body></html>` ) ;
361-
362- return magicFrame ;
363- }
364-
365315 prepareToRun ( ) {
366316 this . benchmarks . sort ( ( a , b ) => a . plan . name . toLowerCase ( ) < b . plan . name . toLowerCase ( ) ? 1 : - 1 ) ;
367317
@@ -578,6 +528,140 @@ const BenchmarkState = Object.freeze({
578528 DONE : "DONE"
579529} )
580530
531+
532+ class Scripts {
533+ constructor ( ) {
534+ this . scripts = [ ] ;
535+ this . add ( `
536+ const isInBrowser = ${ isInBrowser } ;
537+ const isD8 = ${ isD8 } ;
538+ if (typeof performance.mark === 'undefined') {
539+ performance.mark = function(name) { return { name }};
540+ }
541+ if (typeof performance.measure === 'undefined') {
542+ performance.measure = function() {};
543+ }
544+ ` ) ;
545+ }
546+
547+ run ( ) {
548+ throw new Error ( "Subclasses need to implement this" ) ;
549+ }
550+
551+ add ( text ) {
552+ throw new Error ( "Subclasses need to implement this" ) ;
553+ }
554+
555+ addWithURL ( url ) {
556+ throw new Error ( "addWithURL not supported" ) ;
557+ }
558+
559+ addDeterministicRandom ( ) {
560+ this . add ( `(() => {
561+ const initialSeed = 49734321;
562+ let seed = initialSeed;
563+
564+ Math.random = () => {
565+ // Robert Jenkins' 32 bit integer hash function.
566+ seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffff_ffff;
567+ seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffff_ffff;
568+ seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffff_ffff;
569+ seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffff_ffff;
570+ seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffff_ffff;
571+ seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffff_ffff;
572+ // Note that Math.random should return a value that is
573+ // greater than or equal to 0 and less than 1. Here, we
574+ // cast to uint32 first then divided by 2^32 for double.
575+ return (seed >>> 0) / 0x1_0000_0000;
576+ };
577+
578+ Math.random.__resetSeed = () => {
579+ seed = initialSeed;
580+ };
581+ })();` ) ;
582+ }
583+ }
584+
585+ class ShellScripts extends Scripts {
586+ run ( ) {
587+ let globalObject ;
588+ let realm ;
589+ if ( isD8 ) {
590+ realm = Realm . createAllowCrossRealmAccess ( ) ;
591+ globalObject = Realm . global ( realm ) ;
592+ globalObject . loadString = function ( s ) {
593+ return Realm . eval ( realm , s ) ;
594+ } ;
595+ globalObject . readFile = read ;
596+ } else if ( isSpiderMonkey ) {
597+ globalObject = newGlobal ( ) ;
598+ globalObject . loadString = globalObject . evaluate ;
599+ globalObject . readFile = globalObject . readRelativeToScript ;
600+ } else
601+ globalObject = runString ( "" ) ;
602+
603+ globalObject . console = {
604+ log : globalObject . print ,
605+ warn : ( e ) => { print ( "Warn: " + e ) ; } ,
606+ error : ( e ) => { print ( "Error: " + e ) ; } ,
607+ debug : ( e ) => { print ( "Debug: " + e ) ; } ,
608+ } ;
609+
610+ globalObject . self = globalObject ;
611+ globalObject . top = {
612+ currentResolve,
613+ currentReject
614+ } ;
615+
616+ globalObject . performance ??= performance ;
617+ for ( const script of this . scripts )
618+ globalObject . loadString ( script ) ;
619+
620+ return isD8 ? realm : globalObject ;
621+ }
622+
623+ add ( text ) {
624+ this . scripts . push ( text ) ;
625+ }
626+
627+ addWithURL ( url ) {
628+ assert ( false , "Should not reach here in CLI" ) ;
629+ }
630+ }
631+
632+ class BrowserScripts extends Scripts {
633+ constructor ( ) {
634+ super ( ) ;
635+ this . add ( "window.onerror = top.currentReject;" ) ;
636+ }
637+
638+ run ( ) {
639+ const string = this . scripts . join ( "\n" ) ;
640+ const magic = document . getElementById ( "magic" ) ;
641+ magic . contentDocument . body . textContent = "" ;
642+ magic . contentDocument . body . innerHTML = `<iframe id="magicframe" frameborder="0">` ;
643+
644+ const magicFrame = magic . contentDocument . getElementById ( "magicframe" ) ;
645+ magicFrame . contentDocument . open ( ) ;
646+ magicFrame . contentDocument . write ( `<!DOCTYPE html>
647+ <head>
648+ <title>benchmark payload</title>
649+ </head>
650+ <body>${ string } </body>
651+ </html>` ) ;
652+ return magicFrame ;
653+ }
654+
655+
656+ add ( text ) {
657+ this . scripts . push ( `<script>${ text } </script>` ) ;
658+ }
659+
660+ addWithURL ( url ) {
661+ this . scripts . push ( `<script src="${ url } "></script>` ) ;
662+ }
663+ }
664+
581665class Benchmark {
582666 constructor ( plan )
583667 {
@@ -682,98 +766,38 @@ class Benchmark {
682766 if ( this . isDone )
683767 throw new Error ( `Cannot run Benchmark ${ this . name } twice` ) ;
684768 this . _state = BenchmarkState . PREPARE ;
685- let code ;
686- if ( isInBrowser )
687- code = "" ;
688- else
689- code = [ ] ;
690-
691- const addScript = ( text ) => {
692- if ( isInBrowser )
693- code += `<script>${ text } </script>` ;
694- else
695- code . push ( text ) ;
696- } ;
697-
698- const addScriptWithURL = ( url ) => {
699- if ( isInBrowser )
700- code += `<script src="${ url } "></script>` ;
701- else
702- assert ( false , "Should not reach here in CLI" ) ;
703- } ;
704-
705- addScript ( `
706- const isInBrowser = ${ isInBrowser } ;
707- const isD8 = ${ isD8 } ;
708- if (typeof performance.mark === 'undefined') {
709- performance.mark = function(name) { return { name }};
710- }
711- if (typeof performance.measure === 'undefined') {
712- performance.measure = function() {};
713- }
714- ` ) ;
769+ const scripts = isInBrowser ? new BrowserScripts ( ) : new ShellScripts ( ) ;
715770
716- if ( ! ! this . plan . deterministicRandom ) {
717- addScript ( `
718- (() => {
719- const initialSeed = 49734321;
720- let seed = initialSeed;
721-
722- Math.random = () => {
723- // Robert Jenkins' 32 bit integer hash function.
724- seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffff_ffff;
725- seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffff_ffff;
726- seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffff_ffff;
727- seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffff_ffff;
728- seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffff_ffff;
729- seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffff_ffff;
730- // Note that Math.random should return a value that is
731- // greater than or equal to 0 and less than 1. Here, we
732- // cast to uint32 first then divided by 2^32 for double.
733- return (seed >>> 0) / 0x1_0000_0000;
734- };
735-
736- Math.random.__resetSeed = () => {
737- seed = initialSeed;
738- };
739- })();
740- ` ) ;
741- }
771+ if ( ! ! this . plan . deterministicRandom )
772+ scripts . addDeterministicRandom ( )
742773
743774 if ( this . plan . preload ) {
744- let str = "" ;
775+ let preloadCode = "" ;
745776 for ( let [ variableName , blobURLOrPath ] of this . preloads )
746- str += `const ${ variableName } = "${ blobURLOrPath } ";\n` ;
747- addScript ( str ) ;
777+ preloadCode += `const ${ variableName } = "${ blobURLOrPath } ";\n` ;
778+ scripts . add ( preloadCode ) ;
748779 }
749780
750781 const prerunCode = this . prerunCode ;
751782 if ( prerunCode )
752- addScript ( prerunCode ) ;
783+ scripts . add ( prerunCode ) ;
753784
754785 if ( ! isInBrowser ) {
755786 assert ( this . scripts && this . scripts . length === this . plan . files . length ) ;
756-
757787 for ( const text of this . scripts )
758- addScript ( text ) ;
788+ scripts . add ( text ) ;
759789 } else {
760790 const cache = JetStream . blobDataCache ;
761791 for ( const file of this . plan . files )
762- addScriptWithURL ( cache [ file ] . blobURL ) ;
792+ scripts . addWithURL ( cache [ file ] . blobURL ) ;
763793 }
764794
765795 const promise = new Promise ( ( resolve , reject ) => {
766796 currentResolve = resolve ;
767797 currentReject = reject ;
768798 } ) ;
769799
770- if ( isInBrowser ) {
771- code = `
772- <script> window.onerror = top.currentReject; </script>
773- ${ code }
774- ` ;
775- }
776- addScript ( this . runnerCode ) ;
800+ scripts . add ( this . runnerCode ) ;
777801
778802 performance . mark ( this . name ) ;
779803 this . startTime = performance . now ( ) ;
@@ -784,7 +808,7 @@ class Benchmark {
784808 let magicFrame ;
785809 try {
786810 this . _state = BenchmarkState . RUNNING ;
787- magicFrame = JetStream . runCode ( code ) ;
811+ magicFrame = scripts . run ( ) ;
788812 } catch ( e ) {
789813 this . _state = BenchmarkState . ERROR ;
790814 console . log ( "Error in runCode: " , e ) ;
0 commit comments