1
1
use std:: collections:: { HashMap , HashSet } ;
2
- use std:: fmt:: Write ;
3
2
use std:: mem;
4
3
5
4
use decode;
@@ -65,6 +64,18 @@ pub struct SubContext<'a, 'b: 'a> {
65
64
pub vendor_prefixes : HashMap < & ' b str , Vec < & ' b str > > ,
66
65
}
67
66
67
+ pub enum ImportTarget {
68
+ Function ( String ) ,
69
+ Method ( String ) ,
70
+ Constructor ( String ) ,
71
+ StructuralMethod ( String ) ,
72
+ StructuralGetter ( Option < String > , String ) ,
73
+ StructuralSetter ( Option < String > , String ) ,
74
+ StructuralIndexingGetter ( Option < String > ) ,
75
+ StructuralIndexingSetter ( Option < String > ) ,
76
+ StructuralIndexingDeleter ( Option < String > ) ,
77
+ }
78
+
68
79
const INITIAL_SLAB_VALUES : & [ & str ] = & [ "undefined" , "null" , "true" , "false" ] ;
69
80
70
81
impl < ' a > Context < ' a > {
@@ -1944,7 +1955,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
1944
1955
Some ( d) => d,
1945
1956
} ;
1946
1957
1947
- let target = self . generated_import_target ( info, import, & descriptor ) ?;
1958
+ let target = self . generated_import_target ( info, import) ?;
1948
1959
1949
1960
let js = Rust2Js :: new ( self . cx )
1950
1961
. catch ( import. catch )
@@ -1959,137 +1970,103 @@ impl<'a, 'b> SubContext<'a, 'b> {
1959
1970
& mut self ,
1960
1971
info : & decode:: Import < ' b > ,
1961
1972
import : & decode:: ImportFunction ,
1962
- descriptor : & Descriptor ,
1963
- ) -> Result < String , Error > {
1973
+ ) -> Result < ImportTarget , Error > {
1964
1974
let method_data = match & import. method {
1965
1975
Some ( data) => data,
1966
1976
None => {
1967
1977
let name = self . import_name ( info, & import. function . name ) ?;
1968
- return Ok ( if name. contains ( "." ) {
1969
- self . cx . global ( & format ! (
1970
- "
1971
- const {}_target = {};
1972
- " ,
1973
- import. shim, name
1974
- ) ) ;
1975
- format ! ( "{}_target" , import. shim)
1976
- } else {
1977
- name
1978
- } ) ;
1978
+ if import. structural || !name. contains ( "." ) {
1979
+ return Ok ( ImportTarget :: Function ( name) )
1980
+ }
1981
+ self . cx . global ( & format ! ( "const {}_target = {};" , import. shim, name) ) ;
1982
+ let target = format ! ( "{}_target" , import. shim) ;
1983
+ return Ok ( ImportTarget :: Function ( target) )
1979
1984
}
1980
1985
} ;
1981
1986
1982
1987
let class = self . import_name ( info, & method_data. class ) ?;
1983
1988
let op = match & method_data. kind {
1984
- decode:: MethodKind :: Constructor => return Ok ( format ! ( "new {}" , class) ) ,
1989
+ decode:: MethodKind :: Constructor => {
1990
+ return Ok ( ImportTarget :: Constructor ( class. to_string ( ) ) )
1991
+ }
1985
1992
decode:: MethodKind :: Operation ( op) => op,
1986
1993
} ;
1987
- let target = if import. structural {
1988
- let location = if op. is_static { & class } else { "this" } ;
1994
+ if import. structural {
1995
+ let class = if op. is_static { Some ( class. clone ( ) ) } else { None } ;
1989
1996
1990
- match & op. kind {
1997
+ return Ok ( match & op. kind {
1991
1998
decode:: OperationKind :: Regular => {
1992
- let nargs = descriptor. unwrap_function ( ) . arguments . len ( ) ;
1993
- let mut s = format ! ( "function(" ) ;
1994
- for i in 0 ..nargs - 1 {
1995
- if i > 0 {
1996
- drop ( write ! ( s, ", " ) ) ;
1997
- }
1998
- drop ( write ! ( s, "x{}" , i) ) ;
1999
+ let name = import. function . name . to_string ( ) ;
2000
+ match class {
2001
+ Some ( c) => ImportTarget :: Function ( format ! ( "{}.{}" , c, name) ) ,
2002
+ None => ImportTarget :: StructuralMethod ( name) ,
1999
2003
}
2000
- s. push_str ( ") { \n return this." ) ;
2001
- s. push_str ( & import. function . name ) ;
2002
- s. push_str ( "(" ) ;
2003
- for i in 0 ..nargs - 1 {
2004
- if i > 0 {
2005
- drop ( write ! ( s, ", " ) ) ;
2006
- }
2007
- drop ( write ! ( s, "x{}" , i) ) ;
2008
- }
2009
- s. push_str ( ");\n }" ) ;
2010
- s
2011
- }
2012
- decode:: OperationKind :: Getter ( g) => format ! (
2013
- "function() {{
2014
- return {}.{};
2015
- }}" ,
2016
- location, g
2017
- ) ,
2018
- decode:: OperationKind :: Setter ( s) => format ! (
2019
- "function(y) {{
2020
- {}.{} = y;
2021
- }}" ,
2022
- location, s
2023
- ) ,
2024
- decode:: OperationKind :: IndexingGetter => format ! (
2025
- "function(y) {{
2026
- return {}[y];
2027
- }}" ,
2028
- location
2029
- ) ,
2030
- decode:: OperationKind :: IndexingSetter => format ! (
2031
- "function(y, z) {{
2032
- {}[y] = z;
2033
- }}" ,
2034
- location
2035
- ) ,
2036
- decode:: OperationKind :: IndexingDeleter => format ! (
2037
- "function(y) {{
2038
- delete {}[y];
2039
- }}" ,
2040
- location
2041
- ) ,
2042
- }
2043
- } else {
2044
- let target = format ! ( "typeof {0} === 'undefined' ? null : {}{}" ,
2045
- class,
2046
- if op. is_static { "" } else { ".prototype" } ) ;
2047
- let ( mut target, name) = match & op. kind {
2048
- decode:: OperationKind :: Regular => {
2049
- ( format ! ( "{}.{}" , target, import. function. name) , & import. function . name )
2050
2004
}
2051
2005
decode:: OperationKind :: Getter ( g) => {
2052
- self . cx . expose_get_inherited_descriptor ( ) ;
2053
- ( format ! (
2054
- "GetOwnOrInheritedPropertyDescriptor({}, '{}').get" ,
2055
- target, g,
2056
- ) , g)
2006
+ ImportTarget :: StructuralGetter ( class, g. to_string ( ) )
2057
2007
}
2058
2008
decode:: OperationKind :: Setter ( s) => {
2059
- self . cx . expose_get_inherited_descriptor ( ) ;
2060
- ( format ! (
2061
- "GetOwnOrInheritedPropertyDescriptor({}, '{}').set" ,
2062
- target, s,
2063
- ) , s)
2009
+ ImportTarget :: StructuralSetter ( class, s. to_string ( ) )
2064
2010
}
2065
2011
decode:: OperationKind :: IndexingGetter => {
2066
- panic ! ( "indexing getter should be structural" )
2012
+ ImportTarget :: StructuralIndexingGetter ( class )
2067
2013
}
2068
2014
decode:: OperationKind :: IndexingSetter => {
2069
- panic ! ( "indexing setter should be structural" )
2015
+ ImportTarget :: StructuralIndexingSetter ( class )
2070
2016
}
2071
2017
decode:: OperationKind :: IndexingDeleter => {
2072
- panic ! ( "indexing deleter should be structural" )
2018
+ ImportTarget :: StructuralIndexingDeleter ( class )
2073
2019
}
2074
- } ;
2075
- target. push_str ( & format ! ( " || function() {{
2076
- throw new Error(`wasm-bindgen: {}.{} does not exist`);
2077
- }}" , class, name) ) ;
2078
- if op. is_static {
2079
- target. insert ( 0 , '(' ) ;
2080
- target. push_str ( ").bind(" ) ;
2081
- target. push_str ( & class) ;
2082
- target. push_str ( ")" ) ;
2083
- }
2084
- target
2020
+ } )
2021
+ }
2022
+
2023
+ let target = format ! ( "typeof {0} === 'undefined' ? null : {}{}" ,
2024
+ class,
2025
+ if op. is_static { "" } else { ".prototype" } ) ;
2026
+ let ( mut target, name) = match & op. kind {
2027
+ decode:: OperationKind :: Regular => {
2028
+ ( format ! ( "{}.{}" , target, import. function. name) , & import. function . name )
2029
+ }
2030
+ decode:: OperationKind :: Getter ( g) => {
2031
+ self . cx . expose_get_inherited_descriptor ( ) ;
2032
+ ( format ! (
2033
+ "GetOwnOrInheritedPropertyDescriptor({}, '{}').get" ,
2034
+ target, g,
2035
+ ) , g)
2036
+ }
2037
+ decode:: OperationKind :: Setter ( s) => {
2038
+ self . cx . expose_get_inherited_descriptor ( ) ;
2039
+ ( format ! (
2040
+ "GetOwnOrInheritedPropertyDescriptor({}, '{}').set" ,
2041
+ target, s,
2042
+ ) , s)
2043
+ }
2044
+ decode:: OperationKind :: IndexingGetter => {
2045
+ panic ! ( "indexing getter should be structural" )
2046
+ }
2047
+ decode:: OperationKind :: IndexingSetter => {
2048
+ panic ! ( "indexing setter should be structural" )
2049
+ }
2050
+ decode:: OperationKind :: IndexingDeleter => {
2051
+ panic ! ( "indexing deleter should be structural" )
2052
+ }
2085
2053
} ;
2054
+ target. push_str ( & format ! ( " || function() {{
2055
+ throw new Error(`wasm-bindgen: {}.{} does not exist`);
2056
+ }}" , class, name) ) ;
2057
+ if op. is_static {
2058
+ target. insert ( 0 , '(' ) ;
2059
+ target. push_str ( ").bind(" ) ;
2060
+ target. push_str ( & class) ;
2061
+ target. push_str ( ")" ) ;
2062
+ }
2086
2063
2087
2064
self . cx . global ( & format ! ( "const {}_target = {};" , import. shim, target) ) ;
2088
- Ok ( format ! (
2089
- "{}_target{}" ,
2090
- import . shim ,
2091
- if op . is_static { "" } else { ".call" }
2092
- ) )
2065
+ Ok ( if op . is_static {
2066
+ ImportTarget :: Function ( format ! ( "{}_target" , import . shim ) )
2067
+ } else {
2068
+ ImportTarget :: Method ( format ! ( "{}_target" , import . shim ) )
2069
+ } )
2093
2070
}
2094
2071
2095
2072
fn generate_import_type (
0 commit comments