@@ -60,7 +60,11 @@ import 'dart:_js_names'
6060 unmangleAllIdentifiersIfPreservedAnyways;
6161
6262import 'dart:_rti' as newRti
63- show createRuntimeType, getRuntimeType, getTypeFromTypesTable;
63+ show
64+ createRuntimeType,
65+ evalInInstance,
66+ getRuntimeType,
67+ getTypeFromTypesTable;
6468
6569part 'annotations.dart' ;
6670part 'constant_map.dart' ;
@@ -2039,8 +2043,12 @@ abstract class Closure implements Function {
20392043 // The functions are called here to model the calls from JS forms below.
20402044 // The types in the JS forms in the arguments are propagated in type
20412045 // inference.
2042- BoundClosure .receiverOf (JS ('BoundClosure' , '0' ));
2043- BoundClosure .selfOf (JS ('BoundClosure' , '0' ));
2046+ var aBoundClosure = JS ('BoundClosure' , '0' );
2047+ var aString = JS ('String' , '0' );
2048+ BoundClosure .receiverOf (aBoundClosure);
2049+ BoundClosure .selfOf (aBoundClosure);
2050+ BoundClosure .evalRecipeIntercepted (aBoundClosure, aString);
2051+ BoundClosure .evalRecipe (aBoundClosure, aString);
20442052 getType (JS ('int' , '0' ));
20452053 });
20462054 // TODO(ahe): All the place below using \$ should be rewritten to go
@@ -2119,7 +2127,41 @@ abstract class Closure implements Function {
21192127 propertyName);
21202128 }
21212129
2122- var signatureFunction;
2130+ var signatureFunction = JS_GET_FLAG ('USE_NEW_RTI' )
2131+ ? _computeSignatureFunctionNewRti (functionType, isStatic, isIntercepted)
2132+ : _computeSignatureFunctionLegacy (
2133+ functionType, isStatic, isIntercepted);
2134+
2135+ JS ('' , '#[#] = #' , prototype, JS_GET_NAME (JsGetName .SIGNATURE_NAME ),
2136+ signatureFunction);
2137+ var applyTrampoline = trampoline;
2138+ JS ('' , '#[#] = #' , prototype, callName, trampoline);
2139+ for (int i = 1 ; i < functions.length; i++ ) {
2140+ var stub = functions[i];
2141+ var stubCallName = JS ('String|Null' , '#[#]' , stub,
2142+ JS_GET_NAME (JsGetName .CALL_NAME_PROPERTY ));
2143+ if (stubCallName != null ) {
2144+ stub = isStatic ? stub : forwardCallTo (receiver, stub, isIntercepted);
2145+ JS ('' , '#[#] = #' , prototype, stubCallName, stub);
2146+ }
2147+ if (i == applyTrampolineIndex) {
2148+ applyTrampoline = stub;
2149+ JS ('' , '#.\$ reflectionInfo = #' , applyTrampoline, reflectionInfo);
2150+ }
2151+ }
2152+
2153+ JS ('' , '#[#] = #' , prototype, JS_GET_NAME (JsGetName .CALL_CATCH_ALL ),
2154+ applyTrampoline);
2155+ String reqArgProperty = JS_GET_NAME (JsGetName .REQUIRED_PARAMETER_PROPERTY );
2156+ String defValProperty = JS_GET_NAME (JsGetName .DEFAULT_VALUES_PROPERTY );
2157+ JS ('' , '#.# = #.#' , prototype, reqArgProperty, function, reqArgProperty);
2158+ JS ('' , '#.# = #.#' , prototype, defValProperty, function, defValProperty);
2159+
2160+ return constructor;
2161+ }
2162+
2163+ static _computeSignatureFunctionLegacy (
2164+ Object functionType, bool isStatic, bool isIntercepted) {
21232165 if (JS ('bool' , 'typeof # == "number"' , functionType)) {
21242166 // We cannot call [getType] here, since the types-metadata might not be
21252167 // set yet. This is, because fromTearOff might be called for constants
@@ -2128,23 +2170,22 @@ abstract class Closure implements Function {
21282170 // Note that we cannot just textually inline the call
21292171 // `getType(functionType)` since we cannot guarantee that the (then)
21302172 // captured variable `functionType` isn't reused.
2131- signatureFunction = JS (
2173+ return JS (
21322174 '' ,
21332175 '''(function(getType, t) {
21342176 return function(){ return getType(t); };
21352177 })(#, #)''' ,
2136- JS_GET_FLAG ('USE_NEW_RTI' )
2137- ? RAW_DART_FUNCTION_REF (newRti.getTypeFromTypesTable)
2138- : RAW_DART_FUNCTION_REF (getType),
2178+ RAW_DART_FUNCTION_REF (getType),
21392179 functionType);
2140- } else if (JS ('bool' , 'typeof # == "function"' , functionType)) {
2180+ }
2181+ if (JS ('bool' , 'typeof # == "function"' , functionType)) {
21412182 if (isStatic) {
2142- signatureFunction = functionType;
2183+ return functionType;
21432184 } else {
21442185 var getReceiver = isIntercepted
21452186 ? RAW_DART_FUNCTION_REF (BoundClosure .receiverOf)
21462187 : RAW_DART_FUNCTION_REF (BoundClosure .selfOf);
2147- signatureFunction = JS (
2188+ return JS (
21482189 '' ,
21492190 'function(f,r){'
21502191 'return function(){'
@@ -2154,36 +2195,46 @@ abstract class Closure implements Function {
21542195 functionType,
21552196 getReceiver);
21562197 }
2157- } else {
2158- throw 'Error in reflectionInfo.' ;
21592198 }
2199+ throw 'Error in functionType of tearoff' ;
2200+ }
21602201
2161- JS ('' , '#[#] = #' , prototype, JS_GET_NAME (JsGetName .SIGNATURE_NAME ),
2162- signatureFunction);
2163- var applyTrampoline = trampoline;
2164- JS ('' , '#[#] = #' , prototype, callName, trampoline);
2165- for (int i = 1 ; i < functions.length; i++ ) {
2166- var stub = functions[i];
2167- var stubCallName = JS ('String|Null' , '#[#]' , stub,
2168- JS_GET_NAME (JsGetName .CALL_NAME_PROPERTY ));
2169- if (stubCallName != null ) {
2170- stub = isStatic ? stub : forwardCallTo (receiver, stub, isIntercepted);
2171- JS ('' , '#[#] = #' , prototype, stubCallName, stub);
2172- }
2173- if (i == applyTrampolineIndex) {
2174- applyTrampoline = stub;
2175- JS ('' , '#.\$ reflectionInfo = #' , applyTrampoline, reflectionInfo);
2202+ static _computeSignatureFunctionNewRti (
2203+ Object functionType, bool isStatic, bool isIntercepted) {
2204+ if (JS ('bool' , 'typeof # == "number"' , functionType)) {
2205+ // Index into types table.
2206+ //
2207+ // We cannot call [getTypeFromTypesTable] here, since the types-metadata
2208+ // might not be set yet. This is, because fromTearOff might be called for
2209+ // constants when the program isn't completely set up yet. We also want to
2210+ // avoid creating lots of types at startup.
2211+ return JS (
2212+ '' ,
2213+ '''(function(getType, t) {
2214+ return function(){ return getType(t); };
2215+ })(#, #)''' ,
2216+ RAW_DART_FUNCTION_REF (newRti.getTypeFromTypesTable),
2217+ functionType);
2218+ }
2219+ if (JS ('bool' , 'typeof # == "string"' , functionType)) {
2220+ // A recipe to evaluate against the instance type.
2221+ if (isStatic) {
2222+ throw 'TODO: Recipe for static tearoff.' ;
21762223 }
2224+ var typeEvalMethod = isIntercepted
2225+ ? RAW_DART_FUNCTION_REF (BoundClosure .evalRecipeIntercepted)
2226+ : RAW_DART_FUNCTION_REF (BoundClosure .evalRecipe);
2227+ return JS (
2228+ '' ,
2229+ ' function(recipe, evalOnReceiver) {'
2230+ ' return function() {'
2231+ ' return evalOnReceiver(this, recipe);'
2232+ ' };'
2233+ '}(#,#)' ,
2234+ functionType,
2235+ typeEvalMethod);
21772236 }
2178-
2179- JS ('' , '#[#] = #' , prototype, JS_GET_NAME (JsGetName .CALL_CATCH_ALL ),
2180- applyTrampoline);
2181- String reqArgProperty = JS_GET_NAME (JsGetName .REQUIRED_PARAMETER_PROPERTY );
2182- String defValProperty = JS_GET_NAME (JsGetName .DEFAULT_VALUES_PROPERTY );
2183- JS ('' , '#.# = #.#' , prototype, reqArgProperty, function, reqArgProperty);
2184- JS ('' , '#.# = #.#' , prototype, defValProperty, function, defValProperty);
2185-
2186- return constructor;
2237+ throw 'Error in functionType of tearoff' ;
21872238 }
21882239
21892240 static cspForwardCall (
@@ -2531,6 +2582,14 @@ class BoundClosure extends TearOffClosure {
25312582 "${Primitives .objectToHumanReadableString (receiver )}" ;
25322583 }
25332584
2585+ static evalRecipe (BoundClosure closure, String recipe) {
2586+ return newRti.evalInInstance (closure._self, recipe);
2587+ }
2588+
2589+ static evalRecipeIntercepted (BoundClosure closure, String recipe) {
2590+ return newRti.evalInInstance (closure._receiver, recipe);
2591+ }
2592+
25342593 @pragma ('dart2js:noInline' )
25352594 static selfOf (BoundClosure closure) => closure._self;
25362595
0 commit comments