@@ -111,9 +111,31 @@ pub struct ByteCompiler {
111
111
pub variable_freelist : Vec < u32 > ,
112
112
113
113
pub info : Option < Vec < ( Range < usize > , FileLocation ) > > ,
114
+
115
+ pub in_try_stmt : bool ,
116
+ pub fast_calls : Vec < Box < dyn FnOnce ( & mut ByteCompiler ) > >
114
117
}
115
118
116
119
impl ByteCompiler {
120
+ pub fn new ( rt : RuntimeRef , builtins : bool , code : GcPointer < CodeBlock > , scope : Rc < RefCell < Scope > > ) -> Self {
121
+ Self {
122
+ lci : Vec :: new ( ) ,
123
+ builtins,
124
+ variable_freelist : Vec :: with_capacity ( 4 ) ,
125
+ code,
126
+ tail_pos : false ,
127
+ info : None ,
128
+ fmap : HashMap :: new ( ) ,
129
+ val_map : HashMap :: new ( ) ,
130
+ name_map : HashMap :: new ( ) ,
131
+ top_level : false ,
132
+ scope,
133
+ rt : rt,
134
+ in_try_stmt : false ,
135
+ fast_calls : Vec :: new ( )
136
+ }
137
+ }
138
+
117
139
pub fn get_val ( & mut self , vm : & mut Runtime , val : Val ) -> u32 {
118
140
if let Some ( ix) = self . val_map . get ( & val) {
119
141
return * ix;
@@ -472,20 +494,7 @@ impl ByteCompiler {
472
494
depth : 0 ,
473
495
} ) ) ;
474
496
let mut code = CodeBlock :: new ( vm, "<anonymous>" . intern ( ) , false , rel_path. into ( ) ) ;
475
- let mut compiler = ByteCompiler {
476
- lci : Vec :: new ( ) ,
477
- builtins,
478
- variable_freelist : Vec :: with_capacity ( 4 ) ,
479
- code,
480
- tail_pos : false ,
481
- info : None ,
482
- fmap : HashMap :: new ( ) ,
483
- val_map : HashMap :: new ( ) ,
484
- name_map : HashMap :: new ( ) ,
485
- top_level : false ,
486
- scope,
487
- rt : RuntimeRef ( & mut * vm) ,
488
- } ;
497
+ let mut compiler = ByteCompiler :: new ( RuntimeRef ( vm) , builtins, code, scope) ;
489
498
let mut p = 0 ;
490
499
for x in params_. iter ( ) {
491
500
params. push ( x. intern ( ) ) ;
@@ -573,20 +582,7 @@ impl ByteCompiler {
573
582
depth : self . scope . borrow ( ) . depth + 1 ,
574
583
} ) ) ;
575
584
576
- let mut compiler = ByteCompiler {
577
- lci : Vec :: new ( ) ,
578
- builtins : self . builtins ,
579
- variable_freelist : Vec :: with_capacity ( 4 ) ,
580
- code,
581
- info : None ,
582
- tail_pos : false ,
583
- fmap : HashMap :: new ( ) ,
584
- val_map : HashMap :: new ( ) ,
585
- name_map : HashMap :: new ( ) ,
586
- top_level : false ,
587
- scope,
588
- rt : RuntimeRef ( & mut * self . rt ) ,
589
- } ;
585
+ let mut compiler = ByteCompiler :: new ( self . rt , self . builtins , code, scope) ;
590
586
let mut p = 0 ;
591
587
for x in function. params . iter ( ) {
592
588
match x. pat {
@@ -667,24 +663,11 @@ impl ByteCompiler {
667
663
668
664
let mut code = CodeBlock :: new ( & mut vm, name, false , path. into ( ) ) ;
669
665
code. file_name = file. to_string ( ) ;
670
- let mut compiler = ByteCompiler {
671
- lci : Vec :: new ( ) ,
672
- top_level : true ,
673
- info : None ,
674
- tail_pos : false ,
675
- builtins : false ,
676
- scope : Rc :: new ( RefCell :: new ( Scope {
677
- parent : None ,
678
- variables : Default :: default ( ) ,
679
- depth : 0 ,
680
- } ) ) ,
681
- variable_freelist : vec ! [ ] ,
682
- code,
683
- val_map : Default :: default ( ) ,
684
- name_map : Default :: default ( ) ,
685
- fmap : Default :: default ( ) ,
686
- rt : RuntimeRef ( vm) ,
687
- } ;
666
+ let mut compiler = ByteCompiler :: new ( RuntimeRef ( vm) , false , code, Rc :: new ( RefCell :: new ( Scope {
667
+ parent : None ,
668
+ variables : Default :: default ( ) ,
669
+ depth : 0
670
+ } ) ) ) ;
688
671
code. var_count = 1 ;
689
672
code. param_count = 1 ;
690
673
compiler. scope . borrow_mut ( ) . add_var ( "@module" . intern ( ) , 0 ) ;
@@ -857,24 +840,13 @@ impl ByteCompiler {
857
840
let name = "<script>" . intern ( ) ;
858
841
let mut code = CodeBlock :: new ( & mut vm, name, false , path. into ( ) ) ;
859
842
code. file_name = fname;
860
- let mut compiler = ByteCompiler {
861
- lci : Vec :: new ( ) ,
862
- top_level : true ,
863
- info : None ,
864
- tail_pos : false ,
865
- builtins,
866
- scope : Rc :: new ( RefCell :: new ( Scope {
843
+ let mut compiler = ByteCompiler :: new (
844
+ RuntimeRef ( vm) , builtins, code, Rc :: new ( RefCell :: new ( Scope {
867
845
parent : None ,
868
846
variables : Default :: default ( ) ,
869
847
depth : 0 ,
870
- } ) ) ,
871
- variable_freelist : vec ! [ ] ,
872
- code,
873
- val_map : Default :: default ( ) ,
874
- name_map : Default :: default ( ) ,
875
- fmap : Default :: default ( ) ,
876
- rt : RuntimeRef ( vm) ,
877
- } ;
848
+ } ) )
849
+ ) ;
878
850
879
851
let is_strict = match p. body . get ( 0 ) {
880
852
Some ( body) => body. is_use_strict ( ) ,
@@ -903,24 +875,11 @@ impl ByteCompiler {
903
875
let name = "<script>" . intern ( ) ;
904
876
let mut code = CodeBlock :: new ( & mut vm, name, false , path. into ( ) ) ;
905
877
code. file_name = fname;
906
- let mut compiler = ByteCompiler {
907
- lci : Vec :: new ( ) ,
908
- top_level : true ,
909
- info : None ,
910
- tail_pos : false ,
911
- builtins,
912
- scope : Rc :: new ( RefCell :: new ( Scope {
913
- parent : None ,
914
- variables : Default :: default ( ) ,
915
- depth : 0 ,
916
- } ) ) ,
917
- variable_freelist : vec ! [ ] ,
918
- code,
919
- val_map : Default :: default ( ) ,
920
- name_map : Default :: default ( ) ,
921
- fmap : Default :: default ( ) ,
922
- rt : RuntimeRef ( vm) ,
923
- } ;
878
+ let mut compiler = ByteCompiler :: new ( RuntimeRef ( vm) , builtins, code, Rc :: new ( RefCell :: new ( Scope {
879
+ parent : None ,
880
+ variables : Default :: default ( ) ,
881
+ depth : 0 ,
882
+ } ) ) ) ;
924
883
925
884
let is_strict = match p. body . get ( 0 ) {
926
885
Some ( body) => body. is_use_strict ( ) ,
@@ -1122,6 +1081,10 @@ impl ByteCompiler {
1122
1081
None => self . emit ( Opcode :: OP_PUSH_UNDEF , & [ ] , false ) ,
1123
1082
} ;
1124
1083
self . tail_pos = false ;
1084
+ if self . in_try_stmt {
1085
+ let fast_call = self . fast_call ( ) ;
1086
+ self . fast_calls . push ( Box :: new ( fast_call) ) ;
1087
+ }
1125
1088
self . emit ( Opcode :: OP_RET , & [ ] , false ) ;
1126
1089
}
1127
1090
Stmt :: Break ( _) => {
@@ -1303,7 +1266,8 @@ impl ByteCompiler {
1303
1266
}
1304
1267
Stmt :: Try ( try_stmt) => {
1305
1268
let try_push = self . try_ ( ) ;
1306
-
1269
+
1270
+ self . in_try_stmt = true ;
1307
1271
for stmt in try_stmt. block . stmts . iter ( ) {
1308
1272
self . stmt ( stmt) ?;
1309
1273
}
@@ -1337,6 +1301,13 @@ impl ByteCompiler {
1337
1301
1338
1302
jfinally ( self ) ;
1339
1303
jcatch_finally ( self ) ;
1304
+ while self . fast_calls . len ( ) >0 {
1305
+ let call = self . fast_calls . pop ( ) ;
1306
+ if let Some ( c) = call {
1307
+ c ( self ) ;
1308
+ }
1309
+ }
1310
+ self . in_try_stmt = false ;
1340
1311
match try_stmt. finalizer {
1341
1312
Some ( ref block) => {
1342
1313
self . push_scope ( ) ;
@@ -1349,8 +1320,12 @@ impl ByteCompiler {
1349
1320
}
1350
1321
None => { }
1351
1322
}
1323
+ self . emit ( Opcode :: OP_FAST_RET , & [ ] , false ) ;
1352
1324
}
1353
-
1325
+ Stmt :: Debugger ( _) => todo ! ( ) ,
1326
+ Stmt :: With ( _) => todo ! ( ) ,
1327
+ Stmt :: Labeled ( _) => todo ! ( ) ,
1328
+ Stmt :: DoWhile ( _) => todo ! ( ) ,
1354
1329
x => {
1355
1330
return Err ( JsValue :: new (
1356
1331
self . rt . new_syntax_error ( format ! ( "NYI: {:?}" , x) ) ,
@@ -1929,24 +1904,11 @@ impl ByteCompiler {
1929
1904
let p = self . code . path . clone ( ) ;
1930
1905
let mut code = CodeBlock :: new ( & mut self . rt , name, false , p) ;
1931
1906
code. file_name = self . code . file_name . clone ( ) ;
1932
- let mut compiler = ByteCompiler {
1933
- lci : Vec :: new ( ) ,
1934
- top_level : false ,
1935
- tail_pos : false ,
1936
- builtins : self . builtins ,
1937
- code,
1938
- variable_freelist : vec ! [ ] ,
1939
- val_map : Default :: default ( ) ,
1940
- name_map : Default :: default ( ) ,
1941
- info : None ,
1942
- fmap : Default :: default ( ) ,
1943
- rt : RuntimeRef ( & mut * self . rt ) ,
1944
- scope : Rc :: new ( RefCell :: new ( Scope {
1945
- parent : Some ( self . scope . clone ( ) ) ,
1946
- depth : self . scope . borrow ( ) . depth + 1 ,
1947
- variables : HashMap :: new ( ) ,
1948
- } ) ) ,
1949
- } ;
1907
+ let mut compiler = ByteCompiler :: new ( self . rt , self . builtins , code, Rc :: new ( RefCell :: new ( Scope {
1908
+ parent : Some ( self . scope . clone ( ) ) ,
1909
+ depth : self . scope . borrow ( ) . depth + 1 ,
1910
+ variables : HashMap :: new ( ) ,
1911
+ } ) ) ) ;
1950
1912
code. strict = is_strict;
1951
1913
let mut params = vec ! [ ] ;
1952
1914
let mut rest_at = None ;
@@ -2107,6 +2069,23 @@ impl ByteCompiler {
2107
2069
}
2108
2070
}
2109
2071
2072
+ pub fn fast_call ( & mut self ) -> impl FnOnce ( & mut Self ) {
2073
+ let p = self . code . code . len ( ) ;
2074
+ self . emit ( Opcode :: OP_FAST_CALL , & [ 0 ] , false ) ;
2075
+
2076
+ move |this : & mut Self | {
2077
+ // this.emit(Opcode::OP_NOP, &[], false);
2078
+ let to = this. code . code . len ( ) - ( p + 5 ) ;
2079
+ let bytes = ( to as u32 ) . to_le_bytes ( ) ;
2080
+ this. code . code [ p] = Opcode :: OP_FAST_CALL as u8 ;
2081
+ this. code . code [ p + 1 ] = bytes[ 0 ] ;
2082
+ this. code . code [ p + 2 ] = bytes[ 1 ] ;
2083
+ this. code . code [ p + 3 ] = bytes[ 2 ] ;
2084
+ this. code . code [ p + 4 ] = bytes[ 3 ] ;
2085
+ //this.code.code[p] = ins as u8;
2086
+ }
2087
+ }
2088
+
2110
2089
pub fn jmp_custom ( & mut self , op : Opcode ) -> impl FnOnce ( & mut Self ) {
2111
2090
let p = self . code . code . len ( ) ;
2112
2091
self . emit ( op, & [ 0 ] , false ) ;
0 commit comments